npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

claude-code-migrate

v1.14.2

Published

Migrate AI CLI configs (Claude Code, Codex) between machines via SSH or local backup

Readme

ccm - Claude Code Migrate

CLI tool for syncing portable Claude Code and Codex setup between machines via SSH/SCP or local backup archives.

ccm is intentionally not a dotdir mirror. It ships the parts of an agent setup that should travel between hosts, preserves runtime state on the target, and adapts known machine-specific Codex settings after copy.

Versioning:

  • Package uses semver (1.2.0, etc.)
  • Git release tags use vX.Y.Z (example: v1.2.0)

Providers:

  • claude (~/.claude)
  • codex (~/.codex)

Shared skills are migrated from ~/.agents/skills and ~/.agents/lazy-skills when any provider is active.

What Syncs

ccm push uses overlay semantics: it overwrites/adds selected portable config on the target host, but does not delete remote-only runtime state such as auth, sessions, logs, history, caches, and local databases.

Portable surfaces today:

  • Claude: CLAUDE.md, settings.json, agents/, native skills/, hooks/statusline/keybindings when present, and selected MCP config from ~/.claude.json
  • Codex: config.toml, AGENTS.md, agents/, rules/, skills/ except skills/.system, and local Codex marketplace sources referenced from config.toml
  • Shared agents: ~/.agents/skills/, ~/.agents/lazy-skills/, and ~/.agents/.skill-lock.json

Runtime/local state is not migrated broadly. For example, auth.json, sessions, logs, SQLite state, plugin data, and local caches are preserved on the target.

After pushing Codex, ccm normalizes path-based Codex MCP command values when the same binary is available on the remote PATH.

Host-Aware Codex Plugins

Codex plugin enablement is host-aware. ccm copies portable marketplace sources, probes the target host, evaluates enabled plugins against policy, and installs missing allowed plugins through the remote codex plugin add command.

Built-in policy keeps clearly platform-specific plugins off incompatible hosts:

| Plugin | Default policy | | --- | --- | | build-ios-apps@openai-curated | macOS + xcodebuild | | build-macos-apps@openai-curated | macOS + xcodebuild | | test-android-apps@openai-curated | adb available | | computer-use@openai-bundled | macOS GUI host |

Pushes use the target's own OpenAI runtime catalogs. Copying a bundled or primary-runtime manifest does not make its plugins available. Unavailable runtime plugins are disabled in the target config with a reason in the dry run; portable config and skills still sync. Working target runtime paths are preserved, and backups still include runtime snapshots. Custom marketplaces continue to copy.

Legacy @openai-curated IDs use @openai-curated-remote when the target confirms the same plugin there. The host policies above apply to both names. Unknown custom plugins still require confirmed availability. Disabled plugins are not uninstalled from the target cache.

ccm push --dry-run stays non-mutating, but for Codex it now also probes the target and previews plugin policy/install decisions.

Installation

Install the published CLI:

bun add -g claude-code-migrate
# or
npm install -g claude-code-migrate

ccm runs on Bun 1.3.14 or newer on macOS and Linux. npm is a supported installation channel; using npm install does not make the CLI compatible with the Node.js runtime.

For local development from a checkout:

bun install
bun link

Usage

Initialize config

ccm config --init
# Edit ~/.config/claude-code-migrate/config.toml

Backup

ccm backup                      # all enabled providers + shared
ccm backup codex                # codex + shared
ccm backup codex ./out.tar.gz   # codex + shared to custom path
ccm backup ./out.tar.gz         # all enabled providers + shared
ccm backup --dry-run

New backups use the v2 archive manifest. It records the producing ccm version and, for every payload file, its canonical path, size, mode, and SHA-256 digest. ccm verifies the finished archive before publishing it.

Inspect and verify

ccm inspect ./ccm-backup.tar.gz          # metadata summary, no destination extraction
ccm inspect ./ccm-backup.tar.gz --files  # include file metadata
ccm inspect ./ccm-backup.tar.gz --json
ccm verify ./ccm-backup.tar.gz
ccm verify ./ccm-backup.tar.gz --json

inspect exits 0 for a structurally valid v1 or v2 archive. verify exits 0 only when v2 file integrity is verified, 1 for a valid legacy v1 archive whose integrity metadata is unavailable, and 3 for an invalid, unreadable, or unsupported archive. JSON output follows the same exit semantics and is suitable for automation.

Legacy v1 backups remain restorable throughout the ccm 1.x release line. To upgrade one, restore it with a trusted 1.x ccm installation, review the restored files, then create a fresh v2 backup. Do not treat that conversion as retroactive verification of the v1 archive.

Archive reads and restores use bounded streaming extraction. ccm rejects unsafe paths and entry types, duplicate or non-portable destinations, malformed manifests, integrity mismatches, and archives that exceed its compressed, expanded, per-file, entry-count, manifest, or path limits.

Successful and failed mutating restores and pushes also write private execution receipts under ${XDG_STATE_HOME:-~/.local/state}/ccm/receipts/. Use the canonical rcpt_... filename stem:

ccm receipts
ccm inspect latest
ccm verify latest
ccm inspect rcpt_0123456789abcdef0123456789abcdef
ccm inspect rcpt_0123456789abcdef0123456789abcdef --json
ccm verify rcpt_0123456789abcdef0123456789abcdef
ccm verify rcpt_0123456789abcdef0123456789abcdef --remote arda@devbox

