12ui CLI

12ui 0.2.134 · @12ui/design

12ui is the local face of the hosted API. It installs the agent skills, holds your API key, and runs corpus search, image generation, conversion, and export from a shell or from inside an agent's terminal. It ships in the npm package @12ui/design and installs a pinned binary named 12ui.

This page documents CLI 0.2.134 - the version badge above shows the release the installers currently serve, the changelog at the end of this page lists the last five releases, and the full changelog records every release.

Install

The ChatGPT plugin is an optional alternative.

Install plugin

With Node on macOS, Linux, or Windows:

npx -y @12ui/design skill install

Or the npm-free installer for macOS and Linux:

curl -fsSL https://12ui.com/install.sh | sh

Either route installs the 12ui-design skill, pins the CLI, and needs no account (hosted commands ask for a 12ui sign-in when used); both need Node 22.13 or newer. The installer write-probes configured XDG data paths first, then ~/.local, then a private TMPDIR-scoped session root. It prints the exact data root and launcher, labels temporary files and PATH exports as session-only, and keeps any npm cache it creates under the selected writable data root rather than assuming ~/.npm. On Windows the normal locations are %APPDATA%\npm\12ui.cmd and %LOCALAPPDATA%\12ui. Installs are atomic and roll back on failure, and an unrecognised 12ui launcher already on disk is refused rather than replaced. See the skill page for what the skill does.

CLI only

For the binary without the agent skills:

npx -y @12ui/design cli install
curl -fsSL https://12ui.com/install-cli.sh | sh

Both install or update the pinned CLI alone - same SHA-256-verified bundle, same paths, same atomicity, rollback, and refusal to replace an unrecognised launcher - and they write no skills and open no browser. Re-running reports the CLI is already current, and each run points at 12ui auth login to connect an account and 12ui skill install for the full agent setup. npx -y @12ui/design cli install still downloads the pinned release into the managed directory rather than leaving the ephemeral npx copy in place, so the 12ui on your PATH is a verified, stable install. Take this route for a shell or CI that only needs the binary; take the full setup above when an agent should get the skills too.

Usage

12ui auth      login | connect | status | logout
12ui skill     install | status | print | remove
12ui cli       install | status
12ui update
12ui workspace open | draw | runner stop
12ui corpus    inspire | resume
12ui draft     --concept <text> [--candidates 2-16]
12ui next      <run-dir or run-id> [--wait]
12ui review    <run-dir> | --all
12ui branch    execute | resume
12ui prototype <branch-run-dir>
12ui redesign  <url> --direction <text>
12ui improve   <url or image> [--apply]
12ui convert   <image, layerdoc, or conversion id>
12ui convert   package
12ui export    <run-dir or output-dir> --output <format>
12ui resume    <conversion-id or local run-dir>
12ui spend
12ui scene     init | solve | ... (12ui scene --help)
12ui workflow  prepare | execute | ... (12ui workflow --help)
12ui capabilities
12ui mcp

12ui --help prints this usage on stderr and exits 0, and 12ui <command> --help adds that command's purpose, behavior, safety guidance, next steps, and full invocation - including forms the summary leaves out (convert package --template, skill print, skill remove). 12ui --version (or 12ui version) prints the installed package version. Bare 12ui is not a help command - it falls through to convert, which refuses and names what was missing.

Flags are long-form only: --name value, never -n (the scene tools also accept --name=value). --dry-run, --force, --help, --json, --quiet, --skip-auth, --template, --version, and --wait take no value; every other advertised flag consumes the next argument and errors if one is missing. Every command accepts --origin <url> and --api-key <key> to override the stored configuration, and --quiet to silence progress.

The conversion commands stream stage progress to stderr with an expected duration, because a command that prints nothing for four minutes reads as a hang - and a retry buys the work twice. --quiet silences the progress lines; stdout stays machine-readable either way.

Draft keeps every candidate dispatch request in the foreground, then returns with generation owned server-side. Run 12ui next <run-dir> --wait to repair any recorded slots that never started, poll, and download. branch execute and branch resume keep every network request in the foreground through terminal status. convert also blocks because its result is the command's own output.

