Live updates and reconnect
The open thread streams from the server as it happens, and so does the tab strip. When the link goes bad the app says so, and when it comes back it resumes exactly where it left off.
Why you would use it
You watch an agent work from a phone on a moving train. You need to trust two things: that what you see is current, and that the app tells you when it is not.
How to use it
Nothing to do. Opening a thread opens its stream. The connection dot
(#link-dot), right of the version (under the composer on a phone, in the
bar across the bottom of the window on a wide screen), and the offline
banner (#offline-banner) report the state.


What you see
- While connected,
#link-dotis a small plain dot with the titleconnected. - When the app decides it is offline, the dot turns amber, reads
OFFLINE, and its title becomesno connection to the VCode server. The offline banner appears. - Tab badges — working spinners, queued counts, new threads started from another device — move without a refresh.
- After a reconnect the transcript fills in what you missed, in order, with no gap and no duplicates.
Options and settings
| Option | Default | What it changes |
|---|---|---|
heartbeatMs (server, lib/app.js) |
15000 |
How often the stream sends event: ping. The client's budgets are written against this number |
REQUEST_TIMEOUT_MS (public/net.js) |
20000 |
How long any one API request may take before it counts as a network failure |
UPLOAD_TIMEOUT_MS (public/net.js) |
120000 |
The same budget for attachment uploads, which are measured in bytes |
HEARTBEAT_MS (public/net.js) |
15000 |
The client's copy of the server's heartbeat interval |
HEARTBEAT_MISSES (public/net.js) |
2.5 |
How many missed heartbeats make a stream dead (37.5s of silence) |
Limits and known gaps
- One missed heartbeat is not an outage. It takes more than 2.5 intervals of silence before the app declares the stream dead and reopens it.
- A clock that jumps backwards (a phone waking from sleep) never counts as a dead stream.
- A backgrounded tab closes its stream after 60 seconds and resyncs on return.
- The browser's own
onlineevent does not fire when only the server went away, so the app does not rely on it alone. - Token deltas (the live typing) and thread-list frames carry no id. They are never replayed and never enter the local replica.
Related
- open-the-app-offline
- queue-a-message-offline
- switch-tabs — the badges the thread-list frames move
- activity-line — what the stream draws while a turn runs
- status-bar — where the connection state also shows