@sxl-studio/bridge 1.5.1 → 1.6.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 +8 -1
- package/dist/agent-recipes.d.ts +268 -0
- package/dist/agent-recipes.js +637 -0
- package/dist/agent-recipes.js.map +1 -1
- package/dist/command-queue.js +16 -0
- package/dist/command-queue.js.map +1 -1
- package/dist/mcp-factory.js +11 -1
- package/dist/mcp-factory.js.map +1 -1
- package/dist/sxl-mcp-instructions.js +142 -2
- package/dist/sxl-mcp-instructions.js.map +1 -1
- package/dist/tools/audit.d.ts +49 -0
- package/dist/tools/audit.js +83 -0
- package/dist/tools/audit.js.map +1 -0
- package/dist/tools/catalogue-bootstrap.js +34 -0
- package/dist/tools/catalogue-bootstrap.js.map +1 -1
- package/dist/tools/compositions-orchestration.d.ts +91 -0
- package/dist/tools/compositions-orchestration.js +101 -0
- package/dist/tools/compositions-orchestration.js.map +1 -0
- package/dist/tools/mockup.d.ts +323 -0
- package/dist/tools/mockup.js +206 -0
- package/dist/tools/mockup.js.map +1 -0
- package/dist/tools/registry.d.ts +1 -1
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/resources.d.ts +1 -1
- package/dist/tools/resources.js +52 -2
- package/dist/tools/resources.js.map +1 -1
- package/dist/tools/styles-orchestration.d.ts +544 -0
- package/dist/tools/styles-orchestration.js +175 -0
- package/dist/tools/styles-orchestration.js.map +1 -0
- package/dist/tools/tokens.d.ts +60 -60
- package/dist/tools/variables-orchestration.d.ts +20 -0
- package/dist/tools/variables-orchestration.js +116 -0
- package/dist/tools/variables-orchestration.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -29,6 +29,7 @@ Bridge forwards `commandType` + `payload` over WebSocket; **execution is always
|
|
|
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
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
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). |
|
|
32
|
+
| **`1.6.x`** | **`2.3.0+`** | **Audit & Usage (Phase A)** + **Variables orchestration (Phase B)** + **Styles orchestration (Phase C)** + **Mockup-from-DesignSystem (Phase D)** + **Compositions orchestration (Phase E)**. Phase A: `audit` category — `analyze_variable_usage`, `find_variable_usages`, `render_variable_usage_page`, `audit_variable_coverage`, `find_variable_coverage_misses`, `audit_style_coverage`, `find_style_coverage_misses`, `find_unused_variables`, `find_unused_styles`. Chunked traversal with transitive-alias resolution. Token-economy: summary by default, paginated `find_*` for details. Phase B: new `variables-orchestration` category — `import_variable_spec` (idempotent bulk create / update with aliases), `analyze_variable_order` (read-only ordering diff), `dedupe_variables` (merge duplicates, dry-run by default), `rebind_variable_aliases` (bulk alias rewrite), `apply_coverage_suggestions` (audit suggestions → real bindings, dry-run by default). Phase C: new `styles-orchestration` category — `import_style_spec` (idempotent bulk create / update of Paint / Text / Effect styles), `dedupe_styles` (merge duplicates `byName | bySignature`), `rebind_style_consumers` (bulk styleId rewrite on consumer nodes), `audit_style_drift` (read-only drift between local Paint styles and Variables / `expectations[]`), `apply_style_coverage_suggestions` (Phase A `find_style_coverage_misses` → real `setStyleId*` writes). Phase D: new `mockup` category — `find_components` (read-only paginated catalogue of local + library-instantiated components with `componentPropertyDefinitions`, Dev-Mode compatible), `build_mockup` (declarative auto-layout assembly from an `instance | section | spacer | text` item tree with property / text / fill-binding overrides; `dryRun`-aware), `apply_mockup_dataset` (clone a template per dataset row with row-specific overrides; `dryRun`-aware). Phase E: new `compositions-orchestration` category — `bulk_generate_compositions` (bulk `generate` / `apply` of composition files with `fileIds | names | prefix` filters, `operation: auto | generate | apply`, per-item error isolation, `dryRun`-aware), `audit_composition_drift` (read-only drift detection between workspace composition files and tracked Figma components: `linked | unlinked | drift | missing`, Dev-Mode safe). All write commands accept `dryRun` / `apply` so Dev Mode can be used as a preview surface. Recipes: `sxl://agent/recipes/{variable-usage,audit-coverage,find-unused,bulk-variables,auto-bind-from-audit,bulk-styles,style-drift,mockup-builder,bulk-compositions,composition-drift}`. |
|
|
32
33
|
|
|
33
34
|
Treat feature alignment by changelog or release tag, not npm name alone.
|
|
34
35
|
|
|
@@ -183,8 +184,12 @@ Registered in `src/mcp-factory.ts` via `tools/*.ts`:
|
|
|
183
184
|
- **Diagnostics / meta:** `get_plugin_status`, `is_dev_mode`, `get_selection_summary`, `get_drift_status`, `list_tools`.
|
|
184
185
|
- **Tokens / workspace:** `list_token_files`, `get_token_file_content`, `save_token_file` (upsert), `create_token_file`, `delete_token_file`, `move_token_file`, `rename_token_file`, `get_tokens_config`, `save_tokens_config`, `export_variables`, `reset_diff*`, `reapply_token_bindings`, `cross_file_sync_*`, `get_applied_tokens`.
|
|
185
186
|
- **Composition:** `export_composition_json`, `get_codegen`, `list_compositions`, `generate_composition`, `apply_composition`, `preview_composition`, `check_composition_linked`, `inspect_selection`.
|
|
186
|
-
- **Variables:** `get_variables`, `create_variable_collection`, `create_variable`, `bind_variable`, `rename_variable`, `delete_variable`, `rename_variable_collection`, `delete_variable_collection`, `add_variable_mode`, `remove_variable_mode`, `rename_variable_mode`, `set_variable_mode_value`, `set_variable_scopes`, `set_variable_code_syntax`.
|
|
187
|
+
- **Variables:** `get_variables`, `create_variable_collection`, `create_variable`, `bind_variable`, `rename_variable`, `delete_variable`, `rename_variable_collection`, `delete_variable_collection`, `add_variable_mode`, `remove_variable_mode`, `rename_variable_mode`, `set_variable_mode_value`, `set_variable_scopes`, `set_variable_code_syntax`, plus batch ops `batch_create_variables` / `batch_set_variable_values` / `batch_delete_variables` / `batch_bind_variables`.
|
|
188
|
+
- **Variables orchestration (Phase B, Bridge `1.6.0`+):** `import_variable_spec` (idempotent bulk create / update with aliases, `dryRun`), `analyze_variable_order` (read-only ordering diff), `dedupe_variables` (merge duplicates, dry-run by default; canvas write only with `apply: true`), `rebind_variable_aliases` (bulk alias rewrite, `dryRun`), `apply_coverage_suggestions` (audit suggestions → real bindings, dry-run by default).
|
|
187
189
|
- **Styles:** `get_local_styles`, `create_paint_style`, `create_text_style`, `create_effect_style`, `set_text_style`, `set_effect_style`, `set_stroke_style`, `set_fill_style`, `import_style_by_key`.
|
|
190
|
+
- **Styles orchestration (Phase C, Bridge `1.6.0`+):** `import_style_spec` (idempotent bulk create / update of Paint / Text / Effect styles, `dryRun`), `dedupe_styles` (merge duplicates `byName | bySignature`, dry-run by default; canvas write only with `apply: true`), `rebind_style_consumers` (bulk styleId rewrite on consumer nodes, `dryRun`), `audit_style_drift` (READ-ONLY drift between local Paint styles and Variables / `expectations[]`), `apply_style_coverage_suggestions` (Phase A `find_style_coverage_misses` → real `setStyleId*` writes, dry-run by default).
|
|
191
|
+
- **Mockup-from-DesignSystem (Phase D, Bridge `1.6.0`+):** `find_components` (READ-ONLY paginated catalogue of local + library-instantiated components with `componentPropertyDefinitions`; Dev-Mode compatible), `build_mockup` (assemble one auto-layout mockup from a declarative `instance | section | spacer | text` item tree with property / text / fill-binding overrides; `dryRun`-aware), `apply_mockup_dataset` (clone a template per dataset row with row-specific overrides; `dryRun`-aware). Replaces hand-rolled `use_figma { figma.createInstance(...).setProperties(...) }` loops.
|
|
192
|
+
- **Compositions orchestration (Phase E, Bridge `1.6.0`+):** `bulk_generate_compositions` (bulk `generate` / `apply` of composition files in one MCP call; filters `fileIds | names | prefix`; `operation: auto | generate | apply`; per-item error isolation; `dryRun`-aware), `audit_composition_drift` (READ-ONLY drift detector between workspace composition files and tracked Figma components; statuses `linked | unlinked | drift | missing`; Dev-Mode safe). Replaces hand-rolled `for-of` loops over `generate_composition` / `apply_composition` and per-file `check_composition_linked` polling.
|
|
188
193
|
- **Data / nodes:** `apply_mapping`, `apply_all_mappings`, `count_apply_targets`, `generate_instances`, `apply_image`, plus direct node helpers in `data.ts` / `figma-nodes.ts` (`set_node_fill_variable`, `create_rectangle`, `set_auto_layout`, `duplicate_subtree`, `create_component_instance`, `apply_documentation_payload`, extended `create_frame` / `create_text`).
|
|
189
194
|
- **Git:** `git_pull`, `git_hard_pull`, `git_push`.
|
|
190
195
|
- **Orchestration:** `generate_code_from_url`, `compose_from_url`, `document_component`.
|
|
@@ -199,6 +204,8 @@ Registered in `src/mcp-factory.ts` via `tools/*.ts`:
|
|
|
199
204
|
| `sxl://tokens/files` | Token file index |
|
|
200
205
|
| `sxl://tokens/files/{fileId}` | Raw token file body |
|
|
201
206
|
| `sxl://compositions/index` | Composition JSON index |
|
|
207
|
+
| `sxl://agent/recipes/index` | Intent router (start here) |
|
|
208
|
+
| `sxl://agent/recipes/{doc-tokens,doc-component,doc-composition,doc-flow,doc-spec-v2,template-discovery,variable-palette,compose-with-variables,scenario-from-markdown,variable-usage,audit-coverage,find-unused,bulk-variables,auto-bind-from-audit,bulk-styles,style-drift,mockup-builder,bulk-compositions,composition-drift}` | Doc Builder + audit + Phase B + Phase C + Phase D + Phase E orchestration recipes |
|
|
202
209
|
|
|
203
210
|
Cursor / Claude can attach these as context without calling tools.
|
|
204
211
|
|
package/dist/agent-recipes.d.ts
CHANGED
|
@@ -44,6 +44,36 @@ export declare const RECIPE_INDEX: {
|
|
|
44
44
|
}, {
|
|
45
45
|
readonly recipeId: "scenario-from-markdown";
|
|
46
46
|
readonly userPhrases: readonly ["вот md файл сценария, создай flow", "build scenario from this markdown", "у меня есть md с описанием флоу", "создай сценарий из md файла", "render this spec as a figma flow"];
|
|
47
|
+
}, {
|
|
48
|
+
readonly recipeId: "variable-usage";
|
|
49
|
+
readonly userPhrases: readonly ["сколько раз используется accent.medium", "where is this variable used", "посчитай где используется переменная", "render a page with all usages of accent.medium", "найди все объекты с переменной", "show me everywhere this token appears", "выведи на страницу все места где встречается переменная"];
|
|
50
|
+
}, {
|
|
51
|
+
readonly recipeId: "audit-coverage";
|
|
52
|
+
readonly userPhrases: readonly ["проверь везде ли подкреплены переменные", "найди объекты без переменных", "audit raw values without variables", "review the file for missing bindings", "где hex заливки вместо токенов", "найди объекты с дефолтными цветами"];
|
|
53
|
+
}, {
|
|
54
|
+
readonly recipeId: "find-unused";
|
|
55
|
+
readonly userPhrases: readonly ["какие переменные у меня не используются", "find unused variables", "which styles are dead", "почисть неиспользуемые токены", "найди мёртвые стили"];
|
|
56
|
+
}, {
|
|
57
|
+
readonly recipeId: "bulk-variables";
|
|
58
|
+
readonly userPhrases: readonly ["создай набор переменных по этому списку", "import these variables in bulk", "bulk create variables from spec", "обнови переменные пакетно", "перепривяжи алиасы переменных", "rebind aliases from old token to new", "найди дубликаты переменных и слей их", "dedupe variables across collections", "приведи коллекцию в алфавитный порядок", "reorder variables alphabetically"];
|
|
59
|
+
}, {
|
|
60
|
+
readonly recipeId: "auto-bind-from-audit";
|
|
61
|
+
readonly userPhrases: readonly ["примени предложенные переменные к аудиту", "apply variable coverage suggestions", "автопривяжи переменные где есть подсказки", "fix the audit by binding suggested variables", "convert audit suggestions into bindings"];
|
|
62
|
+
}, {
|
|
63
|
+
readonly recipeId: "bulk-styles";
|
|
64
|
+
readonly userPhrases: readonly ["создай набор стилей по этому списку", "import these paint/text/effect styles in bulk", "bulk create paint styles from spec", "обнови стили пакетно", "найди дубликаты стилей и слей их", "dedupe styles across the file", "перепривяжи стили со старого на новый", "rebind style consumers from one style to another", "примени предложенные стили к аудиту", "apply style coverage suggestions"];
|
|
65
|
+
}, {
|
|
66
|
+
readonly recipeId: "style-drift";
|
|
67
|
+
readonly userPhrases: readonly ["проверь дрейф стилей и переменных", "audit style drift vs variables", "стили рассинхронизированы с токенами", "find paint styles that drifted from variables", "сверь PaintStyle со списком ожидаемых цветов", "verify styles against expected colors"];
|
|
68
|
+
}, {
|
|
69
|
+
readonly recipeId: "mockup-builder";
|
|
70
|
+
readonly userPhrases: readonly ["собери макет страницы из компонентов", "build a mockup from existing components", "сделай дашборд из карточек", "render a screen using design system components", "lay out cards in auto-layout", "сложи макет из WCard и WButton", "render a list of N cards from this dataset", "построй продуктовую страницу по описанию", "assemble a settings screen from existing components"];
|
|
71
|
+
}, {
|
|
72
|
+
readonly recipeId: "bulk-compositions";
|
|
73
|
+
readonly userPhrases: readonly ["сгенерируй все компоненты дизайн-системы", "regenerate every WAccordion / WButton from JSON", "пересобери компоненты по композициям", "apply all SXL compositions in this workspace", "обнови компоненты после правок в JSON", "rebuild every composition that drifted", "перегенерируй все компоненты после очистки файла", "fresh-bake the design system from compositions"];
|
|
74
|
+
}, {
|
|
75
|
+
readonly recipeId: "composition-drift";
|
|
76
|
+
readonly userPhrases: readonly ["проверь рассинхрон композиций и компонентов", "audit composition drift", "какие компоненты не соответствуют JSON", "find compositions that drifted from Figma", "сверь tokens/components с реальными ComponentSet", "verify SXL compositions still match the Figma design system", "какие компоненты потерялись", "show compositions whose tracked component was deleted"];
|
|
47
77
|
}];
|
|
48
78
|
readonly decideBetween: readonly [{
|
|
49
79
|
readonly between: readonly ["doc-tokens", "variable-palette"];
|
|
@@ -61,6 +91,62 @@ export declare const RECIPE_INDEX: {
|
|
|
61
91
|
readonly between: readonly ["compose-with-variables", "doc-composition"];
|
|
62
92
|
readonly use_compose_with_variables_when: "goal is to generate a reusable Figma component with variable bindings from a design URL";
|
|
63
93
|
readonly use_doc_composition_when: "goal is to render a documentation frame from an existing composition file";
|
|
94
|
+
}, {
|
|
95
|
+
readonly between: readonly ["variable-usage", "audit-coverage"];
|
|
96
|
+
readonly use_variable_usage_when: "user names a specific variable and wants to know where / how often / 'покажи все места'";
|
|
97
|
+
readonly use_audit_coverage_when: "user wants to know which nodes are NOT bound to variables (e.g. raw hex / dimensions)";
|
|
98
|
+
}, {
|
|
99
|
+
readonly between: readonly ["audit-coverage", "find-unused"];
|
|
100
|
+
readonly use_audit_coverage_when: "the goal is finding nodes that lack a variable / style binding (where to ADD bindings)";
|
|
101
|
+
readonly use_find_unused_when: "the goal is finding variables / styles that nothing references (what to DELETE)";
|
|
102
|
+
}, {
|
|
103
|
+
readonly between: readonly ["audit-coverage", "auto-bind-from-audit"];
|
|
104
|
+
readonly use_audit_coverage_when: "user wants the LIST of missing bindings (no writes)";
|
|
105
|
+
readonly use_auto_bind_from_audit_when: "user wants to APPLY the suggested variables (canvas write — apply_coverage_suggestions)";
|
|
106
|
+
}, {
|
|
107
|
+
readonly between: readonly ["bulk-variables", "doc-tokens"];
|
|
108
|
+
readonly use_bulk_variables_when: "user wants to create / merge / refactor Figma Variables in bulk (one spec → many writes)";
|
|
109
|
+
readonly use_doc_tokens_when: "user wants to render existing token values into a Figma doc frame";
|
|
110
|
+
}, {
|
|
111
|
+
readonly between: readonly ["bulk-styles", "bulk-variables"];
|
|
112
|
+
readonly use_bulk_styles_when: "the targets are Figma local STYLES (PaintStyle / TextStyle / EffectStyle) — fillStyleId / textStyleId / effectStyleId fields";
|
|
113
|
+
readonly use_bulk_variables_when: "the targets are Figma VARIABLES (boundVariables, valuesByMode)";
|
|
114
|
+
}, {
|
|
115
|
+
readonly between: readonly ["bulk-styles", "audit-coverage"];
|
|
116
|
+
readonly use_bulk_styles_when: "user wants to ADD / MERGE / REFACTOR styles, or apply find_style_coverage_misses suggestions";
|
|
117
|
+
readonly use_audit_coverage_when: "user only wants the LIST of nodes missing styleId / variable bindings (no writes)";
|
|
118
|
+
}, {
|
|
119
|
+
readonly between: readonly ["style-drift", "audit-coverage"];
|
|
120
|
+
readonly use_style_drift_when: "user wants to verify EXISTING styles match the source of truth (variables / token snapshot)";
|
|
121
|
+
readonly use_audit_coverage_when: "user wants to find nodes that have NO style binding at all";
|
|
122
|
+
}, {
|
|
123
|
+
readonly between: readonly ["style-drift", "find-unused"];
|
|
124
|
+
readonly use_style_drift_when: "the goal is to detect rendered values that drifted from the source of truth";
|
|
125
|
+
readonly use_find_unused_when: "the goal is to delete styles that nothing references";
|
|
126
|
+
}, {
|
|
127
|
+
readonly between: readonly ["mockup-builder", "doc-component"];
|
|
128
|
+
readonly use_mockup_builder_when: "user wants to ASSEMBLE a screen / dashboard / list from many existing components in auto-layout";
|
|
129
|
+
readonly use_doc_component_when: "user wants to DOCUMENT a single component (title + variants matrix + props table)";
|
|
130
|
+
}, {
|
|
131
|
+
readonly between: readonly ["mockup-builder", "compose-with-variables"];
|
|
132
|
+
readonly use_mockup_builder_when: "the goal is to compose existing components into a layout (consumer)";
|
|
133
|
+
readonly use_compose_with_variables_when: "the goal is to generate / refactor the COMPONENT itself from a design URL (producer)";
|
|
134
|
+
}, {
|
|
135
|
+
readonly between: readonly ["mockup-builder", "doc-flow"];
|
|
136
|
+
readonly use_mockup_builder_when: "user wants a SINGLE auto-layout screen built from components (not a series of pages)";
|
|
137
|
+
readonly use_doc_flow_when: "user wants a STORY of multiple pages / screens stacked side-by-side with captions";
|
|
138
|
+
}, {
|
|
139
|
+
readonly between: readonly ["bulk-compositions", "compose-with-variables"];
|
|
140
|
+
readonly use_bulk_compositions_when: "the composition JSON files already exist in the plugin workspace (`tokens/components/W*.json`) and you want to (re)build many components in one call";
|
|
141
|
+
readonly use_compose_with_variables_when: "the composition JSON does NOT exist yet — you start from a Figma URL, export composition JSON, and generate one component";
|
|
142
|
+
}, {
|
|
143
|
+
readonly between: readonly ["bulk-compositions", "composition-drift"];
|
|
144
|
+
readonly use_bulk_compositions_when: "the user wants to WRITE (generate / apply) compositions";
|
|
145
|
+
readonly use_composition_drift_when: "the user only wants to KNOW which compositions are out of sync (read-only)";
|
|
146
|
+
}, {
|
|
147
|
+
readonly between: readonly ["composition-drift", "style-drift"];
|
|
148
|
+
readonly use_composition_drift_when: "the unit of comparison is a composition JSON ↔ Figma ComponentSet";
|
|
149
|
+
readonly use_style_drift_when: "the unit of comparison is a local PaintStyle ↔ Variable / token snapshot";
|
|
64
150
|
}];
|
|
65
151
|
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
152
|
readonly doneCriteria: "Agent picked exactly one recipe, called only the tools it lists, and produced a verifiable result (doneWhen of that recipe).";
|
|
@@ -202,3 +288,185 @@ export declare const RECIPE_VARIABLE_PALETTE: {
|
|
|
202
288
|
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
289
|
readonly doneCriteria: "One card per target variable next to the template; each swatch is bound to its variable; no use_figma script was used.";
|
|
204
290
|
};
|
|
291
|
+
export declare const RECIPE_VARIABLE_USAGE: {
|
|
292
|
+
readonly id: "variable-usage";
|
|
293
|
+
readonly title: "Find usages of a Figma variable (count + visualize)";
|
|
294
|
+
readonly version: 1;
|
|
295
|
+
readonly userPhrases: readonly ["сколько раз используется accent.medium", "where is this variable used", "посчитай где используется переменная", "render a page with all usages of accent.medium", "найди все объекты с переменной", "выведи на страницу все места где встречается переменная"];
|
|
296
|
+
readonly decideBetween: readonly [{
|
|
297
|
+
readonly between: readonly ["variable-usage", "audit-coverage"];
|
|
298
|
+
readonly hint: "If user wants to find missing bindings (no variable assigned) → audit-coverage. If user names a variable and asks 'where is it used' → variable-usage.";
|
|
299
|
+
}];
|
|
300
|
+
readonly context: "analyze_variable_usage returns a token-friendly summary (counts only). For the full node list, use find_variable_usages with cursor pagination. To visualize the result on the canvas, call render_variable_usage_page (creates a fresh page with cloned references). All three resolve transitive aliases — a variable that aliases the target counts as a usage and is included in target.aliasChain.";
|
|
301
|
+
readonly preferredTools: readonly ["get_variables", "analyze_variable_usage", "find_variable_usages", "render_variable_usage_page"];
|
|
302
|
+
readonly forbidden: readonly ["Writing a use_figma script that walks node.boundVariables manually — analyze_variable_usage already does it (with alias resolution).", "Calling find_variable_usages without limit/cursor for huge files — pagination keeps the agent fast and cheap.", "Cloning nodes by hand into a new page — use render_variable_usage_page (chunked + auto-layout)."];
|
|
303
|
+
readonly steps: readonly ["Identify the variable (variableId is best). If only a name, get_variables narrows it down.", "Call analyze_variable_usage { variable, scope: 'page'|'file' } first — small response, decides next step.", "If user wants details: find_variable_usages { variable, scope, limit }, optionally paginate via the returned cursor.", "If user wants visualization: render_variable_usage_page { variable, scope: 'file', maxClones }. Confirm writesAllowed first via get_plugin_status."];
|
|
304
|
+
readonly doneCriteria: "Agent returned a count + breakdown (analyze) or a paginated record list (find) or created a 'Usage: <variable>' page (render). Transitive aliases included in target.aliasChain.";
|
|
305
|
+
};
|
|
306
|
+
export declare const RECIPE_AUDIT_COVERAGE: {
|
|
307
|
+
readonly id: "audit-coverage";
|
|
308
|
+
readonly title: "Audit nodes that lack a variable / style binding";
|
|
309
|
+
readonly version: 1;
|
|
310
|
+
readonly userPhrases: readonly ["проверь везде ли подкреплены переменные", "найди объекты без переменных", "audit raw values without variables", "review the file for missing bindings", "где hex заливки вместо токенов"];
|
|
311
|
+
readonly decideBetween: readonly [{
|
|
312
|
+
readonly between: readonly ["audit-coverage", "find-unused"];
|
|
313
|
+
readonly hint: "audit-coverage finds where to ADD bindings (raw values). find-unused finds variables/styles to DELETE.";
|
|
314
|
+
}];
|
|
315
|
+
readonly context: "audit_variable_coverage returns SUMMARY only (counts + topOffenders). When `suggest=true` (default) the plugin matches every raw value against existing local variables; the suggestion in topOffenders / details lets the agent propose batch_bind_variables payloads. Style coverage (audit_style_coverage) reports nodes where neither a styleId nor a variable is bound.";
|
|
316
|
+
readonly preferredTools: readonly ["audit_variable_coverage", "find_variable_coverage_misses", "audit_style_coverage", "find_style_coverage_misses", "batch_bind_variables"];
|
|
317
|
+
readonly forbidden: readonly ["Walking the document manually with use_figma — audit_* tools cover the case (chunked, alias-aware).", "Applying suggested bindings without user confirmation — coverage suggestions can be wrong on intentional raw values.", "Running on scope='file' first when 'page' is enough — start narrow, widen on demand."];
|
|
318
|
+
readonly steps: readonly ["Start narrow: audit_variable_coverage { scope: 'page' } — confirm magnitude.", "If acceptable, widen: scope: 'file'.", "For details / fix-up: find_variable_coverage_misses { limit, cursor } — assemble a batch_bind_variables payload from suggestion entries.", "For style coverage do the same with audit_style_coverage / find_style_coverage_misses."];
|
|
319
|
+
readonly doneCriteria: "Agent returned a summary (and optionally a batch_bind_variables proposal) without using use_figma. Coverage gaps are quantified per property and per page.";
|
|
320
|
+
};
|
|
321
|
+
export declare const RECIPE_BULK_VARIABLES: {
|
|
322
|
+
readonly id: "bulk-variables";
|
|
323
|
+
readonly title: "Bulk create / dedupe / rebind / reorder Figma Variables";
|
|
324
|
+
readonly version: 1;
|
|
325
|
+
readonly userPhrases: readonly ["создай набор переменных по этому списку", "import these variables in bulk", "bulk create variables from spec", "обнови переменные пакетно", "перепривяжи алиасы переменных", "rebind aliases from old token to new", "найди дубликаты переменных и слей их", "dedupe variables across collections", "приведи коллекцию в алфавитный порядок", "reorder variables alphabetically"];
|
|
326
|
+
readonly decideBetween: readonly [{
|
|
327
|
+
readonly between: readonly ["bulk-variables", "doc-tokens"];
|
|
328
|
+
readonly hint: "If the user wants to render existing token values as documentation, switch to doc-tokens.";
|
|
329
|
+
}, {
|
|
330
|
+
readonly between: readonly ["bulk-variables", "auto-bind-from-audit"];
|
|
331
|
+
readonly hint: "auto-bind-from-audit applies suggestions from audit_variable_coverage; bulk-variables operates on the variables themselves (CRUD + alias refactors).";
|
|
332
|
+
}];
|
|
333
|
+
readonly context: "Phase B 'thick' commands cover four recurring refactors: (1) declarative bulk import / update via import_variable_spec, (2) duplicate detection + merge via dedupe_variables, (3) alias rewrites across modes via rebind_variable_aliases, (4) read-only ordering analysis via analyze_variable_order. All write commands accept a dry-run mode that returns the exact plan without touching Figma — agents should ALWAYS preview first and surface the plan to the user before committing.";
|
|
334
|
+
readonly preferredTools: readonly ["get_variables", "import_variable_spec", "dedupe_variables", "rebind_variable_aliases", "analyze_variable_order", "batch_bind_variables"];
|
|
335
|
+
readonly forbidden: readonly ["Calling create_variable / set_variable_mode_value in a loop for 5+ items — use import_variable_spec.", "Hand-writing a rebinding loop with rename_variable + set_variable_mode_value — use rebind_variable_aliases.", "Treating analyze_variable_order as a write command — Figma Plugin API does not expose stable variable reordering, so this is diff-only.", "Skipping dryRun on dedupe / rebind / import — always preview before committing.", "Using use_figma scripts to traverse local variables — get_variables + Phase B tools cover the case."];
|
|
336
|
+
readonly steps: readonly ["Read the user's intent: bulk create vs dedupe vs rebind vs reorder. Each maps to one Phase B tool.", "For BULK CREATE / UPDATE: pass spec.collections[] to import_variable_spec with dryRun: true first. The response lists added / updated / skipped variables and unresolved aliases. Re-call without dryRun to commit.", "For DEDUPE: dedupe_variables { strategy: 'byName' | 'byDefaultModeValue' } — default is dry-run. Confirm the proposed survivor with the user, then re-call with apply: true.", "For ALIAS REBIND: rebind_variable_aliases { mappings: [{ fromVariableId, toVariableId }], dryRun: true } first. The response counts how many valuesByMode entries would change. Re-call with dryRun: false to commit.", "For ORDER: analyze_variable_order { collectionId, strategy } — read-only analysis. Return the moves[] to the user; manual reorder in the Variables panel is required."];
|
|
337
|
+
readonly doneCriteria: "Agent produced a single Phase B call (or two: dryRun preview + commit) that the plugin executed; the user has the diff before any write. No use_figma / batch loops were used.";
|
|
338
|
+
};
|
|
339
|
+
export declare const RECIPE_AUTO_BIND_FROM_AUDIT: {
|
|
340
|
+
readonly id: "auto-bind-from-audit";
|
|
341
|
+
readonly title: "Auto-apply audit_variable_coverage suggestions";
|
|
342
|
+
readonly version: 1;
|
|
343
|
+
readonly userPhrases: readonly ["примени предложенные переменные к аудиту", "apply variable coverage suggestions", "автопривяжи переменные где есть подсказки", "fix the audit by binding suggested variables", "convert audit suggestions into bindings"];
|
|
344
|
+
readonly decideBetween: readonly [{
|
|
345
|
+
readonly between: readonly ["auto-bind-from-audit", "audit-coverage"];
|
|
346
|
+
readonly hint: "audit-coverage produces the diagnosis (no writes); auto-bind-from-audit applies the prescribed variable. Always run audit first, confirm, then auto-bind.";
|
|
347
|
+
}];
|
|
348
|
+
readonly context: "find_variable_coverage_misses returns suggestions per node + property: { nodeId, property, suggestion: { variableId, variableName } }. apply_coverage_suggestions translates that array into setBoundVariableForPaint / setBoundVariableForEffect / setBoundVariable writes. Default mode is dry-run — agent receives a preview the user can sign off on. Commit happens only when dryRun: false.";
|
|
349
|
+
readonly preferredTools: readonly ["audit_variable_coverage", "find_variable_coverage_misses", "apply_coverage_suggestions", "batch_bind_variables"];
|
|
350
|
+
readonly forbidden: readonly ["Applying suggestions blindly without showing them to the user — coverage suggestions can be wrong on intentional raw values.", "Calling bind_variable in a loop for each suggestion — apply_coverage_suggestions handles paths like fills[0].color / effects[2].color in one round-trip.", "Skipping the dry-run preview — apply_coverage_suggestions is destructive (it writes bindings on the canvas)."];
|
|
351
|
+
readonly steps: readonly ["Run find_variable_coverage_misses { scope: 'page' | 'file', limit, withSuggestion: true }. Filter entries that have a non-null suggestion.", "Build the suggestions[] array: { nodeId, property, variableId } per entry.", "Call apply_coverage_suggestions with dryRun: true (default). Surface the preview[] to the user.", "On confirmation, re-call apply_coverage_suggestions with dryRun: false to commit. Canvas write — Dev Mode is blocked."];
|
|
352
|
+
readonly doneCriteria: "Bindings prescribed by the audit are applied to the canvas; the response reports applied / failed counts. No use_figma scripts were used.";
|
|
353
|
+
};
|
|
354
|
+
export declare const RECIPE_BULK_STYLES: {
|
|
355
|
+
readonly id: "bulk-styles";
|
|
356
|
+
readonly title: "Bulk create / dedupe / rebind LOCAL Figma styles + apply coverage suggestions (Phase C)";
|
|
357
|
+
readonly version: 1;
|
|
358
|
+
readonly userPhrases: readonly ["создай набор стилей по этому списку", "import these paint / text / effect styles in bulk", "bulk create paint styles from spec", "обнови стили пакетно", "найди дубликаты стилей и слей их", "dedupe styles across the file", "перепривяжи стили со старого на новый", "rebind style consumers from one style to another", "примени предложенные стили к аудиту", "apply style coverage suggestions", "конвертируй raw paints в стили"];
|
|
359
|
+
readonly decideBetween: readonly [{
|
|
360
|
+
readonly between: readonly ["bulk-styles", "bulk-variables"];
|
|
361
|
+
readonly hint: "bulk-styles wraps Figma local STYLES (fillStyleId / textStyleId / effectStyleId). For Figma VARIABLES (boundVariables / valuesByMode) use bulk-variables instead.";
|
|
362
|
+
}, {
|
|
363
|
+
readonly between: readonly ["bulk-styles", "audit-coverage"];
|
|
364
|
+
readonly hint: "audit-coverage only LISTS missing bindings. bulk-styles applies them (apply_style_coverage_suggestions) and refactors styles in bulk.";
|
|
365
|
+
}, {
|
|
366
|
+
readonly between: readonly ["bulk-styles", "style-drift"];
|
|
367
|
+
readonly hint: "style-drift verifies that styles match the source of truth (read-only). bulk-styles modifies styles or their consumers.";
|
|
368
|
+
}];
|
|
369
|
+
readonly context: "Phase C 'thick' commands cover four recurring style refactors: (1) declarative bulk import / update via import_style_spec (PaintStyle + TextStyle + EffectStyle), (2) duplicate detection + merge via dedupe_styles (byName | bySignature), (3) bulk styleId rewriting on consumer nodes via rebind_style_consumers, (4) converting find_style_coverage_misses into setStyleId* writes via apply_style_coverage_suggestions. All write commands accept dry-run / preview mode that returns the plan WITHOUT touching Figma — agent should ALWAYS preview first and surface the diff to the user before committing.";
|
|
370
|
+
readonly preferredTools: readonly ["get_local_styles", "import_style_spec", "dedupe_styles", "rebind_style_consumers", "find_style_coverage_misses", "apply_style_coverage_suggestions"];
|
|
371
|
+
readonly forbidden: readonly ["Calling create_paint_style / create_text_style / create_effect_style in a loop for 5+ items — use import_style_spec.", "Hand-writing a styleId rewriting loop with set_fill_style / set_stroke_style — use rebind_style_consumers.", "Skipping dryRun on dedupe_styles / rebind_style_consumers / apply_style_coverage_suggestions — always preview before committing.", "Using use_figma scripts to traverse local styles — get_local_styles + Phase C tools cover the case.", "Applying coverage suggestions blindly — coverage suggestions can be wrong on intentional raw values."];
|
|
372
|
+
readonly steps: readonly ["Read the user's intent: bulk create vs dedupe vs rebind consumers vs auto-bind from audit. Each maps to one Phase C tool.", "For BULK CREATE / UPDATE: build spec.{paintStyles, textStyles, effectStyles}[] and call import_style_spec with dryRun: true first. SOLID paints accept `color: '#rrggbb[aa]'` shortcut. Re-call without dryRun to commit.", "For DEDUPE: dedupe_styles { strategy: 'byName' | 'bySignature', styleType?: 'PAINT' | 'TEXT' | 'EFFECT' | 'ALL' } — default is dry-run. Confirm the proposed survivor (style with most consumers wins), then re-call with apply: true.", "For STYLE REBIND: rebind_style_consumers { mappings: [{ fromStyleId, toStyleId }], dryRun: true } first. The response counts (node, field) pairs that would change. Re-call with dryRun: false to commit.", "For AUTO-BIND FROM AUDIT: find_style_coverage_misses → assemble suggestions[{ nodeId, property, styleId }] → apply_style_coverage_suggestions { suggestions, dryRun: true }. Style assignments are PER-NODE (PaintStyle covers the whole fills[] array), so duplicates by (nodeId, field) land in skipped[]. Surface preview, then re-call with dryRun: false."];
|
|
373
|
+
readonly doneCriteria: "Agent produced a Phase C call (or two: dryRun preview + commit) that the plugin executed; the user approved the diff before any write. No use_figma / set_*_style loops were used.";
|
|
374
|
+
};
|
|
375
|
+
export declare const RECIPE_STYLE_DRIFT: {
|
|
376
|
+
readonly id: "style-drift";
|
|
377
|
+
readonly title: "Audit drift between local Paint styles and the source of truth (Phase C)";
|
|
378
|
+
readonly version: 1;
|
|
379
|
+
readonly userPhrases: readonly ["проверь дрейф стилей и переменных", "audit style drift vs variables", "стили рассинхронизированы с токенами", "find paint styles that drifted from variables", "сверь PaintStyle со списком ожидаемых цветов", "verify styles against expected colors"];
|
|
380
|
+
readonly decideBetween: readonly [{
|
|
381
|
+
readonly between: readonly ["style-drift", "audit-coverage"];
|
|
382
|
+
readonly hint: "style-drift verifies EXISTING style values vs source of truth. audit-coverage finds nodes WITHOUT a style binding.";
|
|
383
|
+
}, {
|
|
384
|
+
readonly between: readonly ["style-drift", "bulk-styles"];
|
|
385
|
+
readonly hint: "style-drift is READ-ONLY (Dev Mode safe). When drift is found and the user wants to fix it, switch to bulk-styles → import_style_spec to overwrite the drifted style values.";
|
|
386
|
+
}];
|
|
387
|
+
readonly context: "audit_style_drift compares local PaintStyles to the source of truth in two modes: byName-vs-variables (auto-pairs styles with like-named local Variables) or explicit ({ styleId, expectedColor } expectations from a token snapshot). Returns findings[] (drift > tolerance) and skipped[] (styles that couldn't be compared — non-SOLID, non-COLOR variable, etc.). NO canvas writes — fully Dev-Mode-compatible.";
|
|
388
|
+
readonly preferredTools: readonly ["audit_style_drift", "get_variables", "import_style_spec"];
|
|
389
|
+
readonly forbidden: readonly ["Walking PaintStyles + Variables manually with use_figma — audit_style_drift covers it (alias-aware).", "Setting tolerance > 0 silently — when fuzzy matching is enabled, surface the value to the user.", "Treating findings[] as canonical: skipped[] entries (no matching variable, non-SOLID paint, etc.) often need a follow-up question."];
|
|
390
|
+
readonly steps: readonly ["Decide the comparison source: token-driven workflow → byName-vs-variables; token snapshot from the transformer → explicit.", "Call audit_style_drift { request: { mode: 'byName-vs-variables' } } (or explicit + expectations[]) with optional tolerance.", "Surface findings[] grouped by source. For each, show actualColor → expectedColor + delta. Surface skipped[] separately.", "If user wants to fix drift: build an import_style_spec.paintStyles[] payload that overrides the drifted values, dryRun first, then commit."];
|
|
391
|
+
readonly doneCriteria: "Agent produced a deterministic drift report. No canvas writes happened during the audit. If the user requested a fix, a follow-up import_style_spec was issued with explicit dryRun preview.";
|
|
392
|
+
};
|
|
393
|
+
export declare const RECIPE_FIND_UNUSED: {
|
|
394
|
+
readonly id: "find-unused";
|
|
395
|
+
readonly title: "Find unused local variables and styles";
|
|
396
|
+
readonly version: 1;
|
|
397
|
+
readonly userPhrases: readonly ["какие переменные у меня не используются", "find unused variables", "which styles are dead", "почисть неиспользуемые токены", "найди мёртвые стили"];
|
|
398
|
+
readonly context: "find_unused_variables walks the file once, building two reference sets: bindings on every node + alias targets in any variable mode. unused = local variables \\ referenced. find_unused_styles does the equivalent for paint/text/effect styles. Both are read-only.";
|
|
399
|
+
readonly preferredTools: readonly ["find_unused_variables", "find_unused_styles", "batch_delete_variables"];
|
|
400
|
+
readonly forbidden: readonly ["Deleting variables / styles without explicit user confirmation — false positives are possible (e.g. variables used only in published libraries).", "Running unused detection without explaining the scan boundary — it covers the current document only."];
|
|
401
|
+
readonly steps: readonly ["Run find_unused_variables / find_unused_styles — return the lists.", "Confirm with the user which entries to remove (group by collection / styleType for clarity).", "If approved: batch_delete_variables for variables; styles need manual removal (no batch tool yet)."];
|
|
402
|
+
readonly doneCriteria: "Agent returned a deterministic list of unused variables / styles. Deletions only happened after explicit confirmation.";
|
|
403
|
+
};
|
|
404
|
+
export declare const RECIPE_MOCKUP_BUILDER: {
|
|
405
|
+
readonly id: "mockup-builder";
|
|
406
|
+
readonly title: "Assemble a mockup screen from existing design-system components (Phase D)";
|
|
407
|
+
readonly version: 1;
|
|
408
|
+
readonly userPhrases: readonly ["собери макет страницы из компонентов", "build a mockup from existing components", "сделай дашборд из карточек", "render a screen using design system components", "lay out cards in auto-layout", "сложи макет из WCard и WButton", "render a list of N cards from this dataset", "построй продуктовую страницу по описанию", "assemble a settings screen from existing components"];
|
|
409
|
+
readonly decideBetween: readonly [{
|
|
410
|
+
readonly between: readonly ["mockup-builder", "doc-component"];
|
|
411
|
+
readonly hint: "mockup-builder ASSEMBLES a screen from many components; doc-component DOCUMENTS a single component (variants + props).";
|
|
412
|
+
}, {
|
|
413
|
+
readonly between: readonly ["mockup-builder", "compose-with-variables"];
|
|
414
|
+
readonly hint: "mockup-builder is the consumer (lays out instances); compose-with-variables is the producer (creates / refactors the component itself).";
|
|
415
|
+
}, {
|
|
416
|
+
readonly between: readonly ["mockup-builder", "doc-flow"];
|
|
417
|
+
readonly hint: "mockup-builder = single auto-layout screen; doc-flow = multiple pages stacked side-by-side as a story.";
|
|
418
|
+
}];
|
|
419
|
+
readonly context: "Phase D: thick orchestration over `figma.createInstance / setProperties / setBoundVariableForPaint / loadFontAsync`. Pipeline: (1) `find_components` to discover ids / keys + componentPropertyDefinitions; (2) `build_mockup` to assemble an auto-layout container from a declarative item tree (`instance | section | spacer | text`) with property / text / fill-binding overrides; (3) `apply_mockup_dataset` when the same template needs to be cloned per-row from a structured list.";
|
|
420
|
+
readonly preferredTools: readonly ["find_components", "build_mockup", "apply_mockup_dataset", "get_variables"];
|
|
421
|
+
readonly forbidden: readonly ["Calling use_figma to write a hand-rolled `figma.createInstance(...) / setProperties(...)` loop when build_mockup covers the assembly.", "Guessing component names instead of running find_components first — the user's file may have arbitrary local names.", "Skipping dryRun for build_mockup / apply_mockup_dataset — always preview the resolved plan before writing to canvas.", "Hand-coding fill colours when a Figma Variable is available — use fillBindings { variableId } so the mockup picks up theme switches automatically.", "Loading fonts manually — build_mockup loads fonts on demand with a safe Inter Regular fallback.", "Assuming property names like `size#123:0` — pass the human key (`size`); the plugin maps to the internal `name#defId` suffix via `componentProperties`."];
|
|
422
|
+
readonly steps: readonly ["Run find_components { query | prefix?, includeProperties: true, kind?: 'COMPONENT' | 'COMPONENT_SET', limit?: 50 } to enumerate available components. Cache the (id, name, propertyDefinitions, defaultVariantId) list.", "If the user wants library components, set includeRemoteInstances: true so library components instantiated in this file are included; otherwise stay local-only.", "Decide the layout: VERTICAL stack of sections, HORIZONTAL row of cards, or WRAP grid. Pick itemSpacing / padding to match the user's intent (e.g. 16px gutters).", "Build the items[] tree. Use `instance` for components (one of componentId | componentKey | componentName), `section` for nested auto-layout frames, `spacer` for explicit gaps, `text` for bare TEXT layers (TEXT styles can be applied via textStyleId).", "For property / text / fill overrides on instances: pass `properties` (human keys), `textOverrides[]` (layerName + value), `fillBindings[]` (variableId; optional layerName when only one child should receive the fill).", "Call build_mockup { ..., dryRun: true } first. The plugin returns a resolved plan with per-item ok/error. If any errors → fix the spec, do not commit.", "Re-call build_mockup without dryRun to write to canvas. Capture rootNodeId for downstream tools (e.g. document the mockup, run audit_variable_coverage on it).", "If the user wants N cards from a dataset, leave one template instance inside the mockup (kind: 'instance'), then call apply_mockup_dataset { templateNodeId, rows[], dryRun: true } → preview → commit. removeTemplate: true deletes the placeholder after cloning."];
|
|
423
|
+
readonly doneCriteria: "Agent produced one (or a sequence of) Phase D calls (find_components → build_mockup [dryRun → commit] → optional apply_mockup_dataset) that the plugin executed without use_figma. The user approved each diff before commit. The mockup uses real components by id/key (not duplicated geometry) and binds Figma Variables instead of raw hex when a variable is available.";
|
|
424
|
+
};
|
|
425
|
+
export declare const RECIPE_BULK_COMPOSITIONS: {
|
|
426
|
+
readonly id: "bulk-compositions";
|
|
427
|
+
readonly title: "Bulk generate / apply many composition files in one call (Phase E)";
|
|
428
|
+
readonly version: 1;
|
|
429
|
+
readonly userPhrases: readonly ["сгенерируй все компоненты дизайн-системы", "regenerate every WAccordion / WButton / WInput from JSON", "пересобери компоненты по композициям", "apply all SXL compositions in this workspace", "обнови компоненты после правок в JSON", "rebuild every composition that drifted", "перегенерируй все компоненты после очистки файла", "fresh-bake the design system from compositions"];
|
|
430
|
+
readonly decideBetween: readonly [{
|
|
431
|
+
readonly between: readonly ["bulk-compositions", "compose-with-variables"];
|
|
432
|
+
readonly use_bulk_compositions_when: "the composition JSON files already exist in the plugin workspace (`tokens/components/W*.json`) and you want to (re)build many components in one call";
|
|
433
|
+
readonly use_compose_with_variables_when: "the composition JSON does NOT exist yet — you start from a Figma URL, export composition JSON, and generate one component";
|
|
434
|
+
}, {
|
|
435
|
+
readonly between: readonly ["bulk-compositions", "composition-drift"];
|
|
436
|
+
readonly use_bulk_compositions_when: "the user wants to WRITE (generate / apply) compositions";
|
|
437
|
+
readonly use_composition_drift_when: "the user only wants to KNOW which compositions are out of sync (read-only)";
|
|
438
|
+
}, {
|
|
439
|
+
readonly between: readonly ["bulk-compositions", "doc-component"];
|
|
440
|
+
readonly use_bulk_compositions_when: "the goal is to (re)build the actual COMPONENT in Figma from composition JSON";
|
|
441
|
+
readonly use_doc_component_when: "the goal is to render a documentation FRAME for an existing component";
|
|
442
|
+
}];
|
|
443
|
+
readonly context: "Phase E thick orchestration around `handleGenerateComposition` / `handleApplyComposition`. Discovers every `$type:composition` file in the plugin workspace (same source as `list_compositions`), filters by `fileIds | names | prefix`, then runs the per-file pipeline with per-item error isolation (`continueOnError: true` by default). `operation: 'auto'` mirrors the manual UX (apply if a tracked component already exists, otherwise generate); `'generate'` forces a fresh ComponentSet rebuild; `'apply'` forces apply onto an existing component. `dryRun: true` returns the resolved plan WITHOUT touching the canvas — Dev Mode safe.";
|
|
444
|
+
readonly preferredTools: readonly ["list_compositions", "audit_composition_drift", "bulk_generate_compositions"];
|
|
445
|
+
readonly forbidden: readonly ["Calling generate_composition / apply_composition in a hand-written loop for 3+ files — use bulk_generate_compositions to keep per-item error isolation, progress events, and idempotency.", "Using bulk_generate_compositions with `operation: 'apply'` against compositions that have no diff-id tracking entry — the handler will fall back to `generate` per item; if the user explicitly asked for apply-only, run audit_composition_drift first to confirm tracking exists.", "Skipping dryRun when the user expects a preview — agent must surface the resolved plan (file count, expected variant counts, errors) before committing canvas writes.", "Operating on every composition without filters when the user only mentioned a single component family — pass `prefix: 'WAccordion'` / `names: [...]` to keep the run small and idempotent.", "Interpreting `success: true, variantsCreated: 0` as a failure — that's normal idempotent behaviour for `apply` when nothing changed."];
|
|
446
|
+
readonly steps: readonly ["Discover what's in the workspace: read `sxl://compositions/index` (or call list_compositions) to get the full set of composition files + names.", "(Optional) Run audit_composition_drift first when the user is unsure which components actually drifted. Use the report to build the `fileIds` filter for the next step.", "Pick filter scope: `fileIds: [...]` for surgical re-builds, `prefix: 'W'` for a whole DS family, `names: ['WButton', 'WInput']` for a curated list. Omit all filters only when the user explicitly asked to rebuild everything.", "Pick operation: `auto` (default — manual UX), `generate` (force rebuild — use after structural changes / corrupted tracking), `apply` (force apply onto existing — use only when tracking is healthy).", "Call bulk_generate_compositions { ..., dryRun: true } first. The plugin returns the resolved plan with per-item composition name + parse status. If any errors → fix the JSON / config, do not commit.", "Re-call without dryRun to commit. Capture summary { total, processed, created, updated, failed, elapsedMs } and surface it to the user.", "On per-item failures, the run continues by default. Group `items[].errors` by composition for the user; if `continueOnError: false` was set, only `items` up to the first failure are present."];
|
|
447
|
+
readonly doneCriteria: "Agent produced one or two bulk_generate_compositions calls (dryRun → commit) that touched only the requested compositions. Per-item errors were surfaced; failures did not silently rebuild the wrong components. No hand-written generate/apply loops were issued.";
|
|
448
|
+
};
|
|
449
|
+
export declare const RECIPE_COMPOSITION_DRIFT: {
|
|
450
|
+
readonly id: "composition-drift";
|
|
451
|
+
readonly title: "Audit drift between composition JSON files and Figma components (Phase E)";
|
|
452
|
+
readonly version: 1;
|
|
453
|
+
readonly userPhrases: readonly ["проверь рассинхрон композиций и компонентов", "audit composition drift", "какие компоненты не соответствуют JSON", "find compositions that drifted from Figma", "сверь tokens/components с реальными ComponentSet", "verify SXL compositions still match the Figma design system", "какие компоненты потерялись", "show compositions whose tracked component was deleted"];
|
|
454
|
+
readonly decideBetween: readonly [{
|
|
455
|
+
readonly between: readonly ["composition-drift", "bulk-compositions"];
|
|
456
|
+
readonly use_composition_drift_when: "user wants the LIST of out-of-sync compositions (read-only — Dev Mode safe)";
|
|
457
|
+
readonly use_bulk_compositions_when: "user wants to FIX the drift (write — bulk_generate_compositions { fileIds: drifted, operation: 'generate' })";
|
|
458
|
+
}, {
|
|
459
|
+
readonly between: readonly ["composition-drift", "style-drift"];
|
|
460
|
+
readonly use_composition_drift_when: "the unit of comparison is a composition JSON ↔ Figma ComponentSet";
|
|
461
|
+
readonly use_style_drift_when: "the unit of comparison is a local PaintStyle ↔ Variable / token snapshot";
|
|
462
|
+
}, {
|
|
463
|
+
readonly between: readonly ["composition-drift", "find-unused"];
|
|
464
|
+
readonly use_composition_drift_when: "the goal is to verify EXISTING compositions still match the Figma scene";
|
|
465
|
+
readonly use_find_unused_when: "the goal is to clean up dangling local variables / styles (different unit)";
|
|
466
|
+
}];
|
|
467
|
+
readonly context: "audit_composition_drift compares every `$type:composition` file in the plugin workspace against the Figma component it tracked in `diff-id.compositions`. Per-composition status: `linked` (tracking entry valid + Figma node matches), `unlinked` (no tracking — never generated), `drift` (Figma node renamed / variant count mismatch / wrong type), `missing` (tracking points to a deleted node). Findings include human-readable `reason`. Fully Dev-Mode-compatible — never touches the canvas.";
|
|
468
|
+
readonly preferredTools: readonly ["audit_composition_drift", "list_compositions", "bulk_generate_compositions"];
|
|
469
|
+
readonly forbidden: readonly ["Walking diff-id.json + Figma scene tree manually with use_figma — audit_composition_drift covers it.", "Treating `unlinked` as drift — it just means the composition was never generated. Surface it as a separate bucket.", "Auto-fixing without confirmation — drift can mean the designer intentionally renamed the Figma component; ask before running bulk_generate_compositions."];
|
|
470
|
+
readonly steps: readonly ["Run audit_composition_drift with appropriate filters: `prefix: 'W'` for the whole DS, `names: [...]` for a curated list, no filters for the full workspace.", "Group findings by status (linked / unlinked / drift / missing) and surface counts to the user.", "For each `drift` / `missing` finding, surface: composition name, fileId, status, reason, expected vs actual variant count, tracked componentSetId.", "If user wants to fix drift: call bulk_generate_compositions { fileIds: [drift+missing fileIds], operation: 'generate', dryRun: true } first → preview → commit.", "For `unlinked` findings: ask whether to generate them as new components (bulk_generate_compositions { operation: 'auto' }) or leave them."];
|
|
471
|
+
readonly doneCriteria: "Agent returned a deterministic drift report with per-composition status. No canvas writes happened during the audit. If the user approved a fix, a follow-up bulk_generate_compositions was issued with explicit dryRun preview.";
|
|
472
|
+
};
|