@sxl-studio/bridge 1.4.0 → 1.5.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
@@ -27,7 +27,8 @@ Bridge forwards `commandType` + `payload` over WebSocket; **execution is always
27
27
  | `1.1.x` | same-era | `set_node_fill_variable`, extended `create_frame` / `create_text` (`parentId`, Auto Layout fields) |
28
28
  | `1.2.x` | same-era | Remote module split (`dispatch/`, `canvas/`, `sxl/`), MCP instructions, base canvas tools, validated `POST /api/command`, aligned `COMMAND_TIMEOUTS` |
29
29
  | **`1.3.x`** | **`2.1.0+`** | Dev Mode codegen bridge (`get_codegen`, `export_composition_json`), **full token workspace CRUD** (`create_token_file`, `delete_token_file`, `move_token_file`, `save_tokens_config`, upsert `save_token_file`), **Variables CRUD** (modes, scopes, codeSyntax), **Styles CRUD**, **orchestration** (`compose_from_url`, `generate_code_from_url`, `document_component`), **MCP Resources** (`sxl://…`), typed errors (`EDITOR_MODE_READONLY` + structured envelope), `BRIDGE_AUTH_TOKEN`, **Idempotency-Key** on `/api/command`, `/api/log` audit trail, `/api/tools` + `list_tools` meta-tool, editor-mode write-guard with typed propagation. |
30
- | **`1.4.x`** | **`2.1.0+`** (plugin с `apply_token_doc_spec`) | **Doc Spec v1** + `build_token_documentation` / `apply_token_doc_spec`, **MCP resources** `sxl://agent/recipes/doc-tokens` (+ doc-component, doc-composition, doc-flow), расширенные MCP-инструкции для documentation recipes. |
30
+ | **`1.4.x`** | **`2.1.0+`** (plugin with `apply_token_doc_spec`) | **Doc Spec v1** + `build_token_documentation` / `apply_token_doc_spec`, **MCP resources** `sxl://agent/recipes/doc-tokens` (+ doc-component, doc-composition, doc-flow), expanded MCP instructions for documentation recipes. |
31
+ | **`1.5.x`** | **`2.2.0+`** | **Doc Builder v2**: `apply_doc_spec` (generic sections), `bind_variable_palette`, `build_component_doc`, `build_doc_flow`. Intent-router resource `sxl://agent/recipes/index` plus `template-discovery`, `doc-spec-v2`. Reinforced anti-patterns in `sxl-mcp-instructions.ts` (`/tmp` payloads, base64 loaders, `use_figma` scripts). |
31
32
 
32
33
  Treat feature alignment by changelog or release tag, not npm name alone.
33
34
 
@@ -1,36 +1,204 @@
1
1
  /**
2
2
  * Machine-readable documentation recipes for MCP resources (sxl://agent/recipes/*).
3
- * Keep aligned with Plugin/sxl/docs/22-doc-spec-v1.md and sxl-mcp-instructions.ts.
3
+ *
4
+ * Read order for an agent that just got a documentation request:
5
+ * 1. sxl://agent/recipes/index — intent router (THIS file: RECIPE_INDEX).
6
+ * 2. The specific recipe it points to.
7
+ * 3. sxl://agent/recipes/doc-spec-v2 — section vocabulary, when needed.
8
+ * 4. sxl://agent/recipes/template-discovery — how to find templateNodeId.
9
+ *
10
+ * Every recipe MUST list:
11
+ * - userPhrases — short sample utterances that route to it.
12
+ * - decideBetween — siblings + when each wins.
13
+ * - preferredTools — Bridge / direct tool names in call order.
14
+ * - forbidden — concrete anti-patterns to avoid.
15
+ * - steps — minimal sequence to reach doneCriteria.
16
+ * - doneCriteria — verifiable success.
4
17
  */
