+
+ {finished
+ ? '[SYSTEM] Task graph execution finished.'
+ : '[SYSTEM] Task graph execution in progress.'}
+
+ {tasks.map((task) => (
+
+ [{task.assignee?.toUpperCase() ?? 'UNASSIGNED'}] {task.title} {'->'}{' '}
+ {task.status.toUpperCase()}
+
+ ))}
+
+ )
+}
diff --git a/apps/web/src/components/dashboard/TeamRunDashboard.tsx b/apps/web/src/components/dashboard/TeamRunDashboard.tsx
new file mode 100644
index 0000000..498641a
--- /dev/null
+++ b/apps/web/src/components/dashboard/TeamRunDashboard.tsx
@@ -0,0 +1,77 @@
+import { useCallback, useMemo, useState } from 'react'
+import { layoutTasks } from '../../lib/layout-tasks.ts'
+import type { TaskExecutionRecord, TeamRunResult } from '../../types/team-run.ts'
+import { DagEdges } from './DagEdges.tsx'
+import { DagNode } from './DagNode.tsx'
+import { DagViewport } from './DagViewport.tsx'
+import { DetailsPanel } from './DetailsPanel.tsx'
+
+type TeamRunDashboardProps = {
+ readonly result: TeamRunResult
+}
+
+export function TeamRunDashboard({ result }: TeamRunDashboardProps) {
+ const tasks = result.tasks ?? []
+ const goal = result.goal ?? ''
+ const layout = useMemo(() => layoutTasks(tasks), [tasks])
+ const [panelOpen, setPanelOpen] = useState(false)
+ const [selected, setSelected] = useState