figura-cli 0.8.2 → 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/README.md +1 -1
- package/dist/index.js +73 -73
- package/package.json +1 -2
- package/skills/fig/SKILL.md +61 -0
- package/skills/figura-fig/SKILL.md +0 -273
- package/skills/figura-fig/reference/brand-tokens.md +0 -115
- package/skills/figura-fig/reference/examples.md +0 -106
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "figura-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Command-line client for the Figura visualization SaaS",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
"node": ">=20"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
|
-
"gen-skill": "bun run scripts/gen-skill-reference.ts",
|
|
32
31
|
"build": "bun run scripts/bundle-skill.mjs && bun build src/index.ts --target=node --minify --outfile=dist/index.js && bun build ../mcp/src/index.ts --target=node --minify --outfile=dist/mcp.js",
|
|
33
32
|
"dev": "bun run src/index.ts",
|
|
34
33
|
"prepublishOnly": "bun run build"
|
|
@@ -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,273 +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
|
-
<!-- GENERATED — do not edit by hand. Source of truth: packages/core/src/fig/* via
|
|
9
|
-
packages/cli/scripts/gen-skill-reference.ts (run `bun run gen-skill`). -->
|
|
10
|
-
|
|
11
|
-
# Figura Fig
|
|
12
|
-
|
|
13
|
-
Generate ONE self-contained, on-brand HTML fig and persist it to the user's Figura team.
|
|
14
|
-
It renders with the **team's brand profile** (their design tokens). When the team hasn't set
|
|
15
|
-
a brand, Figura is brand-neutral by construction — render with clean, modern, accessible
|
|
16
|
-
**neutral defaults**, never another company's brand.
|
|
17
|
-
|
|
18
|
-
The argument (`$ARGUMENTS`) is what to visualize, e.g. "the settings screen with a sticky
|
|
19
|
-
save bar" or "the pricing page".
|
|
20
|
-
|
|
21
|
-
## Prerequisites
|
|
22
|
-
|
|
23
|
-
The user needs the `figura` CLI installed once…
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
curl -fsSL https://figura.so/install.sh | bash # or, with a runtime: bun add -g figura-cli / npm i -g figura-cli
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
…and an authenticated session, established once:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
figura login
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
`figura login` opens a short browser authorize page — a **device flow**, so there's no
|
|
36
|
-
token to paste, no localhost port, and it works over SSH. Approve there and the CLI writes
|
|
37
|
-
the credential to `~/.figura/config.json` (it also honors the `FIGURA_TOKEN` env var for
|
|
38
|
-
CI/headless). **Never mint or fabricate a token yourself.**
|
|
39
|
-
|
|
40
|
-
If the CLI is missing or the user isn't logged in, you'll hit it at the **persist** step
|
|
41
|
-
([§4](#4-persist-and-optionally-publish-to-the-figura-team)) — handle it there: guide them
|
|
42
|
-
through install / `figura login`, then retry. (If `figura` isn't on PATH, use
|
|
43
|
-
`bunx figura-cli` in its place everywhere below.)
|
|
44
|
-
|
|
45
|
-
## Workflow
|
|
46
|
-
|
|
47
|
-
### 0. New fig or a revision?
|
|
48
|
-
|
|
49
|
-
Decide this first. If the request **iterates on an existing or just-made fig** — "make
|
|
50
|
-
the earlier settings screen darker", "tweak that pricing page", "same screen but landscape"
|
|
51
|
-
— it's a **REVISION**: jump to [§4b](#4b-persist-a-revision) instead of creating a new fig.
|
|
52
|
-
Otherwise fall through and create a new fig as normal. When genuinely unsure, default to a
|
|
53
|
-
new `fig create`.
|
|
54
|
-
|
|
55
|
-
**Resolve the prior fig id** (priority order):
|
|
56
|
-
|
|
57
|
-
1. The id printed by a `fig create`/`fig revise` earlier **in this session** — use it directly.
|
|
58
|
-
2. An id, a `*.figura.so` URL, or a slug the **user pasted/named** — extract the id from it.
|
|
59
|
-
3. Otherwise list and match: `bunx figura-cli fig list --json` (optionally `--area <area>`),
|
|
60
|
-
then match by title / area / tags / recency. If **more than one** plausibly matches, ASK
|
|
61
|
-
(cite id + title) — never silently revise the wrong fig.
|
|
62
|
-
|
|
63
|
-
**Fetch the prior HTML** so you can edit on top of it rather than regenerating from scratch:
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
bunx figura-cli fig open <priorFigId> --print
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
This round-trips the stored document to stdout. Apply the user's change on top of it,
|
|
70
|
-
keeping the brand tokens and overall structure stable.
|
|
71
|
-
|
|
72
|
-
### 1. Resolve the brand + platform
|
|
73
|
-
|
|
74
|
-
**Fetch the team's brand profile first:**
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
bunx figura-cli brand --json
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
This returns `{ name, appDescription, tokensBlock, forbidden, surfaces, isCustom }`
|
|
81
|
-
(`forbidden` is a string, `surfaces` is a string[]).
|
|
82
|
-
|
|
83
|
-
- If **`isCustom: true`** — treat the returned `tokensBlock` as the **design system that
|
|
84
|
-
wins conflicts** (palette, type, spacing, icon language) and render for `name` /
|
|
85
|
-
`appDescription`. If anything in the request conflicts with the design system, the design
|
|
86
|
-
system takes priority. Never invent off-brand values.
|
|
87
|
-
- If **`isCustom: false`** (no brand set) — render with **neutral defaults**: read
|
|
88
|
-
`reference/brand-tokens.md` (next to this file). It is a clean, brand-neutral baseline —
|
|
89
|
-
understated and professional, NOT any specific company's look.
|
|
90
|
-
|
|
91
|
-
**Honor the team's guardrails and surfaces** (they complete the brand the same way the
|
|
92
|
-
engine's own generator does):
|
|
93
|
-
|
|
94
|
-
- **`forbidden`** (when non-empty) — treat it as **HARD BRAND GUARDRAILS — never do these**.
|
|
95
|
-
Whatever it lists, never violate it in the generated HTML. These override any default
|
|
96
|
-
styling instinct; if a guardrail conflicts with the request, keep the guardrail.
|
|
97
|
-
- **`surfaces`** (when non-empty) — the product's known surface/IA list (e.g.
|
|
98
|
-
`feed, settings, onboarding`). Use it to ground the fig in the product's real structure
|
|
99
|
-
instead of inventing an unrelated information architecture; prefer the surface that matches
|
|
100
|
-
the requested screen/area.
|
|
101
|
-
|
|
102
|
-
**Pick the platform** from the request:
|
|
103
|
-
|
|
104
|
-
- **`mobile`** (default) — an iPhone app screen.
|
|
105
|
-
- **`web`** — a browser-framed web/desktop UI (a marketing page, dashboard, SaaS screen).
|
|
106
|
-
Choose this when the product is a website/web app rather than a phone screen.
|
|
107
|
-
|
|
108
|
-
Optionally skim `reference/examples.md` for worked prompt → output pairs.
|
|
109
|
-
|
|
110
|
-
### 2. Confirm scope (only if ambiguous)
|
|
111
|
-
|
|
112
|
-
- **area** — the part of the product this screen belongs to (e.g. `feed`, `profile`,
|
|
113
|
-
`settings`, `onboarding`, or `other`). It's a free-form hint that grounds the design; pick
|
|
114
|
-
what the prompt implies.
|
|
115
|
-
- **orientation** — `landscape` / `portrait` / `both` (mobile only; web is responsive).
|
|
116
|
-
|
|
117
|
-
Pick what the prompt implies; confirm only if you genuinely can't.
|
|
118
|
-
|
|
119
|
-
### 3. Generate the HTML
|
|
120
|
-
|
|
121
|
-
Produce ONE complete, self-contained HTML document. Whatever the platform, it MUST:
|
|
122
|
-
|
|
123
|
-
- Start at `<!DOCTYPE html>` — a full document, inline CSS only (one `<style>` in `<head>`).
|
|
124
|
-
- Contain **NO `<script>` tags** and **NO `on*` event handlers**. Fully static; it renders
|
|
125
|
-
its state with CSS alone (it runs in a sandboxed iframe).
|
|
126
|
-
- Use the resolved brand's tokens for all color/type/spacing — never invent off-brand values.
|
|
127
|
-
- Represent every icon as **inline stroke SVG** via `<symbol>`/`<use>` (currentColor,
|
|
128
|
-
width ~1.6) — **NO emojis anywhere**.
|
|
129
|
-
- Set `<title>` to a short screen name, include `<meta name="figura:context" content="…">`
|
|
130
|
-
(one-line design-intent summary), and an `<h1>` naming the screen.
|
|
131
|
-
|
|
132
|
-
**Mobile platform — FRAMLESS device screen.** Render the **screen contents only, at EXACTLY
|
|
133
|
-
the device's logical screen size, with NO drawn phone bezel / outer border / rounded outer
|
|
134
|
-
frame / notch or Dynamic-Island cutout** — the Figura viewer draws the physical device frame
|
|
135
|
-
+ Dynamic Island around your output, so a fig fits a real phone 1:1.
|
|
136
|
-
|
|
137
|
-
- Portrait: render at **393×852** logical px. Landscape: **852×393**.
|
|
138
|
-
- Lock the body to that size and fill it edge-to-edge (no outer page padding):
|
|
139
|
-
`body { margin:0; width:393px; height:852px; background:#0A0A0A; overflow:hidden; }` (swap W/H for landscape).
|
|
140
|
-
- Reserve the OS-chrome safe areas: keep the top ~59px (status bar / Dynamic
|
|
141
|
-
Island) and bottom ~34px (home indicator) clear of critical controls
|
|
142
|
-
(landscape: top ~59px, bottom ~21px).
|
|
143
|
-
- **Emit `<meta name="figura:artboard" content="393x852">`** (the exact W×H you
|
|
144
|
-
rendered to) so the viewer can frame it. A `.preview` media area is OPTIONAL — include it
|
|
145
|
-
only if the design calls for a hero/media region, sized to the design (any aspect ratio).
|
|
146
|
-
- Hand-roll controls with the pill/capsule convention (see `reference/brand-tokens.md`); do
|
|
147
|
-
not rely on system/OS chrome.
|
|
148
|
-
|
|
149
|
-
(`compare` and `both` are multi-screen comparison layouts — render each screen at the size
|
|
150
|
-
above on a canvas that grows to fit them all, and do NOT emit a single `figura:artboard` meta.)
|
|
151
|
-
|
|
152
|
-
**Web platform** — render a **browser window** instead (no phone frame):
|
|
153
|
-
|
|
154
|
-
```
|
|
155
|
-
.frame-web { width: 980px; max-width: 100%; border: 1px solid #2a2a2c; border-radius: 12px; overflow: hidden; }
|
|
156
|
-
.frame-web .bar { display: flex; gap: 8px; align-items: center; height: 40px; padding: 0 14px; }
|
|
157
|
-
.frame-web .dot { width: 12px; height: 12px; border-radius: 50%; } /* r/y/g window controls */
|
|
158
|
-
.frame-web .urlbar { flex: 1; height: 22px; border-radius: 6px; } /* address pill */
|
|
159
|
-
.frame-web .viewport { /* full-bleed RESPONSIVE content — nav, hero, sections */ }
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
**Hard rules (apply to every fig):**
|
|
163
|
-
|
|
164
|
-
- NO emojis anywhere. Represent every icon as inline stroke SVG via <symbol>/<use> (currentColor, width ~1.6).
|
|
165
|
-
- Plain HTML + INLINE CSS ONLY (a single <style> in <head>). No external stylesheets, no fonts loaded over the network, no frameworks.
|
|
166
|
-
- ABSOLUTELY NO <script> tags and NO on* event handlers (onclick, onload, etc.). The fig must be fully static and render its state with CSS alone. It runs in a sandboxed iframe.
|
|
167
|
-
|
|
168
|
-
**Visual quality (intentional and crafted — never generic "AI" UI):**
|
|
169
|
-
|
|
170
|
-
- Color: 3–5 colors total, drawn from the design system — one primary, 2–3 neutrals, 1–2 accents; never exceed 5. If you override a background color, also override its text color for contrast.
|
|
171
|
-
- Type: at most 2 font families (headings + body). No decorative fonts for body. Clear hierarchy.
|
|
172
|
-
- NEVER add filler decoration: no gradient circles, blurry blobs, or abstract shapes as ornament. Avoid gradients unless the design system calls for them; prefer solid colors.
|
|
173
|
-
- Real, specific content (no lorem ipsum, no "Title goes here"). Generous, consistent spacing. A clear visual identity — not a bland gray/white template.
|
|
174
|
-
|
|
175
|
-
### 4. Persist (and optionally publish) to the Figura team
|
|
176
|
-
|
|
177
|
-
**Generating the HTML is not "creating the fig" — the fig only exists once it's saved to the
|
|
178
|
-
user's team and the CLI returns an id.** Always upload the HTML straight to Figura; **never**
|
|
179
|
-
write it to a local file or leave it only in the conversation as the result. Pipe the
|
|
180
|
-
generated document into the CLI over stdin:
|
|
181
|
-
|
|
182
|
-
```bash
|
|
183
|
-
cat <<'HTML' | bunx figura-cli fig create \
|
|
184
|
-
--title "Settings — account & notifications" \
|
|
185
|
-
--area settings \
|
|
186
|
-
--orientation portrait \
|
|
187
|
-
--tags settings,toggles \
|
|
188
|
-
--publish
|
|
189
|
-
<!DOCTYPE html>
|
|
190
|
-
… the generated document …
|
|
191
|
-
HTML
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
**If the upload fails because the user isn't authenticated** — a 401, "No Figura token", or
|
|
195
|
-
"token validation failed" — they haven't logged in. Run `figura login` (the browser device
|
|
196
|
-
flow from [Prerequisites](#prerequisites)), then **retry the same `fig create`**. Don't
|
|
197
|
-
report the fig as done and don't fall back to writing the HTML to a local file — it isn't a
|
|
198
|
-
fig until the persist succeeds and returns an id. (Same for a missing CLI: point them at the
|
|
199
|
-
install one-liner, then retry.)
|
|
200
|
-
|
|
201
|
-
- `--publish` (recommended when the user wants to share it) flips the fig public and returns
|
|
202
|
-
a **shareable `*.figura.so` URL**. It requires an active subscription (any paid tier); on a
|
|
203
|
-
free team the CLI reports the fig is saved privately. Omit `--publish` to keep the fig
|
|
204
|
-
private to the team.
|
|
205
|
-
- Do NOT use `--file` or `mktemp`/temp files — stream the HTML via stdin so no local copy is
|
|
206
|
-
left behind.
|
|
207
|
-
- `--title` matches the `<title>`; `--area` / `--orientation` are the confirmed facets;
|
|
208
|
-
`--tags` is a short comma-separated list.
|
|
209
|
-
- The token resolves automatically from `FIGURA_TOKEN` or `~/.figura/config.json`.
|
|
210
|
-
|
|
211
|
-
The command prints the result as JSON. When published it includes the shareable `url` —
|
|
212
|
-
surface that to the user. To publish a fig created earlier: `bunx figura-cli fig publish <id>`.
|
|
213
|
-
|
|
214
|
-
### 4b. Persist a revision
|
|
215
|
-
|
|
216
|
-
When the request iterates on an existing fig (resolved in [§0](#0-new-fig-or-a-revision)),
|
|
217
|
-
persist the updated HTML as a **new linked version** with `fig revise <priorFigId>`:
|
|
218
|
-
|
|
219
|
-
```bash
|
|
220
|
-
cat <<'HTML' | bunx figura-cli fig revise <priorFigId> \
|
|
221
|
-
--title "Settings — darker theme" \
|
|
222
|
-
--tags settings,toggles,dark \
|
|
223
|
-
--publish
|
|
224
|
-
<!DOCTYPE html>
|
|
225
|
-
… the full updated document …
|
|
226
|
-
HTML
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
- `revise` creates a NEW row on the SAME root chain with an incremented `version` — it does
|
|
230
|
-
NOT edit the prior fig in place. `<priorFigId>` is a positional argument.
|
|
231
|
-
- `--area` / `--orientation` are **inherited from the parent** unless you override them — a
|
|
232
|
-
refine keeps the same surface. Pass the same Create options otherwise (`--title`, `--tags`,
|
|
233
|
-
`--publish`).
|
|
234
|
-
- The result JSON includes `id`, `version`, and `rootFigId`. Surface it as
|
|
235
|
-
"revision vN of \<root\>" plus the shareable URL when `--publish` was used.
|
|
236
|
-
- To inspect the chain: `bunx figura-cli fig revisions <id>` (any id in the chain; oldest to
|
|
237
|
-
newest).
|
|
238
|
-
|
|
239
|
-
### 4c. Request a teammate's feedback
|
|
240
|
-
|
|
241
|
-
When the user wants a specific person to look at a fig — "I want Adam's feedback on this",
|
|
242
|
-
"get Sara's eyes on it", "ask Maya to review this" — request feedback on the fig. The teammate
|
|
243
|
-
gets a notification (in-app bell, web push, email) and the discussion happens in the fig's
|
|
244
|
-
comment thread on Figura. Use the fig id from this session (the one you just created/revised),
|
|
245
|
-
or resolve it via [§0](#0-new-fig-or-a-revision) first.
|
|
246
|
-
|
|
247
|
-
```bash
|
|
248
|
-
bunx figura-cli fig request-feedback <figId> --from "Adam" --note "does the empty state read right?"
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
- `--from` is the teammate by **name or email**, resolved within your team. If it's ambiguous
|
|
252
|
-
or not found, the CLI says so — relay that and ask the user to clarify (or invite them first).
|
|
253
|
-
- `--note` is optional; pass along whatever the user wants reviewed.
|
|
254
|
-
- This is the entry point for "tell Claude Code → teammate notified → chat on the figura page".
|
|
255
|
-
Report the teammate asked + the fig URL it prints.
|
|
256
|
-
|
|
257
|
-
### MCP fast path
|
|
258
|
-
|
|
259
|
-
If a `figura` **MCP server** is connected, prefer its tools over shelling out to the CLI:
|
|
260
|
-
|
|
261
|
-
- New fig → `figura_create_fig` (fields: html, title, area, orientation, tags, `publish`).
|
|
262
|
-
- **Revision** of an existing fig → `figura_revise_fig` (fields: `id`, html, title?, tags?,
|
|
263
|
-
area?, orientation?, `publish`?) — mirrors how `figura_create_fig` is preferred for new figs.
|
|
264
|
-
- Inspect the chain → `figura_list_revisions` (field: `id`).
|
|
265
|
-
- **Request a teammate's feedback** → `figura_request_feedback` (fields: `id`, `from`, `note?`).
|
|
266
|
-
|
|
267
|
-
Prefer the MCP tools when available; fall back to the CLI otherwise.
|
|
268
|
-
|
|
269
|
-
## Output
|
|
270
|
-
|
|
271
|
-
Report back the persisted fig — the shareable URL if published, otherwise that it was saved
|
|
272
|
-
privately to the team — plus a one-line description of what was rendered. Do not paste the
|
|
273
|
-
full HTML into the conversation unless the user asks to see it.
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
# Figura Fig — neutral default tokens (no team brand set)
|
|
2
|
-
|
|
3
|
-
<!-- GENERATED — do not edit by hand. Source of truth: packages/core/src/fig/* via
|
|
4
|
-
packages/cli/scripts/gen-skill-reference.ts (run `bun run gen-skill`). -->
|
|
5
|
-
|
|
6
|
-
Use this baseline ONLY when `figura brand --json` returns `isCustom: false` (the team
|
|
7
|
-
hasn't set its own brand). It is a clean, modern, accessible, brand-NEUTRAL default — never
|
|
8
|
-
any specific company's look. The moment a team sets tokens, use those instead.
|
|
9
|
-
|
|
10
|
-
Keep it understated and professional.
|
|
11
|
-
|
|
12
|
-
## Colors (neutral defaults — keep to ONE accent)
|
|
13
|
-
|
|
14
|
-
| Role | Value | Usage |
|
|
15
|
-
|------|-------|-------|
|
|
16
|
-
| Canvas | `#0A0A0A` | Near-black base background (the fig screen). |
|
|
17
|
-
| Surface | `#161618` | Cards / raised surfaces. |
|
|
18
|
-
| Text | `#F4F4F6` | Primary text. |
|
|
19
|
-
| Text muted | `#9aa0ad` | Secondary text, captions. |
|
|
20
|
-
| Hairline | `rgba(255,255,255,.10)` | 1px borders / dividers. |
|
|
21
|
-
| Accent | `#4C8DFF` | ONE calm blue accent — primary actions, active state, focus. |
|
|
22
|
-
|
|
23
|
-
No more than one accent hue. No decorative gradients unless the prompt asks. Status tints
|
|
24
|
-
only when genuinely needed: amber `#E8A33D` (warn), green `#3ee07a` (success), error `#ff5f57`.
|
|
25
|
-
|
|
26
|
-
## Type
|
|
27
|
-
|
|
28
|
-
System / neutral sans only — declare stacks, never load fonts over the network:
|
|
29
|
-
|
|
30
|
-
| Role | CSS stack |
|
|
31
|
-
|------|-----------|
|
|
32
|
-
| Sans (everything) | `Inter, -apple-system, BlinkMacSystemFont, system-ui, sans-serif` |
|
|
33
|
-
| Mono (numbers/code) | `ui-monospace, SFMono-Regular, 'JetBrains Mono', monospace` |
|
|
34
|
-
|
|
35
|
-
Clear hierarchy: ~13px body, semibold headings, generous line-height.
|
|
36
|
-
|
|
37
|
-
## Spacing & shape
|
|
38
|
-
|
|
39
|
-
An 8px spacing rhythm; 12–16px corner radii; 1px hairline borders; restrained shadows.
|
|
40
|
-
|
|
41
|
-
## Icon language
|
|
42
|
-
|
|
43
|
-
Inline SVG icons — define <symbol> elements in a hidden <svg> at the top of <body> and reference with <use href="#id"/>. Stroke icons (currentColor stroke, width ~1.6). NO emojis anywhere.
|
|
44
|
-
|
|
45
|
-
## Framless iPhone screen — CSS conventions
|
|
46
|
-
|
|
47
|
-
Mobile figs are **FRAMLESS**: render the screen contents ONLY, at the device's exact logical
|
|
48
|
-
screen size, with **NO drawn phone bezel / outer border / rounded outer frame / notch or
|
|
49
|
-
Dynamic-Island cutout** — the Figura viewer draws the physical device frame + island around
|
|
50
|
-
your output, so a fig fits a real phone 1:1. Lock the body to the screen size and emit a
|
|
51
|
-
`<meta name="figura:artboard" content="WxH">` with that size.
|
|
52
|
-
|
|
53
|
-
| Orientation | Logical screen | Safe area top | Safe area bottom |
|
|
54
|
-
|-------------|----------------|---------------|------------------|
|
|
55
|
-
| Portrait | 393×852 | 59px | 34px |
|
|
56
|
-
| Landscape | 852×393 | 59px | 21px |
|
|
57
|
-
|
|
58
|
-
**Reset + body (lock to the screen size, fill edge-to-edge):**
|
|
59
|
-
|
|
60
|
-
```css
|
|
61
|
-
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
62
|
-
body { margin: 0; width: 393px; height: 852px; background: #0A0A0A; color: #F4F4F6; font-family: Inter, -apple-system, BlinkMacSystemFont, system-ui, sans-serif; overflow: hidden; } /* swap W/H for landscape */
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
**Screen surface + OPTIONAL media area** (include `.preview` only if the design needs a
|
|
66
|
-
hero/media region — size it to the design, any aspect ratio; there is no fixed film ratio):
|
|
67
|
-
|
|
68
|
-
```css
|
|
69
|
-
.screen { position: absolute; inset: 0; background: #0A0A0A; color: #F4F4F6; overflow: hidden; }
|
|
70
|
-
.preview { position: absolute; background: #18181b; } /* optional media/hero region */
|
|
71
|
-
.scrim { position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(0,0,0,.45), transparent 22%, transparent 70%, rgba(0,0,0,.55)); }
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
**Capsule chrome — pill controls, count badge (all fully rounded):**
|
|
75
|
-
|
|
76
|
-
```css
|
|
77
|
-
.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; }
|
|
78
|
-
.tool-tabs { position: absolute; display: inline-flex; gap: 4px; background: rgba(0,0,0,.5); border-radius: 999px; padding: 3px 4px; }
|
|
79
|
-
.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; }
|
|
80
|
-
.tool-tabs span.on { background: rgba(255,255,255,.92); color: #111; font-weight: 700; width: auto; padding: 0 7px; }
|
|
81
|
-
.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 */
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
**Annotation chips — yellow callouts pinned over the screen (label intent):**
|
|
85
|
-
|
|
86
|
-
```css
|
|
87
|
-
.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; }
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
**Inline SVG icons:** Inline SVG icons — define <symbol> elements in a hidden <svg> at the top of <body> and reference with <use href="#id"/>. Stroke icons (currentColor stroke, width ~1.6). NO emojis anywhere.
|
|
91
|
-
|
|
92
|
-
## Hard rules (non-negotiable)
|
|
93
|
-
|
|
94
|
-
- Render the screen contents at EXACTLY the chosen orientation's logical size with NO device
|
|
95
|
-
frame/bezel/notch — the Figura viewer draws the physical phone frame around your output.
|
|
96
|
-
- Emit `<meta name="figura:artboard" content="WxH">` with the exact logical screen size.
|
|
97
|
-
- NO emojis anywhere. Represent every icon as inline stroke SVG via <symbol>/<use> (currentColor, width ~1.6).
|
|
98
|
-
- Hand-roll every control with the pill/capsule convention above — do not rely on system/OS
|
|
99
|
-
chrome or platform glass effects.
|
|
100
|
-
- Plain HTML + INLINE CSS ONLY (a single <style> in <head>). No external stylesheets, no fonts loaded over the network, no frameworks.
|
|
101
|
-
- ABSOLUTELY NO <script> tags and NO on* event handlers (onclick, onload, etc.). The fig must be fully static and render its state with CSS alone. It runs in a sandboxed iframe.
|
|
102
|
-
|
|
103
|
-
## Visual quality (intentional and crafted — never generic "AI" UI)
|
|
104
|
-
|
|
105
|
-
- Color: 3–5 colors total, drawn from the design system — one primary, 2–3 neutrals, 1–2 accents; never exceed 5. If you override a background color, also override its text color for contrast.
|
|
106
|
-
- Type: at most 2 font families (headings + body). No decorative fonts for body. Clear hierarchy.
|
|
107
|
-
- NEVER add filler decoration: no gradient circles, blurry blobs, or abstract shapes as ornament. Avoid gradients unless the design system calls for them; prefer solid colors.
|
|
108
|
-
- Real, specific content (no lorem ipsum, no "Title goes here"). Generous, consistent spacing. A clear visual identity — not a bland gray/white template.
|
|
109
|
-
|
|
110
|
-
## Document contract
|
|
111
|
-
|
|
112
|
-
- Respond with ONLY a complete HTML document. Start at <!DOCTYPE html>. No markdown code fences, no backticks, no prose before or after.
|
|
113
|
-
- Set <title> to a short, descriptive fig title.
|
|
114
|
-
- Include a meta tag summarizing the design intent: <meta name="figura:context" content="...">.
|
|
115
|
-
- An `<h1>` naming the screen.
|
|
@@ -1,106 +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 FRAMLESS portrait screen rendered at exactly 393×852 (no drawn phone
|
|
14
|
-
bezel — the viewer frames it), with `<meta name="figura:artboard" content="393x852">`. Inside,
|
|
15
|
-
a `.screen`: a "Settings" header + a search field, then grouped rows (Account, Notifications,
|
|
16
|
-
Privacy) — each row a label + an inline stroke-SVG glyph + a control (chevron, or a CSS-only
|
|
17
|
-
toggle in the accent color). A sticky bottom save bar ("3 unsaved changes" + Save / Discard)
|
|
18
|
-
pinned over the screen, kept clear of the ~34px bottom safe area. No `.preview` media area
|
|
19
|
-
(this screen has none).
|
|
20
|
-
|
|
21
|
-
A `.annot` chip points at the toggles: "active = accent #4C8DFF". `<title>` = "Settings —
|
|
22
|
-
account & notifications"; `<meta name="figura:context">` summarizes the unsaved-changes
|
|
23
|
-
state; `<h1>` reads "Settings".
|
|
24
|
-
|
|
25
|
-
**Persisted (and shared):**
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
cat <<'HTML' | bunx figura-cli fig create \
|
|
29
|
-
--title "Settings — account & notifications" \
|
|
30
|
-
--area settings \
|
|
31
|
-
--orientation portrait \
|
|
32
|
-
--tags settings,toggles,save-bar \
|
|
33
|
-
--publish
|
|
34
|
-
… the generated document …
|
|
35
|
-
HTML
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Then report the returned shareable `url`.
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## Example 2 — "the pricing page, three tiers" (web)
|
|
43
|
-
|
|
44
|
-
**Resolved scope:** platform `web` (a marketing page, not a phone screen).
|
|
45
|
-
|
|
46
|
-
**Generated document:** a `.frame-web` browser window (r/y/g window dots + an address pill)
|
|
47
|
-
around a responsive `.viewport`: a top nav (wordmark + links + a CTA button in the accent),
|
|
48
|
-
a centered headline + subhead, then a 3-column pricing grid — each card a name, price,
|
|
49
|
-
feature list with inline stroke-SVG checks, and a button (the middle/recommended card
|
|
50
|
-
emphasized with the accent border). Neutral near-black canvas, one accent hue, system sans,
|
|
51
|
-
8px rhythm. No phone frame, no fixed aspect ratio — responsive content fills the frame.
|
|
52
|
-
|
|
53
|
-
A `.annot` chip marks the recommended card. `<title>` = "Pricing — three tiers";
|
|
54
|
-
`<meta name="figura:context">` summarizes the comparison; `<h1>` reads "Pricing".
|
|
55
|
-
|
|
56
|
-
**Persisted (private — omit `--publish` to keep it team-only):**
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
cat <<'HTML' | bunx figura-cli fig create \
|
|
60
|
-
--title "Pricing — three tiers" \
|
|
61
|
-
--area other \
|
|
62
|
-
--tags pricing,marketing,web
|
|
63
|
-
… the generated document …
|
|
64
|
-
HTML
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Then report the fig (saved privately, or the shareable `url` if you added `--publish`).
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## Example 3 — "make the earlier settings screen darker" (revision)
|
|
72
|
-
|
|
73
|
-
**Resolved as a revision** (it iterates on a fig from Example 1, not a new screen).
|
|
74
|
-
|
|
75
|
-
**Resolve the prior id:** if the settings fig was created earlier in this session, reuse the
|
|
76
|
-
id it printed. Otherwise list and match by title/area:
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
bunx figura-cli fig list --json --area settings
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
Pick the matching row's `id` (ask if more than one plausibly matches). Then fetch its HTML:
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
bunx figura-cli fig open <priorFigId> --print
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
**Edit on top of it:** keep the same structure (header, grouped rows, sticky save bar) and
|
|
89
|
-
re-tint the surfaces to neutral **dark** values — near-black canvas, raised dark surfaces for
|
|
90
|
-
the cards/rows, light text — keeping the SAME single accent hue for active toggles. Don't
|
|
91
|
-
regenerate from scratch; preserve the design system.
|
|
92
|
-
|
|
93
|
-
**Persist as a new version:**
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
cat <<'HTML' | bunx figura-cli fig revise <priorFigId> \
|
|
97
|
-
--title "Settings — darker theme" \
|
|
98
|
-
--tags settings,toggles,dark \
|
|
99
|
-
--publish
|
|
100
|
-
… the updated document …
|
|
101
|
-
HTML
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
The result JSON includes `version` (e.g. `2`) and `rootFigId`. Report it as "revision v2 of
|
|
105
|
-
\<root\>" plus the shareable `url` if published. `--area`/`--orientation` were inherited from
|
|
106
|
-
the parent, so they didn't need to be passed again.
|