specpulse 1.4.1__py3-none-any.whl → 1.4.2__py3-none-any.whl

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.
Files changed (31) hide show
  1. specpulse/__init__.py +1 -1
  2. specpulse/cli/main.py +30 -8
  3. specpulse/core/specpulse.py +328 -3
  4. specpulse/core/validator.py +115 -5
  5. specpulse/resources/commands/gemini/sp-pulse.toml +80 -23
  6. specpulse/resources/commands/gemini/sp-spec.toml +90 -45
  7. specpulse/resources/scripts/sp-pulse-decompose.ps1 +74 -0
  8. specpulse/resources/scripts/sp-pulse-execute.ps1 +177 -0
  9. specpulse/resources/scripts/sp-pulse-init.ps1 +36 -11
  10. specpulse/resources/scripts/sp-pulse-init.sh +29 -8
  11. specpulse/resources/scripts/sp-pulse-plan.sh +42 -17
  12. specpulse/resources/scripts/sp-pulse-spec.sh +49 -25
  13. specpulse/resources/scripts/sp-pulse-task.sh +49 -17
  14. specpulse/resources/templates/decomposition/api-contract.yaml +344 -12
  15. specpulse/resources/templates/decomposition/integration-plan.md +249 -97
  16. specpulse/resources/templates/decomposition/interface.ts +244 -13
  17. specpulse/resources/templates/decomposition/microservice.md +151 -0
  18. specpulse/resources/templates/decomposition/service-plan.md +187 -155
  19. specpulse/resources/templates/plan.md +134 -225
  20. specpulse/resources/templates/spec.md +94 -125
  21. specpulse/resources/templates/task.md +216 -161
  22. specpulse/utils/console.py +54 -6
  23. specpulse/utils/git_utils.py +47 -4
  24. specpulse/utils/version_check.py +15 -2
  25. {specpulse-1.4.1.dist-info → specpulse-1.4.2.dist-info}/METADATA +33 -17
  26. {specpulse-1.4.1.dist-info → specpulse-1.4.2.dist-info}/RECORD +30 -28
  27. specpulse/resources/templates/decomposition/microservices.md +0 -35
  28. {specpulse-1.4.1.dist-info → specpulse-1.4.2.dist-info}/WHEEL +0 -0
  29. {specpulse-1.4.1.dist-info → specpulse-1.4.2.dist-info}/entry_points.txt +0 -0
  30. {specpulse-1.4.1.dist-info → specpulse-1.4.2.dist-info}/licenses/LICENSE +0 -0
  31. {specpulse-1.4.1.dist-info → specpulse-1.4.2.dist-info}/top_level.txt +0 -0
