Skip to content
Productivity
Skill

/excalidraw

Generate an Excalidraw whiteboard in Sean's hand-drawn video style (Excalifont, roughness 1, green signature, socials + watermark, source labels). Use whenever the user wants a whiteboard, diagram, teaching board, or "chart" for a video or the docs/whiteboards gallery or a lab/

From plugin
waku-agent
2.2k14 skills

Claude Code

$ npx -y skills add ShenSeanChen/waku-agent --skill excalidraw --agent claude-code

SKILL.md

excalidraw.SKILL.md
name: excalidraw
description: >
  Generate an Excalidraw whiteboard in Sean's hand-drawn video style (Excalifont,
  roughness 1, green signature, socials + watermark, source labels). Use whenever
  the user wants a whiteboard, diagram, teaching board, or "chart" for a video or
  the docs/whiteboards gallery or a lab/ topic — anything Sean will film with.

Excalidraw whiteboards, Sean's way

Boards are generated from code so they match the masters in `~/Developer/Excalidraw` exactly — Sean films with them directly. Never hand-write `.excalidraw` JSON; use the style engine, which locks the values that a from-scratch board always gets wrong.

The five things a naive board gets wrong (all fixed by the engine)

1. `fontFamily 5` (Excalifont) — NOT `1` (legacy Virgil). Wrong font = wrong board. 2. `roughness 1` (controlled) — NOT `2` (scratchy). 3. Stroke-width hierarchy `1` detail / `2` container / `4` emphasis — not flat `2`. 4. Type scale = Excalidraw presets S=16 / M=20 / L=28. Majority is S/M; L (28) reserved for big titles only. Don't inflate past the presets. 5. Signature green `#b2f2bb`, frames, socials block, watermark, source labels.

How to build one

from scripts.whiteboard import style as S   # run from the repo root

e = []
e.append(S.text(60, 40, "Title", size=S.FS_TITLE))
e.append(S.underline(64, 120, 800, color=S.PAL["orange"][1]))
e += S.labeled_box(80, 200, 300, 140, "A box\nwith a note", color="green")
e += S.pill_header(80, 400, 600, "SECTION", color="blue")
e += S.ellipse(500, 200, 180, 120, "agent", color="pink")
e += S.diamond(700, 200, 140, 100, "gate?", color="green")
e += S.labeled_arrow(380, 270, 500, 260, "tool calls")
e += S.socials_block(1980, 44)
e.append(S.watermark(80, 1030))
e.append(S.source_label(80, 900, "per <vendor>, <date>"))   # standing rule
e.append(S.red_note(80, 960, "honest red-ink opinion"))     # standing rule

S.validate(e)                       # catches broken bound-text ids
doc = S.document(e)                 # wraps with appState + white bg

Where the board goes depends on who it is for:

  • **A board that explains Waku's own code:** write it to `docs/whiteboards/<name>.excalidraw`.
  • **A board for a video** (anything a `lab/` topic films): the `.excalidraw` source and the

script that draws it go to `~/Developer/Excalidraw/waku-lab/<topic>/`, **never into the repo**. Commit only a PNG screenshot, to `lab/<topic>/screenshots/<name>.png`. `evals/deterministic/test_rulebook.py` fails if a `.excalidraw` file appears in a lab topic. See `lab/kimi-k3/build_k3_tutorial.py` for a full two-board example.

Palette (name → fill/stroke), meaning follows Sean's color system

  • `green` loop / hero / final reply · `red` harness boundary / cost / honest-ink
  • `blue` LLM-ops / observability · `orange` a loop step · `pink` LLM/agent nodes
  • `grey` neutral state/config · `yellow` callout · `plain` bare container

Always, before delivering

1. `S.validate(elements)` — every bound text must map to a container. 2. Eyeball via SVG proxy → PNG (QuickLook crops wide canvases; use headless Chrome `--screenshot --window-size=W,H` for the full board). Check for overlaps and off-canvas elements. 3. Shareable boards get the socials block + `@ShenSeanChen` watermark. 4. Every technical/vendor claim gets a dated `source_label`.

Two ratios, measured from the masters — check yours before delivering

Generated boards fail in the same two ways every time. Both are countable, so count them instead of eyeballing:

# against ~/Developer/Excalidraw/<newest>.excalidraw
black strokes / all shapes   ->  masters: 96%   (354 of 368)
arrows / all shapes          ->  masters: 0.88  (241 arrows, 165 ellipses)

1. **COLOUR POLLUTION.** The masters are ~96% BLACK strokes with transparent or white fills. Colour lands maybe fifteen times on a whole board: green `#b2f2bb` for the hero, red `#ffc9c9` for the warning, and a handful of coloured strokes on section boundaries. A first-pass generated board typically comes out at 3% black — a coloured stroke on every shape. Ink by default; a fill has to earn its place. Note `labeled_box(fill="chip")` is documented as user-prompt/reply chips ONLY, and using it for general boxes is the usual cause.

2. **NO FLOW.** The masters average nearly one arrow per shape, with ellipses for agents and diamonds for decisions. A board of boxes in a grid with two arrows is an infographic, not a whiteboard — it reads as dead. If the subject has motion, DRAW the motion: fan-outs, back-edges, branches from a diamond. A back-edge that visibly returns is worth more than a paragraph.

Fix both before showing it, because they are the first things Sean notices.

Layout lessons (from comparing generated vs. hand-drawn)

  • Poster-tight beats sprawl for a single teaching idea — fit it in one landscape

frame (~2500×1100) so it reads without panning. Reserve the 8000×20000 sprawl for full system maps.

  • A diagonal "ladder" reads as progress; a red barrier + a green break-through

reads as problem→solution. Reuse those two shapes.

Read more
@shenseanchen
Ships withwaku-agent

Your own AI assistant. On your laptop. In code you can read in an afternoon. Meet Waku — a local-first personal assistant that shows the four pillars behind every serious agent: Harness · Loop · Memory · Eval/LLM-Ops. No frameworks hiding the good parts.

Stars on GitHub

Momentum

stars in total
2.2k
Star history of ShenSeanChen/waku-agent on GitHub, a chart by star-history.com

Other skills on waku-agent.

new-tool

new-tool

Add a new tool to Waku the right way — schema, safe execution, deterministic eval, honest output. Use when adding or modifying…

pr-worktree

pr-worktree

Create and tear down the throwaway git worktrees used to test community PRs for waku-agent, without leaking API keys or leaving…

release

release

Cut a waku-agent release when main is ahead of the last tag. Check the gap, bump the version, tag, confirm PyPI, announce. Use…

review-pr

review-pr

Walk Sean through an incoming waku-agent PR or issue and present it his way — four fixed sections: what this is, why it matters,…

ship

ship

Commit and push the current work properly — lint, run the release gate, write a detailed commit message, push to GitHub. Use…

pokedex

pokedex

Look up any Pokemon's types, base stats, and abilities from the public PokeAPI. Use whenever the user mentions a specific Pokemon…

More skills from other plugins.

i-have-adhd

i-have-adhd

Shape output for a reader with ADHD: lead with the next action, number multi-step work, restate state across turns, suppress…

@ayghri@ayghriInstall Skill
ab-test-analysis

ab-test-analysis

Analyze A/B test results with statistical significance, sample size validation, confidence intervals, and ship/extend/stop…

@phuryn@phurynInstall Skill
distilly

distilly

Set up the owner profile so a personal agent knows who it works for (first-run setup, \"get to know me\"), or distill colleague,…

Questions about excalidraw.

Which coding agents can use excalidraw?
excalidraw installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.