Claude
Skills
Sign in
Back

termrender

Included with Lifetime
$97 forever

Rich terminal rendering of directive-flavored markdown. Panels, trees, columns, callouts, mermaid diagrams, syntax-highlighted code, diffs, charts, KPI tiles, timelines, tasklists, and inline badges — rendered as ANSI output or displayed in a tmux side pane. Use when producing visual output, diagrams, or structured terminal displays.

Writing & Docs

What this skill does


# termrender — Terminal Rendering Skill

Render directive-flavored markdown as rich ANSI terminal output using the `termrender` CLI.

## CLI Quick Reference

```
termrender <file>              Render a markdown file
termrender <file> --tmux       Render in a new tmux side pane
termrender -w 100 <file>       Render at specific column width
termrender --check <file>      Validate syntax without rendering
cat file.md | termrender       Render from stdin
```

## Directives

**Use `:::` (three colons), not `::`.** Two-colon lines are NOT directives — the parser treats them as plain text and they render verbatim. Every fence below opens with at least three colons and closes with the same count.

Directives open with 3+ colons (`:::name{attrs}`, `::::name{attrs}`, etc.) and close with a matching colon count. `:::divider`, `:::progress`, and `:::gauge` are self-closing at top level (no body, no closer needed); every other directive needs an explicit closer.

The available directives are exactly those documented below. Do **not** invent ones not on this list — `tile`, `tab`/`tabs`, `title`, `diagram`, and `table` (with attrs) are not real directives. For tiles use `:::stat`; for diagrams use `:::mermaid`; for tables use plain GFM `| col | col |` syntax with no fence; headings are `#`/`##` markdown.

**Backticks are for code only.** ` ``` ` fences always produce a code block — `` ```mermaid `` and `` ```{name} `` are NOT directives, they render as plain code blocks with `mermaid` or `{name}` as the language label. Every termrender directive uses `:::`.

### Nesting

**Rule:** outer fences must use strictly more colons than the inner fences they wrap. The parser pairs openers and closers by colon count — a closer with a different count is treated as body content and re-parsed recursively. This matches MyST, Pandoc fenced divs, and markdown-it-container conventions.

```
::::columns
:::col{width="50%"}
Left content.
:::
:::col{width="50%"}
Right content.
:::
::::
```

For 3 levels use `:::::` → `::::` → `:::`. The extra colons make it visually clear which closer matches which opener and let the parser fail fast on mismatches.

**Self-closing caveat:** `divider`, `progress`, and `gauge` are only self-closing at the *top level*. When nested inside another directive, they still need an explicit closer.

### Option Lines

Directives support option lines at the top of the body:

```
:::panel
:title: My Panel
:color: blue
Content here.
:::
```

### Panel — bordered box
```
:::panel{title="Title" color="blue"}
Content here.
:::
```

### Columns — side-by-side layout
```
::::columns
:::col{width="50%"}
Left content.
:::
:::col{width="50%"}
Right content.
:::
::::
```

### Tree — hierarchical view
```
:::tree{color="cyan"}
Root
  Branch A
    Leaf 1
    Leaf 2
  Branch B
:::
```
Indentation (2 spaces) defines nesting depth.

### Callout — status box with icon
```
:::callout{type="info"}
Important note here.
:::
```
Types: `info`, `warning`, `error`, `success`

### Quote
```
:::quote{author="Author Name"}
Quoted text here.
:::
```

### Code — syntax highlighted
```
:::code{lang="python"}
def hello():
    print("world")
:::
```

### Divider — horizontal rule (self-closing, no `:::`)
```
:::divider{label="Section Break"}
```

### Diff — colored unified diff
```
:::diff{title="auth.py"}
- old_token = jwt.encode(payload, key)
+ new_token = jwt.encode(payload, key, algorithm="HS256")
  return new_token
