Skip to content

Conversation

@AndyMik90
Copy link
Owner

@AndyMik90 AndyMik90 commented Jan 3, 2026

Summary

  • Terminal Worktree Creation: Users can create isolated git worktrees directly from the terminal header, with options to link to tasks and create git branches
  • Worktree Selector Dropdown: New dropdown to select existing worktrees or create new ones, replacing the simple button
  • PTY Recreation Fix: Fixed "process exited with code 1" error when switching terminal to a worktree by properly resetting usePtyProcess refs
  • Base Branch Selection: Users can choose which branch to base the worktree on, with project settings respected as default
  • Consolidated Worktree Storage: All worktrees now stored under .auto-claude/worktrees/ with clear taxonomy (terminal/ vs tasks/)

Changes

Frontend

  • New WorktreeSelector dropdown component for choosing existing worktrees
  • New CreateWorktreeDialog for creating terminal worktrees with full options
  • Updated Terminal.tsx to use effectiveCwd from store for proper PTY recreation
  • Updated usePtyProcess hook to expose resetForRecreate() and track cwd changes
  • Added terminal worktree IPC handlers and types
  • i18n translations for worktree UI (English and French)

Backend

  • Consolidated worktree paths from .worktrees/ to .auto-claude/worktrees/tasks/
  • Removed legacy backward compatibility code for cleaner codebase
  • Updated WorktreeManager and git utilities to use new paths

Test plan

  • Create a new terminal worktree from the dropdown
  • Verify terminal restarts in the worktree directory (no "exit code 1" error)
  • Select an existing worktree from the dropdown
  • Verify base branch selector shows project's configured default branch
  • Test on macOS, Windows, and Linux

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Terminal Worktrees: create, list, select, open in IDE, and remove isolated terminal worktrees via new UI and dialog.
    • Per-task worktree awareness: task flows and terminal sessions detect and use per-task worktrees when available.
  • Improvements

    • Follow-up reviews now report merge-conflict status and merge-state details to clarify mergeability.
  • Documentation

    • Expanded review prompts and orchestration guidance emphasizing PR scope and validation.
  • Chores

    • Unified worktree layout and added terminal localization strings.

✏️ Tip: You can customize this high-level summary in your review settings.

AndyMik90 and others added 3 commits January 3, 2026 14:54
- 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]>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 3, 2026

Note

Other AI code review bot(s) detected

CodeRabbit 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.

📝 Walkthrough

Walkthrough

Rehomes per-spec worktrees from .worktrees/{spec} to .auto-claude/worktrees/tasks/{spec}, adds terminal worktree IPC (create/list/remove) with UI and PTY recreation hooks, and augments PR review runners/clients to fetch PR-scoped files/commits and surface merge/conflict metadata.

Changes