@@ -1,52 +1,97 @@
1
- description = "Create or manage feature specifications with versioning"
1
+ description = "Create or manage feature specifications using AI-optimized templates"
2
2
  prompt = """
3
- Handle the /sp-spec command with arguments: {{args}}
4
-
5
- First, detect current feature context:
6
- - Read memory/context.md for current feature metadata
7
- - Use git branch name if available (e.g., 001-user-authentication)
8
- - Fall back to most recently created feature directory
9
- - If no context found, ask user to specify feature or run /sp-pulse first
10
-
11
- Parse the arguments to determine the action:
12
- - If starts with "create": Generate new specification
13
- - If starts with "update": Modify existing specification
14
- - If starts with "validate": Check specification completeness
15
- - If no action specified: Default to "create" with full arguments as description
16
-
17
- ## For /sp-spec create [description] or /sp-spec [description]:
18
- 1. Read template from @{templates/spec.md}
19
- 2. Parse the description to identify:
20
- - Functional requirements (Must/Should/Could have)
21
- - User stories and acceptance criteria
22
- - Technical requirements
23
- 3. Mark any uncertainties with [NEEDS CLARIFICATION: detail]
24
- 4. Find current feature directory from detected context
25
- 5. Check existing spec files and create next version (spec-001.md, spec-002.md, etc.)
26
- 6. Write specification to specs/XXX-feature/spec-XXX.md
27
- 7. Run validation:
28
- - !{bash scripts/sp-pulse-spec.sh "XXX-feature"}
29
-
30
- ## For /sp-spec update:
31
- 1. Show list of existing spec files in current feature directory
32
- 2. Ask user which spec file to update
33
- 3. Read selected specification file
34
- 4. Ask user for clarifications or changes
35
- 5. Update content while preserving structure
36
- 6. Remove resolved [NEEDS CLARIFICATION] markers
37
-
38
- ## For /sp-spec validate:
39
- 1. Show list of existing spec files in current feature directory
40
- 2. Ask user which spec file to validate
41
- 3. Run validation:
42
- - !{bash scripts/sp-pulse-spec.sh "XXX-feature"}
43
- 4. Check all required sections are filled
44
- 5. Count [NEEDS CLARIFICATION] markers
45
- 6. Verify acceptance criteria are testable
46
- 7. Report validation results
3
+ ## CRITICAL FILE EDIT RESTRICTIONS
4
+ **NEVER EDIT:** templates/, scripts/, commands/, .claude/, .gemini/
5
+ **ONLY EDIT:** specs/, plans/, tasks/, memory/
6
+ Templates are COPIED to specs/ folder, then edited there
7
+
8
+ ## Command: /sp-spec {{args}}
9
+
10
+ Create, update, or validate feature specifications using SpecPulse methodology.
11
+
12
+ Actions: create, update, validate, clarify (defaults to create)
13
+
14
+ ### Implementation Steps:
15
+
16
+ 1. **Detect current feature context**:
17
+ - Read memory/context.md for current feature metadata
18
+ - Use git branch name if available (e.g., 001-user-authentication)
19
+ - Fall back to most recently created feature directory
20
+ - If no context found, ask user to specify feature or run /sp-pulse first
21
+
22
+ 2. **Parse arguments** to determine action:
23
+ - If starts with 'create': Generate new specification
24
+ - If starts with 'update': Modify existing specification
25
+ - If starts with 'validate': Check specification completeness
26
+ - If starts with 'clarify': Address [NEEDS CLARIFICATION] markers
27
+ - Default to 'create' with full arguments as description
28
+
29
+ 3. **Run specification script**:
30
+ - !{bash scripts/sp-pulse-spec.sh "{{args}}"}
31
+
32
+ 4. **For 'create' action**:
33
+ - Read template from @{templates/spec.md}
34
+ - Parse description to identify:
35
+ * Functional requirements (Must/Should/Could/Won't have)
36
+ * User stories with testable acceptance criteria
37
+ * Non-functional requirements (performance, security, scalability)
38
+ * Technical constraints and dependencies
39
+ - Fill template with AI-generated content
40
+ - Mark unclear items with [NEEDS CLARIFICATION]
41
+ - Create numbered spec file (spec-001.md, spec-002.md, etc.)
42
+ - Save to specs/XXX-feature/spec-XXX.md
43
+
44
+ 5. **Generate comprehensive specification**:
45
+ - Executive Summary
46
+ - Problem Statement
47
+ - Proposed Solution
48
+ - Functional Requirements (FR-001, FR-002, etc.)
49
+ - Non-Functional Requirements (performance, security, scalability)
50
+ - User Stories with acceptance criteria
51
+ - Technical Constraints
52
+ - Dependencies
53
+ - Risks and Mitigations
54
+ - Success Criteria
55
+ - Open Questions marked with [NEEDS CLARIFICATION]
56
+
57
+ 6. **For 'update' action**:
58
+ - Show list of existing spec files
59
+ - Ask user which spec file to update
60
+ - Read selected specification
61
+ - Ask for clarifications or changes
62
+ - Update content while preserving structure
63
+ - Remove resolved [NEEDS CLARIFICATION] markers
64
+
65
+ 7. **For 'validate' action**:
66
+ - Show list of existing spec files
67
+ - Run validation script
68
+ - Check all required sections are filled
69
+ - Count [NEEDS CLARIFICATION] markers
70
+ - Verify acceptance criteria are testable
71
+ - Report validation results
72
+
73
+ 8. **Update context and validate**:
74
+ - Update memory/context.md with specification status
75
+ - Check SDD compliance (Principle 1: Specification First)
76
+ - Validate all sections are filled
77
+ - Report any missing or incomplete sections
78
+
79
+ ### Example AI-Generated Content:
80
+ For "User authentication with OAuth2":
81
+ - FR-001: System SHALL support OAuth2 authentication with Google/GitHub
82
+ - FR-002: System SHALL issue JWT tokens valid for 24 hours
83
+ - NFR-001: Authentication response time < 200ms
84
+ - User Story: As a user, I want to login with Google so that I don't need to remember another password
85
+
86
+ ### SDD Compliance Checklist:
87
+ - [ ] Every requirement is testable (Principle 1)
88
+ - [ ] User stories have clear acceptance criteria (Principle 1)
89
+ - [ ] Dependencies are identified (Principle 4)
90
+ - [ ] Success metrics defined (Principle 6)
47
91
 
48
92
  Examples:
49
93
  - /sp-spec user authentication with OAuth2 and email/password
50
94
  - /sp-spec update
51
95
  - /sp-spec validate
96
+ - /sp-spec clarify
52
97
  """
