@agent-native/core 0.7.14 → 0.7.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -6
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +149 -24
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +166 -51
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/task-store.d.ts +10 -1
- package/dist/a2a/task-store.d.ts.map +1 -1
- package/dist/a2a/task-store.js +36 -2
- package/dist/a2a/task-store.js.map +1 -1
- package/dist/agent/default-model.d.ts +21 -0
- package/dist/agent/default-model.d.ts.map +1 -0
- package/dist/agent/default-model.js +21 -0
- package/dist/agent/default-model.js.map +1 -0
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +7 -4
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +10 -4
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +4 -1
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/engine/builtin.js +1 -1
- package/dist/agent/engine/builtin.js.map +1 -1
- package/dist/agent/engine/registry.d.ts +27 -7
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +101 -20
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +1 -0
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/production-agent.d.ts +25 -3
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +227 -36
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/application-state/handlers.d.ts.map +1 -1
- package/dist/application-state/handlers.js +10 -6
- package/dist/application-state/handlers.js.map +1 -1
- package/dist/application-state/script-helpers.d.ts +1 -1
- package/dist/application-state/script-helpers.d.ts.map +1 -1
- package/dist/application-state/script-helpers.js +12 -8
- package/dist/application-state/script-helpers.js.map +1 -1
- package/dist/application-state/store.d.ts.map +1 -1
- package/dist/application-state/store.js +19 -10
- package/dist/application-state/store.js.map +1 -1
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +4 -1
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +79 -13
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +97 -39
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/templates-meta.d.ts +4 -0
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +56 -12
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/cli/workspacify.d.ts +2 -0
- package/dist/cli/workspacify.d.ts.map +1 -1
- package/dist/cli/workspacify.js +5 -4
- package/dist/cli/workspacify.js.map +1 -1
- package/dist/client/AgentPanel.d.ts +5 -2
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +61 -23
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AgentTaskCard.d.ts.map +1 -1
- package/dist/client/AgentTaskCard.js +3 -2
- package/dist/client/AgentTaskCard.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +79 -16
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
- package/dist/client/ConnectBuilderCard.js +2 -1
- package/dist/client/ConnectBuilderCard.js.map +1 -1
- package/dist/client/DefaultSpinner.d.ts +1 -1
- package/dist/client/DefaultSpinner.d.ts.map +1 -1
- package/dist/client/DefaultSpinner.js +2 -9
- package/dist/client/DefaultSpinner.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +20 -19
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +2 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +3 -1
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +70 -1
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/api-path.d.ts +5 -0
- package/dist/client/api-path.d.ts.map +1 -0
- package/dist/client/api-path.js +48 -0
- package/dist/client/api-path.js.map +1 -0
- package/dist/client/components/ApiKeySettings.d.ts.map +1 -1
- package/dist/client/components/ApiKeySettings.js +3 -2
- package/dist/client/components/ApiKeySettings.js.map +1 -1
- package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
- package/dist/client/components/CodeRequiredDialog.js +3 -2
- package/dist/client/components/CodeRequiredDialog.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +3 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +9 -8
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/draft-key.d.ts +2 -0
- package/dist/client/composer/draft-key.d.ts.map +1 -0
- package/dist/client/composer/draft-key.js +8 -0
- package/dist/client/composer/draft-key.js.map +1 -0
- package/dist/client/composer/use-file-search.d.ts.map +1 -1
- package/dist/client/composer/use-file-search.js +2 -1
- package/dist/client/composer/use-file-search.js.map +1 -1
- package/dist/client/composer/use-mention-search.d.ts.map +1 -1
- package/dist/client/composer/use-mention-search.js +2 -1
- package/dist/client/composer/use-mention-search.js.map +1 -1
- package/dist/client/composer/use-skills.d.ts.map +1 -1
- package/dist/client/composer/use-skills.js +2 -1
- package/dist/client/composer/use-skills.js.map +1 -1
- package/dist/client/composer/useVoiceDictation.d.ts +1 -1
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
- package/dist/client/composer/useVoiceDictation.js +16 -8
- package/dist/client/composer/useVoiceDictation.js.map +1 -1
- package/dist/client/dev-mode.d.ts +14 -0
- package/dist/client/dev-mode.d.ts.map +1 -0
- package/dist/client/dev-mode.js +14 -0
- package/dist/client/dev-mode.js.map +1 -0
- package/dist/client/dev-overlay/DevOverlay.d.ts +26 -0
- package/dist/client/dev-overlay/DevOverlay.d.ts.map +1 -0
- package/dist/client/dev-overlay/DevOverlay.js +315 -0
- package/dist/client/dev-overlay/DevOverlay.js.map +1 -0
- package/dist/client/dev-overlay/builtins.d.ts +6 -0
- package/dist/client/dev-overlay/builtins.d.ts.map +1 -0
- package/dist/client/dev-overlay/builtins.js +35 -0
- package/dist/client/dev-overlay/builtins.js.map +1 -0
- package/dist/client/dev-overlay/index.d.ts +6 -0
- package/dist/client/dev-overlay/index.d.ts.map +1 -0
- package/dist/client/dev-overlay/index.js +5 -0
- package/dist/client/dev-overlay/index.js.map +1 -0
- package/dist/client/dev-overlay/registry.d.ts +13 -0
- package/dist/client/dev-overlay/registry.d.ts.map +1 -0
- package/dist/client/dev-overlay/registry.js +63 -0
- package/dist/client/dev-overlay/registry.js.map +1 -0
- package/dist/client/dev-overlay/types.d.ts +56 -0
- package/dist/client/dev-overlay/types.d.ts.map +1 -0
- package/dist/client/dev-overlay/types.js +9 -0
- package/dist/client/dev-overlay/types.js.map +1 -0
- package/dist/client/dev-overlay/use-dev-option.d.ts +12 -0
- package/dist/client/dev-overlay/use-dev-option.d.ts.map +1 -0
- package/dist/client/dev-overlay/use-dev-option.js +73 -0
- package/dist/client/dev-overlay/use-dev-option.js.map +1 -0
- package/dist/client/dev-overlay/use-dev-overlay-shortcut.d.ts +6 -0
- package/dist/client/dev-overlay/use-dev-overlay-shortcut.d.ts.map +1 -0
- package/dist/client/dev-overlay/use-dev-overlay-shortcut.js +29 -0
- package/dist/client/dev-overlay/use-dev-overlay-shortcut.js.map +1 -0
- package/dist/client/frame.d.ts +1 -0
- package/dist/client/frame.d.ts.map +1 -1
- package/dist/client/frame.js +32 -11
- package/dist/client/frame.js.map +1 -1
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +4 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/IntegrationCard.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationCard.js +3 -2
- package/dist/client/integrations/IntegrationCard.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +3 -2
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/integrations/useIntegrationStatus.d.ts.map +1 -1
- package/dist/client/integrations/useIntegrationStatus.js +2 -1
- package/dist/client/integrations/useIntegrationStatus.js.map +1 -1
- package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
- package/dist/client/notifications/NotificationsBell.js +26 -8
- package/dist/client/notifications/NotificationsBell.js.map +1 -1
- package/dist/client/observability/ThumbsFeedback.d.ts.map +1 -1
- package/dist/client/observability/ThumbsFeedback.js +2 -1
- package/dist/client/observability/ThumbsFeedback.js.map +1 -1
- package/dist/client/observability/useObservability.d.ts.map +1 -1
- package/dist/client/observability/useObservability.js +2 -1
- package/dist/client/observability/useObservability.js.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.d.ts +0 -7
- package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.js +20 -10
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/onboarding/index.d.ts +1 -0
- package/dist/client/onboarding/index.d.ts.map +1 -1
- package/dist/client/onboarding/index.js +1 -0
- package/dist/client/onboarding/index.js.map +1 -1
- package/dist/client/onboarding/use-onboarding.d.ts +1 -7
- package/dist/client/onboarding/use-onboarding.d.ts.map +1 -1
- package/dist/client/onboarding/use-onboarding.js +27 -13
- package/dist/client/onboarding/use-onboarding.js.map +1 -1
- package/dist/client/onboarding/use-preview-mode.d.ts +10 -0
- package/dist/client/onboarding/use-preview-mode.d.ts.map +1 -0
- package/dist/client/onboarding/use-preview-mode.js +35 -0
- package/dist/client/onboarding/use-preview-mode.js.map +1 -0
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +2 -1
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +7 -5
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/org/hooks.d.ts.map +1 -1
- package/dist/client/org/hooks.js +2 -1
- package/dist/client/org/hooks.js.map +1 -1
- package/dist/client/progress/RunsTray.d.ts.map +1 -1
- package/dist/client/progress/RunsTray.js +2 -1
- package/dist/client/progress/RunsTray.js.map +1 -1
- package/dist/client/resources/McpServerDetail.d.ts +0 -8
- package/dist/client/resources/McpServerDetail.d.ts.map +1 -1
- package/dist/client/resources/McpServerDetail.js +6 -1
- package/dist/client/resources/McpServerDetail.js.map +1 -1
- package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
- package/dist/client/resources/ResourceEditor.js +2 -1
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +2 -1
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-mcp-servers.d.ts.map +1 -1
- package/dist/client/resources/use-mcp-servers.js +7 -2
- package/dist/client/resources/use-mcp-servers.js.map +1 -1
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js +9 -7
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts.map +1 -1
- package/dist/client/settings/AgentsSection.js +7 -5
- package/dist/client/settings/AgentsSection.js.map +1 -1
- package/dist/client/settings/AutomationsSection.d.ts.map +1 -1
- package/dist/client/settings/AutomationsSection.js +9 -5
- package/dist/client/settings/AutomationsSection.js.map +1 -1
- package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -1
- package/dist/client/settings/BackgroundAgentSection.js +2 -1
- package/dist/client/settings/BackgroundAgentSection.js.map +1 -1
- package/dist/client/settings/SecretsSection.d.ts.map +1 -1
- package/dist/client/settings/SecretsSection.js +12 -4
- package/dist/client/settings/SecretsSection.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +15 -23
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/UsageSection.d.ts.map +1 -1
- package/dist/client/settings/UsageSection.js +2 -1
- package/dist/client/settings/UsageSection.js.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.d.ts +2 -4
- package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.js +66 -23
- package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +9 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +31 -3
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +7 -2
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
- package/dist/client/sharing/ShareDialog.js +4 -3
- package/dist/client/sharing/ShareDialog.js.map +1 -1
- package/dist/client/terminal/AgentTerminal.d.ts +1 -0
- package/dist/client/terminal/AgentTerminal.d.ts.map +1 -1
- package/dist/client/terminal/AgentTerminal.js +12 -8
- package/dist/client/terminal/AgentTerminal.js.map +1 -1
- package/dist/client/tools/EmbeddedTool.d.ts +20 -0
- package/dist/client/tools/EmbeddedTool.d.ts.map +1 -0
- package/dist/client/tools/EmbeddedTool.js +113 -0
- package/dist/client/tools/EmbeddedTool.js.map +1 -0
- package/dist/client/tools/ExtensionSlot.d.ts +27 -0
- package/dist/client/tools/ExtensionSlot.d.ts.map +1 -0
- package/dist/client/tools/ExtensionSlot.js +96 -0
- package/dist/client/tools/ExtensionSlot.js.map +1 -0
- package/dist/client/tools/ToolEditor.d.ts.map +1 -1
- package/dist/client/tools/ToolEditor.js +5 -4
- package/dist/client/tools/ToolEditor.js.map +1 -1
- package/dist/client/tools/ToolViewer.d.ts.map +1 -1
- package/dist/client/tools/ToolViewer.js +10 -44
- package/dist/client/tools/ToolViewer.js.map +1 -1
- package/dist/client/tools/ToolViewerPage.d.ts.map +1 -1
- package/dist/client/tools/ToolViewerPage.js +2 -1
- package/dist/client/tools/ToolViewerPage.js.map +1 -1
- package/dist/client/tools/ToolsListPage.d.ts.map +1 -1
- package/dist/client/tools/ToolsListPage.js +3 -2
- package/dist/client/tools/ToolsListPage.js.map +1 -1
- package/dist/client/tools/ToolsSidebarSection.d.ts.map +1 -1
- package/dist/client/tools/ToolsSidebarSection.js +4 -3
- package/dist/client/tools/ToolsSidebarSection.js.map +1 -1
- package/dist/client/tools/iframe-bridge.d.ts +16 -0
- package/dist/client/tools/iframe-bridge.d.ts.map +1 -0
- package/dist/client/tools/iframe-bridge.js +118 -0
- package/dist/client/tools/iframe-bridge.js.map +1 -0
- package/dist/client/tools/index.d.ts +2 -0
- package/dist/client/tools/index.d.ts.map +1 -1
- package/dist/client/tools/index.js +2 -0
- package/dist/client/tools/index.js.map +1 -1
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +2 -1
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/use-avatar.d.ts.map +1 -1
- package/dist/client/use-avatar.js +3 -2
- package/dist/client/use-avatar.js.map +1 -1
- package/dist/client/use-builder-enabled.d.ts.map +1 -1
- package/dist/client/use-builder-enabled.js +2 -1
- package/dist/client/use-builder-enabled.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +2 -1
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +3 -2
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/client/use-dev-mode.d.ts.map +1 -1
- package/dist/client/use-dev-mode.js +2 -1
- package/dist/client/use-dev-mode.js.map +1 -1
- package/dist/client/use-send-to-agent-chat.d.ts.map +1 -1
- package/dist/client/use-send-to-agent-chat.js +3 -1
- package/dist/client/use-send-to-agent-chat.js.map +1 -1
- package/dist/client/use-session.d.ts.map +1 -1
- package/dist/client/use-session.js +2 -1
- package/dist/client/use-session.js.map +1 -1
- package/dist/client/useProductionAgent.d.ts.map +1 -1
- package/dist/client/useProductionAgent.js +2 -1
- package/dist/client/useProductionAgent.js.map +1 -1
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +3 -2
- package/dist/collab/client.js.map +1 -1
- package/dist/credentials/index.d.ts +27 -10
- package/dist/credentials/index.d.ts.map +1 -1
- package/dist/credentials/index.js +61 -19
- package/dist/credentials/index.js.map +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +10 -1
- package/dist/db/client.js.map +1 -1
- package/dist/db/migrations.d.ts +13 -5
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +9 -2
- package/dist/db/migrations.js.map +1 -1
- package/dist/deploy/build.d.ts +12 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +195 -23
- package/dist/deploy/build.js.map +1 -1
- package/dist/file-upload/registry.d.ts.map +1 -1
- package/dist/file-upload/registry.js +25 -1
- package/dist/file-upload/registry.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/adapters/email.d.ts.map +1 -1
- package/dist/integrations/adapters/email.js +152 -32
- package/dist/integrations/adapters/email.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +190 -32
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/adapters/telegram.d.ts.map +1 -1
- package/dist/integrations/adapters/telegram.js +37 -2
- package/dist/integrations/adapters/telegram.js.map +1 -1
- package/dist/integrations/adapters/whatsapp.d.ts.map +1 -1
- package/dist/integrations/adapters/whatsapp.js +91 -12
- package/dist/integrations/adapters/whatsapp.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts.map +1 -1
- package/dist/integrations/google-docs-poller.js +5 -2
- package/dist/integrations/google-docs-poller.js.map +1 -1
- package/dist/integrations/internal-token.d.ts.map +1 -1
- package/dist/integrations/internal-token.js +17 -1
- package/dist/integrations/internal-token.js.map +1 -1
- package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
- package/dist/integrations/pending-tasks-retry-job.js +18 -7
- package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
- package/dist/integrations/pending-tasks-store.d.ts +16 -0
- package/dist/integrations/pending-tasks-store.d.ts.map +1 -1
- package/dist/integrations/pending-tasks-store.js +58 -5
- package/dist/integrations/pending-tasks-store.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +198 -15
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/types.d.ts +33 -2
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.d.ts +6 -0
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +141 -61
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/cron.d.ts.map +1 -1
- package/dist/jobs/cron.js +12 -4
- package/dist/jobs/cron.js.map +1 -1
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +141 -16
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/jobs/tools.d.ts.map +1 -1
- package/dist/jobs/tools.js +94 -3
- package/dist/jobs/tools.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +128 -62
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp-client/hub-routes.d.ts +14 -0
- package/dist/mcp-client/hub-routes.d.ts.map +1 -1
- package/dist/mcp-client/hub-routes.js +42 -2
- package/dist/mcp-client/hub-routes.js.map +1 -1
- package/dist/mcp-client/index.d.ts +1 -1
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +1 -1
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/mcp-client/manager.d.ts.map +1 -1
- package/dist/mcp-client/manager.js +28 -3
- package/dist/mcp-client/manager.js.map +1 -1
- package/dist/mcp-client/remote-store.d.ts +49 -1
- package/dist/mcp-client/remote-store.d.ts.map +1 -1
- package/dist/mcp-client/remote-store.js +253 -6
- package/dist/mcp-client/remote-store.js.map +1 -1
- package/dist/mcp-client/routes.d.ts.map +1 -1
- package/dist/mcp-client/routes.js +11 -9
- package/dist/mcp-client/routes.js.map +1 -1
- package/dist/mcp-client/visibility.d.ts +7 -3
- package/dist/mcp-client/visibility.d.ts.map +1 -1
- package/dist/mcp-client/visibility.js +16 -7
- package/dist/mcp-client/visibility.js.map +1 -1
- package/dist/notifications/actions.d.ts.map +1 -1
- package/dist/notifications/actions.js +7 -1
- package/dist/notifications/actions.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/notifications/routes.d.ts.map +1 -1
- package/dist/notifications/routes.js +20 -3
- package/dist/notifications/routes.js.map +1 -1
- package/dist/notifications/store.d.ts.map +1 -1
- package/dist/notifications/store.js +6 -1
- package/dist/notifications/store.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts +43 -2
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +83 -14
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/observability/experiments.js +5 -5
- package/dist/observability/experiments.js.map +1 -1
- package/dist/observability/routes.d.ts.map +1 -1
- package/dist/observability/routes.js +37 -8
- package/dist/observability/routes.js.map +1 -1
- package/dist/observability/store.d.ts.map +1 -1
- package/dist/observability/store.js +19 -3
- package/dist/observability/store.js.map +1 -1
- package/dist/observability/types.d.ts +7 -0
- package/dist/observability/types.d.ts.map +1 -1
- package/dist/observability/types.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts.map +1 -1
- package/dist/onboarding/default-steps.js +1 -2
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/onboarding/plugin.d.ts.map +1 -1
- package/dist/onboarding/plugin.js +63 -32
- package/dist/onboarding/plugin.js.map +1 -1
- package/dist/onboarding/types.d.ts +6 -1
- package/dist/onboarding/types.d.ts.map +1 -1
- package/dist/org/accept-pending.d.ts.map +1 -1
- package/dist/org/accept-pending.js +2 -1
- package/dist/org/accept-pending.js.map +1 -1
- package/dist/progress/actions.d.ts.map +1 -1
- package/dist/progress/actions.js +10 -1
- package/dist/progress/actions.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/progress/routes.d.ts.map +1 -1
- package/dist/progress/routes.js +20 -3
- package/dist/progress/routes.js.map +1 -1
- package/dist/progress/store.d.ts.map +1 -1
- package/dist/progress/store.js +6 -1
- package/dist/progress/store.js.map +1 -1
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +35 -7
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/script-helpers.d.ts.map +1 -1
- package/dist/resources/script-helpers.js +15 -3
- package/dist/resources/script-helpers.js.map +1 -1
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +12 -4
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/call-agent.d.ts +1 -0
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +78 -40
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/scripts/chat/search-chats.d.ts.map +1 -1
- package/dist/scripts/chat/search-chats.js +3 -2
- package/dist/scripts/chat/search-chats.js.map +1 -1
- package/dist/scripts/db/exec.d.ts +1 -1
- package/dist/scripts/db/exec.d.ts.map +1 -1
- package/dist/scripts/db/exec.js +22 -3
- package/dist/scripts/db/exec.js.map +1 -1
- package/dist/scripts/db/migrate-user-api-keys.d.ts.map +1 -1
- package/dist/scripts/db/migrate-user-api-keys.js +10 -0
- package/dist/scripts/db/migrate-user-api-keys.js.map +1 -1
- package/dist/scripts/db/query.d.ts +1 -1
- package/dist/scripts/db/query.d.ts.map +1 -1
- package/dist/scripts/db/query.js +22 -3
- package/dist/scripts/db/query.js.map +1 -1
- package/dist/scripts/db/scoping.d.ts.map +1 -1
- package/dist/scripts/db/scoping.js +15 -9
- package/dist/scripts/db/scoping.js.map +1 -1
- package/dist/scripts/dev/shell.d.ts.map +1 -1
- package/dist/scripts/dev/shell.js +3 -1
- package/dist/scripts/dev/shell.js.map +1 -1
- package/dist/scripts/resources/delete-memory.d.ts.map +1 -1
- package/dist/scripts/resources/delete-memory.js +2 -1
- package/dist/scripts/resources/delete-memory.js.map +1 -1
- package/dist/scripts/resources/delete.d.ts.map +1 -1
- package/dist/scripts/resources/delete.js +2 -1
- package/dist/scripts/resources/delete.js.map +1 -1
- package/dist/scripts/resources/list.d.ts.map +1 -1
- package/dist/scripts/resources/list.js +2 -1
- package/dist/scripts/resources/list.js.map +1 -1
- package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
- package/dist/scripts/resources/migrate-learnings.js +2 -1
- package/dist/scripts/resources/migrate-learnings.js.map +1 -1
- package/dist/scripts/resources/read.d.ts.map +1 -1
- package/dist/scripts/resources/read.js +2 -1
- package/dist/scripts/resources/read.js.map +1 -1
- package/dist/scripts/resources/save-memory.d.ts.map +1 -1
- package/dist/scripts/resources/save-memory.js +2 -1
- package/dist/scripts/resources/save-memory.js.map +1 -1
- package/dist/scripts/resources/write.d.ts.map +1 -1
- package/dist/scripts/resources/write.js +2 -1
- package/dist/scripts/resources/write.js.map +1 -1
- package/dist/secrets/onboarding.d.ts.map +1 -1
- package/dist/secrets/onboarding.js +24 -16
- package/dist/secrets/onboarding.js.map +1 -1
- package/dist/secrets/routes.d.ts.map +1 -1
- package/dist/secrets/routes.js +139 -37
- package/dist/secrets/routes.js.map +1 -1
- package/dist/secrets/storage.d.ts.map +1 -1
- package/dist/secrets/storage.js +23 -12
- package/dist/secrets/storage.js.map +1 -1
- package/dist/secrets/substitution.d.ts +24 -2
- package/dist/secrets/substitution.d.ts.map +1 -1
- package/dist/secrets/substitution.js +44 -6
- package/dist/secrets/substitution.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +15 -51
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +42 -15
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +447 -335
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts +8 -0
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +39 -12
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +4 -1
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/analytics.d.ts +0 -1
- package/dist/server/analytics.d.ts.map +1 -1
- package/dist/server/analytics.js +0 -1
- package/dist/server/analytics.js.map +1 -1
- package/dist/server/app-base-path.d.ts +4 -0
- package/dist/server/app-base-path.d.ts.map +1 -0
- package/dist/server/app-base-path.js +33 -0
- package/dist/server/app-base-path.js.map +1 -0
- package/dist/server/auth.d.ts +15 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +400 -68
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +1 -0
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +67 -15
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts +15 -0
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +90 -4
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/cli-capture.d.ts +31 -0
- package/dist/server/cli-capture.d.ts.map +1 -0
- package/dist/server/cli-capture.js +120 -0
- package/dist/server/cli-capture.js.map +1 -0
- package/dist/server/collab-plugin.d.ts +12 -0
- package/dist/server/collab-plugin.d.ts.map +1 -1
- package/dist/server/collab-plugin.js +63 -21
- package/dist/server/collab-plugin.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +435 -106
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/create-server.d.ts +2 -0
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +82 -11
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/credential-provider.d.ts +11 -0
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +51 -2
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/csrf.d.ts +58 -0
- package/dist/server/csrf.d.ts.map +1 -0
- package/dist/server/csrf.js +165 -0
- package/dist/server/csrf.js.map +1 -0
- package/dist/server/framework-request-handler.d.ts +20 -0
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +115 -34
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-auth-plugin.d.ts.map +1 -1
- package/dist/server/google-auth-plugin.js +10 -2
- package/dist/server/google-auth-plugin.js.map +1 -1
- package/dist/server/google-oauth.d.ts +84 -2
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +248 -45
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/index.d.ts +4 -4
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +4 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/oauth-helpers.d.ts +8 -3
- package/dist/server/oauth-helpers.d.ts.map +1 -1
- package/dist/server/oauth-helpers.js +12 -8
- package/dist/server/oauth-helpers.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +37 -9
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/poll.d.ts +33 -0
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +43 -2
- package/dist/server/poll.js.map +1 -1
- package/dist/server/request-context.d.ts +102 -3
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +100 -7
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/security-headers.d.ts +51 -0
- package/dist/server/security-headers.d.ts.map +1 -0
- package/dist/server/security-headers.js +90 -0
- package/dist/server/security-headers.js.map +1 -0
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +96 -2
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +307 -56
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/server/voice-providers-status.d.ts +12 -0
- package/dist/server/voice-providers-status.d.ts.map +1 -0
- package/dist/server/voice-providers-status.js +71 -0
- package/dist/server/voice-providers-status.js.map +1 -0
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +16 -13
- package/dist/sharing/access.js.map +1 -1
- package/dist/sharing/actions/share-resource.d.ts +1 -0
- package/dist/sharing/actions/share-resource.d.ts.map +1 -1
- package/dist/sharing/actions/share-resource.js +45 -0
- package/dist/sharing/actions/share-resource.js.map +1 -1
- package/dist/templates/default/.agents/skills/delegate-to-agent/SKILL.md +54 -0
- package/dist/templates/default/app/root.tsx +1 -1
- package/dist/templates/default/app/routes/_index.tsx +6 -1
- package/dist/templates/default/public/favicon.svg +13 -0
- package/dist/templates/default/public/icon-180.svg +12 -3
- package/dist/templates/default/public/icon-192.svg +12 -3
- package/dist/templates/default/public/icon-512.svg +12 -3
- package/dist/templates/workspace-core/package.json +22 -4
- package/dist/templates/workspace-core/src/credentials.ts +32 -5
- package/dist/templates/workspace-core/tsconfig.json +4 -1
- package/dist/terminal/pty-server.d.ts.map +1 -1
- package/dist/terminal/pty-server.js +7 -1
- package/dist/terminal/pty-server.js.map +1 -1
- package/dist/terminal/terminal-plugin.js +3 -3
- package/dist/terminal/terminal-plugin.js.map +1 -1
- package/dist/tools/actions.d.ts.map +1 -1
- package/dist/tools/actions.js +130 -0
- package/dist/tools/actions.js.map +1 -1
- package/dist/tools/fetch-tool.d.ts +1 -0
- package/dist/tools/fetch-tool.d.ts.map +1 -1
- package/dist/tools/fetch-tool.js +38 -16
- package/dist/tools/fetch-tool.js.map +1 -1
- package/dist/tools/html-shell.d.ts +43 -1
- package/dist/tools/html-shell.d.ts.map +1 -1
- package/dist/tools/html-shell.js +102 -4
- package/dist/tools/html-shell.js.map +1 -1
- package/dist/tools/proxy-security.d.ts +12 -0
- package/dist/tools/proxy-security.d.ts.map +1 -0
- package/dist/tools/proxy-security.js +158 -0
- package/dist/tools/proxy-security.js.map +1 -0
- package/dist/tools/routes.d.ts.map +1 -1
- package/dist/tools/routes.js +158 -105
- package/dist/tools/routes.js.map +1 -1
- package/dist/tools/schema.d.ts +3 -0
- package/dist/tools/schema.d.ts.map +1 -1
- package/dist/tools/schema.js +3 -0
- package/dist/tools/schema.js.map +1 -1
- package/dist/tools/slots/routes.d.ts +15 -0
- package/dist/tools/slots/routes.d.ts.map +1 -0
- package/dist/tools/slots/routes.js +94 -0
- package/dist/tools/slots/routes.js.map +1 -0
- package/dist/tools/slots/schema.d.ts +303 -0
- package/dist/tools/slots/schema.d.ts.map +1 -0
- package/dist/tools/slots/schema.js +76 -0
- package/dist/tools/slots/schema.js.map +1 -0
- package/dist/tools/slots/store.d.ts +66 -0
- package/dist/tools/slots/store.d.ts.map +1 -0
- package/dist/tools/slots/store.js +227 -0
- package/dist/tools/slots/store.js.map +1 -0
- package/dist/tools/store.d.ts.map +1 -1
- package/dist/tools/store.js +28 -37
- package/dist/tools/store.js.map +1 -1
- package/dist/tools/url-safety.d.ts +24 -0
- package/dist/tools/url-safety.d.ts.map +1 -0
- package/dist/tools/url-safety.js +224 -0
- package/dist/tools/url-safety.js.map +1 -0
- package/dist/tracking/providers.d.ts.map +1 -1
- package/dist/tracking/providers.js +28 -11
- package/dist/tracking/providers.js.map +1 -1
- package/dist/tracking/registry.d.ts.map +1 -1
- package/dist/tracking/registry.js +7 -3
- package/dist/tracking/registry.js.map +1 -1
- package/dist/triggers/actions.d.ts.map +1 -1
- package/dist/triggers/actions.js +11 -6
- package/dist/triggers/actions.js.map +1 -1
- package/dist/triggers/condition-evaluator.d.ts +8 -0
- package/dist/triggers/condition-evaluator.d.ts.map +1 -1
- package/dist/triggers/condition-evaluator.js +39 -4
- package/dist/triggers/condition-evaluator.js.map +1 -1
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +67 -4
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +8 -5
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/dist/vite/client.d.ts +2 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +216 -4
- package/dist/vite/client.js.map +1 -1
- package/docs/content/authentication.md +27 -12
- package/docs/content/drop-in-agent.md +2 -2
- package/docs/content/messaging.md +195 -155
- package/docs/content/onboarding.md +82 -12
- package/docs/content/template-analytics.md +65 -59
- package/docs/content/template-clips.md +7 -9
- package/docs/content/template-design.md +55 -0
- package/docs/content/template-dispatch.md +13 -0
- package/docs/content/template-forms.md +7 -6
- package/docs/content/template-mail.md +78 -80
- package/package.json +2 -1
- package/src/templates/default/.agents/skills/delegate-to-agent/SKILL.md +54 -0
- package/src/templates/default/app/root.tsx +1 -1
- package/src/templates/default/app/routes/_index.tsx +6 -1
- package/src/templates/default/public/favicon.svg +13 -0
- package/src/templates/default/public/icon-180.svg +12 -3
- package/src/templates/default/public/icon-192.svg +12 -3
- package/src/templates/default/public/icon-512.svg +12 -3
- package/src/templates/workspace-core/package.json +22 -4
- package/src/templates/workspace-core/src/credentials.ts +32 -5
- package/src/templates/workspace-core/tsconfig.json +4 -1
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
const HEADER_NAME_RE = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
2
|
+
const BLOCKED_OUTBOUND_HEADERS = new Set([
|
|
3
|
+
"connection",
|
|
4
|
+
"content-length",
|
|
5
|
+
"cookie",
|
|
6
|
+
"forwarded",
|
|
7
|
+
"host",
|
|
8
|
+
"keep-alive",
|
|
9
|
+
"origin",
|
|
10
|
+
"proxy-authenticate",
|
|
11
|
+
"proxy-authorization",
|
|
12
|
+
"referer",
|
|
13
|
+
"set-cookie",
|
|
14
|
+
"te",
|
|
15
|
+
"trailer",
|
|
16
|
+
"transfer-encoding",
|
|
17
|
+
"upgrade",
|
|
18
|
+
"x-forwarded-for",
|
|
19
|
+
"x-forwarded-host",
|
|
20
|
+
"x-forwarded-proto",
|
|
21
|
+
]);
|
|
22
|
+
export const MAX_TOOL_PROXY_RESPONSE_SIZE = 1024 * 1024;
|
|
23
|
+
const ALLOWED_METHODS = new Set([
|
|
24
|
+
"GET",
|
|
25
|
+
"POST",
|
|
26
|
+
"PUT",
|
|
27
|
+
"PATCH",
|
|
28
|
+
"DELETE",
|
|
29
|
+
"HEAD",
|
|
30
|
+
]);
|
|
31
|
+
export function normalizeToolProxyMethod(value) {
|
|
32
|
+
const method = String(value || "GET").toUpperCase();
|
|
33
|
+
return ALLOWED_METHODS.has(method) ? method : null;
|
|
34
|
+
}
|
|
35
|
+
export function sanitizeOutboundHeaders(value) {
|
|
36
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
37
|
+
return {};
|
|
38
|
+
const headers = {};
|
|
39
|
+
for (const [name, rawValue] of Object.entries(value)) {
|
|
40
|
+
const lower = name.toLowerCase();
|
|
41
|
+
if (!HEADER_NAME_RE.test(name) || BLOCKED_OUTBOUND_HEADERS.has(lower)) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (rawValue === undefined || rawValue === null)
|
|
45
|
+
continue;
|
|
46
|
+
const headerValue = String(rawValue);
|
|
47
|
+
if (/[\r\n]/.test(headerValue))
|
|
48
|
+
continue;
|
|
49
|
+
headers[name] = headerValue;
|
|
50
|
+
}
|
|
51
|
+
return headers;
|
|
52
|
+
}
|
|
53
|
+
export function collectSecretValues(...groups) {
|
|
54
|
+
const values = new Set();
|
|
55
|
+
for (const group of groups) {
|
|
56
|
+
for (const value of group ?? []) {
|
|
57
|
+
if (value)
|
|
58
|
+
values.add(value);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return [...values].sort((a, b) => b.length - a.length);
|
|
62
|
+
}
|
|
63
|
+
export function redactSecrets(value, secretValues) {
|
|
64
|
+
if (secretValues.length === 0)
|
|
65
|
+
return value;
|
|
66
|
+
if (typeof value === "string") {
|
|
67
|
+
return redactString(value, secretValues);
|
|
68
|
+
}
|
|
69
|
+
if (Array.isArray(value)) {
|
|
70
|
+
return value.map((item) => redactSecrets(item, secretValues));
|
|
71
|
+
}
|
|
72
|
+
if (value && typeof value === "object") {
|
|
73
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
|
|
74
|
+
key,
|
|
75
|
+
redactSecrets(entry, secretValues),
|
|
76
|
+
]));
|
|
77
|
+
}
|
|
78
|
+
return value;
|
|
79
|
+
}
|
|
80
|
+
export function redactString(text, secretValues) {
|
|
81
|
+
let out = text;
|
|
82
|
+
for (const secret of secretValues) {
|
|
83
|
+
for (const candidate of redactionCandidates(secret)) {
|
|
84
|
+
if (candidate)
|
|
85
|
+
out = out.split(candidate).join("[redacted]");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
function redactionCandidates(secret) {
|
|
91
|
+
const candidates = new Set([secret]);
|
|
92
|
+
try {
|
|
93
|
+
candidates.add(encodeURIComponent(secret));
|
|
94
|
+
}
|
|
95
|
+
catch { }
|
|
96
|
+
try {
|
|
97
|
+
candidates.add(encodeURI(secret));
|
|
98
|
+
}
|
|
99
|
+
catch { }
|
|
100
|
+
return [...candidates].sort((a, b) => b.length - a.length);
|
|
101
|
+
}
|
|
102
|
+
export async function readResponseTextWithLimit(response, maxBytes = MAX_TOOL_PROXY_RESPONSE_SIZE) {
|
|
103
|
+
const contentLength = response.headers.get("content-length");
|
|
104
|
+
if (contentLength && Number(contentLength) > maxBytes) {
|
|
105
|
+
return {
|
|
106
|
+
text: `(response too large - ${contentLength} bytes, max ${maxBytes})`,
|
|
107
|
+
truncated: true,
|
|
108
|
+
size: Number(contentLength),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const reader = response.body?.getReader?.();
|
|
112
|
+
if (!reader) {
|
|
113
|
+
const buffer = await response.arrayBuffer();
|
|
114
|
+
if (buffer.byteLength > maxBytes) {
|
|
115
|
+
return {
|
|
116
|
+
text: `(response truncated - ${buffer.byteLength} bytes, max ${maxBytes})`,
|
|
117
|
+
truncated: true,
|
|
118
|
+
size: buffer.byteLength,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
text: new TextDecoder().decode(buffer),
|
|
123
|
+
truncated: false,
|
|
124
|
+
size: buffer.byteLength,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const chunks = [];
|
|
128
|
+
let total = 0;
|
|
129
|
+
while (true) {
|
|
130
|
+
const { done, value } = await reader.read();
|
|
131
|
+
if (done)
|
|
132
|
+
break;
|
|
133
|
+
if (!value)
|
|
134
|
+
continue;
|
|
135
|
+
total += value.byteLength;
|
|
136
|
+
if (total > maxBytes) {
|
|
137
|
+
await reader.cancel().catch(() => { });
|
|
138
|
+
return {
|
|
139
|
+
text: `(response truncated - ${total} bytes, max ${maxBytes})`,
|
|
140
|
+
truncated: true,
|
|
141
|
+
size: total,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
chunks.push(value);
|
|
145
|
+
}
|
|
146
|
+
const buffer = new Uint8Array(total);
|
|
147
|
+
let offset = 0;
|
|
148
|
+
for (const chunk of chunks) {
|
|
149
|
+
buffer.set(chunk, offset);
|
|
150
|
+
offset += chunk.byteLength;
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
text: new TextDecoder().decode(buffer),
|
|
154
|
+
truncated: false,
|
|
155
|
+
size: total,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=proxy-security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-security.js","sourceRoot":"","sources":["../../src/tools/proxy-security.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/tools/routes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/tools/routes.ts"],"names":[],"mappings":"AA+CA,wBAAgB,kBAAkB,2FA8BjC"}
|
package/dist/tools/routes.js
CHANGED
|
@@ -7,9 +7,12 @@ import { runWithRequestContext, getRequestOrgId, } from "../server/request-conte
|
|
|
7
7
|
import { getOrgContext } from "../org/context.js";
|
|
8
8
|
import { getDbExec, isPostgres } from "../db/client.js";
|
|
9
9
|
import { listTools, getTool, createTool, updateTool, updateToolContent, deleteTool, ensureToolsTables, } from "./store.js";
|
|
10
|
-
import { buildToolHtml } from "./html-shell.js";
|
|
10
|
+
import { buildToolHtml, TOOL_IFRAME_CSP } from "./html-shell.js";
|
|
11
11
|
import { getThemeVars } from "./theme.js";
|
|
12
12
|
import { resolveKeyReferences, validateUrlAllowlist, getKeyAllowlist, } from "../secrets/substitution.js";
|
|
13
|
+
import { collectSecretValues, normalizeToolProxyMethod, readResponseTextWithLimit, redactSecrets, redactString, sanitizeOutboundHeaders, } from "./proxy-security.js";
|
|
14
|
+
import { createSsrfSafeDispatcher, isBlockedToolUrlWithDns, } from "./url-safety.js";
|
|
15
|
+
import { ForbiddenError, resolveAccess } from "../sharing/access.js";
|
|
13
16
|
export function createToolsHandler() {
|
|
14
17
|
return defineEventHandler(async (event) => {
|
|
15
18
|
const method = getMethod(event);
|
|
@@ -25,7 +28,16 @@ export function createToolsHandler() {
|
|
|
25
28
|
const orgCtx = await getOrgContext(event).catch(() => null);
|
|
26
29
|
const userEmail = session.email;
|
|
27
30
|
const orgId = orgCtx?.orgId ?? undefined;
|
|
28
|
-
|
|
31
|
+
try {
|
|
32
|
+
return await runWithRequestContext({ userEmail, orgId }, () => dispatch(event, method, parts, userEmail));
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
if (err instanceof ForbiddenError) {
|
|
36
|
+
setResponseStatus(event, 403);
|
|
37
|
+
return { error: err.message };
|
|
38
|
+
}
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
29
41
|
});
|
|
30
42
|
}
|
|
31
43
|
async function dispatch(event, method, parts, userEmail) {
|
|
@@ -77,7 +89,8 @@ async function dispatch(event, method, parts, userEmail) {
|
|
|
77
89
|
}
|
|
78
90
|
// GET /:id/render
|
|
79
91
|
if (method === "GET" && parts.length === 2 && parts[1] === "render") {
|
|
80
|
-
const
|
|
92
|
+
const access = await resolveAccess("tool", parts[0]);
|
|
93
|
+
const tool = access?.resource;
|
|
81
94
|
if (!tool) {
|
|
82
95
|
setResponseStatus(event, 404);
|
|
83
96
|
return { error: "Tool not found" };
|
|
@@ -85,8 +98,29 @@ async function dispatch(event, method, parts, userEmail) {
|
|
|
85
98
|
const search = event.url?.search || "";
|
|
86
99
|
const isDark = search.includes("dark=1") || search.includes("dark=true");
|
|
87
100
|
const themeVars = getThemeVars(isDark);
|
|
88
|
-
|
|
101
|
+
// Compute viewer-vs-author binding so the iframe can warn when the
|
|
102
|
+
// viewer is NOT the author. This is the minimum-viable trust signal —
|
|
103
|
+
// a full consent flow is tracked as TODO C1 in audit 05-tools-sandbox.md.
|
|
104
|
+
// Resolved access role is plumbed through so future bridge gating can
|
|
105
|
+
// be conditional on owner/editor/viewer (audit H4 — scaffold only).
|
|
106
|
+
const isAuthor = tool.ownerEmail === userEmail;
|
|
107
|
+
const html = buildToolHtml(tool.content, themeVars, isDark, parts[0], {
|
|
108
|
+
authorEmail: tool.ownerEmail,
|
|
109
|
+
viewerEmail: userEmail,
|
|
110
|
+
isAuthor,
|
|
111
|
+
role: access.role,
|
|
112
|
+
});
|
|
113
|
+
// Security headers per render. We set these explicitly here (rather than
|
|
114
|
+
// rely on the global security-headers middleware) because:
|
|
115
|
+
// - The global middleware sets X-Frame-Options: DENY which would break
|
|
116
|
+
// the legitimate iframe usage of this route inside the app.
|
|
117
|
+
// - frame-ancestors in the CSP must be set as an HTTP header to be
|
|
118
|
+
// enforced; meta-CSP can't set it per spec.
|
|
89
119
|
setResponseHeader(event, "Content-Type", "text/html; charset=utf-8");
|
|
120
|
+
setResponseHeader(event, "Content-Security-Policy", TOOL_IFRAME_CSP);
|
|
121
|
+
setResponseHeader(event, "X-Frame-Options", "SAMEORIGIN");
|
|
122
|
+
setResponseHeader(event, "X-Content-Type-Options", "nosniff");
|
|
123
|
+
setResponseHeader(event, "Referrer-Policy", "no-referrer");
|
|
90
124
|
return html;
|
|
91
125
|
}
|
|
92
126
|
// GET /:id
|
|
@@ -278,90 +312,6 @@ async function handleToolDataDelete(event, toolId, collection, itemId, userEmail
|
|
|
278
312
|
});
|
|
279
313
|
return { ok: true };
|
|
280
314
|
}
|
|
281
|
-
const METADATA_HOSTS = [
|
|
282
|
-
"metadata.google.internal",
|
|
283
|
-
"metadata.google.internal.",
|
|
284
|
-
];
|
|
285
|
-
function isPrivateIpv4(a, b) {
|
|
286
|
-
if (a === 127)
|
|
287
|
-
return true;
|
|
288
|
-
if (a === 10)
|
|
289
|
-
return true;
|
|
290
|
-
if (a === 172 && b >= 16 && b <= 31)
|
|
291
|
-
return true;
|
|
292
|
-
if (a === 192 && b === 168)
|
|
293
|
-
return true;
|
|
294
|
-
if (a === 169 && b === 254)
|
|
295
|
-
return true;
|
|
296
|
-
if (a === 0)
|
|
297
|
-
return true;
|
|
298
|
-
return false;
|
|
299
|
-
}
|
|
300
|
-
function isPrivateHost(hostname) {
|
|
301
|
-
const h = hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
302
|
-
if (h === "localhost")
|
|
303
|
-
return true;
|
|
304
|
-
if (METADATA_HOSTS.includes(h))
|
|
305
|
-
return true;
|
|
306
|
-
// IPv6 forms
|
|
307
|
-
if (h === "::1" || h === "::0" || h === "::")
|
|
308
|
-
return true;
|
|
309
|
-
// IPv4-mapped IPv6: ::ffff:127.0.0.1
|
|
310
|
-
const v4mapped = h.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
|
|
311
|
-
if (v4mapped) {
|
|
312
|
-
const [a, b] = v4mapped[1].split(".").map(Number);
|
|
313
|
-
if (isPrivateIpv4(a, b))
|
|
314
|
-
return true;
|
|
315
|
-
}
|
|
316
|
-
// ULA (fc00::/7) and link-local (fe80::/10)
|
|
317
|
-
if (/^f[cd]/.test(h))
|
|
318
|
-
return true;
|
|
319
|
-
if (/^fe[89ab]/.test(h))
|
|
320
|
-
return true;
|
|
321
|
-
// Dotted IPv4
|
|
322
|
-
const raw = hostname.toLowerCase();
|
|
323
|
-
const parts = raw.split(".");
|
|
324
|
-
if (parts.length === 4 && parts.every((p) => /^\d+$/.test(p))) {
|
|
325
|
-
const [a, b] = parts.map(Number);
|
|
326
|
-
if (isPrivateIpv4(a, b))
|
|
327
|
-
return true;
|
|
328
|
-
}
|
|
329
|
-
// Decimal integer IPv4
|
|
330
|
-
if (/^\d+$/.test(raw)) {
|
|
331
|
-
const num = Number(raw);
|
|
332
|
-
if (num >= 0 && num <= 0xffffffff) {
|
|
333
|
-
const a = (num >>> 24) & 0xff;
|
|
334
|
-
const b = (num >>> 16) & 0xff;
|
|
335
|
-
if (isPrivateIpv4(a, b))
|
|
336
|
-
return true;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
return false;
|
|
340
|
-
}
|
|
341
|
-
const DNS_REBIND_SUFFIXES = [
|
|
342
|
-
".nip.io",
|
|
343
|
-
".sslip.io",
|
|
344
|
-
".xip.io",
|
|
345
|
-
".localtest.me",
|
|
346
|
-
".lvh.me",
|
|
347
|
-
];
|
|
348
|
-
function isBlockedUrl(url) {
|
|
349
|
-
try {
|
|
350
|
-
const parsed = new URL(url);
|
|
351
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
352
|
-
return true;
|
|
353
|
-
}
|
|
354
|
-
const host = parsed.hostname.toLowerCase();
|
|
355
|
-
if (isPrivateHost(host))
|
|
356
|
-
return true;
|
|
357
|
-
if (DNS_REBIND_SUFFIXES.some((s) => host.endsWith(s)))
|
|
358
|
-
return true;
|
|
359
|
-
}
|
|
360
|
-
catch {
|
|
361
|
-
return true;
|
|
362
|
-
}
|
|
363
|
-
return false;
|
|
364
|
-
}
|
|
365
315
|
async function handleProxy(event, userEmail) {
|
|
366
316
|
const body = await readBody(event);
|
|
367
317
|
const rawUrl = body.url;
|
|
@@ -369,31 +319,42 @@ async function handleProxy(event, userEmail) {
|
|
|
369
319
|
setResponseStatus(event, 400);
|
|
370
320
|
return { error: "url is required" };
|
|
371
321
|
}
|
|
372
|
-
const method = (body.method || "GET")
|
|
322
|
+
const method = normalizeToolProxyMethod(body.method || "GET");
|
|
323
|
+
if (!method) {
|
|
324
|
+
setResponseStatus(event, 405);
|
|
325
|
+
return {
|
|
326
|
+
error: "Unsupported HTTP method. Allowed methods: GET, POST, PUT, PATCH, DELETE, HEAD.",
|
|
327
|
+
};
|
|
328
|
+
}
|
|
373
329
|
const rawHeaders = body.headers || {};
|
|
374
330
|
const rawBody = body.body;
|
|
375
331
|
let resolvedUrl = rawUrl;
|
|
376
332
|
let resolvedHeaders = JSON.stringify(rawHeaders);
|
|
377
333
|
let resolvedBody = rawBody;
|
|
378
334
|
const allUsedKeys = [];
|
|
335
|
+
const allSecretValues = [];
|
|
379
336
|
try {
|
|
380
337
|
const urlResult = await resolveKeyReferences(rawUrl, "user", userEmail);
|
|
381
338
|
resolvedUrl = urlResult.resolved;
|
|
382
339
|
allUsedKeys.push(...urlResult.usedKeys);
|
|
340
|
+
allSecretValues.push(...urlResult.secretValues);
|
|
383
341
|
const headerResult = await resolveKeyReferences(resolvedHeaders, "user", userEmail);
|
|
384
342
|
resolvedHeaders = headerResult.resolved;
|
|
385
343
|
allUsedKeys.push(...headerResult.usedKeys);
|
|
344
|
+
allSecretValues.push(...headerResult.secretValues);
|
|
386
345
|
if (rawBody) {
|
|
387
346
|
const bodyResult = await resolveKeyReferences(typeof rawBody === "string" ? rawBody : JSON.stringify(rawBody), "user", userEmail);
|
|
388
347
|
resolvedBody = bodyResult.resolved;
|
|
389
348
|
allUsedKeys.push(...bodyResult.usedKeys);
|
|
349
|
+
allSecretValues.push(...bodyResult.secretValues);
|
|
390
350
|
}
|
|
391
351
|
}
|
|
392
352
|
catch (err) {
|
|
393
353
|
setResponseStatus(event, 400);
|
|
394
354
|
return { error: `Key resolution failed: ${err?.message ?? err}` };
|
|
395
355
|
}
|
|
396
|
-
|
|
356
|
+
const secretValues = collectSecretValues(allSecretValues);
|
|
357
|
+
if (await isBlockedToolUrlWithDns(resolvedUrl)) {
|
|
397
358
|
setResponseStatus(event, 403);
|
|
398
359
|
return { error: "Requests to private/internal addresses are not allowed" };
|
|
399
360
|
}
|
|
@@ -408,13 +369,20 @@ async function handleProxy(event, userEmail) {
|
|
|
408
369
|
}
|
|
409
370
|
let headers;
|
|
410
371
|
try {
|
|
411
|
-
headers = JSON.parse(resolvedHeaders);
|
|
372
|
+
headers = sanitizeOutboundHeaders(JSON.parse(resolvedHeaders));
|
|
412
373
|
}
|
|
413
374
|
catch {
|
|
414
|
-
headers = rawHeaders;
|
|
375
|
+
headers = sanitizeOutboundHeaders(rawHeaders);
|
|
415
376
|
}
|
|
416
377
|
const controller = new AbortController();
|
|
417
378
|
const timeout = setTimeout(() => controller.abort(), 15_000);
|
|
379
|
+
// Best-effort connect-time SSRF guard. When undici is available (it ships
|
|
380
|
+
// with Node 18+ but is not always exposed as an importable module), the
|
|
381
|
+
// dispatcher re-checks the resolved IP at TCP-connect time, closing the
|
|
382
|
+
// TOCTOU between the pre-flight `isBlockedToolUrlWithDns` lookup and the
|
|
383
|
+
// actual fetch lookup. If undici is not importable, fall through to plain
|
|
384
|
+
// fetch — the pre-flight remains the primary protection.
|
|
385
|
+
const dispatcher = (await createSsrfSafeDispatcher()) ?? undefined;
|
|
418
386
|
try {
|
|
419
387
|
const fetchOpts = {
|
|
420
388
|
method,
|
|
@@ -422,28 +390,56 @@ async function handleProxy(event, userEmail) {
|
|
|
422
390
|
signal: controller.signal,
|
|
423
391
|
redirect: "manual",
|
|
424
392
|
};
|
|
393
|
+
if (dispatcher)
|
|
394
|
+
fetchOpts.dispatcher = dispatcher;
|
|
425
395
|
if (resolvedBody && ["POST", "PUT", "PATCH"].includes(method)) {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
396
|
+
const isStringBody = typeof resolvedBody === "string";
|
|
397
|
+
fetchOpts.body = isStringBody
|
|
398
|
+
? resolvedBody
|
|
399
|
+
: JSON.stringify(resolvedBody);
|
|
400
|
+
// Only inject Content-Type when (a) the caller didn't set one and
|
|
401
|
+
// (b) the body is actually JSON-shaped (object or stringified JSON).
|
|
402
|
+
// Otherwise leave it unset so the runtime fetch picks an appropriate
|
|
403
|
+
// default and we don't misrepresent text/plain bodies as JSON.
|
|
404
|
+
const hasContentType = Object.keys(headers).some((k) => k.toLowerCase() === "content-type");
|
|
405
|
+
if (!hasContentType) {
|
|
406
|
+
const isJsonShaped = !isStringBody ||
|
|
407
|
+
(typeof resolvedBody === "string" &&
|
|
408
|
+
/^\s*[{[]/.test(resolvedBody) &&
|
|
409
|
+
isLikelyJson(resolvedBody));
|
|
410
|
+
if (isJsonShaped)
|
|
411
|
+
headers["Content-Type"] = "application/json";
|
|
432
412
|
}
|
|
433
413
|
}
|
|
434
414
|
const response = await fetch(resolvedUrl, fetchOpts);
|
|
435
415
|
if (response.status >= 300 && response.status < 400) {
|
|
436
416
|
const location = response.headers.get("location");
|
|
437
|
-
|
|
417
|
+
const redirectUrl = location ? new URL(location, resolvedUrl).href : null;
|
|
418
|
+
if (redirectUrl && (await isBlockedToolUrlWithDns(redirectUrl))) {
|
|
438
419
|
setResponseStatus(event, 403);
|
|
439
420
|
return { error: "Redirect to private/internal address blocked" };
|
|
440
421
|
}
|
|
422
|
+
if (redirectUrl) {
|
|
423
|
+
for (const keyName of new Set(allUsedKeys)) {
|
|
424
|
+
const allowlist = await getKeyAllowlist(keyName, "user", userEmail);
|
|
425
|
+
if (!validateUrlAllowlist(redirectUrl, allowlist)) {
|
|
426
|
+
setResponseStatus(event, 403);
|
|
427
|
+
return {
|
|
428
|
+
error: `Redirect URL is not allowed for key "${keyName}"`,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
441
433
|
return {
|
|
442
434
|
status: response.status,
|
|
443
|
-
body: {
|
|
435
|
+
body: {
|
|
436
|
+
redirect: redirectUrl
|
|
437
|
+
? redactString(redirectUrl, secretValues)
|
|
438
|
+
: location,
|
|
439
|
+
},
|
|
444
440
|
};
|
|
445
441
|
}
|
|
446
|
-
const text = await response
|
|
442
|
+
const { text } = await readResponseTextWithLimit(response);
|
|
447
443
|
let responseBody;
|
|
448
444
|
try {
|
|
449
445
|
responseBody = JSON.parse(text);
|
|
@@ -451,7 +447,10 @@ async function handleProxy(event, userEmail) {
|
|
|
451
447
|
catch {
|
|
452
448
|
responseBody = text;
|
|
453
449
|
}
|
|
454
|
-
return {
|
|
450
|
+
return {
|
|
451
|
+
status: response.status,
|
|
452
|
+
body: redactSecrets(responseBody, secretValues),
|
|
453
|
+
};
|
|
455
454
|
}
|
|
456
455
|
catch (err) {
|
|
457
456
|
if (err?.name === "AbortError") {
|
|
@@ -459,7 +458,9 @@ async function handleProxy(event, userEmail) {
|
|
|
459
458
|
return { error: "Upstream request timed out" };
|
|
460
459
|
}
|
|
461
460
|
setResponseStatus(event, 502);
|
|
462
|
-
return {
|
|
461
|
+
return {
|
|
462
|
+
error: `Proxy request failed: ${redactSecrets(err?.message ?? String(err), secretValues)}`,
|
|
463
|
+
};
|
|
463
464
|
}
|
|
464
465
|
finally {
|
|
465
466
|
clearTimeout(timeout);
|
|
@@ -469,7 +470,14 @@ async function handleProxy(event, userEmail) {
|
|
|
469
470
|
* Capture console output from a CLI script that uses console.log for results.
|
|
470
471
|
* Same technique as wrapCliScript in agent-chat-plugin.ts.
|
|
471
472
|
*/
|
|
473
|
+
let captureCliOutputQueue = Promise.resolve();
|
|
472
474
|
async function captureCliOutput(fn, args) {
|
|
475
|
+
const previousCapture = captureCliOutputQueue;
|
|
476
|
+
let releaseCapture;
|
|
477
|
+
captureCliOutputQueue = new Promise((resolve) => {
|
|
478
|
+
releaseCapture = resolve;
|
|
479
|
+
});
|
|
480
|
+
await previousCapture;
|
|
473
481
|
const logs = [];
|
|
474
482
|
const origLog = console.log;
|
|
475
483
|
const origError = console.error;
|
|
@@ -497,6 +505,7 @@ async function captureCliOutput(fn, args) {
|
|
|
497
505
|
console.log = origLog;
|
|
498
506
|
console.error = origError;
|
|
499
507
|
process.stdout.write = origStdoutWrite;
|
|
508
|
+
releaseCapture();
|
|
500
509
|
}
|
|
501
510
|
return logs.join("\n") || "(no output)";
|
|
502
511
|
}
|
|
@@ -521,6 +530,13 @@ async function handleSqlQuery(event) {
|
|
|
521
530
|
const args = ["--sql", sql, "--format", "json"];
|
|
522
531
|
if (body.limit)
|
|
523
532
|
args.push("--limit", String(body.limit));
|
|
533
|
+
if (body.args !== undefined) {
|
|
534
|
+
if (!Array.isArray(body.args)) {
|
|
535
|
+
setResponseStatus(event, 400);
|
|
536
|
+
return { error: "args must be an array" };
|
|
537
|
+
}
|
|
538
|
+
args.push("--args", JSON.stringify(body.args));
|
|
539
|
+
}
|
|
524
540
|
const output = await captureCliOutput(mod.default, args);
|
|
525
541
|
try {
|
|
526
542
|
return JSON.parse(output);
|
|
@@ -534,11 +550,35 @@ async function handleSqlQuery(event) {
|
|
|
534
550
|
return { error: err?.message ?? "Query failed" };
|
|
535
551
|
}
|
|
536
552
|
}
|
|
537
|
-
|
|
538
|
-
|
|
553
|
+
// TODO(security): replace this regex blocklist with a SQL parser + an explicit
|
|
554
|
+
// allowlist of tables a tool may read/write (e.g. only `tool_data`, plus a
|
|
555
|
+
// per-template list). The current blocklist is best-effort defense in depth
|
|
556
|
+
// and is by design bypassable via SQL constructions that don't include the
|
|
557
|
+
// blocklisted token literally (string concat, dynamic SQL, etc). The temp-
|
|
558
|
+
// view scoping in scripts/db/scoping.ts is the actual ownership boundary.
|
|
559
|
+
const DESTRUCTIVE_SQL_RE = /\b(CREATE\s+(?:(?:LOCAL|GLOBAL)\s+)?(?:TEMPORARY|TEMP)?\s*(TABLE|INDEX|VIEW|SCHEMA|DATABASE|TRIGGER|FUNCTION|EXTENSION|ROLE|TABLESPACE|PUBLICATION|SUBSCRIPTION)|DROP\s+(TABLE|INDEX|VIEW|SCHEMA|DATABASE|TRIGGER|FUNCTION|EXTENSION|ROLE)|TRUNCATE|DELETE\s+FROM\s+(?!tool_data\b)|ALTER\s+(TABLE|VIEW|SCHEMA|DATABASE|FUNCTION|ROLE|EXTENSION|PUBLICATION)\s+(?!tool_data\b)|ATTACH|DETACH|VACUUM|REINDEX|PRAGMA|GRANT|REVOKE|SET\s+ROLE|RESET\s+ROLE|COPY)\b/i;
|
|
560
|
+
// Sensitive tables that tools must not touch directly. Includes Better Auth
|
|
561
|
+
// identity tables, framework infrastructure (tracing, evals, automations,
|
|
562
|
+
// integrations, notifications, scheduling, sharing/orgs), and Postgres
|
|
563
|
+
// catalogs that would let a tool enumerate or read internals.
|
|
564
|
+
const SENSITIVE_SQL_RE = /\b(app_secrets|user|users|session|sessions|account|accounts|verification|oauth_tokens|tools|tool_shares|tool_slots|tool_slot_installs|member|organization|invitation|jwks|agent_trace_spans|agent_trace_summaries|agent_feedback|agent_satisfaction_scores|agent_evals|agent_runs|agent_run_events|notifications|progress_runs|integration_configs|integration_pending_tasks|integration_thread_mappings|resources|org_members|org_invitations|bigquery_cache|dashboard_views|pg_catalog|information_schema|pg_class|pg_proc|pg_namespace|pg_user|pg_roles|pg_authid|pg_shadow)\b/i;
|
|
565
|
+
// Refuses positional INSERTs (no column list). `INSERT INTO recordings VALUES
|
|
566
|
+
// (...)` would let a tool stuff arbitrary owner_email values into a row.
|
|
567
|
+
// `INSERT INTO recordings (col1, col2) VALUES (...)` is required so the
|
|
568
|
+
// downstream injectOwnership helper can append owner_email.
|
|
569
|
+
const POSITIONAL_INSERT_RE = /\bINSERT\s+INTO\s+["'`]?\w+["'`]?\s+VALUES\b/i;
|
|
539
570
|
function stripSqlComments(sql) {
|
|
540
571
|
return sql.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/--[^\n]*/g, " ");
|
|
541
572
|
}
|
|
573
|
+
function isLikelyJson(text) {
|
|
574
|
+
try {
|
|
575
|
+
const parsed = JSON.parse(text);
|
|
576
|
+
return parsed !== null && typeof parsed === "object";
|
|
577
|
+
}
|
|
578
|
+
catch {
|
|
579
|
+
return false;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
542
582
|
async function handleSqlExec(event) {
|
|
543
583
|
const body = await readBody(event);
|
|
544
584
|
const sql = body.sql;
|
|
@@ -557,9 +597,22 @@ async function handleSqlExec(event) {
|
|
|
557
597
|
setResponseStatus(event, 403);
|
|
558
598
|
return { error: "Sensitive framework tables are not writable from tools" };
|
|
559
599
|
}
|
|
600
|
+
if (POSITIONAL_INSERT_RE.test(cleanSql)) {
|
|
601
|
+
setResponseStatus(event, 400);
|
|
602
|
+
return {
|
|
603
|
+
error: "INSERT must specify an explicit column list (e.g. INSERT INTO t (col1, col2) VALUES (?, ?)) so ownership can be injected.",
|
|
604
|
+
};
|
|
605
|
+
}
|
|
560
606
|
try {
|
|
561
607
|
const mod = await import("../scripts/db/exec.js");
|
|
562
608
|
const args = ["--sql", sql, "--format", "json"];
|
|
609
|
+
if (body.args !== undefined) {
|
|
610
|
+
if (!Array.isArray(body.args)) {
|
|
611
|
+
setResponseStatus(event, 400);
|
|
612
|
+
return { error: "args must be an array" };
|
|
613
|
+
}
|
|
614
|
+
args.push("--args", JSON.stringify(body.args));
|
|
615
|
+
}
|
|
563
616
|
const output = await captureCliOutput(mod.default, args);
|
|
564
617
|
try {
|
|
565
618
|
return JSON.parse(output);
|