AgentKit
DocsKitsCLI ReferenceDesktop App
BetaYou are reading docs for the beta channel (2.13.0-beta.20). Features may change before the next stable release.Switch to stable →

Guides

Migrating from ClaudeKit

Preview, apply, verify, and roll back a ClaudeKit migration while preserving custom work.

Migration discovers an existing ClaudeKit setup, classifies what ClaudeKit owns, preserves custom content, and moves supported kits into AgentKit's managed lifecycle. It is a planned transition, not a broad delete-and-reinstall.

Before you start

  1. Run the migration from the project whose ClaudeKit content you want AgentKit to inspect.
  2. Complete the Back up before apply gate below. Do not rely only on version control or AgentKit recovery state.
  3. Close Claude Code and Codex sessions that may be using the affected files.
  4. Confirm that ak is authenticated and that your account has the required kit entitlements with ak whoami and ak licenses.

The migration scans the current project and the standard ClaudeKit user locations, including ~/.claude and ~/.claudekit. It can discover both project and global content, including supported Claude Code and Codex kit surfaces.

Do not delete ~/.claude, ~/.codex, ~/.agentkit, or the project's .claude directory before migrating. Those locations may contain custom or unrelated runtime state that the migration is designed to preserve.

Preview the migration

ak migrate is a dry run by default. State the source explicitly so the intent is clear:

ak migrate --from=ck

For a machine-readable report:

ak migrate --from=ck --json

The preview performs discovery and prints a migration plan without writing files. Review:

  • Detected runtime and project/global scope;
  • ClaudeKit-owned content that can be archived, quarantined, or neutralized;
  • Custom or unknown content that will be preserved;
  • AgentKit kits that will be installed;
  • Conflicts that require resolution before apply.

An apply is blocked while the plan contains conflicts. Resolve them and run the dry run again; do not bypass the review with a forced reinstall.

Choose Claude Code delivery

Migration uses native Claude Code delivery unless you explicitly authorize a project plugin transition. If the preview and your intended install mode require a project plugin, use --switch-to-plugin in both preview and apply:

ak migrate --from=ck --switch-to-plugin

Do not add this flag merely because ClaudeKit used plugin-like files. Choose it only when the resulting AgentKit install should be a Claude Code project plugin.

Back up before apply

Required before apply

You may run the read-only preview first. Do not run with --dry-run=false --yes until you have created the independent backup below and verified it.

Apply can archive, quarantine, or neutralize authorized ClaudeKit surfaces and install replacement content. AgentKit intends to preserve custom work, but an independent copy protects you from a wrong assumption about ownership or scope, an interruption, and later manual recovery.

Run the command for your platform from the same project directory where you ran the preview. It creates a new timestamped directory under AgentKitMigrationBackups in your user home, outside the default migration roots. It copies only existing settings and configuration files that migration or replacement installation can read or update; it does not copy entire runtime homes, kit trees, caches, sessions, or standalone credential stores. Some of the selected settings files can themselves contain credential-like values, so keep the backup private even though the list is bounded.

set -eu
umask 077

project_root=$PWD
backup_root="$HOME/AgentKitMigrationBackups"
stamp=$(date -u +%Y%m%dT%H%M%SZ)
backup_dir="$backup_root/$stamp"
claude_home=${AGENTKIT_CLAUDE_HOME:-"$HOME/.claude"}
codex_home=${CODEX_HOME:-"$HOME/.codex"}
agentkit_home=${AGENTKIT_HOME:-"$HOME/.agentkit"}
codex_skills=${AGENTKIT_CODEX_SKILLS_ROOT:-"$HOME/.agents/skills"}
default_claude_home="$HOME/.claude"
default_codex_home="$HOME/.codex"
default_agentkit_home="$HOME/.agentkit"

