mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 04:15:48 -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>
115 lines
4.4 KiB
JavaScript
115 lines
4.4 KiB
JavaScript
// Assertions for Codex on-demand plugin E2E scenarios.
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import {
|
|
assertNoLegacyPrimaryAuthRows,
|
|
assertOpenAiEnvAuthProfileStore,
|
|
readSharedAuthProfileStoreText,
|
|
} from "../auth-profile-store-assertions.mjs";
|
|
import {
|
|
assertPathInside,
|
|
configPath,
|
|
findPackageJson,
|
|
managedNpmRoot,
|
|
npmProjectRootForInstalledPackage,
|
|
readInstallRecords,
|
|
readJson,
|
|
stateDir,
|
|
} from "../codex-install-utils.mjs";
|
|
import { assertCodexReleasePackageContract } from "../codex-release-package-assertions.mjs";
|
|
|
|
const cfg = readJson(configPath());
|
|
const onboard = readJson("/tmp/openclaw-onboard.json");
|
|
const inspect = readJson("/tmp/openclaw-codex-inspect.json");
|
|
const records = readInstallRecords();
|
|
const codexRecord = records.codex;
|
|
if (onboard.ok !== true || onboard.mode !== "local" || onboard.authChoice !== "openai-api-key") {
|
|
throw new Error(`unexpected onboarding terminal result: ${JSON.stringify(onboard)}`);
|
|
}
|
|
if (cfg.plugins?.installs !== undefined) {
|
|
throw new Error("codex install record remained in config instead of the canonical SQLite index");
|
|
}
|
|
if (!codexRecord) {
|
|
throw new Error(`missing codex install record: ${JSON.stringify(records)}`);
|
|
}
|
|
if (codexRecord.source !== "npm") {
|
|
throw new Error(`expected npm codex install record, got ${codexRecord.source}`);
|
|
}
|
|
if (!codexRecord.spec?.includes("@openclaw/codex")) {
|
|
throw new Error(`expected @openclaw/codex install spec, got ${codexRecord.spec}`);
|
|
}
|
|
|
|
const npmRoot = managedNpmRoot();
|
|
const installPath = (codexRecord.installPath || "").replace(/^~(?=$|\/)/u, process.env.HOME);
|
|
if (!installPath) {
|
|
throw new Error(`missing codex installPath: ${JSON.stringify(codexRecord)}`);
|
|
}
|
|
assertPathInside(npmRoot, installPath, "codex install path");
|
|
|
|
const codexPackageJson = path.join(installPath, "package.json");
|
|
if (!fs.existsSync(codexPackageJson)) {
|
|
throw new Error(`missing npm-installed @openclaw/codex package: ${codexPackageJson}`);
|
|
}
|
|
const codexPackage = readJson(codexPackageJson);
|
|
if (codexPackage.name !== "@openclaw/codex") {
|
|
throw new Error(`unexpected codex package name: ${codexPackage.name}`);
|
|
}
|
|
|
|
const npmProjectRoot = npmProjectRootForInstalledPackage(installPath, "@openclaw/codex");
|
|
const openAiCodexPackageJson = findPackageJson("@openai/codex", [
|
|
installPath,
|
|
npmProjectRoot,
|
|
npmRoot,
|
|
]);
|
|
if (!openAiCodexPackageJson) {
|
|
throw new Error("missing @openai/codex dependency under managed npm root");
|
|
}
|
|
assertPathInside(npmRoot, openAiCodexPackageJson, "@openai/codex dependency");
|
|
assertCodexReleasePackageContract({
|
|
pluginPackageJson: codexPackageJson,
|
|
codexPackageJson: openAiCodexPackageJson,
|
|
packageRoots: [installPath, npmProjectRoot, npmRoot],
|
|
managedRoot: npmRoot,
|
|
});
|
|
|
|
const list = readJson("/tmp/openclaw-plugins-list.json");
|
|
const plugin = (list.plugins || []).find((entry) => entry.id === "codex");
|
|
if (!plugin || plugin.enabled !== true || plugin.status !== "loaded") {
|
|
throw new Error(`codex plugin was not enabled+loaded: ${JSON.stringify(plugin)}`);
|
|
}
|
|
|
|
if (inspect.plugin?.id !== "codex" || inspect.plugin?.status !== "loaded") {
|
|
throw new Error(`unexpected codex inspect state: ${JSON.stringify(inspect.plugin)}`);
|
|
}
|
|
const hasHarness =
|
|
(Array.isArray(inspect.plugin?.agentHarnessIds) &&
|
|
inspect.plugin.agentHarnessIds.includes("codex")) ||
|
|
(Array.isArray(inspect.capabilities) &&
|
|
inspect.capabilities.some(
|
|
(entry) => entry?.kind === "agent-harness" && entry.ids?.includes("codex"),
|
|
));
|
|
if (!hasHarness) {
|
|
throw new Error(`codex harness was not registered: ${JSON.stringify(inspect.plugin)}`);
|
|
}
|
|
|
|
const primaryModel = cfg.agents?.defaults?.model?.primary;
|
|
if (primaryModel !== "openai/gpt-5.6-sol") {
|
|
throw new Error(`expected OpenAI onboarding model openai/gpt-5.6-sol, got ${primaryModel}`);
|
|
}
|
|
const providerRuntime = cfg.models?.providers?.openai?.agentRuntime?.id;
|
|
if (providerRuntime && providerRuntime !== "codex") {
|
|
throw new Error(`unexpected OpenAI provider runtime: ${providerRuntime}`);
|
|
}
|
|
|
|
const openClawStateDir = stateDir();
|
|
assertNoLegacyPrimaryAuthRows(openClawStateDir);
|
|
const authRaw = readSharedAuthProfileStoreText(openClawStateDir);
|
|
if (!authRaw) {
|
|
throw new Error("auth profile SQLite store row was not persisted");
|
|
}
|
|
assertOpenAiEnvAuthProfileStore(authRaw, {
|
|
envRefMessage: "auth profile did not persist OPENAI_API_KEY env ref",
|
|
rawKeyMessage: "auth profile persisted the raw OpenAI test key",
|
|
rawKeyNeedle: "sk-openclaw-codex-on-demand-e2e",
|
|
});
|