@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
@@ -39,18 +39,21 @@ export function dispatchVistaTool(controller, tool, args) {
39
39
  switch (tool) {
40
40
  case VistaToolName.Open: {
41
41
  const parsed = VistaOpenArgsSchema.safeParse(args);
42
- if (!parsed.success)
42
+ if (!parsed.success) {
43
43
  return invalid(parsed.error);
44
+ }
44
45
  return { ok: true, value: { tabId: controller.open(parsed.data) } };
45
46
  }
46
47
  case VistaToolName.Update: {
47
48
  const parsed = VistaUpdateArgsSchema.safeParse(args);
48
- if (!parsed.success)
49
+ if (!parsed.success) {
49
50
  return invalid(parsed.error);
51
+ }
50
52
  const { tabId, ...patch } = parsed.data;
51
53
  const refusal = refusalFor(controller, tabId);
52
- if (refusal !== null)
54
+ if (refusal !== null) {
53
55
  return refusal;
56
+ }
54
57
  if (!controller.update(tabId, patch)) {
55
58
  return {
56
59
  ok: false,
@@ -62,12 +65,14 @@ export function dispatchVistaTool(controller, tool, args) {
62
65
  }
63
66
  case VistaToolName.Close: {
64
67
  const parsed = VistaCloseArgsSchema.safeParse(args);
65
- if (!parsed.success)
68
+ if (!parsed.success) {
66
69
  return invalid(parsed.error);
70
+ }
67
71
  const { tabId } = parsed.data;
68
72
  const refusal = refusalFor(controller, tabId);
69
- if (refusal !== null)
73
+ if (refusal !== null) {
70
74
  return refusal;
75
+ }
71
76
  if (!controller.close(tabId)) {
72
77
  return {
73
78
  ok: false,
@@ -79,8 +84,9 @@ export function dispatchVistaTool(controller, tool, args) {
79
84
  }
80
85
  case VistaToolName.List: {
81
86
  const parsed = VistaListArgsSchema.safeParse(args ?? {});
82
- if (!parsed.success)
87
+ if (!parsed.success) {
83
88
  return invalid(parsed.error);
89
+ }
84
90
  return { ok: true, value: { tabs: controller.list() } };
85
91
  }
86
92
  default:
@@ -1 +1 @@
1
- {"version":3,"file":"vista-tools.js","sourceRoot":"","sources":["../../src/vista/vista-tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vista-tools.js","sourceRoot":"","sources":["../../src/vista/vista-tools.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xemahq/ui-kernel",
3
- "version": "0.10.0",
3
+ "version": "0.11.1",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "Host-framework-agnostic UI kernel for the Xema OS. Defines the SystemBus orchestration contract (capability.invoke, cross-biome intents, command palette, xema:// deeplinks, window manager) AND the biome-host contract surface (FrontendBiome/FrontendBiomeFactory, HostBridge, the singleton biomeRegistry, session contributions) that every frontend biome composes against. No Vite, Next.js, or React-Router — React itself IS allowed as the shared component model (the contracts traffic in ReactNode/ComponentType and a React context). Concrete host adapters (router/auth/toast wiring) live in separate packages that consume this kernel. The SystemBus is pure orchestration: it never authorizes, the backend capability-router enforces all policy.",
@@ -74,10 +74,13 @@
74
74
  "@tanstack/react-query": "^5.100.13",
75
75
  "@types/node": "25.2.3",
76
76
  "@types/react": "^18.3.30",
77
+ "@types/react-dom": "^18.3.7",
78
+ "@xemahq/kernel-contracts": "^8.0.0",
77
79
  "prettier": "3.6.2",
78
80
  "react": "^18.3.1",
81
+ "react-dom": "^18.3.1",
79
82
  "typescript": "5.9.3",
80
- "@xemahq/kernel-contracts": "^0.60.0"
83
+ "vitest": "^3.2.4"
81
84
  },
82
85
  "exports": {
83
86
  ".": {
@@ -109,9 +112,9 @@
109
112
  "scripts": {
110
113
  "clean": "rm -rf dist",
111
114
  "build": "tsc -p tsconfig.json",
112
- "test": "echo '[ui-kernel] *.{test,spec} files run under host-web vitest (this package carries no vitest dep by design — see tsconfig exclude). Write tests with vitest; the frontend-bridge sync fails on a node:test file.'",
115
+ "test": "echo '[ui-kernel] *.{test,spec} files RUN under host-web vitest (this package has no vitest runner config). vitest is a devDependency here for TYPES only, so tsc typechecks the specs in the repo that owns them.'",
113
116
  "format": "prettier --write \"src/**/*.{ts,tsx}\"",
114
- "lint": "tsc -p tsconfig.lint.json --noEmit",
117
+ "lint": "eslint .",
115
118
  "typecheck": "tsc -p tsconfig.lint.json --noEmit"
116
119
  }
117
120
  }
@@ -82,11 +82,17 @@ export interface ValidateBiomeCompositionOptions {
82
82
  */
83
83
  function biomeOwnedSlotOwner(slot: string): string | null {
84
84
  const slashIndex = slot.indexOf('/');
85
- if (slashIndex <= 0) return null; // no slash, or leading slash (empty owner)
86
- if (slot.indexOf('/', slashIndex + 1) !== -1) return null; // more than one slash
85
+ if (slashIndex <= 0) {
86
+ return null;
87
+ } // no slash, or leading slash (empty owner)
88
+ if (slot.indexOf('/', slashIndex + 1) !== -1) {
89
+ return null;
90
+ } // more than one slash
87
91
  const owner = slot.slice(0, slashIndex);
88
92
  const name = slot.slice(slashIndex + 1);
89
- if (owner.length === 0 || name.length === 0) return null;
93
+ if (owner.length === 0 || name.length === 0) {
94
+ return null;
95
+ }
90
96
  return owner;
91
97
  }
92
98
 
@@ -113,12 +119,17 @@ export function validateBiomeComposition(
113
119
  const scope = route.projectScoped ? 'project' : 'root';
114
120
  const key = `${scope}:${route.path}`;
115
121
  const owners = routeOwners.get(key);
116
- if (owners) owners.push(biome.id);
117
- else routeOwners.set(key, [biome.id]);
122
+ if (owners) {
123
+ owners.push(biome.id);
124
+ } else {
125
+ routeOwners.set(key, [biome.id]);
126
+ }
118
127
  }
119
128
  }
120
129
  for (const [key, owners] of routeOwners) {
121
- if (owners.length < 2) continue;
130
+ if (owners.length < 2) {
131
+ continue;
132
+ }
122
133
  const [scope, path] = splitFirst(key, ':');
123
134
  diagnostics.push({
124
135
  code: CompositionDiagnosticCode.DuplicateRoutePath,
@@ -139,12 +150,17 @@ export function validateBiomeComposition(
139
150
  for (const biome of biomes) {
140
151
  for (const navItem of biome.navItems ?? []) {
141
152
  const owners = navOwners.get(navItem.id);
142
- if (owners) owners.push(biome.id);
143
- else navOwners.set(navItem.id, [biome.id]);
153
+ if (owners) {
154
+ owners.push(biome.id);
155
+ } else {
156
+ navOwners.set(navItem.id, [biome.id]);
157
+ }
144
158
  }
145
159
  }
146
160
  for (const [navId, owners] of navOwners) {
147
- if (owners.length < 2) continue;
161
+ if (owners.length < 2) {
162
+ continue;
163
+ }
148
164
  diagnostics.push({
149
165
  code: CompositionDiagnosticCode.DuplicateNavId,
150
166
  severity: CompositionDiagnosticSeverity.Error,
@@ -159,7 +175,9 @@ export function validateBiomeComposition(
159
175
  // ── Panel slots: known-slot + dependency-closure ─────────────────────
160
176
  for (const biome of biomes) {
161
177
  for (const panel of biome.panels ?? []) {
162
- if (options.knownSlots.has(panel.slot)) continue;
178
+ if (options.knownSlots.has(panel.slot)) {
179
+ continue;
180
+ }
163
181
  const owner = biomeOwnedSlotOwner(panel.slot);
164
182
  if (owner === null) {
165
183
  diagnostics.push({
@@ -197,7 +215,9 @@ export function validateBiomeComposition(
197
215
  /** Split on the first occurrence of `sep` into a `[head, tail]` pair. */
198
216
  function splitFirst(value: string, sep: string): [string, string] {
199
217
  const idx = value.indexOf(sep);
200
- if (idx === -1) return [value, ''];
218
+ if (idx === -1) {
219
+ return [value, ''];
220
+ }
201
221
  return [value.slice(0, idx), value.slice(idx + sep.length)];
202
222
  }
203
223
 
@@ -206,10 +226,14 @@ function sortDiagnostics(
206
226
  diagnostics: CompositionDiagnostic[],
207
227
  ): CompositionDiagnostic[] {
208
228
  return diagnostics.slice().sort((a, b) => {
209
- if (a.code !== b.code) return a.code.localeCompare(b.code);
229
+ if (a.code !== b.code) {
230
+ return a.code.localeCompare(b.code);
231
+ }
210
232
  const ai = a.biomeIds.join(',');
211
233
  const bi = b.biomeIds.join(',');
212
- if (ai !== bi) return ai.localeCompare(bi);
234
+ if (ai !== bi) {
235
+ return ai.localeCompare(bi);
236
+ }
213
237
  return a.message.localeCompare(b.message);
214
238
  });
215
239
  }
@@ -36,7 +36,10 @@ import type { HostBridge } from './host-bridge';
36
36
  * register/unregister/bootstrap call is a no-op — a single flag controls
37
37
  * the entire surface.
38
38
  */
39
- class FrontendBiomeRegistry extends Registry<string, FrontendBiome & { key: string }> {
39
+ class FrontendBiomeRegistry extends Registry<
40
+ string,
41
+ FrontendBiome & { key: string }
42
+ > {
40
43
  private revisionCount = 0;
41
44
  private readonly listeners = new Set<() => void>();
42
45
  /**
@@ -54,7 +57,9 @@ class FrontendBiomeRegistry extends Registry<string, FrontendBiome & { key: stri
54
57
  }
55
58
 
56
59
  registerBiome(biome: FrontendBiome): void {
57
- if (!this.enabled) return;
60
+ if (!this.enabled) {
61
+ return;
62
+ }
58
63
  this.register({ ...biome, key: biome.id });
59
64
  this.revisionCount += 1;
60
65
  this.notify();
@@ -67,14 +72,20 @@ class FrontendBiomeRegistry extends Registry<string, FrontendBiome & { key: stri
67
72
  */
68
73
  async runInit(biomeId: string, bridge: HostBridge): Promise<void> {
69
74
  const entry = this.get(biomeId);
70
- if (!entry || !entry.init) return;
71
- if (this.initialized.has(biomeId)) return;
75
+ if (!entry || !entry.init) {
76
+ return;
77
+ }
78
+ if (this.initialized.has(biomeId)) {
79
+ return;
80
+ }
72
81
  this.initialized.add(biomeId);
73
82
  await entry.init({ bridge, biomeId });
74
83
  }
75
84
 
76
85
  unregisterBiome(id: string): boolean {
77
- if (!this.enabled) return false;
86
+ if (!this.enabled) {
87
+ return false;
88
+ }
78
89
  const entry = this.get(id);
79
90
  const removed = this.unregister(id);
80
91
  if (removed) {
@@ -86,7 +97,10 @@ class FrontendBiomeRegistry extends Registry<string, FrontendBiome & { key: stri
86
97
  // because the biome is being torn down anyway.
87
98
  void Promise.resolve(entry.dispose()).catch((error: unknown) => {
88
99
  // Surface for devtools without crashing the unregister flow.
89
- console.error(`[xema-ui-kernel] dispose() failed for '${id}':`, error);
100
+ console.error(
101
+ `[xema-ui-kernel] dispose() failed for '${id}':`,
102
+ error,
103
+ );
90
104
  });
91
105
  }
92
106
  this.notify();
@@ -103,7 +117,9 @@ class FrontendBiomeRegistry extends Registry<string, FrontendBiome & { key: stri
103
117
  }
104
118
 
105
119
  setEnabled(enabled: boolean): void {
106
- if (this.enabled === enabled) return;
120
+ if (this.enabled === enabled) {
121
+ return;
122
+ }
107
123
  this.enabled = enabled;
108
124
  if (!enabled) {
109
125
  // When master-disabling, drop any previously-registered biomes so
@@ -140,11 +156,15 @@ class FrontendBiomeRegistry extends Registry<string, FrontendBiome & { key: stri
140
156
  }
141
157
 
142
158
  panelsForSlot(slot: string): readonly PanelContribution[] {
143
- if (!this.enabled) return [];
159
+ if (!this.enabled) {
160
+ return [];
161
+ }
144
162
  const out: PanelContribution[] = [];
145
163
  for (const biome of this.list()) {
146
164
  for (const panel of biome.panels ?? []) {
147
- if (panel.slot === slot) out.push(panel);
165
+ if (panel.slot === slot) {
166
+ out.push(panel);
167
+ }
148
168
  }
149
169
  }
150
170
  return out.sort((a, b) => (a.weight ?? 100) - (b.weight ?? 100));
@@ -167,7 +187,9 @@ class FrontendBiomeRegistry extends Registry<string, FrontendBiome & { key: stri
167
187
  * rejected contribution is never dropped silently.
168
188
  */
169
189
  outputRenderers(): ReadonlyMap<string, OutputRendererContribution> {
170
- if (!this.enabled) return new Map<string, OutputRendererContribution>();
190
+ if (!this.enabled) {
191
+ return new Map<string, OutputRendererContribution>();
192
+ }
171
193
  // `onDuplicate` fires SYNCHRONOUSLY from inside `register()`, so this
172
194
  // cursor always names the biome whose contribution was rejected — the
173
195
  // contribution object itself does not carry its owner.
@@ -200,6 +222,17 @@ class FrontendBiomeRegistry extends Registry<string, FrontendBiome & { key: stri
200
222
 
201
223
  export const biomeRegistry = new FrontendBiomeRegistry();
202
224
 
225
+ function isFrontendBiome(value: unknown): value is FrontendBiome {
226
+ return (
227
+ value !== null &&
228
+ typeof value === 'object' &&
229
+ 'id' in value &&
230
+ typeof value.id === 'string' &&
231
+ 'displayName' in value &&
232
+ typeof value.displayName === 'string'
233
+ );
234
+ }
235
+
203
236
  /**
204
237
  * Register an already-built `FrontendBiome` instance. Prefer
205
238
  * `registerFrontendBiome(factory, bridge)` for biomes shipped via
@@ -222,9 +255,11 @@ export function registerFrontendBiome(
222
255
  factory: FrontendBiomeFactory,
223
256
  bridge: HostBridge,
224
257
  ): void {
225
- if (!biomeRegistry.isEnabled()) return;
226
- const biome = factory(bridge);
227
- if (!biome || typeof biome !== 'object' || typeof biome.id !== 'string') {
258
+ if (!biomeRegistry.isEnabled()) {
259
+ return;
260
+ }
261
+ const biome: unknown = factory(bridge);
262
+ if (!isFrontendBiome(biome)) {
228
263
  throw new Error(
229
264
  '[xema-ui-kernel] FrontendBiomeFactory returned a non-FrontendBiome value. ' +
230
265
  'A biome module must default-export `(bridge) => FrontendBiome`.',
@@ -11,7 +11,9 @@ export interface RequiredProjectScope {
11
11
  }
12
12
 
13
13
  function normalize(value: string | null | undefined): string | null {
14
- if (typeof value !== 'string') return null;
14
+ if (typeof value !== 'string') {
15
+ return null;
16
+ }
15
17
  const trimmed = value.trim();
16
18
  return trimmed.length > 0 ? trimmed : null;
17
19
  }
@@ -18,10 +18,7 @@ import {
18
18
  type UseQueryResult,
19
19
  } from '@tanstack/react-query';
20
20
 
21
- import {
22
- useProjectScope,
23
- type ProjectScope,
24
- } from './biome-scope-hooks';
21
+ import { useProjectScope, type ProjectScope } from './biome-scope-hooks';
25
22
 
26
23
  /**
27
24
  * The canonical Xema-platform tenant header. Every platform biome-api reads it
@@ -38,8 +35,12 @@ const PROJECT_HEADER = 'X-Project-Id';
38
35
  */
39
36
  export function buildScopedRequestInit(scope: ProjectScope): RequestInit {
40
37
  const headers: Record<string, string> = {};
41
- if (scope.orgId) headers[ORG_HEADER] = scope.orgId;
42
- if (scope.projectId) headers[PROJECT_HEADER] = scope.projectId;
38
+ if (scope.orgId) {
39
+ headers[ORG_HEADER] = scope.orgId;
40
+ }
41
+ if (scope.projectId) {
42
+ headers[PROJECT_HEADER] = scope.projectId;
43
+ }
43
44
  return { headers };
44
45
  }
45
46
 
@@ -1,6 +1,6 @@
1
- import type { ComponentType, ReactNode } from 'react';
2
1
  import type { HostBridge } from './host-bridge';
3
2
  import type { SessionContributions } from './session-contributions';
3
+ import type { ComponentType, ReactNode } from 'react';
4
4
 
5
5
  /**
6
6
  * Runtime contribution types a `target: 'web'` biome composes. Web
@@ -1,12 +1,10 @@
1
- import type { QueryClient } from '@tanstack/react-query';
2
-
3
1
  import { createContext, useContext, type ReactNode } from 'react';
4
2
 
5
3
  import type { CapabilityPort } from '../capabilities';
6
4
  import type { SystemBus } from '../system-bus';
7
-
8
5
  import type { I18nSource } from './i18n-port';
9
6
  import type { RealtimeSource } from './realtime-port';
7
+ import type { QueryClient } from '@tanstack/react-query';
10
8
 
11
9
  /**
12
10
  * `HostBridge` is the host-agnostic abstraction every frontend biome
@@ -44,7 +42,10 @@ export interface HostBridgeNavigation {
44
42
  * declares it is the matched route.
45
43
  */
46
44
  useRouteParams<
47
- T extends Record<string, string | undefined> = Record<string, string | undefined>,
45
+ T extends Record<string, string | undefined> = Record<
46
+ string,
47
+ string | undefined
48
+ >,
48
49
  >(): T;
49
50
  /**
50
51
  * Hook returning the current URL query string as a read-only
@@ -10,6 +10,7 @@
10
10
  */
11
11
 
12
12
  import { useHostBridge } from './host-bridge';
13
+
13
14
  import type { I18nSource, Translator } from './i18n-port';
14
15
 
15
16
  /**
@@ -11,6 +11,7 @@
11
11
  */
12
12
 
13
13
  import { useHostBridge } from './host-bridge';
14
+
14
15
  import type {
15
16
  RealtimeCloudEvent,
16
17
  RealtimeConnectionState,
@@ -20,9 +20,9 @@
20
20
  * `<biome-id>/<contribution>` so cross-biome collisions surface
21
21
  * deterministically at registration time (`RegistryDuplicateKeyError`).
22
22
  */
23
+ import type { HostBridge } from './host-bridge';
23
24
  import type { ComponentType, ReactNode } from 'react';
24
25
 
25
- import type { HostBridge } from './host-bridge';
26
26
  /**
27
27
  * Read-only snapshot of the session the contribution is evaluated
28
28
  * against. Passed into every `appliesTo` predicate and every render
@@ -68,10 +68,12 @@ export function useMutationWithErrorToast<
68
68
  if (successTitle !== null && successTitle !== undefined) {
69
69
  bridge.toast.success(successTitle, successDescription);
70
70
  }
71
- if (userOnSuccess) userOnSuccess(data, variables, context, mutation);
71
+ if (userOnSuccess) {
72
+ userOnSuccess(data, variables, context, mutation);
73
+ }
72
74
  },
73
75
  onError: (error: TError) => {
74
- if (errorTitle !== null && errorTitle !== undefined) {
76
+ if (errorTitle !== undefined) {
75
77
  const shouldSuppressToast = customOnError?.(error) === true;
76
78
  if (!shouldSuppressToast) {
77
79
  const errorMessage = decodeError(
@@ -25,9 +25,12 @@ function buildPath(pathname: string, params: URLSearchParams): string {
25
25
  }
26
26
 
27
27
  function serializeValue<T>(value: T): string {
28
- if (typeof value === 'string') return value;
29
- if (typeof value === 'number' || typeof value === 'boolean')
28
+ if (typeof value === 'string') {
29
+ return value;
30
+ }
31
+ if (typeof value === 'number' || typeof value === 'boolean') {
30
32
  return String(value);
33
+ }
31
34
  return JSON.stringify(value);
32
35
  }
33
36
 
@@ -43,7 +46,9 @@ function deserializePrimitive<T>(
43
46
  rawValue: string,
44
47
  defaultValue: T,
45
48
  ): T | undefined {
46
- if (typeof defaultValue === 'string') return rawValue as T;
49
+ if (typeof defaultValue === 'string') {
50
+ return rawValue as T;
51
+ }
47
52
 
48
53
  if (typeof defaultValue === 'number') {
49
54
  const numericValue = Number(rawValue);
@@ -51,8 +56,12 @@ function deserializePrimitive<T>(
51
56
  }
52
57
 
53
58
  if (typeof defaultValue === 'boolean') {
54
- if (rawValue === 'true') return true as T;
55
- if (rawValue === 'false') return false as T;
59
+ if (rawValue === 'true') {
60
+ return true as T;
61
+ }
62
+ if (rawValue === 'false') {
63
+ return false as T;
64
+ }
56
65
  return defaultValue;
57
66
  }
58
67
 
@@ -60,10 +69,14 @@ function deserializePrimitive<T>(
60
69
  }
61
70
 
62
71
  function deserializeValue<T>(rawValue: string | null, defaultValue: T): T {
63
- if (rawValue === null) return defaultValue;
72
+ if (rawValue === null) {
73
+ return defaultValue;
74
+ }
64
75
 
65
76
  const primitive = deserializePrimitive(rawValue, defaultValue);
66
- if (primitive !== undefined) return primitive;
77
+ if (primitive !== undefined) {
78
+ return primitive;
79
+ }
67
80
 
68
81
  // Default is null/undefined or a complex type (array/object). The value was
69
82
  // written via JSON.stringify in serializeValue, so attempt to parse it back.
@@ -74,9 +87,13 @@ function deserializeValue<T>(rawValue: string | null, defaultValue: T): T {
74
87
  return parsedValue as T;
75
88
  }
76
89
 
77
- if (defaultValue === null || defaultValue === undefined) return rawValue as T;
90
+ if (defaultValue === null || defaultValue === undefined) {
91
+ return rawValue as T;
92
+ }
78
93
 
79
- if (parsedValue !== undefined) return parsedValue as T;
94
+ if (parsedValue !== undefined) {
95
+ return parsedValue as T;
96
+ }
80
97
 
81
98
  if (Array.isArray(defaultValue)) {
82
99
  return rawValue ? ([rawValue] as unknown as T) : defaultValue;
@@ -218,7 +235,7 @@ export function useBatchPageState(): (
218
235
  (updates: Record<string, string | null>) => {
219
236
  const next = new URLSearchParams(searchParams);
220
237
  for (const [key, value] of Object.entries(updates)) {
221
- if (value === null || value === undefined) {
238
+ if (value === null) {
222
239
  next.delete(key);
223
240
  } else {
224
241
  next.set(key, value);
@@ -1,13 +1,13 @@
1
1
  import { useQuery } from '@tanstack/react-query';
2
- import type { ReactNode } from 'react';
3
2
 
4
- import { useHostBridge } from '../biome-host/host-bridge';
5
3
  import {
6
4
  CapabilityContext,
7
5
  type CapabilityContextValue,
8
6
  } from './capability-context';
7
+ import { useHostBridge } from '../biome-host/host-bridge';
9
8
 
10
9
  import type { CapabilityPort, MeCapabilitiesSnapshot } from './types';
10
+ import type { ReactNode } from 'react';
11
11
 
12
12
  /**
13
13
  * Stable query-key root for the capability snapshot. Folded with the active
@@ -46,10 +46,13 @@ export interface CapabilityProviderProps {
46
46
  * Rendering is fail-soft (callers can show a loading state), but failures are
47
47
  * SURFACED via `error` rather than masquerading as an empty capability set.
48
48
  */
49
- export function CapabilityProvider(props: CapabilityProviderProps): JSX.Element {
49
+ export function CapabilityProvider(
50
+ props: CapabilityProviderProps,
51
+ ): JSX.Element {
50
52
  const bridge = useHostBridge();
51
53
  const port = props.port ?? bridge.capabilities;
52
- const orgId = props.orgId !== undefined ? props.orgId : bridge.auth.getOrgId();
54
+ const orgId =
55
+ props.orgId !== undefined ? props.orgId : bridge.auth.getOrgId();
53
56
 
54
57
  const query = useQuery<MeCapabilitiesSnapshot>({
55
58
  queryKey: [...CAPABILITIES_QUERY_ROOT, orgId],
@@ -62,5 +65,9 @@ export function CapabilityProvider(props: CapabilityProviderProps): JSX.Element
62
65
  error: query.error,
63
66
  };
64
67
 
65
- return <CapabilityContext.Provider value={value}>{props.children}</CapabilityContext.Provider>;
68
+ return (
69
+ <CapabilityContext.Provider value={value}>
70
+ {props.children}
71
+ </CapabilityContext.Provider>
72
+ );
66
73
  }
@@ -1,10 +1,10 @@
1
- import type { ExecutionEnvironmentKind } from '@xemahq/kernel-contracts/execution-environment';
2
-
3
1
  import {
4
2
  useCapabilityContext,
5
3
  type CapabilityContextValue,
6
4
  } from './capability-context';
5
+
7
6
  import type { MeCapabilitiesSnapshot } from './types';
7
+ import type { ExecutionEnvironmentKind } from '@xemahq/kernel-contracts/execution-environment';
8
8
 
9
9
  export interface UseCapabilityOptions {
10
10
  /**
@@ -45,12 +45,16 @@ export interface CapabilityDecision {
45
45
  * On error, `allowed` is `false` and `error` is set; the hook never silently
46
46
  * degrades a failed fetch into a confident denial.
47
47
  */
48
- export function useCapability(ref: string, opts?: UseCapabilityOptions): CapabilityDecision {
48
+ export function useCapability(
49
+ ref: string,
50
+ opts?: UseCapabilityOptions,
51
+ ): CapabilityDecision {
49
52
  const { snapshot, isLoading, error } = useCapabilityContext();
50
53
 
51
54
  const entry = snapshot?.capabilities.find((c) => c.ref === ref);
52
55
  const inEnvironment =
53
- !!entry && (!opts?.environment || entry.environments.includes(opts.environment));
56
+ !!entry &&
57
+ (!opts?.environment || entry.environments.includes(opts.environment));
54
58
 
55
59
  return {
56
60
  allowed: inEnvironment && !entry.approvalRequired,
@@ -134,7 +134,9 @@ export function createContributionRegistry<TEntry>(
134
134
  target.set(kind, entry);
135
135
  return;
136
136
  }
137
- if (existing === entry) return;
137
+ if (existing === entry) {
138
+ return;
139
+ }
138
140
  if (duplicatePolicy === DuplicateContributionPolicy.FirstWins) {
139
141
  // `onDuplicate` is guaranteed present under this policy (checked above).
140
142
  (onDuplicate as (k: string, e: TEntry, r: TEntry) => void)(