@specsafe/cli 0.3.6 → 0.5.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 (74) hide show
  1. package/dist/commands/apply.d.ts +3 -0
  2. package/dist/commands/apply.d.ts.map +1 -0
  3. package/dist/commands/apply.js +182 -0
  4. package/dist/commands/apply.js.map +1 -0
  5. package/dist/commands/complete.d.ts.map +1 -1
  6. package/dist/commands/complete.js +4 -1
  7. package/dist/commands/complete.js.map +1 -1
  8. package/dist/commands/delta.d.ts +3 -0
  9. package/dist/commands/delta.d.ts.map +1 -0
  10. package/dist/commands/delta.js +82 -0
  11. package/dist/commands/delta.js.map +1 -0
  12. package/dist/commands/diff.d.ts +3 -0
  13. package/dist/commands/diff.d.ts.map +1 -0
  14. package/dist/commands/diff.js +102 -0
  15. package/dist/commands/diff.js.map +1 -0
  16. package/dist/commands/done.d.ts +3 -0
  17. package/dist/commands/done.d.ts.map +1 -0
  18. package/dist/commands/done.js +237 -0
  19. package/dist/commands/done.js.map +1 -0
  20. package/dist/commands/explore.d.ts +3 -0
  21. package/dist/commands/explore.d.ts.map +1 -0
  22. package/dist/commands/explore.js +236 -0
  23. package/dist/commands/explore.js.map +1 -0
  24. package/dist/commands/init-old.d.ts +3 -0
  25. package/dist/commands/init-old.d.ts.map +1 -0
  26. package/dist/commands/init-old.js +146 -0
  27. package/dist/commands/init-old.js.map +1 -0
  28. package/dist/commands/init.d.ts.map +1 -1
  29. package/dist/commands/init.js +195 -43
  30. package/dist/commands/init.js.map +1 -1
  31. package/dist/commands/new.d.ts.map +1 -1
  32. package/dist/commands/new.js +332 -29
  33. package/dist/commands/new.js.map +1 -1
  34. package/dist/commands/qa.d.ts.map +1 -1
  35. package/dist/commands/qa.js +37 -1
  36. package/dist/commands/qa.js.map +1 -1
  37. package/dist/commands/rules.d.ts.map +1 -1
  38. package/dist/commands/rules.js +182 -97
  39. package/dist/commands/rules.js.map +1 -1
  40. package/dist/commands/spec.d.ts.map +1 -1
  41. package/dist/commands/spec.js +257 -25
  42. package/dist/commands/spec.js.map +1 -1
  43. package/dist/commands/test-apply.d.ts +3 -0
  44. package/dist/commands/test-apply.d.ts.map +1 -0
  45. package/dist/commands/test-apply.js +228 -0
  46. package/dist/commands/test-apply.js.map +1 -0
  47. package/dist/commands/test-create.d.ts +3 -0
  48. package/dist/commands/test-create.d.ts.map +1 -0
  49. package/dist/commands/{test.js → test-create.js} +79 -30
  50. package/dist/commands/test-create.js.map +1 -0
  51. package/dist/commands/verify.d.ts +3 -0
  52. package/dist/commands/verify.d.ts.map +1 -0
  53. package/dist/commands/verify.js +288 -0
  54. package/dist/commands/verify.js.map +1 -0
  55. package/dist/index.d.ts +1 -0
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +58 -6
  58. package/dist/index.js.map +1 -1
  59. package/dist/utils/generateToolConfig.d.ts +1 -1
  60. package/dist/utils/generateToolConfig.d.ts.map +1 -1
  61. package/dist/utils/generateToolConfig.js +980 -209
  62. package/dist/utils/generateToolConfig.js.map +1 -1
  63. package/dist/utils/testRunner.d.ts +39 -0
  64. package/dist/utils/testRunner.d.ts.map +1 -0
  65. package/dist/utils/testRunner.js +325 -0
  66. package/dist/utils/testRunner.js.map +1 -0
  67. package/package.json +3 -3
  68. package/dist/commands/code.d.ts +0 -3
  69. package/dist/commands/code.d.ts.map +0 -1
  70. package/dist/commands/code.js +0 -53
  71. package/dist/commands/code.js.map +0 -1
  72. package/dist/commands/test.d.ts +0 -3
  73. package/dist/commands/test.d.ts.map +0 -1
  74. package/dist/commands/test.js.map +0 -1
@@ -1,12 +1,16 @@
1
1
  import { writeFile, mkdir } from 'fs/promises';
2
2
  import { existsSync } from 'fs';
3
+ import { dirname } from 'path';
4
+ import { fileURLToPath } from 'url';
3
5
  import chalk from 'chalk';
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = dirname(__filename);
4
8
  /**
5
9
  * Generates configuration files for AI coding tools
6
10
  */
7
- const cursorRulesContent = `# SpecSafe Rules for Cursor
8
-
9
- You are working on a SpecSafe project. Follow these rules:
11
+ const cursorRulesContent = `# SpecSafe Rules for Cursor v0.4.0
12
+ # OpenSpec-Style Workflow Configuration
13
+ # https://github.com/luci-efe/specsafe
10
14
 
11
15
  ## Always Check PROJECT_STATE.md
12
16
  Before making changes, read PROJECT_STATE.md to understand:
@@ -14,89 +18,590 @@ Before making changes, read PROJECT_STATE.md to understand:
14
18
  - Which spec is being worked on
15
19
  - Requirements that must be satisfied
16
20
 
17
- ## Spec-Driven Workflow
18
- 1. Specs define WHAT to build (requirements, scenarios)
19
- 2. Tests define HOW to verify (generated by SpecSafe)
20
- 3. Implementation satisfies tests
21
+ ## Spec-Driven Development (SDD) Workflow
22
+
23
+ EXPLORE NEW SPEC TEST-CREATE TEST-APPLY → VERIFY → DONE
21
24
 
22
25
  ## Stage-Aware Development
23
- - SPEC stage: Generate tests from requirements
24
- - TEST stage: Tests exist, implement code to pass them
25
- - CODE stage: Implementation in progress, maintain tests
26
- - QA stage: Validate against scenarios
27
- - COMPLETE: Feature done, archive spec
28
26
 
