@agent-native/core 0.129.2 → 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 (589) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +72 -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/observability/traces.ts +48 -12
  58. package/corpus/core/src/org/handlers.ts +52 -1
  59. package/corpus/core/src/org/migrations.ts +4 -0
  60. package/corpus/core/src/org/plugin.ts +14 -0
  61. package/corpus/core/src/org/schema.ts +1 -0
  62. package/corpus/core/src/org/types.ts +8 -0
  63. package/corpus/core/src/org/workspace-url.ts +74 -0
  64. package/corpus/core/src/resources/handlers.ts +35 -5
  65. package/corpus/core/src/scripts/runner.ts +183 -5
  66. package/corpus/core/src/server/action-routes.ts +32 -2
  67. package/corpus/core/src/server/agent-chat-plugin.ts +29 -0
  68. package/corpus/core/src/server/agent-teams.ts +10 -1
  69. package/corpus/core/src/server/auth.ts +33 -7
  70. package/corpus/core/src/server/embed-route.ts +9 -0
  71. package/corpus/core/src/server/embed-session.ts +62 -3
  72. package/corpus/core/src/server/open-route.ts +20 -6
  73. package/corpus/core/src/server/prompts/framework-core-compact.ts +1 -1
  74. package/corpus/core/src/server/prompts/framework-core.ts +1 -0
  75. package/corpus/core/src/server/request-context.ts +36 -1
  76. package/corpus/core/src/shared/embed-auth.ts +1 -0
  77. package/corpus/core/src/shared/html-document.ts +115 -0
  78. package/corpus/core/src/shared/index.ts +1 -0
  79. package/corpus/core/src/sharing/access.ts +8 -1
  80. package/corpus/core/src/sharing/registry.ts +11 -2
  81. package/corpus/core/src/workspace-files/actions.ts +100 -0
  82. package/corpus/core/src/workspace-files/tool.ts +4 -0
  83. package/corpus/templates/analytics/.agents/skills/analysis-workspace/SKILL.md +4 -0
  84. package/corpus/templates/analytics/.agents/skills/hubspot/SKILL.md +9 -1
  85. package/corpus/templates/analytics/AGENTS.md +17 -24
  86. package/corpus/templates/analytics/actions/data-source-status.ts +11 -1
  87. package/corpus/templates/analytics/app/i18n-data.ts +34 -0
  88. package/corpus/templates/analytics/app/lib/data-source-status.ts +86 -0
  89. package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +9 -0
  90. package/corpus/templates/analytics/app/pages/DataSources.tsx +184 -20
  91. package/corpus/templates/analytics/changelog/2026-07-28-native-analytics-data-sources-no-longer-show-duplicate-mc.md +6 -0
  92. package/corpus/templates/analytics/changelog/2026-07-29-exports-now-appear-in-chat-with-a-direct-download-instead-of.md +6 -0
  93. package/corpus/templates/analytics/changelog/2026-07-29-queued-chat-prompts-no-longer-resend-after-analytics-navigat.md +6 -0
  94. package/corpus/templates/analytics/changelog/2026-07-29-scheduled-dashboard-emails-load-every-panel-reliably-without.md +6 -0
  95. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +6 -3
  96. package/corpus/templates/analytics/server/lib/credential-keys.ts +1 -1
  97. package/corpus/templates/analytics/server/lib/hubspot.ts +1 -1
  98. package/corpus/templates/analytics/server/lib/provider-credentials.ts +55 -1
  99. package/corpus/templates/analytics/server/plugins/agent-chat.ts +123 -27
  100. package/corpus/templates/analytics/server/routes/[...page].get.ts +2 -7
  101. package/corpus/templates/analytics/vite.config.ts +7 -0
  102. package/corpus/templates/brain/actions/list-connection-providers.ts +100 -2
  103. package/corpus/templates/brain/app/lib/brain.ts +10 -0
  104. package/corpus/templates/brain/app/routes/sources.tsx +15 -4
  105. package/corpus/templates/brain/changelog/2026-07-29-brain-automatically-retries-failed-source-syncs-and-guides-y.md +6 -0
  106. package/corpus/templates/brain/jobs/process-ingest-queue.ts +13 -0
  107. package/corpus/templates/brain/server/jobs/sync-sources.ts +27 -22
  108. package/corpus/templates/brain/server/plugins/agent-chat.ts +2 -1
  109. package/corpus/templates/brain/server/routes/api/brain/queue/run.post.ts +7 -1
  110. package/corpus/templates/clips/AGENTS.md +1 -1
  111. package/corpus/templates/clips/actions/create-recording-agent-link.ts +11 -1
  112. package/corpus/templates/clips/actions/update-comment.ts +68 -0
  113. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +0 -1
  114. package/corpus/templates/clips/app/components/player/comments-panel.tsx +221 -65
  115. package/corpus/templates/clips/app/components/player/video-player.tsx +101 -27
  116. package/corpus/templates/clips/app/i18n/en-US.ts +2 -1
  117. package/corpus/templates/clips/app/routes/bug-report.done.tsx +48 -27
  118. package/corpus/templates/clips/app/routes/bug-report.tsx +43 -4
  119. package/corpus/templates/clips/app/routes/record.tsx +2 -0
  120. package/corpus/templates/clips/changelog/2026-07-29-clip-playback-now-recovers-instead-of-getting-stuck-when-a-b.md +6 -0
  121. package/corpus/templates/clips/changelog/2026-07-29-comments-can-now-be-edited-after-posting.md +6 -0
  122. package/corpus/templates/clips/changelog/2026-07-29-download-actions-now-use-a-shorter-clearer-label.md +6 -0
  123. package/corpus/templates/clips/changelog/2026-07-29-embedded-bug-reports-now-return-a-temporary-agent-readable.md +6 -0
  124. package/corpus/templates/clips/shared/bug-report.ts +99 -0
  125. package/corpus/templates/content/actions/_content-database-personal-view.ts +7 -1
  126. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +5 -2
  127. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +20 -8
  128. package/corpus/templates/content/changelog/2026-07-29-missing-databases-no-longer-trigger-repeated-personal-view-e.md +6 -0
  129. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +83 -47
  130. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +474 -55
  131. package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +3 -0
  132. package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +18 -1
  133. package/corpus/templates/design/.generated/bridge/source-location.generated.ts +348 -0
  134. package/corpus/templates/design/actions/add-localhost-screens.ts +2 -7
  135. package/corpus/templates/design/actions/apply-visual-edit.ts +7 -1
  136. package/corpus/templates/design/actions/connect-localhost.ts +5 -9
  137. package/corpus/templates/design/actions/create-component.ts +16 -13
  138. package/corpus/templates/design/actions/grant-localhost-write-consent.ts +2 -7
  139. package/corpus/templates/design/actions/list-design-source-capabilities.ts +4 -7
  140. package/corpus/templates/design/actions/list-local-files.ts +26 -50
  141. package/corpus/templates/design/actions/list-localhost-connections.ts +2 -7
  142. package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +2 -2
  143. package/corpus/templates/design/actions/open-visual-edit.ts +234 -135
  144. package/corpus/templates/design/actions/read-local-file.ts +26 -50
  145. package/corpus/templates/design/actions/request-localhost-write-consent.ts +2 -7
  146. package/corpus/templates/design/actions/write-local-file.ts +31 -73
  147. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +307 -133
  148. package/corpus/templates/design/app/components/design/EditPanel.tsx +94 -22
  149. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +137 -60
  150. package/corpus/templates/design/app/components/design/ResponsiveInteractBar.tsx +75 -14
  151. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +755 -97
  152. package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +8 -0
  153. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +24 -1
  154. package/corpus/templates/design/app/components/design/bridge/source-location.bridge.ts +530 -0
  155. package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbenchLoader.tsx +278 -0
  156. package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +32 -12
  157. package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-setup.ts +14 -3
  158. package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +87 -24
  159. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +36 -0
  160. package/corpus/templates/design/app/components/design/code-workbench/store.tsx +2 -1
  161. package/corpus/templates/design/app/components/design/code-workbench/workspace/localhost-provider.ts +48 -8
  162. package/corpus/templates/design/app/components/design/design-canvas/content-size-report.ts +3 -13
  163. package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +4 -2
  164. package/corpus/templates/design/app/components/design/design-canvas/hit-test.ts +3 -13
  165. package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +3 -1
  166. package/corpus/templates/design/app/components/design/edit-panel/inspect-code-source.ts +93 -0
  167. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +4 -2
  168. package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +35 -0
  169. package/corpus/templates/design/app/components/design/multi-screen/iframe-targeting.ts +24 -0
  170. package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -0
  171. package/corpus/templates/design/app/components/design/types.ts +29 -0
  172. package/corpus/templates/design/app/components/layout/Layout.tsx +7 -4
  173. package/corpus/templates/design/app/hooks/use-navigation-state.ts +3 -0
  174. package/corpus/templates/design/app/i18n-data.ts +153 -46
  175. package/corpus/templates/design/app/i18n-responsive-interact.ts +12 -12
  176. package/corpus/templates/design/app/lib/design-editor-route.ts +23 -0
  177. package/corpus/templates/design/app/pages/VisualEdit.tsx +19 -6
  178. package/corpus/templates/design/app/pages/design-editor/action-error.ts +19 -0
  179. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +29 -0
  180. package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +6 -0
  181. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +277 -15
  182. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +75 -9
  183. package/corpus/templates/design/app/pages/design-editor/layer-state-scope.ts +28 -0
  184. package/corpus/templates/design/app/pages/design-editor/live-screen-layer-drop.ts +41 -0
  185. package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +496 -41
  186. package/corpus/templates/design/app/pages/design-editor/pending-live-edit-unload-guard.ts +27 -0
  187. package/corpus/templates/design/app/pages/design-editor/pending-structure-verification.ts +10 -0
  188. package/corpus/templates/design/app/pages/design-editor/react-semantic-handoff.ts +168 -9
  189. package/corpus/templates/design/app/pages/design-editor/responsive-interact.ts +41 -3
  190. package/corpus/templates/design/app/pages/design-editor/screen-command-utils.ts +5 -0
  191. package/corpus/templates/design/app/pages/design-editor/selection-state.ts +42 -13
  192. package/corpus/templates/design/app/pages/design-editor/source-location.ts +180 -0
  193. package/corpus/templates/design/app/pages/design-editor/tool-state.ts +17 -0
  194. package/corpus/templates/design/app/public-routes.ts +1 -0
  195. package/corpus/templates/design/app/routes/visual-edit.$id.tsx +15 -0
  196. package/corpus/templates/design/changelog/2026-06-29-screen-overview-is-easier-to-find-and-named-screens-open-dir.md +1 -1
  197. package/corpus/templates/design/changelog/2026-07-28-deleting-a-selected-element-now-removes-it-from-the-live-pre.md +6 -0
  198. package/corpus/templates/design/changelog/2026-07-28-deleting-an-element-on-a-connected-localhost-screen-now-queu.md +6 -0
  199. package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-shows-a-responsive-device-preview-with-pre.md +6 -0
  200. package/corpus/templates/design/changelog/2026-07-28-layer-hide-and-lock-now-apply-to-the-live-preview-instead-of.md +6 -0
  201. package/corpus/templates/design/changelog/2026-07-28-layers-panel-selections-on-a-connected-localhost-screen-can-.md +6 -0
  202. package/corpus/templates/design/changelog/2026-07-28-locked-layers-now-show-a-subtle-dashed-outline-in-the-live-p.md +6 -0
  203. package/corpus/templates/design/changelog/2026-07-28-the-apply-design-updates-button-now-counts-pending-live-text.md +6 -0
  204. package/corpus/templates/design/changelog/2026-07-28-the-design-canvas-no-longer-stalls-on-a-render-loop-while-a-.md +6 -0
  205. package/corpus/templates/design/changelog/2026-07-28-visual-edit-on-a-local-dev-server-no-longer-requires-signing.md +6 -0
  206. package/corpus/templates/design/changelog/2026-07-28-visual-edits-on-a-react-19-app-no-longer-report-a-source-lin.md +6 -0
  207. package/corpus/templates/design/changelog/2026-07-29-an-edit-that-cannot-be-written-to-source-now-names-the-reaso.md +6 -0
  208. package/corpus/templates/design/changelog/2026-07-29-applying-a-primitive-dropped-onto-a-connected-localhost-scre.md +6 -0
  209. package/corpus/templates/design/changelog/2026-07-29-changing-a-style-in-the-inspector-now-updates-a-connected-lo.md +6 -0
  210. package/corpus/templates/design/changelog/2026-07-29-choosing-edit-or-annotate-from-a-focused-screen-now-returns-.md +6 -0
  211. package/corpus/templates/design/changelog/2026-07-29-concurrent-source-edits-now-return-a-clear-conflict-response.md +6 -0
  212. package/corpus/templates/design/changelog/2026-07-29-creating-a-component-from-an-element-that-repeats-in-the-sou.md +6 -0
  213. package/corpus/templates/design/changelog/2026-07-29-deleting-an-element-you-just-dropped-onto-a-live-screen-no-l.md +6 -0
  214. package/corpus/templates/design/changelog/2026-07-29-dragging-a-layer-across-screens-no-longer-dies-when-the-poin.md +6 -0
  215. package/corpus/templates/design/changelog/2026-07-29-dragging-an-element-from-a-stored-screen-into-a-live-localho.md +6 -0
  216. package/corpus/templates/design/changelog/2026-07-29-drawing-a-box-on-the-canvas-and-dragging-it-into-a-connected.md +6 -0
  217. package/corpus/templates/design/changelog/2026-07-29-fixed-a-loading-screen-flicker-when-reopening-designs-with-a.md +6 -0
  218. package/corpus/templates/design/changelog/2026-07-29-interact-mode-has-edit-and-annotate-buttons-again-so-you-can.md +6 -0
  219. package/corpus/templates/design/changelog/2026-07-29-layer-groups-can-be-dropped-onto-live-localhost-screens.md +6 -0
  220. package/corpus/templates/design/changelog/2026-07-29-localhost-source-errors-now-say-what-actually-went-wrong-whi.md +6 -0
  221. package/corpus/templates/design/changelog/2026-07-29-opening-or-refreshing-a-live-localhost-screen-in-single-scre.md +6 -0
  222. package/corpus/templates/design/changelog/2026-07-29-redo-after-undoing-a-drop-onto-a-live-screen-puts-the-elemen.md +6 -0
  223. package/corpus/templates/design/changelog/2026-07-29-shapes-can-be-drawn-directly-onto-live-localhost-screens.md +6 -0
  224. package/corpus/templates/design/changelog/2026-07-29-shapes-drawn-on-the-canvas-board-now-appear-immediately-inst.md +6 -0
  225. package/corpus/templates/design/changelog/2026-07-29-style-edits-on-a-running-localhost-screen-now-preview-live-a.md +6 -0
  226. package/corpus/templates/design/changelog/2026-07-29-the-apply-design-updates-control-now-appears-as-a-clean-conn.md +6 -0
  227. package/corpus/templates/design/changelog/2026-07-29-visual-edits-on-a-mapped-component-instance-now-tell-the-age.md +6 -0
  228. package/corpus/templates/design/server/lib/design-data-access.ts +21 -7
  229. package/corpus/templates/design/server/lib/localhost-connection.ts +240 -0
  230. package/corpus/templates/design/server/routes/[...page].get.ts +2 -5
  231. package/corpus/templates/design/server/source-workspace.ts +2 -0
  232. package/corpus/templates/design/shared/code-layer.ts +43 -0
  233. package/corpus/templates/design/shared/html-content.ts +26 -0
  234. package/corpus/templates/design/shared/html-integrity.ts +21 -1
  235. package/corpus/templates/design/shared/local-jsx-visual-edit.ts +15 -0
  236. package/corpus/templates/design/shared/source-mode.ts +76 -0
  237. package/corpus/templates/dispatch/changelog/2026-07-29-workspace-members-without-admin-access-now-see-a-clear-permi.md +6 -0
  238. package/corpus/templates/dispatch/server/lib/usage-metrics.ts +2 -1
  239. package/corpus/templates/plan/app/lib/plan-annotation-runtime.ts +3 -4
  240. package/corpus/templates/plan/server/routes/[...page].get.ts +2 -5
  241. package/corpus/templates/slides/actions/patch-deck.ts +29 -17
  242. package/corpus/toolkit/CHANGELOG.md +6 -0
  243. package/corpus/toolkit/package.json +1 -1
  244. package/corpus/toolkit/src/composer/ComposerPlusMenu.tsx +3 -2
  245. package/dist/action-ui.d.ts +1 -0
  246. package/dist/action-ui.d.ts.map +1 -1
  247. package/dist/action-ui.js +1 -0
  248. package/dist/action-ui.js.map +1 -1
  249. package/dist/action.d.ts +5 -1
  250. package/dist/action.d.ts.map +1 -1
  251. package/dist/action.js.map +1 -1
  252. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  253. package/dist/agent/engine/ai-sdk-engine.js +13 -5
  254. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  255. package/dist/agent/harness/runner.d.ts.map +1 -1
  256. package/dist/agent/harness/runner.js +5 -0
  257. package/dist/agent/harness/runner.js.map +1 -1
  258. package/dist/agent/production-agent.d.ts +16 -0
  259. package/dist/agent/production-agent.d.ts.map +1 -1
  260. package/dist/agent/production-agent.js +18 -1
  261. package/dist/agent/production-agent.js.map +1 -1
  262. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  263. package/dist/agent/run-loop-with-resume.js +6 -0
  264. package/dist/agent/run-loop-with-resume.js.map +1 -1
  265. package/dist/agent/run-manager.d.ts +14 -0
  266. package/dist/agent/run-manager.d.ts.map +1 -1
  267. package/dist/agent/run-manager.js +91 -1
  268. package/dist/agent/run-manager.js.map +1 -1
  269. package/dist/agent/thread-data-builder.d.ts +3 -0
  270. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  271. package/dist/agent/thread-data-builder.js +35 -3
  272. package/dist/agent/thread-data-builder.js.map +1 -1
  273. package/dist/agent/types.d.ts +2 -0
  274. package/dist/agent/types.d.ts.map +1 -1
  275. package/dist/agent/types.js.map +1 -1
  276. package/dist/chat-threads/store.d.ts.map +1 -1
  277. package/dist/chat-threads/store.js +4 -6
  278. package/dist/chat-threads/store.js.map +1 -1
  279. package/dist/cli/create.d.ts +66 -6
  280. package/dist/cli/create.d.ts.map +1 -1
  281. package/dist/cli/create.js +765 -66
  282. package/dist/cli/create.js.map +1 -1
  283. package/dist/cli/design-connect.d.ts.map +1 -1
  284. package/dist/cli/design-connect.js +2 -7
  285. package/dist/cli/design-connect.js.map +1 -1
  286. package/dist/cli/index.js +5 -3
  287. package/dist/cli/index.js.map +1 -1
  288. package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
  289. package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
  290. package/dist/cli/skills-content/design-visual-edit-skill.js +83 -47
  291. package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
  292. package/dist/client/AssistantChat.d.ts.map +1 -1
  293. package/dist/client/AssistantChat.js +16 -9
  294. package/dist/client/AssistantChat.js.map +1 -1
  295. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  296. package/dist/client/agent-chat-adapter.js +21 -0
  297. package/dist/client/agent-chat-adapter.js.map +1 -1
  298. package/dist/client/blocks/library/wireframe-kit.d.ts +2 -0
  299. package/dist/client/blocks/library/wireframe-kit.d.ts.map +1 -1
  300. package/dist/client/blocks/library/wireframe-kit.js +8 -2
  301. package/dist/client/blocks/library/wireframe-kit.js.map +1 -1
  302. package/dist/client/chat/index.d.ts +1 -1
  303. package/dist/client/chat/index.d.ts.map +1 -1
  304. package/dist/client/chat/index.js +1 -1
  305. package/dist/client/chat/index.js.map +1 -1
  306. package/dist/client/chat/message-components.d.ts +17 -0
  307. package/dist/client/chat/message-components.d.ts.map +1 -1
  308. package/dist/client/chat/message-components.js +24 -2
  309. package/dist/client/chat/message-components.js.map +1 -1
  310. package/dist/client/chat/run-recovery.d.ts +6 -0
  311. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  312. package/dist/client/chat/run-recovery.js +13 -3
  313. package/dist/client/chat/run-recovery.js.map +1 -1
  314. package/dist/client/chat/widgets/DataTableWidget.d.ts.map +1 -1
  315. package/dist/client/chat/widgets/DataTableWidget.js +2 -3
  316. package/dist/client/chat/widgets/DataTableWidget.js.map +1 -1
  317. package/dist/client/chat/widgets/WorkspaceFileWidget.d.ts +5 -0
  318. package/dist/client/chat/widgets/WorkspaceFileWidget.d.ts.map +1 -0
  319. package/dist/client/chat/widgets/WorkspaceFileWidget.js +34 -0
  320. package/dist/client/chat/widgets/WorkspaceFileWidget.js.map +1 -0
  321. package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
  322. package/dist/client/chat/widgets/builtin-tool-renderers.js +13 -1
  323. package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
  324. package/dist/client/chat/widgets/workspace-file-result.d.ts +12 -0
  325. package/dist/client/chat/widgets/workspace-file-result.d.ts.map +1 -0
  326. package/dist/client/chat/widgets/workspace-file-result.js +34 -0
  327. package/dist/client/chat/widgets/workspace-file-result.js.map +1 -0
  328. package/dist/client/embed-auth.d.ts.map +1 -1
  329. package/dist/client/embed-auth.js +2 -1
  330. package/dist/client/embed-auth.js.map +1 -1
  331. package/dist/client/org/InvitationBanner.d.ts +5 -2
  332. package/dist/client/org/InvitationBanner.d.ts.map +1 -1
  333. package/dist/client/org/InvitationBanner.js +9 -2
  334. package/dist/client/org/InvitationBanner.js.map +1 -1
  335. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  336. package/dist/client/org/OrgSwitcher.js +3 -2
  337. package/dist/client/org/OrgSwitcher.js.map +1 -1
  338. package/dist/client/org/TeamPage.d.ts.map +1 -1
  339. package/dist/client/org/TeamPage.js +27 -3
  340. package/dist/client/org/TeamPage.js.map +1 -1
  341. package/dist/client/org/WorkspaceNotice.d.ts +18 -0
  342. package/dist/client/org/WorkspaceNotice.d.ts.map +1 -0
  343. package/dist/client/org/WorkspaceNotice.js +56 -0
  344. package/dist/client/org/WorkspaceNotice.js.map +1 -0
  345. package/dist/client/org/hooks.d.ts +1 -0
  346. package/dist/client/org/hooks.d.ts.map +1 -1
  347. package/dist/client/org/hooks.js +12 -0
  348. package/dist/client/org/hooks.js.map +1 -1
  349. package/dist/client/org/index.d.ts +2 -1
  350. package/dist/client/org/index.d.ts.map +1 -1
  351. package/dist/client/org/index.js +2 -1
  352. package/dist/client/org/index.js.map +1 -1
  353. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  354. package/dist/client/resources/McpIntegrationDialog.js +8 -12
  355. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  356. package/dist/client/resources/ResourcesPanel.d.ts +3 -0
  357. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  358. package/dist/client/resources/ResourcesPanel.js +49 -20
  359. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  360. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  361. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  362. package/dist/client/resources/mcp-integration-catalog.js +3 -0
  363. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  364. package/dist/client/resources/use-resources.d.ts +1 -0
  365. package/dist/client/resources/use-resources.d.ts.map +1 -1
  366. package/dist/client/resources/use-resources.js +3 -0
  367. package/dist/client/resources/use-resources.js.map +1 -1
  368. package/dist/client/use-action.d.ts +3 -1
  369. package/dist/client/use-action.d.ts.map +1 -1
  370. package/dist/client/use-action.js +3 -1
  371. package/dist/client/use-action.js.map +1 -1
  372. package/dist/client/widgets/index.d.ts +1 -1
  373. package/dist/client/widgets/index.d.ts.map +1 -1
  374. package/dist/client/widgets/index.js +1 -1
  375. package/dist/client/widgets/index.js.map +1 -1
  376. package/dist/coding-tools/run-code.js +2 -1
  377. package/dist/coding-tools/run-code.js.map +1 -1
  378. package/dist/collab/awareness.d.ts +2 -2
  379. package/dist/collab/awareness.d.ts.map +1 -1
  380. package/dist/db/client.d.ts +1 -0
  381. package/dist/db/client.d.ts.map +1 -1
  382. package/dist/db/client.js +24 -3
  383. package/dist/db/client.js.map +1 -1
  384. package/dist/deploy/build.d.ts.map +1 -1
  385. package/dist/deploy/build.js +25 -3
  386. package/dist/deploy/build.js.map +1 -1
  387. package/dist/eject/remote-mcp-presets.js +1 -1
  388. package/dist/eject/remote-mcp-presets.js.map +1 -1
  389. package/dist/index.browser.d.ts +1 -1
  390. package/dist/index.browser.d.ts.map +1 -1
  391. package/dist/index.browser.js +1 -1
  392. package/dist/index.browser.js.map +1 -1
  393. package/dist/index.d.ts +1 -1
  394. package/dist/index.d.ts.map +1 -1
  395. package/dist/index.js +1 -1
  396. package/dist/index.js.map +1 -1
  397. package/dist/integrations/google-docs-poller.d.ts.map +1 -1
  398. package/dist/integrations/google-docs-poller.js +4 -1
  399. package/dist/integrations/google-docs-poller.js.map +1 -1
  400. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  401. package/dist/integrations/webhook-handler.js +23 -11
  402. package/dist/integrations/webhook-handler.js.map +1 -1
  403. package/dist/jobs/scheduler.js +4 -0
  404. package/dist/jobs/scheduler.js.map +1 -1
  405. package/dist/localization/default-messages.d.ts +3 -2
  406. package/dist/localization/default-messages.d.ts.map +1 -1
  407. package/dist/localization/default-messages.js +3 -2
  408. package/dist/localization/default-messages.js.map +1 -1
  409. package/dist/notifications/routes.d.ts +1 -1
  410. package/dist/observability/routes.d.ts +3 -3
  411. package/dist/observability/traces.d.ts.map +1 -1
  412. package/dist/observability/traces.js +27 -7
  413. package/dist/observability/traces.js.map +1 -1
  414. package/dist/org/handlers.d.ts +15 -0
  415. package/dist/org/handlers.d.ts.map +1 -1
  416. package/dist/org/handlers.js +45 -1
  417. package/dist/org/handlers.js.map +1 -1
  418. package/dist/org/migrations.d.ts.map +1 -1
  419. package/dist/org/migrations.js +4 -0
  420. package/dist/org/migrations.js.map +1 -1
  421. package/dist/org/plugin.d.ts +1 -0
  422. package/dist/org/plugin.d.ts.map +1 -1
  423. package/dist/org/plugin.js +10 -1
  424. package/dist/org/plugin.js.map +1 -1
  425. package/dist/org/schema.d.ts +19 -0
  426. package/dist/org/schema.d.ts.map +1 -1
  427. package/dist/org/schema.js +1 -0
  428. package/dist/org/schema.js.map +1 -1
  429. package/dist/org/types.d.ts +8 -0
  430. package/dist/org/types.d.ts.map +1 -1
  431. package/dist/org/types.js.map +1 -1
  432. package/dist/org/workspace-url.d.ts +32 -0
  433. package/dist/org/workspace-url.d.ts.map +1 -0
  434. package/dist/org/workspace-url.js +63 -0
  435. package/dist/org/workspace-url.js.map +1 -0
  436. package/dist/progress/routes.d.ts +1 -1
  437. package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
  438. package/dist/provider-api/actions/provider-api.d.ts +7 -7
  439. package/dist/resources/handlers.d.ts +2 -3
  440. package/dist/resources/handlers.d.ts.map +1 -1
  441. package/dist/resources/handlers.js +25 -5
  442. package/dist/resources/handlers.js.map +1 -1
  443. package/dist/scripts/runner.d.ts +17 -0
  444. package/dist/scripts/runner.d.ts.map +1 -1
  445. package/dist/scripts/runner.js +130 -5
  446. package/dist/scripts/runner.js.map +1 -1
  447. package/dist/server/action-routes.d.ts.map +1 -1
  448. package/dist/server/action-routes.js +24 -2
  449. package/dist/server/action-routes.js.map +1 -1
  450. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  451. package/dist/server/agent-chat-plugin.js +26 -1
  452. package/dist/server/agent-chat-plugin.js.map +1 -1
  453. package/dist/server/agent-teams.d.ts.map +1 -1
  454. package/dist/server/agent-teams.js +10 -1
  455. package/dist/server/agent-teams.js.map +1 -1
  456. package/dist/server/auth.d.ts +22 -0
  457. package/dist/server/auth.d.ts.map +1 -1
  458. package/dist/server/auth.js +33 -7
  459. package/dist/server/auth.js.map +1 -1
  460. package/dist/server/embed-route.d.ts.map +1 -1
  461. package/dist/server/embed-route.js +6 -1
  462. package/dist/server/embed-route.js.map +1 -1
  463. package/dist/server/embed-session.d.ts +7 -0
  464. package/dist/server/embed-session.d.ts.map +1 -1
  465. package/dist/server/embed-session.js +46 -4
  466. package/dist/server/embed-session.js.map +1 -1
  467. package/dist/server/open-route.d.ts.map +1 -1
  468. package/dist/server/open-route.js +17 -7
  469. package/dist/server/open-route.js.map +1 -1
  470. package/dist/server/prompts/framework-core-compact.js +1 -1
  471. package/dist/server/prompts/framework-core-compact.js.map +1 -1
  472. package/dist/server/prompts/framework-core.d.ts.map +1 -1
  473. package/dist/server/prompts/framework-core.js +1 -0
  474. package/dist/server/prompts/framework-core.js.map +1 -1
  475. package/dist/server/realtime-token.d.ts +1 -1
  476. package/dist/server/request-context.d.ts +26 -0
  477. package/dist/server/request-context.d.ts.map +1 -1
  478. package/dist/server/request-context.js +18 -1
  479. package/dist/server/request-context.js.map +1 -1
  480. package/dist/server/transcribe-voice.d.ts +1 -1
  481. package/dist/shared/embed-auth.d.ts +1 -0
  482. package/dist/shared/embed-auth.d.ts.map +1 -1
  483. package/dist/shared/embed-auth.js +1 -0
  484. package/dist/shared/embed-auth.js.map +1 -1
  485. package/dist/shared/html-document.d.ts +12 -0
  486. package/dist/shared/html-document.d.ts.map +1 -0
  487. package/dist/shared/html-document.js +92 -0
  488. package/dist/shared/html-document.js.map +1 -0
  489. package/dist/shared/index.d.ts +1 -0
  490. package/dist/shared/index.d.ts.map +1 -1
  491. package/dist/shared/index.js +1 -0
  492. package/dist/shared/index.js.map +1 -1
  493. package/dist/sharing/access.d.ts +1 -0
  494. package/dist/sharing/access.d.ts.map +1 -1
  495. package/dist/sharing/access.js +8 -2
  496. package/dist/sharing/access.js.map +1 -1
  497. package/dist/sharing/registry.d.ts +3 -0
  498. package/dist/sharing/registry.d.ts.map +1 -1
  499. package/dist/sharing/registry.js.map +1 -1
  500. package/dist/workspace-files/actions.d.ts +28 -0
  501. package/dist/workspace-files/actions.d.ts.map +1 -0
  502. package/dist/workspace-files/actions.js +75 -0
  503. package/dist/workspace-files/actions.js.map +1 -0
  504. package/dist/workspace-files/tool.d.ts.map +1 -1
  505. package/dist/workspace-files/tool.js +4 -0
  506. package/dist/workspace-files/tool.js.map +1 -1
  507. package/docs/content/cloneable-saas.mdx +114 -0
  508. package/docs/content/creating-templates.mdx +28 -2
  509. package/docs/content/syncing-template-changes.mdx +7 -0
  510. package/docs/content/template-clips-developers.mdx +12 -5
  511. package/docs/content/template-dispatch-developers.mdx +1 -1
  512. package/docs/content/template-dispatch.mdx +1 -1
  513. package/package.json +2 -2
  514. package/src/action-ui.ts +1 -0
  515. package/src/action.ts +5 -1
  516. package/src/agent/engine/ai-sdk-engine.ts +15 -5
  517. package/src/agent/harness/runner.ts +5 -0
  518. package/src/agent/production-agent.ts +33 -0
  519. package/src/agent/run-loop-with-resume.ts +5 -0
  520. package/src/agent/run-manager.ts +126 -1
  521. package/src/agent/thread-data-builder.ts +47 -2
  522. package/src/agent/types.ts +2 -0
  523. package/src/chat-threads/store.ts +4 -5
  524. package/src/cli/create.ts +1139 -65
  525. package/src/cli/design-connect.ts +3 -7
  526. package/src/cli/index.ts +5 -3
  527. package/src/cli/skills-content/design-visual-edit-skill.ts +83 -47
  528. package/src/client/AssistantChat.tsx +27 -16
  529. package/src/client/agent-chat-adapter.ts +24 -0
  530. package/src/client/blocks/library/wireframe-kit.tsx +17 -2
  531. package/src/client/chat/index.ts +1 -0
  532. package/src/client/chat/message-components.tsx +104 -1
  533. package/src/client/chat/run-recovery.tsx +15 -3
  534. package/src/client/chat/widgets/DataTableWidget.tsx +10 -29
  535. package/src/client/chat/widgets/WorkspaceFileWidget.tsx +71 -0
  536. package/src/client/chat/widgets/builtin-tool-renderers.tsx +22 -0
  537. package/src/client/chat/widgets/workspace-file-result.ts +49 -0
  538. package/src/client/embed-auth.ts +2 -0
  539. package/src/client/org/InvitationBanner.tsx +14 -1
  540. package/src/client/org/OrgSwitcher.tsx +23 -0
  541. package/src/client/org/TeamPage.tsx +130 -0
  542. package/src/client/org/WorkspaceNotice.tsx +85 -0
  543. package/src/client/org/hooks.ts +14 -0
  544. package/src/client/org/index.ts +2 -0
  545. package/src/client/resources/McpIntegrationDialog.tsx +27 -40
  546. package/src/client/resources/ResourcesPanel.tsx +134 -51
  547. package/src/client/resources/mcp-integration-catalog.ts +7 -0
  548. package/src/client/resources/use-resources.ts +6 -0
  549. package/src/client/use-action.ts +3 -1
  550. package/src/client/widgets/index.ts +1 -0
  551. package/src/coding-tools/run-code.ts +2 -1
  552. package/src/db/client.ts +28 -4
  553. package/src/deploy/build.ts +31 -3
  554. package/src/eject/remote-mcp-presets.ts +1 -1
  555. package/src/index.browser.ts +1 -0
  556. package/src/index.ts +1 -0
  557. package/src/integrations/google-docs-poller.ts +3 -0
  558. package/src/integrations/webhook-handler.ts +28 -11
  559. package/src/jobs/scheduler.ts +4 -0
  560. package/src/localization/default-messages.ts +3 -2
  561. package/src/observability/traces.ts +48 -12
  562. package/src/org/handlers.ts +52 -1
  563. package/src/org/migrations.ts +4 -0
  564. package/src/org/plugin.ts +14 -0
  565. package/src/org/schema.ts +1 -0
  566. package/src/org/types.ts +8 -0
  567. package/src/org/workspace-url.ts +74 -0
  568. package/src/resources/handlers.ts +35 -5
  569. package/src/scripts/runner.ts +183 -5
  570. package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +2 -1
  571. package/src/server/action-routes.ts +32 -2
  572. package/src/server/agent-chat-plugin.ts +29 -0
  573. package/src/server/agent-teams.ts +10 -1
  574. package/src/server/auth.ts +33 -7
  575. package/src/server/embed-route.ts +9 -0
  576. package/src/server/embed-session.ts +62 -3
  577. package/src/server/open-route.ts +20 -6
  578. package/src/server/prompts/framework-core-compact.ts +1 -1
  579. package/src/server/prompts/framework-core.ts +1 -0
  580. package/src/server/request-context.ts +36 -1
  581. package/src/shared/embed-auth.ts +1 -0
  582. package/src/shared/html-document.ts +115 -0
  583. package/src/shared/index.ts +1 -0
  584. package/src/sharing/access.ts +8 -1
  585. package/src/sharing/registry.ts +11 -2
  586. package/src/workspace-files/actions.ts +100 -0
  587. package/src/workspace-files/tool.ts +4 -0
  588. package/corpus/templates/design/changelog/2026-07-28-interact-mode-can-preview-designs-in-responsive-device-sizes.md +0 -6
  589. package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-opens-a-full-screen-responsive-preview-wit.md +0 -6
