From 8c170480dd9c03724d7bebf31715a88b7ac5ae5d Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Wed, 3 Jun 2026 07:59:20 -0700 Subject: [PATCH] fix(compound-engineering): break dashboard dependency cycle A new workspace-acyclicity invariant on main (run via the PR merge) flagged compound-engineering -> @fusion/dashboard -> compound-engineering: the plugin is listed in @fusion/dashboard's deps (for view loading) AND declared @fusion/dashboard as a runtime dependency, which the cycle check (deps+devDeps) and the 'bundled plugins must not depend on host packages' check both reject. The plugin's only @fusion/dashboard use is the type-only PluginDashboardViewContext import. Drop the @fusion/dashboard dependency and resolve that type via an ambient dashboard-interop.d.ts + tsconfig paths mapping (the fusion-plugin-dependency-graph interop pattern). Breaks the cycle; the host passes the real context at runtime. --- .../package.json | 1 - .../src/dashboard-interop.d.ts | 34 +++++++++++++++++++ .../tsconfig.json | 7 ++-- pnpm-lock.yaml | 3 -- 4 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 plugins/fusion-plugin-compound-engineering/src/dashboard-interop.d.ts diff --git a/plugins/fusion-plugin-compound-engineering/package.json b/plugins/fusion-plugin-compound-engineering/package.json index 80b2b8e082..ddc60d7f07 100644 --- a/plugins/fusion-plugin-compound-engineering/package.json +++ b/plugins/fusion-plugin-compound-engineering/package.json @@ -20,7 +20,6 @@ }, "dependencies": { "@fusion/core": "workspace:*", - "@fusion/dashboard": "workspace:*", "@fusion/plugin-sdk": "workspace:*", "lucide-react": "^0.542.0", "react": "^19.0.0", diff --git a/plugins/fusion-plugin-compound-engineering/src/dashboard-interop.d.ts b/plugins/fusion-plugin-compound-engineering/src/dashboard-interop.d.ts new file mode 100644 index 0000000000..a51b4163de --- /dev/null +++ b/plugins/fusion-plugin-compound-engineering/src/dashboard-interop.d.ts @@ -0,0 +1,34 @@ +// Ambient declaration for the dashboard host's plugin-view context, so this +// bundled plugin can consume the type WITHOUT a runtime dependency on +// `@fusion/dashboard` (a host package). Depending on the host would create a +// dashboard -> plugin -> dashboard cycle and violate the workspace-acyclicity / +// "bundled plugins must not depend on host packages" invariants. The host +// passes the real object at runtime; this minimal structural shape is enough to +// type-check the fields this plugin actually reads. Mirrors the interop pattern +// used by fusion-plugin-dependency-graph. +declare module "@fusion/dashboard/app/plugins/types" { + import type { ReactNode } from "react"; + import type { Task, TaskDetail, WorkflowStep } from "@fusion/core"; + + export type DetailTaskTab = + | "definition" | "logs" | "changes" | "comments" | "model" | "workflow" | "pr" | "retries"; + export type PluginToastType = "success" | "error" | "warning" | "info"; + + export interface PluginCustomEvent { + event: string; + payload: unknown; + } + + export interface PluginDashboardViewContext { + projectId?: string; + tasks: Task[]; + workflowSteps: WorkflowStep[]; + openTaskDetail: (task: Task | TaskDetail, initialTab?: DetailTaskTab) => void; + renderTaskCard?: (task: Task | TaskDetail) => ReactNode; + addToast?: (message: string, type?: PluginToastType) => void; + subscribePluginEvents?: ( + pluginId: string, + onEvent: (event: PluginCustomEvent) => void, + ) => () => void; + } +} diff --git a/plugins/fusion-plugin-compound-engineering/tsconfig.json b/plugins/fusion-plugin-compound-engineering/tsconfig.json index 710a839f68..76979dbfb1 100644 --- a/plugins/fusion-plugin-compound-engineering/tsconfig.json +++ b/plugins/fusion-plugin-compound-engineering/tsconfig.json @@ -4,7 +4,10 @@ "outDir": "dist", "rootDir": "src", "jsx": "react-jsx", - "types": ["node", "vitest/globals"] + "types": ["node", "vitest/globals"], + "paths": { + "@fusion/dashboard/app/plugins/types": ["./src/dashboard-interop.d.ts"] + } }, - "include": ["src/**/*.ts", "src/**/*.tsx"] + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3ebfc96757..89a5acb369 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -700,9 +700,6 @@ importers: '@fusion/core': specifier: workspace:* version: link:../../packages/core - '@fusion/dashboard': - specifier: workspace:* - version: link:../../packages/dashboard '@fusion/plugin-sdk': specifier: workspace:* version: link:../../packages/plugin-sdk