Skip to content

fix(plugin): advertise the namespaced command names engines actually accept - #331

Merged
ralyodio merged 1 commit into
mainfrom
fix-plugin-command-names
Aug 8, 2026
Merged

fix(plugin): advertise the namespaced command names engines actually accept#331
ralyodio merged 1 commit into
mainfrom
fix-plugin-command-names

Conversation

@ralyodio

@ralyodio ralyodio commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Every plugin command was documented bare — /crypto, /stocks, /signals — and none of those exist. Claude Code namespaces plugin commands as /<plugin>:<command> always, not only when two plugins collide. So the first thing anyone did after installing was:

$ /crypto BTC
Unknown command: /crypto

Verified two ways

Against a fresh engine — /crypto and /spark both unknown, /crypto:crypto BTC returns the full report — and against the documented behaviour:

Why namespacing? Plugin skills are always namespaced (like /my-first-plugin:hello) to prevent conflicts when multiple plugins have skills with the same name.
https://code.claude.com/docs/en/plugins

I tested /spark specifically to rule out "/crypto just collides with the plugin name". It doesn't; bare names simply aren't commands.

What changed

Catalog, both plugin READMEs, the main README, and the cross-references inside the command files themselves — those tell the model which command to offer next, so a bare name there sends the user to the same dead end one step later.

Why the drift test didn't catch it

It compared commands against bare filenames — so /crypto "matched" crypto.md and stayed green through two releases of advertising a command that did not exist. Nothing checked the name against how the file is invoked. It now derives the namespaced form via pluginCommandName().

Also fixed

The post-install invitation appended a hardcoded "NVDA" to whatever came first in commands — telling anyone who installed the crypto plugin to try a stock. Each plugin now carries its own runnable example, with a test asserting it invokes a command that plugin actually ships.

Untouched on purpose

The pit's own /stocks … and /crypto … really are bare — they're moshcode's commands, not a plugin's. The READMEs now say so explicitly, since having both spellings in one repo is otherwise the confusing part.

Verification

  • Full suite: 1388 tests, 0 failures.
  • moshcode plugin list now prints /stocks:stocks /stocks:signals … and /crypto:crypto /crypto:quote ….

🤖 Generated with Claude Code

…accept

Every plugin command was documented bare — `/crypto`, `/stocks`, `/signals` —
and none of those exist. Claude Code namespaces plugin commands as
`/<plugin>:<command>` *always*, not only when two plugins collide, so the first
thing anyone did after installing was:

  $ /crypto BTC
  Unknown command: /crypto

Verified against a fresh engine (`/crypto` and `/spark` both unknown,
`/crypto:crypto BTC` returns the full report) and against the documented
behaviour: "Plugin skills are always namespaced (like `/my-first-plugin:hello`)
to prevent conflicts" — https://code.claude.com/docs/en/plugins

Fixed in the catalog, both plugin READMEs, the main README, and the
cross-references inside the command files themselves — those tell the model
which command to offer next, so a bare name there sends the *user* to the same
dead end one step later.

The drift test compared `commands` against bare filenames, which is why it
stayed green through two releases of advertising a command that did not exist:
the name matched a file on disk and nothing checked it against how the file is
invoked. It now derives the namespaced form via pluginCommandName().

Also fixes the post-install invitation, which appended a hardcoded "NVDA" to
whatever came first in `commands` — telling anyone who installed the crypto
plugin to try a stock. Each plugin now carries its own runnable `example`, and
a test asserts it invokes a command that plugin actually ships.

Untouched: the pit's own `/stocks …` and `/crypto …`, which really are bare —
they are moshcode's commands, not a plugin's. The READMEs now say so, since
having both spellings in one repo is otherwise the confusing part.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

ThreatCrush Security Scan

91 finding(s)

HIGH/CRITICAL: 2 | MEDIUM: 41 | LOW: 48

Severity Rule Location
HIGH manifest-typosquat apps/pwa/package.json:19
HIGH js-ssrf-outbound-request apps/pwa/public/sw.js:45
MEDIUM tls-verification-disabled apps/pwa/src/lib/moshpit-gateway.mjs:299
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:61
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:75
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:101
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:265
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:269
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:314
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:499
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:675
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:677
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:736
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:782
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:852
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:955
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:1063
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:1199
MEDIUM js-unescaped-html-sink apps/pwa/src/routes/moshpit.mjs:1419
MEDIUM js-dynamic-code-execution apps/pwa/test/apikey-mask.test.mjs:129
MEDIUM sql-template-interpolation apps/pwa/test/credits-webhook-event-match.test.mjs:111
MEDIUM sql-template-interpolation apps/pwa/test/credits-webhook-event-match.test.mjs:131
MEDIUM sql-template-interpolation apps/pwa/test/moshpit-terms.test.mjs:192
MEDIUM sql-template-interpolation src/dns.mjs:2439
MEDIUM sql-template-interpolation src/selfupdate.mjs:166
MEDIUM sql-template-interpolation src/selfupdate.mjs:170
MEDIUM sql-template-interpolation src/selfupdate.mjs:208
MEDIUM sql-template-interpolation src/selfupdate.mjs:209
MEDIUM insecure-temp-file test/dns-disable-restore.test.mjs:93
MEDIUM insecure-temp-file test/dns-disable-restore.test.mjs:310
MEDIUM insecure-temp-file test/plugins.test.mjs:126
MEDIUM insecure-temp-file test/pty.test.mjs:28
MEDIUM insecure-temp-file test/pty.test.mjs:31
MEDIUM insecure-temp-file test/pty.test.mjs:40
MEDIUM insecure-temp-file test/pty.test.mjs:42
MEDIUM insecure-temp-file test/pty.test.mjs:47
MEDIUM insecure-temp-file test/pty.test.mjs:48
MEDIUM insecure-temp-file test/pty.test.mjs:49
MEDIUM insecure-temp-file test/tabs.test.mjs:8
MEDIUM insecure-temp-file test/tabs.test.mjs:13
MEDIUM insecure-temp-file test/tabs.test.mjs:14
MEDIUM insecure-temp-file test/tabs.test.mjs:22
MEDIUM insecure-temp-file test/trust.test.mjs:240
LOW secret-generic-credential apps/pwa/test/apikey-bearer-scheme.test.mjs:30
LOW secret-generic-credential apps/pwa/test/apikey-mask.test.mjs:38
LOW secret-generic-credential apps/pwa/test/apikey-reveal.test.mjs:35
LOW secret-generic-credential apps/pwa/test/approvals-context.test.mjs:28
LOW secret-generic-credential apps/pwa/test/approvals-credits.test.mjs:28
LOW secret-generic-credential apps/pwa/test/approvals-notify.test.mjs:26
LOW secret-generic-credential apps/pwa/test/approvals-resolve-race.test.mjs:20

…and 41 more. Full results in the Security tab.

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit 0df4099 into main Aug 8, 2026
4 checks passed
@ralyodio ralyodio mentioned this pull request Aug 8, 2026
ralyodio added a commit that referenced this pull request Aug 8, 2026
Bump to v0.29.2, releasing the namespaced plugin command names (#331).

Patch, documentation and strings only. Every plugin command was advertised bare
— /crypto, /stocks, /signals — and none of those exist: Claude Code namespaces
plugin commands as /<plugin>:<command> always, so the first thing anyone tried
after installing answered "Unknown command".

Worth its own release rather than waiting, for the same reason v0.29.1 was: the
wrong names are in the plugin READMEs that ship with the plugins, and the
plugins are what people are being told to install right now.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ralyodio
ralyodio deleted the fix-plugin-command-names branch August 8, 2026 23:52
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.

1 participant