npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@proofofwork-agency/contextrelay

v3.13.4

Published

ContextRelay: local multi-agent coding orchestration for Claude Code and Codex

Downloads

226

Readme

ContextRelay

npm version npm downloads CI License Docs

Put Anthropic's Claude Code and OpenAI's Codex in one working session — so they can disagree, and you can audit it.

Asking one agent to review another's work gets you an opinion. ContextRelay gets you an argument: a handoff with a concrete ask, a peer that pushes back with evidence, a correction that joins the work already in progress, and a durable record of how the two of them got there.

Both agents keep their own UI, their own model, and their own vendor. ContextRelay is the local control plane between them — live messaging, structured handoffs, bounded deliberation, and an append-only shared ledger. Nothing leaves your machine.

ContextRelay running Claude Code and Codex as one pair, with a live shared ledger

Local-only. Loopback. Append-only. No cloud, no extra accounts.

Quick Start

# 1. Install the agents + ContextRelay
npm install -g @anthropic-ai/claude-code @openai/codex @proofofwork-agency/contextrelay

# 2. Set up the project
ctxrelay init --instructions project
ctxrelay codex-mcp install

# 3. Launch the pair
ctxrelay pair

Then inside Claude or Codex:

/contextrelay:handoff review the auth changes
/contextrelay:deliberate is this design sound?

See the full install guide or run ctxrelay doctor.

What You Actually Get

| What | Why it matters | |------|----------------| | Two vendors, one session | Claude Code and Codex keep their own UIs and models. ContextRelay wires them together with one daemon, ledger, coordinator, and task board — peer to peer, in both directions, not one agent calling the other as a tool. | | Guidance that joins live work | on_busy: queue \| steer \| reject on every send. Steering enters the receiver's active turn without interrupting or restarting it; queued work waits durably for their next turn. Ambiguous delivery is reported, never silently duplicated. | | Rate-limit recovery on both sides | When either agent's usage window is exhausted, work ContextRelay delivered is captured and re-sent after the estimated reset. Defaults to notify; see Rate-Limit Recovery for what resume does and does not cover. | | Durable shared ledger | Every message, handoff, note, artifact, test report, release gate, and headless result is append-only JSONL in .contextrelay/. Crash? Inspect and resume later. | | Structured handoffs & deliberation | /contextrelay:handoff or handoff_to_claude passes a concrete ask + files + reason. /contextrelay:deliberate records a short debate before big decisions. | | Headless reviewers on demand | ctxrelay headless run --target codex (or via the contained_run tool) spins up a fresh-context read-only worker. Supports codex, claude, and opencode (on macOS). | | Idle nudges | With autonomy on, the daemon can politely ask the idle agent to pull the next task from the busy coordinator. | | Native TUI + viewer | Full terminal dashboard for status, controls, and activity. Browser "Command Deck" for read-only inspection. | | Git writes stay with the coordinator | Only the designated coordinator (Claude, Codex, or human) is allowed to commit, push, etc. Everyone else is read-only by default. | | Gated writes & release evidence | act:write is off by default and runs in a contained worktree. release-gate records proof before you ship. | | Named sessions & worktrees | Spin up side sessions bound to separate worktrees for parallel review or experiments. |

Daily Workflow

ctxrelay pair              # launch Claude + Codex around this project
ctxrelay viewer            # open the read-only browser command deck
ctxrelay ledger list       # inspect the shared ledger
ctxrelay headless run --target codex --prompt "Review this diff for release blockers"
ctxrelay release-gate      # record release evidence
ctxrelay kill              # stop this project daemon

Inside Claude Code:

/contextrelay:handoff review the risky part of this change
/contextrelay:deliberate should this be a protocol change or display-only?
/contextrelay:finalize

From Codex, use the MCP tools after ctxrelay codex-mcp install: handoff_to_claude, deliberate_with_claude, contained_run, read_context, record_artifact, propose_final, and the rest of the ContextRelay tool surface.

The everyday loop is simple: one agent does the work, the other reviews or challenges it, and ContextRelay keeps the useful context written down.

Headless Reviews

Headless jobs are one-shot reviewers. They do not join the live pair; they inspect context and return one result.

ctxrelay headless run \
  --target codex \
  --prompt "Review the current diff for release blockers. Findings first."

