From agent-tools
How to coordinate with background tasks (dispatched sessions, CI watches, sub-agent dispatches) without polling or sleep-looping. Use Monitor for live streaming output; use run_in_background for fire-and-forget final-result cases. Wait for the harness notification, peek at in-flight output deliberately, surface stalled runs after a reasonable clock budget.
How this skill is triggered — by the user, by Claude, or both
Slash command
/agent-tools:dispatch-wait-reactThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
When you fire a long-running command -- a dispatched session, a `gh pr
When you fire a long-running command -- a dispatched session, a gh pr checks --watch, a sub-agent run -- the right coordination pattern
is background + notification, not poll-and-sleep. This skill
codifies the mechanism that turns "I fired something and now I'm
idle" into "I fired something, here's exactly how I track progress
and act on completion."
Primarily the dispatcher (the interactive session with the user). The dispatcher wants to stay responsive to the user while dispatches run, CI watches, etc. The "background + notification" pattern serves that.
The runner subagent is different. A runner subagent invocation
must complete the FULL lifecycle (fire the dispatch, push, mark ready,
watch CI, merge or surface) before returning to the dispatcher,
because the runner's return signals "task done." If the runner
backgrounds the dispatch and returns early, the lifecycle is
orphaned. The runner should fire its dispatch synchronously (no
run_in_background) and only return once the lifecycle is done.
See ../../agents/runner.md
for the runner-specific discipline.
gh pr checks <PR> --watch)Two mechanisms, different contracts:
| mechanism | use when | what you get |
|---|---|---|
Monitor tool | You want live output as it arrives (tail-and-react) | Each stdout line delivered as a notification; you react per line |
Bash(run_in_background=true) | You want fire-and-forget; only the final result matters | Task ID + output file; single notification on exit |
Use Monitor for:
Use run_in_background for:
gh pr checks --watch when you want a single "done" signalMonitor availability constraint: Monitor is NOT available when
DISABLE_TELEMETRY or CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC
env vars are set. When those vars are set, fall back to
Bash(run_in_background=true) and use the peek-at-output pattern
(section 3 below) to observe progress.
Monitor when you want live streaming outputMonitor(command="gh run watch 12345 --log")
# Each stdout line arrives as a notification; you react as they come.
The Monitor tool fires the command and notifies you once per stdout line. You can react to each line (surface status to the user, detect a failure mid-run, etc.) rather than waiting for the full run to complete.
When Monitor is unavailable (telemetry disabled), use
Bash(run_in_background=true) and peek at the output file
deliberately (see section 3).
Bash(run_in_background=true) for fire-and-forgetYou get back a task ID + an output-file path. Do NOT fire long-
running commands without run_in_background; that blocks your
turn waiting and burns budget on the same context. The default
should be: if it might take >5s, background it.
Bash(command="claude -p --agent runner --add-dir /path \"$(cat /tmp/task-N.md)\"", run_in_background=true)
=> Background job b7jv3db8o; output at /private/tmp/.../b7jv3db8o.output
Don't write a while not_done; sleep 10; check; end loop. The
harness will send a <task-notification> automatically when the
background command exits, carrying the task ID, exit status, and
output-file path. Your job is to wait for that notification,
not to invent a polling loop.
If you find yourself reaching for sleep to wait on a background
job, stop -- you're rebuilding what the harness already provides
for free.
Mid-run, you CAN read the output file via the Read tool to see what's been produced so far. That's free -- no spawned cost, just file IO. Good triggers to peek:
../spiral-diagnosis/SKILL.md
to identify echo-flush spam, cancellation cascades, or other
diagnostic signatures.Peek deliberately, not on every turn. Constantly reading the output file converts coordination into polling -- wasted cycles and noise in the transcript.
When the harness sends a <task-notification> for your job's
task ID, that's your cue to act. The notification carries:
Act based on the exit code:
../spiral-diagnosis/SKILL.md.
For agent-specific failure modes, see the relevant agent body.For each background task, have a rough sense of "too long":
| task | rough budget | reaction at 2x budget |
|---|---|---|
| Small dispatch (doc edit, small flag add) | 2-4 min | peek output + jsonl for spiral signatures |
| Medium dispatch (multi-file refactor, new module) | 5-10 min | same |
| Large dispatch (substantial new feature) | 10-15 min | same |
gh pr checks --watch (CI watch) | 2-5 min | check PR state; maybe merged externally |
| Sub-agent invocation | varies | depends on the sub-agent's scope |
If the harness hasn't notified by 2x the rough budget, peek first before assuming a hang. Then surface to the user with the status + your read on what's happening.
Don't silently wait past 3x budget without surfacing -- that's a real hang or a notification miss, and the user should know.
This skill sits underneath several lifecycle skills + agents:
draft-pr-first -- fire the dispatch ->
wait -> push -> ready -> watch CI -> wait -> merge. Each "wait"
is the pattern in this skill.orchestration-prompt-template --
the PR-lifecycle pattern that includes gh pr checks --watch in
background. Same wait shape.../../agents/dispatcher.md)
-- fire N background tasks; the notification fan-in handles
which finishes first. Wait for ANY notification, then
handle that one job, then go back to waiting.spiral-diagnosis --
when a wait is "too long" or the output file looks weird, peek
the spawned jsonl. That skill describes the diagnostic side;
this one describes the coordination side.DISABLE_TELEMETRY or CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC
is set. Don't assume Monitor is always present; check the env or
fall back to run_in_background.draft-pr-first -- the PR
lifecycle this skill enables.orchestration-prompt-template
-- the dispatcher's full prompt + PR-lifecycle pattern.spiral-diagnosis --
what to do when "wait" is "too long."Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub joshrotenberg/agent-tools --plugin agent-tools