6 months ago
61a8734Desktop JSON-RPC turn starts could queue before the socket became fully ready, which left the chat UI in a misleading idle state: the optimistic user bubble appeared, but there was no busy indicator, no stop affordance, and no protection against accidental duplicate sends. This introduces an explicit pending turn-start state in the desktop runtime and routes the composer through a visible pending status until the server emits real progress or the request fails. While that state is active, duplicate plain sends are rejected so the user cannot keep stacking hidden requests behind a stalled start. Constraint: Pending turn starts must stay distinct from true busy turns so steer semantics only activate once a live turn exists Rejected: Mark queued turn starts as busy immediately | exposed steer UI before activeTurnId existed and still allowed misleading follow-up behavior Confidence: high Scope-risk: moderate Reversibility: clean Directive: Keep pre-start pending UI separate from busy/steer UI unless the runtime can guarantee an active turn id before showing steer affordances Tested: bun test apps/desktop/test/chat-reasoning-ui.test.ts apps/desktop/test/jsonrpc-single-connection.test.ts apps/desktop/test/protocol-v2-events.test.ts; bun run typecheck:desktop; live Electron app verification of send/busy/stop state Not-tested: Long-duration auto-reconnect behavior where a queued start stays pending for extended periods without eventual socket recovery
Parenta9537e9