figma-relai 0.7.11 → 0.8.1

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 CHANGED
@@ -61,9 +61,9 @@ The panel's Memory row lists every entry; delete any of them any time. Nothing i
61
61
 
62
62
  **Kits.** One designer usually runs one product, and its files share the same law. Save this file's rules under a name and other files can use it. Figma drops file-carried law on branch merges; the kit puts it back — one click, or automatically if you flip that kit's auto-restore on.
63
63
 
64
- **AI no-go zones** fence off whole pages — brand masters, legal, the one that is already pixel-perfect. Writes through Relai into a guarded page are rejected before they run, with the reason on the receipt. You set them in the panel; an agent can also add or lift one with `manage_pages`, and that command shows in your activity feed like any other. Protected branches, for the canvas.
64
+ **AI no-go zones** fence off whole pages — brand masters, legal, the one that is already pixel-perfect. Writes through Relai into a guarded page are rejected before they run, with the reason on the receipt — commands inside a batch included. The fences are yours: an agent can add one, but a zone you set is lifted only in the panel. The one exception is a zone the agent added itself in the same plugin session, which it may take back. Every change shows in your activity feed. Protected branches, for the canvas.
65
65
 
66
- **Confirmation** is a dial with four stops — OPEN · RISK · BULK · ALL. At RISK, the default, only destructive operations ask (deleting variables or styles, detach, flatten); everything else keeps moving. Set it in the panel; no Relai tool changes it. It reads the command it receives, so a destructive operation wrapped in `batch_execute` asks only at ALL, or at BULK when the batch is large. While code execution is on, a script could also rewrite the panel's settings — see below.
66
+ **Confirmation** is a dial with four stops — OPEN · RISK · BULK · ALL. At RISK, the default, only destructive operations ask (deleting variables or styles, detach, flatten); everything else keeps moving. Set it in the panel; no Relai tool changes it, and if a script rewrites the stored setting, Relai puts your value back and says so on the receipt. A `batch_execute` asks by what it wraps: at RISK a wrapped destructive operation asks, at BULK one wrapped script asks. ALL asks before every write and every script, because a script cannot be told apart from a write before it runs.
67
67
 
68
68
  ### How far the law reaches
69
69
 
@@ -71,11 +71,11 @@ The law is stored as plugin data inside the file — no extra layers on the canv
71
71
 
72
72
  What the law can stop depends on how a write arrives:
73
73
 
74
- - **Commands sent through Relai's tools** are checked in the plugin, on the file's side of the wire, before they run. A write aimed at a node on a fenced page, or outside your selection lock, is refused. Commands that carry their node ids inside a list — a multi-node `set_text`, `annotate set_multiple` — are checked against the current page only. Variables and modes belong to no page, so no-go zones do not cover them.
75
- - **Scripts sent through `execute_figma`** run in the same plugin sandbox as Relai's checks, so they cannot be screened before they run. Relai refuses a script outright when the current page is fenced off. Afterwards, the result warns the agent about nodes the script created through the `relai` helpers or returned that sit on a fenced page or outside your lock. While code execution is on, a script can also rewrite Relai's settings and law. Turn code execution off when you want every write to go through checked commands.
74
+ - **Commands sent through Relai's tools** are checked in the plugin, on the file's side of the wire, before they run. A write aimed at a node on a fenced page, or outside your selection lock, is refused, and so is each command inside a batch. A multi-node `set_text` is checked item by item; `annotate set_multiple`, which carries its node ids inside a list, is checked against the current page only. Variables and modes belong to no page, so no-go zones do not cover them.
75
+ - **Scripts sent through `execute_figma`** run in the same plugin sandbox as Relai's checks, so they cannot be screened before they run. Relai refuses a script outright when the current page is fenced off. When a script ends — with an error too — Relai checks the nodes it created through the `relai` helpers or returned, and names any that sit on a fenced page or outside your lock, on the receipt and in the panel. Those writes have already happened: scripts are checked after they run, not stopped. If a script rewrote Relai's own settings — the no-go zones, the dial, the lock, the code toggle — Relai puts them back and says so, and panel actions are not applied while a script runs or for three seconds after. A script can still edit the conventions and precedents stored in the file; Relai reports that and leaves the edit in place. Turn code execution off when you want every write to go through checked commands.
76
76
  - **Writes that never pass through Relai** — another plugin, another MCP server, someone editing by hand, anything done while Relai is closed — are outside its reach. Relai neither refuses them nor notices them.
77
77
 
78
- Precedents work at a different strength: they are your recorded words, arriving at the exact moment an edit touches what they reference. The agent backs off because the author shows up, not because anything blocked it. Any client that connects through Relai is bound by all of this, including ones you never configured — and everything it does leaves receipts.
78
+ Precedents work at a different strength: they are your recorded words, matched before an edit runs and arriving with it — first in the result, on each item of a batch, and on the approval card when one is shown. The agent backs off because the author shows up, not because anything blocked it. Any client that connects through Relai is bound by all of this, including ones you never configured — and everything it does leaves receipts.
79
79
 