18
+ export declare const RECIPE_INDEX: {
19
+ readonly id: "index";
20
+ readonly title: "SXL Doc Builder — intent router";
21
+ readonly version: 1;
22
+ readonly context: "Decision tree for any documentation / palette / scenario request that targets a Figma file managed by SXL Studio. Always read this resource first; it routes the agent to a specific recipe instead of running ad-hoc figma.* JS.";
23
+ readonly userIntents: readonly [{
24
+ readonly recipeId: "doc-tokens";
25
+ readonly userPhrases: readonly ["задокументируй токены", "build a token doc", "table of token values", "fill template TEXT layers with token values", "tokenPath, layerName binding", "show DTCG paths in doc frame"];
26
+ }, {
27
+ readonly recipeId: "variable-palette";
28
+ readonly userPhrases: readonly ["добавь все цвета коллекции projects карточками", "render figma variable collection as cards", "swatches from local variable collection", "по коллекции переменных нарисуй палитру", "fill content with one card per variable"];
29
+ }, {
30
+ readonly recipeId: "doc-component";
31
+ readonly userPhrases: readonly ["задокументируй компонент", "document WButton", "component frame with variants and props", "build component doc"];
32
+ }, {
33
+ readonly recipeId: "doc-flow";
34
+ readonly userPhrases: readonly ["сделай flow по этим ссылкам", "build a multi-page scenario", "screen flow doc", "story of pages from these urls"];
35
+ }, {
36
+ readonly recipeId: "doc-spec-v2";
37
+ readonly userPhrases: readonly ["сложная документация: title + variants + props + palette", "mix sections in one frame", "custom doc spec"];
38
+ }, {
39
+ readonly recipeId: "template-discovery";
40
+ readonly userPhrases: readonly ["find the card template inside content frame", "локализуй карточку-шаблон в content", "where is the swatch template node"];
41
+ }, {
42
+ readonly recipeId: "compose-with-variables";
43
+ readonly userPhrases: readonly ["получи JSON компонента и сгенерируй его назначив переменные", "export composition and generate component with variables assigned", "сохрани компонент в репо с привязкой переменных", "generate component from figma url with variable bindings", "создай компонент сет и привяжи переменные"];
44
+ }, {
45
+ readonly recipeId: "scenario-from-markdown";
46
+ readonly userPhrases: readonly ["вот md файл сценария, создай flow", "build scenario from this markdown", "у меня есть md с описанием флоу", "создай сценарий из md файла", "render this spec as a figma flow"];
47
+ }];
48
+ readonly decideBetween: readonly [{
49
+ readonly between: readonly ["doc-tokens", "variable-palette"];
50
+ readonly use_doc_tokens_when: "data source is DTCG token files in the plugin workspace (paths like core.color.fg)";
51
+ readonly use_variable_palette_when: "data source is local Figma Variables (no DTCG file behind them)";
52
+ }, {
53
+ readonly between: readonly ["doc-component", "doc-spec-v2"];
54
+ readonly use_doc_component_when: "single Figma component / component set with default sections (title + variants + props)";
55
+ readonly use_doc_spec_v2_when: "user wants a custom mix of sections, or several non-component artefacts in one frame";
56
+ }, {
57
+ readonly between: readonly ["scenario-from-markdown", "doc-flow"];
58
+ readonly use_scenario_from_markdown_when: "user provides a markdown document with H2 sections and Figma URLs — call build_scenario_from_md";
59
+ readonly use_doc_flow_when: "user provides individual Figma URLs / nodeIds directly (no markdown doc)";
60
+ }, {
61
+ readonly between: readonly ["compose-with-variables", "doc-composition"];
62
+ readonly use_compose_with_variables_when: "goal is to generate a reusable Figma component with variable bindings from a design URL";
63
+ readonly use_doc_composition_when: "goal is to render a documentation frame from an existing composition file";
64
+ }];
65
+ readonly forbidden: readonly ["Calling use_figma with a hand-written figma.* script when an SXL Bridge tool covers the task.", "Shell payload assembly to /tmp/*.json + base64 loaders + node -e glue to invoke MCP.", "Hand-crafting composition / token / Doc Spec JSON when the plugin pipeline (export_composition_json / list_compositions / get_variables) is the source of truth.", "Skipping this index and jumping straight to a sub-recipe without confirming intent."];
66
+ readonly doneCriteria: "Agent picked exactly one recipe, called only the tools it lists, and produced a verifiable result (doneWhen of that recipe).";
67
+ };
68
+ export declare const RECIPE_TEMPLATE_DISCOVERY: {
69
+ readonly id: "template-discovery";
70
+ readonly title: "Find the swatch / card template inside a content frame";
71
+ readonly version: 1;
72
+ readonly context: "Many doc tasks (variable-palette, doc-spec-v2.palette, doc-component.variants) need a templateNodeId — an existing scene node we can clone. This recipe shows how to locate it deterministically without scripts.";
73
+ readonly userPhrases: readonly ["find template card in content", "locate swatch template", "templateNodeId под content фрейма"];
74
+ readonly preferredTools: readonly ["get_node_tree", "find_nodes", "get_node_info", "read_node_properties"];
75
+ readonly forbidden: readonly ["Cloning the entire content frame instead of one card.", "Guessing node ids — always verify via get_node_tree / find_nodes.", "Falling back to use_figma to traverse the file: get_node_tree returns enough info for SXL templates."];
76
+ readonly steps: readonly ["From the user URL, parse node-id (`figma.com/design/.../?node-id=151-2` → `151:2`).", "Call get_node_tree with that nodeId and depth=4 to inspect the frame and its content.", "Pick the first child of the content layer (or one named 'card', 'swatch', 'token-card' — let the user confirm if ambiguous).", "Read swatch / label / value layer names with get_node_tree (depth=2 from the picked card) and pass them to bind_variable_palette / palette section."];
77
+ readonly doneCriteria: "templateNodeId + swatchLayerName (and optionally labelLayerName / valueLayerName) confirmed against the file before any clone.";
78
+ };
79
+ export declare const RECIPE_DOC_SPEC_V2: {
80
+ readonly id: "doc-spec-v2";
81
+ readonly title: "Doc Spec v2 — sections vocabulary";
82
+ readonly version: 1;
83
+ readonly context: "Doc Spec v2 lets you compose a single apply_doc_spec call from a list of sections. Each section is independent: combine only what the user asked for. Read this resource before assembling a custom spec.";
84
+ readonly preferredTools: readonly ["apply_doc_spec", "build_component_doc", "bind_variable_palette", "build_doc_flow"];
85
+ readonly sections: readonly [{
86
+ readonly type: "title";
87
+ readonly note: "Either creates a TEXT node or writes into an existing layerName.";
88
+ }, {
89
+ readonly type: "description";
90
+ readonly note: "Markdown subset → formatted runs. Use **bold**, *italic*, `code`, # headings.";
91
+ }, {
92
+ readonly type: "variants";
93
+ readonly note: "ComponentSet → matrix / grid / list of instances. Use groupBy for matrix rows.";
94
+ }, {
95
+ readonly type: "props";
96
+ readonly note: "componentPropertyDefinitions → table TEXT block. include filters which kinds.";
97
+ }, {
98
+ readonly type: "tokenTable";
99
+ readonly note: "v1 surface preserved: layerName + tokenPath. Picks values from DTCG workspace.";
100
+ }, {
101
+ readonly type: "palette";
102
+ readonly note: "Local Figma Variables → cards by cloning templateNodeId.";
103
+ }, {
104
+ readonly type: "measure";
105
+ readonly note: "Experimental: node.annotations = [...].";
106
+ }];
107
+ readonly forbidden: readonly ["Generating section types not in the schema (the validator rejects them).", "Using `palette.collectionName` for a DTCG file path — palette only inspects local Figma Variables.", "Putting v1 fields (`groups`, `version: \"1\"`) into a v2 spec — use apply_token_doc_spec for v1."];
108
+ readonly steps: readonly ["Decide which sections are needed (intent router → user request).", "Resolve targetRootId (existing frame) or targetParentId (with createIfMissing).", "Call apply_doc_spec with the assembled spec; rely on per-section reports for partial failures."];
109
+ readonly doneCriteria: "apply_doc_spec returns ok=true (or section-level report shows which section failed and why).";
110
+ };
5
111
  export declare const RECIPE_DOC_TOKENS: {
6
112
  readonly id: "doc-tokens";
7
- readonly title: "Token documentation (Doc Spec v1)";
8
- readonly version: 1;
9
- readonly preferredTools: readonly ["list_token_files", "get_token_file_content", "build_token_documentation", "apply_token_doc_spec", "duplicate_subtree", "apply_documentation_payload"];
10
- readonly forbidden: readonly ["Hand-written DTCG or composition JSON as the source of truth — use export_variables / plugin workspace files.", "Raw Figma plugin scripts in the repo for one-off doc builds — use Bridge + whitelist commands."];
11
- readonly steps: readonly ["Read sxl://tokens/config and sxl://tokens/files (or list_token_files) to locate token files.", "In Figma Design mode, duplicate a documentation template frame (e.g. from your DS library) to get targetRootId.", "Build a Doc Spec v1 JSON: version \"1\", groups[].rows with layerName (TEXT layer name) and tokenPath (DTCG path).", "Call build_token_documentation with { spec, targetRootId } (or apply_token_doc_spec with the same).", "On unresolved paths, check tokenPath spelling and that files are loaded in the plugin workspace."];
12
- readonly doneWhen: "TEXT layers under targetRootId show resolved values; apply_token_doc_spec returns ok and updated > 0 (unless dryRun).";
113
+ readonly title: "Token documentation (Doc Spec v1 / v2 tokenTable)";
114
+ readonly version: 2;
115
+ readonly userPhrases: readonly ["задокументируй токены", "fill doc template with token values", "table of DTCG paths and resolved values"];
116
+ readonly decideBetween: readonly [{
117
+ readonly between: readonly ["doc-tokens", "variable-palette"];
118
+ readonly hint: "If the data source is local Figma variables (no DTCG file), switch to variable-palette.";
119
+ }];
120
+ readonly preferredTools: readonly ["list_token_files", "get_token_file_content", "build_token_documentation", "apply_token_doc_spec", "apply_doc_spec", "duplicate_subtree"];
121
+ readonly forbidden: readonly ["Hand-written DTCG / composition JSON as the source of truth — use plugin workspace files.", "Raw figma.* JS / use_figma scripts to traverse tokens — Bridge has list_token_files + get_token_file_content.", "Copy-pasting token values into the spec instead of letting the plugin resolve them."];
122
+ readonly steps: readonly ["Read sxl://tokens/config and sxl://tokens/files (or list_token_files) to locate token files.", "In Figma Design mode duplicate the doc template (or use an existing one) to obtain targetRootId.", "Build Doc Spec v1 (groups[].rows with layerName + tokenPath) — or v2 with a single tokenTable section if you also need title / description.", "Call build_token_documentation / apply_token_doc_spec (v1) or apply_doc_spec (v2) with { spec, targetRootId }.", "On unresolved paths re-check tokenPath spelling and confirm files are present in the workspace."];
123
+ readonly doneCriteria: "TEXT layers under targetRootId show resolved values; the response reports updated > 0 and no unresolved paths (unless dryRun).";
13
124
  };
