@agent-native/core 0.129.1 → 0.130.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (596) 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/google-docs-poller.ts +3 -0
  54. package/corpus/core/src/integrations/webhook-handler.ts +28 -11
  55. package/corpus/core/src/jobs/scheduler.ts +4 -0
  56. package/corpus/core/src/localization/default-messages.ts +3 -2
  57. package/corpus/core/src/mcp/build-server.ts +20 -2
  58. package/corpus/core/src/observability/traces.ts +48 -12
  59. package/corpus/core/src/org/handlers.ts +52 -1
  60. package/corpus/core/src/org/migrations.ts +4 -0
  61. package/corpus/core/src/org/plugin.ts +14 -0
  62. package/corpus/core/src/org/schema.ts +1 -0
  63. package/corpus/core/src/org/types.ts +8 -0
  64. package/corpus/core/src/org/workspace-url.ts +74 -0
  65. package/corpus/core/src/resources/handlers.ts +35 -5
  66. package/corpus/core/src/scripts/runner.ts +183 -5
  67. package/corpus/core/src/server/action-routes.ts +32 -2
  68. package/corpus/core/src/server/agent-chat-plugin.ts +29 -0
  69. package/corpus/core/src/server/agent-teams.ts +10 -1
  70. package/corpus/core/src/server/auth.ts +33 -7
  71. package/corpus/core/src/server/embed-route.ts +9 -0
  72. package/corpus/core/src/server/embed-session.ts +62 -3
  73. package/corpus/core/src/server/open-route.ts +20 -6
  74. package/corpus/core/src/server/prompts/framework-core-compact.ts +1 -1
  75. package/corpus/core/src/server/prompts/framework-core.ts +1 -0
  76. package/corpus/core/src/server/request-context.ts +36 -1
  77. package/corpus/core/src/shared/embed-auth.ts +1 -0
  78. package/corpus/core/src/shared/html-document.ts +115 -0
  79. package/corpus/core/src/shared/index.ts +1 -0
  80. package/corpus/core/src/sharing/access.ts +8 -1
  81. package/corpus/core/src/sharing/registry.ts +11 -2
  82. package/corpus/core/src/workspace-files/actions.ts +100 -0
  83. package/corpus/core/src/workspace-files/tool.ts +4 -0
  84. package/corpus/templates/analytics/.agents/skills/analysis-workspace/SKILL.md +4 -0
  85. package/corpus/templates/analytics/.agents/skills/hubspot/SKILL.md +9 -1
  86. package/corpus/templates/analytics/AGENTS.md +17 -24
  87. package/corpus/templates/analytics/actions/data-source-status.ts +11 -1
  88. package/corpus/templates/analytics/app/i18n-data.ts +34 -0
  89. package/corpus/templates/analytics/app/lib/data-source-status.ts +86 -0
  90. package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +9 -0
  91. package/corpus/templates/analytics/app/pages/DataSources.tsx +184 -20
  92. package/corpus/templates/analytics/changelog/2026-07-28-native-analytics-data-sources-no-longer-show-duplicate-mc.md +6 -0
  93. package/corpus/templates/analytics/changelog/2026-07-29-exports-now-appear-in-chat-with-a-direct-download-instead-of.md +6 -0
  94. package/corpus/templates/analytics/changelog/2026-07-29-queued-chat-prompts-no-longer-resend-after-analytics-navigat.md +6 -0
  95. package/corpus/templates/analytics/changelog/2026-07-29-scheduled-dashboard-emails-load-every-panel-reliably-without.md +6 -0
  96. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +6 -3
  97. package/corpus/templates/analytics/server/lib/credential-keys.ts +1 -1
  98. package/corpus/templates/analytics/server/lib/hubspot.ts +1 -1
  99. package/corpus/templates/analytics/server/lib/provider-credentials.ts +55 -1
  100. package/corpus/templates/analytics/server/plugins/agent-chat.ts +123 -27
  101. package/corpus/templates/analytics/server/routes/[...page].get.ts +2 -7
  102. package/corpus/templates/analytics/vite.config.ts +7 -0
  103. package/corpus/templates/brain/actions/list-connection-providers.ts +100 -2
  104. package/corpus/templates/brain/app/lib/brain.ts +10 -0
  105. package/corpus/templates/brain/app/routes/sources.tsx +15 -4
  106. package/corpus/templates/brain/changelog/2026-07-29-brain-automatically-retries-failed-source-syncs-and-guides-y.md +6 -0
  107. package/corpus/templates/brain/jobs/process-ingest-queue.ts +13 -0
  108. package/corpus/templates/brain/server/jobs/sync-sources.ts +27 -22
  109. package/corpus/templates/brain/server/plugins/agent-chat.ts +2 -1
  110. package/corpus/templates/brain/server/routes/api/brain/queue/run.post.ts +7 -1
  111. package/corpus/templates/clips/AGENTS.md +1 -1
  112. package/corpus/templates/clips/actions/create-recording-agent-link.ts +11 -1
  113. package/corpus/templates/clips/actions/update-comment.ts +68 -0
  114. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +0 -1
  115. package/corpus/templates/clips/app/components/player/comments-panel.tsx +221 -65
  116. package/corpus/templates/clips/app/components/player/video-player.tsx +101 -27
  117. package/corpus/templates/clips/app/i18n/en-US.ts +2 -1
  118. package/corpus/templates/clips/app/routes/bug-report.done.tsx +48 -27
  119. package/corpus/templates/clips/app/routes/bug-report.tsx +43 -4
  120. package/corpus/templates/clips/app/routes/record.tsx +2 -0
  121. package/corpus/templates/clips/changelog/2026-07-29-clip-playback-now-recovers-instead-of-getting-stuck-when-a-b.md +6 -0
  122. package/corpus/templates/clips/changelog/2026-07-29-comments-can-now-be-edited-after-posting.md +6 -0
  123. package/corpus/templates/clips/changelog/2026-07-29-download-actions-now-use-a-shorter-clearer-label.md +6 -0
  124. package/corpus/templates/clips/changelog/2026-07-29-embedded-bug-reports-now-return-a-temporary-agent-readable.md +6 -0
  125. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +1 -1
  126. package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +21 -1
  127. package/corpus/templates/clips/shared/bug-report.ts +99 -0
  128. package/corpus/templates/content/actions/_content-database-personal-view.ts +7 -1
  129. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +5 -2
  130. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +20 -8
  131. package/corpus/templates/content/changelog/2026-07-29-missing-databases-no-longer-trigger-repeated-personal-view-e.md +6 -0
  132. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +83 -47
  133. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +474 -55
  134. package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +3 -0
  135. package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +18 -1
  136. package/corpus/templates/design/.generated/bridge/source-location.generated.ts +348 -0
  137. package/corpus/templates/design/actions/add-localhost-screens.ts +2 -7
  138. package/corpus/templates/design/actions/apply-visual-edit.ts +7 -1
  139. package/corpus/templates/design/actions/connect-localhost.ts +5 -9
  140. package/corpus/templates/design/actions/create-component.ts +16 -13
  141. package/corpus/templates/design/actions/grant-localhost-write-consent.ts +2 -7
  142. package/corpus/templates/design/actions/list-design-source-capabilities.ts +4 -7
  143. package/corpus/templates/design/actions/list-local-files.ts +26 -50
  144. package/corpus/templates/design/actions/list-localhost-connections.ts +2 -7
  145. package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +2 -2
  146. package/corpus/templates/design/actions/open-visual-edit.ts +234 -135
  147. package/corpus/templates/design/actions/read-local-file.ts +26 -50
  148. package/corpus/templates/design/actions/request-localhost-write-consent.ts +2 -7
  149. package/corpus/templates/design/actions/write-local-file.ts +31 -73
  150. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +307 -133
  151. package/corpus/templates/design/app/components/design/EditPanel.tsx +94 -22
  152. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +137 -60
  153. package/corpus/templates/design/app/components/design/ResponsiveInteractBar.tsx +75 -14
  154. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +755 -97
  155. package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +8 -0
  156. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +24 -1
  157. package/corpus/templates/design/app/components/design/bridge/source-location.bridge.ts +530 -0
  158. package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbenchLoader.tsx +278 -0
  159. package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +32 -12
  160. package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-setup.ts +14 -3
  161. package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +87 -24
  162. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +36 -0
  163. package/corpus/templates/design/app/components/design/code-workbench/store.tsx +2 -1
  164. package/corpus/templates/design/app/components/design/code-workbench/workspace/localhost-provider.ts +48 -8
  165. package/corpus/templates/design/app/components/design/design-canvas/content-size-report.ts +3 -13
  166. package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +4 -2
  167. package/corpus/templates/design/app/components/design/design-canvas/hit-test.ts +3 -13
  168. package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +3 -1
  169. package/corpus/templates/design/app/components/design/edit-panel/inspect-code-source.ts +93 -0
  170. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +4 -2
  171. package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +35 -0
  172. package/corpus/templates/design/app/components/design/multi-screen/iframe-targeting.ts +24 -0
  173. package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -0
  174. package/corpus/templates/design/app/components/design/types.ts +29 -0
  175. package/corpus/templates/design/app/components/layout/Layout.tsx +7 -4
  176. package/corpus/templates/design/app/hooks/use-navigation-state.ts +3 -0
  177. package/corpus/templates/design/app/i18n-data.ts +153 -46
  178. package/corpus/templates/design/app/i18n-responsive-interact.ts +12 -12
  179. package/corpus/templates/design/app/lib/design-editor-route.ts +23 -0
  180. package/corpus/templates/design/app/pages/VisualEdit.tsx +19 -6
  181. package/corpus/templates/design/app/pages/design-editor/action-error.ts +19 -0
  182. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +29 -0
  183. package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +6 -0
  184. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +277 -15
  185. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +75 -9
  186. package/corpus/templates/design/app/pages/design-editor/layer-state-scope.ts +28 -0
  187. package/corpus/templates/design/app/pages/design-editor/live-screen-layer-drop.ts +41 -0
  188. package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +496 -41
  189. package/corpus/templates/design/app/pages/design-editor/pending-live-edit-unload-guard.ts +27 -0
  190. package/corpus/templates/design/app/pages/design-editor/pending-structure-verification.ts +10 -0
  191. package/corpus/templates/design/app/pages/design-editor/react-semantic-handoff.ts +168 -9
  192. package/corpus/templates/design/app/pages/design-editor/responsive-interact.ts +41 -3
  193. package/corpus/templates/design/app/pages/design-editor/screen-command-utils.ts +5 -0
  194. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +42 -13
  195. package/corpus/templates/design/app/pages/design-editor/source-location.ts +180 -0
  196. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +17 -0
  197. package/corpus/templates/design/app/public-routes.ts +1 -0
  198. package/corpus/templates/design/app/routes/visual-edit.$id.tsx +15 -0
  199. package/corpus/templates/design/changelog/2026-06-29-screen-overview-is-easier-to-find-and-named-screens-open-dir.md +1 -1
  200. package/corpus/templates/design/changelog/2026-07-28-deleting-a-selected-element-now-removes-it-from-the-live-pre.md +6 -0
  201. package/corpus/templates/design/changelog/2026-07-28-deleting-an-element-on-a-connected-localhost-screen-now-queu.md +6 -0
  202. package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-shows-a-responsive-device-preview-with-pre.md +6 -0
  203. package/corpus/templates/design/changelog/2026-07-28-layer-hide-and-lock-now-apply-to-the-live-preview-instead-of.md +6 -0
  204. package/corpus/templates/design/changelog/2026-07-28-layers-panel-selections-on-a-connected-localhost-screen-can-.md +6 -0
  205. package/corpus/templates/design/changelog/2026-07-28-locked-layers-now-show-a-subtle-dashed-outline-in-the-live-p.md +6 -0
  206. package/corpus/templates/design/changelog/2026-07-28-the-apply-design-updates-button-now-counts-pending-live-text.md +6 -0
  207. package/corpus/templates/design/changelog/2026-07-28-the-design-canvas-no-longer-stalls-on-a-render-loop-while-a-.md +6 -0
  208. package/corpus/templates/design/changelog/2026-07-28-visual-edit-on-a-local-dev-server-no-longer-requires-signing.md +6 -0
  209. package/corpus/templates/design/changelog/2026-07-28-visual-edits-on-a-react-19-app-no-longer-report-a-source-lin.md +6 -0
  210. package/corpus/templates/design/changelog/2026-07-29-an-edit-that-cannot-be-written-to-source-now-names-the-reaso.md +6 -0
  211. package/corpus/templates/design/changelog/2026-07-29-applying-a-primitive-dropped-onto-a-connected-localhost-scre.md +6 -0
  212. package/corpus/templates/design/changelog/2026-07-29-changing-a-style-in-the-inspector-now-updates-a-connected-lo.md +6 -0
  213. package/corpus/templates/design/changelog/2026-07-29-choosing-edit-or-annotate-from-a-focused-screen-now-returns-.md +6 -0
  214. package/corpus/templates/design/changelog/2026-07-29-concurrent-source-edits-now-return-a-clear-conflict-response.md +6 -0
  215. package/corpus/templates/design/changelog/2026-07-29-creating-a-component-from-an-element-that-repeats-in-the-sou.md +6 -0
  216. package/corpus/templates/design/changelog/2026-07-29-deleting-an-element-you-just-dropped-onto-a-live-screen-no-l.md +6 -0
  217. package/corpus/templates/design/changelog/2026-07-29-dragging-a-layer-across-screens-no-longer-dies-when-the-poin.md +6 -0
  218. package/corpus/templates/design/changelog/2026-07-29-dragging-an-element-from-a-stored-screen-into-a-live-localho.md +6 -0
  219. package/corpus/templates/design/changelog/2026-07-29-drawing-a-box-on-the-canvas-and-dragging-it-into-a-connected.md +6 -0
  220. package/corpus/templates/design/changelog/2026-07-29-fixed-a-loading-screen-flicker-when-reopening-designs-with-a.md +6 -0
  221. package/corpus/templates/design/changelog/2026-07-29-interact-mode-has-edit-and-annotate-buttons-again-so-you-can.md +6 -0
  222. package/corpus/templates/design/changelog/2026-07-29-layer-groups-can-be-dropped-onto-live-localhost-screens.md +6 -0
  223. package/corpus/templates/design/changelog/2026-07-29-localhost-source-errors-now-say-what-actually-went-wrong-whi.md +6 -0
  224. package/corpus/templates/design/changelog/2026-07-29-opening-or-refreshing-a-live-localhost-screen-in-single-scre.md +6 -0
  225. package/corpus/templates/design/changelog/2026-07-29-redo-after-undoing-a-drop-onto-a-live-screen-puts-the-elemen.md +6 -0
  226. package/corpus/templates/design/changelog/2026-07-29-shapes-can-be-drawn-directly-onto-live-localhost-screens.md +6 -0
  227. package/corpus/templates/design/changelog/2026-07-29-shapes-drawn-on-the-canvas-board-now-appear-immediately-inst.md +6 -0
  228. package/corpus/templates/design/changelog/2026-07-29-style-edits-on-a-running-localhost-screen-now-preview-live-a.md +6 -0
  229. package/corpus/templates/design/changelog/2026-07-29-the-apply-design-updates-control-now-appears-as-a-clean-conn.md +6 -0
  230. package/corpus/templates/design/changelog/2026-07-29-visual-edits-on-a-mapped-component-instance-now-tell-the-age.md +6 -0
  231. package/corpus/templates/design/server/lib/design-data-access.ts +21 -7
  232. package/corpus/templates/design/server/lib/localhost-connection.ts +240 -0
  233. package/corpus/templates/design/server/routes/[...page].get.ts +2 -5
  234. package/corpus/templates/design/server/source-workspace.ts +2 -0
  235. package/corpus/templates/design/shared/code-layer.ts +43 -0
  236. package/corpus/templates/design/shared/html-content.ts +26 -0
  237. package/corpus/templates/design/shared/html-integrity.ts +21 -1
  238. package/corpus/templates/design/shared/local-jsx-visual-edit.ts +15 -0
  239. package/corpus/templates/design/shared/source-mode.ts +76 -0
  240. package/corpus/templates/dispatch/changelog/2026-07-29-workspace-members-without-admin-access-now-see-a-clear-permi.md +6 -0
  241. package/corpus/templates/dispatch/server/lib/usage-metrics.ts +2 -1
  242. package/corpus/templates/plan/app/lib/plan-annotation-runtime.ts +3 -4
  243. package/corpus/templates/plan/server/routes/[...page].get.ts +2 -5
  244. package/corpus/templates/slides/actions/patch-deck.ts +29 -17
  245. package/corpus/toolkit/CHANGELOG.md +6 -0
  246. package/corpus/toolkit/package.json +1 -1
  247. package/corpus/toolkit/src/composer/ComposerPlusMenu.tsx +3 -2
  248. package/dist/action-ui.d.ts +1 -0
  249. package/dist/action-ui.d.ts.map +1 -1
  250. package/dist/action-ui.js +1 -0
  251. package/dist/action-ui.js.map +1 -1
  252. package/dist/action.d.ts +5 -1
  253. package/dist/action.d.ts.map +1 -1
  254. package/dist/action.js.map +1 -1
  255. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  256. package/dist/agent/engine/ai-sdk-engine.js +13 -5
  257. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  258. package/dist/agent/harness/runner.d.ts.map +1 -1
  259. package/dist/agent/harness/runner.js +5 -0
  260. package/dist/agent/harness/runner.js.map +1 -1
  261. package/dist/agent/production-agent.d.ts +16 -0
  262. package/dist/agent/production-agent.d.ts.map +1 -1
  263. package/dist/agent/production-agent.js +18 -1
  264. package/dist/agent/production-agent.js.map +1 -1
  265. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  266. package/dist/agent/run-loop-with-resume.js +6 -0
  267. package/dist/agent/run-loop-with-resume.js.map +1 -1
  268. package/dist/agent/run-manager.d.ts +14 -0
  269. package/dist/agent/run-manager.d.ts.map +1 -1
  270. package/dist/agent/run-manager.js +91 -1
  271. package/dist/agent/run-manager.js.map +1 -1
  272. package/dist/agent/thread-data-builder.d.ts +3 -0
  273. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  274. package/dist/agent/thread-data-builder.js +35 -3
  275. package/dist/agent/thread-data-builder.js.map +1 -1
  276. package/dist/agent/types.d.ts +2 -0
  277. package/dist/agent/types.d.ts.map +1 -1
  278. package/dist/agent/types.js.map +1 -1
  279. package/dist/chat-threads/store.d.ts.map +1 -1
  280. package/dist/chat-threads/store.js +4 -6
  281. package/dist/chat-threads/store.js.map +1 -1
  282. package/dist/cli/create.d.ts +66 -6
  283. package/dist/cli/create.d.ts.map +1 -1
  284. package/dist/cli/create.js +765 -66
  285. package/dist/cli/create.js.map +1 -1
  286. package/dist/cli/design-connect.d.ts.map +1 -1
  287. package/dist/cli/design-connect.js +2 -7
  288. package/dist/cli/design-connect.js.map +1 -1
  289. package/dist/cli/index.js +5 -3
  290. package/dist/cli/index.js.map +1 -1
  291. package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
  292. package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
  293. package/dist/cli/skills-content/design-visual-edit-skill.js +83 -47
  294. package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
  295. package/dist/client/AssistantChat.d.ts.map +1 -1
  296. package/dist/client/AssistantChat.js +16 -9
  297. package/dist/client/AssistantChat.js.map +1 -1
  298. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  299. package/dist/client/agent-chat-adapter.js +21 -0
  300. package/dist/client/agent-chat-adapter.js.map +1 -1
  301. package/dist/client/blocks/library/wireframe-kit.d.ts +2 -0
  302. package/dist/client/blocks/library/wireframe-kit.d.ts.map +1 -1
  303. package/dist/client/blocks/library/wireframe-kit.js +8 -2
  304. package/dist/client/blocks/library/wireframe-kit.js.map +1 -1
  305. package/dist/client/chat/index.d.ts +1 -1
  306. package/dist/client/chat/index.d.ts.map +1 -1
  307. package/dist/client/chat/index.js +1 -1
  308. package/dist/client/chat/index.js.map +1 -1
  309. package/dist/client/chat/message-components.d.ts +17 -0
  310. package/dist/client/chat/message-components.d.ts.map +1 -1
  311. package/dist/client/chat/message-components.js +24 -2
  312. package/dist/client/chat/message-components.js.map +1 -1
  313. package/dist/client/chat/run-recovery.d.ts +6 -0
  314. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  315. package/dist/client/chat/run-recovery.js +13 -3
  316. package/dist/client/chat/run-recovery.js.map +1 -1
  317. package/dist/client/chat/widgets/DataTableWidget.d.ts.map +1 -1
  318. package/dist/client/chat/widgets/DataTableWidget.js +2 -3
  319. package/dist/client/chat/widgets/DataTableWidget.js.map +1 -1
  320. package/dist/client/chat/widgets/WorkspaceFileWidget.d.ts +5 -0
  321. package/dist/client/chat/widgets/WorkspaceFileWidget.d.ts.map +1 -0
  322. package/dist/client/chat/widgets/WorkspaceFileWidget.js +34 -0
  323. package/dist/client/chat/widgets/WorkspaceFileWidget.js.map +1 -0
  324. package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
  325. package/dist/client/chat/widgets/builtin-tool-renderers.js +13 -1
  326. package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
  327. package/dist/client/chat/widgets/workspace-file-result.d.ts +12 -0
  328. package/dist/client/chat/widgets/workspace-file-result.d.ts.map +1 -0
  329. package/dist/client/chat/widgets/workspace-file-result.js +34 -0
  330. package/dist/client/chat/widgets/workspace-file-result.js.map +1 -0
  331. package/dist/client/embed-auth.d.ts.map +1 -1
  332. package/dist/client/embed-auth.js +2 -1
  333. package/dist/client/embed-auth.js.map +1 -1
  334. package/dist/client/org/InvitationBanner.d.ts +5 -2
  335. package/dist/client/org/InvitationBanner.d.ts.map +1 -1
  336. package/dist/client/org/InvitationBanner.js +9 -2
  337. package/dist/client/org/InvitationBanner.js.map +1 -1
  338. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  339. package/dist/client/org/OrgSwitcher.js +3 -2
  340. package/dist/client/org/OrgSwitcher.js.map +1 -1
  341. package/dist/client/org/TeamPage.d.ts.map +1 -1
  342. package/dist/client/org/TeamPage.js +27 -3
  343. package/dist/client/org/TeamPage.js.map +1 -1
  344. package/dist/client/org/WorkspaceNotice.d.ts +18 -0
  345. package/dist/client/org/WorkspaceNotice.d.ts.map +1 -0
  346. package/dist/client/org/WorkspaceNotice.js +56 -0
  347. package/dist/client/org/WorkspaceNotice.js.map +1 -0
  348. package/dist/client/org/hooks.d.ts +1 -0
  349. package/dist/client/org/hooks.d.ts.map +1 -1
  350. package/dist/client/org/hooks.js +12 -0
  351. package/dist/client/org/hooks.js.map +1 -1
  352. package/dist/client/org/index.d.ts +2 -1
  353. package/dist/client/org/index.d.ts.map +1 -1
  354. package/dist/client/org/index.js +2 -1
  355. package/dist/client/org/index.js.map +1 -1
  356. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  357. package/dist/client/resources/McpIntegrationDialog.js +8 -12
  358. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  359. package/dist/client/resources/ResourcesPanel.d.ts +3 -0
  360. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  361. package/dist/client/resources/ResourcesPanel.js +49 -20
  362. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  363. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  364. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  365. package/dist/client/resources/mcp-integration-catalog.js +3 -0
  366. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  367. package/dist/client/resources/use-resources.d.ts +1 -0
  368. package/dist/client/resources/use-resources.d.ts.map +1 -1
  369. package/dist/client/resources/use-resources.js +3 -0
  370. package/dist/client/resources/use-resources.js.map +1 -1
  371. package/dist/client/use-action.d.ts +3 -1
  372. package/dist/client/use-action.d.ts.map +1 -1
  373. package/dist/client/use-action.js +3 -1
  374. package/dist/client/use-action.js.map +1 -1
  375. package/dist/client/widgets/index.d.ts +1 -1
  376. package/dist/client/widgets/index.d.ts.map +1 -1
  377. package/dist/client/widgets/index.js +1 -1
  378. package/dist/client/widgets/index.js.map +1 -1
  379. package/dist/coding-tools/run-code.js +2 -1
  380. package/dist/coding-tools/run-code.js.map +1 -1
  381. package/dist/collab/awareness.d.ts +2 -2
  382. package/dist/collab/awareness.d.ts.map +1 -1
  383. package/dist/collab/routes.d.ts +1 -1
  384. package/dist/db/client.d.ts +1 -0
  385. package/dist/db/client.d.ts.map +1 -1
  386. package/dist/db/client.js +24 -3
  387. package/dist/db/client.js.map +1 -1
  388. package/dist/deploy/build.d.ts.map +1 -1
  389. package/dist/deploy/build.js +25 -3
  390. package/dist/deploy/build.js.map +1 -1
  391. package/dist/eject/remote-mcp-presets.js +1 -1
  392. package/dist/eject/remote-mcp-presets.js.map +1 -1
  393. package/dist/index.browser.d.ts +1 -1
  394. package/dist/index.browser.d.ts.map +1 -1
  395. package/dist/index.browser.js +1 -1
  396. package/dist/index.browser.js.map +1 -1
  397. package/dist/index.d.ts +1 -1
  398. package/dist/index.d.ts.map +1 -1
  399. package/dist/index.js +1 -1
  400. package/dist/index.js.map +1 -1
  401. package/dist/integrations/google-docs-poller.d.ts.map +1 -1
  402. package/dist/integrations/google-docs-poller.js +4 -1
  403. package/dist/integrations/google-docs-poller.js.map +1 -1
  404. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  405. package/dist/integrations/webhook-handler.js +23 -11
  406. package/dist/integrations/webhook-handler.js.map +1 -1
  407. package/dist/jobs/scheduler.js +4 -0
  408. package/dist/jobs/scheduler.js.map +1 -1
  409. package/dist/localization/default-messages.d.ts +3 -2
  410. package/dist/localization/default-messages.d.ts.map +1 -1
  411. package/dist/localization/default-messages.js +3 -2
  412. package/dist/localization/default-messages.js.map +1 -1
  413. package/dist/mcp/build-server.d.ts.map +1 -1
  414. package/dist/mcp/build-server.js +10 -1
  415. package/dist/mcp/build-server.js.map +1 -1
  416. package/dist/notifications/routes.d.ts +1 -1
  417. package/dist/observability/traces.d.ts.map +1 -1
  418. package/dist/observability/traces.js +27 -7
  419. package/dist/observability/traces.js.map +1 -1
  420. package/dist/org/handlers.d.ts +15 -0
  421. package/dist/org/handlers.d.ts.map +1 -1
  422. package/dist/org/handlers.js +45 -1
  423. package/dist/org/handlers.js.map +1 -1
  424. package/dist/org/migrations.d.ts.map +1 -1
  425. package/dist/org/migrations.js +4 -0
  426. package/dist/org/migrations.js.map +1 -1
  427. package/dist/org/plugin.d.ts +1 -0
  428. package/dist/org/plugin.d.ts.map +1 -1
  429. package/dist/org/plugin.js +10 -1
  430. package/dist/org/plugin.js.map +1 -1
  431. package/dist/org/schema.d.ts +19 -0
  432. package/dist/org/schema.d.ts.map +1 -1
  433. package/dist/org/schema.js +1 -0
  434. package/dist/org/schema.js.map +1 -1
  435. package/dist/org/types.d.ts +8 -0
  436. package/dist/org/types.d.ts.map +1 -1
  437. package/dist/org/types.js.map +1 -1
  438. package/dist/org/workspace-url.d.ts +32 -0
  439. package/dist/org/workspace-url.d.ts.map +1 -0
  440. package/dist/org/workspace-url.js +63 -0
  441. package/dist/org/workspace-url.js.map +1 -0
  442. package/dist/progress/routes.d.ts +1 -1
  443. package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
  444. package/dist/provider-api/actions/provider-api.d.ts +7 -7
  445. package/dist/resources/handlers.d.ts +2 -3
  446. package/dist/resources/handlers.d.ts.map +1 -1
  447. package/dist/resources/handlers.js +25 -5
  448. package/dist/resources/handlers.js.map +1 -1
  449. package/dist/scripts/runner.d.ts +17 -0
  450. package/dist/scripts/runner.d.ts.map +1 -1
  451. package/dist/scripts/runner.js +130 -5
  452. package/dist/scripts/runner.js.map +1 -1
  453. package/dist/secrets/routes.d.ts +9 -9
  454. package/dist/server/action-routes.d.ts.map +1 -1
  455. package/dist/server/action-routes.js +24 -2
  456. package/dist/server/action-routes.js.map +1 -1
  457. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  458. package/dist/server/agent-chat-plugin.js +26 -1
  459. package/dist/server/agent-chat-plugin.js.map +1 -1
  460. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  461. package/dist/server/agent-teams.d.ts.map +1 -1
  462. package/dist/server/agent-teams.js +10 -1
  463. package/dist/server/agent-teams.js.map +1 -1
  464. package/dist/server/auth.d.ts +22 -0
  465. package/dist/server/auth.d.ts.map +1 -1
  466. package/dist/server/auth.js +33 -7
  467. package/dist/server/auth.js.map +1 -1
  468. package/dist/server/embed-route.d.ts.map +1 -1
  469. package/dist/server/embed-route.js +6 -1
  470. package/dist/server/embed-route.js.map +1 -1
  471. package/dist/server/embed-session.d.ts +7 -0
  472. package/dist/server/embed-session.d.ts.map +1 -1
  473. package/dist/server/embed-session.js +46 -4
  474. package/dist/server/embed-session.js.map +1 -1
  475. package/dist/server/open-route.d.ts.map +1 -1
  476. package/dist/server/open-route.js +17 -7
  477. package/dist/server/open-route.js.map +1 -1
  478. package/dist/server/prompts/framework-core-compact.js +1 -1
  479. package/dist/server/prompts/framework-core-compact.js.map +1 -1
  480. package/dist/server/prompts/framework-core.d.ts.map +1 -1
  481. package/dist/server/prompts/framework-core.js +1 -0
  482. package/dist/server/prompts/framework-core.js.map +1 -1
  483. package/dist/server/request-context.d.ts +26 -0
  484. package/dist/server/request-context.d.ts.map +1 -1
  485. package/dist/server/request-context.js +18 -1
  486. package/dist/server/request-context.js.map +1 -1
  487. package/dist/shared/embed-auth.d.ts +1 -0
  488. package/dist/shared/embed-auth.d.ts.map +1 -1
  489. package/dist/shared/embed-auth.js +1 -0
  490. package/dist/shared/embed-auth.js.map +1 -1
  491. package/dist/shared/html-document.d.ts +12 -0
  492. package/dist/shared/html-document.d.ts.map +1 -0
  493. package/dist/shared/html-document.js +92 -0
  494. package/dist/shared/html-document.js.map +1 -0
  495. package/dist/shared/index.d.ts +1 -0
  496. package/dist/shared/index.d.ts.map +1 -1
  497. package/dist/shared/index.js +1 -0
  498. package/dist/shared/index.js.map +1 -1
  499. package/dist/sharing/access.d.ts +1 -0
  500. package/dist/sharing/access.d.ts.map +1 -1
  501. package/dist/sharing/access.js +8 -2
  502. package/dist/sharing/access.js.map +1 -1
  503. package/dist/sharing/registry.d.ts +3 -0
  504. package/dist/sharing/registry.d.ts.map +1 -1
  505. package/dist/sharing/registry.js.map +1 -1
  506. package/dist/workspace-files/actions.d.ts +28 -0
  507. package/dist/workspace-files/actions.d.ts.map +1 -0
  508. package/dist/workspace-files/actions.js +75 -0
  509. package/dist/workspace-files/actions.js.map +1 -0
  510. package/dist/workspace-files/tool.d.ts.map +1 -1
  511. package/dist/workspace-files/tool.js +4 -0
  512. package/dist/workspace-files/tool.js.map +1 -1
  513. package/docs/content/cloneable-saas.mdx +114 -0
  514. package/docs/content/creating-templates.mdx +28 -2
  515. package/docs/content/syncing-template-changes.mdx +7 -0
  516. package/docs/content/template-clips-developers.mdx +12 -5
  517. package/docs/content/template-dispatch-developers.mdx +1 -1
  518. package/docs/content/template-dispatch.mdx +1 -1
  519. package/package.json +2 -2
  520. package/src/action-ui.ts +1 -0
  521. package/src/action.ts +5 -1
  522. package/src/agent/engine/ai-sdk-engine.ts +15 -5
  523. package/src/agent/harness/runner.ts +5 -0
  524. package/src/agent/production-agent.ts +33 -0
  525. package/src/agent/run-loop-with-resume.ts +5 -0
  526. package/src/agent/run-manager.ts +126 -1
  527. package/src/agent/thread-data-builder.ts +47 -2
  528. package/src/agent/types.ts +2 -0
  529. package/src/chat-threads/store.ts +4 -5
  530. package/src/cli/create.ts +1139 -65
  531. package/src/cli/design-connect.ts +3 -7
  532. package/src/cli/index.ts +5 -3
  533. package/src/cli/skills-content/design-visual-edit-skill.ts +83 -47
  534. package/src/client/AssistantChat.tsx +27 -16
  535. package/src/client/agent-chat-adapter.ts +24 -0
  536. package/src/client/blocks/library/wireframe-kit.tsx +17 -2
  537. package/src/client/chat/index.ts +1 -0
  538. package/src/client/chat/message-components.tsx +104 -1
  539. package/src/client/chat/run-recovery.tsx +15 -3
  540. package/src/client/chat/widgets/DataTableWidget.tsx +10 -29
  541. package/src/client/chat/widgets/WorkspaceFileWidget.tsx +71 -0
  542. package/src/client/chat/widgets/builtin-tool-renderers.tsx +22 -0
  543. package/src/client/chat/widgets/workspace-file-result.ts +49 -0
  544. package/src/client/embed-auth.ts +2 -0
  545. package/src/client/org/InvitationBanner.tsx +14 -1
  546. package/src/client/org/OrgSwitcher.tsx +23 -0
  547. package/src/client/org/TeamPage.tsx +130 -0
  548. package/src/client/org/WorkspaceNotice.tsx +85 -0
  549. package/src/client/org/hooks.ts +14 -0
  550. package/src/client/org/index.ts +2 -0
  551. package/src/client/resources/McpIntegrationDialog.tsx +27 -40
  552. package/src/client/resources/ResourcesPanel.tsx +134 -51
  553. package/src/client/resources/mcp-integration-catalog.ts +7 -0
  554. package/src/client/resources/use-resources.ts +6 -0
  555. package/src/client/use-action.ts +3 -1
  556. package/src/client/widgets/index.ts +1 -0
  557. package/src/coding-tools/run-code.ts +2 -1
  558. package/src/db/client.ts +28 -4
  559. package/src/deploy/build.ts +31 -3
  560. package/src/eject/remote-mcp-presets.ts +1 -1
  561. package/src/index.browser.ts +1 -0
  562. package/src/index.ts +1 -0
  563. package/src/integrations/google-docs-poller.ts +3 -0
  564. package/src/integrations/webhook-handler.ts +28 -11
  565. package/src/jobs/scheduler.ts +4 -0
  566. package/src/localization/default-messages.ts +3 -2
  567. package/src/mcp/build-server.ts +20 -2
  568. package/src/observability/traces.ts +48 -12
  569. package/src/org/handlers.ts +52 -1
  570. package/src/org/migrations.ts +4 -0
  571. package/src/org/plugin.ts +14 -0
  572. package/src/org/schema.ts +1 -0
  573. package/src/org/types.ts +8 -0
  574. package/src/org/workspace-url.ts +74 -0
  575. package/src/resources/handlers.ts +35 -5
  576. package/src/scripts/runner.ts +183 -5
  577. package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +2 -1
  578. package/src/server/action-routes.ts +32 -2
  579. package/src/server/agent-chat-plugin.ts +29 -0
  580. package/src/server/agent-teams.ts +10 -1
  581. package/src/server/auth.ts +33 -7
  582. package/src/server/embed-route.ts +9 -0
  583. package/src/server/embed-session.ts +62 -3
  584. package/src/server/open-route.ts +20 -6
  585. package/src/server/prompts/framework-core-compact.ts +1 -1
  586. package/src/server/prompts/framework-core.ts +1 -0
  587. package/src/server/request-context.ts +36 -1
  588. package/src/shared/embed-auth.ts +1 -0
  589. package/src/shared/html-document.ts +115 -0
  590. package/src/shared/index.ts +1 -0
  591. package/src/sharing/access.ts +8 -1
  592. package/src/sharing/registry.ts +11 -2
  593. package/src/workspace-files/actions.ts +100 -0
  594. package/src/workspace-files/tool.ts +4 -0
  595. package/corpus/templates/design/changelog/2026-07-28-interact-mode-can-preview-designs-in-responsive-device-sizes.md +0 -6
  596. package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-opens-a-full-screen-responsive-preview-wit.md +0 -6
