feat(claude): discover skills for the $ picker via SDK reloadSkills - #4325

Closed
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery
Closed

feat(claude): discover skills for the $ picker via SDK reloadSkills#4325
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery

Conversation

@colonelpanic8

@colonelpanic8colonelpanic8 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The Claude provider's capability probe now issues the Claude Agent SDK's reloadSkills control request after initializationResult() and maps the returned entries into ServerProviderSkills, populating skills on the provider snapshot.
  • New pure mapper parseClaudeReloadedSkills (apps/server/src/provider/Layers/ClaudeSkillDiscovery.ts):
    • strips the trailing scope suffix reloadSkills appends to descriptions (e.g. (user)) and maps it to a snapshot scope (user; project/localproject; builtin/bundled/systemsystem);
    • resolves each skill's path best-effort against the workspace .claude/skills/<name>, then the effective Claude config dir's skills/<name>, falling back to a constructed config-dir path (the contract requires a non-empty path); plugin-qualified names skip the filesystem probe;
    • dedupes by name and skips empty names, mirroring the existing slash-command handling.
  • The control request is bounded by its own 5s timeout and any failure falls back to an empty list, so older CLIs that don't answer reload_skills never fail the capability probe.
  • Slash commands are left untouched — skills legitimately also appear as / commands for Claude, matching upstream CLI behavior.

Why

Only the Codex provider populated skills, so the composer's $ skill picker was always empty on Claude threads even though the Claude CLI discovers the same ~/.claude/skills / .claude/skills entries (refs #1480, #2736). With this change Claude skills get the same $ autocomplete, inline pill rendering, and scope labels (Personal/Project/System) that Codex skills already have.

Checklist

  • Focused tests: vp test run ClaudeSkillDiscovery.test.ts ClaudeCapabilitiesProbe.test.ts ProviderRegistry.test.ts → 3 files, 53 tests passed (plus ClaudeAdapter.test.ts regression guard → 60 passed)
  • Typecheck: tsgo --noEmit in apps/server → 0 errors
  • Lint/format: vp lint on changed files, vp fmt → clean

🤖 Generated with Claude Code


Note

Medium Risk
Touches provider health probing and filesystem path resolution for user config; skill reload is isolated with timeouts so auth/command discovery should remain stable, but probe timing and path edge cases could affect the picker on some setups.

Overview
Claude skills now populate the provider snapshot so the composer $ picker can list them like Codex already does.

After a successful SDK initialization, probeClaudeCapabilities issues a best-effort reloadSkills call with its own timeout; failures yield an empty skill list but no longer fail the whole probe. Account info and slash commands are unchanged.

New parseClaudeReloadedSkills maps SDK entries to ServerProviderSkill: strips description scope suffixes (e.g. (user)), resolves paths under workspace .claude/skills or the effective config dir (with CLAUDE_CONFIG_DIR / HOME / USERPROFILE handling), and dedupes by name. checkClaudeProviderStatus threads skills into every built snapshot.

Reviewed by Cursor Bugbot for commit aac809e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude skills for the $ picker via SDK reloadSkills

  • After a successful capabilities probe, probeClaudeCapabilities issues a reloadSkills request to the Claude SDK subprocess and parses the response into ServerProviderSkill objects via the new parseClaudeReloadedSkills utility in ClaudeSkillDiscovery.ts.
  • Skill paths are resolved by checking <cwd>/.claude/skills/<name> then <configDir>/skills/<name>; scope is normalized from description suffix tokens or inferred from the resolved path.
  • The Claude config directory is derived from CLAUDE_CONFIG_DIR (with tilde expansion) or defaults to <home>/.claude, using a new resolveClaudeEnvironmentHomePath helper that prefers HOME over USERPROFILE.
  • Separate timeouts are now used for initialization and skills reload; a skills reload failure is non-fatal and only the initialization timeout causes the probe to return undefined.
  • The skills array is threaded through checkClaudeProviderStatus and included in the provider snapshot (empty when capabilities are absent).

Macroscope summarized aac809e.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eacd9fbe-7634-4689-be12-8058c40b45c7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts
Comment threadapps/server/src/provider/Layers/ClaudeSkillDiscovery.ts
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for skill discovery via the Claude SDK's reloadSkills API, adding new runtime behavior including SDK calls, filesystem checks, and new data flowing through provider capabilities. As a new capability from a first-time contributor, it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 2 times, most recently from 5c7932e to 138250aCompareJuly 23, 2026 16:15

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 138250a0b365d44904c05eec76871add7a7d1ea0. Configure here.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 5 times, most recently from 1339974 to f44f73bCompareJuly 23, 2026 22:27
colonelpanic8and others added 4 commits July 23, 2026 15:35
The Claude provider snapshot never populated `skills`, so Claude-provider
skills were absent from T3 Code's `$` skill picker (only Codex populated
them). Probe the SDK's `reloadSkills` control request after initialization
and map the returned entries into `ServerProviderSkill`s.
The new pure `parseClaudeReloadedSkills` mapper strips the trailing scope
suffix reloadSkills appends to descriptions (e.g. " (user)") and maps it to
a scope (user; project/local -> project; builtin/bundled/system -> system;
others verbatim). Paths are resolved best-effort against the workspace
`.claude/skills/<name>` (project) then the config dir `skills/<name>`
(user), falling back to a constructed config-dir path since the contract
requires a non-empty path; plugin-qualified names skip the filesystem probe.
The control request is bounded by its own timeout and failures fall back to
an empty list so older CLIs never fail the capability probe.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch from f44f73b to aac809eCompareJuly 23, 2026 22:35
@colonelpanic8

Copy link
Copy Markdown
ContributorAuthor

Superseded by the maintainer implementation in #4414, which is now merged. Closing this independent implementation in favor of the upstream-selected approach.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@colonelpanic8
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(claude): discover skills for the $ picker via SDK reloadSkills - #4325

