From 875944208974db30e6d79c655b3e6b1cf416b0cb Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Fri, 12 Jun 2026 06:57:42 -0700 Subject: [PATCH] docs: diagram + multi-format documentation across README, make-pdf skill, and how-to guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit README gains /make-pdf (Publisher) and /diagram (Diagram Maker) rows in the sprint table. make-pdf's skill doc — the agent-facing contract — gains Core patterns for mermaid/excalidraw fences (title/render=false/page= options), the image policy ({width=}/{page=} directives, zero-truncation, conservative auto-landscape), --to html|docx, and --strict, plus the --to vs --format disambiguation in Common flags. New docs/howto-diagrams-and-formats.md is the user-facing walkthrough: fences, directives, formats, /diagram triplet, the mermaid racetrack trick, troubleshooting. Co-Authored-By: Claude Fable 5 --- README.md | 2 + docs/howto-diagrams-and-formats.md | 131 +++++++++++++++++++++++++++++ make-pdf/SKILL.md | 66 +++++++++++++++ make-pdf/SKILL.md.tmpl | 66 +++++++++++++++ 4 files changed, 265 insertions(+) create mode 100644 docs/howto-diagrams-and-formats.md diff --git a/README.md b/README.md index c8b20b308..5236b2019 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,8 @@ Each skill feeds into the next. `/office-hours` writes a design doc that `/plan- | `/autoplan` | **Review Pipeline** | One command, fully reviewed plan. Runs CEO → design → eng review automatically with encoded decision principles. Surfaces only taste decisions for your approval. | | `/spec` | **Spec Author** | Turn vague intent into a precise, executable spec in five phases (why, scope, technical with mandatory code-reading, draft, file). Codex quality gate before file (blocks below 7/10), fail-closed secret redaction, dedupe against existing issues, archive to `$GSTACK_STATE_ROOT/projects/$SLUG/specs/` for team-corpus recall. `--execute` spawns `claude -p` in a fresh worktree; `/ship` auto-closes the source issue on merge. Plan-mode aware. | | `/learn` | **Memory** | Manage what gstack learned across sessions. Review, search, prune, and export project-specific patterns, pitfalls, and preferences. Learnings compound across sessions so gstack gets smarter on your codebase over time. | +| `/make-pdf` | **Publisher** | Markdown in, publication-quality document out. Mermaid and excalidraw fences render as vector diagrams, fully offline. Images scale to the page and never truncate; wide diagrams get their own landscape page. `--to html` emits one self-contained file, `--to docx` a Word doc. | +| `/diagram` | **Diagram Maker** | English in, editable diagram out. Emits a triplet: mermaid source, `.excalidraw` you can open and edit on excalidraw.com, and rendered SVG/PNG. Hand-drawn aesthetic, zero network. Embed the source in markdown and `/make-pdf` renders it. | ### Which review should I use? diff --git a/docs/howto-diagrams-and-formats.md b/docs/howto-diagrams-and-formats.md new file mode 100644 index 000000000..383309a6b --- /dev/null +++ b/docs/howto-diagrams-and-formats.md @@ -0,0 +1,131 @@ +# How to put diagrams in your documents (and export beyond PDF) + +This guide covers the diagram + multi-format engine that ships with +`/make-pdf` and `/diagram` (v1.58.0.0+). Everything here runs fully offline: +the mermaid and excalidraw runtimes are vendored in `lib/diagram-render/`, +loaded into the browse daemon's Chromium. No CDN, no network at render time. + +## Render a mermaid diagram inside a PDF + +Put a fence in your markdown. That's it. + +````markdown +```mermaid title="Render pipeline" +graph LR + A[markdown] --> B[prepass] + B --> C[Chromium] + C --> D[PDF] +``` +```` + +```bash +make-pdf generate doc.md out.pdf +``` + +The fence renders as a **vector** diagram (crisp at any zoom, selectable +text), with the `title` as caption and accessibility label. The raw mermaid +source is preserved in an HTML comment inside the document for debugging. + +**Fence options** (space-separated in the info string): + +| Option | Effect | +|---|---| +| `title="..."` | caption below the diagram + `aria-label` | +| `render=false` | keep the fence as a plain code block | +| `page=landscape` | force this diagram onto its own landscape page | +| `page=portrait` | veto auto-landscape for this diagram | + +A fence that fails to parse renders as a loud red diagnostic block with the +parse error and source excerpt — your document still builds, and the error +is impossible to miss. + +` ```excalidraw ` fences work the same way; the body is a full `.excalidraw` +scene file (what excalidraw.com saves with File → Save). + +## Control image size and orientation + +Local images are inlined automatically (relative paths resolve against the +markdown file) and **never truncate** — every image caps at the content box. +Oversized photos downscale to print resolution (300dpi at the content width), +so a phone photo doesn't bloat the document. + +Per-image directives go immediately after the image: + +```markdown +![quarterly chart](chart.png){width=full} +![logo](logo.png){width=2in} +![wide architecture](arch.png){page=landscape} +![wide screenshot](shot.png){page=portrait} +``` + +`width=` accepts `full`, a percentage (`50%`), or a dimension (`3in`, `8cm`, +`200px`). `page=` forces or vetoes a dedicated landscape page. + +**Auto-landscape:** a wide, small-text, diagram-like image gets its own +vertically-centered landscape page automatically — inside an otherwise +portrait document. The heuristic is deliberately conservative (aspect ratio +≥ 1.8, intrinsic width over ~2.5x the content box, and a diagram-ish alt +word: diagram / architecture / flowchart / chart / graph). If it doesn't +fire when you want it, add `{page=landscape}`; if it fires when you don't, +add `{page=portrait}`. + +## Export single-file HTML or Word + +```bash +make-pdf generate doc.md out.html --to html +make-pdf generate doc.md out.docx --to docx +``` + +- **`--to html`** writes ONE self-contained file: diagrams as inline SVG, + images as data URIs, zero network references, plus a screen-reading layer + (centered measure, padding). Email it, attach it, open it anywhere. +- **`--to docx`** is a content-fidelity export: headings, tables, code + blocks, lists, and diagrams (embedded as 300dpi PNGs with alt text) carry + over. Page-perfect layout does not — that's Word's job once it's open. + +Heads-up: `--to` is the output format. `--format` is an old alias for +`--page-size` — different thing. + +## Generate a diagram from English + +``` +/diagram make a flowchart of our deploy pipeline: build, test, canary, promote +``` + +The skill authors mermaid and emits a **triplet**: + +| File | Use it for | +|---|---| +| `.mmd` | the source of truth — edit and re-render | +| `.excalidraw` | open at excalidraw.com (File → Open), move boxes, hand back | +| `.svg` / `.png` | docs, issues, READMEs, chat | + +Flowcharts convert to fully editable excalidraw scenes. Other mermaid types +(sequence, state, gantt) render to SVG/PNG fine but skip the `.excalidraw` +artifact — an upstream converter limitation the skill will tell you about. + +For documents, embed the `.mmd` source in your markdown instead of the PNG — +`/make-pdf` renders it as vector and the diagram stays editable forever. + +## CI: fail loud instead of shipping placeholders + +```bash +make-pdf generate docs.md --strict +``` + +Missing local images and unfetched remote images exit non-zero instead of +rendering a placeholder — for docs pipelines where a broken image should +break the build. + +## Troubleshooting + +- **"diagram-render bundle not found"** → run `bun run build:diagram-render` + in the gstack repo, or re-run `./setup`. +- **Diagram renders but looks squished inline** → it's wide; give it room + with `page=landscape` on the fence. +- **A two-row "racetrack" loop instead of one long line:** mermaid subgraph + trick — top-level `flowchart TB`, two subgraphs with `direction LR` and + `direction RL`, connect the *subgraphs* (node-level edges across subgraph + boundaries silently disable `direction`). +- **Remote images** → not fetched by default (offline posture). Pass + `--allow-network` to opt in. diff --git a/make-pdf/SKILL.md b/make-pdf/SKILL.md index 9205cda58..ef235371b 100644 --- a/make-pdf/SKILL.md +++ b/make-pdf/SKILL.md @@ -598,6 +598,69 @@ as you edit the markdown. Skip the PDF round trip until you're ready. $P generate --no-confidential memo.md memo.pdf ``` +### Diagrams — mermaid and excalidraw fences render as pictures + +Any ` ```mermaid ` or ` ```excalidraw ` fence in the markdown renders as a +crisp vector diagram, fully offline (vendored bundle, no CDN). A broken fence +produces a visible red diagnostic block with the parse error — never silent +raw code. + +Fence info-string options: + +``` +```mermaid title="Auth flow" ← caption + aria-label +```mermaid render=false ← keep it as a code block (today's behavior) +```mermaid page=landscape ← force this diagram onto a landscape page +``` + +A ` ```excalidraw ` fence contains a full .excalidraw scene file (what +excalidraw.com saves). Authoring NEW diagrams from English is `/diagram`'s +job — it emits an editable triplet (source, .excalidraw, SVG/PNG) and pairs +with this skill: embed the `.mmd` source in your markdown, not the PNG. + +### Images — scaled right, never truncated + +Local images inline automatically (relative paths resolve against the +markdown file). Every image caps at the content box — zero truncation, ever. +Oversized photos downscale to print resolution (300dpi) so payloads stay +small with no visible quality loss. + +Per-image directives, written immediately after the image: + +``` +![chart](data.png){width=full} ← stretch to content-box width +![chart](data.png){width=50%} ← percentage or 3in/8cm/200px +![wide](arch.png){page=landscape} ← give it its own landscape page +![wide](shot.png){page=portrait} ← veto auto-landscape +``` + +Wide, small-text diagram images auto-promote to their own landscape page +(conservative: aspect ≥ 1.8, width over ~2.5x the content box, AND a +diagram-ish alt word — diagram/architecture/flowchart/chart/graph). The +promoted page is vertically centered. When the heuristic guesses wrong, +`{page=portrait}` vetoes it; false negatives just need `{page=landscape}`. + +### Other formats — single-file HTML and Word + +```bash +$P generate readme.md out.html --to html # ONE self-contained file: inline + # SVG diagrams, data-URI images, + # zero network refs, screen-readable +$P generate readme.md out.docx --to docx # Word: content fidelity (headings, + # tables, code, diagrams as PNG) — + # layout is Word's, not ours +``` + +`--to` is the output format. `--format` is something else entirely (a +`--page-size` alias) — don't confuse them. + +### CI mode — fail loud on missing assets + +```bash +$P generate docs.md --strict # missing/remote images exit non-zero + # instead of warn + placeholder +``` + ## Common flags ``` @@ -617,6 +680,9 @@ Branding: --no-confidential Suppress the CONFIDENTIAL right-footer Output: + --to pdf|html|docx Output format (default: pdf). html = single + self-contained file; docx = content fidelity. + --strict Missing/remote images fail the run (CI mode). --page-numbers "N of M" footer (default on) --tagged Accessible PDF (default on) --outline PDF bookmarks from headings (default on) diff --git a/make-pdf/SKILL.md.tmpl b/make-pdf/SKILL.md.tmpl index bfd90441b..7ad10b14c 100644 --- a/make-pdf/SKILL.md.tmpl +++ b/make-pdf/SKILL.md.tmpl @@ -94,6 +94,69 @@ as you edit the markdown. Skip the PDF round trip until you're ready. $P generate --no-confidential memo.md memo.pdf ``` +### Diagrams — mermaid and excalidraw fences render as pictures + +Any ` ```mermaid ` or ` ```excalidraw ` fence in the markdown renders as a +crisp vector diagram, fully offline (vendored bundle, no CDN). A broken fence +produces a visible red diagnostic block with the parse error — never silent +raw code. + +Fence info-string options: + +``` +```mermaid title="Auth flow" ← caption + aria-label +```mermaid render=false ← keep it as a code block (today's behavior) +```mermaid page=landscape ← force this diagram onto a landscape page +``` + +A ` ```excalidraw ` fence contains a full .excalidraw scene file (what +excalidraw.com saves). Authoring NEW diagrams from English is `/diagram`'s +job — it emits an editable triplet (source, .excalidraw, SVG/PNG) and pairs +with this skill: embed the `.mmd` source in your markdown, not the PNG. + +### Images — scaled right, never truncated + +Local images inline automatically (relative paths resolve against the +markdown file). Every image caps at the content box — zero truncation, ever. +Oversized photos downscale to print resolution (300dpi) so payloads stay +small with no visible quality loss. + +Per-image directives, written immediately after the image: + +``` +![chart](data.png){width=full} ← stretch to content-box width +![chart](data.png){width=50%} ← percentage or 3in/8cm/200px +![wide](arch.png){page=landscape} ← give it its own landscape page +![wide](shot.png){page=portrait} ← veto auto-landscape +``` + +Wide, small-text diagram images auto-promote to their own landscape page +(conservative: aspect ≥ 1.8, width over ~2.5x the content box, AND a +diagram-ish alt word — diagram/architecture/flowchart/chart/graph). The +promoted page is vertically centered. When the heuristic guesses wrong, +`{page=portrait}` vetoes it; false negatives just need `{page=landscape}`. + +### Other formats — single-file HTML and Word + +```bash +$P generate readme.md out.html --to html # ONE self-contained file: inline + # SVG diagrams, data-URI images, + # zero network refs, screen-readable +$P generate readme.md out.docx --to docx # Word: content fidelity (headings, + # tables, code, diagrams as PNG) — + # layout is Word's, not ours +``` + +`--to` is the output format. `--format` is something else entirely (a +`--page-size` alias) — don't confuse them. + +### CI mode — fail loud on missing assets + +```bash +$P generate docs.md --strict # missing/remote images exit non-zero + # instead of warn + placeholder +``` + ## Common flags ``` @@ -113,6 +176,9 @@ Branding: --no-confidential Suppress the CONFIDENTIAL right-footer Output: + --to pdf|html|docx Output format (default: pdf). html = single + self-contained file; docx = content fidelity. + --strict Missing/remote images fail the run (CI mode). --page-numbers "N of M" footer (default on) --tagged Accessible PDF (default on) --outline PDF bookmarks from headings (default on)