Receipt verification re-observes only the receipt's symbolic managed roots and, when applicable, Codex plugin state, then compares fingerprints; it does not print file contents. Push receipts use the original target when it can be matched safely from the configured target or profiles. Otherwise, supply it through --remote; the target must match the receipt's redacted endpoint binding. Older schema-v1 receipts remain inspectable but report drift verification as unavailable because they do not carry an observation scope.

Doctor and diff

ccm doctor                 # local checks plus the configured remote target
ccm doctor --local         # explicitly skip remote checks
ccm doctor --remote host   # override the configured remote target
ccm diff                   # push diff against the configured target
ccm diff push codex host   # explicit push diff
ccm diff restore ./backup.tar.gz codex

Remote push planning reports observation progress in human output. JSON output remains one pure object. Observation is always fresh because an exact diff must not rely on stale managed-state data.

Push

ccm push                        # all enabled providers + shared (host from config)
ccm push codex                  # codex + shared
ccm push user@host              # all enabled providers + shared
ccm push claude user@host       # claude + shared
ccm push --all user@host        # all providers + shared, regardless of config enablement
ccm push --providers claude,codex user@host
ccm push codex user@host --dry-run           # explain settings, skills, and plugin changes
ccm push codex user@host --dry-run --verbose # every setting and changed file
ccm push codex user@host --dry-run --json    # stable, redacted execution plan for automation

Human previews compare the target with the final adapted configuration. They show model and permission changes, named MCP servers and plugins, file counts grouped by purpose, and any blockers. Source adaptations are listed separately: for example, dropping a Mac-only MCP server or disabling an iOS plugin on Linux. Credentials and arbitrary configuration values are hidden. Unchanged files are summarized; --verbose expands settings and file paths. Backup, restore, and diff use the same human presentation. JSON plans and diff schemas remain unchanged.

Live pushes summarize the payload file count, transferred and reused bytes, elapsed time, and average payload speed. Helper uploads and raw rsync output stay quiet; use ccm push --verbose for individual file progress and complete transfer output. Warnings and failure diagnostics remain visible by default. A ready payload is staged data; the final success message confirms the configuration was applied and verified.

Remote Codex commands may live in user-owned or root-owned installation directories. Group writability is accepted only when account and group records confirm the file owner's private group, including primary-group membership. Shared-group and world-writable commands remain blocked, and transaction workspaces retain their stricter private permissions.

Plugin observation scales with plugin identities rather than verbose catalog metadata. ccm validates and deduplicates IDs on the target before transport and accepts additional CLI metadata fields. The full catalog has a separate 32 MiB input budget and 30-second deadline; the compact identity list retains its 1 MiB budget. Real marketplace manifests have a 32 MiB planning budget, independent of the 4 MiB configuration-file budget. Exceeding a budget reports which limit failed, instead of claiming SSH is broken. Hung catalog processes and their children are stopped. Plugin recovery queries installed plugins only, so unrelated catalog growth cannot break reconciliation. Files named marketplace.json inside skills or test fixtures are ordinary payload files; only actual Codex marketplace entry points affect plugin availability.

When exactly one profile has the selected target host, push and push diff apply it automatically. Use --profile <name> to select one explicitly or --no-auto-profile to push without automatic profile selection. Multiple matching profiles fail closed.

Restore

ccm restore ./ccm-backup.tar.gz        # restore all providers in archive
ccm restore ./ccm-backup.tar.gz codex  # restore only codex
ccm restore ./ccm-backup.tar.gz --dry-run

If a local restore stops in a recoverable transaction, ccm transactions prints the exact recovery commands. ccm recover --rollback and ccm recover --accept infer the transaction only when exactly one journal matches; pass the transaction ID whenever the choice is ambiguous.

Restored Codex hook trust is deliberately removed. Review the restored hook commands and approve them again on the destination host before relying on them.

Config file

Location: ~/.config/claude-code-migrate/config.toml

[target]
type = "ssh"
host = "[email protected]"

[providers.claude]
enabled = true
settings_local = false
mcp_config = true

[providers.codex]
enabled = true

# Optional host-aware Codex plugin overrides.
# Built-in defaults already handle obvious platform-specific OpenAI plugins.
# mode: auto | always | never | preserve
#
# [providers.codex.plugin_policies."build-ios-apps@openai-curated"]
# mode = "auto"
# os = ["darwin"]
# commands = ["xcodebuild"]
#
# [providers.codex.plugin_policies."computer-use@openai-bundled"]
# mode = "never"

[backup]
path = "~/backups/ccm"

Codex plugin policy fields:

  • mode = "auto" evaluates optional host requirements.
  • mode = "always" explicitly requires the plugin, blocking before upload if unavailable.
  • mode = "never" disables the plugin on the target.
  • mode = "preserve" restores the target's previous enabled/disabled value after overlay copy.
  • os = ["darwin" | "linux" | "windows"] restricts auto to specific operating systems.
  • commands = ["xcodebuild"] requires commands to resolve with command -v on the target.
  • gui = true requires a GUI-capable target.

Full Gate

bun run full-gate

full-gate runs Biome lint, Biome format check, TypeScript typecheck, and Vitest.

Useful scripts:

bun run test        # Vitest once
bun run test:watch  # Vitest watch mode
bun run check       # alias for gate

License

MIT