@adobe/design-data-agent-mcp 1.4.1 → 1.5.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/LICENSE CHANGED
@@ -186,7 +186,7 @@ file or class name and description of purpose be included on the
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
189
+ Copyright 2026 Adobe
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/design-data-agent-mcp",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "MCP server and Claude Code skill for the design-data agent surface — shells out to the design-data CLI",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -30,6 +30,8 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@modelcontextprotocol/sdk": "^1.27.1",
33
+ "@adobe/design-data": "2.0.0",
34
+ "@adobe/design-data-wasm": "0.1.0",
33
35
  "@adobe/spectrum-design-data": "0.3.0"
34
36
  },
35
37
  "devDependencies": {
@@ -2,20 +2,22 @@
2
2
  name: design-data-agent
3
3
  description: >
4
4
  Validate, query, resolve, diff, and author spec-conformant design tokens and components using the
5
- design-data CLI against a local dataset. Use when the user asks about design tokens, a design
5
+ design-data MCP tools against a local dataset. Use when the user asks about design tokens, a design
6
6
  system, token lookup, spec-conformance, drift detection, or token authoring on custom data.
7
7
  when_to_use: >
8
8
  Trigger on: design system, design tokens, spec-conformant, drift, validate tokens, token
9
9
  authoring, custom dataset, DESIGN_DATA_PATH, design-data validate, design-data diff,
10
10
  design-data write, product-context.json.
11
- allowed-tools: Bash(npx @adobe/design-data *)
11
+ allowed-tools: mcp__design-data-agent__primer, mcp__design-data-agent__query_tokens, mcp__design-data-agent__resolve_token, mcp__design-data-agent__describe_component, mcp__design-data-agent__validate_usage, mcp__design-data-agent__diff_datasets, mcp__design-data-agent__write, mcp__design-data-agent__start_authoring_session, mcp__design-data-agent__authoring_session_step_intent, mcp__design-data-agent__authoring_session_step_classification, mcp__design-data-agent__authoring_session_step_values, mcp__design-data-agent__authoring_session_commit, mcp__design-data-agent__authoring_session_cancel, mcp__design-data-agent__authoring_session_get, mcp__design-data-agent__authoring_session_list
12
12
  ---
13
13
 
14
14
  # design-data agent skill
15
15
 
16
- `design-data` is the reference CLI for the Spectrum Design Data specification. It validates, queries, resolves, and authors spec-conformant tokens and components from any dataset on the local filesystem.
16
+ `@adobe/design-data-agent-mcp` provides in-process wasm tools for validating, querying,
17
+ resolving, diffing, and authoring spec-conformant tokens and components from any dataset
18
+ on the local filesystem.
17
19
 
18
- Set two path variables once and reference them throughout. The token dataset and the spec catalog (components, fields, dimensions) live in separate directories:
20
+ Set two path variables once and reference them throughout:
19
21
 
20
22
  ```bash
21
23
  export DESIGN_DATA_PATH=./packages/design-data/tokens
@@ -26,55 +28,50 @@ For Spectrum tokens with zero setup (embedded snapshot), use the `design-data` s
26
28
 
27
29
  ## Bootstrap
28
30
 
29
- On first use, ensure the CLI is available:
31
+ Add `@adobe/design-data-agent-mcp` to your `.cursor/mcp.json`:
30
32
 
33
+ ```json
34
+ {
35
+ "mcpServers": {
36
+ "design-data-agent": {
37
+ "command": "npx",
38
+ "args": ["-y", "@adobe/design-data-agent-mcp"],
39
+ "env": {
40
+ "DESIGN_DATA_PATH": "./packages/tokens/src",
41
+ "DESIGN_DATA_COMPONENTS": "./packages/design-data/components",
42
+ "DESIGN_DATA_FIELDS": "./packages/design-data/fields"
43
+ }
44
+ }
45
+ }
46
+ }
31
47
  ```
32
- npx @adobe/design-data --version
33
- ```
48
+
49
+ Adjust paths to match your dataset layout.
34
50
 
35
51
  ***
36
52
 
37
53
  ## Session start — call `primer` first
38
54
 
39
- Call `primer` at the start of every session that touches design data. It returns the active dimensions, component list, taxonomy fields, and token count — structural context that scopes all subsequent lookups.
40
-
41
- ```bash
42
- npx @adobe/design-data primer "$DESIGN_DATA_PATH" --format json \
43
- --components-dir "$DESIGN_DATA_SPEC_PATH/components" \
44
- --fields-dir "$DESIGN_DATA_SPEC_PATH/fields"
45
- ```
46
-
47
- Always pass `--components-dir` and `--fields-dir` explicitly. These directories live under `packages/design-data/`, alongside the token dataset. The CLI defaults probe those paths relative to CWD, so omitting the flags when running from an arbitrary directory (or with an absolute `DESIGN_DATA_PATH`) produces empty `components` and `taxonomyFields`.
48
-
49
- The payload includes `specVersion`, `manifest`, `components`, `taxonomyFields`, and `tokenCount`.
55
+ Call `primer` at the start of every session that touches design data. It returns the active
56
+ dimensions, component list, taxonomy fields, and token count — structural context that scopes
57
+ all subsequent lookups. No inputs required.
50
58
 
51
59
  ***
52
60
 
53
61
  ## Token lookup
54
62
 
55
- ### Resolve a token to its literal value
56
-
57
- ```bash
58
- npx @adobe/design-data resolve <property> "$DESIGN_DATA_PATH" --format json \
59
- [--color-scheme light|dark] \
60
- [--scale desktop|mobile] \
61
- [--contrast regular|high]
62
- ```
63
-
64
- Example:
63
+ ### Resolve a token to its literal value — `resolve_token`
65
64
 
66
- ```bash
67
- npx @adobe/design-data resolve accent-background-color-default "$DESIGN_DATA_PATH" \
68
- --format json --color-scheme dark --scale desktop
69
- ```
65
+ Required: `property` (string) — e.g. `"accent-background-color-default"`
66
+ Optional: `colorScheme` (`"light"` or `"dark"`), `scale` (`"desktop"` or `"mobile"`),
67
+ `contrast` (`"regular"` or `"high"`)
70
68
 
71
- ### Query tokens by filter expression
69
+ ### Query tokens by filter expression — `query_tokens`
72
70
 
73
- ```bash
74
- npx @adobe/design-data query "$DESIGN_DATA_PATH" --filter "<expr>" --format json
75
- ```
71
+ Required: `filter` (string)
76
72
 
77
- Valid filter keys: `property`, `component`, `variant`, `state`, `colorScheme`, `scale`, `contrast`, `uuid`, `$schema`. Any other key is a parse error. The dimension keys (`colorScheme`, `scale`, `contrast`) accept the same enum values as the `resolve` flags (`light`/`dark`, `desktop`/`mobile`, `regular`/`high`).
73
+ Valid filter keys: `property`, `component`, `variant`, `state`, `colorScheme`, `scale`,
74
+ `contrast`, `uuid`, `$schema`.
78
75
 
79
76
  Filter syntax examples:
80
77
 
@@ -87,64 +84,71 @@ property=background-color|property=border-color
87
84
  $schema=https://spectrum.adobe.com/page/design-token/
88
85
  ```
89
86
 
90
- > **Exit codes:** `0` = matches found; `1` = no matches (returns `[]` — not an error); `>1` = error.
87
+ > **Exit codes:** `0` = matches found; empty array = no matches (not an error).
91
88
 
92
89
  ***
93
90
 
94
- ## Component info
91
+ ## Component info — `describe_component`
95
92
 
96
- ```bash
97
- npx @adobe/design-data component <id> --components-dir "$DESIGN_DATA_SPEC_PATH/components"
98
- ```
93
+ Required: `id` (string) — kebab-case component ID, e.g. `button`, `action-button`
99
94
 
100
- Returns the component contract: `name`, `displayName`, `options`, `anatomy`, `states`, and `tokenBindings`. Output is always JSON; there is no `--format` flag on this subcommand.
95
+ Returns the component contract: `name`, `displayName`, `options`, `anatomy`, `states`,
96
+ and `tokenBindings`.
101
97
 
102
- Pass `--components-dir` explicitly for the same reason as `primer` — the default probes CWD-relative paths that won't resolve in agent contexts.
98
+ ***
103
99
 
104
- Example:
100
+ ## Validation — `validate_usage`
105
101
 
106
- ```bash
107
- npx @adobe/design-data component button --components-dir "$DESIGN_DATA_SPEC_PATH/components"
108
- ```
102
+ Optional inputs:
103
+
104
+ * `path` — dataset path (defaults to `DESIGN_DATA_PATH`)
105
+ * `strict` (boolean) — treat warnings as errors
106
+ * `schema_path` — override schemas directory (defaults to `@adobe/spectrum-tokens` schemas)
107
+
108
+ Runs Layer-1 JSON-Schema structural validation and Layer-2 relational rules.
109
+ Returns `{ valid, errors, warnings }`.
110
+
111
+ > **Note:** `--exceptions-path` (SPEC-007 naming allowlist) is not supported in the
112
+ > in-process path. Use the `design-data` CLI directly if you need exceptions support.
109
113
 
110
114
  ***
111
115
 
112
- ## Validation
116
+ ## Dataset diff — `diff_datasets`
113
117
 
114
- ```bash
115
- npx @adobe/design-data validate "$DESIGN_DATA_PATH" --format json \
116
- [--schema-path <path>] \
117
- [--exceptions-path <path>] \
118
- [--strict]
119
- ```
118
+ Required: `oldPath`, `newPath`
119
+ Optional: `filter` (substring to narrow results by token name)
120
120
 
121
- Returns a `ValidationReport` object: `{ layer: 1|2, errors: [...], warnings: [...] }` where each diagnostic has `rule_id` (e.g. `"SPEC-002"`), `severity` (`"error"` | `"warning"`), and `message`. Layer 1 is schema validation; Layer 2 is cascade-rule validation. `--strict` treats warnings as errors.
121
+ Returns `{ renamed, deprecated, reverted, added, deleted, updated }`.
122
122
 
123
123
  ***
124
124
 
125
- ## Dataset diff
125
+ ## Product-layer authoring — `write`
126
126
 
127
- ```bash
128
- npx @adobe/design-data diff <old-path> <new-path> --format json [--filter <expr>]
129
- ```
127
+ Write or update the product context document in the dataset.
130
128
 
131
- > **Exit codes:** `0` = no changes; `1` = differences found (returns JSON diff — not an error); `>1` = error.
129
+ Optional inputs: `output` (defaults to `$DESIGN_DATA_PATH/product-context.json`),
130
+ `rationale` (string)
132
131
 
133
132
  ***
134
133
 
135
- ## Product-layer authoring
134
+ ## Token authoring session
136
135
 
137
- Write or update the product context document in the dataset:
136
+ Use the following tools in sequence to create a new token through the wizard:
138
137
 
139
- ```bash
140
- npx @adobe/design-data write \
141
- --output "$DESIGN_DATA_PATH/product-context.json" \
142
- --rationale "Why these overrides exist"
143
- ```
138
+ 1. **`start_authoring_session`** — start a session (returns `session_id`)
139
+ 2. **`authoring_session_step_intent`** — provide natural-language intent; get token suggestions
140
+ 3. **`authoring_session_step_classification`** — set layer, property, name fields
141
+ 4. **`authoring_session_step_values`** set mode-specific value rows
142
+ 5. **`authoring_session_commit`** — validate and write the token to disk
143
+ 6. **`authoring_session_cancel`** — cancel without writing
144
144
 
145
- Always pass `--output` with an explicit path inside the dataset. The default resolves relative to CWD, which is rarely correct in agent contexts.
145
+ Helper tools: `authoring_session_get` (inspect state), `authoring_session_list` (all active sessions).
146
146
 
147
- Generates a product-context scaffold at the output path (`specVersion`, `layer: "product"`, `rationale`, attribution metadata). Creates the file if absent; overwrites if it already exists. The confirmation string returned to stdout on success is a plain text message — not JSON.
147
+ `authoring_session_commit` accepts an optional `schema_path` to override the schemas directory
148
+ for Layer-1 JSON-Schema validation before writing.
149
+
150
+ > **Note:** `authoring_session_step_intent` (NLP suggestion ranking) still delegates to the
151
+ > `design-data` CLI because the NLP `suggest` API is not yet on the wasm surface.
148
152
 
149
153
  ***
150
154
 
@@ -152,9 +156,8 @@ Generates a product-context scaffold at the output path (`specVersion`, `layer:
152
156
 
153
157
  * **Scale values:** `desktop` and `mobile` — not `medium`/`large`.
154
158
  * **Contrast values:** `regular` and `high` — not `standard`/`high`.
155
- * **`query` exit 1** means no matches and still emits `[]`. Only `>1` is an error.
156
- * **`diff` exit 1** means changes were found. The JSON diff is in stdout — still a success result.
157
- * **`--format json`** — always pass this in agent and script contexts; the CLI pretty-prints when stdout is a TTY.
159
+ * **`query_tokens` returns `[]`** when no tokens match not an error.
160
+ * **`diff_datasets` filter** matches by token name substring (case-insensitive).
158
161
 
159
162
  ## When working in Cursor
160
163
 
@@ -163,23 +166,3 @@ Cursor Settings → Rules → **Add Rule** → **Remote Rule (GitHub)** → past
163
166
  ```
164
167
  https://github.com/adobe/spectrum-design-data/tree/main/tools/design-data-agent-mcp/skills/design-data
165
168
  ```
166
-
167
- For always-available tool access (higher context cost), add `@adobe/design-data-agent-mcp` to `.cursor/mcp.json`:
168
-
169
- ```json
170
- {
171
- "mcpServers": {
172
- "design-data-agent": {
173
- "command": "npx",
174
- "args": ["-y", "@adobe/design-data-agent-mcp"],
175
- "env": {
176
- "DESIGN_DATA_PATH": "./packages/tokens/src",
177
- "DESIGN_DATA_COMPONENTS": "./packages/design-data/components",
178
- "DESIGN_DATA_FIELDS": "./packages/design-data/fields"
179
- }
180
- }
181
- }
182
- }
183
- ```
184
-
185
- Adjust paths to match your dataset layout.
@@ -8,21 +8,27 @@
8
8
  // OF ANY KIND, either express or implied. See the License for the specific language
9
9
  // governing permissions and limitations under the License.
10
10
 
11
- //! MCP authoring-session tools (RFC #973 Q4).
12
- //!
13
- //! Each tool maps to one `design-data authoring-session` CLI subcommand.
14
- //! State is held on disk (one JSON file per session); the CLI is stateless.
11
+ /**
12
+ * Authoring-session tools for design-data-agent-mcp.
13
+ *
14
+ * Most operations use @adobe/design-data (on-disk session store) and run
15
+ * fully in-process. The exception is authoring_session_step_intent, which still
16
+ * delegates to the CLI because the NLP `suggest` ranking is not yet on the wasm
17
+ * surface. When that API is added, step_intent can be migrated here too.
18
+ */
15
19
 
20
+ import {
21
+ startSession,
22
+ getSession,
23
+ listSessions,
24
+ stepClassification,
25
+ stepValues,
26
+ commitSession,
27
+ cancelSession,
28
+ } from "@adobe/design-data/session";
16
29
  import { runCli } from "../cli.js";
17
30
  import { config } from "../config.js";
18
31
 
19
- async function callCli(args) {
20
- const { exitCode, stdout, stderr } = await runCli(args, { timeout: 30_000 });
21
- if (exitCode !== 0)
22
- throw new Error(stderr || `authoring-session exited ${exitCode}`);
23
- return JSON.parse(stdout);
24
- }
25
-
26
32
  export function createAuthoringTools() {
27
33
  return [
28
34
  {
@@ -48,7 +54,7 @@ export function createAuthoringTools() {
48
54
  "dataset_path is required (or set DESIGN_DATA_PATH in the environment)",
49
55
  );
50
56
  }
51
- return callCli(["authoring-session", "start", path]);
57
+ return startSession(path);
52
58
  },
53
59
  },
54
60
 
@@ -71,15 +77,25 @@ export function createAuthoringTools() {
71
77
  additionalProperties: false,
72
78
  },
73
79
  async handler({ session_id, intent }) {
74
- return callCli([
75
- "authoring-session",
76
- "step",
77
- "intent",
78
- "--session-id",
79
- session_id,
80
- "--intent",
81
- intent,
82
- ]);
80
+ // step_intent requires NLP suggest ranking — still uses the CLI.
81
+ // Will be migrated when suggest is added to the wasm surface.
82
+ const { exitCode, stdout, stderr } = await runCli(
83
+ [
84
+ "authoring-session",
85
+ "step",
86
+ "intent",
87
+ "--session-id",
88
+ session_id,
89
+ "--intent",
90
+ intent,
91
+ ],
92
+ { timeout: 30_000 },
93
+ );
94
+ if (exitCode !== 0)
95
+ throw new Error(
96
+ stderr || `authoring-session step intent exited ${exitCode}`,
97
+ );
98
+ return JSON.parse(stdout);
83
99
  },
84
100
  },
