harness/plugins/exploration/claude/skills/flow-map/SKILL.md
Render an interactive single-page HTML that visualizes packages/components and the cross-package flows of named actions (e.g. "Invite new user", "todesktop build"). Driven by a JSON document. Use when the user says "flow map", "render flows", "interactive workflow html", "visualize package interactions", or has a flows.json from the `explore` skill they want to view.
npx skillsauth add popoffvg/dotfiles flow-mapInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Produce one self-contained HTML file that:
kind on a dark canvas (ToDesktop-style architecture diagram).path:line.Input: a JSON document. Output: a single .html file.
{
"title": "MyApp — Architecture & Flows",
"packages": [
{
"id": "web", // unique slug used in edges
"label": "Web Frontend", // node title
"sub": "apps/web", // optional 2nd line under title
"kind": "actor|client|codebase|sdk|backend|external",
"description": "..." // shown in tooltips / steps if you add it
}
],
"flows": [
{
"id": "invite-user",
"label": "Invite new user",
"description": "...",
"edges": [
{
"from": "web", "to": "api",
"via": "POST /invites", // transport label
"payload": "{ email, role }", // 1-line summary
"source": "apps/web/src/Invite.tsx:84", // verifiable path:line
"notes": "..." // optional caveat
}
]
}
]
}
edges[] order is the temporal step sequence — the renderer numbers them 1, 2, 3, ….
kind taxonomy (drives swimlane columns)| kind | Column label | Tint |
| ---------- | ------------------------ | --------- |
| actor | ACTORS | #fbbf24 |
| client | CLIENT SURFACE | #60a5fa |
| codebase | BLOCK / FUNCTION CODEBASE| #34d399 |
| sdk | SDK / LIB | #a78bfa |
| backend | BACKEND PIPELINE | #f97316 |
| external | EXTERNAL SERVICES | #f87171 |
Free to extend — just pick a hex tint and a header label per new kind.
Default path <input-dir>/index.html next to the source JSON (or
${TMPDIR%/}/claude-flow-map/<basename>.html if input is outside a project).
${TMPDIR%/}/claude-explore/*/flows.json or */flow-map/flows.json in .notes/.edge.from/edge.to resolves to a known package.id.
Every flow.id is unique.mkdir -p if needed.Write tool.
Do NOT generate the HTML through a bash heredoc — see the bash trap below.open on macOS may fail under sandbox; tell
the user to open the file manually if it does.! history expansion mangles <!doctypeBash performs history expansion on ! even inside single-quoted heredocs
on some setups. Result: every <! becomes <\!, the browser stops parsing the
file as HTML, and you get a blank page with literal <\!doctype html> text at
the top.
Fix: never write the HTML through bash << 'EOF' or python3 -c "..."
piped through bash. Build the full HTML string in memory and pass it to the
Write tool. The Write tool bypasses the shell — bytes land verbatim.
Sanity-check after writing:
head -c 16 path/to/index.html # must print: <!doctype html>
</ inside an inlined JSON string closes the <script> tagWhen embedding a JSON literal between <script> tags, any </ substring in
your data terminates the script element. Either:
{ … } directly, not a
JSON string), or</ → <\/ in the resulting string.The first form is what this skill uses.
min-height:0 on its row track
and min-height:300px on #cy or Cytoscape draws nothing.'background-color': ele => … is brittle across
Cytoscape versions. Precompute the color into node data and use
'background-color': 'data(color)'.[email protected].open fails under the agent sandbox. That's not your bug; just print the
path.The skill's HTML is built around these ideas (paste/adapt — keep ~300 lines):
1fr 340px. Left = canvas, right = sidebar.#0a0a0a bg, #e5e7eb text, #fbbf24 accent, #262626
borders).kind), styled with a dashed border, a
small uppercase header label colored in the column tint, and
compound-sizing-wrt-labels: include.parent: <column-id>, fixed position: { x, y },
layout: { name: "preset" }. Columns auto-size to fit.curve-style: unbundled-bezier with control-point-distances
for the curved orange look. target-arrow-shape: triangle.text-background-color: #fbbf24, text-background-shape: round-rectangle,
text-background-padding: 4px, plus a dark text-border for contrast..loop class with loop-direction / loop-sweep.<div class="num">N</div> + a
block with from → to, the via label, payload (monospace), source
(smaller monospace), and notes (in #fde68a).cy.edges().remove(), recompute participants set, toggle
.hot / .dimmed on package nodes, add edges with num: String(i+1),
re-render the STEPS panel.A complete working copy lives at
~/Documents/git/mil/tasks/MILAB-6225-identity-propogation/.notes/flow-map/index.html
— copy-paste and swap the data block when bootstrapping new diagrams.
Re-run the skill — it overwrites the previous HTML in place. The JSON beside
it (flows.json) is the source of truth; keep them next to each other so the
user can edit JSON and re-render.
flow.edges participation order).payload field is a 1-line summary by design. Long structures belong in
the linked source.testing
Use when the user asks to create test sets, enumerate scenarios, generate edge cases, or draft a coverage matrix before implementation.
testing
Use when the user asks to review, audit, score, or validate test sets for missed cases before execution or merge.
tools
Test harness plugins in isolation using tmux panes. Runs MCP servers, unit tests, typecheck, and Claude plugin loading. Use when user says "test plugin", "check plugin", "run plugin tests", "validate plugin", or names a specific plugin to test.
development
Guide for designing integration and e2e tests using BDD (Behavior-Driven Development) methodology with Cucumber-style Given/When/Then scenarios. Use when writing or reviewing tests for any service, API, or component. Language-agnostic — covers scenario structure, step notation, assertion principles, async patterns, and common anti-patterns.