sdd-pipeline 1.2.4 → 1.2.6

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/bin/sdd.cjs ADDED
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env node
2
+ // sdd — Spec-Driven Development CLI
3
+ // Unified entry point for both npm package and local development
4
+
5
+ const path = require('path')
6
+ const fs = require('fs')
7
+
8
+ // Determine if we're in npm package or local development
9
+ const isNpmPackage = fs.existsSync(path.join(__dirname, 'lib/bmad.js'))
10
+ const libDir = isNpmPackage ? path.join(__dirname, 'lib') : path.join(__dirname, '..', 'lib')
11
+
12
+ // Dynamic requires
13
+ const init = require(path.join(libDir, 'init'))
14
+ const bmad = require(path.join(libDir, 'bmad/index'))
15
+ const config = require(path.join(libDir, 'config'))
16
+
17
+ const args = process.argv.slice(2)
18
+ const cmd = args[0]
19
+
20
+ // PowerShell detection - use correct command for platform
21
+ function getPowerShellCommand() {
22
+ if (process.platform === 'win32') {
23
+ // Windows: try powershell.exe first (always available), then pwsh
24
+ const system32 = 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'
25
+ if (fs.existsSync(system32)) {
26
+ return 'powershell'
27
+ }
28
+ return 'powershell' // Fallback to whatever is in PATH
29
+ }
30
+ return 'pwsh' // macOS/Linux: PowerShell Core
31
+ }
32
+
33
+ function runPowerShellScript(scriptPath, scriptArgs, callback) {
34
+ const psCmd = getPowerShellCommand()
35
+ const psArgs = ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', scriptPath, ...scriptArgs]
36
+
37
+ const { spawn } = require('child_process')
38
+ const ps = spawn(psCmd, psArgs, {
39
+ stdio: 'inherit',
40
+ shell: false,
41
+ windowsHide: true
42
+ })
43
+
44
+ ps.on('error', (err) => {
45
+ callback(err, null)
46
+ })
47
+
48
+ ps.on('close', (code) => {
49
+ callback(null, code)
50
+ })
51
+ }
52
+
53
+ switch (cmd) {
54
+ case 'init':
55
+ init.run()
56
+ break
57
+
58
+ case 'bmad': {
59
+ const input = args.slice(1).join(' ')
60
+ if (!input) {
61
+ console.error('Usage: sdd bmad <feature description>')
62
+ console.error('Example: sdd bmad "landing page for my SaaS product"')
63
+ console.error('')
64
+ console.error('For interactive mode (9-question interview), use Claude Code:')
65
+ console.error(' claude "/sdd-bmad landing page for my SaaS"')
66
+ process.exit(1)
67
+ }
68
+
69
+ // Try to run PowerShell script if available
70
+ const commandsDir = isNpmPackage
71
+ ? path.join(libDir, 'bundle', '.claude', 'commands')
72
+ : path.join(__dirname, '..', '.claude', 'commands')
73
+ const bmadScript = path.join(commandsDir, 'sdd-bmad.md')
74
+
75
+ // Note: Claude Code commands are .md files designed for Claude Code CLI
76
+ // PowerShell cannot run .md files directly
77
+ // So we always use the Node.js module for fast mode
78
+
79
+ // Generate brief using Node.js module
80
+ const session = bmad.init(input)
81
+ const result = bmad.generateBrief()
82
+
83
+ console.log('[OK] sdd/brief.md created.')
84
+ console.log(`Confidence: ${result.confidence.score}/100 — ${result.confidence.level}`)
85
+ console.log('')
86
+ console.log('Output: sdd/brief.md')
87
+ console.log('')
88
+ if (result.confidence.score < 70) {
89
+ console.log('Tip: For higher confidence, use Claude Code with interactive mode:')
90
+ console.log(' claude "/sdd-bmad ' + input.substring(0, 30) + '..."')
91
+ }
92
+ console.log('')
93
+ console.log('Next: claude "/sdd-spec" to generate SPEC.md')
94
+ console.log(' (or use Claude Code for full interactive experience)')
95
+ break
96
+ }
97
+
98
+ case 'spec':
99
+ console.log('=== SDD SPEC Generation ===')
100
+ console.log('')
101
+ console.log('This command requires Claude Code for best results.')
102
+ console.log('')
103
+ console.log('Run: claude "/sdd-spec"')
104
+ console.log('')
105
+ console.log('Claude Code will:')
106
+ console.log(' 1. Read sdd/brief.md')
107
+ console.log(' 2. Validate confidence score (requires >= 20)')
108
+ console.log(' 3. Generate sdd/SPEC.md from template')
109
+ break
110
+
111
+ case 'tasks':
112
+ console.log('=== SDD Task Generation ===')
113
+ console.log('')
114
+ console.log('This command requires Claude Code.')
115
+ console.log('')
116
+ console.log('Run: claude "/sdd-tasks"')
117
+ console.log('')
118
+ console.log('Claude Code will:')
119
+ console.log(' 1. Read sdd/SPEC.md')
120
+ console.log(' 2. Extract features from Section 4.1')
121
+ console.log(' 3. Generate sdd/tasks/task-*/ directory')
122
+ console.log(' 4. Create MASTER-TASKS.md and T-XXX-*.md files')
123
+ break
124
+
125
+ case 'cook':
126
+ console.log('=== SDD Implementation ===')
127
+ console.log('')
128
+ console.log('This command requires Claude Code.')
129
+ console.log('')
130
+ console.log('Run: claude "/sdd-cook"')
131
+ console.log('')
132
+ console.log('Claude Code will:')
133
+ console.log(' 1. Read sdd/tasks/task-*/MASTER-TASKS.md')
134
+ console.log(' 2. Execute tasks sequentially')
135
+ console.log(' 3. Scout, implement, test, review each task')
136
+ console.log('')
137
+ console.log('Flags:')
138
+ console.log(' --all Execute all pending tasks')
139
+ console.log(' --task T-001 Execute specific task')
140
+ break
141
+
142
+ case 'converge':
143
+ console.log('=== SDD Converge Validation ===')
144
+ console.log('')
145
+ console.log('Full validation (requires dev server):')
146
+ console.log(' pwsh run-converge.ps1 -Url http://localhost:3000 -Strict')
147
+ console.log('')
148
+ console.log('Per-task validation:')
149
+ console.log(' pwsh run-converge.ps1 -TaskId T-001')
150
+ console.log('')
151
+ console.log('Claude Code:')
152
+ console.log(' claude "/sdd-converge"')
153
+ break
154
+
155
+ case 'status': {
156
+ config.printStatus()
157
+ break
158
+ }
159
+
160
+ case 'help':
161
+ default:
162
+ if (cmd && cmd !== 'help') {
163
+ console.error(`Unknown command: ${cmd}\n`)
164
+ }
165
+ console.log(`
166
+ sdd — Spec-Driven Development CLI
167
+
168
+ Output Structure (v1.1.0+):
169
+ sdd/ All generated artifacts
170
+ brief.md Phase 0: BMAD brief
171
+ SPEC.md Phase 2: Specification
172
+ tasks/ Phase 3: Task directories
173
+ converge/ Phase 5: Validation reports
174
+
175
+ Usage:
176
+ sdd init Initialize SDD pipeline
177
+ sdd bmad <desc> Phase 0: Generate brief (fast mode)
178
+ sdd status Show pipeline status
179
+ sdd help Show this help
180
+
181
+ Full Pipeline (requires Claude Code):
182
+ claude "/sdd-bmad" Interactive 9-question interview (high confidence)
183
+ claude "/sdd-spec" Generate SPEC.md
184
+ claude "/sdd-tasks" Generate task directory
185
+ claude "/sdd-cook" Execute implementation
186
+ claude "/sdd-converge" Validate implementation
187
+
188
+ Quick Start:
189
+ 1. sdd init
190
+ 2. sdd bmad "my feature idea"
191
+ 3. claude "/sdd-spec"
192
+ 4. claude "/sdd-tasks"
193
+ 5. claude "/sdd-cook"
194
+ 6. claude "/sdd-converge"
195
+
196
+ Notes:
197
+ - Claude Code CLI provides the best experience with interactive commands
198
+ - Install Claude Code: npm install -g @anthropic-ai/claude-code
199
+ - Without Claude Code, use "sdd bmad" for fast mode (lower confidence)
200
+ `)
201
+ }
package/lib/bmad/index.js CHANGED
@@ -7,7 +7,7 @@
7
7
  * - 9-question interview framework
