@atlaskit/ads-cli
v0.8.2
Published
An npx-runnable command-line tool to query Atlassian Design System (ADS) structured content — components, tokens, icons, and guidelines — from the terminal.
Readme
@atlaskit/ads-cli
An npx-runnable command-line tool to query Atlassian Design System (ADS) structured content —
components, tokens, icons, and guidelines — directly from your terminal.
npx @atlaskit/ads-cli search buttonIt is a thin, zero-drift layer over the shared @atlaskit/ads-mcp/tools/* exports: the same query
logic that powers the ADS MCP server and the atlassian-design-system agent skill. The CLI never
reimplements search ranking or bundles its own copy of the dataset — there is one source of truth.
Why
Distributing ADS structured content through a CLI lets developers and coding agents query
components from the terminal without configuring an MCP client. Human-readable output is the
default; --json emits a stable, self-describing envelope for machine consumers.
Commands
The CLI has these commands:
| Command | Description |
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| search <query...> | Unified fuzzy-search across components, tokens, icons, and foundations docs at once. Narrow results with --type component\|token\|icon\|docs; limit with --limit N. |
| batch --command <command> [args...]... | Run multiple ADS CLI queries, including different command types, in one process. Repeat --command once per child; each keeps its normal arguments, flags, and response envelope. Tokenized requests are canonical; complete quoted requests are also accepted. |
| component <name> | Detail for a single component. Exact name → detail; ambiguous → a "did you mean?" list. --all lists every component. |
| token <name> | Full detail for a single token, including usage guidelines. Exact name → detail; ambiguous → a "did you mean?" list. --all lists every token as a concise summary. |
| icon <name> | Detail for a single icon (with a copy-paste import). Exact name → detail; ambiguous → a "did you mean?" list. --all lists every icon. |
| lint-rules [term...] | ADS ESLint rules. A term that matches one rule (exactly or uniquely) prints its docs; several matches show a "did you mean?" list. Bare lint-rules prints every rule; --limit N caps the candidate list. |
| docs <topic...> | Read ADS reference docs. Three forms:• docs <term...> — foundations guidelines (spacing, color, …)• docs a11y [topic] — accessibility guidance (optional topic e.g. buttons, forms, colors)• docs migration <id> — a structured migration guide |
| manifest | Describe every command, argument, flag, and JSON response type. Use --json for the machine-readable contract. |
Global flags
--json— emit a machine-readable JSON envelope on stdout.--help,-h— show help.--version,-v— show the CLI version.
Examples
# Unified human-readable search — components, tokens, icons, and docs grouped together
npx @atlaskit/ads-cli search contrast
# Narrow to a single kind
npx @atlaskit/ads-cli search space color --type token
npx @atlaskit/ads-cli search contrast --type docs
# Run multiple queries, including different command types, in one process
npx @atlaskit/ads-cli batch \
--command component Button \
--command component Modal \
--command docs spacing \
--command search contrast --type docs
# Complete-string compatibility form (tokenized input above remains canonical)
npx @atlaskit/ads-cli batch \
--command 'component "Inline Dialog"' \
--command "search contrast" --type docs
# Detail for a single component, token, or icon
npx @atlaskit/ads-cli component Avatar
npx @atlaskit/ads-cli token space.100
npx @atlaskit/ads-cli icon AddIcon
# List every entry of a kind
npx @atlaskit/ads-cli icon --all
# Reference docs — foundations, accessibility, migrations
npx @atlaskit/ads-cli docs spacing
npx @atlaskit/ads-cli docs a11y buttons
npx @atlaskit/ads-cli docs migration motion
# Machine-readable envelope for agents / jq
npx @atlaskit/ads-cli search button --json
# Discover the complete CLI contract
npx @atlaskit/ads-cli manifest --jsonOutput contract
Every command is human-readable by default;
--jsonis the only path to structured output.searchand the--alllistings print one compact line per result (e.g.Avatar @atlaskit/avatar (42 props, 1 example)), and unifiedsearchgroups results intoComponents/Tokens/Icons/Docssections. Everysearchrow includes a follow-up command, such as→ ads-cli component Avataror→ ads-cli docs contrast; this also applies to narrowedsearch --typeoutput. Documentation search results stay concise, whiledocs <query>prints the full matched Markdown.component/token/iconprint a readable detail view (the icon view includes a copy-pasteimportline);docs(foundations,a11y, andmigration) andlint-rulesprint prose/Markdown. A raw JSON dump is only ever a last-resort fallback for an unrecognised shape.Structured output mirrors the human retrieval budget. Search and
--allresponses contain the same compact fields shown by the human rows rather than embedding every component prop and example. Each search record includes a machine-readablefollowUp; run that exact detail command for the full component, token, or icon data. Exact detail commands retain the information shown by their human view, including tokenusageGuidelinesandusage, and an iconimport.manifest --jsonis the intentional exception: it remains the full CLI contract.Lookups never silently guess.
component/token/icon <name>— and a fuzzylint-rules <term>— render the entry whose name matches exactly (case-insensitively). If there is no exact match but several candidates, they print aDid you mean?list (each with a→ ads-cli <command>follow-up) and exit0— under--jsonthis is{ "ambiguous": true, "query", "noun", "candidates": [...] }.Batch commands are independent. Each repeated
--commandstarts a child request. Passing its command and arguments as separate, tokenized argv is the canonical form. A complete quoted request is also accepted, including inner quoting and already-tokenized trailing flags; it is normalized to argv without invoking a shell. Shell operators, pipes, redirects, environment expansion, and command substitution are rejected with a usage error.batchruns valid commands concurrently through the existing command registry in one CLI process. Each item includes its normalized tokenizedrequest, astatus(success,ambiguous, orfailure), and the child command's unchanged success or errorresponseenvelope. A failed or ambiguous child does not discard successful sibling results. A syntactically valid batch exits0; inspect each item's status or nested envelope.Data is written to stdout only. Logs, hints, and errors go to stderr. This keeps
--jsonoutput clean for piping.batchis the one deliberate exception: a child's failure is part of the aggregate result rather than a failure of the batch itself, so per-child errors stay inline on stdout beside theirRequest:heading instead of being split onto stderr.The manifest is derived from the live command registry.
manifest --jsonlists every command, positional argument, flag, example, and success response type without maintaining a separate copy of the CLI surface.With
--json, every success prints a formattedSuccessEnvelopeand every failure prints anErrorEnvelope:// success — unified search groups data by kind { "type": "ads-cli/search", "command": "search", "ok": true, "data": { "components": [ { "name": "Button", "package": "@atlaskit/button", "propCount": 13, "exampleCount": 3, "followUp": "component Button" } ], "tokens": [ { "name": "motion.button.hovered", "exampleValue": "background-color 150ms cubic-bezier(0.4, 1, 0.6, 1)", "followUp": "token motion.button.hovered" } ], "icons": [], "docs": [ { "title": "Button", "summary": "A concise preview of the leading textual content.", "followUp": "docs button" } ] }, "meta": { "terms": ["button"], "count": 12 } } // success — a narrowed (--type) or single-tool command returns a flat array { "type": "ads-cli/search-components", "command": "search", "ok": true, "data": [ { "name": "Avatar", "package": "@atlaskit/avatar", "propCount": 7, "exampleCount": 1, "followUp": "component Avatar" } ], "meta": { "terms": ["avatar"], "limit": 5, "count": 2 } } // success — batch preserves each child command's existing envelope { "type": "ads-cli/batch", "command": "batch", "ok": true, "data": [ { "request": ["component", "Button"], "status": "success", "response": { "type": "ads-cli/component", "command": "component", "ok": true, "data": { /* full Button data */ }, "meta": { "name": "Button" } } }, { "request": ["docs", "missing-topic"], "status": "failure", "response": { "type": "ads-cli/error", "command": "docs", "ok": false, "error": { "code": "NOT_FOUND", "message": "No guidelines found for missing-topic." } } } ], "meta": { "succeeded": 1, "ambiguous": 0, "failed": 1, "count": 2 } } // failure { "type": "ads-cli/error", "command": "search", "ok": false, "error": { "code": "NOT_FOUND", "message": "No ADS components found for 'zzz'." } }The
typediscriminator (ads-cli/<command>orads-cli/error) lets consumers branch without re-parsing.
Exit codes
| Code | Meaning |
| ---- | --------------------------------------------------- |
| 0 | Success. |
| 1 | Unexpected runtime error. |
| 2 | Usage error (invalid arguments or unknown command). |
| 3 | No matching results found. |
Relationship to the ADS MCP server and skill
This CLI, the @atlaskit/ads-mcp server, and the atlassian-design-system agent
skill are all thin surfaces over the same @atlaskit/ads-mcp/tools/* query logic and bundled
ComponentMcpPayload[] dataset. Adding or improving a tool in ads-mcp is automatically reflected
here.
The --json envelope is shared unchanged by the npm and Atlas distributions.
Atlas CLI distribution
The same command surface is available as atlas ads. Its entrypoint delegates directly to run(),
so npm and Atlas share command parsing, output, and exit codes.
Build the self-contained JavaScript bundle from the platform/ directory:
afm workspace @atlaskit/ads-cli build:atlas
node packages/design-system/ads-cli/build/atlas/ads-cli.js search buttonThe .atlas-plugin descriptor declares the ads plugin and the atlas-cli-plugin-ads Statlas
namespace. Every upload fetches manifest.toml from Statlas before adding a release, so the remote
manifest history remains canonical.
Prepare an Atlas-shaped release locally:
VERSION=local-$(git rev-parse --short HEAD) \
afm workspace @atlaskit/ads-cli release:atlas:prepareThis builds 5 variants under build/releases/$VERSION, creates each archive and checksum,
smoke-tests the Linux AMD64 executable when running on Linux AMD64, and adds the release to the
alpha channel in the working manifest.
The ads-cli-build-and-upload-to-statlas custom pipeline runs the tests and typecheck, prepares the
release, uploads all artifacts, then publishes the manifest. Run it from master.
After validating an alpha release, run the ads-cli-promote-stable-version custom pipeline from
master with VERSION_TO_PROMOTE set to its exact version. Promotion updates the canonical remote
manifest without rebuilding or uploading artifacts.
The Statlas namespace authorization and Atlas plugin registry entry are one-time external
prerequisites. Until the registry entry is available, use atlas atlasdev exec to exercise a
packaged binary in the Atlas runtime. The AFM package scripts own the Node.js executable build; the
generic atlas atlasdev plugin build command doesn't drive this package.
