Repository navigation
feat(sync): install git sources from package.json skills fields - #2403
Merged
Merged
Conversation
antfubot
force-pushed
the
feat/sync-remote-entries
branch
from
October 7, 2026 07:12
1f9ca3f to
6fe8278
Compare
Remote entries in a skills field (owner/repo, owner/repo@skill, installed by experimental_sync. Only git-hosted sources are allowed; local paths and plain URLs are errors, as in the skills-npm SPEC. Identical requests from several packages are installed once. Sync installs them in-process with installFromSource, which now takes a parsed source, records via in the lock, and lets the caller drop skills before installing. A skill shipped by a dependency or an earlier source wins, a skill installed with skills add is never shadowed, and a directory sync does not own is never replaced. A request whose skills are already in the lock and on disk is not fetched again; skills update refreshes them. Remote skills that no field requests anymore are removed. --no-remote skips remote entries for both installing and removing. A failing source is reported, the rest of the run continues, and the exit code is 1.
antfubot
force-pushed
the
feat/sync-remote-entries
branch
from
October 9, 2026 02:26
6fe8278 to
e8cce15
Compare
7 of 10 tasks
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.
Step 7 of #2323 (RFC: Install skills from npm packages). Builds on #2400 (field parsing), #2401 (programmatic install primitives) and #2402.
What changes
skills experimental_syncnow installs git sources listed inpackage.jsonskillsfields. This is what makes a skills pack work:{ "name": "@antfu/skills", "skills": [ "vercel-labs/agent-browser", "vercel-labs/agent-skills#v1.4.0@web-design-guidelines", { "source": "antfu/skills", "ref": "v2", "skills": ["vue", "vitest"] }, "npm:@acme/docs" ] }A project that depends on this pack gets all of these skills on
skills experimental_sync. This is the same as runningskills addfor each entry, except that the list comes from the installed packages.Grammar
Remote entries are parsed with the CLI's own
parseSource, soowner/repo,owner/repo@skill,#ref,#ref@skill,/tree/<ref>/<path>URLs, GitLab URLs andgit@/httpsgit URLs all work, as inskills add.Per the skills-npm SPEC:
refon a source that already carries one (#refor/tree/<ref>/) is an error.@skillshorthand is added to the entry'sskillslist.The error rules from step 5 apply: the project's own field stops sync, and a dependency's field only warns.
Installing
Sync calls
installFromSourcein-process. That is the primitive from #2401. It now:ParsedSource, so the object form'srefcan applyviain the lockselecthook that drops skills before installingConflict handling:
skills addis never shadowed.Sync now owns any lock entry it wrote:
sourceType: 'node_modules'or avia. Rules 1 and 2 are shared between shipped and remote skills throughblockedReason.Already installed
A request whose skills are already in the lock (same source, ref and
via) and on disk is not fetched again, so apreparerun with nothing to do needs no network.skills updaterefreshes those skills, because they are ordinarygithub/gitlab/gitlock entries.Cleanup and flags
Remote skills that no field requests anymore are removed by the step 3 cleanup, using the same ownership rule.
--no-remoteskips remote entries for both installing and removing, which is useful offline.A failing source is reported, the rest of the run continues, and the exit code is 1.
Tests
tests/skills-field.test.tscovers git sources with@skillandreffolded in, GitLab/-/tree/, rejection of non-git sources, and rejection of a double ref.tests/sync.test.tsadds aremote skills field entriesgroup. It runs offline against a local git repository throughfile://:via)--no-remoteskills addskill not shadowedThe full suite passes (953).
This PR was created with the help of an agent.