Cohort / File(s) Summary
Backend worktree path changes
apps/backend/cli/batch_commands.py, apps/backend/cli/utils.py, apps/backend/core/worktree.py, apps/backend/core/workspace.py, apps/backend/core/workspace/__init__.py, apps/backend/core/workspace/finalization.py, apps/backend/core/workspace/git_utils.py, apps/backend/core/workspace/models.py, apps/backend/merge/git_utils.py, apps/backend/merge/timeline_git.py
Replaced .worktrees/{spec} with .auto-claude/worktrees/tasks/{spec} across discovery, creation, cleanup and status checks; added new-path-first with legacy fallback lookups; removed legacy single-staging compatibility APIs and updated docstrings/messages.
Backend PR context & GH client
apps/backend/runners/github/context_gatherer.py, apps/backend/runners/github/gh_client.py, apps/backend/runners/github/models.py, apps/backend/runners/github/orchestrator.py, apps/backend/runners/github/services/*
Added paginated PR files/commits retrieval, get_pr_files_changed_since, per-file blob SHA capture, and propagation of reviewed_file_blobs; follow-up gathering uses PR-scoped files/commits and includes has_merge_conflicts and merge_state_status in contexts.
Backend prompts (docs only)
apps/backend/prompts/github/*.md
Inserted structured "CRITICAL: PR Scope and Context" guidance and reorganized validation/orchestration guidance across multiple prompt docs (documentation-only changes).
Frontend centralized worktree helpers
apps/frontend/src/main/worktree-paths.ts, apps/frontend/src/main/project-store.ts, apps/frontend/src/main/release-service.ts, apps/frontend/src/main/task-log-service.ts, apps/frontend/src/main/utils/spec-number-lock.ts
New centralized path helpers and constants (TASK/TERMINAL/LEGACY dirs); replaced hard-coded .worktrees with helpers, added legacy fallbacks and safe existence checks.
Frontend task IPC & handlers
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts, apps/frontend/src/main/ipc-handlers/task/execution-handlers.ts, apps/frontend/src/main/ipc-handlers/index.ts
Replaced direct path construction with findTaskWorktree/helpers, improved listing/validation, adjusted git-clean exclusions to .auto-claude, and updated various IPC flows to respect worktree presence.
Frontend terminal worktree IPC & types
apps/frontend/src/main/ipc-handlers/terminal/index.ts, apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts, apps/frontend/src/preload/api/terminal-api.ts, apps/frontend/src/shared/constants/ipc.ts, apps/frontend/src/shared/types/ipc.ts, apps/frontend/src/shared/types/terminal.ts
New main-process handlers and IPC channels for terminal worktrees (create/list/remove); preload mappings and shared types (TerminalWorktreeConfig, CreateTerminalWorktreeRequest, TerminalWorktreeResult).
Frontend terminal UI & lifecycle
apps/frontend/src/renderer/components/Terminal.tsx, apps/frontend/src/renderer/components/terminal/CreateWorktreeDialog.tsx, apps/frontend/src/renderer/components/terminal/TerminalHeader.tsx, apps/frontend/src/renderer/components/terminal/WorktreeSelector.tsx, apps/frontend/src/renderer/components/terminal/usePtyProcess.ts
New UI components for creating/selecting worktrees, TerminalHeader worktree controls, WorktreeSelector and CreateWorktreeDialog; added PTY recreation helpers (prepareForRecreate/resetForRecreate) and wiring to lifecycle.
Frontend terminal state & mocks
apps/frontend/src/renderer/stores/terminal-store.ts, apps/frontend/src/renderer/lib/browser-mock.ts
Terminal store extended with optional worktreeConfig, setWorktreeConfig, getWorktreeCount; browser mock stubs for terminal worktree IPC methods.
Frontend settings branch sync
apps/frontend/src/renderer/components/settings/integrations/GitHubIntegration.tsx, apps/frontend/src/renderer/components/settings/integrations/GitLabIntegration.tsx, apps/frontend/src/renderer/components/settings/sections/SectionRouter.tsx
Added ProjectSettings props and handleBranchChange to synchronize Electron ProjectSettings.mainBranch with CLI/envConfig.defaultBranch and adjusted auto-detection priority.
Frontend i18n & locales
apps/frontend/src/shared/i18n/index.ts, apps/frontend/src/shared/i18n/locales/en/common.json, apps/frontend/src/shared/i18n/locales/en/terminal.json, apps/frontend/src/shared/i18n/locales/fr/common.json, apps/frontend/src/shared/i18n/locales/fr/terminal.json
Added terminal i18n namespace and English/French translations for worktree UI; added "creating" label to common locales.
Tests
tests/test_worktree.py, tests/test_workspace.py
Updated tests to reflect path/API changes: removed staging-specific constants/APIs, adopt per-spec create_worktree flows and .auto-claude/worktrees/tasks expectations; adjusted assertions and git interactions accordingly.

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()
Loading
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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Suggested reviewers

  • MikeeBuilds
  • AlexMadera

Poem

🐇 I hopped and dug a tidy track,
.auto-claude/worktrees/tasks in my pack.
Branches bloom and PTYs wake,
Dialogs open, configs take—
A rabbit's cheer for code on track! 🌿

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 79.49% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(terminal): add worktree support for terminals' is clear, specific, and directly describes the main feature addition. It accurately reflects the primary change of enabling worktree creation and management within the terminal feature.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b06d325 and edbbf92.

📒 Files selected for processing (10)
  • apps/backend/runners/github/context_gatherer.py
  • apps/backend/runners/github/gh_client.py
  • apps/backend/runners/github/models.py
  • apps/backend/runners/github/orchestrator.py
  • apps/backend/runners/github/services/followup_reviewer.py
  • apps/backend/runners/github/services/parallel_followup_reviewer.py
  • apps/backend/runners/github/services/parallel_orchestrator_reviewer.py
  • apps/frontend/src/main/ipc-handlers/github/pr-handlers.ts
  • apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
  • apps/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.ts
  • apps/frontend/src/main/ipc-handlers/github/pr-handlers.ts
  • apps/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.ts
  • apps/frontend/src/main/ipc-handlers/github/pr-handlers.ts
  • apps/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.ts
  • apps/frontend/src/main/ipc-handlers/github/pr-handlers.ts
  • apps/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-sdk package) for all AI interactions, never use the Anthropic API directly
Use the create_client() function from apps/backend/core/client.py to instantiate Claude SDK clients, not direct ClaudeSDKClient initialization

Files:

  • apps/backend/runners/github/orchestrator.py
  • apps/backend/runners/github/context_gatherer.py
  • apps/backend/runners/github/services/parallel_orchestrator_reviewer.py
  • apps/backend/runners/github/models.py
  • apps/backend/runners/github/services/followup_reviewer.py
  • apps/backend/runners/github/services/parallel_followup_reviewer.py
  • apps/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.py
  • apps/backend/runners/github/context_gatherer.py
  • apps/backend/runners/github/services/parallel_orchestrator_reviewer.py
  • apps/backend/runners/github/models.py
  • apps/backend/runners/github/services/followup_reviewer.py
  • apps/backend/runners/github/services/parallel_followup_reviewer.py
  • apps/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 escapeAppleScriptPath to escapeSingleQuotedPath accurately 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 escapeSingleQuotedPath before 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 of findTaskWorktree with 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 findTaskWorktree with proper null checking and error handling.


1424-1425: LGTM: Proper worktree lookup and cleanup guards.

The merge handler correctly uses findTaskWorktree and defensively checks existence before cleanup operations.

Also applies to: 1671-1671, 1717-1717


2087-2109: LGTM: Consistent worktree lookup and graceful handling.

Correctly uses findTaskWorktree and handles the case where no worktree exists gracefully.

apps/backend/runners/github/gh_client.py (2)

814-876: CI check state classification looks solid

Switching to state and treating SUCCESS/NEUTRAL/SKIPPED as passing, FAILURE/TIMED_OUT/CANCELLED/STARTUP_FAILURE as 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 correct

The new get_pr_files and get_pr_commits helpers paginate with sensible caps (5,000 files / 1,000 commits) and bail out cleanly when no more data is returned. Error handling is delegated to run(), which is consistent with the rest of GHClient.

apps/frontend/src/preload/api/modules/github-api.ts (1)

311-333: PRReviewResult surface extension is consistent

Adding reviewedFileBlobs?: Record<string, string> cleanly mirrors the backend’s reviewed_file_blobs and 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-compatible

The new reviewedFileBlobs?: Record<string, string> field and the mapping from data.reviewed_file_blobs in getReviewResult match 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-ups

The new file_blobs capture using self.gh_client.get_pr_files(pr_number) and passing reviewed_file_blobs=file_blobs into PRReviewResult gives 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_blobs field 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 getattr retrieves reviewed_file_blobs safely
  • Comprehensive logging tracks blob comparison usage
  • Fallback to compare_commits ensures 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.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @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

  • Terminal Worktree Creation: Users can now create isolated Git worktrees directly from the terminal header, with options to link them to tasks and create corresponding Git branches.
  • Worktree Selector Dropdown: A new dropdown component replaces the simple button, allowing users to select existing worktrees or initiate the creation of new ones.
  • PTY Recreation Fix: The 'process exited with code 1' error when switching terminals to a worktree has been resolved by properly resetting usePtyProcess refs, ensuring smooth transitions.
  • Base Branch Selection: Users can choose the base branch for their new worktree, with project settings providing the default selection.
  • Consolidated Worktree Storage: All worktrees are now consistently stored under .auto-claude/worktrees/ with a clear taxonomy (terminal/ for terminal-created worktrees and tasks/ for task-related worktrees).
  • Improved PR Context Gathering: The backend now more accurately gathers PR files and commits for follow-up reviews, specifically excluding merge-introduced changes to prevent reviewing commits from other PRs.

🧠 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 Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a 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.

Comment on lines +172 to +180
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}"
)
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This block of code to determine and print the worktree path is duplicated later in this file (lines 243-251). To improve maintainability and avoid future inconsistencies, consider extracting this logic into a helper function.

.toLowerCase()
.replace(/[^a-z0-9-_]/g, '-')
.replace(/-+/g, '-')
.replace(/^-|-$/g, '');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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.

Suggested change
.replace(/^-|-$/g, '');
.replace(/^[_-]+|[_-]+$/g, '');

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 use t('settings.keyName') for all user-facing strings. GitHubIntegration.tsx should follow the same approach, with translation keys added to apps/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 createTerminal or restoreTerminalSession is 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 in find_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 returning None.

Wrap the directory iteration in a try-except block to handle potential OSError exceptions 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 None
apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts (1)

2127-2198: Consider making processWorktreeEntry a pure function that returns the item.

The helper function modifies the outer worktrees array 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

📥 Commits

Reviewing files that changed from the base of the PR and between 7177c79 and 4b4e640.

📒 Files selected for processing (49)
  • apps/backend/cli/batch_commands.py
  • apps/backend/cli/utils.py
  • apps/backend/core/workspace.py
  • apps/backend/core/workspace/__init__.py
  • apps/backend/core/workspace/finalization.py
  • apps/backend/core/workspace/git_utils.py
  • apps/backend/core/workspace/models.py
  • apps/backend/core/worktree.py
  • apps/backend/merge/git_utils.py
  • apps/backend/merge/timeline_git.py
  • apps/backend/prompts/github/pr_codebase_fit_agent.md
  • apps/backend/prompts/github/pr_finding_validator.md
  • apps/backend/prompts/github/pr_followup_newcode_agent.md
  • apps/backend/prompts/github/pr_followup_orchestrator.md
  • apps/backend/prompts/github/pr_followup_resolution_agent.md
  • apps/backend/prompts/github/pr_logic_agent.md
  • apps/backend/prompts/github/pr_parallel_orchestrator.md
  • apps/backend/prompts/github/pr_quality_agent.md
  • apps/backend/prompts/github/pr_security_agent.md
  • apps/backend/runners/github/context_gatherer.py
  • apps/backend/runners/github/gh_client.py
  • apps/frontend/src/main/ipc-handlers/index.ts
  • apps/frontend/src/main/ipc-handlers/task/execution-handlers.ts
  • apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
  • apps/frontend/src/main/ipc-handlers/terminal/index.ts
  • apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts
  • apps/frontend/src/main/project-store.ts
  • apps/frontend/src/main/release-service.ts
  • apps/frontend/src/main/task-log-service.ts
  • apps/frontend/src/main/utils/spec-number-lock.ts
  • apps/frontend/src/preload/api/terminal-api.ts
  • apps/frontend/src/renderer/components/Terminal.tsx
  • apps/frontend/src/renderer/components/settings/integrations/GitHubIntegration.tsx
  • apps/frontend/src/renderer/components/settings/integrations/GitLabIntegration.tsx
  • apps/frontend/src/renderer/components/settings/sections/SectionRouter.tsx
  • apps/frontend/src/renderer/components/terminal/CreateWorktreeDialog.tsx
  • apps/frontend/src/renderer/components/terminal/TerminalHeader.tsx
  • apps/frontend/src/renderer/components/terminal/WorktreeSelector.tsx
  • apps/frontend/src/renderer/components/terminal/usePtyProcess.ts
  • apps/frontend/src/renderer/lib/browser-mock.ts
  • apps/frontend/src/renderer/stores/terminal-store.ts
  • apps/frontend/src/shared/constants/ipc.ts
  • apps/frontend/src/shared/i18n/index.ts
  • apps/frontend/src/shared/i18n/locales/en/common.json
  • apps/frontend/src/shared/i18n/locales/en/terminal.json
  • apps/frontend/src/shared/i18n/locales/fr/common.json
  • apps/frontend/src/shared/i18n/locales/fr/terminal.json
  • apps/frontend/src/shared/types/ipc.ts
  • apps/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.ts
  • apps/frontend/src/shared/types/terminal.ts
  • apps/frontend/src/renderer/components/terminal/usePtyProcess.ts
  • apps/frontend/src/renderer/components/terminal/CreateWorktreeDialog.tsx
  • apps/frontend/src/main/ipc-handlers/terminal/index.ts
  • apps/frontend/src/shared/constants/ipc.ts
  • apps/frontend/src/main/task-log-service.ts
  • apps/frontend/src/renderer/stores/terminal-store.ts
  • apps/frontend/src/shared/types/ipc.ts
  • apps/frontend/src/main/ipc-handlers/index.ts
  • apps/frontend/src/renderer/components/settings/integrations/GitHubIntegration.tsx
  • apps/frontend/src/renderer/lib/browser-mock.ts
  • apps/frontend/src/renderer/components/terminal/TerminalHeader.tsx
  • apps/frontend/src/main/ipc-handlers/task/execution-handlers.ts
  • apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
  • apps/frontend/src/shared/i18n/index.ts
  • apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts
  • apps/frontend/src/renderer/components/settings/integrations/GitLabIntegration.tsx
  • apps/frontend/src/renderer/components/settings/sections/SectionRouter.tsx
  • apps/frontend/src/main/release-service.ts
  • apps/frontend/src/preload/api/terminal-api.ts
  • apps/frontend/src/main/project-store.ts
  • apps/frontend/src/renderer/components/Terminal.tsx
  • apps/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.ts
  • apps/frontend/src/shared/types/terminal.ts
  • apps/frontend/src/renderer/components/terminal/usePtyProcess.ts
  • apps/frontend/src/renderer/components/terminal/CreateWorktreeDialog.tsx
  • apps/frontend/src/main/ipc-handlers/terminal/index.ts
  • apps/frontend/src/shared/constants/ipc.ts
  • apps/frontend/src/main/task-log-service.ts
  • apps/frontend/src/renderer/stores/terminal-store.ts
  • apps/frontend/src/shared/types/ipc.ts
  • apps/frontend/src/main/ipc-handlers/index.ts
  • apps/frontend/src/renderer/components/settings/integrations/GitHubIntegration.tsx
  • apps/frontend/src/renderer/lib/browser-mock.ts
  • apps/frontend/src/renderer/components/terminal/TerminalHeader.tsx
  • apps/frontend/src/main/ipc-handlers/task/execution-handlers.ts
  • apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
  • apps/frontend/src/shared/i18n/index.ts
  • apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts
  • apps/frontend/src/renderer/components/settings/integrations/GitLabIntegration.tsx
  • apps/frontend/src/renderer/components/settings/sections/SectionRouter.tsx
  • apps/frontend/src/main/release-service.ts
  • apps/frontend/src/preload/api/terminal-api.ts
  • apps/frontend/src/main/project-store.ts
  • apps/frontend/src/renderer/components/Terminal.tsx
  • apps/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.ts
  • apps/frontend/src/shared/types/terminal.ts
  • apps/frontend/src/renderer/components/terminal/usePtyProcess.ts
  • apps/frontend/src/renderer/components/terminal/CreateWorktreeDialog.tsx
  • apps/frontend/src/main/ipc-handlers/terminal/index.ts
  • apps/frontend/src/shared/constants/ipc.ts
  • apps/frontend/src/main/task-log-service.ts
  • apps/frontend/src/renderer/stores/terminal-store.ts
  • apps/frontend/src/shared/types/ipc.ts
  • apps/frontend/src/main/ipc-handlers/index.ts
  • apps/frontend/src/renderer/components/settings/integrations/GitHubIntegration.tsx
  • apps/frontend/src/renderer/lib/browser-mock.ts
  • apps/frontend/src/renderer/components/terminal/TerminalHeader.tsx
  • apps/frontend/src/main/ipc-handlers/task/execution-handlers.ts
  • apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
  • apps/frontend/src/shared/i18n/index.ts
  • apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts
  • apps/frontend/src/renderer/components/settings/integrations/GitLabIntegration.tsx
  • apps/frontend/src/renderer/components/settings/sections/SectionRouter.tsx
  • apps/frontend/src/main/release-service.ts
  • apps/frontend/src/preload/api/terminal-api.ts
  • apps/frontend/src/main/project-store.ts
  • apps/frontend/src/renderer/components/Terminal.tsx
  • apps/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.md
  • apps/backend/prompts/github/pr_followup_resolution_agent.md
  • apps/backend/prompts/github/pr_security_agent.md
  • apps/backend/prompts/github/pr_logic_agent.md
  • apps/backend/prompts/github/pr_followup_newcode_agent.md
  • apps/backend/prompts/github/pr_codebase_fit_agent.md
  • apps/backend/prompts/github/pr_followup_orchestrator.md
  • apps/backend/prompts/github/pr_finding_validator.md
  • apps/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 at apps/frontend/src/shared/i18n/locales/{lang}/*.json for 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.json
  • apps/frontend/src/shared/i18n/locales/en/common.json
  • apps/frontend/src/shared/i18n/locales/en/terminal.json
  • apps/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-sdk package) for all AI interactions, never use the Anthropic API directly
Use the create_client() function from apps/backend/core/client.py to instantiate Claude SDK clients, not direct ClaudeSDKClient initialization

Files:

  • apps/backend/cli/utils.py
  • apps/backend/core/workspace/git_utils.py
  • apps/backend/core/workspace/finalization.py
  • apps/backend/cli/batch_commands.py
  • apps/backend/merge/git_utils.py
  • apps/backend/runners/github/gh_client.py
  • apps/backend/core/workspace/models.py
  • apps/backend/core/workspace.py
  • apps/backend/core/worktree.py
  • apps/backend/merge/timeline_git.py
  • apps/backend/runners/github/context_gatherer.py
  • apps/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.py
  • apps/backend/core/workspace/git_utils.py
  • apps/backend/core/workspace/finalization.py
  • apps/backend/cli/batch_commands.py
  • apps/backend/merge/git_utils.py
  • apps/backend/runners/github/gh_client.py
  • apps/backend/core/workspace/models.py
  • apps/backend/core/workspace.py
  • apps/backend/core/worktree.py
  • apps/backend/merge/timeline_git.py
  • apps/backend/runners/github/context_gatherer.py
  • apps/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.py for bash command validation

Files:

  • apps/backend/core/workspace/git_utils.py
  • apps/backend/core/workspace/finalization.py
  • apps/backend/core/workspace/models.py
  • apps/backend/core/workspace.py
  • apps/backend/core/worktree.py
  • apps/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.ts
  • apps/backend/cli/utils.py
  • apps/backend/core/workspace/git_utils.py
  • apps/frontend/src/main/ipc-handlers/task/execution-handlers.ts
  • apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
  • apps/backend/core/workspace/finalization.py
  • apps/frontend/src/main/release-service.ts
  • apps/backend/cli/batch_commands.py
  • apps/backend/merge/git_utils.py
  • apps/frontend/src/main/project-store.ts
  • apps/backend/core/workspace.py
  • apps/backend/core/worktree.py
  • apps/backend/merge/timeline_git.py
  • apps/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.json
  • apps/frontend/src/shared/i18n/index.ts
  • apps/frontend/src/shared/i18n/locales/en/common.json
  • apps/frontend/src/shared/i18n/locales/en/terminal.json
  • apps/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.py
  • apps/backend/core/workspace.py
  • apps/backend/core/worktree.py
  • apps/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.md
  • apps/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.tsx
  • 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/**/*.{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.ts
  • apps/frontend/src/shared/i18n/locales/en/common.json
  • apps/frontend/src/shared/i18n/locales/en/terminal.json
  • apps/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

Comment on lines +172 to +180
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}"
)
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 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 -100

