Passoff
Portable CLI for transferring coding-agent sessions between Claude Code and Codex when one agent hits a limit.
Requirements
- Node.js 20 or newer
- Local Claude Code and/or Codex transcript files on the same machine
Install
From npm:
npm install -g passoff
passoff --help
Or run without a global install:
npx passoff --help
From a local checkout:
npm install -g .
The npm postinstall step auto-installs the bundled passoff skill globally for both agents:
- Claude Code:
~/.claude/skills/passoff
- Codex:
~/.agents/skills/passoff
Retry or inspect the global skill install with:
passoff install-skills
passoff install-skills --dry-run
Set PASSOFF_SKIP_SKILL_INSTALL=1 to skip postinstall skill installation.
Links
Commands
passoff ls --from claude
passoff ls --from auto --repo /path/to/repo
passoff find "studio-tinkered-parity" --from claude
passoff inspect "studio-tinkered-parity" --from claude
passoff codex 2
passoff codex "studio-tinkered-parity" --from claude --no-launch
passoff claude codex:019dea31
passoff save --from auto --latest
passoff save --from claude --all
passoff install-skills
Common options:
--from claude|codex|auto: choose the source transcript store.
--repo PATH or -C PATH: match sessions for a specific repository.
--latest: select the newest matching session.
--json: print machine-readable output for ls, find, and inspect.
--no-launch: write transfer files without launching the target agent.
--dry-run: show the launch command without running it.
--scan-limit N: cap transcript files inspected per source agent.
Human Limit Playbook
When Claude Code hits a usage limit:
passoff ls --from claude
passoff codex 1
The command reads local Claude transcript files and repository state, writes .passoff/current.md, then launches Codex with a short resume prompt. It does not need Claude to answer another message.
When Codex hits a limit and Claude is available:
passoff ls --from codex
passoff claude 1
Selectors
passoff codex 2
passoff codex claude:7aaea880
passoff codex @checkout-bug
passoff codex "studio-tinkered-parity"
passoff codex --latest
If more than one session matches and no selector is provided, the tool lists sessions and exits instead of guessing.
Selectors can also be human-readable Claude resume names or custom titles. Claude Code transcript metadata such as custom-title, agent-name, teamName, slug, last-prompt, and away_summary is indexed automatically. When several sessions share the same title, the CLI ranks substantive sessions above short /clear or local-command stubs.
Search And Inspect
Use find when the user remembers a title or phrase but not the session id:
passoff find "studio-tinkered-parity" --from claude
passoff find "visual parity" --from auto --json
Use inspect before transfer when several close matches exist:
passoff inspect "studio-tinkered-parity" --from claude
passoff inspect claude:7aaea880 --from claude --json
inspect shows aliases, Claude metadata, cwd history, transcript path, score/stub status, recent messages, and recent tools.
Tags
passoff tag claude:7aaea880 checkout-bug
passoff codex @checkout-bug
Tags are stored in .passoff/tags.json in the current repository.
Output
Each transfer writes:
.passoff/current.md
.passoff/latest.json
.passoff/sessions/<agent>-<session>-<timestamp>.md
The transfer file includes source session metadata, aliases, cwd history, recent transcript messages, recent tool activity, git status, diff stat, a capped diff excerpt, and local plan/instruction files.
Performance And Privacy
- Scans newest transcript files first and caps discovery at 1500 files per source agent by default.
- Uses the first JSONL record to skip sessions from other repositories before reading transcript tails.
- Reads only the first line and a bounded tail of transcript files; it does not load full long-running chats.
- Redacts common token, key, password, and bearer-secret patterns before writing transfer markdown.
- Use
--scan-limit N if a very old session is outside the default scan window.
Local Development
npm test
npm run check:pack
npm run check:publish
npm install -g .
passoff ls --from claude
npm publish runs the test suite through prepublishOnly. Use npm run check:pack to inspect the tarball contents and npm run check:publish to verify npm publish metadata before publishing.