sdd-pipeline 1.2.3 → 1.2.4

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/package.json CHANGED
@@ -1,27 +1,30 @@
1
1
  {
2
2
  "name": "sdd-pipeline",
3
- "version": "1.2.3",
4
- "description": "Spec-Driven Development pipeline for Claude Code — organized output structure (sdd/brief.md, sdd/SPEC.md, sdd/tasks/, sdd/converge/)",
3
+ "version": "1.2.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
  "bin": {
6
6
  "sdd": "bin/sdd.js"
7
7
  },
8
8
  "files": [
9
- "bin",
10
- "lib",
11
- "lib/bundle"
9
+ "bin/",
10
+ "lib/bmad.js",
11
+ "lib/config.js",
12
+ "lib/init.js",
13
+ "lib/sanitize.js",
14
+ "lib/bmad/",
15
+ "lib/bundle/"
12
16
  ],
13
17
  "engines": {
14
18
  "node": ">=18"
15
19
  },
16
20
  "preferGlobal": true,
17
- "scripts": {
18
- "build": "echo 'No build step needed — pure JS'"
19
- },
20
21
  "keywords": [
21
22
  "sdd",
22
23
  "spec-driven",
23
24
  "claude-code",
24
- "pipeline"
25
+ "pipeline",
26
+ "specification",
27
+ "development"
25
28
  ],
26
29
  "license": "MIT"
27
30
  }
