Skip to content

terminfo.dev Information Architecture Design

Entity Taxonomy

Every entity on the site falls into one of these types:

Tested Entities (have probe data)

TypeWhatExampleSlug PatternData Source
App TerminalReal macOS/Linux terminal appGhostty, Kitty, iTerm2/terminals/{slug}probes-apps/
Headless BackendTerminal emulator libraryxterm.js, vterm.js, Alacritty/terminals/{slug}probes-libs/
MultiplexerPass-through testingtmux, GNU Screen/terminals/{slug}probes-mux/

Reference Entities (editorial content, no probe data)

TypeWhatExampleSlug PatternData Source
Historical TerminalDEC hardware, early softwareVT100, VT220, xterm/terminals/{slug}terminals.json (historical)
StandardProtocol/spec groupingECMA-48, VT100, Kitty Extensions/{tag}standards.json + feature tags
CategoryFeature categorySGR, Cursor, Modes/{category}categories.json
FeatureIndividual capabilityBold, Mouse tracking/{category}/{slug}features.json
BaselineCompatibility tierCore TUI, Modern TUI/baseline/{id}baselines.json
FrameworkTUI libraryInk, Textual, Silvery/framework/{id}frameworks.json

Name Disambiguation

Several names refer to multiple entities. The site must clearly distinguish them.

VT100 = 3 things

EntityLabel on SiteSlugWhen User Means
Standard"VT100 Standard"/vt100"features from the VT100 spec"
Historical terminal"DEC VT100"/terminals/vt100-historical"the 1978 hardware terminal"
Headless backend"vt100.js"/terminals/vt100-js"the JavaScript library"

Glossary linking: Bare "VT100" links to /vt100 (the standard). "DEC VT100" links to /terminals/vt100-historical. "vt100.js" links to /terminals/vt100-js.

Cross-links: Each of the 3 pages should have a "See also" box linking to the other two.

xterm = 3 things

EntityLabel on SiteSlugWhen User Means
Standard"Xterm Extensions"/xterm-extensions"the protocol extensions"
Historical terminal"xterm"/terminals/xterm-historical"the X11 terminal emulator"
Headless backend"xterm.js"/terminals/xterm-js"the JavaScript library"

Glossary linking: Bare "xterm" links to /terminals/xterm-historical. "Xterm Extensions" links to /xterm-extensions. "xterm.js" links to /terminals/xterm-js.

Kitty = 2 things

EntityLabel on SiteSlugWhen User Means
Terminal app"Kitty"/terminals/kitty"the terminal emulator"
Standard"Kitty Extensions"/kitty-extensions"the protocols it defined"

Glossary linking: Bare "Kitty" links to /terminals/kitty. "Kitty keyboard protocol" and "Kitty graphics protocol" link to /kitty-extensions.

Ghostty, WezTerm, Alacritty = 1 thing each (clean)

These each have a single terminal page. Headless backend data is subsumed into the app page.

Proposed Navigation Structure

Top Nav

Matrix | Terminals | Features | Standards | Fundamentals | About

Terminals dropdown (grouped):

App Terminals
  Ghostty        Kitty          iTerm2
  Terminal.app   Warp           VS Code
  Cursor         Alacritty      WezTerm

Libraries & Backends
  xterm.js       vterm.js       vt100.js

Multiplexers
  tmux           GNU Screen

Historical
  DEC VT52 (1952)    DEC VT100 (1978)    DEC VT220 (1983)
  xterm (1984)       DEC VT510 (1993)

Features dropdown: categories (unchanged) Standards dropdown: standard tags (unchanged) Fundamentals dropdown: articles (unchanged)

Matrix
Baselines
  Core TUI / Modern TUI / Rich TUI / Unicode
Terminals
  (grouped into App | Library | Mux | Historical subsections)
Features (by category, collapsible)
Standards (by tag)
Compare (popular pairs)
Frameworks
Fundamentals
Glossary
API
About

Homepage

