Skip to content

fix: Gate unsupported-slash-command on SDK command list#2425

Merged
k11kirky merged 1 commit into
mainfrom
05-28-gate_unsupported-slash-command_on_sdk_command_list
May 29, 2026
Merged

fix: Gate unsupported-slash-command on SDK command list#2425
k11kirky merged 1 commit into
mainfrom
05-28-gate_unsupported-slash-command_on_sdk_command_list

Conversation

@charlesvien
Copy link
Copy Markdown
Member

@charlesvien charlesvien commented May 28, 2026

Problem

Plugin/skill slash commands like /skills-store can race with the SDK's idle event during plugin load, getting mis-flagged as "Unsupported slash command".

Changes

  1. Cache SDK's command list from initializationResult().commands on the session
  2. Gate "Unsupported" emission on missing-from-list, not just on no-echo
  3. Helper to collect command names from SDK init response
  4. Test for known-skill early-idle race
  5. Document divergence in UPSTREAM.md

How did you test this?

Manually

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

@charlesvien charlesvien changed the title Gate unsupported-slash-command on SDK command list fix: Gate unsupported-slash-command on SDK command list May 28, 2026
@charlesvien charlesvien marked this pull request as ready for review May 28, 2026 22:33
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 28, 2026

T-Rex T-Rex Logs

What T-Rex did

  • Ran a focused vitest harness to exercise the early-idle slash-command gate with a mocked Claude query.
  • Verified that the MCP command name shape used by the SDK matches the command name sent by ACP clients.
  • Reproduced a real MCP command scenario that produced an 'Unsupported slash command: /mcp:github-search' and ended the turn.
  • Added a sanity case for leading-slash command entries to confirm the bare-name contract.
  • Read gating changes in claude-agent.ts (early-idle branch + collectKnownSlashCommands) and the MCP rename in session/commands.ts, then wrote a focused vitest test to drive the real prompt() loop with a mocked Query and emit only session_state_changed{state:idle}.
  • Installed dependencies and built @posthog/enricher so vitest could resolve its dist.
  • Ran the vitest test with verbose output; one case failed as designed, producing the spurious 'Unsupported slash command: /mcp:github-search' chunk.
  • Validated a second test case where a set containing /help with a leading slash confirms that command names must be bare.
  • Attached the automated repro as validation for manual review.
Artifacts

Verbose vitest output for the failing MCP-prefix repro

  • Shows the verbose vitest run used to reproduce the MCP-prefix failure for review.

Generated focused repro test

  • The focused repro test file that exercises the MCP command shape regression.

Verbose vitest output with stack trace for the failing MCP-prefix case

  • Contains the stack-trace rich run of the failing case from the automated repro.

Focused repro TypeScript test file

  • The focused TypeScript test source file created for the MCP path.

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (1)

  1. packages/agent/src/adapters/claude/claude-agent.ts, line 992-1001 (link)

    P1 Refresh command cache

    refreshSession() waits for the new query's initializationResult(), but it never copies result.value.commands into session.knownSlashCommands. After MCP or skill servers are refreshed, the available-command update can show newly available commands while the early-idle gate still uses the old Set. A newly added command can still be reported as unsupported, and a removed command can remain treated as known and fall through to the failure path instead of producing the intended unsupported-command message.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: packages/agent/src/adapters/claude/claude-agent.ts
    Line: 992-1001
    
    Comment:
    **Refresh command cache**
    
    `refreshSession()` waits for the new query's `initializationResult()`, but it never copies `result.value.commands` into `session.knownSlashCommands`. After MCP or skill servers are refreshed, the available-command update can show newly available commands while the early-idle gate still uses the old Set. A newly added command can still be reported as unsupported, and a removed command can remain treated as known and fall through to the failure path instead of producing the intended unsupported-command message.
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
packages/agent/src/adapters/claude/claude-agent.ts:147-155
**Normalize MCP command names**

`collectKnownSlashCommands` stores the SDK command name verbatim, but MCP commands are exposed to ACP clients with a different name shape. `getAvailableSlashCommands` turns an SDK name like `github:search (MCP)` into `mcp:github:search`, and `promptToClaude` later transforms `/mcp:github:search ...` back before sending it to the SDK. During an early idle, this lookup compares the captured command name against the raw SDK name in the Set, so a real MCP command can miss the gate and emit `Unsupported slash command` even though the SDK supports it. Store the same user-facing alias used by `getAvailableSlashCommands`, or store both forms.

### Issue 2 of 2
packages/agent/src/adapters/claude/claude-agent.ts:992-1001
**Refresh command cache**

`refreshSession()` waits for the new query's `initializationResult()`, but it never copies `result.value.commands` into `session.knownSlashCommands`. After MCP or skill servers are refreshed, the available-command update can show newly available commands while the early-idle gate still uses the old Set. A newly added command can still be reported as unsupported, and a removed command can remain treated as known and fall through to the failure path instead of producing the intended unsupported-command message.

Reviews (1): Last reviewed commit: "Gate unsupported-slash-command on SDK co..." | Re-trigger Greptile

Comment thread packages/agent/src/adapters/claude/claude-agent.ts
@charlesvien charlesvien changed the base branch from main to graphite-base/2425 May 29, 2026 02:33
@charlesvien charlesvien force-pushed the 05-28-gate_unsupported-slash-command_on_sdk_command_list branch from e8eb279 to 2cffc25 Compare May 29, 2026 02:33
@charlesvien charlesvien changed the base branch from graphite-base/2425 to 05-28-fix_task_titel_generation May 29, 2026 02:33
@charlesvien charlesvien force-pushed the 05-28-gate_unsupported-slash-command_on_sdk_command_list branch from 2cffc25 to 4b1d6ed Compare May 29, 2026 02:48
@charlesvien charlesvien force-pushed the 05-28-fix_task_titel_generation branch from 7fad3b2 to f205d09 Compare May 29, 2026 02:48
@charlesvien charlesvien force-pushed the 05-28-gate_unsupported-slash-command_on_sdk_command_list branch 3 times, most recently from 44cf140 to 0edd3dc Compare May 29, 2026 05:19
@charlesvien charlesvien force-pushed the 05-28-fix_task_titel_generation branch from 918979c to 7b11dd7 Compare May 29, 2026 05:19
Copy link
Copy Markdown
Contributor

@k11kirky k11kirky left a comment

Choose a reason for hiding this comment

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

bit of a trust you bro stamp on this one

Copy link
Copy Markdown
Contributor

k11kirky commented May 29, 2026

Merge activity

  • May 29, 10:26 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • May 29, 10:37 AM UTC: Graphite rebased this pull request as part of a merge.
  • May 29, 10:44 AM UTC: @k11kirky merged this pull request with Graphite.

@k11kirky k11kirky changed the base branch from 05-28-fix_task_titel_generation to graphite-base/2425 May 29, 2026 10:27
@k11kirky k11kirky changed the base branch from graphite-base/2425 to main May 29, 2026 10:35
@k11kirky k11kirky force-pushed the 05-28-gate_unsupported-slash-command_on_sdk_command_list branch from 0edd3dc to 0286e6a Compare May 29, 2026 10:36
@k11kirky k11kirky merged commit b265a45 into main May 29, 2026
19 checks passed
@k11kirky k11kirky deleted the 05-28-gate_unsupported-slash-command_on_sdk_command_list branch May 29, 2026 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants