


















@@ -1,5 +1,6 @@
1-import { constants as fsConstants } from "node:fs";
1+import { constants as fsConstants, readFileSync } from "node:fs";
22import { access } from "node:fs/promises";
3+import { createRequire } from "node:module";
34import path from "node:path";
45import { fileURLToPath } from "node:url";
56import type { CodexAppServerStartOptions } from "./config.js";
@@ -66,15 +67,72 @@ function resolveManagedCodexAppServerCommandCandidates(
6667): string[] {
6768const pathApi = pathForPlatform(platform);
6869const commandName = platform === "win32" ? "codex.cmd" : "codex";
69-const roots = [
70+const roots = resolveManagedCodexAppServerCandidateRoots(pluginRoot, platform);
71+return [
72+ ...new Set([
73+ ...roots.map((root) => pathApi.join(root, "node_modules", ".bin", commandName)),
74+ ...resolveManagedCodexPackageBinCandidates(roots, platform),
75+]),
76+];
77+}
78+79+function resolveManagedCodexAppServerCandidateRoots(
80+pluginRoot: string,
81+platform: NodeJS.Platform,
82+): string[] {
83+const pathApi = pathForPlatform(platform);
84+return [
7085pluginRoot,
7186pathApi.dirname(pluginRoot),
7287pathApi.dirname(pathApi.dirname(pluginRoot)),
7388isDistExtensionRoot(pluginRoot, platform)
7489 ? pathApi.dirname(pathApi.dirname(pathApi.dirname(pluginRoot)))
7590 : null,
7691].filter((root): root is string => Boolean(root));
77-return [...new Set(roots.map((root) => pathApi.join(root, "node_modules", ".bin", commandName)))];
92+}
93+94+function resolveManagedCodexPackageBinCandidates(
95+roots: readonly string[],
96+platform: NodeJS.Platform,
97+): string[] {
98+if (platform === "win32") {
99+return [];
100+}
101+102+const candidates: string[] = [];
103+for (const root of roots) {
104+const candidate = resolveManagedCodexPackageBinCandidate(root);
105+if (candidate) {
106+candidates.push(candidate);
107+}
108+}
109+return candidates;
110+}
111+112+function resolveManagedCodexPackageBinCandidate(root: string): string | null {
113+try {
114+const requireFromRoot = createRequire(path.join(root, "package.json"));
115+const packageJsonPath = requireFromRoot.resolve(
116+`${MANAGED_CODEX_APP_SERVER_PACKAGE}/package.json`,
117+);
118+const packageRoot = path.dirname(packageJsonPath);
119+const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8")) as {
120+bin?: unknown;
121+};
122+const binPath =
123+typeof packageJson.bin === "string"
124+ ? packageJson.bin
125+ : isRecord(packageJson.bin) && typeof packageJson.bin.codex === "string"
126+ ? packageJson.bin.codex
127+ : null;
128+return binPath ? path.resolve(packageRoot, binPath) : null;
129+} catch {
130+return null;
131+}
132+}
133+134+function isRecord(value: unknown): value is Record<string, unknown> {
135+return typeof value === "object" && value !== null;
78136}
7913780138function isDistExtensionRoot(pluginRoot: string, platform: NodeJS.Platform): boolean {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。