Skip to content

Repository files navigation

OpenShunt

Give routine reading and generation to a smaller model. Keep the main agent focused.

OpenShunt is a plugin for Claude Code and Codex. It redirects large file reads to a configurable worker and brings back a focused answer. For predictable new files, the worker generates from a reference and returns a file receipt instead of filling the main conversation with code.

Inspired by Spotify's Shunt. Independent, MIT licensed, and currently preview.

Host Default worker Execution
Claude Code Haiku Native subagent
Codex gpt-5.6-luna Native subagent
Either host Your selected Claude or Codex model Optional external CLI worker

Native delegation uses the host's own subagents. No extra CLI session, application server, API-key store, or MCP server is required. Inference uses your existing account and usage allowance. Each mode can use a different model.

Install

Requires Node.js 22+, macOS or Linux, and an authenticated host with access to the selected model. Install the published repository from GitHub:

Claude Code

claude plugin marketplace add teenaxta/openshunt
claude plugin install openshunt@openshunt

Restart Claude, then try /openshunt:bulk-reader. To try the plugin without installing it, run claude --plugin-dir ./plugins/openshunt instead.

Codex

codex plugin marketplace add teenaxta/openshunt
codex plugin add openshunt@openshunt
openshunt setup --host codex --transport native

Restart Codex and review the hooks in /hooks or the app's hook settings. Installation alone does not trust hooks. Setup installs the two native roles into $CODEX_HOME/agents (normally ~/.codex/agents).

For local development from a checkout, use claude plugin marketplace add . or codex plugin marketplace add . from the repository root. Both marketplace catalogs are included. No npm publication is needed.

Try it

Ask your agent:

Use OpenShunt to find which functions in src/service.ts access the database. Return their names and a short explanation.

Use OpenShunt to generate tests/new-handler.test.ts, following tests/existing-handler.test.ts as the reference.

Show my OpenShunt savings.

Claude exposes these plugin commands. In Codex, select the corresponding OpenShunt skill or ask for it by name; the exact picker syntax depends on the host.

Claude command What it does
/openshunt:bulk-reader Answer a bounded question from explicitly selected files
/openshunt:code-writer Generate a complete new file from a reference
/openshunt:setup Choose models and configure native or CLI execution
/openshunt:savings Show recorded routing activity and context estimates

A full text read above 350 lines triggers the routing guard. Targeted reads remain available. Debugging, architecture, safety-critical decisions and existing-code edits stay with the main agent. Treat worker summaries as navigation aids; inspect targeted source before editing.

See what was routed

Run /openshunt:savings in Claude, use the OpenShunt savings skill in Codex, or run:

node ./plugins/openshunt/scripts/openshunt.mjs savings
node ./plugins/openshunt/scripts/openshunt.mjs savings --json

The report covers local history across projects:

Metric What it tells you
Blocked full-read attempts How often the guard redirected a large read
Native delegation attempts Calls to an OpenShunt role that passed its hook checks; completion is unverified
Completed CLI calls External workers that returned a successful result
Per-model breakdown Configured worker model and mode for recorded delegations
Estimated parent context excluded Approximate CLI-only reduction using source/generated bytes minus the returned result, divided by four
Reported worker usage CLI-reported token/cache fields, kept separate by provider and model
Money saved / net token savings Not measured

Blocked reads and native attempts are separate observations—do not add them into a total of completed routed calls. A later permission check, failure or cancellation can stop a native attempt. Model names do not establish that a worker was cheaper than its parent.

The context estimate excludes model, skill and tool overhead. It is not a billing calculation or a guaranteed reduction in total tokens. Old prompt-based estimates are shown separately. Native usage and completion are not reliably available to OpenShunt, so native savings stay unavailable rather than being guessed. There is no 90% savings guarantee.

Tracking starts when this version is installed; earlier native activity cannot be reconstructed. Metadata is stored locally in $XDG_STATE_HOME/openshunt (normally ~/.local/state/openshunt): routing.jsonl for hook observations and usage.jsonl for completed CLI calls. No source text, prompts or file paths are recorded. Set OPENSHUNT_TRACKING=0 to stop recording without disabling routing. Deleting these two files resets recorded history. The older stats command remains available for raw CLI statistics.

Choose your models

The examples below use the openshunt command. From a checkout, optionally install it with npm install --global ./plugins/openshunt first.

# Set each host's native worker model.
openshunt setup --host claude --model haiku --transport native
openshunt setup --host codex --model gpt-5.6-luna --transport native

# Change only one mode, and keep configuration local to this project.
openshunt setup --host codex --mode bulk-reader --model gpt-5.6-luna --scope project

