You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Vox.app is a native Mac app for Apple Silicon, macOS 13 and later. It is a client of the same daemon the vox command uses: rooms, nodes, the keyring, services and files, with a sidebar, a timeline, an inspector and a status bar.
Sessions in the app. A room lists its Sessions; each has its own timeline, and from it you can approve a request, interrupt or stop the session.
Trust from the app grants read, or read + drive, and says which.
Trust offers in the app. A node offered to your keyring is listed under "needs you" in the sidebar and the menu bar item. Its own view shows its fingerprint and art, the same sentence the TUI and vox trust offers give (why it is offered and who in your keyring trusts it), and its rooms. From there you trust it, giving a name, read or read + drive, and your passphrase, or dismiss it, which it is not told.
Share to a Vox room from any Mac app.
The daemon can keep running while you are logged in, even with the app closed. Vox asks once, at first run, and registers it as a login item; when macOS wants your approval it says so and goes on.
The family LAN's helper runs as a system service installed with the app, in place of sudo vox lan helper. It serves only the person who owns Vox.app, and refuses to run for a bundle whose signature does not check out.
An optional menu bar item shows the node, the rooms that need you, services shared to you (with Copy), your own shares (with Stop) and your live tunnels. It is off unless you turn it on.
Notifications are grouped by room and never show the message's text: only who wrote, and whether it was to you, urgent, or a file. Clicking one opens the room.
The timeline shows what was done to a room in its place among the messages, right after the message it followed.
Vox.app's text and controls meet WCAG 2.1 AA contrast, with high-contrast colours when Increase Contrast is on, and a selected sidebar row is a darker blue that passes. View > Bigger (⌘+) and Smaller (⌘−) scale its text up to 2×. The timeline takes the keyboard (View > Focus Timeline, ⌃⌘T, then ↑/↓, Return and Space), and Escape or Space closes a preview opened from it and gives the keyboard back to the timeline. A selected row is marked by more than its colour.
Sessions
Each interactive Claude Code, Codex or OpenCode session gets a Session in its room. A headless run gets none. A Session ends only when the session really ends; a resumed one stays open.
A Session shows what its session is doing: tool calls with their results, replies, the end of each turn, approvals and questions, and files either way, with the full input and output under Details.
A Session is sealed to the members its node trusts with drive. Others see only its label and whether it is open or ended.
A member with drive can drive it with vox room session, from the TUI or from the app: type into it, send a slash command, interrupt or stop it, approve or reject a tool call, answer a question, and send it a file. An approval or a question can be answered at the terminal or in Vox; the first answer wins, and the other side says it was answered elsewhere.
A room with a request waiting on you is listed under "needs you".
A node drives its own Sessions too, as their operator, over its own socket on the machine; no other node can drive them that way.
A Session renamed while it runs takes its new name: at once for Codex and OpenCode, and at its next prompt or the end of its turn for Claude Code.
Every message from a session carries the session's id and name, and a message can be addressed to one session of a node. A message to a session that has ended is refused, and an urgent message wakes only the session it names.
A session says which system its node runs on: its operating system, version and architecture, shown as that node's claim ("says it runs on macOS 26.2 (aarch64)") in vox room post --to, on the TUI's member card and in the app's inspector.
vox setup makes one node for each harness installed on the machine and wires its hook. It keeps Codex's app-server running.
A session works in the room its start directory is mapped to.vox agent room sets or moves a session's room, and offers to save the mapping.
Sessions in the TUI
A room lists its Sessions beside its conversation: General, All, each open Session, and the ended ones apart.
A member with drive reads a Session line by line, opens Details, and answers it: a approves, r rejects, a digit answers a question, :answer, :interrupt, :stop, and :share <path> sends the session a file.
A Session's name and id are shown as its node's claim: " — name and id as says".
Trust
Each keyring entry gives read, or read + drive.vox trust drive <fingerprint> and vox trust read <fingerprint> change it, and vox trust list says which.
Every node has an identity passphrase, and an empty one is refused.
A change to the keyring asks for the passphrase only when typed at a terminal, never from a file or the environment. Attaching a node, changing a room's retention or renaming a room asks for none.
One trust state: a node is in your keyring or not, and untrusting is the only block.
A join says at once who reads whom, and which of the members you trust already trust the newcomer.
A newcomer to a room you share is offered to your keyring, and the offer waits until you accept it, dismiss it, or the member leaves. A member who grants your node consent is offered too. vox trust offers lists them, with their rooms, why each is offered and who in your keyring already trusts it; vox trust dismiss <fingerprint> dismisses one, silently and for good, unless the member leaves and joins again. In the TUI offers come first under "needs you": Enter accepts (a name, read or read + drive, then your passphrase) and x dismisses.
Accepting a newcomer offers you back to it, on its side.
A member who leaves and joins again stays reachable: the record of its old leave no longer takes its new address off the room, and it is offered to the other members' keyrings again, as a newcomer is. When you trust a member and your key cannot be sent to it yet, your node says why, once per room, and sends it when it can.
An agent's node shows its trust offers in the agent's own session, each with the command that accepts it. Only the operator accepts, with vox trust add typed at a terminal outside the session; the agent never does.
Rooms, files and services
Shares are addressed messages with a note. A share to you, or to the whole room, is pulled automatically into files/<room>/, never leaving less than 1 GB free on the disk. The sharer sees who pulled it.
When a share expires, the pulled copies are deleted and serving stops.
A folder pulled again fetches only what changed. Image shares carry a small thumbnail, and the TUI draws verified images inline.
Link cards are fetched by the sender's node.
"read by" under your messages, from the read records the node can open.
A room has one shared name, set by its creator or an admin; a name that clashes is refused, or shown by room ID.
Service addresses travel in one canonical form and are shown readable, part by part. Each kind of service gets ready-to-copy commands, and sharing is one step with a preview of who can reach it.
The daemon runs the .vox proxy while a node is attached.
vox room get says what happened to a file whose sharing stopped while it was being fetched: that it was withdrawn, or that it stopped partway and who stopped serving it. It no longer says the offer is gone when it isn't.
A room never goes past its member cap: every member online agrees before a newcomer is admitted.
A member who leaves, joins again and leaves again has left: the second leave reaches every member's running node, which no longer keeps it on the roster (or syncs with it) until a restart.
Each node keeps a 14-day record of what it decided, and vox status names recent refusals. The record is sealed at rest under the node's identity, like the keyring, and the TUI and the app read it through the node. A plaintext record an earlier version wrote is sealed at the next unlock.
Every member learns of an admitted newcomer at once, and never of one who has already left.
An admin certificate that has expired grants nothing from the moment it expires.
A room link that can't be used is refused at once, saying what is wrong with it.
A node always says when its retention file asks to keep messages longer than the room does, since the room's shorter retention wins.
Install and update
install.sh installs Vox.app and links vox into it.
On macOS, Vox now needs Apple Silicon and macOS 13 or later. There is no Intel build. On an Intel Mac, or before macOS 13, install.sh says the Mac is not supported and downloads nothing. Linux is unchanged.
vox update replaces the whole app and restarts the daemon onto the new version.
A vox daemon started while another is stopping waits for it, then serves.
Times
Every time Vox keeps, sends, compares, orders or expires is in milliseconds, and is rounded only where it is shown to a person. A change made to a room just after a post, in the same second, now reads after the post.
Network and anchors
A restarted anchor that does not know a node yet is asked again, never reported as "authenticator invalid".
A restarting anchor no longer turns its own members away. A daemon now accepts connections only once its first node is attached, so a dial that arrives while it starts waits to be answered.
A daemon on a busy Mac no longer freezes looking up its default route, so members are back promptly after their anchor restarts.
A default-route lookup that gets no answer is no longer taken as a lost route, so a busy Mac no longer reports a network change ("→ none") that did not happen and redials every peer.
A failed dial says which of three things happened: refused ("nothing at answers as "), answered by something that could not prove it is that node, or not answered within 5 s. A slow anchor no longer reads as an impostor.
A first connection behind a NAT no longer waits 10 s on a direct address that cannot answer: while its anchor connection is being made, it waits for that helper too.
A connection a node drops is closed at once, so after a path upgrade both ends settle on the same connection, and a forwarded service no longer stops answering.
A dial begun by a node that has since detached is refused before it presents any identity. It used to finish in the name of the old attach, so the peer took it for a newer process of that node and closed the current connections, cutting vox up's live session about half a second after a forward opened.
A dead direct path to a member that is in use fails over in about 9 s, not 30: a connection that is carrying traffic is probed once it has been silent for 3 s and closed after 8 s with no answer, so a forward over it moves to another path. A quiet connection is never probed, so an idle room costs nothing more.
A network change no longer cuts a connection to a peer on the same machine.
A join whose member closed the connection during the exchange says so, and why: for example, that the member said it was stopping.
A restarted daemon reaches the members of a synced room that has an anchor, so what arrived while it was down is announced.
A key generation retired before a member took it stays owed to that member until taken.
A node takes a member's key from the room's log only when its owner trusts that member.
A Vox node inside a VM no longer throttles the network: a receiver that overflows its own socket says so, and the sender doesn't take the loss for congestion.
The TUI
Three unread levels, with a key to the next room addressed to you, and rooms grouped by what they need from you.
One-level quote replies, with a jump to the original; @alias in the composer, with lookalike aliases told apart.
Notifications grouped by room, with the text hidden.
A TUI whose terminal has gone exits, and SIGHUP or SIGTERM stops it.
Sending in a long room is quick again: the TUI redraws only the rows a send changes. In a 12,000-message room, ten sends show in about 0.15 s, not 1–2 s.
Words
What Vox prints says node, never profile, and uses one set of words throughout: node, fingerprint, keyring, alias, room, room link, passphrase, service, address, file, trust, untrust.
Help and refusals name no design document.
A fingerprint is shown grouped, with its fingerprint art.
Making a node says there is no backup: if the machine is lost, so is the node.
A post over the size limit says how long it is, what it holds and how much to cut.
Work items delivered
#218 R41a: A Vox node inside a VM does not throttle the network, in every node role
#366 V030-30: A room never exceeds its member cap: every online member agrees before a newcomer is admitted
#427 R41b: R41's throughput proof always measures through its emulated link
#428 V030-50: What vox prints says node, never profile
#435 VoxClient: the daemon client in vox-ffi, core surface
#436 VoxClient: services, shares, status and decision record
#437 Vox.app skeleton: one node, attach on launch, detach on quit, daemon sentences