Closed
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery
Closed

feat(claude): discover skills for the $ picker via SDK reloadSkills#4325
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery

Conversation

@colonelpanic8

@colonelpanic8colonelpanic8 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The Claude provider's capability probe now issues the Claude Agent SDK's reloadSkills control request after initializationResult() and maps the returned entries into ServerProviderSkills, populating skills on the provider snapshot.
  • New pure mapper parseClaudeReloadedSkills (apps/server/src/provider/Layers/ClaudeSkillDiscovery.ts):
    • strips the trailing scope suffix reloadSkills appends to descriptions (e.g. (user)) and maps it to a snapshot scope (user; project/localproject; builtin/bundled/systemsystem);
    • resolves each skill's path best-effort against the workspace .claude/skills/<name>, then the effective Claude config dir's skills/<name>, falling back to a constructed config-dir path (the contract requires a non-empty path); plugin-qualified names skip the filesystem probe;
    • dedupes by name and skips empty names, mirroring the existing slash-command handling.
  • The control request is bounded by its own 5s timeout and any failure falls back to an empty list, so older CLIs that don't answer reload_skills never fail the capability probe.
  • Slash commands are left untouched — skills legitimately also appear as / commands for Claude, matching upstream CLI behavior.

Why

Only the Codex provider populated skills, so the composer's $ skill picker was always empty on Claude threads even though the Claude CLI discovers the same ~/.claude/skills / .claude/skills entries (refs #1480, #2736). With this change Claude skills get the same $ autocomplete, inline pill rendering, and scope labels (Personal/Project/System) that Codex skills already have.

Checklist

  • Focused tests: vp test run ClaudeSkillDiscovery.test.ts ClaudeCapabilitiesProbe.test.ts ProviderRegistry.test.ts → 3 files, 53 tests passed (plus ClaudeAdapter.test.ts regression guard → 60 passed)
  • Typecheck: tsgo --noEmit in apps/server → 0 errors
  • Lint/format: vp lint on changed files, vp fmt → clean

🤖 Generated with Claude Code


Note

Medium Risk
Touches provider health probing and filesystem path resolution for user config; skill reload is isolated with timeouts so auth/command discovery should remain stable, but probe timing and path edge cases could affect the picker on some setups.

Overview
Claude skills now populate the provider snapshot so the composer $ picker can list them like Codex already does.

After a successful SDK initialization, probeClaudeCapabilities issues a best-effort reloadSkills call with its own timeout; failures yield an empty skill list but no longer fail the whole probe. Account info and slash commands are unchanged.

New parseClaudeReloadedSkills maps SDK entries to ServerProviderSkill: strips description scope suffixes (e.g. (user)), resolves paths under workspace .claude/skills or the effective config dir (with CLAUDE_CONFIG_DIR / HOME / USERPROFILE handling), and dedupes by name. checkClaudeProviderStatus threads skills into every built snapshot.

Reviewed by Cursor Bugbot for commit aac809e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude skills for the $ picker via SDK reloadSkills

  • After a successful capabilities probe, probeClaudeCapabilities issues a reloadSkills request to the Claude SDK subprocess and parses the response into ServerProviderSkill objects via the new parseClaudeReloadedSkills utility in ClaudeSkillDiscovery.ts.
  • Skill paths are resolved by checking <cwd>/.claude/skills/<name> then <configDir>/skills/<name>; scope is normalized from description suffix tokens or inferred from the resolved path.
  • The Claude config directory is derived from CLAUDE_CONFIG_DIR (with tilde expansion) or defaults to <home>/.claude, using a new resolveClaudeEnvironmentHomePath helper that prefers HOME over USERPROFILE.
  • Separate timeouts are now used for initialization and skills reload; a skills reload failure is non-fatal and only the initialization timeout causes the probe to return undefined.
  • The skills array is threaded through checkClaudeProviderStatus and included in the provider snapshot (empty when capabilities are absent).

Macroscope summarized aac809e.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eacd9fbe-7634-4689-be12-8058c40b45c7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts
Comment threadapps/server/src/provider/Layers/ClaudeSkillDiscovery.ts
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for skill discovery via the Claude SDK's reloadSkills API, adding new runtime behavior including SDK calls, filesystem checks, and new data flowing through provider capabilities. As a new capability from a first-time contributor, it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 2 times, most recently from 5c7932e to 138250aCompareJuly 23, 2026 16:15

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 138250a0b365d44904c05eec76871add7a7d1ea0. Configure here.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 5 times, most recently from 1339974 to f44f73bCompareJuly 23, 2026 22:27
colonelpanic8and others added 4 commits July 23, 2026 15:35
The Claude provider snapshot never populated `skills`, so Claude-provider
skills were absent from T3 Code's `$` skill picker (only Codex populated
them). Probe the SDK's `reloadSkills` control request after initialization
and map the returned entries into `ServerProviderSkill`s.
The new pure `parseClaudeReloadedSkills` mapper strips the trailing scope
suffix reloadSkills appends to descriptions (e.g. " (user)") and maps it to
a scope (user; project/local -> project; builtin/bundled/system -> system;
others verbatim). Paths are resolved best-effort against the workspace
`.claude/skills/<name>` (project) then the config dir `skills/<name>`
(user), falling back to a constructed config-dir path since the contract
requires a non-empty path; plugin-qualified names skip the filesystem probe.
The control request is bounded by its own timeout and failures fall back to
an empty list so older CLIs never fail the capability probe.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch from f44f73b to aac809eCompareJuly 23, 2026 22:35
@colonelpanic8

Copy link
Copy Markdown
ContributorAuthor

Superseded by the maintainer implementation in #4414, which is now merged. Closing this independent implementation in favor of the upstream-selected approach.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@colonelpanic8
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(claude): discover skills for the $ picker via SDK reloadSkills - #4325

Closed
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery
Closed