Repository: 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 -A10

Repository: 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 -A3

Repository: AndyMik90/Auto-Claude

Length of output: 47


🏁 Script executed:

# Look for worktree creation logic
rg -n "\.auto-claude/worktrees" --type=py -B2 -A2

Repository: 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 -A20

Repository: 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 -A15

Repository: 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 -A10

Repository: 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 -A2

Repository: 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 -50

Repository: 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 -A30

Repository: 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 -A3

Repository: 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 -20

Repository: 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 -40

Repository: 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 -A5

Repository: 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 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=py

Repository: 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.py

Repository: 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 -40

Repository: AndyMik90/Auto-Claude

Length of output: 1174


🏁 Script executed:

# Check CLAUDE.md for guidelines
cat CLAUDE.md

Repository: 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:

  1. No backward compatibility: get_existing_build_worktree() only checks the new location. Users with existing worktrees in the old path cannot find them.

  2. Tests still use old path: Multiple test files (test_workspace.py, test_worktree.py) reference the old .worktrees path and will fail after this change.

  3. Analyzer skip lists outdated: apps/backend/analysis/analyzers/base.py and framework_analyzer.py still hardcode .worktrees in directory skip lists—update to .auto-claude/worktrees/tasks or skip both.

  4. Documentation outdated: CLAUDE.md still references the old .worktrees/{spec-name} path in the "Branching & Worktree Strategy" section.

  5. 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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 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 -5