There is one status surface: 12ui next <run-dir | run-id>, which dispatches on the shape of its argument and answers for a hosted draft, a branch run, or a conversion. A bare read never dispatches work. For a recorded draft, --wait idempotently dispatches only pending slots, then blocks with a heartbeat and downloads successful images; settled effects are never bought again.

Review stored work

12ui review <run-dir> starts an ephemeral localhost server, prints its URL, and opens it in the browser. Use 12ui review --all to find automatic draft workspaces in the current system temp directory and runs under the current project's .12ui directory. It never listens on a network interface. An explicit directory is searched for draft, branch, and conversion markers, so it may be the run itself or a parent containing several stored runs.

The review page places draft candidates side by side, shows branch screens and exported HTML pages, opens a branch prototype, and renders conversion output. These are the CLI's existing local-state conventions: automatic drafts use system-temp 12ui-* directories with draft.json and candidates/ (src/draft-workspace.ts); branch output uses <run-dir>/branch/{screens,pages,prototype} (src/branch-run-record.ts); commands append artifact paths to <workspace>/journal.jsonl (src/run-journal.ts); and conversions write beside their input unless --out-dir selects a workspace (src/cli-convert-command.ts).

Save writes the item's note and optional Pick or Approve mark atomically to <run-dir>/review.json with mode 0600. Reloading the page reads that file again. Agents can consume its stable shape directly:

{
  "version": 1,
  "updatedAt": "2026-08-21T01:23:45.000Z",
  "items": {
    "draft-candidate-a-0123abcd": {
      "feedback": {
        "note": "Keep the hierarchy and reduce the footer.",
        "mark": "pick",
        "updatedAt": "2026-08-21T01:23:45.000Z"
      },
      "edits": [{
        "id": "edit-0123abcd",
        "prompt": "Change the heading to Northstar notes.",
        "createdAt": "2026-08-21T01:25:00.000Z",
        "editOperationId": "edit-operation-id",
        "renderOperationId": "render-operation-id",
        "original": "screen.layerdoc.json",
        "layerdoc": "review/edits/edit-0123abcd.layerdoc.json",
        "html": "review/edits/edit-0123abcd.html"
      }]
    }
  }
}

Item keys are stable hashes of their item kind and run-relative path. mark is "pick", "approve", or null; edits is absent until one succeeds.

When a reviewed item is a LayerDoc and conversion credentials are configured, Apply submits the typed text request to the existing POST /api/v1/edit endpoint and puts the edited fixed render beside the original. The button states the price and one click applies it; the page never edits automatically. Design edits use the weekly allowance when available or cost $0.03, and an explicitly requested image action can add $0.02-$0.30. Successful edited LayerDocs and fixed HTML renders are stored under <run-dir>/review/edits/ and recorded in the same review.json item.

Every completed branch with HTML has an explicit Prototype action. It runs the same post-export pipeline as 12ui prototype; review never starts it on page load. A prototype holding page offers Fill this gap only when credentials are configured. The button states $0.48+: $0.03 for one Standard preserve-structure image claim, $0.45 for its Standard HTML conversion, plus the cheap per-screen label calls when the prototype is rebuilt. The original branch evidence stays immutable; the filled page and updated plan live in a private prototype source overlay, with a durable receipt beside it.

VariableEffect
TWELVE_UI_API_KEYAPI key, used ahead of the stored credential file.
TWELVE_UI_ORIGINAPI origin. Defaults to https://12ui.com. Must be a bare HTTP(S) origin with no path, query, or fragment.
TWELVE_UI_CONFIGExact path to the credential file.
XDG_CONFIG_HOMECredential directory root. Defaults to ~/.config.
XDG_DATA_HOMEPinned-CLI and launcher root. Defaults to ~/.local/share plus ~/.local/bin.
CODEX_HOMEAn extra Codex profile home to install skills into.

Authentication

