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.
- package/README.md +96 -27
- package/dist/cli.js +23 -7
- package/dist/cli.js.map +1 -1
- package/dist/commands/add-specs.d.ts.map +1 -1
- package/dist/commands/add-specs.js +4 -9
- package/dist/commands/add-specs.js.map +1 -1
- package/dist/commands/archive.d.ts +5 -0
- package/dist/commands/archive.d.ts.map +1 -0
- package/dist/commands/archive.js +52 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +131 -14
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +23 -3
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/refine.d.ts +8 -0
- package/dist/commands/refine.d.ts.map +1 -0
- package/dist/commands/refine.js +286 -0
- package/dist/commands/refine.js.map +1 -0
- package/dist/commands/specify.d.ts.map +1 -1
- package/dist/commands/specify.js +98 -15
- package/dist/commands/specify.js.map +1 -1
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js.map +1 -1
- package/dist/utils/agentConfigGenerator.d.ts +15 -0
- package/dist/utils/agentConfigGenerator.d.ts.map +1 -0
- package/dist/utils/agentConfigGenerator.js +234 -0
- package/dist/utils/agentConfigGenerator.js.map +1 -0
- package/dist/utils/codeAnalyzer.js +10 -10
- package/dist/utils/codeAnalyzer.js.map +1 -1
- package/dist/utils/frameworks.d.ts +2 -0
- package/dist/utils/frameworks.d.ts.map +1 -0
- package/dist/utils/frameworks.js +11 -0
- package/dist/utils/frameworks.js.map +1 -0
- package/dist/utils/ideConfigGenerator.d.ts +20 -0
- package/dist/utils/ideConfigGenerator.d.ts.map +1 -0
- package/dist/utils/ideConfigGenerator.js +176 -0
- package/dist/utils/ideConfigGenerator.js.map +1 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +27 -18
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/projectDetector.d.ts.map +1 -1
- package/dist/utils/projectDetector.js.map +1 -1
- package/dist/utils/projectMigrator.d.ts.map +1 -1
- package/dist/utils/projectMigrator.js +36 -33
- package/dist/utils/projectMigrator.js.map +1 -1
- package/dist/utils/specArchiver.d.ts +20 -0
- package/dist/utils/specArchiver.d.ts.map +1 -0
- package/dist/utils/specArchiver.js +124 -0
- package/dist/utils/specArchiver.js.map +1 -0
- package/dist/utils/specFileGenerator.d.ts +27 -0
- package/dist/utils/specFileGenerator.d.ts.map +1 -0
- package/dist/utils/specFileGenerator.js +805 -0
- package/dist/utils/specFileGenerator.js.map +1 -0
- package/dist/utils/specGenerator.d.ts +11 -14
- package/dist/utils/specGenerator.d.ts.map +1 -1
- package/dist/utils/specGenerator.js +25 -431
- package/dist/utils/specGenerator.js.map +1 -1
- package/dist/utils/specTreePrinter.d.ts +8 -0
- package/dist/utils/specTreePrinter.d.ts.map +1 -0
- package/dist/utils/specTreePrinter.js +38 -0
- package/dist/utils/specTreePrinter.js.map +1 -0
- package/dist/utils/specValidator.d.ts +3 -0
- package/dist/utils/specValidator.d.ts.map +1 -1
- package/dist/utils/specValidator.js +85 -10
- package/dist/utils/specValidator.js.map +1 -1
- package/dist/utils/templateEngine.d.ts +9 -3
- package/dist/utils/templateEngine.d.ts.map +1 -1
- package/dist/utils/templateEngine.js +44 -36
- package/dist/utils/templateEngine.js.map +1 -1
- 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
|