29
- ## Never
27
+ | Stage | Description | Your Role |
28
+ |-------|-------------|-----------|
29
+ | EXPLORE | Research & validate ideas | Help evaluate approaches |
30
+ | NEW | PRD with requirements | Create PRD, tech stack, rules |
31
+ | SPEC | Detailed specification | Generate scenarios & acceptance criteria |
32
+ | TEST-CREATE | Test generation | Create tests from Given/When/Then |
33
+ | TEST-APPLY | Implementation | Write code to pass tests |
34
+ | VERIFY | Test validation | Run tests, fix failures, loop |
35
+ | DONE | Completion | Archive, summarize, celebrate |
36
+
37
+ ## The 7 OpenSpec-Style Commands
38
+
39
+ ### /specsafe:explore — Pre-Spec Exploration
40
+ **When to use:** Before committing to a spec, explore ideas and validate approaches.
41
+
42
+ **Your responsibilities:**
43
+ - Guide problem definition and user identification
44
+ - Research existing solutions and competitors
45
+ - Evaluate technology options with pros/cons
46
+ - Estimate effort (S/M/L/XL)
47
+ - Output: specs/exploration/FEATURE-NAME.md with findings
48
+
49
+ **Decision gate:** Recommend proceed to /specsafe:new or need more research.
50
+
51
+ ### /specsafe:new — Initialize Spec with PRD
52
+ **When to use:** Starting a new feature with validated concept.
53
+
54
+ **Your responsibilities:**
55
+ 1. Generate spec ID: SPEC-YYYYMMDD-NNN
56
+ 2. Create PRD with problem statement, requirements, scenarios
57
+ 3. Recommend tech stack and define rules
58
+ 4. Output: specs/drafts/SPEC-ID.md + update PROJECT_STATE.md
59
+
60
+ **Always confirm with user before writing files.**
61
+
62
+ ### /specsafe:spec — Generate Detailed Spec
63
+ **When to use:** PRD exists, need implementation-ready specification.
64
+
65
+ **Your responsibilities:**
66
+ 1. Read PRD from specs/drafts/SPEC-ID.md
67
+ 2. Create comprehensive spec with functional requirements (FR-XXX),
68
+ technical requirements (TR-XXX), scenarios, acceptance criteria
69
+ 3. Move to specs/active/SPEC-ID.md
70
+ 4. Update PROJECT_STATE.md: DRAFT → SPEC stage
71
+
72
+ **Validate:** Every requirement must be testable.
73
+
74
+ ### /specsafe:test-create — Create Tests from Spec
75
+ **When to use:** Spec is ready, time to define verification.
76
+
77
+ **Your responsibilities:**
78
+ 1. Read spec scenarios from specs/active/SPEC-ID.md
79
+ 2. Determine test strategy (unit, integration, E2E)
80
+ 3. Generate test files: src/__tests__/SPEC-ID/*.test.ts
81
+ 4. Map each scenario to test cases
82
+ 5. Update PROJECT_STATE.md: SPEC → TEST-CREATE stage
83
+ 6. Output: Test count, coverage expectations
84
+
85
+ ### /specsafe:test-apply — Apply Tests (Development Mode)
86
+ **When to use:** Tests exist, implement to make them pass.
87
+
88
+ **Your responsibilities:**
89
+ 1. Read spec requirements and test expectations
90
+ 2. Guide iterative development: Plan → Implement → Test → Commit
91
+ 3. Enforce rules:
92
+ - Every change maps to a requirement
93
+ - Never modify tests to pass (fix code instead)
94
+ - Keep functions small and focused
95
+ 4. Update PROJECT_STATE.md: TEST-CREATE → TEST-APPLY stage
96
+
97
+ **Ask:** "Which requirement should we tackle next?"
98
+
99
+ ### /specsafe:verify — Verify & Iterate
100
+ **When to use:** Implementation complete, need validation.
101
+
102
+ **Your responsibilities:**
103
+ 1. Read spec for expected behavior
104
+ 2. Run test suite: npm test -- SPEC-ID
105
+ 3. For each failure: identify, map to requirement, fix
106
+ 4. Iterate: Run → Analyze → Fix → Run until all pass
107
+ 5. Check coverage meets spec requirements
108
+ 6. Update PROJECT_STATE.md: TEST-APPLY → VERIFY stage
109
+
110
+ **Output:** Pass rate, coverage %, remaining issues
111
+
112
+ ### /specsafe:done — Complete & Archive
113
+ **When to use:** All tests pass, ready to finalize.
114
+
115
+ **Your responsibilities:**
116
+ 1. Verify completion checklist
117
+ 2. Run final test suite
118
+ 3. Move specs/active/SPEC-ID.md → specs/archive/SPEC-ID.md
119
+ 4. Update PROJECT_STATE.md: move to COMPLETED
120
+ 5. Generate summary: date, files, tests, LOC, notes
121
+ 6. Suggest next spec from active list
122
+
123
+ **Ask for confirmation before archiving.**
124
+
125
+ ## Critical Rules
126
+
127
+ ### ALWAYS
128
+ - Read PROJECT_STATE.md before making changes
129
+ - Ensure implementation satisfies tests
130
+ - Use specsafe CLI commands to advance stages
131
+ - Reference spec ID in commit messages: feat(SPEC-001): add user auth
132
+ - Run tests before marking work complete
133
+
134
+ ### NEVER
30
135
  - Skip tests to implement faster
31
136
  - Modify specs without updating PROJECT_STATE.md
32
137
  - Commit code without corresponding spec entry
138
+ - Break the verify loop by ignoring test failures
139
+ - Modify tests to make them pass without discussion
33
140
 
34
- ## Always
35
- - Run tests before marking work complete
36
- - Update spec stage using \`specsafe\` commands
37
- - Reference spec ID in commit messages
141
+ ## File Organization
142
+
143
+ my-project/
144
+ ├── specs/
145
+ │ ├── drafts/ # PRD stage specs
146
+ │ ├── active/ # In-progress specs
147
+ │ ├── archive/ # Completed specs
148
+ │ └── exploration/ # Research notes
149
+ ├── src/
150
+ │ └── __tests__/ # Test files organized by spec
151
+ ├── PROJECT_STATE.md # Central status tracker
152
+ └── specsafe.config.json # Tool configuration
153
+
154
+ ## Commit Message Format
155
+
156
+ type(SPEC-ID): brief description
157
+
158
+ - Detailed change 1
159
+ - Detailed change 2
160
+
161
+ Refs: SPEC-ID
162
+
163
+ Types: feat, fix, test, docs, refactor, chore
164
+
165
+ ---
166
+ *Version: 0.4.0*
167
+ *OpenSpec-Style Workflow Enabled*
38
168
  `;
39
- const continueConfigContent = {
40
- customCommands: [
41
- {
42
- name: 'specsafe',
43
- description: 'Show current SpecSafe status',
44
- prompt: 'Read PROJECT_STATE.md and show me the current active specs, their stages, and what needs to be done next.',
45
- },
46
- {
47
- name: 'spec',
48
- description: 'Show details for a specific spec',
49
- prompt: 'Read the spec file for {{input}} from specs/active/ and show me its requirements, scenarios, and current stage.',
50
- },
51
- ],
52
- contextProviders: [
53
- {
54
- name: 'specsafe-state',
55
- params: {
56
- file: 'PROJECT_STATE.md',
57
- },
58
- },
59
- ],
60
- };
61
- const aiderConfigContent = `# Aider configuration for SpecSafe projects
169
+ const aiderConfigContent = `# Aider configuration for SpecSafe v0.4.0
170
+ # OpenSpec-Style Workflow Configuration
171
+ # https://aider.chat/docs/config/aider_conf.html
62
172
 
63
173
  # Always read PROJECT_STATE.md for context
64
174
  read:
65
175
  - PROJECT_STATE.md
176
+ - README.md
177
+ - CONVENTIONS.md
66
178
 
67
- # Instructions for the AI
179
+ # Use .aiderignore for file exclusions (gitignore syntax)
180
+ aiderignore: .aiderignore
181
+
182
+ # Don't add .gitignore'd files to aider's scope
183
+ add-gitignore-files: false
184
+
185
+ # AI Assistant Instructions for SpecSafe Workflow
68
186
  assistant_prompt: |
69
- You are working on a SpecSafe project. Always:
70
- 1. Check PROJECT_STATE.md for current specs and stages
71
- 2. Ensure implementation satisfies test requirements
72
- 3. Update spec stage using specsafe commands when complete
73
- 4. Never skip tests or modify specs without tracking
74
-
75
- # Files to ignore
76
- ignore:
77
- - specs/archive/
78
- - node_modules/
79
- - dist/
80
- - .git/
187
+ You are working on a SpecSafe project using spec-driven development (SDD).
188
+
189
+ ## The 7 OpenSpec-Style Commands
190
+
191
+ When the user invokes a command, follow the corresponding workflow:
192
+
193
+ ### /specsafe:explore Pre-Spec Exploration
194
+ - Guide problem definition and user research
195
+ - Evaluate technology options with pros/cons
196
+ - Estimate effort (S/M/L/XL)
197
+ - Document in specs/exploration/FEATURE-NAME.md
198
+ - Recommend proceed, research more, or park idea
199
+
200
+ ### /specsafe:new — Initialize Spec with PRD
201
+ - Generate spec ID: SPEC-YYYYMMDD-NNN format
202
+ - Create PRD with problem statement, requirements, scenarios
203
+ - Recommend tech stack and define rules
204
+ - Output to specs/drafts/SPEC-ID.md
205
+ - Update PROJECT_STATE.md (status: DRAFT)
206
+ - Confirm details with user before writing
207
+
208
+ ### /specsafe:spec — Generate Detailed Spec
209
+ - Read PRD from specs/drafts/SPEC-ID.md
210
+ - Create comprehensive spec:
211
+ * Functional Requirements (FR-001, FR-002...)
212
+ * Technical Requirements (TR-001, TR-002...)
213
+ * Scenarios (Given/When/Then)
214
+ * Acceptance Criteria
215
+ * Architecture Notes
216
+ - Write to specs/active/SPEC-ID.md
217
+ - Update PROJECT_STATE.md: DRAFT → SPEC
218
+ - Ensure every requirement is testable
219
+
220
+ ### /specsafe:test-create — Create Tests from Spec
221
+ - Read spec scenarios from specs/active/SPEC-ID.md
222
+ - Generate test files: src/__tests__/SPEC-ID/*.test.ts
223
+ - Map Given/When/Then to test cases
224
+ - Include happy path and edge cases
225
+ - Update PROJECT_STATE.md: SPEC → TEST-CREATE
226
+ - Report test count and coverage expectations
227
+
228
+ ### /specsafe:test-apply — Apply Tests (Development Mode)
229
+ - Read spec requirements and test expectations
230
+ - Implement one requirement at a time
231
+ - Follow cycle: Plan → Implement → Test → Commit
232
+ - Map every code change to requirement ID
233
+ - Never modify tests to make them pass
234
+ - Update PROJECT_STATE.md: TEST-CREATE → TEST-APPLY
235
+ - Ask: "Which requirement next?"
236
+
237
+ ### /specsafe:verify — Verify and Iterate
238
+ - Run test suite: npm test -- SPEC-ID
239
+ - For each failure: identify, map to requirement, fix
240
+ - Golden rule: Fix code, not tests (unless confirmed wrong)
241
+ - Iterate until all tests pass
242
+ - Check coverage meets requirements
243
+ - Run full suite for regressions
244
+ - Update PROJECT_STATE.md: TEST-APPLY → VERIFY
245
+ - Report: pass rate, coverage %, issues
246
+
247
+ ### /specsafe:done — Complete and Archive
248
+ - Verify completion checklist
249
+ - Run final test suite
250
+ - Move specs/active/SPEC-ID.md → specs/archive/SPEC-ID.md
251
+ - Update PROJECT_STATE.md: move to COMPLETED
252
+ - Generate completion summary
253
+ - Suggest next spec from active list
254
+ - Ask for confirmation before archiving
255
+
256
+ ## Critical Rules
257
+
258
+ ALWAYS:
259
+ - Check PROJECT_STATE.md before making changes
260
+ - Ensure implementation satisfies tests
261
+ - Use spec ID in commit messages: feat(SPEC-001): description
262
+ - Run tests before marking work complete
263
+ - Fix the code, not the test
264
+
265
+ NEVER:
266
+ - Skip tests to implement faster
267
+ - Modify PROJECT_STATE.md directly (use workflow commands)
268
+ - Break the verify loop by ignoring failures
269
+ - Modify tests without discussion
270
+ - Commit code without spec reference
271
+
272
+ ## Workflow Diagram
273
+
274
+ EXPLORE → NEW → SPEC → TEST-CREATE → TEST-APPLY → VERIFY → DONE
275
+
276
+ # Commit message conventions
277
+ commit-prompt: |
278
+ Format: type(SPEC-ID): brief description
279
+
280
+ Types: feat, fix, test, docs, refactor, chore
281
+ Example: feat(SPEC-001): add user authentication
282
+
283
+ Always reference the spec ID in commits.
284
+ `;
285
+ const aiderIgnoreContent = `# Aider ignore patterns for SpecSafe projects
286
+
287
+ # Spec archives (read-only reference)
288
+ specs/archive/
289
+
290
+ # Dependencies
291
+ node_modules/
292
+ vendor/
293
+
294
+ # Build outputs
295
+ dist/
296
+ build/
297
+ *.min.js
298
+ *.min.css
299
+
300
+ # Generated files
301
+ *.generated.ts
302
+ *.generated.js
303
+
304
+ # Logs
305
+ *.log
306
+ logs/
307
+
308
+ # Coverage reports
309
+ coverage/
310
+ .nyc_output/
311
+
312
+ # IDE files
313
+ .vscode/
314
+ .idea/
315
+ *.swp
316
+ *.swo
317
+
318
+ # OS files
319
+ .DS_Store
320
+ Thumbs.db
321
+
322
+ # Test outputs
323
+ test-results/
324
+ playwright-report/
81
325
  `;
82
326
  const zedSettingsContent = {
327
+ name: "specsafe-zed",
328
+ version: "0.4.0",
329
+ description: "SpecSafe v0.4.0 OpenSpec-Style Workflow for Zed Editor",
83
330
  assistant: {
84
331
  default_model: {
85
- provider: 'anthropic',
86
- model: 'claude-3-5-sonnet-latest',
332
+ provider: "anthropic",
333
+ model: "claude-3-5-sonnet-latest"
87
334
  },
88
- version: '2',
335
+ version: "2"
89
336
  },
90
337
  context_servers: {
91
338
  specsafe: {
92
- command: 'cat',
93
- args: ['PROJECT_STATE.md'],
339
+ command: ["cat", "PROJECT_STATE.md"]
340
+ }
341
+ },
342
+ lsp: {
343
+ specsafe: {
344
+ command: "specsafe",
345
+ args: ["status", "--json"]
346
+ }
347
+ },
348
+ agent: {
349
+ name: "SpecSafe",
350
+ description: "Spec-driven development assistant for OpenSpec-style workflow",
351
+ context: {
352
+ files: [
353
+ "PROJECT_STATE.md",
354
+ "specsafe.config.json"
355
+ ],
356
+ directories: [
357
+ "specs/active",
358
+ "specs/drafts"
359
+ ]
360
+ },
361
+ commands: {
362
+ "specsafe:explore": {
363
+ description: "Pre-spec exploration and research",
364
+ prompt: "Conduct preliminary exploration before committing to a full spec. Guide problem definition, research technology options, estimate effort, and document findings in specs/exploration/FEATURE-NAME.md. Recommend proceed to spec creation or need more research.",
365
+ context: ["PROJECT_STATE.md"]
366
+ },
367
+ "specsafe:new": {
368
+ description: "Initialize spec with PRD",
369
+ prompt: "Create a new spec with Product Requirements Document. Generate spec ID (SPEC-YYYYMMDD-NNN), create PRD with problem statement, requirements, scenarios, recommend tech stack, and define rules. Output to specs/drafts/SPEC-ID.md and update PROJECT_STATE.md (status: DRAFT). Confirm with user before writing.",
370
+ context: ["PROJECT_STATE.md"]
371
+ },
372
+ "specsafe:spec": {
373
+ description: "Generate detailed spec from PRD",
374
+ prompt: "Read PRD from specs/drafts/SPEC-ID.md and create comprehensive implementation-ready specification. Include functional requirements (FR-XXX), technical requirements (TR-XXX), Given/When/Then scenarios, acceptance criteria, and architecture notes. Write to specs/active/SPEC-ID.md and update PROJECT_STATE.md (DRAFT → SPEC).",
375
+ context: ["PROJECT_STATE.md", "specs/drafts/*.md"]
376
+ },
377
+ "specsafe:test-create": {
378
+ description: "Create tests from spec scenarios",
379
+ prompt: "Read spec from specs/active/SPEC-ID.md and generate comprehensive test suite. Create test files in src/__tests__/SPEC-ID/ mapping Given/When/Then to test cases. Include happy path and edge cases. Update PROJECT_STATE.md (SPEC → TEST-CREATE) and report test count.",
380
+ context: ["PROJECT_STATE.md", "specs/active/*.md"]
381
+ },
382
+ "specsafe:test-apply": {
383
+ description: "Apply tests (development mode for active spec)",
384
+ prompt: "Guide implementation for active spec. Read requirements and tests, implement one requirement at a time following Plan → Implement → Test → Commit cycle. Map changes to requirement IDs. Never modify tests to make them pass. Update PROJECT_STATE.md (TEST-CREATE → TEST-APPLY). Ask which requirement to tackle next.",
385
+ context: ["PROJECT_STATE.md", "specs/active/*.md", "src/__tests__/**/*.test.ts"]
386
+ },
387
+ "specsafe:verify": {
388
+ description: "Run tests and iterate until pass",
389
+ prompt: "Verify implementation by running test suite. Execute npm test -- SPEC-ID, analyze failures, map to requirements, and fix code (not tests). Iterate until all pass. Check coverage, run full suite for regressions. Update PROJECT_STATE.md (TEST-APPLY → VERIFY). Report pass rate, coverage %, and any issues.",
390
+ context: ["PROJECT_STATE.md", "specs/active/*.md", "src/__tests__/**/*.test.ts"]
391
+ },
392
+ "specsafe:done": {
393
+ description: "Complete and archive spec",
394
+ prompt: "Finalize spec after all tests pass. Verify completion checklist, run final test suite, move specs/active/SPEC-ID.md to specs/archive/SPEC-ID.md. Update PROJECT_STATE.md (VERIFY → COMPLETE). Generate completion summary and suggest next spec. Ask for confirmation before archiving.",
395
+ context: ["PROJECT_STATE.md", "specs/active/*.md"]
396
+ },
397
+ specsafe: {
398
+ description: "Show project status",
399
+ prompt: "Read PROJECT_STATE.md and show current active specs, their stages, what needs attention, and recommended next actions. Provide brief SDD workflow reminder (EXPLORE → NEW → SPEC → TEST-CREATE → TEST-APPLY → VERIFY → DONE).",
400
+ context: ["PROJECT_STATE.md"]
401
+ }
402
+ },
403
+ rules: {
404
+ always: [
405
+ "Read PROJECT_STATE.md before making changes",
406
+ "Ensure implementation satisfies tests",
407
+ "Use spec ID in commit messages: type(SPEC-XXX): description",
408
+ "Run tests before marking work complete"
409
+ ],
410
+ never: [
411
+ "Skip tests to implement faster",
412
+ "Modify PROJECT_STATE.md directly (use commands)",
413
+ "Break verify loop by ignoring failures",
414
+ "Modify tests without discussion",
415
+ "Commit code without spec reference"
416
+ ]
94
417
  },
