Skip to content

update command

FieldValue
Slugcmd-update
Statusimplemented
Last review2026-08-10

Summary

skli update refreshes installed Packages with source=repos by resolving a newer (or current) version from the remote repository, emptying each target install path, re-copying files, and updating Manifest version when it changes. Packages with source=local are skipped (broad filters) or rejected (explicit id).

Also refreshes linked packages from ProjectManifest links: re-fetch the remote ProjectManifest, resolve selected packages (includeAll / includes), copy with empty-first, bump link.version, and when includeAll install newly appeared remote packages.

Also supports targeting a Package by its install path (IDE layout path), optional --version to pin a specific ref on single-Package updates, and optional --gitignore to record destinations in the project .gitignore.

User flows

Flow-01 — Update all repos Packages

Persona: developer.
Preconditions: ProjectManifest present (project scope); at least one source=repos entry (optional).

StepActionExpected resultError
1skli update --allEvery repos Package for all its ides re-resolved, destinations emptied then copied; version updated when resolved version differsMissing ProjectManifest (project scope); gh / network
2Resolved version equals pinned versionSkip that Package (message); continue; exit 0
3No matching repos PackagesInformative message; exit 0

Flow-02 — Filter by IDE(s)

StepActionExpected resultError
1skli update cursor,claude --allOnly repos entries whose ides intersect the selector; copy only into intersection dirsInvalid IdeId

Flow-03 — Filter by kind

StepActionExpected resultError
1skli update cursor skill --allAll repos skills targeting cursor (intersection)Invalid kind
2skli update all rule --allAll repos rules for all IDEs in each entry

Flow-04 — Single Package id

StepActionExpected resultError
1skli update cursor skill arcade-bootstrapThat id only; empty dest + copy; bump version if newerMissing id; source=local; id not targeting selected IDE(s)

Flow-05 — Global scope

StepActionExpected resultError
1skli update --all --globalSame selection against GlobalManifest; copy to global IDE dirs

Flow-06 — Target by install path

StepActionExpected resultError
1skli update .cursor/skills/arcade-bootstrapResolve path → ide/kind/id via ide-targets; same as update cursor skill arcade-bootstrapUnmatched path; missing Manifest entry; source=local
2skli update .claude/rules/foo.mdcResolve to claude/rule/foo

Flow-07 — Explicit --version

Preconditions: Single Package targeted (<ide\|all> <kind> <id> or install path).

StepActionExpected resultError
1skli update cursor skill arcade-bootstrap --version v0.1.7Fetch/pin that ref (no latest resolution); Manifest version = v0.1.7 when changedInvalid with --all / multi-select; ref invalid for entry versioning
2Already pinned to that versionSkip (message); exit 0

Flow-08 — Gitignore after update

StepActionExpected resultError
1skli update cursor skill arcade-bootstrap --gitignoreAppend project-relative destinations under # Ignored AI IDE references (also when refresh is skipped as already at version)--gitignore with --global

Flow-09 — Linked manifests

Preconditions: ProjectManifest with a links entry; project scope (links are not global).

StepActionExpected resultError
1skli update --allPackageEntry repos refresh and each matching link: resolve newer version; fetch remote ProjectManifest; copy selected packages (includeAll or includes); update link.version; with includeAll, also copy new remote packagesgh / network
2skli update cursor skill foo when foo is only linked (not in Package maps)Refresh that linked skill into intersecting IDE dirsMissing if neither map nor links
3Link already at resolved versionSkip link bump; still no-op for packages already at that pin unless restore semantics

Data model

Package entry: config-manifests. Link entry: same. Paths: ide-targets. Version resolve: same as install via resolveInstallRef without Source ref (cmd-install BR-013/014), unless --version supplies an explicit ref.

Fields preserved on PackageEntry: path, repos, versioning, ides, includeReferences. Field updated: version when the resolved (or explicit) version differs.

On LinkEntry: version updated when resolved version differs; selection fields preserved (includeAll / includes); with includeAll, newly discovered remote ids are included in the sync without rewriting includes.

.gitignore behavior matches cmd-install BR-017/018 (all IdeId destinations from the refresh intersection).

CLI

skli update --all [options]
skli update <ide> --all [options]
skli update <ide|all> <kind> --all [options]
skli update <ide|all> <kind> <id> [options]
skli update <install-path> [options]

Arguments (depending on form):
  ide            IdeId CSV, or literal all (all IDEs) when kind is present
  kind           PackageKind: skill | rule | agent
  id             Package id (Manifest map key)
  install-path   Project- or global-relative path under an IdeId layout (e.g. .cursor/skills/arcade-bootstrap)

