2.13.0-beta.20). Tính năng có thể thay đổi trước bản stable tiếp theo.Chuyển sang stable →Hướng dẫn
Chuyển từ ClaudeKit
Xem trước, áp dụng, xác minh và rollback quá trình chuyển từ ClaudeKit trong khi giữ lại nội dung tùy chỉnh.
Migration tìm một bản cài ClaudeKit hiện có, phân loại nội dung thuộc quyền sở hữu ClaudeKit, giữ lại nội dung tùy chỉnh và đưa các Kit được hỗ trợ vào vòng đời do AgentKit quản lý. Đây là quá trình chuyển đổi có kế hoạch, không phải xóa diện rộng rồi cài lại.
Trước khi bắt đầu
- Chạy migration từ project có nội dung ClaudeKit mà bạn muốn AgentKit kiểm tra.
- Hoàn tất gate Sao lưu trước khi apply bên dưới. Không chỉ dựa vào version control hoặc trạng thái khôi phục của AgentKit.
- Đóng các phiên Claude Code và Codex có thể đang dùng những file bị ảnh hưởng.
- Xác nhận
akđã đăng nhập và tài khoản có quyền dùng Kit cần thiết bằngak whoamivàak licenses.
Migration quét project hiện tại và các vị trí người dùng chuẩn của ClaudeKit,
bao gồm ~/.claude và ~/.claudekit. Lệnh có thể tìm cả nội dung project lẫn
global, bao gồm các bề mặt Kit Claude Code và Codex được hỗ trợ.
Không xóa ~/.claude, ~/.codex, ~/.agentkit hoặc thư mục .claude của
project trước migration. Những vị trí này có thể chứa trạng thái runtime tùy
chỉnh hoặc không liên quan mà migration được thiết kế để giữ lại.
Xem trước migration
ak migrate mặc định là dry run. Hãy chỉ định rõ nguồn để ý định không mơ hồ:
ak migrate --from=ckĐể nhận báo cáo máy có thể đọc:
ak migrate --from=ck --jsonBản xem trước chạy discovery và in kế hoạch migration mà không ghi file. Hãy review:
- Runtime và phạm vi project/global đã phát hiện;
- Nội dung thuộc ClaudeKit có thể được archive, quarantine hoặc neutralize;
- Nội dung tùy chỉnh hoặc không rõ nguồn gốc sẽ được giữ lại;
- Kit AgentKit sẽ được cài;
- Xung đột phải được xử lý trước khi áp dụng.
Không thể áp dụng khi kế hoạch còn xung đột. Hãy xử lý chúng và chạy lại dry run; không bỏ qua bước review bằng một lần cài lại cưỡng chế.
Chọn cách phân phối cho Claude Code
Migration dùng cách phân phối Claude Code native trừ khi bạn cho phép rõ ràng
việc chuyển sang plugin trong project. Nếu bản xem trước và chế độ cài đặt bạn
muốn yêu cầu plugin project, hãy dùng --switch-to-plugin ở cả bước xem trước
và áp dụng:
ak migrate --from=ck --switch-to-pluginKhông thêm flag này chỉ vì ClaudeKit đã dùng các file có hình dạng plugin. Chỉ chọn khi bản cài AgentKit sau cùng phải là plugin Claude Code trong project.
Sao lưu trước khi apply
Bắt buộc trước khi apply
Bạn có thể chạy bản xem trước chỉ đọc trước. Không chạy với --dry-run=false --yes cho đến khi đã tạo và xác minh bản sao lưu độc lập bên dưới.
Apply có thể archive, quarantine hoặc neutralize các bề mặt ClaudeKit được phép thay đổi và cài nội dung thay thế. AgentKit được thiết kế để giữ nội dung tùy chỉnh, nhưng một bản sao độc lập bảo vệ bạn khi giả định về quyền sở hữu hoặc phạm vi không đúng, khi thao tác bị gián đoạn và khi cần khôi phục thủ công sau này.
Chạy lệnh cho nền tảng của bạn từ cùng thư mục project nơi bạn đã chạy bản xem
trước. Lệnh tạo thư mục mới có timestamp trong AgentKitMigrationBackups ở thư
mục home của người dùng, nằm ngoài các root migration mặc định. Lệnh chỉ sao
chép những file settings và cấu hình hiện có mà migration hoặc bước cài thay thế
có thể đọc hay cập nhật; không sao chép toàn bộ runtime home, cây Kit, cache,
session hoặc kho credential độc lập. Một số file settings được chọn vẫn có thể
chứa giá trị giống credential, vì vậy hãy giữ bản sao lưu riêng tư dù danh sách
đã được giới hạn.
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"Chạy đoạn này trong PowerShell. Từ cmd.exe, hãy mở PowerShell và dùng quy
trình này thay vì chuyển nó thành batch script.
$ErrorActionPreference = 'Stop'
$ProjectRoot = (Get-Location).Path
$BackupRoot = Join-Path $HOME 'AgentKitMigrationBackups'
$Stamp = [DateTime]::UtcNow.ToString('yyyyMMddTHHmmssZ')
$BackupDir = Join-Path $BackupRoot $Stamp
$ClaudeHome = if ($env:AGENTKIT_CLAUDE_HOME) { $env:AGENTKIT_CLAUDE_HOME } else { Join-Path $HOME '.claude' }
$CodexHome = if ($env:CODEX_HOME) { $env:CODEX_HOME } else { Join-Path $HOME '.codex' }
$AgentKitHome = if ($env:AGENTKIT_HOME) { $env:AGENTKIT_HOME } else { Join-Path $HOME '.agentkit' }
$CodexSkills = if ($env:AGENTKIT_CODEX_SKILLS_ROOT) { $env:AGENTKIT_CODEX_SKILLS_ROOT } else { Join-Path $HOME '.agents\skills' }
$DefaultClaudeHome = Join-Path $HOME '.claude'
$DefaultCodexHome = Join-Path $HOME '.codex'
$DefaultAgentKitHome = Join-Path $HOME '.agentkit'
$UnsafeRoots = @(
$ClaudeHome, $CodexHome, $AgentKitHome, $CodexSkills,
(Join-Path $HOME '.claudekit'),
(Join-Path $ProjectRoot '.claude'),
(Join-Path $ProjectRoot '.claudekit'),
(Join-Path $ProjectRoot '.codex'),
(Join-Path $ProjectRoot '.agentkit'),
(Join-Path $ProjectRoot '.agents\skills')
)
$BackupFull = [IO.Path]::GetFullPath($BackupRoot).TrimEnd('\') + '\'
foreach ($Root in $UnsafeRoots) {
$RootFull = [IO.Path]::GetFullPath($Root).TrimEnd('\') + '\'
if ($BackupFull.StartsWith($RootFull, [StringComparison]::OrdinalIgnoreCase)) {
throw "Choose a BackupRoot outside migration root: $Root"
}
}
New-Item -ItemType Directory -Path $BackupDir | Out-Null
$Identity = [Security.Principal.WindowsIdentity]::GetCurrent().Name
& icacls.exe $BackupDir '/inheritance:r' '/grant:r' ("{0}:(OI)(CI)F" -f $Identity) | Out-Null
if ($LASTEXITCODE -ne 0) { throw 'Could not restrict backup directory access.' }
$Copied = [Collections.Generic.List[object]]::new()
function Copy-BackupFile([string]$Source, [string]$Relative) {
if (Test-Path -LiteralPath $Source -PathType Leaf) {
$Destination = Join-Path $BackupDir $Relative
New-Item -ItemType Directory -Force -Path (Split-Path $Destination) | Out-Null
Copy-Item -LiteralPath $Source -Destination $Destination
$Copied.Add([pscustomobject]@{ Source = $Source; Relative = $Relative })
}
}
foreach ($Name in '.ck.json', 'settings.json', 'settings.local.json') {
Copy-BackupFile (Join-Path $ClaudeHome $Name) "user\claude\$Name"
Copy-BackupFile (Join-Path (Join-Path $HOME '.claudekit') $Name) "user\claudekit\$Name"
Copy-BackupFile (Join-Path (Join-Path $ProjectRoot '.claude') $Name) "project\claude\$Name"
Copy-BackupFile (Join-Path (Join-Path $ProjectRoot '.claudekit') $Name) "project\claudekit\$Name"
}
Copy-BackupFile (Join-Path $CodexHome 'config.toml') 'user\codex\config.toml'
Copy-BackupFile (Join-Path $CodexHome 'hooks.json') 'user\codex\hooks.json'
Copy-BackupFile (Join-Path $AgentKitHome 'config.yaml') 'user\agentkit\config.yaml'
Copy-BackupFile (Join-Path $AgentKitHome 'ownership.json') 'user\agentkit\ownership.json'
if ($ClaudeHome -ne $DefaultClaudeHome) {
Copy-BackupFile (Join-Path $DefaultClaudeHome '.ck.json') 'user\default-claude\.ck.json'
Copy-BackupFile (Join-Path $DefaultClaudeHome 'settings.json') 'user\default-claude\settings.json'
Copy-BackupFile (Join-Path $DefaultClaudeHome 'settings.local.json') 'user\default-claude\settings.local.json'
}
if ($CodexHome -ne $DefaultCodexHome) {
Copy-BackupFile (Join-Path $DefaultCodexHome 'config.toml') 'user\default-codex\config.toml'
Copy-BackupFile (Join-Path $DefaultCodexHome 'hooks.json') 'user\default-codex\hooks.json'
}
if ($AgentKitHome -ne $DefaultAgentKitHome) {
Copy-BackupFile (Join-Path $DefaultAgentKitHome 'config.yaml') 'user\default-agentkit\config.yaml'
Copy-BackupFile (Join-Path $DefaultAgentKitHome 'ownership.json') 'user\default-agentkit\ownership.json'
}
Copy-BackupFile (Join-Path $ProjectRoot '.codex\config.toml') 'project\codex\config.toml'
Copy-BackupFile (Join-Path $ProjectRoot '.codex\hooks.json') 'project\codex\hooks.json'
Copy-BackupFile (Join-Path $ProjectRoot '.agentkit\config.yaml') 'project\agentkit\config.yaml'
Copy-BackupFile (Join-Path $ProjectRoot '.agentkit\ownership.json') 'project\agentkit\ownership.json'
if ($Copied.Count -eq 0) {
throw 'No recognized settings files found; inspect the preview before apply.'
}
$Copied | ForEach-Object { "{0}`t{1}" -f $_.Source, $_.Relative } |
Set-Content -LiteralPath (Join-Path $BackupDir 'files.tsv')
foreach ($File in $Copied) {
$Destination = Join-Path $BackupDir $File.Relative
if (-not (Test-Path -LiteralPath $Destination -PathType Leaf)) {
throw "Missing backup file: $($File.Relative)"
}
if ((Get-FileHash -LiteralPath $File.Source).Hash -ne
(Get-FileHash -LiteralPath $Destination).Hash) {
throw "Backup verification failed: $($File.Relative)"
}
}
Write-Host "Verified $($Copied.Count) files in $BackupDir"Dòng cuối phải in Verified và đường dẫn đích. Nếu lệnh báo không tìm thấy file
được nhận diện, hãy dừng và kiểm tra bản xem trước thay vì coi thư mục rỗng là
một bản sao lưu. Các file đã chọn có thể chứa giá trị provider hoặc MCP nhạy
cảm. Hãy giữ thư mục ở máy cục bộ với quyền truy cập hạn chế; không upload hoặc
commit nó vào version control.
Danh sách này được giới hạn có chủ đích. Root Skill Codex tùy chỉnh, thư mục
plugin và nội dung Kit được chọn theo runtime, phạm vi, tuyến phân phối và bản
xem trước thực tế; chúng không phải root cấu hình chung cho mọi máy. Nếu bản xem
trước cho biết một đường dẫn hiện có khác sẽ bị archive, quarantine, neutralize
hoặc ghi đè, hãy sao chép riêng đúng đường dẫn đó vào thư mục backup rồi xác
minh bản sao. Đừng đoán bằng cách sao chép toàn bộ ~/.claude, ~/.codex,
~/.agentkit hoặc runtime home khác.
Bản sao do bạn tạo độc lập với recovery snapshot và journal riêng cho thao tác mà AgentKit ghi ngay trước các thay đổi của chính nó. Hai lớp phục vụ các đường khôi phục khác nhau. Không lớp nào là bản sao lưu toàn bộ máy; rollback migration chỉ khôi phục trạng thái đã ghi nhận, không dựng lại mọi thứ hoặc gỡ bản thay thế đã cài.
Áp dụng kế hoạch đã review
Để áp dụng, bắt buộc có cả --dry-run=false và --yes:
ak migrate --from=ck --dry-run=false --yesVới tuyến plugin project đã được review rõ ràng:
ak migrate --from=ck --switch-to-plugin --dry-run=false --yesTrước khi cài bản thay thế, AgentKit preflight mọi lượt cài Kit được yêu cầu. Thao tác chuyển các preference được hỗ trợ, archive hoặc quarantine các thư mục ClaudeKit được phép thay đổi, neutralize các bề mặt tích hợp có quyền sở hữu, giữ nội dung tùy chỉnh hoặc không rõ nguồn gốc và cài các Kit AgentKit tương ứng. AgentKit ghi trạng thái khôi phục trước khi thay đổi.
Khi chuyển preference, giá trị cấu hình AgentKit hiện có được ưu tiên. Giá trị
giống credential trong .ck.json của project bị bỏ qua để không đi vào
.agentkit/config.yaml của project. Giá trị giống credential trong
~/.claude/.ck.json ở user hoặc global có thể được chuyển vào config.yaml của
user khi AgentKit chưa đặt giá trị tương ứng. AgentKit ghi config kết quả với
mode 0600 trên hệ thống áp dụng quyền POSIX. Hãy review kế hoạch preference
trong dry run và giữ riêng tư output, file nguồn cùng config kết quả.
Nếu apply thất bại, migration mặc định có thể tiếp tục lại. Hãy đọc trạng thái được báo trước khi chọn chạy lại apply hay rollback.
Chỉ chuyển tùy chọn
Dùng luồng chỉ chuyển tùy chọn khi bạn chưa sẵn sàng chuyển nội dung Kit:
ak migrate prefs --dry-run
ak migrate prefs --dry-run=false --yesLuồng này sao chép các giá trị được hỗ trợ, giữ giá trị AgentKit hiện có, bỏ qua
giá trị giống credential ở project và có thể chuyển giá trị giống credential ở
user/global vào config user riêng tư. Luồng không xóa file .ck.json cũ.
Xác minh kết quả
Sau khi apply thành công:
- Đọc bản tóm tắt và xác nhận đúng runtime, phạm vi và các Kit đã cài.
- Mở lại runtime bị ảnh hưởng.
- Gọi một Skill quan trọng từ mỗi Kit đã chuyển.
- Review các instruction project và hook tùy chỉnh bạn muốn giữ.
- Giữ thông tin khôi phục của migration đến khi hoàn tất các bước kiểm tra.
Chỉ thấy file tồn tại không chứng minh hook đã được đăng ký hoặc đang chạy. Hãy xác minh hành vi quan sát được trong runtime trước khi gỡ nội dung legacy đã được giữ lại.
Rollback
Rollback bắt đầu ngay
ak migrate rollback không có dry run, prompt xác nhận, yêu cầu --yes,
--force hay selector cho journal. Lệnh lập tức reconcile trạng thái khôi phục
mới nhất và có thể hoàn tất việc xóa quarantine thay vì khôi phục nó.
Chỉ chạy rollback sau khi kiểm tra bản sao lưu độc lập và sao chép riêng công việc không liên quan được tạo sau migration:
ak migrate rollbackVới legacy transition, hành vi phụ thuộc phase đã ghi nhận. Trước khi bản cài
thay thế được chứng minh, rollback khôi phục quarantine đã ghi. Ở phase
installed hoặc finalize_pending, lệnh xác minh receipt của bản cài AgentKit,
sau đó finalize và xóa quarantine; lệnh không khôi phục ClaudeKit. Chỉ khi không
có legacy transition đang chờ, lệnh mới khôi phục generic file journal mới nhất.
Nếu không có cả hai trạng thái, lệnh báo không có gì để rollback và thoát thành
công.
Rollback chỉ xử lý trạng thái đã ghi nhận. Đây không phải thao tác hoàn tác có chọn lọc các chỉnh sửa về sau, không dựng lại toàn bộ môi trường trước apply và không gỡ bản thay thế AgentKit đã cài. Nếu không còn muốn bản thay thế, hãy preview rồi uninstall bằng đúng target, scope và delivery route.
Nếu migration bị gián đoạn
Trước tiên, chạy lại dry run mặc định. Nếu AgentKit báo có transition đang chờ, hãy chọn một đường khôi phục:
- Chạy lại apply đã review để thao tác có thể tiếp tục tự khôi phục và hoàn tất;
- Chạy
ak migrate rollbackđể khôi phục trạng thái đang chờ đã ghi nhận.
Journal đang chờ chặn một transition migration khác cho đến khi bạn tiếp tục
hoặc rollback thao tác hiện tại. Dry run thành công trả mã 0; source hoặc flag
không hợp lệ trả 2, hủy thao tác hoặc thiếu xác nhận apply trả 3, còn lỗi
runtime hoặc apply trả 1.
Chỉ dùng --force-unlock khi CLI báo rõ có migration lock cũ do process bị crash
để lại và không còn migration nào đang chạy. Flag này không xử lý xung đột file
và không thay thế quy trình rollback.