mirror of
https://github.com/instructkr/claw-code.git
synced 2026-04-10 10:04:50 +08:00
fix(cli): exclude stub slash commands from help output — ROADMAP #39
The --help slash-command section was listing ~35 unimplemented commands
alongside working ones. Combined with the completions fix (c55c510), the
discovery surface now consistently shows only implemented commands.
Changes:
- commands crate: add render_slash_command_help_filtered(exclude: &[&str])
- move STUB_COMMANDS to module-level const in main.rs (reused by both
completions and help rendering)
- replace render_slash_command_help() with filtered variant at all
help-rendering call sites
156 CLI tests pass, fmt clean.
This commit is contained in:
@@ -1938,6 +1938,42 @@ pub fn suggest_slash_commands(input: &str, limit: usize) -> Vec<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
/// Render the slash-command help section, optionally excluding stub commands
|
||||||
|
/// (commands that are registered in the spec list but not yet implemented).
|
||||||
|
/// Pass an empty slice to include all commands.
|
||||||
|
pub fn render_slash_command_help_filtered(exclude: &[&str]) -> String {
|
||||||
|
let mut lines = vec![
|
||||||
|
"Slash commands".to_string(),
|
||||||
|
" Start here /status, /diff, /agents, /skills, /commit".to_string(),
|
||||||
|
" [resume] also works with --resume SESSION.jsonl".to_string(),
|
||||||
|
String::new(),
|
||||||
|
];
|
||||||
|
|
||||||
|
let categories = ["Session", "Tools", "Config", "Debug"];
|
||||||
|
|
||||||
|
for category in categories {
|
||||||
|
lines.push(category.to_string());
|
||||||
|
for spec in slash_command_specs()
|
||||||
|
.iter()
|
||||||
|
.filter(|spec| slash_command_category(spec.name) == category)
|
||||||
|
.filter(|spec| !exclude.contains(&spec.name))
|
||||||
|
{
|
||||||
|
lines.push(format_slash_command_help_line(spec));
|
||||||
|
}
|
||||||
|
lines.push(String::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
lines
|
||||||
|
.into_iter()
|
||||||
|
.rev()
|
||||||
|
.skip_while(String::is_empty)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into_iter()
|
||||||
|
.rev()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render_slash_command_help() -> String {
|
pub fn render_slash_command_help() -> String {
|
||||||
let mut lines = vec![
|
let mut lines = vec![
|
||||||
"Slash commands".to_string(),
|
"Slash commands".to_string(),
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ use commands::{
|
|||||||
classify_skills_slash_command, handle_agents_slash_command, handle_agents_slash_command_json,
|
classify_skills_slash_command, handle_agents_slash_command, handle_agents_slash_command_json,
|
||||||
handle_mcp_slash_command, handle_mcp_slash_command_json, handle_plugins_slash_command,
|
handle_mcp_slash_command, handle_mcp_slash_command_json, handle_plugins_slash_command,
|
||||||
handle_skills_slash_command, handle_skills_slash_command_json, render_slash_command_help,
|
handle_skills_slash_command, handle_skills_slash_command_json, render_slash_command_help,
|
||||||
resume_supported_slash_commands, slash_command_specs, validate_slash_command_input,
|
render_slash_command_help_filtered, resume_supported_slash_commands, slash_command_specs,
|
||||||
SkillSlashDispatch, SlashCommand,
|
validate_slash_command_input, SkillSlashDispatch, SlashCommand,
|
||||||
};
|
};
|
||||||
use compat_harness::{extract_manifest, UpstreamPaths};
|
use compat_harness::{extract_manifest, UpstreamPaths};
|
||||||
use init::initialize_repo;
|
use init::initialize_repo;
|
||||||
@@ -4711,7 +4711,7 @@ fn render_repl_help() -> String {
|
|||||||
" Browse sessions /session list".to_string(),
|
" Browse sessions /session list".to_string(),
|
||||||
" Show prompt history /history [count]".to_string(),
|
" Show prompt history /history [count]".to_string(),
|
||||||
String::new(),
|
String::new(),
|
||||||
render_slash_command_help(),
|
render_slash_command_help_filtered(STUB_COMMANDS),
|
||||||
]
|
]
|
||||||
.join(
|
.join(
|
||||||
"
|
"
|
||||||
@@ -6925,6 +6925,51 @@ fn collect_prompt_cache_events(summary: &runtime::TurnSummary) -> Vec<serde_json
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Slash commands that are registered in the spec list but not yet implemented
|
||||||
|
/// in this build. Used to filter both REPL completions and help output so the
|
||||||
|
/// discovery surface only shows commands that actually work (ROADMAP #39).
|
||||||
|
const STUB_COMMANDS: &[&str] = &[
|
||||||
|
"login",
|
||||||
|
"logout",
|
||||||
|
"vim",
|
||||||
|
"upgrade",
|
||||||
|
"stats",
|
||||||
|
"share",
|
||||||
|
"feedback",
|
||||||
|
"files",
|
||||||
|
"fast",
|
||||||
|
"exit",
|
||||||
|
"summary",
|
||||||
|
"desktop",
|
||||||
|
"brief",
|
||||||
|
"advisor",
|
||||||
|
"stickers",
|
||||||
|
"insights",
|
||||||
|
"thinkback",
|
||||||
|
"release-notes",
|
||||||
|
"security-review",
|
||||||
|
"keybindings",
|
||||||
|
"privacy-settings",
|
||||||
|
"plan",
|
||||||
|
"review",
|
||||||
|
"tasks",
|
||||||
|
"theme",
|
||||||
|
"voice",
|
||||||
|
"usage",
|
||||||
|
"rename",
|
||||||
|
"copy",
|
||||||
|
"hooks",
|
||||||
|
"context",
|
||||||
|
"color",
|
||||||
|
"effort",
|
||||||
|
"branch",
|
||||||
|
"rewind",
|
||||||
|
"ide",
|
||||||
|
"tag",
|
||||||
|
"output-style",
|
||||||
|
"add-dir",
|
||||||
|
];
|
||||||
|
|
||||||
fn slash_command_completion_candidates_with_sessions(
|
fn slash_command_completion_candidates_with_sessions(
|
||||||
model: &str,
|
model: &str,
|
||||||
active_session_id: Option<&str>,
|
active_session_id: Option<&str>,
|
||||||
@@ -6932,51 +6977,6 @@ fn slash_command_completion_candidates_with_sessions(
|
|||||||
) -> Vec<String> {
|
) -> Vec<String> {
|
||||||
let mut completions = BTreeSet::new();
|
let mut completions = BTreeSet::new();
|
||||||
|
|
||||||
// Commands that are registered in the spec list but not yet implemented
|
|
||||||
// in this build. Exclude them from completions so the discovery surface
|
|
||||||
// matches what actually works (ROADMAP #39).
|
|
||||||
const STUB_COMMANDS: &[&str] = &[
|
|
||||||
"login",
|
|
||||||
"logout",
|
|
||||||
"vim",
|
|
||||||
"upgrade",
|
|
||||||
"stats",
|
|
||||||
"share",
|
|
||||||
"feedback",
|
|
||||||
"files",
|
|
||||||
"fast",
|
|
||||||
"exit",
|
|
||||||
"summary",
|
|
||||||
"desktop",
|
|
||||||
"brief",
|
|
||||||
"advisor",
|
|
||||||
"stickers",
|
|
||||||
"insights",
|
|
||||||
"thinkback",
|
|
||||||
"release-notes",
|
|
||||||
"security-review",
|
|
||||||
"keybindings",
|
|
||||||
"privacy-settings",
|
|
||||||
"plan",
|
|
||||||
"review",
|
|
||||||
"tasks",
|
|
||||||
"theme",
|
|
||||||
"voice",
|
|
||||||
"usage",
|
|
||||||
"rename",
|
|
||||||
"copy",
|
|
||||||
"hooks",
|
|
||||||
"context",
|
|
||||||
"color",
|
|
||||||
"effort",
|
|
||||||
"branch",
|
|
||||||
"rewind",
|
|
||||||
"ide",
|
|
||||||
"tag",
|
|
||||||
"output-style",
|
|
||||||
"add-dir",
|
|
||||||
];
|
|
||||||
|
|
||||||
for spec in slash_command_specs() {
|
for spec in slash_command_specs() {
|
||||||
if STUB_COMMANDS.contains(&spec.name) {
|
if STUB_COMMANDS.contains(&spec.name) {
|
||||||
continue;
|
continue;
|
||||||
@@ -7874,7 +7874,7 @@ fn print_help_to(out: &mut impl Write) -> io::Result<()> {
|
|||||||
)?;
|
)?;
|
||||||
writeln!(out)?;
|
writeln!(out)?;
|
||||||
writeln!(out, "Interactive slash commands:")?;
|
writeln!(out, "Interactive slash commands:")?;
|
||||||
writeln!(out, "{}", render_slash_command_help())?;
|
writeln!(out, "{}", render_slash_command_help_filtered(STUB_COMMANDS))?;
|
||||||
writeln!(out)?;
|
writeln!(out)?;
|
||||||
let resume_commands = resume_supported_slash_commands()
|
let resume_commands = resume_supported_slash_commands()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|||||||
Reference in New Issue
Block a user