deadwood-scan 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +158 -0
- package/dist/index.js +748 -57
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# deadwood-scan
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/deadwood-scan)
|
|
4
|
+
|
|
5
|
+
**Find the code your repo no longer calls — and prove it.** deadwood statically scans a
|
|
6
|
+
JS/TS repo for dead routes, unused exports, unused dependencies and unreachable files,
|
|
7
|
+
attaches **evidence** to every finding, and gives you a safe way to delete it.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx deadwood-scan .
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
☠ 31% of your routes appear dead (9 of 29)
|
|
15
|
+
7 unused exports · 2 unused dependencies
|
|
16
|
+
|
|
17
|
+
DELETE /api/legacy/export legacy.ts:87 70% │ capped
|
|
18
|
+
├─ no client path matches this route
|
|
19
|
+
├─ marked @deprecated
|
|
20
|
+
├─ last commit touching this file: 14 months ago
|
|
21
|
+
└─ no runtime evidence — connect telemetry
|
|
22
|
+
|
|
23
|
+
export draftCheckout pay.ts:12 50% │ demoted
|
|
24
|
+
└─ modified 3 days ago — likely work in progress
|
|
25
|
+
|
|
26
|
+
→ deadwood clean — review & remove these interactively (one revertable commit each)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Zero network calls. Zero telemetry. Nothing leaves your machine.
|
|
30
|
+
|
|
31
|
+
## Why it's different
|
|
32
|
+
|
|
33
|
+
- **Evidence, not verdicts.** Every finding carries the signals that produced it, with
|
|
34
|
+
signed weights. Anything the analyzer can't resolve _lowers_ confidence instead of
|
|
35
|
+
being ignored — so hidden callers (dynamic imports, string dispatch, cron manifests)
|
|
36
|
+
demote a finding rather than causing a false positive.
|
|
37
|
+
- **It says "appears dead", never "is dead".** Static confidence is hard-capped (70 for
|
|
38
|
+
routes, 85 for the rest). Only runtime evidence lifts the cap.
|
|
39
|
+
- **Your git history is evidence.** Code untouched for a year ranks up; code you touched
|
|
40
|
+
this week is demoted as work-in-progress. Works from your first commit, offline.
|
|
41
|
+
|
|
42
|
+
## Commands
|
|
43
|
+
|
|
44
|
+
### Scan
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
deadwood [path] # the shock report
|
|
48
|
+
deadwood --json # machine-readable ScanResult (schemaVersion 1)
|
|
49
|
+
deadwood --md # markdown, for PR comments / Slack
|
|
50
|
+
deadwood --fail-on high # CI gate: exit 1 when tripped
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### `--diff-base <ref>` — the PR delta gate
|
|
54
|
+
|
|
55
|
+
Report only what a change **introduces**, not the whole inventory. This is the loop that
|
|
56
|
+
stops AI-generated orphan code at the door:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
deadwood --diff-base main # "+2 introduced · −1 resolved"
|
|
60
|
+
deadwood --diff-base origin/main --fail-on medium # CI: you may not ADD dead code
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The base ref is scanned in a temporary git worktree; the diff is exact (finding ids are
|
|
64
|
+
stable across scans by design). `--fail-on` then gates the _delta_, not the backlog — so
|
|
65
|
+
a legacy repo can adopt the gate on day one without fixing everything first.
|
|
66
|
+
|
|
67
|
+
### `deadwood clean` — guided deletion
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
deadwood clean --dry-run # print the plan, touch nothing
|
|
71
|
+
deadwood clean # interactive: [d]elete / [s]kip / [a]ll / [q]uit
|
|
72
|
+
deadwood clean --yes # non-interactive, medium+ confidence
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Each accepted removal is applied **and committed on its own**, so `git revert <sha>` is
|
|
76
|
+
always the undo. It only offers removals it can _prove_ (whole unreachable files, unused
|
|
77
|
+
dependencies); routes and exports are listed for manual review, never auto-edited. It
|
|
78
|
+
refuses to run on a dirty working tree.
|
|
79
|
+
|
|
80
|
+
### `deadwood explain <query>`
|
|
81
|
+
|
|
82
|
+
One finding, fully unpacked — every evidence line with its signed weight and source, the
|
|
83
|
+
confidence arithmetic including the active cap, and what would make the code live.
|
|
84
|
+
|
|
85
|
+
### `deadwood mcp`
|
|
86
|
+
|
|
87
|
+
A [Model Context Protocol](https://modelcontextprotocol.io) server over stdio, so your
|
|
88
|
+
coding agents (Cursor, Claude Code, Copilot) can consult the dead-code map _before_
|
|
89
|
+
writing or deleting. Tools: `deadwood_scan`, `deadwood_findings`.
|
|
90
|
+
|
|
91
|
+
```jsonc
|
|
92
|
+
// .cursor/mcp.json or claude_desktop_config.json
|
|
93
|
+
{ "mcpServers": { "deadwood": { "command": "npx", "args": ["deadwood-scan", "mcp", "."] } } }
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### `deadwood badge` · `--watch`
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
deadwood badge --output deadwood-badge.svg # self-hosted status SVG (no external service)
|
|
100
|
+
deadwood --watch # re-scan on save: +introduced / −resolved
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Flags
|
|
104
|
+
|
|
105
|
+
| flag | |
|
|
106
|
+
| -------------------------------------------------------- | --------------------------------------------------------- |
|
|
107
|
+
| `--json` / `--md` | machine-readable / markdown output |
|
|
108
|
+
| `--fail-on <high\|medium\|high:N>` | CI gate (exit 1); with `--diff-base`, gates the delta |
|
|
109
|
+
| `--diff-base <ref>` | report only findings introduced since this git ref |
|
|
110
|
+
| `--watch` | re-scan on save, report the delta per change |
|
|
111
|
+
| `--min-confidence <low\|medium\|high>` | hide findings below this level (never affects the gate) |
|
|
112
|
+
| `--entry <file...>` | extra entry points — the false-positive escape hatch |
|
|
113
|
+
| `--category <…>` · `--workspace <…>` · `--framework <…>` | narrow the scan |
|
|
114
|
+
| `--include` / `--exclude <glob...>` | extra globs |
|
|
115
|
+
| `--no-default-excludes` | also report on `generated/`, `examples/`, fixtures, mocks |
|
|
116
|
+
| `--no-git` | skip git-history evidence |
|
|
117
|
+
| `--no-color` | plain output |
|
|
118
|
+
|
|
119
|
+
**Exit codes:** `0` clean · `1` `--fail-on` gate tripped · `2` scan error.
|
|
120
|
+
|
|
121
|
+
## Configuration (in-repo, versioned with your code)
|
|
122
|
+
|
|
123
|
+
`deadwood.config.json`:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"entries": ["scripts/cron-job.ts"],
|
|
128
|
+
"exclude": ["legacy/**"],
|
|
129
|
+
"publicApi": ["src/index.ts"]
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`entries` = extra entry points. `exclude` = extra globs. **`publicApi`** = files whose
|
|
134
|
+
exports are your published API surface: external consumers are invisible to static
|
|
135
|
+
analysis, so their unused-export findings are demoted with spare evidence — kept visible,
|
|
136
|
+
never shouted.
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
# .deadwoodignore (one glob per line, '#' comments)
|
|
140
|
+
vendor/**
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Evidence signals
|
|
144
|
+
|
|
145
|
+
Findings score as `clamp(0, cap, Σ evidence weights)`:
|
|
146
|
+
|
|
147
|
+
| | |
|
|
148
|
+
| -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
149
|
+
| **kill** (raise confidence) | route registered but nothing references its path · marked `@deprecated` · reachable only from tests · file untouched for a year · last author gone 6+ months · introduced once, never revisited |
|
|
150
|
+
| **spare** (lower confidence — a hidden caller may exist) | dynamic import may load this directory · symbol in a string-dispatch table · referenced by a package script, build config or CI/cron manifest · declared public API · **modified in the last 30 days (work in progress)** |
|
|
151
|
+
| **runtime** (lifts the cap — the paid tiers) | dev/staging/e2e traffic seen (→ 90) · production traffic seen, or coverage-guaranteed zero requests in 90 days (→ 100, _confirmed dead_) |
|
|
152
|
+
|
|
153
|
+
## Beyond the CLI
|
|
154
|
+
|
|
155
|
+
- **GitHub App** — a shock report on every PR, findings that upgrade in place as evidence arrives.
|
|
156
|
+
- **[deadwood-express-probe](https://www.npmjs.com/package/deadwood-express-probe)** — report aggregate route usage (templates, counts, windows — never a concrete URL) from a dev server, e2e suite, or production. That's what turns "appears dead" into _confirmed dead_.
|
|
157
|
+
|
|
158
|
+
See [deadwood.dev](https://github.com/BilalBaheer/deadwood-Cli) · MIT.
|