@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
@@ -82,6 +82,8 @@ const VOLATILE_VIDEO_QUERY_PARAMS = new Set([
82
82
  "Signature",
83
83
  ]);
84
84
 
85
+ const PLAY_ATTEMPT_TIMEOUT_MS = 15_000;
86
+
85
87
  function videoSourceIdentity(url: string | undefined): string {
86
88
  if (!url) return "";
87
89
  try {
@@ -277,6 +279,9 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
277
279
  const suppressNextClickRef = useRef(false);
278
280
  const playAttemptPendingRef = useRef(false);
279
281
  const playAttemptIdRef = useRef(0);
282
+ const playAttemptTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(
283
+ null,
284
+ );
280
285
  // Position to restore after `v.load()` resets `currentTime` to 0 while
281
286
  // recovering from a media error (see `requestPlay`).
282
287
  const resumeAfterReloadMsRef = useRef<number | null>(null);
@@ -322,6 +327,47 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
322
327
  const [isPlayPending, setIsPlayPending] = useState(false);
323
328
  const [isBuffering, setIsBuffering] = useState(false);
324
329
  const [playError, setPlayError] = useState<string | null>(null);
330
+ const clearPlayAttemptWatchdog = useCallback(() => {
331
+ if (playAttemptTimeoutRef.current === null) return;
332
+ clearTimeout(playAttemptTimeoutRef.current);
333
+ playAttemptTimeoutRef.current = null;
334
+ }, []);
335
+ const armPlayAttemptWatchdog = useCallback(
336
+ (attemptId: number) => {
337
+ clearPlayAttemptWatchdog();
338
+ playAttemptTimeoutRef.current = setTimeout(() => {
339
+ playAttemptTimeoutRef.current = null;
340
+ if (
341
+ attemptId !== playAttemptIdRef.current ||
342
+ !playAttemptPendingRef.current
343
+ ) {
344
+ return;
345
+ }
346
+
347
+ playAttemptIdRef.current += 1;
348
+ playAttemptPendingRef.current = false;
349
+ videoRef.current?.pause();
350
+ setIsPlaying(false);
351
+ setIsPlayPending(false);
352
+ setIsBuffering(false);
353
+ setIsPreparing(false);
354
+ const timeoutError = new Error(
355
+ `Playback did not start within ${PLAY_ATTEMPT_TIMEOUT_MS}ms`,
356
+ );
357
+ reportPlaybackIssue(
358
+ "play-start-timeout",
359
+ timeoutError,
360
+ videoRef.current,
361
+ {
362
+ recordingId,
363
+ autoPlay: !!autoPlay,
364
+ },
365
+ );
366
+ setPlayError("Playback is taking too long to start. Try again.");
367
+ }, PLAY_ATTEMPT_TIMEOUT_MS);
368
+ },
369
+ [autoPlay, clearPlayAttemptWatchdog, recordingId],
370
+ );
325
371
  // MediaRecorder-created WebM files report `video.duration === Infinity`
326
372
  // until the browser has actually scrubbed to the end. When that happens
327
373
  // the scrubber's percentage math breaks (anything / Infinity = 0) and
@@ -447,13 +493,20 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
447
493
  playAttemptPendingRef.current = true;
448
494
  setIsPlayPending(true);
449
495
  setIsBuffering(true);
496
+ armPlayAttemptWatchdog(nextId);
450
497
  } else {
498
+ clearPlayAttemptWatchdog();
451
499
  setIsPlaying(false);
452
500
  setIsBuffering(false);
453
501
  }
454
502
  setIsPreparing(true);
455
503
  setCanPlay(false);
456
- }, [mse.mode, activeVideoSrc]);
504
+ }, [
505
+ activeVideoSrc,
506
+ armPlayAttemptWatchdog,
507
+ clearPlayAttemptWatchdog,
508
+ mse.mode,
509
+ ]);
457
510
 
