sdd-pipeline 1.2.8 → 1.3.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 CHANGED
@@ -276,22 +276,36 @@ Two Interfaces (same logic):
276
276
  Shell CLI: sdd bmad "feature" → bin/sdd.cjs
277
277
  Claude Code: /sdd bmad "feature" → .claude/commands/sdd.md
278
278
 
279
- Pipeline files:
279
+ Project structure:
280
280
  ├── .sdd/config.json # Phase tracking
281
- ├── templates/ # SDD templates
282
- ├── skills/ # Implementation skills (Phase 4)
283
- ├── .claude/commands/ # Claude Code slash commands
284
- ├── commands/ # Standalone PowerShell scripts
285
- ├── run-converge.ps1 # Validation automation
281
+ ├── templates/ # SDD templates (synced from bundle)
282
+ ├── skills/ # Implementation skills (synced from bundle)
283
+ ├── .claude/commands/ # Claude Code slash commands (synced from bundle)
284
+ ├── commands/ # Standalone PowerShell scripts (synced from bundle)
285
+ ├── lib/
286
+ │ ├── bmad.js # BMAD CLI wrapper
287
+ │ ├── bmad/ # BMAD modules
288
+ │ └── bundle/ # SOURCE OF TRUTH for npm package
289
+ ├── scripts/
290
+ │ └── sync-bundle.ps1 # Sync bundle to working directories
286
291
  └── extensions/ # Domain-specific (api/frontend/backend)
287
292
 
288
293
  npm package (sdd-pipeline):
289
294
  ├── bin/sdd.cjs # CLI entry
290
- ├── lib/init.js # Extract pipeline
295
+ ├── lib/bmad.js # CLI wrapper
291
296
  ├── lib/bmad/ # BMAD orchestrator
292
- └── lib/bundle/ # 70 pipeline files for distribution
297
+ └── lib/bundle/ # All pipeline files for distribution
293
298
  ```
294
299
 
300
+ ### Development Workflow
301
+
302
+ 1. Edit files in `lib/bundle/` (source of truth)
303
+ 2. Run `npm run sync` to sync to working directories
304
+ 3. Test with `npm run pack --dry-run`
305
+ 4. Commit and publish
306
+
307
+ **Important:** After modifying `lib/bundle/`, always run `npm run sync` before testing!
308
+
295
309
  ---
296
310
 
297
311
  ## Requirements
@@ -314,7 +328,7 @@ jobs:
314
328
  runs-on: windows-latest
315
329
  steps:
316
330
  - uses: actions/checkout@v4
317
- - run: pwsh run-converge.ps1 -Url '${{ env.DEV_URL }}' -Strict
331
+ - run: pwsh lib/bundle/run-converge.ps1 -Url '${{ env.DEV_URL }}' -Strict
318
332
  ```
319
333
 
320
334
  ---
@@ -324,7 +338,7 @@ jobs:
324
338
  | Field | Value |
325
339
  |-------|-------|
326
340
  | Name | `sdd-pipeline` |
327
- | Version | `1.2.7` |
341
+ | Version | `1.3.0` |
328
342
  | Registry | npmjs.com |
329
343
  | CLI command | `sdd` |
330
344
  | Claude Code command | `/sdd` |
