-
-
Notifications
You must be signed in to change notification settings - Fork 1k
feat(terminal): add worktree support for terminals #625
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
45f76b0
d9638a0
4b4e640
3d8f2b7
b5fdcb6
f11f2a3
bef4d2a
1ddaa01
db81736
8dfa230
8914a80
b06d325
48ec0cb
edbbf92
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -169,7 +169,15 @@ def handle_workspace_choice( | |
| if staging_path: | ||
| print(highlight(f" cd {staging_path}")) | ||
| else: | ||
| print(highlight(f" cd {project_dir}/.worktrees/{spec_name}")) | ||
| worktree_path = get_existing_build_worktree(project_dir, spec_name) | ||
| if worktree_path: | ||
| print(highlight(f" cd {worktree_path}")) | ||
| else: | ||
| print( | ||
| highlight( | ||
| f" cd {project_dir}/.auto-claude/worktrees/tasks/{spec_name}" | ||
| ) | ||
| ) | ||
|
Comment on lines
+172
to
+180
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, let's examine the finalization.py file around the specified lines
cat -n apps/backend/core/workspace/finalization.py | head -250 | tail -100Repository: AndyMik90/Auto-Claude Length of output: 4344 🏁 Script executed: # Find the get_existing_build_worktree function definition
rg -n "def get_existing_build_worktree" --type=py -A10Repository: AndyMik90/Auto-Claude Length of output: 936 🏁 Script executed: # Check callers of the function containing this code (appears to be in a larger function)
rg -n "handle_workspace_choice\|print.*worktree" --type=py -B3 -A3Repository: AndyMik90/Auto-Claude Length of output: 47 🏁 Script executed: # Look for worktree creation logic
rg -n "\.auto-claude/worktrees" --type=py -B2 -A2Repository: AndyMik90/Auto-Claude Length of output: 2740 🏁 Script executed: # Get full implementation of get_existing_build_worktree
rg -n "def get_existing_build_worktree" --type=py -A20Repository: AndyMik90/Auto-Claude Length of output: 1711 🏁 Script executed: # Check what get_worktree_info returns and when it might be None
rg -n "def get_worktree_info" --type=py -A15Repository: AndyMik90/Auto-Claude Length of output: 1175 🏁 Script executed: # Look for where worktrees are created
rg -n "def create_worktree\|def setup.*worktree" --type=py -A10Repository: AndyMik90/Auto-Claude Length of output: 47 🏁 Script executed: # Check the broader context around handle_workspace_choice - what calls it and when
rg -n "handle_workspace_choice" --type=py -B5 -A2Repository: AndyMik90/Auto-Claude Length of output: 3753 🏁 Script executed: # Check context of when handle_workspace_choice is called - is worktree guaranteed to exist at this point?
rg -n "handle_workspace_choice" --type=py -B10 | head -50Repository: AndyMik90/Auto-Claude Length of output: 2995 🏁 Script executed: # Check finalize_workspace to see if it creates the worktree
rg -n "def finalize_workspace" --type=py -A30Repository: AndyMik90/Auto-Claude Length of output: 2591 🏁 Script executed: # Check if there are any tests or documentation about the edge case
rg -n "get_worktree_info\|get_existing_build_worktree" --type=py -B2 -A8 | grep -A8 "returns None\|returncode"Repository: AndyMik90/Auto-Claude Length of output: 47 🏁 Script executed: # Look at what could cause get_worktree_info to return None despite path existing
rg -n "rev-parse.*HEAD\|returncode != 0" --type=py -B5 -A3Repository: AndyMik90/Auto-Claude Length of output: 47 🏁 Script executed: # Check if the fallback path is ever actually relied upon or if it's purely defensive
rg -n "\.auto-claude/worktrees/tasks" --type=py | head -20Repository: AndyMik90/Auto-Claude Length of output: 887 🏁 Script executed: # Let's check if there's any error handling after this code is printed
rg -n "cd {worktree" --type=py -A10 | head -40Repository: AndyMik90/Auto-Claude Length of output: 163 🏁 Script executed: # Check if there are any comments or documentation about this fallback behavior
rg -n "fallback\|edge case" --type=py apps/backend/core/workspace/Repository: AndyMik90/Auto-Claude Length of output: 47 🏁 Script executed: # Let's check what happens after handle_workspace_choice is called
rg -n "handle_workspace_choice" --type=py -A5Repository: AndyMik90/Auto-Claude Length of output: 2719 🏁 Script executed: # Check the actual scenario: when would staging_path be None but we still want to show the path?
cat -n apps/backend/core/workspace/finalization.py | sed -n '145,160p'Repository: AndyMik90/Auto-Claude Length of output: 678 🏁 Script executed: # Let's look at the full context of the TEST and LATER branches to understand the intent
cat -n apps/backend/core/workspace/finalization.py | sed -n '156,200p'Repository: AndyMik90/Auto-Claude Length of output: 1932 🏁 Script executed: # Let's understand the complete flow - check what happens in worktree.py get_worktree_info more carefully
cat -n apps/backend/core/worktree.py | sed -n '213,235p'Repository: AndyMik90/Auto-Claude Length of output: 1011 🏁 Script executed: # Also check if there's any guarantee that the worktree must exist at this point
cat -n apps/backend/cli/build_commands.py | sed -n '280,300p'Repository: AndyMik90/Auto-Claude Length of output: 996 Add validation or warning for the fallback worktree path that may not exist. When both Consider one of these approaches:
This affects both the TEST branch (lines 176-180) and LATER branch (lines 247-251). 🤖 Prompt for AI Agents |
||
|
|
||
| # Show likely test/run commands | ||
| if staging_path: | ||
|
|
@@ -232,7 +240,15 @@ def handle_workspace_choice( | |
| if staging_path: | ||
| print(highlight(f" cd {staging_path}")) | ||
| else: | ||
| print(highlight(f" cd {project_dir}/.worktrees/{spec_name}")) | ||
| worktree_path = get_existing_build_worktree(project_dir, spec_name) | ||
| if worktree_path: | ||
| print(highlight(f" cd {worktree_path}")) | ||
| else: | ||
| print( | ||
| highlight( | ||
| f" cd {project_dir}/.auto-claude/worktrees/tasks/{spec_name}" | ||
| ) | ||
| ) | ||
| print() | ||
| print("When you're ready to add it:") | ||
| print(highlight(f" python auto-claude/run.py --spec {spec_name} --merge")) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -222,10 +222,16 @@ def get_existing_build_worktree(project_dir: Path, spec_name: str) -> Path | Non | |
| Returns: | ||
| Path to the worktree if it exists for this spec, None otherwise | ||
| """ | ||
| # Per-spec worktree path: .worktrees/{spec-name}/ | ||
| worktree_path = project_dir / ".worktrees" / spec_name | ||
| if worktree_path.exists(): | ||
| return worktree_path | ||
| # New path first | ||
| new_path = project_dir / ".auto-claude" / "worktrees" / "tasks" / spec_name | ||
| if new_path.exists(): | ||
| return new_path | ||
|
|
||
| # Legacy fallback | ||
| legacy_path = project_dir / ".worktrees" / spec_name | ||
| if legacy_path.exists(): | ||
| return legacy_path | ||
|
|
||
|
Comment on lines
+225
to
+234
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Good backward compatibility fix, but add migration logging. The two-step lookup correctly restores backward compatibility with the legacy 🔎 Proposed enhancement to log legacy path detectionAdd logging when the legacy path is detected to inform users about the migration: +import logging
+
+logger = logging.getLogger(__name__)
+
def get_existing_build_worktree(project_dir: Path, spec_name: str) -> Path | None:
"""
Check if there's an existing worktree for this specific spec.
Args:
project_dir: The main project directory
spec_name: The spec folder name (e.g., "001-feature-name")
Returns:
Path to the worktree if it exists for this spec, None otherwise
"""
# New path first
new_path = project_dir / ".auto-claude" / "worktrees" / "tasks" / spec_name
if new_path.exists():
return new_path
# Legacy fallback
legacy_path = project_dir / ".worktrees" / spec_name
if legacy_path.exists():
+ logger.warning(
+ f"Found worktree at deprecated location: {legacy_path}. "
+ f"Consider migrating to: {new_path}"
+ )
return legacy_path
return None🤖 Prompt for AI Agents |
||
| return None | ||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -249,7 +249,7 @@ def get_next_spec_number(self) -> int: | |
| max_number = max(max_number, self._scan_specs_dir(main_specs_dir)) | ||
|
|
||
| # 2. Scan all worktree specs | ||
| worktrees_dir = self.project_dir / ".worktrees" | ||
| worktrees_dir = self.project_dir / ".auto-claude" / "worktrees" / "tasks" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, examine the file structure and the specific line mentioned
cd /tmp && find . -name "models.py" -path "*/workspace/*" 2>/dev/null | head -5Repository: AndyMik90/Auto-Claude Length of output: 47 🏁 Script executed: # Let me check the actual file from the context of the review
head -n 1 /dev/null && echo "Ready to investigate"Repository: AndyMik90/Auto-Claude Length of output: 85 🏁 Script executed: # Get the git repository structure to find the file
find . -name "models.py" -path "*/core/workspace/*" 2>/dev/nullRepository: AndyMik90/Auto-Claude Length of output: 104 🏁 Script executed: # List Python files in core/workspace to understand structure
fd "\.py$" "apps/backend/core/workspace" 2>/dev/null | head -20Repository: AndyMik90/Auto-Claude Length of output: 303 🏁 Script executed: # Check the actual line 252 and surrounding context
cat -n apps/backend/core/workspace/models.py | sed -n '240,265p'Repository: AndyMik90/Auto-Claude Length of output: 1214 🏁 Script executed: # Search for worktree-related code and path handling
rg "worktrees_dir|\.worktrees" apps/backend/core/workspace/ -A 3 -B 3Repository: AndyMik90/Auto-Claude Length of output: 887 🏁 Script executed: # Look for migration or backward compatibility code
rg "migration|backward|compat|old.*location" apps/backend/ -iRepository: AndyMik90/Auto-Claude Length of output: 48145 🏁 Script executed: # Check for spec number calculation logic
rg "spec.*number|get_next_spec|worktree.*spec" apps/backend/ -i -A 5Repository: AndyMik90/Auto-Claude Length of output: 46364 🏁 Script executed: # Look for references to the old .worktrees location
rg "\.worktrees" apps/backend/ --type pyRepository: AndyMik90/Auto-Claude Length of output: 870 🏁 Script executed: # Check CLAUDE.md for worktree-related guidance
cat CLAUDE.md | head -100Repository: AndyMik90/Auto-Claude Length of output: 2929 🏁 Script executed: # Look for any migration scripts or documentation
find . -name "*migrat*" -o -name "*MIGRATION*" -o -name "*upgrade*" | grep -v node_modules | grep -v ".git"Repository: AndyMik90/Auto-Claude Length of output: 188 🏁 Script executed: # Check git history for this specific line to understand if it changed
git log -p --all -S '.worktrees' -- apps/backend/core/workspace/ 2>/dev/null | head -100Repository: AndyMik90/Auto-Claude Length of output: 47 🏁 Script executed: # Look for any references in README or documentation
find . -name "README*" -o -name "*.md" | xargs grep -l "worktree" 2>/dev/null | head -10Repository: AndyMik90/Auto-Claude Length of output: 365 🏁 Script executed: # Check if there's any old .worktrees directory handling in the codebase
rg "worktrees_dir|old.*location|backward.*compat" apps/backend/core/workspace/ -B 2 -A 2Repository: AndyMik90/Auto-Claude Length of output: 3114 🏁 Script executed: # Check CHANGELOG for context about the worktree path change
grep -A 5 -B 5 "worktree\|\.auto-claude\|\.worktrees" CHANGELOG.md 2>/dev/null | head -50Repository: AndyMik90/Auto-Claude Length of output: 1558 🏁 Script executed: # Check if there are any warnings or migration notes in README
grep -A 10 -B 2 "migration\|worktree" README.md 2>/dev/null | head -80Repository: AndyMik90/Auto-Claude Length of output: 952 🏁 Script executed: # Look for any test files that might show the expected behavior
find . -name "*test*" -type f -path "*/workspace/*" -o -path "*/worktree/*" | head -5Repository: AndyMik90/Auto-Claude Length of output: 47 Add fallback logic to scan old worktree location for spec number calculation or provide user migration guidance. The Since the PR description mentions removing backward-compatibility code, either:
Currently, no migration code or user guidance exists for this breaking change. |
||
| if worktrees_dir.exists(): | ||
| for worktree in worktrees_dir.iterdir(): | ||
| if worktree.is_dir(): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,29 +27,11 @@ def find_worktree(project_dir: Path, task_id: str) -> Path | None: | |
| Returns: | ||
| Path to the worktree, or None if not found | ||
| """ | ||
| # Check common locations | ||
| worktrees_dir = project_dir / ".worktrees" | ||
| worktrees_dir = project_dir / ".auto-claude" / "worktrees" / "tasks" | ||
| if worktrees_dir.exists(): | ||
| # Look for worktree with task_id in name | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inconsistent legacy worktree path fallback across modulesThe Additional Locations (1)
AndyMik90 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| for entry in worktrees_dir.iterdir(): | ||
| if entry.is_dir() and task_id in entry.name: | ||
| return entry | ||
|
|
||
| # Try git worktree list | ||
| try: | ||
| result = subprocess.run( | ||
| ["git", "worktree", "list", "--porcelain"], | ||
| cwd=project_dir, | ||
| capture_output=True, | ||
| text=True, | ||
| check=True, | ||
| ) | ||
| for line in result.stdout.split("\n"): | ||
| if line.startswith("worktree ") and task_id in line: | ||
| return Path(line.split(" ", 1)[1]) | ||
| except subprocess.CalledProcessError: | ||
| pass | ||
|
|
||
| return None | ||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -189,7 +189,14 @@ def get_worktree_file_content(self, task_id: str, file_path: str) -> str: | |||||||||||||||||||
| task_id.replace("task-", "") if task_id.startswith("task-") else task_id | ||||||||||||||||||||
| ) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| worktree_path = self.project_path / ".worktrees" / spec_name / file_path | ||||||||||||||||||||
| worktree_path = ( | ||||||||||||||||||||
| self.project_path | ||||||||||||||||||||
| / ".auto-claude" | ||||||||||||||||||||
| / "worktrees" | ||||||||||||||||||||
| / "tasks" | ||||||||||||||||||||
| / spec_name | ||||||||||||||||||||
| / file_path | ||||||||||||||||||||
| ) | ||||||||||||||||||||
|
Comment on lines
+192
to
+199
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Consider single-line path construction for consistency. The multi-line path construction here differs from the single-line style used consistently throughout the codebase (see 🔎 Proposed refactor for consistency- worktree_path = (
- self.project_path
- / ".auto-claude"
- / "worktrees"
- / "tasks"
- / spec_name
- / file_path
- )
+ worktree_path = self.project_path / ".auto-claude" / "worktrees" / "tasks" / spec_name / file_path📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||
| if worktree_path.exists(): | ||||||||||||||||||||
| try: | ||||||||||||||||||||
| return worktree_path.read_text(encoding="utf-8") | ||||||||||||||||||||
|
|
||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block of code to determine and print the worktree path is duplicated later in this file (lines 243-251). To improve maintainability and avoid future inconsistencies, consider extracting this logic into a helper function.