85
101
 
@@ -118,21 +134,11 @@ export function createAuthoringTools() {
118
134
  additionalProperties: false,
119
135
  },
120
136
  async handler({ session_id, layer, property, name_fields = [] }) {
121
- const args = [
122
- "authoring-session",
123
- "step",
124
- "classification",
125
- "--session-id",
126
- session_id,
127
- "--layer",
137
+ return stepClassification(session_id, {
128
138
  layer,
129
- "--property",
130
139
  property,
131
- ];
132
- for (const { key, value } of name_fields) {
133
- args.push("--name-field", `${key}=${value}`);
134
- }
135
- return callCli(args);
140
+ nameFields: name_fields,
141
+ });
136
142
  },
137
143
  },
138
144
 
@@ -174,15 +180,7 @@ export function createAuthoringTools() {
174
180
  additionalProperties: false,
175
181
  },
176
182
  async handler({ session_id, rows }) {
177
- return callCli([
178
- "authoring-session",
179
- "step",
180
- "values",
181
- "--session-id",
182
- session_id,
183
- "--rows",
184
- JSON.stringify(rows),
185
- ]);
183
+ return stepValues(session_id, rows);
186
184
  },
187
185
  },
188
186
 
@@ -217,7 +215,9 @@ export function createAuthoringTools() {
217
215
  schema_path: {
218
216
  type: "string",
219
217
  description:
220
- "Path to schemas directory. Defaults to packages/tokens/schemas relative to target.",
218
+ "Path to schemas directory containing token-types/ and token-file.json. " +
219
+ "Used for Layer-1 JSON-Schema validation before writing. " +
220
+ "Defaults to @adobe/spectrum-tokens schemas when omitted.",
221
221
  },
222
222
  is_override: {
223
223
  type: "boolean",
@@ -236,22 +236,15 @@ export function createAuthoringTools() {
236
236
  schema_path,
237
237
  is_override = false,
238
238
  }) {
239
- const args = [
240
- "authoring-session",
241
- "commit",
242
- "--session-id",
243
- session_id,
244
- "--schema-url",
245
- schema_url,
246
- "--target",
239
+ return commitSession({
240
+ sessionId: session_id,
241
+ schemaUrl: schema_url,
247
242
  target,
248
- "--rationale",
249
243
  rationale,
250
- ];
251
- if (product_context) args.push("--product-context", product_context);
252
- if (schema_path) args.push("--schema-path", schema_path);
253
- if (is_override) args.push("--is-override");
254
- return callCli(args);
244
+ productContext: product_context,
245
+ schemaPath: schema_path ?? null,
246
+ isOverride: is_override,
247
+ });
255
248
  },
256
249
  },
