gsd-cc 0.1.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/README.md +54 -0
- package/bin/install.js +209 -0
- package/package.json +29 -0
- package/skills/gsd/SKILL.md +178 -0
- package/skills/gsd/apply/.gitkeep +0 -0
- package/skills/gsd/apply/SKILL.md +182 -0
- package/skills/gsd/auto/.gitkeep +0 -0
- package/skills/gsd/auto/SKILL.md +129 -0
- package/skills/gsd/auto/auto-loop.sh +350 -0
- package/skills/gsd/checklists/.gitkeep +0 -0
- package/skills/gsd/checklists/planning-ready.md +36 -0
- package/skills/gsd/checklists/unify-complete.md +41 -0
- package/skills/gsd/discuss/.gitkeep +0 -0
- package/skills/gsd/discuss/SKILL.md +145 -0
- package/skills/gsd/plan/.gitkeep +0 -0
- package/skills/gsd/plan/SKILL.md +250 -0
- package/skills/gsd/prompts/.gitkeep +0 -0
- package/skills/gsd/prompts/apply-instructions.txt +98 -0
- package/skills/gsd/prompts/plan-instructions.txt +76 -0
- package/skills/gsd/prompts/reassess-instructions.txt +65 -0
- package/skills/gsd/prompts/unify-instructions.txt +126 -0
- package/skills/gsd/seed/SKILL.md +186 -0
- package/skills/gsd/seed/types/application/.gitkeep +0 -0
- package/skills/gsd/seed/types/application/config.md +30 -0
- package/skills/gsd/seed/types/application/guide.md +81 -0
- package/skills/gsd/seed/types/application/loadout.md +31 -0
- package/skills/gsd/seed/types/campaign/.gitkeep +0 -0
- package/skills/gsd/seed/types/campaign/config.md +27 -0
- package/skills/gsd/seed/types/campaign/guide.md +57 -0
- package/skills/gsd/seed/types/campaign/loadout.md +30 -0
- package/skills/gsd/seed/types/client/.gitkeep +0 -0
- package/skills/gsd/seed/types/client/config.md +27 -0
- package/skills/gsd/seed/types/client/guide.md +57 -0
- package/skills/gsd/seed/types/client/loadout.md +31 -0
- package/skills/gsd/seed/types/utility/.gitkeep +0 -0
- package/skills/gsd/seed/types/utility/config.md +27 -0
- package/skills/gsd/seed/types/utility/guide.md +49 -0
- package/skills/gsd/seed/types/utility/loadout.md +20 -0
- package/skills/gsd/seed/types/workflow/.gitkeep +0 -0
- package/skills/gsd/seed/types/workflow/config.md +28 -0
- package/skills/gsd/seed/types/workflow/guide.md +65 -0
- package/skills/gsd/seed/types/workflow/loadout.md +21 -0
- package/skills/gsd/status/.gitkeep +0 -0
- package/skills/gsd/status/SKILL.md +157 -0
- package/skills/gsd/templates/.gitkeep +0 -0
- package/skills/gsd/templates/PLAN.xml +65 -0
- package/skills/gsd/templates/PLANNING.md +63 -0
- package/skills/gsd/templates/STATE.md +41 -0
- package/skills/gsd/templates/UNIFY.md +43 -0
- package/skills/gsd/unify/.gitkeep +0 -0
- package/skills/gsd/unify/SKILL.md +230 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd-cc-auto
|
|
3
|
+
description: >
|
|
4
|
+
Start auto-mode. Dispatches tasks via claude -p in fresh sessions.
|
|
5
|
+
Use when user says /gsd-cc-auto, /gsd-cc auto, or chooses "auto" when
|
|
6
|
+
/gsd-cc offers manual vs. auto execution.
|
|
7
|
+
allowed-tools: Read, Write, Bash, Glob
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# /gsd-cc-auto — Auto-Mode
|
|
11
|
+
|
|
12
|
+
You start the auto-loop that executes tasks autonomously, each in a fresh context window.
|
|
13
|
+
|
|
14
|
+
## Step 1: Check Prerequisites
|
|
15
|
+
|
|
16
|
+
Before starting, verify ALL of these:
|
|
17
|
+
|
|
18
|
+
### .gsd/STATE.md exists
|
|
19
|
+
```
|
|
20
|
+
If not: "No project set up. Run /gsd-cc first."
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### At least one slice is planned
|
|
24
|
+
```
|
|
25
|
+
Check for S*-PLAN.md files.
|
|
26
|
+
If none: "No slice is planned yet. Run /gsd-cc to plan first."
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### jq is installed
|
|
30
|
+
```bash
|
|
31
|
+
command -v jq
|
|
32
|
+
```
|
|
33
|
+
If not: "jq is required for auto-mode. Install with: `brew install jq`"
|
|
34
|
+
|
|
35
|
+
### claude -p works
|
|
36
|
+
```bash
|
|
37
|
+
claude -p "echo test" --output-format json --bare --max-turns 1
|
|
38
|
+
```
|
|
39
|
+
If fails: "claude -p is not working. Make sure Claude Code is installed and you're logged in with a Max plan."
|
|
40
|
+
|
|
41
|
+
### No stale lock file
|
|
42
|
+
```
|
|
43
|
+
Check .gsd/auto.lock
|
|
44
|
+
```
|
|
45
|
+
If exists: Check if the PID is still running.
|
|
46
|
+
- If running: "Auto-mode is already running (PID {pid}). Stop it first or wait."
|
|
47
|
+
- If stale: "Found stale lock file from a previous run. Clean up and start fresh?"
|
|
48
|
+
On confirmation: delete auto.lock.
|
|
49
|
+
|
|
50
|
+
## Step 2: Show Current State
|
|
51
|
+
|
|
52
|
+
Display what auto-mode will do:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
Auto-mode ready.
|
|
56
|
+
|
|
57
|
+
Milestone: M{n}
|
|
58
|
+
Starting from: S{nn} / T{nn}
|
|
59
|
+
Phase: {phase}
|
|
60
|
+
Rigor: {rigor} (timeouts: {timeout}s, max turns: {max_turns})
|
|
61
|
+
Remaining: {n} tasks in current slice, {m} slices total
|
|
62
|
+
|
|
63
|
+
Each task gets a fresh context window.
|
|
64
|
+
UNIFY runs automatically after each slice.
|
|
65
|
+
Progress is saved to .gsd/ — you can close this terminal safely.
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Step 3: Ask for Budget (Optional)
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
Set a token budget? (Enter a number, or press Enter for unlimited)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
If the user provides a number, pass it as `--budget`.
|
|
75
|
+
If they press Enter or say "no", no budget limit.
|
|
76
|
+
|
|
77
|
+
## Step 4: Start auto-loop.sh
|
|
78
|
+
|
|
79
|
+
Resolve the script location:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Check local first, then global
|
|
83
|
+
if [[ -f ".claude/skills/gsd/auto/auto-loop.sh" ]]; then
|
|
84
|
+
SCRIPT=".claude/skills/gsd/auto/auto-loop.sh"
|
|
85
|
+
elif [[ -f "$HOME/.claude/skills/gsd/auto/auto-loop.sh" ]]; then
|
|
86
|
+
SCRIPT="$HOME/.claude/skills/gsd/auto/auto-loop.sh"
|
|
87
|
+
fi
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Start it:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
bash "$SCRIPT" --budget {budget}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Or without budget:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
bash "$SCRIPT"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Run this via the Bash tool. The output streams in real-time — the user sees each task starting and completing.
|
|
103
|
+
|
|
104
|
+
## Step 5: When It Finishes
|
|
105
|
+
|
|
106
|
+
Auto-mode stops when:
|
|
107
|
+
- **Milestone complete** — all slices unified
|
|
108
|
+
- **Budget reached** — token limit hit
|
|
109
|
+
- **Stuck** — a task failed twice
|
|
110
|
+
- **Timeout** — a single task exceeded its time limit
|
|
111
|
+
- **Error** — claude -p failed
|
|
112
|
+
|
|
113
|
+
After it stops, read `.gsd/STATE.md` and report:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
Auto-mode finished.
|
|
117
|
+
|
|
118
|
+
Completed: {n} tasks across {m} slices
|
|
119
|
+
Status: {milestone complete | stopped at S{nn}/T{nn} | error}
|
|
120
|
+
|
|
121
|
+
Type /gsd-cc-status for full details.
|
|
122
|
+
Type /gsd-cc to continue from where auto-mode stopped.
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Interrupting Auto-Mode
|
|
126
|
+
|
|
127
|
+
The user can interrupt auto-mode with Ctrl+C. The trap in auto-loop.sh cleans up the lock file. When they return:
|
|
128
|
+
- `/gsd-cc` will detect the state and offer to resume
|
|
129
|
+
- No work is lost — completed tasks are committed to git
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# GSD-CC Auto-Mode Loop
|
|
3
|
+
# The only piece of "code" in GSD-CC. Everything else is Skills (Markdown) and State (.gsd/ files).
|
|
4
|
+
#
|
|
5
|
+
# Usage: bash auto-loop.sh [--budget <tokens>]
|
|
6
|
+
# Requires: claude CLI, jq, git
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# ── Configuration ──────────────────────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
GSD_DIR=".gsd"
|
|
13
|
+
LOCK_FILE="$GSD_DIR/auto.lock"
|
|
14
|
+
COSTS_FILE="$GSD_DIR/COSTS.jsonl"
|
|
15
|
+
BUDGET="${GSD_CC_BUDGET:-0}" # 0 = unlimited
|
|
16
|
+
|
|
17
|
+
# Resolve skills directory (global or local)
|
|
18
|
+
if [[ -d ".claude/skills/gsd" ]]; then
|
|
19
|
+
SKILLS_DIR=".claude/skills/gsd"
|
|
20
|
+
elif [[ -d "$HOME/.claude/skills/gsd" ]]; then
|
|
21
|
+
SKILLS_DIR="$HOME/.claude/skills/gsd"
|
|
22
|
+
else
|
|
23
|
+
echo "❌ GSD-CC skills not found. Run 'npx gsd-cc' to install."
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
PROMPTS_DIR="$SKILLS_DIR/prompts"
|
|
28
|
+
|
|
29
|
+
# Parse --budget flag
|
|
30
|
+
while [[ $# -gt 0 ]]; do
|
|
31
|
+
case "$1" in
|
|
32
|
+
--budget) BUDGET="$2"; shift 2 ;;
|
|
33
|
+
*) echo "Unknown flag: $1"; exit 1 ;;
|
|
34
|
+
esac
|
|
35
|
+
done
|
|
36
|
+
|
|
37
|
+
# ── Prerequisites ──────────────────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
if ! command -v claude &>/dev/null; then
|
|
40
|
+
echo "❌ claude CLI not found. Install Claude Code first."
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
if ! command -v jq &>/dev/null; then
|
|
45
|
+
echo "❌ jq not found. Install with: brew install jq"
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
if [[ ! -f "$GSD_DIR/STATE.md" ]]; then
|
|
50
|
+
echo "❌ No .gsd/STATE.md found. Run /gsd-cc first to set up a project."
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# ── Cleanup trap ───────────────────────────────────────────────────────────────
|
|
55
|
+
|
|
56
|
+
cleanup() {
|
|
57
|
+
rm -f "$LOCK_FILE"
|
|
58
|
+
rm -f /tmp/gsd-prompt-$$.txt
|
|
59
|
+
rm -f /tmp/gsd-result-$$.json
|
|
60
|
+
}
|
|
61
|
+
trap cleanup EXIT
|
|
62
|
+
|
|
63
|
+
# ── Helper functions ───────────────────────────────────────────────────────────
|
|
64
|
+
|
|
65
|
+
read_state_field() {
|
|
66
|
+
grep "^$1:" "$GSD_DIR/STATE.md" | head -1 | sed "s/^$1:[[:space:]]*//"
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
update_state_field() {
|
|
70
|
+
local field="$1" value="$2"
|
|
71
|
+
if grep -q "^${field}:" "$GSD_DIR/STATE.md"; then
|
|
72
|
+
sed -i'' -e "s/^${field}:.*/${field}: ${value}/" "$GSD_DIR/STATE.md"
|
|
73
|
+
fi
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
log_cost() {
|
|
77
|
+
local unit="$1" phase="$2" result_file="$3"
|
|
78
|
+
if [[ -f "$result_file" ]]; then
|
|
79
|
+
jq -c "{unit: \"$unit\", phase: \"$phase\", model: .model, usage: .usage, ts: \"$(date -Iseconds)\"}" \
|
|
80
|
+
"$result_file" >> "$COSTS_FILE" 2>/dev/null || true
|
|
81
|
+
fi
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# ── Main loop ──────────────────────────────────────────────────────────────────
|
|
85
|
+
|
|
86
|
+
echo "▶ GSD-CC Auto-Mode starting..."
|
|
87
|
+
echo " Budget: ${BUDGET:-unlimited} tokens"
|
|
88
|
+
echo ""
|
|
89
|
+
|
|
90
|
+
RETRY_COUNT=0
|
|
91
|
+
MAX_RETRIES=2
|
|
92
|
+
|
|
93
|
+
while true; do
|
|
94
|
+
# ── 1. Read state ──────────────────────────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
PHASE=$(read_state_field "phase")
|
|
97
|
+
SLICE=$(read_state_field "current_slice")
|
|
98
|
+
TASK=$(read_state_field "current_task")
|
|
99
|
+
RIGOR=$(read_state_field "rigor")
|
|
100
|
+
MILESTONE=$(read_state_field "milestone")
|
|
101
|
+
|
|
102
|
+
# ── 2. UNIFY enforcement ───────────────────────────────────────────────────
|
|
103
|
+
|
|
104
|
+
if [[ "$PHASE" == "apply-complete" ]]; then
|
|
105
|
+
UNIFY_FILE="$GSD_DIR/${SLICE}-UNIFY.md"
|
|
106
|
+
if [[ ! -f "$UNIFY_FILE" ]]; then
|
|
107
|
+
echo "⚠ Running mandatory UNIFY for $SLICE..."
|
|
108
|
+
|
|
109
|
+
# Build UNIFY prompt
|
|
110
|
+
PROMPT_FILE="/tmp/gsd-prompt-$$.txt"
|
|
111
|
+
echo "<state>" > "$PROMPT_FILE"
|
|
112
|
+
cat "$GSD_DIR/STATE.md" >> "$PROMPT_FILE"
|
|
113
|
+
echo "</state>" >> "$PROMPT_FILE"
|
|
114
|
+
|
|
115
|
+
# Include slice plan
|
|
116
|
+
if [[ -f "$GSD_DIR/${SLICE}-PLAN.md" ]]; then
|
|
117
|
+
echo "<slice-plan>" >> "$PROMPT_FILE"
|
|
118
|
+
cat "$GSD_DIR/${SLICE}-PLAN.md" >> "$PROMPT_FILE"
|
|
119
|
+
echo "</slice-plan>" >> "$PROMPT_FILE"
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
# Include all task plans for this slice
|
|
123
|
+
echo "<task-plans>" >> "$PROMPT_FILE"
|
|
124
|
+
for f in "$GSD_DIR/${SLICE}"-T*-PLAN.md; do
|
|
125
|
+
[[ -f "$f" ]] && cat "$f" >> "$PROMPT_FILE"
|
|
126
|
+
done
|
|
127
|
+
echo "</task-plans>" >> "$PROMPT_FILE"
|
|
128
|
+
|
|
129
|
+
# Include all summaries for this slice
|
|
130
|
+
echo "<summaries>" >> "$PROMPT_FILE"
|
|
131
|
+
for f in "$GSD_DIR/${SLICE}"-T*-SUMMARY.md; do
|
|
132
|
+
[[ -f "$f" ]] && cat "$f" >> "$PROMPT_FILE"
|
|
133
|
+
done
|
|
134
|
+
echo "</summaries>" >> "$PROMPT_FILE"
|
|
135
|
+
|
|
136
|
+
# Include decisions
|
|
137
|
+
if [[ -f "$GSD_DIR/DECISIONS.md" ]]; then
|
|
138
|
+
echo "<decisions>" >> "$PROMPT_FILE"
|
|
139
|
+
cat "$GSD_DIR/DECISIONS.md" >> "$PROMPT_FILE"
|
|
140
|
+
echo "</decisions>" >> "$PROMPT_FILE"
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
cat "$PROMPTS_DIR/unify-instructions.txt" >> "$PROMPT_FILE"
|
|
144
|
+
|
|
145
|
+
RESULT_FILE="/tmp/gsd-result-$$.json"
|
|
146
|
+
timeout 600 claude -p "$(cat "$PROMPT_FILE")" \
|
|
147
|
+
--allowedTools "Read,Write,Edit,Glob,Grep,Bash(git checkout *),Bash(git merge *),Bash(git commit *)" \
|
|
148
|
+
--output-format json --bare \
|
|
149
|
+
--max-turns 15 > "$RESULT_FILE" 2>/dev/null || {
|
|
150
|
+
echo "❌ UNIFY dispatch failed. Check .gsd/auto.lock for recovery."
|
|
151
|
+
break
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
log_cost "$SLICE" "unify" "$RESULT_FILE"
|
|
155
|
+
echo "✓ UNIFY complete for $SLICE."
|
|
156
|
+
continue
|
|
157
|
+
fi
|
|
158
|
+
fi
|
|
159
|
+
|
|
160
|
+
# ── 3. Determine next unit ─────────────────────────────────────────────────
|
|
161
|
+
|
|
162
|
+
# Check if milestone is complete (all slices unified)
|
|
163
|
+
if [[ "$PHASE" == "unified" ]]; then
|
|
164
|
+
# Check roadmap for remaining slices
|
|
165
|
+
NEXT_RESULT=$(claude -p "Read .gsd/STATE.md and all .gsd/M*-ROADMAP.md and .gsd/S*-UNIFY.md files. Determine the next slice that needs work (no PLAN.md or no UNIFY.md). Output ONLY valid JSON: {\"slice\":\"S01\",\"phase\":\"plan\"} or {\"done\":true} if all slices are unified." \
|
|
166
|
+
--allowedTools "Read,Glob" \
|
|
167
|
+
--output-format json --bare --max-turns 3 2>/dev/null) || {
|
|
168
|
+
echo "❌ Failed to determine next unit."
|
|
169
|
+
break
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
NEXT=$(echo "$NEXT_RESULT" | jq -r '.result // empty' 2>/dev/null || echo "$NEXT_RESULT")
|
|
173
|
+
|
|
174
|
+
if echo "$NEXT" | jq -e '.done' > /dev/null 2>&1; then
|
|
175
|
+
echo ""
|
|
176
|
+
echo "✅ Milestone $MILESTONE complete. All slices planned, executed, and unified."
|
|
177
|
+
break
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
SLICE=$(echo "$NEXT" | jq -r '.slice')
|
|
181
|
+
PHASE=$(echo "$NEXT" | jq -r '.phase')
|
|
182
|
+
TASK="T01"
|
|
183
|
+
|
|
184
|
+
update_state_field "current_slice" "$SLICE"
|
|
185
|
+
update_state_field "phase" "$PHASE"
|
|
186
|
+
update_state_field "current_task" "$TASK"
|
|
187
|
+
fi
|
|
188
|
+
|
|
189
|
+
# ── 4. Budget check ────────────────────────────────────────────────────────
|
|
190
|
+
|
|
191
|
+
if [[ "$BUDGET" -gt 0 ]] && [[ -f "$COSTS_FILE" ]]; then
|
|
192
|
+
TOTAL=$(jq -s '[.[].usage // {} | (.input_tokens // 0) + (.output_tokens // 0)] | add // 0' "$COSTS_FILE" 2>/dev/null || echo 0)
|
|
193
|
+
if [[ "$TOTAL" -gt "$BUDGET" ]]; then
|
|
194
|
+
echo ""
|
|
195
|
+
echo "💰 Budget reached (${TOTAL} tokens). Stopping auto-mode."
|
|
196
|
+
break
|
|
197
|
+
fi
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
# ── 5. Set lock file ──────────────────────────────────────────────────────
|
|
201
|
+
|
|
202
|
+
echo "{\"unit\":\"${SLICE}/${TASK}\",\"phase\":\"${PHASE}\",\"pid\":$$,\"started\":\"$(date -Iseconds)\"}" > "$LOCK_FILE"
|
|
203
|
+
|
|
204
|
+
# ── 6. Build prompt ────────────────────────────────────────────────────────
|
|
205
|
+
|
|
206
|
+
PROMPT_FILE="/tmp/gsd-prompt-$$.txt"
|
|
207
|
+
echo "<state>" > "$PROMPT_FILE"
|
|
208
|
+
cat "$GSD_DIR/STATE.md" >> "$PROMPT_FILE"
|
|
209
|
+
echo "</state>" >> "$PROMPT_FILE"
|
|
210
|
+
|
|
211
|
+
case "$PHASE" in
|
|
212
|
+
plan|roadmap-complete|seed-complete|discuss-complete)
|
|
213
|
+
# Planning phase: include project, roadmap, decisions
|
|
214
|
+
[[ -f "$GSD_DIR/PROJECT.md" ]] && { echo "<project>"; cat "$GSD_DIR/PROJECT.md"; echo "</project>"; } >> "$PROMPT_FILE"
|
|
215
|
+
|
|
216
|
+
for f in "$GSD_DIR"/M*-ROADMAP.md; do
|
|
217
|
+
[[ -f "$f" ]] && { echo "<roadmap>"; cat "$f"; echo "</roadmap>"; } >> "$PROMPT_FILE"
|
|
218
|
+
done
|
|
219
|
+
|
|
220
|
+
[[ -f "$GSD_DIR/DECISIONS.md" ]] && { echo "<decisions>"; cat "$GSD_DIR/DECISIONS.md"; echo "</decisions>"; } >> "$PROMPT_FILE"
|
|
221
|
+
|
|
222
|
+
# Include context if it exists
|
|
223
|
+
[[ -f "$GSD_DIR/${SLICE}-CONTEXT.md" ]] && { echo "<context>"; cat "$GSD_DIR/${SLICE}-CONTEXT.md"; echo "</context>"; } >> "$PROMPT_FILE"
|
|
224
|
+
|
|
225
|
+
cat "$PROMPTS_DIR/plan-instructions.txt" >> "$PROMPT_FILE"
|
|
226
|
+
DISPATCH_PHASE="plan"
|
|
227
|
+
;;
|
|
228
|
+
|
|
229
|
+
plan-complete|applying)
|
|
230
|
+
# Execution phase: include task plan, slice plan, decisions, prior summaries
|
|
231
|
+
TASK_PLAN="$GSD_DIR/${SLICE}-${TASK}-PLAN.md"
|
|
232
|
+
SLICE_PLAN="$GSD_DIR/${SLICE}-PLAN.md"
|
|
233
|
+
|
|
234
|
+
[[ -f "$TASK_PLAN" ]] && { echo "<task-plan>"; cat "$TASK_PLAN"; echo "</task-plan>"; } >> "$PROMPT_FILE"
|
|
235
|
+
[[ -f "$SLICE_PLAN" ]] && { echo "<slice-plan>"; cat "$SLICE_PLAN"; echo "</slice-plan>"; } >> "$PROMPT_FILE"
|
|
236
|
+
[[ -f "$GSD_DIR/DECISIONS.md" ]] && { echo "<decisions>"; cat "$GSD_DIR/DECISIONS.md"; echo "</decisions>"; } >> "$PROMPT_FILE"
|
|
237
|
+
|
|
238
|
+
# Prior task summaries for context
|
|
239
|
+
for f in "$GSD_DIR/${SLICE}"-T*-SUMMARY.md; do
|
|
240
|
+
[[ -f "$f" ]] && { echo "<prior-summary>"; cat "$f"; echo "</prior-summary>"; } >> "$PROMPT_FILE"
|
|
241
|
+
done
|
|
242
|
+
|
|
243
|
+
cat "$PROMPTS_DIR/apply-instructions.txt" >> "$PROMPT_FILE"
|
|
244
|
+
DISPATCH_PHASE="apply"
|
|
245
|
+
;;
|
|
246
|
+
|
|
247
|
+
*)
|
|
248
|
+
echo "⚠ Unknown phase: $PHASE. Stopping."
|
|
249
|
+
break
|
|
250
|
+
;;
|
|
251
|
+
esac
|
|
252
|
+
|
|
253
|
+
# ── 7. Rigor-based timeouts ────────────────────────────────────────────────
|
|
254
|
+
|
|
255
|
+
case "$RIGOR" in
|
|
256
|
+
tight) MAX_TURNS=15; TIMEOUT=300 ;;
|
|
257
|
+
standard) MAX_TURNS=25; TIMEOUT=600 ;;
|
|
258
|
+
deep) MAX_TURNS=40; TIMEOUT=1200 ;;
|
|
259
|
+
creative) MAX_TURNS=30; TIMEOUT=900 ;;
|
|
260
|
+
*) MAX_TURNS=25; TIMEOUT=600 ;;
|
|
261
|
+
esac
|
|
262
|
+
|
|
263
|
+
# ── 8. Dispatch ────────────────────────────────────────────────────────────
|
|
264
|
+
|
|
265
|
+
echo "▶ ${SLICE}/${TASK} (${DISPATCH_PHASE})..."
|
|
266
|
+
|
|
267
|
+
RESULT_FILE="/tmp/gsd-result-$$.json"
|
|
268
|
+
|
|
269
|
+
if [[ "$DISPATCH_PHASE" == "plan" ]]; then
|
|
270
|
+
ALLOWED_TOOLS="Read,Write,Edit,Glob,Grep,Bash(git checkout *),Bash(git branch *)"
|
|
271
|
+
else
|
|
272
|
+
ALLOWED_TOOLS="Read,Write,Edit,Glob,Grep,Bash(npm *),Bash(npx *),Bash(git add *),Bash(git commit *),Bash(node *),Bash(python3 *)"
|
|
273
|
+
fi
|
|
274
|
+
|
|
275
|
+
timeout "$TIMEOUT" claude -p "$(cat "$PROMPT_FILE")" \
|
|
276
|
+
--allowedTools "$ALLOWED_TOOLS" \
|
|
277
|
+
--output-format json --bare \
|
|
278
|
+
--max-turns "$MAX_TURNS" > "$RESULT_FILE" 2>/dev/null || {
|
|
279
|
+
EXIT_CODE=$?
|
|
280
|
+
if [[ $EXIT_CODE -eq 124 ]]; then
|
|
281
|
+
echo "⏰ Timeout after ${TIMEOUT}s on ${SLICE}/${TASK}. Stopping."
|
|
282
|
+
else
|
|
283
|
+
echo "❌ Dispatch failed (exit $EXIT_CODE) on ${SLICE}/${TASK}."
|
|
284
|
+
fi
|
|
285
|
+
log_cost "${SLICE}/${TASK}" "$DISPATCH_PHASE" "$RESULT_FILE"
|
|
286
|
+
break
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
# ── 9. Log costs ──────────────────────────────────────────────────────────
|
|
290
|
+
|
|
291
|
+
log_cost "${SLICE}/${TASK}" "$DISPATCH_PHASE" "$RESULT_FILE"
|
|
292
|
+
|
|
293
|
+
# ── 10. Update state ──────────────────────────────────────────────────────
|
|
294
|
+
|
|
295
|
+
update_state_field "last_updated" "$(date -Iseconds)"
|
|
296
|
+
|
|
297
|
+
# ── 11. Stuck detection ────────────────────────────────────────────────────
|
|
298
|
+
|
|
299
|
+
if [[ "$DISPATCH_PHASE" == "apply" ]]; then
|
|
300
|
+
EXPECTED_SUMMARY="$GSD_DIR/${SLICE}-${TASK}-SUMMARY.md"
|
|
301
|
+
if [[ ! -f "$EXPECTED_SUMMARY" ]]; then
|
|
302
|
+
RETRY_COUNT=$((RETRY_COUNT + 1))
|
|
303
|
+
if [[ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]]; then
|
|
304
|
+
echo "🔄 ${SLICE}/${TASK} stuck after $MAX_RETRIES attempts. Stopping."
|
|
305
|
+
break
|
|
306
|
+
fi
|
|
307
|
+
echo "⚠ Expected $EXPECTED_SUMMARY not found. Retry $RETRY_COUNT/$MAX_RETRIES..."
|
|
308
|
+
continue
|
|
309
|
+
fi
|
|
310
|
+
RETRY_COUNT=0
|
|
311
|
+
fi
|
|
312
|
+
|
|
313
|
+
if [[ "$DISPATCH_PHASE" == "plan" ]]; then
|
|
314
|
+
EXPECTED_PLAN="$GSD_DIR/${SLICE}-PLAN.md"
|
|
315
|
+
if [[ ! -f "$EXPECTED_PLAN" ]]; then
|
|
316
|
+
RETRY_COUNT=$((RETRY_COUNT + 1))
|
|
317
|
+
if [[ "$RETRY_COUNT" -ge "$MAX_RETRIES" ]]; then
|
|
318
|
+
echo "🔄 Planning ${SLICE} stuck after $MAX_RETRIES attempts. Stopping."
|
|
319
|
+
break
|
|
320
|
+
fi
|
|
321
|
+
echo "⚠ Expected $EXPECTED_PLAN not found. Retry $RETRY_COUNT/$MAX_RETRIES..."
|
|
322
|
+
continue
|
|
323
|
+
fi
|
|
324
|
+
RETRY_COUNT=0
|
|
325
|
+
fi
|
|
326
|
+
|
|
327
|
+
# ── 12. Git commit (fallback if task didn't commit) ────────────────────────
|
|
328
|
+
|
|
329
|
+
if ! git diff --quiet HEAD 2>/dev/null || [[ -n "$(git ls-files --others --exclude-standard)" ]]; then
|
|
330
|
+
git add -A
|
|
331
|
+
git commit -m "feat(${SLICE}/${TASK}): auto-mode execution" --no-verify 2>/dev/null || true
|
|
332
|
+
fi
|
|
333
|
+
|
|
334
|
+
# ── 13. Release lock ──────────────────────────────────────────────────────
|
|
335
|
+
|
|
336
|
+
rm -f "$LOCK_FILE"
|
|
337
|
+
|
|
338
|
+
echo "✓ ${SLICE}/${TASK} complete."
|
|
339
|
+
|
|
340
|
+
# ── 14. Rate limiting ─────────────────────────────────────────────────────
|
|
341
|
+
|
|
342
|
+
sleep 2
|
|
343
|
+
|
|
344
|
+
done
|
|
345
|
+
|
|
346
|
+
# ── Cleanup ────────────────────────────────────────────────────────────────────
|
|
347
|
+
|
|
348
|
+
rm -f "$LOCK_FILE"
|
|
349
|
+
echo ""
|
|
350
|
+
echo "Auto-mode finished."
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Quality Gate: Planning Ready
|
|
2
|
+
|
|
3
|
+
Check ALL items before allowing execution to start. If any item fails, fix the plan first.
|
|
4
|
+
|
|
5
|
+
## Acceptance Criteria
|
|
6
|
+
|
|
7
|
+
- [ ] Every task has at least 1 acceptance criterion
|
|
8
|
+
- [ ] Every AC uses Given/When/Then format
|
|
9
|
+
- [ ] Every AC has a unique ID (AC-1, AC-2, ...) within the slice
|
|
10
|
+
- [ ] ACs are testable — there is a concrete way to verify each one
|
|
11
|
+
|
|
12
|
+
## Boundaries
|
|
13
|
+
|
|
14
|
+
- [ ] Every task has a `<boundaries>` section
|
|
15
|
+
- [ ] Boundaries section can be "No boundary restrictions" but must exist
|
|
16
|
+
- [ ] Files created by earlier tasks are listed as DO NOT CHANGE in later tasks that should not modify them
|
|
17
|
+
|
|
18
|
+
## Task Quality
|
|
19
|
+
|
|
20
|
+
- [ ] No "TBD", "TODO", "later", or "tbd" in `<action>` or `<files>` fields
|
|
21
|
+
- [ ] Every `<files>` section lists concrete file paths, not placeholders
|
|
22
|
+
- [ ] Every `<action>` section has numbered, concrete steps
|
|
23
|
+
- [ ] Every `<verify>` references at least one AC by ID
|
|
24
|
+
|
|
25
|
+
## Scope
|
|
26
|
+
|
|
27
|
+
- [ ] Task count per slice: 1-7 (more means the slice should be split)
|
|
28
|
+
- [ ] Each task fits in one context window (~15 files of context + output)
|
|
29
|
+
- [ ] No circular dependencies between tasks
|
|
30
|
+
- [ ] Tasks are ordered by dependency (foundations first)
|
|
31
|
+
|
|
32
|
+
## Completeness
|
|
33
|
+
|
|
34
|
+
- [ ] Slice plan (S{nn}-PLAN.md) has overview, task table, AC table, boundaries summary
|
|
35
|
+
- [ ] Every task has a per-task plan file (S{nn}-T{nn}-PLAN.md)
|
|
36
|
+
- [ ] Git branch created for this slice (gsd/M{n}/S{nn})
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Quality Gate: UNIFY Complete
|
|
2
|
+
|
|
3
|
+
Check ALL items before allowing the next slice to start. If any item fails, complete the UNIFY first.
|
|
4
|
+
|
|
5
|
+
## Plan vs. Actual
|
|
6
|
+
|
|
7
|
+
- [ ] Plan vs. Actual table is present
|
|
8
|
+
- [ ] Every task from the plan is listed (none missing)
|
|
9
|
+
- [ ] Each task has a status: as planned / expanded / partial / skipped
|
|
10
|
+
- [ ] If a task was expanded or skipped, there is a brief explanation
|
|
11
|
+
|
|
12
|
+
## Acceptance Criteria
|
|
13
|
+
|
|
14
|
+
- [ ] AC status table is present
|
|
15
|
+
- [ ] Every AC from the plan is listed with Pass / Partial / Fail
|
|
16
|
+
- [ ] Each AC has an evidence column (test output, manual check, etc.)
|
|
17
|
+
- [ ] No AC is left without a status
|
|
18
|
+
|
|
19
|
+
## Decisions
|
|
20
|
+
|
|
21
|
+
- [ ] Decisions section is present (can be "No additional decisions made.")
|
|
22
|
+
- [ ] Each decision made during execution is listed with rationale
|
|
23
|
+
- [ ] Decisions are appended to .gsd/DECISIONS.md
|
|
24
|
+
|
|
25
|
+
## Boundary Violations
|
|
26
|
+
|
|
27
|
+
- [ ] Boundary violations section is present
|
|
28
|
+
- [ ] "None." if all boundaries were respected
|
|
29
|
+
- [ ] If violations occurred: which file, which task, why
|
|
30
|
+
|
|
31
|
+
## Deferred Issues
|
|
32
|
+
|
|
33
|
+
- [ ] Deferred section is present (can be empty)
|
|
34
|
+
- [ ] Each deferred issue names a target slice or "later"
|
|
35
|
+
- [ ] Deferred items are actionable, not vague
|
|
36
|
+
|
|
37
|
+
## Reassessment
|
|
38
|
+
|
|
39
|
+
- [ ] Reassessment verdict is present
|
|
40
|
+
- [ ] One of: "Roadmap still valid." or "Roadmap needs update: {reason}"
|
|
41
|
+
- [ ] If roadmap needs update, specific changes are described
|
|
File without changes
|