From MCP, call contained_run:

{
  "agent": "claude",
  "prompt": "Review src/backup/runner.ts and tests for regressions.",
  "context_refs": ["git diff", "src/backup/runner.ts"]
}

Renamed: this tool was called headless_run. It collided with Headless, a separate product that ships an MCP tool of the same name — an agent told to "use headless" would reach for the wrong one. The old name is still accepted for one version and still works in CONTEXTRELAY_MCP_TOOLS allowlists, but it is no longer advertised. ContextRelay's feature is still called headless workers; only the tool identifier changed.

Registered contained adapters are exposed automatically. Built-ins today:

  • codex: codex exec --sandbox read-only
  • claude: claude -p with read-only tools
  • opencode: opencode run --pure inside the Darwin read-only sandbox when the binary and sandbox probe are available

The opencode adapter is optional. If you want to use --target opencode, install and authenticate the opencode CLI first and make sure opencode is on PATH for the daemon or CLI process. ContextRelay registers the adapter automatically only on macOS/Darwin when opencode is present and the sandbox-exec write-denial probe passes. To hide just this adapter, start ContextRelay with CONTEXTRELAY_OPENCODE_ENABLED=0; to disable every headless worker, use CONTEXTRELAY_HEADLESS_ENABLED=0.

opencode gets an extra grounding preamble because it runs in minimal --pure mode. It is told exactly which read-only tools exist and not to claim edits, tests, or shell commands it cannot perform. Codex and Claude are left to their native headless runtimes.

Adapters are source-level extension points, not external runtime plugins. To add another terminal-coder target, open a PR that implements HeadlessAdapter in src/backup, registers it in the in-process adapter registry, and includes containment proof, env allowlist, output parsing, tests, and docs. After review and release, users get the adapter through the normal npm package update.

Pair Work

A Claude-to-Codex review handoff recorded in the ContextRelay ledger

Claude -> /contextrelay:handoff
  reason: finished the token refresh change; want a second opinion before merge
  ask:    review src/auth/refresh.ts for races and token leak paths
  files:  src/auth/refresh.ts, src/auth/refresh.test.ts

Codex -> reply
  Two issues: refresh is not single-flight, and the old token remains in memory
  after rotation. Tests pass, but neither path is covered.

Claude -> append_note
  decision: add the single-flight lock, zero the old token, add both tests.

Guide Work While It Is Running

Either coordinator can send guidance without stopping or restarting the other agent. The Claude tools reply, handoff, and deliberate_with_codex, and the Codex tools send_to_claude, handoff_to_claude, and deliberate_with_claude, accept the same on_busy policy:

| Policy | Use it when | If the receiver is busy | | --- | --- | --- | | queue (default) | The message can wait. | Save it for the receiver's next turn. | | steer | The guidance is relevant to work happening now. | Join the active work through the live channel. | | reject | Delivery is useful only if the receiver is idle. | Fail without injecting the message. |

For example, a coordinator can ask its agent to make a tool call shaped like:

reply({ text: "Keep the current API; only fix the retry loop.", on_busy: "steer" })
send_to_claude({ text: "Tests are green; review when free.", on_busy: "queue" })

Tool receipts say what actually happened: joined_active_work, started_new_turn, delivered_live, or queued_for_next_turn. A timeout or disconnect after a live send is treated as ambiguous, so ContextRelay never automatically sends a second copy. The coordinator may steer freely when the message matters now; a worker should steer only for an urgent blocker or a correction relevant to the coordinator's current work.

See the tool reference for receipt details and the operator smoke test for a short end-to-end check.

Rate-Limit Recovery

rateLimitResume.mode now defaults to notify (changed from off). Cycle it with l in the TUI:

| Mode | Behavior | | --- | --- | | off | Do not capture rate-limit failures or schedule a reset notice. | | notify (default) | Detect the exhausted window, estimate its reset, and announce when it should be usable again. Nothing is re-sent automatically. | | resume | Do the same detection and, when ContextRelay owns the rejected body, re-send that captured work after the estimated reset. |