418
+ workflow: {
419
+ stages: ["EXPLORE", "NEW", "SPEC", "TEST-CREATE", "TEST-APPLY", "VERIFY", "COMPLETE"],
420
+ transitions: {
421
+ EXPLORE: ["NEW"],
422
+ NEW: ["SPEC"],
423
+ SPEC: ["TEST-CREATE"],
424
+ "TEST-CREATE": ["TEST-APPLY"],
425
+ "TEST-APPLY": ["VERIFY"],
426
+ VERIFY: ["COMPLETE", "TEST-APPLY"],
427
+ COMPLETE: []
428
+ }
429
+ }
95
430
  },
431
+ file_types: {
432
+ "SpecSafe Spec": {
433
+ path_suffixes: [".specsafe.md"],
434
+ grammar: "markdown"
435
+ }
436
+ }
96
437
  };
438
+ // Skill content for Claude Code slash commands
439
+ const claudeSkillSpecsafeContent = `---
440
+ name: specsafe
441
+ description: Show SpecSafe project status and workflow guidance
442
+ disable-model-invocation: true
443
+ ---
444
+
445
+ You are in a SpecSafe project using spec-driven development.
446
+
447
+ Read PROJECT_STATE.md and provide:
448
+ 1. Summary of active specs and their current stages
449
+ 2. Which specs need attention
450
+ 3. Recommended next actions based on the project state
451
+ 4. Brief reminder of the SDD workflow (EXPLORE → NEW → SPEC → TEST-CREATE → TEST-APPLY → VERIFY → DONE)
452
+ `;
453
+ const claudeSkillExploreContent = `---
454
+ name: specsafe-explore
455
+ description: Pre-spec exploration and research mode
456
+ argument-hint: "[feature-name]"
457
+ disable-model-invocation: true
458
+ ---
459
+
460
+ You are in exploration mode. Guide the user through pre-spec research.
461
+
462
+ **Activities:**
463
+ - Define the problem and identify target users
464
+ - Research existing solutions and competitors
465
+ - Evaluate technology options with pros/cons
466
+ - Estimate effort (S/M/L/XL)
467
+ - Document risks and constraints
468
+
469
+ **Output:** Create specs/exploration/{feature-name}.md with findings.
470
+
471
+ **Decision Gate:** Recommend proceeding to /specsafe:new or gathering more information.
472
+ `;
473
+ const claudeSkillNewContent = `---
474
+ name: specsafe-new
475
+ description: Initialize spec with PRD
476
+ argument-hint: "[feature-name]"
477
+ disable-model-invocation: true
478
+ ---
479
+
480
+ Create a new spec with Product Requirements Document.
481
+
482
+ **Steps:**
483
+ 1. Generate spec ID: SPEC-YYYYMMDD-NNN
484
+ 2. Create PRD with problem statement, requirements, scenarios
485
+ 3. Recommend tech stack and define rules
486
+ 4. Output to specs/drafts/SPEC-ID.md
487
+ 5. Update PROJECT_STATE.md (status: DRAFT)
488
+
489
+ Always confirm with user before writing files.
490
+ `;
491
+ const claudeSkillSpecContent = `---
492
+ name: specsafe-spec
493
+ description: Generate detailed spec from PRD
494
+ argument-hint: "[spec-id]"
495
+ disable-model-invocation: true
496
+ ---
497
+
498
+ Read PRD from specs/drafts/$ARGUMENTS.md and create comprehensive specification.
499
+
500
+ **Include:**
501
+ - Functional Requirements (FR-001, FR-002...)
502
+ - Technical Requirements (TR-001, TR-002...)
503
+ - Scenarios (Given/When/Then)
504
+ - Acceptance Criteria
505
+ - Architecture Notes
506
+
507
+ Move to specs/active/SPEC-ID.md and update PROJECT_STATE.md (DRAFT → SPEC).
508
+
509
+ If no argument provided, list available drafts.
510
+ `;
511
+ const claudeSkillTestCreateContent = `---
512
+ name: specsafe-test-create
513
+ description: Create tests from spec scenarios
514
+ argument-hint: "[spec-id]"
515
+ disable-model-invocation: true
516
+ ---
517
+
518
+ Generate comprehensive test suite from the active spec.
519
+
520
+ **Process:**
521
+ 1. Read spec from specs/active/$ARGUMENTS.md
522
+ 2. Generate test files in src/__tests__/$ARGUMENTS/
523
+ 3. Map Given/When/Then to test cases
524
+ 4. Include happy path and edge cases
525
+ 5. Update PROJECT_STATE.md (SPEC → TEST-CREATE)
526
+
527
+ Report test count and coverage expectations.
528
+ `;
529
+ const claudeSkillTestApplyContent = `---
530
+ name: specsafe-test-apply
531
+ description: Apply tests - development mode to pass tests
532
+ argument-hint: "[spec-id]"
533
+ disable-model-invocation: true
534
+ ---
535
+
536
+ Guide implementation for active spec.
537
+
538
+ **Development Cycle:**
539
+ 1. Plan - Identify smallest slice of functionality
540
+ 2. Implement - Write code for one requirement at a time
541
+ 3. Test - Run tests, fix failures
542
+ 4. Commit - Small commits with spec reference
543
+
544
+ **Rules:**
545
+ - Never modify tests to make them pass (fix the code)
546
+ - Map every change to a requirement ID
547
+ - Update PROJECT_STATE.md (TEST-CREATE → TEST-APPLY)
548
+
549
+ Ask: "Which requirement should we tackle next?"
550
+ `;
551
+ const claudeSkillVerifyContent = `---
552
+ name: specsafe-verify
553
+ description: Verify implementation by running tests
554
+ argument-hint: "[spec-id]"
555
+ disable-model-invocation: true
556
+ ---
557
+
558
+ Run tests and iterate until implementation is correct.
559
+
560
+ **Process:**
561
+ 1. Execute test suite: npm test -- $ARGUMENTS
562
+ 2. Analyze failures and map to requirements
563
+ 3. Fix code (not tests) and re-run
564
+ 4. Iterate until all pass
565
+ 5. Check coverage and run full suite for regressions
566
+
567
+ Update PROJECT_STATE.md (TEST-APPLY → VERIFY).
568
+ Report pass rate, coverage %, and any issues.
569
+ `;
570
+ const claudeSkillDoneContent = `---
571
+ name: specsafe-done
572
+ description: Complete and archive spec
573
+ argument-hint: "[spec-id]"
574
+ disable-model-invocation: true
575
+ ---
576
+
577
+ Finalize spec after all tests pass.
578
+
579
+ **Completion Checklist:**
580
+ - [ ] All requirements implemented
581
+ - [ ] All tests passing
582
+ - [ ] Code reviewed (if required)
583
+ - [ ] Documentation updated
584
+ - [ ] No TODO/debug code
585
+
586
+ **Archive:**
587
+ - Move specs/active/$ARGUMENTS.md → specs/archive/$ARGUMENTS.md
588
+ - Update PROJECT_STATE.md (VERIFY → COMPLETE)
589
+ - Generate completion summary
590
+
591
+ Ask for confirmation before archiving.
592
+ `;
593
+ const claudeSkillValidateContent = `---
594
+ name: specsafe-validate
595
+ description: Validate current implementation against active spec
596
+ disable-model-invocation: true
597
+ ---
598
+
599
+ Check if the current code changes satisfy the requirements in the active spec.
600
+ Point out any gaps or issues that need to be addressed before completing.
601
+ `;
97
602
  /**
98
603
  * Generate configuration for a specific tool
99
- * @param tool - The tool name (cursor, continue, aider, zed, claude-code, crush)
604
+ * @param tool - The tool name (cursor, continue, aider, zed, claude-code, crush, git-hooks)
100
605
  * @param projectDir - The project directory path
101
606
  */
