skill-set

CLI reference

The CLI ships as @skill-set/cli with a single bin, skill-set. Run it without installing via npx.

npx @skill-set/cli <command> [args] [flags] [-- <args for the skills CLI>]

Resolution and installation of individual skills are delegated to the upstream skills CLI, pinned to skills@1.5. skill-set --version prints both versions:

skill-set/<version> (wraps skills@1.5, pinned)

Commands#

CommandUsageDoes
initinit <set> <locator> [locators...]Scaffold a new set manifest
addadd <url|path>Fetch a shared set manifest, then install it
installinstall <set>Install members, skipping ones the lock already satisfies
buildbuild [<set>] [--lock]Regenerate SKILL-SET.md files and the skill-sets.json index
locklock <set>Record each member’s installed content in a set-lock
shareshare [<set>] [--manifest <path>] [--output <dir>]Export a shareable manifest and lock
verifyverify <set> [--frozen]Check installed members against the set (frozen: byte-exact)
updateupdate <set>Update members via the skills CLI, then re-lock
removeremove <set>Remove a set definition, optionally remove skills not otherwise in use

init#

skill-set init <set> <locator> [locators...]

Scaffolds .agents/skills/skill-sets/<set>/<set>.skill-set.json at version 0.1.0 with the given members, then offers to install them and generate the set files. At least one locator is required — a skill-set cannot be empty. Set names are lowercase alphanumerics with single hyphens, at most 64 characters. If a set of that name already exists, init fails; it never overwrites a set definition.

add#

skill-set add <url|path>

Acquires a shared set: fetches the manifest (HTTPS only; at most 5 redirects; 1 MiB response cap) or reads a local path, validates it against the schema and rules, prints the set summary with every member and its source, then asks for confirmation before writing anything. The fetched bytes are written verbatim as <name>.skill-set.json — the filename comes from the manifest’s name — and the normal install flow runs.

Hosts other than recognised skill-set providers prompt for confirmation before any bytes are fetched, and redirects may not hop to a new host. An existing set with the same name is an error, never a silent overwrite.

install#

skill-set install <set>

Before anything installs, every set in the project is checked for members pinned to conflicting refs — a conflict aborts with exit code 4 (see the FAQ). Members whose locked content is already on disk byte-for-byte are skipped; the rest resolve one at a time through npx skills@1.5 add <locator>. The summary reports installed, skipped, and failed counts, and any member failure makes the whole command fail after attempting the rest.

build#

skill-set build [<set>] [--lock]

Regenerates the derived files for one set, or for all sets when no name is given: a SKILL-SET.md discovery page per set (frontmatter, member table, install and provenance sections) and the project-wide skill-sets.json index. Output is deterministic — identical inputs produce identical bytes. --lock also records the set-lock, exactly as lock does.

lock#

skill-set lock <set>

Writes <set>.skill-set.lock.json: for every member, the installed skill name, its content hash (SHA-256 over the skill folder, as defined by the spec), and the resolver-reported source and ref, plus a rollup setHash for the whole set. Every member must be installed first; missing members are reported all at once.

share#

skill-set share [<set>] [--manifest <path>] [--output <dir>]

Prepares a set for distribution. It takes a local set by name or a hand-written manifest (--manifest), and offers to fill in any missing description, author, and homepage. Every member is re-fetched into a throwaway clean project and hashed there, so the exported set-lock records the content the locators actually deliver — not your local, possibly-edited skill folders. A notice names any installed skill that differs from the fetched content, and members with local-only sources cannot be shared and are reported.

The manifest and lock are written to .agents/skills/skill-sets/_share/<set>/ (or --output <dir>). Publish the two together so a recipient’s add finds the sidecar lock, or hand out a validating install command carrying the #sha256=<setHash> fragment.

verify#

skill-set verify <set> [--frozen|--no-frozen]

Two modes:

In CI, frozen is the default whenever a set-lock exists; --no-frozen opts out. See verifying in CI.

update#

skill-set update <set>

Updates every member through npx skills@1.5 update <skills...> -p --yes, then re-locks the set if a lock existed and regenerates the derived files. All members must be installed before anything updates.

remove#

skill-set remove <set>

Removes the set definition — manifest, lock, and generated page — after confirmation, and refreshes the index. It then offers to also remove the set’s member skills, keeping any skill still referenced by another set (reference-counted, including by shared source). Skill removal is delegated to npx skills remove so the upstream lock stays consistent.

Global flags#

FlagEffect
--jsonMachine-readable output: exactly one JSON object on stdout
--yes, -yAssume yes for prompts (required where a prompt would block CI)
--dry-runPrint what would run or be written; change nothing, spawn nothing
--help, -hShow help
--version, -vShow the skill-set version and the pinned skills version

Arguments after -- pass through to the skills CLI verbatim, for example:

skill-set install demo -- --agent claude-code cursor

installs the set’s skills for those agents only. See npx skills --help for what the upstream accepts.

JSON output#

With --json, every run — including crashes — emits exactly one JSON envelope on stdout:

{ "ok": true, "command": "verify", "data": { "name": "frontend", "mode": "frozen", "checked": 4 } }
{
  "ok": false,
  "command": "install",
  "error": {
    "code": "ERR_SKILLSET_CONFLICT",
    "message": "…",
    "hint": "…",
    "data": {}
  }
}

error.code is a stable machine-readable code; hint and data appear when available.

Exit codes#

CodeMeaning
0Success
1Error — anything not covered below
2Usage — bad arguments, a prompt blocked without --yes, or verify --frozen without a set-lock
3Drift — frozen verify found installed content that does not match the set-lock
4Conflict — a member source pinned to different refs across sets