ts-reviewer 2.0.1 → 2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-reviewer",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "Install the TypeScript Code Reviewer skill for Claude Code, Codex, or Antigravity",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -122,7 +122,7 @@ workflow:
122
122
  12. identify the entry points: `index.ts`, `main.ts`, the `exports` of `package.json`
123
123
  13. collect the context files named in `scope:` when the scope mode is scoped
124
124
  14. map the module relationships when Architecture is active: circular imports, deep relative imports, barrel-file cycles, feature slices, public entry points
125
- 15. scan `docs/adr/` for architectural decisions before proposing a change, and skip it silently when the directory is absent
125
+ 15. scan `docs/adr/`, `doc/adr/`, `adr/`, and `docs/decisions/` for architectural decisions before proposing a change, and skip it silently when none of them exists
126
126
  16. report the discovery summary in the shape of `discovery_summary`
127
127
  17. run `npx tsc --noEmit 2>&1 | head -200` over the full project, and report only the errors in the scoped files
128
128
  18. run the linter: `npx eslint [files] --format json` or `npx biome check [files] --reporter json`
@@ -278,17 +278,7 @@ report_format:
278
278
 
279
279
  ## Architecture Opportunities
280
280
 
281
- ### TITLE — Severity
282
-
283
- - **Files:** relative/path/a.ts, relative/path/b.ts
284
- - **Problem:** why this causes friction now
285
- - **Proposed deepening:** what would change
286
- - **Interface shape:** rough sketch of new interface
287
- - **Dependency category:** in-process | local-substitutable | remote-owned | true-external
288
- - **Test strategy:** how tests improve
289
- - **Benefits:** locality, leverage, test impact
290
- - **Trade-offs:** what gets harder
291
- - **Fixability:** auto | needs-confirm | report-only
281
+ <1 entry per candidate, in the shape the `report_format` block of references/architecture.md gives>
292
282
 
293
283
  ---
294
284
  ````
@@ -5,6 +5,8 @@ purpose:
5
5
  scope:
6
6
  - circular imports and deep relative imports are also flagged by the Code Quality domain in every scan mode, and this file adds the refactoring guidance behind them
7
7
  - a wire type reaching a domain module is also a `references/boundary-validation.md` check
8
+ - state modelling, a discriminated union, and a branded type belong to `references/type-safety.md`, and this file names only the module that owns the state
9
+ - the module-scope singleton and the import-time side effect belong to `references/code-quality.md`, and the composition-root check here names where an adapter is built
8
10
 
9
11
  glossary:
10
12
  - use these terms in every architecture finding, and do not substitute "component", "service", "API", or "boundary"
@@ -17,6 +19,14 @@ glossary:
17
19
  - `leverage` — what a caller gets from depth: more capability per unit of interface it has to learn
18
20
  - locality — what a maintainer gets from depth: change, bugs, and knowledge concentrated in 1 place
19
21
 
22
+ confidence_scale:
23
+
24
+ | Confidence | Criteria |
25
+ |---|---|
26
+ | strong | the pain repeats, the owning module is named, and the fix path is safe |
27
+ | worth-exploring | the problem is confirmed, and the interface or the migration needs its own design |
28
+ | speculative | a signal with no call, history, or test evidence behind it |
29
+
20
30
  read_first:
21
31
  - depth is a property of the interface and not of the implementation: a deep module can be internally complex, and what counts is how small its interface is against what it hides
22
32
  - the deletion test: imagine deleting the module, and if the complexity vanishes it was a pass-through, while if it reappears across the callers it was earning its keep
@@ -24,25 +34,41 @@ read_first:
24
34
  - depth is missing as often as it is overdone, so flag a missing abstraction where it already hurts
25
35
  - dependency direction matters more than layer count: the domain owns the logic, and transport and storage are injected or isolated at the edge
26
36
  - 1 adapter is a hypothetical seam and 2 adapters are a real seam: do not introduce a port until at least 2 adapters are justified, production and test at the minimum
