Skip to main content

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.

Three interchangeable binaries

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:

  1. Ensures the project daemon is running (starting it if needed).
  2. Opens Claude Code in a new terminal via ctxrelay claude.
  3. Opens the Codex TUI in another terminal via ctxrelay codex.
  4. 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.

Pair refuses to double-launch

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:

KeyAction
tabCycle the three views: overview → controls → activity.
1 / 2 / 3Jump straight to the overview, controls, or activity view.
rRefresh the view.
pLaunch 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.
vOpen the browser Command Deck (viewer).
aToggle autonomy on/off.
iCycle idle-scanner mode: off → suggest → ask → act → off. Entering act requires a second press.
wCycle write mode (act:write worker dispatch). Requires autonomy on; entering act:write requires a second press and the hard env opt-in.
fToggle auto-finality.
cCycle the coordinator.
xToggle readonly permission mode.
tSwitch the hook token mode between verbose and compact.
uCycle the usage preset: off → lean → strict → off.
h / HShow or hide the in-TUI help screen (esc also closes it).
Ctrl+XOpen the agents/subagents focus view: live worker rows plus the local .claude/agents/*.md catalog, navigable with Up/Down.
qQuit the TUI.
The TUI quitting does not stop the agents

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.

"Daemon disconnected" is often not a crash

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 --all is 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 plain ctxrelay kill for that.)
  • detach-claude clears 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 with ctxrelay claude.
--all is global

ctxrelay 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