Skip to content

fix(web): attach prepared worktrees to the invoking draft - #9

Merged
Artic0din merged 2 commits into
mainfrom
fix/6-issue-draft-attachment
Oct 6, 2026
Merged

Artic0din merged 2 commits into
mainfrom
fix/6-issue-draft-attachment

Conversation

@Artic0din

Copy link
Copy Markdown
Owner

Fixes #6

Problem

Checkout pull request and Start work from issue reused the draft mapped to the project before the draft the user started from.
With several retained drafts in one project, starting from an older draft navigated to the other draft and overwrote its branch, worktree and prompt, while the setup script ran for the invoking thread.

Fix

resolvePreparedWorktreeDraft (ChatView.logic.ts) picks the target: the invoking draft when it belongs to the project, then the mapped draft, then a new draft.
Project membership is matched by environment and project ID instead of the draft's stored logical key, which goes stale when project grouping settings change.

Test plan

  • vp test run src/components/ChatView.logic.test.ts (131 passed, 4 new cases)
  • tsc --noEmit for apps/web
  • Lint: no new warnings in touched files
  • Manual: two drafts in one project, start an issue from the older one, confirm it stays on that draft

Release note: Starting a PR checkout or issue from a draft now keeps that draft instead of switching to another draft in the same project.

Model: Claude Opus 5.5 via Claude Code in T3 Code.

🤖 Generated with Claude Code

Checkout pull request and Start work from issue reused the draft
mapped to the project before the draft the user started from. With
several retained drafts, starting from an older one rewrote and
navigated to the other draft, while the setup script ran for the
invoking thread.

The invoking draft now wins when it belongs to the project, matched
by environment and project ID rather than the stored logical key,
which goes stale when grouping settings change. The mapped draft and
a new draft remain the fallbacks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-06T06:50:04.868793Z ae27829 New commits
🔒 Security Review ✅ Completed 2026-10-06T06:44:25.919247Z 0ae1056 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@sourcery-ai sourcery-ai 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.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="apps/web/src/components/ChatView.tsx" line_range="2794-2802" />
<code_context>
+        storedDraftId: storedDraftSession?.draftId ?? null,
+      });
+
+      if (target.kind === "active" && activeDraftSession) {
+        setDraftThreadContext(target.draftId, input);
+        setLogicalProjectDraftThreadId(logicalProjectKey, activeProjectRef, target.draftId, {
+          threadId: activeDraftSession.threadId,
+          createdAt: activeDraftSession.createdAt,
+          runtimeMode: activeDraftSession.runtimeMode,
+          interactionMode: activeDraftSession.interactionMode,
+          ...input,
+        });
+        return { threadId: activeDraftSession.threadId, draftId: target.draftId };
+      }
</code_context>
<issue_to_address>
**Promotion target gets lost**

When promotion is still in progress and preparation resolves the invoking draft as active before its route redirects or server shell appears, including when grouping changes leave its logical key stale, `setLogicalProjectDraftThreadId` rebuilds the session through `createDraftThreadState`, which clears `promotedTo`; `ThreadRouteView` loses the server-thread target and draft cleanup cannot finish.

Preserve `promotedTo` when rebuilding the session, or avoid selecting a promoted draft as active.

Also at `apps/web/src/components/ChatView.logic.ts:477-478`.
</issue_to_address>

### Comment 2
<location path="apps/web/src/components/ChatView.tsx" line_range="2796-2802" />
<code_context>
+
+      if (target.kind === "active" && activeDraftSession) {
+        setDraftThreadContext(target.draftId, input);
+        setLogicalProjectDraftThreadId(logicalProjectKey, activeProjectRef, target.draftId, {
+          threadId: activeDraftSession.threadId,
+          createdAt: activeDraftSession.createdAt,
+          runtimeMode: activeDraftSession.runtimeMode,
+          interactionMode: activeDraftSession.interactionMode,
+          ...input,
+        });
+        return { threadId: activeDraftSession.threadId, draftId: target.draftId };
+      }
</code_context>
<issue_to_address>
**Draft checkout loses association**

When the invoking draft differs from the mapped draft, which has a branch or worktree but no composer content, `setLogicalProjectDraftThreadId` remaps the project and deletes the mapped draft session, removing its branch or worktree metadata and leaving the checkout unassociated with a draft.

Retain the mapped draft session when it has branch or worktree metadata, even if its composer has no user content.
</issue_to_address>

Fix all in Cursor


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread apps/web/src/components/ChatView.tsx Outdated
Comment thread apps/web/src/components/ChatView.tsx Outdated
Remapping the project to the invoking draft rebuilt its session,
clearing an in-flight promotion target, and garbage-collected an
empty mapped draft along with its branch and worktree context.
Setting the invoking draft's context alone avoids both.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Artic0din
Artic0din merged commit 649f4f3 into main Oct 6, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(web): prepared worktrees attach to the project's mapped draft, not the invoking draft

1 participant