Keys are personal and carry two scopes: design.convert for conversion and edit endpoints, and design.corpus.retrieve for corpus, hosted draft, and branch endpoints. A verified key is stored mode-0600 at $XDG_CONFIG_HOME/12ui/credentials.json or ~/.config/12ui/credentials.json. If those private locations are unusable and TWELVE_UI_CONFIG is not explicit, the same mode-0600 file is stored at $TMPDIR/12ui-<uid>/config/credentials.json, the CLI reports that exact path as environment-lifetime storage, and later commands in the same managed environment rediscover it. Credentials are never written into the workspace; an explicit TWELVE_UI_CONFIG remains authoritative and fails loudly when unusable.

12ui auth login

Opens the browser device-approval page, mints a personal key, verifies it, and stores it. Prints the credential file path. Note that auth login asks for design.convert only - use skill install when you also need hosted draft and branch access, since it requests whichever scopes the selected skills need. Corpus search works without a key; a key with design.corpus.retrieve uses the larger account allowance.

FlagDescription
--api-key <key>Import an existing key instead of opening a browser.
--key-name <name>Label recorded on the minted key.
--login-origin <url>Override the identity origin used for approval and revocation.
--origin <url>Override the API origin recorded with the credential.

TWELVE_UI_API_KEY is imported the same way --api-key is, which makes CI setup a single environment variable.

12ui auth connect CODE

Exchanges the one-time code shown after signing in at /connect-cli, verifies the personal credential, and stores it through the same private credential path as browser approval. The code works once and expires after 15 minutes. This is the paste-back path when a sandbox cannot mint a coded approval link directly.

12ui auth status

Verifies the stored key against each supported scope and prints the account id, credential id, granted scopes, and origin. When the key includes design.convert it also prints the live quota snapshot from /api/v1/convert/quota. Add --json for one machine-readable object; --login-origin <url> overrides the identity origin. Errors when no credential is configured.

12ui auth logout

Revokes the key upstream, then deletes the local credential file. Accepts --login-origin <url>.

Skills

One skill ships in the package: 12ui-design. It covers reference search, drafting, branching, and conversion. The former canonical name design and the four stage skills that used to ship beside it are retired; skill install removes a recognized old copy while preserving locally modified files.

Six clients are supported: Codex, Claude Code, Grok, Cursor, Antigravity, and Copilot. Omit --client and the CLI discovers every installation it can find, including every ~/.codex* profile and CODEX_HOME when it points somewhere else. The skill is written to <client home>/skills/12ui-design. --client <name> targets one client, and --home <dir> overrides that client's home - it requires --client, because a custom home cannot be discovered.

12ui skill install

Installs or updates the skill, pins the CLI, enables each skill in the Codex profile config, retires recognised legacy installations, and sets up credentials. Reports installed, replaced, or already current per target, so re-running it is the supported way to update.

FlagDescription
--skill <name>Name the skill explicitly. 12ui-design is the only value.
--client <name>codex, claude-code, grok, cursor, antigravity, or copilot. Omit to target every detected installation.
--home <dir>Client home override. Requires --client.
--api-key <key>Import a key instead of opening the browser.
--key-name <name>Label recorded on the minted key.
--login-origin <url>Override the identity origin.
--forceReplace skill directories whose contents are unrecognised or locally modified.
--skip-authInstall without any credential step. Cannot be combined with --api-key.

12ui-design needs both design.convert and design.corpus.retrieve, and only those scopes are requested. Credentials are committed last: if any earlier step fails, a freshly minted key is revoked rather than left behind.

12ui skill status

Prints each target's state - not_installed, current, or different - plus whether Codex has the skill enabled, and whether credentials are configured and where. It compares files on disk and makes no network calls, so it reports that a credential file exists without verifying the key. --json emits the same report as one object.

12ui skill print

Writes one skill's SKILL.md to stdout. Requires --skill.

12ui skill remove

Removes the selected skill directories from the selected targets and reports what was and was not there. Credentials are retained, so a later reinstall needs no new sign-in.

CLI installation

12ui cli manages the pinned binary on its own, with no skills and no credential step. It is the update path for an install made with npx -y @12ui/design cli install or curl -fsSL https://12ui.com/install-cli.sh | sh.

12ui cli install

