@agent-native/core 0.5.0-dev.b51eaae → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -37
- package/dist/a2a/agent-card.d.ts.map +1 -1
- package/dist/a2a/agent-card.js +12 -1
- package/dist/a2a/agent-card.js.map +1 -1
- package/dist/a2a/client.d.ts +11 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +38 -1
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/index.d.ts +1 -1
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +1 -1
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/server.d.ts +4 -0
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +53 -8
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/types.d.ts +1 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/action.d.ts +64 -30
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +224 -27
- package/dist/action.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts +24 -0
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -0
- package/dist/agent/engine/ai-sdk-engine.js +302 -0
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -0
- package/dist/agent/engine/anthropic-engine.d.ts +24 -0
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -0
- package/dist/agent/engine/anthropic-engine.js +169 -0
- package/dist/agent/engine/anthropic-engine.js.map +1 -0
- package/dist/agent/engine/builtin.d.ts +12 -0
- package/dist/agent/engine/builtin.d.ts.map +1 -0
- package/dist/agent/engine/builtin.js +72 -0
- package/dist/agent/engine/builtin.js.map +1 -0
- package/dist/agent/engine/index.d.ts +9 -0
- package/dist/agent/engine/index.d.ts.map +1 -0
- package/dist/agent/engine/index.js +8 -0
- package/dist/agent/engine/index.js.map +1 -0
- package/dist/agent/engine/registry.d.ts +61 -0
- package/dist/agent/engine/registry.d.ts.map +1 -0
- package/dist/agent/engine/registry.js +101 -0
- package/dist/agent/engine/registry.js.map +1 -0
- package/dist/agent/engine/translate-ai-sdk.d.ts +20 -0
- package/dist/agent/engine/translate-ai-sdk.d.ts.map +1 -0
- package/dist/agent/engine/translate-ai-sdk.js +174 -0
- package/dist/agent/engine/translate-ai-sdk.js.map +1 -0
- package/dist/agent/engine/translate-anthropic.d.ts +23 -0
- package/dist/agent/engine/translate-anthropic.d.ts.map +1 -0
- package/dist/agent/engine/translate-anthropic.js +140 -0
- package/dist/agent/engine/translate-anthropic.js.map +1 -0
- package/dist/agent/engine/types.d.ts +168 -0
- package/dist/agent/engine/types.d.ts.map +1 -0
- package/dist/agent/engine/types.js +13 -0
- package/dist/agent/engine/types.js.map +1 -0
- package/dist/agent/production-agent.d.ts +48 -2
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +369 -79
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +15 -9
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +5 -5
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +1 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +4 -1
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/agent/types.d.ts +23 -2
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/application-state/handlers.d.ts +8 -8
- package/dist/application-state/handlers.d.ts.map +1 -1
- package/dist/application-state/handlers.js +3 -2
- package/dist/application-state/handlers.js.map +1 -1
- package/dist/application-state/script-helpers.d.ts.map +1 -1
- package/dist/application-state/script-helpers.js +47 -9
- package/dist/application-state/script-helpers.js.map +1 -1
- package/dist/chat-threads/store.d.ts +14 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +32 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/create-workspace.d.ts +8 -0
- package/dist/cli/create-workspace.d.ts.map +1 -0
- package/dist/cli/create-workspace.js +18 -0
- package/dist/cli/create-workspace.js.map +1 -0
- package/dist/cli/create.d.ts +36 -2
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +509 -61
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +73 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/workspacify.d.ts +18 -0
- package/dist/cli/workspacify.d.ts.map +1 -0
- package/dist/cli/workspacify.js +74 -0
- package/dist/cli/workspacify.js.map +1 -0
- package/dist/client/AgentPanel.d.ts +6 -2
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +314 -180
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AgentTaskCard.d.ts +12 -0
- package/dist/client/AgentTaskCard.d.ts.map +1 -0
- package/dist/client/AgentTaskCard.js +146 -0
- package/dist/client/AgentTaskCard.js.map +1 -0
- package/dist/client/AssistantChat.d.ts +13 -2
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +344 -122
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts +7 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +345 -63
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/PoweredByBadge.js +2 -2
- package/dist/client/PoweredByBadge.js.map +1 -1
- package/dist/client/Turnstile.d.ts.map +1 -1
- package/dist/client/Turnstile.js +2 -3
- package/dist/client/Turnstile.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +63 -2
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-chat.d.ts +14 -1
- 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/components/CodeAgentIndicator.d.ts +14 -0
- package/dist/client/components/CodeAgentIndicator.d.ts.map +1 -0
- package/dist/client/components/CodeAgentIndicator.js +29 -0
- package/dist/client/components/CodeAgentIndicator.js.map +1 -0
- package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
- package/dist/client/components/CodeRequiredDialog.js +86 -5
- package/dist/client/components/CodeRequiredDialog.js.map +1 -1
- package/dist/client/composer/MentionPopover.d.ts +4 -1
- package/dist/client/composer/MentionPopover.d.ts.map +1 -1
- package/dist/client/composer/MentionPopover.js +51 -8
- package/dist/client/composer/MentionPopover.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +8 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +149 -17
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/index.d.ts +1 -1
- package/dist/client/composer/index.d.ts.map +1 -1
- package/dist/client/composer/types.d.ts +6 -1
- package/dist/client/composer/types.d.ts.map +1 -1
- package/dist/client/composer/use-mention-search.d.ts.map +1 -1
- package/dist/client/composer/use-mention-search.js +46 -13
- package/dist/client/composer/use-mention-search.js.map +1 -1
- package/dist/client/frame-protocol.d.ts +54 -0
- package/dist/client/frame-protocol.d.ts.map +1 -0
- package/dist/client/frame-protocol.js +9 -0
- package/dist/client/frame-protocol.js.map +1 -0
- package/dist/client/frame.d.ts +56 -0
- package/dist/client/frame.d.ts.map +1 -0
- package/dist/client/{harness.js → frame.js} +49 -26
- package/dist/client/frame.js.map +1 -0
- package/dist/client/index.d.ts +7 -3
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +6 -3
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/IntegrationCard.d.ts +6 -0
- package/dist/client/integrations/IntegrationCard.d.ts.map +1 -0
- package/dist/client/integrations/IntegrationCard.js +45 -0
- package/dist/client/integrations/IntegrationCard.js.map +1 -0
- package/dist/client/integrations/IntegrationsPanel.d.ts +2 -0
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -0
- package/dist/client/integrations/IntegrationsPanel.js +162 -0
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -0
- package/dist/client/integrations/index.d.ts +4 -0
- package/dist/client/integrations/index.d.ts.map +1 -0
- package/dist/client/integrations/index.js +3 -0
- package/dist/client/integrations/index.js.map +1 -0
- package/dist/client/integrations/useIntegrationStatus.d.ts +15 -0
- package/dist/client/integrations/useIntegrationStatus.d.ts.map +1 -0
- package/dist/client/integrations/useIntegrationStatus.js +37 -0
- package/dist/client/integrations/useIntegrationStatus.js.map +1 -0
- package/dist/client/onboarding/OnboardingBanner.d.ts +13 -0
- package/dist/client/onboarding/OnboardingBanner.d.ts.map +1 -0
- package/dist/client/onboarding/OnboardingBanner.js +36 -0
- package/dist/client/onboarding/OnboardingBanner.js.map +1 -0
- package/dist/client/onboarding/OnboardingPanel.d.ts +16 -0
- package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -0
- package/dist/client/onboarding/OnboardingPanel.js +360 -0
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -0
- package/dist/client/onboarding/SetupButton.d.ts +10 -0
- package/dist/client/onboarding/SetupButton.d.ts.map +1 -0
- package/dist/client/onboarding/SetupButton.js +26 -0
- package/dist/client/onboarding/SetupButton.js.map +1 -0
- package/dist/client/onboarding/index.d.ts +12 -0
- package/dist/client/onboarding/index.d.ts.map +1 -0
- package/dist/client/onboarding/index.js +11 -0
- package/dist/client/onboarding/index.js.map +1 -0
- package/dist/client/onboarding/use-onboarding.d.ts +34 -0
- package/dist/client/onboarding/use-onboarding.d.ts.map +1 -0
- package/dist/client/onboarding/use-onboarding.js +101 -0
- package/dist/client/onboarding/use-onboarding.js.map +1 -0
- package/dist/client/org/InvitationBanner.d.ts +9 -0
- package/dist/client/org/InvitationBanner.d.ts.map +1 -0
- package/dist/client/org/InvitationBanner.js +17 -0
- package/dist/client/org/InvitationBanner.js.map +1 -0
- package/dist/client/org/OrgSwitcher.d.ts +14 -0
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -0
- package/dist/client/org/OrgSwitcher.js +51 -0
- package/dist/client/org/OrgSwitcher.js.map +1 -0
- package/dist/client/org/TeamPage.d.ts +28 -0
- package/dist/client/org/TeamPage.d.ts.map +1 -0
- package/dist/client/org/TeamPage.js +216 -0
- package/dist/client/org/TeamPage.js.map +1 -0
- package/dist/client/org/hooks.d.ts +14 -0
- package/dist/client/org/hooks.d.ts.map +1 -0
- package/dist/client/org/hooks.js +101 -0
- package/dist/client/org/hooks.js.map +1 -0
- package/dist/client/org/index.d.ts +6 -0
- package/dist/client/org/index.d.ts.map +1 -0
- package/dist/client/org/index.js +6 -0
- package/dist/client/org/index.js.map +1 -0
- package/dist/client/resources/ResourceEditor.d.ts +8 -1
- package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
- package/dist/client/resources/ResourceEditor.js +141 -89
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts +5 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +33 -5
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +260 -109
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-resources.d.ts +15 -0
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js +2 -2
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts +2 -0
- package/dist/client/settings/AgentsSection.d.ts.map +1 -0
- package/dist/client/settings/AgentsSection.js +198 -0
- package/dist/client/settings/AgentsSection.js.map +1 -0
- package/dist/client/settings/BackgroundAgentSection.d.ts +2 -0
- package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -0
- package/dist/client/settings/BackgroundAgentSection.js +46 -0
- package/dist/client/settings/BackgroundAgentSection.js.map +1 -0
- package/dist/client/settings/BrowserSection.d.ts +2 -0
- package/dist/client/settings/BrowserSection.d.ts.map +1 -0
- package/dist/client/settings/BrowserSection.js +10 -0
- package/dist/client/settings/BrowserSection.js.map +1 -0
- package/dist/client/settings/ComingSoonSection.d.ts +13 -0
- package/dist/client/settings/ComingSoonSection.d.ts.map +1 -0
- package/dist/client/settings/ComingSoonSection.js +9 -0
- package/dist/client/settings/ComingSoonSection.js.map +1 -0
- package/dist/client/settings/LLMSection.d.ts +2 -0
- package/dist/client/settings/LLMSection.d.ts.map +1 -0
- package/dist/client/settings/LLMSection.js +64 -0
- package/dist/client/settings/LLMSection.js.map +1 -0
- package/dist/client/settings/SettingsPanel.d.ts +8 -0
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -0
- package/dist/client/settings/SettingsPanel.js +118 -0
- package/dist/client/settings/SettingsPanel.js.map +1 -0
- package/dist/client/settings/SettingsSection.d.ts +19 -0
- package/dist/client/settings/SettingsSection.d.ts.map +1 -0
- package/dist/client/settings/SettingsSection.js +10 -0
- package/dist/client/settings/SettingsSection.js.map +1 -0
- package/dist/client/settings/index.d.ts +3 -0
- package/dist/client/settings/index.d.ts.map +1 -0
- package/dist/client/settings/index.js +3 -0
- package/dist/client/settings/index.js.map +1 -0
- package/dist/client/settings/useBuilderStatus.d.ts +22 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -0
- package/dist/client/settings/useBuilderStatus.js +41 -0
- package/dist/client/settings/useBuilderStatus.js.map +1 -0
- package/dist/client/sse-event-processor.d.ts +9 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +36 -3
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/terminal/AgentTerminal.d.ts +4 -4
- package/dist/client/terminal/AgentTerminal.d.ts.map +1 -1
- package/dist/client/terminal/AgentTerminal.js +14 -14
- package/dist/client/terminal/AgentTerminal.js.map +1 -1
- package/dist/client/use-action.d.ts +51 -0
- package/dist/client/use-action.d.ts.map +1 -0
- package/dist/client/use-action.js +102 -0
- package/dist/client/use-action.js.map +1 -0
- package/dist/client/use-avatar.d.ts +15 -0
- package/dist/client/use-avatar.d.ts.map +1 -0
- package/dist/client/use-avatar.js +116 -0
- package/dist/client/use-avatar.js.map +1 -0
- package/dist/client/use-chat-threads.d.ts +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +34 -18
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/use-dev-mode.d.ts.map +1 -1
- package/dist/client/use-dev-mode.js +2 -0
- package/dist/client/use-dev-mode.js.map +1 -1
- package/dist/client/use-send-to-agent-chat.d.ts +7 -4
- package/dist/client/use-send-to-agent-chat.d.ts.map +1 -1
- package/dist/client/use-send-to-agent-chat.js +31 -10
- package/dist/client/use-send-to-agent-chat.js.map +1 -1
- package/dist/collab/awareness.d.ts +41 -0
- package/dist/collab/awareness.d.ts.map +1 -0
- package/dist/collab/awareness.js +82 -0
- package/dist/collab/awareness.js.map +1 -0
- package/dist/collab/client.d.ts +49 -0
- package/dist/collab/client.d.ts.map +1 -0
- package/dist/collab/client.js +250 -0
- package/dist/collab/client.js.map +1 -0
- package/dist/collab/emitter.d.ts +12 -0
- package/dist/collab/emitter.d.ts.map +1 -0
- package/dist/collab/emitter.js +16 -0
- package/dist/collab/emitter.js.map +1 -0
- package/dist/collab/index.d.ts +7 -0
- package/dist/collab/index.d.ts.map +1 -0
- package/dist/collab/index.js +14 -0
- package/dist/collab/index.js.map +1 -0
- package/dist/collab/routes.d.ts +69 -0
- package/dist/collab/routes.d.ts.map +1 -0
- package/dist/collab/routes.js +98 -0
- package/dist/collab/routes.js.map +1 -0
- package/dist/collab/storage.d.ts +18 -0
- package/dist/collab/storage.d.ts.map +1 -0
- package/dist/collab/storage.js +94 -0
- package/dist/collab/storage.js.map +1 -0
- package/dist/collab/text-to-yjs.d.ts +23 -0
- package/dist/collab/text-to-yjs.d.ts.map +1 -0
- package/dist/collab/text-to-yjs.js +63 -0
- package/dist/collab/text-to-yjs.js.map +1 -0
- package/dist/collab/xml-ops.d.ts +20 -0
- package/dist/collab/xml-ops.d.ts.map +1 -0
- package/dist/collab/xml-ops.js +59 -0
- package/dist/collab/xml-ops.js.map +1 -0
- package/dist/collab/ydoc-manager.d.ts +52 -0
- package/dist/collab/ydoc-manager.d.ts.map +1 -0
- package/dist/collab/ydoc-manager.js +154 -0
- package/dist/collab/ydoc-manager.js.map +1 -0
- package/dist/db/client.d.ts +10 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +43 -2
- package/dist/db/client.js.map +1 -1
- package/dist/db/create-get-db.js.map +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts +9 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +45 -20
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/schema.d.ts +8 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +13 -2
- package/dist/db/schema.js.map +1 -1
- package/dist/deploy/build.js +795 -86
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/route-discovery.d.ts +22 -4
- package/dist/deploy/route-discovery.d.ts.map +1 -1
- package/dist/deploy/route-discovery.js +148 -35
- package/dist/deploy/route-discovery.js.map +1 -1
- package/dist/deploy/workspace-core.d.ts +28 -0
- package/dist/deploy/workspace-core.d.ts.map +1 -0
- package/dist/deploy/workspace-core.js +223 -0
- package/dist/deploy/workspace-core.js.map +1 -0
- package/dist/deploy/workspace-deploy.d.ts +11 -0
- package/dist/deploy/workspace-deploy.d.ts.map +1 -0
- package/dist/deploy/workspace-deploy.js +148 -0
- package/dist/deploy/workspace-deploy.js.map +1 -0
- package/dist/file-upload/builder.d.ts +11 -0
- package/dist/file-upload/builder.d.ts.map +1 -0
- package/dist/file-upload/builder.js +53 -0
- package/dist/file-upload/builder.js.map +1 -0
- package/dist/file-upload/index.d.ts +4 -0
- package/dist/file-upload/index.d.ts.map +1 -0
- package/dist/file-upload/index.js +3 -0
- package/dist/file-upload/index.js.map +1 -0
- package/dist/file-upload/registry.d.ts +23 -0
- package/dist/file-upload/registry.d.ts.map +1 -0
- package/dist/file-upload/registry.js +52 -0
- package/dist/file-upload/registry.js.map +1 -0
- package/dist/file-upload/types.d.ts +37 -0
- package/dist/file-upload/types.d.ts.map +1 -0
- package/dist/file-upload/types.js +10 -0
- package/dist/file-upload/types.js.map +1 -0
- package/dist/index.browser.d.ts +2 -0
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +4 -0
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/integrations/adapters/google-docs.d.ts +89 -0
- package/dist/integrations/adapters/google-docs.d.ts.map +1 -0
- package/dist/integrations/adapters/google-docs.js +261 -0
- package/dist/integrations/adapters/google-docs.js.map +1 -0
- package/dist/integrations/adapters/slack.d.ts +10 -0
- package/dist/integrations/adapters/slack.d.ts.map +1 -0
- package/dist/integrations/adapters/slack.js +249 -0
- package/dist/integrations/adapters/slack.js.map +1 -0
- package/dist/integrations/adapters/telegram.d.ts +12 -0
- package/dist/integrations/adapters/telegram.d.ts.map +1 -0
- package/dist/integrations/adapters/telegram.js +216 -0
- package/dist/integrations/adapters/telegram.js.map +1 -0
- package/dist/integrations/adapters/whatsapp.d.ts +14 -0
- package/dist/integrations/adapters/whatsapp.d.ts.map +1 -0
- package/dist/integrations/adapters/whatsapp.js +205 -0
- package/dist/integrations/adapters/whatsapp.js.map +1 -0
- package/dist/integrations/config-store.d.ts +24 -0
- package/dist/integrations/config-store.d.ts.map +1 -0
- package/dist/integrations/config-store.js +92 -0
- package/dist/integrations/config-store.js.map +1 -0
- package/dist/integrations/google-docs-poller.d.ts +54 -0
- package/dist/integrations/google-docs-poller.d.ts.map +1 -0
- package/dist/integrations/google-docs-poller.js +442 -0
- package/dist/integrations/google-docs-poller.js.map +1 -0
- package/dist/integrations/index.d.ts +10 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +13 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/plugin.d.ts +20 -0
- package/dist/integrations/plugin.d.ts.map +1 -0
- package/dist/integrations/plugin.js +260 -0
- package/dist/integrations/plugin.js.map +1 -0
- package/dist/integrations/thread-mapping-store.d.ts +25 -0
- package/dist/integrations/thread-mapping-store.d.ts.map +1 -0
- package/dist/integrations/thread-mapping-store.js +95 -0
- package/dist/integrations/thread-mapping-store.js.map +1 -0
- package/dist/integrations/types.d.ts +144 -0
- package/dist/integrations/types.d.ts.map +1 -0
- package/dist/integrations/types.js +2 -0
- package/dist/integrations/types.js.map +1 -0
- package/dist/integrations/webhook-handler.d.ts +40 -0
- package/dist/integrations/webhook-handler.d.ts.map +1 -0
- package/dist/integrations/webhook-handler.js +220 -0
- package/dist/integrations/webhook-handler.js.map +1 -0
- package/dist/jobs/cron.d.ts +14 -0
- package/dist/jobs/cron.d.ts.map +1 -0
- package/dist/jobs/cron.js +100 -0
- package/dist/jobs/cron.js.map +1 -0
- package/dist/jobs/index.d.ts +4 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +4 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/jobs/scheduler.d.ts +32 -0
- package/dist/jobs/scheduler.d.ts.map +1 -0
- package/dist/jobs/scheduler.js +226 -0
- package/dist/jobs/scheduler.js.map +1 -0
- package/dist/jobs/tools.d.ts +3 -0
- package/dist/jobs/tools.d.ts.map +1 -0
- package/dist/jobs/tools.js +209 -0
- package/dist/jobs/tools.js.map +1 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +2 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +26 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +182 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp-client/config.d.ts +46 -0
- package/dist/mcp-client/config.d.ts.map +1 -0
- package/dist/mcp-client/config.js +152 -0
- package/dist/mcp-client/config.js.map +1 -0
- package/dist/mcp-client/index.d.ts +17 -0
- package/dist/mcp-client/index.d.ts.map +1 -0
- package/dist/mcp-client/index.js +53 -0
- package/dist/mcp-client/index.js.map +1 -0
- package/dist/mcp-client/manager.d.ts +76 -0
- package/dist/mcp-client/manager.d.ts.map +1 -0
- package/dist/mcp-client/manager.js +212 -0
- package/dist/mcp-client/manager.js.map +1 -0
- package/dist/oauth-tokens/index.d.ts +1 -1
- package/dist/oauth-tokens/index.d.ts.map +1 -1
- package/dist/oauth-tokens/index.js +1 -1
- package/dist/oauth-tokens/index.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts +5 -0
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +33 -8
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts +10 -0
- package/dist/onboarding/default-steps.d.ts.map +1 -0
- package/dist/onboarding/default-steps.js +164 -0
- package/dist/onboarding/default-steps.js.map +1 -0
- package/dist/onboarding/index.d.ts +12 -0
- package/dist/onboarding/index.d.ts.map +1 -0
- package/dist/onboarding/index.js +11 -0
- package/dist/onboarding/index.js.map +1 -0
- package/dist/onboarding/plugin.d.ts +19 -0
- package/dist/onboarding/plugin.d.ts.map +1 -0
- package/dist/onboarding/plugin.js +147 -0
- package/dist/onboarding/plugin.js.map +1 -0
- package/dist/onboarding/registry.d.ts +24 -0
- package/dist/onboarding/registry.d.ts.map +1 -0
- package/dist/onboarding/registry.js +40 -0
- package/dist/onboarding/registry.js.map +1 -0
- package/dist/onboarding/types.d.ts +71 -0
- package/dist/onboarding/types.d.ts.map +1 -0
- package/dist/onboarding/types.js +10 -0
- package/dist/onboarding/types.js.map +1 -0
- package/dist/org/context.d.ts +11 -0
- package/dist/org/context.d.ts.map +1 -0
- package/dist/org/context.js +61 -0
- package/dist/org/context.js.map +1 -0
- package/dist/org/handlers.d.ts +66 -0
- package/dist/org/handlers.d.ts.map +1 -0
- package/dist/org/handlers.js +306 -0
- package/dist/org/handlers.js.map +1 -0
- package/dist/org/index.d.ts +7 -0
- package/dist/org/index.d.ts.map +1 -0
- package/dist/org/index.js +11 -0
- package/dist/org/index.js.map +1 -0
- package/dist/org/migrations.d.ts +10 -0
- package/dist/org/migrations.d.ts.map +1 -0
- package/dist/org/migrations.js +39 -0
- package/dist/org/migrations.js.map +1 -0
- package/dist/org/plugin.d.ts +26 -0
- package/dist/org/plugin.d.ts.map +1 -0
- package/dist/org/plugin.js +94 -0
- package/dist/org/plugin.js.map +1 -0
- package/dist/org/schema.d.ts +301 -0
- package/dist/org/schema.d.ts.map +1 -0
- package/dist/org/schema.js +23 -0
- package/dist/org/schema.js.map +1 -0
- package/dist/org/types.d.ts +42 -0
- package/dist/org/types.d.ts.map +1 -0
- package/dist/org/types.js +5 -0
- package/dist/org/types.js.map +1 -0
- package/dist/resources/agents.d.ts +4 -0
- package/dist/resources/agents.d.ts.map +1 -0
- package/dist/resources/agents.js +44 -0
- package/dist/resources/agents.js.map +1 -0
- package/dist/resources/handlers.d.ts +27 -1
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +121 -11
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/metadata.d.ts +48 -0
- package/dist/resources/metadata.d.ts.map +1 -0
- package/dist/resources/metadata.js +150 -0
- package/dist/resources/metadata.js.map +1 -0
- package/dist/resources/script-helpers.d.ts.map +1 -1
- package/dist/resources/script-helpers.js +3 -2
- package/dist/resources/script-helpers.js.map +1 -1
- package/dist/resources/store.d.ts +5 -0
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +76 -17
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.d.ts +7 -0
- package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -0
- package/dist/scripts/agent-engines/list-agent-engines.js +42 -0
- package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -0
- package/dist/scripts/agent-engines/set-agent-engine.d.ts +7 -0
- package/dist/scripts/agent-engines/set-agent-engine.d.ts.map +1 -0
- package/dist/scripts/agent-engines/set-agent-engine.js +57 -0
- package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -0
- package/dist/scripts/agent-engines/test-agent-engine.d.ts +7 -0
- package/dist/scripts/agent-engines/test-agent-engine.d.ts.map +1 -0
- package/dist/scripts/agent-engines/test-agent-engine.js +102 -0
- package/dist/scripts/agent-engines/test-agent-engine.js.map +1 -0
- package/dist/scripts/call-agent.d.ts +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +13 -8
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/scripts/chat/index.d.ts +2 -0
- package/dist/scripts/chat/index.d.ts.map +1 -0
- package/dist/scripts/chat/index.js +5 -0
- package/dist/scripts/chat/index.js.map +1 -0
- package/dist/scripts/chat/open-chat.d.ts +11 -0
- package/dist/scripts/chat/open-chat.d.ts.map +1 -0
- package/dist/scripts/chat/open-chat.js +48 -0
- package/dist/scripts/chat/open-chat.js.map +1 -0
- package/dist/scripts/chat/search-chats.d.ts +10 -0
- package/dist/scripts/chat/search-chats.d.ts.map +1 -0
- package/dist/scripts/chat/search-chats.js +90 -0
- package/dist/scripts/chat/search-chats.js.map +1 -0
- package/dist/scripts/core-scripts.d.ts.map +1 -1
- package/dist/scripts/core-scripts.js +4 -0
- package/dist/scripts/core-scripts.js.map +1 -1
- package/dist/scripts/db/check-scoping.d.ts +14 -0
- package/dist/scripts/db/check-scoping.d.ts.map +1 -0
- package/dist/scripts/db/check-scoping.js +174 -0
- package/dist/scripts/db/check-scoping.js.map +1 -0
- package/dist/scripts/db/exec.d.ts +3 -2
- package/dist/scripts/db/exec.d.ts.map +1 -1
- package/dist/scripts/db/exec.js +35 -19
- 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/patch.d.ts +50 -0
- package/dist/scripts/db/patch.d.ts.map +1 -0
- package/dist/scripts/db/patch.js +392 -0
- package/dist/scripts/db/patch.js.map +1 -0
- package/dist/scripts/db/scoping.d.ts +8 -2
- package/dist/scripts/db/scoping.d.ts.map +1 -1
- package/dist/scripts/db/scoping.js +66 -47
- package/dist/scripts/db/scoping.js.map +1 -1
- package/dist/scripts/dev/index.d.ts.map +1 -1
- package/dist/scripts/dev/index.js +64 -1
- package/dist/scripts/dev/index.js.map +1 -1
- package/dist/scripts/docs/index.d.ts +2 -0
- package/dist/scripts/docs/index.d.ts.map +1 -0
- package/dist/scripts/docs/index.js +4 -0
- package/dist/scripts/docs/index.js.map +1 -0
- package/dist/scripts/docs/search.d.ts +13 -0
- package/dist/scripts/docs/search.d.ts.map +1 -0
- package/dist/scripts/docs/search.js +130 -0
- package/dist/scripts/docs/search.js.map +1 -0
- package/dist/scripts/parse-args.d.ts +14 -0
- package/dist/scripts/parse-args.d.ts.map +1 -0
- package/dist/scripts/parse-args.js +45 -0
- package/dist/scripts/parse-args.js.map +1 -0
- package/dist/scripts/resources/delete-memory.d.ts +7 -0
- package/dist/scripts/resources/delete-memory.d.ts.map +1 -0
- package/dist/scripts/resources/delete-memory.js +49 -0
- package/dist/scripts/resources/delete-memory.js.map +1 -0
- 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/index.d.ts.map +1 -1
- package/dist/scripts/resources/index.js +2 -0
- package/dist/scripts/resources/index.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 +9 -0
- package/dist/scripts/resources/save-memory.d.ts.map +1 -0
- package/dist/scripts/resources/save-memory.js +78 -0
- package/dist/scripts/resources/save-memory.js.map +1 -0
- 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/scripts/runner.d.ts.map +1 -1
- package/dist/scripts/runner.js +10 -2
- package/dist/scripts/runner.js.map +1 -1
- package/dist/scripts/utils.d.ts +9 -8
- package/dist/scripts/utils.d.ts.map +1 -1
- package/dist/scripts/utils.js +40 -35
- package/dist/scripts/utils.js.map +1 -1
- package/dist/server/action-discovery.d.ts +5 -0
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +132 -33
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts +15 -0
- package/dist/server/action-routes.d.ts.map +1 -0
- package/dist/server/action-routes.js +111 -0
- package/dist/server/action-routes.js.map +1 -0
- package/dist/server/agent-chat-plugin.d.ts +23 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +1474 -266
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts +8 -3
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +57 -8
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agent-teams.d.ts +70 -0
- package/dist/server/agent-teams.d.ts.map +1 -0
- package/dist/server/agent-teams.js +368 -0
- package/dist/server/agent-teams.js.map +1 -0
- package/dist/server/agents-bundle.d.ts +115 -0
- package/dist/server/agents-bundle.d.ts.map +1 -0
- package/dist/server/agents-bundle.js +275 -0
- package/dist/server/agents-bundle.js.map +1 -0
- package/dist/server/auth-plugin.d.ts +3 -3
- package/dist/server/auth-plugin.d.ts.map +1 -1
- package/dist/server/auth-plugin.js +9 -10
- package/dist/server/auth-plugin.js.map +1 -1
- package/dist/server/auth.d.ts +55 -33
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +640 -610
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +72 -0
- package/dist/server/better-auth-instance.d.ts.map +1 -0
- package/dist/server/better-auth-instance.js +340 -0
- package/dist/server/better-auth-instance.js.map +1 -0
- package/dist/server/builder-browser.d.ts +40 -0
- package/dist/server/builder-browser.d.ts.map +1 -0
- package/dist/server/builder-browser.js +166 -0
- package/dist/server/builder-browser.js.map +1 -0
- package/dist/server/collab-plugin.d.ts +29 -0
- package/dist/server/collab-plugin.d.ts.map +1 -0
- package/dist/server/collab-plugin.js +85 -0
- package/dist/server/collab-plugin.js.map +1 -0
- package/dist/server/core-routes-plugin.d.ts +0 -3
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +248 -32
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/create-server.d.ts +1 -1
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +39 -16
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/credential-provider.d.ts +37 -0
- package/dist/server/credential-provider.d.ts.map +1 -0
- package/dist/server/credential-provider.js +49 -0
- package/dist/server/credential-provider.js.map +1 -0
- package/dist/server/framework-request-handler.d.ts +47 -0
- package/dist/server/framework-request-handler.d.ts.map +1 -0
- package/dist/server/framework-request-handler.js +207 -0
- package/dist/server/framework-request-handler.js.map +1 -0
- package/dist/server/google-auth-plugin.d.ts +4 -0
- package/dist/server/google-auth-plugin.d.ts.map +1 -1
- package/dist/server/google-auth-plugin.js +14 -13
- package/dist/server/google-auth-plugin.js.map +1 -1
- package/dist/server/google-oauth.d.ts +3 -3
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +51 -24
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/h3-helpers.d.ts +23 -0
- package/dist/server/h3-helpers.d.ts.map +1 -0
- package/dist/server/h3-helpers.js +37 -0
- package/dist/server/h3-helpers.js.map +1 -0
- package/dist/server/index.d.ts +12 -4
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +15 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/local-migration.d.ts +32 -0
- package/dist/server/local-migration.d.ts.map +1 -0
- package/dist/server/local-migration.js +205 -0
- package/dist/server/local-migration.js.map +1 -0
- package/dist/server/oauth-helpers.d.ts +5 -6
- package/dist/server/oauth-helpers.d.ts.map +1 -1
- package/dist/server/oauth-helpers.js +10 -11
- package/dist/server/oauth-helpers.js.map +1 -1
- package/dist/server/onboarding-html.d.ts +24 -0
- package/dist/server/onboarding-html.d.ts.map +1 -0
- package/dist/server/onboarding-html.js +438 -0
- package/dist/server/onboarding-html.js.map +1 -0
- package/dist/server/poll.d.ts +7 -2
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +48 -1
- package/dist/server/poll.js.map +1 -1
- package/dist/server/request-context.d.ts +20 -0
- package/dist/server/request-context.d.ts.map +1 -0
- package/dist/server/request-context.js +41 -0
- package/dist/server/request-context.js.map +1 -0
- package/dist/server/resources-plugin.d.ts.map +1 -1
- package/dist/server/resources-plugin.js +4 -3
- package/dist/server/resources-plugin.js.map +1 -1
- package/dist/server/schema-prompt.d.ts +16 -0
- package/dist/server/schema-prompt.d.ts.map +1 -0
- package/dist/server/schema-prompt.js +275 -0
- package/dist/server/schema-prompt.js.map +1 -0
- package/dist/server/sse.d.ts +3 -20
- package/dist/server/sse.d.ts.map +1 -1
- package/dist/server/sse.js +1 -29
- package/dist/server/sse.js.map +1 -1
- package/dist/server/ssr-handler.d.ts +6 -0
- package/dist/server/ssr-handler.d.ts.map +1 -0
- package/dist/server/ssr-handler.js +55 -0
- package/dist/server/ssr-handler.js.map +1 -0
- package/dist/settings/handlers.d.ts +3 -3
- package/dist/settings/handlers.d.ts.map +1 -1
- package/dist/settings/handlers.js +2 -1
- package/dist/settings/handlers.js.map +1 -1
- package/dist/settings/index.d.ts +1 -0
- package/dist/settings/index.d.ts.map +1 -1
- package/dist/settings/index.js +2 -0
- package/dist/settings/index.js.map +1 -1
- package/dist/settings/org-settings.d.ts +22 -0
- package/dist/settings/org-settings.d.ts.map +1 -0
- package/dist/settings/org-settings.js +45 -0
- package/dist/settings/org-settings.js.map +1 -0
- package/dist/shared/agent-chat.d.ts +5 -5
- package/dist/shared/agent-chat.d.ts.map +1 -1
- package/dist/shared/agent-chat.js +8 -8
- package/dist/shared/agent-chat.js.map +1 -1
- package/dist/shared/agent-env.d.ts +1 -1
- package/dist/shared/agent-env.js +1 -1
- package/dist/shared/runtime.d.ts +14 -0
- package/dist/shared/runtime.d.ts.map +1 -0
- package/dist/shared/runtime.js +25 -0
- package/dist/shared/runtime.js.map +1 -0
- package/dist/templates/default/.agents/skills/actions/SKILL.md +143 -0
- package/dist/templates/default/.agents/skills/agent-engines/SKILL.md +127 -0
- package/dist/templates/default/.agents/skills/capture-learnings/SKILL.md +50 -0
- package/dist/templates/default/.agents/skills/create-skill/SKILL.md +167 -0
- package/dist/templates/default/.agents/skills/delegate-to-agent/SKILL.md +90 -0
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +69 -0
- package/dist/templates/default/.agents/skills/real-time-collab/SKILL.md +183 -0
- package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +112 -0
- package/dist/templates/default/.agents/skills/security/SKILL.md +213 -0
- package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +79 -0
- package/{src/templates/default/.agents/skills/files-as-database → dist/templates/default/.agents/skills/storing-data}/SKILL.md +7 -1
- package/dist/templates/default/.claude/settings.json +100 -0
- package/dist/templates/default/.env.example +5 -0
- package/dist/templates/default/.prettierrc +5 -0
- package/dist/templates/default/AGENTS.md +110 -0
- package/dist/templates/default/DEVELOPING.md +117 -0
- package/dist/templates/default/_gitignore +38 -0
- package/dist/templates/default/actions/hello.ts +20 -0
- package/dist/templates/default/actions/navigate.ts +53 -0
- package/dist/templates/default/actions/run.ts +2 -0
- package/dist/templates/default/actions/view-screen.ts +39 -0
- package/dist/templates/default/app/entry.client.tsx +4 -0
- package/dist/templates/default/app/entry.server.tsx +56 -0
- package/dist/templates/default/app/global.css +95 -0
- package/dist/templates/default/app/lib/utils.ts +1 -0
- package/dist/templates/default/app/root.tsx +110 -0
- package/dist/templates/default/app/routes/_index.tsx +62 -0
- package/dist/templates/default/app/routes.ts +4 -0
- package/dist/templates/default/app/vite-env.d.ts +6 -0
- package/dist/templates/default/components.json +20 -0
- package/dist/templates/default/data/.gitkeep +0 -0
- package/dist/templates/default/data/sync-config.json +1 -0
- package/dist/templates/default/learnings.defaults.md +5 -0
- package/dist/templates/default/learnings.md +0 -0
- package/dist/templates/default/package.json +46 -0
- package/dist/templates/default/postcss.config.js +6 -0
- package/dist/templates/default/public/icon-180.svg +4 -0
- package/dist/templates/default/public/icon-192.svg +4 -0
- package/dist/templates/default/public/icon-512.svg +4 -0
- package/dist/templates/default/public/manifest.json +13 -0
- package/dist/templates/default/react-router.config.ts +6 -0
- package/dist/templates/default/server/middleware/auth.ts +15 -0
- package/dist/templates/default/server/plugins/.gitkeep +0 -0
- package/dist/templates/default/server/routes/[...page].get.ts +5 -0
- package/dist/templates/default/server/routes/api/hello.get.ts +5 -0
- package/dist/templates/default/shared/api.ts +6 -0
- package/dist/templates/default/ssr-entry.ts +20 -0
- package/dist/templates/default/tailwind.config.ts +7 -0
- package/dist/templates/default/tsconfig.json +11 -0
- package/dist/templates/default/vite.config.ts +6 -0
- package/dist/templates/workspace-core/AGENTS.md +62 -0
- package/dist/templates/workspace-core/actions/company-directory.ts +38 -0
- package/dist/templates/workspace-core/package.json +39 -0
- package/dist/templates/workspace-core/skills/company-policies/SKILL.md +42 -0
- package/dist/templates/workspace-core/src/client/AuthenticatedLayout.tsx +37 -0
- package/dist/templates/workspace-core/src/client/index.ts +26 -0
- package/dist/templates/workspace-core/src/credentials.ts +29 -0
- package/dist/templates/workspace-core/src/index.ts +21 -0
- package/dist/templates/workspace-core/src/server/agent-chat-plugin.ts +30 -0
- package/dist/templates/workspace-core/src/server/auth-plugin.ts +35 -0
- package/dist/templates/workspace-core/src/server/index.ts +22 -0
- package/dist/templates/workspace-core/tailwind.preset.ts +34 -0
- package/dist/templates/workspace-core/tsconfig.json +9 -0
- package/dist/templates/workspace-root/.env.example +37 -0
- package/dist/templates/workspace-root/README.md +62 -0
- package/dist/templates/workspace-root/_gitignore +23 -0
- package/dist/templates/workspace-root/package.json +18 -0
- package/dist/templates/workspace-root/pnpm-workspace.yaml +3 -0
- package/dist/templates/workspace-root/tsconfig.base.json +21 -0
- package/dist/terminal/cli-registry.d.ts +1 -1
- package/dist/terminal/cli-registry.d.ts.map +1 -1
- package/dist/terminal/cli-registry.js +7 -7
- package/dist/terminal/cli-registry.js.map +1 -1
- package/dist/terminal/pty-server.d.ts +1 -1
- package/dist/terminal/pty-server.d.ts.map +1 -1
- package/dist/terminal/pty-server.js +34 -12
- package/dist/terminal/pty-server.js.map +1 -1
- package/dist/terminal/terminal-plugin.d.ts +0 -9
- package/dist/terminal/terminal-plugin.d.ts.map +1 -1
- package/dist/terminal/terminal-plugin.js +57 -14
- package/dist/terminal/terminal-plugin.js.map +1 -1
- package/dist/usage/store.d.ts +29 -0
- package/dist/usage/store.d.ts.map +1 -0
- package/dist/usage/store.js +102 -0
- package/dist/usage/store.js.map +1 -0
- package/dist/vite/action-types-plugin.d.ts +13 -0
- package/dist/vite/action-types-plugin.d.ts.map +1 -0
- package/dist/vite/action-types-plugin.js +132 -0
- package/dist/vite/action-types-plugin.js.map +1 -0
- package/dist/vite/agents-bundle-plugin.d.ts +3 -0
- package/dist/vite/agents-bundle-plugin.d.ts.map +1 -0
- package/dist/vite/agents-bundle-plugin.js +137 -0
- package/dist/vite/agents-bundle-plugin.js.map +1 -0
- package/dist/vite/client.d.ts +21 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +297 -37
- package/dist/vite/client.js.map +1 -1
- package/dist/vite/index.d.ts +2 -1
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +2 -1
- package/dist/vite/index.js.map +1 -1
- package/docs/content/a2a-protocol.md +223 -0
- package/docs/content/actions.md +129 -0
- package/docs/content/agent-mentions.md +171 -0
- package/docs/content/authentication.md +155 -0
- package/docs/content/cli-adapters.md +244 -0
- package/docs/content/client.md +175 -0
- package/docs/content/context-awareness.md +168 -0
- package/docs/content/creating-templates.md +311 -0
- package/docs/content/database.md +82 -0
- package/docs/content/deployment.md +180 -0
- package/docs/content/enterprise-workspace.md +235 -0
- package/docs/content/faq.md +101 -0
- package/docs/content/file-uploads.md +102 -0
- package/docs/content/frames.md +47 -0
- package/docs/content/getting-started.md +104 -0
- package/docs/content/integrations.md +198 -0
- package/docs/content/key-concepts.md +246 -0
- package/docs/content/mcp-clients.md +110 -0
- package/docs/content/mcp-protocol.md +168 -0
- package/docs/content/onboarding.md +107 -0
- package/docs/content/real-time-collaboration.md +185 -0
- package/docs/content/resources.md +277 -0
- package/docs/content/security.md +158 -0
- package/docs/content/server.md +200 -0
- package/docs/content/skills-guide.md +107 -0
- package/docs/content/what-is-agent-native.md +100 -0
- package/docs/content/workspace-management.md +224 -0
- package/package.json +78 -20
- package/src/templates/default/.agents/skills/actions/SKILL.md +14 -7
- package/src/templates/default/.agents/skills/agent-engines/SKILL.md +127 -0
- package/src/templates/default/.agents/skills/real-time-collab/SKILL.md +183 -0
- package/src/templates/default/.agents/skills/security/SKILL.md +213 -0
- package/src/templates/default/.agents/skills/storing-data/SKILL.md +116 -0
- package/src/templates/default/.claude/settings.json +13 -0
- package/src/templates/default/AGENTS.md +25 -9
- package/src/templates/default/_gitignore +1 -0
- package/src/templates/default/actions/view-screen.ts +1 -1
- package/src/templates/default/app/root.tsx +4 -1
- package/src/templates/default/package.json +2 -2
- package/src/templates/default/server/middleware/auth.ts +15 -0
- package/src/templates/default/server/routes/[...page].get.ts +2 -9
- package/src/templates/default/ssr-entry.ts +20 -0
- package/src/templates/workspace-core/AGENTS.md +62 -0
- package/src/templates/workspace-core/actions/company-directory.ts +38 -0
- package/src/templates/workspace-core/package.json +39 -0
- package/src/templates/workspace-core/skills/company-policies/SKILL.md +42 -0
- package/src/templates/workspace-core/src/client/AuthenticatedLayout.tsx +37 -0
- package/src/templates/workspace-core/src/client/index.ts +26 -0
- package/src/templates/workspace-core/src/credentials.ts +29 -0
- package/src/templates/workspace-core/src/index.ts +21 -0
- package/src/templates/workspace-core/src/server/agent-chat-plugin.ts +30 -0
- package/src/templates/workspace-core/src/server/auth-plugin.ts +35 -0
- package/src/templates/workspace-core/src/server/index.ts +22 -0
- package/src/templates/workspace-core/tailwind.preset.ts +34 -0
- package/src/templates/workspace-core/tsconfig.json +9 -0
- package/src/templates/workspace-root/.env.example +37 -0
- package/src/templates/workspace-root/README.md +62 -0
- package/src/templates/workspace-root/_gitignore +23 -0
- package/src/templates/workspace-root/package.json +18 -0
- package/src/templates/workspace-root/pnpm-workspace.yaml +3 -0
- package/src/templates/workspace-root/tsconfig.base.json +21 -0
- package/dist/adapters/convex/adapter.d.ts +0 -24
- package/dist/adapters/convex/adapter.d.ts.map +0 -1
- package/dist/adapters/convex/adapter.js +0 -125
- package/dist/adapters/convex/adapter.js.map +0 -1
- package/dist/adapters/convex/index.d.ts +0 -4
- package/dist/adapters/convex/index.d.ts.map +0 -1
- package/dist/adapters/convex/index.js +0 -3
- package/dist/adapters/convex/index.js.map +0 -1
- package/dist/adapters/drizzle/adapter.d.ts +0 -36
- package/dist/adapters/drizzle/adapter.d.ts.map +0 -1
- package/dist/adapters/drizzle/adapter.js +0 -210
- package/dist/adapters/drizzle/adapter.js.map +0 -1
- package/dist/adapters/drizzle/index.d.ts +0 -3
- package/dist/adapters/drizzle/index.d.ts.map +0 -1
- package/dist/adapters/drizzle/index.js +0 -3
- package/dist/adapters/drizzle/index.js.map +0 -1
- package/dist/adapters/drizzle/schema.d.ts +0 -146
- package/dist/adapters/drizzle/schema.d.ts.map +0 -1
- package/dist/adapters/drizzle/schema.js +0 -20
- package/dist/adapters/drizzle/schema.js.map +0 -1
- package/dist/adapters/firestore/adapter.d.ts +0 -48
- package/dist/adapters/firestore/adapter.d.ts.map +0 -1
- package/dist/adapters/firestore/adapter.js +0 -62
- package/dist/adapters/firestore/adapter.js.map +0 -1
- package/dist/adapters/firestore/index.d.ts +0 -4
- package/dist/adapters/firestore/index.d.ts.map +0 -1
- package/dist/adapters/firestore/index.js +0 -3
- package/dist/adapters/firestore/index.js.map +0 -1
- package/dist/adapters/supabase/adapter.d.ts +0 -43
- package/dist/adapters/supabase/adapter.d.ts.map +0 -1
- package/dist/adapters/supabase/adapter.js +0 -137
- package/dist/adapters/supabase/adapter.js.map +0 -1
- package/dist/adapters/supabase/index.d.ts +0 -3
- package/dist/adapters/supabase/index.d.ts.map +0 -1
- package/dist/adapters/supabase/index.js +0 -3
- package/dist/adapters/supabase/index.js.map +0 -1
- package/dist/adapters/sync/config.d.ts +0 -40
- package/dist/adapters/sync/config.d.ts.map +0 -1
- package/dist/adapters/sync/config.js +0 -209
- package/dist/adapters/sync/config.js.map +0 -1
- package/dist/adapters/sync/create-file-sync.d.ts +0 -32
- package/dist/adapters/sync/create-file-sync.d.ts.map +0 -1
- package/dist/adapters/sync/create-file-sync.js +0 -218
- package/dist/adapters/sync/create-file-sync.js.map +0 -1
- package/dist/adapters/sync/file-sync.d.ts +0 -94
- package/dist/adapters/sync/file-sync.d.ts.map +0 -1
- package/dist/adapters/sync/file-sync.js +0 -671
- package/dist/adapters/sync/file-sync.js.map +0 -1
- package/dist/adapters/sync/index.d.ts +0 -6
- package/dist/adapters/sync/index.d.ts.map +0 -1
- package/dist/adapters/sync/index.js +0 -6
- package/dist/adapters/sync/index.js.map +0 -1
- package/dist/adapters/sync/merge.d.ts +0 -21
- package/dist/adapters/sync/merge.d.ts.map +0 -1
- package/dist/adapters/sync/merge.js +0 -132
- package/dist/adapters/sync/merge.js.map +0 -1
- package/dist/adapters/sync/types.d.ts +0 -62
- package/dist/adapters/sync/types.d.ts.map +0 -1
- package/dist/adapters/sync/types.js +0 -23
- package/dist/adapters/sync/types.js.map +0 -1
- package/dist/client/harness.d.ts +0 -48
- package/dist/client/harness.d.ts.map +0 -1
- package/dist/client/harness.js.map +0 -1
- package/dist/client/use-file-sync-status.d.ts +0 -21
- package/dist/client/use-file-sync-status.d.ts.map +0 -1
- package/dist/client/use-file-sync-status.js +0 -65
- package/dist/client/use-file-sync-status.js.map +0 -1
- package/dist/server/default-watcher.d.ts +0 -23
- package/dist/server/default-watcher.d.ts.map +0 -1
- package/dist/server/default-watcher.js +0 -57
- package/dist/server/default-watcher.js.map +0 -1
- package/dist/server/file-sync-plugin.d.ts +0 -7
- package/dist/server/file-sync-plugin.d.ts.map +0 -1
- package/dist/server/file-sync-plugin.js +0 -38
- package/dist/server/file-sync-plugin.js.map +0 -1
- package/dist/vite/dev-api-server.d.ts +0 -10
- package/dist/vite/dev-api-server.d.ts.map +0 -1
- package/dist/vite/dev-api-server.js +0 -243
- package/dist/vite/dev-api-server.js.map +0 -1
- /package/{src/templates/default/application-state/.gitkeep → dist/templates/default/.ignore} +0 -0
package/dist/server/auth.js
CHANGED
|
@@ -1,54 +1,97 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
-
import
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
// Lazy fs — loaded via dynamic import() on first use.
|
|
4
|
+
// Avoids static require() which crashes on CF Workers.
|
|
5
|
+
let _fs;
|
|
6
|
+
async function getFs() {
|
|
7
|
+
if (!_fs) {
|
|
8
|
+
_fs = await import("node:fs");
|
|
9
|
+
}
|
|
10
|
+
return _fs;
|
|
11
|
+
}
|
|
12
|
+
import { defineEventHandler, getMethod, getQuery, setResponseHeader, setResponseStatus, getCookie, setCookie, deleteCookie, } from "h3";
|
|
13
|
+
// In h3 v2, `event.req` IS the web Request — no conversion needed.
|
|
14
|
+
function toWebRequest(event) {
|
|
15
|
+
return event.req;
|
|
16
|
+
}
|
|
3
17
|
import { getDbExec, isPostgres, intType } from "../db/client.js";
|
|
18
|
+
import { getBetterAuth, getBetterAuthSync } from "./better-auth-instance.js";
|
|
19
|
+
import { getOnboardingHtml } from "./onboarding-html.js";
|
|
20
|
+
import { migrateLocalUserData } from "./local-migration.js";
|
|
21
|
+
import { readBody } from "../server/h3-helpers.js";
|
|
4
22
|
// ---------------------------------------------------------------------------
|
|
5
23
|
// Constants
|
|
6
24
|
// ---------------------------------------------------------------------------
|
|
7
25
|
const COOKIE_NAME = "an_session";
|
|
8
26
|
const DEFAULT_MAX_AGE = 60 * 60 * 24 * 30; // 30 days
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
27
|
+
const LOCAL_MODE_MARKER_PATH = path.resolve(process.cwd(), ".agent-native", "auth-mode");
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// AUTH_MODE detection
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
/**
|
|
32
|
+
* Check if the app is in local-only mode (no auth).
|
|
33
|
+
*
|
|
34
|
+
* Returns true when AUTH_MODE=local is explicitly set or when the dev
|
|
35
|
+
* onboarding flow has enabled local mode for the current workspace via
|
|
36
|
+
* a runtime marker file.
|
|
37
|
+
*
|
|
38
|
+
* Local mode is an explicit escape hatch for when you want to guarantee
|
|
39
|
+
* no auth is used. In development, getSession() also falls back to
|
|
40
|
+
* local@localhost automatically if no other auth method succeeds, so
|
|
41
|
+
* apps are always usable without configuration in dev.
|
|
42
|
+
*/
|
|
43
|
+
async function isLocalModeEnabled() {
|
|
44
|
+
if (process.env.AUTH_MODE === "local")
|
|
45
|
+
return true;
|
|
46
|
+
try {
|
|
47
|
+
const fs = await getFs();
|
|
48
|
+
const mode = fs.readFileSync(LOCAL_MODE_MARKER_PATH, "utf-8").trim();
|
|
49
|
+
return mode === "local";
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return false;
|
|
18
53
|
}
|
|
19
|
-
}, 5 * 60 * 1000).unref();
|
|
20
|
-
function getClientIp(event) {
|
|
21
|
-
return getRequestIP(event, { xForwardedFor: true }) ?? "unknown";
|
|
22
54
|
}
|
|
23
55
|
/**
|
|
24
|
-
* Check
|
|
25
|
-
*
|
|
56
|
+
* Check if we're in a development/test environment.
|
|
57
|
+
* Used for cookie security settings, not for auth bypass.
|
|
26
58
|
*/
|
|
27
|
-
function
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
59
|
+
function isDevEnvironment() {
|
|
60
|
+
const env = process.env.NODE_ENV;
|
|
61
|
+
return env === "development" || env === "test";
|
|
62
|
+
}
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// ACCESS_TOKEN resolution
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
function getAccessTokens() {
|
|
67
|
+
const single = process.env.ACCESS_TOKEN;
|
|
68
|
+
const multi = process.env.ACCESS_TOKENS;
|
|
69
|
+
const tokens = [];
|
|
70
|
+
if (single)
|
|
71
|
+
tokens.push(single);
|
|
72
|
+
if (multi) {
|
|
73
|
+
for (const t of multi.split(",")) {
|
|
74
|
+
const trimmed = t.trim();
|
|
75
|
+
if (trimmed && !tokens.includes(trimmed))
|
|
76
|
+
tokens.push(trimmed);
|
|
77
|
+
}
|
|
43
78
|
}
|
|
44
|
-
return
|
|
79
|
+
return tokens;
|
|
45
80
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
81
|
+
function safeTokenMatch(input, tokens) {
|
|
82
|
+
const inputBuf = Buffer.from(input);
|
|
83
|
+
for (const token of tokens) {
|
|
84
|
+
const tokenBuf = Buffer.from(token);
|
|
85
|
+
if (inputBuf.length === tokenBuf.length &&
|
|
86
|
+
crypto.timingSafeEqual(inputBuf, tokenBuf)) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
49
91
|
}
|
|
50
92
|
// ---------------------------------------------------------------------------
|
|
51
|
-
//
|
|
93
|
+
// Legacy session store — kept for backward compat (addSession/getSessionEmail)
|
|
94
|
+
// Used by google-oauth.ts for mobile deep linking session creation.
|
|
52
95
|
// ---------------------------------------------------------------------------
|
|
53
96
|
let _sessionInitPromise;
|
|
54
97
|
let sessionMaxAge = DEFAULT_MAX_AGE;
|
|
@@ -63,29 +106,19 @@ async function ensureSessionTable() {
|
|
|
63
106
|
created_at ${intType()} NOT NULL
|
|
64
107
|
)
|
|
65
108
|
`);
|
|
66
|
-
// Migration: add email column to existing tables that lack it
|
|
67
109
|
try {
|
|
68
110
|
await client.execute(`ALTER TABLE sessions ADD COLUMN email TEXT`);
|
|
69
111
|
}
|
|
70
112
|
catch {
|
|
71
|
-
// Column already exists
|
|
113
|
+
// Column already exists
|
|
72
114
|
}
|
|
73
115
|
})();
|
|
74
116
|
}
|
|
75
117
|
return _sessionInitPromise;
|
|
76
118
|
}
|
|
77
|
-
async function pruneExpiredSessions() {
|
|
78
|
-
await ensureSessionTable();
|
|
79
|
-
const client = getDbExec();
|
|
80
|
-
const cutoff = Date.now() - sessionMaxAge * 1000;
|
|
81
|
-
await client.execute({
|
|
82
|
-
sql: `DELETE FROM sessions WHERE created_at < ?`,
|
|
83
|
-
args: [cutoff],
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
119
|
/**
|
|
87
|
-
* Create a new session
|
|
88
|
-
*
|
|
120
|
+
* Create a new session in the legacy sessions table.
|
|
121
|
+
* Used by google-oauth.ts for mobile deep linking.
|
|
89
122
|
*/
|
|
90
123
|
export async function addSession(token, email) {
|
|
91
124
|
await ensureSessionTable();
|
|
@@ -97,7 +130,7 @@ export async function addSession(token, email) {
|
|
|
97
130
|
args: [token, email ?? null, Date.now()],
|
|
98
131
|
});
|
|
99
132
|
}
|
|
100
|
-
/** Remove a session
|
|
133
|
+
/** Remove a session from the legacy sessions table. */
|
|
101
134
|
export async function removeSession(token) {
|
|
102
135
|
await ensureSessionTable();
|
|
103
136
|
const client = getDbExec();
|
|
@@ -107,7 +140,7 @@ export async function removeSession(token) {
|
|
|
107
140
|
});
|
|
108
141
|
}
|
|
109
142
|
/**
|
|
110
|
-
* Look up the email associated with a session token.
|
|
143
|
+
* Look up the email associated with a legacy session token.
|
|
111
144
|
* Returns null if the session doesn't exist, is expired, or has no email.
|
|
112
145
|
*/
|
|
113
146
|
export async function getSessionEmail(token) {
|
|
@@ -129,71 +162,115 @@ export async function getSessionEmail(token) {
|
|
|
129
162
|
}
|
|
130
163
|
return rows[0].email ?? null;
|
|
131
164
|
}
|
|
132
|
-
async function hasSession(token) {
|
|
133
|
-
await ensureSessionTable();
|
|
134
|
-
const client = getDbExec();
|
|
135
|
-
const { rows } = await client.execute({
|
|
136
|
-
sql: `SELECT created_at FROM sessions WHERE token = ?`,
|
|
137
|
-
args: [token],
|
|
138
|
-
});
|
|
139
|
-
if (rows.length === 0)
|
|
140
|
-
return false;
|
|
141
|
-
const createdAt = rows[0].created_at;
|
|
142
|
-
if (Date.now() - createdAt > sessionMaxAge * 1000) {
|
|
143
|
-
await client.execute({
|
|
144
|
-
sql: `DELETE FROM sessions WHERE token = ?`,
|
|
145
|
-
args: [token],
|
|
146
|
-
});
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
return true;
|
|
150
|
-
}
|
|
151
165
|
// ---------------------------------------------------------------------------
|
|
152
|
-
//
|
|
166
|
+
// getSession — the auth contract
|
|
153
167
|
// ---------------------------------------------------------------------------
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
+
let customGetSession = null;
|
|
169
|
+
let authDisabledMode = false;
|
|
170
|
+
let _authGuardConfig = null;
|
|
171
|
+
/**
|
|
172
|
+
* Module-level auth guard function. Set by autoMountAuth() when auth is active.
|
|
173
|
+
* Called by the server middleware to enforce auth on ALL requests (not just
|
|
174
|
+
* /_agent-native/* routes).
|
|
175
|
+
*/
|
|
176
|
+
let _authGuardFn = null;
|
|
177
|
+
/**
|
|
178
|
+
* Run the auth guard on an event. Returns a Response/object to block the
|
|
179
|
+
* request (login page or 401), or undefined to allow it through.
|
|
180
|
+
*
|
|
181
|
+
* Called by the default server middleware (server/middleware/auth.ts) to
|
|
182
|
+
* enforce auth on page routes and API routes — not just framework routes.
|
|
183
|
+
*/
|
|
184
|
+
export async function runAuthGuard(event) {
|
|
185
|
+
if (!_authGuardFn)
|
|
186
|
+
return; // Auth not mounted (local mode, etc.)
|
|
187
|
+
return _authGuardFn(event);
|
|
168
188
|
}
|
|
189
|
+
const LOCAL_SESSION = { email: "local@localhost" };
|
|
169
190
|
// ---------------------------------------------------------------------------
|
|
170
|
-
//
|
|
191
|
+
// Auth guard factory
|
|
171
192
|
// ---------------------------------------------------------------------------
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
193
|
+
/**
|
|
194
|
+
* Create an auth guard function that checks session and blocks
|
|
195
|
+
* unauthenticated requests. Returns the login HTML for page routes
|
|
196
|
+
* or a 401 JSON response for API routes.
|
|
197
|
+
*
|
|
198
|
+
* Reads loginHtml and publicPaths from _authGuardConfig on every request
|
|
199
|
+
* so that a custom plugin can update them after the default has already
|
|
200
|
+
* installed this middleware (the production race condition fix).
|
|
201
|
+
*/
|
|
202
|
+
function createAuthGuardFn() {
|
|
203
|
+
return async (event) => {
|
|
204
|
+
const config = _authGuardConfig;
|
|
205
|
+
if (!config)
|
|
206
|
+
return;
|
|
207
|
+
const { loginHtml, publicPaths } = config;
|
|
208
|
+
const url = event.node?.req?.url ?? event.path ?? "/";
|
|
209
|
+
const p = url.split("?")[0];
|
|
210
|
+
// Skip auth routes and specific Google OAuth endpoints that must be public
|
|
211
|
+
// (callback and auth-url). Other Google endpoints like /status require auth.
|
|
212
|
+
if (p.startsWith("/_agent-native/auth/") ||
|
|
213
|
+
p === "/_agent-native/google/callback" ||
|
|
214
|
+
p === "/_agent-native/google/auth-url" ||
|
|
215
|
+
p === "/_agent-native/google/add-account/callback") {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
// Skip static assets (Vite chunks, fonts, images, etc.)
|
|
219
|
+
if (p.startsWith("/assets/") ||
|
|
220
|
+
p.startsWith("/_build/") ||
|
|
221
|
+
p.endsWith(".js") ||
|
|
222
|
+
p.endsWith(".css") ||
|
|
223
|
+
p.endsWith(".map") ||
|
|
224
|
+
p.endsWith(".ico") ||
|
|
225
|
+
p.endsWith(".png") ||
|
|
226
|
+
p.endsWith(".svg") ||
|
|
227
|
+
p.endsWith(".woff2") ||
|
|
228
|
+
p.endsWith(".woff")) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (isPublicPath(url, publicPaths))
|
|
232
|
+
return;
|
|
233
|
+
const session = await getSession(event);
|
|
234
|
+
if (session)
|
|
235
|
+
return;
|
|
236
|
+
if (p.startsWith("/api/") || p.startsWith("/_agent-native/")) {
|
|
237
|
+
setResponseStatus(event, 401);
|
|
238
|
+
return { error: "Unauthorized" };
|
|
239
|
+
}
|
|
240
|
+
return new Response(loginHtml, {
|
|
241
|
+
status: 200,
|
|
242
|
+
headers: { "Content-Type": "text/html; charset=utf-8" },
|
|
243
|
+
});
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Map a Better Auth session to our AuthSession type.
|
|
248
|
+
*/
|
|
249
|
+
function mapBetterAuthSession(baSession) {
|
|
250
|
+
return {
|
|
251
|
+
email: baSession.user.email,
|
|
252
|
+
userId: baSession.user.id,
|
|
253
|
+
token: baSession.session?.token,
|
|
254
|
+
orgId: baSession.session?.activeOrganizationId ?? undefined,
|
|
255
|
+
};
|
|
177
256
|
}
|
|
178
|
-
// ---------------------------------------------------------------------------
|
|
179
|
-
// getSession — the auth contract
|
|
180
|
-
// ---------------------------------------------------------------------------
|
|
181
|
-
let customGetSession = null;
|
|
182
|
-
let authDisabledMode = false;
|
|
183
|
-
const DEV_SESSION = { email: "local@localhost" };
|
|
184
257
|
/**
|
|
185
258
|
* Get the current auth session for a request.
|
|
186
259
|
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
260
|
+
* Resolution chain:
|
|
261
|
+
* 1. AUTH_MODE=local → local@localhost (explicit escape hatch)
|
|
262
|
+
* 2. AUTH_DISABLED=true → local@localhost (infrastructure auth)
|
|
263
|
+
* 3. ACCESS_TOKEN → check legacy cookie-based token sessions
|
|
264
|
+
* 4. BYOA custom getSession → delegate to template callback
|
|
265
|
+
* 5. Better Auth → check session via Better Auth API (cookie or Bearer)
|
|
266
|
+
* 6. Legacy cookie → check an_session cookie in legacy sessions table
|
|
267
|
+
* 7. Mobile _session query param → promote to cookie
|
|
268
|
+
* 8. Dev-mode fallback → local@localhost (never block in development)
|
|
192
269
|
*/
|
|
193
270
|
export async function getSession(event) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
//
|
|
271
|
+
// 1. AUTH_MODE=local — explicit local-only mode
|
|
272
|
+
if ((await isLocalModeEnabled()) || authDisabledMode) {
|
|
273
|
+
// Check for a real session cookie first (e.g. from Google OAuth)
|
|
197
274
|
try {
|
|
198
275
|
const cookie = getCookie(event, COOKIE_NAME);
|
|
199
276
|
if (cookie) {
|
|
@@ -203,17 +280,59 @@ export async function getSession(event) {
|
|
|
203
280
|
}
|
|
204
281
|
}
|
|
205
282
|
catch {
|
|
206
|
-
// DB not ready yet
|
|
283
|
+
// DB not ready yet
|
|
284
|
+
}
|
|
285
|
+
// Also try Better Auth session (for users who created an account then went local)
|
|
286
|
+
try {
|
|
287
|
+
const ba = getBetterAuthSync();
|
|
288
|
+
if (ba) {
|
|
289
|
+
const baSession = await ba.api.getSession({
|
|
290
|
+
headers: event.headers,
|
|
291
|
+
});
|
|
292
|
+
if (baSession?.user?.email) {
|
|
293
|
+
return mapBetterAuthSession(baSession);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
// Better Auth not initialized yet
|
|
207
299
|
}
|
|
208
|
-
return
|
|
300
|
+
return LOCAL_SESSION;
|
|
209
301
|
}
|
|
302
|
+
// 2. ACCESS_TOKEN check (programmatic/agent access)
|
|
303
|
+
const accessTokens = getAccessTokens();
|
|
304
|
+
if (accessTokens.length > 0) {
|
|
305
|
+
const cookie = getCookie(event, COOKIE_NAME);
|
|
306
|
+
if (cookie) {
|
|
307
|
+
const email = await getSessionEmail(cookie);
|
|
308
|
+
if (email)
|
|
309
|
+
return { email, token: cookie };
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
// 3. BYOA custom getSession
|
|
210
313
|
if (customGetSession) {
|
|
211
314
|
const session = await customGetSession(event);
|
|
212
315
|
if (session)
|
|
213
316
|
return session;
|
|
214
|
-
// Fall through to _session
|
|
317
|
+
// Fall through to mobile _session check
|
|
215
318
|
}
|
|
216
319
|
else {
|
|
320
|
+
// 4. Better Auth session (cookie or Bearer token)
|
|
321
|
+
try {
|
|
322
|
+
const ba = getBetterAuthSync();
|
|
323
|
+
if (ba) {
|
|
324
|
+
const baSession = await ba.api.getSession({
|
|
325
|
+
headers: event.headers,
|
|
326
|
+
});
|
|
327
|
+
if (baSession?.user?.email) {
|
|
328
|
+
return mapBetterAuthSession(baSession);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
// Better Auth not ready
|
|
334
|
+
}
|
|
335
|
+
// 5. Legacy cookie fallback (for sessions created before migration)
|
|
217
336
|
const cookie = getCookie(event, COOKIE_NAME);
|
|
218
337
|
if (cookie) {
|
|
219
338
|
const email = await getSessionEmail(cookie);
|
|
@@ -221,145 +340,46 @@ export async function getSession(event) {
|
|
|
221
340
|
return { email, token: cookie };
|
|
222
341
|
}
|
|
223
342
|
}
|
|
224
|
-
// Mobile
|
|
225
|
-
// completes in Safari the WebView won't have the session cookie. The mobile
|
|
226
|
-
// app passes the token as a query parameter; if it's valid we promote it to
|
|
227
|
-
// an httpOnly cookie so subsequent requests work normally.
|
|
228
|
-
// This MUST run even with custom auth providers (e.g. createGoogleAuthPlugin).
|
|
343
|
+
// 6. Mobile WebView bridge — _session query param
|
|
229
344
|
const qToken = getQuery(event)?._session;
|
|
230
345
|
if (qToken) {
|
|
231
346
|
const email = await getSessionEmail(qToken);
|
|
232
347
|
if (email) {
|
|
233
348
|
setCookie(event, COOKIE_NAME, qToken, {
|
|
234
349
|
httpOnly: true,
|
|
235
|
-
secure:
|
|
350
|
+
secure: !isDevEnvironment(),
|
|
236
351
|
sameSite: "lax",
|
|
237
352
|
path: "/",
|
|
238
353
|
maxAge: sessionMaxAge,
|
|
239
354
|
});
|
|
355
|
+
setResponseHeader(event, "Referrer-Policy", "no-referrer");
|
|
240
356
|
return { email, token: qToken };
|
|
241
357
|
}
|
|
242
358
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
//
|
|
246
|
-
//
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
const inputBuf = Buffer.from(input);
|
|
250
|
-
for (const token of tokens) {
|
|
251
|
-
const tokenBuf = Buffer.from(token);
|
|
252
|
-
if (inputBuf.length === tokenBuf.length &&
|
|
253
|
-
crypto.timingSafeEqual(inputBuf, tokenBuf)) {
|
|
254
|
-
return true;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
return false;
|
|
258
|
-
}
|
|
259
|
-
// ---------------------------------------------------------------------------
|
|
260
|
-
// Password hashing — Web Crypto PBKDF2 (works on Node.js + CF Workers)
|
|
261
|
-
// ---------------------------------------------------------------------------
|
|
262
|
-
const PBKDF2_ITERATIONS = 100_000;
|
|
263
|
-
function toHex(buf) {
|
|
264
|
-
return Array.from(buf)
|
|
265
|
-
.map((b) => b.toString(16).padStart(2, "0"))
|
|
266
|
-
.join("");
|
|
267
|
-
}
|
|
268
|
-
function fromHex(hex) {
|
|
269
|
-
const bytes = new Uint8Array(hex.length / 2);
|
|
270
|
-
for (let i = 0; i < hex.length; i += 2) {
|
|
271
|
-
bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
|
|
359
|
+
// 7. Dev-mode safety net — in development, always fall back to local@localhost
|
|
360
|
+
// so the app is usable without any auth configuration. This prevents 401
|
|
361
|
+
// errors when Better Auth isn't configured, the marker file is missing, or
|
|
362
|
+
// the user simply wants to play around locally.
|
|
363
|
+
if (isDevEnvironment()) {
|
|
364
|
+
return LOCAL_SESSION;
|
|
272
365
|
}
|
|
273
|
-
return
|
|
274
|
-
}
|
|
275
|
-
async function hashPassword(password) {
|
|
276
|
-
const salt = crypto.getRandomValues(new Uint8Array(16));
|
|
277
|
-
const encoded = new TextEncoder().encode(password);
|
|
278
|
-
const keyMaterial = await globalThis.crypto.subtle.importKey("raw", encoded.buffer, "PBKDF2", false, ["deriveBits"]);
|
|
279
|
-
const derived = await globalThis.crypto.subtle.deriveBits({
|
|
280
|
-
name: "PBKDF2",
|
|
281
|
-
salt: salt.buffer,
|
|
282
|
-
iterations: PBKDF2_ITERATIONS,
|
|
283
|
-
hash: "SHA-256",
|
|
284
|
-
}, keyMaterial, 256);
|
|
285
|
-
return `${PBKDF2_ITERATIONS}:${toHex(salt)}:${toHex(new Uint8Array(derived))}`;
|
|
286
|
-
}
|
|
287
|
-
async function verifyPassword(password, stored) {
|
|
288
|
-
const [iterStr, saltHex, hashHex] = stored.split(":");
|
|
289
|
-
const iterations = parseInt(iterStr, 10);
|
|
290
|
-
const salt = fromHex(saltHex);
|
|
291
|
-
const expectedHash = fromHex(hashHex);
|
|
292
|
-
const encoded = new TextEncoder().encode(password);
|
|
293
|
-
const keyMaterial = await globalThis.crypto.subtle.importKey("raw", encoded.buffer, "PBKDF2", false, ["deriveBits"]);
|
|
294
|
-
const derived = new Uint8Array(await globalThis.crypto.subtle.deriveBits({
|
|
295
|
-
name: "PBKDF2",
|
|
296
|
-
salt: salt.buffer,
|
|
297
|
-
iterations,
|
|
298
|
-
hash: "SHA-256",
|
|
299
|
-
}, keyMaterial, 256));
|
|
300
|
-
if (derived.length !== expectedHash.length)
|
|
301
|
-
return false;
|
|
302
|
-
// Constant-time comparison
|
|
303
|
-
let diff = 0;
|
|
304
|
-
for (let i = 0; i < derived.length; i++) {
|
|
305
|
-
diff |= derived[i] ^ expectedHash[i];
|
|
306
|
-
}
|
|
307
|
-
return diff === 0;
|
|
366
|
+
return null;
|
|
308
367
|
}
|
|
309
368
|
// ---------------------------------------------------------------------------
|
|
310
|
-
//
|
|
369
|
+
// Public path matching
|
|
311
370
|
// ---------------------------------------------------------------------------
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
return;
|
|
316
|
-
const client = getDbExec();
|
|
317
|
-
await client.execute(`
|
|
318
|
-
CREATE TABLE IF NOT EXISTS users (
|
|
319
|
-
email TEXT PRIMARY KEY,
|
|
320
|
-
password_hash TEXT NOT NULL,
|
|
321
|
-
created_at ${intType()} NOT NULL
|
|
322
|
-
)
|
|
323
|
-
`);
|
|
324
|
-
_usersTableReady = true;
|
|
325
|
-
}
|
|
326
|
-
async function createUser(email, password) {
|
|
327
|
-
await ensureUsersTable();
|
|
328
|
-
const client = getDbExec();
|
|
329
|
-
// Check if user already exists
|
|
330
|
-
const { rows } = await client.execute({
|
|
331
|
-
sql: `SELECT email FROM users WHERE email = ?`,
|
|
332
|
-
args: [email],
|
|
333
|
-
});
|
|
334
|
-
if (rows.length > 0) {
|
|
335
|
-
return { ok: false, error: "An account with this email already exists" };
|
|
336
|
-
}
|
|
337
|
-
const passwordHash = await hashPassword(password);
|
|
338
|
-
await client.execute({
|
|
339
|
-
sql: `INSERT INTO users (email, password_hash, created_at) VALUES (?, ?, ?)`,
|
|
340
|
-
args: [email, passwordHash, Date.now()],
|
|
341
|
-
});
|
|
342
|
-
return { ok: true };
|
|
343
|
-
}
|
|
344
|
-
async function authenticateUser(email, password) {
|
|
345
|
-
await ensureUsersTable();
|
|
346
|
-
const client = getDbExec();
|
|
347
|
-
const { rows } = await client.execute({
|
|
348
|
-
sql: `SELECT password_hash FROM users WHERE email = ?`,
|
|
349
|
-
args: [email],
|
|
350
|
-
});
|
|
351
|
-
if (rows.length === 0)
|
|
352
|
-
return false;
|
|
353
|
-
return verifyPassword(password, rows[0].password_hash);
|
|
371
|
+
function isPublicPath(url, publicPaths) {
|
|
372
|
+
const p = url.split("?")[0];
|
|
373
|
+
return publicPaths.some((pp) => p === pp || p.startsWith(pp + "/"));
|
|
354
374
|
}
|
|
355
375
|
// ---------------------------------------------------------------------------
|
|
356
|
-
// Login page HTML
|
|
376
|
+
// Login page HTML (ACCESS_TOKEN mode)
|
|
357
377
|
// ---------------------------------------------------------------------------
|
|
358
|
-
const
|
|
378
|
+
const TOKEN_LOGIN_HTML = `<!DOCTYPE html>
|
|
359
379
|
<html lang="en">
|
|
360
380
|
<head>
|
|
361
381
|
<meta charset="UTF-8">
|
|
362
|
-
<meta name="viewport" content="width=device-width, initial-scale=1
|
|
382
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
|
363
383
|
<title>Sign in</title>
|
|
364
384
|
<style>
|
|
365
385
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
@@ -391,7 +411,6 @@ const LOGIN_HTML = `<!DOCTYPE html>
|
|
|
391
411
|
color: #e5e5e5;
|
|
392
412
|
font-size: 0.9375rem;
|
|
393
413
|
outline: none;
|
|
394
|
-
transition: border-color 0.15s;
|
|
395
414
|
}
|
|
396
415
|
input:focus { border-color: rgba(255,255,255,0.3); }
|
|
397
416
|
button {
|
|
@@ -405,7 +424,6 @@ const LOGIN_HTML = `<!DOCTYPE html>
|
|
|
405
424
|
font-size: 0.9375rem;
|
|
406
425
|
font-weight: 500;
|
|
407
426
|
cursor: pointer;
|
|
408
|
-
transition: opacity 0.15s;
|
|
409
427
|
}
|
|
410
428
|
button:hover { opacity: 0.85; }
|
|
411
429
|
.error { margin-top: 0.75rem; font-size: 0.8125rem; color: #f87171; display: none; }
|
|
@@ -441,241 +459,106 @@ const LOGIN_HTML = `<!DOCTYPE html>
|
|
|
441
459
|
</body>
|
|
442
460
|
</html>`;
|
|
443
461
|
// ---------------------------------------------------------------------------
|
|
444
|
-
//
|
|
462
|
+
// setAuthModeLocal — write AUTH_MODE=local to .env for the escape hatch
|
|
445
463
|
// ---------------------------------------------------------------------------
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
454
|
-
body {
|
|
455
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
456
|
-
background: #0a0a0a;
|
|
457
|
-
color: #e5e5e5;
|
|
458
|
-
display: flex;
|
|
459
|
-
align-items: center;
|
|
460
|
-
justify-content: center;
|
|
461
|
-
min-height: 100vh;
|
|
462
|
-
}
|
|
463
|
-
.card {
|
|
464
|
-
width: 100%;
|
|
465
|
-
max-width: 380px;
|
|
466
|
-
padding: 2rem;
|
|
467
|
-
background: #141414;
|
|
468
|
-
border: 1px solid rgba(255,255,255,0.08);
|
|
469
|
-
border-radius: 12px;
|
|
470
|
-
}
|
|
471
|
-
.tabs {
|
|
472
|
-
display: inline-flex;
|
|
473
|
-
width: 100%;
|
|
474
|
-
padding: 4px;
|
|
475
|
-
margin-bottom: 1.5rem;
|
|
476
|
-
background: rgba(255,255,255,0.06);
|
|
477
|
-
border-radius: 8px;
|
|
478
|
-
}
|
|
479
|
-
.tab {
|
|
480
|
-
flex: 1;
|
|
481
|
-
padding: 0.5rem 0.75rem;
|
|
482
|
-
background: none;
|
|
483
|
-
border: none;
|
|
484
|
-
color: #888;
|
|
485
|
-
font-size: 0.8125rem;
|
|
486
|
-
font-weight: 500;
|
|
487
|
-
cursor: pointer;
|
|
488
|
-
border-radius: 6px;
|
|
489
|
-
}
|
|
490
|
-
.tab.active {
|
|
491
|
-
background: #1e1e1e;
|
|
492
|
-
color: #fff;
|
|
493
|
-
box-shadow: 0 1px 2px rgba(0,0,0,0.3);
|
|
494
|
-
}
|
|
495
|
-
.tab:hover:not(.active) { color: #bbb; }
|
|
496
|
-
.form { display: none; }
|
|
497
|
-
.form.active { display: block; }
|
|
498
|
-
label { display: block; font-size: 0.8125rem; color: #888; margin-bottom: 0.375rem; }
|
|
499
|
-
input {
|
|
500
|
-
width: 100%;
|
|
501
|
-
padding: 0.5rem 0.75rem;
|
|
502
|
-
background: transparent;
|
|
503
|
-
border: 1px solid rgba(255,255,255,0.12);
|
|
504
|
-
border-radius: 6px;
|
|
505
|
-
color: #e5e5e5;
|
|
506
|
-
font-size: 0.875rem;
|
|
507
|
-
outline: none;
|
|
508
|
-
margin-bottom: 0.875rem;
|
|
509
|
-
}
|
|
510
|
-
input:focus { border-color: rgba(255,255,255,0.3); box-shadow: 0 0 0 1px rgba(255,255,255,0.1); }
|
|
511
|
-
input::placeholder { color: #555; }
|
|
512
|
-
button[type="submit"] {
|
|
513
|
-
width: 100%;
|
|
514
|
-
margin-top: 0.25rem;
|
|
515
|
-
padding: 0.5rem;
|
|
516
|
-
background: #fff;
|
|
517
|
-
color: #000;
|
|
518
|
-
border: none;
|
|
519
|
-
border-radius: 6px;
|
|
520
|
-
font-size: 0.875rem;
|
|
521
|
-
font-weight: 500;
|
|
522
|
-
cursor: pointer;
|
|
523
|
-
}
|
|
524
|
-
button[type="submit"]:hover { background: #e5e5e5; }
|
|
525
|
-
button[type="submit"]:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
526
|
-
.msg { margin-top: 0.75rem; font-size: 0.8125rem; display: none; }
|
|
527
|
-
.msg.error { color: #f87171; }
|
|
528
|
-
.msg.success { color: #4ade80; }
|
|
529
|
-
.msg.show { display: block; }
|
|
530
|
-
</style>
|
|
531
|
-
</head>
|
|
532
|
-
<body>
|
|
533
|
-
<div class="card">
|
|
534
|
-
<div class="tabs">
|
|
535
|
-
<button class="tab active" data-tab="login">Sign in</button>
|
|
536
|
-
<button class="tab" data-tab="register">Create account</button>
|
|
537
|
-
</div>
|
|
538
|
-
<form id="login-form" class="form active">
|
|
539
|
-
<label for="l-email">Email</label>
|
|
540
|
-
<input id="l-email" type="email" autocomplete="email" autofocus placeholder="you@example.com" required />
|
|
541
|
-
<label for="l-pass">Password</label>
|
|
542
|
-
<input id="l-pass" type="password" autocomplete="current-password" placeholder="Enter password" required />
|
|
543
|
-
<button type="submit">Sign in</button>
|
|
544
|
-
<p class="msg error" id="l-err"></p>
|
|
545
|
-
</form>
|
|
546
|
-
<form id="register-form" class="form">
|
|
547
|
-
<label for="r-email">Email</label>
|
|
548
|
-
<input id="r-email" type="email" autocomplete="email" placeholder="you@example.com" required />
|
|
549
|
-
<label for="r-pass">Password</label>
|
|
550
|
-
<input id="r-pass" type="password" autocomplete="new-password" placeholder="At least 8 characters" required minlength="8" />
|
|
551
|
-
<label for="r-pass2">Confirm password</label>
|
|
552
|
-
<input id="r-pass2" type="password" autocomplete="new-password" placeholder="Confirm password" required minlength="8" />
|
|
553
|
-
<button type="submit">Create account</button>
|
|
554
|
-
<p class="msg" id="r-msg"></p>
|
|
555
|
-
</form>
|
|
556
|
-
</div>
|
|
557
|
-
<script>
|
|
558
|
-
const tabs = document.querySelectorAll('.tab');
|
|
559
|
-
const forms = document.querySelectorAll('.form');
|
|
560
|
-
tabs.forEach(t => t.addEventListener('click', () => {
|
|
561
|
-
tabs.forEach(x => x.classList.remove('active'));
|
|
562
|
-
forms.forEach(x => x.classList.remove('active'));
|
|
563
|
-
t.classList.add('active');
|
|
564
|
-
document.getElementById(t.dataset.tab + '-form').classList.add('active');
|
|
565
|
-
}));
|
|
566
|
-
|
|
567
|
-
document.getElementById('login-form').addEventListener('submit', async (e) => {
|
|
568
|
-
e.preventDefault();
|
|
569
|
-
const err = document.getElementById('l-err');
|
|
570
|
-
err.classList.remove('show');
|
|
571
|
-
const res = await fetch('/_agent-native/auth/login', {
|
|
572
|
-
method: 'POST',
|
|
573
|
-
headers: { 'Content-Type': 'application/json' },
|
|
574
|
-
body: JSON.stringify({
|
|
575
|
-
email: document.getElementById('l-email').value,
|
|
576
|
-
password: document.getElementById('l-pass').value,
|
|
577
|
-
}),
|
|
578
|
-
});
|
|
579
|
-
if (res.ok) {
|
|
580
|
-
window.location.reload();
|
|
581
|
-
} else {
|
|
582
|
-
const data = await res.json().catch(() => ({}));
|
|
583
|
-
err.textContent = data.error || 'Invalid email or password';
|
|
584
|
-
err.classList.add('show');
|
|
464
|
+
async function setAuthModeLocal() {
|
|
465
|
+
try {
|
|
466
|
+
const fs = await getFs();
|
|
467
|
+
fs.mkdirSync(path.dirname(LOCAL_MODE_MARKER_PATH), { recursive: true });
|
|
468
|
+
fs.writeFileSync(LOCAL_MODE_MARKER_PATH, "local\n", "utf-8");
|
|
469
|
+
process.env.AUTH_MODE = "local";
|
|
470
|
+
return true;
|
|
585
471
|
}
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
document.getElementById('register-form').addEventListener('submit', async (e) => {
|
|
589
|
-
e.preventDefault();
|
|
590
|
-
const msg = document.getElementById('r-msg');
|
|
591
|
-
msg.classList.remove('show', 'error', 'success');
|
|
592
|
-
const pass = document.getElementById('r-pass').value;
|
|
593
|
-
const pass2 = document.getElementById('r-pass2').value;
|
|
594
|
-
if (pass !== pass2) {
|
|
595
|
-
msg.textContent = 'Passwords do not match';
|
|
596
|
-
msg.classList.add('show', 'error');
|
|
597
|
-
return;
|
|
472
|
+
catch {
|
|
473
|
+
return false;
|
|
598
474
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
// Auto-login after registration
|
|
612
|
-
const loginRes = await fetch('/_agent-native/auth/login', {
|
|
613
|
-
method: 'POST',
|
|
614
|
-
headers: { 'Content-Type': 'application/json' },
|
|
615
|
-
body: JSON.stringify({
|
|
616
|
-
email: document.getElementById('r-email').value,
|
|
617
|
-
password: pass,
|
|
618
|
-
}),
|
|
619
|
-
});
|
|
620
|
-
if (loginRes.ok) {
|
|
621
|
-
window.location.reload();
|
|
622
|
-
}
|
|
623
|
-
} else {
|
|
624
|
-
msg.textContent = data.error || 'Registration failed';
|
|
625
|
-
msg.classList.add('show', 'error');
|
|
475
|
+
}
|
|
476
|
+
async function removeAuthModeLocal() {
|
|
477
|
+
try {
|
|
478
|
+
const fs = await getFs();
|
|
479
|
+
try {
|
|
480
|
+
fs.unlinkSync(LOCAL_MODE_MARKER_PATH);
|
|
481
|
+
}
|
|
482
|
+
catch {
|
|
483
|
+
// Marker already absent
|
|
484
|
+
}
|
|
485
|
+
delete process.env.AUTH_MODE;
|
|
486
|
+
return true;
|
|
626
487
|
}
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
488
|
+
catch {
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
631
492
|
// ---------------------------------------------------------------------------
|
|
632
|
-
//
|
|
493
|
+
// mountBetterAuthRoutes — Better Auth powered auth with backward-compat routes
|
|
633
494
|
// ---------------------------------------------------------------------------
|
|
634
|
-
function
|
|
635
|
-
|
|
495
|
+
async function mountBetterAuthRoutes(app, options) {
|
|
496
|
+
const publicPaths = [...(options.publicPaths ?? [])];
|
|
497
|
+
// The A2A agent card is part of an open protocol — other agents must be
|
|
498
|
+
// able to discover it without auth. Same for favicons and similar probes.
|
|
499
|
+
for (const pp of ["/.well-known", "/favicon.ico", "/favicon.png"]) {
|
|
500
|
+
if (!publicPaths.includes(pp))
|
|
501
|
+
publicPaths.push(pp);
|
|
502
|
+
}
|
|
503
|
+
// Auto-add Google OAuth routes when credentials are configured
|
|
504
|
+
if (process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET) {
|
|
505
|
+
for (const gp of [
|
|
506
|
+
"/_agent-native/google/callback",
|
|
507
|
+
"/_agent-native/google/auth-url",
|
|
508
|
+
]) {
|
|
509
|
+
if (!publicPaths.includes(gp))
|
|
510
|
+
publicPaths.push(gp);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
636
513
|
const accessTokens = getAccessTokens();
|
|
637
|
-
//
|
|
638
|
-
|
|
514
|
+
// Initialize Better Auth
|
|
515
|
+
const auth = await getBetterAuth(options.betterAuth);
|
|
516
|
+
// Mount Better Auth catch-all handler at /_agent-native/auth/ba/*
|
|
517
|
+
app.use("/_agent-native/auth/ba", defineEventHandler(async (event) => {
|
|
518
|
+
const response = await auth.handler(toWebRequest(event));
|
|
519
|
+
return response;
|
|
520
|
+
}));
|
|
521
|
+
// POST /_agent-native/auth/local-mode — switch to local mode (onboarding escape hatch)
|
|
522
|
+
// Only available in dev — production requires real accounts for usage tracking.
|
|
523
|
+
app.use("/_agent-native/auth/local-mode", defineEventHandler(async (event) => {
|
|
639
524
|
if (getMethod(event) !== "POST") {
|
|
640
525
|
setResponseStatus(event, 405);
|
|
641
526
|
return { error: "Method not allowed" };
|
|
642
527
|
}
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
const email = body?.email?.trim?.()?.toLowerCase?.();
|
|
649
|
-
const password = body?.password;
|
|
650
|
-
if (!email || typeof email !== "string" || !email.includes("@")) {
|
|
651
|
-
setResponseStatus(event, 400);
|
|
652
|
-
return { error: "Valid email is required" };
|
|
528
|
+
if (!isDevEnvironment()) {
|
|
529
|
+
setResponseStatus(event, 403);
|
|
530
|
+
return {
|
|
531
|
+
error: "Local mode is not available in production. Create an account to continue.",
|
|
532
|
+
};
|
|
653
533
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
534
|
+
const ok = await setAuthModeLocal();
|
|
535
|
+
if (!ok) {
|
|
536
|
+
setResponseStatus(event, 500);
|
|
537
|
+
return { error: "Failed to enable local mode" };
|
|
657
538
|
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
539
|
+
return { ok: true };
|
|
540
|
+
}));
|
|
541
|
+
// POST /_agent-native/auth/exit-local-mode — switch back to real auth
|
|
542
|
+
app.use("/_agent-native/auth/exit-local-mode", defineEventHandler(async (event) => {
|
|
543
|
+
if (getMethod(event) !== "POST") {
|
|
544
|
+
setResponseStatus(event, 405);
|
|
545
|
+
return { error: "Method not allowed" };
|
|
546
|
+
}
|
|
547
|
+
const ok = await removeAuthModeLocal();
|
|
548
|
+
if (!ok) {
|
|
549
|
+
setResponseStatus(event, 500);
|
|
550
|
+
return { error: "Failed to disable local mode" };
|
|
662
551
|
}
|
|
663
|
-
resetRateLimit(`register:${ip}`);
|
|
664
552
|
return { ok: true };
|
|
665
553
|
}));
|
|
666
|
-
// POST /_agent-native/auth/login
|
|
554
|
+
// Backward-compat: POST /_agent-native/auth/login
|
|
667
555
|
app.use("/_agent-native/auth/login", defineEventHandler(async (event) => {
|
|
668
556
|
if (getMethod(event) !== "POST") {
|
|
669
557
|
setResponseStatus(event, 405);
|
|
670
558
|
return { error: "Method not allowed" };
|
|
671
559
|
}
|
|
672
|
-
const ip = getClientIp(event);
|
|
673
|
-
const rateLimitKey = `login:${ip}`;
|
|
674
|
-
const limited = checkRateLimit(event, rateLimitKey);
|
|
675
|
-
if (limited)
|
|
676
|
-
return limited;
|
|
677
560
|
const body = await readBody(event);
|
|
678
|
-
// Legacy
|
|
561
|
+
// Legacy ACCESS_TOKEN login
|
|
679
562
|
if (body?.token &&
|
|
680
563
|
typeof body.token === "string" &&
|
|
681
564
|
accessTokens.length > 0) {
|
|
@@ -687,44 +570,81 @@ function mountEmailAuthRoutes(app, publicPaths = []) {
|
|
|
687
570
|
await addSession(sessionToken, "user");
|
|
688
571
|
setCookie(event, COOKIE_NAME, sessionToken, {
|
|
689
572
|
httpOnly: true,
|
|
690
|
-
secure:
|
|
573
|
+
secure: !isDevEnvironment(),
|
|
691
574
|
sameSite: "lax",
|
|
692
575
|
path: "/",
|
|
693
576
|
maxAge: sessionMaxAge,
|
|
694
577
|
});
|
|
695
|
-
resetRateLimit(rateLimitKey);
|
|
696
578
|
return { ok: true };
|
|
697
579
|
}
|
|
698
|
-
// Email/password login
|
|
580
|
+
// Email/password login via Better Auth
|
|
699
581
|
const email = body?.email?.trim?.()?.toLowerCase?.();
|
|
700
582
|
const password = body?.password;
|
|
701
583
|
if (!email || !password) {
|
|
702
584
|
setResponseStatus(event, 400);
|
|
703
585
|
return { error: "Email and password are required" };
|
|
704
586
|
}
|
|
705
|
-
|
|
706
|
-
|
|
587
|
+
try {
|
|
588
|
+
const result = await auth.api.signInEmail({
|
|
589
|
+
body: { email, password },
|
|
590
|
+
});
|
|
591
|
+
if (result?.token) {
|
|
592
|
+
setCookie(event, COOKIE_NAME, result.token, {
|
|
593
|
+
httpOnly: true,
|
|
594
|
+
secure: !isDevEnvironment(),
|
|
595
|
+
sameSite: "lax",
|
|
596
|
+
path: "/",
|
|
597
|
+
maxAge: sessionMaxAge,
|
|
598
|
+
});
|
|
599
|
+
await addSession(result.token, email);
|
|
600
|
+
}
|
|
601
|
+
return { ok: true };
|
|
602
|
+
}
|
|
603
|
+
catch (e) {
|
|
707
604
|
setResponseStatus(event, 401);
|
|
708
|
-
return { error: "Invalid email or password" };
|
|
605
|
+
return { error: e?.message || "Invalid email or password" };
|
|
606
|
+
}
|
|
607
|
+
}));
|
|
608
|
+
// Backward-compat: POST /_agent-native/auth/register
|
|
609
|
+
app.use("/_agent-native/auth/register", defineEventHandler(async (event) => {
|
|
610
|
+
if (getMethod(event) !== "POST") {
|
|
611
|
+
setResponseStatus(event, 405);
|
|
612
|
+
return { error: "Method not allowed" };
|
|
613
|
+
}
|
|
614
|
+
const body = await readBody(event);
|
|
615
|
+
const email = body?.email?.trim?.()?.toLowerCase?.();
|
|
616
|
+
const password = body?.password;
|
|
617
|
+
if (!email || typeof email !== "string" || !email.includes("@")) {
|
|
618
|
+
setResponseStatus(event, 400);
|
|
619
|
+
return { error: "Valid email is required" };
|
|
620
|
+
}
|
|
621
|
+
if (!password || typeof password !== "string" || password.length < 8) {
|
|
622
|
+
setResponseStatus(event, 400);
|
|
623
|
+
return { error: "Password must be at least 8 characters" };
|
|
624
|
+
}
|
|
625
|
+
try {
|
|
626
|
+
await auth.api.signUpEmail({
|
|
627
|
+
body: { email, password, name: email.split("@")[0] },
|
|
628
|
+
});
|
|
629
|
+
return { ok: true };
|
|
630
|
+
}
|
|
631
|
+
catch (e) {
|
|
632
|
+
setResponseStatus(event, 409);
|
|
633
|
+
return { error: e?.message || "Registration failed" };
|
|
709
634
|
}
|
|
710
|
-
const sessionToken = crypto.randomBytes(32).toString("hex");
|
|
711
|
-
await addSession(sessionToken, email);
|
|
712
|
-
setCookie(event, COOKIE_NAME, sessionToken, {
|
|
713
|
-
httpOnly: true,
|
|
714
|
-
secure: process.env.NODE_ENV === "production",
|
|
715
|
-
sameSite: "lax",
|
|
716
|
-
path: "/",
|
|
717
|
-
maxAge: sessionMaxAge,
|
|
718
|
-
});
|
|
719
|
-
resetRateLimit(rateLimitKey);
|
|
720
|
-
return { ok: true };
|
|
721
635
|
}));
|
|
722
|
-
// POST /_agent-native/auth/logout
|
|
636
|
+
// Backward-compat: POST /_agent-native/auth/logout
|
|
723
637
|
app.use("/_agent-native/auth/logout", defineEventHandler(async (event) => {
|
|
724
638
|
const cookie = getCookie(event, COOKIE_NAME);
|
|
725
639
|
if (cookie)
|
|
726
640
|
await removeSession(cookie);
|
|
727
641
|
deleteCookie(event, COOKIE_NAME, { path: "/" });
|
|
642
|
+
try {
|
|
643
|
+
await auth.api.signOut({ headers: event.headers });
|
|
644
|
+
}
|
|
645
|
+
catch {
|
|
646
|
+
// Ignore if no Better Auth session
|
|
647
|
+
}
|
|
728
648
|
return { ok: true };
|
|
729
649
|
}));
|
|
730
650
|
// GET /_agent-native/auth/session
|
|
@@ -736,60 +656,45 @@ function mountEmailAuthRoutes(app, publicPaths = []) {
|
|
|
736
656
|
const session = await getSession(event);
|
|
737
657
|
return session ?? { error: "Not authenticated" };
|
|
738
658
|
}));
|
|
739
|
-
//
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
p === "/_agent-native/auth/session" ||
|
|
747
|
-
p === "/_agent-native/auth/register") {
|
|
748
|
-
return;
|
|
659
|
+
// POST /_agent-native/auth/migrate-local-data — move local-mode data to
|
|
660
|
+
// the currently signed-in account. Called by the UI after a user upgrades
|
|
661
|
+
// from local mode to a real account so they don't lose their data.
|
|
662
|
+
app.use("/_agent-native/auth/migrate-local-data", defineEventHandler(async (event) => {
|
|
663
|
+
if (getMethod(event) !== "POST") {
|
|
664
|
+
setResponseStatus(event, 405);
|
|
665
|
+
return { error: "Method not allowed" };
|
|
749
666
|
}
|
|
750
|
-
if (isPublicPath(url, publicPaths))
|
|
751
|
-
return;
|
|
752
667
|
const session = await getSession(event);
|
|
753
|
-
if (session)
|
|
754
|
-
return;
|
|
755
|
-
if (p.startsWith("/api/") || p.startsWith("/_agent-native/")) {
|
|
668
|
+
if (!session?.email || session.email === "local@localhost") {
|
|
756
669
|
setResponseStatus(event, 401);
|
|
757
|
-
return { error: "
|
|
670
|
+
return { error: "Not authenticated as a real account" };
|
|
671
|
+
}
|
|
672
|
+
try {
|
|
673
|
+
const result = await migrateLocalUserData(session.email);
|
|
674
|
+
return { ok: true, ...result };
|
|
675
|
+
}
|
|
676
|
+
catch (e) {
|
|
677
|
+
setResponseStatus(event, 500);
|
|
678
|
+
return { error: e?.message || "Migration failed" };
|
|
758
679
|
}
|
|
759
|
-
setResponseStatus(event, 200);
|
|
760
|
-
setResponseHeader(event, "Content-Type", "text/html");
|
|
761
|
-
return loginHtml;
|
|
762
680
|
}));
|
|
681
|
+
// Auth guard — stored both in framework middleware registry AND in
|
|
682
|
+
// _authGuardFn so the server middleware can enforce it on ALL routes.
|
|
683
|
+
const loginHtml = options.loginHtml ?? getOnboardingHtml({ googleOnly: options.googleOnly });
|
|
684
|
+
_authGuardConfig = { loginHtml, publicPaths };
|
|
685
|
+
const guardFn = createAuthGuardFn();
|
|
686
|
+
_authGuardFn = guardFn;
|
|
687
|
+
app.use(defineEventHandler(guardFn));
|
|
763
688
|
}
|
|
764
689
|
// ---------------------------------------------------------------------------
|
|
765
|
-
//
|
|
690
|
+
// mountTokenOnlyRoutes — ACCESS_TOKEN-only auth (no Better Auth)
|
|
766
691
|
// ---------------------------------------------------------------------------
|
|
767
|
-
|
|
768
|
-
* Mount auth middleware + login/logout/session routes onto an H3 app.
|
|
769
|
-
*
|
|
770
|
-
* @deprecated Use `autoMountAuth(app, options?)` instead for automatic
|
|
771
|
-
* dev/prod behavior. This function is kept for backwards compatibility
|
|
772
|
-
* when you need explicit control over the access token.
|
|
773
|
-
*/
|
|
774
|
-
export function mountAuthMiddleware(app, accessToken) {
|
|
775
|
-
mountAuthRoutes(app, [accessToken]);
|
|
776
|
-
}
|
|
777
|
-
function isPublicPath(url, publicPaths) {
|
|
778
|
-
const p = url.split("?")[0];
|
|
779
|
-
return publicPaths.some((pp) => p === pp || p.startsWith(pp + "/"));
|
|
780
|
-
}
|
|
781
|
-
function mountAuthRoutes(app, accessTokens, publicPaths = []) {
|
|
782
|
-
// POST /_agent-native/auth/login
|
|
692
|
+
function mountTokenOnlyRoutes(app, accessTokens, publicPaths = []) {
|
|
783
693
|
app.use("/_agent-native/auth/login", defineEventHandler(async (event) => {
|
|
784
694
|
if (getMethod(event) !== "POST") {
|
|
785
695
|
setResponseStatus(event, 405);
|
|
786
696
|
return { error: "Method not allowed" };
|
|
787
697
|
}
|
|
788
|
-
const ip = getClientIp(event);
|
|
789
|
-
const rateLimitKey = `login:${ip}`;
|
|
790
|
-
const limited = checkRateLimit(event, rateLimitKey);
|
|
791
|
-
if (limited)
|
|
792
|
-
return limited;
|
|
793
698
|
const body = await readBody(event);
|
|
794
699
|
if (!body?.token ||
|
|
795
700
|
typeof body.token !== "string" ||
|
|
@@ -801,15 +706,13 @@ function mountAuthRoutes(app, accessTokens, publicPaths = []) {
|
|
|
801
706
|
await addSession(sessionToken, "user");
|
|
802
707
|
setCookie(event, COOKIE_NAME, sessionToken, {
|
|
803
708
|
httpOnly: true,
|
|
804
|
-
secure:
|
|
709
|
+
secure: !isDevEnvironment(),
|
|
805
710
|
sameSite: "lax",
|
|
806
711
|
path: "/",
|
|
807
712
|
maxAge: sessionMaxAge,
|
|
808
713
|
});
|
|
809
|
-
resetRateLimit(rateLimitKey);
|
|
810
714
|
return { ok: true };
|
|
811
715
|
}));
|
|
812
|
-
// POST /_agent-native/auth/logout
|
|
813
716
|
app.use("/_agent-native/auth/logout", defineEventHandler(async (event) => {
|
|
814
717
|
const cookie = getCookie(event, COOKIE_NAME);
|
|
815
718
|
if (cookie)
|
|
@@ -817,7 +720,6 @@ function mountAuthRoutes(app, accessTokens, publicPaths = []) {
|
|
|
817
720
|
deleteCookie(event, COOKIE_NAME, { path: "/" });
|
|
818
721
|
return { ok: true };
|
|
819
722
|
}));
|
|
820
|
-
// GET /_agent-native/auth/session — client session check
|
|
821
723
|
app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
|
|
822
724
|
if (getMethod(event) !== "GET") {
|
|
823
725
|
setResponseStatus(event, 405);
|
|
@@ -826,68 +728,205 @@ function mountAuthRoutes(app, accessTokens, publicPaths = []) {
|
|
|
826
728
|
const session = await getSession(event);
|
|
827
729
|
return session ?? { error: "Not authenticated" };
|
|
828
730
|
}));
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
731
|
+
_authGuardConfig = { loginHtml: TOKEN_LOGIN_HTML, publicPaths };
|
|
732
|
+
const guardFn = createAuthGuardFn();
|
|
733
|
+
_authGuardFn = guardFn;
|
|
734
|
+
app.use(defineEventHandler(guardFn));
|
|
735
|
+
}
|
|
736
|
+
// ---------------------------------------------------------------------------
|
|
737
|
+
// mountLocalModeRoutes — stub routes for AUTH_MODE=local
|
|
738
|
+
// ---------------------------------------------------------------------------
|
|
739
|
+
function mountLocalModeRoutes(app) {
|
|
740
|
+
app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
|
|
741
|
+
if (getMethod(event) !== "GET") {
|
|
742
|
+
setResponseStatus(event, 405);
|
|
743
|
+
return { error: "Method not allowed" };
|
|
838
744
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
745
|
+
return await getSession(event);
|
|
746
|
+
}));
|
|
747
|
+
app.use("/_agent-native/auth/login", defineEventHandler(() => ({ ok: true })));
|
|
748
|
+
app.use("/_agent-native/auth/logout", defineEventHandler(() => ({ ok: true })));
|
|
749
|
+
// Allow exiting local mode to switch to real auth
|
|
750
|
+
app.use("/_agent-native/auth/exit-local-mode", defineEventHandler(async (event) => {
|
|
751
|
+
if (getMethod(event) !== "POST") {
|
|
752
|
+
setResponseStatus(event, 405);
|
|
753
|
+
return { error: "Method not allowed" };
|
|
842
754
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
return
|
|
755
|
+
const ok = await removeAuthModeLocal();
|
|
756
|
+
if (!ok) {
|
|
757
|
+
setResponseStatus(event, 500);
|
|
758
|
+
return { error: "Failed to disable local mode" };
|
|
847
759
|
}
|
|
848
|
-
|
|
849
|
-
|
|
760
|
+
return { ok: true };
|
|
761
|
+
}));
|
|
762
|
+
}
|
|
763
|
+
// ---------------------------------------------------------------------------
|
|
764
|
+
// mountAuthFallbackRoutes — minimal auth endpoints when Better Auth init fails
|
|
765
|
+
// ---------------------------------------------------------------------------
|
|
766
|
+
function mountAuthFallbackRoutes(app) {
|
|
767
|
+
app.use("/_agent-native/auth/login", defineEventHandler(async (event) => {
|
|
768
|
+
if (getMethod(event) !== "POST") {
|
|
769
|
+
setResponseStatus(event, 405);
|
|
770
|
+
return { error: "Method not allowed" };
|
|
771
|
+
}
|
|
772
|
+
const body = await readBody(event);
|
|
773
|
+
const email = body?.email?.trim?.()?.toLowerCase?.();
|
|
774
|
+
const password = body?.password;
|
|
775
|
+
if (!email || !password) {
|
|
776
|
+
setResponseStatus(event, 400);
|
|
777
|
+
return { error: "Email and password are required" };
|
|
778
|
+
}
|
|
779
|
+
try {
|
|
780
|
+
const auth = await getBetterAuth();
|
|
781
|
+
const result = await auth.api.signInEmail({
|
|
782
|
+
body: { email, password },
|
|
783
|
+
});
|
|
784
|
+
if (result?.token) {
|
|
785
|
+
setCookie(event, COOKIE_NAME, result.token, {
|
|
786
|
+
httpOnly: true,
|
|
787
|
+
secure: !isDevEnvironment(),
|
|
788
|
+
sameSite: "lax",
|
|
789
|
+
path: "/",
|
|
790
|
+
maxAge: sessionMaxAge,
|
|
791
|
+
});
|
|
792
|
+
await addSession(result.token, email);
|
|
793
|
+
}
|
|
794
|
+
return { ok: true };
|
|
795
|
+
}
|
|
796
|
+
catch (e) {
|
|
850
797
|
setResponseStatus(event, 401);
|
|
851
|
-
return { error: "
|
|
798
|
+
return { error: e?.message || "Invalid email or password" };
|
|
799
|
+
}
|
|
800
|
+
}));
|
|
801
|
+
app.use("/_agent-native/auth/register", defineEventHandler(async (event) => {
|
|
802
|
+
if (getMethod(event) !== "POST") {
|
|
803
|
+
setResponseStatus(event, 405);
|
|
804
|
+
return { error: "Method not allowed" };
|
|
805
|
+
}
|
|
806
|
+
const body = await readBody(event);
|
|
807
|
+
const email = body?.email?.trim?.()?.toLowerCase?.();
|
|
808
|
+
const password = body?.password;
|
|
809
|
+
if (!email || typeof email !== "string" || !email.includes("@")) {
|
|
810
|
+
setResponseStatus(event, 400);
|
|
811
|
+
return { error: "Valid email is required" };
|
|
812
|
+
}
|
|
813
|
+
if (!password || typeof password !== "string" || password.length < 8) {
|
|
814
|
+
setResponseStatus(event, 400);
|
|
815
|
+
return { error: "Password must be at least 8 characters" };
|
|
816
|
+
}
|
|
817
|
+
try {
|
|
818
|
+
const auth = await getBetterAuth();
|
|
819
|
+
await auth.api.signUpEmail({
|
|
820
|
+
body: { email, password, name: email.split("@")[0] },
|
|
821
|
+
});
|
|
822
|
+
return { ok: true };
|
|
823
|
+
}
|
|
824
|
+
catch (e) {
|
|
825
|
+
setResponseStatus(event, 409);
|
|
826
|
+
return { error: e?.message || "Registration failed" };
|
|
852
827
|
}
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
828
|
+
}));
|
|
829
|
+
app.use("/_agent-native/auth/logout", defineEventHandler(async (event) => {
|
|
830
|
+
const cookie = getCookie(event, COOKIE_NAME);
|
|
831
|
+
if (cookie)
|
|
832
|
+
await removeSession(cookie);
|
|
833
|
+
deleteCookie(event, COOKIE_NAME, { path: "/" });
|
|
834
|
+
try {
|
|
835
|
+
const auth = await getBetterAuth();
|
|
836
|
+
await auth.api.signOut({ headers: event.headers });
|
|
837
|
+
}
|
|
838
|
+
catch {
|
|
839
|
+
// Ignore if Better Auth is still unavailable
|
|
840
|
+
}
|
|
841
|
+
return { ok: true };
|
|
842
|
+
}));
|
|
843
|
+
app.use("/_agent-native/auth/local-mode", defineEventHandler(async (event) => {
|
|
844
|
+
if (getMethod(event) !== "POST") {
|
|
845
|
+
setResponseStatus(event, 405);
|
|
846
|
+
return { error: "Method not allowed" };
|
|
847
|
+
}
|
|
848
|
+
if (!isDevEnvironment()) {
|
|
849
|
+
setResponseStatus(event, 403);
|
|
850
|
+
return {
|
|
851
|
+
error: "Local mode is not available in production. Create an account to continue.",
|
|
852
|
+
};
|
|
853
|
+
}
|
|
854
|
+
const ok = await setAuthModeLocal();
|
|
855
|
+
if (!ok) {
|
|
856
|
+
setResponseStatus(event, 500);
|
|
857
|
+
return { error: "Failed to enable local mode" };
|
|
858
|
+
}
|
|
859
|
+
return { ok: true };
|
|
860
|
+
}));
|
|
861
|
+
app.use("/_agent-native/auth/exit-local-mode", defineEventHandler(async (event) => {
|
|
862
|
+
if (getMethod(event) !== "POST") {
|
|
863
|
+
setResponseStatus(event, 405);
|
|
864
|
+
return { error: "Method not allowed" };
|
|
865
|
+
}
|
|
866
|
+
const ok = await removeAuthModeLocal();
|
|
867
|
+
if (!ok) {
|
|
868
|
+
setResponseStatus(event, 500);
|
|
869
|
+
return { error: "Failed to disable local mode" };
|
|
870
|
+
}
|
|
871
|
+
return { ok: true };
|
|
872
|
+
}));
|
|
873
|
+
app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
|
|
874
|
+
if (getMethod(event) !== "GET") {
|
|
875
|
+
setResponseStatus(event, 405);
|
|
876
|
+
return { error: "Method not allowed" };
|
|
877
|
+
}
|
|
878
|
+
const session = await getSession(event);
|
|
879
|
+
return session ?? { error: "Not authenticated" };
|
|
856
880
|
}));
|
|
857
881
|
}
|
|
858
882
|
// ---------------------------------------------------------------------------
|
|
859
883
|
// autoMountAuth — the recommended entry point
|
|
860
884
|
// ---------------------------------------------------------------------------
|
|
861
885
|
/**
|
|
862
|
-
* Automatically configure auth based on
|
|
863
|
-
*
|
|
864
|
-
* - **Dev mode** (`NODE_ENV !== "production"`): Auth is skipped entirely.
|
|
865
|
-
* `getSession()` returns `{ email: "local@localhost" }` for all requests.
|
|
886
|
+
* Automatically configure auth based on environment and configuration:
|
|
866
887
|
*
|
|
867
|
-
* - **
|
|
868
|
-
*
|
|
869
|
-
*
|
|
870
|
-
*
|
|
871
|
-
* - **
|
|
872
|
-
*
|
|
873
|
-
*
|
|
874
|
-
* - **Production with AUTH_DISABLED=true**: Auth is skipped (for apps behind
|
|
875
|
-
* infrastructure-level auth like Cloudflare Access or a VPN).
|
|
888
|
+
* - **AUTH_MODE=local**: Auth bypassed. `getSession()` returns `{ email: "local@localhost" }`.
|
|
889
|
+
* This is the explicit escape hatch for solo local development.
|
|
890
|
+
* - **BYOA (custom getSession)**: Template-provided auth callback handles everything.
|
|
891
|
+
* - **AUTH_DISABLED=true**: Auth bypassed (for infrastructure-level auth like Cloudflare Access).
|
|
892
|
+
* - **ACCESS_TOKEN/ACCESS_TOKENS**: Simple token-based auth.
|
|
893
|
+
* - **Default**: Better Auth with email/password, social providers, organizations, and JWT.
|
|
894
|
+
* Users see an onboarding page to create an account on first visit.
|
|
876
895
|
*
|
|
877
896
|
* Returns true if auth was mounted, false if skipped.
|
|
878
897
|
*/
|
|
879
|
-
export function autoMountAuth(app, options = {}) {
|
|
880
|
-
//
|
|
881
|
-
//
|
|
898
|
+
export async function autoMountAuth(app, options = {}) {
|
|
899
|
+
// If auth is already mounted (e.g., default plugin ran before custom plugin),
|
|
900
|
+
// don't re-mount routes — but DO update the live config if custom options
|
|
901
|
+
// like googleOnly or loginHtml were provided. This fixes the production race
|
|
902
|
+
// where the default plugin (no googleOnly) mounts first, and the template's
|
|
903
|
+
// custom auth plugin runs later. Because createAuthGuardFn() reads from
|
|
904
|
+
// _authGuardConfig on every request, updating it here takes effect immediately.
|
|
905
|
+
if (_authGuardFn) {
|
|
906
|
+
if (_authGuardConfig) {
|
|
907
|
+
if (options.googleOnly || options.loginHtml) {
|
|
908
|
+
_authGuardConfig.loginHtml =
|
|
909
|
+
options.loginHtml ??
|
|
910
|
+
getOnboardingHtml({ googleOnly: options.googleOnly });
|
|
911
|
+
}
|
|
912
|
+
if (options.publicPaths) {
|
|
913
|
+
_authGuardConfig.publicPaths = [
|
|
914
|
+
...(_authGuardConfig.publicPaths ?? []),
|
|
915
|
+
...options.publicPaths,
|
|
916
|
+
];
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return true;
|
|
920
|
+
}
|
|
882
921
|
if (!app) {
|
|
883
|
-
if (
|
|
922
|
+
if ((await isLocalModeEnabled()) || isDevEnvironment()) {
|
|
884
923
|
authDisabledMode = false;
|
|
885
924
|
customGetSession = null;
|
|
886
925
|
return false;
|
|
887
926
|
}
|
|
888
927
|
throw new Error("autoMountAuth: H3 app is required. In Nitro plugins, pass nitroApp.h3App.");
|
|
889
928
|
}
|
|
890
|
-
// Reset globals
|
|
929
|
+
// Reset globals
|
|
891
930
|
customGetSession = null;
|
|
892
931
|
authDisabledMode = false;
|
|
893
932
|
sessionMaxAge = options.maxAge ?? DEFAULT_MAX_AGE;
|
|
@@ -895,24 +934,23 @@ export function autoMountAuth(app, options = {}) {
|
|
|
895
934
|
if (options.getSession) {
|
|
896
935
|
customGetSession = options.getSession;
|
|
897
936
|
}
|
|
898
|
-
//
|
|
899
|
-
if (
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
937
|
+
// AUTH_MODE=local — explicit local-only mode (escape hatch)
|
|
938
|
+
if (await isLocalModeEnabled()) {
|
|
939
|
+
try {
|
|
940
|
+
// Mount the standard auth endpoints and guard even in local mode so the
|
|
941
|
+
// app can switch back to real auth immediately after AUTH_MODE is
|
|
942
|
+
// cleared, without waiting for a server restart/remount.
|
|
943
|
+
await mountBetterAuthRoutes(app, options);
|
|
944
|
+
}
|
|
945
|
+
catch (err) {
|
|
946
|
+
console.error("[agent-native] Failed to initialize Better Auth in local mode:", err);
|
|
947
|
+
mountLocalModeRoutes(app);
|
|
948
|
+
}
|
|
949
|
+
console.log("[agent-native] Auth mode: local (upgrade path enabled).");
|
|
911
950
|
return false;
|
|
912
951
|
}
|
|
913
|
-
// BYOA
|
|
952
|
+
// BYOA — custom getSession provider
|
|
914
953
|
if (customGetSession) {
|
|
915
|
-
// Mount session endpoint
|
|
916
954
|
app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
|
|
917
955
|
if (getMethod(event) !== "GET") {
|
|
918
956
|
setResponseStatus(event, 405);
|
|
@@ -929,65 +967,57 @@ export function autoMountAuth(app, options = {}) {
|
|
|
929
967
|
deleteCookie(event, COOKIE_NAME, { path: "/" });
|
|
930
968
|
return { ok: true };
|
|
931
969
|
}));
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
const p = url.split("?")[0];
|
|
938
|
-
if (p === "/_agent-native/auth/login" ||
|
|
939
|
-
p === "/_agent-native/auth/logout" ||
|
|
940
|
-
p === "/_agent-native/auth/session") {
|
|
941
|
-
return;
|
|
942
|
-
}
|
|
943
|
-
// Skip public paths
|
|
944
|
-
if (isPublicPath(url, publicPaths)) {
|
|
945
|
-
return;
|
|
946
|
-
}
|
|
947
|
-
const session = await getSession(event);
|
|
948
|
-
if (session)
|
|
949
|
-
return;
|
|
950
|
-
if (p.startsWith("/api/") || p.startsWith("/_agent-native/")) {
|
|
951
|
-
setResponseStatus(event, 401);
|
|
952
|
-
return { error: "Unauthorized" };
|
|
953
|
-
}
|
|
954
|
-
setResponseStatus(event, 200);
|
|
955
|
-
setResponseHeader(event, "Content-Type", "text/html");
|
|
956
|
-
return byoaLoginHtml;
|
|
957
|
-
}));
|
|
970
|
+
const byoaLoginHtml = options.loginHtml ?? TOKEN_LOGIN_HTML;
|
|
971
|
+
_authGuardConfig = { loginHtml: byoaLoginHtml, publicPaths };
|
|
972
|
+
const guardFn = createAuthGuardFn();
|
|
973
|
+
_authGuardFn = guardFn;
|
|
974
|
+
app.use(defineEventHandler(guardFn));
|
|
958
975
|
console.log("[agent-native] Auth enabled — custom getSession provider.");
|
|
959
976
|
return true;
|
|
960
977
|
}
|
|
961
|
-
//
|
|
978
|
+
// AUTH_DISABLED — skip auth (infrastructure-level auth)
|
|
979
|
+
if (process.env.AUTH_DISABLED === "true") {
|
|
980
|
+
authDisabledMode = true;
|
|
981
|
+
console.warn("[agent-native] AUTH_DISABLED=true — running without auth. " +
|
|
982
|
+
"Ensure this app is behind infrastructure-level auth (Cloudflare Access, VPN, etc.).");
|
|
983
|
+
mountLocalModeRoutes(app);
|
|
984
|
+
return false;
|
|
985
|
+
}
|
|
986
|
+
// ACCESS_TOKEN-only mode
|
|
962
987
|
const tokens = getAccessTokens();
|
|
963
|
-
if (tokens.length
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
authDisabledMode = true;
|
|
967
|
-
console.warn("[agent-native] AUTH_DISABLED=true — running in production without auth. " +
|
|
968
|
-
"Ensure this app is behind infrastructure-level auth (Cloudflare Access, VPN, etc.).");
|
|
969
|
-
// Mount session endpoint
|
|
970
|
-
app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
|
|
971
|
-
if (getMethod(event) !== "GET") {
|
|
972
|
-
setResponseStatus(event, 405);
|
|
973
|
-
return { error: "Method not allowed" };
|
|
974
|
-
}
|
|
975
|
-
return await getSession(event);
|
|
976
|
-
}));
|
|
977
|
-
app.use("/_agent-native/auth/login", defineEventHandler(() => ({ ok: true })));
|
|
978
|
-
app.use("/_agent-native/auth/logout", defineEventHandler(() => ({ ok: true })));
|
|
979
|
-
return false;
|
|
980
|
-
}
|
|
981
|
-
// No access tokens set — enable email/password authentication
|
|
982
|
-
pruneExpiredSessions().catch(() => { });
|
|
983
|
-
mountEmailAuthRoutes(app, publicPaths);
|
|
984
|
-
console.log("[agent-native] Auth enabled — email/password authentication.");
|
|
988
|
+
if (tokens.length > 0) {
|
|
989
|
+
mountTokenOnlyRoutes(app, tokens, publicPaths);
|
|
990
|
+
console.log(`[agent-native] Auth enabled — ${tokens.length} access token(s) configured.`);
|
|
985
991
|
return true;
|
|
986
992
|
}
|
|
987
|
-
//
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
993
|
+
// Default: Better Auth (account-first)
|
|
994
|
+
try {
|
|
995
|
+
await mountBetterAuthRoutes(app, options);
|
|
996
|
+
console.log("[agent-native] Auth enabled — Better Auth (accounts + organizations).");
|
|
997
|
+
}
|
|
998
|
+
catch (err) {
|
|
999
|
+
console.error("[agent-native] Failed to initialize Better Auth:", err);
|
|
1000
|
+
mountAuthFallbackRoutes(app);
|
|
1001
|
+
// CRITICAL: Even if Better Auth fails, register the auth guard so
|
|
1002
|
+
// unauthenticated users can't access the app. They'll see the login
|
|
1003
|
+
// page but won't be able to sign in until the DB is available.
|
|
1004
|
+
const loginHtml = options.loginHtml ??
|
|
1005
|
+
getOnboardingHtml({ googleOnly: options.googleOnly });
|
|
1006
|
+
_authGuardConfig = { loginHtml, publicPaths };
|
|
1007
|
+
const guardFn = createAuthGuardFn();
|
|
1008
|
+
_authGuardFn = guardFn;
|
|
1009
|
+
app.use(defineEventHandler(guardFn));
|
|
1010
|
+
console.log("[agent-native] Auth guard registered despite init failure — app is locked.");
|
|
1011
|
+
}
|
|
991
1012
|
return true;
|
|
992
1013
|
}
|
|
1014
|
+
// ---------------------------------------------------------------------------
|
|
1015
|
+
// Deprecated — kept for backward compat
|
|
1016
|
+
// ---------------------------------------------------------------------------
|
|
1017
|
+
/**
|
|
1018
|
+
* @deprecated Use `autoMountAuth(app, options?)` instead.
|
|
1019
|
+
*/
|
|
1020
|
+
export function mountAuthMiddleware(app, accessToken) {
|
|
1021
|
+
mountTokenOnlyRoutes(app, [accessToken]);
|
|
1022
|
+
}
|
|
993
1023
|
//# sourceMappingURL=auth.js.map
|