| name | layered-flow-chart |
| description | Create, update, and refine interactive hierarchical flow diagrams with automatic ELK layout and drill-down navigation.
Outputs a React Flow viewer with zoom, pan, minimap, detail inspector, and progressively deeper levels.
Use this skill when users ask to:
- Visualize a processing flow, architecture, or pipeline as an interactive diagram
- Create a layered/hierarchical flow chart with drill-down
- Diagram a codebase flow with expandable detail levels
- "Make a flow diagram of X" or "Visualize the X process"
- Update an existing flow chart to reflect code changes
- Improve or refine an existing flow chart (layout, detail, boundary connections)
Triggers: "flow diagram", "flow chart", "process visualization", "layered chart", "interactive diagram", "drill-down diagram", "処理フロー図", "フローチャート", "フロー図解", "update flow", "refine flow", "フロー更新", "フロー改善"
|
Layered Flow Chart
Create, update, and refine interactive hierarchical flow diagrams. React Flow renders the graph and ELK calculates node and edge positions automatically. Nodes with childLevelId open progressively finer levels; leaf nodes open a source-aware detail inspector.
Mode Selection
Before starting, determine which mode applies:
| Mode | Trigger | Existing data.js? | Code investigation? |
|---|
| Create | "Make a flow diagram of X" | No | Full (3-phase pipeline) |
| Update | "Update the flow to reflect latest code" | Yes | Targeted (diff-focused) |
| Refine | "Improve the layout / add details / add boundary arrows" | Yes | None or minimal |
How to determine the mode:
- Check if user references an existing flow chart (directory with
index.html + data.js) → if yes, Update or Refine
- If user mentions code changes, new features, or syncing → Update
- If user mentions layout, visuals, detail level, or adding properties like
boundary → Refine
- Otherwise → Create
Create Mode (3-Phase SubAgent Pipeline)
This mode requires deep code investigation BEFORE building the HTML. To prevent shallow analysis, you MUST split the work into 3 phases using SubAgents. Do NOT skip phases or combine them.
Phase 1: Investigation (Serial Explore SubAgents)
Investigation is done in serial steps using multiple Explore agents. Each step builds on the previous output. Do NOT parallelize - the layered nature of the chart requires understanding the high level before deciding what to drill into.
Step 1-1: Broad Survey (Explore)
Understand the overall flow at the highest abstraction level. This becomes the root level of the chart.
Prompt template:
Investigate the following flow/process in this codebase: {user's description}
Produce a HIGH-LEVEL overview report. Focus on the main stages/phases of the flow, NOT implementation details.
## Flow Overview
- Purpose: (one sentence)
- Entry point: (file:line)
- Overall pattern: (e.g., pipeline, event-driven, request-response)
## Root Level Steps (the main stages):
For each major stage (aim for 5-10):
1. **{Stage Name}**
- Role: {what this stage does, one sentence}
- Key file(s): {primary file(s) involved}
- Complexity: simple | moderate | complex
- Branches to: {next stage(s), if any}
## Connections:
- {StageA} -> {StageB} (label if conditional)
- {StageA} -> {StageC} [dashed, on failure]
Focus on identifying WHAT the stages are and HOW they connect. Do not drill into implementation details yet.
Main Agent Review (between steps)
After Step 1-1, review the output and decide:
- Which stages are "complex" or critical enough to warrant a drill-down level?
- Are there stages that were missed or should be split/merged?
- Select 2-4 stages for deep investigation in Step 1-2.
Step 1-2: Deep Dive (Explore)
Investigate the selected stages in detail. These become the drill-down levels of the chart.
Prompt template:
I am investigating this flow: {user's description}
Here is the high-level overview already produced:
{paste Step 1-1 output}
Now deep-dive into these specific stages: {list of selected stages}
For EACH stage, produce a detailed sub-flow:
### Stage: {name}
#### Sub-steps:
1. **{Sub-step Name}**
- Role: {what it does}
- Key file(s): {file:line-range}
- Tech: {libraries/frameworks involved}
- Input: {what it receives}
- Output: {what it produces}
- Branches to: {next sub-step(s), if any}
- Notes: {error handling, edge cases, important details}
#### Connections:
- {SubStepA} -> {SubStepB}
Investigate EVERY file involved. List concrete function names, file paths, and line numbers. Aim for 4-8 sub-steps per stage.
Step 1-3 (Optional): Revise Root Level
If the deep dive revealed that the root level needs corrections (missing stages, wrong connections, stages that should be split), spawn one more Explore agent to verify and patch.
Prompt template:
Here is a high-level flow overview:
{Step 1-1 output}
And here are the deep-dive findings:
{Step 1-2 output}
Based on the deep-dive, does the high-level overview need corrections?
Check for:
- Missing stages that the deep-dive revealed
- Stages that should be split or merged
- Connections that are wrong or missing
- Stages marked as simple that are actually complex (or vice versa)
Output ONLY the corrections needed (or "No corrections needed"). Use the same format as the original overview for any additions/changes.
Phase 2: Data Construction (SubAgent: general-purpose)
Spawn a general-purpose agent. Pass it the Phase 1 report AND the Data Schema section below. The agent constructs the window.LAYERED_GRAPH JavaScript object.
Prompt template:
Convert the following investigation report into a window.LAYERED_GRAPH JavaScript object for a flow chart.
## Investigation Report
{paste Step 1-1 output (with Step 1-3 corrections applied if any)}
## Deep Dive Report
{paste Step 1-2 output}
## Schema Rules
{paste the "Data Schema", "Node Kinds", and "Connection Kinds" sections from this SKILL.md}
Output ONLY the JavaScript for data.js:
- window.LAYERED_GRAPH = { ... };
- document.title = `${window.LAYERED_GRAPH.meta.title} | Layered Flow Chart`;
Requirements:
- Do NOT generate x/y coordinates; ELK computes all layout
- Choose a semantic `kind` for every node and edge
- Set `childLevelId` only when a matching level exists
- Include sourceRefs, technologies, input/output, and details where available
- Aim for 5-10 nodes per level. If the investigation found fewer, that's fine, but do not drop discovered steps
Phase 2.5: Ask Output Location (Main Agent — AskUserQuestion)
Before assembling the HTML, use AskUserQuestion to ask the user where to place the generated file.
Determine the "main file path" from the Phase 1 investigation (the entry point or key file identified in Step 1-1). Use its parent directory as the option 2 suggestion.
AskUserQuestion config:
- header: "Output path"
- question: "フローチャートの出力先ディレクトリを選んでください。"
- options:
/tmp 配下 (Recommended) — /tmp/{project}/flow-{name}/ に出力します。プロジェクトを汚しません。
- メインファイルと同じフォルダ —
{detected main file's directory}/flow-{name}/ に出力します。READMEの代わりなどプロジェクト内に置きたい場合に。
- パスを指定する — 任意のディレクトリパスを入力できます。
Use the user's choice to determine the output directory for the next phase.
- Option 1 →
/tmp/{project}/flow-{name}/ (create dir with mkdir -p if needed)
- Option 2 →
{main file's directory}/flow-{name}/
- Option 3 (Other) → Use the path the user provides as-is
Phase 3: Assembly (Main Agent)
You (the main agent) handle the final assembly. The viewer is prebuilt — the LLM only generates data.js, no HTML/CSS/React generation needed.
- Create output directory:
mkdir -p {output-dir}
- Copy viewer assets:
cp ~/.claude/skills/layered-flow-chart/assets/template.html {output-dir}/index.html
cp ~/.claude/skills/layered-flow-chart/assets/viewer.js {output-dir}/viewer.js
cp ~/.claude/skills/layered-flow-chart/assets/viewer.css {output-dir}/viewer.css
- Write data.js: Write Phase 2 output to
{output-dir}/data.js (the only LLM-generated file)
- Open in browser:
open {output-dir}/index.html (the prebuilt IIFE works from file://; no server required)
- Verify with screenshots at every level. Check the overview, every child level, and at least one leaf inspector.
Update Mode (Sync with Code Changes)
Use when an existing flow chart HTML needs to reflect code changes (new features, refactored modules, removed endpoints, etc.).
Step 0: Extract Current State
- Read the existing
data.js file (in the same directory as the flow chart's index.html) to extract the current window.LAYERED_GRAPH object
- Parse it to understand: which nodes exist, their hierarchy, connections, and metadata
Step 1: Targeted Investigation (Explore)
Spawn an Explore agent focused on what changed, not the entire codebase.
Prompt template:
An existing flow chart describes this process: {brief description}
Here are the current nodes and connections in the chart:
{paste extracted LAYERED_GRAPH summary - just level IDs, node IDs, titles, and sourceRefs}
The user says the following has changed: {user's description of changes}
Investigate the codebase and report:
1. **New steps** that should be added (with file:line, role, connections)
2. **Removed steps** that no longer exist in the code
3. **Modified steps** where the role, file, tech, or connections changed
4. **Connection changes** (new, removed, or changed connections)
For each change, provide the same detail level as the existing nodes (file paths, tech, input/output).
Only report actual changes - do not re-describe unchanged parts.
Step 2: Apply Changes (Main Agent or general-purpose SubAgent)
Based on the diff report:
- Add new nodes/levels to the
window.LAYERED_GRAPH object
- Remove deleted nodes and their connections
- Modify changed nodes (update titles, summaries, sourceRefs, technologies, and edges)
- Re-check semantic ordering - array order influences ELK's stable layout
- Update edge
kind if network crossings or failure paths changed
Step 3: Write and Verify
- Edit the existing
data.js file in-place (update window.LAYERED_GRAPH and document.title only — do not touch viewer assets)
- Open in browser and verify all layers
Refine Mode (Improve Existing Chart)
Use when the chart's content is correct but the presentation needs improvement. No or minimal code investigation.
CRITICAL: Always refine the surrounding context, not just the target.
When a user asks to refine a specific module, you MUST also review and potentially revise its surrounding layers:
Parent Layer (the level containing the target node)
├── Sibling nodes: are they at the same resolution as the refined target?
├── Connections: do arrow counts and labels still make sense?
└── Grouping: should siblings be split/merged to match the new granularity?
Target Node (what the user asked to refine)
└── The node itself + its drill-down level if it has one
Child Layer (the drill-down of the target, if any)
├── Sub-nodes: does the internal structure match the refined understanding?
└── Connections back to parent: are input/output descriptions consistent?
Why this matters: Refining one module often reveals that:
- Adjacent nodes were too coarse or too fine compared to the refined target → split or merge them
- Connections between the target and its neighbors need new arrows, labels, or
boundary flags
- The parent layer's node count needs adjustment (e.g., what was 1 node should be 3)
- Drill-down levels of adjacent nodes need similar resolution increases
Step 0: Read and Scope the Blast Radius
- Read the existing
data.js file to extract the current window.LAYERED_GRAPH object
- Identify the target node the user wants to refine
- Identify the impact zone — all layers/nodes that may need revision:
- The level containing the target (parent layer)
- The drill-down of the target (child layer), if any
- Nodes directly connected to the target (upstream/downstream neighbors)
- Drill-downs of those neighbors, if the resolution gap is large
Step 0.5: Confirm Scope with User
Before proceeding, use AskUserQuestion to confirm the refine scope with the user. Present the identified impact zone and let them choose.
Example question:
「{target node}」の改善にあたり、影響範囲を確認させてください。
1. Target only — 指定ノードとそのドリルダウンのみ
2. Target + neighbors — 前後のノード・接続も見直す(推奨)
3. Full layer review — 対象レイヤー全体のノード数・粒度・接続を再構成
4. (Other — 自由記述)
This prevents over-engineering a simple label fix, while ensuring the user is aware when broader changes are recommended.
Step 1: Assess Granularity Balance
For each node in the impact zone, check:
- Resolution parity: Is this node at a similar level of detail as the refined target? If the target now has 6 sub-steps in its drill-down but a neighbor is still a single vague box, the neighbor needs attention.
- Connection accuracy: Do the arrows entering/leaving this node still represent the actual data flow? Are there missing arrows or stale labels?
- Edge kinds: Should any connection be
kind: 'boundary' or kind: 'failure'?
Step 2: Apply Changes
For each layer in the impact zone:
- Add/split nodes where granularity is too coarse relative to the refined target
- Merge/simplify nodes where granularity is unnecessarily fine
- Update connections — add missing arrows, remove stale ones, update labels and semantic edge kinds
- Review model order — reorder node/edge arrays when the intended reading order is unclear; ELK handles coordinates
- Update drill-down levels — if a node was split, its old drill-down may need to be split too; if merged, drill-downs may need consolidation
Common Refinements
| Request | Action | Impact zone |
|---|
| "Add boundary connections" | Set kind: 'boundary' on cross-network connections | All levels |
| "Improve layout" | Simplify the model, shorten labels, and adjust array order; ELK recalculates positions | All levels |
| "Add more detail to X" | Enrich X + check neighbor resolution parity | Parent + child + neighbors |
| "Add a drill-down for X" | New level + set childLevelId + check if neighbors need drill-downs too | Parent + new child |
| "Fix overlapping arrows" | Simplify cross-links or adjust model order and let ELK reroute | Affected level |
Step 3: Write and Verify
- Edit the existing
data.js file in-place (modify window.LAYERED_GRAPH and document.title only — do not touch viewer assets)
- Open in browser and verify every layer in the impact zone, not just the target
Data Schema
window.LAYERED_GRAPH is the semantic source of truth. Coordinates and edge bend points are deliberately absent: ELK derives them at runtime.
window.LAYERED_GRAPH = {
version: 1,
rootLevelId: 'root',
meta: {
title: 'Order Processing',
product: 'LAYERED FLOW',
logo: 'OP',
repository: 'https://github.com/org/repo',
},
levels: {
root: { },
'validate-detail': { },
},
}
document.title = `${window.LAYERED_GRAPH.meta.title} | Layered Flow Chart`
Level
{
title: 'Level title',
description: 'One sentence describing this abstraction level.',
nodes: [ ],
edges: [ ],
}
Keep a level focused on one resolution. Prefer 4-8 nodes. When a level exceeds 10 nodes, split it into meaningful phases or child levels instead of shrinking labels.
Node
{
id: 'validate',
kind: 'decision',
icon: '02',
title: 'Validate request',
summary: 'Check required fields and business constraints.',
childLevelId: 'validate-detail',
technologies: ['Zod', 'TypeScript'],
sourceRefs: [
{ path: 'src/validate.ts', line: 18, symbol: 'validateOrder' },
],
input: 'OrderDraft',
output: 'ValidatedOrder',
details: ['Reject missing items'],
color: '#0f766e',
}
Do not generate x, y, width, height, hasChildren, or a duplicated file string. Use childLevelId and structured sourceRefs.
Node Kinds
| Kind | Use for |
|---|
input | External request, event, file, or user input |
ui | Browser/client component or interaction |
process | Internal transformation or orchestration |
decision | Validation, guard, branch, or lookup with multiple outcomes |
api | HTTP/RPC handler or service boundary |
storage | Database, cache, queue, or persistent/in-memory store |
output | Response, redirect, rendered result, or terminal outcome |
Edge
{ id: 'parse-validate', source: 'parse', target: 'validate' }
{ id: 'validate-save', source: 'validate', target: 'save', label: 'valid' }
{ id: 'validate-error', source: 'validate', target: 'error', label: 'invalid', kind: 'failure' }
{ id: 'browser-api', source: 'browser', target: 'api', label: 'POST /orders', kind: 'boundary' }
Every edge ID must be unique within its level. Source and target must reference nodes in the same level.
Connection Kinds
- Omit
kind for a normal in-process flow.
- Use
kind: 'failure' for validation errors, exceptions, not-found branches, and retry loops. These render as dashed amber edges.
- Use
kind: 'boundary' when crossing a network, process, storage, or external-service boundary. These render as thick indigo edges.
- Keep labels short: an event, condition, protocol, or endpoint—not a sentence.
Automatic Layout Rules
- ELK Layered calculates all node positions and orthogonal routes.
- Array order is meaningful: list nodes and edges in the intended reading order for stable results.
- Do not solve clutter by adding coordinates. Shorten labels, reduce cross-links, introduce a bridge node, or split the level.
- Keep exception paths outside the main path by modeling them as short terminal branches.
- Avoid edges that cross between different levels. A parent node summarizes the child level's input/output boundary.
- Cycles are supported, but a dense cyclic graph should be simplified to its important control loop.
Key Implementation Notes
- Do not modify
index.html, viewer.js, or viewer.css in generated output. Only generate or edit data.js.
- The viewer validates duplicate IDs, missing child levels, and invalid edge endpoints on load.
- Clicking a node with
childLevelId opens that level. Clicking a leaf opens the inspector.
- Keyboard:
h/j/k/l or arrow keys navigate, y copies the selected leaf as Markdown, q/Escape closes or goes back.
- The viewer is an IIFE bundle, so opening
index.html directly from file:// requires no dev server.
- Changes to
viewer/src/ require npm run build, which regenerates tracked viewer assets and syncs docs/.