Installs or updates the pinned CLI - the launcher at ~/.local/bin/12ui and its versioned bundle under ~/.local/share/12ui - and nothing else. Re-running is idempotent and reports that the CLI is already current. Finishes by pointing at 12ui auth login and 12ui skill install.

12ui cli status

Prints the pinned version, the launcher path, and the data root, or reports that no managed CLI is installed. --json emits the same report as one object.

Corpus

12ui corpus inspire

One free Design Corpus query, with or without an API key. Downloads the full reference images in parallel, verifies each one, and writes a content-hashed manifest into a new output directory. Anonymous callers get 1,000 queries per UTC week; authenticated callers get 2,000. Search never uses wallet credit. Limits of 30 queries and 120 reads per minute apply per network address. Use Direct, Balanced, or Adventurer without a key; Hedge requires account authentication and is also free.

12ui corpus inspire \
  --query "Editorial architecture homepage with warm materiality" \
  --mode balanced \
  --count 4 \
  --out-dir ./references
FlagDescription
--query <text>The concept to search. Exactly one of this or --query-file.
--query-file <file>Read the query from a file.
--out-dir <dir>Required. Must not already exist.
--mode <mode>direct, balanced, adventurer, or hedge. Defaults to balanced. hedge requires account authentication and cannot be combined with --reference-image.
--count <n>1 to 24 references anonymously, or 1 to 48 with a key. Defaults to 4.
--reference-image <file>PNG, JPEG, or WebP added to the query for one image-and-text search. Forwarded ephemerally, never persisted. Pair it with --mode direct, balanced, or adventurer.
--idempotency-key <key>Stable key for replaying the same free search.

balanced is the standalone search default and weighs relevance, quality, and variety evenly. direct stays close to the literal query, and adventurer follows the query's most distinctive directions. For authenticated callers, hedge returns an evidence-bearing ranked slate built to spread the first references across distinct directions while holding the query; preserve its returned order. Hedge cannot use --reference-image, so choose direct, balanced, or adventurer for an image-conditioned search. The modes are locked server-side. The retired --kind, --wildness, --seed, and --aspect flags now fail with an explicit message rather than being ignored.

Before dispatch the CLI writes inspire-attempt.json with the exact request and its idempotency key. A completed run also holds manifest.json, inspire-evidence.json with the upstream response, the numbered reference files, and a digest receipt per image under .reference-receipts/. Command output is JSON: the set id, mode, seed, output directory, manifest path, and references.

12ui corpus resume

Finishes an interrupted inspire in the same output directory, reusing the attempt's idempotency key. The service returns the original stored response or reports it still pending, without repeating the retrieval. Takes --out-dir <dir>. Use this after a transport error or a failed image download instead of running another search.

Design run

Draft makes a hosted round of candidate images: which reference steers which candidate, how the service run and slots are identified, where the run lives, and when each real image is downloaded. A user choosing among new designs starts a Design workspace from a brief instead: 12ui workspace open --concept "<brief>" --wait, or the Codex app's workspace.

12ui draft

The candidate step. One free corpus search, one hosted /api/v1/create run, and one service-owned image effect per candidate slot. Hosted generation uses its existing allowance or prepaid wallet credit.

12ui draft --concept "Editorial architecture studio homepage for independent practices" --candidates 4

It creates a resumable run directory under the system temp root and prints that path as its first line. It searches the corpus in hedge mode with no flag - one reference per candidate slot, spread across distinct directions while holding the concept - pairs one reference with each stable hosted slot, claims one run, records draft.json, and keeps every pending-slot dispatch request in the foreground. In-flight, succeeded, and failed slots are durable service states and are never posted again. Add --wait, or follow with 12ui next <run-dir> --wait, to poll and download successful PNGs into candidates/.

The hosted service owns the image provider and its paid-effect ledger. The caller authenticates with the 12ui credential only; draft never reads a Codex session, OPENAI_API_KEY, or project .env.