@@ -1,19 +1,8 @@
1
- import {
2
- IconDots,
3
- IconDownload,
4
- IconExternalLink,
5
- IconTable,
6
- } from "@tabler/icons-react";
1
+ import { IconDownload, IconExternalLink, IconTable } from "@tabler/icons-react";
7
2
 
8
3
  import { requestAgentSidebarOpen } from "../../agent-sidebar-state.js";
9
4
  import { appPath } from "../../api-path.js";
10
5
  import { startAgentChatViewTransition } from "../../chat-view-transition.js";
11
- import {
12
- DropdownMenu,
13
- DropdownMenuContent,
14
- DropdownMenuItem,
15
- DropdownMenuTrigger,
16
- } from "../../components/ui/dropdown-menu.js";
17
6
  import { downloadFile, toCSVTable } from "../../db-admin/export-utils.js";
18
7
  import { cn } from "../../utils.js";
19
8
  import type { DataTableWidget as DataTableWidgetData } from "./data-widget-types.js";
@@ -165,23 +154,15 @@ export function DataTableWidget({
165
154
  <IconExternalLink className="h-3 w-3" />
166
155
  </a>
167
156
  ) : null}
168
- <DropdownMenu>
169
- <DropdownMenuTrigger asChild>
170
- <button
171
- type="button"
172
- aria-label="Data table options"
173
- className="inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
174
- >
175
- <IconDots className="h-3.5 w-3.5" />
176
- </button>
177
- </DropdownMenuTrigger>
178
- <DropdownMenuContent align="end" className="w-44">
179
- <DropdownMenuItem onSelect={exportCsv} disabled={!canExportCsv}>
180
- <IconDownload className="mr-2 h-3.5 w-3.5" />
181
- Download CSV
182
- </DropdownMenuItem>
183
- </DropdownMenuContent>
184
- </DropdownMenu>
157
+ <button
158
+ type="button"
159
+ onClick={exportCsv}
160
+ disabled={!canExportCsv}
161
+ className="inline-flex shrink-0 items-center gap-1 rounded-md bg-primary px-2 py-1 text-[11px] font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:pointer-events-none disabled:opacity-50"
162
+ >
163
+ <IconDownload className="h-3 w-3" />
164
+ Download CSV
165
+ </button>
185
166
  </div>
