Vega-Lite Interactive Charts
oaustegard/claude-skills
Builds interactive Vega-Lite charts from uploaded data: analyzes the fields, picks five to ten fitting chart types, and produces a React artifact with the data embedded inline.
Chart a Mendix app with Vega-Lite through a pluggable widget that takes the specification and the data as separate properties, so the model emits rows and never assembles a chart payload.
$ npx skills add mendixlabs/mxcli --skill mendix-vega-charts -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install mendixlabs/mxcli mendix-vega-charts --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/packs/mendix-vega-charts .claude/skills/mendix-vega-charts && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "mendix-vega-charts" agent skill from https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/packs/mendix-vega-charts into .claude/skills/mendix-vega-charts/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mendix-vega-charts", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/packs/mendix-vega-chartsType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add mendixlabs/mxcli --skill mendix-vega-charts -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install mendixlabs/mxcli mendix-vega-charts --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/packs/mendix-vega-charts .agents/skills/mendix-vega-charts && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "mendix-vega-charts" agent skill from https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/packs/mendix-vega-charts into .agents/skills/mendix-vega-charts/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mendix-vega-charts", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mendixlabs/mxcli --skill mendix-vega-charts -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install mendixlabs/mxcli mendix-vega-charts --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/packs/mendix-vega-charts .cursor/skills/mendix-vega-charts && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "mendix-vega-charts" agent skill from https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/packs/mendix-vega-charts into .cursor/skills/mendix-vega-charts/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mendix-vega-charts", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/mendixlabs/mxcli.git --path .claude/skills/packs/mendix-vega-charts--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add mendixlabs/mxcli --skill mendix-vega-charts -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install mendixlabs/mxcli mendix-vega-charts --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/packs/mendix-vega-charts .gemini/skills/mendix-vega-charts && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "mendix-vega-charts" agent skill from https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/packs/mendix-vega-charts into .gemini/skills/mendix-vega-charts/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mendix-vega-charts", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install mendixlabs/mxcli mendix-vega-chartsInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add mendixlabs/mxcli --skill mendix-vega-charts -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/packs/mendix-vega-charts .github/skills/mendix-vega-charts && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "mendix-vega-charts" agent skill from https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/packs/mendix-vega-charts into .github/skills/mendix-vega-charts/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mendix-vega-charts", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mendixlabs/mxcli --skill mendix-vega-charts -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install mendixlabs/mxcli mendix-vega-charts --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/packs/mendix-vega-charts .opencode/skills/mendix-vega-charts && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "mendix-vega-charts" agent skill from https://github.com/mendixlabs/mxcli/tree/main/.claude/skills/packs/mendix-vega-charts into .opencode/skills/mendix-vega-charts/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "mendix-vega-charts", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
mendix-vega-chartsChart a Mendix app with Vega-Lite through a pluggable widget that takes the specification and the data as separate properties, so the model emits rows and never assembles a chart payload.
Mendix Vega Charts is an agent skill from mendixlabs/mxcli. Chart a Mendix app with Vega-Lite through a pluggable widget that takes the specification and the data as separate properties, so the model emits rows and never assembles a chart payload. Use when a Mendix project needs charts Studio Pro's own widgets do not cover — small multiples, faceted tables, sparklines inside a data grid, calendar heatmaps, brushed scatter plots, stream graphs — or when an agent is authoring charts from MDL rather than by hand.
Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 39 other files, including scripts and reference files (for example `pack.yaml`, `references/failure-modes.md` and `references/install.md`).
The repository describes itself as: Mendix cli tool, a headless way to work with Mendix projects. Enables Mendix projects for use with 3rd party agentic coding tools like Claude Code and Copilot. Includes a… The licence is Apache-2.0.
Read from SKILL.md and the folder at commit 20a6c89. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 2 files in scripts/ (JavaScript, from the files we listed), which the agent can run.
Shell commands in SKILL.md call:
npmnodeFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use npm, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Mendix Vega Charts loads about 3k tokens when it runs, and up to ~7.1k if it reads all its reference files. Until then it costs about 119 tokens; SKILL.md has 1,597 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from mendixlabs/mxcli at commit 20a6c89, republished under its Apache-2.0 licence (© mendixlabs). 1,597 words, ~2,964 tokens.
.claude/skills/mendix-vega-charts/SKILL.md (or your agent's skills folder). This skill also uses 36 other files; get the full folder from GitHub.A pluggable widget, roughly 150 lines of TSX, with two properties that matter:
| Property | What it carries |
|---|---|
spec | A Vega-Lite or Vega specification, as JSON text. Static, authored once, committed. |
chartData | A string attribute holding a JSON array of row objects. Built by a microflow. |
The widget folds the data into the spec under the name given by datasetName and hands the result to vega-embed, which picks Vega or Vega-Lite from the spec's own $schema. Nothing else happens at runtime.
The split is the whole point. The model emits a table of facts; the specification decides what that table looks like. A microflow that concatenates a chart payload — series, axes, colours — is a microflow that has to be edited every time the chart changes, and it cannot be checked without running the app. A microflow that emits [{"cat":"Groceries","m":"2026-06-01","v":697.70}, ...] can be checked against the database with a SQL query, and the spec beside it can be compiled and measured without a browser at all (see Verifying).
An agent. The tradeoff is deliberate: a hand-authored Vega-Lite spec is a large piece of JSON, which is uncomfortable to maintain in Studio Pro's property editor and comfortable for a coding agent that can compile it, render it headless, and measure the result. If a human will maintain the chart by hand in Studio Pro, use Studio Pro's chart widgets instead.
What makes this usable without deep Vega-Lite knowledge is specs/ — working specifications for the common shapes, each with a sample data file, each of which compiles and renders. Start from the closest one and change fields, not structure.
See references/install.md. Summary: copy the widget source, npm ci, npm run build, put the built .mpk in the project's widgets/ folder, and commit it — a gitignored widgets/ makes every other clone unbuildable.
Re-namespace it away from whoever built it first (ledger.widget.web.… here) with three edits, listed in that file. Verified: after the three edits the built package carries the new namespace throughout, including the widget id inside VegaChart.xml.
pluggablewidget 'acme.widget.web.vegachart.VegaChart' chartSpend (
chartData: ChartData,
datasetName: 'table',
chartHeight: 0,
renderer: 'svg',
showActions: false,
spec: '{ ... }')It needs an entity context — put it in a dataview over the object whose attribute holds the data. The full property table, the escaping rules for putting JSON inside an MDL string, and the click-back path are in references/properties.md.
Two rules worth carrying in your head:
chartHeight: 0 means "as tall as it renders". A chart whose height is decided by its data — a facet row per category, a legend entry per series — has no height the page can be told in advance, and a fixed container silently stops matching the moment the data grows.['Jan','Feb'][datum.m-1] is written [''Jan'',''Feb''][datum.m-1]. It is stored unescaped.As an attribute (the default). A microflow builds a JSON array into a string
attribute, chartData binds to it, and the widget folds it into the spec. Nothing
is fetched; the payload arrives with the page.
As a URL. Leave chartData unbound and put the address in the spec:
"data": {
"url": "/odata/chartapi/v1/MonthCategory?$filter=Yr eq 2026",
"format": {"type": "json", "property": "value"}
}The spec needs no change for this — with no data bound the widget passes it
through untouched and Vega's own loader does the fetch. Verified end to end
against an endpoint served by the app itself: one 200, six marks, no error, and
format.property unwrapping the {"value": […]} envelope OData returns.
X-Csrf-TokenSame-origin requests carry the session cookie, and the cookie alone is not
enough. Mendix refuses a session-authenticated request without the session's
CSRF token — on a read, not just a write, and on /odata/ as well as /xas/.
Measured on 11.14.0 against one URL, four requests:
| request | result |
|---|---|
| no credentials | 401 |
| session cookie only | 401 |
session cookie + X-Csrf-Token | 200, correct payload |
| basic auth | 200, correct payload |
Vega reports the 401 body as an empty dataset, so the chart draws its axes and
a full legend with no marks and no error — measured through this widget's own
loader: 0 marks and 3 axes without the token, 1 mark with it.
The widget shipped here supplies the header (widget/src/csrf.ts),
reading the token from mx.session.getConfig("csrftoken") — it is not a cookie
and cannot ride along by itself. A widget built from an earlier copy of this pack
does not, and needs that loader added:
const instance = vegaLoader();
const fetchHttp = instance.http.bind(instance);
instance.http = (uri, options) => fetchHttp(uri, withCsrfHeader(uri, options, location.href, token));Same-origin only, and the check is a resolution rather than a string test:
the token authenticates this session against this app, so sending it to a
third-party host hands that host a working credential. Resolving the URI against
the page settles the two cases a /^[a-z][a-z0-9+.-]*:\/\//i test on the raw
string gets wrong — a protocol-relative //elsewhere.example/rows.json carries
no scheme and goes to another host, and an absolute URL naming the app's own
origin is the app.
Two things that send a diagnosis the wrong way:
document.cookie shows only originURI=/login.html. That reads like a
missing session cookie and starts a hunt for a cookie problem that does not
exist — XASSESSIONID and xasid are httpOnly, so the browser sends them
and JavaScript cannot see them.The wider rule, and what each authentication method costs, is in
.claude/skills/mendix/odata-data-sharing/reference/errors-and-auth.md.
The URL form buys: browser caching, a payload that is not part of the page state,
query parameters ($filter, $top) as the chart's own controls, and one endpoint
serving several charts.
It costs:
nextLink;
Vega fetches once. A chart over a paged endpoint quietly plots the first page,
so cap the result deliberately ($top) rather than discovering the cap.check-spec.mjs cannot fetch it. Keep a sample .data.json beside the spec
so it stays checkable offline.ID
as key, and that representation is not a property MDL can set (FINDINGS 113).
Setting it once in Studio Pro unblocks it; published REST avoids it entirely.
Confirm you can publish before designing a chart around a URL.Default to the attribute for anything a microflow already computes — it keeps the figures checkable against SQL and the chart working with no endpoint to secure. Reach for the URL when the data is genuinely shared, already published, or large enough that caching matters.
The microflow emits JSON and nothing else. Build it as a string concatenation over a retrieve, ideally over an OQL view entity so the aggregation happens in the database:
loop $R in $Rows
begin
set $Json = $Json + $Sep
+ '{"cat":"' + $R/CategoryName + '"'
+ ',"m":"' + $Month + '"'
+ ',"v":' + toString(round($R/Total, 2)) + '}';
set $Sep = ',';
end loop;toString(round(x, 2)) is the right way to write a number into JSON: it always uses a . decimal point, whatever the user's language, and never switches to an exponent (measured on 11.13: 12.35, and 0.0000001 stays a plain decimal). Do not use formatDecimal(x, '0.00') — without a locale argument it formats in the current user's language, so a Dutch user gets 12,50 and the chart reports "Data is not valid JSON" while it renders fine for you. If you need formatDecimal (fixed trailing zeros), pass an explicit locale with a hyphenated tag: formatDecimal(x, '0.00', 'en-US'). The underscore form 'nl_NL'/'en_US' is not an error — it is silently ignored and falls back to the user's language, so the bug comes back. Never write a value that could be empty into an unquoted position; emit null instead, and never emit 0 for "no data" (a zero against a full budget reads as maximally under budget, which is a lie the chart tells convincingly).
scripts/check-spec.mjs compiles a spec with sample rows, renders it headless, and reports size, mark counts and any Vega-Lite warnings. It catches most authoring errors in about a second, without a build or a browser:
cd .claude/skills/mendix-vega-charts/scripts
npm install # vega + vega-lite, once
node check-spec.mjs ../specs/line-timeseries.json
node check-spec.mjs ../specs/*.json # all of themUse it for more than pass/fail. Because it exposes the scenegraph, it answers questions a screenshot cannot: how tall does this get with 15 categories rather than 13, do these facet rows share a pitch, where did that band edge actually land. Several of the failure modes below were only ever settled by measuring the scenegraph.
Read references/failure-modes.md before guessing. It catalogues the ones that cost real time on this project, each with the symptom, the cause and the fix — a tooltip that silently un-aggregates the chart it is attached to, facet rows that drift out of alignment, a fixed container that stops matching its chart, DESCRIBE PAGE output that will not round-trip, and a stylesheet that never reaches the bundle.
The general rule from all of them: measure the rendered output, do not reason about the spec. More than once here the first hypothesis was wrong and the measurement was decisive in one command.
© mendixlabs, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 36 other files (scripts, references) in .claude/skills/packs/mendix-vega-charts of mendixlabs/mxcli.
Open the folder on GitHubat commit 20a6c89
Mendix Vega Charts next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Mendix Vega Charts this skillmendixlabs/mxcli | 128 | — | ~3k | Automated safety check: Pass | Apache-2.0 | |
| Vega-Lite Interactive Chartsoaustegard/claude-skills | 150 | — | ~2.1k | Automated safety check: Pass | MIT | |
| Chart Visualizationbytedance/deer-flow | 83k | 2 repos | ~840 | Automated safety check: Pass | MIT | |
| Makepad Widgetssickn33/agentic-awesome-skills | 47k | 2 repos | ~1.7k | Automated safety check: Pass | MIT | |
| Working With ChartsPostHog/posthog | 40k | — | ~948 | Automated safety check: Pass | Custom licence | |
| Contact Widgetnexu-io/open-design | 100k | — | ~1.6k | Automated safety check: Pass | Apache-2.0 |
oaustegard/claude-skills
Builds interactive Vega-Lite charts from uploaded data: analyzes the fields, picks five to ten fitting chart types, and produces a React artifact with the data embedded inline.
bytedance/deer-flow
Picks a suitable chart type from 26 options for your data, maps the data to that chart's parameters and generates a chart image through a JavaScript script.
sickn33/agentic-awesome-skills
Version: makepad-widgets (dev branch) | Last Updated: 2026-01-19 Check for updates: https://crates.io/crates/makepad-widgets
PostHog/posthog
Guides consumers of @posthog/quill-charts through chart selection, data, themes, sizing, and composition.
nexu-io/open-design
Self-contained floating chat widget with welcome screen, social links, meeting button, and message input.
sickn33/agentic-awesome-skills
Create, manage, and deploy Helm charts for Kubernetes package management.
mendixlabs/mxcli
Push OData query options into the SQL of a Mendix resource served by a read microflow, so $filter, $orderby, $top, $skip, $count and the key lookup reach the database instead of being silently…
mendixlabs/mxcli
Author Mendix AI agent documents in MDL — Model, Knowledge Base, Consumed MCP Service and Agent, with variables, tools and multi-line prompts.
mendixlabs/mxcli
Run set-based INSERT, UPDATE and DELETE against Mendix entities through OQL statements, which the runtime supports and Studio Pro cannot author.
mendixlabs/mxcli
Define event-driven APIs over Kafka with Mendix business event services — publish and subscribe contracts, CREATE/DROP/DESCRIBE.
mendixlabs/mxcli
Search the Mendix Catalog platform service registry (catalog.mendix.com) from the CLI to find services published across an organisation.
mendixlabs/mxcli
Stand up an HTTP endpoint you control instead of a live third-party API, and point the Mendix app at it — Prism from an OpenAPI contract, a constant swap, or a forward proxy.
Chart a Mendix app with Vega-Lite through a pluggable widget that takes the specification and the data as separate properties, so the model emits rows and never assembles a chart payload. Mendix Vega Charts is an agent skill from mendixlabs/mxcli. Chart a Mendix app with Vega-Lite through a pluggable widget that takes the specification and the data as separate properties, so the model emits rows and never assembles a chart payload.
Mendix Vega Charts fits situations like: A Mendix project needs charts Studio Pros own widgets do not cover — small multiples; sparklines inside a data grid; calendar heatmaps; brushed scatter plots.
Run `npx skills add mendixlabs/mxcli --skill mendix-vega-charts -a claude-code`. Or copy the skill folder (.claude/skills/packs/mendix-vega-charts in mendixlabs/mxcli) into .claude/skills/mendix-vega-charts in your project. Claude Code loads it when a task matches its description.
Run `npx skills add mendixlabs/mxcli --skill mendix-vega-charts -a codex`. Or copy the skill folder (.claude/skills/packs/mendix-vega-charts in mendixlabs/mxcli) into .agents/skills/mendix-vega-charts in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add mendixlabs/mxcli --skill mendix-vega-charts -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/mendix-vega-charts, .gemini/skills/mendix-vega-charts, .github/skills/mendix-vega-charts and .opencode/skills/mendix-vega-charts in your project.
Going by SKILL.md and its folder, Mendix Vega Charts needs JavaScript for the scripts in its folder and the command-line tools its instructions call (npm and node). Our summary lists: Node.js.
SKILL.md contains no URLs. Its commands use npm, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Mendix Vega Charts is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 4.2k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Mendix Vega Charts: Vega-Lite Interactive Charts (oaustegard/claude-skills, 150 stars), Chart Visualization (bytedance/deer-flow, 83k stars), Makepad Widgets (sickn33/agentic-awesome-skills, 47k stars) and Working With Charts (PostHog/posthog, 40k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
mendixlabs (a GitHub organization) maintains it in mendixlabs/mxcli, which has 128 GitHub stars. The repository holds 72 skills in this directory. The repository was last updated on October 7, 2026.
Source: mendixlabs/mxcli on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.