@agent-native/core 0.141.6 → 0.144.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 (501) hide show
  1. package/agent-native.eject.json +9 -0
  2. package/corpus/README.md +1 -1
  3. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +3 -14
  4. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +11 -6
  5. package/corpus/templates/analytics/.agents/skills/prometheus/SKILL.md +5 -5
  6. package/corpus/templates/analytics/.agents/skills/provider-api/SKILL.md +19 -0
  7. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +296 -0
  8. package/corpus/templates/analytics/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  9. package/corpus/templates/analytics/.agents/skills/turn-into-skill/SKILL.md +112 -0
  10. package/corpus/templates/analytics/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  11. package/corpus/templates/analytics/AGENTS.md +37 -40
  12. package/corpus/templates/analytics/actions/compose-dashboard.ts +1 -1
  13. package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +1 -1
  14. package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +17 -22
  15. package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +135 -0
  16. package/corpus/templates/analytics/actions/navigate.ts +5 -6
  17. package/corpus/templates/analytics/actions/provider-api-register.ts +50 -0
  18. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +46 -13
  19. package/corpus/templates/analytics/actions/test-custom-api-connection.ts +106 -0
  20. package/corpus/templates/analytics/actions/update-dashboard.ts +0 -1
  21. package/corpus/templates/analytics/actions/view-screen.ts +0 -20
  22. package/corpus/templates/analytics/app/components/CustomApiCard.tsx +430 -0
  23. package/corpus/templates/analytics/app/components/layout/Header.tsx +0 -1
  24. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +5 -5
  25. package/corpus/templates/analytics/app/i18n-data.ts +682 -90
  26. package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +6 -0
  27. package/corpus/templates/analytics/app/lib/sql-query.ts +33 -6
  28. package/corpus/templates/analytics/app/pages/Agents.tsx +0 -3
  29. package/corpus/templates/analytics/app/pages/DataSources.tsx +4 -0
  30. package/corpus/templates/analytics/app/pages/Settings.tsx +22 -43
  31. package/corpus/templates/analytics/app/pages/settings/settings-search.ts +23 -20
  32. package/corpus/templates/analytics/app/routes/extensions._index.tsx +1 -1
  33. package/corpus/templates/analytics/app/routes/settings.$.tsx +1 -0
  34. package/corpus/templates/analytics/app/routes/team.tsx +1 -1
  35. package/corpus/templates/analytics/changelog/2026-08-05-settings-no-longer-includes-an-unnecessary-about-section.md +6 -0
  36. package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-load-reliably-during-background-data-sw.md +6 -0
  37. package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-remain-responsive-while-historical-data.md +6 -0
  38. package/corpus/templates/analytics/changelog/2026-08-06-analytics-query-results-now-render-as-a-table-with-csv-downl.md +6 -0
  39. package/corpus/templates/analytics/changelog/2026-08-06-connect-public-https-custom-apis-and-hand-tested-endpoints-t.md +6 -0
  40. package/corpus/templates/analytics/changelog/2026-08-06-durable-agent-worker-memory.md +6 -0
  41. package/corpus/templates/analytics/changelog/2026-08-06-live-dashboard-panels-use-the-shared-query-timeout.md +6 -0
  42. package/corpus/templates/analytics/changelog/2026-08-06-on-demand-billing-is-available-as-a-native-dashboard-with-ta.md +6 -0
  43. package/corpus/templates/analytics/changelog/2026-08-06-visible-dashboard-names-are-unique.md +6 -0
  44. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +1 -1
  45. package/corpus/templates/analytics/netlify.toml +7 -0
  46. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +4 -0
  47. package/corpus/templates/analytics/scripts/first-party-analytics-bigquery.sql +104 -0
  48. package/corpus/templates/analytics/server/db/index.ts +27 -0
  49. package/corpus/templates/analytics/server/db/schema.ts +10 -0
  50. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +0 -2
  51. package/corpus/templates/analytics/server/lib/dashboards-store.ts +227 -60
  52. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +1147 -0
  53. package/corpus/templates/analytics/server/lib/first-party-analytics-health.ts +34 -15
  54. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +57 -4
  55. package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +227 -1
  56. package/corpus/templates/analytics/server/lib/real-data-actions.ts +1 -3
  57. package/corpus/templates/analytics/server/plugins/agent-chat.ts +7 -4
  58. package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +1 -0
  59. package/corpus/templates/analytics/server/plugins/db.ts +52 -18
  60. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +36 -8
  61. package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +16 -1
  62. package/corpus/templates/assets/.agents/skills/library-management/SKILL.md +16 -1
  63. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +296 -0
  64. package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  65. package/corpus/templates/assets/.agents/skills/turn-into-skill/SKILL.md +112 -0
  66. package/corpus/templates/assets/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  67. package/corpus/templates/assets/AGENTS.md +1 -0
  68. package/corpus/templates/assets/actions/_helpers.ts +12 -0
  69. package/corpus/templates/assets/actions/generate-image.ts +9 -3
  70. package/corpus/templates/assets/actions/import-style-from-url.ts +115 -0
  71. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +3 -1
  72. package/corpus/templates/assets/app/routes/extensions._index.tsx +1 -1
  73. package/corpus/templates/assets/app/routes/settings.$.tsx +1 -0
  74. package/corpus/templates/assets/app/routes/settings.tsx +5 -0
  75. package/corpus/templates/assets/app/routes/team.tsx +1 -1
  76. package/corpus/templates/assets/changelog/2026-08-05-brand-kits-can-import-a-website-s-hydrated-visual-language-a.md +6 -0
  77. package/corpus/templates/assets/changelog/2026-08-05-generated-images-now-hand-off-embeddable-previews-to-other-w.md +6 -0
  78. package/corpus/templates/assets/server/lib/generation.ts +58 -0
  79. package/corpus/templates/assets/shared/api.ts +12 -0
  80. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +296 -0
  81. package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  82. package/corpus/templates/brain/.agents/skills/turn-into-skill/SKILL.md +112 -0
  83. package/corpus/templates/brain/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  84. package/corpus/templates/brain/actions/list-connection-providers.ts +24 -3
  85. package/corpus/templates/brain/app/lib/dispatch-links.ts +44 -0
  86. package/corpus/templates/brain/app/routes/extensions._index.tsx +1 -1
  87. package/corpus/templates/brain/app/routes/sources.tsx +15 -7
  88. package/corpus/templates/brain/app/routes/team.tsx +1 -1
  89. package/corpus/templates/brain/app/routes.ts +1 -1
  90. package/corpus/templates/brain/changelog/2026-08-06-brain-provider-setup-links-open-dispatch-correctly-in-standa.md +6 -0
  91. package/corpus/templates/brain/server/plugins/agent-chat.ts +1 -0
  92. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +26 -0
  93. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +296 -0
  94. package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  95. package/corpus/templates/calendar/.agents/skills/turn-into-skill/SKILL.md +112 -0
  96. package/corpus/templates/calendar/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  97. package/corpus/templates/calendar/AGENTS.md +11 -32
  98. package/corpus/templates/calendar/actions/update-event.ts +107 -1
  99. package/corpus/templates/calendar/app/components/calendar/EventCalendarSelect.tsx +83 -0
  100. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +57 -0
  101. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +59 -73
  102. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
  103. package/corpus/templates/calendar/app/hooks/use-events.ts +4 -1
  104. package/corpus/templates/calendar/app/i18n-data.ts +20 -0
  105. package/corpus/templates/calendar/app/routes/_app.extensions._index.tsx +1 -1
  106. package/corpus/templates/calendar/app/routes/_app.settings.$.tsx +1 -0
  107. package/corpus/templates/calendar/app/routes/_app.team.tsx +1 -1
  108. package/corpus/templates/calendar/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  109. package/corpus/templates/calendar/changelog/2026-08-06-existing-events-can-move-between-connected-google-account-ca.md +6 -0
  110. package/corpus/templates/calendar/server/lib/google-calendar.ts +101 -0
  111. package/corpus/templates/calendar/server/plugins/agent-chat.ts +7 -1
  112. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  113. package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  114. package/corpus/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  115. package/corpus/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  116. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
  117. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  118. package/corpus/templates/chat/app/root.tsx +1 -1
  119. package/corpus/templates/chat/app/routes/agent.tsx +7 -7
  120. package/corpus/templates/chat/app/routes/extensions._index.tsx +1 -1
  121. package/corpus/templates/chat/app/routes/settings.$.tsx +1 -0
  122. package/corpus/templates/chat/app/routes/team.tsx +1 -1
  123. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +296 -0
  124. package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  125. package/corpus/templates/clips/.agents/skills/turn-into-skill/SKILL.md +112 -0
  126. package/corpus/templates/clips/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  127. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +9 -24
  128. package/corpus/templates/clips/app/components/editor/timeline-geometry.ts +15 -0
  129. package/corpus/templates/clips/app/components/editor/waveform.tsx +4 -17
  130. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
  131. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +14 -3
  132. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +1 -1
  133. package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +1 -1
  134. package/corpus/templates/clips/app/routes/_app.extensions._index.tsx +1 -1
  135. package/corpus/templates/clips/app/routes/_app.settings.$.tsx +1 -0
  136. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +28 -38
  137. package/corpus/templates/clips/app/routes/share.$shareId.tsx +21 -27
  138. package/corpus/templates/clips/changelog/2026-08-06-clips-recovers-from-stalled-recording-setup-without-requirin.md +6 -0
  139. package/corpus/templates/clips/changelog/2026-08-06-clips-starts-faster-after-a-deploy-or-idle-period-startup-no.md +6 -0
  140. package/corpus/templates/clips/changelog/2026-08-06-deleting-a-recording-returns-cleanly-to-the-library-and-fit-.md +6 -0
  141. package/corpus/templates/clips/changelog/2026-08-06-hide-clip-insights-from-viewers-without-analytics-access.md +6 -0
  142. package/corpus/templates/clips/desktop/src/app.tsx +48 -20
  143. package/corpus/templates/clips/desktop/src/lib/recorder.ts +275 -74
  144. package/corpus/templates/clips/desktop/src/lib/recording-start-guard.ts +84 -0
  145. package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +14 -4
  146. package/corpus/templates/clips/server/plugins/db.ts +214 -26
  147. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +296 -0
  148. package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  149. package/corpus/templates/content/.agents/skills/turn-into-skill/SKILL.md +112 -0
  150. package/corpus/templates/content/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  151. package/corpus/templates/content/app/routes/_app.extensions._index.tsx +1 -1
  152. package/corpus/templates/content/app/routes/_app.settings.$.tsx +1 -0
  153. package/corpus/templates/content/app/routes/_app.team.tsx +1 -1
  154. package/corpus/templates/content/e2e/global-setup.ts +1 -1
  155. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +296 -0
  156. package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  157. package/corpus/templates/crm/.agents/skills/turn-into-skill/SKILL.md +112 -0
  158. package/corpus/templates/crm/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  159. package/corpus/templates/crm/changelog/2026-08-06-crm-starts-faster-after-a-deploy-or-idle-period-one-time-dat.md +6 -0
  160. package/corpus/templates/crm/server/plugins/db.ts +11 -8
  161. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +36 -1
  162. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +6 -1
  163. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +296 -0
  164. package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  165. package/corpus/templates/design/.agents/skills/turn-into-skill/SKILL.md +112 -0
  166. package/corpus/templates/design/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  167. package/corpus/templates/design/actions/analyze-brand-assets.ts +7 -7
  168. package/corpus/templates/design/actions/import-from-url.ts +6 -5
  169. package/corpus/templates/design/app/components/design/LayersPanel.tsx +27 -18
  170. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +2 -2
  171. package/corpus/templates/design/app/pages/Index.tsx +6 -2
  172. package/corpus/templates/design/app/routes/extensions._index.tsx +1 -1
  173. package/corpus/templates/design/app/routes/settings.$.tsx +1 -0
  174. package/corpus/templates/design/app/routes/team.tsx +1 -1
  175. package/corpus/templates/design/changelog/2026-08-05-deleting-a-design-from-the-home-page-no-longer-leaves-the-ap.md +6 -0
  176. package/corpus/templates/design/changelog/2026-08-05-renaming-a-layer-now-focuses-its-name-field-automatically.md +6 -0
  177. package/corpus/templates/design/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-de.md +6 -0
  178. package/corpus/templates/design/e2e/global-setup.ts +1 -1
  179. package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
  180. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +296 -0
  181. package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  182. package/corpus/templates/dispatch/.agents/skills/turn-into-skill/SKILL.md +112 -0
  183. package/corpus/templates/dispatch/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  184. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +1 -1
  185. package/corpus/templates/dispatch/app/routes/settings.$.tsx +1 -0
  186. package/corpus/templates/dispatch/app/routes/team.tsx +1 -1
  187. package/corpus/templates/dispatch/changelog/2026-08-06-ready-workspace-apps-stay-one-click-away-in-a-compact-dispat.md +6 -0
  188. package/corpus/templates/dispatch/changelog/2026-08-06-shared-vault-values-and-management-are-now-restricted-to-wor.md +6 -0
  189. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +296 -0
  190. package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  191. package/corpus/templates/factory/.agents/skills/turn-into-skill/SKILL.md +112 -0
  192. package/corpus/templates/factory/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  193. package/corpus/templates/factory/app/hooks/use-navigation-state.ts +1 -1
  194. package/corpus/templates/factory/app/routes/extensions._index.tsx +1 -1
  195. package/corpus/templates/factory/app/routes/settings.$.tsx +1 -0
  196. package/corpus/templates/factory/app/routes/team.tsx +1 -1
  197. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +296 -0
  198. package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  199. package/corpus/templates/forms/.agents/skills/turn-into-skill/SKILL.md +112 -0
  200. package/corpus/templates/forms/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  201. package/corpus/templates/forms/app/routes/_app.extensions._index.tsx +1 -1
  202. package/corpus/templates/forms/app/routes/_app.settings.$.tsx +1 -0
  203. package/corpus/templates/forms/app/routes/_app.team.tsx +1 -1
  204. package/corpus/templates/forms/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  205. package/corpus/templates/forms/server/plugins/agent-chat.ts +4 -0
  206. package/corpus/templates/forms/shared/navigation.ts +1 -1
  207. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +296 -0
  208. package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  209. package/corpus/templates/macros/.agents/skills/turn-into-skill/SKILL.md +112 -0
  210. package/corpus/templates/macros/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  211. package/corpus/templates/macros/app/routes/extensions._index.tsx +1 -1
  212. package/corpus/templates/macros/app/routes/settings.$.tsx +1 -0
  213. package/corpus/templates/macros/app/routes/team.tsx +1 -1
  214. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +296 -0
  215. package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  216. package/corpus/templates/mail/.agents/skills/turn-into-skill/SKILL.md +112 -0
  217. package/corpus/templates/mail/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  218. package/corpus/templates/mail/app/routes/extensions._index.tsx +1 -1
  219. package/corpus/templates/mail/app/routes/settings.$.tsx +1 -0
  220. package/corpus/templates/mail/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  221. package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
  222. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +296 -0
  223. package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  224. package/corpus/templates/plan/.agents/skills/turn-into-skill/SKILL.md +112 -0
  225. package/corpus/templates/plan/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  226. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +1 -1
  227. package/corpus/templates/plan/app/routes/extensions._index.tsx +1 -1
  228. package/corpus/templates/plan/app/routes/settings.$.tsx +1 -0
  229. package/corpus/templates/plan/app/routes/team.tsx +1 -1
  230. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +48 -5
  231. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +40 -2
  232. package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +6 -0
  233. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +15 -2
  234. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +29 -24
  235. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +296 -0
  236. package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  237. package/corpus/templates/slides/.agents/skills/turn-into-skill/SKILL.md +112 -0
  238. package/corpus/templates/slides/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  239. package/corpus/templates/slides/AGENTS.md +7 -9
  240. package/corpus/templates/slides/_gitignore +1 -0
  241. package/corpus/templates/slides/actions/analyze-brand-assets.ts +7 -7
  242. package/corpus/templates/slides/actions/export-pptx.ts +402 -36
  243. package/corpus/templates/slides/actions/import-file.ts +46 -85
  244. package/corpus/templates/slides/actions/import-from-url.ts +6 -6
  245. package/corpus/templates/slides/actions/import-google-slides-reference.ts +271 -12
  246. package/corpus/templates/slides/actions/import-pptx.ts +85 -60
  247. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -13
  248. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +1 -1
  249. package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +5 -1
  250. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +25 -12
  251. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +112 -57
  252. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +202 -0
  253. package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +26 -14
  254. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +176 -0
  255. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +182 -141
  256. package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +1 -0
  257. package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +18 -0
  258. package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +85 -0
  259. package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -0
  260. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +13 -3
  261. package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +27 -1
  262. package/corpus/templates/slides/app/context/DeckContext.tsx +71 -20
  263. package/corpus/templates/slides/app/global.css +6 -0
  264. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  265. package/corpus/templates/slides/app/lib/create-deck-generation.ts +10 -6
  266. package/corpus/templates/slides/app/lib/deck-preview-frame.ts +15 -0
  267. package/corpus/templates/slides/app/lib/deck-share-links.ts +9 -0
  268. package/corpus/templates/slides/app/lib/export-pptx-client.ts +89 -0
  269. package/corpus/templates/slides/app/lib/slide-animation-elements.ts +3 -0
  270. package/corpus/templates/slides/app/pages/DeckEditor.tsx +17 -0
  271. package/corpus/templates/slides/app/pages/Index.tsx +107 -6
  272. package/corpus/templates/slides/app/routes/extensions._index.tsx +1 -1
  273. package/corpus/templates/slides/app/routes/settings.$.tsx +1 -0
  274. package/corpus/templates/slides/app/routes/team.tsx +1 -1
  275. package/corpus/templates/slides/changelog/2026-08-05-failed-deck-creation-and-reference-uploads-now-recover-clean.md +6 -0
  276. package/corpus/templates/slides/changelog/2026-08-05-slides-recover-completed-generation-results-after-a-sync-hic.md +6 -0
  277. package/corpus/templates/slides/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-st.md +6 -0
  278. package/corpus/templates/slides/changelog/2026-08-06-clicking-the-gray-canvas-around-a-slide-clears-its-selection.md +6 -0
  279. package/corpus/templates/slides/changelog/2026-08-06-deck-thumbnails-keep-a-consistent-listing-frame-across-aspec.md +6 -0
  280. package/corpus/templates/slides/changelog/2026-08-06-deep-linked-decks-open-directly-instead-of-being-interrupted.md +6 -0
  281. package/corpus/templates/slides/changelog/2026-08-06-google-slides-exports-now-show-clear-import-steps-when-direc.md +6 -0
  282. package/corpus/templates/slides/changelog/2026-08-06-import-pdf-google-slides-and-powerpoint-decks-directly-from-.md +6 -0
  283. package/corpus/templates/slides/changelog/2026-08-06-imported-powerpoint-exports-keep-text-and-images-editable-an.md +6 -0
  284. package/corpus/templates/slides/changelog/2026-08-06-presentation-prompts-continue-adding-rendered-slides-until-t.md +6 -0
  285. package/corpus/templates/slides/changelog/2026-08-06-public-decks-now-share-read-only-presentation-links-by-defau.md +6 -0
  286. package/corpus/templates/slides/changelog/2026-08-06-slides-offers-a-direct-connect-google-button-when-a-drive-co.md +6 -0
  287. package/corpus/templates/slides/changelog/2026-08-06-slides-preserve-uploaded-pdf-layouts-accept-larger-reference.md +6 -0
  288. package/corpus/templates/slides/changelog/2026-08-06-styled-words-stay-part-of-their-text-box-instead-of-becoming.md +6 -0
  289. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +7 -20
  290. package/corpus/templates/slides/server/handlers/import/html-converter.ts +236 -13
  291. package/corpus/templates/slides/server/handlers/import/pptx-assets.ts +67 -0
  292. package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +2 -0
  293. package/corpus/templates/slides/server/handlers/uploads.ts +7 -3
  294. package/corpus/templates/slides/server/lib/chat-attachments.ts +6 -3
  295. package/corpus/templates/slides/server/lib/emails.ts +7 -2
  296. package/corpus/templates/slides/server/lib/google-docs-error.ts +50 -0
  297. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +1 -0
  298. package/corpus/templates/slides/server/lib/import-asset-storage.ts +127 -0
  299. package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -3
  300. package/corpus/templates/slides/server/routes/api/import-assets/[token].get.ts +70 -0
  301. package/corpus/templates/slides/shared/upload-types.ts +3 -0
  302. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +296 -0
  303. package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  304. package/corpus/templates/tasks/.agents/skills/turn-into-skill/SKILL.md +112 -0
  305. package/corpus/templates/tasks/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  306. package/corpus/templates/tasks/app/components/layout/Header.tsx +3 -1
  307. package/corpus/templates/tasks/app/routes/extensions._index.tsx +1 -1
  308. package/corpus/templates/tasks/app/routes/settings.$.tsx +1 -0
  309. package/dist/agent/engine/ai-sdk-engine.js +49 -3
  310. package/dist/agent/production-agent.d.ts +18 -0
  311. package/dist/agent/production-agent.js +80 -1
  312. package/dist/agent/types.d.ts +7 -0
  313. package/dist/cli/agent-plugin.d.ts +112 -0
  314. package/dist/cli/agent-plugin.js +1081 -0
  315. package/dist/cli/app-skill.js +39 -1
  316. package/dist/cli/code-agent-executor.d.ts +3 -0
  317. package/dist/cli/code-agent-executor.js +51 -13
  318. package/dist/cli/index.js +13 -0
  319. package/dist/cli/templates-meta.js +1 -1
  320. package/dist/client/AgentPanel.d.ts +3 -1
  321. package/dist/client/AgentPanel.js +9 -2
  322. package/dist/client/AssistantChat.d.ts +8 -0
  323. package/dist/client/AssistantChat.js +23 -8
  324. package/dist/client/NewWorkspaceAppFlow.js +1 -0
  325. package/dist/client/agent-chat-adapter.d.ts +1 -1
  326. package/dist/client/agent-chat-adapter.js +153 -7
  327. package/dist/client/agent-page/AgentWorkspaceContent.d.ts +1 -1
  328. package/dist/client/agent-page/AgentWorkspaceContent.js +13 -13
  329. package/dist/client/assistant-ui-recovery.d.ts +2 -1
  330. package/dist/client/assistant-ui-recovery.js +7 -3
  331. package/dist/client/chat/run-recovery.js +5 -1
  332. package/dist/client/embed-auth.js +6 -2
  333. package/dist/client/error-format.js +12 -0
  334. package/dist/client/integrations/IntegrationsPanel.js +40 -6
  335. package/dist/client/onboarding/FirstRunOnboarding.js +11 -4
  336. package/dist/client/org/OrgSwitcher.js +2 -2
  337. package/dist/client/org/TeamPage.js +92 -72
  338. package/dist/client/require-session.d.ts +1 -1
  339. package/dist/client/require-session.js +4 -4
  340. package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
  341. package/dist/client/resources/McpConnectionSuggestion.js +27 -10
  342. package/dist/client/resources/McpIntegrationDialog.js +77 -45
  343. package/dist/client/resources/mcp-integration-catalog.d.ts +13 -1
  344. package/dist/client/resources/mcp-integration-catalog.js +255 -2
  345. package/dist/client/resources/mcp-integration-logos.js +18 -2
  346. package/dist/client/resources/use-mcp-servers.d.ts +5 -0
  347. package/dist/client/resources/use-mcp-servers.js +36 -0
  348. package/dist/client/settings/AccountSettingsCard.js +42 -36
  349. package/dist/client/settings/AutomationsSection.js +1 -1
  350. package/dist/client/settings/DemoModeSection.d.ts +3 -1
  351. package/dist/client/settings/DemoModeSection.js +4 -1
  352. package/dist/client/settings/ExtensionsSettingsContent.js +1 -1
  353. package/dist/client/settings/SchedulingTimezoneField.d.ts +3 -1
  354. package/dist/client/settings/SchedulingTimezoneField.js +9 -5
  355. package/dist/client/settings/SettingsPanel.d.ts +4 -1
  356. package/dist/client/settings/SettingsPanel.js +21 -21
  357. package/dist/client/settings/SettingsTabsPage.d.ts +2 -2
  358. package/dist/client/settings/SettingsTabsPage.js +98 -45
  359. package/dist/client/settings/VoiceTranscriptionSection.js +6 -1
  360. package/dist/client/settings/useSettingsPanelController.js +47 -8
  361. package/dist/collab/routes.d.ts +1 -1
  362. package/dist/db/client.d.ts +9 -0
  363. package/dist/db/client.js +51 -16
  364. package/dist/db/create-get-db.js +2 -2
  365. package/dist/db/ddl-guard.d.ts +11 -10
  366. package/dist/db/ddl-guard.js +40 -12
  367. package/dist/deploy/build.d.ts +2 -0
  368. package/dist/deploy/build.js +97 -4
  369. package/dist/deploy/workspace-deploy.js +0 -2
  370. package/dist/guards/no-env-credentials.js +9 -0
  371. package/dist/ingestion/index.d.ts +1 -1
  372. package/dist/ingestion/pptx.d.ts +68 -0
  373. package/dist/ingestion/pptx.js +660 -213
  374. package/dist/ingestion/website.d.ts +30 -0
  375. package/dist/integrations/plugin.js +9 -6
  376. package/dist/localization/default-messages.d.ts +59 -0
  377. package/dist/localization/default-messages.js +62 -2
  378. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  379. package/dist/mcp-client/oauth-routes.d.ts +2 -0
  380. package/dist/mcp-client/oauth-routes.js +74 -7
  381. package/dist/mcp-client/routes.d.ts +1 -0
  382. package/dist/mcp-client/routes.js +49 -0
  383. package/dist/navigation/index.js +16 -5
  384. package/dist/notifications/routes.d.ts +1 -1
  385. package/dist/observability/routes.d.ts +3 -3
  386. package/dist/onboarding/app-profile.js +11 -0
  387. package/dist/progress/routes.d.ts +1 -1
  388. package/dist/provider-api/actions/custom-provider-registration.d.ts +13 -13
  389. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  390. package/dist/resources/store.js +15 -1
  391. package/dist/scripts/call-agent.js +45 -4
  392. package/dist/secrets/routes.d.ts +6 -6
  393. package/dist/server/agent-chat/action-filters-a2a.d.ts +1 -1
  394. package/dist/server/agent-chat/action-filters-a2a.js +36 -1
  395. package/dist/server/agent-chat-plugin.js +29 -8
  396. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  397. package/dist/server/auth.js +55 -17
  398. package/dist/server/better-auth-instance.js +5 -3
  399. package/dist/server/core-routes-plugin.d.ts +8 -1
  400. package/dist/server/core-routes-plugin.js +28 -3
  401. package/dist/server/credential-provider.d.ts +3 -3
  402. package/dist/server/credential-provider.js +90 -4
  403. package/dist/server/identity-sso.js +2 -1
  404. package/dist/server/onboarding-html.d.ts +2 -0
  405. package/dist/server/onboarding-html.js +171 -62
  406. package/dist/server/realtime-token.d.ts +1 -1
  407. package/dist/server/self-dispatch.d.ts +5 -4
  408. package/dist/server/self-dispatch.js +25 -14
  409. package/dist/server/ssr-handler.d.ts +1 -1
  410. package/dist/server/ssr-handler.js +1 -1
  411. package/dist/server/workspace-provider-oauth.js +1 -1
  412. package/dist/setup-connections/onboarding.js +1 -1
  413. package/dist/shared/cache-control.d.ts +26 -2
  414. package/dist/shared/cache-control.js +43 -2
  415. package/dist/shared/index.d.ts +1 -1
  416. package/dist/shared/index.js +1 -1
  417. package/dist/shared/password-policy.d.ts +3 -0
  418. package/dist/shared/password-policy.js +3 -0
  419. package/dist/shared/sign-in-journey.d.ts +5 -2
  420. package/dist/shared/sign-in-journey.js +10 -4
  421. package/dist/sharing/actions/set-resource-visibility.js +16 -4
  422. package/dist/sharing/registry.d.ts +14 -0
  423. package/dist/styles/agent-native.css +6 -0
  424. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  425. package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  426. package/dist/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  427. package/dist/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  428. package/dist/templates/chat/app/components/layout/Layout.tsx +1 -1
  429. package/dist/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  430. package/dist/templates/chat/app/root.tsx +1 -1
  431. package/dist/templates/chat/app/routes/agent.tsx +7 -7
  432. package/dist/templates/chat/app/routes/extensions._index.tsx +1 -1
  433. package/dist/templates/chat/app/routes/settings.$.tsx +1 -0
  434. package/dist/templates/chat/app/routes/team.tsx +1 -1
  435. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
  436. package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  437. package/dist/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
  438. package/dist/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  439. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
  440. package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  441. package/dist/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
  442. package/dist/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  443. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
  444. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
  445. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
  446. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
  447. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
  448. package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  449. package/dist/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
  450. package/dist/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  451. package/dist/templates/workspace-root/AGENTS.md +7 -0
  452. package/dist/user-profile/actions/change-password.js +8 -3
  453. package/dist/user-profile/actions/set-password.js +5 -1
  454. package/dist/vite/action-types-plugin.js +59 -0
  455. package/docs/content/authentication.mdx +4 -5
  456. package/docs/content/skills-guide.mdx +13 -0
  457. package/docs/content/template-analytics-developers.mdx +1 -1
  458. package/docs/content/template-calendar-developers.mdx +1 -1
  459. package/docs/content/template-chat-developers.mdx +2 -2
  460. package/docs/content/template-content-developers.mdx +1 -1
  461. package/docs/content/template-mail-developers.mdx +1 -1
  462. package/docs/content/template-plan-developers.mdx +1 -1
  463. package/docs/content/toolkit-command-navigation.mdx +6 -6
  464. package/docs/content/toolkit-org-team.mdx +1 -1
  465. package/docs/content/toolkit-settings.mdx +8 -8
  466. package/docs/content/toolkit-setup-connections.mdx +1 -1
  467. package/package.json +6 -2
  468. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  469. package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  470. package/src/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  471. package/src/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  472. package/src/templates/chat/app/components/layout/Layout.tsx +1 -1
  473. package/src/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  474. package/src/templates/chat/app/root.tsx +1 -1
  475. package/src/templates/chat/app/routes/agent.tsx +7 -7
  476. package/src/templates/chat/app/routes/extensions._index.tsx +1 -1
  477. package/src/templates/chat/app/routes/settings.$.tsx +1 -0
  478. package/src/templates/chat/app/routes/team.tsx +1 -1
  479. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
  480. package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  481. package/src/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
  482. package/src/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  483. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
  484. package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  485. package/src/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
  486. package/src/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  487. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
  488. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
  489. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
  490. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
  491. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
  492. package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  493. package/src/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
  494. package/src/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  495. package/src/templates/workspace-root/AGENTS.md +7 -0
  496. package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +0 -62
  497. package/corpus/templates/analytics/actions/install-dashboard-template.ts +0 -369
  498. package/corpus/templates/analytics/actions/list-dashboard-templates.ts +0 -47
  499. package/corpus/templates/analytics/actions/list-native-v2-dashboard-templates.ts +0 -34
  500. package/corpus/templates/analytics/app/routes/catalog.tsx +0 -240
  501. package/src/templates/default/actions/navigate.spec.ts +0 -53
