Agent Handoff is a local, quota-aware bridge between coding CLIs. Install it once, choose an ordered list of CLI/model routes, and keep working normally in Codex or Claude Code.
# From GitHub before an npm release
npx github:Nisarg38/agent-handoff init
# After publishing to npm
npx agent-handoff initThe installer:
- detects supported coding CLIs;
- asks for the preferred CLI + model order;
- installs lifecycle hooks and a shared handoff skill;
- configures usage thresholds and automatic return behavior;
- keeps all state and handoff packets on the local machine.
- Codex and Claude Code adapters
- Interactive route/model preference wizard
agent-handoff preferencesto update routes later- Configurable orchestration prompt automatically passed to every receiving CLI
- Exact Codex ChatGPT subscription-window checks through
codex app-server - Claude limit-error detection from hook/transcript context
- Optional custom Claude usage probe for exact subscription data
- Checks on session start, prompt submission, pre-tool use, stop, and pre-compaction
- Automatic safe-boundary handoff requests
- Automatic return to a higher-priority route when it becomes available
- Shared Markdown + JSON handoff packets
- Cross-platform target launcher, with a macOS Terminal implementation
- Non-destructive hook installation with backups
Codex exposes authenticated account rate limits through its local app-server. Claude Code does not currently expose an equivalent stable, documented local subscription-quota endpoint that this project can depend on.
For Claude, the default adapter therefore uses:
- observed rate/usage-limit errors;
- remembered reset times when present in those errors;
- an optional user-supplied JSON probe command.
This avoids presenting token-cost estimates as subscription quota. Configure a custom probe from agent-handoff preferences or edit ~/.agent-handoff/config.json:
{
"agents": {
"claude": {
"usage": {
"customCommand": "my-claude-usage-command --json"
}
}
}
}The command should print:
{
"available": true,
"remainingPercent": 63,
"resetAt": "2026-07-11T19:00:00-04:00",
"source": "custom"
}agent-handoff init
agent-handoff preferences
agent-handoff preferences show
agent-handoff orchestration
agent-handoff orchestration show
agent-handoff orchestration set "Your custom lead-agent prompt"
agent-handoff orchestration set --file ./orchestration-prompt.txt
agent-handoff orchestration reset
agent-handoff routes set codex:default claude:opus
agent-handoff status
agent-handoff usage
agent-handoff handoff --to claude:opus
agent-handoff handoff --to claude:opus --prompt "Use subagents for implementation"
agent-handoff handoff --to claude:opus --prompt-file ./one-off-prompt.txt
agent-handoff complete --summary-file .agent-handoff/HANDOFF.md
agent-handoff pause
agent-handoff resume
agent-handoff doctorAfter an npx install, the permanent local executable is also available at:
~/.agent-handoff/bin/agent-handoffAdd ~/.agent-handoff/bin to PATH to use the shorter command everywhere.
By default, every newly launched receiving CLI gets a lead-orchestrator instruction before the continuation prompt. The default asks the primary model to own the end-to-end outcome while delegating token-heavy implementation, repository exploration, and repetitive validation to lower-tier subagents when the CLI supports them.
Update it interactively:
agent-handoff orchestrationOr set it directly:
agent-handoff orchestration set "Act as the lead orchestrator..."
agent-handoff orchestration set --file ./my-orchestration-prompt.txt
agent-handoff orchestration disable
agent-handoff orchestration resetA manual handoff can override the configured prompt for that transfer only with --prompt or --prompt-file. The prompt is included in both the new CLI's initial prompt and its receiving SessionStart context.
A route is a CLI/model pair:
[
{ "agent": "codex", "model": "default" },
{ "agent": "claude", "model": "opus" },
{ "agent": "claude", "model": "sonnet" }
]At every configured hook boundary, Agent Handoff checks cached provider usage, refreshes it when needed, and selects the highest-priority route that is available.
A switch is requested when:
- the current route is at or below the handoff threshold;
- an explicit rate-limit error is observed;
- a higher-priority route has recovered and automatic return is enabled;
- the user manually requests a handoff.
The current agent receives instructions to finish its atomic operation, write .agent-handoff/HANDOFF.md, and run agent-handoff complete. The receiving CLI launches in the same working directory and gets the handoff packet through its SessionStart hook.
conservative: session start, user prompt, stopbalanced: conservative + pre-tool-use + pre-compactaggressive: balanced + post-tool-use + post-compact
The runtime always applies a usage cache, so an aggressive profile does not spawn a fresh usage probe for every tool invocation.
~/.agent-handoff/ shared runtime, config, state, packets
~/.claude/settings.json merged Claude hooks
~/.claude/skills/agent-handoff/ Claude skill
~/.codex/hooks.json merged Codex hooks
~/.codex/skills/agent-handoff/ Codex skill
Existing settings are preserved. Modified files receive timestamped backups.
npm test
npm run check
node src/cli.js init --non-interactiveUse an isolated home during development:
AGENT_HANDOFF_HOME=/tmp/agent-handoff-test \
HOME=/tmp/agent-handoff-user \
node src/cli.js init --non-interactiveThis is intentionally a local plugin/runtime—not a hosted orchestrator, task database, or agent platform. Git remains the implementation state, the handoff file carries reasoning state, and a small JSON state file coordinates routing.
This source tree is ready to publish. From the repository directory:
gh repo create Nisarg38/agent-handoff --public --source=. --remote=origin --pushUse --private instead of --public when desired.