diff --git a/apps/server/src/provider/security/CommandCenterProviderIsolation.test.ts b/apps/server/src/provider/security/CommandCenterProviderIsolation.test.ts index a37d649bcf31..63d3e90f39da 100644 --- a/apps/server/src/provider/security/CommandCenterProviderIsolation.test.ts +++ b/apps/server/src/provider/security/CommandCenterProviderIsolation.test.ts @@ -541,6 +541,47 @@ it.layer(NodeServices.layer)("CommandCenter provider runtime isolation", (it) => }), ); + it.effect("resolves the native executable behind a canonical Linux npm launcher", () => + Effect.gen(function* () { + const fileSystem = yield* FileSystem.FileSystem; + const path = yield* Path.Path; + const root = yield* fileSystem.makeTempDirectoryScoped({ prefix: "cc-linux-runtime-" }); + const packageRoot = path.join(root, "node_modules", "@openai", "codex"); + const commandPath = path.join(packageRoot, "bin", "codex.js"); + const platformPackageRoot = path.join( + packageRoot, + "node_modules", + "@openai", + "codex-linux-x64", + ); + const nativePath = path.join( + platformPackageRoot, + "vendor", + "x86_64-unknown-linux-musl", + "bin", + "codex", + ); + yield* writeFile(commandPath, "#!/usr/bin/env node\n"); + yield* writeFile( + path.join(platformPackageRoot, "package.json"), + '{"name":"@openai/codex-linux-x64","version":"0.0.0"}\n', + ); + yield* fileSystem.makeDirectory(path.dirname(nativePath), { recursive: true }); + yield* fileSystem.writeFile(nativePath, Uint8Array.from([0x7f, 0x45, 0x4c, 0x46])); + + NodeAssert.equal( + yield* resolveCommandCenterCodexRuntimeExecutable({ + commandPath, + platform: "linux", + architecture: "x64", + fileSystem, + path, + }), + yield* fileSystem.realPath(nativePath), + ); + }), + ); + it.effect( "grants read-only access to the exact pointer and common metadata for a valid worktree", () => diff --git a/apps/server/src/provider/security/CommandCenterProviderIsolation.ts b/apps/server/src/provider/security/CommandCenterProviderIsolation.ts index 34355c7c1395..6e6e4b68aaf6 100644 --- a/apps/server/src/provider/security/CommandCenterProviderIsolation.ts +++ b/apps/server/src/provider/security/CommandCenterProviderIsolation.ts @@ -387,7 +387,7 @@ function codexHomeError(issue: string, cause?: unknown): CommandCenterCodexHomeI }); } -/** Resolve the native executable behind the official Windows npm launcher without executing it. */ +/** Resolve the native executable behind the official Codex npm launcher without executing it. */ export const resolveCommandCenterCodexRuntimeExecutable = Effect.fn( "CommandCenterProviderIsolation.resolveCodexRuntimeExecutable", )(function* (input: ResolveCommandCenterCodexRuntimeInput) { @@ -399,51 +399,57 @@ export const resolveCommandCenterCodexRuntimeExecutable = Effect.fn( codexHomeError("Command Center could not canonicalize the Codex runtime launcher.", cause), ), ); - if (input.platform !== "win32" || path.extname(canonicalCommandPath).toLowerCase() === ".exe") { + if ( + (input.platform === "win32" && path.extname(canonicalCommandPath).toLowerCase() === ".exe") || + (input.platform !== "win32" && path.basename(canonicalCommandPath) !== "codex.js") + ) { return canonicalCommandPath; } - const target = - input.architecture === "arm64" - ? { - packageName: "@openai/codex-win32-arm64", - triple: "aarch64-pc-windows-msvc", - } - : input.architecture === "x64" - ? { - packageName: "@openai/codex-win32-x64", - triple: "x86_64-pc-windows-msvc", - } - : undefined; + const targets: Readonly< + Record + > = { + "linux:arm64": ["@openai/codex-linux-arm64", "aarch64-unknown-linux-musl", "codex"], + "linux:x64": ["@openai/codex-linux-x64", "x86_64-unknown-linux-musl", "codex"], + "darwin:arm64": ["@openai/codex-darwin-arm64", "aarch64-apple-darwin", "codex"], + "darwin:x64": ["@openai/codex-darwin-x64", "x86_64-apple-darwin", "codex"], + "win32:arm64": ["@openai/codex-win32-arm64", "aarch64-pc-windows-msvc", "codex.exe"], + "win32:x64": ["@openai/codex-win32-x64", "x86_64-pc-windows-msvc", "codex.exe"], + }; + const target = targets[`${input.platform}:${input.architecture}`]; if (target === undefined) { return yield* codexHomeError( - `Command Center does not support the '${input.architecture}' Windows Codex runtime architecture.`, + `Command Center does not support the '${input.architecture}' ${input.platform} Codex runtime architecture.`, ); } - const codexPackageRoot = path.join( - path.dirname(canonicalCommandPath), - "node_modules", - "@openai", - "codex", - ); - const codexLauncherPath = path.join(codexPackageRoot, "bin", "codex.js"); + const codexLauncherPath = + path.basename(canonicalCommandPath) === "codex.js" + ? canonicalCommandPath + : path.join( + path.dirname(canonicalCommandPath), + "node_modules", + "@openai", + "codex", + "bin", + "codex.js", + ); if (!(yield* fileSystem.exists(codexLauncherPath))) { return yield* codexHomeError( - "Command Center requires the official native Codex package; the configured Windows launcher does not have a verifiable @openai/codex installation.", + "Command Center requires the official native Codex package; the configured launcher does not have a verifiable @openai/codex installation.", ); } + const [packageName, triple, executableName] = target; const packageJsonPath = yield* Effect.try({ - try: () => - NodeModule.createRequire(codexLauncherPath).resolve(`${target.packageName}/package.json`), + try: () => NodeModule.createRequire(codexLauncherPath).resolve(`${packageName}/package.json`), catch: (cause) => codexHomeError( - `Command Center could not resolve the native ${target.packageName} package. Reinstall or update @openai/codex.`, + `Command Center could not resolve the native ${packageName} package. Reinstall or update @openai/codex.`, cause, ), }); - const platformVendorRoot = path.join(path.dirname(packageJsonPath), "vendor", target.triple); + const platformVendorRoot = path.join(path.dirname(packageJsonPath), "vendor", triple); const nativeExecutableCandidates = [ - path.join(platformVendorRoot, "bin", "codex.exe"), - path.join(platformVendorRoot, "codex", "codex.exe"), + path.join(platformVendorRoot, "bin", executableName), + path.join(platformVendorRoot, "codex", executableName), ]; for (const candidate of nativeExecutableCandidates) { if (yield* fileSystem.exists(candidate)) { @@ -457,7 +463,7 @@ export const resolveCommandCenterCodexRuntimeExecutable = Effect.fn( } } return yield* codexHomeError( - "Command Center found the Windows Codex package but not its native codex.exe. Reinstall @openai/codex with optional dependencies enabled.", + `Command Center found the ${input.platform} Codex package but not its native ${executableName}. Reinstall @openai/codex with optional dependencies enabled.`, ); }); diff --git a/apps/web/src/components/usage/UsagePage.tsx b/apps/web/src/components/usage/UsagePage.tsx index f01d2619246a..46759b7d41f2 100644 --- a/apps/web/src/components/usage/UsagePage.tsx +++ b/apps/web/src/components/usage/UsagePage.tsx @@ -36,8 +36,8 @@ const WINDOW_OPTIONS = [ export function UsagePage() { const [windowSelection, setWindowSelection] = useState(() => ({ - days: 30, - window: makeWindow(30), + days: 1, + window: makeWindow(1, undefined, "hour"), })); const [metric, setMetric] = useState("cost"); const [breakdown, setBreakdown] = useState<"model" | "time">("model");