A rich canvas your AI draws on — a companion screen for everything your agent wants to show you, instead of scrolling back through walls of chat.
Coding agents bury their answers in long text conversations. termchart gives yours a canvas:
it pushes native visuals to a browser tab in real time — architecture maps, dashboards, PR
reviews, charts, call graphs, live progress — so you glance at a companion screen (a second
monitor or an iPad) and just see what your agent is doing and thinking, no scrolling required.
It ships as a CLI (termchart) plus a Claude Code plugin (skills + the
/termchart:diagram and /termchart:diagram-remote commands):
- The canvas (primary). Run the viewer locally (or deploy it); agents push rich, native visuals over SSE — React Flow graphs, Vega-Lite charts, Mantine UI dashboards, markdown, and split panes — plus live status overlays (toasts / progress bars / loaders). Best on a second monitor or an iPad.
- Inline terminal text (secondary). Deterministic Mermaid → ASCII/Unicode that pastes cleanly into PRs, issues, and chat — no PNGs, no browser, no Mermaid handoff.
Example — an agent reviewing a pull request on the canvas: a before/after summary, a timeline, a validation banner, and an FAQ, linking out to the PR. This is one thing an agent can draw for you — not termchart's own UI.
🖼️ Browse the gallery → — real diagrams across DevOps, SRE, data/ML, research, product, security, finance, and consumer-shopping personas.
🚀 Open the live demo → — a read-only workspace with full example boards (a multi-pane system overview, a DIY plan with video + map, an explainer, a PR review, an algorithm walkthrough) you can click through in the actual viewer.
You never write diagram syntax. Install once, then ask in plain language and your agent picks the right visual and draws it:
/termchart:diagram-remote a sequence diagram of the OAuth login flow → on the canvas
/termchart:diagram a state machine for an order's lifecycle → inline ASCII
Or just say it in any message — “put that on the termchart canvas”, “draw that as a diagram” — and the skill triggers on its own. The agent writes the native spec, validates it, and pushes it to your viewer (or prints aligned text). Then a quick “flip the deploy node to error” or “update the latency stat” and it patches the live view — no rebuild, no scrolling back.
Install — Claude Code:
/plugin marketplace add ivanmkc/termchart
/plugin install termchart@termchart
Install — any other agent (Cursor, Codex, Antigravity/agy, Gemini CLI, … 70+):
npx skills add ivanmkc/termchart # drops the skills into whichever agents you have
npm i -g @ivanmkc/termchart # the CLI they driveFor the canvas, start the viewer (below) and point TERMCHART_VIEWER_URL at it; open that URL
on a second monitor or iPad. The inline terminal renderer needs nothing else.
Agents push diagrams to boards keyed by project/agent (a board is one such view; a
workspace holds many); the browser updates instantly over SSE, and an agent can add --focus to
switch the screen to its board. You author each framework's native JSON — there is no termchart DSL.
The viewer is a tiny Node server — no cloud account needed. Clone the repo, build once, run:
git clone https://github.com/ivanmkc/termchart && cd termchart
npm install && npm run build
PUSH_TOKEN=dev PORT=8080 node packages/viewer/dist/server.jsOpen http://localhost:8080/w/me/ in a browser (any workspace id works — here, me).
Point the CLI at it and push:
export TERMCHART_VIEWER_URL="http://localhost:8080/w/me"
export TERMCHART_VIEWER_TOKEN="dev"
# push a diagram (any --type — see the table below)
termchart push --project demo --agent me --type flow \
plugin/skills/diagram-recipes/examples/user-journey.flow.json --focus
# …or stream progress while you work
termchart status --loader --id build --message "Building…"
termchart status --id build --progress 60 --message "Compiling"
termchart status --success --message "Done"The tab updates the moment you push. Want it on an iPad or a second monitor on your LAN? Point
TERMCHART_VIEWER_URL at your machine's IP (e.g. http://192.168.1.20:8080/w/me) instead of
localhost, and open the same URL on the device.
Prefer an always-on screen you can reach from anywhere? The same server deploys as a container:
cd packages/viewer
gcloud run deploy termchart-viewer --source . \
--min-instances=1 --max-instances=1 --allow-unauthenticated \
--set-env-vars PUSH_TOKEN="$(openssl rand -hex 24)"Then set TERMCHART_VIEWER_URL=https://<service-url>/w/<wsid> and TERMCHART_VIEWER_TOKEN to
the token you generated. More notes — incl. security — in packages/viewer/.
--type |
Renders | content |
|---|---|---|
flow |
React Flow node graph — pan/zoom, dagre auto-layout, legends, status colors | { nodes, edges, direction?, legend? } |
component |
Mantine UI — cards, tables, badges, stats, tabs, timeline, images, links, interactive checklists, embedded maps, video cards | a { type, props, children } tree |
vegalite |
a Vega-Lite chart (incl. scientific: binning, regression, log scales) | a Vega-Lite spec |
markdown |
GitHub-flavored markdown | markdown text |
panes |
a split layout (columns/rows/grid) of any of the above |
{ layout, panes: [{ title?, type, content }] } |
mermaid / text |
terminal-style ASCII/Unicode | mermaid source / text |
Each rich renderer is a lazy-loaded chunk, so the core bundle stays tiny.
Narrate long-running work — builds, deploys, test runs — as transient overlays, keyed by
id so the same id updates in place (a progress bar advances; a loader becomes a success
toast). They stack in the corner and never disturb the main diagram.
The diagram-recipes skill turns the raw formats into good diagrams for common
personas, with copy-paste examples in
plugin/skills/diagram-recipes/examples/:
| Recipe | Type | What it is |
|---|---|---|
| PR review — narrative | component |
Before/After → timeline → validation → FAQ, with a PR link |
| PR review — change graph | flow |
added / removed / modified entities, status-colored edges |
| Product comparison | component |
a logo image + an outbound link + rating per option |
| Stacktrace / call path | component |
a colored monospace call hierarchy (not a graph) |
| User journey / pipeline | flow |
color-coded entry → steps → success / error |
| Metrics dashboard | component |
stat cards + an embedded Vega-Lite trend |
| System architecture | flow |
tiered service/infra topology, colored by layer, animated streams |
| Zoned architecture | flow |
nodes clustered into labeled, non-overlapping zones (tiers/swimlanes) |
| C4 architecture | panes |
one system at three zoom levels — Context → Container → Component |
| Concept explainer | panes |
teach a hard idea: hook → reasoning chain → quantitative chart → grounding |
| Task tracker / board | component |
a cohesive status board — tasks by lane, owners, due, progress |
| Observability dashboard | panes |
dense 2×2 — SLO rings + latency chart + error table + throughput |
| Data lineage | flow |
sources → staging → marts → consumers, zoned, freshness-colored |
| Query plan | flow |
a SQL EXPLAIN operator tree, colored by cost |
| Event-driven | flow |
producers → broker/topic → consumers, with a dead-letter path |
| Recursion tree | flow |
a top-down call tree (base cases / memoized hits colored) |
| Deep-code answer | panes |
annotated code + a step trace table + a complexity curve |
| Big-O complexity | vegalite |
growth-class curves on a symlog scale |
| Risk matrix | component |
likelihood × impact heat-grid with risks in cells |
| Critical path | flow |
task schedule with the critical chain highlighted |
| Sprint burndown | vegalite |
ideal vs actual remaining over a sprint |
| RACI matrix | component |
tasks × roles with R/A/C/I badges |
| Map — routes | component |
a Leaflet/OSM map with markers + color-coded route polylines (origin → N destinations) |
| Task checklist | component |
a two-way checklist — the agent ticks progress, you tick sign-off; synced live |
| DIY / project plan | component |
a top-down build plan — badges, materials table, interactive step checklist, video tutorials, a where-to-buy map, and a budget chart |
| Trace waterfall | vegalite |
distributed-trace spans by start/duration, by service |
| Flame graph | component |
CPU profile — stacked frames, width ∝ time |
| Calendar heatmap | vegalite |
activity grid (week × day), sequential color |
| Matrix heatmap | vegalite |
N×N values (e.g. latency/correlation) with cell labels |
| Sequence · call-hierarchy · state · ER · class | flow |
the classic software diagrams, hand-tuned |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Structured pushes are validated server-side, so a malformed payload is rejected with a precise,
path-pointed reason that termchart push prints — the agent fixes it and re-pushes, instead of
silently rendering something broken:
$ printf '{"panes":[{"type":"component","content":{}}]}' | termchart push --type panes …
push failed: HTTP 400 — panes[0].content must be a JSON string (got object)
- A live persona gallery on an empty workspace, replaced the moment you push.
- Fullscreen any pane; a collapsible sidebar of boards; deep-linkable
#project/agentURLs. - Six themes — System (follows the OS) plus Dark · Midnight · OLED (dark) and Light · Paper · Google Cloud (light) — from a header picker. Each has a distinct accent and a per-theme chart palette, and every renderer follows (React Flow, Vega-Lite, Mantine, and the chrome), persisted locally.
- Interactive checklists — a
Checklistthe agent ticks off viapatchand you tick in the UI; the checked state lives in the spec (sopullreads it back) and syncs live to every screen. - Embedded maps — a
Mapcomponent (Leaflet + OpenStreetMap, no API key) with markers and route polylines, for location/route views right inside a dashboard. - Experimental agent↔human console (off by default) — flip the "Console (beta)" toggle to send
the agent feedback / commands and click agent-pushed suggestion chips; the agent reads them back
with
termchart inboxand offers choices withtermchart suggest. - Flows re-fit on resize (iPad rotation), carry legends, and use measured layout; a server-side geometry lint flags edges that run over or too close to nodes so tangled graphs get fixed.
- Durable & retrievable. Views live server-side, so a new agent session can pick up where the
last left off —
termchart list→pull→ edit →push, orpatcha small change in place. State is in-memory by default; setTERMCHART_STATE_BUCKETto persist to GCS across restarts, or bring your own GitHub repo (see below) for user-owned, git-versioned state.
Persistence is pluggable and opt-in. Precedence: GitHub > GCS > in-memory (if both GitHub and GCS env are set, GitHub wins and a line is logged).
- GitHub (bring-your-own repo) — one file
state/<wsid>.jsonper workspace, committed via the GitHub Contents API. Every save is a commit, so your dashboard history is a git log you can time-travel. Ideal for self-hosted / localtermchart serve.TERMCHART_STATE_GITHUB_REPO=owner/name— presence selects this backend.TERMCHART_STATE_GITHUB_TOKEN= a PAT with repo write access (required; missing ⇒ skipped).TERMCHART_STATE_GITHUB_BRANCH= target branch (optional, defaultmain).TERMCHART_STATE_GITHUB_CREATE=1/trueto auto-create a private repo if it's missing (optional; otherwise a missing repo logs an error and falls back to in-memory).- Saves are debounced (one commit per burst, not per keystroke) and use the file SHA for optimistic concurrency (a conflict re-reads the SHA and retries once).
- GCS — set
TERMCHART_STATE_BUCKETto persist to a bucket; the zero-config default for the hosted viewer.
Deterministic Mermaid → ASCII/Unicode from the same termchart CLI. Built on
beautiful-mermaid — a synchronous, no-DOM
grid renderer, so the same input + flags always produce the same bytes.
$ printf 'graph LR\n A[Client] --> B[API] --> C[(DB)]' | termchart
┌────────┐ ┌─────┐ ┌──────┐
│ Client ├────►│ API ├────►│ DB │
└────────┘ └─────┘ └──────┘
termchart [file] # render a Mermaid file, or stdin if omitted
termchart lint [file] # check source is within the renderable subset
termchart serve [flags] # start a local viewer + print its URL and env exports
termchart begin [flags] # show a board as "composing" instantly (placeholder + focus + loader)
termchart push [flags] # push a diagram to the live viewer (--description required)
termchart patch [flags] # merge a small change into a live view (flow/component/panes; --check too)
termchart status [flags] # push a status update — toast / progress / loader
termchart list [flags] # catalog live views: board · type · description · updated
termchart pull [flags] # print a stored spec (re-pushable; --json for the full record)
termchart suggest [flags] # push clickable suggestion chips to the console (agent → human)
termchart inbox [flags] # read the human's console feedback / clicks (--wait long-polls)
termchart clear [flags] # remove one board (--project/--agent) or --all
termchart --version
Render flags:
--ascii # pure ASCII (+,-,|) instead of Unicode box-drawing
--safe, --portable # alias for --ascii — guaranteed alignment in any terminal
--color <auto|none|16|256|truecolor> # default auto (color on a TTY, plain when piped)
--theme <name> # zinc-dark (default), zinc-light, tokyo-night, dracula, nord, github-dark, …
--padding-x <n> / --padding-y <n>
--rounded # rounded corners/elbows (╭╮╰╯); not usable with --ascii
--fit / --width <n> # auto-compact spacing to fit terminal width (80 if piped)
Exit codes: 0 ok · 1 lint/unsupported · 2 parse error · 3 bad usage.
Six types render deterministically as terminal text — flowchart, sequence, state, class, ER, and xychart. Two examples:
(───────) ╭───────────╮ ◇───────────◇ ╭────────╮ ╭────────╮
│ Client├───►│API Gateway├───►│Authorized?│ ├──yes─►│Service ├───►│Database│
(───────) ╰───────────╯ ◇─────┬─────◇ ╰────────╯ ╰────────╯
│ (────────)
└──────no──────►│ 401 │
(────────)
┌────────┐ ┌─────┐ ┌──────┐
│ Client │ │ API │ │ Auth │
└────┬───┘ └──┬──┘ └───┬──┘
│ POST /login │ │
│────────────────▶ │
│ │ verify(creds) │
│ │──────────────────▶
│ 200 + token │ │
◀╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌│ │
termchart lint errors (exit 1) on constructs the renderer can't draw (sequence
note/loop/alt/opt/par) and warns on fullwidth CJK/emoji labels (the grid allots
one cell per character, so wide glyphs misalign borders). The full
industry gallery shows all six types in Unicode
and ASCII.
npx skills add ivanmkc/termchart # skills → Claude Code, Cursor, Codex, Antigravity, Gemini CLI… (70+)
npm i -g @ivanmkc/termchart # the CLI those skills driveThe skills installer drops termchart's
progressive-disclosure skills (with recipe examples) into whichever agents you have. See
Any coding agent for details. The Claude Code plugin
below is an alternative for Claude users.
/plugin marketplace add ivanmkc/termchart
/plugin install termchart@termchart
On session start the plugin ensures the termchart CLI is on your PATH (installing it from
npm if missing). Then use /termchart:diagram (inline terminal) or
/termchart:diagram-remote (live viewer).
Claude Code namespaces plugin commands (/termchart:diagram). For a plain /diagram, drop a
one-line user command:
mkdir -p ~/.claude/commands
cat > ~/.claude/commands/diagram.md <<'EOF'
---
description: Render a diagram as terminal ASCII via termchart
argument-hint: [mermaid source OR a description of the diagram you want]
---
Render the following as aligned terminal text with the `termchart` CLI, following the
`termchart` skill: write Mermaid in the supported subset, `termchart lint` it, then
`termchart --ascii --color none` it and paste the output verbatim.
$ARGUMENTS
EOFnpm i -g @ivanmkc/termchart # requires Node 18+
Point any agent's rules/skill file at the same CLI: have it write Mermaid in the supported
subset, run termchart lint, then termchart to render — or termchart push to send rich
JSON to the viewer. See plugin/skills/termchart/SKILL.md
(terminal) and plugin/skills/diagram-recipes/SKILL.md
(viewer) — both are written to be agent-agnostic.
termchart's skills install into any coding agent (Claude Code, Cursor, Codex, Antigravity,
Gemini CLI, Windsurf, Zed, Aider — 70+) with one command, via the open
skills installer:
npx skills add ivanmkc/termchart # → the diagram-recipes + termchart skills (recipe examples included)
npm i -g @ivanmkc/termchart # the CLI those skills drive (Node ≥18; the skills also self-heal it)That's the whole setup. The skills are progressive-disclosure (they load only when you ask
for a diagram, so they don't tax every prompt) and they carry the recipe examples/ with them.
For the live viewer, also set TERMCHART_VIEWER_URL + TERMCHART_VIEWER_TOKEN.
Verified: npx skills add installs both skills + all examples into Claude Code, and the same
skills + CLI work in the Antigravity CLI (agy) — a real agy agent rendered and pushed with no
agy-specific files.
Zero-install fallback: the cross-tool AGENTS.md at the repo root is read by
any AGENTS.md-aware agent with no install at all (it just needs the CLI on PATH) — useful for
agents without a skills mechanism. The Claude Code plugin (above) is optional sugar for Claude
users (marketplace install + /termchart:* commands).
npm install # workspace deps
npm run build # tsc + esbuild → packages/*/dist
npm test # vitest across workspaces
npm run -w @ivanmkc/termchart-viewer test:e2e # Playwright (rich renderers)
Design notes live in docs/specs/.
MIT







