feat(skill-registry): index npm-package skills (node_modules/*/skills) - #281
feat(skill-registry): index npm-package skills (node_modules/*/skills)#281ChaoXu1997 wants to merge 3 commits into
Conversation
Add discoverNpmPackageSkillDirs() scanning ~/.pi/agent/npm/node_modules/*/skills/ and wire it into regenerateRegistry + startSkillRegistryWatcher. Add a 'package' scope in scopeForPath so the registry distinguishes project / user / package sources. Previously the registry only scanned loose skill dirs (~/.pi/agent/skills, <cwd>/.claude/skills, etc.), missing ~26 npm-package skills (gentle-pi's own gentle-ai-*, context-mode, pi-lens, pi-mcp-adapter, pi-subagents, pi-intercom). Subagents that rely on .atl/skill-registry.md could not see them. See .pr-body.md for the related shouldSkipDuplicateExtensionLoad path-mismatch follow-up.
|
Warning Review limit reached
Next review available in: 36 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe skill registry now discovers skill directories in npm packages, assigns them ChangesNPM skill registry integration
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant SkillRegistry
participant NpmModules
participant FilesystemWatcher
SkillRegistry->>NpmModules: Discover package skill directories
NpmModules-->>SkillRegistry: Return existing directories
SkillRegistry->>SkillRegistry: Regenerate registry
SkillRegistry->>FilesystemWatcher: Watch package skill directories
FilesystemWatcher-->>SkillRegistry: Trigger rediscovery on package changes
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@extensions/skill-registry.ts`:
- Around line 83-92: Update discoverNpmPackageSkillDirs() to inspect package
directories nested inside scoped entries under node_modules, checking each
<scope>/<package>/skills path alongside direct package paths. Preserve the
existing behavior for unscoped packages, avoid treating scope directories
themselves as packages, and add coverage for both unscoped and scoped package
layouts.
- Around line 511-515: Update startSkillRegistryWatcher around the npm directory
discovery and watcher setup to also watch the npm package root, not only the
initially discovered skill directories. When a new package-level directory
appears under that root, re-run discoverNpmPackageSkillDirs and register the
resulting directories so regenerateRegistry is invoked and the registry reflects
newly installed packages.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 4a2dbe9d-1042-422d-b3a1-e7bc1adb27db
📒 Files selected for processing (1)
extensions/skill-registry.ts
Address CodeRabbit review comments on the npm-package-scan patch: - discoverNpmPackageSkillDirs now descends into @scope directories, so @scope/<pkg>/skills (e.g. @upstash/context7-pi) is discovered. Unscoped behavior is unchanged; scope directories themselves are never treated as packages. - startSkillRegistryWatcher adds a non-recursive watch on the npm package root, so newly installed or removed packages trigger regenerateRegistry (which re-runs discovery) and the registry reflects packages installed mid-session.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
extensions/skill-registry.ts (1)
533-533: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftReconcile npm package skill-directory watchers on registry refresh.
dirsis built once before the watcher loop. A mid-session npm package discovery refreshes the registry throughregenerateRegistry, but it does not add the package’sskillsdirectory toactiveWatchers. Later changes to that package’sSKILL.mdfiles are not observed. When an npm root event changes discovered skill directories, reopen watchers for newly present skill directories and close watchers for directories that are no longer discovered.Also address the skipped root watcher case when
.pi/agent/npm/node_modulesdoes not exist at startup (lines 559-571).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@extensions/skill-registry.ts` at line 533, Update the watcher refresh flow around regenerateRegistry and discoverNpmPackageSkillDirs so npm discovery changes reconcile activeWatchers: open watchers for newly discovered skill directories and close watchers for directories no longer present. Also ensure the npm root watcher is created or retried when .pi/agent/npm/node_modules is absent at startup, rather than permanently skipping npm package updates.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@extensions/skill-registry.ts`:
- Around line 559-571: Update the npm watch setup around npmRoot and
discoverNpmPackageSkillDirs so changes under scoped packages in
node_modules/@scope trigger refresh as well as direct package changes. Add
non-recursive watchers for each existing scope directory, register them in
activeWatchers, and preserve the existing best-effort error handling and refresh
callback.
---
Outside diff comments:
In `@extensions/skill-registry.ts`:
- Line 533: Update the watcher refresh flow around regenerateRegistry and
discoverNpmPackageSkillDirs so npm discovery changes reconcile activeWatchers:
open watchers for newly discovered skill directories and close watchers for
directories no longer present. Also ensure the npm root watcher is created or
retried when .pi/agent/npm/node_modules is absent at startup, rather than
permanently skipping npm package updates.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c931e485-811d-4018-b43f-e639eec10cfd
📒 Files selected for processing (1)
extensions/skill-registry.ts
The npm-root watcher used recursive:false, so it only received events for direct children of node_modules. Adding or removing a package under an existing \@scope directory (e.g. a new \@upstash/pkg when \@upstash already exists) did not create a new direct child of node_modules, so the watcher did not fire and the registry stayed stale for that change. Watch node_modules AND each existing \@scope directory (all non-recursive), so packages added under an existing scope trigger refresh too. The npm root watch still catches new unscoped packages and brand-new scopes. Addresses CodeRabbit line-571 review comment.
Problem
extensions/skill-registry.tsscans only loose skill directories (~/.pi/agent/skills,<cwd>/.claude/skills,~/.trae/skills, …) and misses npm-package-installed skills — the ones living at~/.pi/agent/npm/node_modules/*/skills/.These include gentle-pi's own skills (
gentle-ai-*,comment-writer,cognitive-doc-design,release,work-unit-commits), pluscontext-mode,pi-lens,pi-mcp-adapter,pi-subagents,pi-intercom— roughly 26 skills that pi loads into the agent's<available_skills>but the registry never indexes.Impact
Subagent delegation consumes
.atl/skill-registry.mdto discover and pass skill paths. Because npm-package skills aren't indexed, a delegated subagent can't see them — e.g. a task delegated to a subagent that needs a gentle-ai / context-mode / pi-lens skill getsskill_resolution: none, even though the skill is installed and available to the parent agent.On my machine the registry went from 53 → 79 skills after this patch (26 package skills correctly indexed under a new
packagescope).Fix
discoverNpmPackageSkillDirs()— scans~/.pi/agent/npm/node_modules/*/skills/and returns the existing per-package skill dirs.regenerateRegistry(scan list) andstartSkillRegistryWatcher(watch dirs), so adding/removing a package skill refreshes the registry.scopeForPathgains a"package"scope fornode_modulespaths, so the registry distinguishesproject/user/packagesources.Related (separate, flagged for follow-up — NOT in this PR)
While wiring this I noticed
shouldSkipDuplicateExtensionLoadchecks<cwd>/extensions/skill-registry.tsfor the project-local override, but pi'sdiscoverAndLoadExtensions(@earendil-works/pi-coding-agent/dist/core/extensions/loader.js) actually loads project extensions from<cwd>/.pi/extensions/(CONFIG_DIR_NAME/extensions). So the self-skip never fires for a real project override → duplicate execution (or, if the override is placed at<cwd>/extensions/, the package self-skips but pi never loads it → registry disappears). That path mismatch is a separate bug; this PR leaves it untouched.Testing
packagescope; project + user skills unchanged.Summary by CodeRabbit