


























@@ -0,0 +1,117 @@
1+import fs from "node:fs";
2+import path from "node:path";
3+4+const readJson = (file) => JSON.parse(fs.readFileSync(file, "utf8"));
5+6+function stateDir() {
7+return process.env.OPENCLAW_STATE_DIR || path.join(process.env.HOME, ".openclaw");
8+}
9+10+function configPath() {
11+return process.env.OPENCLAW_CONFIG_PATH || path.join(stateDir(), "openclaw.json");
12+}
13+14+function realPathMaybe(filePath) {
15+try {
16+return fs.realpathSync(filePath);
17+} catch {
18+return path.resolve(filePath);
19+}
20+}
21+22+function assertPathInside(parentPath, childPath, label) {
23+const parent = realPathMaybe(parentPath);
24+const child = realPathMaybe(childPath);
25+const relative = path.relative(parent, child);
26+if (relative.startsWith("..") || path.isAbsolute(relative)) {
27+throw new Error(`${label} resolved outside ${parentPath}: ${child}`);
28+}
29+}
30+31+function installRecords() {
32+const indexPath = path.join(stateDir(), "plugins", "installs.json");
33+const index = fs.existsSync(indexPath) ? readJson(indexPath) : {};
34+return index.installRecords || index.records || cfg.plugins?.installs || {};
35+}
36+37+function findPackageJson(packageName, roots) {
38+const packagePath = packageName.startsWith("@")
39+ ? path.join(...packageName.split("/"), "package.json")
40+ : path.join(packageName, "package.json");
41+const candidates = roots.map((root) => path.join(root, "node_modules", packagePath));
42+return candidates.find((candidate) => fs.existsSync(candidate));
43+}
44+45+const cfg = readJson(configPath());
46+const inspect = readJson("/tmp/openclaw-codex-inspect.json");
47+const records = installRecords();
48+const codexRecord = records.codex || inspect.install;
49+if (!codexRecord) {
50+throw new Error(`missing codex install record: ${JSON.stringify(records)}`);
51+}
52+if (codexRecord.source !== "npm") {
53+throw new Error(`expected npm codex install record, got ${codexRecord.source}`);
54+}
55+if (!String(codexRecord.spec || "").includes("@openclaw/codex")) {
56+throw new Error(`expected @openclaw/codex install spec, got ${codexRecord.spec}`);
57+}
58+59+const npmRoot = path.join(stateDir(), "npm");
60+const installPath = String(codexRecord.installPath || "").replace(/^~(?=$|\/)/u, process.env.HOME);
61+if (!installPath) {
62+throw new Error(`missing codex installPath: ${JSON.stringify(codexRecord)}`);
63+}
64+assertPathInside(npmRoot, installPath, "codex install path");
65+66+const codexPackageJson = path.join(installPath, "package.json");
67+if (!fs.existsSync(codexPackageJson)) {
68+throw new Error(`missing npm-installed @openclaw/codex package: ${codexPackageJson}`);
69+}
70+const codexPackage = readJson(codexPackageJson);
71+if (codexPackage.name !== "@openclaw/codex") {
72+throw new Error(`unexpected codex package name: ${codexPackage.name}`);
73+}
74+75+const openAiCodexPackageJson = findPackageJson("@openai/codex", [installPath, npmRoot]);
76+if (!openAiCodexPackageJson) {
77+throw new Error("missing @openai/codex dependency under managed npm root");
78+}
79+assertPathInside(npmRoot, openAiCodexPackageJson, "@openai/codex dependency");
80+81+const list = readJson("/tmp/openclaw-plugins-list.json");
82+const plugin = (list.plugins || []).find((entry) => entry.id === "codex");
83+if (!plugin || plugin.enabled !== true || plugin.status !== "loaded") {
84+throw new Error(`codex plugin was not enabled+loaded: ${JSON.stringify(plugin)}`);
85+}
86+87+if (inspect.plugin?.id !== "codex" || inspect.plugin?.status !== "loaded") {
88+throw new Error(`unexpected codex inspect state: ${JSON.stringify(inspect.plugin)}`);
89+}
90+const hasHarness =
91+(Array.isArray(inspect.plugin?.agentHarnessIds) &&
92+inspect.plugin.agentHarnessIds.includes("codex")) ||
93+(Array.isArray(inspect.capabilities) &&
94+inspect.capabilities.some(
95+(entry) => entry?.kind === "agent-harness" && entry.ids?.includes("codex"),
96+));
97+if (!hasHarness) {
98+throw new Error(`codex harness was not registered: ${JSON.stringify(inspect.plugin)}`);
99+}
100+101+const primaryModel = cfg.agents?.defaults?.model?.primary;
102+if (primaryModel !== "openai/gpt-5.5") {
103+throw new Error(`expected OpenAI onboarding model openai/gpt-5.5, got ${primaryModel}`);
104+}
105+const providerRuntime = cfg.models?.providers?.openai?.agentRuntime?.id;
106+if (providerRuntime && providerRuntime !== "codex") {
107+throw new Error(`unexpected OpenAI provider runtime: ${providerRuntime}`);
108+}
109+110+const authPath = path.join(stateDir(), "agents", "main", "agent", "auth-profiles.json");
111+const authRaw = fs.readFileSync(authPath, "utf8");
112+if (!authRaw.includes("OPENAI_API_KEY")) {
113+throw new Error("auth profile did not persist OPENAI_API_KEY env ref");
114+}
115+if (authRaw.includes("sk-openclaw-codex-on-demand-e2e")) {
116+throw new Error("auth profile persisted the raw OpenAI test key");
117+}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。