Commands
Every command, with its arguments. Each runs against a file with facet --doc FILE COMMAND (add --headless for a host of your own, without the app), or against the open window without --doc. facet guide TOOL prints the same for one command.
The table names each argument as facet call TOOL '{json}' takes it; the flag beside it is the command-line form.
build
Create a whole tree in one call: frames with auto layout, text, images, vectors, instances with variants and overrides, component sets and variable references. Returns every node id by layer name.
facet build @screen.json [--sync] [--replace] [--parent ID] [--component] [--preview out.png]
| Argument | Flag | Type | About | |
|---|---|---|---|---|
schema | NODE | required | the tree to build (see the grammar below); a bare node also works | |
parentId | --parent | id | build inside this frame instead of on the page | |
position | {x, y} | page position of the root (default: right of existing content) | ||
convertToComponent | --component | bool | make the root a main component | |
replace | --replace | bool | replace the top-level node of the same name: the new one takes its place, its instances move to the new components with the same names, and the old one is deleted (one undo step) | |
sync | --sync | bool | change the top-level node of the same name in place to match: layers that still match keep their ids, instances and comments; the rest are added or deleted (one undo step) | |
preview | --preview | path | write a PNG of the result (the written node, or the page) |
facet build '{"name": "Card", "width": 320, "padding": 16, "gap": 8, "fill": "#FFFFFF", "cornerRadius": 12, "column": [{"text": "Hello", "font": "Inter 20 700"}, "Plain text"]}'
source
A layer written in the build language, shortest form first: what you would write to build it, ready to edit and send back with build --sync.
facet source NODE [--depth N]
| Argument | Flag | Type | About | |
|---|---|---|---|---|
nodeId | id / name / selector | required | the layer | |
depth | --depth | number | levels of children to include (all by default) |
facet source Card
kit
The document's kit: its font, colors, type presets and parts, as you would write it.
facet kit
pages
The document's pages; "add" makes a page and shows it, "show" shows one by name or id. Builds go to the page showing.
facet call pages
facet call pages '{"add": "Flows"}'
facet call pages '{"show": "Flows"}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
add | name | add a page with this name and show it | ||
show | name / id | show this page |
modify
Change an existing node with the same keys as build; edit named descendants with "$nodes", an instance's layers with "$override" and its variant with "$variant".
facet modify NODE @props.json [--preview out.png]
| Argument | Flag | Type | About | |
|---|---|---|---|---|
nodeId | id / name / selector | required | the node to change: its id, or a layer name or selector that matches exactly one node | |
schema | props | required | keys to set, e.g. {"fill": "#000", "$nodes": {"Title": {"text": "Hi"}}} | |
preview | --preview | path | write a PNG of the result (the written node, or the page) |
facet modify 12 '{"$nodes":{"Title":{"text":"Welcome back"}},"fill":"#F8FAFC"}'
tree
The page structure: ids, names, types, positions and sizes, nested.
facet tree [NODE] [--depth N] [--full]
| Argument | Flag | Type | About | |
|---|---|---|---|---|
nodeId | id | start here instead of the page | ||
depth | --depth | number | levels to expand (default 4) | |
detail | --full | "full" | every node with all its properties, as inspect shows them |
facet tree --depth 2
inspect
Everything about one node in grammar keys: position, size, sizing, layout, look, text, component facts, children.
facet inspect NODE
| Argument | Flag | Type | About | |
|---|---|---|---|---|
nodeId | id | required | the node |
facet inspect 12
find
Nodes matching a selector: Name, "[name^=Card]", "[type=text]", "#12", "Card Title" (descendant), "Card > Title" (child), "A, B". Names may contain spaces ("Card Coil > Photo"); [name="..."] matches one name exactly.
facet find SELECTOR [--in NODE]
| Argument | Flag | Type | About | |
|---|---|---|---|---|
selector | string | required | what to match | |
scope | id | search inside this node only |
facet find '[type=text]' --in 12
components
Component sets (with their variant properties and values in order, first is the default) and main components.
facet components
variables
Create a variable collection with any number of modes, in the document's variables (saved with the file, shown in the Variables window); a value may be {"alias": "Collection/name"}. Reference variables in builds as "@Collection/name|fallback": fills, strokes, gradient stop colors and positions, radius, stroke width, size, gap, padding, opacity (percent), font size, letter spacing, text and visibility stay bound, and set_mode switches a subtree's mode.
facet call variables @tokens.json
| Argument | Flag | Type | About | |
|---|---|---|---|---|
collectionName | string | required | e.g. Theme | |
modes | [string] | e.g. ["Light", "Dark"] (default one mode) | ||
variables | [{name, type, value / values}] | required | type: color, number, string, boolean; values: {Mode: value or {"alias": "Collection/name"}} |
facet call variables '{"collectionName":"Theme","modes":["Light","Dark"],"variables":[{"name":"surface","type":"color","values":{"Light":"#FFFFFF","Dark":"#0F172A"}}]}'
set_mode
Show a subtree in another mode of a collection: every property bound to that collection's variables takes the mode's value.
facet call set_mode '{"nodeId":ID,"collectionName":C,"modeName":M}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
nodeId | id | required | subtree root | |
collectionName | string | required | the collection | |
modeName | string | required | the mode |
facet call set_mode '{"nodeId":"12","collectionName":"Theme","modeName":"Dark"}'
design_system
Variables with their modes, components, and the colors and text styles in use.
facet call design_system
package
Save the design and write it with what it needs into one folder (default: "<name> package" beside it): the .facet document, the project's DESIGN.md, the system it follows at that version, fonts.json naming every family, and a README. Never overwrites a folder.
facet --doc F call package '{"out":"/abs/folder"}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
out | string | the package folder (absolute) |
systems
Design systems in the library (~/.facet/systems): each one's name, version, and absolute paths to its tokens.json (DTCG), DESIGN.md (rules) and folder. They are plain files; read and edit them directly.
facet call systems
system
One system (default: the one this file's project follows, named in the header of the DESIGN.md beside it): version, file paths, rules, published versions.
facet call system '{"name":"Acme"}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
name | string | system name |
system_create
Make a system from this file: its tokens as tokens.json, the project's DESIGN.md (or a starter) as the system's rules, version 1.0.0; the project then follows it.
facet call system_create '{"name":"Acme","description":"..."}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
name | string | required | system name | |
description | string | one line about it |
facet call system_create '{"name":"Acme"}'
system_use
Bring a system's tokens into this file (collections, modes, aliases, text, paint and shadow styles; existing ones update) and make the project follow it. Run it again after editing the system's files to take the changes.
facet call system_use '{"name":"Acme","version":"1.2.0"}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
name | string | system (default: the one followed) | ||
version | string | a published version (default: the files as they are) |
facet call system_use '{"name":"Acme"}'
system_save
Write this file's tokens to its system's tokens.json (unpublished until system_publish).
facet call system_save
| Argument | Flag | Type | About | |
|---|---|---|---|---|
name | string | system (default: the one followed) |
system_publish
Record the system's files as a new version (major, minor, patch or an explicit 1.2.0) under versions/; a project that follows it moves to that version.
facet call system_publish '{"bump":"minor"}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
name | string | system (default: the one followed) | ||
bump | string | major, minor (default), patch or a version |
facet call system_publish '{"bump":"patch"}'
lint
Check the page against the design rules in DESIGN.md beside the file (colors, radii and spacing from tokens, text styles, fonts): the rules file's path, its rules and every layer that breaks one (main components and instance overrides; what instances show unchanged is not reported twice). Run it after edits.
facet call lint
duplicate
Copy nodes; a copy sits right of its source. Optional "name" and "mode": {collectionName, modeName} for a themed copy.
facet call duplicate '{"nodeIds":[ID],"name":"Copy"}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
nodeIds | [id] | required | nodes to copy | |
name | string | name of the copy | ||
mode | {collectionName, modeName} | show the copy in this mode | ||
preview | path | write a PNG of the result (the written node, or the page) |
facet call duplicate '{"nodeIds":["12"],"name":"Login Dark","mode":{"collectionName":"Theme","modeName":"Dark"}}'
delete
Delete nodes and their children.
facet call delete '{"nodeIds":[ID]}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
nodeIds | [id] | required | nodes to delete |
facet call delete '{"nodeIds":["14"]}'
move
Move layers into another frame (or onto the page with "parentId": null) at a child index (default: last, on top). Layers keep their place on the canvas unless the new parent's auto layout places them; absolute layers stay absolute.
facet call move '{"nodeIds":[ID],"parentId":FRAME,"index":0}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
nodeIds | [id] | required | layers to move, in order | |
parentId | id / null | the new parent frame (default and null: the page) | ||
index | number | child index in the new parent (0 is the bottom of the stack and the start of a flow) |
facet call move '{"nodeIds":["14"],"parentId":"12","index":0}'
script
Run JavaScript (the body of an async function) over the same tools, as ONE call: canvas.build({...}), canvas.find({selector}), canvas.call(TOOL, args) and plugin-style nodes (facet.currentPage.findOne(...), node.fills = [...], facet.createFrame()). If it throws, everything it did is rolled back; otherwise it is one undo step. --read-only always rolls back. No file, network or clock access; timers run instantly in order. facet guide script lists the API.
facet script @file.js [--read-only] [--input JSON] [--timeout-ms N]
| Argument | Flag | Type | About | |
|---|---|---|---|---|
script | string | required | the code; return gives the result, await works | |
readOnly | --read-only | bool | roll back every change at the end (inspections and measurements) | |
input | --input | any JSON | a value the script reads as canvas.input | |
timeoutMs | --timeout-ms | number | time limit (default 30000, at most 120000) |
facet script 'const card = facet.currentPage.findOne(n => n.name === "Card"); card.resize(320, card.height); return card.width;'
paint_styles
Create paint styles: each one solid color, bound to a color variable when given as "@Collection/name|#fallback". Apply with "$fillStyle" or "$strokeStyle". A name that exists is kept ("reused": true); "update": true gives it the new color instead.
facet call paint_styles '{"styles":[{"name":"Brand/Accent","fill":"@Brand/accent|#2563EB"}]}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
styles | list | required | [{"name", "fill"}] | |
update | bool | redefine styles that exist (layers using them update) |
facet call paint_styles '{"styles":[{"name":"Brand/Accent","fill":"#2563EB"}]}'
effect_styles
Create effect styles from "effects" lists (drop-shadow, inner-shadow, blur, background-blur, as in build). Apply with "$effectStyle". A name that exists is kept; "update": true redefines it and every layer following it updates.
facet call effect_styles '{"styles":[{"name":"Elevation/Card","effects":[...]}]}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
styles | list | required | [{"name", "effects"}] | |
update | bool | redefine styles that exist (layers using them update) |
facet call effect_styles '{"styles":[{"name":"Elevation/Card","effects":[{"type":"drop-shadow","y":4,"blur":12,"color":"#0000001A"}]}]}'
text_styles
Create text styles from text keys (fontFamily, fontWeight or fontStyle, fontSize, lineHeight, letterSpacing). Apply with "$textStyle". A name that exists is kept; "update": true redefines it and every text following it updates.
facet call text_styles '{"styles":[{"name":"Body/Strong","fontFamily":"Inter","fontWeight":600,"fontSize":14}]}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
styles | list | required | [{"name", "fontFamily", "fontWeight", "fontSize", ...}] | |
update | bool | redefine styles that exist (texts following them update) |
photos
Search openly licensed photos (Wikimedia Commons, then Openverse): title, web-sized thumbnail URL, size, license, author and page. Place one with "$image": URL, or the best match directly with "$image": "photo:masala chai". Results and photos are cached.
facet call photos '{"query":"masala chai","limit":6}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
query | string | required | what the photo shows | |
limit | number | results (default 6, at most 20) |
facet call photos '{"query":"masala chai","limit":3}'
fonts
Every font family a document can name: those installed here and every Google Fonts family (styles, weights, italics, variable axes, subsets, license, whether it renders here now). Name any of them as fontFamily: one not installed is downloaded and cached before the write measures (FONT_INSTALLED); text in it shows a metric-close stand-in only while it loads. Runs without a host too.
facet fonts list|search QUERY|info FAMILY [--json]
| Argument | Flag | Type | About | |
|---|---|---|---|---|
action | list / search / info | default: info with family, search with query, else list | ||
query | string | search: part of a family name | ||
family | string | info: the family | ||
category | string | list: sans-serif, serif, display, handwriting or monospace | ||
installed | bool | list: only families that render here now | ||
google | bool | list: only Google Fonts families | ||
limit | number | families returned (list 200, search 20) |
facet fonts search 'playfair' && facet fonts info 'Playfair Display'
refresh_images
Re-read and decode every image under a node (or the page) from the document: how many were refreshed, and which layers miss their image.
facet call refresh_images '{"nodeId":ID}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
nodeId | id | subtree (default: the page) |
facet call refresh_images '{"nodeId":"12"}'
project
Create a project (a folder beside the served document), or reuse the one with that name ("reused": true).
facet call project '{"name":"Checkout"}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
name | string | required | project name |
file
Create an empty document in a project (or reuse it); the reply gives its path. Work on it with facet --doc PATH.
facet call file '{"projectId":"Checkout","title":"Cart"}'
| Argument | Flag | Type | About | |
|---|---|---|---|---|
projectId | string | required | project name | |
title | string | required | file name (without .facet) |
projects
Projects beside the served document, with their files.
facet call projects
undo
Revert the latest write call as a whole (however many engine steps it took). If the document changed since, revert one step.
facet undo
redo
Replay the call undo reverted.
facet redo
audit
Layout findings: content a fixed frame clips (LAYOUT_OVERFLOW) and content an edge-pinned bar covers (LAYOUT_OCCLUDED). Every write runs it on what it wrote.
facet audit [NODE]
| Argument | Flag | Type | About | |
|---|---|---|---|---|
nodeId | id | audit this subtree (default: the page) |
facet audit 12
shot
Render nodes (or the page) to PNG, text included. LOOK at it after every write.
facet shot [NODE...] -o out.png [--scale 2] [--padding 0] [--background #FFFFFF]
| Argument | Flag | Type | About | |
|---|---|---|---|---|
nodeIds | [id] | nodes to frame (default: the page) | ||
output | path | required | PNG file to write | |
scale | --scale | number | pixels per unit (default 1) | |
padding | --padding | number | margin in units (default 0) | |
background | --background | color | color under the content (default transparent) |
facet shot 12 -o card.png --scale 2
spec
Handoff: what a node is, its structure, every string, colors, typography, spacing, radii, shadows, instances, images, bound variables and component states.
facet spec NODE
| Argument | Flag | Type | About | |
|---|---|---|---|---|
nodeId | id | required | the node |
facet spec 12
measure
Handoff: layout as data (redlines): sizes, sizing modes, padding, gaps, insets and the space between siblings.
facet measure NODE [--depth N]
| Argument | Flag | Type | About | |
|---|---|---|---|---|
nodeId | id | required | the node | |
depth | --depth | number | levels of children (default 1) |
facet measure 12 --depth 2
tokens
Handoff: variables, or (when there are none) the colors, spacing, radii, shadows and text styles in use, as CSS custom properties, a TypeScript module or JSON.
facet tokens export --format css|ts|json|dtcg [--mode M] [--node ID] [-o FILE]
| Argument | Flag | Type | About | |
|---|---|---|---|---|
format | --format | css / ts / json | required | output format |
mode | --mode | string | one mode of each collection | |
nodeId | --node | id | infer from this subtree only |
facet tokens export --format css -o tokens.css
assets
Handoff: image files, vectors as SVG and the font families in use, with a manifest.json.
facet assets export [NODE] --out DIR
| Argument | Flag | Type | About | |
|---|---|---|---|---|
output | --out | dir | required | folder to write |
nodeId | id | export from this subtree only |
facet assets export 12 --out assets/
guide
This page. Topics: tools, grammar, results, or a tool name.
facet guide [TOPIC]
| Argument | Flag | Type | About | |
|---|---|---|---|---|
topic | string | tools, grammar, results or a tool name |
facet guide build
Everything else
Files, hosts, the app window and behavior charts, as facet --help prints them:
facet: design by command, and drive the visible app
Agents: read `facet guide` first (generated from the tool catalog).
facet --doc FILE build @screen.json [--preview s.png] one call builds a whole tree
facet --doc FILE modify NODE @props.json change a node (and named layers)
facet --doc FILE tree | inspect NODE | find SELECTOR | components | audit [NODE]
facet --doc FILE spec NODE | measure NODE | shot [NODE] -o x.png
facet --doc FILE tokens export --format css|ts|json|dtcg | assets export [NODE] --out DIR
facet --doc FILE undo | redo whole calls
facet --doc FILE call lint layers breaking the rules in DESIGN.md beside FILE
facet --doc FILE call package ['{"out":DIR}'] FILE with its DESIGN.md, system and fonts in one folder
facet [--doc FILE] call systems | system | system_create | system_use | system_save | system_publish
design systems: plain files in ~/.facet/systems/NAME
(tokens.json as DTCG, DESIGN.md); see `facet guide`
facet [--doc FILE] history [list|version NAME|restore REF|diff FROM [TO]] operation log and versions
facet --doc FILE chart import @chart.json | chart FEATURE [--explore] | chart bind|design FEATURE @f.json
facet --doc FILE states COMPONENT | states apply NODE VIEW | plays list|run | replay FEATURE PLAY --at MS
facet --doc FILE lattice FEATURE matrix|flow|designs|replay [--scenario k=v]
facet --doc FILE shot NODE --state VIEW [--scenario k=v] [--design k=v] -o x.png
facet --doc FILE call TOOL '{json}' any tool (variables, set_mode, duplicate, delete, ...)
facet close --doc FILE save and stop the document's host
facet --doc FILE --headless COMMAND own headless host even when the app has FILE open
facet serve FILE [--socket PATH] [--font FILE] run a headless host in the foreground
facet [--doc FILE] mcp the tools as an MCP server on stdio (facet mcp --help)
Open files (registry ~/.facet/docs, app socket ~/.facet/app.sock; --doc FILE uses the app's host when the app has FILE open):
facet files [--json] [--no-ping] every open file: path, kind app|headless, pid, build, socket, lock holder, ping health (ms)
facet app restart [--bundle PATH] save every file, restart the app on the new build (default: its own bundle), reopen
every tab and headless host on the same sockets with the same view; prints both builds
facet open FILE [--socket PATH] [--focus] [--new-window | --no-window]
open FILE in the running app (a tab in the current window, own socket; --new-window: own window; --no-window: headless host), or start the app
facet focus FILE select FILE's tab and bring its app window to the front
facet close FILE [--no-save] close FILE's app window (saves unless --no-save) or stop its headless host
Without --doc (or CANVAS_DOC) commands drive the running app over its control socket:
facet capabilities [--json] | schema [OP] | demo list|open CASE|step|reset|close
facet tour [CASE] [--delay-ms N] | whats-new [--json] | try [FEATURE] [--json]
facet inspect | select ID | drag HANDLE DX DY | zoom FACTOR | pan DX DY
facet duplicate | undo | redo | fit | save | reopen
facet front bring the window to the front (no other command does)
facet send '{"op":"mask","enabled":true,"mode":"outline"}'
facet export --out DIR [--frames] [--settings JSON] [--wait] background job; export status|cancel [JOB]
facet variables [--json] | tokens [--mode NAME] [-o OUT.json] | tokens import FILE.json [--json]
facet bench [--samples N] [--json]
facet renderer exact|tiles draw every frame exactly, or compose in tiles
facet smoothness [--reset] [--frames] [--json] presented frame rate, dropped frames, input latency, drawn jerk, flicker
facet smoothness --oracle arm [--stride N] [--max-frames N] | stop | clear
facet smoothness --oracle [--evidence DIR] [--threshold T] [--headless] [--json] compare captured frames with references at rest
Without any host:
facet render DOC -o OUT.png [--view content|saved] [--node ID] [--zoom Z] [--scale S] [--padding P] [--background #RRGGBB[AA]]
facet export DOC --out DIR [--page P] [--node ID]... [--frames] [--format png|jpg|svg|pdf] [--size 2x|512w|512h] [--suffix S] [--text outlines|text]
facet export DOC --pdf OUT.pdf [--page P]
facet tokens DOC [--mode NAME] [-o OUT.json]
facet chart CHART.json|DIR [--explore] [--json] a chart file's report (scr-kit interchange)
facet guide [TOPIC] [--json]
facet fonts list|search QUERY|info FAMILY|fetch FAMILY...|refresh [--json] installed and Google Fonts families
Global: --doc FILE, --socket PATH, --headless, --json; every command takes --help. Agent results print on stdout,
`facet: warning:` and `facet: note:` lines on stderr. Exit 0 = completed, 2 = invalid input or
unavailable, 3 = failed or unknown outcome (nothing changed for agent tools). No automatic retries.
Coordinates for drag, pan and pointer commands are canvas-local logical screen pixels; drag handles:
south_east, east, north_west, north, north_east, south, south_west, west, rotate.