A JSON-to-Typst publishing engine for AI-generated ebooks, workbooks, slide decks, and visual content.
This project accepts structured content packages, validates them against the shared AI Flywheel content schemas, generates Typst source, and compiles them into PDF outputs with optional PNG page previews.
It is designed for workflows where one agent writes or structures the content, and this engine handles layout, pagination, visual composition, and export.
Content Agent
-> ebook-layout.v1 JSON
-> schema validation
-> Typst generation
-> Typst compile
-> PDF + PNG previews
Content Agent
-> slides-layout.v1 JSON
-> schema validation
-> Typst generation
-> Typst compile
-> PDF slides + PNG previews
Content Agent
-> poster slide JSON
-> image asset preparation
-> Typst visual composition
-> PDF poster + PNG preview
- Node.js 16.14+
- Typst CLI
typst --versionnpm installnpm run validate
npm run validate:slides
npm run build:example
npm run build:modern
npm run build:classic
npm run build:modern-classic
npm run build:slides
npm run validate:poster
npm run build:posterOutputs:
dist/habit-design.pdfdist/habit-design-modern.pdfdist/habit-design-classic.pdfdist/habit-design-modern-classic.pdfdist/layout-as-code-slides.pdfdist/poster-design.pdfdist/pages/page-001.png, etc.dist/layout-as-code-slides-pages/slide-1.png, etc.dist/poster-design-pages/slide-1.png
ebook-layout validate examples/habit-design/content.json
ebook-layout build \
--input examples/habit-design/content.json \
--template habit-workbook \
--output dist/habit-design.pdf \
--preview dist/pages
ebook-layout validate-slides examples/layout-as-code-slides/content.json
ebook-layout build-slides \
--input examples/layout-as-code-slides/content.json \
--template quiet-power-slides \
--output dist/layout-as-code-slides.pdf \
--preview dist/layout-as-code-slides-pages
ebook-layout validate-slides examples/poster-design/content.json
ebook-layout build-slides \
--input examples/poster-design/content.json \
--template quiet-power-slides \
--output dist/poster-design.pdf \
--preview dist/poster-design-pagesAvailable templates:
habit-workbook: clean practical workbook layoutmodern-workbook: contemporary editorial workbook layout with softer cards and teal accentsclassic-textbook: classic textbook layout with serif typography, generous margins, and simple rulesmodern-classic-textbook: white, spacious textbook layout with modern sans-serif typographyquiet-power-slides: quiet 16:9 presentation layout for publishing infrastructure stories
Supported slide content includes hero slides, structured presentation slides, closing slides, and poster-style visual slides with full-bleed background images and text overlays.
The upstream content agent must produce JSON matching:
@mongmx/ai-flywheel-content-schemas/schemas/ebook-layout.v1.schema.json
@mongmx/ai-flywheel-content-schemas/schemas/slides-layout.v1.schema.json
The schemas live in the shared repository:
https://github.com/mongmx/ai-flywheel-content-schemas
Minimal shape:
{
"schema_version": "ebook-layout.v1",
"book": {
"title": "Book Title",
"description": "Short book description"
},
"layout": {
"template": "habit-workbook",
"theme": "navy-yellow",
"page_size": "a4"
},
"chapters": []
}Minimal slides shape:
{
"schema_version": "slides-layout.v1",
"document_type": "slides",
"deck": {
"title": "Deck Title"
},
"layout": {
"template": "quiet-power-slides",
"theme": "quiet-power",
"page_size": "16:9"
},
"output": {
"width_px": 1920,
"height_px": 1080,
"dpi": 144
},
"slides": []
}Poster-style visual content uses the same slides-layout.v1 contract with type: "poster":
{
"type": "poster",
"title": "ดวงอาทิตย์",
"background_image_url": "https://example.com/bg-poster-01.jpg",
"brand_kicker": "iKL",
"brand_name": "STUDIO",
"quote": "ดวงอาทิตย์\nต่อให้มันร้อนแรงแค่ไหน",
"subtitle": "สุดท้ายมันก็มีวันที่ต้องดับ",
"footer": "iKL Studio",
"overlay": 58,
"text_position": "bottom_left",
"brand_position": "top_left",
"footer_position": "bottom_right"
}For pixel-based output, set the optional root-level output object:
{
"output": {
"width_px": 1920,
"height_px": 1080,
"dpi": 144
}
}The engine converts pixels to Typst page lengths during build:
page width in inches = width_px / dpi
page height in inches = height_px / dpi
For example, 1920x1080 at 144dpi becomes 13.333in x 7.5in.
Poster background images are resolved relative to the input JSON file and copied into the Typst work directory during build, so examples can keep images beside their content.json.
Poster background images can also be downloaded from online storage with background_image_url:
{
"background_image_url": "https://cdn.example.com/bg-poster-01.jpg"
}Rules for remote images:
- Use
https://only. - Use a direct image URL or signed URL that returns image bytes directly.
- Supported extensions:
.jpg,.jpeg,.png,.webp. - The response should have an
image/*content type. - Do not use preview pages such as ordinary Google Drive share pages unless they are direct-download image URLs.
Each poster can place its text, brand, and footer independently:
{
"text_position": "center_right",
"brand_position": "top_left",
"footer_position": "bottom_right"
}Supported position presets:
top_left, top_center, top_right
center_left, center, center_right
bottom_left, bottom_center, bottom_right
src/
cli.mjs
generate-slides-typst.mjs
generate-typst.mjs
render.mjs
validate.mjs
templates/
habit-workbook/
classic-textbook/
modern-classic-textbook/
modern-workbook/
quiet-power-slides/
examples/
habit-design/
layout-as-code-slides/
poster-design/
dist/
- v0.1: one schema, one template, PDF and PNG output
- v0.2: multiple templates and themes
- v0.3: slide deck generation and poster-style visual content
- v0.4: better diagnostics and visual QA helpers
- v0.5: multilingual layout support
- v0.6: template plugin API