diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml index 1a6a33961..d3819453e 100644 --- a/.github/workflows/pr-build.yml +++ b/.github/workflows/pr-build.yml @@ -26,7 +26,29 @@ jobs: uses: dtolnay/rust-toolchain@stable - name: Install NSIS - run: choco install nsis -y + shell: pwsh + run: | + $makensis = $null + for ($attempt = 1; $attempt -le 3; $attempt++) { + choco install nsis -y --no-progress + # Chocolatey 可能在下载失败后返回成功,必须实际验证编译器。 + $candidates = @( + "${env:ProgramFiles(x86)}\NSIS\makensis.exe", + "$env:ProgramFiles\NSIS\makensis.exe" + ) + $makensis = $candidates | Where-Object { Test-Path -LiteralPath $_ -PathType Leaf } | Select-Object -First 1 + if (-not $makensis) { + $command = Get-Command makensis.exe -ErrorAction SilentlyContinue + if ($command) { $makensis = $command.Source } + } + if ($makensis) { + & $makensis /VERSION + if ($LASTEXITCODE -eq 0) { break } + } + $makensis = $null + if ($attempt -lt 3) { Start-Sleep -Seconds (10 * $attempt) } + } + if (-not $makensis) { throw "NSIS 安装失败或编译器不可用,停止 PR 构建。" } - name: Install frontend dependencies working-directory: apps/codex-plus-manager @@ -68,13 +90,26 @@ jobs: if (-not $version -or $version -eq "main") { $version = "0.0.0-${{ github.run_number }}" } - $makensis = "${env:ProgramFiles(x86)}\NSIS\makensis.exe" - if (-not (Test-Path $makensis)) { - $makensis = "makensis" + # NSIS 的 64 位安装目录与 Chocolatey PATH 更新均需要兼容。 + $candidates = @( + "${env:ProgramFiles(x86)}\NSIS\makensis.exe", + "$env:ProgramFiles\NSIS\makensis.exe" + ) + $makensis = $candidates | Where-Object { Test-Path -LiteralPath $_ -PathType Leaf } | Select-Object -First 1 + if (-not $makensis) { + $command = Get-Command makensis.exe -ErrorAction SilentlyContinue + if ($command) { $makensis = $command.Source } + } + if (-not $makensis) { + throw "NSIS 编译器未找到,检查 Chocolatey 安装结果。" } Push-Location scripts/installer/windows - & $makensis "/INPUTCHARSET" "UTF8" "/DVERSION=$version" CodexPlusPlus.nsi - Pop-Location + try { + & $makensis "/INPUTCHARSET" "UTF8" "/DVERSION=$version" CodexPlusPlus.nsi + if ($LASTEXITCODE -ne 0) { throw "NSIS 打包失败,退出码 $LASTEXITCODE" } + } finally { + Pop-Location + } - name: Upload Windows binaries uses: actions/upload-artifact@v4 diff --git a/apps/codex-plus-launcher/src/main.rs b/apps/codex-plus-launcher/src/main.rs index 3c644f197..029ab79ed 100644 --- a/apps/codex-plus-launcher/src/main.rs +++ b/apps/codex-plus-launcher/src/main.rs @@ -518,6 +518,7 @@ async fn run_embedded_session( || repair_session_index_automatically(hooks.index_repair_checks_setting()), ) .await; + handle.stop_isolated_api_quota_gate().await; stopped_by_host = host_stop; result } @@ -1818,9 +1819,16 @@ mod tests { body.matches("repair_session_index_automatically(").count(), 1 ); - assert!(body.contains( - "wait_for_session_exit_or_stop(handle.wait_for_codex_exit(), &mut stop)" - )); + assert!( + body.contains("wait_for_session_exit_or_stop(handle.wait_for_codex_exit(), &mut stop)") + ); + let quota_stop = body + .find("handle.stop_isolated_api_quota_gate().await") + .unwrap(); + let helper_stop = body + .find("hooks.shutdown_helper(options.helper_port).await") + .unwrap(); + assert!(quota_stop < helper_stop); let launch_start = source.find("async fn launcher_session(").unwrap(); let launch_end = source[launch_start..] .find("async fn activate_and_write_running_status(") diff --git a/apps/codex-plus-manager/src/App.tsx b/apps/codex-plus-manager/src/App.tsx index 01221b9ac..8d3d2626b 100644 --- a/apps/codex-plus-manager/src/App.tsx +++ b/apps/codex-plus-manager/src/App.tsx @@ -300,6 +300,7 @@ type BackendSettings = WhaleBalanceSettings & { providerSyncLastSelectedProvider: string; relayProfilesEnabled: boolean; enhancementsEnabled: boolean; + codexAppStandaloneQuotaUnlock: boolean; codexAppPluginMarketplaceUnlock: boolean; codexAppModelWhitelistUnlock: boolean; codexAppSessionDelete: boolean; @@ -1058,6 +1059,7 @@ const defaultSettings: BackendSettings = { providerSyncLastSelectedProvider: "", relayProfilesEnabled: true, enhancementsEnabled: true, + codexAppStandaloneQuotaUnlock: false, codexAppPluginMarketplaceUnlock: true, codexAppModelWhitelistUnlock: true, codexAppSessionDelete: true, @@ -5705,18 +5707,32 @@ function EnhanceScreen({
- +
+ + +
{dirty ? t("有未保存修改") : t("已保存")}