feat(claude): discover skills for the $ picker via SDK reloadSkills#4325
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery

Conversation

@colonelpanic8

@colonelpanic8colonelpanic8 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The Claude provider's capability probe now issues the Claude Agent SDK's reloadSkills control request after initializationResult() and maps the returned entries into ServerProviderSkills, populating skills on the provider snapshot.
  • New pure mapper parseClaudeReloadedSkills (apps/server/src/provider/Layers/ClaudeSkillDiscovery.ts):
    • strips the trailing scope suffix reloadSkills appends to descriptions (e.g. (user)) and maps it to a snapshot scope (user; project/localproject; builtin/bundled/systemsystem);
    • resolves each skill's path best-effort against the workspace .claude/skills/<name>, then the effective Claude config dir's skills/<name>, falling back to a constructed config-dir path (the contract requires a non-empty path); plugin-qualified names skip the filesystem probe;
    • dedupes by name and skips empty names, mirroring the existing slash-command handling.
  • The control request is bounded by its own 5s timeout and any failure falls back to an empty list, so older CLIs that don't answer reload_skills never fail the capability probe.
  • Slash commands are left untouched — skills legitimately also appear as / commands for Claude, matching upstream CLI behavior.

Why

Only the Codex provider populated skills, so the composer's $ skill picker was always empty on Claude threads even though the Claude CLI discovers the same ~/.claude/skills / .claude/skills entries (refs #1480, #2736). With this change Claude skills get the same $ autocomplete, inline pill rendering, and scope labels (Personal/Project/System) that Codex skills already have.

Checklist

  • Focused tests: vp test run ClaudeSkillDiscovery.test.ts ClaudeCapabilitiesProbe.test.ts ProviderRegistry.test.ts → 3 files, 53 tests passed (plus ClaudeAdapter.test.ts regression guard → 60 passed)
  • Typecheck: tsgo --noEmit in apps/server → 0 errors
  • Lint/format: vp lint on changed files, vp fmt → clean

🤖 Generated with Claude Code


Note

Medium Risk
Touches provider health probing and filesystem path resolution for user config; skill reload is isolated with timeouts so auth/command discovery should remain stable, but probe timing and path edge cases could affect the picker on some setups.

Overview
Claude skills now populate the provider snapshot so the composer $ picker can list them like Codex already does.

After a successful SDK initialization, probeClaudeCapabilities issues a best-effort reloadSkills call with its own timeout; failures yield an empty skill list but no longer fail the whole probe. Account info and slash commands are unchanged.

New parseClaudeReloadedSkills maps SDK entries to ServerProviderSkill: strips description scope suffixes (e.g. (user)), resolves paths under workspace .claude/skills or the effective config dir (with CLAUDE_CONFIG_DIR / HOME / USERPROFILE handling), and dedupes by name. checkClaudeProviderStatus threads skills into every built snapshot.

Reviewed by Cursor Bugbot for commit aac809e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude skills for the $ picker via SDK reloadSkills

  • After a successful capabilities probe, probeClaudeCapabilities issues a reloadSkills request to the Claude SDK subprocess and parses the response into ServerProviderSkill objects via the new parseClaudeReloadedSkills utility in ClaudeSkillDiscovery.ts.
  • Skill paths are resolved by checking <cwd>/.claude/skills/<name> then <configDir>/skills/<name>; scope is normalized from description suffix tokens or inferred from the resolved path.
  • The Claude config directory is derived from CLAUDE_CONFIG_DIR (with tilde expansion) or defaults to <home>/.claude, using a new resolveClaudeEnvironmentHomePath helper that prefers HOME over USERPROFILE.
  • Separate timeouts are now used for initialization and skills reload; a skills reload failure is non-fatal and only the initialization timeout causes the probe to return undefined.
  • The skills array is threaded through checkClaudeProviderStatus and included in the provider snapshot (empty when capabilities are absent).

Macroscope summarized aac809e.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eacd9fbe-7634-4689-be12-8058c40b45c7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts
Comment threadapps/server/src/provider/Layers/ClaudeSkillDiscovery.ts
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for skill discovery via the Claude SDK's reloadSkills API, adding new runtime behavior including SDK calls, filesystem checks, and new data flowing through provider capabilities. As a new capability from a first-time contributor, it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 2 times, most recently from 5c7932e to 138250aCompareJuly 23, 2026 16:15

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 138250a0b365d44904c05eec76871add7a7d1ea0. Configure here.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 5 times, most recently from 1339974 to f44f73bCompareJuly 23, 2026 22:27
colonelpanic8and others added 4 commits July 23, 2026 15:35
The Claude provider snapshot never populated `skills`, so Claude-provider
skills were absent from T3 Code's `$` skill picker (only Codex populated
them). Probe the SDK's `reloadSkills` control request after initialization
and map the returned entries into `ServerProviderSkill`s.
The new pure `parseClaudeReloadedSkills` mapper strips the trailing scope
suffix reloadSkills appends to descriptions (e.g. " (user)") and maps it to
a scope (user; project/local -> project; builtin/bundled/system -> system;
others verbatim). Paths are resolved best-effort against the workspace
`.claude/skills/<name>` (project) then the config dir `skills/<name>`
(user), falling back to a constructed config-dir path since the contract
requires a non-empty path; plugin-qualified names skip the filesystem probe.
The control request is bounded by its own timeout and failures fall back to
an empty list so older CLIs never fail the capability probe.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch from f44f73b to aac809eCompareJuly 23, 2026 22:35
@colonelpanic8

Copy link
Copy Markdown
ContributorAuthor

Superseded by the maintainer implementation in #4414, which is now merged. Closing this independent implementation in favor of the upstream-selected approach.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@colonelpanic8
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(claude): discover skills for the $ picker via SDK reloadSkills - #4325

Closed
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery
Closed

feat(claude): discover skills for the $ picker via SDK reloadSkills#4325
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery

Conversation

@colonelpanic8

@colonelpanic8colonelpanic8 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The Claude provider's capability probe now issues the Claude Agent SDK's reloadSkills control request after initializationResult() and maps the returned entries into ServerProviderSkills, populating skills on the provider snapshot.
  • New pure mapper parseClaudeReloadedSkills (apps/server/src/provider/Layers/ClaudeSkillDiscovery.ts):
    • strips the trailing scope suffix reloadSkills appends to descriptions (e.g. (user)) and maps it to a snapshot scope (user; project/localproject; builtin/bundled/systemsystem);
    • resolves each skill's path best-effort against the workspace .claude/skills/<name>, then the effective Claude config dir's skills/<name>, falling back to a constructed config-dir path (the contract requires a non-empty path); plugin-qualified names skip the filesystem probe;
    • dedupes by name and skips empty names, mirroring the existing slash-command handling.
  • The control request is bounded by its own 5s timeout and any failure falls back to an empty list, so older CLIs that don't answer reload_skills never fail the capability probe.
  • Slash commands are left untouched — skills legitimately also appear as / commands for Claude, matching upstream CLI behavior.

Why

Only the Codex provider populated skills, so the composer's $ skill picker was always empty on Claude threads even though the Claude CLI discovers the same ~/.claude/skills / .claude/skills entries (refs #1480, #2736). With this change Claude skills get the same $ autocomplete, inline pill rendering, and scope labels (Personal/Project/System) that Codex skills already have.

Checklist

  • Focused tests: vp test run ClaudeSkillDiscovery.test.ts ClaudeCapabilitiesProbe.test.ts ProviderRegistry.test.ts → 3 files, 53 tests passed (plus ClaudeAdapter.test.ts regression guard → 60 passed)
  • Typecheck: tsgo --noEmit in apps/server → 0 errors
  • Lint/format: vp lint on changed files, vp fmt → clean

🤖 Generated with Claude Code


Note

Medium Risk
Touches provider health probing and filesystem path resolution for user config; skill reload is isolated with timeouts so auth/command discovery should remain stable, but probe timing and path edge cases could affect the picker on some setups.

Overview
Claude skills now populate the provider snapshot so the composer $ picker can list them like Codex already does.

After a successful SDK initialization, probeClaudeCapabilities issues a best-effort reloadSkills call with its own timeout; failures yield an empty skill list but no longer fail the whole probe. Account info and slash commands are unchanged.

New parseClaudeReloadedSkills maps SDK entries to ServerProviderSkill: strips description scope suffixes (e.g. (user)), resolves paths under workspace .claude/skills or the effective config dir (with CLAUDE_CONFIG_DIR / HOME / USERPROFILE handling), and dedupes by name. checkClaudeProviderStatus threads skills into every built snapshot.

Reviewed by Cursor Bugbot for commit aac809e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude skills for the $ picker via SDK reloadSkills

  • After a successful capabilities probe, probeClaudeCapabilities issues a reloadSkills request to the Claude SDK subprocess and parses the response into ServerProviderSkill objects via the new parseClaudeReloadedSkills utility in ClaudeSkillDiscovery.ts.
  • Skill paths are resolved by checking <cwd>/.claude/skills/<name> then <configDir>/skills/<name>; scope is normalized from description suffix tokens or inferred from the resolved path.
  • The Claude config directory is derived from CLAUDE_CONFIG_DIR (with tilde expansion) or defaults to <home>/.claude, using a new resolveClaudeEnvironmentHomePath helper that prefers HOME over USERPROFILE.
  • Separate timeouts are now used for initialization and skills reload; a skills reload failure is non-fatal and only the initialization timeout causes the probe to return undefined.
  • The skills array is threaded through checkClaudeProviderStatus and included in the provider snapshot (empty when capabilities are absent).

Macroscope summarized aac809e.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eacd9fbe-7634-4689-be12-8058c40b45c7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts
Comment threadapps/server/src/provider/Layers/ClaudeSkillDiscovery.ts
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for skill discovery via the Claude SDK's reloadSkills API, adding new runtime behavior including SDK calls, filesystem checks, and new data flowing through provider capabilities. As a new capability from a first-time contributor, it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 2 times, most recently from 5c7932e to 138250aCompareJuly 23, 2026 16:15

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 138250a0b365d44904c05eec76871add7a7d1ea0. Configure here.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 5 times, most recently from 1339974 to f44f73bCompareJuly 23, 2026 22:27
colonelpanic8and others added 4 commits July 23, 2026 15:35
The Claude provider snapshot never populated `skills`, so Claude-provider
skills were absent from T3 Code's `$` skill picker (only Codex populated
them). Probe the SDK's `reloadSkills` control request after initialization
and map the returned entries into `ServerProviderSkill`s.
The new pure `parseClaudeReloadedSkills` mapper strips the trailing scope
suffix reloadSkills appends to descriptions (e.g. " (user)") and maps it to
a scope (user; project/local -> project; builtin/bundled/system -> system;
others verbatim). Paths are resolved best-effort against the workspace
`.claude/skills/<name>` (project) then the config dir `skills/<name>`
(user), falling back to a constructed config-dir path since the contract
requires a non-empty path; plugin-qualified names skip the filesystem probe.
The control request is bounded by its own timeout and failures fall back to
an empty list so older CLIs never fail the capability probe.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch from f44f73b to aac809eCompareJuly 23, 2026 22:35
@colonelpanic8

Copy link
Copy Markdown
ContributorAuthor

Superseded by the maintainer implementation in #4414, which is now merged. Closing this independent implementation in favor of the upstream-selected approach.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@colonelpanic8
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(claude): discover skills for the $ picker via SDK reloadSkills - #4325

Closed
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery
Closed

feat(claude): discover skills for the $ picker via SDK reloadSkills#4325
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery

Conversation

@colonelpanic8