Options:
  -g, --global         Use GlobalManifest and global IDE dirs
  --debug              Diagnostic logs (stderr)
  --all                Select all matching Packages (required unless <id> or <install-path> is given)
  --version <ref>      Single Package only: fetch and pin this ref
  --gitignore          Project scope: add refreshed destinations to `.gitignore`

Invalid combinations (e.g. --all with <id>, <id> without <kind>, no --all and no <id>/<install-path>, --version with --all, --gitignore with --global) → error, exit ≠ 0.

Business rules

IdRule
BR-cmd-update-001Only Packages with source=repos are updated.
BR-cmd-update-002Broad selection (--all forms): skip source=local silently. Explicit <id> or path with source=local → error.
BR-cmd-update-003Project scope: ProjectManifest required (init). --global: GlobalManifest.
BR-cmd-update-004IDE filter: entry matches if ides intersects selected IDEs; copy only to intersection dirs. Selector all or omitted (update --all) = no IDE filter (all ides on each entry).
BR-cmd-update-005Kind filter: when <kind> present, only that PackageKind map.
BR-cmd-update-006Without --version: resolve fetch ref via entry versioning with no Source ref (latest tag / default branch / etc., same as install).
BR-cmd-update-007If resolved (or explicit) version equals entry version, skip fetch/copy for that Package.
BR-cmd-update-008Before copy: remove destination path (directory or file) then copy — no partial merge.
BR-cmd-update-009Skill with includeReferences === false: exclude root references/ from copy (same as install --no-references).
BR-cmd-update-010On successful refresh with a new version: write updated version on the entry; other fields unchanged.
BR-cmd-update-011Explicit <id> or path target missing from Manifest → error. Explicit target with no IDE intersection → error.
BR-cmd-update-012--all and <id> / <install-path> are mutually exclusive.
BR-cmd-update-013Single-arg path form: resolve against all IdeId layouts (ide-targets); equivalent to update <ide> <kind> <id> for the matched IDE. Skill → directory basename as id; rule/agent → file basename without extension.
BR-cmd-update-014--version <ref> only with a single Package target (<ide|all> <kind> <id> or <install-path>). Pin/fetch that ref (validate per entry versioning); do not resolve “latest”. Incompatible with --all / incomplete multi-select forms.
BR-cmd-update-015--gitignore project-scoped only (error with --global); for each matched Package (updated or skipped as already at version), append destinations per cmd-install BR-018.
BR-cmd-update-016Project scope: also refresh matching links entries (resolve newer version; sync selected remote packages; bump link.version). Global scope: PackageEntry only (no links).
BR-cmd-update-017Linked package selection: includeAll ⇒ all ids of that kind in the remote ProjectManifest at the fetch ref; else includes.
BR-cmd-update-018Explicit <id> missing from Package maps but present under a matching link ⇒ treat as linked package refresh. Missing from both ⇒ error.

User scenarios

npx @zortracks/skli update --all upgrades every repos Package in the project Manifest to the latest tag (when versioning=tag).
npx @zortracks/skli update cursor skill arcade-bootstrap upgrades that skill into Cursor dirs only (intersection).
npx @zortracks/skli update .cursor/skills/arcade-bootstrap same as the previous command via path.
npx @zortracks/skli update cursor skill arcade-bootstrap --version v0.1.7 pins that tag.
Already at target version → skip message, exit 0.

Dependencies

Out of scope

  • Updating source=local Packages.
  • Changing an entry’s versioning mode.
  • list.
  • Uninstall — see cmd-remove / cmd-unlink.

Acceptance criteria

  • [x] Four filter CLI forms documented above work for update.
  • [x] Install-path form resolves via IdeId layouts and updates the matching Package.
  • [x] --version pins a single Package; rejected with --all.
  • [x] --gitignore appends destinations (all IdeIds in the refresh); errors with --global.
  • [x] Only source=repos Packages are refreshed; local skipped or rejected per BR.
  • [x] Destination emptied before copy.
  • [x] Manifest version updated when resolved version differs; skipped when equal.
  • [x] --global and --debug supported.
  • [x] Listed in skli --help.
  • [x] Linked manifests (links) refreshed on project-scope update.

Terminology

See domain-glossary. CLI ide selector all is not an IdeId.

Implementation notes

src/commands/update.ts, shared refresh in src/lib/refresh-package.ts / src/lib/refresh-cli.ts; path resolve via src/lib/ide-targets.ts (or helper); src/lib/gitignore.ts; reuses resolveInstallRef, fetchGitHubPathToTemp, Manifest helpers.

Released under the MIT License.