Repository: 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/null

Repository: 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 -20

Repository: 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 3

Repository: AndyMik90/Auto-Claude

Length of output: 887


🏁 Script executed:

# Look for migration or backward compatibility code
rg "migration|backward|compat|old.*location" apps/backend/ -i

Repository: 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 5

Repository: AndyMik90/Auto-Claude

Length of output: 46364


🏁 Script executed:

# Look for references to the old .worktrees location
rg "\.worktrees" apps/backend/ --type py

Repository: AndyMik90/Auto-Claude

Length of output: 870


🏁 Script executed:

# Check CLAUDE.md for worktree-related guidance
cat CLAUDE.md | head -100

Repository: 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 -100

Repository: 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 -10

Repository: 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 2

Repository: 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 -50

Repository: 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 -80

Repository: 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 -5

Repository: 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:

  1. Add fallback logic to also scan the old location (if it existed in prior versions), or
  2. 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.

Comment on lines +192 to +199
worktree_path = (
self.project_path
/ ".auto-claude"
/ "worktrees"
/ "tasks"
/ spec_name
/ file_path
)
Copy link
Contributor

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.

Suggested change
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.

Comment on lines +14 to +15
## CRITICAL: PR Scope and Context

Copy link
Contributor

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.

Comment on lines +101 to +110
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);
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

