cc-devflow 4.1.2 → 4.1.4
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/.claude/CLAUDE.md +3 -2
- package/.claude/commands/flow/dev.md +1 -1
- package/.claude/commands/flow/init.md +16 -1
- package/.claude/commands/flow/quality.md +5 -0
- package/.claude/commands/flow/release.md +33 -9
- package/.claude/commands/flow/restart.md +1 -1
- package/.claude/commands/flow/status.md +2 -2
- package/.claude/commands/flow/update.md +1 -1
- package/.claude/commands/flow/workspace.md +30 -4
- package/.claude/scripts/CLAUDE.md +79 -0
- package/.claude/scripts/create-requirement.sh +12 -0
- package/.claude/scripts/flow-quality-full.sh +32 -1
- package/.claude/scripts/flow-quality-quick.sh +57 -2
- package/.claude/scripts/flow-workspace-start.sh +135 -6
- package/.claude/scripts/flow-workspace-switch.sh +234 -0
- package/.claude/scripts/generate-status-report.sh +5 -5
- package/.claude/scripts/recover-workflow.sh +24 -24
- package/.claude/skills/workflow/flow-init/SKILL.md +8 -1
- package/.claude/skills/workflow/flow-quality/SKILL.md +4 -0
- package/.claude/skills/workflow/flow-release/SKILL.md +18 -5
- package/CHANGELOG.md +66 -0
- package/lib/compiler/__tests__/compile-regression.test.js +9 -0
- package/lib/compiler/__tests__/multi-module-emitters.test.js +37 -11
- package/lib/compiler/emitters/antigravity-emitter.js +22 -3
- package/lib/compiler/emitters/base-emitter.js +78 -0
- package/lib/compiler/emitters/codex-emitter.js +37 -34
- package/package.json +1 -1
|
@@ -13,12 +13,90 @@ set -e
|
|
|
13
13
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
14
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
15
15
|
WORKSPACE_DIR="$PROJECT_ROOT/devflow/workspace"
|
|
16
|
+
COMMON_SH="$SCRIPT_DIR/common.sh"
|
|
17
|
+
|
|
18
|
+
if [[ -f "$COMMON_SH" ]]; then
|
|
19
|
+
source "$COMMON_SH"
|
|
20
|
+
fi
|
|
16
21
|
|
|
17
22
|
# ============================================================================
|
|
18
|
-
#
|
|
23
|
+
# Parse Arguments
|
|
19
24
|
# ============================================================================
|
|
20
25
|
|
|
21
|
-
|
|
26
|
+
usage() {
|
|
27
|
+
cat << 'EOF'
|
|
28
|
+
Usage: flow-workspace-start.sh [REQ_ID|DEVELOPER] [OPTIONS]
|
|
29
|
+
|
|
30
|
+
Start a workspace session and recover context.
|
|
31
|
+
|
|
32
|
+
Arguments:
|
|
33
|
+
REQ_ID Optional requirement ID to activate (REQ-XXX / BUG-XXX)
|
|
34
|
+
DEVELOPER Optional developer name (legacy positional style)
|
|
35
|
+
|
|
36
|
+
Options:
|
|
37
|
+
--developer NAME Explicit developer name
|
|
38
|
+
--req REQ_ID Activate a specific requirement before recovery
|
|
39
|
+
--switch Show switch recommendation to the target worktree
|
|
40
|
+
--cd Try to execute cd (effective only when script is sourced)
|
|
41
|
+
--help, -h Show help
|
|
42
|
+
|
|
43
|
+
Examples:
|
|
44
|
+
flow-workspace-start.sh
|
|
45
|
+
flow-workspace-start.sh REQ-123 --switch
|
|
46
|
+
source flow-workspace-start.sh REQ-123 --switch --cd
|
|
47
|
+
EOF
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
DEVELOPER="${DEVFLOW_DEVELOPER:-$(whoami)}"
|
|
51
|
+
REQ_OVERRIDE=""
|
|
52
|
+
SHOW_SWITCH=false
|
|
53
|
+
DO_CD=false
|
|
54
|
+
POSITIONAL=()
|
|
55
|
+
|
|
56
|
+
while [[ $# -gt 0 ]]; do
|
|
57
|
+
case "$1" in
|
|
58
|
+
--developer)
|
|
59
|
+
DEVELOPER="$2"
|
|
60
|
+
shift 2
|
|
61
|
+
;;
|
|
62
|
+
--req)
|
|
63
|
+
REQ_OVERRIDE="$2"
|
|
64
|
+
shift 2
|
|
65
|
+
;;
|
|
66
|
+
--switch)
|
|
67
|
+
SHOW_SWITCH=true
|
|
68
|
+
shift
|
|
69
|
+
;;
|
|
70
|
+
--cd)
|
|
71
|
+
DO_CD=true
|
|
72
|
+
shift
|
|
73
|
+
;;
|
|
74
|
+
--help|-h)
|
|
75
|
+
usage
|
|
76
|
+
exit 0
|
|
77
|
+
;;
|
|
78
|
+
-*)
|
|
79
|
+
echo "ERROR: Unknown option '$1'. Use --help for usage." >&2
|
|
80
|
+
exit 1
|
|
81
|
+
;;
|
|
82
|
+
*)
|
|
83
|
+
POSITIONAL+=("$1")
|
|
84
|
+
shift
|
|
85
|
+
;;
|
|
86
|
+
esac
|
|
87
|
+
done
|
|
88
|
+
|
|
89
|
+
# Backward compatible positional parsing:
|
|
90
|
+
# - if token looks like REQ/BUG -> requirement override
|
|
91
|
+
# - else treat as developer
|
|
92
|
+
for token in "${POSITIONAL[@]}"; do
|
|
93
|
+
if [[ "$token" =~ ^(REQ|BUG)-[0-9]+(-[0-9]+)?$ ]]; then
|
|
94
|
+
REQ_OVERRIDE=$(echo "$token" | tr '[:lower:]' '[:upper:]')
|
|
95
|
+
else
|
|
96
|
+
DEVELOPER="$token"
|
|
97
|
+
fi
|
|
98
|
+
done
|
|
99
|
+
|
|
22
100
|
DEV_WORKSPACE="$WORKSPACE_DIR/$DEVELOPER"
|
|
23
101
|
|
|
24
102
|
if [[ ! -d "$DEV_WORKSPACE" ]]; then
|
|
@@ -35,16 +113,31 @@ echo "🔄 Session Recovery for $DEVELOPER"
|
|
|
35
113
|
echo "=================================="
|
|
36
114
|
echo ""
|
|
37
115
|
|
|
116
|
+
if [[ -n "$REQ_OVERRIDE" ]]; then
|
|
117
|
+
if declare -f validate_req_id >/dev/null 2>&1; then
|
|
118
|
+
validate_req_id "$REQ_OVERRIDE" || exit 1
|
|
119
|
+
fi
|
|
120
|
+
echo "$REQ_OVERRIDE" > "$DEV_WORKSPACE/.current-req"
|
|
121
|
+
echo "📌 Requirement override: $REQ_OVERRIDE"
|
|
122
|
+
fi
|
|
123
|
+
|
|
38
124
|
# Read current requirement
|
|
39
125
|
if [[ -f "$DEV_WORKSPACE/.current-req" ]]; then
|
|
40
126
|
CURRENT_REQ=$(cat "$DEV_WORKSPACE/.current-req")
|
|
41
127
|
echo "📋 Current Requirement: $CURRENT_REQ"
|
|
42
128
|
|
|
43
|
-
#
|
|
44
|
-
|
|
129
|
+
# Resolve requirement/bug directory by ID prefix
|
|
130
|
+
if [[ "$CURRENT_REQ" =~ ^BUG- ]]; then
|
|
131
|
+
REQ_DIR="$PROJECT_ROOT/devflow/bugs/$CURRENT_REQ"
|
|
132
|
+
STATUS_BASENAME="status.json"
|
|
133
|
+
else
|
|
134
|
+
REQ_DIR="$PROJECT_ROOT/devflow/requirements/$CURRENT_REQ"
|
|
135
|
+
STATUS_BASENAME="orchestration_status.json"
|
|
136
|
+
fi
|
|
137
|
+
|
|
45
138
|
if [[ -d "$REQ_DIR" ]]; then
|
|
46
139
|
# Read orchestration status
|
|
47
|
-
STATUS_FILE="$REQ_DIR
|
|
140
|
+
STATUS_FILE="$REQ_DIR/$STATUS_BASENAME"
|
|
48
141
|
if [[ -f "$STATUS_FILE" ]]; then
|
|
49
142
|
STATUS=$(jq -r '.status' "$STATUS_FILE" 2>/dev/null || echo "unknown")
|
|
50
143
|
echo " Status: $STATUS"
|
|
@@ -57,6 +150,42 @@ if [[ -f "$DEV_WORKSPACE/.current-req" ]]; then
|
|
|
57
150
|
DONE=$(grep -c '^\- \[x\]' "$TASKS_FILE" 2>/dev/null || echo "0")
|
|
58
151
|
echo " Tasks: $DONE/$TOTAL completed"
|
|
59
152
|
fi
|
|
153
|
+
|
|
154
|
+
# Show expected worktree path and whether current session matches.
|
|
155
|
+
if declare -f get_worktree_dir_for_req >/dev/null 2>&1; then
|
|
156
|
+
EXPECTED_WORKTREE=$(get_worktree_dir_for_req "$CURRENT_REQ" 2>/dev/null || echo "")
|
|
157
|
+
CURRENT_GIT_ROOT=$(git -C "$PROJECT_ROOT" rev-parse --show-toplevel 2>/dev/null || echo "")
|
|
158
|
+
|
|
159
|
+
if [[ -n "$EXPECTED_WORKTREE" ]]; then
|
|
160
|
+
echo " Expected Worktree: $EXPECTED_WORKTREE"
|
|
161
|
+
if [[ -d "$EXPECTED_WORKTREE" ]]; then
|
|
162
|
+
if [[ "$CURRENT_GIT_ROOT" == "$EXPECTED_WORKTREE" ]]; then
|
|
163
|
+
echo " Worktree Match: yes"
|
|
164
|
+
else
|
|
165
|
+
echo " Worktree Match: no"
|
|
166
|
+
echo " Action: cd $EXPECTED_WORKTREE"
|
|
167
|
+
fi
|
|
168
|
+
else
|
|
169
|
+
echo " Worktree Match: missing"
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
if $SHOW_SWITCH; then
|
|
173
|
+
if [[ -d "$EXPECTED_WORKTREE" ]]; then
|
|
174
|
+
if $DO_CD; then
|
|
175
|
+
if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then
|
|
176
|
+
cd "$EXPECTED_WORKTREE"
|
|
177
|
+
echo " Auto Switched: yes ($PWD)"
|
|
178
|
+
else
|
|
179
|
+
echo " Auto Switched: no (requires sourced execution)"
|
|
180
|
+
echo " Run: source .claude/scripts/flow-workspace-start.sh $CURRENT_REQ --switch --cd"
|
|
181
|
+
fi
|
|
182
|
+
else
|
|
183
|
+
echo " Switch Command: cd \"$EXPECTED_WORKTREE\""
|
|
184
|
+
fi
|
|
185
|
+
fi
|
|
186
|
+
fi
|
|
187
|
+
fi
|
|
188
|
+
fi
|
|
60
189
|
else
|
|
61
190
|
echo " ⚠️ Requirement directory not found"
|
|
62
191
|
fi
|
|
@@ -85,4 +214,4 @@ fi
|
|
|
85
214
|
echo ""
|
|
86
215
|
echo "Ready to continue. Use:"
|
|
87
216
|
echo " /flow-workspace record \"message\" - Record progress"
|
|
88
|
-
echo " /flow-workspace switch REQ-XXX
|
|
217
|
+
echo " /flow-workspace switch REQ-XXX|BUG-XXX - Switch requirement"
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# [INPUT]: 依赖 common.sh、workspace/.current-req、journal-*.md
|
|
3
|
+
# [OUTPUT]: 更新当前开发者的 REQ 指针,并输出/执行 worktree 切换动作
|
|
4
|
+
# [POS]: scripts 的 workspace 切换脚本,被 /flow-workspace switch 与 start --switch 调用
|
|
5
|
+
# [PROTOCOL]: 变更时更新此头部,然后检查 CLAUDE.md
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
# ============================================================================
|
|
10
|
+
# Configuration
|
|
11
|
+
# ============================================================================
|
|
12
|
+
|
|
13
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
15
|
+
WORKSPACE_DIR="$PROJECT_ROOT/devflow/workspace"
|
|
16
|
+
COMMON_SH="$SCRIPT_DIR/common.sh"
|
|
17
|
+
|
|
18
|
+
if [[ -f "$COMMON_SH" ]]; then
|
|
19
|
+
source "$COMMON_SH"
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# ============================================================================
|
|
23
|
+
# Usage
|
|
24
|
+
# ============================================================================
|
|
25
|
+
|
|
26
|
+
usage() {
|
|
27
|
+
cat << 'EOF'
|
|
28
|
+
Usage: flow-workspace-switch.sh REQ_ID [OPTIONS]
|
|
29
|
+
|
|
30
|
+
Switch workspace context to a target requirement.
|
|
31
|
+
|
|
32
|
+
Arguments:
|
|
33
|
+
REQ_ID Requirement ID (REQ-XXX or BUG-XXX)
|
|
34
|
+
|
|
35
|
+
Options:
|
|
36
|
+
--developer NAME Developer name (default: DEVFLOW_DEVELOPER or current user)
|
|
37
|
+
--print-cd Print `cd "<worktree>"` for eval-style switching
|
|
38
|
+
--cd Try to execute cd (effective only when script is sourced)
|
|
39
|
+
--json Output in JSON format
|
|
40
|
+
--help, -h Show help
|
|
41
|
+
|
|
42
|
+
Examples:
|
|
43
|
+
flow-workspace-switch.sh REQ-123
|
|
44
|
+
flow-workspace-switch.sh REQ-123 --print-cd
|
|
45
|
+
eval "$(flow-workspace-switch.sh REQ-123 --print-cd)"
|
|
46
|
+
source flow-workspace-switch.sh REQ-123 --cd
|
|
47
|
+
EOF
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# ============================================================================
|
|
51
|
+
# Parse Arguments
|
|
52
|
+
# ============================================================================
|
|
53
|
+
|
|
54
|
+
REQ_ID=""
|
|
55
|
+
DEVELOPER="${DEVFLOW_DEVELOPER:-$(whoami)}"
|
|
56
|
+
PRINT_CD=false
|
|
57
|
+
DO_CD=false
|
|
58
|
+
JSON_MODE=false
|
|
59
|
+
|
|
60
|
+
while [[ $# -gt 0 ]]; do
|
|
61
|
+
case "$1" in
|
|
62
|
+
--developer)
|
|
63
|
+
DEVELOPER="$2"
|
|
64
|
+
shift 2
|
|
65
|
+
;;
|
|
66
|
+
--print-cd)
|
|
67
|
+
PRINT_CD=true
|
|
68
|
+
shift
|
|
69
|
+
;;
|
|
70
|
+
--cd)
|
|
71
|
+
DO_CD=true
|
|
72
|
+
shift
|
|
73
|
+
;;
|
|
74
|
+
--json)
|
|
75
|
+
JSON_MODE=true
|
|
76
|
+
shift
|
|
77
|
+
;;
|
|
78
|
+
--help|-h)
|
|
79
|
+
usage
|
|
80
|
+
exit 0
|
|
81
|
+
;;
|
|
82
|
+
-*)
|
|
83
|
+
echo "ERROR: Unknown option '$1'. Use --help for usage." >&2
|
|
84
|
+
exit 1
|
|
85
|
+
;;
|
|
86
|
+
*)
|
|
87
|
+
if [[ -z "$REQ_ID" ]]; then
|
|
88
|
+
REQ_ID="$1"
|
|
89
|
+
else
|
|
90
|
+
echo "ERROR: Too many arguments. Use --help for usage." >&2
|
|
91
|
+
exit 1
|
|
92
|
+
fi
|
|
93
|
+
shift
|
|
94
|
+
;;
|
|
95
|
+
esac
|
|
96
|
+
done
|
|
97
|
+
|
|
98
|
+
if [[ -z "$REQ_ID" ]]; then
|
|
99
|
+
echo "ERROR: REQ_ID is required. Use --help for usage." >&2
|
|
100
|
+
exit 1
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# Normalize and validate REQ_ID
|
|
104
|
+
REQ_ID=$(echo "$REQ_ID" | tr '[:lower:]' '[:upper:]')
|
|
105
|
+
if declare -f validate_req_id >/dev/null 2>&1; then
|
|
106
|
+
validate_req_id "$REQ_ID" || exit 1
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
# ============================================================================
|
|
110
|
+
# Resolve Workspace
|
|
111
|
+
# ============================================================================
|
|
112
|
+
|
|
113
|
+
DEV_WORKSPACE="$WORKSPACE_DIR/$DEVELOPER"
|
|
114
|
+
if [[ ! -d "$DEV_WORKSPACE" ]]; then
|
|
115
|
+
echo "ERROR: Workspace not found for '$DEVELOPER': $DEV_WORKSPACE" >&2
|
|
116
|
+
echo "Run '/flow-workspace init $DEVELOPER' first." >&2
|
|
117
|
+
exit 1
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
# Update current requirement pointer
|
|
121
|
+
echo "$REQ_ID" > "$DEV_WORKSPACE/.current-req"
|
|
122
|
+
|
|
123
|
+
# Append a lightweight journal entry
|
|
124
|
+
LATEST_JOURNAL=$(ls -1 "$DEV_WORKSPACE"/journal-*.md 2>/dev/null | sort -V | tail -1)
|
|
125
|
+
if [[ -z "$LATEST_JOURNAL" ]]; then
|
|
126
|
+
LATEST_JOURNAL="$DEV_WORKSPACE/journal-1.md"
|
|
127
|
+
cat > "$LATEST_JOURNAL" << EOF
|
|
128
|
+
---
|
|
129
|
+
developer: "$DEVELOPER"
|
|
130
|
+
journal_number: 1
|
|
131
|
+
created_at: "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
# Developer Journal: $DEVELOPER
|
|
135
|
+
|
|
136
|
+
> **[PROTOCOL]**: 变更时更新此头部,然后检查 CLAUDE.md
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
EOF
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
TIMESTAMP=$(date +"%Y-%m-%d %H:%M")
|
|
143
|
+
cat >> "$LATEST_JOURNAL" << EOF
|
|
144
|
+
## [$TIMESTAMP] Requirement Switch
|
|
145
|
+
|
|
146
|
+
**REQ**: $REQ_ID
|
|
147
|
+
|
|
148
|
+
Switched workspace pointer to \`$REQ_ID\`.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
EOF
|
|
152
|
+
|
|
153
|
+
# Resolve worktree path
|
|
154
|
+
WORKTREE_DIR=""
|
|
155
|
+
WORKTREE_EXISTS=false
|
|
156
|
+
if declare -f get_worktree_dir_for_req >/dev/null 2>&1; then
|
|
157
|
+
WORKTREE_DIR=$(get_worktree_dir_for_req "$REQ_ID" 2>/dev/null || echo "")
|
|
158
|
+
fi
|
|
159
|
+
if [[ -n "$WORKTREE_DIR" && -d "$WORKTREE_DIR" ]]; then
|
|
160
|
+
WORKTREE_EXISTS=true
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
# Source detection: cd can only affect caller shell when sourced
|
|
164
|
+
IS_SOURCED=false
|
|
165
|
+
if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then
|
|
166
|
+
IS_SOURCED=true
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
CD_EXECUTED=false
|
|
170
|
+
if $DO_CD; then
|
|
171
|
+
if ! $WORKTREE_EXISTS; then
|
|
172
|
+
echo "ERROR: Worktree not found for $REQ_ID: $WORKTREE_DIR" >&2
|
|
173
|
+
exit 1
|
|
174
|
+
fi
|
|
175
|
+
|
|
176
|
+
if $IS_SOURCED; then
|
|
177
|
+
cd "$WORKTREE_DIR"
|
|
178
|
+
CD_EXECUTED=true
|
|
179
|
+
fi
|
|
180
|
+
fi
|
|
181
|
+
|
|
182
|
+
# ============================================================================
|
|
183
|
+
# Output
|
|
184
|
+
# ============================================================================
|
|
185
|
+
|
|
186
|
+
if $JSON_MODE; then
|
|
187
|
+
printf '{"developer":"%s","req_id":"%s","workspace":"%s","worktree_dir":"%s","worktree_exists":%s,"cd_executed":%s}\n' \
|
|
188
|
+
"$DEVELOPER" \
|
|
189
|
+
"$REQ_ID" \
|
|
190
|
+
"$DEV_WORKSPACE" \
|
|
191
|
+
"$WORKTREE_DIR" \
|
|
192
|
+
"$WORKTREE_EXISTS" \
|
|
193
|
+
"$CD_EXECUTED"
|
|
194
|
+
return 0 2>/dev/null || exit 0
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
if $PRINT_CD; then
|
|
198
|
+
if $WORKTREE_EXISTS; then
|
|
199
|
+
printf 'cd "%s"\n' "$WORKTREE_DIR"
|
|
200
|
+
return 0 2>/dev/null || exit 0
|
|
201
|
+
fi
|
|
202
|
+
echo "ERROR: Worktree not found for $REQ_ID: $WORKTREE_DIR" >&2
|
|
203
|
+
exit 1
|
|
204
|
+
fi
|
|
205
|
+
|
|
206
|
+
echo "✅ Workspace switched"
|
|
207
|
+
echo "Developer: $DEVELOPER"
|
|
208
|
+
echo "Current REQ: $REQ_ID"
|
|
209
|
+
echo "Workspace: $DEV_WORKSPACE"
|
|
210
|
+
if [[ -n "$WORKTREE_DIR" ]]; then
|
|
211
|
+
echo "Expected Worktree: $WORKTREE_DIR"
|
|
212
|
+
fi
|
|
213
|
+
echo "Worktree Exists: $WORKTREE_EXISTS"
|
|
214
|
+
|
|
215
|
+
if $DO_CD; then
|
|
216
|
+
if $CD_EXECUTED; then
|
|
217
|
+
echo "Directory switched to: $PWD"
|
|
218
|
+
else
|
|
219
|
+
echo ""
|
|
220
|
+
echo "⚠️ --cd 未生效(脚本以子进程运行,无法修改父 Shell 目录)"
|
|
221
|
+
echo "Use one of:"
|
|
222
|
+
echo " source .claude/scripts/flow-workspace-switch.sh $REQ_ID --cd"
|
|
223
|
+
echo " eval \"\$(.claude/scripts/flow-workspace-switch.sh $REQ_ID --print-cd)\""
|
|
224
|
+
fi
|
|
225
|
+
elif $WORKTREE_EXISTS; then
|
|
226
|
+
echo ""
|
|
227
|
+
echo "Next:"
|
|
228
|
+
echo " cd \"$WORKTREE_DIR\""
|
|
229
|
+
else
|
|
230
|
+
echo ""
|
|
231
|
+
echo "Worktree is missing. Create it with flow-init (default mode) or worktree-create script."
|
|
232
|
+
fi
|
|
233
|
+
|
|
234
|
+
return 0 2>/dev/null || exit 0
|
|
@@ -124,8 +124,8 @@ get_phase_display_name() {
|
|
|
124
124
|
epic_complete) echo "Epic完成" ;;
|
|
125
125
|
development) echo "开发中" ;;
|
|
126
126
|
dev_complete) echo "开发完成" ;;
|
|
127
|
-
qa) echo "
|
|
128
|
-
qa_complete) echo "
|
|
127
|
+
quality|qa) echo "质量验证" ;;
|
|
128
|
+
quality_complete|qa_complete) echo "质量完成" ;;
|
|
129
129
|
release) echo "发布中" ;;
|
|
130
130
|
release_complete) echo "发布完成" ;;
|
|
131
131
|
completed) echo "已完成" ;;
|
|
@@ -143,8 +143,8 @@ get_phase_percentage() {
|
|
|
143
143
|
epic_complete) echo "30" ;;
|
|
144
144
|
development) echo "40" ;;
|
|
145
145
|
dev_complete) echo "70" ;;
|
|
146
|
-
qa) echo "80" ;;
|
|
147
|
-
qa_complete) echo "90" ;;
|
|
146
|
+
quality|qa) echo "80" ;;
|
|
147
|
+
quality_complete|qa_complete) echo "90" ;;
|
|
148
148
|
release|release_complete) echo "95" ;;
|
|
149
149
|
completed) echo "100" ;;
|
|
150
150
|
*) echo "0" ;;
|
|
@@ -520,4 +520,4 @@ main() {
|
|
|
520
520
|
fi
|
|
521
521
|
}
|
|
522
522
|
|
|
523
|
-
main
|
|
523
|
+
main
|
|
@@ -28,7 +28,7 @@ usage() {
|
|
|
28
28
|
|
|
29
29
|
选项:
|
|
30
30
|
-h, --help 显示此帮助信息
|
|
31
|
-
--from STAGE 从指定阶段重新开始 (init/prd/epic/dev/
|
|
31
|
+
--from STAGE 从指定阶段重新开始 (init/prd/epic/dev/quality/release, qa 兼容)
|
|
32
32
|
--force 强制恢复,跳过安全检查
|
|
33
33
|
--dry-run 显示恢复计划但不执行
|
|
34
34
|
--verbose 显示详细信息
|
|
@@ -38,7 +38,7 @@ usage() {
|
|
|
38
38
|
prd - PRD生成阶段
|
|
39
39
|
epic - Epic规划阶段
|
|
40
40
|
dev - 开发执行阶段
|
|
41
|
-
|
|
41
|
+
quality - 质量验证阶段
|
|
42
42
|
release - 发布管理阶段
|
|
43
43
|
|
|
44
44
|
示例:
|
|
@@ -251,17 +251,17 @@ analyze_recovery_strategy() {
|
|
|
251
251
|
echo -e "${CYAN}建议: 继续开发 (恢复未完成任务)${NC}"
|
|
252
252
|
echo "dev"
|
|
253
253
|
else
|
|
254
|
-
echo -e "${CYAN}建议:
|
|
255
|
-
echo "
|
|
254
|
+
echo -e "${CYAN}建议: 进入质量验证阶段${NC}"
|
|
255
|
+
echo "quality"
|
|
256
256
|
fi
|
|
257
257
|
else
|
|
258
258
|
echo -e "${CYAN}建议: 从开发阶段开始${NC}"
|
|
259
259
|
echo "dev"
|
|
260
260
|
fi
|
|
261
261
|
;;
|
|
262
|
-
qa|qa_complete)
|
|
263
|
-
echo -e "${CYAN}建议:
|
|
264
|
-
echo "
|
|
262
|
+
quality|quality_complete|qa|qa_complete)
|
|
263
|
+
echo -e "${CYAN}建议: 从质量验证阶段开始${NC}"
|
|
264
|
+
echo "quality"
|
|
265
265
|
;;
|
|
266
266
|
release|release_complete)
|
|
267
267
|
echo -e "${CYAN}建议: 从发布阶段开始${NC}"
|
|
@@ -284,12 +284,12 @@ validate_stage() {
|
|
|
284
284
|
local stage="$1"
|
|
285
285
|
|
|
286
286
|
case "$stage" in
|
|
287
|
-
init|prd|epic|dev|qa|release)
|
|
287
|
+
init|prd|epic|dev|quality|qa|release)
|
|
288
288
|
return 0
|
|
289
289
|
;;
|
|
290
290
|
*)
|
|
291
291
|
echo -e "${RED}错误: 无效的阶段 '$stage'${NC}"
|
|
292
|
-
echo -e "${YELLOW}有效阶段: init, prd, epic, dev,
|
|
292
|
+
echo -e "${YELLOW}有效阶段: init, prd, epic, dev, quality, release (qa 兼容)${NC}"
|
|
293
293
|
exit 1
|
|
294
294
|
;;
|
|
295
295
|
esac
|
|
@@ -315,19 +315,19 @@ generate_recovery_plan() {
|
|
|
315
315
|
local stages=()
|
|
316
316
|
case "$start_stage" in
|
|
317
317
|
init)
|
|
318
|
-
stages=("init" "prd" "epic" "dev" "
|
|
318
|
+
stages=("init" "prd" "epic" "dev" "quality" "release")
|
|
319
319
|
;;
|
|
320
320
|
prd)
|
|
321
|
-
stages=("prd" "epic" "dev" "
|
|
321
|
+
stages=("prd" "epic" "dev" "quality" "release")
|
|
322
322
|
;;
|
|
323
323
|
epic)
|
|
324
|
-
stages=("epic" "dev" "
|
|
324
|
+
stages=("epic" "dev" "quality" "release")
|
|
325
325
|
;;
|
|
326
326
|
dev)
|
|
327
|
-
stages=("dev" "
|
|
327
|
+
stages=("dev" "quality" "release")
|
|
328
328
|
;;
|
|
329
|
-
qa)
|
|
330
|
-
stages=("
|
|
329
|
+
quality|qa)
|
|
330
|
+
stages=("quality" "release")
|
|
331
331
|
;;
|
|
332
332
|
release)
|
|
333
333
|
stages=("release")
|
|
@@ -351,8 +351,8 @@ generate_recovery_plan() {
|
|
|
351
351
|
dev)
|
|
352
352
|
command="/flow-dev \"$REQ_ID\" --resume"
|
|
353
353
|
;;
|
|
354
|
-
|
|
355
|
-
command="/flow-
|
|
354
|
+
quality)
|
|
355
|
+
command="/flow-quality \"$REQ_ID\""
|
|
356
356
|
;;
|
|
357
357
|
release)
|
|
358
358
|
command="/flow-release \"$REQ_ID\""
|
|
@@ -397,29 +397,29 @@ execute_recovery() {
|
|
|
397
397
|
echo "/flow-prd \"$REQ_ID\""
|
|
398
398
|
echo "/flow-epic \"$REQ_ID\""
|
|
399
399
|
echo "/flow-dev \"$REQ_ID\""
|
|
400
|
-
echo "/flow-
|
|
400
|
+
echo "/flow-quality \"$REQ_ID\""
|
|
401
401
|
echo "/flow-release \"$REQ_ID\""
|
|
402
402
|
;;
|
|
403
403
|
prd)
|
|
404
404
|
echo "/flow-prd \"$REQ_ID\""
|
|
405
405
|
echo "/flow-epic \"$REQ_ID\""
|
|
406
406
|
echo "/flow-dev \"$REQ_ID\""
|
|
407
|
-
echo "/flow-
|
|
407
|
+
echo "/flow-quality \"$REQ_ID\""
|
|
408
408
|
echo "/flow-release \"$REQ_ID\""
|
|
409
409
|
;;
|
|
410
410
|
epic)
|
|
411
411
|
echo "/flow-epic \"$REQ_ID\""
|
|
412
412
|
echo "/flow-dev \"$REQ_ID\""
|
|
413
|
-
echo "/flow-
|
|
413
|
+
echo "/flow-quality \"$REQ_ID\""
|
|
414
414
|
echo "/flow-release \"$REQ_ID\""
|
|
415
415
|
;;
|
|
416
416
|
dev)
|
|
417
417
|
echo "/flow-dev \"$REQ_ID\" --resume"
|
|
418
|
-
echo "/flow-
|
|
418
|
+
echo "/flow-quality \"$REQ_ID\""
|
|
419
419
|
echo "/flow-release \"$REQ_ID\""
|
|
420
420
|
;;
|
|
421
|
-
qa)
|
|
422
|
-
echo "/flow-
|
|
421
|
+
quality|qa)
|
|
422
|
+
echo "/flow-quality \"$REQ_ID\""
|
|
423
423
|
echo "/flow-release \"$REQ_ID\""
|
|
424
424
|
;;
|
|
425
425
|
release)
|
|
@@ -463,4 +463,4 @@ main() {
|
|
|
463
463
|
}
|
|
464
464
|
|
|
465
465
|
# 运行主逻辑
|
|
466
|
-
main
|
|
466
|
+
main
|
|
@@ -50,7 +50,14 @@ description: 'Initialize requirement structure with brainstorming and research.
|
|
|
50
50
|
# 计算路径
|
|
51
51
|
REPO_NAME=$(basename $(git rev-parse --show-toplevel))
|
|
52
52
|
WORKTREE_DIR="../${REPO_NAME}-${REQ_ID}"
|
|
53
|
-
|
|
53
|
+
|
|
54
|
+
# 分支前缀按类型决定
|
|
55
|
+
if [[ "${REQ_ID}" =~ ^BUG- ]]; then
|
|
56
|
+
BRANCH_PREFIX="bugfix"
|
|
57
|
+
else
|
|
58
|
+
BRANCH_PREFIX="feature"
|
|
59
|
+
fi
|
|
60
|
+
BRANCH_NAME="${BRANCH_PREFIX}/${REQ_ID}-${slug(BRANCH_TITLE_EN)}"
|
|
54
61
|
|
|
55
62
|
# 创建 worktree + 分支
|
|
56
63
|
git worktree add -b "$BRANCH_NAME" "$WORKTREE_DIR"
|
|
@@ -70,6 +70,9 @@ version: 3.0.0
|
|
|
70
70
|
✓ Lint Check
|
|
71
71
|
✓ Type Check
|
|
72
72
|
✓ Unit Tests
|
|
73
|
+
Reports Generated (when REQ-ID resolved):
|
|
74
|
+
- TEST_REPORT.md
|
|
75
|
+
- SECURITY_REPORT.md
|
|
73
76
|
```
|
|
74
77
|
|
|
75
78
|
### Full Mode
|
|
@@ -79,6 +82,7 @@ Reports Generated:
|
|
|
79
82
|
- SPEC_REVIEW.md
|
|
80
83
|
- CODE_QUALITY_REVIEW.md
|
|
81
84
|
- SECURITY_REPORT.md
|
|
85
|
+
- TEST_REPORT.md
|
|
82
86
|
```
|
|
83
87
|
|
|
84
88
|
## Deprecation Notice
|
|
@@ -29,12 +29,19 @@ description: 'Create PR and manage release. Usage: /flow-release "REQ-123" or /f
|
|
|
29
29
|
| C) Squash merge | 多提交合并为一 | `gh pr merge --squash` |
|
|
30
30
|
| D) Cleanup only | 工作被废弃 | `git branch -D` |
|
|
31
31
|
|
|
32
|
+
## Merge Semantics
|
|
33
|
+
|
|
34
|
+
- A) Fast-forward: 直接合并到 `main`
|
|
35
|
+
- B) Create PR: 仅创建/更新 PR,不自动合并
|
|
36
|
+
- C) Squash merge: 通过 PR squash 合并到 `main`
|
|
37
|
+
- D) Cleanup only: 不合并,仅清理
|
|
38
|
+
|
|
32
39
|
## Entry Gate
|
|
33
40
|
|
|
34
41
|
1. **PRD.md, TECH_DESIGN.md, EPIC.md, TASKS.md** 存在
|
|
35
42
|
2. **TEST_REPORT.md, SECURITY_REPORT.md** Gate 均为 PASS
|
|
36
|
-
3. **Status**: `qa_complete
|
|
37
|
-
4. **Git**:
|
|
43
|
+
3. **Status**: `quality_complete`(兼容 `qa_complete`)或 `release_failed`
|
|
44
|
+
4. **Git**: 当前在 feature/bugfix 分支;若工作区不干净,必须先按 `.claude/commands/util/git-commit.md` 完成提交(Conventional Commits + 按同类变更拆分)再继续
|
|
38
45
|
|
|
39
46
|
## Execution Flow
|
|
40
47
|
|
|
@@ -51,13 +58,19 @@ description: 'Create PR and manage release. Usage: /flow-release "REQ-123" or /f
|
|
|
51
58
|
- 生成 RELEASE_PLAN.md
|
|
52
59
|
- 生成 PR 描述草稿
|
|
53
60
|
|
|
54
|
-
### Stage 3:
|
|
61
|
+
### Stage 3: Commit Gate (MANDATORY)
|
|
62
|
+
|
|
63
|
+
- 检查 `git status --porcelain`
|
|
64
|
+
- 若存在未提交变更,必须先执行 `/util/git-commit`(规则文件 `.claude/commands/util/git-commit.md`)
|
|
65
|
+
- 提交完成后再次确认工作区干净,再进入 PR 创建
|
|
66
|
+
|
|
67
|
+
### Stage 4: PR Creation
|
|
55
68
|
|
|
56
69
|
使用 `gh` CLI:
|
|
57
70
|
- 标题: `${REQ_ID}: ${TITLE}`
|
|
58
71
|
- 正文: agent 输出
|
|
59
72
|
|
|
60
|
-
### Stage
|
|
73
|
+
### Stage 5: Worktree/Branch Cleanup
|
|
61
74
|
|
|
62
75
|
**Worktree 模式**:
|
|
63
76
|
```bash
|
|
@@ -91,7 +104,7 @@ git merge --ff-only "$BRANCH_NAME"
|
|
|
91
104
|
git branch -d "$BRANCH_NAME"
|
|
92
105
|
```
|
|
93
106
|
|
|
94
|
-
### Stage
|
|
107
|
+
### Stage 6: Exit Gate
|
|
95
108
|
|
|
96
109
|
1. RELEASE_PLAN.md 存在
|
|
97
110
|
2. PR 创建成功
|