@colonelpanic8colonelpanic8 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The Claude provider's capability probe now issues the Claude Agent SDK's reloadSkills control request after initializationResult() and maps the returned entries into ServerProviderSkills, populating skills on the provider snapshot.
  • New pure mapper parseClaudeReloadedSkills (apps/server/src/provider/Layers/ClaudeSkillDiscovery.ts):
    • strips the trailing scope suffix reloadSkills appends to descriptions (e.g. (user)) and maps it to a snapshot scope (user; project/localproject; builtin/bundled/systemsystem);
    • resolves each skill's path best-effort against the workspace .claude/skills/<name>, then the effective Claude config dir's skills/<name>, falling back to a constructed config-dir path (the contract requires a non-empty path); plugin-qualified names skip the filesystem probe;
    • dedupes by name and skips empty names, mirroring the existing slash-command handling.
  • The control request is bounded by its own 5s timeout and any failure falls back to an empty list, so older CLIs that don't answer reload_skills never fail the capability probe.
  • Slash commands are left untouched — skills legitimately also appear as / commands for Claude, matching upstream CLI behavior.

Why

Only the Codex provider populated skills, so the composer's $ skill picker was always empty on Claude threads even though the Claude CLI discovers the same ~/.claude/skills / .claude/skills entries (refs #1480, #2736). With this change Claude skills get the same $ autocomplete, inline pill rendering, and scope labels (Personal/Project/System) that Codex skills already have.

Checklist

  • Focused tests: vp test run ClaudeSkillDiscovery.test.ts ClaudeCapabilitiesProbe.test.ts ProviderRegistry.test.ts → 3 files, 53 tests passed (plus ClaudeAdapter.test.ts regression guard → 60 passed)
  • Typecheck: tsgo --noEmit in apps/server → 0 errors
  • Lint/format: vp lint on changed files, vp fmt → clean

🤖 Generated with Claude Code


Note

Medium Risk
Touches provider health probing and filesystem path resolution for user config; skill reload is isolated with timeouts so auth/command discovery should remain stable, but probe timing and path edge cases could affect the picker on some setups.

Overview
Claude skills now populate the provider snapshot so the composer $ picker can list them like Codex already does.

After a successful SDK initialization, probeClaudeCapabilities issues a best-effort reloadSkills call with its own timeout; failures yield an empty skill list but no longer fail the whole probe. Account info and slash commands are unchanged.

New parseClaudeReloadedSkills maps SDK entries to ServerProviderSkill: strips description scope suffixes (e.g. (user)), resolves paths under workspace .claude/skills or the effective config dir (with CLAUDE_CONFIG_DIR / HOME / USERPROFILE handling), and dedupes by name. checkClaudeProviderStatus threads skills into every built snapshot.

Reviewed by Cursor Bugbot for commit aac809e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude skills for the $ picker via SDK reloadSkills

  • After a successful capabilities probe, probeClaudeCapabilities issues a reloadSkills request to the Claude SDK subprocess and parses the response into ServerProviderSkill objects via the new parseClaudeReloadedSkills utility in ClaudeSkillDiscovery.ts.
  • Skill paths are resolved by checking <cwd>/.claude/skills/<name> then <configDir>/skills/<name>; scope is normalized from description suffix tokens or inferred from the resolved path.
  • The Claude config directory is derived from CLAUDE_CONFIG_DIR (with tilde expansion) or defaults to <home>/.claude, using a new resolveClaudeEnvironmentHomePath helper that prefers HOME over USERPROFILE.
  • Separate timeouts are now used for initialization and skills reload; a skills reload failure is non-fatal and only the initialization timeout causes the probe to return undefined.
  • The skills array is threaded through checkClaudeProviderStatus and included in the provider snapshot (empty when capabilities are absent).

Macroscope summarized aac809e.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eacd9fbe-7634-4689-be12-8058c40b45c7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts
Comment threadapps/server/src/provider/Layers/ClaudeSkillDiscovery.ts
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for skill discovery via the Claude SDK's reloadSkills API, adding new runtime behavior including SDK calls, filesystem checks, and new data flowing through provider capabilities. As a new capability from a first-time contributor, it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 2 times, most recently from 5c7932e to 138250aCompareJuly 23, 2026 16:15

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 138250a0b365d44904c05eec76871add7a7d1ea0. Configure here.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 5 times, most recently from 1339974 to f44f73bCompareJuly 23, 2026 22:27
colonelpanic8and others added 4 commits July 23, 2026 15:35
The Claude provider snapshot never populated `skills`, so Claude-provider
skills were absent from T3 Code's `$` skill picker (only Codex populated
them). Probe the SDK's `reloadSkills` control request after initialization
and map the returned entries into `ServerProviderSkill`s.
The new pure `parseClaudeReloadedSkills` mapper strips the trailing scope
suffix reloadSkills appends to descriptions (e.g. " (user)") and maps it to
a scope (user; project/local -> project; builtin/bundled/system -> system;
others verbatim). Paths are resolved best-effort against the workspace
`.claude/skills/<name>` (project) then the config dir `skills/<name>`
(user), falling back to a constructed config-dir path since the contract
requires a non-empty path; plugin-qualified names skip the filesystem probe.
The control request is bounded by its own timeout and failures fall back to
an empty list so older CLIs never fail the capability probe.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch from f44f73b to aac809eCompareJuly 23, 2026 22:35
@colonelpanic8

Copy link
Copy Markdown
ContributorAuthor

Superseded by the maintainer implementation in #4414, which is now merged. Closing this independent implementation in favor of the upstream-selected approach.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@colonelpanic8
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(claude): discover skills for the $ picker via SDK reloadSkills - #4325

Closed
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery
Closed

feat(claude): discover skills for the $ picker via SDK reloadSkills#4325
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery

Conversation

@colonelpanic8

