diff --git a/codex-cli/build.mjs b/codex-cli/build.mjs index 465e8b92..16664d76 100644 --- a/codex-cli/build.mjs +++ b/codex-cli/build.mjs @@ -72,6 +72,9 @@ if (isDevBuild) { esbuild .build({ entryPoints: ["src/cli.tsx"], + // Do not bundle the contents of package.json at build time: always read it + // at runtime. + external: ["../package.json"], bundle: true, format: "esm", platform: "node", diff --git a/codex-cli/src/app.tsx b/codex-cli/src/app.tsx index 5d859db5..3f84935c 100644 --- a/codex-cli/src/app.tsx +++ b/codex-cli/src/app.tsx @@ -1,12 +1,13 @@ import type { ApprovalPolicy } from "./approvals"; import type { AppConfig } from "./utils/config"; +import type { TerminalChatSession } from "./utils/session.js"; import type { ResponseItem } from "openai/resources/responses/responses"; import TerminalChat from "./components/chat/terminal-chat"; import TerminalChatPastRollout from "./components/chat/terminal-chat-past-rollout"; import { checkInGit } from "./utils/check-in-git"; -import { CLI_VERSION, type TerminalChatSession } from "./utils/session.js"; import { onExit } from "./utils/terminal"; +import { CLI_VERSION } from "./version"; import { ConfirmInput } from "@inkjs/ui"; import { Box, Text, useApp, useStdin } from "ink"; import React, { useMemo, useState } from "react"; diff --git a/codex-cli/src/components/chat/terminal-chat-input.tsx b/codex-cli/src/components/chat/terminal-chat-input.tsx index 819b8ea3..e22ec82e 100644 --- a/codex-cli/src/components/chat/terminal-chat-input.tsx +++ b/codex-cli/src/components/chat/terminal-chat-input.tsx @@ -584,7 +584,7 @@ export default function TerminalChatInput({ try { const os = await import("node:os"); - const { CLI_VERSION } = await import("../../utils/session.js"); + const { CLI_VERSION } = await import("../../version.js"); const { buildBugReportUrl } = await import( "../../utils/bug-report.js" ); diff --git a/codex-cli/src/components/chat/terminal-chat.tsx b/codex-cli/src/components/chat/terminal-chat.tsx index 998a190c..f34ab792 100644 --- a/codex-cli/src/components/chat/terminal-chat.tsx +++ b/codex-cli/src/components/chat/terminal-chat.tsx @@ -24,9 +24,9 @@ import { uniqueById, } from "../../utils/model-utils.js"; import { createOpenAIClient } from "../../utils/openai-client.js"; -import { CLI_VERSION } from "../../utils/session.js"; import { shortCwd } from "../../utils/short-path.js"; import { saveRollout } from "../../utils/storage/save-rollout.js"; +import { CLI_VERSION } from "../../version.js"; import ApprovalModeOverlay from "../approval-mode-overlay.js"; import DiffOverlay from "../diff-overlay.js"; import HelpOverlay from "../help-overlay.js"; diff --git a/codex-cli/src/utils/agent/agent-loop.ts b/codex-cli/src/utils/agent/agent-loop.ts index 60749a23..97041def 100644 --- a/codex-cli/src/utils/agent/agent-loop.ts +++ b/codex-cli/src/utils/agent/agent-loop.ts @@ -11,6 +11,7 @@ import type { } from "openai/resources/responses/responses.mjs"; import type { Reasoning } from "openai/resources.mjs"; +import { CLI_VERSION } from "../../version.js"; import { OPENAI_TIMEOUT_MS, OPENAI_ORGANIZATION, @@ -24,7 +25,6 @@ import { parseToolCallArguments } from "../parsers.js"; import { responsesCreateViaChatCompletions } from "../responses.js"; import { ORIGIN, - CLI_VERSION, getSessionId, setCurrentModel, setSessionId, diff --git a/codex-cli/src/utils/check-updates.ts b/codex-cli/src/utils/check-updates.ts index 5e326c1c..6999c90c 100644 --- a/codex-cli/src/utils/check-updates.ts +++ b/codex-cli/src/utils/check-updates.ts @@ -1,7 +1,7 @@ import type { AgentName } from "package-manager-detector"; import { detectInstallerByPath } from "./package-manager-detector"; -import { CLI_VERSION } from "./session"; +import { CLI_VERSION } from "../version"; import boxen from "boxen"; import chalk from "chalk"; import { getLatestVersion } from "fast-npm-meta"; diff --git a/codex-cli/src/utils/session.ts b/codex-cli/src/utils/session.ts index 19867220..201929f6 100644 --- a/codex-cli/src/utils/session.ts +++ b/codex-cli/src/utils/session.ts @@ -1,9 +1,3 @@ -// Node ESM supports JSON imports behind an assertion. TypeScript's -// `resolveJsonModule` takes care of the typings. -import pkg from "../../package.json" assert { type: "json" }; - -// Read the version directly from package.json. -export const CLI_VERSION: string = (pkg as { version: string }).version; export const ORIGIN = "codex_cli_ts"; export type TerminalChatSession = { diff --git a/codex-cli/src/version.ts b/codex-cli/src/version.ts new file mode 100644 index 00000000..89f638df --- /dev/null +++ b/codex-cli/src/version.ts @@ -0,0 +1,8 @@ +// Note that "../package.json" is marked external in build.mjs. This ensures +// that the contents of package.json will always be read at runtime, which is +// preferable so we do not have to make a temporary change to package.json in +// the source tree to update the version number in the code. +import pkg from "../package.json" with { type: "json" }; + +// Read the version directly from package.json. +export const CLI_VERSION: string = (pkg as { version: string }).version; diff --git a/codex-cli/tests/check-updates.test.ts b/codex-cli/tests/check-updates.test.ts index 75ec8aaf..4f77fc51 100644 --- a/codex-cli/tests/check-updates.test.ts +++ b/codex-cli/tests/check-updates.test.ts @@ -9,7 +9,7 @@ import { renderUpdateCommand, } from "../src/utils/check-updates"; import { detectInstallerByPath } from "../src/utils/package-manager-detector"; -import { CLI_VERSION } from "../src/utils/session"; +import { CLI_VERSION } from "../src/version"; // In-memory FS mock let memfs: Record = {}; @@ -37,8 +37,8 @@ vi.mock("node:fs/promises", async (importOriginal) => { // Mock package name & CLI version const MOCK_PKG = "my-pkg"; +vi.mock("../src/version", () => ({ CLI_VERSION: "1.0.0" })); vi.mock("../package.json", () => ({ name: MOCK_PKG })); -vi.mock("../src/utils/session", () => ({ CLI_VERSION: "1.0.0" })); vi.mock("../src/utils/package-manager-detector", async (importOriginal) => { return { ...(await importOriginal()), diff --git a/codex-cli/vite.config.ts b/codex-cli/vite.config.ts deleted file mode 100644 index 669a10f2..00000000 --- a/codex-cli/vite.config.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { defineConfig } from 'vite'; - -// Provide a stub Vite config in the CLI package to avoid resolving a parent-level vite.config.js -export default defineConfig({}); \ No newline at end of file diff --git a/codex-cli/vitest.config.ts b/codex-cli/vitest.config.ts new file mode 100644 index 00000000..97af07fc --- /dev/null +++ b/codex-cli/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "vitest/config"; + +/** + * Vitest configuration for the CLI package. + * Disables worker threads to avoid pool recursion issues in sandbox. + */ +export default defineConfig({ + test: { + threads: false, + environment: "node", + }, +});