Skip to content

feat(skills): Add npm: source type for installed packages - #150

Open
mohdhassaan wants to merge 1 commit into
getsentry:mainfrom
mohdhassaan:feat/npm-source-type
Open

feat(skills): Add npm: source type for installed packages#150
mohdhassaan wants to merge 1 commit into
getsentry:mainfrom
mohdhassaan:feat/npm-source-type

Conversation

@mohdhassaan

Copy link
Copy Markdown

Closes #149

What

Adds an npm: source type so skills that ship inside installed npm packages can be declared without hardcoding the node_modules layout:

# named skill — the specifier points at the skill directory, like path:
[[skills]]
name = "ui-kit-upgrade"
source = "npm:@acme/ui-kit/skills/ui-kit-upgrade"

# wildcard — package root, scoped by path
[[skills]]
name = "*"
source = "npm:@acme/ui-kit"
path = "skills"

Why

Libraries have started shipping agent skills in their packages so the skill content is versioned with the library (e.g. migration guides that must match the installed version). Today the only way to consume them is path:./node_modules/@acme/ui-kit/..., which hardcodes a layout that isn't guaranteed (Yarn PnP has no node_modules; hoisting moves packages), leaks package internals into every consumer's agents.toml, and a bare @acme/ui-kit/... specifier misparses as GitHub owner/repo shorthand. Details in #149.

Design

npm: behaves exactly like path:, except the root is the resolved installed package:

  • resolveNpmSource locates the package with Node's own module resolution — createRequire(projectRoot).resolve("<pkg>/package.json") — so pnpm symlink layouts, workspace hoisting, and PnP all work. Packages whose exports map doesn't expose ./package.json (common) fall back to a node_modules ancestor walk. Subpath traversal outside the package is rejected; the final directory is stat-checked, mirroring local.ts.
  • After resolution it re-enters the existing local flow (acquireSkillSource returns {type: "local"}), so resolveSkill, wildcard discovery, path scoping, install, and copy logic need no changes.
  • No network access — the package manager fetches; dotagents only locates and copies. The consumer's lockfile is effectively the pin, and skills refresh automatically whenever the dependency is updated (since install re-copies local sources every run).
  • Trust: npm sources are always allowed, like path: — they resolve to directories already on disk, vetted by the package manager's own supply-chain controls at install time.
  • Lockfile: npm sources lock as local entries (one mapping in sourceType).
  • dotagents add npm:... and subagent sources get the same treatment for parity.

Testing

  • 13 new tests in sources/npm.test.ts: specifier grammar (scoped/unscoped/invalid), explicit-specifier classification, trust bypass, resolution via both branches (exports-restricted → walk fallback; plain → require.resolve), not-installed error, traversal rejection, and end-to-end resolveSkill + wildcard-with-path through the real resolver.
  • Lockfile schema case for npm entries.
  • pnpm check green: oxlint 0 warnings, 303/303 lib tests, 581/581 host tests.
  • Also validated the flow shape in a real consumer repo (a design-system package shipping migration skills, consumed via the equivalent path:./node_modules/... form).

Docs updated: source-formats table (cli.mdx), trust note (security.mdx), README example.

Resolve skills that ship inside installed npm packages without hardcoding
the node_modules layout: `npm:@acme/ui-kit/skills/upgrade` locates the
package with Node module resolution (createRequire, with a node_modules
walk fallback for packages whose exports map hides package.json) and then
behaves exactly like a local path: source. Wildcards and `path` scoping
work through the existing local flow; npm sources are always trusted like
path: sources and lock as local entries. No network access — the package
manager fetches, dotagents only locates and copies.

Closes getsentry#149
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown

@mohdhassaan is attempting to deploy a commit to the Sentry Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added the risk: high PR risk score: high label Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: high PR risk score: high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: npm package source type (resolve skills from installed packages without hardcoding node_modules)

1 participant