186
167
  <div className="max-h-[360px] overflow-auto">
187
168
  <table className="w-full min-w-[420px] border-collapse text-xs">
@@ -0,0 +1,71 @@
1
+ import {
2
+ IconDownload,
3
+ IconFile,
4
+ IconFileSpreadsheet,
5
+ IconFileText,
6
+ } from "@tabler/icons-react";
7
+
8
+ import { useFormatters, useT } from "../../i18n.js";
9
+ import { resourceDownloadUrl } from "../../resources/use-resources.js";
10
+ import type { WorkspaceFileResult } from "./workspace-file-result.js";
11
+
12
+ function formatFileSize(
13
+ sizeBytes: number,
14
+ formatNumber: (value: number, options?: Intl.NumberFormatOptions) => string,
15
+ ): string {
16
+ if (sizeBytes < 1024) return `${formatNumber(sizeBytes)} B`;
17
+ if (sizeBytes < 1024 * 1024) {
18
+ return `${formatNumber(sizeBytes / 1024, { maximumFractionDigits: 1 })} KB`;
19
+ }
20
+ return `${formatNumber(sizeBytes / 1024 / 1024, {
21
+ maximumFractionDigits: 1,
22
+ })} MB`;
23
+ }
24
+
25
+ function fileIcon(contentType: string) {
26
+ if (
27
+ contentType === "text/csv" ||
28
+ contentType.includes("spreadsheet") ||
29
+ contentType.includes("excel")
30
+ ) {
31
+ return IconFileSpreadsheet;
32
+ }
33
+ if (contentType.startsWith("text/") || contentType === "application/json") {
34
+ return IconFileText;
35
+ }
36
+ return IconFile;
37
+ }
38
+
39
+ export function WorkspaceFileWidget({
40
+ result,
41
+ }: {
42
+ result: WorkspaceFileResult;
43
+ }) {
44
+ const t = useT();
45
+ const { formatNumber } = useFormatters();
46
+ const { file } = result;
47
+ const FileIcon = fileIcon(file.contentType);
48
+ const href = resourceDownloadUrl(file.resourceId);
49
+
50
+ return (
51
+ <div className="flex items-center gap-3">
52
+ <div className="flex size-10 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground">
53
+ <FileIcon className="size-5" aria-hidden="true" />
54
+ </div>
55
+ <div className="min-w-0 flex-1">
56
+ <div className="truncate text-sm font-medium">{file.name}</div>
57
+ <div className="truncate text-xs text-muted-foreground">
58
+ {formatFileSize(file.sizeBytes, formatNumber)} · {file.path}
59
+ </div>
60
+ </div>
61
+ <a
62
+ href={href}
63
+ download={file.name}
64
+ className="inline-flex shrink-0 items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground no-underline transition-colors hover:bg-primary/90 hover:no-underline"
65
+ >
66
+ <IconDownload className="size-3.5" aria-hidden="true" />
67
+ {t("workspaceFile.download")}
68
+ </a>
69
+ </div>
70
+ );
71
+ }
@@ -6,6 +6,7 @@ import {
6
6
  ACTION_CHAT_UI_DATA_TABLE_RENDERER,
7
7
  ACTION_CHAT_UI_DATA_WIDGET_RENDERER,
8
8
  ACTION_CHAT_UI_INLINE_EXTENSION_RENDERER,
9
+ ACTION_CHAT_UI_WORKSPACE_FILE_RENDERER,
9
10
  } from "../../../action-ui.js";