@@ -0,0 +1,74 @@
1
+ # SpecPulse Decomposition Orchestrator - PowerShell Version
2
+ # Validates decomposition request and returns status for AI processing
3
+
4
+ param(
5
+ [Parameter(Mandatory=$false, Position=0)]
6
+ [string]$SpecId,
7
+
8
+ [Parameter(Mandatory=$false, Position=1)]
9
+ [string]$Action = "validate"
10
+ )
11
+
12
+ # Configuration
13
+ $ScriptDir = Split-Path -Parent $PSCommandPath
14
+ $ProjectRoot = Split-Path -Parent $ScriptDir
15
+
16
+ # Colors for output
17
+ $Green = "Green"
18
+ $Yellow = "Yellow"
19
+
20
+ Write-Host "[SpecPulse Decompose]" -ForegroundColor $Green -NoNewline
21
+ Write-Host " Processing spec: $($SpecId ?? 'current')"
22
+
23
+ # Find specification
24
+ if ([string]::IsNullOrEmpty($SpecId)) {
25
+ $specDirs = Get-ChildItem -Path "$ProjectRoot\specs" -Directory -ErrorAction SilentlyContinue |
26
+ Sort-Object Name -Descending |
27
+ Select-Object -First 1
28
+ $SpecDir = if ($specDirs) { $specDirs.FullName } else { $null }
29
+ } else {
30
+ $specDirs = Get-ChildItem -Path "$ProjectRoot\specs" -Directory -Filter "${SpecId}*" -ErrorAction SilentlyContinue |
31
+ Select-Object -First 1
32
+ $SpecDir = if ($specDirs) { $specDirs.FullName } else { $null }
33
+ }
34
+
35
+ if (-not $SpecDir -or -not (Test-Path $SpecDir)) {
36
+ Write-Host "ERROR: No specification found" -ForegroundColor Red
37
+ Write-Host "SUGGESTION: Run /sp-spec create first"
38
+ exit 1
39
+ }
40
+
41
+ # Check complexity (simple heuristic)
42
+ $specFiles = Get-ChildItem -Path $SpecDir -Filter "spec-*.md" -ErrorAction SilentlyContinue |
43
+ Sort-Object Name |
44
+ Select-Object -Last 1
45
+
46
+ if ($specFiles) {
47
+ $SpecFile = $specFiles.FullName
48
+ $LineCount = (Get-Content $SpecFile | Measure-Object -Line).Lines
49
+
50
+ Write-Output "SPEC_FILE=$SpecFile"
51
+ Write-Output "COMPLEXITY=$LineCount lines"
52
+
53
+ if ($LineCount -gt 100) {
54
+ Write-Output "RECOMMENDATION=Decomposition advised (complex spec)"
55
+ } else {
56
+ Write-Output "RECOMMENDATION=Single service may suffice"
57
+ }
58
+ }
59
+
60
+ # Check for existing decomposition
61
+ $DecompositionPath = Join-Path $SpecDir "decomposition"
62
+ if (Test-Path $DecompositionPath) {
63
+ Write-Output "STATUS=Decomposition exists"
64
+ Write-Output "PATH=$DecompositionPath"
65
+ } else {
66
+ Write-Output "STATUS=Ready for decomposition"
67
+ Write-Output "PATH=$SpecDir"
68
+ }
69
+
70
+ # Return template paths for AI
71
+ Write-Output "TEMPLATES_DIR=templates/decomposition"
72
+ Write-Output "MEMORY_FILE=memory/context.md"
73
+
74
+ exit 0
@@ -0,0 +1,177 @@
1
+ # Execute tasks continuously from task list - PowerShell Version
2
+
3
+ param(
4
+ [Parameter(Mandatory=$false, Position=0)]
5
+ [string]$Command = "next",
6
+
7
+ [Parameter(Mandatory=$false, Position=1)]
8
+ [string]$FeatureDir
9
+ )
10
+
11
+ # Configuration
12
+ $ScriptName = Split-Path -Leaf $PSCommandPath
13
+ $ScriptDir = Split-Path -Parent $PSCommandPath
14
+ $ProjectRoot = Split-Path -Parent $ScriptDir
15
+
16
+ # Logging function
17
+ function Log-Message {
18
+ param([string]$Message)
19
+ $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
20
+ Write-Host "[$timestamp] ${ScriptName}: $Message" -ForegroundColor Cyan
21
+ }
22
+
23
+ # Error handling function
24
+ function Exit-WithError {
25
+ param([string]$Message)
26
+ Write-Host "ERROR: $Message" -ForegroundColor Red
27
+ exit 1
28
+ }
29
+
30
+ # Find active feature if not provided
31
+ if ([string]::IsNullOrEmpty($FeatureDir)) {
32
+ $ContextFile = Join-Path $ProjectRoot "memory\context.md"
33
+ if (Test-Path $ContextFile) {
34
+ # Extract active feature from context
35
+ $contextContent = Get-Content $ContextFile -Raw
36
+ if ($contextContent -match "Active Feature:\s*(.+)") {
37
+ $FeatureName = $matches[1].Trim()
38
+ }
39
+ if ($contextContent -match "Feature ID:\s*(.+)") {
40
+ $FeatureId = $matches[1].Trim()
41
+ }
42
+
43
+ if ($FeatureId -and $FeatureName) {
44
+ # Convert to branch name format
45
+ $BranchSafeName = $FeatureName.ToLower() -replace '[^a-z0-9-]', '-' -replace '--+', '-' -replace '^-|-$', ''
46
+ $FeatureDir = "$FeatureId-$BranchSafeName"
47
+ Log-Message "Using active feature: $FeatureDir"
48
+ } else {
49
+ Exit-WithError "No active feature found in context file"
50
+ }
51
+ } else {
52
+ Exit-WithError "No feature directory provided and no context file found"
53
+ }
54
+ }
55
+
56
+ $TaskDir = Join-Path $ProjectRoot "tasks\$FeatureDir"
57
+
58
+ # Ensure tasks directory exists
59
+ if (-not (Test-Path $TaskDir)) {
60
+ Exit-WithError "Tasks directory not found: $TaskDir"
61
+ }
62
+
63
+ # Find latest task file
64
+ $taskFiles = Get-ChildItem -Path $TaskDir -Filter "*.md" -ErrorAction SilentlyContinue |
65
+ Sort-Object LastWriteTime -Descending |
66
+ Select-Object -First 1
67
+
68
+ if (-not $taskFiles) {
69
+ Exit-WithError "No task files found in $TaskDir"
70
+ }
71
+
72
+ $TaskFile = $taskFiles.FullName
73
+ Log-Message "Analyzing task file: $TaskFile"
74
+
75
+ # Read task content
76
+ $taskContent = Get-Content $TaskFile -Raw
77
+
78
+ # Detect if decomposed (service-specific tasks)
79
+ $IsDecomposed = $false
80
+ if ($taskContent -match "AUTH-T[0-9]|USER-T[0-9]|INT-T[0-9]") {
81
+ $IsDecomposed = $true
82
+ Log-Message "Detected decomposed architecture with service-specific tasks"
83
+ }
84
+
85
+ # Count task status using regex
86
+ $taskPattern = '^- \[.\] (T[0-9]{3}|[A-Z]+-T[0-9]{3})'
87
+ $allTasks = [regex]::Matches($taskContent, $taskPattern, [System.Text.RegularExpressions.RegexOptions]::Multiline)
88
+ $TotalTasks = $allTasks.Count
89
+
90
+ $CompletedTasks = ([regex]::Matches($taskContent, '^- \[x\] (T[0-9]{3}|[A-Z]+-T[0-9]{3})', [System.Text.RegularExpressions.RegexOptions]::Multiline)).Count
91
+ $PendingTasks = ([regex]::Matches($taskContent, '^- \[ \] (T[0-9]{3}|[A-Z]+-T[0-9]{3})', [System.Text.RegularExpressions.RegexOptions]::Multiline)).Count
92
+ $InProgressTasks = ([regex]::Matches($taskContent, '^- \[>\] (T[0-9]{3}|[A-Z]+-T[0-9]{3})', [System.Text.RegularExpressions.RegexOptions]::Multiline)).Count
93
+ $BlockedTasks = ([regex]::Matches($taskContent, '^- \[!\] (T[0-9]{3}|[A-Z]+-T[0-9]{3})', [System.Text.RegularExpressions.RegexOptions]::Multiline)).Count
94
+
95
+ # Find next task to execute
96
+ $NextTask = ""
97
+ $TaskDetails = ""
98
+
99
+ switch ($Command) {
100
+ { $_ -in "next", "continue" } {
101
+ # Find first in-progress task
102
+ $inProgressMatch = [regex]::Match($taskContent, '^- \[>\] ((T[0-9]{3}|[A-Z]+-T[0-9]{3}): .+)$', [System.Text.RegularExpressions.RegexOptions]::Multiline)
103
+ if ($inProgressMatch.Success) {
104
+ $NextTask = $inProgressMatch.Groups[1].Value
105
+ $TaskDetails = "RESUMING IN-PROGRESS TASK"
106
+ } else {
107
+ # Find first pending task
108
+ $pendingMatch = [regex]::Match($taskContent, '^- \[ \] ((T[0-9]{3}|[A-Z]+-T[0-9]{3}): .+)$', [System.Text.RegularExpressions.RegexOptions]::Multiline)
109
+ if ($pendingMatch.Success) {
110
+ $NextTask = $pendingMatch.Groups[1].Value
111
+ $TaskDetails = "STARTING NEW TASK"
112
+ }
113
+ }
114
+ }
115
+ "all" {
116
+ if ($PendingTasks -gt 0 -or $InProgressTasks -gt 0) {
117
+ $NextTask = "ALL_REMAINING"
118
+ $TaskDetails = "EXECUTE ALL TASKS WITHOUT STOPPING"
119
+ }
120
+ }
121
+ default {
122
+ # Specific task requested
123
+ $specificMatch = [regex]::Match($taskContent, "^- \[.\] (($Command): .+)$", [System.Text.RegularExpressions.RegexOptions]::Multiline)
124
+ if ($specificMatch.Success) {
125
+ $NextTask = $specificMatch.Groups[1].Value
126
+ $TaskDetails = "EXECUTE SPECIFIC TASK"
127
+ }
128
+ }
129
+ }
130
+
131
+ # Calculate progress
132
+ if ($TotalTasks -gt 0) {
133
+ $Progress = [math]::Round(($CompletedTasks / $TotalTasks) * 100)
134
+ } else {
135
+ $Progress = 0
136
+ }
137
+
138
+ # Output status
139
+ Write-Output "TASK_FILE=$TaskFile"
140
+ Write-Output "TOTAL_TASKS=$TotalTasks"
141
+ Write-Output "COMPLETED_TASKS=$CompletedTasks"
142
+ Write-Output "PENDING_TASKS=$PendingTasks"
143
+ Write-Output "IN_PROGRESS_TASKS=$InProgressTasks"
144
+ Write-Output "BLOCKED_TASKS=$BlockedTasks"
145
+ Write-Output "PROGRESS=$Progress%"
146
+
147
+ if ($IsDecomposed) {
148
+ Write-Output "ARCHITECTURE=Microservices"
149
+ } else {
150
+ Write-Output "ARCHITECTURE=Monolithic"
151
+ }
152
+
153
+ if ($NextTask) {
154
+ Write-Output "NEXT_TASK=$NextTask"
155
+ Write-Output "ACTION=$TaskDetails"
156
+ if ($Command -eq "all") {
157
+ Write-Output "MODE=CONTINUOUS"
158
+ Write-Output "INSTRUCTION=Execute all tasks without stopping, no explanations between tasks"
159
+ } else {
160
+ Write-Output "MODE=SINGLE"
161
+ Write-Output "INSTRUCTION=Execute this task and report results"
162
+ }
163
+ } else {
164
+ if ($CompletedTasks -eq $TotalTasks -and $TotalTasks -gt 0) {
165
+ Write-Output "STATUS=ALL_COMPLETE"
166
+ Write-Output "MESSAGE=Congratulations! All tasks have been completed!"
167
+ } elseif ($BlockedTasks -gt 0) {
168
+ Write-Output "STATUS=BLOCKED"
169
+ Write-Output "MESSAGE=All remaining tasks are blocked. Resolve blockers first."
170
+ } else {
171
+ Write-Output "STATUS=NO_TASKS"
172
+ Write-Output "MESSAGE=No tasks available to execute"
173
+ }
174
+ }
175
+
176
+ Log-Message "Task analysis complete"
177
+ exit 0
@@ -61,23 +61,48 @@ try {
61
61
  Exit-WithError "Failed to create directories: $_"
62
62
  }
