Hook Payloads¶
Hook payloads vary by agent runtime. Repowire normalizes them before handler code updates peer state or extracts responses.
Normalized concepts¶
| Concept | Claude Code | Codex | Gemini / Antigravity |
|---|---|---|---|
| Prompt event | UserPromptSubmit |
UserPromptSubmit |
BeforeAgent |
| Stop event | Stop |
Stop |
AfterAgent |
| Response field | transcript JSONL | last_assistant_message |
prompt_response |
| Hook output | empty | empty | {"decision": "allow"} |
Runtime model capture¶
Repowire stores the observed runtime model on peer.model when a backend
explicitly reports it. This is runtime state, not spawn intent: Repowire does
not parse --model out of command strings or spawn profiles.
| Backend | Capture path | Gotcha |
|---|---|---|
| Claude Code | SessionStart hook model field. |
Claude Code exposes model on SessionStart; later hook events may not refresh it. |
| Codex | Hook model field on registration and later prompt/stop events. |
Missing values preserve the last known model. |
| Gemini | Best-effort explicit hook model field, if present. |
Current Repowire Gemini path has no confirmed model field. |
| Antigravity | Same best-effort extraction as Gemini once hooks fire. | agy hook firing is still pending upstream, so daemon-spawned CLI-fallback peers usually have no model. |
| OpenCode | Plugin message.updated user-message model; modelID becomes peer.model, provider/model details stay in metadata. |
Model may be unknown until OpenCode emits its first user-message model info. |
| Pi | None in v1. | The current extension path has no clear model accessor/event. |
| MCP HTTP | Caller-supplied model on register/connect/update. |
External transport is authoritative; the daemon does no inference. |
SessionEnd¶
SessionEnd fires once at a true session boundary and carries a reason
(Claude Code: prompt_input_exit for /exit, clear for /clear, logout,
other). The handler always writes the handoff summary, then — for any
reason other than clear — resolves the pane's peer_id and posts a terminal
offline (reason=session_end), deregistering the peer immediately. clear is
skipped because a SessionStart with source=clear rebinds the same pane
milliseconds later. It does not fire on SIGKILL; the ws-hook's agent-pid
watcher covers that case.
Codex has no SessionEnd hook event (its hook set is SessionStart /
UserPromptSubmit / Stop plus tool, compact, and subagent events), so codex
quit deregistration rides entirely on the agent-pid watcher. Repowire
pre-trusts its codex hook entries in [hooks.state] when repowire setup
writes hooks.json — codex silently skips untrusted hooks, so without the
pre-trust every setup run would disable the codex transport until the user
re-trusts in the TUI.
Default delivery path¶
The default hooks + MCP transport uses hooks for lifecycle and Stop-hook reminders, MCP for outbound commands, and tmux pane injection for live inbound delivery.