feat(workflows): show lane pipelines, drop the deep analytics charts

The Workflows page rendered eleven charts of Claude Code harness internals
(collaboration network, subagent effectiveness, patterns, model delegation,
error propagation, concurrency, complexity, compaction). Too specialized to
read and nothing to act on, so they are gone along with their i18n keys.

What is left is what a reader can act on: headline stats, Workflow-tool runs,
the spawning DAG, the tool flow and the per-session drill-in — plus a new
first section for this dashboard's OWN pipelines. LanePipelinePanel renders a
horizontally scrolling lane strip and the selected lane's PipelineMap,
reusing the Workspace components so a stage looks identical on both pages.

The panel is read-only: the console-never-writes-a-stage boundary applies
here too, so every lane action stays on the Workspace page. The workflows API
response shape is untouched.

Closes #6
This commit is contained in:
2026-08-26 10:05:35 +07:00
parent bcfeeb5140
commit 4a0f99583d
16 changed files with 351 additions and 4766 deletions
+21 -104
View File
@@ -1,6 +1,11 @@
/**
* @file Workflows.tsx
* @description Displays comprehensive analytics on agent orchestration patterns, including DAGs of agent spawning, tool usage flows, collaboration networks, and session complexity metrics, with real-time updates and interactive filtering.
* @description Workflows page: this dashboard's own lane pipelines first, then the
* few Claude Code orchestration views that stay readable and interactive — headline
* stats, Workflow-tool runs, the spawning DAG, the tool flow, and the per-session
* drill-in. The deeper analytics (collaboration network, subagent effectiveness,
* patterns, model delegation, error propagation, concurrency, complexity,
* compaction) were dropped in issue #6 as too specialized to act on.
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
*/
/* =============================================================================
@@ -25,14 +30,11 @@
* - `../lib/eventBus`
* - `../lib/types`
* - `../components/workflows/WorkflowStats`
* - `../components/workflows/LanePipelinePanel`
* - `../components/workflows/WorkflowRunsPanel`
* - `../components/workflows/OrchestrationDAG`
* - `../components/workflows/ToolExecutionFlow`
* - `../components/workflows/AgentCollaborationNetwork`
* - `../components/workflows/SubagentEffectiveness`
* - `../components/workflows/WorkflowPatterns`
* - `../components/workflows/ModelDelegationFlow`
* - `../components/workflows/ErrorPropagationMap`
* - `../components/workflows/ConcurrencyTimeline`
* - `../components/workflows/SessionDrillIn`
*
* ## Public surface
* - `Workflows` — exported API; see TSDoc on the symbol for behavior.
@@ -74,16 +76,9 @@ import type { WorkflowData, WSMessage } from "../lib/types";
import { WorkflowStats } from "../components/workflows/WorkflowStats";
import { OrchestrationDAG } from "../components/workflows/OrchestrationDAG";
import { ToolExecutionFlow } from "../components/workflows/ToolExecutionFlow";
import { AgentCollaborationNetwork } from "../components/workflows/AgentCollaborationNetwork";
import { SubagentEffectiveness } from "../components/workflows/SubagentEffectiveness";
import { WorkflowPatterns } from "../components/workflows/WorkflowPatterns";
import { ModelDelegationFlow } from "../components/workflows/ModelDelegationFlow";
import { ErrorPropagationMap } from "../components/workflows/ErrorPropagationMap";
import { ConcurrencyTimeline } from "../components/workflows/ConcurrencyTimeline";
import { SessionComplexityScatter } from "../components/workflows/SessionComplexityScatter";
import { CompactionImpact } from "../components/workflows/CompactionImpact";
import { SessionDrillIn } from "../components/workflows/SessionDrillIn";
import { WorkflowRunsPanel } from "../components/workflows/WorkflowRunsPanel";
import { LanePipelinePanel } from "../components/workflows/LanePipelinePanel";
type StatusFilter = "all" | "active" | "completed";
@@ -203,6 +198,11 @@ export function Workflows() {
{/* Stats Row */}
<WorkflowStats stats={data.stats} />
{/* This dashboard's own pipelines - lane strip + the selected lane's map */}
<Section number={1} title={t("lanes.title")} subtitle={t("lanes.subtitle")} infoKey="lanes">
<LanePipelinePanel />
</Section>
{/* Workflow-tool runs (issue #167) - fleets ingested from on-disk journals */}
<div className="card p-4 space-y-3">
<div>
@@ -215,9 +215,9 @@ export function Workflows() {
<WorkflowRunsPanel statusFilter={statusFilter} />
</div>
{/* Section 1: Agent Orchestration DAG */}
{/* Section 2: Agent Orchestration DAG */}
<Section
number={1}
number={2}
title={t("orchestration.title")}
subtitle={t("orchestration.subtitle")}
infoKey="orchestration"
@@ -243,9 +243,9 @@ export function Workflows() {
)}
</Section>
{/* Section 2: Tool Execution Flow */}
{/* Section 3: Tool Execution Flow */}
<Section
number={2}
number={3}
title={t("toolFlow.title")}
subtitle={t("toolFlow.subtitle")}
infoKey="toolFlow"
@@ -253,92 +253,9 @@ export function Workflows() {
<ToolExecutionFlow data={data.toolFlow} filterAgentType={selectedNode} />
</Section>
{/* Section 3: Agent Collaboration Network */}
{/* Section 4: Session Drill-In */}
<Section
number={3}
title={t("pipeline.title")}
subtitle={t("pipeline.subtitle")}
infoKey="pipeline"
>
<AgentCollaborationNetwork effectiveness={data.effectiveness} edges={data.cooccurrence} />
</Section>
{/* Section 4 + 5: Two Column */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<Section
number={4}
title={t("effectiveness.title")}
subtitle={t("effectiveness.subtitle")}
infoKey="effectiveness"
>
<SubagentEffectiveness data={data.effectiveness} />
</Section>
<Section
number={5}
title={t("patterns.title")}
subtitle={t("patterns.subtitle")}
infoKey="patterns"
>
<WorkflowPatterns data={data.patterns} onPatternClick={() => {}} />
</Section>
</div>
{/* Section 6 + 7: Two Column */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<Section
number={6}
title={t("modelDelegation.title")}
subtitle={t("modelDelegation.subtitle")}
infoKey="modelDelegation"
>
<ModelDelegationFlow data={data.modelDelegation} />
</Section>
<Section
number={7}
title={t("errorPropagation.title")}
subtitle={t("errorPropagation.subtitle")}
infoKey="errorPropagation"
>
<ErrorPropagationMap data={data.errorPropagation} />
</Section>
</div>
{/* Section 8: Agent Concurrency Timeline */}
<Section
number={8}
title={t("concurrency.title")}
subtitle={t("concurrency.subtitle")}
infoKey="concurrency"
>
<ConcurrencyTimeline data={data.concurrency} />
</Section>
{/* Section 9 + 10: Two Column */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<Section
number={9}
title={t("complexity.title")}
subtitle={t("complexity.subtitle")}
infoKey="complexity"
>
<SessionComplexityScatter data={data.complexity} onSessionClick={setSelectedSessionId} />
</Section>
<Section
number={10}
title={t("compaction.title")}
subtitle={t("compaction.subtitle")}
infoKey="compaction"
>
<CompactionImpact data={data.compaction} />
</Section>
</div>
{/* Section 11: Session Drill-In */}
<Section
number={11}
number={4}
title={t("drillIn.title")}
subtitle={t("drillIn.subtitle")}
infoKey="drillIn"