257
250
 
@@ -261,18 +254,11 @@ export function createAuthoringTools() {
261
254
  inputSchema: {
262
255
  type: "object",
263
256
  required: ["session_id"],
264
- properties: {
265
- session_id: { type: "string" },
266
- },
257
+ properties: { session_id: { type: "string" } },
267
258
  additionalProperties: false,
268
259
  },
269
260
  async handler({ session_id }) {
270
- return callCli([
271
- "authoring-session",
272
- "cancel",
273
- "--session-id",
274
- session_id,
275
- ]);
261
+ return cancelSession(session_id);
276
262
  },
277
263
  },
278
264
 
@@ -282,18 +268,11 @@ export function createAuthoringTools() {
282
268
  inputSchema: {
283
269
  type: "object",
284
270
  required: ["session_id"],
285
- properties: {
286
- session_id: { type: "string" },
287
- },
271
+ properties: { session_id: { type: "string" } },
288
272
  additionalProperties: false,
289
273
  },
290
274
  async handler({ session_id }) {
291
- return callCli([
292
- "authoring-session",
293
- "get",
294
- "--session-id",
295
- session_id,
296
- ]);
275
+ return getSession(session_id);
297
276
  },
298
277
  },
299
278
 
@@ -306,7 +285,7 @@ export function createAuthoringTools() {
306
285
  additionalProperties: false,
307
286
  },