458
511
  useEffect(() => {
459
512
  if (!resolvedVideoSrc) {
@@ -494,12 +547,14 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
494
547
 
495
548
  useEffect(() => {
496
549
  if (!isLoomEmbed) return;
550
+ clearPlayAttemptWatchdog();
551
+ playAttemptPendingRef.current = false;
497
552
  setCanPlay(true);
498
553
  setIsPreparing(false);
499
554
  setIsBuffering(false);
500
555
  setIsPlayPending(false);
501
556
  setPlayError(null);
502
- }, [activeVideoSourceIdentity, isLoomEmbed]);
557
+ }, [activeVideoSourceIdentity, clearPlayAttemptWatchdog, isLoomEmbed]);
503
558
 
504
559
  // Hide controls after 2s of idle movement.
505
560
  const bumpControls = useCallback(() => {
@@ -511,23 +566,28 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
511
566
  }, 2000);
512
567
  }, [alwaysShowControls]);
513
568
 
514
- const resolvePlayAttempt = useCallback((attemptId: number) => {
515
- if (attemptId !== playAttemptIdRef.current) return;
516
- playAttemptPendingRef.current = false;
517
- const v = videoRef.current;
518
- if (v && !v.paused && !v.ended) {
519
- setIsPlaying(true);
520
- setHasPlaybackStarted(true);
521
- }
522
- setCanPlay(true);
523
- setIsPlayPending(false);
524
- setIsBuffering(false);
525
- setIsPreparing(false);
526
- }, []);
569
+ const resolvePlayAttempt = useCallback(
570
+ (attemptId: number) => {
571
+ if (attemptId !== playAttemptIdRef.current) return;
572
+ clearPlayAttemptWatchdog();
573
+ playAttemptPendingRef.current = false;
574
+ const v = videoRef.current;
575
+ if (v && !v.paused && !v.ended) {
576
+ setIsPlaying(true);
577
+ setHasPlaybackStarted(true);
578
+ }
579
+ setCanPlay(true);
580
+ setIsPlayPending(false);
581
+ setIsBuffering(false);
582
+ setIsPreparing(false);
583
+ },
584
+ [clearPlayAttemptWatchdog],
585
+ );
527
586
 
528
587
  const rejectPlayAttempt = useCallback(
529
588
  (attemptId: number, err: unknown) => {
530
589
  if (attemptId !== playAttemptIdRef.current) return;
590
+ clearPlayAttemptWatchdog();
531
591
  playAttemptPendingRef.current = false;
532
592
  setIsPlayPending(false);
533
593
  setIsBuffering(false);
@@ -547,7 +607,7 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
547
607
  });
548
608
  setPlayError("Could not start playback. Try again.");
549
609
  },
550
- [autoPlay, recordingId],
610
+ [autoPlay, clearPlayAttemptWatchdog, recordingId],
551
611
  );
552
612
 
553
613
  const attachPlayPromise = useCallback(
@@ -592,8 +652,13 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
592
652
  v.currentTime > 1e7)
593
653
  ) {
594
654
  try {
595
- v.currentTime = 0;
596
- setCurrentMs(0);
655
+ const initialPlaybackMs = skipExcludedRange(
656
+ 0,
657
+ excludedRanges,
658
+ resolvedDurationMs,
659
+ );
660
+ v.currentTime = initialPlaybackMs / 1000;
661
+ setCurrentMs(initialPlaybackMs);
597
662
  } catch {
598
663
  // If the browser refuses the rewind, continue with the normal play
599
664
  // attempt; playback is still better than blocking on a cosmetic seek.
@@ -622,6 +687,7 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
622
687
  const attemptId = playAttemptIdRef.current + 1;
623
688
  playAttemptIdRef.current = attemptId;
624
689
  playAttemptPendingRef.current = true;
690
+ armPlayAttemptWatchdog(attemptId);
625
691
 
626
692
  try {
627
693
  attachPlayPromise(v.play(), attemptId);
@@ -630,11 +696,14 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
630
696
  }
631
697
  }, [
632
698
  activeVideoSrc,
699
+ armPlayAttemptWatchdog,
633
700
  attachPlayPromise,
634
701
  bumpControls,
635
702
  currentMs,
703
+ excludedRanges,
636
704
  hasPlaybackStarted,
637
705
  rejectPlayAttempt,
706
+ resolvedDurationMs,
638
707
  startMs,
639
708
  ]);
640
709
 