80
80
  None of this is setup you grind through — it accumulates. On day one the file is blank law, and the agent behaves like anyone's agent. A month in, it arrives briefed on your conventions and precedents and stops at your fences: the same prompt that produces the average of everyone's design in a fresh file produces yours in yours. Two long-time users are not holding the same tool. They are holding two different instruments.
81
81
 
@@ -127,6 +127,8 @@ The plugin is the designer's side of the deal: a live activity feed of everythin
127
127
 
128
128
  **Lock to selection** rejects edits outside whatever you've selected — the AI gets a clear error, not a silent pass. The relay is local: file contents move only between Figma, your machine, and the AI client you already trust. The UI speaks English, 日本語, and 中文.
129
129
 
130
+ When something needs you — an approval, a kit that refused a push, a script that reached across a fence — it stays on the panel until you deal with it. An approval card counts down; one nobody answers is denied after two minutes, and its row says it timed out.
131
+
130
132
  When something goes wrong anyway — a bad sweep, a wrong "fix" — the feed is your reconstruction and Figma's version history is your restore path. There is no magic undo, and Relai doesn't pretend to have one: `diff_nodes` checkpoints tell you exactly what changed; version history takes you back. And when the law itself is wrong — a stale precedent guarding a gap you've since changed your mind about — tell the agent to go ahead, then delete the entry from the panel's Memory row. Rulings are one click to remove; the law stays yours to amend.
131
133
 
132
134
  ## How it works
@@ -142,6 +144,8 @@ Figma plugin executes Plugin API calls
142
144
 
143
145
  The relay lives inside the MCP server, so there is no extra process to keep alive. When several MCP clients run at once, the first one hosts the relay and the others connect to it; if the host exits, a survivor takes over. Both sides remember their room, rejoin after restarts or sleep, and find each other without any copy-pasting. The `join_room` tool exists for one rare case only: two Figma files running the plugin at the same time.
144
146
 
147
+ Every call that reached the plugin, reads included, ends with a `[relai]` line that says whether Figma changed: `applied`, `not_applied`, or `unknown` — it may have, so read the canvas before trying again. Failures are marked as errors and name a code; scripts can read the same receipt from the result's `_meta`. With several files open, a call can carry `room` to go to one plugin, or `expect_file` to refuse unless the target file has that exact name. Text longer than 40,000 characters is cut before it reaches the AI, and the full text is saved on your machine in `~/.figma-relai/results/` (readable only by you, the newest 50 files, none kept longer than a day); the cut notice names the file.
148
+
145
149
  The receipts above are real timings: rule checks run in the plugin before each write, small edits land sub-second, and the 45,509-node audit took 3.9s.
146
150
 
147
151
  Ports are fixed by Figma's plugin sandbox: the manifest allowlists `ws://localhost:9055–9057`, and other ports cannot work without editing `manifest.json`. That's why there is no port setting in the UI.
@@ -201,13 +205,15 @@ Start with `npx figma-relai doctor` — one command that checks Node, the relay
201
205
 
202
206
  **RELAY says LINK but AGENT says WAITING.** The plumbing is fine — the AI just hasn't called a Figma tool yet in this session. Ask it something about the file.
203
207
 
204
- **"Multiple Figma plugins are connected."** Two files are running the plugin. Tell the AI to `join_room` with the room name shown in the plugin you want to control.
208
+ **"Multiple Figma plugins are connected."** Two files are running the plugin. Tell the AI to `join_room` with the room name shown in the plugin you want to control, or to pass `room` or `expect_file` on each call.
209
+
210
+ **`room_changed`.** The plugin moved to a different file — a branch, or another document — since the last call, so the call was not sent. Sending it again continues in the new file; `join_room` back if that is not the file you meant.
205
211
 
206
212
  **The first `npx` run is slow.** It downloads the package once; later starts are fast.
207
213
 
208
214
  ## Security
209
215
 
210
- The relay binds to `127.0.0.1` only and has no authentication: any process on your machine that can reach it can list the open rooms, with each room's file name, and join one. `execute_figma` runs AI-written code inside Figma's plugin sandbox; it is on by default, every run is visible in the activity feed, and the designer can disable it. Scripts are not atomic — a failed script's earlier changes persist. Full threat model: [SECURITY.md](SECURITY.md).
216
+ The relay binds to `127.0.0.1` only and has no authentication: any process on your machine that can reach it can list the open rooms, with each room's file name, and join one. It refuses connections from ordinary web pages, but that check narrows who can connect; it is not authentication. `execute_figma` runs AI-written code inside Figma's plugin sandbox; it is on by default, every run is visible in the activity feed, and the designer can disable it. Scripts are not atomic — a failed script's earlier changes persist. Full threat model: [SECURITY.md](SECURITY.md).
211
217
 
212
218
  ## For contributors
213
219