308
287
  async handler() {
309
- return callCli(["authoring-session", "list"]);
288
+ return listSessions();
310
289
  },
311
290
  },
312
291
  ];
package/src/tools/diff.js CHANGED
@@ -8,7 +8,32 @@
8
8
  // OF ANY KIND, either express or implied. See the License for the specific language
9
9
  // governing permissions and limitations under the License.
10
10
 
11
- import { runCli } from "../cli.js";
11
+ import { loadDataset } from "@adobe/design-data/load";
12
+
13
+ /**
14
+ * Filter a diff result by a substring match against token names.
15
+ *
16
+ * The diff() return shape uses camelCase (per wasm serde rename_all = "camelCase"):
17
+ * - renamed entries: { oldName, newName, ... }
18
+ * - all other entries: { name, ... }
19
+ *
20
+ * @param {object} diff - DiffResult from Dataset.diff().
21
+ * @param {string} filter - Substring to match (case-insensitive).
22
+ * @returns {object} Filtered diff with the same top-level keys.
23
+ */
24
+ export function filterDiffByName(diff, filter) {
25
+ const f = filter.toLowerCase();
26
+ const matchName = (t) =>
27
+ [t.name, t.oldName, t.newName].some((n) => n?.toLowerCase().includes(f));
28
+ return {
29
+ renamed: diff.renamed.filter(matchName),
30
+ deprecated: diff.deprecated.filter(matchName),
31
+ reverted: diff.reverted.filter(matchName),
32
+ added: diff.added.filter(matchName),
33
+ deleted: diff.deleted.filter(matchName),
34
+ updated: diff.updated.filter(matchName),
35
+ };
36
+ }
12
37
 
