Skip to content

Commit bbcdbc1

Browse files
authored
fix(cli-agent): Windows 启动时检测已安装 agent 不再弹出命令行窗口 (#216)
原先用 where/which 外部命令逐个检测 13 个 CLI agent 是否安装, Windows 上每次 spawn 都会短暂显示命令行窗口,启动时闪现十多次。 改为内联 PATH 搜索:Unix 直接迭代 PATH;Windows 追加 PATHEXT 动态读取后缀匹配。零进程零闪窗,且性能更快。
1 parent 645eb3b commit bbcdbc1

1 file changed

Lines changed: 25 additions & 16 deletions

File tree

app/src/terminal/cli_agent.rs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use std::borrow::Cow;
77
use std::collections::HashMap;
88
use std::path::Path;
9-
use std::process::Command;
109
use std::sync::{Arc, LazyLock, RwLock};
1110

1211
use ai::skills::SkillProvider;
@@ -600,29 +599,39 @@ impl CLIAgent {
600599

601600
/// 同步检测系统是否安装了此 agent。后台线程专用。
602601
fn is_installed_blocking(&self) -> bool {
603-
let check_cmd = |cmd: &str| -> bool {
604-
#[cfg(unix)]
605-
let (shell, arg) = ("which", cmd);
606-
#[cfg(windows)]
607-
let (shell, arg) = ("where", cmd);
608-
Command::new(shell)
609-
.arg(arg)
610-
.stdout(std::process::Stdio::null())
611-
.stderr(std::process::Stdio::null())
612-
.output()
613-
.is_ok_and(|o| o.status.success())
614-
};
615602
match self {
616603
CLIAgent::Unknown => false,
617604
// `agent` 太泛化,Cursor CLI 用 cursor-agent 检测
618-
CLIAgent::CursorCli => check_cmd("cursor-agent"),
605+
CLIAgent::CursorCli => is_on_path("cursor-agent"),
619606
// DeepSeek 同时检查主命令和别名
620-
CLIAgent::DeepSeek => check_cmd("deepseek") || check_cmd("deepseek-tui"),
621-
other => check_cmd(other.command_prefix()),
607+
CLIAgent::DeepSeek => is_on_path("deepseek") || is_on_path("deepseek-tui"),
608+
other => is_on_path(other.command_prefix()),
622609
}
623610
}
624611
}
625612

613+
/// 内联 PATH 搜索,零进程、零闪窗。
614+
#[cfg(unix)]
615+
fn is_on_path(cmd: &str) -> bool {
616+
let Ok(path_var) = std::env::var("PATH") else {
617+
return false;
618+
};
619+
std::env::split_paths(&path_var).any(|dir| dir.join(cmd).is_file())
620+
}
621+
622+
#[cfg(windows)]
623+
fn is_on_path(cmd: &str) -> bool {
624+
let pathext = std::env::var("PATHEXT").unwrap_or_else(|_| ".EXE;.CMD;.BAT".into());
625+
let Ok(path_var) = std::env::var("PATH") else {
626+
return false;
627+
};
628+
let exts: Vec<&str> = pathext.split(';').collect();
629+
std::env::split_paths(&path_var).any(|dir| {
630+
exts.iter()
631+
.any(|ext| dir.join(format!("{}{}", cmd, ext)).is_file())
632+
})
633+
}
634+
626635
#[cfg(test)]
627636
#[path = "cli_agent_tests.rs"]
628637
mod tests;

0 commit comments

Comments
 (0)