specpilot 1.3.0 → 1.6.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 (75) hide show
  1. package/README.md +96 -27
  2. package/dist/cli.js +23 -7
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/add-specs.d.ts.map +1 -1
  5. package/dist/commands/add-specs.js +4 -9
  6. package/dist/commands/add-specs.js.map +1 -1
  7. package/dist/commands/archive.d.ts +5 -0
  8. package/dist/commands/archive.d.ts.map +1 -0
  9. package/dist/commands/archive.js +52 -0
  10. package/dist/commands/archive.js.map +1 -0
  11. package/dist/commands/init.d.ts +1 -0
  12. package/dist/commands/init.d.ts.map +1 -1
  13. package/dist/commands/init.js +131 -14
  14. package/dist/commands/init.js.map +1 -1
  15. package/dist/commands/list.d.ts.map +1 -1
  16. package/dist/commands/list.js +23 -3
  17. package/dist/commands/list.js.map +1 -1
  18. package/dist/commands/migrate.d.ts.map +1 -1
  19. package/dist/commands/migrate.js.map +1 -1
  20. package/dist/commands/refine.d.ts +8 -0
  21. package/dist/commands/refine.d.ts.map +1 -0
  22. package/dist/commands/refine.js +286 -0
  23. package/dist/commands/refine.js.map +1 -0
  24. package/dist/commands/specify.d.ts.map +1 -1
  25. package/dist/commands/specify.js +98 -15
  26. package/dist/commands/specify.js.map +1 -1
  27. package/dist/commands/validate.d.ts.map +1 -1
  28. package/dist/commands/validate.js.map +1 -1
  29. package/dist/utils/agentConfigGenerator.d.ts +15 -0
  30. package/dist/utils/agentConfigGenerator.d.ts.map +1 -0
  31. package/dist/utils/agentConfigGenerator.js +234 -0
  32. package/dist/utils/agentConfigGenerator.js.map +1 -0
  33. package/dist/utils/codeAnalyzer.js +10 -10
  34. package/dist/utils/codeAnalyzer.js.map +1 -1
  35. package/dist/utils/frameworks.d.ts +2 -0
  36. package/dist/utils/frameworks.d.ts.map +1 -0
  37. package/dist/utils/frameworks.js +11 -0
  38. package/dist/utils/frameworks.js.map +1 -0
  39. package/dist/utils/ideConfigGenerator.d.ts +20 -0
  40. package/dist/utils/ideConfigGenerator.d.ts.map +1 -0
  41. package/dist/utils/ideConfigGenerator.js +176 -0
  42. package/dist/utils/ideConfigGenerator.js.map +1 -0
  43. package/dist/utils/logger.d.ts.map +1 -1
  44. package/dist/utils/logger.js +27 -18
  45. package/dist/utils/logger.js.map +1 -1
  46. package/dist/utils/projectDetector.d.ts.map +1 -1
  47. package/dist/utils/projectDetector.js.map +1 -1
  48. package/dist/utils/projectMigrator.d.ts.map +1 -1
  49. package/dist/utils/projectMigrator.js +36 -33
  50. package/dist/utils/projectMigrator.js.map +1 -1
  51. package/dist/utils/specArchiver.d.ts +20 -0
  52. package/dist/utils/specArchiver.d.ts.map +1 -0
  53. package/dist/utils/specArchiver.js +124 -0
  54. package/dist/utils/specArchiver.js.map +1 -0
  55. package/dist/utils/specFileGenerator.d.ts +27 -0
  56. package/dist/utils/specFileGenerator.d.ts.map +1 -0
  57. package/dist/utils/specFileGenerator.js +805 -0
  58. package/dist/utils/specFileGenerator.js.map +1 -0
  59. package/dist/utils/specGenerator.d.ts +11 -14
  60. package/dist/utils/specGenerator.d.ts.map +1 -1
  61. package/dist/utils/specGenerator.js +25 -431
  62. package/dist/utils/specGenerator.js.map +1 -1
  63. package/dist/utils/specTreePrinter.d.ts +8 -0
  64. package/dist/utils/specTreePrinter.d.ts.map +1 -0
  65. package/dist/utils/specTreePrinter.js +38 -0
  66. package/dist/utils/specTreePrinter.js.map +1 -0
  67. package/dist/utils/specValidator.d.ts +3 -0
  68. package/dist/utils/specValidator.d.ts.map +1 -1
  69. package/dist/utils/specValidator.js +85 -10
  70. package/dist/utils/specValidator.js.map +1 -1
  71. package/dist/utils/templateEngine.d.ts +9 -3
  72. package/dist/utils/templateEngine.d.ts.map +1 -1
  73. package/dist/utils/templateEngine.js +44 -36
  74. package/dist/utils/templateEngine.js.map +1 -1
  75. package/package.json +10 -6
