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"],
  "skills": {
    "find-skills": "https://github.com/vercel-labs/skills.git#path:/skills/find-skills",
    "my-local-skill": "file:./local-source#path:/skills/my-local-skill"
  }
}

Field descriptions:

  • installDir: The directory where materialized skills are written.
  • linkTargets: A list of target directories where symbolic links should be created.
  • 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-...

It typically contains:

  • The resolved source type: git or file
  • A specific commit or local content digest
  • The skill path
  • The final content digest

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. When using local skills for internal development, keep the lockfile as well to track digest changes

Specifier Compatibility

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

  1. Source must match: The git URL or file path 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).