:::
```
Lines starting with `+` render green, `-` red, `@` (hunk headers) magenta. Other lines are dim. The `title` attr is optional and defaults to `diff`.

### Bar — multi-bar horizontal chart
```
:::bar{title="requests/sec" color="cyan"}
api-gateway: 12400
auth: 8200
cache: 5100
:::
```
Body is one `label: value` per line (also accepts `label | value unit`). Bar widths scale to the largest value; sub-cell precision uses Unicode eighths blocks. Optional `title` and `color` attrs.

### Progress — single-line progress bar (self-closing)
```
:::progress{value=70 max=100 label="Build"}
```
Color auto-selected by ratio (red < 50% < cyan < 99% < green) unless `color=` is set. Renders as one line.

### Gauge — three-line meter (self-closing)
```
:::gauge{value=88 max=100 label="Memory" unit="%"}
```
Three lines: label, full-width bar, numeric readout. Color auto-selected by load (green < 70% < yellow < 90% < red). Use for resource utilization where the threshold matters.

### Stat — KPI tile
```
:::stat{label="p99 latency" value="34ms" delta="-12%"}
:::
```
Bordered tile with label, large centered value, and trend arrow + delta. `delta` sign auto-picks ▲ (green) or ▼ (red); override with `trend="up|down|flat"`. Optional body becomes a caption below the delta. Compose multiple stats inside `:::columns` for dashboards.

### Timeline — vertical event timeline
```
:::timeline{title="Release history" color="cyan"}
- 2024-01: v1.0 launched
- 2024-06: v2.0 redesign
- 2025-03: v3.0 mobile
:::
```
Body is `- date: event` per line (`|` also works as the separator). Renders dates right-aligned with bullet markers and `│` connectors between entries.

### Tasklist — checkbox list
```
:::tasklist
- [x] write parser
- [x] write renderer
- [ ] write tests
- [!] in progress
:::
```
Renders ☑ / ☐ / ◐ checkboxes. The `:::tasklist` directive forces tasklist styling on the inner list and treats unmarked items as unchecked. Plain markdown lists with at least one `[x]`/`[ ]`/`[!]` marker are auto-promoted to tasklists — the directive is only needed when you want every item to render as an unchecked todo without writing `[ ]` on each line.

### Inline badges
```
Status: :badge[stable]{color=green} :badge[v3.2.0]{color=blue}
```
Inline pill rendered with colored fg + dim bg, usable inside any paragraph, list item, table cell, or stat caption. Colors: `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `gray`. Defaults to `blue`.

### Mermaid — ASCII diagrams
```
:::mermaid
graph TD
    A[Start] --> B{Decision}
    B -->|Yes| C[Action]
    B -->|No| D[End]
:::
```
Body is standard mermaid source. `` ```mermaid `` is **not** supported — it will render as a plain code block.

## Mermaid Best Practices

Mermaid diagrams render as ASCII box art — every node becomes a bordered rectangle. Diagrams that look clean in a browser can be unreadable in a terminal. Follow these rules:

**Fewer nodes, more text.** Each node should carry enough context to be useful on its own. Don't split a concept across multiple tiny nodes — combine them into one descriptive node. 3–6 nodes is ideal; 8+ usually produces output wider than the terminal.

**Keep labels short but descriptive.** Node labels render inside bordered boxes. Long labels make wide boxes that eat horizontal space. Aim for 2–5 words per node. Use `<br/>` for multi-line labels when a node needs more context.

**Prefer `graph TD` over `graph LR`.** Top-down layouts grow vertically (cheap in a terminal) instead of horizontally (expensive). LR graphs with 4+ nodes in a chain will overflow most terminals.

**Limit branching.** A node with 4+ children at the same depth creates 4+ side-by-side boxes. If a node has many children, consider grouping related children into a single summary node, or splitting into separate diagrams.

**Use panels for detail, mermaid for flow.** Don't cram implementation details into node labels. Show the high-level flow in mermaid, then use `:::panel` or `:::columns` below to expand on each step.

**Bad** — too many small nodes, spreads wide:
```
:::mermaid
graph TD
    A[Boot] --> B[Init services]
    B --> C[Check flag]
    C -->|yes| D[Validate auth]
    D --> E[Fetch config]
    E --> F[Start pipeline]
    C -->|no| G[Idle]
    F --> H[Running]
    H --> I[Process events]
    H --> J[Upload data]
    H --> K[Refresh config]
:::
```

**Good** — fewer nodes, each tells a story:
```
:::mermaid
graph TD
    A[Worker boots and<br/>initializes all services] --> B{Feature flag<br/>TAPLINE_ENABLED?}
    B -->|disabled| C[Worker enters idle state,<

Related in Writing & Docs