13
38
  export function createDiffTools() {
14
39
  return [
@@ -36,12 +61,13 @@ export function createDiffTools() {
36
61
  additionalProperties: false,
37
62
  },
38
63
  async handler({ oldPath, newPath, filter }) {
39
- const args = ["diff", oldPath, newPath, "--format", "json"];
40
- if (filter) args.push("--filter", filter);
41
- const { exitCode, stdout, stderr } = await runCli(args);
42
- // exit code 1 means differences found — that is a valid result, not an error
43
- if (exitCode > 1) throw new Error(stderr || `diff exited ${exitCode}`);
44
- return JSON.parse(stdout);
64
+ const [oldDs, newDs] = await Promise.all([
65
+ loadDataset(oldPath),
66
+ loadDataset(newPath),
67
+ ]);
68
+ const diff = oldDs.diff(newDs);
69
+ if (!filter) return diff;
70
+ return filterDiffByName(diff, filter);
45
71
  },
46
72
  },
47
73
  ];
package/src/tools/read.js CHANGED
@@ -8,6 +8,19 @@
8
8
  // OF ANY KIND, either express or implied. See the License for the specific language
9
9
  // governing permissions and limitations under the License.
10
10
 
11
+ /**
12
+ * Read tools for design-data-agent-mcp.
13
+ *
14
+ * query_tokens and resolve_token use @adobe/design-data (loadDataset) + the
15
+ * wasm Dataset to run in-process without spawning the CLI binary.
16
+ *
17
+ * primer and describe_component still invoke the CLI: primer aggregates complex
18
+ * catalog metadata (components, fields) not yet on the wasm surface, and
19
+ * describe_component requires the components catalog path resolution that the CLI
20
+ * handles. These will be ported when those APIs are added to the wasm surface.
21
+ */
22
+
23
+ import { loadDataset } from "@adobe/design-data/load";
11
24
  import { runCli } from "../cli.js";
