Architecture
How Chiltepin is built — a pure core library, with everything else as a consumer of it.
This page is for the curious and for contributors. You don't need it to use Chiltepin. The full version lives in ARCHITECTURE.md in the repo.
The one principle
The files on disk are the only source of truth. The CLI, the studio,
and AI agents are all just editors and consumers of your
.md files — none of them owns any state. The core library turns files into
a validated model; everything else consumes that model.
The packages
Chiltepin is a monorepo where every dependency points inward to a pure core:
chiltepin-core ← pure: parse, the block registry, Zod schemas, terse grammars, diagnostics, edit ops. No I/O.
chiltepin-render ← core. Deterministic renderers; HTML + SVG strings, one editorial skin. No DOM.
chiltepin-studio ← core + render, bundled. The browser editor, shipped as static assets.
chiltepin ← everything above. The chiltepin CLI. The only layer that owns process.exit.
skills/chiltepin ← the agent skill: a short decision path plus selection sheets per family.The rules:
chiltepin-coredoes no I/O — no file system, no network, no DOM. Strings in, models and diagnostics out.- Libraries return diagnostics as values; they don't throw for expected problems. Only the CLI turns diagnostics into console output and exit codes.
- Geometry is code, never prompt. If a fix tempts you to teach the model coordinates, the fix belongs in the renderer.
The block registry
Every block type is registered in one place in chiltepin-core:
export const blockSchemas = {
meta, callout, table, sequence, erd, userstory, timeline, kanban,
// … one entry per block type.
} as const satisfies Record<BlockType, ZodTypeAny>;Renderers use the same Record<BlockType, …> pattern, so the TypeScript
compiler points at every place that needs updating. A block type exists only
when it has a schema, a renderer, a skill entry, a catalog example, and a
test — all of them do. chiltepin block <type> is generated from the
schema, so the reference an agent reads cannot drift from the validator.
Rendering
chiltepin-render emits self-contained HTML: styles are scoped under one
class, SVG diagrams use integer coordinates so output is deterministic, and
the colour scheme is a token set — dark on bare :root, light on
data-theme="light" and in print — which is why one colorScheme key
recolours everything.
The studio
The studio runs the whole parse → validate → render pipeline in the
browser. The chiltepin studio server is only a small file bridge (localhost
JSON read/write plus change events) — it never renders anything itself.
Edits go through the core's edit operations, which rewrite individual blocks
in place, keeping diffs small.
Quality
Strict TypeScript throughout, 2,400+ tests, an accessibility audit in CI, and every published example on this site is rendered by the real pipeline at build time — the docs can't drift from the code.