Skip to content

Commit 2754634

Browse files
authored
Merge pull request #32 from ai-ecoverse/feature/claude-builtin-worktree
Delegate worktree creation to claude's built-in --worktree
2 parents 9d08c33 + a1149f8 commit 2754634

2 files changed

Lines changed: 136 additions & 10 deletions

File tree

executable_yolo

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ Usage: yolo [OPTIONS] [command] [args...]
8181
8282
Options:
8383
-w, --worktree Create a git worktree in .yolo/ before running command
84+
(exception: 'claude' delegates to its built-in --worktree,
85+
which manages worktrees under .claude/worktrees/)
8486
-c, --clean Automatically clean up worktree after command completes
8587
-nc, --no-clean Preserve worktree after command completes (no prompt)
8688
-e, --editor Launch \$EDITOR to compose prompt (works in all modes)
@@ -132,21 +134,26 @@ Examples:
132134
yolo -e -a # Compose prompt in editor, run all agents
133135
yolo -e claude # Compose prompt in editor, run claude
134136
yolo claude # Run claude with --dangerously-skip-permissions
135-
yolo -w claude "fix the bug" # Create worktree, then run claude (prompt for cleanup)
136-
yolo -w -c claude "experiment" # Create worktree, auto-cleanup after
137-
yolo -w -nc claude "keep this" # Create worktree, preserve it after
137+
yolo -w claude "fix the bug" # Use claude's built-in --worktree (claude manages it)
138+
yolo -w -c claude "experiment" # Use claude's built-in --worktree (claude manages it)
139+
yolo -w -nc claude "keep this" # Use claude's built-in --worktree (claude manages it)
138140
yolo -e codex,claude,gemini # Compose prompt in editor, run 3 agents in parallel
139141
yolo copilot chat # Run copilot chat with safety flags disabled
140142
yolo aider "add auth" # Run aider with auto-approval
141143
yolo -w aider "implement feature" # Create worktree, run aider with prompt
142144
143145
Worktree Mode:
144-
When using -w/--worktree flag:
146+
When using -w/--worktree flag (for all commands except 'claude'):
145147
- Creates .yolo/ directory in repository root
146148
- Creates branch: <command>-N (where N is the lowest available number)
147149
- Creates worktree: .yolo/<command>-N
148150
- Changes to worktree directory before running command
149151
152+
When using -w/--worktree flag with 'claude':
153+
- Delegates worktree management to claude's built-in --worktree flag
154+
- Claude creates worktrees under .claude/worktrees/ with its own naming
155+
- Claude handles worktree cleanup; yolo's -c/-nc flags do not apply
156+
150157
Cleanup Mode:
151158
When using -m/--mop flag:
152159
- Removes all .yolo/ worktrees
@@ -1557,12 +1564,25 @@ main() {
15571564
print_info "Will attempt to run it anyway..."
15581565
fi
15591566

1560-
# Create worktree if requested
1567+
# Track whether yolo is managing the worktree itself
1568+
# claude has built-in --worktree support, so we delegate to it rather than
1569+
# creating our own worktree
1570+
local yolo_managed_worktree=false
15611571
if [[ "$use_worktree" == "true" ]]; then
1562-
if ! create_worktree "$command_name"; then
1563-
exit 1
1572+
if [[ "$command_name" == "claude" ]]; then
1573+
print_info "Delegating worktree management to claude's built-in --worktree support"
1574+
# Claude handles its own worktree lifecycle, so yolo's -c/-nc
1575+
# cleanup flags do not apply in this mode.
1576+
if [[ -n "$auto_clean" ]]; then
1577+
print_warning "-c/--clean and -nc/--no-clean are ignored with 'claude -w' (claude manages cleanup)"
1578+
fi
1579+
else
1580+
if ! create_worktree "$command_name"; then
1581+
exit 1
1582+
fi
1583+
# create_worktree sets YOLO_BRANCH_NAME, YOLO_WORKTREE_PATH, YOLO_REPO_ROOT
1584+
yolo_managed_worktree=true
15641585
fi
1565-
# create_worktree sets YOLO_BRANCH_NAME, YOLO_WORKTREE_PATH, YOLO_REPO_ROOT
15661586
fi
15671587

15681588
# Build the final command (single-agent mode) with agent-specific argument semantics
@@ -1720,6 +1740,27 @@ main() {
17201740
full_command+=("--print" "$prompt_joined")
17211741
fi
17221742
;;
1743+
claude)
1744+
# claude has native --worktree support; when -w is requested we
1745+
# delegate worktree creation/cleanup to claude itself rather than
1746+
# creating one with yolo's own logic.
1747+
if [[ -n "$flags" ]]; then
1748+
# shellcheck disable=SC2206
1749+
local flag_array=($flags)
1750+
full_command+=("${flag_array[@]}")
1751+
fi
1752+
if [[ "$use_worktree" == "true" ]]; then
1753+
full_command+=("--worktree")
1754+
# --worktree takes an optional [name]; use -- to stop option
1755+
# parsing so the first prompt arg isn't consumed as the name.
1756+
if (( ${#command_args[@]} )); then
1757+
full_command+=("--")
1758+
fi
1759+
fi
1760+
if (( ${#command_args[@]} )); then
1761+
full_command+=("${command_args[@]}")
1762+
fi
1763+
;;
17231764
*)
17241765
if [[ -n "$flags" ]]; then
17251766
# shellcheck disable=SC2206
@@ -1748,8 +1789,9 @@ main() {
17481789
"${full_command[@]}"
17491790
local exit_code=$?
17501791

1751-
# Handle cleanup if worktree was created
1752-
if [[ "$use_worktree" == "true" && -n "$YOLO_BRANCH_NAME" ]]; then
1792+
# Handle cleanup if yolo created the worktree
1793+
# (claude's built-in --worktree manages its own cleanup)
1794+
if [[ "$yolo_managed_worktree" == "true" && -n "$YOLO_BRANCH_NAME" ]]; then
17531795
if [[ "$auto_clean" == "yes" ]]; then
17541796
# Automatic cleanup
17551797
cleanup_worktree "$YOLO_BRANCH_NAME" "$YOLO_WORKTREE_PATH" "$YOLO_REPO_ROOT"

test.sh

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,89 @@ EOF
442442
rm -f "$test_cmd"
443443
}
444444

445+
# Test 9: Test yolo -w claude delegates to claude's built-in --worktree
446+
test_claude_builtin_worktree() {
447+
print_test_header "Test 9: Claude Built-in Worktree Delegation"
448+
449+
# Create a temporary git repository for testing
450+
local test_repo="/tmp/yolo_test_claude_$$"
451+
mkdir -p "$test_repo"
452+
cd "$test_repo"
453+
454+
# Initialize git repo
455+
git init -q
456+
git config user.email "test@example.com"
457+
git config user.name "Test User"
458+
echo "test" > README.md
459+
git add README.md
460+
git commit -q -m "Initial commit"
461+
462+
# Create a dummy claude command that echoes args (so we can assert pass-through)
463+
local claude_cmd="/tmp/claude"
464+
cat > "$claude_cmd" << 'EOF'
465+
#!/bin/bash
466+
echo "Running in: $PWD"
467+
echo "Args: $@"
468+
EOF
469+
chmod +x "$claude_cmd"
470+
471+
# Assertion 1: --worktree is passed through when -w is set
472+
run_test
473+
local output
474+
if output=$(PATH="/tmp:$PATH" run_with_timeout "$YOLO_TEST_TIMEOUT" "$YOLO_CMD" -w claude "fix the bug" 2>&1); then
475+
if echo "$output" | grep -F -q -- "--worktree"; then
476+
print_pass "yolo -w claude passes through --worktree flag"
477+
else
478+
print_fail "yolo -w claude should pass --worktree (got: $output)"
479+
fi
480+
else
481+
print_fail "yolo -w claude failed to run"
482+
fi
483+
484+
# Assertion 2: -- separator precedes the prompt so commander does not eat it
485+
run_test
486+
if echo "$output" | grep -F -q -- "--worktree -- fix the bug"; then
487+
print_pass "yolo -w claude inserts -- before prompt to preserve it"
488+
else
489+
print_fail "yolo -w claude should insert -- before prompt (got: $output)"
490+
fi
491+
492+
# Assertion 3: yolo did NOT create a .yolo/ directory
493+
run_test
494+
if [[ ! -d "$test_repo/.yolo" ]]; then
495+
print_pass "yolo -w claude does not create .yolo/ worktree directory"
496+
else
497+
print_fail "yolo -w claude should not create .yolo/ directory"
498+
fi
499+
500+
# Assertion 4: yolo did NOT create a git worktree
501+
run_test
502+
local wt_count
503+
wt_count=$(git worktree list | wc -l | tr -d ' ')
504+
if [[ "$wt_count" == "1" ]]; then
505+
print_pass "yolo -w claude does not invoke git worktree add"
506+
else
507+
print_fail "yolo -w claude should not create a git worktree (found $wt_count)"
508+
fi
509+
510+
# Assertion 5: yolo claude (without -w) does NOT pass --worktree
511+
run_test
512+
if output=$(PATH="/tmp:$PATH" run_with_timeout "$YOLO_TEST_TIMEOUT" "$YOLO_CMD" claude "hello" 2>&1); then
513+
if ! echo "$output" | grep -F -q -- "--worktree"; then
514+
print_pass "yolo claude (no -w) does not pass --worktree"
515+
else
516+
print_fail "yolo claude should not pass --worktree without -w (got: $output)"
517+
fi
518+
else
519+
print_fail "yolo claude failed to run"
520+
fi
521+
522+
# Cleanup
523+
cd /tmp
524+
rm -rf "$test_repo"
525+
rm -f "$claude_cmd"
526+
}
527+
445528
# Print summary
446529
print_summary() {
447530
echo ""
@@ -483,6 +566,7 @@ main() {
483566
test_worktree_creation
484567
test_worktree_no_git_error
485568
test_argument_preservation
569+
test_claude_builtin_worktree
486570

487571
print_summary
488572
}

0 commit comments

Comments
 (0)