63
63
 
64
- # Create initial files from templates
64
+ # Validate templates exist but don't copy them directly
65
65
  $TemplateDir = Join-Path $ProjectRoot "templates"
66
66
 
67
- $specTemplate = Join-Path $TemplateDir "spec.md"
68
- $planTemplate = Join-Path $TemplateDir "plan.md"
69
- $taskTemplate = Join-Path $TemplateDir "task.md"
70
-
71
- if (-not (Test-Path $specTemplate)) {
72
- Exit-WithError "Template not found: $specTemplate"
67
+ # Validate all required templates exist
68
+ @("spec.md", "plan.md", "task.md") | ForEach-Object {
69
+ $templatePath = Join-Path $TemplateDir $_
70
+ if (-not (Test-Path $templatePath)) {
71
+ Exit-WithError "Template not found: $templatePath. Please run 'specpulse init' to initialize templates."
72
+ }
73
73
  }
74
74
 
75
+ # Create marker files that indicate AI should use templates to generate content
76
+ # These are placeholder files that will be replaced by AI-generated content
75
77
  try {
76
- Copy-Item -Path $specTemplate -Destination "$SpecsDir\spec-$FeatureId.md" -Force
77
- Copy-Item -Path $planTemplate -Destination "$PlansDir\plan-$FeatureId.md" -Force
78
- Copy-Item -Path $taskTemplate -Destination "$TasksDir\task-$FeatureId.md" -Force
78
+ $specContent = @"
79
+ # Specification for $FeatureName
80
+
81
+ <!-- TO BE GENERATED FROM TEMPLATE: $TemplateDir\spec.md -->
82
+ <!-- FEATURE: $FeatureName -->
83
+ <!-- ID: $FeatureId -->
84
+ "@
85
+ Set-Content -Path "$SpecsDir\spec-001.md" -Value $specContent
86
+
87
+ $planContent = @"
88
+ # Implementation Plan for $FeatureName
89
+
90
+ <!-- TO BE GENERATED FROM TEMPLATE: $TemplateDir\plan.md -->
91
+ <!-- FEATURE: $FeatureName -->
92
+ <!-- ID: $FeatureId -->
93
+ "@
94
+ Set-Content -Path "$PlansDir\plan-001.md" -Value $planContent
95
+
96
+ $taskContent = @"
97
+ # Task Breakdown for $FeatureName
98
+
99
+ <!-- TO BE GENERATED FROM TEMPLATE: $TemplateDir\task.md -->
100
+ <!-- FEATURE: $FeatureName -->
101
+ <!-- ID: $FeatureId -->
102
+ "@
103
+ Set-Content -Path "$TasksDir\task-001.md" -Value $taskContent
79
104
  } catch {
80
- Exit-WithError "Failed to copy templates: $_"
105
+ Exit-WithError "Failed to create marker files: $_"
81
106
  }
82
107
 
83
108
  # Update context
@@ -55,16 +55,37 @@ mkdir -p "$SPECS_DIR" || error_exit "Failed to create specs directory: $SPECS_DI
55
55
  mkdir -p "$PLANS_DIR" || error_exit "Failed to create plans directory: $PLANS_DIR"
56
56
  mkdir -p "$TASKS_DIR" || error_exit "Failed to create tasks directory: $TASKS_DIR"
57
57
 
58
- # Create initial files from templates
58
+ # Validate templates exist but don't copy them directly
59
59
  TEMPLATE_DIR="$PROJECT_ROOT/templates"
60
60
 
61
- if [ ! -f "$TEMPLATE_DIR/spec.md" ]; then
62
- error_exit "Template not found: $TEMPLATE_DIR/spec.md"
63
- fi
64
-
65
- cp "$TEMPLATE_DIR/spec.md" "$SPECS_DIR/spec-${FEATURE_ID}.md" || error_exit "Failed to copy spec template"
66
- cp "$TEMPLATE_DIR/plan.md" "$PLANS_DIR/plan-${FEATURE_ID}.md" || error_exit "Failed to copy plan template"
67
- cp "$TEMPLATE_DIR/task.md" "$TASKS_DIR/task-${FEATURE_ID}.md" || error_exit "Failed to copy task template"
61
+ # Validate all required templates exist
62
+ for template in spec.md plan.md task.md; do
63
+ if [ ! -f "$TEMPLATE_DIR/$template" ]; then
64
+ error_exit "Template not found: $TEMPLATE_DIR/$template. Please run 'specpulse init' to initialize templates."
65
+ fi
66
+ done
67
+
68
+ # Create marker files that indicate AI should use templates to generate content
69
+ # These are placeholder files that will be replaced by AI-generated content
70
+ echo "# Specification for $FEATURE_NAME" > "$SPECS_DIR/spec-001.md"
71
+ echo "# Implementation Plan for $FEATURE_NAME" > "$PLANS_DIR/plan-001.md"
72
+ echo "# Task Breakdown for $FEATURE_NAME" > "$TASKS_DIR/task-001.md"
73
+
74
+ # Add markers indicating these files need AI processing
75
+ echo "" >> "$SPECS_DIR/spec-001.md"
76
+ echo "<!-- TO BE GENERATED FROM TEMPLATE: $TEMPLATE_DIR/spec.md -->" >> "$SPECS_DIR/spec-001.md"
77
+ echo "<!-- FEATURE: $FEATURE_NAME -->" >> "$SPECS_DIR/spec-001.md"
78
+ echo "<!-- ID: $FEATURE_ID -->" >> "$SPECS_DIR/spec-001.md"
79
+
80
+ echo "" >> "$PLANS_DIR/plan-001.md"
81
+ echo "<!-- TO BE GENERATED FROM TEMPLATE: $TEMPLATE_DIR/plan.md -->" >> "$PLANS_DIR/plan-001.md"
82
+ echo "<!-- FEATURE: $FEATURE_NAME -->" >> "$PLANS_DIR/plan-001.md"
83
+ echo "<!-- ID: $FEATURE_ID -->" >> "$PLANS_DIR/plan-001.md"
84
+
85
+ echo "" >> "$TASKS_DIR/task-001.md"
86
+ echo "<!-- TO BE GENERATED FROM TEMPLATE: $TEMPLATE_DIR/task.md -->" >> "$TASKS_DIR/task-001.md"
87
+ echo "<!-- FEATURE: $FEATURE_NAME -->" >> "$TASKS_DIR/task-001.md"
88
+ echo "<!-- ID: $FEATURE_ID -->" >> "$TASKS_DIR/task-001.md"
68
89
 
69
90
  # Update context
70
91
  CONTEXT_FILE="$PROJECT_ROOT/memory/context.md"
@@ -41,8 +41,13 @@ PLAN_DIR="$PROJECT_ROOT/plans/${FEATURE_DIR}"
41
41
  SPEC_DIR="$PROJECT_ROOT/specs/${FEATURE_DIR}"
42
42
  TEMPLATE_FILE="$PROJECT_ROOT/templates/plan.md"
43
43
 
44
+ # Validate template file exists before proceeding
45
+ if [ ! -f "$TEMPLATE_FILE" ]; then
46
+ error_exit "Template not found: $TEMPLATE_FILE. Please ensure templates are properly initialized."
47
+ fi
48
+
44
49
  # Ensure plans directory exists
45
- mkdir -p "$PLAN_DIR"
50
+ mkdir -p "$PLAN_DIR" || error_exit "Failed to create plans directory: $PLAN_DIR"
46
51
 
47
52
  # Find latest spec file
48
53
  if [ -d "$SPEC_DIR" ]; then
@@ -56,8 +61,13 @@ fi
56
61
 
57
62
  # Find next available plan number or create new one
58
63
  if [ -d "$PLAN_DIR" ]; then
59
- existing_plans=$(find "$PLAN_DIR" -name "plan-*.md" | wc -l)
60
- plan_number=$((existing_plans + 1))
64
+ # Get the highest plan number and increment it
65
+ highest_plan=$(find "$PLAN_DIR" -name "plan-*.md" -exec basename {} .md \; | sed 's/plan-//' | sort -n | tail -1)
66
+ if [ -n "$highest_plan" ]; then
67
+ plan_number=$((highest_plan + 1))
68
+ else
69
+ plan_number=1
70
+ fi
61
71
  else
62
72
  plan_number=1
63
73
  fi
@@ -68,25 +78,40 @@ if [ ! -f "$TEMPLATE_FILE" ]; then
68
78
  error_exit "Template not found: $TEMPLATE_FILE"
69
79
  fi
70
80
 
71
- # Create plan
72
- log "Creating implementation plan from template: $PLAN_FILE"
73
- cp "$TEMPLATE_FILE" "$PLAN_FILE" || error_exit "Failed to copy plan template"
81
+ # Create plan marker for AI generation
82
+ log "Creating implementation plan marker: $PLAN_FILE"
83
+ echo "# Implementation Plan - $FEATURE_DIR" > "$PLAN_FILE"
84
+ echo "" >> "$PLAN_FILE"
85
+ echo "<!-- AI: Please generate plan using template: $TEMPLATE_FILE -->" >> "$PLAN_FILE"
86
+ echo "<!-- SPEC_FILE: $SPEC_FILE -->" >> "$PLAN_FILE"
87
+ echo "<!-- FEATURE_DIR: $FEATURE_DIR -->" >> "$PLAN_FILE"
88
+ echo "<!-- FEATURE_ID: $FEATURE_ID -->" >> "$PLAN_FILE"
89
+ echo "" >> "$PLAN_FILE"
90
+ echo "## Awaiting AI Generation" >> "$PLAN_FILE"
91
+ echo "This plan needs to be generated from the template based on specification: $SPEC_FILE" >> "$PLAN_FILE"
74
92
 
75
93
  # Validate plan structure
76
94
  log "Validating implementation plan..."
77
95
 
78
- # Check for required sections
79
- REQUIRED_SECTIONS=("## Implementation Plan:" "## Specification Reference" "## Phase -1: Pre-Implementation Gates" "## Implementation Phases")
80
- MISSING_SECTIONS=()
81
-
82
- for section in "${REQUIRED_SECTIONS[@]}"; do
83
- if ! grep -q "$section" "$PLAN_FILE"; then
84
- MISSING_SECTIONS+=("$section")
96
+ # Check if file needs AI generation
97
+ if grep -q "Awaiting AI Generation" "$PLAN_FILE"; then
98
+ log "WARNING: Plan needs to be generated by AI from template"
99
+ MISSING_SECTIONS=("ALL - Awaiting AI Generation")
100
+ GATE_STATUS="PENDING"
101
+ else
102
+ # Check for required sections only if file has been generated
103
+ REQUIRED_SECTIONS=("## Implementation Plan:" "## Specification Reference" "## Phase -1: Pre-Implementation Gates" "## Implementation Phases")
104
+ MISSING_SECTIONS=()
105
+
106
+ for section in "${REQUIRED_SECTIONS[@]}"; do
107
+ if ! grep -q "$section" "$PLAN_FILE"; then
108
+ MISSING_SECTIONS+=("$section")
109
+ fi
110
+ done
111
+
112
+ if [ ${#MISSING_SECTIONS[@]} -gt 0 ]; then
113
+ log "WARNING: Missing required sections: ${MISSING_SECTIONS[*]}"
85
114
  fi
86
- done
87
-
88
- if [ ${#MISSING_SECTIONS[@]} -gt 0 ]; then
89
- log "WARNING: Missing required sections: ${MISSING_SECTIONS[*]}"
90
115
  fi
91
116
 
92
117
  # Check SDD Gates