@12ui/design 0.2.28 → 0.2.30

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 (184) hide show
  1. package/README.md +97 -3
  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 +2 -0
  13. package/dist/cli-arguments.js.map +1 -1
  14. package/dist/cli-branch-command.d.ts +4 -0
  15. package/dist/cli-branch-command.d.ts.map +1 -1
  16. package/dist/cli-branch-command.js +30 -3
  17. package/dist/cli-branch-command.js.map +1 -1
  18. package/dist/cli-capabilities.d.ts +15 -0
  19. package/dist/cli-capabilities.d.ts.map +1 -1
  20. package/dist/cli-capabilities.js +19 -0
  21. package/dist/cli-capabilities.js.map +1 -1
  22. package/dist/cli-help/design.d.ts +18 -1
  23. package/dist/cli-help/design.d.ts.map +1 -1
  24. package/dist/cli-help/design.js +33 -0
  25. package/dist/cli-help/design.js.map +1 -1
  26. package/dist/cli-help/index.d.ts +18 -1
  27. package/dist/cli-help/index.d.ts.map +1 -1
  28. package/dist/cli-prototype-command.d.ts +12 -0
  29. package/dist/cli-prototype-command.d.ts.map +1 -0
  30. package/dist/cli-prototype-command.js +29 -0
  31. package/dist/cli-prototype-command.js.map +1 -0
  32. package/dist/cli-review-command.d.ts +8 -0
  33. package/dist/cli-review-command.d.ts.map +1 -0
  34. package/dist/cli-review-command.js +90 -0
  35. package/dist/cli-review-command.js.map +1 -0
  36. package/dist/cli-run.d.ts.map +1 -1
  37. package/dist/cli-run.js +16 -0
  38. package/dist/cli-run.js.map +1 -1
  39. package/dist/cli-usage.d.ts.map +1 -1
  40. package/dist/cli-usage.js +8 -1
  41. package/dist/cli-usage.js.map +1 -1
  42. package/dist/conversion-client.d.ts.map +1 -1
  43. package/dist/conversion-client.js +8 -1
  44. package/dist/conversion-client.js.map +1 -1
  45. package/dist/index.d.ts +4 -0
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +4 -0
  48. package/dist/index.js.map +1 -1
  49. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  50. package/dist/legacy-skill-catalog.js +8 -0
  51. package/dist/legacy-skill-catalog.js.map +1 -1
  52. package/dist/next-wait-lease.d.ts +2 -1
  53. package/dist/next-wait-lease.d.ts.map +1 -1
  54. package/dist/next-wait-lease.js +73 -22
  55. package/dist/next-wait-lease.js.map +1 -1
  56. package/dist/next-wait-process.d.ts +17 -0
  57. package/dist/next-wait-process.d.ts.map +1 -0
  58. package/dist/next-wait-process.js +40 -0
  59. package/dist/next-wait-process.js.map +1 -0
  60. package/dist/prototype-gap-html.d.ts +10 -0
  61. package/dist/prototype-gap-html.d.ts.map +1 -0
  62. package/dist/prototype-gap-html.js +55 -0
  63. package/dist/prototype-gap-html.js.map +1 -0
  64. package/dist/prototype-gap-source.d.ts +14 -0
  65. package/dist/prototype-gap-source.d.ts.map +1 -0
  66. package/dist/prototype-gap-source.js +87 -0
  67. package/dist/prototype-gap-source.js.map +1 -0
  68. package/dist/prototype-gates.d.ts +24 -0
  69. package/dist/prototype-gates.d.ts.map +1 -0
  70. package/dist/prototype-gates.js +76 -0
  71. package/dist/prototype-gates.js.map +1 -0
  72. package/dist/prototype-label-client.d.ts +51 -0
  73. package/dist/prototype-label-client.d.ts.map +1 -0
  74. package/dist/prototype-label-client.js +53 -0
  75. package/dist/prototype-label-client.js.map +1 -0
  76. package/dist/prototype-label-score.d.ts +26 -0
  77. package/dist/prototype-label-score.d.ts.map +1 -0
  78. package/dist/prototype-label-score.js +51 -0
  79. package/dist/prototype-label-score.js.map +1 -0
  80. package/dist/prototype-process.d.ts +13 -0
  81. package/dist/prototype-process.d.ts.map +1 -0
  82. package/dist/prototype-process.js +26 -0
  83. package/dist/prototype-process.js.map +1 -0
  84. package/dist/prototype-requests.d.ts +29 -0
  85. package/dist/prototype-requests.d.ts.map +1 -0
  86. package/dist/prototype-requests.js +34 -0
  87. package/dist/prototype-requests.js.map +1 -0
  88. package/dist/prototype-runner.d.ts +22 -0
  89. package/dist/prototype-runner.d.ts.map +1 -0
  90. package/dist/prototype-runner.js +159 -0
  91. package/dist/prototype-runner.js.map +1 -0
  92. package/dist/prototype-source.d.ts +9 -0
  93. package/dist/prototype-source.d.ts.map +1 -0
  94. package/dist/prototype-source.js +48 -0
  95. package/dist/prototype-source.js.map +1 -0
  96. package/dist/review-discovery.d.ts +11 -0
  97. package/dist/review-discovery.d.ts.map +1 -0
  98. package/dist/review-discovery.js +427 -0
  99. package/dist/review-discovery.js.map +1 -0
  100. package/dist/review-edit-html.d.ts +6 -0
  101. package/dist/review-edit-html.d.ts.map +1 -0
  102. package/dist/review-edit-html.js +11 -0
  103. package/dist/review-edit-html.js.map +1 -0
  104. package/dist/review-edit-source.d.ts +22 -0
  105. package/dist/review-edit-source.d.ts.map +1 -0
  106. package/dist/review-edit-source.js +103 -0
  107. package/dist/review-edit-source.js.map +1 -0
  108. package/dist/review-edit.d.ts +15 -0
  109. package/dist/review-edit.d.ts.map +1 -0
  110. package/dist/review-edit.js +192 -0
  111. package/dist/review-edit.js.map +1 -0
  112. package/dist/review-layerdoc-diff.d.ts +7 -0
  113. package/dist/review-layerdoc-diff.d.ts.map +1 -0
  114. package/dist/review-layerdoc-diff.js +92 -0
  115. package/dist/review-layerdoc-diff.js.map +1 -0
  116. package/dist/review-page-assets.d.ts +3 -0
  117. package/dist/review-page-assets.d.ts.map +1 -0
  118. package/dist/review-page-assets.js +62 -0
  119. package/dist/review-page-assets.js.map +1 -0
  120. package/dist/review-page.d.ts +3 -0
  121. package/dist/review-page.d.ts.map +1 -0
  122. package/dist/review-page.js +275 -0
  123. package/dist/review-page.js.map +1 -0
  124. package/dist/review-pricing.d.ts +14 -0
  125. package/dist/review-pricing.d.ts.map +1 -0
  126. package/dist/review-pricing.js +23 -0
  127. package/dist/review-pricing.js.map +1 -0
  128. package/dist/review-prototype-gap.d.ts +48 -0
  129. package/dist/review-prototype-gap.d.ts.map +1 -0
  130. package/dist/review-prototype-gap.js +192 -0
  131. package/dist/review-prototype-gap.js.map +1 -0
  132. package/dist/review-server.d.ts +22 -0
  133. package/dist/review-server.d.ts.map +1 -0
  134. package/dist/review-server.js +268 -0
  135. package/dist/review-server.js.map +1 -0
  136. package/dist/review-store.d.ts +11 -0
  137. package/dist/review-store.d.ts.map +1 -0
  138. package/dist/review-store.js +96 -0
  139. package/dist/review-store.js.map +1 -0
  140. package/dist/review-types.d.ts +140 -0
  141. package/dist/review-types.d.ts.map +1 -0
  142. package/dist/review-types.js +2 -0
  143. package/dist/review-types.js.map +1 -0
  144. package/dist/run-journal-commands.d.ts.map +1 -1
  145. package/dist/run-journal-commands.js +19 -0
  146. package/dist/run-journal-commands.js.map +1 -1
  147. package/open-design.json +2 -2
  148. package/package.json +7 -1
  149. package/prototype-kit/analyze.mjs +275 -0
  150. package/prototype-kit/build.mjs +393 -0
  151. package/prototype-kit/inventory.mjs +104 -0
  152. package/prototype-kit/label-briefs.mjs +47 -0
  153. package/prototype-kit/lib/actions.mjs +15 -0
  154. package/prototype-kit/lib/navigation.mjs +33 -0
  155. package/prototype-kit/lib/runtime-check.mjs +126 -0
  156. package/prototype-kit/lib/shells.mjs +68 -0
  157. package/prototype-kit/lib/static-server.mjs +40 -0
  158. package/prototype-kit/lib/text.mjs +20 -0
  159. package/prototype-kit/runtime/proto.css +46 -0
  160. package/prototype-kit/runtime/proto.js +173 -0
  161. package/prototype-kit/score-labels.mjs +42 -0
  162. package/prototype-kit/tests/README.md +28 -0
  163. package/prototype-kit/tests/adversarial-runtime.mjs +90 -0
  164. package/prototype-kit/tests/discover-runs.mjs +29 -0
  165. package/prototype-kit/tests/fixtures/no-semantic/branch.plan.json +7 -0
  166. package/prototype-kit/tests/fixtures/no-semantic/pages/legacy.html +1 -0
  167. package/prototype-kit/tests/fixtures/partial-plan/branch.plan.json +5 -0
  168. package/prototype-kit/tests/fixtures/partial-plan/pages/orphan.html +4 -0
  169. package/prototype-kit/tests/fixtures/runtime/double.html +5 -0
  170. package/prototype-kit/tests/fixtures/runtime/history-destination.html +1 -0
  171. package/prototype-kit/tests/fixtures/runtime/history.html +6 -0
  172. package/prototype-kit/tests/fixtures/runtime/hover-stack.html +15 -0
  173. package/prototype-kit/tests/fixtures/runtime/invalid-dropdown.html +6 -0
  174. package/prototype-kit/tests/fixtures/runtime/nested.html +7 -0
  175. package/prototype-kit/tests/fixtures/three-shell/branch.plan.json +30 -0
  176. package/prototype-kit/tests/fixtures/three-shell/pages/p0-home.html +11 -0
  177. package/prototype-kit/tests/fixtures/three-shell/pages/p1-reports.html +11 -0
  178. package/prototype-kit/tests/lib/run-discovery.mjs +87 -0
  179. package/prototype-kit/tests/lib/run-process.mjs +49 -0
  180. package/prototype-kit/tests/offline-check.mjs +41 -0
  181. package/prototype-kit/tests/population-sweep.mjs +94 -0
  182. package/prototype-kit/tests/rules-check.mjs +50 -0
  183. package/prototype-kit/verify-runtime.mjs +36 -0
  184. package/skills/12ui-design/SKILL.md +8 -2
