Show HN: Sync Claude Code and Codex configs, with a board that shows the drift
ai-config-sync-manager is a CLI tool for continuously bidirectional syncing of configurations between Claude Code and Codex. It features a diff-first workflow, strict YAML round-trip, risk-tagged operations, automatic backups, and a visual board, aiming to keep configurations consistent across the two AI coding assistants.
Notifications You must be signed in to change notification settings
Fork 4
Star 21
BranchesTags
Open more actions menu
Folders and files
NameName
Last commit message
Last commit date
Latest commit
History
212 Commits
212 Commits
.github
.github
.husky
.husky
assets
assets
bin
bin
docs
docs
integrations
integrations
rules
rules
schemas
schemas
scripts
scripts
snapshots
snapshots
tests
tests
.gitignore
.gitignore
.lintstagedrc.mjs
.lintstagedrc.mjs
.prettierignore
.prettierignore
.prettierrc.json
.prettierrc.json
AGENTS.md
AGENTS.md
CHANGELOG.md
CHANGELOG.md
CLAUDE.md
CLAUDE.md
LICENSE
LICENSE
README.md
README.md
eslint.config.mjs
eslint.config.mjs
package-lock.json
package-lock.json
package.json
package.json
setup
setup
tsconfig.check.json
tsconfig.check.json
Repository files navigation
Continuous bidirectional sync between Claude Code and Codex — round-trip lossless, not a one-shot migrator.
Highlights
Continuous bidirectional sync — claude → codex and codex → claude, run as often as the two hosts drift; not a one-shot migration.
Strict YAML round-trip — Claude lenient YAML and Codex YAML 1.2 strict frontmatter both preserved across repeated syncs without loss or oscillation.
Diff-first workflow — status to compare → sync --dry-run to preview → --apply to write.
Risk-tagged operations — permissions, hooks, custom commands labeled safe / partial / manual.
Backup-on-write — every overwrite snapshotted under .backups/, FIFO retention (30).
Apply ledger — every --apply writes a per-item sha256 attestation (before/after hash, backup path) to ~/.ai-config-sync-manager/ledgers/.
Selector syntax — --include skills:code-writer,instructions --exclude mcp style filtering.
Native semantic mapping — Claude Write → Codex sandbox_mode = "workspace-write", etc.
Prose-level token rewriting — Claude-only tokens (Read, Bash, TaskCreate, headless claude -p) and Codex-only tokens (spawn_agent, codex exec) auto-translate across hosts and round-trip back.
Zero runtime dependencies — single ESM file, Node built-ins only.
Thin host plugins — /config-manager:* for Claude, config-manager-* for Codex.
Visual inventory board — board renders a self-contained HTML page of every skill, agent, hook, and MCP server on both hosts, colored by sync status (in-sync / conflict / one-host-only) and grouped into per-area tabs and by agent harness. Jump to the board →
Why this exists
Claude Code and Codex use the same concepts (instructions / skills / mcp / permissions / hooks) but in different files, formats, and names:
Concept Claude Codex
Instructions ~/.claude/CLAUDE.md ~/.codex/AGENTS.md
Skills ~/.claude/skills/ ~/.codex/skills/
Settings ~/.claude/settings.json ~/.codex/config.toml
MCP ~/.claude/.mcp.json [mcp_servers.*] in config.toml
Hand-rolling the sync invites drift, semantic loss, and accidental secret leaks. This CLI keeps the two hosts aligned while preserving host-native meaning.
This tool is built for two hosts in continuous use — where drift accumulates daily and round-trip integrity matters across repeated syncs — not for a one-shot, one-way migration.
One-shot migrators typically copy Claude-only vocabulary (tool names like Read / Bash, prose like Use the Bash tool, in-line Agent({...}) calls) into the generated file as prompt guidance and flag it for manual review. This CLI instead auto-rewrites those tokens to their host equivalents (Read → workspace-write, TaskCreate → spawn_agent, claude -p → codex exec, …) and round-trips them back when syncing the other direction — so the same content stays correct for both hosts with no manual fix-ups.
Quick Start
npm install -g ai-config-sync-manager ai-config-sync connect # register the plugin for any detected host (Claude / Codex) ai-config-sync status # show drift across global + project scopes ai-config-sync sync # preview changes (--dry-run by default) ai-config-sync sync --apply # apply with automatic backups
connect only registers plugins for hosts it actually finds (~/.claude for Claude, ~/.codex or ~/.agents for Codex). Hosts that are missing are reported as skipped and no directories are created — install the host first, then rerun connect.
Requirements
Node.js ≥ 20
Claude Code and/or Codex CLI installed (host plugins are auto-registered by connect when the matching host directory exists)
Table of Contents
Category Sections
Commands Bundled CLI · Host plugin commands · Flags · Board
Workflow Selector syntax · Ignore rules · Sync direction · Scopes
Safety Safety defaults · Risk levels · Retention
Mapping Native mapping · Areas · Paraphrase · Hidden markers · Unsupported
Reference Install resolution · Local dev · Gotchas · API surface · What's next
Commands
Bundled CLI
After npm install -g, the same binary is on PATH as ai-config-sync — equivalent to ./bin/ai-config-sync.mjs from a source clone.
ai-config-sync connect ai-config-sync status ai-config-sync status --json ai-config-sync status --scope global ai-config-sync status --scope project ai-config-sync status --include skills:code-writer,instructions --exclude mcp ai-config-sync sync --dry-run ai-config-sync sync --scope project --dry-run ai-config-sync sync --scope global --apply ai-config-sync sync --include instructions,skills:code-writer --exclude mcp --dry-run ai-config-sync sync --from claude --to codex ai-config-sync sync --from codex --to claude ai-config-sync board ai-config-sync board --scope global --no-open ai-config-sync reference ai-config-sync paraphrase
Command Purpose
connect Detect installed hosts and register the matching plugin
status Compare global + project config across both hosts
status --json Machine-readable diff
sync --dry-run Preview the merge plan without writing
sync --apply Apply the plan, snapshot to .backups/
board Render an HTML inventory board of both hosts, colored by sync status
reference Emit / persist a self-generated markdown reference
paraphrase Line-level override archive for instruction wording
Host plugin commands
Host Connect Status Sync Paraphrase
Claude /config-manager:connect /config-manager:status /config-manager:sync /config-manager:paraphrase
Codex config-manager-connect config-manager-status config-manager-sync config-manager-paraphrase
Flags
Per-subcommand flag reference, mirroring --help output. Shared flags (--include / --exclude / --scope / --map) get a one-line summary; full syntax lives in the linked section.
connect
Flag Description
-h, --help Show connect help
ai-config-sync connect
status
Flag Description
--json Print the full status report as JSON
--compact One compact line per diff entry
--tree Scope/area/item tree output
--scope global|project|all Limit scope (default: all = global + project)
--include area[:item][,...] Include selector — see Selector syntax
--exclude area[:item][,...] Exclude selector — see Selector syntax
-h, --help Show status help
ai-config-sync status --scope project --tree --include skills:code-writer
board
Renders a self-contained HTML inventory board — every skill, agent, hook, and MCP server on both hosts, split into per-area tabs, colored by sync status: green = in sync, red = conflict, blue = Claude only, purple = Codex only, amber = unsupported. Agents are grouped under their harness (subfolder) where they have one. Type in the filter box to narrow rows; click a row for the full description, paths, and status detail. The file is written to ~/.ai-config-sync-manager/board/ with no external requests, so it works offline, and opens in your default browser automatically (pass --no-open to skip). (Screenshot at the top.)
Flag Description
--scope global|project|all Limit scope (default: all = global + project)
--include area[:item][,...] Include selector — see Selector syntax
--exclude area[:item][,...] Exclude selector — see Selector syntax
--no-open Only write the file; do not open a browser
-h, --help Show board help
ai-config-sync board --scope global
sync
Flag Description
--dry-run Preview without writing (default; mutually exclusive with --apply)
--apply Apply with backups
--plan-json Print the sync plan as JSON
--ledger-json Print the apply ledger as JSON to stdout (--apply only)
--ledger Write the apply ledger JSON to (--apply only)
--from claude|codex Source host (overrides AI_CONFIG_SYNC_HOST)
--to claude|codex Target host (overrides AI_CONFIG_SYNC_HOST)
--scope global|project|all Limit scope (default: all = global + project)
--include area[:item][,...] Include selector — see Selector syntax
--exclude area[:item][,...] Exclude selector — see Selector syntax
-h, --help Show sync help
When --from / --to are omitted, direction follows Sync direction.
ai-config-sync sync --scope project --include mcp:notion --apply
reference
Flag Description
--output Write the reference markdown to (parent directories created)
-h, --help Show reference help
ai-config-sync reference --output ~/.ai-config-sync-manager/reference.md
paraphrase
Flag Description
--apply Rewrite files + register overrides + persist new map entries (default: dry-run)
--register Skip rewriting; only register overrides where the effective map already equates both sides — see Paraphrase
--map token=paraphrase[,...] Inline token-to-paraphrase pairs (free-form prose accepted) — see --map syntax
--non-interactive Skip TTY prompts for tokens missing from paraphrase-map.json
--json Print the result as JSON
--scope global|project|all Limit scope (default: all = global + project)
--include area[:item][,...] Include selector — see Selector syntax
--exclude area[:item][,...] Exclude selector — see Selector syntax
-h, --help Show paraphrase help
ai-config-sync paraphrase --map "Read=read the file,Write=write to the file" --apply
Selector syntax
--include narrows the plan first, then --exclude removes matches. Both accept area or area:item syntax; itemized areas (skills, permissions, hooks, agents, mcp, commands) accept glob items.
ai-config-sync sync --include skills:code-writer,instructions --exclude mcp --dry-run ai-config-sync sync --include "permissions:Write*" --exclude "permissions:Bash(rm:*)" --dry-run
Areas
Area Itemized? Apply granularity
instructions — file merge
skills yes per skill
agents yes per agent
mcp yes per server
permissions yes item-by-item patch
hooks yes item-by-item patch
commands yes per command
plugins yes status only (read-only diff; sync skips this area)
Ignore rules
Persistent ignore lives at one of:
/.ai-config-sync-manager/status-ignore.json (project scope, checked first)
~/.ai-config-sync-manager/rules/status-ignore.json (global)
Each exclude entry is a string selector (area:item or path glob) or an object whose fields combine with AND. term is a line-level mask — lines containing the substring are removed from both sides before the diff, so the conflict can disappear without hiding unrelated changes.
{ "version": 1, "exclude": [ "skills:legacy-skill", "permissions:Bash", "~/.codex/agents/archive-*.toml", { "scope": "global", "area": "agents", "item": "refactor-*" }, { "area": "skills", "host": "claude", "path": "~/.claude/skills/coderabbit-review" }, { "area": "skills", "term": ".claude/docs/repo-analysis/" }, { "area": "agents", "host": "claude", "path": "~/.claude/agents/*.md", "term": "TODO: do not sync" } ] }
The active path and rule count are echoed in status output as Status ignore: rules: [...] (N hidden).
Sync direction
Trigger Default direction
AI_CONFIG_SYNC_HOST=codex (Codex plugin invocation) codex → claude
Otherwise (Claude plugin / direct CLI) claude → codex
--from --to Explicit override
Scopes
Scope Path coverage
global ~/.claude/, ~/.codex/
project /.claude/, /.codex/, /AGENTS.md, /CLAUDE.md
default / all global +
[truncated for AI cost control]