figura-cli 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "figura-cli",
3
- "version": "0.8.1",
3
+ "version": "0.9.0",
4
4
  "description": "Command-line client for the Figura visualization SaaS",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -33,6 +33,7 @@
33
33
  "prepublishOnly": "bun run build"
34
34
  },
35
35
  "devDependencies": {
36
+ "@panofm/figura-core": "workspace:*",
36
37
  "@types/node": "^20.14.0",
37
38
  "axios": "^1.7.9",
38
39
  "postgres": "^3.4.9",
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: fig
3
+ description: "Mock up a screen as an on-brand, shareable HTML fig via your Figura team — render a UI state in seconds before writing the real code. Use when asked to visualize a screen, mock a UI, or 'make a fig'. iPhone-framed by default; browser frame for web/desktop."
4
+ argument-hint: '<what to visualize>'
5
+ allowed-tools: 'mcp__figura__figura_whoami, mcp__figura__figura_generate_fig, mcp__figura__figura_create_fig, Bash(figura *), Bash(bunx figura-cli *)'
6
+ ---
7
+
8
+ # /fig — figure it out before you build it
9
+
10
+ A **fig** is a self-contained HTML mock of one UI state, rendered against your
11
+ Figura team's design system and saved (optionally published with a shareable
12
+ link) to your team's timeline. Build a fig to pressure-test a layout or screen in
13
+ seconds, before writing the real code.
14
+
15
+ This skill is a **thin wrapper over the Figura MCP**. It deliberately carries **no
16
+ brand tokens, colors, fonts, or design rules** — the brand lives in exactly one
17
+ place (your team's Figura brand profile) and is injected server-side. That is the
18
+ whole point: a fig is on-brand *by construction*, and this skill can never drift
19
+ from your brand. To change the brand, use the `figura-brand` skill, not this one.
20
+
21
+ ## When to use
22
+
23
+ - Asked to mock a screen, visualize a UI state, or "make a fig".
24
+ - Before any visual / layout / state change — a wrong fig costs seconds; a wrong
25
+ build costs a recompile-and-screenshot loop.
26
+
27
+ ## How to fig
28
+
29
+ 1. **Check auth** — call **`figura_whoami`** to confirm you're connected to a
30
+ team. Not connected? Tell the user to run `figura login`, or add the MCP:
31
+ `claude mcp add figura -- figura mcp`. (Creating / publishing figs needs the
32
+ `figs:write` scope on the team — a read-only token passes whoami but fails the
33
+ land step.)
34
+
35
+ 2. **Default — build it yourself, with YOUR Claude.** Fetch the team's design
36
+ system — `bunx figura-cli brand --json` — and hand-build the fig's HTML against
37
+ it, then land it with **`figura_create_fig`** (`publish: true`), setting
38
+ `area`, `orientation` (`portrait` / `landscape` / `both`), `mode` (`single` /
39
+ `compare` / `variations`), `title`, and a real description. This uses the
40
+ caller's own Claude (the model running this skill) — no extra cost, full control
41
+ for precise broken-vs-proposed diptychs — and applies the team's brand from the
42
+ fetched design system. **Follow that design system verbatim; never invent brand
43
+ values.** `figura_create_fig` returns a shareable `figura.so/f/<id>` link.
44
+
45
+ 3. **Shortcut — let Figura render it.** Call **`figura_generate_fig`** with a
46
+ natural-language brief (same `area` / `orientation` / `mode` / `title` /
47
+ `publish: true`) when you'd rather not hand-build. Figura renders it server-side
48
+ against the team brand. This is **billed** (a `403` means no active
49
+ subscription); pass **`fidelity: 'high'`** to render on the better model (the
50
+ default `'fast'` is a lighter model — fine for rough states, weaker on brand).
51
+ For best fidelity, prefer the hand-built path above.
52
+
53
+ 4. **Review** the returned link, share it, move on.
54
+
55
+ ## Notes
56
+
57
+ - **MCP unavailable** (headless / cron, or no interactive auth): fall back to the
58
+ CLI — `bunx figura-cli fig create` / `fig publish`, with `fig revise` /
59
+ `fig revisions` for versions, and `bunx figura-cli brand --json` for the brand.
60
+ - **One job, one place.** Brand = the Figura brand profile. Generation = the Figura
61
+ engine. This skill only decides *when* to fig and *which MCP call* to make.
@@ -1,242 +0,0 @@
1
- ---
2
- name: figura-fig
3
- description: "Generate an on-brand, device- or browser-framed HTML fig using your Figura team's design system, save it to your team, and (optionally) publish a shareable link. iPhone frame by default; browser frame for web/desktop UIs. Use when asked to mock up a screen, build a fig, or visualize a UI state."
4
- argument-hint: '<what to visualize>'
5
- allowed-tools: 'Bash(figura *), Bash(bunx figura-cli *)'
6
- ---
7
-
8
- # Figura Fig
9
-
10
- Generate ONE self-contained, on-brand HTML fig and persist it to the user's Figura team.
11
- It renders with the **team's brand profile** (their design tokens). When the team hasn't set
12
- a brand, Figura is brand-neutral by construction — render with clean, modern, accessible
13
- **neutral defaults**, never another company's brand.
14
-
15
- The argument (`$ARGUMENTS`) is what to visualize, e.g. "the settings screen with a sticky
16
- save bar" or "the pricing page".
17
-
18
- ## Prerequisites
19
-
20
- The user needs the `figura` CLI installed once…
21
-
22
- ```bash
23
- curl -fsSL https://figura.so/install.sh | bash # or, with a runtime: bun add -g figura-cli / npm i -g figura-cli
24
- ```
25
-
26
- …and an authenticated session, established once:
27
-
28
- ```bash
29
- figura login
30
- ```
31
-
32
- `figura login` opens a short browser authorize page — a **device flow**, so there's no
33
- token to paste, no localhost port, and it works over SSH. Approve there and the CLI writes
34
- the credential to `~/.figura/config.json` (it also honors the `FIGURA_TOKEN` env var for
35
- CI/headless). **Never mint or fabricate a token yourself.**
36
-
37
- If the CLI is missing or the user isn't logged in, you'll hit it at the **persist** step
38
- ([§4](#4-persist-and-optionally-publish-to-the-figura-team)) — handle it there: guide them
39
- through install / `figura login`, then retry. (If `figura` isn't on PATH, use
40
- `bunx figura-cli` in its place everywhere below.)
41
-
42
- ## Workflow
43
-
44
- ### 0. New fig or a revision?
45
-
46
- Decide this first. If the request **iterates on an existing or just-made fig** — "make
47
- the earlier settings screen darker", "tweak that pricing page", "same screen but landscape"
48
- — it's a **REVISION**: jump to [§4b](#4b-persist-a-revision) instead of creating a new fig.
49
- Otherwise fall through and create a new fig as normal. When genuinely unsure, default to a
50
- new `fig create`.
51
-
52
- **Resolve the prior fig id** (priority order):
53
-
54
- 1. The id printed by a `fig create`/`fig revise` earlier **in this session** — use it directly.
55
- 2. An id, a `*.figura.so` URL, or a slug the **user pasted/named** — extract the id from it.
56
- 3. Otherwise list and match: `bunx figura-cli fig list --json` (optionally `--area <area>`),
57
- then match by title / area / tags / recency. If **more than one** plausibly matches, ASK
58
- (cite id + title) — never silently revise the wrong fig.
59
-
60
- **Fetch the prior HTML** so you can edit on top of it rather than regenerating from scratch:
61
-
62
- ```bash
63
- bunx figura-cli fig open <priorFigId> --print
64
- ```
65
-
66
- This round-trips the stored document to stdout. Apply the user's change on top of it,
67
- keeping the brand tokens and overall structure stable.
68
-
69
- ### 1. Resolve the brand + platform
70
-
71
- **Fetch the team's brand profile first:**
72
-
73
- ```bash
74
- bunx figura-cli brand --json
75
- ```
76
-
77
- This returns `{ name, appDescription, tokensBlock, forbidden, surfaces, isCustom }`
78
- (`forbidden` is a string, `surfaces` is a string[]).
79
-
80
- - If **`isCustom: true`** — use the returned `tokensBlock` as the ground-truth design
81
- system (palette, type, spacing, icon language) and render for `name` / `appDescription`.
82
- Never invent off-brand values.
83
- - If **`isCustom: false`** (no brand set) — render with **neutral defaults**: read
84
- `reference/brand-tokens.md` (next to this file). It is a clean, brand-neutral baseline —
85
- understated and professional, NOT any specific company's look.
86
-
87
- **Honor the team's guardrails and surfaces** (they complete the brand the same way the
88
- engine's own generator does):
89
-
90
- - **`forbidden`** (when non-empty) — treat it as **HARD BRAND GUARDRAILS — never do these**.
91
- Whatever it lists, never violate it in the generated HTML. These override any default
92
- styling instinct; if a guardrail conflicts with the request, keep the guardrail.
93
- - **`surfaces`** (when non-empty) — the product's known surface/IA list (e.g.
94
- `feed, settings, onboarding`). Use it to ground the fig in the product's real structure
95
- instead of inventing an unrelated information architecture; prefer the surface that matches
96
- the requested screen/area.
97
-
98
- **Pick the platform** from the request:
99
-
100
- - **`mobile`** (default) — an iPhone-framed app screen.
101
- - **`web`** — a browser-framed web/desktop UI (a marketing page, dashboard, SaaS screen).
102
- Choose this when the product is a website/web app rather than a phone screen.
103
-
104
- Optionally skim `reference/examples.md` for worked prompt → output pairs.
105
-
106
- ### 2. Confirm scope (only if ambiguous)
107
-
108
- - **area** — the part of the product this screen belongs to (e.g. `feed`, `profile`,
109
- `settings`, `onboarding`, or `other`). It's a free-form hint that grounds the design; pick
110
- what the prompt implies.
111
- - **orientation** — `landscape` / `portrait` / `both` (mobile only; web is responsive).
112
-
113
- Pick what the prompt implies; confirm only if you genuinely can't.
114
-
115
- ### 3. Generate the HTML
116
-
117
- Produce ONE complete, self-contained HTML document. Whatever the platform, it MUST:
118
-
119
- - Start at `<!DOCTYPE html>` — a full document, inline CSS only (one `<style>` in `<head>`).
120
- - Contain **NO `<script>` tags** and **NO `on*` event handlers**. Fully static; it renders
121
- its state with CSS alone (it runs in a sandboxed iframe).
122
- - Use the resolved brand's tokens for all color/type/spacing — never invent off-brand values.
123
- - Represent every icon as **inline stroke SVG** via `<symbol>`/`<use>` (currentColor,
124
- width ~1.6) — **NEVER emoji**.
125
- - Set `<title>` to a short screen name, include `<meta name="figura:context" content="…">`
126
- (one-line design-intent summary), and an `<h1>` naming the screen.
127
-
128
- **Mobile platform** — render an **iPhone device frame** (`.device-port` for portrait,
129
- `.device-land` for landscape) with a dynamic island, per the reference. A `.preview` media
130
- area is OPTIONAL — include it only if the design calls for a hero/media region, and size it
131
- to the design (any aspect ratio). Hand-roll controls with the pill/capsule convention; do
132
- not rely on system/OS chrome.
133
-
134
- **Web platform** — render a **browser window** instead (no phone frame):
135
-
136
- ```
137
- .frame-web { width: 980px; max-width: 100%; border: 1px solid #2a2a2c; border-radius: 12px; overflow: hidden; }
138
- .frame-web .bar { display: flex; gap: 8px; align-items: center; height: 40px; padding: 0 14px; }
139
- .frame-web .dot { width: 12px; height: 12px; border-radius: 50%; } /* r/y/g window controls */
140
- .frame-web .urlbar { flex: 1; height: 22px; border-radius: 6px; } /* address pill */
141
- .frame-web .viewport { /* full-bleed RESPONSIVE content — nav, hero, sections */ }
142
- ```
143
-
144
- ### 4. Persist (and optionally publish) to the Figura team
145
-
146
- **Generating the HTML is not "creating the fig" — the fig only exists once it's saved to the
147
- user's team and the CLI returns an id.** Always upload the HTML straight to Figura; **never**
148
- write it to a local file or leave it only in the conversation as the result. Pipe the
149
- generated document into the CLI over stdin:
150
-
151
- ```bash
152
- cat <<'HTML' | bunx figura-cli fig create \
153
- --title "Settings — account & notifications" \
154
- --area settings \
155
- --orientation portrait \
156
- --tags settings,toggles \
157
- --publish
158
- <!DOCTYPE html>
159
- … the generated document …
160
- HTML
161
- ```
162
-
163
- **If the upload fails because the user isn't authenticated** — a 401, "No Figura token", or
164
- "token validation failed" — they haven't logged in. Run `figura login` (the browser device
165
- flow from [Prerequisites](#prerequisites)), then **retry the same `fig create`**. Don't
166
- report the fig as done and don't fall back to writing the HTML to a local file — it isn't a
167
- fig until the persist succeeds and returns an id. (Same for a missing CLI: point them at the
168
- install one-liner, then retry.)
169
-
170
- - `--publish` (recommended when the user wants to share it) flips the fig public and returns
171
- a **shareable `*.figura.so` URL**. It requires an active subscription (any paid tier); on a
172
- free team the CLI reports the fig is saved privately. Omit `--publish` to keep the fig
173
- private to the team.
174
- - Do NOT use `--file` or `mktemp`/temp files — stream the HTML via stdin so no local copy is
175
- left behind.
176
- - `--title` matches the `<title>`; `--area` / `--orientation` are the confirmed facets;
177
- `--tags` is a short comma-separated list.
178
- - The token resolves automatically from `FIGURA_TOKEN` or `~/.figura/config.json`.
179
-
180
- The command prints the result as JSON. When published it includes the shareable `url` —
181
- surface that to the user. To publish a fig created earlier: `bunx figura-cli fig publish <id>`.
182
-
183
- ### 4b. Persist a revision
184
-
185
- When the request iterates on an existing fig (resolved in [§0](#0-new-fig-or-a-revision)),
186
- persist the updated HTML as a **new linked version** with `fig revise <priorFigId>`:
187
-
188
- ```bash
189
- cat <<'HTML' | bunx figura-cli fig revise <priorFigId> \
190
- --title "Settings — darker theme" \
191
- --tags settings,toggles,dark \
192
- --publish
193
- <!DOCTYPE html>
194
- … the full updated document …
195
- HTML
196
- ```
197
-
198
- - `revise` creates a NEW row on the SAME root chain with an incremented `version` — it does
199
- NOT edit the prior fig in place. `<priorFigId>` is a positional argument.
200
- - `--area` / `--orientation` are **inherited from the parent** unless you override them — a
201
- refine keeps the same surface. Pass the same Create options otherwise (`--title`, `--tags`,
202
- `--publish`).
203
- - The result JSON includes `id`, `version`, and `rootFigId`. Surface it as
204
- "revision vN of \<root\>" plus the shareable URL when `--publish` was used.
205
- - To inspect the chain: `bunx figura-cli fig revisions <id>` (any id in the chain; oldest to
206
- newest).
207
-
208
- ### 4c. Request a teammate's feedback
209
-
210
- When the user wants a specific person to look at a fig — "I want Adam's feedback on this",
211
- "get Sara's eyes on it", "ask Maya to review this" — request feedback on the fig. The teammate
212
- gets a notification (in-app bell, web push, email) and the discussion happens in the fig's
213
- comment thread on Figura. Use the fig id from this session (the one you just created/revised),
214
- or resolve it via [§0](#0-new-fig-or-a-revision) first.
215
-
216
- ```bash
217
- bunx figura-cli fig request-feedback <figId> --from "Adam" --note "does the empty state read right?"
218
- ```
219
-
220
- - `--from` is the teammate by **name or email**, resolved within your team. If it's ambiguous
221
- or not found, the CLI says so — relay that and ask the user to clarify (or invite them first).
222
- - `--note` is optional; pass along whatever the user wants reviewed.
223
- - This is the entry point for "tell Claude Code → teammate notified → chat on the figura page".
224
- Report the teammate asked + the fig URL it prints.
225
-
226
- ### MCP fast path
227
-
228
- If a `figura` **MCP server** is connected, prefer its tools over shelling out to the CLI:
229
-
230
- - New fig → `figura_create_fig` (fields: html, title, area, orientation, tags, `publish`).
231
- - **Revision** of an existing fig → `figura_revise_fig` (fields: `id`, html, title?, tags?,
232
- area?, orientation?, `publish`?) — mirrors how `figura_create_fig` is preferred for new figs.
233
- - Inspect the chain → `figura_list_revisions` (field: `id`).
234
- - **Request a teammate's feedback** → `figura_request_feedback` (fields: `id`, `from`, `note?`).
235
-
236
- Prefer the MCP tools when available; fall back to the CLI otherwise.
237
-
238
- ## Output
239
-
240
- Report back the persisted fig — the shareable URL if published, otherwise that it was saved
241
- privately to the team — plus a one-line description of what was rendered. Do not paste the
242
- full HTML into the conversation unless the user asks to see it.
@@ -1,118 +0,0 @@
1
- # Figura Fig — neutral default tokens (no team brand set)
2
-
3
- Use this baseline ONLY when `figura brand --json` returns `isCustom: false` (the team
4
- hasn't set its own brand). It is a clean, modern, accessible, brand-NEUTRAL default — never
5
- any specific company's look. The moment a team sets tokens, use those instead.
6
-
7
- Keep it understated and professional.
8
-
9
- ## Colors (neutral defaults — keep to ONE accent)
10
-
11
- | Role | Value | Usage |
12
- |------|-------|-------|
13
- | Canvas | `#0E0E10` | Near-black base background. |
14
- | Surface | `#161618` | Cards / raised surfaces. |
15
- | Text | `#F4F4F6` | Primary text. |
16
- | Text muted | `#9aa0ad` | Secondary text, captions. |
17
- | Hairline | `rgba(255,255,255,.10)` | 1px borders / dividers. |
18
- | Accent | `#4C8DFF` | ONE calm blue accent — primary actions, active state, focus. |
19
-
20
- No more than one accent hue. No decorative gradients unless the prompt asks. Status tints
21
- only when genuinely needed: amber `#E8A33D` (warn), green `#3ee07a` (success), error `#ff5f57`.
22
-
23
- ## Type
24
-
25
- System / neutral sans only — declare stacks, never load fonts over the network:
26
-
27
- | Role | CSS stack |
28
- |------|-----------|
29
- | Sans (everything) | `Inter, -apple-system, BlinkMacSystemFont, system-ui, sans-serif` |
30
- | Mono (numbers/code) | `ui-monospace, SFMono-Regular, 'JetBrains Mono', monospace` |
31
-
32
- Clear hierarchy: ~13px body, semibold headings, generous line-height.
33
-
34
- ## Spacing & shape
35
-
36
- An 8px spacing rhythm; 12–16px corner radii; 1px hairline borders; restrained shadows.
37
-
38
- ## Icon language
39
-
40
- Every icon is **inline stroke SVG** via `<symbol>`/`<use>` (`stroke="currentColor"`,
41
- `stroke-width` ~1.6). **NEVER emoji.**
42
-
43
- ## iPhone device frame — CSS conventions
44
-
45
- Reuse these class names + proportions so every mobile fig reads as one house style.
46
-
47
- **Reset + page:**
48
-
49
- ```css
50
- * { box-sizing: border-box; margin: 0; padding: 0; }
51
- body { background: #161618; color: #F4F4F6; font-family: Inter, -apple-system, BlinkMacSystemFont, system-ui, sans-serif; padding: 30px; }
52
- .page { display: flex; flex-direction: column; align-items: center; gap: 14px; }
53
- .row { display: flex; gap: 30px; flex-wrap: wrap; justify-content: center; align-items: flex-start; }
54
- .col { display: flex; flex-direction: column; align-items: center; gap: 11px; }
55
- .col-label { font-size: 11px; letter-spacing: .6px; text-transform: uppercase; color: #9aa0ad; font-weight: 600; }
56
- ```
57
-
58
- **PORTRAIT phone (the common case):**
59
-
60
- ```css
61
- .device-port { position: relative; width: 300px; height: 640px; background: #000; border-radius: 44px; border: 6px solid #2a2a2a; box-shadow: 0 18px 40px rgba(0,0,0,.5), inset 0 0 0 2px #000; overflow: hidden; }
62
- .device-port .island { position: absolute; top: 9px; left: 50%; transform: translateX(-50%); width: 92px; height: 26px; background: #000; border-radius: 15px; z-index: 8; }
63
- ```
64
-
65
- **LANDSCAPE phone (wide window, side island):**
66
-
67
- ```css
68
- .device-land { position: relative; width: 660px; height: 318px; background: #000; border-radius: 44px; border: 6px solid #2a2a2a; box-shadow: 0 24px 50px rgba(0,0,0,.55), inset 0 0 0 2px #000; overflow: hidden; }
69
- .device-land .island { position: absolute; left: 9px; top: 50%; transform: translateY(-50%); width: 26px; height: 96px; background: #000; border-radius: 16px; z-index: 8; }
70
- ```
71
-
72
- **Screen + OPTIONAL media area** (include `.preview` only if the design needs a hero/media
73
- region — size it to the design, any aspect ratio; there is no fixed film ratio):
74
-
75
- ```css
76
- .screen { position: absolute; inset: 0; background: #0E0E10; color: #F4F4F6; overflow: hidden; }
77
- .preview { position: absolute; background: #18181b; } /* optional media/hero region */
78
- .scrim { position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(0,0,0,.45), transparent 22%, transparent 70%, rgba(0,0,0,.55)); }
79
- ```
80
-
81
- **Capsule chrome — pill controls, count badge (all fully rounded):**
82
-
83
- ```css
84
- .time-pill { position: absolute; background: rgba(0,0,0,.55); border-radius: 999px; padding: 4px 11px; font-size: 9.5px; color: #fff; display: inline-flex; gap: 6px; align-items: center; }
85
- .tool-tabs { position: absolute; display: inline-flex; gap: 4px; background: rgba(0,0,0,.5); border-radius: 999px; padding: 3px 4px; }
86
- .tool-tabs span { font-size: 8.5px; color: rgba(255,255,255,.6); width: 18px; height: 18px; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
87
- .tool-tabs span.on { background: rgba(255,255,255,.92); color: #111; font-weight: 700; width: auto; padding: 0 7px; }
88
- .badge { min-width: 15px; height: 15px; padding: 0 4px; background: var(--accent, #4C8DFF); border-radius: 999px; font-size: 9px; font-weight: 700; color: #fff; display: flex; align-items: center; justify-content: center; } /* a quiet count, never a red alarm */
89
- ```
90
-
91
- **Annotation chips — yellow callouts pinned over the frame (label intent):**
92
-
93
- ```css
94
- .annot { position: absolute; font-size: 9px; font-weight: 500; color: #ffe066; background: rgba(0,0,0,.82); border: 1px solid rgba(255,224,102,.45); padding: 3px 6px; border-radius: 4px; pointer-events: none; z-index: 20; max-width: 180px; line-height: 1.3; }
95
- ```
96
-
97
- **Inline SVG icons:** define `<symbol>` elements in a hidden `<svg>` at the top of `<body>`
98
- and reference with `<use href="#id"/>`. Stroke icons (`stroke="currentColor"`,
99
- `stroke-width` ~1.6).
100
-
101
- ## Hard rules (non-negotiable)
102
-
103
- - Lay the screen out to fill the chosen orientation; use whatever media/aspect ratios the
104
- design needs — there is no fixed aspect-ratio requirement.
105
- - NO emojis anywhere. Every icon is inline stroke SVG.
106
- - Hand-roll every control with the pill/capsule convention above — do not rely on system/OS
107
- chrome or platform glass effects.
108
- - Plain HTML + INLINE CSS ONLY (a single `<style>` in `<head>`). No external stylesheets,
109
- no network fonts, no frameworks.
110
- - ABSOLUTELY NO `<script>` tags and NO `on*` event handlers. Fully static; renders state
111
- with CSS alone (runs in a sandboxed iframe).
112
-
113
- ## Document contract
114
-
115
- - Respond with a complete HTML document starting at `<!DOCTYPE html>`.
116
- - `<title>` = short screen name.
117
- - `<meta name="figura:context" content="…">` = one-line design-intent summary.
118
- - An `<h1>` naming the screen.
@@ -1,104 +0,0 @@
1
- # Figura Fig — Examples
2
-
3
- Two worked examples of a prompt → what gets generated and saved. Each produces ONE
4
- self-contained HTML document and persists it to the Figura team via `bunx figura-cli fig create`.
5
- (These use the neutral default tokens; with a custom team brand, swap in its palette/type.)
6
-
7
- ---
8
-
9
- ## Example 1 — "mock up a settings screen with a sticky save bar" (mobile)
10
-
11
- **Resolved scope:** area `settings`, orientation `portrait`.
12
-
13
- **Generated document:** a `.device-port` iPhone frame with a top dynamic-island. Inside, a
14
- `.screen`: a "Settings" header + a search field, then grouped rows (Account, Notifications,
15
- Privacy) — each row a label + an inline stroke-SVG glyph + a control (chevron, or a CSS-only
16
- toggle in the accent color). A sticky bottom save bar ("3 unsaved changes" + Save / Discard)
17
- pinned over the screen. No `.preview` media area (this screen has none).
18
-
19
- A `.annot` chip points at the toggles: "active = accent #4C8DFF". `<title>` = "Settings —
20
- account & notifications"; `<meta name="figura:context">` summarizes the unsaved-changes
21
- state; `<h1>` reads "Settings".
22
-
23
- **Persisted (and shared):**
24
-
25
- ```bash
26
- cat <<'HTML' | bunx figura-cli fig create \
27
- --title "Settings — account & notifications" \
28
- --area settings \
29
- --orientation portrait \
30
- --tags settings,toggles,save-bar \
31
- --publish
32
- … the generated document …
33
- HTML
34
- ```
35
-
36
- Then report the returned shareable `url`.
37
-
38
- ---
39
-
40
- ## Example 2 — "the pricing page, three tiers" (web)
41
-
42
- **Resolved scope:** platform `web` (a marketing page, not a phone screen).
43
-
44
- **Generated document:** a `.frame-web` browser window (r/y/g window dots + an address pill)
45
- around a responsive `.viewport`: a top nav (wordmark + links + a CTA button in the accent),
46
- a centered headline + subhead, then a 3-column pricing grid — each card a name, price,
47
- feature list with inline stroke-SVG checks, and a button (the middle/recommended card
48
- emphasized with the accent border). Neutral near-black canvas, one accent hue, system sans,
49
- 8px rhythm. No phone frame, no fixed aspect ratio — responsive content fills the frame.
50
-
51
- A `.annot` chip marks the recommended card. `<title>` = "Pricing — three tiers";
52
- `<meta name="figura:context">` summarizes the comparison; `<h1>` reads "Pricing".
53
-
54
- **Persisted (private — omit `--publish` to keep it team-only):**
55
-
56
- ```bash
57
- cat <<'HTML' | bunx figura-cli fig create \
58
- --title "Pricing — three tiers" \
59
- --area other \
60
- --tags pricing,marketing,web
61
- … the generated document …
62
- HTML
63
- ```
64
-
65
- Then report the fig (saved privately, or the shareable `url` if you added `--publish`).
66
-
67
- ---
68
-
69
- ## Example 3 — "make the earlier settings screen darker" (revision)
70
-
71
- **Resolved as a revision** (it iterates on a fig from Example 1, not a new screen).
72
-
73
- **Resolve the prior id:** if the settings fig was created earlier in this session, reuse the
74
- id it printed. Otherwise list and match by title/area:
75
-
76
- ```bash
77
- bunx figura-cli fig list --json --area settings
78
- ```
79
-
80
- Pick the matching row's `id` (ask if more than one plausibly matches). Then fetch its HTML:
81
-
82
- ```bash
83
- bunx figura-cli fig open <priorFigId> --print
84
- ```
85
-
86
- **Edit on top of it:** keep the same structure (header, grouped rows, sticky save bar) and
87
- re-tint the surfaces to neutral **dark** values — near-black canvas, raised dark surfaces for
88
- the cards/rows, light text — keeping the SAME single accent hue for active toggles. Don't
89
- regenerate from scratch; preserve the design system.
90
-
91
- **Persist as a new version:**
92
-
93
- ```bash
94
- cat <<'HTML' | bunx figura-cli fig revise <priorFigId> \
95
- --title "Settings — darker theme" \
96
- --tags settings,toggles,dark \
97
- --publish
98
- … the updated document …
99
- HTML
100
- ```
101
-
102
- The result JSON includes `version` (e.g. `2`) and `rootFigId`. Report it as "revision v2 of
103
- \<root\>" plus the shareable `url` if published. `--area`/`--orientation` were inherited from
104
- the parent, so they didn't need to be passed again.