@vendoai/ui 0.4.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/LICENSE +202 -0
- package/README.md +7 -0
- package/dist/chrome/activity-ledger.d.ts +14 -0
- package/dist/chrome/activity-ledger.d.ts.map +1 -0
- package/dist/chrome/activity-ledger.js +40 -0
- package/dist/chrome/activity-ledger.js.map +1 -0
- package/dist/chrome/activity-panel.d.ts +7 -0
- package/dist/chrome/activity-panel.d.ts.map +1 -0
- package/dist/chrome/activity-panel.js +27 -0
- package/dist/chrome/activity-panel.js.map +1 -0
- package/dist/chrome/activity-semantics.d.ts +42 -0
- package/dist/chrome/activity-semantics.d.ts.map +1 -0
- package/dist/chrome/activity-semantics.js +119 -0
- package/dist/chrome/activity-semantics.js.map +1 -0
- package/dist/chrome/approval-card.d.ts +22 -0
- package/dist/chrome/approval-card.d.ts.map +1 -0
- package/dist/chrome/approval-card.js +95 -0
- package/dist/chrome/approval-card.js.map +1 -0
- package/dist/chrome/approval-sheet.d.ts +23 -0
- package/dist/chrome/approval-sheet.d.ts.map +1 -0
- package/dist/chrome/approval-sheet.js +72 -0
- package/dist/chrome/approval-sheet.js.map +1 -0
- package/dist/chrome/automations-panel.d.ts +3 -0
- package/dist/chrome/automations-panel.d.ts.map +1 -0
- package/dist/chrome/automations-panel.js +305 -0
- package/dist/chrome/automations-panel.js.map +1 -0
- package/dist/chrome/build-beat.d.ts +70 -0
- package/dist/chrome/build-beat.d.ts.map +1 -0
- package/dist/chrome/build-beat.js +101 -0
- package/dist/chrome/build-beat.js.map +1 -0
- package/dist/chrome/chrome-css.d.ts +7 -0
- package/dist/chrome/chrome-css.d.ts.map +1 -0
- package/dist/chrome/chrome-css.js +2042 -0
- package/dist/chrome/chrome-css.js.map +1 -0
- package/dist/chrome/chrome-root.d.ts +13 -0
- package/dist/chrome/chrome-root.d.ts.map +1 -0
- package/dist/chrome/chrome-root.js +39 -0
- package/dist/chrome/chrome-root.js.map +1 -0
- package/dist/chrome/clipboard.d.ts +4 -0
- package/dist/chrome/clipboard.d.ts.map +1 -0
- package/dist/chrome/clipboard.js +49 -0
- package/dist/chrome/clipboard.js.map +1 -0
- package/dist/chrome/connect-card.d.ts +19 -0
- package/dist/chrome/connect-card.d.ts.map +1 -0
- package/dist/chrome/connect-card.js +57 -0
- package/dist/chrome/connect-card.js.map +1 -0
- package/dist/chrome/connect-dock.d.ts +25 -0
- package/dist/chrome/connect-dock.d.ts.map +1 -0
- package/dist/chrome/connect-dock.js +192 -0
- package/dist/chrome/connect-dock.js.map +1 -0
- package/dist/chrome/connected-accounts-panel.d.ts +14 -0
- package/dist/chrome/connected-accounts-panel.d.ts.map +1 -0
- package/dist/chrome/connected-accounts-panel.js +157 -0
- package/dist/chrome/connected-accounts-panel.js.map +1 -0
- package/dist/chrome/dev-mode.d.ts +5 -0
- package/dist/chrome/dev-mode.d.ts.map +1 -0
- package/dist/chrome/dev-mode.js +7 -0
- package/dist/chrome/dev-mode.js.map +1 -0
- package/dist/chrome/discoverability.d.ts +33 -0
- package/dist/chrome/discoverability.d.ts.map +1 -0
- package/dist/chrome/discoverability.js +63 -0
- package/dist/chrome/discoverability.js.map +1 -0
- package/dist/chrome/embeds.d.ts +21 -0
- package/dist/chrome/embeds.d.ts.map +1 -0
- package/dist/chrome/embeds.js +181 -0
- package/dist/chrome/embeds.js.map +1 -0
- package/dist/chrome/fluid-thinking.d.ts +15 -0
- package/dist/chrome/fluid-thinking.d.ts.map +1 -0
- package/dist/chrome/fluid-thinking.js +37 -0
- package/dist/chrome/fluid-thinking.js.map +1 -0
- package/dist/chrome/humanize.d.ts +46 -0
- package/dist/chrome/humanize.d.ts.map +1 -0
- package/dist/chrome/humanize.js +104 -0
- package/dist/chrome/humanize.js.map +1 -0
- package/dist/chrome/index.d.ts +39 -0
- package/dist/chrome/index.d.ts.map +1 -0
- package/dist/chrome/index.js +38 -0
- package/dist/chrome/index.js.map +1 -0
- package/dist/chrome/markdown.d.ts +23 -0
- package/dist/chrome/markdown.d.ts.map +1 -0
- package/dist/chrome/markdown.js +149 -0
- package/dist/chrome/markdown.js.map +1 -0
- package/dist/chrome/morph-toast.d.ts +43 -0
- package/dist/chrome/morph-toast.d.ts.map +1 -0
- package/dist/chrome/morph-toast.js +89 -0
- package/dist/chrome/morph-toast.js.map +1 -0
- package/dist/chrome/no-policy-notice.d.ts +8 -0
- package/dist/chrome/no-policy-notice.d.ts.map +1 -0
- package/dist/chrome/no-policy-notice.js +18 -0
- package/dist/chrome/no-policy-notice.js.map +1 -0
- package/dist/chrome/onest-font.gen.d.ts +10 -0
- package/dist/chrome/onest-font.gen.d.ts.map +1 -0
- package/dist/chrome/onest-font.gen.js +10 -0
- package/dist/chrome/onest-font.gen.js.map +1 -0
- package/dist/chrome/overlay-registry.d.ts +66 -0
- package/dist/chrome/overlay-registry.d.ts.map +1 -0
- package/dist/chrome/overlay-registry.js +103 -0
- package/dist/chrome/overlay-registry.js.map +1 -0
- package/dist/chrome/palette-hotkey.d.ts +42 -0
- package/dist/chrome/palette-hotkey.d.ts.map +1 -0
- package/dist/chrome/palette-hotkey.js +91 -0
- package/dist/chrome/palette-hotkey.js.map +1 -0
- package/dist/chrome/policy-notice-body.d.ts +3 -0
- package/dist/chrome/policy-notice-body.d.ts.map +1 -0
- package/dist/chrome/policy-notice-body.js +6 -0
- package/dist/chrome/policy-notice-body.js.map +1 -0
- package/dist/chrome/takeover-portal.d.ts +16 -0
- package/dist/chrome/takeover-portal.d.ts.map +1 -0
- package/dist/chrome/takeover-portal.js +21 -0
- package/dist/chrome/takeover-portal.js.map +1 -0
- package/dist/chrome/thread/attachments.d.ts +24 -0
- package/dist/chrome/thread/attachments.d.ts.map +1 -0
- package/dist/chrome/thread/attachments.js +50 -0
- package/dist/chrome/thread/attachments.js.map +1 -0
- package/dist/chrome/thread/composer.d.ts +63 -0
- package/dist/chrome/thread/composer.d.ts.map +1 -0
- package/dist/chrome/thread/composer.js +259 -0
- package/dist/chrome/thread/composer.js.map +1 -0
- package/dist/chrome/thread/index.d.ts +41 -0
- package/dist/chrome/thread/index.d.ts.map +1 -0
- package/dist/chrome/thread/index.js +258 -0
- package/dist/chrome/thread/index.js.map +1 -0
- package/dist/chrome/thread/message-data.d.ts +35 -0
- package/dist/chrome/thread/message-data.d.ts.map +1 -0
- package/dist/chrome/thread/message-data.js +127 -0
- package/dist/chrome/thread/message-data.js.map +1 -0
- package/dist/chrome/thread/message-list.d.ts +30 -0
- package/dist/chrome/thread/message-list.d.ts.map +1 -0
- package/dist/chrome/thread/message-list.js +11 -0
- package/dist/chrome/thread/message-list.js.map +1 -0
- package/dist/chrome/thread/message.d.ts +18 -0
- package/dist/chrome/thread/message.d.ts.map +1 -0
- package/dist/chrome/thread/message.js +57 -0
- package/dist/chrome/thread/message.js.map +1 -0
- package/dist/chrome/thread/parts.d.ts +53 -0
- package/dist/chrome/thread/parts.d.ts.map +1 -0
- package/dist/chrome/thread/parts.js +184 -0
- package/dist/chrome/thread/parts.js.map +1 -0
- package/dist/chrome/thread/scrolling.d.ts +26 -0
- package/dist/chrome/thread/scrolling.d.ts.map +1 -0
- package/dist/chrome/thread/scrolling.js +214 -0
- package/dist/chrome/thread/scrolling.js.map +1 -0
- package/dist/chrome/truncate.d.ts +12 -0
- package/dist/chrome/truncate.d.ts.map +1 -0
- package/dist/chrome/truncate.js +18 -0
- package/dist/chrome/truncate.js.map +1 -0
- package/dist/chrome/vendo-activities.d.ts +24 -0
- package/dist/chrome/vendo-activities.d.ts.map +1 -0
- package/dist/chrome/vendo-activities.js +38 -0
- package/dist/chrome/vendo-activities.js.map +1 -0
- package/dist/chrome/vendo-overlay.d.ts +63 -0
- package/dist/chrome/vendo-overlay.d.ts.map +1 -0
- package/dist/chrome/vendo-overlay.js +256 -0
- package/dist/chrome/vendo-overlay.js.map +1 -0
- package/dist/chrome/vendo-page.d.ts +3 -0
- package/dist/chrome/vendo-page.d.ts.map +1 -0
- package/dist/chrome/vendo-page.js +162 -0
- package/dist/chrome/vendo-page.js.map +1 -0
- package/dist/chrome/vendo-palette.d.ts +29 -0
- package/dist/chrome/vendo-palette.d.ts.map +1 -0
- package/dist/chrome/vendo-palette.js +95 -0
- package/dist/chrome/vendo-palette.js.map +1 -0
- package/dist/chrome/vendo-slot.d.ts +79 -0
- package/dist/chrome/vendo-slot.d.ts.map +1 -0
- package/dist/chrome/vendo-slot.js +153 -0
- package/dist/chrome/vendo-slot.js.map +1 -0
- package/dist/chrome/vendo-toasts.d.ts +40 -0
- package/dist/chrome/vendo-toasts.d.ts.map +1 -0
- package/dist/chrome/vendo-toasts.js +135 -0
- package/dist/chrome/vendo-toasts.js.map +1 -0
- package/dist/chrome/vendo-trigger.d.ts +24 -0
- package/dist/chrome/vendo-trigger.d.ts.map +1 -0
- package/dist/chrome/vendo-trigger.js +30 -0
- package/dist/chrome/vendo-trigger.js.map +1 -0
- package/dist/chrome/waiting-queue.d.ts +8 -0
- package/dist/chrome/waiting-queue.d.ts.map +1 -0
- package/dist/chrome/waiting-queue.js +21 -0
- package/dist/chrome/waiting-queue.js.map +1 -0
- package/dist/client-impl.d.ts +4 -0
- package/dist/client-impl.d.ts.map +1 -0
- package/dist/client-impl.js +160 -0
- package/dist/client-impl.js.map +1 -0
- package/dist/client.d.ts +136 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -0
- package/dist/context.d.ts +97 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +71 -0
- package/dist/context.js.map +1 -0
- package/dist/eject-templates/activities/index.tsx +113 -0
- package/dist/eject-templates/templates.json +29 -0
- package/dist/eject-templates/thread/attachments.tsx +69 -0
- package/dist/eject-templates/thread/composer.tsx +409 -0
- package/dist/eject-templates/thread/index.tsx +422 -0
- package/dist/eject-templates/thread/message-data.ts +151 -0
- package/dist/eject-templates/thread/message-list.tsx +123 -0
- package/dist/eject-templates/thread/message.tsx +149 -0
- package/dist/eject-templates/thread/parts.tsx +293 -0
- package/dist/eject-templates/thread/scrolling.ts +223 -0
- package/dist/embeds.d.ts +28 -0
- package/dist/embeds.d.ts.map +1 -0
- package/dist/embeds.js +2 -0
- package/dist/embeds.js.map +1 -0
- package/dist/hooks/index.d.ts +18 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +19 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/scripted-transport.d.ts +44 -0
- package/dist/hooks/scripted-transport.d.ts.map +1 -0
- package/dist/hooks/scripted-transport.js +58 -0
- package/dist/hooks/scripted-transport.js.map +1 -0
- package/dist/hooks/use-activity.d.ts +17 -0
- package/dist/hooks/use-activity.d.ts.map +1 -0
- package/dist/hooks/use-activity.js +50 -0
- package/dist/hooks/use-activity.js.map +1 -0
- package/dist/hooks/use-app.d.ts +19 -0
- package/dist/hooks/use-app.d.ts.map +1 -0
- package/dist/hooks/use-app.js +66 -0
- package/dist/hooks/use-app.js.map +1 -0
- package/dist/hooks/use-approvals.d.ts +13 -0
- package/dist/hooks/use-approvals.d.ts.map +1 -0
- package/dist/hooks/use-approvals.js +14 -0
- package/dist/hooks/use-approvals.js.map +1 -0
- package/dist/hooks/use-apps.d.ts +17 -0
- package/dist/hooks/use-apps.d.ts.map +1 -0
- package/dist/hooks/use-apps.js +30 -0
- package/dist/hooks/use-apps.js.map +1 -0
- package/dist/hooks/use-automations.d.ts +25 -0
- package/dist/hooks/use-automations.d.ts.map +1 -0
- package/dist/hooks/use-automations.js +30 -0
- package/dist/hooks/use-automations.js.map +1 -0
- package/dist/hooks/use-connections.d.ts +12 -0
- package/dist/hooks/use-connections.d.ts.map +1 -0
- package/dist/hooks/use-connections.js +15 -0
- package/dist/hooks/use-connections.js.map +1 -0
- package/dist/hooks/use-connector-catalog.d.ts +8 -0
- package/dist/hooks/use-connector-catalog.d.ts.map +1 -0
- package/dist/hooks/use-connector-catalog.js +52 -0
- package/dist/hooks/use-connector-catalog.js.map +1 -0
- package/dist/hooks/use-grants.d.ts +13 -0
- package/dist/hooks/use-grants.d.ts.map +1 -0
- package/dist/hooks/use-grants.js +14 -0
- package/dist/hooks/use-grants.js.map +1 -0
- package/dist/hooks/use-mobile-takeover.d.ts +22 -0
- package/dist/hooks/use-mobile-takeover.d.ts.map +1 -0
- package/dist/hooks/use-mobile-takeover.js +66 -0
- package/dist/hooks/use-mobile-takeover.js.map +1 -0
- package/dist/hooks/use-resource.d.ts +21 -0
- package/dist/hooks/use-resource.d.ts.map +1 -0
- package/dist/hooks/use-resource.js +79 -0
- package/dist/hooks/use-resource.js.map +1 -0
- package/dist/hooks/use-slot-app.d.ts +19 -0
- package/dist/hooks/use-slot-app.d.ts.map +1 -0
- package/dist/hooks/use-slot-app.js +18 -0
- package/dist/hooks/use-slot-app.js.map +1 -0
- package/dist/hooks/use-threads.d.ts +16 -0
- package/dist/hooks/use-threads.d.ts.map +1 -0
- package/dist/hooks/use-threads.js +15 -0
- package/dist/hooks/use-threads.js.map +1 -0
- package/dist/hooks/use-vendo-overlay.d.ts +31 -0
- package/dist/hooks/use-vendo-overlay.d.ts.map +1 -0
- package/dist/hooks/use-vendo-overlay.js +23 -0
- package/dist/hooks/use-vendo-overlay.js.map +1 -0
- package/dist/hooks/use-vendo-status.d.ts +6 -0
- package/dist/hooks/use-vendo-status.d.ts.map +1 -0
- package/dist/hooks/use-vendo-status.js +28 -0
- package/dist/hooks/use-vendo-status.js.map +1 -0
- package/dist/hooks/use-vendo-thread.d.ts +39 -0
- package/dist/hooks/use-vendo-thread.d.ts.map +1 -0
- package/dist/hooks/use-vendo-thread.js +185 -0
- package/dist/hooks/use-vendo-thread.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/kit/charts/bar.d.ts +16 -0
- package/dist/kit/charts/bar.d.ts.map +1 -0
- package/dist/kit/charts/bar.js +21 -0
- package/dist/kit/charts/bar.js.map +1 -0
- package/dist/kit/charts/donut.d.ts +16 -0
- package/dist/kit/charts/donut.d.ts.map +1 -0
- package/dist/kit/charts/donut.js +17 -0
- package/dist/kit/charts/donut.js.map +1 -0
- package/dist/kit/charts/line.d.ts +19 -0
- package/dist/kit/charts/line.d.ts.map +1 -0
- package/dist/kit/charts/line.js +21 -0
- package/dist/kit/charts/line.js.map +1 -0
- package/dist/kit/charts/progress.d.ts +12 -0
- package/dist/kit/charts/progress.d.ts.map +1 -0
- package/dist/kit/charts/progress.js +25 -0
- package/dist/kit/charts/progress.js.map +1 -0
- package/dist/kit/charts/sanitize.d.ts +24 -0
- package/dist/kit/charts/sanitize.d.ts.map +1 -0
- package/dist/kit/charts/sanitize.js +50 -0
- package/dist/kit/charts/sanitize.js.map +1 -0
- package/dist/kit/charts/sparkline.d.ts +11 -0
- package/dist/kit/charts/sparkline.d.ts.map +1 -0
- package/dist/kit/charts/sparkline.js +17 -0
- package/dist/kit/charts/sparkline.js.map +1 -0
- package/dist/kit/data/badge.d.ts +13 -0
- package/dist/kit/data/badge.d.ts.map +1 -0
- package/dist/kit/data/badge.js +12 -0
- package/dist/kit/data/badge.js.map +1 -0
- package/dist/kit/data/card-list.d.ts +23 -0
- package/dist/kit/data/card-list.d.ts.map +1 -0
- package/dist/kit/data/card-list.js +43 -0
- package/dist/kit/data/card-list.js.map +1 -0
- package/dist/kit/data/data-table.d.ts +32 -0
- package/dist/kit/data/data-table.d.ts.map +1 -0
- package/dist/kit/data/data-table.js +153 -0
- package/dist/kit/data/data-table.js.map +1 -0
- package/dist/kit/data/stat.d.ts +15 -0
- package/dist/kit/data/stat.d.ts.map +1 -0
- package/dist/kit/data/stat.js +28 -0
- package/dist/kit/data/stat.js.map +1 -0
- package/dist/kit/feedback/accordion.d.ts +15 -0
- package/dist/kit/feedback/accordion.d.ts.map +1 -0
- package/dist/kit/feedback/accordion.js +33 -0
- package/dist/kit/feedback/accordion.js.map +1 -0
- package/dist/kit/feedback/callout.d.ts +13 -0
- package/dist/kit/feedback/callout.d.ts.map +1 -0
- package/dist/kit/feedback/callout.js +24 -0
- package/dist/kit/feedback/callout.js.map +1 -0
- package/dist/kit/feedback/tabs.d.ts +14 -0
- package/dist/kit/feedback/tabs.d.ts.map +1 -0
- package/dist/kit/feedback/tabs.js +37 -0
- package/dist/kit/feedback/tabs.js.map +1 -0
- package/dist/kit/format.d.ts +60 -0
- package/dist/kit/format.d.ts.map +1 -0
- package/dist/kit/format.js +123 -0
- package/dist/kit/format.js.map +1 -0
- package/dist/kit/forms/button.d.ts +17 -0
- package/dist/kit/forms/button.d.ts.map +1 -0
- package/dist/kit/forms/button.js +33 -0
- package/dist/kit/forms/button.js.map +1 -0
- package/dist/kit/forms/checkbox.d.ts +9 -0
- package/dist/kit/forms/checkbox.d.ts.map +1 -0
- package/dist/kit/forms/checkbox.js +9 -0
- package/dist/kit/forms/checkbox.js.map +1 -0
- package/dist/kit/forms/date-picker.d.ts +13 -0
- package/dist/kit/forms/date-picker.d.ts.map +1 -0
- package/dist/kit/forms/date-picker.js +9 -0
- package/dist/kit/forms/date-picker.js.map +1 -0
- package/dist/kit/forms/disclaimer.d.ts +8 -0
- package/dist/kit/forms/disclaimer.d.ts.map +1 -0
- package/dist/kit/forms/disclaimer.js +20 -0
- package/dist/kit/forms/disclaimer.js.map +1 -0
- package/dist/kit/forms/field.d.ts +18 -0
- package/dist/kit/forms/field.d.ts.map +1 -0
- package/dist/kit/forms/field.js +19 -0
- package/dist/kit/forms/field.js.map +1 -0
- package/dist/kit/forms/form.d.ts +10 -0
- package/dist/kit/forms/form.d.ts.map +1 -0
- package/dist/kit/forms/form.js +9 -0
- package/dist/kit/forms/form.js.map +1 -0
- package/dist/kit/forms/input.d.ts +14 -0
- package/dist/kit/forms/input.d.ts.map +1 -0
- package/dist/kit/forms/input.js +9 -0
- package/dist/kit/forms/input.js.map +1 -0
- package/dist/kit/forms/select.d.ts +21 -0
- package/dist/kit/forms/select.d.ts.map +1 -0
- package/dist/kit/forms/select.js +35 -0
- package/dist/kit/forms/select.js.map +1 -0
- package/dist/kit/forms/textarea.d.ts +12 -0
- package/dist/kit/forms/textarea.d.ts.map +1 -0
- package/dist/kit/forms/textarea.js +9 -0
- package/dist/kit/forms/textarea.js.map +1 -0
- package/dist/kit/index.d.ts +42 -0
- package/dist/kit/index.d.ts.map +1 -0
- package/dist/kit/index.js +45 -0
- package/dist/kit/index.js.map +1 -0
- package/dist/kit/kit-prompt.d.ts +7 -0
- package/dist/kit/kit-prompt.d.ts.map +1 -0
- package/dist/kit/kit-prompt.js +7 -0
- package/dist/kit/kit-prompt.js.map +1 -0
- package/dist/kit/layout.d.ts +29 -0
- package/dist/kit/layout.d.ts.map +1 -0
- package/dist/kit/layout.js +64 -0
- package/dist/kit/layout.js.map +1 -0
- package/dist/kit/registry.d.ts +11 -0
- package/dist/kit/registry.d.ts.map +1 -0
- package/dist/kit/registry.js +34 -0
- package/dist/kit/registry.js.map +1 -0
- package/dist/kit/schema.d.ts +9 -0
- package/dist/kit/schema.d.ts.map +1 -0
- package/dist/kit/schema.js +9 -0
- package/dist/kit/schema.js.map +1 -0
- package/dist/kit/tokens.d.ts +33 -0
- package/dist/kit/tokens.d.ts.map +1 -0
- package/dist/kit/tokens.js +48 -0
- package/dist/kit/tokens.js.map +1 -0
- package/dist/kit/values.d.ts +55 -0
- package/dist/kit/values.d.ts.map +1 -0
- package/dist/kit/values.js +108 -0
- package/dist/kit/values.js.map +1 -0
- package/dist/theme.d.ts +25 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +100 -0
- package/dist/theme.js.map +1 -0
- package/dist/tree/bindings.d.ts +4 -0
- package/dist/tree/bindings.d.ts.map +1 -0
- package/dist/tree/bindings.js +20 -0
- package/dist/tree/bindings.js.map +1 -0
- package/dist/tree/branded.d.ts +124 -0
- package/dist/tree/branded.d.ts.map +1 -0
- package/dist/tree/branded.js +319 -0
- package/dist/tree/branded.js.map +1 -0
- package/dist/tree/error-boundary.d.ts +22 -0
- package/dist/tree/error-boundary.d.ts.map +1 -0
- package/dist/tree/error-boundary.js +25 -0
- package/dist/tree/error-boundary.js.map +1 -0
- package/dist/tree/fluid-reveal.d.ts +22 -0
- package/dist/tree/fluid-reveal.d.ts.map +1 -0
- package/dist/tree/fluid-reveal.js +28 -0
- package/dist/tree/fluid-reveal.js.map +1 -0
- package/dist/tree/forming-skeleton.d.ts +14 -0
- package/dist/tree/forming-skeleton.d.ts.map +1 -0
- package/dist/tree/forming-skeleton.js +36 -0
- package/dist/tree/forming-skeleton.js.map +1 -0
- package/dist/tree/frames.d.ts +52 -0
- package/dist/tree/frames.d.ts.map +1 -0
- package/dist/tree/frames.js +143 -0
- package/dist/tree/frames.js.map +1 -0
- package/dist/tree/host-mount.d.ts +24 -0
- package/dist/tree/host-mount.d.ts.map +1 -0
- package/dist/tree/host-mount.js +0 -0
- package/dist/tree/host-mount.js.map +1 -0
- package/dist/tree/index.d.ts +9 -0
- package/dist/tree/index.d.ts.map +1 -0
- package/dist/tree/index.js +9 -0
- package/dist/tree/index.js.map +1 -0
- package/dist/tree/jail/JailedComponent.d.ts +41 -0
- package/dist/tree/jail/JailedComponent.d.ts.map +1 -0
- package/dist/tree/jail/JailedComponent.js +269 -0
- package/dist/tree/jail/JailedComponent.js.map +1 -0
- package/dist/tree/jail/runtime-bundle.gen.d.ts +3 -0
- package/dist/tree/jail/runtime-bundle.gen.d.ts.map +1 -0
- package/dist/tree/jail/runtime-bundle.gen.js +3 -0
- package/dist/tree/jail/runtime-bundle.gen.js.map +1 -0
- package/dist/tree/jail/runtime-entry.d.ts +18 -0
- package/dist/tree/jail/runtime-entry.d.ts.map +1 -0
- package/dist/tree/jail/runtime-entry.js +440 -0
- package/dist/tree/jail/runtime-entry.js.map +1 -0
- package/dist/tree/jail/viewport-css.d.ts +17 -0
- package/dist/tree/jail/viewport-css.d.ts.map +1 -0
- package/dist/tree/jail/viewport-css.js +32 -0
- package/dist/tree/jail/viewport-css.js.map +1 -0
- package/dist/tree/mcp-shim/entry.d.ts +2 -0
- package/dist/tree/mcp-shim/entry.d.ts.map +1 -0
- package/dist/tree/mcp-shim/entry.js +45 -0
- package/dist/tree/mcp-shim/entry.js.map +1 -0
- package/dist/tree/mcp-shim/http-open-card.d.ts +5 -0
- package/dist/tree/mcp-shim/http-open-card.d.ts.map +1 -0
- package/dist/tree/mcp-shim/http-open-card.js +61 -0
- package/dist/tree/mcp-shim/http-open-card.js.map +1 -0
- package/dist/tree/mcp-shim/shim-core.d.ts +58 -0
- package/dist/tree/mcp-shim/shim-core.d.ts.map +1 -0
- package/dist/tree/mcp-shim/shim-core.js +176 -0
- package/dist/tree/mcp-shim/shim-core.js.map +1 -0
- package/dist/tree/mcp-shim/theme.d.ts +8 -0
- package/dist/tree/mcp-shim/theme.d.ts.map +1 -0
- package/dist/tree/mcp-shim/theme.js +36 -0
- package/dist/tree/mcp-shim/theme.js.map +1 -0
- package/dist/tree/notice.d.ts +8 -0
- package/dist/tree/notice.d.ts.map +1 -0
- package/dist/tree/notice.js +30 -0
- package/dist/tree/notice.js.map +1 -0
- package/dist/tree/primitives.d.ts +30 -0
- package/dist/tree/primitives.d.ts.map +1 -0
- package/dist/tree/primitives.js +105 -0
- package/dist/tree/primitives.js.map +1 -0
- package/dist/tree/renderer-v2.d.ts +15 -0
- package/dist/tree/renderer-v2.d.ts.map +1 -0
- package/dist/tree/renderer-v2.js +71 -0
- package/dist/tree/renderer-v2.js.map +1 -0
- package/dist/tree/renderer.d.ts +77 -0
- package/dist/tree/renderer.d.ts.map +1 -0
- package/dist/tree/renderer.js +376 -0
- package/dist/tree/renderer.js.map +1 -0
- package/dist/voice/driver.d.ts +94 -0
- package/dist/voice/driver.d.ts.map +1 -0
- package/dist/voice/driver.js +2 -0
- package/dist/voice/driver.js.map +1 -0
- package/dist/voice/index.d.ts +7 -0
- package/dist/voice/index.d.ts.map +1 -0
- package/dist/voice/index.js +5 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/realtime-driver.d.ts +57 -0
- package/dist/voice/realtime-driver.d.ts.map +1 -0
- package/dist/voice/realtime-driver.js +592 -0
- package/dist/voice/realtime-driver.js.map +1 -0
- package/dist/voice/stage.d.ts +12 -0
- package/dist/voice/stage.d.ts.map +1 -0
- package/dist/voice/stage.js +259 -0
- package/dist/voice/stage.js.map +1 -0
- package/dist/voice/use-voice-approvals.d.ts +16 -0
- package/dist/voice/use-voice-approvals.d.ts.map +1 -0
- package/dist/voice/use-voice-approvals.js +77 -0
- package/dist/voice/use-voice-approvals.js.map +1 -0
- package/dist/voice/use-voice.d.ts +26 -0
- package/dist/voice/use-voice.d.ts.map +1 -0
- package/dist/voice/use-voice.js +201 -0
- package/dist/voice/use-voice.js.map +1 -0
- package/dist/voice/voice-act.d.ts +13 -0
- package/dist/voice/voice-act.d.ts.map +1 -0
- package/dist/voice/voice-act.js +301 -0
- package/dist/voice/voice-act.js.map +1 -0
- package/dist/voice/voice-blob.d.ts +17 -0
- package/dist/voice/voice-blob.d.ts.map +1 -0
- package/dist/voice/voice-blob.js +67 -0
- package/dist/voice/voice-blob.js.map +1 -0
- package/dist/voice/voice-consent.d.ts +17 -0
- package/dist/voice/voice-consent.d.ts.map +1 -0
- package/dist/voice/voice-consent.js +45 -0
- package/dist/voice/voice-consent.js.map +1 -0
- package/dist/voice/voice-drawer.d.ts +10 -0
- package/dist/voice/voice-drawer.d.ts.map +1 -0
- package/dist/voice/voice-drawer.js +22 -0
- package/dist/voice/voice-drawer.js.map +1 -0
- package/dist/wire-types.d.ts +238 -0
- package/dist/wire-types.d.ts.map +1 -0
- package/dist/wire-types.js +2 -0
- package/dist/wire-types.js.map +1 -0
- package/package.json +106 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ejected from @vendoai/ui v0.4.0 — yours to edit.
|
|
3
|
+
* Presentation only: data and wire logic still flow through @vendoai/ui
|
|
4
|
+
* imports, so protocol updates keep working while these pixels are yours.
|
|
5
|
+
*/
|
|
6
|
+
import type { RiskLabel } from "@vendoai/core";
|
|
7
|
+
import type { UIMessage } from "ai";
|
|
8
|
+
import type { ComponentProps } from "react";
|
|
9
|
+
import { FluidThinking } from "../fluid-thinking.js";
|
|
10
|
+
import { ThreadMessage } from "./message.js";
|
|
11
|
+
import { ThreadApprovals, ThreadConnectRequests } from "./parts.js";
|
|
12
|
+
import type { useMessageWindow, useStickToBottom } from "./scrolling.js";
|
|
13
|
+
|
|
14
|
+
/** The transcript pane: the windowed message list (ENG-218), parked approval
|
|
15
|
+
and connect cards, the ENG-217 streaming indicators, and the jump-to-latest
|
|
16
|
+
affordance (ENG-213). Pure presentation over the thread-level state. */
|
|
17
|
+
export function MessageList({
|
|
18
|
+
scroll, messageWindow, busy, risks, isRestored,
|
|
19
|
+
activeAssistantId, lastUserId, lastAssistantId, onEditLast, onRegenerateLast,
|
|
20
|
+
approvals, guardApprovals, cardRefs, respond, onMorph,
|
|
21
|
+
messages, sendMessage, awaitingFirstChunk, working,
|
|
22
|
+
}: {
|
|
23
|
+
scroll: ReturnType<typeof useStickToBottom>;
|
|
24
|
+
messageWindow: ReturnType<typeof useMessageWindow>;
|
|
25
|
+
busy: boolean;
|
|
26
|
+
risks: Map<string, RiskLabel>;
|
|
27
|
+
isRestored: (id: string) => boolean;
|
|
28
|
+
activeAssistantId?: string | undefined;
|
|
29
|
+
lastUserId?: string | undefined;
|
|
30
|
+
lastAssistantId?: string | undefined;
|
|
31
|
+
onEditLast: () => void;
|
|
32
|
+
onRegenerateLast: () => void;
|
|
33
|
+
approvals: ComponentProps<typeof ThreadApprovals>["approvals"];
|
|
34
|
+
guardApprovals: ComponentProps<typeof ThreadApprovals>["guardApprovals"];
|
|
35
|
+
cardRefs: ComponentProps<typeof ThreadApprovals>["cardRefs"];
|
|
36
|
+
respond: ComponentProps<typeof ThreadApprovals>["respond"];
|
|
37
|
+
onMorph: ComponentProps<typeof ThreadApprovals>["onMorph"];
|
|
38
|
+
messages: UIMessage[];
|
|
39
|
+
sendMessage: ComponentProps<typeof ThreadConnectRequests>["sendMessage"];
|
|
40
|
+
awaitingFirstChunk: boolean;
|
|
41
|
+
working: boolean;
|
|
42
|
+
}) {
|
|
43
|
+
return (
|
|
44
|
+
<div className="fl-msglist-wrap">
|
|
45
|
+
{/* role="log" — aria-label is prohibited on a roleless div (WCAG 4.1.2), and a
|
|
46
|
+
streaming message list is exactly what "log" names. */}
|
|
47
|
+
<div
|
|
48
|
+
className="fl-msglist"
|
|
49
|
+
role="log"
|
|
50
|
+
aria-label="Conversation messages"
|
|
51
|
+
aria-live="polite"
|
|
52
|
+
aria-busy={busy}
|
|
53
|
+
ref={scroll.listRef}
|
|
54
|
+
onScroll={() => { scroll.onScroll(); messageWindow.onNearTop(); }}
|
|
55
|
+
>
|
|
56
|
+
{messageWindow.hasOlder ? (
|
|
57
|
+
<button
|
|
58
|
+
type="button"
|
|
59
|
+
className="fl-load-older"
|
|
60
|
+
onClick={messageWindow.loadOlder}
|
|
61
|
+
>
|
|
62
|
+
Show {messageWindow.olderCount} earlier message{messageWindow.olderCount === 1 ? "" : "s"}
|
|
63
|
+
</button>
|
|
64
|
+
) : null}
|
|
65
|
+
{messageWindow.windowed.map(message => (
|
|
66
|
+
<ThreadMessage
|
|
67
|
+
key={message.id}
|
|
68
|
+
message={message}
|
|
69
|
+
restored={isRestored(message.id)}
|
|
70
|
+
risks={risks}
|
|
71
|
+
busy={busy}
|
|
72
|
+
activeAssistantId={activeAssistantId}
|
|
73
|
+
lastUserId={lastUserId}
|
|
74
|
+
lastAssistantId={lastAssistantId}
|
|
75
|
+
onEditLast={onEditLast}
|
|
76
|
+
onRegenerateLast={onRegenerateLast}
|
|
77
|
+
/>
|
|
78
|
+
))}
|
|
79
|
+
<ThreadApprovals
|
|
80
|
+
approvals={approvals}
|
|
81
|
+
risks={risks}
|
|
82
|
+
guardApprovals={guardApprovals}
|
|
83
|
+
cardRefs={cardRefs}
|
|
84
|
+
respond={respond}
|
|
85
|
+
onMorph={onMorph}
|
|
86
|
+
/>
|
|
87
|
+
<ThreadConnectRequests messages={messages} sendMessage={sendMessage} />
|
|
88
|
+
{awaitingFirstChunk ? (
|
|
89
|
+
<>
|
|
90
|
+
<div className="fl-generating">
|
|
91
|
+
<span className="fl-pulse" aria-hidden="true" />
|
|
92
|
+
Generating…
|
|
93
|
+
</div>
|
|
94
|
+
<div className="fl-skeleton" aria-hidden="true">
|
|
95
|
+
<div className="fl-skeleton-bar" />
|
|
96
|
+
<div className="fl-skeleton-bar" />
|
|
97
|
+
<div className="fl-skeleton-bar" />
|
|
98
|
+
</div>
|
|
99
|
+
</>
|
|
100
|
+
) : null}
|
|
101
|
+
{working ? <FluidThinking label="Working" /> : null}
|
|
102
|
+
</div>
|
|
103
|
+
{/* Lane picks 3A + 6B — the jump affordance is a docked bar with a
|
|
104
|
+
count and snippet ("2 new replies · …"); at mobile widths the same
|
|
105
|
+
element re-clothes as a bottom-center pill (pure CSS, see the lane
|
|
106
|
+
block in chrome-css). Activating it is the same re-stick as before. */}
|
|
107
|
+
{scroll.showJump ? (
|
|
108
|
+
<button
|
|
109
|
+
type="button"
|
|
110
|
+
className="fl-newbar"
|
|
111
|
+
aria-label={`Jump to latest — ${scroll.unseenCount === 1 ? "1 new reply" : `${scroll.unseenCount} new replies`}`}
|
|
112
|
+
onClick={scroll.jumpToLatest}
|
|
113
|
+
>
|
|
114
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
|
115
|
+
<path d="M12 5v14" /><path d="m19 12-7 7-7-7" />
|
|
116
|
+
</svg>
|
|
117
|
+
{scroll.unseenCount === 1 ? "1 new reply" : `${scroll.unseenCount} new replies`}
|
|
118
|
+
{scroll.snippet ? <small>{scroll.snippet}</small> : null}
|
|
119
|
+
</button>
|
|
120
|
+
) : null}
|
|
121
|
+
</div>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ejected from @vendoai/ui v0.4.0 — yours to edit.
|
|
3
|
+
* Presentation only: data and wire logic still flow through @vendoai/ui
|
|
4
|
+
* imports, so protocol updates keep working while these pixels are yours.
|
|
5
|
+
*/
|
|
6
|
+
import type { RiskLabel } from "@vendoai/core";
|
|
7
|
+
import { isToolUIPart, type UIMessage } from "ai";
|
|
8
|
+
import { Fragment } from "react";
|
|
9
|
+
import { useVendoContext } from "../../context.js";
|
|
10
|
+
import { useCopyFeedback } from "../clipboard.js";
|
|
11
|
+
import { toolTitle } from "../humanize.js";
|
|
12
|
+
import { SentAttachment, type FilePart } from "./attachments.js";
|
|
13
|
+
import { assistantText, collapseToolRuns, toolName, userText } from "./message-data.js";
|
|
14
|
+
import { ThreadPart } from "./parts.js";
|
|
15
|
+
|
|
16
|
+
/** Lane pick 8C — the settled turn's quiet sources row: every completed tool
|
|
17
|
+
call the turn drew on, as informational chips ("what did it read?"). The
|
|
18
|
+
full mechanical record stays in the Activity panel; these are the in-place
|
|
19
|
+
scent. Only read-risk calls qualify — writes are actions, not sources. */
|
|
20
|
+
function TurnSources({ message, risks }: { message: UIMessage; risks: Map<string, RiskLabel> }) {
|
|
21
|
+
const { tools } = useVendoContext();
|
|
22
|
+
// Identical repeated calls collapse to one chip with a ×N count — the same
|
|
23
|
+
// ENG-216 run-collapse identity (name + args) the old beat stack used.
|
|
24
|
+
const sources = collapseToolRuns(message.parts).filter(({ part }) =>
|
|
25
|
+
isToolUIPart(part) && part.state === "output-available"
|
|
26
|
+
&& (risks.get(part.toolCallId) ?? "read") === "read");
|
|
27
|
+
if (sources.length === 0) return null;
|
|
28
|
+
return (
|
|
29
|
+
<div className="fl-sources" aria-label="Sources">
|
|
30
|
+
{sources.map(({ part, count }) => {
|
|
31
|
+
const toolPart = part as Extract<UIMessage["parts"][number], { toolCallId: string }>;
|
|
32
|
+
const name = toolName(toolPart);
|
|
33
|
+
return (
|
|
34
|
+
<span className="fl-source" key={toolPart.toolCallId} title="Recorded in Activity">
|
|
35
|
+
<i aria-hidden="true" />
|
|
36
|
+
{toolTitle(name, tools[name])}
|
|
37
|
+
{count > 1 ? <span className="fl-source-count" aria-label={`repeated ${count} times`}>×{count}</span> : null}
|
|
38
|
+
</span>
|
|
39
|
+
);
|
|
40
|
+
})}
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** ENG-225 — the copy turn action (.fl-turn-actions design). */
|
|
46
|
+
function CopyTurnButton({ text }: { text: string }) {
|
|
47
|
+
const [copied, copy] = useCopyFeedback();
|
|
48
|
+
return (
|
|
49
|
+
<button type="button" className="fl-turn-btn" aria-label="Copy message" onClick={() => copy(text)}>
|
|
50
|
+
{copied ? (
|
|
51
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
|
52
|
+
<path d="M20 6 9 17l-5-5" />
|
|
53
|
+
</svg>
|
|
54
|
+
) : (
|
|
55
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
|
56
|
+
<rect width="13" height="13" x="9" y="9" rx="2" /><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
|
|
57
|
+
</svg>
|
|
58
|
+
)}
|
|
59
|
+
{copied ? "Copied" : "Copy"}
|
|
60
|
+
</button>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** One turn in the transcript: the user attachments beside the bubble
|
|
65
|
+
(ENG-225), the article with its stream parts, and the settled-turn
|
|
66
|
+
actions (Copy always; Edit on the last user turn, Regenerate on the
|
|
67
|
+
last assistant turn — ENG-215). */
|
|
68
|
+
export function ThreadMessage({ message, restored, risks, busy, activeAssistantId, lastUserId, lastAssistantId, onEditLast, onRegenerateLast }: {
|
|
69
|
+
message: UIMessage;
|
|
70
|
+
restored: boolean;
|
|
71
|
+
risks: Map<string, RiskLabel>;
|
|
72
|
+
busy: boolean;
|
|
73
|
+
activeAssistantId?: string | undefined;
|
|
74
|
+
lastUserId?: string | undefined;
|
|
75
|
+
lastAssistantId?: string | undefined;
|
|
76
|
+
onEditLast: () => void;
|
|
77
|
+
onRegenerateLast: () => void;
|
|
78
|
+
}) {
|
|
79
|
+
// ENG-225 — a user turn's attachments render BESIDE the bubble
|
|
80
|
+
// (the designed .fl-turn-user-att block), not inside it; a
|
|
81
|
+
// files-only send has no bubble at all.
|
|
82
|
+
const sentFiles = message.role === "user"
|
|
83
|
+
? message.parts.filter((part): part is FilePart => part.type === "file")
|
|
84
|
+
: [];
|
|
85
|
+
const bubbleText = message.role === "user" ? userText(message) : assistantText(message);
|
|
86
|
+
const skipBubble = message.role === "user" && bubbleText.length === 0
|
|
87
|
+
&& message.parts.every(part => part.type === "file");
|
|
88
|
+
// ENG-225 — every settled turn carries a Copy action (hover-
|
|
89
|
+
// revealed, see chrome-css); Edit stays on the last user turn and
|
|
90
|
+
// Regenerate on the last assistant turn (ENG-215). The actively
|
|
91
|
+
// streaming turn gets no actions — its text is still arriving.
|
|
92
|
+
const streamingTurn = busy && message.role === "assistant" && message.id === activeAssistantId;
|
|
93
|
+
const showEdit = !busy && message.role === "user" && message.id === lastUserId;
|
|
94
|
+
const showRegenerate = !busy && message.role === "assistant" && message.id === lastAssistantId;
|
|
95
|
+
const showActions = !streamingTurn && (bubbleText.length > 0 || showEdit || showRegenerate);
|
|
96
|
+
return (
|
|
97
|
+
<Fragment>
|
|
98
|
+
{sentFiles.length > 0 ? (
|
|
99
|
+
<div className={`fl-turn-user-att${restored ? " fl-no-entrance" : ""}`}>
|
|
100
|
+
{sentFiles.map((part, index) => <SentAttachment key={index} part={part} />)}
|
|
101
|
+
</div>
|
|
102
|
+
) : null}
|
|
103
|
+
{skipBubble ? null : (
|
|
104
|
+
<article
|
|
105
|
+
className={`${message.role === "user" ? "fl-turn-user" : "fl-turn-assistant"}${
|
|
106
|
+
restored ? " fl-no-entrance" : ""}`}
|
|
107
|
+
data-role={message.role}
|
|
108
|
+
aria-label={`${message.role} message`}
|
|
109
|
+
>
|
|
110
|
+
{collapseToolRuns(message.parts).map(({ part, index, count }) => (
|
|
111
|
+
<ThreadPart
|
|
112
|
+
key={`${message.id}-${index}`}
|
|
113
|
+
part={part}
|
|
114
|
+
partKey={`${message.id}-${index}`}
|
|
115
|
+
role={message.role}
|
|
116
|
+
restored={restored}
|
|
117
|
+
count={count}
|
|
118
|
+
risks={risks}
|
|
119
|
+
/>
|
|
120
|
+
))}
|
|
121
|
+
{!streamingTurn && message.role === "assistant" ? (
|
|
122
|
+
<TurnSources message={message} risks={risks} />
|
|
123
|
+
) : null}
|
|
124
|
+
{showActions ? (
|
|
125
|
+
<div className="fl-turn-actions">
|
|
126
|
+
{bubbleText.length > 0 ? <CopyTurnButton text={bubbleText} /> : null}
|
|
127
|
+
{showEdit ? (
|
|
128
|
+
<button type="button" className="fl-turn-btn" aria-label="Edit message" onClick={onEditLast}>
|
|
129
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
|
130
|
+
<path d="M12 20h9" /><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z" />
|
|
131
|
+
</svg>
|
|
132
|
+
Edit
|
|
133
|
+
</button>
|
|
134
|
+
) : null}
|
|
135
|
+
{showRegenerate ? (
|
|
136
|
+
<button type="button" className="fl-turn-btn" aria-label="Regenerate" onClick={onRegenerateLast}>
|
|
137
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
|
138
|
+
<path d="M3 12a9 9 0 0 1 15-6.7L21 8" /><path d="M21 3v5h-5" /><path d="M21 12a9 9 0 0 1-15 6.7L3 16" /><path d="M3 21v-5h5" />
|
|
139
|
+
</svg>
|
|
140
|
+
Regenerate
|
|
141
|
+
</button>
|
|
142
|
+
) : null}
|
|
143
|
+
</div>
|
|
144
|
+
) : null}
|
|
145
|
+
</article>
|
|
146
|
+
)}
|
|
147
|
+
</Fragment>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ejected from @vendoai/ui v0.4.0 — yours to edit.
|
|
3
|
+
* Presentation only: data and wire logic still flow through @vendoai/ui
|
|
4
|
+
* imports, so protocol updates keep working while these pixels are yours.
|
|
5
|
+
*/
|
|
6
|
+
import type { ApprovalRequest, Json, RiskLabel, VendoViewPart } from "@vendoai/core";
|
|
7
|
+
import { isToolUIPart, type UIMessage } from "ai";
|
|
8
|
+
import { useState } from "react";
|
|
9
|
+
import { useVendoContext } from "../../context.js";
|
|
10
|
+
import { useMobileTakeover } from "../../hooks/use-mobile-takeover.js";
|
|
11
|
+
import { PayloadView } from "../../tree/renderer.js";
|
|
12
|
+
import { ApprovalCard } from "../approval-card.js";
|
|
13
|
+
import { ApprovalSheet } from "../approval-sheet.js";
|
|
14
|
+
import { BuildBeat, toolPresentation } from "../build-beat.js";
|
|
15
|
+
import { ConnectCard } from "../connect-card.js";
|
|
16
|
+
import { toolTitle } from "../humanize.js";
|
|
17
|
+
import { Markdown } from "../markdown.js";
|
|
18
|
+
import type { MorphToastProps } from "../morph-toast.js";
|
|
19
|
+
import { LONG_TEXT_CAP, truncateHead } from "../truncate.js";
|
|
20
|
+
import { SentAttachment } from "./attachments.js";
|
|
21
|
+
import {
|
|
22
|
+
appTitle,
|
|
23
|
+
partData,
|
|
24
|
+
preview,
|
|
25
|
+
SYNTHESIZED_CREATED_AT,
|
|
26
|
+
toolName,
|
|
27
|
+
} from "./message-data.js";
|
|
28
|
+
|
|
29
|
+
/** ENG-218 — a plain user turn (rendered verbatim, not markdown) collapses when
|
|
30
|
+
huge so a pasted log doesn't flood the thread with DOM. Assistant turns get
|
|
31
|
+
the same treatment inside <Markdown>. */
|
|
32
|
+
function UserText({ text, restored }: { text: string; restored?: boolean }) {
|
|
33
|
+
const [expanded, setExpanded] = useState(false);
|
|
34
|
+
const collapsible = restored === true && text.length > LONG_TEXT_CAP;
|
|
35
|
+
const shown = collapsible && !expanded ? truncateHead(text) : text;
|
|
36
|
+
if (!collapsible) return <div className="fl-usertext">{text}</div>;
|
|
37
|
+
// Lane pick 3D — the collapsed head sits under a gradient fade with a
|
|
38
|
+
// centered pill (GitHub-fold style) instead of a hard cut + inline link:
|
|
39
|
+
// the fade shows the content continues, and the control sits where the
|
|
40
|
+
// eye stops. Expanded keeps the pill below for symmetry.
|
|
41
|
+
return (
|
|
42
|
+
<div className={`fl-fold${expanded ? " fl-fold--open" : ""}`}>
|
|
43
|
+
<div className="fl-usertext">{shown}</div>
|
|
44
|
+
<div className="fl-fold-veil">
|
|
45
|
+
<button type="button" className="fl-more fl-fold-pill" aria-expanded={expanded} onClick={() => setExpanded(value => !value)}>
|
|
46
|
+
{expanded ? "Show less" : `Show full message (${(text.length / 1000).toFixed(0)}k chars)`}
|
|
47
|
+
</button>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** One stream part in a turn: text (user verbatim / assistant markdown with the
|
|
54
|
+
ENG-217 caret choreography), assistant files, tool build beats, and the
|
|
55
|
+
jailed generated-view app card (06-apps §§8–9). */
|
|
56
|
+
export function ThreadPart({ part, partKey, role, restored, count = 1, risks }: {
|
|
57
|
+
part: UIMessage["parts"][number];
|
|
58
|
+
partKey: string;
|
|
59
|
+
role: UIMessage["role"];
|
|
60
|
+
restored: boolean;
|
|
61
|
+
count?: number;
|
|
62
|
+
risks: Map<string, RiskLabel>;
|
|
63
|
+
}) {
|
|
64
|
+
const { client, components, onPin } = useVendoContext();
|
|
65
|
+
if (part.type === "text") {
|
|
66
|
+
if (role === "user") return <UserText text={part.text} restored={restored} />;
|
|
67
|
+
// ENG-217 — lone caret while the streamed turn is still empty (stable
|
|
68
|
+
// line box); once text flows, Markdown's .fl-md--streaming trailing
|
|
69
|
+
// caret takes over.
|
|
70
|
+
if (part.state === "streaming" && part.text.trim().length === 0) {
|
|
71
|
+
return <span className="fl-caret" aria-hidden="true" />;
|
|
72
|
+
}
|
|
73
|
+
return <Markdown text={part.text} streaming={part.state === "streaming"} restored={restored} />;
|
|
74
|
+
}
|
|
75
|
+
if (part.type === "file") {
|
|
76
|
+
// ENG-225 — user attachments render beside the bubble (see the message
|
|
77
|
+
// map); an assistant-authored file lands inline in the turn.
|
|
78
|
+
if (role === "user") return null;
|
|
79
|
+
return <SentAttachment part={part} />;
|
|
80
|
+
}
|
|
81
|
+
if (isToolUIPart(part)) {
|
|
82
|
+
// Lane pick C1 — live progress moved to the StatusRibbon above the
|
|
83
|
+
// composer, so working/done calls leave NO transcript line (the
|
|
84
|
+
// mechanical record stays in the Activity panel). A FAILED call is
|
|
85
|
+
// content, not progress: it keeps the error beat so the failure stays
|
|
86
|
+
// readable after the turn settles.
|
|
87
|
+
if (part.state !== "output-error") return null;
|
|
88
|
+
const risk = risks.get(part.toolCallId) ?? "read";
|
|
89
|
+
return <BuildBeat part={part} risk={risk} count={count} />;
|
|
90
|
+
}
|
|
91
|
+
if (part.type === "data-vendo-view") {
|
|
92
|
+
const data = partData(part) as Partial<VendoViewPart>;
|
|
93
|
+
if (typeof data.appId !== "string" || !data.payload) return null;
|
|
94
|
+
// 06-apps §§8–9 — in-thread surfaces are conversational previews, never
|
|
95
|
+
// the approved in-client venue and never a drift report: both fields are
|
|
96
|
+
// server-authoritative, so whatever the stream carried, render jailed
|
|
97
|
+
// and notice-free.
|
|
98
|
+
const {
|
|
99
|
+
inClient: _neverInThread,
|
|
100
|
+
pinDrift: _serverOnly,
|
|
101
|
+
...payload
|
|
102
|
+
} = data.payload as typeof data.payload & { inClient?: unknown; pinDrift?: unknown };
|
|
103
|
+
const streaming = (payload as { streaming?: boolean }).streaming === true;
|
|
104
|
+
const appId = data.appId;
|
|
105
|
+
return (
|
|
106
|
+
// The generated view lives inside a clear app boundary — a titled
|
|
107
|
+
// frame — so it reads as a distinct piece of software, not loose
|
|
108
|
+
// content bleeding into the surrounding chat text.
|
|
109
|
+
<div className="fl-uihost fl-appcard" key={`${partKey}-${appId}`}>
|
|
110
|
+
{/* Pick C (ui-lane-renderer): the bar narrates forming → live. The
|
|
111
|
+
data-state contract ("building" | "ready") is shared with the
|
|
112
|
+
thread lane; the label pair stays mounted so the swap crossfades. */}
|
|
113
|
+
<div className="fl-appcard-bar" data-state={streaming ? "building" : "ready"}>
|
|
114
|
+
<span className="fl-appcard-dot" aria-hidden="true" />
|
|
115
|
+
<span className="fl-boot-labels fl-appcard-name">
|
|
116
|
+
{/* Both labels stay mounted for the renderer lane's crossfade;
|
|
117
|
+
aria-hidden tracks data-state so screen readers hear only the
|
|
118
|
+
ACTIVE one (AI-review catch — the CSS-faded label was still
|
|
119
|
+
announced, including a stale "Building…" after ready). */}
|
|
120
|
+
<span className="fl-boot-building" aria-hidden={!streaming}>Building your view…</span>
|
|
121
|
+
<span className="fl-boot-ready" aria-hidden={streaming}>{appTitle(payload) ?? "Your app"}</span>
|
|
122
|
+
</span>
|
|
123
|
+
{/* Lane pick C5 (5A+5D) — the pin lives ON the bar (visible only once
|
|
124
|
+
the view is ready), replacing the old full-width footer row. The
|
|
125
|
+
renderer lane's data-state/label/hairline markup above is the
|
|
126
|
+
shared contract and stays untouched. */}
|
|
127
|
+
{!streaming && onPin ? (
|
|
128
|
+
<button
|
|
129
|
+
type="button"
|
|
130
|
+
className="fl-barpin"
|
|
131
|
+
onClick={() => onPin({ appId, payload })}
|
|
132
|
+
>
|
|
133
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
|
|
134
|
+
<path d="M12 17v5M9 3h6l-1 7 3 3H7l3-3-1-7Z" />
|
|
135
|
+
</svg>
|
|
136
|
+
Pin to dashboard
|
|
137
|
+
</button>
|
|
138
|
+
) : null}
|
|
139
|
+
<span className="fl-boot-hairline" aria-hidden="true" />
|
|
140
|
+
</div>
|
|
141
|
+
<div className="fl-appcard-body">
|
|
142
|
+
<PayloadView
|
|
143
|
+
payload={payload}
|
|
144
|
+
components={components}
|
|
145
|
+
onAction={({ action, payload: actionPayload }) => client.apps.call(appId, action, actionPayload ?? {})}
|
|
146
|
+
/>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
type ToolPart = Extract<UIMessage["parts"][number], { toolCallId: string }>;
|
|
155
|
+
|
|
156
|
+
/** The parked in-thread approval cards: each synthesizes an ApprovalRequest
|
|
157
|
+
from the wire parts (ENG-216), morphs into the top-right toast on approve
|
|
158
|
+
(ENG-205), and decides the guard's record over the wire before resuming
|
|
159
|
+
the model loop (05 §1). */
|
|
160
|
+
export function ThreadApprovals({ approvals, risks, guardApprovals, cardRefs, respond, onMorph }: {
|
|
161
|
+
approvals: (ToolPart & { state: "approval-requested"; approval: { id: string } })[];
|
|
162
|
+
risks: Map<string, RiskLabel>;
|
|
163
|
+
guardApprovals: Map<string, { approvalId?: string; invalidatedGrant?: ApprovalRequest["invalidatedGrant"] }>;
|
|
164
|
+
cardRefs: React.MutableRefObject<Map<string, HTMLDivElement | null>>;
|
|
165
|
+
respond: (response: { id: string; approved: boolean }) => void;
|
|
166
|
+
onMorph: (morph: Omit<MorphToastProps, "onDone">) => void;
|
|
167
|
+
}) {
|
|
168
|
+
const { client, theme, tools } = useVendoContext();
|
|
169
|
+
// Lane pick 1-H — below the mobile breakpoint the NEWEST parked approval
|
|
170
|
+
// presents as a bottom sheet (thumb-zone consent); older parked ones stay
|
|
171
|
+
// in-list behind it so the thread record is complete when the sheet closes.
|
|
172
|
+
const mobile = useMobileTakeover().active;
|
|
173
|
+
return (
|
|
174
|
+
<>
|
|
175
|
+
{approvals.map((part, index) => {
|
|
176
|
+
const risk = risks.get(part.toolCallId) ?? "read";
|
|
177
|
+
const input = "input" in part ? part.input : undefined;
|
|
178
|
+
const guardApproval = guardApprovals.get(part.toolCallId);
|
|
179
|
+
const name = toolName(part);
|
|
180
|
+
const approval: ApprovalRequest = {
|
|
181
|
+
id: part.approval.id,
|
|
182
|
+
call: { id: part.toolCallId, tool: name, args: input as Json },
|
|
183
|
+
// The wire approval part carries no descriptor (01-core), so the
|
|
184
|
+
// name is the raw tool id (ApprovalCard humanizes it) and the
|
|
185
|
+
// description is left to host metadata — never a fabricated
|
|
186
|
+
// "Approve <tool>" sentence.
|
|
187
|
+
descriptor: { name, description: tools[name]?.description ?? "", inputSchema: {}, risk },
|
|
188
|
+
inputPreview: preview(input),
|
|
189
|
+
...(guardApproval?.invalidatedGrant === undefined
|
|
190
|
+
? {}
|
|
191
|
+
: { invalidatedGrant: guardApproval.invalidatedGrant }),
|
|
192
|
+
// ENG-216 — the in-thread card renders inside the live conversation,
|
|
193
|
+
// which IS its context, and the wire carries no ctx: rather than
|
|
194
|
+
// invent a principal/venue/presence and stamp a per-render `new
|
|
195
|
+
// Date()`, we hide the context byline in-thread (showContext=false)
|
|
196
|
+
// and only structurally-true, stable values ride here (never shown).
|
|
197
|
+
ctx: { principal: { kind: "user", subject: "" }, venue: "chat", presence: "present" },
|
|
198
|
+
createdAt: SYNTHESIZED_CREATED_AT,
|
|
199
|
+
};
|
|
200
|
+
const guardApprovalId = guardApproval?.approvalId;
|
|
201
|
+
const asSheet = mobile && index === approvals.length - 1;
|
|
202
|
+
const card = (
|
|
203
|
+
<div key={part.approval.id} ref={element => { cardRefs.current.set(part.approval.id, element); }}>
|
|
204
|
+
<ApprovalCard
|
|
205
|
+
approval={approval}
|
|
206
|
+
showContext={false}
|
|
207
|
+
allowRemember={guardApprovalId !== undefined}
|
|
208
|
+
onDecide={async decision => {
|
|
209
|
+
// The approved card lifts into the top-right notification
|
|
210
|
+
// (ENG-205 morph) as the run resumes underneath it.
|
|
211
|
+
if (decision.approve) {
|
|
212
|
+
const card = cardRefs.current.get(part.approval.id)?.querySelector<HTMLElement>(".fl-approval");
|
|
213
|
+
if (card) {
|
|
214
|
+
const presentation = toolPresentation(name, input, tools[name]);
|
|
215
|
+
const rect = card.getBoundingClientRect();
|
|
216
|
+
card.style.transition = "opacity .22s ease";
|
|
217
|
+
card.style.opacity = "0";
|
|
218
|
+
onMorph({
|
|
219
|
+
startRect: { top: rect.top, left: rect.left, width: rect.width, height: rect.height },
|
|
220
|
+
title: `${presentation.title} — approved`,
|
|
221
|
+
sub: presentation.sub ?? "Runs as you · recorded in Activity",
|
|
222
|
+
logoUrl: presentation.logoUrl,
|
|
223
|
+
theme,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// Decide the guard's approval record over the wire FIRST so the
|
|
228
|
+
// resumed execution replays as approved (05 §1) — the native
|
|
229
|
+
// response alone only tells the model loop to continue.
|
|
230
|
+
if (guardApprovalId !== undefined) {
|
|
231
|
+
await client.approvals.decide([guardApprovalId], decision);
|
|
232
|
+
}
|
|
233
|
+
respond({ id: part.approval.id, approved: decision.approve });
|
|
234
|
+
}}
|
|
235
|
+
/>
|
|
236
|
+
</div>
|
|
237
|
+
);
|
|
238
|
+
return asSheet ? (
|
|
239
|
+
<ApprovalSheet key={part.approval.id} label={`Approval for ${toolTitle(name, tools[name])}`}>
|
|
240
|
+
{card}
|
|
241
|
+
</ApprovalSheet>
|
|
242
|
+
) : card;
|
|
243
|
+
})}
|
|
244
|
+
</>
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** 04-actions §3 — connector calls that ended `connect-required`, from the
|
|
249
|
+
LAST assistant message only: a stale turn must not re-offer a connect
|
|
250
|
+
(the persistent panel covers standing management). The typed outcome on
|
|
251
|
+
the native tool part is the source of truth; the data-vendo-connect part
|
|
252
|
+
mirrors it for streaming consumers, matching the approvals pattern. */
|
|
253
|
+
export function ThreadConnectRequests({ messages, sendMessage }: {
|
|
254
|
+
messages: UIMessage[];
|
|
255
|
+
sendMessage: (message: { text: string }) => unknown;
|
|
256
|
+
}) {
|
|
257
|
+
const lastMessage = messages.at(-1);
|
|
258
|
+
const connectRequests = (lastMessage?.role === "assistant" ? lastMessage.parts : [])
|
|
259
|
+
.filter(isToolUIPart)
|
|
260
|
+
.flatMap(part => {
|
|
261
|
+
if (part.state !== "output-available") return [];
|
|
262
|
+
const output = part.output as { status?: unknown; connect?: unknown } | undefined;
|
|
263
|
+
const connect = output?.status === "connect-required"
|
|
264
|
+
? output.connect as { connector?: unknown; toolkit?: unknown; message?: unknown } | undefined
|
|
265
|
+
: undefined;
|
|
266
|
+
if (typeof connect?.connector !== "string" || typeof connect.toolkit !== "string") return [];
|
|
267
|
+
return [{
|
|
268
|
+
part,
|
|
269
|
+
connector: connect.connector,
|
|
270
|
+
toolkit: connect.toolkit,
|
|
271
|
+
message: typeof connect.message === "string" ? connect.message : `Connect ${connect.toolkit} to continue.`,
|
|
272
|
+
}];
|
|
273
|
+
});
|
|
274
|
+
return (
|
|
275
|
+
<>
|
|
276
|
+
{connectRequests.map(({ part, connector, toolkit, message }) => (
|
|
277
|
+
<ConnectCard
|
|
278
|
+
key={`connect-${part.toolCallId}`}
|
|
279
|
+
connector={connector}
|
|
280
|
+
toolkit={toolkit}
|
|
281
|
+
message={message}
|
|
282
|
+
onConnected={() => {
|
|
283
|
+
// The retry: the account is live, so continue the turn — the
|
|
284
|
+
// model re-issues the call, which now executes.
|
|
285
|
+
void sendMessage({
|
|
286
|
+
text: `I connected my ${toolkit} account — retry ${toolName(part)}.`,
|
|
287
|
+
});
|
|
288
|
+
}}
|
|
289
|
+
/>
|
|
290
|
+
))}
|
|
291
|
+
</>
|
|
292
|
+
);
|
|
293
|
+
}
|