Status and triage
Sessions classify themselves from their own output. Nothing is configured, no wrapper script is installed, and the shell is a normal shell. Saggar reads the same things you would read if you were looking at it, which is the only reason it works on the agent you started by hand.
The statuses
| Status | Means |
|---|---|
| Needs you | An agent is blocked on a question, or the shell rang a bell. This is the only state that wants a human, and it is the one the menu, the dock badge, the notifications, and the phone app are all built around. |
| Working | Output is moving. Nothing to do. |
| Idle | A prompt is sitting there, quiet. Often an agent that stopped short and would carry on if nudged. |
| Finished | The session's shell exited cleanly. Review it or move on. |
| Failed | The session's shell exited with a non-zero code. It ranks above a clean finish in triage. |
| Ready for review | A long job finished inside a session that is still alive, and left uncommitted work behind. |
Why Ready for review exists
The five above are classified from the session alone; Ready for review takes the worktree too, which is why it is the one state that can say something was produced.
It exists because the shell outliving the job is the normal case, not the exception. An agent that works for twenty minutes and stops is still sitting at its own prompt afterwards. Nothing exited, so Finished never applies, and without a word of its own it would read as Idle: the same as a session nobody has touched since this morning.
A job that ends having changed nothing stays quiet, so the state means work is waiting rather than merely that something ended.
What it reads
These signals feed the classifier:
| Signal | Source | Feeds |
|---|---|---|
| Interaction cues | a scan of the transcript tail | needs you |
| Output activity | the pty's own data callback, not polling | working / idle |
| Command marks | OSC 133 shell integration: a command in flight, even a silent one | working |
| Bell | BEL: an agent finished, or wants you | needs you |
| Watch patterns | your own patterns in Settings ▸ Notifications | needs you |
| Program notifications | an urgent notification a program raises with an escape sequence | needs you |
| Exit code | process termination | finished / failed |
| Session title | what the agent writes there | session name |
| Process tree | a walk of the shell's children | agent presence |
Interaction cues
The cue vocabulary is deliberately verb-agnostic. Any Do you want to… or Would you like to… counts, so every flavor of approval prompt is caught rather than the three or four somebody remembered to enumerate.
A bell-raised needs-you clears itself when output resumes or you type.
The handshake outranks the scan
Where an agent handshake is installed, it outranks all of this: a permission prompt raises needs you by contract, with no transcript scan involved.
How it asks for you
Status drives five surfaces.
The menu
A mark per session, and a rollup per project. A folded project wears the loudest mark of what is inside it.
The attention cards
Blocked sessions stack over the menu's bottom-left corner. The top card shows the waiting question with the prompt's own options as buttons, so it can be answered without opening the session at all. The cards behind peek out with the queue depth, and the dock icon badges with the same count.
Behind the blocked sessions come the cards that aren't a question in a terminal: a hook event waiting on your review, and a provider that has spent a quota window, which says when the account is back and leaves when it is.
Sounds
Each state change speaks in its own voice: one tone for a new waiter, another for a failed exit, another for a clean finish. One tone per beat, loudest wins, so several sessions turning at once never stack into noise.
It also reads the room. A cue that lands while you are mid-keystroke in another session is held and delivered as a single catch-up once you pause. A decision request should never yank you out of thought.
Notifications
A Notification Center banner posts when Saggar isn't the app you are looking at: a session waiting on you, a shell that just finished or failed, or work that became ready for review. Tap it to raise Saggar on that session.
- A waiting prompt is not a one-shot edge, so leaving Saggar with one still open raises it once; clearing the prompt re-arms the next one.
- Visiting a session, or resolving its claim, removes its delivered notification.
- Settings shows whether macOS has allowed banners and links to System Settings when it has not.
Your phone
The same events, over remote control, if you have armed it.
Triage: ⌘J
One key walks every session with a claim on you, loudest first. The order is fixed, and it is the app's opinion about what a claim actually is:
- Blocked on a prompt
- Failed: an exited shell, or a long job that failed inside a live one
- Ready for review: uncommitted work, whether the shell exited or not
- Finished clean
Within a class, longest-waiting first. Each press selects the next stop, raising its window if it has been popped out.
With nothing left waiting, the key lands on a quiet 0 waiting card instead. The app's whole question is answered with no one, which is a better end to the walk than the key going dead.
Answer the session in front of you
⌘↩ types a waiting prompt's default answer, or marks a bell-only needs-you
as seen, and falls through to the shell whenever there is nothing to answer.
The palette has bulk versions of the same idea:
- accept every waiting prompt;
- tell every idle agent to continue;
- close all the idle ones.