new-tool
Add a new tool to Waku the right way — schema, safe execution, deterministic eval, honest output. Use when adding or modifying agent tools or when the user…
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 — anything
$ npx -y skills add ShenSeanChen/waku-agent --skill excalidraw --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/excalidrawContext preview
The summary Claude sees to decide when to auto-load this skill.
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 — anything
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 — anything Sean will film with.
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.
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.
from waku.ops.whiteboard import style as S 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
Write `json.dumps(doc, indent=2)` to `docs/whiteboards/<name>.excalidraw`. See `waku/ops/whiteboard/build_k3_tutorial.py` for a full two-board example.
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`.
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.
frame (~2500×1100) so it reads without panning. Reserve the 8000×20000 sprawl for full system maps.
reads as problem→solution. Reuse those two shapes.
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.
Add a new tool to Waku the right way — schema, safe execution, deterministic eval, honest output. Use when adding or modifying agent tools or when the user…
Create and tear down the throwaway git worktrees used to test community PRs for waku-agent, without leaking API keys or leaving branches behind. Use when…
Walk Sean through an incoming waku-agent PR or issue and present it his way — four fixed sections: what this is, why it matters, how HE can test it with you as…
Commit and push the current work properly — lint, run the release gate, write a detailed commit message, push to GitHub. Use whenever work reaches a milestone…
Prep me for a meeting or call — who I'm meeting, background, talking points. Use for "prep me for", "get me ready for", "what should I know before", "who am I…
Schedule meetings, calls, or events on the calendar. Use when the user wants to book, plan, schedule, or set up a meeting or appointment with someone at a time.