Files
figcraft/docs/cli.md
T
BFlatandClaude Opus 5.5 e718518a08 M6: import REST API file JSON: pages, layers, paints, text runs, vectors, auto layout, components (#13)
- New `figcraft_format::rest`: imports the public REST API file JSON (`GET /v1/files/:key`, and
  the nodes endpoint's response) using the published reference only. Pages (name, background,
  flow starting points), the layer tree, names, visibility, lock, opacity, blend mode, masks.
- Geometry from `relativeTransform` (children of groups/booleans checked against
  `absoluteBoundingBox` to settle their space), else absolute bounds + rotation; sizes, corner
  radii (uniform and per corner), smoothing, clip content, constraints, export settings, layout
  grids.
- Paints: solid, linear/radial/angular/diamond gradients (handles map 1:1), image fills (fill,
  fit, tile, stretch, rotation, filters) with bytes from a resolver or a grey placeholder keyed by
  the imageRef; paint opacity, visibility and blend. Strokes: weight, per-side weights, align,
  caps, join, dashes, miter angle. Effects: drop/inner shadow (offset, radius, spread, show behind),
  layer and background blur.
- Vectors from `fillGeometry` (stroke-only vectors use the `strokeGeometry` outline), ellipse arc
  data, stars/polygons, boolean operations. Text: characters, type style (family, style or weight
  + italic, size, line height px/%/auto, letter spacing, case, decoration, alignment, auto resize,
  truncation, paragraph spacing/indent, OpenType flags, links), per-character overrides → styled
  runs (UTF-16 aware), list type.
- Auto layout: direction incl. grid, alignment, padding, gaps, wrap, hug/fixed/fill sizing (legacy
  and per-axis fields), absolute positioning, min/max, grid cells.
- Components and sets with descriptions and property definitions (names lose their `#id`
  suffix); instances of components in the file become instances with their property values and
  listed overrides; outside components and component cycles stay frames. Shared styles are created
  from the layers that use them, named from the metadata.
- Unknown types and fields are skipped with a counted warning list; sizes, depth (256), layer count
  (200,000), path length and list lengths are capped; nothing panics on junk.
- Engine: `file.open` / `file.import` / CLI detect the JSON by content, link imported instances to
  their mains (sources and overrides), read image fills from an `images` folder next to the file,
  never save over the JSON, and return `warnings`. `file.import` now remaps ids across all
  imported pages at once (instances keep their main and layer sources) and brings styles and page
  backgrounds along. `figcraft-cli info` prints load notes.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 03:36:30 +07:00

4.0 KiB
Raw Blame History

figcraft-cli

FigCraft without a window: inspect, export, convert and render documents, run command scripts, list commands, serve MCP and measure performance. Build it with cargo build --release -p figcraft-cli (binary target/release/figcraft-cli).

Bad arguments print usage and exit with code 2; failures exit with 1. The CLI never panics on input.

Subcommands

info <file> [--json]

Pages, node counts, top-level frames (id, type, name, size), style/variable/image counts. Repairs of a damaged file and import warnings go to stderr as note: lines (notes with --json).

Every subcommand that reads a file also takes the public REST API file JSON (the response of GET /v1/files/:key or of its nodes endpoint, written to a .json file): it is imported on the fly. Image fills come from images/<imageRef>.png (or .jpg, …) next to the JSON when present, else a grey placeholder.

$ figcraft-cli info app.figcraft
app.figcraft — App (412 nodes, 6 styles, 12 variables, 3 images)
page 1 "Screens": 380 nodes, 4 top-level
  2 FRAME "Home" 393.0×852.0
  …

export <file> -o <out> [--format png|jpg|svg|webp|pdf] [--scale N] [--page NAME] [--node ID|NAME]

  • <out> is a directory: one file per top-level frame of the page (default the first page), named after the frame (Home.png, Settings.png…); with no frames, one file per top-level layer.
  • <out> has an image extension: one file with the given --node, or the whole page composited.
  • --node takes a layer id (12 or 0:12) or a layer name.
  • The format comes from --format, else <out>'s extension, else png. --scale (default 1, max 64) applies to raster formats.
figcraft-cli export app.figcraft -o exports/ --scale 2
figcraft-cli export app.figcraft -o hero.svg --node "Hero"

convert <in> <out>

By extension. Inputs: .figcraft, .json (FigCraft or REST API file JSON), .svg (becomes vectors), .png/.jpg/.webp/.gif/.bmp (an image layer). Outputs: .figcraft, .json (FigCraft JSON, pretty-printed), .svg, .png/.jpg/.webp (the current page rendered at 1x with its background), .pdf (when PDF export is available).

render <file> -o <out.png> [--scale N] [--page NAME]

The whole page (default the first) with its background, as png, jpg or webp. Large pages are scaled down to fit 16384 px.

run <script.json|script.jsonl> [--in <file>] [--out <file>]

Runs commands in a headless session (a new document, or --in), printing one JSON line per step:

{"command":"frame.create","ok":true,"result":{"id":2},"step":0}

A failing step prints "ok": false with the error and exits with code 1 (nothing is saved). --out saves the result by extension like convert.

Script formats: a JSON array of {"command": id, "params": {...}}, an object {"commands": [...]}, or JSON lines (one step per line; blank lines and // lines are skipped).

[
  {"command": "frame.create", "params": {"preset": "iPhone 16", "x": 0, "y": 0, "name": "Home"}},
  {"command": "node.create", "params": {"type": "text", "parent": 2, "x": 24, "y": 64, "text": "Welcome", "props": {"fontSize": 32}}},
  {"command": "layout.add", "params": {"ids": [2], "direction": "vertical"}}
]

Ids are assigned in order (a new document's first page is 1, so the first layer is 2), which lets a script refer to layers it created.

commands [--json] [--filter TEXT]

Every command with its label, shortcut, undoable flag (*) and parameter docs; --json for machines.

mcp [--attach PORT]

Serve MCP on stdio: headless by default, or attached to a running app started with figcraft --control PORT. See mcp.md.

perf [--shapes N] [--frames N]

Builds a synthetic document (default 20 000 shapes in 200 frames: rectangles, ellipses and text) and times building, a full-page render at 1x, 1920×1080 renders (zoomed in and zoom-to-fit), 10 000 hit tests, save/load, SVG export, node.create through the engine and select-all + move + undo. Use a release build for meaningful numbers.