From 212f0b2ad4e2391d7cfe3ce34f9298c0573ccbac Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Wed, 27 May 2026 02:37:17 +0900 Subject: [PATCH] fix(#772): slash command aliases now resolve to canonical forms in interactive_only guidance --- ROADMAP.md | 2 ++ rust/crates/rusty-claude-cli/src/main.rs | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 9c6ca0bf..a5380114 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -7709,3 +7709,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed) 770. **`claw cost/clear/memory/ultraplan/model` with trailing args fell to credential check** — dogfooded 2026-05-27 on `9e1be056`. Same fallthrough gap as #767/#769: these slash-only verbs had no multi-arg match arms, so `claw cost breakdown`, `claw clear --force`, `claw memory reset`, `claw ultraplan bogus`, `claw model opus extra` all became `CliAction::Prompt` literals, hitting `missing_credentials` at the gate. Fix: added `"cost"`, `"clear"`, `"memory"`, `"ultraplan"`, `"model" if rest.len() > 1` match arms, each returning `interactive_only:` + `\n`-delimited hint. Integration test `slash_only_verbs_with_args_return_interactive_only_not_credentials_770` asserts all five cases. 36 CLI contract tests pass. [SCOPE: claw-code] Source: Jobdori sweep on `9e1be056`, 2026-05-27. 771. **`init extraarg` silently succeeded; `usage`/`stats`/`fork` with args fell to credential check** — dogfooded 2026-05-27 on `3a1d8838`. Two distinct gaps: (1) `claw init extraarg` returned `status:ok` with trailing positional ignored — `"init"` arm always returned `Ok(CliAction::Init)` regardless of `rest[1..]`; (2) `claw usage extra`, `claw stats extra`, `claw fork newbranch` had no match arms and fell to `CliAction::Prompt` + credential gate. Fixes: (1) added extra-arg check in `"init"` arm — rejects with `unexpected_extra_args:` prefix + `\n` usage hint; (2) added `"usage"`, `"stats"`, `"fork"` interactive-only arms. All four now return correct `error_kind` + non-null hint. 36 CLI contract tests pass. [SCOPE: claw-code] Source: Jobdori sweep on `3a1d8838`, 2026-05-27. + +772. **Slash command aliases bypassed `bare_slash_command_guidance` lookup** — dogfooded 2026-05-27 on `bf212b98`. `bare_slash_command_guidance()` only checked `spec.name == command_name`, not `spec.aliases`, so `claw yes`, `claw no`, `claw y`, `claw n`, `claw skill`, `claw cwd` all fell through (either to typo suggestions or `missing_credentials`). Should have returned `interactive_only:` guidance referencing the canonical form. Fix: (1) lookup changed to `spec.name == command_name || spec.aliases.contains(&command_name)`; (2) capture `canonical_name = slash_command.name`; (3) guidance strings updated to reference canonical form in remediation (e.g., `claw yes → /approve`, `claw n → /deny`, `claw skill → /skills`). 36 CLI contract tests pass. [SCOPE: claw-code] Source: Gaebal-gajae pinpoint on `bf212b98`, 2026-05-27. diff --git a/rust/crates/rusty-claude-cli/src/main.rs b/rust/crates/rusty-claude-cli/src/main.rs index dd684425..9290a6a5 100644 --- a/rust/crates/rusty-claude-cli/src/main.rs +++ b/rust/crates/rusty-claude-cli/src/main.rs @@ -1519,17 +1519,20 @@ fn bare_slash_command_guidance(command_name: &str) -> Option { } let slash_command = slash_command_specs() .iter() - .find(|spec| spec.name == command_name)?; + // #772: check both spec.name and spec.aliases for command-line invocations + .find(|spec| spec.name == command_name || spec.aliases.contains(&command_name))?; + let canonical_name = slash_command.name; // #745: newline before remediation text so split_error_hint populates hint field let guidance = if slash_command.resume_supported { format!( - "`claw {command_name}` is a slash command.\nUse `claw --resume SESSION.jsonl /{command_name}` or start `claw` and run `/{command_name}`." + "`claw {command_name}` is a slash command.\nUse `claw --resume SESSION.jsonl /{canonical_name}` or start `claw` and run `/{canonical_name}`." ) } else { format!( - "`claw {command_name}` is a slash command.\nStart `claw` and run `/{command_name}` inside the REPL." + "`claw {command_name}` is a slash command.\nStart `claw` and run `/{canonical_name}` inside the REPL." ) }; + // #772: help text still mentions the alias, but the remediation shows canonical form Some(guidance) }