@xemahq/ui-kernel 0.10.0 → 0.11.1

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 (379) hide show
  1. package/dist/lib/biome-host/agent-validation.d.ts.map +1 -1
  2. package/dist/lib/biome-host/agent-validation.js +26 -13
  3. package/dist/lib/biome-host/agent-validation.js.map +1 -1
  4. package/dist/lib/biome-host/biome-registry.d.ts.map +1 -1
  5. package/dist/lib/biome-host/biome-registry.js +27 -10
  6. package/dist/lib/biome-host/biome-registry.js.map +1 -1
  7. package/dist/lib/biome-host/biome-scope-hooks.d.ts.map +1 -1
  8. package/dist/lib/biome-host/biome-scope-hooks.js +2 -1
  9. package/dist/lib/biome-host/biome-scope-hooks.js.map +1 -1
  10. package/dist/lib/biome-host/biome-scoped-query.d.ts.map +1 -1
  11. package/dist/lib/biome-host/biome-scoped-query.js +5 -3
  12. package/dist/lib/biome-host/biome-scoped-query.js.map +1 -1
  13. package/dist/lib/biome-host/frontend-biome.d.ts +1 -1
  14. package/dist/lib/biome-host/frontend-biome.d.ts.map +1 -1
  15. package/dist/lib/biome-host/host-bridge.d.ts +1 -1
  16. package/dist/lib/biome-host/host-bridge.d.ts.map +1 -1
  17. package/dist/lib/biome-host/host-bridge.js.map +1 -1
  18. package/dist/lib/biome-host/i18n-hooks.d.ts.map +1 -1
  19. package/dist/lib/biome-host/i18n-hooks.js.map +1 -1
  20. package/dist/lib/biome-host/realtime-hooks.d.ts.map +1 -1
  21. package/dist/lib/biome-host/realtime-hooks.js.map +1 -1
  22. package/dist/lib/biome-host/session-contributions.d.ts +1 -1
  23. package/dist/lib/biome-host/session-contributions.d.ts.map +1 -1
  24. package/dist/lib/biome-host/use-mutation-with-error-toast.d.ts.map +1 -1
  25. package/dist/lib/biome-host/use-mutation-with-error-toast.js +3 -2
  26. package/dist/lib/biome-host/use-mutation-with-error-toast.js.map +1 -1
  27. package/dist/lib/biome-host/use-page-state.d.ts.map +1 -1
  28. package/dist/lib/biome-host/use-page-state.js +19 -10
  29. package/dist/lib/biome-host/use-page-state.js.map +1 -1
  30. package/dist/lib/capabilities/capability-provider.d.ts +1 -1
  31. package/dist/lib/capabilities/capability-provider.d.ts.map +1 -1
  32. package/dist/lib/capabilities/capability-provider.js +2 -2
  33. package/dist/lib/capabilities/capability-provider.js.map +1 -1
  34. package/dist/lib/capabilities/use-capability.d.ts +1 -1
  35. package/dist/lib/capabilities/use-capability.d.ts.map +1 -1
  36. package/dist/lib/capabilities/use-capability.js +2 -1
  37. package/dist/lib/capabilities/use-capability.js.map +1 -1
  38. package/dist/lib/contribution-registry/contribution-registry.d.ts.map +1 -1
  39. package/dist/lib/contribution-registry/contribution-registry.js +2 -1
  40. package/dist/lib/contribution-registry/contribution-registry.js.map +1 -1
  41. package/dist/lib/system-bus/deeplink.d.ts.map +1 -1
  42. package/dist/lib/system-bus/deeplink.js +4 -2
  43. package/dist/lib/system-bus/deeplink.js.map +1 -1
  44. package/dist/lib/system-bus/host-ports.d.ts +2 -2
  45. package/dist/lib/system-bus/host-ports.d.ts.map +1 -1
  46. package/dist/lib/system-bus/intent-registry.d.ts.map +1 -1
  47. package/dist/lib/system-bus/intent-registry.js +6 -3
  48. package/dist/lib/system-bus/intent-registry.js.map +1 -1
  49. package/dist/lib/system-bus/intents.d.ts +1 -1
  50. package/dist/lib/system-bus/intents.d.ts.map +1 -1
  51. package/dist/lib/system-bus/palette.d.ts +1 -1
  52. package/dist/lib/system-bus/palette.d.ts.map +1 -1
  53. package/dist/lib/system-bus/system-bus-builder.d.ts.map +1 -1
  54. package/dist/lib/system-bus/system-bus-builder.js +1 -1
  55. package/dist/lib/system-bus/system-bus-builder.js.map +1 -1
  56. package/dist/lib/system-bus/windows.d.ts +1 -1
  57. package/dist/lib/system-bus/windows.d.ts.map +1 -1
  58. package/dist/offline/outbox.d.ts +1 -0
  59. package/dist/offline/outbox.d.ts.map +1 -1
  60. package/dist/offline/outbox.js +4 -1
  61. package/dist/offline/outbox.js.map +1 -1
  62. package/dist/offline/react-hooks.d.ts +1 -1
  63. package/dist/offline/react-hooks.d.ts.map +1 -1
  64. package/dist/offline/react-hooks.js.map +1 -1
  65. package/dist/org-db/components/DbResultTable.d.ts.map +1 -1
  66. package/dist/org-db/components/DbResultTable.js +15 -6
  67. package/dist/org-db/components/DbResultTable.js.map +1 -1
  68. package/dist/registry/lib/agent-validation-host.d.ts.map +1 -1
  69. package/dist/registry/lib/agent-validation-host.js +1 -1
  70. package/dist/registry/lib/agent-validation-host.js.map +1 -1
  71. package/dist/registry/lib/biome-slot.d.ts.map +1 -1
  72. package/dist/registry/lib/biome-slot.js +5 -3
  73. package/dist/registry/lib/biome-slot.js.map +1 -1
  74. package/dist/registry/lib/primitives/SessionEventCard.d.ts.map +1 -1
  75. package/dist/registry/lib/primitives/SessionEventCard.js +14 -2
  76. package/dist/registry/lib/primitives/SessionEventCard.js.map +1 -1
  77. package/dist/registry/lib/primitives/SessionEventTimeline.d.ts.map +1 -1
  78. package/dist/registry/lib/primitives/SessionEventTimeline.js +6 -3
  79. package/dist/registry/lib/primitives/SessionEventTimeline.js.map +1 -1
  80. package/dist/registry/lib/primitives/SessionTabbedDrawer.d.ts.map +1 -1
  81. package/dist/registry/lib/primitives/SessionTabbedDrawer.js +10 -5
  82. package/dist/registry/lib/primitives/SessionTabbedDrawer.js.map +1 -1
  83. package/dist/registry/lib/session-context-provider.d.ts +1 -1
  84. package/dist/registry/lib/session-context-provider.d.ts.map +1 -1
  85. package/dist/registry/lib/session-context-provider.js.map +1 -1
  86. package/dist/registry/lib/session-selectors.d.ts.map +1 -1
  87. package/dist/registry/lib/session-selectors.js +35 -20
  88. package/dist/registry/lib/session-selectors.js.map +1 -1
  89. package/dist/session/comments/CommentRail.d.ts.map +1 -1
  90. package/dist/session/comments/CommentRail.js.map +1 -1
  91. package/dist/session/shell/SessionWorkspaceShell.d.ts.map +1 -1
  92. package/dist/session/shell/SessionWorkspaceShell.js.map +1 -1
  93. package/dist/session-kit/approvals/ApprovalCard.d.ts.map +1 -1
  94. package/dist/session-kit/approvals/ApprovalCard.js +6 -2
  95. package/dist/session-kit/approvals/ApprovalCard.js.map +1 -1
  96. package/dist/session-kit/approvals/ApprovalsCenter.d.ts.map +1 -1
  97. package/dist/session-kit/approvals/ApprovalsCenter.js +6 -3
  98. package/dist/session-kit/approvals/ApprovalsCenter.js.map +1 -1
  99. package/dist/session-kit/combobox/Combobox.d.ts.map +1 -1
  100. package/dist/session-kit/combobox/Combobox.js +20 -6
  101. package/dist/session-kit/combobox/Combobox.js.map +1 -1
  102. package/dist/session-kit/display/MD.d.ts.map +1 -1
  103. package/dist/session-kit/display/MD.js +7 -4
  104. package/dist/session-kit/display/MD.js.map +1 -1
  105. package/dist/ui/branding/app-branding-provider.d.ts.map +1 -1
  106. package/dist/ui/branding/app-branding-provider.js.map +1 -1
  107. package/dist/ui/branding/sanitize.d.ts.map +1 -1
  108. package/dist/ui/branding/sanitize.js +12 -6
  109. package/dist/ui/branding/sanitize.js.map +1 -1
  110. package/dist/ui/capture/document-preview.d.ts +1 -1
  111. package/dist/ui/capture/document-preview.d.ts.map +1 -1
  112. package/dist/ui/capture/document-preview.js +8 -6
  113. package/dist/ui/capture/document-preview.js.map +1 -1
  114. package/dist/ui/capture/field-spec-to-zod.d.ts.map +1 -1
  115. package/dist/ui/capture/field-spec-to-zod.js +45 -16
  116. package/dist/ui/capture/field-spec-to-zod.js.map +1 -1
  117. package/dist/ui/capture/field-spec-validate.d.ts.map +1 -1
  118. package/dist/ui/capture/field-spec-validate.js +79 -38
  119. package/dist/ui/capture/field-spec-validate.js.map +1 -1
  120. package/dist/ui/capture/field-spec.d.ts.map +1 -1
  121. package/dist/ui/capture/field-spec.js +17 -6
  122. package/dist/ui/capture/field-spec.js.map +1 -1
  123. package/dist/ui/capture/schema-field-input.d.ts.map +1 -1
  124. package/dist/ui/capture/schema-field-input.js +23 -18
  125. package/dist/ui/capture/schema-field-input.js.map +1 -1
  126. package/dist/ui/capture/schema-form.d.ts +1 -1
  127. package/dist/ui/capture/schema-form.d.ts.map +1 -1
  128. package/dist/ui/capture/schema-form.js +7 -6
  129. package/dist/ui/capture/schema-form.js.map +1 -1
  130. package/dist/ui/capture/use-prefill.d.ts.map +1 -1
  131. package/dist/ui/capture/use-prefill.js +32 -14
  132. package/dist/ui/capture/use-prefill.js.map +1 -1
  133. package/dist/ui/capture/use-schema-validation.d.ts +1 -1
  134. package/dist/ui/capture/use-schema-validation.d.ts.map +1 -1
  135. package/dist/ui/capture/use-schema-validation.js +13 -8
  136. package/dist/ui/capture/use-schema-validation.js.map +1 -1
  137. package/dist/ui/capture/use-wizard.d.ts.map +1 -1
  138. package/dist/ui/capture/use-wizard.js +23 -8
  139. package/dist/ui/capture/use-wizard.js.map +1 -1
  140. package/dist/ui/capture/value-format.d.ts.map +1 -1
  141. package/dist/ui/capture/value-format.js +6 -3
  142. package/dist/ui/capture/value-format.js.map +1 -1
  143. package/dist/ui/capture/wizard.d.ts.map +1 -1
  144. package/dist/ui/capture/wizard.js +3 -3
  145. package/dist/ui/capture/wizard.js.map +1 -1
  146. package/dist/ui/charts/bar-chart.d.ts +1 -1
  147. package/dist/ui/charts/bar-chart.d.ts.map +1 -1
  148. package/dist/ui/charts/bar-chart.js +1 -1
  149. package/dist/ui/charts/bar-chart.js.map +1 -1
  150. package/dist/ui/charts/chart-frame.d.ts +2 -2
  151. package/dist/ui/charts/chart-frame.d.ts.map +1 -1
  152. package/dist/ui/charts/chart-frame.js +4 -3
  153. package/dist/ui/charts/chart-frame.js.map +1 -1
  154. package/dist/ui/charts/chart-utils.d.ts.map +1 -1
  155. package/dist/ui/charts/chart-utils.js +32 -14
  156. package/dist/ui/charts/chart-utils.js.map +1 -1
  157. package/dist/ui/charts/donut-chart.d.ts +1 -1
  158. package/dist/ui/charts/donut-chart.d.ts.map +1 -1
  159. package/dist/ui/charts/donut-chart.js +7 -3
  160. package/dist/ui/charts/donut-chart.js.map +1 -1
  161. package/dist/ui/charts/line-chart.d.ts +1 -1
  162. package/dist/ui/charts/line-chart.d.ts.map +1 -1
  163. package/dist/ui/charts/line-chart.js +7 -4
  164. package/dist/ui/charts/line-chart.js.map +1 -1
  165. package/dist/ui/charts/sparkline.d.ts +1 -1
  166. package/dist/ui/charts/sparkline.d.ts.map +1 -1
  167. package/dist/ui/charts/sparkline.js +10 -6
  168. package/dist/ui/charts/sparkline.js.map +1 -1
  169. package/dist/ui/chrome/AsyncBoundary.d.ts +2 -2
  170. package/dist/ui/chrome/AsyncBoundary.d.ts.map +1 -1
  171. package/dist/ui/chrome/AsyncBoundary.js +3 -3
  172. package/dist/ui/chrome/AsyncBoundary.js.map +1 -1
  173. package/dist/ui/chrome/EmptyState.d.ts +19 -8
  174. package/dist/ui/chrome/EmptyState.d.ts.map +1 -1
  175. package/dist/ui/chrome/EmptyState.js +6 -4
  176. package/dist/ui/chrome/EmptyState.js.map +1 -1
  177. package/dist/ui/chrome/RecordCardList.d.ts +19 -0
  178. package/dist/ui/chrome/RecordCardList.d.ts.map +1 -0
  179. package/dist/ui/chrome/RecordCardList.js +12 -0
  180. package/dist/ui/chrome/RecordCardList.js.map +1 -0
  181. package/dist/ui/chrome/page-shell.d.ts +1 -1
  182. package/dist/ui/chrome/page-shell.d.ts.map +1 -1
  183. package/dist/ui/chrome/page-shell.js +16 -5
  184. package/dist/ui/chrome/page-shell.js.map +1 -1
  185. package/dist/ui/chrome/status-badge.d.ts.map +1 -1
  186. package/dist/ui/chrome/status-badge.js +1 -1
  187. package/dist/ui/chrome/status-badge.js.map +1 -1
  188. package/dist/ui/design-tokens.d.ts +4 -6
  189. package/dist/ui/design-tokens.d.ts.map +1 -1
  190. package/dist/ui/design-tokens.js +17 -11
  191. package/dist/ui/design-tokens.js.map +1 -1
  192. package/dist/ui/index.d.ts +1 -0
  193. package/dist/ui/index.d.ts.map +1 -1
  194. package/dist/ui/index.js +1 -0
  195. package/dist/ui/index.js.map +1 -1
  196. package/dist/ui/primitives/async-combobox.d.ts.map +1 -1
  197. package/dist/ui/primitives/async-combobox.js +4 -2
  198. package/dist/ui/primitives/async-combobox.js.map +1 -1
  199. package/dist/ui/primitives/badge.d.ts +2 -2
  200. package/dist/ui/primitives/badge.d.ts.map +1 -1
  201. package/dist/ui/primitives/badge.js +3 -3
  202. package/dist/ui/primitives/badge.js.map +1 -1
  203. package/dist/ui/primitives/button.d.ts +2 -2
  204. package/dist/ui/primitives/button.d.ts.map +1 -1
  205. package/dist/ui/primitives/button.js +5 -5
  206. package/dist/ui/primitives/button.js.map +1 -1
  207. package/dist/ui/primitives/overflow-tabs.d.ts.map +1 -1
  208. package/dist/ui/primitives/overflow-tabs.js +19 -12
  209. package/dist/ui/primitives/overflow-tabs.js.map +1 -1
  210. package/dist/ui/primitives/preview-device-frame.js +8 -4
  211. package/dist/ui/primitives/preview-device-frame.js.map +1 -1
  212. package/dist/ui/primitives/tag-multi-select.d.ts.map +1 -1
  213. package/dist/ui/primitives/tag-multi-select.js +10 -5
  214. package/dist/ui/primitives/tag-multi-select.js.map +1 -1
  215. package/dist/ui/primitives/url-preview-chrome.d.ts.map +1 -1
  216. package/dist/ui/primitives/url-preview-chrome.js.map +1 -1
  217. package/dist/vista/GenericCatalogueSurface.d.ts.map +1 -1
  218. package/dist/vista/GenericCatalogueSurface.js +5 -3
  219. package/dist/vista/GenericCatalogueSurface.js.map +1 -1
  220. package/dist/vista/VistaPanel.d.ts.map +1 -1
  221. package/dist/vista/VistaPanel.js +8 -4
  222. package/dist/vista/VistaPanel.js.map +1 -1
  223. package/dist/vista/html/CustomUiFrame.d.ts.map +1 -1
  224. package/dist/vista/html/CustomUiFrame.js +2 -1
  225. package/dist/vista/html/CustomUiFrame.js.map +1 -1
  226. package/dist/vista/html/custom-ui-frame-bridge.d.ts.map +1 -1
  227. package/dist/vista/html/custom-ui-frame-bridge.js +6 -3
  228. package/dist/vista/html/custom-ui-frame-bridge.js.map +1 -1
  229. package/dist/vista/html/custom-ui-intents.d.ts.map +1 -1
  230. package/dist/vista/html/custom-ui-intents.js +13 -15
  231. package/dist/vista/html/custom-ui-intents.js.map +1 -1
  232. package/dist/vista/surface-catalogue.d.ts.map +1 -1
  233. package/dist/vista/surface-catalogue.js +6 -3
  234. package/dist/vista/surface-catalogue.js.map +1 -1
  235. package/dist/vista/surfaces/FormSurface.d.ts.map +1 -1
  236. package/dist/vista/surfaces/FormSurface.js +20 -7
  237. package/dist/vista/surfaces/FormSurface.js.map +1 -1
  238. package/dist/vista/surfaces/TableSurface.d.ts.map +1 -1
  239. package/dist/vista/surfaces/TableSurface.js +2 -1
  240. package/dist/vista/surfaces/TableSurface.js.map +1 -1
  241. package/dist/vista/surfaces/blob-surfaces.d.ts.map +1 -1
  242. package/dist/vista/surfaces/blob-surfaces.js +7 -2
  243. package/dist/vista/surfaces/blob-surfaces.js.map +1 -1
  244. package/dist/vista/surfaces/elicitation-transport.d.ts.map +1 -1
  245. package/dist/vista/surfaces/elicitation-transport.js +14 -7
  246. package/dist/vista/surfaces/elicitation-transport.js.map +1 -1
  247. package/dist/vista/surfaces/file-surface-utils.d.ts.map +1 -1
  248. package/dist/vista/surfaces/file-surface-utils.js +8 -4
  249. package/dist/vista/surfaces/file-surface-utils.js.map +1 -1
  250. package/dist/vista/surfaces/register-surfaces.js +2 -1
  251. package/dist/vista/surfaces/register-surfaces.js.map +1 -1
  252. package/dist/vista/surfaces/text-surfaces.d.ts +1 -1
  253. package/dist/vista/surfaces/text-surfaces.d.ts.map +1 -1
  254. package/dist/vista/surfaces/text-surfaces.js +13 -7
  255. package/dist/vista/surfaces/text-surfaces.js.map +1 -1
  256. package/dist/vista/use-vista-tabs.d.ts.map +1 -1
  257. package/dist/vista/use-vista-tabs.js +8 -4
  258. package/dist/vista/use-vista-tabs.js.map +1 -1
  259. package/dist/vista/vista-code-renderer.d.ts.map +1 -1
  260. package/dist/vista/vista-code-renderer.js.map +1 -1
  261. package/dist/vista/vista-file-source.d.ts.map +1 -1
  262. package/dist/vista/vista-file-source.js +9 -5
  263. package/dist/vista/vista-file-source.js.map +1 -1
  264. package/dist/vista/vista-form-host.d.ts.map +1 -1
  265. package/dist/vista/vista-form-host.js +1 -1
  266. package/dist/vista/vista-form-host.js.map +1 -1
  267. package/dist/vista/vista-model.d.ts.map +1 -1
  268. package/dist/vista/vista-model.js +5 -3
  269. package/dist/vista/vista-model.js.map +1 -1
  270. package/dist/vista/vista-open-context.d.ts.map +1 -1
  271. package/dist/vista/vista-open-context.js +1 -1
  272. package/dist/vista/vista-open-context.js.map +1 -1
  273. package/dist/vista/vista-payloads.d.ts.map +1 -1
  274. package/dist/vista/vista-payloads.js +127 -63
  275. package/dist/vista/vista-payloads.js.map +1 -1
  276. package/dist/vista/vista-tabs-manifest.d.ts.map +1 -1
  277. package/dist/vista/vista-tabs-manifest.js +18 -9
  278. package/dist/vista/vista-tabs-manifest.js.map +1 -1
  279. package/dist/vista/vista-tools.d.ts.map +1 -1
  280. package/dist/vista/vista-tools.js +12 -6
  281. package/dist/vista/vista-tools.js.map +1 -1
  282. package/package.json +7 -4
  283. package/src/lib/biome-host/agent-validation.ts +37 -13
  284. package/src/lib/biome-host/biome-registry.ts +48 -13
  285. package/src/lib/biome-host/biome-scope-hooks.ts +3 -1
  286. package/src/lib/biome-host/biome-scoped-query.ts +7 -6
  287. package/src/lib/biome-host/frontend-biome.ts +1 -1
  288. package/src/lib/biome-host/host-bridge.ts +5 -4
  289. package/src/lib/biome-host/i18n-hooks.ts +1 -0
  290. package/src/lib/biome-host/realtime-hooks.ts +1 -0
  291. package/src/lib/biome-host/session-contributions.ts +1 -1
  292. package/src/lib/biome-host/use-mutation-with-error-toast.ts +4 -2
  293. package/src/lib/biome-host/use-page-state.ts +27 -10
  294. package/src/lib/capabilities/capability-provider.tsx +12 -5
  295. package/src/lib/capabilities/use-capability.ts +8 -4
  296. package/src/lib/contribution-registry/contribution-registry.ts +3 -1
  297. package/src/lib/system-bus/deeplink.ts +14 -4
  298. package/src/lib/system-bus/host-ports.ts +3 -7
  299. package/src/lib/system-bus/intent-registry.ts +12 -8
  300. package/src/lib/system-bus/intents.ts +6 -2
  301. package/src/lib/system-bus/palette.ts +2 -1
  302. package/src/lib/system-bus/system-bus-builder.ts +4 -2
  303. package/src/lib/system-bus/windows.ts +1 -1
  304. package/src/offline/outbox.test.ts +12 -3
  305. package/src/offline/outbox.ts +5 -1
  306. package/src/offline/react-hooks.ts +5 -2
  307. package/src/org-db/components/DbResultTable.tsx +48 -15
  308. package/src/registry/lib/agent-validation-host.ts +1 -2
  309. package/src/registry/lib/biome-slot.tsx +7 -4
  310. package/src/registry/lib/primitives/SessionEventCard.tsx +29 -5
  311. package/src/registry/lib/primitives/SessionEventTimeline.tsx +9 -3
  312. package/src/registry/lib/primitives/SessionTabbedDrawer.tsx +15 -5
  313. package/src/registry/lib/session-context-provider.tsx +1 -1
  314. package/src/registry/lib/session-selectors.ts +66 -27
  315. package/src/session/comments/CommentRail.tsx +2 -2
  316. package/src/session/shell/SessionWorkspaceShell.tsx +2 -2
  317. package/src/session-kit/approvals/ApprovalCard.tsx +7 -2
  318. package/src/session-kit/approvals/ApprovalsCenter.tsx +13 -4
  319. package/src/session-kit/combobox/Combobox.tsx +42 -11
  320. package/src/session-kit/display/MD.tsx +14 -5
  321. package/src/ui/branding/app-branding-provider.tsx +2 -3
  322. package/src/ui/branding/sanitize.ts +18 -6
  323. package/src/ui/capture/document-preview.tsx +84 -19
  324. package/src/ui/capture/field-spec-to-zod.ts +62 -14
  325. package/src/ui/capture/field-spec-validate.ts +132 -43
  326. package/src/ui/capture/field-spec.test.ts +2 -2
  327. package/src/ui/capture/field-spec.ts +41 -10
  328. package/src/ui/capture/schema-field-input.tsx +218 -38
  329. package/src/ui/capture/schema-form.tsx +54 -13
  330. package/src/ui/capture/use-prefill.ts +50 -17
  331. package/src/ui/capture/use-schema-validation.ts +45 -13
  332. package/src/ui/capture/use-wizard.ts +57 -11
  333. package/src/ui/capture/value-format.ts +14 -4
  334. package/src/ui/capture/wizard.tsx +9 -5
  335. package/src/ui/charts/bar-chart.tsx +8 -4
  336. package/src/ui/charts/chart-frame.tsx +18 -5
  337. package/src/ui/charts/chart-utils.ts +47 -15
  338. package/src/ui/charts/donut-chart.tsx +24 -6
  339. package/src/ui/charts/line-chart.tsx +34 -12
  340. package/src/ui/charts/sparkline.tsx +17 -9
  341. package/src/ui/chrome/AsyncBoundary.tsx +14 -6
  342. package/src/ui/chrome/EmptyState.tsx +116 -43
  343. package/src/ui/chrome/RecordCardList.tsx +98 -0
  344. package/src/ui/chrome/page-shell.spec.tsx +117 -0
  345. package/src/ui/chrome/page-shell.tsx +81 -25
  346. package/src/ui/chrome/status-badge.tsx +8 -4
  347. package/src/ui/design-tokens.ts +39 -13
  348. package/src/ui/index.ts +5 -0
  349. package/src/ui/primitives/async-combobox.tsx +7 -3
  350. package/src/ui/primitives/badge.tsx +14 -5
  351. package/src/ui/primitives/button.tsx +13 -6
  352. package/src/ui/primitives/overflow-tabs.tsx +46 -16
  353. package/src/ui/primitives/preview-device-frame.tsx +12 -4
  354. package/src/ui/primitives/tag-multi-select.tsx +30 -9
  355. package/src/ui/primitives/url-preview-chrome.tsx +1 -0
  356. package/src/vista/GenericCatalogueSurface.tsx +7 -5
  357. package/src/vista/VistaPanel.tsx +12 -4
  358. package/src/vista/html/CustomUiFrame.spec.tsx +3 -1
  359. package/src/vista/html/CustomUiFrame.tsx +3 -1
  360. package/src/vista/html/custom-ui-frame-bridge.ts +9 -3
  361. package/src/vista/html/custom-ui-intents.spec.ts +3 -1
  362. package/src/vista/html/custom-ui-intents.ts +19 -15
  363. package/src/vista/surface-catalogue.ts +9 -3
  364. package/src/vista/surfaces/FormSurface.tsx +27 -10
  365. package/src/vista/surfaces/TableSurface.tsx +4 -3
  366. package/src/vista/surfaces/blob-surfaces.tsx +13 -3
  367. package/src/vista/surfaces/elicitation-transport.ts +21 -7
  368. package/src/vista/surfaces/file-surface-utils.ts +11 -4
  369. package/src/vista/surfaces/register-surfaces.tsx +3 -1
  370. package/src/vista/surfaces/text-surfaces.tsx +21 -8
  371. package/src/vista/use-vista-tabs.ts +12 -4
  372. package/src/vista/vista-code-renderer.tsx +6 -5
  373. package/src/vista/vista-file-source.tsx +15 -14
  374. package/src/vista/vista-form-host.tsx +3 -8
  375. package/src/vista/vista-model.ts +10 -3
  376. package/src/vista/vista-open-context.tsx +3 -8
  377. package/src/vista/vista-payloads.ts +186 -63
  378. package/src/vista/vista-tabs-manifest.ts +28 -13
  379. package/src/vista/vista-tools.ts +18 -6