# Inspect configuration without making a model request.
openshunt doctor --host codex

Restart Codex after changing a role's model. Claude's Agent call passes the configured model. OpenShunt never silently falls back to a different model. Native model/transport changes must be saved through setup or supplied through environment/project config so the independent hook and role use the same selection.

User settings live in ~/.config/openshunt/config.json (or $XDG_CONFIG_HOME/openshunt/config.json). Project settings live in .openshunt.json. Precedence is flags → environment → project → user → defaults. Within each config file: shared settings → mode → host → host mode.

Configuration example and environment variables
{
  "minLines": 350,
  "hosts": {
    "claude": {
      "modes": {
        "bulk-reader": {"transport": "native", "model": "haiku"},
        "code-writer": {"transport": "native", "model": "haiku"}
      }
    },
    "codex": {
      "model": "gpt-5.6-luna",
      "transport": "native"
    }
  }
}

Environment keys include OPENSHUNT_MIN_LINES, OPENSHUNT_MODEL, OPENSHUNT_WORKER, OPENSHUNT_TRANSPORT, OPENSHUNT_TIMEOUT_MS and OPENSHUNT_MAX_INPUT_BYTES. More specific model keys override general ones: OPENSHUNT_BULK_READER_MODEL, then OPENSHUNT_CODEX_MODEL, then OPENSHUNT_CODEX_BULK_READER_MODEL. Other settings use the same prefixes.

OPENSHUNT_ENABLED=0 explicitly bypasses routing. OPENSHUNT_TRACKING=0 disables metadata recording only. Executable overrides (OPENSHUNT_EXECUTABLE or --executable) belong in user settings, environment or flags, never project config. Config discovery walks upward to the first project config or Git boundary.

Native agents or external CLI workers?

Use native agents for work within the same host. Select CLI transport explicitly for cross-host work or isolated one-shot execution:

openshunt setup --host claude --transport cli --worker codex --model gpt-5.6-luna
openshunt doctor --host claude --live

doctor --live in CLI mode consumes account usage. Native live checks run through the parent's Agent/spawn_agent tool; doctor does not start a CLI on their behalf.

Behavior Native External CLI
Input Task and file paths; child reads files Escaped file contents over stdin
Parent history Fresh child context No parent transcript
Host/project instructions Inherited Isolated temporary directory
Timeout, cancellation and retention Host managed Configurable timeout; ephemeral/nonpersistent worker
Default input limit 1 MiB of selected files before dispatch 1 MiB after encoding
Usage report Attempts only Completed calls, reported usage and context estimate

The native bulk-read --host HOST and code-write --host HOST CLI commands return task envelopes, not model answers. The skill invokes the named child afterward. In CLI transport those commands execute the worker directly. CLI code-write may omit a target to print code; native generation requires a target.

Boundaries and current status

  • Read routing: Claude Read and both hosts' Bash events are supported. The shell guard recognizes simple cat, head, tail, less and more, including quoted paths. Pipes, redirections, flags and unfamiliar syntax pass through. This is a routing aid, not exhaustive enforcement.
  • Generated files: the worker uses a staging file and atomic publication. Existing targets require --overwrite; the target directory must exist. Empty output and incomplete fences are rejected, but semantic completeness still requires validation.
  • Failures: worker errors leave the guard active. Use targeted reads or split the batch. Malformed hook/config input fails open with a diagnostic; hooks never grant host permissions.
  • Claude native: live parent routing, identified child reads and generation passed.
  • Codex native: parent routing and generation worked in a workspace-write parent. Child hook events were not observed in the test recorder, so child model/exemption/recursion checks are not proven enforced on that path. Named custom-agent roles are required; desktop variants without them are unverified.
  • Codex external workers: the tested macOS workspace-write parent can prevent a second Codex CLI from initializing. Native delegation avoids that extra process. Do not weaken the sandbox to match a benchmark.

Tested with Claude Code 2.1.266 and Codex 0.144.5. Native Windows and hosted/cloud parents are deferred. Normal marketplace discovery and interactive hook-trust flows still need installation acceptance. Credentials remain managed by the host/CLI; OpenShunt does not copy them or send telemetry.

Development and evidence

npm test
npm run check

See validation results, native measurements, and acceptance instructions. Opt-in live tests and benchmarks consume account usage. The macOS/Linux CI matrix is configured; local checks are not proof it has run remotely.

OpenShunt adapts Dimitri Mazmanov's Shunt implementation to native agents and authenticated CLIs. It is not an official Spotify, Anthropic or OpenAI product. MIT license.

About

OpenShunt routes large file reads and boilerplate generation to smaller Claude or Codex subagents, reducing parent context usage while preserving focused coding workflows.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages