[Hooks] Missing hook events for inter-teammate notifications in Agent Teams
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Context — Waterfall framework
We're building a framework named "Waterfall" (working name, repo not yet public). It's a multi-agent SDD (Specification-Driven Development) framework built on top of Claude Code's experimental Agent Teams (CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1). It orchestrates 8 specialized agents (Orchestrator=OR, Team Leader=PM, Product Owner=PO, Tech Lead=TL, Reviewer=RV, Developers=DV, QA, Designer=DS) through a strict phased pipeline: BOOTSTRAP → DISCOVERY → SPECIFICATION → TECHNICAL_DESIGN → PLANNING → IMPLEMENTATION → CODE_REVIEW → VALIDATION → CLOSURE (This pipeline is actually a state machin written in bash shell). Agents communicate via SendMessage and a state machine driven by a bash script. The team leader agent acts as the central dispatcher and conversation hub with the Human Operator.
### Problem
With Agent Teams enabled, teammates emit idle_notification and peer_dm messages that surface in the team leader agent's conversation stream. In a workflow with 7 teammates idling between dispatches, this produces a continuous stream of low-signal chatter (idle pings, empty "standing by" summaries, peer-to-peer DM acknowledgments) that pollutes the team leader agent's UI and burns context tokens.
Proposed Solution
What's missing
The CLI Notification hook matchers (permission_prompt, idle_prompt, auth_success, elicitation_dialog) don't cover inter-agent events. The Agent SDK exposes TeammateIdle but it's not available in the Claude Code CLI.
Request
Expose a hook event — or extend Notification matchers — so users can filter/suppress inter-teammate notifications (idle_notification, peer_dm, or similar) before they reach the team leader agent's conversation. This would let multi-agent orchestration frameworks keep the team leader agent's context clean and focused on actionable events.
Alternative Solutions
_No response_
Priority
Medium - Would be very helpful
Feature Category
API and model interactions
Use Case Example
Concrete use case
In Waterfall, after the team leader agent dispatches a task to the Developer agent, the remaining 6 teammates (PO, Tech Lead, Reviewer, QA, Designer, Orchestrator) stay idle until their own phase is triggered. Each of them emits an idle_notification every few minutes with a passive summary ("standing by", "waiting for dispatch", ""). Over a typical 30-minute implementation phase, the team leader receives dozens of these notifications — none actionable, all consuming context tokens and forcing the team leader to re-read and dismiss them.
With a TeammateNotification hook (or equivalent), we could provide a filter script like:
```bash
#!/bin/bash
# ~/.claude/hooks/wf-suppress-idle.sh
# Drop idle_notifications with passive summaries; let actionable ones through.
input=$(cat)
summary=$(echo "$input" | jq -r '.summary // ""' | tr '[:upper:]' '[:lower:]' | xargs)
case "$summary" in
""|"standing by"|"idle"|"waiting"|"no action"|"waiting for dispatch")
echo '{"suppress": true}' ; exit 0 ;;
esac
exit 0
pass through
This would let the team leader focus only on notifications that carry a real status change or request, dramatically reducing noise in multi-agent workflows.
## Additional Context
### Concrete trace captured — 2026-04-21 run
Running a Waterfall need (`or-requery-on-step-advanced`) through the REQUIREMENTS phase produced the following noise pattern in the team leader's conversation stream. Captured over ~30 minutes of real workflow activity:
**Noise inventory**
| Event type | Count | Actionable? |
|---|---|---|
| `{"type":"idle_notification","from":"or","idleReason":"available"}` (no summary) | 7 | ❌ |
| `{"type":"idle_notification","from":"po","idleReason":"available"}` (no summary) | 3 | ❌ |
| `idle_notification` with peer_dm summary `"[to <agent>] <text>"` | 2 | ❌ (informational, per tool docs) |
| Actionable messages (PLEASE_COMPLETE_STEP, spawn_request, question HO, step_advanced) | ~8 | ✅ |
**Ratio : roughly 12 noise events for 8 actionable events — 60% of the stream is filler.**
**Representative examples (verbatim)**
Passive idle notifications after every turn — this teammate just sent a meaningful message and went idle:
{"type":"idle_notification","from":"or","timestamp":"2026-04-21T05:34:47.995Z","idleReason":"available"}
{"type":"idle_notification","from":"po","timestamp":"2026-04-21T06:06:49.979Z","idleReason":"available"}
Peer DM summaries leaking into the team leader's view — these are direct messages between PO and OR, but their summary shows up in the team leader's stream: {"type":"idle_notification","from":"or","idleReason":"available","summary":"[to po] Complète REQUIREMENTS:GENERATE_PRD — PRD.md validé"}
{"type":"idle_notification","from":"po","idleReason":"available","summary":"[to or] step_advanced REQUIREMENTS:GENERATE_PRD → CHECKPOINT_REQ"}
**Cost**
- **Context pollution** : each of these events is a full conversation turn the team leader must parse and dismiss.
- **Token burn** : with only 2 active teammates this is tolerable; at full team scale (8 agents), the signal-to-noise ratio collapses.
- **Cognitive friction** : the team leader has to visually distinguish passive notifications from actionable requests on every message.
### What a filter hook would solve
A single shell hook suppressing `idleReason:"available"` events without a "verdict-shape" summary would eliminate ~80% of these events with zero false negatives, as demonstrated by the `wf-suppress-idle.sh` sketch in the original request.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