specpulse 1.0.3__py3-none-any.whl → 1.0.5__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.
- specpulse/__init__.py +1 -1
- specpulse/resources/commands/claude/plan.md +180 -50
- specpulse/resources/commands/claude/pulse.md +79 -24
- specpulse/resources/commands/claude/spec.md +156 -43
- specpulse/resources/commands/claude/task.md +229 -48
- specpulse/resources/commands/gemini/plan.toml +59 -48
- specpulse/resources/commands/gemini/pulse.toml +21 -39
- specpulse/resources/commands/gemini/spec.toml +40 -28
- specpulse/resources/commands/gemini/task.toml +69 -51
- specpulse/resources/memory/constitution.md +2 -2
- specpulse/resources/scripts/pulse-init.ps1 +186 -0
- specpulse/resources/scripts/pulse-init.py +171 -0
- specpulse/resources/scripts/pulse-init.sh +80 -21
- specpulse/resources/scripts/pulse-plan.ps1 +251 -0
- specpulse/resources/scripts/pulse-plan.py +191 -0
- specpulse/resources/scripts/pulse-plan.sh +113 -12
- specpulse/resources/scripts/pulse-spec.ps1 +185 -0
- specpulse/resources/scripts/pulse-spec.py +167 -0
- specpulse/resources/scripts/pulse-spec.sh +86 -11
- specpulse/resources/scripts/pulse-task.ps1 +263 -0
- specpulse/resources/scripts/pulse-task.py +237 -0
- specpulse/resources/scripts/pulse-task.sh +123 -9
- specpulse/resources/templates/plan.md +142 -287
- specpulse/resources/templates/spec.md +80 -246
- specpulse/resources/templates/task.md +114 -93
- {specpulse-1.0.3.dist-info → specpulse-1.0.5.dist-info}/METADATA +67 -34
- specpulse-1.0.5.dist-info/RECORD +41 -0
- specpulse-1.0.3.dist-info/RECORD +0 -33
- {specpulse-1.0.3.dist-info → specpulse-1.0.5.dist-info}/WHEEL +0 -0
- {specpulse-1.0.3.dist-info → specpulse-1.0.5.dist-info}/entry_points.txt +0 -0
- {specpulse-1.0.3.dist-info → specpulse-1.0.5.dist-info}/licenses/LICENSE +0 -0
- {specpulse-1.0.3.dist-info → specpulse-1.0.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,185 @@
|
|
1
|
+
# SpecPulse Specification Generation Script
|
2
|
+
# Cross-platform PowerShell equivalent of pulse-spec.sh
|
3
|
+
|
4
|
+
param(
|
5
|
+
[Parameter(Mandatory=$true)]
|
6
|
+
[string]$FeatureDir,
|
7
|
+
|
8
|
+
[string]$SpecContent = ""
|
9
|
+
)
|
10
|
+
|
11
|
+
$ErrorActionPreference = "Stop"
|
12
|
+
$ProgressPreference = "SilentlyContinue"
|
13
|
+
|
14
|
+
# Configuration
|
15
|
+
$ScriptName = $MyInvocation.MyCommand.Name
|
16
|
+
$ProjectRoot = $PSScriptRoot | Split-Path -Parent | Split-Path -Parent
|
17
|
+
$MemoryDir = Join-Path $ProjectRoot "memory"
|
18
|
+
$ContextFile = Join-Path $MemoryDir "context.md"
|
19
|
+
$TemplatesDir = Join-Path $ProjectRoot "resources" "templates"
|
20
|
+
|
21
|
+
function Write-Log {
|
22
|
+
param([string]$Message)
|
23
|
+
$Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
24
|
+
Write-Host "[$Timestamp] $ScriptName : $Message" -ForegroundColor Yellow
|
25
|
+
}
|
26
|
+
|
27
|
+
function Exit-WithError {
|
28
|
+
param([string]$Message)
|
29
|
+
Write-Log "ERROR: $Message"
|
30
|
+
exit 1
|
31
|
+
}
|
32
|
+
|
33
|
+
function Sanitize-FeatureDir {
|
34
|
+
param([string]$Dir)
|
35
|
+
|
36
|
+
if ([string]::IsNullOrWhiteSpace($Dir)) {
|
37
|
+
Exit-WithError "Feature directory cannot be empty"
|
38
|
+
}
|
39
|
+
|
40
|
+
# Remove non-alphanumeric characters except hyphens and underscores
|
41
|
+
$Sanitized = $Dir -replace '[^a-zA-Z0-9_-]', ''
|
42
|
+
|
43
|
+
if ([string]::IsNullOrWhiteSpace($Sanitized)) {
|
44
|
+
Exit-WithError "Invalid feature directory: '$Dir'"
|
45
|
+
}
|
46
|
+
|
47
|
+
return $Sanitized
|
48
|
+
}
|
49
|
+
|
50
|
+
function Find-FeatureDirectory {
|
51
|
+
if (-not (Test-Path $ContextFile)) {
|
52
|
+
Exit-WithError "No context file found and no feature directory provided"
|
53
|
+
}
|
54
|
+
|
55
|
+
try {
|
56
|
+
$Content = Get-Content $ContextFile -Raw -Encoding UTF8
|
57
|
+
# Look for "Active Feature" section
|
58
|
+
if ($Content -match 'Active Feature:\s*(.+)') {
|
59
|
+
$FeatureDir = $matches[1].Trim()
|
60
|
+
Write-Log "Using active feature from context: $FeatureDir"
|
61
|
+
return $FeatureDir
|
62
|
+
} else {
|
63
|
+
Exit-WithError "No active feature found in context file"
|
64
|
+
}
|
65
|
+
} catch {
|
66
|
+
Exit-WithError "Failed to read context file: $_"
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
function Get-CurrentFeatureDir {
|
71
|
+
param([string]$ProvidedDir)
|
72
|
+
|
73
|
+
if ($ProvidedDir) {
|
74
|
+
return Sanitize-FeatureDir -Dir $ProvidedDir
|
75
|
+
} else {
|
76
|
+
return Find-FeatureDirectory
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
function Validate-Specification {
|
81
|
+
param([string]$SpecFile)
|
82
|
+
|
83
|
+
if (-not (Test-Path $SpecFile)) {
|
84
|
+
Exit-WithError "Specification file does not exist: $SpecFile"
|
85
|
+
}
|
86
|
+
|
87
|
+
# Required sections
|
88
|
+
$RequiredSections = @(
|
89
|
+
"## Specification:",
|
90
|
+
"## Metadata",
|
91
|
+
"## Functional Requirements",
|
92
|
+
"## Acceptance Scenarios"
|
93
|
+
)
|
94
|
+
|
95
|
+
$Content = Get-Content $SpecFile -Raw -Encoding UTF8
|
96
|
+
$MissingSections = @()
|
97
|
+
|
98
|
+
foreach ($Section in $RequiredSections) {
|
99
|
+
if ($Content -notmatch [regex]::Escape($Section)) {
|
100
|
+
$MissingSections += $Section
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
if ($MissingSections.Count -gt 0) {
|
105
|
+
Write-Log "WARNING: Missing required sections: $($MissingSections -join ', ')"
|
106
|
+
}
|
107
|
+
|
108
|
+
# Check for clarifications needed
|
109
|
+
$ClarificationMatches = [regex]::Matches($Content, 'NEEDS CLARIFICATION')
|
110
|
+
if ($ClarificationMatches.Count -gt 0) {
|
111
|
+
$ClarificationCount = $ClarificationMatches.Count
|
112
|
+
Write-Log "WARNING: Specification has $ClarificationCount clarifications needed"
|
113
|
+
return $ClarificationCount
|
114
|
+
}
|
115
|
+
|
116
|
+
return 0
|
117
|
+
}
|
118
|
+
|
119
|
+
# Main execution
|
120
|
+
Write-Log "Processing specification..."
|
121
|
+
|
122
|
+
# Get and sanitize feature directory
|
123
|
+
$SanitizedDir = Get-CurrentFeatureDir -ProvidedDir $FeatureDir
|
124
|
+
|
125
|
+
# Set file paths
|
126
|
+
$SpecFile = Join-Path $ProjectRoot "specs" $SanitizedDir "spec.md"
|
127
|
+
$TemplateFile = Join-Path $TemplatesDir "spec.md"
|
128
|
+
|
129
|
+
# Ensure specs directory exists
|
130
|
+
$SpecDir = Split-Path $SpecFile -Parent
|
131
|
+
New-Item -ItemType Directory -Path $SpecDir -Force | Out-Null
|
132
|
+
|
133
|
+
# Handle specification content
|
134
|
+
if ($SpecContent) {
|
135
|
+
Write-Log "Updating specification: $SpecFile"
|
136
|
+
try {
|
137
|
+
Set-Content -Path $SpecFile -Value $SpecContent -Encoding UTF8
|
138
|
+
} catch {
|
139
|
+
Exit-WithError "Failed to write specification content: $_"
|
140
|
+
}
|
141
|
+
} else {
|
142
|
+
# Ensure specification exists from template
|
143
|
+
if (-not (Test-Path $SpecFile)) {
|
144
|
+
if (-not (Test-Path $TemplateFile)) {
|
145
|
+
Exit-WithError "Template not found: $TemplateFile"
|
146
|
+
}
|
147
|
+
|
148
|
+
Write-Log "Creating specification from template: $SpecFile"
|
149
|
+
try {
|
150
|
+
Copy-Item $TemplateFile $SpecFile -Force
|
151
|
+
} catch {
|
152
|
+
Exit-WithError "Failed to copy specification template: $_"
|
153
|
+
}
|
154
|
+
} else {
|
155
|
+
Write-Log "Specification already exists: $SpecFile"
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
# Validate specification
|
160
|
+
Write-Log "Validating specification..."
|
161
|
+
$ClarificationCount = Validate-Specification -SpecFile $SpecFile
|
162
|
+
|
163
|
+
# Check for missing sections
|
164
|
+
$Content = Get-Content $SpecFile -Raw -Encoding UTF8
|
165
|
+
$RequiredSections = @(
|
166
|
+
"## Specification:",
|
167
|
+
"## Metadata",
|
168
|
+
"## Functional Requirements",
|
169
|
+
"## Acceptance Scenarios"
|
170
|
+
)
|
171
|
+
|
172
|
+
$MissingSections = @()
|
173
|
+
foreach ($Section in $RequiredSections) {
|
174
|
+
if ($Content -notmatch [regex]::Escape($Section)) {
|
175
|
+
$MissingSections += $Section
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
Write-Log "Specification processing completed successfully"
|
180
|
+
|
181
|
+
# Output results
|
182
|
+
Write-Host "SPEC_FILE=$SpecFile"
|
183
|
+
Write-Host "CLARIFICATIONS_NEEDED=$ClarificationCount"
|
184
|
+
Write-Host "MISSING_SECTIONS=$($MissingSections.Count)"
|
185
|
+
Write-Host "STATUS=updated"
|
@@ -0,0 +1,167 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
SpecPulse Specification Generation Script
|
4
|
+
Cross-platform Python equivalent of pulse-spec.sh
|
5
|
+
"""
|
6
|
+
|
7
|
+
import os
|
8
|
+
import sys
|
9
|
+
import re
|
10
|
+
from pathlib import Path
|
11
|
+
import datetime
|
12
|
+
|
13
|
+
class SpecPulseSpec:
|
14
|
+
def __init__(self):
|
15
|
+
self.script_name = Path(__file__).name
|
16
|
+
self.project_root = Path(__file__).parent.parent.parent
|
17
|
+
self.memory_dir = self.project_root / "memory"
|
18
|
+
self.context_file = self.memory_dir / "context.md"
|
19
|
+
self.templates_dir = self.project_root / "resources" / "templates"
|
20
|
+
|
21
|
+
def log(self, message):
|
22
|
+
"""Log messages with timestamp"""
|
23
|
+
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
24
|
+
print(f"[{timestamp}] {self.script_name}: {message}", file=sys.stderr)
|
25
|
+
|
26
|
+
def error_exit(self, message):
|
27
|
+
"""Exit with error message"""
|
28
|
+
self.log(f"ERROR: {message}")
|
29
|
+
sys.exit(1)
|
30
|
+
|
31
|
+
def sanitize_feature_dir(self, feature_dir):
|
32
|
+
"""Sanitize feature directory name"""
|
33
|
+
if not feature_dir:
|
34
|
+
self.error_exit("Feature directory cannot be empty")
|
35
|
+
|
36
|
+
# Remove non-alphanumeric characters except hyphens and underscores
|
37
|
+
sanitized = re.sub(r'[^a-zA-Z0-9_-]', '', feature_dir)
|
38
|
+
|
39
|
+
if not sanitized:
|
40
|
+
self.error_exit(f"Invalid feature directory: '{feature_dir}'")
|
41
|
+
|
42
|
+
return sanitized
|
43
|
+
|
44
|
+
def find_feature_directory(self):
|
45
|
+
"""Find feature directory from context file"""
|
46
|
+
if not self.context_file.exists():
|
47
|
+
self.error_exit("No context file found and no feature directory provided")
|
48
|
+
|
49
|
+
try:
|
50
|
+
content = self.context_file.read_text(encoding='utf-8')
|
51
|
+
# Look for "Active Feature" section
|
52
|
+
match = re.search(r'Active Feature:\s*(.+)', content)
|
53
|
+
if match:
|
54
|
+
feature_dir = match.group(1).strip()
|
55
|
+
self.log(f"Using active feature from context: {feature_dir}")
|
56
|
+
return feature_dir
|
57
|
+
else:
|
58
|
+
self.error_exit("No active feature found in context file")
|
59
|
+
except Exception as e:
|
60
|
+
self.error_exit(f"Failed to read context file: {e}")
|
61
|
+
|
62
|
+
def get_current_feature_dir(self, provided_dir):
|
63
|
+
"""Get current feature directory"""
|
64
|
+
if provided_dir:
|
65
|
+
return self.sanitize_feature_dir(provided_dir)
|
66
|
+
else:
|
67
|
+
return self.find_feature_directory()
|
68
|
+
|
69
|
+
def validate_specification(self, spec_file):
|
70
|
+
"""Validate specification structure"""
|
71
|
+
if not spec_file.exists():
|
72
|
+
self.error_exit(f"Specification file does not exist: {spec_file}")
|
73
|
+
|
74
|
+
# Required sections
|
75
|
+
required_sections = [
|
76
|
+
"## Specification:",
|
77
|
+
"## Metadata",
|
78
|
+
"## Functional Requirements",
|
79
|
+
"## Acceptance Scenarios"
|
80
|
+
]
|
81
|
+
|
82
|
+
missing_sections = []
|
83
|
+
content = spec_file.read_text(encoding='utf-8')
|
84
|
+
|
85
|
+
for section in required_sections:
|
86
|
+
if section not in content:
|
87
|
+
missing_sections.append(section)
|
88
|
+
|
89
|
+
if missing_sections:
|
90
|
+
self.log(f"WARNING: Missing required sections: {', '.join(missing_sections)}")
|
91
|
+
|
92
|
+
# Check for clarifications needed
|
93
|
+
clarification_matches = re.findall(r'NEEDS CLARIFICATION', content)
|
94
|
+
if clarification_matches:
|
95
|
+
clarification_count = len(clarification_matches)
|
96
|
+
self.log(f"WARNING: Specification has {clarification_count} clarifications needed")
|
97
|
+
return clarification_count
|
98
|
+
|
99
|
+
return 0
|
100
|
+
|
101
|
+
def main(self, args):
|
102
|
+
"""Main execution function"""
|
103
|
+
if len(args) < 1:
|
104
|
+
self.error_exit("Usage: python pulse-spec.py <feature-dir> [spec-content]")
|
105
|
+
|
106
|
+
feature_dir = args[0]
|
107
|
+
spec_content = args[1] if len(args) > 1 else None
|
108
|
+
|
109
|
+
self.log("Processing specification...")
|
110
|
+
|
111
|
+
# Get and sanitize feature directory
|
112
|
+
sanitized_dir = self.get_current_feature_dir(feature_dir)
|
113
|
+
|
114
|
+
# Set file paths
|
115
|
+
spec_file = self.project_root / "specs" / sanitized_dir / "spec.md"
|
116
|
+
template_file = self.templates_dir / "spec.md"
|
117
|
+
|
118
|
+
# Ensure specs directory exists
|
119
|
+
spec_file.parent.mkdir(parents=True, exist_ok=True)
|
120
|
+
|
121
|
+
# Handle specification content
|
122
|
+
if spec_content:
|
123
|
+
self.log(f"Updating specification: {spec_file}")
|
124
|
+
try:
|
125
|
+
spec_file.write_text(spec_content, encoding='utf-8')
|
126
|
+
except Exception as e:
|
127
|
+
self.error_exit(f"Failed to write specification content: {e}")
|
128
|
+
else:
|
129
|
+
# Ensure specification exists from template
|
130
|
+
if not spec_file.exists():
|
131
|
+
if not template_file.exists():
|
132
|
+
self.error_exit(f"Template not found: {template_file}")
|
133
|
+
|
134
|
+
self.log(f"Creating specification from template: {spec_file}")
|
135
|
+
try:
|
136
|
+
spec_file.write_text(template_file.read_text(encoding='utf-8'))
|
137
|
+
except Exception as e:
|
138
|
+
self.error_exit(f"Failed to copy specification template: {e}")
|
139
|
+
else:
|
140
|
+
self.log(f"Specification already exists: {spec_file}")
|
141
|
+
|
142
|
+
# Validate specification
|
143
|
+
self.log("Validating specification...")
|
144
|
+
clarification_count = self.validate_specification(spec_file)
|
145
|
+
|
146
|
+
# Check for missing sections
|
147
|
+
required_sections = [
|
148
|
+
"## Specification:",
|
149
|
+
"## Metadata",
|
150
|
+
"## Functional Requirements",
|
151
|
+
"## Acceptance Scenarios"
|
152
|
+
]
|
153
|
+
|
154
|
+
content = spec_file.read_text(encoding='utf-8')
|
155
|
+
missing_sections = [s for s in required_sections if s not in content]
|
156
|
+
|
157
|
+
self.log("Specification processing completed successfully")
|
158
|
+
|
159
|
+
# Output results
|
160
|
+
print(f"SPEC_FILE={spec_file}")
|
161
|
+
print(f"CLARIFICATIONS_NEEDED={clarification_count}")
|
162
|
+
print(f"MISSING_SECTIONS={len(missing_sections)}")
|
163
|
+
print("STATUS=updated")
|
164
|
+
|
165
|
+
if __name__ == "__main__":
|
166
|
+
spec = SpecPulseSpec()
|
167
|
+
spec.main(sys.argv[1:])
|
@@ -1,29 +1,104 @@
|
|
1
1
|
#!/bin/bash
|
2
2
|
# Generate or update specification
|
3
3
|
|
4
|
-
|
5
|
-
SPEC_CONTENT="${2}"
|
4
|
+
set -euo pipefail # Exit on error, unset vars, pipe failures
|
6
5
|
|
6
|
+
# Configuration
|
7
|
+
SCRIPT_NAME="$(basename "$0")"
|
8
|
+
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
9
|
+
|
10
|
+
# Function to log messages
|
11
|
+
log() {
|
12
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $SCRIPT_NAME: $1" >&2
|
13
|
+
}
|
14
|
+
|
15
|
+
# Function to handle errors
|
16
|
+
error_exit() {
|
17
|
+
log "ERROR: $1"
|
18
|
+
exit 1
|
19
|
+
}
|
20
|
+
|
21
|
+
# Validate arguments
|
22
|
+
if [ $# -eq 0 ]; then
|
23
|
+
error_exit "Usage: $SCRIPT_NAME <feature-dir> [spec-content]"
|
24
|
+
fi
|
25
|
+
|
26
|
+
FEATURE_DIR="$1"
|
27
|
+
SPEC_CONTENT="${2:-}"
|
28
|
+
|
29
|
+
# Sanitize feature directory
|
30
|
+
SANITIZED_DIR=$(echo "$FEATURE_DIR" | sed 's/[^a-zA-Z0-9_-]//g')
|
31
|
+
|
32
|
+
if [ -z "$SANITIZED_DIR" ]; then
|
33
|
+
error_exit "Invalid feature directory: '$FEATURE_DIR'"
|
34
|
+
fi
|
35
|
+
|
36
|
+
# Find feature directory if not provided
|
7
37
|
if [ -z "$FEATURE_DIR" ]; then
|
8
|
-
|
9
|
-
|
38
|
+
CONTEXT_FILE="$PROJECT_ROOT/memory/context.md"
|
39
|
+
if [ -f "$CONTEXT_FILE" ]; then
|
40
|
+
FEATURE_DIR=$(grep -A1 "Active Feature" "$CONTEXT_FILE" | tail -1 | cut -d: -f2 | xargs)
|
41
|
+
if [ -z "$FEATURE_DIR" ]; then
|
42
|
+
error_exit "No active feature found in context file"
|
43
|
+
fi
|
44
|
+
log "Using active feature from context: $FEATURE_DIR"
|
45
|
+
else
|
46
|
+
error_exit "No feature directory provided and no context file found"
|
47
|
+
fi
|
10
48
|
fi
|
11
49
|
|
12
|
-
SPEC_FILE="specs/${FEATURE_DIR}/spec.md"
|
50
|
+
SPEC_FILE="$PROJECT_ROOT/specs/${FEATURE_DIR}/spec.md"
|
51
|
+
TEMPLATE_FILE="$PROJECT_ROOT/templates/spec.md"
|
52
|
+
|
53
|
+
# Ensure specs directory exists
|
54
|
+
mkdir -p "$(dirname "$SPEC_FILE")"
|
13
55
|
|
14
56
|
if [ -n "$SPEC_CONTENT" ]; then
|
15
|
-
# Update specification with content
|
16
|
-
|
57
|
+
# Update specification with provided content
|
58
|
+
log "Updating specification: $SPEC_FILE"
|
59
|
+
echo "$SPEC_CONTENT" > "$SPEC_FILE" || error_exit "Failed to write specification content"
|
17
60
|
else
|
18
|
-
# Ensure
|
61
|
+
# Ensure specification exists from template
|
19
62
|
if [ ! -f "$SPEC_FILE" ]; then
|
20
|
-
|
63
|
+
if [ ! -f "$TEMPLATE_FILE" ]; then
|
64
|
+
error_exit "Template not found: $TEMPLATE_FILE"
|
65
|
+
fi
|
66
|
+
log "Creating specification from template: $SPEC_FILE"
|
67
|
+
cp "$TEMPLATE_FILE" "$SPEC_FILE" || error_exit "Failed to copy specification template"
|
68
|
+
else
|
69
|
+
log "Specification already exists: $SPEC_FILE"
|
21
70
|
fi
|
22
71
|
fi
|
23
72
|
|
24
73
|
# Validate specification
|
25
|
-
|
26
|
-
|
74
|
+
log "Validating specification..."
|
75
|
+
if [ ! -f "$SPEC_FILE" ]; then
|
76
|
+
error_exit "Specification file does not exist: $SPEC_FILE"
|
77
|
+
fi
|
78
|
+
|
79
|
+
# Check for required sections
|
80
|
+
REQUIRED_SECTIONS=("## Specification:" "## Metadata" "## Functional Requirements" "## Acceptance Scenarios")
|
81
|
+
MISSING_SECTIONS=()
|
82
|
+
|
83
|
+
for section in "${REQUIRED_SECTIONS[@]}"; do
|
84
|
+
if ! grep -q "$section" "$SPEC_FILE"; then
|
85
|
+
MISSING_SECTIONS+=("$section")
|
86
|
+
fi
|
87
|
+
done
|
88
|
+
|
89
|
+
if [ ${#MISSING_SECTIONS[@]} -gt 0 ]; then
|
90
|
+
log "WARNING: Missing required sections: ${MISSING_SECTIONS[*]}"
|
91
|
+
fi
|
92
|
+
|
93
|
+
# Check for clarifications needed
|
94
|
+
if grep -q "NEEDS CLARIFICATION" "$SPEC_FILE"; then
|
95
|
+
CLARIFICATION_COUNT=$(grep -c "NEEDS CLARIFICATION" "$SPEC_FILE")
|
96
|
+
log "WARNING: Specification has $CLARIFICATION_COUNT clarifications needed"
|
97
|
+
fi
|
98
|
+
|
99
|
+
log "Specification processing completed successfully"
|
27
100
|
|
28
101
|
echo "SPEC_FILE=$SPEC_FILE"
|
102
|
+
echo "CLARIFICATIONS_NEEDED=${CLARIFICATION_COUNT:-0}"
|
103
|
+
echo "MISSING_SECTIONS=${#MISSING_SECTIONS[@]}"
|
29
104
|
echo "STATUS=updated"
|