@12ui/design 0.2.44 → 0.2.46

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 (125) hide show
  1. package/README.md +7 -0
  2. package/SKILL.md +1 -1
  3. package/dist/branch-execution-types.d.ts +2 -0
  4. package/dist/branch-execution-types.d.ts.map +1 -1
  5. package/dist/branch-execution.d.ts.map +1 -1
  6. package/dist/branch-execution.js +3 -0
  7. package/dist/branch-execution.js.map +1 -1
  8. package/dist/branch-run-record.d.ts +1 -0
  9. package/dist/branch-run-record.d.ts.map +1 -1
  10. package/dist/branch-run-record.js.map +1 -1
  11. package/dist/cli-arguments.d.ts.map +1 -1
  12. package/dist/cli-arguments.js +1 -0
  13. package/dist/cli-arguments.js.map +1 -1
  14. package/dist/cli-branch-command.d.ts.map +1 -1
  15. package/dist/cli-branch-command.js +33 -2
  16. package/dist/cli-branch-command.js.map +1 -1
  17. package/dist/cli-capabilities.d.ts +1 -0
  18. package/dist/cli-capabilities.d.ts.map +1 -1
  19. package/dist/cli-capabilities.js +1 -0
  20. package/dist/cli-capabilities.js.map +1 -1
  21. package/dist/cli-help/design.d.ts +2 -2
  22. package/dist/cli-help/design.d.ts.map +1 -1
  23. package/dist/cli-help/design.js +2 -0
  24. package/dist/cli-help/design.js.map +1 -1
  25. package/dist/cli-help/index.d.ts +2 -2
  26. package/dist/cli-prototype-command.d.ts.map +1 -1
  27. package/dist/cli-prototype-command.js +14 -1
  28. package/dist/cli-prototype-command.js.map +1 -1
  29. package/dist/cli-usage.d.ts.map +1 -1
  30. package/dist/cli-usage.js +4 -3
  31. package/dist/cli-usage.js.map +1 -1
  32. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  33. package/dist/legacy-skill-catalog.js +7 -0
  34. package/dist/legacy-skill-catalog.js.map +1 -1
  35. package/dist/prototype-poststep.d.ts +1 -0
  36. package/dist/prototype-poststep.d.ts.map +1 -1
  37. package/dist/prototype-poststep.js +5 -0
  38. package/dist/prototype-poststep.js.map +1 -1
  39. package/dist/prototype-process.d.ts +1 -1
  40. package/dist/prototype-process.d.ts.map +1 -1
  41. package/dist/prototype-revision.d.ts +1 -1
  42. package/dist/prototype-revision.js +1 -1
  43. package/dist/prototype-run-record.d.ts +2 -1
  44. package/dist/prototype-run-record.d.ts.map +1 -1
  45. package/dist/prototype-run-record.js +28 -6
  46. package/dist/prototype-run-record.js.map +1 -1
  47. package/dist/prototype-runner.d.ts +26 -0
  48. package/dist/prototype-runner.d.ts.map +1 -1
  49. package/dist/prototype-runner.js +55 -8
  50. package/dist/prototype-runner.js.map +1 -1
  51. package/dist/run-journal.d.ts +15 -0
  52. package/dist/run-journal.d.ts.map +1 -1
  53. package/dist/run-journal.js +9 -0
  54. package/dist/run-journal.js.map +1 -1
  55. package/open-design.json +2 -2
  56. package/package.json +2 -2
  57. package/prototype-kit/polish/ground-probe.mjs +119 -0
  58. package/prototype-kit/polish/harm.mjs +23 -0
  59. package/prototype-kit/polish/measure.mjs +333 -0
  60. package/prototype-kit/polish/overrides.mjs +55 -0
  61. package/prototype-kit/polish/polish.mjs +252 -0
  62. package/prototype-kit/polish/report.mjs +76 -0
  63. package/prototype-kit/polish/rules/align.mjs +70 -0
  64. package/prototype-kit/polish/rules/contrast.mjs +80 -0
  65. package/prototype-kit/polish/rules/escape.mjs +192 -0
  66. package/prototype-kit/polish/rules/fit-text.mjs +158 -0
  67. package/prototype-kit/polish/rules/index.mjs +61 -0
  68. package/prototype-kit/polish/rules/left-rail.mjs +77 -0
  69. package/prototype-kit/polish/rules/overlap.mjs +122 -0
  70. package/prototype-kit/polish/rules/page-cut.mjs +203 -0
  71. package/prototype-kit/polish/rules/photo-corners.mjs +38 -0
  72. package/prototype-kit/polish/rules/rhythm.mjs +148 -0
  73. package/prototype-kit/polish/rules/section-breathing.mjs +292 -0
  74. package/prototype-kit/polish/rules/shell-seam.mjs +48 -0
  75. package/prototype-kit/polish/tests/breathing-check.mjs +77 -0
  76. package/prototype-kit/polish/tests/fixtures/align/expect.json +1 -0
  77. package/prototype-kit/polish/tests/fixtures/align/fire.html +14 -0
  78. package/prototype-kit/polish/tests/fixtures/align/silent.html +28 -0
  79. package/prototype-kit/polish/tests/fixtures/contrast/expect.json +1 -0
  80. package/prototype-kit/polish/tests/fixtures/contrast/fallback.html +7 -0
  81. package/prototype-kit/polish/tests/fixtures/contrast/fire.html +9 -0
  82. package/prototype-kit/polish/tests/fixtures/contrast/silent.html +9 -0
  83. package/prototype-kit/polish/tests/fixtures/escape/expect.json +2 -0
  84. package/prototype-kit/polish/tests/fixtures/escape/fire.html +23 -0
  85. package/prototype-kit/polish/tests/fixtures/escape/silent.html +29 -0
  86. package/prototype-kit/polish/tests/fixtures/fit-text/expect.json +3 -0
  87. package/prototype-kit/polish/tests/fixtures/fit-text/fire.html +26 -0
  88. package/prototype-kit/polish/tests/fixtures/fit-text/silent.html +33 -0
  89. package/prototype-kit/polish/tests/fixtures/harm/button-overlap.html +10 -0
  90. package/prototype-kit/polish/tests/fixtures/harm/declared-gap.html +5 -0
  91. package/prototype-kit/polish/tests/fixtures/harm/offcenter.html +21 -0
  92. package/prototype-kit/polish/tests/fixtures/harm/page.html +17 -0
  93. package/prototype-kit/polish/tests/fixtures/left-rail/expect.json +1 -0
  94. package/prototype-kit/polish/tests/fixtures/left-rail/fire.html +8 -0
  95. package/prototype-kit/polish/tests/fixtures/left-rail/silent.html +8 -0
  96. package/prototype-kit/polish/tests/fixtures/overlap/expect.json +4 -0
  97. package/prototype-kit/polish/tests/fixtures/overlap/fire.html +26 -0
  98. package/prototype-kit/polish/tests/fixtures/overlap/silent.html +39 -0
  99. package/prototype-kit/polish/tests/fixtures/page-cut/expect.json +2 -0
  100. package/prototype-kit/polish/tests/fixtures/page-cut/fire.html +31 -0
  101. package/prototype-kit/polish/tests/fixtures/page-cut/silent.html +22 -0
  102. package/prototype-kit/polish/tests/fixtures/photo-corners/expect.json +1 -0
  103. package/prototype-kit/polish/tests/fixtures/photo-corners/fire.html +5 -0
  104. package/prototype-kit/polish/tests/fixtures/photo-corners/silent.html +9 -0
  105. package/prototype-kit/polish/tests/fixtures/rhythm/expect.json +6 -0
  106. package/prototype-kit/polish/tests/fixtures/rhythm/fire.html +22 -0
  107. package/prototype-kit/polish/tests/fixtures/rhythm/silent.html +27 -0
  108. package/prototype-kit/polish/tests/fixtures/section-breathing/attachment-fire.html +5 -0
  109. package/prototype-kit/polish/tests/fixtures/section-breathing/attachment-silent.html +5 -0
  110. package/prototype-kit/polish/tests/fixtures/section-breathing/expect.json +1 -0
  111. package/prototype-kit/polish/tests/fixtures/section-breathing/fire.html +6 -0
  112. package/prototype-kit/polish/tests/fixtures/section-breathing/floor.html +7 -0
  113. package/prototype-kit/polish/tests/fixtures/section-breathing/semantic-fire.html +11 -0
  114. package/prototype-kit/polish/tests/fixtures/section-breathing/semantic-silent.html +8 -0
  115. package/prototype-kit/polish/tests/fixtures/section-breathing/shadow-fire.html +5 -0
  116. package/prototype-kit/polish/tests/fixtures/section-breathing/shadow-silent.html +5 -0
  117. package/prototype-kit/polish/tests/fixtures/section-breathing/silent.html +6 -0
  118. package/prototype-kit/polish/tests/fixtures/section-breathing/tight.html +7 -0
  119. package/prototype-kit/polish/tests/fixtures/shell-seam/expect.json +1 -0
  120. package/prototype-kit/polish/tests/fixtures/shell-seam/fire.html +20 -0
  121. package/prototype-kit/polish/tests/fixtures/shell-seam/silent.html +21 -0
  122. package/prototype-kit/polish/tests/harm-check.mjs +71 -0
  123. package/prototype-kit/polish/tests/report-check.mjs +31 -0
  124. package/prototype-kit/polish/tests/rules-check.mjs +52 -0
  125. package/skills/12ui-design/SKILL.md +4 -0
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ import assert from 'node:assert/strict';
3
+
4
+ import { pageRuleRecords, summarizePolishReport } from '../report.mjs';
5
+
6
+ const page = {
7
+ rules: {
8
+ align: { proposed: 2, overCap: 0 },
9
+ contrast: { proposed: 0, overCap: 0 },
10
+ rhythm: { proposed: 1, overCap: 1 },
11
+ },
12
+ accepted: [{ rule: 'align', overrides: 2 }],
13
+ rejected: [{ rule: 'rhythm', harm: ['spacing'] }],
14
+ };
15
+ page.ruleRecords = pageRuleRecords(page, ['align', 'contrast', 'rhythm']);
16
+ assert.deepEqual(page.ruleRecords.map(({ rule, status }) => ({ rule, status })), [
17
+ { rule: 'align', status: 'fired' },
18
+ { rule: 'contrast', status: 'silent' },
19
+ { rule: 'rhythm', status: 'reverted' },
20
+ ]);
21
+
22
+ const summary = summarizePolishReport({
23
+ policy: 'retained-v1',
24
+ rules: ['align', 'contrast', 'rhythm'],
25
+ pages: [page],
26
+ });
27
+ assert.equal(summary.fired, 1);
28
+ assert.equal(summary.silent, 1);
29
+ assert.equal(summary.reverted, 1);
30
+ assert.equal(summary.rules.find(({ name }) => name === 'rhythm').overCap, 1);
31
+ console.log('polish report outcomes green');
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+ // Paired cases for every polish rule: fixtures/<rule>/fire.html must produce ≥1 override,
3
+ // fixtures/<rule>/silent.html must produce 0. Optional fixtures/<rule>/expect.json pins exact ids/deltas.
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import { chromium } from '@playwright/test';
7
+ import { measurePage } from '../measure.mjs';
8
+ import { loadRules, ALL } from '../rules/index.mjs';
9
+ import { applyOverridesScript, overridesToCss, mergeOverrides } from '../overrides.mjs';
10
+
11
+ const here = path.dirname(new URL(import.meta.url).pathname);
12
+ const only = process.argv[2] ? process.argv[2].split(',') : ALL;
13
+ const rules = await loadRules(only);
14
+ const browser = await chromium.launch();
15
+ const page = await browser.newPage({ viewport: { width: 1536, height: 1024 } });
16
+ let failures = 0;
17
+ const near = (a, b, tol = 0.6) => Math.abs(a - b) <= tol;
18
+ for (const rule of rules) {
19
+ const dir = path.join(here, 'fixtures', rule.name);
20
+ for (const kind of ['fire', 'silent']) {
21
+ const file = path.join(dir, `${kind}.html`);
22
+ if (!fs.existsSync(file)) { console.log(`FAIL ${rule.name}/${kind}: fixture missing`); failures++; continue; }
23
+ await page.goto('file://' + file, { waitUntil: 'load' });
24
+ await page.evaluate(() => document.fonts.ready);
25
+ const before = await measurePage(page, {});
26
+ const found = await page.evaluate(rule.browserFn(), { metrics: before, params: rule.params || {} });
27
+ const ok = kind === 'fire' ? found.length > 0 : found.length === 0;
28
+ let detail = `${found.length} override(s)`;
29
+ let harm = false;
30
+ if (kind === 'fire' && found.length) {
31
+ const merged = mergeOverrides(found);
32
+ await page.evaluate(applyOverridesScript(), overridesToCss(merged));
33
+ const after = await measurePage(page, {});
34
+ harm = after.counts.overlap > before.counts.overlap || after.overflow.filter((o) => o.kind !== 'spill').length > before.overflow.filter((o) => o.kind !== 'spill').length;
35
+ detail += `; overlap ${before.counts.overlap}→${after.counts.overlap}, overflow ${before.counts.overflow}→${after.counts.overflow}, align ${before.counts.alignment}→${after.counts.alignment}, ws ${before.counts.whitespace}→${after.counts.whitespace}`;
36
+ const expectFile = path.join(dir, 'expect.json');
37
+ if (fs.existsSync(expectFile)) {
38
+ const expect = JSON.parse(fs.readFileSync(expectFile, 'utf8'));
39
+ for (const e of expect) {
40
+ const m = merged.find((o) => o.id === e.id);
41
+ const good = m && (e.dx == null || near(m.dx, e.dx)) && (e.dy == null || near(m.dy, e.dy)) && (e.w == null || near(m.w, e.w, 1)) && (e.h == null || near(m.h, e.h, 1)) && (!e.css || Object.entries(e.css).every(([k, v]) => m.css[k] === v));
42
+ if (!good) { detail += `; expected ${JSON.stringify(e)} got ${JSON.stringify(m || null)}`; failures++; }
43
+ }
44
+ }
45
+ }
46
+ if (!ok || harm) failures++;
47
+ console.log(`${ok && !harm ? 'ok ' : 'FAIL'} ${rule.name}/${kind}: ${detail}${harm ? ' HARM' : ''}`);
48
+ }
49
+ }
50
+ await browser.close();
51
+ if (failures) { console.log(`${failures} failure(s)`); process.exit(1); }
52
+ console.log('all polish rule pairs green');
@@ -39,10 +39,14 @@ Execute stays in the foreground through its network work; `next` can report prog
39
39
 
40
40
  Use `--prototype` with `--convert html` when the deliverable should be clickable. The export becomes a working app — navigation, shared shells, and holding pages for unbuilt routes — written to `<run-dir>/branch/prototype/`.
41
41
 
42
+ Add `--polish` only when the user wants the opt-in production-feel pass. It runs the retained deterministic, harm-guarded rules after build, records every rule as fired, silent, or reverted, and runs the prototype runtime gates on that polished output.
43
+
42
44
  For a completed branch that was exported without the flag, run:
43
45
 
44
46
  12ui prototype <run-dir>
45
47
 
48
+ The same opt-in is available here as `12ui prototype <run-dir> --polish`.
49
+
46
50
  ## 3. Convert
47
51
 
48
52
  When you have a single image to convert (or for example only designing a single viewport), you can directly convert the image instead of branching it.