كاتب (kātib, "the writer") — the one who shapes words onto paper.
One skill, bilingual (EN + AR) print-grade PDF generation for Claude Code.
HTML + CSS → WeasyPrint → PDF. Component-composable, brand-aware,
shareable as .katib-pack tarballs.
# v1.0.0 stable
npx @jasemal/katib install
# Pin to the legacy v0 line
npx @jasemal/katib@0 installv1.0.0 is the current stable release. Pack format is frozen at
pack_format: 1— the share format is the public contract. Coming from v0.x? See MIGRATING.md.
| Current stable: | @jasemal/katib@1.0.0 on npm @latest — npx @jasemal/katib install |
| Legacy v0: | @jasemal/katib@0.20.0 on npm @0 — npx @jasemal/katib@0 install (pinned for any user who needs v0.x) |
| Migration guide: | MIGRATING.md — v0.x → v1.0.0 |
| Archived source: | v0 code under v1-reference/ (read-only) |
| Architecture notes: | See CHANGELOG.md for phase-by-phase design decisions |
| Component library | 45 components · 16 primitives, 28 sections, 1 cover |
| Starter recipes | 21 bilingual (EN + AR) across business, editorial, financial, formal, legal, personal, report, and tutorial domains |
| Pack format | pack_format: 1 frozen — see PACK-FORMAT.md |
| Marketplace | Coming next at katib.jneaimi.com (Phase 6) |
| Extending | Build new components with /katib component new — see COMPONENT-BUILDER.md or the tutorial |
An incident on 2026-04-23 surfaced an architectural limit in v1: per-doc-type monolithic HTML templates with hardcoded sample content couldn't grow without either corrupting the skill or adding doc-type entropy. v2 addresses this by separating templates from content entirely — components become the atomic unit of reuse, and doc-types become YAML recipes.
v2 key changes from v1:
- Component-first composition. Every visible element is a reusable component (primitives, sections, covers). Doc-types are YAML recipes that reference components by name.
- OS-standard output routing. v2 writes to the OS user-documents
directory (
~/Documents/katib/or$KATIB_OUTPUT_ROOT) on every install. File navigation belongs at a different layer. - Trilingual contract. EN / AR / bilingual — the third state supports side-by-side UAE contracts in a single PDF.
- Self-contained. No dependency on sibling Claude Code skills. The decision gate, content lint, context sensor all ship inside Katib.
- Four image sources. Components declare image slots; recipes pick from
user-file,screenshot,gemini, orinline-svgper invocation. - Enforced graduation. Adding new components and recipes goes through a CLI-driven workflow with build-time audit checks. Hand-editing the registry fails the skill load.
- User content survives reinstall. Your custom recipes, components,
and brand cover presets live under
~/.katib/, not in the skill dir.npx installnever overwrites them.
Fresh installs seed a curated set of starter recipes into
~/.katib/recipes/ — they're yours from that moment on. Edit them freely;
future npx install runs will never overwrite your edits.
-
Fresh install (
~/.katib/recipes/is empty) → 21 starter recipes are copied in, covering business, editorial, financial, formal, legal, personal, report, and tutorial domains. You can edit, delete, or fork them at will. -
Returning install (any recipe already in
~/.katib/recipes/) → the seed step is skipped entirely. Your changes survive. -
Bundled fallback — if you delete a starter, the bundled version in the skill folder takes over at resolve time. Nothing breaks.
-
Opt-in refresh — to pull a new starter after the manifest grows, or to restore a file you deleted:
uv run scripts/seed.py list # see what's available uv run scripts/seed.py refresh personal-cv # copy bundled → user if absent uv run scripts/seed.py refresh --all # every missing starter uv run scripts/seed.py refresh tutorial \ --force --justification "reset to ship defaults"
The manifest (seed-manifest.yaml at the repo root) is the single source of
truth for what gets seeded. This is the foundation for the Phase-4 share/import
flow — recipes that live under ~/.katib/ are the ones you'll be able to
package up and share with other Katib users.
| Domain | Starter recipes |
|---|---|
| Business | business-proposal-letter, business-proposal-one-pager, business-proposal-proposal |
| Editorial | editorial-article, editorial-white-paper |
| Financial | financial-invoice, financial-quote |
| Formal | formal-authority-letter, formal-noc |
| Legal | legal-mou, legal-nda, legal-service-agreement |
| Personal | personal-bio, personal-cover-letter, personal-cv |
| Report | report-progress |
| Tutorial | tutorial, tutorial-cheatsheet, tutorial-handoff, tutorial-how-to, tutorial-onboarding |
Need something we don't ship? Build it yourself with the AI-assisted builder — see TUTORIAL.md for a 20-minute walkthrough.
Wide tables, slide decks, full-bleed covers, multi-column essays, part dividers, and appendices all compose from dedicated layout components that handle the page-geometry work for you:
| Component | Use case |
|---|---|
landscape-section |
Wide data tables, horizontal timelines, wide charts |
slide-frame |
16:9 slide-deck pages with 4 variants (title / content / two-column / image-bg) |
full-bleed-page |
Edge-to-edge covers and hero images with optional overlay text |
two-column-page |
Newspaper / magazine editorial flow |
section-divider-page |
"Part II" style atomic dividers between major sections |
appendix-page |
Flowing appendix content with a running header in the top margin |
Katib separates bundled content (shipped with the skill) from user
content (yours, kept under ~/.katib/). Both tiers are searched at
resolve time, with user content silently shadowing bundled content of
the same name.
| Tier | Path | Written by |
|---|---|---|
| Bundled recipes | ~/.claude/skills/katib/recipes/ |
Skill install |
| Bundled components | ~/.claude/skills/katib/components/ |
Skill install |
| User recipes | ~/.katib/recipes/ |
katib recipe new |
| User components | ~/.katib/components/ |
katib component new --namespace user |
| Brand profiles + cover presets | ~/.katib/brands/ |
katib brand new, --save-cover-preset |
| Audit + gate logs | ~/.katib/memory/ |
Runtime |
uv run scripts/recipe.py new my-proposal --namespace user \
--description "Client proposal template"
# edit ~/.katib/recipes/my-proposal.yaml (sections, inputs, languages)
# render via /katib in Claude Code, or directly:
uv run scripts/build.py my-proposal --lang enPath A — AI-assisted builder (recommended). Invoke /katib component new
in Claude Code and Claude walks you through an interview, generates the
files, validates, renders a preview, and iterates on feedback. See
TUTORIAL.md for a full walkthrough or the
COMPONENT-BUILDER.md playbook for reference.
Path B — manual scaffold. If you'd rather hand-edit:
uv run scripts/component.py new client-hero --tier section \
--namespace user --languages en,ar \
--description "Full-width hero with brand lockup"
# edit ~/.katib/components/sections/client-hero/{en.html,ar.html,styles.css}
uv run scripts/component.py validate client-hero
uv run scripts/component.py test client-hero # renders EN + AR preview
uv run scripts/component.py register client-hero # update audit + capabilitiesReference it from a recipe exactly like a bundled component:
sections:
- component: client-hero # resolves user-tier first, bundled second
inputs:
headline: "Proposal for ACME"A user component or recipe with the same name as a bundled one silently
wins at resolve time — same pattern as local .env overriding shell
env vars. But scaffolding a user item that collides with a bundled
name is refused without --force --justification '<why>', so you can't
accidentally mask a shipped template.
For testing and CI isolation: KATIB_RECIPES_DIR, KATIB_COMPONENTS_DIR,
KATIB_BRANDS_DIR, KATIB_MEMORY_DIR redirect each user-tier path.
Custom recipes / components / brand profiles can be packaged into a
.katib-pack tarball and imported into another install:
# Pack a recipe + its custom dependencies
uv run scripts/pack.py export --bundle my-recipe
# Verify a pack you received
uv run scripts/pack.py verify my-recipe-1.0.0.katib-pack
# Install
uv run scripts/pack.py import my-recipe-1.0.0.katib-packPack format is frozen at pack_format: 1 — the schema is a public
contract. See PACK-FORMAT.md.
A curated marketplace at katib.jneaimi.com ships post-v1.0.0
(Phase 6). The same .katib-pack artifact will install via:
katib pack install jneaimi/financial-invoiceKATIB_REGISTRY_URL lets enterprises self-host their own registry.
@jasemal/katib@0.20.0 remains on the @0 dist-tag indefinitely; if
you've pinned to it, nothing breaks. To upgrade to v1.0.0 see
MIGRATING.md. New installs default to v1.0.0
(@latest).
| Phase | Status | Scope |
|---|---|---|
| 0 — Archive + ADR | ✅ shipped | v1 frozen in v1-reference/, ADRs approved, baseline measurements |
| 1 — Core engine + primitives | ✅ shipped | Composer, renderer, tokens, output routing, first 8 primitives |
| 2 — Sections + first recipe | ✅ shipped | Image-consuming sections, tutorial recipe, CLI subcommands, decision gate |
| 3a — Layout primitives | ✅ shipped | landscape-section, slide-frame, full-bleed-page, two-column-page, section-divider-page, appendix-page |
| 3b — AI-assisted component builder | ✅ shipped | COMPONENT-BUILDER.md playbook + /katib component new entry point |
| 3c — Content primitives | ✅ shipped | executive-summary, timeline, citation, references-list, toc, metric-block |
| 3d — Recipe migration | ✅ shipped | 6 new bilingual starters (legal-nda, legal-service-agreement, personal-bio, formal-authority-letter, report-progress, editorial-article) |
| 3e — Docs + tutorial | ✅ shipped | README polish, TUTORIAL.md, CHANGELOG, seed manifest expansion |
| 4 — Local share format | ✅ shipped | .katib-pack artifact + katib pack export/import/inspect/verify CLI; pack_format: 1 frozen |
| 5 — v1.0.0 release | ✅ shipped | Migration guide, format frozen, @latest moved from v0.20.0 → v1.0.0 |
| 6 — Marketplace MVP | next | Static landing at katib.jneaimi.com, curated registry, katib pack install <author>/<name> |
| 7 — Community uploads | future | Auth, signing, moderation, ratings — own ADR |
Not accepting external contributions during Phases 0–5. After v1.0.0 stable ships, Tier 2 (sections) and Tier 3 (recipes) will accept community PRs. Tier 1 primitives stay curated until v2.0. Phase 7 will open community uploads via the marketplace.
MIT — see LICENSE.
- npm:
@jasemal/katib - Issues: github.com/jneaimi/katib/issues
- Author: Jasem Al Neaimi