@@ -0,0 +1,84 @@
1
+ export const RECORDING_START_TIMEOUT_MS = 90_000;
2
+
3
+ export class RecordingStartTimeoutError extends Error {
4
+ constructor(timeoutMs: number) {
5
+ super(
6
+ `Recording setup timed out after ${Math.ceil(timeoutMs / 1000)} seconds.`,
7
+ );
8
+ this.name = "TimeoutError";
9
+ }
10
+ }
11
+
12
+ export class RecordingStartCancelledError extends Error {
13
+ constructor() {
14
+ super("Recording setup was cancelled.");
15
+ this.name = "AbortError";
16
+ }
17
+ }
18
+
19
+ export function guardRecordingStart<T>(
20
+ operation: Promise<T>,
21
+ options: {
22
+ signal?: AbortSignal;
23
+ timeoutMs?: number;
24
+ onCancel?: () => void;
25
+ onLateResolve?: (value: T) => void;
26
+ } = {},
27
+ ): Promise<T> {
28
+ const timeoutMs = options.timeoutMs ?? RECORDING_START_TIMEOUT_MS;
29
+
30
+ return new Promise<T>((resolve, reject) => {
31
+ let settled = false;
32
+ let cancellationNotified = false;
33
+ let timer: ReturnType<typeof setTimeout> | null = null;
34
+
35
+ const notifyCancellation = () => {
36
+ if (cancellationNotified) return;
37
+ cancellationNotified = true;
38
+ options.onCancel?.();
39
+ };
40
+
41
+ const cleanup = () => {
42
+ if (timer) {
43
+ clearTimeout(timer);
44
+ timer = null;
45
+ }
46
+ options.signal?.removeEventListener("abort", onAbort);
47
+ };
48
+
49
+ const finish = (callback: () => void) => {
50
+ if (settled) return;
51
+ settled = true;
52
+ cleanup();
53
+ callback();
54
+ };
55
+
56
+ const onAbort = () => {
57
+ notifyCancellation();
58
+ finish(() => reject(new RecordingStartCancelledError()));
59
+ };
60
+
61
+ if (options.signal?.aborted) {
62
+ onAbort();
63
+ return;
64
+ }
65
+ options.signal?.addEventListener("abort", onAbort, { once: true });
66
+
67
+ operation.then(
68
+ (value) => {
69
+ if (settled) {
70
+ options.onLateResolve?.(value);
71
+ return;
72
+ }
73
+ finish(() => resolve(value));
74
+ },
75
+ (error) => {
76
+ finish(() => reject(error));
77
+ },
78
+ );
79
+ timer = setTimeout(() => {
80
+ notifyCancellation();
81
+ finish(() => reject(new RecordingStartTimeoutError(timeoutMs)));
82
+ }, timeoutMs);
83
+ });
84
+ }
@@ -81,12 +81,14 @@ export function Toolbar() {
81
81
 
82
82
  useEffect(() => {
83
83
  const unlistens: Array<() => void> = [];
84
+ const listenerPromises: Array<Promise<() => void>> = [];
84
85
  let stopped = false;
85
86
  // Same race-safe listen tracker as elsewhere: if this effect
86
87
  // cleans up before `listen()` resolves, the unlisten is called
87
88
  // immediately — otherwise the listener lingers for the life of
88
89
  // the webview, holding the setState closures captive.
89
90
  const trackListen = (p: Promise<() => void>) => {
91
+ listenerPromises.push(p);
90
92
  p.then((u) => {
91
93
  if (stopped) {
92
94
  try {
@@ -133,6 +135,11 @@ export function Toolbar() {
133
135
  }
134
136
  }),
135
137
  );
138
+ trackListen(
139
+ listen("clips:toolbar-sync", () => {
140
+ emit("clips:toolbar-ready", {}).catch(() => {});
141
+ }),
142
+ );
136
143
  trackListen(
137
144
  listen<boolean>("clips:toolbar-preparing", (ev) => {
138
145
  setPreparing(!!ev.payload);
@@ -160,6 +167,9 @@ export function Toolbar() {
160
167
  setDiskSpaceLevel("ok");
161
168
  }),
162
169
  );
170
+ void Promise.allSettled(listenerPromises).then(() => {
171
+ if (!stopped) emit("clips:toolbar-ready", {}).catch(() => {});
172
+ });
163
173
  return () => {
164
174
  stopped = true;
165
175
  unlistens.forEach((u) => {
@@ -262,7 +272,7 @@ export function Toolbar() {
262
272
  });
263
273
  }
264
274
  function cancel() {
265
- if (pendingAction || !enabled) return;
275
+ if (pendingAction) return;
266
276
  setPendingAction("cancel");
267
277
  console.log(
268
278
  "[clips-toolbar] cancel clicked — emitting clips:recorder-cancel",
@@ -418,14 +428,14 @@ export function Toolbar() {
418
428
  <button
419
429
  className="toolbar-v-action toolbar-v-action-danger"
420
430
  onClick={cancel}
421
- disabled={!enabled || !!pendingAction}
422
- aria-label="Cancel recording"
431
+ disabled={!!pendingAction}
432
+ aria-label={enabled ? "Cancel recording" : "Cancel recording setup"}
423
433
  title={
424
434
  pendingAction === "cancel"
425
435
  ? pendingActionLabel
426
436
  : enabled
427
437
  ? "Cancel"
428
- : "Recording not started yet"
438
+ : "Cancel recording setup"
429
439
  }
430
440
  data-no-drag
431
441
  >
@@ -1,8 +1,12 @@
1
+ import { randomUUID } from "node:crypto";
2
+
1
3
  import {
2
4
  runMigrations,
5
+ deferMigration,
3
6
  getDbExec,
4
7
  isPostgres,
5
8
  ensureAdditiveColumns,
9
+ type MigrationRunResult,
6
10
  } from "@agent-native/core/db";
7
11
  import { registerEvent } from "@agent-native/core/event-bus";
8
12
  import { z } from "zod";
@@ -67,14 +71,52 @@ async function retypeBooleanColumnsOnPostgres(): Promise<void> {
67
71
  ["meeting_participants", "is_organizer", false],
68
72
  ["clips_meetings", "share_transcript", false],
69
73
  ];
74
+ // One probe for all of them, not one per column. This runs on every cold
75
+ // start, and eleven serialized information_schema round-trips before the
76
+ // process can serve is exactly the startup cost that made these apps slow —
77
+ // the same reason `ensureAdditiveColumns` batches its own introspection.
78
+ // After the first deploy every column already matches and the loop below
79
+ // does nothing, so the probes were the entire remaining cost.
80
+ const typesByColumn = new Map<string, string>();
81
+ try {
82
+ const probe = await exec.execute({
83
+ // `information_schema` columns are the `name` type; the explicit
84
+ // ::text[] casts are what make the comparison legal.
85
+ sql: `SELECT table_name, column_name, data_type
86
+ FROM information_schema.columns
87
+ WHERE table_name = ANY($1::text[]) AND column_name = ANY($2::text[])`,
88
+ args: [
89
+ `{${[...new Set(alters.map(([t]) => t))].join(",")}}`,
90
+ `{${[...new Set(alters.map(([, c]) => c))].join(",")}}`,
91
+ ],
92
+ });
93
+ for (const row of probe.rows as Array<{
94
+ table_name?: string;
95
+ column_name?: string;
96
+ data_type?: string;
97
+ }>) {
98
+ if (row.table_name && row.column_name && row.data_type) {
99
+ typesByColumn.set(
100
+ `${row.table_name}.${row.column_name}`,
101
+ row.data_type,
102
+ );
103
+ }
104
+ }
105
+ } catch (err) {
106
+ // Probing is the optimization; a failure here must not skip the retype and
107
+ // silently leave int columns behind. Fall through with an empty map so each
108
+ // column is attempted individually below, as it was before batching.
109
+ console.warn(
110
+ "[db] batched boolean-column probe failed; retrying per column:",
111
+ (err as Error)?.message ?? err,
112
+ );
113
+ }
114
+
70
115
  for (const [table, column, defaultTrue] of alters) {
71
116
  try {
72
- const probe = await exec.execute({
73
- sql: `SELECT data_type FROM information_schema.columns WHERE table_name = $1 AND column_name = $2`,
74
- args: [table, column],
75
- });
76
- const row = (probe.rows as Array<{ data_type?: string }>)[0];
77
- if (!row || row.data_type === "boolean") continue;
117
+ const known = typesByColumn.get(`${table}.${column}`);
118
+ if (known === "boolean") continue;
119
+ if (!known && typesByColumn.size > 0) continue; // absent column, nothing to retype
78
120
  const def = defaultTrue ? "TRUE" : "FALSE";
79
121
  await exec.execute(
80
122
  `ALTER TABLE ${table} ALTER COLUMN ${column} DROP DEFAULT, ALTER COLUMN ${column} TYPE BOOLEAN USING (${column} <> 0), ALTER COLUMN ${column} SET DEFAULT ${def}`,
@@ -89,6 +131,107 @@ async function retypeBooleanColumnsOnPostgres(): Promise<void> {
89
131
  }
90
132
  }
91
133
 
134
+ const RECORDING_ORG_ID_BACKFILL_BATCH_SIZE = 250;
135
+ const RECORDING_ORG_ID_BACKFILL_LEASE_MS = 30_000;
136
+ const RECORDING_ORG_ID_BACKFILL_DELAY_MS = 100;
137
+ const RECORDING_ORG_ID_BACKFILL_LEASE_KEY = "recording-org-id";
138
+ const recordingOrgIdBackfillHolder = randomUUID();
139
+
140
+ async function acquireRecordingOrgIdBackfillLease(): Promise<boolean> {
141
+ const exec = getDbExec();
142
+ const now = Date.now();
143
+ const expiresAt = now + RECORDING_ORG_ID_BACKFILL_LEASE_MS;
144
+ await exec.execute({
145
+ sql: `INSERT INTO clips_backfill_leases (lease_key, holder, expires_at)
146
+ VALUES (?, ?, ?)
147
+ ON CONFLICT (lease_key) DO UPDATE SET
148
+ holder = excluded.holder,
149
+ expires_at = excluded.expires_at
150
+ WHERE clips_backfill_leases.expires_at <= ?`,
151
+ args: [
152
+ RECORDING_ORG_ID_BACKFILL_LEASE_KEY,
153
+ recordingOrgIdBackfillHolder,
154
+ expiresAt,
155
+ now,
156
+ ],
157
+ });
158
+ const result = await exec.execute({
159
+ sql: `SELECT holder FROM clips_backfill_leases
160
+ WHERE lease_key = ? AND holder = ? AND expires_at > ?`,
161
+ args: [
162
+ RECORDING_ORG_ID_BACKFILL_LEASE_KEY,
163
+ recordingOrgIdBackfillHolder,
164
+ now,
165
+ ],
166
+ });
167
+ return result.rows.length > 0;
168
+ }
169
+
170
+ async function renewRecordingOrgIdBackfillLease(): Promise<boolean> {
171
+ const result = await getDbExec().execute({
172
+ sql: `UPDATE clips_backfill_leases
173
+ SET expires_at = ?
174
+ WHERE lease_key = ? AND holder = ? AND expires_at > ?`,
175
+ args: [
176
+ Date.now() + RECORDING_ORG_ID_BACKFILL_LEASE_MS,
177
+ RECORDING_ORG_ID_BACKFILL_LEASE_KEY,
178
+ recordingOrgIdBackfillHolder,
179
+ Date.now(),
180
+ ],
181
+ });
182
+ return result.rowsAffected > 0;
183
+ }
184
+
185
+ async function backfillRecordingOrgIdsInBatches(): Promise<void> {
186
+ if (!(await acquireRecordingOrgIdBackfillLease())) return;
187
+ const exec = getDbExec();
188
+ try {
189
+ for (;;) {
190
+ if (!(await renewRecordingOrgIdBackfillLease())) return;
191
+ // guard:allow-unscoped — this is a leased, bounded one-time repair over
192
+ // historical recordings whose org id was never populated.
193
+ const result = await exec.execute({
194
+ sql: `UPDATE recordings
195
+ SET org_id = workspace_id
196
+ WHERE id IN (
197
+ SELECT id FROM recordings
198
+ WHERE org_id IS NULL AND workspace_id IS NOT NULL
199
+ ORDER BY id
200
+ LIMIT ?
201
+ )`,
202
+ args: [RECORDING_ORG_ID_BACKFILL_BATCH_SIZE],
203
+ });
204
+ if (result.rowsAffected === 0) return;
205
+ await new Promise<void>((resolve) =>
206
+ setTimeout(resolve, RECORDING_ORG_ID_BACKFILL_DELAY_MS),
207
+ );
208
+ }
209
+ } catch (err) {
210
+ console.warn(
211
+ "[db] recording org-id backfill failed; it will retry in a later process:",
212
+ (err as Error)?.message ?? err,
213
+ );
214
+ } finally {
215
+ await exec
216
+ .execute({
217
+ sql: `DELETE FROM clips_backfill_leases
218
+ WHERE lease_key = ? AND holder = ?`,
219
+ args: [
220
+ RECORDING_ORG_ID_BACKFILL_LEASE_KEY,
221
+ recordingOrgIdBackfillHolder,
222
+ ],
223
+ })
224
+ .catch(() => undefined);
225
+ }
226
+ }
227
+
228
+ function scheduleRecordingOrgIdBackfill(): void {
229
+ const timer = setTimeout(() => {
230
+ void backfillRecordingOrgIdsInBatches();
231
+ }, 1_000);
232
+ if (typeof timer.unref === "function") timer.unref();
233
+ }
234
+
92
235
  // Convention: every new migration below MUST set a unique `name:` slug (see
93
236
  // packages/core/src/db/migrations.ts for the full rationale). Version numbers
94
237
  // alone are not a safe identity across parallel branches that each extend
@@ -946,6 +1089,63 @@ const migrations = runMigrations(
946
1089
  CREATE UNIQUE INDEX IF NOT EXISTS recording_playback_positions_recording_viewer_key_unique_idx
947
1090
  ON recording_playback_positions (recording_id, viewer_key)`,
948
1091
  },
1092
+ {
1093
+ version: 59,
1094
+ name: "backfill-recording-org-id",
1095
+ // Keep the repair's lease in schema migrations, but run the historical
1096
+ // data update below in bounded background batches after boot.
1097
+ sql: `CREATE TABLE IF NOT EXISTS clips_backfill_leases (
1098
+ lease_key TEXT PRIMARY KEY,
1099
+ holder TEXT NOT NULL,
1100
+ expires_at INTEGER NOT NULL
1101
+ )`,
1102
+ },
1103
+ {
1104
+ version: 60,
1105
+ name: "backfill-legacy-clips-tables",
1106
+ // Run-only: this copies legacy rows forward in a way SQL alone cannot
1107
+ // express. It used to sit in the plugin body and re-ran on every cold
1108
+ // start; nothing writes the legacy tables any more, so it is a one-time
1109
+ // historical migration and belongs here. A throw leaves it unrecorded
1110
+ // and it retries on the next boot.
1111
+ sql: {},
1112
+ run: backfillLegacyClipsTables,
1113
+ },
1114
+ {
1115
+ version: 61,
1116
+ name: "sync-workspaces-to-organizations",
1117
+ // Run-only, and ordered after the legacy backfill exactly as the plugin
1118
+ // body ran them. Nothing inserts into `workspaces` anywhere in the app
1119
+ // any more, so this is a one-time backfill of historical rows rather
1120
+ // than an ongoing reconciliation — there is nothing new to sync. It
1121
+ // returns `deferMigration()` while the framework's org tables are still
1122
+ // missing, so a first-boot race leaves it pending instead of applied.
1123
+ sql: {},
1124
+ run: syncWorkspacesToOrganizations,
1125
+ },
1126
+ {
1127
+ version: 62,
1128
+ name: "retype-boolean-columns-postgres",
1129
+ // Run-only: the retype is driven by a fixed historical list of columns
1130
+ // that predate BOOLEAN, and it probes information_schema to decide. Once
1131
+ // applied it can never have anything left to do, so recording it removes
1132
+ // the probe from the boot path entirely instead of paying it forever.
1133
+ // No-ops on SQLite, which never had the wrong type.
1134
+ sql: {},
1135
+ run: retypeBooleanColumnsOnPostgres,
1136
+ },
1137
+ {
1138
+ version: 63,
1139
+ name: "recording-org-id-backfill-lease-table",
1140
+ // v59 was already applied on some deployments before the data repair was
1141
+ // moved off startup. This additive no-op makes the lease table available
1142
+ // there as well, without re-running or blocking on the old UPDATE.
1143
+ sql: `CREATE TABLE IF NOT EXISTS clips_backfill_leases (
1144
+ lease_key TEXT PRIMARY KEY,
1145
+ holder TEXT NOT NULL,
1146
+ expires_at INTEGER NOT NULL
1147
+ )`,
1148
+ },
949
1149
  ],
950
1150
  { table: "clips_migrations" },
951
1151
  );
@@ -966,7 +1166,7 @@ const migrations = runMigrations(
966
1166
  * inserts are guarded with WHERE-NOT-EXISTS so it only writes rows that
967
1167
  * aren't there yet.
968
1168
  */
969
- async function syncWorkspacesToOrganizations(): Promise<void> {
1169
+ async function syncWorkspacesToOrganizations(): Promise<MigrationRunResult> {
970
1170
  const exec = getDbExec();
971
1171
  const pg = isPostgres();
972
1172
 
@@ -1000,7 +1200,12 @@ async function syncWorkspacesToOrganizations(): Promise<void> {
1000
1200
  !(await hasTable("org_members")) ||
1001
1201
  !(await hasTable("organization_settings"))
1002
1202
  ) {
1003
- return;
1203
+ // As a tracked migration this must NOT be recorded as applied when the
1204
+ // framework's org tables simply have not been created yet — recording it
1205
+ // would mean the sync never runs and historical workspaces never become
1206
+ // organizations. Deferring leaves the entry pending so the next boot
1207
+ // retries it, without logging a startup failure.
1208
+ return deferMigration();
1004
1209
  }
1005
1210
 
1006
1211
  // 1) Copy workspaces → organizations. Use the workspace id as the org id
@@ -1230,20 +1435,6 @@ async function syncWorkspacesToOrganizations(): Promise<void> {
1230
1435
  }
1231
1436
  }
1232
1437
 
1233
- async function backfillRecordingOrgId(): Promise<void> {
1234
- const exec = getDbExec();
1235
- try {
1236
- await exec.execute(
1237
- `UPDATE recordings SET org_id = workspace_id WHERE org_id IS NULL AND workspace_id IS NOT NULL`,
1238
- );
1239
- } catch (err) {
1240
- console.warn(
1241
- "[db] backfill recording org_id failed:",
1242
- (err as Error)?.message ?? err,
1243
- );
1244
- }
1245
- }
1246
-
1247
1438
  function assertSafeIdentifier(name: string): string {
1248
1439
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
1249
1440
  throw new Error(`Unsafe SQL identifier: ${name}`);
@@ -1483,10 +1674,6 @@ async function backfillLegacyClipsTables(): Promise<void> {
1483
1674
  */
1484
1675
  export default async (nitroApp: any): Promise<void> => {
1485
1676
  await migrations(nitroApp);
1486
- await retypeBooleanColumnsOnPostgres();
1487
- await backfillLegacyClipsTables();
1488
- await syncWorkspacesToOrganizations();
1489
- await backfillRecordingOrgId();
1490
1677
  try {
1491
1678
  const summary = await ensureAdditiveColumns({
1492
1679
  db: getDbExec(),
@@ -1506,6 +1693,7 @@ export default async (nitroApp: any): Promise<void> => {
1506
1693
  err instanceof Error ? err.message : err,
1507
1694
  );
1508
1695
  }
1696
+ scheduleRecordingOrgIdBackfill();
1509
1697
 
1510
1698
  // ---------------------------------------------------------------------------
1511
1699
  // Register Clips template events for the automations system.