@ggui-ai/ui-gen 0.28.0 → 0.29.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 (308) hide show
  1. package/dist/{adapter-h4_V69LI.d.ts → adapter-DLQ-5COm.d.ts} +1 -1
  2. package/dist/adapters/base.js +2 -27
  3. package/dist/adapters/base.js.map +1 -1
  4. package/dist/adapters/generation-dispatch.d.ts +14 -6
  5. package/dist/adapters/generation-dispatch.js +40 -19260
  6. package/dist/adapters/generation-dispatch.js.map +1 -1
  7. package/dist/adapters/index.d.ts +1 -1
  8. package/dist/adapters/index.js +25 -3561
  9. package/dist/adapters/index.js.map +1 -1
  10. package/dist/adapters/types.js +2 -9
  11. package/dist/adapters/types.js.map +1 -1
  12. package/dist/advanced/index.d.ts +13 -12
  13. package/dist/advanced/index.js +63 -21954
  14. package/dist/advanced/index.js.map +1 -1
  15. package/dist/{bank-Ctdp3FUA.d.ts → bank-LWaiAtaA.d.ts} +1 -1
  16. package/dist/blueprint-validator.js +6 -2301
  17. package/dist/blueprint-validator.js.map +1 -1
  18. package/dist/boilerplate.d.ts +3 -2
  19. package/dist/boilerplate.js +6 -1867
  20. package/dist/boilerplate.js.map +1 -1
  21. package/dist/check/index.d.ts +3 -2
  22. package/dist/check/index.js +6 -1923
  23. package/dist/check/index.js.map +1 -1
  24. package/dist/chunk-33B3BAWS.js +24 -0
  25. package/dist/chunk-33B3BAWS.js.map +1 -0
  26. package/dist/chunk-3HSGA6NI.js +591 -0
  27. package/dist/chunk-3HSGA6NI.js.map +1 -0
  28. package/dist/chunk-3NNNGNTO.js +1707 -0
  29. package/dist/chunk-3NNNGNTO.js.map +1 -0
  30. package/dist/chunk-3T2HMTON.js +79 -0
  31. package/dist/chunk-3T2HMTON.js.map +1 -0
  32. package/dist/chunk-3ZSSDV3L.js +123 -0
  33. package/dist/chunk-3ZSSDV3L.js.map +1 -0
  34. package/dist/chunk-4MBR5GA3.js +99 -0
  35. package/dist/chunk-4MBR5GA3.js.map +1 -0
  36. package/dist/chunk-56NJFD55.js +337 -0
  37. package/dist/chunk-56NJFD55.js.map +1 -0
  38. package/dist/chunk-5AGTY555.js +26 -0
  39. package/dist/chunk-5AGTY555.js.map +1 -0
  40. package/dist/chunk-5EJM7EGY.js +115 -0
  41. package/dist/chunk-5EJM7EGY.js.map +1 -0
  42. package/dist/chunk-5KXCQLLR.js +529 -0
  43. package/dist/chunk-5KXCQLLR.js.map +1 -0
  44. package/dist/chunk-5VBXHVEH.js +171 -0
  45. package/dist/chunk-5VBXHVEH.js.map +1 -0
  46. package/dist/chunk-6KDDEING.js +515 -0
  47. package/dist/chunk-6KDDEING.js.map +1 -0
  48. package/dist/chunk-6VDRWAP6.js +123 -0
  49. package/dist/chunk-6VDRWAP6.js.map +1 -0
  50. package/dist/chunk-732IBFEJ.js +2400 -0
  51. package/dist/chunk-732IBFEJ.js.map +1 -0
  52. package/dist/chunk-73AURS3I.js +46 -0
  53. package/dist/chunk-73AURS3I.js.map +1 -0
  54. package/dist/chunk-77H5SKLX.js +8 -0
  55. package/dist/chunk-77H5SKLX.js.map +1 -0
  56. package/dist/chunk-7QE3AHLE.js +35 -0
  57. package/dist/chunk-7QE3AHLE.js.map +1 -0
  58. package/dist/chunk-A375NNWN.js +11 -0
  59. package/dist/chunk-A375NNWN.js.map +1 -0
  60. package/dist/chunk-AOU33EFS.js +140 -0
  61. package/dist/chunk-AOU33EFS.js.map +1 -0
  62. package/dist/chunk-BA4QYA6E.js +461 -0
  63. package/dist/chunk-BA4QYA6E.js.map +1 -0
  64. package/dist/chunk-DBP764GL.js +3 -0
  65. package/dist/chunk-DBP764GL.js.map +1 -0
  66. package/dist/chunk-DUU3ZJDQ.js +41 -0
  67. package/dist/chunk-DUU3ZJDQ.js.map +1 -0
  68. package/dist/chunk-DXKRBXNU.js +30 -0
  69. package/dist/chunk-DXKRBXNU.js.map +1 -0
  70. package/dist/chunk-FB7OEEAH.js +1467 -0
  71. package/dist/chunk-FB7OEEAH.js.map +1 -0
  72. package/dist/chunk-FLRNMZV2.js +18 -0
  73. package/dist/chunk-FLRNMZV2.js.map +1 -0
  74. package/dist/chunk-FWJIMKFZ.js +2032 -0
  75. package/dist/chunk-FWJIMKFZ.js.map +1 -0
  76. package/dist/chunk-FXRHWYIQ.js +163 -0
  77. package/dist/chunk-FXRHWYIQ.js.map +1 -0
  78. package/dist/chunk-G3PMV62Z.js +33 -0
  79. package/dist/chunk-G3PMV62Z.js.map +1 -0
  80. package/dist/chunk-GAJI7Y3P.js +13 -0
  81. package/dist/chunk-GAJI7Y3P.js.map +1 -0
  82. package/dist/chunk-GYINWMPR.js +2052 -0
  83. package/dist/chunk-GYINWMPR.js.map +1 -0
  84. package/dist/chunk-HD6ABIK7.js +484 -0
  85. package/dist/chunk-HD6ABIK7.js.map +1 -0
  86. package/dist/chunk-HDQVHYO6.js +100 -0
  87. package/dist/chunk-HDQVHYO6.js.map +1 -0
  88. package/dist/chunk-IHUT3SIW.js +7 -0
  89. package/dist/chunk-IHUT3SIW.js.map +1 -0
  90. package/dist/chunk-JDH5EGNZ.js +126 -0
  91. package/dist/chunk-JDH5EGNZ.js.map +1 -0
  92. package/dist/chunk-JMD4RGSV.js +37 -0
  93. package/dist/chunk-JMD4RGSV.js.map +1 -0
  94. package/dist/chunk-KJWGZL5B.js +33 -0
  95. package/dist/chunk-KJWGZL5B.js.map +1 -0
  96. package/dist/chunk-MKMDQFZ7.js +86 -0
  97. package/dist/chunk-MKMDQFZ7.js.map +1 -0
  98. package/dist/chunk-NF6JUZWF.js +85 -0
  99. package/dist/chunk-NF6JUZWF.js.map +1 -0
  100. package/dist/chunk-O2YC6XDC.js +1933 -0
  101. package/dist/chunk-O2YC6XDC.js.map +1 -0
  102. package/dist/chunk-OVLH5ICV.js +29 -0
  103. package/dist/chunk-OVLH5ICV.js.map +1 -0
  104. package/dist/chunk-PBOYHGSD.js +106 -0
  105. package/dist/chunk-PBOYHGSD.js.map +1 -0
  106. package/dist/chunk-PJFH7QWA.js +81 -0
  107. package/dist/chunk-PJFH7QWA.js.map +1 -0
  108. package/dist/chunk-PUH4CXGZ.js +284 -0
  109. package/dist/chunk-PUH4CXGZ.js.map +1 -0
  110. package/dist/chunk-QLXXPGTV.js +18 -0
  111. package/dist/chunk-QLXXPGTV.js.map +1 -0
  112. package/dist/chunk-R5GIGPW2.js +2845 -0
  113. package/dist/chunk-R5GIGPW2.js.map +1 -0
  114. package/dist/chunk-RH4IUSTO.js +83 -0
  115. package/dist/chunk-RH4IUSTO.js.map +1 -0
  116. package/dist/chunk-S2GVXKKY.js +153 -0
  117. package/dist/chunk-S2GVXKKY.js.map +1 -0
  118. package/dist/chunk-TVHGKFJS.js +58 -0
  119. package/dist/chunk-TVHGKFJS.js.map +1 -0
  120. package/dist/chunk-U7GALWLG.js +66 -0
  121. package/dist/chunk-U7GALWLG.js.map +1 -0
  122. package/dist/chunk-VTC263LT.js +256 -0
  123. package/dist/chunk-VTC263LT.js.map +1 -0
  124. package/dist/chunk-WEOXFEVE.js +739 -0
  125. package/dist/chunk-WEOXFEVE.js.map +1 -0
  126. package/dist/chunk-WYHP46LT.js +28 -0
  127. package/dist/chunk-WYHP46LT.js.map +1 -0
  128. package/dist/chunk-XGLO5LGG.js +274 -0
  129. package/dist/chunk-XGLO5LGG.js.map +1 -0
  130. package/dist/chunk-XRBCRKA2.js +29 -0
  131. package/dist/chunk-XRBCRKA2.js.map +1 -0
  132. package/dist/chunk-XW7ADFFV.js +340 -0
  133. package/dist/chunk-XW7ADFFV.js.map +1 -0
  134. package/dist/chunk-YIQ42IUX.js +34 -0
  135. package/dist/chunk-YIQ42IUX.js.map +1 -0
  136. package/dist/chunk-YJZTUY7B.js +101 -0
  137. package/dist/chunk-YJZTUY7B.js.map +1 -0
  138. package/dist/chunk-Z3CXME3K.js +107 -0
  139. package/dist/chunk-Z3CXME3K.js.map +1 -0
  140. package/dist/classifier/index.js +2 -527
  141. package/dist/classifier/index.js.map +1 -1
  142. package/dist/client-JBPCXU7W.js +4 -0
  143. package/dist/client-JBPCXU7W.js.map +1 -0
  144. package/dist/compose.js +3 -367
  145. package/dist/compose.js.map +1 -1
  146. package/dist/cost-tracker-HHGQ4FTW.js +67 -0
  147. package/dist/cost-tracker-HHGQ4FTW.js.map +1 -0
  148. package/dist/{create-ui-generator-BrZHF0cf.d.ts → create-ui-generator-BY-WeaPi.d.ts} +3 -3
  149. package/dist/{design-mode-DGWN_Gkm.d.ts → design-mode-XyOQmzE0.d.ts} +4 -3
  150. package/dist/{dispatch-B07TI30d.d.ts → dispatch-8LzTddKw.d.ts} +3 -2
  151. package/dist/dist-UALN6ZVB.js +543 -0
  152. package/dist/dist-UALN6ZVB.js.map +1 -0
  153. package/dist/dupe-break-X6K7QFIS.js +4 -0
  154. package/dist/dupe-break-X6K7QFIS.js.map +1 -0
  155. package/dist/evaluation/axis-checks/index.d.ts +5 -4
  156. package/dist/evaluation/axis-checks/index.js +6 -1914
  157. package/dist/evaluation/axis-checks/index.js.map +1 -1
  158. package/dist/evaluation/axis-checks/registry.d.ts +3 -2
  159. package/dist/evaluation/axis-checks/registry.js +3 -1844
  160. package/dist/evaluation/axis-checks/registry.js.map +1 -1
  161. package/dist/evaluation/index.d.ts +49 -132
  162. package/dist/evaluation/index.js +302 -6466
  163. package/dist/evaluation/index.js.map +1 -1
  164. package/dist/evaluation/types.d.ts +3 -2
  165. package/dist/evaluation/types.js +2 -5
  166. package/dist/evaluation/types.js.map +1 -1
  167. package/dist/fragments/index.js +2 -338
  168. package/dist/fragments/index.js.map +1 -1
  169. package/dist/{generate-tSO_shQ0.d.ts → generate-DQ4ci90s.d.ts} +1 -1
  170. package/dist/harness/check/runtime-render/index.d.ts +35 -15
  171. package/dist/harness/check/runtime-render/index.js +6 -2390
  172. package/dist/harness/check/runtime-render/index.js.map +1 -1
  173. package/dist/harness/check/runtime-render/render-check-worker.js +4 -1739
  174. package/dist/harness/check/runtime-render/render-check-worker.js.map +1 -1
  175. package/dist/harness/index.d.ts +3 -2
  176. package/dist/harness/index.js +23 -5126
  177. package/dist/harness/index.js.map +1 -1
  178. package/dist/harness/llm-trace-sink.js +2 -24
  179. package/dist/harness/llm-trace-sink.js.map +1 -1
  180. package/dist/harness/prompts.d.ts +2 -2
  181. package/dist/harness/prompts.js +8 -324
  182. package/dist/harness/prompts.js.map +1 -1
  183. package/dist/harness/result-types.d.ts +6 -5
  184. package/dist/harness/result-types.js +2 -0
  185. package/dist/harness/result-types.js.map +1 -1
  186. package/dist/harness/runtime.d.ts +22 -5
  187. package/dist/harness/runtime.js +10 -2313
  188. package/dist/harness/runtime.js.map +1 -1
  189. package/dist/harness/types-public.d.ts +3 -2
  190. package/dist/harness/types-public.js +16 -2954
  191. package/dist/harness/types-public.js.map +1 -1
  192. package/dist/harness/validator-trace-sink.d.ts +3 -2
  193. package/dist/harness/validator-trace-sink.js +2 -26
  194. package/dist/harness/validator-trace-sink.js.map +1 -1
  195. package/dist/hash.js +2 -39
  196. package/dist/hash.js.map +1 -1
  197. package/dist/hashline-5OKREIRM.js +4 -0
  198. package/dist/hashline-5OKREIRM.js.map +1 -0
  199. package/dist/index.d.ts +50 -11
  200. package/dist/index.js +57 -22015
  201. package/dist/index.js.map +1 -1
  202. package/dist/llm-evaluator-PN3WFCS4.js +653 -0
  203. package/dist/llm-evaluator-PN3WFCS4.js.map +1 -0
  204. package/dist/magic-string.es-2NZTC4GZ.js +1307 -0
  205. package/dist/magic-string.es-2NZTC4GZ.js.map +1 -0
  206. package/dist/patch.d.ts +3 -2
  207. package/dist/patch.js +2 -56
  208. package/dist/patch.js.map +1 -1
  209. package/dist/policy-VCYKGSAC.js +5 -0
  210. package/dist/policy-VCYKGSAC.js.map +1 -0
  211. package/dist/policy.js +2 -35
  212. package/dist/policy.js.map +1 -1
  213. package/dist/primitive-index-2OF6F4TZ.js +131 -0
  214. package/dist/primitive-index-2OF6F4TZ.js.map +1 -0
  215. package/dist/primitive-slice-WTMBLYFJ.js +235 -0
  216. package/dist/primitive-slice-WTMBLYFJ.js.map +1 -0
  217. package/dist/{prompts-BhNUuRoZ.d.ts → prompts-CLZGywMP.d.ts} +1 -1
  218. package/dist/provider-adapter-contract.js +10407 -14204
  219. package/dist/provider-adapter-contract.js.map +1 -1
  220. package/dist/provider-adapter.js +2 -44
  221. package/dist/provider-adapter.js.map +1 -1
  222. package/dist/providers/index.d.ts +89 -1
  223. package/dist/providers/index.js +115 -44
  224. package/dist/providers/index.js.map +1 -1
  225. package/dist/raw-C6KBH5I3.js +141 -0
  226. package/dist/raw-C6KBH5I3.js.map +1 -0
  227. package/dist/raw-FXSBXQTZ.js +7 -0
  228. package/dist/raw-FXSBXQTZ.js.map +1 -0
  229. package/dist/raw-MURDUPGK.js +8 -0
  230. package/dist/raw-MURDUPGK.js.map +1 -0
  231. package/dist/raw-T3GW3UVX.js +8 -0
  232. package/dist/raw-T3GW3UVX.js.map +1 -0
  233. package/dist/render-check-host-ZNIS6BJ5.js +5 -0
  234. package/dist/render-check-host-ZNIS6BJ5.js.map +1 -0
  235. package/dist/sdk-4JNSDNSR.js +6 -0
  236. package/dist/sdk-4JNSDNSR.js.map +1 -0
  237. package/dist/sdk-DIVJMHCX.js +7 -0
  238. package/dist/sdk-DIVJMHCX.js.map +1 -0
  239. package/dist/sdk-QRJOCRTS.js +7 -0
  240. package/dist/sdk-QRJOCRTS.js.map +1 -0
  241. package/dist/tag-balance-CTHCTRJ7.js +123 -0
  242. package/dist/tag-balance-CTHCTRJ7.js.map +1 -0
  243. package/dist/tools/get-primitives-ts.d.ts +1 -1
  244. package/dist/tools/get-primitives-ts.js +3 -1
  245. package/dist/tools/get-primitives-ts.js.map +1 -1
  246. package/dist/tools/render-check-worker.js +3 -40
  247. package/dist/tools/render-check-worker.js.map +1 -1
  248. package/dist/{types-public-h8IMnYuh.d.ts → types-public-hYlrerZh.d.ts} +35 -2
  249. package/dist/validation/index.d.ts +2 -2
  250. package/dist/validation/index.js +3 -498
  251. package/dist/validation/index.js.map +1 -1
  252. package/dist/{visual-evaluator-C2strxqD.d.ts → visual-evaluator-KskajxD5.d.ts} +14 -4
  253. package/dist/visual-evaluator-TGEXYQTP.js +12 -0
  254. package/dist/visual-evaluator-TGEXYQTP.js.map +1 -0
  255. package/dist/workflows.d.ts +3 -2
  256. package/dist/workflows.js +2 -151
  257. package/dist/workflows.js.map +1 -1
  258. package/package.json +20 -16
  259. package/src/adapters/claude/sdk.ts +4 -2
  260. package/src/adapters/claude/tool-bridge.ts +2 -1
  261. package/src/adapters/generation-dispatch.ts +9 -0
  262. package/src/adapters/openai/raw.ts +4 -0
  263. package/src/adapters/openai/sdk.ts +6 -1
  264. package/src/adapters/openai/tokens.ts +21 -7
  265. package/src/adapters/tool-bridge.ts +1 -1
  266. package/src/adapters/tools.ts +1 -1
  267. package/src/advanced/feedback.ts +1 -2
  268. package/src/advanced/generator.ts +4 -3
  269. package/src/boilerplate/free-design-prompt.ts +7 -0
  270. package/src/boilerplate/generate.ts +18 -5
  271. package/src/boilerplate/hard-sections.ts +8 -3
  272. package/src/boilerplate/react-hooks.ts +56 -0
  273. package/src/boilerplate/system-prompt.ts +12 -3
  274. package/src/check/run-tier0.ts +233 -8
  275. package/src/check/type-checker.ts +128 -16
  276. package/src/coding-agent/tools.ts +26 -3
  277. package/src/design-mode.ts +4 -9
  278. package/src/evaluation/axis-checks/checks/state-merge.ts +2 -4
  279. package/src/evaluation/axis-checks/checks/state-payload.ts +1 -28
  280. package/src/evaluation/axis-checks/checks/tint.ts +197 -0
  281. package/src/evaluation/axis-checks/helpers.ts +121 -0
  282. package/src/evaluation/axis-checks/registry.ts +2 -0
  283. package/src/evaluation/criteria/__fixtures__/edge-v2-draw2.json +4629 -0
  284. package/src/evaluation/criteria/bank.ts +1 -1
  285. package/src/evaluation/criteria/edge-instruments.ts +14 -0
  286. package/src/evaluation/criteria/edge-probe-v2.ts +352 -0
  287. package/src/evaluation/criteria/edge-v2.ts +242 -0
  288. package/src/evaluation/criteria/resolve.ts +24 -5
  289. package/src/evaluation/index.ts +3 -5
  290. package/src/evaluation/mcp-server.ts +0 -50
  291. package/src/evaluation/types-public.ts +6 -1
  292. package/src/evaluation/visual-evaluator.ts +161 -30
  293. package/src/harness/check/runtime-render/index.ts +28 -4
  294. package/src/harness/check/runtime-render/render-check.ts +20 -21
  295. package/src/harness/claude-agent-sdk-loader.ts +93 -0
  296. package/src/harness/claude-code-login-query.ts +1 -1
  297. package/src/harness/coding/generate-task-runner.ts +1 -0
  298. package/src/harness/coding/run-coding-turn.ts +3 -0
  299. package/src/harness/coding/run-eval-round.ts +9 -0
  300. package/src/harness/llm-router.ts +50 -2
  301. package/src/harness/runtime.ts +17 -0
  302. package/src/index.ts +9 -0
  303. package/src/providers/anthropic-tool-call.ts +263 -0
  304. package/src/providers/index.ts +13 -0
  305. package/src/tools/get-primitives-ts.ts +1 -1
  306. package/src/tools/render-check.ts +4 -4
  307. package/src/validation/primitives.ts +2 -1
  308. package/src/evaluation/loop.ts +0 -218