12
25
  import { config } from "../config.js";
13
26
 
@@ -33,6 +46,7 @@ export function createReadTools() {
33
46
  return JSON.parse(stdout);
34
47
  },
35
48
  },
49
+
36
50
  {
37
51
  name: "resolve_token",
38
52
  description:
@@ -64,16 +78,21 @@ export function createReadTools() {
64
78
  additionalProperties: false,
65
79
  },
66
80
  async handler({ property, colorScheme, scale, contrast }) {
67
- const args = ["resolve", property, config.dataPath, "--format", "json"];
68
- if (colorScheme) args.push("--color-scheme", colorScheme);
69
- if (scale) args.push("--scale", scale);
70
- if (contrast) args.push("--contrast", contrast);
71
- const { exitCode, stdout, stderr } = await runCli(args);
72
- if (exitCode !== 0)
73
- throw new Error(stderr || `resolve exited ${exitCode}`);
74
- return JSON.parse(stdout);
81
+ const ds = await loadDataset(config.dataPath);
82
+ const context = {};
83
+ if (colorScheme) context.colorScheme = colorScheme;
84
+ if (scale) context.scale = scale;
85
+ if (contrast) context.contrast = contrast;
86
+ const result = ds.resolve(property, context);
87
+ if (!result) {
88
+ throw new Error(
89
+ `No token found for property "${property}" in context ${JSON.stringify(context)}`,
90
+ );
91
+ }
92
+ return result;
75
93
  },
76
94
  },
