specpulse 1.4.2__tar.gz → 1.4.4__tar.gz
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.
- {specpulse-1.4.2/specpulse.egg-info → specpulse-1.4.4}/PKG-INFO +13 -2
- {specpulse-1.4.2 → specpulse-1.4.4}/README.md +12 -1
- {specpulse-1.4.2 → specpulse-1.4.4}/pyproject.toml +2 -1
- {specpulse-1.4.2 → specpulse-1.4.4}/setup.py +2 -1
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/__init__.py +1 -1
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/claude/sp-plan.md +6 -2
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/claude/sp-spec.md +8 -4
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/scripts/sp-pulse-execute.ps1 +58 -23
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/scripts/sp-pulse-execute.sh +9 -9
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/scripts/sp-pulse-init.ps1 +12 -9
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/scripts/sp-pulse-init.sh +12 -9
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/scripts/sp-pulse-plan.ps1 +48 -23
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/scripts/sp-pulse-plan.sh +8 -11
- specpulse-1.4.4/specpulse/resources/scripts/sp-pulse-spec.ps1 +153 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/scripts/sp-pulse-spec.sh +22 -24
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/scripts/sp-pulse-task.ps1 +61 -31
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/scripts/sp-pulse-task.sh +8 -13
- {specpulse-1.4.2 → specpulse-1.4.4/specpulse.egg-info}/PKG-INFO +13 -2
- specpulse-1.4.2/specpulse/resources/scripts/sp-pulse-spec.ps1 +0 -126
- {specpulse-1.4.2 → specpulse-1.4.4}/LICENSE +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/MANIFEST.in +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/requirements.txt +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/setup.cfg +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/cli/__init__.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/cli/main.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/core/__init__.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/core/specpulse.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/core/validator.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/claude/sp-continue.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/claude/sp-decompose.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/claude/sp-execute.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/claude/sp-pulse.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/claude/sp-status.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/claude/sp-task.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/gemini/sp-continue.toml +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/gemini/sp-decompose.toml +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/gemini/sp-execute.toml +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/gemini/sp-plan.toml +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/gemini/sp-pulse.toml +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/gemini/sp-spec.toml +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/gemini/sp-status.toml +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/commands/gemini/sp-task.toml +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/memory/constitution.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/memory/context.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/memory/decisions.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/scripts/sp-pulse-decompose.ps1 +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/scripts/sp-pulse-decompose.sh +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/templates/decomposition/api-contract.yaml +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/templates/decomposition/integration-plan.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/templates/decomposition/interface.ts +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/templates/decomposition/microservice.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/templates/decomposition/service-plan.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/templates/plan.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/templates/spec.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/resources/templates/task.md +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/utils/__init__.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/utils/console.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/utils/git_utils.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse/utils/version_check.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse.egg-info/SOURCES.txt +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse.egg-info/dependency_links.txt +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse.egg-info/entry_points.txt +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse.egg-info/not-zip-safe +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse.egg-info/requires.txt +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/specpulse.egg-info/top_level.txt +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_all.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_cli.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_cli_fixed.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_complete_100.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_complete_coverage.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_console.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_coverage_100.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_final_100.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_full_coverage.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_git_utils.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_integration.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_specpulse.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_validator.py +0 -0
- {specpulse-1.4.2 → specpulse-1.4.4}/tests/test_version_utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: specpulse
|
3
|
-
Version: 1.4.
|
3
|
+
Version: 1.4.4
|
4
4
|
Summary: Specification-Driven Development Framework
|
5
5
|
Home-page: https://github.com/specpulse
|
6
6
|
Author: SpecPulse
|
@@ -67,7 +67,18 @@ Dynamic: requires-python
|
|
67
67
|
|
68
68
|
SpecPulse is a universal **Specification-Driven Development (SDD)** framework that works with ANY software project - web apps, mobile apps, desktop software, games, APIs, ML projects, and more. It ensures every feature starts with clear specifications, validated plans, and tracked tasks.
|
69
69
|
|
70
|
-
> **Latest Update (v1.4.
|
70
|
+
> **Latest Update (v1.4.4)** - Critical Workflow Fixes:
|
71
|
+
> - 🐛 **Fixed Script Numbering**: Resolved `/sp-pulse` creating empty placeholders while subsequent commands created new files
|
72
|
+
> - 🎯 **Fixed Task Detection**: Execute scripts now properly detect task format (`### T001:` with `**Status**:`)
|
73
|
+
> - 📝 **Unified Placeholders**: All scripts use consistent `<!-- INSTRUCTION: Generate -->` markers
|
74
|
+
> - 🔧 **PowerShell Parity**: PowerShell scripts now match Bash behavior exactly
|
75
|
+
>
|
76
|
+
> **v1.4.3** - Script Numbering Fix:
|
77
|
+
> - 🔢 **Fixed Numbering Logic**: Spec, plan, and task files now number correctly (001, 002, 003...)
|
78
|
+
> - 📝 **No Empty First Files**: spec-001.md, plan-001.md, task-001.md always contain content
|
79
|
+
> - 🎯 **Proper Interactive Mode**: Scripts create placeholder files for AI to fill
|
80
|
+
>
|
81
|
+
> **v1.4.2** - Template System Enhancement:
|
71
82
|
> - 📁 **Physical Template Files**: Templates now exist as physical files for AI tools to read
|
72
83
|
> - 🔧 **Complete PowerShell Support**: Added PowerShell scripts matching all Bash functionality
|
73
84
|
> - 📝 **Enhanced Decomposition Templates**: Full microservice decomposition template support
|
@@ -21,7 +21,18 @@
|
|
21
21
|
|
22
22
|
SpecPulse is a universal **Specification-Driven Development (SDD)** framework that works with ANY software project - web apps, mobile apps, desktop software, games, APIs, ML projects, and more. It ensures every feature starts with clear specifications, validated plans, and tracked tasks.
|
23
23
|
|
24
|
-
> **Latest Update (v1.4.
|
24
|
+
> **Latest Update (v1.4.4)** - Critical Workflow Fixes:
|
25
|
+
> - 🐛 **Fixed Script Numbering**: Resolved `/sp-pulse` creating empty placeholders while subsequent commands created new files
|
26
|
+
> - 🎯 **Fixed Task Detection**: Execute scripts now properly detect task format (`### T001:` with `**Status**:`)
|
27
|
+
> - 📝 **Unified Placeholders**: All scripts use consistent `<!-- INSTRUCTION: Generate -->` markers
|
28
|
+
> - 🔧 **PowerShell Parity**: PowerShell scripts now match Bash behavior exactly
|
29
|
+
>
|
30
|
+
> **v1.4.3** - Script Numbering Fix:
|
31
|
+
> - 🔢 **Fixed Numbering Logic**: Spec, plan, and task files now number correctly (001, 002, 003...)
|
32
|
+
> - 📝 **No Empty First Files**: spec-001.md, plan-001.md, task-001.md always contain content
|
33
|
+
> - 🎯 **Proper Interactive Mode**: Scripts create placeholder files for AI to fill
|
34
|
+
>
|
35
|
+
> **v1.4.2** - Template System Enhancement:
|
25
36
|
> - 📁 **Physical Template Files**: Templates now exist as physical files for AI tools to read
|
26
37
|
> - 🔧 **Complete PowerShell Support**: Added PowerShell scripts matching all Bash functionality
|
27
38
|
> - 📝 **Enhanced Decomposition Templates**: Full microservice decomposition template support
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "specpulse"
|
7
|
-
version = "1.4.
|
7
|
+
version = "1.4.4"
|
8
8
|
description = "Specification-Driven Development Framework"
|
9
9
|
readme = "README.md"
|
10
10
|
requires-python = ">=3.11"
|
@@ -93,6 +93,7 @@ specpulse = [
|
|
93
93
|
"resources/templates/decomposition/*.ts",
|
94
94
|
"resources/memory/*.md",
|
95
95
|
"resources/scripts/*.sh",
|
96
|
+
"resources/scripts/*.ps1",
|
96
97
|
"resources/commands/claude/*.md",
|
97
98
|
"resources/commands/gemini/*.toml",
|
98
99
|
]
|
@@ -11,7 +11,7 @@ long_description = (this_directory / "README.md").read_text(encoding="utf-8")
|
|
11
11
|
|
12
12
|
setup(
|
13
13
|
name="specpulse",
|
14
|
-
version="1.4.
|
14
|
+
version="1.4.4",
|
15
15
|
author="SpecPulse",
|
16
16
|
author_email="",
|
17
17
|
description="Next-Generation Specification-Driven Development Framework",
|
@@ -64,6 +64,7 @@ setup(
|
|
64
64
|
"resources/templates/decomposition/*.ts",
|
65
65
|
"resources/memory/*.md",
|
66
66
|
"resources/scripts/*.sh",
|
67
|
+
"resources/scripts/*.ps1",
|
67
68
|
"resources/commands/claude/*.md",
|
68
69
|
"resources/commands/gemini/*.toml",
|
69
70
|
],
|
@@ -96,8 +96,12 @@ When called with `/sp-plan $ARGUMENTS`, I will:
|
|
96
96
|
- Create improvement strategies for technical debt
|
97
97
|
- Track future enhancement opportunities
|
98
98
|
|
99
|
-
i. **
|
100
|
-
|
99
|
+
i. **CRITICAL NUMBERING LOGIC**:
|
100
|
+
- Check if `plans/XXX-feature/plan-001.md` exists
|
101
|
+
- If plan-001.md does NOT exist: Create plan-001.md with full content from template
|
102
|
+
- If plan-001.md EXISTS: Create plan-002.md (or next number) with new content
|
103
|
+
- NEVER leave plan-001.md as placeholder if it's the first plan
|
104
|
+
j. **Write FULL plan content** to `plans/XXX-feature/plan-XXX.md`
|
101
105
|
k. **IMPORTANT**: Can EDIT files in plans/ folder, but NEVER modify templates/, scripts/, or commands/ folders
|
102
106
|
|
103
107
|
4. **For `/sp-plan validate`:**
|
@@ -43,7 +43,12 @@ When called with `/sp-spec $ARGUMENTS`, I will:
|
|
43
43
|
- If no action specified: Default to `create` with full arguments as description
|
44
44
|
|
45
45
|
3. **For `/sp-spec create [description]` or `/sp-spec [description]`:**
|
46
|
-
-
|
46
|
+
- **CRITICAL NUMBERING LOGIC**:
|
47
|
+
- Check if `specs/XXX-feature/spec-001.md` exists
|
48
|
+
- If spec-001.md does NOT exist: Create spec-001.md with full content from template
|
49
|
+
- If spec-001.md EXISTS: Create spec-002.md (or next number) with new content
|
50
|
+
- NEVER leave spec-001.md as placeholder if it's the first spec
|
51
|
+
- READ template from `templates/spec.md` and use it to generate content
|
47
52
|
- IMPORTANT: Only edit files in specs/, plans/, tasks/ folders. NEVER edit templates/, scripts/, or commands/
|
48
53
|
- Parse the description to identify:
|
49
54
|
- Functional requirements (Must/Should/Could/Won't have)
|
@@ -60,11 +65,10 @@ When called with `/sp-spec $ARGUMENTS`, I will:
|
|
60
65
|
```
|
61
66
|
- Mark any uncertainties with `[NEEDS CLARIFICATION: specific question]`
|
62
67
|
- Use detected feature context to determine target directory
|
63
|
-
-
|
64
|
-
- Write NEW specification to `specs/ID-feature-name/spec-XXX.md`
|
68
|
+
- Write FULL specification content to `specs/ID-feature-name/spec-XXX.md`
|
65
69
|
- Can EDIT files in specs/ folder, but NEVER modify templates/, scripts/, or commands/ folders
|
66
70
|
- Run validation:
|
67
|
-
- `bash scripts/sp-pulse-spec.sh "$FEATURE_DIR"`
|
71
|
+
- `bash scripts/sp-pulse-spec.sh "$FEATURE_DIR" "$SPEC_CONTENT"`
|
68
72
|
|
69
73
|
4. **For `/sp-spec update`:**
|
70
74
|
- **Show existing spec files**: List all spec-XXX.md files in current feature directory
|
@@ -82,15 +82,34 @@ if ($taskContent -match "AUTH-T[0-9]|USER-T[0-9]|INT-T[0-9]") {
|
|
82
82
|
Log-Message "Detected decomposed architecture with service-specific tasks"
|
83
83
|
}
|
84
84
|
|
85
|
-
# Count task status using
|
86
|
-
|
87
|
-
|
88
|
-
$TotalTasks = $
|
89
|
-
|
90
|
-
|
91
|
-
$
|
92
|
-
$
|
93
|
-
$
|
85
|
+
# Count task status using the actual format used in task files
|
86
|
+
# Format is: ### T001: Task Name
|
87
|
+
# **Status**: [x] Completed
|
88
|
+
$TotalTasks = ([regex]::Matches($taskContent, '^### T[0-9]{3}:', [System.Text.RegularExpressions.RegexOptions]::Multiline)).Count
|
89
|
+
|
90
|
+
# Count completed tasks by finding task headers followed by status within next few lines
|
91
|
+
$CompletedTasks = 0
|
92
|
+
$PendingTasks = 0
|
93
|
+
$InProgressTasks = 0
|
94
|
+
$BlockedTasks = 0
|
95
|
+
|
96
|
+
$taskHeaders = [regex]::Matches($taskContent, '^### (T[0-9]{3}):', [System.Text.RegularExpressions.RegexOptions]::Multiline)
|
97
|
+
foreach ($header in $taskHeaders) {
|
98
|
+
$taskId = $header.Groups[1].Value
|
99
|
+
$startIndex = $header.Index
|
100
|
+
$endIndex = if ($header.Index + 500 -lt $taskContent.Length) { $header.Index + 500 } else { $taskContent.Length }
|
101
|
+
$taskSection = $taskContent.Substring($startIndex, $endIndex - $startIndex)
|
102
|
+
|
103
|
+
if ($taskSection -match '\*\*Status\*\*:\s*\[x\]') {
|
104
|
+
$CompletedTasks++
|
105
|
+
} elseif ($taskSection -match '\*\*Status\*\*:\s*\[ \]') {
|
106
|
+
$PendingTasks++
|
107
|
+
} elseif ($taskSection -match '\*\*Status\*\*:\s*\[>\]') {
|
108
|
+
$InProgressTasks++
|
109
|
+
} elseif ($taskSection -match '\*\*Status\*\*:\s*\[!\]') {
|
110
|
+
$BlockedTasks++
|
111
|
+
}
|
112
|
+
}
|
94
113
|
|
95
114
|
# Find next task to execute
|
96
115
|
$NextTask = ""
|
@@ -98,17 +117,34 @@ $TaskDetails = ""
|
|
98
117
|
|
99
118
|
switch ($Command) {
|
100
119
|
{ $_ -in "next", "continue" } {
|
101
|
-
# Find first in-progress task
|
102
|
-
|
103
|
-
|
104
|
-
$
|
105
|
-
$
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
if ($
|
110
|
-
$NextTask = $
|
111
|
-
$TaskDetails = "
|
120
|
+
# Find first in-progress or pending task
|
121
|
+
foreach ($header in $taskHeaders) {
|
122
|
+
$taskId = $header.Groups[1].Value
|
123
|
+
$startIndex = $header.Index
|
124
|
+
$endIndex = if ($header.Index + 500 -lt $taskContent.Length) { $header.Index + 500 } else { $taskContent.Length }
|
125
|
+
$taskSection = $taskContent.Substring($startIndex, $endIndex - $startIndex)
|
126
|
+
|
127
|
+
# Check for in-progress task first
|
128
|
+
if ($taskSection -match '\*\*Status\*\*:\s*\[>\]') {
|
129
|
+
$NextTask = $taskId
|
130
|
+
$TaskDetails = "RESUMING IN-PROGRESS TASK"
|
131
|
+
break
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
# If no in-progress task found, find first pending
|
136
|
+
if (-not $NextTask) {
|
137
|
+
foreach ($header in $taskHeaders) {
|
138
|
+
$taskId = $header.Groups[1].Value
|
139
|
+
$startIndex = $header.Index
|
140
|
+
$endIndex = if ($header.Index + 500 -lt $taskContent.Length) { $header.Index + 500 } else { $taskContent.Length }
|
141
|
+
$taskSection = $taskContent.Substring($startIndex, $endIndex - $startIndex)
|
142
|
+
|
143
|
+
if ($taskSection -match '\*\*Status\*\*:\s*\[ \]') {
|
144
|
+
$NextTask = $taskId
|
145
|
+
$TaskDetails = "STARTING NEW TASK"
|
146
|
+
break
|
147
|
+
}
|
112
148
|
}
|
113
149
|
}
|
114
150
|
}
|
@@ -120,9 +156,8 @@ switch ($Command) {
|
|
120
156
|
}
|
121
157
|
default {
|
122
158
|
# Specific task requested
|
123
|
-
|
124
|
-
|
125
|
-
$NextTask = $specificMatch.Groups[1].Value
|
159
|
+
if ($taskContent -match "^### ($Command):" ) {
|
160
|
+
$NextTask = $Command
|
126
161
|
$TaskDetails = "EXECUTE SPECIFIC TASK"
|
127
162
|
}
|
128
163
|
}
|
@@ -67,23 +67,23 @@ if grep -qE "AUTH-T[0-9]|USER-T[0-9]|INT-T[0-9]" "$TASK_FILE" 2>/dev/null; then
|
|
67
67
|
log "Detected decomposed architecture with service-specific tasks"
|
68
68
|
fi
|
69
69
|
|
70
|
-
# Count task status
|
71
|
-
TOTAL_TASKS=$(grep -cE "
|
72
|
-
COMPLETED_TASKS=$(
|
73
|
-
PENDING_TASKS=$(
|
74
|
-
IN_PROGRESS_TASKS=$(
|
75
|
-
BLOCKED_TASKS=$(
|
70
|
+
# Count task status - handle the actual format used in task files
|
71
|
+
TOTAL_TASKS=$(grep -cE "^### T[0-9]{3}:" "$TASK_FILE" 2>/dev/null || echo "0")
|
72
|
+
COMPLETED_TASKS=$(awk '/^### T[0-9]{3}:/{task=$0; found=0; for(i=0; i<5; i++) {getline; if(/^\*\*Status\*\*: \[x\]/) {found=1; break} if(/^###/) break} if(found) count++} END{print count+0}' "$TASK_FILE" 2>/dev/null || echo "0")
|
73
|
+
PENDING_TASKS=$(awk '/^### T[0-9]{3}:/{task=$0; found=0; for(i=0; i<5; i++) {getline; if(/^\*\*Status\*\*: \[ \]/) {found=1; break} if(/^###/) break} if(found) count++} END{print count+0}' "$TASK_FILE" 2>/dev/null || echo "0")
|
74
|
+
IN_PROGRESS_TASKS=$(awk '/^### T[0-9]{3}:/{task=$0; found=0; for(i=0; i<5; i++) {getline; if(/^\*\*Status\*\*: \[>\]/) {found=1; break} if(/^###/) break} if(found) count++} END{print count+0}' "$TASK_FILE" 2>/dev/null || echo "0")
|
75
|
+
BLOCKED_TASKS=$(awk '/^### T[0-9]{3}:/{task=$0; found=0; for(i=0; i<5; i++) {getline; if(/^\*\*Status\*\*: \[!\]/) {found=1; break} if(/^###/) break} if(found) count++} END{print count+0}' "$TASK_FILE" 2>/dev/null || echo "0")
|
76
76
|
|
77
77
|
# Find next task to execute
|
78
78
|
case "$COMMAND" in
|
79
79
|
"next"|"continue")
|
80
80
|
# Find first in-progress task
|
81
81
|
if [ "$IN_PROGRESS_TASKS" -gt 0 ]; then
|
82
|
-
NEXT_TASK=$(grep
|
82
|
+
NEXT_TASK=$(grep "^\*\*Status\*\*: \[>\]" "$TASK_FILE" -B1 | grep -E "^### T[0-9]{3}:" | head -1 | sed -E 's/^### (T[0-9]{3}):.*/\1/')
|
83
83
|
log "Resuming in-progress task: $NEXT_TASK"
|
84
84
|
# Otherwise find first pending task
|
85
85
|
elif [ "$PENDING_TASKS" -gt 0 ]; then
|
86
|
-
NEXT_TASK=$(grep
|
86
|
+
NEXT_TASK=$(grep "^\*\*Status\*\*: \[ \]" "$TASK_FILE" -B1 | grep -E "^### T[0-9]{3}:" | head -1 | sed -E 's/^### (T[0-9]{3}):.*/\1/')
|
87
87
|
log "Starting next pending task: $NEXT_TASK"
|
88
88
|
else
|
89
89
|
if [ "$BLOCKED_TASKS" -gt 0 ]; then
|
@@ -147,7 +147,7 @@ fi
|
|
147
147
|
if [ "$PENDING_TASKS" -gt 0 ]; then
|
148
148
|
echo ""
|
149
149
|
echo "NEXT_TASKS_PREVIEW:"
|
150
|
-
|
150
|
+
awk '/^### T[0-9]{3}:/{task=$0; found=0; for(i=0; i<5; i++) {getline; if(/^\*\*Status\*\*: \[ \]/) {found=1; break} if(/^###/) break} if(found) {print task; count++; if(count>=5) exit}}' "$TASK_FILE" | while read -r line; do
|
151
151
|
echo " $line"
|
152
152
|
done
|
153
153
|
fi
|
@@ -78,27 +78,30 @@ try {
|
|
78
78
|
$specContent = @"
|
79
79
|
# Specification for $FeatureName
|
80
80
|
|
81
|
-
<!--
|
82
|
-
<!--
|
83
|
-
<!--
|
81
|
+
<!-- INSTRUCTION: Generate specification content using template: $TemplateDir\spec.md -->
|
82
|
+
<!-- FEATURE_DIR: $BranchName -->
|
83
|
+
<!-- FEATURE_ID: $FeatureId -->
|
84
84
|
"@
|
85
85
|
Set-Content -Path "$SpecsDir\spec-001.md" -Value $specContent
|
86
86
|
|
87
87
|
$planContent = @"
|
88
88
|
# Implementation Plan for $FeatureName
|
89
89
|
|
90
|
-
<!--
|
91
|
-
<!--
|
92
|
-
<!--
|
90
|
+
<!-- INSTRUCTION: Generate plan using template: $TemplateDir\plan.md -->
|
91
|
+
<!-- SPEC_FILE: $SpecsDir\spec-001.md -->
|
92
|
+
<!-- FEATURE_DIR: $BranchName -->
|
93
|
+
<!-- FEATURE_ID: $FeatureId -->
|
93
94
|
"@
|
94
95
|
Set-Content -Path "$PlansDir\plan-001.md" -Value $planContent
|
95
96
|
|
96
97
|
$taskContent = @"
|
97
98
|
# Task Breakdown for $FeatureName
|
98
99
|
|
99
|
-
<!--
|
100
|
-
<!--
|
101
|
-
<!--
|
100
|
+
<!-- INSTRUCTION: Generate tasks using template: $TemplateDir\task.md -->
|
101
|
+
<!-- SPEC_FILE: $SpecsDir\spec-001.md -->
|
102
|
+
<!-- PLAN_FILE: $PlansDir\plan-001.md -->
|
103
|
+
<!-- FEATURE_DIR: $BranchName -->
|
104
|
+
<!-- FEATURE_ID: $FeatureId -->
|
102
105
|
"@
|
103
106
|
Set-Content -Path "$TasksDir\task-001.md" -Value $taskContent
|
104
107
|
} catch {
|
@@ -73,19 +73,22 @@ echo "# Task Breakdown for $FEATURE_NAME" > "$TASKS_DIR/task-001.md"
|
|
73
73
|
|
74
74
|
# Add markers indicating these files need AI processing
|
75
75
|
echo "" >> "$SPECS_DIR/spec-001.md"
|
76
|
-
echo "<!--
|
77
|
-
echo "<!--
|
78
|
-
echo "<!--
|
76
|
+
echo "<!-- INSTRUCTION: Generate specification content using template: $TEMPLATE_DIR/spec.md -->" >> "$SPECS_DIR/spec-001.md"
|
77
|
+
echo "<!-- FEATURE_DIR: $BRANCH_NAME -->" >> "$SPECS_DIR/spec-001.md"
|
78
|
+
echo "<!-- FEATURE_ID: $FEATURE_ID -->" >> "$SPECS_DIR/spec-001.md"
|
79
79
|
|
80
80
|
echo "" >> "$PLANS_DIR/plan-001.md"
|
81
|
-
echo "<!--
|
82
|
-
echo "<!--
|
83
|
-
echo "<!--
|
81
|
+
echo "<!-- INSTRUCTION: Generate plan using template: $TEMPLATE_DIR/plan.md -->" >> "$PLANS_DIR/plan-001.md"
|
82
|
+
echo "<!-- SPEC_FILE: $SPECS_DIR/spec-001.md -->" >> "$PLANS_DIR/plan-001.md"
|
83
|
+
echo "<!-- FEATURE_DIR: $BRANCH_NAME -->" >> "$PLANS_DIR/plan-001.md"
|
84
|
+
echo "<!-- FEATURE_ID: $FEATURE_ID -->" >> "$PLANS_DIR/plan-001.md"
|
84
85
|
|
85
86
|
echo "" >> "$TASKS_DIR/task-001.md"
|
86
|
-
echo "<!--
|
87
|
-
echo "<!--
|
88
|
-
echo "<!--
|
87
|
+
echo "<!-- INSTRUCTION: Generate tasks using template: $TEMPLATE_DIR/task.md -->" >> "$TASKS_DIR/task-001.md"
|
88
|
+
echo "<!-- SPEC_FILE: $SPECS_DIR/spec-001.md -->" >> "$TASKS_DIR/task-001.md"
|
89
|
+
echo "<!-- PLAN_FILE: $PLANS_DIR/plan-001.md -->" >> "$TASKS_DIR/task-001.md"
|
90
|
+
echo "<!-- FEATURE_DIR: $BRANCH_NAME -->" >> "$TASKS_DIR/task-001.md"
|
91
|
+
echo "<!-- FEATURE_ID: $FEATURE_ID -->" >> "$TASKS_DIR/task-001.md"
|
89
92
|
|
90
93
|
# Update context
|
91
94
|
CONTEXT_FILE="$PROJECT_ROOT/memory/context.md"
|
@@ -57,9 +57,20 @@ if (Test-Path $SpecDir) {
|
|
57
57
|
Exit-WithError "Specifications directory not found: $SpecDir. Please create specification first."
|
58
58
|
}
|
59
59
|
|
60
|
-
#
|
61
|
-
$
|
62
|
-
|
60
|
+
# Check if plan-001.md exists
|
61
|
+
$FirstPlan = Join-Path $PlanDir "plan-001.md"
|
62
|
+
if (Test-Path $FirstPlan) {
|
63
|
+
# Find next available plan number
|
64
|
+
$existingPlans = Get-ChildItem -Path $PlanDir -Filter "plan-*.md" -ErrorAction SilentlyContinue | Sort-Object Name
|
65
|
+
if ($existingPlans) {
|
66
|
+
$highestPlan = [int]($existingPlans[-1].BaseName -replace 'plan-', '')
|
67
|
+
$planNumber = $highestPlan + 1
|
68
|
+
} else {
|
69
|
+
$planNumber = 2
|
70
|
+
}
|
71
|
+
} else {
|
72
|
+
$planNumber = 1
|
73
|
+
}
|
63
74
|
$PlanFile = Join-Path $PlanDir ("plan-{0:D3}.md" -f $planNumber)
|
64
75
|
|
65
76
|
# Ensure plan template exists
|
@@ -67,36 +78,50 @@ if (-not (Test-Path $TemplateFile)) {
|
|
67
78
|
Exit-WithError "Template not found: $TemplateFile"
|
68
79
|
}
|
69
80
|
|
70
|
-
# Create plan
|
71
|
-
Log-Message "Creating implementation plan
|
81
|
+
# Create placeholder file for AI to generate plan
|
82
|
+
Log-Message "Creating implementation plan: $PlanFile"
|
72
83
|
try {
|
73
|
-
|
84
|
+
@"
|
85
|
+
# Implementation Plan - $FeatureDir
|
86
|
+
|
87
|
+
<!-- INSTRUCTION: Generate plan using template: $TemplateFile -->
|
88
|
+
<!-- SPEC_FILE: $SpecFile -->
|
89
|
+
<!-- FEATURE_DIR: $FeatureDir -->
|
90
|
+
<!-- FEATURE_ID: $FeatureId -->
|
91
|
+
"@ | Set-Content -Path $PlanFile
|
74
92
|
} catch {
|
75
|
-
Exit-WithError "Failed to
|
93
|
+
Exit-WithError "Failed to create plan file: $_"
|
76
94
|
}
|
77
95
|
|
78
96
|
# Validate plan structure
|
79
97
|
Log-Message "Validating implementation plan..."
|
80
98
|
|
81
|
-
# Check
|
82
|
-
$RequiredSections = @(
|
83
|
-
"## Implementation Plan:",
|
84
|
-
"## Specification Reference",
|
85
|
-
"## Phase -1: Pre-Implementation Gates",
|
86
|
-
"## Implementation Phases"
|
87
|
-
)
|
88
|
-
|
99
|
+
# Check if file needs AI generation
|
89
100
|
$content = Get-Content -Path $PlanFile -Raw
|
90
|
-
$
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
101
|
+
if ($content -match "INSTRUCTION: Generate plan") {
|
102
|
+
Log-Message "WARNING: Plan needs to be generated by AI from template"
|
103
|
+
$MissingSections = @("ALL - Awaiting AI Generation")
|
104
|
+
$GateStatus = "PENDING"
|
105
|
+
} else {
|
106
|
+
# Check for required sections only if file has been generated
|
107
|
+
$RequiredSections = @(
|
108
|
+
"## Implementation Plan:",
|
109
|
+
"## Specification Reference",
|
110
|
+
"## Phase -1: Pre-Implementation Gates",
|
111
|
+
"## Implementation Phases"
|
112
|
+
)
|
113
|
+
|
114
|
+
$MissingSections = @()
|
115
|
+
|
116
|
+
foreach ($section in $RequiredSections) {
|
117
|
+
if ($content -notmatch [regex]::Escape($section)) {
|
118
|
+
$MissingSections += $section
|
119
|
+
}
|
95
120
|
}
|
96
|
-
}
|
97
121
|
|
98
|
-
if ($MissingSections.Count -gt 0) {
|
99
|
-
|
122
|
+
if ($MissingSections.Count -gt 0) {
|
123
|
+
Log-Message "WARNING: Missing required sections: $($MissingSections -join ', ')"
|
124
|
+
}
|
100
125
|
}
|
101
126
|
|
102
127
|
# Check SDD Gates
|
@@ -59,14 +59,14 @@ else
|
|
59
59
|
error_exit "Specifications directory not found: $SPEC_DIR. Please create specification first."
|
60
60
|
fi
|
61
61
|
|
62
|
-
#
|
63
|
-
if [ -
|
64
|
-
#
|
62
|
+
# Check if plan-001.md exists
|
63
|
+
if [ -f "$PLAN_DIR/plan-001.md" ]; then
|
64
|
+
# Find next available plan number
|
65
65
|
highest_plan=$(find "$PLAN_DIR" -name "plan-*.md" -exec basename {} .md \; | sed 's/plan-//' | sort -n | tail -1)
|
66
66
|
if [ -n "$highest_plan" ]; then
|
67
67
|
plan_number=$((highest_plan + 1))
|
68
68
|
else
|
69
|
-
plan_number=
|
69
|
+
plan_number=2
|
70
70
|
fi
|
71
71
|
else
|
72
72
|
plan_number=1
|
@@ -78,23 +78,20 @@ if [ ! -f "$TEMPLATE_FILE" ]; then
|
|
78
78
|
error_exit "Template not found: $TEMPLATE_FILE"
|
79
79
|
fi
|
80
80
|
|
81
|
-
# Create
|
82
|
-
log "Creating implementation plan
|
81
|
+
# Create placeholder file for AI to generate plan
|
82
|
+
log "Creating implementation plan: $PLAN_FILE"
|
83
83
|
echo "# Implementation Plan - $FEATURE_DIR" > "$PLAN_FILE"
|
84
84
|
echo "" >> "$PLAN_FILE"
|
85
|
-
echo "<!--
|
85
|
+
echo "<!-- INSTRUCTION: Generate plan using template: $TEMPLATE_FILE -->" >> "$PLAN_FILE"
|
86
86
|
echo "<!-- SPEC_FILE: $SPEC_FILE -->" >> "$PLAN_FILE"
|
87
87
|
echo "<!-- FEATURE_DIR: $FEATURE_DIR -->" >> "$PLAN_FILE"
|
88
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"
|
92
89
|
|
93
90
|
# Validate plan structure
|
94
91
|
log "Validating implementation plan..."
|
95
92
|
|
96
93
|
# Check if file needs AI generation
|
97
|
-
if grep -q "
|
94
|
+
if grep -q "INSTRUCTION: Generate plan" "$PLAN_FILE"; then
|
98
95
|
log "WARNING: Plan needs to be generated by AI from template"
|
99
96
|
MISSING_SECTIONS=("ALL - Awaiting AI Generation")
|
100
97
|
GATE_STATUS="PENDING"
|