diff --git a/changelog.d/fixes/13604-dashboard-logs-cursor-cli-version-client-leak.md b/changelog.d/fixes/13604-dashboard-logs-cursor-cli-version-client-leak.md new file mode 100644 index 000000000000..59489157346b --- /dev/null +++ b/changelog.d/fixes/13604-dashboard-logs-cursor-cli-version-client-leak.md @@ -0,0 +1 @@ +- **fix(build):** keep `node:fs`/`node:os`/`node:path` out of the client chunk graph for `/dashboard/logs` — a further, previously-undiscovered edge (`src/lib/oauth/constants/oauth.ts` importing `cursorAgentCliVersion.ts`, reachable from 250+ dashboard pages) of the same root cause already fixed in #13436/#13509/#13568. Moves the pinned CLI version string into a new import-free leaf module and extends the `client-bundle-no-server-only-10692` guard test to cover it ([#13604](https://github.com/diegosouzapw/OmniRoute/pull/13604)). diff --git a/open-sse/utils/cursorAgentCliVersion.ts b/open-sse/utils/cursorAgentCliVersion.ts index 91bedd220631..ba0dda576a28 100644 --- a/open-sse/utils/cursorAgentCliVersion.ts +++ b/open-sse/utils/cursorAgentCliVersion.ts @@ -19,12 +19,9 @@ import { } from "node:fs"; import { homedir } from "node:os"; import { join } from "node:path"; +import { CURSOR_AGENT_CLI_VERSION } from "./cursorAgentCliVersionPin.ts"; -/** - * Pinned Agent CLI build id used when no local install is found (typical - * headless OmniRoute). Bump when refreshing Cursor CLI impersonation. - */ -export const CURSOR_AGENT_CLI_VERSION = "2026.07.08-0c04a8a"; +export { CURSOR_AGENT_CLI_VERSION }; const VERSION_ID_RE = /^\d{4}\.\d{2}\.\d{2}-[0-9a-f]+$/; const CACHE_TTL_MS = 60 * 60 * 1000; diff --git a/open-sse/utils/cursorAgentCliVersionPin.ts b/open-sse/utils/cursorAgentCliVersionPin.ts new file mode 100644 index 000000000000..77830e3ede78 --- /dev/null +++ b/open-sse/utils/cursorAgentCliVersionPin.ts @@ -0,0 +1,14 @@ +/** + * Pinned Agent CLI build id used when no local install is found (typical + * headless OmniRoute). Bump when refreshing Cursor CLI impersonation. + * + * Deliberately import-free: cursorAgentCliVersion.ts (the full resolver: + * env → local install detect → disk-cached installer scrape → this pin) + * pulls in `node:fs`/`node:os`/`node:path`. Any client-reachable file that + * only needs the pin string -- not the full resolver -- must import it from + * here instead, or Turbopack/webpack chokes trying to bundle those Node + * builtins into the browser build ("the chunking context does not support + * external modules"). See #13436/#13509/#13568 for the same cut applied to + * other edges reaching this same resolver. + */ +export const CURSOR_AGENT_CLI_VERSION = "2026.07.08-0c04a8a"; diff --git a/src/lib/oauth/constants/oauth.ts b/src/lib/oauth/constants/oauth.ts index 8094bb58cd04..1a108f8144c1 100644 --- a/src/lib/oauth/constants/oauth.ts +++ b/src/lib/oauth/constants/oauth.ts @@ -19,7 +19,7 @@ import { GROK_BUILD_TOKEN_URL, } from "@omniroute/open-sse/config/grokBuild.ts"; import { resolvePublicCred } from "@omniroute/open-sse/utils/publicCreds.ts"; -import { CURSOR_AGENT_CLI_VERSION } from "@omniroute/open-sse/utils/cursorAgentCliVersion.ts"; +import { CURSOR_AGENT_CLI_VERSION } from "@omniroute/open-sse/utils/cursorAgentCliVersionPin.ts"; import { buildGitLabOAuthEndpoints, GITLAB_DUO_DEFAULT_BASE_URL } from "../gitlab"; /** @@ -381,7 +381,7 @@ export const KIRO_CONFIG = { // Cursor stores credentials in SQLite database: state.vscdb // Keys: cursorAuth/accessToken, cursorAuth/refreshToken, storage.serviceMachineId // Deep-control PKCE + refresh aligned with OpenCodex (lidge-jun/opencodex src/oauth/cursor.ts). -// clientVersion pin lives in open-sse/utils/cursorAgentCliVersion.ts — single source of truth. +// clientVersion pin lives in open-sse/utils/cursorAgentCliVersionPin.ts — single source of truth. export const CURSOR_CONFIG = { // API endpoints apiEndpoint: "https://api2.cursor.sh", diff --git a/tests/unit/client-bundle-no-server-only-10692.test.ts b/tests/unit/client-bundle-no-server-only-10692.test.ts index e29ae9d2fafb..da2d7589f239 100644 --- a/tests/unit/client-bundle-no-server-only-10692.test.ts +++ b/tests/unit/client-bundle-no-server-only-10692.test.ts @@ -37,6 +37,13 @@ const SERVER_ONLY = new Set([ "src/lib/db/migrationRunner.ts", "open-sse/utils/proxyFetch.ts", "open-sse/utils/tlsClient.ts", + // fs/os/path resolver behind CURSOR_AGENT_CLI_VERSION; the pin string alone + // lives in the import-free cursorAgentCliVersionPin.ts (single source of + // truth) precisely so client-reachable code can depend on the value + // without dragging this file in. Turbopack panic reproduced live via + // `open-sse/config/providerModels.ts` -> ... -> `src/lib/oauth/constants/oauth.ts` + // -> here, reached from /dashboard/logs. + "open-sse/utils/cursorAgentCliVersion.ts", ]); /**