for unsafe_root in \
  "$claude_home" "$codex_home" "$agentkit_home" "$codex_skills" \
  "$HOME/.claudekit" "$project_root/.claude" \
  "$project_root/.claudekit" "$project_root/.codex" \
  "$project_root/.agentkit" "$project_root/.agents/skills"
do
  case "$backup_root/" in
    "$unsafe_root/"*)
      printf 'Choose a backup_root outside migration root: %s\n' "$unsafe_root" >&2
      exit 1
      ;;
  esac
done

mkdir -m 700 -p "$backup_root"
mkdir -m 700 "$backup_dir"
: > "$backup_dir/files.tsv"

copy_backup_file() {
  source_path=$1
  relative_path=$2
  if [ -f "$source_path" ]; then
    destination="$backup_dir/$relative_path"
    mkdir -p "$(dirname "$destination")"
    cp -p "$source_path" "$destination"
    printf '%s\t%s\n' "$source_path" "$relative_path" >> "$backup_dir/files.tsv"
  fi
}

for name in .ck.json settings.json settings.local.json; do
  copy_backup_file "$claude_home/$name" "user/claude/$name"
  copy_backup_file "$HOME/.claudekit/$name" "user/claudekit/$name"
  copy_backup_file "$project_root/.claude/$name" "project/claude/$name"
  copy_backup_file "$project_root/.claudekit/$name" "project/claudekit/$name"
done
copy_backup_file "$codex_home/config.toml" "user/codex/config.toml"
copy_backup_file "$codex_home/hooks.json" "user/codex/hooks.json"
copy_backup_file "$agentkit_home/config.yaml" "user/agentkit/config.yaml"
copy_backup_file "$agentkit_home/ownership.json" "user/agentkit/ownership.json"
if [ "$claude_home" != "$default_claude_home" ]; then
  copy_backup_file "$default_claude_home/.ck.json" "user/default-claude/.ck.json"
  copy_backup_file "$default_claude_home/settings.json" "user/default-claude/settings.json"
  copy_backup_file "$default_claude_home/settings.local.json" "user/default-claude/settings.local.json"
fi
if [ "$codex_home" != "$default_codex_home" ]; then
  copy_backup_file "$default_codex_home/config.toml" "user/default-codex/config.toml"
  copy_backup_file "$default_codex_home/hooks.json" "user/default-codex/hooks.json"
fi
if [ "$agentkit_home" != "$default_agentkit_home" ]; then
  copy_backup_file "$default_agentkit_home/config.yaml" "user/default-agentkit/config.yaml"
  copy_backup_file "$default_agentkit_home/ownership.json" "user/default-agentkit/ownership.json"
fi
copy_backup_file "$project_root/.codex/config.toml" "project/codex/config.toml"
copy_backup_file "$project_root/.codex/hooks.json" "project/codex/hooks.json"
copy_backup_file "$project_root/.agentkit/config.yaml" "project/agentkit/config.yaml"
copy_backup_file "$project_root/.agentkit/ownership.json" "project/agentkit/ownership.json"

if [ ! -s "$backup_dir/files.tsv" ]; then
  printf 'No recognized settings files found; inspect the preview before apply.\n' >&2
  exit 1
fi

tab=$(printf '\t')
while IFS="$tab" read -r source_path relative_path; do
  test -f "$backup_dir/$relative_path"
  cmp -s "$source_path" "$backup_dir/$relative_path"
done < "$backup_dir/files.tsv"

count=$(wc -l < "$backup_dir/files.tsv" | tr -d ' ')
printf 'Verified %s files in %s\n' "$count" "$backup_dir"

The last line must print Verified and the destination. If the command reports no recognized files, stop and inspect the preview rather than treating an empty directory as a backup. The selected files can contain sensitive provider or MCP values. Keep the directory local with restricted access; never upload it or commit it to version control.