37
+ - an architecture finding rests on evidence: named files and symbols, an import or call direction, a repeated change path in `git log`, a duplicated rule, or a test no correct seam can reach
38
+ - state the observation apart from the inference drawn from it, and mark a candidate with no evidence behind it as speculative rather than reporting it as a defect
39
+ - a defect no test can reach through a correct seam is an architecture finding, and not a reason to write a test past the interface
40
+ - before proposing a module, a port, or a container, check in order: drop the need, an existing module in the repository, the standard library, a platform feature, an installed dependency
41
+ - design a hard-to-reverse proposal twice: compare 2 different interfaces on caller knowledge, seam placement, and migration cost, then recommend 1
42
+ - a cycle is unclear ownership and not a bad graph: move the type or the rule to its owner, and `import type` or a lazy import hides the direction rather than fixing it
43
+ - a path alias shortens an import path and is not an architecture boundary: ownership and a controlled export list are
44
+ - pick the simplest form a deepened module can take: a pure function for a transformation, a reducer for events over 1 state, a state machine when a command is valid only in some states, a class only when it owns long-lived state
27
45
 
28
46
  workflow:
29
- 1. grep for feature-module imports inside the `shared`, `common`, `core`, and `utils` directories, which is the inverted direction
30
- 2. list the importers of each module, and treat a module whose every export has exactly 1 importer as a pass-through candidate for the deletion test
31
- 3. treat an interface or type re-exported unchanged through 3+ files as a pass-through chain
32
- 4. check whether the exports of a utility file imported by most modules share 1 domain concept
33
- 5. read `git log --name-only` and treat a feature whose commits consistently touch 4+ directories as scattered logic
34
- 6. run these checks rather than guessing from file names
47
+ 1. trace 1 typical scenario end to end before naming a finding: entry point, orchestration, domain rule, storage or external call, response
48
+ 2. grep for feature-module imports inside the `shared`, `common`, `core`, and `utils` directories, which is the inverted direction
49
+ 3. list the importers of each module, and treat a module whose every export has exactly 1 importer as a pass-through candidate for the deletion test
50
+ 4. treat an interface or type re-exported unchanged through 3+ files as a pass-through chain
51
+ 5. check whether the exports of a utility file imported by most modules share 1 domain concept
52
+ 6. read `git log --name-only` and use it twice: a feature whose commits consistently touch 4+ directories is scattered logic, and the directories changing most often are where to start
53
+ 7. name the module owning the rule and the module owning the state for each candidate, and mark the candidate speculative when neither is identifiable
54
+ 8. run these checks rather than guessing from file names
35
55
 
36
56
  checks:
37
57
  - shallow modules — understanding 1 concept requires bouncing across many tiny modules: Medium
38
58
  - shallow modules — a module interface nearly as complex as its implementation: Medium
39
59
  - shallow modules — a pass-through wrapper, manager, helper, or service that hides no complexity: Medium, apply the deletion test
40
60
  - shallow modules — pure functions extracted for testability alone while the real bugs sit in the orchestration: Medium, the extraction bought no locality
61
+ - shallow modules — a DTO type, a domain type, and a mapper between them, where this repository owns both types and their shapes and meanings are identical: Low, the mapper is a pass-through
62
+ - shallow modules — note: a mapper for a type an external contract owns is not a pass-through, whatever the shapes match, and the dependency direction check below owns that case
41
63
  - coupling and seams — coupling leaking across a module interface, where callers have to know implementation details: High
64
+ - coupling and seams — retry, ordering, or compensation decided inside a pure domain computation instead of the orchestrator owning the side effects: Medium
42
65
  - coupling and seams — tests that reach into module internals, or that mock many neighbours to test 1 thing: High
43
66
  - coupling and seams — a public API exporting implementation details, config, ordering constraints, or internal error modes: Medium, a caller should not need them
44
67
  - import and module structure — a barrel-file cycle or a circular import chain that reordering cannot resolve: High
45
68
  - import and module structure — a deep relative import, `../../../`, marking a module not co-located with what it depends on: Low, suggest a path alias or co-location
69
+ - import and module structure — an import reaching into the internal files of another package instead of its declared entry point: Medium, import from the path `package.json#exports` names
70
+ - import and module structure — a barrel re-exporting a whole tree with `export *`, so the module owning a symbol is not identifiable at the import: Low, name the exports explicitly
71
+ - import and module structure — note: a barrel that also closes a cycle is the barrel-file cycle check above, at High, and it is reported once and not twice
46
72
  - locality — a shared utility module mixing unrelated domain concepts: Medium
47
73
  - locality — feature logic split by technical layer, a controller, service, and repo per feature, so that 1 feature change touches 4+ files: Medium