8
8
  * - 3-agent synthesis (single-pass LLM mode)
9
9
  * - Confidence scoring
10
- * - BMAD-brief.md output
10
+ * - Brief output to sdd/ directory
11
11
  */
12
12
 
13
13
  const fs = require('fs')
@@ -18,7 +18,9 @@ const problemFirst = require('./problem-first')
18
18
  const synthesis = require('./synthesis')
19
19
  const confidenceCalc = require('./confidence')
20
20
 
21
- const OUTPUT_FILE = 'BMAD-brief.md'
21
+ // Output directory - can be overridden via environment
22
+ const OUTPUT_BASE = process.env.SDD_OUTPUT_BASE || 'sdd'
23
+ const OUTPUT_FILE = path.join(OUTPUT_BASE, 'brief.md')
22
24
  const TEMPLATE_DATE = new Date().toISOString().split('T')[0]
23
25
  const TEMPLATE_EXPIRY = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
24
26
  .toISOString()
@@ -33,6 +35,15 @@ let state = {
33
35
  currentTier: 0,
34
36
  }
35
37
 
38
+ /**
39
+ * Ensure output directory exists
40
+ */
41
+ function ensureOutputDir() {
42
+ if (!fs.existsSync(OUTPUT_BASE)) {
43
+ fs.mkdirSync(OUTPUT_BASE, { recursive: true })
44
+ }
45
+ }
46
+
36
47
  /**
37
48
  * Initialize a new BMAD interview session.
38
49
  * @param {string} rawInput - Raw user feature description
@@ -85,7 +96,7 @@ function canProceed() {
85
96
  }
86
97
 
87
98
  /**
88
- * Generate the BMAD-brief.md file.
99
+ * Generate the sdd/brief.md file.
89
100
  * @returns {{ filePath: string, confidence: object }}
90
101
  */
