@adobe/design-data-agent-mcp 1.9.4 → 1.9.6

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
@@ -38,7 +38,11 @@ package version — there's no separate data update to run. Pin `@latest` (as ab
38
38
  fetches the newest published version rather than reusing whatever it last cached; `-y` alone
39
39
  only skips the install confirmation, it doesn't force a re-fetch. Already on `/plugin`? Run
40
40
  `/plugin update design-data-agent@spectrum-design-data`. Call the primer tool and check
41
- `provenance.designDataVersion` to see which dataset version is embedded.
41
+ `provenance.designDataVersion` to see which dataset version is embedded. The primer tool
42
+ also does a best-effort check against the latest published `@adobe/spectrum-design-data`
43
+ version — if the embedded dataset is behind, it adds a `provenance.datasetStatus` field and
44
+ logs a one-line warning to stderr. This is silent on any network failure (offline/air-gapped
45
+ use is unaffected); set `DESIGN_DATA_SKIP_VERSION_CHECK=1` to disable the check entirely.
42
46
 
43
47
  ## MCP server
44
48
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/design-data-agent-mcp",
3
- "version": "1.9.4",
3
+ "version": "1.9.6",
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",
@@ -30,9 +30,9 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@modelcontextprotocol/sdk": "^1.27.1",
33
- "@adobe/design-data": "3.0.7",
34
33
  "@adobe/design-data-wasm": "0.7.0",
35
- "@adobe/spectrum-design-data": "2.6.0"
34
+ "@adobe/design-data": "3.0.7",
35
+ "@adobe/spectrum-design-data": "2.7.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "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.9.4"
9
+ version: "1.9.6"
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,
@@ -0,0 +1,95 @@
1
+ // Copyright 2026 Adobe. All rights reserved.
2
+ // This file is licensed to you under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License. You may obtain a copy
4
+ // of the License at http://www.apache.org/licenses/LICENSE-2.0
5
+ //
6
+ // Unless required by applicable law or agreed to in writing, software distributed under
7
+ // the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
8
+ // OF ANY KIND, either express or implied. See the License for the specific language
9
+ // governing permissions and limitations under the License.
10
+
11
+ /**
12
+ * Best-effort runtime check that the embedded dataset (provenance.designDataVersion,
13
+ * baked into @adobe/design-data-wasm at build time) isn't behind the latest published
14
+ * @adobe/spectrum-design-data. See spectrum-design-data-9fe.5 — a plain `npx -y <pkg>`
15
+ * (no @latest tag) can silently reuse a cached older wasm build.
16
+ *
17
+ * Deliberately silent on any failure (offline, registry down, timeout): this is a
18
+ * courtesy signal, never a reason to break the primer response.
19
+ */
20
+
21
+ const REGISTRY_URL =
22
+ "https://registry.npmjs.org/@adobe/spectrum-design-data/latest";
23
+ const TIMEOUT_MS = 1500;
24
+
25
+ /**
26
+ * Numeric major.minor.patch compare. ponytail: ignores prerelease/build tags;
27
+ * add real semver only if a data prerelease ships.
28
+ */
29
+ export function isBehind(embedded, latest) {
30
+ const a = String(embedded).split(".").map(Number);
31
+ const b = String(latest).split(".").map(Number);
32
+ for (let i = 0; i < Math.max(a.length, b.length); i++) {
33
+ const x = a[i] ?? 0;
34
+ const y = b[i] ?? 0;
35
+ if (x !== y) return x < y;
36
+ }
37
+ return false;
38
+ }
39
+
40
+ let warned = false;
41
+ let cached; // Promise<status|null>, memoized per process — cleared on failure so a
42
+ // transient network blip doesn't permanently disable the check (see fetchLatest).
43
+
44
+ /**
45
+ * @param {string} embeddedVersion - provenance.designDataVersion from ds.primer()
46
+ * @returns {Promise<{latestVersion: string, isStale: boolean, message?: string}|null>}
47
+ */
48
+ export function checkDatasetFreshness(embeddedVersion) {
49
+ if (!embeddedVersion || process.env.DESIGN_DATA_SKIP_VERSION_CHECK) {
50
+ return Promise.resolve(null);
51
+ }
52
+ if (!cached) {
53
+ cached = fetchLatest(embeddedVersion).then((status) => {
54
+ // A null result means the check failed (offline/timeout/registry error) —
55
+ // don't memoize failure, so the next primer call retries instead of being
56
+ // stuck with no freshness signal for the rest of the process.
57
+ if (status === null) cached = undefined;
58
+ return status;
59
+ });
60
+ }
61
+ return cached;
62
+ }
63
+
64
+ async function fetchLatest(embeddedVersion) {
65
+ const controller = new AbortController();
66
+ const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
67
+ try {
68
+ const res = await fetch(REGISTRY_URL, { signal: controller.signal });
69
+ if (!res.ok) return null;
70
+ const { version: latestVersion } = await res.json();
71
+ const isStale = isBehind(embeddedVersion, latestVersion);
72
+ const status = { latestVersion, isStale };
73
+ if (isStale) {
74
+ status.message =
75
+ `Embedded dataset (${embeddedVersion}) is behind the latest published ` +
76
+ `@adobe/spectrum-design-data (${latestVersion}). Reinstall with ` +
77
+ `npx -y @adobe/design-data-agent-mcp@latest to pick up the newer snapshot.`;
78
+ if (!warned) {
79
+ warned = true;
80
+ console.error(`[design-data] ${status.message}`);
81
+ }
82
+ }
83
+ return status;
84
+ } catch {
85
+ return null;
86
+ } finally {
87
+ clearTimeout(timer);
88
+ }
89
+ }
90
+
91
+ /** Test-only: clear the memoized check + warn-once flag between cases. */
92
+ export function __resetFreshnessCache() {
93
+ warned = false;
94
+ cached = undefined;
95
+ }
package/src/tools/read.js CHANGED
@@ -32,6 +32,7 @@ import { readFileSync, existsSync, readdirSync } from "fs";
32
32
  import { join } from "path";
33
33
  import { loadDataset } from "@adobe/design-data/load";
34
34
  import { config } from "../config.js";
35
+ import { checkDatasetFreshness } from "../dataset-freshness.js";
35
36
 
36
37
  // Note: this module intentionally never spawns the native binary — primer and
37
38
  // describe_component must keep working with no CLI on PATH at all (see the
@@ -107,6 +108,11 @@ export function createReadTools() {
107
108
  const wasm = await getWasm();
108
109
  const ds = await getDataset();
109
110
  const { provenance } = ds.primer();
111
+ // Best-effort staleness check (spectrum-design-data-9fe.5) — silent on
112
+ // failure, never blocks the primer response.
113
+ const datasetStatus = await checkDatasetFreshness(
114
+ provenance.designDataVersion,
115
+ );
110
116
  return {
111
117
  // top-level source is the legacy skill-contract field; provenance.source
112
118
  // duplicates it intentionally — provenance is the richer metrics object
@@ -124,7 +130,9 @@ export function createReadTools() {
124
130
  },
125
131
  components: wasm.getFieldValues("component") ?? [],
126
132
  properties: wasm.getFieldValues("property") ?? [],
127
- provenance,
133
+ provenance: datasetStatus
134
+ ? { ...provenance, datasetStatus }
135
+ : provenance,
128
136
  };
129
137
  },
130
138
  },