Skip to content

Commit 38973c4

Browse files
author
SqlRush
committed
Add status all slash command output
1 parent 7373376 commit 38973c4

4 files changed

Lines changed: 114 additions & 7 deletions

File tree

docs/cc-100-roadmap.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ M8 补充:`/mcp refresh`/`/mcp reload` 现在会走 no-query 本地刷新路
265265

266266
M8 补充:`/mcp remove|rm|delete <server>` 现在会从用户 `settings.json` 删除对应 `mcpServers` 配置,并同步清理该 server 的 allowed/denied MCP policy 与 runner 内存状态;project/local/plugin 来源会明确拒绝在 user settings 路径删除,避免误删非用户级来源。
267267

268-
M8 补充:`/status` built-in local-jsx command 现在在 headless/local runner 中返回基础 status text,包含 session id、working directory、model、tool count 和 settings-derived MCP server list,写入 result/transcript 且不会请求模型;`/status show <section>` 可只读展示 session/model/auth/tools/MCP/plugins 等运行态 section 详情,status local result 也会保留 slash args 供 runner 分派。完整 TUI status panel、account/API connectivity、tool health 和插件状态仍未完成。
268+
M8 补充:`/status` built-in local-jsx command 现在在 headless/local runner 中返回基础 status text,包含 session id、working directory、model、tool count 和 settings-derived MCP server list,写入 result/transcript 且不会请求模型;`/status show <section>` 可只读展示 session/model/auth/tools/MCP/plugins/telemetry/bridge/remote/daemon/lsp/native/integrations 等运行态 section 详情,`/status all|full|dump``/status show all` 可组合输出全部 section,未知 section 返回 usage 而不是未实现占位。完整 TUI status panel、account/API connectivity、tool health 和插件状态仍未完成。
269269

270270
M8 补充:`/help``/skills` built-in local-jsx command 现在有基础 text result:`/help` 从 command registry 输出可见命令列表,并支持 `/help search <query>` 按命令名、描述、类型、来源和 alias 过滤;`/skills` 输出可见 prompt skill 列表或空状态,并支持 `/skills search <query>` 只过滤 prompt skill;二者不会请求模型,完整 TUI help/skills 面板、筛选、分组和 plugin/MCP skill 展示仍未完成。
271271

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ test/parity/ # golden tests against TS/official behavior
317317
- 本轮补充:`/cost status``/cost current``/cost usage` 现在复用 `/cost` totals no-query 本地路径,`/cost breakdown`/`show` 继续输出逐消息明细,`/cost json|export` 会输出同口径 JSON 汇总和 message breakdown;当 history/transcript 含 timestamp 时,文本与 JSON 都会给出 session started/updated/duration,未知 cost 子命令会返回 usage 而不是未实现占位。
318318
- 本轮补充:`/memory files``/memory ls` 现在复用 `/memory list` 的 no-query 本地记忆文件列表路径,`/memory status` 仍保持会话/相关记忆概览。
319319
- 本轮补充:`/memory save|add|write <relative.md> <content>``/memory remove|rm|delete <relative.md>` 现在可在配置的 relevant memory directory 内安全维护 markdown 记忆文件,拒绝未配置目录、越界路径、非 markdown 文件、目录和 symlink 目标,并保持 no-query 本地结果。
320-
- 本轮补充:`/status <section>` 现在复用 `/status show <section>` 的 section alias normalization,`/status integrations``/status diagnostics` 等直接调用不会再落入 unsupported subcommand 分支。
320+
- 本轮补充:`/status <section>` 现在复用 `/status show <section>` 的 section alias normalization,`/status integrations``/status diagnostics` 等直接调用不会再落入 unsupported subcommand 分支`/status all|full|dump``/status show all` 会组合输出全部已知 status section,未知 section 返回 usage 而不是未实现占位
321321
- 本轮补充:`/mcp refresh``/mcp reload` 现在走 no-query 本地刷新路径,会重新检查 settings 文件变化并刷新 plugin MCP server app-state,返回刷新摘要而不是落入 unsupported subcommand。
322322
- 本轮补充:`/mcp restart``/mcp reconnect [server]` 现在走 headless stateless restart 路径,会刷新 settings/plugin MCP server 状态、校验指定 server 是否存在,并明确 server 会在下一次 tool call 重新打开,不再误报 unsupported。
323323
- 本轮补充:`/mcp remove|rm|delete <server>` 现在会从用户 `settings.json` 删除对应 `mcpServers` 配置,并同步清理该 server 的 allowed/denied MCP policy 与 runner 内存状态;project/local/plugin 来源会明确拒绝在 user settings 路径删除,避免误删非用户级来源。

internal/conversation/run.go

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,16 +1196,26 @@ func (r Runner) formatStatusSummary(raw string) string {
11961196
switch args[0] {
11971197
case "show", "info":
11981198
if len(args) < 2 || strings.TrimSpace(args[1]) == "" {
1199-
return "Usage: /status " + args[0] + " <session|model|auth|tools|mcp|plugins|telemetry|bridge|remote|daemon|lsp|native|integrations>"
1199+
return statusUsageText(args[0])
1200+
}
1201+
if isAllStatusSection(args[1]) {
1202+
return r.formatStatusAll()
12001203
}
12011204
return r.formatStatusShow(args[1])
12021205
case "session", "model", "auth", "tools", "mcp", "plugins", "telemetry", "bridge", "remote", "daemon", "lsp", "native", "integrations":
12031206
return r.formatStatusShow(args[0])
1207+
case "all", "full", "dump":
1208+
return r.formatStatusAll()
1209+
case "help", "-h", "--help":
1210+
return statusUsageText("")
12041211
default:
1212+
if isAllStatusSection(args[0]) {
1213+
return r.formatStatusAll()
1214+
}
12051215
if section := normalizeStatusSection(args[0]); isKnownStatusSection(section) {
12061216
return r.formatStatusShow(args[0])
12071217
}
1208-
return "Status section is not implemented in the Go runtime yet: " + strings.Join(args, " ")
1218+
return "Unknown status section: " + strings.Join(args, " ") + "\n" + statusUsageText("")
12091219
}
12101220
}
12111221
model := r.model()
@@ -1241,6 +1251,14 @@ func (r Runner) formatStatusSummary(raw string) string {
12411251
)
12421252
}
12431253

1254+
func (r Runner) formatStatusAll() string {
1255+
lines := []string{"Status all"}
1256+
for _, section := range statusSectionNames() {
1257+
lines = append(lines, "", strings.TrimSpace(r.formatStatusShow(section)))
1258+
}
1259+
return strings.Join(lines, "\n")
1260+
}
1261+
12441262
func (r Runner) formatStatusShow(raw string) string {
12451263
switch normalizeStatusSection(raw) {
12461264
case "session":
@@ -1360,15 +1378,36 @@ func (r Runner) formatStatusShow(raw string) string {
13601378
}
13611379
}
13621380

1363-
func isKnownStatusSection(section string) bool {
1364-
switch section {
1365-
case "session", "model", "auth", "tools", "mcp", "plugins", "telemetry", "bridge", "remote", "daemon", "lsp", "native", "integrations":
1381+
func statusSectionNames() []string {
1382+
return []string{"session", "model", "auth", "tools", "mcp", "plugins", "telemetry", "bridge", "remote", "daemon", "lsp", "native", "integrations"}
1383+
}
1384+
1385+
func statusUsageText(command string) string {
1386+
prefix := "/status"
1387+
if strings.TrimSpace(command) != "" {
1388+
prefix += " " + strings.TrimSpace(command)
1389+
}
1390+
return "Usage: " + prefix + " <all|" + strings.Join(statusSectionNames(), "|") + ">"
1391+
}
1392+
1393+
func isAllStatusSection(raw string) bool {
1394+
switch strings.ToLower(strings.TrimSpace(strings.TrimPrefix(raw, "--"))) {
1395+
case "all", "full", "dump", "everything":
13661396
return true
13671397
default:
13681398
return false
13691399
}
13701400
}
13711401

1402+
func isKnownStatusSection(section string) bool {
1403+
for _, known := range statusSectionNames() {
1404+
if section == known {
1405+
return true
1406+
}
1407+
}
1408+
return false
1409+
}
1410+
13721411
func normalizeStatusSection(raw string) string {
13731412
value := strings.TrimSpace(raw)
13741413
value = strings.TrimPrefix(value, "--")

internal/conversation/run_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2792,6 +2792,74 @@ func TestRunnerExecutesStatusSlashCommandWithoutQuery(t *testing.T) {
27922792
}
27932793
}
27942794

2795+
func TestRunnerStatusSlashCommandReportsAllSections(t *testing.T) {
2796+
client := &fakeClient{}
2797+
registry, err := tool.NewRegistry(tool.FuncTool{
2798+
DefinitionValue: contracts.ToolDefinition{Name: "Read", InputSchema: contracts.JSONSchema{"type": "object"}},
2799+
CallFunc: func(tool.Context, json.RawMessage, tool.ProgressSink) (contracts.ToolResult, error) {
2800+
t.Fatal("status should not call tools")
2801+
return contracts.ToolResult{}, nil
2802+
},
2803+
})
2804+
if err != nil {
2805+
t.Fatal(err)
2806+
}
2807+
runner := Runner{
2808+
Client: client,
2809+
Tools: tool.NewExecutor(registry),
2810+
Model: "sonnet",
2811+
SessionID: "sess_status_all",
2812+
SessionPath: filepath.Join(t.TempDir(), "session.jsonl"),
2813+
WorkingDirectory: t.TempDir(),
2814+
}
2815+
for _, prompt := range []string{"/status all", "/status show all"} {
2816+
result, err := runner.RunTurn(context.Background(), nil, messages.UserText(prompt))
2817+
if err != nil {
2818+
t.Fatal(err)
2819+
}
2820+
if len(client.requests) != 0 {
2821+
t.Fatalf("%s should not query model, requests = %#v", prompt, client.requests)
2822+
}
2823+
text := result.Messages[1].Content[0].Text
2824+
for _, want := range []string{
2825+
"Status all",
2826+
"Status session",
2827+
"Status model",
2828+
"Status auth",
2829+
"Status tools",
2830+
"Status plugins",
2831+
"Status telemetry",
2832+
"Status bridge",
2833+
"Status native",
2834+
"Status advanced integrations",
2835+
} {
2836+
if !strings.Contains(text, want) {
2837+
t.Fatalf("%s missing %q: %q", prompt, want, text)
2838+
}
2839+
}
2840+
}
2841+
}
2842+
2843+
func TestRunnerStatusSlashCommandReportsUsageForUnknownSection(t *testing.T) {
2844+
runner := Runner{Client: &fakeClient{}, SessionID: "sess_status_unknown"}
2845+
result, err := runner.RunTurn(context.Background(), nil, messages.UserText("/status unknown-section"))
2846+
if err != nil {
2847+
t.Fatal(err)
2848+
}
2849+
got := result.Messages[1].Content[0].Text
2850+
for _, want := range []string{
2851+
"Unknown status section: unknown-section",
2852+
"Usage: /status <all|session|model|auth|tools|mcp|plugins|telemetry|bridge|remote|daemon|lsp|native|integrations>",
2853+
} {
2854+
if !strings.Contains(got, want) {
2855+
t.Fatalf("unknown status result missing %q: %q", want, got)
2856+
}
2857+
}
2858+
if strings.Contains(got, "not implemented") {
2859+
t.Fatalf("unknown status should not report not implemented: %q", got)
2860+
}
2861+
}
2862+
27952863
func TestRunnerTelemetryDisabledByDefault(t *testing.T) {
27962864
client := &fakeClient{}
27972865
dir := t.TempDir()

0 commit comments

Comments
 (0)