FlagDescription
--concept <text>Required, 1-20,000 characters. The product, audience, surface, goal, and personality.
--candidates <2-16>Number of hosted slots. Defaults to four.
--corpus-mode <mode>direct, balanced, adventurer, or hedge. Defaults to hedge, one reference per candidate slot. The others retrieve the wider twelve-reference slate.
--reference <path-or-url>An existing design to lead from. Conditions the corpus search, which then runs balanced: the corpus refuses a hedge query that carries an image, so --corpus-mode hedge with it is refused at the flag.
`--redesign-source <pngjpeg
`--mode exploratoryreskin`
--aspect <aspect>landscape, portrait, or square. Defaults to landscape.
--waitBlock until the hosted slots settle and their images download instead of returning.

The run directory holds references/ with corpus evidence, draft.json with the hosted run and stable slots, draft.dispatch.json with the owning foreground process, candidates/A-P.png as requested, and draft.complete.json with image digests and byte counts.

12ui next

12ui next <run-dir | run-id> is the one surface for "what is happening and what do I do". It takes one argument and works out whether it names a draft directory, a branch directory, a crt- hosted run, a conversion id, or a journal-backed workspace.

It reports state from durable local and hosted records, elapsed time against what is typical, and one next command. A bare invocation is read-only. For a draft directory, --wait refreshes the exact hosted run id recorded in draft.json, repairs only pending slots, and never replaces settled work.

--wait blocks with a heartbeat until the run is terminal, which removes the need to invent a sleep loop. --json prints the record alone, with no human line.

Branch

12ui branch grows one approved design into the rest of a surface: the server plans the screens, and the CLI dispatches them in dependency order, downloads them in page order, and converts each whole page as one package.

12ui branch execute

One foreground command for the entire choreography. It holds the owning execution channel through every network request and returns at terminal status.

12ui branch execute \
  --start <run-dir>/candidates/A.png \
  --concept "Studio marketing site for independent architects" \
  --scope page \
  --convert html \
  --prototype

--start names the approved PNG, JPEG, or WebP explicitly. A draft candidate is just a local image, so no selection record or separate generation command stands between approval and branching. Branch creates a unique run directory when --out-dir is omitted and keeps its records under branch/, with per-page HTML in branch/pages/ and an optional clickable artifact in branch/prototype/.

FlagDescription
--start <file>Required. The approved PNG, JPEG, or WebP to expand.
--concept <text> / --concept-file <file>Required. Counted after whitespace collapses. Say what the surface must cover and leave the visual decisions to the model.
`--scope pagesite`
--out-dir <dir>Optional run directory. Omit it to create and print a unique temporary directory.
--convert htmlAlso submit the terminal package conversions, one per page. Omit to stop at downloaded PNGs.
--prototypeAfter HTML export, build and runtime-verify a clickable prototype. Requires --convert html.
--polishOpt in to the retained deterministic, harm-guarded polish rules between prototype build and runtime verification. Requires --prototype.
--convert-model <model>fast, standard, or pro for the package. Requires --convert.
--convert-quality <q>standard or pro responsive quality. Requires --convert html.
--source-conversion-id <id>Reuse an existing succeeded conversion of the winner as viewport 1 of the first page instead of buying it twice.
--max-screens <n>Trim the returned plan to the first n screens in plan order.
--idempotency-key <key>Override the derived run key. Normally omitted.
--dry-runPrint the derived run key and resolved inputs. No network call, no spend.
--waitBlock until the whole run finishes. Off by default.
--quietSilence the progress lines on stderr.

The claim runs the planner inline in 10 to 20 seconds and buys no image. Each screen then costs up to about 2.5 minutes - the server's provider budget - and continuations of one page are serial because each continues the previous. Budget about 10 to 14 minutes for --scope page and 15 to 25 for --scope site, plus about 6 minutes per page conversion.

Dispatch is unkeyed on purpose: an unkeyed repeat replays a settled screen for free, while a new key on a settled slot buys another image. The run key, each redraw key, and each package key are derived, never hand-written.

The out-dir holds branch.attempt.json (written before any spend, and refused if one already exists so only --resume may proceed), branch.plan.json, branch.progress.json, screens/<slot>.png materialized atomically at the end, pages/<page-id>.html when converting, and branch.complete.json. That last file is the sentinel: written once at a terminal state with every slot's status, hash, and byte count, every blocked slot and the failure that blocked it, and each page's package and conversion ids. Its absence means the run is still going, never that it failed.

With --prototype, the post-export stage separates application states, canonicalizes shared shells, derives navigation from branch.plan.json, preserves real page content, and creates honest holding pages for planned routes that have no export yet. One cheap product-provider call labels ambiguous controls on each exported screen with the strict four-way schema navigate | dropdown | modal | none; deterministic links, forms, and plan edges win when facts conflict. Add --polish explicitly to apply the 11 retained deterministic rules after build; a harm-guarded proposal that is unsafe is reverted and logged, and the runtime gates consume the polished copy. The polish report, manifest, and run journal retain per-rule fired, silent, and reverted counts. Missing HTML or plan, legacy viewport ids, and runtime failures stop publication. Any safe action demotion, holding page, skipped shell transplant, shell size residual, or untested script direction remains a warning or degradation and measured fact in proto-manifest.json.

A failed screen is settled, paid work. Every screen downstream of it is marked blocked with the cause named, and the run reaches a terminal state instead of polling for something that can never arrive. Some screens failing parks the run rather than failing it: whole pages are still converted and the gaps are reported.

12ui branch resume

Continues an interrupted run from the recorded inputs: 12ui branch resume <run-dir>.

Follow a branch run with 12ui next <run-dir>. It accepts either the draft run directory or the branch directory inside it, reports the per-slot tally, how long the current screen has been generating against its typical duration, and every blocked slot. It reads the local snapshot and refreshes from the service when credentials are available, so it still answers offline.

12ui prototype

Builds the same clickable artifact for an existing, terminal branch run that already has exported HTML:

12ui prototype <run-dir> [--polish]

The argument may be the branch directory itself or its parent run directory. The command reads the branch completion and plan, performs one cheap label call per exported screen through the product API, optionally polishes with --polish, replaces branch/prototype/ atomically only after every runtime gate passes, and prints the manifest path, label cost, and warnings as JSON. Playwright's Chromium registry is cache/ms-playwright inside the same XDG, HOME, or session data root selected for the managed CLI. If Chromium is absent, the command stops before labeling and prints the exact version-matched install command; it never downloads a browser on its own. It never claims a new branch screen or converts an image. Repeating it uses stable label keys, so settled calls replay rather than buying duplicate labels.

Convert

12ui convert

Converts one PNG, JPEG, or WebP - or a public LayerDoc v2 JSON file - into any supported output. A finished LayerDoc conversion ID can instead derive several formats at once. The command waits for every requested result and writes it with its signed raster artifacts.

12ui convert ./screen.png --output html --out-dir ./screen

Outputs are layerdoc, html, html_fixed, svg, png, jpg, webp, pdf, psd, pptx, and sketch.

FlagDescription
--output <format>Required.
--model <model>fast, standard, or pro. Defaults to standard. Image input only.
--width <px>Native output canvas width, 1 to 8192; image input is resized proportionally before upload. Image input only.
--responsive-quality <q>standard or pro. Only valid with --output html.
--out-dir <directory>Output directory. Filenames are derived from the input. Defaults to <name>-12ui/ beside the input.
--timeout-ms <ms>Bound the wait. At least 1000. Defaults to the operation's expiry.
--idempotency-key <key>Stable key for the paid request. When omitted, a key is derived from the request and journaled in the output folder, so re-running a command whose answer was lost collects that run instead of buying another.

With Codex ready on this machine, --output html runs in this process on your Codex sign-in, with no 12ui account, and writes editable HTML/CSS and assets without a LayerDoc. On the 12ui service (--engine api, or when Codex is not ready) it writes both the LayerDoc and responsive HTML through one fused request. Several images, top to bottom, are one page: stacked and converted as that page. Derive assets, PNG, JPEG, WebP, PDF, or React from a saved run with 12ui export <run-dir> --output <format> --out-dir <dir>.

12ui convert ./screen.png --output html --out-dir ./screen

The 12ui service path:

12ui convert ./screen.png --output html --out-dir ./screen

The responsive work starts alongside conversion, so the pair finishes in about the same wall time as conversion alone. Leave the blocking command running; progress streams to stderr. If the shell is interrupted after admission, 12ui resume <conversion-id> recovers the original files from the CLI's local purchase record.

12ui convert package

Submits ordered viewports of one or more pages as one package conversion per page, which is what preserves page order and stitching. Converting a stacked page one image at a time loses both.

12ui convert package --manifest ./package.json --out-dir ./pages

The manifest is version 1 with an output, an optional model and responsiveQuality, and a pages array. Each page needs an id and a viewports array; each viewport needs an id and an image path resolved relative to the manifest. Ordinals default to declaration order. A viewport may add sourceConversionId to reuse an already succeeded conversion of exactly those bytes - no upload and no second paid conversion - though the local image is still named so the CLI can prove the bytes.

FlagDescription
--manifest <file>Required.
--out-dir <dir>Required. Refuses to run into a directory that already holds a package result.
--idempotency-key <key>Derived from the manifest bytes and output when omitted.
--timeout-ms <ms>Bound the wait. Defaults to 30 minutes.
--waitBlock until the package finishes. This is the default for convert package, which is a single request.
--quietSilence the progress lines on stderr.

Every viewport of a page must share one width: the CLI checks locally and refuses before spending, because the server rejects a mismatched page at admission after the viewports would already have been paid for. Expect about 5 to 8 minutes for a multi-viewport page at output: html. Results land as <out-dir>/<page-id>.<ext> plus package.result.json naming the package id, each page's conversion id, and each file's digest.

12ui resume

Waits for an existing conversion and downloads it.

12ui resume <conversion-id>

Bare resume uses the original filenames recorded when this CLI bought the conversion; --out-dir keeps those basenames in a different directory. For an older or externally created purchase, the power form --output <format> --out <file> collects one named operation. --timeout-ms applies; --model, --width, --responsive-quality, and --detach are rejected.

Derive from a conversion

Pass a finished LayerDoc conversion ID to convert to derive several formats. The base LayerDoc is downloaded once and requested formats are dispatched concurrently.

12ui convert <source-conversion-id> \
  --output html_fixed,pdf,psd,pptx,sketch \
  --out-dir ./exports \
  --idempotency-key product-exports-v1
FlagDescription
--output <formats>Required. Comma-separated output list.
--out-dir <dir>Required. Created if missing.
--idempotency-key <key>Stable base key. Derived from the source conversion when omitted.
--responsive-quality <q>standard or pro. Defaults to standard.
--timeout-ms <ms>Bound each wait. At least 1000.

The source must be a succeeded layerdoc conversion. Results are named after the format - export.responsive.html, export.fixed.html, export.pdf, and so on. The command refuses before any API request if a selected output, its asset directory, or export-manifest.json already exists, and it writes that manifest with the source digest, stable request evidence, and every result or failure.

Capabilities

12ui capabilities

Prints the machine-readable capability document: accepted inputs and outputs, conversion models, the --width bounds, responsive qualities, duration hints, status commands, and durable journal/receipt contracts. Output is always JSON, so --json is accepted but changes nothing.

MCP server

12ui mcp

Starts the Model Context Protocol server on stdio, exposing the workflow, convert, corpus, status, and workspace tools. design.convert takes imagePath for image input or layerdocPath for LayerDoc v2 JSON, the exact profile object for project outputs, and an optional idempotencyKey. Accepts --origin and --api-key.

Prefer hosted tools and platform-managed sign-in? Connect the six-tool remote MCP server without installing the CLI.

For agents

The skill is plain markdown with a trigger description, so installing it is only a way to put that markdown where an agent will read it; 12ui skill print --skill 12ui-design writes it to stdout. It drives the CLI commands above.

ShapeTriggers onDrives
ExploreNon-trivial UI creation - web, app, or mobile.The Design workspace (12ui workspace open --concept, or the Codex app's workspace): twelve options from sketches, one chosen, then Build this hands the image to 12ui branch execute --start or 12ui convert.
SearchNeeding real references before generating or implementing, or references as the deliverable.12ui corpus inspire for a ranked, diverse reference set.
ConvertTurning a finished PNG, JPEG, or WebP into code or another format.12ui convert to LayerDoc and every derived export, and 12ui convert package for ordered viewports of one page.
BranchAny deliverable larger than one viewport: a full page, a multi-route site, or an app with several states.12ui branch execute - your own Codex (or the 12ui service when Codex is not ready) plans 2 to 8 screens, the CLI dispatches them as their gates clear and converts each page as one package; add --prototype when it should be clickable.

For direct integration, the API page is the contract: the HTTP reference for convert, create, and corpus. The same package exports a typed SDK - TwelveUiConversionClient, TwelveUiCorpusClient, and TwelveUiConversionPackageClient - for Node consumers that would rather not shell out.

Changelog

0.2.134: Hosted convert, create and edit never buy the same work twice after a lost response or interrupted run: they replay their key, wait when the service answers retry: wait, and say whether you were charged. The CLI also works behind HTTP(S) proxies (credentials never printed), in read-only sandboxes and on Windows, and prints one line a day when a newer release exists.

0.2.133: 12ui convert --engine codex no longer fails with "EPERM: operation not permitted, mkdir ~/.cache" inside sandboxed agents: the local Codex runtime cache, and npm cache and logs, now use the first writable of TWELVE_UI_CODEX_RUNTIME_CACHE, XDG_CACHE_HOME or LOCALAPPDATA, ~/.cache, and the temp folder.

0.2.132: Design workspace site suggestions and captions no longer fail on Windows with "EBUSY: resource busy or locked": agent calls wait for the process to exit before the temp folder is removed, removal retries, and a cleanup problem is logged instead of replacing a successful answer.

0.2.131: The CLI no longer shows your agent your Codex plan, credits, usage limits or home-folder paths, and sends only what a design needs: uploads carry no photo metadata or file names, sign-in names the device by platform, normal corpus searches go out without your account key, and improve never reads form values. The SDK's filename input is deprecated and no longer sent.

0.2.130: The 12ui-design skill files carry a trailing blank line so every channel ships the exact bytes of the 1.0.5 Codex plugin, whose skill passed OpenAI's skill check; the Codex plugin template carries the 1.0.5 listing.

0.2.129: Corpus searches recover on their own: a search that gets no answer within 120 s is retried with the same request key instead of waiting five minutes, and a caller's cancel stops the whole download. The Design workspace keeps loading finished options while its page is out of sight, so they are already there when you look. The Codex plugin template carries the 1.0.4 listing, and every local workspace tool declares all four annotation hints.

0.2.128: The 12ui-design skill states its routing rule once and the CLI refusals, help and capabilities match the shipped behaviour: draft and next stop offering a choosing route, a finished draft's next offers branch execute or convert, 12ui convert on an empty directory with --output react names export, and an outdated CLI's message names the command to run.

0.2.127: In Claude Code and the Claude app the 12ui-design skill starts the Design workspace on this computer from the brief (12ui workspace open --concept) even when the hosted design.slate.create tool is listed; the Codex app keeps design.slate.create.

0.2.126: 12ui workspace open --concept starts a Design workspace from a brief: its first round is twelve options in three groups of four, each drawn from its own sketch, and the 12ui-design skill opens it wherever the hosted workspace screen does not show; the workspace page now loads its designs in Claude's browser pane, a round's caption counts its designs, and More defaults to 12 after the first round.

0.2.125: A draw run inside the first seconds after create waits for the workspace to appear before handing its round to the runner, so a host that never shows it gets the workspace page.

0.2.124: A hosted Design workspace opens as a page on this machine when the host never shows it (12ui workspace open <w_…>, and workspace draw --run-dir when no screen showed the request); the Codex-unavailable draw settles every group of a round served in parts.

0.2.123: The release pipeline now deploys a version bump on its own; no CLI behaviour changes.

Earlier releases are in the full changelog.

Paid work is metered the same way whichever surface calls it. See pricing for rates and the free weekly allowance.