specsmd 0.0.0-dev.2 → 0.0.0-dev.21

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 CHANGED
@@ -29,8 +29,9 @@ Track your AI-DLC progress with our sidebar extension for VS Code and compatible
29
29
  > **Note:** Works with any VS Code-based IDE including [Cursor](https://cursor.sh), [Google Antigravity](https://antigravity.google), [Windsurf](https://codeium.com/windsurf), and others.
30
30
 
31
31
  **Install from:**
32
- - [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=fabriqaai.specsmd)
33
- - [GitHub Releases (VSIX)](https://github.com/fabriqaai/specs.md/releases)
32
+ - [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=fabriqaai.specsmd) — VS Code, GitHub Codespaces
33
+ - [Open VSX Registry](https://open-vsx.org/extension/fabriqaai/specsmd) — Cursor, Windsurf, Amazon Kiro, Google Antigravity, VSCodium, Gitpod, Google IDX
34
+ - [GitHub Releases (VSIX)](https://github.com/fabriqaai/specs.md/releases) — Manual installation
34
35
 
35
36
  ---
36
37
 
@@ -306,6 +307,13 @@ Specs and Memory Bank provide structured context for AI agents. Agents reload co
306
307
  | **Cursor** | Full support | Rules in `.cursor/rules/` (`.mdc` format) |
307
308
  | **GitHub Copilot** | Full support | Agents in `.github/agents/` (`.agent.md` format) |
308
309
  | **Google Antigravity** | Full support | Agents in `.agent/agents/` |
310
+ | **Windsurf** | Full support | Workflows in `.windsurf/workflows/` |
311
+ | **Amazon Kiro** | Full support | Steering in `.kiro/steering/` |
312
+ | **Gemini CLI** | Full support | Commands in `.gemini/commands/` (`.toml` format) |
313
+ | **Cline** | Full support | Rules in `.clinerules/` |
314
+ | **Roo Code** | Full support | Commands in `.roo/commands/` |
315
+ | **OpenAI Codex** | Full support | Config in `.codex/` |
316
+ | **OpenCode** | Full support | Agents in `.opencode/agent/` |
309
317
 
310
318
  ---
311
319
 
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Building phase agent - execute bolts through DDD stages (model, test, implement)
3
+ ---
4
+
1
5
  # Activate Construction Agent
2
6
 
3
7
  **Command**: `/specsmd-construction-agent`
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Planning phase agent - requirements gathering, story creation, and bolt planning
3
+ ---
4
+
1
5
  # Activate Inception Agent
2
6
 
3
7
  **Command**: `/specsmd-inception-agent`
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Master orchestrator for AI-DLC - routes to appropriate phase/agent based on project state
3
+ ---
4
+
1
5
  # Activate Master Agent
2
6
 
3
7
  **Command**: `/specsmd-master-agent`
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Deployment phase agent - build, deploy, verify, and monitor releases
3
+ ---
4
+
1
5
  # Activate Operations Agent
2
6
 
3
7
  **Command**: `/specsmd-operations-agent`
@@ -10,9 +10,9 @@
10
10
  * - Timestamp format (ISO 8601 without milliseconds)
11
11
  *
12
12
  * Usage:
13
- * node .specsmd/scripts/artifact-validator.js
14
- * node .specsmd/scripts/artifact-validator.js --json
15
- * node .specsmd/scripts/artifact-validator.js --fix
13
+ * node .specsmd/aidlc/scripts/artifact-validator.js
14
+ * node .specsmd/aidlc/scripts/artifact-validator.js --json
15
+ * node .specsmd/aidlc/scripts/artifact-validator.js --fix
16
16
  *
17
17
  * Cross-platform: Works on Linux, macOS, Windows via Node.js
18
18
  */
@@ -115,11 +115,11 @@
115
115
  *
116
116
  * From agent skill (bolt-start.md Step 10):
117
117
  *
118
- * node .specsmd/scripts/bolt-complete.js 016-analytics-tracker
118
+ * node .specsmd/aidlc/scripts/bolt-complete.js 016-analytics-tracker
119
119
  *
120
120
  * With optional stage name:
121
121
  *
122
- * node .specsmd/scripts/bolt-complete.js 016-analytics-tracker --last-stage test
122
+ * node .specsmd/aidlc/scripts/bolt-complete.js 016-analytics-tracker --last-stage test
123
123
  *
124
124
  * ═══════════════════════════════════════════════════════════════════════════════
125
125
  */
@@ -510,6 +510,29 @@ async function updateIntentStatus(bolt) {
510
510
  return { updated: false };
511
511
  }
512
512
 
513
+ /**
514
+ * Validate bolt status before allowing completion
515
+ *
516
+ * Pre-flight checks to ensure:
517
+ * - Bolt is in "in-progress" status (can't complete already-complete or not-started bolts)
518
+ * - Bolt has not already been completed
519
+ */
520
+ function validateBoltStatus(bolt) {
521
+ const status = bolt.frontmatter.status || 'unknown';
522
+
523
+ // Cannot complete a bolt that's already complete
524
+ if (status === 'complete') {
525
+ return { valid: false, reason: 'Bolt is already complete' };
526
+ }
527
+
528
+ // Bolt should be in-progress before completing
529
+ if (status !== 'in-progress') {
530
+ return { valid: false, reason: `Bolt status is "${status}", expected "in-progress"` };
531
+ }
532
+
533
+ return { valid: true };
534
+ }
535
+
513
536
  /**
514
537
  * Main: Mark bolt as complete with all dependent updates
515
538
  */
@@ -522,6 +545,14 @@ async function boltMarkComplete(boltId, lastStage) {
522
545
  // Step 1: Read bolt file
523
546
  const bolt = await readBolt(boltId);
524
547
 
548
+ // Step 1.5: Validate bolt status before proceeding
549
+ const validation = validateBoltStatus(bolt);
550
+ if (!validation.valid) {
551
+ console.error(`\n${colors.red}Error:${colors.reset} ${validation.reason}`);
552
+ console.error(`${colors.dim}Use bolt-status command to check current state.${colors.reset}`);
553
+ return 1;
554
+ }
555
+
525
556
  console.log(`${colors.dim}Bolt: ${bolt.id}${colors.reset}`);
526
557
  console.log(`${colors.dim}Intent: ${bolt.frontmatter.intent}${colors.reset}`);
527
558
  console.log(`${colors.dim}Unit: ${bolt.frontmatter.unit}${colors.reset}`);
@@ -537,11 +568,11 @@ async function boltMarkComplete(boltId, lastStage) {
537
568
  console.log(`\n${colors.dim}Stories: ${colors.green}${storyResults.updated} updated${colors.reset}, ${colors.dim}${storyResults.skipped} skipped${colors.reset}${storyResults.errors > 0 ? `, ${colors.red}${storyResults.errors} errors${colors.reset}` : ''}\n`);
538
569
 
539
570
  // Step 4: Update unit status
540
- const unitResult = await updateUnitStatus(bolt);
571
+ await updateUnitStatus(bolt);
541
572
  console.log();
542
573
 
543
574
  // Step 5: Update intent status
544
- const intentResult = await updateIntentStatus(bolt);
575
+ await updateIntentStatus(bolt);
545
576
  console.log();
546
577
 
547
578
  // Final summary
@@ -7,8 +7,8 @@
7
7
  * Status must cascade correctly: Bolt complete → Stories complete → Unit complete → Intent complete
8
8
  *
9
9
  * Usage:
10
- * node .specsmd/scripts/status-integrity.js
11
- * node .specsmd/scripts/status-integrity.js --fix
10
+ * node .specsmd/aidlc/scripts/status-integrity.js
11
+ * node .specsmd/aidlc/scripts/status-integrity.js --fix
12
12
  *
13
13
  * Cross-platform: Works on Linux, macOS, Windows via Node.js
14
14
  */
@@ -584,8 +584,8 @@ Options:
584
584
  --help, -h Show this help message
585
585
 
586
586
  Examples:
587
- node .specsmd/scripts/status-integrity.js
588
- node .specsmd/scripts/status-integrity.js --fix
587
+ node .specsmd/aidlc/scripts/status-integrity.js
588
+ node .specsmd/aidlc/scripts/status-integrity.js --fix
589
589
  `);
590
590
  process.exit(0);
591
591
  }
@@ -182,6 +182,23 @@ Ready to proceed?
182
182
 
183
183
  If the bolt type specifies automatic validation criteria, follow those rules.
184
184
 
185
+ ### 8b. Final Stage Checkpoint (CRITICAL RE-READ)
186
+
187
+ **⚠️ If this is the FINAL stage of the bolt**, before presenting completion:
188
+
189
+ 1. **STOP** and re-read **Step 10** from this skill
190
+ 2. This step is often skipped due to context distance - re-reading prevents this
191
+ 3. Do NOT report bolt as complete until you have executed Step 10
192
+
193
+ ```text
194
+ ┌─────────────────────────────────────────────────────────────┐
195
+ │ FINAL STAGE DETECTED │
196
+ │ → Re-read Step 10 NOW │
197
+ │ → You MUST run: node .specsmd/aidlc/scripts/bolt-complete.js │
198
+ │ → Do NOT manually edit story files │
199
+ └─────────────────────────────────────────────────────────────┘
200
+ ```
201
+
185
202
  ### 9. Update Bolt File on Stage Completion
186
203
 
187
204
  **Trigger**: After EACH stage completion (not just final stage).
@@ -210,14 +227,25 @@ stages_completed:
210
227
 
211
228
  ---
212
229
 
213
- ### 10. Mark Bolt Complete (CRITICAL - MANDATORY ON FINAL STAGE)
230
+ ### 10. Mark Bolt Complete (HARD GATE - MANDATORY ON FINAL STAGE)
214
231
 
215
232
  **Trigger**: ONLY when this is the FINAL stage.
216
233
 
217
- **⚠️ DO NOT SKIP THIS STEP. When the final stage completes, you MUST run the command below.**
234
+ ```text
235
+ ⛔ HARD GATE - SCRIPT EXECUTION REQUIRED
236
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
237
+ You CANNOT report bolt completion without:
238
+ 1. Running the bolt-complete.js script
239
+ 2. Showing the script output to the user
240
+
241
+ If you skip this, the memory-bank becomes inconsistent.
242
+ Do NOT manually edit story files - the script handles everything.
243
+ ```
244
+
245
+ **Run this command:**
218
246
 
219
247
  ```bash
220
- node .specsmd/scripts/bolt-complete.js {bolt-id}
248
+ node .specsmd/aidlc/scripts/bolt-complete.js {bolt-id}
221
249
  ```
222
250
 
223
251
  **What this command does (deterministically):**
@@ -289,10 +289,23 @@ Establish execution order based on dependencies:
289
289
 
290
290
  Check the plan against:
291
291
 
292
+ **Frontmatter Validation (CRITICAL - check each bolt.md)**:
293
+
294
+ - [ ] `id` - Bolt identifier present
295
+ - [ ] `unit` - Parent unit ID present
296
+ - [ ] `intent` - Parent intent ID present
297
+ - [ ] `type` - Bolt type specified (`ddd-construction-bolt` or `simple-construction-bolt`)
298
+ - [ ] `status` - Set to `planned`
299
+ - [ ] `stories` - **Array of story IDs included** (NOT just in body, MUST be in frontmatter)
300
+ - [ ] `created` - Timestamp present
301
+ - [ ] `requires_bolts` - Dependency array present (can be empty `[]`)
302
+ - [ ] `enables_bolts` - Enables array present (can be empty `[]`)
303
+ - [ ] `complexity` - Complexity block with all 4 fields
304
+
305
+ **Content Validation**:
306
+
292
307
  - [ ] All stories are assigned to bolts
293
308
  - [ ] Dependencies are respected (bolt-to-bolt AND unit-to-unit)
294
- - [ ] All dependencies documented in frontmatter
295
- - [ ] Complexity assessment included for each bolt
296
309
  - [ ] Each bolt has clear outputs
297
310
  - [ ] No bolt is too large (max 5-6 stories)
298
311
  - [ ] No circular dependencies exist
@@ -57,6 +57,27 @@ complexity:
57
57
 
58
58
  ---
59
59
 
60
+ ## Required Frontmatter Fields (VALIDATION CHECKLIST)
61
+
62
+ Before creating a bolt, verify ALL required fields are present:
63
+
64
+ | Field | Required | Description |
65
+ |-------|----------|-------------|
66
+ | `id` | **YES** | Bolt identifier (format: `{BBB}-{unit-name}`) |
67
+ | `unit` | **YES** | Parent unit ID |
68
+ | `intent` | **YES** | Parent intent ID |
69
+ | `type` | **YES** | Bolt type (`ddd-construction-bolt` or `simple-construction-bolt`) |
70
+ | `status` | **YES** | Current status (`planned`, `in-progress`, `completed`, `blocked`) |
71
+ | `stories` | **YES** | Array of story IDs included in this bolt |
72
+ | `created` | **YES** | Creation timestamp |
73
+ | `requires_bolts` | **YES** | Array of bolt IDs this depends on (can be empty `[]`) |
74
+ | `enables_bolts` | **YES** | Array of bolt IDs waiting on this (can be empty `[]`) |
75
+ | `complexity` | **YES** | Complexity assessment block |
76
+
77
+ **If any required field is missing, the bolt is INVALID.**
78
+
79
+ ---
80
+
60
81
  ## Content
61
82
 
62
83
  ```markdown
@@ -270,6 +270,11 @@ created: {YYYY-MM-DDTHH:MM:SSZ}
270
270
  - **Tests**: {passed}/{total} passed
271
271
  - **Coverage**: {percentage}%
272
272
 
273
+ ### Test Files
274
+
275
+ - [x] `{path/to/test-file.test.ts}` - {what this test file covers}
276
+ - [x] `{path/to/another.test.ts}` - {what this test file covers}
277
+
273
278
  ### Acceptance Criteria Validation
274
279
 
275
280
  - ✅/❌ **{Criterion}**: {Status}
@@ -56,7 +56,12 @@ class AnalyticsTracker {
56
56
  const Mixpanel = require('mixpanel');
57
57
  this.mixpanel = Mixpanel.init(MIXPANEL_TOKEN, {
58
58
  protocol: 'https',
59
- host: 'api-eu.mixpanel.com' // EU endpoint for GDPR compliance
59
+ host: 'api-eu.mixpanel.com', // EU endpoint for GDPR compliance
60
+ // Note: geolocate: true enables IP-based geolocation for analytics.
61
+ // This data is used solely for aggregate usage insights (e.g., country-level
62
+ // adoption patterns). No personal identifiers are collected. Users can
63
+ // opt out via the --no-telemetry flag or SPECSMD_NO_TELEMETRY env var.
64
+ geolocate: true
60
65
  });
61
66
 
62
67
  // Generate IDs
@@ -117,7 +122,7 @@ class AnalyticsTracker {
117
122
  if (waitForDelivery) {
118
123
  return new Promise((resolve) => {
119
124
  try {
120
- this.mixpanel.track(eventName, eventData, (err) => {
125
+ this.mixpanel.track(eventName, eventData, () => {
121
126
  // Resolve regardless of error - silent failure
122
127
  resolve();
123
128
  });
package/lib/installer.js CHANGED
@@ -229,6 +229,9 @@ async function installFlow(flowKey, toolKeys) {
229
229
  if (await fs.pathExists(path.join(flowPath, 'shared'))) {
230
230
  await fs.copy(path.join(flowPath, 'shared'), path.join(targetFlowDir, 'shared'));
231
231
  }
232
+ if (await fs.pathExists(path.join(flowPath, 'scripts'))) {
233
+ await fs.copy(path.join(flowPath, 'scripts'), path.join(targetFlowDir, 'scripts'));
234
+ }
232
235
 
233
236
  // Copy config files
234
237
  if (await fs.pathExists(path.join(flowPath, 'memory-bank.yaml'))) {
@@ -250,20 +253,6 @@ async function installFlow(flowKey, toolKeys) {
250
253
 
251
254
  CLIUtils.displayStatus('', 'Installed flow resources', 'success');
252
255
 
253
- // Step 2.5: Install local scripts for deterministic operations
254
- // These scripts are version-matched to the installed specsmd version
255
- const scriptsDir = path.join(specsmdDir, 'scripts');
256
- await fs.ensureDir(scriptsDir);
257
-
258
- const sourceScriptsDir = path.join(__dirname, '..', 'scripts');
259
- if (await fs.pathExists(sourceScriptsDir)) {
260
- await fs.copy(sourceScriptsDir, scriptsDir);
261
- CLIUtils.displayStatus('', 'Installed local scripts', 'success');
262
- }
263
-
264
- // Note: Scripts are invoked directly via relative path (e.g., node .specsmd/scripts/bolt-complete.js)
265
- // No npm scripts added to package.json to avoid dependency on package.json for execution
266
-
267
256
  // NOTE: memory-bank/ is NOT created during installation
268
257
  // It will be created when user runs project-init
269
258
  // This allows us to detect if project is initialized by checking for memory-bank/standards/
@@ -1,8 +1,5 @@
1
1
  const ToolInstaller = require('./ToolInstaller');
2
- const fs = require('fs-extra');
3
2
  const path = require('path');
4
- const CLIUtils = require('../cli-utils');
5
- const { theme } = CLIUtils;
6
3
 
7
4
  class WindsurfInstaller extends ToolInstaller {
8
5
  get key() {
@@ -20,57 +17,6 @@ class WindsurfInstaller extends ToolInstaller {
20
17
  get detectPath() {
21
18
  return '.windsurf';
22
19
  }
23
-
24
- /**
25
- * Override to add frontmatter for Windsurf workflows
26
- */
27
- async installCommands(flowPath, config) {
28
- const targetCommandsDir = this.commandsDir;
29
- console.log(theme.dim(` Installing workflows to ${targetCommandsDir}/...`));
30
- await fs.ensureDir(targetCommandsDir);
31
-
32
- const commandsSourceDir = path.join(flowPath, 'commands');
33
-
34
- if (!await fs.pathExists(commandsSourceDir)) {
35
- console.log(theme.warning(` No commands folder found at ${commandsSourceDir}`));
36
- return [];
37
- }
38
-
39
- const commandFiles = await fs.readdir(commandsSourceDir);
40
- const installedFiles = [];
41
-
42
- for (const cmdFile of commandFiles) {
43
- if (cmdFile.endsWith('.md')) {
44
- const sourcePath = path.join(commandsSourceDir, cmdFile);
45
- const prefix = (config && config.command && config.command.prefix) ? `${config.command.prefix}-` : '';
46
-
47
- const targetFileName = `specsmd-${prefix}${cmdFile}`;
48
- const targetPath = path.join(targetCommandsDir, targetFileName);
49
-
50
- // Extract agent name from target filename (e.g., "specsmd-master-agent.md" -> "specsmd-master-agent")
51
- const agentName = targetFileName.replace(/\.md$/, '');
52
-
53
- // Read source content and add Windsurf frontmatter
54
- let content = await fs.readFile(sourcePath, 'utf8');
55
-
56
- // Add Windsurf-specific frontmatter if not present
57
- if (!content.startsWith('---')) {
58
- const frontmatter = `---
59
- description: ${agentName}
60
- ---
61
-
62
- `;
63
- content = frontmatter + content;
64
- }
65
-
66
- await fs.writeFile(targetPath, content);
67
- installedFiles.push(targetFileName);
68
- }
69
- }
70
-
71
- CLIUtils.displayStatus('', `Installed ${installedFiles.length} workflows for ${this.name}`, 'success');
72
- return installedFiles;
73
- }
74
20
  }
75
21
 
76
22
  module.exports = WindsurfInstaller;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specsmd",
3
- "version": "0.0.0-dev.2",
3
+ "version": "0.0.0-dev.21",
4
4
  "description": "Multi-agent orchestration system for AI-native software development. Delivers AI-DLC, Agile, and custom SDLC flows as markdown-based agent systems.",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {