mirror of
https://github.com/ultraworkers/claw-code.git
synced 2026-05-30 11:45:20 +08:00
fix(#718): implement plugins show/info/describe command with not-found error, parity with agents/skills show
This commit is contained in:
parent
8d80f2ffe7
commit
556a598f2d
@ -7601,3 +7601,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed)
|
|||||||
716. **Resume-path error JSON used legacy `{type:"error", error:...}` shape instead of standard `{kind, action, status:"error", error_kind, exit_code}` envelope — 5 error paths affected** — dogfooded 2026-05-26 on `76c8d480`. Session load failure, unsupported command, unsupported resumed command, SlashCommand parse error, and broad-cwd abort all emitted the old two-key shape. Fix: aligned all 5 to `{kind, action:"resume"|"abort", status:"error", error_kind, error, exit_code}`. Updated `resumed_stub_command_emits_not_implemented_json` test to assert `status:"error"` + `kind:"unsupported_command"`. Source: Jobdori dogfood on `76c8d480`, 2026-05-26.
|
716. **Resume-path error JSON used legacy `{type:"error", error:...}` shape instead of standard `{kind, action, status:"error", error_kind, exit_code}` envelope — 5 error paths affected** — dogfooded 2026-05-26 on `76c8d480`. Session load failure, unsupported command, unsupported resumed command, SlashCommand parse error, and broad-cwd abort all emitted the old two-key shape. Fix: aligned all 5 to `{kind, action:"resume"|"abort", status:"error", error_kind, error, exit_code}`. Updated `resumed_stub_command_emits_not_implemented_json` test to assert `status:"error"` + `kind:"unsupported_command"`. Source: Jobdori dogfood on `76c8d480`, 2026-05-26.
|
||||||
|
|
||||||
717. **`claw agents show <name>` missing — `handle_agents_slash_command_json` only accepted `list`; `show/info/describe` was unimplemented unlike skills which had parity** — dogfooded 2026-05-26 on `6a007344`. `claw agents show claw-code --output-format json` returned `unknown_agents_subcommand` error. Fix: added `show/info/describe` and `list <filter>` arms to both `handle_agents_slash_command` and `handle_agents_slash_command_json`, mirroring the skills handler; renamed `render_agents_report_json` → `render_agents_report_json_with_action`; not-found path returns `{kind:"agents", action:"show", status:"error", error_kind:"agent_not_found", requested:"<name>"}` + Ok; added `classify_error_kind` branch for `agent_not_found`. Updated 2 tests. Source: Jobdori dogfood on `6a007344`, 2026-05-26.
|
717. **`claw agents show <name>` missing — `handle_agents_slash_command_json` only accepted `list`; `show/info/describe` was unimplemented unlike skills which had parity** — dogfooded 2026-05-26 on `6a007344`. `claw agents show claw-code --output-format json` returned `unknown_agents_subcommand` error. Fix: added `show/info/describe` and `list <filter>` arms to both `handle_agents_slash_command` and `handle_agents_slash_command_json`, mirroring the skills handler; renamed `render_agents_report_json` → `render_agents_report_json_with_action`; not-found path returns `{kind:"agents", action:"show", status:"error", error_kind:"agent_not_found", requested:"<name>"}` + Ok; added `classify_error_kind` branch for `agent_not_found`. Updated 2 tests. Source: Jobdori dogfood on `6a007344`, 2026-05-26.
|
||||||
|
|
||||||
|
718. **`claw plugins show <name>` unimplemented — unlike `agents show` and `skills show`, `/plugins show` returned `unknown_plugins_action` error** — dogfooded 2026-05-26 on `8d80f2ff`. Fix: added `show/info/describe` arm to `handle_plugins_slash_command` that filters installed plugins by name; `print_plugins` JSON path filters `payload.plugins` when action is `show/info/describe` and emits `{kind:"plugin", action:"show", status:"error", error_kind:"plugin_not_found", requested:"<name>"}` for missing names. Updated error message in catch-all to name `show` as supported. Source: Jobdori dogfood on `8d80f2ff`, 2026-05-26.
|
||||||
|
|||||||
@ -2301,8 +2301,28 @@ pub fn handle_plugins_slash_command(
|
|||||||
reload_runtime: true,
|
reload_runtime: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Some("show" | "info" | "describe") => {
|
||||||
|
// Show a named plugin by filtering the installed registry.
|
||||||
|
// Without a target, shows all (same as list).
|
||||||
|
let report = manager.installed_plugin_registry_report()?;
|
||||||
|
let plugins: Vec<_> = if let Some(name) = target {
|
||||||
|
let needle = name.to_lowercase();
|
||||||
|
report
|
||||||
|
.summaries()
|
||||||
|
.into_iter()
|
||||||
|
.filter(|p| p.metadata.id.to_lowercase() == needle)
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
report.summaries().into_iter().collect()
|
||||||
|
};
|
||||||
|
let failures = report.failures();
|
||||||
|
Ok(PluginsCommandResult {
|
||||||
|
message: render_plugins_report_with_failures(&plugins, failures),
|
||||||
|
reload_runtime: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
Some(other) => Err(PluginError::CommandFailed(format!(
|
Some(other) => Err(PluginError::CommandFailed(format!(
|
||||||
"unknown_plugins_action: '{other}' is not a supported /plugins action. Use list, install, enable, disable, uninstall, or update."
|
"unknown_plugins_action: '{other}' is not a supported /plugins action. Use list, show, install, enable, disable, uninstall, or update."
|
||||||
))),
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5999,28 +5999,65 @@ impl LiveCli {
|
|||||||
CliOutputFormat::Text => println!("{}", payload.message),
|
CliOutputFormat::Text => println!("{}", payload.message),
|
||||||
CliOutputFormat::Json => {
|
CliOutputFormat::Json => {
|
||||||
let action_str = action.unwrap_or("list");
|
let action_str = action.unwrap_or("list");
|
||||||
let enabled_count = payload
|
// For show/info/describe, filter to the named plugin.
|
||||||
.plugins
|
let is_show_action = matches!(action_str, "show" | "info" | "describe");
|
||||||
|
let filtered_plugins: Vec<_> = if is_show_action {
|
||||||
|
if let Some(name) = target {
|
||||||
|
let needle = name.to_lowercase();
|
||||||
|
payload
|
||||||
|
.plugins
|
||||||
|
.iter()
|
||||||
|
.filter(|p| {
|
||||||
|
p.get("id")
|
||||||
|
.and_then(|v| v.as_str())
|
||||||
|
.map(|id| id.to_lowercase() == needle)
|
||||||
|
.unwrap_or(false)
|
||||||
|
})
|
||||||
|
.cloned()
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
payload.plugins.clone()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
payload.plugins.clone()
|
||||||
|
};
|
||||||
|
// Return not-found error for show with missing target.
|
||||||
|
if is_show_action {
|
||||||
|
if let Some(name) = target {
|
||||||
|
if filtered_plugins.is_empty() {
|
||||||
|
let obj = json!({
|
||||||
|
"kind": "plugin",
|
||||||
|
"action": action_str,
|
||||||
|
"status": "error",
|
||||||
|
"error_kind": "plugin_not_found",
|
||||||
|
"requested": name,
|
||||||
|
});
|
||||||
|
println!("{}", serde_json::to_string_pretty(&obj)?);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let enabled_count = filtered_plugins
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|p| p.get("enabled").and_then(|v| v.as_bool()).unwrap_or(false))
|
.filter(|p| p.get("enabled").and_then(|v| v.as_bool()).unwrap_or(false))
|
||||||
.count();
|
.count();
|
||||||
let disabled_count = payload.plugins.len().saturating_sub(enabled_count);
|
let disabled_count = filtered_plugins.len().saturating_sub(enabled_count);
|
||||||
let mut obj = json!({
|
let mut obj = json!({
|
||||||
"kind": "plugin",
|
"kind": "plugin",
|
||||||
"action": action_str,
|
"action": action_str,
|
||||||
"status": payload.status,
|
"status": payload.status,
|
||||||
"summary": {
|
"summary": {
|
||||||
"total": payload.plugins.len(),
|
"total": filtered_plugins.len(),
|
||||||
"enabled": enabled_count,
|
"enabled": enabled_count,
|
||||||
"disabled": disabled_count,
|
"disabled": disabled_count,
|
||||||
"load_failures": payload.load_failures.len(),
|
"load_failures": payload.load_failures.len(),
|
||||||
},
|
},
|
||||||
"config_load_error": payload.config_load_error,
|
"config_load_error": payload.config_load_error,
|
||||||
"plugins": payload.plugins,
|
"plugins": filtered_plugins,
|
||||||
"load_failures": payload.load_failures,
|
"load_failures": payload.load_failures,
|
||||||
});
|
});
|
||||||
// Only include operation-result fields for mutating actions
|
// Only include operation-result fields for mutating actions (not list/show)
|
||||||
if action_str != "list" {
|
if action_str != "list" && !is_show_action {
|
||||||
obj["target"] = json!(target);
|
obj["target"] = json!(target);
|
||||||
obj["reload_runtime"] = json!(payload.reload_runtime);
|
obj["reload_runtime"] = json!(payload.reload_runtime);
|
||||||
obj["message"] = json!(payload.message);
|
obj["message"] = json!(payload.message);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user