102
607
  export async function generateToolConfig(tool, projectDir = '.') {
@@ -119,6 +624,9 @@ export async function generateToolConfig(tool, projectDir = '.') {
119
624
  case 'crush':
120
625
  await generateCrushConfig(projectDir);
121
626
  break;
627
+ case 'git-hooks':
628
+ await generateGitHooks(projectDir);
629
+ break;
122
630
  default:
123
631
  throw new Error(`Unknown tool: ${tool}`);
124
632
  }
@@ -130,26 +638,213 @@ async function generateCursorConfig(projectDir) {
130
638
  return;
131
639
  }
132
640
  await writeFile(configPath, cursorRulesContent);
641
+ console.log(chalk.green('✓ Created .cursorrules'));
133
642
  }
134
643
  async function generateContinueConfig(projectDir) {
135
644
  const configDir = `${projectDir}/.continue`;
136
- const configPath = `${configDir}/config.json`;
645
+ const promptsDir = `${configDir}/prompts`;
137
646
  if (!existsSync(configDir)) {
138
647
  await mkdir(configDir, { recursive: true });
139
648
  }
140
- if (existsSync(configPath)) {
141
- console.log(chalk.yellow('⚠ .continue/config.json already exists, skipping'));
142
- return;
649
+ if (!existsSync(promptsDir)) {
650
+ await mkdir(promptsDir, { recursive: true });
651
+ }
652
+ // Create config.yaml
653
+ const configPath = `${configDir}/config.yaml`;
654
+ if (!existsSync(configPath)) {
655
+ const continueConfigContent = `# Continue.dev configuration for SpecSafe v0.4.0
656
+ # Generated by SpecSafe
657
+
658
+ name: SpecSafe
659
+ version: 0.4.0
660
+ schema: v1
661
+
662
+ prompts:
663
+ - uses: file://prompts/specsafe.md
664
+ - uses: file://prompts/spec.md
665
+ - uses: file://prompts/validate.md
666
+ - uses: file://prompts/specsafe-explore.md
667
+ - uses: file://prompts/specsafe-new.md
668
+ - uses: file://prompts/specsafe-spec.md
669
+ - uses: file://prompts/specsafe-test-create.md
670
+ - uses: file://prompts/specsafe-test-apply.md
671
+ - uses: file://prompts/specsafe-verify.md
672
+ - uses: file://prompts/specsafe-done.md
673
+
674
+ context:
675
+ include:
676
+ - PROJECT_STATE.md
677
+ - specs/active/*.md
678
+ - specs/drafts/*.md
679
+ `;
680
+ await writeFile(configPath, continueConfigContent);
681
+ console.log(chalk.green('✓ Created .continue/config.yaml'));
682
+ }
683
+ else {
684
+ console.log(chalk.yellow('⚠ .continue/config.yaml already exists, skipping'));
685
+ }
686
+ // Create basic prompt files
687
+ const promptFiles = {
688
+ 'specsafe.md': `---
689
+ name: specsafe
690
+ description: Show SpecSafe project status
691
+ invokable: true
692
+ ---
693
+
694
+ Read PROJECT_STATE.md and summarize:
695
+ 1) Active specs and their stages
696
+ 2) What spec is currently being worked on
697
+ 3) What the next steps should be
698
+ `,
699
+ 'spec.md': `---
700
+ name: spec
701
+ description: Show details for a specific spec
702
+ invokable: true
703
+ ---
704
+
705
+ Read the spec file for {{input}} from specs/active/ and show its requirements, scenarios, and current stage.
706
+ `,
707
+ 'validate.md': `---
708
+ name: validate
709
+ description: Validate implementation against spec
710
+ invokable: true
711
+ ---
712
+
713
+ Check if the current implementation satisfies the active spec requirements.
714
+ `,
715
+ 'specsafe-explore.md': `---
716
+ name: specsafe-explore
717
+ description: Pre-Spec Exploration
718
+ invokable: true
719
+ ---
720
+
721
+ You are in exploration mode. Guide pre-spec research:
722
+ - Define problem and identify users
723
+ - Research existing solutions
724
+ - Evaluate technology options
725
+ - Estimate effort (S/M/L/XL)
726
+
727
+ Output: specs/exploration/FEATURE-NAME.md
728
+ `,
729
+ 'specsafe-new.md': `---
730
+ name: specsafe-new
731
+ description: Initialize Spec with PRD
732
+ invokable: true
733
+ ---
734
+
735
+ Create a new spec:
736
+ 1. Generate spec ID: SPEC-YYYYMMDD-NNN
737
+ 2. Create PRD with requirements and scenarios
738
+ 3. Recommend tech stack
739
+ 4. Output: specs/drafts/SPEC-ID.md
740
+ 5. Update PROJECT_STATE.md (status: DRAFT)
741
+
742
+ Confirm before writing.
743
+ `,
744
+ 'specsafe-spec.md': `---
745
+ name: specsafe-spec
746
+ description: Generate Detailed Spec
747
+ invokable: true
748
+ ---
749
+
750
+ Convert PRD to comprehensive spec:
751
+ - Functional Requirements (FR-XXX)
752
+ - Technical Requirements (TR-XXX)
753
+ - Scenarios (Given/When/Then)
754
+ - Acceptance Criteria
755
+ - Architecture Notes
756
+
757
+ Move: specs/drafts/ → specs/active/
758
+ Update: PROJECT_STATE.md (DRAFT → SPEC)
759
+ `,
760
+ 'specsafe-test-create.md': `---
761
+ name: specsafe-test-create
762
+ description: Create Tests from Spec
763
+ invokable: true
764
+ ---
765
+
766
+ Generate test suite:
767
+ 1. Read spec scenarios
768
+ 2. Create src/__tests__/SPEC-ID/*.test.ts
769
+ 3. Map Given/When/Then to test cases
770
+ 4. Include happy path and edge cases
771
+ 5. Update PROJECT_STATE.md (SPEC → TEST-CREATE)
772
+
773
+ Report: test count and coverage
774
+ `,
775
+ 'specsafe-test-apply.md': `---
776
+ name: specsafe-test-apply
777
+ description: Apply Tests (Development Mode)
778
+ invokable: true
779
+ ---
780
+
781
+ Guide implementation:
782
+ - Plan → Implement → Test → Commit
783
+ - Map changes to requirement IDs
784
+ - Never modify tests to pass (fix code)
785
+ - Update PROJECT_STATE.md (TEST-CREATE → TEST-APPLY)
786
+
787
+ Ask: "Which requirement next?"
788
+ `,
789
+ 'specsafe-verify.md': `---
790
+ name: specsafe-verify
791
+ description: Verify and Iterate
792
+ invokable: true
793
+ ---
794
+
795
+ Run tests and fix failures:
796
+ 1. Execute: npm test -- SPEC-ID
797
+ 2. Map failures to requirements
798
+ 3. Fix code (not tests)
799
+ 4. Iterate until all pass
800
+ 5. Check coverage
801
+
802
+ Update PROJECT_STATE.md (TEST-APPLY → VERIFY)
803
+ `,
804
+ 'specsafe-done.md': `---
805
+ name: specsafe-done
806
+ description: Complete and Archive
807
+ invokable: true
808
+ ---
809
+
810
+ Finalize spec:
811
+ - Verify completion checklist
812
+ - Run final test suite
813
+ - Move: specs/active/ → specs/archive/
814
+ - Update PROJECT_STATE.md (VERIFY → COMPLETE)
815
+ - Generate summary
816
+
817
+ Confirm before archiving.
818
+ `
819
+ };
820
+ for (const [filename, content] of Object.entries(promptFiles)) {
821
+ const targetPath = `${promptsDir}/${filename}`;
822
+ if (!existsSync(targetPath)) {
823
+ await writeFile(targetPath, content);
824
+ console.log(chalk.green(`✓ Created .continue/prompts/${filename}`));
825
+ }
826
+ else {
827
+ console.log(chalk.yellow(`⚠ .continue/prompts/${filename} already exists, skipping`));
828
+ }
143
829
  }
144
- await writeFile(configPath, JSON.stringify(continueConfigContent, null, 2));
145
830
  }
146
831
  async function generateAiderConfig(projectDir) {
147
832
  const configPath = `${projectDir}/.aider.conf.yml`;
833
+ const ignorePath = `${projectDir}/.aiderignore`;
148
834
  if (existsSync(configPath)) {
149
835
  console.log(chalk.yellow('⚠ .aider.conf.yml already exists, skipping'));
150
- return;
151
836
  }
152
- await writeFile(configPath, aiderConfigContent);
837
+ else {
838
+ await writeFile(configPath, aiderConfigContent);
839
+ console.log(chalk.green('✓ Created .aider.conf.yml'));
840
+ }
841
+ if (existsSync(ignorePath)) {
842
+ console.log(chalk.yellow('⚠ .aiderignore already exists, skipping'));
843
+ }
844
+ else {
845
+ await writeFile(ignorePath, aiderIgnoreContent);
846
+ console.log(chalk.green('✓ Created .aiderignore'));
847
+ }
153
848
  }
154
849
  async function generateZedConfig(projectDir) {
155
850
  const configDir = `${projectDir}/.zed`;
@@ -162,100 +857,71 @@ async function generateZedConfig(projectDir) {
162
857
  return;
163
858
  }
164
859
  await writeFile(configPath, JSON.stringify(zedSettingsContent, null, 2));
860
+ console.log(chalk.green('✓ Created .zed/settings.json'));
165
861
  }
166
- // Skill content for Claude Code slash commands
167
- const claudeSkillSpecsafeContent = `---
168
- name: specsafe
169
- description: Show SpecSafe project status and workflow guidance
170
- disable-model-invocation: true
171
- ---
172
-
173
- You are in a SpecSafe project using spec-driven development.
174
-
175
- Read PROJECT_STATE.md and provide:
176
- 1. Summary of active specs and their current stages
177
- 2. Which specs need attention
178
- 3. Recommended next actions based on the project state
179
- 4. Brief reminder of the SDD workflow (SPEC → TEST → CODE → QA → COMPLETE)
180
- `;
181
- const claudeSkillSpecContent = `---
182
- name: specsafe-spec
183
- description: Show details for a specific spec by ID
184
- argument-hint: "[spec-id]"
185
- disable-model-invocation: true
186
- ---
187
-
188
- Read the spec file from specs/active/$ARGUMENTS.md and show:
189
- - Requirements
190
- - Scenarios/acceptance criteria
191
- - Current stage
192
- - Implementation files referenced
193
-
194
- If no argument provided, list available specs.
195
- `;
196
- const claudeSkillValidateContent = `---
197
- name: specsafe-validate
198
- description: Validate current implementation against active spec
199
- disable-model-invocation: true
200
- ---
201
-
202
- Check if the current code changes satisfy the requirements in the active spec.
203
- Point out any gaps or issues that need to be addressed before completing.
204
- `;
205
862
  async function generateClaudeCodeConfig(projectDir) {
206
863
  // Create CLAUDE.md project context file
207
864
  const configPath = `${projectDir}/CLAUDE.md`;
208
865
  if (!existsSync(configPath)) {
209
- const claudeContent = `# SpecSafe Project Claude Code Configuration
866
+ const claudeContent = `# SpecSafe Project - Claude Code Configuration
210
867
 
211
868
  You are working on a SpecSafe project using spec-driven development (SDD).
212
869
 
213
870
  ## Project Context
214
871
 
215
- **PROJECT_STATE.md** Always read this file first. It contains:
872
+ **PROJECT_STATE.md** - Always read this file first. It contains:
216
873
  - Active specs and their current stages
217
874
  - Which spec is being worked on
218
875
  - Overall project status
219
876
 
220
- **Specs directory** \`specs/active/*.md\` contains detailed spec files with:
877
+ **Specs directory** - specs/active/*.md contains detailed spec files with:
221
878
  - Requirements (must be satisfied)
222
879
  - Scenarios (acceptance criteria)
223
- - Current stage (SPEC → TEST → CODE → QA → COMPLETE)
880
+ - Current stage
224
881
 
225
882
  ## Spec-Driven Development Workflow
226
883
 
227
- 1. **SPEC stage**: Spec defines WHAT to build (requirements, scenarios)
228
- 2. **TEST stage**: Tests define HOW to verify (generated by SpecSafe)
229
- 3. **CODE stage**: Implementation satisfies the tests
230
- 4. **QA stage**: Validate against scenarios, edge cases
231
- 5. **COMPLETE**: Feature done, spec archived
884
+ 1. **EXPLORE**: Research and validate ideas
885
+ 2. **NEW**: PRD with requirements
886
+ 3. **SPEC**: Detailed specification
887
+ 4. **TEST-CREATE**: Generate tests from spec
888
+ 5. **TEST-APPLY**: Implement to pass tests
889
+ 6. **VERIFY**: Validate all tests pass
890
+ 7. **DONE**: Complete and archive
232
891
 
233
892
  ## Critical Rules
234
893
 
235
- ✅ **ALWAYS** read PROJECT_STATE.md before making changes
236
- ✅ **ALWAYS** ensure implementation satisfies tests
237
- ✅ **ALWAYS** use \`specsafe\` CLI commands to advance stages
238
- ✅ **ALWAYS** reference spec ID in commit messages
894
+ ALWAYS read PROJECT_STATE.md before making changes
895
+ ALWAYS ensure implementation satisfies tests
896
+ ALWAYS use specsafe CLI commands to advance stages
897
+ ALWAYS reference spec ID in commit messages
239
898
 
240
- ❌ **NEVER** modify PROJECT_STATE.md directly (use CLI)
241
- ❌ **NEVER** skip tests to implement faster
242
- ❌ **NEVER** modify specs without updating state
899
+ NEVER modify PROJECT_STATE.md directly (use CLI)
900
+ NEVER skip tests to implement faster
901
+ NEVER modify tests to make them pass without discussion
243
902
 
244
903
  ## SpecSafe CLI Reference
245
904
 
246
- - \`specsafe status\` Show current project status
247
- - \`specsafe spec <id>\` View spec details, move to SPEC stage
248
- - \`specsafe test <id>\` Generate tests, move to TEST stage
249
- - \`specsafe code <id>\` Start implementation, move to CODE stage
250
- - \`specsafe qa <id>\` Run QA validation, move to QA stage
251
- - \`specsafe complete <id>\` Complete spec, move to COMPLETE stage
905
+ - specsafe status - Show current project status
906
+ - specsafe explore <name> - Start exploration
907
+ - specsafe new <name> - Create PRD
908
+ - specsafe spec <id> - Generate detailed spec
909
+ - specsafe test-create <id> - Create tests
910
+ - specsafe test-apply <id> - Start implementation
911
+ - specsafe verify <id> - Run validation
912
+ - specsafe done <id> - Complete spec
252
913
 
253
914
  ## Claude Code Skills
254
915
 
255
916
  This project includes Claude Code skills for slash commands:
256
- - \`/specsafe\` Show project status and workflow guidance
257
- - \`/spec <id>\` Show details for a specific spec
258
- - \`/validate\` Validate implementation against active spec
917
+ - /specsafe - Show project status
918
+ - /specsafe-explore - Pre-spec exploration
919
+ - /specsafe-new - Initialize spec with PRD
920
+ - /specsafe-spec - Generate detailed spec
921
+ - /specsafe-test-create - Create tests
922
+ - /specsafe-test-apply - Development mode
923
+ - /specsafe-verify - Run verification
924
+ - /specsafe-done - Complete and archive
259
925
  `;
260
926
  await writeFile(configPath, claudeContent);
261
927
  console.log(chalk.green('✓ Created CLAUDE.md'));
@@ -268,44 +934,30 @@ This project includes Claude Code skills for slash commands:
268
934
  if (!existsSync(skillsDir)) {
269
935
  await mkdir(skillsDir, { recursive: true });
270
936
  }
271
- // Create specsafe skill
272
- const specsafeSkillDir = `${skillsDir}/specsafe`;
273
- const specsafeSkillPath = `${specsafeSkillDir}/SKILL.md`;
274
- if (!existsSync(specsafeSkillPath)) {
275
- if (!existsSync(specsafeSkillDir)) {
276
- await mkdir(specsafeSkillDir, { recursive: true });
937
+ const skills = [
938
+ { name: 'specsafe', content: claudeSkillSpecsafeContent },
939
+ { name: 'specsafe-explore', content: claudeSkillExploreContent },
940
+ { name: 'specsafe-new', content: claudeSkillNewContent },
941
+ { name: 'specsafe-spec', content: claudeSkillSpecContent },
942
+ { name: 'specsafe-test-create', content: claudeSkillTestCreateContent },
943
+ { name: 'specsafe-test-apply', content: claudeSkillTestApplyContent },
944
+ { name: 'specsafe-verify', content: claudeSkillVerifyContent },
945
+ { name: 'specsafe-done', content: claudeSkillDoneContent },
946
+ { name: 'specsafe-validate', content: claudeSkillValidateContent },
947
+ ];
948
+ for (const skill of skills) {
949
+ const skillDir = `${skillsDir}/${skill.name}`;
950
+ const skillPath = `${skillDir}/SKILL.md`;
951
+ if (!existsSync(skillPath)) {
952
+ if (!existsSync(skillDir)) {
953
+ await mkdir(skillDir, { recursive: true });
954
+ }
955
+ await writeFile(skillPath, skill.content);
956
+ console.log(chalk.green(`✓ Created .claude/skills/${skill.name}/SKILL.md`));
277
957
  }
278
- await writeFile(specsafeSkillPath, claudeSkillSpecsafeContent);
279
- console.log(chalk.green('✓ Created .claude/skills/specsafe/SKILL.md'));
280
- }
281
- else {
282
- console.log(chalk.yellow('⚠ .claude/skills/specsafe/SKILL.md already exists, skipping'));
283
- }
284
- // Create spec skill
285
- const specSkillDir = `${skillsDir}/specsafe-spec`;
286
- const specSkillPath = `${specSkillDir}/SKILL.md`;
287
- if (!existsSync(specSkillPath)) {
288
- if (!existsSync(specSkillDir)) {
289
- await mkdir(specSkillDir, { recursive: true });
958
+ else {
959
+ console.log(chalk.yellow(`⚠ .claude/skills/${skill.name}/SKILL.md already exists, skipping`));
290
960
  }
291
- await writeFile(specSkillPath, claudeSkillSpecContent);
292
- console.log(chalk.green('✓ Created .claude/skills/specsafe-spec/SKILL.md'));
293
- }
294
- else {
295
- console.log(chalk.yellow('⚠ .claude/skills/specsafe-spec/SKILL.md already exists, skipping'));
296
- }
297
- // Create validate skill
298
- const validateSkillDir = `${skillsDir}/specsafe-validate`;
299
- const validateSkillPath = `${validateSkillDir}/SKILL.md`;
300
- if (!existsSync(validateSkillPath)) {
301
- if (!existsSync(validateSkillDir)) {
302
- await mkdir(validateSkillDir, { recursive: true });
303
- }
304
- await writeFile(validateSkillPath, claudeSkillValidateContent);
305
- console.log(chalk.green('✓ Created .claude/skills/specsafe-validate/SKILL.md'));
306
- }
307
- else {
308
- console.log(chalk.yellow('⚠ .claude/skills/specsafe-validate/SKILL.md already exists, skipping'));
309
961
  }
310
962
  }
311
963
  async function generateCrushConfig(projectDir) {
@@ -314,27 +966,17 @@ async function generateCrushConfig(projectDir) {
314
966
  if (!existsSync(commandsDir)) {
315
967
  await mkdir(commandsDir, { recursive: true });
316
968
  }
317
- // Create specsafe command
318
- const specsafeCmdPath = `${commandsDir}/specsafe.md`;
319
- if (!existsSync(specsafeCmdPath)) {
320
- const specsafeContent = `Show SpecSafe project status and workflow guidance
969
+ // Create basic command files
970
+ const commandFiles = {
971
+ 'specsafe.md': `Show SpecSafe project status
321
972
 
322
973
  Read PROJECT_STATE.md and provide:
323
974
  1. Summary of active specs and their current stages
324
975
  2. Which specs need attention
325
- 3. Recommended next actions based on the project state
326
- 4. Brief reminder of the SDD workflow (SPEC → TEST → CODE → QA → COMPLETE)
327
- `;
328
- await writeFile(specsafeCmdPath, specsafeContent);
329
- console.log(chalk.green('✓ Created .opencode/commands/specsafe.md'));
330
- }
331
- else {
332
- console.log(chalk.yellow('⚠ .opencode/commands/specsafe.md already exists, skipping'));
333
- }
334
- // Create spec command
335
- const specCmdPath = `${commandsDir}/spec.md`;
336
- if (!existsSync(specCmdPath)) {
337
- const specContent = `Show details for a specific spec by ID
976
+ 3. Recommended next actions
977
+ 4. SDD workflow reminder
978
+ `,
979
+ 'spec.md': `Show details for a specific spec by ID
338
980
 
339
981
  Read the spec file from specs/active/$SPEC_ID.md and show:
340
982
  - Requirements
@@ -343,26 +985,97 @@ Read the spec file from specs/active/$SPEC_ID.md and show:
343
985
  - Implementation files referenced
344
986
 
345
987
  If no SPEC_ID provided, list available specs.
346
- `;
347
- await writeFile(specCmdPath, specContent);
348
- console.log(chalk.green('✓ Created .opencode/commands/spec.md'));
349
- }
350
- else {
351
- console.log(chalk.yellow('⚠ .opencode/commands/spec.md already exists, skipping'));
352
- }
353
- // Create validate command
354
- const validateCmdPath = `${commandsDir}/validate.md`;
355
- if (!existsSync(validateCmdPath)) {
356
- const validateContent = `Validate current implementation against active spec
988
+ `,
989
+ 'validate.md': `Validate current implementation against active spec
357
990
 
358
991
  Check if the current code changes satisfy the requirements in the active spec.
359
992
  Point out any gaps or issues that need to be addressed before completing.
360
- `;
361
- await writeFile(validateCmdPath, validateContent);
362
- console.log(chalk.green('✓ Created .opencode/commands/validate.md'));
363
- }
364
- else {
365
- console.log(chalk.yellow('⚠ .opencode/commands/validate.md already exists, skipping'));
993
+ `,
994
+ 'specsafe-explore.md': `Pre-Spec Exploration and Research Mode
995
+
996
+ Guide the user through pre-spec research:
997
+ - Define problem and identify users
998
+ - Research existing solutions
999
+ - Evaluate technology options
1000
+ - Estimate effort (S/M/L/XL)
1001
+ - Output: specs/exploration/FEATURE-NAME.md
1002
+ `,
1003
+ 'specsafe-new.md': `Initialize Spec with Product Requirements Document
1004
+
1005
+ Create a new spec:
1006
+ 1. Generate spec ID: SPEC-YYYYMMDD-NNN
1007
+ 2. Create PRD with requirements, scenarios
1008
+ 3. Recommend tech stack
1009
+ 4. Output: specs/drafts/SPEC-ID.md
1010
+ 5. Update PROJECT_STATE.md (status: DRAFT)
1011
+
1012
+ Confirm before writing.
1013
+ `,
1014
+ 'specsafe-spec.md': `Generate Detailed Spec from PRD
1015
+
1016
+ Convert PRD to comprehensive spec:
1017
+ - Functional Requirements (FR-XXX)
1018
+ - Technical Requirements (TR-XXX)
1019
+ - Scenarios (Given/When/Then)
1020
+ - Acceptance Criteria
1021
+ - Architecture Notes
1022
+
1023
+ Move: specs/drafts/ → specs/active/
1024
+ Update: PROJECT_STATE.md (DRAFT → SPEC)
1025
+ `,
1026
+ 'specsafe-test-create.md': `Create Tests from Spec Scenarios
1027
+
1028
+ Generate test suite:
1029
+ 1. Read spec scenarios
1030
+ 2. Create src/__tests__/SPEC-ID/*.test.ts
1031
+ 3. Map Given/When/Then to test cases
1032
+ 4. Include happy path and edge cases
1033
+ 5. Update PROJECT_STATE.md (SPEC → TEST-CREATE)
1034
+
1035
+ Report: test count and coverage
1036
+ `,
1037
+ 'specsafe-test-apply.md': `Apply Tests - Development Mode
1038
+
1039
+ Guide implementation:
1040
+ - Plan → Implement → Test → Commit
1041
+ - Map changes to requirement IDs
1042
+ - Never modify tests to pass (fix code)
1043
+ - Update PROJECT_STATE.md (TEST-CREATE → TEST-APPLY)
1044
+
1045
+ Ask: "Which requirement next?"
1046
+ `,
1047
+ 'specsafe-verify.md': `Verify Implementation and Iterate
1048
+
1049
+ Run tests and fix:
1050
+ 1. Execute: npm test -- SPEC-ID
1051
+ 2. Map failures to requirements
1052
+ 3. Fix code (not tests)
1053
+ 4. Iterate until all pass
1054
+ 5. Check coverage
1055
+
1056
+ Update PROJECT_STATE.md (TEST-APPLY → VERIFY)
1057
+ `,
1058
+ 'specsafe-done.md': `Complete and Archive Spec
1059
+
1060
+ Finalize:
1061
+ - Verify completion checklist
1062
+ - Run final test suite
1063
+ - Move: specs/active/ → specs/archive/
1064
+ - Update PROJECT_STATE.md (VERIFY → COMPLETE)
1065
+ - Generate summary
1066
+
1067
+ Confirm before archiving.
1068
+ `
1069
+ };
1070
+ for (const [filename, content] of Object.entries(commandFiles)) {
1071
+ const targetPath = `${commandsDir}/${filename}`;
1072
+ if (!existsSync(targetPath)) {
1073
+ await writeFile(targetPath, content);
1074
+ console.log(chalk.green(`✓ Created .opencode/commands/${filename}`));
1075
+ }
1076
+ else {
1077
+ console.log(chalk.yellow(`⚠ .opencode/commands/${filename} already exists, skipping`));
1078
+ }
366
1079
  }
367
1080
  }
368
1081
  /**
@@ -376,20 +1089,77 @@ export async function generateGitHooks(projectDir) {
376
1089
  await mkdir(hooksDir, { recursive: true });
377
1090
  }
378
1091
  const preCommitContent = `#!/bin/bash
379
- # SpecSafe pre-commit hook
1092
+ # SpecSafe pre-commit hook v0.4.0
1093
+ # Enhanced verification for OpenSpec-style workflow
380
1094
 
381
- echo "🔍 Running SpecSafe pre-commit checks..."
1095
+ set -e
382
1096
 
383
- # Validate PROJECT_STATE.md exists
1097
+ echo "Running SpecSafe pre-commit checks..."
1098
+
1099
+ FAILED=0
1100
+
1101
+ # Check 1: Validate PROJECT_STATE.md exists
1102
+ echo "Checking PROJECT_STATE.md..."
384
1103
  if [ ! -f "PROJECT_STATE.md" ]; then
385
- echo "PROJECT_STATE.md not found. Run 'specsafe init' first."
386
- exit 1
1104
+ echo "PROJECT_STATE.md not found. Run 'specsafe init' first."
1105
+ FAILED=1
1106
+ else
1107
+ echo "PROJECT_STATE.md exists"
387
1108
  fi
388
1109
 
389
- # Run spec validation (if we add a validate command)
390
- # specsafe validate --silent || exit 1
1110
+ # Check 2: Verify specs directory structure
1111
+ echo "Checking specs directory structure..."
1112
+ if [ -d "specs" ]; then
1113
+ for subdir in drafts active archive exploration; do
1114
+ if [ ! -d "specs/\$subdir" ]; then
1115
+ echo "Missing specs/\$subdir directory - creating"
1116
+ mkdir -p "specs/\$subdir"
1117
+ fi
1118
+ done
1119
+ echo "Specs directory structure valid"
1120
+ else
1121
+ echo "No specs directory found. Run 'specsafe init'."
1122
+ fi
391
1123
 
392
- echo "✅ Pre-commit checks passed"
1124
+ # Check 3: Check for TODO/FIXME in staged files
1125
+ echo "Checking for TODO/FIXME markers..."
1126
+ STAGED_FILES=\$(git diff --cached --name-only --diff-filter=ACM 2>/dev/null || true)
1127
+
1128
+ if [ -n "\$STAGED_FILES" ]; then
1129
+ TODO_FOUND=0
1130
+ for file in \$STAGED_FILES; do
1131
+ if echo "\$file" | grep -qE '\\.(ts|tsx|js|jsx|py|java|go|rs|cpp|c|h|php|rb)\$'; then
1132
+ if git diff --cached "\$file" | grep -i "TODO\\|FIXME\\|XXX\\|HACK" > /dev/null 2>&1; then
1133
+ echo "Warning: \$file contains TODO/FIXME markers"
1134
+ TODO_FOUND=1
1135
+ fi
1136
+ fi
1137
+ done
1138
+
1139
+ if [ \$TODO_FOUND -eq 1 ]; then
1140
+ echo "Consider resolving these before committing"
1141
+ fi
1142
+ fi
1143
+
1144
+ # Check 4: Run specsafe doctor if available
1145
+ if command -v specsafe >/dev/null 2>&1; then
1146
+ echo "Running SpecSafe validation..."
1147
+ if specsafe doctor --silent 2>/dev/null; then
1148
+ echo "SpecSafe doctor passed"
1149
+ else
1150
+ echo "SpecSafe doctor found issues. Run 'specsafe doctor' for details."
1151
+ fi
1152
+ fi
1153
+
1154
+ # Final status
1155
+ echo ""
1156
+ if [ \$FAILED -eq 0 ]; then
1157
+ echo "All pre-commit checks passed"
1158
+ exit 0
1159
+ else
1160
+ echo "Some pre-commit checks failed"
1161
+ exit 1
1162
+ fi
393
1163
  `;
394
1164
  if (existsSync(preCommitPath)) {
395
1165
  console.log(chalk.yellow('⚠ .githooks/pre-commit already exists, skipping'));
@@ -400,9 +1170,10 @@ echo "✅ Pre-commit checks passed"
400
1170
  try {
401
1171
  const { exec } = await import('child_process');
402
1172
  exec(`chmod +x ${preCommitPath}`);
1173
+ console.log(chalk.green('✓ Created .githooks/pre-commit'));
403
1174
  }
404
1175
  catch {
405
- // Ignore chmod errors on Windows
1176
+ console.log(chalk.yellow('⚠ Could not make pre-commit executable'));
406
1177
  }
407
1178
  }
408
1179
  //# sourceMappingURL=generateToolConfig.js.map