feat: .edit skill <name> support from within the REPL

This commit is contained in:
2026-06-01 15:48:19 -06:00
parent 0f90dd5f53
commit 5c374bb5bf
2 changed files with 28 additions and 16 deletions
+11
View File
@@ -1928,6 +1928,15 @@ impl RequestContext {
"skill", "skill",
"agent-data", "agent-data",
]), ]),
".edit" => super::map_completion_values(vec![
"config",
"mcp-config",
"role",
"session",
"rag-docs",
"agent-config",
"skill",
]),
".vault" => { ".vault" => {
let mut values = vec!["add", "get", "update", "delete", "list"]; let mut values = vec!["add", "get", "update", "delete", "list"];
values.sort_unstable(); values.sort_unstable();
@@ -1938,6 +1947,8 @@ impl RequestContext {
} }
_ => vec![], _ => vec![],
}; };
} else if cmd == ".edit" && args.first() == Some(&"skill") && args.len() == 2 {
values = super::map_completion_values(paths::list_skills());
} else if cmd == ".install" && args.first() == Some(&"remote") && args.len() >= 2 { } else if cmd == ".install" && args.first() == Some(&"remote") && args.len() >= 2 {
let prev = args.get(args.len() - 2).copied().unwrap_or(""); let prev = args.get(args.len() - 2).copied().unwrap_or("");
if prev == "--filter" { if prev == "--filter" {
+17 -16
View File
@@ -529,8 +529,8 @@ pub async fn run_repl_command(
.skill loaded # List currently-loaded skills .skill loaded # List currently-loaded skills
.skill load <name> # Load a skill into the current context .skill load <name> # Load a skill into the current context
.skill unload <name> # Unload a loaded skill .skill unload <name> # Unload a loaded skill
.skill edit <name> # Open an existing skill in $EDITOR .skill <name> # Open the skill in $EDITOR; create with a scaffold if missing
.skill <name> # Open the skill in $EDITOR; create with a scaffold if missing"# # (Use `.edit skill <name>` to edit an existing skill without the create-if-missing behavior.)"#
), ),
"loaded" => ctx.list_loaded_skills(), "loaded" => ctx.list_loaded_skills(),
"load" => { "load" => {
@@ -547,19 +547,6 @@ pub async fn run_repl_command(
ctx.unload_skill_repl(rest, abort_signal.clone()).await?; ctx.unload_skill_repl(rest, abort_signal.clone()).await?;
} }
} }
"edit" => {
if rest.is_empty() {
println!("Usage: .skill edit <name>");
} else if !paths::has_skill(rest) {
bail!(
"Skill '{rest}' is not installed (expected at {})",
paths::skill_file(rest).display()
);
} else {
let app = Arc::clone(&ctx.app.config);
ctx.upsert_skill(app.as_ref(), rest)?;
}
}
name => { name => {
let app = Arc::clone(&ctx.app.config); let app = Arc::clone(&ctx.app.config);
ctx.upsert_skill(app.as_ref(), name)?; ctx.upsert_skill(app.as_ref(), name)?;
@@ -712,9 +699,23 @@ pub async fn run_repl_command(
Some("mcp-config") => { Some("mcp-config") => {
ctx.edit_mcp_config()?; ctx.edit_mcp_config()?;
} }
Some(s) if s == "skill" || s.starts_with("skill ") => {
let name = s.strip_prefix("skill").unwrap_or("").trim();
if name.is_empty() {
println!("Usage: .edit skill <name>");
} else if !paths::has_skill(name) {
bail!(
"Skill '{name}' is not installed (expected at {})",
paths::skill_file(name).display()
);
} else {
let app = Arc::clone(&ctx.app.config);
ctx.upsert_skill(app.as_ref(), name)?;
}
}
_ => { _ => {
println!( println!(
r#"Usage: .edit <config|mcp-config|role|session|rag-docs|agent-config>"# r#"Usage: .edit <config|mcp-config|role|session|rag-docs|agent-config|skill <name>>"#
) )
} }
} }