diff --git a/VERSION b/VERSION index 7f046486..be0e1ece 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.75.1 +0.75.2 diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 4251bfe6..7b652cb9 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -8,6 +8,20 @@ This project follows the repository versioning rule: - `improvement` -> `+0.0.1`(bugfix + 小功能混合) - `bugfix` -> `+0.0.1` +## [0.75.2] — 2026-09-25 + +Released: 2026-09-25 + +### Highlights +- 修复 Windows 启动器固定使用旧版 PowerShell 的问题,优先在 Windows Terminal 新窗口中运行 PowerShell 7。 + +### Fixed +- 仓库与桌面 CMD 引导优先使用 `pwsh.exe`,缺少新版 PowerShell 或 Terminal 时保留可用环境回退。 +- 已以管理员运行的入口同样进入首选终端,子窗口校验权限后直接衔接 WSL,避免重复提权和递归开窗。 +- 补齐终端选择、含空格路径、提权分支回归和中英文说明,保持 WSL 重启参数及默认端口不变。 + +--- + ## [0.75.1] — 2026-09-25 Released: 2026-09-25 diff --git a/docs/technical/en/ops-planet-sh-startup.md b/docs/technical/en/ops-planet-sh-startup.md index d33fa587..d5fcb2f4 100644 --- a/docs/technical/en/ops-planet-sh-startup.md +++ b/docs/technical/en/ops-planet-sh-startup.md @@ -2,6 +2,8 @@ ## Windows desktop launcher +The launcher prefers a new Windows Terminal window and explicitly runs PowerShell 7 (`pwsh.exe`), independently of the default Terminal profile. Without PowerShell 7 it falls back to Windows PowerShell; without Terminal it starts the available PowerShell directly. The CMD bootstrap also prefers PowerShell 7. Ordinary entries request elevation; entries already running as administrator still dispatch to the preferred terminal without another elevation request. The child validates its privileges and enters WSL directly, preventing recursive windows. The existing post-restart WSL shell is retained. + On first use, open the actual project folder in Windows Explorer and double-click the repository's `planet.cmd`. It derives the WSL distribution and Linux project directory from its own location, creates `Planet.cmd` on the current user's actual Windows desktop, then follows the normal restart flow. Both `\\wsl$\distribution\...` and `\\wsl.localhost\distribution\...` work. Local Windows-drive checkouts use the default WSL distribution and `wslpath`. Windows resolves the desktop location, including redirected desktops such as OneDrive; WSL, zsh and project dependencies must already be installed. Subsequent desktop launches use the bound target, request the existing administrator elevation and call `planet.sh restart --allow-lan`. No test ports are embedded: defaults remain frontend 3000, backend 8000 and AI Provider 8010, subject to explicit `DEFAULT_*_PORT` environment overrides. Successful restarts open Earth using the actual `ports.env` values and retain the WSL shell; failures display their error without opening a success page. `scripts/windows/planet-launcher.ps1` owns path resolution, desktop installation and elevation; `scripts/windows/restart.zsh` only bridges to the existing lifecycle script. diff --git a/docs/technical/zh/ops-planet-sh-startup.md b/docs/technical/zh/ops-planet-sh-startup.md index f249bb5e..c5399fd9 100644 --- a/docs/technical/zh/ops-planet-sh-startup.md +++ b/docs/technical/zh/ops-planet-sh-startup.md @@ -2,6 +2,8 @@ ## Windows 桌面启动器 +启动窗口优先使用 Windows Terminal,并显式运行 PowerShell 7(`pwsh.exe`),不依赖 Terminal 默认配置文件。未安装 PowerShell 7 时回退到 Windows PowerShell;未安装 Terminal 时直接启动可用的 PowerShell。CMD 初始引导同样优先 PowerShell 7。普通入口请求提权,已经以管理员运行的入口也会进入新 Terminal 窗口,但不会再次请求提权;子窗口校验权限后直接执行 WSL,避免递归打开窗口。重启完成后仍保留原有 WSL shell。 + 首次在 Windows 文件资源管理器中打开实际项目目录,双击仓库根目录的 `planet.cmd`。它从自身位置识别 WSL 发行版和 Linux 项目目录,在 Windows 当前用户的实际桌面生成 `Planet.cmd`,随后进入正常重启流程。支持 `\\wsl$\发行版\...` 与 `\\wsl.localhost\发行版\...`;仓库位于 Windows 本地磁盘时,使用默认 WSL 发行版及 `wslpath` 映射。系统桌面位置由 Windows 获取,兼容不同用户名和 OneDrive 等桌面重定向;WSL、zsh 及项目依赖仍须先准备好。 后续双击桌面副本,使用已绑定的发行版与目录,申请原有管理员权限,并调用 `planet.sh restart --allow-lan`。不写入测试端口;默认前端 3000、后端 8000、AI Provider 8010,显式 `DEFAULT_*_PORT` 环境配置仍有效。成功后按实际 `ports.env` 端口打开 Earth,终端保留 WSL shell;失败只显示错误,不打开成功页面。源文件负责生成入口,`scripts/windows/planet-launcher.ps1` 负责 Windows 路径、桌面安装与提权,`scripts/windows/restart.zsh` 只衔接现有重启流程。 diff --git a/docs/version-history.md b/docs/version-history.md index f4dc36b3..ea552b8b 100644 --- a/docs/version-history.md +++ b/docs/version-history.md @@ -16,12 +16,13 @@ ## Current Version - `main` 当前主线历史推导到:`0.16.5` -- `dev` 当前开发分支历史推导到:`0.75.1` +- `dev` 当前开发分支历史推导到:`0.75.2` ## Timeline | Version | Type | Branch | Commit | Summary | | --- | --- | --- | --- | --- | +| `0.75.2` | bugfix | `dev` | `v0.75.2` | Windows 启动器优先 Terminal 与 PowerShell 7,修复管理员入口分流,补齐兼容回退与提权测试 | | `0.75.1` | improvement | `dev` | `v0.75.1` | Windows 启动器自动生成本机桌面入口,后台维护算力比较数据,恢复小球惯性与大球跟手分流并更新 agent 策略 | | `0.75.0` | feature | `dev` | `v0.75.0` | 四图切换默认原始底图,新增算力区域态势卡片,统一空间连线与重排,优化启动和缩放拖动并补齐地理规则交付 | | `0.74.7` | improvement | `dev` | `v0.74.7` | Docker 镜像网络故障临时回退,精简副行进度与失败显示,修复数据库端口冲突及启动重试并补齐实际验证 | diff --git a/frontend/package.json b/frontend/package.json index bf4a9931..91042410 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "planet-frontend", - "version": "0.75.1", + "version": "0.75.2", "private": true, "packageManager": "bun@1", "dependencies": { diff --git a/planet.cmd b/planet.cmd index 7694f211..d353adbc 100644 --- a/planet.cmd +++ b/planet.cmd @@ -3,7 +3,10 @@ setlocal EnableExtensions DisableDelayedExpansion set "PLANET_LAUNCHER_SOURCE=%~f0" set "PLANET_LAUNCHER_INSTALL_ONLY=" if /i "%~1"=="--install-only" set "PLANET_LAUNCHER_INSTALL_ONLY=1" -powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "& (Join-Path (Split-Path -LiteralPath $env:PLANET_LAUNCHER_SOURCE) 'scripts\windows\planet-launcher.ps1') -InstallOnly:($env:PLANET_LAUNCHER_INSTALL_ONLY -eq '1')" +set "PLANET_POWERSHELL=powershell.exe" +where.exe pwsh.exe >nul 2>&1 +if not errorlevel 1 set "PLANET_POWERSHELL=pwsh.exe" +%PLANET_POWERSHELL% -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "& (Join-Path (Split-Path -LiteralPath $env:PLANET_LAUNCHER_SOURCE) 'scripts\windows\planet-launcher.ps1') -InstallOnly:($env:PLANET_LAUNCHER_INSTALL_ONLY -eq '1')" set "planet_launcher_exit=%errorlevel%" if not "%planet_launcher_exit%"=="0" pause exit /b %planet_launcher_exit% diff --git a/pyproject.toml b/pyproject.toml index 7bd5a5a7..b0280da4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "planet" -version = "0.75.1" +version = "0.75.2" description = "智能星球计划 - 态势感知系统" requires-python = ">=3.14" dependencies = [ diff --git a/scripts/harness/test_windows_launcher.ps1 b/scripts/harness/test_windows_launcher.ps1 index 6a19af34..3e773b89 100644 --- a/scripts/harness/test_windows_launcher.ps1 +++ b/scripts/harness/test_windows_launcher.ps1 @@ -78,3 +78,50 @@ try { [IO.Path]::GetFileName($resolved) -notlike 'planet-launcher-tests-*') { throw 'Unsafe cleanup path' } Remove-Item -LiteralPath $resolved -Recurse -Force } + +function Get-Command { + param([string]$Name, [string]$CommandType, [string]$ErrorAction) + if ($script:AvailableLaunchCommands.ContainsKey($Name)) { + return [pscustomobject]@{ Source = $script:AvailableLaunchCommands[$Name] } + } +} +$pwshPath = 'C:\Program Files\PowerShell\7\pwsh.exe' +$terminalPath = 'C:\Users\Test\AppData\Local\Microsoft\WindowsApps\wt.exe' +$legacyPath = 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' +foreach ($hasTerminal in @($true, $false)) { + foreach ($hasPwsh in @($true, $false)) { + $script:AvailableLaunchCommands = @{ 'powershell.exe' = $legacyPath } + if ($hasTerminal) { $script:AvailableLaunchCommands['wt.exe'] = $terminalPath } + if ($hasPwsh) { $script:AvailableLaunchCommands['pwsh.exe'] = $pwshPath } + $launch = Get-PlanetTerminalLaunch 'TESTPAYLOAD' + $expectedShell = if ($hasPwsh) { $pwshPath } else { $legacyPath } + $expectedExecutable = if ($hasTerminal) { $terminalPath } else { $expectedShell } + Assert-Equal $expectedExecutable $launch.FilePath 'Terminal/shell priority' + if ($hasTerminal -and -not $launch.ArgumentList.Contains('"' + $expectedShell + '"')) { + throw 'Terminal shell path must be quoted, including Program Files paths' + } + if ($launch.ArgumentList -notmatch '-EncodedCommand TESTPAYLOAD$') { + throw 'Encoded bootstrap was not preserved' + } + } +} +function Test-PlanetAdministrator { return $script:IsTestAdministrator } +function Start-Process { + param($FilePath, $ArgumentList, $WindowStyle, $Verb) + $script:CapturedLaunch = @{ FilePath = $FilePath; ArgumentList = $ArgumentList; Verb = $Verb } + $script:LaunchCount++ +} +$script:AvailableLaunchCommands = @{ 'pwsh.exe' = $pwshPath; 'wt.exe' = $terminalPath } +$script:LaunchCount = 0 +foreach ($isAdmin in @($false, $true)) { + $script:IsTestAdministrator = $isAdmin + Start-PlanetRestart $target + Assert-Equal $terminalPath $script:CapturedLaunch.FilePath 'Admin and ordinary entry both use Terminal' + if ($isAdmin -and $script:CapturedLaunch.Verb) { throw 'Already elevated entry must not request UAC again' } + if (-not $isAdmin) { Assert-Equal 'RunAs' $script:CapturedLaunch.Verb 'Ordinary entry requires elevation' } +} +$script:IsTestAdministrator = $false +try { Start-PlanetRestart $target -AlreadyElevated; throw 'Unelevated child accepted' } +catch { if ($_.Exception.Message -ne 'Administrator elevation was not granted.') { throw } } +Assert-Equal 2 $script:LaunchCount 'Child must not recursively launch more windows' +Write-Host 'PASS: Terminal/PowerShell priority, quoted paths, elevation and no recursive dispatch' diff --git a/scripts/windows/planet-launcher.ps1 b/scripts/windows/planet-launcher.ps1 index dad76bed..41871dc2 100644 --- a/scripts/windows/planet-launcher.ps1 +++ b/scripts/windows/planet-launcher.ps1 @@ -114,7 +114,10 @@ function Install-PlanetDesktopLauncher { '@echo off', 'setlocal EnableExtensions DisableDelayedExpansion', $marker, 'set "PLANET_LAUNCHER_INSTALL_ONLY="', 'if /i "%~1"=="--install-only" set "PLANET_LAUNCHER_INSTALL_ONLY=1"', - "powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -EncodedCommand $encoded", + 'set "PLANET_POWERSHELL=powershell.exe"', + 'where.exe pwsh.exe >nul 2>&1', + 'if not errorlevel 1 set "PLANET_POWERSHELL=pwsh.exe"', + "%PLANET_POWERSHELL% -NoLogo -NoProfile -ExecutionPolicy Bypass -EncodedCommand $encoded", 'set "planet_launcher_exit=%errorlevel%"', 'if not "%planet_launcher_exit%"=="0" pause', 'exit /b %planet_launcher_exit%' @@ -129,18 +132,39 @@ function Test-PlanetAdministrator { return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } +function Get-PlanetTerminalLaunch { + param([string]$EncodedCommand) + $shell = Get-Command pwsh.exe -CommandType Application -ErrorAction SilentlyContinue | + Select-Object -First 1 + if (-not $shell) { + $shell = Get-Command powershell.exe -CommandType Application -ErrorAction Stop | + Select-Object -First 1 + } + $shellArguments = "-NoLogo -NoProfile -NoExit -ExecutionPolicy Bypass -EncodedCommand $EncodedCommand" + $launch = @{ FilePath = $shell.Source; ArgumentList = $shellArguments; WindowStyle = 'Normal' } + $terminal = Get-Command wt.exe -CommandType Application -ErrorAction SilentlyContinue | + Select-Object -First 1 + if ($terminal) { + $launch.FilePath = $terminal.Source + # Start-Process joins arguments: quote the executable path explicitly. + $launch.ArgumentList = '-w new new-tab --title Planet "' + $shell.Source + '" ' + $shellArguments + } + return $launch +} + function Start-PlanetRestart { param([hashtable]$Target, [switch]$AlreadyElevated) $script:PlanetLauncherExitCode = 0 - if (-not (Test-PlanetAdministrator)) { - if ($AlreadyElevated) { throw 'Administrator elevation was not granted.' } + $isAdministrator = Test-PlanetAdministrator + if (-not $AlreadyElevated) { $encoded = ConvertTo-PlanetEncodedCommand (Get-PlanetBootstrap $Target -RunElevated) + $launch = Get-PlanetTerminalLaunch $encoded + if (-not $isAdministrator) { $launch.Verb = 'RunAs' } # An interactive terminal is intentional: startup logs and the WSL shell stay visible. - Start-Process powershell.exe -Verb RunAs -WindowStyle Normal -ArgumentList @( - '-NoLogo', '-NoProfile', '-NoExit', '-ExecutionPolicy', 'Bypass', '-EncodedCommand', $encoded - ) | Out-Null + Start-Process @launch | Out-Null return } + if (-not $isAdministrator) { throw 'Administrator elevation was not granted.' } Write-Host "Restarting Planet in $($Target.Distro):$($Target.LinuxProjectRoot)" & wsl.exe -d $Target.Distro --cd $Target.LinuxProjectRoot --exec zsh -l -i ($Target.LinuxProjectRoot + '/scripts/windows/restart.zsh') $script:PlanetLauncherExitCode = $LASTEXITCODE diff --git a/uv.lock b/uv.lock index 63304f2e..801da15d 100644 --- a/uv.lock +++ b/uv.lock @@ -757,7 +757,7 @@ wheels = [ [[package]] name = "planet" -version = "0.75.1" +version = "0.75.2" source = { virtual = "." } dependencies = [ { name = "aiofiles" },