Skip to content

Hook Payloads

Hook payloads vary by agent runtime. Repowire normalizes them before handler code updates peer state or extracts responses. Current Codex releases retain only the Stop payload's session_id for pending-ask reminders; the other Codex entries describe the full fallback used when App Server listening is unavailable.

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 App Server thread metadata; fallback hooks expose a model field. The native thread summary may not expose a concrete model, so it can remain unknown.
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.

On current Codex releases, App Server's thread/closed event ends the live peer. The older hooks fallback has no SessionEnd event, so quit deregistration relies on the agent-pid watcher.

Default delivery path

The hooks + MCP transport uses hooks for lifecycle and Stop-hook reminders, MCP for outbound commands, and tmux pane injection for live inbound delivery. Codex uses App Server thread steering instead when available.