@agent-native/core 0.129.2 → 0.130.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +78 -0
- package/corpus/core/docs/content/cloneable-saas.mdx +114 -0
- package/corpus/core/docs/content/creating-templates.mdx +28 -2
- package/corpus/core/docs/content/syncing-template-changes.mdx +7 -0
- package/corpus/core/docs/content/template-clips-developers.mdx +12 -5
- package/corpus/core/docs/content/template-dispatch-developers.mdx +1 -1
- package/corpus/core/docs/content/template-dispatch.mdx +1 -1
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/action-ui.ts +1 -0
- package/corpus/core/src/action.ts +5 -1
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +15 -5
- package/corpus/core/src/agent/harness/runner.ts +5 -0
- package/corpus/core/src/agent/production-agent.ts +33 -0
- package/corpus/core/src/agent/run-loop-with-resume.ts +5 -0
- package/corpus/core/src/agent/run-manager.ts +126 -1
- package/corpus/core/src/agent/thread-data-builder.ts +47 -2
- package/corpus/core/src/agent/types.ts +2 -0
- package/corpus/core/src/chat-threads/store.ts +4 -5
- package/corpus/core/src/cli/create.ts +1139 -65
- package/corpus/core/src/cli/design-connect.ts +3 -7
- package/corpus/core/src/cli/index.ts +5 -3
- package/corpus/core/src/cli/skills-content/design-visual-edit-skill.ts +83 -47
- package/corpus/core/src/client/AssistantChat.tsx +27 -16
- package/corpus/core/src/client/agent-chat-adapter.ts +24 -0
- package/corpus/core/src/client/blocks/library/wireframe-kit.tsx +17 -2
- package/corpus/core/src/client/chat/index.ts +1 -0
- package/corpus/core/src/client/chat/message-components.tsx +104 -1
- package/corpus/core/src/client/chat/run-recovery.tsx +15 -3
- package/corpus/core/src/client/chat/widgets/DataTableWidget.tsx +10 -29
- package/corpus/core/src/client/chat/widgets/WorkspaceFileWidget.tsx +71 -0
- package/corpus/core/src/client/chat/widgets/builtin-tool-renderers.tsx +22 -0
- package/corpus/core/src/client/chat/widgets/workspace-file-result.ts +49 -0
- package/corpus/core/src/client/embed-auth.ts +2 -0
- package/corpus/core/src/client/org/InvitationBanner.tsx +14 -1
- package/corpus/core/src/client/org/OrgSwitcher.tsx +23 -0
- package/corpus/core/src/client/org/TeamPage.tsx +130 -0
- package/corpus/core/src/client/org/WorkspaceNotice.tsx +85 -0
- package/corpus/core/src/client/org/hooks.ts +14 -0
- package/corpus/core/src/client/org/index.ts +2 -0
- package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +27 -40
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +134 -51
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +7 -0
- package/corpus/core/src/client/resources/use-resources.ts +6 -0
- package/corpus/core/src/client/use-action.ts +3 -1
- package/corpus/core/src/client/widgets/index.ts +1 -0
- package/corpus/core/src/coding-tools/run-code.ts +2 -1
- package/corpus/core/src/db/client.ts +28 -4
- package/corpus/core/src/deploy/build.ts +31 -3
- package/corpus/core/src/eject/remote-mcp-presets.ts +1 -1
- package/corpus/core/src/index.browser.ts +1 -0
- package/corpus/core/src/index.ts +1 -0
- package/corpus/core/src/integrations/a2a-continuation-processor.ts +481 -122
- package/corpus/core/src/integrations/a2a-continuations-store.ts +345 -14
- package/corpus/core/src/integrations/adapters/slack.ts +243 -53
- package/corpus/core/src/integrations/google-docs-poller.ts +3 -0
- package/corpus/core/src/integrations/integration-campaign-recovery.ts +4 -1
- package/corpus/core/src/integrations/plugin.ts +39 -21
- package/corpus/core/src/integrations/task-queue-stats.ts +146 -0
- package/corpus/core/src/integrations/types.ts +25 -4
- package/corpus/core/src/integrations/webhook-handler.ts +46 -16
- package/corpus/core/src/jobs/scheduler.ts +4 -0
- package/corpus/core/src/localization/default-messages.ts +3 -2
- package/corpus/core/src/observability/traces.ts +48 -12
- package/corpus/core/src/org/handlers.ts +52 -1
- package/corpus/core/src/org/migrations.ts +4 -0
- package/corpus/core/src/org/plugin.ts +14 -0
- package/corpus/core/src/org/schema.ts +1 -0
- package/corpus/core/src/org/types.ts +8 -0
- package/corpus/core/src/org/workspace-url.ts +74 -0
- package/corpus/core/src/resources/handlers.ts +35 -5
- package/corpus/core/src/scripts/runner.ts +183 -5
- package/corpus/core/src/server/action-routes.ts +32 -2
- package/corpus/core/src/server/agent-chat-plugin.ts +29 -0
- package/corpus/core/src/server/agent-teams.ts +10 -1
- package/corpus/core/src/server/auth.ts +33 -7
- package/corpus/core/src/server/embed-route.ts +9 -0
- package/corpus/core/src/server/embed-session.ts +62 -3
- package/corpus/core/src/server/open-route.ts +20 -6
- package/corpus/core/src/server/prompts/framework-core-compact.ts +1 -1
- package/corpus/core/src/server/prompts/framework-core.ts +1 -0
- package/corpus/core/src/server/request-context.ts +36 -1
- package/corpus/core/src/shared/embed-auth.ts +1 -0
- package/corpus/core/src/shared/html-document.ts +115 -0
- package/corpus/core/src/shared/index.ts +1 -0
- package/corpus/core/src/sharing/access.ts +8 -1
- package/corpus/core/src/sharing/registry.ts +11 -2
- package/corpus/core/src/workspace-files/actions.ts +100 -0
- package/corpus/core/src/workspace-files/tool.ts +4 -0
- package/corpus/templates/analytics/.agents/skills/analysis-workspace/SKILL.md +4 -0
- package/corpus/templates/analytics/.agents/skills/hubspot/SKILL.md +9 -1
- package/corpus/templates/analytics/AGENTS.md +17 -24
- package/corpus/templates/analytics/actions/data-source-status.ts +11 -1
- package/corpus/templates/analytics/app/i18n-data.ts +34 -0
- package/corpus/templates/analytics/app/lib/data-source-status.ts +86 -0
- package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +9 -0
- package/corpus/templates/analytics/app/pages/DataSources.tsx +184 -20
- package/corpus/templates/analytics/changelog/2026-07-28-native-analytics-data-sources-no-longer-show-duplicate-mc.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-29-exports-now-appear-in-chat-with-a-direct-download-instead-of.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-29-queued-chat-prompts-no-longer-resend-after-analytics-navigat.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-29-scheduled-dashboard-emails-load-every-panel-reliably-without.md +6 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +6 -3
- package/corpus/templates/analytics/server/lib/credential-keys.ts +1 -1
- package/corpus/templates/analytics/server/lib/hubspot.ts +1 -1
- package/corpus/templates/analytics/server/lib/provider-credentials.ts +55 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +123 -27
- package/corpus/templates/analytics/server/routes/[...page].get.ts +2 -7
- package/corpus/templates/analytics/vite.config.ts +7 -0
- package/corpus/templates/brain/actions/list-connection-providers.ts +100 -2
- package/corpus/templates/brain/app/lib/brain.ts +10 -0
- package/corpus/templates/brain/app/routes/sources.tsx +15 -4
- package/corpus/templates/brain/changelog/2026-07-29-brain-automatically-retries-failed-source-syncs-and-guides-y.md +6 -0
- package/corpus/templates/brain/jobs/process-ingest-queue.ts +13 -0
- package/corpus/templates/brain/server/jobs/sync-sources.ts +27 -22
- package/corpus/templates/brain/server/plugins/agent-chat.ts +2 -1
- package/corpus/templates/brain/server/routes/api/brain/queue/run.post.ts +7 -1
- package/corpus/templates/clips/AGENTS.md +1 -1
- package/corpus/templates/clips/actions/create-recording-agent-link.ts +11 -1
- package/corpus/templates/clips/actions/update-comment.ts +68 -0
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +0 -1
- package/corpus/templates/clips/app/components/player/comments-panel.tsx +221 -65
- package/corpus/templates/clips/app/components/player/video-player.tsx +101 -27
- package/corpus/templates/clips/app/i18n/en-US.ts +2 -1
- package/corpus/templates/clips/app/routes/bug-report.done.tsx +48 -27
- package/corpus/templates/clips/app/routes/bug-report.tsx +43 -4
- package/corpus/templates/clips/app/routes/record.tsx +2 -0
- package/corpus/templates/clips/changelog/2026-07-29-clip-playback-now-recovers-instead-of-getting-stuck-when-a-b.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-29-comments-can-now-be-edited-after-posting.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-29-download-actions-now-use-a-shorter-clearer-label.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-29-embedded-bug-reports-now-return-a-temporary-agent-readable.md +6 -0
- package/corpus/templates/clips/shared/bug-report.ts +99 -0
- package/corpus/templates/content/actions/_content-database-personal-view.ts +7 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +5 -2
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +20 -8
- package/corpus/templates/content/changelog/2026-07-29-missing-databases-no-longer-trigger-repeated-personal-view-e.md +6 -0
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +83 -47
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +474 -55
- package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +3 -0
- package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +18 -1
- package/corpus/templates/design/.generated/bridge/source-location.generated.ts +348 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +2 -7
- package/corpus/templates/design/actions/apply-visual-edit.ts +7 -1
- package/corpus/templates/design/actions/connect-localhost.ts +5 -9
- package/corpus/templates/design/actions/create-component.ts +16 -13
- package/corpus/templates/design/actions/grant-localhost-write-consent.ts +2 -7
- package/corpus/templates/design/actions/list-design-source-capabilities.ts +4 -7
- package/corpus/templates/design/actions/list-local-files.ts +26 -50
- package/corpus/templates/design/actions/list-localhost-connections.ts +2 -7
- package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +2 -2
- package/corpus/templates/design/actions/open-visual-edit.ts +234 -135
- package/corpus/templates/design/actions/read-local-file.ts +26 -50
- package/corpus/templates/design/actions/request-localhost-write-consent.ts +2 -7
- package/corpus/templates/design/actions/write-local-file.ts +31 -73
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +307 -133
- package/corpus/templates/design/app/components/design/EditPanel.tsx +94 -22
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +137 -60
- package/corpus/templates/design/app/components/design/ResponsiveInteractBar.tsx +75 -14
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +755 -97
- package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +8 -0
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +24 -1
- package/corpus/templates/design/app/components/design/bridge/source-location.bridge.ts +530 -0
- package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbenchLoader.tsx +278 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +32 -12
- package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-setup.ts +14 -3
- package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +87 -24
- package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +36 -0
- package/corpus/templates/design/app/components/design/code-workbench/store.tsx +2 -1
- package/corpus/templates/design/app/components/design/code-workbench/workspace/localhost-provider.ts +48 -8
- package/corpus/templates/design/app/components/design/design-canvas/content-size-report.ts +3 -13
- package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +4 -2
- package/corpus/templates/design/app/components/design/design-canvas/hit-test.ts +3 -13
- package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +3 -1
- package/corpus/templates/design/app/components/design/edit-panel/inspect-code-source.ts +93 -0
- package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +4 -2
- package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +35 -0
- package/corpus/templates/design/app/components/design/multi-screen/iframe-targeting.ts +24 -0
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -0
- package/corpus/templates/design/app/components/design/types.ts +29 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +7 -4
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +3 -0
- package/corpus/templates/design/app/i18n-data.ts +153 -46
- package/corpus/templates/design/app/i18n-responsive-interact.ts +12 -12
- package/corpus/templates/design/app/lib/design-editor-route.ts +23 -0
- package/corpus/templates/design/app/pages/VisualEdit.tsx +19 -6
- package/corpus/templates/design/app/pages/design-editor/action-error.ts +19 -0
- package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +29 -0
- package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +6 -0
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +277 -15
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +75 -9
- package/corpus/templates/design/app/pages/design-editor/layer-state-scope.ts +28 -0
- package/corpus/templates/design/app/pages/design-editor/live-screen-layer-drop.ts +41 -0
- package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +496 -41
- package/corpus/templates/design/app/pages/design-editor/pending-live-edit-unload-guard.ts +27 -0
- package/corpus/templates/design/app/pages/design-editor/pending-structure-verification.ts +10 -0
- package/corpus/templates/design/app/pages/design-editor/react-semantic-handoff.ts +168 -9
- package/corpus/templates/design/app/pages/design-editor/responsive-interact.ts +41 -3
- package/corpus/templates/design/app/pages/design-editor/screen-command-utils.ts +5 -0
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +42 -13
- package/corpus/templates/design/app/pages/design-editor/source-location.ts +180 -0
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +17 -0
- package/corpus/templates/design/app/public-routes.ts +1 -0
- package/corpus/templates/design/app/routes/visual-edit.$id.tsx +15 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-is-easier-to-find-and-named-screens-open-dir.md +1 -1
- package/corpus/templates/design/changelog/2026-07-28-deleting-a-selected-element-now-removes-it-from-the-live-pre.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-deleting-an-element-on-a-connected-localhost-screen-now-queu.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-shows-a-responsive-device-preview-with-pre.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-layer-hide-and-lock-now-apply-to-the-live-preview-instead-of.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-layers-panel-selections-on-a-connected-localhost-screen-can-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-locked-layers-now-show-a-subtle-dashed-outline-in-the-live-p.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-the-apply-design-updates-button-now-counts-pending-live-text.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-the-design-canvas-no-longer-stalls-on-a-render-loop-while-a-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-visual-edit-on-a-local-dev-server-no-longer-requires-signing.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-visual-edits-on-a-react-19-app-no-longer-report-a-source-lin.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-an-edit-that-cannot-be-written-to-source-now-names-the-reaso.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-applying-a-primitive-dropped-onto-a-connected-localhost-scre.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-changing-a-style-in-the-inspector-now-updates-a-connected-lo.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-choosing-edit-or-annotate-from-a-focused-screen-now-returns-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-concurrent-source-edits-now-return-a-clear-conflict-response.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-creating-a-component-from-an-element-that-repeats-in-the-sou.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-deleting-an-element-you-just-dropped-onto-a-live-screen-no-l.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-dragging-a-layer-across-screens-no-longer-dies-when-the-poin.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-dragging-an-element-from-a-stored-screen-into-a-live-localho.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-drawing-a-box-on-the-canvas-and-dragging-it-into-a-connected.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-fixed-a-loading-screen-flicker-when-reopening-designs-with-a.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-interact-mode-has-edit-and-annotate-buttons-again-so-you-can.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-layer-groups-can-be-dropped-onto-live-localhost-screens.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-localhost-source-errors-now-say-what-actually-went-wrong-whi.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-opening-or-refreshing-a-live-localhost-screen-in-single-scre.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-redo-after-undoing-a-drop-onto-a-live-screen-puts-the-elemen.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-shapes-can-be-drawn-directly-onto-live-localhost-screens.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-shapes-drawn-on-the-canvas-board-now-appear-immediately-inst.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-style-edits-on-a-running-localhost-screen-now-preview-live-a.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-the-apply-design-updates-control-now-appears-as-a-clean-conn.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-visual-edits-on-a-mapped-component-instance-now-tell-the-age.md +6 -0
- package/corpus/templates/design/server/lib/design-data-access.ts +21 -7
- package/corpus/templates/design/server/lib/localhost-connection.ts +240 -0
- package/corpus/templates/design/server/routes/[...page].get.ts +2 -5
- package/corpus/templates/design/server/source-workspace.ts +2 -0
- package/corpus/templates/design/shared/code-layer.ts +43 -0
- package/corpus/templates/design/shared/html-content.ts +26 -0
- package/corpus/templates/design/shared/html-integrity.ts +21 -1
- package/corpus/templates/design/shared/local-jsx-visual-edit.ts +15 -0
- package/corpus/templates/design/shared/source-mode.ts +76 -0
- package/corpus/templates/dispatch/changelog/2026-07-26-slack-replies-recover-after-connected-app-updates.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-29-workspace-members-without-admin-access-now-see-a-clear-permi.md +6 -0
- package/corpus/templates/dispatch/server/lib/usage-metrics.ts +2 -1
- package/corpus/templates/plan/app/lib/plan-annotation-runtime.ts +3 -4
- package/corpus/templates/plan/server/routes/[...page].get.ts +2 -5
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +15 -0
- package/corpus/templates/slides/actions/delete-design-system.ts +145 -0
- package/corpus/templates/slides/actions/list-design-systems.ts +94 -2
- package/corpus/templates/slides/actions/patch-deck.ts +29 -17
- package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +43 -1
- package/corpus/templates/slides/app/hooks/use-design-systems.ts +2 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +7 -0
- package/corpus/templates/slides/app/pages/DesignSystems.tsx +56 -1
- package/corpus/templates/slides/changelog/2026-07-28-delete-a-design-system-you-own-from-the-design-systems-page-.md +6 -0
- package/corpus/toolkit/CHANGELOG.md +6 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/composer/ComposerPlusMenu.tsx +3 -2
- package/dist/action-ui.d.ts +1 -0
- package/dist/action-ui.d.ts.map +1 -1
- package/dist/action-ui.js +1 -0
- package/dist/action-ui.js.map +1 -1
- package/dist/action.d.ts +5 -1
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +13 -5
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/harness/runner.d.ts.map +1 -1
- package/dist/agent/harness/runner.js +5 -0
- package/dist/agent/harness/runner.js.map +1 -1
- package/dist/agent/production-agent.d.ts +16 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +18 -1
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
- package/dist/agent/run-loop-with-resume.js +6 -0
- package/dist/agent/run-loop-with-resume.js.map +1 -1
- package/dist/agent/run-manager.d.ts +14 -0
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +91 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +3 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +35 -3
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/agent/types.d.ts +2 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +4 -6
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/create.d.ts +66 -6
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +765 -66
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +2 -7
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/index.js +5 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.js +83 -47
- package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +16 -9
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +21 -0
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/blocks/library/wireframe-kit.d.ts +2 -0
- package/dist/client/blocks/library/wireframe-kit.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe-kit.js +8 -2
- package/dist/client/blocks/library/wireframe-kit.js.map +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js +1 -1
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +17 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +24 -2
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/run-recovery.d.ts +6 -0
- package/dist/client/chat/run-recovery.d.ts.map +1 -1
- package/dist/client/chat/run-recovery.js +13 -3
- package/dist/client/chat/run-recovery.js.map +1 -1
- package/dist/client/chat/widgets/DataTableWidget.d.ts.map +1 -1
- package/dist/client/chat/widgets/DataTableWidget.js +2 -3
- package/dist/client/chat/widgets/DataTableWidget.js.map +1 -1
- package/dist/client/chat/widgets/WorkspaceFileWidget.d.ts +5 -0
- package/dist/client/chat/widgets/WorkspaceFileWidget.d.ts.map +1 -0
- package/dist/client/chat/widgets/WorkspaceFileWidget.js +34 -0
- package/dist/client/chat/widgets/WorkspaceFileWidget.js.map +1 -0
- package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
- package/dist/client/chat/widgets/builtin-tool-renderers.js +13 -1
- package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
- package/dist/client/chat/widgets/workspace-file-result.d.ts +12 -0
- package/dist/client/chat/widgets/workspace-file-result.d.ts.map +1 -0
- package/dist/client/chat/widgets/workspace-file-result.js +34 -0
- package/dist/client/chat/widgets/workspace-file-result.js.map +1 -0
- package/dist/client/embed-auth.d.ts.map +1 -1
- package/dist/client/embed-auth.js +2 -1
- package/dist/client/embed-auth.js.map +1 -1
- package/dist/client/org/InvitationBanner.d.ts +5 -2
- package/dist/client/org/InvitationBanner.d.ts.map +1 -1
- package/dist/client/org/InvitationBanner.js +9 -2
- package/dist/client/org/InvitationBanner.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +3 -2
- 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 +27 -3
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/org/WorkspaceNotice.d.ts +18 -0
- package/dist/client/org/WorkspaceNotice.d.ts.map +1 -0
- package/dist/client/org/WorkspaceNotice.js +56 -0
- package/dist/client/org/WorkspaceNotice.js.map +1 -0
- package/dist/client/org/hooks.d.ts +1 -0
- package/dist/client/org/hooks.d.ts.map +1 -1
- package/dist/client/org/hooks.js +12 -0
- package/dist/client/org/hooks.js.map +1 -1
- package/dist/client/org/index.d.ts +2 -1
- package/dist/client/org/index.d.ts.map +1 -1
- package/dist/client/org/index.js +2 -1
- package/dist/client/org/index.js.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.js +8 -12
- package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts +3 -0
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +49 -20
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
- package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.js +3 -0
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/client/resources/use-resources.d.ts +1 -0
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js +3 -0
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/use-action.d.ts +3 -1
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +3 -1
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/widgets/index.d.ts +1 -1
- package/dist/client/widgets/index.d.ts.map +1 -1
- package/dist/client/widgets/index.js +1 -1
- package/dist/client/widgets/index.js.map +1 -1
- package/dist/coding-tools/run-code.js +2 -1
- package/dist/coding-tools/run-code.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/client.d.ts +1 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +24 -3
- package/dist/db/client.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +25 -3
- package/dist/deploy/build.js.map +1 -1
- package/dist/eject/remote-mcp-presets.js +1 -1
- package/dist/eject/remote-mcp-presets.js.map +1 -1
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.browser.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/a2a-continuation-processor.d.ts +5 -0
- package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
- package/dist/integrations/a2a-continuation-processor.js +293 -79
- package/dist/integrations/a2a-continuation-processor.js.map +1 -1
- package/dist/integrations/a2a-continuations-store.d.ts +23 -1
- package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
- package/dist/integrations/a2a-continuations-store.js +249 -15
- package/dist/integrations/a2a-continuations-store.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +155 -31
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts.map +1 -1
- package/dist/integrations/google-docs-poller.js +4 -1
- package/dist/integrations/google-docs-poller.js.map +1 -1
- package/dist/integrations/integration-campaign-recovery.d.ts.map +1 -1
- package/dist/integrations/integration-campaign-recovery.js +3 -1
- package/dist/integrations/integration-campaign-recovery.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +29 -12
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/task-queue-stats.d.ts +12 -0
- package/dist/integrations/task-queue-stats.d.ts.map +1 -1
- package/dist/integrations/task-queue-stats.js +106 -0
- package/dist/integrations/task-queue-stats.js.map +1 -1
- package/dist/integrations/types.d.ts +24 -6
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/types.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +35 -14
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/scheduler.js +4 -0
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/localization/default-messages.d.ts +3 -2
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +3 -2
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +27 -7
- package/dist/observability/traces.js.map +1 -1
- package/dist/org/handlers.d.ts +15 -0
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +45 -1
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/migrations.d.ts.map +1 -1
- package/dist/org/migrations.js +4 -0
- package/dist/org/migrations.js.map +1 -1
- package/dist/org/plugin.d.ts +1 -0
- package/dist/org/plugin.d.ts.map +1 -1
- package/dist/org/plugin.js +10 -1
- package/dist/org/plugin.js.map +1 -1
- package/dist/org/schema.d.ts +19 -0
- package/dist/org/schema.d.ts.map +1 -1
- package/dist/org/schema.js +1 -0
- package/dist/org/schema.js.map +1 -1
- package/dist/org/types.d.ts +8 -0
- package/dist/org/types.d.ts.map +1 -1
- package/dist/org/types.js.map +1 -1
- package/dist/org/workspace-url.d.ts +32 -0
- package/dist/org/workspace-url.d.ts.map +1 -0
- package/dist/org/workspace-url.js +63 -0
- package/dist/org/workspace-url.js.map +1 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- package/dist/provider-api/actions/provider-api.d.ts +7 -7
- package/dist/resources/handlers.d.ts +3 -4
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +25 -5
- package/dist/resources/handlers.js.map +1 -1
- package/dist/scripts/runner.d.ts +17 -0
- package/dist/scripts/runner.d.ts.map +1 -1
- package/dist/scripts/runner.js +130 -5
- package/dist/scripts/runner.js.map +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +24 -2
- 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 +26 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +10 -1
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/auth.d.ts +22 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +33 -7
- package/dist/server/auth.js.map +1 -1
- package/dist/server/embed-route.d.ts.map +1 -1
- package/dist/server/embed-route.js +6 -1
- package/dist/server/embed-route.js.map +1 -1
- package/dist/server/embed-session.d.ts +7 -0
- package/dist/server/embed-session.d.ts.map +1 -1
- package/dist/server/embed-session.js +46 -4
- package/dist/server/embed-session.js.map +1 -1
- package/dist/server/open-route.d.ts.map +1 -1
- package/dist/server/open-route.js +17 -7
- package/dist/server/open-route.js.map +1 -1
- package/dist/server/prompts/framework-core-compact.js +1 -1
- package/dist/server/prompts/framework-core-compact.js.map +1 -1
- package/dist/server/prompts/framework-core.d.ts.map +1 -1
- package/dist/server/prompts/framework-core.js +1 -0
- package/dist/server/prompts/framework-core.js.map +1 -1
- package/dist/server/request-context.d.ts +26 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +18 -1
- package/dist/server/request-context.js.map +1 -1
- package/dist/shared/embed-auth.d.ts +1 -0
- package/dist/shared/embed-auth.d.ts.map +1 -1
- package/dist/shared/embed-auth.js +1 -0
- package/dist/shared/embed-auth.js.map +1 -1
- package/dist/shared/html-document.d.ts +12 -0
- package/dist/shared/html-document.d.ts.map +1 -0
- package/dist/shared/html-document.js +92 -0
- package/dist/shared/html-document.js.map +1 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +1 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/sharing/access.d.ts +1 -0
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +8 -2
- package/dist/sharing/access.js.map +1 -1
- package/dist/sharing/registry.d.ts +3 -0
- package/dist/sharing/registry.d.ts.map +1 -1
- package/dist/sharing/registry.js.map +1 -1
- package/dist/workspace-files/actions.d.ts +28 -0
- package/dist/workspace-files/actions.d.ts.map +1 -0
- package/dist/workspace-files/actions.js +75 -0
- package/dist/workspace-files/actions.js.map +1 -0
- package/dist/workspace-files/tool.d.ts.map +1 -1
- package/dist/workspace-files/tool.js +4 -0
- package/dist/workspace-files/tool.js.map +1 -1
- package/docs/content/cloneable-saas.mdx +114 -0
- package/docs/content/creating-templates.mdx +28 -2
- package/docs/content/syncing-template-changes.mdx +7 -0
- package/docs/content/template-clips-developers.mdx +12 -5
- package/docs/content/template-dispatch-developers.mdx +1 -1
- package/docs/content/template-dispatch.mdx +1 -1
- package/package.json +2 -2
- package/src/action-ui.ts +1 -0
- package/src/action.ts +5 -1
- package/src/agent/engine/ai-sdk-engine.ts +15 -5
- package/src/agent/harness/runner.ts +5 -0
- package/src/agent/production-agent.ts +33 -0
- package/src/agent/run-loop-with-resume.ts +5 -0
- package/src/agent/run-manager.ts +126 -1
- package/src/agent/thread-data-builder.ts +47 -2
- package/src/agent/types.ts +2 -0
- package/src/chat-threads/store.ts +4 -5
- package/src/cli/create.ts +1139 -65
- package/src/cli/design-connect.ts +3 -7
- package/src/cli/index.ts +5 -3
- package/src/cli/skills-content/design-visual-edit-skill.ts +83 -47
- package/src/client/AssistantChat.tsx +27 -16
- package/src/client/agent-chat-adapter.ts +24 -0
- package/src/client/blocks/library/wireframe-kit.tsx +17 -2
- package/src/client/chat/index.ts +1 -0
- package/src/client/chat/message-components.tsx +104 -1
- package/src/client/chat/run-recovery.tsx +15 -3
- package/src/client/chat/widgets/DataTableWidget.tsx +10 -29
- package/src/client/chat/widgets/WorkspaceFileWidget.tsx +71 -0
- package/src/client/chat/widgets/builtin-tool-renderers.tsx +22 -0
- package/src/client/chat/widgets/workspace-file-result.ts +49 -0
- package/src/client/embed-auth.ts +2 -0
- package/src/client/org/InvitationBanner.tsx +14 -1
- package/src/client/org/OrgSwitcher.tsx +23 -0
- package/src/client/org/TeamPage.tsx +130 -0
- package/src/client/org/WorkspaceNotice.tsx +85 -0
- package/src/client/org/hooks.ts +14 -0
- package/src/client/org/index.ts +2 -0
- package/src/client/resources/McpIntegrationDialog.tsx +27 -40
- package/src/client/resources/ResourcesPanel.tsx +134 -51
- package/src/client/resources/mcp-integration-catalog.ts +7 -0
- package/src/client/resources/use-resources.ts +6 -0
- package/src/client/use-action.ts +3 -1
- package/src/client/widgets/index.ts +1 -0
- package/src/coding-tools/run-code.ts +2 -1
- package/src/db/client.ts +28 -4
- package/src/deploy/build.ts +31 -3
- package/src/eject/remote-mcp-presets.ts +1 -1
- package/src/index.browser.ts +1 -0
- package/src/index.ts +1 -0
- package/src/integrations/a2a-continuation-processor.ts +481 -122
- package/src/integrations/a2a-continuations-store.ts +345 -14
- package/src/integrations/adapters/slack.ts +243 -53
- package/src/integrations/google-docs-poller.ts +3 -0
- package/src/integrations/integration-campaign-recovery.ts +4 -1
- package/src/integrations/plugin.ts +39 -21
- package/src/integrations/task-queue-stats.ts +146 -0
- package/src/integrations/types.ts +25 -4
- package/src/integrations/webhook-handler.ts +46 -16
- package/src/jobs/scheduler.ts +4 -0
- package/src/localization/default-messages.ts +3 -2
- package/src/observability/traces.ts +48 -12
- package/src/org/handlers.ts +52 -1
- package/src/org/migrations.ts +4 -0
- package/src/org/plugin.ts +14 -0
- package/src/org/schema.ts +1 -0
- package/src/org/types.ts +8 -0
- package/src/org/workspace-url.ts +74 -0
- package/src/resources/handlers.ts +35 -5
- package/src/scripts/runner.ts +183 -5
- package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +2 -1
- package/src/server/action-routes.ts +32 -2
- package/src/server/agent-chat-plugin.ts +29 -0
- package/src/server/agent-teams.ts +10 -1
- package/src/server/auth.ts +33 -7
- package/src/server/embed-route.ts +9 -0
- package/src/server/embed-session.ts +62 -3
- package/src/server/open-route.ts +20 -6
- package/src/server/prompts/framework-core-compact.ts +1 -1
- package/src/server/prompts/framework-core.ts +1 -0
- package/src/server/request-context.ts +36 -1
- package/src/shared/embed-auth.ts +1 -0
- package/src/shared/html-document.ts +115 -0
- package/src/shared/index.ts +1 -0
- package/src/sharing/access.ts +8 -1
- package/src/sharing/registry.ts +11 -2
- package/src/workspace-files/actions.ts +100 -0
- package/src/workspace-files/tool.ts +4 -0
- package/corpus/templates/design/changelog/2026-07-28-interact-mode-can-preview-designs-in-responsive-device-sizes.md +0 -6
- package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-opens-a-full-screen-responsive-preview-wit.md +0 -6
|
@@ -23,8 +23,9 @@ import {
|
|
|
23
23
|
shouldAllowMcpEmbedCredentials,
|
|
24
24
|
} from "../shared/mcp-embed-headers.js";
|
|
25
25
|
import {
|
|
26
|
-
|
|
26
|
+
isEmbedCapabilityScope,
|
|
27
27
|
requestHasEmbedAuthMarker,
|
|
28
|
+
resolveEmbedSessionFromRequest,
|
|
28
29
|
} from "./embed-session.js";
|
|
29
30
|
import type { H3AppShim } from "./framework-request-handler.js";
|
|
30
31
|
|
|
@@ -351,6 +352,7 @@ export function getCookieDomain(): string | undefined {
|
|
|
351
352
|
export const COOKIE_NAME = AUTH_COOKIE_NAMESPACE.frameworkCookieName;
|
|
352
353
|
export const BETTER_AUTH_COOKIE_PREFIX =
|
|
353
354
|
AUTH_COOKIE_NAMESPACE.betterAuthCookiePrefix;
|
|
355
|
+
const AUTH_DISABLED_OPT_OUT_COOKIE = `${COOKIE_NAME}_auth_disabled_opt_out`;
|
|
354
356
|
|
|
355
357
|
/**
|
|
356
358
|
* Cookie domain attribute spread into every `setCookie`/`deleteCookie`.
|
|
@@ -2047,8 +2049,11 @@ function isAuthDisabled(): boolean {
|
|
|
2047
2049
|
return value === "1" || value === "true";
|
|
2048
2050
|
}
|
|
2049
2051
|
|
|
2050
|
-
function getAuthDisabledSession(): AuthSession | null {
|
|
2052
|
+
function getAuthDisabledSession(event: H3Event): AuthSession | null {
|
|
2051
2053
|
if (!isAuthDisabled()) return null;
|
|
2054
|
+
if (getCookieValues(event, AUTH_DISABLED_OPT_OUT_COOKIE).includes("1")) {
|
|
2055
|
+
return null;
|
|
2056
|
+
}
|
|
2052
2057
|
if (!authDisabledWarningLogged) {
|
|
2053
2058
|
authDisabledWarningLogged = true;
|
|
2054
2059
|
console.warn(
|
|
@@ -2058,6 +2063,17 @@ function getAuthDisabledSession(): AuthSession | null {
|
|
|
2058
2063
|
return { email: AUTO_DEV_ACCOUNT_EMAIL };
|
|
2059
2064
|
}
|
|
2060
2065
|
|
|
2066
|
+
function optOutOfAuthDisabledSession(event: H3Event): void {
|
|
2067
|
+
if (!isAuthDisabled()) return;
|
|
2068
|
+
setCookie(event, AUTH_DISABLED_OPT_OUT_COOKIE, "1", {
|
|
2069
|
+
httpOnly: true,
|
|
2070
|
+
...crossSiteCookieAttrs(event),
|
|
2071
|
+
...cookieDomainAttrs(),
|
|
2072
|
+
path: "/",
|
|
2073
|
+
maxAge: sessionMaxAge,
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2061
2077
|
async function hasAutoDevAccountUser(
|
|
2062
2078
|
db: ReturnType<typeof getDbExec>,
|
|
2063
2079
|
): Promise<boolean> {
|
|
@@ -2314,7 +2330,7 @@ async function resolveSessionUncached(
|
|
|
2314
2330
|
// an_session cookie prevents a stale cookie (common when an ACCESS_TOKEN is
|
|
2315
2331
|
// configured) from shadowing the embed identity.
|
|
2316
2332
|
const embedSession = await resolveEmbedSessionFromRequest(event);
|
|
2317
|
-
if (embedSession) {
|
|
2333
|
+
if (embedSession && !isEmbedCapabilityScope(embedSession.scope)) {
|
|
2318
2334
|
return {
|
|
2319
2335
|
email: embedSession.email,
|
|
2320
2336
|
token: embedSession.token,
|
|
@@ -2394,7 +2410,7 @@ async function resolveSessionUncached(
|
|
|
2394
2410
|
// 9. AUTH_DISABLED fallback — only when no session resolved above.
|
|
2395
2411
|
// Must run after BYOA customGetSession so infrastructure/custom auth keeps
|
|
2396
2412
|
// caller identity instead of collapsing to the shared preview user.
|
|
2397
|
-
const authDisabledSession = getAuthDisabledSession();
|
|
2413
|
+
const authDisabledSession = getAuthDisabledSession(event);
|
|
2398
2414
|
if (authDisabledSession) return authDisabledSession;
|
|
2399
2415
|
|
|
2400
2416
|
return null;
|
|
@@ -2452,8 +2468,9 @@ export function setFrameworkSessionCookie(event: H3Event, token: string): void {
|
|
|
2452
2468
|
}
|
|
2453
2469
|
|
|
2454
2470
|
/**
|
|
2455
|
-
* Build a redirect `Response` that carries
|
|
2456
|
-
*
|
|
2471
|
+
* Build a redirect `Response` that carries the security-sensitive headers just
|
|
2472
|
+
* staged on the event (e.g. by `setFrameworkSessionCookie` or query-session
|
|
2473
|
+
* promotion).
|
|
2457
2474
|
*
|
|
2458
2475
|
* h3 v2's `setCookie` appends the cookie onto `event.res.headers`. When a
|
|
2459
2476
|
* handler returns a plain object/string, h3's `prepareResponse` merges those
|
|
@@ -2471,7 +2488,7 @@ export function setFrameworkSessionCookie(event: H3Event, token: string): void {
|
|
|
2471
2488
|
* any non-Response continuation path; h3 only skips the merge for the
|
|
2472
2489
|
* Response branch, so there's no double-emit.)
|
|
2473
2490
|
*/
|
|
2474
|
-
function redirectWithStagedCookies(
|
|
2491
|
+
export function redirectWithStagedCookies(
|
|
2475
2492
|
event: H3Event,
|
|
2476
2493
|
location: string,
|
|
2477
2494
|
status = 302,
|
|
@@ -2479,6 +2496,8 @@ function redirectWithStagedCookies(
|
|
|
2479
2496
|
const headers = new Headers({ Location: location });
|
|
2480
2497
|
const staged = event.res?.headers?.getSetCookie?.() ?? [];
|
|
2481
2498
|
for (const cookie of staged) headers.append("set-cookie", cookie);
|
|
2499
|
+
const referrerPolicy = event.res?.headers?.get?.("Referrer-Policy");
|
|
2500
|
+
if (referrerPolicy) headers.set("Referrer-Policy", referrerPolicy);
|
|
2482
2501
|
return new Response("", { status, headers });
|
|
2483
2502
|
}
|
|
2484
2503
|
|
|
@@ -3045,6 +3064,9 @@ async function mountBetterAuthRoutes(
|
|
|
3045
3064
|
const isSendVerificationEmail =
|
|
3046
3065
|
reqPath.includes("send-verification-email") &&
|
|
3047
3066
|
getMethod(event) === "POST";
|
|
3067
|
+
const isSignOut =
|
|
3068
|
+
reqPath.includes("sign-out") && getMethod(event) === "POST";
|
|
3069
|
+
if (isSignOut) optOutOfAuthDisabledSession(event);
|
|
3048
3070
|
const authRequest = toWebRequest(event);
|
|
3049
3071
|
let requestForAuth = authRequest;
|
|
3050
3072
|
|
|
@@ -3354,6 +3376,7 @@ async function mountBetterAuthRoutes(
|
|
|
3354
3376
|
const bearerToken = getBearerSessionToken(event);
|
|
3355
3377
|
if (bearerToken) await removeSession(bearerToken);
|
|
3356
3378
|
clearFrameworkSessionCookies(event);
|
|
3379
|
+
optOutOfAuthDisabledSession(event);
|
|
3357
3380
|
|
|
3358
3381
|
try {
|
|
3359
3382
|
await auth.api.signOut({ headers: event.headers });
|
|
@@ -3421,6 +3444,7 @@ async function mountBetterAuthRoutes(
|
|
|
3421
3444
|
// 3. Drop the current request's cookie and best-effort sign out
|
|
3422
3445
|
// of Better Auth (so the response sets the proper expiry header).
|
|
3423
3446
|
clearFrameworkSessionCookies(event);
|
|
3447
|
+
optOutOfAuthDisabledSession(event);
|
|
3424
3448
|
try {
|
|
3425
3449
|
await auth.api.signOut({ headers: event.headers });
|
|
3426
3450
|
} catch {
|
|
@@ -3589,6 +3613,7 @@ function mountAuthFallbackRoutes(app: H3App): void {
|
|
|
3589
3613
|
const bearerToken = getBearerSessionToken(event);
|
|
3590
3614
|
if (bearerToken) await removeSession(bearerToken);
|
|
3591
3615
|
clearFrameworkSessionCookies(event);
|
|
3616
|
+
optOutOfAuthDisabledSession(event);
|
|
3592
3617
|
|
|
3593
3618
|
try {
|
|
3594
3619
|
const auth = await getBetterAuth();
|
|
@@ -3746,6 +3771,7 @@ export async function autoMountAuth(
|
|
|
3746
3771
|
const bearerToken = getBearerSessionToken(event);
|
|
3747
3772
|
if (bearerToken) await removeSession(bearerToken);
|
|
3748
3773
|
clearFrameworkSessionCookies(event);
|
|
3774
|
+
optOutOfAuthDisabledSession(event);
|
|
3749
3775
|
if (isElectronRequest(event)) await clearDesktopSso();
|
|
3750
3776
|
return { ok: true };
|
|
3751
3777
|
}),
|
|
@@ -22,6 +22,7 @@ import { getConfiguredAppBasePath } from "./app-base-path.js";
|
|
|
22
22
|
import type { AuthSession } from "./auth.js";
|
|
23
23
|
import {
|
|
24
24
|
consumeEmbedSessionTicket,
|
|
25
|
+
isEmbedCapabilityScope,
|
|
25
26
|
normalizeEmbedTargetPath,
|
|
26
27
|
setEmbedSessionCookie,
|
|
27
28
|
signEmbedSessionToken,
|
|
@@ -263,6 +264,14 @@ export function createEmbedStartRouteHandler(
|
|
|
263
264
|
orgId: consumed.orgId,
|
|
264
265
|
targetPath: target,
|
|
265
266
|
scope: consumed.scope,
|
|
267
|
+
...(isEmbedCapabilityScope(consumed.scope)
|
|
268
|
+
? {
|
|
269
|
+
ttlSeconds: Math.max(
|
|
270
|
+
1,
|
|
271
|
+
Math.floor((consumed.expiresAt - Date.now()) / 1000),
|
|
272
|
+
),
|
|
273
|
+
}
|
|
274
|
+
: {}),
|
|
266
275
|
});
|
|
267
276
|
setEmbedSessionCookie(event, token);
|
|
268
277
|
setResponseHeader(event, "Referrer-Policy", "no-referrer");
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
EMBED_MODE_QUERY_PARAM,
|
|
16
16
|
EMBED_SESSION_COOKIE,
|
|
17
17
|
EMBED_TARGET_HEADER,
|
|
18
|
+
EMBED_TARGET_QUERY_PARAM,
|
|
18
19
|
EMBED_TOKEN_QUERY_PARAM,
|
|
19
20
|
} from "../shared/embed-auth.js";
|
|
20
21
|
import { normalizeAppPath } from "../shared/sign-in-journey.js";
|
|
@@ -24,6 +25,7 @@ import { getWorkspaceA2ADerivedSecret } from "./derived-secret.js";
|
|
|
24
25
|
const TOKEN_KIND = "agent-native-embed-session";
|
|
25
26
|
const DEFAULT_TOKEN_TTL_SECONDS = 60 * 60;
|
|
26
27
|
const DEFAULT_TICKET_TTL_SECONDS = 5 * 60;
|
|
28
|
+
const EMBED_CAPABILITY_SCOPE_PREFIX = "capability:";
|
|
27
29
|
const CONTROL_CHARS = new RegExp("[\\u0000-\\u001f\\u007f]");
|
|
28
30
|
const OPEN_ROUTE_PATH = "/_agent-native/open";
|
|
29
31
|
const OPEN_ROUTE_VIEW_PATHS: Record<string, string> = {
|
|
@@ -114,6 +116,34 @@ export type ResolvedEmbedSession = {
|
|
|
114
116
|
scope?: string;
|
|
115
117
|
};
|
|
116
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Capability embed scopes authorize one narrow, non-identity operation. They
|
|
121
|
+
* must never be promoted into the ticket owner's authenticated browser
|
|
122
|
+
* session: the owner claim only records who minted the capability.
|
|
123
|
+
*/
|
|
124
|
+
export function isEmbedCapabilityScope(
|
|
125
|
+
scope: string | undefined | null,
|
|
126
|
+
): boolean {
|
|
127
|
+
return (
|
|
128
|
+
typeof scope === "string" && scope.startsWith(EMBED_CAPABILITY_SCOPE_PREFIX)
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function resolvedEmbedCapabilityScope(
|
|
133
|
+
session: ResolvedEmbedSession | null,
|
|
134
|
+
): string | undefined {
|
|
135
|
+
const scope = session?.scope;
|
|
136
|
+
if (
|
|
137
|
+
!isEmbedCapabilityScope(scope) ||
|
|
138
|
+
!scope ||
|
|
139
|
+
scope.length > 512 ||
|
|
140
|
+
CONTROL_CHARS.test(scope)
|
|
141
|
+
) {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
return scope;
|
|
145
|
+
}
|
|
146
|
+
|
|
117
147
|
async function ensureTable(): Promise<void> {
|
|
118
148
|
if (!_initPromise) {
|
|
119
149
|
_initPromise = (async () => {
|
|
@@ -394,7 +424,12 @@ function headerTargetPathname(event: H3Event): string | null {
|
|
|
394
424
|
if (typeof direct === "string") return pathnameFromPath(direct);
|
|
395
425
|
try {
|
|
396
426
|
const raw = getHeader(event, EMBED_TARGET_HEADER);
|
|
397
|
-
|
|
427
|
+
if (typeof raw === "string") return pathnameFromPath(raw);
|
|
428
|
+
const queryValue = getQuery(event)?.[EMBED_TARGET_QUERY_PARAM];
|
|
429
|
+
const queryTarget = Array.isArray(queryValue) ? queryValue[0] : queryValue;
|
|
430
|
+
return typeof queryTarget === "string"
|
|
431
|
+
? pathnameFromPath(queryTarget)
|
|
432
|
+
: null;
|
|
398
433
|
} catch {
|
|
399
434
|
return null;
|
|
400
435
|
}
|
|
@@ -474,6 +509,17 @@ function isEmbedRuntimeRequest(event: H3Event): boolean {
|
|
|
474
509
|
);
|
|
475
510
|
}
|
|
476
511
|
|
|
512
|
+
function isEmbedStaticRuntimeRequest(event: H3Event): boolean {
|
|
513
|
+
const pathname = requestPathname(event);
|
|
514
|
+
return (
|
|
515
|
+
!!pathname &&
|
|
516
|
+
(pathname.startsWith("/@") ||
|
|
517
|
+
pathname.startsWith("/app/") ||
|
|
518
|
+
pathname.startsWith("/node_modules/") ||
|
|
519
|
+
pathname.startsWith("/packages/"))
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
|
|
477
523
|
export function normalizeEmbedTargetPath(
|
|
478
524
|
raw: string | undefined | null,
|
|
479
525
|
requestOrigin?: string,
|
|
@@ -751,7 +797,14 @@ export async function resolveEmbedSessionFromRequest(
|
|
|
751
797
|
candidate.source === "cookie" && isRuntimeRequest;
|
|
752
798
|
const isRuntimeQueryRequest =
|
|
753
799
|
candidate.source === "query" && isRuntimeRequest;
|
|
754
|
-
|
|
800
|
+
const capabilityScope = isEmbedCapabilityScope(verified.claims.scope);
|
|
801
|
+
const allowsUnboundRuntimeRequest =
|
|
802
|
+
!capabilityScope || isEmbedStaticRuntimeRequest(event);
|
|
803
|
+
if (
|
|
804
|
+
!matchesTarget &&
|
|
805
|
+
(!allowsUnboundRuntimeRequest ||
|
|
806
|
+
(!isRuntimeCookieRequest && !isRuntimeQueryRequest))
|
|
807
|
+
) {
|
|
755
808
|
continue;
|
|
756
809
|
}
|
|
757
810
|
if (candidate.source === "query" && candidate.token) {
|
|
@@ -789,10 +842,16 @@ export function requestHasEmbedAuthMarker(event: H3Event): boolean {
|
|
|
789
842
|
const runtimeRequest = isEmbedRuntimeRequest(event);
|
|
790
843
|
for (const candidate of candidates) {
|
|
791
844
|
const verified = verifyEmbedSessionToken(candidate.token);
|
|
845
|
+
const allowsUnboundRuntimeRequest =
|
|
846
|
+
verified.ok &&
|
|
847
|
+
(!isEmbedCapabilityScope(verified.claims.scope) ||
|
|
848
|
+
isEmbedStaticRuntimeRequest(event));
|
|
792
849
|
if (
|
|
793
850
|
verified.ok &&
|
|
794
851
|
(requestMatchesEmbedTarget(event, verified.claims.targetPath) ||
|
|
795
|
-
(candidate.allowRuntime &&
|
|
852
|
+
(candidate.allowRuntime &&
|
|
853
|
+
runtimeRequest &&
|
|
854
|
+
allowsUnboundRuntimeRequest))
|
|
796
855
|
) {
|
|
797
856
|
return true;
|
|
798
857
|
}
|
|
@@ -40,7 +40,11 @@ import {
|
|
|
40
40
|
} from "../shared/mcp-embed-headers.js";
|
|
41
41
|
import { normalizeAppPath } from "../shared/sign-in-journey.js";
|
|
42
42
|
import { getConfiguredAppBasePath } from "./app-base-path.js";
|
|
43
|
-
import {
|
|
43
|
+
import {
|
|
44
|
+
getSession,
|
|
45
|
+
getConfiguredLoginHtml,
|
|
46
|
+
redirectWithStagedCookies,
|
|
47
|
+
} from "./auth.js";
|
|
44
48
|
import { requestHasEmbedAuthMarker } from "./embed-session.js";
|
|
45
49
|
|
|
46
50
|
/** Query keys that are route control, not navigation payload. */
|
|
@@ -49,6 +53,11 @@ const RESERVED = new Set([
|
|
|
49
53
|
"view",
|
|
50
54
|
"to",
|
|
51
55
|
"compose",
|
|
56
|
+
// Mobile/caller-session bridge token (see `promoteQuerySession` in
|
|
57
|
+
// auth.ts). `getSession()` below reads and promotes it into a cookie; it
|
|
58
|
+
// must never also land in `navParams`, or it would be persisted into the
|
|
59
|
+
// `navigate` application-state row that the client polls and reads.
|
|
60
|
+
"_session",
|
|
52
61
|
EMBED_MODE_QUERY_PARAM,
|
|
53
62
|
EMBED_TOKEN_QUERY_PARAM,
|
|
54
63
|
MCP_APP_CHAT_BRIDGE_QUERY_PARAM,
|
|
@@ -138,11 +147,16 @@ function redirect(
|
|
|
138
147
|
location: string,
|
|
139
148
|
embedRedirect: boolean,
|
|
140
149
|
): Response {
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
150
|
+
// A bare `new Response("", { status: 302, headers: { Location } })` here
|
|
151
|
+
// would silently drop the Set-Cookie `getSession()` just staged below (e.g.
|
|
152
|
+
// `promoteQuerySession` promoting a `_session` query token) — h3 v2 only
|
|
153
|
+
// merges `event.res.headers`-staged cookies onto a returned Response when
|
|
154
|
+
// it's 2xx. Route through the same cookie-preserving redirect auth.ts uses.
|
|
155
|
+
const response = redirectWithStagedCookies(event, location);
|
|
156
|
+
if (!embedRedirect) return response;
|
|
157
|
+
const headers = new Headers(response.headers);
|
|
158
|
+
addMcpEmbedHeaders(event, headers);
|
|
159
|
+
return new Response("", { status: response.status, headers });
|
|
146
160
|
}
|
|
147
161
|
|
|
148
162
|
function appendSearchParams(target: string, params: URLSearchParams): string {
|
|
@@ -76,7 +76,7 @@ Bring a senior engineer's judgment, arrived at through attention not premature c
|
|
|
76
76
|
7. **Security** — ${securityRule}
|
|
77
77
|
${sharedRule8(examples, options)}
|
|
78
78
|
${SHARED_RULE_9}
|
|
79
|
-
**Native widgets** — For table/chart/graph/report requests, prefer actions labeled \`Native chat widget\`; use \`render-data-widget\` for already-summarized data (≤50 rows) instead of markdown tables. Above that, give the total plus the top rows — never retype a full result set as widget arguments.
|
|
79
|
+
**Native widgets** — For table/chart/graph/report requests, prefer actions labeled \`Native chat widget\`; use \`render-data-widget\` for already-summarized data (≤50 rows) instead of markdown tables. Above that, give the total plus the top rows — never retype a full result set as widget arguments. Deliver files in chat, never just a path.
|
|
80
80
|
10. **Your tool list is not the whole surface** — Most app actions and connected MCP tools load on demand, so search the live registry with \`tool-search\` before concluding a capability doesn't exist.
|
|
81
81
|
11. **Relative dates use runtime context** — The \`<runtime-context>\` block gives the authoritative current date/time. Resolve "today", "yesterday", "last week", and similar phrases to explicit calendar dates before querying data or creating artifacts.
|
|
82
82
|
${SHARED_RULE_14}
|
|
@@ -98,6 +98,7 @@ ${securityRule}
|
|
|
98
98
|
${sharedRule8(examples, options)}
|
|
99
99
|
${SHARED_RULE_9}
|
|
100
100
|
**Native chat widgets** — When an available action says it renders a native widget such as \`data-table\`, \`data-chart\`, or \`data-insights\`, call that action for user requests asking for a table, chart, graph, trend, report, or inline data view. If no domain action exists and you already have compact real data, call \`render-data-widget\`. Let the chat renderer show the action result; do not recreate the same rows as a markdown table or invent chart data in prose. Add only a short human summary or next-step link around the widget. Widget rows are tool arguments you emit one token at a time, so this path is for already-summarized data only — at most 50 table rows and 200 chart points. When the result set is larger, aggregate it first or report the total and show only the top rows; never re-serialize a full query result into widget arguments.
|
|
101
|
+
**Downloadable files** — When the user asks you to create or export a file, deliver it in the same chat turn. For compact tabular results, prefer \`render-data-widget\` so the user gets the native Download CSV action without a second stored copy. For a complete or durable file written through \`workspaceWrite\`, use a normal non-\`scratch/\` path and then call \`show-workspace-file\` with that path so chat renders a direct download card. Never finish by giving filesystem paths or telling the user to navigate elsewhere to find the file.
|
|
101
102
|
10. **Your tool list is not the whole surface** — Most app actions and connected MCP tools load on demand, so search the live registry with \`tool-search\` before concluding a capability doesn't exist.
|
|
102
103
|
11. **Relative dates use runtime context** — The \`<runtime-context>\` block gives the authoritative current date/time. Resolve "today", "yesterday", "last week", and similar phrases to explicit calendar dates before querying data or creating artifacts. When answering factual questions, include the exact date or date range you used.
|
|
103
104
|
${SHARED_RULE_14}
|
|
@@ -133,6 +133,12 @@ export interface RequestContext {
|
|
|
133
133
|
userEmail?: string;
|
|
134
134
|
userName?: string;
|
|
135
135
|
orgId?: string;
|
|
136
|
+
/**
|
|
137
|
+
* Narrow authorization capability verified from an embed session. This is
|
|
138
|
+
* deliberately separate from user identity: capability-only sessions must
|
|
139
|
+
* not satisfy account-backed auth or inherit the ticket owner's privileges.
|
|
140
|
+
*/
|
|
141
|
+
authCapability?: string;
|
|
136
142
|
timezone?: string;
|
|
137
143
|
/**
|
|
138
144
|
* Set when code reads authenticated request context. Public SSR shell/data
|
|
@@ -148,6 +154,18 @@ export interface RequestContext {
|
|
|
148
154
|
* fallback. Optional — absent on paths that don't populate it.
|
|
149
155
|
*/
|
|
150
156
|
requestOrigin?: string;
|
|
157
|
+
/**
|
|
158
|
+
* True when the request's real socket peer is loopback, captured by the
|
|
159
|
+
* action-route handler while the h3 event is still in scope (nothing below
|
|
160
|
+
* that layer can see the event). Derived from `getRequestIP()` WITHOUT
|
|
161
|
+
* `x-forwarded-for`, so a remote client cannot set it via headers.
|
|
162
|
+
*
|
|
163
|
+
* A local-dev gate only. A tunnel or reverse proxy that reaches the dev
|
|
164
|
+
* server over loopback also presents as loopback, so this is necessary but
|
|
165
|
+
* not sufficient on its own — pair it with something that scopes the blast
|
|
166
|
+
* radius (a resource that is itself local-only, NODE_ENV, etc.).
|
|
167
|
+
*/
|
|
168
|
+
isLoopbackRequest?: boolean;
|
|
151
169
|
/**
|
|
152
170
|
* True when this request is being processed by an integration-platform
|
|
153
171
|
* webhook (Slack, Telegram, etc.) where the function timeout is the
|
|
@@ -388,9 +406,26 @@ export function getRequestOrgId(): string | undefined {
|
|
|
388
406
|
return processEnv("AGENT_ORG_ID");
|
|
389
407
|
}
|
|
390
408
|
|
|
409
|
+
/** Return the verified capability for this request, without implying identity. */
|
|
410
|
+
export function getRequestAuthCapability(): string | undefined {
|
|
411
|
+
const store = als.getStore();
|
|
412
|
+
if (!store) return undefined;
|
|
413
|
+
if (store.authCapability) markAuthContextAccess(store);
|
|
414
|
+
return store.authCapability;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Whether the current request came from a loopback socket peer. Fails closed:
|
|
419
|
+
* outside a request store (CLI, background job, agent run) there is no peer to
|
|
420
|
+
* vouch for, so this is `false` rather than inheriting an ambient default.
|
|
421
|
+
*/
|
|
422
|
+
export function getRequestIsLoopback(): boolean {
|
|
423
|
+
return als.getStore()?.isLoopbackRequest === true;
|
|
424
|
+
}
|
|
425
|
+
|
|
391
426
|
function markAuthContextAccess(ctx: RequestContext | undefined) {
|
|
392
427
|
if (!ctx) return;
|
|
393
|
-
if (ctx.userEmail || ctx.userName || ctx.orgId) {
|
|
428
|
+
if (ctx.userEmail || ctx.userName || ctx.orgId || ctx.authCapability) {
|
|
394
429
|
ctx.authContextAccessed = true;
|
|
395
430
|
}
|
|
396
431
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export const EMBED_START_PATH = "/_agent-native/embed/start";
|
|
2
2
|
export const EMBED_TOKEN_QUERY_PARAM = "__an_embed_token";
|
|
3
|
+
export const EMBED_TARGET_QUERY_PARAM = "__an_embed_target";
|
|
3
4
|
export const EMBED_MODE_QUERY_PARAM = "embedded";
|
|
4
5
|
export const MCP_APP_CHAT_BRIDGE_QUERY_PARAM = "__an_mcp_chat_bridge";
|
|
5
6
|
export const EMBED_SESSION_COOKIE = "an_embed_session";
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
type HtmlInjectionTarget = "head" | "body";
|
|
2
|
+
const RAW_TEXT_TAG_NAMES = new Set(["script", "style", "textarea", "title"]);
|
|
3
|
+
|
|
4
|
+
function tagEndIndex(html: string, start: number): number {
|
|
5
|
+
let quote: '"' | "'" | null = null;
|
|
6
|
+
|
|
7
|
+
for (let index = start; index < html.length; index += 1) {
|
|
8
|
+
const character = html[index];
|
|
9
|
+
if (quote) {
|
|
10
|
+
if (character === quote) quote = null;
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
if (character === '"' || character === "'") {
|
|
14
|
+
quote = character;
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (character === ">") return index;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return -1;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function tagNameAt(html: string, start: number): string | null {
|
|
24
|
+
const match = /^[A-Za-z][\w:-]*/.exec(html.slice(start));
|
|
25
|
+
return match?.[0]?.toLowerCase() ?? null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function rawTextCloseIndex(html: string, tag: string, start: number): number {
|
|
29
|
+
const pattern = new RegExp(`<\\/${tag}\\s*>`, "gi");
|
|
30
|
+
pattern.lastIndex = start;
|
|
31
|
+
return pattern.exec(html)?.index ?? -1;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function closingTagIndex(
|
|
35
|
+
html: string,
|
|
36
|
+
tag: HtmlInjectionTarget | "html",
|
|
37
|
+
last: boolean,
|
|
38
|
+
): number {
|
|
39
|
+
let index = -1;
|
|
40
|
+
let cursor = 0;
|
|
41
|
+
|
|
42
|
+
while (cursor < html.length) {
|
|
43
|
+
const tagStart = html.indexOf("<", cursor);
|
|
44
|
+
if (tagStart === -1) break;
|
|
45
|
+
|
|
46
|
+
if (html.startsWith("<!--", tagStart)) {
|
|
47
|
+
const commentEnd = html.indexOf("-->", tagStart + 4);
|
|
48
|
+
cursor = commentEnd === -1 ? html.length : commentEnd + 3;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const closing = html[tagStart + 1] === "/";
|
|
53
|
+
const nameStart = tagStart + (closing ? 2 : 1);
|
|
54
|
+
const tagName = tagNameAt(html, nameStart);
|
|
55
|
+
if (!tagName) {
|
|
56
|
+
cursor = tagStart + 1;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const tagEnd = tagEndIndex(html, nameStart + tagName.length);
|
|
61
|
+
if (tagEnd === -1) break;
|
|
62
|
+
|
|
63
|
+
if (
|
|
64
|
+
closing &&
|
|
65
|
+
tagName === tag &&
|
|
66
|
+
!/\S/.test(html.slice(nameStart + tagName.length, tagEnd))
|
|
67
|
+
) {
|
|
68
|
+
index = tagStart;
|
|
69
|
+
if (!last) return index;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!closing && RAW_TEXT_TAG_NAMES.has(tagName)) {
|
|
73
|
+
const rawTextEnd = rawTextCloseIndex(html, tagName, tagEnd + 1);
|
|
74
|
+
cursor =
|
|
75
|
+
rawTextEnd === -1 ? html.length : rawTextEnd + tagName.length + 3;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
cursor = tagEnd + 1;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return index;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Inserts markup at a document boundary without using String.replace's
|
|
87
|
+
* replacement-string semantics. It ignores raw text, attributes, and comments
|
|
88
|
+
* when locating a real closing tag. Body and html closers use their last
|
|
89
|
+
* marker so literal close tags cannot capture the injection.
|
|
90
|
+
*/
|
|
91
|
+
export function injectDocumentMarkup(
|
|
92
|
+
html: string,
|
|
93
|
+
markup: string,
|
|
94
|
+
options: { target?: HtmlInjectionTarget } = {},
|
|
95
|
+
): string {
|
|
96
|
+
if (!markup) return html;
|
|
97
|
+
|
|
98
|
+
const target = options.target ?? "body";
|
|
99
|
+
const targetIndex = closingTagIndex(html, target, target === "body");
|
|
100
|
+
if (targetIndex !== -1) {
|
|
101
|
+
return html.slice(0, targetIndex) + markup + html.slice(targetIndex);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const bodyIndex = closingTagIndex(html, "body", true);
|
|
105
|
+
if (bodyIndex !== -1) {
|
|
106
|
+
return html.slice(0, bodyIndex) + markup + html.slice(bodyIndex);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const htmlIndex = closingTagIndex(html, "html", true);
|
|
110
|
+
if (htmlIndex !== -1) {
|
|
111
|
+
return html.slice(0, htmlIndex) + markup + html.slice(htmlIndex);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return html + markup;
|
|
115
|
+
}
|
|
@@ -20,6 +20,7 @@ export {
|
|
|
20
20
|
type SignInJourneyInput,
|
|
21
21
|
} from "./sign-in-journey.js";
|
|
22
22
|
export { truncate } from "./truncate.js";
|
|
23
|
+
export { injectDocumentMarkup } from "./html-document.js";
|
|
23
24
|
export { withBuilderUtmTrackingParams } from "./builder-link-tracking.js";
|
|
24
25
|
export {
|
|
25
26
|
llmConnectionTrackingProperties,
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { and, eq, or, sql, type SQL } from "drizzle-orm";
|
|
17
17
|
|
|
18
18
|
import {
|
|
19
|
+
getRequestAuthCapability,
|
|
19
20
|
getRequestUserEmail,
|
|
20
21
|
getRequestOrgId,
|
|
21
22
|
} from "../server/request-context.js";
|
|
@@ -54,6 +55,7 @@ export class ForbiddenError extends Error {
|
|
|
54
55
|
export interface AccessContext {
|
|
55
56
|
userEmail?: string;
|
|
56
57
|
orgId?: string;
|
|
58
|
+
authCapability?: string;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
/** Current request's access context. Pulls from request-context ALS. */
|
|
@@ -61,6 +63,7 @@ export function currentAccess(): AccessContext {
|
|
|
61
63
|
return {
|
|
62
64
|
userEmail: getRequestUserEmail(),
|
|
63
65
|
orgId: getRequestOrgId(),
|
|
66
|
+
authCapability: getRequestAuthCapability(),
|
|
64
67
|
};
|
|
65
68
|
}
|
|
66
69
|
|
|
@@ -68,7 +71,11 @@ export function resolveRegisteredAccessContext(
|
|
|
68
71
|
reg: ShareableResourceRegistration | undefined,
|
|
69
72
|
ctx: AccessContext,
|
|
70
73
|
): AccessContext {
|
|
71
|
-
|
|
74
|
+
if (!reg?.resolveAccessContext) return ctx;
|
|
75
|
+
const resolved = reg.resolveAccessContext(ctx);
|
|
76
|
+
return ctx.authCapability
|
|
77
|
+
? { ...resolved, authCapability: ctx.authCapability }
|
|
78
|
+
: resolved;
|
|
72
79
|
}
|
|
73
80
|
|
|
74
81
|
function normalizeEmailForAccess(email: string | undefined): string | null {
|
|
@@ -124,7 +124,11 @@ export interface ShareableResourceRegistration {
|
|
|
124
124
|
| "admin"
|
|
125
125
|
| ((
|
|
126
126
|
resource: any,
|
|
127
|
-
ctx: {
|
|
127
|
+
ctx: {
|
|
128
|
+
userEmail?: string;
|
|
129
|
+
orgId?: string;
|
|
130
|
+
authCapability?: string;
|
|
131
|
+
},
|
|
128
132
|
) =>
|
|
129
133
|
| "viewer"
|
|
130
134
|
| "editor"
|
|
@@ -148,9 +152,14 @@ export interface ShareableResourceRegistration {
|
|
|
148
152
|
* identity can normalize here so the generic framework sharing actions and
|
|
149
153
|
* access helpers stay in sync with template-owned actions.
|
|
150
154
|
*/
|
|
151
|
-
resolveAccessContext?: (ctx: {
|
|
155
|
+
resolveAccessContext?: (ctx: {
|
|
152
156
|
userEmail?: string;
|
|
153
157
|
orgId?: string;
|
|
158
|
+
authCapability?: string;
|
|
159
|
+
}) => {
|
|
160
|
+
userEmail?: string;
|
|
161
|
+
orgId?: string;
|
|
162
|
+
authCapability?: string;
|
|
154
163
|
};
|
|
155
164
|
/**
|
|
156
165
|
* When true, direct ownership is recognized by owner_email regardless of the
|