@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
@@ -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
@@ -0,0 +1,100 @@
1
+ import { z } from "zod";
2
+
3
+ import { ACTION_CHAT_UI_WORKSPACE_FILE_RENDERER } from "../action-ui.js";
4
+ import { defineAction } from "../action.js";
5
+ import type { ActionEntry } from "../agent/production-agent.js";
6
+ import {
7
+ getRequestOrgId,
8
+ getRequestUserEmail,
9
+ } from "../server/request-context.js";
10
+ import { getWorkspaceFileMeta, type WorkspaceFilesScope } from "./store.js";
11
+
12
+ const workspaceFileResultSchema = z.object({
13
+ file: z.object({
14
+ resourceId: z.string().min(1),
15
+ path: z.string().min(1),
16
+ name: z.string().min(1),
17
+ contentType: z.string().min(1),
18
+ sizeBytes: z.number().int().nonnegative(),
19
+ updatedAt: z.string().min(1),
20
+ }),
21
+ });
22
+
23
+ export type WorkspaceFileActionResult = z.infer<
24
+ typeof workspaceFileResultSchema
25
+ >;
26
+
27
+ function currentWorkspaceScope(): WorkspaceFilesScope {
28
+ const orgId = getRequestOrgId();
29
+ if (orgId) return { scope: "org", scopeId: orgId };
30
+
31
+ const userEmail = getRequestUserEmail();
32
+ if (userEmail) return { scope: "user", scopeId: userEmail };
33
+
34
+ throw new Error(
35
+ "show-workspace-file requires an authenticated request context.",
36
+ );
37
+ }
38
+
39
+ function fileName(path: string): string {
40
+ return path.split("/").at(-1) || path;
41
+ }
42
+
43
+ function isTextWorkspaceFile(contentType: string): boolean {
44
+ const mimeType = contentType.split(";")[0].trim().toLowerCase();
45
+ return mimeType.startsWith("text/") || mimeType === "application/json";
46
+ }
47
+
48
+ export const showWorkspaceFileAction = defineAction({
49
+ description:
50
+ "Render a workspace file as a downloadable card in chat. Call this after writing a user-requested export or other durable file with workspaceWrite; a file export is not complete until this action succeeds and the download card appears. The path must exactly match an existing file in the current organization or personal workspace.",
51
+ schema: z.object({
52
+ path: z
53
+ .string()
54
+ .trim()
55
+ .min(1)
56
+ .describe(
57
+ 'Exact workspace-relative path returned by workspaceWrite, for example "exports/report.csv".',
58
+ ),
59
+ }),
60
+ outputSchema: workspaceFileResultSchema,
61
+ outputErrorStrategy: "strict",
62
+ http: false,
63
+ readOnly: true,
64
+ chatUI: {
65
+ renderer: ACTION_CHAT_UI_WORKSPACE_FILE_RENDERER,
66
+ title: "Workspace file",
67
+ description: "A private, downloadable workspace file.",
68
+ },
69
+ run: async ({ path }) => {
70
+ const file = await getWorkspaceFileMeta(currentWorkspaceScope(), path);
71
+ if (!file) {
72
+ throw new Error(`Workspace file not found: "${path}"`);
73
+ }
74
+ if (!isTextWorkspaceFile(file.contentType)) {
75
+ throw new Error(
76
+ `Workspace file "${path}" has unsupported content type "${file.contentType}". show-workspace-file currently supports text files and application/json.`,
77
+ );
78
+ }
79
+
80
+ return {
81
+ file: {
82
+ resourceId: file.id,
83
+ path: file.path,
84
+ name: fileName(file.path),
85
+ contentType: file.contentType,
86
+ sizeBytes: file.sizeBytes,
87
+ updatedAt: file.updatedAt,
88
+ },
89
+ };
90
+ },
91
+ });
92
+
93
+ export function createWorkspaceFileActionEntries(): Record<
94
+ string,
95
+ ActionEntry
96
+ > {
97
+ return {
98
+ "show-workspace-file": showWorkspaceFileAction,
99
+ };
100
+ }
@@ -133,7 +133,9 @@ export function createWorkspaceFilesTool(): Record<string, ActionEntry> {
133
133
  return JSON.stringify({
134
134
  ok: true,
135
135
  action: "write",
136
+ resourceId: meta.id,
136
137
  path: meta.path,
138
+ contentType: meta.contentType,
137
139
  sizeBytes: meta.sizeBytes,
138
140
  updatedAt: meta.updatedAt,
139
141
  });
@@ -153,7 +155,9 @@ export function createWorkspaceFilesTool(): Record<string, ActionEntry> {
153
155
  return JSON.stringify({
154
156
  ok: true,
155
157
  action: "append",
158
+ resourceId: meta.id,
156
159
  path: meta.path,
160
+ contentType: meta.contentType,
157
161
  sizeBytes: meta.sizeBytes,
158
162
  updatedAt: meta.updatedAt,
159
163
  });
@@ -1,6 +0,0 @@
1
- ---
2
- type: added
3
- date: 2026-07-28
4
- ---
5
-
6
- Interact mode can preview designs in responsive device sizes
@@ -1,6 +0,0 @@
1
- ---
2
- type: added
3
- date: 2026-07-28
4
- ---
5
-
6
- Interact mode now opens a full-screen responsive preview with device presets, editable width/height, and zoom-to-fit