feat: remove skills lockfile persistence#33
Merged
Conversation
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
skills-package-manager | f2dadfb | May 18 2026, 11:40 AM |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR shifts skills-package-manager from lockfile-backed installs to skills.json as the only user-facing manifest and pin source, updating core install/update/add/patch flows, pnpm integration, tests, and documentation around in-memory install plans and install state.
Changes:
- Removes skills lockfile read/write/frozen behavior and replaces lock entries with resolved in-memory install plans.
- Updates CLI behavior for pinned
github:/npm specifiers, repeated--skill,--list,--all, and removed--frozen-lockfile. - Refreshes tests, website docs, README content, and pnpm plugin docs/tests for the manifest-only model.
Reviewed changes
Copilot reviewed 69 out of 69 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
AGENTS.md |
Updates contributor guidance terminology from lockfiles to manifest/install state. |
README.md |
Updates top-level marketing/docs for single-manifest workflow. |
skills.json |
Updates schema version and pins GitHub skills with github: specifiers. |
skills-lock.yaml |
Removes checked-in lockfile. |
packages/pnpm-plugin-skills/README.md |
Updates plugin docs for in-memory install plans. |
packages/pnpm-plugin-skills/src/index.ts |
Renames pnpm lockfile variables and keeps install hook behavior. |
packages/pnpm-plugin-skills/test/index.test.ts |
Updates plugin test to install from skills.json only. |
packages/skills-package-manager/README.md |
Updates package CLI/API docs for manifest pins and new add flags. |
packages/skills-package-manager/skills/skills-package-manager-cli/SKILL.md |
Updates bundled helper skill docs for manifest-only workflow. |
packages/skills-package-manager/src/cli/runCli.ts |
Adds add-command compatibility flags and removes install frozen-lockfile option. |
packages/skills-package-manager/src/commands/add.ts |
Pins resolved add specifiers and supports list/all/repeated skill flows. |
packages/skills-package-manager/src/commands/install.ts |
Resolves manifest to an install plan and runs the pipeline without writing lockfiles. |
packages/skills-package-manager/src/commands/patch.ts |
Resolves patch base content from install plans. |
packages/skills-package-manager/src/commands/patchCommit.ts |
Reinstalls patched skills from resolved plans and stops writing lockfiles. |
packages/skills-package-manager/src/commands/update.ts |
Updates remote pins in skills.json after successful install. |
packages/skills-package-manager/src/config/compareSkillsLock.ts |
Removes lockfile comparison logic. |
packages/skills-package-manager/src/config/readSkillsLock.ts |
Removes lockfile reader. |
packages/skills-package-manager/src/config/resolveSkillsPlan.ts |
Replaces lock sync with resolved install plan generation. |
packages/skills-package-manager/src/config/types.ts |
Renames lock entry types to resolved plan types and updates command options/results. |
packages/skills-package-manager/src/config/writeSkillsLock.ts |
Removes lockfile writer. |
packages/skills-package-manager/src/errors/codes.ts |
Removes lockfile-specific error codes. |
packages/skills-package-manager/src/errors/index.ts |
Removes lockfile-specific display guidance. |
packages/skills-package-manager/src/errors/types.ts |
Narrows manifest errors to manifest-only operations. |
packages/skills-package-manager/src/fetchers/file.ts |
Updates fetcher typing to resolved skill entries. |
packages/skills-package-manager/src/fetchers/git.ts |
Updates git fetcher typing to resolved skill entries. |
packages/skills-package-manager/src/fetchers/index.ts |
Updates fetch dispatcher typing to resolved skill entries. |
packages/skills-package-manager/src/fetchers/link.ts |
Updates link fetcher typing to resolved skill entries. |
packages/skills-package-manager/src/fetchers/local.ts |
Updates local fetcher typing to resolved skill entries. |
packages/skills-package-manager/src/fetchers/npm.ts |
Updates npm fetcher typing and cache cleanup comment. |
packages/skills-package-manager/src/github/listSkills.ts |
Expands hidden directories scanned for skills. |
packages/skills-package-manager/src/index.ts |
Updates public exports for plan APIs and removes lockfile APIs. |
packages/skills-package-manager/src/install/extractSkillToDir.ts |
Updates extraction typing to resolved skill entries. |
packages/skills-package-manager/src/install/installPlan.ts |
Adds install-plan stage hooks. |
packages/skills-package-manager/src/install/installSkills.ts |
Simplifies legacy install wrapper to delegate to installCommand. |
packages/skills-package-manager/src/install/localSkills.ts |
Updates local-skill helpers to operate on resolved plans. |
packages/skills-package-manager/src/install/withBundledSelfSkillLock.ts |
Removes self-skill lockfile injection helper. |
packages/skills-package-manager/src/patches/skillPatch.ts |
Updates patch edit state typing to resolved skill entries. |
packages/skills-package-manager/src/pipeline/context.ts |
Stops loading lockfiles into workspace context. |
packages/skills-package-manager/src/pipeline/fetchQueue.ts |
Uses plan installDir instead of lockfile context. |
packages/skills-package-manager/src/pipeline/index.ts |
Runs pipeline from resolved plans and writes plan-based install state. |
packages/skills-package-manager/src/pipeline/linkQueue.ts |
Uses plan installDir/linkTargets. |
packages/skills-package-manager/src/pipeline/resolveQueue.ts |
Passes manifest context into specifier normalization. |
packages/skills-package-manager/src/pipeline/types.ts |
Replaces lockfile context/state types with plan/install-state types. |
packages/skills-package-manager/src/resolvers/file.ts |
Updates resolver typing to resolved skill entries. |
packages/skills-package-manager/src/resolvers/git.ts |
Updates resolver typing to resolved skill entries. |
packages/skills-package-manager/src/resolvers/index.ts |
Updates resolver dispatcher typing. |
packages/skills-package-manager/src/resolvers/link.ts |
Updates resolver typing to resolved skill entries. |
packages/skills-package-manager/src/resolvers/local.ts |
Updates resolver typing to resolved skill entries. |
packages/skills-package-manager/src/resolvers/npm.ts |
Updates resolver typing to resolved skill entries. |
packages/skills-package-manager/src/specifiers/normalizeSpecifier.ts |
Adds github: handling, local:*, and &path: normalization. |
packages/skills-package-manager/src/specifiers/parseSpecifier.ts |
Parses &path: outside hash fragments. |
packages/skills-package-manager/test/add.test.ts |
Updates/adds add-command tests for pins, list/all, repeated skills, and no lockfiles. |
packages/skills-package-manager/test/cli.test.ts |
Updates CLI dispatch tests for new add flags and removed frozen lockfile. |
packages/skills-package-manager/test/init.test.ts |
Updates README usage assertion for repeated --skill. |
packages/skills-package-manager/test/install.test.ts |
Reworks install tests around manifest-only installs and install state. |
packages/skills-package-manager/test/patch.test.ts |
Updates patch tests to assert no lockfile writes. |
packages/skills-package-manager/test/specifiers.test.ts |
Updates specifier tests for github:, local:*, npm versions, and &path:. |
packages/skills-package-manager/test/update.test.ts |
Reworks update tests around manifest pin rewrites. |
website/docs/_pnpm.mdx |
Updates pnpm walkthrough for manifest pins and no lockfile. |
website/docs/api/commands.mdx |
Updates command API docs for new add/update/install behavior. |
website/docs/api/specifiers.mdx |
Updates specifier docs for github:, local:*, npm versions, and &path:. |
website/docs/architecture/_meta.json |
Replaces manifest-and-lockfile page with manifest page. |
website/docs/architecture/cli-commands.mdx |
Simplifies CLI architecture docs for manifest-only workflow. |
website/docs/architecture/how-it-works.mdx |
Updates install architecture overview for install plans and install state. |
website/docs/architecture/manifest-and-lockfile.mdx |
Removes obsolete manifest/lockfile architecture page. |
website/docs/architecture/manifest.mdx |
Adds new manifest and pinning model documentation. |
website/docs/architecture/pnpm-plugin.mdx |
Updates pnpm plugin architecture docs. |
website/docs/getting-started.mdx |
Updates getting-started flow for manifest resolution and add compatibility flags. |
website/docs/index.mdx |
Updates homepage frontmatter for single-file pins and pinned specifiers. |
website/rspress.config.ts |
Updates website description. |
website/theme/components/HomePage/index.tsx |
Updates homepage UI copy/config sample and removes lockfile tab. |
Comments suppressed due to low confidence (2)
packages/skills-package-manager/src/commands/add.ts:527
local:*is normalized without a manifest skill name in the direct add path, sonpx skills-package-manager add local:*writes a skill literally named*pointing at.agents/skills/*; the user cannot supply the intended skill name because the direct-specifier path ignoresoptions.skill. This should either rejectlocal:*foraddor pass an explicit skill name into normalization/resolution.
let normalized: NormalizedSpecifier
try {
normalized = normalizeSpecifier(specifier, {
installDir: existingManifest.installDir,
})
packages/skills-package-manager/src/commands/add.ts:665
- This
--listfast path runs only afterresolveAddManifestContexthas already validated and possibly created/loaded the target manifest context. As a result, read-only list operations can still fail global first-use validation (or invalid--agentvalidation) even though--listpromises not to write or install anything. Handleoptions.listbefore resolving install/link-target context so inspection remains side-effect-free and does not require--agent.
if (options.list) {
printAvailableSkills(discoveredSkills)
p.outro('Listed skills')
return { status: 'listed' as const, skills: discoveredSkills }
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+60
to
+65
| npx skills-package-manager add github:owner/repo#abc1234&path:/skills/my-skill | ||
| npx skills-package-manager add link:./local-source/skills/my-skill | ||
| npx skills-package-manager add local:./.agents/skills/my-skill | ||
| npx skills-package-manager add local:* | ||
| npx skills-package-manager add ./local-source | ||
| npx skills-package-manager add file:./skills-package.tgz#path:/skills/my-skill | ||
| npx skills-package-manager add npm:@scope/skills-package#path:/skills/my-skill | ||
| npx skills-package-manager add file:./skills-package.tgz&path:/skills/my-skill | ||
| npx skills-package-manager add npm:@scope/skills-package@1.0.0&path:/skills/my-skill |
|
|
||
| # Add to the global workspace using an agent-specific global directory | ||
| npx skills-package-manager add ../local-skills -g --agent claude-code --skill hello-skill -y | ||
| npx skills-package-manager add npm:@scope/skills-package@1.0.0&path:/skills/my-skill |
Comment on lines
152
to
+157
| await pruneManagedSkills( | ||
| ctx.cwd, | ||
| installDir, | ||
| linkTargets, | ||
| skillNames, | ||
| getLocalSkillDirs(ctx.cwd, [runtimeLockfile, ctx.lockfile]), | ||
| getLocalSkillDirs(ctx.cwd, [plan]), |
Comment on lines
21
to
23
| try { | ||
| let lockfile: SkillsLock | ||
| const installDir = ctx.manifest.installDir ?? '.agents/skills' | ||
|
|
||
| if (options.frozenLockfile) { | ||
| // Frozen mode: lock must exist and be in sync | ||
| if (!ctx.lockfile) { | ||
| throw new ManifestError({ | ||
| code: ErrorCode.LOCKFILE_NOT_FOUND, | ||
| filePath: `${options.cwd}/skills-lock.yaml`, | ||
| message: | ||
| 'Lockfile is required in frozen mode but none was found. Run "spm install" first.', | ||
| }) | ||
| } | ||
| if ( | ||
| !(await isLockInSync( | ||
| options.cwd, | ||
| ctx.manifest, | ||
| ctx.lockfile, | ||
| ctx.manifestStat, | ||
| ctx.installState, | ||
| )) | ||
| ) { | ||
| throw new ManifestError({ | ||
| code: ErrorCode.LOCKFILE_OUTDATED, | ||
| filePath: `${options.cwd}/skills-lock.yaml`, | ||
| message: | ||
| 'Lockfile is out of sync with manifest. Run install without --frozen-lockfile to update.', | ||
| }) | ||
| } | ||
| lockfile = ctx.lockfile | ||
| } else { | ||
| // Normal mode: check install-dir lock copy for fast-path skip. | ||
| // Only skip when there are no file: skills, because tarball contents | ||
| // may change without the lockfile being modified. link: and local: | ||
| // skills always reflect the current source. | ||
| const hasLocalSource = Object.values(ctx.manifest.skills).some((s) => s.startsWith('file:')) | ||
| const installDirLock = await readInstallDirLock(options.cwd, installDir) | ||
| if ( | ||
| !hasLocalSource && | ||
| ctx.lockfile && | ||
| installDirLock && | ||
| isSkillsLockEqual(ctx.lockfile, installDirLock) && | ||
| (await isLockInSync(options.cwd, ctx.manifest, ctx.lockfile)) | ||
| ) { | ||
| console.info('Skills Lockfile is up to date, resolve skipped') | ||
| lockfile = ctx.lockfile | ||
| } else { | ||
| lockfile = await syncSkillsLock(options.cwd, ctx.manifest, ctx.lockfile, { | ||
| manifestStat: ctx.manifestStat, | ||
| installState: ctx.installState, | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| const runtimeLock = await withBundledSelfSkillLock(options.cwd, ctx.manifest, lockfile) | ||
| const plan = await resolveSkillsPlan(options.cwd, ctx.manifest) | ||
|
|
| <p> | ||
| <strong>The Next-Gen Package Manager for <a href="https://skills-package-manager.site">Agent Skills</a></strong><br> | ||
| Manage, install, and link SKILL.md-based skills with lockfile-driven reproducibility. | ||
| Manage, install, and link SKILL.md-based skills from a single `skills.json` manifest. |
Comment on lines
+20
to
+22
| - title: Single-File Pins | ||
| details: Keep exact GitHub commits, npm versions, local links, install directories, and agent link targets in `skills.json`. | ||
| icon: manifest |
Comment on lines
1
to
+5
| import type { | ||
| InstallProgressEvent, | ||
| NormalizedSkillsManifest, | ||
| SkillsLock, | ||
| SkillsLockEntry, | ||
| ResolvedSkillsPlan, | ||
| ResolvedSkillEntry, |
Comment on lines
+135
to
+140
| const [treeRef, ...subpathParts] = normalizedTreeSuffix.split('/') | ||
| if (subpathParts.length > 0) { | ||
| return { | ||
| ref: treeRef, | ||
| subpath: sanitizeSourceSubpath(subpathParts.join('/')), | ||
| } |
2 tasks
SoonIter
added a commit
that referenced
this pull request
Jun 5, 2026
## Summary This PR follows up on #33 review feedback by tightening `add` compatibility and safety: direct `local:*` add now requires an explicit skill name, `--list` stays read-only before write-context validation, ambiguous tree URLs require an explicit ref, and pinned full Git commits skip remote ref resolution. It also protects adopted local skills by clearing stale managed markers, removes the root `skills-lock.yaml`, updates the root manifest to `github:` pins, and fixes the called-out docs/homepage rendering issues. ## Related Links #33 ## Checklist - [x] Tests updated (or not required). - [x] Documentation updated (or not required). Tested with `pnpm test`, `pnpm build`, `pnpm build:website`, and `pnpm check`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR makes
skills.jsonthe only user-facing configuration and pin source for skills-package-manager. It removes skills lockfile read/write/frozen behavior, resolves installs through an in-memory plan plus internal install state, updates add/update/patch/pnpm plugin flows, and expandsaddcompatibility with commonnpx skills addforms while persisting GitHub sources as pinnedgithub:specifiers.Tested with
pnpm build,pnpm build:website,pnpm test, and scopedbiome check.Related Links
https://raw.githubusercontent.com/vercel-labs/skills/refs/heads/main/README.md
Checklist