@agent-native/core 0.95.1 → 0.97.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +64 -0
- package/corpus/core/docs/content/audit-log.mdx +2 -1
- package/corpus/core/docs/content/automations.mdx +7 -7
- package/corpus/core/docs/content/creating-templates.mdx +1 -1
- package/corpus/core/docs/content/internationalization.mdx +2 -1
- package/corpus/core/docs/content/locales/ar-SA/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/ar-SA/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/ar-SA/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/ar-SA/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/package-lifecycle.mdx +19 -0
- package/corpus/core/docs/content/locales/ar-SA/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/ar-SA/security.mdx +8 -0
- package/corpus/core/docs/content/locales/de-DE/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/de-DE/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/de-DE/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/de-DE/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/package-lifecycle.mdx +22 -0
- package/corpus/core/docs/content/locales/de-DE/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/de-DE/security.mdx +8 -0
- package/corpus/core/docs/content/locales/es-ES/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/es-ES/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/es-ES/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/es-ES/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/package-lifecycle.mdx +22 -0
- package/corpus/core/docs/content/locales/es-ES/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/es-ES/security.mdx +8 -0
- package/corpus/core/docs/content/locales/fr-FR/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/fr-FR/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/fr-FR/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/fr-FR/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/package-lifecycle.mdx +21 -0
- package/corpus/core/docs/content/locales/fr-FR/sandbox-adapters.mdx +19 -8
- package/corpus/core/docs/content/locales/fr-FR/security.mdx +8 -0
- package/corpus/core/docs/content/locales/hi-IN/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/hi-IN/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/hi-IN/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/hi-IN/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/package-lifecycle.mdx +20 -0
- package/corpus/core/docs/content/locales/hi-IN/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/hi-IN/security.mdx +8 -0
- package/corpus/core/docs/content/locales/ja-JP/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/ja-JP/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/ja-JP/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/ja-JP/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/package-lifecycle.mdx +21 -0
- package/corpus/core/docs/content/locales/ja-JP/sandbox-adapters.mdx +17 -6
- package/corpus/core/docs/content/locales/ja-JP/security.mdx +8 -0
- package/corpus/core/docs/content/locales/ko-KR/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/ko-KR/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/ko-KR/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/ko-KR/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/package-lifecycle.mdx +20 -0
- package/corpus/core/docs/content/locales/ko-KR/sandbox-adapters.mdx +17 -6
- package/corpus/core/docs/content/locales/ko-KR/security.mdx +8 -0
- package/corpus/core/docs/content/locales/pt-BR/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/pt-BR/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/pt-BR/getting-started.mdx +7 -1
- package/corpus/core/docs/content/locales/pt-BR/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/package-lifecycle.mdx +21 -0
- package/corpus/core/docs/content/locales/pt-BR/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/pt-BR/security.mdx +8 -0
- package/corpus/core/docs/content/locales/zh-CN/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/zh-CN/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/zh-CN/getting-started.mdx +6 -4
- package/corpus/core/docs/content/locales/zh-CN/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/package-lifecycle.mdx +19 -0
- package/corpus/core/docs/content/locales/zh-CN/sandbox-adapters.mdx +17 -6
- package/corpus/core/docs/content/locales/zh-CN/security.mdx +8 -0
- package/corpus/core/docs/content/locales/zh-TW/audit-log.mdx +2 -1
- package/corpus/core/docs/content/locales/zh-TW/automations.mdx +7 -7
- package/corpus/core/docs/content/locales/zh-TW/getting-started.mdx +6 -4
- package/corpus/core/docs/content/locales/zh-TW/internationalization.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/package-lifecycle.mdx +19 -0
- package/corpus/core/docs/content/locales/zh-TW/sandbox-adapters.mdx +18 -7
- package/corpus/core/docs/content/locales/zh-TW/security.mdx +8 -0
- package/corpus/core/docs/content/package-lifecycle.mdx +51 -0
- package/corpus/core/docs/content/sandbox-adapters.mdx +16 -5
- package/corpus/core/package.json +11 -2
- package/corpus/core/src/a2a/auth-policy.ts +33 -0
- package/corpus/core/src/a2a/client.ts +11 -1
- package/corpus/core/src/agent/durable-background.ts +15 -7
- package/corpus/core/src/agent/production-agent.ts +87 -27
- package/corpus/core/src/agent/run-store.ts +13 -4
- package/corpus/core/src/agent/thread-data-builder.ts +7 -5
- package/corpus/core/src/audit/actions/export-audit-events.ts +162 -0
- package/corpus/core/src/audit/store.ts +8 -3
- package/corpus/core/src/audit/types.ts +3 -0
- package/corpus/core/src/chat-threads/store.ts +20 -1
- package/corpus/core/src/cli/code-agent-executor.ts +1 -0
- package/corpus/core/src/cli/code-agent-runs.ts +14 -0
- package/corpus/core/src/cli/doctor.ts +396 -0
- package/corpus/core/src/cli/index.ts +56 -0
- package/corpus/core/src/cli/info.ts +3 -3
- package/corpus/core/src/cli/package-lifecycle.ts +821 -0
- package/corpus/core/src/client/AgentPanel.tsx +32 -25
- package/corpus/core/src/client/AssistantChat.tsx +36 -20
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +141 -90
- package/corpus/core/src/client/agent-chat-adapter.ts +9 -9
- package/corpus/core/src/client/chat/ChatHistoryList.tsx +404 -0
- package/corpus/core/src/client/chat/index.ts +6 -0
- package/corpus/core/src/client/chat/tool-call-display.tsx +37 -3
- package/corpus/core/src/client/code-agent-chat-adapter.ts +72 -4
- package/corpus/core/src/client/composer/RealtimeVoiceMode.tsx +52 -11
- package/corpus/core/src/client/composer/TiptapComposer.tsx +157 -20
- package/corpus/core/src/client/composer/VoiceButton.tsx +28 -0
- package/corpus/core/src/client/composer/useRealtimeVoiceMode.tsx +5 -0
- package/corpus/core/src/client/conversation/code-agent-transcript.ts +4 -5
- package/corpus/core/src/client/guided-questions.tsx +2 -1
- package/corpus/core/src/client/index.ts +11 -0
- package/corpus/core/src/client/use-chat-threads.ts +10 -1
- package/corpus/core/src/client/voice-provider-status.ts +44 -0
- package/corpus/core/src/code-agents/transcript-normalizer.ts +76 -0
- package/corpus/core/src/deploy/build.ts +12 -11
- package/corpus/core/src/guards/db-tool-scoping.ts +129 -0
- package/corpus/core/src/guards/index.ts +23 -0
- package/corpus/core/src/guards/no-drizzle-push.ts +116 -0
- package/corpus/core/src/guards/no-env-credentials.ts +229 -0
- package/corpus/core/src/guards/no-env-mutation.ts +114 -0
- package/corpus/core/src/guards/no-localhost-fallback.ts +124 -0
- package/corpus/core/src/guards/no-unscoped-credentials.ts +227 -0
- package/corpus/core/src/guards/no-unscoped-queries.ts +834 -0
- package/corpus/core/src/guards/scan-utils.ts +105 -0
- package/corpus/core/src/guards/types.ts +30 -0
- package/corpus/core/src/integrations/a2a-continuation-processor.ts +35 -5
- package/corpus/core/src/integrations/adapters/slack.ts +74 -21
- package/corpus/core/src/integrations/webhook-handler.ts +14 -0
- package/corpus/core/src/localization/default-messages.ts +6 -0
- package/corpus/core/src/observability/hosted-model-experiment.ts +118 -0
- package/corpus/core/src/observability/routes.ts +17 -0
- package/corpus/core/src/observability/store.ts +4 -1
- package/corpus/core/src/observability/traces.ts +41 -2
- package/corpus/core/src/org/accept-pending.ts +9 -1
- package/corpus/core/src/org/migrations.ts +41 -0
- package/corpus/core/src/package-lifecycle/index.ts +1 -0
- package/corpus/core/src/package-lifecycle/manifest.ts +120 -0
- package/corpus/core/src/provider-api/custom-registry.ts +56 -0
- package/corpus/core/src/provider-api/index.ts +2 -0
- package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +19 -1
- package/corpus/core/src/scripts/call-agent.ts +53 -3
- package/corpus/core/src/scripts/chat/search-chats.ts +11 -8
- package/corpus/core/src/secrets/register-framework-secrets.ts +1 -1
- package/corpus/core/src/secrets/storage.ts +47 -27
- package/corpus/core/src/server/action-discovery.ts +4 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +95 -18
- package/corpus/core/src/server/core-routes-plugin.ts +45 -14
- package/corpus/core/src/server/csrf.ts +24 -5
- package/corpus/core/src/server/framework-request-handler.ts +34 -0
- package/corpus/core/src/server/google-realtime-session.ts +1 -36
- package/corpus/core/src/server/poll.ts +24 -2
- package/corpus/core/src/server/realtime-voice.ts +80 -24
- package/corpus/core/src/server/request-origin.ts +63 -0
- package/corpus/core/src/server/transcribe-voice.ts +1 -50
- package/corpus/core/src/server/voice-providers-status.ts +4 -3
- package/corpus/core/src/shared/cache-control.ts +2 -8
- package/corpus/core/src/styles/agent-native.css +1 -0
- package/corpus/core/src/styles/chat-history-list.css +313 -0
- package/corpus/core/src/templates/default/package.json +2 -2
- package/corpus/core/src/templates/headless/package.json +0 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/audit-log/SKILL.md +3 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/automations/SKILL.md +1 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +8 -4
- package/corpus/core/src/templates/workspace-core/package.json +0 -1
- package/corpus/core/src/templates/workspace-root/package.json +0 -1
- package/corpus/core/src/triggers/actions.ts +11 -3
- package/corpus/core/src/triggers/types.ts +7 -1
- package/corpus/core/src/vite/client.ts +1 -0
- package/corpus/templates/analytics/AGENTS.md +7 -0
- package/corpus/templates/analytics/actions/bigquery.ts +26 -2
- package/corpus/templates/analytics/actions/compose-dashboard.ts +65 -37
- package/corpus/templates/analytics/actions/data-source-status.ts +18 -0
- package/corpus/templates/analytics/actions/mutate-dashboard.ts +73 -24
- package/corpus/templates/analytics/actions/reorder-dashboard-panels.ts +16 -13
- package/corpus/templates/analytics/actions/update-dashboard.ts +53 -42
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +5 -4
- package/corpus/templates/analytics/app/global.css +10 -0
- package/corpus/templates/analytics/app/pages/Ask.tsx +25 -2
- package/corpus/templates/analytics/changelog/2026-07-10-analytics-answers-simple-time-bounded-metrics-without-unnece.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-analytics-chat-reliably-uses-connected-data-sources-across-s.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-chat-threads-now-stay-clear-of-top-actions-and-fade-smoothly.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-context-chips-can-now-be-selected-and-removed-one-at-a-time-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-dashboard-edits-from-the-agent-and-the-ui-at-the-same-time-n.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-the-ask-composer-no-longer-carries-dashboard-or-panel-contex.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-the-ask-section-stays-highlighted-while-its-chat-history-is-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-10-timed-out-bigquery-jobs-are-now-cancelled-so-they-stop-consu.md +6 -0
- package/corpus/templates/analytics/package.json +1 -2
- package/corpus/templates/analytics/server/lib/bigquery.ts +91 -14
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +154 -11
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +82 -7
- package/corpus/templates/assets/package.json +1 -2
- package/corpus/templates/brain/package.json +1 -2
- package/corpus/templates/calendar/package.json +1 -2
- package/corpus/templates/chat/package.json +1 -2
- package/corpus/templates/clips/changelog/2026-07-10-atomic-view-tracking.md +6 -0
- package/corpus/templates/clips/chrome-extension/package.json +3 -2
- package/corpus/templates/clips/desktop/package.json +6 -4
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +26 -13
- package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +4 -1
- package/corpus/templates/clips/package.json +1 -2
- package/corpus/templates/clips/server/db/schema.ts +29 -17
- package/corpus/templates/clips/server/plugins/db.ts +8 -0
- package/corpus/templates/clips/server/routes/api/view-event.post.ts +260 -105
- package/corpus/templates/content/.agents/skills/notion-integration/SKILL.md +16 -0
- package/corpus/templates/content/AGENTS.md +72 -62
- package/corpus/templates/content/actions/_content-database-source-adapters.ts +84 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +206 -96
- package/corpus/templates/content/actions/_notion-database-source-adapter.ts +216 -0
- package/corpus/templates/content/actions/_position-utils.ts +76 -0
- package/corpus/templates/content/actions/_property-utils.ts +31 -20
- package/corpus/templates/content/actions/add-database-item.ts +52 -39
- package/corpus/templates/content/actions/attach-content-database-source.ts +95 -11
- package/corpus/templates/content/actions/change-content-database-source-role.ts +24 -1
- package/corpus/templates/content/actions/configure-document-property.ts +36 -27
- package/corpus/templates/content/actions/create-content-database.ts +40 -30
- package/corpus/templates/content/actions/create-document.ts +39 -32
- package/corpus/templates/content/actions/duplicate-document-property.ts +37 -28
- package/corpus/templates/content/actions/list-notion-database-sources.ts +80 -0
- package/corpus/templates/content/actions/move-document.ts +64 -48
- package/corpus/templates/content/actions/refresh-content-database-source.ts +42 -3
- package/corpus/templates/content/actions/share-local-file-document.ts +36 -27
- package/corpus/templates/content/actions/suggest-source-join-key.ts +39 -16
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +89 -23
- package/corpus/templates/content/app/components/editor/database/settings.tsx +1 -1
- package/corpus/templates/content/app/hooks/use-content-database.ts +18 -1
- package/corpus/templates/content/app/i18n/zh-TW.ts +4 -0
- package/corpus/templates/content/app/i18n-data.ts +40 -0
- package/corpus/templates/content/changelog/2026-07-10-failed-row-creation-and-source-attach-now-show-an-error-inst.md +6 -0
- package/corpus/templates/content/changelog/2026-07-10-items-added-at-the-same-time-no-longer-end-up-with-identical.md +6 -0
- package/corpus/templates/content/changelog/2026-07-10-notion-databases-can-add-read-only-details-to-content-tables.md +6 -0
- package/corpus/templates/content/package.json +1 -2
- package/corpus/templates/content/parity/matrix.md +25 -25
- package/corpus/templates/content/parity/matrix.ts +1 -0
- package/corpus/templates/content/server/routes/api/documents/[id]/move.patch.ts +43 -26
- package/corpus/templates/content/shared/api.ts +16 -1
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +8 -4
- package/corpus/templates/design/AGENTS.md +12 -2
- package/corpus/templates/design/DEVELOPING.md +10 -6
- package/corpus/templates/design/actions/apply-visual-edit.ts +191 -6
- package/corpus/templates/design/actions/duplicate-design.ts +31 -25
- package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +5 -1
- package/corpus/templates/design/changelog/2026-07-10-duplicating-a-design-can-no-longer-produce-a-copy-with-missi.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-local-visual-edits-can-now-save-safe-leaf-text-class-and.md +6 -0
- package/corpus/templates/design/package.json +1 -1
- package/corpus/templates/design/shared/local-jsx-visual-edit.ts +388 -0
- package/corpus/templates/dispatch/package.json +1 -2
- package/corpus/templates/forms/actions/patch-form-fields.ts +82 -44
- package/corpus/templates/forms/changelog/2026-07-10-simultaneous-edits-to-different-form-fields-no-longer-overwr.md +6 -0
- package/corpus/templates/forms/package.json +1 -2
- package/corpus/templates/macros/package.json +1 -2
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +3 -1
- package/corpus/templates/mail/changelog/2026-07-10-fixed-calendar-rsvp-buttons-in-emails-firing-duplicate-respo.md +6 -0
- package/corpus/templates/mail/package.json +1 -2
- package/corpus/templates/plan/actions/restore-plan-version.ts +126 -96
- package/corpus/templates/plan/changelog/2026-07-10-restoring-a-plan-version-can-no-longer-leave-a-plan-half-res.md +6 -0
- package/corpus/templates/plan/package.json +1 -2
- package/corpus/templates/plan/server/plans.ts +9 -2
- package/corpus/templates/slides/actions/list-decks.ts +28 -0
- package/corpus/templates/slides/app/components/deck/MermaidRenderer.tsx +41 -26
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +4 -8
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +2 -4
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +4 -8
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +5 -12
- package/corpus/templates/slides/app/components/editor/HistoryPanel.tsx +3 -6
- package/corpus/templates/slides/app/components/editor/ImageDropPromptPopover.tsx +3 -6
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +2 -5
- package/corpus/templates/slides/app/context/DeckContext.tsx +47 -4
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +11 -30
- package/corpus/templates/slides/app/pages/Index.tsx +2 -3
- package/corpus/templates/slides/app/root.tsx +0 -5
- package/corpus/templates/slides/changelog/2026-07-10-deck-lists-load-much-faster-and-no-longer-re-download-slide-.md +6 -0
- package/corpus/templates/slides/package.json +1 -2
- package/dist/a2a/auth-policy.d.ts +19 -0
- package/dist/a2a/auth-policy.d.ts.map +1 -1
- package/dist/a2a/auth-policy.js +32 -0
- package/dist/a2a/auth-policy.js.map +1 -1
- package/dist/a2a/client.d.ts +7 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +2 -1
- package/dist/a2a/client.js.map +1 -1
- package/dist/agent/durable-background.d.ts +8 -5
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +15 -8
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/production-agent.d.ts +6 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +63 -26
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +9 -4
- 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 +6 -5
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/audit/actions/export-audit-events.d.ts +27 -0
- package/dist/audit/actions/export-audit-events.d.ts.map +1 -0
- package/dist/audit/actions/export-audit-events.js +144 -0
- package/dist/audit/actions/export-audit-events.js.map +1 -0
- package/dist/audit/store.d.ts +1 -0
- package/dist/audit/store.d.ts.map +1 -1
- package/dist/audit/store.js +8 -3
- package/dist/audit/store.js.map +1 -1
- package/dist/audit/types.d.ts +3 -0
- package/dist/audit/types.d.ts.map +1 -1
- package/dist/audit/types.js.map +1 -1
- package/dist/chat-threads/store.d.ts +10 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +6 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/code-agent-executor.d.ts.map +1 -1
- package/dist/cli/code-agent-executor.js +1 -0
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/cli/code-agent-runs.d.ts +12 -0
- package/dist/cli/code-agent-runs.d.ts.map +1 -1
- package/dist/cli/code-agent-runs.js +1 -0
- package/dist/cli/code-agent-runs.js.map +1 -1
- package/dist/cli/doctor.d.ts +83 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +277 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/index.js +50 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/info.js +3 -3
- package/dist/cli/info.js.map +1 -1
- package/dist/cli/package-lifecycle.d.ts +50 -0
- package/dist/cli/package-lifecycle.d.ts.map +1 -0
- package/dist/cli/package-lifecycle.js +560 -0
- package/dist/cli/package-lifecycle.js.map +1 -0
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +3 -3
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +11 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +7 -4
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +83 -10
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.js +7 -3
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/chat/ChatHistoryList.d.ts +88 -0
- package/dist/client/chat/ChatHistoryList.d.ts.map +1 -0
- package/dist/client/chat/ChatHistoryList.js +83 -0
- package/dist/client/chat/ChatHistoryList.js.map +1 -0
- package/dist/client/chat/index.d.ts +1 -0
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js +1 -0
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +13 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +10 -2
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/code-agent-chat-adapter.d.ts +17 -1
- package/dist/client/code-agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/code-agent-chat-adapter.js +47 -3
- package/dist/client/code-agent-chat-adapter.js.map +1 -1
- package/dist/client/composer/RealtimeVoiceMode.d.ts +11 -1
- package/dist/client/composer/RealtimeVoiceMode.d.ts.map +1 -1
- package/dist/client/composer/RealtimeVoiceMode.js +5 -3
- package/dist/client/composer/RealtimeVoiceMode.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +25 -2
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +96 -5
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/VoiceButton.d.ts.map +1 -1
- package/dist/client/composer/VoiceButton.js +21 -1
- package/dist/client/composer/VoiceButton.js.map +1 -1
- package/dist/client/composer/useRealtimeVoiceMode.d.ts.map +1 -1
- package/dist/client/composer/useRealtimeVoiceMode.js +5 -0
- package/dist/client/composer/useRealtimeVoiceMode.js.map +1 -1
- package/dist/client/conversation/code-agent-transcript.d.ts +2 -0
- package/dist/client/conversation/code-agent-transcript.d.ts.map +1 -1
- package/dist/client/conversation/code-agent-transcript.js +3 -5
- package/dist/client/conversation/code-agent-transcript.js.map +1 -1
- package/dist/client/guided-questions.d.ts.map +1 -1
- package/dist/client/guided-questions.js +2 -1
- package/dist/client/guided-questions.js.map +1 -1
- package/dist/client/index.d.ts +3 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +9 -1
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/voice-provider-status.d.ts +10 -0
- package/dist/client/voice-provider-status.d.ts.map +1 -0
- package/dist/client/voice-provider-status.js +32 -0
- package/dist/client/voice-provider-status.js.map +1 -0
- package/dist/code-agents/transcript-normalizer.d.ts +29 -0
- package/dist/code-agents/transcript-normalizer.d.ts.map +1 -1
- package/dist/code-agents/transcript-normalizer.js +55 -0
- package/dist/code-agents/transcript-normalizer.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +13 -11
- package/dist/deploy/build.js.map +1 -1
- package/dist/guards/db-tool-scoping.d.ts +38 -0
- package/dist/guards/db-tool-scoping.d.ts.map +1 -0
- package/dist/guards/db-tool-scoping.js +114 -0
- package/dist/guards/db-tool-scoping.js.map +1 -0
- package/dist/guards/index.d.ts +23 -0
- package/dist/guards/index.d.ts.map +1 -0
- package/dist/guards/index.js +19 -0
- package/dist/guards/index.js.map +1 -0
- package/dist/guards/no-drizzle-push.d.ts +14 -0
- package/dist/guards/no-drizzle-push.d.ts.map +1 -0
- package/dist/guards/no-drizzle-push.js +97 -0
- package/dist/guards/no-drizzle-push.js.map +1 -0
- package/dist/guards/no-env-credentials.d.ts +36 -0
- package/dist/guards/no-env-credentials.d.ts.map +1 -0
- package/dist/guards/no-env-credentials.js +204 -0
- package/dist/guards/no-env-credentials.js.map +1 -0
- package/dist/guards/no-env-mutation.d.ts +23 -0
- package/dist/guards/no-env-mutation.d.ts.map +1 -0
- package/dist/guards/no-env-mutation.js +90 -0
- package/dist/guards/no-env-mutation.js.map +1 -0
- package/dist/guards/no-localhost-fallback.d.ts +30 -0
- package/dist/guards/no-localhost-fallback.d.ts.map +1 -0
- package/dist/guards/no-localhost-fallback.js +105 -0
- package/dist/guards/no-localhost-fallback.js.map +1 -0
- package/dist/guards/no-unscoped-credentials.d.ts +28 -0
- package/dist/guards/no-unscoped-credentials.d.ts.map +1 -0
- package/dist/guards/no-unscoped-credentials.js +199 -0
- package/dist/guards/no-unscoped-credentials.js.map +1 -0
- package/dist/guards/no-unscoped-queries.d.ts +32 -0
- package/dist/guards/no-unscoped-queries.d.ts.map +1 -0
- package/dist/guards/no-unscoped-queries.js +720 -0
- package/dist/guards/no-unscoped-queries.js.map +1 -0
- package/dist/guards/scan-utils.d.ts +28 -0
- package/dist/guards/scan-utils.d.ts.map +1 -0
- package/dist/guards/scan-utils.js +92 -0
- package/dist/guards/scan-utils.js.map +1 -0
- package/dist/guards/types.d.ts +28 -0
- package/dist/guards/types.d.ts.map +1 -0
- package/dist/guards/types.js +11 -0
- package/dist/guards/types.js.map +1 -0
- package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
- package/dist/integrations/a2a-continuation-processor.js +25 -5
- package/dist/integrations/a2a-continuation-processor.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +55 -21
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +11 -0
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/localization/default-messages.d.ts +5 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +5 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/hosted-model-experiment.d.ts +39 -0
- package/dist/observability/hosted-model-experiment.d.ts.map +1 -0
- package/dist/observability/hosted-model-experiment.js +90 -0
- package/dist/observability/hosted-model-experiment.js.map +1 -0
- package/dist/observability/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts.map +1 -1
- package/dist/observability/routes.js +16 -0
- package/dist/observability/routes.js.map +1 -1
- package/dist/observability/store.d.ts.map +1 -1
- package/dist/observability/store.js +4 -1
- package/dist/observability/store.js.map +1 -1
- package/dist/observability/traces.d.ts +6 -0
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +28 -2
- package/dist/observability/traces.js.map +1 -1
- package/dist/org/accept-pending.d.ts.map +1 -1
- package/dist/org/accept-pending.js +9 -1
- package/dist/org/accept-pending.js.map +1 -1
- package/dist/org/migrations.d.ts +7 -2
- package/dist/org/migrations.d.ts.map +1 -1
- package/dist/org/migrations.js +41 -0
- package/dist/org/migrations.js.map +1 -1
- package/dist/package-lifecycle/index.d.ts +2 -0
- package/dist/package-lifecycle/index.d.ts.map +1 -0
- package/dist/package-lifecycle/index.js +2 -0
- package/dist/package-lifecycle/index.js.map +1 -0
- package/dist/package-lifecycle/manifest.d.ts +24 -0
- package/dist/package-lifecycle/manifest.d.ts.map +1 -0
- package/dist/package-lifecycle/manifest.js +81 -0
- package/dist/package-lifecycle/manifest.js.map +1 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/custom-registry.d.ts +32 -1
- package/dist/provider-api/custom-registry.d.ts.map +1 -1
- package/dist/provider-api/custom-registry.js +41 -1
- package/dist/provider-api/custom-registry.js.map +1 -1
- package/dist/provider-api/index.d.ts +1 -1
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +1 -1
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.js +19 -1
- package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +43 -3
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/scripts/chat/search-chats.d.ts +1 -1
- package/dist/scripts/chat/search-chats.d.ts.map +1 -1
- package/dist/scripts/chat/search-chats.js +11 -8
- package/dist/scripts/chat/search-chats.js.map +1 -1
- package/dist/secrets/register-framework-secrets.js +1 -1
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/secrets/storage.d.ts.map +1 -1
- package/dist/secrets/storage.js +45 -27
- package/dist/secrets/storage.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +4 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +11 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +74 -19
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/core-routes-plugin.d.ts +3 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +36 -12
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/csrf.js +18 -5
- package/dist/server/csrf.js.map +1 -1
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +34 -0
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-realtime-session.d.ts.map +1 -1
- package/dist/server/google-realtime-session.js +2 -34
- package/dist/server/google-realtime-session.js.map +1 -1
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +24 -2
- package/dist/server/poll.js.map +1 -1
- package/dist/server/realtime-voice.d.ts.map +1 -1
- package/dist/server/realtime-voice.js +64 -21
- package/dist/server/realtime-voice.js.map +1 -1
- package/dist/server/request-origin.d.ts +10 -0
- package/dist/server/request-origin.d.ts.map +1 -0
- package/dist/server/request-origin.js +60 -0
- package/dist/server/request-origin.js.map +1 -0
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +2 -48
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/server/voice-providers-status.d.ts.map +1 -1
- package/dist/server/voice-providers-status.js +2 -3
- package/dist/server/voice-providers-status.js.map +1 -1
- package/dist/shared/cache-control.d.ts +4 -6
- package/dist/shared/cache-control.d.ts.map +1 -1
- package/dist/shared/cache-control.js +2 -7
- package/dist/shared/cache-control.js.map +1 -1
- package/dist/styles/agent-native.css +1 -0
- package/dist/styles/chat-history-list.css +313 -0
- package/dist/templates/default/package.json +2 -2
- package/dist/templates/headless/package.json +0 -1
- package/dist/templates/workspace-core/.agents/skills/audit-log/SKILL.md +3 -0
- package/dist/templates/workspace-core/.agents/skills/automations/SKILL.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +8 -4
- package/dist/templates/workspace-core/package.json +0 -1
- package/dist/templates/workspace-root/package.json +0 -1
- package/dist/triggers/actions.d.ts.map +1 -1
- package/dist/triggers/actions.js +8 -3
- package/dist/triggers/actions.js.map +1 -1
- package/dist/triggers/types.d.ts +7 -1
- package/dist/triggers/types.d.ts.map +1 -1
- package/dist/triggers/types.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +1 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/audit-log.mdx +2 -1
- package/docs/content/automations.mdx +7 -7
- package/docs/content/creating-templates.mdx +1 -1
- package/docs/content/internationalization.mdx +2 -1
- package/docs/content/locales/ar-SA/audit-log.mdx +2 -1
- package/docs/content/locales/ar-SA/automations.mdx +7 -7
- package/docs/content/locales/ar-SA/getting-started.mdx +7 -1
- package/docs/content/locales/ar-SA/internationalization.mdx +1 -1
- package/docs/content/locales/ar-SA/package-lifecycle.mdx +19 -0
- package/docs/content/locales/ar-SA/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/ar-SA/security.mdx +8 -0
- package/docs/content/locales/de-DE/audit-log.mdx +2 -1
- package/docs/content/locales/de-DE/automations.mdx +7 -7
- package/docs/content/locales/de-DE/getting-started.mdx +7 -1
- package/docs/content/locales/de-DE/internationalization.mdx +1 -1
- package/docs/content/locales/de-DE/package-lifecycle.mdx +22 -0
- package/docs/content/locales/de-DE/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/de-DE/security.mdx +8 -0
- package/docs/content/locales/es-ES/audit-log.mdx +2 -1
- package/docs/content/locales/es-ES/automations.mdx +7 -7
- package/docs/content/locales/es-ES/getting-started.mdx +7 -1
- package/docs/content/locales/es-ES/internationalization.mdx +1 -1
- package/docs/content/locales/es-ES/package-lifecycle.mdx +22 -0
- package/docs/content/locales/es-ES/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/es-ES/security.mdx +8 -0
- package/docs/content/locales/fr-FR/audit-log.mdx +2 -1
- package/docs/content/locales/fr-FR/automations.mdx +7 -7
- package/docs/content/locales/fr-FR/getting-started.mdx +7 -1
- package/docs/content/locales/fr-FR/internationalization.mdx +1 -1
- package/docs/content/locales/fr-FR/package-lifecycle.mdx +21 -0
- package/docs/content/locales/fr-FR/sandbox-adapters.mdx +19 -8
- package/docs/content/locales/fr-FR/security.mdx +8 -0
- package/docs/content/locales/hi-IN/audit-log.mdx +2 -1
- package/docs/content/locales/hi-IN/automations.mdx +7 -7
- package/docs/content/locales/hi-IN/getting-started.mdx +7 -1
- package/docs/content/locales/hi-IN/internationalization.mdx +1 -1
- package/docs/content/locales/hi-IN/package-lifecycle.mdx +20 -0
- package/docs/content/locales/hi-IN/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/hi-IN/security.mdx +8 -0
- package/docs/content/locales/ja-JP/audit-log.mdx +2 -1
- package/docs/content/locales/ja-JP/automations.mdx +7 -7
- package/docs/content/locales/ja-JP/getting-started.mdx +7 -1
- package/docs/content/locales/ja-JP/internationalization.mdx +1 -1
- package/docs/content/locales/ja-JP/package-lifecycle.mdx +21 -0
- package/docs/content/locales/ja-JP/sandbox-adapters.mdx +17 -6
- package/docs/content/locales/ja-JP/security.mdx +8 -0
- package/docs/content/locales/ko-KR/audit-log.mdx +2 -1
- package/docs/content/locales/ko-KR/automations.mdx +7 -7
- package/docs/content/locales/ko-KR/getting-started.mdx +7 -1
- package/docs/content/locales/ko-KR/internationalization.mdx +1 -1
- package/docs/content/locales/ko-KR/package-lifecycle.mdx +20 -0
- package/docs/content/locales/ko-KR/sandbox-adapters.mdx +17 -6
- package/docs/content/locales/ko-KR/security.mdx +8 -0
- package/docs/content/locales/pt-BR/audit-log.mdx +2 -1
- package/docs/content/locales/pt-BR/automations.mdx +7 -7
- package/docs/content/locales/pt-BR/getting-started.mdx +7 -1
- package/docs/content/locales/pt-BR/internationalization.mdx +1 -1
- package/docs/content/locales/pt-BR/package-lifecycle.mdx +21 -0
- package/docs/content/locales/pt-BR/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/pt-BR/security.mdx +8 -0
- package/docs/content/locales/zh-CN/audit-log.mdx +2 -1
- package/docs/content/locales/zh-CN/automations.mdx +7 -7
- package/docs/content/locales/zh-CN/getting-started.mdx +6 -4
- package/docs/content/locales/zh-CN/internationalization.mdx +1 -1
- package/docs/content/locales/zh-CN/package-lifecycle.mdx +19 -0
- package/docs/content/locales/zh-CN/sandbox-adapters.mdx +17 -6
- package/docs/content/locales/zh-CN/security.mdx +8 -0
- package/docs/content/locales/zh-TW/audit-log.mdx +2 -1
- package/docs/content/locales/zh-TW/automations.mdx +7 -7
- package/docs/content/locales/zh-TW/getting-started.mdx +6 -4
- package/docs/content/locales/zh-TW/internationalization.mdx +1 -1
- package/docs/content/locales/zh-TW/package-lifecycle.mdx +19 -0
- package/docs/content/locales/zh-TW/sandbox-adapters.mdx +18 -7
- package/docs/content/locales/zh-TW/security.mdx +8 -0
- package/docs/content/package-lifecycle.mdx +51 -0
- package/docs/content/sandbox-adapters.mdx +16 -5
- package/package.json +12 -3
- package/src/templates/default/package.json +2 -2
- package/src/templates/headless/package.json +0 -1
- package/src/templates/workspace-core/.agents/skills/audit-log/SKILL.md +3 -0
- package/src/templates/workspace-core/.agents/skills/automations/SKILL.md +1 -1
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +20 -0
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +8 -4
- package/src/templates/workspace-core/package.json +0 -1
- package/src/templates/workspace-root/package.json +0 -1
- package/corpus/templates/slides/app/components/ui/toast.tsx +0 -1
- package/corpus/templates/slides/app/components/ui/toaster.tsx +0 -1
- package/corpus/templates/slides/app/hooks/use-toast.ts +0 -1
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
getMethod,
|
|
9
9
|
getQuery,
|
|
10
10
|
getHeader,
|
|
11
|
+
getRequestIP,
|
|
11
12
|
type H3Event,
|
|
12
13
|
} from "h3";
|
|
13
14
|
|
|
@@ -19,7 +20,8 @@ import {
|
|
|
19
20
|
} from "../a2a/artifact-response.js";
|
|
20
21
|
import {
|
|
21
22
|
hasConfiguredA2ASecret,
|
|
22
|
-
|
|
23
|
+
isLoopbackAddress,
|
|
24
|
+
isTrustedLocalRuntime,
|
|
23
25
|
} from "../a2a/auth-policy.js";
|
|
24
26
|
import {
|
|
25
27
|
applyAgentTextEventToBuffer,
|
|
@@ -54,11 +56,16 @@ import {
|
|
|
54
56
|
listAgentEngines,
|
|
55
57
|
registerBuiltinEngines,
|
|
56
58
|
} from "../agent/engine/index.js";
|
|
57
|
-
import type {
|
|
59
|
+
import type {
|
|
60
|
+
AgentEngine,
|
|
61
|
+
EngineMessage,
|
|
62
|
+
EngineTool,
|
|
63
|
+
} from "../agent/engine/types.js";
|
|
58
64
|
import {
|
|
59
65
|
createProductionAgentHandler,
|
|
60
66
|
actionsToEngineTools,
|
|
61
67
|
executeAgentToolCall,
|
|
68
|
+
filterInitialEngineTools,
|
|
62
69
|
getActiveRunForThreadAsync,
|
|
63
70
|
abortRunDurably,
|
|
64
71
|
subscribeToRun,
|
|
@@ -1060,6 +1067,10 @@ function appStateKeyForBrowserTab(key: string, browserTabId: unknown): string {
|
|
|
1060
1067
|
*/
|
|
1061
1068
|
const generateTitleRateLimit = new Map<string, number[]>();
|
|
1062
1069
|
|
|
1070
|
+
/** Only sweep drained rate-limit entries once the map grows past this size,
|
|
1071
|
+
* so the common small-map case stays O(1). */
|
|
1072
|
+
const RATE_LIMIT_SWEEP_THRESHOLD = 1000;
|
|
1073
|
+
|
|
1063
1074
|
/**
|
|
1064
1075
|
* Creates the `set-search-params` / `set-url-path` tools. Writes a one-shot
|
|
1065
1076
|
* URL command to application_state; the client's URLSync component applies
|
|
@@ -1903,6 +1914,11 @@ async function createChatScriptEntries(): Promise<Record<string, ActionEntry>> {
|
|
|
1903
1914
|
description: "Output format",
|
|
1904
1915
|
enum: ["json", "text"],
|
|
1905
1916
|
},
|
|
1917
|
+
includeArchived: {
|
|
1918
|
+
type: "boolean",
|
|
1919
|
+
description:
|
|
1920
|
+
"Also include archived chats in the results. Archived chats are excluded by default.",
|
|
1921
|
+
},
|
|
1906
1922
|
},
|
|
1907
1923
|
},
|
|
1908
1924
|
},
|
|
@@ -1953,6 +1969,11 @@ async function createChatScriptEntries(): Promise<Record<string, ActionEntry>> {
|
|
|
1953
1969
|
description: "(search) Output format",
|
|
1954
1970
|
enum: ["json", "text"],
|
|
1955
1971
|
},
|
|
1972
|
+
includeArchived: {
|
|
1973
|
+
type: "boolean",
|
|
1974
|
+
description:
|
|
1975
|
+
"(search) Also include archived chats in the results. Archived chats are excluded by default, matching the 'archive' action's effect on the chat list.",
|
|
1976
|
+
},
|
|
1956
1977
|
id: {
|
|
1957
1978
|
type: "string",
|
|
1958
1979
|
description:
|
|
@@ -2940,6 +2961,22 @@ export function runA2AAgentLoop(
|
|
|
2940
2961
|
);
|
|
2941
2962
|
}
|
|
2942
2963
|
|
|
2964
|
+
/**
|
|
2965
|
+
* Keep delegated A2A turns on the same compact initial tool surface as
|
|
2966
|
+
* interactive chat. `tool-search` remains in the initial set, while the
|
|
2967
|
+
* complete registry is supplied separately so the run loop can load a matched
|
|
2968
|
+
* schema after a tool-search result.
|
|
2969
|
+
*/
|
|
2970
|
+
export function createA2AEngineToolSurface(
|
|
2971
|
+
availableTools: EngineTool[],
|
|
2972
|
+
initialToolNames?: string[],
|
|
2973
|
+
): { tools: EngineTool[]; availableTools: EngineTool[] } {
|
|
2974
|
+
return {
|
|
2975
|
+
tools: filterInitialEngineTools(availableTools, initialToolNames),
|
|
2976
|
+
availableTools,
|
|
2977
|
+
};
|
|
2978
|
+
}
|
|
2979
|
+
|
|
2943
2980
|
/**
|
|
2944
2981
|
* Verbose framework sections returned by the `get-framework-context` tool.
|
|
2945
2982
|
* Keyed by topic so the agent can request specific sections.
|
|
@@ -2971,9 +3008,9 @@ Use for charts, visualizations, previews. Don't use for simple text/tables or ex
|
|
|
2971
3008
|
"chat-history": `### Chat History
|
|
2972
3009
|
|
|
2973
3010
|
You can search and restore previous chat conversations using \`chat-history\`:
|
|
2974
|
-
- \`chat-history\` (action: "search") — Search or list past chat threads by keyword
|
|
3011
|
+
- \`chat-history\` (action: "search") — Search or list past chat threads by keyword. Archived threads are excluded by default; pass \`includeArchived: true\` to also see them.
|
|
2975
3012
|
- \`chat-history\` (action: "open") — Open a chat thread in the UI as a new tab and focus it
|
|
2976
|
-
- \`chat-history\` (actions: "rename", "pin", "unpin", "archive") — Organize a known chat thread by ID
|
|
3013
|
+
- \`chat-history\` (actions: "rename", "pin", "unpin", "archive") — Organize a known chat thread by ID. Archiving a thread hides it from the default chat list and search.
|
|
2977
3014
|
|
|
2978
3015
|
When the user asks to find a previous conversation, use \`chat-history\` with action "search" first to find matching threads, then action "open" to restore the one they want.`,
|
|
2979
3016
|
|
|
@@ -5077,7 +5114,10 @@ export function createAgentChatPlugin(
|
|
|
5077
5114
|
},
|
|
5078
5115
|
);
|
|
5079
5116
|
|
|
5080
|
-
const
|
|
5117
|
+
const a2aToolSurface = createA2AEngineToolSurface(
|
|
5118
|
+
actionsToEngineTools(a2aActions),
|
|
5119
|
+
options?.initialToolNames,
|
|
5120
|
+
);
|
|
5081
5121
|
|
|
5082
5122
|
// Precise current time rides the user message (not the cached
|
|
5083
5123
|
// system-prompt prefix) — same pattern as the interactive handler.
|
|
@@ -5098,7 +5138,7 @@ export function createAgentChatPlugin(
|
|
|
5098
5138
|
const controller = new AbortController();
|
|
5099
5139
|
|
|
5100
5140
|
console.log(
|
|
5101
|
-
`[A2A] Starting agent loop: ${
|
|
5141
|
+
`[A2A] Starting agent loop: ${a2aToolSurface.tools.length}/${a2aToolSurface.availableTools.length} initial tools, prompt ${systemPrompt.length} chars`,
|
|
5102
5142
|
);
|
|
5103
5143
|
|
|
5104
5144
|
await runA2AAgentLoop(
|
|
@@ -5106,7 +5146,8 @@ export function createAgentChatPlugin(
|
|
|
5106
5146
|
engine: a2aEngine,
|
|
5107
5147
|
model,
|
|
5108
5148
|
systemPrompt,
|
|
5109
|
-
tools:
|
|
5149
|
+
tools: a2aToolSurface.tools,
|
|
5150
|
+
availableTools: a2aToolSurface.availableTools,
|
|
5110
5151
|
messages: a2aMessages,
|
|
5111
5152
|
actions: a2aActions,
|
|
5112
5153
|
send: (event) => {
|
|
@@ -6516,12 +6557,17 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
6516
6557
|
setResponseStatus(event, 401);
|
|
6517
6558
|
return { error: "Invalid or expired processor token" };
|
|
6518
6559
|
}
|
|
6519
|
-
} else
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6560
|
+
} else {
|
|
6561
|
+
const loopback = isLoopbackAddress(
|
|
6562
|
+
getRequestIP(event, { xForwardedFor: false }),
|
|
6563
|
+
);
|
|
6564
|
+
if (!isTrustedLocalRuntime({ loopback })) {
|
|
6565
|
+
setResponseStatus(event, 503);
|
|
6566
|
+
return {
|
|
6567
|
+
error:
|
|
6568
|
+
"Agent Teams processor not configured — set A2A_SECRET on this deployment (or A2A_ALLOW_UNSIGNED_INTERNAL=1 for trusted local dev).",
|
|
6569
|
+
};
|
|
6570
|
+
}
|
|
6525
6571
|
}
|
|
6526
6572
|
|
|
6527
6573
|
try {
|
|
@@ -7189,6 +7235,11 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7189
7235
|
setResponseHeader(event, "Content-Type", "application/x-ndjson");
|
|
7190
7236
|
setResponseHeader(event, "Cache-Control", "no-cache");
|
|
7191
7237
|
|
|
7238
|
+
// Lets `cancel()` signal in-flight source work to stop early on
|
|
7239
|
+
// client disconnect, instead of only being noticed the next time
|
|
7240
|
+
// `flush()`'s `controller.enqueue` throws.
|
|
7241
|
+
const mentionsAbort = new AbortController();
|
|
7242
|
+
|
|
7192
7243
|
const stream = new ReadableStream({
|
|
7193
7244
|
start(controller) {
|
|
7194
7245
|
return runWithRequestContext(
|
|
@@ -7200,7 +7251,9 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7200
7251
|
);
|
|
7201
7252
|
},
|
|
7202
7253
|
cancel() {
|
|
7203
|
-
// Client disconnected — stop enqueuing
|
|
7254
|
+
// Client disconnected — stop enqueuing and let in-flight source
|
|
7255
|
+
// work short-circuit instead of running to completion unseen.
|
|
7256
|
+
mentionsAbort.abort();
|
|
7204
7257
|
},
|
|
7205
7258
|
});
|
|
7206
7259
|
|
|
@@ -7211,10 +7264,13 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7211
7264
|
) {
|
|
7212
7265
|
const MAX_RESULTS = 50;
|
|
7213
7266
|
let totalSent = 0;
|
|
7214
|
-
let cancelled =
|
|
7267
|
+
let cancelled = mentionsAbort.signal.aborted;
|
|
7215
7268
|
|
|
7216
7269
|
const flush = (batch: MentionItemResponse[]) => {
|
|
7217
|
-
if (cancelled)
|
|
7270
|
+
if (cancelled || mentionsAbort.signal.aborted) {
|
|
7271
|
+
cancelled = true;
|
|
7272
|
+
return;
|
|
7273
|
+
}
|
|
7218
7274
|
const filtered = batch.filter(matchesQuery);
|
|
7219
7275
|
if (filtered.length === 0) return;
|
|
7220
7276
|
const remaining = MAX_RESULTS - totalSent;
|
|
@@ -7297,6 +7353,8 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7297
7353
|
|
|
7298
7354
|
// 3. Custom mention providers (each flushes independently)
|
|
7299
7355
|
for (const [key, provider] of Object.entries(mentionProviders)) {
|
|
7356
|
+
// Client already disconnected — don't spawn more provider work.
|
|
7357
|
+
if (mentionsAbort.signal.aborted) break;
|
|
7300
7358
|
sources.push(
|
|
7301
7359
|
(async () => {
|
|
7302
7360
|
try {
|
|
@@ -7384,7 +7442,9 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7384
7442
|
);
|
|
7385
7443
|
|
|
7386
7444
|
await Promise.all(sources);
|
|
7387
|
-
if (!cancelled
|
|
7445
|
+
if (!cancelled && !mentionsAbort.signal.aborted) {
|
|
7446
|
+
controller.close();
|
|
7447
|
+
}
|
|
7388
7448
|
}
|
|
7389
7449
|
}),
|
|
7390
7450
|
);
|
|
@@ -7415,6 +7475,19 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
7415
7475
|
recent.push(now);
|
|
7416
7476
|
generateTitleRateLimit.set(ownerEmail, recent);
|
|
7417
7477
|
|
|
7478
|
+
// Opportunistic eviction: keep the map from growing unbounded by
|
|
7479
|
+
// the count of distinct users on a long-lived process. Drop any
|
|
7480
|
+
// key whose window has fully drained (no timestamps within the
|
|
7481
|
+
// rolling window).
|
|
7482
|
+
if (generateTitleRateLimit.size > RATE_LIMIT_SWEEP_THRESHOLD) {
|
|
7483
|
+
for (const [email, times] of generateTitleRateLimit) {
|
|
7484
|
+
if (email === ownerEmail) continue;
|
|
7485
|
+
if (times.every((t) => now - t >= limitWindowMs)) {
|
|
7486
|
+
generateTitleRateLimit.delete(email);
|
|
7487
|
+
}
|
|
7488
|
+
}
|
|
7489
|
+
}
|
|
7490
|
+
|
|
7418
7491
|
const body = await readBody(event);
|
|
7419
7492
|
const message = body?.message;
|
|
7420
7493
|
if (!message || typeof message !== "string") {
|
|
@@ -8403,10 +8476,14 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
8403
8476
|
|
|
8404
8477
|
// Validate + HMAC-authenticate the self-dispatch and prepare the
|
|
8405
8478
|
// background-worker body. Pure decision (unit-tested in
|
|
8406
|
-
// durable-background.spec.ts); the route only wires it to h3.
|
|
8479
|
+
// durable-background.spec.ts); the route only wires it to h3. This
|
|
8480
|
+
// handler DOES have the h3 event, so it can see the real socket
|
|
8481
|
+
// peer — thread the loopback signal through so unsigned local-dev
|
|
8482
|
+
// self-dispatch (no A2A_SECRET) still works over 127.0.0.1/::1.
|
|
8407
8483
|
const prepared = prepareProcessRunRequest(
|
|
8408
8484
|
processBody,
|
|
8409
8485
|
getHeader(event, "authorization"),
|
|
8486
|
+
isLoopbackAddress(getRequestIP(event, { xForwardedFor: false })),
|
|
8410
8487
|
);
|
|
8411
8488
|
if (!prepared.ok) {
|
|
8412
8489
|
// DIAGNOSTIC: record the auth/validation failure ONTO the run
|
|
@@ -298,6 +298,7 @@ const BUILDER_WAITLIST_USE_CASES = new Set([
|
|
|
298
298
|
BUILDER_WAITLIST_DEFAULT_USE_CASE,
|
|
299
299
|
"design_publish_app",
|
|
300
300
|
"docs_build_online_waitlist",
|
|
301
|
+
"docs_edit_online_waitlist",
|
|
301
302
|
]);
|
|
302
303
|
const BUILDER_WAITLIST_FORM_TIMEOUT_MS = 8000;
|
|
303
304
|
const BUILDER_WAITLIST_TEXT_LIMIT = 4000;
|
|
@@ -320,6 +321,7 @@ export interface BuilderWaitlistBody {
|
|
|
320
321
|
appUrl?: unknown;
|
|
321
322
|
pageUrl?: unknown;
|
|
322
323
|
source?: unknown;
|
|
324
|
+
template?: unknown;
|
|
323
325
|
useCase?: unknown;
|
|
324
326
|
}
|
|
325
327
|
|
|
@@ -352,6 +354,13 @@ function normalizeBuilderWaitlistUseCase(value: unknown): string {
|
|
|
352
354
|
: BUILDER_WAITLIST_DEFAULT_USE_CASE;
|
|
353
355
|
}
|
|
354
356
|
|
|
357
|
+
function normalizeBuilderWaitlistTemplate(value: unknown): string | undefined {
|
|
358
|
+
const template = cleanBuilderWaitlistText(value, 100);
|
|
359
|
+
return template && /^[a-z0-9][a-z0-9-]{0,99}$/.test(template)
|
|
360
|
+
? template
|
|
361
|
+
: undefined;
|
|
362
|
+
}
|
|
363
|
+
|
|
355
364
|
function isValidWaitlistEmail(email: string): boolean {
|
|
356
365
|
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
357
366
|
}
|
|
@@ -506,6 +515,7 @@ export function buildBuilderWaitlistFormPayload(
|
|
|
506
515
|
getOrigin(event);
|
|
507
516
|
const source =
|
|
508
517
|
cleanBuilderWaitlistText(body.source, 100) ?? BUILDER_WAITLIST_FORM_SOURCE;
|
|
518
|
+
const template = normalizeBuilderWaitlistTemplate(body.template);
|
|
509
519
|
const useCase = normalizeBuilderWaitlistUseCase(body.useCase);
|
|
510
520
|
|
|
511
521
|
return {
|
|
@@ -515,6 +525,7 @@ export function buildBuilderWaitlistFormPayload(
|
|
|
515
525
|
appUrl,
|
|
516
526
|
prompt: cleanBuilderWaitlistText(body.prompt),
|
|
517
527
|
source,
|
|
528
|
+
template,
|
|
518
529
|
useCase,
|
|
519
530
|
},
|
|
520
531
|
_hp: "",
|
|
@@ -522,6 +533,7 @@ export function buildBuilderWaitlistFormPayload(
|
|
|
522
533
|
submitterEmail: sessionEmail,
|
|
523
534
|
pageUrl: appUrl,
|
|
524
535
|
source,
|
|
536
|
+
template,
|
|
525
537
|
useCase,
|
|
526
538
|
},
|
|
527
539
|
};
|
|
@@ -1157,12 +1169,20 @@ export function createCoreRoutesPlugin(
|
|
|
1157
1169
|
}),
|
|
1158
1170
|
);
|
|
1159
1171
|
|
|
1160
|
-
// Defense-in-depth CSRF check for state-changing /_agent-native/* routes
|
|
1161
|
-
//
|
|
1162
|
-
//
|
|
1163
|
-
//
|
|
1164
|
-
|
|
1165
|
-
|
|
1172
|
+
// Defense-in-depth CSRF check for state-changing /_agent-native/* routes
|
|
1173
|
+
// (see `csrf.ts` for the threat model and allowlist) is registered by
|
|
1174
|
+
// `getH3App()` itself (framework-request-handler.ts), synchronously, on
|
|
1175
|
+
// the very first call to `getH3App(nitroApp)` for this process — NOT
|
|
1176
|
+
// here. Registering it inside this plugin's own async init chain would
|
|
1177
|
+
// race against agent-chat-plugin's action-route registration (a
|
|
1178
|
+
// SEPARATE, independently-async-initialized Nitro plugin file in real
|
|
1179
|
+
// deployments): whichever plugin's `getH3App(nitroApp).use(...)` call
|
|
1180
|
+
// happened to resolve first would win the position in the middleware
|
|
1181
|
+
// array, and CSRF losing that race would let an action route match and
|
|
1182
|
+
// run before the CSRF check ever saw the request. Centralizing the
|
|
1183
|
+
// registration in `getH3App()`'s one-time bootstrap makes it the first
|
|
1184
|
+
// middleware any plugin's route can possibly land behind, regardless of
|
|
1185
|
+
// plugin init ordering.
|
|
1166
1186
|
|
|
1167
1187
|
// Agent discovery primitive — shared by headless CLI/A2A surfaces and
|
|
1168
1188
|
// UI shells that need to show connected peer apps without depending on
|
|
@@ -1263,8 +1283,11 @@ export function createCoreRoutesPlugin(
|
|
|
1263
1283
|
return { error: "executionId required" };
|
|
1264
1284
|
}
|
|
1265
1285
|
|
|
1266
|
-
const {
|
|
1267
|
-
|
|
1286
|
+
const {
|
|
1287
|
+
hasConfiguredA2ASecret,
|
|
1288
|
+
isLoopbackAddress,
|
|
1289
|
+
isTrustedLocalRuntime,
|
|
1290
|
+
} = await import("../a2a/auth-policy.js");
|
|
1268
1291
|
if (hasConfiguredA2ASecret()) {
|
|
1269
1292
|
const { verifyInternalToken, extractBearerToken } =
|
|
1270
1293
|
await import("../integrations/internal-token.js");
|
|
@@ -1273,12 +1296,17 @@ export function createCoreRoutesPlugin(
|
|
|
1273
1296
|
setResponseStatus(event, 401);
|
|
1274
1297
|
return { error: "Invalid or expired processor token" };
|
|
1275
1298
|
}
|
|
1276
|
-
} else
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1299
|
+
} else {
|
|
1300
|
+
const loopback = isLoopbackAddress(
|
|
1301
|
+
getRequestIP(event, { xForwardedFor: false }),
|
|
1302
|
+
);
|
|
1303
|
+
if (!isTrustedLocalRuntime({ loopback })) {
|
|
1304
|
+
setResponseStatus(event, 503);
|
|
1305
|
+
return {
|
|
1306
|
+
error:
|
|
1307
|
+
"Sandbox execution processor not configured — set A2A_SECRET on this deployment (or A2A_ALLOW_UNSIGNED_INTERNAL=1 for trusted local dev).",
|
|
1308
|
+
};
|
|
1309
|
+
}
|
|
1282
1310
|
}
|
|
1283
1311
|
|
|
1284
1312
|
try {
|
|
@@ -2021,6 +2049,7 @@ export function createCoreRoutesPlugin(
|
|
|
2021
2049
|
body,
|
|
2022
2050
|
);
|
|
2023
2051
|
const waitlistSource = waitlistPayload.data.source;
|
|
2052
|
+
const waitlistTemplate = waitlistPayload.data.template;
|
|
2024
2053
|
const waitlistUseCase = waitlistPayload.data.useCase;
|
|
2025
2054
|
let formSubmission: { submitted: boolean; formId?: string };
|
|
2026
2055
|
try {
|
|
@@ -2039,6 +2068,7 @@ export function createCoreRoutesPlugin(
|
|
|
2039
2068
|
err instanceof Error ? err.message : "unknown_waitlist_error",
|
|
2040
2069
|
source: waitlistSource,
|
|
2041
2070
|
stage: "waitlist",
|
|
2071
|
+
template: waitlistTemplate ?? null,
|
|
2042
2072
|
useCase: waitlistUseCase,
|
|
2043
2073
|
},
|
|
2044
2074
|
);
|
|
@@ -2057,6 +2087,7 @@ export function createCoreRoutesPlugin(
|
|
|
2057
2087
|
formSubmitted: formSubmission.submitted,
|
|
2058
2088
|
source: waitlistSource,
|
|
2059
2089
|
stage: "waitlist",
|
|
2090
|
+
template: waitlistTemplate ?? null,
|
|
2060
2091
|
useCase: waitlistUseCase,
|
|
2061
2092
|
},
|
|
2062
2093
|
);
|
|
@@ -50,6 +50,8 @@ import {
|
|
|
50
50
|
setResponseStatus,
|
|
51
51
|
} from "h3";
|
|
52
52
|
|
|
53
|
+
import { getConfiguredAppBasePath } from "./app-base-path.js";
|
|
54
|
+
|
|
53
55
|
/**
|
|
54
56
|
* Path prefixes (relative to the framework prefix `/_agent-native`) that are
|
|
55
57
|
* allowed to receive cross-origin state-changing POSTs without first-party
|
|
@@ -144,9 +146,10 @@ function requestHasCookies(event: any): boolean {
|
|
|
144
146
|
}
|
|
145
147
|
|
|
146
148
|
/**
|
|
147
|
-
*
|
|
148
|
-
* `
|
|
149
|
-
*
|
|
149
|
+
* The path is the full request URL pathname (e.g.
|
|
150
|
+
* `/_agent-native/actions/foo` or `/app/_agent-native/actions/foo`).
|
|
151
|
+
* `frameworkPrefix` is the root framework route prefix without a trailing
|
|
152
|
+
* slash, e.g. `/_agent-native`.
|
|
150
153
|
*/
|
|
151
154
|
function isOnAllowlist(pathname: string, frameworkPrefix: string): boolean {
|
|
152
155
|
if (!pathname.startsWith(frameworkPrefix)) return false;
|
|
@@ -157,6 +160,21 @@ function isOnAllowlist(pathname: string, frameworkPrefix: string): boolean {
|
|
|
157
160
|
return false;
|
|
158
161
|
}
|
|
159
162
|
|
|
163
|
+
function matchingFrameworkPrefix(
|
|
164
|
+
pathname: string,
|
|
165
|
+
frameworkPrefix: string,
|
|
166
|
+
): string | undefined {
|
|
167
|
+
if (pathname.startsWith(frameworkPrefix)) return frameworkPrefix;
|
|
168
|
+
|
|
169
|
+
const basePath = getConfiguredAppBasePath();
|
|
170
|
+
const basePathFrameworkPrefix = `${basePath}${frameworkPrefix}`;
|
|
171
|
+
if (basePath && pathname.startsWith(basePathFrameworkPrefix)) {
|
|
172
|
+
return basePathFrameworkPrefix;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return undefined;
|
|
176
|
+
}
|
|
177
|
+
|
|
160
178
|
/**
|
|
161
179
|
* Create the framework CSRF middleware.
|
|
162
180
|
*
|
|
@@ -176,8 +194,9 @@ export function createCsrfMiddleware(
|
|
|
176
194
|
if (!STATE_CHANGING_METHODS.has(method)) return undefined;
|
|
177
195
|
|
|
178
196
|
const pathname = event.url?.pathname ?? "";
|
|
179
|
-
|
|
180
|
-
if (
|
|
197
|
+
const matchingPrefix = matchingFrameworkPrefix(pathname, frameworkPrefix);
|
|
198
|
+
if (!matchingPrefix) return undefined;
|
|
199
|
+
if (isOnAllowlist(pathname, matchingPrefix)) return undefined;
|
|
181
200
|
|
|
182
201
|
// No cookie = no risk of confused-deputy CSRF on the session cookie.
|
|
183
202
|
if (!requestHasCookies(event)) return undefined;
|
|
@@ -17,6 +17,7 @@ import { setResponseHeader, setResponseStatus } from "h3";
|
|
|
17
17
|
import { getMissingDefaultPlugins } from "../deploy/route-discovery.js";
|
|
18
18
|
import { getConfiguredAppBasePath } from "./app-base-path.js";
|
|
19
19
|
import { captureError } from "./capture-error.js";
|
|
20
|
+
import { createCsrfMiddleware } from "./csrf.js";
|
|
20
21
|
|
|
21
22
|
const BOOTSTRAPPED = new WeakSet<object>();
|
|
22
23
|
const IN_BOOTSTRAP = new WeakSet<object>();
|
|
@@ -164,6 +165,27 @@ export function getH3App(nitroApp: any): H3AppShim {
|
|
|
164
165
|
prepend: true,
|
|
165
166
|
});
|
|
166
167
|
|
|
168
|
+
// CSRF (see csrf.ts): registered here — synchronously, on the very
|
|
169
|
+
// first `getH3App()` call for this nitroApp — rather than inside
|
|
170
|
+
// createCoreRoutesPlugin's own async init chain. Real deployments mount
|
|
171
|
+
// core-routes and agent-chat as SEPARATE, independently-async-initialized
|
|
172
|
+
// Nitro plugin files with no explicit ordering between them; both
|
|
173
|
+
// eventually call `getH3App(nitroApp).use(...)` to register their own
|
|
174
|
+
// routes (CSRF, action routes) after their own async setup (DB reads,
|
|
175
|
+
// dynamic imports) resolves in unpredictable relative order. The
|
|
176
|
+
// readiness gate above only guarantees every tracked plugin has FINISHED
|
|
177
|
+
// registering by the time a gated request is released — it does NOT
|
|
178
|
+
// guarantee CSRF's registration call happens to `.push()` onto
|
|
179
|
+
// `~middleware` before an action route's does. If agent-chat's action
|
|
180
|
+
// route push happened to land first, that route would match and run
|
|
181
|
+
// before CSRF ever saw the request. Registering CSRF here instead makes
|
|
182
|
+
// it the first non-prepended middleware pushed onto the array for this
|
|
183
|
+
// nitroApp, full stop — every plugin's own route registrations reach
|
|
184
|
+
// `getH3App()` (and therefore run after this point) before they can
|
|
185
|
+
// register anything, regardless of which plugin's async chain resolves
|
|
186
|
+
// first.
|
|
187
|
+
registerMiddleware(nitroApp, "", createCsrfMiddleware());
|
|
188
|
+
|
|
167
189
|
// Primary gate: Nitro bridges this `request` hook to h3's `config.onRequest`,
|
|
168
190
|
// which h3 awaits BEFORE `handler()` snapshots middleware and resolves the
|
|
169
191
|
// route. The middleware gate above runs too late on production dispatchers —
|
|
@@ -466,7 +488,18 @@ function registerMiddleware(
|
|
|
466
488
|
let originalPathname: string | undefined;
|
|
467
489
|
let originalEventPath: string | undefined;
|
|
468
490
|
let hadEventPath = false;
|
|
491
|
+
// Only true once this specific middleware invocation has actually
|
|
492
|
+
// stripped a mount prefix (i.e. `path` was non-empty and matched).
|
|
493
|
+
// Global (`path === ""`) middleware never mutates event.path/pathname,
|
|
494
|
+
// so `restoreOriginalPath` must be a no-op for it — otherwise it would
|
|
495
|
+
// unconditionally `delete event.path` on every pass-through (hadEventPath
|
|
496
|
+
// defaults to false), corrupting the event for any middleware that runs
|
|
497
|
+
// later in the chain (a real bug: two or more global middlewares in
|
|
498
|
+
// sequence, e.g. security-headers + CORS + CSRF, would wipe event.path
|
|
499
|
+
// for everything downstream, including the final route handler).
|
|
500
|
+
let didStripPath = false;
|
|
469
501
|
const restoreOriginalPath = () => {
|
|
502
|
+
if (!didStripPath) return;
|
|
470
503
|
if (originalPathname !== undefined) {
|
|
471
504
|
try {
|
|
472
505
|
event.url.pathname = originalPathname;
|
|
@@ -502,6 +535,7 @@ function registerMiddleware(
|
|
|
502
535
|
const eventAny = event as any;
|
|
503
536
|
hadEventPath = "path" in eventAny;
|
|
504
537
|
originalEventPath = eventAny.path;
|
|
538
|
+
didStripPath = true;
|
|
505
539
|
try {
|
|
506
540
|
originalPathname = event.url.pathname;
|
|
507
541
|
// Save the full path in context so handlers that need the original URL
|
|
@@ -3,7 +3,6 @@ import { readFile } from "node:fs/promises";
|
|
|
3
3
|
import {
|
|
4
4
|
defineEventHandler,
|
|
5
5
|
getMethod,
|
|
6
|
-
getRequestHeader,
|
|
7
6
|
readBody,
|
|
8
7
|
setResponseStatus,
|
|
9
8
|
type H3Event,
|
|
@@ -15,6 +14,7 @@ import { readAppSecret } from "../secrets/storage.js";
|
|
|
15
14
|
import { getSession } from "./auth.js";
|
|
16
15
|
import { resolveBuilderCredentials } from "./credential-provider.js";
|
|
17
16
|
import { runWithRequestContext } from "./request-context.js";
|
|
17
|
+
import { isSameOriginRequest } from "./request-origin.js";
|
|
18
18
|
|
|
19
19
|
interface GoogleRealtimeSessionResponse {
|
|
20
20
|
websocketUrl: string;
|
|
@@ -22,41 +22,6 @@ interface GoogleRealtimeSessionResponse {
|
|
|
22
22
|
websocketProtocol?: string;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
function isSameOriginRequest(event: H3Event): boolean {
|
|
26
|
-
const host = getRequestHeader(event, "host");
|
|
27
|
-
const origin = getRequestHeader(event, "origin");
|
|
28
|
-
if (origin && host) {
|
|
29
|
-
try {
|
|
30
|
-
const parsed = new URL(origin);
|
|
31
|
-
if (parsed.host === host) return true;
|
|
32
|
-
if (parsed.protocol === "tauri:" && parsed.hostname === "localhost") {
|
|
33
|
-
return true;
|
|
34
|
-
}
|
|
35
|
-
if (
|
|
36
|
-
(parsed.protocol === "http:" || parsed.protocol === "https:") &&
|
|
37
|
-
parsed.hostname === "tauri.localhost" &&
|
|
38
|
-
(host.startsWith("localhost:") || host.startsWith("127.0.0.1:"))
|
|
39
|
-
) {
|
|
40
|
-
return true;
|
|
41
|
-
}
|
|
42
|
-
if (
|
|
43
|
-
parsed.protocol === "http:" &&
|
|
44
|
-
(parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1") &&
|
|
45
|
-
parsed.port === "1420" &&
|
|
46
|
-
(host.startsWith("localhost:") || host.startsWith("127.0.0.1:"))
|
|
47
|
-
) {
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
return false;
|
|
51
|
-
} catch {
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
const fetchSite = getRequestHeader(event, "sec-fetch-site");
|
|
56
|
-
if (fetchSite) return fetchSite === "same-origin" || fetchSite === "none";
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
25
|
export async function resolveGoogleRealtimeCredentials(opts: {
|
|
61
26
|
userEmail?: string | null;
|
|
62
27
|
orgId?: string | null;
|
|
@@ -738,9 +738,31 @@ async function getDurableChangesSinceForUser(
|
|
|
738
738
|
}
|
|
739
739
|
|
|
740
740
|
try {
|
|
741
|
+
// Scope the fetch to rows that could ever be visible to this caller
|
|
742
|
+
// before paying to JSON.parse and visibility-check every deployment-wide
|
|
743
|
+
// event: deployment-global rows (no owner, no org), the caller's own
|
|
744
|
+
// rows, the caller's org's rows, and resource-scoped rows (owner/org
|
|
745
|
+
// don't gate those — access is decided below by
|
|
746
|
+
// `getChangeVisibilityForUser`'s access-aware branch, which can grant a
|
|
747
|
+
// non-owner sharee, so resource-scoped rows must still flow through that
|
|
748
|
+
// check regardless of who owns them). This lets Postgres/SQLite use the
|
|
749
|
+
// `sync_events_owner_version_idx` / `sync_events_org_version_idx` indexes
|
|
750
|
+
// instead of scanning every tenant's activity on every poll. The OR group
|
|
751
|
+
// is parenthesized so `version > ?` ANDs against the whole group, not
|
|
752
|
+
// just the first term. A caller with no org passes a null `orgId` bind
|
|
753
|
+
// param, which makes `org_id = ?` evaluate to no match for every row
|
|
754
|
+
// (including null-org rows) in both dialects — mirroring the
|
|
755
|
+
// `event.orgId && orgId` truthy check in `getChangeVisibilityForUser`.
|
|
741
756
|
const result = await getDbExec().execute({
|
|
742
|
-
sql: `SELECT version, event_json FROM sync_events WHERE version > ?
|
|
743
|
-
|
|
757
|
+
sql: `SELECT version, event_json FROM sync_events WHERE version > ?
|
|
758
|
+
AND (
|
|
759
|
+
(owner IS NULL AND org_id IS NULL)
|
|
760
|
+
OR owner = ?
|
|
761
|
+
OR org_id = ?
|
|
762
|
+
OR resource_type IS NOT NULL
|
|
763
|
+
)
|
|
764
|
+
ORDER BY version ASC LIMIT ?`,
|
|
765
|
+
args: [since, userEmail, orgId ?? null, DURABLE_READ_LIMIT + 1],
|
|
744
766
|
});
|
|
745
767
|
const events: ChangeEvent[] = [];
|
|
746
768
|
let version = Math.max(_version, since);
|