fix: detect Windows npm ai agent shims

This commit is contained in:
lucaronin
2026-04-29 04:01:53 +02:00
parent ed52a9e800
commit f4790d5763
2 changed files with 110 additions and 2 deletions

View File

@@ -40,13 +40,21 @@ fn version_for_binary(binary: &PathBuf) -> Option<String> {
}
fn find_binary_on_path() -> Option<PathBuf> {
crate::hidden_command("which")
crate::hidden_command(path_lookup_command())
.arg("opencode")
.output()
.ok()
.and_then(|output| path_from_successful_output(&output))
}
fn path_lookup_command() -> &'static str {
if cfg!(windows) {
"where"
} else {
"which"
}
}
fn find_binary_in_user_shell() -> Option<PathBuf> {
user_shell_candidates()
.into_iter()
@@ -107,12 +115,26 @@ fn opencode_binary_candidates() -> Vec<PathBuf> {
fn opencode_binary_candidates_for_home(home: &Path) -> Vec<PathBuf> {
vec![
home.join(".local/bin/opencode"),
home.join(".local/bin/opencode.exe"),
home.join(".opencode/bin/opencode"),
home.join(".opencode/bin/opencode.exe"),
home.join(".local/share/mise/shims/opencode"),
home.join(".local/share/mise/shims/opencode.exe"),
home.join(".asdf/shims/opencode"),
home.join(".asdf/shims/opencode.exe"),
home.join(".npm-global/bin/opencode"),
home.join(".npm-global/bin/opencode.cmd"),
home.join(".npm-global/bin/opencode.exe"),
home.join(".npm/bin/opencode"),
home.join(".npm/bin/opencode.cmd"),
home.join(".npm/bin/opencode.exe"),
home.join(".bun/bin/opencode"),
home.join(".bun/bin/opencode.exe"),
home.join("AppData/Roaming/npm/opencode.cmd"),
home.join("AppData/Roaming/npm/opencode.exe"),
home.join("AppData/Local/pnpm/opencode.cmd"),
home.join("AppData/Local/pnpm/opencode.exe"),
home.join("scoop/shims/opencode.exe"),
PathBuf::from("/usr/local/bin/opencode"),
PathBuf::from("/opt/homebrew/bin/opencode"),
]
@@ -145,6 +167,38 @@ mod tests {
}
}
#[test]
fn binary_candidates_include_windows_npm_and_toolchain_shims() {
let home = PathBuf::from(r"C:\Users\alex");
let candidates = opencode_binary_candidates_for_home(&home);
let expected = [
home.join(".npm-global/bin/opencode.cmd"),
home.join(".npm-global/bin/opencode.exe"),
home.join(".npm/bin/opencode.cmd"),
home.join(".npm/bin/opencode.exe"),
home.join("AppData/Roaming/npm/opencode.cmd"),
home.join("AppData/Roaming/npm/opencode.exe"),
home.join("AppData/Local/pnpm/opencode.cmd"),
home.join("AppData/Local/pnpm/opencode.exe"),
home.join("scoop/shims/opencode.exe"),
];
for candidate in expected {
assert!(
candidates.contains(&candidate),
"missing {}",
candidate.display()
);
}
}
#[test]
fn path_lookup_command_matches_current_platform() {
let expected = if cfg!(windows) { "where" } else { "which" };
assert_eq!(path_lookup_command(), expected);
}
#[test]
fn first_existing_path_skips_empty_and_missing_lines() {
let dir = tempfile::tempdir().unwrap();