@duro-app/cli 2.0.1 → 3.0.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 (41) hide show
  1. package/README.md +49 -4
  2. package/dist/bin.js +15 -1
  3. package/dist/bin.js.map +1 -1
  4. package/dist/commands/hook.d.ts.map +1 -1
  5. package/dist/commands/hook.js +21 -0
  6. package/dist/commands/hook.js.map +1 -1
  7. package/dist/commands/mcp.d.ts +28 -1
  8. package/dist/commands/mcp.d.ts.map +1 -1
  9. package/dist/commands/mcp.js +22 -1
  10. package/dist/commands/mcp.js.map +1 -1
  11. package/dist/commands/mockup.d.ts +38 -0
  12. package/dist/commands/mockup.d.ts.map +1 -0
  13. package/dist/commands/mockup.js +436 -0
  14. package/dist/commands/mockup.js.map +1 -0
  15. package/dist/commands/skill.d.ts +9 -0
  16. package/dist/commands/skill.d.ts.map +1 -0
  17. package/dist/commands/skill.js +100 -0
  18. package/dist/commands/skill.js.map +1 -0
  19. package/dist/disambiguation.d.ts.map +1 -1
  20. package/dist/disambiguation.js +4 -2
  21. package/dist/disambiguation.js.map +1 -1
  22. package/dist/hook-script.d.ts +7 -6
  23. package/dist/hook-script.d.ts.map +1 -1
  24. package/dist/hook-script.js +6 -5
  25. package/dist/hook-script.js.map +1 -1
  26. package/dist/index.d.ts +1 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +1 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/manifest.d.ts +2 -0
  31. package/dist/manifest.d.ts.map +1 -1
  32. package/dist/manifest.js +58 -1
  33. package/dist/manifest.js.map +1 -1
  34. package/dist/registry-types.d.ts +6 -0
  35. package/dist/registry-types.d.ts.map +1 -1
  36. package/dist/skill-template.d.ts +22 -0
  37. package/dist/skill-template.d.ts.map +1 -0
  38. package/dist/skill-template.js +119 -0
  39. package/dist/skill-template.js.map +1 -0
  40. package/package.json +5 -5
  41. package/registry.json +152 -7