Comment on lines +67 to +78
<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>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

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.

Suggested change
<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...",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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...").

Comment on lines +1 to +26
{
"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"
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

Comment on lines +144 to +161
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;
}
Copy link
Contributor

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 branchName is empty → hasGitBranch is false
  • If branchName is non-empty → hasGitBranch is 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.

@AndyMik90 AndyMik90 self-assigned this Jan 3, 2026
AndyMik90 and others added 2 commits January 3, 2026 15:57
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]>
@github-actions github-actions bot added area/fullstack This is Frontend + Backend feature New feature or request size/XL Extra large (1000+ lines) 🔄 Checking Checking PR Status labels Jan 3, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 of getToolPath('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 but getToolPath resolves 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 touch
apps/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 from execution-handlers.ts. Extract to a shared utility module.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b4e640 and b5fdcb6.

📒 Files selected for processing (6)
  • apps/backend/prompts/github/pr_followup_orchestrator.md
  • apps/backend/prompts/github/pr_parallel_orchestrator.md
  • apps/backend/runners/github/context_gatherer.py
  • apps/backend/runners/github/models.py
  • apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
  • apps/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.md
  • apps/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.ts
  • apps/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.ts
  • apps/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.ts
  • apps/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-sdk package) for all AI interactions, never use the Anthropic API directly
