mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 20:05:46 -06:00
b68c136609
* feat(codex): upgrade app-server integration to 0.149.0 Co-authored-by: Vincent Koc <vincentkoc@ieee.org> * fix(codex): harden full app-server integration and lifecycle * fix(codex): scope guardian trust and satisfy integration gates * fix(codex): keep guardian startup and router tests within gates * chore(codex): tighten guardian assertion safety baseline * fix(ui): preserve sidebar icon path contracts * test(codex): align side-question auth fixture Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com> * style(codex): format transcript mirror imports Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com> * test(codex): preserve native approval decisions Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com> * test(codex): isolate app cache and catalog fixtures Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com> * fix(ui): render guardian review and system notices Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com> * test(codex): isolate native approval decisions Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com> * fix(codex): revalidate reviewer config trust Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com> * chore(codex): update app-server to 0.149.1 Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com> * test(codex): align desktop version warning Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com> * fix(ui): scope notices to the active run Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com> * fix(codex): isolate review, hosted app, and auth ownership Co-authored-by: Vito Cappello <hixvac@gmail.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org> Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com> * chore(codex): keep release notes out of the release-owned changelog * test(codex): reject reviewer cancellation with its explicit error --------- Co-authored-by: Peter Steinberger <steipete@gmail.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org> Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com> Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com> Co-authored-by: Vito Cappello <hixvac@gmail.com>
137 lines
5.5 KiB
JavaScript
137 lines
5.5 KiB
JavaScript
// Exact package assertions shared by Codex release install scenarios.
|
|
import { spawnSync } from "node:child_process";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { assertPathInside, findPackageJson, readJson } from "./codex-install-utils.mjs";
|
|
|
|
const EXPECTED_CODEX_VERSION = "0.149.1";
|
|
const CODEX_PLATFORM_TARGETS = new Map([
|
|
["linux:x64", { alias: "@openai/codex-linux-x64", os: "linux", cpu: "x64" }],
|
|
["linux:arm64", { alias: "@openai/codex-linux-arm64", os: "linux", cpu: "arm64" }],
|
|
["darwin:x64", { alias: "@openai/codex-darwin-x64", os: "darwin", cpu: "x64" }],
|
|
["darwin:arm64", { alias: "@openai/codex-darwin-arm64", os: "darwin", cpu: "arm64" }],
|
|
["win32:x64", { alias: "@openai/codex-win32-x64", os: "win32", cpu: "x64" }],
|
|
["win32:arm64", { alias: "@openai/codex-win32-arm64", os: "win32", cpu: "arm64" }],
|
|
]);
|
|
|
|
function exactStringArray(value, expected) {
|
|
return Array.isArray(value) && value.length === 1 && value[0] === expected;
|
|
}
|
|
|
|
function recordEvidence(evidence) {
|
|
for (const [key, value] of Object.entries(evidence)) {
|
|
process.stdout.write(`[codex-release] ${key}=${value}\n`);
|
|
}
|
|
}
|
|
|
|
export function assertCodexReleasePackageContract(params) {
|
|
const platform = params.platform ?? process.platform;
|
|
const arch = params.arch ?? process.arch;
|
|
const target = CODEX_PLATFORM_TARGETS.get(`${platform}:${arch}`);
|
|
if (!target) {
|
|
throw new Error(`unsupported Codex release platform: ${platform}/${arch}`);
|
|
}
|
|
|
|
const pluginPackage = readJson(params.pluginPackageJson);
|
|
const expectedDependency = pluginPackage.dependencies?.["@openai/codex"];
|
|
if (expectedDependency !== EXPECTED_CODEX_VERSION) {
|
|
throw new Error(
|
|
`@openclaw/codex must depend on @openai/codex ${EXPECTED_CODEX_VERSION}; found ${String(expectedDependency)}`,
|
|
);
|
|
}
|
|
const requiredPlatformPackages = pluginPackage.openclaw?.install?.requiredPlatformPackages;
|
|
if (
|
|
!Array.isArray(requiredPlatformPackages) ||
|
|
!requiredPlatformPackages.includes(target.alias)
|
|
) {
|
|
throw new Error(
|
|
`@openclaw/codex manifest does not require current platform alias ${target.alias}`,
|
|
);
|
|
}
|
|
|
|
assertPathInside(params.managedRoot, params.codexPackageJson, "@openai/codex dependency");
|
|
const codexPackage = readJson(params.codexPackageJson);
|
|
if (codexPackage.version !== EXPECTED_CODEX_VERSION) {
|
|
throw new Error(
|
|
`installed @openai/codex version mismatch: expected ${EXPECTED_CODEX_VERSION}, got ${String(codexPackage.version)}`,
|
|
);
|
|
}
|
|
const expectedAliasSpec = `npm:@openai/codex@${EXPECTED_CODEX_VERSION}-${platform}-${arch}`;
|
|
if (codexPackage.optionalDependencies?.[target.alias] !== expectedAliasSpec) {
|
|
throw new Error(
|
|
`@openai/codex current platform alias mismatch: expected ${target.alias}=${expectedAliasSpec}`,
|
|
);
|
|
}
|
|
|
|
const platformPackageJson = findPackageJson(target.alias, params.packageRoots);
|
|
if (!platformPackageJson) {
|
|
throw new Error(`missing current Codex platform alias ${target.alias}`);
|
|
}
|
|
assertPathInside(params.managedRoot, platformPackageJson, "Codex platform package");
|
|
const platformPackage = readJson(platformPackageJson);
|
|
const expectedPlatformVersion = `${EXPECTED_CODEX_VERSION}-${platform}-${arch}`;
|
|
if (platformPackage.version !== expectedPlatformVersion) {
|
|
throw new Error(
|
|
`installed ${target.alias} version mismatch: expected ${expectedPlatformVersion}, got ${String(platformPackage.version)}`,
|
|
);
|
|
}
|
|
if (!exactStringArray(platformPackage.os, target.os)) {
|
|
throw new Error(
|
|
`installed ${target.alias} os mismatch: expected [${target.os}], got ${JSON.stringify(platformPackage.os)}`,
|
|
);
|
|
}
|
|
if (!exactStringArray(platformPackage.cpu, target.cpu)) {
|
|
throw new Error(
|
|
`installed ${target.alias} cpu mismatch: expected [${target.cpu}], got ${JSON.stringify(platformPackage.cpu)}`,
|
|
);
|
|
}
|
|
|
|
const codexBinPath =
|
|
typeof codexPackage.bin === "string"
|
|
? codexPackage.bin
|
|
: codexPackage.bin && typeof codexPackage.bin.codex === "string"
|
|
? codexPackage.bin.codex
|
|
: undefined;
|
|
if (!codexBinPath) {
|
|
throw new Error(`@openai/codex package has no codex bin: ${params.codexPackageJson}`);
|
|
}
|
|
const codexBin = path.resolve(path.dirname(params.codexPackageJson), codexBinPath);
|
|
if (!fs.existsSync(codexBin)) {
|
|
throw new Error(`missing managed Codex binary: ${codexBin}`);
|
|
}
|
|
assertPathInside(params.managedRoot, codexBin, "managed Codex binary");
|
|
const versionRun = spawnSync(process.execPath, [codexBin, "--version"], {
|
|
encoding: "utf8",
|
|
maxBuffer: 64 * 1024,
|
|
timeout: 15_000,
|
|
windowsHide: true,
|
|
});
|
|
const stdout = versionRun.stdout?.trim() ?? "";
|
|
const stderr = versionRun.stderr?.trim() ?? "";
|
|
if (versionRun.error || versionRun.status !== 0) {
|
|
const failure = versionRun.error?.message ?? `exit status ${String(versionRun.status)}`;
|
|
throw new Error(
|
|
`managed Codex --version failed (${failure}): ${stderr || stdout || "no output"}`,
|
|
);
|
|
}
|
|
const versionMatch = /^codex-cli\s+(\S+)$/u.exec(stdout);
|
|
if (versionMatch?.[1] !== EXPECTED_CODEX_VERSION) {
|
|
throw new Error(
|
|
`managed Codex CLI version mismatch: expected ${EXPECTED_CODEX_VERSION}, got ${JSON.stringify(stdout)}`,
|
|
);
|
|
}
|
|
|
|
const evidence = {
|
|
packageVersion: codexPackage.version,
|
|
cliVersion: versionMatch[1],
|
|
platformAlias: target.alias,
|
|
platformVersion: platformPackage.version,
|
|
platformOs: target.os,
|
|
platformCpu: target.cpu,
|
|
};
|
|
if (params.recordEvidence !== false) {
|
|
recordEvidence(evidence);
|
|
}
|
|
return { codexBin, evidence };
|
|
}
|