AgentKit
DocsKitsCLI ReferenceDesktop App

ak skills

ak skills sync

Project every skill pinned in the skill lock at exactly its locked digest, without upgrading or changing the pins.

Use ak skills sync --locked to make the installed skills match the skill lock for a scope. Each locked package is projected at exactly its locked digest. The command never upgrades a skill and does not change what the lock pins.

Usage

ak skills sync --locked [flags]

The command accepts no positional arguments. --locked is required; without it the command exits 2 with a usage error.

Options

FlagDefaultDescription
--lockedfalseRequired. Confirms the sync follows the lock and never upgrades.
--scope <scope>projectSelect project or global.
--runtime <list>Runtimes whose receipt records a user owner, else claude-codeRepeatable or comma-separated, such as claude-code,codex.
--dry-runfalsePlan the changes and report them without writing.

Shared flags are described in CLI conventions.

Requirements

Both SkillX and the skill store must be on: after ak update --ssot, or with each variable set to exactly 1.

SettingEffect
AGENTKIT_SKILLX=1Enables SkillX release-state checks.
AGENTKIT_SKILL_STORE=1Enables the content store the packages are projected from.

If either is off, the command exits 2.

What it reads and writes

ItemLocation
Project lock.agentkit/skill-state/skill-lock.json
Global lockAGENTKIT_HOME/state/skill-lock.json
Project Claude Code skills<project>/.claude/skills
Global Claude Code skills<claude home>/skills
Codex skillsResolved by the Codex adapter

The command applies without a prompt. It reads the scope's skill lock and never writes it: no locked digest changes. It writes the verified release into the skill store, the projected files into each runtime's skills root, removing stale ones, the scope's receipts, and, for a project, the project root registry under AGENTKIT_HOME/state and the project skill state .gitignore. It never runs declared scripts, npm, npx, or SkillX installers. Projected files have mode 0644 and are never executable.

  • An intact, already projected package needs no network.
  • Offline, a package with a verified store copy still installs, with an offline_stale warning. A package without a copy fails with source.offline and nothing changes.
  • A digest that does not match the lock fails with store.digest_mismatch.

The sync is one journaled transaction under the kit lifecycle lock, which waits 10 seconds before reporting busy. It refuses a lock that changed during the run, and it refuses project state that is not recorded in the root registry, treating it as untrusted. Preview with --dry-run first on a project you did not create.

Output

JSON uses kind=skills.sync with these fields under data:

operation, scope, dryRun, applied, changed, planDigest
lockPath, lockGeneration
packages[]: identity, version, releaseDigest, trust, exposure, alias, host,
            keyId, manifestDigest, declaredScripts, executable (false), fromStore
targets[]: runtime, root, rootIdentity, alias, action, projectionDigest,
           writes, removes, preserved
warnings[]

A target action is create, replace, co-own, repair, unchanged, remove, or release.

Exit behavior

ExitMeaning
0The sync succeeded or there was nothing to change.
1Offline without a verified copy, a credential was refused, a path was too long, or recovery is required.
2SkillX or the store is disabled, flags or arguments are invalid, or an alias is reserved.
4The kit lifecycle lock is held by another operation.
5A release was not found or not entitled.
6Alias collision, an unowned or modified path, untrusted project state, or the lock changed during the run.
7A release is revoked, yanked, quarantined, or untrusted, a link sits in a target path, or a digest mismatched.