Source profileQuality 93/100Review permissions

typeclaw/typeclaw/src/bundled-plugins/doc-render/skills/typeclaw-render-pdf/SKILL.md

typeclaw-render-pdf

The ONLY supported way to render Markdown into a polished, professional PDF (and optionally attach it to a channel). Load this whenever you need to deliver a document as a PDF rather than raw markdown — reports, summaries, briefs, meeting notes, docs, render report, export document, anything a human would want to download, print, or forward, including a researcher's report file shipped as a Slack/Discord attachment. Triggers: 'make a PDF', 'export to PDF', 'markdown to PDF', 'PDF report', 'rende

Source repository stars
57
Declared platforms
0
Static risk flags
2
Last source update
2026-08-26
Source checked
2026-08-26

Decision brief

What it does: where it fits

You can produce professional PDFs from Markdown. The bundled doc-render plugin ships two things: a themed report library (lib.typ) that does all the styling, and a render script that does the compile. The only thing installed on demand is the Typst compiler — a single npm packag…

Best for

  • A research report, brief, or summary the user wants as a downloadable file.
  • A subagent (e.g. the researcher) handed you a research-.md to ship as a PDF.
  • Any channel message asking for "a PDF" / "the report attached" / "예쁘게 PDF로".

Not for

  • Don't hand-write a styling wrapper. Use show: report.with(theme: …) from
  • Don't import lib.typ by absolute path — copy it next to the markdown

Compatibility matrix

Platform support, with evidence labels

PlatformStatusEvidenceWhat to check
CodexNot declaredNo explicit evidencePortability before use
Claude CodeNot declaredNo explicit evidencePortability before use
CursorNot declaredNo explicit evidencePortability before use
Gemini CLINot declaredNo explicit evidencePortability before use
Open the compatibility checker

Installation

Inspect first. Install second.

The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

Source-detected install commandSource
npx skills add https://github.com/typeclaw/typeclaw --skill "src/bundled-plugins/doc-render/skills/typeclaw-render-pdf"
Safe inspection promptEditorial

Inspect the Agent Skill "typeclaw-render-pdf" from https://github.com/typeclaw/typeclaw/blob/e525119cd01aad6b88f905daa7f532bd8ca84acd/src/bundled-plugins/doc-render/skills/typeclaw-render-pdf/SKILL.md at commit e525119cd01aad6b88f905daa7f532bd8ca84acd. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

Workflow