The matrix remains primary. Below the matrix tables, add a "Learn More" section:

## Explore

[Fundamentals]        [Standards]           [Historical]
How terminals work    From VT100 to Kitty   The terminals that
                                            shaped computing

[Baselines]           [Glossary]            [Compare]
What should your      CSI, SGR, OSC...      Side-by-side feature
terminal support?     107 terms explained   comparison

This is a simple 2x3 card grid below the fold. Doesn't compete with the matrix.

Content Generation Flow

                    MANUAL/EDITORIAL
                    ================
content/features.json       ← feature metadata (name, slug, tags, body)
content/terminals.json      ← terminal metadata (label, description, body)
content/standards.json      ← standard metadata (label, description, url)
content/categories.json     ← category metadata (label, order, description)
content/baselines.json      ← baseline tiers (label, features, description)
content/frameworks.json     ← framework metadata (label, baseline, description)
content/glossary.json       ← glossary terms (expansion, description, link)
content/annotations.json    ← result overrides / failure explanations
docs/standards.md           ← hand-authored standards index
docs/features.md            ← hand-authored features index
docs/fundamentals/*.md      ← hand-authored fundamentals articles
docs/about.md               ← hand-authored about page

                    AUTOMATED PROBES
                    ================
bun terminfo probe termless --all  → content/probes-libs/*.json
bun terminfo probe app --all       → content/probes-apps/*.json
bun terminfo probe mux --all       → content/probes-mux/*.json

                    AI-GENERATED
                    =============
bun analysis                → content/analysis.json
  (template-based, reads probe results + editorial JSON)
  (generates commentary for: terminals, baselines, comparisons,
   frameworks, categories, standards, features)

                    BUILD-TIME DERIVATION
                    =====================
docs/data/probes.data.ts
  Reads: all content/*.json + probes-*/*.json
  Computes: stats, baseline compliance, merged metadata
  Output: CensusData object consumed by Vue templates

docs/data/linkify-content.ts
  Reads: glossary.json, terminals.json, frameworks.json,
         standards.json, baselines.json
  Output: linkifyContent(text) → HTML with <a> tags

docs/data/load-probes.ts
  Shared helpers: slugs, labels, tag resolution

docs/.vitepress/plugins/glossary-links.ts
  Reads: same sources as linkify-content.ts
  Operates: markdown-it plugin at parse time
  First-occurrence-only per page

                    ROUTE GENERATION
                    ================
[id].paths.ts           → category + tag pages (~23)
terminal/[id].paths.ts  → terminal pages (~19)
[category]/[id].paths.ts → feature detail pages (~133)
compare/[id].paths.ts   → comparison pages (~66)
baseline/[id].paths.ts  → baseline pages (4)
framework/[id].paths.ts → framework pages (6)

                    BUILD OUTPUT
                    ============
vitepress build docs → docs/.vitepress/dist/ (250+ static HTML pages)
                     → Deployed to Cloudflare Pages

Immediate Fixes Needed

1. Meta description uses raw HTML (P0 — causes garbled pages)

config.ts transformPageData uses params.categoryDescription (linkified HTML with <a> tags) as the page <meta name="description">. This renders as garbled visible text.

Fix: Strip HTML tags before using as meta description.

2. Sidebar/nav doesn't distinguish terminal types

All terminal types (apps, libraries, muxes) are in one flat list.

Fix: Group into subsections in both sidebar and nav dropdown.

The VT100 standard page doesn't link to the VT100 historical page or vt100.js.

Fix: Add "Related" or "See also" boxes on pages where the entity name is ambiguous.

4. linkify-content.ts escaping is incomplete

Only escapes " in tooltips. Should also escape &, <, > like glossary-links.ts does.

Fix: Add full escapeAttr() function.

5. Duplicate Cursor entry in terminals.json

Both cursor and com.todesktop.230313mzl4w4u92 map to the same slug/label.

Fix: Remove the duplicate entry.

Powered by Termless
Playwright for Terminals