Status and notifications
Agent states in the sidebar and tabs, notifications and the Dock
Agents and notifications
- Tab capsules, space rows and their agent rows, the hover card, notifications and the
Dock all read
agent_statusandcompletion_seqfrom the snapshot. No extra calls. - Status comes only from the multiplexer's API (D55), never from OSC 7501 (Future work).
- Each agent pane is needs you (herdr's
blocked), working, finished (not seen) or idle. herdr'sdoneis not used. A tab and a space show the strongest state of their panes, as one icon: needs you, then finished, then working; nothing when all are idle. - A finish stays unseen until the user leaves the agent's pane. The rules: Selection and "seen" are the app's own.
- Each change carries the time the app saw it, kept across relaunches while
herdr's
state_change_seqof the agent stays the same. An agent row shows a Working agent's time from that time.
Agents
One sidebar (D111): each space row shows its strongest agent's state and, unless folded, its agent panes, one line each with its state box and working time, by tab and place in the tab. A click on an agent row selects that space, tab and pane and gives the pane the keyboard. Its unread check stays until the user leaves the pane; the row does not move for it. Archived Sessions at the foot lists the closed sessions of Claude Code, Codex, Pi and OpenCode, which a click resumes.
The look is in Main window: Space rows and Agent rows.
Notifications
The app makes notifications itself, from snapshot changes, for every session open in any window. Each change posts once, even when several windows show the session:
- A pane's status becomes
blocked: "codex needs you", with "‹session› · ‹space› · ‹tab›" as the body. On a remote machine ‹session› is "‹machine› · ‹session›", or the machine's name fordefault; the subtitle below and the Dock menu use the same name. completion_seqchanges to a new non-null value: "pi finished", with the same body.- None for the panes of the tab shown in the key window while the app is active. The others still show as banners.
- None for the panes of a space that Show Only Pinned Spaces hides (Pinned spaces): they show no state at all.
- The first snapshot after app launch, or after a page opens, never notifies. After a reconnect, changes against the last known state do notify.
- The id is
"<machine>|<session>|<terminal_id>"(localfor This Mac), so a newer notification replaces the older one. It is removed when its tab shows in the key window, and when its state no longer holds (the pane works, idles, closes or loses its agent). - A click activates the app, shows that page and selects the pane.
- The app asks for permission (alerts and the badge) at launch; macOS asks the user only once.
- An agent posts its own with
ovvi notify <title> [<body>](CLI): the title and body it gives, with "‹agent› · ‹session›" as the subtitle. The id is"agent|<machine>|<session>|<terminal_id>", so a newer one from the same pane replaces the older. It is removed only when its pane closes. A click activates the app and shows the pane, as for needs you. One per asking pane every 10 s. - Three switches in Settings ▸ Agents turn them off: When an agent needs you, When an agent finishes and When an agent sends one, each on by default (D105, Settings).
Delivery
UNUserNotificationCenter. Its delegate is set at launch, in the app delegate (NSApplicationDelegateAdaptor), so a click that starts the app is not lost.- Dock badge: the number of panes that need you, over every open page, less the spaces Show Only Pinned Spaces hides.
- Sounds: none.
- Dock menu: a row per pane that needs you or finished ("codex needs you · default · infra"; a click selects it), less the spaces Show Only Pinned Spaces hides, a separator, then New Tab.