illustrate
Skill0 starsChanged 3 months agoMITView on GitHub
Engine for show-me-how. Plans as many mascot panels as the story needs (typically 3-6, max 8) for a brief as a short storybook, generates them in parallel via an image backend, overlays labels in the brand font, and writes one doc with the panels in sequence. Invoked by /show-me-how:explain, /show-me-how:write-doc and /show-me-how:pr-review; also usable when the user asks to "illustrate", "draw how X works", or "make an explainer image".
- Installs packages
3 other projects use a version of this.
Adopted by
Most recently taken up by
- devinat1/skillstheir own version, first seen Oct 6, 2026
- yodakeisuke/skill-illustratetheir own version, first seen Aug 14, 2026
- howells/fictiontheir own version, first seen May 22, 2026
Other versions3 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 3
- howells/fiction★ 23same name
- devinat1/skills★ 1same name
- yodakeisuke/skill-illustrate★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 0 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 19
If you were not given one, build it first: read the files the user points at, write BRIEF (<=200 words: what it is, who it is for, the 3-6 …
- Very specific: line 23
Read once, before drawing: references/style-dna.md, references/composition-patterns.md, references/prompt-template.md.
- Very specific: line 31
Before any script call below: if $PLUGIN/node_modules/sharp is missing, run npm install --silent with cwd $PLUGIN first.
- Very specific: line 92
Look at the PNG and write SCRATCH/NN.labels.json:
- Very specific: line 108
Only after every panel is either labelled or pending.
- Very specific: line 142
If no panel is pending: delete SCRATCH (only REPO/.show-me-how/SLUG, never .show-me-how itself).
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
illustrate
Input is a brief block:
MODE: explain | doc
TOPIC: <text>
SOURCES: <list of files/commits read>
BRIEF: <=200 words
MAX_IMAGES: n (hard cap; the beat sheet decides the real count)
OUTDIR: <optional, overrides DIR>If you were not given one, build it first: read the files the user points at, write BRIEF (<=200 words: what it is, who it is for, the 3-6 ideas a reader must get, the one gotcha), set MODE=explain, MAX_IMAGES=8.
MODE changes only one thing: explain echoes the finished doc in chat (step 6); doc prints its path. Both always save the file.
Read once, before drawing: references/style-dna.md, references/composition-patterns.md, references/prompt-template.md. Read references/qa-checklist.md after the first image lands. Read references/mascot-flow.md only if show-me-how.md has no ## Mascot section. Read references/backends.md whenever a generate call returns ok:false.
REPO below is the absolute path of the git root (git rev-parse --show-toplevel). Run every command from there. Never stop the run because one panel failed — mark it pending and keep going.
PLUGIN is the plugin's install folder (the one holding scripts/, assets/, skills/). Resolve it once: if the CLAUDE_PLUGIN_ROOT environment variable is set (Claude Code), use that; otherwise it is two directories above this SKILL.md file (Codex, OpenCode and other harnesses). Shell note: on Windows your shell may be PowerShell — every command below is a plain node ... invocation that works in bash and PowerShell alike; where a loop is shown, both forms are given.
0. Resolve brand, backend, folders
Before any script call below: if $PLUGIN/node_modules/sharp is missing, run npm install --silent with cwd $PLUGIN first.
node "$PLUGIN/scripts/design.mjs" "REPO"-> JSON (file,mascot,font,colors,tone,output.docs,output.backend,output.imageFormat).EXT=output.imageFormat(webpby default;pngif the user set it). Iffileisnull, say once: "No show-me-how.md found; using Flow + Caveat defaults. Run /show-me-how:init to customize." Trustfile, not the disk: a repo's own unrelateddesign.mdis not our config.node "$PLUGIN/scripts/backend.mjs" detect --cwd "REPO"-> printsbackend: .... Echo that line to the user verbatim; it already carries the install / login hint when codex is missing, outdated or signed out, so do not add advice of your own. If the line containsrunning inside the Codex sandbox(pinned or not), that is expected inside Codex: continue, and draw with the native image tool in step 3a.3(a). If the command errors instead of printingbackend:, show the error; it meansshow-me-how.mdpins a backend that is not usable (codex not installed / too old / signed out, an API key variable not set, or an unknownimage_model). Show the error, ask them to fix it or setbackend: auto, then stop.node "$PLUGIN/scripts/slug.mjs" "<TOPIC>"->SLUG.DIR=<design.output.docs>joined withSLUGwith exactly one/between them (output.docsmay end in/) (e.g.docs/show-me-how/label-overlay), orOUTDIRif the brief block has one.DOC=DIR/SLUG.md(e.g.docs/show-me-how/label-overlay/label-overlay.md).SCRATCH=REPO/.show-me-how/SLUG. CreateDIRandSCRATCH(mkdir -p).
- Mascot refs:
design.mascot.references(repo-root-relative) if non-empty, else$PLUGIN/assets/flow/front.png,.../working.png,.../stuck.png. Drop any path that does not exist; if none exist, pass no--refat all — the character still comes from the prompt text.
1. Beats
Turn BRIEF into a beat sheet using "Beat sheet" in references/composition-patterns.md. There is no target number: use as many panels as the story needs, one beat each — a small helper needs 2-3, a multi-step feature 5-6. Never pad to fill and never squeeze two beats into one panel. MAX_IMAGES is only a hard cap. Panels form one continuous scene: same mascot, main object may carry over, the mascot's action must change every panel. One panel = one beat.
2. Panel list (show it, do not ask)
Print this, then continue without waiting for approval:
NN <beat> <structure> "<title>"
<mascot>: <what it physically does>
Labels: <2-5 short labels, <=4 words each>
Caption: <one line, <=12 words — baked into the panel in the brand font>
Text: <1-2 sentences, <=40 words — the description under the panel in the doc>NN is the zero-padded panel number (01, 02, ...). <beat> is setup / action / twist / payoff.
3a. Launch every generation at once
- For every panel, fill every
{slot}of the template inreferences/prompt-template.md(including{previous_panel}) and write the result toSCRATCH/NN.prompt.txt. - Skip any panel whose
SCRATCH/NN.pngalready exists (the user saved it by hand after a manual run); it goes straight to step 4. Pick one of these two ways to draw, for the whole run:
(a) Native image tool. If your harness gives you an image-generation tool directly (Codex:
image_gen/image_gen__imagegen, present when codex runs with--enable image_generation), use it — no subprocess, no sandbox trouble. For each remaining panel: call the tool with the full text ofSCRATCH/NN.prompt.txtas the prompt and the mascot refs from step 0.4 as reference images (if the tool accepts them), landscape 16:9 (about 1536x1024). Save or copy the returned image toSCRATCH/NN.png, then writeSCRATCH/NN.result.jsonyourself with exactly{"ok":true,"backend":"image_gen","out":"<absolute path of NN.png>"}. If the tool fails for a panel, write{"ok":false,"backend":"image_gen","out":"...","stderr":"<the error, one line>"}instead. Run the panels concurrently if the harness allows; sequentially is fine. Tell the user the backend isimage_gen (native).(b) The script. Otherwise start the generate commands in the same turn, all concurrently, in the background (Claude Code: Bash with
run_in_background: true; other harnesses: your background-command feature, or in bash append&to each and launch them from one shell call). Redirect each one's stdout to its own result file:node "$PLUGIN/scripts/backend.mjs" generate --prompt-file "SCRATCH/NN.prompt.txt" --out "SCRATCH/NN.png" --ref "<ref1>" --ref "<ref2>" --cwd "REPO" > "SCRATCH/NN.result.json"Each command always exits 0. Read success from the JSON
okfield inSCRATCH/NN.result.json, never from the exit code. Tell the user how many generations are running. If step 0.2 saidcodex unavailable: running inside the Codex sandbox, the script cannot reach codex from here: use (a) if you have the tool; if not, ask the user to approve running the generate command outside the sandbox (network on), or fall through to manual.Do not end your turn while any generation is running. Completion notifications for background shells are not guaranteed to reach you (they never reach a subagent), so never rely on them. Instead, poll: read every
SCRATCH/NN.result.jsonthat is still missing or empty — one shell call can check all of them:- bash:
for f in SCRATCH/*.result.json; do echo "$f: $(cat "$f")"; done - PowerShell:
Get-ChildItem SCRATCH/*.result.json | ForEach-Object { "$($_.Name): $(Get-Content $_ -Raw)" }
Handle any that now contain a JSON line (step 3b), then check again. A generation takes 1-3 minutes; keep checking, as many times as it takes, until every panel has its JSON line. An empty or missing file means it is still running — never treat it as a failure, and never stop and say you are "waiting".
- bash:
3b. Collect, in whatever order they finish
Handle each result as its shell exits; do not wait for all of them before starting QA on the first.
ok:falsewithpromptFile(manual backend) — collect all such panels, then tell the user once: "Prompts saved to<promptFile>(one per panel). Paste each into ChatGPT/Gemini, save the image asSCRATCH/NN.png, then re-run the same slash command; saved panels are picked up and labelled." Mark each pending.ok:falsewithstderr(the backend failed) — show the last 5 lines ofstderr, then point the user atSCRATCH/NN.prompt.txtand the same save path with the same re-run line. Mark pending.ok:true— viewSCRATCH/NN.pngwith the Read tool and check it against every "Must pass" item inreferences/qa-checklist.md. If any fails, regenerate exactly once, in the background, without blocking other panels:- Append the matching line from "Iteration moves" in
references/qa-checklist.mdto the end ofSCRATCH/NN.prompt.txt. For a decorative mascot, append the retry prompt fromreferences/prompt-template.md. For text in the image, append a stronger no-text instruction — never the mascot-central retry text. If no move matches, append the failed "Must pass" line itself as an instruction. - The retry text is only ever appended to the original filled prompt; never sent alone.
- Delete
SCRATCH/NN.pngandSCRATCH/NN.result.jsonfirst, so a failed retry cannot be reported asok:trueon the stale file, then draw that panel again the same way as in step 3a.3 (native tool or script) and poll its result file as in 3a.4. If the retry isok:false, handle it exactly like 3b.1/3b.2. Accept whatever the retry gives you. One retry per panel.
- Append the matching line from "Iteration moves" in
- As soon as a panel's PNG is accepted, label it (step 4) — do not wait for the others.
4. Label (once per accepted panel)
- Look at the PNG and write
SCRATCH/NN.labels.json:{ "labels": [{ "text": "", "x": 0.0, "y": 0.0, "kind": "black" }], "arrows": [{ "from": [0.0, 0.0], "to": [0.0, 0.0], "kind": "flow" }] }x/yare 0-1 fractions of width/height, placed in empty space next to the object they describe. The canvas is about 1672x941 and a label is centred on itsx/y, so keep every centre within x 0.12-0.88 and y 0.08-0.94.kind:black(names),flow(movement),warn(the gotcha or result),note(side info). Max 5 labels, 2 arrows. Omitcolors/font— the script fills them fromshow-me-how.md. - Overlay:
node "$PLUGIN/scripts/label.mjs" --in "SCRATCH/NN.png" --labels "SCRATCH/NN.labels.json" --caption "<caption>" --out "DIR/NN.EXT" --design-cwd "REPO"--captionis the panel's one-line caption from step 2; the script adds a white strip below the picture with that line in the brand font. Pass it for every panel. The output format follows the--outextension (EXTfrom step 0.1); the finished panel is written in that format at the generated size (a WebP panel is ~45 KB against ~700 KB as PNG). The result is a JSON line. If it carries ahintfield, the labels were drawn in the system font instead of the brand font (this happens on macOS until the font is installed for the user — seescripts/font.mjs). Show thathintline to the user once per run, keep going, and do not try to fix it yourself. - View
DIR/NN.EXTonce. If a label sits on line art or runs off the edge, nudge itsx/yand rerun 4.2. At most one nudge per panel.
5. Write the storybook
Only after every panel is either labelled or pending. Write DOC exactly in this shape — no ## section headings; each panel is the image, then its caption as a ### line (so it reads large), then its text:
# <Title>
<hook: 1-2 sentences — what this is and why the reader cares>

### <caption 1>
<text 1>

### <caption 2>
<text 2>
**Remember:** <the one gotcha, one sentence>
<details><summary>Sources</summary>
- <each file/commit from SOURCES, one per line>
</details>Word budget: caption <=12 words, text <=40 words per panel; hook + Remember <=60 words together. Every panel gets a caption and a text — an image alone is not a beat. Plain language, no jargon dumps. Image links are relative to DIR, so no folder prefix, and use the real extension (01.webp by default).
For a pending panel, write  where <REL> is one .. per path segment of DIR relative to REPO (default docs/show-me-how/<slug> → ../../..), followed by one line: _Pending: prompt at <prompt file>._
6. Export, clean up, finish
- Export a shareable copy:
node "$PLUGIN/scripts/export.mjs" --doc "DOC"writesDIR/SLUG.htmlwith every panel inlined, so the storybook can be sent as one file and opened in any browser. Run it after every write ofDOC, including re-runs. - If no panel is pending: delete
SCRATCH(onlyREPO/.show-me-how/SLUG, never.show-me-howitself). If deleting fails, say so in one line and continue. If any panel is pending, keepSCRATCHand say it is kept for the re-run. DIRmust now contain onlySLUG.md,SLUG.htmlandNN.EXTfiles. List it. Delete only leftovers this plugin itself produces —NN-*.png,NN-*.svg,README.md, and araw/folder from a v0.1 run. Anything else (other files, other folders) is the user's: leave it and tell them it is there.MODE=explain: print the full contents ofDOCin chat.MODE=doc: do not.- Print exactly: how many panels were produced, which backend was used (
image_gen (native)for 3a.3a) and, when any result carriedusdorestimatedUsd, the sum as~$X.XX(saychargedwhen every panel hadusd, elseestimated, approx. list prices 2026-08), the path toDOCand toSLUG.html("send this one to share"), and which panel numbers are pending with each one's prompt file — or "none pending". Then suggest, without editing anything: "Add.show-me-how/to your.gitignoreto keep prompts and unlabelled generations out of the repo." Do not commit anything.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

