The dashboard task-create route now uses the distributed task ID allocator (FN-3450). On projects whose tasks had been allocated through the legacy config.nextId counter, the allocator's `ensureStateRow` was seeding a fresh prefix at sequence 1, so new tasks restarted at FN-001 even when FN-3700 already existed. ensureStateRow now seeds past: - the legacy config.nextId counter (when configured taskPrefix matches), and - one past the highest numeric suffix on any existing tasks/archivedTasks row for the prefix. A regression test seeds FN-3700 in a fresh DB and asserts the next reservation returns FN-3701, not FN-001. Plugin dashboard view contracts are now exposed via a slim type-only module (`@fusion/dashboard/app/plugins/types`). External plugin tsc builds previously imported `pluginViewRegistry`, transitively pulling in dashboard runtime sources (React components, CSS, lucide-react). The dependency-graph plugin's import + path mapping is updated to use the new module. Schema housekeeping: drop unused scaffolding tables left over from an earlier migration via a new idempotent migration (v67). Fresh DBs see no change; existing DBs that ran the older migration get the orphan tables dropped on next init. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fusion-plugin-dependency-graph
Plugin-provided top-level Graph dashboard view for Fusion.
Rendering approach
- Filtering: includes
triage,todo,in-progress,in-review; excludesdone,archived - Graph build: edges are resolved only from
task.dependenciesassource=dependent,target=dependency - Orphan dependency handling: if a visible task depends on an excluded/missing dependency (for example
done/archivedafter filtering), the missing edge is silently dropped and graph rendering continues without broken connectors - Auto-layout: Sugiyama-style layered layout (
computeAutoLayout) groups nodes by dependency depth and spaces layers consistently - Edge drawing: SVG bezier curves from source bottom-center to target top-center, with arrowheads showing dependent → dependency direction
- Interaction: drag-to-pan canvas background, drag-to-reposition nodes, cursor-centered wheel zoom, pinch-to-zoom with stationary midpoint, keyboard shortcuts, zoom toolbar, reset, and fit-to-graph
- Fit-to-graph: computes node bounding box with layout node dimensions and applies zoom/pan so the graph fits in viewport with padding
- Initial auto-fit: when no saved scoped positions exist, the first non-empty render auto-fits once; subsequent updates preserve user navigation state
- Position persistence: dragged node positions are stored per project in browser localStorage and restored on reload
- Animated transitions: fit/reset operations animate
transform(var(--transition-normal)), while continuous drag/wheel/pinch stays transition-free for responsiveness - Node rendering: each graph node renders the real dashboard
TaskCardviaGraphTaskNode(no duplicated card markup) - Task detail integration: clicking a graph card opens the native dashboard task detail modal through host context (
openTaskDetail), matching board/list behavior - In-progress behavior: steps are visible by default and active-task glow (
agent-active) is preserved because node cards reuse TaskCard directly - Active-state indicator bar: active nodes render a compact top bar (
.graph-task-active-indicator) with the current execution status label (for exampleExecuting,Planning) and pulsing--in-progressemphasis - Current-step highlighting: active nodes set
data-current-stepfor valid native step indices so CSS selectors highlight the currently executing.card-step-itemand pulse its step dot - Zoom-out differentiation:
.graph-task-node--activeadds amplified glow and subtle scale/border tint so active nodes remain distinguishable at reduced zoom levels - In-review visual treatment:
in-reviewnodes get a static.graph-task-node--in-reviewleft accent in--in-reviewto distinguish waiting-review work from active execution nodes - Graph node classes:
.graph-task-node,.graph-task-node--active,.graph-task-node--in-review,.graph-task-node--highlighted,.graph-task-node--dimmed,.graph-node--highlighted, and.graph-node--dimmedare available for graph-specific layering/highlight states while card internals remain owned byTaskCard.css - Graph edge classes:
.graph-edge--highlightedand.graph-edge--dimmedare applied during dependency-chain emphasis states - Drag behavior: graph nodes pass
disableDrag={true}toTaskCardso card-level HTML5 drag does not conflict with canvas pan/zoom
Position persistence
- Storage key format:
kb:${projectId}:dependency-graph-positions(falls back todependency-graph-positionswhen no project is selected) - Read path: positions load on graph mount and whenever
projectIdchanges, then merge with fresh auto-layout so new tasks still receive layout defaults - Write path: positions persist on drag end only (not on every drag frame), filtered to currently visible tasks for stale cleanup
- Reset behavior: Fit to graph / Reset view clear persisted positions and re-apply auto-layout
- Implementation detail: the plugin ships local
scopedStoragehelpers duplicated from dashboardprojectStorageto stay plugin-isolated while preserving the samekb:${projectId}:${baseKey}convention
Dependency chain highlighting
- Hover a node to highlight the full transitive upstream + downstream chain for that task.
- Click a node to persist selection highlighting until the same node is clicked again or the canvas pane is clicked.
- Priority: hover state overrides selected state; when hover leaves, selected highlighting reappears.
- Dimming: when a chain is active, unrelated nodes and edges are dimmed.
- Neutral state: when nothing is hovered/selected, no highlight/dim classes are applied.
- Edge rule: an edge is highlighted only when both its source and target nodes are in the active chain.
Controls
Toolbar (bottom-right)
- Zoom in (
ZoomIn) — button +Ctrl+=/Cmd+= - Zoom out (
ZoomOut) — button +Ctrl+-/Cmd+- - Zoom percent label — live readout (for example
100%,75%,250%) - Fit to graph (
Maximize) — button +Ctrl+Shift+F/Cmd+Shift+F - Reset view (
RotateCcw) — button +Ctrl+0/Cmd+0
Additional keyboard behavior
- Escape resets to default view (
zoom=1,pan=0,0) - Shortcuts are suppressed when focus is inside
input,textarea,select, orcontentEditableelements
All controls are rendered as floating .btn-icon actions in the bottom-right corner, with mobile-friendly 44px touch targets in the @media (max-width: 768px) override.