.claude/skills/dead-code/SKILL.md
Find and remove dead code (unused files, exports, class members) using Knip as a candidate generator, then verify each candidate through AST-level analysis and interface tracing before removing anything. Use when the user asks to clean up unused code, find dead code, or reduce the codebase.
npx skillsauth add shift-editor/shift dead-codeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill to find unused files, exports, and class members in the codebase. It uses Knip as a candidate generator, then verifies each candidate through AST-level analysis and interface tracing before removing anything.
NEVER use knip --fix — it has previously deleted code that was actually in use, breaking the editor and tests.
Run Knip to generate candidates:
pnpm deadcode 2>&1 # unused files + exports
pnpm deadcode:class 2>&1 # unused class members
Parse the output into three categories:
For each candidate, apply the appropriate checks below. Use scripts/find-refs.ts when reading code alone is insufficient.
tsconfig.json, vite.*.config.ts, forge.config.tspackage.json scripts or CI workflowsindex.ts) consumed by another packageextends/implements clausesnpx tsx scripts/find-refs.ts <file> <symbol> for compiler-level reference countThis is where most false positives occur. Knip cannot trace usage through interfaces, composite types, or dep interfaces.
Check these patterns in order:
ShiftEditor = EditorAPI & CanvasCoordinatorContext means all EditorAPI members on Editor are used.BaseCommand, BaseTool) and used by subclasses?npx tsx scripts/find-refs.ts <file> <memberName> for compiler confirmation.Members that satisfy any of these interfaces are NOT dead code, even if Knip reports them:
EditorAPI sub-interfaces (apps/desktop/src/renderer/src/lib/tools/core/EditorAPI.ts):
Viewport: zoomLevel, panX, panY, screenToUpm, upmToScreen, screenToUpmDistance, viewportBoundsSelection: selectedPointIds, selectedSegmentIds, selectPoints, selectSegments, clearSelection, marqueePreviewPointIds, setMarqueePreviewHitTesting: hitTestPoint, hitTestSegment, hitTestContour, hitTestBoundingBox, hitTestContourEndpoint, hitTestHandleSnapping: createDragSnapSession, createRotateSnapSession, setSnapIndicatorEditing: startEdit, commitEdit, cancelEdit, isEditingCommands: executeToolLifecycle: activeTool, setActiveTool, activeToolSettingsVisualState: hoveredPoint, setHoveredPoint, hoveredSegment, setHoveredSegment, cursor, setCursorFont interface (apps/desktop/src/renderer/src/lib/editor/Font.ts):
getMetrics, getMetadata, getSvgPath, getAdvance, getBboxCommand interface (apps/desktop/src/renderer/src/lib/commands/core/):
execute, undo, redo, nameBehavior interface (apps/desktop/src/renderer/src/lib/tools/core/):
canHandle, transition, onTransitionBaseTool abstract members:
behaviors, render, executeAction, onStateChange, preTransitionDep interfaces (consumed by managers, implemented by FontEngine or Editor):
EditingEngineDeps — apps/desktop/src/renderer/src/engine/editing.tsSessionEngineDeps — apps/desktop/src/renderer/src/engine/session.tsInfoEngineDeps — apps/desktop/src/renderer/src/engine/info.tsIOEngineDeps — apps/desktop/src/renderer/src/engine/io.tsSnap — apps/desktop/src/renderer/src/managers/SnapManager.tsClipboard — apps/desktop/src/renderer/src/managers/ClipboardManager.tsCanvasCoordinatorContext — apps/desktop/src/renderer/src/lib/editor/rendering/CanvasCoordinator.ts# Check if a symbol has any non-definition references
npx tsx scripts/find-refs.ts apps/desktop/src/renderer/src/lib/editor/Editor.ts undo
# Output shows: file, line, kind (definition vs reference)
# Zero non-definition references = confirmed dead
# >0 references = inspect them to confirm usage
Present a categorized report:
| Category | Meaning | Action |
| ------------------ | ------------------------------------------------ | --------------------------- |
| Confirmed dead | No references, not on any interface | Remove with confirmation |
| Likely dead | Ambiguous — few references, possibly test-only | Flag for human review |
| False positive | Interface-mediated, dep interface, or base class | Tag with @knipclassignore |
knip --fix)pnpm typecheck && pnpm test && pnpm lint:check
For confirmed false positive class members, add the @knipclassignore JSDoc tag:
/** @knipclassignore */
undo(): void {
// ...
}
After tagging, decrease the --max-issues threshold in package.json's deadcode:class script:
# Current threshold
pnpm deadcode:class # check current --max-issues value
# After tagging N false positives, reduce by N
# Edit package.json: --max-issues (current - N)
# Verify the new threshold holds
pnpm deadcode:class
The goal is to drive --max-issues toward 0, at which point CI catches any new dead code with zero tolerance.
knip --fix or deadcode:fixpnpm typecheck && pnpm test && pnpm lint:check after removalstesting
Update or create DOCS.md files for Shift subsystems. Use this skill whenever the user asks to update docs, refresh documentation, create a DOCS.md, write module documentation, or says "update docs for X". Also trigger after completing a large feature when Claude.md says to update docs — check if any DOCS.md in the affected subsystem needs refreshing.
development
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.
development
Maintainer workflow for OpenClaw releases, prereleases, changelog release notes, and publish validation. Use when Codex needs to prepare or verify stable or beta release steps, align version naming, assemble release notes, check release auth requirements, or validate publish-time commands and artifacts.
development
Run, watch, debug, and extend OpenClaw QA testing with qa-lab and qa-channel. Use when Codex needs to execute the repo-backed QA suite, inspect live QA artifacts, debug failing scenarios, add new QA scenarios, or explain the OpenClaw QA workflow. Prefer the live OpenAI lane with regular openai/gpt-5.4 in fast mode; do not use gpt-5.4-pro or gpt-5.4-mini unless the user explicitly overrides that policy.