From 29d94e0fa3723d21bbdbf1b7461ca2ef1d50bfee Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Mon, 17 Aug 2026 15:58:58 -0700 Subject: [PATCH] fix: drop dependency-graph plugin's use of removed stuck-task tagging The dependency-graph plugin imported the deleted taskStuck util through its dashboard interop shim, breaking the dashboard vite build. Remove the isStuck gate from graph nodes, the taskStuckTimeoutMs prop threading, the taskStuck module declaration from dashboard-interop.d.ts, and the stalled-card-as-stuck test coverage. Covered by the existing remove-stuck-task-tagging changeset. Co-Authored-By: Claude Fable 5 --- .../src/DependencyGraph.tsx | 3 -- .../src/GraphTaskNode.tsx | 13 +++---- .../src/__tests__/GraphTaskNode.drag.test.tsx | 1 - .../src/__tests__/GraphTaskNode.test.tsx | 35 ++----------------- .../src/__tests__/interactions.test.tsx | 1 - .../src/dashboard-interop.d.ts | 23 +++--------- 6 files changed, 10 insertions(+), 66 deletions(-) diff --git a/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.tsx b/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.tsx index 5b77ad424f..4b52beab39 100644 --- a/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.tsx +++ b/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.tsx @@ -31,7 +31,6 @@ export interface DependencyGraphProps { onDeleteTask?: (id: string, options?: { removeDependencyReferences?: boolean }) => Promise; onRetryTask?: (id: string) => Promise; onOpenDetailWithTab?: (task: Task, initialTab: "changes") => void; - taskStuckTimeoutMs?: number; onOpenMission?: (missionId: string) => void; onMoveTask?: (id: string, column: Task["column"], optionsOrPosition?: { preserveProgress?: boolean } | number) => Promise; lastFetchTimeMs?: number; @@ -53,7 +52,6 @@ export function DependencyGraph({ onDeleteTask, onRetryTask, onOpenDetailWithTab, - taskStuckTimeoutMs, onOpenMission, onMoveTask, lastFetchTimeMs, @@ -500,7 +498,6 @@ export function DependencyGraph({ onDeleteTask={onDeleteTask} onRetryTask={onRetryTask} onOpenDetailWithTab={onOpenDetailWithTab} - taskStuckTimeoutMs={taskStuckTimeoutMs} onOpenMission={onOpenMission} onMoveTask={onMoveTask} lastFetchTimeMs={lastFetchTimeMs} diff --git a/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.tsx b/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.tsx index 123003d172..67b316c70c 100644 --- a/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.tsx +++ b/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.tsx @@ -3,7 +3,6 @@ import type { TraitFlags } from "@fusion/core"; import type { GraphPosition } from "./types.js"; import { useNodeDrag } from "./hooks/useNodeDrag.js"; import { TaskCard } from "@fusion/dashboard/app/components/TaskCard"; -import { isTaskStuck } from "@fusion/dashboard/app/utils/taskStuck"; import "./GraphTaskNode.css"; import "./GraphHighlight.css"; import "./styles/drag.css"; @@ -23,7 +22,6 @@ type TaskCardBridgeProps = Pick< | "onDeleteTask" | "onRetryTask" | "onOpenDetailWithTab" - | "taskStuckTimeoutMs" | "onOpenMission" | "onMoveTask" | "lastFetchTimeMs" @@ -34,10 +32,8 @@ export interface GraphTaskNodeProps extends TaskCardBridgeProps, Pick> = onOpenDetailWithTab: vi.fn(), onMoveTask: vi.fn(), onOpenMission: vi.fn(), - taskStuckTimeoutMs: 1000, lastFetchTimeMs: Date.now(), workflowStepNameLookup: new Map(), ...overrides, diff --git a/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.test.tsx b/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.test.tsx index 47a04bb50d..e1e1ac7780 100644 --- a/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.test.tsx +++ b/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.test.tsx @@ -48,7 +48,6 @@ function createProps(task: Task) { onOpenDetailWithTab: vi.fn(), onMoveTask: vi.fn(), onOpenMission: vi.fn(), - taskStuckTimeoutMs: 60_000, lastFetchTimeMs: Date.now(), workflowStepNameLookup: new Map(), }; @@ -384,38 +383,8 @@ describe("GraphTaskNode", () => { }); }); -/* -FNXC:WorkflowLifecycleColumns 2026-07-31-15:30: -THE INVARIANT: a stalled card in the board's OWN wip lane reads as stuck, not as healthily running. - -`isTaskStuck` was called without its `columnFlags` argument, so `isWipColumnRole` fell back to the -literal `in-progress`. On a renamed board no graph card could ever be stuck — and because `isStuck` -gates `isActive`, a wedged card rendered with the ACTIVE styling instead: the graph said "running" -about a task that had not moved in hours, while the main board showed the same card as stuck. - -That asymmetry between two views of one task is the whole defect, and it is what this pins. - -Reverted (the 4th argument dropped, or the flags not threaded from the host context), the first case -gets the `--active` class back and fails. -*/ -describe("stuck detection on a renamed board", () => { - const STALE_MS = 120_000; - - function stalledCard() { - return createTask({ - column: "building", - status: "executing", - updatedAt: new Date(Date.now() - STALE_MS).toISOString(), - } as Partial); - } - - it("treats a stalled card in a RENAMED wip lane as stuck, not active", () => { - const props = createProps(stalledCard()); - render(); - - expect(screen.getByTestId("graph-task-node-FN-TEST").className).not.toContain("graph-task-node--active"); - }); - +// FNXC:StuckTagRemoval 2026-08-17-22:30: stuck-task tagging removed from the dashboard; the stalled-card-as-stuck coverage went with it. +describe("active styling", () => { it("still reads a legacy in-progress card as active when it is fresh", () => { const props = createProps(createTask({ column: "in-progress", status: "executing", updatedAt: new Date().toISOString() } as Partial)); render(); diff --git a/plugins/fusion-plugin-dependency-graph/src/__tests__/interactions.test.tsx b/plugins/fusion-plugin-dependency-graph/src/__tests__/interactions.test.tsx index ec15f8a624..e1d898906b 100644 --- a/plugins/fusion-plugin-dependency-graph/src/__tests__/interactions.test.tsx +++ b/plugins/fusion-plugin-dependency-graph/src/__tests__/interactions.test.tsx @@ -157,7 +157,6 @@ describe("dependency graph interactions", () => { onOpenDetailWithTab={vi.fn()} onMoveTask={vi.fn()} onOpenMission={vi.fn()} - taskStuckTimeoutMs={1_000} lastFetchTimeMs={Date.now()} workflowStepNameLookup={new Map()} />, diff --git a/plugins/fusion-plugin-dependency-graph/src/dashboard-interop.d.ts b/plugins/fusion-plugin-dependency-graph/src/dashboard-interop.d.ts index ddcb29ee92..499100d807 100644 --- a/plugins/fusion-plugin-dependency-graph/src/dashboard-interop.d.ts +++ b/plugins/fusion-plugin-dependency-graph/src/dashboard-interop.d.ts @@ -1,21 +1,7 @@ -declare module "@fusion/dashboard/app/utils/taskStuck" { - import type { Task, TraitFlags } from "@fusion/core"; - - /* FNXC:WorkflowLifecycleColumns 2026-07-31-15:30: the 4th parameter existed upstream and this shim - did not declare it, so the plugin could not pass resolved traits even once it had them — and - `isWipColumnRole` fell back to the literal, meaning NO card in the graph was ever shown stuck on a - renamed board while the same card showed stuck correctly on the main board. */ - export function isTaskStuck( - task: Task, - /* FNXC:PluginInteropDrift 2026-07-31-07:50: positionally REQUIRED in the real signature - (`number | undefined`), not optional — a mirror that is merely approximate is the drift this - file already caused once. Found by check-plugin-interop-drift. */ - taskStuckTimeoutMs: number | undefined, - lastFetchTimeMs?: number, - columnFlags?: Partial, - ): boolean; -} - +/* +FNXC:StuckTagRemoval 2026-08-17-22:30: +The taskStuck shim was deleted with the dashboard's stuck-task tagging; the host module no longer exists. +*/ declare module "@fusion/dashboard/app/plugins/types" { import type { ReactNode } from "react"; import type { Task, TaskDetail, TraitFlags, WorkflowStep } from "@fusion/core"; @@ -57,7 +43,6 @@ declare module "@fusion/dashboard/app/components/TaskCard" { onDeleteTask?: (id: string, options?: { removeDependencyReferences?: boolean }) => Promise; onRetryTask?: (id: string) => Promise; onOpenDetailWithTab?: (task: Task | TaskDetail, initialTab: "changes") => void; - taskStuckTimeoutMs?: number; onOpenMission?: (missionId: string) => void; onMoveTask?: (id: string, column: Column, optionsOrPosition?: { preserveProgress?: boolean } | number) => Promise; lastFetchTimeMs?: number;