@calibrate-ds/cli 0.1.6 → 0.1.8

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.
Files changed (49) hide show
  1. package/dist/commands/bridge.d.ts +3 -0
  2. package/dist/commands/bridge.d.ts.map +1 -0
  3. package/dist/commands/bridge.js +62 -0
  4. package/dist/commands/bridge.js.map +1 -0
  5. package/dist/commands/diff.d.ts +7 -0
  6. package/dist/commands/diff.d.ts.map +1 -1
  7. package/dist/commands/diff.js +68 -0
  8. package/dist/commands/diff.js.map +1 -1
  9. package/dist/commands/generate-components.d.ts.map +1 -1
  10. package/dist/commands/generate-components.js +31 -1
  11. package/dist/commands/generate-components.js.map +1 -1
  12. package/dist/commands/init.d.ts.map +1 -1
  13. package/dist/commands/init.js +4 -1
  14. package/dist/commands/init.js.map +1 -1
  15. package/dist/commands/mcp.d.ts +4 -0
  16. package/dist/commands/mcp.d.ts.map +1 -0
  17. package/dist/commands/mcp.js +25 -0
  18. package/dist/commands/mcp.js.map +1 -0
  19. package/dist/commands/verify.d.ts +6 -0
  20. package/dist/commands/verify.d.ts.map +1 -0
  21. package/dist/commands/verify.js +280 -0
  22. package/dist/commands/verify.js.map +1 -0
  23. package/dist/index.js +38 -2
  24. package/dist/index.js.map +1 -1
  25. package/dist/mcp/registry.d.ts +20 -0
  26. package/dist/mcp/registry.d.ts.map +1 -0
  27. package/dist/mcp/registry.js +8 -0
  28. package/dist/mcp/registry.js.map +1 -0
  29. package/dist/mcp/server.d.ts +3 -0
  30. package/dist/mcp/server.d.ts.map +1 -0
  31. package/dist/mcp/server.js +67 -0
  32. package/dist/mcp/server.js.map +1 -0
  33. package/dist/mcp/tools/component-tools.d.ts +9 -0
  34. package/dist/mcp/tools/component-tools.d.ts.map +1 -0
  35. package/dist/mcp/tools/component-tools.js +105 -0
  36. package/dist/mcp/tools/component-tools.js.map +1 -0
  37. package/dist/mcp/tools/governance-tools.d.ts +3 -0
  38. package/dist/mcp/tools/governance-tools.d.ts.map +1 -0
  39. package/dist/mcp/tools/governance-tools.js +180 -0
  40. package/dist/mcp/tools/governance-tools.js.map +1 -0
  41. package/dist/mcp/tools/token-tools.d.ts +3 -0
  42. package/dist/mcp/tools/token-tools.d.ts.map +1 -0
  43. package/dist/mcp/tools/token-tools.js +60 -0
  44. package/dist/mcp/tools/token-tools.js.map +1 -0
  45. package/dist/mcp/tools/verify-tool.d.ts +3 -0
  46. package/dist/mcp/tools/verify-tool.d.ts.map +1 -0
  47. package/dist/mcp/tools/verify-tool.js +82 -0
  48. package/dist/mcp/tools/verify-tool.js.map +1 -0
  49. package/package.json +6 -5
