fix(claude): skills picked from the composer now run - #9128

Merged
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer
Sep 2, 2026
Merged

fix(claude): skills picked from the composer now run#9128
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 1, 2026

Copy link
Copy Markdown
Member

Picking a skill from the $ menu did nothing useful on Claude. The composer inserts $name for every provider. Codex reads that natively, but Claude Code treats it as prose, so the agent guessed at a skill it could see and sometimes ran a different one. One user picked $re-release-version and the agent cut a whole new release with release-version instead. Skills marked disable-model-invocation never ran at all, and skills switched off in Claude's settings still showed up in the picker.

Fix

Claude Code runs a skill only from a message whose last text block starts with /name. The Claude adapter now splits the outgoing message around the last $skill mention: the text before it stays as its own block, and the mention plus everything after becomes a trailing /name args block that the CLI expands itself. So ok, now $implement all the tickets goes to Claude as two blocks, ok, now and /implement all the tickets. The user's message and the timeline stay unchanged, and a skill runs from anywhere in the message, the same as on Codex. Skills marked disable-model-invocation work because you picked them, which is the user invocation Claude asks for. Earlier mentions in the same message are rewritten to /name inline so the model starts them through its Skill tool.

Discovery now reads disable-model-invocation, user-invocable, and the skillOverrides map from Claude's settings files, identifies skills by directory name, and lets the user scope win collisions, all matching the CLI. Skills switched off or reserved for the agent leave both pickers and are never dispatched.

Provider slash commands are only offered in the / menu where they open the message, since that is the only place a provider expands them. Skills are no longer position-gated there.