95
+
77
96
  {
78
97
  name: "query_tokens",
79
98
  description:
@@ -90,20 +109,11 @@ export function createReadTools() {
90
109
  additionalProperties: false,
91
110
  },
92
111
  async handler({ filter }) {
93
- const args = [
94
- "query",
95
- config.dataPath,
96
- "--filter",
97
- filter,
98
- "--format",
99
- "json",
100
- ];
101
- const { exitCode, stdout, stderr } = await runCli(args);
102
- // exit code 1 means no matches — still valid JSON []
103
- if (exitCode > 1) throw new Error(stderr || `query exited ${exitCode}`);
104
- return JSON.parse(stdout);
112
+ const ds = await loadDataset(config.dataPath);
113
+ return ds.query(filter);
105
114
  },
106
115
  },
116
+
107
117
  {
108
118
  name: "describe_component",
109
119
  description:
@@ -8,7 +8,7 @@
8
8
  // OF ANY KIND, either express or implied. See the License for the specific language
9
9
  // governing permissions and limitations under the License.
10
10
 
11
- import { runCli } from "../cli.js";
11
+ import { validateDataset } from "@adobe/design-data/validate";
12
12
  import { config } from "../config.js";
13
13
 
14
14
  export function createValidateTools() {
@@ -16,7 +16,8 @@ export function createValidateTools() {
16
16
  {
17
17
  name: "validate_usage",
18
18
  description:
19
- "Validate design token usage in a dataset. Returns a JSON report of violations and warnings.",
19
+ "Validate design token usage in a dataset. Runs Layer-1 JSON-Schema structural " +
20
+ "validation and Layer-2 relational rules. Returns a JSON report of violations and warnings.",
20
21
  inputSchema: {
21
22
  type: "object",
22
23
  properties: {
@@ -26,20 +27,24 @@ export function createValidateTools() {
26
27
  "Path to dataset to validate (defaults to DESIGN_DATA_PATH)",
27
28
  },
28
29
  strict: { type: "boolean", description: "Treat warnings as errors" },
30
+ schema_path: {
31
+ type: "string",
32
+ description:
33
+ "Path to schemas directory containing token-types/ and token-file.json. " +
34
+ "Defaults to @adobe/spectrum-tokens schemas. Set DESIGN_DATA_SCHEMAS env var or " +
35
+ "pass explicitly for custom schema sets.",
36
+ },
29
37
  },
30
38
  additionalProperties: false,
31
39
  },
32
- async handler({ path, strict } = {}) {
40
+ async handler({ path, strict, schema_path } = {}) {
33
41
  const target = path ?? config.dataPath;
34
- const args = ["validate", target, "--format", "json"];
35
- if (config.schemaPath) args.push("--schema-path", config.schemaPath);
36
- if (config.exceptionsPath)
37
- args.push("--exceptions-path", config.exceptionsPath);
38
- if (strict === true) args.push("--strict");
39
- const { exitCode, stdout, stderr } = await runCli(args);
40
- if (exitCode !== 0 && !stdout)
41
- throw new Error(stderr || `validate exited ${exitCode}`);
42
- return JSON.parse(stdout);
42
+ const schemaPath = schema_path ?? config.schemaPath ?? null;
43
+ // NOTE: exceptionsPath (DESIGN_DATA_EXCEPTIONS / --exceptions-path) applies to the
44
+ // SPEC-007 naming rule in the relational layer. The in-process wasm validate() does
45
+ // not consume it. Passing exceptionsPath here would throw an explicit error from
46
+ // validateDataset omit it and document the limitation.
47
+ return validateDataset(target, { schemaPath, strict: strict ?? false });
43
48
  },
44
49
  },
45
50
  ];
@@ -9,7 +9,7 @@
9
9
  // governing permissions and limitations under the License.
10
10
 
11
11
  import { join } from "path";
12
- import { runCli } from "../cli.js";
12
+ import { writeProductContext } from "@adobe/design-data/write";
13
13
  import { config } from "../config.js";
14
14
 
15
15
  export function createWriteTools() {
@@ -36,12 +36,7 @@ export function createWriteTools() {
36
36
  async handler({ output, rationale } = {}) {
37
37
  const resolvedOutput =
38
38
  output ?? join(config.dataPath, "product-context.json");
39
- const args = ["write", "--output", resolvedOutput];
40
- if (rationale) args.push("--rationale", rationale);
41
- const { exitCode, stdout, stderr } = await runCli(args);
42
- if (exitCode !== 0)
43
- throw new Error(stderr || `write exited ${exitCode}`);
44
- return stdout;
39
+ return writeProductContext({ output: resolvedOutput, rationale });
45
40
  },
46
41
  },
47
42
  ];