


























11import fs from "node:fs";
22import path from "node:path";
3+import {
4+assertPathInside,
5+configPath,
6+findPackageJson,
7+managedNpmRoot,
8+npmProjectRootForInstalledPackage,
9+readInstallRecords,
10+readJson,
11+realPathMaybe,
12+stateDir,
13+} from "../codex-install-utils.mjs";
314415const command = process.argv[2];
5-const readJson = (file) => JSON.parse(fs.readFileSync(file, "utf8"));
616const allowBetaCompatDiagnostics =
717process.env.OPENCLAW_CODEX_NPM_PLUGIN_ALLOW_BETA_COMPAT_DIAGNOSTICS === "1";
8189-function stateDir() {
10-return process.env.OPENCLAW_STATE_DIR || path.join(process.env.HOME, ".openclaw");
11-}
12-13-function configPath() {
14-return process.env.OPENCLAW_CONFIG_PATH || path.join(stateDir(), "openclaw.json");
15-}
16-17-function realPathMaybe(filePath) {
18-try {
19-return fs.realpathSync(filePath);
20-} catch {
21-return path.resolve(filePath);
22-}
23-}
24-25-function assertPathInside(parentPath, childPath, label) {
26-const parent = realPathMaybe(parentPath);
27-const child = realPathMaybe(childPath);
28-const relative = path.relative(parent, child);
29-if (relative.startsWith("..") || path.isAbsolute(relative)) {
30-throw new Error(`${label} resolved outside ${parentPath}: ${child}`);
31-}
32-}
33-3419function configure() {
3520const modelRef = process.argv[3] || "codex/gpt-5.4";
3621const state = stateDir();
@@ -80,24 +65,13 @@ function configure() {
8065}
81668267function readInstallRecord() {
83-const indexPath = path.join(stateDir(), "plugins", "installs.json");
84-const index = readJson(indexPath);
85-const record = (index.installRecords || index.records || {}).codex;
68+const record = readInstallRecords().codex;
8669if (!record) {
8770throw new Error("missing codex install record");
8871}
8972return record;
9073}
917492-function readInstallRecords() {
93-const indexPath = path.join(stateDir(), "plugins", "installs.json");
94-if (!fs.existsSync(indexPath)) {
95-return {};
96-}
97-const index = readJson(indexPath);
98-return index.installRecords || index.records || {};
99-}
100-10175function normalizePluginSpec(spec) {
10276if (spec.startsWith("npm:")) {
10377return {
@@ -198,10 +172,6 @@ function assertPlugin() {
198172}
199173}
200174201-function managedNpmRoot() {
202-return path.join(stateDir(), "npm");
203-}
204-205175function codexInstallPath() {
206176const record = readInstallRecord();
207177if (typeof record.installPath !== "string" || record.installPath.length === 0) {
@@ -211,31 +181,12 @@ function codexInstallPath() {
211181}
212182213183function codexNpmProjectRoot() {
214-const installPath = codexInstallPath();
215-const packageRoot = "@openclaw/codex"
216-.split("/")
217-.reduce((current) => path.dirname(current), installPath);
218-return path.basename(packageRoot) === "node_modules"
219- ? path.dirname(packageRoot)
220- : managedNpmRoot();
184+return npmProjectRootForInstalledPackage(codexInstallPath(), "@openclaw/codex");
221185}
222186223-function findPackageJson(packageName) {
224-const parts = packageName.split("/");
187+function findCodexPackageJson(packageName) {
225188const projectRoot = codexNpmProjectRoot();
226-const candidates =
227-packageName.startsWith("@") && parts.length === 2
228- ? [
229-path.join(projectRoot, "node_modules", parts[0], parts[1], "package.json"),
230-path.join(codexInstallPath(), "node_modules", parts[0], parts[1], "package.json"),
231-path.join(managedNpmRoot(), "node_modules", parts[0], parts[1], "package.json"),
232-]
233- : [
234-path.join(projectRoot, "node_modules", packageName, "package.json"),
235-path.join(codexInstallPath(), "node_modules", packageName, "package.json"),
236-path.join(managedNpmRoot(), "node_modules", packageName, "package.json"),
237-];
238-return candidates.find((candidate) => fs.existsSync(candidate));
189+return findPackageJson(packageName, [projectRoot, codexInstallPath(), managedNpmRoot()]);
239190}
240191241192function assertNpmDeps() {
@@ -253,7 +204,7 @@ function assertNpmDeps() {
253204throw new Error(`unexpected codex package name: ${pluginPackage.name}`);
254205}
255206256-const openAiCodexPackageJson = findPackageJson("@openai/codex");
207+const openAiCodexPackageJson = findCodexPackageJson("@openai/codex");
257208if (!openAiCodexPackageJson) {
258209throw new Error("missing @openai/codex dependency under .openclaw/npm");
259210}
@@ -277,7 +228,7 @@ function resolveCodexBin() {
277228if (candidate) {
278229return candidate;
279230}
280-const packageJson = findPackageJson("@openai/codex");
231+const packageJson = findCodexPackageJson("@openai/codex");
281232if (!packageJson) {
282233throw new Error("cannot resolve Codex binary without @openai/codex package");
283234}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。