Releases: csthink/dashmotion
2.2.4 — Output safety: attribute-safe escaping, ARIA wiring, input sanity
A patch, not a feature: same inputs, same self-contained-HTML output contract. Three generator-internal hardening items.
Fixed
- A
\"(or') in any label / id no longer corrupts the output.esc()escaped only& < >, yet its result feeds attribute contexts (data-grp,data-grp-id,<title>/<desc>); a single quote broke out of the attribute, so the SVG stopped parsing as XML and arbitrary markup could go live. It now also escapes\"→"and'→'— lossless (rendered identically as text;check_fidelityunescapes before comparing, so labels stay verbatim). No attacker needed; a Mermaid label with a quote triggered it. - A malformed group
parentcycle no longer hangs the engine forever. The layout walked the parent chain in three places with no cycle guard, so a loop spun indefinitely — a silent hang that ate the whole latency budget. Generation now validates up front and exits with a named cycle.
Added
- Style-token validation (fail-safe-to-render). Journey dot
color, classDefsemStroke/semDash, andlegendExtrastroke/dash are validated (color = hex orrgb[a], dash numeric). An unrecognized value falls back to the engine default and prints a one-line stderr notice; it never drops a node or aborts the render. - ARIA wiring on the output SVG.
<title>/<desc>now carry ids; the<svg>links them viaaria-labelledby/aria-describedbyand setsaria-roledescription(flowchart/architecture diagram). Invisible to sighted users; the file stays self-contained. - Pre-render input sanity (fail-closed). Missing
id/from/to, edge/journey endpoints referencing unknown nodes, and groupparentreferencing an unknown group are all reported at once with a readable list instead of a deep traceback. Not a general schema validator — only the invariants the engine assumes.
Verified
run_checks11/11,check_diagram0 violations (incl. C9) on all 12 fixtures,check_fidelityPASS. End-to-end medium-effort run: 11/11 cases verified, a fresh bianque-class 30+ node diagram in ~3 min (inside the 8-min gate). Performance-neutral: model output unchanged; render +~0.8 ms/figure, output +~1.4% (ARIA attributes).
Install: npx skills add csthink/dashmotion -a claude-code -g; upgrade: npx skills update dashmotion -g -y; or download the zip.
2.2.3 — Leaner model output + group-membership check
2.2.3 — Leaner model output: omittable shape/tier + group-membership check
A patch, not a feature: same inputs, same self-contained-HTML output contract.
Two fields the model used to hand-write on every node are derivable, so the
authoring docs now tell it to omit them — less model output (the project's dominant
cost) for an identical diagram — and a new structural check closes a blind spot in
the verifier. Nothing new to ask for.
Changed
- Flow
shapeis omitted on steps.stepis exactly what the engine renders
whenshapeis absent, so the authoring contract now says to writeshapeonly
for pills and decisions, never"shape": "step". Identical render, less output —
a livem7-pr-cicdgeneration trimmed ~170 B of node JSON (≈10% of the flow graph). - Architecture
tieris omitted for ungrouped / single-group diagrams. The
engine already layers by longest-path whentieris absent; the docs now say to
omittierthere (all-or-nothing) and keep it explicit only for multi-group
diagrams, or when a cross-cutting sink must be pinned to a row. A live ungrouped-arch
generation trimmed ~77 B (≈12% of its node array). - The omission guidance is deliberately imperative ("do not write it; omit it"),
not permissive: a live test showed an "optional" framing left the model writing
every field anyway, realizing zero saving. The docs state the cost so the model acts.
Added
check_diagramC9 — group membership. A node sitting fully inside a group box
it is not a member of is now reported. This is the silent corruption class the
existing C1 cannot see — C1 exempts full containment (subnet-in-region is a
legitimate box-contains-node case), so a group-blind layout could swallow a foreign
node with a green check. To make membership judgeable from the HTML alone (no graph
JSON needed at generation-time Step 6), the renderer now embedsdata-grp(a node's
resolved ancestor-group set) anddata-grp-id(a box's group) on architecture
rects. The attributes are invisible and the file stays self-contained.
Verified
run_checks11/11,check_diagram0 violations (including C9),check_fidelity
PASS. Group-membership guardcheck_c9.py: authored fixtures 0 C9; tier-stripped
multi-group fixtures correctly FAIL C9 (the previously-silent corruptions).- Live medium-effort validation: flow (
m7) omitted all 12 step shapes; an ungrouped
architecture omitted all tiers (engine auto-layered cleanly, sinks at the bottom);
bianque (35 nodes / 38 edges, multi-group) kept its tiers, generated in ~4 min
(inside the 8-min perf gate), 0 violations including C9 — no false positive on a
freshly generated multi-group diagram.
v2.2.2 — Self-contained output; stricter label fidelity
A patch — same inputs, same output contract; the rendered file is now fully self-contained, and the fidelity check no longer hides a dropped label separator.
Changed
- Output drops the Google Fonts dependency — now truly self-contained. The rendered HTML no longer links
fonts.googleapis.com; it falls back through a system monospace stack ('JetBrains Mono', ui-monospace, 'SF Mono', 'Cascadia Code', Menlo, Consolas, monospace), so JetBrains Mono still renders when installed locally, but the file opens offline, issues no third-party request, and carries zero external assets. The output contract's "no external assets except Google Fonts" becomes just "no external assets."
Fixed
check_fidelity.pycatches a genuinely dropped label separator. It used to strip separator punctuation (::·•,,;;) before matching, which also silently accepted a label whose separator was lost in rendering. It now matches the separator as an element boundary — the legitimate architecture label/sublabel split (A:B→ two adjacent<text>elements) still passes, while a real collapse (A:B→ "A B" in one element) is reported instead of hidden.
Verified
run_checks11/11,check_diagram0 violations,check_fidelityPASS (incl. the new boundary case). Local-test bianque (35 nodes / 38 edges) generated in ~3 min, inside the 8-min perf-gate. Model output and render latency unchanged — both changes live off the model's authoring path.
Install / update (Claude Code): npx skills add csthink/dashmotion -a claude-code (re-run to update in place). claude.ai: download dashmotion.zip below → Settings → Skills → upload.
v2.2.1 — Performance: layout.py renders the finished file
A performance patch — same inputs, same self-contained-HTML output contract; the generator just does more of the work, so diagrams come out faster.
Changed
layout.py --render out.htmlwrites the complete, ready-to-ship HTML (geometry + style layer + the model's copy) instead of the model hand-transcribing 35 rects and 38 pathds into a template. The semantic graph JSON now carries the copy (subtitle, a 3-cardsummary, optionalfooter); the model authors semantics + copy and runs the script, keeping final say by editing the JSON (re-render) or the emitted file.--emit-svgkept as an alias; the hand-transcribe path remains the no-Python fallback. The tempgraph.jsonis written outside the output folder, so the user's folder holds only the.html.- Routing: shared per-source trunk lanes — a node fanning out to several off-column targets shares one margin trunk with horizontal taps instead of N lanes marching into empty space (bianque: 12 left lanes → 3, left band −64%).
- Journey dots speed up on long edges — per-hop dot duration capped at 4s, so dots on long cross-diagram edges no longer crawl (bianque slowest ~11.6s → ≤4s).
Performance
- Generation output the model must write drops ~84% aggregate across the 11-case regression and ~79.5% on the bianque-class benchmark. Regression green:
run_checks11/11,check_diagram0 violations (12 graphs),check_fidelityPASS (7 mermaid + bianque). Local-test bianque (35 nodes / 38 edges) generated in ~3 min — inside the 8-min perf-gate, down from ~5 min.
Install / update (Claude Code): npx skills add csthink/dashmotion -a claude-code (re-run to update in place). claude.ai: download dashmotion.zip below → Settings → Skills → upload.
v2.2.0 — Mermaid input + deterministic layout engine
Feature release — paste a Mermaid source (or describe a system in plain English) and get the same animated, self-contained HTML diagram.
Highlights
- Mermaid input —
flowchart/graph/stateDiagram-v2→ an animated diagram. Every node, edge, edge label and subgraph containment is preserved; layout is recomputed top-down. Unsupported diagram types are declined rather than lossily guessed. - Deterministic layout engine (
scripts/layout.py, pure stdlib) — the model emits a semantic graph, the script computes all geometry (routing, boundaries, journeys). Large diagrams generate dramatically faster, with zero structural violations. - Mechanized self-check — bundled
check_diagram.py(structure) andcheck_fidelity.py(Mermaid labels/edges verbatim) run at generation time and fix what they find.
The output stays dependency-free: one self-contained HTML file — no libraries, no build step.
Install
- Claude Code:
npx skills add csthink/dashmotion -a claude-code - claude.ai: download
dashmotion.zipbelow → Settings → Capabilities → Skills → + Add → upload → toggle on
Full notes: CHANGELOG.md
v2.1.1 — npx skills add support
Patch over v2.1.0. No change to the skill's behavior, animation contracts, or output — this makes the skill installable via the skills CLI and fixes a latent frontmatter bug.
What's new
npx skills add csthink/dashmotionnow works (andnpx skills updateto update in place). The skill moved intoskills/dashmotion/, so the CLI installs only the skill files — a clean ~KB install, no eval artifacts or demo GIFs dragged along.- Fixed invalid YAML frontmatter. The
descriptioncontained a bare:("…anything that moves: requests…") that is illegal in an unquoted YAML scalar. Claude's loader tolerated it; strict parsers (skills.sh) rejected the skill outright. Now single-quoted — exact triggering text unchanged.
Install
skillsCLI:npx skills add csthink/dashmotion- claude.ai → Settings → Capabilities → Skills → + Add → upload
dashmotion.zipbelow → toggle on - Claude Code (manual) →
unzip dashmotion.zip -d ~/.claude/skills/
Zip contains dashmotion/ (SKILL.md + references/ + resources/), identical layout to v2.1.0; verified sha256-matching the tagged tree.
v2.1.0 — Structural self-check
What's new
Step 6 — post-generation structural self-check. Before delivering a diagram, the skill now re-verifies the SVG it just produced against a structural checklist (overlapping boxes, connectors cutting through nodes, broken animation loops, out-of-viewBox coordinates, connector/markup hygiene) and fixes what it finds. Animation contracts, design tokens, accessibility, and the pure-SVG/SMIL/no-JS output form are unchanged.
Eval harness (eval/). 10 realistic prompts (5 flow + 5 architecture), a deterministic geometry checker (check_diagram.py), paired baseline/checked runs, and EVAL.md with the before/after numbers. Headline: layout-arithmetic failures were 0/10 — so deterministic auto-layout (elkjs) is deferred; the残余 failures sit in the animation-geometry layer instead.
Refreshed demo GIFs. Richer examples (CI/CD pipeline; Kubernetes + Kafka platform), captured in real time, sharper and ~3× smaller than before.
Install
Download dashmotion.zip below, then:
- claude.ai → Settings → Capabilities → Skills → + Add → upload → toggle on
- Claude Code →
unzip dashmotion.zip -d ~/.claude/skills/
Zip verified byte-for-byte against the tagged tree (SKILL.md + references/×2 + resources/×2).
dashmotion v2.0.0
First public release. Diagrams that move — a Claude AI skill that generates animated technical diagrams as self-contained HTML/SVG files. The name is the implementation: stroke-dashoffset + animateMotion.
Two modes
- Flow — workflows, pipelines, state machines. Dashed connectors stream from START to END through branches and merges.
- Architecture — system topology with semantic component colors, region/security-group boundaries, legend, summary cards — and the differentiator: animated request journeys. A dot leaves the client, hops through CDN → gateway → service → database via chained SMIL timing, then a new request begins.
Install
- Download
dashmotion.zipbelow - claude.ai → Settings → Capabilities → Skills → + Add → upload → toggle on
Or Claude Code: unzip dashmotion.zip -d ~/.claude/skills/
Notes
- Output is a single HTML file: vector, infs anywhere. Convert to GIF/MP4 with one
timecut/ffmpegcommand when needed. prefers-reduced-motionrespected; every diagram ships a pause toggle.- Coexists with Cocoon-AI/architecture-diagram-generator — animation intent routes here, static requests stay there. Tested side by side.
Requires Claude Pro, Max, Team, or Enterprise.