@@ -653,10 +722,11 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
653
722
  const pauseVideo = useCallback(() => {
654
723
  playAttemptIdRef.current += 1;
655
724
  playAttemptPendingRef.current = false;
725
+ clearPlayAttemptWatchdog();
656
726
  setIsPlayPending(false);
657
727
  setIsBuffering(false);
658
728
  videoRef.current?.pause();
659
- }, []);
729
+ }, [clearPlayAttemptWatchdog]);
660
730
 
661
731
  const togglePlayback = useCallback(() => {
662
732
  const v = videoRef.current;
@@ -995,11 +1065,12 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
995
1065
  setLoomStartMs(null);
996
1066
  playAttemptIdRef.current += 1;
997
1067
  playAttemptPendingRef.current = false;
1068
+ clearPlayAttemptWatchdog();
998
1069
  setCanPlay(false);
999
1070
  setIsPlayPending(false);
1000
1071
  setIsBuffering(false);
1001
1072
  setPlayError(null);
1002
- }, [activeVideoSourceIdentity, recordingId]);
1073
+ }, [activeVideoSourceIdentity, clearPlayAttemptWatchdog, recordingId]);
1003
1074
 
1004
1075
  useEffect(() => {
1005
1076
  setThumbnailLoadFailed(false);
@@ -1132,6 +1203,13 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
1132
1203
  };
1133
1204
  }, [bumpControls]);
1134
1205
 
1206
+ useEffect(
1207
+ () => () => {
1208
+ clearPlayAttemptWatchdog();
1209
+ },
1210
+ [clearPlayAttemptWatchdog],
1211
+ );
1212
+
1135
1213
  // Keep isPip in sync with the browser's PiP state (React doesn't support
1136
1214
  // PiP events as JSX handlers; wire them via addEventListener instead).