48
74
  - under-engineering — 1 business rule, the same constants and branching, implemented in 2+ modules: Medium, deepen 1 module to own the rule
@@ -51,6 +77,18 @@ checks:
51
77
  - dependency direction — a domain or computation module importing IO directly, `node:fs`, `node:http`, a DB client, or `fetch`, where the classification puts that IO behind a seam: Medium
52
78
  - dependency direction — a shared or leaf module, `utils/`, `types/`, or `core/`, importing from a feature module: High, the inverted direction is how import cycles start
53
79
  - dependency direction — a wire or DTO type from an external API imported deep into a domain module instead of mapped at the seam that owns the external contract: Medium
80
+ - state ownership — 2+ modules mutating 1 entity, cache, or record with no single owning module: High, the write paths cannot be tested or reasoned about apart
81
+ - state ownership — fix: a shared mutable entity, by naming 1 owning module and turning each write into a named command on it
82
+ - composition root — an infrastructure adapter, an HTTP client, a DB client, or a config read, constructed inside a domain module instead of passed in from the entry point: Medium
83
+ - composition root — a service locator or a DI container wiring 1 dependency graph: Low, pass the value or the function the module needs
84
+ - distributed side effects — a multi-step write path with no idempotency key, no ordering rule, and no compensation, where a retry leaves the effects partly applied: High
85
+ - distributed side effects — note: flag it from a named failure scenario, a retry, a timeout, or a crash between 2 steps, and not from the shape of the code
86
+
87
+ non_findings:
88
+ - a module with exactly 1 importer that hides an ordering, an invariant, or a decision: 1 importer starts the deletion test and is not a finding by itself
89
+ - a layer count: the direction of the dependencies is the finding, and a layer holding a real rule is not
90
+ - a port with 1 production adapter whose test double checks the same contract: the double is the second adapter
91
+ - formatting, import ordering, and file naming: `references/code-quality.md` owns them, and they are not architecture findings
54
92
 
55
93
  forbidden_behaviors:
56
94
  - do not invent a domain term: use a function, type, file, or package name that already exists, and prefer one used in adjacent code
@@ -59,6 +97,12 @@ forbidden_behaviors:
59
97
  - do not expose an internal seam through the interface because a test wants it
60
98
  - do not accept a test that has to change whenever the implementation changes: it is testing past the interface
61
99
  - do not touch code for a `needs-confirm` change before showing a diff or a migration plan and getting an explicit go-ahead
100
+ - do not recommend microservices, event sourcing, CQRS, hexagonal architecture, or DDD tactical patterns without a named defect, change scenario, or failure the current shape caused
101
+ - do not propose a rewrite when a staged migration reaches the same shape
102
+ - do not leave a new structure standing beside the old one: every proposal names the step deleting what it replaces
103
+ - do not propose a change contradicting a decision under `docs/adr/` silently: name the ADR and the conflict, and leave the decision to the operator
104
+ - do not report architecture candidates without naming 1 top recommendation and the reason it goes first
105
+ - do not add an import-linting dependency for 1 rule: use `package.json#exports`, the linter the project already runs, or the workspace layout
62
106
 
63
107
  dependency_classification:
64
108
 
@@ -90,13 +134,17 @@ report_format:
90
134
  ```md
91
135
  ### TITLE — Severity
92
136
 
137
+ - **Confidence:** strong | worth-exploring | speculative
93
138
  - **Files:** relative/path/a.ts, relative/path/b.ts
94
139
  - **Problem:** why this causes friction now (not just a pattern name)
140
+ - **Evidence:** the imports, callers, `git log` path, or test the finding rests on
95
141
  - **Proposed deepening:** plain-English description of what would change
96
142
  - **Interface shape:** rough sketch of the new interface (types, methods, key invariants)
97
143
  - **Dependency category:** in-process | local-substitutable | remote-owned | true-external
98
144
  - **Test strategy:** how tests would improve (what tests survive, what gets deleted, what's new)
145
+ - **Migration:** prefactor | vertical slices | expand-contract, and the step deleting the replaced code
99
146
  - **Benefits:** locality gained, leverage gained, test impact
100
147
  - **Trade-offs:** what gets harder, what is genuinely uncertain
101
148
  - **Fixability:** auto | needs-confirm | report-only
149
+ - **Top recommendation:** on exactly 1 entry in the report, the reason this candidate goes first
102
150
  ```