Skip to content

Stop new threads inheriting checkout/branch from viewed thread#4411

Merged
t3dotgg merged 5 commits into
mainfrom
t3code/fix-new-thread-context-fallback
Jul 24, 2026
Merged

Stop new threads inheriting checkout/branch from viewed thread#4411
t3dotgg merged 5 commits into
mainfrom
t3code/fix-new-thread-context-fallback

Conversation

@t3dotgg

@t3dotgg t3dotgg commented Jul 24, 2026

Copy link
Copy Markdown
Member

What Changed

  • Removed implicit workspace carry-over from every "new thread" entry point (cmd+n / cmd+shift+o, sidebar v1/v2 buttons, command palette). New threads inherit only the project from context; branch, worktree, and env mode always come from the configured defaults. Deleted buildContextualThreadOptions, startNewThreadInProjectFromContext, and the v1 sidebar's seed-context machinery.
  • Stored drafts reset stale env context on resurrection so drafts seeded under the old carry-over behavior stop resurfacing with "current checkout" branches. Composer text is preserved; a draft that's already open is left untouched.
  • Working mode still carries: model selection (including options like reasoning effort and context window), permission mode, and interaction mode follow from the viewed thread into the new draft. Composer overrides win over persisted thread state.
  • Explicit affordances for deliberate reuse:
    • "Previous worktree (branch)" entry in the composer workspace selector (desktop + mobile) points an unstarted draft at the project's most recently active non-archived worktree.
    • "New thread on branch" in the sidebar thread context menu (v1 + v2) seeds a draft with that thread's branch/worktree, with error toasts on failure.

Why

