@duro-app/cli 5.15.0 → 5.17.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.
Files changed (77) hide show
  1. package/README.md +32 -11
  2. package/dist/bin.js +13 -5
  3. package/dist/bin.js.map +1 -1
  4. package/dist/commands/doctor.d.ts +7 -1
  5. package/dist/commands/doctor.d.ts.map +1 -1
  6. package/dist/commands/doctor.js +25 -12
  7. package/dist/commands/doctor.js.map +1 -1
  8. package/dist/commands/hook.d.ts.map +1 -1
  9. package/dist/commands/hook.js +11 -2
  10. package/dist/commands/hook.js.map +1 -1
  11. package/dist/commands/list.d.ts.map +1 -1
  12. package/dist/commands/list.js +23 -2
  13. package/dist/commands/list.js.map +1 -1
  14. package/dist/commands/lookup.d.ts.map +1 -1
  15. package/dist/commands/lookup.js +15 -1
  16. package/dist/commands/lookup.js.map +1 -1
  17. package/dist/commands/mcp.d.ts +57 -0
  18. package/dist/commands/mcp.d.ts.map +1 -1
  19. package/dist/commands/mcp.js +87 -37
  20. package/dist/commands/mcp.js.map +1 -1
  21. package/dist/commands/mockup.d.ts +33 -5
  22. package/dist/commands/mockup.d.ts.map +1 -1
  23. package/dist/commands/mockup.js +167 -13
  24. package/dist/commands/mockup.js.map +1 -1
  25. package/dist/commands/skill.d.ts +6 -0
  26. package/dist/commands/skill.d.ts.map +1 -1
  27. package/dist/commands/skill.js +168 -24
  28. package/dist/commands/skill.js.map +1 -1
  29. package/dist/format.d.ts.map +1 -1
  30. package/dist/format.js +7 -0
  31. package/dist/format.js.map +1 -1
  32. package/dist/hook-script.d.ts +2 -2
  33. package/dist/hook-script.d.ts.map +1 -1
  34. package/dist/hook-script.js +1 -1
  35. package/dist/manifest.d.ts +2 -0
  36. package/dist/manifest.d.ts.map +1 -1
  37. package/dist/manifest.js +28 -10
  38. package/dist/manifest.js.map +1 -1
  39. package/dist/registry-types.d.ts +5 -0
  40. package/dist/registry-types.d.ts.map +1 -1
  41. package/dist/registry.d.ts +20 -0
  42. package/dist/registry.d.ts.map +1 -1
  43. package/dist/registry.js +38 -0
  44. package/dist/registry.js.map +1 -1
  45. package/dist/skill-template.d.ts +1 -1
  46. package/dist/skill-template.d.ts.map +1 -1
  47. package/dist/skill-template.js +20 -9
  48. package/dist/skill-template.js.map +1 -1
  49. package/package.json +6 -5
  50. package/registry.json +35 -0
  51. package/{LICENSE → skills/colors/LICENSE} +1 -1
  52. package/skills/colors/NOTICE.md +36 -0
  53. package/skills/colors/SKILL.md +99 -0
  54. package/skills/colors/color-formats.md +90 -0
  55. package/skills/colors/color-usage.md +109 -0
  56. package/skills/colors/contrast.md +70 -0
  57. package/skills/colors/palette-generation.md +108 -0
  58. package/skills/colors/palette-structure.md +72 -0
  59. package/skills/colors/token-naming.md +99 -0
  60. package/skills/typography/LICENSE +21 -0
  61. package/skills/typography/NOTICE.md +36 -0
  62. package/skills/typography/SKILL.md +169 -0
  63. package/skills/typography/choosing-fonts.md +53 -0
  64. package/skills/typography/css-cheat-sheet.md +67 -0
  65. package/skills/typography/details-and-accessibility.md +84 -0
  66. package/skills/typography/spacing-and-sizing.md +87 -0
  67. package/skills/typography/variable-fonts-and-opentype.md +100 -0
  68. package/skills/typography/wrapping-and-punctuation.md +23 -0
  69. package/skills/ui/LICENSE +21 -0
  70. package/skills/ui/NOTICE.md +36 -0
  71. package/skills/ui/SKILL.md +139 -0
  72. package/skills/ui/animations.md +170 -0
  73. package/skills/ui/enter-exit.md +157 -0
  74. package/skills/ui/icon-transitions.md +72 -0
  75. package/skills/ui/icons.md +105 -0
  76. package/skills/ui/performance.md +63 -0
  77. package/skills/ui/surfaces.md +166 -0
@@ -21,6 +21,8 @@ export declare function toolDefinitions(registry: Registry): ({
21
21
  kind?: undefined;
22
22
  html?: undefined;
23
23
  file?: undefined;
24
+ artboards?: undefined;
25
+ title?: undefined;
24
26
  };
25
27
  required: string[];
26
28
  };
@@ -39,6 +41,8 @@ export declare function toolDefinitions(registry: Registry): ({
39
41
  sourceOnly?: undefined;
40
42
  html?: undefined;
41
43
  file?: undefined;
44
+ artboards?: undefined;
45
+ title?: undefined;
42
46
  };
43
47
  required?: undefined;
44
48
  };
@@ -54,6 +58,8 @@ export declare function toolDefinitions(registry: Registry): ({
54
58
  kind?: undefined;
55
59
  html?: undefined;
56
60
  file?: undefined;
61
+ artboards?: undefined;
62
+ title?: undefined;
57
63
  };
58
64
  required?: undefined;
59
65
  };
@@ -75,6 +81,45 @@ export declare function toolDefinitions(registry: Registry): ({
75
81
  part?: undefined;
76
82
  sourceOnly?: undefined;
77
83
  kind?: undefined;
84
+ artboards?: undefined;
85
+ title?: undefined;
86
+ };
87
+ required: string[];
88
+ };
89
+ } | {
90
+ name: string;
91
+ description: string;
92
+ inputSchema: {
93
+ type: string;
94
+ properties: {
95
+ artboards: {
96
+ type: string;
97
+ description: string;
98
+ items: {
99
+ type: string;
100
+ properties: {
101
+ file: {
102
+ type: string;
103
+ description: string;
104
+ };
105
+ html: {
106
+ type: string;
107
+ description: string;
108
+ };
109
+ };
110
+ required: string[];
111
+ };
112
+ };
113
+ title: {
114
+ type: string;
115
+ description: string;
116
+ };
117
+ name?: undefined;
118
+ part?: undefined;
119
+ sourceOnly?: undefined;
120
+ kind?: undefined;
121
+ html?: undefined;
122
+ file?: undefined;
78
123
  };
79
124
  required: string[];
80
125
  };
@@ -98,5 +143,17 @@ export declare function callTool(registry: Registry, name: string, args: Record<
98
143
  data: unknown;
99
144
  isError: boolean;
100
145
  };
146
+ export declare function listResources(registry: Registry): {
147
+ uri: string;
148
+ name: string;
149
+ mimeType: string;
150
+ }[];
151
+ export declare function readResource(registry: Registry, uri: string): {
152
+ contents: {
153
+ uri: string;
154
+ mimeType: string;
155
+ text: string;
156
+ }[];
157
+ };
101
158
  export declare function runMcp(registry: Registry): Promise<void>;
102
159
  //# sourceMappingURL=mcp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAA;AAalD,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoDjD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;uBAInB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;EAG/F;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;EA2BvF;AAED,wBAAsB,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA2F9D"}
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAA;AAclD,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4EjD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;uBAInB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;EAG/F;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;EAwCvF;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,EAAE,CAkBjG;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,MAAM,GACV;IAAC,QAAQ,EAAE;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,EAAE,CAAA;CAAC,CAkB7D;AAED,wBAAsB,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAmE9D"}
@@ -1,9 +1,10 @@
1
1
  import { buildManifest } from '../manifest.js';
2
+ import { guideNames, lookupGuide } from '../registry.js';
2
3
  import { runLookup } from './lookup.js';
3
4
  import { runList } from './list.js';
4
5
  import { cliVersion } from './manifest.js';
5
6
  import { renderComponent, renderRecipe } from '../format.js';
6
- import { checkArtboard } from './mockup.js';
7
+ import { buildCanvas, checkArtboard } from './mockup.js';
7
8
  const INSTALL_HINT = `duro mcp needs @modelcontextprotocol/sdk (an optional peer).
8
9
  npm i -D @modelcontextprotocol/sdk
9
10
  or run it without installing:
@@ -13,13 +14,13 @@ export function toolDefinitions(registry) {
13
14
  return [
14
15
  {
15
16
  name: 'duro_ds_lookup',
16
- description: 'Docs for anything in the Duro design system by name: a component (props, usage, example), a recipe (runnable source), a token group, "icons", or "rules". Free text falls back to a ranked search over usage metadata — pass what you need, e.g. "tags that wrap".',
17
+ description: 'Docs for anything in the Duro design system by name: a component (props, usage, example), a recipe (runnable source), a token group, "icons", "rules", or an interface guide ("guide:colors", "guide:typography", "guide:ui"; "guide:<skill>/<file>" for one of its reference files). Free text falls back to a ranked search over usage metadata — pass what you need, e.g. "tags that wrap".',
17
18
  inputSchema: {
18
19
  type: 'object',
19
20
  properties: {
20
21
  name: {
21
22
  type: 'string',
22
- description: 'Component/recipe/token-group name, "icons", "rules", or free text to search',
23
+ description: 'Component/recipe/token-group name, "icons", "rules", "guide:<skill>[/<file>]", or free text to search',
23
24
  },
24
25
  part: {
25
26
  type: 'string',
@@ -32,11 +33,11 @@ export function toolDefinitions(registry) {
32
33
  },
33
34
  {
34
35
  name: 'duro_ds_list',
35
- description: `One-line index of everything documented (${Object.keys(registry.components).length} components, ${Object.keys(registry.recipes).length} recipes, token groups).`,
36
+ description: `One-line index of everything documented (${Object.keys(registry.components).length} components, ${Object.keys(registry.recipes).length} recipes, token groups; kind "guides" lists the interface guides).`,
36
37
  inputSchema: {
37
38
  type: 'object',
38
39
  properties: {
39
- kind: { type: 'string', enum: ['components', 'recipes', 'tokens'] },
40
+ kind: { type: 'string', enum: ['components', 'recipes', 'tokens', 'guides'] },
40
41
  },
41
42
  },
42
43
  },
@@ -57,6 +58,29 @@ export function toolDefinitions(registry) {
57
58
  required: ['html'],
58
59
  },
59
60
  },
61
+ {
62
+ name: 'duro_ds_mockup_canvas',
63
+ description: 'One self-contained HTML review page for a set of mockup artboards: each direction (Tree.dc.html and Tree-Phone.dc.html are direction Tree) under a letter, every artboard inlined and scaled to its frame. Publish the page for the person to pick a direction. Nothing is built while an artboard fails duro_ds_mockup_check: the findings come back instead.',
64
+ inputSchema: {
65
+ type: 'object',
66
+ properties: {
67
+ artboards: {
68
+ type: 'array',
69
+ description: 'The artboards, each with its file name and full HTML',
70
+ items: {
71
+ type: 'object',
72
+ properties: {
73
+ file: { type: 'string', description: 'e.g. Tree-Phone.dc.html' },
74
+ html: { type: 'string', description: 'The full artboard HTML' },
75
+ },
76
+ required: ['file', 'html'],
77
+ },
78
+ },
79
+ title: { type: 'string', description: 'The page title' },
80
+ },
81
+ required: ['artboards'],
82
+ },
83
+ },
60
84
  ];
61
85
  }
62
86
  /**
@@ -96,10 +120,66 @@ export function callTool(registry, name, args) {
96
120
  : findings.map((f) => `${f.file}:${f.line} ${f.rule}: ${f.message}`).join('\n');
97
121
  return { text, data: { ok: findings.length === 0, findings }, isError: false };
98
122
  }
123
+ case 'duro_ds_mockup_canvas': {
124
+ const artboards = (Array.isArray(args.artboards) ? args.artboards : [])
125
+ .filter((a) => typeof a === 'object' && a !== null)
126
+ .map((a) => ({ file: String(a.file ?? 'artboard.dc.html'), html: String(a.html ?? '') }));
127
+ if (artboards.length === 0) {
128
+ return { text: 'give at least one artboard', data: { ok: false }, isError: true };
129
+ }
130
+ const title = typeof args.title === 'string' ? args.title : undefined;
131
+ const { html, findings } = buildCanvas(registry, artboards, { title });
132
+ const text = html ?? findings.map((f) => `${f.file}:${f.line} ${f.rule}: ${f.message}`).join('\n');
133
+ return { text, data: { ok: html !== null, html, findings }, isError: false };
134
+ }
99
135
  default:
100
136
  throw new Error(`unknown tool ${name}`);
101
137
  }
102
138
  }
139
+ export function listResources(registry) {
140
+ return [
141
+ ...Object.keys(registry.components).map((name) => ({
142
+ uri: `duro://component/${encodeURIComponent(name)}`,
143
+ name: `${name} docs`,
144
+ mimeType: 'text/plain',
145
+ })),
146
+ ...Object.keys(registry.recipes).map((name) => ({
147
+ uri: `duro://recipe/${name}`,
148
+ name: `${name} recipe`,
149
+ mimeType: 'text/plain',
150
+ })),
151
+ ...guideNames(registry).map((name) => ({
152
+ uri: `duro://guide/${name.slice('guide:'.length)}`,
153
+ name: `${name} guide`,
154
+ mimeType: 'text/markdown',
155
+ })),
156
+ ];
157
+ }
158
+ export function readResource(registry, uri) {
159
+ const componentMatch = /^duro:\/\/component\/(.+)$/.exec(uri);
160
+ const recipeMatch = /^duro:\/\/recipe\/(.+)$/.exec(uri);
161
+ const guideMatch = /^duro:\/\/guide\/(.+)$/.exec(uri);
162
+ let text = null;
163
+ if (guideMatch) {
164
+ const guide = lookupGuide(registry, `guide:${guideMatch[1]}`);
165
+ if (guide.ok)
166
+ text = guide.content;
167
+ }
168
+ else if (componentMatch) {
169
+ const key = decodeURIComponent(componentMatch[1]);
170
+ const entry = registry.components[key];
171
+ if (entry)
172
+ text = renderComponent(registry, key, entry);
173
+ }
174
+ else if (recipeMatch) {
175
+ const entry = registry.recipes[recipeMatch[1]];
176
+ if (entry)
177
+ text = renderRecipe(entry);
178
+ }
179
+ if (text === null)
180
+ throw new Error(`unknown resource ${uri}`);
181
+ return { contents: [{ uri, mimeType: 'text/plain', text }] };
182
+ }
103
183
  export async function runMcp(registry) {
104
184
  let sdkServer, sdkStdio, sdkTypes;
105
185
  try {
@@ -117,39 +197,9 @@ export async function runMcp(registry) {
117
197
  }));
118
198
  server.setRequestHandler(sdkTypes.CallToolRequestSchema, (request) => toolResponse(registry, request.params.name, (request.params.arguments ?? {})));
119
199
  server.setRequestHandler(sdkTypes.ListResourcesRequestSchema, () => ({
120
- resources: [
121
- ...Object.keys(registry.components).map((name) => ({
122
- uri: `duro://component/${encodeURIComponent(name)}`,
123
- name: `${name} docs`,
124
- mimeType: 'text/plain',
125
- })),
126
- ...Object.keys(registry.recipes).map((name) => ({
127
- uri: `duro://recipe/${name}`,
128
- name: `${name} recipe`,
129
- mimeType: 'text/plain',
130
- })),
131
- ],
200
+ resources: listResources(registry),
132
201
  }));
133
- server.setRequestHandler(sdkTypes.ReadResourceRequestSchema, (request) => {
134
- const uri = request.params.uri;
135
- const componentMatch = /^duro:\/\/component\/(.+)$/.exec(uri);
136
- const recipeMatch = /^duro:\/\/recipe\/(.+)$/.exec(uri);
137
- let text = null;
138
- if (componentMatch) {
139
- const key = decodeURIComponent(componentMatch[1]);
140
- const entry = registry.components[key];
141
- if (entry)
142
- text = renderComponent(registry, key, entry);
143
- }
144
- else if (recipeMatch) {
145
- const entry = registry.recipes[recipeMatch[1]];
146
- if (entry)
147
- text = renderRecipe(entry);
148
- }
149
- if (text === null)
150
- throw new Error(`unknown resource ${uri}`);
151
- return { contents: [{ uri, mimeType: 'text/plain', text }] };
152
- });
202
+ server.setRequestHandler(sdkTypes.ReadResourceRequestSchema, (request) => readResource(registry, request.params.uri));
153
203
  server.setRequestHandler(sdkTypes.ListPromptsRequestSchema, () => ({
154
204
  prompts: [
155
205
  {
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  import type { Registry } from '../registry-types.js';
2
2
  import type { CommandResult } from './lookup.js';
3
+ import { MOCKUP_SUBCOMMANDS } from '../manifest.js';
3
4
  export declare const TOKENS_START = "/* duro:tokens start */";
4
5
  export declare const TOKENS_END = "/* duro:tokens end */";
5
- /** The artboard size the design canvas expects on the root element. */
6
+ /** The artboard size, on the root element and in the review canvas's frames. */
6
7
  export declare const ARTBOARD_WIDTH = 1120;
7
8
  export declare const ARTBOARD_HEIGHT = 840;
8
9
  export declare const MOCKUP_THEMES: readonly ["dark", "light", "high-contrast"];
@@ -10,7 +11,7 @@ export type MockupTheme = (typeof MOCKUP_THEMES)[number];
10
11
  export interface SeedOptions {
11
12
  /** Directory to write into. Defaults to docs/mockups/<name>. */
12
13
  out?: string;
13
- /** Artboard file stem. The design canvas needs one called Main. */
14
+ /** Artboard file stem (default Main). */
14
15
  name?: string;
15
16
  theme?: string;
16
17
  cwd?: string;
@@ -18,6 +19,18 @@ export interface SeedOptions {
18
19
  export interface CheckOptions {
19
20
  cwd?: string;
20
21
  }
22
+ export interface CanvasOptions {
23
+ /** Where to write the page. Defaults to <dir>/canvas.html. */
24
+ out?: string;
25
+ /** The page title. Defaults to "<dir name> directions". */
26
+ title?: string;
27
+ cwd?: string;
28
+ }
29
+ /** One artboard handed to the canvas: its file name and its HTML. */
30
+ export interface CanvasArtboard {
31
+ file: string;
32
+ html: string;
33
+ }
21
34
  export interface Finding {
22
35
  file: string;
23
36
  line: number;
@@ -25,8 +38,8 @@ export interface Finding {
25
38
  message: string;
26
39
  }
27
40
  /**
28
- * The artboard skeleton, in the shape the `design` skill's canvas expects:
29
- * support.js verbatim, one <x-dc>, one <helmet><style>. Everything a
41
+ * The artboard skeleton: support.js verbatim, one <x-dc>, one
42
+ * <helmet><style>. Everything a
30
43
  * finished artboard adds goes inside the same style block and the root div.
31
44
  */
32
45
  export declare function seedArtboard(registry: Registry, name: string, theme: MockupTheme): string;
@@ -34,5 +47,20 @@ export declare function runMockupSeed(registry: Registry, options?: SeedOptions)
34
47
  /** Every finding for one artboard's HTML. Exported for the MCP tool and tests. */
35
48
  export declare function checkArtboard(registry: Registry, file: string, source: string): Finding[];
36
49
  export declare function runMockupCheck(registry: Registry, files: string[], options?: CheckOptions): CommandResult;
37
- export declare function runMockup(registry: Registry, sub: string | undefined, rest: string[], options: SeedOptions & CheckOptions): CommandResult;
50
+ /**
51
+ * The review page: every direction side by side, each artboard inlined by
52
+ * srcdoc so the page is one file (an Artifact needs no supporting files, and
53
+ * a local copy opens from disk). The frames are sandboxed: an artboard is
54
+ * untrusted HTML (the MCP tool takes it from the caller) and needs no script. Nothing is built while an artboard fails the
55
+ * check: the person picks from contracts, not from sketches that drift.
56
+ */
57
+ export declare function buildCanvas(registry: Registry, artboards: CanvasArtboard[], options: {
58
+ title?: string;
59
+ }): {
60
+ html: string | null;
61
+ findings: Finding[];
62
+ };
63
+ export declare function runMockupCanvas(registry: Registry, dir: string | undefined, options?: CanvasOptions): CommandResult;
64
+ export { MOCKUP_SUBCOMMANDS };
65
+ export declare function runMockup(registry: Registry, sub: string | undefined, rest: string[], options: SeedOptions & CheckOptions & CanvasOptions): CommandResult;
38
66
  //# sourceMappingURL=mockup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mockup.d.ts","sourceRoot":"","sources":["../../src/commands/mockup.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,aAAa,CAAA;AAuB9C,eAAO,MAAM,YAAY,4BAA4B,CAAA;AACrD,eAAO,MAAM,UAAU,0BAA0B,CAAA;AAEjD,uEAAuE;AACvE,eAAO,MAAM,cAAc,OAAO,CAAA;AAClC,eAAO,MAAM,eAAe,MAAM,CAAA;AAElC,eAAO,MAAM,aAAa,6CAA8C,CAAA;AACxE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAExD,MAAM,WAAW,WAAW;IAC1B,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EACA,WAAW,GACX,YAAY,GACZ,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,GAClB,qBAAqB,CAAA;IACzB,OAAO,EAAE,MAAM,CAAA;CAChB;AAKD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,CA6DzF;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAE,WAAgB,GAAG,aAAa,CAgC1F;AA+UD,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAUzF;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,GAAE,YAAiB,GACzB,aAAa,CA6Bf;AAID,wBAAgB,SAAS,CACvB,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,WAAW,GAAG,YAAY,GAClC,aAAa,CASf"}
1
+ {"version":3,"file":"mockup.d.ts","sourceRoot":"","sources":["../../src/commands/mockup.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,aAAa,CAAA;AAI9C,OAAO,EAAC,kBAAkB,EAAC,MAAM,gBAAgB,CAAA;AAuBjD,eAAO,MAAM,YAAY,4BAA4B,CAAA;AACrD,eAAO,MAAM,UAAU,0BAA0B,CAAA;AAEjD,gFAAgF;AAChF,eAAO,MAAM,cAAc,OAAO,CAAA;AAClC,eAAO,MAAM,eAAe,MAAM,CAAA;AAElC,eAAO,MAAM,aAAa,6CAA8C,CAAA;AACxE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAExD,MAAM,WAAW,WAAW;IAC1B,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EACA,WAAW,GACX,YAAY,GACZ,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,GAClB,qBAAqB,CAAA;IACzB,OAAO,EAAE,MAAM,CAAA;CAChB;AAKD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,CA6DzF;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAE,WAAgB,GAAG,aAAa,CAgC1F;AA+UD,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAUzF;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,GAAE,YAAiB,GACzB,aAAa,CA+Bf;AAoDD;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,cAAc,EAAE,EAC3B,OAAO,EAAE;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,GACxB;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAC,CAqD5C;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,OAAO,GAAE,aAAkB,GAC1B,aAAa,CAsCf;AAED,OAAO,EAAC,kBAAkB,EAAC,CAAA;AAE3B,wBAAgB,SAAS,CACvB,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,WAAW,GAAG,YAAY,GAAG,aAAa,GAClD,aAAa,CAaf"}
@@ -1,8 +1,10 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
- import { join, resolve } from 'node:path';
1
+ import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
2
+ import { dirname, join, relative, resolve } from 'node:path';
3
3
  import { lookup } from '../registry.js';
4
4
  import { suggestions } from '../search.js';
5
5
  import { lineOf } from '../scan.js';
6
+ import { MOCKUP_SUBCOMMANDS } from '../manifest.js';
7
+ import { uiVersionSkew } from './doctor.js';
6
8
  /*
7
9
  * duro mockup — token-seeded artboards, and the check that makes one a
8
10
  * handoff contract.
@@ -13,7 +15,9 @@ import { lineOf } from '../scan.js';
13
15
  * palette). `seed` writes an artboard whose only design vocabulary is the
14
16
  * resolved token block, so the artboard is written in token names from the
15
17
  * first line; `check` refuses an artboard that reaches past them, and refuses
16
- * one that does not say which design-system component each control is.
18
+ * one that does not say which design-system component each control is;
19
+ * `canvas` puts the directions side by side on one page for the person to
20
+ * pick from, and builds it only from artboards that pass `check`.
17
21
  *
18
22
  * What binds when a direction is chosen: layout, hierarchy, states, the
19
23
  * data-duro component map and the token names — sizes and border widths
@@ -22,15 +26,15 @@ import { lineOf } from '../scan.js';
22
26
  */
23
27
  export const TOKENS_START = '/* duro:tokens start */';
24
28
  export const TOKENS_END = '/* duro:tokens end */';
25
- /** The artboard size the design canvas expects on the root element. */
29
+ /** The artboard size, on the root element and in the review canvas's frames. */
26
30
  export const ARTBOARD_WIDTH = 1120;
27
31
  export const ARTBOARD_HEIGHT = 840;
28
32
  export const MOCKUP_THEMES = ['dark', 'light', 'high-contrast'];
29
33
  // ---------------------------------------------------------------------------
30
34
  // seed
31
35
  /**
32
- * The artboard skeleton, in the shape the `design` skill's canvas expects:
33
- * support.js verbatim, one <x-dc>, one <helmet><style>. Everything a
36
+ * The artboard skeleton: support.js verbatim, one <x-dc>, one
37
+ * <helmet><style>. Everything a
34
38
  * finished artboard adds goes inside the same style block and the root div.
35
39
  */
36
40
  export function seedArtboard(registry, name, theme) {
@@ -450,20 +454,165 @@ export function runMockupCheck(registry, files, options = {}) {
450
454
  }
451
455
  all.push(...checkArtboard(registry, file, source));
452
456
  }
453
- const lines = all.map((f) => `${f.file}:${f.line} ${f.rule}: ${f.message}`);
457
+ const lines = all.map(findingLine);
458
+ const skew = uiVersionSkew(cwd);
459
+ const note = skew ? `\n${skewNote(skew, `mockup check ${files.join(' ')}`)}` : '';
454
460
  if (all.length === 0) {
455
461
  return {
456
- text: `duro mockup check: ${files.length} artboard(s) speak tokens and name their components`,
457
- data: { ok: true, files, findings: [] },
462
+ text: `duro mockup check: ${files.length} artboard(s) speak tokens and name their components${note}`,
463
+ data: { ok: true, files, findings: [], ...(skew && { skew }) },
458
464
  };
459
465
  }
460
466
  return {
461
- text: `duro mockup check: ${all.length} finding(s)\n${lines.join('\n')}`,
462
- data: { ok: false, files, findings: all },
467
+ text: `duro mockup check: ${all.length} finding(s)\n${lines.join('\n')}${note}`,
468
+ data: { ok: false, files, findings: all, ...(skew && { skew }) },
463
469
  exitCode: 1,
464
470
  };
465
471
  }
466
- const SUBCOMMANDS = ['seed', 'check'];
472
+ const findingLine = (f) => `${f.file}:${f.line} ${f.rule}: ${f.message}`;
473
+ /**
474
+ * doctor's version-skew finding, said where it explains a finding: a checker
475
+ * older than the app reports a component it has not heard of as unknown. npx
476
+ * keeps a cached CLI that satisfies a range, so this is not hypothetical.
477
+ */
478
+ function skewNote(skew, command) {
479
+ return `note: @duro-app/ui is ${skew.installed}, but this checker knows ${skew.own} — a component newer than the checker reads as unknown. Run: npx -y @duro-app/cli@${skew.installed} ${command}`;
480
+ }
481
+ // ---------------------------------------------------------------------------
482
+ // canvas
483
+ const ARTBOARD_SUFFIX = '.dc.html';
484
+ /** The artboard's own canvas size, from the seeded custom properties. */
485
+ function artboardSize(html) {
486
+ const width = /--duro-mockup-canvas-width:\s*(\d+)px/.exec(html);
487
+ const height = /--duro-mockup-canvas-height:\s*(\d+)px/.exec(html);
488
+ return {
489
+ width: width ? Number(width[1]) : ARTBOARD_WIDTH,
490
+ height: height ? Number(height[1]) : ARTBOARD_HEIGHT,
491
+ };
492
+ }
493
+ const escapeHtml = (text) => text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
494
+ /**
495
+ * An artboard as the page inlines it: without the seed's relative support.js,
496
+ * which a srcdoc frame cannot load and the page does not need.
497
+ */
498
+ const inlineable = (html) => html.replace(/<script src="\.\/support\.js"><\/script>\n?/g, '');
499
+ /** `Tree-Phone.dc.html` is direction `Tree`; `Main` sorts first, then by name. */
500
+ function directions(artboards) {
501
+ const stem = (a) => a.file.split('/').pop().replace(ARTBOARD_SUFFIX, '');
502
+ const groups = new Map();
503
+ for (const artboard of artboards) {
504
+ const key = stem(artboard).split('-')[0];
505
+ groups.set(key, [...(groups.get(key) ?? []), artboard]);
506
+ }
507
+ const rank = (key) => (key === 'Main' ? '' : key);
508
+ return [...groups.entries()]
509
+ .sort(([a], [b]) => rank(a).localeCompare(rank(b)))
510
+ .map(([key, group]) => [key, group.sort((a, b) => stem(a).localeCompare(stem(b)))]);
511
+ }
512
+ /**
513
+ * The review page: every direction side by side, each artboard inlined by
514
+ * srcdoc so the page is one file (an Artifact needs no supporting files, and
515
+ * a local copy opens from disk). The frames are sandboxed: an artboard is
516
+ * untrusted HTML (the MCP tool takes it from the caller) and needs no script. Nothing is built while an artboard fails the
517
+ * check: the person picks from contracts, not from sketches that drift.
518
+ */
519
+ export function buildCanvas(registry, artboards, options) {
520
+ const findings = artboards.flatMap((a) => checkArtboard(registry, a.file, a.html));
521
+ if (findings.length > 0)
522
+ return { html: null, findings };
523
+ const title = escapeHtml(options.title ?? 'Mockup directions');
524
+ const sections = directions(artboards).map(([key, group], index) => {
525
+ const letter = String.fromCharCode(65 + (index % 26));
526
+ const figures = group.map((artboard) => {
527
+ const { width, height } = artboardSize(artboard.html);
528
+ const name = escapeHtml(artboard.file.split('/').pop());
529
+ return `<figure>
530
+ <div class="frame" style="aspect-ratio: ${width} / ${height}"><iframe title="${name}" width="${width}" height="${height}" data-width="${width}" style="transform: scale(0.5)" sandbox="" srcdoc="${escapeHtml(inlineable(artboard.html))}"></iframe></div>
531
+ <figcaption>${name} · ${width}×${height}</figcaption>
532
+ </figure>`;
533
+ });
534
+ return `<section>\n<h2>${letter} · ${escapeHtml(key)}</h2>\n<div class="grid">\n${figures.join('\n')}\n</div>\n</section>`;
535
+ });
536
+ const html = `<!doctype html>
537
+ <html lang="en">
538
+ <head>
539
+ <meta charset="utf-8">
540
+ <meta name="viewport" content="width=device-width, initial-scale=1">
541
+ <title>${title}</title>
542
+ <!-- GENERATED by duro mockup canvas: regenerate it, never edit it. -->
543
+ <style>
544
+ /* The page's own chrome, not a Duro surface: self-contained, themed by system colours. */
545
+ :root { color-scheme: light dark; --gap: 16px; }
546
+ body { margin: 0; padding: var(--gap); background: Canvas; color: CanvasText; font: 14px/1.5 system-ui, sans-serif; }
547
+ h1 { font-size: 20px; margin: 0 0 4px; }
548
+ h2 { font-size: 14px; margin: 32px 0 8px; text-transform: uppercase; letter-spacing: 0.04em; }
549
+ p { margin: 0; opacity: 0.75; }
550
+ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 420px), 1fr)); gap: var(--gap); }
551
+ figure { margin: 0; min-width: 0; }
552
+ .frame { position: relative; width: 100%; overflow: hidden; border: 1px solid GrayText; border-radius: 8px; }
553
+ .frame iframe { position: absolute; inset: 0 auto auto 0; border: 0; transform-origin: 0 0; }
554
+ figcaption { margin-top: 4px; font-size: 12px; opacity: 0.75; }
555
+ </style>
556
+ </head>
557
+ <body>
558
+ <h1>${title}</h1>
559
+ <p>Pick one direction by its letter. Sizes, colours and the component map are the contract; positions are a sketch.</p>
560
+ ${sections.join('\n')}
561
+ <script>
562
+ // Scale each artboard to its frame's width; 0.5 stands until this runs.
563
+ const fit = () => document.querySelectorAll('.frame iframe').forEach((f) => {
564
+ f.style.transform = 'scale(' + f.parentElement.clientWidth / Number(f.dataset.width) + ')'
565
+ })
566
+ new ResizeObserver(fit).observe(document.body)
567
+ fit()
568
+ </script>
569
+ </body>
570
+ </html>
571
+ `;
572
+ return { html, findings: [] };
573
+ }
574
+ export function runMockupCanvas(registry, dir, options = {}) {
575
+ if (!dir)
576
+ return usage('duro mockup canvas: give the directory holding the *.dc.html artboards');
577
+ const cwd = options.cwd ?? process.cwd();
578
+ const abs = resolve(cwd, dir);
579
+ if (!existsSync(abs) || !statSync(abs).isDirectory()) {
580
+ return usage(`duro mockup canvas: ${dir} is not a directory`);
581
+ }
582
+ const files = readdirSync(abs)
583
+ .filter((name) => name.endsWith(ARTBOARD_SUFFIX))
584
+ .sort();
585
+ if (files.length === 0)
586
+ return usage(`duro mockup canvas: no *${ARTBOARD_SUFFIX} in ${dir}`);
587
+ const artboards = files.map((name) => ({
588
+ file: join(dir, name),
589
+ html: readFileSync(join(abs, name), 'utf8'),
590
+ }));
591
+ const title = options.title ?? `${abs.split('/').pop()} directions`;
592
+ const { html, findings } = buildCanvas(registry, artboards, { title });
593
+ const skew = uiVersionSkew(cwd);
594
+ const note = skew ? `\n${skewNote(skew, `mockup canvas ${dir}`)}` : '';
595
+ if (html === null) {
596
+ return {
597
+ text: `duro mockup canvas: ${findings.length} finding(s) — fix them, then build the page\n${findings.map(findingLine).join('\n')}${note}`,
598
+ data: { ok: false, findings, ...(skew && { skew }) },
599
+ exitCode: 1,
600
+ };
601
+ }
602
+ const out = options.out ?? join(dir, 'canvas.html');
603
+ mkdirSync(dirname(resolve(cwd, out)), { recursive: true });
604
+ writeFileSync(resolve(cwd, out), html, 'utf8');
605
+ return {
606
+ text: `duro mockup canvas: ${relative(cwd, resolve(cwd, out))} — ${files.length} artboard(s). Publish it as the Artifact, or open it locally.${note}`,
607
+ data: {
608
+ ok: true,
609
+ path: relative(cwd, resolve(cwd, out)),
610
+ artboards: files.length,
611
+ ...(skew && { skew }),
612
+ },
613
+ };
614
+ }
615
+ export { MOCKUP_SUBCOMMANDS };
467
616
  export function runMockup(registry, sub, rest, options) {
468
617
  if (sub === 'seed') {
469
618
  if (rest.length > 0)
@@ -472,6 +621,11 @@ export function runMockup(registry, sub, rest, options) {
472
621
  }
473
622
  if (sub === 'check')
474
623
  return runMockupCheck(registry, rest, options);
475
- return usage(`duro mockup: unknown subcommand "${sub ?? ''}" — expected ${SUBCOMMANDS.join(' | ')}`);
624
+ if (sub === 'canvas') {
625
+ if (rest.length > 1)
626
+ return usage('duro mockup canvas takes one directory');
627
+ return runMockupCanvas(registry, rest[0], options);
628
+ }
629
+ return usage(`duro mockup: unknown subcommand "${sub ?? ''}" — expected ${MOCKUP_SUBCOMMANDS.join(' | ')}`);
476
630
  }
477
631
  //# sourceMappingURL=mockup.js.map