@@ -0,0 +1,105 @@
1
+ import * as fs from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ import { z } from "zod";
4
+ import { getComponentContext } from "@calibrate-ds/core";
5
+ function toSlug(name) {
6
+ return name.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
7
+ }
8
+ function findComponent(snapshot, query) {
9
+ const q = query.toLowerCase();
10
+ const slug = toSlug(query);
11
+ return snapshot.components.find((c) => c.name.toLowerCase() === q || toSlug(c.name) === slug || c.id === query);
12
+ }
13
+ export async function loadBridge(workspaceRoot) {
14
+ try {
15
+ const raw = await fs.readFile(path.join(workspaceRoot, "ptb-bridge.json"), "utf-8");
16
+ return JSON.parse(raw);
17
+ }
18
+ catch {
19
+ return [];
20
+ }
21
+ }
22
+ export const componentTools = {
23
+ name: "component",
24
+ register(server, getContext) {
25
+ server.tool("get_component", "Get the full design context for a component by name. Returns variant axes, token bindings, state contract, interaction contract, implementation hints, and the render tree.", { name: z.string().describe("Component display name, e.g. 'Button' or 'Notification Item'") }, async ({ name }) => {
26
+ let ctx;
27
+ try {
28
+ ctx = await getContext();
29
+ }
30
+ catch (e) {
31
+ return { content: [{ type: "text", text: e.message }] };
32
+ }
33
+ const comp = findComponent(ctx.snapshot, name);
34
+ if (!comp) {
35
+ const available = ctx.snapshot.components.map((c) => c.name).slice(0, 15).join(", ");
36
+ return { content: [{ type: "text", text: `Component '${name}' not found.\nAvailable (first 15): ${available}` }] };
37
+ }
38
+ try {
39
+ const context = await getComponentContext(comp.id, ctx.snapshot, ctx.config);
40
+ if (!context)
41
+ return { content: [{ type: "text", text: `Could not build context for '${name}'.` }] };
42
+ return { content: [{ type: "text", text: JSON.stringify(context, null, 2) }] };
43
+ }
44
+ catch (e) {
45
+ return { content: [{ type: "text", text: `Error building context: ${e.message}` }] };
46
+ }
47
+ });
48
+ server.tool("list_components", "List all components in the design system. Returns name, kind, category, variant axis count, and Figma node ID for each.", async () => {
49
+ let ctx;
50
+ try {
51
+ ctx = await getContext();
52
+ }
53
+ catch (e) {
54
+ return { content: [{ type: "text", text: e.message }] };
55
+ }
56
+ const items = ctx.snapshot.components.map((c) => ({
57
+ name: c.name,
58
+ slug: toSlug(c.name),
59
+ kind: c.kind?.value ?? "unknown",
60
+ category: c.categoryPath ?? "unclassified",
61
+ variantAxes: c.variantAxes?.map((a) => a.name) ?? [],
62
+ nodeId: c.designToolNodeId ?? null,
63
+ }));
64
+ return { content: [{ type: "text", text: JSON.stringify(items, null, 2) }] };
65
+ });
66
+ server.tool("find_component_by_figma_node", "Find a design system component by its Figma node ID. Returns the component definition plus Symbol Bridge export/file info if registered.", { nodeId: z.string().describe("Figma node ID, e.g. '123:456'") }, async ({ nodeId }) => {
67
+ let ctx;
68
+ try {
69
+ ctx = await getContext();
70
+ }
71
+ catch (e) {
72
+ return { content: [{ type: "text", text: e.message }] };
73
+ }
74
+ const comp = ctx.snapshot.components.find((c) => c.designToolNodeId === nodeId);
75
+ if (!comp) {
76
+ return { content: [{ type: "text", text: `No component found for Figma node '${nodeId}'.` }] };
77
+ }
78
+ const bridge = await loadBridge(ctx.workspaceRoot);
79
+ const entry = bridge.find((b) => b.nodeId === nodeId);
80
+ const result = {
81
+ componentName: comp.name,
82
+ nodeId,
83
+ kind: comp.kind?.value ?? "unknown",
84
+ category: comp.categoryPath ?? "unclassified",
85
+ };
86
+ if (entry) {
87
+ result.exportName = entry.componentName;
88
+ result.filePath = entry.filePath;
89
+ }
90
+ try {
91
+ const context = await getComponentContext(comp.id, ctx.snapshot, ctx.config);
92
+ if (context?.variantAxes?.length) {
93
+ result.variantAxes = context.variantAxes.map((a) => ({
94
+ name: a.name,
95
+ options: a.options,
96
+ default: context.component.defaultVariantSelection?.[a.name] ?? a.options[0],
97
+ }));
98
+ }
99
+ }
100
+ catch { /* non-fatal */ }
101
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
102
+ });
103
+ },
104
+ };
105
+ //# sourceMappingURL=component-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/component-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { MCPToolGroup } from "../registry.js";
2
+ export declare const governanceTools: MCPToolGroup;
3
+ //# sourceMappingURL=governance-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"governance-tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/governance-tools.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,gBAAgB,CAAC;AAgB/D,eAAO,MAAM,eAAe,EAAE,YAmL7B,CAAC"}
@@ -0,0 +1,180 @@
1
+ import * as fs from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ import { z } from "zod";
4
+ function toSlug(name) {
5
+ return name.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
6
+ }
7
+ async function loadLock(workspaceRoot) {
8
+ try {
9
+ const raw = await fs.readFile(path.join(workspaceRoot, "ptb.lock"), "utf-8");
10
+ return JSON.parse(raw);
11
+ }
12
+ catch {
13
+ return null;
14
+ }
15
+ }
16
+ export const governanceTools = {
17
+ name: "governance",
18
+ register(server, getContext) {
19
+ server.tool("is_stale", "Check which components are stale (design changed since last stamp), ready (stamped and current), or unstamped (never implemented). Use this to understand the current health of the design system.", async () => {
20
+ let ctx;
21
+ try {
22
+ ctx = await getContext();
23
+ }
24
+ catch (e) {
25
+ return { content: [{ type: "text", text: e.message }] };
26
+ }
27
+ const lock = await loadLock(ctx.workspaceRoot);
28
+ if (!lock) {
29
+ return { content: [{ type: "text", text: "No ptb.lock found. Run 'ptb export context' first." }] };
30
+ }
31
+ const stale = [];
32
+ const ready = [];
33
+ const unstamped = [];
34
+ for (const [slug, entry] of Object.entries(lock.components)) {
35
+ if (!entry.stampedHash) {
36
+ unstamped.push({ name: entry.displayName, slug, assignedTo: entry.assignedTo ?? null });
37
+ }
38
+ else if (entry.stampedHash !== entry.designHash) {
39
+ stale.push({
40
+ name: entry.displayName,
41
+ slug,
42
+ stampedAt: entry.stampedAt ?? null,
43
+ stampedBy: entry.stampedBy ?? null,
44
+ assignedTo: entry.assignedTo ?? null,
45
+ });
46
+ }
47
+ else {
48
+ ready.push({
49
+ name: entry.displayName,
50
+ slug,
51
+ stampedAt: entry.stampedAt ?? null,
52
+ stampedBy: entry.stampedBy ?? null,
53
+ });
54
+ }
55
+ }
56
+ const summary = {
57
+ total: ready.length + stale.length + unstamped.length,
58
+ ready: ready.length,
59
+ stale: stale.length,
60
+ unstamped: unstamped.length,
61
+ components: { ready, stale, unstamped },
62
+ };
63
+ return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
64
+ });
65
+ server.tool("what_uses", "Find all components that depend on a given component. Useful for understanding blast radius before changing a component.", { name: z.string().describe("Component name to search for usages, e.g. 'Toggle' or 'Avatar'") }, async ({ name }) => {
66
+ let ctx;
67
+ try {
68
+ ctx = await getContext();
69
+ }
70
+ catch (e) {
71
+ return { content: [{ type: "text", text: e.message }] };
72
+ }
73
+ const q = name.toLowerCase();
74
+ const slug = toSlug(name);
75
+ const target = ctx.snapshot.components.find((c) => c.name.toLowerCase() === q || toSlug(c.name) === slug || c.id === name);
76
+ if (!target) {
77
+ return { content: [{ type: "text", text: `Component '${name}' not found in snapshot.` }] };
78
+ }
79
+ // Check both the id and designToolNodeId for reverse-dependency lookup
80
+ const targetIds = new Set([target.id, target.designToolNodeId].filter(Boolean));
81
+ const users = ctx.snapshot.components
82
+ .filter((c) => {
83
+ if (c.id === target.id)
84
+ return false;
85
+ const deps = c.dependencies ?? [];
86
+ if (deps.some((id) => targetIds.has(id)))
87
+ return true;
88
+ const instances = c.dependencyInstances ?? [];
89
+ return instances.some((di) => targetIds.has(di.componentId));
90
+ })
91
+ .map((c) => ({
92
+ name: c.name,
93
+ kind: c.kind?.value ?? "unknown",
94
+ category: c.categoryPath ?? "unclassified",
95
+ }));
96
+ // Also check model-level dependency edges
97
+ const modelEdges = (ctx.snapshot.dependencies ?? [])
98
+ .filter((e) => targetIds.has(e.targetId))
99
+ .map((e) => {
100
+ const src = ctx.snapshot.components.find((c) => c.id === e.sourceId);
101
+ return src ? { name: src.name, kind: src.kind?.value ?? "unknown", via: e.type } : null;
102
+ })
103
+ .filter(Boolean);
104
+ const merged = [...users];
105
+ for (const edge of modelEdges) {
106
+ if (!merged.find((u) => u.name === edge.name))
107
+ merged.push(edge);
108
+ }
109
+ if (merged.length === 0) {
110
+ return { content: [{ type: "text", text: `No other components depend on '${target.name}'.` }] };
111
+ }
112
+ return { content: [{ type: "text", text: JSON.stringify({ target: target.name, usedBy: merged }, null, 2) }] };
113
+ });
114
+ server.tool("coverage_summary", "Get a high-level coverage report for the whole design system: how many components are ready, stale, or unimplemented. Grouped by category.", async () => {
115
+ let ctx;
116
+ try {
117
+ ctx = await getContext();
118
+ }
119
+ catch (e) {
120
+ return { content: [{ type: "text", text: e.message }] };
121
+ }
122
+ const lock = await loadLock(ctx.workspaceRoot);
123
+ if (!lock) {
124
+ return { content: [{ type: "text", text: "No ptb.lock found. Run 'ptb export context' first." }] };
125
+ }
126
+ const byCategory = {};
127
+ const getOrCreate = (cat) => {
128
+ if (!byCategory[cat])
129
+ byCategory[cat] = { ready: 0, stale: 0, unstamped: 0 };
130
+ return byCategory[cat];
131
+ };
132
+ for (const [slug, entry] of Object.entries(lock.components)) {
133
+ const comp = ctx.snapshot.components.find((c) => toSlug(c.name) === slug);
134
+ const cat = comp?.categoryPath ?? "unclassified";
135
+ const bucket = getOrCreate(cat);
136
+ if (!entry.stampedHash)
137
+ bucket.unstamped++;
138
+ else if (entry.stampedHash !== entry.designHash)
139
+ bucket.stale++;
140
+ else
141
+ bucket.ready++;
142
+ }
143
+ const total = Object.values(lock.components);
144
+ const summary = {
145
+ total: total.length,
146
+ ready: total.filter((e) => e.stampedHash && e.stampedHash === e.designHash).length,
147
+ stale: total.filter((e) => e.stampedHash && e.stampedHash !== e.designHash).length,
148
+ unstamped: total.filter((e) => !e.stampedHash).length,
149
+ byCategory,
150
+ };
151
+ return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
152
+ });
153
+ server.tool("token_impact", "Find all components that use a specific design token. Useful for understanding which components will be affected when a token value changes.", { tokenName: z.string().describe("Token name or CSS variable, e.g. 'colors.brand.900' or '--ptb-colors-brand-900'") }, async ({ tokenName }) => {
154
+ let ctx;
155
+ try {
156
+ ctx = await getContext();
157
+ }
158
+ catch (e) {
159
+ return { content: [{ type: "text", text: e.message }] };
160
+ }
161
+ const query = tokenName.replace(/^--/, "").toLowerCase();
162
+ const affected = [];
163
+ for (const comp of ctx.snapshot.components) {
164
+ const bindings = comp.tokenBindings ?? [];
165
+ const matches = bindings.filter((b) => {
166
+ const name = (b.tokenName ?? b.cssVar ?? b.variableName ?? "").toLowerCase();
167
+ return name.includes(query);
168
+ });
169
+ if (matches.length > 0) {
170
+ affected.push({ component: comp.name, category: comp.categoryPath, bindings: matches });
171
+ }
172
+ }
173
+ if (affected.length === 0) {
174
+ return { content: [{ type: "text", text: `No components found using token '${tokenName}'.` }] };
175
+ }
176
+ return { content: [{ type: "text", text: JSON.stringify({ tokenName, affectedComponents: affected }, null, 2) }] };
177
+ });
178
+ },
179
+ };
180
+ //# sourceMappingURL=governance-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"governance-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/governance-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { MCPToolGroup } from "../registry.js";
2
+ export declare const tokenTools: MCPToolGroup;
3
+ //# sourceMappingURL=token-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/token-tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,gBAAgB,CAAC;AAG/D,eAAO,MAAM,UAAU,EAAE,YAgExB,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { z } from "zod";
2
+ export const tokenTools = {
3
+ name: "token",
4
+ register(server, getContext) {
5
+ server.tool("list_themes", "List all token collections (themes) in the design system. Returns each collection's name and a sample of its tokens.", async () => {
6
+ let ctx;
7
+ try {
8
+ ctx = await getContext();
9
+ }
10
+ catch (e) {
11
+ return { content: [{ type: "text", text: e.message }] };
12
+ }
13
+ const collections = ctx.snapshot.tokens ?? [];
14
+ if (collections.length === 0) {
15
+ return { content: [{ type: "text", text: "No token collections found in snapshot." }] };
16
+ }
17
+ const summary = collections.map((col) => ({
18
+ name: col.name,
19
+ tokenCount: col.tokens?.length ?? 0,
20
+ sampleTokens: (col.tokens ?? []).slice(0, 5).map((t) => ({
21
+ name: t.name,
22
+ cssVar: t.cssVar ?? t.codeNames?.css ?? null,
23
+ value: t.resolvedValue ?? t.value ?? null,
24
+ })),
25
+ }));
26
+ return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
27
+ });
28
+ server.tool("get_token", "Look up a design token by name or path. Returns resolved value, CSS variable, and which collection it belongs to.", { path: z.string().describe("Token name or partial path, e.g. 'brand.900', 'spacing.4', or 'border-radius'") }, async ({ path: tokenPath }) => {
29
+ let ctx;
30
+ try {
31
+ ctx = await getContext();
32
+ }
33
+ catch (e) {
34
+ return { content: [{ type: "text", text: e.message }] };
35
+ }
36
+ const query = tokenPath.toLowerCase();
37
+ const matches = [];
38
+ for (const col of (ctx.snapshot.tokens ?? [])) {
39
+ for (const token of col.tokens ?? []) {
40
+ const name = (token.name ?? "").toLowerCase();
41
+ const cssVar = (token.cssVar ?? token.codeNames?.css ?? "").toLowerCase();
42
+ if (name.includes(query) || cssVar.includes(query)) {
43
+ matches.push({
44
+ collection: col.name,
45
+ name: token.name,
46
+ cssVar: token.cssVar ?? token.codeNames?.css ?? null,
47
+ resolvedValue: token.resolvedValue ?? token.value ?? null,
48
+ valueType: token.valueType ?? null,
49
+ });
50
+ }
51
+ }
52
+ }
53
+ if (matches.length === 0) {
54
+ return { content: [{ type: "text", text: `No tokens found matching '${tokenPath}'.` }] };
55
+ }
56
+ return { content: [{ type: "text", text: JSON.stringify(matches, null, 2) }] };
57
+ });
58
+ },
59
+ };
60
+ //# sourceMappingURL=token-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-tools.js","sourceRoot":"","sources":["../../../src/mcp/tools/token-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { MCPToolGroup } from "../registry.js";
2
+ export declare const verifyTool: MCPToolGroup;
3
+ //# sourceMappingURL=verify-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-tool.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/verify-tool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,gBAAgB,CAAC;AAO/D,eAAO,MAAM,UAAU,EAAE,YA8ExB,CAAC"}
@@ -0,0 +1,82 @@
1
+ import * as fs from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ import { z } from "zod";
4
+ function toSlug(name) {
5
+ return name.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
6
+ }
7
+ export const verifyTool = {
8
+ name: "verify",
9
+ register(server, getContext) {
10
+ server.tool("get_verify_report", "Retrieve the latest visual verification report for a component. Shows pixel match score, AI-detected visual differences, and paths to screenshots. Run 'ptb verify component <name>' first to generate or refresh the report.", { name: z.string().describe("Component name, e.g. 'Button'") }, async ({ name }) => {
11
+ let ctx;
12
+ try {
13
+ ctx = await getContext();
14
+ }
15
+ catch (e) {
16
+ return { content: [{ type: "text", text: e.message }] };
17
+ }
18
+ const slug = toSlug(name);
19
+ const reportPath = path.join(ctx.metadataDir, "verify", slug, "report.json");
20
+ try {
21
+ const raw = await fs.readFile(reportPath, "utf-8");
22
+ const report = JSON.parse(raw);
23
+ const summary = {
24
+ component: report.componentName,
25
+ checkedAt: report.checkedAt,
26
+ pixelMatchScore: report.pixelMatch?.score ?? null,
27
+ assessment: report.aiFeedback?.overallAssessment ?? null,
28
+ summary: report.aiFeedback?.summary ?? null,
29
+ differences: report.aiFeedback?.differences ?? [],
30
+ screenshots: report.screenshots,
31
+ };
32
+ return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
33
+ }
34
+ catch {
35
+ return {
36
+ content: [{
37
+ type: "text",
38
+ text: `No verify report found for '${name}'.\nRun: ptb verify component ${name}`,
39
+ }],
40
+ };
41
+ }
42
+ });
43
+ server.tool("list_verify_reports", "List all components that have been visually verified, with their latest pixel match scores and assessment.", async () => {
44
+ let ctx;
45
+ try {
46
+ ctx = await getContext();
47
+ }
48
+ catch (e) {
49
+ return { content: [{ type: "text", text: e.message }] };
50
+ }
51
+ const verifyDir = path.join(ctx.metadataDir, "verify");
52
+ let slugDirs;
53
+ try {
54
+ slugDirs = await fs.readdir(verifyDir);
55
+ }
56
+ catch {
57
+ return { content: [{ type: "text", text: "No verify reports found. Run 'ptb verify component <name>' to generate one." }] };
58
+ }
59
+ const reports = [];
60
+ for (const slug of slugDirs) {
61
+ const reportPath = path.join(verifyDir, slug, "report.json");
62
+ try {
63
+ const raw = await fs.readFile(reportPath, "utf-8");
64
+ const report = JSON.parse(raw);
65
+ reports.push({
66
+ component: report.componentName,
67
+ slug,
68
+ checkedAt: report.checkedAt,
69
+ score: report.pixelMatch?.score ?? null,
70
+ assessment: report.aiFeedback?.overallAssessment ?? null,
71
+ });
72
+ }
73
+ catch { /* skip malformed */ }
74
+ }
75
+ if (reports.length === 0) {
76
+ return { content: [{ type: "text", text: "No valid verify reports found." }] };
77
+ }
78
+ return { content: [{ type: "text", text: JSON.stringify(reports, null, 2) }] };
79
+ });
80
+ },
81
+ };
82
+ //# sourceMappingURL=verify-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-tool.js","sourceRoot":"","sources":["../../../src/mcp/tools/verify-tool.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calibrate-ds/cli",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,13 +20,14 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@anthropic-ai/sdk": "^0.39.0",
23
+ "@modelcontextprotocol/sdk": "^1.29.0",
23
24
  "commander": "^14.0.3",
24
25
  "openai": "^6.34.0",
25
26
  "zod": "^4.3.6",
26
- "@calibrate-ds/figma-client": "^0.1.6",
27
- "@calibrate-ds/shared-types": "^0.1.6",
28
- "@calibrate-ds/core": "^0.1.6",
29
- "@calibrate-ds/generator-react": "^0.1.6"
27
+ "@calibrate-ds/core": "^0.1.8",
28
+ "@calibrate-ds/figma-client": "^0.1.8",
29
+ "@calibrate-ds/shared-types": "^0.1.8",
30
+ "@calibrate-ds/generator-react": "^0.1.8"
30
31
  },
31
32
  "devDependencies": {
32
33
  "@types/node": "^22.13.5",