cc-devflow 4.1.4 → 4.1.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/.claude/CLAUDE.md +87 -1183
- package/.claude/commands/core/architecture.md +2 -2
- package/.claude/commands/core/guidelines.md +2 -2
- package/.claude/commands/core/roadmap.md +4 -4
- package/.claude/commands/core/style.md +40 -268
- package/.claude/commands/flow/CLAUDE.md +28 -0
- package/.claude/commands/flow/archive.md +2 -2
- package/.claude/commands/flow/checklist.md +9 -251
- package/.claude/commands/flow/clarify.md +9 -127
- package/.claude/commands/flow/constitution.md +1 -1
- package/.claude/commands/flow/context.md +1 -1
- package/.claude/commands/flow/dev.md +19 -395
- package/.claude/commands/flow/fix.md +1 -6
- package/.claude/commands/flow/ideate.md +13 -13
- package/.claude/commands/flow/init.md +19 -41
- package/.claude/commands/flow/new.md +12 -268
- package/.claude/commands/flow/quality.md +10 -153
- package/.claude/commands/flow/release.md +18 -131
- package/.claude/commands/flow/restart.md +15 -16
- package/.claude/commands/flow/spec.md +14 -164
- package/.claude/commands/flow/status.md +12 -12
- package/.claude/commands/flow/update.md +4 -4
- package/.claude/commands/flow/upgrade.md +6 -6
- package/.claude/commands/flow/verify.md +19 -78
- package/.claude/commands/flow/workspace.md +3 -20
- package/.claude/docs/guides/INIT_TROUBLESHOOTING.md +7 -7
- package/.claude/docs/guides/NEW_TROUBLESHOOTING.md +44 -96
- package/.claude/docs/guides/ROADMAP_TROUBLESHOOTING.md +1 -1
- package/.claude/docs/guides/TASK_COMPLETION_MARKING.md +5 -5
- package/.claude/docs/guides/TEAM_MODE_GUIDE.md +0 -1
- package/.claude/docs/templates/ATTEMPT_TEMPLATE.md +1 -1
- package/.claude/docs/templates/BACKLOG_TEMPLATE.md +3 -3
- package/.claude/docs/templates/CLARIFICATION_REPORT_TEMPLATE.md +5 -5
- package/.claude/docs/templates/ERROR_LOG_TEMPLATE.md +2 -2
- package/.claude/docs/templates/INIT_FLOW_TEMPLATE.md +3 -3
- package/.claude/docs/templates/NEW_ORCHESTRATION_TEMPLATE.md +33 -64
- package/.claude/docs/templates/RESEARCH_TEMPLATE.md +3 -3
- package/.claude/docs/templates/ROADMAP_DIALOGUE_TEMPLATE.md +2 -2
- package/.claude/docs/templates/ROADMAP_TEMPLATE.md +2 -2
- package/.claude/docs/templates/STYLE_TEMPLATE.md +3 -3
- package/.claude/docs/templates/UI_PROTOTYPE_TEMPLATE.md +8 -9
- package/.claude/guides/workflow-guides/flow-orchestrator.md +31 -265
- package/.claude/hooks/CLAUDE.md +1 -1
- package/.claude/hooks/checklist-gate.js +4 -4
- package/.claude/hooks/inject-agent-context.ts +2 -2
- package/.claude/hooks/teammate-idle-hook.ts +1 -1
- package/.claude/rules/devflow-conventions.md +2 -93
- package/.claude/scripts/CLAUDE.md +1 -4
- package/.claude/scripts/calculate-checklist-completion.sh +2 -2
- package/.claude/scripts/check-prerequisites.sh +2 -2
- package/.claude/scripts/checklist-errors.sh +4 -4
- package/.claude/scripts/common.sh +12 -147
- package/.claude/scripts/flow-quality-full.sh +5 -5
- package/.claude/scripts/flow-quality-quick.sh +4 -4
- package/.claude/scripts/flow-workspace-init.sh +2 -2
- package/.claude/scripts/generate-clarification-report.sh +4 -4
- package/.claude/scripts/recover-workflow.sh +70 -73
- package/.claude/scripts/run-quality-gates.sh +1 -1
- package/.claude/scripts/setup-epic.sh +2 -2
- package/.claude/scripts/setup-ralph-loop.sh +2 -2
- package/.claude/scripts/validate-research.sh +1 -1
- package/.claude/scripts/verify-setup.sh +1 -1
- package/.claude/skills/cc-devflow-orchestrator/SKILL.md +88 -108
- package/.claude/skills/workflow/CLAUDE.md +24 -0
- package/.claude/skills/workflow/flow-dev/CLAUDE.md +14 -76
- package/.claude/skills/workflow/flow-dev/SKILL.md +29 -67
- package/.claude/skills/workflow/flow-dev/context.jsonl +4 -8
- package/.claude/skills/workflow/flow-init/SKILL.md +23 -186
- package/.claude/skills/workflow/flow-init/assets/RESEARCH_TEMPLATE.md +1 -1
- package/.claude/skills/workflow/flow-init/context.jsonl +3 -3
- package/.claude/skills/workflow/flow-init/scripts/check-prerequisites.sh +1 -1
- package/.claude/skills/workflow/flow-init/scripts/create-requirement.sh +15 -134
- package/.claude/skills/workflow/flow-init/scripts/validate-research.sh +1 -1
- package/.claude/skills/workflow/flow-release/SKILL.md +20 -110
- package/.claude/skills/workflow/flow-release/context.jsonl +5 -7
- package/.claude/skills/workflow/flow-spec/CLAUDE.md +15 -101
- package/.claude/skills/workflow/flow-spec/SKILL.md +15 -518
- package/.claude/skills/workflow/flow-spec/context.jsonl +5 -7
- package/.claude/skills/workflow/flow-verify/CLAUDE.md +10 -0
- package/.claude/skills/workflow/flow-verify/SKILL.md +53 -0
- package/.claude/skills/workflow/flow-verify/context.jsonl +5 -0
- package/.claude/skills/workflow.yaml +72 -270
- package/CHANGELOG.md +72 -0
- package/README.md +91 -69
- package/README.zh-CN.md +90 -67
- package/bin/harness.js +22 -0
- package/docs/commands/README.md +34 -38
- package/docs/commands/README.zh-CN.md +34 -36
- package/docs/commands/core-roadmap.md +2 -2
- package/docs/commands/core-roadmap.zh-CN.md +2 -2
- package/docs/commands/core-style.md +29 -381
- package/docs/commands/core-style.zh-CN.md +29 -381
- package/docs/commands/flow-init.md +10 -10
- package/docs/commands/flow-init.zh-CN.md +11 -11
- package/docs/commands/flow-new.md +25 -260
- package/docs/commands/flow-new.zh-CN.md +26 -257
- package/docs/guides/getting-started.md +16 -15
- package/docs/guides/getting-started.zh-CN.md +10 -12
- package/lib/compiler/__tests__/manifest.test.js +156 -0
- package/lib/compiler/__tests__/parser.test.js +21 -0
- package/lib/compiler/index.js +17 -1
- package/lib/compiler/manifest.js +68 -6
- package/lib/compiler/parser.js +5 -0
- package/lib/harness/CLAUDE.md +21 -0
- package/lib/harness/cli.js +208 -0
- package/lib/harness/index.js +16 -0
- package/lib/harness/operations/dispatch.js +285 -0
- package/lib/harness/operations/init.js +48 -0
- package/lib/harness/operations/janitor.js +74 -0
- package/lib/harness/operations/pack.js +100 -0
- package/lib/harness/operations/plan.js +29 -0
- package/lib/harness/operations/release.js +83 -0
- package/lib/harness/operations/resume.js +44 -0
- package/lib/harness/operations/verify.js +163 -0
- package/lib/harness/planner.js +141 -0
- package/lib/harness/schemas.js +108 -0
- package/lib/harness/store.js +240 -0
- package/package.json +9 -1
- package/.claude/scripts/flow-workspace-start.sh +0 -217
- package/.claude/scripts/flow-workspace-switch.sh +0 -234
- package/.claude/skills/domain/using-git-worktrees/SKILL.md +0 -252
- package/.claude/skills/domain/using-git-worktrees/assets/SHELL_ALIASES.md +0 -133
- package/.claude/skills/domain/using-git-worktrees/context.jsonl +0 -4
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-cleanup.sh +0 -218
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-create.sh +0 -232
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-list.sh +0 -130
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-status.sh +0 -140
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-switch.sh +0 -70
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
# Git Worktree Shell Aliases
|
|
2
|
-
|
|
3
|
-
> 将以下内容添加到 `~/.zshrc` 或 `~/.bashrc`
|
|
4
|
-
|
|
5
|
-
## Quick Navigation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
# =============================================================================
|
|
9
|
-
# Git Worktree Aliases for CC-DevFlow
|
|
10
|
-
# =============================================================================
|
|
11
|
-
|
|
12
|
-
# 快速导航到当前 worktree 根目录
|
|
13
|
-
alias za='cd $(git rev-parse --show-toplevel 2>/dev/null || echo .)'
|
|
14
|
-
|
|
15
|
-
# 列出所有 worktree
|
|
16
|
-
alias zl='git worktree list'
|
|
17
|
-
|
|
18
|
-
# 导航到主仓库 (修改为你的实际路径)
|
|
19
|
-
alias zm='cd ~/projects/cc-devflow'
|
|
20
|
-
|
|
21
|
-
# 快速切换到指定 REQ 的 worktree
|
|
22
|
-
zw() {
|
|
23
|
-
local req_id="${1:-}"
|
|
24
|
-
if [[ -z "$req_id" ]]; then
|
|
25
|
-
echo "Usage: zw REQ-123"
|
|
26
|
-
echo ""
|
|
27
|
-
echo "Available worktrees:"
|
|
28
|
-
git worktree list
|
|
29
|
-
return 1
|
|
30
|
-
fi
|
|
31
|
-
|
|
32
|
-
# Normalize to uppercase
|
|
33
|
-
req_id=$(echo "$req_id" | tr '[:lower:]' '[:upper:]')
|
|
34
|
-
|
|
35
|
-
# Get repo name from current git repo or main repo
|
|
36
|
-
local main_repo
|
|
37
|
-
if git rev-parse --show-toplevel >/dev/null 2>&1; then
|
|
38
|
-
main_repo=$(git rev-parse --show-toplevel)
|
|
39
|
-
# If in worktree, find main repo
|
|
40
|
-
local git_dir=$(git rev-parse --git-dir)
|
|
41
|
-
if [[ "$git_dir" == *".git/worktrees/"* ]]; then
|
|
42
|
-
main_repo=$(cat "$(git rev-parse --show-toplevel)/.git" 2>/dev/null | sed 's/gitdir: //' | sed 's|/.git/worktrees/.*||')
|
|
43
|
-
fi
|
|
44
|
-
else
|
|
45
|
-
main_repo=~/projects/cc-devflow
|
|
46
|
-
fi
|
|
47
|
-
|
|
48
|
-
local repo_name=$(basename "$main_repo")
|
|
49
|
-
local target_dir="$(dirname "$main_repo")/${repo_name}-${req_id}"
|
|
50
|
-
|
|
51
|
-
if [[ -d "$target_dir" ]]; then
|
|
52
|
-
cd "$target_dir"
|
|
53
|
-
echo "Switched to: $target_dir"
|
|
54
|
-
echo "Branch: $(git rev-parse --abbrev-ref HEAD)"
|
|
55
|
-
else
|
|
56
|
-
echo "Worktree not found: $target_dir"
|
|
57
|
-
echo ""
|
|
58
|
-
echo "Available worktrees:"
|
|
59
|
-
git worktree list
|
|
60
|
-
return 1
|
|
61
|
-
fi
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
# 创建新 worktree (快捷方式)
|
|
65
|
-
zwn() {
|
|
66
|
-
local req_id="${1:-}"
|
|
67
|
-
local title="${2:-}"
|
|
68
|
-
|
|
69
|
-
if [[ -z "$req_id" ]]; then
|
|
70
|
-
echo "Usage: zwn REQ-123 [title]"
|
|
71
|
-
return 1
|
|
72
|
-
fi
|
|
73
|
-
|
|
74
|
-
# Find the skill script
|
|
75
|
-
local script_path
|
|
76
|
-
if [[ -f ".claude/skills/domain/using-git-worktrees/scripts/worktree-create.sh" ]]; then
|
|
77
|
-
script_path=".claude/skills/domain/using-git-worktrees/scripts/worktree-create.sh"
|
|
78
|
-
elif [[ -f "$(git rev-parse --show-toplevel 2>/dev/null)/.claude/skills/domain/using-git-worktrees/scripts/worktree-create.sh" ]]; then
|
|
79
|
-
script_path="$(git rev-parse --show-toplevel)/.claude/skills/domain/using-git-worktrees/scripts/worktree-create.sh"
|
|
80
|
-
else
|
|
81
|
-
echo "ERROR: worktree-create.sh not found"
|
|
82
|
-
return 1
|
|
83
|
-
fi
|
|
84
|
-
|
|
85
|
-
bash "$script_path" "$req_id" "$title"
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
# 清理已合并的 worktree
|
|
89
|
-
zwc() {
|
|
90
|
-
local script_path
|
|
91
|
-
if [[ -f ".claude/skills/domain/using-git-worktrees/scripts/worktree-cleanup.sh" ]]; then
|
|
92
|
-
script_path=".claude/skills/domain/using-git-worktrees/scripts/worktree-cleanup.sh"
|
|
93
|
-
elif [[ -f "$(git rev-parse --show-toplevel 2>/dev/null)/.claude/skills/domain/using-git-worktrees/scripts/worktree-cleanup.sh" ]]; then
|
|
94
|
-
script_path="$(git rev-parse --show-toplevel)/.claude/skills/domain/using-git-worktrees/scripts/worktree-cleanup.sh"
|
|
95
|
-
else
|
|
96
|
-
echo "ERROR: worktree-cleanup.sh not found"
|
|
97
|
-
return 1
|
|
98
|
-
fi
|
|
99
|
-
|
|
100
|
-
bash "$script_path" --merged "$@"
|
|
101
|
-
}
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Usage Examples
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
# 列出所有 worktree
|
|
108
|
-
zl
|
|
109
|
-
|
|
110
|
-
# 切换到 REQ-123 的 worktree
|
|
111
|
-
zw REQ-123
|
|
112
|
-
|
|
113
|
-
# 创建新 worktree
|
|
114
|
-
zwn REQ-456 "New Feature"
|
|
115
|
-
|
|
116
|
-
# 清理已合并的 worktree
|
|
117
|
-
zwc
|
|
118
|
-
|
|
119
|
-
# 导航到主仓库
|
|
120
|
-
zm
|
|
121
|
-
|
|
122
|
-
# 导航到当前 worktree 根目录
|
|
123
|
-
za
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## Customization
|
|
127
|
-
|
|
128
|
-
根据你的项目路径修改 `zm` 别名:
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
# 如果主仓库在不同位置
|
|
132
|
-
alias zm='cd /path/to/your/main/repo'
|
|
133
|
-
```
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
{"file": ".claude/scripts/common.sh", "reason": "Worktree helper functions"}
|
|
2
|
-
{"file": ".claude/skills/workflow/flow-init/SKILL.md", "reason": "Worktree creation integration"}
|
|
3
|
-
{"file": ".claude/skills/workflow/flow-release/SKILL.md", "reason": "Worktree cleanup integration"}
|
|
4
|
-
{"file": ".claude/rules/devflow-conventions.md", "reason": "Git worktree conventions", "optional": true}
|
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# =============================================================================
|
|
3
|
-
# worktree-cleanup.sh - Clean up git worktrees
|
|
4
|
-
# =============================================================================
|
|
5
|
-
#
|
|
6
|
-
# Usage: worktree-cleanup.sh [REQ_ID] [OPTIONS]
|
|
7
|
-
#
|
|
8
|
-
# ARGUMENTS:
|
|
9
|
-
# REQ_ID Specific requirement to clean up (optional)
|
|
10
|
-
#
|
|
11
|
-
# OPTIONS:
|
|
12
|
-
# --merged Clean up all worktrees with merged branches
|
|
13
|
-
# --force Force removal even if branch not merged
|
|
14
|
-
# --dry-run Show what would be cleaned without doing it
|
|
15
|
-
# --json Output in JSON format
|
|
16
|
-
# --help, -h Show help message
|
|
17
|
-
#
|
|
18
|
-
# [PROTOCOL]: 变更时更新此头部,然后检查 CLAUDE.md
|
|
19
|
-
|
|
20
|
-
set -e
|
|
21
|
-
|
|
22
|
-
REQ_ID=""
|
|
23
|
-
MERGED_ONLY=false
|
|
24
|
-
FORCE=false
|
|
25
|
-
DRY_RUN=false
|
|
26
|
-
JSON_MODE=false
|
|
27
|
-
|
|
28
|
-
while [[ $# -gt 0 ]]; do
|
|
29
|
-
case "$1" in
|
|
30
|
-
--merged)
|
|
31
|
-
MERGED_ONLY=true
|
|
32
|
-
shift
|
|
33
|
-
;;
|
|
34
|
-
--force)
|
|
35
|
-
FORCE=true
|
|
36
|
-
shift
|
|
37
|
-
;;
|
|
38
|
-
--dry-run)
|
|
39
|
-
DRY_RUN=true
|
|
40
|
-
shift
|
|
41
|
-
;;
|
|
42
|
-
--json)
|
|
43
|
-
JSON_MODE=true
|
|
44
|
-
shift
|
|
45
|
-
;;
|
|
46
|
-
--help|-h)
|
|
47
|
-
cat << 'EOF'
|
|
48
|
-
Usage: worktree-cleanup.sh [REQ_ID] [OPTIONS]
|
|
49
|
-
|
|
50
|
-
Clean up git worktrees.
|
|
51
|
-
|
|
52
|
-
ARGUMENTS:
|
|
53
|
-
REQ_ID Specific requirement to clean up (optional)
|
|
54
|
-
|
|
55
|
-
OPTIONS:
|
|
56
|
-
--merged Clean up all worktrees with merged branches
|
|
57
|
-
--force Force removal even if branch not merged
|
|
58
|
-
--dry-run Show what would be cleaned without doing it
|
|
59
|
-
--json Output in JSON format
|
|
60
|
-
--help, -h Show help message
|
|
61
|
-
|
|
62
|
-
EXAMPLES:
|
|
63
|
-
worktree-cleanup.sh REQ-123 # Clean specific worktree
|
|
64
|
-
worktree-cleanup.sh --merged # Clean all merged worktrees
|
|
65
|
-
worktree-cleanup.sh --merged --dry-run # Preview cleanup
|
|
66
|
-
EOF
|
|
67
|
-
exit 0
|
|
68
|
-
;;
|
|
69
|
-
-*)
|
|
70
|
-
echo "ERROR: Unknown option '$1'. Use --help for usage." >&2
|
|
71
|
-
exit 1
|
|
72
|
-
;;
|
|
73
|
-
*)
|
|
74
|
-
REQ_ID="$1"
|
|
75
|
-
shift
|
|
76
|
-
;;
|
|
77
|
-
esac
|
|
78
|
-
done
|
|
79
|
-
|
|
80
|
-
# =============================================================================
|
|
81
|
-
# Source Common Functions
|
|
82
|
-
# =============================================================================
|
|
83
|
-
|
|
84
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
85
|
-
COMMON_SH="$SCRIPT_DIR/../../../scripts/common.sh"
|
|
86
|
-
|
|
87
|
-
if [[ -f "$COMMON_SH" ]]; then
|
|
88
|
-
source "$COMMON_SH"
|
|
89
|
-
fi
|
|
90
|
-
|
|
91
|
-
# =============================================================================
|
|
92
|
-
# Get Main Repo
|
|
93
|
-
# =============================================================================
|
|
94
|
-
|
|
95
|
-
MAIN_REPO=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
96
|
-
if [[ -z "$MAIN_REPO" ]]; then
|
|
97
|
-
echo "ERROR: Not in a git repository" >&2
|
|
98
|
-
exit 1
|
|
99
|
-
fi
|
|
100
|
-
|
|
101
|
-
REPO_NAME=$(basename "$MAIN_REPO")
|
|
102
|
-
|
|
103
|
-
# =============================================================================
|
|
104
|
-
# Cleanup Functions
|
|
105
|
-
# =============================================================================
|
|
106
|
-
|
|
107
|
-
cleanup_worktree() {
|
|
108
|
-
local path="$1"
|
|
109
|
-
local branch="$2"
|
|
110
|
-
local force_flag=""
|
|
111
|
-
|
|
112
|
-
if $FORCE; then
|
|
113
|
-
force_flag="--force"
|
|
114
|
-
fi
|
|
115
|
-
|
|
116
|
-
if $DRY_RUN; then
|
|
117
|
-
if ! $JSON_MODE; then
|
|
118
|
-
echo "[DRY-RUN] Would remove: $path (branch: $branch)"
|
|
119
|
-
fi
|
|
120
|
-
return 0
|
|
121
|
-
fi
|
|
122
|
-
|
|
123
|
-
# Remove worktree
|
|
124
|
-
git -C "$MAIN_REPO" worktree remove "$path" $force_flag 2>/dev/null || {
|
|
125
|
-
if $FORCE; then
|
|
126
|
-
rm -rf "$path"
|
|
127
|
-
else
|
|
128
|
-
echo "ERROR: Failed to remove worktree $path" >&2
|
|
129
|
-
return 1
|
|
130
|
-
fi
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
# Delete branch if not main/master
|
|
134
|
-
if [[ "$branch" != "main" && "$branch" != "master" && -n "$branch" && "$branch" != "(detached)" ]]; then
|
|
135
|
-
if $FORCE; then
|
|
136
|
-
git -C "$MAIN_REPO" branch -D "$branch" 2>/dev/null || true
|
|
137
|
-
else
|
|
138
|
-
git -C "$MAIN_REPO" branch -d "$branch" 2>/dev/null || true
|
|
139
|
-
fi
|
|
140
|
-
fi
|
|
141
|
-
|
|
142
|
-
if ! $JSON_MODE; then
|
|
143
|
-
echo "Removed: $path (branch: $branch)"
|
|
144
|
-
fi
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
# =============================================================================
|
|
148
|
-
# Main Logic
|
|
149
|
-
# =============================================================================
|
|
150
|
-
|
|
151
|
-
if [[ -n "$REQ_ID" ]]; then
|
|
152
|
-
# Clean specific worktree
|
|
153
|
-
REQ_ID=$(echo "$REQ_ID" | tr '[:lower:]' '[:upper:]')
|
|
154
|
-
WORKTREE_DIR="$(dirname "$MAIN_REPO")/${REPO_NAME}-${REQ_ID}"
|
|
155
|
-
|
|
156
|
-
if [[ ! -d "$WORKTREE_DIR" ]]; then
|
|
157
|
-
if $JSON_MODE; then
|
|
158
|
-
printf '{"error":"not_found","path":"%s"}\n' "$WORKTREE_DIR"
|
|
159
|
-
else
|
|
160
|
-
echo "ERROR: Worktree not found: $WORKTREE_DIR" >&2
|
|
161
|
-
fi
|
|
162
|
-
exit 1
|
|
163
|
-
fi
|
|
164
|
-
|
|
165
|
-
# Get branch name
|
|
166
|
-
BRANCH=$(git -C "$WORKTREE_DIR" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
|
|
167
|
-
|
|
168
|
-
cleanup_worktree "$WORKTREE_DIR" "$BRANCH"
|
|
169
|
-
|
|
170
|
-
if $JSON_MODE; then
|
|
171
|
-
printf '{"cleaned":[{"path":"%s","branch":"%s"}]}\n' "$WORKTREE_DIR" "$BRANCH"
|
|
172
|
-
fi
|
|
173
|
-
|
|
174
|
-
elif $MERGED_ONLY; then
|
|
175
|
-
# Clean all merged worktrees
|
|
176
|
-
cleaned=()
|
|
177
|
-
|
|
178
|
-
while IFS= read -r line; do
|
|
179
|
-
if [[ "$line" =~ ^worktree ]]; then
|
|
180
|
-
path="${line#worktree }"
|
|
181
|
-
elif [[ "$line" =~ ^branch ]]; then
|
|
182
|
-
branch="${line#branch refs/heads/}"
|
|
183
|
-
|
|
184
|
-
# Skip main repo
|
|
185
|
-
if [[ "$path" == "$MAIN_REPO" ]]; then
|
|
186
|
-
continue
|
|
187
|
-
fi
|
|
188
|
-
|
|
189
|
-
# Check if branch is merged into main
|
|
190
|
-
if git -C "$MAIN_REPO" branch --merged main 2>/dev/null | grep -q "^\s*$branch$"; then
|
|
191
|
-
cleanup_worktree "$path" "$branch"
|
|
192
|
-
cleaned+=("$path")
|
|
193
|
-
fi
|
|
194
|
-
fi
|
|
195
|
-
done < <(git worktree list --porcelain)
|
|
196
|
-
|
|
197
|
-
if $JSON_MODE; then
|
|
198
|
-
printf '{"cleaned":['
|
|
199
|
-
first=true
|
|
200
|
-
for p in "${cleaned[@]}"; do
|
|
201
|
-
if ! $first; then printf ','; fi
|
|
202
|
-
first=false
|
|
203
|
-
printf '"%s"' "$p"
|
|
204
|
-
done
|
|
205
|
-
printf ']}\n'
|
|
206
|
-
else
|
|
207
|
-
if [[ ${#cleaned[@]} -eq 0 ]]; then
|
|
208
|
-
echo "No merged worktrees to clean up."
|
|
209
|
-
else
|
|
210
|
-
echo ""
|
|
211
|
-
echo "Cleaned ${#cleaned[@]} worktree(s)."
|
|
212
|
-
fi
|
|
213
|
-
fi
|
|
214
|
-
|
|
215
|
-
else
|
|
216
|
-
echo "ERROR: Specify REQ_ID or use --merged flag. Use --help for usage." >&2
|
|
217
|
-
exit 1
|
|
218
|
-
fi
|
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# =============================================================================
|
|
3
|
-
# worktree-create.sh - Create a new git worktree for requirement development
|
|
4
|
-
# =============================================================================
|
|
5
|
-
#
|
|
6
|
-
# Usage: worktree-create.sh REQ_ID [TITLE] [OPTIONS]
|
|
7
|
-
#
|
|
8
|
-
# ARGUMENTS:
|
|
9
|
-
# REQ_ID Requirement ID (REQ-XXX or BUG-XXX format)
|
|
10
|
-
# TITLE Optional title for branch naming
|
|
11
|
-
#
|
|
12
|
-
# OPTIONS:
|
|
13
|
-
# --existing-branch Use existing branch instead of creating new one
|
|
14
|
-
# --force Force creation even if worktree exists
|
|
15
|
-
# --json Output in JSON format
|
|
16
|
-
# --help, -h Show help message
|
|
17
|
-
#
|
|
18
|
-
# EXAMPLES:
|
|
19
|
-
# worktree-create.sh REQ-123 "User Authentication"
|
|
20
|
-
# worktree-create.sh REQ-123 --existing-branch
|
|
21
|
-
# worktree-create.sh BUG-456 "Fix Login Issue"
|
|
22
|
-
#
|
|
23
|
-
# [PROTOCOL]: 变更时更新此头部,然后检查 CLAUDE.md
|
|
24
|
-
|
|
25
|
-
set -e
|
|
26
|
-
|
|
27
|
-
# =============================================================================
|
|
28
|
-
# Argument Parsing
|
|
29
|
-
# =============================================================================
|
|
30
|
-
|
|
31
|
-
REQ_ID=""
|
|
32
|
-
TITLE=""
|
|
33
|
-
EXISTING_BRANCH=false
|
|
34
|
-
FORCE=false
|
|
35
|
-
JSON_MODE=false
|
|
36
|
-
|
|
37
|
-
while [[ $# -gt 0 ]]; do
|
|
38
|
-
case "$1" in
|
|
39
|
-
--existing-branch)
|
|
40
|
-
EXISTING_BRANCH=true
|
|
41
|
-
shift
|
|
42
|
-
;;
|
|
43
|
-
--force)
|
|
44
|
-
FORCE=true
|
|
45
|
-
shift
|
|
46
|
-
;;
|
|
47
|
-
--json)
|
|
48
|
-
JSON_MODE=true
|
|
49
|
-
shift
|
|
50
|
-
;;
|
|
51
|
-
--help|-h)
|
|
52
|
-
cat << 'EOF'
|
|
53
|
-
Usage: worktree-create.sh REQ_ID [TITLE] [OPTIONS]
|
|
54
|
-
|
|
55
|
-
Create a new git worktree for requirement development.
|
|
56
|
-
|
|
57
|
-
ARGUMENTS:
|
|
58
|
-
REQ_ID Requirement ID (REQ-XXX or BUG-XXX format)
|
|
59
|
-
TITLE Optional title for branch naming
|
|
60
|
-
|
|
61
|
-
OPTIONS:
|
|
62
|
-
--existing-branch Use existing branch instead of creating new one
|
|
63
|
-
--force Force creation even if worktree exists
|
|
64
|
-
--json Output in JSON format
|
|
65
|
-
--help, -h Show help message
|
|
66
|
-
|
|
67
|
-
EXAMPLES:
|
|
68
|
-
worktree-create.sh REQ-123 "User Authentication"
|
|
69
|
-
worktree-create.sh REQ-123 --existing-branch
|
|
70
|
-
worktree-create.sh BUG-456 "Fix Login Issue"
|
|
71
|
-
EOF
|
|
72
|
-
exit 0
|
|
73
|
-
;;
|
|
74
|
-
-*)
|
|
75
|
-
echo "ERROR: Unknown option '$1'. Use --help for usage." >&2
|
|
76
|
-
exit 1
|
|
77
|
-
;;
|
|
78
|
-
*)
|
|
79
|
-
if [[ -z "$REQ_ID" ]]; then
|
|
80
|
-
REQ_ID="$1"
|
|
81
|
-
elif [[ -z "$TITLE" ]]; then
|
|
82
|
-
TITLE="$1"
|
|
83
|
-
else
|
|
84
|
-
echo "ERROR: Too many arguments. Use --help for usage." >&2
|
|
85
|
-
exit 1
|
|
86
|
-
fi
|
|
87
|
-
shift
|
|
88
|
-
;;
|
|
89
|
-
esac
|
|
90
|
-
done
|
|
91
|
-
|
|
92
|
-
# =============================================================================
|
|
93
|
-
# Source Common Functions
|
|
94
|
-
# =============================================================================
|
|
95
|
-
|
|
96
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
97
|
-
COMMON_SH="$SCRIPT_DIR/../../../scripts/common.sh"
|
|
98
|
-
|
|
99
|
-
if [[ -f "$COMMON_SH" ]]; then
|
|
100
|
-
source "$COMMON_SH"
|
|
101
|
-
else
|
|
102
|
-
echo "ERROR: common.sh not found at $COMMON_SH" >&2
|
|
103
|
-
exit 1
|
|
104
|
-
fi
|
|
105
|
-
|
|
106
|
-
# =============================================================================
|
|
107
|
-
# Validation
|
|
108
|
-
# =============================================================================
|
|
109
|
-
|
|
110
|
-
if [[ -z "$REQ_ID" ]]; then
|
|
111
|
-
echo "ERROR: REQ_ID is required. Use --help for usage." >&2
|
|
112
|
-
exit 1
|
|
113
|
-
fi
|
|
114
|
-
|
|
115
|
-
# Normalize to uppercase
|
|
116
|
-
REQ_ID=$(echo "$REQ_ID" | tr '[:lower:]' '[:upper:]')
|
|
117
|
-
|
|
118
|
-
# Validate format
|
|
119
|
-
validate_req_id "$REQ_ID" || exit 1
|
|
120
|
-
|
|
121
|
-
# =============================================================================
|
|
122
|
-
# Path Calculation
|
|
123
|
-
# =============================================================================
|
|
124
|
-
|
|
125
|
-
MAIN_REPO=$(get_main_repo_path)
|
|
126
|
-
if [[ -z "$MAIN_REPO" ]]; then
|
|
127
|
-
MAIN_REPO=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
128
|
-
fi
|
|
129
|
-
|
|
130
|
-
if [[ -z "$MAIN_REPO" ]]; then
|
|
131
|
-
echo "ERROR: Not in a git repository" >&2
|
|
132
|
-
exit 1
|
|
133
|
-
fi
|
|
134
|
-
|
|
135
|
-
REPO_NAME=$(basename "$MAIN_REPO")
|
|
136
|
-
WORKTREE_DIR="$(dirname "$MAIN_REPO")/${REPO_NAME}-${REQ_ID}"
|
|
137
|
-
|
|
138
|
-
# Determine branch name
|
|
139
|
-
REQ_TYPE=$(get_req_type "$REQ_ID")
|
|
140
|
-
if [[ -n "$TITLE" ]]; then
|
|
141
|
-
BRANCH_SUFFIX=$(slugify "$TITLE")
|
|
142
|
-
else
|
|
143
|
-
BRANCH_SUFFIX="dev"
|
|
144
|
-
fi
|
|
145
|
-
|
|
146
|
-
if [[ "$REQ_TYPE" == "bug" ]]; then
|
|
147
|
-
BRANCH_NAME="bugfix/${REQ_ID}-${BRANCH_SUFFIX}"
|
|
148
|
-
else
|
|
149
|
-
BRANCH_NAME="feature/${REQ_ID}-${BRANCH_SUFFIX}"
|
|
150
|
-
fi
|
|
151
|
-
|
|
152
|
-
# =============================================================================
|
|
153
|
-
# Pre-flight Checks
|
|
154
|
-
# =============================================================================
|
|
155
|
-
|
|
156
|
-
# Check if worktree already exists
|
|
157
|
-
if [[ -d "$WORKTREE_DIR" ]]; then
|
|
158
|
-
if $FORCE; then
|
|
159
|
-
if ! $JSON_MODE; then
|
|
160
|
-
echo "WARNING: Removing existing worktree at $WORKTREE_DIR" >&2
|
|
161
|
-
fi
|
|
162
|
-
git -C "$MAIN_REPO" worktree remove "$WORKTREE_DIR" --force 2>/dev/null || rm -rf "$WORKTREE_DIR"
|
|
163
|
-
else
|
|
164
|
-
if $JSON_MODE; then
|
|
165
|
-
printf '{"error":"worktree_exists","path":"%s"}\n' "$WORKTREE_DIR"
|
|
166
|
-
else
|
|
167
|
-
echo "ERROR: Worktree already exists at $WORKTREE_DIR" >&2
|
|
168
|
-
echo "Use --force to recreate or cd to existing worktree" >&2
|
|
169
|
-
fi
|
|
170
|
-
exit 1
|
|
171
|
-
fi
|
|
172
|
-
fi
|
|
173
|
-
|
|
174
|
-
# Check if branch is already checked out in another worktree
|
|
175
|
-
if ! $EXISTING_BRANCH; then
|
|
176
|
-
if git -C "$MAIN_REPO" rev-parse --verify "$BRANCH_NAME" >/dev/null 2>&1; then
|
|
177
|
-
# Branch exists, check if it's in use
|
|
178
|
-
BRANCH_WORKTREE=$(git -C "$MAIN_REPO" worktree list --porcelain | grep -A2 "branch refs/heads/$BRANCH_NAME" | head -1 | sed 's/worktree //')
|
|
179
|
-
if [[ -n "$BRANCH_WORKTREE" ]]; then
|
|
180
|
-
if $JSON_MODE; then
|
|
181
|
-
printf '{"error":"branch_in_use","branch":"%s","worktree":"%s"}\n' "$BRANCH_NAME" "$BRANCH_WORKTREE"
|
|
182
|
-
else
|
|
183
|
-
echo "ERROR: Branch $BRANCH_NAME is already checked out in $BRANCH_WORKTREE" >&2
|
|
184
|
-
fi
|
|
185
|
-
exit 1
|
|
186
|
-
fi
|
|
187
|
-
# Branch exists but not in use, use it
|
|
188
|
-
EXISTING_BRANCH=true
|
|
189
|
-
fi
|
|
190
|
-
fi
|
|
191
|
-
|
|
192
|
-
# =============================================================================
|
|
193
|
-
# Create Worktree
|
|
194
|
-
# =============================================================================
|
|
195
|
-
|
|
196
|
-
if ! $JSON_MODE; then
|
|
197
|
-
echo "Creating worktree for $REQ_ID..." >&2
|
|
198
|
-
fi
|
|
199
|
-
|
|
200
|
-
if $EXISTING_BRANCH; then
|
|
201
|
-
# Use existing branch
|
|
202
|
-
git -C "$MAIN_REPO" worktree add "$WORKTREE_DIR" "$BRANCH_NAME"
|
|
203
|
-
else
|
|
204
|
-
# Create new branch
|
|
205
|
-
git -C "$MAIN_REPO" worktree add -b "$BRANCH_NAME" "$WORKTREE_DIR"
|
|
206
|
-
fi
|
|
207
|
-
|
|
208
|
-
# =============================================================================
|
|
209
|
-
# Output
|
|
210
|
-
# =============================================================================
|
|
211
|
-
|
|
212
|
-
if $JSON_MODE; then
|
|
213
|
-
printf '{"req_id":"%s","worktree_dir":"%s","branch":"%s","main_repo":"%s","created_at":"%s"}\n' \
|
|
214
|
-
"$REQ_ID" \
|
|
215
|
-
"$WORKTREE_DIR" \
|
|
216
|
-
"$BRANCH_NAME" \
|
|
217
|
-
"$MAIN_REPO" \
|
|
218
|
-
"$(get_beijing_time_iso)"
|
|
219
|
-
else
|
|
220
|
-
echo ""
|
|
221
|
-
echo "✅ Worktree created successfully!"
|
|
222
|
-
echo ""
|
|
223
|
-
echo "Requirement ID: $REQ_ID"
|
|
224
|
-
echo "Worktree: $WORKTREE_DIR"
|
|
225
|
-
echo "Branch: $BRANCH_NAME"
|
|
226
|
-
echo "Main Repo: $MAIN_REPO"
|
|
227
|
-
echo ""
|
|
228
|
-
echo "Next Steps:"
|
|
229
|
-
echo " cd $WORKTREE_DIR"
|
|
230
|
-
echo " claude # Start new Claude Code session"
|
|
231
|
-
echo ""
|
|
232
|
-
fi
|