Skip to content

Allow empty server threads to bootstrap new worktrees#1936

Open
juliusmarminge wants to merge 1 commit intomainfrom
feature/empty-server-worktree-bootstrap
Open

Allow empty server threads to bootstrap new worktrees#1936
juliusmarminge wants to merge 1 commit intomainfrom
feature/empty-server-worktree-bootstrap

Conversation

@juliusmarminge
Copy link
Copy Markdown
Member

@juliusmarminge juliusmarminge commented Apr 11, 2026

Summary

  • Enables empty server threads to enter New worktree mode and bootstrap the first send without forcing a separate draft thread.
  • Preserves selected base-branch state for empty server threads so branch changes made in the toolbar are used when creating the worktree.
  • Clarifies workspace labeling for locked env mode states and adds logic coverage for the new send/env-mode behavior.
  • Adds browser-level coverage for first-send worktree bootstrap and base-branch selection on empty server threads.

Testing

  • bun fmt
  • bun lint
  • bun typecheck
  • bun run test
  • Browser flow checks added in apps/web/src/components/ChatView.browser.tsx for:
    • bootstrapping the first send in New worktree mode from an empty server thread
    • updating the selected worktree base branch before send

Note

Medium Risk
Changes first-send behavior for server threads by allowing transient env-mode/branch overrides and affecting worktree bootstrap parameters; regressions could alter how/when worktrees are created on send. Impact is bounded to chat composer send/workspace selection and covered by new unit/browser tests.

Overview
Empty server threads (no messages, no worktree path) can now temporarily switch into New worktree mode and pick a base branch in the BranchToolbar, with those selections carried through to the first thread.turn.start bootstrap.

This adds pending override state in ChatView for env mode/branch, threads it through BranchToolbar/BranchToolbarBranchSelector, and adjusts send-time logic to use the overridden branch and a new resolveSendEnvMode guard (forcing local when not in a git repo).

UI copy for locked workspace display is shortened via resolveLockedWorkspaceLabel, and new unit + browser tests cover the empty-server-thread worktree bootstrap and base-branch selection behavior.

Reviewed by Cursor Bugbot for commit 9efc9f9. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Allow empty server threads to select env mode and base branch before bootstrapping a new worktree

  • Empty server threads without an existing worktree now support selecting a pending env mode and base branch before the first message is sent; the first send bootstraps a new worktree from those selections.
  • Adds pendingServerThreadEnvMode and pendingServerThreadBranch state to ChatView.tsx, passed down as overrides to BranchToolbar and BranchToolbarBranchSelector.
  • Adds resolveSendEnvMode in ChatView.logic.ts to force 'local' env mode when the project is not a git repository, regardless of the selected mode.
  • Replaces longer locked workspace labels with shorter 'Local checkout' / 'Worktree' labels in BranchToolbarEnvModeSelector via the new resolveLockedWorkspaceLabel util.
  • Behavioral Change: sending on an empty server thread in new-worktree mode now requires an active branch to be set and will no longer silently fall back; non-git repos are always coerced to 'local' at send time.
📊 Macroscope summarized 9efc9f9. 9 files reviewed, 1 issue evaluated, 0 issues filtered, 1 comment posted

🗂️ Filtered Issues

- Let the first send on an empty server thread override env mode and base branch
- Use shorter locked workspace labels in the branch toolbar
- Add coverage for worktree bootstrap and env-mode resolution
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 11, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0f40e424-c84e-4f40-ae67-04530a34eacb

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/empty-server-worktree-bootstrap

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

@github-actions github-actions bot added size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Apr 11, 2026
isGitRepo,
});

useEffect(() => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟠 High components/ChatView.tsx:2231

When switching from one server thread to another, both allowing environment mode overrides, pendingServerThreadEnvMode and pendingServerThreadBranch from Thread A incorrectly persist and apply to Thread B. The cleanup effect at lines 2231-2237 only resets these states when the new thread doesn't allow overrides, but when both threads allow overrides, the effect early-returns without clearing the pending state. This causes Thread B to use Thread A's pending branch selection when creating a worktree. Consider resetting the pending override state whenever activeThread.id changes, regardless of whether the new thread allows overrides.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file apps/web/src/components/ChatView.tsx around line 2231:

When switching from one server thread to another, both allowing environment mode overrides, `pendingServerThreadEnvMode` and `pendingServerThreadBranch` from Thread A incorrectly persist and apply to Thread B. The cleanup effect at lines 2231-2237 only resets these states when the *new* thread doesn't allow overrides, but when both threads allow overrides, the effect early-returns without clearing the pending state. This causes Thread B to use Thread A's pending branch selection when creating a worktree. Consider resetting the pending override state whenever `activeThread.id` changes, regardless of whether the new thread allows overrides.

Evidence trail:
ChatView.tsx lines 2220-2237 at REVIEWED_COMMIT - specifically lines 2231-2237 show the cleanup effect that early-returns when `canOverrideServerThreadEnvMode` is true, and lines 2223-2226 show how `pendingServerThreadBranch` is used to compute `activeThreadBranch` without regard to which thread the pending value was set for.

Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Pending override state leaks between empty server threads
    • Added a ref to track the previous thread ID so the cleanup effect resets pendingServerThreadEnvMode and pendingServerThreadBranch whenever activeThread.id changes, even when canOverrideServerThreadEnvMode remains true for both threads.

Create PR

Or push these changes by commenting:

@cursor push a440ab779e
Preview (a440ab779e)
diff --git a/apps/web/src/components/ChatView.tsx b/apps/web/src/components/ChatView.tsx
--- a/apps/web/src/components/ChatView.tsx
+++ b/apps/web/src/components/ChatView.tsx
@@ -2228,12 +2228,15 @@
     isGitRepo,
   });
 
+  const prevThreadIdForPendingReset = useRef(activeThread?.id);
   useEffect(() => {
-    if (canOverrideServerThreadEnvMode) {
-      return;
+    const threadChanged = prevThreadIdForPendingReset.current !== activeThread?.id;
+    prevThreadIdForPendingReset.current = activeThread?.id;
+
+    if (threadChanged || !canOverrideServerThreadEnvMode) {
+      setPendingServerThreadEnvMode(null);
+      setPendingServerThreadBranch(undefined);
     }
-    setPendingServerThreadEnvMode(null);
-    setPendingServerThreadBranch(undefined);
   }, [canOverrideServerThreadEnvMode, activeThread?.id]);
 
   useEffect(() => {

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 9efc9f9. Configure here.

}
setPendingServerThreadEnvMode(null);
setPendingServerThreadBranch(undefined);
}, [canOverrideServerThreadEnvMode, activeThread?.id]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pending override state leaks between empty server threads

Medium Severity

The cleanup effect includes activeThread?.id in its dependency array, suggesting it intends to reset pending state on thread navigation. However, the early return when canOverrideServerThreadEnvMode is true prevents the reset from ever running when switching between two empty server threads. pendingServerThreadEnvMode and pendingServerThreadBranch set on thread A will incorrectly apply to thread B, causing the toolbar to display the wrong env mode and branch, and potentially sending with the wrong base branch.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9efc9f9. Configure here.

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp bot commented Apr 11, 2026

Approvability

Verdict: Needs human review

1 blocking correctness issue found. New feature adding worktree bootstrap capability for empty server threads with significant state management changes. Two unresolved review comments identify the same bug: pending override state leaks between empty server threads when navigating, potentially causing incorrect branch selection.

You can customize Macroscope's approvability policy. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant