Skip to content

Group threads by worktree#3898

Open
jakeleventhal wants to merge 33 commits into
pingdotgg:mainfrom
jakeleventhal:t3code/group-threads-worktrees
Open

Group threads by worktree#3898
jakeleventhal wants to merge 33 commits into
pingdotgg:mainfrom
jakeleventhal:t3code/group-threads-worktrees

Conversation

@jakeleventhal

@jakeleventhal jakeleventhal commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Solves #3697

Verification

Screen.Recording.2026-07-11.at.5.22.24.PM.mov

Summary

  • add a Group threads setting with Group by worktree as the default and Keep separate for the previous behavior
  • add workspace-aware thread creation with Main checkout, New worktree, and existing-worktree choices
  • make Cmd+N follow the configured default and add Cmd+T for creating a thread in the active worktree
  • group sidebar threads under their checkout/worktree and keep labels consistent across the picker and sidebar
  • fall back to a local base when a branch has no remote-tracking commit

Why

Thread creation previously conflated the registered project checkout, the true main checkout, and the active worktree. That made new drafts inherit whichever worktree happened to be active, produced misleading picker selections, and could make Cmd+N silently do nothing while resolving the main checkout.

The new flow resolves the primary checkout from Git worktree/ref data, keeps Cmd+N and Cmd+T semantics separate, and ensures checkout discovery failures cannot swallow thread creation.

User impact

Users can keep related threads grouped by worktree, deliberately create a thread in an existing worktree, and rely on Cmd+N to honor the configured Main checkout/New worktree default. Cmd+T always retains the active worktree.

Validation

  • vp check
  • vp run typecheck
  • focused web tests: 83 passed
  • desktop dev-app smoke testing for grouping, workspace selection, worktree creation, and provider submission

Note

Group sidebar threads by worktree and add chat.newSameWorktree shortcut

  • Adds a sidebarThreadGroupingMode client setting ('worktree' default, 'separate' legacy) that groups sidebar threads under labeled headers per worktree path, including a 'Main checkout' label for the primary checkout.
  • Introduces groupSidebarThreadsByWorktree and orderSidebarThreadsByWorktree in Sidebar.logic.ts with cross-platform path normalization (case-insensitive on Windows/UNC paths).
  • Updates BranchToolbarEnvModeSelector and MobileRunContextSelector to display and select main checkout and existing worktrees with encoded main:<path> / existing:<path> values.
  • Adds deriveWorkspaceOptions and resolveWorkspaceSelection in BranchToolbar.logic.ts to build deduplicated worktree option lists and resolve selection labels.
  • Adds startNewThreadInSameWorktreeFromContext and wires a new mod+t keybinding (chat.newSameWorktree) to start a thread in the currently active worktree.
  • resolveRemoteTrackingCommit now returns a structured RemoteTrackingRefNotFoundError; the server bootstrap falls back to the local base ref instead of failing when the remote tracking branch is missing.
  • Behavioral Change: sidebarThreadGroupingMode defaults to 'worktree', so existing users will see threads grouped by worktree immediately after update.

Macroscope summarized 3f42da8.


Note

Medium Risk
Touches thread bootstrap, worktree metadata, and default new-thread semantics across web/desktop; behavior changes on upgrade (default sidebar grouping) and git edge cases need regression testing.

Overview
Adds worktree-aware workspace UX across the sidebar, branch toolbar, and new-thread flows, with a server-side bootstrap fix when remote bases are missing.

Sidebar & settings: New sidebarThreadGroupingMode client setting defaults to Group by worktree; threads render under checkout/worktree headers (with Keep separate for the old flat list). Labels distinguish main checkout vs linked worktrees using mainCheckoutPath from listRefs.

Workspace picker: Branch toolbar workspace controls now offer Main checkout, New worktree, and existing worktrees (with path normalization and fallbacks when refs are partial). Chat can apply pending worktree/branch overrides before the first message on empty server threads.

Thread creation: Cmd+N (chat.new) uses per-project default env mode and resolved main-checkout branch/path instead of inheriting the active worktree. Cmd+T (chat.newSameWorktree) keeps the prior “same checkout” behavior. Cmd+Shift+N / local flows target the main checkout explicitly.

Git/server: resolveRemoteTrackingCommit surfaces RemoteTrackingRefNotFoundError; thread bootstrap with startFromOrigin logs and falls back to the local base branch instead of failing when origin/<branch> is absent.

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

@coderabbitai

coderabbitai Bot commented Jul 11, 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: 86b70d81-ec53-4961-9b7d-c3189a4be3ed

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 size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Jul 11, 2026
Comment thread apps/web/src/components/BranchToolbar.tsx Outdated
Comment thread apps/web/src/components/Sidebar.tsx Outdated
Comment thread apps/web/src/components/BranchToolbar.logic.ts Outdated
Comment thread apps/web/src/lib/chatThreadActions.ts
Comment thread apps/web/src/hooks/useHandleNewThread.ts Outdated
@jakeleventhal jakeleventhal marked this pull request as ready for review July 11, 2026 22:10
Comment thread apps/web/src/hooks/useHandleNewThread.ts
Comment thread apps/web/src/hooks/useHandleNewThread.ts Outdated
Comment thread apps/web/src/components/BranchToolbar.logic.ts Outdated
Comment thread apps/web/src/components/BranchToolbarEnvModeSelector.tsx Outdated
Comment thread apps/web/src/components/Sidebar.logic.ts
@macroscopeapp

macroscopeapp Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for grouping threads by worktree, including new UI, keybindings, and thread creation behavior changes. Additionally, 15 unresolved review comments identify potential bugs around race conditions, path handling, and defaults that warrant human review.

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

Here are some automated review suggestions for this pull request.

Reviewed commit: 9b96569856

ℹ️ 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".

Comment on lines +293 to +294
return (
serverConfigs.get(newThreadProjectRef.environmentId)?.settings ?? DEFAULT_SERVER_SETTINGS

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use target environment defaults for explicit project starts

When starting a thread from the sidebar or the command palette's "New thread in..." flow, startNewThreadInProjectFromContext is passed the selected projectRef, but the default mode/start-from-origin values here are resolved from newThreadProjectRef (the active/default project) instead. In a multi-environment setup where the selected project lives on an environment with different defaultThreadEnvMode or newWorktreesStartFromOrigin, the new draft is created with the wrong workspace mode for that target project.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in afe1ae1e: wire target-scoped defaults through sidebar, command-palette, and shortcut entry points.

environmentId: projectRef.environmentId,
input: { cwd: project.workspaceRoot, limit: 100 },
});
if (result._tag === "Failure") return activeProjectMainCheckout;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid reusing the active checkout for another project

If listRefs fails while resolving the main checkout for a project other than the active one, this falls back to activeProjectMainCheckout. In the "New thread in..." or sidebar project button flows, that can seed a draft for project B with project A's branch/worktree path, so the first send can run in the wrong checkout instead of the selected project's checkout.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Regression coverage added in fd4f7526 to ensure failed target discovery never reuses another project's checkout.

Comment thread apps/web/src/components/Sidebar.tsx Outdated
Comment on lines +984 to +985
const workspaceEnvironmentId = renderedThreads[0]?.environmentId ?? null;
const workspaceProjectId = renderedThreads[0]?.projectId ?? null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Build worktree identity per project in grouped rows

With the default repository project grouping, renderedThreads can include threads from several project ids/checkouts in the same repo, but this derives a single workspace identity from only the first thread. Threads from the other grouped checkouts that have worktreePath: null will not have their project checkout path substituted, so they are split into project-id buckets and mislabeled instead of being grouped with their actual worktree.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Regression coverage added in 0e60ec29 for grouped rows containing multiple project checkouts.

