atrium — Docs
docs/concepts/daemon.md

The daemon

atriumd — agents that keep running when the window is closed.

Agents used to live and die with the atrium window. Now they don't: a background daemon called atriumd owns the sessions, the PTYs, and the activity state, and the window is a client that attaches to it.

Practically, that means closing the window no longer kills your fleet, a webview crash no longer takes your agents down, and the menu bar can tell you what's happening while atrium is not on screen.

Quitting vs. closing

Cmd+Q opens a progressive HUD rather than quitting outright:

  • Tap Cmd+Q again — detach. The window hides into accessory mode and the daemon keeps every agent running.
  • Hold Cmd+Q for about 1.4 seconds — full quit, with a progress ring. The runtime is SIGTERM'd and shut down in order.
  • Esc or click away — cancel.
Closing the window with the red traffic light does the same thing as detach while Keep running on close is on.

Background & startup settings

Settings → Background & startup:

  • Keep running on close (on by default) — closing the window detaches instead of quitting.
  • Launch at login (off by default) — installs a per-data-dir launchd agent so the daemon is up before you open the window. It respawns on crash but stays down after an intentional quit.

The menu bar

The tray icon is the atrium mark, embedded as a monochrome template image so it adapts to a light or dark menu bar. It turns accent-yellow whenever an agent is actively working, so "atrium is doing work" reads at a glance without opening anything.

  • The title carries the working count; corner badges carry the counts, with a bare + once they overflow.
  • The menu header spells it out: N working · M waiting, or K agents · idle when the fleet is up but quiet.
  • Per-agent rows with colored status dots. Click one to focus that pane — reopening the window if it was detached.
  • A popover that reuses the real activity sidebar, not a reduced copy: the same cards, the same density options, live updates.

Updates

Updates are idle-gated. atrium folds the fleet's turn state and waits for a quiet moment rather than interrupting a running turn, and it detects version skew between a running daemon and a newly installed app.

If an update leaves you with an app that will not start, recovery is CLI-only by design:

atrium update rollback

This reinstalls the app generation the last update superseded — the previous version is kept on disk at ~/.atrium/previous for exactly this purpose. See Install → Updating.

Durability

The daemon is built to survive being killed, not just to avoid it. Its crash-consistency suite runs repeated SIGKILL cycles and asserts that state is never torn: the contract is no corruption, explicitly not no loss. After a hard kill, PTYs survive, scrollback keeps growing across the gap, un-flushed state is still served, and interrupted runs are marked interrupted rather than left pretending to be alive.

Instances and data directories

Each atrium instance owns a data directory and a control socket, and every pane's shell is told which via ATRIUM_DATA_DIR and ATRIUM_SOCKET. Never infer the data directory from a channel name — resolve it from those variables, or you will read another instance's state. See Data directory.

A stale daemon can outlive an app restart. atrium context reports which instance you are actually talking to.