Repository navigation
Description
Found by the reviewer of #1093 while enumerating every live-state the OpenCode terminal package can emit. #1093 covers the server that never came up; this is the other half.
The gap
| payload | emitted when |
|---|---|
{connected:false, reason:'server-unreachable'} |
only while everConnected === false, once per instance — the deadline timer |
{connected:false, reason:'stream ended'} |
only after a successful open |
{connected:false, reason:<read error>} |
only after a successful open |
{connected:true} / {connected:true, reason:'resync-incomplete: …'} |
open / re-sync |
SseStream.markDisconnected returns early when !this.connected, so a failed initial connect emits no disconnect at all — every disconnect-derived reason implies the channel was healthy once. #1093 deliberately reports only server-unreachable, because a flap is not a death: the package reconnects, and standing a permanent "reload this agent" banner over a pane that is about to be fine is the harm AgentTerminalLeaf warns about.
So today: a TUI whose server dies while the process lives — it is killed, it crashes, the port is stolen after the fact — emits {connected:false, reason:'stream ended'}, the adapter forwards it as a diagnostic, and nothing surfaces it. The pane keeps its last known activity and conditions, both stale, and programmatic prompt delivery (which goes through that server, #877) fails with no explanation.
Why it is not just "report that one too"
A disconnect is recoverable by design — the package retries with backoff for the life of the instance. Reporting every disconnect immediately would retrain the user to ignore the banner within a day. What is needed is a distinction #1093 does not have to make:
- a drop that the reconnect fixes → say nothing, or something transient;
- a drop that persists → say it, and clear it if the stream comes back.
#1093's recovery path (the renderer clears the banner on connected: true) is the half that already exists and makes this safe to build on: a persistent-drop report can be raised on a timer after a disconnect and withdrawn the moment the channel returns.
Acceptance
- A terminal pane whose live channel stays down for a meaningful period says so, in a way that clears itself when the channel returns.
- A brief reconnect does not produce a banner at all.
- Evidence first: a recording of a mid-session server death, as
port-conflict.jsonis for the never-came-up case.
Activity