Uh oh!
There was an error while loading. Please reload this page.
fix(cursor): discover symlinked skills as package boundaries - #9420
Open
EzraBuild wants to merge 1 commit into
Open
fix(cursor): discover symlinked skills as package boundaries#9420EzraBuild wants to merge 1 commit into
EzraBuild wants to merge 1 commit into
Conversation
Cursor skill discovery canonicalized every directory and skipped any that resolved outside the scanned root. A skill installed as a symlink into a config repo therefore never reached the `$` picker or the `$skill` to `/skill` rewrite, while Claude and Codex on the same machine listed it. Treat an escaping symlink as a package boundary: read its own SKILL.md under the link name, but never walk the target tree. The visited set and scan budgets still bound the work. Fixes part of pingdotgg#2736. Model: Claude Fable 5.1. Harness: Claude Code.
Contributor
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a narrowly scoped Cursor skill-discovery bug fix that recognizes externally symlinked packages without traversing their target trees. Existing cycle and scan-budget protections remain in place, and a regression test covers both discovery and the traversal boundary. You can add or adjust custom eligibility rules. Learn more. |
Melv1C
approved these changes
Sep 3, 2026
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 freeto 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.
What Changed
Cursor skill discovery (
CursorSkills.ts, added in #9180) canonicalizes each directory and skips any whose resolved path falls outside the scanned root. A skill installed as a symlink into a config repo, for example~/.cursor/skills/my-skill -> ~/config-repo/agents/skills/my-skill, resolved outside the root and was silently dropped. The$picker stayed empty and$my-skillwas never rewritten to Cursor's native/my-skill.This treats an escaping symlink as a package boundary: read that directory's own
SKILL.mdunder the link name, but never walk the target tree. The visited set still prevents loops and the existing entry and byte budgets still bound the scan. Nothing outside the root is ever traversed.One new test symlinks a skill from an outside directory into
.cursor/skills, asserts it is discovered under the link path, asserts a nestedSKILL.mdbelow the target is not discovered, and asserts the probe reports success.Why
Fixes the remaining case in #2736, as reported in the 2026-09-03 comment there. Claude's scanner already follows these symlinks and the Antigravity scanner ships a test for the same behavior, so Cursor was the odd one out on the same machine.
UI Changes
None.
Checklist
Validation
vp test run apps/server/src/provider/Layers/CursorProvider.test.tsvp lintandvp fmt --checkon the two changed filesvp run --filter t3 typecheckModel: Claude Fable 5.1. Harness: Claude Code.