diff --git a/build.ps1 b/build.ps1 index 5b2e281..a958702 100644 --- a/build.ps1 +++ b/build.ps1 @@ -58,7 +58,7 @@ if (-not (Test-Path -LiteralPath $AppBin -PathType Leaf)) { throw "Build finished, but executable not found: $AppBin" } -& bun $PreparePortable --binary $AppBin --output $BinDir --download true +& bun $PreparePortable --binary $AppBin --output $BinDir --download true --preserve-runtime-config true if ($LASTEXITCODE -ne 0) { throw "Portable preparation failed with exit code $LASTEXITCODE." } @@ -68,15 +68,14 @@ if (-not (Test-Path -LiteralPath $BinOut -PathType Leaf)) { } $CoreOut = Join-Path $BinDir 'cpa-core' -$CoreEntries = @(Get-ChildItem -LiteralPath $CoreOut -Force) -if ( - $CoreEntries.Count -ne 1 -or - $CoreEntries[0].PSIsContainer -or - $CoreEntries[0].Name -notmatch '^CLIProxyAPI_.+_windows_.+\.zip$' -) { +$CoreArchives = @( + Get-ChildItem -LiteralPath $CoreOut -File | + Where-Object { $_.Name -match '^CLIProxyAPI_.+_windows_.+\.zip$' } +) +if ($CoreArchives.Count -ne 1) { throw "Portable core output must contain exactly one Windows core archive: $CoreOut" } Write-Host "Built: $AppBin" Write-Host "Copied: $BinOut" -Write-Host "Bundled core archive: $($CoreEntries[0].FullName)" +Write-Host "Bundled core archive: $($CoreArchives[0].FullName)" diff --git a/core-version.txt b/core-version.txt index 32bf1fc..ee4117d 100644 --- a/core-version.txt +++ b/core-version.txt @@ -1 +1 @@ -7.2.109 +7.2.112 diff --git a/scripts/prepare-portable.mjs b/scripts/prepare-portable.mjs index 1615c06..37b7fd8 100644 --- a/scripts/prepare-portable.mjs +++ b/scripts/prepare-portable.mjs @@ -14,6 +14,7 @@ const binary = resolve(args.get('--binary') ?? join(root, 'src-tauri', 'target', const targetOS = args.get('--os') ?? ({ linux: 'linux', darwin: 'darwin', win32: 'windows' })[process.platform]; const targetArch = args.get('--arch') ?? ({ x64: 'amd64', arm64: 'aarch64' })[process.arch]; const shouldDownload = args.get('--download') === 'true'; +const preserveRuntimeConfig = args.get('--preserve-runtime-config') === 'true'; if (!targetOS || !targetArch) throw new Error(`Unsupported target: ${process.platform}/${process.arch}`); if (!existsSync(binary)) throw new Error(`GUI binary not found: ${binary}`); @@ -75,17 +76,25 @@ await writeFile(join(output, 'portable-app.json'), `${JSON.stringify({ }, null, 2)}\n`); const coreOutput = join(output, 'cpa-core'); -await rm(coreOutput, { recursive: true, force: true }); +if (preserveRuntimeConfig) { + await mkdir(coreOutput, { recursive: true }); + const entries = await readdir(coreOutput, { withFileTypes: true }); + await Promise.all(entries + .filter((entry) => entry.name !== 'config.yaml') + .map((entry) => rm(join(coreOutput, entry.name), { recursive: true, force: true }))); +} else { + await rm(coreOutput, { recursive: true, force: true }); +} await mkdir(coreOutput, { recursive: true }); await copyFile(sourceArchive, join(coreOutput, assetName)); const coreEntries = await readdir(coreOutput, { withFileTypes: true }); -if ( - coreEntries.length !== 1 - || !coreEntries[0].isFile() - || coreEntries[0].name !== assetName -) { +const bundledArchive = coreEntries.find((entry) => entry.isFile() && entry.name === assetName); +if (!bundledArchive) { + throw new Error(`Core output must contain ${assetName}`); +} +if (!preserveRuntimeConfig && coreEntries.length !== 1) { throw new Error(`Core output must contain only ${assetName}`); } console.log(`Prepared portable directory: ${output}`); -console.log(`Bundled core: ${basename(sourceArchive)} (archive only)`); +console.log(`Bundled core: ${basename(sourceArchive)}${preserveRuntimeConfig ? ' (preserved cpa-core/config.yaml)' : ' (archive only)'}`); diff --git a/src-tauri/src/codex_catalog.rs b/src-tauri/src/codex_catalog.rs index 4b1829e..8e3f482 100644 --- a/src-tauri/src/codex_catalog.rs +++ b/src-tauri/src/codex_catalog.rs @@ -99,11 +99,14 @@ pub(crate) fn parse_runtime_models(payload: &Value) -> Result Result