14
125
  export declare const RECIPE_DOC_COMPONENT: {
15
126
  readonly id: "doc-component";
16
- readonly title: "Component documentation";
17
- readonly version: 1;
18
- readonly preferredTools: readonly ["export_composition_json", "get_codegen", "document_component", "apply_documentation_payload", "create_component_instance"];
19
- readonly forbidden: readonly ["Synthesising composition JSON from get_node_tree — use export_composition_json or get_codegen (designer-json)."];
20
- readonly steps: readonly ["Select the component (or pass nodeId) and call get_codegen / export_composition_json for authoritative JSON.", "Use document_component or apply_documentation_payload with targetRootId and entries [{ layerName, text }] to fill a template frame."];
127
+ readonly title: "Component documentation (title + variants + props + optional measure)";
128
+ readonly version: 2;
129
+ readonly userPhrases: readonly ["задокументируй компонент", "document this component", "WButton documentation frame", "build component doc"];
130
+ readonly decideBetween: readonly [{
131
+ readonly between: readonly ["doc-component", "doc-spec-v2"];
132
+ readonly hint: "If you need anything beyond title/description/variants/props/measure (e.g. palette, tokenTable), pick doc-spec-v2 + apply_doc_spec.";
133
+ }];
134
+ readonly preferredTools: readonly ["build_component_doc", "apply_doc_spec", "export_composition_json", "get_codegen", "duplicate_subtree"];
135
+ readonly forbidden: readonly ["Synthesising composition JSON from get_node_tree — use export_composition_json / get_codegen.", "Calling use_figma to read componentPropertyDefinitions — the plugin already exposes it via build_component_doc.", "Mutating the component itself when documenting it — work on the doc frame, not the source."];
136
+ readonly steps: readonly ["Identify the component (componentNodeId). For a component set, pass the set id.", "Provide either targetRootId (existing doc frame) or targetParentId (createIfMissing=true).", "Call build_component_doc; toggle includeMeasure only if the user asked for size annotations.", "Refine specific sections (e.g. update description markdown) by re-running with new payload."];
137
+ readonly doneCriteria: "The doc frame contains a title, a variants matrix (when applicable), and a props table with all componentPropertyDefinitions.";
21
138
  readonly phases: "Measuring/annotations: see Plugin/sxl/docs/23-doc-agent-phased-roadmap.md (Phase 3).";
22
139
  };
