From 7705aede6feb18767e22416e83ba1888efbfa112 Mon Sep 17 00:00:00 2001 From: Koosha Pari Date: Sat, 12 Sep 2026 16:47:42 -0700 Subject: [PATCH] fix(combos): remove open-sse imports from controlCenter.ts client boundary (#13474) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit controlCenter.ts is imported by the "use client" component ComboControlCenterClient.tsx. PR #13283 added imports of resolveComboTargetModelStr (open-sse/services/combo/) and resolveProviderAlias (open-sse/services/model.ts) which transitively pull the DB/playwright/sharp chain into the browser bundle, causing 168 Turbopack "Module not found" errors on npm run build:release. Fix: remove both open-sse imports and simplify providerFromModel() to extract the provider prefix directly from the model string (slash- delimited). This matches the approach already taken on main. The label accuracy trade-off (no alias resolution in the control center display) is acceptable — the control center shows the prefix the caller used, not the resolved upstream id. Changes: - src/lib/combos/controlCenter.ts: remove resolveComboTargetModelStr and resolveProviderAlias imports, simplify providerFromModel() - tests/unit/controlcenter-client-boundary-13474.test.ts: 2 new tests verifying no open-sse/services/ or open-sse/config/ imports Fixes #13474 --- src/lib/combos/controlCenter.ts | 12 +---- ...ontrolcenter-client-boundary-13474.test.ts | 52 +++++++++++++++++++ 2 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 tests/unit/controlcenter-client-boundary-13474.test.ts diff --git a/src/lib/combos/controlCenter.ts b/src/lib/combos/controlCenter.ts index 92a87b2738a0..d606d2ec93b2 100644 --- a/src/lib/combos/controlCenter.ts +++ b/src/lib/combos/controlCenter.ts @@ -1,6 +1,4 @@ import { normalizeComboModels, type ComboStep } from "./steps"; -import { resolveComboTargetModelStr } from "../../../open-sse/services/combo/opencodeTargetAlias.ts"; -import { resolveProviderAlias } from "../../../open-sse/services/model.ts"; type JsonRecord = Record; @@ -110,15 +108,9 @@ function toString(value: unknown): string | null { function providerFromModel(model: string | null | undefined): string | null { if (!model) return null; - // #11912: resolve through the same "opencode" -> "oc" combo-target alias - // treatment (and then the general alias table) that target resolution - // applies before dispatch, so this label matches what actually executed - // upstream instead of a raw, un-aliased prefix slice. - const normalized = resolveComboTargetModelStr(model); - const slashIndex = normalized.indexOf("/"); + const slashIndex = model.indexOf("/"); if (slashIndex <= 0) return null; - const prefix = normalized.slice(0, slashIndex); - return resolveProviderAlias(prefix) || prefix; + return model.slice(0, slashIndex); } function normalizeSuccessRate(value: unknown): number { diff --git a/tests/unit/controlcenter-client-boundary-13474.test.ts b/tests/unit/controlcenter-client-boundary-13474.test.ts new file mode 100644 index 000000000000..ab64367ea4e2 --- /dev/null +++ b/tests/unit/controlcenter-client-boundary-13474.test.ts @@ -0,0 +1,52 @@ +/** + * @file controlcenter-client-boundary-13474.test.ts + * @description Verifies that src/lib/combos/controlCenter.ts has no + * transitive imports from open-sse/services/ or open-sse/config/, which + * would pull the DB/playwright chain into the "use client" bundle and + * break production builds. (#13474) + */ + +import test from "node:test"; +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { join } from "node:path"; + +test("controlCenter.ts does not import from open-sse/services/ or open-sse/config/", () => { + const filePath = join(process.cwd(), "src/lib/combos/controlCenter.ts"); + const content = readFileSync(filePath, "utf8"); + + // Check for direct imports from problematic open-sse paths + const problematicPatterns = [ + /from\s+["'].*open-sse\/services\//, + /from\s+["'].*open-sse\/config\//, + /import\s+.*open-sse\/services\//, + /import\s+.*open-sse\/config\//, + ]; + + for (const pattern of problematicPatterns) { + const match = content.match(pattern); + assert.ok( + !match, + `controlCenter.ts should not import from open-sse/services/ or open-sse/config/ — ` + + `found: ${match?.[0]}` + ); + } +}); + +test("controlCenter.ts only imports from safe internal modules", () => { + const filePath = join(process.cwd(), "src/lib/combos/controlCenter.ts"); + const content = readFileSync(filePath, "utf8"); + + // Extract all import lines + const importLines = content + .split("\n") + .filter((line) => line.trimStart().startsWith("import ")); + + // Each import should be from a safe path (no open-sse) + for (const line of importLines) { + assert.ok( + !line.includes("open-sse"), + `controlCenter.ts has unsafe import: ${line.trim()}` + ); + } +});