@@ -0,0 +1,529 @@
1
+ // src/classifier/inspect.ts
2
+ function resolveSchema(node) {
3
+ if (!node || typeof node !== "object") return void 0;
4
+ const n = node;
5
+ return n.schema ?? n;
6
+ }
7
+ function propType(p) {
8
+ const s = resolveSchema(p);
9
+ return s?.type;
10
+ }
11
+ function itemShape(p) {
12
+ const s = resolveSchema(p);
13
+ return s?.items;
14
+ }
15
+ function propertiesOf(p) {
16
+ const s = resolveSchema(p);
17
+ return s?.properties;
18
+ }
19
+ var ID_FIELD_CANDIDATES = ["id", "uuid", "symbol", "key", "slug", "code"];
20
+ function inferIdField(itemProps) {
21
+ if (!itemProps) return "id";
22
+ for (const cand of ID_FIELD_CANDIDATES) {
23
+ if (cand in itemProps) return cand;
24
+ }
25
+ return "id";
26
+ }
27
+ function singularize(name) {
28
+ if (name.endsWith("ies")) return name.slice(0, -3) + "y";
29
+ if (name.endsWith("ses")) return name.slice(0, -2);
30
+ if (name.endsWith("s") && !name.endsWith("ss")) return name.slice(0, -1);
31
+ return name;
32
+ }
33
+ function walkForArrObj(node, depth = 0) {
34
+ if (depth > 8 || !node || typeof node !== "object") return false;
35
+ const s = resolveSchema(node);
36
+ if (!s) return false;
37
+ const t = s.type;
38
+ const items = s.items;
39
+ if (t === "array" && items?.type === "object") return true;
40
+ const props = s.properties;
41
+ if (props) {
42
+ for (const v of Object.values(props)) {
43
+ if (walkForArrObj(v, depth + 1)) return true;
44
+ }
45
+ }
46
+ if (items && typeof items === "object") {
47
+ const itemProps = items.properties;
48
+ if (itemProps) {
49
+ for (const v of Object.values(itemProps)) {
50
+ if (walkForArrObj(v, depth + 1)) return true;
51
+ }
52
+ }
53
+ }
54
+ return false;
55
+ }
56
+ function hasGeoCoordsRecursive(node, depth = 0) {
57
+ if (depth > 8 || !node || typeof node !== "object") return false;
58
+ const s = resolveSchema(node);
59
+ if (!s) return false;
60
+ const props = s.properties;
61
+ if (props) {
62
+ const keys = Object.keys(props);
63
+ const lowered = keys.map((k) => k.toLowerCase());
64
+ const hasLat = lowered.includes("lat") || lowered.includes("latitude");
65
+ const hasLng = lowered.includes("lng") || lowered.includes("lon") || lowered.includes("longitude");
66
+ if (hasLat && hasLng) return true;
67
+ for (const v of Object.values(props)) {
68
+ if (hasGeoCoordsRecursive(v, depth + 1)) return true;
69
+ }
70
+ }
71
+ if (s.items) {
72
+ if (hasGeoCoordsRecursive(s.items, depth + 1)) return true;
73
+ }
74
+ return false;
75
+ }
76
+ function scalarKeyCount(obj) {
77
+ if (!obj || typeof obj !== "object" || Array.isArray(obj)) return [];
78
+ const keys = [];
79
+ for (const [k, v] of Object.entries(obj)) {
80
+ const t = typeof v;
81
+ if (t === "string" || t === "number" || t === "boolean") keys.push(k);
82
+ }
83
+ return keys;
84
+ }
85
+ function allTopLevelKeys(obj) {
86
+ if (!obj || typeof obj !== "object" || Array.isArray(obj)) return [];
87
+ return Object.keys(obj);
88
+ }
89
+ function referencedEntitiesForPayload(keys, entityLists, singletons) {
90
+ const hits = /* @__PURE__ */ new Set();
91
+ for (const key of keys) {
92
+ if (/Id$/.test(key) && key.length > 2) {
93
+ const stem = key.slice(0, -2).toLowerCase();
94
+ for (const e of entityLists) {
95
+ if (e.singular.toLowerCase() === stem) hits.add(e.name);
96
+ }
97
+ for (const s of singletons) {
98
+ if (s.name.toLowerCase() === stem) hits.add(`__singleton:${s.name}`);
99
+ }
100
+ }
101
+ }
102
+ return [...hits];
103
+ }
104
+ function isFullEntity(eventKeys, entity) {
105
+ return entity.itemKeys.every((k) => eventKeys.includes(k));
106
+ }
107
+ function inferStreamKindFromSchema(eventSchema, entityLists, singletons) {
108
+ const eventProps = eventSchema?.properties ?? {};
109
+ const eventKeys = Object.keys(eventProps);
110
+ const hasBool = Object.values(eventProps).some(
111
+ (v) => propType(v) === "boolean"
112
+ );
113
+ const hasUserKey = eventKeys.some(
114
+ (k) => /sender|user|author|actor|from/i.test(k)
115
+ );
116
+ if (hasBool && hasUserKey && eventKeys.length <= 3) return "presence";
117
+ for (const v of Object.values(eventProps)) {
118
+ const s = resolveSchema(v);
119
+ if (s?.type === "object" && s.properties && "id" in s.properties) {
120
+ return "merge";
121
+ }
122
+ }
123
+ for (const entity of entityLists) {
124
+ if (isFullEntity(eventKeys, entity)) return "append";
125
+ }
126
+ for (const entity of entityLists) {
127
+ const directMatch = eventKeys.includes(entity.idField);
128
+ const suffixMatch = eventKeys.some((k) => {
129
+ if (!/Id$/.test(k) || k.length <= 2) return false;
130
+ return k.slice(0, -2).toLowerCase() === entity.singular.toLowerCase();
131
+ });
132
+ if (directMatch || suffixMatch) return "merge";
133
+ }
134
+ for (const singleton of singletons) {
135
+ const suffixMatch = eventKeys.some((k) => {
136
+ if (!/Id$/.test(k) || k.length <= 2) return false;
137
+ return k.slice(0, -2).toLowerCase() === singleton.name.toLowerCase();
138
+ });
139
+ if (suffixMatch) return "merge";
140
+ const overlapCount = eventKeys.filter((k) => singleton.keys.includes(k)).length;
141
+ if (overlapCount >= 2) return "merge";
142
+ }
143
+ for (const v of Object.values(eventProps)) {
144
+ const s = resolveSchema(v);
145
+ if (Array.isArray(s?.enum) && s.enum.length > 0) return "status";
146
+ }
147
+ return "other";
148
+ }
149
+ function inspect(contract) {
150
+ const empty = {
151
+ actions: [],
152
+ streams: [],
153
+ agentTools: [],
154
+ clientCapabilities: [],
155
+ entityLists: [],
156
+ singletons: [],
157
+ hasArrObjAnywhere: false,
158
+ hasGeoCoords: false,
159
+ entityListIdInPayload: false,
160
+ singletonIdInPayload: false,
161
+ crossEntityAction: false,
162
+ multiFieldSubmit: false,
163
+ topLevelScalarCount: 0,
164
+ entitiesHaveGridPositions: false
165
+ };
166
+ if (!contract) return empty;
167
+ const propsField = contract.propsSpec;
168
+ const propsProps = propsField?.properties ?? {};
169
+ const entityLists = [];
170
+ for (const [name, p] of Object.entries(propsProps)) {
171
+ const t = propType(p);
172
+ const items = itemShape(p);
173
+ if (t === "array" && items?.type === "object") {
174
+ const itemProps = items.properties ?? {};
175
+ entityLists.push({
176
+ name,
177
+ singular: singularize(name),
178
+ idField: inferIdField(itemProps),
179
+ itemKeys: Object.keys(itemProps)
180
+ });
181
+ }
182
+ }
183
+ const singletons = [];
184
+ for (const [name, p] of Object.entries(propsProps)) {
185
+ const t = propType(p);
186
+ if (t === "object") {
187
+ const childProps = propertiesOf(p) ?? {};
188
+ const keys = Object.keys(childProps);
189
+ if (keys.length > 0) {
190
+ singletons.push({ name, keys });
191
+ }
192
+ }
193
+ }
194
+ const actionsMap = contract.actionSpec ?? {};
195
+ const actions = [];
196
+ for (const [name, action] of Object.entries(actionsMap)) {
197
+ const a = action;
198
+ const scalarKeys = scalarKeyCount(a?.example);
199
+ const allKeys = allTopLevelKeys(a?.example);
200
+ const referencedEntities = referencedEntitiesForPayload(
201
+ allKeys,
202
+ entityLists,
203
+ singletons
204
+ );
205
+ actions.push({
206
+ name,
207
+ nextStep: a?.nextStep,
208
+ example: a?.example,
209
+ scalarKeys,
210
+ allKeys,
211
+ referencedEntities
212
+ });
213
+ }
214
+ const channelsMap = contract.streamSpec ?? {};
215
+ const streams = [];
216
+ for (const [name, channel] of Object.entries(channelsMap)) {
217
+ streams.push({ name, schema: channel.schema });
218
+ }
219
+ const agentToolsMap = contract.agentCapabilities?.tools ?? {};
220
+ const agentTools = [];
221
+ for (const [name, tool] of Object.entries(agentToolsMap)) {
222
+ const t = tool;
223
+ const req = t?.toolInfo?.inputSchema?.properties ?? {};
224
+ agentTools.push({ name, requestKeys: Object.keys(req) });
225
+ }
226
+ const gadgetsMap = contract.clientCapabilities?.gadgets ?? {};
227
+ const clientCapabilities = [];
228
+ for (const name of Object.keys(gadgetsMap)) {
229
+ clientCapabilities.push({ name, requestKeys: [] });
230
+ }
231
+ const hasArrObjAnywhere = walkForArrObj({ properties: propsProps });
232
+ const hasGeoCoords = hasGeoCoordsRecursive({ properties: propsProps });
233
+ const entityListNames = new Set(entityLists.map((e) => e.name));
234
+ const entityListIdInPayload = actions.some(
235
+ (a) => a.referencedEntities.some((r) => entityListNames.has(r))
236
+ );
237
+ const singletonIdInPayload = actions.some(
238
+ (a) => a.referencedEntities.some((r) => r.startsWith("__singleton:"))
239
+ );
240
+ const crossEntityAction = actions.some((a) => {
241
+ const entityRefs = a.referencedEntities.filter(
242
+ (r) => entityListNames.has(r)
243
+ );
244
+ return new Set(entityRefs).size >= 2;
245
+ });
246
+ const multiFieldSubmit = actions.some((a) => a.scalarKeys.length >= 3);
247
+ let topLevelScalarCount = 0;
248
+ for (const v of Object.values(propsProps)) {
249
+ const t = propType(v);
250
+ if (t === "string" || t === "number" || t === "boolean") topLevelScalarCount++;
251
+ }
252
+ const entitiesHaveGridPositions = entityLists.some((e) => {
253
+ const keys = e.itemKeys;
254
+ return keys.includes("row") && keys.includes("col") || keys.includes("x") && keys.includes("y") && keys.length > 2 || keys.includes("gridRow") && keys.includes("gridColumn");
255
+ });
256
+ return {
257
+ actions,
258
+ streams,
259
+ agentTools,
260
+ clientCapabilities,
261
+ entityLists,
262
+ singletons,
263
+ hasArrObjAnywhere,
264
+ hasGeoCoords,
265
+ entityListIdInPayload,
266
+ singletonIdInPayload,
267
+ crossEntityAction,
268
+ multiFieldSubmit,
269
+ topLevelScalarCount,
270
+ entitiesHaveGridPositions
271
+ };
272
+ }
273
+
274
+ // src/classifier/infer-state.ts
275
+ var AFFORDANCE_KEYWORDS = /\b(search\b|filter\b|sort\b|select\b|tabs?\b|quantity\b|paginat|expand(ed|able)?|collaps|click(?:s|ing|ed)?\s+(an|a|the)\s+\w+\s*→?\s*detail|click\s+to\s+(select|open|view))/i;
276
+ function inferState(s, prompt) {
277
+ if (s.actions.length === 1 && s.multiFieldSubmit && !s.entityListIdInPayload && !s.singletonIdInPayload) {
278
+ return { value: "payload", source: "contract" };
279
+ }
280
+ if (s.streams.length > 0) {
281
+ return { value: "merge", source: "contract" };
282
+ }
283
+ if (s.entityLists.length > 0 && s.entityListIdInPayload) {
284
+ return { value: "merge", source: "contract" };
285
+ }
286
+ if (AFFORDANCE_KEYWORDS.test(prompt)) {
287
+ return { value: "ui-affordance", source: "prompt" };
288
+ }
289
+ if (s.actions.length >= 1) {
290
+ return { value: "ui-affordance", source: "heuristic" };
291
+ }
292
+ return { value: "none", source: "contract" };
293
+ }
294
+
295
+ // src/classifier/infer-writes.ts
296
+ function inferWrites(s) {
297
+ if (s.actions.length === 0) {
298
+ return { value: "none", source: "contract" };
299
+ }
300
+ if (s.crossEntityAction) {
301
+ return { value: "compose", source: "contract" };
302
+ }
303
+ if (s.entityListIdInPayload) {
304
+ return { value: "per-item", source: "contract" };
305
+ }
306
+ if (s.actions.length === 1 && s.multiFieldSubmit) {
307
+ return { value: "submit", source: "contract" };
308
+ }
309
+ if (s.actions.length >= 2) {
310
+ return { value: "multi-commit", source: "contract" };
311
+ }
312
+ return { value: "commit", source: "contract" };
313
+ }
314
+
315
+ // src/classifier/infer-realtime.ts
316
+ function inferRealtime(s) {
317
+ if (s.streams.length === 0) {
318
+ return { value: "none", source: "contract" };
319
+ }
320
+ const kinds = {};
321
+ for (const stream of s.streams) {
322
+ kinds[stream.name] = inferStreamKindFromSchema(
323
+ stream.schema,
324
+ s.entityLists,
325
+ s.singletons
326
+ );
327
+ }
328
+ const distinct = new Set(Object.values(kinds));
329
+ if (distinct.size === 1) {
330
+ const only = [...distinct][0];
331
+ if (only === "other") {
332
+ return { value: "mixed", streamKinds: kinds, source: "contract" };
333
+ }
334
+ return { value: only, source: "contract" };
335
+ }
336
+ return { value: "mixed", streamKinds: kinds, source: "contract" };
337
+ }
338
+
339
+ // src/classifier/infer-fetch.ts
340
+ var PAGINATION_KEYS = /* @__PURE__ */ new Set([
341
+ "cursor",
342
+ "offset",
343
+ "page",
344
+ "before",
345
+ "after",
346
+ "limit",
347
+ "pageSize"
348
+ ]);
349
+ var SEARCH_KEYS = /* @__PURE__ */ new Set(["query", "q", "search", "keyword"]);
350
+ function inferFetch(s) {
351
+ if (s.agentTools.length === 0) {
352
+ return { value: "none", source: "contract" };
353
+ }
354
+ const tools = s.agentTools;
355
+ for (const tool of tools) {
356
+ for (const key of tool.requestKeys) {
357
+ if (PAGINATION_KEYS.has(key)) return { value: "pagination", source: "contract" };
358
+ }
359
+ }
360
+ for (const tool of tools) {
361
+ for (const key of tool.requestKeys) {
362
+ if (SEARCH_KEYS.has(key)) return { value: "search", source: "contract" };
363
+ }
364
+ }
365
+ const entityIdFields = new Set(s.entityLists.map((e) => e.idField));
366
+ for (const tool of tools) {
367
+ for (const key of tool.requestKeys) {
368
+ if (key === "id") return { value: "drill-down", source: "contract" };
369
+ if (/Id$/.test(key) && key.length > 2) {
370
+ return { value: "drill-down", source: "contract" };
371
+ }
372
+ if (entityIdFields.has(key)) {
373
+ return { value: "drill-down", source: "contract" };
374
+ }
375
+ }
376
+ }
377
+ return { value: "refresh", source: "contract" };
378
+ }
379
+
380
+ // src/classifier/infer-render.ts
381
+ var CHART_RX = /\b(chart|graph|trend|bar\s*graph|line\s*graph|pie)\b/i;
382
+ var TIMELINE_RX = /\b(timeline|chronolog|activity\s*feed|event\s*feed)\b/i;
383
+ var GRID_RX = /\bgrid\b|\btile\s*layout\b|\b\d+\s*columns\b|\bkanban\b|\bcolumns?\s*:/i;
384
+ var MAP_RX = /\b(on\s*a\s*map|on\s*the\s*map|geo|gps|lat\/lng)\b/i;
385
+ var MASTER_DETAIL_RX = /\b(left\s*pane|right\s*pane|sidebar|master[- ]detail|split\s*view|two[- ]pane)\b/i;
386
+ var STATIC_RX = /\b(card\s*stack|card\s*deck|one\s*(card|email|message|item)\s*at\s*a\s*time|full[- ]screen\s*card)\b/i;
387
+ function inferRender(s, prompt, blueprint) {
388
+ if (blueprint?.layoutHint) {
389
+ const hint = blueprint.layoutHint.toLowerCase();
390
+ if (hint.includes("master-detail") || hint.includes("split"))
391
+ return { value: "master-detail", source: "blueprint" };
392
+ if (hint.includes("card-stack") || hint.includes("deck") || hint.includes("modal"))
393
+ return { value: "static", source: "blueprint" };
394
+ if (hint.includes("spatial") || hint.includes("map"))
395
+ return { value: "spatial", source: "blueprint" };
396
+ if (hint.includes("timeline")) return { value: "timeline", source: "blueprint" };
397
+ if (hint.includes("chart")) return { value: "chart", source: "blueprint" };
398
+ if (hint.includes("grid")) return { value: "grid", source: "blueprint" };
399
+ }
400
+ if (s.hasGeoCoords) {
401
+ return { value: "spatial", source: "contract" };
402
+ }
403
+ if (s.entitiesHaveGridPositions) {
404
+ return { value: "grid", source: "contract" };
405
+ }
406
+ if (CHART_RX.test(prompt)) return { value: "chart", source: "prompt" };
407
+ if (TIMELINE_RX.test(prompt)) return { value: "timeline", source: "prompt" };
408
+ if (MASTER_DETAIL_RX.test(prompt))
409
+ return { value: "master-detail", source: "prompt" };
410
+ if (GRID_RX.test(prompt)) return { value: "grid", source: "prompt" };
411
+ if (MAP_RX.test(prompt) && !s.hasGeoCoords)
412
+ return { value: "spatial", source: "prompt" };
413
+ if (STATIC_RX.test(prompt)) return { value: "static", source: "prompt" };
414
+ if (s.entityLists.length === 0) {
415
+ return { value: "static", source: "contract" };
416
+ }
417
+ if (s.entityLists.length === 1 && s.topLevelScalarCount >= 4) {
418
+ return { value: "static", source: "contract" };
419
+ }
420
+ if (s.entityLists.length >= 2) {
421
+ return { value: "master-detail", source: "contract" };
422
+ }
423
+ return { value: "list", source: "contract" };
424
+ }
425
+
426
+ // src/classifier/infer-layout.ts
427
+ var OVERLAY_RX = /\b(overlay|overlaid|on\s*top|positioned\s*over|floating\s*action)\b/i;
428
+ var MODAL_RX = /\b(modal|dialog|sheet|drawer|card\s*stack)\b/i;
429
+ var MULTI_STEP_RX = /\b(multi[- ]step|wizard|step\s*\d+|step\s*\d+\s*:)/i;
430
+ var MASTER_DETAIL_RX2 = /\b(left\s*pane|right\s*pane|left\s*sidebar|right\s*main|split\s*view|two[- ]pane|master[- ]detail)\b/i;
431
+ function inferLayout(s, prompt, blueprint) {
432
+ if (blueprint?.layoutHint) {
433
+ const hint = blueprint.layoutHint.toLowerCase();
434
+ if (hint.includes("master-detail") || hint.includes("split"))
435
+ return { value: "master-detail", source: "blueprint" };
436
+ if (hint.includes("modal") || hint.includes("card-stack") || hint.includes("deck"))
437
+ return { value: "modal", source: "blueprint" };
438
+ if (hint.includes("overlay")) return { value: "overlay", source: "blueprint" };
439
+ if (hint.includes("multi-step") || hint.includes("wizard"))
440
+ return { value: "multi-step", source: "blueprint" };
441
+ }
442
+ if (MULTI_STEP_RX.test(prompt)) return { value: "multi-step", source: "prompt" };
443
+ if (OVERLAY_RX.test(prompt)) return { value: "overlay", source: "prompt" };
444
+ if (MODAL_RX.test(prompt)) return { value: "modal", source: "prompt" };
445
+ if (MASTER_DETAIL_RX2.test(prompt))
446
+ return { value: "master-detail", source: "prompt" };
447
+ return { value: "single", source: "default" };
448
+ }
449
+
450
+ // src/classifier/infer-trigger.ts
451
+ var DRAG_RX = /\b(drag|drop|dragging|draggable)\b/i;
452
+ var SWIPE_RX = /\b(swipe|swipes|gesture\s*stack)\b/i;
453
+ var KEYBOARD_RX = /\b(keyboard\s*shortcut|hotkey|keystroke|kbd)\b/i;
454
+ function inferWriteTrigger(s, prompt) {
455
+ if (s.actions.length === 0) {
456
+ return { value: "click", source: "default" };
457
+ }
458
+ if (DRAG_RX.test(prompt)) return { value: "drag", source: "prompt" };
459
+ if (SWIPE_RX.test(prompt)) return { value: "swipe", source: "prompt" };
460
+ if (KEYBOARD_RX.test(prompt)) return { value: "keystroke", source: "prompt" };
461
+ return { value: "click", source: "default" };
462
+ }
463
+
464
+ // src/classifier/infer-tooling.ts
465
+ function inferTooling(s) {
466
+ const hasAgent = s.agentTools.length > 0;
467
+ const hasClient = s.clientCapabilities.length > 0;
468
+ if (hasAgent && hasClient) return { value: "both", source: "contract" };
469
+ if (hasAgent) return { value: "wired", source: "contract" };
470
+ if (hasClient) return { value: "client", source: "contract" };
471
+ return { value: "none", source: "default" };
472
+ }
473
+
474
+ // src/classifier/risk-tier.ts
475
+ function deriveRiskTier(v) {
476
+ if (v.writes === "compose") return "high";
477
+ if (v.writeTrigger === "drag" || v.writeTrigger === "swipe") return "high";
478
+ if (v.realtime === "mixed") return "high";
479
+ if (v.render === "spatial" && v.realtime !== "none") return "high";
480
+ if (v.state === "merge" && v.writes === "per-item") return "high";
481
+ if ((v.state === "none" || v.state === "ui-affordance") && v.writes === "none" && v.realtime === "none" && v.fetch === "none") {
482
+ return "low";
483
+ }
484
+ return "medium";
485
+ }
486
+
487
+ // src/classifier/classifier.ts
488
+ function classifyAxes(input) {
489
+ const s = inspect(input.contract);
490
+ const prompt = input.prompt ?? "";
491
+ const blueprint = input.blueprint;
492
+ const state = inferState(s, prompt);
493
+ const writes = inferWrites(s);
494
+ const realtime = inferRealtime(s);
495
+ const fetch = inferFetch(s);
496
+ const render = inferRender(s, prompt, blueprint);
497
+ const layout = inferLayout(s, prompt, blueprint);
498
+ const writeTrigger = inferWriteTrigger(s, prompt);
499
+ const tooling = inferTooling(s);
500
+ const vector = {
501
+ render: render.value,
502
+ state: state.value,
503
+ writes: writes.value,
504
+ writeTrigger: writeTrigger.value,
505
+ realtime: realtime.value,
506
+ fetch: fetch.value,
507
+ layout: layout.value,
508
+ tooling: tooling.value
509
+ };
510
+ if (realtime.streamKinds) {
511
+ vector.streamKinds = realtime.streamKinds;
512
+ }
513
+ const provenance = {
514
+ render: render.source,
515
+ state: state.source,
516
+ writes: writes.source,
517
+ writeTrigger: writeTrigger.source,
518
+ realtime: realtime.source,
519
+ fetch: fetch.source,
520
+ layout: layout.source,
521
+ tooling: tooling.source
522
+ };
523
+ const riskTier = deriveRiskTier(vector);
524
+ return { vector, provenance, riskTier };
525
+ }
526
+
527
+ export { classifyAxes, deriveRiskTier, inferFetch, inferLayout, inferRealtime, inferRender, inferState, inferStreamKindFromSchema, inferTooling, inferWriteTrigger, inferWrites, inspect };
528
+ //# sourceMappingURL=chunk-5KXCQLLR.js.map
529
+ //# sourceMappingURL=chunk-5KXCQLLR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/classifier/inspect.ts","../src/classifier/infer-state.ts","../src/classifier/infer-writes.ts","../src/classifier/infer-realtime.ts","../src/classifier/infer-fetch.ts","../src/classifier/infer-render.ts","../src/classifier/infer-layout.ts","../src/classifier/infer-trigger.ts","../src/classifier/infer-tooling.ts","../src/classifier/risk-tier.ts","../src/classifier/classifier.ts"],"names":["MASTER_DETAIL_RX"],"mappings":"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","file":"chunk-5KXCQLLR.js","sourcesContent":["// packages/ui-gen/src/classifier/inspect.ts\n//\n// Contract inspection — extracts raw signals that axis inference consumes.\n// Pure function, no prompt / blueprint inputs.\n\nimport type {\n ClientCapabilitiesSpec,\n StreamChannelEntry,\n} from \"@ggui-ai/protocol\";\nimport type { StreamEventKind } from \"./axes\";\n\nexport type ClassifierInput = {\n propsSpec?: unknown;\n /**\n * Flat `Record<actionName, ActionEntry>`. Mirrors\n * {@link DataContract.actionSpec} exactly — the classifier accepts\n * the same shape callers pass through the render path.\n */\n actionSpec?: unknown;\n /**\n * Flat `Record<channelName, StreamChannelEntry>`. Mirrors\n * {@link DataContract.streamSpec}.\n */\n streamSpec?: unknown;\n agentCapabilities?: unknown;\n /**\n * Mirrors {@link DataContract.clientCapabilities}. Typed (not\n * `unknown`) so the gadget-name walk reads `gadgets` without a cast.\n */\n clientCapabilities?: ClientCapabilitiesSpec;\n} | undefined;\n\n// =============================================================================\n// Shared walk helpers\n// =============================================================================\n\ninterface SchemaShape {\n type?: string;\n enum?: unknown[];\n items?: SchemaShape & { properties?: Record<string, unknown> };\n properties?: Record<string, unknown>;\n schema?: SchemaShape;\n}\n\nfunction resolveSchema(node: unknown): SchemaShape | undefined {\n if (!node || typeof node !== \"object\") return undefined;\n const n = node as SchemaShape;\n return n.schema ?? n;\n}\n\nfunction propType(p: unknown): string | undefined {\n const s = resolveSchema(p);\n return s?.type;\n}\n\nfunction itemShape(p: unknown): SchemaShape | undefined {\n const s = resolveSchema(p);\n return s?.items;\n}\n\nfunction propertiesOf(p: unknown): Record<string, unknown> | undefined {\n const s = resolveSchema(p);\n return s?.properties;\n}\n\n// =============================================================================\n// Id-field detection — find the entity's identity key\n// =============================================================================\n\nconst ID_FIELD_CANDIDATES = [\"id\", \"uuid\", \"symbol\", \"key\", \"slug\", \"code\"];\n\nfunction inferIdField(itemProps: Record<string, unknown> | undefined): string {\n if (!itemProps) return \"id\";\n for (const cand of ID_FIELD_CANDIDATES) {\n if (cand in itemProps) return cand;\n }\n // No dedicated ID candidate — use 'id' as the expected field. Avoid the\n // \"first string\" fallback because it creates spurious matches (e.g.,\n // messages.sender matching a typing-presence event's sender field).\n return \"id\";\n}\n\n// =============================================================================\n// Entity-list + singleton-with-id detection\n// =============================================================================\n\nexport interface EntityList {\n /** Prop name, plural (e.g., \"tasks\") */\n name: string;\n /** Singular stem for Id-suffix matching (e.g., \"task\") */\n singular: string;\n /** Identity field on each item */\n idField: string;\n /** Keys present on each item */\n itemKeys: string[];\n}\n\nexport interface SingletonEntity {\n /** Prop name (e.g., \"ride\", \"flight\", \"product\") */\n name: string;\n /** Keys present on the singleton */\n keys: string[];\n}\n\nfunction singularize(name: string): string {\n if (name.endsWith(\"ies\")) return name.slice(0, -3) + \"y\";\n if (name.endsWith(\"ses\")) return name.slice(0, -2);\n if (name.endsWith(\"s\") && !name.endsWith(\"ss\")) return name.slice(0, -1);\n return name;\n}\n\n// =============================================================================\n// Recursive arr<obj> scan (for hasArrObjAnywhere)\n// =============================================================================\n\nfunction walkForArrObj(node: unknown, depth = 0): boolean {\n if (depth > 8 || !node || typeof node !== \"object\") return false;\n const s = resolveSchema(node);\n if (!s) return false;\n const t = s.type;\n const items = s.items;\n if (t === \"array\" && items?.type === \"object\") return true;\n const props = s.properties;\n if (props) {\n for (const v of Object.values(props)) {\n if (walkForArrObj(v, depth + 1)) return true;\n }\n }\n if (items && typeof items === \"object\") {\n const itemProps = items.properties;\n if (itemProps) {\n for (const v of Object.values(itemProps)) {\n if (walkForArrObj(v, depth + 1)) return true;\n }\n }\n }\n return false;\n}\n\n// =============================================================================\n// Geo-coord detection (any prop at any depth has lat/lng pair)\n// =============================================================================\n\nfunction hasGeoCoordsRecursive(node: unknown, depth = 0): boolean {\n if (depth > 8 || !node || typeof node !== \"object\") return false;\n const s = resolveSchema(node);\n if (!s) return false;\n const props = s.properties;\n if (props) {\n const keys = Object.keys(props);\n const lowered = keys.map((k) => k.toLowerCase());\n const hasLat = lowered.includes(\"lat\") || lowered.includes(\"latitude\");\n const hasLng =\n lowered.includes(\"lng\") ||\n lowered.includes(\"lon\") ||\n lowered.includes(\"longitude\");\n if (hasLat && hasLng) return true;\n for (const v of Object.values(props)) {\n if (hasGeoCoordsRecursive(v, depth + 1)) return true;\n }\n }\n if (s.items) {\n if (hasGeoCoordsRecursive(s.items, depth + 1)) return true;\n }\n return false;\n}\n\n// =============================================================================\n// ActionEntry and payload analysis\n// =============================================================================\n\nexport interface ActionEntryInfo {\n name: string;\n nextStep?: string;\n example?: Record<string, unknown>;\n /** Top-level keys in example whose value is scalar (string/number/boolean). */\n scalarKeys: string[];\n /** All top-level keys in the example. */\n allKeys: string[];\n /** Entity lists referenced by id-key match (taskId ↔ tasks). */\n referencedEntities: string[];\n}\n\nfunction scalarKeyCount(obj: unknown): string[] {\n if (!obj || typeof obj !== \"object\" || Array.isArray(obj)) return [];\n const keys: string[] = [];\n for (const [k, v] of Object.entries(obj as Record<string, unknown>)) {\n const t = typeof v;\n if (t === \"string\" || t === \"number\" || t === \"boolean\") keys.push(k);\n }\n return keys;\n}\n\nfunction allTopLevelKeys(obj: unknown): string[] {\n if (!obj || typeof obj !== \"object\" || Array.isArray(obj)) return [];\n return Object.keys(obj as Record<string, unknown>);\n}\n\nfunction referencedEntitiesForPayload(\n keys: string[],\n entityLists: EntityList[],\n singletons: SingletonEntity[],\n): string[] {\n const hits = new Set<string>();\n for (const key of keys) {\n // direct id/key/index match → ambiguous, skip unless entity has id\n // id-suffix match: \"taskId\" → \"task\"\n if (/Id$/.test(key) && key.length > 2) {\n const stem = key.slice(0, -2).toLowerCase();\n for (const e of entityLists) {\n if (e.singular.toLowerCase() === stem) hits.add(e.name);\n }\n // Singleton with name matching the stem\n for (const s of singletons) {\n if (s.name.toLowerCase() === stem) hits.add(`__singleton:${s.name}`);\n }\n }\n }\n return [...hits];\n}\n\n// =============================================================================\n// Stream-event kind inference\n// =============================================================================\n\nfunction isFullEntity(\n eventKeys: string[],\n entity: EntityList,\n): boolean {\n // Consider \"full entity\" when all entity item keys are present in event schema\n return entity.itemKeys.every((k) => eventKeys.includes(k));\n}\n\nexport function inferStreamKindFromSchema(\n eventSchema: SchemaShape | undefined,\n entityLists: EntityList[],\n singletons: SingletonEntity[],\n): StreamEventKind {\n const eventProps = eventSchema?.properties ?? {};\n const eventKeys = Object.keys(eventProps);\n const hasBool = Object.values(eventProps).some(\n (v) => propType(v) === \"boolean\",\n );\n const hasUserKey = eventKeys.some((k) =>\n /sender|user|author|actor|from/i.test(k),\n );\n\n // Rule 1: presence — small payload with boolean + user-identifier\n // (fires BEFORE entity-list match because typing events superficially\n // share a key name with messages.sender).\n if (hasBool && hasUserKey && eventKeys.length <= 3) return \"presence\";\n\n // Rule 2: nested object with id → merge (kanban taskChanged.task.id)\n for (const v of Object.values(eventProps)) {\n const s = resolveSchema(v);\n if (s?.type === \"object\" && s.properties && \"id\" in s.properties) {\n return \"merge\";\n }\n }\n\n // Rule 3: full entity → append (event payload matches entity item schema)\n for (const entity of entityLists) {\n if (isFullEntity(eventKeys, entity)) return \"append\";\n }\n\n // Rule 4: entity-list idField or id-suffix match → merge\n for (const entity of entityLists) {\n const directMatch = eventKeys.includes(entity.idField);\n const suffixMatch = eventKeys.some((k) => {\n if (!/Id$/.test(k) || k.length <= 2) return false;\n return k.slice(0, -2).toLowerCase() === entity.singular.toLowerCase();\n });\n if (directMatch || suffixMatch) return \"merge\";\n }\n\n // Rule 5: singleton match — id-suffix OR field-overlap (≥ 2 fields)\n for (const singleton of singletons) {\n const suffixMatch = eventKeys.some((k) => {\n if (!/Id$/.test(k) || k.length <= 2) return false;\n return k.slice(0, -2).toLowerCase() === singleton.name.toLowerCase();\n });\n if (suffixMatch) return \"merge\";\n const overlapCount = eventKeys.filter((k) => singleton.keys.includes(k)).length;\n if (overlapCount >= 2) return \"merge\";\n }\n\n // Rule 6: enum field (no entity target) → status\n for (const v of Object.values(eventProps)) {\n const s = resolveSchema(v);\n if (Array.isArray(s?.enum) && s.enum.length > 0) return \"status\";\n }\n\n return \"other\";\n}\n\n// =============================================================================\n// agentCapabilities.tools inspection\n// =============================================================================\n\n/**\n * Per-tool projection of the contract's `agentCapabilities.tools`\n * catalog. Also reused for `clientCapabilities.gadgets` entries\n * (always with empty `requestKeys`) — gadgets are pure declaration.\n */\nexport interface AgentToolInfo {\n name: string;\n requestKeys: string[];\n}\n\n// =============================================================================\n// Top-level inspect\n// =============================================================================\n\nexport interface ContractSignals {\n actions: ActionEntryInfo[];\n streams: Array<{ name: string; schema?: SchemaShape }>;\n /** Projection of `contract.agentCapabilities.tools`. The agent\n * invokes these — they are NOT component hooks; recorded here for\n * fetch-axis classification. */\n agentTools: AgentToolInfo[];\n /**\n * Binding names declared in `clientCapabilities.gadgets`. The\n * `requestKeys` field is always empty — gadgets are\n * declaration-only.\n */\n clientCapabilities: AgentToolInfo[];\n /** Top-level arr<obj> props with inferred idField. */\n entityLists: EntityList[];\n /** Top-level object props with an id field (singleton entities). */\n singletons: SingletonEntity[];\n hasArrObjAnywhere: boolean;\n hasGeoCoords: boolean;\n /**\n * Any action payload references an entity-id matching an arr<obj> prop.\n * NOTE: singleton id-refs are excluded — they don't count as per-item.\n */\n entityListIdInPayload: boolean;\n /** Any action payload references an id-suffix key matching a singleton prop. */\n singletonIdInPayload: boolean;\n /** Any single action payload references keys matching ≥ 2 different entity lists. */\n crossEntityAction: boolean;\n /** Any action payload has ≥ 3 scalar keys at top level. */\n multiFieldSubmit: boolean;\n /** Count of top-level scalar-typed props (string/number/boolean). */\n topLevelScalarCount: number;\n /** Any entity list's items carry 2D grid coordinates (row+col or x+y). */\n entitiesHaveGridPositions: boolean;\n}\n\nexport function inspect(contract: ClassifierInput): ContractSignals {\n const empty: ContractSignals = {\n actions: [],\n streams: [],\n agentTools: [],\n clientCapabilities: [],\n entityLists: [],\n singletons: [],\n hasArrObjAnywhere: false,\n hasGeoCoords: false,\n entityListIdInPayload: false,\n singletonIdInPayload: false,\n crossEntityAction: false,\n multiFieldSubmit: false,\n topLevelScalarCount: 0,\n entitiesHaveGridPositions: false,\n };\n if (!contract) return empty;\n\n const propsField = contract.propsSpec as\n | { properties?: Record<string, unknown> }\n | undefined;\n const propsProps = propsField?.properties ?? {};\n\n // Entity lists (top-level arr<obj>)\n const entityLists: EntityList[] = [];\n for (const [name, p] of Object.entries(propsProps)) {\n const t = propType(p);\n const items = itemShape(p);\n if (t === \"array\" && items?.type === \"object\") {\n const itemProps = items.properties ?? {};\n entityLists.push({\n name,\n singular: singularize(name),\n idField: inferIdField(itemProps),\n itemKeys: Object.keys(itemProps),\n });\n }\n }\n\n // Singleton entities (top-level object props with an identifiable id key)\n const singletons: SingletonEntity[] = [];\n for (const [name, p] of Object.entries(propsProps)) {\n const t = propType(p);\n if (t === \"object\") {\n const childProps = propertiesOf(p) ?? {};\n const keys = Object.keys(childProps);\n if (keys.length > 0) {\n singletons.push({ name, keys });\n }\n }\n }\n\n // Actions — flat `Record<name, ActionEntry>`.\n const actionsMap =\n (contract.actionSpec as Record<string, unknown> | undefined) ?? {};\n const actions: ActionEntryInfo[] = [];\n for (const [name, action] of Object.entries(actionsMap)) {\n const a = action as { example?: Record<string, unknown>; nextStep?: string };\n const scalarKeys = scalarKeyCount(a?.example);\n const allKeys = allTopLevelKeys(a?.example);\n const referencedEntities = referencedEntitiesForPayload(\n allKeys,\n entityLists,\n singletons,\n );\n actions.push({\n name,\n nextStep: a?.nextStep,\n example: a?.example,\n scalarKeys,\n allKeys,\n referencedEntities,\n });\n }\n\n // Streams — each declared channel on the live render plane. Flat\n // `Record<name, StreamChannelEntry>`. Uses the real protocol type\n // (not `Record<string, unknown>`) so the iteration walks typed\n // entries.\n const channelsMap: Record<string, StreamChannelEntry> =\n (contract.streamSpec as Record<string, StreamChannelEntry> | undefined) ??\n {};\n const streams: Array<{ name: string; schema?: SchemaShape }> = [];\n for (const [name, channel] of Object.entries(channelsMap)) {\n // `StreamChannelEntry.schema` is `JsonSchema`, which structurally\n // satisfies the local `SchemaShape` (JsonSchema is a superset).\n streams.push({ name, schema: channel.schema as SchemaShape });\n }\n\n // agentCapabilities.tools — the agent-side tool catalog\n const agentToolsMap =\n ((contract.agentCapabilities as { tools?: Record<string, unknown> } | undefined)\n ?.tools) ?? {};\n const agentTools: AgentToolInfo[] = [];\n for (const [name, tool] of Object.entries(agentToolsMap)) {\n const t = tool as { toolInfo?: { inputSchema?: SchemaShape } };\n const req = t?.toolInfo?.inputSchema?.properties ?? {};\n agentTools.push({ name, requestKeys: Object.keys(req) });\n }\n\n // clientCapabilities.gadgets — pure declaration; `requestKeys` is\n // always empty (gadgets don't carry an inputSchema).\n const gadgetsMap = contract.clientCapabilities?.gadgets ?? {};\n const clientCapabilities: AgentToolInfo[] = [];\n for (const name of Object.keys(gadgetsMap)) {\n clientCapabilities.push({ name, requestKeys: [] });\n }\n\n // Derived flags\n const hasArrObjAnywhere = walkForArrObj({ properties: propsProps });\n const hasGeoCoords = hasGeoCoordsRecursive({ properties: propsProps });\n\n const entityListNames = new Set(entityLists.map((e) => e.name));\n const entityListIdInPayload = actions.some((a) =>\n a.referencedEntities.some((r) => entityListNames.has(r)),\n );\n const singletonIdInPayload = actions.some((a) =>\n a.referencedEntities.some((r) => r.startsWith(\"__singleton:\")),\n );\n const crossEntityAction = actions.some((a) => {\n const entityRefs = a.referencedEntities.filter((r) =>\n entityListNames.has(r),\n );\n return new Set(entityRefs).size >= 2;\n });\n const multiFieldSubmit = actions.some((a) => a.scalarKeys.length >= 3);\n\n // Top-level scalar prop count\n let topLevelScalarCount = 0;\n for (const v of Object.values(propsProps)) {\n const t = propType(v);\n if (t === \"string\" || t === \"number\" || t === \"boolean\") topLevelScalarCount++;\n }\n\n // Entity lists with 2D grid coordinates\n const entitiesHaveGridPositions = entityLists.some((e) => {\n const keys = e.itemKeys;\n return (\n (keys.includes(\"row\") && keys.includes(\"col\")) ||\n (keys.includes(\"x\") && keys.includes(\"y\") && keys.length > 2) ||\n (keys.includes(\"gridRow\") && keys.includes(\"gridColumn\"))\n );\n });\n\n return {\n actions,\n streams,\n agentTools,\n clientCapabilities,\n entityLists,\n singletons,\n hasArrObjAnywhere,\n hasGeoCoords,\n entityListIdInPayload,\n singletonIdInPayload,\n crossEntityAction,\n multiFieldSubmit,\n topLevelScalarCount,\n entitiesHaveGridPositions,\n };\n}\n","// packages/ui-gen/src/classifier/infer-state.ts\n\nimport type { AxisSource, StateShape } from \"./axes\";\nimport type { ContractSignals } from \"./inspect\";\n\n// Intentionally excludes 'current' (false-matches \"Current temperature\").\n// Each keyword should imply meaningful local state.\nconst AFFORDANCE_KEYWORDS =\n /\\b(search\\b|filter\\b|sort\\b|select\\b|tabs?\\b|quantity\\b|paginat|expand(ed|able)?|collaps|click(?:s|ing|ed)?\\s+(an|a|the)\\s+\\w+\\s*→?\\s*detail|click\\s+to\\s+(select|open|view))/i;\n\nexport function inferState(\n s: ContractSignals,\n prompt: string,\n): { value: StateShape; source: AxisSource } {\n // Payload assembly: single action with multi-scalar payload, no entity ref\n if (\n s.actions.length === 1 &&\n s.multiFieldSubmit &&\n !s.entityListIdInPayload &&\n !s.singletonIdInPayload\n ) {\n return { value: \"payload\", source: \"contract\" };\n }\n\n // Live merge: streams exist\n if (s.streams.length > 0) {\n return { value: \"merge\", source: \"contract\" };\n }\n\n // Live merge: entity list with mutating action (optimistic update)\n if (s.entityLists.length > 0 && s.entityListIdInPayload) {\n return { value: \"merge\", source: \"contract\" };\n }\n\n // UI affordance: prompt signals search / filter / select / tab / quantity\n if (AFFORDANCE_KEYWORDS.test(prompt)) {\n return { value: \"ui-affordance\", source: \"prompt\" };\n }\n\n // Single action without explicit affordance signal — assume some small\n // state (e.g., disabled flag, commit draft) via heuristic.\n if (s.actions.length >= 1) {\n return { value: \"ui-affordance\", source: \"heuristic\" };\n }\n\n return { value: \"none\", source: \"contract\" };\n}\n","// packages/ui-gen/src/classifier/infer-writes.ts\n\nimport type { AxisSource, WriteShape } from \"./axes\";\nimport type { ContractSignals } from \"./inspect\";\n\nexport function inferWrites(\n s: ContractSignals,\n): { value: WriteShape; source: AxisSource } {\n if (s.actions.length === 0) {\n return { value: \"none\", source: \"contract\" };\n }\n\n // Compose: one action payload references ≥ 2 different entity collections\n if (s.crossEntityAction) {\n return { value: \"compose\", source: \"contract\" };\n }\n\n // Per-item: actions target an entity LIST via id. Singleton id refs don't\n // count (that's just \"commit on a detail view\" like product-page's addToCart).\n if (s.entityListIdInPayload) {\n return { value: \"per-item\", source: \"contract\" };\n }\n\n // Submit: single action with multi-field payload\n if (s.actions.length === 1 && s.multiFieldSubmit) {\n return { value: \"submit\", source: \"contract\" };\n }\n\n // Multi-commit: multiple independent actions\n if (s.actions.length >= 2) {\n return { value: \"multi-commit\", source: \"contract\" };\n }\n\n return { value: \"commit\", source: \"contract\" };\n}\n","// packages/ui-gen/src/classifier/infer-realtime.ts\n\nimport type { AxisSource, RealtimeShape, StreamEventKind } from \"./axes\";\nimport type { ContractSignals } from \"./inspect\";\nimport { inferStreamKindFromSchema } from \"./inspect\";\n\nexport function inferRealtime(\n s: ContractSignals,\n): {\n value: RealtimeShape;\n streamKinds?: Record<string, StreamEventKind>;\n source: AxisSource;\n} {\n if (s.streams.length === 0) {\n return { value: \"none\", source: \"contract\" };\n }\n\n const kinds: Record<string, StreamEventKind> = {};\n for (const stream of s.streams) {\n kinds[stream.name] = inferStreamKindFromSchema(\n stream.schema,\n s.entityLists,\n s.singletons,\n );\n }\n\n const distinct = new Set(Object.values(kinds));\n\n if (distinct.size === 1) {\n const only = [...distinct][0];\n // 'other' as the only kind is too vague — surface it as 'mixed' w/ kinds\n // so downstream can still reason, rather than pretending we know.\n if (only === \"other\") {\n return { value: \"mixed\", streamKinds: kinds, source: \"contract\" };\n }\n return { value: only as RealtimeShape, source: \"contract\" };\n }\n\n return { value: \"mixed\", streamKinds: kinds, source: \"contract\" };\n}\n","// packages/ui-gen/src/classifier/infer-fetch.ts\n\nimport type { AxisSource, FetchShape } from \"./axes\";\nimport type { ContractSignals } from \"./inspect\";\n\nconst PAGINATION_KEYS = new Set([\n \"cursor\",\n \"offset\",\n \"page\",\n \"before\",\n \"after\",\n \"limit\",\n \"pageSize\",\n]);\nconst SEARCH_KEYS = new Set([\"query\", \"q\", \"search\", \"keyword\"]);\n\nexport function inferFetch(\n s: ContractSignals,\n): { value: FetchShape; source: AxisSource } {\n // clientCapabilities are browser-capability hooks, not data-fetch.\n // Only agentTools participate in fetch classification.\n if (s.agentTools.length === 0) {\n return { value: \"none\", source: \"contract\" };\n }\n\n const tools = s.agentTools;\n\n for (const tool of tools) {\n for (const key of tool.requestKeys) {\n if (PAGINATION_KEYS.has(key)) return { value: \"pagination\", source: \"contract\" };\n }\n }\n\n for (const tool of tools) {\n for (const key of tool.requestKeys) {\n if (SEARCH_KEYS.has(key)) return { value: \"search\", source: \"contract\" };\n }\n }\n\n // Drill-down: any `id` key, any `*Id` suffix key, or any key matching\n // an entity's idField (e.g., `symbol` for stocks). Loose on purpose so\n // fetch tools targeting a specific entity are caught regardless of\n // whether the entity is in top-level props.\n const entityIdFields = new Set(s.entityLists.map((e) => e.idField));\n for (const tool of tools) {\n for (const key of tool.requestKeys) {\n if (key === \"id\") return { value: \"drill-down\", source: \"contract\" };\n if (/Id$/.test(key) && key.length > 2) {\n return { value: \"drill-down\", source: \"contract\" };\n }\n if (entityIdFields.has(key)) {\n return { value: \"drill-down\", source: \"contract\" };\n }\n }\n }\n\n return { value: \"refresh\", source: \"contract\" };\n}\n","// packages/ui-gen/src/classifier/infer-render.ts\n\nimport type { AxisSource, RenderShape } from \"./axes\";\nimport type { ContractSignals } from \"./inspect\";\n\ninterface BlueprintHint {\n mechanic?: import(\"@ggui-ai/protocol\").ScreenMechanic;\n layoutHint?: string;\n}\n\nconst CHART_RX = /\\b(chart|graph|trend|bar\\s*graph|line\\s*graph|pie)\\b/i;\nconst TIMELINE_RX = /\\b(timeline|chronolog|activity\\s*feed|event\\s*feed)\\b/i;\n// Tightened: require explicit grid/tile/column-count terminology.\n// Includes bare 'grid' word (matches \"grid of cards\", \"CSS grid\", etc.)\n// but is bounded to avoid matching \"grid\" as a substring of \"background\".\nconst GRID_RX = /\\bgrid\\b|\\btile\\s*layout\\b|\\b\\d+\\s*columns\\b|\\bkanban\\b|\\bcolumns?\\s*:/i;\nconst MAP_RX = /\\b(on\\s*a\\s*map|on\\s*the\\s*map|geo|gps|lat\\/lng)\\b/i;\nconst MASTER_DETAIL_RX =\n /\\b(left\\s*pane|right\\s*pane|sidebar|master[- ]detail|split\\s*view|two[- ]pane)\\b/i;\n// Tightened: 'card' and 'profile' are too generic (match weather-card,\n// product-page, etc. false-positively). Only explicit card-stack phrases.\nconst STATIC_RX =\n /\\b(card\\s*stack|card\\s*deck|one\\s*(card|email|message|item)\\s*at\\s*a\\s*time|full[- ]screen\\s*card)\\b/i;\n\nexport function inferRender(\n s: ContractSignals,\n prompt: string,\n blueprint: BlueprintHint | undefined,\n): { value: RenderShape; source: AxisSource } {\n // Blueprint layoutHint — most specific\n if (blueprint?.layoutHint) {\n const hint = blueprint.layoutHint.toLowerCase();\n if (hint.includes(\"master-detail\") || hint.includes(\"split\"))\n return { value: \"master-detail\", source: \"blueprint\" };\n if (hint.includes(\"card-stack\") || hint.includes(\"deck\") || hint.includes(\"modal\"))\n return { value: \"static\", source: \"blueprint\" };\n if (hint.includes(\"spatial\") || hint.includes(\"map\"))\n return { value: \"spatial\", source: \"blueprint\" };\n if (hint.includes(\"timeline\")) return { value: \"timeline\", source: \"blueprint\" };\n if (hint.includes(\"chart\")) return { value: \"chart\", source: \"blueprint\" };\n if (hint.includes(\"grid\")) return { value: \"grid\", source: \"blueprint\" };\n }\n\n // Contract: multiple geo-coord sources → spatial\n if (s.hasGeoCoords) {\n return { value: \"spatial\", source: \"contract\" };\n }\n\n // Contract: entity items carry 2D grid positions → grid\n if (s.entitiesHaveGridPositions) {\n return { value: \"grid\", source: \"contract\" };\n }\n\n // Prompt: explicit render keywords (before structural fallback)\n if (CHART_RX.test(prompt)) return { value: \"chart\", source: \"prompt\" };\n if (TIMELINE_RX.test(prompt)) return { value: \"timeline\", source: \"prompt\" };\n if (MASTER_DETAIL_RX.test(prompt))\n return { value: \"master-detail\", source: \"prompt\" };\n if (GRID_RX.test(prompt)) return { value: \"grid\", source: \"prompt\" };\n if (MAP_RX.test(prompt) && !s.hasGeoCoords)\n return { value: \"spatial\", source: \"prompt\" };\n if (STATIC_RX.test(prompt)) return { value: \"static\", source: \"prompt\" };\n\n // Contract fallbacks\n if (s.entityLists.length === 0) {\n return { value: \"static\", source: \"contract\" };\n }\n // Weather-card-like: scalars dominate the single arr<obj> sub-list.\n if (s.entityLists.length === 1 && s.topLevelScalarCount >= 4) {\n return { value: \"static\", source: \"contract\" };\n }\n if (s.entityLists.length >= 2) {\n return { value: \"master-detail\", source: \"contract\" };\n }\n return { value: \"list\", source: \"contract\" };\n}\n","// packages/ui-gen/src/classifier/infer-layout.ts\n\nimport type { AxisSource, LayoutShape } from \"./axes\";\nimport type { ContractSignals } from \"./inspect\";\n\ninterface BlueprintHint {\n mechanic?: import(\"@ggui-ai/protocol\").ScreenMechanic;\n layoutHint?: string;\n}\n\nconst OVERLAY_RX =\n /\\b(overlay|overlaid|on\\s*top|positioned\\s*over|floating\\s*action)\\b/i;\nconst MODAL_RX = /\\b(modal|dialog|sheet|drawer|card\\s*stack)\\b/i;\nconst MULTI_STEP_RX = /\\b(multi[- ]step|wizard|step\\s*\\d+|step\\s*\\d+\\s*:)/i;\nconst MASTER_DETAIL_RX =\n /\\b(left\\s*pane|right\\s*pane|left\\s*sidebar|right\\s*main|split\\s*view|two[- ]pane|master[- ]detail)\\b/i;\n\nexport function inferLayout(\n s: ContractSignals,\n prompt: string,\n blueprint: BlueprintHint | undefined,\n): { value: LayoutShape; source: AxisSource } {\n if (blueprint?.layoutHint) {\n const hint = blueprint.layoutHint.toLowerCase();\n if (hint.includes(\"master-detail\") || hint.includes(\"split\"))\n return { value: \"master-detail\", source: \"blueprint\" };\n if (hint.includes(\"modal\") || hint.includes(\"card-stack\") || hint.includes(\"deck\"))\n return { value: \"modal\", source: \"blueprint\" };\n if (hint.includes(\"overlay\")) return { value: \"overlay\", source: \"blueprint\" };\n if (hint.includes(\"multi-step\") || hint.includes(\"wizard\"))\n return { value: \"multi-step\", source: \"blueprint\" };\n }\n\n if (MULTI_STEP_RX.test(prompt)) return { value: \"multi-step\", source: \"prompt\" };\n if (OVERLAY_RX.test(prompt)) return { value: \"overlay\", source: \"prompt\" };\n if (MODAL_RX.test(prompt)) return { value: \"modal\", source: \"prompt\" };\n if (MASTER_DETAIL_RX.test(prompt))\n return { value: \"master-detail\", source: \"prompt\" };\n\n // Don't bother using s for now — layout is mostly prompt/blueprint driven.\n void s;\n\n return { value: \"single\", source: \"default\" };\n}\n","// packages/ui-gen/src/classifier/infer-trigger.ts\n\nimport type { AxisSource, WriteTrigger } from \"./axes\";\nimport type { ContractSignals } from \"./inspect\";\n\nconst DRAG_RX = /\\b(drag|drop|dragging|draggable)\\b/i;\nconst SWIPE_RX = /\\b(swipe|swipes|gesture\\s*stack)\\b/i;\nconst KEYBOARD_RX = /\\b(keyboard\\s*shortcut|hotkey|keystroke|kbd)\\b/i;\n\n// The blueprint hint no longer participates: the mechanics that once\n// carried a trigger signal (drag/swipe) were deleted from ScreenMechanic\n// in draft-2026-06-12; static/live/form say nothing about triggers.\nexport function inferWriteTrigger(\n s: ContractSignals,\n prompt: string,\n): { value: WriteTrigger; source: AxisSource } {\n // If there are no actions at all, trigger is irrelevant — default to 'click'\n // but mark source as 'default' to convey that the value isn't load-bearing.\n if (s.actions.length === 0) {\n return { value: \"click\", source: \"default\" };\n }\n\n // Prompt signals\n if (DRAG_RX.test(prompt)) return { value: \"drag\", source: \"prompt\" };\n if (SWIPE_RX.test(prompt)) return { value: \"swipe\", source: \"prompt\" };\n if (KEYBOARD_RX.test(prompt)) return { value: \"keystroke\", source: \"prompt\" };\n\n return { value: \"click\", source: \"default\" };\n}\n","// packages/ui-gen/src/classifier/infer-tooling.ts\n//\n// tooling axis — derived purely from contract presence of\n// `agentCapabilities.tools` / `clientCapabilities.gadgets`.\n// Describes the *direction* of tool usage present on the contract:\n// wired = UI references an agent tool, client = UI declares a\n// browser-capability gadget hook.\n\nimport type { AxisSource, ToolingShape } from \"./axes\";\nimport type { ContractSignals } from \"./inspect\";\n\nexport function inferTooling(\n s: ContractSignals,\n): { value: ToolingShape; source: AxisSource } {\n const hasAgent = s.agentTools.length > 0;\n const hasClient = s.clientCapabilities.length > 0;\n if (hasAgent && hasClient) return { value: \"both\", source: \"contract\" };\n // \"wired\" / \"client\" axis-shape names are retained for backward\n // compatibility with downstream classifiers — the underlying signal is\n // now \"the contract declares agent-side tools\" (wired) vs \"the\n // contract declares client-side capabilities\" (client).\n if (hasAgent) return { value: \"wired\", source: \"contract\" };\n if (hasClient) return { value: \"client\", source: \"contract\" };\n return { value: \"none\", source: \"default\" };\n}\n","// packages/ui-gen/src/classifier/risk-tier.ts\n\nimport type { AxisVector, RiskTier } from \"./axes\";\n\n/**\n * Derive risk tier from an AxisVector. Policy, not description — drives the\n * eval loop's depth and repair budget. Kept coarse and easy to revise.\n *\n * See AXIS_VECTOR_SKETCH.md §riskTier.\n */\nexport function deriveRiskTier(v: AxisVector): RiskTier {\n // High auto-promotions: ggui's moat scenarios\n if (v.writes === \"compose\") return \"high\";\n if (v.writeTrigger === \"drag\" || v.writeTrigger === \"swipe\") return \"high\";\n if (v.realtime === \"mixed\") return \"high\";\n if (v.render === \"spatial\" && v.realtime !== \"none\") return \"high\";\n if (v.state === \"merge\" && v.writes === \"per-item\") return \"high\";\n\n // The tooling axis is intentionally NOT a tier-promotion input.\n // Combos like tooling=both + state=merge might deserve \"high\", but\n // tier promotion costs staged-process turns on every affected\n // generation — premature without a concrete observed regression.\n // Revisit if a tooling-heavy fixture underperforms on the medium tier.\n\n // Low: tightened pure-passive rule (matches display bypass)\n if (\n (v.state === \"none\" || v.state === \"ui-affordance\") &&\n v.writes === \"none\" &&\n v.realtime === \"none\" &&\n v.fetch === \"none\"\n ) {\n return \"low\";\n }\n\n return \"medium\";\n}\n","// packages/ui-gen/src/classifier/classifier.ts\n//\n// Multi-axis classifier orchestrator. Composes per-axis inference and risk\n// tier into a Classification. Pure function, no side effects.\n\nimport type {\n AxisProvenance,\n AxisVector,\n Classification,\n} from \"./axes\";\nimport { inspect, type ClassifierInput } from \"./inspect\";\nimport { inferState } from \"./infer-state\";\nimport { inferWrites } from \"./infer-writes\";\nimport { inferRealtime } from \"./infer-realtime\";\nimport { inferFetch } from \"./infer-fetch\";\nimport { inferRender } from \"./infer-render\";\nimport { inferLayout } from \"./infer-layout\";\nimport { inferWriteTrigger } from \"./infer-trigger\";\nimport { inferTooling } from \"./infer-tooling\";\nimport { deriveRiskTier } from \"./risk-tier\";\n\nexport interface ClassifyInput {\n contract: ClassifierInput;\n prompt?: string;\n blueprint?: {\n mechanic?: import(\"@ggui-ai/protocol\").ScreenMechanic;\n layoutHint?: string;\n };\n}\n\nexport function classifyAxes(input: ClassifyInput): Classification {\n const s = inspect(input.contract);\n const prompt = input.prompt ?? \"\";\n const blueprint = input.blueprint;\n\n const state = inferState(s, prompt);\n const writes = inferWrites(s);\n const realtime = inferRealtime(s);\n const fetch = inferFetch(s);\n const render = inferRender(s, prompt, blueprint);\n const layout = inferLayout(s, prompt, blueprint);\n const writeTrigger = inferWriteTrigger(s, prompt);\n const tooling = inferTooling(s);\n\n const vector: AxisVector = {\n render: render.value,\n state: state.value,\n writes: writes.value,\n writeTrigger: writeTrigger.value,\n realtime: realtime.value,\n fetch: fetch.value,\n layout: layout.value,\n tooling: tooling.value,\n };\n if (realtime.streamKinds) {\n vector.streamKinds = realtime.streamKinds;\n }\n\n const provenance: AxisProvenance = {\n render: render.source,\n state: state.source,\n writes: writes.source,\n writeTrigger: writeTrigger.source,\n realtime: realtime.source,\n fetch: fetch.source,\n layout: layout.source,\n tooling: tooling.source,\n };\n\n const riskTier = deriveRiskTier(vector);\n\n return { vector, provenance, riskTier };\n}\n"]}