From 93a403af67df15bad2007a99b9a9f4e3639cb6a2 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sun, 26 Jul 2026 13:22:18 -0700 Subject: [PATCH] fix(dashboard): import delete-attribution constants via browser-safe subpath The client bundle aliases `@fusion/core` to the leaf `core/src/types.ts` to keep Node-only dependencies out of the browser, so a package-root import of `FUSION_CLIENT_HEADER`/`FUSION_DASHBOARD_UI_CLIENT` typechecked but failed `vite build`: "FUSION_CLIENT_HEADER" is not exported by "../core/src/types.ts" Follow the documented pattern instead of widening the root alias: declare a `./task-delete-attribution` subpath export, add the matching Vite alias ahead of the broader `@fusion/core` key (Vite matches in order), register the module in the browser-safe-core allowlist, and import the subpath from the client. `task-delete-attribution.ts` has no imports at all, so it is a safe leaf. `app/utils/detectContentLanguage.ts` already warned about exactly this trap; the miss was mine for verifying with typecheck, lint and test:gate but not `pnpm build`, which is one of the four checks CI blocks on. Co-Authored-By: Claude Opus 5 (1M context) --- packages/core/package.json | 5 +++++ packages/dashboard/app/api/client.ts | 3 ++- packages/dashboard/vite.config.ts | 7 +++++++ scripts/lib/dashboard-browser-safe-core-modules.json | 5 +++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/core/package.json b/packages/core/package.json index 7d9b779887..94d3c8d98c 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -24,6 +24,11 @@ "source": "./src/gh-cli.ts", "import": "./dist/gh-cli.js" }, + "./task-delete-attribution": { + "types": "./src/task-delete-attribution.ts", + "source": "./src/task-delete-attribution.ts", + "import": "./dist/task-delete-attribution.js" + }, "./detect-content-language": { "types": "./src/detect-content-language.ts", "source": "./src/detect-content-language.ts", diff --git a/packages/dashboard/app/api/client.ts b/packages/dashboard/app/api/client.ts index d2e0574e74..b054390c41 100644 --- a/packages/dashboard/app/api/client.ts +++ b/packages/dashboard/app/api/client.ts @@ -2,7 +2,8 @@ * FNXC:CodeOrganization 2026-07-15-16:00: * Dashboard API client core (fetch wrapper + ApiRequestError). */ -import { FUSION_CLIENT_HEADER, FUSION_DASHBOARD_UI_CLIENT } from "@fusion/core"; +// FNXC:TaskDeleteAttribution 2026-07-26-17:05: import the browser-safe leaf, not the package root — the root alias resolves to `core/src/types.ts` in the client bundle and does not carry these constants. +import { FUSION_CLIENT_HEADER, FUSION_DASHBOARD_UI_CLIENT } from "@fusion/core/task-delete-attribution"; import { getAuthToken, withTokenHeader } from "../auth"; import type { DedupeOptions } from "./dedupe"; diff --git a/packages/dashboard/vite.config.ts b/packages/dashboard/vite.config.ts index f5de60e987..f43737f518 100644 --- a/packages/dashboard/vite.config.ts +++ b/packages/dashboard/vite.config.ts @@ -134,6 +134,13 @@ export default defineConfig({ The dashboard core-import scanner enforces this alias boundary for both relative core/src and package-subpath value imports. Add a new browser leaf only after its full dependency graph is reviewed and it has a dated entry in scripts/lib/dashboard-browser-safe-core-modules.json. */ + /* + FNXC:TaskDeleteAttribution 2026-07-26-17:05: + The delete-attribution constants (`x-fusion-client` header name + the dashboard-UI token) are shared by the browser client that STAMPS the header and the route that READS it, so both sides cannot drift apart into two spellings of the same string. + `task-delete-attribution.ts` imports nothing at all, so it is a safe browser leaf; alias its subpath rather than widening the `@fusion/core` alias, which would drag the Node-heavy index into the client bundle. + Ordered before the `@fusion/core` entry because Vite matches aliases in order and the broader key would otherwise swallow this subpath — the exact failure this line was added to fix (`"FUSION_CLIENT_HEADER" is not exported by ../core/src/types.ts`). + */ + "@fusion/core/task-delete-attribution": resolve(__dirname, "../core/src/task-delete-attribution.ts"), "@fusion/core/detect-content-language": resolve(__dirname, "../core/src/detect-content-language.ts"), "@fusion/core": resolve(__dirname, "../core/src/types.ts"), "@fusion/dashboard/app/components/TaskCard": resolve(__dirname, "app/components/TaskCard.tsx"), diff --git a/scripts/lib/dashboard-browser-safe-core-modules.json b/scripts/lib/dashboard-browser-safe-core-modules.json index 4b263806ef..e256bf5b07 100644 --- a/scripts/lib/dashboard-browser-safe-core-modules.json +++ b/scripts/lib/dashboard-browser-safe-core-modules.json @@ -55,6 +55,11 @@ "reason": "2026-07-16: Language detection is pure shared string logic with an explicit Vite subpath alias.", "verifiedAt": "2026-07-16" }, + { + "module": "task-delete-attribution", + "reason": "2026-07-26: Delete caller-attribution constants and the pure header resolver are shared by the browser client that stamps `x-fusion-client` and the route that reads it; the module has no imports at all.", + "verifiedAt": "2026-07-26" + }, { "module": "live-agent-count", "reason": "2026-07-21: FN-8453 shares pure workflow-trait-based Running and Waiting predicates with dashboard capacity indicators; its dependency graph has no Node-only modules.",