claude-symphony 0.0.5 → 0.0.6
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/bin/create.js +120 -3
- package/package.json +3 -2
- package/template/.claude/settings.json +0 -2
- package/template/.claude/skills/context-compression/README.md +39 -0
- package/template/CLAUDE.md +64 -1
- package/template/config/ai_fallbacks.yaml +130 -0
- package/template/config/implementation.yaml.template +72 -72
- package/template/config/pipeline.yaml +50 -0
- package/template/config/ui-ux.yaml +31 -0
- package/template/scripts/config-manager.sh +350 -0
- package/template/scripts/context-manager.sh +55 -4
- package/template/scripts/goto-stage.sh +264 -0
- package/template/scripts/next-stage.sh +132 -0
- package/template/stages/01-brainstorm/HANDOFF.md.template +42 -42
- package/template/stages/02-research/HANDOFF.md.template +42 -42
- package/template/stages/03-planning/HANDOFF.md.template +39 -39
- package/template/stages/04-ui-ux/CLAUDE.md +40 -0
- package/template/stages/04-ui-ux/HANDOFF.md.template +38 -38
- package/template/stages/04-ui-ux/inputs/moodboard/brand-assets/.gitkeep +3 -0
- package/template/stages/04-ui-ux/inputs/moodboard/sketches/.gitkeep +3 -0
- package/template/stages/04-ui-ux/inputs/moodboard/ui-references/.gitkeep +3 -0
- package/template/stages/05-task-management/HANDOFF.md.template +38 -38
- package/template/stages/06-implementation/CLAUDE.md +39 -0
- package/template/stages/06-implementation/HANDOFF.md.template +76 -76
- package/template/stages/06-implementation/config.yaml +16 -0
- package/template/stages/07-refactoring/HANDOFF.md.template +42 -42
- package/template/stages/08-qa/HANDOFF.md.template +45 -45
- package/template/stages/09-testing/HANDOFF.md.template +46 -46
- package/template/stages/10-deployment/HANDOFF.md.template +60 -60
- package/template/state/progress.json.template +26 -0
- package/template/state/templates/handoff_base.md.template +57 -57
- package/template/state/templates/phase_state.md.template +35 -35
|
@@ -63,11 +63,62 @@ get_current_stage() {
|
|
|
63
63
|
fi
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
# Estimate tokens (
|
|
66
|
+
# Estimate tokens (content-based estimation)
|
|
67
|
+
# Token estimation rules:
|
|
68
|
+
# - English: word count × 1.3
|
|
69
|
+
# - Korean: character count × 0.5
|
|
70
|
+
# - Code: line count × 10
|
|
67
71
|
estimate_tokens() {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
local total_tokens=0
|
|
73
|
+
local current_stage=$(get_current_stage)
|
|
74
|
+
|
|
75
|
+
# Scan stage outputs for token estimation
|
|
76
|
+
local stage_dir="$PROJECT_ROOT/stages/$current_stage/outputs"
|
|
77
|
+
if [ -d "$stage_dir" ]; then
|
|
78
|
+
for file in "$stage_dir"/*.md "$stage_dir"/*.txt 2>/dev/null; do
|
|
79
|
+
[ -f "$file" ] || continue
|
|
80
|
+
|
|
81
|
+
local content=$(cat "$file")
|
|
82
|
+
|
|
83
|
+
# Count English words (ASCII alphanumeric sequences)
|
|
84
|
+
local english_words=$(echo "$content" | grep -oE '[a-zA-Z]+' | wc -w | tr -d ' ')
|
|
85
|
+
|
|
86
|
+
# Count Korean characters (Hangul range: AC00-D7AF)
|
|
87
|
+
local korean_chars=$(echo "$content" | grep -oE '[\xEA-\xED][\x80-\xBF][\x80-\xBF]' 2>/dev/null | wc -c | tr -d ' ')
|
|
88
|
+
korean_chars=$((korean_chars / 3)) # UTF-8 Korean chars are 3 bytes
|
|
89
|
+
|
|
90
|
+
# Calculate tokens for this file
|
|
91
|
+
local file_tokens=$(( (english_words * 13 / 10) + (korean_chars / 2) ))
|
|
92
|
+
total_tokens=$((total_tokens + file_tokens))
|
|
93
|
+
done
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Scan code files
|
|
97
|
+
local project_src="$PROJECT_ROOT/src"
|
|
98
|
+
if [ -d "$project_src" ]; then
|
|
99
|
+
local code_lines=$(find "$project_src" -type f \( -name "*.js" -o -name "*.ts" -o -name "*.tsx" -o -name "*.py" -o -name "*.go" \) -exec wc -l {} + 2>/dev/null | tail -1 | awk '{print $1}')
|
|
100
|
+
if [ -n "$code_lines" ] && [ "$code_lines" -gt 0 ]; then
|
|
101
|
+
total_tokens=$((total_tokens + code_lines * 10))
|
|
102
|
+
fi
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# Scan HANDOFF files
|
|
106
|
+
for handoff in "$PROJECT_ROOT"/stages/*/HANDOFF.md 2>/dev/null; do
|
|
107
|
+
[ -f "$handoff" ] || continue
|
|
108
|
+
local handoff_words=$(wc -w < "$handoff" 2>/dev/null | tr -d ' ')
|
|
109
|
+
total_tokens=$((total_tokens + handoff_words * 13 / 10))
|
|
110
|
+
done
|
|
111
|
+
|
|
112
|
+
# Add base context overhead (conversation history estimate)
|
|
113
|
+
local base_overhead=10000
|
|
114
|
+
total_tokens=$((total_tokens + base_overhead))
|
|
115
|
+
|
|
116
|
+
# Minimum floor for realistic estimation
|
|
117
|
+
if [ "$total_tokens" -lt 15000 ]; then
|
|
118
|
+
total_tokens=15000
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
echo "$total_tokens"
|
|
71
122
|
}
|
|
72
123
|
|
|
73
124
|
# Generate progress bar
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# goto-stage.sh - Jump to previous stage (loop-back)
|
|
3
|
+
# claude-symphony workflow pipeline
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
8
|
+
PROGRESS_FILE="$PROJECT_ROOT/state/progress.json"
|
|
9
|
+
STAGES_DIR="$PROJECT_ROOT/stages"
|
|
10
|
+
CONFIG_FILE="$PROJECT_ROOT/config/pipeline.yaml"
|
|
11
|
+
|
|
12
|
+
# Color definitions
|
|
13
|
+
RED='\033[0;31m'
|
|
14
|
+
GREEN='\033[0;32m'
|
|
15
|
+
YELLOW='\033[1;33m'
|
|
16
|
+
BLUE='\033[0;34m'
|
|
17
|
+
CYAN='\033[0;36m'
|
|
18
|
+
WHITE='\033[1;37m'
|
|
19
|
+
GRAY='\033[0;90m'
|
|
20
|
+
NC='\033[0m' # No Color
|
|
21
|
+
|
|
22
|
+
# Stage info
|
|
23
|
+
declare -a STAGE_IDS=("01-brainstorm" "02-research" "03-planning" "04-ui-ux" "05-task-management" "06-implementation" "07-refactoring" "08-qa" "09-testing" "10-deployment")
|
|
24
|
+
|
|
25
|
+
# Option handling
|
|
26
|
+
TARGET_STAGE=""
|
|
27
|
+
LIST_MODE=false
|
|
28
|
+
HISTORY_MODE=false
|
|
29
|
+
REASON=""
|
|
30
|
+
|
|
31
|
+
print_usage() {
|
|
32
|
+
echo "Usage: goto-stage.sh <stage-id> [--reason \"reason\"]"
|
|
33
|
+
echo " goto-stage.sh --list"
|
|
34
|
+
echo " goto-stage.sh --history"
|
|
35
|
+
echo ""
|
|
36
|
+
echo "Options:"
|
|
37
|
+
echo " <stage-id> Target stage to jump to (e.g., 06-implementation)"
|
|
38
|
+
echo " --reason \"text\" Reason for loop-back (required)"
|
|
39
|
+
echo " --list Show available stages for loop-back"
|
|
40
|
+
echo " --history Show loop-back history"
|
|
41
|
+
echo ""
|
|
42
|
+
echo "Examples:"
|
|
43
|
+
echo " ./goto-stage.sh 06-implementation --reason \"BUG-002 fix required\""
|
|
44
|
+
echo " ./goto-stage.sh --list"
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
while [[ "$#" -gt 0 ]]; do
|
|
48
|
+
case $1 in
|
|
49
|
+
--list) LIST_MODE=true ;;
|
|
50
|
+
--history) HISTORY_MODE=true ;;
|
|
51
|
+
--reason) REASON="$2"; shift ;;
|
|
52
|
+
--help|-h) print_usage; exit 0 ;;
|
|
53
|
+
*)
|
|
54
|
+
if [[ -z "$TARGET_STAGE" ]]; then
|
|
55
|
+
TARGET_STAGE="$1"
|
|
56
|
+
fi
|
|
57
|
+
;;
|
|
58
|
+
esac
|
|
59
|
+
shift
|
|
60
|
+
done
|
|
61
|
+
|
|
62
|
+
# Check jq
|
|
63
|
+
if ! command -v jq &> /dev/null; then
|
|
64
|
+
echo -e "${RED}Error:${NC} jq is required."
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# Check progress.json
|
|
69
|
+
if [ ! -f "$PROGRESS_FILE" ]; then
|
|
70
|
+
echo -e "${RED}Error:${NC} Cannot find progress.json."
|
|
71
|
+
exit 1
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# Get current stage
|
|
75
|
+
CURRENT_STAGE=$(jq -r '.current_stage // "none"' "$PROGRESS_FILE")
|
|
76
|
+
|
|
77
|
+
if [ "$CURRENT_STAGE" == "none" ] || [ -z "$CURRENT_STAGE" ]; then
|
|
78
|
+
echo -e "${RED}Error:${NC} No stage in progress."
|
|
79
|
+
exit 1
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
# Find current stage index
|
|
83
|
+
get_stage_index() {
|
|
84
|
+
local STAGE_ID=$1
|
|
85
|
+
for i in "${!STAGE_IDS[@]}"; do
|
|
86
|
+
if [ "${STAGE_IDS[$i]}" == "$STAGE_ID" ]; then
|
|
87
|
+
echo "$i"
|
|
88
|
+
return
|
|
89
|
+
fi
|
|
90
|
+
done
|
|
91
|
+
echo "-1"
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
CURRENT_IDX=$(get_stage_index "$CURRENT_STAGE")
|
|
95
|
+
|
|
96
|
+
# Handle --list
|
|
97
|
+
if [ "$LIST_MODE" = true ]; then
|
|
98
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
99
|
+
echo -e "📋 ${WHITE}Available Loop-back Targets${NC}"
|
|
100
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
101
|
+
echo -e "Current stage: ${CYAN}$CURRENT_STAGE${NC}"
|
|
102
|
+
echo ""
|
|
103
|
+
echo "Available targets (max 3 stages back):"
|
|
104
|
+
|
|
105
|
+
# Check max_stages_back from config (default 3)
|
|
106
|
+
MAX_BACK=3
|
|
107
|
+
if command -v yq &> /dev/null && [ -f "$CONFIG_FILE" ]; then
|
|
108
|
+
MAX_BACK=$(yq '.sprint_mode.loop_back.max_stages_back // 3' "$CONFIG_FILE" 2>/dev/null)
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
for ((i = CURRENT_IDX - 1; i >= 0 && i >= CURRENT_IDX - MAX_BACK; i--)); do
|
|
112
|
+
STAGE_STATUS=$(jq -r ".stages[\"${STAGE_IDS[$i]}\"].status // \"pending\"" "$PROGRESS_FILE")
|
|
113
|
+
if [ "$STAGE_STATUS" == "completed" ]; then
|
|
114
|
+
echo -e " ${GREEN}✓${NC} ${STAGE_IDS[$i]}"
|
|
115
|
+
fi
|
|
116
|
+
done
|
|
117
|
+
|
|
118
|
+
echo ""
|
|
119
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
120
|
+
exit 0
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
# Handle --history
|
|
124
|
+
if [ "$HISTORY_MODE" = true ]; then
|
|
125
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
126
|
+
echo -e "📜 ${WHITE}Loop-back History${NC}"
|
|
127
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
128
|
+
|
|
129
|
+
HISTORY_COUNT=$(jq '.loop_back_history | length' "$PROGRESS_FILE" 2>/dev/null || echo "0")
|
|
130
|
+
|
|
131
|
+
if [ "$HISTORY_COUNT" == "0" ]; then
|
|
132
|
+
echo "No loop-back history found."
|
|
133
|
+
else
|
|
134
|
+
jq -r '.loop_back_history[] | "[\(.timestamp)] \(.from_stage) → \(.to_stage): \(.reason)"' "$PROGRESS_FILE" 2>/dev/null
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
138
|
+
exit 0
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# Validate target stage
|
|
142
|
+
if [ -z "$TARGET_STAGE" ]; then
|
|
143
|
+
echo -e "${RED}Error:${NC} Target stage is required."
|
|
144
|
+
print_usage
|
|
145
|
+
exit 1
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
# Find target stage index
|
|
149
|
+
TARGET_IDX=$(get_stage_index "$TARGET_STAGE")
|
|
150
|
+
|
|
151
|
+
if [ "$TARGET_IDX" == "-1" ]; then
|
|
152
|
+
echo -e "${RED}Error:${NC} Unknown stage: $TARGET_STAGE"
|
|
153
|
+
exit 1
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
# Validate loop-back (must go backwards)
|
|
157
|
+
if [ "$TARGET_IDX" -ge "$CURRENT_IDX" ]; then
|
|
158
|
+
echo -e "${RED}Error:${NC} Can only loop back to previous stages."
|
|
159
|
+
echo " Current: $CURRENT_STAGE (index $CURRENT_IDX)"
|
|
160
|
+
echo " Target: $TARGET_STAGE (index $TARGET_IDX)"
|
|
161
|
+
exit 1
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
# Check max stages back
|
|
165
|
+
MAX_BACK=3
|
|
166
|
+
if command -v yq &> /dev/null && [ -f "$CONFIG_FILE" ]; then
|
|
167
|
+
MAX_BACK=$(yq '.sprint_mode.loop_back.max_stages_back // 3' "$CONFIG_FILE" 2>/dev/null)
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
STAGES_BACK=$((CURRENT_IDX - TARGET_IDX))
|
|
171
|
+
if [ "$STAGES_BACK" -gt "$MAX_BACK" ]; then
|
|
172
|
+
echo -e "${RED}Error:${NC} Cannot loop back more than $MAX_BACK stages."
|
|
173
|
+
echo " Attempted: $STAGES_BACK stages back"
|
|
174
|
+
exit 1
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
# Require reason
|
|
178
|
+
if [ -z "$REASON" ]; then
|
|
179
|
+
echo -e "${RED}Error:${NC} Reason is required for loop-back."
|
|
180
|
+
echo " Use: --reason \"your reason\""
|
|
181
|
+
exit 1
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
# Execute loop-back
|
|
185
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
186
|
+
echo -e "🔙 ${WHITE}Stage Loop-back${NC}"
|
|
187
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
188
|
+
echo -e "$CURRENT_STAGE → $TARGET_STAGE"
|
|
189
|
+
echo ""
|
|
190
|
+
|
|
191
|
+
# 1. Create checkpoint
|
|
192
|
+
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
193
|
+
CHECKPOINT_ID="checkpoint_loopback_${TIMESTAMP}"
|
|
194
|
+
CHECKPOINT_DIR="$PROJECT_ROOT/state/checkpoints/$CHECKPOINT_ID"
|
|
195
|
+
|
|
196
|
+
mkdir -p "$CHECKPOINT_DIR"
|
|
197
|
+
echo -e "${GREEN}✓${NC} Checkpoint: $CHECKPOINT_ID"
|
|
198
|
+
|
|
199
|
+
# 2. Record loop-back in progress.json
|
|
200
|
+
LOOP_BACK_ENTRY=$(cat << EOF
|
|
201
|
+
{
|
|
202
|
+
"timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
|
|
203
|
+
"from_stage": "$CURRENT_STAGE",
|
|
204
|
+
"to_stage": "$TARGET_STAGE",
|
|
205
|
+
"reason": "$REASON",
|
|
206
|
+
"checkpoint_id": "$CHECKPOINT_ID"
|
|
207
|
+
}
|
|
208
|
+
EOF
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
jq ".loop_back_history += [$LOOP_BACK_ENTRY]" "$PROGRESS_FILE" > "${PROGRESS_FILE}.tmp" \
|
|
212
|
+
&& mv "${PROGRESS_FILE}.tmp" "$PROGRESS_FILE"
|
|
213
|
+
echo -e "${GREEN}✓${NC} Reason: $REASON"
|
|
214
|
+
|
|
215
|
+
# 3. Generate loop-back HANDOFF
|
|
216
|
+
HANDOFF_FILE="$STAGES_DIR/$CURRENT_STAGE/LOOPBACK_HANDOFF.md"
|
|
217
|
+
cat > "$HANDOFF_FILE" << EOF
|
|
218
|
+
# Loop-back Handoff: $CURRENT_STAGE → $TARGET_STAGE
|
|
219
|
+
|
|
220
|
+
Created: $(date "+%Y-%m-%d %H:%M")
|
|
221
|
+
|
|
222
|
+
## Reason
|
|
223
|
+
|
|
224
|
+
$REASON
|
|
225
|
+
|
|
226
|
+
## Context
|
|
227
|
+
|
|
228
|
+
This is an intentional loop-back to address issues discovered during $CURRENT_STAGE.
|
|
229
|
+
|
|
230
|
+
## Checkpoint
|
|
231
|
+
|
|
232
|
+
- ID: $CHECKPOINT_ID
|
|
233
|
+
- Location: state/checkpoints/$CHECKPOINT_ID
|
|
234
|
+
|
|
235
|
+
## Instructions
|
|
236
|
+
|
|
237
|
+
1. Review the reason for loop-back
|
|
238
|
+
2. Address the issues in $TARGET_STAGE
|
|
239
|
+
3. Return to $CURRENT_STAGE after resolution
|
|
240
|
+
4. Reference this file for context
|
|
241
|
+
|
|
242
|
+
## Previous Stage Status
|
|
243
|
+
|
|
244
|
+
- Stage: $CURRENT_STAGE
|
|
245
|
+
- Status at loop-back: in_progress
|
|
246
|
+
EOF
|
|
247
|
+
|
|
248
|
+
# Copy to handoffs archive
|
|
249
|
+
cp "$HANDOFF_FILE" "$PROJECT_ROOT/state/handoffs/loopback_${TIMESTAMP}_handoff.md"
|
|
250
|
+
|
|
251
|
+
# 4. Update progress.json - change stages
|
|
252
|
+
jq ".current_stage = \"$TARGET_STAGE\" | \
|
|
253
|
+
.stages[\"$TARGET_STAGE\"].status = \"in_progress\" | \
|
|
254
|
+
.stages[\"$TARGET_STAGE\"].started_at = \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\"" \
|
|
255
|
+
"$PROGRESS_FILE" > "${PROGRESS_FILE}.tmp" && mv "${PROGRESS_FILE}.tmp" "$PROGRESS_FILE"
|
|
256
|
+
|
|
257
|
+
echo ""
|
|
258
|
+
echo -e "${GREEN}✅${NC} Moved to ${WHITE}$TARGET_STAGE${NC}!"
|
|
259
|
+
echo ""
|
|
260
|
+
echo "Next steps:"
|
|
261
|
+
echo " 1. Reference stages/$TARGET_STAGE/CLAUDE.md"
|
|
262
|
+
echo " 2. Address: $REASON"
|
|
263
|
+
echo " 3. Use /next to proceed after resolution"
|
|
264
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
@@ -22,17 +22,142 @@ NC='\033[0m' # No Color
|
|
|
22
22
|
FORCE_MODE=false
|
|
23
23
|
PREVIEW_MODE=false
|
|
24
24
|
NO_HANDOFF=false
|
|
25
|
+
STAGE_FORCE=false
|
|
25
26
|
|
|
26
27
|
while [[ "$#" -gt 0 ]]; do
|
|
27
28
|
case $1 in
|
|
28
29
|
--force) FORCE_MODE=true ;;
|
|
29
30
|
--preview) PREVIEW_MODE=true ;;
|
|
30
31
|
--no-handoff) NO_HANDOFF=true ;;
|
|
32
|
+
--stage) STAGE_FORCE=true ;;
|
|
31
33
|
*) ;;
|
|
32
34
|
esac
|
|
33
35
|
shift
|
|
34
36
|
done
|
|
35
37
|
|
|
38
|
+
# Check for yq (YAML parser)
|
|
39
|
+
check_yq() {
|
|
40
|
+
if command -v yq &> /dev/null; then
|
|
41
|
+
return 0
|
|
42
|
+
fi
|
|
43
|
+
return 1
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# Sprint-aware transition logic
|
|
47
|
+
handle_sprint_transition() {
|
|
48
|
+
local CONFIG_FILE="$PROJECT_ROOT/config/pipeline.yaml"
|
|
49
|
+
|
|
50
|
+
# Check if yq is available
|
|
51
|
+
if ! check_yq; then
|
|
52
|
+
return 1 # Proceed with stage transition
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# Check if sprint mode is enabled
|
|
56
|
+
local SPRINT_ENABLED=$(yq '.sprint_mode.enabled // false' "$CONFIG_FILE" 2>/dev/null)
|
|
57
|
+
if [ "$SPRINT_ENABLED" != "true" ]; then
|
|
58
|
+
return 1 # Proceed with stage transition
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Check if current stage is iterative
|
|
62
|
+
local STAGE_ITERATIVE=$(yq ".sprint_mode.stage_iterations[\"$CURRENT_STAGE\"].iterative // false" "$CONFIG_FILE" 2>/dev/null)
|
|
63
|
+
if [ "$STAGE_ITERATIVE" != "true" ]; then
|
|
64
|
+
return 1 # Proceed with stage transition
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# Get current sprint info
|
|
68
|
+
local CURRENT_SPRINT=$(jq -r '.current_iteration.current_sprint // 1' "$PROGRESS_FILE")
|
|
69
|
+
local TOTAL_SPRINTS=$(jq -r '.current_iteration.total_sprints // 3' "$PROGRESS_FILE")
|
|
70
|
+
|
|
71
|
+
if [ "$CURRENT_SPRINT" -lt "$TOTAL_SPRINTS" ]; then
|
|
72
|
+
# Sprint transition
|
|
73
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
74
|
+
echo -e "🔄 ${WHITE}Sprint Transition${NC}"
|
|
75
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
76
|
+
echo -e "Sprint $CURRENT_SPRINT → Sprint $((CURRENT_SPRINT + 1))"
|
|
77
|
+
echo ""
|
|
78
|
+
|
|
79
|
+
# Generate Sprint HANDOFF
|
|
80
|
+
generate_sprint_handoff "$CURRENT_SPRINT"
|
|
81
|
+
|
|
82
|
+
# Create Sprint checkpoint
|
|
83
|
+
create_sprint_checkpoint "$CURRENT_SPRINT"
|
|
84
|
+
|
|
85
|
+
# Advance sprint
|
|
86
|
+
advance_sprint "$CURRENT_SPRINT"
|
|
87
|
+
|
|
88
|
+
echo ""
|
|
89
|
+
echo -e "${GREEN}✅${NC} Sprint $((CURRENT_SPRINT + 1)) started!"
|
|
90
|
+
echo "Remaining Sprints: $((TOTAL_SPRINTS - CURRENT_SPRINT - 1))"
|
|
91
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
92
|
+
|
|
93
|
+
return 0 # Sprint transition completed
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
return 1 # All sprints complete, proceed with stage transition
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# Generate Sprint HANDOFF
|
|
100
|
+
generate_sprint_handoff() {
|
|
101
|
+
local SPRINT_NUM=$1
|
|
102
|
+
local HANDOFF_FILE="$STAGES_DIR/$CURRENT_STAGE/outputs/SPRINT_HANDOFF_${SPRINT_NUM}.md"
|
|
103
|
+
local TIMESTAMP=$(date "+%Y-%m-%d %H:%M")
|
|
104
|
+
|
|
105
|
+
mkdir -p "$STAGES_DIR/$CURRENT_STAGE/outputs"
|
|
106
|
+
|
|
107
|
+
cat > "$HANDOFF_FILE" << EOF
|
|
108
|
+
# Sprint Handoff: Sprint $SPRINT_NUM → Sprint $((SPRINT_NUM + 1))
|
|
109
|
+
|
|
110
|
+
Created: $TIMESTAMP
|
|
111
|
+
|
|
112
|
+
## Completed Tasks (Sprint $SPRINT_NUM)
|
|
113
|
+
|
|
114
|
+
$(jq -r ".sprints[\"Sprint $SPRINT_NUM\"].completed_tasks // [] | .[]" "$PROGRESS_FILE" 2>/dev/null | while read -r task; do echo "- [x] $task"; done)
|
|
115
|
+
|
|
116
|
+
## Sprint Summary
|
|
117
|
+
|
|
118
|
+
- Tasks completed: $(jq -r ".sprints[\"Sprint $SPRINT_NUM\"].tasks_completed // 0" "$PROGRESS_FILE")
|
|
119
|
+
- Test results: lint ✓, typecheck ✓
|
|
120
|
+
- Checkpoint: sprint_${SPRINT_NUM}_$(date +%Y%m%d)
|
|
121
|
+
|
|
122
|
+
## Next Sprint Focus
|
|
123
|
+
|
|
124
|
+
- Reference Sprint $((SPRINT_NUM + 1)) tasks in sprint_plan.md
|
|
125
|
+
|
|
126
|
+
EOF
|
|
127
|
+
|
|
128
|
+
# Archive copy
|
|
129
|
+
mkdir -p "$PROJECT_ROOT/state/handoffs"
|
|
130
|
+
cp "$HANDOFF_FILE" "$PROJECT_ROOT/state/handoffs/sprint_${SPRINT_NUM}_handoff.md"
|
|
131
|
+
|
|
132
|
+
echo -e "${GREEN}✓${NC} SPRINT_HANDOFF_${SPRINT_NUM}.md generated"
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# Create Sprint checkpoint
|
|
136
|
+
create_sprint_checkpoint() {
|
|
137
|
+
local SPRINT_NUM=$1
|
|
138
|
+
local CHECKPOINT_DIR="$PROJECT_ROOT/state/checkpoints"
|
|
139
|
+
local CHECKPOINT_ID="sprint_${SPRINT_NUM}_$(date +%Y%m%d_%H%M%S)"
|
|
140
|
+
|
|
141
|
+
mkdir -p "$CHECKPOINT_DIR/$CHECKPOINT_ID"
|
|
142
|
+
|
|
143
|
+
# Update progress.json with checkpoint
|
|
144
|
+
jq ".sprints[\"Sprint $SPRINT_NUM\"].checkpoint_id = \"$CHECKPOINT_ID\"" \
|
|
145
|
+
"$PROGRESS_FILE" > "${PROGRESS_FILE}.tmp" && mv "${PROGRESS_FILE}.tmp" "$PROGRESS_FILE"
|
|
146
|
+
|
|
147
|
+
echo -e "${GREEN}✓${NC} Checkpoint: $CHECKPOINT_ID"
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
# Advance sprint counter
|
|
151
|
+
advance_sprint() {
|
|
152
|
+
local CURRENT=$1
|
|
153
|
+
local NEXT=$((CURRENT + 1))
|
|
154
|
+
|
|
155
|
+
jq ".current_iteration.current_sprint = $NEXT | \
|
|
156
|
+
.sprints[\"Sprint $CURRENT\"].status = \"completed\" | \
|
|
157
|
+
.sprints[\"Sprint $NEXT\"].status = \"in_progress\"" \
|
|
158
|
+
"$PROGRESS_FILE" > "${PROGRESS_FILE}.tmp" && mv "${PROGRESS_FILE}.tmp" "$PROGRESS_FILE"
|
|
159
|
+
}
|
|
160
|
+
|
|
36
161
|
# Check jq
|
|
37
162
|
if ! command -v jq &> /dev/null; then
|
|
38
163
|
echo -e "${RED}Error:${NC} jq is required."
|
|
@@ -92,6 +217,13 @@ NEXT_STAGE="${STAGE_IDS[$NEXT_IDX]}"
|
|
|
92
217
|
CURRENT_STAGE_DIR="$STAGES_DIR/$CURRENT_STAGE"
|
|
93
218
|
NEXT_STAGE_DIR="$STAGES_DIR/$NEXT_STAGE"
|
|
94
219
|
|
|
220
|
+
# Check for sprint transition (unless --stage flag is used)
|
|
221
|
+
if [ "$STAGE_FORCE" = false ]; then
|
|
222
|
+
if handle_sprint_transition; then
|
|
223
|
+
exit 0 # Sprint transition completed, exit
|
|
224
|
+
fi
|
|
225
|
+
fi
|
|
226
|
+
|
|
95
227
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
96
228
|
echo -e "🔄 ${WHITE}Stage Transition${NC}"
|
|
97
229
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
@@ -1,102 +1,102 @@
|
|
|
1
1
|
# Stage Handoff: 01-brainstorm → 02-research
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
**Created**: {{TIMESTAMP}}
|
|
4
|
+
**Creator**: {{MODEL}}
|
|
5
|
+
**Duration**: {{DURATION}}
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Completed Tasks
|
|
10
10
|
|
|
11
|
-
- [ ]
|
|
12
|
-
- [ ]
|
|
13
|
-
- [ ]
|
|
14
|
-
- [ ]
|
|
15
|
-
- [ ] MVP
|
|
16
|
-
- [ ] HANDOFF.md
|
|
11
|
+
- [ ] Project brief analysis
|
|
12
|
+
- [ ] Brainstorming ({{IDEA_COUNT}} ideas)
|
|
13
|
+
- [ ] User persona creation ({{PERSONA_COUNT}} personas)
|
|
14
|
+
- [ ] Requirements analysis
|
|
15
|
+
- [ ] MVP scope definition
|
|
16
|
+
- [ ] HANDOFF.md generation
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
##
|
|
20
|
+
## Context for Next Agent
|
|
21
21
|
|
|
22
|
-
###
|
|
22
|
+
### Key Decisions
|
|
23
23
|
|
|
24
|
-
|
|
|
25
|
-
|
|
24
|
+
| Decision | Rationale | Reversible |
|
|
25
|
+
|----------|-----------|------------|
|
|
26
26
|
| {{DECISION_1}} | {{REASON_1}} | Yes/No |
|
|
27
27
|
| {{DECISION_2}} | {{REASON_2}} | Yes/No |
|
|
28
28
|
|
|
29
|
-
###
|
|
29
|
+
### Successful Approaches
|
|
30
30
|
- {{SUCCESSFUL_APPROACH_1}}
|
|
31
31
|
- {{SUCCESSFUL_APPROACH_2}}
|
|
32
32
|
|
|
33
|
-
###
|
|
33
|
+
### Failed Approaches
|
|
34
34
|
- {{FAILED_APPROACH_1}}: {{FAILURE_REASON_1}}
|
|
35
35
|
|
|
36
|
-
###
|
|
36
|
+
### Priority Ideas (Top 5)
|
|
37
37
|
1. **{{IDEA_1}}** - {{IDEA_1_VALUE}}
|
|
38
38
|
2. **{{IDEA_2}}** - {{IDEA_2_VALUE}}
|
|
39
39
|
3. **{{IDEA_3}}** - {{IDEA_3_VALUE}}
|
|
40
40
|
4. **{{IDEA_4}}** - {{IDEA_4_VALUE}}
|
|
41
41
|
5. **{{IDEA_5}}** - {{IDEA_5_VALUE}}
|
|
42
42
|
|
|
43
|
-
### MVP
|
|
43
|
+
### MVP Core Features
|
|
44
44
|
1. {{MVP_FEATURE_1}}
|
|
45
45
|
2. {{MVP_FEATURE_2}}
|
|
46
46
|
3. {{MVP_FEATURE_3}}
|
|
47
47
|
|
|
48
48
|
---
|
|
49
49
|
|
|
50
|
-
##
|
|
50
|
+
## Generated Outputs
|
|
51
51
|
|
|
52
|
-
|
|
|
53
|
-
|
|
54
|
-
| ideas.md |
|
|
55
|
-
| requirements_analysis.md |
|
|
56
|
-
| personas.md |
|
|
52
|
+
| File | Description | Location |
|
|
53
|
+
|------|-------------|----------|
|
|
54
|
+
| ideas.md | Brainstorming ideas | `outputs/ideas.md` |
|
|
55
|
+
| requirements_analysis.md | Requirements analysis | `outputs/requirements_analysis.md` |
|
|
56
|
+
| personas.md | User personas | `outputs/personas.md` (optional) |
|
|
57
57
|
|
|
58
58
|
---
|
|
59
59
|
|
|
60
|
-
## 02-research
|
|
60
|
+
## 02-research Stage Guide
|
|
61
61
|
|
|
62
|
-
###
|
|
63
|
-
1. `outputs/requirements_analysis.md`
|
|
64
|
-
2.
|
|
65
|
-
3.
|
|
62
|
+
### Immediate Tasks
|
|
63
|
+
1. Read `outputs/requirements_analysis.md` and verify MVP scope
|
|
64
|
+
2. Research tech stack for priority ideas
|
|
65
|
+
3. In-depth competitor analysis
|
|
66
66
|
|
|
67
|
-
###
|
|
67
|
+
### Research Priorities
|
|
68
68
|
1. {{RESEARCH_PRIORITY_1}}
|
|
69
69
|
2. {{RESEARCH_PRIORITY_2}}
|
|
70
70
|
3. {{RESEARCH_PRIORITY_3}}
|
|
71
71
|
|
|
72
|
-
###
|
|
72
|
+
### Assumptions to Validate
|
|
73
73
|
- {{ASSUMPTION_1}}
|
|
74
74
|
- {{ASSUMPTION_2}}
|
|
75
75
|
|
|
76
|
-
###
|
|
77
|
-
- `firecrawl`:
|
|
78
|
-
- `exa`: AI
|
|
79
|
-
- `context7`:
|
|
76
|
+
### Recommended MCP Servers
|
|
77
|
+
- `firecrawl`: Web crawling
|
|
78
|
+
- `exa`: AI search
|
|
79
|
+
- `context7`: Documentation search
|
|
80
80
|
|
|
81
81
|
---
|
|
82
82
|
|
|
83
|
-
##
|
|
84
|
-
>
|
|
83
|
+
## Checkpoint Reference
|
|
84
|
+
> Checkpoints are not required for this stage.
|
|
85
85
|
|
|
86
86
|
---
|
|
87
87
|
|
|
88
|
-
## AI
|
|
88
|
+
## AI Call Log
|
|
89
89
|
|
|
90
|
-
| AI |
|
|
91
|
-
|
|
90
|
+
| AI | Call Time | Prompt | Result | Status |
|
|
91
|
+
|----|-----------|--------|--------|--------|
|
|
92
92
|
| {{AI_1}} | {{TIME_1}} | {{PROMPT_1}} | {{OUTPUT_1}} | {{STATUS_1}} |
|
|
93
93
|
| {{AI_2}} | {{TIME_2}} | {{PROMPT_2}} | {{OUTPUT_2}} | {{STATUS_2}} |
|
|
94
94
|
|
|
95
|
-
>
|
|
95
|
+
> Configuration: `config/ai_logging.yaml`
|
|
96
96
|
|
|
97
97
|
---
|
|
98
98
|
|
|
99
|
-
##
|
|
99
|
+
## Metadata
|
|
100
100
|
|
|
101
101
|
```yaml
|
|
102
102
|
stage: "01-brainstorm"
|