OrbyNode uses one authenticated multiplexed WebSocket per client. REST handles commands; realtime state uses snapshots, sequenced events and bounded replay.
GET /ws
The client must send a hello op before subscribing.
{"op":"hello","last_seq":42101}
or {"op":"hello"} for a fresh session.
{"op":"sub","stream":"terminal:1"}
{"op":"unsub","stream":"terminal:1"}
{
"v": 1,
"seq": 42101,
"stream": "terminal:1",
"type": "terminal.output",
"data": {},
"priority": "droppable"
}
seq is a global monotonic sequence. priority is either critical or
droppable.
Critical events include attention, approvals and security state. Droppable events include raw terminal output and replaceable metrics.
Common stream shapes:
| Stream | Purpose |
|---|---|
terminal:<id> |
PTY output and terminal state. |
project:<id> |
Project-scoped task and worktree updates. |
attention |
Cross-project attention items. |
host |
Host and session metrics. |
notifications |
Notification deliveries. |
workflows |
Workflow run updates. |
Stream names are canonical strings, not scopes by themselves. Server-side authorization decides access.
Each stream has a bounded replay ring. On reconnect, the client sends its last sequence. If retained replay can cover the gap, the server resumes from the next event. If replay is unavailable, the client must request a fresh snapshot and discard stale state.
Sequence gaps indicate lost droppable events and require resnapshot or resubscribe. Critical events are protected ahead of droppable events.
Each client has a bounded outgoing queue. Slow clients never block producers or other clients. When droppable traffic overflows, that stream is marked for resubscribe or resnapshot. Critical traffic can replace old droppable entries when necessary.
PTY bytes use binary frames rather than JSON escaping:
[u32 big-endian stream-length][stream bytes][PTY payload]
The daemon reads the PTY once and fans the bytes out to authorized subscribers.
Every subscription is checked server-side. A client cannot learn state by guessing a stream name. Membership or role revocation ends access on the next authorization check; the project RBAC path closes unauthorized subscriptions.
The web client:
hello,Do not poll REST endpoints to derive live state.