Use the create_client() function from apps/backend/core/client.py to instantiate Claude SDK clients, not direct ClaudeSDKClient initialization

Files:

  • apps/backend/runners/github/models.py
  • apps/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.py
  • apps/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.ts
  • apps/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 findTaskWorktree and 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 the existsSync guards.

These guards are appropriate since significant time and async operations may have elapsed between the initial findTaskWorktree call 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 tabOrder field 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() to get_pr_files_changed_since() correctly addresses the problem of merge-introduced changes appearing in follow-up reviews. The error handling with fallback to compare_commits() provides resilience, and the logging clearly indicates when the fallback is used. Method signature includes proper async/await patterns and type hints.

Comment on lines +11 to +21
### 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:**
Copy link
Contributor

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.

Suggested change
### 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).

Comment on lines +207 to +211
# 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
)
Copy link
Contributor

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.

Comment on lines +565 to +569
# 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
)
Copy link
Contributor

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.UNKNOWN

You'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.

Comment on lines 9 to 13
const TASK_WORKTREE_DIR = '.auto-claude/worktrees/tasks';

function getWorktreeDir(projectPath: string): string {
return path.join(projectPath, TASK_WORKTREE_DIR);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 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 -10

Repository: 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}`, {
Copy link

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)

Fix in Cursor Fix in Web

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]>
@github-actions github-actions bot added 🔄 Checking Checking PR Status and removed 🔄 Checking Checking PR Status labels Jan 3, 2026
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 'WorktreeInfo' is not used.
Import of 'WorktreeError' is not used.

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.

Suggested changeset 1
tests/test_worktree.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/tests/test_worktree.py b/tests/test_worktree.py
--- a/tests/test_worktree.py
+++ b/tests/test_worktree.py
@@ -16,7 +16,7 @@
 
 import pytest
 
-from worktree import WorktreeManager, WorktreeInfo, WorktreeError
+from worktree import WorktreeManager
 
 
 class TestWorktreeManagerInitialization:
EOF
@@ -16,7 +16,7 @@

import pytest

from worktree import WorktreeManager, WorktreeInfo, WorktreeError
from worktree import WorktreeManager


class TestWorktreeManagerInitialization:
Copilot is powered by AI and may make mistakes. Always verify output.
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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) > 0 is 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

📥 Commits

Reviewing files that changed from the base of the PR and between b5fdcb6 and f11f2a3.

📒 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
Copy link
Contributor

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.

Copy link
Owner Author

@AndyMik90 AndyMik90 left a 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();
Copy link

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)

Fix in Cursor Fix in Web

…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]>
@github-actions github-actions bot added 🔄 Checking Checking PR Status and removed 🔄 Checking Checking PR Status labels Jan 3, 2026
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]>
@github-actions github-actions bot added the 🔄 Checking Checking PR Status label Jan 3, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 -b succeeds (creating both worktree and branch) but saveWorktreeConfig throws, 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

📥 Commits

Reviewing files that changed from the base of the PR and between 8914a80 and b06d325.

📒 Files selected for processing (6)
  • apps/frontend/src/main/ipc-handlers/task/execution-handlers.ts
  • apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
  • apps/frontend/src/main/ipc-handlers/terminal/worktree-handlers.ts
  • apps/frontend/src/main/project-store.ts
  • apps/frontend/src/main/task-log-service.ts
  • apps/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.ts
  • apps/frontend/src/main/project-store.ts
  • apps/frontend/src/main/task-log-service.ts
  • apps/frontend/src/main/ipc-handlers/task/execution-handlers.ts
  • apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
  • apps/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.ts
  • apps/frontend/src/main/project-store.ts
  • apps/frontend/src/main/task-log-service.ts
  • apps/frontend/src/main/ipc-handlers/task/execution-handlers.ts
  • apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
  • apps/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.ts
  • apps/frontend/src/main/project-store.ts
  • apps/frontend/src/main/task-log-service.ts
  • apps/frontend/src/main/ipc-handlers/task/execution-handlers.ts
  • apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
  • apps/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.ts
  • apps/frontend/src/main/ipc-handlers/task/execution-handlers.ts
  • apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
  • apps/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 getTaskWorktreeDir from 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 findWorktreeSpecDir helper cleanly wraps findTaskWorktree (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 findTaskWorktree from the shared module properly addresses past review concerns about:

  1. DRY violations (centralized helper)
  2. Missing legacy path fallback (the helper checks both new and legacy paths)

The derived hasWorktree boolean 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-claude exclusion 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_REGEX validation at line 131 addresses the command injection vulnerability flagged in previous reviews. Combined with execFileSync (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.branchName against GIT_BRANCH_REGEX before 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 getTaskWorktreeDir and findTaskWorktree from 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 findTaskWorktree is 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_WORKTREES handler uses getTaskWorktreeDir() 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:

  1. Clear separation of concerns: "get" functions construct paths, "find" functions discover existing worktrees with legacy fallback
  2. Backward compatibility: findTaskWorktree and findTerminalWorktree check new paths first, then fall back to legacy locations
  3. 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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 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 -50

Repository: 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 1

Repository: 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]>
@github-actions github-actions bot added 🔄 Checking Checking PR Status and removed 🔄 Checking Checking PR Status labels Jan 3, 2026

const worktreesDir = path.join(project.path, '.worktrees');
const worktrees: WorktreeListItem[] = [];
const worktreesDir = getTaskWorktreeDir(project.path);
Copy link

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)

Fix in Cursor Fix in Web

if (isCreatedRef.current) {
await window.electronAPI.destroyTerminal(id);
isCreatedRef.current = false;
}
Copy link

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)

Fix in Cursor Fix in Web

…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]>
@github-actions github-actions bot added 🔄 Checking Checking PR Status and removed 🔄 Checking Checking PR Status labels Jan 3, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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_WORKTREES handler only scans .auto-claude/worktrees/tasks/ via getTaskWorktreeDir(), but doesn't check the legacy .worktrees/ directory. This is inconsistent with individual worktree lookups (STATUS, DIFF, DISCARD) which use findTaskWorktree() 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_DIR and LEGACY_WORKTREE_DIR constants, which should match the values in worktree-paths.ts.

apps/backend/runners/github/services/followup_reviewer.py (1)

28-52: Blob SHA capture for follow-up reviews is well-contained

Importing GHClient and capturing filename → sha via get_pr_files() before returning PRReviewResult gives 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 pipeline

The new GHClient import and file_blobs collection in review() correctly snapshot per-file blob SHAs and thread them through PRReviewResult.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 reviews

Creating a GHClient with project_dir=self.project_dir and repo=self.config.repo, then filling reviewed_file_blobs from get_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: Short base_sha prefixes (<7 chars) never match, forcing fallback path

In get_pr_files_changed_since, base_prefix may be shorter than 7 characters, but commit_prefix is always 7 characters long. When len(base_sha) < 7, base_prefix (e.g. "abc12") can never equal commit["sha"][:7] (e.g. "abc1234"), so base_index remains -1 even 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
+                    break
apps/backend/runners/github/models.py (1)

570-574: Use an Enum for merge_state_status to prevent typos and improve type safety.

A past review already flagged this: merge_state_status should be an Enum (e.g., MergeStateStatus) rather than a plain str. This would prevent typos in comparisons like mergeable == "CONFLICTING" in context_gatherer.py and 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 in context_gatherer.py). The default should be MergeStateStatus.UNKNOWN for 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 for merge_state_status for type safety.

This field has the same issue flagged in models.py: plain str should be replaced with a MergeStateStatus Enum. 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 be MergeStateStatus.UNKNOWN.

See the proposed Enum definition in the existing review comment for apps/backend/runners/github/models.py lines 570-574.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b06d325 and edbbf92.

📒 Files selected for processing (10)
  • apps/backend/runners/github/context_gatherer.py
  • apps/backend/runners/github/gh_client.py
  • apps/backend/runners/github/models.py
  • apps/backend/runners/github/orchestrator.py
  • apps/backend/runners/github/services/followup_reviewer.py
  • apps/backend/runners/github/services/parallel_followup_reviewer.py
  • apps/backend/runners/github/services/parallel_orchestrator_reviewer.py
  • apps/frontend/src/main/ipc-handlers/github/pr-handlers.ts
  • apps/frontend/src/main/ipc-handlers/task/worktree-handlers.ts
  • apps/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.ts
  • apps/frontend/src/main/ipc-handlers/github/pr-handlers.ts
  • apps/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.ts
  • apps/frontend/src/main/ipc-handlers/github/pr-handlers.ts
  • apps/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.ts
  • apps/frontend/src/main/ipc-handlers/github/pr-handlers.ts
  • apps/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-sdk package) for all AI interactions, never use the Anthropic API directly
Use the create_client() function from apps/backend/core/client.py to instantiate Claude SDK clients, not direct ClaudeSDKClient initialization

Files:

  • apps/backend/runners/github/orchestrator.py
  • apps/backend/runners/github/context_gatherer.py
  • apps/backend/runners/github/services/parallel_orchestrator_reviewer.py
  • apps/backend/runners/github/models.py
  • apps/backend/runners/github/services/followup_reviewer.py
  • apps/backend/runners/github/services/parallel_followup_reviewer.py
  • apps/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.py
  • apps/backend/runners/github/context_gatherer.py
  • apps/backend/runners/github/services/parallel_orchestrator_reviewer.py
  • apps/backend/runners/github/models.py
  • apps/backend/runners/github/services/followup_reviewer.py
  • apps/backend/runners/github/services/parallel_followup_reviewer.py
  • apps/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 escapeAppleScriptPath to escapeSingleQuotedPath accurately 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 escapeSingleQuotedPath before 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 of findTaskWorktree with 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 findTaskWorktree with proper null checking and error handling.


1424-1425: LGTM: Proper worktree lookup and cleanup guards.

The merge handler correctly uses findTaskWorktree and defensively checks existence before cleanup operations.

Also applies to: 1671-1671, 1717-1717


2087-2109: LGTM: Consistent worktree lookup and graceful handling.

Correctly uses findTaskWorktree and handles the case where no worktree exists gracefully.

apps/backend/runners/github/gh_client.py (2)

814-876: CI check state classification looks solid

Switching to state and treating SUCCESS/NEUTRAL/SKIPPED as passing, FAILURE/TIMED_OUT/CANCELLED/STARTUP_FAILURE as 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 correct

The new get_pr_files and get_pr_commits helpers paginate with sensible caps (5,000 files / 1,000 commits) and bail out cleanly when no more data is returned. Error handling is delegated to run(), which is consistent with the rest of GHClient.

apps/frontend/src/preload/api/modules/github-api.ts (1)

311-333: PRReviewResult surface extension is consistent

Adding reviewedFileBlobs?: Record<string, string> cleanly mirrors the backend’s reviewed_file_blobs and 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-compatible

The new reviewedFileBlobs?: Record<string, string> field and the mapping from data.reviewed_file_blobs in getReviewResult match 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-ups

The new file_blobs capture using self.gh_client.get_pr_files(pr_number) and passing reviewed_file_blobs=file_blobs into PRReviewResult gives 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_blobs field 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 getattr retrieves reviewed_file_blobs safely
  • Comprehensive logging tracks blob comparison usage
  • Fallback to compare_commits ensures 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.

Copy link
Owner Author

@AndyMik90 AndyMik90 left a 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.

@AndyMik90 AndyMik90 merged commit 13535f1 into develop Jan 3, 2026
14 checks passed
@AndyMik90 AndyMik90 deleted the feat/terminal-worktree branch January 3, 2026 18:38
@AndyMik90 AndyMik90 restored the feat/terminal-worktree branch January 3, 2026 18:38
ayoahha added a commit to ayoahha/Auto-Claude that referenced this pull request Jan 4, 2026
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]>
ruinosus added a commit to ruinosus/Auto-Claude that referenced this pull request Jan 4, 2026
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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/fullstack This is Frontend + Backend 🔄 Checking Checking PR Status feature New feature or request size/XL Extra large (1000+ lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants