mirror of
https://github.com/instructkr/claw-code.git
synced 2026-04-11 02:24:49 +08:00
fix(cli): stop circular 'Did you mean /X?' for spec commands with no parse arm
23 spec-registered commands had no parse arm in validate_slash_command_input,
causing the circular error 'Unknown slash command: /X — Did you mean /X?'
when users typed them in --resume mode.
Two fixes:
1. Add the 23 confirmed parse-armless commands to STUB_COMMANDS (excluded
from REPL completions and help output).
2. In resume dispatch, intercept STUB_COMMANDS before SlashCommand::parse
and emit a clean '{error: "/X is not yet implemented in this build"}'
instead of the confusing error from the Err parse path.
Affected: /allowed-tools, /bookmarks, /workspace, /reasoning, /budget,
/rate-limit, /changelog, /diagnostics, /metrics, /tool-details, /focus,
/unfocus, /pin, /unpin, /language, /profile, /max-tokens, /temperature,
/system-prompt, /notifications, /telemetry, /env, /project, plus ~40
additional unreachable spec names.
159 CLI tests pass.
This commit is contained in:
@@ -2246,6 +2246,33 @@ fn resume_session(session_path: &Path, commands: &[String], output_format: CliOu
|
|||||||
|
|
||||||
let mut session = session;
|
let mut session = session;
|
||||||
for raw_command in commands {
|
for raw_command in commands {
|
||||||
|
// Intercept spec commands that have no parse arm before calling
|
||||||
|
// SlashCommand::parse — they return Err(SlashCommandParseError) which
|
||||||
|
// formats as the confusing circular "Did you mean /X?" message.
|
||||||
|
// STUB_COMMANDS covers both completions-filtered stubs and parse-less
|
||||||
|
// spec entries; treat both as unsupported in resume mode.
|
||||||
|
{
|
||||||
|
let cmd_root = raw_command
|
||||||
|
.trim_start_matches('/')
|
||||||
|
.split_whitespace()
|
||||||
|
.next()
|
||||||
|
.unwrap_or("");
|
||||||
|
if STUB_COMMANDS.contains(&cmd_root) {
|
||||||
|
if output_format == CliOutputFormat::Json {
|
||||||
|
eprintln!(
|
||||||
|
"{}",
|
||||||
|
serde_json::json!({
|
||||||
|
"type": "error",
|
||||||
|
"error": format!("/{cmd_root} is not yet implemented in this build"),
|
||||||
|
"command": raw_command,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
eprintln!("/{cmd_root} is not yet implemented in this build");
|
||||||
|
}
|
||||||
|
std::process::exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
let command = match SlashCommand::parse(raw_command) {
|
let command = match SlashCommand::parse(raw_command) {
|
||||||
Ok(Some(command)) => command,
|
Ok(Some(command)) => command,
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
@@ -7355,6 +7382,77 @@ const STUB_COMMANDS: &[&str] = &[
|
|||||||
"tag",
|
"tag",
|
||||||
"output-style",
|
"output-style",
|
||||||
"add-dir",
|
"add-dir",
|
||||||
|
// Spec entries with no parse arm — produce circular "Did you mean" error
|
||||||
|
// without this guard. Adding here routes them to the proper unsupported
|
||||||
|
// message and excludes them from REPL completions / help.
|
||||||
|
"allowed-tools",
|
||||||
|
"bookmarks",
|
||||||
|
"workspace",
|
||||||
|
"reasoning",
|
||||||
|
"budget",
|
||||||
|
"rate-limit",
|
||||||
|
"changelog",
|
||||||
|
"diagnostics",
|
||||||
|
"metrics",
|
||||||
|
"tool-details",
|
||||||
|
"focus",
|
||||||
|
"unfocus",
|
||||||
|
"pin",
|
||||||
|
"unpin",
|
||||||
|
"language",
|
||||||
|
"profile",
|
||||||
|
"max-tokens",
|
||||||
|
"temperature",
|
||||||
|
"system-prompt",
|
||||||
|
"notifications",
|
||||||
|
"telemetry",
|
||||||
|
"env",
|
||||||
|
"project",
|
||||||
|
"terminal-setup",
|
||||||
|
"api-key",
|
||||||
|
"reset",
|
||||||
|
"undo",
|
||||||
|
"stop",
|
||||||
|
"retry",
|
||||||
|
"paste",
|
||||||
|
"screenshot",
|
||||||
|
"image",
|
||||||
|
"search",
|
||||||
|
"listen",
|
||||||
|
"speak",
|
||||||
|
"format",
|
||||||
|
"test",
|
||||||
|
"lint",
|
||||||
|
"build",
|
||||||
|
"run",
|
||||||
|
"git",
|
||||||
|
"stash",
|
||||||
|
"blame",
|
||||||
|
"log",
|
||||||
|
"cron",
|
||||||
|
"team",
|
||||||
|
"benchmark",
|
||||||
|
"migrate",
|
||||||
|
"templates",
|
||||||
|
"explain",
|
||||||
|
"refactor",
|
||||||
|
"docs",
|
||||||
|
"fix",
|
||||||
|
"perf",
|
||||||
|
"chat",
|
||||||
|
"web",
|
||||||
|
"map",
|
||||||
|
"symbols",
|
||||||
|
"references",
|
||||||
|
"definition",
|
||||||
|
"hover",
|
||||||
|
"autofix",
|
||||||
|
"multi",
|
||||||
|
"macro",
|
||||||
|
"alias",
|
||||||
|
"parallel",
|
||||||
|
"subagent",
|
||||||
|
"agent",
|
||||||
];
|
];
|
||||||
|
|
||||||
fn slash_command_completion_candidates_with_sessions(
|
fn slash_command_completion_candidates_with_sessions(
|
||||||
|
|||||||
Reference in New Issue
Block a user