Manifest and lockfile

skills-package-manager uses two files to describe and lock the installed state of skills.

skills.json

skills.json is a declarative manifest that describes which skills a project needs and where they should be installed.

{
  "installDir": ".agents/skills",
  "linkTargets": [".claude/skills"],
  "selfSkill": false,
  "patchedSkills": {
    "find-skills": "patches/find-skills.patch"
  },
  "skills": {
    "find-skills": "https://github.com/vercel-labs/skills.git#path:/skills/find-skills",
    "my-local-skill": "link:./local-source/skills/my-local-skill",
    "my-existing-skill": "local:./.agents/skills/my-existing-skill",
    "my-packed-skill": "file:./skills-package.tgz#path:/skills/my-packed-skill",
    "my-npm-skill": "npm:@scope/skills-package#path:/skills/my-npm-skill"
  }
}

Field descriptions:

  • installDir: The directory where managed skills are written.
  • linkTargets: A list of target directories where symbolic links should be created.
  • selfSkill: Whether to auto-install the bundled skills-package-manager-cli skill during install. It is not written to skills-lock.yaml. Defaults to false.
  • patchedSkills: Optional mapping from skill name to a committed patch file path.
  • skills: A mapping from skill name to specifier.

skills-lock.yaml

skills-lock.yaml locks resolved results so installations produce consistent content across different machines and points in time.

lockfileVersion: "0.1"
installDir: .agents/skills
skills:
  find-skills:
    specifier: https://github.com/vercel-labs/skills.git#path:/skills/find-skills
    resolution:
      type: git
      url: https://github.com/vercel-labs/skills.git
      commit: abc1234...
      path: /skills/find-skills
    digest: sha256-...
    patch:
      path: patches/find-skills.patch
      digest: sha256-...

It typically contains:

  • The resolved source type: git, link, local, file, or npm
  • A specific commit, local content digest, tarball reference, or resolved package version and integrity
  • The skill path
  • The final content digest
  • Optional patch path and patch digest metadata

Why both exist

  • skills.json captures the team-maintained intent.
  • skills-lock.yaml captures the installer-resolved result.

The former is suitable for review; the latter is suitable for reproducibility.

  1. Always commit both skills.json and skills-lock.yaml
  2. Standardize installDir and linkTargets across the team
  3. Prefer explicit GitHub specifiers with path: for external skills
  4. Use local: for existing user-owned skill directories that should not be copied or replaced

Specifier Compatibility

When comparing manifest and lockfile specifiers (e.g., with npx skills-package-manager install --frozen-lockfile), the following rules apply:

  1. Source must match: The git URL, local path, tarball path, or npm source must be identical
  2. Path must match: The skill path within the repository must be identical
  3. Ref compatibility:
    • Manifest without ref → compatible with any lock ref (use lock version)
    • Manifest with ref → must match lock ref exactly

This means you can omit the commit SHA in skills.json:

{
  "skills": {
    "my-skill": "https://github.com/owner/repo.git#path:/skills/my-skill"
  }
}

And the lockfile will pin the exact version:

skills:
  my-skill:
    specifier: https://github.com/owner/repo.git#abc1234&path:/skills/my-skill
    resolution:
      type: git
      url: https://github.com/owner/repo.git
      commit: abc1234...
      path: /skills/my-skill

The --frozen-lockfile flag will accept this combination because the manifest specifier (without ref) is satisfied by the lockfile specifier (with resolved commit).