1137
1215
  useEffect(() => {
@@ -1280,13 +1358,6 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
1280
1358
  ref={setVideoNode}
1281
1359
  src={domVideoSrc}
1282
1360
  poster={resolveLocalUrl(thumbnailUrl)}
1283
- // `crossOrigin` is only needed so the owner's canvas thumbnail
1284
- // capture isn't tainted. For everyone else (viewers, and the Slack
1285
- // unfurl embed) it adds nothing — but if the player is ever framed
1286
- // into a sandboxed/opaque-origin context (Slack double-iframes the
1287
- // embed), the resulting CORS check on the media bytes fails and the
1288
- // video won't load. Scope it to owners so embeds load cleanly.
1289
- crossOrigin={role === "owner" ? "anonymous" : undefined}
1290
1361
  className={cn(
1291
1362
  "w-full h-full",
1292
1363
  cover ? "object-cover" : "object-contain",
@@ -1425,6 +1496,8 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
1425
1496
  onTimeUpdate?.(ms, resolvedDurationMs);
1426
1497
  }}
1427
1498
  onEnded={() => {
1499
+ clearPlayAttemptWatchdog();
1500
+ playAttemptPendingRef.current = false;
1428
1501
  const endedMs =
1429
1502
  resolvedDurationMs > 0
1430
1503
  ? resolvedDurationMs
@@ -1442,6 +1515,7 @@ export const VideoPlayer = forwardRef<VideoPlayerHandle, VideoPlayerProps>(
1442
1515
  onEnded?.();
1443
1516
  }}
1444
1517
  onError={(e) => {
1518
+ clearPlayAttemptWatchdog();
1445
1519
  playAttemptPendingRef.current = false;
1446
1520
  setIsPlayPending(false);
1447
1521
 
@@ -926,6 +926,7 @@ All notable user-facing changes to Clips are documented here. Open it any time f
926
926
  replyingTo: "Replying to",
927
927
  commentAt: "Comment at",
928
928
  writeReply: "Write a reply...",
929
+ editComment: "Edit comment",
929
930
  commentButton: "Comment",
930
931
  composerPlaceholder: "Add a comment…",
931
932
  mentionSomeone: "Mention someone",
@@ -1322,7 +1323,7 @@ All notable user-facing changes to Clips are documented here. Open it any time f
1322
1323
  downloadDesktopApp: "Download desktop app",
1323
1324
  technicalDetails: "Technical details",
1324
1325
  whatToCheck: "What to check",
1325
- downloadRecording: "Download recording",
1326
+ downloadRecording: "Download",
1326
1327
  openRecorderInTab: "Open recorder in tab",
1327
1328
  connectStorageToFinish:
1328
1329
  "Connect storage on the next screen: Builder.io (free tier storage + AI) or S3-compatible storage. Clips will finish saving it.",
@@ -1,5 +1,13 @@
1
1
  import { appBasePath } from "@agent-native/core/client/api-path";
2
+ import { callAction } from "@agent-native/core/client/hooks";
2
3
  import { useT } from "@agent-native/core/client/i18n";
4
+ import {
5
+ BUG_REPORT_AGENT_ACCESS_TTL_SECONDS,
6
+ BUG_REPORT_POPUP_RESPONSE_HEADERS,
7
+ bugReportSubmissionTargetOrigins,
8
+ createBugReportSubmissionMessage,
9
+ type BugReportAgentLink,
10
+ } from "@shared/bug-report";
3
11
  import {
4
12
  IconArrowLeft,
5
13
  IconCheck,
@@ -16,20 +24,15 @@ export function meta() {
16
24
  return [{ title: enMessages.bugReportRoute.donePageTitle }];
17
25
  }
18
26
 
27
+ export function headers() {
28
+ return BUG_REPORT_POPUP_RESPONSE_HEADERS;
29
+ }
30
+
19
31
  function absoluteAppUrl(path: string) {
20
32
  if (typeof window === "undefined") return path;
21
33
  return new URL(`${appBasePath()}${path}`, window.location.origin).toString();
22
34
  }
23
35
 
24
- function targetOrigin(returnUrl: string | null) {
25
- if (!returnUrl) return "*";
26
- try {
27
- return new URL(returnUrl).origin;
28
- } catch {
29
- return "*";
30
- }
31
- }
32
-
33
36
  export default function BugReportDoneRoute() {
34
37
  const t = useT();
35
38
  const location = useLocation();
@@ -47,27 +50,45 @@ export default function BugReportDoneRoute() {
47
50
  const embedUrl = recordingId
48
51
  ? absoluteAppUrl(`/embed/${encodeURIComponent(recordingId)}`)
49
52
  : null;
50
- const agentContextUrl = recordingId
51
- ? absoluteAppUrl(
52
- `/api/agent-context.json?id=${encodeURIComponent(recordingId)}`,
53
- )
54
- : null;
55
-
56
53
  useEffect(() => {
57
54
  if (!recordingId || !recordingUrl) return;
58
- const message = {
59
- type: "agent-native.clips.bug-report.submitted",
60
- recordingId,
61
- recordingUrl,
62
- embedUrl,
63
- agentContextUrl,
55
+ let cancelled = false;
56
+ void (async () => {
57
+ let agentLink: BugReportAgentLink | null = null;
58
+ try {
59
+ agentLink = (await callAction(
60
+ "create-recording-agent-link" as any,
61
+ {
62
+ recordingId,
63
+ ttlSeconds: BUG_REPORT_AGENT_ACCESS_TTL_SECONDS,
64
+ } as any,
65
+ )) as BugReportAgentLink;
66
+ } catch {
67
+ agentLink = null;
68
+ }
69
+ if (cancelled) return;
70
+
71
+ const message = createBugReportSubmissionMessage({
72
+ recordingId,
73
+ recordingUrl,
74
+ embedUrl: embedUrl ?? recordingUrl,
75
+ agentLink,
76
+ });
77
+
78
+ for (const origin of bugReportSubmissionTargetOrigins(
79
+ window.location.origin,
80
+ returnUrl,
81
+ )) {
82
+ window.opener?.postMessage(message, origin);
83
+ if (window.parent && window.parent !== window) {
84
+ window.parent.postMessage(message, origin);
85
+ }
86
+ }
87
+ })();
88
+ return () => {
89
+ cancelled = true;
64
90
  };
65
- const origin = targetOrigin(returnUrl);
66
- window.opener?.postMessage(message, origin);
67
- if (window.parent && window.parent !== window) {
68
- window.parent.postMessage(message, origin);
69
- }
70
- }, [agentContextUrl, embedUrl, recordingId, recordingUrl, returnUrl]);
91
+ }, [embedUrl, recordingId, recordingUrl, returnUrl]);
71
92
 
72
93
  const copyRecordingUrl = async () => {
73
94
  if (!recordingUrl) return;
@@ -1,7 +1,9 @@
1
1
  import { appBasePath } from "@agent-native/core/client/api-path";
2
2
  import { useT } from "@agent-native/core/client/i18n";
3
3
  import {
4
+ BUG_REPORT_POPUP_RESPONSE_HEADERS,
4
5
  bugReportContextToSearchParams,
6
+ isBugReportSubmissionMessage,
5
7
  parseBugReportContext,
6
8
  type BugReportContext,
7
9
  type BugReportSeverity,
@@ -12,7 +14,7 @@ import {
12
14
  IconExternalLink,
13
15
  IconShieldCheck,
14
16
  } from "@tabler/icons-react";
15
- import { useEffect, useMemo, useState } from "react";
17
+ import { useEffect, useMemo, useRef, useState } from "react";
16
18
  import { useLocation, useOutlet } from "react-router";
17
19
 
18
20
  import { Button } from "@/components/ui/button";
@@ -33,7 +35,11 @@ export function meta() {
33
35
  return [{ title: enMessages.bugReportRoute.pageTitle }];
34
36
  }
35
37
 
36
- function openRecorder(url: string) {
38
+ export function headers() {
39
+ return BUG_REPORT_POPUP_RESPONSE_HEADERS;
40
+ }
41
+
42
+ function openRecorder(url: string): Window | null {
37
43
  const opened = window.open(
38
44
  url,
39
45
  "agent-native-clips-bug-report",
@@ -41,9 +47,19 @@ function openRecorder(url: string) {
41
47
  );
42
48
  if (!opened) {
43
49
  window.location.href = url;
44
- return;
50
+ return null;
45
51
  }
46
52
  opened.focus();
53
+ return opened;
54
+ }
55
+
56
+ function originFor(value: string | null): string | null {
57
+ if (!value) return null;
58
+ try {
59
+ return new URL(value).origin;
60
+ } catch {
61
+ return null;
62
+ }
47
63
  }
48
64
 
49
65
  export default function BugReportRoute() {
@@ -66,6 +82,7 @@ export default function BugReportRoute() {
66
82
  initialContext?.severity ?? "normal",
67
83
  );
68
84
  const [referrer, setReferrer] = useState<string | null>(null);
85
+ const recorderWindowRef = useRef<Window | null>(null);
69
86
 
70
87
  useEffect(() => {
71
88
  setReferrer(document.referrer || null);
@@ -75,6 +92,26 @@ export default function BugReportRoute() {
75
92
  const pageTitle = initialContext?.pageTitle ?? null;
76
93
  const sourceLabel =
77
94
  pageTitle || sourceUrl || t("bugReportRoute.sourceUnknown");
95
+ const hostOrigin = originFor(initialContext?.returnUrl ?? sourceUrl);
96
+
97
+ useEffect(() => {
98
+ if (!hostOrigin) return;
99
+ const relaySubmission = (event: MessageEvent) => {
100
+ if (event.origin !== window.location.origin) return;
101
+ if (
102
+ recorderWindowRef.current &&
103
+ event.source !== recorderWindowRef.current
104
+ ) {
105
+ return;
106
+ }
107
+ if (!isBugReportSubmissionMessage(event.data)) return;
108
+ if (window.parent && window.parent !== window) {
109
+ window.parent.postMessage(event.data, hostOrigin);
110
+ }
111
+ };
112
+ window.addEventListener("message", relaySubmission);
113
+ return () => window.removeEventListener("message", relaySubmission);
114
+ }, [hostOrigin]);
78
115
 
79
116
  if (outlet) return outlet;
80
117
 
@@ -99,7 +136,9 @@ export default function BugReportRoute() {
99
136
  params.set("intent", "bug-report");
100
137
  params.set("mode", "screen");
101
138
  params.set("surface", "browser");
102
- openRecorder(`${appBasePath()}/record?${params.toString()}`);
139
+ recorderWindowRef.current = openRecorder(
140
+ `${appBasePath()}/record?${params.toString()}`,
141
+ );
103
142
  };
104
143
 
105
144
  return (
@@ -93,6 +93,7 @@ async function writeAppState(key: string, value: unknown): Promise<void> {
93
93
  }
94
94
 
95
95
  import {
96
+ BUG_REPORT_POPUP_RESPONSE_HEADERS,
96
97
  bugReportTitle,
97
98
  parseBugReportContext,
98
99
  type BugReportContext,
@@ -129,6 +130,7 @@ export function headers() {
129
130
  return {
130
131
  "Permissions-Policy":
131
132
  "camera=(self), microphone=(self), display-capture=(self), geolocation=(), screen-wake-lock=()",
133
+ ...BUG_REPORT_POPUP_RESPONSE_HEADERS,
132
134
  };
133
135
  }
134
136
 
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-29
4
+ ---
5
+
6
+ Edited clips now start after trimmed intros and recover instead of getting stuck when a browser cannot start the video.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-07-29
4
+ ---
5
+
6
+ Comments can now be edited after posting.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-07-29
4
+ ---
5
+
6
+ Download actions now use a shorter, clearer label.
@@ -0,0 +1,6 @@
1
+ ---
2
+ date: "2026-07-29"
3
+ type: improved
4
+ ---
5
+
6
+ Embedded bug reports now return a temporary agent-readable link with transcript, timestamped frames, and diagnostics.
@@ -1,4 +1,7 @@
1
1
  export const BUG_REPORT_QUERY_FLAG = "bugReport";
2
+ export const BUG_REPORT_SUBMITTED_MESSAGE_TYPE =
3
+ "agent-native.clips.bug-report.submitted";
4
+ export const BUG_REPORT_AGENT_ACCESS_TTL_SECONDS = 7 * 24 * 60 * 60;
2
5
 
3
6
  export const BUG_REPORT_SEVERITIES = [
4
7
  "low",
@@ -25,6 +28,27 @@ export interface BugReportContext {
25
28
  returnUrl: string | null;
26
29
  }
27
30
 
31
+ export interface BugReportSubmissionMessage {
32
+ type: typeof BUG_REPORT_SUBMITTED_MESSAGE_TYPE;
33
+ recordingId: string;
34
+ recordingUrl: string;
35
+ embedUrl: string;
36
+ agentShareUrl: string | null;
37
+ agentContextUrl: string | null;
38
+ agentAccessExpiresAt: string | null;
39
+ agentAccessStatus: "ready" | "unavailable";
40
+ }
41
+
42
+ export interface BugReportAgentLink {
43
+ url?: string | null;
44
+ contextUrl?: string | null;
45
+ expiresAt?: string | null;
46
+ }
47
+
48
+ export const BUG_REPORT_POPUP_RESPONSE_HEADERS = {
49
+ "Cross-Origin-Opener-Policy": "unsafe-none",
50
+ } as const;
51
+
28
52
  const PARAMS = {
29
53
  projectId: "projectId",
30
54
  title: "title",
@@ -159,3 +183,78 @@ export function bugReportTitle(context: BugReportContext | null): string {
159
183
  context?.title || context?.pageTitle || context?.sourceUrl || "Bug report"
160
184
  );
161
185
  }
186
+
187
+ function nonEmptyString(value: unknown): value is string {
188
+ return typeof value === "string" && value.trim().length > 0;
189
+ }
190
+
191
+ export function createBugReportSubmissionMessage(input: {
192
+ recordingId: string;
193
+ recordingUrl: string;
194
+ embedUrl: string;
195
+ agentLink: BugReportAgentLink | null;
196
+ }): BugReportSubmissionMessage {
197
+ const agentShareUrl = nonEmptyString(input.agentLink?.url)
198
+ ? input.agentLink.url
199
+ : null;
200
+ const agentContextUrl = nonEmptyString(input.agentLink?.contextUrl)
201
+ ? input.agentLink.contextUrl
202
+ : null;
203
+ const agentAccessExpiresAt = nonEmptyString(input.agentLink?.expiresAt)
204
+ ? input.agentLink.expiresAt
205
+ : null;
206
+ const agentAccessReady =
207
+ agentShareUrl !== null &&
208
+ agentContextUrl !== null &&
209
+ agentAccessExpiresAt !== null;
210
+
211
+ return {
212
+ type: BUG_REPORT_SUBMITTED_MESSAGE_TYPE,
213
+ recordingId: input.recordingId,
214
+ recordingUrl: input.recordingUrl,
215
+ embedUrl: input.embedUrl,
216
+ agentShareUrl: agentAccessReady ? agentShareUrl : null,
217
+ agentContextUrl: agentAccessReady ? agentContextUrl : null,
218
+ agentAccessExpiresAt: agentAccessReady ? agentAccessExpiresAt : null,
219
+ agentAccessStatus: agentAccessReady ? "ready" : "unavailable",
220
+ };
221
+ }
222
+
223
+ export function bugReportSubmissionTargetOrigins(
224
+ clipsOrigin: string,
225
+ returnUrl: string | null,
226
+ ): string[] {
227
+ let returnOrigin: string | null = null;
228
+ if (returnUrl) {
229
+ try {
230
+ const parsed = new URL(returnUrl);
231
+ returnOrigin = parsed.origin === "null" ? null : parsed.origin;
232
+ } catch {
233
+ returnOrigin = null;
234
+ }
235
+ }
236
+ return [...new Set([clipsOrigin, returnOrigin].filter(nonEmptyString))];
237
+ }
238
+
239
+ export function isBugReportSubmissionMessage(
240
+ value: unknown,
241
+ ): value is BugReportSubmissionMessage {
242
+ if (!value || typeof value !== "object") return false;
243
+ const message = value as Record<string, unknown>;
244
+ const validAgentAccess =
245
+ (message.agentAccessStatus === "ready" &&
246
+ nonEmptyString(message.agentShareUrl) &&
247
+ nonEmptyString(message.agentContextUrl) &&
248
+ nonEmptyString(message.agentAccessExpiresAt)) ||
249
+ (message.agentAccessStatus === "unavailable" &&
250
+ message.agentShareUrl === null &&
251
+ message.agentContextUrl === null &&
252
+ message.agentAccessExpiresAt === null);
253
+ return (
254
+ message.type === BUG_REPORT_SUBMITTED_MESSAGE_TYPE &&
255
+ nonEmptyString(message.recordingId) &&
256
+ nonEmptyString(message.recordingUrl) &&
257
+ nonEmptyString(message.embedUrl) &&
258
+ validAgentAccess
259
+ );
260
+ }
@@ -99,7 +99,13 @@ export async function assertContentDatabaseViewerAccess(databaseId: string) {
99
99
  isNull(schema.contentDatabases.deletedAt),
100
100
  ),
101
101
  );
102
- if (!database) throw new Error(`Database "${databaseId}" not found`);
102
+ if (!database) {
103
+ const error = new Error(`Database "${databaseId}" not found`) as Error & {
104
+ statusCode: number;
105
+ };
106
+ error.statusCode = 404;
107
+ throw error;
108
+ }
103
109
 
104
110
  try {
105
111
  await assertAccess("document", database.documentId, "viewer");
@@ -812,11 +812,14 @@ function DatabaseTable({
812
812
  const isLoadingMoreItems =
813
813
  database.isFetching && data?.pagination?.limit !== databaseRequestItemLimit;
814
814
  const databaseId = data?.database.id ?? expectedDatabaseId;
815
+ const personalViewDatabaseId = data?.database.id ?? null;
815
816
  const newDatabaseRowLabel = isWorkspaceCatalog
816
817
  ? t("sidebar.addWorkspace")
817
818
  : dbText("newPage");
818
- const personalView = useContentDatabasePersonalView(databaseId);
819
- const updatePersonalView = useUpdateContentDatabasePersonalView(databaseId);
819
+ const personalView = useContentDatabasePersonalView(personalViewDatabaseId);
820
+ const updatePersonalView = useUpdateContentDatabasePersonalView(
821
+ personalViewDatabaseId,
822
+ );
820
823
  const source = data?.source ?? null;
821
824
  const sources = useMemo(
822
825
  () => databaseAttachedSources(data?.sources, source),