specflow-cc 1.12.0 → 1.14.0
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/CHANGELOG.md +74 -0
- package/README.md +22 -8
- package/agents/impl-reviewer.md +8 -0
- package/agents/sf-spec-executor-orchestrator.md +8 -0
- package/agents/spec-auditor.md +8 -0
- package/agents/spec-creator.md +13 -2
- package/agents/spec-executor-orchestrator.md +21 -0
- package/agents/spec-executor.md +8 -0
- package/agents/spec-reviser.md +8 -0
- package/agents/spec-splitter.md +11 -1
- package/bin/install.js +20 -0
- package/bin/lib/config.cjs +91 -0
- package/bin/lib/core.cjs +120 -0
- package/bin/lib/spec.cjs +130 -0
- package/bin/lib/state.cjs +241 -0
- package/bin/lib/verify.cjs +117 -0
- package/bin/sf-tools.cjs +103 -0
- package/commands/sf/audit.md +11 -69
- package/commands/sf/autopilot.md +601 -0
- package/commands/sf/done.md +32 -71
- package/commands/sf/health.md +220 -0
- package/commands/sf/help.md +16 -0
- package/commands/sf/review.md +11 -69
- package/commands/sf/revise.md +4 -7
- package/commands/sf/run.md +11 -69
- package/commands/sf/split.md +14 -3
- package/commands/sf/validate.md +154 -0
- package/hooks/context-monitor.js +121 -0
- package/hooks/statusline.js +17 -0
- package/package.json +1 -1
package/commands/sf/done.md
CHANGED
|
@@ -175,7 +175,7 @@ mkdir -p .specflow/archive
|
|
|
175
175
|
Update frontmatter:
|
|
176
176
|
- status → "done"
|
|
177
177
|
|
|
178
|
-
Add completion
|
|
178
|
+
Add completion summary section to the spec:
|
|
179
179
|
|
|
180
180
|
```markdown
|
|
181
181
|
---
|
|
@@ -185,14 +185,33 @@ Add completion timestamp:
|
|
|
185
185
|
**Completed:** {date} {time}
|
|
186
186
|
**Total Commits:** {count from Execution Summary}
|
|
187
187
|
**Review Cycles:** {count of Review v[N] entries}
|
|
188
|
+
|
|
189
|
+
### Outcome
|
|
190
|
+
|
|
191
|
+
{1-2 sentence summary of what was delivered}
|
|
192
|
+
|
|
193
|
+
### Key Files
|
|
194
|
+
|
|
195
|
+
- `{path}` — {what it does/why it matters}
|
|
196
|
+
|
|
197
|
+
### Patterns Established
|
|
198
|
+
|
|
199
|
+
{List any new patterns, conventions, or architectural decisions introduced.
|
|
200
|
+
If none: "None — followed existing patterns."}
|
|
201
|
+
|
|
202
|
+
### Deviations
|
|
203
|
+
|
|
204
|
+
{Any deviations from the original spec during implementation.
|
|
205
|
+
If none: "None — implemented as specified."}
|
|
188
206
|
```
|
|
189
207
|
|
|
190
208
|
## Step 7: Extract Decisions
|
|
191
209
|
|
|
192
|
-
Scan specification for important decisions:
|
|
210
|
+
Scan specification and Completion section for important decisions:
|
|
193
211
|
- Technology choices mentioned in Context or Assumptions
|
|
194
212
|
- Patterns established during implementation
|
|
195
213
|
- Constraints discovered
|
|
214
|
+
- Deviations that became new conventions
|
|
196
215
|
|
|
197
216
|
If significant decisions found, add to STATE.md Decisions table:
|
|
198
217
|
|
|
@@ -228,75 +247,17 @@ If implementation established new patterns, add to Project Patterns section.
|
|
|
228
247
|
|
|
229
248
|
After updating STATE.md, check if rotation is needed:
|
|
230
249
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
RECENT_DECISIONS=$(echo "$DECISIONS" | tail -5)
|
|
243
|
-
OLD_DECISION_COUNT=$((DECISION_COUNT - 5))
|
|
244
|
-
OLD_DECISIONS=$(echo "$DECISIONS" | head -n $OLD_DECISION_COUNT)
|
|
245
|
-
|
|
246
|
-
# Create or append to archive
|
|
247
|
-
if [ ! -f .specflow/DECISIONS_ARCHIVE.md ]; then
|
|
248
|
-
cat > .specflow/DECISIONS_ARCHIVE.md << 'EOF'
|
|
249
|
-
# SpecFlow Decisions Archive
|
|
250
|
-
|
|
251
|
-
Historical decisions rotated from STATE.md to maintain compactness.
|
|
252
|
-
|
|
253
|
-
## Archived Decisions
|
|
254
|
-
|
|
255
|
-
| Date | Decision |
|
|
256
|
-
|------|----------|
|
|
257
|
-
EOF
|
|
258
|
-
fi
|
|
259
|
-
|
|
260
|
-
# Write old decisions to temp file for awk to read (awk -v cannot handle multiline strings)
|
|
261
|
-
TEMP_OLD=$(mktemp)
|
|
262
|
-
echo "$OLD_DECISIONS" > "$TEMP_OLD"
|
|
263
|
-
|
|
264
|
-
# Append old decisions to archive (insert after table header)
|
|
265
|
-
TEMP_ARCHIVE=$(mktemp)
|
|
266
|
-
awk -v oldfile="$TEMP_OLD" '
|
|
267
|
-
/^\| Date \| Decision \|$/ { print; getline; print; while ((getline line < oldfile) > 0) print line; close(oldfile); next }
|
|
268
|
-
{print}
|
|
269
|
-
' .specflow/DECISIONS_ARCHIVE.md > "$TEMP_ARCHIVE"
|
|
270
|
-
mv "$TEMP_ARCHIVE" .specflow/DECISIONS_ARCHIVE.md
|
|
271
|
-
rm -f "$TEMP_OLD"
|
|
272
|
-
|
|
273
|
-
# Write recent decisions to temp file for awk to read
|
|
274
|
-
TEMP_RECENT=$(mktemp)
|
|
275
|
-
echo "$RECENT_DECISIONS" > "$TEMP_RECENT"
|
|
276
|
-
|
|
277
|
-
# Update STATE.md with only recent decisions
|
|
278
|
-
TEMP_STATE=$(mktemp)
|
|
279
|
-
awk -v recentfile="$TEMP_RECENT" '
|
|
280
|
-
/^## Decisions$/ {
|
|
281
|
-
print
|
|
282
|
-
print ""
|
|
283
|
-
print "| Date | Decision |"
|
|
284
|
-
print "|------|----------|"
|
|
285
|
-
while ((getline line < recentfile) > 0) print line
|
|
286
|
-
close(recentfile)
|
|
287
|
-
in_decisions=1
|
|
288
|
-
next
|
|
289
|
-
}
|
|
290
|
-
/^## / && in_decisions { in_decisions=0 }
|
|
291
|
-
!in_decisions || !/^\|/ { print }
|
|
292
|
-
' .specflow/STATE.md > "$TEMP_STATE"
|
|
293
|
-
mv "$TEMP_STATE" .specflow/STATE.md
|
|
294
|
-
rm -f "$TEMP_RECENT"
|
|
295
|
-
|
|
296
|
-
echo "Rotated $(echo "$OLD_DECISIONS" | grep -c '^|') old decisions to DECISIONS_ARCHIVE.md"
|
|
297
|
-
fi
|
|
298
|
-
fi
|
|
299
|
-
```
|
|
250
|
+
1. Use the Read tool to read `.specflow/STATE.md` and count total lines
|
|
251
|
+
2. If total lines <= 100, no action needed
|
|
252
|
+
3. If total lines > 100:
|
|
253
|
+
a. Read the `## Decisions` section and extract all decision rows (lines matching `| YYYY-`)
|
|
254
|
+
b. Count decision rows. If <= 7, no rotation needed
|
|
255
|
+
c. If > 7 decisions:
|
|
256
|
+
- Identify the 5 most recent decisions (last 5 rows) -- these STAY
|
|
257
|
+
- Identify older decisions (all rows except last 5) -- these MOVE to archive
|
|
258
|
+
- Read `.specflow/DECISIONS_ARCHIVE.md` (create with template if missing)
|
|
259
|
+
- Write updated DECISIONS_ARCHIVE.md: insert old decisions after the table header row
|
|
260
|
+
- Write updated STATE.md: replace Decisions section content with only the 5 most recent decisions
|
|
300
261
|
|
|
301
262
|
## Step 10: Create Final Commit (if needed)
|
|
302
263
|
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sf:health
|
|
3
|
+
description: Diagnose .specflow/ directory health and optionally repair issues
|
|
4
|
+
argument-hint: [--repair]
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Bash
|
|
8
|
+
- Glob
|
|
9
|
+
- Write
|
|
10
|
+
- AskUserQuestion
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
<purpose>
|
|
14
|
+
Validate `.specflow/` directory integrity and report actionable issues. Checks for missing files, invalid state, orphaned specs, and queue inconsistencies. Optionally repairs auto-fixable issues.
|
|
15
|
+
</purpose>
|
|
16
|
+
|
|
17
|
+
<context>
|
|
18
|
+
@.specflow/STATE.md
|
|
19
|
+
</context>
|
|
20
|
+
|
|
21
|
+
<workflow>
|
|
22
|
+
|
|
23
|
+
## Step 1: Verify Initialization
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
[ -d .specflow ] && echo "OK" || echo "NOT_INITIALIZED"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**If NOT_INITIALIZED:**
|
|
30
|
+
```
|
|
31
|
+
SpecFlow not initialized. Run `/sf:init` first.
|
|
32
|
+
```
|
|
33
|
+
Exit.
|
|
34
|
+
|
|
35
|
+
## Step 2: Parse Arguments
|
|
36
|
+
|
|
37
|
+
Check if `--repair` flag is present.
|
|
38
|
+
|
|
39
|
+
## Step 3: Run Health Checks
|
|
40
|
+
|
|
41
|
+
Initialize collectors:
|
|
42
|
+
- `errors[]` — critical issues
|
|
43
|
+
- `warnings[]` — non-critical issues
|
|
44
|
+
- `info[]` — informational notes
|
|
45
|
+
- `repairs[]` — actions taken (if --repair)
|
|
46
|
+
|
|
47
|
+
### 3.1 Core Files Check
|
|
48
|
+
|
|
49
|
+
| Check | File | Severity | Repairable |
|
|
50
|
+
|-------|------|----------|------------|
|
|
51
|
+
| E001 | `.specflow/STATE.md` missing | error | Yes — regenerate minimal STATE.md |
|
|
52
|
+
| E002 | `.specflow/STATE.md` missing `## Queue` section | error | No |
|
|
53
|
+
| W001 | `.specflow/todos/TODO.md` missing | warning | Yes — create empty TODO.md |
|
|
54
|
+
| W002 | `.specflow/specs/` directory missing | warning | Yes — create directory |
|
|
55
|
+
| W003 | `.specflow/archive/` directory missing | warning | Yes — create directory |
|
|
56
|
+
| W004 | `.specflow/execution/` directory missing | warning | Yes — create directory |
|
|
57
|
+
|
|
58
|
+
For each check:
|
|
59
|
+
1. Test existence
|
|
60
|
+
2. If missing and repairable and `--repair`: fix it, add to `repairs[]`
|
|
61
|
+
3. If missing and not repairable: add to `errors[]` or `warnings[]`
|
|
62
|
+
|
|
63
|
+
### 3.2 STATE.md Integrity
|
|
64
|
+
|
|
65
|
+
Read STATE.md and validate:
|
|
66
|
+
|
|
67
|
+
**E003: Active spec references non-existent file**
|
|
68
|
+
- Extract active spec ID from `## Active Specification`
|
|
69
|
+
- If not "—" or empty, check `.specflow/specs/{ID}.md` exists
|
|
70
|
+
- If missing: error (repairable — clear active spec to "—")
|
|
71
|
+
|
|
72
|
+
**W005: Queue references non-existent spec file**
|
|
73
|
+
- Parse queue table rows
|
|
74
|
+
- For each spec ID, verify `.specflow/specs/{ID}.md` or `.specflow/archive/{ID}.md` exists
|
|
75
|
+
- If missing: warning (not repairable — spec may have been manually deleted)
|
|
76
|
+
|
|
77
|
+
**W006: Queue has duplicate spec IDs**
|
|
78
|
+
- Parse all IDs from queue table
|
|
79
|
+
- If duplicates found: warning (not repairable)
|
|
80
|
+
|
|
81
|
+
**W007: STATUS.md malformed — missing required sections**
|
|
82
|
+
- Check for: `## Active Specification`, `## Queue`
|
|
83
|
+
- If missing: warning
|
|
84
|
+
|
|
85
|
+
### 3.3 Orphaned Specs Check
|
|
86
|
+
|
|
87
|
+
**I001: Spec file exists but not in queue or archive**
|
|
88
|
+
- List all files in `.specflow/specs/`
|
|
89
|
+
- For each, check if its ID appears in STATE.md queue
|
|
90
|
+
- If not: info (may be work-in-progress)
|
|
91
|
+
|
|
92
|
+
### 3.4 Archive Consistency
|
|
93
|
+
|
|
94
|
+
**I002: Spec in queue marked as completed but not archived**
|
|
95
|
+
- Parse queue for specs with status containing "done" or "complete"
|
|
96
|
+
- Check if file exists in `.specflow/archive/`
|
|
97
|
+
- If not: info
|
|
98
|
+
|
|
99
|
+
### 3.5 Execution State
|
|
100
|
+
|
|
101
|
+
**W008: Stale execution state files**
|
|
102
|
+
- List `.specflow/execution/*.json`
|
|
103
|
+
- For each, check if the spec ID is the currently active spec
|
|
104
|
+
- If not active: warning (repairable — delete stale files)
|
|
105
|
+
|
|
106
|
+
## Step 4: Calculate Status
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
HEALTHY = 0 errors, 0 warnings
|
|
110
|
+
DEGRADED = 0 errors, 1+ warnings
|
|
111
|
+
BROKEN = 1+ errors
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Step 5: Display Results
|
|
115
|
+
|
|
116
|
+
**IMPORTANT:** Output the following directly as formatted text, NOT wrapped in a markdown code block:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
120
|
+
SpecFlow Health Check
|
|
121
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
122
|
+
|
|
123
|
+
**Status:** HEALTHY | DEGRADED | BROKEN
|
|
124
|
+
**Errors:** N | **Warnings:** N | **Info:** N
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**If repairs were performed:**
|
|
128
|
+
```
|
|
129
|
+
### Repairs Performed
|
|
130
|
+
|
|
131
|
+
- Repaired: {description}
|
|
132
|
+
- Repaired: {description}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**If errors exist:**
|
|
136
|
+
```
|
|
137
|
+
### Errors
|
|
138
|
+
|
|
139
|
+
- [{code}] {message}
|
|
140
|
+
Fix: {suggested fix}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**If warnings exist:**
|
|
144
|
+
```
|
|
145
|
+
### Warnings
|
|
146
|
+
|
|
147
|
+
- [{code}] {message}
|
|
148
|
+
Fix: {suggested fix}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**If info exists:**
|
|
152
|
+
```
|
|
153
|
+
### Info
|
|
154
|
+
|
|
155
|
+
- [{code}] {message}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Footer (if repairable issues exist and --repair was NOT used):**
|
|
159
|
+
```
|
|
160
|
+
---
|
|
161
|
+
{N} issues can be auto-repaired. Run: `/sf:health --repair`
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Step 6: Offer Repair (if applicable)
|
|
165
|
+
|
|
166
|
+
If repairable issues found and `--repair` was NOT passed:
|
|
167
|
+
- Ask user if they want to run repairs
|
|
168
|
+
- If yes, execute repairs and re-run checks to verify
|
|
169
|
+
|
|
170
|
+
## Step 7: Verify Repairs (if --repair was used)
|
|
171
|
+
|
|
172
|
+
Re-run all checks without repair to confirm resolution.
|
|
173
|
+
Display final status.
|
|
174
|
+
|
|
175
|
+
</workflow>
|
|
176
|
+
|
|
177
|
+
<error_codes>
|
|
178
|
+
|
|
179
|
+
| Code | Severity | Description | Repairable |
|
|
180
|
+
|------|----------|-------------|------------|
|
|
181
|
+
| E001 | error | STATE.md not found | Yes |
|
|
182
|
+
| E002 | error | STATE.md missing Queue section | No |
|
|
183
|
+
| E003 | error | Active spec references non-existent file | Yes |
|
|
184
|
+
| W001 | warning | TODO.md not found | Yes |
|
|
185
|
+
| W002 | warning | specs/ directory missing | Yes |
|
|
186
|
+
| W003 | warning | archive/ directory missing | Yes |
|
|
187
|
+
| W004 | warning | execution/ directory missing | Yes |
|
|
188
|
+
| W005 | warning | Queue references non-existent spec | No |
|
|
189
|
+
| W006 | warning | Queue has duplicate spec IDs | No |
|
|
190
|
+
| W007 | warning | STATE.md missing required sections | No |
|
|
191
|
+
| W008 | warning | Stale execution state files | Yes |
|
|
192
|
+
| I001 | info | Spec not in queue (may be WIP) | No |
|
|
193
|
+
| I002 | info | Completed spec not archived | No |
|
|
194
|
+
|
|
195
|
+
</error_codes>
|
|
196
|
+
|
|
197
|
+
<repair_actions>
|
|
198
|
+
|
|
199
|
+
| Action | Effect | Risk |
|
|
200
|
+
|--------|--------|------|
|
|
201
|
+
| Create STATE.md | Minimal template with empty queue | None |
|
|
202
|
+
| Create TODO.md | Empty TODO template | None |
|
|
203
|
+
| Create directories | specs/, archive/, execution/ | None |
|
|
204
|
+
| Clear active spec | Set to "—" if spec file missing | Loses active reference |
|
|
205
|
+
| Delete stale execution | Remove orphaned .json state files | None |
|
|
206
|
+
|
|
207
|
+
**Not repairable (too risky):**
|
|
208
|
+
- STATE.md content/queue entries
|
|
209
|
+
- Spec file contents
|
|
210
|
+
- Archive decisions
|
|
211
|
+
|
|
212
|
+
</repair_actions>
|
|
213
|
+
|
|
214
|
+
<success_criteria>
|
|
215
|
+
- [ ] All health checks executed
|
|
216
|
+
- [ ] Clear status reported (HEALTHY/DEGRADED/BROKEN)
|
|
217
|
+
- [ ] Each issue has error code and suggested fix
|
|
218
|
+
- [ ] --repair only fixes safe, non-destructive issues
|
|
219
|
+
- [ ] Repairs verified by re-running checks
|
|
220
|
+
</success_criteria>
|
package/commands/sf/help.md
CHANGED
|
@@ -226,6 +226,7 @@ Workflow: Spec → Audit → Revise → Run → Review → Fix → Done
|
|
|
226
226
|
| /sf:revise | Revise spec based on audit feedback |
|
|
227
227
|
| /sf:run | Execute specification |
|
|
228
228
|
| /sf:review | Review implementation (fresh context) |
|
|
229
|
+
| /sf:validate | Run validation checklist from spec |
|
|
229
230
|
| /sf:verify | Interactive human verification |
|
|
230
231
|
| /sf:fix | Fix implementation based on review |
|
|
231
232
|
| /sf:done | Finalize, commit, and archive |
|
|
@@ -236,6 +237,12 @@ Workflow: Spec → Audit → Revise → Run → Review → Fix → Done
|
|
|
236
237
|
|--------------|-----------------------------------------|
|
|
237
238
|
| /sf:quick | Execute minor tasks (1-3 files) fast |
|
|
238
239
|
|
|
240
|
+
## Autonomous Execution
|
|
241
|
+
|
|
242
|
+
| Command | Description |
|
|
243
|
+
|--------------|-----------------------------------------|
|
|
244
|
+
| /sf:autopilot | Run full lifecycle autonomously |
|
|
245
|
+
|
|
239
246
|
## Navigation
|
|
240
247
|
|
|
241
248
|
| Command | Description |
|
|
@@ -282,6 +289,7 @@ Workflow: Spec → Audit → Revise → Run → Review → Fix → Done
|
|
|
282
289
|
| Command | Description |
|
|
283
290
|
|--------------|-----------------------------------------|
|
|
284
291
|
| /sf:help | This help (or detailed: /sf:help new) |
|
|
292
|
+
| /sf:health | Diagnose .specflow/ integrity (--repair)|
|
|
285
293
|
| /sf:history | View completed specifications |
|
|
286
294
|
| /sf:metrics | Project statistics and insights |
|
|
287
295
|
|
|
@@ -296,6 +304,7 @@ Workflow: Spec → Audit → Revise → Run → Review → Fix → Done
|
|
|
296
304
|
5. `/sf:run` — Implement
|
|
297
305
|
6. `/sf:review` — Review implementation
|
|
298
306
|
7. `/sf:done` — Complete and archive
|
|
307
|
+
8. Or skip steps 4-7: `/sf:autopilot` -- run everything autonomously
|
|
299
308
|
|
|
300
309
|
## Typical Session
|
|
301
310
|
|
|
@@ -309,6 +318,13 @@ Workflow: Spec → Audit → Revise → Run → Review → Fix → Done
|
|
|
309
318
|
/sf:done # Complete
|
|
310
319
|
```
|
|
311
320
|
|
|
321
|
+
## Autonomous Alternative
|
|
322
|
+
|
|
323
|
+
```
|
|
324
|
+
/sf:autopilot # Process active spec end-to-end
|
|
325
|
+
/sf:autopilot --all # Process entire queue
|
|
326
|
+
```
|
|
327
|
+
|
|
312
328
|
---
|
|
313
329
|
|
|
314
330
|
**Detailed help:** `/sf:help <command>`
|
package/commands/sf/review.md
CHANGED
|
@@ -129,75 +129,17 @@ The agent will:
|
|
|
129
129
|
|
|
130
130
|
After the agent updates STATE.md, check if rotation is needed:
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
RECENT_DECISIONS=$(echo "$DECISIONS" | tail -5)
|
|
144
|
-
OLD_DECISION_COUNT=$((DECISION_COUNT - 5))
|
|
145
|
-
OLD_DECISIONS=$(echo "$DECISIONS" | head -n $OLD_DECISION_COUNT)
|
|
146
|
-
|
|
147
|
-
# Create or append to archive
|
|
148
|
-
if [ ! -f .specflow/DECISIONS_ARCHIVE.md ]; then
|
|
149
|
-
cat > .specflow/DECISIONS_ARCHIVE.md << 'EOF'
|
|
150
|
-
# SpecFlow Decisions Archive
|
|
151
|
-
|
|
152
|
-
Historical decisions rotated from STATE.md to maintain compactness.
|
|
153
|
-
|
|
154
|
-
## Archived Decisions
|
|
155
|
-
|
|
156
|
-
| Date | Decision |
|
|
157
|
-
|------|----------|
|
|
158
|
-
EOF
|
|
159
|
-
fi
|
|
160
|
-
|
|
161
|
-
# Write old decisions to temp file for awk to read (awk -v cannot handle multiline strings)
|
|
162
|
-
TEMP_OLD=$(mktemp)
|
|
163
|
-
echo "$OLD_DECISIONS" > "$TEMP_OLD"
|
|
164
|
-
|
|
165
|
-
# Append old decisions to archive (insert after table header)
|
|
166
|
-
TEMP_ARCHIVE=$(mktemp)
|
|
167
|
-
awk -v oldfile="$TEMP_OLD" '
|
|
168
|
-
/^\| Date \| Decision \|$/ { print; getline; print; while ((getline line < oldfile) > 0) print line; close(oldfile); next }
|
|
169
|
-
{print}
|
|
170
|
-
' .specflow/DECISIONS_ARCHIVE.md > "$TEMP_ARCHIVE"
|
|
171
|
-
mv "$TEMP_ARCHIVE" .specflow/DECISIONS_ARCHIVE.md
|
|
172
|
-
rm -f "$TEMP_OLD"
|
|
173
|
-
|
|
174
|
-
# Write recent decisions to temp file for awk to read
|
|
175
|
-
TEMP_RECENT=$(mktemp)
|
|
176
|
-
echo "$RECENT_DECISIONS" > "$TEMP_RECENT"
|
|
177
|
-
|
|
178
|
-
# Update STATE.md with only recent decisions
|
|
179
|
-
TEMP_STATE=$(mktemp)
|
|
180
|
-
awk -v recentfile="$TEMP_RECENT" '
|
|
181
|
-
/^## Decisions$/ {
|
|
182
|
-
print
|
|
183
|
-
print ""
|
|
184
|
-
print "| Date | Decision |"
|
|
185
|
-
print "|------|----------|"
|
|
186
|
-
while ((getline line < recentfile) > 0) print line
|
|
187
|
-
close(recentfile)
|
|
188
|
-
in_decisions=1
|
|
189
|
-
next
|
|
190
|
-
}
|
|
191
|
-
/^## / && in_decisions { in_decisions=0 }
|
|
192
|
-
!in_decisions || !/^\|/ { print }
|
|
193
|
-
' .specflow/STATE.md > "$TEMP_STATE"
|
|
194
|
-
mv "$TEMP_STATE" .specflow/STATE.md
|
|
195
|
-
rm -f "$TEMP_RECENT"
|
|
196
|
-
|
|
197
|
-
echo "Rotated $(echo "$OLD_DECISIONS" | grep -c '^|') old decisions to DECISIONS_ARCHIVE.md"
|
|
198
|
-
fi
|
|
199
|
-
fi
|
|
200
|
-
```
|
|
132
|
+
1. Use the Read tool to read `.specflow/STATE.md` and count total lines
|
|
133
|
+
2. If total lines <= 100, no action needed
|
|
134
|
+
3. If total lines > 100:
|
|
135
|
+
a. Read the `## Decisions` section and extract all decision rows (lines matching `| YYYY-`)
|
|
136
|
+
b. Count decision rows. If <= 7, no rotation needed
|
|
137
|
+
c. If > 7 decisions:
|
|
138
|
+
- Identify the 5 most recent decisions (last 5 rows) -- these STAY
|
|
139
|
+
- Identify older decisions (all rows except last 5) -- these MOVE to archive
|
|
140
|
+
- Read `.specflow/DECISIONS_ARCHIVE.md` (create with template if missing)
|
|
141
|
+
- Write updated DECISIONS_ARCHIVE.md: insert old decisions after the table header row
|
|
142
|
+
- Write updated STATE.md: replace Decisions section content with only the 5 most recent decisions
|
|
201
143
|
|
|
202
144
|
## Step 8: Display Result
|
|
203
145
|
|
package/commands/sf/revise.md
CHANGED
|
@@ -156,13 +156,10 @@ Continue to Step 5 with analysis context available.
|
|
|
156
156
|
| "..." | Treat as custom revision instructions |
|
|
157
157
|
|
|
158
158
|
**Check for `--no-analysis` flag:**
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
ARGS=$(echo "$ARGS" | sed 's/--no-analysis//g' | xargs)
|
|
164
|
-
fi
|
|
165
|
-
```
|
|
159
|
+
|
|
160
|
+
If the arguments string contains `--no-analysis`:
|
|
161
|
+
- Set SKIP_ANALYSIS to true
|
|
162
|
+
- Remove the `--no-analysis` flag from the arguments string for further processing
|
|
166
163
|
|
|
167
164
|
### If Interactive Mode (no arguments):
|
|
168
165
|
|
package/commands/sf/run.md
CHANGED
|
@@ -251,75 +251,17 @@ The agent will:
|
|
|
251
251
|
|
|
252
252
|
After updating STATE.md, check if rotation is needed:
|
|
253
253
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
RECENT_DECISIONS=$(echo "$DECISIONS" | tail -5)
|
|
266
|
-
OLD_DECISION_COUNT=$((DECISION_COUNT - 5))
|
|
267
|
-
OLD_DECISIONS=$(echo "$DECISIONS" | head -n $OLD_DECISION_COUNT)
|
|
268
|
-
|
|
269
|
-
# Create or append to archive
|
|
270
|
-
if [ ! -f .specflow/DECISIONS_ARCHIVE.md ]; then
|
|
271
|
-
cat > .specflow/DECISIONS_ARCHIVE.md << 'EOF'
|
|
272
|
-
# SpecFlow Decisions Archive
|
|
273
|
-
|
|
274
|
-
Historical decisions rotated from STATE.md to maintain compactness.
|
|
275
|
-
|
|
276
|
-
## Archived Decisions
|
|
277
|
-
|
|
278
|
-
| Date | Decision |
|
|
279
|
-
|------|----------|
|
|
280
|
-
EOF
|
|
281
|
-
fi
|
|
282
|
-
|
|
283
|
-
# Write old decisions to temp file for awk to read (awk -v cannot handle multiline strings)
|
|
284
|
-
TEMP_OLD=$(mktemp)
|
|
285
|
-
echo "$OLD_DECISIONS" > "$TEMP_OLD"
|
|
286
|
-
|
|
287
|
-
# Append old decisions to archive (insert after table header)
|
|
288
|
-
TEMP_ARCHIVE=$(mktemp)
|
|
289
|
-
awk -v oldfile="$TEMP_OLD" '
|
|
290
|
-
/^\| Date \| Decision \|$/ { print; getline; print; while ((getline line < oldfile) > 0) print line; close(oldfile); next }
|
|
291
|
-
{print}
|
|
292
|
-
' .specflow/DECISIONS_ARCHIVE.md > "$TEMP_ARCHIVE"
|
|
293
|
-
mv "$TEMP_ARCHIVE" .specflow/DECISIONS_ARCHIVE.md
|
|
294
|
-
rm -f "$TEMP_OLD"
|
|
295
|
-
|
|
296
|
-
# Write recent decisions to temp file for awk to read
|
|
297
|
-
TEMP_RECENT=$(mktemp)
|
|
298
|
-
echo "$RECENT_DECISIONS" > "$TEMP_RECENT"
|
|
299
|
-
|
|
300
|
-
# Update STATE.md with only recent decisions
|
|
301
|
-
TEMP_STATE=$(mktemp)
|
|
302
|
-
awk -v recentfile="$TEMP_RECENT" '
|
|
303
|
-
/^## Decisions$/ {
|
|
304
|
-
print
|
|
305
|
-
print ""
|
|
306
|
-
print "| Date | Decision |"
|
|
307
|
-
print "|------|----------|"
|
|
308
|
-
while ((getline line < recentfile) > 0) print line
|
|
309
|
-
close(recentfile)
|
|
310
|
-
in_decisions=1
|
|
311
|
-
next
|
|
312
|
-
}
|
|
313
|
-
/^## / && in_decisions { in_decisions=0 }
|
|
314
|
-
!in_decisions || !/^\|/ { print }
|
|
315
|
-
' .specflow/STATE.md > "$TEMP_STATE"
|
|
316
|
-
mv "$TEMP_STATE" .specflow/STATE.md
|
|
317
|
-
rm -f "$TEMP_RECENT"
|
|
318
|
-
|
|
319
|
-
echo "Rotated $(echo "$OLD_DECISIONS" | grep -c '^|') old decisions to DECISIONS_ARCHIVE.md"
|
|
320
|
-
fi
|
|
321
|
-
fi
|
|
322
|
-
```
|
|
254
|
+
1. Use the Read tool to read `.specflow/STATE.md` and count total lines
|
|
255
|
+
2. If total lines <= 100, no action needed
|
|
256
|
+
3. If total lines > 100:
|
|
257
|
+
a. Read the `## Decisions` section and extract all decision rows (lines matching `| YYYY-`)
|
|
258
|
+
b. Count decision rows. If <= 7, no rotation needed
|
|
259
|
+
c. If > 7 decisions:
|
|
260
|
+
- Identify the 5 most recent decisions (last 5 rows) -- these STAY
|
|
261
|
+
- Identify older decisions (all rows except last 5) -- these MOVE to archive
|
|
262
|
+
- Read `.specflow/DECISIONS_ARCHIVE.md` (create with template if missing)
|
|
263
|
+
- Write updated DECISIONS_ARCHIVE.md: insert old decisions after the table header row
|
|
264
|
+
- Write updated STATE.md: replace Decisions section content with only the 5 most recent decisions
|
|
323
265
|
|
|
324
266
|
## Step 10: Display Result
|
|
325
267
|
|
package/commands/sf/split.md
CHANGED
|
@@ -201,9 +201,20 @@ Your choice [1]:
|
|
|
201
201
|
|
|
202
202
|
**If 1 (Accept):**
|
|
203
203
|
- Agent creates child specifications
|
|
204
|
-
- Agent archives parent
|
|
205
|
-
-
|
|
206
|
-
|
|
204
|
+
- Agent archives parent and updates STATE.md
|
|
205
|
+
- **Verify archival:** After agent completes, check if parent was moved:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
if [ -f ".specflow/specs/{ID}.md" ]; then
|
|
209
|
+
mkdir -p .specflow/archive
|
|
210
|
+
mv ".specflow/specs/{ID}.md" ".specflow/archive/{ID}.md"
|
|
211
|
+
echo "ARCHIVED"
|
|
212
|
+
else
|
|
213
|
+
echo "ALREADY_ARCHIVED"
|
|
214
|
+
fi
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
- Continue to Step 8
|
|
207
218
|
|
|
208
219
|
**If 2 (Modify):**
|
|
209
220
|
- Use AskUserQuestion to get modifications
|