@@ -1 +1 @@
1
- {"version":3,"file":"run-journal-commands.js","sourceRoot":"","sources":["../src/run-journal-commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-journal-commands.js","sourceRoot":"","sources":["../src/run-journal-commands.ts"],"names":[],"mappings":"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"}
package/open-design.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "specVersion": "1.0.0",
4
4
  "name": "12ui-design",
5
5
  "title": "12UI Design",
6
- "version": "0.2.28",
6
+ "version": "0.2.30",
7
7
  "description": "Explore corpus-grounded interface directions, choose one, and convert it into production-ready responsive or native artifacts with 12UI.",
8
8
  "author": {
9
9
  "name": "Just Every",
@@ -49,7 +49,7 @@
49
49
  "command": "npx",
50
50
  "args": [
51
51
  "-y",
52
- "@12ui/design@0.2.28",
52
+ "@12ui/design@0.2.30",
53
53
  "mcp"
54
54
  ]
55
55
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@12ui/design",
3
- "version": "0.2.28",
3
+ "version": "0.2.30",
4
4
  "type": "module",
5
5
  "description": "The canonical 12ui CLI, SDK, MCP server, and visual interface design skills",
6
6
  "main": "dist/index.js",
@@ -10,6 +10,7 @@
10
10
  },
11
11
  "files": [
12
12
  "dist/**/*",
13
+ "prototype-kit/**/*",
13
14
  "skills/**/*",
14
15
  "SKILL.md",
15
16
  "open-design.json",
@@ -22,14 +23,19 @@
22
23
  "start": "node dist/cli.js",
23
24
  "test": "vitest",
24
25
  "test:run": "vitest run",
26
+ "test:prototype": "node prototype-kit/tests/rules-check.mjs && node prototype-kit/tests/offline-check.mjs && node prototype-kit/tests/adversarial-runtime.mjs --assert",
25
27
  "typecheck": "tsc --noEmit && tsc -p tsconfig.type-tests.json",
26
28
  "prepublishOnly": "npm run build"
27
29
  },
28
30
  "dependencies": {
29
31
  "@just-every/ensemble": "0.2.274",
30
32
  "@modelcontextprotocol/sdk": "^1.29.0",
33
+ "linkedom": "^0.18.12",
31
34
  "sharp": "^0.35.3"
32
35
  },
36
+ "peerDependencies": {
37
+ "@playwright/test": "1.59.1"
38
+ },
33
39
  "devDependencies": {
34
40
  "@types/node": "^22.19.17",
35
41
  "typescript": "^5.9.3",
@@ -0,0 +1,275 @@
1
+ // Deterministic analysis of an inventory: states, shared shell, nav items, dropdowns, rows, buttons, link-like texts.
2
+ // Usage: node analyze.mjs <inventory.json> <model.json>
3
+ import fs from 'node:fs';
4
+ import { matchPlannedPage } from './lib/navigation.mjs';
5
+ import { compareCanonicalShells, isWithinShell, qualifiesShellCandidate, selectOneShellPerRegion } from './lib/shells.mjs';
6
+ import { normalizeText as norm, slugText as slug } from './lib/text.mjs';
7
+
8
+ const [invFile, outFile] = process.argv.slice(2);
9
+ const inv = JSON.parse(fs.readFileSync(invFile, 'utf8'));
10
+ const W = 1536, H = 1024;
11
+ const planScreens = Array.isArray(inv.plan?.screens) ? inv.plan.screens : [];
12
+ const chevronDown = (l) => /\b(down|caret down|chevron down|expand)\b/.test(norm(l)) && /chevron|caret|arrow|down/.test(norm(l));
13
+ const chevronRight = (l) => /right/.test(norm(l)) && /chevron|arrow|caret/.test(norm(l));
14
+ const linkVerb = /^(view|open|see|manage|clear|add|run|export|download|learn|read|sign|get|start|try|book|browse|explore|edit|approve|defer|review|show|load|invite|create|upgrade|contact|subscribe|join|buy|shop|reserve|rsvp|register|continue|back|cancel|save|send|submit|apply|filter|sort|search|show)\b/;
15
+
16
+ // ---- states
17
+ const states = [];
18
+ for (const p of inv.pages) {
19
+ p.sections.forEach((s, i) => {
20
+ const slotMatch = s.sectionId.match(/^viewport-(\d+)-(\w+)$/);
21
+ const slot = slotMatch ? slotMatch[2] : String(i);
22
+ const screen = planScreens.find((x) => x.slot === slot);
23
+ const ordinal = i + 1;
24
+ const base = p.pageId.replace(/^p\d+-/, '');
25
+ states.push({
26
+ stateId: ordinal === 1 ? base : `${base}-${ordinal}`,
27
+ pageId: p.pageId,
28
+ pageIndex: p.planPage?.index ?? null,
29
+ file: p.file,
30
+ sectionId: s.sectionId,
31
+ slot,
32
+ ordinal,
33
+ title: p.planPage?.title || base.replace(/-/g, ' ').replace(/\b\p{L}/gu, (letter) => letter.toUpperCase()),
34
+ purpose: p.planPage?.purpose || '',
35
+ surfaceType: p.planPage?.surfaceType || '',
36
+ direction: screen?.direction || '',
37
+ content: screen?.content || '',
38
+ dependsOnSlot: screen?.dependsOnSlot || null,
39
+ isSource: !!p.planPage?.startsFromWinner && ordinal === 1,
40
+ items: s.items,
41
+ containers: s.containers,
42
+ height: s.height,
43
+ scriptDirection: s.scriptDirection,
44
+ writingMode: s.writingMode,
45
+ });
46
+ });
47
+ }
48
+ if (!states.length) throw new Error('Prototype input error: no semantic viewport sections found; exports require section ids shaped like viewport-<ordinal>-<slot>');
49
+ const byId = Object.fromEntries(states.map((s) => [s.stateId, s]));
50
+ const slotToState = Object.fromEntries(states.map((s) => [s.slot, s.stateId]));
51
+
52
+ // ---- shell: elements repeated (same text/label, bbox within tol) across >= 60% of states
53
+ const key = (it) => (it.text ? 't:' + norm(it.text) : it.label ? 'l:' + norm(it.label) : null);
54
+ const TOL = 40;
55
+ const minStates = Math.max(2, Math.ceil(states.length * 0.4));
56
+ function repeatedKeys() {
57
+ const map = new Map();
58
+ for (const s of states) {
59
+ const seen = new Set();
60
+ for (const it of s.items) {
61
+ const k = key(it); if (!k || seen.has(k)) continue;
62
+ seen.add(k);
63
+ (map.get(k) || map.set(k, []).get(k)).push({ state: s.stateId, x: it.x, y: it.y, yb: s.height - it.y, w: it.w, h: it.h, id: it.id });
64
+ }
65
+ }
66
+ const rep = new Map();
67
+ for (const [k, occ] of map) {
68
+ if (occ.length < minStates) continue;
69
+ // cluster by position: count occurrences within TOL of the median
70
+ const mx = median(occ.map((o) => o.x)), my = median(occ.map((o) => o.y)), myb = median(occ.map((o) => o.yb));
71
+ const near = occ.filter((o) => Math.abs(o.x - mx) <= TOL && (Math.abs(o.y - my) <= TOL || Math.abs(o.yb - myb) <= TOL));
72
+ if (near.length >= minStates) rep.set(k, { x: mx, y: my, occ: near });
73
+ }
74
+ return rep;
75
+ }
76
+ function median(a) { const b = [...a].sort((x, y) => x - y); return b[Math.floor(b.length / 2)]; }
77
+ const repeated = repeatedKeys();
78
+
79
+ // top-level containers per state and their shell share
80
+ function topContainers(s) {
81
+ const pre = s.sectionId + '-';
82
+ return s.containers.filter((c) => c.id.startsWith(pre) && !c.id.slice(pre.length).includes('-') && c.children > 0);
83
+ }
84
+ function regionOf(c) {
85
+ if (c.w <= 0.3 * W && c.h >= 0.7 * H && c.x <= 0.05 * W) return 'sidebar';
86
+ if (c.w >= 0.15 * W && c.h <= 0.2 * H && c.y <= 0.08 * H) return 'header';
87
+ if (c.w >= 0.6 * W && c.h <= 0.45 * H && c.y + c.h >= 0.9 * H) return 'footer';
88
+ return null;
89
+ }
90
+ const rejectedShellsByState = new Map();
91
+ for (const s of states) {
92
+ s.shell = [];
93
+ const rejected = [];
94
+ for (const c of topContainers(s)) {
95
+ const inside = s.items.filter((it) => it.chain.includes(c.id) || it.id === c.id);
96
+ if (inside.length < 2) continue;
97
+ const shellCount = inside.filter((it) => { const k = key(it); return k && repeated.has(k) && repeated.get(k).occ.some((o) => o.state === s.stateId); }).length;
98
+ const share = shellCount / inside.length;
99
+ const region = regionOf(c);
100
+ const semantic = ['aside', 'header', 'footer', 'nav'].includes(c.tag) || /-(sidebar|nav|navbar|header|footer|topbar|sidenav)$/.test(c.id);
101
+ const shell = { containerId: c.id, region, share: +share.toFixed(2), semantic, items: inside.length, box: [c.x, c.y, c.w, c.h] };
102
+ const hasShellEvidence = region && (share >= 0.5 || (semantic && region === 'sidebar' && inside.length >= 3));
103
+ if (!hasShellEvidence) continue;
104
+ if (qualifiesShellCandidate(shell, W)) s.shell.push(shell);
105
+ else rejected.push(shell);
106
+ }
107
+ rejectedShellsByState.set(s.stateId, rejected);
108
+ }
109
+ const shellAmbiguities = [];
110
+ for (const state of states) {
111
+ const { selected, dropped } = selectOneShellPerRegion(state.shell);
112
+ state.shell = selected;
113
+ for (const shell of [...dropped, ...(rejectedShellsByState.get(state.stateId) || [])]) {
114
+ const kept = selected.find((candidate) => candidate.region === shell.region);
115
+ if (!kept) continue;
116
+ shellAmbiguities.push({
117
+ state: state.stateId,
118
+ region: shell.region,
119
+ dropped: shell.containerId,
120
+ droppedBox: shell.box,
121
+ kept: kept?.containerId || null,
122
+ keptBox: kept?.box || null,
123
+ });
124
+ }
125
+ }
126
+ // canonical shell per region: prefer the source state, else the state whose container has the highest share*items
127
+ let regions = [...new Set(states.flatMap((s) => s.shell.map((x) => x.region)))];
128
+ const canonical = {};
129
+ // how many short texts inside a container match a planned page title (used to rank competing shells)
130
+ function pageMatches(s, cid) {
131
+ return s.items.filter((it) => it.text && it.text.length <= 32 && it.chain.includes(cid)).map((it) => matchPage(it.text)).filter(Boolean).length;
132
+ }
133
+ for (const r of regions) {
134
+ const cands = states.flatMap((s) => s.shell.filter((x) => x.region === r).map((x) => ({ ...x, stateId: s.stateId, isSource: s.isSource, matches: pageMatches(s, x.containerId) })));
135
+ if (cands.length < 2) { for (const s of states) s.shell = s.shell.filter((x) => x.region !== r); continue; }
136
+ cands.sort(compareCanonicalShells);
137
+ canonical[r] = { stateId: cands[0].stateId, containerId: cands[0].containerId, box: cands[0].box, presentIn: cands.map((c) => c.stateId), ranking: cands.map((c) => `${c.stateId}:${c.matches}m/${c.items}i/${c.share}`) };
138
+ }
139
+ regions = Object.keys(canonical);
140
+
141
+ // ---- nav items: texts inside a canonical shell container that repeat, font >= 12, excluding long copy
142
+ const nav = [];
143
+ for (const r of regions) {
144
+ const can = canonical[r]; const s = byId[can.stateId];
145
+ const texts = s.items.filter((it) => it.text && it.chain.includes(can.containerId) && it.fontSize >= 12 && it.text.length <= 32 && !it.inButton && !/\d/.test(it.text));
146
+ // a nav list = >= 3 texts sharing the same x (vertical list) or same y (horizontal list)
147
+ const groups = new Map();
148
+ for (const t of texts) {
149
+ const gx = 'x' + Math.round(t.x / 6), gy = 'y' + Math.round(t.y / 6);
150
+ (groups.get(gx) || groups.set(gx, []).get(gx)).push(t);
151
+ (groups.get(gy) || groups.set(gy, []).get(gy)).push(t);
152
+ }
153
+ const best = [...groups.values()].sort((a, b) => b.length - a.length)[0] || [];
154
+ if (best.length >= 3) for (const t of best) nav.push({ region: r, id: t.id, text: t.text, x: t.x, y: t.y, w: t.w, h: t.h, fontSize: t.fontSize, color: t.color, fontWeight: t.fontWeight });
155
+ }
156
+ // match nav text -> page (first state of that page) by token overlap with title / pageId
157
+ function matchPage(text) {
158
+ return matchPlannedPage(text, states.filter((state) => state.ordinal === 1))?.stateId || null;
159
+ }
160
+ for (const n of nav) { n.target = matchPage(n.text); }
161
+ { const first = nav.find((n) => n.region !== 'footer'); const home = states.find((s) => s.isSource) || states[0];
162
+ if (first && !first.target && /^(home|overview|dashboard|start)$/.test(norm(first.text))) { first.target = home.stateId; first.fallback = 'home'; } }
163
+ for (const n of nav) n.holding = n.target ? null : 'holding-' + slug(n.text);
164
+
165
+ // ---- per-state interactive candidates
166
+ function smallestCommon(s, ids) {
167
+ const chains = ids.map((id) => { const it = s.items.find((x) => x.id === id); return it ? [it.id, ...it.chain] : []; });
168
+ for (const c of chains[0]) if (chains.every((ch) => ch.includes(c))) return c;
169
+ return null;
170
+ }
171
+ function containerItems(s, cid) { return s.items.filter((it) => it.id === cid || it.chain.includes(cid)); }
172
+ for (const s of states) {
173
+ const shellIds = new Set(s.shell.map((x) => x.containerId));
174
+ const inShell = (it) => it.chain.some((c) => shellIds.has(c));
175
+ const cands = [];
176
+ // buttons
177
+ const btnMap = new Map();
178
+ for (const it of s.items) if (it.inButton && it.text) btnMap.set(it.buttonId, ((btnMap.get(it.buttonId) || '') + ' ' + it.text).trim());
179
+ for (const [bid, text] of btnMap) {
180
+ const c = s.containers.find((x) => x.id === bid);
181
+ cands.push({ id: bid, kind: 'button', text, box: c ? [c.x, c.y, c.w, c.h] : null, inShell: !!c && [...shellIds].some((sh) => s.items.find((it) => it.buttonId === bid)?.chain.includes(sh)) });
182
+ }
183
+ // dropdown triggers: a down-chevron icon whose smallest container with a text sibling
184
+ for (const ic of s.items.filter((it) => (it.cls.includes('icon') || it.tag === 'img') && chevronDown(it.label))) {
185
+ // find nearest text to the left on the same line
186
+ // prefer an enclosing input/select-like container; else the nearest text to the left on the same line
187
+ const fieldCid = ic.chain.find((cid) => /(input|select|filter|sort|dropdown|picker|menu)(-|$)/.test(cid) && (s.containers.find((x) => x.id === cid)?.w || 0) <= 420);
188
+ let near = fieldCid ? containerItems(s, fieldCid).filter((t) => t.text).sort((a, b) => a.x - b.x)[0] : null;
189
+ if (!near) near = s.items.filter((t) => t.text && Math.abs((t.y + t.h / 2) - (ic.y + ic.h / 2)) <= Math.max(8, t.h) && t.x + t.w <= ic.x + 4 && ic.x - (t.x + t.w) <= 260).sort((a, b) => (ic.x - (a.x + a.w)) - (ic.x - (b.x + b.w)))[0];
190
+ if (!near) continue;
191
+ const cid = fieldCid || smallestCommon(s, [ic.id, near.id]);
192
+ const c = s.containers.find((x) => x.id === cid);
193
+ if (cands.some((x) => x.id === (cid || near.id))) { const ex = cands.find((x) => x.id === (cid || near.id)); ex.kind = 'dropdown'; ex.textId = near.id; continue; }
194
+ cands.push({ id: cid || near.id, kind: 'dropdown', text: near.text, textId: near.id, iconId: ic.id, box: c ? [c.x, c.y, c.w, c.h] : [near.x, near.y, ic.x + ic.w - near.x, Math.max(near.h, ic.h)], inShell: inShell(near) });
195
+ }
196
+ // rows: right-chevron icon -> its row container (smallest container wider than 200px holding the icon and >=1 text)
197
+ for (const ic of s.items.filter((it) => (it.cls.includes('icon') || it.tag === 'img') && chevronRight(it.label))) {
198
+ // the full row = the widest ancestor that is still row-shaped (<= 140px tall)
199
+ let row = null;
200
+ for (const cid of ic.chain) { const c = s.containers.find((x) => x.id === cid); if (c && c.h <= 140 && c.w >= 200 && containerItems(s, cid).some((t) => t.text) && (!row || c.w * c.h >= row.w * row.h)) row = c; }
201
+ if (!row || shellIds.has(row.id) || isWithinShell(ic.chain, shellIds)) continue;
202
+ if (cands.some((x) => x.id === row.id)) continue;
203
+ const texts = containerItems(s, row.id).filter((t) => t.text).sort((a, b) => b.fontSize - a.fontSize);
204
+ cands.push({ id: row.id, kind: 'row', text: texts.slice(0, 2).map((t) => t.text).join(' — '), box: [row.x, row.y, row.w, row.h], inShell: false });
205
+ }
206
+ // link-like texts
207
+ for (const t of s.items) {
208
+ if (!t.text || t.inButton || t.text.length > 40) continue;
209
+ if (cands.some((c) => c.id === t.id || c.textId === t.id)) continue;
210
+ const isNav = inShell(t) && nav.some((n) => norm(n.text) === norm(t.text));
211
+ if (isNav) { cands.push({ id: t.id, kind: 'nav', text: t.text, box: [t.x, t.y, t.w, t.h], inShell: true }); continue; }
212
+ if (linkVerb.test(norm(t.text)) && t.text.split(' ').length <= 5) cands.push({ id: t.id, kind: 'link', text: t.text, box: [t.x, t.y, t.w, t.h], inShell: inShell(t) });
213
+ }
214
+ // card titles: prominent texts inside a sizeable card container (not the page title, not chrome)
215
+ const pageTitleY = Math.min(...s.items.filter((t) => t.text && t.fontSize >= 24 && !inShell(t)).map((t) => t.y), 1e9);
216
+ for (const t of s.items) {
217
+ if (!t.text || t.inButton || inShell(t) || t.fontSize < 17 || t.text.length > 48 || t.y <= pageTitleY + 4) continue;
218
+ if (cands.some((c) => c.id === t.id || c.textId === t.id || t.chain.includes(c.id))) continue;
219
+ const card = t.chain.map((cid) => s.containers.find((x) => x.id === cid)).find((c) => c && c.w >= 240 && c.h >= 80 && c.h <= 600 && c.bg && c.bg !== 'rgba(0, 0, 0, 0)');
220
+ if (!card) continue;
221
+ cands.push({ id: card.id, kind: 'card', text: t.text, textId: t.id, box: [card.x, card.y, card.w, card.h], inShell: false });
222
+ }
223
+ // search / bell / avatar icons in header: utility
224
+ for (const ic of s.items.filter((it) => (it.cls.includes('icon') || it.tag === 'img') && /search|magnif|bell|notification|avatar|profile|menu|hamburger|user/.test(norm(it.label)) && !it.inButton)) {
225
+ if (cands.some((c) => c.id === ic.id)) continue;
226
+ cands.push({ id: ic.id, kind: 'utility', text: ic.label, box: [ic.x, ic.y, ic.w, ic.h], inShell: inShell(ic) });
227
+ }
228
+ s.candidates = cands;
229
+ // form fields: containers whose id mentions input/field/composer/search and have a text child (placeholder)
230
+ s.fields = s.containers.filter((c) => /(input|field|composer|search|textarea|prompt)(-|$)/.test(c.id) && c.w >= 120 && c.h >= 28 && c.h <= 160 && !cands.some((x) => x.id === c.id)).map((c) => {
231
+ const texts = containerItems(s, c.id).filter((t) => t.text);
232
+ return { id: c.id, placeholder: texts[0]?.text || '', box: [c.x, c.y, c.w, c.h] };
233
+ });
234
+ }
235
+
236
+ // ---- style tokens from the source (or first) state
237
+ const src = states.find((s) => s.isSource) || states[0];
238
+ function mode(arr) { const m = new Map(); for (const a of arr) if (a) m.set(a, (m.get(a) || 0) + 1); return [...m.entries()].sort((a, b) => b[1] - a[1])[0]?.[0]; }
239
+ const bodyTexts = src.items.filter((t) => t.text && t.fontSize >= 12 && t.fontSize <= 16);
240
+ const heading = src.items.filter((t) => t.text).sort((a, b) => b.fontSize - a.fontSize)[0];
241
+ const btnBgs = states.flatMap((s) => s.containers.filter((c) => c.tag === 'button' && c.bg && c.bg !== 'rgba(0, 0, 0, 0)').map((c) => c.bg));
242
+ const accentText = mode(src.items.filter((t) => t.text && t.fontWeight >= 500 && !/rgb\((\d+), \1, \1\)/.test(t.color) && t.color !== 'rgb(0, 0, 0)').map((t) => t.color));
243
+ const tokens = {
244
+ bodyFont: mode(bodyTexts.map((t) => t.fontFamily)),
245
+ bodySize: mode(bodyTexts.map((t) => Math.round(t.fontSize))),
246
+ bodyColor: mode(bodyTexts.map((t) => t.color)),
247
+ mutedColor: mode(src.items.filter((t) => t.text && t.fontSize < 13).map((t) => t.color)),
248
+ headingFont: heading?.fontFamily, headingSize: heading?.fontSize, headingColor: heading?.color, headingWeight: heading?.fontWeight,
249
+ accent: accentText,
250
+ buttonBg: mode(btnBgs),
251
+ cardRadius: mode(src.containers.filter((c) => c.w > 200 && c.h > 80 && c.radius !== '0px').map((c) => c.radius)),
252
+ cardBorder: mode(src.containers.filter((c) => c.w > 200 && c.h > 80 && !c.border.startsWith('0px')).map((c) => c.border)),
253
+ pageBg: src.containers.find((c) => c.x === 0 && c.y === 0 && c.w >= W - 1 && c.h >= H - 1)?.bg,
254
+ surfaceBg: mode(src.containers.filter((c) => c.w > 300 && c.h > 100 && c.bg !== 'rgba(0, 0, 0, 0)').map((c) => c.bg)),
255
+ };
256
+
257
+ const model = {
258
+ run: inv.runDir,
259
+ plan: { concept: typeof inv.plan?.concept === 'string' ? inv.plan.concept : '', sitePurpose: typeof inv.plan?.sitePurpose === 'string' ? inv.plan.sitePurpose : '', scope: inv.plan?.scope || null },
260
+ tokens,
261
+ canonicalShell: canonical,
262
+ shellAmbiguities,
263
+ nav,
264
+ states: states.map((s) => ({
265
+ stateId: s.stateId, pageId: s.pageId, file: s.file, sectionId: s.sectionId, slot: s.slot, ordinal: s.ordinal, title: s.title, purpose: s.purpose,
266
+ surfaceType: s.surfaceType, direction: s.direction, content: s.content, dependsOn: s.dependsOnSlot ? slotToState[s.dependsOnSlot] : null, isSource: s.isSource,
267
+ shell: s.shell, candidates: s.candidates, fields: s.fields, scriptDirection: s.scriptDirection, writingMode: s.writingMode,
268
+ texts: s.items.filter((t) => t.text).map((t) => ({ id: t.id, text: t.text })).length,
269
+ })),
270
+ };
271
+ fs.writeFileSync(outFile, JSON.stringify(model, null, 1));
272
+ // summary
273
+ console.error(`states: ${states.length}; shell regions: ${regions.join(',') || 'none'}; nav items: ${nav.length} (${nav.filter((n) => n.target).length} matched to pages)`);
274
+ for (const s of model.states) console.error(` ${s.stateId.padEnd(28)} shell=${s.shell.map((x) => x.region).join('+') || '-'} cands=${s.candidates.length} [${['button', 'dropdown', 'row', 'link', 'nav', 'utility', 'card'].map((k) => k[0] + s.candidates.filter((c) => c.kind === k).length).join(' ')}] fields=${s.fields.length}`);
275
+ console.error('tokens', JSON.stringify(tokens));