@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.
Files changed (634) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +78 -0
  3. package/corpus/core/docs/content/cloneable-saas.mdx +114 -0
  4. package/corpus/core/docs/content/creating-templates.mdx +28 -2
  5. package/corpus/core/docs/content/syncing-template-changes.mdx +7 -0
  6. package/corpus/core/docs/content/template-clips-developers.mdx +12 -5
  7. package/corpus/core/docs/content/template-dispatch-developers.mdx +1 -1
  8. package/corpus/core/docs/content/template-dispatch.mdx +1 -1
  9. package/corpus/core/package.json +1 -1
  10. package/corpus/core/src/action-ui.ts +1 -0
  11. package/corpus/core/src/action.ts +5 -1
  12. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +15 -5
  13. package/corpus/core/src/agent/harness/runner.ts +5 -0
  14. package/corpus/core/src/agent/production-agent.ts +33 -0
  15. package/corpus/core/src/agent/run-loop-with-resume.ts +5 -0
  16. package/corpus/core/src/agent/run-manager.ts +126 -1
  17. package/corpus/core/src/agent/thread-data-builder.ts +47 -2
  18. package/corpus/core/src/agent/types.ts +2 -0
  19. package/corpus/core/src/chat-threads/store.ts +4 -5
  20. package/corpus/core/src/cli/create.ts +1139 -65
  21. package/corpus/core/src/cli/design-connect.ts +3 -7
  22. package/corpus/core/src/cli/index.ts +5 -3
  23. package/corpus/core/src/cli/skills-content/design-visual-edit-skill.ts +83 -47
  24. package/corpus/core/src/client/AssistantChat.tsx +27 -16
  25. package/corpus/core/src/client/agent-chat-adapter.ts +24 -0
  26. package/corpus/core/src/client/blocks/library/wireframe-kit.tsx +17 -2
  27. package/corpus/core/src/client/chat/index.ts +1 -0
  28. package/corpus/core/src/client/chat/message-components.tsx +104 -1
  29. package/corpus/core/src/client/chat/run-recovery.tsx +15 -3
  30. package/corpus/core/src/client/chat/widgets/DataTableWidget.tsx +10 -29
  31. package/corpus/core/src/client/chat/widgets/WorkspaceFileWidget.tsx +71 -0
  32. package/corpus/core/src/client/chat/widgets/builtin-tool-renderers.tsx +22 -0
  33. package/corpus/core/src/client/chat/widgets/workspace-file-result.ts +49 -0
  34. package/corpus/core/src/client/embed-auth.ts +2 -0
  35. package/corpus/core/src/client/org/InvitationBanner.tsx +14 -1
  36. package/corpus/core/src/client/org/OrgSwitcher.tsx +23 -0
  37. package/corpus/core/src/client/org/TeamPage.tsx +130 -0
  38. package/corpus/core/src/client/org/WorkspaceNotice.tsx +85 -0
  39. package/corpus/core/src/client/org/hooks.ts +14 -0
  40. package/corpus/core/src/client/org/index.ts +2 -0
  41. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +27 -40
  42. package/corpus/core/src/client/resources/ResourcesPanel.tsx +134 -51
  43. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +7 -0
  44. package/corpus/core/src/client/resources/use-resources.ts +6 -0
  45. package/corpus/core/src/client/use-action.ts +3 -1
  46. package/corpus/core/src/client/widgets/index.ts +1 -0
  47. package/corpus/core/src/coding-tools/run-code.ts +2 -1
  48. package/corpus/core/src/db/client.ts +28 -4
  49. package/corpus/core/src/deploy/build.ts +31 -3
  50. package/corpus/core/src/eject/remote-mcp-presets.ts +1 -1
  51. package/corpus/core/src/index.browser.ts +1 -0
  52. package/corpus/core/src/index.ts +1 -0
  53. package/corpus/core/src/integrations/a2a-continuation-processor.ts +481 -122
  54. package/corpus/core/src/integrations/a2a-continuations-store.ts +345 -14
  55. package/corpus/core/src/integrations/adapters/slack.ts +243 -53
  56. package/corpus/core/src/integrations/google-docs-poller.ts +3 -0
  57. package/corpus/core/src/integrations/integration-campaign-recovery.ts +4 -1
  58. package/corpus/core/src/integrations/plugin.ts +39 -21
  59. package/corpus/core/src/integrations/task-queue-stats.ts +146 -0
  60. package/corpus/core/src/integrations/types.ts +25 -4
  61. package/corpus/core/src/integrations/webhook-handler.ts +46 -16
  62. package/corpus/core/src/jobs/scheduler.ts +4 -0
  63. package/corpus/core/src/localization/default-messages.ts +3 -2
  64. package/corpus/core/src/observability/traces.ts +48 -12
  65. package/corpus/core/src/org/handlers.ts +52 -1
  66. package/corpus/core/src/org/migrations.ts +4 -0
  67. package/corpus/core/src/org/plugin.ts +14 -0
  68. package/corpus/core/src/org/schema.ts +1 -0
  69. package/corpus/core/src/org/types.ts +8 -0
  70. package/corpus/core/src/org/workspace-url.ts +74 -0
  71. package/corpus/core/src/resources/handlers.ts +35 -5
  72. package/corpus/core/src/scripts/runner.ts +183 -5
  73. package/corpus/core/src/server/action-routes.ts +32 -2
  74. package/corpus/core/src/server/agent-chat-plugin.ts +29 -0
  75. package/corpus/core/src/server/agent-teams.ts +10 -1
  76. package/corpus/core/src/server/auth.ts +33 -7
  77. package/corpus/core/src/server/embed-route.ts +9 -0
  78. package/corpus/core/src/server/embed-session.ts +62 -3
  79. package/corpus/core/src/server/open-route.ts +20 -6
  80. package/corpus/core/src/server/prompts/framework-core-compact.ts +1 -1
  81. package/corpus/core/src/server/prompts/framework-core.ts +1 -0
  82. package/corpus/core/src/server/request-context.ts +36 -1
  83. package/corpus/core/src/shared/embed-auth.ts +1 -0
  84. package/corpus/core/src/shared/html-document.ts +115 -0
  85. package/corpus/core/src/shared/index.ts +1 -0
  86. package/corpus/core/src/sharing/access.ts +8 -1
  87. package/corpus/core/src/sharing/registry.ts +11 -2
  88. package/corpus/core/src/workspace-files/actions.ts +100 -0
  89. package/corpus/core/src/workspace-files/tool.ts +4 -0
  90. package/corpus/templates/analytics/.agents/skills/analysis-workspace/SKILL.md +4 -0
  91. package/corpus/templates/analytics/.agents/skills/hubspot/SKILL.md +9 -1
  92. package/corpus/templates/analytics/AGENTS.md +17 -24
  93. package/corpus/templates/analytics/actions/data-source-status.ts +11 -1
  94. package/corpus/templates/analytics/app/i18n-data.ts +34 -0
  95. package/corpus/templates/analytics/app/lib/data-source-status.ts +86 -0
  96. package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +9 -0
  97. package/corpus/templates/analytics/app/pages/DataSources.tsx +184 -20
  98. package/corpus/templates/analytics/changelog/2026-07-28-native-analytics-data-sources-no-longer-show-duplicate-mc.md +6 -0
  99. package/corpus/templates/analytics/changelog/2026-07-29-exports-now-appear-in-chat-with-a-direct-download-instead-of.md +6 -0
  100. package/corpus/templates/analytics/changelog/2026-07-29-queued-chat-prompts-no-longer-resend-after-analytics-navigat.md +6 -0
  101. package/corpus/templates/analytics/changelog/2026-07-29-scheduled-dashboard-emails-load-every-panel-reliably-without.md +6 -0
  102. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +6 -3
  103. package/corpus/templates/analytics/server/lib/credential-keys.ts +1 -1
  104. package/corpus/templates/analytics/server/lib/hubspot.ts +1 -1
  105. package/corpus/templates/analytics/server/lib/provider-credentials.ts +55 -1
  106. package/corpus/templates/analytics/server/plugins/agent-chat.ts +123 -27
  107. package/corpus/templates/analytics/server/routes/[...page].get.ts +2 -7
  108. package/corpus/templates/analytics/vite.config.ts +7 -0
  109. package/corpus/templates/brain/actions/list-connection-providers.ts +100 -2
  110. package/corpus/templates/brain/app/lib/brain.ts +10 -0
  111. package/corpus/templates/brain/app/routes/sources.tsx +15 -4
  112. package/corpus/templates/brain/changelog/2026-07-29-brain-automatically-retries-failed-source-syncs-and-guides-y.md +6 -0
  113. package/corpus/templates/brain/jobs/process-ingest-queue.ts +13 -0
  114. package/corpus/templates/brain/server/jobs/sync-sources.ts +27 -22
  115. package/corpus/templates/brain/server/plugins/agent-chat.ts +2 -1
  116. package/corpus/templates/brain/server/routes/api/brain/queue/run.post.ts +7 -1
  117. package/corpus/templates/clips/AGENTS.md +1 -1
  118. package/corpus/templates/clips/actions/create-recording-agent-link.ts +11 -1
  119. package/corpus/templates/clips/actions/update-comment.ts +68 -0
  120. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +0 -1
  121. package/corpus/templates/clips/app/components/player/comments-panel.tsx +221 -65
  122. package/corpus/templates/clips/app/components/player/video-player.tsx +101 -27
  123. package/corpus/templates/clips/app/i18n/en-US.ts +2 -1
  124. package/corpus/templates/clips/app/routes/bug-report.done.tsx +48 -27
  125. package/corpus/templates/clips/app/routes/bug-report.tsx +43 -4
  126. package/corpus/templates/clips/app/routes/record.tsx +2 -0
  127. package/corpus/templates/clips/changelog/2026-07-29-clip-playback-now-recovers-instead-of-getting-stuck-when-a-b.md +6 -0
  128. package/corpus/templates/clips/changelog/2026-07-29-comments-can-now-be-edited-after-posting.md +6 -0
  129. package/corpus/templates/clips/changelog/2026-07-29-download-actions-now-use-a-shorter-clearer-label.md +6 -0
  130. package/corpus/templates/clips/changelog/2026-07-29-embedded-bug-reports-now-return-a-temporary-agent-readable.md +6 -0
  131. package/corpus/templates/clips/shared/bug-report.ts +99 -0
  132. package/corpus/templates/content/actions/_content-database-personal-view.ts +7 -1
  133. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +5 -2
  134. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +20 -8
  135. package/corpus/templates/content/changelog/2026-07-29-missing-databases-no-longer-trigger-repeated-personal-view-e.md +6 -0
  136. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +83 -47
  137. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +474 -55
  138. package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +3 -0
  139. package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +18 -1
  140. package/corpus/templates/design/.generated/bridge/source-location.generated.ts +348 -0
  141. package/corpus/templates/design/actions/add-localhost-screens.ts +2 -7
  142. package/corpus/templates/design/actions/apply-visual-edit.ts +7 -1
  143. package/corpus/templates/design/actions/connect-localhost.ts +5 -9
  144. package/corpus/templates/design/actions/create-component.ts +16 -13
  145. package/corpus/templates/design/actions/grant-localhost-write-consent.ts +2 -7
  146. package/corpus/templates/design/actions/list-design-source-capabilities.ts +4 -7
  147. package/corpus/templates/design/actions/list-local-files.ts +26 -50
  148. package/corpus/templates/design/actions/list-localhost-connections.ts +2 -7
  149. package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +2 -2
  150. package/corpus/templates/design/actions/open-visual-edit.ts +234 -135
  151. package/corpus/templates/design/actions/read-local-file.ts +26 -50
  152. package/corpus/templates/design/actions/request-localhost-write-consent.ts +2 -7
  153. package/corpus/templates/design/actions/write-local-file.ts +31 -73
  154. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +307 -133
  155. package/corpus/templates/design/app/components/design/EditPanel.tsx +94 -22
  156. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +137 -60
  157. package/corpus/templates/design/app/components/design/ResponsiveInteractBar.tsx +75 -14
  158. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +755 -97
  159. package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +8 -0
  160. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +24 -1
  161. package/corpus/templates/design/app/components/design/bridge/source-location.bridge.ts +530 -0
  162. package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbenchLoader.tsx +278 -0
  163. package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +32 -12
  164. package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-setup.ts +14 -3
  165. package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +87 -24
  166. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +36 -0
  167. package/corpus/templates/design/app/components/design/code-workbench/store.tsx +2 -1
  168. package/corpus/templates/design/app/components/design/code-workbench/workspace/localhost-provider.ts +48 -8
  169. package/corpus/templates/design/app/components/design/design-canvas/content-size-report.ts +3 -13
  170. package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +4 -2
  171. package/corpus/templates/design/app/components/design/design-canvas/hit-test.ts +3 -13
  172. package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +3 -1
  173. package/corpus/templates/design/app/components/design/edit-panel/inspect-code-source.ts +93 -0
  174. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +4 -2
  175. package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +35 -0
  176. package/corpus/templates/design/app/components/design/multi-screen/iframe-targeting.ts +24 -0
  177. package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -0
  178. package/corpus/templates/design/app/components/design/types.ts +29 -0
  179. package/corpus/templates/design/app/components/layout/Layout.tsx +7 -4
  180. package/corpus/templates/design/app/hooks/use-navigation-state.ts +3 -0
  181. package/corpus/templates/design/app/i18n-data.ts +153 -46
  182. package/corpus/templates/design/app/i18n-responsive-interact.ts +12 -12
  183. package/corpus/templates/design/app/lib/design-editor-route.ts +23 -0
  184. package/corpus/templates/design/app/pages/VisualEdit.tsx +19 -6
  185. package/corpus/templates/design/app/pages/design-editor/action-error.ts +19 -0
  186. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +29 -0
  187. package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +6 -0
  188. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +277 -15
  189. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +75 -9
  190. package/corpus/templates/design/app/pages/design-editor/layer-state-scope.ts +28 -0
  191. package/corpus/templates/design/app/pages/design-editor/live-screen-layer-drop.ts +41 -0
  192. package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +496 -41
  193. package/corpus/templates/design/app/pages/design-editor/pending-live-edit-unload-guard.ts +27 -0
  194. package/corpus/templates/design/app/pages/design-editor/pending-structure-verification.ts +10 -0
  195. package/corpus/templates/design/app/pages/design-editor/react-semantic-handoff.ts +168 -9
  196. package/corpus/templates/design/app/pages/design-editor/responsive-interact.ts +41 -3
  197. package/corpus/templates/design/app/pages/design-editor/screen-command-utils.ts +5 -0
  198. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +42 -13
  199. package/corpus/templates/design/app/pages/design-editor/source-location.ts +180 -0
  200. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +17 -0
  201. package/corpus/templates/design/app/public-routes.ts +1 -0
  202. package/corpus/templates/design/app/routes/visual-edit.$id.tsx +15 -0
  203. package/corpus/templates/design/changelog/2026-06-29-screen-overview-is-easier-to-find-and-named-screens-open-dir.md +1 -1
  204. package/corpus/templates/design/changelog/2026-07-28-deleting-a-selected-element-now-removes-it-from-the-live-pre.md +6 -0
  205. package/corpus/templates/design/changelog/2026-07-28-deleting-an-element-on-a-connected-localhost-screen-now-queu.md +6 -0
  206. package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-shows-a-responsive-device-preview-with-pre.md +6 -0
  207. package/corpus/templates/design/changelog/2026-07-28-layer-hide-and-lock-now-apply-to-the-live-preview-instead-of.md +6 -0
  208. package/corpus/templates/design/changelog/2026-07-28-layers-panel-selections-on-a-connected-localhost-screen-can-.md +6 -0
  209. package/corpus/templates/design/changelog/2026-07-28-locked-layers-now-show-a-subtle-dashed-outline-in-the-live-p.md +6 -0
  210. package/corpus/templates/design/changelog/2026-07-28-the-apply-design-updates-button-now-counts-pending-live-text.md +6 -0
  211. package/corpus/templates/design/changelog/2026-07-28-the-design-canvas-no-longer-stalls-on-a-render-loop-while-a-.md +6 -0
  212. package/corpus/templates/design/changelog/2026-07-28-visual-edit-on-a-local-dev-server-no-longer-requires-signing.md +6 -0
  213. package/corpus/templates/design/changelog/2026-07-28-visual-edits-on-a-react-19-app-no-longer-report-a-source-lin.md +6 -0
  214. package/corpus/templates/design/changelog/2026-07-29-an-edit-that-cannot-be-written-to-source-now-names-the-reaso.md +6 -0
  215. package/corpus/templates/design/changelog/2026-07-29-applying-a-primitive-dropped-onto-a-connected-localhost-scre.md +6 -0
  216. package/corpus/templates/design/changelog/2026-07-29-changing-a-style-in-the-inspector-now-updates-a-connected-lo.md +6 -0
  217. package/corpus/templates/design/changelog/2026-07-29-choosing-edit-or-annotate-from-a-focused-screen-now-returns-.md +6 -0
  218. package/corpus/templates/design/changelog/2026-07-29-concurrent-source-edits-now-return-a-clear-conflict-response.md +6 -0
  219. package/corpus/templates/design/changelog/2026-07-29-creating-a-component-from-an-element-that-repeats-in-the-sou.md +6 -0
  220. package/corpus/templates/design/changelog/2026-07-29-deleting-an-element-you-just-dropped-onto-a-live-screen-no-l.md +6 -0
  221. package/corpus/templates/design/changelog/2026-07-29-dragging-a-layer-across-screens-no-longer-dies-when-the-poin.md +6 -0
  222. package/corpus/templates/design/changelog/2026-07-29-dragging-an-element-from-a-stored-screen-into-a-live-localho.md +6 -0
  223. package/corpus/templates/design/changelog/2026-07-29-drawing-a-box-on-the-canvas-and-dragging-it-into-a-connected.md +6 -0
  224. package/corpus/templates/design/changelog/2026-07-29-fixed-a-loading-screen-flicker-when-reopening-designs-with-a.md +6 -0
  225. package/corpus/templates/design/changelog/2026-07-29-interact-mode-has-edit-and-annotate-buttons-again-so-you-can.md +6 -0
  226. package/corpus/templates/design/changelog/2026-07-29-layer-groups-can-be-dropped-onto-live-localhost-screens.md +6 -0
  227. package/corpus/templates/design/changelog/2026-07-29-localhost-source-errors-now-say-what-actually-went-wrong-whi.md +6 -0
  228. package/corpus/templates/design/changelog/2026-07-29-opening-or-refreshing-a-live-localhost-screen-in-single-scre.md +6 -0
  229. package/corpus/templates/design/changelog/2026-07-29-redo-after-undoing-a-drop-onto-a-live-screen-puts-the-elemen.md +6 -0
  230. package/corpus/templates/design/changelog/2026-07-29-shapes-can-be-drawn-directly-onto-live-localhost-screens.md +6 -0
  231. package/corpus/templates/design/changelog/2026-07-29-shapes-drawn-on-the-canvas-board-now-appear-immediately-inst.md +6 -0
  232. package/corpus/templates/design/changelog/2026-07-29-style-edits-on-a-running-localhost-screen-now-preview-live-a.md +6 -0
  233. package/corpus/templates/design/changelog/2026-07-29-the-apply-design-updates-control-now-appears-as-a-clean-conn.md +6 -0
  234. package/corpus/templates/design/changelog/2026-07-29-visual-edits-on-a-mapped-component-instance-now-tell-the-age.md +6 -0
  235. package/corpus/templates/design/server/lib/design-data-access.ts +21 -7
  236. package/corpus/templates/design/server/lib/localhost-connection.ts +240 -0
  237. package/corpus/templates/design/server/routes/[...page].get.ts +2 -5
  238. package/corpus/templates/design/server/source-workspace.ts +2 -0
  239. package/corpus/templates/design/shared/code-layer.ts +43 -0
  240. package/corpus/templates/design/shared/html-content.ts +26 -0
  241. package/corpus/templates/design/shared/html-integrity.ts +21 -1
  242. package/corpus/templates/design/shared/local-jsx-visual-edit.ts +15 -0
  243. package/corpus/templates/design/shared/source-mode.ts +76 -0
  244. package/corpus/templates/dispatch/changelog/2026-07-26-slack-replies-recover-after-connected-app-updates.md +6 -0
  245. package/corpus/templates/dispatch/changelog/2026-07-29-workspace-members-without-admin-access-now-see-a-clear-permi.md +6 -0
  246. package/corpus/templates/dispatch/server/lib/usage-metrics.ts +2 -1
  247. package/corpus/templates/plan/app/lib/plan-annotation-runtime.ts +3 -4
  248. package/corpus/templates/plan/server/routes/[...page].get.ts +2 -5
  249. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +15 -0
  250. package/corpus/templates/slides/actions/delete-design-system.ts +145 -0
  251. package/corpus/templates/slides/actions/list-design-systems.ts +94 -2
  252. package/corpus/templates/slides/actions/patch-deck.ts +29 -17
  253. package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +43 -1
  254. package/corpus/templates/slides/app/hooks/use-design-systems.ts +2 -0
  255. package/corpus/templates/slides/app/i18n/en-US.ts +7 -0
  256. package/corpus/templates/slides/app/pages/DesignSystems.tsx +56 -1
  257. package/corpus/templates/slides/changelog/2026-07-28-delete-a-design-system-you-own-from-the-design-systems-page-.md +6 -0
  258. package/corpus/toolkit/CHANGELOG.md +6 -0
  259. package/corpus/toolkit/package.json +1 -1
  260. package/corpus/toolkit/src/composer/ComposerPlusMenu.tsx +3 -2
  261. package/dist/action-ui.d.ts +1 -0
  262. package/dist/action-ui.d.ts.map +1 -1
  263. package/dist/action-ui.js +1 -0
  264. package/dist/action-ui.js.map +1 -1
  265. package/dist/action.d.ts +5 -1
  266. package/dist/action.d.ts.map +1 -1
  267. package/dist/action.js.map +1 -1
  268. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  269. package/dist/agent/engine/ai-sdk-engine.js +13 -5
  270. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  271. package/dist/agent/harness/runner.d.ts.map +1 -1
  272. package/dist/agent/harness/runner.js +5 -0
  273. package/dist/agent/harness/runner.js.map +1 -1
  274. package/dist/agent/production-agent.d.ts +16 -0
  275. package/dist/agent/production-agent.d.ts.map +1 -1
  276. package/dist/agent/production-agent.js +18 -1
  277. package/dist/agent/production-agent.js.map +1 -1
  278. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  279. package/dist/agent/run-loop-with-resume.js +6 -0
  280. package/dist/agent/run-loop-with-resume.js.map +1 -1
  281. package/dist/agent/run-manager.d.ts +14 -0
  282. package/dist/agent/run-manager.d.ts.map +1 -1
  283. package/dist/agent/run-manager.js +91 -1
  284. package/dist/agent/run-manager.js.map +1 -1
  285. package/dist/agent/thread-data-builder.d.ts +3 -0
  286. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  287. package/dist/agent/thread-data-builder.js +35 -3
  288. package/dist/agent/thread-data-builder.js.map +1 -1
  289. package/dist/agent/types.d.ts +2 -0
  290. package/dist/agent/types.d.ts.map +1 -1
  291. package/dist/agent/types.js.map +1 -1
  292. package/dist/chat-threads/store.d.ts.map +1 -1
  293. package/dist/chat-threads/store.js +4 -6
  294. package/dist/chat-threads/store.js.map +1 -1
  295. package/dist/cli/create.d.ts +66 -6
  296. package/dist/cli/create.d.ts.map +1 -1
  297. package/dist/cli/create.js +765 -66
  298. package/dist/cli/create.js.map +1 -1
  299. package/dist/cli/design-connect.d.ts.map +1 -1
  300. package/dist/cli/design-connect.js +2 -7
  301. package/dist/cli/design-connect.js.map +1 -1
  302. package/dist/cli/index.js +5 -3
  303. package/dist/cli/index.js.map +1 -1
  304. package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
  305. package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
  306. package/dist/cli/skills-content/design-visual-edit-skill.js +83 -47
  307. package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
  308. package/dist/client/AssistantChat.d.ts.map +1 -1
  309. package/dist/client/AssistantChat.js +16 -9
  310. package/dist/client/AssistantChat.js.map +1 -1
  311. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  312. package/dist/client/agent-chat-adapter.js +21 -0
  313. package/dist/client/agent-chat-adapter.js.map +1 -1
  314. package/dist/client/blocks/library/wireframe-kit.d.ts +2 -0
  315. package/dist/client/blocks/library/wireframe-kit.d.ts.map +1 -1
  316. package/dist/client/blocks/library/wireframe-kit.js +8 -2
  317. package/dist/client/blocks/library/wireframe-kit.js.map +1 -1
  318. package/dist/client/chat/index.d.ts +1 -1
  319. package/dist/client/chat/index.d.ts.map +1 -1
  320. package/dist/client/chat/index.js +1 -1
  321. package/dist/client/chat/index.js.map +1 -1
  322. package/dist/client/chat/message-components.d.ts +17 -0
  323. package/dist/client/chat/message-components.d.ts.map +1 -1
  324. package/dist/client/chat/message-components.js +24 -2
  325. package/dist/client/chat/message-components.js.map +1 -1
  326. package/dist/client/chat/run-recovery.d.ts +6 -0
  327. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  328. package/dist/client/chat/run-recovery.js +13 -3
  329. package/dist/client/chat/run-recovery.js.map +1 -1
  330. package/dist/client/chat/widgets/DataTableWidget.d.ts.map +1 -1
  331. package/dist/client/chat/widgets/DataTableWidget.js +2 -3
  332. package/dist/client/chat/widgets/DataTableWidget.js.map +1 -1
  333. package/dist/client/chat/widgets/WorkspaceFileWidget.d.ts +5 -0
  334. package/dist/client/chat/widgets/WorkspaceFileWidget.d.ts.map +1 -0
  335. package/dist/client/chat/widgets/WorkspaceFileWidget.js +34 -0
  336. package/dist/client/chat/widgets/WorkspaceFileWidget.js.map +1 -0
  337. package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
  338. package/dist/client/chat/widgets/builtin-tool-renderers.js +13 -1
  339. package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
  340. package/dist/client/chat/widgets/workspace-file-result.d.ts +12 -0
  341. package/dist/client/chat/widgets/workspace-file-result.d.ts.map +1 -0
  342. package/dist/client/chat/widgets/workspace-file-result.js +34 -0
  343. package/dist/client/chat/widgets/workspace-file-result.js.map +1 -0
  344. package/dist/client/embed-auth.d.ts.map +1 -1
  345. package/dist/client/embed-auth.js +2 -1
  346. package/dist/client/embed-auth.js.map +1 -1
  347. package/dist/client/org/InvitationBanner.d.ts +5 -2
  348. package/dist/client/org/InvitationBanner.d.ts.map +1 -1
  349. package/dist/client/org/InvitationBanner.js +9 -2
  350. package/dist/client/org/InvitationBanner.js.map +1 -1
  351. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  352. package/dist/client/org/OrgSwitcher.js +3 -2
  353. package/dist/client/org/OrgSwitcher.js.map +1 -1
  354. package/dist/client/org/TeamPage.d.ts.map +1 -1
  355. package/dist/client/org/TeamPage.js +27 -3
  356. package/dist/client/org/TeamPage.js.map +1 -1
  357. package/dist/client/org/WorkspaceNotice.d.ts +18 -0
  358. package/dist/client/org/WorkspaceNotice.d.ts.map +1 -0
  359. package/dist/client/org/WorkspaceNotice.js +56 -0
  360. package/dist/client/org/WorkspaceNotice.js.map +1 -0
  361. package/dist/client/org/hooks.d.ts +1 -0
  362. package/dist/client/org/hooks.d.ts.map +1 -1
  363. package/dist/client/org/hooks.js +12 -0
  364. package/dist/client/org/hooks.js.map +1 -1
  365. package/dist/client/org/index.d.ts +2 -1
  366. package/dist/client/org/index.d.ts.map +1 -1
  367. package/dist/client/org/index.js +2 -1
  368. package/dist/client/org/index.js.map +1 -1
  369. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  370. package/dist/client/resources/McpIntegrationDialog.js +8 -12
  371. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  372. package/dist/client/resources/ResourcesPanel.d.ts +3 -0
  373. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  374. package/dist/client/resources/ResourcesPanel.js +49 -20
  375. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  376. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  377. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  378. package/dist/client/resources/mcp-integration-catalog.js +3 -0
  379. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  380. package/dist/client/resources/use-resources.d.ts +1 -0
  381. package/dist/client/resources/use-resources.d.ts.map +1 -1
  382. package/dist/client/resources/use-resources.js +3 -0
  383. package/dist/client/resources/use-resources.js.map +1 -1
  384. package/dist/client/use-action.d.ts +3 -1
  385. package/dist/client/use-action.d.ts.map +1 -1
  386. package/dist/client/use-action.js +3 -1
  387. package/dist/client/use-action.js.map +1 -1
  388. package/dist/client/widgets/index.d.ts +1 -1
  389. package/dist/client/widgets/index.d.ts.map +1 -1
  390. package/dist/client/widgets/index.js +1 -1
  391. package/dist/client/widgets/index.js.map +1 -1
  392. package/dist/coding-tools/run-code.js +2 -1
  393. package/dist/coding-tools/run-code.js.map +1 -1
  394. package/dist/collab/awareness.d.ts +2 -2
  395. package/dist/collab/awareness.d.ts.map +1 -1
  396. package/dist/collab/struct-routes.d.ts +1 -1
  397. package/dist/db/client.d.ts +1 -0
  398. package/dist/db/client.d.ts.map +1 -1
  399. package/dist/db/client.js +24 -3
  400. package/dist/db/client.js.map +1 -1
  401. package/dist/deploy/build.d.ts.map +1 -1
  402. package/dist/deploy/build.js +25 -3
  403. package/dist/deploy/build.js.map +1 -1
  404. package/dist/eject/remote-mcp-presets.js +1 -1
  405. package/dist/eject/remote-mcp-presets.js.map +1 -1
  406. package/dist/index.browser.d.ts +1 -1
  407. package/dist/index.browser.d.ts.map +1 -1
  408. package/dist/index.browser.js +1 -1
  409. package/dist/index.browser.js.map +1 -1
  410. package/dist/index.d.ts +1 -1
  411. package/dist/index.d.ts.map +1 -1
  412. package/dist/index.js +1 -1
  413. package/dist/index.js.map +1 -1
  414. package/dist/integrations/a2a-continuation-processor.d.ts +5 -0
  415. package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
  416. package/dist/integrations/a2a-continuation-processor.js +293 -79
  417. package/dist/integrations/a2a-continuation-processor.js.map +1 -1
  418. package/dist/integrations/a2a-continuations-store.d.ts +23 -1
  419. package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
  420. package/dist/integrations/a2a-continuations-store.js +249 -15
  421. package/dist/integrations/a2a-continuations-store.js.map +1 -1
  422. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  423. package/dist/integrations/adapters/slack.js +155 -31
  424. package/dist/integrations/adapters/slack.js.map +1 -1
  425. package/dist/integrations/google-docs-poller.d.ts.map +1 -1
  426. package/dist/integrations/google-docs-poller.js +4 -1
  427. package/dist/integrations/google-docs-poller.js.map +1 -1
  428. package/dist/integrations/integration-campaign-recovery.d.ts.map +1 -1
  429. package/dist/integrations/integration-campaign-recovery.js +3 -1
  430. package/dist/integrations/integration-campaign-recovery.js.map +1 -1
  431. package/dist/integrations/plugin.d.ts.map +1 -1
  432. package/dist/integrations/plugin.js +29 -12
  433. package/dist/integrations/plugin.js.map +1 -1
  434. package/dist/integrations/task-queue-stats.d.ts +12 -0
  435. package/dist/integrations/task-queue-stats.d.ts.map +1 -1
  436. package/dist/integrations/task-queue-stats.js +106 -0
  437. package/dist/integrations/task-queue-stats.js.map +1 -1
  438. package/dist/integrations/types.d.ts +24 -6
  439. package/dist/integrations/types.d.ts.map +1 -1
  440. package/dist/integrations/types.js.map +1 -1
  441. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  442. package/dist/integrations/webhook-handler.js +35 -14
  443. package/dist/integrations/webhook-handler.js.map +1 -1
  444. package/dist/jobs/scheduler.js +4 -0
  445. package/dist/jobs/scheduler.js.map +1 -1
  446. package/dist/localization/default-messages.d.ts +3 -2
  447. package/dist/localization/default-messages.d.ts.map +1 -1
  448. package/dist/localization/default-messages.js +3 -2
  449. package/dist/localization/default-messages.js.map +1 -1
  450. package/dist/notifications/routes.d.ts +1 -1
  451. package/dist/observability/traces.d.ts.map +1 -1
  452. package/dist/observability/traces.js +27 -7
  453. package/dist/observability/traces.js.map +1 -1
  454. package/dist/org/handlers.d.ts +15 -0
  455. package/dist/org/handlers.d.ts.map +1 -1
  456. package/dist/org/handlers.js +45 -1
  457. package/dist/org/handlers.js.map +1 -1
  458. package/dist/org/migrations.d.ts.map +1 -1
  459. package/dist/org/migrations.js +4 -0
  460. package/dist/org/migrations.js.map +1 -1
  461. package/dist/org/plugin.d.ts +1 -0
  462. package/dist/org/plugin.d.ts.map +1 -1
  463. package/dist/org/plugin.js +10 -1
  464. package/dist/org/plugin.js.map +1 -1
  465. package/dist/org/schema.d.ts +19 -0
  466. package/dist/org/schema.d.ts.map +1 -1
  467. package/dist/org/schema.js +1 -0
  468. package/dist/org/schema.js.map +1 -1
  469. package/dist/org/types.d.ts +8 -0
  470. package/dist/org/types.d.ts.map +1 -1
  471. package/dist/org/types.js.map +1 -1
  472. package/dist/org/workspace-url.d.ts +32 -0
  473. package/dist/org/workspace-url.d.ts.map +1 -0
  474. package/dist/org/workspace-url.js +63 -0
  475. package/dist/org/workspace-url.js.map +1 -0
  476. package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
  477. package/dist/provider-api/actions/provider-api.d.ts +7 -7
  478. package/dist/resources/handlers.d.ts +3 -4
  479. package/dist/resources/handlers.d.ts.map +1 -1
  480. package/dist/resources/handlers.js +25 -5
  481. package/dist/resources/handlers.js.map +1 -1
  482. package/dist/scripts/runner.d.ts +17 -0
  483. package/dist/scripts/runner.d.ts.map +1 -1
  484. package/dist/scripts/runner.js +130 -5
  485. package/dist/scripts/runner.js.map +1 -1
  486. package/dist/secrets/routes.d.ts +9 -9
  487. package/dist/server/action-routes.d.ts.map +1 -1
  488. package/dist/server/action-routes.js +24 -2
  489. package/dist/server/action-routes.js.map +1 -1
  490. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  491. package/dist/server/agent-chat-plugin.js +26 -1
  492. package/dist/server/agent-chat-plugin.js.map +1 -1
  493. package/dist/server/agent-teams.d.ts.map +1 -1
  494. package/dist/server/agent-teams.js +10 -1
  495. package/dist/server/agent-teams.js.map +1 -1
  496. package/dist/server/auth.d.ts +22 -0
  497. package/dist/server/auth.d.ts.map +1 -1
  498. package/dist/server/auth.js +33 -7
  499. package/dist/server/auth.js.map +1 -1
  500. package/dist/server/embed-route.d.ts.map +1 -1
  501. package/dist/server/embed-route.js +6 -1
  502. package/dist/server/embed-route.js.map +1 -1
  503. package/dist/server/embed-session.d.ts +7 -0
  504. package/dist/server/embed-session.d.ts.map +1 -1
  505. package/dist/server/embed-session.js +46 -4
  506. package/dist/server/embed-session.js.map +1 -1
  507. package/dist/server/open-route.d.ts.map +1 -1
  508. package/dist/server/open-route.js +17 -7
  509. package/dist/server/open-route.js.map +1 -1
  510. package/dist/server/prompts/framework-core-compact.js +1 -1
  511. package/dist/server/prompts/framework-core-compact.js.map +1 -1
  512. package/dist/server/prompts/framework-core.d.ts.map +1 -1
  513. package/dist/server/prompts/framework-core.js +1 -0
  514. package/dist/server/prompts/framework-core.js.map +1 -1
  515. package/dist/server/request-context.d.ts +26 -0
  516. package/dist/server/request-context.d.ts.map +1 -1
  517. package/dist/server/request-context.js +18 -1
  518. package/dist/server/request-context.js.map +1 -1
  519. package/dist/shared/embed-auth.d.ts +1 -0
  520. package/dist/shared/embed-auth.d.ts.map +1 -1
  521. package/dist/shared/embed-auth.js +1 -0
  522. package/dist/shared/embed-auth.js.map +1 -1
  523. package/dist/shared/html-document.d.ts +12 -0
  524. package/dist/shared/html-document.d.ts.map +1 -0
  525. package/dist/shared/html-document.js +92 -0
  526. package/dist/shared/html-document.js.map +1 -0
  527. package/dist/shared/index.d.ts +1 -0
  528. package/dist/shared/index.d.ts.map +1 -1
  529. package/dist/shared/index.js +1 -0
  530. package/dist/shared/index.js.map +1 -1
  531. package/dist/sharing/access.d.ts +1 -0
  532. package/dist/sharing/access.d.ts.map +1 -1
  533. package/dist/sharing/access.js +8 -2
  534. package/dist/sharing/access.js.map +1 -1
  535. package/dist/sharing/registry.d.ts +3 -0
  536. package/dist/sharing/registry.d.ts.map +1 -1
  537. package/dist/sharing/registry.js.map +1 -1
  538. package/dist/workspace-files/actions.d.ts +28 -0
  539. package/dist/workspace-files/actions.d.ts.map +1 -0
  540. package/dist/workspace-files/actions.js +75 -0
  541. package/dist/workspace-files/actions.js.map +1 -0
  542. package/dist/workspace-files/tool.d.ts.map +1 -1
  543. package/dist/workspace-files/tool.js +4 -0
  544. package/dist/workspace-files/tool.js.map +1 -1
  545. package/docs/content/cloneable-saas.mdx +114 -0
  546. package/docs/content/creating-templates.mdx +28 -2
  547. package/docs/content/syncing-template-changes.mdx +7 -0
  548. package/docs/content/template-clips-developers.mdx +12 -5
  549. package/docs/content/template-dispatch-developers.mdx +1 -1
  550. package/docs/content/template-dispatch.mdx +1 -1
  551. package/package.json +2 -2
  552. package/src/action-ui.ts +1 -0
  553. package/src/action.ts +5 -1
  554. package/src/agent/engine/ai-sdk-engine.ts +15 -5
  555. package/src/agent/harness/runner.ts +5 -0
  556. package/src/agent/production-agent.ts +33 -0
  557. package/src/agent/run-loop-with-resume.ts +5 -0
  558. package/src/agent/run-manager.ts +126 -1
  559. package/src/agent/thread-data-builder.ts +47 -2
  560. package/src/agent/types.ts +2 -0
  561. package/src/chat-threads/store.ts +4 -5
  562. package/src/cli/create.ts +1139 -65
  563. package/src/cli/design-connect.ts +3 -7
  564. package/src/cli/index.ts +5 -3
  565. package/src/cli/skills-content/design-visual-edit-skill.ts +83 -47
  566. package/src/client/AssistantChat.tsx +27 -16
  567. package/src/client/agent-chat-adapter.ts +24 -0
  568. package/src/client/blocks/library/wireframe-kit.tsx +17 -2
  569. package/src/client/chat/index.ts +1 -0
  570. package/src/client/chat/message-components.tsx +104 -1
  571. package/src/client/chat/run-recovery.tsx +15 -3
  572. package/src/client/chat/widgets/DataTableWidget.tsx +10 -29
  573. package/src/client/chat/widgets/WorkspaceFileWidget.tsx +71 -0
  574. package/src/client/chat/widgets/builtin-tool-renderers.tsx +22 -0
  575. package/src/client/chat/widgets/workspace-file-result.ts +49 -0
  576. package/src/client/embed-auth.ts +2 -0
  577. package/src/client/org/InvitationBanner.tsx +14 -1
  578. package/src/client/org/OrgSwitcher.tsx +23 -0
  579. package/src/client/org/TeamPage.tsx +130 -0
  580. package/src/client/org/WorkspaceNotice.tsx +85 -0
  581. package/src/client/org/hooks.ts +14 -0
  582. package/src/client/org/index.ts +2 -0
  583. package/src/client/resources/McpIntegrationDialog.tsx +27 -40
  584. package/src/client/resources/ResourcesPanel.tsx +134 -51
  585. package/src/client/resources/mcp-integration-catalog.ts +7 -0
  586. package/src/client/resources/use-resources.ts +6 -0
  587. package/src/client/use-action.ts +3 -1
  588. package/src/client/widgets/index.ts +1 -0
  589. package/src/coding-tools/run-code.ts +2 -1
  590. package/src/db/client.ts +28 -4
  591. package/src/deploy/build.ts +31 -3
  592. package/src/eject/remote-mcp-presets.ts +1 -1
  593. package/src/index.browser.ts +1 -0
  594. package/src/index.ts +1 -0
  595. package/src/integrations/a2a-continuation-processor.ts +481 -122
  596. package/src/integrations/a2a-continuations-store.ts +345 -14
  597. package/src/integrations/adapters/slack.ts +243 -53
  598. package/src/integrations/google-docs-poller.ts +3 -0
  599. package/src/integrations/integration-campaign-recovery.ts +4 -1
  600. package/src/integrations/plugin.ts +39 -21
  601. package/src/integrations/task-queue-stats.ts +146 -0
  602. package/src/integrations/types.ts +25 -4
  603. package/src/integrations/webhook-handler.ts +46 -16
  604. package/src/jobs/scheduler.ts +4 -0
  605. package/src/localization/default-messages.ts +3 -2
  606. package/src/observability/traces.ts +48 -12
  607. package/src/org/handlers.ts +52 -1
  608. package/src/org/migrations.ts +4 -0
  609. package/src/org/plugin.ts +14 -0
  610. package/src/org/schema.ts +1 -0
  611. package/src/org/types.ts +8 -0
  612. package/src/org/workspace-url.ts +74 -0
  613. package/src/resources/handlers.ts +35 -5
  614. package/src/scripts/runner.ts +183 -5
  615. package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +2 -1
  616. package/src/server/action-routes.ts +32 -2
  617. package/src/server/agent-chat-plugin.ts +29 -0
  618. package/src/server/agent-teams.ts +10 -1
  619. package/src/server/auth.ts +33 -7
  620. package/src/server/embed-route.ts +9 -0
  621. package/src/server/embed-session.ts +62 -3
  622. package/src/server/open-route.ts +20 -6
  623. package/src/server/prompts/framework-core-compact.ts +1 -1
  624. package/src/server/prompts/framework-core.ts +1 -0
  625. package/src/server/request-context.ts +36 -1
  626. package/src/shared/embed-auth.ts +1 -0
  627. package/src/shared/html-document.ts +115 -0
  628. package/src/shared/index.ts +1 -0
  629. package/src/sharing/access.ts +8 -1
  630. package/src/sharing/registry.ts +11 -2
  631. package/src/workspace-files/actions.ts +100 -0
  632. package/src/workspace-files/tool.ts +4 -0
  633. package/corpus/templates/design/changelog/2026-07-28-interact-mode-can-preview-designs-in-responsive-device-sizes.md +0 -6
  634. 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
- resolveEmbedSessionFromRequest,
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 whatever `Set-Cookie` headers were
2456
- * just staged on the event (e.g. by `setFrameworkSessionCookie`).
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
- return typeof raw === "string" ? pathnameFromPath(raw) : null;
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
- if (!matchesTarget && !isRuntimeCookieRequest && !isRuntimeQueryRequest) {
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 && runtimeRequest))
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 { getSession, getConfiguredLoginHtml } from "./auth.js";
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
- // Native web Response (not h3 v2's reworked sendRedirect) matches the
142
- // redirect pattern used elsewhere in auth.ts.
143
- const headers = new Headers({ Location: location });
144
- if (embedRedirect) addMcpEmbedHeaders(event, headers);
145
- return new Response("", { status: 302, headers });
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
- return reg?.resolveAccessContext ? reg.resolveAccessContext(ctx) : ctx;
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: { userEmail?: string; orgId?: string },
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: { userEmail?: string; orgId?: string }) => {
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