Skip to content

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.