From 74390bca0a6cffae1babbde039ee6ba88cd86e90 Mon Sep 17 00:00:00 2001 From: NI0317 Date: Sun, 19 Jul 2026 11:22:48 +0800 Subject: [PATCH] fix(ui): never reuse a stale live-turn skeleton and poll lagging traces A finished turn whose persisted JSONL had not flushed yet left the live turn on screen; the next prompt then patched its content into the stale skeleton, so the new message rendered under the previous user bubble. Key each live turn and rebuild the skeleton on mismatch, and poll the persisted trace after a lagging read so the conversation converges without waiting for a user action. Module nav rows also collapse to one line at the primary-action control height. --- packages/ui/desktop/src/app.ts | 54 ++++++++++++-- packages/ui/desktop/src/styles.css | 7 +- packages/ui/desktop/tests/renderer.spec.ts | 87 ++++++++++++++++++++++ 3 files changed, 140 insertions(+), 8 deletions(-) diff --git a/packages/ui/desktop/src/app.ts b/packages/ui/desktop/src/app.ts index 33dacb2926..fc855d951f 100644 --- a/packages/ui/desktop/src/app.ts +++ b/packages/ui/desktop/src/app.ts @@ -69,6 +69,8 @@ interface SessionUpdatePayload { /** One in-flight turn rendered incrementally while ACP updates stream in. */ interface LiveTurn { + /** Distinguishes turns so a new prompt never reuses the previous turn's DOM skeleton. */ + key: number userText?: string thinking: string answer: string @@ -154,6 +156,9 @@ const state = { graph: buildTraceGraph('', []), expandedActivityIds: new Set(), traceLoadRevision: 0, + liveTurnCounter: 0, + traceCatchupTimer: undefined as number | undefined, + traceCatchupAttempts: 0, } function t(key: I18nKey): string { @@ -212,8 +217,8 @@ function buildShell(): void {