On Codex, ContextRelay receives the rejected injected input directly. On Claude, the bundled plugin's StopFailure hook reports rate_limit and billing_error turn failures. Claude resume means “re-send work ContextRelay delivered.” It does not reconstruct or replay a prompt the human typed in Claude Code: ContextRelay never owned that text, so replaying it would require transcript scraping and could duplicate private or already-handled work. A human-typed Claude failure therefore remains notify-only even when the mode is resume.

Claude-side detection requires the current plugin bundle. Run ctxrelay upgrade and then /reload-plugins (or restart Claude Code) after upgrading. If plugin refresh is skipped with --no-plugin, the Codex path still works but Claude-side detection does not. OpenTelemetry's claude_code.api_error event is a possible fallback route, but it is explicitly not built: the hook needs neither a loopback collector nor a prompt/tool-detail logging surface.

Idle Ask-For-Work

When global autonomy is on, ContextRelay can keep the non-coordinator from silently sitting idle.

If Codex is coordinator and currently busy while Claude is idle, the daemon nudges Claude:

[IMPORTANT] ASK_FOR_WORK: You appear idle while the coordinator is actively working.
Ask Codex for the next concrete task now, and include either what you just finished or that you are ready for work.

If Claude is coordinator and Codex is idle, the same mechanism injects the nudge into Codex. The feature is automatic, cooldown-limited, and records an idle_ask_for_work artifact in the ledger. It is not a public MCP tool; it is daemon behavior controlled by config.

Enable the autonomy master switch:

ctxrelay autonomy on

Disable just this nudge in .contextrelay/config.json:

{
  "autonomy": {
    "idleScanner": {
      "askForWork": {
        "enabled": false
      }
    }
  }
}

Control Deck

The native TUI opens with contextrelay or ctxrelay tui [--no-start] [--force].

Safety Model

ContextRelay assumes one trusted operator on one workstation.

  • The daemon binds to 127.0.0.1.
  • The viewer cannot dispatch agent work; it can clear current-session history through its authenticated local maintenance endpoint.
  • Git writes are policy-routed through one coordinator or the human.
  • Autonomy is off by default.
  • contained_run is read-only and only accepts registered contained adapters.
  • act:write is default-off and only runs in an ephemeral git worktree behind dual-idle, budget, single-flight, and containment gates.
  • The plugin's hooks reach the daemon over loopback only, authenticated with the local control token, size-bounded, and rejected outright for browser-origin requests. Hook payloads are parsed for a reset estimate and then discarded — they are never persisted, logged, or forwarded to the other agent.
  • Provider CLIs still use their own auth and approval systems.

Read docs/THREAT_MODEL.md before relying on any stronger boundary.

Common Commands

contextrelay                  # open the native ContextRelay TUI
ctxrelay init --instructions project
ctxrelay codex-mcp install|remove|status|server
ctxrelay pair [--dry-run] [--no-tui] [--port-base <port>] [--session <id>]
ctxrelay status [--json]
ctxrelay viewer [--no-open]
ctxrelay release-gate [--json] [--smoke]
ctxrelay headless run --target <codex|claude|opencode> (--prompt <text>|--prompt-file <path>) [--timeout <ms>] [--label <name>] [--json]
ctxrelay kill [--all|--session <id>]

The full command, MCP, environment, metrics, and artifact reference lives in docs/REFERENCE.md. Day-to-day recovery lives in docs/RUNBOOK.md.

Documentation

The compact CLI reference is at the end of this file for sync purposes.

Develop

git clone https://github.com/proofofwork-agency/contextrelay.git
cd contextrelay
bun install
bun run build:cli
bun run build:plugin
bun link
bun link @proofofwork-agency/contextrelay
ctxrelay init --instructions project
ctxrelay codex-mcp install
ctxrelay pair

Run the local gate:

bun run check

Run package evidence before publishing:

ctxrelay release-gate --json

License

MIT. See LICENSE. ContextRelay preserves the original AgentBridge MIT copyright notice and adds the ProofOfWork / Danillo Felixdaal copyright notice for this fork's changes.

This section keeps the README synchronized with the public CLI and tool surface. Most readers should use docs/REFERENCE.md instead.

CLI aliases: contextrelay, context-relay, ctxrelay.