@@ -1,260 +0,0 @@
1
- param(
2
- [Parameter(Mandatory=$true)]
3
- [string]$TaskId,
4
-
5
- [string]$SpecFile = "",
6
-
7
- [string]$TaskDir = "",
8
-
9
- [string]$ConvergeDir = "",
10
-
11
- [switch]$Strict
12
- )
13
-
14
- $ErrorActionPreference = "Continue"
15
- $script:issuesFound = @()
16
-
17
- # ============================================================
18
- # SDD Path Resolution
19
- # ============================================================
20
- $SDD_OUTPUT_BASE = "sdd"
21
- $SDD_SPEC_FILE = "sdd/SPEC.md"
22
- $SDD_TASKS_DIR = "sdd/tasks"
23
- $SDD_CONVERGE_DIR = "sdd/converge"
24
-
25
- if (Test-Path ".sdd/config.json") {
26
- try {
27
- $config = Get-Content ".sdd/config.json" -Raw | ConvertFrom-Json
28
- if ($config.output) {
29
- if ($config.output.baseDir) { $SDD_OUTPUT_BASE = $config.output.baseDir }
30
- if ($config.output.spec) { $SDD_SPEC_FILE = $config.output.spec }
31
- if ($config.output.tasksDir) { $SDD_TASKS_DIR = $config.output.tasksDir }
32
- if ($config.output.convergeDir) { $SDD_CONVERGE_DIR = $config.output.convergeDir }
33
- }
34
- } catch {}
35
- }
36
-
37
- # Legacy fallback
38
- if (-not $SpecFile) {
39
- if (Test-Path "SPEC.md") { $SpecFile = "SPEC.md" }
40
- elseif (Test-Path $SDD_SPEC_FILE) { $SpecFile = $SDD_SPEC_FILE }
41
- else { $SpecFile = $SDD_SPEC_FILE }
42
- }
43
-
44
- if (-not $ConvergeDir) {
45
- if (Test-Path "converge") { $ConvergeDir = "converge" }
46
- else { $ConvergeDir = $SDD_CONVERGE_DIR }
47
- }
48
-
49
- # Ensure converge directory exists
50
- if (-not (Test-Path $ConvergeDir)) {
51
- New-Item -ItemType Directory -Path $ConvergeDir -Force | Out-Null
52
- }
53
-
54
- # Import shared functions
55
- $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
56
- . "$scriptDir/shared-converge.ps1"
57
-
58
- # Find Task File
59
- function Get-TaskFile {
60
- param([string]$TaskId, [string]$Dir)
61
-
62
- if (-not $Dir) {
63
- # Check new location first
64
- if (Test-Path $SDD_TASKS_DIR) {
65
- $dirs = Get-ChildItem -Path $SDD_TASKS_DIR -Filter "task-*-*" -Directory -ErrorAction SilentlyContinue
66
- if ($dirs) {
67
- $Dir = Join-Path $SDD_TASKS_DIR ($dirs | Select-Object -First 1).Name
68
- }
69
- }
70
- # Fallback to legacy
71
- if (-not $Dir) {
72
- $dirs = Get-ChildItem -Filter "task-*-*" -Directory -ErrorAction SilentlyContinue
73
- if ($dirs) { $Dir = ($dirs | Select-Object -First 1).Name }
74
- }
75
- }
76
- if (-not $Dir) { return $null, $null }
77
-
78
- $pattern = "$TaskId-*.md"
79
- $files = Get-ChildItem -Path $Dir -Filter $pattern -ErrorAction SilentlyContinue
80
- $files = $files | Where-Object { $_.Name -ne "MASTER-TASKS.md" }
81
- return $Dir, ($files | Select-Object -First 1)
82
- }
83
-
84
- # Generate Report
85
- function New-ConvergeReport {
86
- param(
87
- [string]$TaskId,
88
- [string[]]$Clauses,
89
- [object[]]$Issues,
90
- [int]$PassCount,
91
- [int]$FailCount,
92
- [string]$SpecFile,
93
- [string]$OutputDir
94
- )
95
-
96
- $reportDir = Join-Path $OutputDir "task-$TaskId"
97
- if (-not (Test-Path $reportDir)) {
98
- New-Item -ItemType Directory -Path $reportDir -Force | Out-Null
99
- }
100
-
101
- $reportFile = Join-Path $reportDir "report.md"
102
- $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
103
-
104
- $report = @"
105
- # Converge Report: $TaskId
106
-
107
- Generated: $timestamp by SDD Converge
108
-
109
- ## Summary
110
-
111
- | Metric | Value |
112
- |--------|-------|
113
- | Clauses Found | $($Clauses.Count) |
114
- | Clauses Passed | $PassCount |
115
- | Clauses Failed | $FailCount |
116
- | Status | $(if ($FailCount -eq 0) { 'PASS' } else { 'FAIL' }) |
117
-
118
- ## Clause Results
119
-
120
- | Clause ID | Type | Status | Notes |
121
- |-----------|------|--------|-------|
122
- "@
123
-
124
- foreach ($clauseId in $Clauses) {
125
- $clauseType = Get-ClauseType -ClauseId $clauseId
126
- $isFail = $clauseId -in $Issues.Clause
127
- $status = if ($isFail) { "FAIL" } else { "PASS" }
128
- $report += "`n| $clauseId | $clauseType | $status | [Text spec] |"
129
- }
130
-
131
- $report += @"
132
-
133
- ## Issues Found
134
-
135
- | Clause | Issue | Location |
136
- |--------|-------|----------|
137
- "@
138
-
139
- if ($Issues.Count -eq 0) {
140
- $report += "`n| - | No issues found | - |"
141
- } else {
142
- foreach ($issue in $Issues) {
143
- $report += "`n| $($issue.Clause) | $($issue.Issue) | $($issue.Location) |"
144
- }
145
- }
146
-
147
- $report += @"
148
-
149
- ## Next Steps
150
-
151
- $(if ($FailCount -eq 0) {
152
- "- [ ] **PROCEED:** All checks pass -> Move to next task"
153
- } else {
154
- "- [ ] **FIX:** Address issues above -> Re-run converge
155
- - [ ] **IF SPEC ISSUE:** Update SPEC.md clause -> Re-generate task"
156
- })
157
-
158
- ---
159
- Generated by SDD Per-Task Converge v1.1.0
160
- "@
161
-
162
- $report | Out-File -FilePath $reportFile -Encoding UTF8
163
- return $reportFile
164
- }
165
-
166
- # Main Execution
167
- Write-Host ""
168
- Write-Host "========================================" -ForegroundColor Cyan
169
- Write-Host " SDD Per-Task Converge: $TaskId" -ForegroundColor Cyan
170
- Write-Host "========================================" -ForegroundColor Cyan
171
- Write-Host ""
172
- Write-Host "Output: $SDD_OUTPUT_BASE/" -ForegroundColor Gray
173
- Write-Host ""
174
-
175
- # Step 1: Find task file
176
- $taskDir, $taskFile = Get-TaskFile -TaskId $TaskId -Dir $TaskDir
177
- if (-not $taskFile) {
178
- Write-Host "[FAIL] Task file for $TaskId not found" -ForegroundColor Red
179
- exit 1
180
- }
181
- Write-Host "[PASS] Task file: $([System.IO.Path]::GetFileName($taskDir))/$($taskFile.Name)" -ForegroundColor Green
182
-
183
- # Step 2: Find SPEC.md
184
- if (-not (Test-Path $SpecFile)) {
185
- Write-Host "[FAIL] SPEC file not found: $SpecFile" -ForegroundColor Red
186
- exit 1
187
- }
188
- Write-Host "[PASS] SPEC file: $SpecFile" -ForegroundColor Green
189
-
190
- # Step 3: Extract clauses from SPEC.md
191
- $clauses = Get-SpecClauses -File $SpecFile
192
- Write-Host "[INFO] Found $($clauses.Count) clause IDs in SPEC.md" -ForegroundColor Cyan
193
-
194
- # Step 4: Get implementation files
195
- $implFiles = Get-TaskFiles -TaskId $TaskId -TaskDir $taskDir
196
- Write-Host "[INFO] Implementation files: $($implFiles.Count)" -ForegroundColor Cyan
197
- foreach ($f in $implFiles) {
198
- Write-Host " -> $f" -ForegroundColor Gray
199
- }
200
-
201
- # Step 5: Validate each clause
202
- Write-Host ""
203
- Write-Host "--- Clause Validation ---" -ForegroundColor Magenta
204
-
205
- $passCount = 0
206
- $failCount = 0
207
-
208
- foreach ($clause in $clauses) {
209
- $result = Test-ClauseMatch -ClauseId $clause.Id -ClauseText $clause.Text -ClauseType $clause.Type -Files $implFiles
210
-
211
- if ($result.Found) {
212
- $passCount++
213
- Write-Host "[PASS] $($clause.Id)" -ForegroundColor Green
214
- } else {
215
- $failCount++
216
- Write-Host "[FAIL] $($clause.Id)" -ForegroundColor Red
217
- $script:issuesFound += @{
218
- Clause = $clause.Id
219
- Issue = "Not found in implementation"
220
- Location = $result.Location
221
- }
222
- }
223
- }
224
-
225
- # Summary
226
- Write-Host ""
227
- Write-Host "========================================" -ForegroundColor Cyan
228
- Write-Host " Summary" -ForegroundColor Cyan
229
- Write-Host "========================================" -ForegroundColor Cyan
230
- Write-Host ""
231
- Write-Host " Clauses Passed: $passCount" -ForegroundColor Green
232
- Write-Host " Clauses Failed: $failCount" -ForegroundColor $(if ($failCount -gt 0) { "Red" } else { "Green" })
233
-
234
- if ($failCount -gt 0) {
235
- Write-Host ""
236
- Write-Host " Issues Found:" -ForegroundColor Yellow
237
- foreach ($issue in $script:issuesFound) {
238
- Write-Host " - $($issue.Clause): $($issue.Issue)" -ForegroundColor Yellow
239
- Write-Host " Location: $($issue.Location)" -ForegroundColor DarkGray
240
- }
241
- }
242
-
243
- # Step 6: Generate report
244
- $reportFile = New-ConvergeReport -TaskId $TaskId -Clauses $clauses.Id -Issues $script:issuesFound -PassCount $passCount -FailCount $failCount -SpecFile $SpecFile -OutputDir $ConvergeDir
245
- Write-Host ""
246
- Write-Host "[PASS] Report saved: $reportFile" -ForegroundColor Green
247
-
248
- # Exit code
249
- if ($failCount -gt 0) {
250
- if ($Strict) {
251
- Write-Host "[FAIL] Converge FAILED (strict mode)" -ForegroundColor Red
252
- exit 1
253
- } else {
254
- Write-Host "[WARN] Converge completed with issues (non-strict)" -ForegroundColor Yellow
255
- exit 0
256
- }
257
- } else {
258
- Write-Host "[PASS] Converge PASSED" -ForegroundColor Green
259
- exit 0
260
- }