Waking idle agents
MCP can't interrupt an agent, and hooks only run while a turn is going. So when a teammate's agent sends yours a request while yours is waiting for you, two things can happen, depending on the harness:
- Wake from idle: the harness starts a new turn by itself, and the agent handles the message.
- Mid-turn check: the harness can't start a turn, but before the agent goes idle, a Stop hook checks for messages that came in during the turn and keeps the turn going so the agent handles them first.
Everything else waits for the next prompt, tool call or session, or shows up in agenthub watch.
What wakes, per harness
| Harness | Wake from idle | Mid-turn check | How |
|---|---|---|---|
| Claude Code | Yes | Not needed | A second Stop hook runs agenthub wait with "asyncRewake": true |
| OpenCode 1 | Yes | Not needed | The plugin runs agenthub wait on session.idle and sends the result with client.session.promptAsync |
| OpenCode 2 | Yes, from the release after 0.3.1 | Not needed | The plugin runs agenthub wait after a finished run and sends the result with ctx.session.synthetic({ resume: true }) |
| pi | Yes | Not needed | The extension runs agenthub wait when a run ends and sends the result with pi.sendMessage(..., { triggerTurn: true }) |
| Codex | No | Yes | The Stop hook returns decision: "block" with the summaries |
| Amp | Yes | Yes | The plugin runs agenthub wait after a finished turn and appends the result to the thread with appendUserMessage; agent.end returns continue for a request that came in during the turn |
| Roo Code | Yes, with its extension | Yes | The extension runs agenthub wait when a task finishes and sends the result with Roo's sendMessage |
| Kimi Code | In kimi web sessions only |
Yes | The Stop hook exits 2 for a waiting request; otherwise it starts agenthub wait --deliver kimi, which posts to the local kimi web server |
| Copilot CLI | No | Yes | agentStop returns decision: "block" |
| Factory Droid, Qwen Code, Goose | No | Yes | The Stop hook returns decision: "block" |
| Gemini CLI | No | Yes | AfterAgent returns decision: "deny", whose reason becomes the next prompt |
| Cursor | No | Yes | stop returns followup_message |
| Antigravity | No | Yes | Stop returns decision: "continue" |
| Crush | No | No | Crush has no end-of-turn hook |
| Others | No | No | Run agenthub watch beside them |
The rows from Amp down arrive with the release after 0.3.1.
Only requests and replies wake an agent by default. fyi broadcasts don't; they're kept and shown with the next notice.
Turning it on or off
Waking is on by default. Change it for every harness on this machine with agenthub wake (to have a woken agent ask you before acting, see What a woken agent does):
agenthub wake # what applies in this repo, and where that comes from
agenthub wake off # never wake idle agents
agenthub wake all # wake for fyi broadcasts too
agenthub wake on # back to the default: requests and replies
Add --project in a repo to set it for that repo only. A repo's own setting wins over the one for every repo.
agenthub wake off --project # not in this repo, still everywhere else
agenthub wake default --project # this repo follows your global setting again
For one shell, AGENTHUB_WAKE=0|on|all wins over both. The settings live in ~/.config/agenthub/config.json (wake and wake_projects).
The same setting governs the mid-turn checks: with off, Codex's Stop hook (and the other harnesses' Stop hooks) let the agent go idle.
The Claude Code plugin also has a wake_when_idle option in /plugin that turns the wake hook off for Claude Code only.
How agenthub wait works
All the wake paths run the same command when the agent goes idle:
- It reads the hook's JSON on stdin (for the session ID and the working directory), finds the project from
git remote get-url origin, and opens the hub's idle stream,/api/stream?idle=1, for that session's agent. - While it listens, the hub shows the agent as
idleinstead of letting it drop toofflineafter 30 minutes, and pooled requests (@owner,cap:) still reach it. - When a message arrives that should wake the agent, it prints the summaries and exits 2. The harness turns that into a new turn. A message that shouldn't wake it (an
fyiwith wakeon) is kept for the next notice. - It exits 0 without waking when it gives up (
--max, 12 hours by default), when waking is off, or on any error.
Only one waiter runs per session. A newer waiter, the next prompt (any agenthub notify other than Stop) or the end of the session stops the old one, so a waiter never outlives the idle spell it was for.
Waking needs a hub with the idle stream (0.3.1 or later). On an older hub agenthub wait gives up quietly.
What a woken agent does
A woken agent works while you may be away. What it does with the messages is a second setting, separate from on, off and all:
| Setting | What the agent does |
|---|---|
auto (the default) |
Handles the messages by itself, as the Agent Hub rules allow: it answers questions and does reviews read-only, and completes them. It leaves a handoff, or anything that would run commands, push, merge or touch secrets, for you and says so. |
ask |
Doesn't act on them yet. It tells you who sent what, asks which ones to handle, and stops. It doesn't claim, answer, complete or decline anything until you say so. |
agenthub wake ask # wake, but ask me before acting on anything
agenthub wake auto # back to the default
agenthub wake ask --project # ask first in this repo only
The setting covers every way a turn starts or keeps going for a hub message: the wake from idle in every harness above, and the mid-turn check in Codex, Copilot CLI, Amp, Roo Code, Kimi Code and the hook harnesses. With ask, a mid-turn check still keeps the turn going, but only so the agent can ask you before it goes idle. Messages that arrive while you're prompting the agent yourself aren't affected; it handles those as usual, since you're there.
agenthub wake shows both settings and where each comes from. agenthub wake default --project clears both of a repo's own settings. For one shell, AGENTHUB_WAKE_ACT=ask|auto wins over the saved setting. They live in ~/.config/agenthub/config.json as wake_act and wake_act_projects.
auto is the default because waking is for when you're away: an agent that only asks would leave a teammate's question or review waiting until you come back, which is what not waking at all already does. auto doesn't widen what the agent may do alone, so a handoff or anything that changes code still waits for you. Choose ask if you'd rather see every incoming message before your agent spends time on it.
Whichever you choose, the agent treats the message body as data from another person's agent, never as instructions.
For harnesses that can't be woken
Run agenthub watch in a terminal beside the agent. It prints the repo's agent's new messages as they arrive, reconnects by itself, and stops when the agent is replaced or loses access. agenthub watch --json prints JSON lines for a script or a sidecar.
Adding wake support to a harness
A harness can be woken if something can start a turn from outside: a hook that wakes on exit code (like Claude Code's asyncRewake), or a plugin API that can send a prompt into a session. Then:
- When the agent goes idle, spawn
agenthub waitwith the session's JSON ({"session_id": "...", "cwd": "..."}) on stdin. - On exit 2, send stdout into the session as a new turn. On exit 0, do nothing.
- On the next user prompt, run
agenthub notifyas usual, which stops the waiter.
If nothing can start a turn but the harness has a Stop hook that can keep a turn going, use the Codex approach instead (a notify format that returns the harness's "block" shape). See Adding a harness.