@colonelpanic8colonelpanic8 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The Claude provider's capability probe now issues the Claude Agent SDK's reloadSkills control request after initializationResult() and maps the returned entries into ServerProviderSkills, populating skills on the provider snapshot.
  • New pure mapper parseClaudeReloadedSkills (apps/server/src/provider/Layers/ClaudeSkillDiscovery.ts):
    • strips the trailing scope suffix reloadSkills appends to descriptions (e.g. (user)) and maps it to a snapshot scope (user; project/localproject; builtin/bundled/systemsystem);
    • resolves each skill's path best-effort against the workspace .claude/skills/<name>, then the effective Claude config dir's skills/<name>, falling back to a constructed config-dir path (the contract requires a non-empty path); plugin-qualified names skip the filesystem probe;
    • dedupes by name and skips empty names, mirroring the existing slash-command handling.
  • The control request is bounded by its own 5s timeout and any failure falls back to an empty list, so older CLIs that don't answer reload_skills never fail the capability probe.
  • Slash commands are left untouched — skills legitimately also appear as / commands for Claude, matching upstream CLI behavior.

Why

Only the Codex provider populated skills, so the composer's $ skill picker was always empty on Claude threads even though the Claude CLI discovers the same ~/.claude/skills / .claude/skills entries (refs #1480, #2736). With this change Claude skills get the same $ autocomplete, inline pill rendering, and scope labels (Personal/Project/System) that Codex skills already have.

Checklist

  • Focused tests: vp test run ClaudeSkillDiscovery.test.ts ClaudeCapabilitiesProbe.test.ts ProviderRegistry.test.ts → 3 files, 53 tests passed (plus ClaudeAdapter.test.ts regression guard → 60 passed)
  • Typecheck: tsgo --noEmit in apps/server → 0 errors
  • Lint/format: vp lint on changed files, vp fmt → clean

🤖 Generated with Claude Code


Note

Medium Risk
Touches provider health probing and filesystem path resolution for user config; skill reload is isolated with timeouts so auth/command discovery should remain stable, but probe timing and path edge cases could affect the picker on some setups.

Overview
Claude skills now populate the provider snapshot so the composer $ picker can list them like Codex already does.

After a successful SDK initialization, probeClaudeCapabilities issues a best-effort reloadSkills call with its own timeout; failures yield an empty skill list but no longer fail the whole probe. Account info and slash commands are unchanged.

New parseClaudeReloadedSkills maps SDK entries to ServerProviderSkill: strips description scope suffixes (e.g. (user)), resolves paths under workspace .claude/skills or the effective config dir (with CLAUDE_CONFIG_DIR / HOME / USERPROFILE handling), and dedupes by name. checkClaudeProviderStatus threads skills into every built snapshot.

Reviewed by Cursor Bugbot for commit aac809e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude skills for the $ picker via SDK reloadSkills

  • After a successful capabilities probe, probeClaudeCapabilities issues a reloadSkills request to the Claude SDK subprocess and parses the response into ServerProviderSkill objects via the new parseClaudeReloadedSkills utility in ClaudeSkillDiscovery.ts.
  • Skill paths are resolved by checking <cwd>/.claude/skills/<name> then <configDir>/skills/<name>; scope is normalized from description suffix tokens or inferred from the resolved path.
  • The Claude config directory is derived from CLAUDE_CONFIG_DIR (with tilde expansion) or defaults to <home>/.claude, using a new resolveClaudeEnvironmentHomePath helper that prefers HOME over USERPROFILE.
  • Separate timeouts are now used for initialization and skills reload; a skills reload failure is non-fatal and only the initialization timeout causes the probe to return undefined.
  • The skills array is threaded through checkClaudeProviderStatus and included in the provider snapshot (empty when capabilities are absent).

Macroscope summarized aac809e.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eacd9fbe-7634-4689-be12-8058c40b45c7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts
Comment threadapps/server/src/provider/Layers/ClaudeSkillDiscovery.ts
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for skill discovery via the Claude SDK's reloadSkills API, adding new runtime behavior including SDK calls, filesystem checks, and new data flowing through provider capabilities. As a new capability from a first-time contributor, it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 2 times, most recently from 5c7932e to 138250aCompareJuly 23, 2026 16:15

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 138250a0b365d44904c05eec76871add7a7d1ea0. Configure here.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 5 times, most recently from 1339974 to f44f73bCompareJuly 23, 2026 22:27
colonelpanic8and others added 4 commits July 23, 2026 15:35
The Claude provider snapshot never populated `skills`, so Claude-provider
skills were absent from T3 Code's `$` skill picker (only Codex populated
them). Probe the SDK's `reloadSkills` control request after initialization
and map the returned entries into `ServerProviderSkill`s.
The new pure `parseClaudeReloadedSkills` mapper strips the trailing scope
suffix reloadSkills appends to descriptions (e.g. " (user)") and maps it to
a scope (user; project/local -> project; builtin/bundled/system -> system;
others verbatim). Paths are resolved best-effort against the workspace
`.claude/skills/<name>` (project) then the config dir `skills/<name>`
(user), falling back to a constructed config-dir path since the contract
requires a non-empty path; plugin-qualified names skip the filesystem probe.
The control request is bounded by its own timeout and failures fall back to
an empty list so older CLIs never fail the capability probe.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch from f44f73b to aac809eCompareJuly 23, 2026 22:35
@colonelpanic8

Copy link
Copy Markdown
ContributorAuthor

Superseded by the maintainer implementation in #4414, which is now merged. Closing this independent implementation in favor of the upstream-selected approach.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@colonelpanic8
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(claude): discover skills for the $ picker via SDK reloadSkills - #4325

Closed
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery
Closed

feat(claude): discover skills for the $ picker via SDK reloadSkills#4325
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery

Conversation

@colonelpanic8

