使用rust which包来查找命令路径,解决部分电脑环境变量识别问题
This commit is contained in:
@@ -131,9 +131,13 @@ async fn build_agent(
|
||||
parts.push(format!("{k}={v}"));
|
||||
}
|
||||
parts.push(
|
||||
crate::process::normalized_program(cmd)
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
which::which(cmd)
|
||||
.map(|p| p.to_string_lossy().to_string())
|
||||
.unwrap_or_else(|_| {
|
||||
crate::process::normalized_program(cmd)
|
||||
.to_string_lossy()
|
||||
.to_string()
|
||||
}),
|
||||
);
|
||||
for a in args {
|
||||
parts.push((*a).into());
|
||||
|
||||
@@ -93,14 +93,24 @@ async fn check_npm_environment(node_required: Option<&str>) -> Vec<CheckItem> {
|
||||
return checks;
|
||||
}
|
||||
|
||||
// Run node and npm checks in parallel
|
||||
// Resolve absolute paths via `which` crate to avoid GUI PATH issues,
|
||||
// then run version checks in parallel.
|
||||
let node_path = which::which("node").ok();
|
||||
let npm_path = which::which("npm").ok();
|
||||
|
||||
let (node_result, npm_result) = tokio::join!(
|
||||
crate::process::tokio_command("node")
|
||||
.arg("--version")
|
||||
.output(),
|
||||
crate::process::tokio_command("npm")
|
||||
.arg("--version")
|
||||
.output(),
|
||||
async {
|
||||
match &node_path {
|
||||
Some(p) => crate::process::tokio_command(p).arg("--version").output().await,
|
||||
None => Err(std::io::Error::new(std::io::ErrorKind::NotFound, "node not found in PATH")),
|
||||
}
|
||||
},
|
||||
async {
|
||||
match &npm_path {
|
||||
Some(p) => crate::process::tokio_command(p).arg("--version").output().await,
|
||||
None => Err(std::io::Error::new(std::io::ErrorKind::NotFound, "npm not found in PATH")),
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Track the raw node version string for reuse in the version check
|
||||
|
||||
@@ -81,27 +81,15 @@ fn package_name_from_spec(package: &str) -> String {
|
||||
/// Check whether a command is available on the system PATH.
|
||||
/// Uses `which` on unix and `where` on windows — lightweight and does not
|
||||
/// invoke the target binary itself, avoiding side-effects or slow startups.
|
||||
async fn is_cmd_available(cmd: &str) -> bool {
|
||||
#[cfg(unix)]
|
||||
let check_cmd = "which";
|
||||
#[cfg(windows)]
|
||||
let check_cmd = "where";
|
||||
|
||||
crate::process::tokio_command(check_cmd)
|
||||
.arg(cmd)
|
||||
.stdout(std::process::Stdio::null())
|
||||
.stderr(std::process::Stdio::null())
|
||||
.status()
|
||||
.await
|
||||
.map(|s| s.success())
|
||||
.unwrap_or(false)
|
||||
fn is_cmd_available(cmd: &str) -> bool {
|
||||
which::which(cmd).is_ok()
|
||||
}
|
||||
|
||||
async fn detect_local_version(agent_type: AgentType) -> Option<String> {
|
||||
let meta = registry::get_agent_meta(agent_type);
|
||||
match meta.distribution {
|
||||
registry::AgentDistribution::Npx { cmd, package, .. } => {
|
||||
if is_cmd_available(cmd).await {
|
||||
if is_cmd_available(cmd) {
|
||||
version_from_package_spec(package)
|
||||
} else {
|
||||
None
|
||||
@@ -1047,7 +1035,7 @@ pub async fn acp_connect(
|
||||
}
|
||||
|
||||
if let registry::AgentDistribution::Npx { cmd, .. } = meta.distribution {
|
||||
if !is_cmd_available(cmd).await {
|
||||
if !is_cmd_available(cmd) {
|
||||
return Err(AcpError::protocol(format!(
|
||||
"{} SDK is not installed. Please install it in Agent Settings.",
|
||||
meta.name
|
||||
|
||||
Reference in New Issue
Block a user