Skip to content

Commit 387373e

Browse files
author
SqlRush
committed
Add plugin command help aliases
1 parent d33c395 commit 387373e

6 files changed

Lines changed: 94 additions & 4 deletions

File tree

docs/cc-100-roadmap.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ M4/M11 补充:bridge-safe 内置本地命令 `/summary`、`/release-notes`、`
3939

4040
M11 补充:`/native status|show` 已接入 no-query 本地路径,复用 `/status show native` 的 session native manifest 审计输出,报告平台、capability、clipboard adapter、file index 和 clipboard state,不请求模型且不调用外部 adapter。
4141

42+
M8 补充:`/plugin help|--help|-h` 已输出官方插件命令用法,`/plugin manage` 复用 installed plugin summary,`/plugin i` 作为 install alias 复用安装路径;builtin command registry 同步声明官方 `/plugins``/marketplace` 顶层别名。
43+
4244
M10 补充:plugin command/agent 的 allowed tool frontmatter 解析现在只在顶层逗号或空白处分隔,保留括号、方括号和引号内的逗号/空白,避免 `Bash(git commit -m "x,y")` 这类 tool pattern 被误拆。
4345

4446
M8 补充:CLI `plugin marketplace list` 现在可列出 settings 中已配置的 marketplace;`--json` 输出按名称排序的 source/repo/url/path/package/installLocation 结构,普通文本输出与无配置提示也已覆盖。CLI `plugin marketplace add [--scope user|project|local] [--type ...] <name> <source>` 和 `plugin marketplace remove [--scope user|project|local] <name>` 现在复用 `internal/config` settings 文件写入 helper,可按目标 scope 写入/删除 `extraKnownMarketplaces`,并在写入前复用 marketplace source validation,且 `installLocation` 会校验为 `user|project|local`。CLI `plugin marketplace update [name]` 现在可按全部或指定 marketplace 触发现有 URL/git/github/npm/settings cache 加载刷新路径,命名 update 会用轻量 settings 读取避免启动时提前刷新全部 marketplace。运行时插件发现现在会合并项目链 `.claude/plugins` 和用户级 `${CLAUDE_CONFIG_DIR}/plugins`,项目同名插件优先。CLI `plugin install --scope project|user|local <plugin>` 与 headless `/plugin install [--scope project|user|local] <plugin>` 现在复用 `internal/plugins` 共享安装 API,把 marketplace 插件复制到目标 scope 的 `plugins/<safe-name>`,未显式传 scope 时会尊重 marketplace `installLocation` 默认值,并保留冲突检测、重复安装识别和 symlink/non-regular file 拒绝。CLI `plugin update --scope project|user|local|all <plugin>` 与 headless `/plugin update [--scope project|user|local|all] [plugin]` 现在复用 `internal/plugins` 共享更新 API,把目标 scope 已安装同名插件替换为最新 marketplace 副本,未显式传 scope 的命名更新同样会尊重 marketplace `installLocation`。CLI `plugin enable|disable [--scope user|project|local] <plugin>` 与 `plugin disable --all --scope ...` 现在复用 `internal/config` settings 文件写入 helper,按目标 scope 更新 `enabledPlugins` 并覆盖基本参数冲突。

docs/claude-code-go-rewrite-plan.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,8 @@ test/parity/ # golden tests against TS/official behavior
897897
- 本轮补充:`/native clipboard status|show` 现在走 no-query 本地状态路径,只展示 session clipboard 文件路径、item 数、更新时间和 adapter 可用性/命令,不读取、不写入、不展示剪贴板文本内容;`/native clipboard` usage 同步暴露 status 子命令。
898898
- 本轮补充:`/native status|show` 现在复用 `/status show native` 的 no-query 状态路径,可直接审计 session native manifest、平台、capability 数、clipboard adapter、file index 和 clipboard state,不请求模型也不调用外部 clipboard adapter。
899899

900+
- 本轮补充:`/plugin help|--help|-h` 现在输出官方 Plugin Command Usage 文案,`/plugin manage` 复用已安装 plugin summary,`/plugin i` 作为 install alias 接入同一安装路径,builtin command registry 同步声明官方 `/plugins``/marketplace` 顶层别名。
901+
900902
- 本轮补充:bridge-safe 内置本地命令 `/summary``/release-notes``/files` 现在已注册并接入 no-query runner 路径;`/summary` 输出确定性的会话/历史消息计数、工具使用计数、估算 token 和最近用户/助手预览,`/files` 只读列出当前工作目录第一层条目而不读取文件内容,`/release-notes` 明确报告当前 Go runtime 未打包 release notes。完整 local-jsx UI surface 和其它本地命令 parity 仍需继续补。
901903

902904
### M12: Parity hardening

docs/first-second-parity-audit.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ Anthropic API 和 conversation:
8787
- `/native voice status|show` and `/native computer status|show` now take no-query local status paths that report the session plan path, adapter availability, selected commands, and voice/computer-use runtime parameters without starting capture or input actions.
8888
- `/mcp refresh` and `/mcp reload` now take a no-query local refresh path that checks settings-file changes, refreshes plugin MCP server app-state, and reports configured/plugin MCP server counts instead of falling into the unsupported-subcommand branch.
8989
- `/mcp <server-name>` now takes the no-query local server-detail path used by `/mcp show <server-name>` when the name matches a configured settings or plugin MCP server, while unknown one-word subcommands still report unsupported.
90+
- `/plugin help|--help|-h` now returns the official plugin command usage text without querying the model, `/plugin manage` reuses the installed-plugin summary path, `/plugin i` aliases install, and the built-in command registry now exposes the official `/plugins` and `/marketplace` aliases.
9091
- `/plugin <plugin-name>` now takes the no-query local plugin-detail path used by `/plugin show <plugin-name>` when the name matches a local plugin manifest, while unknown one-word subcommands still report unsupported.
9192
- `/model show`, `/model info`, and `/model current` now take the no-query current-model path instead of treating those words as custom model names and mutating the runner model.
9293
- A basic `Skill` tool wrapper is now registered with the default built-in tool set. It can invoke local project and plugin-directory prompt skills through the command registry, returns the official-style `Launching skill: ...` result plus structured command metadata, preserves command source/display/root/frontmatter metadata for plugin skills, and passes expanded meta user messages through `ToolResult.NewMessages`; the conversation runner now appends those new messages to transcripts and subsequent model requests.

internal/commands/registry.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ func BuiltinCommands() []contracts.Command {
288288
{Type: contracts.CommandLocalJSX, Name: "help", Description: "Show help and available commands", Source: contracts.CommandSourceBuiltin},
289289
{Type: contracts.CommandLocalJSX, Name: "config", Aliases: []string{"settings"}, Description: "Open config panel", Source: contracts.CommandSourceBuiltin},
290290
{Type: contracts.CommandLocalJSX, Name: "mcp", Description: "Manage MCP servers", ArgumentHint: "[enable|disable [server-name]]", Source: contracts.CommandSourceBuiltin, Immediate: true},
291-
{Type: contracts.CommandLocalJSX, Name: "plugin", Description: "Manage plugins", Source: contracts.CommandSourceBuiltin},
291+
{Type: contracts.CommandLocalJSX, Name: "plugin", Aliases: []string{"plugins", "marketplace"}, Description: "Manage plugins", Source: contracts.CommandSourceBuiltin},
292292
{Type: contracts.CommandLocalJSX, Name: "skills", Description: "List available skills", Source: contracts.CommandSourceBuiltin},
293293
{Type: contracts.CommandLocalJSX, Name: "memory", Description: "Edit memory files", Source: contracts.CommandSourceBuiltin},
294294
{Type: contracts.CommandLocal, Name: "native", Description: "Run explicit native integration commands", ArgumentHint: "clipboard|chrome|voice|computer", Source: contracts.CommandSourceBuiltin, SupportsNonInteractive: true},

internal/conversation/run.go

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3357,7 +3357,9 @@ func (r Runner) formatPluginSummary(raw string) string {
33573357
args := strings.Fields(strings.TrimSpace(raw))
33583358
if len(args) > 0 {
33593359
switch args[0] {
3360-
case "list", "status":
3360+
case "list", "status", "manage":
3361+
case "help", "--help", "-h":
3362+
return pluginCommandHelp()
33613363
case "show", "info":
33623364
return r.formatPluginShow(args)
33633365
case "search", "find":
@@ -3386,7 +3388,7 @@ func (r Runner) formatPluginSummary(raw string) string {
33863388
return r.formatMarketplacePlugins(subcommandRemainder(raw, args[0]))
33873389
case "config", "settings":
33883390
return r.formatPluginConfig(args)
3389-
case "install":
3391+
case "install", "i":
33903392
return r.installPluginSummary(subcommandRemainder(raw, args[0]))
33913393
case "update":
33923394
return r.updatePluginSummary(subcommandRemainder(raw, args[0]))
@@ -3506,6 +3508,42 @@ func (r Runner) formatPluginSummary(raw string) string {
35063508
return strings.Join(lines, "\n")
35073509
}
35083510

3511+
func pluginCommandHelp() string {
3512+
return strings.Join([]string{
3513+
"Plugin Command Usage:",
3514+
"",
3515+
"Installation:",
3516+
"/plugin install - Browse and install plugins",
3517+
"/plugin install <marketplace> - Install from specific marketplace",
3518+
"/plugin install <plugin> - Install specific plugin",
3519+
"/plugin install <plugin>@<market> - Install plugin from marketplace",
3520+
"",
3521+
"Management:",
3522+
"/plugin manage - Manage installed plugins",
3523+
"/plugin enable <plugin> - Enable a plugin",
3524+
"/plugin disable <plugin> - Disable a plugin",
3525+
"/plugin uninstall <plugin> - Uninstall a plugin",
3526+
"",
3527+
"Marketplaces:",
3528+
"/plugin marketplace - Marketplace management menu",
3529+
"/plugin marketplace add - Add a marketplace",
3530+
"/plugin marketplace add <path/url> - Add marketplace directly",
3531+
"/plugin marketplace update - Update marketplaces",
3532+
"/plugin marketplace update <name> - Update specific marketplace",
3533+
"/plugin marketplace remove - Remove a marketplace",
3534+
"/plugin marketplace remove <name> - Remove specific marketplace",
3535+
"/plugin marketplace list - List all marketplaces",
3536+
"",
3537+
"Validation:",
3538+
"/plugin validate <path> - Validate a manifest file or directory",
3539+
"",
3540+
"Other:",
3541+
"/plugin - Main plugin menu",
3542+
"/plugin help - Show this help",
3543+
"/plugins - Alias for /plugin",
3544+
}, "\n")
3545+
}
3546+
35093547
func (r Runner) formatPluginShow(args []string) string {
35103548
if len(args) < 2 || strings.TrimSpace(args[1]) == "" {
35113549
return "Usage: /plugin " + args[0] + " <plugin-name>"

internal/conversation/run_test.go

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4942,6 +4942,53 @@ func TestRunnerExecutesPluginSlashCommandWithoutQuery(t *testing.T) {
49424942
t.Fatalf("plugin text missing %q: %q", want, text)
49434943
}
49444944
}
4945+
4946+
result, err = runner.RunTurn(context.Background(), nil, messages.UserText("/plugin manage"))
4947+
if err != nil {
4948+
t.Fatal(err)
4949+
}
4950+
if len(client.requests) != 0 {
4951+
t.Fatalf("model should not be queried, requests = %#v", client.requests)
4952+
}
4953+
text = result.Messages[1].Content[0].Text
4954+
for _, want := range []string{
4955+
"Plugins",
4956+
"Local plugin manifests: 1",
4957+
"Plugin commands:",
4958+
"- /plugin:deploy",
4959+
} {
4960+
if !strings.Contains(text, want) {
4961+
t.Fatalf("plugin manage text missing %q: %q", want, text)
4962+
}
4963+
}
4964+
4965+
for _, prompt := range []string{"/plugin help", "/plugin --help", "/plugin -h", "/plugins help", "/marketplace help"} {
4966+
result, err = runner.RunTurn(context.Background(), nil, messages.UserText(prompt))
4967+
if err != nil {
4968+
t.Fatal(err)
4969+
}
4970+
if len(client.requests) != 0 {
4971+
t.Fatalf("%s queried model, requests = %#v", prompt, client.requests)
4972+
}
4973+
text = result.Messages[1].Content[0].Text
4974+
for _, want := range []string{
4975+
"Plugin Command Usage:",
4976+
"Installation:",
4977+
"/plugin install <plugin>@<market> - Install plugin from marketplace",
4978+
"Management:",
4979+
"/plugin manage - Manage installed plugins",
4980+
"Marketplaces:",
4981+
"/plugin marketplace list - List all marketplaces",
4982+
"Validation:",
4983+
"/plugin validate <path> - Validate a manifest file or directory",
4984+
"Other:",
4985+
"/plugin help - Show this help",
4986+
} {
4987+
if !strings.Contains(text, want) {
4988+
t.Fatalf("%s help missing %q: %q", prompt, want, text)
4989+
}
4990+
}
4991+
}
49454992
}
49464993

49474994
func TestRunnerPluginShowReportsLocalPluginDetails(t *testing.T) {
@@ -5166,7 +5213,7 @@ func TestRunnerPluginInstallCopiesSettingsMarketplacePlugin(t *testing.T) {
51665213
}},
51675214
}
51685215

5169-
result, err := runner.RunTurn(context.Background(), nil, messages.UserText("/plugin install market demo"))
5216+
result, err := runner.RunTurn(context.Background(), nil, messages.UserText("/plugin i market demo"))
51705217
if err != nil {
51715218
t.Fatal(err)
51725219
}

0 commit comments

Comments
 (0)