@colonelpanic8colonelpanic8 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The Claude provider's capability probe now issues the Claude Agent SDK's reloadSkills control request after initializationResult() and maps the returned entries into ServerProviderSkills, populating skills on the provider snapshot.
  • New pure mapper parseClaudeReloadedSkills (apps/server/src/provider/Layers/ClaudeSkillDiscovery.ts):
    • strips the trailing scope suffix reloadSkills appends to descriptions (e.g. (user)) and maps it to a snapshot scope (user; project/localproject; builtin/bundled/systemsystem);
    • resolves each skill's path best-effort against the workspace .claude/skills/<name>, then the effective Claude config dir's skills/<name>, falling back to a constructed config-dir path (the contract requires a non-empty path); plugin-qualified names skip the filesystem probe;
    • dedupes by name and skips empty names, mirroring the existing slash-command handling.
  • The control request is bounded by its own 5s timeout and any failure falls back to an empty list, so older CLIs that don't answer reload_skills never fail the capability probe.
  • Slash commands are left untouched — skills legitimately also appear as / commands for Claude, matching upstream CLI behavior.

Why

Only the Codex provider populated skills, so the composer's $ skill picker was always empty on Claude threads even though the Claude CLI discovers the same ~/.claude/skills / .claude/skills entries (refs #1480, #2736). With this change Claude skills get the same $ autocomplete, inline pill rendering, and scope labels (Personal/Project/System) that Codex skills already have.

Checklist

  • Focused tests: vp test run ClaudeSkillDiscovery.test.ts ClaudeCapabilitiesProbe.test.ts ProviderRegistry.test.ts → 3 files, 53 tests passed (plus ClaudeAdapter.test.ts regression guard → 60 passed)
  • Typecheck: tsgo --noEmit in apps/server → 0 errors
  • Lint/format: vp lint on changed files, vp fmt → clean

🤖 Generated with Claude Code


Note

Medium Risk
Touches provider health probing and filesystem path resolution for user config; skill reload is isolated with timeouts so auth/command discovery should remain stable, but probe timing and path edge cases could affect the picker on some setups.

Overview
Claude skills now populate the provider snapshot so the composer $ picker can list them like Codex already does.

After a successful SDK initialization, probeClaudeCapabilities issues a best-effort reloadSkills call with its own timeout; failures yield an empty skill list but no longer fail the whole probe. Account info and slash commands are unchanged.

New parseClaudeReloadedSkills maps SDK entries to ServerProviderSkill: strips description scope suffixes (e.g. (user)), resolves paths under workspace .claude/skills or the effective config dir (with CLAUDE_CONFIG_DIR / HOME / USERPROFILE handling), and dedupes by name. checkClaudeProviderStatus threads skills into every built snapshot.

Reviewed by Cursor Bugbot for commit aac809e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude skills for the $ picker via SDK reloadSkills

  • After a successful capabilities probe, probeClaudeCapabilities issues a reloadSkills request to the Claude SDK subprocess and parses the response into ServerProviderSkill objects via the new parseClaudeReloadedSkills utility in ClaudeSkillDiscovery.ts.
  • Skill paths are resolved by checking <cwd>/.claude/skills/<name> then <configDir>/skills/<name>; scope is normalized from description suffix tokens or inferred from the resolved path.
  • The Claude config directory is derived from CLAUDE_CONFIG_DIR (with tilde expansion) or defaults to <home>/.claude, using a new resolveClaudeEnvironmentHomePath helper that prefers HOME over USERPROFILE.
  • Separate timeouts are now used for initialization and skills reload; a skills reload failure is non-fatal and only the initialization timeout causes the probe to return undefined.
  • The skills array is threaded through checkClaudeProviderStatus and included in the provider snapshot (empty when capabilities are absent).

Macroscope summarized aac809e.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eacd9fbe-7634-4689-be12-8058c40b45c7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts
Comment threadapps/server/src/provider/Layers/ClaudeSkillDiscovery.ts
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for skill discovery via the Claude SDK's reloadSkills API, adding new runtime behavior including SDK calls, filesystem checks, and new data flowing through provider capabilities. As a new capability from a first-time contributor, it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 2 times, most recently from 5c7932e to 138250aCompareJuly 23, 2026 16:15

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 138250a0b365d44904c05eec76871add7a7d1ea0. Configure here.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 5 times, most recently from 1339974 to f44f73bCompareJuly 23, 2026 22:27
colonelpanic8and others added 4 commits July 23, 2026 15:35
The Claude provider snapshot never populated `skills`, so Claude-provider
skills were absent from T3 Code's `$` skill picker (only Codex populated
them). Probe the SDK's `reloadSkills` control request after initialization
and map the returned entries into `ServerProviderSkill`s.
The new pure `parseClaudeReloadedSkills` mapper strips the trailing scope
suffix reloadSkills appends to descriptions (e.g. " (user)") and maps it to
a scope (user; project/local -> project; builtin/bundled/system -> system;
others verbatim). Paths are resolved best-effort against the workspace
`.claude/skills/<name>` (project) then the config dir `skills/<name>`
(user), falling back to a constructed config-dir path since the contract
requires a non-empty path; plugin-qualified names skip the filesystem probe.
The control request is bounded by its own timeout and failures fall back to
an empty list so older CLIs never fail the capability probe.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch from f44f73b to aac809eCompareJuly 23, 2026 22:35
@colonelpanic8

Copy link
Copy Markdown
ContributorAuthor

Superseded by the maintainer implementation in #4414, which is now merged. Closing this independent implementation in favor of the upstream-selected approach.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@colonelpanic8
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(claude): discover skills for the $ picker via SDK reloadSkills - #4325

Closed
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery
Closed

feat(claude): discover skills for the $ picker via SDK reloadSkills#4325
colonelpanic8 wants to merge 4 commits into
pingdotgg:mainfrom
colonelpanic8:feat/claude-skill-discovery

Conversation

@colonelpanic8

