Kami — AI Document Design System Complete Tutorial
Kami (紙, かみ) means paper in Japanese. It is a constraint-based design system that turns AI-generated content into professionally typeset documents. This tutorial covers the upstream open-source project and the custom extensions built on top of it for enterprise use.
1. What is Kami? (專案定位)
The Problem
AI models like Claude and GPT can write content that rivals professional human writers. But every time you ask an AI to “make a PDF,” you get a different layout, a different font, a different shade of gray. The output is competent but forgettable. You would never send it to an investor, a hiring committee, or a conference audience without extensive manual cleanup.
The bottleneck is not writing capability. It is design consistency.
The Solution: A Constraint Language
Kami is not a template pack or a CSS framework. It is a constraint language – a minimal, opinionated set of rules that any AI agent can follow to produce documents you would actually ship. Think of it like a style guide for robots: one palette, one type hierarchy, one editorial rhythm, applied across every document type.
The philosophy is simple: good content deserves good paper.
The Trilogy
Kami is the third piece of tw93’s AI-tool trilogy:
| Project | Japanese | Role |
|---|---|---|
| Kaku | 書く (to write) | Writes code |
| Waza | 技 (technique) | Drills habits |
| Kami | 紙 (paper) | Delivers documents |
Together they form a complete loop: Kaku builds the tool, Waza makes you better at using it, and Kami delivers the final artifact.
Where Kami Fits in the AI Document Workflow
flowchart LR
A[User Request] --> B[AI Agent]
B --> C{Content Ready?}
C -->|No| B
C -->|Yes| D[Kami Constraint Language]
D --> E[Template Selection]
E --> F[HTML Generation]
F --> G{Output Path}
G -->|Default| H[WeasyPrint PDF]
G -->|Editable| I[python-pptx PPTX]
G -->|Markdown| J[Marp Slides]
G -->|Web| K[Static HTML Site]
style D fill:#1B365D,color:#fff
style H fill:#f5f4ed,stroke:#1B365D
style I fill:#f5f4ed,stroke:#1B365D
style J fill:#f5f4ed,stroke:#1B365D
style K fill:#f5f4ed,stroke:#1B365D
Key Stats
| Metric | Value |
|---|---|
| Stars | 9,286 |
| Forks | 436 |
| License | MIT |
| Latest Version | V1.9.1 (2026-06-29) |
| Created | 2026-04-20 |
| Homepage | https://kami.tw93.fun |
| Primary Language | HTML |
| Supported Languages | EN, CN, JA (best-effort), KO (best-effort) |
2. Installation Guide (安裝指南)
Kami supports four installation paths depending on your AI tool of choice. All paths install the same design system; they differ only in how the agent discovers and loads the skill.
2.1 Claude Code (Recommended)
Requires Claude Code v2.1.142 or newer.
1# Install from the plugin marketplace
2/plugin marketplace add tw93/kami
3/plugin install kami@kami
4
5# Update later
6claude plugin update kami
2.2 Codex
1# Install from the repo marketplace
2codex plugin marketplace add tw93/kami
3codex plugin add kami@kami
4
5# Update later
6codex plugin marketplace upgrade kami
7codex plugin add kami@kami # refresh the installed snapshot
2.3 Generic Agents (OpenCode, Pi, etc.)
For tools that read skills from ~/.agents/:
1npx skills add tw93/kami/plugins/kami/skills/kami -a '*' -g -y
The subpath plugins/kami/skills/kami points at the self-contained skill package. Using a bare tw93/kami would install only SKILL.md, because the repo root doubles as the website source.
To update, re-run the same npx skills add command. Avoid npx skills update for now (it collapses repo-root skills to a single file).
2.4 Claude Desktop
- Download kami.zip from the latest release
- Open Customize > Skills > “+” > Create skill
- Upload the ZIP directly (no need to unzip)
To update: download the latest ZIP, click “…” on the skill card, choose Replace, upload.
2.5 Brand Profile Setup
The brand profile is optional but recommended. It persists your identity, brand colors, defaults, and writing habits across sessions.
Create the file:
1mkdir -p ~/.config/kami
2# Copy the example template and customize
3cp references/brand.example.md ~/.config/kami/brand.md
The file uses YAML frontmatter for structured fields and a Markdown body for freeform notes:
1---
2name: Jane Doe
3role: Founder & CEO
4email: jane@example.com
5brand_color: "#1B365D"
6language: en
7page_size: A4
8tone: professional
9---
10
11# Writing Habits
12- Prefer active voice
13- Keep sentences under 25 words
14- Use Oxford comma
Priority order: explicit prompt > editorial judgment > habit notes > frontmatter defaults > built-in defaults. The profile fills gaps silently; it never overrides what you ask for in the current conversation.
2.6 Font Handling
Each language uses a single serif font for the entire page:
| Language | Font | License | Notes |
|---|---|---|---|
| Chinese | TsangerJinKai02 (倉耳今楷02) | Free personal use; commercial license from tsanger.cn | |
| English | Charter | OFL | Bundled |
| Japanese | YuMincho (游明朝) | System-bundled | Best-effort path |
| Korean | Source Han Serif K (본명조) | OFL | Best-effort path |
Large CJK fonts are excluded from the skill package to keep the ZIP lightweight. When fonts are missing, scripts/ensure-fonts.sh recovers them into the user font directory:
1bash scripts/ensure-fonts.sh
In a full repo checkout, fonts load from local files first, then fall back to jsDelivr CDN.
Installation Decision Tree
flowchart TD
A[Which AI tool?] --> B{Claude Code?}
B -->|Yes| C["/plugin marketplace add tw93/kami"]
B -->|No| D{Codex?}
D -->|Yes| E["codex plugin marketplace add tw93/kami"]
D -->|No| F{Claude Desktop?}
F -->|Yes| G["Download kami.zip, upload via Skills UI"]
F -->|No| H["npx skills add tw93/kami/..."]
C --> I[Run: bash scripts/ensure-fonts.sh]
E --> I
G --> I
H --> I
I --> J{Brand profile?}
J -->|Yes| K["Create ~/.config/kami/brand.md"]
J -->|No| L[Ready to use]
K --> L
3. Core Architecture (核心架構)
The 6-Step Workflow
Every Kami document goes through the same six steps, whether you are making a one-pager or a 15-page white paper:
- Load brand profile – Read
~/.config/kami/brand.mdif it exists. Apply as lowest-priority defaults. - Decide the language – Match the user’s language. Chinese uses
*.html, English uses*-en.html, Korean uses*-ko.html, Japanese uses the Chinese path as best-effort with YuMincho. - Pick the document type – Match user intent to one of the 10 document types using the decision tree.
- Fill the template – The agent fills HTML template placeholders with actual content, following design.md and writing.md guidelines.
- Build – Render to the target format (WeasyPrint PDF, python-pptx PPTX, or Marp MD).
- Verify – Visual QA check, especially for CJK rendering and layout integrity.
The 10 Document Types
| # | Type | Trigger Words | Pages | Output |
|---|---|---|---|---|
| 1 | One-Pager | “one-pager / exec summary / 方案 / 执行摘要” | 1 | |
| 2 | Long Doc | “white paper / 白皮书 / 长文 / technical report” | 6-15 | |
| 3 | Letter | “formal letter / 信件 / 推荐信 / memo” | 1 | |
| 4 | Portfolio | “portfolio / 作品集 / case studies” | 3-6 | |
| 5 | Resume | “resume / CV / 简历 / 履歴書” | 1-2 | |
| 6 | Slides (Weasy) | “slides / PPT / deck / 演示” | 8-20 | |
| 7 | Equity Report | “个股研报 / equity report / investment memo” | 4-8 | |
| 8 | Changelog | “changelog / release notes / 版本记录” | 1-3 | |
| 9 | Landing Page | “landing page / 落地页 / 官网 / product page” | N/A | HTML |
Three Rendering Paths
| Path | Technology | When to Use | Output |
|---|---|---|---|
| WeasyPrint HTML to PDF | Python + WeasyPrint | Default for all document types | .pdf |
| python-pptx to PPTX | Python + python-pptx | User explicitly needs editable slides | .pptx |
| Marp to Markdown slides | Marp CLI | User explicitly asks for “Marp” or “markdown slides” | .md + .pdf |
Full Pipeline Architecture
flowchart TB
subgraph Input
U[User Prompt]
B[Brand Profile]
M[Mermaid Source .mmd]
end
subgraph KamiCore["Kami Core Engine"]
S1[Step 1: Load Brand]
S2[Step 2: Language Detection]
S3[Step 3: Doc Type Selection]
S4[Step 4: Fill Template]
S5[Step 5: Build]
S6[Step 6: Verify]
S1 --> S2 --> S3 --> S4 --> S5 --> S6
end
subgraph Templates["10 Templates"]
T1[one-pager]
T2[long-doc]
T3[letter]
T4[portfolio]
T5[resume]
T6[slides-weasy]
T7[equity-report]
T8[changelog]
T9[landing-page]
end
subgraph MermaidPipeline["Mermaid Pipeline"]
BM[beautiful-mermaid SVG]
MC[mermaid-cli PNG]
MN[mermaid_normalize.py]
CI[codex-image Editorial PNG]
BM --> MN --> SVG[Clean SVG]
MC --> PNG[High-res PNG]
M --> CI
end
subgraph Output
PDF[WeasyPrint PDF]
PPTX[python-pptx PPTX]
MARP[Marp MD Slides]
HTML[Static HTML Site]
end
U --> S1
B --> S1
S3 --> Templates
Templates --> S4
MermaidPipeline --> S4
S5 --> PDF
S5 --> PPTX
S5 --> MARP
S5 --> HTML
style KamiCore fill:#f5f4ed,stroke:#1B365D
style T10 fill:#00A896,color:#fff
4. Design System Deep Dive (設計系統詳解)
The Kami Palette
The entire design system rests on a deliberately limited palette. The constraint is the point: fewer colors means more consistency.
| Token | Name | Hex | Role |
|---|---|---|---|
--parchment | Parchment | #f5f4ed | Canvas background – warm, never pure white |
--ivory | Ivory | #faf9f5 | Card/section backgrounds |
--brand | Ink Blue | #1B365D | Sole accent color – headings, links, emphasis |
--near-black | Near Black | #141413 | Primary text |
--dark-warm | Dark Warm | #3d3d3a | Secondary text |
--olive | Olive | #504e49 | Tertiary text, lines |
--stone | Stone | #6b6a64 | Muted text, captions |
--border | Border | #e8e6dc | Borders, dividers |
The golden rule: ink blue is the only accent. Everything else is a shade of warm gray. No other colors, no gradients, no drop shadows, no 3D effects.
Typography
Kami uses a single serif font per language. The choice is deliberate: serif typefaces carry hierarchy naturally (through weight and size variation), while sans-serif requires additional visual cues.
| Language | Font | Category | Fallback |
|---|---|---|---|
| English | Charter | Serif | Georgia, Times New Roman |
| Chinese | TsangerJinKai02 | Calligraphic serif | Noto Serif CJK SC |
| Japanese | YuMincho | Mincho (serif) | Noto Serif CJK JP |
| Korean | Source Han Serif K | Serif | Noto Serif CJK KR |
The type scale is simple:
- Title: large, bold, ink blue
- Subtitle: medium, regular weight, dark warm gray
- Body: comfortable reading size, near black
- Caption: small, stone gray
Layout Principles
- No shadows – Drop shadows are a crutch. Use whitespace and borders instead.
- No gradients – Solid colors only. This also ensures WeasyPrint compatibility.
- Serif hierarchy – Size and weight carry structure, not color variety.
- Generous whitespace – Let the content breathe. A cramped page is an unread page.
- Warm canvas – The
#f5f4edparchment background is warmer than pure white, reducing eye strain and giving documents a composed, editorial feel. - Print variant – An opt-in white-paper mode flips the background to white for office printers, sinking warmth into cards and tables.
17 Inline SVG Diagram Types
Kami ships 17 hand-drawn diagram primitives as inline SVG. These are not separate document types – they are components you embed inside any document.
| Category | Diagram Types |
|---|---|
| Flow & Process | Architecture, Flowchart, Gantt, Timeline |
| Data Visualization | Bar Chart, Line Chart, Donut Chart, Candlestick, Waterfall |
| Relationships | Mindmap, Org Chart, Radar |
| Technical | Sequence, Class, ER |
| Comparison | Comparison, Quadrant |
Each diagram uses the Kami palette (parchment background, ink blue accent, warm gray neutrals) and is fully static – no JavaScript required.
5. Document Types & Examples (文件類型與範例)
5.1 One-Pager (一頁紙)
Use case: Executive summaries, product briefs, investor one-pagers. Must fit on a single page.
Key features: Dense layout, metric tiles, clear section hierarchy, designed for quick scanning.
Example prompts:
- EN:
"Make a one-pager for my SaaS startup that summarizes our Q2 metrics" - CN:
"帮我做一份一页纸,总结我们的 Q2 运营数据"
5.2 Long Doc (長文)
Use case: White papers, technical reports, annual summaries. 6-15 pages of sustained argument.
Key features: Table of contents, numbered sections, footnotes, figure captions, margin notes.
Example prompts:
- EN:
"Turn this research into a 10-page white paper on federated learning" - CN:
"帮我把这份研究排版成一份关于联邦学习的白皮书"
5.3 Letter (信件)
Use case: Recommendation letters, formal correspondence, resignations, memos.
Key features: Letterhead, date, addressee, formal closing, signature line.
Example prompts:
- EN:
"Write a formal recommendation letter for my colleague" - CN:
"帮我写一封正式推荐信"
5.4 Portfolio (作品集)
Use case: Project showcases, case studies, design portfolios. 3-6 pages, visual-heavy.
Key features: Hero images, project cards, before/after comparisons, testimonials.
Example prompts:
- EN:
"Make a portfolio of my top 5 open source projects" - CN:
"帮我做一份我的开源项目作品集"
5.5 Resume (簡歷)
Use case: Professional resumes, academic CVs. 1-2 pages.
Key features: Header with contact info, experience timeline, skill tags, education section.
Example prompts:
- EN:
"Build me a resume highlighting my ML engineering experience" - CN:
"帮我做一份强调机器学习工程经验的简历"
5.6 Slides (Weasy) (簡報 - 學術風格)
Use case: Conference talks, research presentations, academic seminars. The default presentation style.
Key features: Parchment background, Charter serif, eyebrow section labels, SVG diagrams, speaker notes.
Example prompts:
- EN:
"Design a slide deck for my talk on agent architectures" - CN:
"帮我做一套关于 Agent 架构的演讲幻灯片"
5.7 Equity Report (個股研報)
Use case: Investment memos, stock analyses, quarterly reviews.
Key features: Metric dashboards, price charts (candlestick/waterfall), valuation tables, risk matrices.
Example prompts:
- EN:
"Write a Tesla Q1 2026 equity report with my analysis notes" - CN:
"帮我写一份 Tesla Q1 2026 的个股研报"
5.8 Changelog (更新日誌)
Use case: Release notes, version histories, product update logs.
Key features: Version headers, date stamps, categorized changes (Added/Changed/Fixed/Removed).
Example prompts:
- EN:
"Make a changelog for our v1.7.1 release" - CN:
"帮我做一份 v1.7.1 的更新日志"
5.9 Landing Page (落地頁)
Use case: Product homepages, marketing sites. Screen-first, no PDF output.
Key features: Hero section with entrance animation, gallery carousel with auto-rotate, responsive breakpoints (880px / 480px), prefers-reduced-motion support, multilingual companion files (sitemap, robots.txt, llms.txt).
Example prompts:
- EN:
"Build a landing page for my Mac utility app" - CN:
"帮我做一个产品落地页"
Use case: Corporate BD pitches, investor presentations, pharmaceutical pipeline decks. See Section 7 for full details.
Key features: Teal + navy palette, sans-serif (Inter/Lato/Outfit), pipeline navigation bar, 8 slide types, card-based layout.
Example prompts:
|——–|————-|—————|
| Background | Parchment #f5f4ed | White #ffffff |
| Accent color | Ink blue #1B365D | Teal #00A896 |
| Typography | Charter (serif) | Outfit/Inter/Lato (sans-serif) |
| Style | Academic, editorial, quiet | Corporate BD, pitch-ready |
| Layout | Dense academic rhythm | Card-based, icon-rich, generous spacing |
| Icons | None | Circular container outline icons |
| Navigation | Eyebrow section labels | Pipeline progress bar (5-stage) |
| Audience | Researchers, academics | Investors, BD partners, executives |
6. Mermaid Diagram Pipeline (Mermaid 圖表流水線)
Why Mermaid Matters
Mermaid is a text-based diagram language. Instead of dragging boxes in PowerPoint, you describe the structure in code, and a renderer draws it. This makes diagrams version-controllable, AI-writable, and reproducible.
Kami integrates Mermaid through two distinct rendering paths, each suited to different environments.
Path 1: beautiful-mermaid (Browser SVG)
beautiful-mermaid is a browser-based renderer that produces native SVG with <text> elements (not <foreignObject>). This is the preferred path for PDF output.
Workflow:
- Write your Mermaid code in a
.mmdfile - Render to SVG in any browser running beautiful-mermaid (e.g., https://agents.craft.do/mermaid)
- Run the normalizer to re-theme to Kami palette:
1python3 scripts/mermaid_normalize.py raw.svg -o clean.svg - Embed the clean SVG into your document template
Path 2: mermaid-cli (Headless PNG)
When beautiful-mermaid is unavailable (e.g., headless Docker environments), mermaid-cli renders .mmd files directly. However, its SVG output uses <foreignObject> for text labels, which WeasyPrint cannot render – the PDF shows boxes and lines with invisible text.
The fix: render to PNG, not SVG.
1# Create a puppeteer config for Docker/container
2echo '{"args":["--no-sandbox","--disable-setuid-sandbox"]}' > puppeteer-config.json
3
4# Render to PNG at high resolution
5npx --yes @mermaid-js/mermaid-cli \
6 -i diagram.mmd -o diagram.png \
7 -b white -w 1600 \
8 -p puppeteer-config.json \
9 -c theme.json --quiet
The mermaid_normalize.py Script
This pure Python script (no Node dependency) transforms any beautiful-mermaid SVG into a Kami-themed diagram:
| What it does | Why |
|---|---|
| Re-themes to Kami palette (7 color roles) | Source theme becomes irrelevant |
Resolves var() and color-mix(in srgb, ...) to static hex | WeasyPrint cannot compute CSS variables or color-mix() |
Strips Google Fonts @import | External fonts break offline rendering |
Rewrites font-family to Kami serif stack | CJK labels embed correctly |
The --check flag runs a lint pass that catches any color-mix(, <foreignObject>, or web-font import that would break PDF rendering.
The WeasyPrint SVG Trap
This is the single most common gotcha in the Kami mermaid pipeline:
mermaid-cli SVG uses
<foreignObject>for text labels. WeasyPrint ignores<foreignObject>. Your PDF will have boxes and lines but no text inside them.
The solution is simple: if you are using mermaid-cli, always render to PNG, not SVG. If you are using beautiful-mermaid, its <text> elements work fine after normalization.
The Kami Theme (mermaid-theme.json)
references/mermaid-theme.json maps beautiful-mermaid’s seven color roles onto the Kami palette:
| Role | Token | Hex | Used For |
|---|---|---|---|
bg | --parchment | #f5f4ed | Diagram background |
fg | --near-black | #141413 | Text labels |
line | --olive | #504e49 | Connector lines |
accent | --brand | #1B365D | Focal element highlight |
muted | --stone | #6b6a64 | Secondary labels |
surface | --ivory | #faf9f5 | Node fill |
border | --border | #e8e6dc | Node borders |
The Two Paths Compared
flowchart LR
subgraph Input
MMD[".mmd Source File"]
end
subgraph PathA["Path A: beautiful-mermaid"]
BM["Browser Render (SVG)"]
NM["mermaid_normalize.py"]
CSVG["Clean SVG"]
BM --> NM --> CSVG
end
subgraph PathB["Path B: mermaid-cli"]
MCLI["npx mermaid-cli (PNG)"]
HPNG["High-res PNG"]
MCLI --> HPNG
end
MMD --> BM
MMD --> MCLI
CSVG --> DOC["Embed in Document"]
HPNG --> DOC
style PathA fill:#f5f4ed,stroke:#1B365D
style PathB fill:#f5f4ed,stroke:#504e49
Sizing Guide for mermaid-cli PNGs
| Diagram Shape | Slides Style | Long-doc Style |
|---|---|---|
| Wide (landscape) | max-width: 100%; max-height: 110mm; | max-width: 100%; |
| Tall (portrait, e.g., flowchart TB) | max-width: 80%; max-height: 120mm; | max-width: 80%; |
| Square | max-width: 90%; max-height: 110mm; | max-width: 90%; |
Always add object-fit: contain; display: block; margin: 0 auto; for centering.
Why It Was Created
The upstream Kami slides-weasy template is designed for academic and editorial presentations: warm parchment background, Charter serif, quiet rhythm. This is perfect for research talks but wrong for corporate BD (Business Development; 商務開發) pitch decks, where audiences expect a modern, clean, sans-serif aesthetic with a corporate color identity.
CSS Variables (WeasyPrint safe):
1:root {
2 /* Primary */
3 --vz-teal: #00A896; /* Primary brand accent */
4 --vz-teal-dark: #007A6E; /* Darker teal for emphasis */
5 --vz-teal-deepest: #1A5E59;/* Deepest teal - title slide bg */
6
7 /* Text */
8 --vz-navy: #0F172A; /* Primary text (near black) */
9 --vz-slate: #475569; /* Secondary text */
10 --vz-muted: #6F7A88; /* Muted text */
11
12 /* Surface */
13 --vz-white: #ffffff; /* Main background */
14 --vz-gray-light: #f8fafc; /* Card backgrounds */
15 --vz-border: #e2e8f0; /* Borders and dividers */
16
17 /* Semantic */
18 --vz-red: #C00000; /* Risk, warning */
19 --vz-green: #70AD47; /* Success, verified */
20 --vz-orange: #ED7D31; /* Caution */
21 --vz-yellow: #FFC000; /* Attention */
22}
The 8 Slide Types
| # | CSS Class | Purpose | Layout |
|---|---|---|---|
| 1 | .slide-title | Cover / chapter page | Solid deep teal bg + centered white text |
| 2 | .slide-content | Card-based content | Title + 3-column card grid |
| 3 | .slide-pipeline | Pipeline navigation | 5-stage progress bar + content area |
| 4 | .slide-tech | Technical architecture | Two-column: 55% diagram + 45% text |
| 5 | .slide-table | Data tables | Full-width table with dark header |
| 6 | .slide-media | Media / external proof | 2-3 screenshot grid with source attribution |
| 7 | .slide-team | Team introduction | Person card grid (avatar + name + title) |
| 8 | .slide-contact | Contact / CTA | Contact info + addresses + call-to-action |
All slides share a common HTML structure:
1<section class="slide slide-{type}">
2 <div class="slide-header">
3 <span class="eyebrow">SECTION LABEL</span>
4 <h2>Page Title</h2>
5 <p class="lead">Subtitle</p>
6 </div>
7 <div class="slide-body">
8 <!-- Type-specific content -->
9 </div>
10 <div class="slide-footer">
11 <span class="confidential">Confidential. ...</span>
12 <span class="page-num"></span>
13 </div>
14</section>
How to Trigger
| Trigger | Behavior |
|---|---|
"企業簡報" / "投資人簡報" | Chinese trigger words |
Typography
| Role | Font | Covers |
|---|---|---|
| Headings | Outfit | Geometric sans, replaces Montserrat |
| Body | Inter | Readable sans, replaces Space Grotesk |
| Fallback | Lato | Lightweight secondary sans |
CJK fallback: Microsoft JhengHei (TC), Malgun Gothic (KR), Noto Sans CJK.
WeasyPrint Adaptations
Because WeasyPrint is not a browser, certain CSS features must be adapted:
| Browser CSS | WeasyPrint Replacement |
|---|---|
linear-gradient() | Solid color or inline SVG <rect> |
box-shadow | border simulation |
backdrop-filter | Omitted |
flex-wrap (complex) | table-cell layout for card grids |
| CSS Grid (advanced) | Basic grid OK; complex layouts use <table> |
Title slide backgrounds use --vz-teal-deepest (#1A5E59) as a solid color instead of a gradient.
8. Custom Extension: codex-image Skill (客製化:Codex 圖片生成 Layer 24)
The Problem
Both beautiful-mermaid and mermaid-cli produce accurate diagrams, but they look like tool output – functional, precise, and plain. For investor pitch decks and conference presentations, you want diagrams that look like they were drawn by a designer: editorial illustrations with character and visual appeal.
The Solution
The codex-image skill converts mermaid code (or natural language descriptions) into editorial-style 16:9 PNG images using the Codex CLI. Under the hood, the Codex agent (gpt-5.4) internally calls the imagegen/gpt-image-2 model to render beautiful illustrations.
The Key Discovery
The path to making this work was not obvious:
- Direct
-m gpt-image-2fails – The gpt-image-2 model is not supported when using Codex with a ChatGPT account. - Direct API call fails – The environment has no
OPENAI_API_KEY(Codex uses ChatGPT OAuth). - The working approach: Use the default model
codex execand let the Codex agent internally call imagegen. This bypasses the 350-character API limit and allows complete mermaid code (tested up to 1,863 characters) as input.
1# This fails:
2codex exec -m gpt-image-2 "draw a diagram"
3
4# This works:
5codex exec "Redraw this Mermaid diagram as a clean 16:9 landscape diagram..."
The 6 Style Presets
All presets share a common prefix: "Redraw this Mermaid diagram as a clean 16:9 landscape diagram (1536x1024)."
| Preset | Background | Accent | Feel | Best For |
|---|---|---|---|---|
editorial (default) | Parchment #f5f4ed | Ink blue #1B365D | Calm, composed, reportlike | Academic, research, kami docs |
tech-dark | Dark #1a1a2e | Cyan #00d4ff | Futuristic terminal | Developer talks, tech keynotes |
sketch | White | Black sketch lines | Hand-drawn whiteboard | Brainstorming, workshops |
pharma | White | Deep navy #003366 + teal | Clinical, regulatory-ready | Regulatory filings, clinical reports |
scripts/codex-image.sh
The 546-line shell script is the execution engine. Key capabilities:
1# Batch mode: process all .mmd files in a directory
2bash scripts/codex-image.sh mermaid_assets/deck-a/
3
4
5# Custom style prompt
6bash scripts/codex-image.sh diagrams/ --style "neon cyberpunk, dark bg" --timeout 180
7
8# Add extra context
9bash scripts/codex-image.sh flow.mmd --context "emphasise the JAK2 pathway"
How it works internally:
- Reads
.mmdfile content - Assembles prompt:
style_prompt + mermaid_code + context - Calls
codex exec "$PROMPT"and captures the log - Extracts the session ID from the log using UUID regex
- Copies the generated image from
~/.codex/generated_images/{sid}/ig_*.pngto the output directory
Output: 1536x1024 PNG at gpt-image-2 high quality, saved to {input_dir}/codex_generated/.
Routing: codex-image vs. Kami Mermaid
Both handle mermaid, but they serve different purposes:
| Signal | Routes To |
|---|---|
Contains codex / gpt-image / editorial diagram / 生成 png | codex-image |
Contains PDF / WeasyPrint / 排版 / kami build | Kami (mermaid-cli or beautiful-mermaid) |
Contains mermaid normalize / SVG / beautiful-mermaid | Kami |
Only editorial + mermaid, no other signal | Ask user which path |
Principle: codex-image produces AI-generated concept illustrations (editorial style). Kami produces programmatically rendered precise diagrams. They complement, not compete.
9. Custom Extension: kami_to_pptx Scripts (客製化:PPTX 生成腳本)
Why Separate Scripts?
WeasyPrint HTML-to-PDF is the default Kami output path. But sometimes users need an editable PPTX file – to hand off to a colleague who uses PowerPoint, to make last-minute adjustments before a meeting, or to comply with a corporate template requirement.
The python-pptx library can create PPTX files programmatically, but raw python-pptx output looks like auto-generated textboxes on blank slides. The kami_to_pptx scripts bring the full Kami design system into the PPTX world.
kami_to_pptx.py (Kami Academic Style)
Size: 1,534 lines
This script generates PPTX files using the Kami parchment aesthetic:
Design constants:
1PARCHMENT = RGBColor(0xf5, 0xf4, 0xed) # Canvas background
2IVORY = RGBColor(0xfa, 0xf9, 0xf5) # Card backgrounds
3BRAND = RGBColor(0x1B, 0x5F, 0xAA) # Accent (adjusted for screen)
4NEAR_BLACK = RGBColor(0x14, 0x14, 0x13) # Primary text
5OLIVE = RGBColor(0x50, 0x4e, 0x49) # Tertiary text
6BORDER = RGBColor(0xe8, 0xe6, 0xdc) # Borders
7SERIF = "Charter" # Primary font
Key helper functions:
| Function | Purpose |
|---|---|
blank_slide(prs) | Creates a slide with Kami parchment background (full-bleed rectangle fill) |
add_text(slide, ...) | Adds a text box with proper font, color, alignment, and optional anchor |
add_rich_text(slide, runs_data, ...) | Adds text with mixed formatting (bold/italic/color per run) |
add_card_bg(slide, ...) | Draws a rounded-rectangle card background (ivory fill, border stroke) |
diagram_text_slide(prs, ...) | Full slide layout: diagram image + text legend + caption |
diagram_table_slide(prs, ...) | Full slide layout: diagram image + data table + caption |
platform_slide(prs, ...) | Platform overview layout with multiple content zones |
Size: 814 lines
1WHITE = RGBColor(0xff, 0xff, 0xff) # Canvas background
2VZ_TEAL = RGBColor(0x00, 0xA8, 0x96) # Primary accent
3VZ_NAVY = RGBColor(0x0F, 0x17, 0x2A) # Primary text
4VZ_SLATE = RGBColor(0x47, 0x55, 0x69) # Secondary text
5VZ_TEAL_DEEP = RGBColor(0x1A, 0x5E, 0x59) # Deep teal for title slides
6SERIF = "Inter" # Primary font (sans-serif)
When to Use
| Scenario | Tool |
|---|---|
| Standard PDF output, no edits needed | WeasyPrint (default path) |
| Editable PPTX with Kami parchment design | kami_to_pptx.py |
| Markdown-first slides, version-controlled | Marp |
10. Two-Stage Workflow (兩階段工作流)
The most powerful pattern in the Kami ecosystem is the two-stage workflow, which combines fast structural iteration with high-fidelity visual polish.
Stage 1: Quick Structure Review
1Markdown (with mermaid code)
2 |
3 v
4Extract .mmd files from fenced code blocks
5 |
6 v
7mermaid-cli renders each .mmd to PNG (fast, accurate)
8 |
9 v
10 |
11 v
12WeasyPrint renders to PDF v1
13 |
14 v
15User reviews structure and content
Purpose: Get the content and layout right before investing in visual polish. mermaid-cli PNGs are functional but plain – perfectly adequate for structure review.
Stage 2: Beautiful Editorial Version
1 |
2 v
3Codex agent generates editorial PNGs (1536x1024 each)
4 |
5 v
6Replace mermaid-cli PNGs with codex editorial PNGs
7 |
8 v
9WeasyPrint renders to PDF v2 (SAVED SEPARATELY)
10 |
11 v
12User reviews final output
Purpose: Transform the verified structure into a presentation-ready document with AI-generated editorial illustrations.
The Full Sequence
sequenceDiagram
participant U as User
participant C as Claude Agent
participant MC as mermaid-cli
participant WP as WeasyPrint
participant CX as Codex (codex-image)
U->>C: Markdown with mermaid code
C->>C: Extract .mmd files
rect rgb(245, 244, 237)
Note over C,WP: Stage 1 - Structure Review
C->>MC: Render .mmd to PNG
MC-->>C: diagram PNGs
C->>WP: Build HTML to PDF
WP-->>C: pdf-v1.pdf
C->>U: Review structure
end
U->>C: Structure approved
rect rgb(0, 168, 150)
Note over C,CX: Stage 2 - Editorial Polish
CX-->>C: editorial PNGs (1536x1024)
C->>C: Replace PNGs in template
C->>WP: Build HTML to PDF
WP-->>C: pdf-v2.pdf (saved separately)
C->>U: Final output
end
Key Rules
- v1 and v2 coexist – Never overwrite v1 with v2. They serve different purposes (review vs. delivery).
.mmdintermediate files are preserved – The mermaid source files are kept for reproducibility.- Stage 2 is opt-in – If the mermaid-cli PNGs are sufficient, skip codex-image entirely.
- codex-image output goes to a separate directory –
{mmd_dir}/codex_generated/keeps editorial PNGs isolated from mermaid-cli output.
File Structure After Both Stages
1project/
2├── content.md # Source markdown
3├── mmd/ # Extracted mermaid sources
4│ ├── slide-01.mmd
5│ ├── slide-02.mmd
6│ ├── slide-01.png # mermaid-cli output (Stage 1)
7│ ├── slide-02.png
8│ └── codex_generated/ # codex-image output (Stage 2)
9│ ├── slide-01.png
10│ └── slide-02.png
11├── output-v1.pdf # Stage 1 (structure review)
12└── output-v2.pdf # Stage 2 (editorial polish)
11. FAQ & Troubleshooting (常見問題)
Q1: My PDF has boxes and lines but no text in diagrams
Cause: You embedded a mermaid-cli SVG directly. mermaid-cli uses <foreignObject> for text, which WeasyPrint ignores.
Fix: Render to PNG instead of SVG:
1npx --yes @mermaid-js/mermaid-cli -i diagram.mmd -o diagram.png -b white -w 1600
Or use beautiful-mermaid SVG + mermaid_normalize.py instead.
Q2: Chinese/Korean text renders as boxes or tofu
Cause: CJK fonts are not installed.
Fix:
1bash scripts/ensure-fonts.sh
For Chinese, ensure TsangerJinKai02 is in your user font directory. For Korean, ensure Source Han Serif K is installed. After installing fonts, you may need to clear the font cache:
1fc-cache -fv
Q3: codex exec times out or produces no image
Cause: Network issues, Codex auth expiration, or overly complex prompt.
Fix:
- Verify Codex is working:
codex doctor - Check auth: ensure
~/.codex/auth.jsonhas valid credentials - Try a simpler prompt first to isolate the issue
- Increase timeout:
--timeout 300(default is 300 seconds) - Use
--retry 1to automatically retry on failure
Q4: codex-image cannot extract the session ID
Cause: The Codex log format may have changed, or the image was not generated.
Fix: The script uses UUID regex to find the session ID in the codex exec output. If this fails:
- Check
~/.codex/generated_images/manually for recent folders - Try running
codex execdirectly and observe the output - Update the Codex CLI to the latest version
Q5: WeasyPrint CSS does not look like the browser preview
Cause: WeasyPrint has limited CSS support compared to browsers.
Common traps and fixes:
| CSS Feature | Browser | WeasyPrint | Fix |
|---|---|---|---|
linear-gradient() | Works | Ignored | Use solid color or inline SVG |
box-shadow | Works | Ignored | Use border to simulate |
flex-wrap (complex) | Works | Unreliable | Use table-cell layout |
CSS var() in SVG | Works | Ignored | Resolve to static hex via mermaid_normalize.py |
color-mix() | Works | Ignored | Resolve to static hex |
@font-face with woff2 | Works | Works | No issue |
border-radius | Works | Works | No issue |
Q6: PPTX slides look like plain textboxes
Cause: You used basic python-pptx without the design system helpers.
Q7: Mermaid SVG text is invisible in kami PDF but visible in browser
Cause: The SVG has not been normalized. Raw beautiful-mermaid SVGs may contain color-mix(), CSS variables, or Google Fonts imports that WeasyPrint cannot process.
Fix:
1python3 scripts/mermaid_normalize.py raw.svg -o clean.svg
2# Verify:
3python3 scripts/mermaid_normalize.py clean.svg --check
Q8: Which slide template should I use?
| Scenario | Template |
|---|---|
| Academic conference talk | slides-weasy |
| Research presentation | slides-weasy |
| Markdown-first, version-controlled | Marp variant |
| Need editable PPTX | kami_to_pptx*.py scripts |
Q9: The .pageformat directive causes an error on the first page of my PDF
Cause: Incorrect syntax. .pageformat {A4} is wrong.
Fix: Use the named parameter syntax:
1.pageformat size:{A4}
Q10: How do I use the print (white-paper) variant?
Add the print variant flag when building. This flips the background from parchment to pure white, suitable for office or home printers. Cards and tables retain warmth so the hierarchy still reads.
12. Quick Reference Checklist (速查清單)
Installation Checklist
- Install Kami via your tool’s plugin system (Claude Code / Codex / Claude Desktop / Generic)
- Run
bash scripts/ensure-fonts.shto install CJK fonts - (Optional) Create
~/.config/kami/brand.mdwith your identity and defaults - (Optional) Install WeasyPrint:
pip install weasyprint(oruv pip install weasyprint) - (Optional) Install python-pptx:
pip install python-pptx Pillow(for PPTX output) - (Optional) Install mermaid-cli:
npm install -g @mermaid-js/mermaid-cli(for diagram rendering) - (Optional) Verify Codex CLI:
codex doctor(for codex-image skill)
Document Type Selection Guide
| I need… | Use this |
|---|---|
| A single-page executive summary | One-Pager |
| A multi-page technical report | Long Doc |
| Formal correspondence | Letter |
| A visual project showcase | Portfolio |
| A professional CV | Resume |
| Academic/research slides | Slides (Weasy) |
| An investment memo | Equity Report |
| Release notes | Changelog |
| A product homepage | Landing Page |
Style Preset Selection Guide (codex-image)
| I need diagrams for… | Use this preset |
|---|---|
| Kami parchment documents | editorial |
| Developer/tech presentations | tech-dark |
| Workshop/brainstorming materials | sketch |
| Pharmaceutical/regulatory documents | pharma |
Key File Locations
| File | Purpose |
|---|---|
~/.config/kami/brand.md | Brand profile (identity, colors, defaults) |
references/design.md | Complete design specification |
references/writing.md | Writing guidelines |
references/anti-patterns.md | What NOT to do |
references/mermaid.md | Mermaid diagram pipeline documentation |
references/mermaid-theme.json | Kami mermaid color theme |
references/tokens.json | Design tokens (color values) |
references/brand.example.md | Brand profile template |
scripts/mermaid_normalize.py | SVG normalizer (re-theme + WeasyPrint safe) |
scripts/codex-image.sh | Codex editorial image generation |
scripts/kami_to_pptx.py | PPTX generator (Kami parchment style) |
scripts/ensure-fonts.sh | CJK font recovery |
scripts/build.py | Main build script |
scripts/check-update.sh | Version check (non-blocking, daily) |
assets/diagrams/ | 17 pre-built SVG diagram templates |
assets/templates/marp/ | Marp slide template and CSS |
CHEATSHEET.md | Quick design reference |
Build Commands
1# Build all targets
2python3 scripts/build.py
3
4# Quick validation check
5python3 scripts/build.py --check
6
7# Full verification
8python3 scripts/build.py --verify
9
10# Normalize a mermaid SVG for PDF embedding
11python3 scripts/mermaid_normalize.py raw.svg -o clean.svg
12
13# Check an SVG for WeasyPrint compatibility
14python3 scripts/mermaid_normalize.py diagram.svg --check
15
16# Generate editorial diagrams from mermaid
17bash scripts/codex-image.sh mermaid_assets/ --style editorial
18
19
20# Recover missing fonts
21bash scripts/ensure-fonts.sh
22
23# Run tests
24python3 scripts/tests/test_build.py
Comments