Behavior was verified against Claude Code 2.1.237 in stream-json mode: the last-text-block rule, the image ordering rule, and the one-skill-per-message limit (anthropics/claude-code#87113).

Supersedes #7673, #8336, and #9105. The discovery work is cherry-picked from #7673 with Rodrigo's authorship kept.

Fixes#7671
Fixes#8295

Verification

  • Server: 182 tests across skill discovery, skill dispatch, and the Claude adapter, including new cases for mid-prompt dispatch, image ordering, and disabled skills left as prose.
  • Clients: 26 tests across client-runtime, web skill search, slash menu position, and the mobile menu hook.
  • Typecheck clean for contracts, client-runtime, server, web, and mobile. Scoped lint and format clean.

Made by Claude Fable 5.1 via Claude Code.


Note

Medium Risk
Changes Claude turn payload shaping and per-send filesystem/settings skill scans; wrong dispatch or override parsing could run the wrong skill or skip valid picks.

Overview
Composer $skill picks on Claude now reach the CLI as /name blocks instead of inert prose. The adapter adds planClaudeSkillDispatch, which rewrites the last known skill mention into a trailing slash command (with images ordered before that block) and turns earlier mentions into inline /name text; disabled, unknown, or agent-only skills stay literal.

Claude skill discovery is realigned with Claude Code: scan user and .claude/skills only (drop .agents/skills), resolve names from directory names with user scope winning collisions, and merge skillOverrides from the same settings stack the CLI uses. Skills expose userInvocationOnly / userInvocable on the contract, and isProviderSkillUserInvocable filters composer search and slash menus.

Slash autocomplete now hides provider-native commands when the / trigger is not at message start; skills stay available on any line because the server dispatches them from any position. User docs describe the new behavior.

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

Note

Fix composer-selected skills so they run and filter agent-only skills from autocomplete

Fixes the useComposerCommandMenu hook so skills chosen from the composer menu are user-invocable. It now filters skill results to enabled, non-agent-only skills and restricts provider slash commands to message position zero; built-in commands and skills remain available at other positions.

  • Risk: provider-native slash commands no longer appear once the prompt has non-whitespace content before the trigger; users relying on mid-message provider commands will lose that autocomplete.

Macroscope summarized 8f27b8e.

rodrigoB-CBand others added 2 commits September 1, 2026 16:32
Skill discovery read only name and description from SKILL.md and
hardcoded every skill as enabled. Claude Code also honours
disable-model-invocation, user-invocable, and the skillOverrides map in
its settings files, so the composer offered skills the CLI would refuse.
Parse those flags, merge skillOverrides from the user, project, local,
and managed settings files, identify skills by directory name, and let
the user scope win name collisions. All three match the CLI's behaviour.
Cherry-picked from #7673.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Picking a skill inserted `$name` for every provider. Codex reads that
natively, but Claude Code treats it as prose, so the agent guessed at a
skill it could see and sometimes ran the wrong one. Claude Code runs a
skill only from a message whose last text block starts with `/name`.
The Claude adapter now splits the outgoing message around the last
`$skill` mention: the text before it stays as its own block, and the
mention plus everything after becomes a trailing `/name args` block that
the CLI expands itself. The user's message and the timeline are
unchanged. Earlier mentions in the same message are rewritten to `/name`
inline so the model starts them through its Skill tool. Skills switched
off in Claude's settings or reserved for the agent are left out of both
pickers and never dispatched.
Provider slash commands are only offered where they open the message on
web and mobile, since that is the only place a provider expands them.
Skills are no longer position-gated in the `/` menu.
Discovery changes cherry-picked from #7673 by Rodrigo Brechard.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/server/src/provider/Drivers/ClaudeSkills.ts
Comment threadapps/server/src/provider/Drivers/ClaudeSkillDispatch.ts
@github-actions

github-actionsBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.4 KiB+139 B (+1.0%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB0 B (0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.5 KiB+139 B (+2.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB57.0 KiB+1.4 KiB (+2.6%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.2 KiB13.2 KiB+97 B (+0.7%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−1 B (−0.0%)7.3 KiB
ClaudeLive turn WebSocket wire6.3 KiB6.4 KiB+98 B (+1.5%)7.8 KiB
ClaudeLive turn WebSocket decoded55.5 KiB56.3 KiB+840 B (+1.5%)66.4 KiB
ClaudeLive turn messages880 (0.0%)21

Baseline: 04efa79 · PR result: 8f27b8e · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

…kspace
Claude Code reads the repository root's `.claude/settings.local.json`
from a nested cwd and lets it outrank the workspace's own local file, so
a user skill switched off at the root was offered and dispatched from a
sub-package workspace. Walk up to the nearest `.git` and merge that file
in the CLI's order. The root's plain `settings.json` is not read, which
matches the CLI.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This change introduces Claude-native skill execution, new settings and invocation-policy handling, and altered composer behavior across web, mobile, and server layers. Its runtime scope extends beyond a small isolated fix, particularly because existing Claude prompt and skill-resolution paths now behave differently.

You can add or adjust custom eligibility rules. Learn more.

…ode does
Two discovery details did not match the CLI. Claude Code validates the
whole skillOverrides map, so one unknown or boolean value makes it drop
every override in that file; discovery applied the valid siblings. And
Claude Code never loads `.agents/skills`, so a skill living only there
was offered and dispatched to an `Unknown command` reply. Both verified
against the CLI and matched.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@t3dotgg
t3dotgg merged commit ea71a19 into mainSep 2, 2026
27 checks passed
@t3dotgg
t3dotgg deleted the t3code/fix-skills-anywhere-composer branch September 2, 2026 00:44
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Upstream pingdotgg#9128 now invokes composer $skill picks on Claude. Grok still
only expands /name, so the wire rewrite stays as the remaining delta.
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

2 participants

@t3dotgg@rodrigoB-CB
, '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

fix(claude): skills picked from the composer now run - #9128

Merged
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer
Sep 2, 2026
Merged

fix(claude): skills picked from the composer now run#9128
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 1, 2026

Copy link
Copy Markdown
Member

Picking a skill from the $ menu did nothing useful on Claude. The composer inserts $name for every provider. Codex reads that natively, but Claude Code treats it as prose, so the agent guessed at a skill it could see and sometimes ran a different one. One user picked $re-release-version and the agent cut a whole new release with release-version instead. Skills marked disable-model-invocation never ran at all, and skills switched off in Claude's settings still showed up in the picker.

Fix

Claude Code runs a skill only from a message whose last text block starts with /name. The Claude adapter now splits the outgoing message around the last $skill mention: the text before it stays as its own block, and the mention plus everything after becomes a trailing /name args block that the CLI expands itself. So ok, now $implement all the tickets goes to Claude as two blocks, ok, now and /implement all the tickets. The user's message and the timeline stay unchanged, and a skill runs from anywhere in the message, the same as on Codex. Skills marked disable-model-invocation work because you picked them, which is the user invocation Claude asks for. Earlier mentions in the same message are rewritten to /name inline so the model starts them through its Skill tool.

Discovery now reads disable-model-invocation, user-invocable, and the skillOverrides map from Claude's settings files, identifies skills by directory name, and lets the user scope win collisions, all matching the CLI. Skills switched off or reserved for the agent leave both pickers and are never dispatched.

Provider slash commands are only offered in the / menu where they open the message, since that is the only place a provider expands them. Skills are no longer position-gated there.

Behavior was verified against Claude Code 2.1.237 in stream-json mode: the last-text-block rule, the image ordering rule, and the one-skill-per-message limit (anthropics/claude-code#87113).

Supersedes #7673, #8336, and #9105. The discovery work is cherry-picked from #7673 with Rodrigo's authorship kept.

Fixes#7671
Fixes#8295

Verification

  • Server: 182 tests across skill discovery, skill dispatch, and the Claude adapter, including new cases for mid-prompt dispatch, image ordering, and disabled skills left as prose.
  • Clients: 26 tests across client-runtime, web skill search, slash menu position, and the mobile menu hook.
  • Typecheck clean for contracts, client-runtime, server, web, and mobile. Scoped lint and format clean.

Made by Claude Fable 5.1 via Claude Code.


Note

Medium Risk
Changes Claude turn payload shaping and per-send filesystem/settings skill scans; wrong dispatch or override parsing could run the wrong skill or skip valid picks.

Overview
Composer $skill picks on Claude now reach the CLI as /name blocks instead of inert prose. The adapter adds planClaudeSkillDispatch, which rewrites the last known skill mention into a trailing slash command (with images ordered before that block) and turns earlier mentions into inline /name text; disabled, unknown, or agent-only skills stay literal.

Claude skill discovery is realigned with Claude Code: scan user and .claude/skills only (drop .agents/skills), resolve names from directory names with user scope winning collisions, and merge skillOverrides from the same settings stack the CLI uses. Skills expose userInvocationOnly / userInvocable on the contract, and isProviderSkillUserInvocable filters composer search and slash menus.

Slash autocomplete now hides provider-native commands when the / trigger is not at message start; skills stay available on any line because the server dispatches them from any position. User docs describe the new behavior.

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

Note

Fix composer-selected skills so they run and filter agent-only skills from autocomplete

Fixes the useComposerCommandMenu hook so skills chosen from the composer menu are user-invocable. It now filters skill results to enabled, non-agent-only skills and restricts provider slash commands to message position zero; built-in commands and skills remain available at other positions.

  • Risk: provider-native slash commands no longer appear once the prompt has non-whitespace content before the trigger; users relying on mid-message provider commands will lose that autocomplete.

Macroscope summarized 8f27b8e.

rodrigoB-CBand others added 2 commits September 1, 2026 16:32
Skill discovery read only name and description from SKILL.md and
hardcoded every skill as enabled. Claude Code also honours
disable-model-invocation, user-invocable, and the skillOverrides map in
its settings files, so the composer offered skills the CLI would refuse.
Parse those flags, merge skillOverrides from the user, project, local,
and managed settings files, identify skills by directory name, and let
the user scope win name collisions. All three match the CLI's behaviour.
Cherry-picked from #7673.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Picking a skill inserted `$name` for every provider. Codex reads that
natively, but Claude Code treats it as prose, so the agent guessed at a
skill it could see and sometimes ran the wrong one. Claude Code runs a
skill only from a message whose last text block starts with `/name`.
The Claude adapter now splits the outgoing message around the last
`$skill` mention: the text before it stays as its own block, and the
mention plus everything after becomes a trailing `/name args` block that
the CLI expands itself. The user's message and the timeline are
unchanged. Earlier mentions in the same message are rewritten to `/name`
inline so the model starts them through its Skill tool. Skills switched
off in Claude's settings or reserved for the agent are left out of both
pickers and never dispatched.
Provider slash commands are only offered where they open the message on
web and mobile, since that is the only place a provider expands them.
Skills are no longer position-gated in the `/` menu.
Discovery changes cherry-picked from #7673 by Rodrigo Brechard.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/server/src/provider/Drivers/ClaudeSkills.ts
Comment threadapps/server/src/provider/Drivers/ClaudeSkillDispatch.ts
@github-actions

github-actionsBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.4 KiB+139 B (+1.0%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB0 B (0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.5 KiB+139 B (+2.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB57.0 KiB+1.4 KiB (+2.6%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.2 KiB13.2 KiB+97 B (+0.7%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−1 B (−0.0%)7.3 KiB
ClaudeLive turn WebSocket wire6.3 KiB6.4 KiB+98 B (+1.5%)7.8 KiB
ClaudeLive turn WebSocket decoded55.5 KiB56.3 KiB+840 B (+1.5%)66.4 KiB
ClaudeLive turn messages880 (0.0%)21

Baseline: 04efa79 · PR result: 8f27b8e · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

…kspace
Claude Code reads the repository root's `.claude/settings.local.json`
from a nested cwd and lets it outrank the workspace's own local file, so
a user skill switched off at the root was offered and dispatched from a
sub-package workspace. Walk up to the nearest `.git` and merge that file
in the CLI's order. The root's plain `settings.json` is not read, which
matches the CLI.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This change introduces Claude-native skill execution, new settings and invocation-policy handling, and altered composer behavior across web, mobile, and server layers. Its runtime scope extends beyond a small isolated fix, particularly because existing Claude prompt and skill-resolution paths now behave differently.

You can add or adjust custom eligibility rules. Learn more.

…ode does
Two discovery details did not match the CLI. Claude Code validates the
whole skillOverrides map, so one unknown or boolean value makes it drop
every override in that file; discovery applied the valid siblings. And
Claude Code never loads `.agents/skills`, so a skill living only there
was offered and dispatched to an `Unknown command` reply. Both verified
against the CLI and matched.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@t3dotgg
t3dotgg merged commit ea71a19 into mainSep 2, 2026
27 checks passed
@t3dotgg
t3dotgg deleted the t3code/fix-skills-anywhere-composer branch September 2, 2026 00:44
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Upstream pingdotgg#9128 now invokes composer $skill picks on Claude. Grok still
only expands /name, so the wire rewrite stays as the remaining delta.
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

2 participants

@t3dotgg@rodrigoB-CB
, '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

fix(claude): skills picked from the composer now run - #9128

Merged
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer
Sep 2, 2026
Merged

fix(claude): skills picked from the composer now run#9128
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 1, 2026

Copy link
Copy Markdown
Member

Picking a skill from the $ menu did nothing useful on Claude. The composer inserts $name for every provider. Codex reads that natively, but Claude Code treats it as prose, so the agent guessed at a skill it could see and sometimes ran a different one. One user picked $re-release-version and the agent cut a whole new release with release-version instead. Skills marked disable-model-invocation never ran at all, and skills switched off in Claude's settings still showed up in the picker.

Fix

Claude Code runs a skill only from a message whose last text block starts with /name. The Claude adapter now splits the outgoing message around the last $skill mention: the text before it stays as its own block, and the mention plus everything after becomes a trailing /name args block that the CLI expands itself. So ok, now $implement all the tickets goes to Claude as two blocks, ok, now and /implement all the tickets. The user's message and the timeline stay unchanged, and a skill runs from anywhere in the message, the same as on Codex. Skills marked disable-model-invocation work because you picked them, which is the user invocation Claude asks for. Earlier mentions in the same message are rewritten to /name inline so the model starts them through its Skill tool.

Discovery now reads disable-model-invocation, user-invocable, and the skillOverrides map from Claude's settings files, identifies skills by directory name, and lets the user scope win collisions, all matching the CLI. Skills switched off or reserved for the agent leave both pickers and are never dispatched.

Provider slash commands are only offered in the / menu where they open the message, since that is the only place a provider expands them. Skills are no longer position-gated there.

Behavior was verified against Claude Code 2.1.237 in stream-json mode: the last-text-block rule, the image ordering rule, and the one-skill-per-message limit (anthropics/claude-code#87113).

Supersedes #7673, #8336, and #9105. The discovery work is cherry-picked from #7673 with Rodrigo's authorship kept.

Fixes#7671
Fixes#8295

Verification

  • Server: 182 tests across skill discovery, skill dispatch, and the Claude adapter, including new cases for mid-prompt dispatch, image ordering, and disabled skills left as prose.
  • Clients: 26 tests across client-runtime, web skill search, slash menu position, and the mobile menu hook.
  • Typecheck clean for contracts, client-runtime, server, web, and mobile. Scoped lint and format clean.

Made by Claude Fable 5.1 via Claude Code.


Note

Medium Risk
Changes Claude turn payload shaping and per-send filesystem/settings skill scans; wrong dispatch or override parsing could run the wrong skill or skip valid picks.

Overview
Composer $skill picks on Claude now reach the CLI as /name blocks instead of inert prose. The adapter adds planClaudeSkillDispatch, which rewrites the last known skill mention into a trailing slash command (with images ordered before that block) and turns earlier mentions into inline /name text; disabled, unknown, or agent-only skills stay literal.

Claude skill discovery is realigned with Claude Code: scan user and .claude/skills only (drop .agents/skills), resolve names from directory names with user scope winning collisions, and merge skillOverrides from the same settings stack the CLI uses. Skills expose userInvocationOnly / userInvocable on the contract, and isProviderSkillUserInvocable filters composer search and slash menus.

Slash autocomplete now hides provider-native commands when the / trigger is not at message start; skills stay available on any line because the server dispatches them from any position. User docs describe the new behavior.

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

Note

Fix composer-selected skills so they run and filter agent-only skills from autocomplete

Fixes the useComposerCommandMenu hook so skills chosen from the composer menu are user-invocable. It now filters skill results to enabled, non-agent-only skills and restricts provider slash commands to message position zero; built-in commands and skills remain available at other positions.

  • Risk: provider-native slash commands no longer appear once the prompt has non-whitespace content before the trigger; users relying on mid-message provider commands will lose that autocomplete.

Macroscope summarized 8f27b8e.

rodrigoB-CBand others added 2 commits September 1, 2026 16:32
Skill discovery read only name and description from SKILL.md and
hardcoded every skill as enabled. Claude Code also honours
disable-model-invocation, user-invocable, and the skillOverrides map in
its settings files, so the composer offered skills the CLI would refuse.
Parse those flags, merge skillOverrides from the user, project, local,
and managed settings files, identify skills by directory name, and let
the user scope win name collisions. All three match the CLI's behaviour.
Cherry-picked from #7673.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Picking a skill inserted `$name` for every provider. Codex reads that
natively, but Claude Code treats it as prose, so the agent guessed at a
skill it could see and sometimes ran the wrong one. Claude Code runs a
skill only from a message whose last text block starts with `/name`.
The Claude adapter now splits the outgoing message around the last
`$skill` mention: the text before it stays as its own block, and the
mention plus everything after becomes a trailing `/name args` block that
the CLI expands itself. The user's message and the timeline are
unchanged. Earlier mentions in the same message are rewritten to `/name`
inline so the model starts them through its Skill tool. Skills switched
off in Claude's settings or reserved for the agent are left out of both
pickers and never dispatched.
Provider slash commands are only offered where they open the message on
web and mobile, since that is the only place a provider expands them.
Skills are no longer position-gated in the `/` menu.
Discovery changes cherry-picked from #7673 by Rodrigo Brechard.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/server/src/provider/Drivers/ClaudeSkills.ts
Comment threadapps/server/src/provider/Drivers/ClaudeSkillDispatch.ts
@github-actions

github-actionsBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.4 KiB+139 B (+1.0%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB0 B (0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.5 KiB+139 B (+2.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB57.0 KiB+1.4 KiB (+2.6%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.2 KiB13.2 KiB+97 B (+0.7%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−1 B (−0.0%)7.3 KiB
ClaudeLive turn WebSocket wire6.3 KiB6.4 KiB+98 B (+1.5%)7.8 KiB
ClaudeLive turn WebSocket decoded55.5 KiB56.3 KiB+840 B (+1.5%)66.4 KiB
ClaudeLive turn messages880 (0.0%)21

Baseline: 04efa79 · PR result: 8f27b8e · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

…kspace
Claude Code reads the repository root's `.claude/settings.local.json`
from a nested cwd and lets it outrank the workspace's own local file, so
a user skill switched off at the root was offered and dispatched from a
sub-package workspace. Walk up to the nearest `.git` and merge that file
in the CLI's order. The root's plain `settings.json` is not read, which
matches the CLI.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This change introduces Claude-native skill execution, new settings and invocation-policy handling, and altered composer behavior across web, mobile, and server layers. Its runtime scope extends beyond a small isolated fix, particularly because existing Claude prompt and skill-resolution paths now behave differently.

You can add or adjust custom eligibility rules. Learn more.

…ode does
Two discovery details did not match the CLI. Claude Code validates the
whole skillOverrides map, so one unknown or boolean value makes it drop
every override in that file; discovery applied the valid siblings. And
Claude Code never loads `.agents/skills`, so a skill living only there
was offered and dispatched to an `Unknown command` reply. Both verified
against the CLI and matched.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@t3dotgg
t3dotgg merged commit ea71a19 into mainSep 2, 2026
27 checks passed
@t3dotgg
t3dotgg deleted the t3code/fix-skills-anywhere-composer branch September 2, 2026 00:44
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Upstream pingdotgg#9128 now invokes composer $skill picks on Claude. Grok still
only expands /name, so the wire rewrite stays as the remaining delta.
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

2 participants

@t3dotgg@rodrigoB-CB
, '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

fix(claude): skills picked from the composer now run - #9128

Merged
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer
Sep 2, 2026
Merged

fix(claude): skills picked from the composer now run#9128
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 1, 2026

Copy link
Copy Markdown
Member

Picking a skill from the $ menu did nothing useful on Claude. The composer inserts $name for every provider. Codex reads that natively, but Claude Code treats it as prose, so the agent guessed at a skill it could see and sometimes ran a different one. One user picked $re-release-version and the agent cut a whole new release with release-version instead. Skills marked disable-model-invocation never ran at all, and skills switched off in Claude's settings still showed up in the picker.

Fix

Claude Code runs a skill only from a message whose last text block starts with /name. The Claude adapter now splits the outgoing message around the last $skill mention: the text before it stays as its own block, and the mention plus everything after becomes a trailing /name args block that the CLI expands itself. So ok, now $implement all the tickets goes to Claude as two blocks, ok, now and /implement all the tickets. The user's message and the timeline stay unchanged, and a skill runs from anywhere in the message, the same as on Codex. Skills marked disable-model-invocation work because you picked them, which is the user invocation Claude asks for. Earlier mentions in the same message are rewritten to /name inline so the model starts them through its Skill tool.

Discovery now reads disable-model-invocation, user-invocable, and the skillOverrides map from Claude's settings files, identifies skills by directory name, and lets the user scope win collisions, all matching the CLI. Skills switched off or reserved for the agent leave both pickers and are never dispatched.

Provider slash commands are only offered in the / menu where they open the message, since that is the only place a provider expands them. Skills are no longer position-gated there.

Behavior was verified against Claude Code 2.1.237 in stream-json mode: the last-text-block rule, the image ordering rule, and the one-skill-per-message limit (anthropics/claude-code#87113).

Supersedes #7673, #8336, and #9105. The discovery work is cherry-picked from #7673 with Rodrigo's authorship kept.

Fixes#7671
Fixes#8295

Verification

  • Server: 182 tests across skill discovery, skill dispatch, and the Claude adapter, including new cases for mid-prompt dispatch, image ordering, and disabled skills left as prose.
  • Clients: 26 tests across client-runtime, web skill search, slash menu position, and the mobile menu hook.
  • Typecheck clean for contracts, client-runtime, server, web, and mobile. Scoped lint and format clean.

Made by Claude Fable 5.1 via Claude Code.


Note

Medium Risk
Changes Claude turn payload shaping and per-send filesystem/settings skill scans; wrong dispatch or override parsing could run the wrong skill or skip valid picks.

Overview
Composer $skill picks on Claude now reach the CLI as /name blocks instead of inert prose. The adapter adds planClaudeSkillDispatch, which rewrites the last known skill mention into a trailing slash command (with images ordered before that block) and turns earlier mentions into inline /name text; disabled, unknown, or agent-only skills stay literal.

Claude skill discovery is realigned with Claude Code: scan user and .claude/skills only (drop .agents/skills), resolve names from directory names with user scope winning collisions, and merge skillOverrides from the same settings stack the CLI uses. Skills expose userInvocationOnly / userInvocable on the contract, and isProviderSkillUserInvocable filters composer search and slash menus.

Slash autocomplete now hides provider-native commands when the / trigger is not at message start; skills stay available on any line because the server dispatches them from any position. User docs describe the new behavior.

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

Note

Fix composer-selected skills so they run and filter agent-only skills from autocomplete

Fixes the useComposerCommandMenu hook so skills chosen from the composer menu are user-invocable. It now filters skill results to enabled, non-agent-only skills and restricts provider slash commands to message position zero; built-in commands and skills remain available at other positions.

  • Risk: provider-native slash commands no longer appear once the prompt has non-whitespace content before the trigger; users relying on mid-message provider commands will lose that autocomplete.

Macroscope summarized 8f27b8e.

rodrigoB-CBand others added 2 commits September 1, 2026 16:32
Skill discovery read only name and description from SKILL.md and
hardcoded every skill as enabled. Claude Code also honours
disable-model-invocation, user-invocable, and the skillOverrides map in
its settings files, so the composer offered skills the CLI would refuse.
Parse those flags, merge skillOverrides from the user, project, local,
and managed settings files, identify skills by directory name, and let
the user scope win name collisions. All three match the CLI's behaviour.
Cherry-picked from #7673.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Picking a skill inserted `$name` for every provider. Codex reads that
natively, but Claude Code treats it as prose, so the agent guessed at a
skill it could see and sometimes ran the wrong one. Claude Code runs a
skill only from a message whose last text block starts with `/name`.
The Claude adapter now splits the outgoing message around the last
`$skill` mention: the text before it stays as its own block, and the
mention plus everything after becomes a trailing `/name args` block that
the CLI expands itself. The user's message and the timeline are
unchanged. Earlier mentions in the same message are rewritten to `/name`
inline so the model starts them through its Skill tool. Skills switched
off in Claude's settings or reserved for the agent are left out of both
pickers and never dispatched.
Provider slash commands are only offered where they open the message on
web and mobile, since that is the only place a provider expands them.
Skills are no longer position-gated in the `/` menu.
Discovery changes cherry-picked from #7673 by Rodrigo Brechard.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/server/src/provider/Drivers/ClaudeSkills.ts
Comment threadapps/server/src/provider/Drivers/ClaudeSkillDispatch.ts
@github-actions

github-actionsBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.4 KiB+139 B (+1.0%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB0 B (0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.5 KiB+139 B (+2.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB57.0 KiB+1.4 KiB (+2.6%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.2 KiB13.2 KiB+97 B (+0.7%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−1 B (−0.0%)7.3 KiB
ClaudeLive turn WebSocket wire6.3 KiB6.4 KiB+98 B (+1.5%)7.8 KiB
ClaudeLive turn WebSocket decoded55.5 KiB56.3 KiB+840 B (+1.5%)66.4 KiB
ClaudeLive turn messages880 (0.0%)21

Baseline: 04efa79 · PR result: 8f27b8e · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

…kspace
Claude Code reads the repository root's `.claude/settings.local.json`
from a nested cwd and lets it outrank the workspace's own local file, so
a user skill switched off at the root was offered and dispatched from a
sub-package workspace. Walk up to the nearest `.git` and merge that file
in the CLI's order. The root's plain `settings.json` is not read, which
matches the CLI.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This change introduces Claude-native skill execution, new settings and invocation-policy handling, and altered composer behavior across web, mobile, and server layers. Its runtime scope extends beyond a small isolated fix, particularly because existing Claude prompt and skill-resolution paths now behave differently.

You can add or adjust custom eligibility rules. Learn more.

…ode does
Two discovery details did not match the CLI. Claude Code validates the
whole skillOverrides map, so one unknown or boolean value makes it drop
every override in that file; discovery applied the valid siblings. And
Claude Code never loads `.agents/skills`, so a skill living only there
was offered and dispatched to an `Unknown command` reply. Both verified
against the CLI and matched.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@t3dotgg
t3dotgg merged commit ea71a19 into mainSep 2, 2026
27 checks passed
@t3dotgg
t3dotgg deleted the t3code/fix-skills-anywhere-composer branch September 2, 2026 00:44
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Upstream pingdotgg#9128 now invokes composer $skill picks on Claude. Grok still
only expands /name, so the wire rewrite stays as the remaining delta.
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

2 participants

@t3dotgg@rodrigoB-CB
, '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

fix(claude): skills picked from the composer now run - #9128

Merged
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer
Sep 2, 2026
Merged

fix(claude): skills picked from the composer now run#9128
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 1, 2026

Copy link
Copy Markdown
Member

Picking a skill from the $ menu did nothing useful on Claude. The composer inserts $name for every provider. Codex reads that natively, but Claude Code treats it as prose, so the agent guessed at a skill it could see and sometimes ran a different one. One user picked $re-release-version and the agent cut a whole new release with release-version instead. Skills marked disable-model-invocation never ran at all, and skills switched off in Claude's settings still showed up in the picker.

Fix

Claude Code runs a skill only from a message whose last text block starts with /name. The Claude adapter now splits the outgoing message around the last $skill mention: the text before it stays as its own block, and the mention plus everything after becomes a trailing /name args block that the CLI expands itself. So ok, now $implement all the tickets goes to Claude as two blocks, ok, now and /implement all the tickets. The user's message and the timeline stay unchanged, and a skill runs from anywhere in the message, the same as on Codex. Skills marked disable-model-invocation work because you picked them, which is the user invocation Claude asks for. Earlier mentions in the same message are rewritten to /name inline so the model starts them through its Skill tool.

Discovery now reads disable-model-invocation, user-invocable, and the skillOverrides map from Claude's settings files, identifies skills by directory name, and lets the user scope win collisions, all matching the CLI. Skills switched off or reserved for the agent leave both pickers and are never dispatched.

Provider slash commands are only offered in the / menu where they open the message, since that is the only place a provider expands them. Skills are no longer position-gated there.

Behavior was verified against Claude Code 2.1.237 in stream-json mode: the last-text-block rule, the image ordering rule, and the one-skill-per-message limit (anthropics/claude-code#87113).

Supersedes #7673, #8336, and #9105. The discovery work is cherry-picked from #7673 with Rodrigo's authorship kept.

Fixes#7671
Fixes#8295

Verification

  • Server: 182 tests across skill discovery, skill dispatch, and the Claude adapter, including new cases for mid-prompt dispatch, image ordering, and disabled skills left as prose.
  • Clients: 26 tests across client-runtime, web skill search, slash menu position, and the mobile menu hook.
  • Typecheck clean for contracts, client-runtime, server, web, and mobile. Scoped lint and format clean.

Made by Claude Fable 5.1 via Claude Code.


Note

Medium Risk
Changes Claude turn payload shaping and per-send filesystem/settings skill scans; wrong dispatch or override parsing could run the wrong skill or skip valid picks.

Overview
Composer $skill picks on Claude now reach the CLI as /name blocks instead of inert prose. The adapter adds planClaudeSkillDispatch, which rewrites the last known skill mention into a trailing slash command (with images ordered before that block) and turns earlier mentions into inline /name text; disabled, unknown, or agent-only skills stay literal.

Claude skill discovery is realigned with Claude Code: scan user and .claude/skills only (drop .agents/skills), resolve names from directory names with user scope winning collisions, and merge skillOverrides from the same settings stack the CLI uses. Skills expose userInvocationOnly / userInvocable on the contract, and isProviderSkillUserInvocable filters composer search and slash menus.

Slash autocomplete now hides provider-native commands when the / trigger is not at message start; skills stay available on any line because the server dispatches them from any position. User docs describe the new behavior.

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

Note

Fix composer-selected skills so they run and filter agent-only skills from autocomplete

Fixes the useComposerCommandMenu hook so skills chosen from the composer menu are user-invocable. It now filters skill results to enabled, non-agent-only skills and restricts provider slash commands to message position zero; built-in commands and skills remain available at other positions.

  • Risk: provider-native slash commands no longer appear once the prompt has non-whitespace content before the trigger; users relying on mid-message provider commands will lose that autocomplete.

Macroscope summarized 8f27b8e.

rodrigoB-CBand others added 2 commits September 1, 2026 16:32
Skill discovery read only name and description from SKILL.md and
hardcoded every skill as enabled. Claude Code also honours
disable-model-invocation, user-invocable, and the skillOverrides map in
its settings files, so the composer offered skills the CLI would refuse.
Parse those flags, merge skillOverrides from the user, project, local,
and managed settings files, identify skills by directory name, and let
the user scope win name collisions. All three match the CLI's behaviour.
Cherry-picked from #7673.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Picking a skill inserted `$name` for every provider. Codex reads that
natively, but Claude Code treats it as prose, so the agent guessed at a
skill it could see and sometimes ran the wrong one. Claude Code runs a
skill only from a message whose last text block starts with `/name`.
The Claude adapter now splits the outgoing message around the last
`$skill` mention: the text before it stays as its own block, and the
mention plus everything after becomes a trailing `/name args` block that
the CLI expands itself. The user's message and the timeline are
unchanged. Earlier mentions in the same message are rewritten to `/name`
inline so the model starts them through its Skill tool. Skills switched
off in Claude's settings or reserved for the agent are left out of both
pickers and never dispatched.
Provider slash commands are only offered where they open the message on
web and mobile, since that is the only place a provider expands them.
Skills are no longer position-gated in the `/` menu.
Discovery changes cherry-picked from #7673 by Rodrigo Brechard.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/server/src/provider/Drivers/ClaudeSkills.ts
Comment threadapps/server/src/provider/Drivers/ClaudeSkillDispatch.ts
@github-actions

github-actionsBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.4 KiB+139 B (+1.0%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB0 B (0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.5 KiB+139 B (+2.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB57.0 KiB+1.4 KiB (+2.6%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.2 KiB13.2 KiB+97 B (+0.7%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−1 B (−0.0%)7.3 KiB
ClaudeLive turn WebSocket wire6.3 KiB6.4 KiB+98 B (+1.5%)7.8 KiB
ClaudeLive turn WebSocket decoded55.5 KiB56.3 KiB+840 B (+1.5%)66.4 KiB
ClaudeLive turn messages880 (0.0%)21

Baseline: 04efa79 · PR result: 8f27b8e · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

…kspace
Claude Code reads the repository root's `.claude/settings.local.json`
from a nested cwd and lets it outrank the workspace's own local file, so
a user skill switched off at the root was offered and dispatched from a
sub-package workspace. Walk up to the nearest `.git` and merge that file
in the CLI's order. The root's plain `settings.json` is not read, which
matches the CLI.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This change introduces Claude-native skill execution, new settings and invocation-policy handling, and altered composer behavior across web, mobile, and server layers. Its runtime scope extends beyond a small isolated fix, particularly because existing Claude prompt and skill-resolution paths now behave differently.

You can add or adjust custom eligibility rules. Learn more.

…ode does
Two discovery details did not match the CLI. Claude Code validates the
whole skillOverrides map, so one unknown or boolean value makes it drop
every override in that file; discovery applied the valid siblings. And
Claude Code never loads `.agents/skills`, so a skill living only there
was offered and dispatched to an `Unknown command` reply. Both verified
against the CLI and matched.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@t3dotgg
t3dotgg merged commit ea71a19 into mainSep 2, 2026
27 checks passed
@t3dotgg
t3dotgg deleted the t3code/fix-skills-anywhere-composer branch September 2, 2026 00:44
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Upstream pingdotgg#9128 now invokes composer $skill picks on Claude. Grok still
only expands /name, so the wire rewrite stays as the remaining delta.
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

2 participants

@t3dotgg@rodrigoB-CB
, '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

fix(claude): skills picked from the composer now run - #9128

Merged
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer
Sep 2, 2026
Merged

fix(claude): skills picked from the composer now run#9128
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 1, 2026

Copy link
Copy Markdown
Member

Picking a skill from the $ menu did nothing useful on Claude. The composer inserts $name for every provider. Codex reads that natively, but Claude Code treats it as prose, so the agent guessed at a skill it could see and sometimes ran a different one. One user picked $re-release-version and the agent cut a whole new release with release-version instead. Skills marked disable-model-invocation never ran at all, and skills switched off in Claude's settings still showed up in the picker.

Fix

Claude Code runs a skill only from a message whose last text block starts with /name. The Claude adapter now splits the outgoing message around the last $skill mention: the text before it stays as its own block, and the mention plus everything after becomes a trailing /name args block that the CLI expands itself. So ok, now $implement all the tickets goes to Claude as two blocks, ok, now and /implement all the tickets. The user's message and the timeline stay unchanged, and a skill runs from anywhere in the message, the same as on Codex. Skills marked disable-model-invocation work because you picked them, which is the user invocation Claude asks for. Earlier mentions in the same message are rewritten to /name inline so the model starts them through its Skill tool.

Discovery now reads disable-model-invocation, user-invocable, and the skillOverrides map from Claude's settings files, identifies skills by directory name, and lets the user scope win collisions, all matching the CLI. Skills switched off or reserved for the agent leave both pickers and are never dispatched.

Provider slash commands are only offered in the / menu where they open the message, since that is the only place a provider expands them. Skills are no longer position-gated there.

Behavior was verified against Claude Code 2.1.237 in stream-json mode: the last-text-block rule, the image ordering rule, and the one-skill-per-message limit (anthropics/claude-code#87113).

Supersedes #7673, #8336, and #9105. The discovery work is cherry-picked from #7673 with Rodrigo's authorship kept.

Fixes#7671
Fixes#8295

Verification

  • Server: 182 tests across skill discovery, skill dispatch, and the Claude adapter, including new cases for mid-prompt dispatch, image ordering, and disabled skills left as prose.
  • Clients: 26 tests across client-runtime, web skill search, slash menu position, and the mobile menu hook.
  • Typecheck clean for contracts, client-runtime, server, web, and mobile. Scoped lint and format clean.

Made by Claude Fable 5.1 via Claude Code.


Note

Medium Risk
Changes Claude turn payload shaping and per-send filesystem/settings skill scans; wrong dispatch or override parsing could run the wrong skill or skip valid picks.

Overview
Composer $skill picks on Claude now reach the CLI as /name blocks instead of inert prose. The adapter adds planClaudeSkillDispatch, which rewrites the last known skill mention into a trailing slash command (with images ordered before that block) and turns earlier mentions into inline /name text; disabled, unknown, or agent-only skills stay literal.

Claude skill discovery is realigned with Claude Code: scan user and .claude/skills only (drop .agents/skills), resolve names from directory names with user scope winning collisions, and merge skillOverrides from the same settings stack the CLI uses. Skills expose userInvocationOnly / userInvocable on the contract, and isProviderSkillUserInvocable filters composer search and slash menus.

Slash autocomplete now hides provider-native commands when the / trigger is not at message start; skills stay available on any line because the server dispatches them from any position. User docs describe the new behavior.

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

Note

Fix composer-selected skills so they run and filter agent-only skills from autocomplete

Fixes the useComposerCommandMenu hook so skills chosen from the composer menu are user-invocable. It now filters skill results to enabled, non-agent-only skills and restricts provider slash commands to message position zero; built-in commands and skills remain available at other positions.

  • Risk: provider-native slash commands no longer appear once the prompt has non-whitespace content before the trigger; users relying on mid-message provider commands will lose that autocomplete.

Macroscope summarized 8f27b8e.

rodrigoB-CBand others added 2 commits September 1, 2026 16:32
Skill discovery read only name and description from SKILL.md and
hardcoded every skill as enabled. Claude Code also honours
disable-model-invocation, user-invocable, and the skillOverrides map in
its settings files, so the composer offered skills the CLI would refuse.
Parse those flags, merge skillOverrides from the user, project, local,
and managed settings files, identify skills by directory name, and let
the user scope win name collisions. All three match the CLI's behaviour.
Cherry-picked from #7673.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Picking a skill inserted `$name` for every provider. Codex reads that
natively, but Claude Code treats it as prose, so the agent guessed at a
skill it could see and sometimes ran the wrong one. Claude Code runs a
skill only from a message whose last text block starts with `/name`.
The Claude adapter now splits the outgoing message around the last
`$skill` mention: the text before it stays as its own block, and the
mention plus everything after becomes a trailing `/name args` block that
the CLI expands itself. The user's message and the timeline are
unchanged. Earlier mentions in the same message are rewritten to `/name`
inline so the model starts them through its Skill tool. Skills switched
off in Claude's settings or reserved for the agent are left out of both
pickers and never dispatched.
Provider slash commands are only offered where they open the message on
web and mobile, since that is the only place a provider expands them.
Skills are no longer position-gated in the `/` menu.
Discovery changes cherry-picked from #7673 by Rodrigo Brechard.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/server/src/provider/Drivers/ClaudeSkills.ts
Comment threadapps/server/src/provider/Drivers/ClaudeSkillDispatch.ts
@github-actions

github-actionsBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.4 KiB+139 B (+1.0%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB0 B (0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.5 KiB+139 B (+2.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB57.0 KiB+1.4 KiB (+2.6%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.2 KiB13.2 KiB+97 B (+0.7%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−1 B (−0.0%)7.3 KiB
ClaudeLive turn WebSocket wire6.3 KiB6.4 KiB+98 B (+1.5%)7.8 KiB
ClaudeLive turn WebSocket decoded55.5 KiB56.3 KiB+840 B (+1.5%)66.4 KiB
ClaudeLive turn messages880 (0.0%)21

Baseline: 04efa79 · PR result: 8f27b8e · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

…kspace
Claude Code reads the repository root's `.claude/settings.local.json`
from a nested cwd and lets it outrank the workspace's own local file, so
a user skill switched off at the root was offered and dispatched from a
sub-package workspace. Walk up to the nearest `.git` and merge that file
in the CLI's order. The root's plain `settings.json` is not read, which
matches the CLI.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This change introduces Claude-native skill execution, new settings and invocation-policy handling, and altered composer behavior across web, mobile, and server layers. Its runtime scope extends beyond a small isolated fix, particularly because existing Claude prompt and skill-resolution paths now behave differently.

You can add or adjust custom eligibility rules. Learn more.

…ode does
Two discovery details did not match the CLI. Claude Code validates the
whole skillOverrides map, so one unknown or boolean value makes it drop
every override in that file; discovery applied the valid siblings. And
Claude Code never loads `.agents/skills`, so a skill living only there
was offered and dispatched to an `Unknown command` reply. Both verified
against the CLI and matched.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@t3dotgg
t3dotgg merged commit ea71a19 into mainSep 2, 2026
27 checks passed
@t3dotgg
t3dotgg deleted the t3code/fix-skills-anywhere-composer branch September 2, 2026 00:44
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Upstream pingdotgg#9128 now invokes composer $skill picks on Claude. Grok still
only expands /name, so the wire rewrite stays as the remaining delta.
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

2 participants

@t3dotgg@rodrigoB-CB
, '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

fix(claude): skills picked from the composer now run - #9128

Merged
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer
Sep 2, 2026
Merged

fix(claude): skills picked from the composer now run#9128
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 1, 2026

Copy link
Copy Markdown
Member

Picking a skill from the $ menu did nothing useful on Claude. The composer inserts $name for every provider. Codex reads that natively, but Claude Code treats it as prose, so the agent guessed at a skill it could see and sometimes ran a different one. One user picked $re-release-version and the agent cut a whole new release with release-version instead. Skills marked disable-model-invocation never ran at all, and skills switched off in Claude's settings still showed up in the picker.

Fix

Claude Code runs a skill only from a message whose last text block starts with /name. The Claude adapter now splits the outgoing message around the last $skill mention: the text before it stays as its own block, and the mention plus everything after becomes a trailing /name args block that the CLI expands itself. So ok, now $implement all the tickets goes to Claude as two blocks, ok, now and /implement all the tickets. The user's message and the timeline stay unchanged, and a skill runs from anywhere in the message, the same as on Codex. Skills marked disable-model-invocation work because you picked them, which is the user invocation Claude asks for. Earlier mentions in the same message are rewritten to /name inline so the model starts them through its Skill tool.

Discovery now reads disable-model-invocation, user-invocable, and the skillOverrides map from Claude's settings files, identifies skills by directory name, and lets the user scope win collisions, all matching the CLI. Skills switched off or reserved for the agent leave both pickers and are never dispatched.

Provider slash commands are only offered in the / menu where they open the message, since that is the only place a provider expands them. Skills are no longer position-gated there.

Behavior was verified against Claude Code 2.1.237 in stream-json mode: the last-text-block rule, the image ordering rule, and the one-skill-per-message limit (anthropics/claude-code#87113).

Supersedes #7673, #8336, and #9105. The discovery work is cherry-picked from #7673 with Rodrigo's authorship kept.

Fixes#7671
Fixes#8295

Verification

  • Server: 182 tests across skill discovery, skill dispatch, and the Claude adapter, including new cases for mid-prompt dispatch, image ordering, and disabled skills left as prose.
  • Clients: 26 tests across client-runtime, web skill search, slash menu position, and the mobile menu hook.
  • Typecheck clean for contracts, client-runtime, server, web, and mobile. Scoped lint and format clean.

Made by Claude Fable 5.1 via Claude Code.


Note

Medium Risk
Changes Claude turn payload shaping and per-send filesystem/settings skill scans; wrong dispatch or override parsing could run the wrong skill or skip valid picks.

Overview
Composer $skill picks on Claude now reach the CLI as /name blocks instead of inert prose. The adapter adds planClaudeSkillDispatch, which rewrites the last known skill mention into a trailing slash command (with images ordered before that block) and turns earlier mentions into inline /name text; disabled, unknown, or agent-only skills stay literal.

Claude skill discovery is realigned with Claude Code: scan user and .claude/skills only (drop .agents/skills), resolve names from directory names with user scope winning collisions, and merge skillOverrides from the same settings stack the CLI uses. Skills expose userInvocationOnly / userInvocable on the contract, and isProviderSkillUserInvocable filters composer search and slash menus.

Slash autocomplete now hides provider-native commands when the / trigger is not at message start; skills stay available on any line because the server dispatches them from any position. User docs describe the new behavior.

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

Note

Fix composer-selected skills so they run and filter agent-only skills from autocomplete

Fixes the useComposerCommandMenu hook so skills chosen from the composer menu are user-invocable. It now filters skill results to enabled, non-agent-only skills and restricts provider slash commands to message position zero; built-in commands and skills remain available at other positions.

  • Risk: provider-native slash commands no longer appear once the prompt has non-whitespace content before the trigger; users relying on mid-message provider commands will lose that autocomplete.

Macroscope summarized 8f27b8e.

rodrigoB-CBand others added 2 commits September 1, 2026 16:32
Skill discovery read only name and description from SKILL.md and
hardcoded every skill as enabled. Claude Code also honours
disable-model-invocation, user-invocable, and the skillOverrides map in
its settings files, so the composer offered skills the CLI would refuse.
Parse those flags, merge skillOverrides from the user, project, local,
and managed settings files, identify skills by directory name, and let
the user scope win name collisions. All three match the CLI's behaviour.
Cherry-picked from #7673.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Picking a skill inserted `$name` for every provider. Codex reads that
natively, but Claude Code treats it as prose, so the agent guessed at a
skill it could see and sometimes ran the wrong one. Claude Code runs a
skill only from a message whose last text block starts with `/name`.
The Claude adapter now splits the outgoing message around the last
`$skill` mention: the text before it stays as its own block, and the
mention plus everything after becomes a trailing `/name args` block that
the CLI expands itself. The user's message and the timeline are
unchanged. Earlier mentions in the same message are rewritten to `/name`
inline so the model starts them through its Skill tool. Skills switched
off in Claude's settings or reserved for the agent are left out of both
pickers and never dispatched.
Provider slash commands are only offered where they open the message on
web and mobile, since that is the only place a provider expands them.
Skills are no longer position-gated in the `/` menu.
Discovery changes cherry-picked from #7673 by Rodrigo Brechard.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/server/src/provider/Drivers/ClaudeSkills.ts
Comment threadapps/server/src/provider/Drivers/ClaudeSkillDispatch.ts
@github-actions

github-actionsBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.4 KiB+139 B (+1.0%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB0 B (0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.5 KiB+139 B (+2.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB57.0 KiB+1.4 KiB (+2.6%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.2 KiB13.2 KiB+97 B (+0.7%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−1 B (−0.0%)7.3 KiB
ClaudeLive turn WebSocket wire6.3 KiB6.4 KiB+98 B (+1.5%)7.8 KiB
ClaudeLive turn WebSocket decoded55.5 KiB56.3 KiB+840 B (+1.5%)66.4 KiB
ClaudeLive turn messages880 (0.0%)21

Baseline: 04efa79 · PR result: 8f27b8e · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

…kspace
Claude Code reads the repository root's `.claude/settings.local.json`
from a nested cwd and lets it outrank the workspace's own local file, so
a user skill switched off at the root was offered and dispatched from a
sub-package workspace. Walk up to the nearest `.git` and merge that file
in the CLI's order. The root's plain `settings.json` is not read, which
matches the CLI.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This change introduces Claude-native skill execution, new settings and invocation-policy handling, and altered composer behavior across web, mobile, and server layers. Its runtime scope extends beyond a small isolated fix, particularly because existing Claude prompt and skill-resolution paths now behave differently.

You can add or adjust custom eligibility rules. Learn more.

…ode does
Two discovery details did not match the CLI. Claude Code validates the
whole skillOverrides map, so one unknown or boolean value makes it drop
every override in that file; discovery applied the valid siblings. And
Claude Code never loads `.agents/skills`, so a skill living only there
was offered and dispatched to an `Unknown command` reply. Both verified
against the CLI and matched.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@t3dotgg
t3dotgg merged commit ea71a19 into mainSep 2, 2026
27 checks passed
@t3dotgg
t3dotgg deleted the t3code/fix-skills-anywhere-composer branch September 2, 2026 00:44
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Upstream pingdotgg#9128 now invokes composer $skill picks on Claude. Grok still
only expands /name, so the wire rewrite stays as the remaining delta.
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

2 participants

@t3dotgg@rodrigoB-CB
, '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

fix(claude): skills picked from the composer now run - #9128

Merged
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer
Sep 2, 2026
Merged

fix(claude): skills picked from the composer now run#9128
t3dotgg merged 4 commits into
mainfrom
t3code/fix-skills-anywhere-composer

Conversation

@t3dotgg

@t3dotggt3dotgg commented Sep 1, 2026

Copy link
Copy Markdown
Member

Picking a skill from the $ menu did nothing useful on Claude. The composer inserts $name for every provider. Codex reads that natively, but Claude Code treats it as prose, so the agent guessed at a skill it could see and sometimes ran a different one. One user picked $re-release-version and the agent cut a whole new release with release-version instead. Skills marked disable-model-invocation never ran at all, and skills switched off in Claude's settings still showed up in the picker.

Fix

Claude Code runs a skill only from a message whose last text block starts with /name. The Claude adapter now splits the outgoing message around the last $skill mention: the text before it stays as its own block, and the mention plus everything after becomes a trailing /name args block that the CLI expands itself. So ok, now $implement all the tickets goes to Claude as two blocks, ok, now and /implement all the tickets. The user's message and the timeline stay unchanged, and a skill runs from anywhere in the message, the same as on Codex. Skills marked disable-model-invocation work because you picked them, which is the user invocation Claude asks for. Earlier mentions in the same message are rewritten to /name inline so the model starts them through its Skill tool.

Discovery now reads disable-model-invocation, user-invocable, and the skillOverrides map from Claude's settings files, identifies skills by directory name, and lets the user scope win collisions, all matching the CLI. Skills switched off or reserved for the agent leave both pickers and are never dispatched.

Provider slash commands are only offered in the / menu where they open the message, since that is the only place a provider expands them. Skills are no longer position-gated there.

Behavior was verified against Claude Code 2.1.237 in stream-json mode: the last-text-block rule, the image ordering rule, and the one-skill-per-message limit (anthropics/claude-code#87113).

Supersedes #7673, #8336, and #9105. The discovery work is cherry-picked from #7673 with Rodrigo's authorship kept.

Fixes#7671
Fixes#8295

Verification

  • Server: 182 tests across skill discovery, skill dispatch, and the Claude adapter, including new cases for mid-prompt dispatch, image ordering, and disabled skills left as prose.
  • Clients: 26 tests across client-runtime, web skill search, slash menu position, and the mobile menu hook.
  • Typecheck clean for contracts, client-runtime, server, web, and mobile. Scoped lint and format clean.

Made by Claude Fable 5.1 via Claude Code.


Note

Medium Risk
Changes Claude turn payload shaping and per-send filesystem/settings skill scans; wrong dispatch or override parsing could run the wrong skill or skip valid picks.

Overview
Composer $skill picks on Claude now reach the CLI as /name blocks instead of inert prose. The adapter adds planClaudeSkillDispatch, which rewrites the last known skill mention into a trailing slash command (with images ordered before that block) and turns earlier mentions into inline /name text; disabled, unknown, or agent-only skills stay literal.

Claude skill discovery is realigned with Claude Code: scan user and .claude/skills only (drop .agents/skills), resolve names from directory names with user scope winning collisions, and merge skillOverrides from the same settings stack the CLI uses. Skills expose userInvocationOnly / userInvocable on the contract, and isProviderSkillUserInvocable filters composer search and slash menus.

Slash autocomplete now hides provider-native commands when the / trigger is not at message start; skills stay available on any line because the server dispatches them from any position. User docs describe the new behavior.

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

Note

Fix composer-selected skills so they run and filter agent-only skills from autocomplete

Fixes the useComposerCommandMenu hook so skills chosen from the composer menu are user-invocable. It now filters skill results to enabled, non-agent-only skills and restricts provider slash commands to message position zero; built-in commands and skills remain available at other positions.

  • Risk: provider-native slash commands no longer appear once the prompt has non-whitespace content before the trigger; users relying on mid-message provider commands will lose that autocomplete.

Macroscope summarized 8f27b8e.

rodrigoB-CBand others added 2 commits September 1, 2026 16:32
Skill discovery read only name and description from SKILL.md and
hardcoded every skill as enabled. Claude Code also honours
disable-model-invocation, user-invocable, and the skillOverrides map in
its settings files, so the composer offered skills the CLI would refuse.
Parse those flags, merge skillOverrides from the user, project, local,
and managed settings files, identify skills by directory name, and let
the user scope win name collisions. All three match the CLI's behaviour.
Cherry-picked from #7673.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Picking a skill inserted `$name` for every provider. Codex reads that
natively, but Claude Code treats it as prose, so the agent guessed at a
skill it could see and sometimes ran the wrong one. Claude Code runs a
skill only from a message whose last text block starts with `/name`.
The Claude adapter now splits the outgoing message around the last
`$skill` mention: the text before it stays as its own block, and the
mention plus everything after becomes a trailing `/name args` block that
the CLI expands itself. The user's message and the timeline are
unchanged. Earlier mentions in the same message are rewritten to `/name`
inline so the model starts them through its Skill tool. Skills switched
off in Claude's settings or reserved for the agent are left out of both
pickers and never dispatched.
Provider slash commands are only offered where they open the message on
web and mobile, since that is the only place a provider expands them.
Skills are no longer position-gated in the `/` menu.
Discovery changes cherry-picked from #7673 by Rodrigo Brechard.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 1, 2026
Comment threadapps/server/src/provider/Drivers/ClaudeSkills.ts
Comment threadapps/server/src/provider/Drivers/ClaudeSkillDispatch.ts
@github-actions

github-actionsBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.4 KiB+139 B (+1.0%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB0 B (0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.5 KiB+139 B (+2.1%)7.8 KiB
CodexLive turn WebSocket decoded55.6 KiB57.0 KiB+1.4 KiB (+2.6%)66.4 KiB
CodexLive turn messages10100 (0.0%)21
ClaudeTotal thread wire13.2 KiB13.2 KiB+97 B (+0.7%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB−1 B (−0.0%)7.3 KiB
ClaudeLive turn WebSocket wire6.3 KiB6.4 KiB+98 B (+1.5%)7.8 KiB
ClaudeLive turn WebSocket decoded55.5 KiB56.3 KiB+840 B (+1.5%)66.4 KiB
ClaudeLive turn messages880 (0.0%)21

Baseline: 04efa79 · PR result: 8f27b8e · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

…kspace
Claude Code reads the repository root's `.claude/settings.local.json`
from a nested cwd and lets it outrank the workspace's own local file, so
a user skill switched off at the root was offered and dispatched from a
sub-package workspace. Walk up to the nearest `.git` and merge that file
in the CLI's order. The root's plain `settings.json` is not read, which
matches the CLI.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@macroscopeapp

macroscopeappBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This change introduces Claude-native skill execution, new settings and invocation-policy handling, and altered composer behavior across web, mobile, and server layers. Its runtime scope extends beyond a small isolated fix, particularly because existing Claude prompt and skill-resolution paths now behave differently.

You can add or adjust custom eligibility rules. Learn more.

…ode does
Two discovery details did not match the CLI. Claude Code validates the
whole skillOverrides map, so one unknown or boolean value makes it drop
every override in that file; discovery applied the valid siblings. And
Claude Code never loads `.agents/skills`, so a skill living only there
was offered and dispatched to an `Unknown command` reply. Both verified
against the CLI and matched.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@t3dotgg
t3dotgg merged commit ea71a19 into mainSep 2, 2026
27 checks passed
@t3dotgg
t3dotgg deleted the t3code/fix-skills-anywhere-composer branch September 2, 2026 00:44
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Conflict resolutions:
- Claude $skill: adopt upstream's last-block dispatch (pingdotgg#9128). Drop the
fork's in-place $→/ rewrite on the Claude send path so the dispatcher
still sees $ tokens. Ultrathink wrapping a leading $skill is now safe
(prefix in the leading text block, command block still starts with
/name). Keep the Grok $→/ rewrite.
- Mobile composer menus: keep cwd-scoped composerSkills; apply upstream's
user-invocable filter and dedupe on that list. Path search now imports
from state/queries (upstream deleted the dedicated hook).
- Files surface: keep lazy explorer listDirectory/readDirectoryChildren;
adopt upstream's expandHomePathWith. Legacy (non-lazy) tree uses
incremental path updates (pingdotgg#8968) plus the fork's symlink badges and
ignored git status.
- Tilde paths: skip ~/ inline-code candidates in the shared
markdownLinks helper upstream extracted from web.
Pre-sync fork: backup/upstream-test-drive-pre-sync-20260902 (d4f79f8).
dascapytal1559 added a commit to dascapytal1559/t3code that referenced this pull request Sep 2, 2026
Upstream pingdotgg#9128 now invokes composer $skill picks on Claude. Grok still
only expands /name, so the wire rewrite stays as the remaining delta.
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Adopts main's round-19 features into the v2 stack: payload-budgeted
orchestration replay (#8992), sidebar row subscription leases (#9052),
tool group virtualization and scroll anchoring (#9106), repeated-command
and browser-group presentation, inline assistant citations (#9146),
per-cwd provider skills discovery (#8778), Claude composer skill
dispatch (#9128), grok health probe and model negotiation (#9154), and
the failed-tool thinking fallback (#9165).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

2 participants

@t3dotgg@rodrigoB-CB