fix(tui): refreshed optimistic replay handles

Updated optimistic replay to track the replacement component handles created during transcript rebuilds, so expanded slash prompts still replace the raw replayed message.

Extended the regression test to cover the rebuild window called out in review.

Fixes #3199
This commit is contained in:
roboomp
2026-06-21 15:37:04 +00:00
parent 01f31a6238
commit b345b3aa57
2 changed files with 13 additions and 10 deletions
@@ -1461,15 +1461,17 @@ export class InteractiveMode implements InteractiveModeContext {
if (!this.optimisticUserMessageSignature) return;
const submission = this.#pendingSubmittedInput;
if (!submission || submission.cancelled || submission.customType) return;
this.addMessageToChat(
{
role: "user",
content: [{ type: "text", text: submission.text }, ...(submission.images ?? [])],
attribution: "user",
timestamp: Date.now(),
},
{ imageLinks: submission.imageLinks },
);
this.#optimisticUserMessageComponents = this.#captureAddedChatComponents(() => {
this.addMessageToChat(
{
role: "user",
content: [{ type: "text", text: submission.text }, ...(submission.images ?? [])],
attribution: "user",
timestamp: Date.now(),
},
{ imageLinks: submission.imageLinks },
);
});
}
#formatTodoLine(todo: TodoItem, prefix: string, matched: boolean): string {
@@ -116,6 +116,7 @@ describe("issue #2372 pre-streaming chat rebuild preserves optimistic submission
const addMessageSpy = vi.spyOn(mode, "addMessageToChat");
mode.startPendingSubmission({ text: "/jira-task" });
mode.rebuildChatFromMessages();
await controller.handleEvent({
type: "message_start",
message: {
@@ -135,7 +136,7 @@ describe("issue #2372 pre-streaming chat rebuild preserves optimistic submission
.map(content => content.text)
.join("\n");
});
expect(renderedTexts).toEqual(["/jira-task", "Expanded Jira task prompt"]);
expect(renderedTexts).toEqual(["/jira-task", "/jira-task", "Expanded Jira task prompt"]);
expect(mode.chatContainer.children).toHaveLength(1);
expect(mode.optimisticUserMessageSignature).toBeUndefined();
expect(mode.locallySubmittedUserSignatures.has("/jira-task\u00000")).toBe(false);