Skip to content

discover skills in Yarn Berry PnP projects + speed up skill discovery#151

Merged
LadyBluenotes merged 4 commits into
mainfrom
fix/pnp-zip-discovery
Jun 13, 2026
Merged

discover skills in Yarn Berry PnP projects + speed up skill discovery#151
LadyBluenotes merged 4 commits into
mainfrom
fix/pnp-zip-discovery

Conversation

@LadyBluenotes

@LadyBluenotes LadyBluenotes commented Jun 13, 2026

Copy link
Copy Markdown
Member

Summary

Two related changes to skill discovery:

Yarn Berry (PnP) support

With nodeLinker: pnp and no node_modules, dependencies live inside
.yarn/cache/*.zip archives that are only readable through Yarn's
libzip-patched filesystem. intent list and intent load now read package
metadata and SKILL.md files from those archives, so skills are discovered
and loaded correctly — including when Intent runs via npx/dlx from outside
the project's PnP graph.

  • A failed PnP runtime load fails closed with a clear diagnostic and never
    falls back to importing candidate package code.
  • The project's PnP module-resolution hook is no longer left installed in
    Intent's process after discovery.

Discovery performance

  • parseFrontmatter reads only the leading region of each SKILL.md (bounded
    readSync into a reused buffer) instead of the whole file, with a full-read
    fallback when frontmatter exceeds the probe window or the read primitives
    are unavailable. ~4x faster on large skill bodies, neutral on small ones.
  • resolveDepDir memoizes its module resolver per package instead of rebuilding
    it for every dependency. req.resolve still hits the live filesystem, so
    cached entries never go stale (safe under long-running mcp serve).
  • Dropped a redundant existsSync before readdirSync in the skill-file walk
    and avoided per-directory array-spread allocations.

Fixes #144

Summary by CodeRabbit

  • New Features

    • Support Yarn Berry (PnP) projects for dependency and skill discovery from Yarn’s cache archives.
  • Bug Fixes

    • Fail-closed behavior and clearer diagnostics when PnP resolution fails; no leftover runtime hooks after failure.
  • Performance Improvements

    • Parse only frontmatter metadata, reuse resolver context, and remove redundant filesystem checks to speed discovery.
  • Tests

    • Added integration and unit tests covering PnP discovery, frontmatter parsing, and fail-closed behavior.

@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 04db8c5d-a96b-408a-a11d-5d890b099bbb

📥 Commits

Reviewing files that changed from the base of the PR and between 6176b8c and 34b56f9.

📒 Files selected for processing (1)
  • packages/intent/tests/integration/pnp-berry-corepack.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/intent/tests/integration/pnp-berry-corepack.test.ts

📝 Walkthrough

Walkthrough

This PR fixes Yarn PnP skill discovery by introducing a pluggable filesystem abstraction throughout the scanner. It captures Yarn's patched filesystem during PnP setup, routes all file reading through that filesystem, optimizes frontmatter parsing to read only the leading region, and validates the fix with real Yarn Berry integration tests.

Changes

Yarn PnP skill discovery and filesystem abstraction

Layer / File(s) Summary
ReadFs abstraction and core utilities
packages/intent/src/utils.ts
Introduces ReadFs interface and nodeReadFs implementation to abstract filesystem operations, updates createFsIdentityCache, findSkillFiles, listNodeModulesPackageDirs, resolveDepDir, and parseFrontmatter to accept optional ReadFs parameters; adds bounded frontmatter parsing via low-level openSync/readSync/closeSync primitives and module resolver caching per base package.
fsCache filesystem swapping
packages/intent/src/fs-cache.ts
Introduces swappable activeFs initialized to nodeReadFs, adds public methods useFs(), getReadFs(), and exists() to dynamically switch and query the active filesystem, reconfigures cache identity tracking to use the current activeFs, and routes all package.json reads and skill file discovery through the active filesystem.
PnP API loading and Yarn fs capture
packages/intent/src/scanner.ts (import & loadPnpApi)
Refactors loadPnpApi to capture and return both the PnP API and Yarn's patched readFs, preserves Node's original fs before PnP patches it, restores the module resolver hook after setup (including on errors), falls back to findPnpApi on load failure, and throws a clear diagnostic when both paths fail.
Skill discovery with pluggable filesystem
packages/intent/src/core.ts, packages/intent/src/discovery/register.ts, packages/intent/src/scanner.ts (discovery functions)
Updates toResolvedIntentSkill to compute paths via injected readFs, passes fsCache.getReadFs() through resolution fast-path and full-scan flows, reads skill file content via resolved.readFs, adds exists callback to CreatePackageRegistrarOptions for abstracted existence checks, and threads fsCache.getReadFs() and fsCache.exists into discoverSkills, discoverSkillByNameHint, and package registrar for consistent filesystem behavior.
Frontmatter and PnP failure mode tests
packages/intent/tests/parse-frontmatter.test.ts, packages/intent/tests/scanner.test.ts
Validates bounded frontmatter parsing with unit tests covering normal cases, large file bodies, values exceeding bounded read probes, and null results for missing/invalid files; verifies that broken PnP setups fail closed with a diagnostic error and do not execute candidate code.
Real Yarn Berry PnP integration test
packages/intent/tests/integration/pnp-berry-corepack.test.ts
Scaffolds a live Yarn Berry (v4) project with nodeLinker: pnp, packs a skill-bearing dependency into the zip-backed cache via corepack yarn install, runs the Intent CLI to list packages and load the skill, and asserts the expected output; test runs unconditionally on CI and locally only if Yarn Berry can be provisioned.
Release notes
.changeset/yellow-queens-doubt.md
Documents the patch release covering PnP skill discovery fixes (zip-backed reads, closed-fail diagnostics, hook cleanup), performance improvements (bounded frontmatter parsing, resolver caching, reduced filesystem checks), and test coverage.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • #144 — Fix Yarn PnP discovery: This PR directly addresses the issue by reproducing real Yarn Berry PnP scenarios with zip-backed dependencies, implementing closed-fail diagnostics for broken PnP loads, and validating the fix with an integration test exercising the npx path.
  • #146: Similar PnP-focused changes to scanner/fs-cache/utils; likely related to the same objectives around Yarn PnP ReadFs usage.

Suggested reviewers

  • KevinVandy

Poem

🐰 A patch to make Yarn PnP sing,
With fs swapped like a magic ring,
From zip-backed cache, skills now found,
Frontmatter bounds, no files unbound!
When PnP fails, we fail just right — diagnostics bright!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.13% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the two main changes: Yarn Berry PnP support for skill discovery and performance improvements to the skill discovery process.
Description check ✅ Passed The description provides detailed explanations of both main changes (Yarn Berry PnP support and performance improvements), their motivations, and includes a reference to the fixed issue.
Linked Issues check ✅ Passed The PR fulfills all coding requirements from issue #144: adds real Yarn Berry PnP support with .yarn/cache/*.zip reading, implements fail-closed behavior with clear diagnostics, removes PnP hook from process, and includes integration test demonstrating the fix.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the stated objectives: PnP support infrastructure, discovery performance improvements, and related tests. No unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pnp-zip-discovery

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud

nx-cloud Bot commented Jun 13, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 34b56f9

Command Status Duration Result
nx run-many --targets=build --exclude=examples/** ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2026-06-13 03:03:58 UTC

@nx-cloud

nx-cloud Bot commented Jun 13, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 6176b8c

Command Status Duration Result
nx run-many --targets=build --exclude=examples/** ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2026-06-13 00:13:11 UTC

@pkg-pr-new

pkg-pr-new Bot commented Jun 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/TanStack/intent/@tanstack/intent@151

commit: 34b56f9

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/intent/tests/parse-frontmatter.test.ts (1)

36-54: 📐 Maintainability & Code Quality | ⚡ Quick win

Strengthen this regression by asserting the bounded-read path, not just output.

Right now, these cases still pass if parseFrontmatter regresses to full-file reads. Add a mocked/injected ReadFs assertion that verifies openSync/readSync are used for the large-body case and readFileSync is only used for the overflow fallback case.

Proposed test-shape diff
+  it('uses bounded reads when frontmatter fits in the probe window', () => {
+    const body = 'x'.repeat(64 * 1024)
+    const path = write('large-body.md', `---\nname: big\n---\n\n${body}\n`)
+    const calls = { open: 0, read: 0, full: 0 }
+    const spyFs = {
+      ...nodeReadFs,
+      openSync(...args: Parameters<typeof nodeReadFs.openSync>) {
+        calls.open++
+        return nodeReadFs.openSync!(...args)
+      },
+      readSync(...args: Parameters<typeof nodeReadFs.readSync>) {
+        calls.read++
+        return nodeReadFs.readSync!(...args)
+      },
+      readFileSync(...args: Parameters<typeof nodeReadFs.readFileSync>) {
+        calls.full++
+        return nodeReadFs.readFileSync(...args)
+      },
+    }
+    expect(parseFrontmatter(path, spyFs)).toEqual({ name: 'big' })
+    expect(calls.open).toBeGreaterThan(0)
+    expect(calls.read).toBeGreaterThan(0)
+    expect(calls.full).toBe(0)
+  })
🤖 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 `@packages/intent/tests/parse-frontmatter.test.ts` around lines 36 - 54, Update
the tests in parse-frontmatter.test.ts to assert the bounded-read code path by
injecting a mocked ReadFs into parseFrontmatter: for the large-body test replace
real fs with a mock that records calls and fails if readFileSync is invoked, and
assert openSync/readSync were called; for the large-frontmatter (overflow) test
use a mock that records calls and assert that readFileSync was used as the
fallback while openSync/readSync may not be called. Make the mocks target the
same ReadFs interface/object used by parseFrontmatter and ensure the tests pass
the mock into parseFrontmatter (or its factory) so the assertions validate which
fs methods were used rather than only the parsed output.
🤖 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 `@packages/intent/tests/integration/pnp-berry-corepack.test.ts`:
- Around line 42-54: The execFileSync calls in berryAvailable (and the other
execFileSync usages in this test file) are unbounded and can hang CI; update
each call (including the corepack check in berryAvailable and the execFileSync
calls around lines 90-109 and 116-132) to pass a timeout option (e.g., a few
seconds or test-appropriate timeout) and increase maxBuffer for commands that
produce install output; modify the options object passed to execFileSync (the
one currently containing cwd, env, stdio) to include timeout and maxBuffer
values so subprocesses are killed and large outputs don't overflow the buffer.

---

Nitpick comments:
In `@packages/intent/tests/parse-frontmatter.test.ts`:
- Around line 36-54: Update the tests in parse-frontmatter.test.ts to assert the
bounded-read code path by injecting a mocked ReadFs into parseFrontmatter: for
the large-body test replace real fs with a mock that records calls and fails if
readFileSync is invoked, and assert openSync/readSync were called; for the
large-frontmatter (overflow) test use a mock that records calls and assert that
readFileSync was used as the fallback while openSync/readSync may not be called.
Make the mocks target the same ReadFs interface/object used by parseFrontmatter
and ensure the tests pass the mock into parseFrontmatter (or its factory) so the
assertions validate which fs methods were used rather than only the parsed
output.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro

Run ID: dcc7541f-6e9d-4939-a9e3-90f3cd0b3bb2

📥 Commits

Reviewing files that changed from the base of the PR and between c53dbc3 and 6176b8c.

📒 Files selected for processing (9)
  • .changeset/yellow-queens-doubt.md
  • packages/intent/src/core.ts
  • packages/intent/src/discovery/register.ts
  • packages/intent/src/fs-cache.ts
  • packages/intent/src/scanner.ts
  • packages/intent/src/utils.ts
  • packages/intent/tests/integration/pnp-berry-corepack.test.ts
  • packages/intent/tests/parse-frontmatter.test.ts
  • packages/intent/tests/scanner.test.ts

Comment thread packages/intent/tests/integration/pnp-berry-corepack.test.ts
@LadyBluenotes LadyBluenotes merged commit ae42b35 into main Jun 13, 2026
9 checks passed
@LadyBluenotes LadyBluenotes deleted the fix/pnp-zip-discovery branch June 13, 2026 03:07
@github-actions github-actions Bot mentioned this pull request Jun 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix Yarn PnP discovery

1 participant