mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-07-15 09:21:32 +08:00
按全量代码审查(8 角度 × 对抗验证)修复 10 项确认问题并完成收口: 安全: - 媒体资产下载仅对与服务商 Base URL 同主机的地址携带 API Key,防止密钥外泄 - 助手媒体工具默认关闭需显式开启;付费图片/视频生成在任何模式下强制确认 数据与容错: - 媒体数据统一存放 openclaw 数据目录下,便携迁移后配置与历史直接生效 - 视频轮询 429/5xx 瞬时错误不再永久标记失败;失败任务可重新轮询找回 - 创建视频任务无法识别任务 ID 时保留任务记录与原始响应(可能已计费) - 便携迁移失败时正确显示错误状态;便携命令加入 Web 模式 ALWAYS_LOCAL 性能与体验: - 任务记录落盘前裁剪 base64 等超大字段,媒体历史文件不再膨胀 - 资产预览 stat 预检 + 64MB 上限 + 缓存淘汰;轮询并行化(后端 jobs 加锁) - 初始设置页两阶段渲染:本地检测先出首屏,版本网络查询异步补充 - 创作中心删除改用统一确认弹窗(原生 confirm 在 macOS WebView 失效) - 检查配置/获取模型列表放行 http:// 自建网关;桌面/Web 状态解析对齐 - 统一三处路径包含检查为 utils 共享 helper(Linux 大小写误判修复) - 补充便携模式 hermes-cli-missing 警告翻译(简/繁/英) 其他:修复 web-headless-reload-policy 陈旧断言(e16ff2b 后 ws-client 已无隐式 reload) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
147 lines
4.7 KiB
PowerShell
147 lines
4.7 KiB
PowerShell
param(
|
|
[string]$DriveLetter = "",
|
|
[string]$RootName = "ClawPanelPortable",
|
|
[switch]$Keep
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
function Find-FreeDriveLetter {
|
|
foreach ($letter in @("Z", "Y", "X", "W", "V", "U", "T", "S", "R", "Q", "P")) {
|
|
if (-not (Get-PSDrive -Name $letter -ErrorAction SilentlyContinue)) {
|
|
return $letter
|
|
}
|
|
}
|
|
throw "No free test drive letter found"
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($DriveLetter)) {
|
|
$DriveLetter = Find-FreeDriveLetter
|
|
}
|
|
$DriveLetter = $DriveLetter.Replace(':', '').ToUpperInvariant()
|
|
if (Get-PSDrive -Name $DriveLetter -ErrorAction SilentlyContinue) {
|
|
throw "Drive $DriveLetter already exists. Choose another DriveLetter."
|
|
}
|
|
|
|
$hostRoot = Join-Path $env:TEMP ("clawpanel-usb-smoke-" + [guid]::NewGuid().ToString("N"))
|
|
New-Item -ItemType Directory -Force -Path $hostRoot | Out-Null
|
|
|
|
try {
|
|
$driveName = $DriveLetter + ":"
|
|
$driveRoot = $DriveLetter + ":\"
|
|
subst $driveName $hostRoot
|
|
$usbRoot = Join-Path $driveRoot $RootName
|
|
$dataDir = Join-Path $usbRoot "data"
|
|
$panelDir = Join-Path $dataDir "clawpanel"
|
|
$openclawDir = Join-Path $dataDir "openclaw"
|
|
$hermesHome = Join-Path $dataDir "hermes"
|
|
$openclawEngine = Join-Path $usbRoot "engines\openclaw"
|
|
$hermesBin = Join-Path $usbRoot "engines\hermes\bin"
|
|
$uvBin = Join-Path $usbRoot "runtimes\uv\bin"
|
|
$gitCmd = Join-Path $usbRoot "runtimes\git\cmd"
|
|
|
|
foreach ($dir in @($panelDir, $openclawDir, $hermesHome, $openclawEngine, $hermesBin, $uvBin, $gitCmd)) {
|
|
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
}
|
|
|
|
@{
|
|
mode = "portable"
|
|
dataDir = "./data"
|
|
enginesDir = "./engines"
|
|
runtimesDir = "./runtimes"
|
|
} | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath (Join-Path $usbRoot "portable.json") -Encoding UTF8
|
|
|
|
@{
|
|
accessPassword = "portable-smoke"
|
|
engine = "openclaw"
|
|
} | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath (Join-Path $panelDir "clawpanel.json") -Encoding UTF8
|
|
|
|
'{ "gateway": { "port": 18789 }, "agents": { "main": { "name": "main" } } }' |
|
|
Set-Content -LiteralPath (Join-Path $openclawDir "openclaw.json") -Encoding UTF8
|
|
"model: smoke" | Set-Content -LiteralPath (Join-Path $hermesHome "config.yaml") -Encoding UTF8
|
|
|
|
@(
|
|
"@echo off",
|
|
"echo openclaw portable smoke"
|
|
) | Set-Content -LiteralPath (Join-Path $openclawEngine "openclaw.cmd") -Encoding ASCII
|
|
|
|
@(
|
|
"@echo off",
|
|
'if "%1"=="version" (',
|
|
" echo Hermes Agent v0.0.0-portable-smoke",
|
|
" exit /b 0",
|
|
")",
|
|
'if "%1"=="--version" (',
|
|
" echo Hermes Agent v0.0.0-portable-smoke",
|
|
" exit /b 0",
|
|
")",
|
|
'if "%1"=="gateway" (',
|
|
' if "%2"=="status" (',
|
|
" echo stopped",
|
|
" exit /b 0",
|
|
" )",
|
|
")",
|
|
"echo hermes portable smoke",
|
|
"exit /b 0"
|
|
) | Set-Content -LiteralPath (Join-Path $hermesBin "hermes.cmd") -Encoding ASCII
|
|
|
|
@(
|
|
"@echo off",
|
|
"echo uv 0.0.0-portable-smoke"
|
|
) | Set-Content -LiteralPath (Join-Path $uvBin "uv.cmd") -Encoding ASCII
|
|
|
|
@(
|
|
"@echo off",
|
|
"echo git version 0.0.0-portable-smoke"
|
|
) | Set-Content -LiteralPath (Join-Path $gitCmd "git.cmd") -Encoding ASCII
|
|
|
|
$oldPortableRoot = $env:CLAWPANEL_PORTABLE_ROOT
|
|
$oldHermesHome = $env:HERMES_HOME
|
|
$oldUvToolDir = $env:UV_TOOL_DIR
|
|
$oldUvToolBinDir = $env:UV_TOOL_BIN_DIR
|
|
$oldUvCacheDir = $env:UV_CACHE_DIR
|
|
$oldUvPythonInstallDir = $env:UV_PYTHON_INSTALL_DIR
|
|
$oldPath = $env:PATH
|
|
|
|
$env:CLAWPANEL_PORTABLE_ROOT = $usbRoot
|
|
$env:HERMES_HOME = $hermesHome
|
|
$env:UV_TOOL_DIR = Join-Path $usbRoot "engines\hermes"
|
|
$env:UV_TOOL_BIN_DIR = $hermesBin
|
|
$env:UV_CACHE_DIR = Join-Path $usbRoot "runtimes\uv\cache"
|
|
$env:UV_PYTHON_INSTALL_DIR = Join-Path $usbRoot "runtimes\uv\python"
|
|
$env:PATH = "$hermesBin;$openclawEngine;$uvBin;$gitCmd;$env:SystemRoot\System32"
|
|
|
|
try {
|
|
$hermesVersion = & hermes version
|
|
$openclawVersion = & openclaw
|
|
$gitVersion = & git --version
|
|
$uvVersion = & uv --version
|
|
} finally {
|
|
$env:CLAWPANEL_PORTABLE_ROOT = $oldPortableRoot
|
|
$env:HERMES_HOME = $oldHermesHome
|
|
$env:UV_TOOL_DIR = $oldUvToolDir
|
|
$env:UV_TOOL_BIN_DIR = $oldUvToolBinDir
|
|
$env:UV_CACHE_DIR = $oldUvCacheDir
|
|
$env:UV_PYTHON_INSTALL_DIR = $oldUvPythonInstallDir
|
|
$env:PATH = $oldPath
|
|
}
|
|
|
|
[pscustomobject]@{
|
|
ok = $true
|
|
drive = $driveName
|
|
usbRoot = $usbRoot
|
|
hostRoot = $hostRoot
|
|
hermes = ($hermesVersion -join "`n")
|
|
openclaw = ($openclawVersion -join "`n")
|
|
git = ($gitVersion -join "`n")
|
|
uv = ($uvVersion -join "`n")
|
|
} | ConvertTo-Json -Depth 4
|
|
} finally {
|
|
if (-not $Keep) {
|
|
subst $driveName /D 2>$null
|
|
Remove-Item -LiteralPath $hostRoot -Recurse -Force -ErrorAction SilentlyContinue
|
|
} else {
|
|
Write-Host "Keeping test drive $driveName -> $hostRoot"
|
|
}
|
|
}
|