mirror of
https://github.com/instructkr/claude-code.git
synced 2026-05-27 07:56:46 +00:00
fix(#794): plugins install not-found path returns typed plugin_source_not_found instead of unknown+null
This commit is contained in:
@@ -7753,3 +7753,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed)
|
||||
792. **`claw agents list --bogus-flag` and `claw skills list --bogus-flag` silently returned `status:"ok" count:0` instead of an error** — dogfooded 2026-05-27 on `93a159dc`. The `list <filter>` arm in both handlers treated flag-shaped tokens (`--something`) as name substring filters. Since no agents/skills have `--bogus` in their name, result was empty success list — a false positive that masks typos and unknown flags. Fix: added flag-prefix guard at the top of both `list <args>` arms in `commands/src/lib.rs`; detected filter tokens starting with `-` return `unknown_option` + usage hint. Two new integration tests `agents_list_flag_shaped_filter_returns_unknown_option_792`, `skills_list_flag_shaped_filter_returns_unknown_option_792`. 53 CLI contract tests pass. [SCOPE: claw-code] Source: Jobdori agents/skills list probe on `93a159dc`, 2026-05-27.
|
||||
|
||||
793. **`claw plugins list --bogus-flag` silent empty success + `plugins uninstall <not-found>` had `hint:null`** — dogfooded 2026-05-27 on `abfa2e4c`. Two gaps: (1) `plugins list` filter branch in `print_plugins` treated `--bogus-flag` as an id substring filter, found no matches, returned `status:"ok"` empty list — same false-positive as #792 for agents/skills. (2) `plugins uninstall no-such` propagated `plugin_not_found` error via `?` with no `\n` delimiter; `plugin_not_found` was missing from `fallback_hint_for_error_kind` table. Fix: (1) added flag-prefix guard in `print_plugins` `is_list_action` branch (detects tokens starting with `-`, returns `unknown_option` + usage hint, exits 1); (2) added `"plugin_not_found"` → `"Run 'claw plugins list' to see installed plugins."` to fallback table. Two new tests `plugins_list_flag_shaped_filter_returns_unknown_option_793`, `plugins_uninstall_not_found_has_hint_793`. 55 CLI contract tests pass. [SCOPE: claw-code] Source: Jobdori plugins lifecycle probe on `abfa2e4c`, 2026-05-27.
|
||||
|
||||
794. **`claw plugins install /nonexistent/path` returned `error_kind:"unknown"` + `hint:null`** — dogfooded 2026-05-27 on `57a57ef7`. The error message `"plugin source '/path' was not found"` had no classifier arm, falling to `"unknown"`. Fix: added `plugin_source_not_found` classifier arm (`message.contains("plugin source") && message.contains("was not found")`); added `"plugin_source_not_found"` → `"Check that the path or URL is correct..."` to `fallback_hint_for_error_kind`. Unit test assertion added to `test_classify_error_kind`; integration test `plugins_install_not_found_path_returns_typed_kind_794` added. 56 CLI contract tests pass. [SCOPE: claw-code] Source: Jobdori plugins install probe on `57a57ef7`, 2026-05-27.
|
||||
|
||||
@@ -337,6 +337,9 @@ fn classify_error_kind(message: &str) -> &'static str {
|
||||
"agent_not_found"
|
||||
} else if message.contains("is not installed") {
|
||||
"plugin_not_found"
|
||||
} else if message.contains("plugin source") && message.contains("was not found") {
|
||||
// #794: `plugins install /nonexistent/path` → "plugin source ... was not found"
|
||||
"plugin_source_not_found"
|
||||
} else if (message.contains("skill source") && message.contains("not found"))
|
||||
|| message.starts_with("skill '")
|
||||
{
|
||||
@@ -414,6 +417,10 @@ fn fallback_hint_for_error_kind(kind: &str) -> Option<&'static str> {
|
||||
// #793: plugins uninstall/enable/disable of non-existing plugin propagates through
|
||||
// the ? operator with no \n delimiter, so split_error_hint returns None.
|
||||
"plugin_not_found" => Some("Run `claw plugins list` to see installed plugins."),
|
||||
// #794: plugins install with a path that doesn't exist
|
||||
"plugin_source_not_found" => Some(
|
||||
"Check that the path or URL is correct. Use a local directory or a valid registry id.",
|
||||
),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -13178,6 +13185,11 @@ mod tests {
|
||||
classify_error_kind("my-plugin is not installed"),
|
||||
"plugin_not_found"
|
||||
);
|
||||
// #794: plugins install with missing source path
|
||||
assert_eq!(
|
||||
classify_error_kind("plugin source `/nonexistent/path` was not found"),
|
||||
"plugin_source_not_found"
|
||||
);
|
||||
assert_eq!(
|
||||
classify_error_kind("skill source /path/to/skill not found"),
|
||||
"skill_not_found"
|
||||
|
||||
@@ -3156,3 +3156,48 @@ fn plugins_uninstall_not_found_has_hint_793() {
|
||||
"hint should reference plugins list, got: {h:?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plugins_install_not_found_path_returns_typed_kind_794() {
|
||||
// #794: `claw plugins install /nonexistent/path` returned error_kind:"unknown" + hint:null.
|
||||
// The message "plugin source ... was not found" had no classifier arm; fell to "unknown".
|
||||
// Fix: added "plugin_source_not_found" classifier arm + fallback hint table entry.
|
||||
let root = unique_temp_dir("plugins-install-794");
|
||||
fs::create_dir_all(&root).expect("temp dir");
|
||||
std::process::Command::new("git")
|
||||
.args(["init", "-q"])
|
||||
.current_dir(&root)
|
||||
.output()
|
||||
.ok();
|
||||
|
||||
let output = run_claw(
|
||||
&root,
|
||||
&[
|
||||
"--output-format",
|
||||
"json",
|
||||
"plugins",
|
||||
"install",
|
||||
"/nonexistent-path-xyz-794",
|
||||
],
|
||||
&[],
|
||||
);
|
||||
assert!(
|
||||
!output.status.success(),
|
||||
"plugins install not-found-path must exit non-zero (#794)"
|
||||
);
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
let j: serde_json::Value = stderr
|
||||
.lines()
|
||||
.find(|l| l.trim_start().starts_with('{'))
|
||||
.and_then(|l| serde_json::from_str(l).ok())
|
||||
.expect("plugins install not-found should emit JSON error envelope");
|
||||
assert_eq!(
|
||||
j["error_kind"], "plugin_source_not_found",
|
||||
"plugins install not-found should be plugin_source_not_found, got {:?}",
|
||||
j["error_kind"]
|
||||
);
|
||||
let h = j["hint"]
|
||||
.as_str()
|
||||
.expect("plugin_source_not_found must have non-null hint (#794)");
|
||||
assert!(!h.is_empty(), "hint must be non-empty");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user