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
+10 -24
View File
@@ -455,7 +455,7 @@ graph TD
DETAIL --> CONV["ConversationView<br/>(MarkdownContent + CodeBlock<br/>+ ToolCallBlock per-tool styling)"]
DETAIL --> TL["Event Timeline"]
ACTIVITY --> FEED["Streaming Event List<br/>(click row → expand payload;<br/>Session btn → session detail)"]
WORKFLOWS_P --> WFC["12 D3.js components<br/>(workflows/ directory)"]
WORKFLOWS_P --> WFC["Lane pipelines +<br/>4 analytics components<br/>(workflows/ directory)"]
style APP fill:#6366f1,stroke:#818cf8,color:#fff
style LAYOUT fill:#1a1a28,stroke:#2a2a3d,color:#e4e4ed
@@ -465,7 +465,6 @@ graph TD
- **`SplashScreen.tsx`** — rendered by `App.tsx` as a fixed full-screen overlay alongside the router. Shows once per browser session (`sessionStorage` gate, read synchronously so a repeat mount never flashes). Time-aware greeting + localized tagline/subtexts (`splash` i18n namespace, en/zh/vi/ko) + an animated node-graph brand mark on a dark backdrop (radial glow, drifting constellation, grain). The backdrop is **opaque from the first paint** (no entrance fade on the root) so the app rendered behind it never flashes through; only the inner content cascades in. Holds ~2.5 s, then fades out and unmounts; click-to-skip; honors `prefers-reduced-motion`. CSS-only keyframes, no added dependencies.
- **Loading skeletons** — the shared `Skeleton` primitive (`components/Skeleton.tsx`) uses Tailwind `animate-pulse`. `Analytics.tsx` now renders a pulsing `AnalyticsChartsSkeleton` for the whole chart region while `data` is null (previously it fell back to empty/zero charts).
- **`workflows/CompactionImpact.tsx`** — redesigned from a one-bar-per-session chart into a "sessions by compaction count" histogram (D3) with axis titles, stat tiles (total / sessions affected / avg / peak), an explanatory help line, a plain-English summary, and rich React-managed hover tooltips (full-height per-bucket hit-area + bar highlight) matching the other charts.
- **`Workflows.tsx` `Section`** — the right-aligned section subtitle is clamped to a single line (`truncate` + `max-w` + hover `title`) so a long translation never wraps and unbalances the header; the full text stays in the section's `i` popover.
### Self-hosted assets (no external CDN)
@@ -657,33 +656,21 @@ graph TD
WS_D --> WF
WF --> S1["WorkflowStats<br/>Summary cards"]
WF --> S2["OrchestrationDAG<br/>Horizontal DAG —<br/>Sessions → Main → Subagents → Outcomes"]
WF --> S3["ToolExecutionFlow<br/>d3-sankey tool transitions"]
WF --> S4["AgentCollaborationNetwork<br/>Force-directed pipeline graph"]
WF --> S5["SubagentEffectiveness<br/>SVG success rings +<br/>day-of-week sparklines"]
WF --> S6["WorkflowPatterns<br/>Auto-detected sequences"]
WF --> S7["ModelDelegationFlow<br/>Model → agent routing"]
WF --> S8["ErrorPropagationMap<br/>React horizontal bars +<br/>API/session error support"]
WF --> S9["ConcurrencyTimeline<br/>Swim-lane parallel execution"]
WF --> S10["SessionComplexityScatter<br/>D3 bubble chart"]
WF --> S11["CompactionImpact<br/>Token compression analysis"]
WF --> S12["SessionDrillIn<br/>Searchable session explorer<br/>(3 tabs: tree / timeline / events)"]
WF --> S2["LanePipelinePanel<br/>Lane strip + selected lane's<br/>PipelineMap (read-only)"]
WF --> S3["WorkflowRunsPanel<br/>Workflow-tool runs<br/>(on-disk journals)"]
WF --> S4["OrchestrationDAG<br/>Horizontal DAG —<br/>Sessions → Main → Subagents → Outcomes"]
WF --> S5["ToolExecutionFlow<br/>d3-sankey tool transitions"]
WF --> S6["SessionDrillIn<br/>Searchable session explorer<br/>(3 tabs: tree / timeline / events)"]
classDef root fill:#6366f1,stroke:#818cf8,color:#fff
```
| Component | Visualization | D3 Feature |
| --- | --- | --- |
| `LanePipelinePanel` | This dashboard's own lanes: a horizontally scrolling lane strip and the selected lane's pipeline map | Plain React; reuses `lanes/LaneStripCard` + `lanes/PipelineMap`, polls `GET /api/lanes` and debounces websocket events. Read-only — every lane action stays on the Workspace page |
| `WorkflowRunsPanel` | Workflow-tool runs reconstructed from on-disk journals | Per-run phase chips, per-agent table, expandable results |
| `OrchestrationDAG` | Horizontal DAG of aggregate spawning patterns | Custom DAG layout, capped at top 7 subagent types with overflow node |
| `ToolExecutionFlow` | Tool-to-tool transition Sankey diagram | `d3-sankey` |
| `AgentCollaborationNetwork` | Agent pipeline graph with directed edges | `d3-force` with arrowheads and frequency labels |
| `SubagentEffectiveness` | Scorecard grid with success rate rings | SVG arc rendering, day-of-week sparklines (Mon-Sun). Per-bar tooltip is rendered through `createPortal` to `document.body` and positioned with viewport-clamped fixed coordinates so it escapes the card's `overflow:hidden` (and any `hover:translate` containing block) and is never clipped by the card edge — fixes Sun/Sat/Mon/Fri visibility |
| `WorkflowPatterns` | Common orchestration sequences | Pattern detection from event data; clicking a row expands an inline detail panel with the full step chain, a stats grid, a deterministic narrative (shape buckets: solo / two-step / short / long; loop detection; frequency bucket: dominant > 50% / common > 25% / regular > 10% / niche), and a practical suggestion bucket. All copy is i18n-driven (`workflows.patterns.detail.*`) |
| `ModelDelegationFlow` | Model routing through agent hierarchies | Hierarchical layout |
| `ErrorPropagationMap` | Error clustering by hierarchy depth with API/session event errors | Pure React horizontal bars (replaced D3 bar chart), `eventErrors` support for API and session-level errors |
| `ConcurrencyTimeline` | Swim-lane parallel agent execution | Time-scaled horizontal bars |
| `SessionComplexityScatter` | Duration vs agents vs tokens | D3 bubble/scatter chart |
| `CompactionImpact` | Token compression events and recovery | Before/after comparison |
| `SessionDrillIn` | Per-session agent tree, tool timeline, events | Searchable dropdown with pagination, 3 tabs |
**Cross-filtering:** Clicking nodes in the OrchestrationDAG filters data in other sections. **JSON export:** All workflow data can be exported as JSON from the page header.
@@ -697,7 +684,6 @@ Every chart in the Workflows page follows a single, deterministic tooltip patter
- **Container-level `mouseleave` fallback.** The chart's outer wrapper also calls `hideTip()` on leave. If a node-level handler is missed because D3 destroyed the element under the cursor on data refresh, the wrapper guarantees dismissal.
- **Re-render safety.** Each chart's render effect ends with `hideTip()` so any stale tooltip from before a websocket-driven refresh is cleared the moment new data arrives.
- **Fade transitions.** Tooltips stay in the DOM with `opacity: 0` and `pointer-events: none`, transitioning over 120 ms — show/hide feels smooth instead of flickering, and the element never intercepts pointer events that would prevent `mouseleave` from firing on the chart.
- **Portal escape for clipped containers.** `SubagentEffectiveness` cards use `overflow:hidden` plus a hover `translate` (which becomes the fixed-position containing block), so its sparkline tooltip is rendered with `react-dom.createPortal(…, document.body)` rather than as a child of the card. Coordinates are computed from the bar's bounding rect and clamped to the viewport, so the tooltip is visible on every day of the week regardless of the card's screen position.
### Structured info popovers
@@ -726,7 +712,7 @@ flowchart LR
See [docs/I18N.md](docs/I18N.md) for resource strategy, key naming conventions, localization tests, troubleshooting, and rollout checklists.
**Coverage scope.** The translation layer extends end-to-end through the Workflows tooltip surfaces — `workflows.stats.tooltip.*` (calculation copy, deterministic value-bucket interpretations, metric phrases), `workflows.chartInfo.*` (per-chart "What / How to read / Why" entries for all 11 sections), `workflows.{orchestration,toolFlow,pipeline,modelDelegation,concurrency}.tooltip.*` (per-graph hover content), and `workflows.patterns.detail.*` (Workflow Patterns expansion narrative + suggestion buckets) — plus the Settings additions: `settings.pricing.tooltip.*` (pricing rule lookup, `%` wildcard syntax, manual-update reminder), `settings.claudeHome.*` (CLAUDE_HOME panel labels), and the full `settings.import.*` block (now translated to vi/zh, where the panel previously fell back to English).
**Coverage scope.** The translation layer extends end-to-end through the Workflows tooltip surfaces — `workflows.stats.tooltip.*` (calculation copy, deterministic value-bucket interpretations, metric phrases), `workflows.chartInfo.*` (per-section "What / How to read / Why" entries), and `workflows.{orchestration,toolFlow}.tooltip.*` (per-graph hover content) — plus the Settings additions: `settings.pricing.tooltip.*` (pricing rule lookup, `%` wildcard syntax, manual-update reminder), `settings.claudeHome.*` (CLAUDE_HOME panel labels), and the full `settings.import.*` block (now translated to vi/zh, where the panel previously fell back to English).
---
@@ -2484,7 +2470,7 @@ The function handles:
- Version number dot-joining (hyphen-separated digits → dotted)
- Title-casing for word segments
Components that consume this: SessionDetail, Analytics (donut chart + breakdown), Dashboard (model stats), MessageList, SessionCard, AgentCard, SessionComplexityScatter, SessionDrillIn, ModelDelegationFlow, and EventDetail.
Components that consume this: SessionDetail, Analytics (donut chart + breakdown), Dashboard (model stats), MessageList, SessionCard, AgentCard, SessionDrillIn, and EventDetail.
### Data Flow