[FEATURE] Expose background tasks (and tools-called-this-turn) to hooks — re-raise of #23386 with agent-teams use cases
Summary
Re-raising #23386 (auto-closed for inactivity, then locked, no maintainer engagement). The original ask — make running background tasks visible to hooks via input JSON — is still valid, and the agent-teams primitive landed in the interim has made it strictly more useful. I'd also push the ask one step broader: expose agent execution state to hooks, of which background_tasks is one slice and "tools called this turn" is another (motivated below).
Original use cases (from #23386, still apply)
- Prevent duplicate work — a
PreToolUsehook can block starting a second build/test run if one is already in progress. - Resource management — limit concurrent background tasks to avoid overwhelming the system.
- Stop-hook coordination — check if background work is still pending before allowing the agent to finish.
- Debugging / observability — log or display what's currently running.
New: agent-teams use cases
The TeammateIdle hook exists but is partially blind to the state of the teammate it's gating.
- TeammateIdle gate on in-flight background work. A teammate that still has a long-running
Bash run_in_background:trueor backgroundAgentshouldn't be allowed to idle yet, but the hook can't see what's still running. Without background-task visibility, the hook either over-blocks (forces wake-ups just to "check on something") or under-blocks (lets the teammate idle while a build/eval/job is still in flight). Either pattern degrades how the team-lead reasons about teammate state.
- Catch teammates that finished without calling
SendMessage. A teammate ending a turn withoutSendMessageAND with no background tasks pending is almost certainly stuck — they did the work but never told the lead. ATeammateIdlehook with visibility into (a) tools called this turn and (b) running background tasks could implement:
> "no SendMessage called this turn AND no background work pending → block idle, prompt the teammate to send a message to the lead before stopping."
This is a real recurring failure mode that the lead currently has to detect after the fact (or never).
This is the case that motivates the broader framing: background_tasks alone isn't enough. Tools-called-this-turn is the adjacent field that closes the loop.
- Lead-side stall detection. A
Stophook on the lead could check whether any teammate has background work pending before allowing the lead's turn to end. Less critical, same pattern.
Proposed input shape
Same shape as #23386 proposed, plus a sibling field for the per-turn tool calls:
{
"session_id": "abc123",
"hook_event_name": "TeammateIdle",
"teammate_name": "researcher",
"team_name": "infra",
"background_tasks": [
{
"task_id": "task-xyz",
"tool_name": "Bash",
"started_at": "2026-05-12T10:30:00Z",
"description": "Running test suite"
},
{
"task_id": "agent-abc",
"tool_name": "Agent",
"subagent_type": "Explore",
"started_at": "2026-05-12T10:31:00Z",
"description": "Exploring codebase"
}
],
"tools_called_this_turn": [
{"tool_name": "Read", "count": 4},
{"tool_name": "Edit", "count": 1}
]
}
Exact shape is a strawman — what matters is exposing these two pieces of state.
Current workaround (still bad)
Per-session sidecar state files keyed off session_id work for background_tasks but require user code to mirror what the harness already tracks. For "tools called this turn" the workaround is re-parsing the session's JSONL transcript on every hook fire — expensive and brittle.
Related
- #23386 — original request for
background_tasks(auto-closed for inactivity, locked). - #4321 — Session-Scoped In-Memory State for Hooks (broader framing).
- #50779 — agent-teams inbox delivery deferred until
end_turn; the workarounds in the comments there would benefit from background-task visibility for similar reasons.
---
🤖 Generated with Claude Code
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