CROSSBY — Cross-platform Bridge for Your AI agents
Project description
crossby
One config. Every AI tool.
Stop re-writing your rules, permissions, and agents for every CLI. crossby syncs them across Claude, Copilot, Gemini, Codex, Cursor, OpenCode, VS Code, and Antigravity — and lets you hand off a live session from one tool to another without losing context.
$ crossby sync --from codex
✓ rules AGENTS.md → CLAUDE.md, GEMINI.md, .cursorrules, +1 more
✓ agents .agents/ → .claude/agents/, .cursor/agents/, +2 more
✓ skills .agents/skills/ → .claude/skills/, .cursor/skills/, +2 more
✓ permissions → translated for Claude, Cursor, Gemini
✓ hooks → written for Claude, Cursor, Copilot, Gemini
✓ mcp servers → merged into Claude, Cursor, Codex, Copilot, Gemini
Already on Claude? crossby sync --from claude works the same way — any tool can be the source.
Why crossby?
- Every new tool inherits your setup. Install a new AI CLI tomorrow and one
crossby syncgives it your rules, agents, permissions, hooks, and MCP servers — translated into whatever format that tool expects. - Pick any tool as your source.
AGENTS.md,CLAUDE.md,GEMINI.md,.cursorrules, Copilot instructions — whatever you already write in becomes canonical. No migration, no lock-in. - One set of launch flags for every tool.
--model,--effort,--yolo,--plan,--resume— crossby handles the per-tool translation. Unsupported flags raise errors instead of silently disappearing. - Cross-tool session handoff. Mid-session in one CLI and want to continue in another?
crossby handoffsummarizes the transcript and hands it off — so you never re-explain what you're doing. - Stateless by default. Works without a config file:
crossby syncreads directly from each tool's standard paths. Drop in a.crossby.ymlonly when you want saved profiles or defaults.
Install
pip install crossby
# or
uv tool install crossby
# or
pipx install crossby
Requires Python 3.11+.
Quick start
# Don't know where to start? Run crossby with no args for an interactive menu.
crossby
# Scaffold a .crossby.yml with your defaults (launch, sync, handoff).
crossby init
# Sync your setup to every installed tool (replace codex with claude, cursor, gemini, copilot…)
crossby sync --from codex
# Or launch the interactive wizard
crossby sync
# Launch a saved profile (e.g. Claude + Sonnet + high effort + YOLO — see below)
crossby launch ccyolo
# …or spell it out with unified flags
crossby launch --tool claude --model claude-sonnet-4.6 --effort high --yolo
# Inspect before writing — plan, doctor, validate
crossby sync --plan --from claude
crossby sync --doctor --from claude
crossby sync --validate-target
# Hand the current session off to another tool
crossby handoff --from claude --to codex
# Parse a session transcript for token usage
crossby stats /path/to/transcript.txt
Every command with missing arguments drops into a "Proceed / Change X" review so you can accept the resolved defaults with one keystroke or tweak any single value before it runs.
What gets synced
| Config | Strategy | Notes |
|---|---|---|
| Rules | Symlink (auto-copy) | AGENTS.md ↔ CLAUDE.md ↔ GEMINI.md ↔ .cursorrules ↔ .github/copilot-instructions.md. Falls back to copy with a <!-- crossby:manual-fix --> block when the source mentions surfaces specific to a different tool (/hooks, ExitPlanMode, permissionMode, …). |
| Agents | Symlink / translate | Markdown-shape tools (Claude / Cursor / Gemini / Copilot) symlink directories. Codex translates per file into .codex/agents/<name>.toml with permissionMode → sandbox_mode, model + effort family-mapped to GPT, lossy fields preserved as a manual-fix block. |
| Skills | Symlink / translate | All five tools accept the same SKILL.md shape, so symlink is the default. --strategy translate rewrites per tool with manual-fix notes for Claude allowed-tools on non-Claude targets, and converts Claude slash commands (.claude/commands/*.md) into claude-command-<slug> skills for every other tool. |
| Permissions | Convert | Canonical cmd:args ↔ Bash() / Shell() / shell() format per tool |
| Hooks | Write | Per-tool native hook schema; matcher widens on re-runs |
| MCP servers | Merge | Source tool's MCP config → each target's; Authorization: Bearer ${VAR}, ${VAR} headers, and env-var self-references are rewritten into Codex bearer_token_env_var / env_http_headers / env_vars |
| Plugins | Detect (manual) | .claude/plugins/, plugin-marketplaces.json, and .claude-plugin/marketplace.json are reported as Not Added; bundled commands/agents/MCP servers must be migrated by hand |
Before writing anything, crossby sync --plan shows a stage-by-concern dry-run summary; --doctor adds a readiness rating (high / medium / low) plus the target-validation checks that would run after; --validate-target re-parses already-synced files (TOML / JSON parseability, agent required fields, skill frontmatter, AGENTS.md size threshold, MCP command on PATH). Use --dry-run to run a real sync in shadow mode.
After every real sync, the result table is also written to .crossby/sync-report.md — a portable | Status | Item | Notes | markdown table you can paste into a PR description. Pass --no-persist-report to skip, or --report-format markdown-table to render the same shape on stdout.
Need to translate a single allowlist pattern by hand (e.g. while editing a config file)?
crossby convert "Bash(myapp:*)" --from claude --to cursorprints the equivalent pattern for the target tool.
Translate strategy and manual-fix blocks
Default strategy is symlink (with content-aware copy fallback for rules). Pass --strategy translate to do per-file rewriting that preserves intent across tools whose semantics diverge:
crossby sync --from claude --strategy translate
When a field doesn't have a faithful equivalent on the target — e.g. Claude permissionMode: plan going to Codex, or allowed-tools going to a tool that doesn't enforce them — the rendered file gets a clearly-marked block:
<!-- crossby:manual-fix:start -->
## Manual migration required
- Claude-specific agent semantics carried over verbatim. The target tool does not enforce them — review and rewrite or remove as needed. Fields preserved: `permissionMode: plan`, `skills` preload list (`release-notes`).
<!-- crossby:manual-fix:end -->
Re-running crossby sync replaces the block in lockstep with the source — no stacking. Removing the block once you've addressed the note is supported; the next sync only re-emits if the source still triggers it.
Cross-provider model translation
crossby launch translates model ids across families when the target tool wouldn't accept the source family natively:
# Pass a Claude model id to Codex — translated to gpt-5.4-mini under the hood
crossby launch --tool codex --model claude-sonnet-4.6 --effort high
# → codex --model gpt-5.4-mini -c model_reasoning_effort=xhigh
Sonnet shifts effort up one tier (low→medium, medium→high, high→xhigh) for coding-agent behavior. The reverse direction (gpt-5.4 → Claude) picks the lowest source tier so users don't accidentally over-bill. A UserWarning fires whenever a translation happens; pass a native id to silence it.
Agent-readable runbook
crossby init --install-skill copies the bundled crossby-sync skill into every installed tool's skills directory. From inside Claude Code / Codex / Cursor / etc., the LLM can drive the full sync loop end-to-end — scan, plan, fix manual-fix blocks, validate — without leaving the session. The bundle is at src/crossby/data/skill/; the references/differences.md file in the bundle has the per-surface mapping table.
The bundle follows the Agent Skills standard layout (SKILL.md, agents/openai.yaml, references/), so Codex users can also install it via the upstream $skill-installer skill without touching crossby:
$skill-installer install https://github.com/ivanviragine/crossby/tree/main/src/crossby/data/skill
That installs it globally under $CODEX_HOME/skills/ instead of per-project. Use whichever model fits — crossby init --install-skill for a project-scoped install that travels with the repo, or $skill-installer for a one-time user-scoped install.
Session handoff
# Hand off the latest session from the source tool
crossby handoff --from claude --to codex
# Or pick a specific session by id
crossby handoff --from claude --to codex --session-id 019cb497-ec14-7453-9224
# Write the handoff file but don't launch — review before switching tools
crossby handoff --from cursor --to copilot --no-launch
# Use the bundled Claude Code "compact" prompt instead of the default summary
crossby handoff --from claude --to codex --prompt-preset cc-compact
# Or supply your own summarization prompt
crossby handoff --from claude --to codex --prompt ./my-prompt.md
crossby reads the chosen session from the source tool, asks an LLM to summarize it into a structured handoff document, writes it to .crossby/handoffs/HANDOFF-<timestamp>.md, and launches the target with the file path (not its contents) as the initial prompt — so it fits under OS argv limits regardless of transcript size.
The default preset produces a structured six-section handoff (current task, key decisions, modified files, blockers, next steps, critical context). Pass --prompt-preset cc-compact to use Claude Code's partial-compaction prompt, or --prompt <path> to supply your own; both paths skip structured parsing and write the summarizer's output verbatim. The two flags are mutually exclusive.
Supported sources: Claude, Cursor, Codex, Copilot. Supported targets: all of the above plus Gemini, OpenCode, Antigravity, VS Code.
Optional: .crossby.yml
Run crossby init to scaffold this file interactively, or hand-author it to set defaults and save launch profiles:
version: 1
ai:
default_tool: claude
default_model: claude-sonnet-4.6
effort: medium
profiles:
ccyolo: # → crossby launch ccyolo
tool: claude
model: claude-sonnet-4.6
effort: high
yolo: true
quick: # → crossby launch quick
tool: cursor
model: haiku
effort: low
sync_defaults: # fed into `crossby sync`
from: claude
to: cursor
handoff_defaults: # fed into `crossby handoff`
from: claude
to: codex
prompt_preset: default
token_budget: 32000
Profiles are just named bundles of --tool / --model / --effort / --yolo. Run them by name (crossby launch ccyolo) or with --profile ccyolo. Explicit flags on the command line still override the profile.
sync_defaults and handoff_defaults feed the interactive prompts for those commands — CLI flags still win, and you always get the "Proceed / Change X" review before anything runs. crossby sync does not require this file — it reads directly from each tool's standard paths.
Supported tools
| Tool | Sync | Launch | Handoff (source) | Handoff (target) |
|---|---|---|---|---|
| Claude | ✓ | ✓ | ✓ | ✓ |
| Copilot | ✓ | ✓ | ✓ | ✓ |
| Gemini | ✓ | ✓ | — | ✓ |
| Codex | ✓ | ✓ | ✓ | ✓ |
| Cursor | ✓ | ✓ | ✓ | ✓ |
| OpenCode | ✓ | ✓ | — | ✓ |
| VS Code | ✓ | ✓ | — | ✓ |
| Antigravity | ✓ | ✓ | — | ✓ |
Per-tool flag mappings and adapter details live in CONTRIBUTING.md.
Documentation
- CONTRIBUTING.md — architecture, how to add a new tool, per-tool flag reference, release process.
Contributing
Issues and PRs welcome. See CONTRIBUTING.md for development setup and architecture.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file crossby-0.2.4.tar.gz.
File metadata
- Download URL: crossby-0.2.4.tar.gz
- Upload date:
- Size: 331.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df543910bb5b0893325d2830f4df9a7421f80ec728a30d3b839a7e32047f7074
|
|
| MD5 |
cb5eabd4dae9da4e60a544d90a678af6
|
|
| BLAKE2b-256 |
f487c4669408c009a6b2174bbae9da33c62b69bffdb71aae11e84edf5db98658
|
File details
Details for the file crossby-0.2.4-py3-none-any.whl.
File metadata
- Download URL: crossby-0.2.4-py3-none-any.whl
- Upload date:
- Size: 210.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ae8e6902540ed68cd3c7290dda8f6344251401ae07e526936dbf23f900e12e0
|
|
| MD5 |
75f9ef1820a121a2c75e86b71f6a7996
|
|
| BLAKE2b-256 |
cd661f9d5775b3c5df2ba51248067ca21a4d9b72c2db3acf5b11ccf7fa319cf0
|