package/bin/sdd.cjs CHANGED
@@ -143,10 +143,10 @@ switch (cmd) {
143
143
  console.log('=== SDD Converge Validation ===')
144
144
  console.log('')
145
145
  console.log('Full validation (requires dev server):')
146
- console.log(' pwsh run-converge.ps1 -Url http://localhost:3000 -Strict')
146
+ console.log(' pwsh lib/bundle/run-converge.ps1 -Url http://localhost:3000 -Strict')
147
147
  console.log('')
148
148
  console.log('Per-task validation:')
149
- console.log(' pwsh run-converge.ps1 -TaskId T-001')
149
+ console.log(' pwsh lib/bundle/run-converge.ps1 -TaskId T-001')
150
150
  console.log('')
151
151
  console.log('Claude Code:')
152
152
  console.log(' claude "/sdd-converge"')
@@ -1,18 +1,18 @@
1
1
  ---
2
- # SDD BMAD — Brainstorm, Multi-Agent, Define (Interactive)
2
+ # SDD BMAD — Brainstorm, Multi-Agent, Define (Interactive + Batch)
3
3
  ---
4
4
  tool: Bash
5
5
  when: always
6
- description: Phase 0 — Interactive brainstorm. Asks 9 discovery questions (Problem/Architect/UX tiers), applies problem-first inversion, generates confidence-scored brief. Outputs to sdd/brief.md. Args: "<feature description>"
6
+ description: Phase 0 — Interactive brainstorm with batch mode. Asks 9 discovery questions (Problem/Architect/UX tiers), applies problem-first inversion, generates confidence-scored brief. Outputs to sdd/brief.md. Args: "<feature>" or "--batch <file.json>" or "--answers '{...}'"
7
7
  ---
8
8
  # ============================================================
9
- # SDD BMAD Interactive Mode
9
+ # SDD BMAD Interactive + Batch Mode
10
10
  # ============================================================
11
11
  # Phase 0: Brainstorm, Multi-Agent, Define
12
12
  # Asks 9 discovery questions (Tier 1 + 2 + 3)
13
13
  # Applies problem-first inversion
14
- # Spawns 3 parallel agents (PM / Architect / UX)
15
14
  # Produces confidence-scored brief
15
+ # Supports batch mode: --batch file.json or --answers '{...}'
16
16
  # ============================================================
17
17
 
18
18
  $ErrorActionPreference = 'Stop'
@@ -27,16 +27,80 @@ function Sanitize-UserInput {
27
27
 
28
28
  # --- Parse arguments ---
29
29
  $rawInput = $args -join ' '
30
- if (-not $rawInput) {
30
+ $batchMode = $false
31
+ $batchFile = $null
32
+ $batchAnswers = $null
33
+ $answers = @{}
34
+
35
+ # Check for batch mode
36
+ if ($args -contains "--batch") {
37
+ $batchMode = $true
38
+ $batchIdx = [array]::IndexOf($args, "--batch")
39
+ if ($batchIdx -ge 0 -and $batchIdx + 1 -lt $args.Count) {
40
+ $batchFile = $args[$batchIdx + 1]
41
+ }
42
+ } elseif ($args -contains "--answers") {
43
+ $batchMode = $true
44
+ $batchIdx = [array]::IndexOf($args, "--answers")
45
+ if ($batchIdx -ge 0 -and $batchIdx + 1 -lt $args.Count) {
46
+ $batchAnswers = $args[$batchIdx + 1]
47
+ }
48
+ }
49
+
50
+ # Extract feature description (first positional arg, or --input value)
51
+ $featureDesc = ($args | Where-Object { $_ -notmatch '^--' } | Select-Object -First 1)
52
+
53
+ if (-not $featureDesc) {
31
54
  Write-Host "Usage: /sdd-bmad <feature description>"
32
- Write-Host "Example: /sdd-bmad `"landing page for my SaaS product`""
55
+ Write-Host " /sdd-bmad --batch <answers.json>"
56
+ Write-Host " /sdd-bmad --answers '`{`"q1`":`"answer`",...`}`'"
57
+ Write-Host ""
58
+ Write-Host "Example interactive: /sdd-bmad `"landing page for my SaaS product`""
59
+ Write-Host "Example batch: /sdd-bmad --batch answers.json"
33
60
  exit 1
34
61
  }
35
62
 
36
- $sanitizedInput = Sanitize-UserInput -Input $rawInput
37
- Write-Host ""
38
- Write-Host "=== BMAD Interactive Session ===" -ForegroundColor Cyan
39
- Write-Host "Input sanitized. Prompt injection protection active." -ForegroundColor Gray
63
+ $sanitizedInput = Sanitize-UserInput -Input $featureDesc
64
+
65
+ if ($batchMode) {
66
+ Write-Host ""
67
+ Write-Host "=== BMAD Batch Mode ===" -ForegroundColor Cyan
68
+
69
+ # Load answers from file or inline JSON
70
+ if ($batchFile) {
71
+ if (Test-Path $batchFile) {
72
+ try {
73
+ $jsonContent = Get-Content $batchFile -Raw
74
+ $batchData = $jsonContent | ConvertFrom-Json
75
+ foreach ($prop in $batchData.PSObject.Properties) {
76
+ $answers[$prop.Name] = Sanitize-UserInput -Input $prop.Value
77
+ }
78
+ Write-Host "Loaded $($answers.Count) answers from: $batchFile" -ForegroundColor Green
79
+ } catch {
80
+ Write-Host "[ERROR] Failed to parse JSON file: $_" -ForegroundColor Red
81
+ exit 1
82
+ }
83
+ } else {
84
+ Write-Host "[ERROR] Batch file not found: $batchFile" -ForegroundColor Red
85
+ exit 1
86
+ }
87
+ } elseif ($batchAnswers) {
88
+ try {
89
+ $batchData = $batchAnswers | ConvertFrom-Json
90
+ foreach ($prop in $batchData.PSObject.Properties) {
91
+ $answers[$prop.Name] = Sanitize-UserInput -Input $prop.Value
92
+ }
93
+ Write-Host "Loaded $($answers.Count) answers from inline JSON" -ForegroundColor Green
94
+ } catch {
95
+ Write-Host "[ERROR] Failed to parse inline JSON: $_" -ForegroundColor Red
96
+ exit 1
97
+ }
98
+ }
99
+ } else {
100
+ Write-Host ""
101
+ Write-Host "=== BMAD Interactive Session ===" -ForegroundColor Cyan
102
+ Write-Host "Input sanitized. Prompt injection protection active." -ForegroundColor Gray
103
+ }
40
104
 
41
105
  # --- Date helpers ---
42
106
  $date = Get-Date -Format 'yyyy-MM-dd'
@@ -106,26 +170,28 @@ $questions = @(
106
170
  @{ id="q9"; tier=3; tierName="UX & Polish"; q="What could go wrong that we need to handle gracefully?"; hint="Network failure, empty data, permission denied, slow loading" }
107
171
  )
108
172
 
109
- # Answers hash
110
- $answers = @{}
111
-
112
- foreach ($q in $questions) {
113
- # Show tier header on first question of each tier
114
- if ($q.id -eq "q1") { Write-Host "=== Tier 1: Problem Definition ===" -ForegroundColor Cyan }
115
- if ($q.id -eq "q4") { Write-Host ""; Write-Host "=== Tier 2: Technical & Feasibility ===" -ForegroundColor Cyan }
116
- if ($q.id -eq "q7") { Write-Host ""; Write-Host "=== Tier 3: UX & Polish ===" -ForegroundColor Cyan }
173
+ # Skip interactive questions in batch mode (answers already loaded)
174
+ if (-not $batchMode) {
175
+ foreach ($q in $questions) {
176
+ # Show tier header on first question of each tier
177
+ if ($q.id -eq "q1") { Write-Host "=== Tier 1: Problem Definition ===" -ForegroundColor Cyan }
178
+ if ($q.id -eq "q4") { Write-Host ""; Write-Host "=== Tier 2: Technical & Feasibility ===" -ForegroundColor Cyan }
179
+ if ($q.id -eq "q7") { Write-Host ""; Write-Host "=== Tier 3: UX & Polish ===" -ForegroundColor Cyan }
117
180
 
118
- Write-Host ""
119
- Write-Host "[$($q.id)] $($q.q)" -ForegroundColor White
120
- Write-Host "Hint: $($q.hint)" -ForegroundColor Gray
181
+ Write-Host ""
182
+ Write-Host "[$($q.id)] $($q.q)" -ForegroundColor White
183
+ Write-Host "Hint: $($q.hint)" -ForegroundColor Gray
121
184
 
122
- $answer = Read-Host "Your answer"
123
- $answer = Sanitize-UserInput -Input $answer
124
- $answers[$q.id] = $answer
185
+ $answer = Read-Host "Your answer"
186
+ $answer = Sanitize-UserInput -Input $answer
187
+ $answers[$q.id] = $answer
125
188
 
126
- if (-not $answer) {
127
- Write-Host "(skipped — answer recorded as empty)" -ForegroundColor DarkGray
189
+ if (-not $answer) {
190
+ Write-Host "(skipped — answer recorded as empty)" -ForegroundColor DarkGray
191
+ }
128
192
  }
193
+ } else {
194
+ Write-Host "Using batch mode — skipping interactive questions." -ForegroundColor Gray
129
195
  }
130
196
 
131
197
  # ============================================================
@@ -2,39 +2,158 @@
2
2
  ---
3
3
  tool: Bash
4
4
  when: always
5
- description: Phase 5 — Validate implementation matches SPEC.md. Self-correcting converge loop. Args: [--task <task-id>] or full project. Checks clause IDs, exact text, hex colors, ACs, dev server health.
5
+ args: --task <task-id>
6
+ description: Phase 5 — Validate implementation matches SPEC.md. Self-correcting converge loop. Args: [--task <task-id>] or full project. Checks clause IDs, exact text, hex colors, ACs, dev server health. Output to sdd/converge/.
6
7
  ---
7
- $missing = @()
8
+ $ErrorActionPreference = 'Continue'
8
9
 
9
- if (!(Test-Path "SPEC.md")) {
10
- Write-Host "ERROR: SPEC.md not found" -ForegroundColor Red
11
- $missing += "SPEC.md"
10
+ # Parse task argument
11
+ $taskId = $null
12
+ if ($argsRaw -match '-task["\s]+([T-t]-\d+)') {
13
+ $taskId = $Matches[1].ToUpper()
12
14
  }
13
15
 
14
- # Find task directory
15
- $taskDirs = Get-ChildItem -Filter "task-*-*" -Directory -ErrorAction SilentlyContinue
16
- if ($taskDirs) {
17
- $taskDir = ($taskDirs | Select-Object -First 1).Name
18
- if (!(Test-Path "$taskDir/MASTER-TASKS.md")) {
19
- Write-Host "ERROR: $taskDir/MASTER-TASKS.md not found" -ForegroundColor Red
20
- $missing += "$taskDir/MASTER-TASKS.md"
21
- }
22
- } else {
23
- Write-Host "ERROR: No task directory found (task-*/)" -ForegroundColor Red
24
- $missing += "task-*/MASTER-TASKS.md"
16
+ # Ensure converge directory exists
17
+ $convergeDir = "sdd/converge"
18
+ if (-not (Test-Path $convergeDir)) {
19
+ New-Item -ItemType Directory -Path $convergeDir -Force | Out-Null
25
20
  }
26
21
 
27
- if ($missing.Count -gt 0) {
28
- Write-Host "Missing artifacts: $($missing -join ', ')" -ForegroundColor Red
29
- Write-Host "Run /sdd-tasks first."
30
- exit 1
22
+ # Run converge validation
23
+ Write-Host "=== SDD Converge Validation ===" -ForegroundColor Cyan
24
+
25
+ if ($taskId) {
26
+ Write-Host "Running per-task converge for: $taskId" -ForegroundColor Cyan
27
+ pwsh run-converge.ps1 -TaskId $taskId
28
+ } else {
29
+ Write-Host "Running full project converge..." -ForegroundColor Cyan
30
+ pwsh run-converge.ps1
31
31
  }
32
32
 
33
- Write-Host "All required artifacts verified." -ForegroundColor Green
34
- Write-Host "Running converge validation..."
35
- Write-Host "Run: pwsh run-converge.ps1 -Url 'http://localhost:3000' -Strict"
33
+ Write-Host ""
34
+ Write-Host "Converge reports saved to: $convergeDir/" -ForegroundColor Green
35
+
36
+ ## SDD Converge — Phase 5 Validation
37
+
38
+ **Purpose:** Verify implementation matches SPEC.md. Run per-task or full project.
39
+
40
+ **Output Location:** `sdd/converge/` (v1.1.0+)
41
+
42
+ ### Usage
43
+
44
+ ```bash
45
+ # Full project converge (after all tasks)
46
+ claude "/sdd-converge"
47
+
48
+ # Per-task converge (after each task)
49
+ pwsh run-converge.ps1 -TaskId "T-001"
50
+
51
+ # Per-task with strict mode
52
+ pwsh run-converge.ps1 -TaskId "T-002" -Strict
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Per-Task Converge (Recommended)
58
+
59
+ Run after each task to catch issues early:
60
+
61
+ ```
62
+ pwsh run-converge.ps1 -TaskId "T-001"
63
+ pwsh run-converge.ps1 -TaskId "T-002" -Strict
64
+ ```
65
+
66
+ ### What it validates:
67
+ - ✅ All spec clause IDs match implementation
68
+ - ✅ Required text appears verbatim
69
+ - ✅ Colors match hex values
70
+ - ✅ Acceptance criteria met
71
+ - ✅ Edge cases handled
72
+
73
+ ### Output:
74
+ - `sdd/converge/task-T-XXX/report.md` — Per-task validation report
36
75
 
37
76
  ---
38
77
 
39
- # Run converge automation: pwsh run-converge.ps1
40
- # Validates: SPEC.md + task-*/MASTER-TASKS.md
78
+ ## Full Project Converge
79
+
80
+ Run after all tasks complete:
81
+
82
+ ```
83
+ pwsh run-converge.ps1 -Url 'http://localhost:3000' -Strict
84
+ ```
85
+
86
+ ### What it validates:
87
+ - ✅ All artifacts exist (sdd/SPEC.md, sdd/tasks/)
88
+ - ✅ SPEC.md structure complete
89
+ - ✅ Dev server health check
90
+ - ✅ All tasks implemented
91
+ - ✅ Lighthouse/axe-core (if URL provided)
92
+
93
+ ### Output:
94
+ - `sdd/converge/validation.md` — Full project validation
95
+
96
+ ---
97
+
98
+ ## Phase Status
99
+
100
+ ```
101
+ ╔══════════════════════════════════════════════════════════════╗
102
+ ║ SDD Converge — Phase 5 ║
103
+ ╠══════════════════════════════════════════════════════════════╣
104
+ ║ Per-Task: Run after each task → sdd/converge/task-T-XXX║
105
+ ║ Full: Run after all tasks → sdd/converge/validation ║
106
+ ║ ║
107
+ ║ Flow: Task → Fix → Re-converge → Next Task ║
108
+ ╚══════════════════════════════════════════════════════════════╝
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Agent Instructions
114
+
115
+ After implementing a task:
116
+
117
+ 1. **Generate converge report:**
118
+ ```bash
119
+ pwsh run-converge.ps1 -TaskId "T-XXX"
120
+ ```
121
+
122
+ 2. **Review report** for any failures
123
+
124
+ 3. **If PASS:** Update task status in MASTER-TASKS.md → proceed to next task
125
+
126
+ 4. **If FAIL:** Fix issues → re-run converge until PASS
127
+
128
+ 5. **If SPEC issue:** Update SPEC.md → re-generate affected tasks
129
+
130
+ ---
131
+
132
+ ## Validation Checks
133
+
134
+ ### Per-Task (run-converge.ps1 -TaskId)
135
+ | Check | Description |
136
+ |-------|-------------|
137
+ | Clause IDs | All `[SC-xxx]` from SPEC.md found in implementation |
138
+ | Text Match | Required text appears verbatim |
139
+ | Color Match | Hex values match exactly |
140
+ | AC Check | Acceptance criteria `[AC-xxx]` verified |
141
+
142
+ ### Full Project (run-converge.ps1)
143
+ | Check | Description |
144
+ |-------|-------------|
145
+ | Artifacts | SPEC.md, TASKS.md, task files exist |
146
+ | Structure | Required sections in SPEC.md |
147
+ | URL Safety | No SSRF vulnerabilities |
148
+ | Dev Health | Target server reachable |
149
+ | Live Tests | Lighthouse, axe-core (if URL provided) |
150
+
151
+ ---
152
+
153
+ ## Loop-Back Rules
154
+
155
+ | Failure Type | Re-enter Phase | Action |
156
+ |-------------|---------------|--------|
157
+ | Clause mismatch | Phase 4 | Fix implementation |
158
+ | SPEC unclear | Phase 2 | Update SPEC.md |
159
+ | Intent wrong | Phase 1 | Regenerate BMAD brief |
@@ -10,7 +10,7 @@ $ErrorActionPreference = "Stop"
10
10
  # Parse arguments
11
11
  $args = $argsRaw.Trim()
12
12
 
13
- # Output path resolution
13
+ # SDD Path Resolution
14
14
  $SDD_OUTPUT_BASE = "sdd"
15
15
  $SDD_TASKS_DIR = "$SDD_OUTPUT_BASE/tasks"
16
16
 
@@ -18,11 +18,9 @@ $SDD_TASKS_DIR = "$SDD_OUTPUT_BASE/tasks"
18
18
  if (Test-Path ".sdd/config.json") {
19
19
  try {
20
20
  $config = Get-Content ".sdd/config.json" -Raw | ConvertFrom-Json
21
- if ($config.output -and $config.output.baseDir) {
22
- $SDD_OUTPUT_BASE = $config.output.baseDir
23
- }
24
- if ($config.output -and $config.output.tasksDir) {
25
- $SDD_TASKS_DIR = $config.output.tasksDir
21
+ if ($config.output) {
22
+ if ($config.output.baseDir) { $SDD_OUTPUT_BASE = $config.output.baseDir }
23
+ if ($config.output.tasksDir) { $SDD_TASKS_DIR = $config.output.tasksDir }
26
24
  }
27
25
  } catch {}
28
26
  }
@@ -53,6 +51,16 @@ if (Test-Path $specPath) {
53
51
  $activeSpec = $legacySpecPath
54
52
  }
55
53
 
54
+ # Gate 2: Template must exist
55
+ $templatePath = "templates/task-detail.template.md"
56
+ if (-not (Test-Path $templatePath)) {
57
+ Write-Host "[ERROR] Template not found: $templatePath" -ForegroundColor Red
58
+ Write-Host "Run /sdd-init first" -ForegroundColor Yellow
59
+ exit 1
60
+ }
61
+ $templateContent = Get-Content $templatePath -Raw -Encoding UTF8
62
+ Write-Host "[OK] Template: $templatePath" -ForegroundColor Green
63
+
56
64
  Write-Host ""
57
65
  Write-Host "=== SDD Tasks Generator - Phase 3 ===" -ForegroundColor Cyan
58
66
 
@@ -187,80 +195,42 @@ $($testCategories -join ', ')
187
195
  ## Notes
188
196
 
189
197
  Generated from: SPEC.md
190
- Auto-generated by SDD Pipeline v1.2.2
198
+ Auto-generated by SDD Pipeline v1.3.0
191
199
  "@
192
200
 
193
201
  Set-Content -Path "$taskDir/MASTER-TASKS.md" -Value $masterContent -Encoding UTF8
194
202
  Write-Host " [CREATED] MASTER-TASKS.md" -ForegroundColor Gray
195
203
 
196
- # Generate individual task files with SPEC details
197
- $taskNum = 1
204
+ # Generate individual task files using template
198
205
  foreach ($task in $tasks) {
199
206
  $safeName = $task.Name -replace '[^a-zA-Z0-9]', '-' -replace '-+', '-'
200
207
  $filename = "$($task.Id)-$safeName.md"
201
208
 
202
- # Extract feature content if available
203
- $featureContent = ""
209
+ # Determine spec sections based on task type
204
210
  $specSection = "4.1"
205
- $extractedClauses = @()
206
-
207
211
  if ($task.Name -eq "Project Setup") {
208
- # Setup task - extract colors and dimensions from SPEC
209
- $colors = @()
210
- if ($specContent -match '(?s)## 3\.2.*?Colors(.+?)(?=##|\Z)') {
211
- $colorMatches = [regex]::Matches($Matches[1], '`([^`]+)`')
212
- foreach ($m in $colorMatches) {
213
- $colors += $m.Groups[1].Value
214
- }
215
- }
216
- $featureContent = "## Files to Create`n`n"
217
- $featureContent += "- `index.html` — Main calculator page`n"
218
- $featureContent += "- `styles.css` — Calculator styling`n"
219
- $featureContent += "- `app.js` — Calculator logic`n`n"
220
- $featureContent += "## Implementation Steps`n`n"
221
- $featureContent += "1. Create `index.html` with calculator structure`n"
222
- $featureContent += "2. Create `styles.css` with colors from SPEC §3.2`n"
223
- $featureContent += "3. Create `app.js` with calculator state`n"
224
212
  $specSection = "3.1, 3.2, 3.3, 6"
225
- } else {
226
- # Feature tasks - extract from feature content
227
- $featureContent = "## Files to Modify/Create`n`n"
228
- $featureContent += "- `app.js` — Add calculator logic`n`n"
229
- $featureContent += "## Implementation Steps`n`n"
230
- $featureContent += "1. Read SPEC.md §4.1 for feature details`n"
231
- $featureContent += "2. Implement the feature logic`n"
232
- $featureContent += "3. Test with manual verification`n"
233
213
  }
234
214
 
215
+ # Format depends_on
235
216
  $dependsStr = ""
236
217
  if ($task.DependsOn.Count -gt 0 -and $task.DependsOn[0]) {
237
- $dependsStr = '"' + ($task.DependsOn -join '", "') + '"'
218
+ $dependsStr = "`"" + ($task.DependsOn -join "`", `"") + "`""
238
219
  }
239
220
 
240
- $taskContent = @"
241
- ---
242
- name: $filename
243
- description: "$($task.Name)"
244
- phase: $($task.Phase)
245
- estimate: 1h
246
- spec_sections: ["$specSection"]
247
- depends_on: [$dependsStr]
248
- ---
249
-
250
- # $($task.Id): $($task.Name)
251
-
252
- $featureContent
253
-
254
- ## Verification
255
-
256
- - [ ] Implementation matches SPEC requirements
257
- - [ ] No console errors
258
- - [ ] Manual test passes
259
- "@
221
+ # Apply template substitutions
222
+ $taskContent = $templateContent
223
+ $taskContent = $taskContent -replace '\{\{TASK_ID\}\}', $task.Id
224
+ $taskContent = $taskContent -replace '\{\{TASK_NAME\}\}', $task.Name
225
+ $taskContent = $taskContent -replace '\{\{FILENAME\}\}', $filename
226
+ $taskContent = $taskContent -replace '\{\{DESCRIPTION\}\}', $task.Name
227
+ $taskContent = $taskContent -replace '\{\{PHASE\}\}', $task.Phase
228
+ $taskContent = $taskContent -replace '\{\{ESTIMATE\}\}', "1h"
229
+ $taskContent = $taskContent -replace '\{\{SPEC_SECTIONS\}\}', $specSection
230
+ $taskContent = $taskContent -replace '\{\{DEPENDS_ON\}\}', $dependsStr
260
231
 
261
232
  Set-Content -Path "$taskDir/$filename" -Value $taskContent -Encoding UTF8
262
233
  Write-Host " [CREATED] $filename" -ForegroundColor Gray
263
- $taskNum++
264
234
  }
265
235
 
266
236
  # Update config
@@ -285,7 +285,7 @@ switch ($cmd) {
285
285
  Write-Host "[OK] All artifacts present." -ForegroundColor Green
286
286
  Write-Host "Running converge validation..."
287
287
  Write-Host ""
288
- Write-Host "Run: pwsh run-converge.ps1 -Url 'http://localhost:3000' -Strict"
288
+ Write-Host "Run: pwsh lib/bundle/run-converge.ps1 -Url 'http://localhost:3000' -Strict"
289
289
  }
290
290
 
291
291
  "help" {
@@ -52,7 +52,7 @@ jobs:
52
52
 
53
53
  - name: Run Converge
54
54
  run: |
55
- pwsh -File run-converge.ps1 -Url "http://localhost:3000" -Strict
55
+ pwsh -File lib/bundle/run-converge.ps1 -Url "http://localhost:3000" -Strict
56
56
 
57
57
  - name: Upload reports
58
58
  if: always()
@@ -143,10 +143,10 @@ switch (cmd) {
143
143
  console.log('=== SDD Converge Validation ===')
144
144
  console.log('')
145
145
  console.log('Full validation (requires dev server):')
146
- console.log(' pwsh run-converge.ps1 -Url http://localhost:3000 -Strict')
146
+ console.log(' pwsh lib/bundle/run-converge.ps1 -Url http://localhost:3000 -Strict')
147
147
  console.log('')
148
148
  console.log('Per-task validation:')
149
- console.log(' pwsh run-converge.ps1 -TaskId T-001')
149
+ console.log(' pwsh lib/bundle/run-converge.ps1 -TaskId T-001')
150
150
  console.log('')
151
151
  console.log('Claude Code:')
152
152
  console.log(' claude "/sdd-converge"')
@@ -8,6 +8,19 @@ if (!(Test-Path $configPath)) {
8
8
 
9
9
  $config = Get-Content $configPath | ConvertFrom-Json
10
10
 
11
+ # SDD Path Resolution - read from config
12
+ $SDD_OUTPUT_BASE = "sdd"
13
+ $SDD_SPEC_FILE = "sdd/SPEC.md"
14
+ $SDD_BRIEF_FILE = "sdd/brief.md"
15
+ $SDD_TASKS_DIR = "sdd/tasks"
16
+
17
+ if ($config.output) {
18
+ if ($config.output.baseDir) { $SDD_OUTPUT_BASE = $config.output.baseDir }
19
+ if ($config.output.spec) { $SDD_SPEC_FILE = $config.output.spec }
20
+ if ($config.output.brief) { $SDD_BRIEF_FILE = $config.output.brief }
21
+ if ($config.output.tasksDir) { $SDD_TASKS_DIR = $config.output.tasksDir }
22
+ }
23
+
11
24
  Write-Host "=== SDD Pipeline Status ===" -ForegroundColor Cyan
12
25
  Write-Host "Project: $($config.project.name)"
13
26
  Write-Host "Phase: $($config.phases.current)"
@@ -34,34 +47,58 @@ foreach ($p in $phases) {
34
47
  if ($Verify) {
35
48
  Write-Host ""
36
49
  Write-Host "=== Verification ===" -ForegroundColor Cyan
37
- $artifacts = @(
38
- @{ File = "SPEC.md"; Phase = "phase2"; Required = $true },
39
- @{ File = "BMAD-brief.md"; Phase = "phase0"; Required = $false }
40
- )
41
50
 
42
- foreach ($a in $artifacts) {
43
- $exists = Test-Path $a.File
44
- $configStatus = if ($config.phases.($a.Phase).status) { $config.phases.($a.Phase).status } else { "unknown" }
45
- if ($exists -and $configStatus -eq "completed") {
46
- Write-Host "[V] $a.File (in sync)" -ForegroundColor Green
47
- } elseif ($exists -and $configStatus -ne "completed") {
48
- Write-Host "[!] $a.File (exists but config shows $configStatus)" -ForegroundColor Yellow
49
- } elseif (-not $exists -and $a.Required) {
50
- Write-Host "[X] $a.File (missing, required)" -ForegroundColor Red
51
- } else {
52
- Write-Host "[ ] $a.File (optional, not present)" -ForegroundColor Gray
51
+ # Check brief (v1.1.0 location + legacy fallback)
52
+ $briefExists = (Test-Path $SDD_BRIEF_FILE) -or (Test-Path "BMAD-brief.md")
53
+ $briefStatus = $config.phases.phase0.status
54
+ if ($briefExists -and $briefStatus -eq "completed") {
55
+ Write-Host "[V] brief.md (in sync)" -ForegroundColor Green
56
+ } elseif ($briefExists -and $briefStatus -ne "completed") {
57
+ Write-Host "[!] brief.md (exists but config shows $briefStatus)" -ForegroundColor Yellow
58
+ } elseif (-not $briefExists) {
59
+ Write-Host "[ ] brief.md (not created yet)" -ForegroundColor Gray
60
+ }
61
+
62
+ # Check SPEC (v1.1.0 location + legacy fallback)
63
+ $specExists = (Test-Path $SDD_SPEC_FILE) -or (Test-Path "SPEC.md")
64
+ $specStatus = $config.phases.phase2.status
65
+ if ($specExists -and $specStatus -eq "completed") {
66
+ Write-Host "[V] SPEC.md (in sync)" -ForegroundColor Green
67
+ } elseif ($specExists -and $specStatus -ne "completed") {
68
+ Write-Host "[!] SPEC.md (exists but config shows $specStatus)" -ForegroundColor Yellow
69
+ } elseif (-not $specExists) {
70
+ Write-Host "[ ] SPEC.md (not created yet)" -ForegroundColor Gray
71
+ }
72
+
73
+ # Check task directory (v1.1.0 location + legacy fallback)
74
+ $taskDir = $null
75
+ $taskDirSource = ""
76
+
77
+ # Check new location first
78
+ if (Test-Path $SDD_TASKS_DIR) {
79
+ $taskDirs = Get-ChildItem -Path $SDD_TASKS_DIR -Filter "task-*-*" -Directory -ErrorAction SilentlyContinue
80
+ if ($taskDirs) {
81
+ $taskDir = Join-Path $SDD_TASKS_DIR ($taskDirs | Select-Object -First 1).Name
82
+ $taskDirSource = "v1.1.0"
83
+ }
84
+ }
85
+
86
+ # Fallback to legacy location
87
+ if (-not $taskDir) {
88
+ $legacyDirs = Get-ChildItem -Filter "task-*-*" -Directory -ErrorAction SilentlyContinue
89
+ if ($legacyDirs) {
90
+ $taskDir = ($legacyDirs | Select-Object -First 1).FullName
91
+ $taskDirSource = "legacy"
53
92
  }
54
93
  }
55
94
 
56
- # Check task directory
57
- $taskDirs = Get-ChildItem -Filter "task-*-*" -Directory -ErrorAction SilentlyContinue
58
- if ($taskDirs) {
59
- $taskDir = ($taskDirs | Select-Object -First 1).Name
95
+ if ($taskDir) {
60
96
  $masterPath = Join-Path $taskDir "MASTER-TASKS.md"
61
97
  $taskFiles = Get-ChildItem -Path $taskDir -Filter "T-*.md" -ErrorAction SilentlyContinue
62
98
  $taskFiles = $taskFiles | Where-Object { $_.Name -ne "MASTER-TASKS.md" }
63
99
  if ($masterPath) {
64
- Write-Host "[V] $taskDir/ (found)" -ForegroundColor Green
100
+ $sourceNote = if ($taskDirSource -eq "legacy") { " (legacy)" } else { "" }
101
+ Write-Host "[V] $taskDir/$sourceNote (found)" -ForegroundColor Green
65
102
  Write-Host " $($taskFiles.Count) task files" -ForegroundColor Gray
66
103
  } else {
67
104
  Write-Host "[X] $taskDir/MASTER-TASKS.md (missing)" -ForegroundColor Red
@@ -71,8 +108,7 @@ if ($Verify) {
71
108
  }
72
109
 
73
110
  # Check task progress
74
- if ($taskDirs) {
75
- $taskDir = ($taskDirs | Select-Object -First 1).Name
111
+ if ($taskDir) {
76
112
  $allTaskFiles = Get-ChildItem -Path $taskDir -Filter "T-*.md" -ErrorAction SilentlyContinue
77
113
  $allTaskFiles = $allTaskFiles | Where-Object { $_.Name -ne "MASTER-TASKS.md" }
78
114
  $total = $allTaskFiles.Count
@@ -90,4 +126,4 @@ if ($Verify) {
90
126
 
91
127
  Write-Host ""
92
128
  Write-Host "Next: Phase $($config.phases.current + 1)"
93
- Write-Host "Run /sdd-status --verify to check artifact sync."
129
+ Write-Host "Run sdd status --verify to check artifact sync."
@@ -7,18 +7,53 @@ $ErrorActionPreference = 'Stop'
7
7
  Write-Host ""
8
8
  Write-Host "=== SDD Tasks Generator - Phase 3 ===" -ForegroundColor Cyan
9
9
 
10
+ # SDD Path Resolution
11
+ $SDD_OUTPUT_BASE = "sdd"
12
+ $SDD_TASKS_DIR = "$SDD_OUTPUT_BASE/tasks"
13
+
14
+ # Check config for custom output directory
15
+ if (Test-Path ".sdd/config.json") {
16
+ try {
17
+ $config = Get-Content ".sdd/config.json" -Raw | ConvertFrom-Json
18
+ if ($config.output) {
19
+ if ($config.output.baseDir) { $SDD_OUTPUT_BASE = $config.output.baseDir }
20
+ if ($config.output.tasksDir) { $SDD_TASKS_DIR = $config.output.tasksDir }
21
+ }
22
+ } catch {}
23
+ }
24
+
10
25
  # Check SPEC
11
- $specPath = "sdd/SPEC.md"
12
- if (-not (Test-Path $specPath)) {
26
+ $specPath = "$SDD_OUTPUT_BASE/SPEC.md"
27
+ $legacySpecPath = "SPEC.md"
28
+
29
+ if (-not (Test-Path $specPath) -and -not (Test-Path $legacySpecPath)) {
13
30
  Write-Host "[ERROR] SPEC.md not found at $specPath" -ForegroundColor Red
14
31
  Write-Host "Run: sdd bmad [feature]" -ForegroundColor Yellow
15
32
  Write-Host "Then: claude `/sdd-spec`" -ForegroundColor Yellow
16
33
  exit 1
17
34
  }
18
- Write-Host "[OK] Found: $specPath" -ForegroundColor Green
35
+
36
+ # Use new path if exists, else use legacy
37
+ if (Test-Path $specPath) {
38
+ Write-Host "[OK] Found: $specPath" -ForegroundColor Green
39
+ $activeSpec = $specPath
40
+ } else {
41
+ Write-Host "[OK] Found: $legacySpecPath (legacy location)" -ForegroundColor Green
42
+ $activeSpec = $legacySpecPath
43
+ }
44
+
45
+ # Read template
46
+ $templatePath = "templates/task-detail.template.md"
47
+ if (-not (Test-Path $templatePath)) {
48
+ Write-Host "[ERROR] Template not found: $templatePath" -ForegroundColor Red
49
+ Write-Host "Run: /sdd-init first" -ForegroundColor Yellow
50
+ exit 1
51
+ }
52
+ $templateContent = Get-Content $templatePath -Raw -Encoding UTF8
53
+ Write-Host "[OK] Template: $templatePath" -ForegroundColor Green
19
54
 
20
55
  # Parse SPEC
21
- $specContent = Get-Content $specPath -Raw -Encoding UTF8
56
+ $specContent = Get-Content $activeSpec -Raw -Encoding UTF8
22
57
 
23
58
  # Extract project name
24
59
  $projectName = "Project"
@@ -53,9 +88,20 @@ Write-Host "[OK] Test categories: $($testCategories -join ', ')" -ForegroundColo
53
88
  # Create task directory
54
89
  $timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
55
90
  $safeName = $projectName -replace '[^a-zA-Z0-9]', '-' -replace '-+', '-'
56
- $taskDir = "sdd/tasks/task-$timestamp-$safeName"
57
- New-Item -ItemType Directory -Path $taskDir -Force | Out-Null
58
- Write-Host "[OK] Created: $taskDir" -ForegroundColor Green
91
+ $taskDir = "$SDD_TASKS_DIR/task-$timestamp-$safeName"
92
+
93
+ # Check for existing task directories for this project
94
+ $existingDirs = Get-ChildItem -Path $SDD_TASKS_DIR -Filter "task-*-${safeName}" -Directory -ErrorAction SilentlyContinue
95
+ if ($existingDirs) {
96
+ $existingDir = $existingDirs[0].FullName
97
+ Write-Host ""
98
+ Write-Host "[WARN] Task directory already exists: $existingDir" -ForegroundColor Yellow
99
+ Write-Host "[INFO] Using existing directory" -ForegroundColor Cyan
100
+ $taskDir = $existingDir
101
+ } else {
102
+ New-Item -ItemType Directory -Path $taskDir -Force | Out-Null
103
+ Write-Host "[OK] Created: $taskDir" -ForegroundColor Green
104
+ }
59
105
 
60
106
  # Build task list
61
107
  $tasks = @()
@@ -89,49 +135,45 @@ $masterContent += "| ID | Name | Estimate | Status |`n|----|------|----------|--
89
135
  foreach ($t in $tasks) {
90
136
  $masterContent += "| $($t.Id) | $($t.Name) | 1h | [ ] |`n"
91
137
  }
92
- $masterContent += "`n## Progress`n`n- Completed: 0 / $($tasks.Count)`n- Pending: $($tasks.Count)`n`n"
138
+ $masterContent += "`n## Progress`n`n- Completed: 0 / $($tasks.Count)`n- In Progress: 0`n- Pending: $($tasks.Count)`n`n"
93
139
  $masterContent += "## Test Categories`n`n$($testCategories -join ', ')`n`n"
94
140
  $masterContent += "## Notes`n`nGenerated from: SPEC.md`nAuto-generated by SDD Pipeline v1.2.2`n"
95
141
 
96
142
  Set-Content -Path "$taskDir/MASTER-TASKS.md" -Value $masterContent -Encoding UTF8
97
143
  Write-Host " [CREATED] MASTER-TASKS.md" -ForegroundColor Gray
98
144
 
99
- # Generate task files
145
+ # Generate task files using template
100
146
  foreach ($t in $tasks) {
101
147
  $safeName = $t.Name -replace '[^a-zA-Z0-9]', '-' -replace '-+', '-'
102
148
  $filename = "$($t.Id)-$safeName.md"
103
- $dependsOn = if ($t.DependsOn) { "@($($t.DependsOn))" } else { "@()" }
104
-
105
- $taskContent = @"
106
- ---
107
- name: $filename
108
- description: "$($t.Name)"
109
- phase: $($t.Phase)
110
- estimate: 1h
111
- spec_sections: ["4.1"]
112
- depends_on: [$dependsOn]
113
- ---
114
-
115
- # $($t.Id): $($t.Name)
116
-
117
- ## Files to Modify/Create
118
- - [List files]
119
-
120
- ## Implementation Steps
121
- 1. [Step 1]
122
- 2. [Step 2]
123
- 3. [Step 3]
124
-
125
- ## Verification
126
- - [ ] Check 1
127
- - [ ] Check 2
128
- - [ ] Check 3
129
- "@
149
+ $dependsOn = if ($t.DependsOn) { "`"$($t.DependsOn)`"" } else { "" }
150
+
151
+ # Apply template substitutions
152
+ $taskContent = $templateContent
153
+ $taskContent = $taskContent -replace '\{\{TASK_ID\}\}', $t.Id
154
+ $taskContent = $taskContent -replace '\{\{TASK_NAME\}\}', $t.Name
155
+ $taskContent = $taskContent -replace '\{\{FILENAME\}\}', $filename
156
+ $taskContent = $taskContent -replace '\{\{DESCRIPTION\}\}', $t.Name
157
+ $taskContent = $taskContent -replace '\{\{PHASE\}\}', $t.Phase
158
+ $taskContent = $taskContent -replace '\{\{ESTIMATE\}\}', "1h"
159
+ $taskContent = $taskContent -replace '\{\{SPEC_SECTIONS\}\}', "4.1"
160
+ $taskContent = $taskContent -replace '\{\{DEPENDS_ON\}\}', $dependsOn
130
161
 
131
162
  Set-Content -Path "$taskDir/$filename" -Value $taskContent -Encoding UTF8
132
163
  Write-Host " [CREATED] $filename" -ForegroundColor Gray
133
164
  }
134
165
 
166
+ # Update config
167
+ if (Test-Path ".sdd/config.json") {
168
+ $config = Get-Content ".sdd/config.json" -Raw | ConvertFrom-Json
169
+ $config.phases.current = 3
170
+ $config.phases.phase2.status = "completed"
171
+ $config.phases.phase2.completedAt = (Get-Date -Format "yyyy-MM-dd")
172
+ $config.phases.phase3.status = "in-progress"
173
+ $config | ConvertTo-Json -Depth 10 | Set-Content ".sdd/config.json"
174
+ Write-Host "[OK] Config updated" -ForegroundColor Green
175
+ }
176
+
135
177
  Write-Host ""
136
178
  Write-Host "[OK] Tasks generated: $($tasks.Count) tasks" -ForegroundColor Green
137
179
  Write-Host ""
@@ -30,7 +30,7 @@ const FILES = [
30
30
  'templates/README.md',
31
31
  'converge/validation.md',
32
32
  'CLAUDE.md',
33
- 'run-converge.ps1',
33
+ 'lib/bundle/run-converge.ps1',
34
34
  ]
35
35
 
36
36
  const DIRS = ['.sdd', 'templates', 'converge', 'commands', 'extensions', 'sdd', 'skills']
@@ -4,6 +4,23 @@ Standard patterns for spawning subagents during SDD task execution.
4
4
 
5
5
  **IMPORTANT:** All subagent names listed here are verified to exist in the Claude Code environment.
6
6
 
7
+ ## IMPORTANT: Claude Code Commands vs CLI Commands
8
+
9
+ **When running SDD pipeline commands in subagents, use Claude Code commands:**
10
+ ```bash
11
+ # CORRECT
12
+ claude "/sdd-bmad simple calculator app..."
13
+ claude "/sdd-spec"
14
+ claude "/sdd-tasks"
15
+ claude "/sdd-cook --task T-001"
16
+
17
+ # WRONG
18
+ sdd bmad "simple calculator app..."
19
+ sdd spec
20
+ sdd tasks
21
+ sdd cook --task T-001
22
+ ```
23
+
7
24
  ## Task Tool Pattern
8
25
 
9
26
  ```
@@ -2,6 +2,28 @@
2
2
 
3
3
  Standard templates for spawning subagents during SDD task execution.
4
4
 
5
+ ## IMPORTANT: Claude Code Commands vs CLI Commands
6
+
7
+ **When running SDD pipeline commands in subagents, use Claude Code commands:**
8
+ ```bash
9
+ # CORRECT - Interactive mode with higher confidence
10
+ claude "/sdd-bmad simple calculator app..."
11
+ claude "/sdd-spec"
12
+ claude "/sdd-tasks"
13
+ claude "/sdd-cook --task T-001"
14
+
15
+ # WRONG - Fast CLI mode with lower confidence
16
+ sdd bmad "simple calculator app..."
17
+ sdd spec
18
+ sdd tasks
19
+ sdd cook --task T-001
20
+ ```
21
+
22
+ **Why:** Claude Code commands run in interactive mode, which:
23
+ - Generates higher confidence briefs (50-100 vs 5-30)
24
+ - Provides better prompts for SPEC generation
25
+ - Enables the full 9-question BMAD interview
26
+
5
27
  ## Task Tool Pattern
6
28
 
7
29
  ```
@@ -1,19 +1,26 @@
1
1
  <!--
2
- Template: T-XXX-task-name.md v1.1.0
2
+ Template: T-XXX-task-name.md v1.2.0
3
3
  Spec-Driven Development — Phase 3 Task
4
4
  Generated by: /sdd-tasks
5
+ Updated: 2026-08-31 (Use template for generation)
5
6
  -->
6
7
  ---
7
- depends_on: []
8
+ name: {{FILENAME}}
9
+ description: "{{DESCRIPTION}}"
10
+ phase: {{PHASE}}
11
+ estimate: {{ESTIMATE}}
12
+ status: pending
13
+ spec_sections: [{{SPEC_SECTIONS}}]
8
14
  parallel_group: ""
9
- spec_sections: []
15
+ depends_on: [{{DEPENDS_ON}}]
10
16
  ---
11
17
 
12
- # T-XXX: [Task Name]
18
+ # {{TASK_ID}}: {{TASK_NAME}}
13
19
 
14
- **Phase:** [Phase from PLAN]
15
- **Estimate:** [X hours]
20
+ **Phase:** {{PHASE}}
21
+ **Estimate:** {{ESTIMATE}}
16
22
  **Status:** Pending
23
+ **Converge Status:** ⏳ PENDING
17
24
 
18
25
  ## Description
19
26
 
@@ -29,12 +36,61 @@ spec_sections: []
29
36
  2. [Step 2]
30
37
  3. [Step 3]
31
38
 
32
- ## Verification
39
+ ## Acceptance Criteria
33
40
 
34
- - [ ] [Specific check 1]
35
- - [ ] [Specific check 2]
41
+ > **Agent:** Verify each criterion against SPEC.md before marking complete.
42
+
43
+ | ID | Criterion | Spec Clause | Verified By | Status |
44
+ |----|-----------|-------------|-------------|--------|
45
+ | AC-001 | [Specific criterion] | [SC-xxx] | [Test/Check] | ⏳ PENDING |
46
+ | AC-002 | [Specific criterion] | [SC-xxx] | [Test/Check] | ⏳ PENDING |
47
+
48
+ ## Spec Clauses
49
+
50
+ > **Track exact spec text for automated validation.**
51
+
52
+ | Clause ID | Spec Text | Location | Verified |
53
+ |-----------|-----------|----------|----------|
54
+ | [SC-xxx] | "[exact text from SPEC.md]" | [SPEC.md §X.X] | ⏳ |
55
+
56
+ ## Converge Report
57
+
58
+ > **Fill after implementation — see converge/task-{{TASK_ID}}/report.md**
59
+
60
+ ```markdown
61
+ ## {{TASK_ID}} Converge Report
62
+
63
+ **Task:** {{TASK_NAME}}
64
+ **Date:** [YYYY-MM-DD]
65
+ **Agent:** [Claude/User]
66
+ **Status:** ✅ PASS | ❌ FAIL
67
+
68
+ ### Spec Adherence
69
+
70
+ | Clause | Spec Says | Implementation Has | Match |
71
+ |--------|-----------|-------------------|-------|
72
+ | [SC-xxx] | "[text]" | "[found text]" | ✅/❌ |
73
+
74
+ ### Acceptance Criteria
75
+
76
+ | Criterion | Status |
77
+ |-----------|--------|
78
+ | AC-001 | ✅/❌ |
79
+ | AC-002 | ✅/❌ |
80
+
81
+ ### Issues Found (if any)
82
+
83
+ - [Issue 1]
84
+ - [Issue 2]
85
+
86
+ ### Next Steps
87
+
88
+ - [If PASS: Proceed to next task]
89
+ - [If FAIL: Fix issues, re-run converge]
90
+ ```
36
91
 
37
92
  ## References
38
93
 
39
94
  - SPEC.md Sections: [§X.X, §Y.Y — from spec_sections above]
40
95
  - MASTER-TASKS: `../MASTER-TASKS.md`
96
+ - Converge: `../../converge/task-{{TASK_ID}}/report.md`
package/lib/init.js CHANGED
@@ -30,7 +30,7 @@ const FILES = [
30
30
  'templates/README.md',
31
31
  'converge/validation.md',
32
32
  'CLAUDE.md',
33
- 'run-converge.ps1',
33
+ 'lib/bundle/run-converge.ps1',
34
34
  ]
35
35
 
36
36
  const DIRS = ['.sdd', 'templates', 'converge', 'commands', 'extensions', 'sdd', 'skills']
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sdd-pipeline",
3
- "version": "1.2.8",
3
+ "version": "1.3.1",
4
4
  "description": "Spec-Driven Development pipeline for Claude Code CLI — transforms raw feature requests into validated, shipped code through a self-correcting converge loop",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -8,7 +8,11 @@
8
8
  },
9
9
  "files": [
10
10
  "bin/",
11
- "lib/",
11
+ "lib/bmad.js",
12
+ "lib/bmad/",
13
+ "lib/config.js",
14
+ "lib/init.js",
15
+ "lib/sanitize.js",
12
16
  "lib/bundle/"
13
17
  ],
14
18
  "engines": {
@@ -25,6 +29,8 @@
25
29
  ],
26
30
  "license": "MIT",
27
31
  "scripts": {
28
- "test": "node test/run.js"
32
+ "test": "node test/run.js",
33
+ "sync": "pwsh scripts/sync-bundle.ps1",
34
+ "pack": "npm pack --dry-run"
29
35
  }
30
36
  }