fix: #145 仪表盘版本缓存 + #144 macOS手动安装检测 + #146 更新提示持久化 + #148 AI助手Web模式CORS

- dashboard.js: 版本/状态信息持久化缓存,实例切换时自动清空 (#145)
- service.rs: macOS is_cli_installed 改为真实路径探测,无plist时返回默认Gateway条目 (#144)
- utils.rs: 新增 common_non_windows_cli_candidates,resolve_openclaw_cli_path 优先检测 standalone/手动安装路径 (#144)
- config.rs: macOS get_local_version 增加 resolve_cli + canonicalize,detect_installed_source 增加 CLI 分类 + standalone 检测 (#144)
- dev-api.js: macOS CLI/版本/来源检测补齐 Intel Homebrew + standalone + findOpenclawBin (#144)
- main.js: 更新 banner dismiss 从 sessionStorage 改 localStorage (#146)
- assistant.js: Web 模式 AI 测试走后端代理 api.testModel 绕过 CORS (#148)
This commit is contained in:
晴天
2026-03-26 02:02:19 +08:00
parent 038e9c01bc
commit 7de40624f7
7 changed files with 159 additions and 16 deletions

View File

@@ -425,11 +425,30 @@ function buildGitInstallEnv() {
function detectInstalledSource() {
if (isMac) {
// ARM Homebrew
try {
const target = fs.readlinkSync('/opt/homebrew/bin/openclaw')
if (String(target).includes('openclaw-zh')) return 'chinese'
return 'official'
} catch {}
// Intel Homebrew
try {
const target = fs.readlinkSync('/usr/local/bin/openclaw')
if (String(target).includes('openclaw-zh')) return 'chinese'
return 'official'
} catch {}
// standalone (~/.openclaw-bin)
const saDir = path.join(homedir(), '.openclaw-bin')
if (fs.existsSync(path.join(saDir, 'openclaw')) || fs.existsSync(path.join(saDir, 'VERSION'))) return 'chinese'
if (fs.existsSync('/opt/openclaw/openclaw')) return 'chinese'
// findOpenclawBin fallback
const bin = findOpenclawBin()
if (bin) {
const lower = bin.replace(/\\/g, '/').toLowerCase()
if (lower.includes('openclaw-zh') || lower.includes('@qingchencloud') || lower.includes('/openclaw-bin/') || lower.includes('/opt/openclaw/')) return 'chinese'
return 'official'
}
return 'official'
}
if (isWindows) {
try {
@@ -452,11 +471,34 @@ function detectInstalledSource() {
function getLocalOpenclawVersion() {
let current = null
if (isMac) {
// ARM Homebrew
try {
const target = fs.readlinkSync('/opt/homebrew/bin/openclaw')
const pkgPath = path.resolve('/opt/homebrew/bin', target, '..', 'package.json')
current = JSON.parse(fs.readFileSync(pkgPath, 'utf8')).version
} catch {}
// Intel Homebrew
if (!current) {
try {
const target = fs.readlinkSync('/usr/local/bin/openclaw')
const pkgPath = path.resolve('/usr/local/bin', target, '..', 'package.json')
current = JSON.parse(fs.readFileSync(pkgPath, 'utf8')).version
} catch {}
}
// standalone (~/.openclaw-bin)
if (!current) {
try {
const vf = path.join(homedir(), '.openclaw-bin', 'VERSION')
if (fs.existsSync(vf)) {
const lines = fs.readFileSync(vf, 'utf8').split('\n')
for (const l of lines) { if (l.startsWith('openclaw_version=')) { current = l.split('=')[1]?.trim(); break } }
}
if (!current) {
const pkg = path.join(homedir(), '.openclaw-bin', 'node_modules', '@qingchencloud', 'openclaw-zh', 'package.json')
if (fs.existsSync(pkg)) current = JSON.parse(fs.readFileSync(pkg, 'utf8')).version
}
} catch {}
}
}
if (!current && isWindows) {
try {
@@ -1530,7 +1572,11 @@ const handlers = {
let cliInstalled = false
if (isMac) {
cliInstalled = fs.existsSync('/opt/homebrew/bin/openclaw') || fs.existsSync('/usr/local/bin/openclaw')
cliInstalled = fs.existsSync('/opt/homebrew/bin/openclaw')
|| fs.existsSync('/usr/local/bin/openclaw')
|| fs.existsSync(path.join(homedir(), '.openclaw-bin', 'openclaw'))
|| fs.existsSync('/opt/openclaw/openclaw')
|| !!findOpenclawBin()
} else if (isWindows) {
try {
const paths = [