What the source asks the agent to do

  1. 01

    Step 0 — install the Typst compiler (once per session)

    The PDF compiler is not baked into the image — install it on first use. It is a single version-pinned npm package (npm pulls only this platform's prebuilt binary — Linux x64/arm64, glibc or musl). Install it in the session's writable /tmp runtime; the agent-root dependency tree…

    The PDF compiler is not baked into the image — install it on first use. It is a single version-pinned npm package (npm pulls only this platform's prebuilt binary — Linux x64/arm64, glibc or musl). Install it in the sess…The @0.7.0 pin embeds Typst 0.14.2 and keeps the toolchain reproducible. If you forget this step, the render script in Step 3 stops with the exact bun add line to run, so you can also just try the render and follow its…Where it goes: /tmp/typeclaw-doc-render-runtime, backed by TypeClaw's per-session scratch directory. It is writable to model-driven bash and reused across calls in the same session, but not promised across container res…
  2. 02

    Step 1 — have the markdown ready

    Use an existing markdown file (yours or a subagent's), or write your content to a markdown file. Standard CommonMark plus tables and footnotes all work. Put the .md, the copied lib.typ, and the .typ wrapper (Step 2) in the same directory so the wrapper's relative read("...") and…

    Use an existing markdown file (yours or a subagent's), or write your content to a markdown file. Standard CommonMark plus tables and footnotes all work. Put the .md, the copied lib.typ, and the .typ wrapper (Step 2) in…
  3. 03

    Step 2 — pick a theme and write the wrapper

    First, copy the bundled theme library next to your markdown (Typst's workspace sandbox only resolves imports under the render's working directory, so the library must sit beside the wrapper — an absolute import from outside won't resolve):

    editorial — magazine look: a dedicated cover page, smallcaps trackedmodern — startup look: a bold bleed-bar masthead, accent-bar headings,report — data / consulting look: a cover page with a full accent band,
  4. 04

    Step 3 — render

    The render script is bundled with the plugin — you do not write it. It lives at /agent/nodemodules/typeclaw/src/bundled-plugins/doc-render/render.ts.

    The render script is bundled with the plugin — you do not write it. It lives at /agent/nodemodules/typeclaw/src/bundled-plugins/doc-render/render.ts.You should already be cd'd into the directory holding your .typ, .md, and the copied lib.typ (from Step 2). The wrapper's read("report.md") and import "lib.typ" both resolve relative to the render's working directory, s…On success it prints wrote report.pdf ( bytes) and report.pdf exists in that directory.
  5. 05

    Step 4 — deliver

    Use a human-friendly filename and an absolute path. Slack, Discord, Telegram, and KakaoTalk upload the file; LINE and the GitHub adapter have no attachment support, so there post a link or paste the markdown.

    Channel asked for the PDF — attach it:Replying in a thread — use channelreply with the same attachments shape.No channel (TUI session) — just report the path: report.pdf.

Permission review

Static risk signals and limitations

Runs scripts

medium · line 14

The documentation asks the agent to run terminal commands or scripts.

4-line wrapper that picks a **theme**, **(4)** run the render script. If a channel

Runs scripts

medium · line 52

The documentation asks the agent to run terminal commands or scripts.

bun add @myriaddreamin/[email protected]

Writes files

medium · line 243

The documentation asks the agent to create, modify, or delete local files.

Only after the user agrees: edit `typeclaw.json` to set `docker.file.cjkFonts:

Evidence record

Why each signal appears

EvidenceSourceComputedTestedEditorial
SignalValueEvidence typeMeaning
Quality score93/100ComputedDocumentation, specificity, maintenance, and trust rules
Repository stars57SourceRepository attention, not individual Skill quality
Compatibility0 platformsSourceDeclared in the catalog source record
Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

Pinned source

Provenance and original SKILL.md

Repository
typeclaw/typeclaw
Skill path
src/bundled-plugins/doc-render/skills/typeclaw-render-pdf/SKILL.md
Commit
e525119cd01aad6b88f905daa7f532bd8ca84acd
License
MIT
Collected
2026-08-26
Default branch
main
View the original SKILL.md

typeclaw-render-pdf

You can produce professional PDFs from Markdown. The bundled doc-render plugin ships two things: a themed report library (lib.typ) that does all the styling, and a render script that does the compile. The only thing installed on demand is the Typst compiler — a single npm package the agent bun adds into writable session scratch the first time you need a PDF, then reuses for that session. No Pandoc, no LaTeX, no headless browser, no PDF toolchain baked into the image.

The flow is: (1) install the compiler once (bun add), (2) have your Markdown ready, (3) copy the theme library next to it and write a tiny 4-line wrapper that picks a theme, (4) run the render script. If a channel asked for the PDF, attach the result with channel_send.

You do not write Typst markup or hand-style anything. The library's report template styles every Markdown element — headings, lists, tables, code, quotes, links, figures — and adds a cover, running header, and page footer. The cmarker package converts your CommonMark to Typst; the theme makes it look designed. Your only real choice is which theme fits the document.

This is the only supported way to make a PDF from Markdown in TypeClaw. Do not reach for jsPDF, pdfkit, a <canvas> text dump, a headless-browser "print raw text" path, or Python ReportLab. Those skip Markdown rendering (you get literal ## and ** in the output) and ship no CJK font, so Korean/Japanese/Chinese come out as mojibake. The Typst path below renders the Markdown properly. If you catch yourself about to bun add a PDF library other than the Typst compiler named here, stop.

When to use this

  • A research report, brief, or summary the user wants as a downloadable file.
  • A subagent (e.g. the researcher) handed you a research-<slug>.md to ship as a PDF.
  • Any channel message asking for "a PDF" / "the report attached" / "예쁘게 PDF로".
  • Anyone complaining a previous PDF looked "plain" — switch theme and/or follow the design tips below; do not hand-roll a new styling system.

When plain markdown in chat is fine, don't make a PDF. This is for when a file is the deliverable.

Step 0 — install the Typst compiler (once per session)

The PDF compiler is not baked into the image — install it on first use. It is a single version-pinned npm package (npm pulls only this platform's prebuilt binary — Linux x64/arm64, glibc or musl). Install it in the session's writable /tmp runtime; the agent-root dependency tree is protected read-only:

mkdir -p /tmp/typeclaw-doc-render-runtime && cd /tmp/typeclaw-doc-render-runtime
bun add @myriaddreamin/[email protected]

The @0.7.0 pin embeds Typst 0.14.2 and keeps the toolchain reproducible. If you forget this step, the render script in Step 3 stops with the exact bun add line to run, so you can also just try the render and follow its guidance.

Where it goes: /tmp/typeclaw-doc-render-runtime, backed by TypeClaw's per-session scratch directory. It is writable to model-driven bash and reused across calls in the same session, but not promised across container restarts. Do not modify /agent/node_modules or create a dependency tree under workspace/.

Step 1 — have the markdown ready

Use an existing markdown file (yours or a subagent's), or write your content to a markdown file. Standard CommonMark plus tables and footnotes all work. Put the .md, the copied lib.typ, and the .typ wrapper (Step 2) in the same directory so the wrapper's relative read("...") and #import "lib.typ" both resolve. Any agent-writable directory works (workspace/, public/, mounts/, or wherever the source .md already lives, e.g. a researcher's report under public/). There is no required directory; keep the three files together and run the render from there.

Step 2 — pick a theme and write the wrapper

First, copy the bundled theme library next to your markdown (Typst's workspace sandbox only resolves imports under the render's working directory, so the library must sit beside the wrapper — an absolute import from outside won't resolve):

cd /agent/workspace            # or wherever your .md lives (public/, mounts/, …)
cp /agent/node_modules/typeclaw/src/bundled-plugins/doc-render/templates/lib.typ .

Then write a tiny .typ wrapper next to the markdown. This is the entire wrapper — you do not style anything yourself; the theme does it:

#import "lib.typ": report, callout, kpi, kpi-row, pullquote
#show: report.with(
  theme: "editorial",                       // editorial | modern | report | minimal
  title: "Edge-AI Quarterly Brief",
  subtitle: "Q2 2026 · Internal Distribution",
  date: "2026-06-17",
  author: "Research",
)
#import "@preview/cmarker:0.1.8"
#cmarker.render(
  read("report.md"),
  h1-level: 1,
  blockquote: quote.with(block: true),
  // makes the helpers available to <!--raw-typst …--> snippets in the markdown
  scope: (callout: callout, kpi: kpi, kpi-row: kpi-row, pullquote: pullquote),
)

Choosing the theme

Pick the one that fits the document's purpose. All four are built on the fonts that ship in the container, so they render identically everywhere.

  • editorial — magazine look: a dedicated cover page, smallcaps tracked headings, booktabs tables, wine accent. The elegant default for prose: reports, briefs, memos, articles.
  • modern — startup look: a bold bleed-bar masthead, accent-bar headings, airy ragged-right, indigo accent, accent-header tables. Product/launch briefs, updates, anything that should feel current.
  • report — data / consulting look: a cover page with a full accent band, accent-ruled section heads, strong navy zebra tables, plus kpi() and pullquote() helpers. Boardroom-ready analyses and data reports.
  • minimal — Apple-clean: a spacious title block, large light headings, no running header, generous margins, ultra-light tables. Short notes, letters, one-pagers.

When unsure, use editorial. If a user said the last PDF looked plain, try modern or report (the most visibly "designed") and apply the tips below.

Optional knobs

  • accent: rgb("#0f766e") — override the theme's accent color (links, rules, headings, cover, table headers). Omit or pass accent: auto for the theme default.
  • cover: "page" | "masthead" | "title" | none — override the cover treatment (page = dedicated cover page, masthead = bold top block, title = compact title block), or none to drop it (e.g. a short memo). Omit for the theme default.
  • Omit title entirely and no cover is drawn — useful when the markdown already opens with its own H1.

Step 3 — render

The render script is bundled with the plugin — you do not write it. It lives at /agent/node_modules/typeclaw/src/bundled-plugins/doc-render/render.ts.

You should already be cd'd into the directory holding your .typ, .md, and the copied lib.typ (from Step 2). The wrapper's read("report.md") and #import "lib.typ" both resolve relative to the render's working directory, so you must run it from there:

cd /agent/workspace            # or wherever your .typ + .md + lib.typ live
bun run /agent/node_modules/typeclaw/src/bundled-plugins/doc-render/render.ts report.typ report.pdf

On success it prints wrote report.pdf (<N> bytes) and report.pdf exists in that directory.

If it stops with @myriaddreamin/typst-ts-node-compiler is not installed (exit 3), run the Step 0 bun add and re-run. If it stops with a NotDir / ENOTDIR error, that is the sandbox /proc degraded mode, not your markup and not a font — retry once; if it persists, report it as a sandbox/environment issue and do not switch to another PDF library (it won't help). Any other error is a real Typst compile error (usually raw HTML or an unsupported markdown extension) and names the offending line — simplify that part and re-run.

Make it genuinely beautiful (design tips)

A theme gets you 90% of the way. The rest is content discipline — the same things that separate a designed document from a markdown dump:

  • Front-load structure. A short lead paragraph under the title, then clear ## sections. Don't open with a wall of text.

  • Tables over repeated bullet stanzas. If you're repeating the same fields per item (name, value, status…), a table reads far better than N bullet lists. The theme styles tables with clean rules and a header row.

  • Caption your images so they read as figures, not floating screenshots:

    <!--raw-typst
    #figure(image("chart.png", width: 80%), caption: [Revenue trend, Q1–Q2 2026.])
    -->
    

    Images default to a sensible max width; keep them to one strong figure per idea rather than many raw dumps at random sizes.

  • Use callouts for what matters — a risk, a key result, a caveat — instead of bolding a whole paragraph. callout is exported by the library (pass it via scope: as shown above), then used inside the markdown:

    <!--raw-typst
    #callout(kind: "warning", title: "Risk")[A single supplier covers 40% of NPUs.]
    #callout(kind: "success")[Revenue grew 31% YoY, ahead of plan.]
    -->
    

    Kinds: note, tip, success, warning, danger. Keep them rare — two or three in a document read as deliberate; a wall of colored boxes reads as noise.

  • Lead with the numbers (data reports). For a metrics-heavy document, open a section with a row of KPI cards instead of burying figures in prose. kpi and kpi-row are exported by the library (pass them via scope: as shown above):

    <!--raw-typst
    #kpi-row(
      kpi("$5.5M", "Revenue", sub: "+31% YoY"),
      kpi("124%", "Net retention", sub: "+6pt"),
      kpi("63.4%", "Gross margin", sub: "+240bp"),
    )
    -->
    

    Use pullquote("…", by: "…") for a centered featured quote between sections.

  • Let whitespace breathe, but don't pad. Trust the theme's rhythm; don't add manual #v(...) spacers around everything.

Handling CJK content

CJK fonts are opt-in (the docker.file.cjkFonts toggle). The themes already list Noto Serif CJK / Noto Sans Mono CJK as fallbacks, so Korean/Japanese/ Chinese resolve automatically when those fonts are present. When the toggle is off, Typst still renders — it just substitutes .notdef tofu (□) boxes for every CJK glyph. Do not download, vendor, or curl a font to work around this, and do not silently deliver a tofu PDF.

You don't need a pre-render gate: render first, then verify. If the source markdown contains CJK and the resulting PDF shows tofu boxes (or you know CJK fonts aren't enabled on this container), tell the user honestly and offer the fix:

This report has Korean/Japanese/Chinese text but the container has no CJK font — they're opt-in, so the PDF comes out as tofu boxes. Want me to set docker.file.cjkFonts: true in typeclaw.json? It's a boot setting, so after I edit it you'll run typeclaw restart from the host project directory, and then I'll regenerate the PDF.

Only after the user agrees: edit typeclaw.json to set docker.file.cjkFonts: true (use the typeclaw-config skill), ask them to typeclaw restart, and regenerate the PDF after the restarted container comes back. If the markdown has no CJK, this section doesn't apply.

Rendering an existing web page or HTML to PDF

This skill renders markdown you author. To capture an existing web page or a live URL as a PDF — something Typst cannot do — use the already-installed agent-browser (Chrome): agent-browser --allow-file-access open file:///agent/workspace/page.html (or a URL), then agent-browser pdf /agent/workspace/out.pdf. Its output is fixed US-Letter with default margins, so it's the right tool for archiving web content, not for authoring styled reports. For authored documents, stay on the Typst path above.

Step 4 — deliver

  • Channel asked for the PDF — attach it:

    channel_send(text: "Here's the report.", attachments: [{ path: "/agent/workspace/report.pdf", filename: "Edge-AI-Brief.pdf" }])
    

    Use a human-friendly filename and an absolute path. Slack, Discord, Telegram, and KakaoTalk upload the file; LINE and the GitHub adapter have no attachment support, so there post a link or paste the markdown.

  • Replying in a thread — use channel_reply with the same attachments shape.

  • No channel (TUI session) — just report the path: report.pdf.

If you got the markdown from a subagent

The researcher subagent writes its report to research-<slug>.md and returns a <report> block naming the file. Copy lib.typ into that file's directory, point the wrapper's read(...) at the report, render there, and attach. You do the PDF step — the researcher's bash is read-only and it only emits markdown by design.

Customizing this skill

This is a bundled default. Want a fifth theme, a cover page with a logo, or a house style? Two options: (a) copy lib.typ into the document directory and edit your local copy before rendering (one-off), or (b) for a durable change, copy this file to .agents/skills/<your-name>/SKILL.md (use a different name; bundled skills win name collisions) and point it at your own theme library.

Known limitations

cmarker covers CommonMark well, but a few markdown features don't render as you might expect:

  • Task-list checkboxes (- [ ] / - [x]) render as literal [ ] text, not checkboxes. Use a plain bullet list or a status column in a table instead.
  • Bold/italic directly adjacent to CJK + parenthetical Latin (e.g. **로컬 우선(local-first)**) may not be recognized as emphasis — CommonMark's flanking rules treat that boundary as non-emphasis. Put a space inside, or bold a pure run of text.
  • Raw HTML in the markdown is mostly ignored. Express structure in markdown (tables, lists) rather than HTML.

Don'ts

  • Don't hand-write a styling wrapper. Use #show: report.with(theme: …) from the bundled library; only reach for raw Typst (via <!--raw-typst … -->) for the occasional figure or callout.
  • Don't import lib.typ by absolute path — copy it next to the markdown first (Typst's workspace sandbox won't resolve an import from outside the render's working directory).
  • Don't build a package.json / node_modules / a render script under workspace/ or modify the protected agent-root dependencies. The compiler installs in /tmp/typeclaw-doc-render-runtime; the render script and theme library are bundled with the plugin (under /agent/node_modules/typeclaw/src/bundled-plugins/doc-render/).
  • Don't attach a PDF to a GitHub channel — that adapter rejects attachments. Link or inline instead.

Frequently asked questions

What to verify before installation and use

What does the typeclaw-render-pdf source document cover?

You can produce professional PDFs from Markdown. The bundled doc-render plugin ships two things: a themed report library (lib.typ) that does all the styling, and a render script that does the compile. The only thing installed on demand is the Typst compiler — a single npm packag…

How do I install typeclaw-render-pdf?

The source record exposes this install command: npx skills add https://github.com/typeclaw/typeclaw --skill "src/bundled-plugins/doc-render/skills/typeclaw-render-pdf". Inspect the command and pinned source before running it.

Which permission-related actions were detected?

Static rules flagged exec-script, write-files in the source; the page lists the matching lines and excerpts.

Alternatives

Compare before choosing

Computed 9916

NintendaDev/unikit-ai

unikit-docs

Generate and maintain the project's TECHNICAL documentation from its codebase — scans the project structure, tech stack, and module boundaries, then writes a lean README landing page plus detailed topic pages (architecture, modules, setup, build, APIs), only the docs that are relevant. Use whenever the user wants to create, update, or validate documentation of the CODE or the project itself, e.g. "generate documentation", "create docs", "write the README", "update the project docs", "document th

Computed 9817

eugenelim/agent-ready-repo

work-loop

Use when implementing or resuming a non-trivial repository change: a feature, behavior-changing fix, refactor, migration, framework or dependency upgrade, schema or API change, performance work, infrastructure or build-system change, reversion, or an existing build spec under `docs/specs/`. Also use for bare continuation commands ('resume', 'continue', 'keep going', 'pick up where I left off', 'let's get going') when conversation or workspace context identifies active build work. Do not use for

Computed 9741

objectstack-ai/objectstack

objectstack-ui

Author ObjectStack UI metadata — Views (list/form/kanban/calendar/gantt), Apps (navigation), Pages (structured plus the HTML and React source-authoring tiers, ADR-0080/0081), Dashboards, Reports, Charts, Actions, and package Docs (`src/docs/*.md`). Use when the user is adding `*.view.ts` / `*.app.ts` / `*.dashboard.ts` / `*.action.ts` / `src/docs/*.md` files or designing a Studio-rendered UI surface, including dataset-bound dashboard/report widgets. Do not use for: data schema (see objectstack-d

Computed 976

mgiovani/cc-arsenal

team-review

Multi-agent review team: architecture, security, performance, testing, style, docs/UX, plus an adversary that cross-examines the other 6, for security-sensitive, architectural, or large PRs (15+ files) where a single-agent pass risks missing cross-cutting issues. Use for auth/payments/PII changes, schema/pattern changes, compliance sign-off, or when asked to 'get the review team on this' / 'multi-agent review' / 'thorough review before merge'. For a standard PR or a quick pre-merge check, use /r