ts-reviewer 1.0.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 +202 -0
- package/dist/cli.js +57 -0
- package/dist/cli.js.map +1 -0
- package/dist/hash.js +11 -0
- package/dist/hash.js.map +1 -0
- package/dist/incoming.js +34 -0
- package/dist/incoming.js.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/io.js +39 -0
- package/dist/io.js.map +1 -0
- package/dist/meta.js +27 -0
- package/dist/meta.js.map +1 -0
- package/dist/paths.js +57 -0
- package/dist/paths.js.map +1 -0
- package/dist/prompt.js +64 -0
- package/dist/prompt.js.map +1 -0
- package/dist/updatePolicy.js +18 -0
- package/dist/updatePolicy.js.map +1 -0
- package/package.json +39 -0
- package/ts-reviewer/SKILL.md +351 -0
- package/ts-reviewer/references/async-patterns.md +64 -0
- package/ts-reviewer/references/code-quality.md +74 -0
- package/ts-reviewer/references/fix-workflow.md +358 -0
- package/ts-reviewer/references/modernization.md +94 -0
- package/ts-reviewer/references/security.md +75 -0
- package/ts-reviewer/references/tsconfig.md +59 -0
- package/ts-reviewer/references/type-safety.md +101 -0
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ts-reviewer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Install the TypeScript Code Reviewer skill for Claude Code, Codex, or Antigravity",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/VirtualMaestro/ts-reviewer"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"ts-reviewer": "dist/cli.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist/**",
|
|
15
|
+
"ts-reviewer/**"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=18"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc -p tsconfig.json",
|
|
22
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
23
|
+
"test": "npm run typecheck",
|
|
24
|
+
"dev": "npm run build && node --enable-source-maps dist/cli.js"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"typescript",
|
|
28
|
+
"code-review",
|
|
29
|
+
"codex",
|
|
30
|
+
"antigravity",
|
|
31
|
+
"claude-code",
|
|
32
|
+
"skill",
|
|
33
|
+
"ts-reviewer"
|
|
34
|
+
],
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^22.0.0",
|
|
37
|
+
"typescript": "^5.9.0"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ts-reviewer
|
|
3
|
+
description: >
|
|
4
|
+
Deep TypeScript code review and auto-fix tool. Three modes: scan (find issues),
|
|
5
|
+
fix (apply fixes from scan report), auto (scan + fix + verify in one pass).
|
|
6
|
+
Supports scoped review: full codebase, uncommitted changes, branch diff (PR review),
|
|
7
|
+
or last N commits. Outputs a prioritized report and can auto-fix issues with
|
|
8
|
+
regression tests and verification.
|
|
9
|
+
Use this skill whenever the user asks to "review", "audit", "check", "lint", "find issues",
|
|
10
|
+
"find problems", "find bugs", "fix issues", "fix code smells", "auto-fix",
|
|
11
|
+
"review and fix", "clean up code", or "review code quality" in a TypeScript project.
|
|
12
|
+
Also trigger when the user mentions "tech debt", "code health", "refactor candidates",
|
|
13
|
+
"security audit", "modernize", "review my changes", "review my PR", "check what I changed",
|
|
14
|
+
"review last commit", or "review uncommitted" in a TypeScript context. Works with pure
|
|
15
|
+
TypeScript 5.9+ codebases — no framework-specific checks (React, Vue, Angular, etc.).
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# TypeScript Code Reviewer
|
|
19
|
+
|
|
20
|
+
A comprehensive, multi-pass code reviewer and auto-fixer for pure TypeScript 5.9+ codebases.
|
|
21
|
+
|
|
22
|
+
## Modes
|
|
23
|
+
|
|
24
|
+
This skill operates in three modes. Detect the mode from the user's request:
|
|
25
|
+
|
|
26
|
+
| User says | Mode |
|
|
27
|
+
|---|---|
|
|
28
|
+
| "review", "find issues", "audit", "scan", "check" | `scan` |
|
|
29
|
+
| "fix issues", "fix the report", "apply fixes", "fix code smells" | `fix` |
|
|
30
|
+
| "review and fix", "auto-fix", "scan and fix", "clean up" | `auto` |
|
|
31
|
+
|
|
32
|
+
**`scan`** — Analyze the codebase and write a report to `code-smells.md`.
|
|
33
|
+
**`fix`** — Read `code-smells.md` and apply fixes with verification.
|
|
34
|
+
**`auto`** — Run scan, then fix, then re-scan to verify. Delete report if clean.
|
|
35
|
+
|
|
36
|
+
## Report File Location
|
|
37
|
+
|
|
38
|
+
- Always write to `code-smells.md` in the project root (not in `.claude/`)
|
|
39
|
+
This ensures the skill works in non-Claude environments and the file is visible regardless of tooling.
|
|
40
|
+
- Recommend the user adds `code-smells.md` to `.gitignore` — it's a review artifact
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## High-Level Workflows
|
|
45
|
+
|
|
46
|
+
### scan
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
Phase 1: Discovery -> understand project structure, config, scope
|
|
50
|
+
Phase 2: Diagnostics -> run tsc, linters, collect machine-reported issues
|
|
51
|
+
Phase 3: Analysis -> spin up specialized sub-agents (or run sequentially)
|
|
52
|
+
Phase 4: Report -> deduplicate, rank, write code-smells.md
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### fix
|
|
56
|
+
|
|
57
|
+
Read `references/fix-workflow.md` before executing fix mode.
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
Step 1: Read code-smells.md (must exist — error if missing)
|
|
61
|
+
Step 2: Detect test runner, run baseline tests
|
|
62
|
+
Step 3: Fix issues file-by-file, write regression tests, run tsc after each file
|
|
63
|
+
Step 4: Run linter, fix lint errors
|
|
64
|
+
Step 5: Run full test suite, compare with baseline, fix regressions
|
|
65
|
+
Step 6: Verification loop — repeat tsc + lint + tests up to 5 iterations
|
|
66
|
+
Step 7: Update code-smells.md (remove fixed, mark failed)
|
|
67
|
+
Do NOT commit, do NOT stage
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### auto
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
1. Run scan -> writes code-smells.md
|
|
74
|
+
2. Show summary to user, ask "proceed with fix?"
|
|
75
|
+
3. If yes -> run fix (reads references/fix-workflow.md for full protocol)
|
|
76
|
+
4. If ALL issues fixed -> delete code-smells.md, report success
|
|
77
|
+
5. If some remain -> code-smells.md stays as audit trail (fixed + remaining)
|
|
78
|
+
Max 2 full scan-fix cycles. If issues persist after 2 cycles, stop.
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Scope Modes
|
|
84
|
+
|
|
85
|
+
The reviewer supports four scope modes. Detect the mode from the user's request.
|
|
86
|
+
If not specified, default to **full codebase**.
|
|
87
|
+
|
|
88
|
+
| User says | Scope mode |
|
|
89
|
+
|---|---|
|
|
90
|
+
| "review my code", "audit the project", "find issues" (no qualifier) | `full` |
|
|
91
|
+
| "review my changes", "check uncommitted", "what I changed" | `uncommitted` |
|
|
92
|
+
| "review my PR", "review my branch", "diff against main" | `branch` |
|
|
93
|
+
| "review last commit", "check last 3 commits", "what did I break" | `commits:N` |
|
|
94
|
+
|
|
95
|
+
### Git commands per scope
|
|
96
|
+
|
|
97
|
+
**`full`** — all `.ts` files:
|
|
98
|
+
```bash
|
|
99
|
+
npx glob '**/*.ts' --ignore '**/node_modules/**'
|
|
100
|
+
# or: git ls-files '*.ts'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**`uncommitted`** — staged + unstaged + untracked:
|
|
104
|
+
```bash
|
|
105
|
+
git diff --name-only HEAD -- '*.ts'
|
|
106
|
+
git ls-files --others --exclude-standard -- '*.ts'
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**`branch`** — current branch vs base:
|
|
110
|
+
```bash
|
|
111
|
+
BASE=$(git rev-parse --verify main 2>/dev/null && echo main || echo master)
|
|
112
|
+
git diff --name-only "$BASE"...HEAD -- '*.ts'
|
|
113
|
+
git diff --name-only HEAD -- '*.ts'
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**`commits:N`** — last N commits:
|
|
117
|
+
```bash
|
|
118
|
+
git diff --name-only HEAD~N..HEAD -- '*.ts'
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Context files (scoped reviews)
|
|
122
|
+
|
|
123
|
+
Analysis scope = diff file list. Reading scope = wider. Always include as read-only:
|
|
124
|
+
|
|
125
|
+
1. `tsconfig.json` (and extended configs)
|
|
126
|
+
2. Files imported by scoped files (one level deep)
|
|
127
|
+
3. Shared type definitions (`types.ts`, `*.d.ts`, `interfaces/`, `shared/`)
|
|
128
|
+
4. `package.json`
|
|
129
|
+
|
|
130
|
+
Context files are NOT analyzed for issues.
|
|
131
|
+
|
|
132
|
+
### Diff-aware severity boost (scoped modes only)
|
|
133
|
+
|
|
134
|
+
Collect changed hunks:
|
|
135
|
+
```bash
|
|
136
|
+
git diff -U0 [appropriate range] -- '*.ts' | grep '^@@'
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
- Issue on **new/modified line**: boost severity +1 (Low→Medium, Medium→High, High→Highest)
|
|
140
|
+
- Issue on **unchanged line**: keep original severity (pre-existing tech debt)
|
|
141
|
+
- Mark boosted issues: `High [boosted, was Medium — new code]`
|
|
142
|
+
- In `full` mode: no boost, all code treated equally
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Phase 1 — Discovery (scan mode)
|
|
147
|
+
|
|
148
|
+
1. **Detect scope mode** from user's request. Build file list.
|
|
149
|
+
If scoped mode yields 0 files, ask whether to fall back to full.
|
|
150
|
+
|
|
151
|
+
2. **Map project tree** — full structure regardless of scope.
|
|
152
|
+
|
|
153
|
+
3. **Read `tsconfig.json`**. Load `references/tsconfig.md` and audit config flags.
|
|
154
|
+
In scoped modes: only flag config if `tsconfig.json` is in diff or if full review.
|
|
155
|
+
|
|
156
|
+
4. **Check for linter configs** — `eslint.config.*`, `.eslintrc.*`, `biome.json`, `deno.json`.
|
|
157
|
+
|
|
158
|
+
5. **Read `package.json`** — TS version, dependencies, module type.
|
|
159
|
+
|
|
160
|
+
6. **Identify entry points** — `index.ts`, `main.ts`, exports in `package.json`.
|
|
161
|
+
|
|
162
|
+
7. **Collect context files** (scoped modes only).
|
|
163
|
+
|
|
164
|
+
Discovery summary:
|
|
165
|
+
```
|
|
166
|
+
Project: <n>
|
|
167
|
+
Scope: full / uncommitted / branch (vs <base>) / commits:<N>
|
|
168
|
+
TS version: <version>
|
|
169
|
+
Module system: ESM / CJS
|
|
170
|
+
Strict mode: yes / partial / no
|
|
171
|
+
Linter: eslint / biome / none
|
|
172
|
+
Test runner: vitest / jest / mocha / node:test / none
|
|
173
|
+
Files in scope: <N> .ts files (+ <M> context files)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Phase 2 — Diagnostics (scan mode)
|
|
179
|
+
|
|
180
|
+
### 2a. TypeScript compiler
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
npx tsc --noEmit 2>&1 | head -200
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Compiler errors -> **Highest**. Warnings -> **High**.
|
|
187
|
+
In scoped modes: run on full project, report only errors in scoped files.
|
|
188
|
+
|
|
189
|
+
### 2b. Linter
|
|
190
|
+
|
|
191
|
+
ESLint: `npx eslint [files] --format json 2>/dev/null | head -500`
|
|
192
|
+
Biome: `npx biome check [files] --reporter json 2>/dev/null | head -500`
|
|
193
|
+
|
|
194
|
+
Map: `error` -> **High**, `warning` -> **Medium**, `info` -> **Low**.
|
|
195
|
+
|
|
196
|
+
### 2c. LSP diagnostics (if available)
|
|
197
|
+
|
|
198
|
+
Query TypeScript LSP via MCP if accessible. Merge with compiler output, deduplicate.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Phase 3 — Analysis (scan mode)
|
|
203
|
+
|
|
204
|
+
Read the corresponding reference file before each analysis pass.
|
|
205
|
+
|
|
206
|
+
| Agent | Reference file | Focus |
|
|
207
|
+
|---|---|---|
|
|
208
|
+
| Type Safety | `references/type-safety.md` | `any`, casts, `!`, exhaustiveness, generics |
|
|
209
|
+
| Security | `references/security.md` | Injection, prototype pollution, ReDoS, path traversal |
|
|
210
|
+
| Async Patterns | `references/async-patterns.md` | Floating promises, race conditions, error propagation |
|
|
211
|
+
| Modernization | `references/modernization.md` | Outdated patterns vs TS 5.9+ idioms |
|
|
212
|
+
| Code Quality | `references/code-quality.md` | Complexity, duplication, naming, dead code |
|
|
213
|
+
| Config | `references/tsconfig.md` | tsconfig.json flags and module setup |
|
|
214
|
+
|
|
215
|
+
### Sub-agent template (Claude Code)
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
You are a specialized TypeScript reviewer focused on [DOMAIN].
|
|
219
|
+
Read the reference checklist: [REFERENCE_PATH]
|
|
220
|
+
Review these files: [FILE_LIST]
|
|
221
|
+
Context files (read-only, do NOT report issues): [CONTEXT_FILE_LIST]
|
|
222
|
+
Scope mode: [full|uncommitted|branch|commits:N]
|
|
223
|
+
|
|
224
|
+
Output JSONL, one object per line:
|
|
225
|
+
{
|
|
226
|
+
"category": "[DOMAIN]",
|
|
227
|
+
"severity": "highest|high|medium|low",
|
|
228
|
+
"title": "Short descriptive title",
|
|
229
|
+
"file": "relative/path.ts",
|
|
230
|
+
"line": 42,
|
|
231
|
+
"snippet": "3-7 lines of code",
|
|
232
|
+
"problem": "One-sentence explanation",
|
|
233
|
+
"fix": "Concrete recommendation with code example",
|
|
234
|
+
"auto_fixable": true|false,
|
|
235
|
+
"in_diff": true|false,
|
|
236
|
+
"reference": "URL or docs ref"
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Sequential mode (no sub-agents)
|
|
241
|
+
|
|
242
|
+
Go through each domain one at a time. Same JSON structure.
|
|
243
|
+
|
|
244
|
+
### File batching
|
|
245
|
+
|
|
246
|
+
- <= 20 scoped files: each agent reviews all files
|
|
247
|
+
- > 20 files: split by directory, ensure shared types visible to all agents
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Phase 4 — Report (scan mode)
|
|
252
|
+
|
|
253
|
+
### Processing
|
|
254
|
+
|
|
255
|
+
1. Apply severity boost (scoped modes only): `in_diff: true` -> boost +1 level.
|
|
256
|
+
2. Deduplicate: same file + line + issue -> keep one.
|
|
257
|
+
3. Merge overlapping: keep higher severity, note overlap.
|
|
258
|
+
4. Consolidate patterns: 3+ identical issues -> one "Recurring Pattern" entry.
|
|
259
|
+
|
|
260
|
+
### Report structure
|
|
261
|
+
|
|
262
|
+
Write to `code-smells.md`:
|
|
263
|
+
|
|
264
|
+
````markdown
|
|
265
|
+
# TypeScript Code Review Report
|
|
266
|
+
|
|
267
|
+
**Project:** <n>
|
|
268
|
+
**Reviewed:** <date>
|
|
269
|
+
**TypeScript version:** <version>
|
|
270
|
+
**Scope:** Full / Uncommitted / Branch `x` vs `y` / Last N commits
|
|
271
|
+
**Files analyzed:** N (+ M context)
|
|
272
|
+
**Total issues:** N (X critical, Y high, Z medium, W low)
|
|
273
|
+
**Severity-boosted:** N (scoped modes only)
|
|
274
|
+
|
|
275
|
+
## Summary
|
|
276
|
+
|
|
277
|
+
<2-3 sentences on codebase health and key patterns>
|
|
278
|
+
|
|
279
|
+
## Highest + High Issues
|
|
280
|
+
|
|
281
|
+
### TITLE — Severity [boosted info if applicable]
|
|
282
|
+
|
|
283
|
+
**Category:** cat | **File:** `path` | **Line:** N | **Auto-fixable:** Yes/No | **New code:** Yes/No
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
// snippet
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Problem:** explanation
|
|
290
|
+
**Fix:** recommendation with code
|
|
291
|
+
**Reference:** link
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Medium Issues
|
|
296
|
+
## Low Issues
|
|
297
|
+
## Recurring Patterns
|
|
298
|
+
## Config Issues
|
|
299
|
+
## Pre-existing Issues (scoped modes only)
|
|
300
|
+
````
|
|
301
|
+
|
|
302
|
+
### Sorting
|
|
303
|
+
|
|
304
|
+
1. By severity group, then category, then file path.
|
|
305
|
+
2. In scoped modes: `in_diff=true` sorts before pre-existing.
|
|
306
|
+
3. If > 15 issues in Medium/Low: show top 10, summarize rest in table.
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Fix Mode
|
|
311
|
+
|
|
312
|
+
**Read `references/fix-workflow.md` before executing.** It contains the complete
|
|
313
|
+
fix protocol: test runner detection, baseline capture, file-by-file fix strategy,
|
|
314
|
+
regression test writing, verification loop, and failure handling.
|
|
315
|
+
|
|
316
|
+
Key principles:
|
|
317
|
+
- Fix reads `code-smells.md` as its work plan (Terraform plan/apply pattern)
|
|
318
|
+
- Fixes are applied file-by-file with `tsc --noEmit` after each file
|
|
319
|
+
- Regression tests are written for each fix where testable
|
|
320
|
+
- Full test suite runs after all fixes, compared against baseline
|
|
321
|
+
- Max 5 verification iterations (tsc + lint + tests)
|
|
322
|
+
- NEVER commit, NEVER stage — user reviews and decides
|
|
323
|
+
- ALL fixed -> delete `code-smells.md` (clean slate)
|
|
324
|
+
- Some remain -> keep `code-smells.md` as audit trail with BEFORE/AFTER for fixed issues,
|
|
325
|
+
status tags for failed/reverted/skipped, and original entries for untouched issues
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Severity Scale
|
|
330
|
+
|
|
331
|
+
| Level | Criteria | Examples |
|
|
332
|
+
|---|---|---|
|
|
333
|
+
| Highest | Active bugs, security vulns, data loss | SQL injection, uncaught rejection, lying type predicate |
|
|
334
|
+
| High | Bugs waiting to happen, edge-case failures | Missing null check, `as` hiding mismatch, floating promise |
|
|
335
|
+
| Medium | Tech debt to clean up in-context | `any` internally, missing exhaustive check, complex function |
|
|
336
|
+
| Low | Style — improve when convenient | Naming, missing readonly, verbose type |
|
|
337
|
+
|
|
338
|
+
In scoped modes: these are base severities before diff-aware boost.
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## Important Guidelines
|
|
343
|
+
|
|
344
|
+
- **No framework checks.** Pure TypeScript only.
|
|
345
|
+
- **No false positives from intentional patterns.** `// @ts-expect-error` with explanation = Low.
|
|
346
|
+
`// @ts-ignore` (legacy) = Medium. Without explanation = Medium.
|
|
347
|
+
- **Respect project conventions.** Don't flag consistent patterns unless harmful.
|
|
348
|
+
- **Be concrete.** Every issue needs a snippet and a fix recommendation.
|
|
349
|
+
"Consider refactoring" is not a valid fix.
|
|
350
|
+
- **Don't flood with noise.** Consolidate identical issues into Recurring Patterns.
|
|
351
|
+
- **Scoped mode focus.** Prioritize diff issues. Pre-existing = informational only.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Async Patterns Checklist
|
|
2
|
+
|
|
3
|
+
## Floating Promises
|
|
4
|
+
|
|
5
|
+
- Async function called without `await`, `.then()`, or `.catch()`.
|
|
6
|
+
Severity: **High**. Fix: `await doWork()` or `void doWork().catch(handleError)`.
|
|
7
|
+
- `items.forEach(async (item) => ...)` — forEach ignores returned promises.
|
|
8
|
+
Severity: **High**. Fix: `for...of` with `await`, or `Promise.all(items.map(...))`.
|
|
9
|
+
- Floating promise in constructor (cannot be async).
|
|
10
|
+
Severity: **High**. Fix: static factory `static async create(): Promise<Foo>`.
|
|
11
|
+
- Async event handler where caller doesn't expect promise.
|
|
12
|
+
Severity: **Medium**. Fix: try/catch inside handler.
|
|
13
|
+
|
|
14
|
+
## Error Handling
|
|
15
|
+
|
|
16
|
+
- `catch(e)` without typing as `unknown` (requires `useUnknownInCatchVariables`).
|
|
17
|
+
Severity: **Medium**.
|
|
18
|
+
- Empty catch blocks: `catch(e) {}`. Severity: **High** (unless commented).
|
|
19
|
+
- `catch` that only logs without rethrowing. Severity: **Medium**.
|
|
20
|
+
- `Promise.allSettled()` ignoring `'rejected'` entries. Severity: **Medium**.
|
|
21
|
+
|
|
22
|
+
## Race Conditions
|
|
23
|
+
|
|
24
|
+
- Multiple async ops modifying shared state without coordination.
|
|
25
|
+
Severity: **High**.
|
|
26
|
+
- `Promise.race()` where losing promise's side effects still execute.
|
|
27
|
+
Severity: **Medium**.
|
|
28
|
+
- Read-modify-write with `await` in the middle. Severity: **High** in concurrent contexts.
|
|
29
|
+
|
|
30
|
+
## Cancellation
|
|
31
|
+
|
|
32
|
+
- Long async ops without `AbortController`/`AbortSignal` support.
|
|
33
|
+
Severity: **Low** (internal), **Medium** (public API).
|
|
34
|
+
- `AbortSignal` accepted but never checked. Severity: **Medium**.
|
|
35
|
+
- Missing cleanup on cancellation (timers, listeners, streams). Severity: **High**.
|
|
36
|
+
|
|
37
|
+
## Promise Utilities
|
|
38
|
+
|
|
39
|
+
- Manual promise + resolve/reject variables where `Promise.withResolvers()` (ES2024) applies.
|
|
40
|
+
Severity: **Low**. Fix: `const { promise, resolve, reject } = Promise.withResolvers()`.
|
|
41
|
+
Note: only flag if TS target is ES2024+ or polyfill is available.
|
|
42
|
+
|
|
43
|
+
## Promise Anti-Patterns
|
|
44
|
+
|
|
45
|
+
- `new Promise()` wrapping async operation (explicit promise constructor anti-pattern).
|
|
46
|
+
Severity: **Low**. Fix: use async/await.
|
|
47
|
+
- `async function() { return await bar(); }` — unnecessary await (except in try/catch).
|
|
48
|
+
Severity: **Low**.
|
|
49
|
+
- Mixing `await` and `.then()` chains in same function. Severity: **Low**.
|
|
50
|
+
- Sequential `await` in loop when iterations are independent.
|
|
51
|
+
Severity: **Medium**. Fix: `Promise.all(items.map(...))` if order doesn't matter.
|
|
52
|
+
|
|
53
|
+
## Async Iterators
|
|
54
|
+
|
|
55
|
+
- Async generator that never yields — should be regular async function. Severity: **Low**.
|
|
56
|
+
- Missing cleanup in async iteration `finally` block. Severity: **Medium**.
|
|
57
|
+
- Async iterator without proper cleanup on early termination (break/return). Severity: **Medium**.
|
|
58
|
+
|
|
59
|
+
## Timer Patterns
|
|
60
|
+
|
|
61
|
+
- `setTimeout`/`setInterval` without storing timer ID. Severity: **Medium**.
|
|
62
|
+
- `setInterval` for async work (calls stack up). Severity: **High**.
|
|
63
|
+
Fix: recursive `setTimeout` after async work completes.
|
|
64
|
+
- `setTimeout(fn, 0)` for async coordination. Severity: **Low**.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Code Quality Checklist
|
|
2
|
+
|
|
3
|
+
## Complexity
|
|
4
|
+
|
|
5
|
+
- Functions > ~50 lines. Severity: **Medium**.
|
|
6
|
+
- Cyclomatic complexity > 10. Severity: **Medium**.
|
|
7
|
+
- Deeply nested callbacks/promises (> 3 levels). Severity: **Medium**.
|
|
8
|
+
- God classes (10+ methods or 500+ lines). Severity: **Medium**.
|
|
9
|
+
- Functions with 5+ parameters — use options object. Severity: **Low**.
|
|
10
|
+
|
|
11
|
+
## Dead Code
|
|
12
|
+
|
|
13
|
+
- Unreachable code after return/throw/break. Severity: **Low**.
|
|
14
|
+
- Commented-out code blocks (> 2-3 lines). Severity: **Low**. Fix: delete (VCS has history).
|
|
15
|
+
- Unused private class members. Severity: **Low**.
|
|
16
|
+
- Exported symbols never imported anywhere. Severity: **Medium**.
|
|
17
|
+
- Empty files or import-only files. Severity: **Low**.
|
|
18
|
+
- Defined but never called functions. Severity: **Medium**.
|
|
19
|
+
|
|
20
|
+
## Naming
|
|
21
|
+
|
|
22
|
+
- Misleading names (`isReady` containing a string). Severity: **Medium**.
|
|
23
|
+
- Single-letter variables outside trivial loops. Severity: **Low**.
|
|
24
|
+
- Inconsistent conventions (mixing camelCase/snake_case). Severity: **Low**.
|
|
25
|
+
- Booleans without `is`/`has`/`should`/`can` prefix. Severity: **Low**.
|
|
26
|
+
- Opaque abbreviations (`usr`, `msg`, `cfg`). Severity: **Low**.
|
|
27
|
+
|
|
28
|
+
## Error Handling
|
|
29
|
+
|
|
30
|
+
- Throwing raw strings. Severity: **Medium**. Fix: `throw new Error(...)`.
|
|
31
|
+
- Custom errors not extending `Error`. Severity: **Medium**.
|
|
32
|
+
- Error messages without context. Severity: **Low**.
|
|
33
|
+
- Missing `cause` chaining (ES2022):
|
|
34
|
+
`catch(e) { throw new Error("msg", { cause: e }); }`. Severity: **Low**.
|
|
35
|
+
|
|
36
|
+
## Duplication
|
|
37
|
+
|
|
38
|
+
- Repeated code blocks (3+ lines in 2+ places). Severity: **Medium**.
|
|
39
|
+
- Copy-pasted logic with minor variations. Severity: **Medium**.
|
|
40
|
+
|
|
41
|
+
## Mutability
|
|
42
|
+
|
|
43
|
+
- `let` where `const` works. Severity: **Low**.
|
|
44
|
+
- Functions mutating input parameters. Severity: **Medium**.
|
|
45
|
+
- Class fields that should be `readonly`. Severity: **Low**.
|
|
46
|
+
- Exported mutable state (`export let count = 0`). Severity: **High**.
|
|
47
|
+
|
|
48
|
+
## Collections and Iteration
|
|
49
|
+
|
|
50
|
+
- `for(let i=0;...)` where `for...of` with `.entries()` or `.map()` is cleaner.
|
|
51
|
+
Severity: **Low**. (Don't flag when the index is genuinely needed for non-sequential access.)
|
|
52
|
+
- Array lookup in hot path — use `Set`/`Map`. Severity: **Medium**.
|
|
53
|
+
- `indexOf(x) !== -1` -> `includes(x)`. Severity: **Low**.
|
|
54
|
+
|
|
55
|
+
## Ad-hoc / Hacky Patterns
|
|
56
|
+
|
|
57
|
+
- Magic numbers without named constants. Severity: **Low**.
|
|
58
|
+
- `setTimeout(..., 100)` as sync mechanism. Severity: **High** (race condition).
|
|
59
|
+
- Try/catch wrapping entire function body. Severity: **Medium**.
|
|
60
|
+
- Collect TODO/FIXME/HACK comments — note total count. Severity: **Low** each.
|
|
61
|
+
- Boolean parameters: `doSomething(true, false, true)`. Severity: **Low**.
|
|
62
|
+
- Platform checks scattered instead of centralized. Severity: **Low**.
|
|
63
|
+
|
|
64
|
+
## Module Structure
|
|
65
|
+
|
|
66
|
+
- Barrel files causing circular dependencies. Severity: **Low** to **Medium**.
|
|
67
|
+
- Circular imports. Severity: **High**.
|
|
68
|
+
- Deep relative imports (`../../../`). Severity: **Low**. Fix: path aliases.
|
|
69
|
+
|
|
70
|
+
## Comments
|
|
71
|
+
|
|
72
|
+
- JSDoc repeating the type info. Severity: **Low**.
|
|
73
|
+
- Comments describing WHAT instead of WHY. Severity: **Low**.
|
|
74
|
+
- Outdated comments not matching code. Severity: **Medium**.
|