CLI

The same rendering pipeline as the extension and the MCP server, as shell commands. Render a figure source to SVG or PNG, validate sources in CI, list formats, or host the MCP server — with output byte-for-byte identical to what quarto render produces.

Install

Nothing to install with npx:

npx livefigures --help

Or use the copy that ships inside the extension — every project that ran quarto add already has it:

node _extensions/seandavi/livefigures/cli.mjs --help

Node ≥ 18 is the only requirement, same as the extension.

Commands

# render a source file (format inferred from the extension)
livefigures render figures/arch.excalidraw -o arch.png
livefigures render figures/deps.dot -o deps.svg

# render from stdin
echo 'digraph { a -> b }' | livefigures render - --format graphviz > g.svg

# check sources without producing output — exit 1 + the exact
# quarto render error on a bad source
livefigures validate figures/*.dot figures/*.vl.json

# what can I write?
livefigures formats
livefigures formats --json

# host the MCP server (stdio)
livefigures mcp

Render options mirror the extension: --theme light|dark, --background transparent|scene (Excalidraw, Vega-Lite and Vega only), --scale <n> for PNG.

Look at the figure, not just the exit code

validate catches broken sources. It cannot catch the more common problem: a figure that renders perfectly and is still wrong. Those never raise an error, so the only thing that catches them is rendering the figure and looking at it — which is what render -o is for.

What to look for, and the usual repair:

What you see Fix
Text too small on a slide — the figure is tall and height-bound Check the output aspect ratio against the target medium; restructure the figure
A row laid out as a diagonal staircase (Graphviz) {rank=same; a; b; c; }
Two opposing edges overlapping, labels colliding One dir=both edge with a single label
An edge label sitting on the arrow Shorten it, or lengthen the edge (nodesep / ranksep)
Clusters reordered after a rankdir change (Graphviz) Disconnected-cluster order is not rankdir-stable — re-check visually after any such edit
A literal {...} appearing as text (nomnoml) Inline directives don’t work everywhere; define #.name: fill=… and use [ Label]
Legend or axis labels truncated (Vega-Lite) Raise labelLimit, e.g. legend: {labelLimit: 300}
A cluster label clipped at the figure edge (Graphviz) Reduce the figure width in the document, or add graph margin

Agents get the same checklist from the skill, and the MCP server returns the rendered image in-context so an agent can do this pass itself.

Validate figures in CI

validate exits non-zero on the first bad source, so a one-line CI step keeps broken figures out of main:

- name: Validate figure sources
  run: npx -y livefigures validate figures/*

See also

  • MCP server — the same tools, callable by your agent, with images the agent can see.
  • Agent skill — teach an agent when and how to use all of this.