A semantic document DSL for AI agents.
Teach agents to write with hierarchy, evidence, and structure — then render it as self-contained HTML.
When an AI agent writes a document, it faces two problems. First, the visual layer: agents reinvent CSS every time, producing inconsistent, unstyled output. Second, the writing layer: without structural guardrails, agents dump information linearly — the reader gets a wall of text instead of a scannable document with hierarchy.
Prism solves both by giving agents a vocabulary of 45 semantic components that encode both visual consistency and writing conventions.
The key insight is that the DSL is the rubric. A verdict belongs in a <p-decision>, not a sentence. A code reference belongs in a <p-source>, not a quoted snippet. A comparison belongs in <p-compare>, not a "pros and cons" list. Agents don't need to learn writing conventions — they pick from components that already enforce them.
Prism is opinionated, not exclusive. You can write your own <style> block in any template — for a one-off page, a specific brand moment, or just because. Prism components render with semantic class names you can override, and standard HTML stays standard HTML. Bring as much or as little of Prism as you want.
One command, no build step. The runtime is pre-built. The agent discovers the skill via SKILL.md and uses it automatically when you ask for structured documents.
npx skills add tommy0103/prism
npx skills add tommy0103/prism --global
The workflow is three steps: the agent writes a template containing only Vue component markup (no boilerplate HTML), the build script wraps it into a self-contained file, and the output opens in any browser with zero dependencies.
Step 1 — the agent writes a template. Here is a real example — a P0 bug report with a full reproduction trace collapsed behind the verdict:
<!-- lang: zh-CN -->
<p-decision status="rejected" verdict="P0">
<template #title>并发 refresh 导致合法用户 token 家族被撤销</template>
<p>影响所有多 tab 用户。两个 tab 同时刷新 token 时,第二个请求被误判为
token 盗用,导致整个 token 家族被撤销。</p>
</p-decision>
<p-collapse title="复现链路">
<p-source path="src/lib/refresh.ts:8-18" lang="TypeScript">
<pre><code>export async function rotateRefreshToken(token: string) {
const record = await db.refreshToken.findByHash(hash(token));
if (record.consumedAt) {
await db.refreshToken.revokeFamily(record.familyId);
throw new AuthError('token_reuse_detected');
}
// ...
}</code></pre>
</p-source>
</p-collapse>
Step 2 & 3 — build and open:
node prism/build.js template.html index.html
open index.html # No server. No deps. Just HTML.
git clone https://github.com/tommy0103/prism.git
cd prism
npx http-server . -p 3000
# Open http://localhost:3000/references/showcase.html
45 components across 8 families. Every component ships with a .md doc explaining when — and when not — to use it. The "when not to use" section is what separates Prism from a typical component library: it doesn't just give agents tools, it teaches them restraint.
p-decision — Verdict card with status
p-callout — Interruption block
p-compare — Pro / con side-by-side
p-contrast — Same word, different contexts
p-myth — Misconception → correction
p-analogy — Known ≈ unknown mapping
p-source — Expandable code block
p-ref — Inline reference chip
p-code — Code block with file header
p-copy — Copy-to-clipboard button
p-term — Inline term with tooltip
p-metrics + p-metric — Key numbers
p-bars + p-bar — Bar chart
p-stacked-bar — Proportional breakdown
p-flow — Architecture flow diagram
p-flow-node + p-flow-arrow
p-steps + p-step — Timeline
p-branch + p-branch-item — Decision tree
p-tracks + p-track — Parallel evaluation
p-finding — Observation in a track
p-evidence + p-evidence-item
p-checklist + p-check-item
p-file-list — File impact map
p-collapse + p-collapse-group
p-tabs + p-tab — Tab switcher
p-pages + p-page — Multi-page
p-grid — Column layout
p-card — Container
p-divider — Section divider
And the inline primitives that glue everything together: p-badge, p-tag, p-kv, p-params + p-param.
Beyond the component library, Prism bundles several document-level features that activate automatically — no configuration needed.
Every code block shows line numbers. <p-source path="auth.ts:42-48"> starts numbering at line 42.
Hover any code block to reveal a copy button. Line numbers are automatically stripped from the clipboard content.
Auto-generated from <h2> and <h3> headings. Click to jump, smooth scrolling, active section tracking.
Follows prefers-color-scheme automatically. Force a mode with PrismUI.setTheme('dark').
Syntax highlighting covers 14 languages: TypeScript, JavaScript, Rust, C/C++, Python, SQL, JSON, YAML, Bash, HTML/XML, CSS, and Diff.
Prism separates protocol (the DSL agents write) from visual (what it looks like). You can rebrand without changing how agents use it — the writing conventions stay, the look changes.
/* backgrounds */
--p-bg, --p-bg-secondary, --p-surface
/* text */
--p-text, --p-text-secondary, --p-text-light
/* semantic colors */
--p-accent, --p-success, --p-warning, --p-danger, --p-purple
/* borders */
--p-border, --p-divider
/* typography */
--p-font-display, --p-font-body, --p-font-mono
/* radii */
--p-radius, --p-radius-lg
Prism is intentionally small today — 45 components, one Notion-inspired theme, one build path. The plan is to grow the vocabulary, not the surface area.
themes/ as drop-in CSS files.
<p-glossary>, <p-changelog>, <p-spec>, <p-test-result>. Driven by real agent patterns in the wild.
Have a theme or component you want to see? Open an issue — Prism's direction is shaped by the documents agents are actually writing.
npm install
npm run build # Build dist/prism.iife.js
npm run dev # Watch mode
MIT © tommy0103