@@ -30,11 +30,15 @@ interface GenericSurfaceField {
30
30
  }
31
31
 
32
32
  function stringify(value: unknown): string {
33
- if (typeof value === 'string') return value;
33
+ if (typeof value === 'string') {
34
+ return value;
35
+ }
34
36
  if (typeof value === 'number' || typeof value === 'boolean') {
35
37
  return String(value);
36
38
  }
37
- if (value === null || value === undefined) return '—';
39
+ if (value === null || value === undefined) {
40
+ return '—';
41
+ }
38
42
  try {
39
43
  return JSON.stringify(value);
40
44
  } catch {
@@ -43,9 +47,7 @@ function stringify(value: unknown): string {
43
47
  }
44
48
 
45
49
  function isPlainObject(value: unknown): value is Record<string, unknown> {
46
- return (
47
- typeof value === 'object' && value !== null && !Array.isArray(value)
48
- );
50
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
49
51
  }
50
52
 
51
53
  /**
@@ -114,10 +114,16 @@ export function VistaTabBar({
114
114
  indicator?: boolean;
115
115
  icon?: OverflowTab['icon'];
116
116
  } = { value: tab.tabId, label: tab.title };
117
- if (tab.pinned === true) entry.pinned = true;
118
- if (indicatorTabIds?.includes(tab.tabId) === true) entry.indicator = true;
117
+ if (tab.pinned === true) {
118
+ entry.pinned = true;
119
+ }
120
+ if (indicatorTabIds?.includes(tab.tabId) === true) {
121
+ entry.indicator = true;
122
+ }
119
123
  const icon = surfaceKindIcon(tab.kind);
120
- if (icon !== undefined) entry.icon = icon;
124
+ if (icon !== undefined) {
125
+ entry.icon = icon;
126
+ }
121
127
  return entry;
122
128
  });
123
129
  return (
@@ -143,7 +149,9 @@ export function VistaSurfaceBody({
143
149
  tab,
144
150
  }: Readonly<{ tab: VistaTab }>): ReactElement {
145
151
  const resolution = vistaSurfaceRegistry.resolve(tab);
146
- if (resolution.matched) return resolution.rendered;
152
+ if (resolution.matched) {
153
+ return resolution.rendered;
154
+ }
147
155
  return (
148
156
  <SurfaceFallbackCard
149
157
  kind={resolution.kind}
@@ -34,7 +34,9 @@ const STYLE_CSS = ':root{--x:1}';
34
34
  function parseIframe(markup: string): Element {
35
35
  const doc = new DOMParser().parseFromString(markup, 'text/html');
36
36
  const iframe = doc.querySelector('iframe');
37
- if (!iframe) throw new Error('no iframe rendered');
37
+ if (!iframe) {
38
+ throw new Error('no iframe rendered');
39
+ }
38
40
  return iframe;
39
41
  }
40
42
 
@@ -153,7 +153,9 @@ export function CustomUiFrame<TIntent>({
153
153
  // re-render, per the HostProps contract). Before ready, the frameReady
154
154
  // handler above pushes the current props — so no update is lost.
155
155
  useEffect(() => {
156
- if (!readyRef.current) return;
156
+ if (!readyRef.current) {
157
+ return;
158
+ }
157
159
  iframeRef.current?.contentWindow?.postMessage(
158
160
  hostPropsMessage(componentProps),
159
161
  '*',
@@ -52,10 +52,14 @@ export function classifyFrameMessage<TIntent>(
52
52
  ): ClassifiedFrameMessage<TIntent> {
53
53
  // Gate 1: source identity. Reject if we have no frame yet or the message did
54
54
  // not come from THIS frame's window.
55
- if (frameWindow === null || event.source !== frameWindow) return IGNORED;
55
+ if (frameWindow === null || event.source !== frameWindow) {
56
+ return IGNORED;
57
+ }
56
58
 
57
59
  const data = event.data;
58
- if (data === null || typeof data !== 'object') return IGNORED;
60
+ if (data === null || typeof data !== 'object') {
61
+ return IGNORED;
62
+ }
59
63
  const envelope = data as {
60
64
  protocol?: unknown;
61
65
  type?: unknown;
@@ -64,7 +68,9 @@ export function classifyFrameMessage<TIntent>(
64
68
  };
65
69
 
66
70
  // Gate 2: protocol version.
67
- if (envelope.protocol !== CUSTOM_UI_FRAME_PROTOCOL) return IGNORED;
71
+ if (envelope.protocol !== CUSTOM_UI_FRAME_PROTOCOL) {
72
+ return IGNORED;
73
+ }
68
74
 
69
75
  // Gate 3: closed message-type set.
70
76
  switch (envelope.type) {
@@ -104,7 +104,9 @@ describe('createNavigateIntentSet', () => {
104
104
  kind: CustomUiIntentKind.Navigate,
105
105
  href: '/apps/x',
106
106
  });
107
- if (intent === null) throw new Error('expected a parsed navigate intent');
107
+ if (intent === null) {
108
+ throw new Error('expected a parsed navigate intent');
109
+ }
108
110
  set.perform(intent);
109
111
  expect(navigate).toHaveBeenCalledWith({
110
112
  kind: CustomUiIntentKind.Navigate,
@@ -72,13 +72,19 @@ export interface CustomUiIntentHandlers {
72
72
  */
73
73
  function isHostRelativePath(href: string): boolean {
74
74
  // Must be rooted at '/'.
75
- if (!href.startsWith('/')) return false;
75
+ if (!href.startsWith('/')) {
76
+ return false;
77
+ }
76
78
  // A backslash is a protocol-relative/scheme trick after WHATWG normalisation
77
79
  // ("/\\evil.com" -> //evil.com -> foreign origin); whitespace / control
78
80
  // chars can also confuse the parser. Reject any before resolving.
79
- if (href.includes('\\')) return false;
81
+ if (href.includes('\\')) {
82
+ return false;
83
+ }
80
84
  // eslint-disable-next-line no-control-regex
81
- if (/[\u0000-\u0020\u007f]/.test(href)) return false;
85
+ if (/[\u0000-\u0020\u007f]/.test(href)) {
86
+ return false;
87
+ }
82
88
  let resolved: URL;
83
89
  try {
84
90
  resolved = new URL(href, window.location.origin);
@@ -96,12 +102,18 @@ function isHostRelativePath(href: string): boolean {
96
102
  * an out-of-policy value all return `null` — the caller rejects it.
97
103
  */
98
104
  export function parseCustomUiIntent(raw: unknown): CustomUiIntent | null {
99
- if (raw === null || typeof raw !== 'object') return null;
105
+ if (raw === null || typeof raw !== 'object') {
106
+ return null;
107
+ }
100
108
  const candidate = raw as { kind?: unknown; href?: unknown };
101
109
  switch (candidate.kind) {
102
110
  case CustomUiIntentKind.Navigate:
103
- if (typeof candidate.href !== 'string') return null;
104
- if (!isHostRelativePath(candidate.href)) return null;
111
+ if (typeof candidate.href !== 'string') {
112
+ return null;
113
+ }
114
+ if (!isHostRelativePath(candidate.href)) {
115
+ return null;
116
+ }
105
117
  return { kind: CustomUiIntentKind.Navigate, href: candidate.href };
106
118
  default:
107
119
  return null;
@@ -118,15 +130,7 @@ export function performCustomUiIntent(
118
130
  intent: CustomUiIntent,
119
131
  handlers: CustomUiIntentHandlers,
120
132
  ): void {
121
- switch (intent.kind) {
122
- case CustomUiIntentKind.Navigate:
123
- handlers[CustomUiIntentKind.Navigate](intent);
124
- return;
125
- default: {
126
- const exhaustive: never = intent.kind;
127
- throw new Error(`Unhandled custom-UI intent kind: ${String(exhaustive)}`);
128
- }
129
- }
133
+ handlers[CustomUiIntentKind.Navigate](intent);
130
134
  }
131
135
 
132
136
  /** The built-in intent set: host-relative navigation and nothing else. */
@@ -55,16 +55,22 @@ export function __resetSurfaceCatalogueSyncForTests(): void {
55
55
  export async function syncSurfaceCatalogue(
56
56
  fetchCatalogue: SurfaceCatalogueFetcher,
57
57
  ): Promise<void> {
58
- if (synced) return;
58
+ if (synced) {
59
+ return;
60
+ }
59
61
  synced = true;
60
62
  try {
61
63
  const entries = await fetchCatalogue();
62
64
  for (const entry of entries) {
63
65
  // Only biome-contributed kinds need registering here; first-party kinds
64
66
  // are already registered by the static builtins.
65
- if (entry.source !== SurfaceKindSource.Biome) continue;
67
+ if (entry.source !== SurfaceKindSource.Biome) {
68
+ continue;
69
+ }
66
70
  // Never shadow a biome's own (or an already-registered) renderer.
67
- if (vistaSurfaceRegistry.has(entry.kind)) continue;
71
+ if (vistaSurfaceRegistry.has(entry.kind)) {
72
+ continue;
73
+ }
68
74
  vistaSurfaceRegistry.register(entry.kind, {
69
75
  version: entry.version,
70
76
  validate: (payload) =>
@@ -48,10 +48,7 @@ import { captureValuesToStringMap } from '../../ui/capture/submit-values';
48
48
  import { useSchemaValidation } from '../../ui/capture/use-schema-validation';
49
49
  import { cn } from '../../ui/cn';
50
50
  import { Button } from '../../ui/primitives/button';
51
- import {
52
- useVistaFormHost,
53
- type VistaFormOutcome,
54
- } from '../vista-form-context';
51
+ import { useVistaFormHost, type VistaFormOutcome } from '../vista-form-context';
55
52
 
56
53
  import type { CaptureValues } from '../../ui/capture/field-spec';
57
54
  import type { VistaFormPayload } from '../vista-payloads';
@@ -117,9 +114,13 @@ export function FormSurface(payload: Readonly<VistaFormPayload>): ReactElement {
117
114
  }, []);
118
115
 
119
116
  const handleSubmit = useCallback((): void => {
120
- if (host === null) return;
117
+ if (host === null) {
118
+ return;
119
+ }
121
120
  setShowFieldErrors(true);
122
- if (!isValid) return;
121
+ if (!isValid) {
122
+ return;
123
+ }
123
124
  setServiceError(null);
124
125
  setPhase(FormPhase.Working);
125
126
  // The values object is a PARAMETER here and nowhere else. It is never
@@ -138,7 +139,9 @@ export function FormSurface(payload: Readonly<VistaFormPayload>): ReactElement {
138
139
  }, [host, isValid, payload.fields, payload.ref, settle, failed, values]);
139
140
 
140
141
  const handleCheckStatus = useCallback((): void => {
141
- if (host === null) return;
142
+ if (host === null) {
143
+ return;
144
+ }
142
145
  setServiceError(null);
143
146
  setPhase(FormPhase.Working);
144
147
  void host
@@ -167,10 +170,24 @@ export function FormSurface(payload: Readonly<VistaFormPayload>): ReactElement {
167
170
  // an event, not a timer — there is no polling loop and no timeout.
168
171
  const isLaunch = payload.launch !== undefined;
169
172
  useEffect(() => {
170
- if (!isLaunch || phase === FormPhase.Settled || host === null) return;
173
+ if (!isLaunch || phase === FormPhase.Settled || host === null) {
174
+ return;
175
+ }
171
176
  const onFocus = (): void => handleCheckStatus();
172
- globalThis.addEventListener?.('focus', onFocus);
173
- return () => globalThis.removeEventListener?.('focus', onFocus);
177
+ const addEventListener: unknown = Reflect.get(globalThis, 'addEventListener');
178
+ if (typeof addEventListener !== 'function') {
179
+ return;
180
+ }
181
+ Reflect.apply(addEventListener, globalThis, ['focus', onFocus]);
182
+ return () => {
183
+ const removeEventListener: unknown = Reflect.get(
184
+ globalThis,
185
+ 'removeEventListener',
186
+ );
187
+ if (typeof removeEventListener === 'function') {
188
+ Reflect.apply(removeEventListener, globalThis, ['focus', onFocus]);
189
+ }
190
+ };
174
191
  // `handleCheckStatus` is stable per (host, payload) and re-subscribing on a
175
192
  // phase change is intended: a settled surface stops listening.
176
193
  }, [isLaunch, phase, host, handleCheckStatus]);
@@ -9,9 +9,10 @@
9
9
  import type { VistaTablePayload } from '../vista-payloads';
10
10
  import type { ReactElement } from 'react';
11
11
 
12
-
13
12
  function cellText(value: unknown): string {
14
- if (value === null || value === undefined) return '';
13
+ if (value === null || value === undefined) {
14
+ return '';
15
+ }
15
16
  if (typeof value === 'object') {
16
17
  try {
17
18
  return JSON.stringify(value);
@@ -62,7 +63,7 @@ export function TableSurface({
62
63
  <tr
63
64
  // Rows carry no identity in the generic contract; position is the
64
65
  // only stable key available.
65
-
66
+
66
67
  key={rowIndex}
67
68
  >
68
69
  {columns.map((column, columnIndex) => (
@@ -29,7 +29,9 @@ function BlobBody({
29
29
  payload: VistaBlobPayload;
30
30
  render: (url: string) => ReactNode;
31
31
  }>): ReactElement {
32
- if (payload.url !== undefined) return <>{render(payload.url)}</>;
32
+ if (payload.url !== undefined) {
33
+ return <>{render(payload.url)}</>;
34
+ }
33
35
  // `validateBlobPayload` guarantees exactly one of url/path.
34
36
  return <VistaFileUrl path={payload.path as string} render={render} />;
35
37
  }
@@ -51,7 +53,11 @@ export function ImageSurface(payload: VistaBlobPayload): ReactElement {
51
53
  <img
52
54
  src={url}
53
55
  alt={payload.alt ?? 'Preview'}
54
- style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain' }}
56
+ style={{
57
+ maxWidth: '100%',
58
+ maxHeight: '100%',
59
+ objectFit: 'contain',
60
+ }}
55
61
  />
56
62
  </div>
57
63
  )}
@@ -113,7 +119,11 @@ export function MediaSurface(payload: VistaBlobPayload): ReactElement {
113
119
  >
114
120
  {isAudio ? (
115
121
  // eslint-disable-next-line jsx-a11y/media-has-caption
116
- <audio src={url} controls style={{ width: '100%', maxWidth: 520 }} />
122
+ <audio
123
+ src={url}
124
+ controls
125
+ style={{ width: '100%', maxWidth: 520 }}
126
+ />
117
127
  ) : (
118
128
  // eslint-disable-next-line jsx-a11y/media-has-caption
119
129
  <video
@@ -66,7 +66,9 @@ function asRecord(value: unknown): UnknownRecord | null {
66
66
  */
67
67
  function unwrapEnvelope(body: unknown): UnknownRecord | null {
68
68
  const record = asRecord(body);
69
- if (record === null) return null;
69
+ if (record === null) {
70
+ return null;
71
+ }
70
72
  const inner = asRecord(record.data);
71
73
  return inner ?? record;
72
74
  }
@@ -82,14 +84,20 @@ export function extractServiceMessage(body: unknown, status: number): string {
82
84
  record === null
83
85
  ? undefined
84
86
  : (record.message ?? asRecord(record.error)?.message ?? record.error);
85
- if (typeof candidate === 'string' && candidate.length > 0) return candidate;
87
+ if (typeof candidate === 'string' && candidate.length > 0) {
88
+ return candidate;
89
+ }
86
90
  if (Array.isArray(candidate)) {
87
91
  const joined = candidate
88
92
  .filter((m): m is string => typeof m === 'string')
89
93
  .join(' ');
90
- if (joined.length > 0) return joined;
94
+ if (joined.length > 0) {
95
+ return joined;
96
+ }
97
+ }
98
+ if (typeof body === 'string' && body.length > 0) {
99
+ return body;
91
100
  }
92
- if (typeof body === 'string' && body.length > 0) return body;
93
101
  return `The service rejected the submission (HTTP ${status}).`;
94
102
  }
95
103
 
@@ -112,11 +120,15 @@ async function readBody(response: Response): Promise<unknown> {
112
120
  */
113
121
  function toOutcome(body: unknown, ref: string): VistaFormOutcome | null {
114
122
  const record = unwrapEnvelope(body);
115
- if (record === null) return null;
123
+ if (record === null) {
124
+ return null;
125
+ }
116
126
  const submitted =
117
127
  record.submitted === true ||
118
128
  (typeof record.status === 'string' && record.status === 'submitted');
119
- if (!submitted) return null;
129
+ if (!submitted) {
130
+ return null;
131
+ }
120
132
  const connectionId =
121
133
  typeof record.connectionId === 'string' && record.connectionId.length > 0
122
134
  ? record.connectionId
@@ -133,7 +145,9 @@ function authHeaders(
133
145
  Authorization: `Bearer ${accessToken}`,
134
146
  Accept: 'application/json',
135
147
  };
136
- if (json) headers['Content-Type'] = 'application/json';
148
+ if (json) {
149
+ headers['Content-Type'] = 'application/json';
150
+ }
137
151
  return headers;
138
152
  }
139
153
 
@@ -37,8 +37,12 @@ export interface VistaFileGroup {
37
37
  }
38
38
 
39
39
  function compareDirs(a: string, b: string): number {
40
- if (a === '') return -1;
41
- if (b === '') return 1;
40
+ if (a === '') {
41
+ return -1;
42
+ }
43
+ if (b === '') {
44
+ return 1;
45
+ }
42
46
  return a.localeCompare(b);
43
47
  }
44
48
 
@@ -50,8 +54,11 @@ export function groupFilesByFolder(
50
54
  const slash = file.path.lastIndexOf('/');
51
55
  const dir = slash < 0 ? '' : file.path.slice(0, slash);
52
56
  const bucket = groups.get(dir);
53
- if (bucket) bucket.push(file);
54
- else groups.set(dir, [file]);
57
+ if (bucket) {
58
+ bucket.push(file);
59
+ } else {
60
+ groups.set(dir, [file]);
61
+ }
55
62
  }
56
63
  return [...groups.keys()].sort(compareDirs).map((dir) => ({
57
64
  dir,
@@ -60,7 +60,9 @@ import {
60
60
  */
61
61
  function validateMediaPayload(raw: unknown): VistaBlobPayload | null {
62
62
  const payload = validateBlobPayload(raw);
63
- if (payload === null) return null;
63
+ if (payload === null) {
64
+ return null;
65
+ }
64
66
  return payload.contentType === undefined ? null : payload;
65
67
  }
66
68
 
@@ -35,7 +35,9 @@ function TextBody({
35
35
  payload: VistaTextPayload;
36
36
  render: (content: string) => ReactNode;
37
37
  }>): ReactElement {
38
- if (payload.content !== undefined) return <>{render(payload.content)}</>;
38
+ if (payload.content !== undefined) {
39
+ return <>{render(payload.content)}</>;
40
+ }
39
41
  // `validateTextPayload` guarantees exactly one of content/path.
40
42
  return <VistaFileText path={payload.path as string} render={render} />;
41
43
  }
@@ -73,10 +75,13 @@ export function CodeSurface(payload: VistaTextPayload): ReactElement {
73
75
  * parses and shown VERBATIM when it does not (a malformed JSON file is shown as
74
76
  * it is, never swallowed).
75
77
  */
76
- export function JsonSurface({ data }: Readonly<{ data: unknown }>): ReactElement {
78
+ export function JsonSurface({
79
+ data,
80
+ }: Readonly<{ data: unknown }>): ReactElement {
77
81
  let text: string;
78
82
  try {
79
- text = JSON.stringify(data, null, 2) ?? String(data);
83
+ const serialized: unknown = JSON.stringify(data, null, 2);
84
+ text = typeof serialized === 'string' ? serialized : String(data);
80
85
  } catch {
81
86
  text = String(data);
82
87
  }
@@ -89,10 +94,18 @@ export function JsonSurface({ data }: Readonly<{ data: unknown }>): ReactElement
89
94
 
90
95
  /** Colour a unified-diff line by its leading marker. */
91
96
  function diffLineColor(line: string): string | undefined {
92
- if (line.startsWith('+++') || line.startsWith('---')) return 'hsl(var(--ink-3))';
93
- if (line.startsWith('@@')) return 'hsl(var(--info))';
94
- if (line.startsWith('+')) return 'hsl(var(--success))';
95
- if (line.startsWith('-')) return 'hsl(var(--destructive, var(--danger)))';
97
+ if (line.startsWith('+++') || line.startsWith('---')) {
98
+ return 'hsl(var(--ink-3))';
99
+ }
100
+ if (line.startsWith('@@')) {
101
+ return 'hsl(var(--info))';
102
+ }
103
+ if (line.startsWith('+')) {
104
+ return 'hsl(var(--success))';
105
+ }
106
+ if (line.startsWith('-')) {
107
+ return 'hsl(var(--destructive, var(--danger)))';
108
+ }
96
109
  return undefined;
97
110
  }
98
111
 
@@ -105,7 +118,7 @@ export function DiffSurface(payload: VistaTextPayload): ReactElement {
105
118
  {content.split('\n').map((line, index) => (
106
119
  <div
107
120
  // A diff has no stable per-line identity other than its position.
108
-
121
+
109
122
  key={index}
110
123
  style={{ color: diffLineColor(line) }}
111
124
  >
@@ -128,14 +128,18 @@ export function useVistaTabs({
128
128
  activeRef.current = activeTabId;
129
129
 
130
130
  const activate = useCallback((tabId: string): void => {
131
- if (!tabsRef.current.some((t) => t.tabId === tabId)) return;
131
+ if (!tabsRef.current.some((t) => t.tabId === tabId)) {
132
+ return;
133
+ }
132
134
  setActiveTabId(tabId);
133
135
  }, []);
134
136
 
135
137
  const open = useCallback((surface: VistaTab): string => {
136
138
  setOpenedTabs((prev) => {
137
139
  const index = prev.findIndex((t) => t.tabId === surface.tabId);
138
- if (index === -1) return [...prev, surface];
140
+ if (index === -1) {
141
+ return [...prev, surface];
142
+ }
139
143
  // Re-opening the same tabId REPLACES it (the `VistaSurface` contract).
140
144
  const next = [...prev];
141
145
  next[index] = surface;
@@ -153,7 +157,9 @@ export function useVistaTabs({
153
157
  // overwritten on the next reconcile, so it is REFUSED rather than
154
158
  // silently lost. Ownership is decided synchronously from the ref, not
155
159
  // inside the state updater (which React may invoke twice).
156
- if (!openedTabsRef.current.some((t) => t.tabId === tabId)) return false;
160
+ if (!openedTabsRef.current.some((t) => t.tabId === tabId)) {
161
+ return false;
162
+ }
157
163
  setOpenedTabs((prev) =>
158
164
  prev.map((tab) => (tab.tabId === tabId ? { ...tab, ...patch } : tab)),
159
165
  );
@@ -164,7 +170,9 @@ export function useVistaTabs({
164
170
 
165
171
  const close = useCallback((tabId: string): boolean => {
166
172
  const tab = tabsRef.current.find((t) => t.tabId === tabId);
167
- if (tab === undefined || tab.pinned === true) return false;
173
+ if (tab === undefined || tab.pinned === true) {
174
+ return false;
175
+ }
168
176
  setOpenedTabs((prev) => prev.filter((t) => t.tabId !== tabId));
169
177
  setClosedHostTabIds((prev) =>
170
178
  prev.includes(tabId) ? prev : [...prev, tabId],
@@ -13,10 +13,8 @@
13
13
  * pane is the intended rendering, and with a provider the host's renderer is
14
14
  * the intended rendering. Neither is an error path.
15
15
  */
16
- import {
17
- type ReactElement,
18
- type ReactNode,
19
- } from 'react';
16
+ import { type ReactElement, type ReactNode } from 'react';
17
+
20
18
  import {
21
19
  VistaCodeRendererContext,
22
20
  type VistaCodeRenderer,
@@ -25,7 +23,10 @@ import {
25
23
  export function VistaCodeRendererProvider({
26
24
  renderer,
27
25
  children,
28
- }: Readonly<{ renderer: VistaCodeRenderer; children: ReactNode }>): ReactElement {
26
+ }: Readonly<{
27
+ renderer: VistaCodeRenderer;
28
+ children: ReactNode;
29
+ }>): ReactElement {
29
30
  return (
30
31
  <VistaCodeRendererContext.Provider value={renderer}>
31
32
  {children}
@@ -12,12 +12,8 @@
12
12
  * provider renders a visible error, never a blank pane and never a silent
13
13
  * "content unavailable".
14
14
  */
15
- import {
16
- useEffect,
17
- useState,
18
- type ReactElement,
19
- type ReactNode,
20
- } from 'react';
15
+ import { useEffect, useState, type ReactElement, type ReactNode } from 'react';
16
+
21
17
  import {
22
18
  VistaFileSourceContext,
23
19
  useVistaFileSource,
@@ -43,10 +39,7 @@ type LoadState =
43
39
 
44
40
  const LOADING: LoadState = { status: 'loading' };
45
41
 
46
- function useResolvedFile(
47
- path: string,
48
- mode: 'text' | 'url',
49
- ): LoadState {
42
+ function useResolvedFile(path: string, mode: 'text' | 'url'): LoadState {
50
43
  const source = useVistaFileSource();
51
44
  const revision = source?.revision;
52
45
  const [state, setState] = useState<LoadState>(LOADING);
@@ -66,10 +59,14 @@ function useResolvedFile(
66
59
  mode === 'text' ? source.readText(path) : source.resolveUrl(path);
67
60
  promise.then(
68
61
  (value) => {
69
- if (!cancelled) setState({ status: 'ready', value });
62
+ if (!cancelled) {
63
+ setState({ status: 'ready', value });
64
+ }
70
65
  },
71
66
  (error: unknown) => {
72
- if (cancelled) return;
67
+ if (cancelled) {
68
+ return;
69
+ }
73
70
  setState({
74
71
  status: 'error',
75
72
  message: error instanceof Error ? error.message : String(error),
@@ -122,7 +119,9 @@ export function VistaFileText({
122
119
  render: (content: string) => ReactNode;
123
120
  }>): ReactElement {
124
121
  const state = useResolvedFile(path, 'text');
125
- if (state.status !== 'ready') return <LoadNotice state={state} />;
122
+ if (state.status !== 'ready') {
123
+ return <LoadNotice state={state} />;
124
+ }
126
125
  return <>{render(state.value)}</>;
127
126
  }
128
127
 
@@ -135,6 +134,8 @@ export function VistaFileUrl({
135
134
  render: (url: string) => ReactNode;
136
135
  }>): ReactElement {
137
136
  const state = useResolvedFile(path, 'url');
138
- if (state.status !== 'ready') return <LoadNotice state={state} />;
137
+ if (state.status !== 'ready') {
138
+ return <LoadNotice state={state} />;
139
+ }
139
140
  return <>{render(state.value)}</>;
140
141
  }
@@ -26,14 +26,9 @@
26
26
  * provider renders a visible refusal and cannot submit. Fail-closed — a form
27
27
  * that silently posts nowhere would be worse than one that says it cannot.
28
28
  */
29
- import {
30
- type ReactElement,
31
- type ReactNode,
32
- } from 'react';
33
- import {
34
- VistaFormHostContext,
35
- type VistaFormHost,
36
- } from './vista-form-context';
29
+ import { type ReactElement, type ReactNode } from 'react';
30
+
31
+ import { VistaFormHostContext, type VistaFormHost } from './vista-form-context';
37
32
 
38
33
  /**
39
34
  * Everything a settled elicitation reports. Closed, scalar-only, and