Skip to content

Preserve checkout context when creating threads#3918

Open
jakeleventhal wants to merge 3 commits into
pingdotgg:mainfrom
jakeleventhal:t3code/preserve-branch-when-creating-threads
Open

Preserve checkout context when creating threads#3918
jakeleventhal wants to merge 3 commits into
pingdotgg:mainfrom
jakeleventhal:t3code/preserve-branch-when-creating-threads

Conversation

@jakeleventhal

@jakeleventhal jakeleventhal commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • preserve the active draft's branch and worktree when creating another thread from the same project
  • preserve the active server thread's branch or worktree even when the global default thread mode is New worktree
  • retain the configured default mode as the fallback when there is no matching active thread context
  • add regression coverage for existing branches, existing worktrees, and active drafts

Why

Creating a thread from an existing branch or worktree communicates that the new thread should operate in that same checkout. Previously, resolveSidebarNewThreadSeedContext checked the global defaultThreadEnvMode first. When that setting was worktree, it returned only { envMode: "worktree" } and discarded the active branch and worktree path.

On the first message, that missing worktree path satisfied the worktree-bootstrap condition. T3 Code therefore created a new worktree with a temporary branch and later renamed the branch from the prompt. This made a contextual "new thread" action unexpectedly mutate repository structure and move the conversation away from the branch the user was already viewing.

That behavior is wrong because the default is a fallback preference, not an explicit request to override concrete checkout context. It is also risky and confusing: users can unintentionally accumulate branches and worktrees, and separate threads that were meant to collaborate on the same changes can end up in isolated checkouts.

The active matching context now takes precedence. A new branch is still created when the user is actually starting a new-worktree draft, or when there is no active context and New worktree is the configured default.

Validation

  • pnpm exec vp test apps/web/src/components/Sidebar.logic.test.ts
  • pnpm exec vp check
  • pnpm exec vp run typecheck

Note

Preserve checkout context when creating new threads in resolveSidebarNewThreadSeedContext

  • Previously, resolveSidebarNewThreadSeedContext would immediately override context with 'worktree' mode whenever defaultEnvMode was 'worktree', ignoring any active thread or draft state.
  • Now, the function checks for a matching activeDraftThread first, returning its full context (branch, worktreePath, envMode, startFromOrigin), then falls back to activeThread context with envMode derived from the presence of worktreePath, and finally falls back to defaultEnvMode.
  • Behavioral Change: new threads now inherit branch and worktree context from the active thread or draft instead of defaulting to the project-level env mode.

Macroscope summarized 6ce36df.


Note

Medium Risk
Changes thread-creation seeding and can affect worktree/branch bootstrap on first message; behavior is localized to sidebar logic with regression tests.

Overview
New threads from the sidebar now inherit the active checkout instead of being forced into a fresh worktree when the project default is New worktree.

resolveSidebarNewThreadSeedContext no longer returns early with only { envMode: "worktree" } when defaultEnvMode is worktree. It now seeds from a matching active draft (branch, worktree, env mode, startFromOrigin), else the active server thread in the same project (branch/worktree and local vs worktree from worktreePath), and only then falls back to the configured default env mode.

That stops “new thread” while viewing an existing branch or worktree from bootstrapping a new worktree and branch on first message. Tests cover draft-over-default, local branch, and existing worktree cases.

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

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

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: 06b44247-0fb8-4763-8c04-dec319fb6444

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

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.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Jul 12, 2026
@jakeleventhal
jakeleventhal marked this pull request as ready for review July 12, 2026 18:27
@macroscopeapp

macroscopeapp Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved

Straightforward bug fix that removes an early-return condition that was incorrectly discarding checkout context when creating threads. The change is small, self-contained, and well-covered by updated unit tests demonstrating the intended behavior.

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

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

envMode: input.activeThread.worktreePath ? "worktree" : "local",

P2 Badge Preserve worktree default when no branch is known

When defaultEnvMode is worktree, this newly reachable path also runs for matching active server threads that have neither branch nor worktreePath (for example, the auto-bootstrap empty thread is created with both fields null in serverRuntimeStartup.ts). In that case there is no checkout context to preserve, but this returns envMode: "local", so the sidebar “new thread” action silently ignores the user's New worktree default and creates a local draft instead of falling back to the default mode. Consider only overriding the default when the active thread actually has a branch or worktree path.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

if (input.activeThread?.projectId === input.projectId) {
return {
branch: input.activeThread.branch,
worktreePath: input.activeThread.worktreePath,
envMode: input.activeThread.worktreePath ? "worktree" : "local",

P2 Badge Fall back when active context is empty

When the current thread belongs to the same project but has both branch and worktreePath set to null, this branch now treats it as concrete context and returns envMode: "local", even if the project's default is worktree. In that scenario there is no checkout to preserve, and because handleNewThread treats the returned envMode as an explicit option, users with the New worktree default get a local draft instead of the default worktree flow.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

};
}

if (input.activeDraftThread?.projectId === input.projectId) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Scope inherited checkout context by environment

When the target environment's default mode is worktree, this new precedence now accepts an active draft/thread based only on projectId; the sidebar caller also filters with currentActiveDraftThread.projectId === member.id / currentActiveThread.projectId === member.id and does not compare member.environmentId. Project ids are only unique within an environment in this codebase, so with two environments containing the same project id, clicking the other environment's project can seed its draft with a branch/worktree path from the currently viewed environment. That path is persisted into the created thread and later used as the provider cwd via resolveThreadWorkspaceCwd, so the turn can fail or run against the wrong checkout instead of falling back to the target environment's new-worktree default.

Useful? React with 👍 / 👎.

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

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant