Agent hooks
Agents (Claude Code, Codex, Cursor) can report lifecycle state to the multiplexer without relying on screen heuristics.
Socket API
{"id":"1","method":"pane.report_agent","params":{
"pane_id": "w1:p1",
"agent": "claude",
"state": "working",
"source": "hook"
}}
States: idle, working, blocked, done, unknown.
When source is hook, screen heuristics are ignored until the pane is reset.
Shell hook example
Install into your agent wrapper (~/.config/flock/hooks/herdr-agent-state.sh):
#!/usr/bin/env bash
# Usage: herdr-agent-state.sh <pane_id> <agent> <state>
PANE_ID="${1:?pane_id}"
AGENT="${2:?agent}"
STATE="${3:?state}"
SOCKET="${FLOCK_SOCKET:-$HOME/.config/flock/flock.sock}"
printf '%s\n' "{\"id\":\"hook\",\"method\":\"pane.report_agent\",\"params\":{\"pane_id\":\"$PANE_ID\",\"agent\":\"$AGENT\",\"state\":\"$STATE\",\"source\":\"hook\"}}" \
| nc -U "$SOCKET"
Claude / Codex / Cursor integration
| Agent | Suggested hook point |
|---|---|
| Claude Code | Wrap claude in a shell function; call hook on tool-approval and turn-complete |
| Codex | Export CODEX_HOOK_CMD pointing to the script above |
| Cursor | Use cursor-agent lifecycle env callbacks if available; else poll is fallback |
CLI wait helper
flock herd wait --pane w1:p1 --status idle --timeout-ms 60000
Equivalent to events.wait with pane_agent_status_changed.
Environment
| Variable | Purpose |
|---|---|
FLOCK_SOCKET | Override default ~/.config/flock/flock.sock |
FLOCK_ENV=1 | Set in spawned pane shells (detect flock-managed sessions) |