figma-console-mcp 1.26.0 → 1.27.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 +17 -11
- package/dist/core/tokens/alias-resolver.d.ts +40 -0
- package/dist/core/tokens/alias-resolver.d.ts.map +1 -0
- package/dist/core/tokens/alias-resolver.js +99 -0
- package/dist/core/tokens/alias-resolver.js.map +1 -0
- package/dist/core/tokens/config.d.ts +352 -0
- package/dist/core/tokens/config.d.ts.map +1 -0
- package/dist/core/tokens/config.js +285 -0
- package/dist/core/tokens/config.js.map +1 -0
- package/dist/core/tokens/figma-converter.d.ts +81 -0
- package/dist/core/tokens/figma-converter.d.ts.map +1 -0
- package/dist/core/tokens/figma-converter.js +196 -0
- package/dist/core/tokens/figma-converter.js.map +1 -0
- package/dist/core/tokens/formatters/css-vars.d.ts +24 -0
- package/dist/core/tokens/formatters/css-vars.d.ts.map +1 -0
- package/dist/core/tokens/formatters/css-vars.js +330 -0
- package/dist/core/tokens/formatters/css-vars.js.map +1 -0
- package/dist/core/tokens/formatters/dtcg.d.ts +27 -0
- package/dist/core/tokens/formatters/dtcg.d.ts.map +1 -0
- package/dist/core/tokens/formatters/dtcg.js +300 -0
- package/dist/core/tokens/formatters/dtcg.js.map +1 -0
- package/dist/core/tokens/formatters/index.d.ts +30 -0
- package/dist/core/tokens/formatters/index.d.ts.map +1 -0
- package/dist/core/tokens/formatters/index.js +46 -0
- package/dist/core/tokens/formatters/index.js.map +1 -0
- package/dist/core/tokens/formatters/json.d.ts +5 -0
- package/dist/core/tokens/formatters/json.d.ts.map +1 -0
- package/dist/core/tokens/formatters/json.js +8 -0
- package/dist/core/tokens/formatters/json.js.map +1 -0
- package/dist/core/tokens/formatters/less.d.ts +4 -0
- package/dist/core/tokens/formatters/less.d.ts.map +1 -0
- package/dist/core/tokens/formatters/less.js +5 -0
- package/dist/core/tokens/formatters/less.js.map +1 -0
- package/dist/core/tokens/formatters/scss.d.ts +4 -0
- package/dist/core/tokens/formatters/scss.d.ts.map +1 -0
- package/dist/core/tokens/formatters/scss.js +5 -0
- package/dist/core/tokens/formatters/scss.js.map +1 -0
- package/dist/core/tokens/formatters/stubs.d.ts +8 -0
- package/dist/core/tokens/formatters/stubs.d.ts.map +1 -0
- package/dist/core/tokens/formatters/stubs.js +11 -0
- package/dist/core/tokens/formatters/stubs.js.map +1 -0
- package/dist/core/tokens/formatters/style-dictionary-v3.d.ts +4 -0
- package/dist/core/tokens/formatters/style-dictionary-v3.d.ts.map +1 -0
- package/dist/core/tokens/formatters/style-dictionary-v3.js +5 -0
- package/dist/core/tokens/formatters/style-dictionary-v3.js.map +1 -0
- package/dist/core/tokens/formatters/tailwind-v3.d.ts +4 -0
- package/dist/core/tokens/formatters/tailwind-v3.d.ts.map +1 -0
- package/dist/core/tokens/formatters/tailwind-v3.js +5 -0
- package/dist/core/tokens/formatters/tailwind-v3.js.map +1 -0
- package/dist/core/tokens/formatters/tailwind-v4.d.ts +4 -0
- package/dist/core/tokens/formatters/tailwind-v4.d.ts.map +1 -0
- package/dist/core/tokens/formatters/tailwind-v4.js +5 -0
- package/dist/core/tokens/formatters/tailwind-v4.js.map +1 -0
- package/dist/core/tokens/formatters/tokens-studio.d.ts +4 -0
- package/dist/core/tokens/formatters/tokens-studio.d.ts.map +1 -0
- package/dist/core/tokens/formatters/tokens-studio.js +5 -0
- package/dist/core/tokens/formatters/tokens-studio.js.map +1 -0
- package/dist/core/tokens/formatters/ts-module.d.ts +4 -0
- package/dist/core/tokens/formatters/ts-module.d.ts.map +1 -0
- package/dist/core/tokens/formatters/ts-module.js +5 -0
- package/dist/core/tokens/formatters/ts-module.js.map +1 -0
- package/dist/core/tokens/index.d.ts +17 -0
- package/dist/core/tokens/index.d.ts.map +1 -0
- package/dist/core/tokens/index.js +16 -0
- package/dist/core/tokens/index.js.map +1 -0
- package/dist/core/tokens/parsers/css-vars.d.ts +3 -0
- package/dist/core/tokens/parsers/css-vars.d.ts.map +1 -0
- package/dist/core/tokens/parsers/css-vars.js +5 -0
- package/dist/core/tokens/parsers/css-vars.js.map +1 -0
- package/dist/core/tokens/parsers/dtcg.d.ts +21 -0
- package/dist/core/tokens/parsers/dtcg.d.ts.map +1 -0
- package/dist/core/tokens/parsers/dtcg.js +254 -0
- package/dist/core/tokens/parsers/dtcg.js.map +1 -0
- package/dist/core/tokens/parsers/index.d.ts +37 -0
- package/dist/core/tokens/parsers/index.d.ts.map +1 -0
- package/dist/core/tokens/parsers/index.js +139 -0
- package/dist/core/tokens/parsers/index.js.map +1 -0
- package/dist/core/tokens/parsers/json.d.ts +4 -0
- package/dist/core/tokens/parsers/json.d.ts.map +1 -0
- package/dist/core/tokens/parsers/json.js +8 -0
- package/dist/core/tokens/parsers/json.js.map +1 -0
- package/dist/core/tokens/parsers/scss.d.ts +3 -0
- package/dist/core/tokens/parsers/scss.d.ts.map +1 -0
- package/dist/core/tokens/parsers/scss.js +5 -0
- package/dist/core/tokens/parsers/scss.js.map +1 -0
- package/dist/core/tokens/parsers/stubs.d.ts +10 -0
- package/dist/core/tokens/parsers/stubs.d.ts.map +1 -0
- package/dist/core/tokens/parsers/stubs.js +13 -0
- package/dist/core/tokens/parsers/stubs.js.map +1 -0
- package/dist/core/tokens/parsers/style-dictionary-v3.d.ts +3 -0
- package/dist/core/tokens/parsers/style-dictionary-v3.d.ts.map +1 -0
- package/dist/core/tokens/parsers/style-dictionary-v3.js +5 -0
- package/dist/core/tokens/parsers/style-dictionary-v3.js.map +1 -0
- package/dist/core/tokens/parsers/tailwind-v3.d.ts +3 -0
- package/dist/core/tokens/parsers/tailwind-v3.d.ts.map +1 -0
- package/dist/core/tokens/parsers/tailwind-v3.js +5 -0
- package/dist/core/tokens/parsers/tailwind-v3.js.map +1 -0
- package/dist/core/tokens/parsers/tailwind-v4.d.ts +3 -0
- package/dist/core/tokens/parsers/tailwind-v4.d.ts.map +1 -0
- package/dist/core/tokens/parsers/tailwind-v4.js +5 -0
- package/dist/core/tokens/parsers/tailwind-v4.js.map +1 -0
- package/dist/core/tokens/parsers/tokens-studio.d.ts +3 -0
- package/dist/core/tokens/parsers/tokens-studio.d.ts.map +1 -0
- package/dist/core/tokens/parsers/tokens-studio.js +5 -0
- package/dist/core/tokens/parsers/tokens-studio.js.map +1 -0
- package/dist/core/tokens/schemas.d.ts +152 -0
- package/dist/core/tokens/schemas.d.ts.map +1 -0
- package/dist/core/tokens/schemas.js +149 -0
- package/dist/core/tokens/schemas.js.map +1 -0
- package/dist/core/tokens/transforms/color.d.ts +7 -0
- package/dist/core/tokens/transforms/color.d.ts.map +1 -0
- package/dist/core/tokens/transforms/color.js +10 -0
- package/dist/core/tokens/transforms/color.js.map +1 -0
- package/dist/core/tokens/transforms/index.d.ts +34 -0
- package/dist/core/tokens/transforms/index.d.ts.map +1 -0
- package/dist/core/tokens/transforms/index.js +28 -0
- package/dist/core/tokens/transforms/index.js.map +1 -0
- package/dist/core/tokens/transforms/size.d.ts +6 -0
- package/dist/core/tokens/transforms/size.d.ts.map +1 -0
- package/dist/core/tokens/transforms/size.js +7 -0
- package/dist/core/tokens/transforms/size.js.map +1 -0
- package/dist/core/tokens/types.d.ts +228 -0
- package/dist/core/tokens/types.d.ts.map +1 -0
- package/dist/core/tokens/types.js +19 -0
- package/dist/core/tokens/types.js.map +1 -0
- package/dist/core/tokens-tools.d.ts +36 -0
- package/dist/core/tokens-tools.d.ts.map +1 -0
- package/dist/core/tokens-tools.js +841 -0
- package/dist/core/tokens-tools.js.map +1 -0
- package/dist/local.d.ts.map +1 -1
- package/dist/local.js +14 -3
- package/dist/local.js.map +1 -1
- package/figma-desktop-bridge/code.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,9 +51,9 @@ Figma Console MCP connects AI assistants (like Claude) to Figma, enabling:
|
|
|
51
51
|
| Real-time monitoring (console, selection) | ✅ | ❌ | ❌ |
|
|
52
52
|
| Desktop Bridge plugin | ✅ | ✅ | ❌ |
|
|
53
53
|
| Requires Node.js | Yes | **No** | No |
|
|
54
|
-
| **Total tools available** | **
|
|
54
|
+
| **Total tools available** | **103** | **93** | **9** |
|
|
55
55
|
|
|
56
|
-
> **Bottom line:** Remote SSE is **read-only** with ~38% of the tools. **Cloud Mode** unlocks write access from web AI clients without Node.js. NPX/Local Git gives the full
|
|
56
|
+
> **Bottom line:** Remote SSE is **read-only** with ~38% of the tools. **Cloud Mode** unlocks write access from web AI clients without Node.js. NPX/Local Git gives the full 103 tools with real-time monitoring.
|
|
57
57
|
|
|
58
58
|
---
|
|
59
59
|
|
|
@@ -61,7 +61,7 @@ Figma Console MCP connects AI assistants (like Claude) to Figma, enabling:
|
|
|
61
61
|
|
|
62
62
|
**Best for:** Designers who want full AI-assisted design capabilities.
|
|
63
63
|
|
|
64
|
-
**What you get:** All
|
|
64
|
+
**What you get:** All 103 tools including design creation, variable management, and component instantiation.
|
|
65
65
|
|
|
66
66
|
#### Prerequisites
|
|
67
67
|
|
|
@@ -128,9 +128,11 @@ If you're not sure where to put the JSON configuration above, here's where each
|
|
|
128
128
|
3. Select `~/.figma-console-mcp/plugin/manifest.json` (stable path, auto-created by the MCP server)
|
|
129
129
|
4. Run the plugin in your Figma file — it scans ports 9223–9232 and connects automatically to your running MCP server
|
|
130
130
|
|
|
131
|
-
> **Heads-up on plugin updates.** Figma caches plugin files (`code.js` and `ui.html`) at the application level.
|
|
131
|
+
> **Heads-up on plugin updates.** Figma caches plugin files (`code.js` and `ui.html`) at the application level. The MCP server refreshes the files at `~/.figma-console-mcp/plugin/` on every startup, but Figma keeps using its cached copy until you re-import the manifest.
|
|
132
132
|
>
|
|
133
|
-
>
|
|
133
|
+
> **Re-importing is _required_ only when a release notes entry says so** — typically when the plugin adds a new method the server needs (e.g. v1.22.4, v1.10.0). For most upgrades the new server stays wire-compatible with the previous plugin, and re-importing is **optional**: you'll still get every functional change, just not the cosmetic plugin-side touches (status-pill copy, `pluginVersion` reporting).
|
|
134
|
+
>
|
|
135
|
+
> When you do re-import: Plugins → Manage plugins → re-import `~/.figma-console-mcp/plugin/manifest.json`. The stable path never changes, so it's a one-click step.
|
|
134
136
|
|
|
135
137
|
#### Step 4: Restart Your MCP Client
|
|
136
138
|
|
|
@@ -156,7 +158,7 @@ Create a simple frame with a blue background
|
|
|
156
158
|
|
|
157
159
|
**Best for:** Developers who want to modify source code or contribute to the project.
|
|
158
160
|
|
|
159
|
-
**What you get:** Same
|
|
161
|
+
**What you get:** Same 103 tools as NPX, plus full source code access.
|
|
160
162
|
|
|
161
163
|
#### Quick Setup
|
|
162
164
|
|
|
@@ -245,7 +247,7 @@ Ready for design creation? Follow the [NPX Setup](#-npx-setup-recommended) guide
|
|
|
245
247
|
|
|
246
248
|
**Best for:** Using Claude.ai, v0, Replit, or Lovable to create and modify Figma designs — no Node.js required.
|
|
247
249
|
|
|
248
|
-
**What you get:**
|
|
250
|
+
**What you get:** 95 tools including full write access — design creation, variable management, component instantiation, and all REST API tools. Only real-time monitoring (console logs, selection tracking, document changes) requires Local Mode.
|
|
249
251
|
|
|
250
252
|
#### Prerequisites
|
|
251
253
|
|
|
@@ -302,7 +304,7 @@ AI Client → Cloud MCP Server → Durable Object Relay → Desktop Bridge Plugi
|
|
|
302
304
|
| Feature | NPX (Recommended) | Cloud Mode | Local Git | Remote SSE |
|
|
303
305
|
|---------|-------------------|------------|-----------|------------|
|
|
304
306
|
| **Setup time** | ~10 minutes | ~5 minutes | ~15 minutes | ~2 minutes |
|
|
305
|
-
| **Total tools** | **
|
|
307
|
+
| **Total tools** | **103** | **93** | **103** | **9** (read-only) |
|
|
306
308
|
| **Design creation** | ✅ | ✅ | ✅ | ❌ |
|
|
307
309
|
| **Variable management** | ✅ | ✅ | ✅ | ❌ |
|
|
308
310
|
| **Component instantiation** | ✅ | ✅ | ✅ | ❌ |
|
|
@@ -317,7 +319,7 @@ AI Client → Cloud MCP Server → Durable Object Relay → Desktop Bridge Plugi
|
|
|
317
319
|
| **Automatic updates** | ✅ (`@latest`) | ✅ | Manual (`git pull`) | ✅ |
|
|
318
320
|
| **Source code access** | ❌ | ❌ | ✅ | ❌ |
|
|
319
321
|
|
|
320
|
-
> **Key insight:** Remote SSE is read-only. Cloud Mode adds write access for web AI clients without Node.js. NPX/Local Git give the full
|
|
322
|
+
> **Key insight:** Remote SSE is read-only. Cloud Mode adds write access for web AI clients without Node.js. NPX/Local Git give the full 103 tools.
|
|
321
323
|
|
|
322
324
|
**📖 [Complete Feature Comparison](docs/mode-comparison.md)**
|
|
323
325
|
|
|
@@ -419,6 +421,10 @@ When you first use design system tools:
|
|
|
419
421
|
- `figma_check_design_parity` - Compare Figma component specs against code implementation, producing a scored diff report with actionable fix items
|
|
420
422
|
- `figma_generate_component_doc` - Generate platform-agnostic markdown documentation by merging Figma design data with code-side info
|
|
421
423
|
|
|
424
|
+
### 🔁 Token Sync (Local Mode + Cloud Mode)
|
|
425
|
+
- `figma_export_tokens` - **Export Figma variables to design token files in your codebase.** Canonical DTCG JSON + CSS custom properties out of the box. Diff-aware merge against existing source files (only writes what changed). `tokens.config.json` autodiscovery means zero-arg calls after first setup. Replaces Style Dictionary and Tokens Studio's export pipeline for popular styling methods.
|
|
426
|
+
- `figma_import_tokens` - **Push code-side token edits back to Figma.** Diff against current Figma state, apply only the deltas. Round-trip safe — Figma variable IDs preserved in DTCG `$extensions["figma-console-mcp"]` so renames on either side don't create duplicates. Dry-run default for safety. In Cloud Mode, pass tokens inline via `payload` or `files` (no local filesystem access).
|
|
427
|
+
|
|
422
428
|
### 🔧 Variable Management (Local Mode + Cloud Mode)
|
|
423
429
|
- `figma_create_variable_collection` - Create new variable collections with modes
|
|
424
430
|
- `figma_create_variable` - Create COLOR, FLOAT, STRING, or BOOLEAN variables
|
|
@@ -653,7 +659,7 @@ The **Figma Desktop Bridge** plugin is the recommended way to connect Figma to t
|
|
|
653
659
|
- The MCP server communicates via **WebSocket** through the Desktop Bridge plugin
|
|
654
660
|
- The server tries port 9223 first, then automatically falls back through ports 9224–9232 if needed
|
|
655
661
|
- The plugin scans all ports in the range and connects to every active server it finds
|
|
656
|
-
- All
|
|
662
|
+
- All 103 tools work through the WebSocket transport
|
|
657
663
|
|
|
658
664
|
**Multiple files:** The WebSocket server supports multiple simultaneous plugin connections — one per open Figma file. Each connection is tracked by file key with independent state (selection, document changes, console logs).
|
|
659
665
|
|
|
@@ -792,7 +798,7 @@ The architecture supports adding new apps with minimal boilerplate — each app
|
|
|
792
798
|
|
|
793
799
|
## 🛤️ Roadmap
|
|
794
800
|
|
|
795
|
-
**Current Status:** v1.23.0 (Stable) - Production-ready with version history & time-series awareness, FigJam + Slides support, Cloud Write Relay, Design System Kit, WebSocket-only connectivity, smart multi-file tracking,
|
|
801
|
+
**Current Status:** v1.23.0 (Stable) - Production-ready with version history & time-series awareness, FigJam + Slides support, Cloud Write Relay, Design System Kit, WebSocket-only connectivity, smart multi-file tracking, 103 tools, Comments API, and MCP Apps
|
|
796
802
|
|
|
797
803
|
**Recent Releases:**
|
|
798
804
|
- [x] **v1.17.0** - Figma Slides Support: 15 new tools for managing presentations — slides, transitions, content, reordering, and navigation. Inspired by Toni Haidamous (PR #11).
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alias reference resolution and validation.
|
|
3
|
+
*
|
|
4
|
+
* DTCG alias references look like `{color.primary}` or `{tier-1.color.blue.500}`.
|
|
5
|
+
* They can chain (an alias can reference another alias), but cycles are an
|
|
6
|
+
* error.
|
|
7
|
+
*
|
|
8
|
+
* This module:
|
|
9
|
+
* - Resolves an alias to its eventual literal value (for formatters that
|
|
10
|
+
* can't natively express references — CSS, SCSS, Tailwind).
|
|
11
|
+
* - Validates that every alias points to an existing token.
|
|
12
|
+
* - Detects cycles.
|
|
13
|
+
*/
|
|
14
|
+
import type { Token, TokenDocument, TokenValue } from "./types.js";
|
|
15
|
+
/**
|
|
16
|
+
* Build a lookup map from dot-path strings (e.g. "color.primary") to Token
|
|
17
|
+
* objects. Used as the index for resolveAliases().
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildTokenIndex(doc: TokenDocument): Map<string, Token>;
|
|
20
|
+
/**
|
|
21
|
+
* Resolve a single alias reference. Returns the eventual literal value, or
|
|
22
|
+
* throws if the reference is unresolvable or cyclic.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveReference(reference: string, mode: string, index: Map<string, Token>, seen?: Set<string>): TokenValue;
|
|
25
|
+
/**
|
|
26
|
+
* Validate every alias in the document. Returns a list of error messages —
|
|
27
|
+
* empty array means all aliases resolve cleanly.
|
|
28
|
+
*/
|
|
29
|
+
export declare function validateAliases(doc: TokenDocument): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Format an alias reference for DTCG output. DTCG uses `{path.to.token}`
|
|
32
|
+
* syntax with curly braces.
|
|
33
|
+
*/
|
|
34
|
+
export declare function formatDtcgReference(referencePath: string[]): string;
|
|
35
|
+
/**
|
|
36
|
+
* Parse a DTCG alias string back into a path array. Returns null if the
|
|
37
|
+
* string isn't an alias reference.
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseDtcgReference(s: string): string[] | null;
|
|
40
|
+
//# sourceMappingURL=alias-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alias-resolver.d.ts","sourceRoot":"","sources":["../../../src/core/tokens/alias-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnE;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAStE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,EACzB,IAAI,GAAE,GAAG,CAAC,MAAM,CAAa,GAC5B,UAAU,CAsCZ;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,EAAE,CAqB5D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,CAEnE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAI7D"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alias reference resolution and validation.
|
|
3
|
+
*
|
|
4
|
+
* DTCG alias references look like `{color.primary}` or `{tier-1.color.blue.500}`.
|
|
5
|
+
* They can chain (an alias can reference another alias), but cycles are an
|
|
6
|
+
* error.
|
|
7
|
+
*
|
|
8
|
+
* This module:
|
|
9
|
+
* - Resolves an alias to its eventual literal value (for formatters that
|
|
10
|
+
* can't natively express references — CSS, SCSS, Tailwind).
|
|
11
|
+
* - Validates that every alias points to an existing token.
|
|
12
|
+
* - Detects cycles.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Build a lookup map from dot-path strings (e.g. "color.primary") to Token
|
|
16
|
+
* objects. Used as the index for resolveAliases().
|
|
17
|
+
*/
|
|
18
|
+
export function buildTokenIndex(doc) {
|
|
19
|
+
const index = new Map();
|
|
20
|
+
for (const set of doc.sets) {
|
|
21
|
+
for (const token of set.tokens) {
|
|
22
|
+
const key = token.path.join(".");
|
|
23
|
+
index.set(key, token);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return index;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve a single alias reference. Returns the eventual literal value, or
|
|
30
|
+
* throws if the reference is unresolvable or cyclic.
|
|
31
|
+
*/
|
|
32
|
+
export function resolveReference(reference, mode, index, seen = new Set()) {
|
|
33
|
+
// Strip the curly braces if present: "{color.primary}" → "color.primary"
|
|
34
|
+
const path = reference.replace(/^\{|\}$/g, "");
|
|
35
|
+
if (seen.has(path)) {
|
|
36
|
+
throw new Error(`[figma-console-mcp] Alias cycle detected: ${[...seen, path].join(" → ")}`);
|
|
37
|
+
}
|
|
38
|
+
seen.add(path);
|
|
39
|
+
const target = index.get(path);
|
|
40
|
+
if (!target) {
|
|
41
|
+
throw new Error(`[figma-console-mcp] Unresolvable alias reference: {${path}}`);
|
|
42
|
+
}
|
|
43
|
+
// Find the value for the requested mode; fall back to the only mode if
|
|
44
|
+
// there's just one (alias's target may be single-mode while the source
|
|
45
|
+
// is multi-mode, or vice versa).
|
|
46
|
+
const value = target.values[mode] ??
|
|
47
|
+
(Object.keys(target.values).length === 1
|
|
48
|
+
? Object.values(target.values)[0]
|
|
49
|
+
: undefined);
|
|
50
|
+
if (!value) {
|
|
51
|
+
throw new Error(`[figma-console-mcp] Alias {${path}} has no value for mode "${mode}"`);
|
|
52
|
+
}
|
|
53
|
+
// Chain: if the target's value is itself an alias, recurse.
|
|
54
|
+
if (value.reference) {
|
|
55
|
+
return resolveReference(value.reference, mode, index, seen);
|
|
56
|
+
}
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Validate every alias in the document. Returns a list of error messages —
|
|
61
|
+
* empty array means all aliases resolve cleanly.
|
|
62
|
+
*/
|
|
63
|
+
export function validateAliases(doc) {
|
|
64
|
+
const index = buildTokenIndex(doc);
|
|
65
|
+
const errors = [];
|
|
66
|
+
for (const set of doc.sets) {
|
|
67
|
+
for (const token of set.tokens) {
|
|
68
|
+
for (const [mode, value] of Object.entries(token.values)) {
|
|
69
|
+
if (value.reference) {
|
|
70
|
+
try {
|
|
71
|
+
resolveReference(value.reference, mode, index);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
errors.push(`${token.path.join(".")} (mode "${mode}"): ${err instanceof Error ? err.message : String(err)}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return errors;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Format an alias reference for DTCG output. DTCG uses `{path.to.token}`
|
|
84
|
+
* syntax with curly braces.
|
|
85
|
+
*/
|
|
86
|
+
export function formatDtcgReference(referencePath) {
|
|
87
|
+
return `{${referencePath.join(".")}}`;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Parse a DTCG alias string back into a path array. Returns null if the
|
|
91
|
+
* string isn't an alias reference.
|
|
92
|
+
*/
|
|
93
|
+
export function parseDtcgReference(s) {
|
|
94
|
+
const match = s.match(/^\{([^}]+)\}$/);
|
|
95
|
+
if (!match)
|
|
96
|
+
return null;
|
|
97
|
+
return match[1].split(".");
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=alias-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alias-resolver.js","sourceRoot":"","sources":["../../../src/core/tokens/alias-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tokens.config.json schema, loader, and autodiscovery for the figma-console-mcp
|
|
3
|
+
* token sync engine.
|
|
4
|
+
*
|
|
5
|
+
* Both figma_export_tokens and figma_import_tokens read this single config so
|
|
6
|
+
* follow-up calls in a project are zero-arg. Autodiscovery walks up from the
|
|
7
|
+
* current working directory looking for `tokens.config.json` at each level
|
|
8
|
+
* — same convention as `tsconfig.json`, `package.json`, `.eslintrc`, etc.
|
|
9
|
+
*/
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import type { ConflictResolution, ExportFormat } from "./types.js";
|
|
12
|
+
/**
|
|
13
|
+
* Schema for a single output target in `tokens.config.json`. Each entry
|
|
14
|
+
* produces one or more files when figma_export_tokens runs.
|
|
15
|
+
*/
|
|
16
|
+
declare const OutputTargetSchema: z.ZodObject<{
|
|
17
|
+
format: z.ZodEnum<["dtcg", "tokens-studio", "css-vars", "tailwind-v4", "tailwind-v3", "scss", "less", "ts-module", "json-flat", "json-nested", "style-dictionary-v3"]>;
|
|
18
|
+
/** Optional filename override. Default is derived from format + scope. */
|
|
19
|
+
filename: z.ZodOptional<z.ZodString>;
|
|
20
|
+
/** Output prefix applied to every token name (e.g. "ds-", "al-"). */
|
|
21
|
+
prefix: z.ZodOptional<z.ZodString>;
|
|
22
|
+
/** Emit one file per mode (e.g. tokens-light.css, tokens-dark.css). */
|
|
23
|
+
splitByMode: z.ZodOptional<z.ZodBoolean>;
|
|
24
|
+
/** Emit one file per token set / Figma collection. */
|
|
25
|
+
splitByCollection: z.ZodOptional<z.ZodBoolean>;
|
|
26
|
+
/**
|
|
27
|
+
* If true, alias references are resolved to literal values in the output.
|
|
28
|
+
* If false, aliases are preserved (default for JSON formats, forced true
|
|
29
|
+
* for CSS/SCSS/Tailwind/etc. since they can't natively express aliases).
|
|
30
|
+
*/
|
|
31
|
+
resolveAliases: z.ZodOptional<z.ZodBoolean>;
|
|
32
|
+
/** Per-target transform options. Override the global defaults. */
|
|
33
|
+
transforms: z.ZodOptional<z.ZodObject<{
|
|
34
|
+
colorFormat: z.ZodOptional<z.ZodEnum<["hex", "hex8", "rgba", "oklch", "hsl"]>>;
|
|
35
|
+
sizeUnit: z.ZodOptional<z.ZodEnum<["px", "rem", "pt", "dp"]>>;
|
|
36
|
+
remBase: z.ZodOptional<z.ZodNumber>;
|
|
37
|
+
}, "strip", z.ZodTypeAny, {
|
|
38
|
+
colorFormat?: "hex" | "hex8" | "rgba" | "oklch" | "hsl" | undefined;
|
|
39
|
+
sizeUnit?: "px" | "rem" | "pt" | "dp" | undefined;
|
|
40
|
+
remBase?: number | undefined;
|
|
41
|
+
}, {
|
|
42
|
+
colorFormat?: "hex" | "hex8" | "rgba" | "oklch" | "hsl" | undefined;
|
|
43
|
+
sizeUnit?: "px" | "rem" | "pt" | "dp" | undefined;
|
|
44
|
+
remBase?: number | undefined;
|
|
45
|
+
}>>;
|
|
46
|
+
}, "strip", z.ZodTypeAny, {
|
|
47
|
+
format: "dtcg" | "tokens-studio" | "css-vars" | "tailwind-v4" | "tailwind-v3" | "scss" | "less" | "ts-module" | "json-flat" | "json-nested" | "style-dictionary-v3";
|
|
48
|
+
resolveAliases?: boolean | undefined;
|
|
49
|
+
filename?: string | undefined;
|
|
50
|
+
prefix?: string | undefined;
|
|
51
|
+
splitByMode?: boolean | undefined;
|
|
52
|
+
splitByCollection?: boolean | undefined;
|
|
53
|
+
transforms?: {
|
|
54
|
+
colorFormat?: "hex" | "hex8" | "rgba" | "oklch" | "hsl" | undefined;
|
|
55
|
+
sizeUnit?: "px" | "rem" | "pt" | "dp" | undefined;
|
|
56
|
+
remBase?: number | undefined;
|
|
57
|
+
} | undefined;
|
|
58
|
+
}, {
|
|
59
|
+
format: "dtcg" | "tokens-studio" | "css-vars" | "tailwind-v4" | "tailwind-v3" | "scss" | "less" | "ts-module" | "json-flat" | "json-nested" | "style-dictionary-v3";
|
|
60
|
+
resolveAliases?: boolean | undefined;
|
|
61
|
+
filename?: string | undefined;
|
|
62
|
+
prefix?: string | undefined;
|
|
63
|
+
splitByMode?: boolean | undefined;
|
|
64
|
+
splitByCollection?: boolean | undefined;
|
|
65
|
+
transforms?: {
|
|
66
|
+
colorFormat?: "hex" | "hex8" | "rgba" | "oklch" | "hsl" | undefined;
|
|
67
|
+
sizeUnit?: "px" | "rem" | "pt" | "dp" | undefined;
|
|
68
|
+
remBase?: number | undefined;
|
|
69
|
+
} | undefined;
|
|
70
|
+
}>;
|
|
71
|
+
export type OutputTarget = z.infer<typeof OutputTargetSchema>;
|
|
72
|
+
/**
|
|
73
|
+
* Full schema for `tokens.config.json`. Every field is optional so the
|
|
74
|
+
* minimum-viable config is `{ "figmaFile": "..." }` — the rest gets sensible
|
|
75
|
+
* defaults.
|
|
76
|
+
*/
|
|
77
|
+
export declare const TokensConfigSchema: z.ZodObject<{
|
|
78
|
+
/** Optional JSON Schema URL for editor autocompletion. */
|
|
79
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
80
|
+
/**
|
|
81
|
+
* Figma file URL or fileKey. When omitted, tools fall back to the
|
|
82
|
+
* currently-connected Desktop Bridge plugin's file (Local Mode) or the
|
|
83
|
+
* file context bound by figma_pair_plugin (Cloud Mode).
|
|
84
|
+
*/
|
|
85
|
+
figmaFile: z.ZodOptional<z.ZodString>;
|
|
86
|
+
/** Where the canonical (committed) token sources live. */
|
|
87
|
+
source: z.ZodDefault<z.ZodObject<{
|
|
88
|
+
/** Directory holding the canonical token files. */
|
|
89
|
+
dir: z.ZodString;
|
|
90
|
+
/** Glob pattern within dir. Default: "*.tokens.json" */
|
|
91
|
+
pattern: z.ZodOptional<z.ZodString>;
|
|
92
|
+
/**
|
|
93
|
+
* Canonical format for source files. DTCG is the recommended default;
|
|
94
|
+
* Tokens Studio is supported for users who already have a `$themes.json`
|
|
95
|
+
* setup (e.g. Altitude).
|
|
96
|
+
*/
|
|
97
|
+
canonical: z.ZodDefault<z.ZodEnum<["dtcg", "tokens-studio"]>>;
|
|
98
|
+
}, "strip", z.ZodTypeAny, {
|
|
99
|
+
dir: string;
|
|
100
|
+
canonical: "dtcg" | "tokens-studio";
|
|
101
|
+
pattern?: string | undefined;
|
|
102
|
+
}, {
|
|
103
|
+
dir: string;
|
|
104
|
+
pattern?: string | undefined;
|
|
105
|
+
canonical?: "dtcg" | "tokens-studio" | undefined;
|
|
106
|
+
}>>;
|
|
107
|
+
/** Where build outputs (CSS, Tailwind, etc.) get written. */
|
|
108
|
+
generated: z.ZodOptional<z.ZodObject<{
|
|
109
|
+
dir: z.ZodDefault<z.ZodString>;
|
|
110
|
+
formats: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
111
|
+
format: z.ZodEnum<["dtcg", "tokens-studio", "css-vars", "tailwind-v4", "tailwind-v3", "scss", "less", "ts-module", "json-flat", "json-nested", "style-dictionary-v3"]>;
|
|
112
|
+
/** Optional filename override. Default is derived from format + scope. */
|
|
113
|
+
filename: z.ZodOptional<z.ZodString>;
|
|
114
|
+
/** Output prefix applied to every token name (e.g. "ds-", "al-"). */
|
|
115
|
+
prefix: z.ZodOptional<z.ZodString>;
|
|
116
|
+
/** Emit one file per mode (e.g. tokens-light.css, tokens-dark.css). */
|
|
117
|
+
splitByMode: z.ZodOptional<z.ZodBoolean>;
|
|
118
|
+
/** Emit one file per token set / Figma collection. */
|
|
119
|
+
splitByCollection: z.ZodOptional<z.ZodBoolean>;
|
|
120
|
+
/**
|
|
121
|
+
* If true, alias references are resolved to literal values in the output.
|
|
122
|
+
* If false, aliases are preserved (default for JSON formats, forced true
|
|
123
|
+
* for CSS/SCSS/Tailwind/etc. since they can't natively express aliases).
|
|
124
|
+
*/
|
|
125
|
+
resolveAliases: z.ZodOptional<z.ZodBoolean>;
|
|
126
|
+
/** Per-target transform options. Override the global defaults. */
|
|
127
|
+
transforms: z.ZodOptional<z.ZodObject<{
|
|
128
|
+
colorFormat: z.ZodOptional<z.ZodEnum<["hex", "hex8", "rgba", "oklch", "hsl"]>>;
|
|
129
|
+
sizeUnit: z.ZodOptional<z.ZodEnum<["px", "rem", "pt", "dp"]>>;
|
|
130
|
+
remBase: z.ZodOptional<z.ZodNumber>;
|
|
131
|
+
}, "strip", z.ZodTypeAny, {
|
|
132
|
+
colorFormat?: "hex" | "hex8" | "rgba" | "oklch" | "hsl" | undefined;
|
|
133
|
+
sizeUnit?: "px" | "rem" | "pt" | "dp" | undefined;
|
|
134
|
+
remBase?: number | undefined;
|
|
135
|
+
}, {
|
|
136
|
+
colorFormat?: "hex" | "hex8" | "rgba" | "oklch" | "hsl" | undefined;
|
|
137
|
+
sizeUnit?: "px" | "rem" | "pt" | "dp" | undefined;
|
|
138
|
+
remBase?: number | undefined;
|
|
139
|
+
}>>;
|
|
140
|
+
}, "strip", z.ZodTypeAny, {
|
|
141
|
+
format: "dtcg" | "tokens-studio" | "css-vars" | "tailwind-v4" | "tailwind-v3" | "scss" | "less" | "ts-module" | "json-flat" | "json-nested" | "style-dictionary-v3";
|
|
142
|
+
resolveAliases?: boolean | undefined;
|
|
143
|
+
filename?: string | undefined;
|
|
144
|
+
prefix?: string | undefined;
|
|
145
|
+
splitByMode?: boolean | undefined;
|
|
146
|
+
splitByCollection?: boolean | undefined;
|
|
147
|
+
transforms?: {
|
|
148
|
+
colorFormat?: "hex" | "hex8" | "rgba" | "oklch" | "hsl" | undefined;
|
|
149
|
+
sizeUnit?: "px" | "rem" | "pt" | "dp" | undefined;
|
|
150
|
+
remBase?: number | undefined;
|
|
151
|
+
} | undefined;
|
|
152
|
+
}, {
|
|
153
|
+
format: "dtcg" | "tokens-studio" | "css-vars" | "tailwind-v4" | "tailwind-v3" | "scss" | "less" | "ts-module" | "json-flat" | "json-nested" | "style-dictionary-v3";
|
|
154
|
+
resolveAliases?: boolean | undefined;
|
|
155
|
+
filename?: string | undefined;
|
|
156
|
+
prefix?: string | undefined;
|
|
157
|
+
splitByMode?: boolean | undefined;
|
|
158
|
+
splitByCollection?: boolean | undefined;
|
|
159
|
+
transforms?: {
|
|
160
|
+
colorFormat?: "hex" | "hex8" | "rgba" | "oklch" | "hsl" | undefined;
|
|
161
|
+
sizeUnit?: "px" | "rem" | "pt" | "dp" | undefined;
|
|
162
|
+
remBase?: number | undefined;
|
|
163
|
+
} | undefined;
|
|
164
|
+
}>, "many">>;
|
|
165
|
+
}, "strip", z.ZodTypeAny, {
|
|
166
|
+
dir: string;
|
|
167
|
+
formats: {
|
|
168
|
+
format: "dtcg" | "tokens-studio" | "css-vars" | "tailwind-v4" | "tailwind-v3" | "scss" | "less" | "ts-module" | "json-flat" | "json-nested" | "style-dictionary-v3";
|
|
169
|
+
resolveAliases?: boolean | undefined;
|
|
170
|
+
filename?: string | undefined;
|
|
171
|
+
prefix?: string | undefined;
|
|
172
|
+
splitByMode?: boolean | undefined;
|
|
173
|
+
splitByCollection?: boolean | undefined;
|
|
174
|
+
transforms?: {
|
|
175
|
+
colorFormat?: "hex" | "hex8" | "rgba" | "oklch" | "hsl" | undefined;
|
|
176
|
+
sizeUnit?: "px" | "rem" | "pt" | "dp" | undefined;
|
|
177
|
+
remBase?: number | undefined;
|
|
178
|
+
} | undefined;
|
|
179
|
+
}[];
|
|
180
|
+
}, {
|
|
181
|
+
dir?: string | undefined;
|
|
182
|
+
formats?: {
|
|
183
|
+
format: "dtcg" | "tokens-studio" | "css-vars" | "tailwind-v4" | "tailwind-v3" | "scss" | "less" | "ts-module" | "json-flat" | "json-nested" | "style-dictionary-v3";
|
|
184
|
+
resolveAliases?: boolean | undefined;
|
|
185
|
+
filename?: string | undefined;
|
|
186
|
+
prefix?: string | undefined;
|
|
187
|
+
splitByMode?: boolean | undefined;
|
|
188
|
+
splitByCollection?: boolean | undefined;
|
|
189
|
+
transforms?: {
|
|
190
|
+
colorFormat?: "hex" | "hex8" | "rgba" | "oklch" | "hsl" | undefined;
|
|
191
|
+
sizeUnit?: "px" | "rem" | "pt" | "dp" | undefined;
|
|
192
|
+
remBase?: number | undefined;
|
|
193
|
+
} | undefined;
|
|
194
|
+
}[] | undefined;
|
|
195
|
+
}>>;
|
|
196
|
+
/** Mode name mappings (Figma mode name → output mode name). */
|
|
197
|
+
modes: z.ZodOptional<z.ZodObject<{
|
|
198
|
+
/** e.g. { "Light": "light", "Dark": "dark" } */
|
|
199
|
+
map: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
200
|
+
/** Default mode if a token has no explicit mode (e.g. "Light"). */
|
|
201
|
+
default: z.ZodOptional<z.ZodString>;
|
|
202
|
+
}, "strip", z.ZodTypeAny, {
|
|
203
|
+
map?: Record<string, string> | undefined;
|
|
204
|
+
default?: string | undefined;
|
|
205
|
+
}, {
|
|
206
|
+
map?: Record<string, string> | undefined;
|
|
207
|
+
default?: string | undefined;
|
|
208
|
+
}>>;
|
|
209
|
+
/** Default conflict-resolution strategy when not specified per-call. */
|
|
210
|
+
conflictResolution: z.ZodDefault<z.ZodEnum<["ask", "figma-wins", "code-wins", "skip"]>>;
|
|
211
|
+
/** Behavior for tokens that exist on one side but not the other. */
|
|
212
|
+
sync: z.ZodOptional<z.ZodObject<{
|
|
213
|
+
onMissingInCode: z.ZodDefault<z.ZodEnum<["preserve", "delete", "warn"]>>;
|
|
214
|
+
onMissingInFigma: z.ZodDefault<z.ZodEnum<["preserve", "delete", "warn"]>>;
|
|
215
|
+
}, "strip", z.ZodTypeAny, {
|
|
216
|
+
onMissingInCode: "warn" | "delete" | "preserve";
|
|
217
|
+
onMissingInFigma: "warn" | "delete" | "preserve";
|
|
218
|
+
}, {
|
|
219
|
+
onMissingInCode?: "warn" | "delete" | "preserve" | undefined;
|
|
220
|
+
onMissingInFigma?: "warn" | "delete" | "preserve" | undefined;
|
|
221
|
+
}>>;
|
|
222
|
+
}, "strict", z.ZodTypeAny, {
|
|
223
|
+
source: {
|
|
224
|
+
dir: string;
|
|
225
|
+
canonical: "dtcg" | "tokens-studio";
|
|
226
|
+
pattern?: string | undefined;
|
|
227
|
+
};
|
|
228
|
+
conflictResolution: "ask" | "figma-wins" | "code-wins" | "skip";
|
|
229
|
+
sync?: {
|
|
230
|
+
onMissingInCode: "warn" | "delete" | "preserve";
|
|
231
|
+
onMissingInFigma: "warn" | "delete" | "preserve";
|
|
232
|
+
} | undefined;
|
|
233
|
+
modes?: {
|
|
234
|
+
map?: Record<string, string> | undefined;
|
|
235
|
+
default?: string | undefined;
|
|
236
|
+
} | undefined;
|
|
237
|
+
$schema?: string | undefined;
|
|
238
|
+
figmaFile?: string | undefined;
|
|
239
|
+
generated?: {
|
|
240
|
+
dir: string;
|
|
241
|
+
formats: {
|
|
242
|
+
format: "dtcg" | "tokens-studio" | "css-vars" | "tailwind-v4" | "tailwind-v3" | "scss" | "less" | "ts-module" | "json-flat" | "json-nested" | "style-dictionary-v3";
|
|
243
|
+
resolveAliases?: boolean | undefined;
|
|
244
|
+
filename?: string | undefined;
|
|
245
|
+
prefix?: string | undefined;
|
|
246
|
+
splitByMode?: boolean | undefined;
|
|
247
|
+
splitByCollection?: boolean | undefined;
|
|
248
|
+
transforms?: {
|
|
249
|
+
colorFormat?: "hex" | "hex8" | "rgba" | "oklch" | "hsl" | undefined;
|
|
250
|
+
sizeUnit?: "px" | "rem" | "pt" | "dp" | undefined;
|
|
251
|
+
remBase?: number | undefined;
|
|
252
|
+
} | undefined;
|
|
253
|
+
}[];
|
|
254
|
+
} | undefined;
|
|
255
|
+
}, {
|
|
256
|
+
sync?: {
|
|
257
|
+
onMissingInCode?: "warn" | "delete" | "preserve" | undefined;
|
|
258
|
+
onMissingInFigma?: "warn" | "delete" | "preserve" | undefined;
|
|
259
|
+
} | undefined;
|
|
260
|
+
source?: {
|
|
261
|
+
dir: string;
|
|
262
|
+
pattern?: string | undefined;
|
|
263
|
+
canonical?: "dtcg" | "tokens-studio" | undefined;
|
|
264
|
+
} | undefined;
|
|
265
|
+
modes?: {
|
|
266
|
+
map?: Record<string, string> | undefined;
|
|
267
|
+
default?: string | undefined;
|
|
268
|
+
} | undefined;
|
|
269
|
+
$schema?: string | undefined;
|
|
270
|
+
figmaFile?: string | undefined;
|
|
271
|
+
generated?: {
|
|
272
|
+
dir?: string | undefined;
|
|
273
|
+
formats?: {
|
|
274
|
+
format: "dtcg" | "tokens-studio" | "css-vars" | "tailwind-v4" | "tailwind-v3" | "scss" | "less" | "ts-module" | "json-flat" | "json-nested" | "style-dictionary-v3";
|
|
275
|
+
resolveAliases?: boolean | undefined;
|
|
276
|
+
filename?: string | undefined;
|
|
277
|
+
prefix?: string | undefined;
|
|
278
|
+
splitByMode?: boolean | undefined;
|
|
279
|
+
splitByCollection?: boolean | undefined;
|
|
280
|
+
transforms?: {
|
|
281
|
+
colorFormat?: "hex" | "hex8" | "rgba" | "oklch" | "hsl" | undefined;
|
|
282
|
+
sizeUnit?: "px" | "rem" | "pt" | "dp" | undefined;
|
|
283
|
+
remBase?: number | undefined;
|
|
284
|
+
} | undefined;
|
|
285
|
+
}[] | undefined;
|
|
286
|
+
} | undefined;
|
|
287
|
+
conflictResolution?: "ask" | "figma-wins" | "code-wins" | "skip" | undefined;
|
|
288
|
+
}>;
|
|
289
|
+
export type TokensConfig = z.infer<typeof TokensConfigSchema>;
|
|
290
|
+
/**
|
|
291
|
+
* Result of running `loadTokensConfig`. Includes the resolved config plus
|
|
292
|
+
* provenance info — where the file was found and the absolute project root.
|
|
293
|
+
*/
|
|
294
|
+
export interface LoadedTokensConfig {
|
|
295
|
+
config: TokensConfig;
|
|
296
|
+
/** Absolute path to the discovered `tokens.config.json`. */
|
|
297
|
+
configPath: string;
|
|
298
|
+
/** Directory containing the config file — used as the project root. */
|
|
299
|
+
projectRoot: string;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Walk up from `startDir` looking for `tokens.config.json`. Returns the first
|
|
303
|
+
* match, or `null` if none found by the filesystem root.
|
|
304
|
+
*/
|
|
305
|
+
export declare function findTokensConfig(startDir: string): string | null;
|
|
306
|
+
/**
|
|
307
|
+
* Load and validate `tokens.config.json`. If `explicitPath` is provided, uses
|
|
308
|
+
* that; otherwise autodiscovers by walking up from `cwd` (default
|
|
309
|
+
* `process.cwd()`).
|
|
310
|
+
*
|
|
311
|
+
* Returns `null` if no config is found AND no explicit path was given. Throws
|
|
312
|
+
* if an explicit path doesn't exist, or if the discovered file fails schema
|
|
313
|
+
* validation.
|
|
314
|
+
*/
|
|
315
|
+
export declare function loadTokensConfig(opts?: {
|
|
316
|
+
cwd?: string;
|
|
317
|
+
explicitPath?: string;
|
|
318
|
+
}): LoadedTokensConfig | null;
|
|
319
|
+
/**
|
|
320
|
+
* Default config used when none is found. Drives the "no-config detected"
|
|
321
|
+
* response shape from figma_export_tokens — the AI uses this to propose a
|
|
322
|
+
* scaffold to the user.
|
|
323
|
+
*/
|
|
324
|
+
export declare const DEFAULT_TOKENS_CONFIG: TokensConfig;
|
|
325
|
+
/**
|
|
326
|
+
* Build a `suggestedScaffold` payload returned when a tool is called and no
|
|
327
|
+
* `tokens.config.json` exists. The AI presents this scaffold to the user,
|
|
328
|
+
* writes the files via its native edit/write tools, then calls the original
|
|
329
|
+
* tool again.
|
|
330
|
+
*/
|
|
331
|
+
export declare function buildSuggestedScaffold(opts: {
|
|
332
|
+
projectRoot: string;
|
|
333
|
+
detectedFramework?: "tailwind-v4" | "tailwind-v3" | "css" | "scss" | "ts";
|
|
334
|
+
}): {
|
|
335
|
+
configContent: string;
|
|
336
|
+
directories: string[];
|
|
337
|
+
stylesheetImport: string;
|
|
338
|
+
nextSteps: string;
|
|
339
|
+
};
|
|
340
|
+
/**
|
|
341
|
+
* Pick the export formats from a loaded config that map to a given runtime
|
|
342
|
+
* format. Used by figma_export_tokens to decide which generated files to
|
|
343
|
+
* write. Returns the list verbatim if the caller passed an explicit format.
|
|
344
|
+
*/
|
|
345
|
+
export declare function resolveOutputTargets(config: TokensConfig | null, explicitFormat: ExportFormat | undefined): OutputTarget[];
|
|
346
|
+
/**
|
|
347
|
+
* Resolve the conflict-resolution strategy. Per-call argument wins over config
|
|
348
|
+
* default, which wins over the global default ("ask").
|
|
349
|
+
*/
|
|
350
|
+
export declare function resolveConflictStrategy(config: TokensConfig | null, perCall: ConflictResolution | undefined): ConflictResolution;
|
|
351
|
+
export {};
|
|
352
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/core/tokens/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEnE;;;GAGG;AACH,QAAA,MAAM,kBAAkB;;IActB,0EAA0E;;IAE1E,qEAAqE;;IAErE,uEAAuE;;IAEvE,sDAAsD;;IAEtD;;;;OAIG;;IAEH,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQlE,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;IAE3B,0DAA0D;;IAE1D;;;;OAIG;;IAEH,0DAA0D;;QAGtD,mDAAmD;;QAEnD,wDAAwD;;QAExD;;;;WAIG;;;;;;;;;;;IAIP,6DAA6D;;;;;YAxD/D,0EAA0E;;YAE1E,qEAAqE;;YAErE,uEAAuE;;YAEvE,sDAAsD;;YAEtD;;;;eAIG;;YAEH,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAiDhE,+DAA+D;;QAG3D,gDAAgD;;QAEhD,mEAAmE;;;;;;;;;IAIvE,wEAAwE;;IAIxE,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAY7D,CAAC;AAEZ,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,YAAY,CAAC;IACrB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBhE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,GAAE;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,kBAAkB,GAAG,IAAI,CAwCjC;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,YASnC,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,aAAa,GAAG,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;CAC3E,GAAG;IACF,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,CAyBA;AA6CD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,GAAG,IAAI,EAC3B,cAAc,EAAE,YAAY,GAAG,SAAS,GACvC,YAAY,EAAE,CAWhB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,YAAY,GAAG,IAAI,EAC3B,OAAO,EAAE,kBAAkB,GAAG,SAAS,GACtC,kBAAkB,CAEpB"}
|