fix(cursor): cursor skills discovery - #5168
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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.
Effect service conventions review: one finding in apps/server/src/provider/ProviderSkillInventory.ts.
Posted via Macroscope — Effect Service Conventions
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit be0f379. Configure here.
ApprovabilityVerdict: Needs human review ... You can customize Macroscope's approvability policy. Learn more. |
- Discover skills from Claude, Codex, Agents, and Cursor roots - Resolve archived thread workspaces and protect against symlink escapes
- Preserve skills found in wide directories before applying the entry inspection limit - Update coverage for bounded traversal behavior

What Changed
Cursor skills now show up in the
$picker, scoped to the project or worktree where the thread actually runs.CursorSkillsscanner reads.cursor/skillsand.agents/skillsat user and project scope for a given working directory, applying Cursor's precedence and naming rules (directory name wins over frontmattername,.cursorbeats.agents, and project beats user). Discovery is bounded and best-effort, rejects roots and symlinks that escape their canonical boundaries, reads at most 64 KiB of metadata perSKILL.md, and never sends skill bodies over the wire.providers.skillInventorytakes a thread or project id—never a raw path—andServerProvideroptionally advertisesskillInventoryMode: "project"; absence means snapshot mode.ProviderSkillInventoryresolves the id to a cwd with the same helper provider sessions use, so a worktree thread lists that worktree's skills.docs/internals/providers.mddocuments inventory modes, cwd resolution, typed request failures, best-effort discovery, canonical containment, and traversal budgets.Why
This addresses the Cursor portion of pingdotgg/t3code#2736, which reports that Cursor and OpenCode skills exist on disk but remain absent from T3 Code's provider inventory. OpenCode discovery remains outside this PR's scope.
The
$picker renderedServerProvider.skills, an environment-wide snapshot computed once from wherever the server started. That is wrong for every project but one, and empty for Cursor: its ACP surface only exposes slash-command metadata mixed with built-ins, with no paths and no scope, so there was nothing reliable to snapshot.Cursor's inventory depends on the directory where the agent will run, so the lookup must be per thread or project rather than per environment. Passing an id instead of a path, together with canonical containment of skill roots and symlinks, keeps the picker from becoming a filesystem probe.
UI Changes
The
$picker with Cursor selected: empty before, populated with the project's skills after.Before
After
cursor-skills.mov
Checklist
Note
Medium Risk
Adds filesystem traversal and a new read RPC scoped by thread/project; discovery is bounded and best-effort, but wrong cwd resolution would show incorrect skills for worktree threads.
Overview
Cursor skills now appear in the
$picker because inventory is resolved for the actual working directory (project root or worktree), not from a one-time environment snapshot.Server:
discoverCursorSkillsscans eight precedence-ordered roots (user/project ×.claude,.codex,.agents,.cursor), merges by directory name, and applies Cursor’s naming/description rules.CursorDriverexposes optionalskillInventory; snapshots getskillInventoryMode: "project".providers.skillInventoryaccepts thread or project ids (not paths), resolves cwd viagetThreadWorkspaceContextByIdand the same helper provider sessions use, then calls the driver.Clients: Web and mobile use shared
useProviderSkills/selectProviderSkills—snapshot providers stay zero-round-trip; project-mode providers fetch per (environment, scope, instance) with snapshot fallback before/after RPC failure.Contracts:
ServerProvider.skillInventoryMode, inventory input/result types, and orchestration read scope for the new RPC.Reviewed by Cursor Bugbot for commit 6f02789. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add Cursor skill discovery and a
providers.skillInventoryRPC for project-scoped skillsdiscoverCursorSkillsinCursorSkills.ts, which scans eight filesystem roots (user and project, across.claude,.codex,.agents,.cursor) in precedence order and returns a merged, name-sorted list of skills.skillInventorycapability toProviderInstanceand decorates provider snapshots withskillInventoryMode: "project"when the capability is present, signaling clients to fetch skills dynamically.providers.skillInventoryWebSocket RPC that resolves the caller's scope (thread or project) to a working directory and returns skills from the provider instance or falls back to snapshot skills.useProviderSkillshooks on web and mobile that transparently return snapshot skills for non-project-mode providers and issue askillInventoryrequest for project-mode providers.ProjectionSnapshotQuerywithgetThreadWorkspaceContextByIdto resolve thread workspace and worktree paths needed for cwd resolution.useProviderSkillsinstead of directly readingprovider.skills, so displayed skills may differ when a project-mode provider is active.Macroscope summarized 6f02789.