The list is deliberately bounded. Custom Codex skill roots, plugin directories, and kit content are selected from the runtime, scope, delivery route, and actual preview; they are not universal configuration roots. If the preview says an additional existing path will be archived, quarantined, neutralized, or overwritten, copy that exact path separately into the backup directory and verify the copy. Do not guess by copying all of ~/.claude, ~/.codex, ~/.agentkit, or another runtime home.

This user-created backup is independent of AgentKit's operation-specific recovery snapshot and migration journal, which AgentKit records immediately before its own mutations. The two layers serve different recovery paths. Neither is a general full-machine backup, and migration rollback restores only recorded state; it does not reconstruct everything or remove an installed replacement.

Apply the reviewed plan

Apply requires both --dry-run=false and --yes:

ak migrate --from=ck --dry-run=false --yes

For the explicitly reviewed project-plugin route:

ak migrate --from=ck --switch-to-plugin --dry-run=false --yes

Before replacement installation, AgentKit preflights every requested kit install. The operation migrates supported preferences, archives or quarantines authorized ClaudeKit directories, neutralizes owned integration surfaces, preserves custom or unknown content, and installs the corresponding AgentKit kits. It records recovery state before mutation.

Existing AgentKit configuration values win when preferences are migrated. Credential-like values in a project .ck.json are omitted so they do not reach project .agentkit/config.yaml. Credential-like values in a user or global ~/.claude/.ck.json can migrate into the user config.yaml when AgentKit does not already define them. AgentKit writes the resulting config with mode 0600 on systems that enforce POSIX permissions. Review the dry-run preference plan, and keep its output, the source file, and the resulting config private.

If an apply fails, the migration is resumable by default. Read the reported state before choosing whether to rerun apply or roll it back.

Migrate preferences only

Use the preference-only flow when you are not ready to transition kit content:

ak migrate prefs --dry-run
ak migrate prefs --dry-run=false --yes

This copies supported values, keeps existing AgentKit values, omits credential-like project values, and can carry credential-like user/global values into the private user config. It does not delete the legacy .ck.json file.

Verify the result

After a successful apply:

  1. Read the summary and confirm the expected runtime, scope, and installed kits.
  2. Reopen the affected runtime.
  3. Invoke one important Skill from each migrated kit.
  4. Review custom project instructions and hooks you expected to keep.
  5. Keep the migration recovery information until you have completed those checks.

A file's presence alone does not prove that a hook is registered or executing. Verify the observable runtime behavior before removing any preserved legacy content.

Roll back

Rollback starts immediately

ak migrate rollback has no dry-run, confirmation prompt, required --yes, --force, or journal selector. It immediately reconciles the newest recovery state and can finalize deletion of a quarantine instead of restoring it.

Run rollback only after checking the independent backup and copying aside unrelated work created after migration:

ak migrate rollback

For a legacy transition, behavior depends on the recorded phase. Before a replacement install is proven, rollback restores the recorded quarantine. At installed or finalize_pending, it verifies the AgentKit install receipts and then finalizes and deletes the quarantine; it does not restore ClaudeKit. Only when no pending legacy transition exists does the command restore the latest generic file journal. If neither state exists, it reports that there is nothing to roll back and exits successfully.

Rollback handles only the recorded state. It is not a selective undo for later edits, does not reconstruct the entire pre-apply environment, and does not remove an installed AgentKit replacement. Preview and uninstall that replacement through the matching target, scope, and delivery route if you no longer want it.

If migration is interrupted

Run the default dry run again first. If AgentKit reports a pending transition, choose one recovery path:

  • Rerun the reviewed apply so the resumable operation can recover and finish;
  • Run ak migrate rollback to restore the recorded pending state.

A pending journal blocks a different migration transition until you resume or roll back the current one. A successful dry run exits 0; invalid source or flags exit 2, cancellation or missing apply confirmation exits 3, and a runtime or apply failure exits 1.

Use --force-unlock only when the CLI specifically reports a stale migration lock left by a crashed process and no migration is still running. It does not resolve file conflicts or replace the rollback workflow.

See also