Turn a Low-Level Design doc (Mermaid sequence diagrams, state machines, pipeline charts) into ONE interactive, single-screen request-flow explorer — a persistent system map where you pick any flow and watch a request travel end-to-end, hop by hop, with the active path highlighted, the wire message named, and run/step state shown live. Use when an LLD/HLD/RFC/runbook contains multiple flows through a shared set of components and static diagrams keep leaving the reader asking 'how does a reques...
Scanned 8/30/2026
Install to Claude Code
npx -y skills add SI-Jothee/lld-flow-explorer --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of lld-flow-explorer?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/si-jothee-lld-flow-explorer)More formats (shields.io, HTML) on the badges page.
---
name: lld-flow-explorer
description: "Turn a Low-Level Design doc (Mermaid sequence diagrams, state machines, pipeline charts) into ONE interactive, single-screen request-flow explorer — a persistent system map where you pick any flow and watch a request travel end-to-end, hop by hop, with the active path highlighted, the wire message named, and run/step state shown live. Use when an LLD/HLD/RFC/runbook contains multiple flows through a shared set of components and static diagrams keep leaving the reader asking 'how does a request actually move through this?'. Triggers: /lld-flow-explorer, or any request to visualize/animate/explore an LLD, sequence diagrams, or service request flows."
---
# Skill — LLD → Interactive Request-Flow Explorer
Turn the sequence diagrams, state machines, and pipeline charts buried in a Low-Level Design (LLD) doc into **one interactive, single-screen explorer**: a persistent system map where you pick any flow and *watch a request travel the system end-to-end* — hop by hop, with the active path highlighted, the wire message named, and run/step state shown live.
This is the skill that produced the *Job Orchestration · Request Flow Explorer*. It is written so you can point it at **any** event-driven / service LLD and get the same artifact.
> A complete, working build ships with this skill at **[`references/request-flow-explorer.html`](references/request-flow-explorer.html)** — open it in a browser to see exactly what you're aiming for.
---
## 1. When to use this
Use it when an LLD (or HLD, RFC, runbook) contains **multiple flows through a shared set of components** — typically:
- Mermaid `sequenceDiagram` blocks ("create run", "retry", "failure → incident", …)
- `stateDiagram-v2` blocks (an entity's lifecycle)
- a pipeline / step-graph (`flowchart`)
…and the reader keeps asking *"okay, but how does a request actually move through this?"* Static diagrams answer that one flow at a time; this turns all of them into one explorable, animated map.
**Don't** use it for a single linear flow (a plain diagram is enough) or for pure data-model / class diagrams (no movement to animate).
---
## 2. Output contract
A single **Design Component** (`<Name> Flow Explorer.dc.html`) — streaming, opens in a browser, no build step. It contains:
| Region | What it shows |
|---|---|
| **Header** | Title + one-line "how to read it" + a status-color legend |
| **Flow tabs** | One tab per flow (`§x.y` + title). Clicking selects a flow. |
| **Transport bar** | ⏮ / ▶ Play-Pause / ⏭, a **hop counter**, a **scrubber** (jump to any hop), speed control |
| **System map** (center) | A *persistent* set of component nodes laid out once. The selected flow draws its path on top; a glowing packet + wire-message label travels the active edge; visited edges stay as a trail; uninvolved nodes dim. |
| **Inspector** (right) | Current flow meta/title, the wire message badge, call/return/event direction, a plain-English narration line, and the **run-state** + **step-state** machines with the current state highlighted. |
| **Pipeline strip** (bottom) | The step graph, highlighting the active stage. |
Interaction model: **live animated playback with a scrubber.** Pick a flow → Play → the request animates across the shared map; or scrub/step to any point.
---
## 3. Process
### Step 0 — Read the LLD, ask first
Read the whole doc. Then confirm with the user (one round of questions): interaction model (playback vs click-to-explore), which flows to include, one-shared-map vs per-flow diagrams, how much detail per hop (narration / state / wire message / DB rows), visual theme, audience. Defaults that work well: **playback + scrubber, one shared map, narration + run/step state + wire message, all sequence flows + both state machines + the pipeline.**
### Step 1 — Extract the system map (the nodes)
List every participant that appears across the sequence diagrams + the C4 container view. Collapse duplicates (e.g. one "Orchestrator" node even if diagrams name several use-cases). Give each a **kind** (drives its accent + tag): `actor, api, core, store, loop, queue, worker, sns, dlq, ext`.
Lay them out **once** on a fixed 1200×640 canvas, left→right along the dominant request direction, grouping by tier (ingress · core+DB · queues · workers · notifications). Keep ~180px between centers so the 152px node cards don't collide. You only draw a flow's *own* edges later, so don't worry about wiring every possible connection — just place nodes cleanly.
### Step 2 — Extract each flow as a list of hops
Each `sequenceDiagram` (and any worked example) becomes one **flow**: an ordered array of **hops**. Translate every arrow / note into one hop:
```js
F(from, to, wire, tone, note, opts)
// from,to : node ids (self-hop when from===to)
// wire : the on-the-wire label — STEP_EXECUTE, 202 Accepted, BEGIN TX, ITEM_READY…
// tone : color class — 'cmd'|'ok'|'err'|'wait'|'db'|'http'|'info'
// note : one plain-English sentence (the "walk it" narration)
// opts : { run, step, stage, dir }
// run : run-state AFTER this hop, if it changed (else omit) → highlights the run state machine
// step : step-state after this hop, if it changed → highlights the step state machine
// stage : pipeline stage now active, if it changed → highlights the pipeline strip
// dir : 'call'(default, solid) | 'ret'(dashed return) | 'event'(no packet — a crash/timeout note)
```
Rules of faithful translation:
- A solid arrow → `dir:'call'`; a dashed return/delivery → `dir:'ret'`; a `Note over X` with no message (crash, lease expiry) → a self/`event` hop on that node.
- Internal decisions ("RetryPolicy?", "compare hash") → a **self-hop** (`from===to`) that pulses the node.
- Set `run`/`step`/`stage` **only on the hop where they change**; the engine carries the last value forward. Give each flow an `init:{run,step,stage}` for the state it starts in.
- Keep `note` to one sentence. Don't editorialize or add facts the LLD doesn't state.
- Pick `tone` by message meaning: commands/dispatch=`cmd`, success/completed=`ok`, failure/cancel=`err`, wait/retry/resume=`wait`, DB writes/transactions=`db`, HTTP responses=`http`, plumbing/routing=`info`.
For branching flows (e.g. idempotent vs supersede), walk the **most instructive branch** and name the others in the first hop's narration — a single packet can't fork.
### Step 3 — Extract the state machines + pipeline
- Each `stateDiagram-v2` → `{ states:{NAME:[x,y]}, edges:[[from,to]] }` on its own small canvas. Position the hub state centrally. These render as static reference graphs; the **current** state (carried from the hops) is highlighted.
- The pipeline `flowchart` → an ordered list of stages `{key, queue, policy, wait?}`. The active stage is highlighted; mark any stage with an external-wait loop (`wait:true`).
### Step 4 — Build the Design Component
Drop your extracted `NODES`, `FLOWS`, `RUN_SM`, `STEP_SM`, `PIPE` into the **reusable engine** (Appendix B). The engine handles: rAF packet animation + easing, play/pause/next/prev/scrub, carry-forward of run/step/stage, a ResizeObserver that scales the fixed 1200×640 stage to fit, and all the rendering (map, state machines, pipeline, tabs, transport, badges). You only author **data**, not behavior.
Authoring notes specific to Design Components:
- Chrome (header, tabs bar, control bar, panels, narration, labels) lives in the **template** (`b_dc_html`) as inline-styled markup so it streams and stays editable.
- The data-driven visuals (the map SVG+nodes+packet, the two state machines, the pipeline strip, the tab/transport buttons) are built with `React.createElement` in the **logic class** and surfaced through `{{ holes }}`. This is the sanctioned exception: they're animated / per-frame state that the template can't express.
- Expose `accent` (color) and `loop` (boolean) as props so the deck is tweakable without code.
### Step 5 — Theme
Two ready palettes (see Appendix C): **light "architecture blueprint"** (paper-white panels, ink text, blue primary, soft shadows) and **dark "ops console"** (near-black canvas, glowing active path). The active path is the only thing that should *pop*: bold toned line + soft halo, everything else calm. Status colors are semantic and consistent everywhere (map, badges, state machines).
### Step 6 — Verify
Load it; step into 2–3 flows and confirm: the active edge + packet + wire label render, the trail builds, the run/step machines highlight the right state, the pipeline tracks the stage, and the scrubber jumps cleanly. Designed for a 1440×900 desktop viewport.
### (Optional) Ship it
- **Standalone offline HTML:** because the DC runtime pulls React from a CDN, add `<script src="…react…">` + `<script src="…react-dom…">` *before* the runtime script and a `<template id="__bundler_thumbnail">` splash, then bundle to a single self-contained file (inlines React + fonts; zero network). The shipped [`references/request-flow-explorer.html`](references/request-flow-explorer.html) is exactly this kind of bundle.
- **PPTX:** an interactive tool doesn't export meaningfully as slides — instead build a companion deck (title + system map, one slide per flow with its full path drawn and hops listed) and export that.
---
## Appendix A — Data schema (fill this in per LLD)
```js
// 1. NODES — id → {x,y,name,sub,kind}. Canvas is 1200×640; (x,y) is the node center.
this.NODES = {
API: {x:84, y:330, name:'API Controller', sub:'REST /createJob', kind:'api'},
UC: {x:322, y:322, name:'Orchestrator', sub:'use-cases', kind:'core'},
DB: {x:322, y:520, name:'Postgres', sub:'source of truth', kind:'store'},
// …one entry per participant. kinds: actor api core store loop queue worker sns dlq ext
};
// 2. FLOWS — one per sequence diagram. F(from,to,wire,tone,note,opts)
const F=(from,to,wire,tone,note,o)=>Object.assign(
{from,to,wire,tone,note,run:null,step:null,stage:null,dir:'call'}, o||{});
this.FLOWS = [
{ meta:'§9.1', title:'Create run → first step dispatched',
init:{run:null,step:null,stage:null}, hops:[
F('API','UC','CreateRun()','http','Caller hits POST /createJob; one DB transaction opens.'),
F('UC','DB','BEGIN TX','db','Insert the run (CREATED) + first step (QUEUED) + variables.',
{run:'CREATED',step:'QUEUED',stage:'preparation'}),
F('UC','API','202 Accepted','http','Return 202 with the runId immediately.',{dir:'ret'}),
// …
]},
// …one object per flow
];
// 3. State machines — {vb:[w,h], box:[w,h], states:{NAME:[cx,cy]}, edges:[[from,to]]}
this.RUN_SM = { vb:[380,300], box:[96,24], states:{/*…*/}, edges:[/*…*/] };
this.STEP_SM = { vb:[380,206], box:[96,24], states:{/*…*/}, edges:[/*…*/] };
// 4. Pipeline — ordered stages
this.PIPE = [
{key:'preparation', q:'wf-prep-jobs', pol:'retry×2 · lease 5m', wait:true},
{key:'generation', q:'wf-gen-jobs', pol:'retry×3 · lease 30m'},
// …
];
```
---
## Appendix B — Reusable engine (logic class `Component extends DCLogic`)
Paste this whole class; replace only the four data structures in the constructor (Appendix A). Everything else — animation, playback, scaling, rendering — is generic.
> A complete, working build ships with this skill: **[`references/request-flow-explorer.html`](references/request-flow-explorer.html)** — open it in a browser to see the target artifact, and read its logic class for the full engine. (It's the bundled standalone build with React inlined; the editable `.dc.html` source is the same logic class with the four data structures swapped.) Copy it, then swap its `NODES` / `FLOWS` / `RUN_SM` / `STEP_SM` / `PIPE` for your LLD's. Key methods and their roles:
| Method | Role |
|---|---|
| `animateHop()` | rAF loop: eases the packet 0→1 along the current edge; on finish, if playing, dwells then advances (or loops / stops). Instant for self/event hops. |
| `playPause() / next() / prev() / scrub(v) / selectFlow(i) / setSpeed(s)` | Transport + navigation; each (re)starts `animateHop()`. |
| `carry(field)` | Walks `init` + hops `0..current`, returning the last non-null `run`/`step`/`stage` — so state persists between the hops that change it. |
| `measure()` + ResizeObserver | Computes `scale = min(w/1200, h/640)` and scales the fixed stage to fit any panel size with no distortion. |
| `clampSeg(A,B,hw,hh)` | Trims an edge so it starts/ends at the node-box border (used for both the map and the state machines). |
| `buildMap()` | Renders the SVG edges (trail dim, current toned + halo, arrowheads per tone), node cards (dim/seen/endpoint/arrived states), and the traveling packet + wire label. |
| `buildSM(def,current)` | Renders a state machine; highlights `current`. |
| `buildPipeline(active)` | Renders the stage strip; highlights `active`. |
| `buildFlowTabs() / buildTransport() / buildSpeed() / buildLegend() / badge() / dirBadge()` | The chrome controls + badges. |
| `toneColor(t) / statusColor(s) / kindMeta(k)` | The single source of truth for color — edit these to retheme. |
| `renderVals()` | Assembles every `{{ hole }}` the template consumes. |
---
## Appendix C — Palettes (edit `toneColor` / `statusColor` / `kindMeta` + template literals)
**Light — "architecture blueprint"**
```
app #e9edf3 · panels #ffffff · soft #f3f6fa · canvas #fbfcfe
borders #d4dce6 / #e0e7f0 · ink #16202e · secondary #5a6a7e · muted #8693a4
accent #2f6df0
tones cmd #2f6df0 · ok #1a8f4a · err #d83a34 · wait #bd7d0c · db #7a4ddb · http #0e8aa0 · info #5f6f82
status CREATED #3b7fd0 · RUNNING/PUBLISHED/ACTIVE #2f6df0 · QUEUED #5f6f82 · WAITING/RETRYING/PAUSED #bd7d0c
INCIDENT/FAILED/ERROR #d83a34 · COMPLETED #1a8f4a · CANCELLED #94a3b8
active path = bold toned line + soft colored halo (drop-shadow ~0 1px 3px tone66); node glow = soft colored shadow, NOT neon
```
**Dark — "ops console"**
```
app #080b11 · panels #0b0f16 · soft #0a0e15 · borders #182230/#131c28
ink #e6edf3 · muted #6b7785 · accent #37d6e0
tones cmd #37d6e0 · ok #34d399 · err #ff5c6c · wait #f5b73d · db #a78bfa · http #5b9bff · info #8a99ab
active path glows (drop-shadow ~0 0 5px tone); nodes get an accent ring + outer glow
```
Status semantics are identical across themes — only the hex values shift for legibility on the background.
---
## Appendix D — Pitfalls
- **Node cards must scale with the stage.** Size the stage as a fixed 1200×640 element and `transform: scale()` it (via the ResizeObserver) — don't position nodes in `%` with `px` sizes, or they overlap when the panel shrinks.
- **One packet can't branch.** Model branching flows as the main branch + narration for the alternates.
- **Set state only on the hop that changes it.** Let `carry()` fill the gaps; don't repeat `run`/`step` on every hop.
- **Keep the map honest.** Route result events through the result queue node even when the source diagram condenses them, so every flow uses the same component vocabulary.
- **Don't invent content.** Wire names, states, and narration come from the LLD. If a stage has sub-steps the orchestrator doesn't track, keep them inside the worker node — don't add fake hops.
- **Offline build:** the DC runtime fetches React from a CDN; inline it (Step 6) or the standalone file breaks with no network.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!