@colonelpanic8colonelpanic8 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The Claude provider's capability probe now issues the Claude Agent SDK's reloadSkills control request after initializationResult() and maps the returned entries into ServerProviderSkills, populating skills on the provider snapshot.
  • New pure mapper parseClaudeReloadedSkills (apps/server/src/provider/Layers/ClaudeSkillDiscovery.ts):
    • strips the trailing scope suffix reloadSkills appends to descriptions (e.g. (user)) and maps it to a snapshot scope (user; project/localproject; builtin/bundled/systemsystem);
    • resolves each skill's path best-effort against the workspace .claude/skills/<name>, then the effective Claude config dir's skills/<name>, falling back to a constructed config-dir path (the contract requires a non-empty path); plugin-qualified names skip the filesystem probe;
    • dedupes by name and skips empty names, mirroring the existing slash-command handling.
  • The control request is bounded by its own 5s timeout and any failure falls back to an empty list, so older CLIs that don't answer reload_skills never fail the capability probe.
  • Slash commands are left untouched — skills legitimately also appear as / commands for Claude, matching upstream CLI behavior.

Why

Only the Codex provider populated skills, so the composer's $ skill picker was always empty on Claude threads even though the Claude CLI discovers the same ~/.claude/skills / .claude/skills entries (refs #1480, #2736). With this change Claude skills get the same $ autocomplete, inline pill rendering, and scope labels (Personal/Project/System) that Codex skills already have.

Checklist

  • Focused tests: vp test run ClaudeSkillDiscovery.test.ts ClaudeCapabilitiesProbe.test.ts ProviderRegistry.test.ts → 3 files, 53 tests passed (plus ClaudeAdapter.test.ts regression guard → 60 passed)
  • Typecheck: tsgo --noEmit in apps/server → 0 errors
  • Lint/format: vp lint on changed files, vp fmt → clean

🤖 Generated with Claude Code


Note

Medium Risk
Touches provider health probing and filesystem path resolution for user config; skill reload is isolated with timeouts so auth/command discovery should remain stable, but probe timing and path edge cases could affect the picker on some setups.

Overview
Claude skills now populate the provider snapshot so the composer $ picker can list them like Codex already does.

After a successful SDK initialization, probeClaudeCapabilities issues a best-effort reloadSkills call with its own timeout; failures yield an empty skill list but no longer fail the whole probe. Account info and slash commands are unchanged.

New parseClaudeReloadedSkills maps SDK entries to ServerProviderSkill: strips description scope suffixes (e.g. (user)), resolves paths under workspace .claude/skills or the effective config dir (with CLAUDE_CONFIG_DIR / HOME / USERPROFILE handling), and dedupes by name. checkClaudeProviderStatus threads skills into every built snapshot.

Reviewed by Cursor Bugbot for commit aac809e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude skills for the $ picker via SDK reloadSkills

  • After a successful capabilities probe, probeClaudeCapabilities issues a reloadSkills request to the Claude SDK subprocess and parses the response into ServerProviderSkill objects via the new parseClaudeReloadedSkills utility in ClaudeSkillDiscovery.ts.
  • Skill paths are resolved by checking <cwd>/.claude/skills/<name> then <configDir>/skills/<name>; scope is normalized from description suffix tokens or inferred from the resolved path.
  • The Claude config directory is derived from CLAUDE_CONFIG_DIR (with tilde expansion) or defaults to <home>/.claude, using a new resolveClaudeEnvironmentHomePath helper that prefers HOME over USERPROFILE.
  • Separate timeouts are now used for initialization and skills reload; a skills reload failure is non-fatal and only the initialization timeout causes the probe to return undefined.
  • The skills array is threaded through checkClaudeProviderStatus and included in the provider snapshot (empty when capabilities are absent).

Macroscope summarized aac809e.

@coderabbitai

coderabbitaiBot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eacd9fbe-7634-4689-be12-8058c40b45c7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 23, 2026
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts
Comment threadapps/server/src/provider/Layers/ClaudeSkillDiscovery.ts
@macroscopeapp

macroscopeappBot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for skill discovery via the Claude SDK's reloadSkills API, adding new runtime behavior including SDK calls, filesystem checks, and new data flowing through provider capabilities. As a new capability from a first-time contributor, it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 2 times, most recently from 5c7932e to 138250aCompareJuly 23, 2026 16:15

@cursorcursorBot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 138250a0b365d44904c05eec76871add7a7d1ea0. Configure here.

Comment threadapps/server/src/provider/Layers/ClaudeProvider.ts Outdated
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch 5 times, most recently from 1339974 to f44f73bCompareJuly 23, 2026 22:27
colonelpanic8and others added 4 commits July 23, 2026 15:35
The Claude provider snapshot never populated `skills`, so Claude-provider
skills were absent from T3 Code's `$` skill picker (only Codex populated
them). Probe the SDK's `reloadSkills` control request after initialization
and map the returned entries into `ServerProviderSkill`s.
The new pure `parseClaudeReloadedSkills` mapper strips the trailing scope
suffix reloadSkills appends to descriptions (e.g. " (user)") and maps it to
a scope (user; project/local -> project; builtin/bundled/system -> system;
others verbatim). Paths are resolved best-effort against the workspace
`.claude/skills/<name>` (project) then the config dir `skills/<name>`
(user), falling back to a constructed config-dir path since the contract
requires a non-empty path; plugin-qualified names skip the filesystem probe.
The control request is bounded by its own timeout and failures fall back to
an empty list so older CLIs never fail the capability probe.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@colonelpanic8
colonelpanic8force-pushed the feat/claude-skill-discovery branch from f44f73b to aac809eCompareJuly 23, 2026 22:35
@colonelpanic8

Copy link
Copy Markdown
ContributorAuthor

Superseded by the maintainer implementation in #4414, which is now merged. Closing this independent implementation in favor of the upstream-selected approach.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@colonelpanic8