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 +10 -2
- package/flows/aidlc/commands/construction-agent.md +4 -0
- package/flows/aidlc/commands/inception-agent.md +4 -0
- package/flows/aidlc/commands/master-agent.md +4 -0
- package/flows/aidlc/commands/operations-agent.md +4 -0
- package/{scripts → flows/aidlc/scripts}/artifact-validator.js +3 -3
- package/{scripts → flows/aidlc/scripts}/bolt-complete.js +35 -4
- package/{scripts → flows/aidlc/scripts}/status-integrity.js +4 -4
- package/flows/aidlc/skills/construction/bolt-start.md +31 -3
- package/flows/aidlc/skills/inception/bolt-plan.md +15 -2
- package/flows/aidlc/templates/construction/bolt-template.md +21 -0
- package/flows/aidlc/templates/construction/bolt-types/simple-construction-bolt.md +5 -0
- package/lib/analytics/tracker.js +7 -2
- package/lib/installer.js +3 -14
- package/lib/installers/WindsurfInstaller.js +0 -54
- package/package.json +1 -1
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
|
-
- [
|
|
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
|
|
|
@@ -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
|
-
|
|
571
|
+
await updateUnitStatus(bolt);
|
|
541
572
|
console.log();
|
|
542
573
|
|
|
543
574
|
// Step 5: Update intent status
|
|
544
|
-
|
|
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 (
|
|
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
|
-
|
|
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}
|
package/lib/analytics/tracker.js
CHANGED
|
@@ -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, (
|
|
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.
|
|
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": {
|