@agent-native/core 0.7.13 → 0.7.15
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 +56 -6
- package/dist/a2a/client.d.ts +44 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +88 -11
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/handlers.d.ts +10 -0
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +417 -67
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +212 -19
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/task-store.d.ts +20 -1
- package/dist/a2a/task-store.d.ts.map +1 -1
- package/dist/a2a/task-store.js +72 -2
- package/dist/a2a/task-store.js.map +1 -1
- package/dist/agent/default-model.d.ts +21 -0
- package/dist/agent/default-model.d.ts.map +1 -0
- package/dist/agent/default-model.js +21 -0
- package/dist/agent/default-model.js.map +1 -0
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +7 -4
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +10 -4
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts +1 -1
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +11 -26
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/engine/builtin.js +1 -1
- package/dist/agent/engine/builtin.js.map +1 -1
- package/dist/agent/engine/registry.d.ts +27 -7
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +101 -20
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +1 -0
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/production-agent.d.ts +25 -3
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +227 -36
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/application-state/handlers.d.ts.map +1 -1
- package/dist/application-state/handlers.js +10 -6
- package/dist/application-state/handlers.js.map +1 -1
- package/dist/application-state/script-helpers.d.ts +1 -1
- package/dist/application-state/script-helpers.d.ts.map +1 -1
- package/dist/application-state/script-helpers.js +12 -8
- package/dist/application-state/script-helpers.js.map +1 -1
- package/dist/application-state/store.d.ts.map +1 -1
- package/dist/application-state/store.js +19 -10
- package/dist/application-state/store.js.map +1 -1
- package/dist/chat-threads/store.d.ts +3 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +36 -1
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +79 -13
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +97 -39
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/templates-meta.d.ts +4 -0
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +67 -12
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/cli/workspacify.d.ts +2 -0
- package/dist/cli/workspacify.d.ts.map +1 -1
- package/dist/cli/workspacify.js +5 -4
- package/dist/cli/workspacify.js.map +1 -1
- package/dist/client/AgentPanel.d.ts +7 -2
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +81 -32
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AgentTaskCard.d.ts.map +1 -1
- package/dist/client/AgentTaskCard.js +5 -2
- package/dist/client/AgentTaskCard.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +183 -84
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
- package/dist/client/ConnectBuilderCard.js +2 -1
- package/dist/client/ConnectBuilderCard.js.map +1 -1
- package/dist/client/DefaultSpinner.d.ts +1 -1
- package/dist/client/DefaultSpinner.d.ts.map +1 -1
- package/dist/client/DefaultSpinner.js +2 -9
- package/dist/client/DefaultSpinner.js.map +1 -1
- package/dist/client/ErrorBoundary.d.ts +1 -3
- package/dist/client/ErrorBoundary.d.ts.map +1 -1
- package/dist/client/ErrorBoundary.js +37 -9
- package/dist/client/ErrorBoundary.js.map +1 -1
- package/dist/client/FeedbackButton.d.ts.map +1 -1
- package/dist/client/FeedbackButton.js +4 -3
- package/dist/client/FeedbackButton.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +165 -68
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +2 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-chat.d.ts +11 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +4 -2
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +70 -1
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/api-path.d.ts +5 -0
- package/dist/client/api-path.d.ts.map +1 -0
- package/dist/client/api-path.js +48 -0
- package/dist/client/api-path.js.map +1 -0
- package/dist/client/components/AgentPresenceChip.d.ts +12 -0
- package/dist/client/components/AgentPresenceChip.d.ts.map +1 -0
- package/dist/client/components/AgentPresenceChip.js +42 -0
- package/dist/client/components/AgentPresenceChip.js.map +1 -0
- package/dist/client/components/ApiKeySettings.d.ts.map +1 -1
- package/dist/client/components/ApiKeySettings.js +3 -2
- package/dist/client/components/ApiKeySettings.js.map +1 -1
- package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
- package/dist/client/components/CodeRequiredDialog.js +3 -2
- package/dist/client/components/CodeRequiredDialog.js.map +1 -1
- package/dist/client/components/PresenceBar.d.ts +17 -0
- package/dist/client/components/PresenceBar.d.ts.map +1 -0
- package/dist/client/components/PresenceBar.js +118 -0
- package/dist/client/components/PresenceBar.js.map +1 -0
- package/dist/client/composer/ComposerPlusMenu.d.ts +6 -1
- package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.js +22 -83
- package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +3 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +245 -23
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/draft-key.d.ts +2 -0
- package/dist/client/composer/draft-key.d.ts.map +1 -0
- package/dist/client/composer/draft-key.js +8 -0
- package/dist/client/composer/draft-key.js.map +1 -0
- package/dist/client/composer/types.d.ts +1 -0
- package/dist/client/composer/types.d.ts.map +1 -1
- package/dist/client/composer/use-file-search.d.ts.map +1 -1
- package/dist/client/composer/use-file-search.js +2 -1
- package/dist/client/composer/use-file-search.js.map +1 -1
- package/dist/client/composer/use-mention-search.d.ts.map +1 -1
- package/dist/client/composer/use-mention-search.js +2 -1
- package/dist/client/composer/use-mention-search.js.map +1 -1
- package/dist/client/composer/use-skills.d.ts.map +1 -1
- package/dist/client/composer/use-skills.js +2 -1
- package/dist/client/composer/use-skills.js.map +1 -1
- package/dist/client/composer/useVoiceDictation.d.ts +3 -1
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
- package/dist/client/composer/useVoiceDictation.js +101 -18
- 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/dev-overlay/DevOverlay.d.ts +26 -0
- package/dist/client/dev-overlay/DevOverlay.d.ts.map +1 -0
- package/dist/client/dev-overlay/DevOverlay.js +315 -0
- package/dist/client/dev-overlay/DevOverlay.js.map +1 -0
- package/dist/client/dev-overlay/builtins.d.ts +6 -0
- package/dist/client/dev-overlay/builtins.d.ts.map +1 -0
- package/dist/client/dev-overlay/builtins.js +35 -0
- package/dist/client/dev-overlay/builtins.js.map +1 -0
- package/dist/client/dev-overlay/index.d.ts +6 -0
- package/dist/client/dev-overlay/index.d.ts.map +1 -0
- package/dist/client/dev-overlay/index.js +5 -0
- package/dist/client/dev-overlay/index.js.map +1 -0
- package/dist/client/dev-overlay/registry.d.ts +13 -0
- package/dist/client/dev-overlay/registry.d.ts.map +1 -0
- package/dist/client/dev-overlay/registry.js +63 -0
- package/dist/client/dev-overlay/registry.js.map +1 -0
- package/dist/client/dev-overlay/types.d.ts +56 -0
- package/dist/client/dev-overlay/types.d.ts.map +1 -0
- package/dist/client/dev-overlay/types.js +9 -0
- package/dist/client/dev-overlay/types.js.map +1 -0
- package/dist/client/dev-overlay/use-dev-option.d.ts +12 -0
- package/dist/client/dev-overlay/use-dev-option.d.ts.map +1 -0
- package/dist/client/dev-overlay/use-dev-option.js +73 -0
- package/dist/client/dev-overlay/use-dev-option.js.map +1 -0
- package/dist/client/dev-overlay/use-dev-overlay-shortcut.d.ts +6 -0
- package/dist/client/dev-overlay/use-dev-overlay-shortcut.d.ts.map +1 -0
- package/dist/client/dev-overlay/use-dev-overlay-shortcut.js +29 -0
- package/dist/client/dev-overlay/use-dev-overlay-shortcut.js.map +1 -0
- package/dist/client/frame.d.ts +1 -0
- package/dist/client/frame.d.ts.map +1 -1
- package/dist/client/frame.js +32 -11
- package/dist/client/frame.js.map +1 -1
- package/dist/client/index.d.ts +7 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +9 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/IntegrationCard.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationCard.js +3 -2
- package/dist/client/integrations/IntegrationCard.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +3 -2
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/integrations/useIntegrationStatus.d.ts.map +1 -1
- package/dist/client/integrations/useIntegrationStatus.js +2 -1
- package/dist/client/integrations/useIntegrationStatus.js.map +1 -1
- package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
- package/dist/client/notifications/NotificationsBell.js +26 -8
- package/dist/client/notifications/NotificationsBell.js.map +1 -1
- package/dist/client/observability/ThumbsFeedback.d.ts.map +1 -1
- package/dist/client/observability/ThumbsFeedback.js +2 -1
- package/dist/client/observability/ThumbsFeedback.js.map +1 -1
- package/dist/client/observability/useObservability.d.ts.map +1 -1
- package/dist/client/observability/useObservability.js +2 -1
- package/dist/client/observability/useObservability.js.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.d.ts +0 -7
- package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.js +20 -10
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/onboarding/index.d.ts +1 -0
- package/dist/client/onboarding/index.d.ts.map +1 -1
- package/dist/client/onboarding/index.js +1 -0
- package/dist/client/onboarding/index.js.map +1 -1
- package/dist/client/onboarding/use-onboarding.d.ts +1 -7
- package/dist/client/onboarding/use-onboarding.d.ts.map +1 -1
- package/dist/client/onboarding/use-onboarding.js +27 -13
- package/dist/client/onboarding/use-onboarding.js.map +1 -1
- package/dist/client/onboarding/use-preview-mode.d.ts +10 -0
- package/dist/client/onboarding/use-preview-mode.d.ts.map +1 -0
- package/dist/client/onboarding/use-preview-mode.js +35 -0
- package/dist/client/onboarding/use-preview-mode.js.map +1 -0
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +2 -1
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/RequireActiveOrg.d.ts.map +1 -1
- package/dist/client/org/RequireActiveOrg.js +15 -10
- package/dist/client/org/RequireActiveOrg.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +132 -9
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/org/hooks.d.ts +30 -0
- package/dist/client/org/hooks.d.ts.map +1 -1
- package/dist/client/org/hooks.js +67 -1
- package/dist/client/org/hooks.js.map +1 -1
- package/dist/client/org/index.d.ts +2 -2
- package/dist/client/org/index.d.ts.map +1 -1
- package/dist/client/org/index.js +1 -1
- package/dist/client/org/index.js.map +1 -1
- package/dist/client/progress/RunsTray.d.ts.map +1 -1
- package/dist/client/progress/RunsTray.js +2 -1
- package/dist/client/progress/RunsTray.js.map +1 -1
- package/dist/client/resources/McpServerDetail.d.ts +0 -8
- package/dist/client/resources/McpServerDetail.d.ts.map +1 -1
- package/dist/client/resources/McpServerDetail.js +6 -1
- package/dist/client/resources/McpServerDetail.js.map +1 -1
- package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
- package/dist/client/resources/ResourceEditor.js +2 -1
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +7 -2
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-mcp-servers.d.ts.map +1 -1
- package/dist/client/resources/use-mcp-servers.js +7 -2
- package/dist/client/resources/use-mcp-servers.js.map +1 -1
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js +9 -7
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts.map +1 -1
- package/dist/client/settings/AgentsSection.js +7 -5
- package/dist/client/settings/AgentsSection.js.map +1 -1
- package/dist/client/settings/AutomationsSection.d.ts.map +1 -1
- package/dist/client/settings/AutomationsSection.js +10 -5
- package/dist/client/settings/AutomationsSection.js.map +1 -1
- package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -1
- package/dist/client/settings/BackgroundAgentSection.js +2 -1
- package/dist/client/settings/BackgroundAgentSection.js.map +1 -1
- package/dist/client/settings/SecretsSection.d.ts.map +1 -1
- package/dist/client/settings/SecretsSection.js +12 -4
- package/dist/client/settings/SecretsSection.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +38 -33
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/UsageSection.d.ts.map +1 -1
- package/dist/client/settings/UsageSection.js +2 -1
- package/dist/client/settings/UsageSection.js.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.d.ts +2 -4
- package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.js +66 -23
- package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +9 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +31 -3
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +7 -2
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
- package/dist/client/sharing/ShareDialog.js +4 -3
- package/dist/client/sharing/ShareDialog.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +10 -0
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/terminal/AgentTerminal.d.ts +1 -0
- package/dist/client/terminal/AgentTerminal.d.ts.map +1 -1
- package/dist/client/terminal/AgentTerminal.js +12 -8
- package/dist/client/terminal/AgentTerminal.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 +113 -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 +99 -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 +275 -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 +73 -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 +189 -0
- package/dist/client/tools/ToolsSidebarSection.js.map +1 -0
- package/dist/client/tools/iframe-bridge.d.ts +16 -0
- package/dist/client/tools/iframe-bridge.d.ts.map +1 -0
- package/dist/client/tools/iframe-bridge.js +118 -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/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +2 -1
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/use-avatar.d.ts.map +1 -1
- package/dist/client/use-avatar.js +3 -2
- package/dist/client/use-avatar.js.map +1 -1
- package/dist/client/use-builder-enabled.d.ts.map +1 -1
- package/dist/client/use-builder-enabled.js +2 -1
- package/dist/client/use-builder-enabled.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts +1 -0
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +31 -1
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +9 -8
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/client/use-dev-mode.d.ts.map +1 -1
- package/dist/client/use-dev-mode.js +2 -1
- package/dist/client/use-dev-mode.js.map +1 -1
- package/dist/client/use-send-to-agent-chat.d.ts.map +1 -1
- package/dist/client/use-send-to-agent-chat.js +3 -1
- package/dist/client/use-send-to-agent-chat.js.map +1 -1
- package/dist/client/use-session.d.ts.map +1 -1
- package/dist/client/use-session.js +2 -1
- package/dist/client/use-session.js.map +1 -1
- package/dist/client/useProductionAgent.d.ts.map +1 -1
- package/dist/client/useProductionAgent.js +2 -1
- package/dist/client/useProductionAgent.js.map +1 -1
- package/dist/collab/agent-identity.d.ts +15 -0
- package/dist/collab/agent-identity.d.ts.map +1 -0
- package/dist/collab/agent-identity.js +14 -0
- package/dist/collab/agent-identity.js.map +1 -0
- package/dist/collab/agent-presence.d.ts +59 -0
- package/dist/collab/agent-presence.d.ts.map +1 -0
- package/dist/collab/agent-presence.js +165 -0
- package/dist/collab/agent-presence.js.map +1 -0
- package/dist/collab/awareness.d.ts +7 -0
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/awareness.js +2 -2
- package/dist/collab/awareness.js.map +1 -1
- package/dist/collab/client-struct.d.ts +43 -0
- package/dist/collab/client-struct.d.ts.map +1 -0
- package/dist/collab/client-struct.js +272 -0
- package/dist/collab/client-struct.js.map +1 -0
- package/dist/collab/client.d.ts +2 -0
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +18 -3
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/index.d.ts +6 -1
- package/dist/collab/index.d.ts.map +1 -1
- package/dist/collab/index.js +11 -1
- package/dist/collab/index.js.map +1 -1
- package/dist/collab/json-to-yjs.d.ts +72 -0
- package/dist/collab/json-to-yjs.d.ts.map +1 -0
- package/dist/collab/json-to-yjs.js +456 -0
- package/dist/collab/json-to-yjs.js.map +1 -0
- package/dist/collab/struct-routes.d.ts +52 -0
- package/dist/collab/struct-routes.d.ts.map +1 -0
- package/dist/collab/struct-routes.js +74 -0
- package/dist/collab/struct-routes.js.map +1 -0
- package/dist/collab/ydoc-manager.d.ts +19 -0
- package/dist/collab/ydoc-manager.d.ts.map +1 -1
- package/dist/collab/ydoc-manager.js +49 -0
- package/dist/collab/ydoc-manager.js.map +1 -1
- package/dist/credentials/index.d.ts +27 -10
- package/dist/credentials/index.d.ts.map +1 -1
- package/dist/credentials/index.js +61 -19
- package/dist/credentials/index.js.map +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +10 -1
- package/dist/db/client.js.map +1 -1
- package/dist/db/migrations.d.ts +13 -5
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +9 -2
- package/dist/db/migrations.js.map +1 -1
- package/dist/deploy/build.d.ts +12 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +196 -24
- package/dist/deploy/build.js.map +1 -1
- package/dist/file-upload/builder.d.ts.map +1 -1
- package/dist/file-upload/builder.js +2 -1
- package/dist/file-upload/builder.js.map +1 -1
- package/dist/file-upload/registry.d.ts.map +1 -1
- package/dist/file-upload/registry.js +25 -1
- package/dist/file-upload/registry.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/adapters/email.d.ts +17 -0
- package/dist/integrations/adapters/email.d.ts.map +1 -0
- package/dist/integrations/adapters/email.js +740 -0
- package/dist/integrations/adapters/email.js.map +1 -0
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +190 -32
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/adapters/telegram.d.ts.map +1 -1
- package/dist/integrations/adapters/telegram.js +56 -5
- package/dist/integrations/adapters/telegram.js.map +1 -1
- package/dist/integrations/adapters/whatsapp.d.ts.map +1 -1
- package/dist/integrations/adapters/whatsapp.js +91 -12
- package/dist/integrations/adapters/whatsapp.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts.map +1 -1
- package/dist/integrations/google-docs-poller.js +5 -2
- package/dist/integrations/google-docs-poller.js.map +1 -1
- package/dist/integrations/index.d.ts +1 -0
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +1 -0
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/internal-token.d.ts +18 -0
- package/dist/integrations/internal-token.d.ts.map +1 -0
- package/dist/integrations/internal-token.js +102 -0
- package/dist/integrations/internal-token.js.map +1 -0
- package/dist/integrations/pending-tasks-retry-job.d.ts +15 -0
- package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -0
- package/dist/integrations/pending-tasks-retry-job.js +210 -0
- package/dist/integrations/pending-tasks-retry-job.js.map +1 -0
- package/dist/integrations/pending-tasks-store.d.ts +56 -0
- package/dist/integrations/pending-tasks-store.d.ts.map +1 -0
- package/dist/integrations/pending-tasks-store.js +204 -0
- package/dist/integrations/pending-tasks-store.js.map +1 -0
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +340 -15
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/task-queue-stats.d.ts +22 -0
- package/dist/integrations/task-queue-stats.d.ts.map +1 -0
- package/dist/integrations/task-queue-stats.js +117 -0
- package/dist/integrations/task-queue-stats.js.map +1 -0
- package/dist/integrations/types.d.ts +35 -2
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.d.ts +29 -4
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +323 -85
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/cron.d.ts.map +1 -1
- package/dist/jobs/cron.js +12 -4
- package/dist/jobs/cron.js.map +1 -1
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +141 -16
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/jobs/tools.d.ts.map +1 -1
- package/dist/jobs/tools.js +94 -3
- package/dist/jobs/tools.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +128 -62
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp-client/hub-routes.d.ts +14 -0
- package/dist/mcp-client/hub-routes.d.ts.map +1 -1
- package/dist/mcp-client/hub-routes.js +42 -2
- package/dist/mcp-client/hub-routes.js.map +1 -1
- package/dist/mcp-client/index.d.ts +1 -1
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +1 -1
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/mcp-client/manager.d.ts +3 -0
- package/dist/mcp-client/manager.d.ts.map +1 -1
- package/dist/mcp-client/manager.js +33 -3
- package/dist/mcp-client/manager.js.map +1 -1
- package/dist/mcp-client/remote-store.d.ts +49 -1
- package/dist/mcp-client/remote-store.d.ts.map +1 -1
- package/dist/mcp-client/remote-store.js +253 -6
- package/dist/mcp-client/remote-store.js.map +1 -1
- package/dist/mcp-client/routes.d.ts.map +1 -1
- package/dist/mcp-client/routes.js +11 -9
- package/dist/mcp-client/routes.js.map +1 -1
- package/dist/mcp-client/visibility.d.ts +7 -3
- package/dist/mcp-client/visibility.d.ts.map +1 -1
- package/dist/mcp-client/visibility.js +16 -7
- package/dist/mcp-client/visibility.js.map +1 -1
- package/dist/notifications/actions.d.ts.map +1 -1
- package/dist/notifications/actions.js +7 -1
- package/dist/notifications/actions.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/notifications/routes.d.ts.map +1 -1
- package/dist/notifications/routes.js +20 -3
- package/dist/notifications/routes.js.map +1 -1
- package/dist/notifications/store.d.ts.map +1 -1
- package/dist/notifications/store.js +6 -1
- package/dist/notifications/store.js.map +1 -1
- package/dist/oauth-tokens/google-refresh.d.ts.map +1 -1
- package/dist/oauth-tokens/google-refresh.js +6 -0
- package/dist/oauth-tokens/google-refresh.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts +43 -2
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +83 -14
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/observability/experiments.js +5 -5
- package/dist/observability/experiments.js.map +1 -1
- package/dist/observability/routes.d.ts.map +1 -1
- package/dist/observability/routes.js +37 -8
- package/dist/observability/routes.js.map +1 -1
- package/dist/observability/store.d.ts.map +1 -1
- package/dist/observability/store.js +19 -3
- package/dist/observability/store.js.map +1 -1
- package/dist/observability/types.d.ts +7 -0
- package/dist/observability/types.d.ts.map +1 -1
- package/dist/observability/types.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts.map +1 -1
- package/dist/onboarding/default-steps.js +10 -4
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/onboarding/plugin.d.ts.map +1 -1
- package/dist/onboarding/plugin.js +63 -32
- package/dist/onboarding/plugin.js.map +1 -1
- package/dist/onboarding/types.d.ts +6 -1
- package/dist/onboarding/types.d.ts.map +1 -1
- package/dist/org/accept-pending.d.ts.map +1 -1
- package/dist/org/accept-pending.js +2 -1
- package/dist/org/accept-pending.js.map +1 -1
- package/dist/org/context.d.ts +35 -0
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +136 -0
- package/dist/org/context.js.map +1 -1
- package/dist/org/handlers.d.ts +76 -0
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +411 -2
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/index.d.ts +2 -2
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +2 -2
- package/dist/org/index.js.map +1 -1
- package/dist/org/migrations.d.ts.map +1 -1
- package/dist/org/migrations.js +8 -0
- package/dist/org/migrations.js.map +1 -1
- package/dist/org/plugin.d.ts +6 -0
- package/dist/org/plugin.d.ts.map +1 -1
- package/dist/org/plugin.js +71 -7
- package/dist/org/plugin.js.map +1 -1
- package/dist/org/schema.d.ts +38 -0
- package/dist/org/schema.d.ts.map +1 -1
- package/dist/org/schema.js +2 -0
- package/dist/org/schema.js.map +1 -1
- package/dist/org/types.d.ts +7 -0
- package/dist/org/types.d.ts.map +1 -1
- package/dist/progress/actions.d.ts.map +1 -1
- package/dist/progress/actions.js +10 -1
- package/dist/progress/actions.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/progress/routes.d.ts.map +1 -1
- package/dist/progress/routes.js +20 -3
- package/dist/progress/routes.js.map +1 -1
- package/dist/progress/store.d.ts.map +1 -1
- package/dist/progress/store.js +6 -1
- package/dist/progress/store.js.map +1 -1
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +35 -7
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/script-helpers.d.ts.map +1 -1
- package/dist/resources/script-helpers.js +15 -3
- package/dist/resources/script-helpers.js.map +1 -1
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +12 -4
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/call-agent.d.ts +1 -0
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +146 -36
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/scripts/chat/search-chats.d.ts.map +1 -1
- package/dist/scripts/chat/search-chats.js +3 -2
- package/dist/scripts/chat/search-chats.js.map +1 -1
- package/dist/scripts/db/exec.d.ts +1 -1
- package/dist/scripts/db/exec.d.ts.map +1 -1
- package/dist/scripts/db/exec.js +22 -3
- package/dist/scripts/db/exec.js.map +1 -1
- package/dist/scripts/db/index.d.ts.map +1 -1
- package/dist/scripts/db/index.js +2 -0
- package/dist/scripts/db/index.js.map +1 -1
- package/dist/scripts/db/migrate-user-api-keys.d.ts +24 -0
- package/dist/scripts/db/migrate-user-api-keys.d.ts.map +1 -0
- package/dist/scripts/db/migrate-user-api-keys.js +234 -0
- package/dist/scripts/db/migrate-user-api-keys.js.map +1 -0
- package/dist/scripts/db/query.d.ts +1 -1
- package/dist/scripts/db/query.d.ts.map +1 -1
- package/dist/scripts/db/query.js +22 -3
- package/dist/scripts/db/query.js.map +1 -1
- package/dist/scripts/db/scoping.d.ts.map +1 -1
- package/dist/scripts/db/scoping.js +15 -9
- package/dist/scripts/db/scoping.js.map +1 -1
- package/dist/scripts/db/wipe-leaked-builder-keys.d.ts +27 -0
- package/dist/scripts/db/wipe-leaked-builder-keys.d.ts.map +1 -0
- package/dist/scripts/db/wipe-leaked-builder-keys.js +163 -0
- package/dist/scripts/db/wipe-leaked-builder-keys.js.map +1 -0
- package/dist/scripts/dev/shell.d.ts.map +1 -1
- package/dist/scripts/dev/shell.js +3 -1
- package/dist/scripts/dev/shell.js.map +1 -1
- package/dist/scripts/resources/delete-memory.d.ts.map +1 -1
- package/dist/scripts/resources/delete-memory.js +2 -1
- package/dist/scripts/resources/delete-memory.js.map +1 -1
- package/dist/scripts/resources/delete.d.ts.map +1 -1
- package/dist/scripts/resources/delete.js +2 -1
- package/dist/scripts/resources/delete.js.map +1 -1
- package/dist/scripts/resources/list.d.ts.map +1 -1
- package/dist/scripts/resources/list.js +2 -1
- package/dist/scripts/resources/list.js.map +1 -1
- package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
- package/dist/scripts/resources/migrate-learnings.js +2 -1
- package/dist/scripts/resources/migrate-learnings.js.map +1 -1
- package/dist/scripts/resources/read.d.ts.map +1 -1
- package/dist/scripts/resources/read.js +2 -1
- package/dist/scripts/resources/read.js.map +1 -1
- package/dist/scripts/resources/save-memory.d.ts.map +1 -1
- package/dist/scripts/resources/save-memory.js +2 -1
- package/dist/scripts/resources/save-memory.js.map +1 -1
- package/dist/scripts/resources/write.d.ts.map +1 -1
- package/dist/scripts/resources/write.js +2 -1
- package/dist/scripts/resources/write.js.map +1 -1
- package/dist/secrets/onboarding.d.ts.map +1 -1
- package/dist/secrets/onboarding.js +24 -16
- package/dist/secrets/onboarding.js.map +1 -1
- package/dist/secrets/register-framework-secrets.d.ts +5 -0
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
- package/dist/secrets/register-framework-secrets.js +7 -44
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/secrets/routes.d.ts.map +1 -1
- package/dist/secrets/routes.js +139 -37
- package/dist/secrets/routes.js.map +1 -1
- package/dist/secrets/storage.d.ts.map +1 -1
- package/dist/secrets/storage.js +23 -12
- package/dist/secrets/storage.js.map +1 -1
- package/dist/secrets/substitution.d.ts +24 -2
- package/dist/secrets/substitution.d.ts.map +1 -1
- package/dist/secrets/substitution.js +58 -8
- package/dist/secrets/substitution.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +54 -51
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +42 -15
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +632 -373
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts +8 -0
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +39 -12
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +4 -1
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/analytics.d.ts +0 -1
- package/dist/server/analytics.d.ts.map +1 -1
- package/dist/server/analytics.js +0 -1
- package/dist/server/analytics.js.map +1 -1
- package/dist/server/app-base-path.d.ts +4 -0
- package/dist/server/app-base-path.d.ts.map +1 -0
- package/dist/server/app-base-path.js +33 -0
- package/dist/server/app-base-path.js.map +1 -0
- package/dist/server/auth.d.ts +29 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +629 -82
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +1 -0
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +67 -15
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts +16 -1
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +102 -16
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/cli-capture.d.ts +31 -0
- package/dist/server/cli-capture.d.ts.map +1 -0
- package/dist/server/cli-capture.js +120 -0
- package/dist/server/cli-capture.js.map +1 -0
- package/dist/server/collab-plugin.d.ts +16 -0
- package/dist/server/collab-plugin.d.ts.map +1 -1
- package/dist/server/collab-plugin.js +87 -19
- package/dist/server/collab-plugin.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +499 -164
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/create-server.d.ts +2 -0
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +82 -11
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/credential-provider.d.ts +54 -2
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +164 -2
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/csrf.d.ts +58 -0
- package/dist/server/csrf.d.ts.map +1 -0
- package/dist/server/csrf.js +165 -0
- package/dist/server/csrf.js.map +1 -0
- package/dist/server/design-token-utils.d.ts +132 -0
- package/dist/server/design-token-utils.d.ts.map +1 -0
- package/dist/server/design-token-utils.js +714 -0
- package/dist/server/design-token-utils.js.map +1 -0
- package/dist/server/email.d.ts +10 -0
- package/dist/server/email.d.ts.map +1 -1
- package/dist/server/email.js +63 -16
- package/dist/server/email.js.map +1 -1
- package/dist/server/framework-request-handler.d.ts +20 -0
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +140 -24
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-auth-plugin.d.ts.map +1 -1
- package/dist/server/google-auth-plugin.js +10 -2
- package/dist/server/google-auth-plugin.js.map +1 -1
- package/dist/server/google-oauth.d.ts +102 -3
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +263 -43
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/index.d.ts +5 -5
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +5 -5
- package/dist/server/index.js.map +1 -1
- package/dist/server/oauth-helpers.d.ts +8 -3
- package/dist/server/oauth-helpers.d.ts.map +1 -1
- package/dist/server/oauth-helpers.js +12 -8
- package/dist/server/oauth-helpers.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +50 -9
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/poll.d.ts +33 -0
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +43 -2
- package/dist/server/poll.js.map +1 -1
- package/dist/server/request-context.d.ts +102 -3
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +100 -7
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/security-headers.d.ts +51 -0
- package/dist/server/security-headers.d.ts.map +1 -0
- package/dist/server/security-headers.js +90 -0
- package/dist/server/security-headers.js.map +1 -0
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +96 -2
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +376 -60
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/server/voice-providers-status.d.ts +12 -0
- package/dist/server/voice-providers-status.d.ts.map +1 -0
- package/dist/server/voice-providers-status.js +71 -0
- package/dist/server/voice-providers-status.js.map +1 -0
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +16 -13
- package/dist/sharing/access.js.map +1 -1
- package/dist/sharing/actions/share-resource.d.ts +1 -0
- package/dist/sharing/actions/share-resource.d.ts.map +1 -1
- package/dist/sharing/actions/share-resource.js +45 -0
- package/dist/sharing/actions/share-resource.js.map +1 -1
- package/dist/sharing/schema.d.ts +1 -1
- package/dist/styles/agent-native.css +5 -0
- package/dist/templates/default/.agents/skills/delegate-to-agent/SKILL.md +54 -0
- package/dist/templates/default/app/root.tsx +51 -14
- package/dist/templates/default/app/routes/_index.tsx +6 -1
- package/dist/templates/default/public/favicon.svg +13 -0
- package/dist/templates/default/public/icon-180.svg +12 -3
- package/dist/templates/default/public/icon-192.svg +12 -3
- package/dist/templates/default/public/icon-512.svg +12 -3
- package/dist/templates/default/react-router.config.ts +3 -0
- package/dist/templates/workspace-core/package.json +22 -4
- package/dist/templates/workspace-core/src/credentials.ts +32 -5
- package/dist/templates/workspace-core/tsconfig.json +4 -1
- package/dist/terminal/pty-server.d.ts.map +1 -1
- package/dist/terminal/pty-server.js +7 -1
- package/dist/terminal/pty-server.js.map +1 -1
- package/dist/terminal/terminal-plugin.d.ts.map +1 -1
- package/dist/terminal/terminal-plugin.js +26 -6
- package/dist/terminal/terminal-plugin.js.map +1 -1
- package/dist/tools/actions.d.ts +3 -0
- package/dist/tools/actions.d.ts.map +1 -0
- package/dist/tools/actions.js +270 -0
- package/dist/tools/actions.js.map +1 -0
- package/dist/tools/fetch-tool.d.ts +1 -0
- package/dist/tools/fetch-tool.d.ts.map +1 -1
- package/dist/tools/fetch-tool.js +39 -17
- package/dist/tools/fetch-tool.js.map +1 -1
- package/dist/tools/html-shell.d.ts +44 -0
- package/dist/tools/html-shell.d.ts.map +1 -0
- package/dist/tools/html-shell.js +485 -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 +629 -0
- package/dist/tools/routes.js.map +1 -0
- package/dist/tools/schema.d.ts +578 -0
- package/dist/tools/schema.d.ts.map +1 -0
- package/dist/tools/schema.js +115 -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 +181 -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/tracking/providers.d.ts.map +1 -1
- package/dist/tracking/providers.js +28 -11
- package/dist/tracking/providers.js.map +1 -1
- package/dist/tracking/registry.d.ts.map +1 -1
- package/dist/tracking/registry.js +7 -3
- package/dist/tracking/registry.js.map +1 -1
- package/dist/transcription/builder-transcription.d.ts.map +1 -1
- package/dist/transcription/builder-transcription.js +26 -14
- package/dist/transcription/builder-transcription.js.map +1 -1
- package/dist/triggers/actions.d.ts.map +1 -1
- package/dist/triggers/actions.js +11 -6
- package/dist/triggers/actions.js.map +1 -1
- package/dist/triggers/condition-evaluator.d.ts +8 -0
- package/dist/triggers/condition-evaluator.d.ts.map +1 -1
- package/dist/triggers/condition-evaluator.js +39 -4
- package/dist/triggers/condition-evaluator.js.map +1 -1
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +67 -4
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +18 -7
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/dist/vite/client.d.ts +2 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +240 -8
- package/dist/vite/client.js.map +1 -1
- package/docs/content/a2a-protocol.md +2 -2
- package/docs/content/authentication.md +78 -12
- package/docs/content/cloneable-saas.md +59 -62
- package/docs/content/drop-in-agent.md +2 -2
- package/docs/content/faq.md +73 -43
- package/docs/content/getting-started.md +37 -61
- package/docs/content/mcp-clients.md +14 -1
- package/docs/content/messaging.md +324 -0
- package/docs/content/onboarding.md +82 -12
- package/docs/content/pure-agent-apps.md +55 -28
- package/docs/content/template-analytics.md +65 -59
- package/docs/content/template-calendar.md +61 -56
- package/docs/content/template-clips.md +25 -23
- package/docs/content/template-content.md +36 -26
- package/docs/content/template-design.md +55 -0
- package/docs/content/template-dispatch.md +15 -1
- package/docs/content/template-forms.md +19 -16
- package/docs/content/template-mail.md +78 -80
- package/docs/content/template-slides.md +43 -31
- package/docs/content/template-video.md +49 -22
- package/docs/content/tools.md +107 -0
- package/docs/content/what-is-agent-native.md +89 -105
- package/package.json +5 -1
- package/src/templates/default/.agents/skills/delegate-to-agent/SKILL.md +54 -0
- package/src/templates/default/app/root.tsx +51 -14
- package/src/templates/default/app/routes/_index.tsx +6 -1
- package/src/templates/default/public/favicon.svg +13 -0
- package/src/templates/default/public/icon-180.svg +12 -3
- package/src/templates/default/public/icon-192.svg +12 -3
- package/src/templates/default/public/icon-512.svg +12 -3
- package/src/templates/default/react-router.config.ts +3 -0
- package/src/templates/workspace-core/package.json +22 -4
- package/src/templates/workspace-core/src/credentials.ts +32 -5
- package/src/templates/workspace-core/tsconfig.json +4 -1
- package/docs/content/integrations.md +0 -198
package/dist/server/auth.js
CHANGED
|
@@ -9,10 +9,40 @@ async function getFs() {
|
|
|
9
9
|
}
|
|
10
10
|
return _fs;
|
|
11
11
|
}
|
|
12
|
-
import { defineEventHandler, getMethod, getQuery, setResponseHeader, setResponseStatus, getCookie, setCookie, deleteCookie, } from "h3";
|
|
13
|
-
// In h3 v2, `event.req` IS the web Request —
|
|
12
|
+
import { defineEventHandler, getMethod, getQuery, getRequestIP, sendRedirect, setResponseHeader, setResponseStatus, getCookie, setCookie, deleteCookie, } from "h3";
|
|
13
|
+
// In h3 v2, `event.req` IS the web Request — but in Nitro's dev server (srvx
|
|
14
|
+
// runtime), event.url and event.req share the same underlying URL object.
|
|
15
|
+
// When registerMiddleware strips the mount prefix from event.url.pathname, it
|
|
16
|
+
// also mutates event.req.url (NodeRequestURL setter updates nodeReq.url).
|
|
17
|
+
// Better Auth's router uses new URL(request.url).pathname to extract the
|
|
18
|
+
// sub-route, so it must receive the original full URL — not the stripped one.
|
|
19
|
+
// registerMiddleware saves the original pathname in event.context so we can
|
|
20
|
+
// reconstruct a fresh Request with the correct URL here.
|
|
14
21
|
function toWebRequest(event) {
|
|
15
|
-
|
|
22
|
+
const req = event.req;
|
|
23
|
+
const ctx = event.context;
|
|
24
|
+
if (ctx?._mountedPathname && ctx._mountPrefix) {
|
|
25
|
+
try {
|
|
26
|
+
const url = new URL(req.url);
|
|
27
|
+
const mountedPathname = stripAppBasePath(ctx._mountedPathname);
|
|
28
|
+
if (url.pathname !== mountedPathname) {
|
|
29
|
+
url.pathname = mountedPathname;
|
|
30
|
+
const method = req.method.toUpperCase();
|
|
31
|
+
const hasBody = method !== "GET" && method !== "HEAD";
|
|
32
|
+
return new Request(url.href, {
|
|
33
|
+
method: req.method,
|
|
34
|
+
headers: req.headers,
|
|
35
|
+
// Body may already be partially consumed; pass through as-is.
|
|
36
|
+
// GET/HEAD cannot have a body — omit to avoid spec errors.
|
|
37
|
+
...(hasBody ? { body: req.body, duplex: "half" } : {}),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// URL reconstruction failed — fall through and use original req.
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return req;
|
|
16
46
|
}
|
|
17
47
|
import { getDbExec, isPostgres, intType, isLocalDatabase, retryOnDdlRace, } from "../db/client.js";
|
|
18
48
|
import { getBetterAuth, getBetterAuthSync } from "./better-auth-instance.js";
|
|
@@ -20,7 +50,7 @@ import { getOnboardingHtml, getResetPasswordHtml } from "./onboarding-html.js";
|
|
|
20
50
|
import { migrateLocalUserData } from "./local-migration.js";
|
|
21
51
|
import { readBody } from "../server/h3-helpers.js";
|
|
22
52
|
import { readDesktopSso, writeDesktopSso, clearDesktopSso, } from "./desktop-sso.js";
|
|
23
|
-
import { isElectron as isElectronRequest,
|
|
53
|
+
import { isElectron as isElectronRequest, getAppBasePath, getAppUrl, encodeOAuthState, decodeOAuthState, createOAuthSession, oauthCallbackResponse, oauthErrorPage, resolveOAuthRedirectUri, isAllowedOAuthRedirectUri, } from "./google-oauth.js";
|
|
24
54
|
/**
|
|
25
55
|
* Get the configured session max age. Desktop SSO broker writes from
|
|
26
56
|
* OAuth flows read this so expiration stays consistent with the cookie.
|
|
@@ -95,10 +125,106 @@ async function isLocalModeEnabled() {
|
|
|
95
125
|
* Check if we're in a development/test environment.
|
|
96
126
|
* Used for cookie security settings, not for auth bypass.
|
|
97
127
|
*/
|
|
98
|
-
function isDevEnvironment() {
|
|
128
|
+
export function isDevEnvironment() {
|
|
99
129
|
const env = process.env.NODE_ENV;
|
|
100
130
|
return env === "development" || env === "test";
|
|
101
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Validate a `?return=` URL for the /_agent-native/sign-in entrypoint.
|
|
134
|
+
*
|
|
135
|
+
* Parses the candidate against a sentinel base origin; any input that
|
|
136
|
+
* resolves to a different origin (network-path references, absolute URLs,
|
|
137
|
+
* `data:` / `javascript:` schemes, backslash-bypass tricks WHATWG normalises
|
|
138
|
+
* to `//`) gets rejected and falls back to "/". Control characters are
|
|
139
|
+
* stripped up front to defend against header-injection. Returns the
|
|
140
|
+
* normalised path the parser produced — never the raw input.
|
|
141
|
+
*
|
|
142
|
+
* Exported for unit tests.
|
|
143
|
+
*/
|
|
144
|
+
export function safeReturnPath(raw) {
|
|
145
|
+
if (!raw)
|
|
146
|
+
return "/";
|
|
147
|
+
if (/[\x00-\x1f]/.test(raw))
|
|
148
|
+
return "/";
|
|
149
|
+
try {
|
|
150
|
+
const parsed = new URL(raw, "http://safe-base.invalid");
|
|
151
|
+
if (parsed.origin !== "http://safe-base.invalid")
|
|
152
|
+
return "/";
|
|
153
|
+
return parsed.pathname + parsed.search + parsed.hash;
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
return "/";
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Read the desktop-SSO broker file, but only if the request is plausibly
|
|
161
|
+
* from the Electron desktop app *and* coming from the local machine.
|
|
162
|
+
*
|
|
163
|
+
* The broker file lives in the user's home directory and trusts the local
|
|
164
|
+
* trust boundary — a non-loopback request that pretends to be Electron
|
|
165
|
+
* via User-Agent must NEVER be allowed to read it. We additionally refuse
|
|
166
|
+
* any read in production builds: the desktop app launches with
|
|
167
|
+
* `NODE_ENV=development` (or unset), and any web-hosted production deploy
|
|
168
|
+
* has no business consulting a per-user file on the server's homedir
|
|
169
|
+
* even if one exists.
|
|
170
|
+
*
|
|
171
|
+
* Returns null when the safety checks fail or the file isn't present.
|
|
172
|
+
*/
|
|
173
|
+
async function readDesktopSsoSafely(event) {
|
|
174
|
+
if (process.env.NODE_ENV === "production")
|
|
175
|
+
return null;
|
|
176
|
+
if (!isElectronRequest(event))
|
|
177
|
+
return null;
|
|
178
|
+
// Loopback-only: 127.0.0.1, ::1, and the IPv4-mapped form.
|
|
179
|
+
let ip;
|
|
180
|
+
try {
|
|
181
|
+
ip = getRequestIP(event) ?? undefined;
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
ip = undefined;
|
|
185
|
+
}
|
|
186
|
+
// Strip an optional zone id (e.g. "fe80::1%en0") before comparing.
|
|
187
|
+
const normalised = (ip ?? "").split("%")[0];
|
|
188
|
+
const isLoopback = normalised === "127.0.0.1" ||
|
|
189
|
+
normalised === "::1" ||
|
|
190
|
+
normalised === "::ffff:127.0.0.1" ||
|
|
191
|
+
normalised.startsWith("127.");
|
|
192
|
+
if (!isLoopback)
|
|
193
|
+
return null;
|
|
194
|
+
return await readDesktopSso();
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Extract the framework session token from a Better Auth response's
|
|
198
|
+
* Set-Cookie headers, if any. Used by the password-reset path to skip
|
|
199
|
+
* the freshly-minted session when revoking sibling sessions for the
|
|
200
|
+
* user. Returns undefined if no session cookie was minted (the common
|
|
201
|
+
* case — Better Auth's reset doesn't auto-sign-in by default).
|
|
202
|
+
*/
|
|
203
|
+
function extractSessionTokenFromSetCookies(response) {
|
|
204
|
+
try {
|
|
205
|
+
// Headers may have multiple Set-Cookie entries; iterate via getSetCookie
|
|
206
|
+
// when available (Node 20+ / undici), else fall back to comma split.
|
|
207
|
+
const headers = response.headers;
|
|
208
|
+
const setCookies = typeof headers.getSetCookie === "function"
|
|
209
|
+
? headers.getSetCookie()
|
|
210
|
+
: (headers.get("set-cookie") ?? "")
|
|
211
|
+
.split(/,(?=[^;]+=)/)
|
|
212
|
+
.map((s) => s.trim())
|
|
213
|
+
.filter(Boolean);
|
|
214
|
+
for (const sc of setCookies) {
|
|
215
|
+
// Better Auth's session cookie name is configurable but defaults to
|
|
216
|
+
// `<prefix>.session_token`. Match either the Better Auth default or
|
|
217
|
+
// our COOKIE_NAME (`an_session`) on the same line.
|
|
218
|
+
const match = sc.match(/(?:^|\s|;)(an_session|[\w.-]*session_token)=([^;]+)/i);
|
|
219
|
+
if (match)
|
|
220
|
+
return match[2];
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// Best-effort; treat as no token.
|
|
225
|
+
}
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
102
228
|
// ---------------------------------------------------------------------------
|
|
103
229
|
// ACCESS_TOKEN resolution
|
|
104
230
|
// ---------------------------------------------------------------------------
|
|
@@ -233,6 +359,83 @@ export async function getSessionEmail(token) {
|
|
|
233
359
|
let customGetSession = null;
|
|
234
360
|
let authDisabledMode = false;
|
|
235
361
|
let _authGuardConfig = null;
|
|
362
|
+
// Desktop OAuth exchange store — holds session tokens keyed by a unique flow
|
|
363
|
+
// ID so native apps (Tauri, Electron) that open OAuth in the system browser
|
|
364
|
+
// can retrieve the token after the callback completes on the server.
|
|
365
|
+
//
|
|
366
|
+
// Primary: in-memory Map (fast, works for single-instance dev/preview builds).
|
|
367
|
+
// Fallback: sessions table with a "dex:" prefixed key for cross-instance
|
|
368
|
+
// durability (Cloudflare Workers, multi-region deployments). The value stored
|
|
369
|
+
// in the `email` column is "{realToken}::{userEmail}" so both can be recovered
|
|
370
|
+
// from a single DB lookup.
|
|
371
|
+
const _desktopExchanges = new Map();
|
|
372
|
+
// 5-minute TTL for exchange entries (short — single-use tokens).
|
|
373
|
+
const DESKTOP_EXCHANGE_TTL_MS = 5 * 60 * 1000;
|
|
374
|
+
export function setDesktopExchange(flowId, token, email) {
|
|
375
|
+
_desktopExchanges.set(flowId, {
|
|
376
|
+
token,
|
|
377
|
+
email,
|
|
378
|
+
expiresAt: Date.now() + DESKTOP_EXCHANGE_TTL_MS,
|
|
379
|
+
});
|
|
380
|
+
// Persist to DB so the token survives cross-instance routing (e.g. when
|
|
381
|
+
// templates call this helper directly instead of going through the OAuth
|
|
382
|
+
// callback path).
|
|
383
|
+
void persistDesktopExchangeToDB(flowId, token, email);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Persist a desktop exchange entry to the sessions table so it survives
|
|
387
|
+
* cross-instance routing (e.g. Cloudflare Workers). Stored under a synthetic
|
|
388
|
+
* token key "dex:{flowId}"; the `email` column packs both the real session
|
|
389
|
+
* token and the user email so they can be recovered in one query.
|
|
390
|
+
* Non-fatal — if the DB isn't ready yet the in-memory Map still works for
|
|
391
|
+
* same-instance requests.
|
|
392
|
+
*/
|
|
393
|
+
async function persistDesktopExchangeToDB(flowId, token, email) {
|
|
394
|
+
try {
|
|
395
|
+
await addSession(`dex:${flowId}`, `${token}::${email}`);
|
|
396
|
+
}
|
|
397
|
+
catch {
|
|
398
|
+
// non-fatal — in-memory Map is the primary path
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Retrieve and consume a desktop exchange entry from the DB fallback.
|
|
403
|
+
* Returns null if not found or already consumed.
|
|
404
|
+
*/
|
|
405
|
+
async function consumeDesktopExchangeFromDB(flowId) {
|
|
406
|
+
try {
|
|
407
|
+
// Atomic DELETE...RETURNING prevents token replay: two concurrent polls
|
|
408
|
+
// cannot both retrieve the token because only one DELETE will match the row.
|
|
409
|
+
// SQLite ≥3.35 and PostgreSQL both support this syntax.
|
|
410
|
+
// The created_at predicate enforces the 5-minute TTL so stale DB entries
|
|
411
|
+
// (e.g. the desktop app never polled) are rejected rather than silently
|
|
412
|
+
// redeemed with the session table's default 30-day TTL.
|
|
413
|
+
const client = getDbExec();
|
|
414
|
+
const { rows } = await client.execute({
|
|
415
|
+
sql: `DELETE FROM sessions WHERE token = ? AND created_at > ? RETURNING email`,
|
|
416
|
+
args: [`dex:${flowId}`, Date.now() - DESKTOP_EXCHANGE_TTL_MS],
|
|
417
|
+
});
|
|
418
|
+
if (rows.length === 0)
|
|
419
|
+
return null;
|
|
420
|
+
const packed = (rows[0].email ?? rows[0][0]);
|
|
421
|
+
if (!packed)
|
|
422
|
+
return null;
|
|
423
|
+
const sepIdx = packed.indexOf("::");
|
|
424
|
+
if (sepIdx === -1)
|
|
425
|
+
return null;
|
|
426
|
+
return { token: packed.slice(0, sepIdx), email: packed.slice(sepIdx + 2) };
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
setInterval(() => {
|
|
433
|
+
const now = Date.now();
|
|
434
|
+
for (const [k, v] of _desktopExchanges) {
|
|
435
|
+
if (v.expiresAt < now)
|
|
436
|
+
_desktopExchanges.delete(k);
|
|
437
|
+
}
|
|
438
|
+
}, 60_000).unref?.();
|
|
236
439
|
/**
|
|
237
440
|
* Module-level auth guard function. Set by autoMountAuth() when auth is active.
|
|
238
441
|
* Called by the server middleware to enforce auth on ALL requests (not just
|
|
@@ -260,7 +463,17 @@ export async function runAuthGuard(event) {
|
|
|
260
463
|
return; // Auth not mounted (local mode, etc.)
|
|
261
464
|
return _authGuardFn(event);
|
|
262
465
|
}
|
|
263
|
-
|
|
466
|
+
/**
|
|
467
|
+
* The framework's dev-mode bypass identity. When `AUTH_MODE=local` (or
|
|
468
|
+
* dev-mode falls back), `getSession()` returns `{ email: DEV_MODE_USER_EMAIL }`.
|
|
469
|
+
* Production code that needs to check whether the current request is the
|
|
470
|
+
* dev-mode user (or filter it out of mailers, dashboards, etc.) should
|
|
471
|
+
* compare against this constant instead of inlining the literal —
|
|
472
|
+
* `guard-no-localhost-fallback.mjs` blocks the literal everywhere except
|
|
473
|
+
* `auth.ts` and a handful of dev-mode helpers.
|
|
474
|
+
*/
|
|
475
|
+
export const DEV_MODE_USER_EMAIL = "local@localhost";
|
|
476
|
+
const LOCAL_SESSION = { email: DEV_MODE_USER_EMAIL };
|
|
264
477
|
// ---------------------------------------------------------------------------
|
|
265
478
|
// Auth guard factory
|
|
266
479
|
// ---------------------------------------------------------------------------
|
|
@@ -283,7 +496,7 @@ function applyCorsHeaders(event) {
|
|
|
283
496
|
const originRaw = reqHeaders["origin"];
|
|
284
497
|
const origin = Array.isArray(originRaw) ? originRaw[0] : originRaw;
|
|
285
498
|
if (!origin)
|
|
286
|
-
return;
|
|
499
|
+
return { hasOrigin: false, allowed: true };
|
|
287
500
|
// Dev convenience: always allow localhost origins across ports (Tauri
|
|
288
501
|
// tray apps, the frame, docs). In prod, the CORS_ALLOWED_ORIGINS env
|
|
289
502
|
// var is the safe-list.
|
|
@@ -292,15 +505,16 @@ function applyCorsHeaders(event) {
|
|
|
292
505
|
.map((s) => s.trim())
|
|
293
506
|
.filter(Boolean);
|
|
294
507
|
const allowed = allowlist.length === 0
|
|
295
|
-
? /^https
|
|
508
|
+
? /^(https?|tauri):\/\/(localhost|127\.0\.0\.1|tauri\.localhost)(:\d+)?$/.test(origin)
|
|
296
509
|
: allowlist.includes(origin);
|
|
297
510
|
if (!allowed)
|
|
298
|
-
return;
|
|
511
|
+
return { hasOrigin: true, allowed: false };
|
|
299
512
|
setResponseHeader(event, "Access-Control-Allow-Origin", origin);
|
|
300
513
|
setResponseHeader(event, "Vary", "Origin");
|
|
301
514
|
setResponseHeader(event, "Access-Control-Allow-Credentials", "true");
|
|
302
|
-
setResponseHeader(event, "Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE,OPTIONS");
|
|
303
|
-
setResponseHeader(event, "Access-Control-Allow-Headers", "Content-Type,Authorization,X-Requested-With");
|
|
515
|
+
setResponseHeader(event, "Access-Control-Allow-Methods", "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS");
|
|
516
|
+
setResponseHeader(event, "Access-Control-Allow-Headers", "Content-Type,Authorization,X-Requested-With,X-Request-Source,X-Agent-Native-CSRF");
|
|
517
|
+
return { hasOrigin: true, allowed: true };
|
|
304
518
|
}
|
|
305
519
|
function createAuthGuardFn() {
|
|
306
520
|
return async (event) => {
|
|
@@ -309,13 +523,20 @@ function createAuthGuardFn() {
|
|
|
309
523
|
return;
|
|
310
524
|
const { loginHtml, publicPaths } = config;
|
|
311
525
|
const url = event.node?.req?.url ?? event.path ?? "/";
|
|
312
|
-
const
|
|
526
|
+
const queryStart = url.indexOf("?");
|
|
527
|
+
const rawPath = queryStart >= 0 ? url.slice(0, queryStart) : url;
|
|
528
|
+
const p = stripAppBasePath(rawPath);
|
|
529
|
+
const normalizedUrl = queryStart >= 0 ? `${p}${url.slice(queryStart)}` : p;
|
|
313
530
|
// Emit CORS headers on every request the guard sees so that even
|
|
314
531
|
// error responses (401) reach the browser.
|
|
315
|
-
applyCorsHeaders(event);
|
|
532
|
+
const cors = applyCorsHeaders(event);
|
|
316
533
|
// Preflight short-circuit: the browser sends OPTIONS before the real
|
|
317
534
|
// credentialed request. Must return success without invoking auth.
|
|
318
535
|
if (getMethod(event) === "OPTIONS") {
|
|
536
|
+
if (cors.hasOrigin && !cors.allowed) {
|
|
537
|
+
setResponseStatus(event, 403);
|
|
538
|
+
return "";
|
|
539
|
+
}
|
|
319
540
|
setResponseStatus(event, 204);
|
|
320
541
|
return "";
|
|
321
542
|
}
|
|
@@ -327,6 +548,71 @@ function createAuthGuardFn() {
|
|
|
327
548
|
p === "/_agent-native/google/add-account/callback") {
|
|
328
549
|
return;
|
|
329
550
|
}
|
|
551
|
+
// Integration webhook endpoints verify authenticity via platform-specific
|
|
552
|
+
// signature verification (Slack HMAC, Telegram token, etc.), not sessions.
|
|
553
|
+
if (/^\/_agent-native\/integrations\/[^/]+\/webhook$/.test(p)) {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
// Internal processor endpoint for the integration webhook fanout. The
|
|
557
|
+
// webhook handler enqueues a task to SQL and dispatches a fresh HTTP POST
|
|
558
|
+
// to this endpoint so the agent loop runs in its own function execution
|
|
559
|
+
// (cross-platform serverless-safe — see `integrations/webhook-handler.ts`).
|
|
560
|
+
// Authenticity is verified via an HMAC token signed with A2A_SECRET, plus
|
|
561
|
+
// an atomic SQL claim that prevents duplicate processing.
|
|
562
|
+
if (p === "/_agent-native/integrations/process-task") {
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
// A2A endpoint verifies authenticity via JWT signed with the org's A2A
|
|
566
|
+
// secret (or the global A2A_SECRET fallback), not via session cookies.
|
|
567
|
+
if (p === "/_agent-native/a2a") {
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
// Internal processor endpoint for the A2A async-mode fanout. Mirrors the
|
|
571
|
+
// integration webhook fanout: when `message/send` is called with
|
|
572
|
+
// `async: true`, the JSON-RPC handler enqueues to a2a_tasks and self-
|
|
573
|
+
// fires a POST here so the handler runs in a fresh function execution.
|
|
574
|
+
// Authenticity is verified via an HMAC token signed with A2A_SECRET
|
|
575
|
+
// (same scheme as /_agent-native/integrations/process-task).
|
|
576
|
+
if (p === "/_agent-native/a2a/_process-task") {
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
// A2A secret receive endpoint — verifies authenticity via JWT signed
|
|
580
|
+
// with the calling app's A2A secret, not via session cookies. Used to
|
|
581
|
+
// sync the org A2A secret across connected apps.
|
|
582
|
+
if (p === "/_agent-native/org/a2a-secret/receive") {
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
// Force-sign-in entrypoint. Templates send viewers from public pages
|
|
586
|
+
// (share links, embeds) here with a `?return=<path>` query — anonymous
|
|
587
|
+
// visitors get the loginHtml, and once they sign in the loginHtml's
|
|
588
|
+
// post-login reload re-hits this same URL with a session cookie set,
|
|
589
|
+
// so we 302 them to the original page.
|
|
590
|
+
//
|
|
591
|
+
// `return` is validated by parsing it against a sentinel base origin
|
|
592
|
+
// and checking the resolved origin still matches. This rejects every
|
|
593
|
+
// open-redirect shape — `//evil.com/...` (network-path reference),
|
|
594
|
+
// `/\evil.com/...` (WHATWG URL parser normalises `\` to `/` in HTTP
|
|
595
|
+
// URLs, so a naive prefix check on `//` misses this), absolute URLs
|
|
596
|
+
// like `https://evil.com`, and `data:` / `javascript:` schemes. The
|
|
597
|
+
// reconstructed path comes from the parsed segments so any leftover
|
|
598
|
+
// quirks get normalised. Control chars (incl. CR/LF for header
|
|
599
|
+
// injection) are rejected up front.
|
|
600
|
+
//
|
|
601
|
+
if (p === "/_agent-native/sign-in") {
|
|
602
|
+
const queryStr = queryStart >= 0 ? url.slice(queryStart + 1) : "";
|
|
603
|
+
const safeReturn = safeReturnPath(new URLSearchParams(queryStr).get("return"));
|
|
604
|
+
const session = await getSession(event);
|
|
605
|
+
if (session) {
|
|
606
|
+
return new Response("", {
|
|
607
|
+
status: 302,
|
|
608
|
+
headers: { Location: safeReturn },
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
return new Response(loginHtml, {
|
|
612
|
+
status: 200,
|
|
613
|
+
headers: { "Content-Type": "text/html; charset=utf-8" },
|
|
614
|
+
});
|
|
615
|
+
}
|
|
330
616
|
// Skip static assets (Vite chunks, fonts, images, etc.)
|
|
331
617
|
if (p.startsWith("/assets/") ||
|
|
332
618
|
p.startsWith("/_build/") ||
|
|
@@ -340,7 +626,7 @@ function createAuthGuardFn() {
|
|
|
340
626
|
p.endsWith(".woff")) {
|
|
341
627
|
return;
|
|
342
628
|
}
|
|
343
|
-
if (isPublicPath(
|
|
629
|
+
if (isPublicPath(normalizedUrl, publicPaths))
|
|
344
630
|
return;
|
|
345
631
|
const session = await getSession(event);
|
|
346
632
|
if (session)
|
|
@@ -429,12 +715,12 @@ export async function getSession(event) {
|
|
|
429
715
|
return session;
|
|
430
716
|
// Desktop SSO broker: even with BYOA auth, fall back to the broker
|
|
431
717
|
// for Electron requests so cross-template SSO works for custom-auth
|
|
432
|
-
// templates too.
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
718
|
+
// templates too. Gated on `readDesktopSsoSafely` so a non-loopback
|
|
719
|
+
// request that spoofs `User-Agent: ... Electron/...` cannot read the
|
|
720
|
+
// home-dir broker file (and so production builds never consult it).
|
|
721
|
+
const sso = await readDesktopSsoSafely(event);
|
|
722
|
+
if (sso?.email)
|
|
723
|
+
return { email: sso.email, token: sso.token };
|
|
438
724
|
// Fall through to mobile _session check
|
|
439
725
|
}
|
|
440
726
|
else {
|
|
@@ -453,8 +739,8 @@ export async function getSession(event) {
|
|
|
453
739
|
}
|
|
454
740
|
}
|
|
455
741
|
}
|
|
456
|
-
catch {
|
|
457
|
-
|
|
742
|
+
catch (e) {
|
|
743
|
+
console.error("[auth] ba.api.getSession error:", e);
|
|
458
744
|
}
|
|
459
745
|
// 5. Legacy cookie fallback (for sessions created before migration)
|
|
460
746
|
const cookie = getCookie(event, COOKIE_NAME);
|
|
@@ -470,14 +756,14 @@ export async function getSession(event) {
|
|
|
470
756
|
// a session token created by one template doesn't resolve in another.
|
|
471
757
|
// When an Electron request has no resolvable session, trust the
|
|
472
758
|
// home-dir SSO record written by whichever template the user signed
|
|
473
|
-
// into. Gated on
|
|
474
|
-
//
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
}
|
|
759
|
+
// into. Gated on `readDesktopSsoSafely`: requires Electron User-Agent,
|
|
760
|
+
// a loopback (127.0.0.1 / ::1) source IP, and a non-production NODE_ENV
|
|
761
|
+
// — anything else is rejected so a hostile network request cannot
|
|
762
|
+
// impersonate whichever email last signed into the desktop app.
|
|
763
|
+
const sso = await readDesktopSsoSafely(event);
|
|
764
|
+
if (sso?.email) {
|
|
765
|
+
clearUpgradePendingCookie(event);
|
|
766
|
+
return { email: sso.email, token: sso.token };
|
|
481
767
|
}
|
|
482
768
|
}
|
|
483
769
|
// 6. Mobile WebView bridge — _session query param
|
|
@@ -504,11 +790,18 @@ export async function getSession(event) {
|
|
|
504
790
|
// on a shared DB (Postgres, Turso, D1) this fallback would land every
|
|
505
791
|
// developer on the same account and expose each other's data.
|
|
506
792
|
//
|
|
793
|
+
// STRICT NODE_ENV check: this used to read `isDevEnvironment()` which
|
|
794
|
+
// also accepted `NODE_ENV=test`, meaning a misconfigured prod deploy
|
|
795
|
+
// started with `NODE_ENV=test` (or undefined NODE_ENV in some CI/build
|
|
796
|
+
// contexts) would silently bypass auth entirely. Limiting to the literal
|
|
797
|
+
// string "development" closes that footgun. Tests that need this branch
|
|
798
|
+
// to fire stub NODE_ENV explicitly to "development".
|
|
799
|
+
//
|
|
507
800
|
// EXCEPTION: if the user has explicitly exited local mode (clicked "Upgrade
|
|
508
801
|
// to real account"), they've signaled they want real auth. The upgrade
|
|
509
802
|
// cookie suppresses this fallback so the onboarding/sign-in page is served
|
|
510
803
|
// instead of silently re-authenticating them as local@localhost.
|
|
511
|
-
if (
|
|
804
|
+
if (process.env.NODE_ENV === "development" &&
|
|
512
805
|
isLocalDatabase() &&
|
|
513
806
|
!isUpgradePending(event) &&
|
|
514
807
|
!hasSignInFlag(event)) {
|
|
@@ -554,6 +847,10 @@ function hasSignInFlag(event) {
|
|
|
554
847
|
return false;
|
|
555
848
|
}
|
|
556
849
|
}
|
|
850
|
+
function isReadMethod(event) {
|
|
851
|
+
const method = getMethod(event);
|
|
852
|
+
return method === "GET" || method === "HEAD";
|
|
853
|
+
}
|
|
557
854
|
/**
|
|
558
855
|
* Cookie attributes that work in both same-site and third-party iframe
|
|
559
856
|
* contexts. Over HTTPS we emit `SameSite=None; Secure` (required by browsers
|
|
@@ -609,6 +906,17 @@ function isPublicPath(url, publicPaths) {
|
|
|
609
906
|
const p = url.split("?")[0];
|
|
610
907
|
return publicPaths.some((pp) => p === pp || p.startsWith(pp + "/"));
|
|
611
908
|
}
|
|
909
|
+
function stripAppBasePath(pathname) {
|
|
910
|
+
const basePath = getAppBasePath();
|
|
911
|
+
if (!basePath)
|
|
912
|
+
return pathname;
|
|
913
|
+
if (pathname === basePath)
|
|
914
|
+
return "/";
|
|
915
|
+
if (pathname.startsWith(`${basePath}/`)) {
|
|
916
|
+
return pathname.slice(basePath.length) || "/";
|
|
917
|
+
}
|
|
918
|
+
return pathname;
|
|
919
|
+
}
|
|
612
920
|
// ---------------------------------------------------------------------------
|
|
613
921
|
// Login page HTML (ACCESS_TOKEN mode)
|
|
614
922
|
// ---------------------------------------------------------------------------
|
|
@@ -678,10 +986,18 @@ const TOKEN_LOGIN_HTML = `<!DOCTYPE html>
|
|
|
678
986
|
</form>
|
|
679
987
|
</div>
|
|
680
988
|
<script>
|
|
989
|
+
function __anBasePath() {
|
|
990
|
+
var marker = '/_agent-native';
|
|
991
|
+
var idx = window.location.pathname.indexOf(marker);
|
|
992
|
+
return idx > 0 ? window.location.pathname.slice(0, idx) : '';
|
|
993
|
+
}
|
|
994
|
+
function __anPath(path) {
|
|
995
|
+
return __anBasePath() + path;
|
|
996
|
+
}
|
|
681
997
|
document.getElementById('form').addEventListener('submit', async (e) => {
|
|
682
998
|
e.preventDefault();
|
|
683
999
|
const token = document.getElementById('token').value;
|
|
684
|
-
const res = await fetch('/_agent-native/auth/login', {
|
|
1000
|
+
const res = await fetch(__anPath('/_agent-native/auth/login'), {
|
|
685
1001
|
method: 'POST',
|
|
686
1002
|
headers: { 'Content-Type': 'application/json' },
|
|
687
1003
|
body: JSON.stringify({ token }),
|
|
@@ -703,7 +1019,7 @@ async function setAuthModeLocal() {
|
|
|
703
1019
|
const fs = await getFs();
|
|
704
1020
|
fs.mkdirSync(path.dirname(LOCAL_MODE_MARKER_PATH), { recursive: true });
|
|
705
1021
|
fs.writeFileSync(LOCAL_MODE_MARKER_PATH, "local\n", "utf-8");
|
|
706
|
-
process.env.AUTH_MODE = "local";
|
|
1022
|
+
process.env.AUTH_MODE = "local"; // guard:allow-env-mutation — escape-hatch writes the local-mode marker file; mirrored into env so the in-flight process honors the change without restart
|
|
707
1023
|
return true;
|
|
708
1024
|
}
|
|
709
1025
|
catch {
|
|
@@ -719,7 +1035,7 @@ async function removeAuthModeLocal() {
|
|
|
719
1035
|
catch {
|
|
720
1036
|
// Marker already absent
|
|
721
1037
|
}
|
|
722
|
-
delete process.env.AUTH_MODE;
|
|
1038
|
+
delete process.env.AUTH_MODE; // guard:allow-env-mutation — escape-hatch removes the local-mode marker; mirrored into env so the in-flight process honors the change without restart
|
|
723
1039
|
return true;
|
|
724
1040
|
}
|
|
725
1041
|
catch {
|
|
@@ -754,7 +1070,11 @@ const migrateLocalDataHandler = defineEventHandler(async (event) => {
|
|
|
754
1070
|
setResponseStatus(event, 500);
|
|
755
1071
|
return {
|
|
756
1072
|
error: e?.message || "Migration failed",
|
|
757
|
-
|
|
1073
|
+
// Only surface the stack when explicitly enabled. `isDevEnvironment()`
|
|
1074
|
+
// returns true on preview deploys and Lambda contexts that forget
|
|
1075
|
+
// NODE_ENV=production, which leaked stack traces to clients. Use
|
|
1076
|
+
// AGENT_NATIVE_DEBUG_ERRORS=1 for opt-in debug visibility.
|
|
1077
|
+
stack: process.env.AGENT_NATIVE_DEBUG_ERRORS === "1" ? e?.stack : undefined,
|
|
758
1078
|
};
|
|
759
1079
|
}
|
|
760
1080
|
});
|
|
@@ -786,17 +1106,31 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
786
1106
|
"https://www.googleapis.com/auth/userinfo.profile",
|
|
787
1107
|
].join(" ");
|
|
788
1108
|
app.use("/_agent-native/google/auth-url", defineEventHandler((event) => {
|
|
789
|
-
if (event.context.matchedRoute &&
|
|
790
|
-
event.context.matchedRoute.path !== "/**:page")
|
|
791
|
-
return undefined;
|
|
792
1109
|
if (getMethod(event) !== "GET") {
|
|
793
1110
|
setResponseStatus(event, 405);
|
|
794
1111
|
return { error: "Method not allowed" };
|
|
795
1112
|
}
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
1113
|
+
// Validate the user-supplied `redirect_uri` against the framework's
|
|
1114
|
+
// server-side allowlist (must be same-origin and under
|
|
1115
|
+
// `/_agent-native/...`). Reject anything else so an attacker can't
|
|
1116
|
+
// smuggle a different already-registered redirect URI past Google's
|
|
1117
|
+
// host-prefix matching. See HIGH-1 in 09-oauth-session.md.
|
|
1118
|
+
const redirectUri = resolveOAuthRedirectUri(event);
|
|
1119
|
+
if (redirectUri === null) {
|
|
1120
|
+
setResponseStatus(event, 400);
|
|
1121
|
+
return { error: "Invalid redirect_uri" };
|
|
1122
|
+
}
|
|
1123
|
+
const q = getQuery(event);
|
|
1124
|
+
const desktop = isElectronRequest(event) || q.desktop === "1" || q.desktop === "true";
|
|
1125
|
+
const flowId = desktop ? q.flow_id || undefined : undefined;
|
|
1126
|
+
// Validate the caller's return param up front and only embed it
|
|
1127
|
+
// into the OAuth state when it normalises to a non-root path —
|
|
1128
|
+
// skip embedding "/" (the default fallback) so the state stays
|
|
1129
|
+
// small for the common case.
|
|
1130
|
+
const returnQuery = q.return;
|
|
1131
|
+
const validated = typeof returnQuery === "string" ? safeReturnPath(returnQuery) : "/";
|
|
1132
|
+
const returnUrl = validated !== "/" ? validated : undefined;
|
|
1133
|
+
const state = encodeOAuthState(redirectUri, undefined, desktop, false, undefined, returnUrl, flowId);
|
|
800
1134
|
const params = new URLSearchParams({
|
|
801
1135
|
client_id: process.env.GOOGLE_CLIENT_ID,
|
|
802
1136
|
redirect_uri: redirectUri,
|
|
@@ -806,14 +1140,13 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
806
1140
|
prompt: "select_account",
|
|
807
1141
|
state,
|
|
808
1142
|
});
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
1143
|
+
const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?${params}`;
|
|
1144
|
+
if (q.redirect === "1") {
|
|
1145
|
+
return sendRedirect(event, authUrl, 302);
|
|
1146
|
+
}
|
|
1147
|
+
return { url: authUrl };
|
|
812
1148
|
}));
|
|
813
1149
|
app.use("/_agent-native/google/callback", defineEventHandler(async (event) => {
|
|
814
|
-
if (event.context.matchedRoute &&
|
|
815
|
-
event.context.matchedRoute.path !== "/**:page")
|
|
816
|
-
return undefined;
|
|
817
1150
|
if (getMethod(event) !== "GET") {
|
|
818
1151
|
setResponseStatus(event, 405);
|
|
819
1152
|
return { error: "Method not allowed" };
|
|
@@ -825,7 +1158,16 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
825
1158
|
setResponseStatus(event, 400);
|
|
826
1159
|
return { error: "Missing authorization code" };
|
|
827
1160
|
}
|
|
828
|
-
const { redirectUri, desktop } = decodeOAuthState(query.state,
|
|
1161
|
+
const { redirectUri, desktop, returnUrl, flowId } = decodeOAuthState(query.state, getAppUrl(event, "/_agent-native/google/callback"));
|
|
1162
|
+
// Defence in depth: the state is HMAC-signed, but if the signing
|
|
1163
|
+
// key ever leaked an attacker could mint state with their own
|
|
1164
|
+
// redirect_uri. Re-validate against the same allowlist used at
|
|
1165
|
+
// auth-url time so the token exchange is always sent to a URI we
|
|
1166
|
+
// own.
|
|
1167
|
+
if (!isAllowedOAuthRedirectUri(redirectUri, event)) {
|
|
1168
|
+
setResponseStatus(event, 400);
|
|
1169
|
+
return { error: "Invalid redirect_uri in state" };
|
|
1170
|
+
}
|
|
829
1171
|
const tokenRes = await fetch("https://oauth2.googleapis.com/token", {
|
|
830
1172
|
method: "POST",
|
|
831
1173
|
headers: {
|
|
@@ -850,13 +1192,37 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
850
1192
|
const email = user.email;
|
|
851
1193
|
if (!email)
|
|
852
1194
|
throw new Error("Could not get email from Google");
|
|
1195
|
+
// Reject unverified Google addresses. Google returns
|
|
1196
|
+
// `verified_email: false` for accounts where ownership of the
|
|
1197
|
+
// address hasn't been proven (rare on consumer accounts but
|
|
1198
|
+
// reachable on Workspace tenants that allow it). Without this
|
|
1199
|
+
// check, an attacker could sign up as `victim@example.com` on
|
|
1200
|
+
// Google without controlling the inbox and take over a local
|
|
1201
|
+
// password account that already exists at that address (Better
|
|
1202
|
+
// Auth's accountLinking auto-merges trusted-provider sign-ins).
|
|
1203
|
+
if (user.verified_email !== true) {
|
|
1204
|
+
throw new Error("Google account email is not verified. Please verify your email with Google and try again.");
|
|
1205
|
+
}
|
|
853
1206
|
const { sessionToken } = await createOAuthSession(event, email, {
|
|
854
1207
|
hasProductionSession: false,
|
|
855
1208
|
desktop,
|
|
856
1209
|
});
|
|
1210
|
+
if (flowId && sessionToken) {
|
|
1211
|
+
_desktopExchanges.set(flowId, {
|
|
1212
|
+
token: sessionToken,
|
|
1213
|
+
email,
|
|
1214
|
+
expiresAt: Date.now() + DESKTOP_EXCHANGE_TTL_MS,
|
|
1215
|
+
});
|
|
1216
|
+
// Also persist to DB for cross-instance durability (Cloudflare
|
|
1217
|
+
// Workers, multi-region). Fire-and-forget — in-memory Map is
|
|
1218
|
+
// still the primary fast path for same-instance requests.
|
|
1219
|
+
void persistDesktopExchangeToDB(flowId, sessionToken, email);
|
|
1220
|
+
}
|
|
857
1221
|
return oauthCallbackResponse(event, email, {
|
|
858
1222
|
sessionToken,
|
|
859
1223
|
desktop,
|
|
1224
|
+
returnUrl,
|
|
1225
|
+
flowId,
|
|
860
1226
|
});
|
|
861
1227
|
}
|
|
862
1228
|
catch (error) {
|
|
@@ -865,6 +1231,40 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
865
1231
|
}
|
|
866
1232
|
}));
|
|
867
1233
|
}
|
|
1234
|
+
// Desktop OAuth exchange — native apps (Tauri tray, Electron) open OAuth
|
|
1235
|
+
// in the system browser but need a way to retrieve the session token
|
|
1236
|
+
// afterwards since they don't share a cookie jar with the browser.
|
|
1237
|
+
app.use("/_agent-native/auth/desktop-exchange", defineEventHandler(async (event) => {
|
|
1238
|
+
if (getMethod(event) !== "GET") {
|
|
1239
|
+
setResponseStatus(event, 405);
|
|
1240
|
+
return { error: "Method not allowed" };
|
|
1241
|
+
}
|
|
1242
|
+
const flowId = getQuery(event).flow_id;
|
|
1243
|
+
if (!flowId) {
|
|
1244
|
+
setResponseStatus(event, 400);
|
|
1245
|
+
return { error: "Missing flow_id" };
|
|
1246
|
+
}
|
|
1247
|
+
let entry = _desktopExchanges.get(flowId);
|
|
1248
|
+
if (!entry || entry.expiresAt < Date.now()) {
|
|
1249
|
+
// In-memory miss — fall back to the DB-persisted entry. This handles
|
|
1250
|
+
// cross-instance routing (Cloudflare Workers, multi-region) where the
|
|
1251
|
+
// OAuth callback and the polling request may hit different isolates.
|
|
1252
|
+
const fromDb = await consumeDesktopExchangeFromDB(flowId);
|
|
1253
|
+
if (!fromDb) {
|
|
1254
|
+
return { pending: true };
|
|
1255
|
+
}
|
|
1256
|
+
entry = {
|
|
1257
|
+
token: fromDb.token,
|
|
1258
|
+
email: fromDb.email,
|
|
1259
|
+
expiresAt: Date.now() + 1, // already consumed from DB
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
_desktopExchanges.delete(flowId);
|
|
1263
|
+
// Also wipe the DB-persisted entry so it cannot be replayed via the
|
|
1264
|
+
// DB fallback path after in-memory consumption.
|
|
1265
|
+
void removeSession(`dex:${flowId}`);
|
|
1266
|
+
return { token: entry.token, email: entry.email };
|
|
1267
|
+
}));
|
|
868
1268
|
const accessTokens = getAccessTokens();
|
|
869
1269
|
// Initialize Better Auth
|
|
870
1270
|
const auth = await getBetterAuth(options.betterAuth);
|
|
@@ -872,24 +1272,55 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
872
1272
|
app.use("/_agent-native/auth/ba", defineEventHandler(async (event) => {
|
|
873
1273
|
const reqPath = event.url?.pathname ?? event.path ?? "";
|
|
874
1274
|
const isResetPassword = reqPath.includes("reset-password") && getMethod(event) === "POST";
|
|
875
|
-
// Pre-read the body for reset-password so we can
|
|
876
|
-
//
|
|
1275
|
+
// Pre-read the body for reset-password so we can auto-verify the
|
|
1276
|
+
// user's email after they save the new password. CRUCIAL: clone
|
|
1277
|
+
// the Request first — h3 v2 `event.req` is the live web Request,
|
|
1278
|
+
// and `.text()`/`.json()` consume the stream. The same `event.req`
|
|
1279
|
+
// is handed to Better Auth below; without the clone, Better Auth
|
|
1280
|
+
// sees an empty body, fails Zod validation, and returns 400 —
|
|
1281
|
+
// which the reset page renders as "the link may have expired".
|
|
877
1282
|
let resetToken;
|
|
1283
|
+
let resetUserId;
|
|
878
1284
|
if (isResetPassword) {
|
|
879
1285
|
try {
|
|
880
|
-
const
|
|
1286
|
+
const cloned = event.req.clone();
|
|
1287
|
+
const body = (await cloned.json().catch(() => undefined));
|
|
881
1288
|
resetToken = body?.token;
|
|
882
1289
|
}
|
|
883
1290
|
catch {
|
|
884
1291
|
// ignore — Better Auth will handle validation
|
|
885
1292
|
}
|
|
1293
|
+
// Look up userId BEFORE calling auth.handler — Better Auth deletes
|
|
1294
|
+
// the verification row as part of the reset, so by the time the
|
|
1295
|
+
// handler returns 200 the row is gone and we can't recover the user.
|
|
1296
|
+
if (resetToken) {
|
|
1297
|
+
try {
|
|
1298
|
+
const { getDbExec } = await import("../db/client.js");
|
|
1299
|
+
const db = getDbExec();
|
|
1300
|
+
const rows = await db.execute({
|
|
1301
|
+
sql: "SELECT value FROM verification WHERE identifier = ?",
|
|
1302
|
+
args: [`reset-password:${resetToken}`],
|
|
1303
|
+
});
|
|
1304
|
+
resetUserId = rows.rows[0]?.value;
|
|
1305
|
+
}
|
|
1306
|
+
catch {
|
|
1307
|
+
// Best-effort — if we can't read the verification row we just
|
|
1308
|
+
// skip auto-verify; the user can verify normally.
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
886
1311
|
}
|
|
887
1312
|
const response = await auth.handler(toWebRequest(event));
|
|
888
1313
|
const isResponse = response != null &&
|
|
889
1314
|
typeof response.status === "number" &&
|
|
890
1315
|
typeof response.headers?.get === "function";
|
|
891
|
-
// After email verification, add ?verified to the redirect so the
|
|
892
|
-
// login page can show
|
|
1316
|
+
// After email verification, add ?verified=1 to the redirect so the
|
|
1317
|
+
// login page can show "Email verified!". MUTATE the response in
|
|
1318
|
+
// place — `new Response(null, { headers: new Headers(response.headers) })`
|
|
1319
|
+
// collapses multiple Set-Cookie headers into one comma-joined value,
|
|
1320
|
+
// which browsers reject. With `autoSignInAfterVerification: true`
|
|
1321
|
+
// Better Auth emits 2–3 Set-Cookie headers (session token + cookie
|
|
1322
|
+
// cache + dontRememberToken); losing them strands the user on the
|
|
1323
|
+
// login page even though verification succeeded.
|
|
893
1324
|
if (reqPath.includes("verify-email") &&
|
|
894
1325
|
isResponse &&
|
|
895
1326
|
response.status >= 300 &&
|
|
@@ -897,38 +1328,83 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
897
1328
|
const loc = response.headers.get("location");
|
|
898
1329
|
if (loc && !/[?&]verified=/.test(loc)) {
|
|
899
1330
|
const sep = loc.includes("?") ? "&" : "?";
|
|
900
|
-
|
|
901
|
-
status: response.status,
|
|
902
|
-
headers: new Headers(response.headers),
|
|
903
|
-
});
|
|
904
|
-
newResponse.headers.set("location", loc + sep + "verified=1");
|
|
905
|
-
return newResponse;
|
|
1331
|
+
response.headers.set("location", loc + sep + "verified=1");
|
|
906
1332
|
}
|
|
907
1333
|
}
|
|
908
1334
|
// Auto-verify email after a successful password reset. The user
|
|
909
|
-
// proved email ownership by receiving and using the reset link
|
|
1335
|
+
// proved email ownership by receiving and using the reset link, so
|
|
1336
|
+
// we don't want them stuck behind `requireEmailVerification` after
|
|
1337
|
+
// resetting — that's the exact escape hatch they just used.
|
|
910
1338
|
if (isResetPassword &&
|
|
911
|
-
|
|
1339
|
+
resetUserId &&
|
|
912
1340
|
isResponse &&
|
|
913
1341
|
response.status >= 200 &&
|
|
914
1342
|
response.status < 300) {
|
|
915
1343
|
try {
|
|
916
1344
|
const { getDbExec } = await import("../db/client.js");
|
|
917
1345
|
const db = getDbExec();
|
|
918
|
-
//
|
|
919
|
-
//
|
|
920
|
-
//
|
|
921
|
-
//
|
|
922
|
-
|
|
923
|
-
sql: "
|
|
924
|
-
args: [
|
|
1346
|
+
// Use boolean literals for cross-dialect portability: Postgres
|
|
1347
|
+
// stores `email_verified` as BOOLEAN and rejects integer 1/0,
|
|
1348
|
+
// SQLite accepts TRUE/FALSE as aliases for 1/0 (since 3.23).
|
|
1349
|
+
// Quote `"user"` because it's a reserved keyword in Postgres.
|
|
1350
|
+
await db.execute({
|
|
1351
|
+
sql: 'UPDATE "user" SET email_verified = TRUE WHERE id = ? AND (email_verified = FALSE OR email_verified IS NULL)',
|
|
1352
|
+
args: [resetUserId],
|
|
925
1353
|
});
|
|
926
|
-
|
|
927
|
-
|
|
1354
|
+
// Revoke every existing session for this user so a stolen
|
|
1355
|
+
// cookie doesn't outlive the password it was paired with. We
|
|
1356
|
+
// do this AFTER Better Auth's response has been generated so
|
|
1357
|
+
// the freshly-minted post-reset session (if any) is captured
|
|
1358
|
+
// by the response's Set-Cookie header — but `auth.handler` for
|
|
1359
|
+
// reset-password does not auto-sign-in by default, so the
|
|
1360
|
+
// common path is "wipe everything; user signs in with new
|
|
1361
|
+
// password." The legacy `sessions` table is also wiped by
|
|
1362
|
+
// joining through the `user.email` column.
|
|
1363
|
+
//
|
|
1364
|
+
// Skip the freshly-minted Better Auth session id when present
|
|
1365
|
+
// (auto-sign-in plugins / future config). Reading it from the
|
|
1366
|
+
// response avoids racing against Better Auth's own writes.
|
|
1367
|
+
const newSessionToken = extractSessionTokenFromSetCookies(response);
|
|
1368
|
+
// 1. Better Auth `session` table — keyed by user_id.
|
|
1369
|
+
if (newSessionToken) {
|
|
928
1370
|
await db.execute({
|
|
929
|
-
sql:
|
|
930
|
-
args: [
|
|
1371
|
+
sql: 'DELETE FROM "session" WHERE user_id = ? AND token <> ?',
|
|
1372
|
+
args: [resetUserId, newSessionToken],
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
else {
|
|
1376
|
+
await db.execute({
|
|
1377
|
+
sql: 'DELETE FROM "session" WHERE user_id = ?',
|
|
1378
|
+
args: [resetUserId],
|
|
1379
|
+
});
|
|
1380
|
+
}
|
|
1381
|
+
// 2. Legacy `sessions` table — keyed by `email` column. The
|
|
1382
|
+
// reset-password verification row holds the user's id, not
|
|
1383
|
+
// their email, so we look up the email first. Best-effort —
|
|
1384
|
+
// skip silently if the lookup fails so the response still ships.
|
|
1385
|
+
try {
|
|
1386
|
+
const { rows } = await db.execute({
|
|
1387
|
+
sql: 'SELECT email FROM "user" WHERE id = ?',
|
|
1388
|
+
args: [resetUserId],
|
|
931
1389
|
});
|
|
1390
|
+
const userEmail = (rows[0]?.email ?? rows[0]?.[0]);
|
|
1391
|
+
if (userEmail) {
|
|
1392
|
+
if (newSessionToken) {
|
|
1393
|
+
await db.execute({
|
|
1394
|
+
sql: "DELETE FROM sessions WHERE email = ? AND token <> ?",
|
|
1395
|
+
args: [userEmail, newSessionToken],
|
|
1396
|
+
});
|
|
1397
|
+
}
|
|
1398
|
+
else {
|
|
1399
|
+
await db.execute({
|
|
1400
|
+
sql: "DELETE FROM sessions WHERE email = ?",
|
|
1401
|
+
args: [userEmail],
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
catch {
|
|
1407
|
+
// Best-effort — don't block the response
|
|
932
1408
|
}
|
|
933
1409
|
}
|
|
934
1410
|
catch {
|
|
@@ -1089,9 +1565,77 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
1089
1565
|
await clearDesktopSso();
|
|
1090
1566
|
return { ok: true };
|
|
1091
1567
|
}));
|
|
1568
|
+
// POST /_agent-native/auth/logout-all — revoke every session row for
|
|
1569
|
+
// the authenticated user across both auth tables. Companion to the
|
|
1570
|
+
// password-reset session-revocation logic; lets a user sign out
|
|
1571
|
+
// everywhere from one device. Requires an authenticated session.
|
|
1572
|
+
app.use("/_agent-native/auth/logout-all", defineEventHandler(async (event) => {
|
|
1573
|
+
if (getMethod(event) !== "POST") {
|
|
1574
|
+
setResponseStatus(event, 405);
|
|
1575
|
+
return { error: "Method not allowed" };
|
|
1576
|
+
}
|
|
1577
|
+
const session = await getSession(event);
|
|
1578
|
+
if (!session?.email) {
|
|
1579
|
+
setResponseStatus(event, 401);
|
|
1580
|
+
return { error: "Not authenticated" };
|
|
1581
|
+
}
|
|
1582
|
+
try {
|
|
1583
|
+
const db = getDbExec();
|
|
1584
|
+
// 1. Resolve user_id from email so we can wipe Better Auth sessions
|
|
1585
|
+
// by their FK column.
|
|
1586
|
+
let userId;
|
|
1587
|
+
try {
|
|
1588
|
+
const { rows } = await db.execute({
|
|
1589
|
+
sql: 'SELECT id FROM "user" WHERE email = ?',
|
|
1590
|
+
args: [session.email],
|
|
1591
|
+
});
|
|
1592
|
+
userId = (rows[0]?.id ?? rows[0]?.[0]);
|
|
1593
|
+
}
|
|
1594
|
+
catch {
|
|
1595
|
+
// User table may not exist on token-only deployments — skip.
|
|
1596
|
+
}
|
|
1597
|
+
if (userId) {
|
|
1598
|
+
try {
|
|
1599
|
+
await db.execute({
|
|
1600
|
+
sql: 'DELETE FROM "session" WHERE user_id = ?',
|
|
1601
|
+
args: [userId],
|
|
1602
|
+
});
|
|
1603
|
+
}
|
|
1604
|
+
catch {
|
|
1605
|
+
// Best-effort.
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
// 2. Legacy `sessions` table — keyed by `email` column.
|
|
1609
|
+
try {
|
|
1610
|
+
await db.execute({
|
|
1611
|
+
sql: "DELETE FROM sessions WHERE email = ?",
|
|
1612
|
+
args: [session.email],
|
|
1613
|
+
});
|
|
1614
|
+
}
|
|
1615
|
+
catch {
|
|
1616
|
+
// Best-effort.
|
|
1617
|
+
}
|
|
1618
|
+
// 3. Drop the current request's cookie and best-effort sign out
|
|
1619
|
+
// of Better Auth (so the response sets the proper expiry header).
|
|
1620
|
+
deleteCookie(event, COOKIE_NAME, { path: "/" });
|
|
1621
|
+
try {
|
|
1622
|
+
await auth.api.signOut({ headers: event.headers });
|
|
1623
|
+
}
|
|
1624
|
+
catch {
|
|
1625
|
+
// Ignore — sessions are already gone in DB.
|
|
1626
|
+
}
|
|
1627
|
+
if (isElectronRequest(event))
|
|
1628
|
+
await clearDesktopSso();
|
|
1629
|
+
return { ok: true };
|
|
1630
|
+
}
|
|
1631
|
+
catch (e) {
|
|
1632
|
+
setResponseStatus(event, 500);
|
|
1633
|
+
return { error: e?.message || "Failed to revoke sessions" };
|
|
1634
|
+
}
|
|
1635
|
+
}));
|
|
1092
1636
|
// GET /_agent-native/auth/session
|
|
1093
1637
|
app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
|
|
1094
|
-
if (
|
|
1638
|
+
if (!isReadMethod(event)) {
|
|
1095
1639
|
setResponseStatus(event, 405);
|
|
1096
1640
|
return { error: "Method not allowed" };
|
|
1097
1641
|
}
|
|
@@ -1106,7 +1650,7 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
1106
1650
|
// reset link in their email. Reads ?token=... and POSTs to Better Auth's
|
|
1107
1651
|
// /reset-password endpoint on submit.
|
|
1108
1652
|
app.use("/_agent-native/auth/reset", defineEventHandler((event) => {
|
|
1109
|
-
if (
|
|
1653
|
+
if (!isReadMethod(event)) {
|
|
1110
1654
|
setResponseStatus(event, 405);
|
|
1111
1655
|
return { error: "Method not allowed" };
|
|
1112
1656
|
}
|
|
@@ -1162,7 +1706,7 @@ function mountTokenOnlyRoutes(app, accessTokens, publicPaths = []) {
|
|
|
1162
1706
|
return { ok: true };
|
|
1163
1707
|
}));
|
|
1164
1708
|
app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
|
|
1165
|
-
if (
|
|
1709
|
+
if (!isReadMethod(event)) {
|
|
1166
1710
|
setResponseStatus(event, 405);
|
|
1167
1711
|
return { error: "Method not allowed" };
|
|
1168
1712
|
}
|
|
@@ -1180,7 +1724,7 @@ function mountTokenOnlyRoutes(app, accessTokens, publicPaths = []) {
|
|
|
1180
1724
|
// ---------------------------------------------------------------------------
|
|
1181
1725
|
function mountLocalModeRoutes(app) {
|
|
1182
1726
|
app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
|
|
1183
|
-
if (
|
|
1727
|
+
if (!isReadMethod(event)) {
|
|
1184
1728
|
setResponseStatus(event, 405);
|
|
1185
1729
|
return { error: "Method not allowed" };
|
|
1186
1730
|
}
|
|
@@ -1340,7 +1884,7 @@ function mountAuthFallbackRoutes(app) {
|
|
|
1340
1884
|
return { ok: true };
|
|
1341
1885
|
}));
|
|
1342
1886
|
app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
|
|
1343
|
-
if (
|
|
1887
|
+
if (!isReadMethod(event)) {
|
|
1344
1888
|
setResponseStatus(event, 405);
|
|
1345
1889
|
return { error: "Method not allowed" };
|
|
1346
1890
|
}
|
|
@@ -1443,7 +1987,7 @@ export async function autoMountAuth(app, options = {}) {
|
|
|
1443
1987
|
// BYOA — custom getSession provider
|
|
1444
1988
|
if (customGetSession) {
|
|
1445
1989
|
app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
|
|
1446
|
-
if (
|
|
1990
|
+
if (!isReadMethod(event)) {
|
|
1447
1991
|
setResponseStatus(event, 405);
|
|
1448
1992
|
return { error: "Method not allowed" };
|
|
1449
1993
|
}
|
|
@@ -1466,7 +2010,8 @@ export async function autoMountAuth(app, options = {}) {
|
|
|
1466
2010
|
const guardFn = createAuthGuardFn();
|
|
1467
2011
|
_authGuardFn = guardFn;
|
|
1468
2012
|
app.use(defineEventHandler(guardFn));
|
|
1469
|
-
|
|
2013
|
+
if (process.env.DEBUG)
|
|
2014
|
+
console.log("[agent-native] Auth enabled — custom getSession provider.");
|
|
1470
2015
|
return true;
|
|
1471
2016
|
}
|
|
1472
2017
|
// AUTH_DISABLED — skip auth (infrastructure-level auth)
|
|
@@ -1481,13 +2026,15 @@ export async function autoMountAuth(app, options = {}) {
|
|
|
1481
2026
|
const tokens = getAccessTokens();
|
|
1482
2027
|
if (tokens.length > 0) {
|
|
1483
2028
|
mountTokenOnlyRoutes(app, tokens, publicPaths);
|
|
1484
|
-
|
|
2029
|
+
if (process.env.DEBUG)
|
|
2030
|
+
console.log(`[agent-native] Auth enabled — ${tokens.length} access token(s) configured.`);
|
|
1485
2031
|
return true;
|
|
1486
2032
|
}
|
|
1487
2033
|
// Default: Better Auth (account-first)
|
|
1488
2034
|
try {
|
|
1489
2035
|
await mountBetterAuthRoutes(app, options);
|
|
1490
|
-
|
|
2036
|
+
if (process.env.DEBUG)
|
|
2037
|
+
console.log("[agent-native] Auth enabled — Better Auth (accounts + organizations).");
|
|
1491
2038
|
}
|
|
1492
2039
|
catch (err) {
|
|
1493
2040
|
console.error("[agent-native] Failed to initialize Better Auth:", err);
|