- Rename delegate_task tool to task across codebase (100 files) - Update model references: claude-opus-4-6 → 4-5, gpt-5.3-codex → 5.2-codex - Add tool-metadata-store to restore metadata overwritten by fromPlugin() - Add session ID polling for BackgroundManager task sessions - Await async ctx.metadata() calls in tool executors - Add ses_ prefix guard to getMessageDir for performance - Harden BackgroundManager with idle deferral and error handling - Fix duplicate task key in sisyphus-junior test object literals - Fix unawaited showOutputToUser in ast_grep_replace - Fix background=true → run_in_background=true in ultrawork prompt - Fix duplicate task/task references in docs and comments
343 lines
9.9 KiB
Markdown
343 lines
9.9 KiB
Markdown
---
|
|
description: Remove unused code from this project with ultrawork mode, LSP-verified safety, atomic commits
|
|
---
|
|
|
|
<command-instruction>
|
|
You are a dead code removal specialist. Execute the FULL dead code removal workflow using ultrawork mode.
|
|
|
|
Your core weapon: **LSP FindReferences**. If a symbol has ZERO external references, it's dead. Remove it.
|
|
|
|
## CRITICAL RULES
|
|
|
|
1. **LSP is law.** Never guess. Always verify with `LspFindReferences` before removing ANYTHING.
|
|
2. **One removal = one commit.** Every dead code removal gets its own atomic commit.
|
|
3. **Test after every removal.** Run `bun test` after each. If it fails, REVERT and skip.
|
|
4. **Leaf-first order.** Remove deepest unused symbols first, then work up the dependency chain. Removing a leaf may expose new dead code upstream.
|
|
5. **Never remove entry points.** `src/index.ts`, `src/cli/index.ts`, test files, config files, and files in `packages/` are off-limits unless explicitly targeted.
|
|
|
|
---
|
|
|
|
## STEP 0: REGISTER TODO LIST (MANDATORY FIRST ACTION)
|
|
|
|
```
|
|
TodoWrite([
|
|
{"id": "scan", "content": "PHASE 1: Scan codebase for dead code candidates using LSP + explore agents", "status": "pending", "priority": "high"},
|
|
{"id": "verify", "content": "PHASE 2: Verify each candidate with LspFindReferences - zero false positives", "status": "pending", "priority": "high"},
|
|
{"id": "plan", "content": "PHASE 3: Plan removal order (leaf-first dependency order)", "status": "pending", "priority": "high"},
|
|
{"id": "remove", "content": "PHASE 4: Remove dead code one-by-one (remove -> test -> commit loop)", "status": "pending", "priority": "high"},
|
|
{"id": "final", "content": "PHASE 5: Final verification - full test suite + build + typecheck", "status": "pending", "priority": "high"}
|
|
])
|
|
```
|
|
|
|
---
|
|
|
|
## PHASE 1: SCAN FOR DEAD CODE CANDIDATES
|
|
|
|
**Mark scan as in_progress.**
|
|
|
|
### 1.1: Launch Parallel Explore Agents (ALL BACKGROUND)
|
|
|
|
Fire ALL simultaneously:
|
|
|
|
```
|
|
// Agent 1: Find all exported symbols
|
|
task(subagent_type="explore", run_in_background=true,
|
|
prompt="Find ALL exported functions, classes, types, interfaces, and constants across src/.
|
|
List each with: file path, line number, symbol name, export type (named/default).
|
|
EXCLUDE: src/index.ts root exports, test files.
|
|
Return as structured list.")
|
|
|
|
// Agent 2: Find potentially unused files
|
|
task(subagent_type="explore", run_in_background=true,
|
|
prompt="Find files in src/ that are NOT imported by any other file.
|
|
Check import/require statements across the entire codebase.
|
|
EXCLUDE: index.ts files, test files, entry points, config files, .md files.
|
|
Return list of potentially orphaned files.")
|
|
|
|
// Agent 3: Find unused imports within files
|
|
task(subagent_type="explore", run_in_background=true,
|
|
prompt="Find unused imports across src/**/*.ts files.
|
|
Look for import statements where the imported symbol is never referenced in the file body.
|
|
Return: file path, line number, imported symbol name.")
|
|
|
|
// Agent 4: Find functions/variables only used in their own declaration
|
|
task(subagent_type="explore", run_in_background=true,
|
|
prompt="Find private/non-exported functions, variables, and types in src/**/*.ts that appear
|
|
to have zero usage beyond their declaration. Return: file path, line number, symbol name.")
|
|
```
|
|
|
|
### 1.2: Direct AST-Grep Scans (WHILE AGENTS RUN)
|
|
|
|
```typescript
|
|
// Find unused imports pattern
|
|
ast_grep_search(pattern="import { $NAME } from '$PATH'", lang="typescript", paths=["src/"])
|
|
|
|
// Find empty export objects
|
|
ast_grep_search(pattern="export {}", lang="typescript", paths=["src/"])
|
|
```
|
|
|
|
### 1.3: Collect All Results
|
|
|
|
Collect background agent results. Compile into a master candidate list:
|
|
|
|
```
|
|
## DEAD CODE CANDIDATES
|
|
|
|
| # | File | Line | Symbol | Type | Confidence |
|
|
|---|------|------|--------|------|------------|
|
|
| 1 | src/foo.ts | 42 | unusedFunc | function | HIGH |
|
|
| 2 | src/bar.ts | 10 | OldType | type | MEDIUM |
|
|
```
|
|
|
|
**Mark scan as completed.**
|
|
|
|
---
|
|
|
|
## PHASE 2: VERIFY WITH LSP (ZERO FALSE POSITIVES)
|
|
|
|
**Mark verify as in_progress.**
|
|
|
|
For EVERY candidate from Phase 1, run this verification:
|
|
|
|
### 2.1: The LSP Verification Protocol
|
|
|
|
For each candidate symbol:
|
|
|
|
```typescript
|
|
// Step 1: Find the symbol's exact position
|
|
LspDocumentSymbols(filePath) // Get line/character of the symbol
|
|
|
|
// Step 2: Find ALL references across the ENTIRE workspace
|
|
LspFindReferences(filePath, line, character, includeDeclaration=false)
|
|
// includeDeclaration=false → only counts USAGES, not the definition itself
|
|
|
|
// Step 3: Evaluate
|
|
// 0 references → CONFIRMED DEAD CODE
|
|
// 1+ references → NOT dead, remove from candidate list
|
|
```
|
|
|
|
### 2.2: False Positive Guards
|
|
|
|
**NEVER mark as dead code if:**
|
|
- Symbol is in `src/index.ts` (package entry point)
|
|
- Symbol is in any `index.ts` that re-exports (barrel file check: look if it's re-exported)
|
|
- Symbol is referenced in test files (tests are valid consumers)
|
|
- Symbol has `@public` or `@api` JSDoc tags
|
|
- Symbol is in a file listed in `package.json` exports
|
|
- Symbol is a hook factory (`createXXXHook`) registered in `src/index.ts`
|
|
- Symbol is a tool factory (`createXXXTool`) registered in tool loading
|
|
- Symbol is an agent definition registered in `agentSources`
|
|
- File is a command template, skill definition, or MCP config
|
|
|
|
### 2.3: Build Confirmed Dead Code List
|
|
|
|
After verification, produce:
|
|
|
|
```
|
|
## CONFIRMED DEAD CODE (LSP-verified, 0 external references)
|
|
|
|
| # | File | Line | Symbol | Type | Safe to Remove |
|
|
|---|------|------|--------|------|----------------|
|
|
| 1 | src/foo.ts | 42 | unusedFunc | function | YES |
|
|
```
|
|
|
|
**If ZERO confirmed dead code found: Report "No dead code found" and STOP.**
|
|
|
|
**Mark verify as completed.**
|
|
|
|
---
|
|
|
|
## PHASE 3: PLAN REMOVAL ORDER
|
|
|
|
**Mark plan as in_progress.**
|
|
|
|
### 3.1: Dependency Analysis
|
|
|
|
For each confirmed dead symbol:
|
|
1. Check if removing it would expose other dead code
|
|
2. Check if other dead symbols depend on this one
|
|
3. Build removal dependency graph
|
|
|
|
### 3.2: Order by Leaf-First
|
|
|
|
```
|
|
Removal Order:
|
|
1. [Leaf symbols - no other dead code depends on them]
|
|
2. [Intermediate symbols - depended on only by already-removed dead code]
|
|
3. [Dead files - entire files with no live exports]
|
|
```
|
|
|
|
### 3.3: Register Granular Todos
|
|
|
|
Create one todo per removal:
|
|
|
|
```
|
|
TodoWrite([
|
|
{"id": "remove-1", "content": "Remove unusedFunc from src/foo.ts:42", "status": "pending", "priority": "high"},
|
|
{"id": "remove-2", "content": "Remove OldType from src/bar.ts:10", "status": "pending", "priority": "high"},
|
|
// ... one per confirmed dead symbol
|
|
])
|
|
```
|
|
|
|
**Mark plan as completed.**
|
|
|
|
---
|
|
|
|
## PHASE 4: ITERATIVE REMOVAL LOOP
|
|
|
|
**Mark remove as in_progress.**
|
|
|
|
For EACH dead code item, execute this exact loop:
|
|
|
|
### 4.1: Pre-Removal Check
|
|
|
|
```typescript
|
|
// Re-verify it's still dead (previous removals may have changed things)
|
|
LspFindReferences(filePath, line, character, includeDeclaration=false)
|
|
// If references > 0 now → SKIP (previous removal exposed a new consumer)
|
|
```
|
|
|
|
### 4.2: Remove the Dead Code
|
|
|
|
Use appropriate tool:
|
|
|
|
**For unused imports:**
|
|
```typescript
|
|
Edit(filePath, oldString="import { deadSymbol } from '...';\n", newString="")
|
|
// Or if it's one of many imports, remove just the symbol from the import list
|
|
```
|
|
|
|
**For unused functions/classes/types:**
|
|
```typescript
|
|
// Read the full symbol extent first
|
|
Read(filePath, offset=startLine, limit=endLine-startLine+1)
|
|
// Then remove it
|
|
Edit(filePath, oldString="[full symbol text]", newString="")
|
|
```
|
|
|
|
**For dead files:**
|
|
```bash
|
|
# Only after confirming ZERO imports point to this file
|
|
rm "path/to/dead-file.ts"
|
|
```
|
|
|
|
**After removal, also clean up:**
|
|
- Remove any imports that were ONLY used by the removed code
|
|
- Remove any now-empty import statements
|
|
- Fix any trailing whitespace / double blank lines left behind
|
|
|
|
### 4.3: Post-Removal Verification
|
|
|
|
```typescript
|
|
// 1. LSP diagnostics on changed file
|
|
LspDiagnostics(filePath, severity="error")
|
|
// Must be clean (or only pre-existing errors)
|
|
|
|
// 2. Run tests
|
|
bash("bun test")
|
|
// Must pass
|
|
|
|
// 3. Typecheck
|
|
bash("bun run typecheck")
|
|
// Must pass
|
|
```
|
|
|
|
### 4.4: Handle Failures
|
|
|
|
If ANY verification fails:
|
|
1. **REVERT** the change immediately (`git checkout -- [file]`)
|
|
2. Mark this removal todo as `cancelled` with note: "Removal caused [error]. Skipped."
|
|
3. Proceed to next item
|
|
|
|
### 4.5: Commit
|
|
|
|
```bash
|
|
git add [changed-files]
|
|
git commit -m "refactor: remove unused [symbolType] [symbolName] from [filePath]"
|
|
```
|
|
|
|
Mark this removal todo as `completed`.
|
|
|
|
### 4.6: Re-scan After Removal
|
|
|
|
After removing a symbol, check if its removal exposed NEW dead code:
|
|
- Were there imports that only existed to serve the removed symbol?
|
|
- Are there other symbols in the same file now unreferenced?
|
|
|
|
If new dead code is found, add it to the removal queue.
|
|
|
|
**Repeat 4.1-4.6 for every item. Mark remove as completed when done.**
|
|
|
|
---
|
|
|
|
## PHASE 5: FINAL VERIFICATION
|
|
|
|
**Mark final as in_progress.**
|
|
|
|
### 5.1: Full Test Suite
|
|
```bash
|
|
bun test
|
|
```
|
|
|
|
### 5.2: Full Typecheck
|
|
```bash
|
|
bun run typecheck
|
|
```
|
|
|
|
### 5.3: Full Build
|
|
```bash
|
|
bun run build
|
|
```
|
|
|
|
### 5.4: Summary Report
|
|
|
|
```markdown
|
|
## Dead Code Removal Complete
|
|
|
|
### Removed
|
|
| # | Symbol | File | Type | Commit |
|
|
|---|--------|------|------|--------|
|
|
| 1 | unusedFunc | src/foo.ts | function | abc1234 |
|
|
|
|
### Skipped (caused failures)
|
|
| # | Symbol | File | Reason |
|
|
|---|--------|------|--------|
|
|
| 1 | riskyFunc | src/bar.ts | Test failure: [details] |
|
|
|
|
### Verification
|
|
- Tests: PASSED (X/Y passing)
|
|
- Typecheck: CLEAN
|
|
- Build: SUCCESS
|
|
- Total dead code removed: N symbols across M files
|
|
- Total commits: K atomic commits
|
|
```
|
|
|
|
**Mark final as completed.**
|
|
|
|
---
|
|
|
|
## SCOPE CONTROL
|
|
|
|
**If $ARGUMENTS is provided**, narrow the scan to the specified scope:
|
|
- File path: Only scan that file
|
|
- Directory: Only scan that directory
|
|
- Symbol name: Only check that specific symbol
|
|
- "all" or empty: Full project scan (default)
|
|
|
|
## ABORT CONDITIONS
|
|
|
|
**STOP and report to user if:**
|
|
- 3 consecutive removals cause test failures
|
|
- Build breaks and cannot be fixed by reverting
|
|
- More than 50 candidates found (ask user to narrow scope)
|
|
|
|
## LANGUAGE
|
|
|
|
Use English for commit messages and technical output.
|
|
|
|
</command-instruction>
|
|
|
|
<user-request>
|
|
$ARGUMENTS
|
|
</user-request>
|