91
102
  function generateBrief() {
@@ -102,11 +113,16 @@ function generateBrief() {
102
113
 
103
114
  const fullContent = header + brief
104
115
 
116
+ // Ensure output directory exists
117
+ ensureOutputDir()
118
+
119
+ // Write to sdd/brief.md
105
120
  fs.writeFileSync(OUTPUT_FILE, fullContent, 'utf8')
106
121
 
107
122
  return {
108
123
  filePath: path.resolve(OUTPUT_FILE),
109
124
  confidence,
125
+ outputDir: OUTPUT_BASE,
110
126
  }
111
127
  }
112
128
 
@@ -137,4 +153,5 @@ module.exports = {
137
153
  getState,
138
154
  getQuestionsWithStatus,
139
155
  OUTPUT_FILE,
156
+ OUTPUT_BASE,
140
157
  }
@@ -0,0 +1,153 @@
1
+ # SDD Inline Check — Real-time Spec Validation
2
+ ---
3
+ tool: Bash
4
+ when: always
5
+ args: <file-path> --section <spec-section>
6
+ description: Real-time inline validation. Check file(s) against SPEC.md clauses ([SC-xxx], [AC-xxx]). Catches missing text/colors/dimensions during implementation, not at end. Args: <file-path> [--section <spec-section>]
7
+ ---
8
+
9
+ ## SDD Check — Real-Time Inline Validation
10
+
11
+ **Purpose:** Validate current file against SPEC.md during implementation. Get instant feedback.
12
+
13
+ ### Usage
14
+
15
+ ```bash
16
+ # Check specific file against SPEC.md
17
+ sdd check src/components/Button.tsx
18
+
19
+ # Check with specific spec section
20
+ sdd check src/components/Button.tsx --section 4.1.1
21
+
22
+ # Check multiple files
23
+ sdd check src/components/ src/utils/
24
+ ```
25
+
26
+ ---
27
+
28
+ ## What It Does
29
+
30
+ ### 1. Extract Spec Clauses
31
+ Reads SPEC.md and extracts all `[SC-xxx]` clause IDs with their text.
32
+
33
+ ### 2. Search Implementation
34
+ Searches the target file(s) for:
35
+ - ✅ Exact text matches
36
+ - ✅ Color hex values
37
+ - ✅ Dimension values
38
+ - ✅ Component patterns
39
+
40
+ ### 3. Inline Report
41
+
42
+ ```
43
+ ╔══════════════════════════════════════════════════════════╗
44
+ ║ SDD Check: src/components/Button.tsx ║
45
+ ╠══════════════════════════════════════════════════════════╣
46
+ ║ ✅ SC-001: "Start Free Trial" found at line 42 ║
47
+ ║ ✅ SC-COLOR-001: #22c55e found ║
48
+ ║ ❌ SC-002: "Get Started" NOT FOUND ║
49
+ ║ → Expected at: line 45 ║
50
+ ║ ✅ AC-001: Loading state implemented ║
51
+ ╚══════════════════════════════════════════════════════════╝
52
+
53
+ Result: 2/3 clauses verified | 1 ISSUE
54
+ ```
55
+
56
+ ---
57
+
58
+ ## Implementation
59
+
60
+ ```powershell
61
+ # sdd-check.ps1
62
+ param(
63
+ [Parameter(Mandatory=$true)]
64
+ [string]$FilePath,
65
+
66
+ [string]$Section = "",
67
+
68
+ [string]$SpecFile = "SPEC.md"
69
+ )
70
+
71
+ $ErrorActionPreference = "Continue"
72
+
73
+ # Extract clauses from SPEC.md
74
+ $specContent = Get-Content $SpecFile -Raw
75
+ $clausePattern = '\[(SC-[A-Z0-9]+-[0-9]+|SC-[0-9]+)\]'
76
+ $clauses = [regex]::Matches($specContent, $clausePattern) | ForEach-Object {
77
+ @{
78
+ Id = $_.Groups[1].Value
79
+ Text = (Get-ClauseContext -SpecFile $SpecFile -ClauseId $_.Groups[1].Value)
80
+ }
81
+ }
82
+
83
+ # Read implementation file
84
+ $implContent = Get-Content $FilePath -Raw
85
+
86
+ # Check each clause
87
+ $passCount = 0
88
+ $failCount = 0
89
+
90
+ foreach ($clause in $clauses) {
91
+ $searchText = $clause.Text -replace '\[.*?\]', '' -replace '\(.*?\)', ''
92
+
93
+ if ($implContent -match [regex]::Escape($searchText)) {
94
+ Write-Host "✅ $($clause.Id): FOUND" -ForegroundColor Green
95
+ $passCount++
96
+ } else {
97
+ Write-Host "❌ $($clause.Id): NOT FOUND" -ForegroundColor Red
98
+ Write-Host " Expected: $searchText" -ForegroundColor Yellow
99
+ $failCount++
100
+ }
101
+ }
102
+
103
+ Write-Host ""
104
+ Write-Host "Result: $passCount/$($clauses.Count) clauses verified" -ForegroundColor $(if ($failCount -eq 0) { "Green" } else { "Yellow" })
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Example Workflow
110
+
111
+ ### Before Implementation
112
+ ```bash
113
+ sdd check src/components/Button.tsx --section 4.1.1
114
+ ```
115
+ → Shows what clauses should be in the file
116
+
117
+ ### During Implementation
118
+ ```bash
119
+ sdd check src/components/Button.tsx
120
+ ```
121
+ → Real-time feedback on what's missing
122
+
123
+ ### After Implementation
124
+ ```bash
125
+ sdd converge --task T-001
126
+ ```
127
+ → Full converge report
128
+
129
+ ---
130
+
131
+ ## For Claude Code Agents
132
+
133
+ Add to your implementation loop:
134
+
135
+ ```
136
+ 1. Read SPEC.md → identify relevant clauses
137
+ 2. Implement feature
138
+ 3. Run: sdd check [file]
139
+ 4. Fix any ❌ issues
140
+ 5. Run: sdd converge --task T-XXX
141
+ 6. Proceed to next task
142
+ ```
143
+
144
+ ---
145
+
146
+ ## Benefits
147
+
148
+ | Benefit | Description |
149
+ |---------|-------------|
150
+ | Early Detection | Catch missing clauses before converge |
151
+ | Faster Iterations | Don't wait until end to find issues |
152
+ | Clear Direction | Know exactly what's missing |
153
+ | Less Rework | Fix as you go, not all at once |