From 515d325db76633896f527bbf91f17b484162f6e8 Mon Sep 17 00:00:00 2001 From: yanghang <2390375302@qq.com> Date: Tue, 16 Jun 2026 23:06:15 +0800 Subject: [PATCH 1/2] Add desktop release test materials --- desktop_release/CHECKLIST.md | 14 + desktop_release/TODO.md | 56 +++ desktop_release/apps/linux/.gitkeep | 0 desktop_release/apps/linux/README.md | 15 + desktop_release/apps/macos/.gitkeep | 0 desktop_release/apps/macos/README.md | 14 + desktop_release/apps/windows/.gitkeep | 0 desktop_release/apps/windows/README.md | 17 + .../scripts/linux/install_linux.sh | 6 + .../scripts/macos/install_macos.sh | 6 + desktop_release/scripts/windows/install.bat | 9 + .../scripts/windows/install_windows.ps1 | 336 ++++++++++++++++++ 12 files changed, 473 insertions(+) create mode 100644 desktop_release/CHECKLIST.md create mode 100644 desktop_release/TODO.md create mode 100644 desktop_release/apps/linux/.gitkeep create mode 100644 desktop_release/apps/linux/README.md create mode 100644 desktop_release/apps/macos/.gitkeep create mode 100644 desktop_release/apps/macos/README.md create mode 100644 desktop_release/apps/windows/.gitkeep create mode 100644 desktop_release/apps/windows/README.md create mode 100644 desktop_release/scripts/linux/install_linux.sh create mode 100644 desktop_release/scripts/macos/install_macos.sh create mode 100644 desktop_release/scripts/windows/install.bat create mode 100644 desktop_release/scripts/windows/install_windows.ps1 diff --git a/desktop_release/CHECKLIST.md b/desktop_release/CHECKLIST.md new file mode 100644 index 00000000..85a86971 --- /dev/null +++ b/desktop_release/CHECKLIST.md @@ -0,0 +1,14 @@ + +## 一、基础功能测试 + +例如秘钥配置 + +--- + +## 二、核心模块测试 + + +例子:在“指挥家”页发送:“请规划一个桌面版冒烟测试步骤清单,只输出 5 步以内,不要执行任何文件操作 + +--- + diff --git a/desktop_release/TODO.md b/desktop_release/TODO.md new file mode 100644 index 00000000..5dbd22c9 --- /dev/null +++ b/desktop_release/TODO.md @@ -0,0 +1,56 @@ +# GenericAgent Desktop 测试 TODO + +## 目标 + +本轮测试只关注两个结果: + +1. 当前系统能产出可用的环境配置脚本和桌面程序壳。 +2. 在干净环境/干净仓库中,测试员可以用脚本完成环境配置,并成功运行这个程序壳。 + +不要求测试员填写复杂过程;只要证明结果可复现,并记录失败原因即可。 + +--- + +## 系统覆盖 + +重点测试 Windows 和 Linux;macOS 由项目负责人自测。 + +| 优先级 | 系统 | 架构/版本 | 测试员 | 状态 | 备注 | +|---|---|---|---|---|---| +| P0 | Windows 11 | x64 | 无 | 开发过程中已测试 | 当前最优先 Windows 环境 | +| P0 | Windows 10 | x64 | 杨航 | TODO | 常见 Windows 环境 | +| P0 | Ubuntu 24.04 LTS | x64 | 张景铭 | TODO | 当前常见 Linux LTS | +| P0 | Ubuntu 22.04 LTS | x64 | 张景铭 | TODO | 仍然常见的 Linux LTS | +| P1 | Debian 12 | x64 | 曹兮 | TODO | 可选,覆盖 Debian 系 | +| Owner | macOS | Apple Silicon 或 Intel | 杨航 | TODO | | + + +--- + +## 每个系统需要完成的任务 + +### 任务 1:生成脚本和程序壳 + +测试员需要在自己的系统上产出: + +- 对应系统的环境配置脚本; +- 对应系统的桌面程序壳(可执行程序)。 + +脚本实现可以直接参考 Windows 版本:`release/scripts/windows/install_windows.ps1`。核心做法是由脚本准备运行环境,并写入用户级桌面配置(如 `~/.ga_desktop_settings.json`),让程序壳能找到 `project_dir`、`python_path` 和 bridge 脚本。 + + + +### 任务 2:干净环境验证通过 + +从干净仓库或尽量干净的测试目录开始,验证: + +- 环境配置脚本可以成功运行; +- 脚本能把运行桌面版需要的环境准备好; +- 从 `frontends/` 标准位置启动程序壳可以正常打开; +- 程序壳能连上本地 bridge/后端; + +如果方便,建议用全新 clone 再走一遍; + +### 任务 3:根据 CHECKLIST 测一下在不同平台下的界面使用兼容性 + +--- diff --git a/desktop_release/apps/linux/.gitkeep b/desktop_release/apps/linux/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/desktop_release/apps/linux/README.md b/desktop_release/apps/linux/README.md new file mode 100644 index 00000000..ed15b6d0 --- /dev/null +++ b/desktop_release/apps/linux/README.md @@ -0,0 +1,15 @@ +# Linux 桌面壳 + +真实二进制壳不直接提交到 Git 仓库。 + +测试时请从项目 Release/内部发布位置下载 Linux 版本壳,并放到本目录。 + +常见形式可能是: + +```text +GenericAgent.AppImage +genericagent.deb +genericagent.rpm +``` + +具体文件名以后续发布说明为准。 \ No newline at end of file diff --git a/desktop_release/apps/macos/.gitkeep b/desktop_release/apps/macos/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/desktop_release/apps/macos/README.md b/desktop_release/apps/macos/README.md new file mode 100644 index 00000000..1a97280b --- /dev/null +++ b/desktop_release/apps/macos/README.md @@ -0,0 +1,14 @@ +# macOS 桌面壳 + +真实二进制壳不直接提交到 Git 仓库。 + +测试时请从项目 Release/内部发布位置下载 macOS 版本壳,并放到本目录。 + +常见形式可能是: + +```text +GenericAgent.app +GenericAgent.dmg +``` + +具体文件名以后续发布说明为准。 \ No newline at end of file diff --git a/desktop_release/apps/windows/.gitkeep b/desktop_release/apps/windows/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/desktop_release/apps/windows/README.md b/desktop_release/apps/windows/README.md new file mode 100644 index 00000000..f8517006 --- /dev/null +++ b/desktop_release/apps/windows/README.md @@ -0,0 +1,17 @@ +# Windows 桌面壳 + +真实二进制壳不直接提交到 Git 仓库。 + +测试时请从项目 Release/内部发布位置下载 Windows 版本壳,并放到本目录,例如: + +```text +release/apps/windows/ga-desktop.exe +``` + +然后先运行: + +```text +release/scripts/windows/install.bat +``` + +脚本完成后再启动桌面壳。 \ No newline at end of file diff --git a/desktop_release/scripts/linux/install_linux.sh b/desktop_release/scripts/linux/install_linux.sh new file mode 100644 index 00000000..b55dcc1c --- /dev/null +++ b/desktop_release/scripts/linux/install_linux.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -euo pipefail + +echo "TODO: implement Linux environment setup script." +echo "Expected future usage: ./install_linux.sh --project-dir /path/to/GenericAgent_Desktop --mode prepare-only" +exit 2 \ No newline at end of file diff --git a/desktop_release/scripts/macos/install_macos.sh b/desktop_release/scripts/macos/install_macos.sh new file mode 100644 index 00000000..0dea10b2 --- /dev/null +++ b/desktop_release/scripts/macos/install_macos.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -euo pipefail + +echo "TODO: implement macOS environment setup script." +echo "Expected future usage: ./install_macos.sh --project-dir /path/to/GenericAgent_Desktop --mode prepare-only" +exit 2 \ No newline at end of file diff --git a/desktop_release/scripts/windows/install.bat b/desktop_release/scripts/windows/install.bat new file mode 100644 index 00000000..8ff061fc --- /dev/null +++ b/desktop_release/scripts/windows/install.bat @@ -0,0 +1,9 @@ +@echo off +setlocal +cd /d "%~dp0" +set "SCRIPT_DIR=%~dp0" +for %%I in ("%SCRIPT_DIR%..\..\..") do set "PROJECT_DIR=%%~fI" +powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%SCRIPT_DIR%install_windows.ps1" -ProjectDir "%PROJECT_DIR%" -Mode PrepareOnly -SkipNpmInstall %* +echo. +echo If the installer failed, copy the error above and send it to the developer. +pause \ No newline at end of file diff --git a/desktop_release/scripts/windows/install_windows.ps1 b/desktop_release/scripts/windows/install_windows.ps1 new file mode 100644 index 00000000..2677a0a8 --- /dev/null +++ b/desktop_release/scripts/windows/install_windows.ps1 @@ -0,0 +1,336 @@ +<# +GenericAgent Desktop Windows setup script + +Usage examples: + powershell -ExecutionPolicy Bypass -File .\install_windows.ps1 + powershell -ExecutionPolicy Bypass -File .\install_windows.ps1 -ProjectDir D:\GenericAgent_Desktop -Mode PrepareOnly + powershell -ExecutionPolicy Bypass -File .\install_windows.ps1 -Mode BridgeOnly + powershell -ExecutionPolicy Bypass -File .\install_windows.ps1 -Mode NpmInstallOnly + powershell -ExecutionPolicy Bypass -File .\install_windows.ps1 -Mode DesktopBuildOnly + powershell -ExecutionPolicy Bypass -File .\install_windows.ps1 -Mode DesktopDevOnly + +What this script does: + 1. Locate GenericAgent project dir, which must contain agentmain.py. + 2. Locate a supported Python, or create/use .venv. + 3. Install minimal Python dependencies for desktop bridge. + 4. Copy mykey_template.py to mykey.py if mykey.py is missing. + 5. Write %USERPROFILE%\.ga_desktop_settings.json for the Tauri shell. + 6. Optionally install npm/Tauri dependencies, build debug desktop exe, or start bridge/exe. + +Important: + - This script lives under test_workspace and is still a draft, but these modes have been smoke-tested here: + PrepareOnly, BridgeOnly/manual bridge smoke, NpmInstallOnly, DesktopBuildOnly, and debug exe GUI autostart. + - Development install and packaged-user install are not exactly the same. + Shared part: Python/env/deps/config preparation. + Different part: where files live, whether exe exists, whether Python is bundled. +#> + +param( + [string]$ProjectDir = "", + [string]$PythonPath = "", + [ValidateSet("Auto", "PrepareOnly", "BridgeOnly", "ExeOnly", "NpmInstallOnly", "DesktopDevOnly", "DesktopBuildOnly")] + [string]$Mode = "Auto", + [switch]$NoVenv, + [switch]$SkipPipInstall, + [switch]$SkipNpmInstall, + [switch]$SkipWebView2Check +) + +$ErrorActionPreference = "Stop" + +function Write-Step([string]$msg) { Write-Host "`n==> $msg" -ForegroundColor Cyan } +function Write-Ok([string]$msg) { Write-Host "[OK] $msg" -ForegroundColor Green } +function Write-Warn([string]$msg) { Write-Host "[WARN] $msg" -ForegroundColor Yellow } +function Fail([string]$msg) { throw "[ERROR] $msg" } + +function Resolve-ScriptRoot { + if ($PSScriptRoot) { return (Resolve-Path $PSScriptRoot).Path } + return (Get-Location).Path +} + +function Find-ProjectRoot([string]$startDir) { + if ($ProjectDir) { + $p = Resolve-Path $ProjectDir -ErrorAction Stop + if (Test-Path (Join-Path $p "agentmain.py")) { return $p.Path } + Fail "ProjectDir does not contain agentmain.py: $ProjectDir" + } + + $candidates = @( + (Get-Location).Path, + $startDir, + (Join-Path $startDir ".."), + (Join-Path $startDir "..\.."), + (Join-Path $startDir "..\..\.."), + "D:\GenericAgent_Desktop" + ) + + foreach ($c in $candidates) { + try { $rp = Resolve-Path $c -ErrorAction Stop } catch { continue } + if (Test-Path (Join-Path $rp.Path "agentmain.py")) { return $rp.Path } + } + Fail "Cannot locate GenericAgent project root. Pass -ProjectDir ." +} + +function Get-PythonVersionObject([string]$py) { + try { + $out = & $py -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')" 2>$null + if ($LASTEXITCODE -ne 0 -or -not $out) { return $null } + return [version]($out.Trim()) + } catch { return $null } +} + +function Test-SupportedPython([string]$py) { + $v = Get-PythonVersionObject $py + if (-not $v) { return $false } + return ($v.Major -eq 3 -and $v.Minor -ge 10 -and $v.Minor -lt 14) +} + +function Find-Python([string]$root) { + if ($PythonPath) { + if (Test-SupportedPython $PythonPath) { return (Resolve-Path $PythonPath).Path } + Fail "Specified Python is not supported. Need Python >=3.10,<3.14: $PythonPath" + } + + $portableCandidates = @( + (Join-Path $root ".portable\uv-python\python.exe"), + (Join-Path $root ".portable\python\python.exe"), + (Join-Path $root "python\python.exe") + ) + foreach ($p in $portableCandidates) { + if ((Test-Path $p) -and (Test-SupportedPython $p)) { return (Resolve-Path $p).Path } + } + + $cmds = @("python", "py") + foreach ($cmd in $cmds) { + try { + if ($cmd -eq "py") { + $probe = & py -3.12 -c "import sys; print(sys.executable)" 2>$null + if ($LASTEXITCODE -eq 0 -and $probe -and (Test-SupportedPython $probe.Trim())) { return $probe.Trim() } + $probe = & py -3.11 -c "import sys; print(sys.executable)" 2>$null + if ($LASTEXITCODE -eq 0 -and $probe -and (Test-SupportedPython $probe.Trim())) { return $probe.Trim() } + $probe = & py -3.10 -c "import sys; print(sys.executable)" 2>$null + if ($LASTEXITCODE -eq 0 -and $probe -and (Test-SupportedPython $probe.Trim())) { return $probe.Trim() } + } else { + $probe = & python -c "import sys; print(sys.executable)" 2>$null + if ($LASTEXITCODE -eq 0 -and $probe -and (Test-SupportedPython $probe.Trim())) { return $probe.Trim() } + } + } catch { } + } + + Fail "No supported Python found. Install Python 3.10-3.13, or pass -PythonPath." +} + +function Ensure-Venv([string]$root, [string]$basePython) { + if ($NoVenv) { return $basePython } + $venvDir = Join-Path $root ".venv" + $venvPy = Join-Path $venvDir "Scripts\python.exe" + if (-not (Test-Path $venvPy)) { + Write-Step "Create virtual environment: $venvDir" + & $basePython -m venv $venvDir + if ($LASTEXITCODE -ne 0) { Fail "Failed to create venv." } + } + if (-not (Test-SupportedPython $venvPy)) { Fail "Venv Python is invalid: $venvPy" } + return (Resolve-Path $venvPy).Path +} + +function Install-Dependencies([string]$root, [string]$py) { + if ($SkipPipInstall) { Write-Warn "SkipPipInstall is set; dependencies are not installed."; return } + Write-Step "Upgrade pip" + & $py -m pip install --upgrade pip + if ($LASTEXITCODE -ne 0) { Fail "pip upgrade failed." } + + Write-Step "Install GenericAgent minimal package and desktop bridge extras" + # pyproject.toml already includes: requests, beautifulsoup4, bottle, simple-websocket-server, aiohttp. + # desktop_bridge.py additionally imports psutil. + & $py -m pip install -e $root psutil + if ($LASTEXITCODE -ne 0) { Fail "pip install failed." } +} + +function Ensure-MyKey([string]$root) { + $mykey = Join-Path $root "mykey.py" + $tpl = Join-Path $root "mykey_template.py" + if (Test-Path $mykey) { + Write-Ok "mykey.py exists" + return + } + if (Test-Path $tpl) { + Copy-Item $tpl $mykey + Write-Warn "Created mykey.py from mykey_template.py. User still needs to fill API keys." + } else { + Write-Warn "mykey.py and mykey_template.py are missing. Model config may not work." + } +} + +function Write-DesktopSettings([string]$root, [string]$py) { + $settingsPath = Join-Path $env:USERPROFILE ".ga_desktop_settings.json" + $obj = [ordered]@{ + python_path = $py + project_dir = $root + bridge_script = (Join-Path $root "frontends\desktop_bridge.py") + } + $json = $obj | ConvertTo-Json -Depth 5 + # PowerShell 5.1 `Set-Content -Encoding UTF8` writes a UTF-8 BOM. + # Rust serde_json does not accept BOM at the beginning, causing the Tauri shell + # to ignore this settings file and auto-discover the wrong project directory. + $utf8NoBom = New-Object System.Text.UTF8Encoding($false) + [System.IO.File]::WriteAllText($settingsPath, $json, $utf8NoBom) + Write-Ok "Wrote desktop settings: $settingsPath" +} + +function Test-WebView2Installed { + if ($SkipWebView2Check) { return } + Write-Step "Check Microsoft Edge WebView2 Runtime" + $keys = @( + "HKLM:\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}", + "HKLM:\SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}", + "HKCU:\SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" + ) + foreach ($k in $keys) { + if (Test-Path $k) { Write-Ok "WebView2 Runtime detected"; return } + } + Write-Warn "WebView2 Runtime not detected. Tauri desktop window may fail on clean Windows." + Write-Warn "Download: https://developer.microsoft.com/microsoft-edge/webview2/" +} + +function Find-DesktopDir([string]$root) { + $desktop = Join-Path $root "frontends\desktop" + if (-not (Test-Path (Join-Path $desktop "src-tauri\tauri.conf.json"))) { + Fail "Tauri desktop dir not found: $desktop" + } + return (Resolve-Path $desktop).Path +} + +function Ensure-NodeAndNpm { + $node = Get-Command node -ErrorAction SilentlyContinue + $npm = Get-Command npm -ErrorAction SilentlyContinue + if (-not $node) { Fail "node is not available in PATH. Install Node.js 20+ for desktop dev/build." } + if (-not $npm) { Fail "npm is not available in PATH. Install Node.js/npm for desktop dev/build." } + $nodeVer = & node --version + $npmVer = & cmd /c npm --version + Write-Ok "Node: $nodeVer; npm: $npmVer" +} + +function Install-DesktopNpm([string]$root) { + if ($SkipNpmInstall) { Write-Warn "SkipNpmInstall is set; desktop npm dependencies are not installed."; return } + $desktop = Find-DesktopDir $root + Ensure-NodeAndNpm + Write-Step "Install Tauri desktop npm dependencies: $desktop" + Push-Location $desktop + try { + & cmd /c npm install + if ($LASTEXITCODE -ne 0) { Fail "npm install failed in $desktop" } + & cmd /c npx tauri --version + if ($LASTEXITCODE -ne 0) { Fail "npx tauri --version failed after npm install" } + } finally { + Pop-Location + } +} + +function Build-DesktopDebug([string]$root) { + $desktop = Find-DesktopDir $root + Install-DesktopNpm $root + Write-Step "Build Tauri debug desktop exe" + Push-Location $desktop + try { + & cmd /c npx tauri build --debug + if ($LASTEXITCODE -ne 0) { Fail "Tauri debug build failed." } + } finally { + Pop-Location + } + $debugExe = Join-Path $desktop "src-tauri\target\debug\ga-desktop.exe" + if (Test-Path $debugExe) { Write-Ok "Debug exe: $debugExe" } else { Write-Warn "Debug exe not found at expected path: $debugExe" } +} + +function Start-DesktopDev([string]$root) { + $desktop = Find-DesktopDir $root + Install-DesktopNpm $root + Write-Step "Start Tauri desktop dev shell" + Write-Warn "This keeps running in current console. If status checks fail, bypass proxy for http://127.0.0.1:14168/status." + Push-Location $desktop + try { + & cmd /c npx tauri dev -- --dev + } finally { + Pop-Location + } +} + +function Find-PackagedExe([string]$root) { + $candidates = @( + (Join-Path $root "frontends\GenericAgent.exe"), + (Join-Path $root "frontends\desktop\src-tauri\target\release\GenericAgent.exe"), + (Join-Path $root "frontends\desktop\src-tauri\target\release\ga-desktop.exe"), + (Join-Path $root "frontends\desktop\src-tauri\target\debug\ga-desktop.exe") + ) + foreach ($p in $candidates) { if (Test-Path $p) { return (Resolve-Path $p).Path } } + return "" +} + +function Start-Bridge([string]$root, [string]$py) { + $bridge = Join-Path $root "frontends\desktop_bridge.py" + if (-not (Test-Path $bridge)) { Fail "desktop_bridge.py not found: $bridge" } + Write-Step "Start bridge: $bridge" + Write-Warn "This keeps running in current console. Browse http://127.0.0.1:14168/status to check." + $env:PYTHONPATH = "$root;$(Join-Path $root 'frontends');$env:PYTHONPATH" + & $py $bridge +} + +function Start-Exe([string]$root) { + $exe = Find-PackagedExe $root + if (-not $exe) { Fail "Packaged GenericAgent.exe not found. Use -Mode BridgeOnly or build Tauri first." } + Write-Step "Start packaged desktop exe" + Start-Process -FilePath $exe -WorkingDirectory (Split-Path $exe -Parent) + Write-Ok "Started: $exe" +} + +Write-Step "Resolve project root" +$scriptRoot = Resolve-ScriptRoot +$root = Find-ProjectRoot $scriptRoot +Write-Ok "Project root: $root" + +Write-Step "Resolve Python" +$basePy = Find-Python $root +Write-Ok "Base Python: $basePy" + +$py = Ensure-Venv $root $basePy +Write-Ok "Runtime Python: $py" + +Install-Dependencies $root $py +Ensure-MyKey $root +Write-DesktopSettings $root $py +Test-WebView2Installed + +if ($Mode -eq "PrepareOnly") { + Write-Ok "Preparation finished. No app started because -Mode PrepareOnly was used." + exit 0 +} + +if ($Mode -eq "BridgeOnly") { + Start-Bridge $root $py + exit 0 +} + +if ($Mode -eq "NpmInstallOnly") { + Install-DesktopNpm $root + Write-Ok "Desktop npm setup finished." + exit 0 +} + +if ($Mode -eq "DesktopBuildOnly") { + Build-DesktopDebug $root + Write-Ok "Desktop debug build finished." + exit 0 +} + +if ($Mode -eq "DesktopDevOnly") { + Start-DesktopDev $root + exit 0 +} + +if ($Mode -eq "ExeOnly") { + Start-Exe $root + exit 0 +} + +# Auto mode: prefer packaged exe if present, otherwise start bridge for source/dev tree. +$exe = Find-PackagedExe $root +if ($exe) { Start-Exe $root } else { Start-Bridge $root $py } From 1a78bc6237594faef09f3c6a9abfc2ef6bad0381 Mon Sep 17 00:00:00 2001 From: yanghang <2390375302@qq.com> Date: Tue, 16 Jun 2026 23:10:33 +0800 Subject: [PATCH 2/2] Revert "Add desktop release test materials" This reverts commit 82442ce9df0a27839473409167074a8d81137356. --- desktop_release/CHECKLIST.md | 14 - desktop_release/TODO.md | 56 --- desktop_release/apps/linux/.gitkeep | 0 desktop_release/apps/linux/README.md | 15 - desktop_release/apps/macos/.gitkeep | 0 desktop_release/apps/macos/README.md | 14 - desktop_release/apps/windows/.gitkeep | 0 desktop_release/apps/windows/README.md | 17 - .../scripts/linux/install_linux.sh | 6 - .../scripts/macos/install_macos.sh | 6 - desktop_release/scripts/windows/install.bat | 9 - .../scripts/windows/install_windows.ps1 | 336 ------------------ 12 files changed, 473 deletions(-) delete mode 100644 desktop_release/CHECKLIST.md delete mode 100644 desktop_release/TODO.md delete mode 100644 desktop_release/apps/linux/.gitkeep delete mode 100644 desktop_release/apps/linux/README.md delete mode 100644 desktop_release/apps/macos/.gitkeep delete mode 100644 desktop_release/apps/macos/README.md delete mode 100644 desktop_release/apps/windows/.gitkeep delete mode 100644 desktop_release/apps/windows/README.md delete mode 100644 desktop_release/scripts/linux/install_linux.sh delete mode 100644 desktop_release/scripts/macos/install_macos.sh delete mode 100644 desktop_release/scripts/windows/install.bat delete mode 100644 desktop_release/scripts/windows/install_windows.ps1 diff --git a/desktop_release/CHECKLIST.md b/desktop_release/CHECKLIST.md deleted file mode 100644 index 85a86971..00000000 --- a/desktop_release/CHECKLIST.md +++ /dev/null @@ -1,14 +0,0 @@ - -## 一、基础功能测试 - -例如秘钥配置 - ---- - -## 二、核心模块测试 - - -例子:在“指挥家”页发送:“请规划一个桌面版冒烟测试步骤清单,只输出 5 步以内,不要执行任何文件操作 - ---- - diff --git a/desktop_release/TODO.md b/desktop_release/TODO.md deleted file mode 100644 index 5dbd22c9..00000000 --- a/desktop_release/TODO.md +++ /dev/null @@ -1,56 +0,0 @@ -# GenericAgent Desktop 测试 TODO - -## 目标 - -本轮测试只关注两个结果: - -1. 当前系统能产出可用的环境配置脚本和桌面程序壳。 -2. 在干净环境/干净仓库中,测试员可以用脚本完成环境配置,并成功运行这个程序壳。 - -不要求测试员填写复杂过程;只要证明结果可复现,并记录失败原因即可。 - ---- - -## 系统覆盖 - -重点测试 Windows 和 Linux;macOS 由项目负责人自测。 - -| 优先级 | 系统 | 架构/版本 | 测试员 | 状态 | 备注 | -|---|---|---|---|---|---| -| P0 | Windows 11 | x64 | 无 | 开发过程中已测试 | 当前最优先 Windows 环境 | -| P0 | Windows 10 | x64 | 杨航 | TODO | 常见 Windows 环境 | -| P0 | Ubuntu 24.04 LTS | x64 | 张景铭 | TODO | 当前常见 Linux LTS | -| P0 | Ubuntu 22.04 LTS | x64 | 张景铭 | TODO | 仍然常见的 Linux LTS | -| P1 | Debian 12 | x64 | 曹兮 | TODO | 可选,覆盖 Debian 系 | -| Owner | macOS | Apple Silicon 或 Intel | 杨航 | TODO | | - - ---- - -## 每个系统需要完成的任务 - -### 任务 1:生成脚本和程序壳 - -测试员需要在自己的系统上产出: - -- 对应系统的环境配置脚本; -- 对应系统的桌面程序壳(可执行程序)。 - -脚本实现可以直接参考 Windows 版本:`release/scripts/windows/install_windows.ps1`。核心做法是由脚本准备运行环境,并写入用户级桌面配置(如 `~/.ga_desktop_settings.json`),让程序壳能找到 `project_dir`、`python_path` 和 bridge 脚本。 - - - -### 任务 2:干净环境验证通过 - -从干净仓库或尽量干净的测试目录开始,验证: - -- 环境配置脚本可以成功运行; -- 脚本能把运行桌面版需要的环境准备好; -- 从 `frontends/` 标准位置启动程序壳可以正常打开; -- 程序壳能连上本地 bridge/后端; - -如果方便,建议用全新 clone 再走一遍; - -### 任务 3:根据 CHECKLIST 测一下在不同平台下的界面使用兼容性 - ---- diff --git a/desktop_release/apps/linux/.gitkeep b/desktop_release/apps/linux/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/desktop_release/apps/linux/README.md b/desktop_release/apps/linux/README.md deleted file mode 100644 index ed15b6d0..00000000 --- a/desktop_release/apps/linux/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Linux 桌面壳 - -真实二进制壳不直接提交到 Git 仓库。 - -测试时请从项目 Release/内部发布位置下载 Linux 版本壳,并放到本目录。 - -常见形式可能是: - -```text -GenericAgent.AppImage -genericagent.deb -genericagent.rpm -``` - -具体文件名以后续发布说明为准。 \ No newline at end of file diff --git a/desktop_release/apps/macos/.gitkeep b/desktop_release/apps/macos/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/desktop_release/apps/macos/README.md b/desktop_release/apps/macos/README.md deleted file mode 100644 index 1a97280b..00000000 --- a/desktop_release/apps/macos/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# macOS 桌面壳 - -真实二进制壳不直接提交到 Git 仓库。 - -测试时请从项目 Release/内部发布位置下载 macOS 版本壳,并放到本目录。 - -常见形式可能是: - -```text -GenericAgent.app -GenericAgent.dmg -``` - -具体文件名以后续发布说明为准。 \ No newline at end of file diff --git a/desktop_release/apps/windows/.gitkeep b/desktop_release/apps/windows/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/desktop_release/apps/windows/README.md b/desktop_release/apps/windows/README.md deleted file mode 100644 index f8517006..00000000 --- a/desktop_release/apps/windows/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Windows 桌面壳 - -真实二进制壳不直接提交到 Git 仓库。 - -测试时请从项目 Release/内部发布位置下载 Windows 版本壳,并放到本目录,例如: - -```text -release/apps/windows/ga-desktop.exe -``` - -然后先运行: - -```text -release/scripts/windows/install.bat -``` - -脚本完成后再启动桌面壳。 \ No newline at end of file diff --git a/desktop_release/scripts/linux/install_linux.sh b/desktop_release/scripts/linux/install_linux.sh deleted file mode 100644 index b55dcc1c..00000000 --- a/desktop_release/scripts/linux/install_linux.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -echo "TODO: implement Linux environment setup script." -echo "Expected future usage: ./install_linux.sh --project-dir /path/to/GenericAgent_Desktop --mode prepare-only" -exit 2 \ No newline at end of file diff --git a/desktop_release/scripts/macos/install_macos.sh b/desktop_release/scripts/macos/install_macos.sh deleted file mode 100644 index 0dea10b2..00000000 --- a/desktop_release/scripts/macos/install_macos.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -echo "TODO: implement macOS environment setup script." -echo "Expected future usage: ./install_macos.sh --project-dir /path/to/GenericAgent_Desktop --mode prepare-only" -exit 2 \ No newline at end of file diff --git a/desktop_release/scripts/windows/install.bat b/desktop_release/scripts/windows/install.bat deleted file mode 100644 index 8ff061fc..00000000 --- a/desktop_release/scripts/windows/install.bat +++ /dev/null @@ -1,9 +0,0 @@ -@echo off -setlocal -cd /d "%~dp0" -set "SCRIPT_DIR=%~dp0" -for %%I in ("%SCRIPT_DIR%..\..\..") do set "PROJECT_DIR=%%~fI" -powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%SCRIPT_DIR%install_windows.ps1" -ProjectDir "%PROJECT_DIR%" -Mode PrepareOnly -SkipNpmInstall %* -echo. -echo If the installer failed, copy the error above and send it to the developer. -pause \ No newline at end of file diff --git a/desktop_release/scripts/windows/install_windows.ps1 b/desktop_release/scripts/windows/install_windows.ps1 deleted file mode 100644 index 2677a0a8..00000000 --- a/desktop_release/scripts/windows/install_windows.ps1 +++ /dev/null @@ -1,336 +0,0 @@ -<# -GenericAgent Desktop Windows setup script - -Usage examples: - powershell -ExecutionPolicy Bypass -File .\install_windows.ps1 - powershell -ExecutionPolicy Bypass -File .\install_windows.ps1 -ProjectDir D:\GenericAgent_Desktop -Mode PrepareOnly - powershell -ExecutionPolicy Bypass -File .\install_windows.ps1 -Mode BridgeOnly - powershell -ExecutionPolicy Bypass -File .\install_windows.ps1 -Mode NpmInstallOnly - powershell -ExecutionPolicy Bypass -File .\install_windows.ps1 -Mode DesktopBuildOnly - powershell -ExecutionPolicy Bypass -File .\install_windows.ps1 -Mode DesktopDevOnly - -What this script does: - 1. Locate GenericAgent project dir, which must contain agentmain.py. - 2. Locate a supported Python, or create/use .venv. - 3. Install minimal Python dependencies for desktop bridge. - 4. Copy mykey_template.py to mykey.py if mykey.py is missing. - 5. Write %USERPROFILE%\.ga_desktop_settings.json for the Tauri shell. - 6. Optionally install npm/Tauri dependencies, build debug desktop exe, or start bridge/exe. - -Important: - - This script lives under test_workspace and is still a draft, but these modes have been smoke-tested here: - PrepareOnly, BridgeOnly/manual bridge smoke, NpmInstallOnly, DesktopBuildOnly, and debug exe GUI autostart. - - Development install and packaged-user install are not exactly the same. - Shared part: Python/env/deps/config preparation. - Different part: where files live, whether exe exists, whether Python is bundled. -#> - -param( - [string]$ProjectDir = "", - [string]$PythonPath = "", - [ValidateSet("Auto", "PrepareOnly", "BridgeOnly", "ExeOnly", "NpmInstallOnly", "DesktopDevOnly", "DesktopBuildOnly")] - [string]$Mode = "Auto", - [switch]$NoVenv, - [switch]$SkipPipInstall, - [switch]$SkipNpmInstall, - [switch]$SkipWebView2Check -) - -$ErrorActionPreference = "Stop" - -function Write-Step([string]$msg) { Write-Host "`n==> $msg" -ForegroundColor Cyan } -function Write-Ok([string]$msg) { Write-Host "[OK] $msg" -ForegroundColor Green } -function Write-Warn([string]$msg) { Write-Host "[WARN] $msg" -ForegroundColor Yellow } -function Fail([string]$msg) { throw "[ERROR] $msg" } - -function Resolve-ScriptRoot { - if ($PSScriptRoot) { return (Resolve-Path $PSScriptRoot).Path } - return (Get-Location).Path -} - -function Find-ProjectRoot([string]$startDir) { - if ($ProjectDir) { - $p = Resolve-Path $ProjectDir -ErrorAction Stop - if (Test-Path (Join-Path $p "agentmain.py")) { return $p.Path } - Fail "ProjectDir does not contain agentmain.py: $ProjectDir" - } - - $candidates = @( - (Get-Location).Path, - $startDir, - (Join-Path $startDir ".."), - (Join-Path $startDir "..\.."), - (Join-Path $startDir "..\..\.."), - "D:\GenericAgent_Desktop" - ) - - foreach ($c in $candidates) { - try { $rp = Resolve-Path $c -ErrorAction Stop } catch { continue } - if (Test-Path (Join-Path $rp.Path "agentmain.py")) { return $rp.Path } - } - Fail "Cannot locate GenericAgent project root. Pass -ProjectDir ." -} - -function Get-PythonVersionObject([string]$py) { - try { - $out = & $py -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')" 2>$null - if ($LASTEXITCODE -ne 0 -or -not $out) { return $null } - return [version]($out.Trim()) - } catch { return $null } -} - -function Test-SupportedPython([string]$py) { - $v = Get-PythonVersionObject $py - if (-not $v) { return $false } - return ($v.Major -eq 3 -and $v.Minor -ge 10 -and $v.Minor -lt 14) -} - -function Find-Python([string]$root) { - if ($PythonPath) { - if (Test-SupportedPython $PythonPath) { return (Resolve-Path $PythonPath).Path } - Fail "Specified Python is not supported. Need Python >=3.10,<3.14: $PythonPath" - } - - $portableCandidates = @( - (Join-Path $root ".portable\uv-python\python.exe"), - (Join-Path $root ".portable\python\python.exe"), - (Join-Path $root "python\python.exe") - ) - foreach ($p in $portableCandidates) { - if ((Test-Path $p) -and (Test-SupportedPython $p)) { return (Resolve-Path $p).Path } - } - - $cmds = @("python", "py") - foreach ($cmd in $cmds) { - try { - if ($cmd -eq "py") { - $probe = & py -3.12 -c "import sys; print(sys.executable)" 2>$null - if ($LASTEXITCODE -eq 0 -and $probe -and (Test-SupportedPython $probe.Trim())) { return $probe.Trim() } - $probe = & py -3.11 -c "import sys; print(sys.executable)" 2>$null - if ($LASTEXITCODE -eq 0 -and $probe -and (Test-SupportedPython $probe.Trim())) { return $probe.Trim() } - $probe = & py -3.10 -c "import sys; print(sys.executable)" 2>$null - if ($LASTEXITCODE -eq 0 -and $probe -and (Test-SupportedPython $probe.Trim())) { return $probe.Trim() } - } else { - $probe = & python -c "import sys; print(sys.executable)" 2>$null - if ($LASTEXITCODE -eq 0 -and $probe -and (Test-SupportedPython $probe.Trim())) { return $probe.Trim() } - } - } catch { } - } - - Fail "No supported Python found. Install Python 3.10-3.13, or pass -PythonPath." -} - -function Ensure-Venv([string]$root, [string]$basePython) { - if ($NoVenv) { return $basePython } - $venvDir = Join-Path $root ".venv" - $venvPy = Join-Path $venvDir "Scripts\python.exe" - if (-not (Test-Path $venvPy)) { - Write-Step "Create virtual environment: $venvDir" - & $basePython -m venv $venvDir - if ($LASTEXITCODE -ne 0) { Fail "Failed to create venv." } - } - if (-not (Test-SupportedPython $venvPy)) { Fail "Venv Python is invalid: $venvPy" } - return (Resolve-Path $venvPy).Path -} - -function Install-Dependencies([string]$root, [string]$py) { - if ($SkipPipInstall) { Write-Warn "SkipPipInstall is set; dependencies are not installed."; return } - Write-Step "Upgrade pip" - & $py -m pip install --upgrade pip - if ($LASTEXITCODE -ne 0) { Fail "pip upgrade failed." } - - Write-Step "Install GenericAgent minimal package and desktop bridge extras" - # pyproject.toml already includes: requests, beautifulsoup4, bottle, simple-websocket-server, aiohttp. - # desktop_bridge.py additionally imports psutil. - & $py -m pip install -e $root psutil - if ($LASTEXITCODE -ne 0) { Fail "pip install failed." } -} - -function Ensure-MyKey([string]$root) { - $mykey = Join-Path $root "mykey.py" - $tpl = Join-Path $root "mykey_template.py" - if (Test-Path $mykey) { - Write-Ok "mykey.py exists" - return - } - if (Test-Path $tpl) { - Copy-Item $tpl $mykey - Write-Warn "Created mykey.py from mykey_template.py. User still needs to fill API keys." - } else { - Write-Warn "mykey.py and mykey_template.py are missing. Model config may not work." - } -} - -function Write-DesktopSettings([string]$root, [string]$py) { - $settingsPath = Join-Path $env:USERPROFILE ".ga_desktop_settings.json" - $obj = [ordered]@{ - python_path = $py - project_dir = $root - bridge_script = (Join-Path $root "frontends\desktop_bridge.py") - } - $json = $obj | ConvertTo-Json -Depth 5 - # PowerShell 5.1 `Set-Content -Encoding UTF8` writes a UTF-8 BOM. - # Rust serde_json does not accept BOM at the beginning, causing the Tauri shell - # to ignore this settings file and auto-discover the wrong project directory. - $utf8NoBom = New-Object System.Text.UTF8Encoding($false) - [System.IO.File]::WriteAllText($settingsPath, $json, $utf8NoBom) - Write-Ok "Wrote desktop settings: $settingsPath" -} - -function Test-WebView2Installed { - if ($SkipWebView2Check) { return } - Write-Step "Check Microsoft Edge WebView2 Runtime" - $keys = @( - "HKLM:\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}", - "HKLM:\SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}", - "HKCU:\SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" - ) - foreach ($k in $keys) { - if (Test-Path $k) { Write-Ok "WebView2 Runtime detected"; return } - } - Write-Warn "WebView2 Runtime not detected. Tauri desktop window may fail on clean Windows." - Write-Warn "Download: https://developer.microsoft.com/microsoft-edge/webview2/" -} - -function Find-DesktopDir([string]$root) { - $desktop = Join-Path $root "frontends\desktop" - if (-not (Test-Path (Join-Path $desktop "src-tauri\tauri.conf.json"))) { - Fail "Tauri desktop dir not found: $desktop" - } - return (Resolve-Path $desktop).Path -} - -function Ensure-NodeAndNpm { - $node = Get-Command node -ErrorAction SilentlyContinue - $npm = Get-Command npm -ErrorAction SilentlyContinue - if (-not $node) { Fail "node is not available in PATH. Install Node.js 20+ for desktop dev/build." } - if (-not $npm) { Fail "npm is not available in PATH. Install Node.js/npm for desktop dev/build." } - $nodeVer = & node --version - $npmVer = & cmd /c npm --version - Write-Ok "Node: $nodeVer; npm: $npmVer" -} - -function Install-DesktopNpm([string]$root) { - if ($SkipNpmInstall) { Write-Warn "SkipNpmInstall is set; desktop npm dependencies are not installed."; return } - $desktop = Find-DesktopDir $root - Ensure-NodeAndNpm - Write-Step "Install Tauri desktop npm dependencies: $desktop" - Push-Location $desktop - try { - & cmd /c npm install - if ($LASTEXITCODE -ne 0) { Fail "npm install failed in $desktop" } - & cmd /c npx tauri --version - if ($LASTEXITCODE -ne 0) { Fail "npx tauri --version failed after npm install" } - } finally { - Pop-Location - } -} - -function Build-DesktopDebug([string]$root) { - $desktop = Find-DesktopDir $root - Install-DesktopNpm $root - Write-Step "Build Tauri debug desktop exe" - Push-Location $desktop - try { - & cmd /c npx tauri build --debug - if ($LASTEXITCODE -ne 0) { Fail "Tauri debug build failed." } - } finally { - Pop-Location - } - $debugExe = Join-Path $desktop "src-tauri\target\debug\ga-desktop.exe" - if (Test-Path $debugExe) { Write-Ok "Debug exe: $debugExe" } else { Write-Warn "Debug exe not found at expected path: $debugExe" } -} - -function Start-DesktopDev([string]$root) { - $desktop = Find-DesktopDir $root - Install-DesktopNpm $root - Write-Step "Start Tauri desktop dev shell" - Write-Warn "This keeps running in current console. If status checks fail, bypass proxy for http://127.0.0.1:14168/status." - Push-Location $desktop - try { - & cmd /c npx tauri dev -- --dev - } finally { - Pop-Location - } -} - -function Find-PackagedExe([string]$root) { - $candidates = @( - (Join-Path $root "frontends\GenericAgent.exe"), - (Join-Path $root "frontends\desktop\src-tauri\target\release\GenericAgent.exe"), - (Join-Path $root "frontends\desktop\src-tauri\target\release\ga-desktop.exe"), - (Join-Path $root "frontends\desktop\src-tauri\target\debug\ga-desktop.exe") - ) - foreach ($p in $candidates) { if (Test-Path $p) { return (Resolve-Path $p).Path } } - return "" -} - -function Start-Bridge([string]$root, [string]$py) { - $bridge = Join-Path $root "frontends\desktop_bridge.py" - if (-not (Test-Path $bridge)) { Fail "desktop_bridge.py not found: $bridge" } - Write-Step "Start bridge: $bridge" - Write-Warn "This keeps running in current console. Browse http://127.0.0.1:14168/status to check." - $env:PYTHONPATH = "$root;$(Join-Path $root 'frontends');$env:PYTHONPATH" - & $py $bridge -} - -function Start-Exe([string]$root) { - $exe = Find-PackagedExe $root - if (-not $exe) { Fail "Packaged GenericAgent.exe not found. Use -Mode BridgeOnly or build Tauri first." } - Write-Step "Start packaged desktop exe" - Start-Process -FilePath $exe -WorkingDirectory (Split-Path $exe -Parent) - Write-Ok "Started: $exe" -} - -Write-Step "Resolve project root" -$scriptRoot = Resolve-ScriptRoot -$root = Find-ProjectRoot $scriptRoot -Write-Ok "Project root: $root" - -Write-Step "Resolve Python" -$basePy = Find-Python $root -Write-Ok "Base Python: $basePy" - -$py = Ensure-Venv $root $basePy -Write-Ok "Runtime Python: $py" - -Install-Dependencies $root $py -Ensure-MyKey $root -Write-DesktopSettings $root $py -Test-WebView2Installed - -if ($Mode -eq "PrepareOnly") { - Write-Ok "Preparation finished. No app started because -Mode PrepareOnly was used." - exit 0 -} - -if ($Mode -eq "BridgeOnly") { - Start-Bridge $root $py - exit 0 -} - -if ($Mode -eq "NpmInstallOnly") { - Install-DesktopNpm $root - Write-Ok "Desktop npm setup finished." - exit 0 -} - -if ($Mode -eq "DesktopBuildOnly") { - Build-DesktopDebug $root - Write-Ok "Desktop debug build finished." - exit 0 -} - -if ($Mode -eq "DesktopDevOnly") { - Start-DesktopDev $root - exit 0 -} - -if ($Mode -eq "ExeOnly") { - Start-Exe $root - exit 0 -} - -# Auto mode: prefer packaged exe if present, otherwise start bridge for source/dev tree. -$exe = Find-PackagedExe $root -if ($exe) { Start-Exe $root } else { Start-Bridge $root $py }