yf-diagram-authoring
Generate light-mode, white-background diagram PNGs from d2 source, keeping the .d2 source beside every .png render. Stan
Generate light-mode, white-background diagram PNGs from d2 source, keeping the .d2 source beside every .png render. Standardizes d2 (not mermaid) as the single, local, offline diagram engine: write .d2 -> render .png (theme 0, elk) -> verify by Read.
At a glance
- Category:
utility - Invocation:
/yf-diagram-authoring(user-invocable) - Requires tools:
d2 - Source:
SKILL.md·README.md
When it fires
the operator asks to author/render/regenerate a diagram, or a content-producing skill (yf-plan, yf-research, yf-skill-authoring) generates a structural diagram for a plan, research report, or skill spec.
When to skip it
non-diagram image work; mermaid-specific workflows; any task that does not produce a d2 diagram. Output locations are caller-supplied (the skill is location-agnostic); consumers set their own convention (plan_dir/diagrams, research_dir/ diagrams, skill spec/ co-resident, project docs/diagrams).
Prerequisites
| Tool | Version | Purpose | Install |
|---|---|---|---|
d2 |
>= 0.7 | Diagram compiler/renderer (.d2 → .png, theme 0, elk) |
brew install d2 |
Mirrors SKILL.md frontmatter depends-on-tool: [d2]. The first PNG render fetches a one-time
~140MB playwright Chromium; that warm-up is owned outside this skill (e.g. a dotfiles bootstrap
hook). Preflight only checks that d2 is on PATH — it never probes the Chromium cache.
Usage
User-invocable. Drive d2 through scripts/render.py (run via uv run):
uv run scripts/render.py preflight # OS-independent `command -v d2` check
uv run scripts/render.py render <slug>.d2 # one .d2 -> sibling .png (theme 0, elk)
uv run scripts/render.py render-dir <dir> # (re)render every .d2 under <dir>
uv run scripts/render.py check-dir <dir> # every .d2 has a .png (+ advisory staleness)
uv run scripts/render.py embed <src.d2> <tgt.md> # insert source as an inline ```d2 fence
uv run scripts/render.py lift <tgt.md> # inline ```d2 -> standalone .d2 + .png + link
uv run scripts/render.py inline <tgt.md> # standalone .png link -> inline ```d2 fence
Write .d2 source into the caller's diagrams location, render, then Read the PNG to verify
(white background, legible labels). Reference a render from docs with relative markdown image
syntax —  from a skill README,  from
the project README.
Inline source vs standalone render. A diagram can travel inline as a ```d2 fence
(rendered at preview/PDF time by yf-markdown-pdf — one file, no committed binary) or as a
standalone committed .d2 + .png referenced by an image link (previews anywhere, but adds a
binary + a regeneration discipline). embed inserts inline source, lift converts inline →
standalone, inline converts standalone → inline; the pair round-trips (source unchanged). See
SKILL.md for the full workflow, the trade-off table, location conventions, and d2 authoring notes.
Layout
skills/diagram-authoring/
├── SKILL.md # the d2 workflow, location conventions, when-to-diagram, d2 authoring notes
├── README.md # this file
└── scripts/
├── render.py # PEP 723 helper: preflight / render / render-dir / check-dir / embed / lift / inline
└── test_render.py # pytest: embed/lift/inline parsing + the round-trip guarantee