mirror of
https://github.com/ultraworkers/claw-code.git
synced 2026-04-12 02:21:44 +08:00
feat(commands): surface broken plugin warnings in /plugins list
Implements ROADMAP #40: Show warnings for broken/missing plugin manifests instead of silently failing. - Add PluginLoadFailure import - New render_plugins_report_with_failures() function - Shows ⚠️ warnings for failed plugin loads with error details - Updates ROADMAP.md to mark #40 in progress Ultraclaw droid session: ultraclaw-03-broken-plugins
This commit is contained in:
parent
8aa1fa2cc9
commit
2ef447bd07
4
.gitignore
vendored
4
.gitignore
vendored
@ -5,3 +5,7 @@ archive/
|
||||
# Claude Code local artifacts
|
||||
.claude/settings.local.json
|
||||
.claude/sessions/
|
||||
# Claw Code local artifacts
|
||||
.claw/settings.local.json
|
||||
.claw/sessions/
|
||||
status-help.txt
|
||||
|
||||
75
ROADMAP.md
75
ROADMAP.md
File diff suppressed because one or more lines are too long
@ -4,7 +4,7 @@ use std::fmt;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use plugins::{PluginError, PluginManager, PluginSummary};
|
||||
use plugins::{PluginError, PluginLoadFailure, PluginManager, PluginSummary};
|
||||
use runtime::{
|
||||
compact_session, CompactionConfig, ConfigLoader, ConfigSource, McpOAuthConfig, McpServerConfig,
|
||||
ScopedMcpServerConfig, Session,
|
||||
@ -2210,10 +2210,15 @@ pub fn handle_plugins_slash_command(
|
||||
manager: &mut PluginManager,
|
||||
) -> Result<PluginsCommandResult, PluginError> {
|
||||
match action {
|
||||
None | Some("list") => Ok(PluginsCommandResult {
|
||||
message: render_plugins_report(&manager.list_installed_plugins()?),
|
||||
reload_runtime: false,
|
||||
}),
|
||||
None | Some("list") => {
|
||||
let report = manager.installed_plugin_registry_report()?;
|
||||
let plugins = report.summaries();
|
||||
let failures = report.failures();
|
||||
Ok(PluginsCommandResult {
|
||||
message: render_plugins_report_with_failures(&plugins, failures),
|
||||
reload_runtime: false,
|
||||
})
|
||||
}
|
||||
Some("install") => {
|
||||
let Some(target) = target else {
|
||||
return Ok(PluginsCommandResult {
|
||||
@ -2667,6 +2672,48 @@ pub fn render_plugins_report(plugins: &[PluginSummary]) -> String {
|
||||
lines.join("\n")
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn render_plugins_report_with_failures(
|
||||
plugins: &[PluginSummary],
|
||||
failures: &[PluginLoadFailure],
|
||||
) -> String {
|
||||
let mut lines = vec!["Plugins".to_string()];
|
||||
|
||||
// Show successfully loaded plugins
|
||||
if plugins.is_empty() {
|
||||
lines.push(" No plugins installed.".to_string());
|
||||
} else {
|
||||
for plugin in plugins {
|
||||
let enabled = if plugin.enabled {
|
||||
"enabled"
|
||||
} else {
|
||||
"disabled"
|
||||
};
|
||||
lines.push(format!(
|
||||
" {name:<20} v{version:<10} {enabled}",
|
||||
name = plugin.metadata.name,
|
||||
version = plugin.metadata.version,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Show warnings for broken plugins
|
||||
if !failures.is_empty() {
|
||||
lines.push("".to_string());
|
||||
lines.push("Warnings:".to_string());
|
||||
for failure in failures {
|
||||
lines.push(format!(
|
||||
" ⚠️ Failed to load {} plugin from `{}`",
|
||||
failure.kind,
|
||||
failure.plugin_root.display()
|
||||
));
|
||||
lines.push(format!(" Error: {}", failure.error()));
|
||||
}
|
||||
}
|
||||
|
||||
lines.join("\n")
|
||||
}
|
||||
|
||||
fn render_plugin_install_report(plugin_id: &str, plugin: Option<&PluginSummary>) -> String {
|
||||
let name = plugin.map_or(plugin_id, |plugin| plugin.metadata.name.as_str());
|
||||
let version = plugin.map_or("unknown", |plugin| plugin.metadata.version.as_str());
|
||||
|
||||
Loading…
Reference in New Issue
Block a user