-
-
Notifications
You must be signed in to change notification settings - Fork 985
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
Conversation
- Add WorktreeSelector dropdown to choose existing worktrees or create new - Fix terminal "process exited with code 1" when creating worktree by properly resetting usePtyProcess refs via resetForRecreate() - Use effectiveCwd from store to detect cwd changes for PTY recreation - Read project settings mainBranch for default branch instead of auto-detect - Add i18n translations for worktree selector (en/fr) The PTY recreation issue was caused by usePtyProcess having its own internal refs that weren't reset when Terminal.tsx destroyed the PTY. Now the hook exposes resetForRecreate() and tracks cwd changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
… commits Follow-up PR reviews were incorrectly flagging issues from OTHER PRs when authors merged develop/main into their feature branch. The commit comparison included all commits in the merge, not just the PR's own work. Changes: - Add get_pr_files() and get_pr_commits() to gh_client.py to fetch PR-scoped data from GitHub's PR endpoints (excludes merge-introduced changes) - Update FollowupContextGatherer to use PR-scoped methods with fallback - Add nuanced "PR Scope and Context" guidance to all review agent prompts distinguishing between: - In scope: issues in changed code, impact on other code, missing updates - Out of scope: pre-existing bugs, code from other PRs via merge commits The prompts now allow reviewers to flag "you changed X but forgot Y" while rejecting "old code in legacy.ts has a bug" false positives. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughRehomes per-spec worktrees from Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User
participant TerminalUI as Terminal UI
participant Dialog as CreateWorktreeDialog
participant Preload as Electron Preload API
participant Main as Main Process IPC
participant Git as Git
participant FS as FileSystem
User->>TerminalUI: Click "Create Worktree"
TerminalUI->>Dialog: open()
Dialog->>Preload: request branches
Preload->>Main: IPC -> fetch branches
Main->>Git: git branch list / remote lookup
Git-->>Main: branch list
Main-->>Preload: branches
Preload-->>Dialog: branches + default
User->>Dialog: submit create request
Dialog->>Preload: createTerminalWorktree(request)
Preload->>Main: IPC -> create request
Main->>FS: mkdir -p .auto-claude/worktrees/tasks/{name}
Main->>Git: git worktree add [--branch] {path}
Git-->>Main: created
Main->>FS: write config.json
Main-->>Preload: success + config
Preload-->>TerminalUI: notify created
TerminalUI->>usePtyProcess: prepareForRecreate()
TerminalUI->>usePtyProcess: resetForRecreate()
sequenceDiagram
autonumber
participant ContextGatherer
participant GHClient
participant GitHubAPI as GitHub API
participant DiffBuilder
ContextGatherer->>GHClient: get_pr_files_changed_since(pr, base_sha)
GHClient->>GitHubAPI: GET /pulls/{pr}/files (paginated)
GitHubAPI-->>GHClient: files (with blob SHAs)
GHClient->>GitHubAPI: GET /pulls/{pr}/commits (paginated)
GitHubAPI-->>GHClient: commits
GHClient->>GHClient: locate base_sha in commits
alt base found
GHClient->>ContextGatherer: pr_files + commits_after_base
else base not found
GHClient->>ContextGatherer: pr_files + all_commits (warn)
end
ContextGatherer->>DiffBuilder: build diff_since_review using pr_files and commits
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (10)
🧰 Additional context used📓 Path-based instructions (4)apps/frontend/src/**/*.{ts,tsx,jsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
apps/frontend/src/**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
apps/frontend/**/*.{ts,tsx}⚙️ CodeRabbit configuration file
Files:
apps/backend/**/*.py📄 CodeRabbit inference engine (CLAUDE.md)
Files:
⚙️ CodeRabbit configuration file
Files:
🧠 Learnings (2)📓 Common learnings📚 Learning: 2025-12-30T16:38:36.314ZApplied to files:
🧬 Code graph analysis (6)apps/backend/runners/github/orchestrator.py (2)
apps/backend/runners/github/context_gatherer.py (2)
apps/backend/runners/github/services/parallel_orchestrator_reviewer.py (1)
apps/backend/runners/github/services/followup_reviewer.py (2)
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts (2)
apps/backend/runners/github/services/parallel_followup_reviewer.py (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
🔇 Additional comments (15)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @AndyMik90, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces robust support for Git worktrees within the terminal environment, enabling developers to create isolated development spaces directly from the UI. This significantly enhances workflow flexibility by allowing users to quickly spin up dedicated environments for tasks or features, complete with optional branch creation and task linking. Additionally, it refines the underlying Git integration by consolidating worktree storage paths and improving the accuracy of PR context gathering for review agents, ensuring that only relevant changes are considered during follow-up reviews. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
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.
Code Review
This pull request introduces a significant and well-executed feature for terminal worktrees, allowing for isolated development environments. The changes are comprehensive, spanning the frontend, backend, and Python scripts, and include a thoughtful consolidation of worktree storage paths and removal of legacy code. The new UI components for creating and selecting worktrees are a great addition, and the fix for the PTY recreation bug is clever. My review includes a couple of minor suggestions to improve maintainability and fix a small validation inconsistency, but overall, this is excellent work.
| 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}" | ||
| ) | ||
| ) |
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.
| .toLowerCase() | ||
| .replace(/[^a-z0-9-_]/g, '-') | ||
| .replace(/-+/g, '-') | ||
| .replace(/^-|-$/g, ''); |
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.
The sanitization logic here doesn't fully align with the validation regex used in handleCreate. Specifically, this sanitization removes leading/trailing hyphens but not underscores. If a user enters a name like _my-feature_, it will pass this sanitization but then fail the validation regex (/^[a-z0-9][a-z0-9_-]*[a-z0-9]$|^[a-z0-9]$/), which disallows leading/trailing underscores.
To make this more robust, you could update the sanitization to also handle leading/trailing underscores.
| .replace(/^-|-$/g, ''); | |
| .replace(/^[_-]+|[_-]+$/g, ''); |
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.
Actionable comments posted: 22
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
apps/frontend/src/renderer/components/settings/integrations/GitHubIntegration.tsx (1)
211-213: Update GitHubIntegration.tsx to use i18n translations instead of hardcoded strings.This component contains numerous hardcoded English strings that violate the coding guideline requiring i18n translation keys for all user-facing text. Examples include:
- "Enable GitHub Issues" (line 211)
- "Sync issues from GitHub and create tasks automatically" (line 213)
- "Connected via GitHub CLI" (line 232)
- "Personal Access Token" (line 290)
- "Default Branch" (line 634)
- "Base branch for creating task worktrees" (line 637)
GitLabIntegration.tsx demonstrates the correct pattern: import
useTranslation()and uset('settings.keyName')for all user-facing strings. GitHubIntegration.tsx should follow the same approach, with translation keys added toapps/frontend/src/shared/i18n/locales/{en,fr}/github.json.Also applies to: 232-236, 247, 269, 275, 290, 298, 309, 410, 444, 519-520, 541, 573-574, 593, 596, 634, 637, 676, 706, 741
apps/frontend/src/renderer/components/terminal/usePtyProcess.ts (1)
44-108: Add cleanup function to prevent state updates on unmounted component.The create PTY effect performs async operations but lacks a cleanup function. If the component unmounts while
createTerminalorrestoreTerminalSessionis pending, the promise callbacks will still execute and attempt to update state on an unmounted component, causing React warnings and potential memory leaks.🔎 Suggested fix: Add cleanup with cancellation tracking
// Create PTY process useEffect(() => { + let cancelled = false; + if (isCreatingRef.current || isCreatedRef.current) return; const terminalState = useTerminalStore.getState().terminals.find((t) => t.id === terminalId); const alreadyRunning = terminalState?.status === 'running' || terminalState?.status === 'claude-active'; const isRestored = terminalState?.isRestored; isCreatingRef.current = true; if (isRestored && terminalState) { // Restored session window.electronAPI.restoreTerminalSession( // ... args ... ).then((result) => { + if (cancelled) return; if (result.success && result.data?.success) { isCreatedRef.current = true; setTerminalStatus(terminalId, terminalState.isClaudeMode ? 'claude-active' : 'running'); updateTerminal(terminalId, { isRestored: false }); onCreated?.(); } else { const error = `Error restoring session: ${result.data?.error || result.error}`; onError?.(error); } isCreatingRef.current = false; }).catch((err) => { + if (cancelled) return; onError?.(err.message); isCreatingRef.current = false; }); } else { // New terminal window.electronAPI.createTerminal({ // ... args ... }).then((result) => { + if (cancelled) return; if (result.success) { isCreatedRef.current = true; if (!alreadyRunning) { setTerminalStatus(terminalId, 'running'); } onCreated?.(); } else { onError?.(result.error || 'Unknown error'); } isCreatingRef.current = false; }).catch((err) => { + if (cancelled) return; onError?.(err.message); isCreatingRef.current = false; }); } + + return () => { + cancelled = true; + }; }, [terminalId, cwd, projectPath, cols, rows, setTerminalStatus, updateTerminal, onCreated, onError]);apps/backend/merge/git_utils.py (1)
19-35: Add error handling for directory operations infind_worktree.The function lacks try-except protection around
worktrees_dir.iterdir()at line 32. If directory operations fail (permission denied, filesystem errors, corrupted state), the function will crash instead of returningNone.Wrap the directory iteration in a try-except block to handle potential
OSErrorexceptions gracefully:Example fix
def find_worktree(project_dir: Path, task_id: str) -> Path | None: """ Find the worktree path for a task. Args: project_dir: The project root directory task_id: The task identifier Returns: Path to the worktree, or None if not found """ worktrees_dir = project_dir / ".auto-claude" / "worktrees" / "tasks" try: if worktrees_dir.exists(): for entry in worktrees_dir.iterdir(): if entry.is_dir() and task_id in entry.name: return entry except (OSError, PermissionError): pass return Noneapps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts (1)
2127-2198: Consider makingprocessWorktreeEntrya pure function that returns the item.The helper function modifies the outer
worktreesarray via closure, which reduces testability and makes the data flow less explicit.🔎 Suggested refactor
- const processWorktreeEntry = (entry: string, entryPath: string) => { + const processWorktreeEntry = (entry: string, entryPath: string): WorktreeListItem | null => { try { // Get branch info const branch = execFileSync(getToolPath('git'), ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: entryPath, encoding: 'utf-8' }).trim(); // ... rest of git operations ... - worktrees.push({ + return { specName: entry, path: entryPath, branch, baseBranch, commitCount, filesChanged, additions, deletions - }); + }; } catch (gitError) { console.error(`Error getting info for worktree ${entry}:`, gitError); - // Skip this worktree if we can't get git info + return null; } - }; + }; // Scan worktrees directory if (existsSync(worktreesDir)) { const entries = readdirSync(worktreesDir); for (const entry of entries) { const entryPath = path.join(worktreesDir, entry); try { const stat = statSync(entryPath); if (stat.isDirectory()) { - processWorktreeEntry(entry, entryPath); + const item = processWorktreeEntry(entry, entryPath); + if (item) worktrees.push(item); } } catch { // Skip entries that can't be stat'd } } }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (49)
apps/backend/cli/batch_commands.pyapps/backend/cli/utils.pyapps/backend/core/workspace.pyapps/backend/core/workspace/__init__.pyapps/backend/core/workspace/finalization.pyapps/backend/core/workspace/git_utils.pyapps/backend/core/workspace/models.pyapps/backend/core/worktree.pyapps/backend/merge/git_utils.pyapps/backend/merge/timeline_git.pyapps/backend/prompts/github/pr_codebase_fit_agent.mdapps/backend/prompts/github/pr_finding_validator.mdapps/backend/prompts/github/pr_followup_newcode_agent.mdapps/backend/prompts/github/pr_followup_orchestrator.mdapps/backend/prompts/github/pr_followup_resolution_agent.mdapps/backend/prompts/github/pr_logic_agent.mdapps/backend/prompts/github/pr_parallel_orchestrator.mdapps/backend/prompts/github/pr_quality_agent.mdapps/backend/prompts/github/pr_security_agent.mdapps/backend/runners/github/context_gatherer.pyapps/backend/runners/github/gh_client.pyapps/frontend/src/main/ipc-handlers/index.tsapps/frontend/src/main/ipc-handlers/task/execution-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/main/ipc-handlers/terminal/index.tsapps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.tsapps/frontend/src/main/project-store.tsapps/frontend/src/main/release-service.tsapps/frontend/src/main/task-log-service.tsapps/frontend/src/main/utils/spec-number-lock.tsapps/frontend/src/preload/api/terminal-api.tsapps/frontend/src/renderer/components/Terminal.tsxapps/frontend/src/renderer/components/settings/integrations/GitHubIntegration.tsxapps/frontend/src/renderer/components/settings/integrations/GitLabIntegration.tsxapps/frontend/src/renderer/components/settings/sections/SectionRouter.tsxapps/frontend/src/renderer/components/terminal/CreateWorktreeDialog.tsxapps/frontend/src/renderer/components/terminal/TerminalHeader.tsxapps/frontend/src/renderer/components/terminal/WorktreeSelector.tsxapps/frontend/src/renderer/components/terminal/usePtyProcess.tsapps/frontend/src/renderer/lib/browser-mock.tsapps/frontend/src/renderer/stores/terminal-store.tsapps/frontend/src/shared/constants/ipc.tsapps/frontend/src/shared/i18n/index.tsapps/frontend/src/shared/i18n/locales/en/common.jsonapps/frontend/src/shared/i18n/locales/en/terminal.jsonapps/frontend/src/shared/i18n/locales/fr/common.jsonapps/frontend/src/shared/i18n/locales/fr/terminal.jsonapps/frontend/src/shared/types/ipc.tsapps/frontend/src/shared/types/terminal.ts
🧰 Additional context used
📓 Path-based instructions (7)
apps/frontend/src/**/*.{ts,tsx,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always use i18n translation keys for all user-facing text in the frontend instead of hardcoded strings
Files:
apps/frontend/src/main/utils/spec-number-lock.tsapps/frontend/src/shared/types/terminal.tsapps/frontend/src/renderer/components/terminal/usePtyProcess.tsapps/frontend/src/renderer/components/terminal/CreateWorktreeDialog.tsxapps/frontend/src/main/ipc-handlers/terminal/index.tsapps/frontend/src/shared/constants/ipc.tsapps/frontend/src/main/task-log-service.tsapps/frontend/src/renderer/stores/terminal-store.tsapps/frontend/src/shared/types/ipc.tsapps/frontend/src/main/ipc-handlers/index.tsapps/frontend/src/renderer/components/settings/integrations/GitHubIntegration.tsxapps/frontend/src/renderer/lib/browser-mock.tsapps/frontend/src/renderer/components/terminal/TerminalHeader.tsxapps/frontend/src/main/ipc-handlers/task/execution-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/shared/i18n/index.tsapps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.tsapps/frontend/src/renderer/components/settings/integrations/GitLabIntegration.tsxapps/frontend/src/renderer/components/settings/sections/SectionRouter.tsxapps/frontend/src/main/release-service.tsapps/frontend/src/preload/api/terminal-api.tsapps/frontend/src/main/project-store.tsapps/frontend/src/renderer/components/Terminal.tsxapps/frontend/src/renderer/components/terminal/WorktreeSelector.tsx
apps/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use
useTranslation()hook with namespace prefixes (e.g., 'navigation:items.key') for accessing translation strings in React components
Files:
apps/frontend/src/main/utils/spec-number-lock.tsapps/frontend/src/shared/types/terminal.tsapps/frontend/src/renderer/components/terminal/usePtyProcess.tsapps/frontend/src/renderer/components/terminal/CreateWorktreeDialog.tsxapps/frontend/src/main/ipc-handlers/terminal/index.tsapps/frontend/src/shared/constants/ipc.tsapps/frontend/src/main/task-log-service.tsapps/frontend/src/renderer/stores/terminal-store.tsapps/frontend/src/shared/types/ipc.tsapps/frontend/src/main/ipc-handlers/index.tsapps/frontend/src/renderer/components/settings/integrations/GitHubIntegration.tsxapps/frontend/src/renderer/lib/browser-mock.tsapps/frontend/src/renderer/components/terminal/TerminalHeader.tsxapps/frontend/src/main/ipc-handlers/task/execution-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/shared/i18n/index.tsapps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.tsapps/frontend/src/renderer/components/settings/integrations/GitLabIntegration.tsxapps/frontend/src/renderer/components/settings/sections/SectionRouter.tsxapps/frontend/src/main/release-service.tsapps/frontend/src/preload/api/terminal-api.tsapps/frontend/src/main/project-store.tsapps/frontend/src/renderer/components/Terminal.tsxapps/frontend/src/renderer/components/terminal/WorktreeSelector.tsx
apps/frontend/**/*.{ts,tsx}
⚙️ CodeRabbit configuration file
apps/frontend/**/*.{ts,tsx}: Review React patterns and TypeScript type safety.
Check for proper state management and component composition.
Files:
apps/frontend/src/main/utils/spec-number-lock.tsapps/frontend/src/shared/types/terminal.tsapps/frontend/src/renderer/components/terminal/usePtyProcess.tsapps/frontend/src/renderer/components/terminal/CreateWorktreeDialog.tsxapps/frontend/src/main/ipc-handlers/terminal/index.tsapps/frontend/src/shared/constants/ipc.tsapps/frontend/src/main/task-log-service.tsapps/frontend/src/renderer/stores/terminal-store.tsapps/frontend/src/shared/types/ipc.tsapps/frontend/src/main/ipc-handlers/index.tsapps/frontend/src/renderer/components/settings/integrations/GitHubIntegration.tsxapps/frontend/src/renderer/lib/browser-mock.tsapps/frontend/src/renderer/components/terminal/TerminalHeader.tsxapps/frontend/src/main/ipc-handlers/task/execution-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/shared/i18n/index.tsapps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.tsapps/frontend/src/renderer/components/settings/integrations/GitLabIntegration.tsxapps/frontend/src/renderer/components/settings/sections/SectionRouter.tsxapps/frontend/src/main/release-service.tsapps/frontend/src/preload/api/terminal-api.tsapps/frontend/src/main/project-store.tsapps/frontend/src/renderer/components/Terminal.tsxapps/frontend/src/renderer/components/terminal/WorktreeSelector.tsx
apps/backend/prompts/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Agent prompts should be stored as markdown files in
apps/backend/prompts/with descriptive names matching their purpose
Files:
apps/backend/prompts/github/pr_parallel_orchestrator.mdapps/backend/prompts/github/pr_followup_resolution_agent.mdapps/backend/prompts/github/pr_security_agent.mdapps/backend/prompts/github/pr_logic_agent.mdapps/backend/prompts/github/pr_followup_newcode_agent.mdapps/backend/prompts/github/pr_codebase_fit_agent.mdapps/backend/prompts/github/pr_followup_orchestrator.mdapps/backend/prompts/github/pr_finding_validator.mdapps/backend/prompts/github/pr_quality_agent.md
apps/frontend/src/shared/i18n/locales/**/*.json
📄 CodeRabbit inference engine (CLAUDE.md)
apps/frontend/src/shared/i18n/locales/**/*.json: Store translation strings in namespace-organized JSON files atapps/frontend/src/shared/i18n/locales/{lang}/*.jsonfor each supported language
When implementing new frontend features, add translation keys to all language files (minimum: en/.json and fr/.json)
Files:
apps/frontend/src/shared/i18n/locales/fr/common.jsonapps/frontend/src/shared/i18n/locales/en/common.jsonapps/frontend/src/shared/i18n/locales/en/terminal.jsonapps/frontend/src/shared/i18n/locales/fr/terminal.json
apps/backend/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
apps/backend/**/*.py: Always use the Claude Agent SDK (claude-agent-sdkpackage) for all AI interactions, never use the Anthropic API directly
Use thecreate_client()function fromapps/backend/core/client.pyto instantiate Claude SDK clients, not directClaudeSDKClientinitialization
Files:
apps/backend/cli/utils.pyapps/backend/core/workspace/git_utils.pyapps/backend/core/workspace/finalization.pyapps/backend/cli/batch_commands.pyapps/backend/merge/git_utils.pyapps/backend/runners/github/gh_client.pyapps/backend/core/workspace/models.pyapps/backend/core/workspace.pyapps/backend/core/worktree.pyapps/backend/merge/timeline_git.pyapps/backend/runners/github/context_gatherer.pyapps/backend/core/workspace/__init__.py
⚙️ CodeRabbit configuration file
apps/backend/**/*.py: Focus on Python best practices, type hints, and async patterns.
Check for proper error handling and security considerations.
Verify compatibility with Python 3.12+.
Files:
apps/backend/cli/utils.pyapps/backend/core/workspace/git_utils.pyapps/backend/core/workspace/finalization.pyapps/backend/cli/batch_commands.pyapps/backend/merge/git_utils.pyapps/backend/runners/github/gh_client.pyapps/backend/core/workspace/models.pyapps/backend/core/workspace.pyapps/backend/core/worktree.pyapps/backend/merge/timeline_git.pyapps/backend/runners/github/context_gatherer.pyapps/backend/core/workspace/__init__.py
apps/backend/core/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Implement dynamic command allowlisting based on detected project stack using
core/security.pyfor bash command validation
Files:
apps/backend/core/workspace/git_utils.pyapps/backend/core/workspace/finalization.pyapps/backend/core/workspace/models.pyapps/backend/core/workspace.pyapps/backend/core/worktree.pyapps/backend/core/workspace/__init__.py
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Use git worktrees for isolated agent builds with branches following the naming pattern `auto-claude/{spec-name}`
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Use git worktrees for isolated agent builds with branches following the naming pattern `auto-claude/{spec-name}`
Applied to files:
apps/frontend/src/main/utils/spec-number-lock.tsapps/backend/cli/utils.pyapps/backend/core/workspace/git_utils.pyapps/frontend/src/main/ipc-handlers/task/execution-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/backend/core/workspace/finalization.pyapps/frontend/src/main/release-service.tsapps/backend/cli/batch_commands.pyapps/backend/merge/git_utils.pyapps/frontend/src/main/project-store.tsapps/backend/core/workspace.pyapps/backend/core/worktree.pyapps/backend/merge/timeline_git.pyapps/backend/core/workspace/__init__.py
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Applies to apps/frontend/src/shared/i18n/locales/**/*.json : When implementing new frontend features, add translation keys to all language files (minimum: en/*.json and fr/*.json)
Applied to files:
apps/frontend/src/shared/i18n/locales/fr/common.jsonapps/frontend/src/shared/i18n/index.tsapps/frontend/src/shared/i18n/locales/en/common.jsonapps/frontend/src/shared/i18n/locales/en/terminal.jsonapps/frontend/src/shared/i18n/locales/fr/terminal.json
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Store project-specific data including specs, plans, and QA reports in `.auto-claude/specs/` directory and add to .gitignore
Applied to files:
apps/backend/cli/utils.pyapps/backend/core/workspace.pyapps/backend/core/worktree.pyapps/backend/core/workspace/__init__.py
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Applies to apps/backend/prompts/**/*.md : Agent prompts should be stored as markdown files in `apps/backend/prompts/` with descriptive names matching their purpose
Applied to files:
apps/backend/prompts/github/pr_codebase_fit_agent.mdapps/backend/prompts/github/pr_quality_agent.md
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Applies to apps/frontend/src/**/*.{ts,tsx} : Use `useTranslation()` hook with namespace prefixes (e.g., 'navigation:items.key') for accessing translation strings in React components
Applied to files:
apps/frontend/src/renderer/components/terminal/TerminalHeader.tsxapps/frontend/src/shared/i18n/index.ts
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Applies to apps/frontend/src/**/*.{ts,tsx,jsx} : Always use i18n translation keys for all user-facing text in the frontend instead of hardcoded strings
Applied to files:
apps/frontend/src/shared/i18n/index.ts
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Applies to apps/frontend/src/shared/i18n/locales/**/*.json : Store translation strings in namespace-organized JSON files at `apps/frontend/src/shared/i18n/locales/{lang}/*.json` for each supported language
Applied to files:
apps/frontend/src/shared/i18n/index.tsapps/frontend/src/shared/i18n/locales/en/common.jsonapps/frontend/src/shared/i18n/locales/en/terminal.jsonapps/frontend/src/shared/i18n/locales/fr/terminal.json
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Keep all spec branches local until the user explicitly pushes to remote; never automatically push spec branches to GitHub
Applied to files:
apps/backend/core/worktree.py
🧬 Code graph analysis (15)
apps/frontend/src/main/ipc-handlers/terminal/index.ts (2)
apps/frontend/src/main/ipc-handlers/index.ts (1)
registerTerminalWorktreeIpcHandlers(133-133)apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts (1)
registerTerminalWorktreeHandlers(259-293)
apps/frontend/src/renderer/stores/terminal-store.ts (1)
apps/frontend/src/shared/types/terminal.ts (1)
TerminalWorktreeConfig(144-161)
apps/frontend/src/shared/types/ipc.ts (1)
apps/frontend/src/shared/types/terminal.ts (3)
CreateTerminalWorktreeRequest(166-179)TerminalWorktreeResult(184-188)TerminalWorktreeConfig(144-161)
apps/frontend/src/main/ipc-handlers/index.ts (1)
apps/frontend/src/main/ipc-handlers/terminal/index.ts (1)
registerTerminalWorktreeIpcHandlers(13-15)
apps/frontend/src/renderer/components/settings/integrations/GitHubIntegration.tsx (3)
apps/frontend/src/shared/types/project.ts (1)
ProjectSettings(15-29)apps/frontend/src/main/ipc-handlers/github/utils/logger.ts (1)
debugLog(29-37)apps/frontend/src/renderer/components/settings/utils/hookProxyFactory.ts (4)
setSettings(16-16)updateEnvConfig(29-29)settings(15-15)envConfig(23-23)
apps/frontend/src/renderer/components/terminal/TerminalHeader.tsx (2)
apps/frontend/src/shared/types/terminal.ts (1)
TerminalWorktreeConfig(144-161)apps/frontend/src/renderer/components/terminal/WorktreeSelector.tsx (1)
WorktreeSelector(25-133)
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts (1)
apps/frontend/src/shared/constants/config.ts (1)
AUTO_BUILD_PATHS(81-98)
apps/backend/core/workspace/finalization.py (1)
apps/backend/core/workspace/git_utils.py (1)
get_existing_build_worktree(214-228)
apps/frontend/src/renderer/components/settings/integrations/GitLabIntegration.tsx (3)
apps/frontend/src/shared/types/project.ts (1)
ProjectSettings(15-29)apps/frontend/src/main/ipc-handlers/github/utils/logger.ts (1)
debugLog(29-37)apps/frontend/src/renderer/components/settings/utils/hookProxyFactory.ts (4)
setSettings(16-16)updateEnvConfig(29-29)settings(15-15)envConfig(23-23)
apps/frontend/src/renderer/components/settings/sections/SectionRouter.tsx (1)
apps/frontend/src/renderer/components/settings/utils/hookProxyFactory.ts (2)
settings(15-15)setSettings(16-16)
apps/frontend/src/preload/api/terminal-api.ts (1)
apps/frontend/src/shared/types/terminal.ts (3)
CreateTerminalWorktreeRequest(166-179)TerminalWorktreeResult(184-188)TerminalWorktreeConfig(144-161)
apps/frontend/src/main/project-store.ts (1)
scripts/bump-version.js (1)
path(31-31)
apps/backend/core/worktree.py (2)
apps/backend/runners/github/multi_repo.py (1)
name(89-91)apps/backend/core/workspace/git_utils.py (1)
has_uncommitted_changes(192-200)
apps/backend/runners/github/context_gatherer.py (1)
apps/backend/runners/github/gh_client.py (2)
get_pr_files_changed_since(981-1034)compare_commits(660-682)
apps/frontend/src/renderer/components/terminal/WorktreeSelector.tsx (3)
apps/frontend/src/shared/types/terminal.ts (1)
TerminalWorktreeConfig(144-161).design-system/src/lib/utils.ts (1)
cn(4-6).design-system/src/lib/icons.ts (1)
Plus(30-30)
🪛 Biome (2.1.2)
apps/frontend/src/renderer/components/terminal/WorktreeSelector.tsx
[error] 67-73: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
🪛 markdownlint-cli2 (0.18.1)
apps/backend/prompts/github/pr_parallel_orchestrator.md
11-11: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
17-17: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
apps/backend/prompts/github/pr_followup_resolution_agent.md
17-17: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
28-28: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
apps/backend/prompts/github/pr_logic_agent.md
11-11: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
17-17: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
apps/backend/prompts/github/pr_followup_newcode_agent.md
16-16: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
22-22: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
apps/backend/prompts/github/pr_codebase_fit_agent.md
11-11: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
17-17: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
apps/backend/prompts/github/pr_followup_orchestrator.md
14-14: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
20-20: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
apps/backend/prompts/github/pr_quality_agent.md
11-11: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
17-17: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Cursor Bugbot
| 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}" | ||
| ) | ||
| ) |
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.
🧩 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 worktree_info is None and get_existing_build_worktree() returns None, the code prints a default path at .auto-claude/worktrees/tasks/{spec_name} that may not actually exist on disk. Users who copy this path to test will encounter a "directory not found" error with no context about why.
Consider one of these approaches:
- Add a warning message indicating the path should be created if not found
- Check if the fallback path exists before printing it
- Print messaging that indicates the path must be manually created
This affects both the TEST branch (lines 176-180) and LATER branch (lines 247-251).
🤖 Prompt for AI Agents
In apps/backend/core/workspace/finalization.py around lines 172-180 (and
similarly update the LATER branch at ~247-251), the code prints a fallback path
.auto-claude/worktrees/tasks/{spec_name} even when get_existing_build_worktree()
returned None which may not exist; change this to compute the fallback_path =
os.path.join(project_dir, ".auto-claude", "worktrees", "tasks", spec_name),
check os.path.exists(fallback_path) and if it exists print the highlighted cd
line, otherwise print a highlighted cd line plus a clear warning that the
directory does not exist and must be created (or offer to create it
automatically using os.makedirs with exist_ok=True if you prefer automatic
creation); apply the same existence check and warning behavior in the LATER
branch.
| """ | ||
| # Per-spec worktree path: .worktrees/{spec-name}/ | ||
| worktree_path = project_dir / ".worktrees" / spec_name | ||
| worktree_path = project_dir / ".auto-claude" / "worktrees" / "tasks" / spec_name |
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for migration logic and old worktree path references
rg -n "\.worktrees" --type=py
echo "---"
# Search for migration/upgrade references
rg -n -i "migration|upgrade|breaking" --type=py --type=md
echo "---"
# Check for auto-claude path references
rg -n "auto-claude" --type=pyRepository: AndyMik90/Auto-Claude
Length of output: 50377
🏁 Script executed:
# Get full context of git_utils.py around line 225
wc -l apps/backend/core/workspace/git_utils.pyRepository: AndyMik90/Auto-Claude
Length of output: 109
🏁 Script executed:
# Read the git_utils.py file to understand the context
head -250 apps/backend/core/workspace/git_utils.py | tail -40Repository: AndyMik90/Auto-Claude
Length of output: 1174
🏁 Script executed:
# Check CLAUDE.md for guidelines
cat CLAUDE.mdRepository: AndyMik90/Auto-Claude
Length of output: 17822
This path change breaks existing worktree discovery and requires test/documentation updates.
The worktree path changed from .worktrees/{spec_name} to .auto-claude/worktrees/tasks/{spec_name}, but:
-
No backward compatibility:
get_existing_build_worktree()only checks the new location. Users with existing worktrees in the old path cannot find them. -
Tests still use old path: Multiple test files (
test_workspace.py,test_worktree.py) reference the old.worktreespath and will fail after this change. -
Analyzer skip lists outdated:
apps/backend/analysis/analyzers/base.pyandframework_analyzer.pystill hardcode.worktreesin directory skip lists—update to.auto-claude/worktrees/tasksor skip both. -
Documentation outdated:
CLAUDE.mdstill references the old.worktrees/{spec-name}path in the "Branching & Worktree Strategy" section. -
No migration guidance: No documentation explaining the change to users or migration steps for existing worktrees.
Add a fallback check in get_existing_build_worktree() to detect old-location worktrees with migration notice, or document the breaking change and update all affected tests and docs.
🤖 Prompt for AI Agents
In apps/backend/core/workspace/git_utils.py around line 225 the worktree
creation path was changed to ".auto-claude/worktrees/tasks/{spec_name}",
breaking discovery of existing worktrees stored under the old
".worktrees/{spec_name}"; update get_existing_build_worktree() to check the new
path first and then fall back to the old ".worktrees/{spec_name}" location, emit
a clear migration/log notice when the old location is found (so users are
informed), and ensure any returned path is normalized to the new layout;
additionally update tests (test_workspace.py, test_worktree.py) to accept both
locations (or update fixtures to new path), revise analyzer skip lists in
apps/backend/analysis/analyzers/base.py and framework_analyzer.py to skip both
".auto-claude/worktrees/tasks" and ".worktrees", and update CLAUDE.md to
document the new path and provide migration steps for existing worktrees.
|
|
||
| # 2. Scan all worktree specs | ||
| worktrees_dir = self.project_dir / ".worktrees" | ||
| worktrees_dir = self.project_dir / ".auto-claude" / "worktrees" / "tasks" |
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.
🧩 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 SpecNumberLock.get_next_spec_number() method only scans specs in .auto-claude/worktrees/tasks/ but does not check for specs in any legacy .worktrees/ location. If existing worktrees with specs were created under the old path, they will be orphaned and their spec numbers won't be included in the global maximum, creating a collision risk.
Since the PR description mentions removing backward-compatibility code, either:
- Add fallback logic to also scan the old location (if it existed in prior versions), or
- Provide clear migration guidance in CLAUDE.md and release notes for users to manually migrate or clean up old worktrees
Currently, no migration code or user guidance exists for this breaking change.
| worktree_path = ( | ||
| self.project_path | ||
| / ".auto-claude" | ||
| / "worktrees" | ||
| / "tasks" | ||
| / spec_name | ||
| / file_path | ||
| ) |
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.
🧹 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 apps/backend/core/workspace/models.py:252 and apps/backend/cli/batch_commands.py:187).
🔎 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
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 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 |
🤖 Prompt for AI Agents
In apps/backend/merge/timeline_git.py around lines 192 to 199, the worktree_path
is built across multiple lines; change it to a single-line Path join (e.g.,
self.project_path / ".auto-claude" / "worktrees" / "tasks" / spec_name /
file_path expressed on one line) to match the single-line style used elsewhere
for consistency, ensuring line length stays reasonable or wrap only by breaking
before operators if necessary.
| ## CRITICAL: PR Scope and Context | ||
|
|
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.
🛠️ Refactor suggestion | 🟠 Major
Add blank lines around headings to meet markdown standards.
Lines 14 and 22 introduce headings without the required blank line above them, violating the MD022 rule. Consistent with the prior file, add a blank line before each heading.
🔎 Proposed fix
Review the incremental diff for:
1. Security vulnerabilities
2. Logic errors and edge cases
3. Code quality issues
4. Potential regressions
5. Incomplete implementations
+
### What IS in scope (report these issues):
1. **Issues in changed code** - Problems in files/lines actually modified by this PR
2. **Impact on unchanged code** - "This change breaks callers in `other_file.ts`"
3. **Missing related changes** - "Similar pattern in `utils.ts` wasn't updated"
4. **Incomplete implementations** - "New field added but not handled in serializer"
+
### What is NOT in scope (do NOT report):As per coding guidelines, agent prompts should follow markdown standards. See markdownlint-cli2 rule MD022.
Also applies to: 22-23
🤖 Prompt for AI Agents
In apps/backend/prompts/github/pr_followup_newcode_agent.md around lines 14-15
and 22-23, headings are missing the required blank line above (MD022); insert a
single blank line immediately before each heading so there is an empty line
separating the previous paragraph or content from the heading, and run
markdownlint to verify MD022 is satisfied.
| const handleNameChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => { | ||
| // Auto-sanitize: lowercase, replace spaces and invalid chars | ||
| const sanitized = e.target.value | ||
| .toLowerCase() | ||
| .replace(/[^a-z0-9-_]/g, '-') | ||
| .replace(/-+/g, '-') | ||
| .replace(/^-|-$/g, ''); | ||
| setName(sanitized); | ||
| setError(null); | ||
| }, []); |
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.
Strengthen name sanitization to handle edge cases.
The regex .replace(/^-|-$/g, '') only removes one leading and one trailing dash per execution. Input with multiple consecutive special characters (e.g., "___test___") would become "---test---" after the first replacements, then "--test--" after removing leading/trailing dashes, which would fail the validation regex at line 140.
🔎 Proposed fix
const handleNameChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
// Auto-sanitize: lowercase, replace spaces and invalid chars
const sanitized = e.target.value
.toLowerCase()
.replace(/[^a-z0-9-_]/g, '-')
.replace(/-+/g, '-')
- .replace(/^-|-$/g, '');
+ .replace(/^[-_]+|[-_]+$/g, '');
setName(sanitized);
setError(null);
}, []);The updated regex removes all leading and trailing dashes/underscores, not just one.
🤖 Prompt for AI Agents
In apps/frontend/src/renderer/components/terminal/CreateWorktreeDialog.tsx
around lines 101 to 110, the final replace call only strips a single
leading/trailing dash; change it to remove all leading/trailing dashes and
underscores by using a global anchored regex, e.g. replace(/^[-_]+|[-_]+$/g,
''), so inputs like "___test___" are fully trimmed and pass downstream
validation.
| <button | ||
| className={cn( | ||
| 'flex items-center gap-1 h-6 px-2 rounded text-xs font-medium transition-colors', | ||
| 'hover:bg-amber-500/10 hover:text-amber-500 text-muted-foreground' | ||
| )} | ||
| onClick={(e) => e.stopPropagation()} | ||
| > | ||
| <FolderGit className="h-3 w-3" /> | ||
| <span>{t('terminal:worktree.create')}</span> | ||
| <ChevronDown className="h-2.5 w-2.5 opacity-60" /> | ||
| </button> | ||
| </DropdownMenuTrigger> |
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.
Add explicit type="button" to prevent unintended form submission.
The button element lacks an explicit type attribute. In React, buttons inside forms default to type="submit", which can cause unintended form submissions and unexpected behavior.
🔎 Proposed fix
<button
+ type="button"
className={cn(
'flex items-center gap-1 h-6 px-2 rounded text-xs font-medium transition-colors',
'hover:bg-amber-500/10 hover:text-amber-500 text-muted-foreground'
)}
onClick={(e) => e.stopPropagation()}
>Based on static analysis hints from Biome.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <button | |
| className={cn( | |
| 'flex items-center gap-1 h-6 px-2 rounded text-xs font-medium transition-colors', | |
| 'hover:bg-amber-500/10 hover:text-amber-500 text-muted-foreground' | |
| )} | |
| onClick={(e) => e.stopPropagation()} | |
| > | |
| <FolderGit className="h-3 w-3" /> | |
| <span>{t('terminal:worktree.create')}</span> | |
| <ChevronDown className="h-2.5 w-2.5 opacity-60" /> | |
| </button> | |
| </DropdownMenuTrigger> | |
| <button | |
| type="button" | |
| className={cn( | |
| 'flex items-center gap-1 h-6 px-2 rounded text-xs font-medium transition-colors', | |
| 'hover:bg-amber-500/10 hover:text-amber-500 text-muted-foreground' | |
| )} | |
| onClick={(e) => e.stopPropagation()} | |
| > | |
| <FolderGit className="h-3 w-3" /> | |
| <span>{t('terminal:worktree.create')}</span> | |
| <ChevronDown className="h-2.5 w-2.5 opacity-60" /> | |
| </button> | |
| </DropdownMenuTrigger> |
🧰 Tools
🪛 Biome (2.1.2)
[error] 67-73: Provide an explicit type prop for the button element.
The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset
(lint/a11y/useButtonType)
🤖 Prompt for AI Agents
In apps/frontend/src/renderer/components/terminal/WorktreeSelector.tsx around
lines 67 to 78, the button used as a dropdown trigger is missing an explicit
type attribute which can cause it to act as a submit button inside a form;
update the JSX for this button to include type="button" so it won't submit
parent forms (keep existing onClick and children intact).
| "success": "Succès", | ||
| "initializing": "Initialisation...", | ||
| "saving": "Enregistrement...", | ||
| "creating": "Creation...", |
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.
Correct the French translation: missing accent.
The French word should be "Création..." with an accent on the 'e', not "Creation...".
🔎 Proposed fix
- "creating": "Creation...",
+ "creating": "Création...",🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/fr/common.json around line 40, the
French translation "Creating" is missing an accent; replace the value
"Creation..." with the correctly accented "Création..." (i.e., update the string
to use 'É' so it reads "Création...").
| { | ||
| "worktree": { | ||
| "create": "Worktree", | ||
| "createNew": "+ Nouveau Worktree", | ||
| "existing": "Worktrees Existants", | ||
| "createTitle": "Creer un Worktree Terminal", | ||
| "createDescription": "Creer un espace de travail isole pour ce terminal. Tout le travail se fera dans le repertoire du worktree.", | ||
| "name": "Nom du Worktree", | ||
| "namePlaceholder": "ma-fonctionnalite", | ||
| "nameRequired": "Le nom du worktree est requis", | ||
| "nameInvalid": "Le nom doit commencer et se terminer par une lettre ou un chiffre", | ||
| "nameHelp": "Lettres minuscules, chiffres, tirets et underscores uniquement", | ||
| "associateTask": "Lier a une Tache", | ||
| "selectTask": "Selectionner une tache...", | ||
| "noTask": "Pas de tache (worktree autonome)", | ||
| "createBranch": "Creer une Branche Git", | ||
| "branchHelp": "Cree la branche: {{branch}}", | ||
| "baseBranch": "Branche de Base", | ||
| "selectBaseBranch": "Selectionner la branche de base...", | ||
| "useProjectDefault": "Utiliser la valeur par defaut du projet ({{branch}})", | ||
| "baseBranchHelp": "La branche a partir de laquelle creer le worktree", | ||
| "openInIDE": "Ouvrir dans IDE", | ||
| "maxReached": "Maximum de 12 worktrees terminal atteint", | ||
| "alreadyExists": "Un worktree avec ce nom existe deja" | ||
| } | ||
| } |
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.
Fix missing French accents for proper localization.
Multiple translation strings are missing required French accents, which impacts the professional quality of the UI. French-speaking users will notice these omissions.
🔎 Corrected French translations
{
"worktree": {
"create": "Worktree",
"createNew": "+ Nouveau Worktree",
"existing": "Worktrees Existants",
- "createTitle": "Creer un Worktree Terminal",
- "createDescription": "Creer un espace de travail isole pour ce terminal. Tout le travail se fera dans le repertoire du worktree.",
+ "createTitle": "Créer un Worktree Terminal",
+ "createDescription": "Créer un espace de travail isolé pour ce terminal. Tout le travail se fera dans le répertoire du worktree.",
"name": "Nom du Worktree",
"namePlaceholder": "ma-fonctionnalite",
"nameRequired": "Le nom du worktree est requis",
"nameInvalid": "Le nom doit commencer et se terminer par une lettre ou un chiffre",
"nameHelp": "Lettres minuscules, chiffres, tirets et underscores uniquement",
- "associateTask": "Lier a une Tache",
- "selectTask": "Selectionner une tache...",
- "noTask": "Pas de tache (worktree autonome)",
- "createBranch": "Creer une Branche Git",
- "branchHelp": "Cree la branche: {{branch}}",
+ "associateTask": "Lier à une Tâche",
+ "selectTask": "Sélectionner une tâche...",
+ "noTask": "Pas de tâche (worktree autonome)",
+ "createBranch": "Créer une Branche Git",
+ "branchHelp": "Crée la branche: {{branch}}",
"baseBranch": "Branche de Base",
- "selectBaseBranch": "Selectionner la branche de base...",
- "useProjectDefault": "Utiliser la valeur par defaut du projet ({{branch}})",
- "baseBranchHelp": "La branche a partir de laquelle creer le worktree",
+ "selectBaseBranch": "Sélectionner la branche de base...",
+ "useProjectDefault": "Utiliser la valeur par défaut du projet ({{branch}})",
+ "baseBranchHelp": "La branche à partir de laquelle créer le worktree",
"openInIDE": "Ouvrir dans IDE",
"maxReached": "Maximum de 12 worktrees terminal atteint",
- "alreadyExists": "Un worktree avec ce nom existe deja"
+ "alreadyExists": "Un worktree avec ce nom existe déjà"
}
}🤖 Prompt for AI Agents
In apps/frontend/src/shared/i18n/locales/fr/terminal.json around lines 1 to 26,
several French strings are missing proper accents; update the translation values
to use correct French accents (e.g., "Creer" -> "Créer", "isole" -> "isolé",
"repertoire" -> "répertoire", "Selectionner" -> "Sélectionner", "tache"/"Tache"
-> "tâche"/"Tâche", "defaut" -> "défaut", "creer" in other contexts -> "créer",
"ouvir" if present -> "ouvrir") so all keys (createTitle, createDescription,
createNew, existing, create, associateTask, selectTask, noTask, createBranch,
branchHelp, selectBaseBranch, useProjectDefault, baseBranchHelp, openInIDE,
maxReached, alreadyExists) contain properly accented French text.
| export interface TerminalWorktreeConfig { | ||
| /** Unique worktree name (used as directory name) */ | ||
| name: string; | ||
| /** Path to the worktree directory (.auto-claude/worktrees/terminal/{name}/) */ | ||
| worktreePath: string; | ||
| /** Git branch name (terminal/{name}) - empty if no branch created */ | ||
| branchName: string; | ||
| /** Base branch the worktree was created from (from project settings or auto-detected) */ | ||
| baseBranch: string; | ||
| /** Whether a git branch was created for this worktree */ | ||
| hasGitBranch: boolean; | ||
| /** Associated task ID (optional - for task-linked worktrees) */ | ||
| taskId?: string; | ||
| /** When the worktree was created */ | ||
| createdAt: string; | ||
| /** Terminal ID this worktree is associated with */ | ||
| terminalId: string; | ||
| } |
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.
🧹 Nitpick | 🔵 Trivial
Consider simplifying the git branch representation.
The TerminalWorktreeConfig interface uses both hasGitBranch: boolean (line 154) and branchName: string (line 150) where the comment indicates branchName can be empty if no branch was created. This creates redundancy:
- If
branchNameis empty →hasGitBranchis false - If
branchNameis non-empty →hasGitBranchis true
You could simplify by making branchName optional and removing hasGitBranch:
/** Git branch name (terminal/{name}) - undefined if no branch created */
branchName?: string;This reduces the chance of inconsistency (e.g., hasGitBranch: true with branchName: "").
🤖 Prompt for AI Agents
In apps/frontend/src/shared/types/terminal.ts around lines 144 to 161, the
TerminalWorktreeConfig duplicates git branch state with both branchName: string
and hasGitBranch: boolean; remove the boolean and make branchName optional
instead (branchName?: string) and update the JSDoc to indicate undefined means
no branch; then search and update any code that reads hasGitBranch to instead
check for the presence/non-empty branchName (or handle undefined), and update
any serialization/tests/types that depended on hasGitBranch accordingly.
AI reviewers were not detecting when PRs had merge conflicts with the base branch. Now both initial and follow-up reviews check for conflicts via GitHub's mergeable status and report them as CRITICAL findings. Changes: - Add has_merge_conflicts and merge_state_status fields to PRContext and FollowupReviewContext - Fetch mergeable and mergeStateStatus from GitHub API - Update orchestrator prompts to instruct AI to report conflicts prominently with category "merge_conflict" and severity "critical" Note: GitHub API only reports IF conflicts exist, not WHICH files. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Merge origin/develop and resolve conflict in task/worktree-handlers.ts by using develop's worktreeSpecDir approach with proper null checks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
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.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts (1)
1643-1648: Inconsistent git command path: uses bare'git'instead ofgetToolPath('git').All other git invocations in this file use
getToolPath('git')to ensure the correct git binary is found. This one instance uses the bare string, which could fail on systems where git is not in PATH butgetToolPathresolves it.🔎 Proposed fix
execFileSync( - 'git', + getToolPath('git'), ['merge-base', '--is-ancestor', specBranch, 'HEAD'], { cwd: project.path, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] } );
♻️ Duplicate comments (2)
apps/backend/prompts/github/pr_followup_orchestrator.md (1)
14-21: Add blank lines after subsection headings to comply with markdown standards (same issue as previous review).This file reintroduces the same MD022 violations that were flagged in a previous review commit. Lines 14 and 20 contain subsection headings ("### What IS in scope..." and "### What is NOT in scope...") that immediately precede list content without separating blank lines. The markdown standard requires headings to be surrounded by blank lines both above and below.
🔎 Proposed fix
## CRITICAL: PR Scope and Context ### What IS in scope (report these issues): + 1. **Issues in changed code** - Problems in files/lines actually modified by this PR 2. **Impact on unchanged code** - "You changed X but forgot to update Y that depends on it" 3. **Missing related changes** - "This pattern also exists in Z, did you mean to update it too?" 4. **Breaking changes** - "This change breaks callers in other files" ### What is NOT in scope (do NOT report): + 1. **Pre-existing issues in unchanged code** - If old code has a bug but this PR didn't touch it, don't flag it 2. **Code from merged branches** - Commits with PR references like `(#584)` are from OTHER already-reviewed PRs 3. **Unrelated improvements** - Don't suggest refactoring code the PR didn't touchapps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts (1)
16-30: Same DRY concern: helper functions duplicated.These helpers (
getTaskWorktreeDir,getTaskWorktreePath,findTaskWorktree) are duplicated fromexecution-handlers.ts. Extract to a shared utility module.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (6)
apps/backend/prompts/github/pr_followup_orchestrator.mdapps/backend/prompts/github/pr_parallel_orchestrator.mdapps/backend/runners/github/context_gatherer.pyapps/backend/runners/github/models.pyapps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/main/project-store.ts
🧰 Additional context used
📓 Path-based instructions (5)
apps/backend/prompts/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Agent prompts should be stored as markdown files in
apps/backend/prompts/with descriptive names matching their purpose
Files:
apps/backend/prompts/github/pr_followup_orchestrator.mdapps/backend/prompts/github/pr_parallel_orchestrator.md
apps/frontend/src/**/*.{ts,tsx,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always use i18n translation keys for all user-facing text in the frontend instead of hardcoded strings
Files:
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/main/project-store.ts
apps/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use
useTranslation()hook with namespace prefixes (e.g., 'navigation:items.key') for accessing translation strings in React components
Files:
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/main/project-store.ts
apps/frontend/**/*.{ts,tsx}
⚙️ CodeRabbit configuration file
apps/frontend/**/*.{ts,tsx}: Review React patterns and TypeScript type safety.
Check for proper state management and component composition.
Files:
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/main/project-store.ts
apps/backend/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
apps/backend/**/*.py: Always use the Claude Agent SDK (claude-agent-sdkpackage) for all AI interactions, never use the Anthropic API directly
Use thecreate_client()function fromapps/backend/core/client.pyto instantiate Claude SDK clients, not directClaudeSDKClientinitialization
Files:
apps/backend/runners/github/models.pyapps/backend/runners/github/context_gatherer.py
⚙️ CodeRabbit configuration file
apps/backend/**/*.py: Focus on Python best practices, type hints, and async patterns.
Check for proper error handling and security considerations.
Verify compatibility with Python 3.12+.
Files:
apps/backend/runners/github/models.pyapps/backend/runners/github/context_gatherer.py
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Use git worktrees for isolated agent builds with branches following the naming pattern `auto-claude/{spec-name}`
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Applies to apps/backend/prompts/**/*.md : Agent prompts should be stored as markdown files in `apps/backend/prompts/` with descriptive names matching their purpose
Applied to files:
apps/backend/prompts/github/pr_followup_orchestrator.md
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Use git worktrees for isolated agent builds with branches following the naming pattern `auto-claude/{spec-name}`
Applied to files:
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/main/project-store.ts
🧬 Code graph analysis (2)
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts (1)
apps/frontend/src/shared/constants/config.ts (1)
AUTO_BUILD_PATHS(81-98)
apps/frontend/src/main/project-store.ts (1)
scripts/bump-version.js (1)
path(31-31)
🪛 markdownlint-cli2 (0.18.1)
apps/backend/prompts/github/pr_followup_orchestrator.md
14-14: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
20-20: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
apps/backend/prompts/github/pr_parallel_orchestrator.md
14-14: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
20-20: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Cursor Bugbot
- GitHub Check: CodeQL (python)
- GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (11)
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts (6)
1179-1196: LGTM!The handler correctly uses
findTaskWorktreeand properly handles the null case when no worktree exists.
1289-1303: LGTM!The handler correctly uses the new worktree path resolution and handles the case when no worktree exists.
1681-1682: LGTM on theexistsSyncguards.These guards are appropriate since significant time and async operations may have elapsed between the initial
findTaskWorktreecall and these cleanup operations, making re-verification prudent to avoid TOCTOU issues.Also applies to: 1727-1728
1920-1992: LGTM!The merge preview handler properly checks for uncommitted changes and delegates conflict analysis to the Python script. Error handling is comprehensive.
2099-2119: LGTM!The discard handler correctly uses the new worktree resolution and gracefully handles the case when no worktree exists.
2263-2277: LGTM!The worktree listing logic has good error resilience—individual entries that fail to stat are gracefully skipped without breaking the entire listing.
apps/frontend/src/main/project-store.ts (2)
18-18: LGTM!The
tabOrderfield is properly typed, initialized with a sensible default ([]), validated against valid project IDs (line 172), and persisted correctly.
272-272: LGTM!Consistent use of the
getWorktreeDir()helper improves maintainability and ensures the worktree path is constructed uniformly across the codebase. The refactoring preserves existing error handling and type safety.Also applies to: 651-651
apps/backend/runners/github/context_gatherer.py (3)
1187-1206: LGTM! Merge conflict status fetch is well-implemented.The merge status is fetched appropriately at the end of follow-up context gathering, with sensible defaults (
UNKNOWN) if the fetch fails. The error handling ensures the follow-up review can proceed even if merge status cannot be determined.
284-293: No changes needed — code correctly uses GitHub GraphQL API enum values.The code properly checks for
mergeable == "CONFLICTING"and uses"UNKNOWN"as fallback values, both of which are documented enum values in GitHub's GraphQL API. The merge conflict detection logic is correct and follows the API specification.
1059-1094: Good implementation of PR-scoped data retrieval with robust fallback mechanism.The switch from
compare_commits()toget_pr_files_changed_since()correctly addresses the problem of merge-introduced changes appearing in follow-up reviews. The error handling with fallback tocompare_commits()provides resilience, and the logging clearly indicates when the fallback is used. Method signature includes proper async/await patterns and type hints.
| ### What IS in scope (report these issues): | ||
| 1. **Issues in changed code** - Problems in files/lines actually modified by this PR | ||
| 2. **Impact on unchanged code** - "You changed X but forgot to update Y that depends on it" | ||
| 3. **Missing related changes** - "This pattern also exists in Z, did you mean to update it too?" | ||
| 4. **Breaking changes** - "This change breaks callers in other files" | ||
|
|
||
| ### What is NOT in scope (do NOT report): | ||
| 1. **Pre-existing issues** - Old bugs/issues in code this PR didn't touch | ||
| 2. **Unrelated improvements** - Don't suggest refactoring untouched code | ||
|
|
||
| **Key distinction:** |
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.
🛠️ Refactor suggestion | 🟠 Major
Add blank lines after subsection headings to comply with markdown standards.
Lines 11 and 20 introduce subsection headings that immediately precede list items without separating blank lines. This violates the MD022 rule, which requires headings to be surrounded by blank lines (both above and below).
🔎 Proposed fix
## CRITICAL: PR Scope and Context
### What IS in scope (report these issues):
+
1. **Issues in changed code** - Problems in files/lines actually modified by this PR
2. **Impact on unchanged code** - "You changed X but forgot to update Y that depends on it"
3. **Missing related changes** - "This pattern also exists in Z, did you mean to update it too?"
4. **Breaking changes** - "This change breaks callers in other files"
### What is NOT in scope (do NOT report):
+
1. **Pre-existing issues** - Old bugs/issues in code this PR didn't touch
2. **Unrelated improvements** - Don't suggest refactoring untouched code📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ### What IS in scope (report these issues): | |
| 1. **Issues in changed code** - Problems in files/lines actually modified by this PR | |
| 2. **Impact on unchanged code** - "You changed X but forgot to update Y that depends on it" | |
| 3. **Missing related changes** - "This pattern also exists in Z, did you mean to update it too?" | |
| 4. **Breaking changes** - "This change breaks callers in other files" | |
| ### What is NOT in scope (do NOT report): | |
| 1. **Pre-existing issues** - Old bugs/issues in code this PR didn't touch | |
| 2. **Unrelated improvements** - Don't suggest refactoring untouched code | |
| **Key distinction:** | |
| ### What IS in scope (report these issues): | |
| 1. **Issues in changed code** - Problems in files/lines actually modified by this PR | |
| 2. **Impact on unchanged code** - "You changed X but forgot to update Y that depends on it" | |
| 3. **Missing related changes** - "This pattern also exists in Z, did you mean to update it too?" | |
| 4. **Breaking changes** - "This change breaks callers in other files" | |
| ### What is NOT in scope (do NOT report): | |
| 1. **Pre-existing issues** - Old bugs/issues in code this PR didn't touch | |
| 2. **Unrelated improvements** - Don't suggest refactoring untouched code | |
| **Key distinction:** |
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
14-14: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
20-20: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🤖 Prompt for AI Agents
In apps/backend/prompts/github/pr_parallel_orchestrator.md around lines 11 to
21, the subsection headings at lines 11 and 20 lack a blank line separating them
from the following list items (violating MD022); insert a single blank line
after each of those subsection headings so each heading is followed by an empty
line before the list content (also verify there is a blank line above the
headings if needed to fully satisfy MD022).
| # Merge conflict status | ||
| has_merge_conflicts: bool = False # True if PR has conflicts with base branch | ||
| merge_state_status: str = ( | ||
| "" # BEHIND, BLOCKED, CLEAN, DIRTY, HAS_HOOKS, UNKNOWN, UNSTABLE | ||
| ) |
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.
🧹 Nitpick | 🔵 Trivial
Consider using an Enum for merge_state_status for consistency with the codebase.
Similar to the FollowupReviewContext in models.py, this field would benefit from an Enum definition. The file already uses Enums in related modules, and defining a MergeStateStatus enum would prevent string typos and provide better IDE support.
See the proposed enum definition in the review comment for apps/backend/runners/github/models.py (lines 565-569).
🤖 Prompt for AI Agents
In apps/backend/runners/github/context_gatherer.py around lines 207 to 211,
replace the plain string field merge_state_status with a typed Enum to avoid
string typos: define a MergeStateStatus enum (e.g., CLEAN, DIRTY, BEHIND,
BLOCKED, HAS_HOOKS, UNKNOWN, UNSTABLE) in the GitHub models module (or the file
suggested in the other review), import it here, change the field type to
MergeStateStatus, initialize it to MergeStateStatus.UNKNOWN (or an appropriate
default), and update any places that set or compare this field to use the enum
members instead of raw strings.
| # Merge conflict status | ||
| has_merge_conflicts: bool = False # True if PR has conflicts with base branch | ||
| merge_state_status: str = ( | ||
| "" # BEHIND, BLOCKED, CLEAN, DIRTY, HAS_HOOKS, UNKNOWN, UNSTABLE | ||
| ) |
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.
🧹 Nitpick | 🔵 Trivial
Consider using an Enum for merge_state_status to ensure type safety and consistency.
The file already defines multiple Enums (e.g., ReviewSeverity, ReviewCategory, MergeVerdict). Using a plain str for merge_state_status could lead to typos and inconsistent values. Additionally, defaulting to an empty string "" is ambiguous—consider using "UNKNOWN" to explicitly indicate when the status hasn't been fetched.
🔎 Proposed refactor to add MergeStateStatus enum
Add the enum definition after the existing enums (e.g., after line 76):
+class MergeStateStatus(str, Enum):
+ """GitHub PR merge state status."""
+
+ BEHIND = "BEHIND"
+ BLOCKED = "BLOCKED"
+ CLEAN = "CLEAN"
+ DIRTY = "DIRTY"
+ HAS_HOOKS = "HAS_HOOKS"
+ UNKNOWN = "UNKNOWN"
+ UNSTABLE = "UNSTABLE"Then update the field definition:
# Merge conflict status
has_merge_conflicts: bool = False # True if PR has conflicts with base branch
- merge_state_status: str = (
- "" # BEHIND, BLOCKED, CLEAN, DIRTY, HAS_HOOKS, UNKNOWN, UNSTABLE
- )
+ merge_state_status: MergeStateStatus = MergeStateStatus.UNKNOWNYou'll also need to update serialization/deserialization in the to_dict() and from_dict() methods if they exist for FollowupReviewContext.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/backend/runners/github/models.py around lines 565 to 569, replace the
plain str merge_state_status with a new MergeStateStatus enum (add the enum near
the other enums) and change the field type to that enum with a default of
MergeStateStatus.UNKNOWN instead of an empty string; update any
serialization/deserialization logic (to_dict/from_dict or pydantic/json helpers)
to emit/consume the enum's string value and update any code that constructs or
compares merge_state_status to use the enum members (or .value) to avoid string
typos.
| const TASK_WORKTREE_DIR = '.auto-claude/worktrees/tasks'; | ||
|
|
||
| function getWorktreeDir(projectPath: string): string { | ||
| return path.join(projectPath, TASK_WORKTREE_DIR); | ||
| } |
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# 1. Search for migration-related code regarding worktrees
echo "=== Searching for migration/backward compatibility code ==="
rg -i "migrate|migration|backward.*compat|upgrade" --type ts --type tsx -C 2 | grep -i "worktree\|\.worktrees" | head -20 || echo "No migration code found for worktrees"
# 2. Search for references to old .worktrees path (not under .auto-claude)
echo -e "\n=== Searching for old .worktrees path references ==="
rg '\.worktrees' --type ts --type tsx | grep -v '\.auto-claude' || echo "No direct .worktrees references found"
# 3. Search all worktree-related paths
echo -e "\n=== All worktree path definitions ==="
rg 'worktree|\.auto-claude' --type ts --type tsx -B1 -A1 | head -50
# 4. Check for any path constants related to worktrees across the codebase
echo -e "\n=== Worktree path constants ==="
rg "WORKTREE|worktree.*DIR|worktree.*PATH" --type ts --type tsx | head -20
# 5. Look for the actual implementation in project-store.ts
echo -e "\n=== Checking project-store.ts file ==="
head -20 apps/frontend/src/main/project-store.ts 2>/dev/null || echo "File not found at expected path"Repository: AndyMik90/Auto-Claude
Length of output: 1235
🏁 Script executed:
#!/bin/bash
# 1. Search for any "worktree" references across all files (no type restriction)
echo "=== All worktree references (all file types) ==="
rg -i "worktree" | head -40
# 2. Search for .auto-claude references to understand path structure
echo -e "\n=== References to .auto-claude paths ==="
rg "\.auto-claude" | head -30
# 3. Check if there are any old-style paths like .worktrees
echo -e "\n=== Check for any .worktrees paths ==="
rg "\.worktrees" | head -20 || echo "No .worktrees found"
# 4. Look at the git history briefly to see if old paths existed
echo -e "\n=== Recent commits affecting worktree paths ==="
git log --oneline --all -20 | grep -i "worktree\|path\|migrate" || echo "No recent worktree/path commits in recent history"
# 5. Check project structure and shared constants
echo -e "\n=== Checking shared constants file ==="
fd -e ts -e tsx | xargs grep -l "WORKTREE\|worktree" | head -10Repository: AndyMik90/Auto-Claude
Length of output: 8539
Address incomplete migration from .worktrees/ to .auto-claude/worktrees/tasks/.
The new TASK_WORKTREE_DIR constant introduces a breaking change in the worktree path structure. However, the codebase still contains multiple references to the old .worktrees/ path that must be updated in parallel:
- Documentation:
guides/CLI-USAGE.md,CLAUDE.md - Type definitions:
apps/frontend/src/shared/types/task.ts,apps/frontend/src/shared/types/ipc.ts(outdated comments) - Build config:
apps/frontend/electron.vite.config.ts(exclusion patterns) - File handling:
apps/frontend/src/main/ipc-handlers/file-handlers.ts(ignore list) - Tests:
tests/test_worktree.py,tests/test_workspace.py
Without updating these references and implementing migration logic for existing installations, this change will cause inconsistencies and potential data loss. Ensure all path references are consolidated, documentation is updated, and a migration strategy is implemented.
🤖 Prompt for AI Agents
In apps/frontend/src/main/project-store.ts around lines 9 to 13, the new
TASK_WORKTREE_DIR constant changes the worktree path to
'.auto-claude/worktrees/tasks' but other parts of the repo still reference
'.worktrees/', causing breakage; update all references listed
(guides/CLI-USAGE.md, CLAUDE.md, apps/frontend/src/shared/types/task.ts,
apps/frontend/src/shared/types/ipc.ts, apps/frontend/electron.vite.config.ts,
apps/frontend/src/main/ipc-handlers/file-handlers.ts, tests/test_worktree.py,
tests/test_workspace.py) to use the new path or neutral constant, and implement
migration logic in project-store (detect existing '.worktrees' directories on
startup, move or symlink them to the new TASK_WORKTREE_DIR preserving data and
permissions, and log/report any failures) plus update comments/types, exclusion
patterns, ignore lists, docs, and tests to reflect the new path.
| debugLog('[TerminalWorktree] Using base branch:', baseBranch, customBaseBranch ? '(custom)' : '(default)'); | ||
|
|
||
| try { | ||
| execSync(`git fetch origin ${baseBranch}`, { |
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.
Command injection via unvalidated baseBranch parameter in shell commands
The customBaseBranch parameter from the IPC request is passed directly to execSync shell commands without validation or sanitization. While the name parameter is validated against a regex, baseBranch has no validation. A malicious value like main; rm -rf / would result in command execution since the value is interpolated unquoted into shell command strings. The IPC handler receives data that could be manipulated by a compromised renderer process or XSS attack. Using execFileSync with separate arguments instead of string interpolation with execSync would prevent this.
Additional Locations (1)
Remove tests for staging methods that were removed during the worktree storage consolidation refactor: - Remove entire TestStagingWorktree class - Remove test_remove_staging test - Remove staging-related tests from TestWorktreeCommitAndMerge - Update TestChangeTracking tests to use create_worktree - Update TestWorktreeUtilities tests to use create_worktree 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
| import pytest | ||
|
|
||
| from worktree import WorktreeManager, WorktreeInfo, WorktreeError, STAGING_WORKTREE_NAME | ||
| from worktree import WorktreeManager, WorktreeInfo, WorktreeError |
Check notice
Code scanning / CodeQL
Unused import Note test
Import of 'WorktreeError' is not used.
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 4 days ago
To fix the problem, remove the unused names from the import statement so that you only import what is actually used in this test module. This keeps dependencies minimal and makes the code clearer.
Concretely, in tests/test_worktree.py, adjust the import on line 19 so it imports only WorktreeManager. Do not change the module path or other imports, just reduce the list of imported symbols. No additional methods, imports, or definitions are needed; this is a simple import-list edit and does not affect existing functionality, since the removed names are not referenced in the provided code.
-
Copy modified line R19
| @@ -16,7 +16,7 @@ | ||
|
|
||
| import pytest | ||
|
|
||
| from worktree import WorktreeManager, WorktreeInfo, WorktreeError | ||
| from worktree import WorktreeManager | ||
|
|
||
|
|
||
| class TestWorktreeManagerInitialization: |
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.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
tests/test_worktree.py (4)
2-12: Outdated docstring: "Staging worktree management" no longer applies.Line 8 references "Staging worktree management" but the AI summary indicates staging APIs were removed in this PR. Update the docstring to reflect the current functionality.
🔎 Suggested fix
""" Tests for Git Worktree Management ================================= Tests the worktree.py module functionality including: - Worktree creation and removal -- Staging worktree management +- Per-spec worktree management - Branch operations - Merge operations - Change tracking """
226-230: Strengthen assertion: verify exact file count instead of> 0.The assertion
assert len(files) > 0is weak. Since the test adds exactly one file (added.txt), assert the expected count for stronger validation.🔎 Suggested fix
files = manager.get_changed_files("test-spec") - assert len(files) > 0 + assert len(files) == 1 file_names = [f[1] for f in files] assert "added.txt" in file_names
236-246: Consider asserting worktree names/branches, not just count.The test verifies the count of worktrees but doesn't validate that the correct worktrees (
spec-1,spec-2) are returned. This could miss bugs where wrong worktrees are listed.🔎 Suggested fix
worktrees = manager.list_all_worktrees() assert len(worktrees) == 2 + branches = {wt.branch for wt in worktrees} + assert "auto-claude/spec-1" in branches + assert "auto-claude/spec-2" in branches
268-278: Test could verify worktree directories are actually removed.The test creates 3 worktrees, calls
cleanup_all(), and verifies the list is empty. Consider also asserting that the worktree directories no longer exist on disk for stronger validation.🔎 Suggested fix
def test_cleanup_all(self, temp_git_repo: Path): """cleanup_all removes all worktrees.""" manager = WorktreeManager(temp_git_repo) manager.setup() - manager.create_worktree("spec-1") - manager.create_worktree("spec-2") - manager.create_worktree("spec-3") + info1 = manager.create_worktree("spec-1") + info2 = manager.create_worktree("spec-2") + info3 = manager.create_worktree("spec-3") manager.cleanup_all() assert len(manager.list_all_worktrees()) == 0 + assert not info1.path.exists() + assert not info2.path.exists() + assert not info3.path.exists()
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
tests/test_worktree.py
🧰 Additional context used
📓 Path-based instructions (1)
tests/**
⚙️ CodeRabbit configuration file
tests/**: Ensure tests are comprehensive and follow pytest conventions.
Check for proper mocking and test isolation.
Files:
tests/test_worktree.py
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Use git worktrees for isolated agent builds with branches following the naming pattern `auto-claude/{spec-name}`
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Use git worktrees for isolated agent builds with branches following the naming pattern `auto-claude/{spec-name}`
Applied to files:
tests/test_worktree.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Cursor Bugbot
- GitHub Check: CodeQL (javascript-typescript)
- GitHub Check: CodeQL (python)
🔇 Additional comments (4)
tests/test_worktree.py (4)
25-31: LGTM! Path assertion correctly updated to new worktree location.The assertion on line 30 correctly validates the new consolidated worktree path
.auto-claude/worktrees/tasks, aligning with the PR's objective to consolidate worktree storage.
77-88: LGTM! Test validates branch naming convention.The test correctly verifies that worktree branches follow the
auto-claude/{spec-name}naming pattern, which aligns with the retrieved learnings about branch naming conventions.
192-211: LGTM! Test updated to use per-spec worktree for change tracking.The test now correctly creates a dedicated worktree and commits changes before verifying the change summary, aligning with the removal of staging worktree semantics.
308-319: LGTM! Test uses distinct spec name to avoid conflicts.Good practice using
"test-spec-node"as a distinct spec name and updating line 317 to match, avoiding potential conflicts with other tests.
| import pytest | ||
|
|
||
| from worktree import WorktreeManager, WorktreeInfo, WorktreeError, STAGING_WORKTREE_NAME | ||
| from worktree import WorktreeManager, WorktreeInfo, WorktreeError |
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.
🧹 Nitpick | 🔵 Trivial
Unused import: WorktreeError is imported but never used.
WorktreeError is imported but no tests exercise error scenarios. Per coding guidelines, tests should be comprehensive. Consider adding tests for error cases such as:
- Creating a worktree with an invalid spec name
- Removing a non-existent worktree
- Getting info for a non-existent worktree
🔎 Example error case test
class TestWorktreeErrors:
"""Tests for error handling."""
def test_remove_nonexistent_worktree_raises_error(self, temp_git_repo: Path):
"""Removing a non-existent worktree raises WorktreeError."""
manager = WorktreeManager(temp_git_repo)
manager.setup()
with pytest.raises(WorktreeError):
manager.remove_worktree("nonexistent-spec")
def test_get_info_nonexistent_returns_none(self, temp_git_repo: Path):
"""Getting info for non-existent worktree returns None."""
manager = WorktreeManager(temp_git_repo)
manager.setup()
info = manager.get_worktree_info("nonexistent-spec")
assert info is None🤖 Prompt for AI Agents
In tests/test_worktree.py around line 19, the imported WorktreeError is unused;
add a new TestWorktreeErrors class with tests that exercise error cases:
instantiate WorktreeManager(temp_git_repo), call manager.setup(), then (1)
assert that removing a non-existent worktree raises WorktreeError using
pytest.raises(manager.remove_worktree("nonexistent-spec")), (2) assert that
get_worktree_info("nonexistent-spec") returns None, and (3) add a test that
creating a worktree with an invalid spec name raises WorktreeError; use the
existing temp_git_repo fixture and follow the project’s pytest style and
assertions so the import becomes used.
AndyMik90
left a comment
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.
🤖 Auto Claude PR Review
Merge Verdict: 🔴 BLOCKED
Blocked by 1 security vulnerabilities
Risk Assessment
| Factor | Level | Notes |
|---|---|---|
| Complexity | High | Based on lines changed |
| Security Impact | Critical | Based on security findings |
| Scope Coherence | Good | Based on structural review |
🚨 Blocking Issues (Must Fix)
- Security: Command injection via baseBranch parameter (apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts:126)
Findings Summary
- Critical: 1 issue(s)
- High: 2 issue(s)
- Medium: 9 issue(s)
- Low: 3 issue(s)
Generated by Auto Claude PR Review
Findings (15 selected of 15 total)
🔴 [CRITICAL] Command injection via baseBranch parameter
📁 apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts:126
The baseBranch parameter from user input is passed directly to execSync shell commands without validation: execSync(git fetch origin ${baseBranch}) and execSync(git rev-parse --verify origin/${baseBranch}). A malicious baseBranch value like main; rm -rf / or main$(whoami) would execute arbitrary commands. While the frontend limits selection to a dropdown, the backend IPC handler has no validation.
Suggested fix:
Add validation: `if (customBaseBranch && !/^[a-zA-Z0-9_.\/\-]+$/.test(customBaseBranch)) { return { success: false, error: 'Invalid base branch name' }; }`. Better: use execFileSync with array arguments instead of string interpolation.
🟠 [HIGH] Missing input validation in removeTerminalWorktree allows path traversal
📁 apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts:212
The removeTerminalWorktree function accepts name parameter without validation (unlike createTerminalWorktree). A malicious name like ../important-data could target directories outside the intended worktree location. The existsSync check and git worktree remove --force would then operate on unintended directories.
Suggested fix:
Add the same validation regex at the start of removeTerminalWorktree: `if (!/^[a-zA-Z0-9_-]+$/.test(name)) { return { success: false, error: 'Invalid worktree name' }; }`
🟠 [HIGH] Race condition between store update and PTY destruction
📁 apps/frontend/src/renderer/components/Terminal.tsx:175
In handleWorktreeCreated, the code updates the store with new cwd (line 180), then awaits destroyTerminal (line 184), then calls resetForRecreate(). However, usePtyProcess's effect depends on cwd in its dependency array. The store update triggers a re-render and the effect may run BEFORE destroyTerminal completes, potentially creating a new PTY while the old one is still being destroyed.
Suggested fix:
Set isCreatingRef.current = true BEFORE updating the store to prevent the effect from running, or restructure so destroyTerminal completes before updateTerminal is called.
🟡 [MEDIUM] Shell injection risk with execSync string interpolation
📁 apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts:150
All git commands use execSync with string interpolation in shell context. Even with current validation, this pattern is inherently risky. Double quotes in bash still allow variable expansion and command substitution. Using execFileSync with array arguments eliminates shell interpretation entirely.
Suggested fix:
Use execFileSync instead of execSync: `execFileSync('git', ['worktree', 'add', '-b', branchName, worktreePath, baseRef], { cwd: projectPath, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] })`
🟡 [MEDIUM] Missing projectPath validation allows filesystem enumeration
📁 apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts:269
All three IPC handlers (create, list, remove) accept projectPath directly from the renderer process without validation. An attacker with renderer access could call listTerminalWorktrees('/etc') or other paths to probe filesystem locations.
Suggested fix:
Validate projectPath against registered projects: `const project = projectStore.getProjects().find(p => p.path === projectPath); if (!project) { return { success: false, error: 'Invalid project path' }; }`
🟡 [MEDIUM] Uncaught exception when git commands fail in getDefaultBranch
📁 apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts:65
The getDefaultBranch function calls execSync('git rev-parse --abbrev-ref HEAD') at line 65-69 without try-catch. If this command fails (corrupted git state, detached HEAD issues, git not in PATH), it throws an uncaught exception. Earlier git commands are wrapped in try-catch, but this fallback is not.
Suggested fix:
Wrap lines 65-69 in a try-catch block and return a sensible default (e.g., 'main') or throw a more descriptive error.
🟡 [MEDIUM] Partial state on git worktree creation failure - no cleanup
📁 apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts:149
In createTerminalWorktree, mkdirSync creates the parent directory (line 119) before git worktree add (lines 150/157). If git worktree add fails (branch already exists, permission issues), the directory structure remains. Subsequent calls fail with 'Worktree already exists' because existsSync returns true even though the worktree was never fully created.
Suggested fix:
Add cleanup logic in the catch block (lines 180-186) to remove the worktreePath directory if it exists but git worktree creation failed.
🟡 [MEDIUM] Duplicated TASK_WORKTREE_DIR constant and helpers across 4+ files
📁 apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts:16
The constant TASK_WORKTREE_DIR and helper functions (getTaskWorktreeDir, getTaskWorktreePath, findTaskWorktree) are duplicated in execution-handlers.ts, worktree-handlers.ts, task-log-service.ts, and project-store.ts. TERMINAL_WORKTREE_DIR follows the same pattern. Changes to worktree structure require updating all files.
Suggested fix:
Extract to shared module 'apps/frontend/src/main/worktree-utils.ts' with exported constants and helper functions.
🟡 [MEDIUM] Validation regex inconsistency between frontend and backend
📁 apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts:96
Frontend (CreateWorktreeDialog.tsx line 140) uses /^[a-z0-9][a-z0-9_-]*[a-z0-9]$|^[a-z0-9]$/ (lowercase only, alphanumeric start/end). Backend (worktree-handlers.ts line 96) uses /^[a-zA-Z0-9_-]+$/ (allows uppercase, allows starting with dash). This inconsistency means direct IPC calls could create names the frontend doesn't expect.
Suggested fix:
Synchronize validation: export a shared WORKTREE_NAME_REGEX from constants and use in both frontend and backend. Backend should be authoritative.
🟡 [MEDIUM] SHA prefix comparison may cause false matches
📁 apps/backend/runners/github/gh_client.py:1014
SHA comparison uses asymmetric logic: commit['sha'].startswith(base_sha) or base_sha.startswith(commit['sha'][:8]). If base_sha is very short (e.g., 4 chars), it could match multiple commits. The [:8] slice on the second condition is arbitrary and inconsistent with the first.
Suggested fix:
Normalize comparison to use a minimum prefix length for both sides: `commit['sha'][:8] == base_sha[:8]` or require minimum 7-char SHAs.
🟡 [MEDIUM] Return type inconsistency: TerminalWorktreeResult vs IPCResult
📁 apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts:91
createTerminalWorktree returns TerminalWorktreeResult with { success, config?, error? } while codebase standard is IPCResult with { success, data?, error? }. listTerminalWorktrees correctly uses IPCResult but createTerminalWorktree deviates.
Suggested fix:
Change TerminalWorktreeResult to use IPCResult<TerminalWorktreeConfig> pattern: return { success: true, data: config } instead of { success: true, config }
🟡 [MEDIUM] loadWorktreeConfig silently returns null on JSON parse error
📁 apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts:81
If config.json has malformed JSON, the catch block returns null with no logging. Corrupted config files make worktrees silently invisible in the list. Users cannot interact with these worktrees through the UI with no indication why.
Suggested fix:
Add debugError call in the catch block: `debugError('[TerminalWorktree] Corrupted config.json in:', configPath, err);`
🔵 [LOW] Unused variable pr_commit_shas - dead code
📁 apps/backend/runners/github/gh_client.py:1009
The set pr_commit_shas is built from PR commits but never used. The subsequent code iterates pr_commits directly. This appears to be leftover from development.
Suggested fix:
Remove line 1009 as it serves no purpose.
🔵 [LOW] Unused ref recreateRequestedRef is never read
📁 apps/frontend/src/renderer/components/terminal/usePtyProcess.ts:25
The recreateRequestedRef is set to true in two places (lines 35 and 114) but is never read anywhere. This appears to be dead code intended to track recreation state but never integrated.
Suggested fix:
Either remove recreateRequestedRef if not needed, or add logic that reads it to implement the intended behavior.
🔵 [LOW] No user feedback when IDE fails to open
📁 apps/frontend/src/renderer/components/Terminal.tsx:207
handleOpenInIDE logs errors to console but doesn't show user feedback. Users receive no indication when IDE launch fails.
Suggested fix:
Add toast notification for failed IDE launches.
This review was generated by Auto Claude.
|
|
||
| // Reset the usePtyProcess hook's internal refs to allow recreation | ||
| // The effect will trigger because effectiveCwd has changed (reads from store) | ||
| resetForRecreate(); |
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.
Race condition when creating worktree before PTY ready
The worktree creation handlers (handleWorktreeCreated and handleSelectWorktree) check isCreatedRef.current from Terminal.tsx to decide whether to destroy the PTY, but this ref is separate from usePtyProcess.ts's internal isCreatedRef. If a user creates a worktree before the initial PTY creation completes, Terminal.tsx's isCreatedRef is still false so destroyTerminal is skipped, but resetForRecreate() resets the hook's refs allowing a second PTY to be created. This results in two PTY processes for the same terminal - a resource leak and potential for mixed terminal output.
Additional Locations (1)
…ndlers CRITICAL: - Add GIT_BRANCH_REGEX validation for baseBranch to prevent command injection - Replace execSync with execFileSync to eliminate shell interpretation HIGH: - Add name validation in removeTerminalWorktree to prevent path traversal - Fix race condition in handleWorktreeCreated by adding prepareForRecreate MEDIUM: - Add projectPath validation against registered projects - Add try-catch for getDefaultBranch fallback - Add cleanup logic on worktree creation failure - Add logging for config.json parse errors LOW: - Remove unused recreateRequestedRef from usePtyProcess - Add toast notification for IDE launch failures 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
The function was only checking the new path but missing the legacy fallback for existing worktrees at .worktrees/. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
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.
Actionable comments posted: 1
♻️ Duplicate comments (2)
apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts (2)
116-143: User-facing error messages should use i18n translation keys.Per coding guidelines, all user-facing text in the frontend should use i18n translation keys instead of hardcoded strings. The error messages here will be displayed to users but are hardcoded in English.
Consider returning error codes that the frontend can map to translated strings:
// Example error code approach export const WORKTREE_ERRORS = { INVALID_PROJECT_PATH: 'terminal:worktree.errors.invalidProjectPath', INVALID_WORKTREE_NAME: 'terminal:worktree.errors.invalidWorktreeName', // ... } as const;Based on coding guidelines requiring i18n for user-facing text.
220-239: Incomplete cleanup: orphaned git branch on partial failure.If
git worktree add -bsucceeds (creating both worktree and branch) butsaveWorktreeConfigthrows, the cleanup removes the worktree directory and prunes stale registrations, but doesn't delete the orphaned git branch.🔎 Proposed fix to clean up orphaned branch
try { rmSync(worktreePath, { recursive: true, force: true }); debugLog('[TerminalWorktree] Cleaned up failed worktree directory:', worktreePath); // Also prune stale worktree registrations try { execFileSync('git', ['worktree', 'prune'], { cwd: projectPath, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], }); debugLog('[TerminalWorktree] Pruned stale worktree registrations'); } catch { // Ignore prune errors - not critical } + // Clean up the branch if it was created + if (createGitBranch) { + try { + execFileSync('git', ['branch', '-D', branchName], { + cwd: projectPath, + encoding: 'utf-8', + stdio: ['pipe', 'pipe', 'pipe'], + }); + debugLog('[TerminalWorktree] Cleaned up orphaned branch:', branchName); + } catch { + // Branch may not have been created, ignore + } + } } catch (cleanupError) {
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (6)
apps/frontend/src/main/ipc-handlers/task/execution-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.tsapps/frontend/src/main/project-store.tsapps/frontend/src/main/task-log-service.tsapps/frontend/src/main/worktree-paths.ts
🧰 Additional context used
📓 Path-based instructions (3)
apps/frontend/src/**/*.{ts,tsx,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always use i18n translation keys for all user-facing text in the frontend instead of hardcoded strings
Files:
apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.tsapps/frontend/src/main/project-store.tsapps/frontend/src/main/task-log-service.tsapps/frontend/src/main/ipc-handlers/task/execution-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/main/worktree-paths.ts
apps/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use
useTranslation()hook with namespace prefixes (e.g., 'navigation:items.key') for accessing translation strings in React components
Files:
apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.tsapps/frontend/src/main/project-store.tsapps/frontend/src/main/task-log-service.tsapps/frontend/src/main/ipc-handlers/task/execution-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/main/worktree-paths.ts
apps/frontend/**/*.{ts,tsx}
⚙️ CodeRabbit configuration file
apps/frontend/**/*.{ts,tsx}: Review React patterns and TypeScript type safety.
Check for proper state management and component composition.
Files:
apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.tsapps/frontend/src/main/project-store.tsapps/frontend/src/main/task-log-service.tsapps/frontend/src/main/ipc-handlers/task/execution-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/main/worktree-paths.ts
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Use git worktrees for isolated agent builds with branches following the naming pattern `auto-claude/{spec-name}`
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Applies to apps/frontend/src/**/*.{ts,tsx,jsx} : Always use i18n translation keys for all user-facing text in the frontend instead of hardcoded strings
Applied to files:
apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Applies to apps/frontend/src/shared/i18n/locales/**/*.json : When implementing new frontend features, add translation keys to all language files (minimum: en/*.json and fr/*.json)
Applied to files:
apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Applies to apps/frontend/src/**/*.{ts,tsx} : Use `useTranslation()` hook with namespace prefixes (e.g., 'navigation:items.key') for accessing translation strings in React components
Applied to files:
apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Use git worktrees for isolated agent builds with branches following the naming pattern `auto-claude/{spec-name}`
Applied to files:
apps/frontend/src/main/project-store.tsapps/frontend/src/main/ipc-handlers/task/execution-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/main/worktree-paths.ts
🧬 Code graph analysis (5)
apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts (5)
apps/frontend/src/main/project-store.ts (1)
projectStore(785-785)apps/frontend/src/main/ipc-handlers/context/utils.ts (1)
parseEnvFile(38-61)apps/frontend/src/shared/types/terminal.ts (2)
TerminalWorktreeConfig(144-161)CreateTerminalWorktreeRequest(166-179)apps/frontend/src/main/worktree-paths.ts (2)
getTerminalWorktreePath(58-60)getTerminalWorktreeDir(51-53)apps/frontend/src/main/ipc-handlers/terminal/index.ts (1)
registerTerminalWorktreeHandlers(17-17)
apps/frontend/src/main/project-store.ts (1)
apps/frontend/src/main/worktree-paths.ts (1)
getTaskWorktreeDir(21-23)
apps/frontend/src/main/task-log-service.ts (1)
apps/frontend/src/main/worktree-paths.ts (1)
findTaskWorktree(36-46)
apps/frontend/src/main/ipc-handlers/task/execution-handlers.ts (1)
apps/frontend/src/main/worktree-paths.ts (1)
findTaskWorktree(36-46)
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts (1)
apps/frontend/src/shared/constants/config.ts (1)
AUTO_BUILD_PATHS(81-98)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Cursor Bugbot
- GitHub Check: CodeQL (javascript-typescript)
- GitHub Check: CodeQL (python)
🔇 Additional comments (11)
apps/frontend/src/main/project-store.ts (1)
8-8: Good: Centralized worktree path import.The import of
getTaskWorktreeDirfrom the shared module properly addresses the DRY concerns flagged in previous reviews. This centralizes path handling and ensures consistency across the codebase.apps/frontend/src/main/task-log-service.ts (1)
5-13: Well-structured helper with proper legacy support.The
findWorktreeSpecDirhelper cleanly wrapsfindTaskWorktree(which includes legacy path fallback) and constructs the full spec directory path. This addresses the DRY concerns from previous reviews while maintaining backward compatibility.apps/frontend/src/main/ipc-handlers/task/execution-handlers.ts (2)
18-18: Good: Centralized worktree discovery with legacy support.The refactoring to use
findTaskWorktreefrom the shared module properly addresses past review concerns about:
- DRY violations (centralized helper)
- Missing legacy path fallback (the helper checks both new and legacy paths)
The derived
hasWorktreeboolean simplifies the conditional logic throughout the handler.Also applies to: 336-338
386-393: Good: Protect .auto-claude directory during git clean.The
-e .auto-claudeexclusion prevents accidental deletion of specs and worktree data when discarding changes. This is a sensible safeguard.apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts (2)
130-136: Good: baseBranch validation prevents command injection.The
GIT_BRANCH_REGEXvalidation at line 131 addresses the command injection vulnerability flagged in previous reviews. Combined withexecFileSync(which doesn't use shell interpolation), this provides robust protection against malicious branch names.
311-327: Good: Defense-in-depth validation of config.branchName.The re-validation of
config.branchNameagainstGIT_BRANCH_REGEXbefore using it in the git command addresses the past review concern about tampered config files. This is good defensive coding.apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts (4)
15-18: Good: Centralized worktree path utilities.The import of
getTaskWorktreeDirandfindTaskWorktreefrom the shared module properly centralizes path handling and addresses the DRY concerns from previous reviews.
1176-1183: Cleaner worktree discovery logic.The refactored code using
findTaskWorktreeis more readable and includes legacy path fallback, ensuring backward compatibility with existing worktrees at the old location.
2175-2265: List operation may miss legacy worktrees.The
TASK_LIST_WORKTREEShandler usesgetTaskWorktreeDir()which only returns the new path (.auto-claude/worktrees/tasks). Worktrees at the legacy.worktrees/location won't be listed.Consider also scanning the legacy directory for completeness:
// Scan both new and legacy directories const dirsToScan = [ getTaskWorktreeDir(project.path), path.join(project.path, LEGACY_WORKTREE_DIR) ]; for (const worktreesDir of dirsToScan) { if (existsSync(worktreesDir)) { // ... scan logic } }Alternatively, this might be intentional to encourage migration - please clarify.
1669-1690: Good: Guarded worktree cleanup prevents errors.The cleanup paths now properly check
worktreePath && existsSync(worktreePath)before attempting removal, preventing errors when the worktree doesn't exist or was already cleaned up.Also applies to: 1715-1737
apps/frontend/src/main/worktree-paths.ts (1)
1-76: Excellent: Well-designed centralized worktree path module.This new module properly addresses the DRY violations flagged across multiple files in previous reviews. Key design decisions:
- Clear separation of concerns: "get" functions construct paths, "find" functions discover existing worktrees with legacy fallback
- Backward compatibility:
findTaskWorktreeandfindTerminalWorktreecheck new paths first, then fall back to legacy locations- Single source of truth: Constants centralize the path patterns for consistent usage
The different legacy naming conventions (task:
{specId}vs terminal:terminal-{name}) are correctly handled in each respective find function.
| // This prevents deleted tasks from "coming back" when the worktree isn't cleaned up. | ||
| // Alternative behavior: include all worktree tasks (remove the mainSpecIds check below). | ||
| const worktreesDir = path.join(project.path, '.worktrees'); | ||
| const worktreesDir = getTaskWorktreeDir(project.path); |
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check for legacy worktree references and migration logic
rg -n "LEGACY_WORKTREE_DIR|\.worktrees|legacy" --type ts -i | head -50Repository: AndyMik90/Auto-Claude
Length of output: 5325
🏁 Script executed:
#!/bin/bash
# Find getTaskWorktreeDir and findTaskWorktree implementations
rg -n "getTaskWorktreeDir|findTaskWorktree" --type ts -A 5 -B 1Repository: AndyMik90/Auto-Claude
Length of output: 10788
🏁 Script executed:
#!/bin/bash
# Check context around line 267 in project-store.ts
cat -n apps/frontend/src/main/project-store.ts | sed -n '260,280p'Repository: AndyMik90/Auto-Claude
Length of output: 1205
Use findTaskWorktree to support legacy worktree locations during project initialization.
The code at line 267 scans for worktrees using getTaskWorktreeDir(), which returns only the new path (.auto-claude/worktrees/tasks). However, existing installations may have worktrees at the legacy location (.worktrees/). The codebase already defines LEGACY_WORKTREE_DIR and provides findTaskWorktree() for legacy fallback support (used elsewhere in task-log-service.ts, execution-handlers.ts, and worktree-handlers.ts), but this scan misses them.
Either use findTaskWorktree() to discover individual worktrees, or check both locations when scanning.
🤖 Prompt for AI Agents
In apps/frontend/src/main/project-store.ts around line 267, the code currently
uses getTaskWorktreeDir(project.path) which only returns the new worktree path
and therefore misses legacy worktrees; replace that lookup with
findTaskWorktree(project.path) (or modify the scan to check both the new
getTaskWorktreeDir() and LEGACY_WORKTREE_DIR locations) so initialization
discovers existing legacy worktrees; ensure you handle the returned value(s)
consistently with the rest of the code (null/undefined if not found) and reuse
the existing helper rather than hard-coding paths.
Function is used for both AppleScript and shell contexts - the new name better reflects that it escapes single quotes for any single-quoted string. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
|
|
||
| const worktreesDir = path.join(project.path, '.worktrees'); | ||
| const worktrees: WorktreeListItem[] = []; | ||
| const worktreesDir = getTaskWorktreeDir(project.path); |
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.
Worktree listing misses legacy paths, breaking upgrades
The worktree path handling is inconsistent between individual lookups and directory scanning. findTaskWorktree() correctly checks both the new path (.auto-claude/worktrees/tasks/) and legacy path (.worktrees/), but scanning functions like TASK_LIST_WORKTREES, checkWorktreesForVersion in release-service, and loadTasksForProject in project-store only check the new path via getTaskWorktreeDir(). Users upgrading from the old worktree location will not see their existing worktrees in listings, release checks won't detect unmerged legacy worktrees (potentially allowing releases with unmerged work), and task deduplication logic may miss legacy worktree data.
Additional Locations (2)
| if (isCreatedRef.current) { | ||
| await window.electronAPI.destroyTerminal(id); | ||
| isCreatedRef.current = false; | ||
| } |
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.
PTY destruction result ignored, may cause orphaned processes
In handleWorktreeCreated and handleSelectWorktree, the result of destroyTerminal is awaited but completely ignored. The destroyTerminal function can return {success: false} if the terminal is not found or if destruction fails with an exception. When destruction fails, the code still sets isCreatedRef = false and calls resetForRecreate(), which triggers creation of a new PTY. This can leave orphaned PTY processes running (resource leak), cause race conditions with the old PTY still processing events, and leave the terminal in an inconsistent state where the store reflects one directory but the actual shell is in another.
Additional Locations (1)
…reviews When a PR is rebased or force-pushed, commit SHAs change but file content blob SHAs persist. This feature stores blob SHAs during initial review and uses them to detect which files actually changed content when the old commit SHA is no longer found in the PR history. Changes: - Add reviewed_file_blobs field to PRReviewResult model - Update get_pr_files_changed_since with blob comparison fallback - Capture file blobs in all reviewer implementations - Pass blob data through context gatherer for follow-ups - Update TypeScript types and IPC handler mapping This prevents unnecessary re-review of unchanged files after rebases, improving follow-up review efficiency and accuracy. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
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.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts (1)
2165-2267: Worktree listing doesn't check legacy paths, breaking backward compatibility.The
TASK_LIST_WORKTREEShandler only scans.auto-claude/worktrees/tasks/viagetTaskWorktreeDir(), but doesn't check the legacy.worktrees/directory. This is inconsistent with individual worktree lookups (STATUS, DIFF, DISCARD) which usefindTaskWorktree()to check both paths.Impact:
- Users upgrading from the old worktree location won't see their existing worktrees in the UI
- Any code that relies on this listing (e.g., release validation, task deduplication) will miss legacy worktrees
- Data loss risk if users don't realize their old worktrees still exist
🔎 Proposed fix: Scan both new and legacy directories
const worktrees: WorktreeListItem[] = []; - const worktreesDir = getTaskWorktreeDir(project.path); + // Check both new and legacy worktree directories for backward compatibility + const TASK_WORKTREE_DIR = '.auto-claude/worktrees/tasks'; + const LEGACY_WORKTREE_DIR = '.worktrees'; + const worktreeDirs = [ + path.join(project.path, TASK_WORKTREE_DIR), + path.join(project.path, LEGACY_WORKTREE_DIR) + ]; // Helper to process a single worktree entry const processWorktreeEntry = (entry: string, entryPath: string) => { // ... existing code ... }; - // Scan worktrees directory - if (existsSync(worktreesDir)) { - const entries = readdirSync(worktreesDir); + // Scan both worktree directories + for (const worktreesDir of worktreeDirs) { + if (!existsSync(worktreesDir)) continue; + + const entries = readdirSync(worktreesDir); for (const entry of entries) { const entryPath = path.join(worktreesDir, entry); try { const stat = statSync(entryPath); if (stat.isDirectory()) { processWorktreeEntry(entry, entryPath); } } catch { // Skip entries that can't be stat'd } } }Note: You'll need to import or define
TASK_WORKTREE_DIRandLEGACY_WORKTREE_DIRconstants, which should match the values inworktree-paths.ts.apps/backend/runners/github/services/followup_reviewer.py (1)
28-52: Blob SHA capture for follow-up reviews is well-containedImporting
GHClientand capturingfilename → shaviaget_pr_files()before returningPRReviewResultgives the follow-up pipeline a stable content identifier across rebases. Errors are downgraded to warnings, which is appropriate for an enrichment-only feature.You now have identical blob-capture blocks here, in the orchestrator, and in the parallel reviewers; consider extracting a small helper (e.g.
async def collect_pr_file_blobs(gh_client, pr_number) -> dict[str, str]) to avoid divergence over time, but the current behavior is functionally sound.Also applies to: 235-275
apps/backend/runners/github/services/parallel_orchestrator_reviewer.py (1)
31-50: Parallel orchestrator blob tracking matches the rest of the pipelineThe new
GHClientimport andfile_blobscollection inreview()correctly snapshot per-file blob SHAs and thread them throughPRReviewResult.reviewed_file_blobs. The try/except keeps this enrichment non-fatal if GitHub API calls fail.Given the same pattern now exists in several services, you might later centralize this into a shared helper to reduce duplication and ensure consistent logging, but behavior-wise this looks good.
Also applies to: 804-837
apps/backend/runners/github/services/parallel_followup_reviewer.py (1)
32-59: Rebase-resistant blob capture is correctly integrated into parallel follow-up reviewsCreating a
GHClientwithproject_dir=self.project_dirandrepo=self.config.repo, then fillingreviewed_file_blobsfromget_pr_files(context.pr_number), aligns with how initial and sequential follow-up reviewers now behave. The best-effort try/except keeps this from impacting review success/failure.Same note as elsewhere: the blob-capture block is duplicated across multiple services and could be factored into a shared helper, but the current implementation is correct.
Also applies to: 503-542
♻️ Duplicate comments (3)
apps/backend/runners/github/gh_client.py (1)
983-1083: Shortbase_shaprefixes (<7 chars) never match, forcing fallback pathIn
get_pr_files_changed_since,base_prefixmay be shorter than 7 characters, butcommit_prefixis always 7 characters long. Whenlen(base_sha) < 7,base_prefix(e.g."abc12") can never equalcommit["sha"][:7](e.g."abc1234"), sobase_indexremains-1even if the commit actually exists. That unnecessarily forces the "base not found" fallback (blob comparison or full PR) for valid short SHAs.This doesn’t corrupt results (you still get all files/commits) but it defeats the intent of efficiently finding commits after a known base when callers store short SHAs.
Proposed fix: compare using the effective prefix length
- # Find the position of base_sha in PR commits - # Use minimum 7-char prefix comparison (git's default short SHA length) - base_index = -1 - min_prefix_len = 7 - base_prefix = ( - base_sha[:min_prefix_len] if len(base_sha) >= min_prefix_len else base_sha - ) - for i, commit in enumerate(pr_commits): - commit_prefix = commit["sha"][:min_prefix_len] - if commit_prefix == base_prefix: - base_index = i - break + # Find the position of base_sha in PR commits + # Use a common prefix length so short SHAs (e.g. 4–6 chars) still match + base_index = -1 + min_prefix_len = 7 + if base_sha: + effective_prefix_len = min(min_prefix_len, len(base_sha)) + for i, commit in enumerate(pr_commits): + if commit["sha"][:effective_prefix_len] == base_sha[:effective_prefix_len]: + base_index = i + breakapps/backend/runners/github/models.py (1)
570-574: Use an Enum formerge_state_statusto prevent typos and improve type safety.A past review already flagged this:
merge_state_statusshould be an Enum (e.g.,MergeStateStatus) rather than a plainstr. This would prevent typos in comparisons likemergeable == "CONFLICTING"incontext_gatherer.pyand provide better IDE support.Additionally, the default value of
""is inconsistent with the code's use of"UNKNOWN"as a fallback (see lines 286, 1192, 1199 incontext_gatherer.py). The default should beMergeStateStatus.UNKNOWNfor clarity.See the proposed Enum definition in the existing review comment for lines 570-574.
apps/backend/runners/github/context_gatherer.py (1)
207-211: Use an Enum formerge_state_statusfor type safety.This field has the same issue flagged in
models.py: plainstrshould be replaced with aMergeStateStatusEnum. This would prevent typos in comparisons (e.g., line 287:mergeable == "CONFLICTING") and provide IntelliSense support.The default of
""is also inconsistent—line 286 uses"UNKNOWN"as a fallback. The default should beMergeStateStatus.UNKNOWN.See the proposed Enum definition in the existing review comment for
apps/backend/runners/github/models.pylines 570-574.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (10)
apps/backend/runners/github/context_gatherer.pyapps/backend/runners/github/gh_client.pyapps/backend/runners/github/models.pyapps/backend/runners/github/orchestrator.pyapps/backend/runners/github/services/followup_reviewer.pyapps/backend/runners/github/services/parallel_followup_reviewer.pyapps/backend/runners/github/services/parallel_orchestrator_reviewer.pyapps/frontend/src/main/ipc-handlers/github/pr-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.tsapps/frontend/src/preload/api/modules/github-api.ts
🧰 Additional context used
📓 Path-based instructions (4)
apps/frontend/src/**/*.{ts,tsx,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always use i18n translation keys for all user-facing text in the frontend instead of hardcoded strings
Files:
apps/frontend/src/preload/api/modules/github-api.tsapps/frontend/src/main/ipc-handlers/github/pr-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
apps/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use
useTranslation()hook with namespace prefixes (e.g., 'navigation:items.key') for accessing translation strings in React components
Files:
apps/frontend/src/preload/api/modules/github-api.tsapps/frontend/src/main/ipc-handlers/github/pr-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
apps/frontend/**/*.{ts,tsx}
⚙️ CodeRabbit configuration file
apps/frontend/**/*.{ts,tsx}: Review React patterns and TypeScript type safety.
Check for proper state management and component composition.
Files:
apps/frontend/src/preload/api/modules/github-api.tsapps/frontend/src/main/ipc-handlers/github/pr-handlers.tsapps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
apps/backend/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
apps/backend/**/*.py: Always use the Claude Agent SDK (claude-agent-sdkpackage) for all AI interactions, never use the Anthropic API directly
Use thecreate_client()function fromapps/backend/core/client.pyto instantiate Claude SDK clients, not directClaudeSDKClientinitialization
Files:
apps/backend/runners/github/orchestrator.pyapps/backend/runners/github/context_gatherer.pyapps/backend/runners/github/services/parallel_orchestrator_reviewer.pyapps/backend/runners/github/models.pyapps/backend/runners/github/services/followup_reviewer.pyapps/backend/runners/github/services/parallel_followup_reviewer.pyapps/backend/runners/github/gh_client.py
⚙️ CodeRabbit configuration file
apps/backend/**/*.py: Focus on Python best practices, type hints, and async patterns.
Check for proper error handling and security considerations.
Verify compatibility with Python 3.12+.
Files:
apps/backend/runners/github/orchestrator.pyapps/backend/runners/github/context_gatherer.pyapps/backend/runners/github/services/parallel_orchestrator_reviewer.pyapps/backend/runners/github/models.pyapps/backend/runners/github/services/followup_reviewer.pyapps/backend/runners/github/services/parallel_followup_reviewer.pyapps/backend/runners/github/gh_client.py
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Use git worktrees for isolated agent builds with branches following the naming pattern `auto-claude/{spec-name}`
📚 Learning: 2025-12-30T16:38:36.314Z
Learnt from: CR
Repo: AndyMik90/Auto-Claude PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-30T16:38:36.314Z
Learning: Use git worktrees for isolated agent builds with branches following the naming pattern `auto-claude/{spec-name}`
Applied to files:
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
🧬 Code graph analysis (6)
apps/backend/runners/github/orchestrator.py (2)
apps/backend/runners/github/providers/github_provider.py (1)
gh_client(71-73)apps/backend/runners/github/gh_client.py (1)
get_pr_files(878-929)
apps/backend/runners/github/context_gatherer.py (2)
apps/backend/runners/github/providers/github_provider.py (1)
gh_client(71-73)apps/backend/runners/github/gh_client.py (3)
get_pr_files_changed_since(983-1083)compare_commits(660-682)pr_get(329-367)
apps/backend/runners/github/services/parallel_orchestrator_reviewer.py (1)
apps/backend/runners/github/gh_client.py (1)
get_pr_files(878-929)
apps/backend/runners/github/services/followup_reviewer.py (2)
apps/backend/runners/github/providers/github_provider.py (1)
gh_client(71-73)apps/backend/runners/github/gh_client.py (2)
GHClient(62-1083)get_pr_files(878-929)
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts (2)
apps/frontend/src/main/worktree-paths.ts (2)
findTaskWorktree(36-46)getTaskWorktreeDir(21-23)apps/frontend/src/shared/constants/config.ts (1)
AUTO_BUILD_PATHS(81-98)
apps/backend/runners/github/services/parallel_followup_reviewer.py (2)
apps/backend/runners/github/providers/github_provider.py (1)
gh_client(71-73)apps/backend/runners/github/gh_client.py (2)
GHClient(62-1083)get_pr_files(878-929)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Cursor Bugbot
- GitHub Check: CodeQL (javascript-typescript)
- GitHub Check: CodeQL (python)
🔇 Additional comments (15)
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts (6)
681-689: LGTM: Function correctly renamed and documented.The rename from
escapeAppleScriptPathtoescapeSingleQuotedPathaccurately reflects its broader use across AppleScript and POSIX shell contexts. The implementation correctly prevents injection attacks.
1078-1079: LGTM: Proper escaping prevents injection attacks.The use of
escapeSingleQuotedPathbefore injecting directory paths into shell commands (AppleScript on macOS, xterm on Linux) correctly prevents command injection vulnerabilities.Also applies to: 1121-1122
1167-1186: LGTM: Correct use offindTaskWorktreewith proper fallback.The handler correctly uses
findTaskWorktree, which checks both new (.auto-claude/worktrees/tasks/) and legacy (.worktrees/) paths, ensuring backward compatibility for upgraded projects.
1277-1293: LGTM: Consistent with status handler.Correctly uses
findTaskWorktreewith proper null checking and error handling.
1424-1425: LGTM: Proper worktree lookup and cleanup guards.The merge handler correctly uses
findTaskWorktreeand defensively checks existence before cleanup operations.Also applies to: 1671-1671, 1717-1717
2087-2109: LGTM: Consistent worktree lookup and graceful handling.Correctly uses
findTaskWorktreeand handles the case where no worktree exists gracefully.apps/backend/runners/github/gh_client.py (2)
814-876: CI check state classification looks solidSwitching to
stateand treatingSUCCESS/NEUTRAL/SKIPPEDas passing,FAILURE/TIMED_OUT/CANCELLED/STARTUP_FAILUREas failing, and everything else as pending is a straightforward, robust simplification over conclusion-based logic. No issues noticed here.
878-981: Pagination and safety bounds for PR files/commits look correctThe new
get_pr_filesandget_pr_commitshelpers paginate with sensible caps (5,000 files / 1,000 commits) and bail out cleanly when no more data is returned. Error handling is delegated torun(), which is consistent with the rest ofGHClient.apps/frontend/src/preload/api/modules/github-api.ts (1)
311-333: PRReviewResult surface extension is consistentAdding
reviewedFileBlobs?: Record<string, string>cleanly mirrors the backend’sreviewed_file_blobsand the IPC mapping. Optional typing keeps existing callers safe.apps/frontend/src/main/ipc-handlers/github/pr-handlers.ts (1)
92-115: Reviewed file blob wiring is correct and backwards-compatibleThe new
reviewedFileBlobs?: Record<string, string>field and the mapping fromdata.reviewed_file_blobsingetReviewResultmatch the backend shape and remain optional, so older review files without this field still deserialize cleanly.Also applies to: 516-556
apps/backend/runners/github/orchestrator.py (1)
438-476: Initial PR review now correctly seeds blob SHAs for follow-upsThe new
file_blobscapture usingself.gh_client.get_pr_files(pr_number)and passingreviewed_file_blobs=file_blobsintoPRReviewResultgives downstream follow-up reviews a stable per-file content map. The try/except that logs a warning on failure is appropriate since this is supplemental data and shouldn’t block the main review.No functional issues spotted here.
apps/backend/runners/github/models.py (1)
386-388: LGTM! Well-designed field for rebase-resistant reviews.The
reviewed_file_blobsfield enables blob SHA comparison to survive rebases and force-pushes, which is a solid approach. The type hint is precise, the default factory is appropriate, and the comment clearly explains the purpose.apps/backend/runners/github/context_gatherer.py (3)
284-293: Merge conflict detection logic is sound.The approach correctly identifies conflicts by checking
mergeable == "CONFLICTING"and provides clear logging. However, this string comparison would benefit from the Enum refactor mentioned in the previous comment to avoid potential typos.
1059-1097: Well-designed PR-scoped data fetching with robust fallback handling.This refactor solves the "merge introduced commits" problem by using PR-scoped endpoints and includes rebase-resistant blob comparison. The implementation is solid:
- Defensive
getattrretrievesreviewed_file_blobssafely- Comprehensive logging tracks blob comparison usage
- Fallback to
compare_commitsensures resilience if PR endpoints fail- Error messages clearly distinguish between PR data and fallback data
The logic correctly excludes merge-introduced changes while handling rebases gracefully.
1190-1209: Follow-up merge conflict detection is correctly implemented.The logic mirrors the initial review's merge detection (lines 284-293) and includes proper error handling. The warning log at line 1204 provides clear visibility when conflicts exist.
AndyMik90
left a comment
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.
🤖 Auto Claude PR Review
🔄 Follow-up Review: Needs Revision
Resolution Status
- ✅ Resolved: 4 previous findings addressed
- ❌ Unresolved: 0 previous findings remain
- 🆕 New Issues: 5 new findings in recent changes
Verdict
Excellent progress: All 4 previous findings (2 medium, 2 low) have been resolved through targeted refactoring commits. However, 2 new MEDIUM severity issues were identified in the new code: (1) NEW-010 - Missing input validation in findTaskWorktree creates potential path traversal vulnerability, and (2) NEW-011 - JSON parsing in gh_client.py lacks exception handling. While the overall code quality is good with proper use of execFileSync and regex validation in terminal handlers, these medium-severity findings should be addressed before merging. Additionally, 3 LOW severity defense-in-depth improvements were identified.
Review Process
Agents invoked: resolution-verifier, new-code-reviewer
This is an AI-generated follow-up review using parallel specialist analysis with finding validation.
Findings (5 selected of 5 total)
🟡 [MEDIUM] Missing input validation in findTaskWorktree allows potential path traversal
📁 apps/frontend/src/main/worktree-paths.ts:36
The findTaskWorktree function accepts an arbitrary specId parameter and uses it directly in path.join without validation. While path.join normalizes paths, an attacker could potentially pass values like '../../../etc' to traverse outside the intended worktree directory. Unlike terminal worktree handlers which validate names against WORKTREE_NAME_REGEX, the task worktree utilities have no such validation.
Suggested fix:
Add validation that specId matches expected pattern (e.g., /^[a-z0-9][a-z0-9_-]*$/i) before using in path operations, or document that callers must validate inputs.
🟡 [MEDIUM] JSON parsing without exception handling could crash on malformed API response
📁 apps/backend/runners/github/gh_client.py:909
In get_pr_files (line 909), json.loads(result.stdout) is called without explicit exception handling for JSONDecodeError. If the GitHub API returns malformed JSON (network issues, API changes, etc.), this will raise an unhandled exception. The same pattern appears at line 961 in get_pr_commits.
Suggested fix:
Wrap json.loads in try-except to handle JSONDecodeError gracefully, returning an empty list and logging a warning.
🔵 [LOW] getTerminalWorktreePath lacks input validation despite callers validating
📁 apps/frontend/src/main/worktree-paths.ts:58
The getTerminalWorktreePath function accepts a name parameter without validation. While the callers in worktree-handlers.ts do validate using WORKTREE_NAME_REGEX, this creates a defense-in-depth gap. If this utility function is called from new code that forgets to validate, it would be vulnerable.
Suggested fix:
Consider adding validation directly in the path utility functions as defense-in-depth, or add JSDoc documenting the requirement that callers must validate inputs.
🔵 [LOW] SHA prefix comparison may cause false matches in large repositories
📁 apps/backend/runners/github/gh_client.py:1023
The SHA comparison uses a 7-character minimum prefix. While 7 chars is git's default short SHA, in large repositories with many commits, there's a small possibility of prefix collisions which could lead to incorrect filtering of commits.
Suggested fix:
Consider using the full SHA when available, or add a comment documenting the known limitation and its probability.
🔵 [LOW] Blob comparison special-cases renamed files unnecessarily
📁 apps/backend/runners/github/gh_client.py:1057
The blob comparison logic unconditionally includes renamed files without checking if content changed. A renamed file without content changes has the same blob SHA, so the existing blob comparison would handle renames correctly. The special case adds false positives to re-review.
Suggested fix:
Consider removing the special case for renamed files and relying on blob SHA comparison alone, or add a comment explaining the design choice.
This review was generated by Auto Claude.
Merged upstream changes: - fix(ci): include update manifests for architecture-specific auto-updates (AndyMik90#611) - fix: security hook cwd extraction and PATH issues (AndyMik90#555, AndyMik90#556) (AndyMik90#587) - fix(frontend): filter empty env vars to prevent OAuth token override (AndyMik90#520) - refactor(github-review): replace confidence scoring with evidence-based validation (AndyMik90#628) - feat(terminal): add worktree support for terminals (AndyMik90#625) - fix: human_review status persistence bug (worktree plan path fix) (AndyMik90#605) - fix(frontend): resolve PATH and PYTHONPATH issues in insights and changelog services (AndyMik90#558) (AndyMik90#610) - fix: pass electron version explicitly to electron-rebuild on Windows (AndyMik90#622) - fix(kanban): complete refresh button implementation (AndyMik90#584) Conflict resolution: - insights-executor.ts: Combined local diagnostics with upstream error message improvements 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Merged commits: - fix: check .claude.json for OAuth auth in profile scorer (AndyMik90#652) - fix(mcp): use shell mode for Windows command spawning (AndyMik90#572) - fix(ui): update TaskCard description truncation (AndyMik90#637) - fix: change hardcoded Opus defaults to Sonnet (fix AndyMik90#433) (AndyMik90#633) - Fix/small fixes 2.7.3 (AndyMik90#631) - fix(ci): include update manifests for architecture-specific auto-updates (AndyMik90#611) - fix: security hook cwd extraction and PATH issues (AndyMik90#555, AndyMik90#556) (AndyMik90#587) - fix(frontend): filter empty env vars to prevent OAuth token override (AndyMik90#520) - refactor(github-review): replace confidence scoring with evidence-based validation (AndyMik90#628) - feat(terminal): add worktree support for terminals (AndyMik90#625) Resolved conflicts: - Model defaults: Accepted upstream change from opus to sonnet (fix AndyMik90#433) - i18n namespaces: Combined both branches (analytics + terminal) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Summary
.auto-claude/worktrees/with clear taxonomy (terminal/vstasks/)Changes
Frontend
WorktreeSelectordropdown component for choosing existing worktreesCreateWorktreeDialogfor creating terminal worktrees with full optionsTerminal.tsxto useeffectiveCwdfrom store for proper PTY recreationusePtyProcesshook to exposeresetForRecreate()and track cwd changesBackend
.worktrees/to.auto-claude/worktrees/tasks/WorktreeManagerand git utilities to use new pathsTest plan
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Improvements
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.