fix(cli): dispatch bare skill names to skill invoker in REPL — ROADMAP #36

Users were typing skill names (e.g. 'caveman', 'find-skills') directly in
the REPL and getting LLM responses instead of skill invocation. Only
'/skills <name>' triggered dispatch; bare names fell through to run_turn.

Fix: after slash-command parse returns None (bare text), check if the first
token looks like a skill name (alphanumeric/dash/underscore, no slash).
If resolve_skill_invocation() confirms the skill exists, dispatch the full
input as a skill prompt. Unknown words fall through unchanged.

156 CLI tests pass, fmt clean.
This commit is contained in:
YeonGyu-Kim
2026-04-09 16:01:18 +09:00
parent 4d10caebc6
commit 8d0308eecb

View File

@@ -35,8 +35,8 @@ use commands::{
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_skills_slash_command, handle_skills_slash_command_json, render_slash_command_help,
render_slash_command_help_filtered, resume_supported_slash_commands, slash_command_specs,
validate_slash_command_input, SkillSlashDispatch, SlashCommand,
render_slash_command_help_filtered, resolve_skill_invocation, resume_supported_slash_commands,
slash_command_specs, validate_slash_command_input, SkillSlashDispatch, SlashCommand,
};
use compat_harness::{extract_manifest, UpstreamPaths};
use init::initialize_repo;
@@ -2862,6 +2862,26 @@ fn run_repl(
continue;
}
}
// Bare-word skill dispatch: if the first token of the input
// matches a known skill name, invoke it as `/skills <input>`
// rather than forwarding raw text to the LLM (ROADMAP #36).
let bare_first_token = trimmed.split_whitespace().next().unwrap_or_default();
let looks_like_skill_name = !bare_first_token.is_empty()
&& !bare_first_token.starts_with('/')
&& bare_first_token
.chars()
.all(|c| c.is_alphanumeric() || c == '-' || c == '_');
if looks_like_skill_name {
let cwd = std::env::current_dir().unwrap_or_default();
if let Ok(SkillSlashDispatch::Invoke(prompt)) =
resolve_skill_invocation(&cwd, Some(&trimmed))
{
editor.push_history(input);
cli.record_prompt_history(&trimmed);
cli.run_turn(&prompt)?;
continue;
}
}
editor.push_history(input);
cli.record_prompt_history(&trimmed);
cli.run_turn(&trimmed)?;