fix(tui): recover stale streaming status after unbound final#73749
fix(tui): recover stale streaming status after unbound final#73749vincentkoc merged 3 commits intomainfrom
Conversation
Greptile SummaryThis PR fixes a stale Confidence Score: 4/5Safe to merge; only P2 style/test clarity suggestions, no logic defects found. The guard rewrite is logically sound, concurrent-run protections are preserved, and the three new tests cover the primary recovery paths. Two P2 observations: the ternary in the guard deserves a clarifying comment to prevent well-intentioned simplifications that would regress the fix, and one test pre-condition is achieved through direct state mutation rather than organic event flow, weakening its regression value slightly. No files require special attention beyond the inline notes. Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/tui/tui-event-handlers.ts
Line: 199-207
Comment:
**Subtle guard — null vs. absent distinction**
The rewritten guard is logically correct but the ternary `(activeRunId ? sessionRuns.has(activeRunId) : false)` is easy to misread at first glance. When `activeRunId` is `null` the sub-expression evaluates to `false`, which means the guard does **not** bail, allowing the stale-streaming clear to proceed. This is exactly the intended fix — but the semantics are the opposite of what the surrounding `||` chain might suggest to a reader expecting "any truthy sub-expression = bail".
A small inline comment would prevent future readers from accidentally "simplifying" the ternary back to `sessionRuns.has(activeRunId!)` or `!!activeRunId && sessionRuns.has(activeRunId)` (both of which would break the null case).
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: src/tui/tui-event-handlers.test.ts
Line: 605-619
Comment:
**Direct state mutation simulates an impossible in-production sequence**
Between the two `handleChatEvent` calls the test manually resets `state.activityStatus = "streaming"` and `state.activeChatRunId = null`. In practice the first "final" event would have already moved `activityStatus` to `"idle"` via `finalizeRun`, so the second event would hit the `activityStatus !== "streaming"` guard and be a no-op regardless of the fix. The test therefore validates a state that real event flow cannot produce.
If the intent is to prove the helper clears stale streaming when a duplicate final arrives while the status happens to be `"streaming"`, consider documenting why that state is reachable (e.g., an interleaved delta from another run armed streaming after the first final), or add a delta from a second run before the second final to make the pre-condition organic.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(clownfish): address review for ghcra..." | Re-trigger Greptile |
|
Codex review: needs maintainer review before merge. What this changes: The PR updates TUI event handling to clear stale Maintainer follow-up before merge: Leave this PR open for maintainer review. If accepted, land the narrow TUI handler recovery and regression tests for null-active-run duplicate finals and local Best possible solution: Leave this PR open for maintainer review. If accepted, land the narrow TUI handler recovery and regression tests for null-active-run duplicate finals and local What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against e6cd90e3fd9c. |
1518c6c to
4b26bcd
Compare
4b26bcd to
0a34647
Compare
0a34647 to
37f2109
Compare
…w#73749) * fix(tui): clear stale streaming after unbound final events * fix(clownfish): address review for ghcrawl-156749-autonomous-smoke (1) * fix(tui): address stale streaming review
…w#73749) * fix(tui): clear stale streaming after unbound final events * fix(clownfish): address review for ghcrawl-156749-autonomous-smoke (1) * fix(tui): address stale streaming review
Summary
Attribution
This replacement carries forward the narrow ideas from @briandevans in #64842 and #64843, and from @Yanhu007 in #64847 and #64862. Those branches are closed and maintainer_can_modify=false, so ProjectClownfish cannot safely update them directly.
Validation
Notes
Related UX timing issues #67052 and #67053 remain open because they ask for a prompt content-completion/finalizing transition beyond this narrow stale terminal-state recovery.
ProjectClownfish replacement details: