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

CLI Reference

ak update

Preview or apply project and global kit updates with drift-aware backups.

ak update refreshes AgentKit-owned project files or global kit installations while preserving user-owned content.

Syntax

ak update [project-dir] [options]
ak update --global [options]

Before you run

  • An implicit non-interactive preview exits 3. Add --dry-run for an explicit preview that exits 0, or --yes to apply.
  • A bare command in a TTY opens a unified wizard. Each CLI, global-kit, and project-kit update defaults to no; --yes accepts applicable steps.
  • Remote preview can still authenticate, check entitlements, download kit content, and update the cache before it calculates the plan.
  • --force authorizes replacement only after a snapshot unless --no-backup is set. It does not turn global installation into unconditional overwrite.
  • --json, --quiet, --no-interactive, or a non-TTY selects scripted behavior. In an interactive project or global run, declining every prompt exits 0.
  • An attended project update (TTY accept or --yes) refreshes the tracked kits/ tree, then every installed runtime of each project kit. See Project runtime refresh.

Arguments

[project-dir] selects a project. Without it, project mode discovers the current project unless --global is set. The command has no aliases.

Runtime targets and sources

Target validation uses both the selected scope and source:

Scope and sourceValid targets
Project, remoteclaude-code, codex, cursor, dsh, grok, omp, or pi
Global, remoteclaude-code, codex, cursor, dsh, grok, or omp
Global, localclaude-code, codex, cursor, dsh, grok, or omp

An explicit target that does not apply to its scope or source is rejected before discovery or mutation and exits 2. In the unified wizard, the same selection is projected onto each step: a project-only target such as pi is omitted from the global step but remains available to the project step. If no selected target applies globally, the wizard skips that step and continues.

In both scopes, --target a,b filters which installed runtimes refresh; unset means every installed runtime. A requested runtime that has no install in that scope is listed under skipped_targets rather than created. At project scope the tracked kits/ tree still comes from one runtime's download: claude-code when it is selected, installed, or nothing is selected; otherwise the first selected runtime.

Project runtime refresh

After the tracked kits/ tree, an attended project update refreshes every installed runtime of each project kit (.claude, .codex, and adapter roots) through the same path as ak kit refresh, one pass per kit and runtime. The kits it considers are the --kits list when given, otherwise the kits tracked in kits/ plus every kit with an owned project install.

  • A failed pass does not stop the others. Each pass reports its own row, and the command exits 1 after all passes finish.
  • A project that has only ak kit init runtime installs, with no tracked kits/ tree, refreshes those installs instead of exiting 2.
  • Preview and --dry-run list each planned refresh as a preview row and write nothing.
  • The CLI preflight takes the highest kit CLI requirement across the selected runtimes.
  • A project Claude Code plugin install is reported as plugin_only, not converted. Refresh it with ak kit refresh <kit> --target claude-code --switch-to-plugin --yes.
  • A runtime the remote source does not serve is skipped with reason source_inapplicable; re-run with --local --kits-dir <dir>.
  • When the project directory resolves to the user-level install (for example, the home directory), that runtime is skipped with reason project_is_global_home and never refreshed. Run ak update --global to refresh it.
  • If --target matches no installed project runtime and there is no tracked kits/ tree, the command exits 2.

Background auto-update (opt-in)

--schedule daily|weekly turns on a detached background update that starts on the first ordinary ak command after the chosen interval; --schedule off stops it and clears its state. It refreshes the CLI and global kits, plus any project opted in with --project <dir> (repeatable; the directory must already be registered with ak projects add) whose git tree is clean and has no live agent session. A background project update refreshes only the tracked kits/ tree; it never refreshes project runtime installs. It records a notice to run ak update <dir> --yes or ak kit refresh <kit> instead. --no-project <dir> (repeatable) opts a project back out, even if its directory no longer exists. --status [--json] reports the schedule and the last background result without changing anything; add --ack to mark that result as seen.

These settings flags only write the auto_update: section of ~/.agentkit/config.yaml — they update nothing immediately, and none of --schedule, --project, --no-project, --status, or --ack can be combined with an update flag (--kits, --force, --global, …) or a project-dir argument; run them as separate commands.

A background update never starts when AK_NO_AUTO_UPDATE=1 or CI is set, for --json invocations, or for lifecycle/interactive top-level commands (update, self-update, setup, onboard, kit, init, migrate, backups, recover, gui, uninstall, completion, help, bootstrap*). Liveness is tracked by a Kit hook (session-heartbeat.cjs) registered on SessionStart, UserPromptSubmit, Stop, and SessionEnd; it writes a per-session marker under the AgentKit home so the updater skips a project that has a running session, and it never blocks or fails a session (exits 0 on its own failure). On SessionStart, an unacknowledged background result prints as a one-line notice; acknowledge it with ak update --status --ack --json. See ak doctor's auto_update check for schedule, stuck-run, and opted-in-project diagnostics.

Options

OptionDefaultPurpose
--ackfalseWith --status: mark the last background auto-update result as seen.
--backupfalseSnapshot the whole project, not only the files the refresh changes; backups.enabled: true in ~/.agentkit/config.yaml makes this the default.
--betafalseInclude beta CLI self-update behavior.
--channel <channel>Receipt channel, then kit.channel, then stableSelect the kit channel for this request only; the value is not saved.
--dry-runfalsePreview without project or global installation writes.
--forcefalseAuthorize drift replacement after backup unless --no-backup.
-g, --globalfalseUpdate global kit installations.
--kits <names>EmptyLimit the comma-separated kit selection.
--kits-dir <path>EmptyRead kits from a local directory.
--localfalseUse the local kit source.
--no-backupfalseSkip pre-update recovery snapshots, including the one --force takes (power users only — data loss risk).
--no-project <dir>EmptyRemove a project from background auto-update, even if its directory is gone (repeatable).
--project <dir>EmptyOpt a project registered with ak projects add into background auto-update (repeatable).
--registry-url <url>EmptyOverride the registry URL.
--remotetrueUse the remote registry.
--runtime <runtime>claude-codeAlias of --target; select runtime(s) from the scope-and-source matrix above. The default is not an explicit selection.
--schedule <daily|weekly|off>EmptySet or clear the background auto-update schedule (settings only; updates nothing now).
--show-difffalseInclude file diffs in the plan.
--statusfalseShow the background auto-update schedule and last result (read-only).
--target <target>EmptyComma-separated runtime(s) from the scope-and-source matrix above; unset means all installed runtimes. Pass only one of --target or --runtime.
--version <version>EmptyPin a kit version.

Examples

Preview a project update with a successful preview status:

ak update . --dry-run --show-diff

Apply a project update without prompting:

ak update . --yes

Refresh only the Claude Code and Codex installs of a project:

ak update . --target claude-code,codex --yes

Preview global updates:

ak update --global --dry-run --kits core --runtime claude-code
ak update --global --dry-run --kits core --local --kits-dir ./kits --target grok

Turn on background auto-update and check its status:

ak update --schedule daily --project .
ak update --status --json

Output and streams

With --json, stdout uses the shared envelope with "kind": "update". Project data includes project_dir, files_updated, files_skipped, files_new, and dry_run; it can also include snapshot fields, backup_skipped, skipped, diffs, project_config, project_config_created, and scope. When the project has runtime installs, it also includes kits (one row per kit and runtime pass) and skipped_targets (requested runtimes with no project install).

Global output also includes locations, kits, and skipped_targets. Each Kit result can report kit, runtime, status, channel, reason, error, why, next, snapshot fields, locations, and warnings. The global envelope can also report backup_skipped. A selected runtime that is not installed globally is reported as skipped rather than created.

An unfiltered remote global run may discover an existing local-only install. It reports that install with status: "skipped" and reason: "source_inapplicable" instead of changing sources implicitly. Follow its next guidance and run ak update --global --local --kits-dir <dir> to refresh from an explicit local source. An explicit source-incompatible target is an exit-2 validation error, not a source_inapplicable result.

An implicit JSON preview prints a success envelope to stdout and then exits 3. Command errors, including flag-parse errors (exit 2), write the shared error envelope to stderr.

Human and JSON execution errors show the recovery reason without requiring --verbose. Default disclosed errors redact known secret shapes and URL query strings while preserving paths. A global Kit result that completes with an attention item also shows its sanitized reason in human output without --verbose; this does not turn that result into a failed update.

--verbose can expose raw execution errors and full warning lists. Review diagnostics before sharing them.

Exit status

CodeMeaning
0Update applied, explicit dry-run completed, or an interactive prompt was declined.
1Runtime, lifecycle, source, snapshot, write, partial global update, or a project runtime refresh pass failed; for the auto-update settings and --status --ack, also an I/O failure or a busy state file.
2Flags, scope, source, target, or eligible global installation selection is invalid; at project scope, there is no tracked kit and no runtime install, or --target matches no project runtime install; for the auto-update settings, also an invalid --schedule, an unregistered --project, or a settings flag combined with an update flag or a project-dir argument.
3A non-interactive implicit preview requires --yes to apply.

Effects, safety, and recovery

Project updates classify owned files. Clean files can be replaced; modified or newly occupied files are skipped unless --force is used. Apply also prunes AgentKit-owned files under kits/<id>/ that the incoming source no longer ships, and only for kits present in that incoming set. Clean and already-missing copies are removed; a user-modified copy is preserved and reported unless --force is set. A path that is no longer a regular file is left in place. Empty directories left inside the kit tree are removed; the kit root is not.

By default, apply snapshots only the exact files it writes or prunes — a restorable bundle authorized by its project root (--allow-root), whose result includes the restore command. --force, --backup, or backups.enabled: true in ~/.agentkit/config.yaml instead captures the whole project; --backup does not widen global kit refresh snapshots. --no-backup skips every snapshot, including the one --force takes, and warns on stderr; --force --no-backup adds an escalated warning. Structured results report backup_skipped so a missing snapshot_id is not enough to tell an intentional skip from a no-op. Desktop plan apply that keeps user content takes the same exact-file capture unless user content is overwritten or backups.enabled is set, in which case it captures the whole project; it does not accept --no-backup. Some files outside its restore scope require manual recovery; follow snapshot_data_dir when reported. A missing project config can be created before classification and snapshot, even if a later step fails.

Writes are sequential, so an error can leave a partial update. Global updates continue across kits, report per-kit failures, and can create a support bundle under ~/.agentkit/support. Global force mode may archive authorized legacy Codex skills, but it still preserves user modifications. Project --force never archives legacy ClaudeKit Codex skills: a project runtime pass that finds them reports a skipped row with reason needs_legacy_migration. Run ak migrate --from ck from the project directory, then re-run the update. Archival through --force remains a --global --force consent.

On Windows, ak update applies the signed CLI replacement in place under an exclusive update lock, validates the running binary preimage, then re-executes the original command inside a Windows Job Object so Kit refresh continues on the first invocation. Standalone ak self-update still uses the staged detached helper handoff. Paired Desktop apply stages the matching CLI and Desktop artifacts, then a trusted helper commits the swap after the parent process releases the executables.

Use ak new for a new project and ak uninstall to remove owned files. After a partial failure, ak doctor can filter dedicated suites only for claude-code, codex, and cursor; any other --adapter value is invalid and exits 2. See CLI conventions for shared flags.