ck migrate

One-shot migration of all ClaudeKit portable content (agents, commands, skills, config, rules, hooks) to other AI coding providers with intelligent reconciliation and conflict resolution.

Quick Start

# Interactive mode (auto-detects installed providers)
ck migrate

# Migrate to specific providers
ck migrate --agent cursor --agent codex

# Migrate to all supported providers globally
ck migrate --all --global

# Preview migration plan without writing files
ck migrate --dry-run

# Force ASCII borders for legacy terminals
CK_FORCE_ASCII=1 ck migrate --agent codex --dry-run

# Non-interactive with sensible defaults
ck migrate --yes

Terminal Flow

The current CLI flow is optimized to answer the two questions users actually ask during migration:

  1. Where will the files go?
  2. What changed?

Before any write happens, ck migrate now renders:

  • A source/destination intro panel showing discovered Claude Code content and the target provider paths
  • A pre-flight summary with one row per portable type (Agents, Skills, Commands, Config, Rules, Hooks)
  • Inline scope notes such as merge when a provider does not map 1

After execution, the command ends with a boxed footer:

  • WHERE — destination paths that were actually touched
  • WHAT — item counts by type
  • NEXT — follow-up commands such as ck doctor or provider-specific inspection commands

--dry-run uses the same structure, but reports what would change instead of writing files.

Scope Behavior

  • Default scope: project-level
  • Global scope: pass -g or --global
  • Provider quirks still apply: for example, Codex commands migrate as skills, so project scope writes .agents/skills/source-command-*/SKILL.md and global scope writes ~/.agents/skills/source-command-*/SKILL.md

If you are migrating in older Windows terminals, set CK_FORCE_ASCII=1 to force the ASCII fallback border set.

What Happens

The ck migrate command:

  1. Discovers all portable items from your .claude/ directory (agents, commands, skills, config, rules, hooks)
  2. Detects installed AI coding providers on your system
  3. Computes a reconciliation plan comparing source vs target states
  4. Resolves conflicts interactively (or auto-resolves with --yes)
  5. Installs converted content to each target provider’s format
  6. Merges hook settings into provider-specific settings.json
  7. Cleans up stale registry entries and deprecated paths

Generated hook cleanup (v4.3.0+): ck migrate does not migrate ClaudeKit’s generated session/subagent/usage context hooks by default. It also removes stale registrations and hook files for those generated hooks from existing migrated providers, including Codex and Claude Code, while preserving safety hooks such as privacy and scout blocking.

Supported Providers

Each column indicates how well ck migrate can transfer that content type to the target provider:

  • Yes — Provider has a native equivalent. Content migrates 1
    with full functionality.
  • Partial — Content is copied/converted, but the provider has no native equivalent for this concept. It may work as context or rules, but not as a first-class feature (e.g., agents merged into a flat context file).
  • - — Not supported. Content is not migrated to this provider.
ProviderAgentsCommandsSkillsConfigRulesHooks
Claude CodeYesYesYesYesYesYes
OpenCodeYesYesYesYesYes-
GitHub CopilotYes-YesYesYes-
CodexYesYesYesYesYesYes
DroidYesYesYesYesYesYes
CursorPartial-YesYesYes-
Roo CodeYes-YesYesYes-
Kilo CodeYes-YesYesYes-
WindsurfPartialYesYesYesYes-
GoosePartial-YesYesYes-
Gemini CLIPartialYesYesYesYes-
AmpPartial-YesYesYes-
Antigravity-YesYesYesYes-
ClinePartial-YesYesYes-
OpenHandsPartial-YesYesYes-

Options

Target Options

FlagDescription
-a, --agent <provider>Target provider(s), can be specified multiple times
--allMigrate to all supported providers
-g, --globalInstall globally instead of project-level
-y, --yesSkip confirmation prompts
-f, --forceForce reinstall deleted/edited items
--dry-runPreview migration plan without writing files

Content Selection

FlagDescription
--configMigrate CLAUDE.md config only
--rulesMigrate .claude/rules/ only
--hooksMigrate .claude/hooks/ only
--skip-configSkip config migration
--skip-rulesSkip rules migration
--skip-hooksSkip hooks migration
--source <path>Custom CLAUDE.md source path

Content Selection Logic

The content selection flags follow a precise truth table:

“Only” mode — when any of --config, --rules, --hooks are specified:

  • --config — only config (no agents/commands/skills/rules/hooks)
  • --rules — only rules
  • --hooks — only hooks
  • --config --rules — only config AND rules
  • --config --hooks — only config AND hooks
  • --config --rules --hooks — only config, rules, AND hooks

“Skip” mode — when any of --skip-* flags are used:

  • --skip-config — everything except config
  • --skip-rules — everything except rules
  • --skip-hooks — everything except hooks

Default (no flags) — migrates everything.

Reconciliation Engine

The migrate command uses a sophisticated reconciliation engine that:

  1. Computes checksums for both source items and target files
  2. Compares states against the portable registry to detect:
    • New items to install
    • Updated items needing refresh
    • Unchanged items to skip
    • Deleted items to clean up
    • Conflicts requiring resolution
  3. Generates a plan showing all actions before execution

Conflict Resolution

When a target file has been modified externally, the command offers:

  • Overwrite — replace with source content
  • Smart merge — attempt to merge changes
  • Skip — keep existing content
  • View diff — see the differences before deciding

Examples

Migrate everything to Cursor

ck migrate --agent cursor

Migrate config and rules to all providers

ck migrate --all --config --rules

Force re-migrate hooks globally

ck migrate --all --global --hooks --force

Preview what would change

ck migrate --dry-run

Migrate to multiple specific providers

ck migrate --agent droid --agent codex --agent cursor

Skip hooks during migration

ck migrate --all --skip-hooks

Use custom CLAUDE.md source

ck migrate --agent cursor --source ./custom/CLAUDE.md

Migration Phases

Phase 1: Discovery

Scans .claude/agents/, .claude/commands/, .claude/skills/, .claude/rules/, .claude/hooks/, and CLAUDE.md for portable content.

Phase 2: Provider Selection

Auto-detects installed providers or prompts for selection. Use --agent or --all to skip detection.

Phase 3: Scope Selection

Choose between project-level (.claude/ in CWD, the default) or global (~/.claude/) installation.

Phase 4: Reconciliation

Computes a migration plan using checksums and registry state. Displays actions (install, update, skip, delete, conflict).

Phase 5: Execution

Installs items, merges hook settings, processes metadata deletions, and cleans up stale entries.

Phase 6: Summary

Displays a destination-aware WHERE / WHAT / NEXT footer and offers rollback on partial failures.

Provider Notes

OpenCode

ck migrate --agent opencode writes a default model to opencode.json so migrated agents resolve at invocation. The migration:

  1. Reads your authenticated providers from ~/.local/share/opencode/auth.json.
  2. Picks a sensible default model from the models.dev catalog. When OpenCode Zen (provider id opencode) is authenticated — the most common case — the migration prefers a free-tier model (*-free), sorted newest first.
  3. In interactive mode, you can accept the suggestion, type a custom provider/model string, or skip. In --yes / non-interactive mode, the suggestion is auto-accepted.
  4. If opencode is not authenticated (no auth.json or empty), --yes mode exits with a clear hint: Run: opencode auth login. The migration does NOT write a guessed default that would later fail.
  5. If your opencode.json already has a model field, the migration validates it against the live models.dev catalog. A valid existing model is preserved untouched. An invalid existing model (e.g. left over from an older release) triggers an interactive rewrite/keep prompt; in non-interactive mode, the invalid value is left in place with a loud warning so you can fix it manually.

The catalog is fetched once per 24 hours and cached at ~/.config/claudekit/cache/models-dev.json.

Why the default isn’t anthropic/... anymore

Earlier releases hardcoded an Anthropic default (anthropic/claude-sonnet-4-6). For users authenticated only with OpenCode Zen (qwen, glm, kimi, etc.), that default triggered ProviderModelNotFoundError at sub-agent invocation because the user has no Anthropic provider configured. The migration now derives the default from your actual auth state instead of guessing.

Override via .ck.json

If you want to pin a specific default:

{
  "taxonomy": {
    "opencode": {
      "default": { "model": "opencode/glm-4.7-free" }
    }
  }
}

This wins over auto-detection.

Rollback on Failure

If some items fail while others succeed, the command offers a rollback option:

  • New writes are removed
  • Overwritten files are preserved (cannot be rolled back)
  • Registry entries are cleaned up