@agent-native/core 0.14.8 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +30 -9
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +14 -4
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +71 -4
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/types.d.ts +9 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/appearance/actions/change-appearance.d.ts +3 -0
- package/dist/appearance/actions/change-appearance.d.ts.map +1 -0
- package/dist/appearance/actions/change-appearance.js +29 -0
- package/dist/appearance/actions/change-appearance.js.map +1 -0
- package/dist/chat-threads/store.d.ts +53 -2
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +172 -12
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +114 -37
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +30 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/workspace-dev.d.ts +25 -1
- package/dist/cli/workspace-dev.d.ts.map +1 -1
- package/dist/cli/workspace-dev.js +275 -49
- package/dist/cli/workspace-dev.js.map +1 -1
- package/dist/client/AgentPanel.d.ts +23 -4
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +276 -53
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AppearancePicker.d.ts +11 -0
- package/dist/client/AppearancePicker.d.ts.map +1 -0
- package/dist/client/AppearancePicker.js +16 -0
- package/dist/client/AppearancePicker.js.map +1 -0
- package/dist/client/AssistantChat.d.ts +35 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +315 -32
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
- package/dist/client/ConnectBuilderCard.js +5 -2
- package/dist/client/ConnectBuilderCard.js.map +1 -1
- package/dist/client/ErrorBoundary.d.ts.map +1 -1
- package/dist/client/ErrorBoundary.js +8 -10
- package/dist/client/ErrorBoundary.js.map +1 -1
- package/dist/client/FeedbackButton.d.ts.map +1 -1
- package/dist/client/FeedbackButton.js +1 -1
- package/dist/client/FeedbackButton.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts +13 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +217 -38
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
- package/dist/client/NewWorkspaceAppFlow.js +37 -14
- package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts +5 -0
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +4 -0
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-sidebar-state.d.ts +12 -0
- package/dist/client/agent-sidebar-state.d.ts.map +1 -1
- package/dist/client/agent-sidebar-state.js +8 -0
- package/dist/client/agent-sidebar-state.js.map +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +175 -3
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/appearance.d.ts +40 -0
- package/dist/client/appearance.d.ts.map +1 -0
- package/dist/client/appearance.js +114 -0
- package/dist/client/appearance.js.map +1 -0
- package/dist/client/builder-frame.d.ts +1 -0
- package/dist/client/builder-frame.d.ts.map +1 -1
- package/dist/client/builder-frame.js +19 -9
- package/dist/client/builder-frame.js.map +1 -1
- package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
- package/dist/client/components/CodeRequiredDialog.js +10 -2
- package/dist/client/components/CodeRequiredDialog.js.map +1 -1
- package/dist/client/components/ui/dropdown-menu.js +2 -2
- package/dist/client/components/ui/dropdown-menu.js.map +1 -1
- package/dist/client/components/ui/hover-card.js +1 -1
- package/dist/client/components/ui/hover-card.js.map +1 -1
- package/dist/client/components/ui/popover.js +1 -1
- package/dist/client/components/ui/popover.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts +7 -0
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +63 -32
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +5 -0
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +36 -6
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
- package/dist/client/composer/useVoiceDictation.js +13 -1
- package/dist/client/composer/useVoiceDictation.js.map +1 -1
- package/dist/client/dev-mode.d.ts +14 -0
- package/dist/client/dev-mode.d.ts.map +1 -0
- package/dist/client/dev-mode.js +14 -0
- package/dist/client/dev-mode.js.map +1 -0
- package/dist/client/error-format.d.ts +3 -2
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +9 -2
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/extensions/EmbeddedTool.d.ts +20 -0
- package/dist/client/extensions/EmbeddedTool.d.ts.map +1 -0
- package/dist/client/extensions/EmbeddedTool.js +199 -0
- package/dist/client/extensions/EmbeddedTool.js.map +1 -0
- package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionViewer.js +24 -2
- package/dist/client/extensions/ExtensionViewer.js.map +1 -1
- package/dist/client/extensions/ToolEditor.d.ts +5 -0
- package/dist/client/extensions/ToolEditor.d.ts.map +1 -0
- package/dist/client/extensions/ToolEditor.js +129 -0
- package/dist/client/extensions/ToolEditor.js.map +1 -0
- package/dist/client/extensions/ToolViewer.d.ts +5 -0
- package/dist/client/extensions/ToolViewer.d.ts.map +1 -0
- package/dist/client/extensions/ToolViewer.js +400 -0
- package/dist/client/extensions/ToolViewer.js.map +1 -0
- package/dist/client/extensions/ToolViewerPage.d.ts +2 -0
- package/dist/client/extensions/ToolViewerPage.d.ts.map +1 -0
- package/dist/client/extensions/ToolViewerPage.js +24 -0
- package/dist/client/extensions/ToolViewerPage.js.map +1 -0
- package/dist/client/extensions/ToolsListPage.d.ts +2 -0
- package/dist/client/extensions/ToolsListPage.d.ts.map +1 -0
- package/dist/client/extensions/ToolsListPage.js +67 -0
- package/dist/client/extensions/ToolsListPage.js.map +1 -0
- package/dist/client/extensions/ToolsSidebarSection.d.ts +2 -0
- package/dist/client/extensions/ToolsSidebarSection.d.ts.map +1 -0
- package/dist/client/extensions/ToolsSidebarSection.js +236 -0
- package/dist/client/extensions/ToolsSidebarSection.js.map +1 -0
- package/dist/client/extensions/tool-order.d.ts +7 -0
- package/dist/client/extensions/tool-order.d.ts.map +1 -0
- package/dist/client/extensions/tool-order.js +47 -0
- package/dist/client/extensions/tool-order.js.map +1 -0
- package/dist/client/index.d.ts +8 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +7 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.js +1 -0
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/org/InvitationBanner.d.ts.map +1 -1
- package/dist/client/org/InvitationBanner.js +23 -2
- package/dist/client/org/InvitationBanner.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +5 -4
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +57 -9
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/hooks.d.ts.map +1 -1
- package/dist/client/org/hooks.js +10 -6
- package/dist/client/org/hooks.js.map +1 -1
- package/dist/client/org/workspace-app-links.d.ts +31 -0
- package/dist/client/org/workspace-app-links.d.ts.map +1 -0
- package/dist/client/org/workspace-app-links.js +268 -0
- package/dist/client/org/workspace-app-links.js.map +1 -0
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +18 -5
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-resources.d.ts +18 -13
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js +24 -6
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -1
- package/dist/client/settings/BackgroundAgentSection.js +9 -1
- package/dist/client/settings/BackgroundAgentSection.js.map +1 -1
- package/dist/client/settings/BrowserSection.d.ts.map +1 -1
- package/dist/client/settings/BrowserSection.js +16 -1
- package/dist/client/settings/BrowserSection.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +4 -1
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.js +5 -5
- package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +8 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +50 -13
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.spec.d.ts +2 -0
- package/dist/client/settings/useBuilderStatus.spec.d.ts.map +1 -0
- package/dist/client/settings/useBuilderStatus.spec.js +64 -0
- package/dist/client/settings/useBuilderStatus.spec.js.map +1 -0
- package/dist/client/sharing/ShareButton.d.ts +5 -0
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +60 -6
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/theme.js +1 -1
- package/dist/client/theme.js.map +1 -1
- package/dist/client/tools/EmbeddedTool.d.ts +20 -0
- package/dist/client/tools/EmbeddedTool.d.ts.map +1 -0
- package/dist/client/tools/EmbeddedTool.js +199 -0
- package/dist/client/tools/EmbeddedTool.js.map +1 -0
- package/dist/client/tools/ExtensionSlot.d.ts +27 -0
- package/dist/client/tools/ExtensionSlot.d.ts.map +1 -0
- package/dist/client/tools/ExtensionSlot.js +96 -0
- package/dist/client/tools/ExtensionSlot.js.map +1 -0
- package/dist/client/tools/ToolEditor.d.ts +5 -0
- package/dist/client/tools/ToolEditor.d.ts.map +1 -0
- package/dist/client/tools/ToolEditor.js +129 -0
- package/dist/client/tools/ToolEditor.js.map +1 -0
- package/dist/client/tools/ToolViewer.d.ts +5 -0
- package/dist/client/tools/ToolViewer.d.ts.map +1 -0
- package/dist/client/tools/ToolViewer.js +400 -0
- package/dist/client/tools/ToolViewer.js.map +1 -0
- package/dist/client/tools/ToolViewerPage.d.ts +2 -0
- package/dist/client/tools/ToolViewerPage.d.ts.map +1 -0
- package/dist/client/tools/ToolViewerPage.js +24 -0
- package/dist/client/tools/ToolViewerPage.js.map +1 -0
- package/dist/client/tools/ToolsListPage.d.ts +2 -0
- package/dist/client/tools/ToolsListPage.d.ts.map +1 -0
- package/dist/client/tools/ToolsListPage.js +67 -0
- package/dist/client/tools/ToolsListPage.js.map +1 -0
- package/dist/client/tools/ToolsSidebarSection.d.ts +2 -0
- package/dist/client/tools/ToolsSidebarSection.d.ts.map +1 -0
- package/dist/client/tools/ToolsSidebarSection.js +236 -0
- package/dist/client/tools/ToolsSidebarSection.js.map +1 -0
- package/dist/client/tools/iframe-bridge.d.ts +38 -0
- package/dist/client/tools/iframe-bridge.d.ts.map +1 -0
- package/dist/client/tools/iframe-bridge.js +207 -0
- package/dist/client/tools/iframe-bridge.js.map +1 -0
- package/dist/client/tools/index.d.ts +8 -0
- package/dist/client/tools/index.d.ts.map +1 -0
- package/dist/client/tools/index.js +8 -0
- package/dist/client/tools/index.js.map +1 -0
- package/dist/client/tools/tool-order.d.ts +7 -0
- package/dist/client/tools/tool-order.d.ts.map +1 -0
- package/dist/client/tools/tool-order.js +47 -0
- package/dist/client/tools/tool-order.js.map +1 -0
- package/dist/client/transcription/BuilderTranscriptionCta.d.ts.map +1 -1
- package/dist/client/transcription/BuilderTranscriptionCta.js +2 -3
- package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -1
- package/dist/client/use-change-version.d.ts +46 -0
- package/dist/client/use-change-version.d.ts.map +1 -0
- package/dist/client/use-change-version.js +135 -0
- package/dist/client/use-change-version.js.map +1 -0
- package/dist/client/use-chat-threads.d.ts +16 -2
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +87 -12
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/use-chat-threads.spec.d.ts +2 -0
- package/dist/client/use-chat-threads.spec.d.ts.map +1 -0
- package/dist/client/use-chat-threads.spec.js +85 -0
- package/dist/client/use-chat-threads.spec.js.map +1 -0
- package/dist/client/use-db-sync.d.ts +5 -2
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +41 -16
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/client/use-pinch-zoom.d.ts +35 -0
- package/dist/client/use-pinch-zoom.d.ts.map +1 -0
- package/dist/client/use-pinch-zoom.js +105 -0
- package/dist/client/use-pinch-zoom.js.map +1 -0
- package/dist/deploy/workspace-deploy.d.ts.map +1 -1
- package/dist/deploy/workspace-deploy.js +99 -5
- package/dist/deploy/workspace-deploy.js.map +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +3 -0
- package/dist/extensions/actions.js.map +1 -1
- package/dist/extensions/store.d.ts +5 -0
- package/dist/extensions/store.d.ts.map +1 -1
- package/dist/extensions/store.js +16 -1
- package/dist/extensions/store.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +3 -0
- package/dist/file-upload/actions/upload-image.d.ts.map +1 -0
- package/dist/file-upload/actions/upload-image.js +145 -0
- package/dist/file-upload/actions/upload-image.js.map +1 -0
- package/dist/file-upload/builder.d.ts.map +1 -1
- package/dist/file-upload/builder.js +31 -11
- package/dist/file-upload/builder.js.map +1 -1
- package/dist/file-upload/index.d.ts +1 -0
- package/dist/file-upload/index.d.ts.map +1 -1
- package/dist/file-upload/index.js +1 -0
- package/dist/file-upload/index.js.map +1 -1
- package/dist/file-upload/pre-upload-attachments.d.ts +39 -0
- package/dist/file-upload/pre-upload-attachments.d.ts.map +1 -0
- package/dist/file-upload/pre-upload-attachments.js +110 -0
- package/dist/file-upload/pre-upload-attachments.js.map +1 -0
- package/dist/file-upload/registry.d.ts.map +1 -1
- package/dist/file-upload/registry.js +8 -7
- package/dist/file-upload/registry.js.map +1 -1
- package/dist/onboarding/default-steps.js +1 -1
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/org/context.d.ts +15 -1
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +25 -0
- package/dist/org/context.js.map +1 -1
- package/dist/org/handlers.d.ts +2 -2
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +3 -17
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/index.d.ts +1 -1
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +1 -1
- package/dist/org/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +6 -0
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +30 -6
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/script-helpers.d.ts +11 -2
- package/dist/resources/script-helpers.d.ts.map +1 -1
- package/dist/resources/script-helpers.js +20 -3
- package/dist/resources/script-helpers.js.map +1 -1
- package/dist/resources/store.d.ts +28 -3
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +170 -20
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/resources/list.d.ts +1 -1
- package/dist/scripts/resources/list.d.ts.map +1 -1
- package/dist/scripts/resources/list.js +16 -4
- package/dist/scripts/resources/list.js.map +1 -1
- package/dist/scripts/resources/write.d.ts +1 -1
- package/dist/scripts/resources/write.d.ts.map +1 -1
- package/dist/scripts/resources/write.js +47 -3
- package/dist/scripts/resources/write.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +8 -3
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +214 -25
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts +35 -0
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +139 -8
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/app-url.d.ts +12 -6
- package/dist/server/app-url.d.ts.map +1 -1
- package/dist/server/app-url.js +58 -11
- package/dist/server/app-url.js.map +1 -1
- package/dist/server/auth.d.ts +22 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +316 -65
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +0 -4
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +0 -3
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +23 -0
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +29 -14
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +14 -0
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +88 -11
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/google-auth-plugin.d.ts.map +1 -1
- package/dist/server/google-auth-plugin.js +65 -17
- package/dist/server/google-auth-plugin.js.map +1 -1
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +47 -17
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/local-migration.d.ts +41 -0
- package/dist/server/local-migration.d.ts.map +1 -0
- package/dist/server/local-migration.js +235 -0
- package/dist/server/local-migration.js.map +1 -0
- package/dist/server/oauth-public-origin.d.ts.map +1 -1
- package/dist/server/oauth-public-origin.js +19 -1
- package/dist/server/oauth-public-origin.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +74 -19
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +20 -5
- package/dist/server/poll.js.map +1 -1
- package/dist/server/request-context.d.ts +8 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js.map +1 -1
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +2 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/llm-connection.d.ts +10 -0
- package/dist/shared/llm-connection.d.ts.map +1 -0
- package/dist/shared/llm-connection.js +29 -0
- package/dist/shared/llm-connection.js.map +1 -0
- package/dist/shared/workspace-app-audience.d.ts +25 -0
- package/dist/shared/workspace-app-audience.d.ts.map +1 -0
- package/dist/shared/workspace-app-audience.js +126 -0
- package/dist/shared/workspace-app-audience.js.map +1 -0
- package/dist/shared/workspace-app-id.d.ts +1 -1
- package/dist/shared/workspace-app-id.d.ts.map +1 -1
- package/dist/shared/workspace-app-id.js +1 -0
- package/dist/shared/workspace-app-id.js.map +1 -1
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +46 -5
- package/dist/sharing/access.js.map +1 -1
- package/dist/sharing/actions/list-resource-shares.d.ts.map +1 -1
- package/dist/sharing/actions/list-resource-shares.js +8 -1
- package/dist/sharing/actions/list-resource-shares.js.map +1 -1
- package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -1
- package/dist/sharing/actions/set-resource-visibility.js +12 -3
- package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
- package/dist/sharing/actions/share-resource.d.ts.map +1 -1
- package/dist/sharing/actions/share-resource.js +50 -1
- package/dist/sharing/actions/share-resource.js.map +1 -1
- package/dist/sharing/registry.d.ts +26 -0
- package/dist/sharing/registry.d.ts.map +1 -1
- package/dist/sharing/registry.js.map +1 -1
- package/dist/styles/agent-native.css +91 -0
- package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +72 -0
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +60 -37
- package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +28 -17
- package/dist/templates/default/.agents/skills/shadcn-ui/SKILL.md +79 -0
- package/dist/templates/default/AGENTS.md +22 -19
- package/dist/templates/default/actions/navigate.ts +3 -0
- package/dist/templates/default/app/hooks/use-navigation-state.ts +29 -5
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +251 -0
- package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +264 -0
- package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +130 -0
- package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +112 -0
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +88 -0
- package/dist/templates/workspace-core/.agents/skills/automations/SKILL.md +191 -0
- package/dist/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +74 -0
- package/dist/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +75 -0
- package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +190 -0
- package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +168 -0
- package/dist/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +163 -0
- package/dist/templates/workspace-core/.agents/skills/extension-points/SKILL.md +205 -0
- package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +720 -0
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +92 -0
- package/dist/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +285 -0
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +192 -0
- package/dist/templates/workspace-core/.agents/skills/onboarding/SKILL.md +43 -0
- package/dist/templates/workspace-core/.agents/skills/portability/SKILL.md +84 -0
- package/dist/templates/workspace-core/.agents/skills/qa/SKILL.md +313 -0
- package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +112 -0
- package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +165 -0
- package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +41 -0
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +239 -0
- package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +191 -0
- package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +79 -0
- package/dist/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +73 -0
- package/dist/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +79 -0
- package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +217 -0
- package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +132 -0
- package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +150 -0
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +124 -0
- package/dist/templates/workspace-core/AGENTS.md +16 -1
- package/dist/templates/workspace-root/AGENTS.md +35 -0
- package/dist/templates/workspace-root/README.md +7 -0
- package/dist/tools/actions.d.ts +3 -0
- package/dist/tools/actions.d.ts.map +1 -0
- package/dist/tools/actions.js +272 -0
- package/dist/tools/actions.js.map +1 -0
- package/dist/tools/fetch-tool.d.ts +23 -0
- package/dist/tools/fetch-tool.d.ts.map +1 -0
- package/dist/tools/fetch-tool.js +178 -0
- package/dist/tools/fetch-tool.js.map +1 -0
- package/dist/tools/html-shell.d.ts +45 -0
- package/dist/tools/html-shell.d.ts.map +1 -0
- package/dist/tools/html-shell.js +514 -0
- package/dist/tools/html-shell.js.map +1 -0
- package/dist/tools/proxy-security.d.ts +12 -0
- package/dist/tools/proxy-security.d.ts.map +1 -0
- package/dist/tools/proxy-security.js +158 -0
- package/dist/tools/proxy-security.js.map +1 -0
- package/dist/tools/routes.d.ts +2 -0
- package/dist/tools/routes.d.ts.map +1 -0
- package/dist/tools/routes.js +627 -0
- package/dist/tools/routes.js.map +1 -0
- package/dist/tools/schema.d.ts +664 -0
- package/dist/tools/schema.d.ts.map +1 -0
- package/dist/tools/schema.js +146 -0
- package/dist/tools/schema.js.map +1 -0
- package/dist/tools/slots/routes.d.ts +15 -0
- package/dist/tools/slots/routes.d.ts.map +1 -0
- package/dist/tools/slots/routes.js +94 -0
- package/dist/tools/slots/routes.js.map +1 -0
- package/dist/tools/slots/schema.d.ts +303 -0
- package/dist/tools/slots/schema.d.ts.map +1 -0
- package/dist/tools/slots/schema.js +76 -0
- package/dist/tools/slots/schema.js.map +1 -0
- package/dist/tools/slots/store.d.ts +66 -0
- package/dist/tools/slots/store.d.ts.map +1 -0
- package/dist/tools/slots/store.js +227 -0
- package/dist/tools/slots/store.js.map +1 -0
- package/dist/tools/store.d.ts +40 -0
- package/dist/tools/store.d.ts.map +1 -0
- package/dist/tools/store.js +193 -0
- package/dist/tools/store.js.map +1 -0
- package/dist/tools/theme.d.ts +2 -0
- package/dist/tools/theme.d.ts.map +1 -0
- package/dist/tools/theme.js +67 -0
- package/dist/tools/theme.js.map +1 -0
- package/dist/tools/url-safety.d.ts +24 -0
- package/dist/tools/url-safety.d.ts.map +1 -0
- package/dist/tools/url-safety.js +224 -0
- package/dist/tools/url-safety.js.map +1 -0
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +4 -0
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/docs/content/authentication.md +36 -0
- package/docs/content/creating-templates.md +15 -0
- package/docs/content/dispatch.md +3 -3
- package/docs/content/multi-app-workspace.md +5 -0
- package/docs/content/tracking.md +12 -0
- package/docs/content/workspace-management.md +39 -4
- package/package.json +15 -12
- package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +72 -0
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +60 -37
- package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +28 -17
- package/src/templates/default/.agents/skills/shadcn-ui/SKILL.md +79 -0
- package/src/templates/default/AGENTS.md +22 -19
- package/src/templates/default/actions/navigate.ts +3 -0
- package/src/templates/default/app/hooks/use-navigation-state.ts +29 -5
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +251 -0
- package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +264 -0
- package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +130 -0
- package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +112 -0
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +88 -0
- package/src/templates/workspace-core/.agents/skills/automations/SKILL.md +191 -0
- package/src/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +74 -0
- package/src/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +75 -0
- package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +190 -0
- package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +168 -0
- package/src/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +163 -0
- package/src/templates/workspace-core/.agents/skills/extension-points/SKILL.md +205 -0
- package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +720 -0
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +92 -0
- package/src/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +285 -0
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +192 -0
- package/src/templates/workspace-core/.agents/skills/onboarding/SKILL.md +43 -0
- package/src/templates/workspace-core/.agents/skills/portability/SKILL.md +84 -0
- package/src/templates/workspace-core/.agents/skills/qa/SKILL.md +313 -0
- package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +112 -0
- package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +165 -0
- package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +41 -0
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +239 -0
- package/src/templates/workspace-core/.agents/skills/security/SKILL.md +191 -0
- package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +79 -0
- package/src/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +73 -0
- package/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +79 -0
- package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +217 -0
- package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +132 -0
- package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +150 -0
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +124 -0
- package/src/templates/workspace-core/AGENTS.md +16 -1
- package/src/templates/workspace-root/AGENTS.md +35 -0
- package/src/templates/workspace-root/README.md +7 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/extensions/store.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { eq } from \"drizzle-orm\";\nimport { getDbExec, isPostgres, retryOnDdlRace } from \"../db/client.js\";\nimport { createGetDb } from \"../db/create-get-db.js\";\nimport {\n accessFilter,\n assertAccess,\n resolveAccess,\n} from \"../sharing/access.js\";\nimport {\n getRequestUserEmail,\n getRequestOrgId,\n} from \"../server/request-context.js\";\nimport { registerShareableResource } from \"../sharing/registry.js\";\nimport {\n extensions,\n extensionHides,\n extensionShares,\n EXTENSIONS_CREATE_SQL,\n EXTENSIONS_CREATE_SQL_PG,\n EXTENSION_SHARES_CREATE_SQL,\n EXTENSION_SHARES_CREATE_SQL_PG,\n EXTENSION_DATA_CREATE_SQL,\n EXTENSION_DATA_CREATE_SQL_PG,\n EXTENSION_DATA_ITEM_INDEX_SQL,\n EXTENSION_DATA_ITEM_INDEX_SQL_PG,\n EXTENSION_DATA_DROP_OLD_INDEX_SQL,\n EXTENSION_DATA_DROP_OLD_INDEX_SQL_PG,\n EXTENSIONS_OWNER_INDEX_SQL,\n EXTENSIONS_ORG_INDEX_SQL,\n EXTENSION_SHARES_RESOURCE_INDEX_SQL,\n EXTENSION_HIDES_CREATE_SQL,\n EXTENSION_HIDES_CREATE_SQL_PG,\n EXTENSION_HIDES_UNIQUE_INDEX_SQL,\n EXTENSION_HIDES_OWNER_INDEX_SQL,\n EXTENSION_CONSENTS_CREATE_SQL,\n EXTENSION_CONSENTS_CREATE_SQL_PG,\n EXTENSION_CONSENTS_VIEWER_INDEX_SQL,\n} from \"./schema.js\";\n\nconst getDb = createGetDb({ extensions, extensionShares, extensionHides });\n\nlet _initPromise: Promise<void> | undefined;\n\nexport async function ensureExtensionsTables(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const pg = isPostgres();\n await retryOnDdlRace(() =>\n client.execute(pg ? EXTENSIONS_CREATE_SQL_PG : EXTENSIONS_CREATE_SQL),\n );\n await migrateMisnamedExtensionsTable(client, pg);\n await retryOnDdlRace(() =>\n client.execute(\n pg ? EXTENSION_SHARES_CREATE_SQL_PG : EXTENSION_SHARES_CREATE_SQL,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n pg ? EXTENSION_DATA_CREATE_SQL_PG : EXTENSION_DATA_CREATE_SQL,\n ),\n );\n await ensureExtensionDataItemId(client, pg);\n await ensureExtensionDataScope(client, pg);\n await client.execute(\n pg\n ? EXTENSION_DATA_DROP_OLD_INDEX_SQL_PG\n : EXTENSION_DATA_DROP_OLD_INDEX_SQL,\n );\n await retryOnDdlRace(() =>\n client.execute(\n pg ? EXTENSION_DATA_ITEM_INDEX_SQL_PG : EXTENSION_DATA_ITEM_INDEX_SQL,\n ),\n );\n await retryOnDdlRace(() => client.execute(EXTENSIONS_OWNER_INDEX_SQL));\n await retryOnDdlRace(() => client.execute(EXTENSIONS_ORG_INDEX_SQL));\n await retryOnDdlRace(() =>\n client.execute(EXTENSION_SHARES_RESOURCE_INDEX_SQL),\n );\n await retryOnDdlRace(() =>\n client.execute(\n pg ? EXTENSION_HIDES_CREATE_SQL_PG : EXTENSION_HIDES_CREATE_SQL,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(EXTENSION_HIDES_UNIQUE_INDEX_SQL),\n );\n await retryOnDdlRace(() =>\n client.execute(EXTENSION_HIDES_OWNER_INDEX_SQL),\n );\n // tool_consents was introduced for an audit-C1 per-viewer consent\n // gate that we removed once we settled on intra-org trust as the\n // baseline. The table is kept (additive — never drop) so deploys\n // that already created it stay healthy; the runtime consent code\n // is gone. Idempotent CREATE IF NOT EXISTS for fresh schemas.\n await retryOnDdlRace(() =>\n client.execute(\n pg ? EXTENSION_CONSENTS_CREATE_SQL_PG : EXTENSION_CONSENTS_CREATE_SQL,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(EXTENSION_CONSENTS_VIEWER_INDEX_SQL),\n );\n })();\n }\n\n try {\n await _initPromise;\n } catch (err) {\n _initPromise = undefined;\n throw err;\n }\n}\n\nasync function migrateMisnamedExtensionsTable(\n client: ReturnType<typeof getDbExec>,\n pg: boolean,\n): Promise<void> {\n const sql = pg\n ? `INSERT INTO tools (id, name, description, content, icon, created_at, updated_at, owner_email, org_id, visibility)\n SELECT id, name, description, content, icon, created_at, updated_at, owner_email, org_id, visibility\n FROM extensions\n ON CONFLICT (id) DO NOTHING`\n : `INSERT OR IGNORE INTO tools (id, name, description, content, icon, created_at, updated_at, owner_email, org_id, visibility)\n SELECT id, name, description, content, icon, created_at, updated_at, owner_email, org_id, visibility\n FROM extensions`;\n\n try {\n await client.execute(sql);\n } catch (err: any) {\n const message = String(err?.message ?? err).toLowerCase();\n if (\n message.includes(\"no such table: extensions\") ||\n message.includes('relation \"extensions\" does not exist') ||\n message.includes(\"relation extensions does not exist\")\n ) {\n return;\n }\n throw err;\n }\n}\n\nasync function ensureExtensionDataItemId(\n client: ReturnType<typeof getDbExec>,\n pg: boolean,\n): Promise<void> {\n if (pg) {\n await client.execute(\n `ALTER TABLE tool_data ADD COLUMN IF NOT EXISTS item_id TEXT`,\n );\n return;\n }\n\n // Keep this additive: legacy rows with item_id=id are still read correctly\n // through COALESCE(item_id, id), so SQLite never needs a table rebuild here.\n try {\n await client.execute(`ALTER TABLE tool_data ADD COLUMN item_id TEXT`);\n } catch (err: any) {\n if (\n !String(err?.message ?? err)\n .toLowerCase()\n .includes(\"duplicate\")\n ) {\n throw err;\n }\n }\n}\n\nasync function ensureExtensionDataScope(\n client: ReturnType<typeof getDbExec>,\n pg: boolean,\n): Promise<void> {\n const addCol = (name: string, def: string) => {\n if (pg) {\n return client.execute(\n `ALTER TABLE tool_data ADD COLUMN IF NOT EXISTS ${name} ${def}`,\n );\n }\n return client\n .execute(`ALTER TABLE tool_data ADD COLUMN ${name} ${def}`)\n .catch((err: any) => {\n if (\n !String(err?.message ?? err)\n .toLowerCase()\n .includes(\"duplicate\")\n )\n throw err;\n });\n };\n await addCol(\"scope\", \"TEXT NOT NULL DEFAULT 'user'\");\n await addCol(\"org_id\", \"TEXT\");\n await addCol(\"scope_key\", \"TEXT NOT NULL DEFAULT 'local@localhost'\");\n // One-time backfill migration: replaces the dev-mode DEFAULT scope_key\n // with each row's real owner_email. Not a per-request fallback.\n await client.execute(\n // guard:allow-localhost-fallback — one-time backfill migration replacing dev-mode default scope_key with the row's real owner_email\n `UPDATE tool_data SET scope_key = owner_email WHERE scope_key = 'local@localhost' AND owner_email != 'local@localhost'`,\n );\n}\n\nexport function registerExtensionsShareable() {\n registerShareableResource({\n type: \"extension\",\n resourceTable: extensions,\n sharesTable: extensionShares,\n displayName: \"Extension\",\n titleColumn: \"name\",\n getDb: () => getDb(),\n });\n}\n\nexport interface ExtensionRow {\n id: string;\n name: string;\n description: string;\n content: string;\n icon: string | null;\n createdAt: string;\n updatedAt: string;\n ownerEmail: string;\n orgId: string | null;\n visibility: \"private\" | \"org\" | \"public\";\n}\n\nexport interface ListExtensionsOptions {\n includeHidden?: boolean;\n}\n\nexport async function listExtensions(\n options: ListExtensionsOptions = {},\n): Promise<ExtensionRow[]> {\n await ensureExtensionsTables();\n const db = getDb();\n const rows = (await db\n .select()\n .from(extensions)\n .where(accessFilter(extensions, extensionShares))) as ExtensionRow[];\n\n if (options.includeHidden) return rows;\n\n const hiddenIds = await getHiddenExtensionIdsForCurrentUser();\n if (hiddenIds.size === 0) return rows;\n return rows.filter((row) => !hiddenIds.has(row.id));\n}\n\nexport async function getExtension(id: string): Promise<ExtensionRow | null> {\n await ensureExtensionsTables();\n const access = await resolveAccess(\"extension\", id);\n return (access?.resource as ExtensionRow | undefined) ?? null;\n}\n\nexport interface CreateExtensionData {\n name: string;\n description?: string;\n content?: string;\n icon?: string;\n}\n\nexport async function createExtension(\n data: CreateExtensionData,\n): Promise<ExtensionRow> {\n await ensureExtensionsTables();\n const db = getDb();\n const userEmail = getRequestUserEmail();\n if (!userEmail) throw new Error(\"no authenticated user\");\n const orgId = getRequestOrgId();\n const id = randomUUID();\n const now = new Date().toISOString();\n const row: ExtensionRow = {\n id,\n name: data.name,\n description: data.description ?? \"\",\n content: data.content ?? \"\",\n icon: data.icon ?? null,\n createdAt: now,\n updatedAt: now,\n ownerEmail: userEmail,\n orgId: orgId ?? null,\n visibility: \"private\",\n };\n await db.insert(extensions).values(row);\n return row;\n}\n\nexport interface UpdateExtensionData {\n name?: string;\n description?: string;\n icon?: string;\n visibility?: \"private\" | \"org\" | \"public\";\n}\n\nexport async function updateExtension(\n id: string,\n data: UpdateExtensionData,\n): Promise<ExtensionRow | null> {\n await ensureExtensionsTables();\n await assertAccess(\"extension\", id, \"editor\");\n const db = getDb();\n const updates: Record<string, unknown> = {\n updatedAt: new Date().toISOString(),\n };\n if (data.name !== undefined) updates.name = data.name;\n if (data.description !== undefined) updates.description = data.description;\n if (data.icon !== undefined) updates.icon = data.icon;\n if (data.visibility !== undefined) updates.visibility = data.visibility;\n await db.update(extensions).set(updates).where(eq(extensions.id, id));\n const rows = await db.select().from(extensions).where(eq(extensions.id, id));\n return (rows[0] as ExtensionRow) ?? null;\n}\n\nexport interface UpdateExtensionContentOpts {\n content?: string;\n patches?: Array<{ find: string; replace: string }>;\n}\n\nexport async function updateExtensionContent(\n id: string,\n opts: UpdateExtensionContentOpts,\n): Promise<ExtensionRow | null> {\n await ensureExtensionsTables();\n await assertAccess(\"extension\", id, \"editor\");\n const db = getDb();\n\n let newContent: string;\n if (opts.content !== undefined) {\n newContent = opts.content;\n } else if (opts.patches) {\n const rows = await db\n .select()\n .from(extensions)\n .where(eq(extensions.id, id));\n if (!rows[0]) return null;\n newContent = (rows[0] as ExtensionRow).content;\n for (const patch of opts.patches) {\n newContent = newContent.replace(patch.find, patch.replace);\n }\n } else {\n return null;\n }\n\n await db\n .update(extensions)\n .set({ content: newContent, updatedAt: new Date().toISOString() })\n .where(eq(extensions.id, id));\n const rows = await db.select().from(extensions).where(eq(extensions.id, id));\n return (rows[0] as ExtensionRow) ?? null;\n}\n\nexport async function deleteExtension(id: string): Promise<boolean> {\n await ensureExtensionsTables();\n await assertAccess(\"extension\", id, \"admin\");\n const db = getDb();\n const rows = await db.select().from(extensions).where(eq(extensions.id, id));\n if (!rows[0]) return false;\n await db.delete(extensionShares).where(eq(extensionShares.resourceId, id));\n await db.delete(extensionHides).where(eq(extensionHides.extensionId, id));\n await getDbExec().execute({\n sql: `DELETE FROM tool_data WHERE tool_id = ?`,\n args: [id],\n });\n const { cascadeDeleteExtensionSlots } = await import(\"./slots/store.js\");\n await cascadeDeleteExtensionSlots(id);\n await db.delete(extensions).where(eq(extensions.id, id));\n return true;\n}\n\nexport async function getHiddenExtensionIdsForCurrentUser(): Promise<\n Set<string>\n> {\n await ensureExtensionsTables();\n const userEmail = getRequestUserEmail();\n if (!userEmail) return new Set();\n\n const db = getDb();\n const rows = await db\n .select({ extensionId: extensionHides.extensionId })\n .from(extensionHides)\n .where(eq(extensionHides.ownerEmail, userEmail));\n return new Set(rows.map((row) => row.extensionId));\n}\n\nexport async function hideExtension(id: string): Promise<boolean> {\n await ensureExtensionsTables();\n await assertAccess(\"extension\", id, \"viewer\");\n const userEmail = getRequestUserEmail();\n if (!userEmail) throw new Error(\"no authenticated user\");\n\n const now = new Date().toISOString();\n await getDbExec().execute({\n sql: `INSERT INTO tool_hidden_extensions (id, tool_id, owner_email, created_at)\n VALUES (?, ?, ?, ?)\n ON CONFLICT (owner_email, tool_id) DO NOTHING`,\n args: [randomUUID(), id, userEmail, now],\n });\n return true;\n}\n\nexport async function unhideExtension(id: string): Promise<boolean> {\n await ensureExtensionsTables();\n const userEmail = getRequestUserEmail();\n if (!userEmail) throw new Error(\"no authenticated user\");\n\n await getDbExec().execute({\n sql: `DELETE FROM tool_hidden_extensions WHERE tool_id = ? AND owner_email = ?`,\n args: [id, userEmail],\n });\n return true;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/extensions/store.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { eq } from \"drizzle-orm\";\nimport { getDbExec, isPostgres, retryOnDdlRace } from \"../db/client.js\";\nimport { createGetDb } from \"../db/create-get-db.js\";\nimport {\n accessFilter,\n assertAccess,\n resolveAccess,\n ForbiddenError,\n} from \"../sharing/access.js\";\nimport {\n getRequestUserEmail,\n getRequestOrgId,\n} from \"../server/request-context.js\";\nimport { registerShareableResource } from \"../sharing/registry.js\";\nimport {\n extensions,\n extensionHides,\n extensionShares,\n EXTENSIONS_CREATE_SQL,\n EXTENSIONS_CREATE_SQL_PG,\n EXTENSION_SHARES_CREATE_SQL,\n EXTENSION_SHARES_CREATE_SQL_PG,\n EXTENSION_DATA_CREATE_SQL,\n EXTENSION_DATA_CREATE_SQL_PG,\n EXTENSION_DATA_ITEM_INDEX_SQL,\n EXTENSION_DATA_ITEM_INDEX_SQL_PG,\n EXTENSION_DATA_DROP_OLD_INDEX_SQL,\n EXTENSION_DATA_DROP_OLD_INDEX_SQL_PG,\n EXTENSIONS_OWNER_INDEX_SQL,\n EXTENSIONS_ORG_INDEX_SQL,\n EXTENSION_SHARES_RESOURCE_INDEX_SQL,\n EXTENSION_HIDES_CREATE_SQL,\n EXTENSION_HIDES_CREATE_SQL_PG,\n EXTENSION_HIDES_UNIQUE_INDEX_SQL,\n EXTENSION_HIDES_OWNER_INDEX_SQL,\n EXTENSION_CONSENTS_CREATE_SQL,\n EXTENSION_CONSENTS_CREATE_SQL_PG,\n EXTENSION_CONSENTS_VIEWER_INDEX_SQL,\n} from \"./schema.js\";\n\nconst getDb = createGetDb({ extensions, extensionShares, extensionHides });\n\nlet _initPromise: Promise<void> | undefined;\n\nexport async function ensureExtensionsTables(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const pg = isPostgres();\n await retryOnDdlRace(() =>\n client.execute(pg ? EXTENSIONS_CREATE_SQL_PG : EXTENSIONS_CREATE_SQL),\n );\n await migrateMisnamedExtensionsTable(client, pg);\n await retryOnDdlRace(() =>\n client.execute(\n pg ? EXTENSION_SHARES_CREATE_SQL_PG : EXTENSION_SHARES_CREATE_SQL,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n pg ? EXTENSION_DATA_CREATE_SQL_PG : EXTENSION_DATA_CREATE_SQL,\n ),\n );\n await ensureExtensionDataItemId(client, pg);\n await ensureExtensionDataScope(client, pg);\n await client.execute(\n pg\n ? EXTENSION_DATA_DROP_OLD_INDEX_SQL_PG\n : EXTENSION_DATA_DROP_OLD_INDEX_SQL,\n );\n await retryOnDdlRace(() =>\n client.execute(\n pg ? EXTENSION_DATA_ITEM_INDEX_SQL_PG : EXTENSION_DATA_ITEM_INDEX_SQL,\n ),\n );\n await retryOnDdlRace(() => client.execute(EXTENSIONS_OWNER_INDEX_SQL));\n await retryOnDdlRace(() => client.execute(EXTENSIONS_ORG_INDEX_SQL));\n await retryOnDdlRace(() =>\n client.execute(EXTENSION_SHARES_RESOURCE_INDEX_SQL),\n );\n await retryOnDdlRace(() =>\n client.execute(\n pg ? EXTENSION_HIDES_CREATE_SQL_PG : EXTENSION_HIDES_CREATE_SQL,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(EXTENSION_HIDES_UNIQUE_INDEX_SQL),\n );\n await retryOnDdlRace(() =>\n client.execute(EXTENSION_HIDES_OWNER_INDEX_SQL),\n );\n // tool_consents was introduced for an audit-C1 per-viewer consent\n // gate that we removed once we settled on intra-org trust as the\n // baseline. The table is kept (additive — never drop) so deploys\n // that already created it stay healthy; the runtime consent code\n // is gone. Idempotent CREATE IF NOT EXISTS for fresh schemas.\n await retryOnDdlRace(() =>\n client.execute(\n pg ? EXTENSION_CONSENTS_CREATE_SQL_PG : EXTENSION_CONSENTS_CREATE_SQL,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(EXTENSION_CONSENTS_VIEWER_INDEX_SQL),\n );\n })();\n }\n\n try {\n await _initPromise;\n } catch (err) {\n _initPromise = undefined;\n throw err;\n }\n}\n\nasync function migrateMisnamedExtensionsTable(\n client: ReturnType<typeof getDbExec>,\n pg: boolean,\n): Promise<void> {\n const sql = pg\n ? `INSERT INTO tools (id, name, description, content, icon, created_at, updated_at, owner_email, org_id, visibility)\n SELECT id, name, description, content, icon, created_at, updated_at, owner_email, org_id, visibility\n FROM extensions\n ON CONFLICT (id) DO NOTHING`\n : `INSERT OR IGNORE INTO tools (id, name, description, content, icon, created_at, updated_at, owner_email, org_id, visibility)\n SELECT id, name, description, content, icon, created_at, updated_at, owner_email, org_id, visibility\n FROM extensions`;\n\n try {\n await client.execute(sql);\n } catch (err: any) {\n const message = String(err?.message ?? err).toLowerCase();\n if (\n message.includes(\"no such table: extensions\") ||\n message.includes('relation \"extensions\" does not exist') ||\n message.includes(\"relation extensions does not exist\")\n ) {\n return;\n }\n throw err;\n }\n}\n\nasync function ensureExtensionDataItemId(\n client: ReturnType<typeof getDbExec>,\n pg: boolean,\n): Promise<void> {\n if (pg) {\n await client.execute(\n `ALTER TABLE tool_data ADD COLUMN IF NOT EXISTS item_id TEXT`,\n );\n return;\n }\n\n // Keep this additive: legacy rows with item_id=id are still read correctly\n // through COALESCE(item_id, id), so SQLite never needs a table rebuild here.\n try {\n await client.execute(`ALTER TABLE tool_data ADD COLUMN item_id TEXT`);\n } catch (err: any) {\n if (\n !String(err?.message ?? err)\n .toLowerCase()\n .includes(\"duplicate\")\n ) {\n throw err;\n }\n }\n}\n\nasync function ensureExtensionDataScope(\n client: ReturnType<typeof getDbExec>,\n pg: boolean,\n): Promise<void> {\n const addCol = (name: string, def: string) => {\n if (pg) {\n return client.execute(\n `ALTER TABLE tool_data ADD COLUMN IF NOT EXISTS ${name} ${def}`,\n );\n }\n return client\n .execute(`ALTER TABLE tool_data ADD COLUMN ${name} ${def}`)\n .catch((err: any) => {\n if (\n !String(err?.message ?? err)\n .toLowerCase()\n .includes(\"duplicate\")\n )\n throw err;\n });\n };\n await addCol(\"scope\", \"TEXT NOT NULL DEFAULT 'user'\");\n await addCol(\"org_id\", \"TEXT\");\n await addCol(\"scope_key\", \"TEXT NOT NULL DEFAULT 'local@localhost'\");\n // One-time backfill migration: replaces the dev-mode DEFAULT scope_key\n // with each row's real owner_email. Not a per-request fallback.\n await client.execute(\n // guard:allow-localhost-fallback — one-time backfill migration replacing dev-mode default scope_key with the row's real owner_email\n `UPDATE tool_data SET scope_key = owner_email WHERE scope_key = 'local@localhost' AND owner_email != 'local@localhost'`,\n );\n}\n\nexport function registerExtensionsShareable() {\n registerShareableResource({\n type: \"extension\",\n resourceTable: extensions,\n sharesTable: extensionShares,\n displayName: \"Extension\",\n titleColumn: \"name\",\n getDb: () => getDb(),\n // Extension HTML executes inside an iframe and calls actions / SQL / the\n // secrets-injecting proxy as the *viewer*. A public extension would let a\n // random authenticated user run code with the viewer's credentials — and\n // a malicious shared extension could re-share itself wider. Lock both:\n // no public visibility, and individual user shares must already be (or\n // be invited to) the org.\n allowPublic: false,\n requireOrgMemberForUserShares: true,\n });\n}\n\nexport interface ExtensionRow {\n id: string;\n name: string;\n description: string;\n content: string;\n icon: string | null;\n createdAt: string;\n updatedAt: string;\n ownerEmail: string;\n orgId: string | null;\n visibility: \"private\" | \"org\" | \"public\";\n}\n\nexport interface ListExtensionsOptions {\n includeHidden?: boolean;\n}\n\nexport async function listExtensions(\n options: ListExtensionsOptions = {},\n): Promise<ExtensionRow[]> {\n await ensureExtensionsTables();\n const db = getDb();\n const rows = (await db\n .select()\n .from(extensions)\n .where(accessFilter(extensions, extensionShares))) as ExtensionRow[];\n\n if (options.includeHidden) return rows;\n\n const hiddenIds = await getHiddenExtensionIdsForCurrentUser();\n if (hiddenIds.size === 0) return rows;\n return rows.filter((row) => !hiddenIds.has(row.id));\n}\n\nexport async function getExtension(id: string): Promise<ExtensionRow | null> {\n await ensureExtensionsTables();\n const access = await resolveAccess(\"extension\", id);\n return (access?.resource as ExtensionRow | undefined) ?? null;\n}\n\nexport interface CreateExtensionData {\n name: string;\n description?: string;\n content?: string;\n icon?: string;\n}\n\nexport async function createExtension(\n data: CreateExtensionData,\n): Promise<ExtensionRow> {\n await ensureExtensionsTables();\n const db = getDb();\n const userEmail = getRequestUserEmail();\n if (!userEmail) throw new Error(\"no authenticated user\");\n const orgId = getRequestOrgId();\n const id = randomUUID();\n const now = new Date().toISOString();\n const row: ExtensionRow = {\n id,\n name: data.name,\n description: data.description ?? \"\",\n content: data.content ?? \"\",\n icon: data.icon ?? null,\n createdAt: now,\n updatedAt: now,\n ownerEmail: userEmail,\n orgId: orgId ?? null,\n visibility: \"private\",\n };\n await db.insert(extensions).values(row);\n return row;\n}\n\nexport interface UpdateExtensionData {\n name?: string;\n description?: string;\n icon?: string;\n /**\n * Extensions cannot be public — `set-resource-visibility` and this store\n * helper both reject `\"public\"`. The type lists it so the framework's\n * generic share UI compiles, not because it's allowed at runtime.\n */\n visibility?: \"private\" | \"org\" | \"public\";\n}\n\nexport async function updateExtension(\n id: string,\n data: UpdateExtensionData,\n): Promise<ExtensionRow | null> {\n await ensureExtensionsTables();\n await assertAccess(\"extension\", id, \"editor\");\n if (data.visibility === \"public\") {\n // Defense in depth — `registerExtensionsShareable` sets\n // `allowPublic: false`, so `set-resource-visibility` already rejects\n // this. Block direct callers too (HTTP `PUT /extensions/:id`, internal\n // refactors) so the rule holds regardless of entry point.\n throw new ForbiddenError(\n \"Extensions cannot be made public — share with specific people or your organization instead.\",\n );\n }\n const db = getDb();\n const updates: Record<string, unknown> = {\n updatedAt: new Date().toISOString(),\n };\n if (data.name !== undefined) updates.name = data.name;\n if (data.description !== undefined) updates.description = data.description;\n if (data.icon !== undefined) updates.icon = data.icon;\n if (data.visibility !== undefined) updates.visibility = data.visibility;\n await db.update(extensions).set(updates).where(eq(extensions.id, id));\n const rows = await db.select().from(extensions).where(eq(extensions.id, id));\n return (rows[0] as ExtensionRow) ?? null;\n}\n\nexport interface UpdateExtensionContentOpts {\n content?: string;\n patches?: Array<{ find: string; replace: string }>;\n}\n\nexport async function updateExtensionContent(\n id: string,\n opts: UpdateExtensionContentOpts,\n): Promise<ExtensionRow | null> {\n await ensureExtensionsTables();\n await assertAccess(\"extension\", id, \"editor\");\n const db = getDb();\n\n let newContent: string;\n if (opts.content !== undefined) {\n newContent = opts.content;\n } else if (opts.patches) {\n const rows = await db\n .select()\n .from(extensions)\n .where(eq(extensions.id, id));\n if (!rows[0]) return null;\n newContent = (rows[0] as ExtensionRow).content;\n for (const patch of opts.patches) {\n newContent = newContent.replace(patch.find, patch.replace);\n }\n } else {\n return null;\n }\n\n await db\n .update(extensions)\n .set({ content: newContent, updatedAt: new Date().toISOString() })\n .where(eq(extensions.id, id));\n const rows = await db.select().from(extensions).where(eq(extensions.id, id));\n return (rows[0] as ExtensionRow) ?? null;\n}\n\nexport async function deleteExtension(id: string): Promise<boolean> {\n await ensureExtensionsTables();\n await assertAccess(\"extension\", id, \"admin\");\n const db = getDb();\n const rows = await db.select().from(extensions).where(eq(extensions.id, id));\n if (!rows[0]) return false;\n await db.delete(extensionShares).where(eq(extensionShares.resourceId, id));\n await db.delete(extensionHides).where(eq(extensionHides.extensionId, id));\n await getDbExec().execute({\n sql: `DELETE FROM tool_data WHERE tool_id = ?`,\n args: [id],\n });\n const { cascadeDeleteExtensionSlots } = await import(\"./slots/store.js\");\n await cascadeDeleteExtensionSlots(id);\n await db.delete(extensions).where(eq(extensions.id, id));\n return true;\n}\n\nexport async function getHiddenExtensionIdsForCurrentUser(): Promise<\n Set<string>\n> {\n await ensureExtensionsTables();\n const userEmail = getRequestUserEmail();\n if (!userEmail) return new Set();\n\n const db = getDb();\n const rows = await db\n .select({ extensionId: extensionHides.extensionId })\n .from(extensionHides)\n .where(eq(extensionHides.ownerEmail, userEmail));\n return new Set(rows.map((row) => row.extensionId));\n}\n\nexport async function hideExtension(id: string): Promise<boolean> {\n await ensureExtensionsTables();\n await assertAccess(\"extension\", id, \"viewer\");\n const userEmail = getRequestUserEmail();\n if (!userEmail) throw new Error(\"no authenticated user\");\n\n const now = new Date().toISOString();\n await getDbExec().execute({\n sql: `INSERT INTO tool_hidden_extensions (id, tool_id, owner_email, created_at)\n VALUES (?, ?, ?, ?)\n ON CONFLICT (owner_email, tool_id) DO NOTHING`,\n args: [randomUUID(), id, userEmail, now],\n });\n return true;\n}\n\nexport async function unhideExtension(id: string): Promise<boolean> {\n await ensureExtensionsTables();\n const userEmail = getRequestUserEmail();\n if (!userEmail) throw new Error(\"no authenticated user\");\n\n await getDbExec().execute({\n sql: `DELETE FROM tool_hidden_extensions WHERE tool_id = ? AND owner_email = ?`,\n args: [id, userEmail],\n });\n return true;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-image.d.ts","sourceRoot":"","sources":["../../../src/file-upload/actions/upload-image.ts"],"names":[],"mappings":";AA6FA,wBAwEG"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { defineAction } from "../../action.js";
|
|
3
|
+
import { getRequestUserEmail } from "../../server/request-context.js";
|
|
4
|
+
import { uploadFile } from "../registry.js";
|
|
5
|
+
const MAX_REMOTE_FETCH_BYTES = 25 * 1024 * 1024;
|
|
6
|
+
const SUPPORTED_IMAGE_MIME_TYPES = new Set([
|
|
7
|
+
"image/png",
|
|
8
|
+
"image/jpeg",
|
|
9
|
+
"image/jpg",
|
|
10
|
+
"image/gif",
|
|
11
|
+
"image/webp",
|
|
12
|
+
"image/avif",
|
|
13
|
+
"image/svg+xml",
|
|
14
|
+
"image/heic",
|
|
15
|
+
"image/heif",
|
|
16
|
+
]);
|
|
17
|
+
function extensionFromMime(mimeType) {
|
|
18
|
+
const bare = mimeType.split(";")[0].trim().toLowerCase();
|
|
19
|
+
if (bare === "image/jpeg" || bare === "image/jpg")
|
|
20
|
+
return ".jpg";
|
|
21
|
+
if (bare === "image/png")
|
|
22
|
+
return ".png";
|
|
23
|
+
if (bare === "image/gif")
|
|
24
|
+
return ".gif";
|
|
25
|
+
if (bare === "image/webp")
|
|
26
|
+
return ".webp";
|
|
27
|
+
if (bare === "image/avif")
|
|
28
|
+
return ".avif";
|
|
29
|
+
if (bare === "image/svg+xml")
|
|
30
|
+
return ".svg";
|
|
31
|
+
if (bare === "image/heic")
|
|
32
|
+
return ".heic";
|
|
33
|
+
if (bare === "image/heif")
|
|
34
|
+
return ".heif";
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
function defaultFilename(mimeType) {
|
|
38
|
+
return `image-${Date.now()}${extensionFromMime(mimeType) || ".bin"}`;
|
|
39
|
+
}
|
|
40
|
+
function parseDataUrl(dataUrl) {
|
|
41
|
+
const match = dataUrl.match(/^data:([^;,]+)(;base64)?,(.+)$/);
|
|
42
|
+
if (!match) {
|
|
43
|
+
throw new Error("data must be a data URL (data:image/...;base64,...)");
|
|
44
|
+
}
|
|
45
|
+
const mimeType = match[1].trim().toLowerCase();
|
|
46
|
+
const isBase64 = !!match[2];
|
|
47
|
+
const payload = match[3];
|
|
48
|
+
const bytes = isBase64
|
|
49
|
+
? new Uint8Array(Buffer.from(payload, "base64"))
|
|
50
|
+
: new TextEncoder().encode(decodeURIComponent(payload));
|
|
51
|
+
return { bytes, mimeType };
|
|
52
|
+
}
|
|
53
|
+
async function fetchRemote(url) {
|
|
54
|
+
let parsed;
|
|
55
|
+
try {
|
|
56
|
+
parsed = new URL(url);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
throw new Error(`url is not a valid URL: ${url}`);
|
|
60
|
+
}
|
|
61
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
62
|
+
throw new Error("url must use http(s)");
|
|
63
|
+
}
|
|
64
|
+
const response = await fetch(url);
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
throw new Error(`Failed to fetch image (${response.status} ${response.statusText})`);
|
|
67
|
+
}
|
|
68
|
+
const contentType = response.headers.get("content-type") || "";
|
|
69
|
+
const mimeType = contentType.split(";")[0].trim().toLowerCase() ||
|
|
70
|
+
"application/octet-stream";
|
|
71
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
72
|
+
if (buffer.byteLength > MAX_REMOTE_FETCH_BYTES) {
|
|
73
|
+
throw new Error(`Image too large (${buffer.byteLength} bytes, max ${MAX_REMOTE_FETCH_BYTES})`);
|
|
74
|
+
}
|
|
75
|
+
return { bytes: new Uint8Array(buffer), mimeType };
|
|
76
|
+
}
|
|
77
|
+
function uploadNotConfiguredError() {
|
|
78
|
+
return [
|
|
79
|
+
"Image uploads are not configured for this app.",
|
|
80
|
+
"Configure a file upload provider — connect Builder.io in Settings → File uploads (free credits), set BUILDER_PRIVATE_KEY, or register a custom provider (S3, R2, GCS, etc.) via registerFileUploadProvider().",
|
|
81
|
+
].join(" ");
|
|
82
|
+
}
|
|
83
|
+
export default defineAction({
|
|
84
|
+
description: "Upload an image to the configured file-upload provider (Builder.io by default) and return a hosted CDN URL. " +
|
|
85
|
+
"Use this to turn a base64 data URL, a chat-attached image, or a transient remote URL into a stable URL that " +
|
|
86
|
+
'can be embedded in <img src="...">, slide HTML, documents, or shared with other apps. Falls back to a clear ' +
|
|
87
|
+
"'connect Builder.io' message when no provider is configured.",
|
|
88
|
+
schema: z
|
|
89
|
+
.object({
|
|
90
|
+
data: z
|
|
91
|
+
.string()
|
|
92
|
+
.optional()
|
|
93
|
+
.describe("Base64 data URL (data:image/png;base64,...). Pass when the image bytes are already in the chat context — for example an attached or generated image. Either `data` or `url` is required."),
|
|
94
|
+
url: z
|
|
95
|
+
.string()
|
|
96
|
+
.optional()
|
|
97
|
+
.describe("Remote image URL to re-host. Useful for preserving transient generated images, third-party search results, or any external URL whose long-term availability you don't control. Either `data` or `url` is required."),
|
|
98
|
+
filename: z
|
|
99
|
+
.string()
|
|
100
|
+
.optional()
|
|
101
|
+
.describe("Optional filename hint, used by the provider for display and to derive an extension when missing."),
|
|
102
|
+
})
|
|
103
|
+
.refine((args) => !!args.data || !!args.url, {
|
|
104
|
+
message: "Either `data` or `url` is required.",
|
|
105
|
+
}),
|
|
106
|
+
run: async (args) => {
|
|
107
|
+
let bytes;
|
|
108
|
+
let mimeType;
|
|
109
|
+
if (args.data) {
|
|
110
|
+
({ bytes, mimeType } = parseDataUrl(args.data));
|
|
111
|
+
}
|
|
112
|
+
else if (args.url) {
|
|
113
|
+
({ bytes, mimeType } = await fetchRemote(args.url));
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
return { error: "Either `data` or `url` is required." };
|
|
117
|
+
}
|
|
118
|
+
if (!SUPPORTED_IMAGE_MIME_TYPES.has(mimeType)) {
|
|
119
|
+
return {
|
|
120
|
+
error: `Unsupported image type: ${mimeType}. Supported: ${[...SUPPORTED_IMAGE_MIME_TYPES].join(", ")}.`,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const filename = (args.filename || defaultFilename(mimeType)).trim();
|
|
124
|
+
const ownerEmail = getRequestUserEmail() ?? undefined;
|
|
125
|
+
const result = await uploadFile({
|
|
126
|
+
data: bytes,
|
|
127
|
+
filename,
|
|
128
|
+
mimeType,
|
|
129
|
+
ownerEmail,
|
|
130
|
+
});
|
|
131
|
+
if (!result) {
|
|
132
|
+
return {
|
|
133
|
+
error: uploadNotConfiguredError(),
|
|
134
|
+
configured: false,
|
|
135
|
+
connectPath: "/_agent-native/builder/connect",
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
url: result.url,
|
|
140
|
+
id: result.id,
|
|
141
|
+
provider: result.provider,
|
|
142
|
+
};
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
//# sourceMappingURL=upload-image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-image.js","sourceRoot":"","sources":["../../../src/file-upload/actions/upload-image.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport { defineAction } from \"../../action.js\";\nimport { getRequestUserEmail } from \"../../server/request-context.js\";\nimport { uploadFile } from \"../registry.js\";\n\nconst MAX_REMOTE_FETCH_BYTES = 25 * 1024 * 1024;\n\nconst SUPPORTED_IMAGE_MIME_TYPES = new Set([\n \"image/png\",\n \"image/jpeg\",\n \"image/jpg\",\n \"image/gif\",\n \"image/webp\",\n \"image/avif\",\n \"image/svg+xml\",\n \"image/heic\",\n \"image/heif\",\n]);\n\nfunction extensionFromMime(mimeType: string): string {\n const bare = mimeType.split(\";\")[0].trim().toLowerCase();\n if (bare === \"image/jpeg\" || bare === \"image/jpg\") return \".jpg\";\n if (bare === \"image/png\") return \".png\";\n if (bare === \"image/gif\") return \".gif\";\n if (bare === \"image/webp\") return \".webp\";\n if (bare === \"image/avif\") return \".avif\";\n if (bare === \"image/svg+xml\") return \".svg\";\n if (bare === \"image/heic\") return \".heic\";\n if (bare === \"image/heif\") return \".heif\";\n return \"\";\n}\n\nfunction defaultFilename(mimeType: string): string {\n return `image-${Date.now()}${extensionFromMime(mimeType) || \".bin\"}`;\n}\n\nfunction parseDataUrl(dataUrl: string): {\n bytes: Uint8Array;\n mimeType: string;\n} {\n const match = dataUrl.match(/^data:([^;,]+)(;base64)?,(.+)$/);\n if (!match) {\n throw new Error(\"data must be a data URL (data:image/...;base64,...)\");\n }\n const mimeType = match[1].trim().toLowerCase();\n const isBase64 = !!match[2];\n const payload = match[3];\n const bytes = isBase64\n ? new Uint8Array(Buffer.from(payload, \"base64\"))\n : new TextEncoder().encode(decodeURIComponent(payload));\n return { bytes, mimeType };\n}\n\nasync function fetchRemote(url: string): Promise<{\n bytes: Uint8Array;\n mimeType: string;\n}> {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw new Error(`url is not a valid URL: ${url}`);\n }\n if (parsed.protocol !== \"https:\" && parsed.protocol !== \"http:\") {\n throw new Error(\"url must use http(s)\");\n }\n\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(\n `Failed to fetch image (${response.status} ${response.statusText})`,\n );\n }\n const contentType = response.headers.get(\"content-type\") || \"\";\n const mimeType =\n contentType.split(\";\")[0].trim().toLowerCase() ||\n \"application/octet-stream\";\n const buffer = Buffer.from(await response.arrayBuffer());\n if (buffer.byteLength > MAX_REMOTE_FETCH_BYTES) {\n throw new Error(\n `Image too large (${buffer.byteLength} bytes, max ${MAX_REMOTE_FETCH_BYTES})`,\n );\n }\n return { bytes: new Uint8Array(buffer), mimeType };\n}\n\nfunction uploadNotConfiguredError(): string {\n return [\n \"Image uploads are not configured for this app.\",\n \"Configure a file upload provider — connect Builder.io in Settings → File uploads (free credits), set BUILDER_PRIVATE_KEY, or register a custom provider (S3, R2, GCS, etc.) via registerFileUploadProvider().\",\n ].join(\" \");\n}\n\nexport default defineAction({\n description:\n \"Upload an image to the configured file-upload provider (Builder.io by default) and return a hosted CDN URL. \" +\n \"Use this to turn a base64 data URL, a chat-attached image, or a transient remote URL into a stable URL that \" +\n 'can be embedded in <img src=\"...\">, slide HTML, documents, or shared with other apps. Falls back to a clear ' +\n \"'connect Builder.io' message when no provider is configured.\",\n schema: z\n .object({\n data: z\n .string()\n .optional()\n .describe(\n \"Base64 data URL (data:image/png;base64,...). Pass when the image bytes are already in the chat context — for example an attached or generated image. Either `data` or `url` is required.\",\n ),\n url: z\n .string()\n .optional()\n .describe(\n \"Remote image URL to re-host. Useful for preserving transient generated images, third-party search results, or any external URL whose long-term availability you don't control. Either `data` or `url` is required.\",\n ),\n filename: z\n .string()\n .optional()\n .describe(\n \"Optional filename hint, used by the provider for display and to derive an extension when missing.\",\n ),\n })\n .refine((args) => !!args.data || !!args.url, {\n message: \"Either `data` or `url` is required.\",\n }),\n run: async (args) => {\n let bytes: Uint8Array;\n let mimeType: string;\n\n if (args.data) {\n ({ bytes, mimeType } = parseDataUrl(args.data));\n } else if (args.url) {\n ({ bytes, mimeType } = await fetchRemote(args.url));\n } else {\n return { error: \"Either `data` or `url` is required.\" };\n }\n\n if (!SUPPORTED_IMAGE_MIME_TYPES.has(mimeType)) {\n return {\n error: `Unsupported image type: ${mimeType}. Supported: ${[...SUPPORTED_IMAGE_MIME_TYPES].join(\", \")}.`,\n };\n }\n\n const filename = (args.filename || defaultFilename(mimeType)).trim();\n const ownerEmail = getRequestUserEmail() ?? undefined;\n\n const result = await uploadFile({\n data: bytes,\n filename,\n mimeType,\n ownerEmail,\n });\n\n if (!result) {\n return {\n error: uploadNotConfiguredError(),\n configured: false,\n connectPath: \"/_agent-native/builder/connect\",\n };\n }\n\n return {\n url: result.url,\n id: result.id,\n provider: result.provider,\n };\n },\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/file-upload/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAYrD;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,EAAE,
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/file-upload/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAYrD;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,EAAE,kBAkFvC,CAAC"}
|
|
@@ -39,17 +39,37 @@ export const builderFileUploadProvider = {
|
|
|
39
39
|
const body = typeof Blob !== "undefined"
|
|
40
40
|
? new Blob([bytes], { type: bareMimeType })
|
|
41
41
|
: bytes;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
42
|
+
// Retry transient 5xx once with backoff. Builder.io's upload service
|
|
43
|
+
// occasionally returns a bodyless 500 ("Internal Error") on the first
|
|
44
|
+
// attempt — usually GCS write hiccups that succeed on retry. We bound
|
|
45
|
+
// it tight so a deterministic 500 surfaces quickly to the caller.
|
|
46
|
+
const RETRY_DELAYS_MS = [600, 1800];
|
|
47
|
+
let response = null;
|
|
48
|
+
let lastErrorBody = "";
|
|
49
|
+
for (let attempt = 0; attempt <= RETRY_DELAYS_MS.length; attempt++) {
|
|
50
|
+
response = await fetch(url, {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: {
|
|
53
|
+
Authorization: `Bearer ${privateKey}`,
|
|
54
|
+
"Content-Type": bareMimeType,
|
|
55
|
+
},
|
|
56
|
+
body,
|
|
57
|
+
});
|
|
58
|
+
if (response.ok)
|
|
59
|
+
break;
|
|
60
|
+
const isTransient = response.status >= 500 && response.status !== 501;
|
|
61
|
+
const isLastAttempt = attempt === RETRY_DELAYS_MS.length;
|
|
62
|
+
if (!isTransient || isLastAttempt) {
|
|
63
|
+
lastErrorBody = await response.text().catch(() => "");
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
lastErrorBody = await response.text().catch(() => "");
|
|
67
|
+
await new Promise((r) => setTimeout(r, RETRY_DELAYS_MS[attempt]));
|
|
68
|
+
}
|
|
69
|
+
if (!response || !response.ok) {
|
|
70
|
+
const status = response?.status ?? 0;
|
|
71
|
+
const statusText = response?.statusText ?? "no response";
|
|
72
|
+
throw new Error(`Builder.io upload failed (${status}): ${lastErrorBody || statusText}`);
|
|
53
73
|
}
|
|
54
74
|
const json = (await response.json().catch(() => ({})));
|
|
55
75
|
if (!json.url) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/file-upload/builder.ts"],"names":[],"mappings":"AAEA,MAAM,wBAAwB,GAAG,oBAAoB,CAAC;AAEtD,SAAS,iBAAiB;IACxB,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,gBAAgB;QAC5B,OAAO,CAAC,GAAG,CAAC,uBAAuB;QACnC,wBAAwB,CACzB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAuB;IAC3D,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,YAAY;IAClB,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB;IACrD,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC7C,MAAM,EAAE,wBAAwB,EAAE,GAChC,MAAM,MAAM,CAAC,kCAAkC,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,MAAM,wBAAwB,EAAE,CAAC;QACpD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAC3D,IAAI,QAAQ;YAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAErD,iEAAiE;QACjE,qEAAqE;QACrE,qEAAqE;QACrE,sEAAsE;QACtE,iEAAiE;QACjE,oBAAoB;QACpB,MAAM,YAAY,GAAG,CAAC,QAAQ,IAAI,0BAA0B,CAAC;aAC1D,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aACb,IAAI,EAAE,CAAC;QAEV,MAAM,MAAM,GACV,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAW,CAAC,CAAC;QAClE,MAAM,KAAK,GAAG,IAAI,UAAU,CAC1B,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,UAAU,CAClB,CAAC;QACF,MAAM,IAAI,GACR,OAAO,IAAI,KAAK,WAAW;YACzB,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;YAC3C,CAAC,CAAE,KAA6B,CAAC;QAErC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/file-upload/builder.ts"],"names":[],"mappings":"AAEA,MAAM,wBAAwB,GAAG,oBAAoB,CAAC;AAEtD,SAAS,iBAAiB;IACxB,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,gBAAgB;QAC5B,OAAO,CAAC,GAAG,CAAC,uBAAuB;QACnC,wBAAwB,CACzB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAuB;IAC3D,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,YAAY;IAClB,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB;IACrD,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC7C,MAAM,EAAE,wBAAwB,EAAE,GAChC,MAAM,MAAM,CAAC,kCAAkC,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,MAAM,wBAAwB,EAAE,CAAC;QACpD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAC3D,IAAI,QAAQ;YAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAErD,iEAAiE;QACjE,qEAAqE;QACrE,qEAAqE;QACrE,sEAAsE;QACtE,iEAAiE;QACjE,oBAAoB;QACpB,MAAM,YAAY,GAAG,CAAC,QAAQ,IAAI,0BAA0B,CAAC;aAC1D,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aACb,IAAI,EAAE,CAAC;QAEV,MAAM,MAAM,GACV,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAW,CAAC,CAAC;QAClE,MAAM,KAAK,GAAG,IAAI,UAAU,CAC1B,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,UAAU,CAClB,CAAC;QACF,MAAM,IAAI,GACR,OAAO,IAAI,KAAK,WAAW;YACzB,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;YAC3C,CAAC,CAAE,KAA6B,CAAC;QAErC,qEAAqE;QACrE,sEAAsE;QACtE,sEAAsE;QACtE,kEAAkE;QAClE,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,QAAQ,GAAoB,IAAI,CAAC;QACrC,IAAI,aAAa,GAAG,EAAE,CAAC;QACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC;YACnE,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAC1B,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,UAAU,EAAE;oBACrC,cAAc,EAAE,YAAY;iBAC7B;gBACD,IAAI;aACL,CAAC,CAAC;YACH,IAAI,QAAQ,CAAC,EAAE;gBAAE,MAAM;YACvB,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC;YACtE,MAAM,aAAa,GAAG,OAAO,KAAK,eAAe,CAAC,MAAM,CAAC;YACzD,IAAI,CAAC,WAAW,IAAI,aAAa,EAAE,CAAC;gBAClC,aAAa,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBACtD,MAAM;YACR,CAAC;YACD,aAAa,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YACtD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;YACrC,MAAM,UAAU,GAAG,QAAQ,EAAE,UAAU,IAAI,aAAa,CAAC;YACzD,MAAM,IAAI,KAAK,CACb,6BAA6B,MAAM,MAAM,aAAa,IAAI,UAAU,EAAE,CACvE,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAGpD,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QAED,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IAC7D,CAAC;CACF,CAAC","sourcesContent":["import type { FileUploadProvider } from \"./types.js\";\n\nconst DEFAULT_BUILDER_APP_HOST = \"https://builder.io\";\n\nfunction builderUploadHost(): string {\n return (\n process.env.BUILDER_APP_HOST ||\n process.env.BUILDER_PUBLIC_APP_HOST ||\n DEFAULT_BUILDER_APP_HOST\n );\n}\n\n/**\n * Built-in Builder.io file upload provider.\n * Uses the same BUILDER_PRIVATE_KEY as the browser/background-agent flows,\n * so connecting Builder once (via the sidebar \"Connect Builder\" action)\n * automatically enables file uploads.\n *\n * Upload API: https://www.builder.io/c/docs/upload-api\n */\nexport const builderFileUploadProvider: FileUploadProvider = {\n id: \"builder\",\n name: \"Builder.io\",\n isConfigured: () => !!process.env.BUILDER_PRIVATE_KEY,\n upload: async ({ data, filename, mimeType }) => {\n const { resolveBuilderPrivateKey } =\n await import(\"../server/credential-provider.js\");\n const privateKey = await resolveBuilderPrivateKey();\n if (!privateKey) {\n throw new Error(\"BUILDER_PRIVATE_KEY is not set\");\n }\n\n const url = new URL(\"/api/v1/upload\", builderUploadHost());\n if (filename) url.searchParams.set(\"name\", filename);\n\n // Strip any media-type parameters (e.g. `;codecs=avc1,opus` from\n // MediaRecorder blobs) — Builder's upload API parses the body as raw\n // binary only when Content-Type is a bare MIME type. A parameterized\n // Content-Type falls through to the multipart/base64 paths which look\n // for an `image` field, and returns \"No image specified\" when it\n // doesn't find one.\n const bareMimeType = (mimeType || \"application/octet-stream\")\n .split(\";\")[0]\n .trim();\n\n const buffer =\n data instanceof Uint8Array ? data : new Uint8Array(data as any);\n const bytes = new Uint8Array(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength,\n );\n const body =\n typeof Blob !== \"undefined\"\n ? new Blob([bytes], { type: bareMimeType })\n : (bytes as unknown as BodyInit);\n\n // Retry transient 5xx once with backoff. Builder.io's upload service\n // occasionally returns a bodyless 500 (\"Internal Error\") on the first\n // attempt — usually GCS write hiccups that succeed on retry. We bound\n // it tight so a deterministic 500 surfaces quickly to the caller.\n const RETRY_DELAYS_MS = [600, 1800];\n let response: Response | null = null;\n let lastErrorBody = \"\";\n for (let attempt = 0; attempt <= RETRY_DELAYS_MS.length; attempt++) {\n response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${privateKey}`,\n \"Content-Type\": bareMimeType,\n },\n body,\n });\n if (response.ok) break;\n const isTransient = response.status >= 500 && response.status !== 501;\n const isLastAttempt = attempt === RETRY_DELAYS_MS.length;\n if (!isTransient || isLastAttempt) {\n lastErrorBody = await response.text().catch(() => \"\");\n break;\n }\n lastErrorBody = await response.text().catch(() => \"\");\n await new Promise((r) => setTimeout(r, RETRY_DELAYS_MS[attempt]));\n }\n\n if (!response || !response.ok) {\n const status = response?.status ?? 0;\n const statusText = response?.statusText ?? \"no response\";\n throw new Error(\n `Builder.io upload failed (${status}): ${lastErrorBody || statusText}`,\n );\n }\n\n const json = (await response.json().catch(() => ({}))) as {\n url?: string;\n id?: string;\n };\n if (!json.url) {\n throw new Error(\"Builder.io upload returned no URL\");\n }\n\n return { url: json.url, id: json.id, provider: \"builder\" };\n },\n};\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type { FileUploadInput, FileUploadProvider, FileUploadResult, } from "./types.js";
|
|
2
2
|
export { registerFileUploadProvider, unregisterFileUploadProvider, listFileUploadProviders, getActiveFileUploadProvider, uploadFile, } from "./registry.js";
|
|
3
3
|
export { builderFileUploadProvider } from "./builder.js";
|
|
4
|
+
export { preUploadImageAttachments, type PreUploadAttachmentsResult, type PreUploadedImageAttachment, } from "./pre-upload-attachments.js";
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/file-upload/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,0BAA0B,EAC1B,4BAA4B,EAC5B,uBAAuB,EACvB,2BAA2B,EAC3B,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/file-upload/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,0BAA0B,EAC1B,4BAA4B,EAC5B,uBAAuB,EACvB,2BAA2B,EAC3B,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EACL,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,GAChC,MAAM,6BAA6B,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { registerFileUploadProvider, unregisterFileUploadProvider, listFileUploadProviders, getActiveFileUploadProvider, uploadFile, } from "./registry.js";
|
|
2
2
|
export { builderFileUploadProvider } from "./builder.js";
|
|
3
|
+
export { preUploadImageAttachments, } from "./pre-upload-attachments.js";
|
|
3
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/file-upload/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,0BAA0B,EAC1B,4BAA4B,EAC5B,uBAAuB,EACvB,2BAA2B,EAC3B,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC","sourcesContent":["export type {\n FileUploadInput,\n FileUploadProvider,\n FileUploadResult,\n} from \"./types.js\";\nexport {\n registerFileUploadProvider,\n unregisterFileUploadProvider,\n listFileUploadProviders,\n getActiveFileUploadProvider,\n uploadFile,\n} from \"./registry.js\";\nexport { builderFileUploadProvider } from \"./builder.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/file-upload/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,0BAA0B,EAC1B,4BAA4B,EAC5B,uBAAuB,EACvB,2BAA2B,EAC3B,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EACL,yBAAyB,GAG1B,MAAM,6BAA6B,CAAC","sourcesContent":["export type {\n FileUploadInput,\n FileUploadProvider,\n FileUploadResult,\n} from \"./types.js\";\nexport {\n registerFileUploadProvider,\n unregisterFileUploadProvider,\n listFileUploadProviders,\n getActiveFileUploadProvider,\n uploadFile,\n} from \"./registry.js\";\nexport { builderFileUploadProvider } from \"./builder.js\";\nexport {\n preUploadImageAttachments,\n type PreUploadAttachmentsResult,\n type PreUploadedImageAttachment,\n} from \"./pre-upload-attachments.js\";\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { AgentChatAttachment } from "../agent/types.js";
|
|
2
|
+
export interface PreUploadedImageAttachment {
|
|
3
|
+
name?: string;
|
|
4
|
+
url: string;
|
|
5
|
+
provider: string;
|
|
6
|
+
contentType?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface PreUploadAttachmentsResult {
|
|
9
|
+
/** Same array reference. Each image attachment that was uploaded also gets a
|
|
10
|
+
* `url` property attached (non-breaking; consumers that don't read it are
|
|
11
|
+
* unaffected). */
|
|
12
|
+
attachments: AgentChatAttachment[];
|
|
13
|
+
/** Set when at least one image was uploaded. List of hosted URLs the agent
|
|
14
|
+
* can embed in HTML, slide content, documents, etc. */
|
|
15
|
+
uploaded: PreUploadedImageAttachment[];
|
|
16
|
+
/** True if at least one image attachment failed to upload because no
|
|
17
|
+
* file-upload provider is configured. Templates use this to render a
|
|
18
|
+
* "Connect Builder.io" suggestion. */
|
|
19
|
+
providerMissing: boolean;
|
|
20
|
+
/** A pre-formatted block to inject into the user message text so the agent
|
|
21
|
+
* has each hosted URL inline. Null when nothing was uploaded or no provider
|
|
22
|
+
* is configured. */
|
|
23
|
+
injectedText: string | null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Pre-upload chat image attachments through the active file-upload provider
|
|
27
|
+
* (Builder.io by default) so the agent can embed hosted URLs in HTML, slide
|
|
28
|
+
* content, and outbound messages. Keeps the original base64 data URL on the
|
|
29
|
+
* attachment so multimodal vision still works — only adds a hosted `url`.
|
|
30
|
+
*
|
|
31
|
+
* Safe to call when no provider is configured: it returns the attachments
|
|
32
|
+
* untouched with `providerMissing: true` so callers can surface a connect-
|
|
33
|
+
* Builder.io hint to the agent.
|
|
34
|
+
*/
|
|
35
|
+
export declare function preUploadImageAttachments(opts: {
|
|
36
|
+
attachments: AgentChatAttachment[] | undefined;
|
|
37
|
+
ownerEmail: string | null | undefined;
|
|
38
|
+
}): Promise<PreUploadAttachmentsResult>;
|
|
39
|
+
//# sourceMappingURL=pre-upload-attachments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pre-upload-attachments.d.ts","sourceRoot":"","sources":["../../src/file-upload/pre-upload-attachments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG7D,MAAM,WAAW,0BAA0B;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,0BAA0B;IACzC;;uBAEmB;IACnB,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC;4DACwD;IACxD,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC;;2CAEuC;IACvC,eAAe,EAAE,OAAO,CAAC;IACzB;;yBAEqB;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAYD;;;;;;;;;GASG;AACH,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,WAAW,EAAE,mBAAmB,EAAE,GAAG,SAAS,CAAC;IAC/C,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACvC,GAAG,OAAO,CAAC,0BAA0B,CAAC,CA6FtC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { uploadFile } from "./registry.js";
|
|
2
|
+
const DATA_URL_RE = /^data:(image\/[^;]+);base64,(.+)$/;
|
|
3
|
+
function escapeXmlAttr(value) {
|
|
4
|
+
return value
|
|
5
|
+
.replace(/&/g, "&")
|
|
6
|
+
.replace(/</g, "<")
|
|
7
|
+
.replace(/>/g, ">")
|
|
8
|
+
.replace(/"/g, """);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Pre-upload chat image attachments through the active file-upload provider
|
|
12
|
+
* (Builder.io by default) so the agent can embed hosted URLs in HTML, slide
|
|
13
|
+
* content, and outbound messages. Keeps the original base64 data URL on the
|
|
14
|
+
* attachment so multimodal vision still works — only adds a hosted `url`.
|
|
15
|
+
*
|
|
16
|
+
* Safe to call when no provider is configured: it returns the attachments
|
|
17
|
+
* untouched with `providerMissing: true` so callers can surface a connect-
|
|
18
|
+
* Builder.io hint to the agent.
|
|
19
|
+
*/
|
|
20
|
+
export async function preUploadImageAttachments(opts) {
|
|
21
|
+
const list = Array.isArray(opts.attachments) ? opts.attachments : [];
|
|
22
|
+
const uploaded = [];
|
|
23
|
+
let providerMissing = false;
|
|
24
|
+
if (list.length === 0) {
|
|
25
|
+
return {
|
|
26
|
+
attachments: list,
|
|
27
|
+
uploaded,
|
|
28
|
+
providerMissing: false,
|
|
29
|
+
injectedText: null,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
for (const att of list) {
|
|
33
|
+
if (att.type !== "image" || typeof att.data !== "string")
|
|
34
|
+
continue;
|
|
35
|
+
if (att.url) {
|
|
36
|
+
// Already pre-uploaded earlier in the pipeline — reuse it.
|
|
37
|
+
uploaded.push({
|
|
38
|
+
name: att.name,
|
|
39
|
+
url: att.url,
|
|
40
|
+
provider: att.uploadProvider || "unknown",
|
|
41
|
+
contentType: att.contentType,
|
|
42
|
+
});
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const match = att.data.match(DATA_URL_RE);
|
|
46
|
+
if (!match)
|
|
47
|
+
continue;
|
|
48
|
+
const mimeType = match[1];
|
|
49
|
+
let bytes;
|
|
50
|
+
try {
|
|
51
|
+
bytes = new Uint8Array(Buffer.from(match[2], "base64"));
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const result = await uploadFile({
|
|
58
|
+
data: bytes,
|
|
59
|
+
filename: att.name,
|
|
60
|
+
mimeType,
|
|
61
|
+
ownerEmail: opts.ownerEmail || undefined,
|
|
62
|
+
});
|
|
63
|
+
if (!result) {
|
|
64
|
+
providerMissing = true;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
att.url = result.url;
|
|
68
|
+
att.uploadProvider = result.provider;
|
|
69
|
+
uploaded.push({
|
|
70
|
+
name: att.name,
|
|
71
|
+
url: result.url,
|
|
72
|
+
provider: result.provider,
|
|
73
|
+
contentType: att.contentType,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
// Real upload failure (network, API). Keep the base64 so the model
|
|
78
|
+
// can still see the image, but don't crash the turn.
|
|
79
|
+
console.warn("[agent-native] pre-upload of chat image attachment failed:", err instanceof Error ? err.message : String(err));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
let injectedText = null;
|
|
83
|
+
if (uploaded.length > 0) {
|
|
84
|
+
const lines = uploaded.map((u) => {
|
|
85
|
+
const attrs = [
|
|
86
|
+
u.name ? `name="${escapeXmlAttr(u.name)}"` : null,
|
|
87
|
+
`url="${escapeXmlAttr(u.url)}"`,
|
|
88
|
+
u.contentType ? `contentType="${escapeXmlAttr(u.contentType)}"` : null,
|
|
89
|
+
`provider="${escapeXmlAttr(u.provider)}"`,
|
|
90
|
+
].filter(Boolean);
|
|
91
|
+
return `<chat-image-attachment ${attrs.join(" ")} />`;
|
|
92
|
+
});
|
|
93
|
+
injectedText = [
|
|
94
|
+
'<chat-image-attachments note="The user attached these images. They have been uploaded — use the url attribute when embedding in HTML, slide content, or any outbound message.">',
|
|
95
|
+
...lines,
|
|
96
|
+
"</chat-image-attachments>",
|
|
97
|
+
].join("\n");
|
|
98
|
+
}
|
|
99
|
+
else if (providerMissing) {
|
|
100
|
+
injectedText = [
|
|
101
|
+
"<chat-image-attachment-upload-error>",
|
|
102
|
+
"The user attached one or more images, but no file-upload provider is configured for this app.",
|
|
103
|
+
"Tell the user they need to configure one of: (a) Builder.io — recommended, free credits, one-click connect from Settings → File uploads, (b) BUILDER_PRIVATE_KEY environment variable, (c) a custom provider like S3 / R2 / GCS registered via registerFileUploadProvider(). Use `connect-builder` to render an inline connect card for option (a) when available.",
|
|
104
|
+
"Until that's done, you can still SEE the image, but you do NOT have a URL to embed it in HTML or share with other apps.",
|
|
105
|
+
"</chat-image-attachment-upload-error>",
|
|
106
|
+
].join("\n");
|
|
107
|
+
}
|
|
108
|
+
return { attachments: list, uploaded, providerMissing, injectedText };
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=pre-upload-attachments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pre-upload-attachments.js","sourceRoot":"","sources":["../../src/file-upload/pre-upload-attachments.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentChatAttachment } from \"../agent/types.js\";\nimport { uploadFile } from \"./registry.js\";\n\nexport interface PreUploadedImageAttachment {\n name?: string;\n url: string;\n provider: string;\n contentType?: string;\n}\n\nexport interface PreUploadAttachmentsResult {\n /** Same array reference. Each image attachment that was uploaded also gets a\n * `url` property attached (non-breaking; consumers that don't read it are\n * unaffected). */\n attachments: AgentChatAttachment[];\n /** Set when at least one image was uploaded. List of hosted URLs the agent\n * can embed in HTML, slide content, documents, etc. */\n uploaded: PreUploadedImageAttachment[];\n /** True if at least one image attachment failed to upload because no\n * file-upload provider is configured. Templates use this to render a\n * \"Connect Builder.io\" suggestion. */\n providerMissing: boolean;\n /** A pre-formatted block to inject into the user message text so the agent\n * has each hosted URL inline. Null when nothing was uploaded or no provider\n * is configured. */\n injectedText: string | null;\n}\n\nconst DATA_URL_RE = /^data:(image\\/[^;]+);base64,(.+)$/;\n\nfunction escapeXmlAttr(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\");\n}\n\n/**\n * Pre-upload chat image attachments through the active file-upload provider\n * (Builder.io by default) so the agent can embed hosted URLs in HTML, slide\n * content, and outbound messages. Keeps the original base64 data URL on the\n * attachment so multimodal vision still works — only adds a hosted `url`.\n *\n * Safe to call when no provider is configured: it returns the attachments\n * untouched with `providerMissing: true` so callers can surface a connect-\n * Builder.io hint to the agent.\n */\nexport async function preUploadImageAttachments(opts: {\n attachments: AgentChatAttachment[] | undefined;\n ownerEmail: string | null | undefined;\n}): Promise<PreUploadAttachmentsResult> {\n const list = Array.isArray(opts.attachments) ? opts.attachments : [];\n const uploaded: PreUploadedImageAttachment[] = [];\n let providerMissing = false;\n\n if (list.length === 0) {\n return {\n attachments: list,\n uploaded,\n providerMissing: false,\n injectedText: null,\n };\n }\n\n for (const att of list) {\n if (att.type !== \"image\" || typeof att.data !== \"string\") continue;\n if ((att as any).url) {\n // Already pre-uploaded earlier in the pipeline — reuse it.\n uploaded.push({\n name: att.name,\n url: (att as any).url as string,\n provider: ((att as any).uploadProvider as string) || \"unknown\",\n contentType: att.contentType,\n });\n continue;\n }\n\n const match = att.data.match(DATA_URL_RE);\n if (!match) continue;\n const mimeType = match[1];\n let bytes: Uint8Array;\n try {\n bytes = new Uint8Array(Buffer.from(match[2], \"base64\"));\n } catch {\n continue;\n }\n\n try {\n const result = await uploadFile({\n data: bytes,\n filename: att.name,\n mimeType,\n ownerEmail: opts.ownerEmail || undefined,\n });\n if (!result) {\n providerMissing = true;\n continue;\n }\n (att as any).url = result.url;\n (att as any).uploadProvider = result.provider;\n uploaded.push({\n name: att.name,\n url: result.url,\n provider: result.provider,\n contentType: att.contentType,\n });\n } catch (err) {\n // Real upload failure (network, API). Keep the base64 so the model\n // can still see the image, but don't crash the turn.\n console.warn(\n \"[agent-native] pre-upload of chat image attachment failed:\",\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n let injectedText: string | null = null;\n if (uploaded.length > 0) {\n const lines = uploaded.map((u) => {\n const attrs = [\n u.name ? `name=\"${escapeXmlAttr(u.name)}\"` : null,\n `url=\"${escapeXmlAttr(u.url)}\"`,\n u.contentType ? `contentType=\"${escapeXmlAttr(u.contentType)}\"` : null,\n `provider=\"${escapeXmlAttr(u.provider)}\"`,\n ].filter(Boolean);\n return `<chat-image-attachment ${attrs.join(\" \")} />`;\n });\n injectedText = [\n '<chat-image-attachments note=\"The user attached these images. They have been uploaded — use the url attribute when embedding in HTML, slide content, or any outbound message.\">',\n ...lines,\n \"</chat-image-attachments>\",\n ].join(\"\\n\");\n } else if (providerMissing) {\n injectedText = [\n \"<chat-image-attachment-upload-error>\",\n \"The user attached one or more images, but no file-upload provider is configured for this app.\",\n \"Tell the user they need to configure one of: (a) Builder.io — recommended, free credits, one-click connect from Settings → File uploads, (b) BUILDER_PRIVATE_KEY environment variable, (c) a custom provider like S3 / R2 / GCS registered via registerFileUploadProvider(). Use `connect-builder` to render an inline connect card for option (a) when available.\",\n \"Until that's done, you can still SEE the image, but you do NOT have a URL to embed it in HTML or share with other apps.\",\n \"</chat-image-attachment-upload-error>\",\n ].join(\"\\n\");\n }\n\n return { attachments: list, uploaded, providerMissing, injectedText };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/file-upload/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/file-upload/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAoBpB;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAE7E;AAED,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE7D;AAED,wBAAgB,uBAAuB,IAAI,kBAAkB,EAAE,CAE9D;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,IAAI,kBAAkB,GAAG,IAAI,CAQvE;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA4ClC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { builderFileUploadProvider } from "./builder.js";
|
|
2
|
-
const
|
|
3
|
-
|
|
2
|
+
const globals = globalThis;
|
|
3
|
+
const providers = (globals.__agentNativeFileUploadProviders ??= new Map());
|
|
4
|
+
const warnedFallbackRef = (globals.__agentNativeFileUploadWarnedFallback ??= { value: false });
|
|
4
5
|
/**
|
|
5
6
|
* Register a file upload provider. Call from a server plugin or app
|
|
6
7
|
* bootstrap. Idempotent per id — later calls with the same id replace.
|
|
@@ -65,11 +66,11 @@ export async function uploadFile(input) {
|
|
|
65
66
|
// API, rate-limit) propagate to the caller; do NOT catch them here.
|
|
66
67
|
return await builderFileUploadProvider.upload(input);
|
|
67
68
|
}
|
|
68
|
-
if (!
|
|
69
|
-
|
|
70
|
-
console.warn("[agent-native] No file upload provider configured
|
|
71
|
-
"Connect Builder.io in Settings → File uploads,
|
|
72
|
-
"
|
|
69
|
+
if (!warnedFallbackRef.value) {
|
|
70
|
+
warnedFallbackRef.value = true;
|
|
71
|
+
console.warn("[agent-native] No file upload provider configured. " +
|
|
72
|
+
"Connect Builder.io in Settings → File uploads, set BUILDER_PRIVATE_KEY, " +
|
|
73
|
+
"or register a custom provider (S3, R2, GCS, …) via registerFileUploadProvider().");
|
|
73
74
|
}
|
|
74
75
|
return null;
|
|
75
76
|
}
|