@@ -0,0 +1,436 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join, resolve } from 'node:path';
3
+ import { lookup } from '../registry.js';
4
+ import { suggestions } from '../search.js';
5
+ /*
6
+ * duro mockup — token-seeded artboards, and the check that makes one a
7
+ * handoff contract.
8
+ *
9
+ * A mockup drawn outside the token system has to be TRANSLATED into the
10
+ * design system when it is implemented, and every translation drifts (the
11
+ * gate-board mockup of 2026-09 used 158 hex literals, 15 of them in the
12
+ * palette). `seed` writes an artboard whose only design vocabulary is the
13
+ * resolved token block, so the artboard is written in token names from the
14
+ * first line; `check` refuses an artboard that reaches past them, and refuses
15
+ * one that does not say which design-system component each control is.
16
+ *
17
+ * What binds when a direction is chosen: layout, hierarchy, states, the
18
+ * data-duro component map and the token names. What does not: the artboard's
19
+ * pixel geometry — widths, heights and positions are not tokens and are not
20
+ * checked.
21
+ */
22
+ export const TOKENS_START = '/* duro:tokens start */';
23
+ export const TOKENS_END = '/* duro:tokens end */';
24
+ /** The artboard size the design canvas expects on the root element. */
25
+ export const ARTBOARD_WIDTH = 1120;
26
+ export const ARTBOARD_HEIGHT = 840;
27
+ export const MOCKUP_THEMES = ['dark', 'light', 'high-contrast'];
28
+ // ---------------------------------------------------------------------------
29
+ // seed
30
+ /**
31
+ * The artboard skeleton, in the shape the `design` skill's canvas expects:
32
+ * support.js verbatim, one <x-dc>, one <helmet><style>. Everything a
33
+ * finished artboard adds goes inside the same style block and the root div.
34
+ */
35
+ export function seedArtboard(registry, name, theme) {
36
+ const themeAttr = theme === 'dark' ? '' : ` data-theme="${theme}"`;
37
+ const tokens = registry.tokens.mockupCss.trimEnd();
38
+ return `<!doctype html>
39
+ <html${themeAttr}>
40
+ <head>
41
+ <meta charset="utf-8">
42
+ <script src="./support.js"></script>
43
+ </head>
44
+ <body>
45
+ <x-dc>
46
+ <helmet>
47
+ <style>
48
+ ${TOKENS_START}
49
+ ${tokens}
50
+ ${TOKENS_END}
51
+
52
+ /*
53
+ * ${name} — a Duro mockup artboard. GENERATED by \`duro mockup seed\`.
54
+ *
55
+ * Every colour, spacing, radius, font, shadow and duration below is a
56
+ * var(--duro-*) from the block above — never a literal. Geometry (widths,
57
+ * heights, positions) is free. Every element a person can act on carries
58
+ * data-duro="<Component>" or data-duro="<Component>.<Part>" naming the
59
+ * @duro-app/ui component that will implement it (duro list components).
60
+ * \`duro mockup check ${name}.dc.html\` enforces both.
61
+ */
62
+ body {
63
+ margin: 0;
64
+ background: var(--duro-color-bg);
65
+ color: var(--duro-color-text);
66
+ font-family: var(--duro-typography-font-family);
67
+ font-size: var(--duro-typography-font-size-md);
68
+ line-height: var(--duro-typography-line-height);
69
+ }
70
+ .artboard {
71
+ width: ${ARTBOARD_WIDTH}px;
72
+ height: ${ARTBOARD_HEIGHT}px;
73
+ overflow: hidden;
74
+ padding: var(--duro-spacing-lg);
75
+ box-sizing: border-box;
76
+ }
77
+ </style>
78
+ </helmet>
79
+ <div class="artboard">
80
+ <!--
81
+ Vocabulary (delete this comment when the artboard is authored):
82
+ <div data-duro="PageShell"> … </div>
83
+ <button data-duro="Button variant=primary">Save</button>
84
+ <div data-duro="Tabs"> <div data-duro="Tabs.List"> <div data-duro="Tabs.Tab">…</div> </div> </div>
85
+ <div data-duro="Table"> … </div>
86
+ <span data-duro="Badge variant=success">Granted</span>
87
+ Props after the name are notes for the implementer, not checked.
88
+ -->
89
+ </div>
90
+ </x-dc>
91
+ </body>
92
+ </html>
93
+ `;
94
+ }
95
+ export function runMockupSeed(registry, options = {}) {
96
+ const cwd = options.cwd ?? process.cwd();
97
+ const name = options.name ?? 'Main';
98
+ if (!/^[A-Za-z][A-Za-z0-9-]*$/.test(name)) {
99
+ return usage(`duro mockup seed: --name must be a bare file stem, got "${name}"`);
100
+ }
101
+ const theme = (options.theme ?? 'dark');
102
+ if (!MOCKUP_THEMES.includes(theme)) {
103
+ return usage(`duro mockup seed: --theme must be one of ${MOCKUP_THEMES.join(' | ')}, got "${theme}"`);
104
+ }
105
+ const dir = options.out ?? join('docs', 'mockups', name.toLowerCase());
106
+ const path = join(dir, `${name}.dc.html`);
107
+ const abs = resolve(cwd, path);
108
+ if (existsSync(abs)) {
109
+ return {
110
+ text: `duro mockup seed: ${path} exists — pick another --name or --out, or delete it`,
111
+ data: { kind: 'exists', path },
112
+ exitCode: 1,
113
+ };
114
+ }
115
+ mkdirSync(resolve(cwd, dir), { recursive: true });
116
+ writeFileSync(abs, seedArtboard(registry, name, theme), 'utf8');
117
+ return {
118
+ text: [
119
+ `Seeded ${path} (${theme}).`,
120
+ 'Author it with var(--duro-*) values and data-duro component names only,',
121
+ `then: duro mockup check ${path} (an unauthored seed fails on no-component-map alone)`,
122
+ ].join('\n'),
123
+ data: { ok: true, path, theme },
124
+ };
125
+ }
126
+ // ---------------------------------------------------------------------------
127
+ // check
128
+ /** CSS properties whose values are design tokens in this system. */
129
+ const SPACING_PROPS = /^(padding|margin|gap|row-gap|column-gap|inset|padding-[a-z-]+|margin-[a-z-]+)$/;
130
+ const RADIUS_PROPS = /^border(-[a-z]+-[a-z]+)?-radius$/;
131
+ const TYPE_PROPS = /^(font-size|font-weight|font-family|font)$/;
132
+ const SHADOW_PROPS = /^box-shadow$/;
133
+ const MOTION_PROPS = /^(transition|transition-duration|transition-timing-function|animation|animation-duration|animation-timing-function)$/;
134
+ const COLOR_LITERAL = /#[0-9a-fA-F]{3,8}\b|\b(?:rgba?|hsla?)\(/g;
135
+ const LENGTH_LITERAL = /(?<![\w.-])(\d*\.?\d+)(px|rem|em|ms|s)\b/g;
136
+ const WEIGHT_LITERAL = /(?<![\w.-])([1-9]00)\b/;
137
+ const BREAKPOINT_QUERY = /@(?:media|container)[^{]*?\(\s*(?:min|max)-(?:width|height)\s*:\s*(\d+)px\s*\)/g;
138
+ /** Native controls — a duro component exists for each; an artboard names it. */
139
+ const NATIVE_CONTROLS = new Set(['button', 'input', 'select', 'textarea', 'a', 'table', 'dialog']);
140
+ const VOID_ELEMENTS = new Set([
141
+ 'area',
142
+ 'base',
143
+ 'br',
144
+ 'col',
145
+ 'embed',
146
+ 'hr',
147
+ 'img',
148
+ 'input',
149
+ 'link',
150
+ 'meta',
151
+ 'source',
152
+ 'track',
153
+ 'wbr',
154
+ ]);
155
+ function usage(text) {
156
+ return { text, data: { kind: 'usage-error' }, exitCode: 2 };
157
+ }
158
+ function lineOf(source, index) {
159
+ let line = 1;
160
+ for (let i = 0; i < index && i < source.length; i++)
161
+ if (source[i] === '\n')
162
+ line++;
163
+ return line;
164
+ }
165
+ /** Blank out the token block so its literals are never scanned, keeping offsets. */
166
+ function maskTokenBlock(source) {
167
+ const start = source.indexOf(TOKENS_START);
168
+ if (start < 0)
169
+ return source;
170
+ const end = source.indexOf(TOKENS_END, start);
171
+ if (end < 0)
172
+ return source;
173
+ const stop = end + TOKENS_END.length;
174
+ return (source.slice(0, start) + source.slice(start, stop).replace(/[^\n]/g, ' ') + source.slice(stop));
175
+ }
176
+ /** Blank out comments and var(...) references, keeping offsets. */
177
+ function maskInert(css) {
178
+ return css
179
+ .replace(/\/\*[\s\S]*?\*\//g, (m) => m.replace(/[^\n]/g, ' '))
180
+ .replace(/var\([^)]*\)/g, (m) => ' '.repeat(m.length));
181
+ }
182
+ /** Every `prop: value` in a CSS text, with file offsets. Braces are ignored. */
183
+ function declarations(css, base) {
184
+ const out = [];
185
+ const re = /([a-zA-Z-]+)\s*:\s*([^;{}]+)/g;
186
+ let m;
187
+ while ((m = re.exec(css))) {
188
+ const prop = m[1].toLowerCase();
189
+ // `a:hover`, `@media (min-width: …)` and URLs are not declarations.
190
+ if (prop.startsWith('-') || (m.index > 0 && /[(@:]/.test(css[m.index - 1] ?? '')))
191
+ continue;
192
+ out.push({ prop, value: m[2], at: base + m.index + m[0].indexOf(m[2]) });
193
+ }
194
+ return out;
195
+ }
196
+ function scanCss(file, source, css, base, findings) {
197
+ const inert = maskInert(css);
198
+ // Colors: a literal is never right, on any property.
199
+ for (const m of inert.matchAll(COLOR_LITERAL)) {
200
+ findings.push({
201
+ file,
202
+ line: lineOf(source, base + (m.index ?? 0)),
203
+ rule: 'raw-color',
204
+ message: `'${m[0].replace(/\($/, '')}' is a raw colour — use a var(--duro-color-*) from the token block`,
205
+ });
206
+ }
207
+ // Breakpoints: media queries cannot read a variable, so a literal is
208
+ // allowed — but only one from the scale.
209
+ const scale = breakpointScale();
210
+ for (const m of inert.matchAll(BREAKPOINT_QUERY)) {
211
+ if (!scale.has(Number(m[1]))) {
212
+ findings.push({
213
+ file,
214
+ line: lineOf(source, base + (m.index ?? 0)),
215
+ rule: 'raw-breakpoint',
216
+ message: `${m[1]}px is not a breakpoint — the scale is ${[...scale].join(' / ')}px`,
217
+ });
218
+ }
219
+ }
220
+ for (const { prop, value, at } of declarations(inert, base)) {
221
+ const hint = SPACING_PROPS.test(prop)
222
+ ? '--duro-spacing-*'
223
+ : RADIUS_PROPS.test(prop)
224
+ ? '--duro-radius-*'
225
+ : TYPE_PROPS.test(prop)
226
+ ? '--duro-typography-* / --duro-type-scale-*'
227
+ : SHADOW_PROPS.test(prop)
228
+ ? '--duro-shadow-*'
229
+ : MOTION_PROPS.test(prop)
230
+ ? '--duro-duration-* / --duro-easing-*'
231
+ : null;
232
+ if (!hint)
233
+ continue;
234
+ const hit = value.match(LENGTH_LITERAL)?.find((l) => !/^0(px|rem|em|ms|s)$/.test(l));
235
+ const weight = prop === 'font-weight' || prop === 'font' ? value.match(WEIGHT_LITERAL)?.[1] : null;
236
+ const literal = hit ?? weight;
237
+ if (literal) {
238
+ findings.push({
239
+ file,
240
+ line: lineOf(source, at),
241
+ rule: 'raw-length',
242
+ message: `${literal} on \`${prop}\` is a raw value — use a var(${hint}) token`,
243
+ });
244
+ }
245
+ }
246
+ }
247
+ let cachedScale = null;
248
+ function breakpointScale() {
249
+ return (cachedScale ?? (cachedScale = new Set([480, 640, 768, 1024, 1280])));
250
+ }
251
+ function resolveComponent(registry, spec) {
252
+ // "Button variant=primary" → Button; "Tabs.Tab" → Tabs + part Tab.
253
+ const head = spec.trim().split(/\s+/)[0] ?? '';
254
+ const [name, part] = head.split('.');
255
+ const hit = lookup(registry, name);
256
+ if (!hit || (hit.kind !== 'component' && hit.kind !== 'recipe'))
257
+ return `unknown component "${name}"`;
258
+ if (part && hit.kind === 'component') {
259
+ const parts = hit.entry.parts;
260
+ if (!parts)
261
+ return `${hit.key} has no parts — drop ".${part}"`;
262
+ if (!parts[part])
263
+ return `${hit.key} has no part "${part}" (${Object.keys(parts).join(', ')})`;
264
+ }
265
+ return null;
266
+ }
267
+ function scanMarkup(file, source, findings, registry) {
268
+ // The markup is what is left once <style> blocks are blanked.
269
+ const blank = (m) => m.replace(/[^\n]/g, ' ');
270
+ const html = source
271
+ .replace(/<style\b[\s\S]*?<\/style>/gi, blank)
272
+ .replace(/<!--[\s\S]*?-->/g, blank);
273
+ const styleBlocks = [...source.matchAll(/<style\b[^>]*>([\s\S]*?)<\/style>/gi)];
274
+ // Classes whose rules read like a control, so a styled div that uses one
275
+ // has to be named. A control in a canvas artboard is rarely a <button>: it
276
+ // is a div with a pointer cursor, a hover state, or the padded rounded
277
+ // filled look of a button/chip/row. The signature is the UNION over every
278
+ // rule that mentions the class — `.btn{padding;border-radius}` and
279
+ // `.btn.pri{background}` together make `btn` a control.
280
+ const traits = new Map();
281
+ const trait = (cls, t) => {
282
+ const set = traits.get(cls) ?? new Set();
283
+ set.add(t);
284
+ traits.set(cls, set);
285
+ };
286
+ for (const block of styleBlocks) {
287
+ const css = maskInert(maskTokenBlock(block[1]));
288
+ for (const rule of css.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
289
+ const [, selector, body] = rule;
290
+ const classes = [...selector.matchAll(/\.([A-Za-z_][\w-]*)/g)].map((m) => m[1]);
291
+ for (const cls of classes) {
292
+ if (/cursor\s*:\s*pointer/.test(body))
293
+ trait(cls, 'pointer');
294
+ if (/:(hover|active|focus)/.test(selector))
295
+ trait(cls, 'state');
296
+ if (/border-radius\s*:/.test(body))
297
+ trait(cls, 'radius');
298
+ if (/padding(-[a-z]+)?\s*:/.test(body))
299
+ trait(cls, 'padding');
300
+ if (/background(-color)?\s*:/.test(body))
301
+ trait(cls, 'fill');
302
+ }
303
+ }
304
+ }
305
+ const controlClasses = new Set([...traits]
306
+ .filter(([, t]) => t.has('pointer') ||
307
+ t.has('state') ||
308
+ (t.has('radius') && t.has('padding') && t.has('fill')))
309
+ .map(([cls]) => cls));
310
+ const stack = [];
311
+ let annotatedCount = 0;
312
+ const tagRe = /<\/?([a-zA-Z][\w-]*)([^>]*)>/g;
313
+ let m;
314
+ while ((m = tagRe.exec(html))) {
315
+ const [whole, rawTag, attrs] = m;
316
+ const tag = rawTag.toLowerCase();
317
+ if (whole.startsWith('</')) {
318
+ // Pop to the matching open tag; tolerate stray closes.
319
+ const i = stack.map((t) => t.tag).lastIndexOf(tag);
320
+ if (i >= 0)
321
+ stack.length = i;
322
+ continue;
323
+ }
324
+ const duro = attrs.match(/\bdata-duro\s*=\s*"([^"]*)"|\bdata-duro\s*=\s*'([^']*)'/);
325
+ const spec = duro ? (duro[1] ?? duro[2] ?? '') : null;
326
+ const line = lineOf(source, m.index);
327
+ let annotated = false;
328
+ if (spec !== null) {
329
+ annotatedCount++;
330
+ annotated = true;
331
+ const problem = resolveComponent(registry, spec);
332
+ if (problem) {
333
+ const head = spec.trim().split(/[\s.]/)[0] ?? '';
334
+ const near = suggestions(registry, head).slice(0, 3);
335
+ findings.push({
336
+ file,
337
+ line,
338
+ rule: 'unknown-component',
339
+ message: `data-duro="${spec}": ${problem}${near.length ? ` — did you mean ${near.join(', ')}?` : ''}`,
340
+ });
341
+ }
342
+ }
343
+ const classes = attrs.match(/\bclass\s*=\s*"([^"]*)"|\bclass\s*=\s*'([^']*)'/);
344
+ const classList = (classes?.[1] ?? classes?.[2] ?? '').split(/\s+/).filter(Boolean);
345
+ const inline = attrs.match(/\bstyle\s*=\s*"([^"]*)"|\bstyle\s*=\s*'([^']*)'/);
346
+ const inlineCss = inline?.[1] ?? inline?.[2] ?? '';
347
+ if (inlineCss) {
348
+ const at = m.index + whole.indexOf(inlineCss);
349
+ scanCss(file, source, inlineCss, at, findings);
350
+ }
351
+ // A styled control must name itself: a named parent never covers a child
352
+ // that draws like a control, or naming the list once would excuse every
353
+ // row. The parent covers only a bare native control inside it (the ×
354
+ // button of a Tag, the input of a Combobox).
355
+ const styledControl = /\b(role|tabindex)\s*=/.test(attrs) ||
356
+ /cursor\s*:\s*pointer/.test(inlineCss) ||
357
+ classList.some((c) => controlClasses.has(c));
358
+ const parent = stack[stack.length - 1];
359
+ const unnamed = !annotated && (styledControl || (NATIVE_CONTROLS.has(tag) && !parent?.annotated));
360
+ if (unnamed) {
361
+ findings.push({
362
+ file,
363
+ line,
364
+ rule: 'unannotated-control',
365
+ message: `<${tag}${classList.length ? ` class="${classList.join(' ')}"` : ''}> reads as a control but names no design-system component — add data-duro="<Component>" (duro list components)`,
366
+ });
367
+ }
368
+ const selfClosing = VOID_ELEMENTS.has(tag) || whole.endsWith('/>');
369
+ if (!selfClosing)
370
+ stack.push({ tag, annotated });
371
+ }
372
+ if (annotatedCount === 0) {
373
+ findings.push({
374
+ file,
375
+ line: 1,
376
+ rule: 'no-component-map',
377
+ message: 'no data-duro attribute anywhere — an artboard names the design-system component behind every control, or it cannot be implemented from',
378
+ });
379
+ }
380
+ }
381
+ /** Every finding for one artboard's HTML. Exported for the MCP tool and tests. */
382
+ export function checkArtboard(registry, file, source) {
383
+ const findings = [];
384
+ const masked = maskTokenBlock(source);
385
+ for (const block of masked.matchAll(/<style\b[^>]*>([\s\S]*?)<\/style>/gi)) {
386
+ const at = (block.index ?? 0) + block[0].indexOf(block[1]);
387
+ scanCss(file, source, block[1], at, findings);
388
+ }
389
+ scanMarkup(file, masked, findings, registry);
390
+ findings.sort((a, b) => a.line - b.line || a.rule.localeCompare(b.rule));
391
+ return findings;
392
+ }
393
+ export function runMockupCheck(registry, files, options = {}) {
394
+ if (files.length === 0)
395
+ return usage('duro mockup check: give at least one <file.dc.html>');
396
+ const cwd = options.cwd ?? process.cwd();
397
+ const all = [];
398
+ for (const file of files) {
399
+ let source;
400
+ try {
401
+ source = readFileSync(resolve(cwd, file), 'utf8');
402
+ }
403
+ catch {
404
+ return {
405
+ text: `duro mockup check: cannot read ${file}`,
406
+ data: { kind: 'not-found', file },
407
+ exitCode: 2,
408
+ };
409
+ }
410
+ all.push(...checkArtboard(registry, file, source));
411
+ }
412
+ const lines = all.map((f) => `${f.file}:${f.line} ${f.rule}: ${f.message}`);
413
+ if (all.length === 0) {
414
+ return {
415
+ text: `duro mockup check: ${files.length} artboard(s) speak tokens and name their components`,
416
+ data: { ok: true, files, findings: [] },
417
+ };
418
+ }
419
+ return {
420
+ text: `duro mockup check: ${all.length} finding(s)\n${lines.join('\n')}`,
421
+ data: { ok: false, files, findings: all },
422
+ exitCode: 1,
423
+ };
424
+ }
425
+ const SUBCOMMANDS = ['seed', 'check'];
426
+ export function runMockup(registry, sub, rest, options) {
427
+ if (sub === 'seed') {
428
+ if (rest.length > 0)
429
+ return usage('duro mockup seed takes flags only (--out, --name, --theme)');
430
+ return runMockupSeed(registry, options);
431
+ }
432
+ if (sub === 'check')
433
+ return runMockupCheck(registry, rest, options);
434
+ return usage(`duro mockup: unknown subcommand "${sub ?? ''}" — expected ${SUBCOMMANDS.join(' | ')}`);
435
+ }
436
+ //# sourceMappingURL=mockup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mockup.js","sourceRoot":"","sources":["../../src/commands/mockup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { CommandResult } from './lookup.js';
2
+ export interface SkillOptions {
3
+ /** Report drift and exit 1 instead of writing. For CI. */
4
+ check?: boolean;
5
+ /** Repo root. Defaults to the process cwd. */
6
+ cwd?: string;
7
+ }
8
+ export declare function runSkill(action: string | undefined, options?: SkillOptions): CommandResult;
9
+ //# sourceMappingURL=skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../src/commands/skill.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,aAAa,CAAA;AAY9C,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AA0CD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,GAAE,YAAiB,GAAG,aAAa,CAoE9F"}
@@ -0,0 +1,100 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { SKILL, SKILL_NOTES_PATH, SKILL_PATH } from '../skill-template.js';
5
+ const ACTIONS = ['install'];
6
+ function read(path) {
7
+ try {
8
+ return readFileSync(path, 'utf8');
9
+ }
10
+ catch {
11
+ return null;
12
+ }
13
+ }
14
+ function write(path, content) {
15
+ mkdirSync(dirname(path), { recursive: true });
16
+ writeFileSync(path, content, 'utf8');
17
+ }
18
+ /**
19
+ * Repos that allowlist .claude (".claude/*" plus "!" exceptions) silently
20
+ * ignore the file install just wrote — the skill then works locally and
21
+ * ships to nobody. Best-effort: no git, no warning.
22
+ */
23
+ function ignoredTrackables(root, candidates) {
24
+ try {
25
+ const out = execFileSync('git', ['check-ignore', '--', ...candidates], {
26
+ cwd: root,
27
+ encoding: 'utf8',
28
+ stdio: ['ignore', 'pipe', 'ignore'],
29
+ });
30
+ return out.split('\n').filter(Boolean);
31
+ }
32
+ catch {
33
+ // Exit 1 means nothing matched, which is the happy path.
34
+ return [];
35
+ }
36
+ }
37
+ export function runSkill(action, options = {}) {
38
+ if (action !== 'install') {
39
+ return {
40
+ text: `duro skill: unknown action "${action ?? ''}" — expected ${ACTIONS.join(' | ')}`,
41
+ data: { kind: 'usage-error' },
42
+ exitCode: 2,
43
+ };
44
+ }
45
+ const root = options.cwd ?? process.cwd();
46
+ const changes = [];
47
+ const current = read(join(root, SKILL_PATH));
48
+ if (current === SKILL) {
49
+ changes.push({ path: SKILL_PATH, status: 'unchanged', detail: 'already up to date' });
50
+ }
51
+ else if (options.check) {
52
+ changes.push({
53
+ path: SKILL_PATH,
54
+ status: 'stale',
55
+ detail: current === null ? 'missing' : 'differs',
56
+ });
57
+ }
58
+ else {
59
+ write(join(root, SKILL_PATH), SKILL);
60
+ changes.push({
61
+ path: SKILL_PATH,
62
+ status: 'written',
63
+ detail: current === null ? 'created' : 'regenerated',
64
+ });
65
+ }
66
+ const lines = changes.map((change) => ` ${change.status.padEnd(9)} ${change.path} — ${change.detail}`);
67
+ const stale = changes.filter((change) => change.status === 'stale');
68
+ if (options.check) {
69
+ return stale.length === 0
70
+ ? {
71
+ text: `duro skill install --check: up to date\n${lines.join('\n')}`,
72
+ data: { ok: true, changes },
73
+ }
74
+ : {
75
+ text: `duro skill install --check: ${stale.length} file(s) out of date\n${lines.join('\n')}\nRun: npx -y @duro-app/cli skill install`,
76
+ data: { ok: false, changes },
77
+ exitCode: 1,
78
+ };
79
+ }
80
+ const ignored = ignoredTrackables(root, [SKILL_PATH, SKILL_NOTES_PATH]);
81
+ return {
82
+ text: [
83
+ 'Duro mockup skill installed — invoke it as /duro-mockup.',
84
+ ...lines,
85
+ '',
86
+ `Repo-specific notes: put them in ${SKILL_NOTES_PATH} — the skill reads that file,`,
87
+ 'and regeneration leaves it alone.',
88
+ ...(ignored.length === 0
89
+ ? []
90
+ : [
91
+ '',
92
+ 'WARNING: .gitignore excludes these, so the skill would ship to nobody.',
93
+ 'Add a negation for each:',
94
+ ...ignored.map((path) => ` !${path}`),
95
+ ]),
96
+ ].join('\n'),
97
+ data: { ok: true, changes, ignored },
98
+ };
99
+ }
100
+ //# sourceMappingURL=skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.js","sourceRoot":"","sources":["../../src/commands/skill.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"disambiguation.d.ts","sourceRoot":"","sources":["../src/disambiguation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAA;AAEjD,yDAAyD;AACzD,MAAM,WAAW,WAAW;IAC1B,0EAA0E;IAC1E,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,GAAG,aAAa,GAAG,WAAW,EAAE,CAyBhG"}
1
+ {"version":3,"file":"disambiguation.d.ts","sourceRoot":"","sources":["../src/disambiguation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAA;AAEjD,yDAAyD;AACzD,MAAM,WAAW,WAAW;IAC1B,0EAA0E;IAC1E,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,GAAG,aAAa,GAAG,WAAW,EAAE,CA4BhG"}
@@ -18,8 +18,10 @@ export function relatedPairs(registry, kind) {
18
18
  for (const related of entry.meta?.relatedTo ?? []) {
19
19
  if (related.kind !== kind)
20
20
  continue;
21
- // A pair is only useful if both sides are documented.
22
- if (!(related.component in registry.components) || related.component === name)
21
+ // A pair is only useful if both sides are documented. A recipe counts:
22
+ // "PageShell + page-with-sidenav" is the edge that stops the hand-roll.
23
+ const known = related.component in registry.components || related.component in registry.recipes;
24
+ if (!known || related.component === name)
23
25
  continue;
24
26
  const [a, b] = [name, related.component].sort();
25
27
  const candidate = { a, b, relationship: related.relationship };
@@ -1 +1 @@
1
- {"version":3,"file":"disambiguation.js","sourceRoot":"","sources":["../src/disambiguation.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAAC,QAAkB,EAAE,IAAgC;IAC/E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC7C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAChE,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE,SAAS,IAAI,EAAE,EAAE,CAAC;YAClD,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI;gBAAE,SAAQ;YACnC,sDAAsD;YACtD,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,SAAS,KAAK,IAAI;gBAAE,SAAQ;YACvF,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAA;YAC/C,MAAM,SAAS,GAAgB,EAAC,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAC,CAAA;YACzE,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACpC,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;gBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,CAAA;QAC9F,CAAC;IACH,CAAC;IACD,wEAAwE;IACxE,yEAAyE;IACzE,qEAAqE;IACrE,+DAA+D;IAC/D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC3C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QACxC,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;IACxF,CAAC;IACD,sEAAsE;IACtE,mDAAmD;IACnD,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAC5F,CAAC;AAED;;;;;GAKG;AACH,SAAS,KAAK,CAAC,IAAiB;IAC9B,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACzF,CAAC"}
1
+ {"version":3,"file":"disambiguation.js","sourceRoot":"","sources":["../src/disambiguation.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAAC,QAAkB,EAAE,IAAgC;IAC/E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC7C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAChE,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE,SAAS,IAAI,EAAE,EAAE,CAAC;YAClD,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI;gBAAE,SAAQ;YACnC,uEAAuE;YACvE,wEAAwE;YACxE,MAAM,KAAK,GACT,OAAO,CAAC,SAAS,IAAI,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,SAAS,IAAI,QAAQ,CAAC,OAAO,CAAA;YACnF,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,SAAS,KAAK,IAAI;gBAAE,SAAQ;YAClD,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAA;YAC/C,MAAM,SAAS,GAAgB,EAAC,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAC,CAAA;YACzE,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACpC,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;gBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,CAAA;QAC9F,CAAC;IACH,CAAC;IACD,wEAAwE;IACxE,yEAAyE;IACzE,qEAAqE;IACrE,+DAA+D;IAC/D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC3C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QACxC,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;IACxF,CAAC;IACD,sEAAsE;IACtE,mDAAmD;IACnD,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAC5F,CAAC;AAED;;;;;GAKG;AACH,SAAS,KAAK,CAAC,IAAiB;IAC9B,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACzF,CAAC"}
@@ -19,12 +19,13 @@ export declare const HOOK_NOTES_PATH = ".claude/duro-hook.local.md";
19
19
  /** What settings.json runs. Also the marker install matches on. */
20
20
  export declare const HOOK_COMMAND = "sh .claude/hooks/duro-catalog.sh";
21
21
  /**
22
- * Floor for the npx pin. `hook session-start` landed in 1.2.0; on older
23
- * versions the unknown "hook" positional falls through to lookup/search and
24
- * caches junk. Raise this only when the script needs newer CLI behavior —
25
- * a floating pin keeps patch releases from showing up as --check drift.
22
+ * Floor for the npx pin. Raise this only when the session payload needs
23
+ * newer CLI behavior — a floating pin keeps patch releases from showing up
24
+ * as --check drift, but a floor left behind a major means no consumer ever
25
+ * sees what the payload gained (1.2.0 pinned every repo out of 2.x).
26
+ * 3.0.0: the SCREENS section and the /duro-mockup pointer.
26
27
  */
27
- export declare const HOOK_MIN_CLI = "1.2.0";
28
- export declare const HOOK_SCRIPT = "#!/bin/sh\n# Duro design-system session bootstrap \u2014 GENERATED by `duro hook install`.\n# Regenerate: npx -y @duro-app/cli hook install (--check verifies it in CI)\n#\n# Injects the consult-first preamble plus the component catalog into agent\n# context at SessionStart, so \"check the design system before building UI\" is\n# ambient context instead of a step an agent has to remember.\n#\n# Do not hand-edit. Repo-specific caveats go in\n# .claude/duro-hook.local.md \u2014 appended below, and left alone by regeneration.\ncache=\".claude/.duro-session.cache\"\nnotes=\".claude/duro-hook.local.md\"\n\n# npx resolution dominates session start; the catalog only changes on upgrade.\nif [ ! -s \"$cache\" ] || [ -n \"$(find \"$cache\" -mtime +7 2>/dev/null)\" ]; then\n if npx -y @duro-app/cli@^1.2.0 hook session-start >\"$cache.tmp\" 2>/dev/null; then\n mv \"$cache.tmp\" \"$cache\"\n else\n rm -f \"$cache.tmp\"\n fi\nfi\n\n# Offline with no cache yet: stay silent rather than fail the session.\n[ -s \"$cache\" ] || exit 0\ncat \"$cache\"\n\nif [ -s \"$notes\" ]; then\n echo\n cat \"$notes\"\nfi\n";
28
+ export declare const HOOK_MIN_CLI = "3.0.0";
29
+ export declare const HOOK_SCRIPT = "#!/bin/sh\n# Duro design-system session bootstrap \u2014 GENERATED by `duro hook install`.\n# Regenerate: npx -y @duro-app/cli hook install (--check verifies it in CI)\n#\n# Injects the consult-first preamble plus the component catalog into agent\n# context at SessionStart, so \"check the design system before building UI\" is\n# ambient context instead of a step an agent has to remember.\n#\n# Do not hand-edit. Repo-specific caveats go in\n# .claude/duro-hook.local.md \u2014 appended below, and left alone by regeneration.\ncache=\".claude/.duro-session.cache\"\nnotes=\".claude/duro-hook.local.md\"\n\n# npx resolution dominates session start; the catalog only changes on upgrade.\nif [ ! -s \"$cache\" ] || [ -n \"$(find \"$cache\" -mtime +7 2>/dev/null)\" ]; then\n if npx -y @duro-app/cli@^3.0.0 hook session-start >\"$cache.tmp\" 2>/dev/null; then\n mv \"$cache.tmp\" \"$cache\"\n else\n rm -f \"$cache.tmp\"\n fi\nfi\n\n# Offline with no cache yet: stay silent rather than fail the session.\n[ -s \"$cache\" ] || exit 0\ncat \"$cache\"\n\nif [ -s \"$notes\" ]; then\n echo\n cat \"$notes\"\nfi\n";
29
30
  export declare const GITIGNORE_BLOCK = "# Duro session-hook cache (duro hook install)\n.claude/.duro-session.cache*\n";
30
31
  //# sourceMappingURL=hook-script.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hook-script.d.ts","sourceRoot":"","sources":["../src/hook-script.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,yCAAyC;AACzC,eAAO,MAAM,gBAAgB,kCAAkC,CAAA;AAC/D,eAAO,MAAM,kBAAkB,0BAA0B,CAAA;AACzD,eAAO,MAAM,eAAe,gCAAgC,CAAA;AAC5D;;;GAGG;AACH,eAAO,MAAM,iBAAiB,iCAAwB,CAAA;AACtD,gFAAgF;AAChF,eAAO,MAAM,eAAe,+BAA+B,CAAA;AAE3D,mEAAmE;AACnE,eAAO,MAAM,YAAY,qCAA2B,CAAA;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,YAAY,UAAU,CAAA;AAEnC,eAAO,MAAM,WAAW,omCA8BvB,CAAA;AAED,eAAO,MAAM,eAAe,kFAA0E,CAAA"}
1
+ {"version":3,"file":"hook-script.d.ts","sourceRoot":"","sources":["../src/hook-script.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,yCAAyC;AACzC,eAAO,MAAM,gBAAgB,kCAAkC,CAAA;AAC/D,eAAO,MAAM,kBAAkB,0BAA0B,CAAA;AACzD,eAAO,MAAM,eAAe,gCAAgC,CAAA;AAC5D;;;GAGG;AACH,eAAO,MAAM,iBAAiB,iCAAwB,CAAA;AACtD,gFAAgF;AAChF,eAAO,MAAM,eAAe,+BAA+B,CAAA;AAE3D,mEAAmE;AACnE,eAAO,MAAM,YAAY,qCAA2B,CAAA;AAEpD;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,UAAU,CAAA;AAEnC,eAAO,MAAM,WAAW,omCA8BvB,CAAA;AAED,eAAO,MAAM,eAAe,kFAA0E,CAAA"}