Attention model
Several agents create an attention problem. Instead of streaming logs, sessions emit attention signals, and agtd surfaces the ones that need you.
Attention levels
Section titled “Attention levels”Every signal has a level. Clients sort and surface sessions by it, not by raw output.
Program status reports
Section titled “Program status reports”The signal is the program’s own word. Through program status reports (OSC 7501), a program says it is working (with progress), blocked on you and why, done or error, with a one-line message.
agtd does not guess. A program that does not report shows as running, with no inferred waiting or idleness. A session needs attention until you look at it: attaching or detaching acknowledges it.
❯ agt ls RUN AGE NAME ACTIVITY CWD ATTENTION ⚠ 12m fix-tests blocked 2m ~/src/app permission: Run the tests? ● 40m dep-bump working 47% ~/src/app ● 3m docs idle 5m ~/src/docs Updated the README ○ 1h refactor exited ~/src/app finished (exit 0)
Sessions that need you come first in agt ls, in the picker and in the Ctrl-Y switcher. agt status NAME shows the details.
Which agents report
Section titled “Which agents report”- Claude Code reports natively since 2.1.295: permission prompts, questions and finished turns surface with their message, with nothing to configure.
- Agents that don’t report yet (Codex, older Claude Code, plain tools) show as running, with the foreground command and terminal title as context. A non-reporting command that is silent for half an hour records a
stallednotice.
Bells don't raise attention
Bells and desktop notifications (OSC 9 and OSC 777) are recorded as info-level events in agt events, but raise no attention and trigger no --notify.
Making agents ask out loud
Section titled “Making agents ask out loud”Any program can report with one escape sequence. agtd answers the protocol’s detection query for every session, attached or not.
❯ printf '\e]7501;state=blocked:kind=permission:msg=%s\e\\' "$(printf 'Deploy?' | base64)"Wrap a tool you already use to report how it finished:
❯ mytool; printf '\e]7501;state=%s:msg=%s\e\\' \
"$([ $? -eq 0 ] && echo done || echo error)" "$(printf 'mytool finished' | base64)"Typing into the session counts a blocked report as answered until the program reports again.
Following events
Section titled “Following events”Every session keeps its newest 500 events. Follow them, or get a desktop notification when a session needs you.
❯ agt events ❯ agt events fix-tests --follow ❯ agt events --follow --notify ❯ agt events --follow --level action --exec 'say "$AGTD_EVENT_SESSION needs you"' ❯ agt events --json --after 120
--notify writes to your terminal, so it pops a notification wherever your terminal supports one: iTerm2, Ghostty, WezTerm and kitty use OSC 9; VTE terminals, foot and urxvt use OSC 777. Inside tmux, set -g allow-passthrough on.