sequant 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.
Files changed (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +237 -0
  3. package/dist/bin/cli.d.ts +8 -0
  4. package/dist/bin/cli.d.ts.map +1 -0
  5. package/dist/bin/cli.js +70 -0
  6. package/dist/bin/cli.js.map +1 -0
  7. package/dist/src/commands/doctor.d.ts +8 -0
  8. package/dist/src/commands/doctor.d.ts.map +1 -0
  9. package/dist/src/commands/doctor.js +171 -0
  10. package/dist/src/commands/doctor.js.map +1 -0
  11. package/dist/src/commands/init.d.ts +11 -0
  12. package/dist/src/commands/init.d.ts.map +1 -0
  13. package/dist/src/commands/init.js +124 -0
  14. package/dist/src/commands/init.js.map +1 -0
  15. package/dist/src/commands/run.d.ts +18 -0
  16. package/dist/src/commands/run.d.ts.map +1 -0
  17. package/dist/src/commands/run.js +229 -0
  18. package/dist/src/commands/run.js.map +1 -0
  19. package/dist/src/commands/status.d.ts +5 -0
  20. package/dist/src/commands/status.d.ts.map +1 -0
  21. package/dist/src/commands/status.js +45 -0
  22. package/dist/src/commands/status.js.map +1 -0
  23. package/dist/src/commands/update.d.ts +10 -0
  24. package/dist/src/commands/update.d.ts.map +1 -0
  25. package/dist/src/commands/update.js +124 -0
  26. package/dist/src/commands/update.js.map +1 -0
  27. package/dist/src/index.d.ts +15 -0
  28. package/dist/src/index.d.ts.map +1 -0
  29. package/dist/src/index.js +13 -0
  30. package/dist/src/index.js.map +1 -0
  31. package/dist/src/lib/fs.d.ts +10 -0
  32. package/dist/src/lib/fs.d.ts.map +1 -0
  33. package/dist/src/lib/fs.js +44 -0
  34. package/dist/src/lib/fs.js.map +1 -0
  35. package/dist/src/lib/manifest.d.ts +14 -0
  36. package/dist/src/lib/manifest.d.ts.map +1 -0
  37. package/dist/src/lib/manifest.js +37 -0
  38. package/dist/src/lib/manifest.js.map +1 -0
  39. package/dist/src/lib/stacks.d.ts +22 -0
  40. package/dist/src/lib/stacks.d.ts.map +1 -0
  41. package/dist/src/lib/stacks.js +131 -0
  42. package/dist/src/lib/stacks.js.map +1 -0
  43. package/dist/src/lib/templates.d.ts +16 -0
  44. package/dist/src/lib/templates.d.ts.map +1 -0
  45. package/dist/src/lib/templates.js +118 -0
  46. package/dist/src/lib/templates.js.map +1 -0
  47. package/dist/src/lib/workflow/cli-args.d.ts +138 -0
  48. package/dist/src/lib/workflow/cli-args.d.ts.map +1 -0
  49. package/dist/src/lib/workflow/cli-args.js +210 -0
  50. package/dist/src/lib/workflow/cli-args.js.map +1 -0
  51. package/dist/src/lib/workflow/execute-issues.d.ts +42 -0
  52. package/dist/src/lib/workflow/execute-issues.d.ts.map +1 -0
  53. package/dist/src/lib/workflow/execute-issues.js +463 -0
  54. package/dist/src/lib/workflow/execute-issues.js.map +1 -0
  55. package/dist/src/lib/workflow/logger.d.ts +168 -0
  56. package/dist/src/lib/workflow/logger.d.ts.map +1 -0
  57. package/dist/src/lib/workflow/logger.js +249 -0
  58. package/dist/src/lib/workflow/logger.js.map +1 -0
  59. package/dist/src/lib/workflow/types.d.ts +89 -0
  60. package/dist/src/lib/workflow/types.d.ts.map +1 -0
  61. package/dist/src/lib/workflow/types.js +23 -0
  62. package/dist/src/lib/workflow/types.js.map +1 -0
  63. package/package.json +69 -0
  64. package/stacks/go.yaml +22 -0
  65. package/stacks/nextjs.yaml +28 -0
  66. package/stacks/python.yaml +24 -0
  67. package/stacks/rust.yaml +23 -0
  68. package/templates/hooks/post-tool.sh +301 -0
  69. package/templates/hooks/pre-tool.sh +350 -0
  70. package/templates/memory/constitution.md +60 -0
  71. package/templates/scripts/cleanup-worktree.sh +78 -0
  72. package/templates/scripts/list-worktrees.sh +50 -0
  73. package/templates/scripts/new-feature.sh +156 -0
  74. package/templates/settings.json +26 -0
  75. package/templates/skills/assess/SKILL.md +428 -0
  76. package/templates/skills/clean/SKILL.md +196 -0
  77. package/templates/skills/docs/SKILL.md +323 -0
  78. package/templates/skills/exec/SKILL.md +426 -0
  79. package/templates/skills/fullsolve/SKILL.md +479 -0
  80. package/templates/skills/loop/SKILL.md +310 -0
  81. package/templates/skills/qa/SKILL.md +261 -0
  82. package/templates/skills/qa/references/code-quality-exemplars.md +112 -0
  83. package/templates/skills/qa/references/code-review-checklist.md +77 -0
  84. package/templates/skills/qa/references/quality-gates.md +95 -0
  85. package/templates/skills/qa/references/testing-requirements.md +109 -0
  86. package/templates/skills/qa/scripts/quality-checks.sh +109 -0
  87. package/templates/skills/reflect/SKILL.md +159 -0
  88. package/templates/skills/reflect/references/documentation-tiers.md +70 -0
  89. package/templates/skills/reflect/references/phase-reflection.md +95 -0
  90. package/templates/skills/reflect/scripts/workflow-queries.ts +165 -0
  91. package/templates/skills/security-review/SKILL.md +344 -0
  92. package/templates/skills/security-review/references/security-checklists.md +377 -0
  93. package/templates/skills/solve/SKILL.md +242 -0
  94. package/templates/skills/spec/SKILL.md +169 -0
  95. package/templates/skills/spec/references/parallel-groups.md +72 -0
  96. package/templates/skills/spec/references/verification-criteria.md +104 -0
  97. package/templates/skills/test/SKILL.md +508 -0
  98. package/templates/skills/testgen/SKILL.md +561 -0
  99. package/templates/skills/verify/SKILL.md +266 -0
@@ -0,0 +1,561 @@
1
+ ---
2
+ name: testgen
3
+ description: "Generate test stubs from /spec verification criteria"
4
+ license: MIT
5
+ metadata:
6
+ author: sequant
7
+ version: "1.0"
8
+ allowed-tools:
9
+ - Read
10
+ - Write
11
+ - Edit
12
+ - Glob
13
+ - Grep
14
+ - Bash(gh issue view:*)
15
+ - Bash(gh issue comment:*)
16
+ - Bash(npm test:*)
17
+ - Bash(git worktree list:*)
18
+ - Bash(ls:*)
19
+ - Bash(mkdir:*)
20
+ - mcp__supabase__*
21
+ ---
22
+
23
+ # Test Generation Command
24
+
25
+ You are the "Test Generation Agent" for the current repository.
26
+
27
+ ## Purpose
28
+
29
+ When invoked as `/testgen <issue-number>`, your job is to:
30
+
31
+ 1. Read verification criteria from the latest `/spec` comment on the GitHub issue
32
+ 2. Parse each AC's verification method and test scenario
33
+ 3. Generate appropriate test stubs based on verification method type
34
+ 4. Output stubs to the correct directories with TODO markers
35
+ 5. Post a summary comment to the GitHub issue
36
+
37
+ ## Invocation
38
+
39
+ - `/testgen 123` - Generate test stubs for issue #123 based on /spec comment
40
+ - `/testgen` - Generate stubs for the most recently discussed issue in conversation
41
+
42
+ ## Workflow
43
+
44
+ ### Step 1: Read Verification Criteria from GitHub Issue
45
+
46
+ ```bash
47
+ gh issue view <issue-number> --json comments --jq '.comments | reverse | .[0].body'
48
+ ```
49
+
50
+ Look for the `/spec` planning comment containing verification criteria blocks:
51
+
52
+ ```markdown
53
+ ### AC-1: [Description]
54
+
55
+ **Verification Method:** Unit Test | Integration Test | Manual Test | Browser Test
56
+
57
+ **Test Scenario:**
58
+ - Given: [Initial state]
59
+ - When: [Action]
60
+ - Then: [Expected outcome]
61
+
62
+ **Integration Points:**
63
+ - [External system or component]
64
+
65
+ **Assumptions to Validate:**
66
+ - [ ] [Assumption 1]
67
+ - [ ] [Assumption 2]
68
+ ```
69
+
70
+ ### Step 2: Parse Verification Criteria
71
+
72
+ For each AC, extract:
73
+ - **AC number and description**
74
+ - **Verification method** (Unit Test, Integration Test, Browser Test, Manual Test, N/A)
75
+ - **Test scenario** (Given/When/Then)
76
+ - **Integration points**
77
+ - **Assumptions to validate**
78
+
79
+ ### Step 2.1: Identify Failure Scenarios from /spec
80
+
81
+ Scan the `/spec` comment for failure scenarios to generate additional test stubs:
82
+
83
+ **Explicit Error Handling Sections:**
84
+ Look for these section headers in the `/spec` output:
85
+ - "Error handling"
86
+ - "Edge cases"
87
+ - "What could go wrong"
88
+ - "Risks & Mitigations"
89
+
90
+ Extract scenarios from these sections and add as failure path stubs.
91
+
92
+ **Negative Requirements:**
93
+ Look for patterns indicating what should NOT happen:
94
+ - "should NOT allow"
95
+ - "must NOT"
96
+ - "reject"
97
+ - "block"
98
+ - "prevent"
99
+ - "deny"
100
+ - "fail when"
101
+ - "throw when"
102
+
103
+ Each negative requirement becomes a failure path test stub.
104
+
105
+ **Inferred Failure Scenarios:**
106
+ Based on the action verb in each AC, infer common failure scenarios:
107
+
108
+ | Action Verb | Happy Path | Inferred Failure Paths |
109
+ |-------------|------------|------------------------|
110
+ | Create | Successfully creates X | - Fail to create when invalid input<br>- Handle duplicate X<br>- Reject unauthorized create |
111
+ | Fetch/Read | Returns X data | - Handle missing X (404)<br>- Handle fetch timeout<br>- Handle malformed response |
112
+ | Update | Successfully updates X | - Reject update with invalid data<br>- Handle concurrent updates<br>- Reject unauthorized update |
113
+ | Delete | Successfully deletes X | - Handle delete of non-existent X<br>- Handle delete when X is in use<br>- Reject unauthorized delete |
114
+ | Submit | Successfully submits form | - Show validation errors<br>- Handle server rejection<br>- Handle network timeout |
115
+ | Authenticate | Login succeeds | - Reject invalid credentials<br>- Handle locked account<br>- Handle session timeout |
116
+
117
+ ### Step 3: Generate Test Stubs by Verification Method
118
+
119
+ #### Unit Test → Jest stub in `__tests__/`
120
+
121
+ **Output file:** `__tests__/[feature-name].test.ts`
122
+
123
+ **Template:**
124
+ ```typescript
125
+ // Generated test stub for Issue #<issue-number>
126
+ // AC-<N>: <description>
127
+ // Run with: npm test -- __tests__/<feature-name>.test.ts
128
+
129
+ describe('<Feature Name>', () => {
130
+ describe('AC-<N>: <description>', () => {
131
+ it('should <expected behavior from Then clause>', () => {
132
+ // Given: <initial state>
133
+ // TODO: Set up test fixtures
134
+
135
+ // When: <action>
136
+ // TODO: Call the function/method being tested
137
+
138
+ // Then: <expected outcome>
139
+ // TODO: Add assertions
140
+
141
+ throw new Error('Test stub - implement this test');
142
+ });
143
+
144
+ // === FAILURE PATHS ===
145
+ describe('error handling', () => {
146
+ it('should throw when <invalid condition>', () => {
147
+ // Given: <invalid input or state>
148
+ // TODO: Set up invalid test conditions
149
+
150
+ // When: <action with invalid input>
151
+ // TODO: Call the function with invalid input
152
+
153
+ // Then: <error thrown or graceful failure>
154
+ // TODO: Expect error to be thrown or handled gracefully
155
+
156
+ throw new Error('Failure path stub - implement this test');
157
+ });
158
+
159
+ it('should return null/empty when <edge case>', () => {
160
+ // Given: <edge case condition>
161
+ // TODO: Set up edge case (empty array, null input, etc.)
162
+
163
+ // When: <action>
164
+ // TODO: Call the function
165
+
166
+ // Then: <graceful handling>
167
+ // TODO: Assert null, empty, or default value returned
168
+
169
+ throw new Error('Edge case stub - implement this test');
170
+ });
171
+ });
172
+ });
173
+ });
174
+ ```
175
+
176
+ #### Integration Test → Template in `__tests__/integration/`
177
+
178
+ **Output file:** `__tests__/integration/[feature-name].integration.test.ts`
179
+
180
+ **Template:**
181
+ ```typescript
182
+ // Generated integration test stub for Issue #<issue-number>
183
+ // AC-<N>: <description>
184
+ // Run with: npm test -- __tests__/integration/<feature-name>.integration.test.ts
185
+
186
+ import { exec } from 'child_process';
187
+ import * as fs from 'fs';
188
+ import * as path from 'path';
189
+ import { promisify } from 'util';
190
+
191
+ const execAsync = promisify(exec);
192
+
193
+ describe('<Feature Name> - Integration', () => {
194
+ // === SANDBOX ISOLATION ===
195
+ // Each test run gets a unique temp directory to prevent test pollution
196
+ // and support parallel test execution.
197
+ const TEST_DIR = `/tmp/sequant-test-${process.pid}-${Date.now()}`;
198
+
199
+ // Integration Points:
200
+ // - <integration point 1>
201
+ // - <integration point 2>
202
+
203
+ // Assumptions to Validate:
204
+ // - [ ] <assumption 1>
205
+ // - [ ] <assumption 2>
206
+
207
+ beforeAll(async () => {
208
+ // Create isolated test directory
209
+ fs.mkdirSync(TEST_DIR, { recursive: true });
210
+ process.env.TEST_TMP_DIR = TEST_DIR;
211
+
212
+ // TODO: Set up integration test environment
213
+ // - Ensure external dependencies are available
214
+ // - Set up test data/fixtures
215
+ });
216
+
217
+ afterAll(async () => {
218
+ // TODO: Clean up integration test environment
219
+ // - Remove test data
220
+ // - Reset external state
221
+
222
+ // DEBUGGING: Comment out the next line to inspect test artifacts after failure
223
+ fs.rmSync(TEST_DIR, { recursive: true, force: true });
224
+ delete process.env.TEST_TMP_DIR;
225
+ });
226
+
227
+ // For database isolation (future): Create test schema in beforeAll,
228
+ // drop in afterAll. Pattern: `test_schema_${process.pid}_${Date.now()}`
229
+
230
+ describe('AC-<N>: <description>', () => {
231
+ it('should <expected behavior from Then clause>', async () => {
232
+ // Given: <initial state>
233
+ // TODO: Set up test preconditions
234
+ // Use TEST_DIR for any file operations, e.g.:
235
+ // const testFile = path.join(TEST_DIR, 'test-output.log');
236
+
237
+ // When: <action>
238
+ // TODO: Execute the integration action
239
+
240
+ // Then: <expected outcome>
241
+ // TODO: Verify integration result
242
+
243
+ throw new Error('Integration test stub - implement this test');
244
+ });
245
+
246
+ // Assumption validation tests
247
+ it('validates assumption: <assumption 1>', async () => {
248
+ // TODO: Verify this assumption holds true
249
+ // This test documents and validates a critical assumption
250
+
251
+ throw new Error('Assumption validation stub - implement this test');
252
+ });
253
+ });
254
+
255
+ // === ERROR SCENARIOS ===
256
+ describe('error scenarios', () => {
257
+ it('should handle <external service failure>', async () => {
258
+ // Given: <external dependency is unavailable/erroring>
259
+ // TODO: Mock external service to return error
260
+
261
+ // When: <action that depends on external service>
262
+ // TODO: Execute the integration action
263
+
264
+ // Then: <graceful degradation or clear error>
265
+ // TODO: Verify error is caught and handled appropriately
266
+
267
+ throw new Error('Error scenario stub - implement this test');
268
+ });
269
+
270
+ it('should recover from <transient failure>', async () => {
271
+ // Given: <temporary failure condition>
272
+ // TODO: Simulate transient failure (network timeout, temporary 503)
273
+
274
+ // When: <action with retry logic>
275
+ // TODO: Execute with potential retry
276
+
277
+ // Then: <successful recovery or clear failure after retries>
278
+ // TODO: Verify retry behavior or graceful degradation
279
+
280
+ throw new Error('Recovery stub - implement this test');
281
+ });
282
+
283
+ it('should handle concurrent operations safely', async () => {
284
+ // Given: <multiple simultaneous operations>
285
+ // TODO: Set up parallel execution
286
+
287
+ // When: <concurrent actions>
288
+ // TODO: Run operations in parallel
289
+
290
+ // Then: <no data corruption, proper isolation>
291
+ // TODO: Verify data integrity
292
+
293
+ throw new Error('Concurrency stub - implement this test');
294
+ });
295
+ });
296
+ });
297
+ ```
298
+
299
+ #### Browser Test → Scenarios for `/test` command
300
+
301
+ **Output:** GitHub comment with test scenarios (not a file)
302
+
303
+ **Template:**
304
+ ```markdown
305
+ ## Browser Test Scenarios for AC-<N>
306
+
307
+ **For use with `/test <issue-number>`**
308
+
309
+ ### Scenario 1: <scenario name>
310
+
311
+ **Given:**
312
+ - <precondition 1>
313
+ - <precondition 2>
314
+
315
+ **Steps:**
316
+ 1. Navigate to <URL>
317
+ 2. <action 1>
318
+ 3. <action 2>
319
+
320
+ **Expected:**
321
+ - [ ] <verification 1>
322
+ - [ ] <verification 2>
323
+
324
+ **Chrome DevTools MCP Commands:**
325
+ ```javascript
326
+ // Navigation
327
+ mcp__chrome-devtools__navigate_page({ url: "<URL>" })
328
+
329
+ // Snapshot to find elements
330
+ mcp__chrome-devtools__take_snapshot()
331
+
332
+ // Interact with elements
333
+ mcp__chrome-devtools__click({ uid: "<element-uid>" })
334
+ mcp__chrome-devtools__fill({ uid: "<input-uid>", value: "<test-value>" })
335
+
336
+ // Verify results
337
+ mcp__chrome-devtools__take_screenshot()
338
+ ```
339
+
340
+ ### Negative Test Scenarios
341
+
342
+ **Scenario: Invalid form submission**
343
+ - Given: Form is displayed with required fields
344
+ - When: Submit with empty required fields
345
+ - Expected:
346
+ - [ ] Validation errors displayed inline
347
+ - [ ] Form not submitted to server
348
+ - [ ] Focus moves to first error field
349
+ - [ ] Error message is descriptive
350
+
351
+ **Scenario: Unauthorized access attempt**
352
+ - Given: User is not logged in / lacks permission
353
+ - When: Navigate to protected route directly
354
+ - Expected:
355
+ - [ ] Redirect to login or access denied page
356
+ - [ ] No protected content visible in DOM
357
+ - [ ] Appropriate error message shown
358
+ - [ ] No sensitive data in network requests
359
+
360
+ **Scenario: Network failure graceful degradation**
361
+ - Given: Page is loaded successfully
362
+ - When: Network becomes unavailable during action
363
+ - Expected:
364
+ - [ ] User-friendly error message displayed
365
+ - [ ] No unhandled exceptions in console
366
+ - [ ] Retry option available (if applicable)
367
+ - [ ] User can recover by retrying
368
+ ```
369
+
370
+ #### Manual Test → Checklist
371
+
372
+ **Output:** GitHub comment with checklist (not a file)
373
+
374
+ **Template:**
375
+ ```markdown
376
+ ## Manual Test Checklist for AC-<N>
377
+
378
+ ### Prerequisites
379
+ - [ ] <prerequisite 1>
380
+ - [ ] <prerequisite 2>
381
+
382
+ ### Test Steps
383
+ 1. **Setup:** <setup step>
384
+ 2. **Action:** <action to perform>
385
+ 3. **Verify:** <what to check>
386
+
387
+ ### Expected Results
388
+ - [ ] <expected result 1>
389
+ - [ ] <expected result 2>
390
+
391
+ ### Error Handling Verification
392
+ - [ ] Invalid input shows appropriate error message
393
+ - [ ] Network failure shows user-friendly error
394
+ - [ ] Timeout shows loading state then error
395
+ - [ ] Concurrent operations don't cause data corruption
396
+
397
+ ### Edge Cases
398
+ - [ ] Empty state displays correctly (no data)
399
+ - [ ] Maximum values handled (long strings, large numbers)
400
+ - [ ] Minimum values handled (0, empty string, null)
401
+ - [ ] Special characters handled properly (unicode, emojis, HTML)
402
+
403
+ ### Notes
404
+ - <any special considerations>
405
+ ```
406
+
407
+ #### N/A - Trivial → Skip with note
408
+
409
+ If an AC has verification method "N/A - Trivial", skip test generation and note why.
410
+
411
+ ### Step 4: Locate Feature Worktree
412
+
413
+ If generating file-based tests (Unit Test, Integration Test), find the worktree:
414
+
415
+ ```bash
416
+ git worktree list | grep -E "feature.*<issue-number>"
417
+ ```
418
+
419
+ Or check:
420
+ ```bash
421
+ ls ../worktrees/feature/<issue-number>-*/
422
+ ```
423
+
424
+ Create test directories if needed:
425
+ ```bash
426
+ mkdir -p __tests__/integration
427
+ ```
428
+
429
+ ### Step 5: Write Test Files
430
+
431
+ For each test file generated:
432
+ 1. Check if file already exists (don't overwrite)
433
+ 2. Write the generated stub to the appropriate directory
434
+ 3. Ensure file is executable and has proper imports
435
+
436
+ ### Step 6: Post Summary to GitHub Issue
437
+
438
+ Create a comment summarizing what was generated:
439
+
440
+ ```markdown
441
+ ## Test Stubs Generated
442
+
443
+ | AC | Verification | Happy Path | Failure Paths |
444
+ |----|--------------|------------|---------------|
445
+ | AC-1 | Unit Test | 1 test | 2 error cases |
446
+ | AC-2 | Integration | 1 test | 3 error scenarios |
447
+ | AC-3 | Browser Test | 2 scenarios | 3 negative scenarios |
448
+ | AC-4 | Manual Test | 2 items | 8 failure checks |
449
+ | AC-5 | N/A - Trivial | Skipped | - |
450
+
451
+ **Counts explained:**
452
+ - **Happy Path:** Number of positive/success test stubs or scenarios
453
+ - **Failure Paths:** Number of error handling, edge case, and negative test stubs
454
+
455
+ ### Unit Test Stubs
456
+ - `__tests__/<feature>.test.ts`
457
+ - Happy path: X test cases
458
+ - Error handling: Y failure stubs
459
+
460
+ ### Integration Test Stubs
461
+ - `__tests__/integration/<feature>.integration.test.ts`
462
+ - Happy path: X test cases
463
+ - Assumption validators: Y tests
464
+ - Error scenarios: Z failure stubs
465
+
466
+ ### Browser Test Scenarios
467
+ **Positive scenarios:** [count]
468
+ [Browser test scenarios here]
469
+
470
+ **Negative scenarios:** [count]
471
+ [Negative scenarios here]
472
+
473
+ ### Manual Test Checklists
474
+ **Expected results:** [count] items
475
+ [Manual test checklists here]
476
+
477
+ **Error handling verification:** 4 items
478
+ **Edge cases:** 4 items
479
+
480
+ ---
481
+
482
+ **Next steps:**
483
+ 1. Implement the test stubs (replace `throw new Error(...)` with actual test logic)
484
+ 2. Run `/exec <issue>` to implement the feature
485
+ 3. Verify tests pass with `npm test`
486
+
487
+ ---
488
+ Generated with [Claude Code](https://claude.com/claude-code)
489
+ ```
490
+
491
+ ## Error Handling
492
+
493
+ ### No Verification Criteria Found
494
+
495
+ If the issue doesn't have verification criteria in the /spec comment:
496
+
497
+ ```markdown
498
+ ## Unable to Generate Tests
499
+
500
+ No verification criteria found in the latest /spec comment for Issue #<N>.
501
+
502
+ **Next steps:**
503
+ 1. Run `/spec <issue>` first to create a plan with verification criteria
504
+ 2. Ensure each AC has a "Verification Method" and "Test Scenario"
505
+ 3. Then run `/testgen <issue>` again
506
+ ```
507
+
508
+ ### Missing Worktree
509
+
510
+ If generating file-based tests and no worktree exists:
511
+
512
+ ```markdown
513
+ ## Worktree Not Found
514
+
515
+ Cannot generate test files - no feature worktree exists for Issue #<N>.
516
+
517
+ **Options:**
518
+ 1. Run `/exec <issue>` first (creates worktree automatically)
519
+ 2. Create worktree manually: `./scripts/dev/new-feature.sh <issue>`
520
+ 3. Use the browser/manual test scenarios from this comment
521
+ ```
522
+
523
+ ### Existing Test Files
524
+
525
+ If test files already exist:
526
+ - Don't overwrite existing tests
527
+ - Note which files were skipped
528
+ - Suggest reviewing existing tests against new verification criteria
529
+
530
+ ## Example Output
531
+
532
+ For Issue #452 (hooks):
533
+
534
+ **Generated files:**
535
+ - `__tests__/integration/hooks.integration.test.ts`
536
+
537
+ **GitHub comment:**
538
+ ```markdown
539
+ ## Test Stubs Generated for Issue #452
540
+
541
+ | AC | Verification | Happy Path | Failure Paths |
542
+ |----|--------------|------------|---------------|
543
+ | AC-1 | Integration | 1 test | 3 error scenarios |
544
+
545
+ ### Integration Test Stubs
546
+
547
+ **File:** `__tests__/integration/hooks.integration.test.ts`
548
+ - Happy path: 1 test case
549
+ - Assumption validators: 1 test
550
+ - Error scenarios: 3 failure stubs
551
+
552
+ **Assumptions to validate before implementation:**
553
+ - [ ] Claude Code passes tool data via stdin JSON (NOT env vars)
554
+ - [ ] stdin JSON contains tool_name field
555
+ - [ ] stdin JSON contains tool_input field
556
+ - [ ] Hook can parse JSON with jq
557
+ - [ ] Hook has write permission to /tmp
558
+
559
+ ---
560
+ Generated with [Claude Code](https://claude.com/claude-code)
561
+ ```