23
140
  export declare const RECIPE_DOC_COMPOSITION: {
24
141
  readonly id: "doc-composition";
25
142
  readonly title: "Documentation from composition file";
26
- readonly version: 1;
143
+ readonly version: 2;
144
+ readonly userPhrases: readonly ["render this composition file as documentation", "доку по composition.json", "build a frame from a composition file"];
27
145
  readonly preferredTools: readonly ["list_compositions", "export_composition_json", "generate_composition", "apply_composition", "compose_from_url"];
28
- readonly steps: readonly ["Prefer compose_from_url or export_composition_json create_token_file generate_composition to materialise the layout.", "Do not hand-assemble the composition tree; the plugin pipeline is the single source of truth."];
146
+ readonly forbidden: readonly ["Hand-assembling composition trees in JSON the plugin pipeline is the single source of truth.", "Using use_figma to draw the composition manually."];
147
+ readonly steps: readonly ["Prefer compose_from_url for a Figma URL → export_composition_json → create_token_file → generate_composition.", "Apply with apply_composition / generate_composition; do not hand-construct nodes."];
148
+ readonly doneCriteria: "Composition file in workspace + generated component / instance on the canvas matching the source.";
29
149
  };
30
150
  export declare const RECIPE_DOC_FLOW: {
31
151
  readonly id: "doc-flow";
32
- readonly title: "Multi-page screen flow";
152
+ readonly title: "Multi-page screen flow / scenario";
153
+ readonly version: 2;
154
+ readonly userPhrases: readonly ["сделай flow по этим ссылкам", "build a screen flow doc", "story of pages from these urls", "scenario doc with multiple frames"];
155
+ readonly preferredTools: readonly ["build_doc_flow", "compose_from_url", "duplicate_subtree", "apply_doc_spec"];
156
+ readonly forbidden: readonly ["Calling use_figma to clone many frames into one container — use build_doc_flow.", "Skipping captions when the user provided a description per page — pass them via pages[].title / description."];
157
+ readonly steps: readonly ["Resolve each Figma URL to a node id (parseFigmaUrl handles `&node-id=` segments).", "Call build_doc_flow with pages[] (each with nodeId and optional title / description).", "If a page references a composition file rather than a node, call compose_from_url first to materialise it."];
158
+ readonly doneCriteria: "All requested pages appear inside a single auto-layout container with optional captions; no use_figma script was used.";
159
+ };
160
+ export declare const RECIPE_COMPOSE_WITH_VARIABLES: {
161
+ readonly id: "compose-with-variables";
162
+ readonly title: "Export composition and generate component with Figma variable bindings";
33
163
  readonly version: 1;
34
- readonly preferredTools: readonly ["compose_from_url", "generate_composition", "export_composition_json", "get_codegen"];
35
- readonly steps: readonly ["For each screen, use a Figma URL with node-id or export_composition_json from the source node.", "Chain composition saves and generate_composition; avoid ad-hoc canvas scripts for full flows (see Phase 4 roadmap)."];
164
+ readonly userPhrases: readonly ["получи JSON компонента и сгенерируй его назначив переменные", "export composition and generate component with variables assigned", "сохрани компонент в репо и создай с привязкой переменных фигмы", "generate component from figma url with variable bindings", "создай компонент сет и привяжи переменные экспортированные из фигмы", "get code JSON and generate component assigning all variables"];
165
+ readonly decideBetween: readonly [{
166
+ readonly between: readonly ["compose-with-variables", "doc-composition"];
167
+ readonly hint: "If the goal is documentation (render a frame, not generate a reusable component), use doc-composition.";
168
+ }];
169
+ readonly context: "Variable references inside a composition JSON are automatically applied during generate_composition — the plugin binds Figma local variables to nodes without extra steps. Use batch_bind_variables only for bindings NOT captured in the composition JSON.";
170
+ readonly preferredTools: readonly ["compose_from_url", "export_composition_json", "create_token_file", "generate_composition", "get_variables", "batch_bind_variables"];
171
+ readonly forbidden: readonly ["Hand-crafting composition JSON from get_node_tree — always use export_composition_json / get_codegen.", "Calling bind_variable N times in a loop — use batch_bind_variables for bulk wiring.", "Skipping get_plugin_status before canvas writes — confirm writesAllowed first."];
172
+ readonly steps: readonly ["Call compose_from_url { url, generate: true } — exports composition JSON, saves token file, generates Figma component. Variable references inside the JSON are auto-bound.", "If additional bindings are needed (not in composition JSON): call get_variables to list local variables, then batch_bind_variables with the required {nodeId, variableId, field} entries.", "Verify result with get_drift_status or get_selection_summary."];
173
+ readonly doneCriteria: "Composition token file exists in workspace; Figma component generated on canvas; variable bindings visible in Figma inspector.";
174
+ };
175
+ export declare const RECIPE_SCENARIO_FROM_MARKDOWN: {
176
+ readonly id: "scenario-from-markdown";
177
+ readonly title: "Multi-page scenario / flow from a markdown spec document";
178
+ readonly version: 1;
179
+ readonly userPhrases: readonly ["вот md файл сценария, создай flow в фигме", "build scenario from this markdown document", "у меня есть md с описанием флоу", "render this spec as a figma flow", "создай сценарий из md файла", "scenario document → figma pages", "make a user flow from this spec", "go through this markdown and create a figma scenario"];
180
+ readonly decideBetween: readonly [{
181
+ readonly between: readonly ["scenario-from-markdown", "doc-flow"];
182
+ readonly hint: "If the user provides individual Figma URLs (not a markdown document), use doc-flow / build_doc_flow directly.";
183
+ }];
184
+ readonly context: "The markdown spec format: H1 = flow container title, H2 sections = pages, Figma URL per section = source node to clone, paragraph text = page caption. build_scenario_from_md parses this automatically.";
185
+ readonly preferredTools: readonly ["build_scenario_from_md", "build_doc_flow"];
186
+ readonly forbidden: readonly ["Hand-parsing Figma URLs from markdown and assembling pages[] manually — use build_scenario_from_md.", "Calling use_figma to create frames and place screenshots.", "Generating a node-by-node script when build_scenario_from_md covers the whole flow."];
187
+ readonly steps: readonly ["Run build_scenario_from_md { markdown, dryRun: true } — confirm the parsed pages list (title, nodeId, description) is correct.", "If nodeIds are missing: check that Figma URLs in the markdown include ?node-id= parameters.", "Run build_scenario_from_md with targetParentId (or targetRootId for an existing container) and dryRun: false."];
188
+ readonly doneCriteria: "All H2 pages from the markdown appear as frames inside a single auto-layout container; each page has the correct caption.";
189
+ };
190
+ export declare const RECIPE_VARIABLE_PALETTE: {
191
+ readonly id: "variable-palette";
192
+ readonly title: "Color (or variable) cards from a Figma variable collection";
193
+ readonly version: 2;
194
+ readonly userPhrases: readonly ["добавь все цвета коллекции projects карточками", "render figma variable collection as cards", "swatches from local variable collection", "по коллекции переменных нарисуй палитру"];
195
+ readonly decideBetween: readonly [{
196
+ readonly between: readonly ["variable-palette", "doc-tokens"];
197
+ readonly hint: "If user names a DTCG file or token path (`core.color.*`), switch to doc-tokens.";
198
+ }];
199
+ readonly context: "Example: fill a frame's content with one card per COLOR variable in the Projects collection, using an existing card component / instance as template.";
200
+ readonly preferredTools: readonly ["get_plugin_status", "get_variables", "get_node_tree", "find_nodes", "bind_variable_palette", "apply_doc_spec"];
201
+ readonly forbidden: readonly ["use_figma (official Figma MCP) with a custom JavaScript payload — SXL session cannot execute that in the plugin; bind_variable_palette covers the same flow.", "Shell payloads (/tmp/*.json, base64 loaders, copy-paste into tokens/system, node -e glue) to invoke MCP — pass JSON directly to bind_variable_palette.", "Pretending the task requires a 'Figma script' when get_variables + bind_variable_palette is enough."];
202
+ readonly steps: readonly ["get_plugin_status — confirm writesAllowed (Figma Design, not Dev Mode read-only).", "Use sxl://agent/recipes/template-discovery to locate templateNodeId + swatchLayerName under the user's content frame.", "Call bind_variable_palette with { templateNodeId, collectionName, variableType: 'COLOR', swatchLayerName, labelLayerName? }.", "Inspect the response: created should equal the variable count; bound should equal created (one fill bind per swatch)."];
203
+ readonly doneCriteria: "One card per target variable next to the template; each swatch is bound to its variable; no use_figma script was used.";
36
204
  };