@@ -0,0 +1,805 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SpecFileGenerator = void 0;
4
+ const path_1 = require("path");
5
+ const fs_1 = require("fs");
6
+ /**
7
+ * Generates all `.specs/` markdown and YAML files.
8
+ * Responsible only for content inside the specs directory.
9
+ */
10
+ class SpecFileGenerator {
11
+ constructor(templateEngine) {
12
+ this.templateEngine = templateEngine;
13
+ // ── README templates ────────────────────────────────────────────
14
+ this.NEW_PROJECT_README = `# SpecPilot Specifications
15
+
16
+ This folder contains structured documentation for your project.
17
+
18
+ ## 🚀 Quick Start: Generate Your Specs with AI
19
+
20
+ Your specs files have been scaffolded with placeholders. Use your AI agent to draft them based on the project description you provided during \`specpilot init\`.
21
+
22
+ ### Step 1: Copy the Onboarding Prompt
23
+ 1. Open [\`development/prompts.md\`](development/prompts.md).
24
+ 2. Find the **"New Project Onboarding Prompt"** section.
25
+ 3. Copy the entire fenced code block (\`\`\`...\`\`\`).
26
+
27
+ ### Step 2: Paste into Your AI Agent
28
+ 1. In your IDE (VS Code, Cursor, etc.), open the AI chat.
29
+ 2. Paste the prompt and run it.
30
+ 3. The AI will draft all spec files based on your project description.
31
+
32
+ ### Step 3: Review & Refine
33
+ - The generated specs are a **starting point** based on the AI's understanding.
34
+ - Review each file — change, add, or remove anything as your project evolves.
35
+ - Add details the AI couldn't know before you start coding.
36
+ - Run \`specpilot validate\` to ensure consistency.
37
+
38
+ ## 📁 File Structure
39
+ - \`project/\`: Metadata and requirements
40
+ - \`architecture/\`: Design and APIs
41
+ - \`planning/\`: Tasks and roadmap
42
+ - \`quality/\`: Testing
43
+ - \`development/\`: Docs and prompts
44
+
45
+ ## 🛠️ Commands
46
+ \\\`\\\`\\\`bash
47
+ # Validate your specs
48
+ specpilot validate
49
+
50
+ # Add specs to an existing project later
51
+ specpilot add-specs
52
+ \\\`\\\`\\\`
53
+
54
+ For AI guidelines and prompt history, see [\`development/prompts.md\`](development/prompts.md).`;
55
+ this.EXISTING_PROJECT_README = `# SpecPilot Specifications
56
+
57
+ This folder contains structured documentation for your codebase.
58
+
59
+ ## 🚀 Quick Start: Populate Your Specs
60
+
61
+ Your specs files have been scaffolded with placeholders. Use your AI agent to populate them by analyzing your existing codebase.
62
+
63
+ ### Step 1: Copy the Onboarding Prompt
64
+ 1. Open [\`development/prompts.md\`](development/prompts.md).
65
+ 2. Find the **"Existing Project Onboarding Prompt"** section.
66
+ 3. Copy the entire fenced code block (\`\`\`...\`\`\`).
67
+
68
+ ### Step 2: Paste into Your AI Agent
69
+ 1. In your IDE (VS Code, Cursor, etc.), open the AI chat.
70
+ 2. Paste the prompt and run it.
71
+ 3. The AI will analyze your codebase and populate all spec files.
72
+
73
+ ### Step 3: Review & Iterate
74
+ - Check the generated content in each \`.specs\` file.
75
+ - Refine as needed (e.g., add missing details).
76
+ - Run \`specpilot validate\` to ensure consistency.
77
+
78
+ ## 📁 File Structure
79
+ - \`project/\`: Metadata and requirements
80
+ - \`architecture/\`: Design and APIs
81
+ - \`planning/\`: Tasks and roadmap
82
+ - \`quality/\`: Testing
83
+ - \`development/\`: Docs and prompts
84
+
85
+ ## 🛠️ Commands
86
+ \\\`\\\`\\\`bash
87
+ # Validate your specs
88
+ specpilot validate
89
+
90
+ # Update specs after code changes
91
+ specpilot add-specs
92
+ \\\`\\\`\\\`
93
+
94
+ For AI guidelines and prompt history, see [\`development/prompts.md\`](development/prompts.md).`;
95
+ }
96
+ /** Generate all spec files into the pre-created specs directory. */
97
+ async generateAll(specsDir, context) {
98
+ await this.generateReadmeMd(specsDir, context);
99
+ await this.generateProjectYaml((0, path_1.join)(specsDir, 'project'), context);
100
+ await this.generateRequirementsMd((0, path_1.join)(specsDir, 'project'), context);
101
+ await this.generateArchitectureMd((0, path_1.join)(specsDir, 'architecture'), context);
102
+ await this.generateApiYaml((0, path_1.join)(specsDir, 'architecture'), context);
103
+ await this.generateTasksMd((0, path_1.join)(specsDir, 'planning'), context);
104
+ await this.generateRoadmapMd((0, path_1.join)(specsDir, 'planning'), context);
105
+ await this.generateDocsMd((0, path_1.join)(specsDir, 'development'), context);
106
+ await this.generateContextMd((0, path_1.join)(specsDir, 'development'), context);
107
+ await this.generatePromptsMd((0, path_1.join)(specsDir, 'development'), context);
108
+ await this.generateTestsMd((0, path_1.join)(specsDir, 'quality'), context);
109
+ const securityDir = (0, path_1.join)(specsDir, 'security');
110
+ (0, fs_1.mkdirSync)(securityDir, { recursive: true });
111
+ await this.generateThreatModelMd(securityDir, context);
112
+ await this.generateSecurityDecisionsMd(securityDir, context);
113
+ }
114
+ async generateReadmeMd(specsDir, context) {
115
+ const template = context.mode === 'existing' ? this.EXISTING_PROJECT_README : this.NEW_PROJECT_README;
116
+ const rendered = this.templateEngine.renderFromString(template, context);
117
+ (0, fs_1.writeFileSync)((0, path_1.join)(specsDir, 'README.md'), rendered);
118
+ }
119
+ async generateProjectYaml(specsDir, context) {
120
+ const template = this.templateEngine.getBuiltinTemplate(context.language, context.framework, 'project.yaml');
121
+ const content = this.templateEngine.renderFromString(template, context);
122
+ (0, fs_1.writeFileSync)((0, path_1.join)(specsDir, 'project.yaml'), content);
123
+ }
124
+ async generateArchitectureMd(specsDir, context) {
125
+ const template = this.templateEngine.getBuiltinTemplate(context.language, context.framework, 'architecture.md');
126
+ const content = this.templateEngine.renderFromString(template, context);
127
+ (0, fs_1.writeFileSync)((0, path_1.join)(specsDir, 'architecture.md'), content);
128
+ }
129
+ async generateRequirementsMd(specsDir, context) {
130
+ const content = `---
131
+ title: Requirements
132
+ project: {{projectName}}
133
+ language: {{language}}
134
+ framework: {{framework}}
135
+ lastUpdated: {{currentDate}}
136
+ sourceOfTruth: project/project.yaml
137
+ ---
138
+
139
+ # {{projectName}} Requirements
140
+
141
+ ## Project Overview
142
+ {{description}}
143
+
144
+ ## Functional Requirements
145
+ [TODO: Add requirements with proper template]
146
+
147
+ ## Assumptions
148
+
149
+ > Label each assumption with [ASSUMPTION] so it can be reviewed and revised.
150
+
151
+ - [ASSUMPTION] [e.g. Users have internet access at runtime]
152
+ - [ASSUMPTION] [e.g. Single-user deployment, no multi-tenancy required]
153
+ - [ASSUMPTION] [e.g. Input data is well-formed; no adversarial input expected]
154
+
155
+ ## Cross-References
156
+ - Architecture: ../architecture/architecture.md
157
+ - API: ../architecture/api.yaml
158
+ - Project config: ../project/project.yaml
159
+
160
+ ---
161
+ *Last updated: {{currentDate}}*`;
162
+ const rendered = this.templateEngine.renderFromString(content, context);
163
+ (0, fs_1.writeFileSync)((0, path_1.join)(specsDir, 'requirements.md'), rendered);
164
+ }
165
+ async generateApiYaml(specsDir, context) {
166
+ const content = `# .specs/architecture/api.yaml
167
+ # ------------------------------------------------------------
168
+ # API & Interface Specification
169
+ # Remove the section(s) that don't apply to your project.
170
+ # meta: project={{projectName}} language={{language}} framework={{framework}} updated={{currentDate}}
171
+ # ------------------------------------------------------------
172
+
173
+ project: "{{projectName}}"
174
+ version: "1.0.0"
175
+ lastUpdated: "{{currentDate}}"
176
+
177
+ # ============================================================
178
+ # OPTION A: REST API (remove if not a web API project)
179
+ # ============================================================
180
+ openapi: "3.0.0"
181
+ info:
182
+ title: "{{projectName}} API"
183
+ version: "1.0.0"
184
+ description: "[TODO: Describe your API]"
185
+
186
+ servers:
187
+ - url: "http://localhost:3000"
188
+ description: "Local development"
189
+
190
+ paths:
191
+ /example:
192
+ get:
193
+ summary: "[TODO: Replace with your first endpoint]"
194
+ responses:
195
+ "200":
196
+ description: "Success"
197
+
198
+ # ============================================================
199
+ # OPTION B: CLI Interface (remove if not a CLI project)
200
+ # ============================================================
201
+ cli:
202
+ name: "{{projectName}}"
203
+ version: "1.0.0"
204
+ commands:
205
+ - name: "[TODO: first-command]"
206
+ description: "[TODO: What does this command do?]"
207
+ arguments:
208
+ - name: "[TODO: arg]"
209
+ description: "[TODO: argument description]"
210
+ required: true
211
+ options:
212
+ - flag: "--example <value>"
213
+ description: "[TODO: option description]"
214
+
215
+ # ============================================================
216
+ # OPTION C: GraphQL (remove if not a GraphQL project)
217
+ # ============================================================
218
+ graphql:
219
+ endpoint: "/graphql"
220
+ queries:
221
+ - name: "[TODO: firstQuery]"
222
+ description: "[TODO: What does this query return?]"
223
+ mutations:
224
+ - name: "[TODO: firstMutation]"
225
+ description: "[TODO: What does this mutation do?]"
226
+ `;
227
+ const rendered = this.templateEngine.renderFromString(content, context);
228
+ (0, fs_1.writeFileSync)((0, path_1.join)(specsDir, 'api.yaml'), rendered);
229
+ }
230
+ async generateTasksMd(specsDir, context) {
231
+ const content = `---
232
+ fileID: TASKS-001
233
+ lastUpdated: {{currentDate}}
234
+ version: 1.0
235
+ contributors: [{{author}}]
236
+ relatedFiles: [roadmap.md, project.yaml, requirements.md]
237
+ ---
238
+
239
+ # {{projectName}} — Task Tracking
240
+
241
+ Task ID conventions
242
+
243
+ - BL-###: Backlog items
244
+ - CS-###: Current Sprint items
245
+ - CD-###: Completed items
246
+
247
+ Notes
248
+
249
+ - IDs are stable; do not change once assigned (even if reordered or moved between sections).
250
+ - Reference tasks by ID in commits, prompts, PRs, and discussions.
251
+ - When moving an item from Backlog to Current Sprint, retain its original BL ID or create a CS mirror that references the BL ID.
252
+ - Archive guidance: when Completed grows large, move older entries to \`tasks-archive.md\` and add a pointer here.
253
+
254
+ ## Backlog
255
+
256
+ 1. [BL-001] Plan initial feature set
257
+ 2. [BL-002] Gather user feedback and feature requests
258
+ 3. [BL-003] Write documentation and usage guide
259
+
260
+ ## Current Sprint
261
+
262
+ 1. [CS-001] Set up project foundation and tooling
263
+ 2. [CS-002] Implement core features
264
+ 3. [CS-003] Write unit tests
265
+
266
+ ## Completed
267
+
268
+ 1. [CD-001] Initialise .specs directory ({{currentDate}})
269
+
270
+ ## Cross-References
271
+
272
+ - Roadmap (milestones): ./roadmap.md
273
+ - Requirements: ../project/requirements.md
274
+ - Project config: ../project/project.yaml`;
275
+ const rendered = this.templateEngine.renderFromString(content, context);
276
+ (0, fs_1.writeFileSync)((0, path_1.join)(specsDir, 'tasks.md'), rendered);
277
+ }
278
+ async generateRoadmapMd(specsDir, context) {
279
+ const content = `---
280
+ title: Roadmap
281
+ project: {{projectName}}
282
+ language: {{language}}
283
+ framework: {{framework}}
284
+ lastUpdated: {{currentDate}}
285
+ sourceOfTruth: project/project.yaml
286
+ ---
287
+
288
+ <!--
289
+ PURPOSE: Release-level milestone planner — the "when are we shipping what" file.
290
+ Scope: Quarter-level phases, version targets, feature groupings, goals, and risks.
291
+ Update cadence: Per release / per sprint planning session.
292
+
293
+ Boundary guide:
294
+ - roadmap.md → release milestones, timeline, objectives, and risks (this file)
295
+ - tasks.md → individual work items and sprint status
296
+ -->
297
+
298
+ # {{projectName}} — Development Roadmap
299
+
300
+ ## v0.1.0 — Foundation _(current)_
301
+ **Goal:** Get a working skeleton in place.
302
+ - [x] Project initialised
303
+ - [ ] Core data model implemented
304
+ - [ ] Basic CLI / API working
305
+
306
+ ## v0.2.0 — Core Features
307
+ **Goal:** Deliver the primary user-facing functionality.
308
+ - [ ] Feature A
309
+ - [ ] Feature B
310
+ - [ ] Unit test coverage ≥ 80 %
311
+
312
+ ## v1.0.0 — Production Ready
313
+ **Goal:** Stable, documented, deployable release.
314
+ - [ ] All P0/P1 requirements met
315
+ - [ ] Documentation complete
316
+ - [ ] CI/CD pipeline green
317
+
318
+ ## Unscheduled / Icebox
319
+ - [ ] Nice-to-have feature ideas go here
320
+
321
+ ## Objectives
322
+ - [Primary goal for this project]
323
+ - [Secondary goal]
324
+
325
+ ## Goals & Success Criteria
326
+ | Goal | Success Metric | Target |
327
+ |------|----------------|--------|
328
+ | [Primary goal] | [How we measure it] | [Target value] |
329
+
330
+ ## Risks and Mitigations
331
+ - [Risk 1]: [Mitigation]
332
+ - [Risk 2]: [Mitigation]
333
+
334
+ ## Cross-References
335
+ - Sprint tasks: ./tasks.md
336
+ - Requirements: ../project/requirements.md
337
+
338
+ ---
339
+ *Last updated: {{currentDate}}*`;
340
+ const rendered = this.templateEngine.renderFromString(content, context);
341
+ (0, fs_1.writeFileSync)((0, path_1.join)(specsDir, 'roadmap.md'), rendered);
342
+ }
343
+ async generateDocsMd(specsDir, context) {
344
+ const content = `---
345
+ fileID: DOC-001
346
+ lastUpdated: {{currentDate}}
347
+ version: 1.0
348
+ contributors: []
349
+ relatedFiles: [project/project.yaml, development/context.md, planning/roadmap.md, planning/tasks.md]
350
+ ---
351
+
352
+ # {{projectName}} \u2014 Development Documentation
353
+
354
+ ## Spec File Conventions
355
+
356
+ All \`.specs/\` files must include a YAML front-matter header with:
357
+ - \`fileID\`: Unique identifier (e.g., \`REQ-001\`, \`ARCH-001\`)
358
+ - \`lastUpdated\`: Date in YYYY-MM-DD format
359
+ - \`version\`: Semantic version (e.g., \`1.0\`)
360
+ - \`contributors\`: Array of contributor handles
361
+ - \`relatedFiles\`: Array of related spec file paths
362
+
363
+ Section IDs use the format \`[PREFIX-NNN.S]\` (e.g., \`[REQ-001.1]\`) and must be stable — do not change once assigned.
364
+
365
+ ## Development Procedures
366
+
367
+ ### Workflow
368
+
369
+ 1. Update relevant \`.specs/\` files before committing
370
+ 2. Write tests before implementation
371
+ 3. Use small, focused commits with conventional commit messages (\`type(scope): description\`)
372
+ 4. Log all AI interactions in \`development/prompts.md\`
373
+
374
+ ### Spec Update Checklist (before each commit)
375
+
376
+ - [ ] \`tasks.md\` \u2014 task status updated
377
+ - [ ] \`context.md\` \u2014 decisions and lessons logged
378
+ - [ ] \`requirements.md\` \u2014 updated if features changed
379
+ - [ ] \`architecture.md\` \u2014 updated if structure changed
380
+ - [ ] \`api.yaml\` \u2014 updated if CLI interface changed
381
+ - [ ] \`tests.md\` \u2014 updated if test strategy changed
382
+
383
+ ## CLI Commands Reference
384
+
385
+ \\\`\\\`\\\`bash
386
+ # Initialize a new project
387
+ specpilot init <project-name> [--lang <language>] [--framework <framework>] [--no-prompts]
388
+
389
+ # Add .specs/ to an existing project
390
+ specpilot add-specs
391
+
392
+ # List available templates
393
+ specpilot list
394
+
395
+ # Validate spec files
396
+ specpilot validate [--fix]
397
+
398
+ # Migrate to newer spec structure
399
+ specpilot migrate
400
+
401
+ # Update specs with current project context (shows diff + confirmation)
402
+ specpilot refine
403
+ \\\`\\\`\\\`
404
+
405
+ ## Cross-References
406
+ - Context: ./context.md
407
+ - Roadmap: ../planning/roadmap.md
408
+ - Tasks: ../planning/tasks.md
409
+ - Project config: ../project/project.yaml
410
+
411
+ > For contributing guidelines, troubleshooting, and support, see README.md.
412
+
413
+ ---
414
+ *Last updated: {{currentDate}}*`;
415
+ const rendered = this.templateEngine.renderFromString(content, context);
416
+ (0, fs_1.writeFileSync)((0, path_1.join)(specsDir, 'docs.md'), rendered);
417
+ }
418
+ async generateContextMd(specsDir, context) {
419
+ const content = `---
420
+ title: Development Context
421
+ project: {{projectName}}
422
+ language: {{language}}
423
+ framework: {{framework}}
424
+ lastUpdated: {{currentDate}}
425
+ sourceOfTruth: project/project.yaml
426
+ ---
427
+
428
+ # {{projectName}} Development Context
429
+
430
+ ## Project Memory
431
+ [TODO: Add project context and decisions]
432
+
433
+ ## Cross-References
434
+ - Docs: ./docs.md
435
+ - Roadmap: ../planning/roadmap.md
436
+ - Project config: ../project/project.yaml
437
+
438
+ ---
439
+ *Last updated: {{currentDate}}*`;
440
+ const rendered = this.templateEngine.renderFromString(content, context);
441
+ (0, fs_1.writeFileSync)((0, path_1.join)(specsDir, 'context.md'), rendered);
442
+ }
443
+ async generatePromptsMd(specsDir, context) {
444
+ const isNew = context.mode !== 'existing';
445
+ const pc = context.projectContext;
446
+ // ── Shared conventions block (used by both prompts) ──────────
447
+ const conventions = `**Conventions & Rules:**
448
+ 1. **IDs**: Use semantic prefixes (REQ-, TASK-, ARCH-, TEST-, etc.) with zero-padded numbers (e.g., REQ-001, TASK-042)
449
+ 2. **Status values**: Must be one of: not-started, in-progress, completed, blocked, deprecated
450
+ 3. **Priority values**: Must be: critical, high, medium, low
451
+ 4. **Dates**: Use ISO 8601 format (YYYY-MM-DD)
452
+ 5. **YAML**: Use proper indentation (2 spaces), include all required fields
453
+ 6. **Markdown**: Use ATX headers (#), fenced code blocks, and consistent formatting
454
+ 7. **Traceability**: Link requirements to tasks, tasks to tests, architecture to implementation
455
+ 8. **❌ CRITICAL**: Never modify the .specs folder structure or file names. Only update file CONTENTS. The directory structure is IMMUTABLE.
456
+
457
+ **File Structure Standards:**
458
+
459
+ - \\\`project/project.yaml\\\`: name, version, description, tech_stack[], dependencies[], metadata
460
+ - \\\`project/requirements.md\\\`: ## Functional/Non-Functional Requirements with REQ-XXX IDs, priority, status
461
+ - \\\`architecture/architecture.md\\\`: ## Overview, Components, Data Flow, Tech Stack, Decisions (ADR format)
462
+ - \\\`architecture/api.yaml\\\`: OpenAPI 3.0 spec or endpoints list with methods, paths, descriptions
463
+ - \\\`planning/tasks.md\\\`: ## Backlog/In Progress/Completed with TASK-XXX, assignee, priority, dependencies
464
+ - \\\`planning/roadmap.md\\\`: ## Milestones with versions, dates, features, status
465
+ - \\\`quality/tests.md\\\`: ## Test Strategy, Test Cases (TEST-XXX), Coverage Goals, CI/CD integration
466
+ - \\\`development/docs.md\\\`: ## Getting Started, Architecture, API, Deployment, Contributing
467
+ - \\\`development/context.md\\\`: ## Project Context, Key Decisions, Known Issues, Future Considerations`;
468
+ // ── New-project prompt ────────────────────────────────────────
469
+ const projectContextBlock = pc
470
+ ? `**Project context (provided by the developer):**
471
+ - **What it does:** ${pc.whatItDoes}
472
+ - **Target users:** ${pc.targetUsers}
473
+ - **Expected scale:** ${pc.expectedScale}
474
+ - **Key constraints:** ${pc.constraints}`
475
+ : `**Project context:**
476
+ - **What it does:** [DESCRIBE YOUR PROJECT HERE]
477
+ - **Target users:** Not specified — use your judgment and mark as [ASSUMPTION]
478
+ - **Expected scale:** Not specified — use your judgment and mark as [ASSUMPTION]
479
+ - **Key constraints:** Not specified — use your judgment and mark as [ASSUMPTION]`;
480
+ const newProjectPrompt = `You are the specification co-pilot for a new project called "{{projectName}}".
481
+ Tech stack: {{language}}{{#if framework}} / {{framework}}{{/if}}
482
+
483
+ ${projectContextBlock}
484
+
485
+ **For any areas not covered above, make reasonable assumptions. Clearly label ALL assumptions with [ASSUMPTION] so the developer can review and revise them.**
486
+
487
+ Based on this context, populate all .specs files following these strict conventions:
488
+
489
+ ${conventions}
490
+
491
+ **Your Process:**
492
+ 1. Read the project context above carefully
493
+ 2. For each .specs file, generate content that:
494
+ - Derives requirements, architecture, and tasks from the project description
495
+ - Follows the conventions above exactly
496
+ - Maintains internal consistency (cross-references work)
497
+ - Scales appropriately to project ambition (prototype = concise, production = comprehensive)
498
+ 3. Propose a realistic roadmap with milestones
499
+ 4. Draft a test strategy appropriate for the project type
500
+
501
+ **Output Format:**
502
+ For each file, provide the complete content in a markdown code block:
503
+ \\\\\`\\\\\`\\\\\`markdown
504
+ // filepath: .specs/project/project.yaml
505
+ [full file content]
506
+ \\\\\`\\\\\`\\\\\`
507
+
508
+ **Constraints:**
509
+ - These specs are a starting point — the developer will review and refine them
510
+ - Flag uncertainties and assumptions with [ASSUMPTION] comments
511
+ - Keep descriptions clear, concise, and technical
512
+ - Ensure all IDs are unique within their domain
513
+
514
+ After populating all files, provide a summary of:
515
+ - What you understood about the project
516
+ - Assumptions you made and why
517
+ - Recommended next steps before the developer starts coding
518
+
519
+ **Important:** These specifications are generated based on the AI's understanding of the project description. They are a draft — the developer should review, change, add, or remove anything as the project evolves. Add more detail into the spec files before starting AI-assisted coding.
520
+
521
+ Begin drafting now.`;
522
+ // ── Existing-project prompt ──────────────────────────────────
523
+ const existingProjectPrompt = `You are onboarding as the specification co-pilot for this repository. We just initialized the .specs directory using SpecPilot SDD. Your task is to inspect the codebase and populate all .specs files following these strict conventions:
524
+
525
+ ${conventions}
526
+
527
+ **Your Process:**
528
+ 1. Analyze the codebase: language, framework, structure, existing tests, dependencies
529
+ 2. For each .specs file, generate content that:
530
+ - Reflects the actual implementation state
531
+ - Follows the conventions above exactly
532
+ - Maintains internal consistency (cross-references work)
533
+ - Scales appropriately to project size (small projects = concise specs, large = comprehensive)
534
+ 3. Identify gaps: missing tests, undocumented APIs, unclear requirements, architectural debt
535
+ 4. Propose actionable next steps in planning/tasks.md
536
+
537
+ **Output Format:**
538
+ For each file, provide the complete content in a markdown code block:
539
+ \\\\\`\\\\\`\\\\\`markdown
540
+ // filepath: .specs/project/project.yaml
541
+ [full file content]
542
+ \\\\\`\\\\\`\\\\\`
543
+
544
+ **Constraints:**
545
+ - Maintain the exact file paths and names from the .specs structure
546
+ - Don't invent features that don't exist in the code
547
+ - Flag uncertainties with TODO comments
548
+ - Keep descriptions clear, concise, and technical
549
+ - Ensure all IDs are unique within their domain
550
+
551
+ After populating all files, provide a summary of:
552
+ - What was discovered about the project
553
+ - What's documented vs. what's implemented
554
+ - Critical gaps or risks
555
+ - Recommended immediate actions
556
+
557
+ Begin your analysis now.`;
558
+ // ── Assemble the full prompts.md ─────────────────────────────
559
+ const primaryLabel = isNew ? 'New Project' : 'Existing Project';
560
+ const secondaryLabel = isNew ? 'Existing Project' : 'New Project';
561
+ const primaryPrompt = isNew ? newProjectPrompt : existingProjectPrompt;
562
+ const secondaryPrompt = isNew ? existingProjectPrompt : newProjectPrompt;
563
+ const primaryNote = isNew
564
+ ? 'Use this prompt to have your AI agent draft all specification files based on your project description.'
565
+ : 'Use this prompt to have your AI agent analyze your codebase and populate all specification files.';
566
+ const secondaryNote = isNew
567
+ ? 'If you later need to re-generate specs from an existing codebase (e.g., after significant implementation), use this prompt instead.'
568
+ : 'If you start a fresh module or sub-project and want to plan specs before writing code, use this prompt instead.';
569
+ const content = `---
570
+ title: Prompts Log
571
+ project: {{projectName}}
572
+ language: {{language}}
573
+ framework: {{framework}}
574
+ lastUpdated: {{currentDate}}
575
+ sourceOfTruth: project/project.yaml
576
+ ---
577
+
578
+ # Development Prompts Log
579
+
580
+ ## Overview
581
+ This file (prompts.md) contains ALL AI interactions for {{projectName}}. Update .specs/prompts.md with every AI interaction.
582
+
583
+ **🚨 MANDATE**: Update with every AI interaction.
584
+
585
+ ## Archive Policy
586
+
587
+ > **Line limit: 300 lines.** When this file exceeds 300 lines, run:
588
+ >
589
+ > \`\`\`bash
590
+ > specpilot archive
591
+ > \`\`\`
592
+ >
593
+ > This will move older entries from this file into \`development/prompts-archive.md\` automatically, keeping the most recent entries here. A \`--dry-run\` flag is available to preview changes before writing.
594
+ >
595
+ > No stub \`prompts-archive.md\` file is generated during \`specpilot init\` — it is created on first archive run.
596
+
597
+ ## ${primaryLabel} Onboarding Prompt
598
+
599
+ ${primaryNote}
600
+
601
+ ~~~
602
+ ${primaryPrompt}
603
+ ~~~
604
+
605
+ ---
606
+
607
+ ## ${secondaryLabel} Onboarding Prompt (Reference)
608
+
609
+ ${secondaryNote}
610
+
611
+ ~~~
612
+ ${secondaryPrompt}
613
+ ~~~
614
+
615
+ ---
616
+
617
+ ## Re-Anchor Prompt
618
+
619
+ > Paste this into your AI agent when: the session has been running > 1 hour, you've made > 20 exchanges, or the AI seems to have forgotten project rules.
620
+
621
+ ~~~
622
+ You are working on {{projectName}} ({{language}}{{#if framework}} / {{framework}}{{/if}}).
623
+
624
+ CRITICAL RULES — re-read these before continuing:
625
+ 1. NEVER commit, push, or deploy unless I explicitly ask you to.
626
+ 2. NEVER modify .specs/ folder structure or file names — only update file contents.
627
+ 3. After EVERY code change, proactively update all affected .specs/ files without being asked.
628
+ 4. Spec-First Development — update .specs/ before writing code.
629
+ 5. Log this and all AI interactions in .specs/development/prompts.md.
630
+
631
+ For full project context, read .specs/project/project.yaml.
632
+ ~~~
633
+
634
+ ---
635
+
636
+ ## Prompt History
637
+
638
+ | Date | User | Prompt Summary | Context |
639
+ |------|------|----------------|---------|
640
+ | YYYY-MM-DD | @username | Example prompt | Brief context or outcome |
641
+
642
+ ## Common Commands
643
+
644
+ \\\`\\\`\\\`bash
645
+ # Generate specs for new project
646
+ specpilot init
647
+
648
+ # Add specs to existing project
649
+ specpilot add-specs
650
+
651
+ # Validate spec files
652
+ specpilot validate
653
+ \\\`\\\`\\\`
654
+
655
+ ## AI Agent Guidelines
656
+
657
+ When working with AI agents on this codebase:
658
+ - Always reference relevant .specs files for context
659
+ - Update specifications before/after significant changes
660
+ - Use the conventions defined in the onboarding prompt
661
+ - Link code changes to tasks (TASK-XXX) and requirements (REQ-XXX)
662
+ - Keep development/context.md current with architectural decisions
663
+ - **🚨 MANDATE**: Never modify the .specs folder structure or file names - only update file contents
664
+ - **🚨 RELEASE MANDATE**: Never commit, push, create tags, publish releases, or publish to npm without explicit user consent and approval
665
+
666
+ ## Cross-References
667
+ - Context: ./context.md
668
+ - Project config: ../project/project.yaml
669
+
670
+ ---
671
+ *Last updated: {{currentDate}}*`;
672
+ const rendered = this.templateEngine.renderFromString(content, context);
673
+ (0, fs_1.writeFileSync)((0, path_1.join)(specsDir, 'prompts.md'), rendered);
674
+ }
675
+ async generateTestsMd(specsDir, context) {
676
+ const content = `---
677
+ title: Test Strategy
678
+ project: {{projectName}}
679
+ language: {{language}}
680
+ framework: {{framework}}
681
+ lastUpdated: {{currentDate}}
682
+ sourceOfTruth: project/project.yaml
683
+ ---
684
+
685
+ # {{projectName}} Test Strategy
686
+
687
+ ## Overview
688
+ [TODO: Add testing strategy and approach]
689
+
690
+ ## Cross-References
691
+ - Requirements: ../project/requirements.md
692
+ - Project config: ../project/project.yaml
693
+
694
+ ---
695
+ *Last updated: {{currentDate}}*`;
696
+ const rendered = this.templateEngine.renderFromString(content, context);
697
+ (0, fs_1.writeFileSync)((0, path_1.join)(specsDir, 'tests.md'), rendered);
698
+ }
699
+ async generateThreatModelMd(specsDir, context) {
700
+ const content = `---
701
+ fileID: SEC-001
702
+ lastUpdated: {{currentDate}}
703
+ version: 1.0
704
+ contributors: [{{author}}]
705
+ relatedFiles: [security/security-decisions.md, architecture/architecture.md, project/requirements.md]
706
+ ---
707
+
708
+ # Threat Model
709
+
710
+ ## Overview [SEC-001.1]
711
+
712
+ > Describe the attack surface: what the system does, what it reads/writes, and what it does NOT do (e.g., no network calls at runtime).
713
+
714
+ [TODO: Summarise the system's threat surface — input sources, outputs, and offline/online constraints.]
715
+
716
+ ## Threat Model [SEC-002]
717
+
718
+ ### [Threat Name] [SEC-002.1]
719
+
720
+ | Field | Detail |
721
+ |---|---|
722
+ | **Description** | [TODO: Describe the threat] |
723
+ | **Impact** | [TODO: High / Medium / Low] |
724
+ | **Likelihood** | [TODO: High / Medium / Low / Very low] |
725
+ | **Entry point** | [TODO: Where does attacker-controlled data enter?] |
726
+ | **Mitigation** | [TODO: What control prevents or limits this threat?] |
727
+ | **Residual risk** | [TODO: What risk remains after mitigation?] |
728
+
729
+ ### [Threat Name] [SEC-002.2]
730
+
731
+ | Field | Detail |
732
+ |---|---|
733
+ | **Description** | [TODO: Describe the threat] |
734
+ | **Impact** | [TODO: High / Medium / Low] |
735
+ | **Likelihood** | [TODO: High / Medium / Low / Very low] |
736
+ | **Entry point** | [TODO: Where does attacker-controlled data enter?] |
737
+ | **Mitigation** | [TODO: What control prevents or limits this threat?] |
738
+ | **Residual risk** | [TODO: What risk remains after mitigation?] |
739
+
740
+ ## Attack Surface Summary [SEC-003]
741
+
742
+ | Entry Point | Data Type | Validated? | Used In |
743
+ |---|---|---|---|
744
+ | [TODO: entry point] | [TODO: type] | [TODO: ✅ / ⚠️ / ❌] | [TODO: component] |
745
+
746
+ ## Out of Scope [SEC-004]
747
+
748
+ - [TODO: List threats explicitly out of scope, e.g. OS-level permissions, container isolation]
749
+
750
+ ---
751
+
752
+ _Last updated: {{currentDate}}_`;
753
+ const rendered = this.templateEngine.renderFromString(content, context);
754
+ (0, fs_1.writeFileSync)((0, path_1.join)(specsDir, 'threat-model.md'), rendered);
755
+ }
756
+ async generateSecurityDecisionsMd(specsDir, context) {
757
+ const content = `---
758
+ fileID: SEC-002
759
+ lastUpdated: {{currentDate}}
760
+ version: 1.0
761
+ contributors: [{{author}}]
762
+ relatedFiles: [security/threat-model.md, architecture/architecture.md]
763
+ ---
764
+
765
+ # Security Decisions
766
+
767
+ > Record security-relevant architectural decisions here in ADR style.
768
+ > Each entry should capture: what was decided, why, and any trade-offs.
769
+
770
+ ## Decisions [SEC-002.1]
771
+
772
+ ### [Decision title] [ADR-001]
773
+
774
+ | Field | Detail |
775
+ |---|---|
776
+ | **Decision** | [TODO: What was decided?] |
777
+ | **Status** | [TODO: Accepted / Proposed / Deprecated] |
778
+ | **Context** | [TODO: What problem does this solve?] |
779
+ | **Rationale** | [TODO: Why was this approach chosen over alternatives?] |
780
+ | **Trade-offs** | [TODO: What are the downsides or limitations?] |
781
+ | **Related threat** | [TODO: Which threat in threat-model.md does this address?] |
782
+
783
+ ### [Decision title] [ADR-002]
784
+
785
+ | Field | Detail |
786
+ |---|---|
787
+ | **Decision** | [TODO: What was decided?] |
788
+ | **Status** | [TODO: Accepted / Proposed / Deprecated] |
789
+ | **Context** | [TODO: What problem does this solve?] |
790
+ | **Rationale** | [TODO: Why was this approach chosen over alternatives?] |
791
+ | **Trade-offs** | [TODO: What are the downsides or limitations?] |
792
+ | **Related threat** | [TODO: Which threat in threat-model.md does this address?] |
793
+
794
+ ## Cross-References
795
+ - Threat model: ./threat-model.md
796
+ - Architecture: ../architecture/architecture.md
797
+
798
+ ---
799
+ *Last updated: {{currentDate}}*`;
800
+ const rendered = this.templateEngine.renderFromString(content, context);
801
+ (0, fs_1.writeFileSync)((0, path_1.join)(specsDir, 'security-decisions.md'), rendered);
802
+ }
803
+ }
804
+ exports.SpecFileGenerator = SpecFileGenerator;
805
+ //# sourceMappingURL=specFileGenerator.js.map