Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src-tauri/src/commands/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1891,6 +1891,23 @@ pub fn write_mcp_config(config: Value) -> Result<(), String> {
/// macOS: 优先从 npm 包的 package.json 读取(含完整后缀),fallback 到 CLI
/// Windows/Linux: 优先读文件系统,fallback 到 CLI
async fn get_local_version() -> Option<String> {
// 优先从运行中的 openclaw 实例获取版本(openclaw status --json → runtimeVersion)
// 避免多实例共存时读取到非活跃安装的版本
if let Ok(output) = crate::utils::openclaw_command_async()
.args(["status", "--json"])
.output()
.await
{
if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
if let Some(ver) = crate::commands::skills::extract_json_pub(&stdout)
.and_then(|v| v.get("runtimeVersion")?.as_str().map(String::from))
{
return Some(ver);
}
}
}

#[cfg(target_os = "macos")]
{
if let Some(cli_path) = crate::utils::resolve_openclaw_cli_path() {
Expand Down Expand Up @@ -2638,6 +2655,17 @@ fn read_version_from_installation(cli_path: &std::path::Path) -> Option<String>
}
}
}
// CLI 本体位于包目录中时(如 npm 全局安装:nvm、Homebrew 等),
// 直接读取同目录的 package.json(即该包自身的版本文件)
let own_pkg = dir.join("package.json");
if let Ok(content) = std::fs::read_to_string(&own_pkg) {
if let Some(ver) = serde_json::from_str::<serde_json::Value>(&content)
.ok()
.and_then(|v| v.get("version")?.as_str().map(String::from))
{
return Some(ver);
}
}
// 根据 CLI 路径判断来源,决定 package.json 检查顺序
// 避免残留的另一来源包被优先读取
let cli_source = crate::utils::classify_cli_source(&cli_path.to_string_lossy());
Expand Down
13 changes: 8 additions & 5 deletions src-tauri/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,8 @@ pub fn resolve_openclaw_cli_path() -> Option<String> {
}
#[cfg(not(target_os = "windows"))]
{
for candidate in common_non_windows_cli_candidates() {
if candidate.exists() {
return Some(candidate.to_string_lossy().to_string());
}
}
// 优先通过 enhanced_path 搜索:其中 nvm/volta 等版本管理器路径排在 Homebrew 前面,
// 与 `which openclaw` 的优先级一致,避免残留的 Homebrew 旧版本被优先检测到
let path = crate::commands::enhanced_path();
let sep = ':';
for dir in path.split(sep) {
Expand All @@ -123,6 +120,12 @@ pub fn resolve_openclaw_cli_path() -> Option<String> {
return Some(candidate.to_string_lossy().to_string());
}
}
// 兜底:检查 enhanced_path 可能未覆盖到的固定路径(如 GUI 环境 PATH 受限时)
for candidate in common_non_windows_cli_candidates() {
if candidate.exists() {
return Some(candidate.to_string_lossy().to_string());
}
}
None
}
}
Expand Down