Hyperscribe
Hyperscribe turns an A2UI-style JSON envelope into a single, self-contained HTML file. You — the model — emit semantic data only, never HTML, CSS, or styling decisions. A zero-dependency Node renderer handles presentation. The file opens offline in any browser with no build step.
Use this skill when a visual explanation would be clearer than terminal text. Prefer Hyperscribe over hand-written HTML, Mermaid fences in chat, or ASCII tables whenever the reader will benefit from structure or interactivity.
When to use
Use Hyperscribe when any of these hold:
- The user asks for a diagram, flowchart, architecture, process view, slide deck, comparison, or visual explainer.
- You are about to render a markdown table with 4+ rows OR 3+ columns in a chat reply — render a instead.
- You are about to render ASCII art of a system, flow, or state machine — use or instead.
- The user asks for a "slide deck", "presentation", "recap", or "summary with sections".
- Reviewing a PR / diff and a before-after view plus impacted-module map would help — use .
- The user wants to share a result with others — render then call .
Do not use Hyperscribe when:
- The answer is one or two sentences.
- The user explicitly asks to stay in the terminal.
- The task is pure code editing with no explanation artifact needed.
Step 0 — resolve the user's theme preference (always run first)
Before building any envelope, resolve the user's theme + mode. If no preference file exists yet, prompt once, save, then proceed. This runs on every invocation of the main skill and its variants.
bash
# 1. Resolve preference path: project-local first, then global.
PREF=""
for p in ./.hyperscribe/preference.md ~/.hyperscribe/preference.md; do
[ -f "$p" ] && { PREF="$p"; break; }
done
# 2. First run — prompt and save defaults to ~/.hyperscribe/preference.md
if [ -z "$PREF" ]; then
# Claude Code: ask via AskUserQuestion (theme 4-choice, mode 3-choice).
# Other agents: print the prompt below and wait for a single-line answer.
cat <<'PROMPT'
Hyperscribe first-run setup. Pick a theme and mode.
Themes: 1) studio (Airtable — clean enterprise canvas + Airtable Blue)
2) midnight (Cal.com — grayscale monochrome + Cal Sans display)
3) void (Bugatti — architectural black + 3-color discipline)
4) gallery (Apple — cinematic binary surfaces + SF Pro)
Modes: light / dark / auto
Reply with "<theme> <mode>" (e.g., "studio light"),
a single theme name (mode=light),
or "skip" to use studio + light.
PROMPT
# Parse the user's answer into $THEME and $MODE.
# If unparseable or empty, fall back to defaults silently.
THEME="studio"
MODE="light"
# (Agents with AskUserQuestion populate $THEME and $MODE from the structured answer.)
mkdir -p ~/.hyperscribe
PREF=~/.hyperscribe/preference.md
cat > "$PREF" <<EOF
---
theme: $THEME
mode: $MODE
created_at: $(date -u +%Y-%m-%dT%H:%M:%SZ)
---
# Hyperscribe preferences
Edit the values above to change your defaults. Delete this file to re-run
the first-run setup on the next hyperscribe invocation.
Valid values:
theme: studio | midnight | void | gallery
mode: light | dark | auto
EOF
fi
# 3. Read preference into env vars (every run)
THEME=$(awk -F': *' '/^theme:/{print $2; exit}' "$PREF")
MODE=$(awk -F': *' '/^mode:/{print $2; exit}' "$PREF")
[ -z "$THEME" ] && THEME=studio
[ -z "$MODE" ] && MODE=light
When invoking the renderer in later steps, always pass
and — when
is
or
—
. When
is
, omit
so the page follows
and localStorage at load time.
How to use
- Understand intent. Classify the request: (a) documentation page, (b) comparison/table, (c) slide deck, (d) diff review, (e) metrics/status page. The classification picks the root component and commands.
- Pick components. Consult for exact prop schemas and choose the smallest set that covers the content. Compose, don't reinvent — e.g. "overview + 3 modules + risks" = > > + .
- Build the envelope. Emit the A2UI JSON envelope (shape below). Every component node is
{ "component": "hyperscribe/X", "props": {...}, "children": [...] }
. must be (or in slides mode).
- Call the CLI. Pipe the JSON into the wrapper via Bash:
bash
HS=$(for p in \
./.claude/skills/hyperscribe ~/.claude/skills/hyperscribe \
./.codex/skills/hyperscribe ~/.codex/skills/hyperscribe \
./.cursor/skills/hyperscribe ~/.cursor/skills/hyperscribe \
./.opencode/skills/hyperscribe ~/.opencode/skills/hyperscribe \
~/.claude/plugins/cache/hyperscribe-marketplace/*/plugins/hyperscribe \
./plugins/hyperscribe
do [ -x "$p/scripts/hyperscribe" ] && { echo "$p/scripts/hyperscribe"; break; }; done)
MODE_FLAG=""
[ "$MODE" = "light" ] && MODE_FLAG="--mode light"
[ "$MODE" = "dark" ] && MODE_FLAG="--mode dark"
mkdir -p ~/.hyperscribe/out
echo '<json>' | "$HS" --theme "$THEME" $MODE_FLAG --out ~/.hyperscribe/out/<slug>.html
Omit to let the CLI write ~/.hyperscribe/out/<slug-from-title>-<timestamp>.html
and print the path.
- Open it for the user. On macOS: . On Linux: .
- Report the path. Reply with the absolute path and a one-line summary of what's inside. Don't dump the JSON back to the user.
Visualization planning
Before choosing components, make one fast pass over the content and decide what kind of visual this should be.
1. Classify the content
- Topology — systems, modules, services, ownership boundaries, dependencies.
- Flow — pipelines, request lifecycles, state changes, ordered handoffs.
- Comparison — options, before/after, trade-offs, audits, matrices.
- Evidence — metrics, tables, file inventories, code excerpts.
- Narrative — recap, walkthrough, phased explanation, summary for humans.
Most useful pages mix 2-3 of these, but one should dominate.
2. Pick the dominant visual surface first
- Use when card content matters more than exact edge routing.
- Use as the compatibility fallback for diagram types the native catalog does not cover.
- Use for actor-message timelines and request/response traces.
- Use for simple pipelines with ranked stages and explicit decisions.
- Use when the same process must be grouped by role, team, service, or lane.
- Use for 2x2 prioritization, risk, or positioning matrices.
- Use or when the user needs side-by-side evaluation rather than a diagram.
- Use only when the numbers themselves carry the point; do not chart tiny or mostly categorical data just to make the page feel visual.
- Use when sequence matters but a diagram would add noise.
2.1 Resolve close calls
| If deciding between | Prefer this | When |
|---|
| vs | | Actors exchange messages over time. |
| vs | | Work moves across lanes and ownership is the point. |
| vs | | The stages are ordered and lane ownership is secondary. |
| vs | | The user needs module/service shape, responsibilities, or boundaries. |
| vs | | The user needs a pipeline, decision path, or lifecycle. |
| vs | | Options need bullets, trade-offs, or verdicts. |
| vs | | Positioning on two axes is the main message. |
| vs | | Exact values, labels, or rows matter. |
| vs | | Shape, trend, or magnitude is the main point. |
| vs | | Specific lines need explanation. |
| vs | | The change itself is the point. |
3. Compose around that surface
Prefer these page recipes:
- Architecture explainer:
-> overview with or -> supporting , , , , or
- Process walkthrough:
-> summary -> or -> -> for failure modes or decisions
- Comparison / decision memo:
-> framing -> or -> recommendation -> optional
- Code / diff explainer:
-> architecture or flow context -> / / -> risks -> next actions
- Repo / system recap:
-> short summary -> one dominant diagram -> one evidence block (, , , or )
For repo explainers, the first content section should usually be diagram-led, anchored by , , , or .
Use , , or as evidence surfaces instead of long explanatory prose.
4. Scale information density deliberately
- If the page has one key idea, use one dominant visual and keep supporting content sparse.
- If the page has multiple sections, each section should have one job: overview, topology, evidence, or next steps.
- If the content is dense, prefer multiple focused sections over one overloaded mega-diagram.
- If labels would become long paragraphs inside nodes, use + surrounding prose instead of forcing everything into .
- For repo explainers, architecture explainers, and system walkthroughs, use no more than 2 Prose blocks unless the user explicitly asks for a prose-heavy artifact.
- For repo explainers, include at least one of , , , , or as the dominant visual surface.
5. Avoid weak compositions
- Do not stack unrelated components just to show variety.
- Do not use both and for the same exact relationship unless they tell different stories.
- Do not use both and for the same exact process unless one shows messages and the other shows ownership.
- Do not open with a table when a diagram would explain the system faster.
- Do not open with long prose when the user asked for something visual.
- Do not use where a or would be more legible.
- Avoid as the dominant visual for repo explainers unless the source is explicitly about alternatives, trade-offs, or before/after states.
- Do not create a page where every section has equal visual weight; decide what the eye should land on first.
- Use inline code sparingly. Reserve backticks for real file paths, commands, identifiers, and schema keys.
- No more than 1-2 inline code spans per paragraph or list item. If a section needs many identifiers, switch to , , , or a diagram label instead.
- Do not wrap every tool, noun, or phrase in backticks just because it is technical.
The test: if you removed one component and the page got clearer, it probably did not belong there.
Envelope format
Canonical shape — always this exact structure:
json
{
"a2ui_version": "0.9",
"catalog": "hyperscribe/v1",
"is_task_complete": true,
"parts": [
{
"component": "hyperscribe/Page",
"props": { "title": "Auth Flow", "toc": true },
"children": [
{
"component": "hyperscribe/Section",
"props": { "id": "overview", "title": "Overview" },
"children": [
{ "component": "hyperscribe/Prose", "props": { "markdown": "..." } }
]
}
]
}
]
}
Rules:
- , , are required. is always .
- Exactly one element in . Its is (default) or (slide mode only). Multiple pages per envelope are not supported.
- Container components use . Leaf components omit .
- Any unknown component name or missing required prop fails validation with exit 2.
Component inventory
23 default components across 7 categories. See
for full prop schemas and examples.
and
are
slide-mode-only components owned by
. They are intentionally excluded from the default page-mode inventory below.
| Category | Component | Purpose |
|---|
| Structure | | Root container. Exactly one per envelope. Props: , , . |
| Structure | | Titled section with auto TOC anchor. Props: , , . |
| Structure | | In-section h2/h3/h4. Props: , , . |
| Structure | | Markdown paragraph block (CommonMark + GFM). Props: . |
| Media | | Inline image. accepts https:// URL (passthrough) or local path (base64 inlined). Props: , , , , . |
| Emphasis | | Boxed highlight. Props: (||||), , . |
| Emphasis | | Metric card with optional delta. Props: , , , . |
| Code | | Single snippet with optional line highlights. Props: , , , . |
| Code | | Before/after unified diff hunks. Props: , , . |
| Diagrams | | Mermaid.js diagram with zoom/pan. Props: , , . |
| Diagrams | | Native SVG sequence diagram (Notion-styled, no CDN). Props: , (kind: sync/async/return/self/note). Prefer over with for consistent design. |
| Diagrams | | Native SVG directed graph with box/pill/diamond nodes. Caller supplies (arrays of node ids) — no auto-layout. Props: (TD/LR), , , . Prefer over Mermaid flowchart for simple pipelines. |
| Diagrams | hyperscribe/ArchitectureGrid
| Card-based architecture with SVG connectors. Props: , , , . |
| Diagrams | | 2x2 prioritization matrix with plotted points. Props: , , , . |
| Diagrams | | Lane-based process diagram across roles on a shared sequence. Props: , , . |
| Data | | Semantic HTML table. Props: , , , , . |
| Data | | Chart.js wrapper. Props: , , , , . |
| Data | | N-way comparison. Props: , (|). |
| Narrative | | Ordered steps / checklist. Props: , . |
| Structure | | Directory/file structure. Props: (recursive), , . |
| Structure | | Per-file summary card. Props: , , , , , . |
| Code | hyperscribe/AnnotatedCode
| Code with pinned side annotations. Props: , , , . |
| Diagrams | | DB/type ERD. Props: , , . |
Slide mode only
| Category | Component | Purpose |
|---|
| Slides | | Slide container. Props: , , . Children: Slide[]. |
| Slides | | Single slide. Props: (|||||), , , , , . |
Semantic-only props — NEVER style
carries
data, not presentation. The renderer and
own every visual decision.
- Do not emit , , , , , , , , or any CSS-like prop.
- Do not pass inline HTML in markdown fields beyond what CommonMark/GFM allows. Script tags are stripped.
- Do not try to reorder the page with custom containers — use + hierarchy.
- Do not specify chart colors, table widths, or slide transitions as decoration. Pick the right component; trust the renderer.
If you find yourself reaching for a styling prop, the correct answer is usually a different component (e.g. use
instead of "red box", use
KPICard delta.direction="down"
instead of "red number").
Commands
| Command | Use when |
|---|
| General-purpose page. Default choice for diagrams, docs, tables, architectures, and metric summaries. |
| Slide deck mode. Forces root; extracts slides from a topic or outline. |
| Diff / PR review. Combines (impacted modules) + + (risks). |
| Deploys an existing HTML output to Vercel and returns a live URL. Input: path to a previously rendered file. |
Auto-trigger logic
Apply these rules proactively — do not wait for the user to say the word "Hyperscribe":
- Table auto-trigger. If you are about to emit a markdown/ASCII table in a chat reply with OR , switch to inside a minimal envelope.
- Diagram auto-trigger. If you are about to draw ASCII boxes-and-arrows of a system, pipeline, or state machine, emit (for actor-message diagrams), (flowchart / state / er / mindmap / class), or
hyperscribe/ArchitectureGrid
(for module/service topology). Prefer over with — it is native SVG with consistent Notion styling and no CDN.
- Slide auto-trigger. If the user says "slides", "deck", "presentation", "walk me through", or asks for a 5+ step recap, route through .
- Diff auto-trigger. If the user pastes output or a PR URL and asks for review, route through .
- Escape hatch. If the user explicitly asks to keep it in terminal ("just tell me", "don't open a browser"), skip Hyperscribe and reply in plain text.
Modeled after
nicobailon/visual-explainer
's proactive-rendering behavior, but emitting semantic JSON instead of raw HTML.
Error handling
The CLI validates before rendering. Exit codes:
| Code | Meaning |
|---|
| 0 | Success |
| 1 | JSON parse error |
| 2 | Schema validation failure (stderr lists per error) |
| 3 | IO error (cannot write output) |
| 4 | Render runtime error (partial fragment saved to ) |
On exit 2, read stderr, diagnose, retry. Common failures:
parts[0].props.title: required
— is missing .
parts[0].children[2].props.title: required
— needs both and .
...props.severity: must be one of info|note|warn|success|danger
— wrong severity enum.
...component: unknown component "hyperscribe/Flowchart"
— wrong name; did you mean with ?
...props.level: must be one of 2,3,4
— only accepts 2/3/4; use for h1.
Retry policy: up to 2 automatic retries adjusting the JSON each time. After the 3rd failure, surface the original JSON and stderr to the user so they can intervene.
Limitations (v1)
- No streaming render — full JSON is produced, then rendered end-to-end.
- No custom / third-party components — catalog is fixed at 23 default page components plus 2 slide-only components.
- No direct styling overrides in props. Users may place
~/.hyperscribe/theme.json
to override CSS token values at the renderer level.
- Themeable renderer. Built-in themes are , , , and .
- No multi-page envelopes — one per default invocation. Slide mode uses one .
- Fonts: is not bundled; fallback chain uses Inter / system-ui.
Quick example
A minimal envelope that renders a page with a callout:
json
{
"a2ui_version": "0.9",
"catalog": "hyperscribe/v1",
"is_task_complete": true,
"parts": [
{
"component": "hyperscribe/Page",
"props": { "title": "Deploy checklist", "toc": false },
"children": [
{
"component": "hyperscribe/Section",
"props": { "id": "pre", "title": "Before merging" },
"children": [
{
"component": "hyperscribe/StepList",
"props": {
"numbered": true,
"steps": [
{ "title": "Run tests", "body": "`pnpm test` locally.", "state": "done" },
{ "title": "Check migrations", "body": "Review `prisma/migrations/`.", "state": "doing" },
{ "title": "Smoke DEV", "body": "Hit `/api/health`.", "state": "todo" }
]
}
},
{
"component": "hyperscribe/Callout",
"props": {
"severity": "warn",
"title": "Do not merge to main directly",
"body": "Use the `preview` branch and open a PR."
}
}
]
}
]
}
]
}
Pipe it to the CLI:
bash
echo '<json-above>' | ~/.claude/plugins/hyperscribe/plugins/hyperscribe/scripts/hyperscribe \
--out ~/.hyperscribe/out/deploy-checklist.html && \
open ~/.hyperscribe/out/deploy-checklist.html
Then report the path to the user.