Daily operation: launch, inspect, stop
Once ContextRelay is installed, almost everything you do day to day comes down to three moves: launch the pair, inspect what the agents are doing, and stop cleanly when you are done. This page is the code-first driver for all three.
The mental model is simple. ContextRelay runs a small loopback-only daemon per project. The daemon owns the shared ledger, routes messages between Claude Code and Codex, and enforces policy. You launch agents that connect to it, you watch the daemon through a TUI or browser viewer, and you stop the daemon (and its managed Codex runtime) when the session ends. Everything is local; nothing leaves your machine.
contextrelay, ctxrelay, and context-relay are the same CLI from the @proofofwork-agency/contextrelay package. This page uses ctxrelay for brevity. Use whichever you prefer.
Launch the pair
The fastest way to start a working session is to launch both agents at once:
ctxrelay pair
ctxrelay pair does four things:
- Ensures the project daemon is running (starting it if needed).
- Opens Claude Code in a new terminal via
ctxrelay claude. - Opens the Codex TUI in another terminal via
ctxrelay codex. - Opens the native control TUI in the foreground so you can monitor the session.
Preview before you launch
Pass --dry-run to see exactly what pair would run - the resolved instance, ports, and the three launch commands - without starting anything:
ctxrelay pair --dry-run
This is the safest way to understand what ContextRelay will spawn, especially the first few times.
Useful pair flags
ctxrelay pair --no-tui # launch both agents, skip the foreground TUI
ctxrelay pair --port-base 4510 # run a second, independent pair in the same repo
ctxrelay pair --session review # launch a named runtime pair inside the daemon
--port-base is how you run two independent pairs against the same repository - each pair gets its own daemon and port group. --session <id> launches a named runtime session, useful when you want a separate lane (for example, a review pair) alongside your default work.
If a pair is already active, pair will not start a second copy of the default pair - it tells you so and points you at the next option (press p again in the TUI for a named pair, or use --port-base for a fully separate instance). This is intentional: it keeps you from accidentally spawning duplicate daemons or agents.
Start agents individually
You do not have to use pair. You can start each side on its own - handy when you only need one agent, want to resume a session, or are wiring up the two agents in separate panes yourself:
ctxrelay claude # start Claude Code with the ContextRelay plugin channel
ctxrelay codex # start the Codex TUI connected to the daemon
Extra arguments after the subcommand pass straight through to the underlying binary:
ctxrelay claude --resume # resume a previous Claude Code session
ctxrelay codex --model o3 # start Codex with a specific model
Both accept --session <id> to join (or create) a named runtime pair.
Inspect the running session
The native TUI
Run the bare command (no subcommand) to open the native terminal dashboard:
contextrelay
This is equivalent to ctxrelay tui. The TUI is your live control deck. It shows the ContextRelay version, bridge readiness, daemon pid, instance id, port group, ledger count, queue depth, same-project peer count, runtime sessions, agent states, the configured coordinator, autonomy, scanner mode, finality mode, readonly policy, hook token mode, usage preset, handoff status, and recent high-signal activity.
Two flags adjust startup behavior:
ctxrelay tui --no-start # render status without starting the daemon
ctxrelay tui --force # render even when stdin is not an interactive TTY
TUI hotkeys
The TUI has three tabbed views - overview, controls, and activity - that you cycle with tab (or jump to one with 1 / 2 / 3). It is not just a viewer: most policy controls are one keystroke away:
| Key | Action |
|---|---|
tab | Cycle the three views: overview → controls → activity. |
1 / 2 / 3 | Jump straight to the overview, controls, or activity view. |
r | Refresh the view. |
p | Launch the Claude + Codex pair. If the default pair is already active, the first press shows a named-pair prompt and a second fresh press launches the named runtime pair. |
v | Open the browser Command Deck (viewer). |
a | Toggle autonomy on/off. |
i | Cycle idle-scanner mode: off → suggest → ask → act → off. Entering act requires a second press. |
w | Cycle write mode (act:write worker dispatch). Requires autonomy on; entering act:write requires a second press and the hard env opt-in. |
f | Toggle auto-finality. |
c | Cycle the coordinator. |
x | Toggle readonly permission mode. |
t | Switch the hook token mode between verbose and compact. |
u | Cycle the usage preset: off → lean → strict → off. |
h / H | Show or hide the in-TUI help screen (esc also closes it). |
Ctrl+X | Open the agents/subagents focus view: live worker rows plus the local .claude/agents/*.md catalog, navigable with Up/Down. |
q | Quit the TUI. |
Pressing q closes the dashboard only. The daemon, Claude, and Codex keep running. To actually stop the session, use ctxrelay kill (see Stop cleanly).
The browser Command Deck
For a richer, read-only view - task lanes, artifacts, the policy surface, and a timeline - open the browser viewer:
ctxrelay viewer
The viewer is read-only: it is for inspecting and reviewing what the agents have recorded, not for driving them. Add --no-open to print the URL instead of launching a browser (useful over SSH or in headless setups):
ctxrelay viewer --no-open
You can also open it from the TUI by pressing v.
Quick status checks
When you just need facts - not a live dashboard - these one-shot commands print and exit:
ctxrelay status # daemon, session, connection, ledger, and policy state
ctxrelay status --json # the same, machine-readable
ctxrelay instances # every known project instance and its assigned ports
ctxrelay doctor # diagnose binaries, auth, state, plugin, and daemon health
ctxrelay status is your first stop for "is the daemon up, who is connected, how deep is the queue." ctxrelay instances is the map of every project's daemon and port group on this machine. ctxrelay doctor is the deeper health check; pass --no-auth to skip the Claude/Codex auth probes when you only care about local state.
If an agent reports the daemon disconnected, check ctxrelay status before restarting anything. A long turn can trip a turn watchdog and reset the connection even though the daemon itself is healthy - a restart you did not need can lose in-flight context. Inspect first; restart only if status/doctor actually show the daemon down.
Ports at a glance
The default first port group is:
4500 Codex app-server
4501 ContextRelay Codex proxy
4502 ContextRelay daemon control
Additional projects increment by 10 (so the next project's group is 4510 / 4511 / 4512, and so on). ctxrelay instances shows you which project owns which group, which is handy when a port looks busy.
Stop cleanly
When you finish a session, stop the daemon and its managed Codex runtime so nothing lingers in the background:
ctxrelay kill
This stops only the resolved instance for the current project - sibling instances in other projects are left untouched. After it runs, restart Claude Code, switch to a new conversation, or run /resume to fully disconnect the Claude side.
Targeted and emergency stops
ctxrelay kill --all # emergency: stop every known instance across all projects
ctxrelay kill --session review # stop one named session's Codex runtime only
ctxrelay detach-claude # clear a stale Claude attachment, leave Codex + daemon up
kill --allis the big red button. It walks the local registry and stops every ContextRelay daemon and managed Codex TUI on the machine. Reach for this when things are tangled across multiple projects.kill --session <id>stops just that named session's Codex runtime and managed TUI; the daemon, the Claude connection, and other sessions keep running. (The default session cannot be killed this way - use plainctxrelay killfor that.)detach-claudeclears the active Claude foreground attachment without killing Codex or the daemon. Use it when Claude shows as connected but the real session is gone, and you want to reconnect withctxrelay claude.
--all is globalctxrelay kill --all stops ContextRelay for every project on this machine, not just the one you are in. If you only want to stop the current project, use plain ctxrelay kill.
A typical day, end to end
ctxrelay pair # launch Claude + Codex, opens the control TUI
# ... work: hand off tasks, deliberate, review (see the tutorials below) ...
ctxrelay status # sanity check from another shell at any point
ctxrelay viewer # open the read-only Command Deck to review artifacts
ctxrelay kill # stop the project daemon + managed Codex when done
That loop - pair, inspect with the TUI / status / viewer, then kill - is the whole rhythm of daily operation. Everything else (handoffs, deliberation, policy, autonomy) layers on top of these three moves.
Next steps
- Tutorial: your first paired session - a guided walk-through of a real session.
- Configure collaboration policy - set the coordinator, git-write policy, and permissions.
- Troubleshooting and recovery - what to do when the daemon, ports, or a connection misbehave.
- CLI command reference - every command and flag in one place.