10
11
  import {
11
12
  registerReservedActionChatRenderer,
@@ -22,6 +23,7 @@ import {
22
23
  type DataWidgetResult,
23
24
  } from "./data-widget-types.js";
24
25
  import { normalizeInlineExtensionToolResult } from "./inline-extension-result.js";
26
+ import { normalizeWorkspaceFileResult } from "./workspace-file-result.js";
25
27
 
26
28
  const LazyDataChartWidget = lazy(() =>
27
29
  import("./DataChartWidget.js").then((module) => ({
@@ -43,6 +45,11 @@ const LazyInlineExtensionWidget = lazy(() =>
43
45
  default: module.InlineExtensionWidget,
44
46
  })),
45
47
  );
48
+ const LazyWorkspaceFileWidget = lazy(() =>
49
+ import("./WorkspaceFileWidget.js").then((module) => ({
50
+ default: module.WorkspaceFileWidget,
51
+ })),
52
+ );
46
53
 
47
54
  function isRecord(value: unknown): value is Record<string, unknown> {
48
55
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -149,6 +156,15 @@ const BuiltinInlineExtensionRenderer: ToolRendererComponent = ({ context }) =>
149
156
  </Suspense>
150
157
  ) : null;
151
158
 
159
+ const BuiltinWorkspaceFileRenderer: ToolRendererComponent = ({ context }) => {
160
+ const result = normalizeWorkspaceFileResult(context.resultJson);
161
+ return result ? (
162
+ <Suspense fallback={<BuiltinToolRendererSkeleton framed={false} />}>
163
+ <LazyWorkspaceFileWidget result={result} />
164
+ </Suspense>
165
+ ) : null;
166
+ };
167
+
152
168
  export function isBuiltinDataWidgetActionRenderer(
153
169
  context: ToolRendererContext,
154
170
  ): boolean {
@@ -170,6 +186,12 @@ export function resolveBuiltinActionChatRenderer(
170
186
  ) {
171
187
  return BuiltinInlineExtensionRenderer;
172
188
  }
189
+ if (
190
+ context.chatUI?.renderer === ACTION_CHAT_UI_WORKSPACE_FILE_RENDERER &&
191
+ normalizeWorkspaceFileResult(context.resultJson)
192
+ ) {
193
+ return BuiltinWorkspaceFileRenderer;
194
+ }
173
195
  if (
174
196
  isBuiltinDataWidgetActionRenderer(context) &&
175
197
  normalizeActionDataWidgetResult(context)
@@ -0,0 +1,49 @@
1
+ export interface WorkspaceFileResult {
2
+ file: {
3
+ resourceId: string;
4
+ path: string;
5
+ name: string;
6
+ contentType: string;
7
+ sizeBytes: number;
8
+ updatedAt?: string;
9
+ };
10
+ }
11
+
12
+ function isRecord(value: unknown): value is Record<string, unknown> {
13
+ return !!value && typeof value === "object" && !Array.isArray(value);
14
+ }
15
+
16
+ export function normalizeWorkspaceFileResult(
17
+ value: unknown,
18
+ ): WorkspaceFileResult | null {
19
+ if (!isRecord(value) || !isRecord(value.file)) return null;
20
+ const file = value.file;
21
+ if (
22
+ typeof file.resourceId !== "string" ||
23
+ !file.resourceId ||
24
+ typeof file.path !== "string" ||
25
+ !file.path ||
26
+ typeof file.name !== "string" ||
27
+ !file.name ||
28
+ typeof file.contentType !== "string" ||
29
+ !file.contentType ||
30
+ typeof file.sizeBytes !== "number" ||
31
+ !Number.isFinite(file.sizeBytes) ||
32
+ file.sizeBytes < 0
33
+ ) {
34
+ return null;
35
+ }
36
+
37
+ return {
38
+ file: {
39
+ resourceId: file.resourceId,
40
+ path: file.path,
41
+ name: file.name,
42
+ contentType: file.contentType,
43
+ sizeBytes: file.sizeBytes,
44
+ ...(typeof file.updatedAt === "string"
45
+ ? { updatedAt: file.updatedAt }
46
+ : {}),
47
+ },
48
+ };
49
+ }
@@ -2,6 +2,7 @@ import {
2
2
  EMBED_MODE_QUERY_PARAM,
3
3
  EMBED_START_PATH,
4
4
  EMBED_TARGET_HEADER,
5
+ EMBED_TARGET_QUERY_PARAM,
5
6
  EMBED_TOKEN_QUERY_PARAM,
6
7
  MCP_APP_CHAT_BRIDGE_QUERY_PARAM,
7
8
  } from "../shared/embed-auth.js";
@@ -463,6 +464,7 @@ function withEmbedAuthHeaders(
463
464
  isAgentNativeRuntimePath(url.pathname)
464
465
  ) {
465
466
  url.searchParams.set(EMBED_TOKEN_QUERY_PARAM, token);
467
+ url.searchParams.set(EMBED_TARGET_QUERY_PARAM, currentEmbedTarget(win));
466
468
  return [url.toString(), init];
467
469
  }
468
470
 
@@ -2,13 +2,17 @@ import { IconLoader2 } from "@tabler/icons-react";
2
2
  import { useState } from "react";
3
3
 
4
4
  import { useOrg, useAcceptInvitation, useJoinByDomain } from "./hooks.js";
5
+ import { WorkspaceNotice } from "./WorkspaceNotice.js";
5
6
 
6
7
  export interface InvitationBannerProps {
7
8
  className?: string;
8
9
  }
9
10
 
10
11
  /**
11
- * Top-of-app banner that surfaces:
12
+ * Top-of-app notice bar. Mounted in every template shell, so it owns the
13
+ * org-level notices a member needs before they can make sense of what they're
14
+ * looking at:
15
+ * - They're on the wrong deployment ({@link WorkspaceNotice}).
12
16
  * - Pending org invitations (one-click Accept).
13
17
  * - Domain-match orgs the user can auto-join because their email domain
14
18
  * matches `organizations.allowed_domain` (one-click Join). Lets a new
@@ -18,6 +22,15 @@ export interface InvitationBannerProps {
18
22
  * Renders nothing when there's nothing to surface.
19
23
  */
20
24
  export function InvitationBanner({ className }: InvitationBannerProps) {
25
+ return (
26
+ <>
27
+ <WorkspaceNotice className={className} />
28
+ <InvitationRows className={className} />
29
+ </>
30
+ );
31
+ }
32
+
33
+ function InvitationRows({ className }: InvitationBannerProps) {
21
34
  const { data: org } = useOrg();
22
35
  const acceptInvitation = useAcceptInvitation();
23
36
  const joinByDomain = useJoinByDomain();
@@ -12,6 +12,7 @@ import {
12
12
  IconChevronRight,
13
13
  IconClipboardList,
14
14
  IconCode,
15
+ IconExternalLink,
15
16
  IconFileText,
16
17
  IconKey,
17
18
  IconLayoutBoard,
@@ -41,6 +42,7 @@ import {
41
42
  import { useState } from "react";
42
43
  import { useNavigate } from "react-router";
43
44
 
45
+ import { shouldOfferWorkspace } from "../../org/workspace-url.js";
44
46
  import { agentNativePath } from "../api-path.js";
45
47
  import { useT } from "../i18n.js";
46
48
  import { useSession } from "../use-session.js";
@@ -426,6 +428,27 @@ export function OrgSwitcher({
426
428
  >
427
429
  {mode === "list" && (
428
430
  <>
431
+ {/* The org name alone is ambiguous: the same org exists on every
432
+ deployment a member has signed into, so the switcher reads
433
+ identically on all of them. The host is what tells them
434
+ which one they're actually looking at. */}
435
+ {typeof window !== "undefined" && (
436
+ <div className="px-2.5 pb-1.5 pt-1 text-[11px] text-muted-foreground">
437
+ <div className="truncate">{window.location.host}</div>
438
+ {shouldOfferWorkspace(
439
+ window.location.href,
440
+ org.workspaceUrl,
441
+ ) && (
442
+ <a
443
+ href={org.workspaceUrl ?? undefined}
444
+ className="mt-0.5 inline-flex items-center gap-1 text-foreground no-underline hover:underline"
445
+ >
446
+ <IconExternalLink className="h-3 w-3 shrink-0" />
447
+ Your workspace
448
+ </a>
449
+ )}
450
+ </div>
451
+ )}
429
452
  {!inOrg && (
430
453
  <div
431
454
  className="flex w-full items-center gap-2 px-2.5 py-1.5 text-xs text-muted-foreground"
@@ -46,6 +46,7 @@ import {
46
46
  IconAlertTriangle,
47
47
  IconUsersGroup,
48
48
  IconHelpCircle,
49
+ IconExternalLink,
49
50
  } from "@tabler/icons-react";
50
51
  import {
51
52
  forwardRef,
@@ -81,6 +82,7 @@ import {
81
82
  useDeleteOrg,
82
83
  useSwitchOrg,
83
84
  useSetOrgDomain,
85
+ useSetOrgWorkspaceUrl,
84
86
  useRevealA2ASecret,
85
87
  useSetA2ASecret,
86
88
  useSyncA2ASecret,
@@ -460,6 +462,8 @@ function MembersCard({ appRoles }: { appRoles?: AppRolesDescriptor }) {
460
462
  ownerEmail={org.email}
461
463
  />
462
464
 
465
+ <WorkspaceUrlSettingsSection workspaceUrl={org.workspaceUrl} />
466
+
463
467
  {isOwner && <A2ASecretSection isSet={Boolean(org.a2aSecretSet)} />}
464
468
  </div>
465
469
  )}
@@ -1477,6 +1481,132 @@ function DomainSettingsSection({
1477
1481
  );
1478
1482
  }
1479
1483
 
1484
+ function WorkspaceUrlSettingsSection({
1485
+ workspaceUrl,
1486
+ }: {
1487
+ workspaceUrl: string | null;
1488
+ }) {
1489
+ const setWorkspaceUrl = useSetOrgWorkspaceUrl();
1490
+ const [editing, setEditing] = useState(false);
1491
+ const [draft, setDraft] = useState(workspaceUrl ?? "");
1492
+
1493
+ function save() {
1494
+ const trimmed = draft.trim();
1495
+ if (trimmed === (workspaceUrl ?? "")) {
1496
+ setEditing(false);
1497
+ return;
1498
+ }
1499
+ setWorkspaceUrl.mutate(trimmed || null, {
1500
+ onSuccess: () => setEditing(false),
1501
+ });
1502
+ }
1503
+
1504
+ return (
1505
+ <div className="space-y-2 border-t border-border pt-3 first:border-t-0 first:pt-0">
1506
+ <div className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
1507
+ Your workspace
1508
+ </div>
1509
+ <p className="text-[11px] text-muted-foreground">
1510
+ If your team runs its own workspace, members who land on a different
1511
+ deployment — opening a template from the catalog, for instance — get
1512
+ pointed here instead of an app that looks empty.
1513
+ </p>
1514
+ {!editing ? (
1515
+ <div className="flex items-center gap-2">
1516
+ {workspaceUrl ? (
1517
+ <>
1518
+ <span className="inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm">
1519
+ <IconExternalLink className="h-3.5 w-3.5 text-muted-foreground" />
1520
+ {workspaceUrl}
1521
+ </span>
1522
+ <Tooltip>
1523
+ <TooltipTrigger asChild>
1524
+ <Button
1525
+ type="button"
1526
+ onClick={() => {
1527
+ setDraft(workspaceUrl);
1528
+ setEditing(true);
1529
+ }}
1530
+ className="text-muted-foreground hover:text-foreground"
1531
+ >
1532
+ <IconPencil size={14} />
1533
+ </Button>
1534
+ </TooltipTrigger>
1535
+ <TooltipContent>Edit workspace URL</TooltipContent>
1536
+ </Tooltip>
1537
+ <Tooltip>
1538
+ <TooltipTrigger asChild>
1539
+ <Button
1540
+ type="button"
1541
+ intent="danger"
1542
+ emphasis="ghost"
1543
+ disabled={setWorkspaceUrl.isPending}
1544
+ onClick={() => setWorkspaceUrl.mutate(null)}
1545
+ className="text-muted-foreground hover:text-destructive disabled:opacity-50"
1546
+ >
1547
+ <IconX size={14} />
1548
+ </Button>
1549
+ </TooltipTrigger>
1550
+ <TooltipContent>Remove workspace URL</TooltipContent>
1551
+ </Tooltip>
1552
+ </>
1553
+ ) : (
1554
+ <Button
1555
+ type="button"
1556
+ intent="neutral"
1557
+ emphasis="outline"
1558
+ onClick={() => setEditing(true)}
1559
+ className="flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium hover:bg-accent/50"
1560
+ >
1561
+ <IconExternalLink size={14} />
1562
+ Set workspace URL
1563
+ </Button>
1564
+ )}
1565
+ </div>
1566
+ ) : (
1567
+ <div className="flex items-center gap-2">
1568
+ <input
1569
+ type="text"
1570
+ value={draft}
1571
+ onChange={(e) => setDraft(e.target.value)}
1572
+ onKeyDown={(e) => {
1573
+ if (e.key === "Enter") save();
1574
+ if (e.key === "Escape") setEditing(false);
1575
+ }}
1576
+ placeholder="workspace.example.com"
1577
+ className="rounded-md border border-border bg-background px-2.5 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground"
1578
+ autoFocus
1579
+ />
1580
+ <Button
1581
+ type="button"
1582
+ intent="primary"
1583
+ emphasis="solid"
1584
+ disabled={setWorkspaceUrl.isPending}
1585
+ onClick={save}
1586
+ className="rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 disabled:opacity-50"
1587
+ >
1588
+ {setWorkspaceUrl.isPending ? (
1589
+ <IconLoader2 size={14} className="animate-spin" />
1590
+ ) : (
1591
+ "Save"
1592
+ )}
1593
+ </Button>
1594
+ <Button
1595
+ type="button"
1596
+ intent="neutral"
1597
+ emphasis="outline"
1598
+ onClick={() => setEditing(false)}
1599
+ className="rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground"
1600
+ >
1601
+ Cancel
1602
+ </Button>
1603
+ </div>
1604
+ )}
1605
+ <ErrorText error={setWorkspaceUrl.error} />
1606
+ </div>
1607
+ );
1608
+ }
1609
+
1480
1610
  function A2ASecretSection({ isSet }: { isSet: boolean }) {
1481
1611
  const revealA2ASecret = useRevealA2ASecret();
1482
1612
  const setA2ASecret = useSetA2ASecret();
@@ -0,0 +1,85 @@
1
+ import { IconExternalLink } from "@tabler/icons-react";
2
+ import { useState } from "react";
3
+
4
+ import { shouldOfferWorkspace } from "../../org/workspace-url.js";
5
+ import { useOrg } from "./hooks.js";
6
+
7
+ const DISMISS_KEY_PREFIX = "agent-native:workspace-notice-dismissed:";
8
+
9
+ function dismissKey(workspaceUrl: string): string {
10
+ return `${DISMISS_KEY_PREFIX}${workspaceUrl}`;
11
+ }
12
+
13
+ function readDismissed(workspaceUrl: string): boolean {
14
+ try {
15
+ return localStorage.getItem(dismissKey(workspaceUrl)) === "1";
16
+ } catch {
17
+ return false;
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Points a member at their org's own workspace when they've landed somewhere
23
+ * else — typically a shared hosted app opened from the template catalog.
24
+ *
25
+ * The switcher shows the same org name on both deployments, so without this
26
+ * the two are indistinguishable: the app looks like their team's, the team's
27
+ * apps aren't in it, and the natural reading is a broken session rather than
28
+ * a different host. Renders nothing unless an owner/admin has set a workspace
29
+ * URL and the member is not already on it.
30
+ *
31
+ * Deliberately a choice, not a redirect. The shared hosted app is the real
32
+ * product for most people, and some members of an org with a workspace still
33
+ * want to be here.
34
+ */
35
+ export function WorkspaceNotice({ className }: { className?: string }) {
36
+ const { data: org } = useOrg();
37
+ // Only re-renders after a click; the persisted answer is re-read below,
38
+ // because on every load this renders before the org query resolves and a
39
+ // value captured then would always be the pre-data default.
40
+ const [dismissedNow, setDismissedNow] = useState(false);
41
+ const workspaceUrl = org?.workspaceUrl ?? null;
42
+
43
+ if (typeof window === "undefined") return null;
44
+ if (!workspaceUrl || dismissedNow || readDismissed(workspaceUrl)) return null;
45
+ if (!shouldOfferWorkspace(window.location.href, workspaceUrl)) return null;
46
+
47
+ const workspaceHost = new URL(workspaceUrl).host;
48
+
49
+ return (
50
+ <div
51
+ className={`border-b border-border bg-blue-50 dark:bg-blue-950/30 px-3 py-2.5 sm:px-4 ${className ?? ""}`}
52
+ >
53
+ <div className="flex items-center justify-between gap-4 text-sm">
54
+ <span className="min-w-0 flex-1 text-foreground">
55
+ <span className="font-medium">{org?.orgName}</span> has its own
56
+ workspace at <span className="font-medium">{workspaceHost}</span>.
57
+ Your team&apos;s apps live there, not here.
58
+ </span>
59
+ <div className="flex shrink-0 items-center gap-2">
60
+ <a
61
+ href={workspaceUrl}
62
+ className="inline-flex items-center gap-1.5 rounded-md bg-green-600 px-3 py-1.5 text-xs font-medium text-white no-underline hover:bg-green-700"
63
+ >
64
+ <IconExternalLink className="h-3 w-3" />
65
+ Go there
66
+ </a>
67
+ <button
68
+ type="button"
69
+ onClick={() => {
70
+ try {
71
+ localStorage.setItem(dismissKey(workspaceUrl), "1");
72
+ } catch {
73
+ // Private-mode storage failure only costs a repeat banner.
74
+ }
75
+ setDismissedNow(true);
76
+ }}
77
+ className="rounded-md border border-border px-3 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground cursor-pointer"
78
+ >
79
+ Stay here
80
+ </button>
81
+ </div>
82
+ </div>
83
+ </div>
84
+ );
85
+ }
@@ -318,6 +318,20 @@ export function useSetOrgDomain() {
318
318
  });
319
319
  }
320
320
 
321
+ export function useSetOrgWorkspaceUrl() {
322
+ const qc = useQueryClient();
323
+ return useMutation({
324
+ mutationFn: (url: string | null) =>
325
+ apiFetch(`${ORG_BASE}/workspace-url`, {
326
+ method: "PUT",
327
+ body: JSON.stringify({ url }),
328
+ }),
329
+ onSuccess: async () => {
330
+ await qc.invalidateQueries({ queryKey: ["org-me"] });
331
+ },
332
+ });
333
+ }
334
+
321
335
  export interface AppRoleAssignment {
322
336
  email: string;
323
337
  role: string;
@@ -15,6 +15,7 @@ export {
15
15
  useSwitchOrg,
16
16
  useJoinByDomain,
17
17
  useSetOrgDomain,
18
+ useSetOrgWorkspaceUrl,
18
19
  useRevealA2ASecret,
19
20
  useSetA2ASecret,
20
21
  useSyncA2ASecret,
@@ -43,6 +44,7 @@ export {
43
44
  InvitationBanner,
44
45
  type InvitationBannerProps,
45
46
  } from "./InvitationBanner.js";
47
+ export { WorkspaceNotice } from "./WorkspaceNotice.js";
46
48
  export { TeamPage, type TeamPageProps } from "./TeamPage.js";
47
49
  export {
48
50
  RequireActiveOrg,