The new-thread defaults fix (#4276) only covered the no-options path. Every other entry point passed explicit options copied from the viewed thread, which silently bypassed the "always use new worktrees / default main / latest origin" preferences — new threads on remote boxes kept landing on "current checkout" and random branches. Carrying the workspace implicitly was the wrong default; carrying the working mode (model/effort/permissions) is what users actually want, and branch reuse is now an explicit, visible choice.

Review-bot findings addressed during review: working-mode carry now applies when explicit workspace options are passed; carried model selections replace stale draft options (replaceOptions); draft remaps across logical-project members no longer wipe workspace context; previous-worktree ranking uses parsed timestamps and skips archived threads; context-menu failures surface a toast.

UI Changes

  • Workspace selector gains a third "Previous worktree (branch)" option (only when an eligible worktree exists).
  • Sidebar thread right-click menu gains "New thread on branch" (only when the thread has a recorded branch).

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

🤖 Generated with Claude Code

"New thread" (cmd+n / cmd+shift+o, sidebar buttons, command palette)
copied the viewed thread's branch, worktree, and env mode into the new
draft, bypassing the configured defaults (new worktree from origin
main). Remove the implicit carry-over everywhere: only the project is
inherited from context; workspace context always comes from settings.
Stored drafts resurrected without explicit options also reset their env
context so stale "current checkout" drafts stop resurfacing.

What still carries over is the working mode: model selection (including
reasoning effort / context window options), permission mode, and
interaction mode.

Deliberate branch reuse gets explicit affordances instead:
- "Previous worktree (<branch>)" entry in the composer workspace
  selector points a draft at the project's most recently active
  worktree.
- "New thread on <branch>" in the sidebar thread context menu (v1+v2)
  seeds a draft with that thread's branch/worktree.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds explicit previous-worktree reuse, changes new-thread creation to avoid implicit workspace-context propagation, adds branch-based sidebar actions, and carries model/runtime state into new or resurrected drafts.

Changes

Thread context and worktree selection

Layer / File(s) Summary
Previous worktree selection
apps/web/src/components/BranchToolbar.logic.ts, apps/web/src/components/BranchToolbar.tsx, apps/web/src/components/BranchToolbarEnvModeSelector.tsx, apps/web/src/components/BranchToolbar.logic.test.ts
The toolbar selects the newest eligible prior worktree, displays its branch-aware label, and applies its branch, path, and project to the draft context.
Explicit thread creation paths
apps/web/src/lib/chatThreadActions.ts, apps/web/src/components/Sidebar*.tsx, apps/web/src/components/CommandPalette.tsx, apps/web/src/routes/_chat.tsx, apps/web/src/lib/chatThreadActions.test.ts, apps/web/src/components/Sidebar.logic*.ts
New-thread actions now use project-only context by default, while sidebar branch actions explicitly carry branch and worktree values.
Draft state carry-over
apps/web/src/hooks/useHandleNewThread.ts
New and resurrected drafts apply carried model, runtime, and interaction state with explicit workspace-context precedence.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

Possibly related PRs

  • pingdotgg/t3code#3 — Both modify branch/worktree selection and thread branch state in the web UI.

Suggested reviewers: juliusmarminge, maria-rcks

Poem

A rabbit hops through branches bright,
Reusing worktrees just right.
New threads spring with paths made clear,
Old context fades, explicit draws near.
Model and runtime tags align—
Fresh drafts bloom in orderly time.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main behavior change: new threads no longer inherit branch or checkout from the viewed thread.
Description check ✅ Passed The description matches the template and covers what changed, why, UI changes, and checklist items; screenshots for UI changes are still missing.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch t3code/fix-new-thread-context-fallback

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

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 24, 2026
Comment thread apps/web/src/hooks/useHandleNewThread.ts
…pace options

Review: the model/permissions/interaction-mode carry only ran in the
no-options branch of the stored-draft reuse path, so "New thread on
<branch>" (which passes explicit workspace options) reopened stale
drafts with their old model and permission mode. Restructure the branch
so explicit workspace options and the defaults-reset share one write
that always includes the carried working mode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread apps/web/src/hooks/useHandleNewThread.ts
…selection

Review: setModelSelection merges — a selection without options keeps the
draft's existing options, so carrying a thread whose model has no
options (default effort/context window) left the resurrected draft's
stale option state in place. Add a replaceOptions flag for callers
passing a complete snapshot and use it for the working-mode carry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursor cursor Bot left a comment

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.

Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fcae817. Configure here.

Comment thread apps/web/src/components/BranchToolbar.logic.ts Outdated
Comment thread apps/web/src/components/BranchToolbar.tsx
Comment thread apps/web/src/hooks/useHandleNewThread.ts
@macroscopeapp

macroscopeapp Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR changes core thread creation behavior by stopping implicit branch/worktree inheritance and adding new UI affordances for explicit worktree selection. The scope of runtime behavior changes to user-facing workflow warrants human review.

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

…t members

Review (high): setLogicalProjectDraftThreadId was called with only
threadId after the setDraftThreadContext write. When projectRef targets
a different physical member of the same logical project,
createDraftThreadState treats the remap as a project change and wipes
branch/worktreePath and forces envMode to "local", undoing both the
defaults reset and "New thread on <branch>" seeding. Pass the same
workspace context and carried working mode through the remap call.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Jul 24, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
apps/web/src/hooks/useHandleNewThread.ts (1)

149-167: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Minor duplication of the explicit-option spread pattern.

The per-field conditional-spread idiom used to build the explicit-override object (Line 152-156) mirrors the same pattern already used verbatim at Line 213-217 and Line 224-227. Consider extracting a small buildExplicitWorkspaceOptions(options) helper to avoid a third copy of this logic drifting out of sync if a new workspace field is added later.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/hooks/useHandleNewThread.ts` around lines 149 - 167, Extract the
repeated conditional-spread construction into a shared
buildExplicitWorkspaceOptions(options) helper, then use it in the
workspaceContext logic and the existing equivalent blocks around the later
occurrences. Preserve each field’s current option guards and values so all
explicit workspace overrides remain consistent.
apps/web/src/components/BranchToolbar.tsx (1)

176-182: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated "previous-worktree" sentinel string.

This literal is hardcoded here (twice) and also exported as PREVIOUS_WORKTREE_SELECT_VALUE from BranchToolbarEnvModeSelector.tsx. See consolidated comment for the shared fix across both files.

Also applies to: 202-209

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/BranchToolbar.tsx` around lines 176 - 182, Replace
the hardcoded "previous-worktree" sentinel checks in the BranchToolbar
value-change handlers with the shared PREVIOUS_WORKTREE_SELECT_VALUE export from
BranchToolbarEnvModeSelector.tsx, including both referenced handler locations,
while preserving the existing callback and return behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/src/components/BranchToolbar.tsx`:
- Around line 259-277: Filter the result from useThreadShellsForProjectRefs
before passing it to resolvePreviousWorktreeSeed in the previousWorktreeSeed
useMemo, retaining only threads whose archivedAt is null. Keep the existing
canUsePreviousWorktree and activeWorktreePath behavior unchanged.

In `@apps/web/src/components/Sidebar.tsx`:
- Around line 2129-2140: The new-thread-on-branch branch in Sidebar.tsx must
handle rejected handleNewThread promises instead of discarding them. Wrap the
call using the same settlePromise pattern as createThreadForProjectMember and
surface failures with the existing toast/error feedback, while preserving the
current branch, worktreePath, envMode, and startFromOrigin arguments.

In `@apps/web/src/components/SidebarV2.tsx`:
- Around line 1604-1616: Update the "new-thread-on-branch" case in SidebarV2.tsx
to handle rejected promises from handleNewThreadRef.current and provide user
feedback using the same failure-handling pattern as the equivalent Sidebar.tsx
action and nearby mutation flows. Preserve the existing branch, worktreePath,
envMode, and startFromOrigin arguments.

---

Nitpick comments:
In `@apps/web/src/components/BranchToolbar.tsx`:
- Around line 176-182: Replace the hardcoded "previous-worktree" sentinel checks
in the BranchToolbar value-change handlers with the shared
PREVIOUS_WORKTREE_SELECT_VALUE export from BranchToolbarEnvModeSelector.tsx,
including both referenced handler locations, while preserving the existing
callback and return behavior.

In `@apps/web/src/hooks/useHandleNewThread.ts`:
- Around line 149-167: Extract the repeated conditional-spread construction into
a shared buildExplicitWorkspaceOptions(options) helper, then use it in the
workspaceContext logic and the existing equivalent blocks around the later
occurrences. Preserve each field’s current option guards and values so all
explicit workspace overrides remain consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3b513d64-6ecc-45d8-9b12-fbc01957fae6

📥 Commits

Reviewing files that changed from the base of the PR and between 67a7b1a and 55a7695.

📒 Files selected for processing (13)
  • apps/web/src/components/BranchToolbar.logic.test.ts
  • apps/web/src/components/BranchToolbar.logic.ts
  • apps/web/src/components/BranchToolbar.tsx
  • apps/web/src/components/BranchToolbarEnvModeSelector.tsx
  • apps/web/src/components/CommandPalette.tsx
  • apps/web/src/components/Sidebar.logic.test.ts
  • apps/web/src/components/Sidebar.logic.ts
  • apps/web/src/components/Sidebar.tsx
  • apps/web/src/components/SidebarV2.tsx
  • apps/web/src/hooks/useHandleNewThread.ts
  • apps/web/src/lib/chatThreadActions.test.ts
  • apps/web/src/lib/chatThreadActions.ts
  • apps/web/src/routes/_chat.tsx
💤 Files with no reviewable changes (2)
  • apps/web/src/components/Sidebar.logic.test.ts
  • apps/web/src/components/Sidebar.logic.ts

Comment thread apps/web/src/components/BranchToolbar.tsx
Comment on lines +2129 to +2140
if (clicked === "new-thread-on-branch") {
// Explicit branch carry-over: reuse the thread's worktree when it
// has one, otherwise its branch on the local checkout.
void handleNewThread(scopeProjectRef(thread.environmentId, thread.projectId), {
branch: thread.branch,
worktreePath: thread.worktreePath,
envMode: thread.worktreePath ? "worktree" : "local",
startFromOrigin: false,
});
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Missing failure handling for the new "New thread on <branch>" action.

void handleNewThread(...) here has no error path, unlike createThreadForProjectMember (lines 1881-1893) in this same file, which wraps the identical call in settlePromise and shows a toast on failure. A rejected promise here silently fails with no user feedback. See consolidated comment for the shared fix with SidebarV2.tsx.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/Sidebar.tsx` around lines 2129 - 2140, The
new-thread-on-branch branch in Sidebar.tsx must handle rejected handleNewThread
promises instead of discarding them. Wrap the call using the same settlePromise
pattern as createThreadForProjectMember and surface failures with the existing
toast/error feedback, while preserving the current branch, worktreePath,
envMode, and startFromOrigin arguments.

Comment thread apps/web/src/components/SidebarV2.tsx Outdated
Comment on lines +1604 to +1616
case "new-thread-on-branch":
// Explicit branch carry-over: reuse the thread's worktree when it
// has one, otherwise its branch on the local checkout.
void handleNewThreadRef.current(
scopeProjectRef(thread.environmentId, thread.projectId),
{
branch: thread.branch,
worktreePath: thread.worktreePath,
envMode: thread.worktreePath ? "worktree" : "local",
startFromOrigin: false,
},
);
return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Missing failure handling for the new "New thread on <branch>" action.

Same gap as Sidebar.tsx's equivalent action: void handleNewThreadRef.current(...) has no failure path or user feedback, unlike this file's other mutation flows. See consolidated comment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/SidebarV2.tsx` around lines 1604 - 1616, Update the
"new-thread-on-branch" case in SidebarV2.tsx to handle rejected promises from
handleNewThreadRef.current and provide user feedback using the same
failure-handling pattern as the equivalent Sidebar.tsx action and nearby
mutation flows. Preserve the existing branch, worktreePath, envMode, and
startFromOrigin arguments.

… action

Review: both sidebars discarded the handleNewThread promise for the new
context-menu action, so a failed thread creation gave no user feedback.
Wrap in settlePromise and show the same error toast the other
new-thread flows use.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@t3dotgg
t3dotgg merged commit 2f41c07 into main Jul 24, 2026
16 checks passed
@t3dotgg
t3dotgg deleted the t3code/fix-new-thread-context-fallback branch July 24, 2026 01:06
jetblk added a commit to jetblk/t3code that referenced this pull request Jul 24, 2026
…nch inheritance fix

22 upstream commits (pingdotgg#4274-pingdotgg#4411). No conflicts; no overlap with the fork's
provider-usage feature or release pipeline.
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Jul 25, 2026
…otgg#4411)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 2f41c07)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 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