@@ -11,6 +11,7 @@
11
11
  */
12
12
 
13
13
  import fs from "fs";
14
+ import { spawnSync } from "node:child_process";
14
15
  import path from "path";
15
16
  import { pathToFileURL } from "url";
16
17
 
@@ -29,6 +30,174 @@ import { loadEnv } from "./utils.js";
29
30
  // Load .env from cwd so DATABASE_URL and other vars are available to all actions.
30
31
  loadEnv();
31
32
 
33
+ const CLI_HANDOFF_KEYS = new Set(["embedStartUrl", "startUrl"]);
34
+ const CLI_HANDOFF_URL_PATTERN =
35
+ /\/_agent-native\/embed\/start\?[^\s"'<>)}\]]+/g;
36
+
37
+ function withoutCliHandoffText(value: unknown): string {
38
+ return String(value).replace(
39
+ CLI_HANDOFF_URL_PATTERN,
40
+ "[redacted embed handoff]",
41
+ );
42
+ }
43
+
44
+ function cliHandoffUrl(result: unknown): string | undefined {
45
+ if (!result || typeof result !== "object") return undefined;
46
+ for (const key of CLI_HANDOFF_KEYS) {
47
+ const value = (result as Record<string, unknown>)[key];
48
+ if (
49
+ typeof value === "string" &&
50
+ value.includes("/_agent-native/embed/start?")
51
+ ) {
52
+ return value;
53
+ }
54
+ }
55
+ return undefined;
56
+ }
57
+
58
+ function withoutCliHandoffSecrets(
59
+ value: unknown,
60
+ ancestors = new WeakSet<object>(),
61
+ ): unknown {
62
+ if (
63
+ typeof value === "string" &&
64
+ value.includes("/_agent-native/embed/start?")
65
+ ) {
66
+ return withoutCliHandoffText(value);
67
+ }
68
+ if (!value || typeof value !== "object") return value;
69
+ if (ancestors.has(value)) return "[Circular]";
70
+ ancestors.add(value);
71
+ try {
72
+ if (Array.isArray(value)) {
73
+ return value.map((child) => withoutCliHandoffSecrets(child, ancestors));
74
+ }
75
+ return Object.fromEntries(
76
+ Object.entries(value as Record<string, unknown>)
77
+ .filter(([key]) => !CLI_HANDOFF_KEYS.has(key))
78
+ .map(([key, child]) => [
79
+ key,
80
+ withoutCliHandoffSecrets(child, ancestors),
81
+ ]),
82
+ );
83
+ } finally {
84
+ ancestors.delete(value);
85
+ }
86
+ }
87
+
88
+ type CliHandoffLaunchOutcome =
89
+ | { ok: true }
90
+ | {
91
+ ok: false;
92
+ reason: "disabled" | "missing-base" | "invalid-url" | "open-failed";
93
+ message: string;
94
+ };
95
+
96
+ interface CliHandoffLaunchDeps {
97
+ env?: NodeJS.ProcessEnv;
98
+ platform?: NodeJS.Platform;
99
+ spawn?: (
100
+ command: string,
101
+ args: string[],
102
+ ) => { status: number | null; error?: Error };
103
+ }
104
+
105
+ export function openCliHandoff(
106
+ urlOrPath: string,
107
+ deps: CliHandoffLaunchDeps = {},
108
+ ): CliHandoffLaunchOutcome {
109
+ const env = deps.env ?? process.env;
110
+ if (env.AGENT_NATIVE_NO_OPEN === "1") {
111
+ return {
112
+ ok: false,
113
+ reason: "disabled",
114
+ message:
115
+ "Secure browser handoff is disabled by AGENT_NATIVE_NO_OPEN. Remove it and rerun this action.",
116
+ };
117
+ }
118
+ let url = urlOrPath;
119
+ if (urlOrPath.startsWith("/")) {
120
+ const baseUrl =
121
+ env.APP_URL ||
122
+ env.WORKSPACE_GATEWAY_URL ||
123
+ env.VITE_WORKSPACE_GATEWAY_URL ||
124
+ env.BETTER_AUTH_URL;
125
+ if (!baseUrl) {
126
+ return {
127
+ ok: false,
128
+ reason: "missing-base",
129
+ message:
130
+ "Secure browser handoff needs APP_URL or WORKSPACE_GATEWAY_URL. Start the app locally or set its URL, then rerun this action.",
131
+ };
132
+ }
133
+ try {
134
+ url = new URL(urlOrPath, baseUrl).toString();
135
+ } catch {
136
+ return {
137
+ ok: false,
138
+ reason: "invalid-url",
139
+ message:
140
+ "Secure browser handoff found an invalid app URL. Fix APP_URL or WORKSPACE_GATEWAY_URL, then rerun this action.",
141
+ };
142
+ }
143
+ }
144
+ try {
145
+ const parsed = new URL(url);
146
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
147
+ throw new Error("unsupported protocol");
148
+ }
149
+ } catch {
150
+ return {
151
+ ok: false,
152
+ reason: "invalid-url",
153
+ message:
154
+ "Secure browser handoff found an invalid app URL. Fix APP_URL or WORKSPACE_GATEWAY_URL, then rerun this action.",
155
+ };
156
+ }
157
+
158
+ const platform = deps.platform ?? process.platform;
159
+ const command =
160
+ platform === "darwin" ? "open" : platform === "win32" ? "cmd" : "xdg-open";
161
+ const args = platform === "win32" ? ["/c", "start", "", url] : [url];
162
+ try {
163
+ const launch =
164
+ deps.spawn?.(command, args) ??
165
+ spawnSync(command, args, {
166
+ stdio: "ignore",
167
+ timeout: 10_000,
168
+ });
169
+ if (launch.error || launch.status !== 0) {
170
+ return {
171
+ ok: false,
172
+ reason: "open-failed",
173
+ message:
174
+ "Secure browser handoff could not invoke the system URL opener. Verify local URL handling, then rerun this action.",
175
+ };
176
+ }
177
+ } catch {
178
+ return {
179
+ ok: false,
180
+ reason: "open-failed",
181
+ message:
182
+ "Secure browser handoff could not invoke the system URL opener. Verify local URL handling, then rerun this action.",
183
+ };
184
+ }
185
+ return { ok: true };
186
+ }
187
+
188
+ function printActionResult(result: unknown): CliHandoffLaunchOutcome | null {
189
+ const handoffUrl = cliHandoffUrl(result);
190
+ const handoff = handoffUrl ? openCliHandoff(handoffUrl) : null;
191
+ console.log(withoutCliHandoffSecrets(result));
192
+ return handoff;
193
+ }
194
+
195
+ function assertCliHandoffLaunched(
196
+ outcome: CliHandoffLaunchOutcome | null,
197
+ ): void {
198
+ if (outcome && !outcome.ok) throw new Error(outcome.message);
199
+ }
200
+
32
201
  export interface RunScriptOptions {
33
202
  /**
34
203
  * Actions contributed by packages rather than the app's local `actions/`
@@ -276,7 +445,7 @@ async function dispatchAction(
276
445
  if (handler.readOnly !== true) {
277
446
  await notifyActionChange({ actionName }).catch(() => {});
278
447
  }
279
- if (result) console.log(result);
448
+ if (result) assertCliHandoffLaunched(printActionResult(result));
280
449
  } else if (typeof handler === "function") {
281
450
  await handler(args);
282
451
  } else {
@@ -289,7 +458,10 @@ async function dispatchAction(
289
458
  process.exit(0);
290
459
  } catch (err: any) {
291
460
  await closeDbExec().catch(() => {});
292
- console.error(`Action "${actionName}" failed:`, err.message || err);
461
+ console.error(
462
+ `Action "${actionName}" failed:`,
463
+ withoutCliHandoffText(err.message || err),
464
+ );
293
465
  process.exit(1);
294
466
  }
295
467
  }
@@ -307,12 +479,15 @@ async function dispatchAction(
307
479
  if (packageAction.readOnly !== true) {
308
480
  await notifyActionChange({ actionName }).catch(() => {});
309
481
  }
310
- if (result) console.log(result);
482
+ if (result) assertCliHandoffLaunched(printActionResult(result));
311
483
  await closeDbExec().catch(() => {});
312
484
  process.exit(0);
313
485
  } catch (err: any) {
314
486
  await closeDbExec().catch(() => {});
315
- console.error(`Action "${actionName}" failed:`, err.message || err);
487
+ console.error(
488
+ `Action "${actionName}" failed:`,
489
+ withoutCliHandoffText(err.message || err),
490
+ );
316
491
  process.exit(1);
317
492
  }
318
493
  }
@@ -326,7 +501,10 @@ async function dispatchAction(
326
501
  process.exit(0);
327
502
  } catch (err: any) {
328
503
  await closeDbExec().catch(() => {});
329
- console.error(`Core action "${actionName}" failed:`, err.message || err);
504
+ console.error(
505
+ `Core action "${actionName}" failed:`,
506
+ withoutCliHandoffText(err.message || err),
507
+ );
330
508
  process.exit(1);
331
509
  }
332
510
  }
@@ -26,7 +26,7 @@ Bring a senior engineer's judgment, arrived at through attention not premature c
26
26
  - **Never fabricate factual claims or records** — do not invent numbers, metrics, records, query results, URLs, citations, source attributions, customer names, dates, or success rates. This applies inside generated artifacts too: decks, documents, reports, dashboards, Slack/email replies, and charts. Only state factual numbers/claims the user provided or you retrieved with an action/tool. If a data source is unavailable, returns no rows, is missing credentials, or has a connection error, say so clearly; do not create placeholder rows or fetch unrelated providers to look complete unless the user explicitly asked you to import/sync/backfill. Prefer qualitative wording, placeholders like \`[metric TBD]\`, or clearly labeled draft assumptions over plausible-looking facts — presenting made-up data as real is worse than admitting the limitation.
27
27
  - **Never fabricate success from tool errors** — when a tool call returns an error (marked \`isError: true\`, contains "Command failed", "Error:", or non-zero exit output), the operation FAILED; do not synthesize a success narrative or describe what it "would have" produced. Report the failure verbatim (this applies especially to \`bash(command="pnpm action ...")\` calls). Before telling the user a mutating action (create/update/delete/send/publish) is done, confirm it actually landed — check the tool result, or read the refreshed \`<current-screen>\` / re-query the data; having *called* an action is not proof it worked. If a result is ambiguous, check rather than assume.
28
28
  - **Recover instead of giving up** — treat a failure or ambiguous result as a signal to retry the obvious fix, try an alternate tool or approach, or clearly hand the blocker back with what you tried; never silently give up, and never paper over a failure by claiming success.
29
- **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.
29
+ **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.
30
30
  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.
31
31
  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.
32
32
  12. **Plan and track multi-step work** — When a task spans several real steps the user would want to watch, open a \`manage-progress\` run so the work is visible while it's still in flight, and keep it updated as you go rather than after the fact; the tool's own description carries the full discipline. Skip it for single-action lookups, simple reads, and anything that finishes in one tool call — never create single-step plans.
@@ -88,6 +88,7 @@ Write like a sharp, warm product teammate: concise, direct, and human. Lead with
88
88
  - **Never fabricate success from tool errors** — when a tool call returns an error (marked \`isError: true\`, contains "Command failed", "Error:", or non-zero exit output), the operation FAILED; do not synthesize a success narrative or describe what it "would have" produced. Report the failure verbatim (this applies especially to \`bash(command="pnpm action ...")\` calls). Before telling the user a mutating action (create/update/delete/send/publish) is done, confirm it actually landed — check the tool result, or read the refreshed \`<current-screen>\` / re-query the data; having *called* an action is not proof it worked. If a result is ambiguous, check rather than assume.
89
89
  - **Recover instead of giving up** — treat a failure or ambiguous result as a signal to retry the obvious fix, try an alternate tool or approach, or clearly hand the blocker back with what you tried; never silently give up, and never paper over a failure by claiming success.
90
90
  **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.
91
+ **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.
91
92
  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.
92
93
  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.
93
94
  12. **Plan and track multi-step work** — When a task spans several real steps the user would want to watch, open a \`manage-progress\` run so the work is visible while it's still in flight, and keep it updated as you go rather than after the fact; the tool's own description carries the full discipline. Skip it for single-action lookups, simple reads, and anything that finishes in one tool call — never create single-step plans.
@@ -31,6 +31,10 @@ import {
31
31
  getAllowedCorsOrigin as resolveAllowedCorsOrigin,
32
32
  readCorsAllowedOrigins,
33
33
  } from "./cors-origins.js";
34
+ import {
35
+ resolveEmbedSessionFromRequest,
36
+ resolvedEmbedCapabilityScope,
37
+ } from "./embed-session.js";
34
38
  import { getHttpRequestTelemetryId } from "./http-response-telemetry.js";
35
39
 
36
40
  declare const __AGENT_NATIVE_BUILD_ID__: string | undefined;
@@ -58,10 +62,12 @@ function currentBuildId(): string {
58
62
  * Actions are exposed as POST by default. Use `http: { method: "GET" }` in
59
63
  * defineAction to expose as GET. Use `http: false` to mark as agent-only.
60
64
  */
65
+ import { isLoopbackRequest } from "./auth.js";
61
66
  import { getH3App } from "./framework-request-handler.js";
62
67
  import { runWithRequestContext } from "./request-context.js";
63
68
 
64
69
  const ROUTE_PREFIX = "/_agent-native/actions";
70
+ const FRONTEND_MUTATION_METHODS = new Set(["POST", "PUT", "DELETE"]);
65
71
 
66
72
  async function resolveFeatureFlagA2ACaller(event: any, actionName: string) {
67
73
  const required =
@@ -309,6 +315,19 @@ function isAuthResolutionFailure(error: unknown): boolean {
309
315
  );
310
316
  }
311
317
 
318
+ async function resolveRequestAuthCapability(
319
+ event: any,
320
+ ): Promise<string | undefined> {
321
+ try {
322
+ return resolvedEmbedCapabilityScope(
323
+ await resolveEmbedSessionFromRequest(event),
324
+ );
325
+ } catch {
326
+ // Invalid or unavailable embed auth must fail closed as no capability.
327
+ return undefined;
328
+ }
329
+ }
330
+
312
331
  /**
313
332
  * Mount discovered actions as HTTP endpoints.
314
333
  *
@@ -348,8 +367,14 @@ export function mountActionRoutes(
348
367
  "X-Agent-Native-Client-Mismatch,X-Agent-Native-Build-Id,X-Agent-Native-Client-Compatibility",
349
368
  );
350
369
 
351
- // Allow the declared method
352
- if (effectiveMethod !== method) {
370
+ // Browser action calls are RPCs over the framework transport. The
371
+ // action's HTTP method remains authoritative for direct HTTP callers,
372
+ // but frontend callers must not have to duplicate it in every hook.
373
+ const isFrontendMutation =
374
+ isFrontendActionRequest(event) &&
375
+ FRONTEND_MUTATION_METHODS.has(method) &&
376
+ FRONTEND_MUTATION_METHODS.has(effectiveMethod);
377
+ if (effectiveMethod !== method && !isFrontendMutation) {
353
378
  setResponseStatus(event, 405);
354
379
  return { error: `Method not allowed. Use ${method}.` };
355
380
  }
@@ -403,6 +428,7 @@ export function mountActionRoutes(
403
428
  // Resolve auth context for per-request scoping
404
429
  let userEmail: string | undefined;
405
430
  let userName: string | undefined;
431
+ const authCapability = await resolveRequestAuthCapability(event);
406
432
  // An app-supplied auth adapter runs first: it can accept caller
407
433
  // identities the framework's getSession chain doesn't understand (e.g.
408
434
  // an A2A JWT). A resolved caller is seeded onto the event context so any
@@ -493,8 +519,12 @@ export function mountActionRoutes(
493
519
  userEmail,
494
520
  userName,
495
521
  orgId,
522
+ authCapability,
496
523
  timezone,
497
524
  requestOrigin: getRequestURL(event).origin,
525
+ // Captured here because this is the last layer that still holds
526
+ // the h3 event; everything below reads it off the request store.
527
+ isLoopbackRequest: isLoopbackRequest(event),
498
528
  },
499
529
  async () => {
500
530
  // Reject oversize bodies from Content-Length before parsing, so a
@@ -90,8 +90,10 @@ import {
90
90
  import {
91
91
  buildAssistantMessage,
92
92
  buildUserMessage,
93
+ claimQueuedMessage,
93
94
  extractThreadMeta,
94
95
  foldAssistantTurn,
96
+ hasClaimedQueuedMessage,
95
97
  mergeThreadDataForClientSave,
96
98
  upsertUserMessage,
97
99
  } from "../agent/thread-data-builder.js";
@@ -1043,6 +1045,12 @@ export function createAgentChatPlugin(
1043
1045
  await import("../workspace-files/tool.js");
1044
1046
  workspaceFilesTool = createWorkspaceFilesTool();
1045
1047
  } catch {}
1048
+ let workspaceFileActions: Record<string, ActionEntry> = {};
1049
+ try {
1050
+ const { createWorkspaceFileActionEntries } =
1051
+ await import("../workspace-files/actions.js");
1052
+ workspaceFileActions = createWorkspaceFileActionEntries();
1053
+ } catch {}
1046
1054
  let toolActions: Record<string, ActionEntry> =
1047
1055
  createDataWidgetActionEntries();
1048
1056
  if (extensionToolsEnabled) {
@@ -1238,6 +1246,7 @@ export function createAgentChatPlugin(
1238
1246
  ...fetchTool,
1239
1247
  ...webSearchTool,
1240
1248
  ...workspaceFilesTool,
1249
+ ...workspaceFileActions,
1241
1250
  ...toolActions,
1242
1251
  ...browserSessionTools,
1243
1252
  ...coreEmailTools,
@@ -1263,6 +1272,7 @@ export function createAgentChatPlugin(
1263
1272
  ...fetchTool,
1264
1273
  ...webSearchTool,
1265
1274
  ...workspaceFilesTool,
1275
+ ...workspaceFileActions,
1266
1276
  ...toolActions,
1267
1277
  ...browserSessionTools,
1268
1278
  ...coreEmailTools,
@@ -1302,6 +1312,7 @@ export function createAgentChatPlugin(
1302
1312
  ...fetchTool,
1303
1313
  ...webSearchTool,
1304
1314
  ...workspaceFilesTool,
1315
+ ...workspaceFileActions,
1305
1316
  ...toolActions,
1306
1317
  ...browserSessionTools,
1307
1318
  ...coreEmailTools,
@@ -1630,6 +1641,7 @@ export function createAgentChatPlugin(
1630
1641
  ...fetchTool,
1631
1642
  ...webSearchTool,
1632
1643
  ...workspaceFilesTool,
1644
+ ...workspaceFileActions,
1633
1645
  ...toolActions,
1634
1646
  ...browserSessionTools,
1635
1647
  ...coreEmailTools,
@@ -1651,6 +1663,7 @@ export function createAgentChatPlugin(
1651
1663
  ...fetchTool,
1652
1664
  ...webSearchTool,
1653
1665
  ...workspaceFilesTool,
1666
+ ...workspaceFileActions,
1654
1667
  ...toolActions,
1655
1668
  ...browserSessionTools,
1656
1669
  ...coreEmailTools,
@@ -2030,6 +2043,7 @@ export function createAgentChatPlugin(
2030
2043
  ...fetchTool,
2031
2044
  ...webSearchTool,
2032
2045
  ...workspaceFilesTool,
2046
+ ...workspaceFileActions,
2033
2047
  ...toolActions,
2034
2048
  ...mcpActionEntries,
2035
2049
  ...devScriptsForA2A,
@@ -2047,6 +2061,7 @@ export function createAgentChatPlugin(
2047
2061
  ...fetchTool,
2048
2062
  ...webSearchTool,
2049
2063
  ...workspaceFilesTool,
2064
+ ...workspaceFileActions,
2050
2065
  ...toolActions,
2051
2066
  ...mcpActionEntries,
2052
2067
  ...(resolvedProdCodeExec !== "off" ? runCodeTool : {}),
@@ -2472,6 +2487,7 @@ export function createAgentChatPlugin(
2472
2487
  threadId: string | undefined;
2473
2488
  message: string;
2474
2489
  attachments?: AgentChatAttachment[];
2490
+ queuedMessageId?: string;
2475
2491
  }) => {
2476
2492
  const threadId = details.threadId;
2477
2493
  if (!threadId) return;
@@ -2514,12 +2530,23 @@ export function createAgentChatPlugin(
2514
2530
  repo = {};
2515
2531
  }
2516
2532
 
2533
+ if (details.queuedMessageId) {
2534
+ if (hasClaimedQueuedMessage(repo, details.queuedMessageId)) {
2535
+ throw createError({
2536
+ statusCode: 409,
2537
+ statusMessage: "Queued message was already submitted",
2538
+ });
2539
+ }
2540
+ repo = claimQueuedMessage(repo, details.queuedMessageId);
2541
+ }
2542
+
2517
2543
  repo = upsertUserMessage(
2518
2544
  repo,
2519
2545
  buildUserMessage({
2520
2546
  text: details.message,
2521
2547
  attachments: details.attachments,
2522
2548
  runId: details.runId,
2549
+ queuedMessageId: details.queuedMessageId,
2523
2550
  }),
2524
2551
  );
2525
2552
 
@@ -2654,6 +2681,7 @@ export function createAgentChatPlugin(
2654
2681
  ...fetchTool,
2655
2682
  ...webSearchTool,
2656
2683
  ...workspaceFilesTool,
2684
+ ...workspaceFileActions,
2657
2685
  ...toolActions,
2658
2686
  ...browserSessionTools,
2659
2687
  ...coreEmailTools,
@@ -3193,6 +3221,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
3193
3221
  ...fetchTool,
3194
3222
  ...webSearchTool,
3195
3223
  ...workspaceFilesTool,
3224
+ ...workspaceFileActions,
3196
3225
  ...toolActions,
3197
3226
  ...browserSessionTools,
3198
3227
  ...coreEmailTools,
@@ -1988,7 +1988,16 @@ export async function processAgentTeamRun(
1988
1988
  resolve();
1989
1989
  }
1990
1990
  },
1991
- { useHostedSoftTimeoutDefault: true, turnId },
1991
+ {
1992
+ useHostedSoftTimeoutDefault: true,
1993
+ turnId,
1994
+ // No userId here: `ownerEmail` is the only identity known at
1995
+ // this scope and is PII (email), which the terminal event must
1996
+ // not carry.
1997
+ model: config.model,
1998
+ engineName: config.engine.name,
1999
+ attemptCount: claimedAttempts,
2000
+ },
1992
2001
  );
1993
2002
  });
1994
2003
 
@@ -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");