contextrelay
ctxrelay tui [--no-start] [--force]
ctxrelay init [--instructions project|global|both|skip]
ctxrelay upgrade [--dry-run] [--no-plugin] [--instructions refresh|project|global|both|skip]
ctxrelay dev
ctxrelay claude [--session <id>] [args...]
ctxrelay codex [--session <id>] [args...]
ctxrelay codex-mcp install|remove|status|server
ctxrelay pair [--dry-run] [--no-tui] [--port-base <port>] [--session <id>]
ctxrelay doctor [--no-auth]
ctxrelay instructions status|install|remove [--scope project|global|both]
ctxrelay coordinator [status|claude|codex|human] [--scope project|global|both]
ctxrelay permissions status|readonly on|off|allow <capability>|deny <capability>|reset [--agent <agentId>]
ctxrelay detach-claude
ctxrelay status [--json]
ctxrelay session list|create|select|archive|rebind [...]
ctxrelay recover [--json]
ctxrelay instances
ctxrelay viewer [--no-open]
ctxrelay autonomy on|off|status
ctxrelay idle-scanner off|suggest|ask|act|status [--why]|check
ctxrelay idle-budget status|reset
ctxrelay idle-eval status|compare
ctxrelay act on|off|status [--budget <usd>]
ctxrelay finalize auto|manual|status
ctxrelay usage status|off|lean|strict
ctxrelay usage hook status|verbose|compact|count|set
ctxrelay usage context off|lean|strict|status
ctxrelay usage ledger compact [--dry-run|--apply] [--session <id>] [--recent <count>] [--preview-chars <count>]
ctxrelay usage ledger clear [--dry-run|--apply] [--session <id>]
ctxrelay hook-compaction status|verbose|compact|count|set
ctxrelay usage-control off|lean|strict|status
ctxrelay ledger list|show|compact|clear [...]
ctxrelay queue list|show|remove|drain [...]
ctxrelay messages status|drain [...]
ctxrelay release-gate [--json] [--smoke]
ctxrelay headless run --target <codex|claude|opencode> (--prompt <text>|--prompt-file <path>) [--timeout <ms>] [--label <name>] [--json]
ctxrelay kill [--all|--session <id>]
ctxrelay standalone on|off|status [--scope project|global|both] [--path <file>]
ctxrelay attach [session-name]
ctxrelay detach
ctxrelay gate-check [--status|--json|--why]

Claude MCP tools:

reply
get_messages
wait_for_messages
handoff
deliberate_with_codex
append_note
read_context
session_info
create_session
select_session
archive_session
rebind_session
task_state
record_artifact
ask_codex_backup
backup_status
contained_run
propose_final

Codex MCP tools:

send_to_claude
handoff_to_claude
deliberate_with_claude
read_context
wait_for_claude
append_note
session_info
create_session
select_session
archive_session
rebind_session
task_state
record_artifact
ask_claude_backup
backup_status
contained_run
propose_final

Claude slash commands:

/contextrelay:init
/contextrelay:status
/contextrelay:handoff
/contextrelay:review
/contextrelay:deliberate
/contextrelay:finalize
/contextrelay:on
/contextrelay:off

Artifact kinds: patch_summary, release_gate, test_report, command_log, escalation_suggestion, idle_opportunity, idle_ask_for_work, idle_action_result, idle_fleet_result, idle_evaluation_result, idle_write_result, headless_result.

Artifact statuses: passed, failed, blocked, unknown, skipped, timed_out.

Core env vars: CONTEXTRELAY_STATE_DIR, CONTEXTRELAY_CONTROL_PORT, CODEX_WS_PORT, CODEX_PROXY_PORT, CONTEXTRELAY_PORT_BASE, CONTEXTRELAY_PROJECT_ROOT, CONTEXTRELAY_INSTANCE_ID, CONTEXTRELAY_AUTO_CONNECT, CONTEXTRELAY_MODE, CONTEXTRELAY_MCP_TOOLS, CONTEXTRELAY_ALLOW_NAMED_SESSIONS, CONTEXTRELAY_MAX_BUFFERED_MESSAGES, CONTEXTRELAY_IDLE_SCANNER, CONTEXTRELAY_HEADLESS_ENABLED, CONTEXTRELAY_OPENCODE_ENABLED.

Claude Code host env vars read by bundled hooks: CLAUDE_PLUGIN_ROOT, CLAUDE_PROJECT_DIR.