@adobe/design-data-agent-mcp 1.14.6 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -103,7 +103,10 @@ node tools/design-data-agent-mcp/src/index.js
103
103
  > materializes the result to a temp dir and points `primer` / `resolve_token` /
104
104
  > `query_tokens` / `validate_usage` / `describe_component` /
105
105
  > `describe_guideline` / `list_guidelines` at it instead of the embedded
106
- > Spectrum snapshot. Component, relationship, and guideline catalogs are copied
106
+ > Spectrum snapshot. Component and guideline catalogs come from
107
+ > `design-data catalog export --out <dir> [--platform <id>]`, so extension
108
+ > components, implementation rows, and replacements come from the SDK cascade
109
+ > (this needs a `design-data` newer than 0.12.1). Relationships are still copied
107
110
  > from the fallback dataset and overlaid with platform manifest extensions. If
108
111
  > resolution fails
109
112
  > (e.g. no network for a github source), the server logs a warning and falls
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/design-data-agent-mcp",
3
- "version": "1.14.6",
3
+ "version": "1.15.1",
4
4
  "description": "MCP server and Claude Code skill for the design-data agent surface — read tools run in-process via wasm",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -32,8 +32,8 @@
32
32
  "dependencies": {
33
33
  "@modelcontextprotocol/sdk": "^1.27.1",
34
34
  "@adobe/design-data": "3.2.8",
35
- "@adobe/design-data-wasm": "0.11.1",
36
- "@adobe/spectrum-design-data": "3.6.1"
35
+ "@adobe/spectrum-design-data": "3.6.1",
36
+ "@adobe/design-data-wasm": "0.11.1"
37
37
  },
38
38
  "devDependencies": {
39
39
  "ava": "^6.0.1"
@@ -6,7 +6,7 @@ description: >
6
6
  system, token lookup, spec-conformance, drift detection, or token authoring on custom data.
7
7
  metadata:
8
8
  author: adobe
9
- version: "1.14.6"
9
+ version: "1.15.1"
10
10
  when_to_use: >
11
11
  Trigger on: design system, design tokens, spec-conformant, drift, validate tokens, token
12
12
  authoring, custom dataset, DESIGN_DATA_PATH, design-data validate, design-data diff,
@@ -99,7 +99,34 @@ async function resolveActivePlatformId(configDir, config, run) {
99
99
  }
100
100
  }
101
101
 
102
- function materializeCatalogs(config, cascadeDir, configDir, activePlatformId) {
102
+ /**
103
+ * Materialize the component and guideline catalogs by asking the CLI for the
104
+ * platform-merged result (`catalog export`), so extension components,
105
+ * implementation rows and replacements come from the SDK cascade rather than
106
+ * a second merge here. Relationships are not part of that export yet and are
107
+ * still copied from the fallback dir plus the platform's `extensions/`.
108
+ * Throws on failure so bootstrap falls back explicitly instead of serving a
109
+ * half-populated cascade.
110
+ */
111
+ async function materializeCatalogs(
112
+ config,
113
+ cascadeDir,
114
+ configDir,
115
+ activePlatformId,
116
+ run,
117
+ ) {
118
+ const exportArgs = ["catalog", "export", "--out", cascadeDir];
119
+ if (activePlatformId) exportArgs.push("--platform", activePlatformId);
120
+ const { exitCode, stderr } = await run(exportArgs, {
121
+ timeout: 60_000,
122
+ cwd: configDir,
123
+ });
124
+ if (exitCode !== 0) {
125
+ throw new Error(
126
+ stderr || `design-data catalog export exited with code ${exitCode}`,
127
+ );
128
+ }
129
+
103
130
  const manifestPath = resolveManifestPath(configDir, activePlatformId);
104
131
  let extensionsDir = null;
105
132
  if (manifestPath) {
@@ -109,58 +136,18 @@ function materializeCatalogs(config, cascadeDir, configDir, activePlatformId) {
109
136
  manifest.extensionsDir ?? "extensions",
110
137
  );
111
138
  }
112
-
113
- for (const [key, subdir] of [
114
- ["componentsDir", "components"],
115
- ["relationshipsDir", "relationships"],
116
- ["guidelinesDir", "guidelines"],
117
- ]) {
118
- const targetDir = join(cascadeDir, subdir);
119
- mkdirSync(targetDir, { recursive: true });
120
- const fallbackDir = config[key];
121
- if (fallbackDir && existsSync(fallbackDir)) {
122
- cpSync(fallbackDir, targetDir, { recursive: true, force: true });
123
- }
124
- const extensionDir = extensionsDir && join(extensionsDir, subdir);
125
- if (extensionDir && existsSync(extensionDir)) {
126
- cpSync(extensionDir, targetDir, { recursive: true, force: true });
127
- if (subdir === "guidelines") {
128
- mergeGuidelineManifest(targetDir, extensionDir);
129
- }
130
- }
131
- }
132
- }
133
-
134
- function mergeGuidelineManifest(targetDir, extensionDir) {
135
- const manifestPath = join(targetDir, "manifest.json");
136
- const manifest = existsSync(manifestPath)
137
- ? JSON.parse(readFileSync(manifestPath, "utf-8"))
138
- : { guidelines: [] };
139
- const entries = new Map(
140
- (manifest.guidelines ?? []).map((entry) => [entry.slug, entry]),
141
- );
142
-
143
- for (const file of readdirSync(extensionDir)) {
144
- if (!file.endsWith(".json") || file === "manifest.json") continue;
145
- const document = JSON.parse(
146
- readFileSync(join(extensionDir, file), "utf-8"),
147
- );
148
- const slug = document.name ?? file.replace(/\.json$/, "");
149
- entries.set(slug, {
150
- slug,
151
- ...(document.title && { title: document.title }),
152
- ...(document.category && { category: document.category }),
153
- ...(document.status && { status: document.status }),
154
- ...(document.sourceUrl && { sourceUrl: document.sourceUrl }),
155
- file: `guidelines/${file}`,
139
+ const targetDir = join(cascadeDir, "relationships");
140
+ mkdirSync(targetDir, { recursive: true });
141
+ if (config.relationshipsDir && existsSync(config.relationshipsDir)) {
142
+ cpSync(config.relationshipsDir, targetDir, {
143
+ recursive: true,
144
+ force: true,
156
145
  });
157
146
  }
158
-
159
- writeFileSync(
160
- manifestPath,
161
- JSON.stringify({ ...manifest, guidelines: [...entries.values()] }),
162
- "utf-8",
163
- );
147
+ const extensionDir = extensionsDir && join(extensionsDir, "relationships");
148
+ if (extensionDir && existsSync(extensionDir)) {
149
+ cpSync(extensionDir, targetDir, { recursive: true, force: true });
150
+ }
164
151
  }
165
152
 
166
153
  /**
@@ -226,7 +213,7 @@ export async function bootstrapCascade(config, { run = runCli } = {}) {
226
213
  JSON.stringify(tokens),
227
214
  "utf-8",
228
215
  );
229
- materializeCatalogs(config, dir, configDir, activePlatformId);
216
+ await materializeCatalogs(config, dir, configDir, activePlatformId, run);
230
217
 
231
218
  config.cascadeDataPath = dir;
232
219
  config.cascadeActive = true;