ts-reviewer 3.0.1 → 3.1.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 +14 -2
- package/package.json +1 -1
- package/ts-reviewer/SKILL.md +82 -48
package/README.md
CHANGED
|
@@ -84,6 +84,8 @@ Audit the codebase for security and type safety problems
|
|
|
84
84
|
Claude will analyze the project and write a report to `code-smells/report.md` in the project root.
|
|
85
85
|
With Architecture active, the same directory also holds project discovery, Knip, graph, metric, co-change, rule, and Mermaid artifacts.
|
|
86
86
|
|
|
87
|
+
The analysis passes run in waves. `--agents N` sets how many run at once (default 3; `--agents 1` runs them one at a time in the main agent). Each pass writes its own findings file under `code-smells/passes/`, and the queue in `code-smells/passes/queue.md` tracks which passes are done, so an interrupted scan does not lose finished work.
|
|
88
|
+
|
|
87
89
|
#### Domain flags
|
|
88
90
|
|
|
89
91
|
By default, only the nine core domains run. Use flags to control which domains are active:
|
|
@@ -197,6 +199,12 @@ cnlp/ # the CNL-P format the skill files are wri
|
|
|
197
199
|
|
|
198
200
|
ts-reviewer/
|
|
199
201
|
├── SKILL.md # Main skill file — mode routing, workflow orchestration
|
|
202
|
+
├── tools/ # Mechanical pre-pass and report validator — plain Node, no dependencies
|
|
203
|
+
│ ├── discover-projects.mjs # Finds the TypeScript projects and their source roots
|
|
204
|
+
│ ├── co-change.mjs # Git co-change pairs across directory boundaries
|
|
205
|
+
│ ├── run-cruise.mjs # dependency-cruiser graphs, metrics, and Mermaid diagrams per project
|
|
206
|
+
│ ├── classify-run.mjs # Reads a tool run by its output, not its exit code
|
|
207
|
+
│ └── validate-report.mjs # Checks code-smells/report.md against the report contract
|
|
200
208
|
└── references/
|
|
201
209
|
├── type-safety.md # Checklist: any, unknown, casts, !, exhaustiveness, branded types
|
|
202
210
|
├── security.md # Checklist: trust boundaries, injection, SSRF, pollution, ReDoS
|
|
@@ -240,9 +248,9 @@ The test catches a check line that lost its severity, a block the profile does n
|
|
|
240
248
|
### Scan mode
|
|
241
249
|
|
|
242
250
|
1. **Discovery** — detects domain flags, maps the project, reads tsconfig.json, detects linter and test runner, and asks once before downloading a missing architecture tool.
|
|
243
|
-
2. **Diagnostics** — runs `tsc --noEmit`, linter, and LSP diagnostics (if available)
|
|
251
|
+
2. **Diagnostics** — runs `tsc --noEmit`, linter, and LSP diagnostics (if available); compiler and linter output is cached under `code-smells/passes/` and reused on a resume of the same commit.
|
|
244
252
|
3. **Architecture pre-pass** — when active, writes bounded Knip, graph, metric, co-change, rule, and Mermaid artifacts under `code-smells/`, with project coverage and bounded failure diagnostics.
|
|
245
|
-
4. **Analysis** — specialized passes judge the candidates against the active checklists;
|
|
253
|
+
4. **Analysis** — specialized passes judge the candidates against the active checklists, running in waves of `--agents` at a time; each pass writes its own `code-smells/passes/<id>.jsonl`, and `passes/queue.md` marks which are done, so a stopped run resumes from the last checkpoint. Tool output is never a finding by itself.
|
|
246
254
|
5. **Report** — deduplicates, applies severity boost (scoped modes), consolidates recurring patterns, enforces a noise budget, writes `code-smells/report.md`, and validates its contract before the scan succeeds. Architecture findings appear in a separate `## Architecture Opportunities` section at the end.
|
|
247
255
|
|
|
248
256
|
Validate a report directly with `node ts-reviewer/tools/validate-report.mjs --repo . --report code-smells/report.md`. It checks headings, counts, finding anchors, architecture fields, and linked artifacts without adding a dependency. An **error** is a defect of the report that rewriting it fixes; a **warning** names an outcome of the mechanical pre-pass — a graph with no diagram, say — that the report cannot fix, and warnings do not fail the run.
|
|
@@ -263,6 +271,10 @@ Validate a report directly with `node ts-reviewer/tools/validate-report.mjs --re
|
|
|
263
271
|
|
|
264
272
|
- **Add `code-smells/` to `.gitignore`** — it contains review artifacts, not source code.
|
|
265
273
|
|
|
274
|
+
- **Resume an interrupted scan** — run the same scan again. When `code-smells/passes/queue.md` exists, the skill asks whether to resume (finished passes are skipped, cached `tsc` and linter output is reused on the same commit) or restart from scratch.
|
|
275
|
+
|
|
276
|
+
- **Claude Code users** — `CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS` in `settings.json` under `env` caps sub-agents for every session on the host. It is independent of `--agents`, which caps one review run and works in every supported agent.
|
|
277
|
+
|
|
266
278
|
- **Commit before running fix** — so you can `git diff` to review changes and `git checkout -- .` to revert if needed.
|
|
267
279
|
|
|
268
280
|
- **Edit the report before fix** — since fix uses `code-smells/report.md` as its work plan, you can delete issues you don't want fixed, change severities, or add notes before running fix.
|
package/package.json
CHANGED
package/ts-reviewer/SKILL.md
CHANGED
|
@@ -23,7 +23,7 @@ target_stack:
|
|
|
23
23
|
- a pattern below this stack is a finding, and a feature above it is never recommended
|
|
24
24
|
|
|
25
25
|
inputs:
|
|
26
|
-
- the request, which carries the run mode, the domain set, and the
|
|
26
|
+
- the request, which carries the run mode, the domain set, the scope mode, and the wave size
|
|
27
27
|
- the project `tsconfig.json`, `package.json`, and linter config
|
|
28
28
|
- the reference checklists under `references/`
|
|
29
29
|
|
|
@@ -62,9 +62,12 @@ forbidden_behaviors:
|
|
|
62
62
|
- do not download and execute a missing analysis tool before the operator approves it once at discovery
|
|
63
63
|
- do not run `npm install` or `npm uninstall` for analysis: use an approved pinned-major `npx -y` command, or record the pre-pass as skipped
|
|
64
64
|
- do not rename a report section, field, severity, confidence, or domain: `report_format` and `domains` hold exact identifiers
|
|
65
|
+
- do not start a wave before every pass of the previous wave is marked `done`, `pending`, or `failed` in the queue
|
|
66
|
+
- do not read a finding from an agent reply: the `.jsonl` file under `code-smells/passes/` is the record, and a reply holds 1 line
|
|
65
67
|
|
|
66
68
|
outputs:
|
|
67
69
|
- `code-smells/report.md` in the project root: the scan report, and the work plan fix reads
|
|
70
|
+
- `code-smells/passes/`: the pass queue, the cached diagnostics, and 1 JSONL file per pass
|
|
68
71
|
- `code-smells/knip.json`, `projects.json`, `co-change.md`, `cruise-summary.md`, `metrics.md`, and graph and diagram directories when Architecture is active
|
|
69
72
|
- `code-smells/suggested.dependency-cruiser.cjs` when prose declares dependency rules and no machine-readable declaration owns them
|
|
70
73
|
- the `## Architecture Opportunities` section of the report only when Architecture is active and at least 1 confirmed finding exists
|
|
@@ -120,58 +123,65 @@ workflow:
|
|
|
120
123
|
3. identify the scope mode from `scope_modes`, and default to `full` when the request names none
|
|
121
124
|
4. build the file list with the command in `scope_commands` for that scope mode
|
|
122
125
|
5. ask whether to fall back to `full` when a scoped mode yields 0 files
|
|
123
|
-
6.
|
|
124
|
-
7.
|
|
125
|
-
8.
|
|
126
|
-
9.
|
|
127
|
-
10.
|
|
128
|
-
11.
|
|
129
|
-
12.
|
|
130
|
-
13.
|
|
131
|
-
14.
|
|
132
|
-
15.
|
|
133
|
-
16. collect
|
|
134
|
-
17.
|
|
135
|
-
18.
|
|
136
|
-
19.
|
|
137
|
-
20.
|
|
138
|
-
21.
|
|
139
|
-
22.
|
|
140
|
-
23.
|
|
141
|
-
24.
|
|
142
|
-
25.
|
|
143
|
-
26.
|
|
144
|
-
27.
|
|
145
|
-
28.
|
|
146
|
-
29.
|
|
147
|
-
30.
|
|
148
|
-
31.
|
|
149
|
-
32.
|
|
150
|
-
33.
|
|
151
|
-
34.
|
|
152
|
-
35.
|
|
126
|
+
6. ask once whether to resume or restart when `code-smells/passes/queue.md` exists, and delete `code-smells/passes/` on restart
|
|
127
|
+
7. warn when the `HEAD` in the queue header differs from the current `HEAD` on a resume: the line re-read below catches a stale line
|
|
128
|
+
8. map the project tree in full, whatever the scope mode
|
|
129
|
+
9. read `tsconfig.json` and `references/tsconfig.md`, then audit the config flags
|
|
130
|
+
10. detect monorepo workspaces in `package.json` and `pnpm-workspace.yaml`, and every further tsconfig
|
|
131
|
+
11. audit the config that governs the files in scope, and name that config in the summary
|
|
132
|
+
12. read the linter config: `eslint.config.*`, `.eslintrc.*`, `biome.json`, `deno.json`
|
|
133
|
+
13. read `package.json` for the dependencies and the module type, and verify the TypeScript version, `engines.node`, and `@types/node` against `target_stack`
|
|
134
|
+
14. identify declared entry points from `package.json#exports`, `main`, `bin`, and the `start`, `dev`, and `serve` scripts
|
|
135
|
+
15. when Architecture is active, inspect local Knip and dependency-cruiser binaries and ask once before running either missing tool through pinned-major `npx -y`
|
|
136
|
+
16. collect the context files named in `scope:` when the scope mode is scoped
|
|
137
|
+
17. identify feature slices and public entry points when Architecture is active, leaving graph discovery to its mechanical pre-pass
|
|
138
|
+
18. collect machine-readable dependency rules and prose from ADR directories, `ARCHITECTURE.md`, README, and `CONTRIBUTING.md`
|
|
139
|
+
19. run `npx tsc --noEmit 2>&1 | head -200` over the full project into `code-smells/passes/tsc.log`, and report only the errors in the scoped files
|
|
140
|
+
20. run the linter into `code-smells/passes/lint.json`: `npx eslint [files] --format json` or `npx biome check [files] --reporter json`
|
|
141
|
+
21. reuse `tsc.log` and `lint.json` on a resume when the queue `HEAD` matches and the tree is clean, and rerun both otherwise
|
|
142
|
+
22. query the TypeScript LSP over MCP when it is reachable, then merge and deduplicate against the compiler output
|
|
143
|
+
23. triage every compiler and linter diagnostic through `severity_mapping`
|
|
144
|
+
24. read the reference file named in `domains` before each analysis pass
|
|
145
|
+
25. run the mechanical pre-pass in `references/architecture.md` when Architecture is active, passing the approved tool decision and scoped base
|
|
146
|
+
26. report the discovery summary in the shape of `discovery_summary`, including skipped and clean mechanical results
|
|
147
|
+
27. build the pass list: 1 pass per active domain, split by directory when scoped files > 20, with the shared types visible to every pass
|
|
148
|
+
28. write `code-smells/passes/queue.md` in the shape of `pass_queue`, in its domain order, and skip a pass marked `done` on a resume
|
|
149
|
+
29. run the pending passes in waves of the wave size, as sub-agents shaped by `subagent_template`, or in the main agent when the wave size is 1
|
|
150
|
+
30. wait for every agent of a wave, then mark each pass `done` when the last line of its file is the `done` line, and `pending` otherwise
|
|
151
|
+
31. mark a pass `failed` after 2 attempts without a `done` line, name it in the discovery summary, and report its domain as not run
|
|
152
|
+
32. read the findings of every `done` pass from its `.jsonl` file before the re-read below
|
|
153
|
+
33. re-read the exact lines in the current file state before a finding enters the report
|
|
154
|
+
34. read the callers to verify a data flow a finding rests on, or mark its problem statement with "if <condition>" and cap its severity at Medium
|
|
155
|
+
35. downgrade a flagged non-High pattern that appears 5+ times across the codebase by 1 level, and report it once as a Recurring Pattern
|
|
156
|
+
36. boost a finding carrying `in_diff: true` by 1 level in a scoped mode, and mark it `High [boosted, was Medium — new code]`
|
|
157
|
+
37. deduplicate the findings on the same file, line, and issue, keeping 1
|
|
158
|
+
38. merge the findings 2 domains raise on the same file and line into 1 entry attributing both categories, at the higher severity
|
|
159
|
+
39. consolidate 3+ identical issues into 1 Recurring Pattern entry
|
|
160
|
+
40. keep the top 15 by severity and impact when a single domain produces more than 25 Medium or Low findings, and consolidate the rest into Recurring Pattern entries with their counts
|
|
161
|
+
41. write `code-smells/report.md` in the shape of `report_format`
|
|
162
|
+
42. validate the report against `report_format` after writing it, and treat a `warning:` line as a pre-pass outcome the report cannot correct
|
|
153
163
|
```bash
|
|
154
164
|
# SKILL is the directory this file was loaded from.
|
|
155
165
|
SKILL=<the directory this file was loaded from>
|
|
156
166
|
node "$SKILL/tools/validate-report.mjs" --repo . --report code-smells/report.md
|
|
157
167
|
```
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
168
|
+
43. correct every named error and retry with report validation iterations <= 2
|
|
169
|
+
44. keep `code-smells/report.md` when the second validation fails, write `> unvalidated: <the first error>` under its title, and name the errors to the operator
|
|
170
|
+
45. sort by severity group, then category, then file path, and place `in_diff: true` before pre-existing in a scoped mode
|
|
171
|
+
46. show the top 10 and summarize the rest in a table when Medium and Low together hold more than 15 issues
|
|
172
|
+
47. recommend that the operator adds `code-smells/` to `.gitignore`: it holds review artifacts
|
|
173
|
+
48. read `references/fix-workflow.md` before fix mode executes: it holds the complete protocol
|
|
174
|
+
49. detect the test runner and run the baseline tests
|
|
175
|
+
50. fix the issues file by file, and run `tsc --noEmit` after each file
|
|
176
|
+
51. run the linter and fix the lint errors it reports
|
|
177
|
+
52. run the full test suite, compare it against the baseline, and fix the regressions
|
|
178
|
+
53. repeat the compiler, linter, and test verification with verification iterations <= 5
|
|
179
|
+
54. rerun the Architecture mechanical pre-pass on the fixed tree when Architecture is active
|
|
180
|
+
55. update `code-smells/report.md`: remove what is fixed, mark what failed
|
|
181
|
+
56. show the scan summary in auto mode, and ask the operator whether to proceed with the fix
|
|
182
|
+
57. re-scan after the fix in auto mode with full scan-fix cycles <= 2, and stop when issues persist after the second
|
|
183
|
+
58. delete `code-smells/report.md` and report success when every issue is fixed
|
|
184
|
+
59. retain the remaining `code-smells/` artifacts, state what they contain, and remove them only after the operator confirms
|
|
175
185
|
|
|
176
186
|
scope_commands:
|
|
177
187
|
```bash
|
|
@@ -232,6 +242,8 @@ Strict mode: yes / partial / no
|
|
|
232
242
|
Linter: eslint / biome / none
|
|
233
243
|
Test runner: vitest / jest / mocha / node:test / none
|
|
234
244
|
Files in scope: <N> .ts files (+ <M> context files)
|
|
245
|
+
Agents per wave: <N>
|
|
246
|
+
Resumed: <done>/<total> passes from code-smells/passes/queue.md, or no
|
|
235
247
|
Architecture projects: <config and source roots, when active>
|
|
236
248
|
Architecture tools: <local or approved npx versions, when active>
|
|
237
249
|
Architecture coverage: <successful>/<selected>, when active
|
|
@@ -252,6 +264,9 @@ Read the reference checklist: [REFERENCE_PATH]
|
|
|
252
264
|
Review these files: [FILE_LIST]
|
|
253
265
|
Context files (read-only, do NOT report issues): [CONTEXT_FILE_LIST]
|
|
254
266
|
Scope mode: [full|uncommitted|branch|commits:N]
|
|
267
|
+
Write every finding as 1 JSONL line to: [OUTPUT_PATH]
|
|
268
|
+
Append 1 last line when every file is reviewed: {"done": true, "findings": N, "files": M}
|
|
269
|
+
Reply with 1 line: the pass id, the findings count, the files count. The file is the result; the reply is not.
|
|
255
270
|
|
|
256
271
|
Output JSONL, one object per line:
|
|
257
272
|
{
|
|
@@ -269,6 +284,25 @@ Output JSONL, one object per line:
|
|
|
269
284
|
}
|
|
270
285
|
```
|
|
271
286
|
|
|
287
|
+
pass_queue:
|
|
288
|
+
- `--agents N` in the request sets the wave size, and the default is 3
|
|
289
|
+
- `--agents 1` runs 1 pass at a time in the main agent, with no sub-agent
|
|
290
|
+
- the pass id is the domain slug, or `<domain slug>.<directory slug>` for a split pass
|
|
291
|
+
- the domain order: Security, Type Safety, Async Patterns, Error Handling, Boundary Validation, Config, Dependency Hygiene, Modernization, Code Quality, Architecture
|
|
292
|
+
- a status is `pending`, `done`, or `failed`, and `Attempts` counts the waves the pass ran in
|
|
293
|
+
```markdown
|
|
294
|
+
# Pass queue
|
|
295
|
+
|
|
296
|
+
HEAD: <sha>
|
|
297
|
+
Scope: <mode>
|
|
298
|
+
Agents per wave: <N>
|
|
299
|
+
|
|
300
|
+
| Pass | Domain | Files | Status | Attempts | Findings |
|
|
301
|
+
|---|---|---|---|---|---|
|
|
302
|
+
| security | Security | 42 | done | 1 | 7 |
|
|
303
|
+
| type-safety.src-auth | Type Safety | 12 | pending | 1 | |
|
|
304
|
+
```
|
|
305
|
+
|
|
272
306
|
report_format:
|
|
273
307
|
- the `##` sections of the block below are the whole set, in that order, and a heading outside it is a renamed section
|
|
274
308
|
- Discovery, Pre-existing Issues, Architecture Opportunities, Verification, and Generated artifacts are optional, and the other 5 are always present
|