Install
openclaw skills install @biubiubiu533/code-flow-graphGenerate interactive HTML node-graph diagrams for code visualization. Trigger when user asks to: visualize code architecture, diagram module dependencies, map call chains, graph class relationships, show UI event flows, display widget hierarchy layouts, or understand how code connects. Keywords: "visualize", "diagram", "graph", "map out", "call chain", "architecture", "code flow", "widget hierarchy", "UI layout", "界面布局", "调用链", "代码架构", "可视化", "模块依赖", "函数关系", "类图", "事件流".
openclaw skills install @biubiubiu533/code-flow-graphGenerate interactive node-graph HTML diagrams that visualize code structure and call relationships.
Two files in <project>/docs/code_graph/ (or user-specified / config.json path):
code_flow_graph.html — rendering engine (copy verbatim from example/code_flow_graph.html in THIS skill's directory)code_flow_graph_data.js — diagram data (you generate this; use templates/diagram_skeleton.js as starting point)This is a guide, not a script. Adapt steps based on project size, user needs, and context. Skip or merge steps when appropriate.
references/analysis_guide.md for inclusion/exclusion criteria.ask_followup_question with dynamic options based on discovered entry points. Always include "自定义:分析其他函数或模块" as last option.references/deep_dive_types.md.scripts/validate_data.js on the generated file; fix any errors before delivering.Check config.json in this skill's directory for user preferences. If missing, use defaults:
<project>/docs/code_graph/On first run for a project, create state/code_flow_graph_session.json:
{
"project": "<absolute-project-path>",
"created_at": "<ISO8601>",
"updated_at": "<ISO8601>",
"analyzed_entries": ["func1", "func2"],
"generated_diagrams": ["overview", "func1_callchain"],
"pending_items": ["func3_callchain", "ui_events"],
"last_config_hash": "<sha256-of-config.json>"
}
On subsequent runs, read this file to resume context: skip re-analysis of completed entries, continue from pending_items.
references/data_format.mdtemplates/node_patterns.js (6 node types + connections + groups)templates/diagram_skeleton.js (copy as starting point)references/deep_dive_types.mdreferences/analysis_guide.mdThe template is at example/code_flow_graph.html relative to THIS skill's SKILL.md file. Use the absolute path based on the skill's installation directory. Do NOT resolve it relative to the user's project root.
Why: The HTML engine lives inside the skill directory, not the user's project. Resolving relative to the project root yields "file not found."
// ❌ Wrong — resolves against user's project (file won't exist there)
fs.copyFileSync('example/code_flow_graph.html', outputDir);
// ✅ Right — resolve against THIS skill's installation directory
fs.copyFileSync(path.join(SKILL_DIR, 'example/code_flow_graph.html'), outputDir);
offsetTop, Not getBoundingClientRectWhy: The canvas uses CSS transform: scale() for zoom. getBoundingClientRect() returns screen-space coordinates that include the scale factor, causing connections to misalign at any zoom level other than 1x.
// ❌ Wrong — misaligns at zoom ≠ 1x
var relY = (el.getBoundingClientRect().top - nodeEl.getBoundingClientRect().top) + el.offsetHeight / 2;
// ✅ Right — layout-space coordinates, zoom-independent
var relY = el.offsetHeight / 2;
var cur = el;
while (cur && cur !== nodeEl) { relY += cur.offsetTop; cur = cur.offsetParent; }
Why: After switchDiagram() resets scale = 1; panX = 0; panY = 0;, measurements in redrawConnections() read stale CSS transform values unless applyTransform() runs first.
// ❌ Wrong — measurements happen against stale transform
switchDiagram(key);
requestAnimationFrame(() => redrawConnections());
// ✅ Right — apply transform before requesting redraw
switchDiagram(key);
applyTransform();
requestAnimationFrame(() => redrawConnections());
callChain[].id Must Match Attr IDs ExactlyWhy: The detail panel uses callChain item IDs to highlight the corresponding node/attr on click. A mismatch silently breaks click-to-highlight with no error.
// ❌ Wrong — inconsistent ID format
{ id: 'method_name', name: 'method_name()', ... } // Missing NodeId prefix
// ✅ Right — format is always NodeId.method_name
{ id: 'ClassName.method_name', name: 'method_name()', ... }
// Must exactly match an existing attr's id in the same diagram
Why: The file is loaded via <script src>. A single syntax error (missing comma, unescaped quote, unbalanced brace) silently breaks the entire viewer with no user-visible error.
// ❌ Wrong — missing comma between array items, unescaped string
attrs: [
{ id: 'A.foo', name: 'foo()' } // ← missing comma
{ id: 'A.bar', name: "it's broken" } // ← unescaped quote
]
// ✅ Right — valid JS, properly escaped
attrs: [
{ id: 'A.foo', name: 'foo()' },
{ id: 'A.bar', name: "it\\'s fixed" },
]
Validation: Always run node scripts/validate_data.js <file> before delivering.
Why: Default thresholds (fan-out >= 2, fan-in >= 3) produce unreadably dense diagrams on large codebases (> 500 lines per diagram page).
// ❌ Wrong — default thresholds on a large project → 80+ nodes
fan_out_threshold: 2, fan_in_threshold: 3
// ✅ Right — raised thresholds for large projects
fan_out_threshold: 3, fan_in_threshold: 4
// Also: collapse deeper calls into `children`, summarize repetitive patterns
Why: The Overview is for architecture comprehension. Per-function detail belongs in deep-dive diagrams. Mixing levels makes the Overview unreadable.
// ❌ Wrong — Overview with individual functions as nodes
DIAGRAMS.overview.NODES = [
{ id: 'parse_args', type: 'function', ... },
{ id: 'validate_input', type: 'function', ... },
];
// ✅ Right — one node per module/class in Overview
DIAGRAMS.overview.NODES = [
{ id: 'cli', label: 'CLI Module', type: 'module', ... },
{ id: 'core', label: 'Core Engine', type: 'class', ... },
];
Why: The HTML file contains a tightly-coupled rendering engine with search, tooltips, panels, persistence, and undo. Any modification risks breaking these interconnected features.
// ❌ Wrong — editing the HTML to add a feature
// Adding custom CSS, modifying event handlers, changing DOM structure
// ✅ Right — copy verbatim, all customization goes in the data file
// The engine supports: search, tooltips, callChain panel, fieldDetail panel,
// drag persistence, undo, groups, themes — all driven by data alone.
Why: Scattered or overlapping node placement makes diagrams unreadable. The engine expects consistent column-based positioning.
// ❌ Wrong — random positions, overlapping nodes
{ id: 'A', x: 47, y: 133, w: 280, ... },
{ id: 'B', x: 52, y: 180, w: 280, ... }, // overlaps A
// ✅ Right — grid-aligned columns (30, 350, 670, 990...) with 40px vertical gaps
{ id: 'A', x: 30, y: 60, w: 280, ... },
{ id: 'B', x: 30, y: 300, w: 280, ... }, // same column, proper gap
{ id: 'C', x: 350, y: 60, w: 280, ... }, // next column
Why: Users accumulate diagrams across multiple requests. Regenerating the file loses all previous deep-dive diagrams, breaking the append-only contract.
// ❌ Wrong — overwriting the entire data file
var DIAGRAMS = {}; // Wipes all existing diagrams
DIAGRAMS.new_chain = { ... };
// ✅ Right — read existing file, append new diagram entry, write back
// 1. Read existing code_flow_graph_data.js
// 2. Add new DIAGRAMS.new_chain = { ... }; at the end (before UI_LAYOUT_VIEWS if any)
// 3. Write the complete file back
UI_LAYOUT_VIEWS)