Hooks not firing¶
A peer never registers, or stops appearing in list_peers after a session restart. Almost always a hook configuration problem.
Quick check¶
If a runtime is detected but its hooks are marked missing, run repowire setup again. Re-running is idempotent and will rewrite the hook entries.
repowire doctor also checks that the daemon, tmux, and git are available.
Re-run repowire setup to reinstall both runtime integrations and the
server-global tmux lifecycle hooks used for pane exits and renames.
Per-runtime diagnostics¶
Claude Code¶
- Open
~/.claude/settings.json. Thehookskey should contain entries forSessionStart,UserPromptSubmit,Notification,Stop,StopFailure, andSessionEnd, each pointing atrepowire hook .... - Confirm
repowireis onPATHfor the shell Claude Code was launched from. Hooks shell out, so a missingrepowireinPATHsilently no-ops. - Start Claude Code in a tmux pane. After your first prompt, run
repowire peer listin another shell. Peer should appear within a few seconds. - On Claude Code 2.1.224+,
/statusshould show aPeer addressandrepowire peer describe NAMEshould reporttransport: claude-inbox. If native delivery fails, Repowire logs the socket error under~/.cache/repowire/logs/ws-hook-*.logand returns a failed delivery receipt. There is no keystroke fallback.
If the hook reports pane_identity_mismatch after tmux has restarted, the pane
id may have been reused while an ownership record from an older tmux session
remained on disk. Repowire discards that stale bootstrap record automatically.
It still rejects path or placement mismatches within the same live tmux session,
because those records may authorize destructive pane operations.
Codex¶
Current Codex releases use App Server for registration, lifecycle, chat, and
delivery. They retain only a reminder-only Stop hook so unacknowledged asks
resurface after a turn. Check repowire service status,
~/.repowire/codex-bridge.log, and the Stop entry in
~/.codex/hooks.json. Older Codex releases without app-server --listen retain
the full hooks transport.
OpenCode¶
OpenCode does not use shell hooks. It uses a TypeScript plugin at ~/.config/opencode/plugins/repowire.ts. If the peer never appears:
- Confirm the plugin file exists and is non-empty.
- Check OpenCode's log for plugin load errors.
- Re-run
repowire setupto rewrite the plugin file.
Daemon must be running¶
All hooks shell out to the daemon over HTTP. If the daemon is down, hooks
succeed (they do not block agent startup) but no peer state changes. A later
Claude Code UserPromptSubmit repairs a missing pane registration with the
current session's authenticated inbox. It also replaces a connected ws-hook
whose Claude inbox socket belongs to an older process, rather than accepting a
status-only recovery that cannot deliver messages. A failed SessionStart is
never retained as an empty ws-hook identity. See Daemon unreachable.
After upgrading repowire¶
Hooks call the installed repowire binary. Native upgrades keep the ~/.local/bin/repowire symlink stable. If you install to a different location, re-run repowire setup so hook entries pick up the new path.