visual-explainer
/visual-explainer
Buduje samodzielne strony HTML z ręcznie rysowanymi diagramami SVG, odtwarzaczami kroków i zestawami wielostronicowymi dla systemów technicznych.
- Autor
- hongguifeng ↗
- Repozytorium
- visual-explainer ↗
- Licencja
- MIT
- Ostatnia zmiana repozytorium
- 07.11.2026
Ocena i bezpieczeństwo
- Pliki w paczce
- 5
- Skrypty
- 0
- Komentarze HTML
- 0
- Adresy URL w SKILL.md
- 2
Brak sygnałów. Repozytorium zmienione 07.11.2026, bez odwołań do wycofanych modeli i API.
MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.
Co robi i kiedy
Buduje samodzielne strony HTML z ręcznie rysowanymi diagramami SVG, odtwarzaczami kroków i zestawami wielostronicowymi dla systemów technicznych.
Oryginalny opis (EN)
Build offline, self-contained HTML visual explainers for technical systems — hand-drawn SVG diagrams, step players/animations, and multi-page suites. Use when asked for an HTML diagram page, interactive visualization, architecture/flow animation, or a visual version of a long document.
Jak działa
- 0. Pick the shape before writing HTML
- 1. Evidence before drawing
- 2. Storyboard, then draw
- 3. Build the shared kit first
- 4. Draw the diagram so it cannot lie
- 5. The player contract
- 6. Failure catalogue (what actually went wrong)
- 7. Verify mechanically
- 8. Pre-ship checklist
- 9. Bundled files
Podgląd SKILL.md
---
name: visual-explainer
description: Build offline, self-contained HTML visual explainers for technical systems — hand-drawn SVG diagrams, step players/animations, and multi-page suites. Use when asked for an HTML diagram page, interactive visualization, architecture/flow animation, or a visual version of a long document.
---
# visual-explainer
A visual explainer is **an argument made of pictures**, not a pile of pretty boxes. Each page makes one
claim, shows the evidence, and lets the reader replay the part where order matters. Everything must open
from `file://` with no network.
Start from `page-template.html`. When the repository already has a visual suite, read one page's source
and copy its conventions rather than inventing new ones.
## 0. Pick the shape before writing HTML
| Situation | Deliverable |
| --- | --- |
| One mechanism, ≤ 5 diagrams | Single page |
| A subsystem with structure + sequence + concurrency + state | 5–9 page suite, one claim per page |
| Order/race/failure timing matters | Add a step player to the static diagram |
| Exhaustive enumeration (ioctls, flags, error codes) | Table, not a diagram |
| Two backends or versions differ | Side-by-side page, or one explicit column per variant |
Rules of thumb:
- **More than ~6 diagrams, or more than 3 interacting subsystems → split into pages.** One 100 KB page
is harder to navigate and to edit than nine 15 KB pages.
- **A player is justified only when the reader must see a sequence.** If a static before/after picture
answers the question, draw that instead. 5–10 steps is the sweet spot; 15 is a code walk, not a visual.
- Name the reader's acceptance action first: "after this page they can explain why a 4 KiB oneway fails
at message 128", not "cover the allocator".
## 1. Evidence before drawing
A wrong arrow is worse than a missing one. Build a fact ledger before the first `<rect>`:
- Every constant, field order, branch condition, and runtime number on screen must resolve to a
`file:line` or a captured command output. Put the strongest anchors in the page footer.
- Mark runtime observations with the environment (`staging build 42`, `main@abc1234`) and keep them
separate from source facts (`main@def5678`).
- Where two implementations differ, **never average them into one drawing**. Pick one and label it, or
draw both columns.
- Re-verify claims that "everyone knows". Two real regressions caught this way: a diagram said a memory
allocator never merges adjacent free blocks (the implementation does), and a plausible-looking state
constant did not exist anywhere in the source. Both had already shipped in diagrams.
If a number appears on several pages, keep one source for it and reuse the exact value. Drift between
pages destroys trust faster than a missing detail.
## 2. Storyboard, then draw
Write a table before writing markup:
| # | Page claim (a sentence) | Visual | Interaction | Evidence |
| --- | --- | --- | --- | --- |
| 03 | A request passes nine stages, each with a failure exit | stage timeline + buffer layout | offset translation | `src/transaction.c:handle` |
| 04 | Worker threads sleep in `wait_for_work`; there is no thread per worker in the kernel | bitfield + state machine | thread lifecycle | `src/worker.c:wait_for_work` |
Six reusable viewpoints; pick the two or three the page actually needs:
1. **Structure** — who points to whom (client / worker / queue / task).
2. **Sequence** — one call in time order, including failure exits.
3. **Concurrency** — queues, waiters, wakeups, what runs in whose context.
4. **State machine** — lifecycle, freeze, refcount transitions.
5. **Layout** — bytes, headers, page tables, segment splits.
6. **Observability** — files, endpoints, metrics, logs, how to see the state yourself.
A page title should state the claim ("there is no thread per worker in the kernel"), not the topic
("threading model").
## 3. Build the shared kit first
```
suite/
├── index.html
├── objects.html
├── ...
└── assets/
├── kit.css # tokens, layout, cards, tables, player, diagram primitives
└── kit.js # markers, player engine, tabs, TOC
```
Start from this skill's `assets/kit.css` and `assets/kit.js`; do not fork them per page. One suite, one
design system, one player implementation.
```bash
SKILL_DIR=/path/to/visual-explainer
mkdir -p docs/my-suite/assets
cp "$SKILL_DIR"/assets/kit.css "$SKILL_DIR"/assets/kit.js docs/my-suite/assets/
cp "$SKILL_DIR"/page-template.html docs/my-suite/index.html
```
Conventions that scale from one page to nine:
- 1280 px shell, 220 px sticky TOC, 1180×N `viewBox` for wide diagrams; let SVG scale with `width:100%`.
- Semantic colors, used consistently: indigo = normal/sync, cyan = memory/allocator, green = success,
amber = warning/backpressure, rose = failure/death, violet = deferred/async or the other implementation.
- Two SVG text sizes are enough (`.sm` 10.8 px, `.xs` 9.8 px). Below 10 px at 1180 wide becomes
unreadable when the page is projected.
- Diagram captions are numbered (`Figure 1-3`) and carry a source line. A figure without a caption is
decoration.
- A fixed nav with one link per page, plus a prev/next pager; page numbers in `h2 .no` match the nav order.
Page skeleton: claim (`h1` + lede) → 3–6 sections, each one diagram or one player → a table for the
exhaustive part → failure modes/traps → footer sources.
## 4. Draw the diagram so it cannot lie
- Lay out on a grid (header row, lane columns, 40–60 px row pitch). Free-hand coordinates are where
overlaps and crossing wires come from.
- Estimate label width before placing it: Latin `chars × 0.55 × font-size`, CJK `chars × 1.0 × font-size`.
Leave 8 px padding; if it does not fit, shorten the label or move it to a second line.
- One direction per diagram: time flows down or right, not both. Lane diagrams: time down, actors across.
- Solid wire = the path being explained; dashed = deferred, async, reclaim, or "later". Put this in a legend.
- Every failure exit gets its own labeled arrow (`QUEUE_FULL`, `TIMEOUT`). A diagram that only shows the
happy path teaches half the system.
- Keep one diagram under ~25 primitives. If it needs more, split it or move detail to a table.
- Define arrow markers once per document (see `kit.js`), reference them as `marker-end="url(#ahb)"`.
Marker IDs are document-global: duplicate `<defs>` blocks with the same IDs behave unpredictably.
- Accessibility: `role="img"` + `aria-label` on the `<svg>`; never encode meaning by color alone; give a
text/table equivalent for the critical numbers.
See `references/svg-craft.md` for geometry, text wrapping, CSS-vs-attribute conflicts and a collision checklist.
## 5. The player contract
A player is a tiny state machine, not a pile of `setTimeout`s. The bundled `kit.js` implements this
contract; keep it if you write your own.
```js
Kit.player('#stage', {
reset(){ /* restore EVERY visual + counter + caption to initial state */ },
steps:[
{chip:'1 enqueue', title:'…', who:'queue.enqueue()', body:'…', code:'…', hold:900,
run: async (instant)=>{ /* mutate state; await Kit.wait(ms,instant); paint(); */ }}
]
});
```
Hard requirements:
- `seek(i)` = `reset()` + replay steps `0..i` (`instant` for `k < i`). Replaying is what makes jumping
to step 7 consistent with pressing "next" seven times.
- A monotonically increasing **generation token** cancels stale runs when the reader clicks ahead or
presses play twice. Every `await` is followed by a generation check.
- `run(instant)` only mutates state and calls `paint(state)`; it must be idempotent and must not read
the clock except through `Kit.wait`.
- `reset()` restores captions too, not just the SVG. The bundled kit snapshots the initial `data-cap`
markup and restores it.
- Controls: play/pause, prev, next, reset, speed, clickable step chips, keyboard (`Space`, `←/→`,
`Home/End`). Show current/done state on the progress strip.
- Expose `window.Kit.players` so tests can seek deterministically.
More detail and the race-condition walkthrough: `references/player-engine.md`.
## 6. Failure catalogue (what actually went wrong)
### Content
1. **Drawing from memory.** A plausible label is not a fact. Verify the symbol exists in the source before
it becomes a box; a fake constant or an inverted behaviour is worse than no diagram.
2. **Mixing variants.** Two backends or two versions differ in enum values, output formats, or feature
sets. Label the variant on the page and in the caption.
3. **Mixing versions.** The running build may be older than the source tree. Resolve conflicts by version
and say which one the picture shows.
4. **Numbers drifting between pages.** Use one value and one source; grep the suite for the number before
shipping.
### SVG
5. **Text escaping leaking into captions.** `title:'… ptr->next …'` rendered through `textContent`
shows the literal `->`. Either write `→`, or render controlled strings with `innerHTML` (as `kit.js` does).
6. **CSS class overriding presentation attributes.** `.cbox{fill:#fff}` beats `fill="#eef2ff"`, so the
"highlighted" state never appears. Drive state with classes and set both `fill`/`stroke` in CSS, or use
CSS variables everywhere for that element.
7. **Wires through labels.** Route around text boxes; when a long cross-lane arrow must pass a lane, give it
its own row where that lane has no content.
8. **Labels outside the viewBox.** They are silently clipped. Run the DOM audit (§7) rather than trusting the eye.
9. **Arrowheads missing.** The marker id is undefined, or the marker is defined in a different SVG. Inject
one document-level `<defs>` before first paint.
10. **`<br>` inside SVG text.** It does nothing. Use separate `<text>`/`<tspan>` lines with explicit `dy`.
### Player / JS
11. **Not awaiting `seek()` in tests.** `seek` is async; reading the DOM on the next line shows the reset
state. This once produced a false "the queue never splits" result.
12. **Partial reset.** SVG resets but the caption, notification box, gauge, or play-button label still shows
the last step. Reset must be a single function that restores *all* of them.
13. **Fast clicking corrupts state.** Two overlapping `seek`/`play` loops interleave. Generation token, and
check it after every await.
14. **Reading the hidden tab.** A parser or counter that queries the document globally picks the first pane,
not the visible one. Scope to `.pane.on` and re-run after `setTimeout(...,0)` on tab change.
15. **Dead stage.** A 300 px `min-height` plus no initial content leaves half the player blank. Either show
an intro hint or shrink the stage for the first step.
### Layout
16. **Step chips overflow.** 13 chips do not fit a narrow card. Keep `overflow:auto`, short chip labels,
and test at 1024 px.
17. **Wide tables/code blow out the grid.** Add `min-width:0` to grid children and `overflow:auto` to the
scroller; don't rely on `white-space:nowrap` for long code.
18. **Tiny SVG text.** A 1180-wide diagram scaled into a 700 px column halves the font. Put dense diagrams
full width (`.player.wide`, full-bleed `.diagram`) instead of shrinking the type.
### Process
19. **Editing a 100 KB page with global replace.** Grep the count first; a wording fix needed in 5 places
was applied to 3. Prefer one edit call per region and re-grep afterwards.
20. **Screenshot-only QA.** Screenshots catch composition, not state. Pair them with DOM assertions and a
bbox audit; see §7.
## 7. Verify mechanically
Run from the suite directory. The paths below assume this repo; if the skill is installed elsewhere,
replace `.agents/skills/visual-explainer` with the installed skill directory:
```bash
SKILL_DIR=/path/to/visual-explainer
python3 "$SKILL_DIR"/scripts/check_page.py path/to/suite
python3 "$SKILL_DIR"/scripts/audit_dom.py path/to/suite/index.html
python3 "$SKILL_DIR"/scripts/shot.py path/to/suite/page.html /tmp/page.png \
--hide '.page-head,.details' --seek '0:2'
```
`check_page.py` — tag balance, `node --check` on every inline script, duplicate IDs, broken relative
links, external/CDN references, missing marker definitions, SVG `viewBox`, oversized files.
`audit_dom.py` — headless Chrome: text outside the `viewBox`, text-text overlaps, horizontal page
overflow, JS errors, player count. It reports candidates; a label over a shape is fine, two labels on top
of each other is not.
`shot.py` — deterministic screenshots: hide preceding sections, seek a player, scroll, crop.
Manual pass, in this order:
1. First screen (claim + one diagram) at 1440 and 1024 wide.
2. Click through **every** step of every player; then reset; then jump to the last step; then a failure step.
3. Switch every tab and confirm the dependent widget re-renders.
4. Keyboard-only pass: Space, arrows, tab order, focus visible.
5. Offline check: `grep -R "https\?://"` finds only prose links; open via `file://` with DevTools offline.
6. Cross-page consistency: nav numbering, figure numbers, the same constant everywhere.
7. If the page accompanies a Markdown doc, run the project's doc linter and keep the numbers identical.
## 8. Pre-ship checklist
- [ ] Every page states one claim in its title and lede.
- [ ] Every diagram has a numbered caption and a source anchor.
- [ ] Every failure path mentioned in the text has a visual or table row.
- [ ] Variant (A/B, v1/v2) and version are labeled where they matter.
- [ ] No external font, script, stylesheet, image, or CDN.
- [ ] All players: reset, last step, rapid next, play→pause→play.
- [ ] No text outside the viewBox; no text-text overlap (DOM audit).
- [ ] 1440 px and 1024 px screenshots reviewed.
- [ ] Links and pager resolve; nav numbering matches sections.
- [ ] `check_page.py` exits 0; inline scripts pass `node --check`.
- [ ] Facts re-checked against `file:line`; no invented symbols.
- [ ] Suite entry linked from the project README or docs index if it is a durable deliverable.
## 9. Bundled files
| File | Use |
| --- | --- |
| `assets/kit.css` | Design tokens, layout, cards/tables, diagram primitives, player chrome |
| `assets/kit.js` | Marker injection, `Kit.player`, speed/instant, tabs, TOC |
| `page-template.html` | Minimal working page: diagram + 3-step player + table |
| `references/svg-craft.md` | Geometry, label measurement, color semantics, SVG/HTML traps |
| `references/player-engine.md` | Player state machine, cancellation, reset, test hooks |
| `references/verification.md` | Exact commands and injected-DOM assertion snippets |
| `README.md` | Install, quick start, requirements, repository layout |
| `scripts/check_page.py` | Static suite checker |
| `scripts/audit_dom.py` | Headless geometry/overlap audit |
| `scripts/shot.py` | Screenshot helper (hide/seek/scroll/crop) |
## 10. Portability
The kit, template, and scripts have no dependency on a particular repository, platform, or language.
The examples use a generic producer/queue/consumer model; replace them with your own domain.
Requirements:
| Tool | Needed for | Fallback |
| --- | --- | --- |
| Python 3.8+ | all three scripts | — |
| Node | `node --check` on inline scripts | `check_page.py --no-js` |
| Chrome / Chromium | `audit_dom.py`, `shot.py` | set `CHROME=/path/to/chrome` (works on macOS/Windows) |
| Pillow | `shot.py --crop` | skip cropping |
Install it where the target harness looks for skills:
```bash
# user-wide, available to every project (Pi / Agent Skills layout)
git clone https://github.com/hongguifeng/visual-explainer.git ~/.agents/skills/visual-explainer
# or per project
mkdir -p <project>/.agents/skills
git clone https://github.com/hongguifeng/visual-explainer.git <project>/.agents/skills/visual-explainer
```
A symlink to this directory also works and keeps fixes in one place. For harnesses that use a
different skills directory (e.g. `.claude/skills/`), copy the whole folder and keep the
`SKILL.md` + `assets/` + `references/` + `scripts/` layout.
When reusing it elsewhere:
- Replace the sample paths (`docs/my-suite`, `path/to/suite`) and the `SKILL_DIR` prefix with your
own layout.
- `check_page.py` resolves marker ids from `<page-dir>/assets/kit.js`; if the suite renames the kit,
pass `--kit path/to/kit.js` (or the arrowhead check will report false missing ids).
- `audit_dom.py` and `shot.py` read `window.Kit.players` only for player count/seeking; pages without
the kit still audit and screenshot fine.
- Template copy is English; translate captions and labels if the target audience needs another
language. The layout and CSS do not depend on the wording.
- The war stories in §6 are illustrations, not runtime dependencies.
Pliki w paczce (5)
- .gitignore 1 KB
- LICENSE 1 KB
- README.md 4 KB
- SKILL.md 16 KB
- page-template.html 8 KB
Wersje
| Repozytorium | Wynik | Licencja |
|---|---|---|
| Ta strona · hongguifeng/visual-explainer | 100 | MIT |
| atretyak1985/swarmery | 100 | Apache-2.0 |
| salexandr0s/ai-config | 100 | MIT |
| Prahaladha-Reddy/skills | 100 | MIT |
| nicobailon/visual-explainer | 100 | MIT |
| vercel-labs/vgpu | 100 | MIT |
| jscraik/Agent-Skills | 100 | Apache-2.0 |
| luanmorenommaciel/agentspec | 100 | MIT |
| luanmorenommaciel/agentspec | 100 | MIT |
Migawka bazy z 13.11.2026 · wersja paczki 6f3bad3d907a (skrót SHA-256 całej paczki)
Pobrania w ostatnich 30 dniach: 0 · ranking
Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.
Podobne skille
- 100plannotator-visual-explainer
Generuje samodzielne strony HTML z planami, wyjaśnieniami pull requestów, diagramami i prezentacjami w motywie Plannotator. - 100diagram-generation
Generuje samodzielne diagramy architektury w HTML do PR, planów zadań i wyjaśnień architektonicznych. - 100plannotator-visual-explainer
Tworzy wizualizacje HTML planów, diagramów architektury i tabel danych w motywie Plannotator. - 100static-web-artifacts-builder
Buduje samodzielne statyczne strony HTML do otwarcia w przeglądarce: interaktywne diagramy, dashboardy i infografiki. - 100html-diagram-artifact
Tworzy samodzielny artefakt HTML wyjaśniający architekturę, stos i przepływy systemu diagramami SVG i minimalną ilością tekstu. - 100visualise
Renderuje w rozmowie interaktywne wizualizacje: diagramy SVG, widżety HTML, wykresy i wyjaśnienia tam, gdzie tekst nie wystarcza.