? renderedThreads.map(renderThread)
: null}
{shouldShowThreadPanel && threadGroupingMode === "worktree"
? renderedThreadGroups.flatMap((group) => [

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep keyboard order aligned with grouped rows

In worktree grouping mode, this renders each group's threads together, so a sorted list like A/worktree1, B/worktree2, C/worktree1 appears as A, C, B. The jump labels, next/previous navigation, and shift-selection ranges are still computed from the ungrouped thread order, so those shortcuts no longer match the visual row order whenever groups are interleaved.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in b4fa9a38: navigation, jump labels, and range selection now use grouped visual order.

Comment on lines +253 to +256
const defaultRef = activeProjectBranches.data.refs.find(
(ref) => !ref.isRemote && ref.isDefault,
);
return defaultRef ? { branch: defaultRef.name, path: null } : undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use the current checkout branch for local drafts

When a normal project checkout is currently on a feature branch while the default branch is main, this fallback returns main with path: null. Local-mode drafts do not run a checkout before the first send, so the agent still runs in the current cwd on the feature branch while the thread metadata/bootstrap records main, making sidebar/status data and later worktree bases point at the wrong branch.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 69592d82: local drafts are seeded from the branch actually checked out in the project checkout.

Comment on lines +4877 to +4879
setPendingServerThreadEnvMode("worktree");
setPendingServerThreadBranch(worktree.branch);
void updateThreadMetadata({

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the selected worktree for fast sends

For an empty server thread, selecting an existing worktree only stores the env mode and branch as pending while the worktreePath update is sent asynchronously. Until that metadata update round-trips, the send path still sees activeThread.worktreePath === null and treats worktree mode as a request to create a brand-new worktree, so pressing Enter immediately after selecting an existing worktree can run in a different checkout than the one selected.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 9145cbb1: pending existing-worktree selections are honored immediately by the send path.

projectRef.environmentId === newThreadProjectRef.environmentId &&
projectRef.projectId === newThreadProjectRef.projectId
) {
return activeProjectMainCheckout;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Wait for active ref discovery before seeding drafts

For the active project, this returns the memoized activeProjectMainCheckout even while the branch query is still loading or has failed, instead of running the resolver path below. Creating a default worktree draft in that window seeds branch: null, so the first send is blocked by "Select a base branch" despite the project having a current branch; local/main-checkout starts can similarly miss the discovered main checkout until the query happens to finish.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Regression coverage added in 67955356 for starting a draft while active ref discovery is still pending.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Comment thread apps/web/src/components/BranchToolbar.logic.ts Outdated
Comment thread apps/web/src/components/BranchToolbar.tsx Outdated
Comment thread apps/web/src/components/BranchToolbar.tsx
Comment thread apps/web/src/components/Sidebar.tsx Outdated
Drive-letter paths can differ only by casing across refs and thread metadata, so workspace matching must ignore case for those paths.

Co-authored-by: Cursor <cursoragent@cursor.com>
jakeleventhal and others added 3 commits July 11, 2026 22:54
withActiveWorkspaceFallback should run even when listRefs returns data, since the first page can omit the thread's current worktree.

Co-authored-by: Cursor <cursoragent@cursor.com>
Pass the effective checkout path into BranchToolbar so empty server threads show the selected worktree before metadata round-trips.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sidebar workspace identity should only treat an explicit main checkout path as main, not fall back to the project workspace root.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread apps/web/src/components/BranchToolbar.tsx Outdated

@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

Here are some automated review suggestions for this pull request.

Reviewed commit: 3abce121a5

ℹ️ 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".

Comment on lines +268 to +271
const activeWorktreePath =
activeWorktreePathOverride !== undefined
? activeWorktreePathOverride
: (serverThread?.worktreePath ?? draftThread?.worktreePath ?? null);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Forward pending worktree paths to the branch selector

When an empty server thread has a pending existing-worktree selection, this override makes the workspace picker show the selected checkout immediately, but BranchToolbarBranchSelector still reads serverThread.worktreePath/draft state and sees null until updateMetadata returns. If the user changes the branch before that round-trip, the branch picker treats the thread as “New worktree” from the project cwd and can write worktreePath: null instead of switching/reusing the selected checkout.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 5e3872d3: the branch selector now uses the pending worktree path immediately.

Comment on lines +35 to +36
function normalizeWorkspacePath(path: string): string {
return path.trim().replaceAll("\\", "/").replace(/\/+$/, "");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Normalize Windows workspace keys case-insensitively

For Windows-backed environments, the same checkout can be reported with different drive-letter/path casing by thread metadata vs. git worktree list; this normalizer only fixes separators/trailing slashes, so C:/repo and c:/repo become different sidebar group keys and fail the main-checkout comparison. In that case threads from the same worktree are split or the main checkout label is missed even though the paths refer to the same checkout.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 8b6e2257: Windows drive and UNC workspace keys are normalized case-insensitively, with regression coverage.

Comment thread apps/web/src/components/Sidebar.tsx Outdated
Comment on lines +991 to +997
threadGroupingMode === "worktree"
? projectMembers.map((member) => ({
member,
atom: vcsEnvironment.listRefs({
environmentId: member.environmentId,
input: { cwd: member.workspaceRoot, limit: 100 },
}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid loading refs for hidden project rows

Because SidebarProjectThreadList is mounted for every project row, default worktree grouping now builds and reads a listRefs atom for every member project even when shouldShowThreadPanel is false and no grouped rows will be rendered. In sidebars with many collapsed projects or repository-grouped members, this issues unnecessary git ref/worktree scans for hidden rows; gate these targets on the panel actually being shown.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 9d2ed11c: hidden project rows no longer subscribe to ref scans.

Comment on lines +288 to +291
const options = deriveWorkspaceOptions(
branchState.data?.refs ?? [],
activeProject.workspaceRoot,
branchState.data?.mainCheckoutPath,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include worktrees outside the first ref page

When a repo has more than the first 100 refs returned by useBranches, any existing worktree whose branch sorts after that page never reaches deriveWorkspaceOptions, so it is absent from the workspace picker unless it is the active fallback. The same partial page can also fabricate the main checkout as HEAD when its path is known but its branch ref was not loaded, so users with large repos cannot reliably choose existing checkouts.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 9644cd87: the workspace picker now loads all ref pages before deriving its complete worktree list.

Comment thread apps/server/src/ws.ts Outdated
})
.pipe(
Effect.matchEffect({
onFailure: (error) =>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Propagate unexpected origin-base resolution failures

When startFromOrigin is requested, this handler catches every resolveRemoteTrackingCommit failure and creates the worktree from the local branch instead. That fallback is appropriate when the remote-tracking ref is absent, but if the lookup fails for another reason after fetchRemote succeeds (for example a transient Git/config/refs error), the thread silently starts from a potentially stale local base despite the user asking to start from origin.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 770796f4: only a specifically classified missing remote ref falls back locally; unexpected lookup failures propagate, with regression coverage.

Comment thread apps/web/src/state/queries.ts
Comment thread apps/web/src/state/queries.ts
Comment thread apps/web/src/state/queries.ts

@macroscopeapp macroscopeapp 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.

Effect service conventions: one issue found. See inline comment.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/vcs/GitVcsDriver.ts Outdated

@macroscopeapp macroscopeapp 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.

Effect Service Conventions: one finding on the new resolveRemoteTrackingCommit failure handling. See inline comment.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/vcs/GitVcsDriver.ts

@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

Here are some automated review suggestions for this pull request.

Reviewed commit: 3ffbe06f2e

ℹ️ 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".

isServerThread &&
activeThread &&
activeThread.messages.length === 0 &&
activeThread.worktreePath === null &&

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Allow empty worktree threads to change workspace

Once an existing-worktree selection for an empty server thread round-trips, activeThread.worktreePath becomes non-null while the thread still has no messages/session. This condition then disables the override path, and BranchToolbar also treats the persisted worktree path as locked, so a user who picked the wrong existing worktree cannot switch back to Main checkout or another worktree before the first send without abandoning the thread.

Useful? React with 👍 / 👎.

effectiveEnvModeOverride: envMode,
activeWorktreePathOverride: activeWorktreePath,
activeThreadBranchOverride: activeThreadBranch,
onActiveThreadBranchOverrideChange: setPendingServerThreadBranch,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Track pending worktree paths from branch picks

For an empty server thread, choosing a branch that is already checked out in another worktree through the branch dropdown updates server metadata asynchronously with that worktree path, but the parent only records the pending branch override here. If the user presses Enter before the metadata update round-trips, activeWorktreePath is still null, so the send path treats the thread as the main checkout instead of the selected existing worktree.

Useful? React with 👍 / 👎.

}

function looksLikeWindowsPath(path: string): boolean {
return /^[a-zA-Z]:\//.test(path);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Normalize UNC workspace paths case-insensitively

Fresh evidence beyond the sidebar-path finding: the branch toolbar uses this separate normalizer, and it only lowercases drive-letter Windows paths. In Windows-backed environments where the same UNC checkout is reported as \\Server\Share\Repo by thread metadata and //server/share/repo by Git, workspacePathsEqual returns false, so the workspace picker can fail to recognize the selected main/existing checkout and show duplicate or wrong workspace choices.

Useful? React with 👍 / 👎.

@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 1 potential issue.

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 3f42da8. Configure here.

new Promise<undefined>((resolve) => {
timeout = setTimeout(resolve, MAIN_CHECKOUT_RESOLUTION_TIMEOUT_MS);
}),
])) ??

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.

Late race rejection unhandled

Low Severity

After the 500ms timeout wins Promise.race in resolveMainCheckout, a later rejection from resolveDefaultMainCheckout is no longer observed by the surrounding try/catch, so it can surface as an unhandled promise rejection instead of falling back to defaultMainCheckout.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3f42da8. Configure here.

@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

Here are some automated review suggestions for this pull request.

Reviewed commit: 3f42da85e8

ℹ️ 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".

loadRefs: async () => {
const result = await listRefs({
environmentId: projectRef.environmentId,
input: { cwd: project.workspaceRoot, limit: 100 },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Resolve all ref pages before seeding main checkout

When the selected project is a linked checkout and its real main checkout is on a non-default branch that falls outside the first 100 refs, this resolver never fetches the page containing the ref whose worktreePath matches mainCheckoutPath. resolveMainCheckoutTarget then falls back to branch: "HEAD" for that main checkout, so new local/default drafts are created with bogus branch metadata while running in the actual checkout; later sidebar/status data and new-worktree bases can point at HEAD instead of the checked-out branch. Load all ref pages here before resolving the main checkout, like the toolbar path does.

Useful? React with 👍 / 👎.

Comment on lines +152 to +155
await context.handleNewThread(projectRef, {
branch: mainCheckout?.branch ?? null,
worktreePath: threadEnvMode === "local" ? (mainCheckout?.path ?? null) : null,
envMode: threadEnvMode,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve defaults when reusing grouped-project drafts

When this path starts a draft for a selected grouped project, these options are lost if useNewThreadHandler reuses an existing stored draft for the same logical repo but remaps it to a different member project/environment: that branch calls setDraftThreadContext first, then setLogicalProjectDraftThreadId(..., { threadId }), and the remap clears branch/worktree/env on project changes. In that scenario, clicking New thread for project B while an unused draft from project A exists silently drops the target main-checkout/default-mode values and creates a local/null draft for B instead; forward the same options through the remap call as the active-draft path does.

Useful? React with 👍 / 👎.

{ key: "mod+0", command: "preview.resetZoom", when: "previewFocus" },
{ key: "mod+k", command: "commandPalette.toggle", when: "!terminalFocus" },
{ key: "mod+n", command: "chat.new", when: "!terminalFocus" },
{ key: "mod+t", command: "chat.newSameWorktree", when: "!terminalFocus" },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid binding same-worktree to New Tab

In the browser build, mod+t is the standard new-tab shortcut (Cmd+T/Ctrl+T), but this default binding now resolves to chat.newSameWorktree; ChatRouteGlobalShortcuts then calls preventDefault() for that command in chat views whenever the terminal is not focused. As a result, users typing in the composer or navigating the chat cannot open a browser tab with the normal shortcut and instead create a T3 thread, so choose a non-reserved default or gate this binding to the desktop app.

Useful? React with 👍 / 👎.

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

Labels

size:XXL 1,000+ 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