AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Kagen

skill-eliasoulkadi-shokunin-kagen · by EliasOulkadi

Convert Kami HTML templates to production-grade PDF via Chromium/Playwright. Complements Kami (design) with PDF rendering. Use when user asks to generate PDF files, render HTML to PDF, or export documents.

No reviews yet
0 installs
35 views
0.0% view→install

Install

$ agentstack add skill-eliasoulkadi-shokunin-kagen

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-eliasoulkadi-shokunin-kagen)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Kagen? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

kagen · 紙源

紙源 · かげん - paper source. PDF generation companion to Kami.

Kami designs, Kagen ships. Converts Kami HTML templates to production-grade PDF using Chromium (Playwright), bypassing WeasyPrint's Windows limitations.

Why Kagen

| Problem | Solution | |---------|----------| | WeasyPrint doesn't work on Windows (no GTK) | Kagen uses Playwright/Chromium — works everywhere | | WeasyPrint cold-start ~630ms per render | Playwright warm ~13ms per render | | WeasyPrint can't execute JS | Chromium renders fully (charts, dynamic content) | | wkhtmltopdf is deprecated and unmaintained | Playwright is actively maintained by Microsoft |

Based on benchmarks (pdf4.dev 2026), engineering discussions (HN, Stack Overflow, BrowserStack), and production experience from DocRaptor, customjs.space, and print-css.rocks.

Prerequisites

  • Node.js 20+
  • Playwright (npx playwright auto-installs on first use)
  • Chromium browser installed (npx playwright install chromium)
  • Kami HTML templates (any valid HTML with print CSS)

Quick start

npx playwright pdf "file:///path/to/doc.html" "output.pdf"

Or from Node.js:

const { chromium } = require('playwright');
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('file:///path/to/doc.html', { waitUntil: 'networkidle' });
await page.pdf({
  path: 'output.pdf',
  format: 'A4',
  printBackground: true,
  margin: { top: '0', bottom: '0', left: '0', right: '0' }
});
await browser.close();

Production settings (from professional research)

Page options

await page.pdf({
  path: 'output.pdf',
  format: 'A4',              // or 'Letter', 'A3'
  printBackground: true,     // always true — renders parchment bg
  margin: { top: '0', bottom: '0', left: '0', right: '0' },
  // For screen media (not print):
  // await page.emulateMedia({ media: 'screen' });
});

Critical CSS rules for reliable PDF output

/* Always include in your HTML template header */

@page {
  size: A4;
  margin: 24mm 26mm 26mm 26mm;
  background: #f5f4ed;
  widows: 4;
  orphans: 4;
}

/* Force background colors in Chromium */
* {
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

/* Avoid orphan text lines — high widows/orphans prevents single-line splits */
body { widows: 4; orphans: 4; }
p    { widows: 3; orphans: 3; }
li   { widows: 2; orphans: 2; }

/* Page break control — only on chapters with heavy content */
.chapter { }
.chapter.break { break-before: page; }

/* Never let a heading sit alone at page bottom */
h1, h2, h3, h4 { break-after: avoid; }

/* Keep these blocks intact — never split across pages */
table, pre, figure, .callout, .card,
blockquote, .finding-header, .takeaway {
  break-inside: avoid;
}

/* Avoid code blocks getting orphaned from their preceding paragraph */
pre {
  margin-top: 6pt;
  page-break-before: avoid;
}

/* Tables should not break rows across pages */
table tr {
  break-inside: avoid;
}

Visual patterns by document type

Each document type needs its own set of visual patterns. Apply accordingly:

| Type | Required patterns | Optional patterns | |------|----------------------|---------------------| | Pentest / Security report | Severity badges (red/orange/green), risk bar, code blocks with left border, impact/remediation boxes | Finding-header with metadata, findings table with badges | | One-pager / Executive summary | Glance grid (4 metrics), lead paragraph, takeaway box, cover with large title + decorative line | Callout for key data point, footer with contact | | White paper / Long doc | Chapter breaks in dense sections, table of contents, callouts, keep-together on critical blocks | Quotes, diagrams, appendix | | Letter | Wide margins (25mm), formal greeting and closing, no columns, no tables | Letterhead, signature | | Resume | Dense body (9.2pt), metric row, project bullets with action + result | Timeline, skills grid | | Slides | Assertion-evidence titles, one idea per slide, one-line bullets, pinned callout | Code cards, 2x2 table |

Rule: if the document type isn't in the table, choose the closest one and adapt.

Near-empty pages prevention

Nothing looks more amateur than a page with 2 lines. Causes and solutions:

| Cause | Solution | Auto-detection | |-------|----------|---------------------| | Heading with 1 short paragraph at the end | Merge with previous section | If a chapter has only 1 h2 + 1 p, it doesn't deserve its own page | | break-before: page on every section | Only use on chapters with >1/3 page of content | Count paragraphs + tables + lists. If they add up to less than 5 elements, don't force a break | | break-inside: avoid on large block that doesn't fit | Relax break-inside or split the block | If a keep-together measures more than 1 page, don't force it | | Source list at the end spilling onto a separate page | Move to consolidated sources chapter | Sources go in one place, not repeated in each chapter |

AI anti-patterns in documents

Validate that content inherited from Kami doesn't have these marks:

| Anti-pattern | Problem | Fix | |-------------|----------|-----| | Repeated em dash as label/value separator | Black Box — no credentials, multiple lines in a row | Parentheses, comma, colon. The dash is for genuine asides, not for separating labels | | Uniform tables without color | All rows identical, no visual indication of severity or priority | Color badges, subtle zebra rows, highlighted first column | | Code blocks without contrast | They blend with the body, don't look like code | Left blue border, ivory background, monospace, generous padding | | Same structure on every page | Every page is title + table or title + list | Vary: finding box, risk bar, flowchart, callout. Alternate rhythm | | Claims without source | "LLMs hallucinate 15-20%" without attribution | "According to Vectara HHEM 2026, LLMs..." |

Best practices from professionals

| Practice | Source | Why | |----------|--------|-----| | Always set printBackground: true | BrowserStack, Playwright docs | Kami uses parchment bg #f5f4ed — Chromium strips it by default | | Use file:// protocol | Stack Overflow, DocuPotion | Avoids auth/CORS issues with local files | | Set waitUntil: 'networkidle' | BrowserStack | Ensures fonts, CSS fully loaded | | Lock browser version in CI | BrowserStack, blog.rasc.ch | Chromium updates can change rendering | | Use @page margins, not Playwright margins | print-css.rocks, CSS Paged Media spec | CSS margins are more predictable for paged media | | -webkit-print-color-adjust: exact | MDN, Chromium docs | Critical for parchment backgrounds and brand colors | | Reuse browser instance (warm) | pdf4.dev benchmark | 42ms → 3ms speedup (14x) | | Validate PDF visually in CI | BrowserStack | Page count, whitespace, font check |

Warm mode (production pipeline)

const { chromium } = require('playwright');

class PDFRenderer {
  constructor() {
    this.browser = null;
  }

  async start() {
    this.browser = await chromium.launch();
  }

  async render(htmlPath, outputPath) {
    const page = await this.browser.newPage();
    await page.goto('file:///' + htmlPath.replace(/\\/g, '/'), {
      waitUntil: 'networkidle'
    });
    await page.pdf({
      path: outputPath,
      format: 'A4',
      printBackground: true,
      margin: { top: '0', bottom: '0', left: '0', right: '0' }
    });
    await page.close();
  }

  async stop() {
    await this.browser.close();
  }
}

Font embedding

Chromium embeds system fonts by default. For custom fonts (like TsangerJinKai02 in Kami):

@font-face {
  font-family: "CustomFont";
  src: url("fonts/CustomFont.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
}

Place font files relative to the HTML and use relative src paths. Chromium resolves them from the HTML file's directory.

Troubleshooting

| Problem | Fix | |---------|-----| | White background instead of parchment | Add printColorAdjust: exact in CSS and printBackground: true in JS | | Fonts not rendering | Use relative paths in @font-face, check font file exists | | Page breaks wrong | Check break-inside: avoid on tables, pre, callout | | Near-empty page (2 lines alone) | Merge short section with previous; avoid break-before: page on light chapters | | Content overflow | Use page-break-inside: avoid on large blocks | | Chinese chars as boxes | Include CJK font in @font-face or use system CJK fallback | | PDF too large | Remove unnecessary images, compress embedded fonts | | Slow first render | Keep browser instance alive (warm mode) |

CSS visual pattern snippets

Concrete patterns to include in the HTML by document type:

/* Severity badges (pentest, security) */
.badge-high { background: #f5e8e8; color: #a83030; display: inline-block; padding: 2pt 7pt; border-radius: 3pt; font-size: 8pt; font-weight: 500; text-transform: uppercase; }
.badge-medium { background: #f5ede2; color: #b86a25; display: inline-block; padding: 2pt 7pt; border-radius: 3pt; font-size: 8pt; font-weight: 500; text-transform: uppercase; }
.badge-ok { background: #e8f2ec; color: #2a7a4a; display: inline-block; padding: 2pt 7pt; border-radius: 3pt; font-size: 8pt; font-weight: 500; text-transform: uppercase; }

/* Risk bar (pentest exec summary) */
.risk-bar { display: flex; gap: 2pt; margin: 8pt 0 14pt 0; height: 12pt; }
.risk-bar .seg { border-radius: 2pt; display: flex; align-items: center; justify-content: center; font-size: 7pt; color: #fff; font-weight: 500; }

/* Code blocks with left border (pentest, technical) */
pre { border-left: 2.5pt solid #1B365D; border-radius: 3pt; background: #faf9f5; padding: 10pt 14pt; font-family: Consolas, monospace; font-size: 9pt; line-height: 1.5; break-inside: avoid; }

/* Impact/Remediation boxes (pentest) */
.impact-box, .remediation-box { border-left: 2pt solid #e8e6dc; padding-left: 12pt; margin: 10pt 0 14pt 0; break-inside: avoid; }
.impact-box .label, .remediation-box .label { font-size: 8.5pt; letter-spacing: 0.8pt; text-transform: uppercase; font-weight: 500; color: #1B365D; margin-bottom: 4pt; }

/* Cover accent line */
.cover-line { width: 60pt; height: 2pt; background: #1B365D; margin: 20pt 0; border-radius: 1pt; }

/* Pipeline flow (4 step horizontal) */
.pipeline-flow { display: flex; gap: 0; margin: 18pt 0; break-inside: avoid; }
.pipeline-step { flex: 1; text-align: center; padding: 10pt 8pt; }
.pipeline-step .dot { width: 6pt; height: 6pt; border-radius: 50%; background: #1B365D; margin: 0 auto 5pt auto; }
.pipeline-step + .pipeline-step { border-left: 0.5pt dotted #e8e6dc; }
.pipeline-step .name { font-size: 9pt; font-weight: 500; color: #141413; margin-bottom: 3pt; }
.pipeline-step .desc { font-size: 7.5pt; color: #6b6a64; line-height: 1.35; }

/* Keep-together wrapper */
.keep-together { break-inside: avoid; }

Self-review protocol (mandatory)

Don't generate the PDF without passing this checklist. Each item is a real failure documented in previous iterations.

Structural (blocking)

  • [ ] Each chapter has enough content to fill >1/3 of a page
  • [ ] No sections with just heading + 1 short paragraph (merge)
  • [ ] No near-empty pages (2 lines alone)
  • [ ] break-before: page only on chapters with dense content

Visual (high priority)

  • [ ] Visual elements match the document type (badges, risk bars, code blocks, etc.)
  • [ ] Tables have proper styling (optional zebra, padding, clear headers)
  • [ ] Code blocks are distinguishable from body (border, background, monospace)
  • [ ] No repeated em dashes used as label/value separators
  • [ ] There's variety in visual rhythm (not all pages the same)

Content (high priority)

  • [ ] Every categorical claim has its visible source ("according to X...")
  • [ ] Internal methodology is distinguished from verified fact (disclaimer if applicable)
  • [ ] No redundant content between chapters (sources, repeated lists)
  • [ ] Every paragraph is necessary (if it can be removed without loss, remove it)

Technical (blocking)

  • [ ] printBackground: true in Playwright configuration
  • [ ] -webkit-print-color-adjust: exact in CSS
  • [ ] widows: 4; orphans: 4 in @page and body
  • [ ] break-inside: avoid on pre, table, blockquote, callout
  • [ ] table tr { break-inside: avoid } so tables don't split rows

Complete HTML example

Minimum functional template that includes all essential patterns. Copy and adapt:


Document Title

  @page { size: A4; margin: 24mm 26mm 26mm 26mm; background: #f5f4ed; widows: 4; orphans: 4; }
  * { box-sizing: border-box; margin: 0; padding: 0; -webkit-print-color-adjust: exact; }
  :root {
    --parchment: #f5f4ed; --ivory: #faf9f5; --near-black: #141413;
    --dark-warm: #3d3d3a; --olive: #504e49; --stone: #6b6a64;
    --brand: #1B365D; --border: #e8e6dc; --border-soft: #e5e3d8;
    --serif: Charter, Georgia, Palatino, "Times New Roman", serif;
    --mono: Consolas, "Courier New", monospace;
  }
  body { font-family: var(--serif); font-size: 10.5pt; line-height: 1.65; color: var(--near-black); background: var(--parchment); widows: 4; orphans: 4; }
  h1 { font-size: 24pt; border-left: 2.5pt solid var(--brand); padding-left: 8pt; margin: 0 0 10pt 0; break-after: avoid; }
  h2 { font-size: 16pt; margin: 24pt 0 8pt 0; break-after: avoid; }
  p { margin: 0 0 10pt 0; widows: 3; orphans: 3; }
  table { width: 100%; border-collapse: collapse; font-size: 9.5pt; margin: 12pt 0; break-inside: avoid; }
  table th { text-align: left; padding: 6pt 8pt; border-bottom: 1pt solid var(--border); background: var(--ivory); }
  table td { padding: 5pt 8pt; border-bottom: 0.3pt solid var(--border-soft); }
  table tr { break-inside: avoid; }
  pre { border-left: 2.5pt solid var(--brand); border-radius: 3pt; background: var(--ivory); padding: 10pt 14pt; font-size: 9pt; font-family: var(--mono); break-inside: avoid; margin: 6pt 0 10pt 0; }
  .callout { background: var(--ivory); border-left: 2pt solid var(--brand); padding: 10pt 14pt; border-radius: 3pt; margin: 12pt 0; break-inside: avoid; }
  .keep-together { break-inside: avoid; }
  .break { break-before: page; }
  /* Add visual patterns by document type (badges, risk bar, etc.) */

  
    Document Type
    Main Title
    
    Subtitle or description
  
  Author · Date

  Chapter Title
  Document content. Verify sources (research), humanize text (humanize), design with Kami.
  

Integration with Kami

# One-liner from Kami HTML to PDF
npx playwright pdf "file:///path/to/kami-output.html" "final.pdf"

Sources

Workflow

Step 1: Validate HTML template

Before rendering, verify the template is production-ready:

  1. Open the HTML in a browser first: confirm fonts load, CSS applies, layout renders correctly at print size
  2. Check that @page rules specify explicit size (A4, Letter) and margins
  3. Verify -webkit-print-color-adjust: exact and print-color-adjust: exact are set on *
  4. Confirm all @font-face declarations use relative paths, not absolute filesystem paths

Step 2: Configure render settings

  1. Set format (A4, Letter, A3) to match the template's `@pag

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.