fix(sessions): snapshot send target so a project switch cannot reroute a pending send (#2871)

Snapshot the new-session draft (and keep the existing-session target captured) at
submit time, then use that snapshot for draft materialization and routing instead
of re-reading live selection state after async preparation.

Fixes #2222
Fixes #2315
This commit is contained in:
Serhii Dziupin
2026-08-13 12:31:33 +03:00
committed by GitHub
parent 8a6eca5597
commit d3011a6247
3 changed files with 138 additions and 7 deletions
+14 -3
View File
@@ -962,6 +962,9 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
const queuedMessageId = options?.queuedMessageId;
const delivery = options?.delivery === 'steer' && sessionPhase !== 'idle' ? 'steer' : undefined;
const capturedTarget = messageQueueTarget;
// Snapshot the draft and current-session identity before the first
// async gap so a later sidebar selection cannot reroute the send.
const capturedDraftSnapshot = newSessionDraftOpen ? { ...newSessionDraft } : null;
const inputSnapshot = options?.presetText != null
? {
message: options.presetText,
@@ -1034,9 +1037,17 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
}
}
const sendMessageOptions = capturedTarget
? { target: capturedTarget, ...(delivery ? { delivery } : {}) }
: delivery ? { delivery } : undefined;
const sendMessageOptions: {
target?: NonNullable<typeof capturedTarget>;
draftSnapshot?: NonNullable<typeof capturedDraftSnapshot>;
delivery?: 'steer';
} | undefined = (capturedTarget || capturedDraftSnapshot || delivery)
? {
...(capturedTarget ? { target: capturedTarget } : {}),
...(capturedDraftSnapshot ? { draftSnapshot: capturedDraftSnapshot } : {}),
...(delivery ? { delivery } : {}),
}
: undefined;
// Inline review comments and synthetic context are consumed before
// assembly so a failed send can restore exactly what it took.