mirror of
https://github.com/ultraworkers/claw-code.git
synced 2026-05-30 03:35:20 +08:00
fix: unknown slash command emits unknown_slash_command error_kind (#827)
Both direct-slash CLI path (claw /boguscommand) and resume slash path (claw --resume session /boguscommand) previously emitted error_kind:unknown (opaque fallback). Machine consumers could not distinguish unrecognized slash commands from other error classes. Fix: - format_unknown_direct_slash_command: prefix with 'unknown_slash_command:' - format_unknown_slash_command (resume path): prefix with 'unknown_slash_command:' - Add classifier arm for 'unknown_slash_command:' prefix One new regression test: direct_unknown_slash_command_emits_typed_error_kind Uses the direct-slash CLI path (no session load needed; reproducible on CI). 572 tests pass, 1 pre-existing worker_boot failure unrelated.
This commit is contained in:
parent
58902915f6
commit
9d05573f24
@ -271,7 +271,9 @@ Run `claw --help` for usage."
|
|||||||
/// matching against the error messages produced throughout the CLI surface.
|
/// matching against the error messages produced throughout the CLI surface.
|
||||||
fn classify_error_kind(message: &str) -> &'static str {
|
fn classify_error_kind(message: &str) -> &'static str {
|
||||||
// Check specific patterns first (more specific before generic)
|
// Check specific patterns first (more specific before generic)
|
||||||
if message.starts_with("command_not_found:") {
|
if message.starts_with("unknown_slash_command:") {
|
||||||
|
"unknown_slash_command"
|
||||||
|
} else if message.starts_with("command_not_found:") {
|
||||||
"command_not_found"
|
"command_not_found"
|
||||||
} else if message.contains("missing Anthropic credentials") {
|
} else if message.contains("missing Anthropic credentials") {
|
||||||
"missing_credentials"
|
"missing_credentials"
|
||||||
@ -1764,7 +1766,10 @@ fn format_unknown_option(option: &str) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn format_unknown_direct_slash_command(name: &str) -> String {
|
fn format_unknown_direct_slash_command(name: &str) -> String {
|
||||||
let mut message = format!("unknown slash command outside the REPL: /{name}");
|
// #827: prefix with classifier-friendly token so classify_error_kind
|
||||||
|
// returns "unknown_slash_command" instead of the opaque fallback.
|
||||||
|
let mut message =
|
||||||
|
format!("unknown_slash_command: unknown slash command outside the REPL: /{name}");
|
||||||
if let Some(suggestions) = render_suggestion_line("Did you mean", &suggest_slash_commands(name))
|
if let Some(suggestions) = render_suggestion_line("Did you mean", &suggest_slash_commands(name))
|
||||||
{
|
{
|
||||||
message.push('\n');
|
message.push('\n');
|
||||||
@ -1779,7 +1784,9 @@ fn format_unknown_direct_slash_command(name: &str) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn format_unknown_slash_command(name: &str) -> String {
|
fn format_unknown_slash_command(name: &str) -> String {
|
||||||
let mut message = format!("Unknown slash command: /{name}");
|
// #827: prefix with classifier-friendly token so classify_error_kind
|
||||||
|
// can return "unknown_slash_command" instead of the opaque fallback.
|
||||||
|
let mut message = format!("unknown_slash_command: Unknown slash command: /{name}");
|
||||||
if let Some(suggestions) = render_suggestion_line("Did you mean", &suggest_slash_commands(name))
|
if let Some(suggestions) = render_suggestion_line("Did you mean", &suggest_slash_commands(name))
|
||||||
{
|
{
|
||||||
message.push('\n');
|
message.push('\n');
|
||||||
|
|||||||
@ -3967,3 +3967,29 @@ fn multi_word_unknown_subcommand_falls_through_to_prompt_826() {
|
|||||||
"multi-word fallthrough JSON must have empty stderr: {stderr:?}"
|
"multi-word fallthrough JSON must have empty stderr: {stderr:?}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #827: direct /unknown-slash-command must emit typed error_kind, not "unknown"
|
||||||
|
// Uses the direct-slash CLI path (no session load needed; reproducible on CI).
|
||||||
|
#[test]
|
||||||
|
fn direct_unknown_slash_command_emits_typed_error_kind() {
|
||||||
|
let root = unique_temp_dir("direct-unknown-slash-827");
|
||||||
|
std::fs::create_dir_all(&root).expect("create temp dir");
|
||||||
|
let output = run_claw(&root, &["--output-format", "json", "/boguscommand"], &[]);
|
||||||
|
assert_eq!(output.status.code(), Some(1), "unknown slash should exit 1");
|
||||||
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
let j: serde_json::Value =
|
||||||
|
serde_json::from_str(stdout.trim()).expect("unknown slash must emit JSON (#827)");
|
||||||
|
assert_ne!(
|
||||||
|
j["error_kind"], "unknown",
|
||||||
|
"direct unknown slash must not emit opaque \'unknown\' error_kind (#827): {j}"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
j["error_kind"], "unknown_slash_command",
|
||||||
|
"direct unknown slash must emit unknown_slash_command (#827): {j}"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
stderr.is_empty(),
|
||||||
|
"direct unknown slash JSON must have empty stderr (#827)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user