@hustle-together/api-dev-tools 3.12.3 → 4.5.1

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.
Files changed (159) hide show
  1. package/.claude/adr-requests/.gitkeep +10 -0
  2. package/.claude/agents/adr-researcher.md +109 -0
  3. package/.claude/agents/visual-analyzer.md +183 -0
  4. package/.claude/api-dev-state.json +7 -463
  5. package/.claude/documentation-audit.json +114 -0
  6. package/.claude/registry.json +289 -0
  7. package/.claude/settings.json +45 -1
  8. package/.claude/workflow-logs/None.json +49 -0
  9. package/.claude/workflow-logs/session-20251230-143727.json +106 -0
  10. package/.skills/adr-deep-research/SKILL.md +351 -0
  11. package/.skills/api-create/SKILL.md +116 -17
  12. package/.skills/api-research/SKILL.md +130 -0
  13. package/.skills/docs-sync/SKILL.md +260 -0
  14. package/.skills/docs-update/SKILL.md +205 -0
  15. package/.skills/hustle-brand/SKILL.md +368 -0
  16. package/.skills/hustle-build/SKILL.md +786 -0
  17. package/.skills/hustle-build-review/SKILL.md +518 -0
  18. package/.skills/parallel-spawn/SKILL.md +212 -0
  19. package/.skills/ralph-continue/SKILL.md +151 -0
  20. package/.skills/ralph-loop/SKILL.md +341 -0
  21. package/.skills/ralph-status/SKILL.md +87 -0
  22. package/.skills/refactor/SKILL.md +59 -0
  23. package/.skills/shadcn/SKILL.md +522 -0
  24. package/.skills/test-all/SKILL.md +210 -0
  25. package/.skills/test-builds/SKILL.md +208 -0
  26. package/.skills/test-debug/SKILL.md +212 -0
  27. package/.skills/test-e2e/SKILL.md +168 -0
  28. package/.skills/test-review/SKILL.md +707 -0
  29. package/.skills/test-unit/SKILL.md +143 -0
  30. package/.skills/test-visual/SKILL.md +301 -0
  31. package/.skills/token-report/SKILL.md +132 -0
  32. package/CHANGELOG.md +575 -0
  33. package/README.md +426 -56
  34. package/bin/cli.js +1538 -88
  35. package/commands/hustle-api-create.md +22 -0
  36. package/commands/hustle-build.md +259 -0
  37. package/commands/hustle-combine.md +81 -2
  38. package/commands/hustle-ui-create-page.md +84 -2
  39. package/commands/hustle-ui-create.md +82 -2
  40. package/hooks/__pycache__/api-workflow-check.cpython-314.pyc +0 -0
  41. package/hooks/__pycache__/auto-answer.cpython-314.pyc +0 -0
  42. package/hooks/__pycache__/cache-research.cpython-314.pyc +0 -0
  43. package/hooks/__pycache__/check-api-routes.cpython-314.pyc +0 -0
  44. package/hooks/__pycache__/check-playwright-setup.cpython-314.pyc +0 -0
  45. package/hooks/__pycache__/check-storybook-setup.cpython-314.pyc +0 -0
  46. package/hooks/__pycache__/check-update.cpython-314.pyc +0 -0
  47. package/hooks/__pycache__/completion-promise-detector.cpython-314.pyc +0 -0
  48. package/hooks/__pycache__/context-capacity-warning.cpython-314.pyc +0 -0
  49. package/hooks/__pycache__/detect-interruption.cpython-314.pyc +0 -0
  50. package/hooks/__pycache__/docs-update-check.cpython-314.pyc +0 -0
  51. package/hooks/__pycache__/enforce-a11y-audit.cpython-314.pyc +0 -0
  52. package/hooks/__pycache__/enforce-brand-guide.cpython-314.pyc +0 -0
  53. package/hooks/__pycache__/enforce-component-type-confirm.cpython-314.pyc +0 -0
  54. package/hooks/__pycache__/enforce-deep-research.cpython-314.pyc +0 -0
  55. package/hooks/__pycache__/enforce-disambiguation.cpython-314.pyc +0 -0
  56. package/hooks/__pycache__/enforce-documentation.cpython-314.pyc +0 -0
  57. package/hooks/__pycache__/enforce-dry-run.cpython-314.pyc +0 -0
  58. package/hooks/__pycache__/enforce-environment.cpython-314.pyc +0 -0
  59. package/hooks/__pycache__/enforce-external-research.cpython-314.pyc +0 -0
  60. package/hooks/__pycache__/enforce-freshness.cpython-314.pyc +0 -0
  61. package/hooks/__pycache__/enforce-interview.cpython-314.pyc +0 -0
  62. package/hooks/__pycache__/enforce-page-components.cpython-314.pyc +0 -0
  63. package/hooks/__pycache__/enforce-page-data-schema.cpython-314.pyc +0 -0
  64. package/hooks/__pycache__/enforce-questions-sourced.cpython-314.pyc +0 -0
  65. package/hooks/__pycache__/enforce-refactor.cpython-314.pyc +0 -0
  66. package/hooks/__pycache__/enforce-research.cpython-314.pyc +0 -0
  67. package/hooks/__pycache__/enforce-schema-from-interview.cpython-314.pyc +0 -0
  68. package/hooks/__pycache__/enforce-schema.cpython-314.pyc +0 -0
  69. package/hooks/__pycache__/enforce-scope.cpython-314.pyc +0 -0
  70. package/hooks/__pycache__/enforce-tdd-red.cpython-314.pyc +0 -0
  71. package/hooks/__pycache__/enforce-ui-disambiguation.cpython-314.pyc +0 -0
  72. package/hooks/__pycache__/enforce-ui-interview.cpython-314.pyc +0 -0
  73. package/hooks/__pycache__/enforce-verify.cpython-314.pyc +0 -0
  74. package/hooks/__pycache__/generate-adr-options.cpython-314.pyc +0 -0
  75. package/hooks/__pycache__/generate-manifest-entry.cpython-314.pyc +0 -0
  76. package/hooks/__pycache__/hook_utils.cpython-314.pyc +0 -0
  77. package/hooks/__pycache__/notify-input-needed.cpython-314.pyc +0 -0
  78. package/hooks/__pycache__/notify-phase-complete.cpython-314.pyc +0 -0
  79. package/hooks/__pycache__/ntfy-on-question.cpython-314.pyc +0 -0
  80. package/hooks/__pycache__/orchestrator-completion.cpython-314.pyc +0 -0
  81. package/hooks/__pycache__/orchestrator-handoff.cpython-314.pyc +0 -0
  82. package/hooks/__pycache__/orchestrator-session-startup.cpython-314.pyc +0 -0
  83. package/hooks/__pycache__/parallel-orchestrator.cpython-314.pyc +0 -0
  84. package/hooks/__pycache__/periodic-reground.cpython-314.pyc +0 -0
  85. package/hooks/__pycache__/project-document-prompt.cpython-314.pyc +0 -0
  86. package/hooks/__pycache__/remote-question-proxy.cpython-314.pyc +0 -0
  87. package/hooks/__pycache__/remote-question-server.cpython-314.pyc +0 -0
  88. package/hooks/__pycache__/run-code-review.cpython-314.pyc +0 -0
  89. package/hooks/__pycache__/run-visual-qa.cpython-314.pyc +0 -0
  90. package/hooks/__pycache__/session-logger.cpython-314.pyc +0 -0
  91. package/hooks/__pycache__/session-startup.cpython-314.pyc +0 -0
  92. package/hooks/__pycache__/track-scope-coverage.cpython-314.pyc +0 -0
  93. package/hooks/__pycache__/track-token-usage.cpython-314.pyc +0 -0
  94. package/hooks/__pycache__/track-tool-use.cpython-314.pyc +0 -0
  95. package/hooks/__pycache__/update-adr-decision.cpython-314.pyc +0 -0
  96. package/hooks/__pycache__/update-api-showcase.cpython-314.pyc +0 -0
  97. package/hooks/__pycache__/update-registry.cpython-314.pyc +0 -0
  98. package/hooks/__pycache__/update-ui-showcase.cpython-314.pyc +0 -0
  99. package/hooks/__pycache__/verify-after-green.cpython-314.pyc +0 -0
  100. package/hooks/__pycache__/verify-implementation.cpython-314.pyc +0 -0
  101. package/hooks/api-workflow-check.py +34 -0
  102. package/hooks/auto-answer.py +305 -0
  103. package/hooks/check-update.py +132 -0
  104. package/hooks/completion-promise-detector.py +293 -0
  105. package/hooks/context-capacity-warning.py +171 -0
  106. package/hooks/docs-update-check.py +120 -0
  107. package/hooks/enforce-dry-run.py +134 -0
  108. package/hooks/enforce-external-research.py +25 -0
  109. package/hooks/enforce-interview.py +20 -0
  110. package/hooks/generate-adr-options.py +282 -0
  111. package/hooks/hook_utils.py +609 -0
  112. package/hooks/lib/__pycache__/__init__.cpython-314.pyc +0 -0
  113. package/hooks/lib/__pycache__/greptile.cpython-314.pyc +0 -0
  114. package/hooks/lib/__pycache__/ntfy.cpython-314.pyc +0 -0
  115. package/hooks/ntfy-on-question.py +240 -0
  116. package/hooks/orchestrator-completion.py +313 -0
  117. package/hooks/orchestrator-handoff.py +267 -0
  118. package/hooks/orchestrator-session-startup.py +146 -0
  119. package/hooks/parallel-orchestrator.py +451 -0
  120. package/hooks/periodic-reground.py +270 -67
  121. package/hooks/project-document-prompt.py +302 -0
  122. package/hooks/remote-question-proxy.py +284 -0
  123. package/hooks/remote-question-server.py +1224 -0
  124. package/hooks/run-code-review.py +176 -29
  125. package/hooks/run-visual-qa.py +338 -0
  126. package/hooks/session-logger.py +27 -1
  127. package/hooks/session-startup.py +113 -0
  128. package/hooks/update-adr-decision.py +236 -0
  129. package/hooks/update-api-showcase.py +13 -1
  130. package/hooks/update-testing-checklist.py +195 -0
  131. package/hooks/update-ui-showcase.py +13 -1
  132. package/package.json +7 -3
  133. package/scripts/extract-schema-docs.cjs +322 -0
  134. package/templates/.skills/hustle-interview/SKILL.md +174 -0
  135. package/templates/CLAUDE-SECTION.md +89 -64
  136. package/templates/adr-viewer/_components/ADRViewer.tsx +326 -0
  137. package/templates/api-dev-state.json +33 -1
  138. package/templates/api-showcase/_components/APIModal.tsx +100 -8
  139. package/templates/api-showcase/_components/APIShowcase.tsx +36 -4
  140. package/templates/api-showcase/_components/APITester.tsx +367 -58
  141. package/templates/brand-page/page.tsx +645 -0
  142. package/templates/component/Component.visual.spec.ts +30 -24
  143. package/templates/docs/page.tsx +230 -0
  144. package/templates/eslint-plugin-zod-schema/index.js +446 -0
  145. package/templates/eslint-plugin-zod-schema/package.json +26 -0
  146. package/templates/github-workflows/security.yml +274 -0
  147. package/templates/hustle-build-defaults.json +136 -0
  148. package/templates/hustle-dev-dashboard/page.tsx +365 -0
  149. package/templates/page/page.e2e.test.ts +30 -26
  150. package/templates/performance-budgets.json +63 -5
  151. package/templates/playwright-report/page.tsx +258 -0
  152. package/templates/registry.json +279 -3
  153. package/templates/review-dashboard/page.tsx +510 -0
  154. package/templates/settings.json +155 -7
  155. package/templates/test-results/page.tsx +237 -0
  156. package/templates/typedoc.json +19 -0
  157. package/templates/ui-showcase/_components/UIShowcase.tsx +48 -1
  158. package/templates/ui-showcase/_components/VisualTestingDashboard.tsx +579 -0
  159. package/templates/ui-showcase/page.tsx +1 -1
@@ -0,0 +1,707 @@
1
+ ---
2
+ name: test-review
3
+ description: AI-powered code review for antipatterns, security, and performance
4
+ tools: Bash, Read, Glob, Grep, Task
5
+ model: sonnet
6
+ ---
7
+
8
+ # Test Review Skill
9
+
10
+ Analyze code for security vulnerabilities, performance issues, antipatterns, and best practice violations using a tiered approach: deterministic ESLint rules + structured AI review.
11
+
12
+ ## When to Use
13
+
14
+ - After implementing a feature
15
+ - Before creating a pull request
16
+ - To audit existing code
17
+ - During code review phase (Phase 11)
18
+
19
+ ## Tiered Strategy for Large Codebases
20
+
21
+ > **Reality Check:** AI cannot hold 5000 files in context at once.
22
+ > We use a tiered approach to ensure comprehensive coverage.
23
+
24
+ ### Tier 1: ESLint (ALL Files - Deterministic)
25
+
26
+ ESLint runs on **every file**, every time. This is fast pattern matching that scales infinitely.
27
+
28
+ ```bash
29
+ # Run on entire codebase
30
+ pnpm eslint src/ --plugin security --plugin no-unsanitized --format json > eslint-report.json
31
+
32
+ # Count files scanned
33
+ jq '.length' eslint-report.json
34
+ ```
35
+
36
+ **What ESLint Catches (100% Coverage):**
37
+ - XSS via innerHTML/insertAdjacentHTML
38
+ - eval() with user input
39
+ - Path traversal via fs calls
40
+ - Prototype pollution via bracket notation
41
+ - Regex DoS patterns
42
+ - Command injection via child_process
43
+
44
+ ### Tier 2: AI Review - Changed Files (Per Commit/PR)
45
+
46
+ Only review files that changed in the current branch/PR.
47
+
48
+ ```bash
49
+ # Get changed files
50
+ git diff --name-only main...HEAD | grep -E '\.(ts|tsx|js|jsx)$'
51
+ ```
52
+
53
+ **Limit:** 50-100 files max per AI review session.
54
+
55
+ ### Tier 3: AI Review - Critical Paths (Always Included)
56
+
57
+ Even if unchanged, always include security-critical files:
58
+
59
+ ```bash
60
+ # Critical paths that ALWAYS get reviewed
61
+ CRITICAL_PATHS=(
62
+ "src/app/api/**/*" # All API routes
63
+ "src/middleware*" # Middleware
64
+ "src/lib/auth*" # Auth utilities
65
+ "src/lib/db*" # Database utilities
66
+ "src/lib/crypto*" # Cryptography
67
+ "src/hooks/useAuth*" # Auth hooks
68
+ )
69
+ ```
70
+
71
+ ### Tier 4: Full Scan (Weekly/Scheduled)
72
+
73
+ For complete codebase audits, batch files:
74
+
75
+ ```bash
76
+ # Split files into batches of 200
77
+ find src -name "*.ts" -o -name "*.tsx" | split -l 200 - batch_
78
+
79
+ # Review each batch separately
80
+ for batch in batch_*; do
81
+ /test-review $(cat $batch | tr '\n' ' ')
82
+ done
83
+ ```
84
+
85
+ **Output:** Aggregate report with all findings across batches.
86
+
87
+ ## How We Know Everything Was Reviewed
88
+
89
+ ### Coverage Tracking
90
+
91
+ ```bash
92
+ # Total files in codebase
93
+ TOTAL=$(find src -name "*.ts" -o -name "*.tsx" | wc -l)
94
+
95
+ # Files covered by ESLint
96
+ ESLINT_COVERED=$(jq '.length' eslint-report.json)
97
+
98
+ # Files reviewed by AI
99
+ AI_REVIEWED=$(cat .claude/review-log.json | jq '.files_reviewed | length')
100
+
101
+ # Coverage report
102
+ echo "ESLint Coverage: $ESLINT_COVERED / $TOTAL (100%)"
103
+ echo "AI Review Coverage: $AI_REVIEWED files (changed + critical)"
104
+ ```
105
+
106
+ ### Review Log (Written After Each Review)
107
+
108
+ ```json
109
+ // .claude/review-log.json
110
+ {
111
+ "last_full_scan": "2025-12-29T10:00:00Z",
112
+ "last_pr_review": "2025-12-29T15:30:00Z",
113
+ "files_reviewed": [
114
+ "src/app/api/users/route.ts",
115
+ "src/lib/auth.ts"
116
+ ],
117
+ "findings_count": {
118
+ "critical": 0,
119
+ "warning": 2,
120
+ "suggestion": 5
121
+ }
122
+ }
123
+ ```
124
+
125
+ ## AI Security Detection Patterns
126
+
127
+ ### What AI Catches (That ESLint Cannot)
128
+
129
+ These require understanding context and data flow:
130
+
131
+ #### 1. SQL Injection
132
+
133
+ ```typescript
134
+ // DETECT: Raw SQL with template literals
135
+ const result = await db.query(`SELECT * FROM users WHERE id = ${userId}`);
136
+
137
+ // SAFE: Parameterized queries
138
+ const result = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
139
+ ```
140
+
141
+ **AI Pattern:** Look for SQL keywords (SELECT, INSERT, UPDATE, DELETE) with template literals containing variables.
142
+
143
+ #### 2. Authentication Bypass
144
+
145
+ ```typescript
146
+ // DETECT: API route without auth check
147
+ export async function GET(request: Request) {
148
+ const data = await fetchSensitiveData();
149
+ return Response.json(data);
150
+ }
151
+
152
+ // SAFE: Auth middleware applied
153
+ export async function GET(request: Request) {
154
+ const session = await auth();
155
+ if (!session) return new Response('Unauthorized', { status: 401 });
156
+ const data = await fetchSensitiveData();
157
+ return Response.json(data);
158
+ }
159
+ ```
160
+
161
+ **AI Pattern:** Check every API route for authentication calls (auth(), getSession(), validateToken()).
162
+
163
+ #### 3. CSRF Vulnerabilities
164
+
165
+ ```typescript
166
+ // DETECT: Mutation without CSRF token
167
+ export async function POST(request: Request) {
168
+ const data = await request.json();
169
+ await updateUser(data);
170
+ }
171
+
172
+ // SAFE: CSRF token validated
173
+ export async function POST(request: Request) {
174
+ const token = request.headers.get('X-CSRF-Token');
175
+ if (!validateCsrfToken(token)) throw new Error('Invalid CSRF');
176
+ const data = await request.json();
177
+ await updateUser(data);
178
+ }
179
+ ```
180
+
181
+ **AI Pattern:** POST/PUT/DELETE endpoints without CSRF validation.
182
+
183
+ #### 4. Insecure Direct Object Reference (IDOR)
184
+
185
+ ```typescript
186
+ // DETECT: No ownership check
187
+ export async function GET(request: Request, { params }: { params: { id: string } }) {
188
+ const order = await getOrder(params.id);
189
+ return Response.json(order);
190
+ }
191
+
192
+ // SAFE: Ownership verified
193
+ export async function GET(request: Request, { params }: { params: { id: string } }) {
194
+ const session = await auth();
195
+ const order = await getOrder(params.id);
196
+ if (order.userId !== session.user.id) {
197
+ return new Response('Forbidden', { status: 403 });
198
+ }
199
+ return Response.json(order);
200
+ }
201
+ ```
202
+
203
+ **AI Pattern:** Route handlers that fetch resources without checking ownership.
204
+
205
+ #### 5. Mass Assignment
206
+
207
+ ```typescript
208
+ // DETECT: Spreading user input to database
209
+ const user = await prisma.user.update({
210
+ where: { id: userId },
211
+ data: { ...request.body } // User could set role: 'admin'
212
+ });
213
+
214
+ // SAFE: Allowlist fields
215
+ const { name, email } = request.body;
216
+ const user = await prisma.user.update({
217
+ where: { id: userId },
218
+ data: { name, email }
219
+ });
220
+ ```
221
+
222
+ **AI Pattern:** Spread operators with user input into database operations.
223
+
224
+ #### 6. Sensitive Data Exposure
225
+
226
+ ```typescript
227
+ // DETECT: Password in response
228
+ return Response.json({ user }); // user object includes password field
229
+
230
+ // SAFE: Exclude sensitive fields
231
+ const { password, ...safeUser } = user;
232
+ return Response.json({ user: safeUser });
233
+ ```
234
+
235
+ **AI Pattern:** API responses that include fields named password, secret, token, key.
236
+
237
+ ## Multi-Pass Review System
238
+
239
+ > **Why Multi-Pass?** Each pass focuses on ONE category. This prevents context dilution
240
+ > and ensures deterministic checklist completion.
241
+
242
+ ### Pass Structure
243
+
244
+ ```
245
+ ┌─────────────────────────────────────────────────────────────────┐
246
+ │ MULTI-PASS REVIEW │
247
+ ├─────────────────────────────────────────────────────────────────┤
248
+ │ │
249
+ │ PASS 1: Logic & Bugs │
250
+ │ ├─ Null/undefined handling │
251
+ │ ├─ Off-by-one errors │
252
+ │ ├─ Race conditions │
253
+ │ ├─ Type coercion issues │
254
+ │ └─ Dead code paths │
255
+ │ │
256
+ │ PASS 2: Security │
257
+ │ ├─ Authentication bypass │
258
+ │ ├─ Authorization gaps │
259
+ │ ├─ Input validation │
260
+ │ ├─ Data exposure │
261
+ │ └─ Injection vulnerabilities │
262
+ │ │
263
+ │ PASS 3: Performance │
264
+ │ ├─ N+1 queries │
265
+ │ ├─ Missing indexes │
266
+ │ ├─ Unbounded loops │
267
+ │ ├─ Memory leaks │
268
+ │ └─ Unnecessary re-renders │
269
+ │ │
270
+ │ PASS 4: Miscellaneous (AI Judgment) │
271
+ │ ├─ Code clarity │
272
+ │ ├─ Pattern consistency │
273
+ │ ├─ Error handling gaps │
274
+ │ └─ Documentation needs │
275
+ │ │
276
+ └─────────────────────────────────────────────────────────────────┘
277
+ ```
278
+
279
+ ### Pass 1: Logic & Bugs (Deterministic Checklist)
280
+
281
+ Each item is a YES/NO question. The AI must answer ALL items.
282
+
283
+ ```markdown
284
+ ## Pass 1: Logic & Bugs Checklist
285
+
286
+ ### Null/Undefined Handling
287
+ - [ ] All optional properties checked before access
288
+ - [ ] Array/object spread on potentially null values
289
+ - [ ] Promise rejections properly caught
290
+ - [ ] Default values provided for destructuring
291
+
292
+ ### Off-by-One Errors
293
+ - [ ] Loop bounds correct (< vs <=)
294
+ - [ ] Array indices valid (0-based accounting)
295
+ - [ ] String slice/substring bounds correct
296
+ - [ ] Pagination offset/limit calculations
297
+
298
+ ### Race Conditions
299
+ - [ ] State updates batched appropriately
300
+ - [ ] Async operations don't have stale closures
301
+ - [ ] Concurrent modifications handled
302
+ - [ ] Loading states prevent double-submits
303
+
304
+ ### Type Coercion
305
+ - [ ] === used instead of == for comparisons
306
+ - [ ] Number parsing handles NaN
307
+ - [ ] Boolean coercion is intentional
308
+ - [ ] String concatenation vs addition clear
309
+
310
+ ### Dead Code
311
+ - [ ] No unreachable code after returns
312
+ - [ ] Switch cases have breaks/returns
313
+ - [ ] Conditional logic can be triggered
314
+ - [ ] Unused variables and imports
315
+ ```
316
+
317
+ ### Pass 2: Security (Deterministic Checklist)
318
+
319
+ ```markdown
320
+ ## Pass 2: Security Checklist
321
+
322
+ ### Authentication
323
+ - [ ] All API routes check session/token validity
324
+ - [ ] JWT tokens verified for expiration
325
+ - [ ] Sensitive routes require re-authentication
326
+ - [ ] Password reset tokens are single-use
327
+
328
+ ### Authorization
329
+ - [ ] Role-based access enforced
330
+ - [ ] Resource ownership verified (IDOR prevention)
331
+ - [ ] Admin routes protected
332
+ - [ ] Elevated actions logged
333
+
334
+ ### Input Validation
335
+ - [ ] User inputs validated with Zod/joi/yup
336
+ - [ ] SQL queries use parameterized statements
337
+ - [ ] File uploads checked (type, size, content)
338
+ - [ ] URL parameters sanitized
339
+
340
+ ### Data Protection
341
+ - [ ] Passwords excluded from API responses
342
+ - [ ] Error messages don't leak internals
343
+ - [ ] Logs sanitized of PII/secrets
344
+ - [ ] HTTPS enforced
345
+
346
+ ### Session Security
347
+ - [ ] Session tokens HTTP-only cookies
348
+ - [ ] CSRF tokens on mutations
349
+ - [ ] Session expiration enforced
350
+ - [ ] Logout invalidates server-side
351
+
352
+ ### API Security
353
+ - [ ] Rate limiting on auth endpoints
354
+ - [ ] CORS allows specific origins only
355
+ - [ ] API keys are environment variables
356
+ - [ ] Webhook signatures verified
357
+ ```
358
+
359
+ ### Pass 3: Performance (Deterministic Checklist)
360
+
361
+ ```markdown
362
+ ## Pass 3: Performance Checklist
363
+
364
+ ### Database
365
+ - [ ] No N+1 queries (use eager loading)
366
+ - [ ] Queries have appropriate indexes
367
+ - [ ] Large result sets paginated
368
+ - [ ] Expensive queries cached
369
+
370
+ ### Memory
371
+ - [ ] Event listeners cleaned up
372
+ - [ ] Large objects garbage collected
373
+ - [ ] Streams used for large files
374
+ - [ ] Subscriptions unsubscribed
375
+
376
+ ### Rendering (React)
377
+ - [ ] useMemo for expensive calculations
378
+ - [ ] useCallback for stable references
379
+ - [ ] Keys on list items are stable
380
+ - [ ] Components split for isolation
381
+
382
+ ### Network
383
+ - [ ] Requests debounced/throttled
384
+ - [ ] Responses compressed
385
+ - [ ] Assets lazy loaded
386
+ - [ ] API calls batched when possible
387
+
388
+ ### Async
389
+ - [ ] Parallel execution where possible
390
+ - [ ] Timeouts on external calls
391
+ - [ ] Retries with backoff
392
+ - [ ] Loading states prevent waterfalls
393
+ ```
394
+
395
+ ### Pass 4: Miscellaneous (AI Judgment)
396
+
397
+ > Unlike Passes 1-3, this pass uses AI judgment for subjective items.
398
+
399
+ ```markdown
400
+ ## Pass 4: Miscellaneous
401
+
402
+ ### Code Clarity
403
+ - Is the code self-documenting?
404
+ - Are variable names descriptive?
405
+ - Are complex algorithms commented?
406
+ - Could any logic be simplified?
407
+
408
+ ### Pattern Consistency
409
+ - Does it follow project conventions?
410
+ - Is error handling consistent?
411
+ - Are similar operations handled similarly?
412
+ - Does it match surrounding code style?
413
+
414
+ ### Error Handling
415
+ - Are all error cases covered?
416
+ - Are errors user-friendly?
417
+ - Is error context preserved?
418
+ - Are failures graceful?
419
+
420
+ ### Documentation Needs
421
+ - Do public APIs have JSDoc?
422
+ - Are complex types documented?
423
+ - Are edge cases noted?
424
+ - Is the README updated if needed?
425
+ ```
426
+
427
+ ## Review Execution
428
+
429
+ ### Sequential Pass Execution
430
+
431
+ ```bash
432
+ # Each pass runs independently and reports findings
433
+ /test-review --pass logic # Pass 1
434
+ /test-review --pass security # Pass 2
435
+ /test-review --pass perf # Pass 3
436
+ /test-review --pass misc # Pass 4
437
+
438
+ # Or run all passes in sequence
439
+ /test-review --all-passes
440
+ ```
441
+
442
+ ### Pass Output Format
443
+
444
+ ```
445
+ ═══════════════════════════════════════════════════════════════
446
+ PASS 1: LOGIC & BUGS
447
+ ═══════════════════════════════════════════════════════════════
448
+
449
+ Files Reviewed: 45
450
+ Time: 2m 34s
451
+
452
+ Checklist Results:
453
+ ┌────────────────────────────────────────────────────┬─────────┐
454
+ │ Item │ Status │
455
+ ├────────────────────────────────────────────────────┼─────────┤
456
+ │ Null/Undefined Handling │ │
457
+ │ ├─ Optional properties checked │ ✅ Pass │
458
+ │ ├─ Spread on null values │ ⚠️ Warn │
459
+ │ ├─ Promise rejections caught │ ✅ Pass │
460
+ │ └─ Default values for destructuring │ ✅ Pass │
461
+ ├────────────────────────────────────────────────────┼─────────┤
462
+ │ Off-by-One Errors │ │
463
+ │ ├─ Loop bounds correct │ ✅ Pass │
464
+ │ ├─ Array indices valid │ ✅ Pass │
465
+ │ ├─ String slice bounds │ ✅ Pass │
466
+ │ └─ Pagination calculations │ ❌ Fail │
467
+ └────────────────────────────────────────────────────┴─────────┘
468
+
469
+ Findings:
470
+ ───────────────────────────────────────────────────────────────
471
+
472
+ ❌ FAIL: Pagination calculations
473
+ File: src/app/api/users/route.ts:67
474
+ Code: const offset = (page - 1) * limit + 1
475
+ Issue: Off-by-one error - offset should not add 1
476
+ Fix: const offset = (page - 1) * limit
477
+
478
+ ⚠️ WARN: Spread on null values
479
+ File: src/lib/merge.ts:23
480
+ Code: const result = { ...maybeNull }
481
+ Issue: maybeNull could be null/undefined
482
+ Fix: const result = { ...(maybeNull ?? {}) }
483
+
484
+ ═══════════════════════════════════════════════════════════════
485
+ Pass 1 Complete: 1 Failure, 1 Warning
486
+ ═══════════════════════════════════════════════════════════════
487
+ ```
488
+
489
+ ### Combined Report
490
+
491
+ After all passes:
492
+
493
+ ```
494
+ ═══════════════════════════════════════════════════════════════
495
+ MULTI-PASS REVIEW SUMMARY
496
+ ═══════════════════════════════════════════════════════════════
497
+
498
+ Pass Results:
499
+ ───────────────────────────────────────────────────────────────
500
+ Pass 1 - Logic & Bugs: 1 ❌ 1 ⚠️ 18 ✅
501
+ Pass 2 - Security: 0 ❌ 2 ⚠️ 22 ✅
502
+ Pass 3 - Performance: 2 ❌ 0 ⚠️ 14 ✅
503
+ Pass 4 - Miscellaneous: 0 ❌ 3 ⚠️ 4 ✅
504
+ ───────────────────────────────────────────────────────────────
505
+ TOTAL: 3 ❌ 6 ⚠️ 58 ✅ (87% Pass Rate)
506
+ ───────────────────────────────────────────────────────────────
507
+
508
+ Critical Issues (Must Fix):
509
+ 1. [Logic] Off-by-one in pagination (users/route.ts:67)
510
+ 2. [Perf] N+1 query in orders loop (orders/route.ts:34)
511
+ 3. [Perf] Missing useCallback causing re-renders (Dashboard.tsx:89)
512
+
513
+ Warnings (Should Fix):
514
+ 1. [Logic] Spread on potential null (merge.ts:23)
515
+ 2. [Security] CORS allows localhost in prod (middleware.ts:12)
516
+ 3. [Security] Session cookie missing SameSite (auth.ts:45)
517
+ 4. [Misc] Complex function needs comment (utils.ts:123)
518
+ 5. [Misc] Inconsistent error handling (api/orders)
519
+ 6. [Misc] Missing JSDoc on public API (types.ts)
520
+
521
+ ═══════════════════════════════════════════════════════════════
522
+ ```
523
+
524
+ ## Execution Steps
525
+
526
+ ### Step 1: Run ESLint Security Scan (All Files)
527
+
528
+ ```bash
529
+ # Ensure security plugins installed
530
+ pnpm add -D eslint-plugin-security eslint-plugin-no-unsanitized
531
+
532
+ # Run full scan
533
+ pnpm eslint src/ --plugin security --plugin no-unsanitized --format json > eslint-security.json
534
+
535
+ # Count issues
536
+ CRITICAL=$(jq '[.[] | .messages[] | select(.severity == 2)] | length' eslint-security.json)
537
+ echo "ESLint found $CRITICAL critical issues"
538
+ ```
539
+
540
+ ### Step 2: Identify Files for AI Review
541
+
542
+ ```bash
543
+ # Changed files
544
+ CHANGED=$(git diff --name-only main...HEAD | grep -E '\.(ts|tsx|js|jsx)$')
545
+
546
+ # Critical paths (always review)
547
+ CRITICAL_PATHS="src/app/api src/middleware src/lib/auth"
548
+
549
+ # Combine and deduplicate
550
+ FILES_TO_REVIEW=$(echo "$CHANGED" "$CRITICAL_PATHS" | tr ' ' '\n' | sort -u)
551
+ ```
552
+
553
+ ### Step 3: Spawn AI Review (Batched if Needed)
554
+
555
+ ```javascript
556
+ // If > 100 files, batch
557
+ const batches = chunk(filesToReview, 100);
558
+
559
+ for (const batch of batches) {
560
+ Task({
561
+ subagent_type: "code-reviewer",
562
+ model: "sonnet",
563
+ prompt: `Review these files using the security checklist:
564
+ ${batch.join('\n')}
565
+
566
+ Check for:
567
+ 1. SQL Injection (template literals with SQL)
568
+ 2. Auth Bypass (API routes without auth)
569
+ 3. CSRF (mutations without token validation)
570
+ 4. IDOR (no ownership verification)
571
+ 5. Mass Assignment (spreading user input)
572
+ 6. Data Exposure (passwords in responses)
573
+
574
+ Return JSON: {findings: [{file, line, type, severity, detail, fix}]}`
575
+ });
576
+ }
577
+ ```
578
+
579
+ ### Step 4: Generate Coverage Report
580
+
581
+ ```
582
+ ═══════════════════════════════════════════════════════════════
583
+ SECURITY REVIEW REPORT
584
+ ═══════════════════════════════════════════════════════════════
585
+
586
+ Coverage:
587
+ ───────────────────────────────────────────────────────────────
588
+ ESLint (Deterministic): 1,234 / 1,234 files (100%)
589
+ AI Review (Changed): 45 files
590
+ AI Review (Critical Paths): 12 files
591
+ ───────────────────────────────────────────────────────────────
592
+
593
+ ESLint Findings:
594
+ ───────────────────────────────────────────────────────────────
595
+ ✅ No critical issues
596
+ ⚠️ 2 warnings (see eslint-security.json)
597
+ ───────────────────────────────────────────────────────────────
598
+
599
+ AI Review Findings:
600
+ ───────────────────────────────────────────────────────────────
601
+ 🔴 Critical: 1
602
+ - src/app/api/users/route.ts:45 - SQL Injection
603
+ Code: `SELECT * FROM users WHERE id = ${userId}`
604
+ Fix: Use parameterized query
605
+
606
+ 🟠 Warning: 2
607
+ - src/app/api/orders/route.ts:23 - Missing ownership check
608
+ - src/lib/auth.ts:89 - Session token not HTTP-only
609
+
610
+ 🟡 Suggestion: 3
611
+ - src/hooks/useData.ts:12 - Add error boundary
612
+ ───────────────────────────────────────────────────────────────
613
+
614
+ Last Full Scan: 2025-12-29
615
+ Next Scheduled: 2026-01-05 (weekly)
616
+
617
+ ═══════════════════════════════════════════════════════════════
618
+ ```
619
+
620
+ ## Arguments
621
+
622
+ | Argument | Description | Default |
623
+ |----------|-------------|---------|
624
+ | `[files]` | Specific files to review | Changed files |
625
+ | `--security` | Security-focused review | false |
626
+ | `--performance` | Performance-focused review | false |
627
+ | `--all` | Review all files (batched) | false |
628
+ | `--full-scan` | Force full codebase scan | false |
629
+
630
+ ## Examples
631
+
632
+ ```bash
633
+ # Review changed files + critical paths
634
+ /test-review
635
+
636
+ # Security audit only
637
+ /test-review --security
638
+
639
+ # Full codebase scan (batched)
640
+ /test-review --full-scan
641
+
642
+ # Review specific file
643
+ /test-review src/app/api/users/route.ts
644
+ ```
645
+
646
+ ## Autonomous Loop Completion (Ralph Wiggum Pattern)
647
+
648
+ When running in autonomous mode (`--auto` flag or `/ralph-loop`), this skill supports
649
+ self-terminating loops for iterative code review cycles.
650
+
651
+ ### Promise Signal
652
+
653
+ After completing all passes and addressing all findings, output:
654
+
655
+ ```
656
+ <promise>REVIEW_CLEAN</promise>
657
+ ```
658
+
659
+ This signal is detected by the `completion-promise-detector.py` hook, which:
660
+ 1. Records the promise in `.claude/completion-promises.json`
661
+ 2. Allows graceful workflow termination
662
+ 3. Prevents infinite review loops
663
+
664
+ ### When to Output the Promise
665
+
666
+ Output `<promise>REVIEW_CLEAN</promise>` when:
667
+ - All 4 passes have been executed
668
+ - All critical issues have been fixed
669
+ - Re-review confirms no new issues
670
+ - The codebase is ready for merge
671
+
672
+ ### Iterative Review Loop
673
+
674
+ ```
675
+ ┌─────────────────────────────────────────────────────────────────┐
676
+ │ REVIEW LOOP (Ralph Wiggum) │
677
+ ├─────────────────────────────────────────────────────────────────┤
678
+ │ │
679
+ │ 1. Run multi-pass review │
680
+ │ └─ Findings? → Fix issues │
681
+ │ │
682
+ │ 2. Re-run review on changed files │
683
+ │ └─ New findings? → Loop back to step 1 │
684
+ │ │
685
+ │ 3. All clean? │
686
+ │ └─ Output: <promise>REVIEW_CLEAN</promise> │
687
+ │ └─ Hook detects → Workflow terminates gracefully │
688
+ │ │
689
+ └─────────────────────────────────────────────────────────────────┘
690
+ ```
691
+
692
+ **Credit:** Ralph Wiggum pattern by [Geoffrey Huntley](https://ghuntley.com/ralph/)
693
+
694
+ ## Integration
695
+
696
+ This skill is invoked during:
697
+ - Phase 11 (Code Review) of all workflows
698
+ - `/test-all` final step
699
+ - Weekly scheduled audits (CI/CD)
700
+
701
+ ## See Also
702
+
703
+ - `/test-all` - Complete test suite
704
+ - `/test-debug` - Debug issues
705
+ - `/ralph-loop` - Autonomous loop execution
706
+ - [docs/AUTONOMOUS_LOOPS.md](../../docs/AUTONOMOUS_LOOPS.md) - Pattern documentation
707
+ - [OWASP Top 10](https://owasp.org/www-project-top-ten/)