@xemahq/ui-kernel 0.9.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/biome-host/agent-validation.d.ts.map +1 -1
- package/dist/lib/biome-host/agent-validation.js +26 -13
- package/dist/lib/biome-host/agent-validation.js.map +1 -1
- package/dist/lib/biome-host/biome-registry.d.ts.map +1 -1
- package/dist/lib/biome-host/biome-registry.js +27 -10
- package/dist/lib/biome-host/biome-registry.js.map +1 -1
- package/dist/lib/biome-host/biome-scope-hooks.d.ts.map +1 -1
- package/dist/lib/biome-host/biome-scope-hooks.js +2 -1
- package/dist/lib/biome-host/biome-scope-hooks.js.map +1 -1
- package/dist/lib/biome-host/biome-scoped-query.d.ts.map +1 -1
- package/dist/lib/biome-host/biome-scoped-query.js +5 -3
- package/dist/lib/biome-host/biome-scoped-query.js.map +1 -1
- package/dist/lib/biome-host/frontend-biome.d.ts +1 -1
- package/dist/lib/biome-host/frontend-biome.d.ts.map +1 -1
- package/dist/lib/biome-host/host-bridge.d.ts +1 -1
- package/dist/lib/biome-host/host-bridge.d.ts.map +1 -1
- package/dist/lib/biome-host/host-bridge.js.map +1 -1
- package/dist/lib/biome-host/i18n-hooks.d.ts.map +1 -1
- package/dist/lib/biome-host/i18n-hooks.js.map +1 -1
- package/dist/lib/biome-host/index.d.ts +0 -1
- package/dist/lib/biome-host/index.d.ts.map +1 -1
- package/dist/lib/biome-host/index.js +0 -1
- package/dist/lib/biome-host/index.js.map +1 -1
- package/dist/lib/biome-host/realtime-hooks.d.ts.map +1 -1
- package/dist/lib/biome-host/realtime-hooks.js.map +1 -1
- package/dist/lib/biome-host/session-contributions.d.ts +10 -5
- package/dist/lib/biome-host/session-contributions.d.ts.map +1 -1
- package/dist/lib/biome-host/use-mutation-with-error-toast.d.ts.map +1 -1
- package/dist/lib/biome-host/use-mutation-with-error-toast.js +3 -2
- package/dist/lib/biome-host/use-mutation-with-error-toast.js.map +1 -1
- package/dist/lib/biome-host/use-page-state.d.ts.map +1 -1
- package/dist/lib/biome-host/use-page-state.js +19 -10
- package/dist/lib/biome-host/use-page-state.js.map +1 -1
- package/dist/lib/capabilities/capability-provider.d.ts +1 -1
- package/dist/lib/capabilities/capability-provider.d.ts.map +1 -1
- package/dist/lib/capabilities/capability-provider.js +2 -2
- package/dist/lib/capabilities/capability-provider.js.map +1 -1
- package/dist/lib/capabilities/use-capability.d.ts +1 -1
- package/dist/lib/capabilities/use-capability.d.ts.map +1 -1
- package/dist/lib/capabilities/use-capability.js +2 -1
- package/dist/lib/capabilities/use-capability.js.map +1 -1
- package/dist/lib/contribution-registry/contribution-registry.d.ts.map +1 -1
- package/dist/lib/contribution-registry/contribution-registry.js +2 -1
- package/dist/lib/contribution-registry/contribution-registry.js.map +1 -1
- package/dist/lib/system-bus/deeplink.d.ts.map +1 -1
- package/dist/lib/system-bus/deeplink.js +4 -2
- package/dist/lib/system-bus/deeplink.js.map +1 -1
- package/dist/lib/system-bus/host-ports.d.ts +2 -2
- package/dist/lib/system-bus/host-ports.d.ts.map +1 -1
- package/dist/lib/system-bus/intent-registry.d.ts.map +1 -1
- package/dist/lib/system-bus/intent-registry.js +6 -3
- package/dist/lib/system-bus/intent-registry.js.map +1 -1
- package/dist/lib/system-bus/intents.d.ts +1 -1
- package/dist/lib/system-bus/intents.d.ts.map +1 -1
- package/dist/lib/system-bus/palette.d.ts +1 -1
- package/dist/lib/system-bus/palette.d.ts.map +1 -1
- package/dist/lib/system-bus/system-bus-builder.d.ts.map +1 -1
- package/dist/lib/system-bus/system-bus-builder.js +1 -1
- package/dist/lib/system-bus/system-bus-builder.js.map +1 -1
- package/dist/lib/system-bus/windows.d.ts +1 -1
- package/dist/lib/system-bus/windows.d.ts.map +1 -1
- package/dist/offline/outbox.d.ts +1 -0
- package/dist/offline/outbox.d.ts.map +1 -1
- package/dist/offline/outbox.js +4 -1
- package/dist/offline/outbox.js.map +1 -1
- package/dist/offline/react-hooks.d.ts +1 -1
- package/dist/offline/react-hooks.d.ts.map +1 -1
- package/dist/offline/react-hooks.js.map +1 -1
- package/dist/org-db/components/DbResultTable.d.ts.map +1 -1
- package/dist/org-db/components/DbResultTable.js +15 -6
- package/dist/org-db/components/DbResultTable.js.map +1 -1
- package/dist/registry/lib/agent-validation-host.d.ts.map +1 -1
- package/dist/registry/lib/agent-validation-host.js +1 -1
- package/dist/registry/lib/agent-validation-host.js.map +1 -1
- package/dist/registry/lib/biome-slot.d.ts.map +1 -1
- package/dist/registry/lib/biome-slot.js +5 -3
- package/dist/registry/lib/biome-slot.js.map +1 -1
- package/dist/registry/lib/primitives/SessionEventCard.d.ts.map +1 -1
- package/dist/registry/lib/primitives/SessionEventCard.js +14 -2
- package/dist/registry/lib/primitives/SessionEventCard.js.map +1 -1
- package/dist/registry/lib/primitives/SessionEventTimeline.d.ts.map +1 -1
- package/dist/registry/lib/primitives/SessionEventTimeline.js +6 -3
- package/dist/registry/lib/primitives/SessionEventTimeline.js.map +1 -1
- package/dist/registry/lib/primitives/SessionTabbedDrawer.d.ts.map +1 -1
- package/dist/registry/lib/primitives/SessionTabbedDrawer.js +10 -5
- package/dist/registry/lib/primitives/SessionTabbedDrawer.js.map +1 -1
- package/dist/registry/lib/session-context-builder.d.ts +10 -2
- package/dist/registry/lib/session-context-builder.d.ts.map +1 -1
- package/dist/registry/lib/session-context-builder.js +14 -7
- package/dist/registry/lib/session-context-builder.js.map +1 -1
- package/dist/registry/lib/session-context-provider.d.ts +1 -1
- package/dist/registry/lib/session-context-provider.d.ts.map +1 -1
- package/dist/registry/lib/session-context-provider.js.map +1 -1
- package/dist/registry/lib/session-selectors.d.ts.map +1 -1
- package/dist/registry/lib/session-selectors.js +35 -20
- package/dist/registry/lib/session-selectors.js.map +1 -1
- package/dist/session/comments/CommentRail.d.ts.map +1 -1
- package/dist/session/comments/CommentRail.js.map +1 -1
- package/dist/session/shell/SessionWorkspaceShell.d.ts.map +1 -1
- package/dist/session/shell/SessionWorkspaceShell.js.map +1 -1
- package/dist/session-kit/approvals/ApprovalCard.d.ts.map +1 -1
- package/dist/session-kit/approvals/ApprovalCard.js +6 -2
- package/dist/session-kit/approvals/ApprovalCard.js.map +1 -1
- package/dist/session-kit/approvals/ApprovalsCenter.d.ts.map +1 -1
- package/dist/session-kit/approvals/ApprovalsCenter.js +6 -3
- package/dist/session-kit/approvals/ApprovalsCenter.js.map +1 -1
- package/dist/session-kit/combobox/Combobox.d.ts.map +1 -1
- package/dist/session-kit/combobox/Combobox.js +20 -6
- package/dist/session-kit/combobox/Combobox.js.map +1 -1
- package/dist/session-kit/display/MD.d.ts.map +1 -1
- package/dist/session-kit/display/MD.js +7 -4
- package/dist/session-kit/display/MD.js.map +1 -1
- package/dist/ui/branding/app-branding-provider.d.ts.map +1 -1
- package/dist/ui/branding/app-branding-provider.js.map +1 -1
- package/dist/ui/branding/sanitize.d.ts.map +1 -1
- package/dist/ui/branding/sanitize.js +12 -6
- package/dist/ui/branding/sanitize.js.map +1 -1
- package/dist/ui/capture/document-preview.d.ts +1 -1
- package/dist/ui/capture/document-preview.d.ts.map +1 -1
- package/dist/ui/capture/document-preview.js +8 -6
- package/dist/ui/capture/document-preview.js.map +1 -1
- package/dist/ui/capture/field-spec-to-zod.d.ts.map +1 -1
- package/dist/ui/capture/field-spec-to-zod.js +45 -16
- package/dist/ui/capture/field-spec-to-zod.js.map +1 -1
- package/dist/ui/capture/field-spec-validate.d.ts.map +1 -1
- package/dist/ui/capture/field-spec-validate.js +79 -38
- package/dist/ui/capture/field-spec-validate.js.map +1 -1
- package/dist/ui/capture/field-spec.d.ts.map +1 -1
- package/dist/ui/capture/field-spec.js +17 -6
- package/dist/ui/capture/field-spec.js.map +1 -1
- package/dist/ui/capture/schema-field-input.d.ts.map +1 -1
- package/dist/ui/capture/schema-field-input.js +23 -18
- package/dist/ui/capture/schema-field-input.js.map +1 -1
- package/dist/ui/capture/schema-form.d.ts +1 -1
- package/dist/ui/capture/schema-form.d.ts.map +1 -1
- package/dist/ui/capture/schema-form.js +7 -6
- package/dist/ui/capture/schema-form.js.map +1 -1
- package/dist/ui/capture/use-prefill.d.ts.map +1 -1
- package/dist/ui/capture/use-prefill.js +32 -14
- package/dist/ui/capture/use-prefill.js.map +1 -1
- package/dist/ui/capture/use-schema-validation.d.ts +1 -1
- package/dist/ui/capture/use-schema-validation.d.ts.map +1 -1
- package/dist/ui/capture/use-schema-validation.js +13 -8
- package/dist/ui/capture/use-schema-validation.js.map +1 -1
- package/dist/ui/capture/use-wizard.d.ts.map +1 -1
- package/dist/ui/capture/use-wizard.js +23 -8
- package/dist/ui/capture/use-wizard.js.map +1 -1
- package/dist/ui/capture/value-format.d.ts.map +1 -1
- package/dist/ui/capture/value-format.js +6 -3
- package/dist/ui/capture/value-format.js.map +1 -1
- package/dist/ui/capture/wizard.d.ts.map +1 -1
- package/dist/ui/capture/wizard.js +3 -3
- package/dist/ui/capture/wizard.js.map +1 -1
- package/dist/ui/charts/bar-chart.d.ts +1 -1
- package/dist/ui/charts/bar-chart.d.ts.map +1 -1
- package/dist/ui/charts/bar-chart.js +1 -1
- package/dist/ui/charts/bar-chart.js.map +1 -1
- package/dist/ui/charts/chart-frame.d.ts +2 -2
- package/dist/ui/charts/chart-frame.d.ts.map +1 -1
- package/dist/ui/charts/chart-frame.js +4 -3
- package/dist/ui/charts/chart-frame.js.map +1 -1
- package/dist/ui/charts/chart-utils.d.ts.map +1 -1
- package/dist/ui/charts/chart-utils.js +32 -14
- package/dist/ui/charts/chart-utils.js.map +1 -1
- package/dist/ui/charts/donut-chart.d.ts +1 -1
- package/dist/ui/charts/donut-chart.d.ts.map +1 -1
- package/dist/ui/charts/donut-chart.js +7 -3
- package/dist/ui/charts/donut-chart.js.map +1 -1
- package/dist/ui/charts/line-chart.d.ts +1 -1
- package/dist/ui/charts/line-chart.d.ts.map +1 -1
- package/dist/ui/charts/line-chart.js +7 -4
- package/dist/ui/charts/line-chart.js.map +1 -1
- package/dist/ui/charts/sparkline.d.ts +1 -1
- package/dist/ui/charts/sparkline.d.ts.map +1 -1
- package/dist/ui/charts/sparkline.js +10 -6
- package/dist/ui/charts/sparkline.js.map +1 -1
- package/dist/ui/chrome/AsyncBoundary.d.ts +2 -2
- package/dist/ui/chrome/AsyncBoundary.d.ts.map +1 -1
- package/dist/ui/chrome/AsyncBoundary.js +3 -3
- package/dist/ui/chrome/AsyncBoundary.js.map +1 -1
- package/dist/ui/chrome/EmptyState.d.ts +19 -8
- package/dist/ui/chrome/EmptyState.d.ts.map +1 -1
- package/dist/ui/chrome/EmptyState.js +6 -4
- package/dist/ui/chrome/EmptyState.js.map +1 -1
- package/dist/ui/chrome/RecordCardList.d.ts +19 -0
- package/dist/ui/chrome/RecordCardList.d.ts.map +1 -0
- package/dist/ui/chrome/RecordCardList.js +12 -0
- package/dist/ui/chrome/RecordCardList.js.map +1 -0
- package/dist/ui/chrome/page-shell.d.ts.map +1 -1
- package/dist/ui/chrome/page-shell.js +9 -3
- package/dist/ui/chrome/page-shell.js.map +1 -1
- package/dist/ui/chrome/status-badge.d.ts.map +1 -1
- package/dist/ui/chrome/status-badge.js +1 -1
- package/dist/ui/chrome/status-badge.js.map +1 -1
- package/dist/ui/design-tokens.d.ts +4 -6
- package/dist/ui/design-tokens.d.ts.map +1 -1
- package/dist/ui/design-tokens.js +17 -11
- package/dist/ui/design-tokens.js.map +1 -1
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +1 -0
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/primitives/async-combobox.d.ts.map +1 -1
- package/dist/ui/primitives/async-combobox.js +4 -2
- package/dist/ui/primitives/async-combobox.js.map +1 -1
- package/dist/ui/primitives/badge.d.ts +2 -2
- package/dist/ui/primitives/badge.d.ts.map +1 -1
- package/dist/ui/primitives/badge.js +3 -3
- package/dist/ui/primitives/badge.js.map +1 -1
- package/dist/ui/primitives/button.d.ts +2 -2
- package/dist/ui/primitives/button.d.ts.map +1 -1
- package/dist/ui/primitives/button.js +5 -5
- package/dist/ui/primitives/button.js.map +1 -1
- package/dist/ui/primitives/overflow-tabs.d.ts.map +1 -1
- package/dist/ui/primitives/overflow-tabs.js +19 -12
- package/dist/ui/primitives/overflow-tabs.js.map +1 -1
- package/dist/ui/primitives/preview-device-frame.js +8 -4
- package/dist/ui/primitives/preview-device-frame.js.map +1 -1
- package/dist/ui/primitives/tag-multi-select.d.ts.map +1 -1
- package/dist/ui/primitives/tag-multi-select.js +10 -5
- package/dist/ui/primitives/tag-multi-select.js.map +1 -1
- package/dist/ui/primitives/url-preview-chrome.d.ts.map +1 -1
- package/dist/ui/primitives/url-preview-chrome.js.map +1 -1
- package/dist/vista/GenericCatalogueSurface.d.ts.map +1 -1
- package/dist/vista/GenericCatalogueSurface.js +5 -3
- package/dist/vista/GenericCatalogueSurface.js.map +1 -1
- package/dist/vista/VistaPanel.d.ts.map +1 -1
- package/dist/vista/VistaPanel.js +8 -4
- package/dist/vista/VistaPanel.js.map +1 -1
- package/dist/vista/html/CustomUiFrame.d.ts.map +1 -1
- package/dist/vista/html/CustomUiFrame.js +2 -1
- package/dist/vista/html/CustomUiFrame.js.map +1 -1
- package/dist/vista/html/custom-ui-frame-bridge.d.ts.map +1 -1
- package/dist/vista/html/custom-ui-frame-bridge.js +6 -3
- package/dist/vista/html/custom-ui-frame-bridge.js.map +1 -1
- package/dist/vista/html/custom-ui-intents.d.ts.map +1 -1
- package/dist/vista/html/custom-ui-intents.js +13 -15
- package/dist/vista/html/custom-ui-intents.js.map +1 -1
- package/dist/vista/surface-catalogue.d.ts.map +1 -1
- package/dist/vista/surface-catalogue.js +6 -3
- package/dist/vista/surface-catalogue.js.map +1 -1
- package/dist/vista/surfaces/FormSurface.d.ts.map +1 -1
- package/dist/vista/surfaces/FormSurface.js +20 -7
- package/dist/vista/surfaces/FormSurface.js.map +1 -1
- package/dist/vista/surfaces/TableSurface.d.ts.map +1 -1
- package/dist/vista/surfaces/TableSurface.js +2 -1
- package/dist/vista/surfaces/TableSurface.js.map +1 -1
- package/dist/vista/surfaces/blob-surfaces.d.ts.map +1 -1
- package/dist/vista/surfaces/blob-surfaces.js +7 -2
- package/dist/vista/surfaces/blob-surfaces.js.map +1 -1
- package/dist/vista/surfaces/elicitation-transport.d.ts.map +1 -1
- package/dist/vista/surfaces/elicitation-transport.js +14 -7
- package/dist/vista/surfaces/elicitation-transport.js.map +1 -1
- package/dist/vista/surfaces/file-surface-utils.d.ts.map +1 -1
- package/dist/vista/surfaces/file-surface-utils.js +8 -4
- package/dist/vista/surfaces/file-surface-utils.js.map +1 -1
- package/dist/vista/surfaces/register-surfaces.js +2 -1
- package/dist/vista/surfaces/register-surfaces.js.map +1 -1
- package/dist/vista/surfaces/text-surfaces.d.ts +1 -1
- package/dist/vista/surfaces/text-surfaces.d.ts.map +1 -1
- package/dist/vista/surfaces/text-surfaces.js +13 -7
- package/dist/vista/surfaces/text-surfaces.js.map +1 -1
- package/dist/vista/use-vista-tabs.d.ts.map +1 -1
- package/dist/vista/use-vista-tabs.js +8 -4
- package/dist/vista/use-vista-tabs.js.map +1 -1
- package/dist/vista/vista-code-renderer.d.ts.map +1 -1
- package/dist/vista/vista-code-renderer.js.map +1 -1
- package/dist/vista/vista-file-source.d.ts.map +1 -1
- package/dist/vista/vista-file-source.js +9 -5
- package/dist/vista/vista-file-source.js.map +1 -1
- package/dist/vista/vista-form-host.d.ts.map +1 -1
- package/dist/vista/vista-form-host.js +1 -1
- package/dist/vista/vista-form-host.js.map +1 -1
- package/dist/vista/vista-model.d.ts.map +1 -1
- package/dist/vista/vista-model.js +5 -3
- package/dist/vista/vista-model.js.map +1 -1
- package/dist/vista/vista-open-context.d.ts.map +1 -1
- package/dist/vista/vista-open-context.js +1 -1
- package/dist/vista/vista-open-context.js.map +1 -1
- package/dist/vista/vista-payloads.d.ts.map +1 -1
- package/dist/vista/vista-payloads.js +127 -63
- package/dist/vista/vista-payloads.js.map +1 -1
- package/dist/vista/vista-tabs-manifest.d.ts.map +1 -1
- package/dist/vista/vista-tabs-manifest.js +18 -9
- package/dist/vista/vista-tabs-manifest.js.map +1 -1
- package/dist/vista/vista-tools.d.ts.map +1 -1
- package/dist/vista/vista-tools.js +12 -6
- package/dist/vista/vista-tools.js.map +1 -1
- package/package.json +3 -3
- package/src/lib/biome-host/agent-validation.ts +37 -13
- package/src/lib/biome-host/biome-registry.ts +48 -13
- package/src/lib/biome-host/biome-scope-hooks.ts +3 -1
- package/src/lib/biome-host/biome-scoped-query.ts +7 -6
- package/src/lib/biome-host/frontend-biome.ts +1 -1
- package/src/lib/biome-host/host-bridge.ts +5 -4
- package/src/lib/biome-host/i18n-hooks.ts +1 -0
- package/src/lib/biome-host/index.ts +0 -1
- package/src/lib/biome-host/realtime-hooks.ts +1 -0
- package/src/lib/biome-host/session-contributions.ts +22 -19
- package/src/lib/biome-host/use-mutation-with-error-toast.ts +4 -2
- package/src/lib/biome-host/use-page-state.ts +27 -10
- package/src/lib/capabilities/capability-provider.tsx +12 -5
- package/src/lib/capabilities/use-capability.ts +8 -4
- package/src/lib/contribution-registry/contribution-registry.ts +3 -1
- package/src/lib/system-bus/deeplink.ts +14 -4
- package/src/lib/system-bus/host-ports.ts +3 -7
- package/src/lib/system-bus/intent-registry.ts +12 -8
- package/src/lib/system-bus/intents.ts +6 -2
- package/src/lib/system-bus/palette.ts +2 -1
- package/src/lib/system-bus/system-bus-builder.ts +4 -2
- package/src/lib/system-bus/windows.ts +1 -1
- package/src/offline/outbox.test.ts +12 -3
- package/src/offline/outbox.ts +5 -1
- package/src/offline/react-hooks.ts +5 -2
- package/src/org-db/components/DbResultTable.tsx +48 -15
- package/src/registry/lib/agent-validation-host.ts +1 -2
- package/src/registry/lib/biome-slot.tsx +7 -4
- package/src/registry/lib/primitives/SessionEventCard.tsx +29 -5
- package/src/registry/lib/primitives/SessionEventTimeline.tsx +9 -3
- package/src/registry/lib/primitives/SessionTabbedDrawer.tsx +15 -5
- package/src/registry/lib/session-context-builder.ts +33 -17
- package/src/registry/lib/session-context-provider.tsx +1 -1
- package/src/registry/lib/session-selectors.ts +66 -27
- package/src/session/comments/CommentRail.tsx +2 -2
- package/src/session/shell/SessionWorkspaceShell.tsx +2 -2
- package/src/session-kit/approvals/ApprovalCard.tsx +7 -2
- package/src/session-kit/approvals/ApprovalsCenter.tsx +13 -4
- package/src/session-kit/combobox/Combobox.tsx +42 -11
- package/src/session-kit/display/MD.tsx +14 -5
- package/src/ui/branding/app-branding-provider.tsx +2 -3
- package/src/ui/branding/sanitize.ts +18 -6
- package/src/ui/capture/document-preview.tsx +84 -19
- package/src/ui/capture/field-spec-to-zod.ts +62 -14
- package/src/ui/capture/field-spec-validate.ts +132 -43
- package/src/ui/capture/field-spec.test.ts +2 -2
- package/src/ui/capture/field-spec.ts +41 -10
- package/src/ui/capture/schema-field-input.tsx +218 -38
- package/src/ui/capture/schema-form.tsx +54 -13
- package/src/ui/capture/use-prefill.ts +50 -17
- package/src/ui/capture/use-schema-validation.ts +45 -13
- package/src/ui/capture/use-wizard.ts +57 -11
- package/src/ui/capture/value-format.ts +14 -4
- package/src/ui/capture/wizard.tsx +9 -5
- package/src/ui/charts/bar-chart.tsx +8 -4
- package/src/ui/charts/chart-frame.tsx +18 -5
- package/src/ui/charts/chart-utils.ts +47 -15
- package/src/ui/charts/donut-chart.tsx +24 -6
- package/src/ui/charts/line-chart.tsx +34 -12
- package/src/ui/charts/sparkline.tsx +17 -9
- package/src/ui/chrome/AsyncBoundary.tsx +14 -6
- package/src/ui/chrome/EmptyState.tsx +116 -43
- package/src/ui/chrome/RecordCardList.tsx +98 -0
- package/src/ui/chrome/page-shell.tsx +32 -8
- package/src/ui/chrome/status-badge.tsx +8 -4
- package/src/ui/design-tokens.ts +39 -13
- package/src/ui/index.ts +5 -0
- package/src/ui/primitives/async-combobox.tsx +7 -3
- package/src/ui/primitives/badge.tsx +14 -5
- package/src/ui/primitives/button.tsx +13 -6
- package/src/ui/primitives/overflow-tabs.tsx +46 -16
- package/src/ui/primitives/preview-device-frame.tsx +12 -4
- package/src/ui/primitives/tag-multi-select.tsx +30 -9
- package/src/ui/primitives/url-preview-chrome.tsx +1 -0
- package/src/vista/GenericCatalogueSurface.tsx +7 -5
- package/src/vista/VistaPanel.tsx +12 -4
- package/src/vista/html/CustomUiFrame.spec.tsx +3 -1
- package/src/vista/html/CustomUiFrame.tsx +3 -1
- package/src/vista/html/custom-ui-frame-bridge.ts +9 -3
- package/src/vista/html/custom-ui-intents.spec.ts +3 -1
- package/src/vista/html/custom-ui-intents.ts +19 -15
- package/src/vista/surface-catalogue.ts +9 -3
- package/src/vista/surfaces/FormSurface.tsx +27 -10
- package/src/vista/surfaces/TableSurface.tsx +4 -3
- package/src/vista/surfaces/blob-surfaces.tsx +13 -3
- package/src/vista/surfaces/elicitation-transport.ts +21 -7
- package/src/vista/surfaces/file-surface-utils.ts +11 -4
- package/src/vista/surfaces/register-surfaces.tsx +3 -1
- package/src/vista/surfaces/text-surfaces.tsx +21 -8
- package/src/vista/use-vista-tabs.ts +12 -4
- package/src/vista/vista-code-renderer.tsx +6 -5
- package/src/vista/vista-file-source.tsx +15 -14
- package/src/vista/vista-form-host.tsx +3 -8
- package/src/vista/vista-model.ts +10 -3
- package/src/vista/vista-open-context.tsx +3 -8
- package/src/vista/vista-payloads.ts +186 -63
- package/src/vista/vista-tabs-manifest.ts +28 -13
- package/src/vista/vista-tools.ts +18 -6
- package/dist/lib/biome-host/session-profiles.d.ts +0 -18
- package/dist/lib/biome-host/session-profiles.d.ts.map +0 -1
- package/dist/lib/biome-host/session-profiles.js +0 -38
- package/dist/lib/biome-host/session-profiles.js.map +0 -1
- package/src/lib/biome-host/session-profiles.ts +0 -105
|
@@ -3,12 +3,10 @@ import {
|
|
|
3
3
|
type XemaObjectKind,
|
|
4
4
|
type XemaObjectRef,
|
|
5
5
|
} from '@xemahq/kernel-contracts/object';
|
|
6
|
+
|
|
6
7
|
import { ActionRefKind } from './enums';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
IntentRegistration,
|
|
10
|
-
ResolvedIntent,
|
|
11
|
-
} from './intents';
|
|
8
|
+
|
|
9
|
+
import type { IntentBus, IntentRegistration, ResolvedIntent } from './intents';
|
|
12
10
|
|
|
13
11
|
const VALID_ACTION_KINDS: ReadonlySet<ActionRefKind> = new Set([
|
|
14
12
|
ActionRefKind.Capability,
|
|
@@ -58,14 +56,18 @@ export class IntentRegistry implements IntentBus {
|
|
|
58
56
|
|
|
59
57
|
unregister(biomeId: string): boolean {
|
|
60
58
|
const removed = this.registrations.delete(biomeId);
|
|
61
|
-
if (removed)
|
|
59
|
+
if (removed) {
|
|
60
|
+
this.notify();
|
|
61
|
+
}
|
|
62
62
|
return removed;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
resolve(kind: XemaObjectKind): readonly ResolvedIntent[] {
|
|
66
66
|
const out: ResolvedIntent[] = [];
|
|
67
67
|
for (const registration of this.registrations.values()) {
|
|
68
|
-
if (!registration.handles.includes(kind))
|
|
68
|
+
if (!registration.handles.includes(kind)) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
69
71
|
for (const action of registration.provides) {
|
|
70
72
|
out.push({ biomeId: registration.biomeId, action });
|
|
71
73
|
}
|
|
@@ -100,6 +102,8 @@ export class IntentRegistry implements IntentBus {
|
|
|
100
102
|
}
|
|
101
103
|
|
|
102
104
|
private notify(): void {
|
|
103
|
-
for (const listener of this.listeners)
|
|
105
|
+
for (const listener of this.listeners) {
|
|
106
|
+
listener();
|
|
107
|
+
}
|
|
104
108
|
}
|
|
105
109
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { type ActionRefKind } from './enums';
|
|
2
|
+
|
|
1
3
|
import type { CapabilityRef } from '@xemahq/kernel-contracts/capability';
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
+
import type {
|
|
5
|
+
XemaObjectKind,
|
|
6
|
+
XemaObjectRef,
|
|
7
|
+
} from '@xemahq/kernel-contracts/object';
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* Cross-biome intent registry — the "Open with… / Send to…" plane.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { PaletteEntrySource } from './enums';
|
|
2
1
|
import {
|
|
3
2
|
parseDeeplink,
|
|
4
3
|
type DeeplinkBus,
|
|
5
4
|
type ParsedDeeplink,
|
|
6
5
|
} from './deeplink';
|
|
6
|
+
import { PaletteEntrySource } from './enums';
|
|
7
7
|
import {
|
|
8
8
|
type CapabilityInvoker,
|
|
9
9
|
type DeeplinkResolver,
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
type PaletteEntry,
|
|
18
18
|
type PaletteQuery,
|
|
19
19
|
} from './palette';
|
|
20
|
+
|
|
20
21
|
import type { SystemBus } from './system-bus';
|
|
21
22
|
|
|
22
23
|
/**
|
|
@@ -121,7 +122,8 @@ function buildDeeplinkBus(resolver: DeeplinkResolver): DeeplinkBus {
|
|
|
121
122
|
async resolve(target: string | ParsedDeeplink): Promise<void> {
|
|
122
123
|
// Parse-first so a malformed deeplink fails fast in the kernel parser
|
|
123
124
|
// before the host navigation ever runs.
|
|
124
|
-
const parsed =
|
|
125
|
+
const parsed =
|
|
126
|
+
typeof target === 'string' ? parseDeeplink(target) : target;
|
|
125
127
|
await resolver.resolve(parsed);
|
|
126
128
|
},
|
|
127
129
|
};
|
|
@@ -80,7 +80,7 @@ describe('Outbox', () => {
|
|
|
80
80
|
expect(send).toHaveBeenCalledTimes(1);
|
|
81
81
|
const snap = outbox.getSnapshot();
|
|
82
82
|
expect(snap.failedCount).toBe(1);
|
|
83
|
-
expect(snap.entries[0]
|
|
83
|
+
expect(snap.entries[0]?.status).toBe(OutboxEntryStatus.Failed);
|
|
84
84
|
});
|
|
85
85
|
|
|
86
86
|
it('dead-letters after exhausting retries on persistent 5xx', async () => {
|
|
@@ -93,7 +93,9 @@ describe('Outbox', () => {
|
|
|
93
93
|
await outbox.enqueue(KIND, { a: 1 });
|
|
94
94
|
await outbox.drain();
|
|
95
95
|
expect(calls).toBe(3);
|
|
96
|
-
expect(outbox.getSnapshot().entries[0]
|
|
96
|
+
expect(outbox.getSnapshot().entries[0]?.status).toBe(
|
|
97
|
+
OutboxEntryStatus.Failed,
|
|
98
|
+
);
|
|
97
99
|
});
|
|
98
100
|
|
|
99
101
|
it('a network failure never advances the attempt counter or dead-letters', async () => {
|
|
@@ -114,6 +116,11 @@ describe('Outbox', () => {
|
|
|
114
116
|
await outbox.enqueue(KIND, { a: 1 });
|
|
115
117
|
await outbox.drain();
|
|
116
118
|
const parked = outbox.getSnapshot().entries[0];
|
|
119
|
+
if (!parked) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
'the offline entry was dropped from the outbox instead of parked',
|
|
122
|
+
);
|
|
123
|
+
}
|
|
117
124
|
expect(parked.status).toBe(OutboxEntryStatus.Pending);
|
|
118
125
|
expect(parked.attempts).toBe(0); // offline is not the payload's fault
|
|
119
126
|
expect(outbox.getSnapshot().failedCount).toBe(0);
|
|
@@ -157,7 +164,9 @@ describe('Outbox', () => {
|
|
|
157
164
|
online.reportOffline(); // keep it queued so we can observe the recovery
|
|
158
165
|
const outbox = new Outbox({ storage, online, scheduler: (fn) => fn() });
|
|
159
166
|
await outbox.start();
|
|
160
|
-
expect(outbox.getSnapshot().entries[0]
|
|
167
|
+
expect(outbox.getSnapshot().entries[0]?.status).toBe(
|
|
168
|
+
OutboxEntryStatus.Pending,
|
|
169
|
+
);
|
|
161
170
|
outbox.stop();
|
|
162
171
|
});
|
|
163
172
|
});
|
package/src/offline/outbox.ts
CHANGED
|
@@ -231,13 +231,17 @@ export class Outbox {
|
|
|
231
231
|
do {
|
|
232
232
|
this.drainRequested = false;
|
|
233
233
|
await this.drainOnce();
|
|
234
|
-
} while (this.
|
|
234
|
+
} while (this.shouldContinueDrain());
|
|
235
235
|
} finally {
|
|
236
236
|
this.draining = false;
|
|
237
237
|
this.notify();
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
+
private shouldContinueDrain(): boolean {
|
|
242
|
+
return this.drainRequested && this.online.isOnline();
|
|
243
|
+
}
|
|
244
|
+
|
|
241
245
|
// ── internals ──────────────────────────────────────────────────────────────
|
|
242
246
|
|
|
243
247
|
private async hydrate(): Promise<void> {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createContext, useContext, useSyncExternalStore } from 'react';
|
|
2
2
|
|
|
3
|
-
import { Outbox } from './outbox';
|
|
3
|
+
import { type Outbox } from './outbox';
|
|
4
4
|
|
|
5
5
|
import type { OutboxSnapshot } from './types';
|
|
6
6
|
|
|
@@ -14,7 +14,10 @@ export function useOutbox(): Outbox {
|
|
|
14
14
|
return ctx;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
function resolveOutbox(
|
|
17
|
+
function resolveOutbox(
|
|
18
|
+
explicit: Outbox | undefined,
|
|
19
|
+
ctx: Outbox | null,
|
|
20
|
+
): Outbox {
|
|
18
21
|
const instance = explicit ?? ctx;
|
|
19
22
|
if (!instance) {
|
|
20
23
|
throw new Error('An <OutboxProvider> or an explicit outbox is required.');
|
|
@@ -10,12 +10,22 @@ export interface DbResultTableProps {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
function toDisplayValue(value: unknown): string {
|
|
13
|
-
if (value === null || value === undefined)
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
if (value === null || value === undefined) {
|
|
14
|
+
return '';
|
|
15
|
+
}
|
|
16
|
+
if (typeof value === 'string') {
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
if (
|
|
20
|
+
typeof value === 'number' ||
|
|
21
|
+
typeof value === 'boolean' ||
|
|
22
|
+
typeof value === 'bigint'
|
|
23
|
+
) {
|
|
16
24
|
return String(value);
|
|
17
25
|
}
|
|
18
|
-
if (value instanceof Date)
|
|
26
|
+
if (value instanceof Date) {
|
|
27
|
+
return value.toISOString();
|
|
28
|
+
}
|
|
19
29
|
try {
|
|
20
30
|
return JSON.stringify(value);
|
|
21
31
|
} catch {
|
|
@@ -34,11 +44,14 @@ export function DbResultTable(props: DbResultTableProps) {
|
|
|
34
44
|
const { columns, rows, rowCount, truncated, durationMs, statement } = props;
|
|
35
45
|
|
|
36
46
|
const csvContent = useMemo(() => {
|
|
37
|
-
const header = columns
|
|
47
|
+
const header = columns
|
|
48
|
+
.map((column) => escapeCsvValue(column.name))
|
|
49
|
+
.join(',');
|
|
38
50
|
const dataLines = rows.map((row) =>
|
|
39
51
|
row
|
|
40
52
|
.map((cell) => {
|
|
41
|
-
const printable =
|
|
53
|
+
const printable =
|
|
54
|
+
cell === null || cell === undefined ? '' : toDisplayValue(cell);
|
|
42
55
|
return escapeCsvValue(printable);
|
|
43
56
|
})
|
|
44
57
|
.join(','),
|
|
@@ -64,7 +77,9 @@ export function DbResultTable(props: DbResultTableProps) {
|
|
|
64
77
|
<section className="rounded-lg border border-border bg-card text-card-foreground">
|
|
65
78
|
{statement ? (
|
|
66
79
|
<details className="border-b border-border px-4 py-3">
|
|
67
|
-
<summary className="cursor-pointer text-sm font-medium text-foreground">
|
|
80
|
+
<summary className="cursor-pointer text-sm font-medium text-foreground">
|
|
81
|
+
SQL statement
|
|
82
|
+
</summary>
|
|
68
83
|
<pre className="mt-3 overflow-x-auto rounded-md bg-muted p-3 text-xs leading-6 text-muted-foreground">
|
|
69
84
|
<code>{statement}</code>
|
|
70
85
|
</pre>
|
|
@@ -73,13 +88,16 @@ export function DbResultTable(props: DbResultTableProps) {
|
|
|
73
88
|
|
|
74
89
|
{truncated ? (
|
|
75
90
|
<div className="border-b border-amber-300/60 bg-amber-100/60 px-4 py-3 text-sm text-amber-900">
|
|
76
|
-
Showing first {displayedCount} rows of {rowCount} total - download CSV
|
|
91
|
+
Showing first {displayedCount} rows of {rowCount} total - download CSV
|
|
92
|
+
for full results.
|
|
77
93
|
</div>
|
|
78
94
|
) : null}
|
|
79
95
|
|
|
80
96
|
<div className="flex items-center justify-between gap-3 border-b border-border px-4 py-3">
|
|
81
97
|
<div className="text-sm text-muted-foreground">
|
|
82
|
-
{rowCount === 0
|
|
98
|
+
{rowCount === 0
|
|
99
|
+
? 'No rows returned'
|
|
100
|
+
: `${displayedCount} row${displayedCount === 1 ? '' : 's'} shown`}
|
|
83
101
|
</div>
|
|
84
102
|
<button
|
|
85
103
|
type="button"
|
|
@@ -91,14 +109,19 @@ export function DbResultTable(props: DbResultTableProps) {
|
|
|
91
109
|
</div>
|
|
92
110
|
|
|
93
111
|
{rowCount === 0 ? (
|
|
94
|
-
<div className="px-4 py-8 text-center text-sm text-muted-foreground">
|
|
112
|
+
<div className="px-4 py-8 text-center text-sm text-muted-foreground">
|
|
113
|
+
No rows returned
|
|
114
|
+
</div>
|
|
95
115
|
) : (
|
|
96
116
|
<div className="overflow-x-auto">
|
|
97
117
|
<table className="min-w-full border-collapse text-sm">
|
|
98
118
|
<thead>
|
|
99
119
|
<tr className="border-b border-border bg-muted/40">
|
|
100
120
|
{columns.map((column) => (
|
|
101
|
-
<th
|
|
121
|
+
<th
|
|
122
|
+
key={column.name}
|
|
123
|
+
className="px-4 py-3 text-left font-medium text-foreground"
|
|
124
|
+
>
|
|
102
125
|
<div className="flex flex-wrap items-center gap-2">
|
|
103
126
|
<span>{column.name}</span>
|
|
104
127
|
{column.type ? (
|
|
@@ -113,15 +136,25 @@ export function DbResultTable(props: DbResultTableProps) {
|
|
|
113
136
|
</thead>
|
|
114
137
|
<tbody>
|
|
115
138
|
{rows.map((row, rowIndex) => (
|
|
116
|
-
<tr
|
|
139
|
+
<tr
|
|
140
|
+
key={`row-${rowIndex}`}
|
|
141
|
+
className="border-b border-border/70 align-top"
|
|
142
|
+
>
|
|
117
143
|
{columns.map((column, colIndex) => {
|
|
118
144
|
const cell = row[colIndex];
|
|
119
145
|
return (
|
|
120
|
-
<td
|
|
146
|
+
<td
|
|
147
|
+
key={`${column.name}-${rowIndex}`}
|
|
148
|
+
className="px-4 py-2 text-muted-foreground"
|
|
149
|
+
>
|
|
121
150
|
{cell === null || cell === undefined ? (
|
|
122
|
-
<span className="italic text-muted-foreground">
|
|
151
|
+
<span className="italic text-muted-foreground">
|
|
152
|
+
null
|
|
153
|
+
</span>
|
|
123
154
|
) : (
|
|
124
|
-
<span className="break-all text-foreground">
|
|
155
|
+
<span className="break-all text-foreground">
|
|
156
|
+
{toDisplayValue(cell)}
|
|
157
|
+
</span>
|
|
125
158
|
)}
|
|
126
159
|
</td>
|
|
127
160
|
);
|
|
@@ -8,14 +8,13 @@
|
|
|
8
8
|
* calls after every enabled biome has registered.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import { HostExtensionSlots } from './extension-points';
|
|
11
12
|
import {
|
|
12
13
|
type CompositionDiagnostic,
|
|
13
14
|
type FrontendBiome,
|
|
14
15
|
validateBiomeComposition,
|
|
15
16
|
} from '../../index';
|
|
16
17
|
|
|
17
|
-
import { HostExtensionSlots } from './extension-points';
|
|
18
|
-
|
|
19
18
|
/**
|
|
20
19
|
* Every slot id the host shell renders a `<BiomeSlot>` for. A panel
|
|
21
20
|
* targeting anything outside this set (and not a `<owner>/<name>`
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Fragment, type ReactElement } from 'react';
|
|
2
2
|
|
|
3
|
-
import { biomeRegistry, useBiomeRegistryRevision } from '../../index';
|
|
4
|
-
|
|
5
3
|
import { useBiomesEnabled } from './biomes-enabled-context';
|
|
4
|
+
import { biomeRegistry, useBiomeRegistryRevision } from '../../index';
|
|
6
5
|
|
|
7
6
|
export interface BiomeSlotProps {
|
|
8
7
|
/** Slot name biomes target via `PanelContribution.slot`. */
|
|
@@ -34,9 +33,13 @@ export function BiomeSlot(props: BiomeSlotProps): ReactElement | null {
|
|
|
34
33
|
// Subscribe so this slot re-renders when biomes register/change.
|
|
35
34
|
useBiomeRegistryRevision();
|
|
36
35
|
const enabled = useBiomesEnabled();
|
|
37
|
-
if (!enabled)
|
|
36
|
+
if (!enabled) {
|
|
37
|
+
return props.fallback ?? null;
|
|
38
|
+
}
|
|
38
39
|
const panels = biomeRegistry.panelsForSlot(props.name);
|
|
39
|
-
if (panels.length === 0)
|
|
40
|
+
if (panels.length === 0) {
|
|
41
|
+
return props.fallback ?? null;
|
|
42
|
+
}
|
|
40
43
|
return (
|
|
41
44
|
<Fragment>
|
|
42
45
|
{panels.map((panel) => (
|
|
@@ -22,7 +22,12 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import { type CSSProperties, type ReactNode, type ReactElement } from 'react';
|
|
24
24
|
|
|
25
|
-
export type SessionEventCardTone =
|
|
25
|
+
export type SessionEventCardTone =
|
|
26
|
+
| 'default'
|
|
27
|
+
| 'pending'
|
|
28
|
+
| 'success'
|
|
29
|
+
| 'error'
|
|
30
|
+
| 'info';
|
|
26
31
|
|
|
27
32
|
const TONE_DOT: Record<SessionEventCardTone, string> = {
|
|
28
33
|
default: 'hsl(var(--ink-4, 228 6% 58%))',
|
|
@@ -55,7 +60,9 @@ export interface SessionEventCardProps {
|
|
|
55
60
|
|
|
56
61
|
function formatTime(iso: string): string {
|
|
57
62
|
const date = new Date(iso);
|
|
58
|
-
if (Number.isNaN(date.getTime()))
|
|
63
|
+
if (Number.isNaN(date.getTime())) {
|
|
64
|
+
return '—';
|
|
65
|
+
}
|
|
59
66
|
return date.toLocaleTimeString([], {
|
|
60
67
|
hour: '2-digit',
|
|
61
68
|
minute: '2-digit',
|
|
@@ -121,12 +128,29 @@ export function SessionEventCard({
|
|
|
121
128
|
)}
|
|
122
129
|
</div>
|
|
123
130
|
<div style={{ minWidth: 0, flex: 1 }}>
|
|
124
|
-
<div
|
|
125
|
-
|
|
131
|
+
<div
|
|
132
|
+
style={{
|
|
133
|
+
display: 'flex',
|
|
134
|
+
gap: 6,
|
|
135
|
+
alignItems: 'baseline',
|
|
136
|
+
flexWrap: 'wrap',
|
|
137
|
+
}}
|
|
138
|
+
>
|
|
139
|
+
<span
|
|
140
|
+
style={{
|
|
141
|
+
color: 'hsl(var(--ink, 228 14% 11%))',
|
|
142
|
+
wordBreak: 'break-word',
|
|
143
|
+
}}
|
|
144
|
+
>
|
|
126
145
|
{title}
|
|
127
146
|
</span>
|
|
128
147
|
{detail !== null && detail !== undefined && (
|
|
129
|
-
<span
|
|
148
|
+
<span
|
|
149
|
+
style={{
|
|
150
|
+
color: 'hsl(var(--ink-3, 228 6% 40%))',
|
|
151
|
+
wordBreak: 'break-word',
|
|
152
|
+
}}
|
|
153
|
+
>
|
|
130
154
|
{detail}
|
|
131
155
|
</span>
|
|
132
156
|
)}
|
|
@@ -51,7 +51,9 @@ export function SessionEventTimeline<TItem>({
|
|
|
51
51
|
|
|
52
52
|
useEffect(() => {
|
|
53
53
|
const node = scrollRef.current;
|
|
54
|
-
if (!node)
|
|
54
|
+
if (!node) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
55
57
|
const handler = () => {
|
|
56
58
|
const distanceFromBottom =
|
|
57
59
|
node.scrollHeight - node.scrollTop - node.clientHeight;
|
|
@@ -62,9 +64,13 @@ export function SessionEventTimeline<TItem>({
|
|
|
62
64
|
}, [stickThreshold]);
|
|
63
65
|
|
|
64
66
|
useLayoutEffect(() => {
|
|
65
|
-
if (!stuckToBottom)
|
|
67
|
+
if (!stuckToBottom) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
66
70
|
const node = scrollRef.current;
|
|
67
|
-
if (!node)
|
|
71
|
+
if (!node) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
68
74
|
node.scrollTop = node.scrollHeight;
|
|
69
75
|
}, [items, stuckToBottom]);
|
|
70
76
|
|
|
@@ -57,19 +57,29 @@ export function SessionTabbedDrawer({
|
|
|
57
57
|
|
|
58
58
|
const select = useMemo(() => {
|
|
59
59
|
return (id: string) => {
|
|
60
|
-
if (activeTabId === undefined)
|
|
60
|
+
if (activeTabId === undefined) {
|
|
61
|
+
setInternalActive(id);
|
|
62
|
+
}
|
|
61
63
|
onActiveTabChange?.(id);
|
|
62
64
|
};
|
|
63
65
|
}, [activeTabId, onActiveTabChange]);
|
|
64
66
|
|
|
65
67
|
useEffect(() => {
|
|
66
|
-
if (!enableKeyboardShortcuts)
|
|
68
|
+
if (!enableKeyboardShortcuts) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
67
71
|
const handler = (event: KeyboardEvent) => {
|
|
68
|
-
if (!(event.metaKey || event.ctrlKey))
|
|
72
|
+
if (!(event.metaKey || event.ctrlKey)) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
69
75
|
const idx = Number.parseInt(event.key, 10);
|
|
70
|
-
if (Number.isNaN(idx) || idx < 1 || idx > tabs.length)
|
|
76
|
+
if (Number.isNaN(idx) || idx < 1 || idx > tabs.length) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
71
79
|
const target = tabs[idx - 1];
|
|
72
|
-
if (!target)
|
|
80
|
+
if (!target) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
73
83
|
event.preventDefault();
|
|
74
84
|
select(target.id);
|
|
75
85
|
};
|
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
* Single helper hook the host's session shell calls once per render to
|
|
3
3
|
* build the `SessionContext` it passes into every contribution selector.
|
|
4
4
|
*
|
|
5
|
-
* Inputs are the
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `SessionContext`. Memoised by the underlying selectors — callers can
|
|
9
|
-
* pass the result as a dep without worrying about identity churn.
|
|
5
|
+
* Inputs are the host's session fields plus the resolved Agent projection.
|
|
6
|
+
* The helper freezes capability refs and returns a stable `SessionContext`.
|
|
7
|
+
* It never fabricates a profile or capability fallback.
|
|
10
8
|
*
|
|
11
9
|
* Keeping this helper in the SDK (rather than the host) is what lets
|
|
12
10
|
* biomes also build a context — e.g. from inside a slash command
|
|
@@ -14,17 +12,23 @@
|
|
|
14
12
|
*/
|
|
15
13
|
import { useMemo } from 'react';
|
|
16
14
|
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
import type { SessionContext } from '../../index';
|
|
16
|
+
|
|
17
|
+
export interface SessionResolvedAgentInput {
|
|
18
|
+
readonly ref: string;
|
|
19
|
+
readonly requiredCapabilities: readonly string[];
|
|
20
|
+
readonly mayEditRepositories: boolean;
|
|
21
|
+
readonly mayWriteKnowledgeBase: boolean;
|
|
22
|
+
readonly hasOutputSurface: boolean;
|
|
23
|
+
}
|
|
21
24
|
|
|
22
25
|
export interface BuildSessionContextInput {
|
|
23
26
|
readonly sessionId: string;
|
|
24
27
|
readonly orgId: string;
|
|
25
28
|
readonly projectId: string;
|
|
26
29
|
readonly biomeId?: string;
|
|
27
|
-
readonly
|
|
30
|
+
readonly repositoryId?: string;
|
|
31
|
+
readonly agent?: SessionResolvedAgentInput;
|
|
28
32
|
readonly status: string;
|
|
29
33
|
readonly isActive: boolean;
|
|
30
34
|
}
|
|
@@ -41,17 +45,29 @@ export function isStatusActive(status: string): boolean {
|
|
|
41
45
|
return !TERMINAL_STATUSES.has(status);
|
|
42
46
|
}
|
|
43
47
|
|
|
44
|
-
export function useSessionContext(
|
|
45
|
-
|
|
48
|
+
export function useSessionContext(
|
|
49
|
+
input: BuildSessionContextInput,
|
|
50
|
+
): SessionContext {
|
|
46
51
|
return useMemo<SessionContext>(
|
|
47
52
|
() => ({
|
|
48
53
|
sessionId: input.sessionId,
|
|
49
54
|
orgId: input.orgId,
|
|
50
55
|
projectId: input.projectId,
|
|
51
|
-
biomeId: input.biomeId
|
|
52
|
-
|
|
56
|
+
...(input.biomeId !== undefined ? { biomeId: input.biomeId } : {}),
|
|
57
|
+
...(input.repositoryId !== undefined
|
|
58
|
+
? { repositoryId: input.repositoryId }
|
|
59
|
+
: {}),
|
|
60
|
+
...(input.agent !== undefined
|
|
61
|
+
? {
|
|
62
|
+
agent: {
|
|
63
|
+
...input.agent,
|
|
64
|
+
requiredCapabilities: Object.freeze(
|
|
65
|
+
new Set(input.agent.requiredCapabilities),
|
|
66
|
+
),
|
|
67
|
+
},
|
|
68
|
+
}
|
|
69
|
+
: {}),
|
|
53
70
|
status: input.status,
|
|
54
|
-
capabilities: Object.freeze(new Set(descriptor.capabilities)),
|
|
55
71
|
isActive: input.isActive,
|
|
56
72
|
}),
|
|
57
73
|
[
|
|
@@ -59,10 +75,10 @@ export function useSessionContext(input: BuildSessionContextInput): SessionConte
|
|
|
59
75
|
input.orgId,
|
|
60
76
|
input.projectId,
|
|
61
77
|
input.biomeId,
|
|
62
|
-
input.
|
|
78
|
+
input.repositoryId,
|
|
79
|
+
input.agent,
|
|
63
80
|
input.status,
|
|
64
81
|
input.isActive,
|
|
65
|
-
descriptor,
|
|
66
82
|
],
|
|
67
83
|
);
|
|
68
84
|
}
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
* stable, importable hook — `import { useCurrentSessionContext } from
|
|
11
11
|
* '@xemahq/ui-kernel/registry'`.
|
|
12
12
|
*/
|
|
13
|
-
import type { ReactElement, ReactNode } from 'react';
|
|
14
13
|
|
|
15
14
|
import { SessionContextValue } from './session-context';
|
|
16
15
|
|
|
17
16
|
import type { SessionContext } from '../../index';
|
|
17
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
18
18
|
|
|
19
19
|
export interface SessionContextProviderProps {
|
|
20
20
|
readonly value: SessionContext;
|