@agent-native/core 0.85.7 → 0.86.1

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 (1132) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +133 -1
  3. package/corpus/core/README.md +0 -11
  4. package/corpus/core/docs/content/cloneable-saas.mdx +0 -1
  5. package/corpus/core/docs/content/locales/ar-SA/cloneable-saas.mdx +0 -1
  6. package/corpus/core/docs/content/locales/ar-SA/plan-plugin.mdx +10 -9
  7. package/corpus/core/docs/content/locales/ar-SA/sharing.mdx +1 -2
  8. package/corpus/core/docs/content/locales/ar-SA/skills-guide.mdx +2 -3
  9. package/corpus/core/docs/content/locales/ar-SA/template-plan.mdx +23 -7
  10. package/corpus/core/docs/content/locales/ar-SA/tracking.mdx +1 -1
  11. package/corpus/core/docs/content/locales/ar-SA/workspace-connections.mdx +11 -11
  12. package/corpus/core/docs/content/locales/de-DE/cloneable-saas.mdx +0 -1
  13. package/corpus/core/docs/content/locales/de-DE/plan-plugin.mdx +10 -9
  14. package/corpus/core/docs/content/locales/de-DE/sharing.mdx +1 -2
  15. package/corpus/core/docs/content/locales/de-DE/skills-guide.mdx +2 -3
  16. package/corpus/core/docs/content/locales/de-DE/template-plan.mdx +23 -7
  17. package/corpus/core/docs/content/locales/de-DE/tracking.mdx +1 -1
  18. package/corpus/core/docs/content/locales/de-DE/workspace-connections.mdx +1 -1
  19. package/corpus/core/docs/content/locales/es-ES/cloneable-saas.mdx +0 -1
  20. package/corpus/core/docs/content/locales/es-ES/plan-plugin.mdx +10 -9
  21. package/corpus/core/docs/content/locales/es-ES/sharing.mdx +1 -2
  22. package/corpus/core/docs/content/locales/es-ES/skills-guide.mdx +2 -3
  23. package/corpus/core/docs/content/locales/es-ES/template-plan.mdx +23 -7
  24. package/corpus/core/docs/content/locales/es-ES/tracking.mdx +1 -1
  25. package/corpus/core/docs/content/locales/es-ES/workspace-connections.mdx +1 -1
  26. package/corpus/core/docs/content/locales/fr-FR/cloneable-saas.mdx +0 -1
  27. package/corpus/core/docs/content/locales/fr-FR/plan-plugin.mdx +10 -9
  28. package/corpus/core/docs/content/locales/fr-FR/sharing.mdx +1 -2
  29. package/corpus/core/docs/content/locales/fr-FR/skills-guide.mdx +2 -3
  30. package/corpus/core/docs/content/locales/fr-FR/template-plan.mdx +23 -7
  31. package/corpus/core/docs/content/locales/fr-FR/tracking.mdx +1 -1
  32. package/corpus/core/docs/content/locales/fr-FR/workspace-connections.mdx +1 -1
  33. package/corpus/core/docs/content/locales/hi-IN/cloneable-saas.mdx +0 -1
  34. package/corpus/core/docs/content/locales/hi-IN/plan-plugin.mdx +10 -9
  35. package/corpus/core/docs/content/locales/hi-IN/sharing.mdx +1 -2
  36. package/corpus/core/docs/content/locales/hi-IN/skills-guide.mdx +2 -3
  37. package/corpus/core/docs/content/locales/hi-IN/template-plan.mdx +23 -7
  38. package/corpus/core/docs/content/locales/hi-IN/tracking.mdx +1 -1
  39. package/corpus/core/docs/content/locales/hi-IN/workspace-connections.mdx +1 -1
  40. package/corpus/core/docs/content/locales/ja-JP/cloneable-saas.mdx +0 -1
  41. package/corpus/core/docs/content/locales/ja-JP/plan-plugin.mdx +10 -9
  42. package/corpus/core/docs/content/locales/ja-JP/sharing.mdx +1 -2
  43. package/corpus/core/docs/content/locales/ja-JP/skills-guide.mdx +2 -3
  44. package/corpus/core/docs/content/locales/ja-JP/template-plan.mdx +23 -7
  45. package/corpus/core/docs/content/locales/ja-JP/tracking.mdx +1 -1
  46. package/corpus/core/docs/content/locales/ja-JP/workspace-connections.mdx +1 -1
  47. package/corpus/core/docs/content/locales/ko-KR/cloneable-saas.mdx +0 -1
  48. package/corpus/core/docs/content/locales/ko-KR/plan-plugin.mdx +10 -9
  49. package/corpus/core/docs/content/locales/ko-KR/sharing.mdx +1 -2
  50. package/corpus/core/docs/content/locales/ko-KR/skills-guide.mdx +2 -3
  51. package/corpus/core/docs/content/locales/ko-KR/template-plan.mdx +23 -7
  52. package/corpus/core/docs/content/locales/ko-KR/tracking.mdx +1 -1
  53. package/corpus/core/docs/content/locales/ko-KR/workspace-connections.mdx +1 -1
  54. package/corpus/core/docs/content/locales/pt-BR/cloneable-saas.mdx +0 -1
  55. package/corpus/core/docs/content/locales/pt-BR/plan-plugin.mdx +10 -9
  56. package/corpus/core/docs/content/locales/pt-BR/sharing.mdx +1 -2
  57. package/corpus/core/docs/content/locales/pt-BR/skills-guide.mdx +2 -3
  58. package/corpus/core/docs/content/locales/pt-BR/template-plan.mdx +23 -7
  59. package/corpus/core/docs/content/locales/pt-BR/tracking.mdx +1 -1
  60. package/corpus/core/docs/content/locales/pt-BR/workspace-connections.mdx +1 -1
  61. package/corpus/core/docs/content/locales/zh-CN/cloneable-saas.mdx +0 -1
  62. package/corpus/core/docs/content/locales/zh-CN/plan-plugin.mdx +10 -9
  63. package/corpus/core/docs/content/locales/zh-CN/sharing.mdx +1 -2
  64. package/corpus/core/docs/content/locales/zh-CN/skills-guide.mdx +2 -3
  65. package/corpus/core/docs/content/locales/zh-CN/template-plan.mdx +23 -7
  66. package/corpus/core/docs/content/locales/zh-CN/tracking.mdx +1 -1
  67. package/corpus/core/docs/content/locales/zh-CN/workspace-connections.mdx +1 -1
  68. package/corpus/core/docs/content/locales/zh-TW/cloneable-saas.mdx +0 -1
  69. package/corpus/core/docs/content/locales/zh-TW/plan-plugin.mdx +10 -9
  70. package/corpus/core/docs/content/locales/zh-TW/sharing.mdx +1 -2
  71. package/corpus/core/docs/content/locales/zh-TW/skills-guide.mdx +2 -3
  72. package/corpus/core/docs/content/locales/zh-TW/template-plan.mdx +23 -7
  73. package/corpus/core/docs/content/locales/zh-TW/tracking.mdx +1 -1
  74. package/corpus/core/docs/content/locales/zh-TW/workspace-connections.mdx +1 -1
  75. package/corpus/core/docs/content/plan-plugin.mdx +12 -11
  76. package/corpus/core/docs/content/sharing.mdx +1 -2
  77. package/corpus/core/docs/content/skills-guide.mdx +4 -3
  78. package/corpus/core/docs/content/template-plan.mdx +37 -6
  79. package/corpus/core/docs/content/tracking.mdx +1 -1
  80. package/corpus/core/docs/content/workspace-connections.mdx +1 -1
  81. package/corpus/core/package.json +7 -6
  82. package/corpus/core/src/agent/run-store.ts +1 -1
  83. package/corpus/core/src/chat-threads/store.ts +73 -11
  84. package/corpus/core/src/checkpoints/store.ts +13 -2
  85. package/corpus/core/src/cli/create.ts +3 -4
  86. package/corpus/core/src/cli/design-connect.ts +469 -9
  87. package/corpus/core/src/cli/index.ts +13 -0
  88. package/corpus/core/src/cli/plan-local.ts +281 -24
  89. package/corpus/core/src/cli/skills.ts +177 -21
  90. package/corpus/core/src/cli/templates-meta.ts +0 -13
  91. package/corpus/core/src/cli/visualize-repo.ts +715 -0
  92. package/corpus/core/src/client/AgentPanel.tsx +10 -0
  93. package/corpus/core/src/client/AssistantChat.tsx +194 -21
  94. package/corpus/core/src/client/ErrorBoundary.tsx +67 -12
  95. package/corpus/core/src/client/ErrorReportActions.tsx +69 -0
  96. package/corpus/core/src/client/FeedbackButton.tsx +8 -4
  97. package/corpus/core/src/client/agent-chat-adapter.ts +6 -5
  98. package/corpus/core/src/client/app-providers.tsx +2 -2
  99. package/corpus/core/src/client/collab/index.ts +31 -0
  100. package/corpus/core/src/client/components/LiveCursorOverlay.tsx +16 -1
  101. package/corpus/core/src/client/components/PresenceBar.tsx +14 -1
  102. package/corpus/core/src/client/components/RecentEditHighlights.tsx +219 -0
  103. package/corpus/core/src/client/components/RemoteSelectionRings.tsx +40 -6
  104. package/corpus/core/src/client/db-admin/DbAdminPage.tsx +41 -13
  105. package/corpus/core/src/client/db-admin/SqlEditor.tsx +10 -3
  106. package/corpus/core/src/client/db-admin/TableEditor.tsx +12 -5
  107. package/corpus/core/src/client/db-admin/useAgentSync.ts +10 -3
  108. package/corpus/core/src/client/db-admin/useDbAdmin.ts +65 -16
  109. package/corpus/core/src/client/error-reporting.ts +100 -0
  110. package/corpus/core/src/client/index.ts +59 -0
  111. package/corpus/core/src/client/org/OrgSwitcher.tsx +0 -4
  112. package/corpus/core/src/client/org/RequireActiveOrg.tsx +12 -0
  113. package/corpus/core/src/client/rich-markdown-editor/SharedRichEditor.tsx +49 -32
  114. package/corpus/core/src/client/rich-markdown-editor/index.ts +6 -0
  115. package/corpus/core/src/client/rich-markdown-editor/surgical-apply.ts +192 -0
  116. package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +59 -8
  117. package/corpus/core/src/client/session-replay.ts +181 -15
  118. package/corpus/core/src/client/sse-event-processor.ts +90 -1
  119. package/corpus/core/src/client/use-action.ts +123 -25
  120. package/corpus/core/src/client/use-agent-engine-configured.ts +7 -1
  121. package/corpus/core/src/client/use-chat-threads.ts +18 -7
  122. package/corpus/core/src/client/use-db-sync.ts +104 -19
  123. package/corpus/core/src/client/visual-style-controls.tsx +1088 -0
  124. package/corpus/core/src/collab/agent-presence.ts +191 -62
  125. package/corpus/core/src/collab/awareness.ts +83 -6
  126. package/corpus/core/src/collab/client.ts +89 -146
  127. package/corpus/core/src/collab/index.ts +34 -0
  128. package/corpus/core/src/collab/recent-edits.ts +171 -0
  129. package/corpus/core/src/collab/undo.ts +432 -0
  130. package/corpus/core/src/collab/ydoc-manager.ts +68 -0
  131. package/corpus/core/src/connections/catalog.ts +2 -3
  132. package/corpus/core/src/db/create-get-db.ts +86 -1
  133. package/corpus/core/src/db/ensure-additive-columns.ts +430 -0
  134. package/corpus/core/src/db/index.ts +6 -0
  135. package/corpus/core/src/db/migrations.ts +236 -35
  136. package/corpus/core/src/db-admin/index.ts +26 -0
  137. package/corpus/core/src/db-admin/operations.ts +87 -49
  138. package/corpus/core/src/jobs/scheduler.ts +17 -14
  139. package/corpus/core/src/localization/default-messages.ts +4 -0
  140. package/corpus/core/src/observability/traces.ts +182 -1
  141. package/corpus/core/src/org/context.ts +79 -2
  142. package/corpus/core/src/server/agent-chat-plugin.ts +10 -6
  143. package/corpus/core/src/server/auth-marketing.ts +0 -11
  144. package/corpus/core/src/server/auth.ts +11 -4
  145. package/corpus/core/src/server/builder-design-systems.ts +328 -9
  146. package/corpus/core/src/server/collab-plugin.ts +56 -13
  147. package/corpus/core/src/server/design-token-utils.ts +1 -1
  148. package/corpus/core/src/server/fusion-app.ts +447 -0
  149. package/corpus/core/src/server/index.ts +28 -0
  150. package/corpus/core/src/server/onboarding-html.ts +3 -4
  151. package/corpus/core/src/server/poll-events.ts +14 -2
  152. package/corpus/core/src/server/poll.ts +219 -12
  153. package/corpus/core/src/server/schema-prompt.ts +28 -9
  154. package/corpus/core/src/settings/store.ts +33 -2
  155. package/corpus/core/src/sharing/actions/set-resource-visibility.ts +2 -0
  156. package/corpus/core/src/sharing/actions/share-resource.ts +3 -0
  157. package/corpus/core/src/sharing/actions/unshare-resource.ts +2 -0
  158. package/corpus/core/src/styles/agent-native.css +0 -5
  159. package/corpus/core/src/templates/default/.agents/skills/real-time-collab/SKILL.md +82 -19
  160. package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +15 -0
  161. package/corpus/core/src/templates/default/.agents/skills/storing-data/SKILL.md +8 -0
  162. package/corpus/core/src/templates/default/app/root.tsx +47 -0
  163. package/corpus/core/src/templates/default/package.json +3 -3
  164. package/corpus/core/src/templates/workspace-core/.agents/skills/client-methods/SKILL.md +8 -0
  165. package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +22 -0
  166. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +82 -19
  167. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +15 -0
  168. package/corpus/core/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +8 -0
  169. package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -0
  170. package/corpus/core/src/tracking/providers.ts +22 -1
  171. package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +15 -0
  172. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +20 -5
  173. package/corpus/templates/analytics/.agents/skills/storing-data/SKILL.md +8 -0
  174. package/corpus/templates/analytics/AGENTS.md +35 -6
  175. package/corpus/templates/analytics/actions/delete-db-admin-connection.ts +19 -0
  176. package/corpus/templates/analytics/actions/list-db-admin-connections.ts +18 -0
  177. package/corpus/templates/analytics/actions/navigate.ts +28 -4
  178. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
  179. package/corpus/templates/analytics/actions/save-db-admin-connection.ts +33 -0
  180. package/corpus/templates/analytics/actions/view-screen.ts +65 -0
  181. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +23 -1
  182. package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -0
  183. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +21 -0
  184. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +16 -0
  185. package/corpus/templates/analytics/app/i18n/zh-TW.ts +36 -1
  186. package/corpus/templates/analytics/app/i18n-data.ts +361 -10
  187. package/corpus/templates/analytics/app/pages/Agents.tsx +512 -0
  188. package/corpus/templates/analytics/app/pages/DataSources.tsx +11 -1
  189. package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +76 -40
  190. package/corpus/templates/analytics/app/pages/sessions/session-replay-devtools.ts +5 -0
  191. package/corpus/templates/analytics/app/routes/agents.tsx +10 -0
  192. package/corpus/templates/analytics/changelog/2026-07-03-agent-admin-tools-page.md +6 -0
  193. package/corpus/templates/analytics/changelog/2026-07-03-agent-llm-observability-dashboard.md +6 -0
  194. package/corpus/templates/analytics/changelog/2026-07-03-connect-other-app-databases-from-analytics.md +6 -0
  195. package/corpus/templates/analytics/changelog/2026-07-03-session-recordings-now-include-response-bodies-for-5xx-error.md +6 -0
  196. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +34 -0
  197. package/corpus/templates/analytics/docs/schemas/tracked-events.md +6 -0
  198. package/corpus/templates/analytics/package.json +3 -3
  199. package/corpus/templates/analytics/seeds/dashboards/agent-observability-llm.json +173 -0
  200. package/corpus/templates/analytics/server/db/schema.ts +27 -0
  201. package/corpus/templates/analytics/server/jobs/analytics-alerts.ts +23 -5
  202. package/corpus/templates/analytics/server/lib/analytics-alerts.ts +58 -13
  203. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +23 -0
  204. package/corpus/templates/analytics/server/lib/dashboard-seeds.ts +5 -0
  205. package/corpus/templates/analytics/server/lib/db-admin-connections.ts +458 -0
  206. package/corpus/templates/analytics/server/lib/session-replay-agent-context.ts +120 -8
  207. package/corpus/templates/analytics/server/lib/session-replay.ts +3 -2
  208. package/corpus/templates/analytics/server/plugins/db.ts +128 -2
  209. package/corpus/templates/analytics/server/routes/[base]/_agent-native/analytics-db-admin/[...path].ts +1 -0
  210. package/corpus/templates/analytics/server/routes/_agent-native/analytics-db-admin/[...path].ts +160 -0
  211. package/corpus/templates/analytics/server/routes/api/session-replay/agent-diagnostics.json.get.ts +45 -1
  212. package/corpus/templates/analytics/shared/session-replay-diagnostics.ts +10 -0
  213. package/corpus/templates/assets/.agents/skills/real-time-collab/SKILL.md +82 -19
  214. package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +15 -0
  215. package/corpus/templates/assets/.agents/skills/storing-data/SKILL.md +8 -0
  216. package/corpus/templates/assets/package.json +3 -3
  217. package/corpus/templates/assets/server/plugins/db.ts +63 -2
  218. package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +15 -0
  219. package/corpus/templates/brain/package.json +3 -3
  220. package/corpus/templates/brain/server/plugins/db.ts +75 -2
  221. package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +15 -0
  222. package/corpus/templates/calendar/.agents/skills/storing-data/SKILL.md +8 -0
  223. package/corpus/templates/calendar/package.json +3 -3
  224. package/corpus/templates/calendar/server/plugins/db.ts +64 -2
  225. package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +15 -0
  226. package/corpus/templates/chat/package.json +3 -3
  227. package/corpus/templates/clips/actions/finalize-recording.ts +50 -40
  228. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +8 -6
  229. package/corpus/templates/clips/app/routes/share.$shareId.tsx +3 -3
  230. package/corpus/templates/clips/changelog/2026-07-03-mobile-recording-pages-keep-videos-in-a-16-9-player-with-act.md +6 -0
  231. package/corpus/templates/clips/package.json +3 -3
  232. package/corpus/templates/clips/server/lib/recording-upload-state.ts +56 -0
  233. package/corpus/templates/clips/server/plugins/db.ts +68 -1
  234. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +27 -3
  235. package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +15 -0
  236. package/corpus/templates/content/.agents/skills/storing-data/SKILL.md +8 -0
  237. package/corpus/templates/content/actions/edit-document.ts +48 -1
  238. package/corpus/templates/content/actions/list-documents.ts +101 -94
  239. package/corpus/templates/content/actions/search-documents.ts +19 -3
  240. package/corpus/templates/content/actions/update-document.ts +54 -1
  241. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +127 -7
  242. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +97 -2
  243. package/corpus/templates/content/app/root.tsx +9 -0
  244. package/corpus/templates/content/changelog/2026-07-03-agent-document-edits-now-appear-as-a-live-collaborator-prese.md +6 -0
  245. package/corpus/templates/content/changelog/2026-07-03-document-search-and-list-views-load-faster-on-large-workspac.md +6 -0
  246. package/corpus/templates/content/changelog/2026-07-03-error-screens-now-include-a-feedback-button-with-debug-info.md +6 -0
  247. package/corpus/templates/content/package.json +3 -3
  248. package/corpus/templates/content/server/plugins/db.ts +57 -1
  249. package/corpus/templates/design/.agents/skills/full-app-build/SKILL.md +140 -0
  250. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +20 -0
  251. package/corpus/templates/design/AGENTS.md +63 -19
  252. package/corpus/templates/design/actions/add-fusion-screens.ts +91 -0
  253. package/corpus/templates/design/actions/apply-a11y-fix.ts +5 -1
  254. package/corpus/templates/design/actions/apply-component-prop-edit.ts +10 -2
  255. package/corpus/templates/design/actions/apply-fusion-edits.ts +161 -0
  256. package/corpus/templates/design/actions/apply-visual-edit.ts +34 -1
  257. package/corpus/templates/design/actions/create-component.ts +5 -1
  258. package/corpus/templates/design/actions/create-fusion-app.ts +202 -0
  259. package/corpus/templates/design/actions/deploy-fusion-app.ts +123 -0
  260. package/corpus/templates/design/actions/edit-design.ts +13 -16
  261. package/corpus/templates/design/actions/get-design-system.ts +21 -0
  262. package/corpus/templates/design/actions/get-fusion-deploy-status.ts +86 -0
  263. package/corpus/templates/design/actions/index-design-system-with-builder.ts +14 -37
  264. package/corpus/templates/design/actions/list-fusion-edits.ts +96 -0
  265. package/corpus/templates/design/actions/list-local-files.ts +133 -0
  266. package/corpus/templates/design/actions/push-fusion-app.ts +62 -0
  267. package/corpus/templates/design/actions/queue-fusion-edit.ts +112 -0
  268. package/corpus/templates/design/actions/read-local-file.ts +139 -0
  269. package/corpus/templates/design/actions/send-fusion-message.ts +69 -0
  270. package/corpus/templates/design/actions/sync-fusion-app.ts +196 -0
  271. package/corpus/templates/design/actions/write-local-file.ts +115 -14
  272. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +12 -0
  273. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +379 -0
  274. package/corpus/templates/design/app/components/design/EditPanel.tsx +149 -73
  275. package/corpus/templates/design/app/components/design/FusionAppBanner.tsx +328 -0
  276. package/corpus/templates/design/app/components/design/LayersPanel.tsx +148 -30
  277. package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +1 -1
  278. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +567 -6
  279. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +7 -98
  280. package/corpus/templates/design/app/components/design/code-workbench/ActivityBar.tsx +85 -0
  281. package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +466 -0
  282. package/corpus/templates/design/app/components/design/code-workbench/SideBar.tsx +114 -0
  283. package/corpus/templates/design/app/components/design/code-workbench/commands.ts +339 -0
  284. package/corpus/templates/design/app/components/design/code-workbench/editor/Breadcrumbs.tsx +42 -0
  285. package/corpus/templates/design/app/components/design/code-workbench/editor/BufferSync.tsx +128 -0
  286. package/corpus/templates/design/app/components/design/code-workbench/editor/EditorTabs.tsx +372 -0
  287. package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +268 -0
  288. package/corpus/templates/design/app/components/design/code-workbench/editor/StatusBar.tsx +208 -0
  289. package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-setup.ts +61 -0
  290. package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-theme-palette.ts +191 -0
  291. package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-theme.ts +29 -0
  292. package/corpus/templates/design/app/components/design/code-workbench/editor/status-bar-lang.ts +21 -0
  293. package/corpus/templates/design/app/components/design/code-workbench/editor/tab-drag.ts +27 -0
  294. package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +161 -0
  295. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +555 -0
  296. package/corpus/templates/design/app/components/design/code-workbench/explorer/file-icons.tsx +115 -0
  297. package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open.ts +65 -0
  298. package/corpus/templates/design/app/components/design/code-workbench/format/prettier-format.ts +182 -0
  299. package/corpus/templates/design/app/components/design/code-workbench/model-registry.ts +133 -0
  300. package/corpus/templates/design/app/components/design/code-workbench/quickinput/QuickInput.tsx +563 -0
  301. package/corpus/templates/design/app/components/design/code-workbench/quickinput/fuzzy.ts +170 -0
  302. package/corpus/templates/design/app/components/design/code-workbench/search/SearchView.tsx +508 -0
  303. package/corpus/templates/design/app/components/design/code-workbench/search/search-engine.ts +280 -0
  304. package/corpus/templates/design/app/components/design/code-workbench/store.tsx +782 -0
  305. package/corpus/templates/design/app/components/design/code-workbench/workspace/create-providers.ts +39 -0
  306. package/corpus/templates/design/app/components/design/code-workbench/workspace/inline-provider.ts +196 -0
  307. package/corpus/templates/design/app/components/design/code-workbench/workspace/localhost-provider.ts +177 -0
  308. package/corpus/templates/design/app/components/design/code-workbench/workspace/tree.ts +110 -0
  309. package/corpus/templates/design/app/components/design/code-workbench/workspace/types.ts +103 -0
  310. package/corpus/templates/design/app/components/design/code-workbench-theme.ts +68 -0
  311. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +127 -10
  312. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +52 -29
  313. package/corpus/templates/design/app/components/design/inspector/index.ts +9 -0
  314. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +56 -0
  315. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +80 -1
  316. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +6 -16
  317. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +6 -0
  318. package/corpus/templates/design/app/i18n/zh-TW.ts +17 -15
  319. package/corpus/templates/design/app/i18n-data.ts +185 -160
  320. package/corpus/templates/design/app/pages/DesignEditor.tsx +1474 -175
  321. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +32 -14
  322. package/corpus/templates/design/app/pages/Index.tsx +90 -17
  323. package/corpus/templates/design/changelog/2026-07-03-design-system-setup-now-indexes-figma-code-and-design-md-sou.md +6 -0
  324. package/corpus/templates/design/changelog/2026-07-03-the-ai-now-edits-like-a-collaborator-on-canvas-its-cursor-gl.md +6 -0
  325. package/corpus/templates/design/changelog/2026-07-03-the-code-editor-is-easier-to-use-with-top-sidebar-tabs-clear.md +6 -0
  326. package/corpus/templates/design/changelog/2026-07-03-the-code-panel-is-now-a-full-vs-code-style-editor-with-a-fil.md +6 -0
  327. package/corpus/templates/design/package.json +4 -3
  328. package/corpus/templates/design/server/db/schema.ts +31 -0
  329. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +16 -106
  330. package/corpus/templates/design/server/lib/fusion-screens.ts +246 -0
  331. package/corpus/templates/design/server/plugins/db.ts +89 -2
  332. package/corpus/templates/design/shared/collab-selection.ts +52 -0
  333. package/corpus/templates/design/shared/full-app.ts +126 -0
  334. package/corpus/templates/design/shared/pen-path.ts +296 -0
  335. package/corpus/templates/dispatch/package.json +3 -3
  336. package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +15 -0
  337. package/corpus/templates/forms/.agents/skills/storing-data/SKILL.md +8 -0
  338. package/corpus/templates/forms/package.json +3 -3
  339. package/corpus/templates/forms/server/plugins/db.ts +62 -2
  340. package/corpus/templates/macros/package.json +3 -3
  341. package/corpus/templates/macros/server/plugins/db.ts +63 -2
  342. package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +15 -0
  343. package/corpus/templates/mail/.agents/skills/storing-data/SKILL.md +8 -0
  344. package/corpus/templates/mail/app/root.tsx +60 -1
  345. package/corpus/templates/mail/changelog/2026-07-03-error-screens-now-include-a-feedback-button-with-debug-info.md +6 -0
  346. package/corpus/templates/mail/package.json +3 -3
  347. package/corpus/templates/mail/server/lib/contact-frequency.ts +42 -15
  348. package/corpus/templates/mail/server/plugins/db.ts +63 -2
  349. package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +15 -0
  350. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +9 -3
  351. package/corpus/templates/plan/.agents/skills/visualize-repo/SKILL.md +92 -0
  352. package/corpus/templates/plan/actions/export-visual-plan.ts +5 -0
  353. package/corpus/templates/plan/actions/get-local-plan-folder.ts +4 -22
  354. package/corpus/templates/plan/actions/get-plan-version.ts +6 -16
  355. package/corpus/templates/plan/actions/list-plan-versions.ts +48 -20
  356. package/corpus/templates/plan/actions/patch-visual-plan-source.ts +41 -1
  357. package/corpus/templates/plan/actions/promote-local-plan-folder.ts +4 -22
  358. package/corpus/templates/plan/actions/update-local-plan-comments.ts +4 -2
  359. package/corpus/templates/plan/actions/update-local-plan-folder.ts +4 -22
  360. package/corpus/templates/plan/actions/update-visual-plan.ts +60 -1
  361. package/corpus/templates/plan/agent-native.app-skill.json +10 -0
  362. package/corpus/templates/plan/app/components/editor/PlanDocumentEditor.tsx +138 -39
  363. package/corpus/templates/plan/app/components/editor/usePlanUndoStack.ts +165 -23
  364. package/corpus/templates/plan/app/components/plan/PlanContentRenderer.tsx +80 -4
  365. package/corpus/templates/plan/app/global.css +11 -9
  366. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +10 -1
  367. package/corpus/templates/plan/app/hooks/use-plan-presence.ts +66 -0
  368. package/corpus/templates/plan/app/i18n/ar-SA.ts +3 -0
  369. package/corpus/templates/plan/app/i18n/de-DE.ts +4 -0
  370. package/corpus/templates/plan/app/i18n/en-US.ts +4 -0
  371. package/corpus/templates/plan/app/i18n/es-ES.ts +4 -0
  372. package/corpus/templates/plan/app/i18n/fr-FR.ts +4 -0
  373. package/corpus/templates/plan/app/i18n/hi-IN.ts +3 -0
  374. package/corpus/templates/plan/app/i18n/ja-JP.ts +4 -0
  375. package/corpus/templates/plan/app/i18n/ko-KR.ts +4 -0
  376. package/corpus/templates/plan/app/i18n/pt-BR.ts +4 -0
  377. package/corpus/templates/plan/app/i18n/zh-CN.ts +3 -0
  378. package/corpus/templates/plan/app/i18n/zh-TW.ts +3 -0
  379. package/corpus/templates/plan/app/pages/PlansPage.tsx +289 -66
  380. package/corpus/templates/plan/changelog/2026-07-03-error-screens-now-include-a-feedback-button-with-debug-info.md +6 -0
  381. package/corpus/templates/plan/changelog/2026-07-03-local-visual-plans-and-recaps-can-save-comments-without-sign.md +6 -0
  382. package/corpus/templates/plan/changelog/2026-07-03-plan-tabs-render-nested-text-instead-of-raw-json.md +6 -0
  383. package/corpus/templates/plan/changelog/2026-07-03-plans-are-now-fully-real-time-collaborative-multiple-people-.md +6 -0
  384. package/corpus/templates/plan/changelog/2026-07-03-plans-open-and-refresh-faster-especially-long-lived-plans-wi.md +6 -0
  385. package/corpus/templates/plan/changelog/2026-07-03-undo-now-survives-agent-edits-cmd-z-keeps-working-on-your-ow.md +6 -0
  386. package/corpus/templates/plan/package.json +5 -3
  387. package/corpus/templates/plan/server/db/schema.ts +12 -0
  388. package/corpus/templates/plan/server/lib/local-plan-kind.ts +25 -0
  389. package/corpus/templates/plan/server/lib/plan-versions.ts +83 -1
  390. package/corpus/templates/plan/server/lib/public-action-paths.ts +0 -2
  391. package/corpus/templates/plan/server/plans.ts +26 -3
  392. package/corpus/templates/plan/server/plugins/db.ts +105 -2
  393. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +8 -4
  394. package/corpus/templates/slides/AGENTS.md +11 -3
  395. package/corpus/templates/slides/actions/_agent-presence.ts +48 -0
  396. package/corpus/templates/slides/actions/add-slide.ts +16 -18
  397. package/corpus/templates/slides/actions/get-design-system.ts +21 -0
  398. package/corpus/templates/slides/actions/import-file.ts +15 -7
  399. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +14 -37
  400. package/corpus/templates/slides/actions/patch-deck.ts +4 -2
  401. package/corpus/templates/slides/actions/update-slide.ts +114 -77
  402. package/corpus/templates/slides/actions/view-screen.ts +39 -0
  403. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +32 -8
  404. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +47 -3
  405. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +34 -39
  406. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +507 -72
  407. package/corpus/templates/slides/app/components/editor/SlideStyleInspector.tsx +346 -0
  408. package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +56 -6
  409. package/corpus/templates/slides/app/components/editor/TweaksPanel.tsx +46 -96
  410. package/corpus/templates/slides/app/components/layout/Layout.tsx +6 -1
  411. package/corpus/templates/slides/app/components/visual-editor/SaveStatusIndicator.tsx +8 -1
  412. package/corpus/templates/slides/app/context/DeckContext.tsx +589 -176
  413. package/corpus/templates/slides/app/hooks/use-deck-presence.ts +84 -42
  414. package/corpus/templates/slides/app/i18n/ar-SA.ts +54 -7
  415. package/corpus/templates/slides/app/i18n/de-DE.ts +53 -8
  416. package/corpus/templates/slides/app/i18n/en-US.ts +54 -7
  417. package/corpus/templates/slides/app/i18n/es-ES.ts +53 -8
  418. package/corpus/templates/slides/app/i18n/fr-FR.ts +53 -8
  419. package/corpus/templates/slides/app/i18n/hi-IN.ts +54 -7
  420. package/corpus/templates/slides/app/i18n/ja-JP.ts +53 -8
  421. package/corpus/templates/slides/app/i18n/ko-KR.ts +53 -7
  422. package/corpus/templates/slides/app/i18n/pt-BR.ts +53 -8
  423. package/corpus/templates/slides/app/i18n/zh-CN.ts +54 -7
  424. package/corpus/templates/slides/app/i18n/zh-TW.ts +54 -7
  425. package/corpus/templates/slides/app/lib/canvas-zoom.ts +16 -1
  426. package/corpus/templates/slides/app/pages/DeckEditor.tsx +28 -16
  427. package/corpus/templates/slides/changelog/2026-07-03-design-system-setup-now-indexes-figma-code-and-design-md-sou.md +6 -0
  428. package/corpus/templates/slides/changelog/2026-07-03-figma-style-slide-editing.md +6 -0
  429. package/corpus/templates/slides/changelog/2026-07-03-see-the-ai-working-with-you-when-the-agent-edits-a-slide-it-.md +6 -0
  430. package/corpus/templates/slides/changelog/2026-07-03-slide-editing-now-keeps-thumbnails-speaker-notes-styling-and.md +6 -0
  431. package/corpus/templates/slides/changelog/2026-07-03-undo-redo-is-now-precise-and-safe-with-collaborators-it-only.md +6 -0
  432. package/corpus/templates/slides/package.json +3 -3
  433. package/corpus/templates/slides/server/handlers/decks.ts +31 -3
  434. package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +16 -104
  435. package/corpus/templates/slides/server/plugins/db.ts +65 -2
  436. package/corpus/templates/videos/netlify.toml +1 -12
  437. package/dist/agent/run-store.js +1 -1
  438. package/dist/agent/run-store.js.map +1 -1
  439. package/dist/chat-threads/store.d.ts +9 -1
  440. package/dist/chat-threads/store.d.ts.map +1 -1
  441. package/dist/chat-threads/store.js +63 -11
  442. package/dist/chat-threads/store.js.map +1 -1
  443. package/dist/checkpoints/store.d.ts.map +1 -1
  444. package/dist/checkpoints/store.js +10 -2
  445. package/dist/checkpoints/store.js.map +1 -1
  446. package/dist/cli/create.d.ts.map +1 -1
  447. package/dist/cli/create.js +3 -5
  448. package/dist/cli/create.js.map +1 -1
  449. package/dist/cli/design-connect.d.ts +49 -1
  450. package/dist/cli/design-connect.d.ts.map +1 -1
  451. package/dist/cli/design-connect.js +414 -9
  452. package/dist/cli/design-connect.js.map +1 -1
  453. package/dist/cli/index.js +12 -0
  454. package/dist/cli/index.js.map +1 -1
  455. package/dist/cli/plan-local.d.ts +24 -0
  456. package/dist/cli/plan-local.d.ts.map +1 -1
  457. package/dist/cli/plan-local.js +188 -20
  458. package/dist/cli/plan-local.js.map +1 -1
  459. package/dist/cli/skills.d.ts +3 -1
  460. package/dist/cli/skills.d.ts.map +1 -1
  461. package/dist/cli/skills.js +173 -21
  462. package/dist/cli/skills.js.map +1 -1
  463. package/dist/cli/templates-meta.d.ts.map +1 -1
  464. package/dist/cli/templates-meta.js +0 -14
  465. package/dist/cli/templates-meta.js.map +1 -1
  466. package/dist/cli/visualize-repo.d.ts +49 -0
  467. package/dist/cli/visualize-repo.d.ts.map +1 -0
  468. package/dist/cli/visualize-repo.js +561 -0
  469. package/dist/cli/visualize-repo.js.map +1 -0
  470. package/dist/client/AgentPanel.d.ts.map +1 -1
  471. package/dist/client/AgentPanel.js +2 -1
  472. package/dist/client/AgentPanel.js.map +1 -1
  473. package/dist/client/AssistantChat.d.ts.map +1 -1
  474. package/dist/client/AssistantChat.js +175 -18
  475. package/dist/client/AssistantChat.js.map +1 -1
  476. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  477. package/dist/client/ErrorBoundary.js +37 -2
  478. package/dist/client/ErrorBoundary.js.map +1 -1
  479. package/dist/client/ErrorReportActions.d.ts +13 -0
  480. package/dist/client/ErrorReportActions.d.ts.map +1 -0
  481. package/dist/client/ErrorReportActions.js +14 -0
  482. package/dist/client/ErrorReportActions.js.map +1 -0
  483. package/dist/client/FeedbackButton.d.ts +3 -1
  484. package/dist/client/FeedbackButton.d.ts.map +1 -1
  485. package/dist/client/FeedbackButton.js +6 -5
  486. package/dist/client/FeedbackButton.js.map +1 -1
  487. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  488. package/dist/client/agent-chat-adapter.js +6 -5
  489. package/dist/client/agent-chat-adapter.js.map +1 -1
  490. package/dist/client/app-providers.d.ts +2 -2
  491. package/dist/client/app-providers.js.map +1 -1
  492. package/dist/client/collab/index.d.ts +4 -1
  493. package/dist/client/collab/index.d.ts.map +1 -1
  494. package/dist/client/collab/index.js +3 -0
  495. package/dist/client/collab/index.js.map +1 -1
  496. package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -1
  497. package/dist/client/components/LiveCursorOverlay.js +11 -3
  498. package/dist/client/components/LiveCursorOverlay.js.map +1 -1
  499. package/dist/client/components/PresenceBar.d.ts.map +1 -1
  500. package/dist/client/components/PresenceBar.js +6 -1
  501. package/dist/client/components/PresenceBar.js.map +1 -1
  502. package/dist/client/components/RecentEditHighlights.d.ts +43 -0
  503. package/dist/client/components/RecentEditHighlights.d.ts.map +1 -0
  504. package/dist/client/components/RecentEditHighlights.js +146 -0
  505. package/dist/client/components/RecentEditHighlights.js.map +1 -0
  506. package/dist/client/components/RemoteSelectionRings.d.ts +9 -0
  507. package/dist/client/components/RemoteSelectionRings.d.ts.map +1 -1
  508. package/dist/client/components/RemoteSelectionRings.js +22 -8
  509. package/dist/client/components/RemoteSelectionRings.js.map +1 -1
  510. package/dist/client/db-admin/DbAdminPage.d.ts +9 -1
  511. package/dist/client/db-admin/DbAdminPage.d.ts.map +1 -1
  512. package/dist/client/db-admin/DbAdminPage.js +17 -13
  513. package/dist/client/db-admin/DbAdminPage.js.map +1 -1
  514. package/dist/client/db-admin/SqlEditor.d.ts +3 -1
  515. package/dist/client/db-admin/SqlEditor.d.ts.map +1 -1
  516. package/dist/client/db-admin/SqlEditor.js +3 -3
  517. package/dist/client/db-admin/SqlEditor.js.map +1 -1
  518. package/dist/client/db-admin/TableEditor.d.ts +3 -1
  519. package/dist/client/db-admin/TableEditor.d.ts.map +1 -1
  520. package/dist/client/db-admin/TableEditor.js +6 -6
  521. package/dist/client/db-admin/TableEditor.js.map +1 -1
  522. package/dist/client/db-admin/useAgentSync.d.ts +3 -2
  523. package/dist/client/db-admin/useAgentSync.d.ts.map +1 -1
  524. package/dist/client/db-admin/useAgentSync.js +8 -4
  525. package/dist/client/db-admin/useAgentSync.js.map +1 -1
  526. package/dist/client/db-admin/useDbAdmin.d.ts +11 -7
  527. package/dist/client/db-admin/useDbAdmin.d.ts.map +1 -1
  528. package/dist/client/db-admin/useDbAdmin.js +45 -20
  529. package/dist/client/db-admin/useDbAdmin.js.map +1 -1
  530. package/dist/client/error-reporting.d.ts +19 -0
  531. package/dist/client/error-reporting.d.ts.map +1 -0
  532. package/dist/client/error-reporting.js +71 -0
  533. package/dist/client/error-reporting.js.map +1 -0
  534. package/dist/client/index.d.ts +8 -1
  535. package/dist/client/index.d.ts.map +1 -1
  536. package/dist/client/index.js +9 -0
  537. package/dist/client/index.js.map +1 -1
  538. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  539. package/dist/client/org/OrgSwitcher.js +1 -3
  540. package/dist/client/org/OrgSwitcher.js.map +1 -1
  541. package/dist/client/org/RequireActiveOrg.d.ts.map +1 -1
  542. package/dist/client/org/RequireActiveOrg.js +2 -1
  543. package/dist/client/org/RequireActiveOrg.js.map +1 -1
  544. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts +8 -1
  545. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts.map +1 -1
  546. package/dist/client/rich-markdown-editor/SharedRichEditor.js +8 -2
  547. package/dist/client/rich-markdown-editor/SharedRichEditor.js.map +1 -1
  548. package/dist/client/rich-markdown-editor/index.d.ts +1 -0
  549. package/dist/client/rich-markdown-editor/index.d.ts.map +1 -1
  550. package/dist/client/rich-markdown-editor/index.js +1 -0
  551. package/dist/client/rich-markdown-editor/index.js.map +1 -1
  552. package/dist/client/rich-markdown-editor/surgical-apply.d.ts +66 -0
  553. package/dist/client/rich-markdown-editor/surgical-apply.d.ts.map +1 -0
  554. package/dist/client/rich-markdown-editor/surgical-apply.js +147 -0
  555. package/dist/client/rich-markdown-editor/surgical-apply.js.map +1 -0
  556. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts +18 -2
  557. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
  558. package/dist/client/rich-markdown-editor/useCollabReconcile.js +39 -8
  559. package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
  560. package/dist/client/session-replay.d.ts +10 -1
  561. package/dist/client/session-replay.d.ts.map +1 -1
  562. package/dist/client/session-replay.js +134 -7
  563. package/dist/client/session-replay.js.map +1 -1
  564. package/dist/client/sse-event-processor.d.ts.map +1 -1
  565. package/dist/client/sse-event-processor.js +81 -1
  566. package/dist/client/sse-event-processor.js.map +1 -1
  567. package/dist/client/use-action.d.ts +24 -0
  568. package/dist/client/use-action.d.ts.map +1 -1
  569. package/dist/client/use-action.js +109 -27
  570. package/dist/client/use-action.js.map +1 -1
  571. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  572. package/dist/client/use-agent-engine-configured.js +7 -1
  573. package/dist/client/use-agent-engine-configured.js.map +1 -1
  574. package/dist/client/use-chat-threads.d.ts.map +1 -1
  575. package/dist/client/use-chat-threads.js +11 -3
  576. package/dist/client/use-chat-threads.js.map +1 -1
  577. package/dist/client/use-db-sync.d.ts +36 -0
  578. package/dist/client/use-db-sync.d.ts.map +1 -1
  579. package/dist/client/use-db-sync.js +68 -12
  580. package/dist/client/use-db-sync.js.map +1 -1
  581. package/dist/client/visual-style-controls.d.ts +90 -0
  582. package/dist/client/visual-style-controls.d.ts.map +1 -0
  583. package/dist/client/visual-style-controls.js +499 -0
  584. package/dist/client/visual-style-controls.js.map +1 -0
  585. package/dist/collab/agent-presence.d.ts +51 -5
  586. package/dist/collab/agent-presence.d.ts.map +1 -1
  587. package/dist/collab/agent-presence.js +144 -58
  588. package/dist/collab/agent-presence.js.map +1 -1
  589. package/dist/collab/awareness-store.d.ts +32 -0
  590. package/dist/collab/awareness-store.d.ts.map +1 -0
  591. package/dist/collab/awareness-store.js +0 -0
  592. package/dist/collab/awareness-store.js.map +1 -0
  593. package/dist/collab/awareness.d.ts +12 -1
  594. package/dist/collab/awareness.d.ts.map +1 -1
  595. package/dist/collab/awareness.js +53 -5
  596. package/dist/collab/awareness.js.map +1 -1
  597. package/dist/collab/client.d.ts +2 -0
  598. package/dist/collab/client.d.ts.map +1 -1
  599. package/dist/collab/client.js +79 -119
  600. package/dist/collab/client.js.map +1 -1
  601. package/dist/collab/index.d.ts +3 -1
  602. package/dist/collab/index.d.ts.map +1 -1
  603. package/dist/collab/index.js +5 -1
  604. package/dist/collab/index.js.map +1 -1
  605. package/dist/collab/recent-edits.d.ts +87 -0
  606. package/dist/collab/recent-edits.d.ts.map +1 -0
  607. package/dist/collab/recent-edits.js +116 -0
  608. package/dist/collab/recent-edits.js.map +1 -0
  609. package/dist/collab/routes.d.ts +1 -1
  610. package/dist/collab/undo.d.ts +121 -0
  611. package/dist/collab/undo.d.ts.map +1 -0
  612. package/dist/collab/undo.js +244 -0
  613. package/dist/collab/undo.js.map +1 -0
  614. package/dist/collab/ydoc-manager.d.ts +10 -0
  615. package/dist/collab/ydoc-manager.d.ts.map +1 -1
  616. package/dist/collab/ydoc-manager.js +57 -0
  617. package/dist/collab/ydoc-manager.js.map +1 -1
  618. package/dist/connections/catalog.d.ts +2 -2
  619. package/dist/connections/catalog.d.ts.map +1 -1
  620. package/dist/connections/catalog.js +1 -1
  621. package/dist/connections/catalog.js.map +1 -1
  622. package/dist/db/create-get-db.d.ts +22 -0
  623. package/dist/db/create-get-db.d.ts.map +1 -1
  624. package/dist/db/create-get-db.js +73 -1
  625. package/dist/db/create-get-db.js.map +1 -1
  626. package/dist/db/ensure-additive-columns.d.ts +93 -0
  627. package/dist/db/ensure-additive-columns.d.ts.map +1 -0
  628. package/dist/db/ensure-additive-columns.js +355 -0
  629. package/dist/db/ensure-additive-columns.js.map +1 -0
  630. package/dist/db/index.d.ts +1 -0
  631. package/dist/db/index.d.ts.map +1 -1
  632. package/dist/db/index.js +1 -0
  633. package/dist/db/index.js.map +1 -1
  634. package/dist/db/migrations.d.ts +70 -0
  635. package/dist/db/migrations.d.ts.map +1 -1
  636. package/dist/db/migrations.js +196 -33
  637. package/dist/db/migrations.js.map +1 -1
  638. package/dist/db-admin/index.d.ts +3 -0
  639. package/dist/db-admin/index.d.ts.map +1 -0
  640. package/dist/db-admin/index.js +2 -0
  641. package/dist/db-admin/index.js.map +1 -0
  642. package/dist/db-admin/operations.d.ts +26 -5
  643. package/dist/db-admin/operations.d.ts.map +1 -1
  644. package/dist/db-admin/operations.js +66 -55
  645. package/dist/db-admin/operations.js.map +1 -1
  646. package/dist/jobs/scheduler.js +17 -10
  647. package/dist/jobs/scheduler.js.map +1 -1
  648. package/dist/localization/default-messages.d.ts +3 -0
  649. package/dist/localization/default-messages.d.ts.map +1 -1
  650. package/dist/localization/default-messages.js +3 -0
  651. package/dist/localization/default-messages.js.map +1 -1
  652. package/dist/notifications/routes.d.ts +2 -2
  653. package/dist/observability/routes.d.ts +2 -2
  654. package/dist/observability/traces.d.ts.map +1 -1
  655. package/dist/observability/traces.js +155 -1
  656. package/dist/observability/traces.js.map +1 -1
  657. package/dist/org/context.d.ts +7 -0
  658. package/dist/org/context.d.ts.map +1 -1
  659. package/dist/org/context.js +54 -2
  660. package/dist/org/context.js.map +1 -1
  661. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  662. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  663. package/dist/server/agent-chat-plugin.js +10 -6
  664. package/dist/server/agent-chat-plugin.js.map +1 -1
  665. package/dist/server/auth-marketing.d.ts.map +1 -1
  666. package/dist/server/auth-marketing.js +0 -10
  667. package/dist/server/auth-marketing.js.map +1 -1
  668. package/dist/server/auth.d.ts.map +1 -1
  669. package/dist/server/auth.js +6 -4
  670. package/dist/server/auth.js.map +1 -1
  671. package/dist/server/builder-design-systems.d.ts +61 -0
  672. package/dist/server/builder-design-systems.d.ts.map +1 -1
  673. package/dist/server/builder-design-systems.js +219 -14
  674. package/dist/server/builder-design-systems.js.map +1 -1
  675. package/dist/server/collab-plugin.d.ts.map +1 -1
  676. package/dist/server/collab-plugin.js +45 -13
  677. package/dist/server/collab-plugin.js.map +1 -1
  678. package/dist/server/design-token-utils.d.ts +1 -1
  679. package/dist/server/design-token-utils.js +1 -1
  680. package/dist/server/design-token-utils.js.map +1 -1
  681. package/dist/server/fusion-app.d.ts +107 -0
  682. package/dist/server/fusion-app.d.ts.map +1 -0
  683. package/dist/server/fusion-app.js +371 -0
  684. package/dist/server/fusion-app.js.map +1 -0
  685. package/dist/server/index.d.ts +2 -1
  686. package/dist/server/index.d.ts.map +1 -1
  687. package/dist/server/index.js +2 -1
  688. package/dist/server/index.js.map +1 -1
  689. package/dist/server/onboarding-html.d.ts.map +1 -1
  690. package/dist/server/onboarding-html.js +3 -4
  691. package/dist/server/onboarding-html.js.map +1 -1
  692. package/dist/server/poll-events.d.ts +2 -0
  693. package/dist/server/poll-events.d.ts.map +1 -1
  694. package/dist/server/poll-events.js +7 -2
  695. package/dist/server/poll-events.js.map +1 -1
  696. package/dist/server/poll.d.ts +47 -3
  697. package/dist/server/poll.d.ts.map +1 -1
  698. package/dist/server/poll.js +176 -10
  699. package/dist/server/poll.js.map +1 -1
  700. package/dist/server/schema-prompt.d.ts.map +1 -1
  701. package/dist/server/schema-prompt.js +24 -7
  702. package/dist/server/schema-prompt.js.map +1 -1
  703. package/dist/settings/store.d.ts.map +1 -1
  704. package/dist/settings/store.js +32 -3
  705. package/dist/settings/store.js.map +1 -1
  706. package/dist/sharing/actions/set-resource-visibility.js +2 -0
  707. package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
  708. package/dist/sharing/actions/share-resource.d.ts.map +1 -1
  709. package/dist/sharing/actions/share-resource.js +3 -0
  710. package/dist/sharing/actions/share-resource.js.map +1 -1
  711. package/dist/sharing/actions/unshare-resource.js +2 -0
  712. package/dist/sharing/actions/unshare-resource.js.map +1 -1
  713. package/dist/styles/agent-native.css +0 -5
  714. package/dist/templates/default/.agents/skills/real-time-collab/SKILL.md +82 -19
  715. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +15 -0
  716. package/dist/templates/default/.agents/skills/storing-data/SKILL.md +8 -0
  717. package/dist/templates/default/app/root.tsx +47 -0
  718. package/dist/templates/default/package.json +3 -3
  719. package/dist/templates/workspace-core/.agents/skills/client-methods/SKILL.md +8 -0
  720. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +22 -0
  721. package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +82 -19
  722. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +15 -0
  723. package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +8 -0
  724. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -0
  725. package/dist/tracking/providers.d.ts.map +1 -1
  726. package/dist/tracking/providers.js +17 -1
  727. package/dist/tracking/providers.js.map +1 -1
  728. package/docs/content/cloneable-saas.mdx +0 -1
  729. package/docs/content/locales/ar-SA/cloneable-saas.mdx +0 -1
  730. package/docs/content/locales/ar-SA/plan-plugin.mdx +10 -9
  731. package/docs/content/locales/ar-SA/sharing.mdx +1 -2
  732. package/docs/content/locales/ar-SA/skills-guide.mdx +2 -3
  733. package/docs/content/locales/ar-SA/template-plan.mdx +23 -7
  734. package/docs/content/locales/ar-SA/tracking.mdx +1 -1
  735. package/docs/content/locales/ar-SA/workspace-connections.mdx +11 -11
  736. package/docs/content/locales/de-DE/cloneable-saas.mdx +0 -1
  737. package/docs/content/locales/de-DE/plan-plugin.mdx +10 -9
  738. package/docs/content/locales/de-DE/sharing.mdx +1 -2
  739. package/docs/content/locales/de-DE/skills-guide.mdx +2 -3
  740. package/docs/content/locales/de-DE/template-plan.mdx +23 -7
  741. package/docs/content/locales/de-DE/tracking.mdx +1 -1
  742. package/docs/content/locales/de-DE/workspace-connections.mdx +1 -1
  743. package/docs/content/locales/es-ES/cloneable-saas.mdx +0 -1
  744. package/docs/content/locales/es-ES/plan-plugin.mdx +10 -9
  745. package/docs/content/locales/es-ES/sharing.mdx +1 -2
  746. package/docs/content/locales/es-ES/skills-guide.mdx +2 -3
  747. package/docs/content/locales/es-ES/template-plan.mdx +23 -7
  748. package/docs/content/locales/es-ES/tracking.mdx +1 -1
  749. package/docs/content/locales/es-ES/workspace-connections.mdx +1 -1
  750. package/docs/content/locales/fr-FR/cloneable-saas.mdx +0 -1
  751. package/docs/content/locales/fr-FR/plan-plugin.mdx +10 -9
  752. package/docs/content/locales/fr-FR/sharing.mdx +1 -2
  753. package/docs/content/locales/fr-FR/skills-guide.mdx +2 -3
  754. package/docs/content/locales/fr-FR/template-plan.mdx +23 -7
  755. package/docs/content/locales/fr-FR/tracking.mdx +1 -1
  756. package/docs/content/locales/fr-FR/workspace-connections.mdx +1 -1
  757. package/docs/content/locales/hi-IN/cloneable-saas.mdx +0 -1
  758. package/docs/content/locales/hi-IN/plan-plugin.mdx +10 -9
  759. package/docs/content/locales/hi-IN/sharing.mdx +1 -2
  760. package/docs/content/locales/hi-IN/skills-guide.mdx +2 -3
  761. package/docs/content/locales/hi-IN/template-plan.mdx +23 -7
  762. package/docs/content/locales/hi-IN/tracking.mdx +1 -1
  763. package/docs/content/locales/hi-IN/workspace-connections.mdx +1 -1
  764. package/docs/content/locales/ja-JP/cloneable-saas.mdx +0 -1
  765. package/docs/content/locales/ja-JP/plan-plugin.mdx +10 -9
  766. package/docs/content/locales/ja-JP/sharing.mdx +1 -2
  767. package/docs/content/locales/ja-JP/skills-guide.mdx +2 -3
  768. package/docs/content/locales/ja-JP/template-plan.mdx +23 -7
  769. package/docs/content/locales/ja-JP/tracking.mdx +1 -1
  770. package/docs/content/locales/ja-JP/workspace-connections.mdx +1 -1
  771. package/docs/content/locales/ko-KR/cloneable-saas.mdx +0 -1
  772. package/docs/content/locales/ko-KR/plan-plugin.mdx +10 -9
  773. package/docs/content/locales/ko-KR/sharing.mdx +1 -2
  774. package/docs/content/locales/ko-KR/skills-guide.mdx +2 -3
  775. package/docs/content/locales/ko-KR/template-plan.mdx +23 -7
  776. package/docs/content/locales/ko-KR/tracking.mdx +1 -1
  777. package/docs/content/locales/ko-KR/workspace-connections.mdx +1 -1
  778. package/docs/content/locales/pt-BR/cloneable-saas.mdx +0 -1
  779. package/docs/content/locales/pt-BR/plan-plugin.mdx +10 -9
  780. package/docs/content/locales/pt-BR/sharing.mdx +1 -2
  781. package/docs/content/locales/pt-BR/skills-guide.mdx +2 -3
  782. package/docs/content/locales/pt-BR/template-plan.mdx +23 -7
  783. package/docs/content/locales/pt-BR/tracking.mdx +1 -1
  784. package/docs/content/locales/pt-BR/workspace-connections.mdx +1 -1
  785. package/docs/content/locales/zh-CN/cloneable-saas.mdx +0 -1
  786. package/docs/content/locales/zh-CN/plan-plugin.mdx +10 -9
  787. package/docs/content/locales/zh-CN/sharing.mdx +1 -2
  788. package/docs/content/locales/zh-CN/skills-guide.mdx +2 -3
  789. package/docs/content/locales/zh-CN/template-plan.mdx +23 -7
  790. package/docs/content/locales/zh-CN/tracking.mdx +1 -1
  791. package/docs/content/locales/zh-CN/workspace-connections.mdx +1 -1
  792. package/docs/content/locales/zh-TW/cloneable-saas.mdx +0 -1
  793. package/docs/content/locales/zh-TW/plan-plugin.mdx +10 -9
  794. package/docs/content/locales/zh-TW/sharing.mdx +1 -2
  795. package/docs/content/locales/zh-TW/skills-guide.mdx +2 -3
  796. package/docs/content/locales/zh-TW/template-plan.mdx +23 -7
  797. package/docs/content/locales/zh-TW/tracking.mdx +1 -1
  798. package/docs/content/locales/zh-TW/workspace-connections.mdx +1 -1
  799. package/docs/content/plan-plugin.mdx +12 -11
  800. package/docs/content/sharing.mdx +1 -2
  801. package/docs/content/skills-guide.mdx +4 -3
  802. package/docs/content/template-plan.mdx +37 -6
  803. package/docs/content/tracking.mdx +1 -1
  804. package/docs/content/workspace-connections.mdx +1 -1
  805. package/package.json +7 -6
  806. package/src/templates/default/.agents/skills/real-time-collab/SKILL.md +82 -19
  807. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +15 -0
  808. package/src/templates/default/.agents/skills/storing-data/SKILL.md +8 -0
  809. package/src/templates/default/app/root.tsx +47 -0
  810. package/src/templates/default/package.json +3 -3
  811. package/src/templates/workspace-core/.agents/skills/client-methods/SKILL.md +8 -0
  812. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +22 -0
  813. package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +82 -19
  814. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +15 -0
  815. package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +8 -0
  816. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -0
  817. package/corpus/core/docs/content/locales/ar-SA/template-videos.mdx +0 -336
  818. package/corpus/core/docs/content/locales/de-DE/template-videos.mdx +0 -336
  819. package/corpus/core/docs/content/locales/es-ES/template-videos.mdx +0 -336
  820. package/corpus/core/docs/content/locales/fr-FR/template-videos.mdx +0 -336
  821. package/corpus/core/docs/content/locales/hi-IN/template-videos.mdx +0 -336
  822. package/corpus/core/docs/content/locales/ja-JP/template-videos.mdx +0 -336
  823. package/corpus/core/docs/content/locales/ko-KR/template-videos.mdx +0 -336
  824. package/corpus/core/docs/content/locales/pt-BR/template-videos.mdx +0 -336
  825. package/corpus/core/docs/content/locales/zh-CN/template-videos.mdx +0 -334
  826. package/corpus/core/docs/content/locales/zh-TW/template-videos.mdx +0 -334
  827. package/corpus/core/docs/content/template-videos.mdx +0 -332
  828. package/corpus/templates/design/app/components/design/CodeWorkbenchHost.tsx +0 -697
  829. package/corpus/templates/slides/app/components/editor/CodeEditor.tsx +0 -49
  830. package/corpus/templates/videos/.agents/skills/actions/SKILL.md +0 -432
  831. package/corpus/templates/videos/.agents/skills/animation-tracks/SKILL.md +0 -99
  832. package/corpus/templates/videos/.agents/skills/capture-learnings/SKILL.md +0 -76
  833. package/corpus/templates/videos/.agents/skills/composition-management/SKILL.md +0 -106
  834. package/corpus/templates/videos/.agents/skills/create-skill/SKILL.md +0 -221
  835. package/corpus/templates/videos/.agents/skills/delegate-to-agent/SKILL.md +0 -263
  836. package/corpus/templates/videos/.agents/skills/frontend-design/SKILL.md +0 -112
  837. package/corpus/templates/videos/.agents/skills/security/SKILL.md +0 -263
  838. package/corpus/templates/videos/.agents/skills/self-modifying-code/SKILL.md +0 -88
  839. package/corpus/templates/videos/.agents/skills/shadcn-ui/SKILL.md +0 -95
  840. package/corpus/templates/videos/.builder/ANIMATED_PROPERTIES.md +0 -335
  841. package/corpus/templates/videos/.builder/KEYFRAME_SYNC.md +0 -166
  842. package/corpus/templates/videos/.builder/SEAMLESS_SYNC.md +0 -211
  843. package/corpus/templates/videos/.builder/rules/deploy-app.mdc +0 -22
  844. package/corpus/templates/videos/.builder/rules/organize-ui.mdc +0 -9
  845. package/corpus/templates/videos/.builder/skills/remotion/SKILL.md +0 -29
  846. package/corpus/templates/videos/.builder/skills/remotion/rules/animations.md +0 -27
  847. package/corpus/templates/videos/.builder/skills/remotion/rules/assets.md +0 -43
  848. package/corpus/templates/videos/.builder/skills/remotion/rules/audio.md +0 -58
  849. package/corpus/templates/videos/.builder/skills/remotion/rules/compositions.md +0 -129
  850. package/corpus/templates/videos/.builder/skills/remotion/rules/fonts.md +0 -47
  851. package/corpus/templates/videos/.builder/skills/remotion/rules/images.md +0 -41
  852. package/corpus/templates/videos/.builder/skills/remotion/rules/parameters.md +0 -59
  853. package/corpus/templates/videos/.builder/skills/remotion/rules/sequencing.md +0 -54
  854. package/corpus/templates/videos/.builder/skills/remotion/rules/tailwind.md +0 -11
  855. package/corpus/templates/videos/.builder/skills/remotion/rules/text-animations.md +0 -18
  856. package/corpus/templates/videos/.builder/skills/remotion/rules/timing.md +0 -103
  857. package/corpus/templates/videos/.builder/skills/remotion/rules/transparent-videos.md +0 -35
  858. package/corpus/templates/videos/.builder/skills/remotion/rules/trimming.md +0 -38
  859. package/corpus/templates/videos/.builder/skills/remotion/rules/videos.md +0 -54
  860. package/corpus/templates/videos/.dockerignore +0 -62
  861. package/corpus/templates/videos/.env.example +0 -4
  862. package/corpus/templates/videos/.oxfmtrc.json +0 -8
  863. package/corpus/templates/videos/AGENTS.md +0 -46
  864. package/corpus/templates/videos/CHANGELOG.md +0 -10
  865. package/corpus/templates/videos/DEVELOPING.md +0 -143
  866. package/corpus/templates/videos/README.md +0 -33
  867. package/corpus/templates/videos/actions/analyze-brand-assets.ts +0 -151
  868. package/corpus/templates/videos/actions/apply-design-system.ts +0 -35
  869. package/corpus/templates/videos/actions/create-design-system.ts +0 -84
  870. package/corpus/templates/videos/actions/create-folder.ts +0 -48
  871. package/corpus/templates/videos/actions/db-connect.ts +0 -45
  872. package/corpus/templates/videos/actions/db-health.ts +0 -24
  873. package/corpus/templates/videos/actions/db-status.ts +0 -28
  874. package/corpus/templates/videos/actions/delete-composition.ts +0 -272
  875. package/corpus/templates/videos/actions/delete-folder.ts +0 -27
  876. package/corpus/templates/videos/actions/generate-animated-component.ts +0 -470
  877. package/corpus/templates/videos/actions/get-composition.ts +0 -36
  878. package/corpus/templates/videos/actions/get-design-system.ts +0 -35
  879. package/corpus/templates/videos/actions/import-code.ts +0 -67
  880. package/corpus/templates/videos/actions/import-design-project.ts +0 -42
  881. package/corpus/templates/videos/actions/import-document.ts +0 -125
  882. package/corpus/templates/videos/actions/import-from-url.ts +0 -18
  883. package/corpus/templates/videos/actions/import-github.ts +0 -182
  884. package/corpus/templates/videos/actions/list-compositions.ts +0 -32
  885. package/corpus/templates/videos/actions/list-design-systems.ts +0 -66
  886. package/corpus/templates/videos/actions/list-folders.ts +0 -61
  887. package/corpus/templates/videos/actions/move-composition-to-folder.ts +0 -59
  888. package/corpus/templates/videos/actions/navigate.ts +0 -40
  889. package/corpus/templates/videos/actions/rename-folder.ts +0 -41
  890. package/corpus/templates/videos/actions/run.ts +0 -2
  891. package/corpus/templates/videos/actions/save-composition.ts +0 -114
  892. package/corpus/templates/videos/actions/set-default-design-system.ts +0 -40
  893. package/corpus/templates/videos/actions/update-composition.ts +0 -81
  894. package/corpus/templates/videos/actions/update-design-system.ts +0 -68
  895. package/corpus/templates/videos/actions/validate-compositions.ts +0 -502
  896. package/corpus/templates/videos/actions/view-screen.ts +0 -48
  897. package/corpus/templates/videos/app/components/CameraControls.tsx +0 -442
  898. package/corpus/templates/videos/app/components/CameraToolbar.tsx +0 -437
  899. package/corpus/templates/videos/app/components/CloudUpgrade.tsx +0 -287
  900. package/corpus/templates/videos/app/components/CollabPresenceBar.tsx +0 -81
  901. package/corpus/templates/videos/app/components/CompSettingsEditor.tsx +0 -107
  902. package/corpus/templates/videos/app/components/ComponentLibrarySidebar.tsx +0 -457
  903. package/corpus/templates/videos/app/components/ComponentPropsPanel.tsx +0 -227
  904. package/corpus/templates/videos/app/components/ComponentsSidebar.tsx +0 -70
  905. package/corpus/templates/videos/app/components/CompositionCard.tsx +0 -147
  906. package/corpus/templates/videos/app/components/CurrentElementPanel.tsx +0 -835
  907. package/corpus/templates/videos/app/components/CursorControls.tsx +0 -664
  908. package/corpus/templates/videos/app/components/CursorPositioningOverlay.tsx +0 -238
  909. package/corpus/templates/videos/app/components/LibraryFolderRow.tsx +0 -235
  910. package/corpus/templates/videos/app/components/MotionCurveSelect.tsx +0 -61
  911. package/corpus/templates/videos/app/components/NewCompositionPopover.tsx +0 -192
  912. package/corpus/templates/videos/app/components/PropsEditor.tsx +0 -210
  913. package/corpus/templates/videos/app/components/QuestionFlow.tsx +0 -40
  914. package/corpus/templates/videos/app/components/Sidebar.tsx +0 -609
  915. package/corpus/templates/videos/app/components/StudioHeader.tsx +0 -109
  916. package/corpus/templates/videos/app/components/Timeline.tsx +0 -2067
  917. package/corpus/templates/videos/app/components/TrackPropertiesPanel.tsx +0 -922
  918. package/corpus/templates/videos/app/components/TweaksPanel.tsx +0 -277
  919. package/corpus/templates/videos/app/components/VideoPlayer.tsx +0 -487
  920. package/corpus/templates/videos/app/components/design-system/DesignSystemCard.tsx +0 -134
  921. package/corpus/templates/videos/app/components/design-system/DesignSystemPreview.tsx +0 -176
  922. package/corpus/templates/videos/app/components/design-system/DesignSystemSetup.tsx +0 -707
  923. package/corpus/templates/videos/app/components/keyframes/KeyframeActionButtons.tsx +0 -78
  924. package/corpus/templates/videos/app/components/keyframes/KeyframeNavigation.tsx +0 -59
  925. package/corpus/templates/videos/app/components/keyframes/PropertyNumberInput.tsx +0 -56
  926. package/corpus/templates/videos/app/components/layout/Header.tsx +0 -64
  927. package/corpus/templates/videos/app/components/layout/HeaderActions.tsx +0 -84
  928. package/corpus/templates/videos/app/components/layout/Layout.tsx +0 -132
  929. package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +0 -180
  930. package/corpus/templates/videos/app/components/ui/accordion.tsx +0 -56
  931. package/corpus/templates/videos/app/components/ui/alert-dialog.tsx +0 -139
  932. package/corpus/templates/videos/app/components/ui/alert.tsx +0 -59
  933. package/corpus/templates/videos/app/components/ui/aspect-ratio.tsx +0 -5
  934. package/corpus/templates/videos/app/components/ui/avatar.tsx +0 -48
  935. package/corpus/templates/videos/app/components/ui/badge.tsx +0 -37
  936. package/corpus/templates/videos/app/components/ui/breadcrumb.tsx +0 -115
  937. package/corpus/templates/videos/app/components/ui/button.tsx +0 -57
  938. package/corpus/templates/videos/app/components/ui/calendar.tsx +0 -68
  939. package/corpus/templates/videos/app/components/ui/card.tsx +0 -86
  940. package/corpus/templates/videos/app/components/ui/carousel.tsx +0 -260
  941. package/corpus/templates/videos/app/components/ui/chart.tsx +0 -375
  942. package/corpus/templates/videos/app/components/ui/checkbox.tsx +0 -28
  943. package/corpus/templates/videos/app/components/ui/collapsible.tsx +0 -9
  944. package/corpus/templates/videos/app/components/ui/command.tsx +0 -154
  945. package/corpus/templates/videos/app/components/ui/context-menu.tsx +0 -202
  946. package/corpus/templates/videos/app/components/ui/dialog.tsx +0 -130
  947. package/corpus/templates/videos/app/components/ui/drawer.tsx +0 -116
  948. package/corpus/templates/videos/app/components/ui/dropdown-menu.tsx +0 -212
  949. package/corpus/templates/videos/app/components/ui/form.tsx +0 -177
  950. package/corpus/templates/videos/app/components/ui/hover-card.tsx +0 -27
  951. package/corpus/templates/videos/app/components/ui/input-otp.tsx +0 -69
  952. package/corpus/templates/videos/app/components/ui/input.tsx +0 -22
  953. package/corpus/templates/videos/app/components/ui/label.tsx +0 -24
  954. package/corpus/templates/videos/app/components/ui/menubar.tsx +0 -234
  955. package/corpus/templates/videos/app/components/ui/navigation-menu.tsx +0 -128
  956. package/corpus/templates/videos/app/components/ui/pagination.tsx +0 -121
  957. package/corpus/templates/videos/app/components/ui/popover.tsx +0 -44
  958. package/corpus/templates/videos/app/components/ui/progress.tsx +0 -26
  959. package/corpus/templates/videos/app/components/ui/radio-group.tsx +0 -42
  960. package/corpus/templates/videos/app/components/ui/resizable.tsx +0 -43
  961. package/corpus/templates/videos/app/components/ui/scroll-area.tsx +0 -46
  962. package/corpus/templates/videos/app/components/ui/select.tsx +0 -158
  963. package/corpus/templates/videos/app/components/ui/separator.tsx +0 -29
  964. package/corpus/templates/videos/app/components/ui/sheet.tsx +0 -160
  965. package/corpus/templates/videos/app/components/ui/sidebar.tsx +0 -782
  966. package/corpus/templates/videos/app/components/ui/skeleton.tsx +0 -15
  967. package/corpus/templates/videos/app/components/ui/slider.tsx +0 -26
  968. package/corpus/templates/videos/app/components/ui/sonner.tsx +0 -58
  969. package/corpus/templates/videos/app/components/ui/spinner.tsx +0 -17
  970. package/corpus/templates/videos/app/components/ui/switch.tsx +0 -27
  971. package/corpus/templates/videos/app/components/ui/table.tsx +0 -117
  972. package/corpus/templates/videos/app/components/ui/tabs.tsx +0 -53
  973. package/corpus/templates/videos/app/components/ui/textarea.tsx +0 -23
  974. package/corpus/templates/videos/app/components/ui/toast.tsx +0 -127
  975. package/corpus/templates/videos/app/components/ui/toaster.tsx +0 -33
  976. package/corpus/templates/videos/app/components/ui/toggle-group.tsx +0 -59
  977. package/corpus/templates/videos/app/components/ui/toggle.tsx +0 -43
  978. package/corpus/templates/videos/app/components/ui/tooltip.tsx +0 -30
  979. package/corpus/templates/videos/app/components/ui/use-toast.ts +0 -3
  980. package/corpus/templates/videos/app/config/constants.ts +0 -204
  981. package/corpus/templates/videos/app/contexts/CompositionContext.tsx +0 -437
  982. package/corpus/templates/videos/app/contexts/CurrentElementContext.tsx +0 -247
  983. package/corpus/templates/videos/app/contexts/PlaybackContext.tsx +0 -65
  984. package/corpus/templates/videos/app/contexts/TimelineContext.tsx +0 -433
  985. package/corpus/templates/videos/app/entry.client.tsx +0 -19
  986. package/corpus/templates/videos/app/entry.server.tsx +0 -10
  987. package/corpus/templates/videos/app/global.css +0 -171
  988. package/corpus/templates/videos/app/hooks/use-composition-collab.ts +0 -269
  989. package/corpus/templates/videos/app/hooks/use-composition-design-system.ts +0 -47
  990. package/corpus/templates/videos/app/hooks/use-database-compositions.ts +0 -144
  991. package/corpus/templates/videos/app/hooks/use-db-status.ts +0 -30
  992. package/corpus/templates/videos/app/hooks/use-design-systems.ts +0 -21
  993. package/corpus/templates/videos/app/hooks/use-folders.ts +0 -199
  994. package/corpus/templates/videos/app/hooks/use-mobile.tsx +0 -21
  995. package/corpus/templates/videos/app/hooks/use-navigation-state.ts +0 -52
  996. package/corpus/templates/videos/app/hooks/use-question-flow.ts +0 -14
  997. package/corpus/templates/videos/app/hooks/use-toast.ts +0 -188
  998. package/corpus/templates/videos/app/hooks/useUnsavedChanges.ts +0 -48
  999. package/corpus/templates/videos/app/i18n/ar-SA.ts +0 -446
  1000. package/corpus/templates/videos/app/i18n/de-DE.ts +0 -470
  1001. package/corpus/templates/videos/app/i18n/en-US.ts +0 -452
  1002. package/corpus/templates/videos/app/i18n/es-ES.ts +0 -468
  1003. package/corpus/templates/videos/app/i18n/fr-FR.ts +0 -469
  1004. package/corpus/templates/videos/app/i18n/hi-IN.ts +0 -446
  1005. package/corpus/templates/videos/app/i18n/index.ts +0 -34
  1006. package/corpus/templates/videos/app/i18n/ja-JP.ts +0 -460
  1007. package/corpus/templates/videos/app/i18n/ko-KR.ts +0 -453
  1008. package/corpus/templates/videos/app/i18n/pt-BR.ts +0 -461
  1009. package/corpus/templates/videos/app/i18n/zh-CN.ts +0 -437
  1010. package/corpus/templates/videos/app/i18n/zh-TW.ts +0 -437
  1011. package/corpus/templates/videos/app/lib/database-compositions.ts +0 -67
  1012. package/corpus/templates/videos/app/lib/design-systems.ts +0 -234
  1013. package/corpus/templates/videos/app/lib/tab-id.ts +0 -1
  1014. package/corpus/templates/videos/app/lib/utils.ts +0 -1
  1015. package/corpus/templates/videos/app/pages/ComponentLibrary.tsx +0 -134
  1016. package/corpus/templates/videos/app/pages/ComponentLibraryView.tsx +0 -362
  1017. package/corpus/templates/videos/app/pages/CompositionView.tsx +0 -715
  1018. package/corpus/templates/videos/app/pages/DesignSystems.tsx +0 -180
  1019. package/corpus/templates/videos/app/pages/Index.tsx +0 -258
  1020. package/corpus/templates/videos/app/pages/NewComposition.tsx +0 -95
  1021. package/corpus/templates/videos/app/pages/NotFound.tsx +0 -36
  1022. package/corpus/templates/videos/app/remotion/CameraHost.tsx +0 -223
  1023. package/corpus/templates/videos/app/remotion/animations/useElementAnimations.ts +0 -231
  1024. package/corpus/templates/videos/app/remotion/componentRegistry.ts +0 -473
  1025. package/corpus/templates/videos/app/remotion/components/AnimatedElement.tsx +0 -436
  1026. package/corpus/templates/videos/app/remotion/components/InteractiveElement.tsx +0 -159
  1027. package/corpus/templates/videos/app/remotion/components/InteractiveZoneEditor.tsx +0 -273
  1028. package/corpus/templates/videos/app/remotion/compositions/BlankComposition.tsx +0 -204
  1029. package/corpus/templates/videos/app/remotion/compositions/index.ts +0 -2
  1030. package/corpus/templates/videos/app/remotion/createComponentCursorTrack.ts +0 -132
  1031. package/corpus/templates/videos/app/remotion/docs/CURSOR_TRACKS.md +0 -285
  1032. package/corpus/templates/videos/app/remotion/easingFunctions.ts +0 -255
  1033. package/corpus/templates/videos/app/remotion/hooks/createInteractiveComposition.tsx +0 -283
  1034. package/corpus/templates/videos/app/remotion/hooks/useCursorHistory.ts +0 -72
  1035. package/corpus/templates/videos/app/remotion/hooks/useCursorTypeFromHover.ts +0 -35
  1036. package/corpus/templates/videos/app/remotion/hooks/useEditableZones.tsx +0 -267
  1037. package/corpus/templates/videos/app/remotion/hooks/useHoverAnimation.ts +0 -90
  1038. package/corpus/templates/videos/app/remotion/hooks/useHoverAnimationSmooth.ts +0 -146
  1039. package/corpus/templates/videos/app/remotion/hooks/useInteractiveComponent.ts +0 -711
  1040. package/corpus/templates/videos/app/remotion/hooks/useRegisterInteractiveElement.ts +0 -56
  1041. package/corpus/templates/videos/app/remotion/library-components/Button.tsx +0 -252
  1042. package/corpus/templates/videos/app/remotion/library-components/Card.tsx +0 -241
  1043. package/corpus/templates/videos/app/remotion/library-components/CodePanel.tsx +0 -1005
  1044. package/corpus/templates/videos/app/remotion/library-components/FileItem.tsx +0 -196
  1045. package/corpus/templates/videos/app/remotion/library-components/FolderItem.tsx +0 -199
  1046. package/corpus/templates/videos/app/remotion/library-components/PrimaryButton.tsx +0 -177
  1047. package/corpus/templates/videos/app/remotion/library-components/SecondaryButton.tsx +0 -167
  1048. package/corpus/templates/videos/app/remotion/library-components/SectionHeader.tsx +0 -108
  1049. package/corpus/templates/videos/app/remotion/library-components/TEMPLATE.tsx +0 -211
  1050. package/corpus/templates/videos/app/remotion/library-components/index.ts +0 -10
  1051. package/corpus/templates/videos/app/remotion/registry.ts +0 -91
  1052. package/corpus/templates/videos/app/remotion/testing/animationTestUtils.ts +0 -366
  1053. package/corpus/templates/videos/app/remotion/trackAnimation.ts +0 -179
  1054. package/corpus/templates/videos/app/remotion/trackHelpers.ts +0 -110
  1055. package/corpus/templates/videos/app/remotion/ui-components/Cursor.tsx +0 -182
  1056. package/corpus/templates/videos/app/remotion/ui-components/InteractiveButton.tsx +0 -116
  1057. package/corpus/templates/videos/app/remotion/ui-components/InteractiveCard.tsx +0 -126
  1058. package/corpus/templates/videos/app/remotion/ui-components/index.ts +0 -16
  1059. package/corpus/templates/videos/app/remotion/utils/animationHelpers.ts +0 -444
  1060. package/corpus/templates/videos/app/remotion/utils/interactiveElements.ts +0 -235
  1061. package/corpus/templates/videos/app/remotion/utils/springAnimation.ts +0 -76
  1062. package/corpus/templates/videos/app/root.tsx +0 -165
  1063. package/corpus/templates/videos/app/routes/$.tsx +0 -10
  1064. package/corpus/templates/videos/app/routes/_index.tsx +0 -25
  1065. package/corpus/templates/videos/app/routes/c.$compositionId.tsx +0 -10
  1066. package/corpus/templates/videos/app/routes/components.tsx +0 -10
  1067. package/corpus/templates/videos/app/routes/design-systems.tsx +0 -10
  1068. package/corpus/templates/videos/app/routes/extensions.$id.$slug.tsx +0 -2
  1069. package/corpus/templates/videos/app/routes/extensions.$id.tsx +0 -5
  1070. package/corpus/templates/videos/app/routes/extensions._index.tsx +0 -5
  1071. package/corpus/templates/videos/app/routes/extensions.tsx +0 -5
  1072. package/corpus/templates/videos/app/routes/settings.tsx +0 -88
  1073. package/corpus/templates/videos/app/routes/team.tsx +0 -11
  1074. package/corpus/templates/videos/app/routes.ts +0 -4
  1075. package/corpus/templates/videos/app/state.ts +0 -77
  1076. package/corpus/templates/videos/app/types/elementAnimations.ts +0 -121
  1077. package/corpus/templates/videos/app/types.ts +0 -200
  1078. package/corpus/templates/videos/app/utils/compositionHelpers.ts +0 -445
  1079. package/corpus/templates/videos/app/utils/debug.ts +0 -63
  1080. package/corpus/templates/videos/app/utils/keyframeUtils.ts +0 -331
  1081. package/corpus/templates/videos/app/utils/timelineCoordinates.ts +0 -79
  1082. package/corpus/templates/videos/app/vite-env.d.ts +0 -6
  1083. package/corpus/templates/videos/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +0 -6
  1084. package/corpus/templates/videos/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +0 -6
  1085. package/corpus/templates/videos/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +0 -6
  1086. package/corpus/templates/videos/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +0 -6
  1087. package/corpus/templates/videos/changelog/2026-06-29-video-layouts-adapt-when-the-agent-sidebar-is-open.md +0 -6
  1088. package/corpus/templates/videos/components.json +0 -20
  1089. package/corpus/templates/videos/data/sync-config.json +0 -3
  1090. package/corpus/templates/videos/docs/examples/create-composition.example.ts +0 -128
  1091. package/corpus/templates/videos/drizzle.config.ts +0 -3
  1092. package/corpus/templates/videos/learnings.defaults.md +0 -5
  1093. package/corpus/templates/videos/package.json +0 -114
  1094. package/corpus/templates/videos/public/agent-native-icon-dark.svg +0 -10
  1095. package/corpus/templates/videos/public/agent-native-icon-light.svg +0 -10
  1096. package/corpus/templates/videos/public/agent-native-logo-dark.svg +0 -21
  1097. package/corpus/templates/videos/public/agent-native-logo-light.svg +0 -21
  1098. package/corpus/templates/videos/public/favicon.svg +0 -1
  1099. package/corpus/templates/videos/public/icon-180.svg +0 -1
  1100. package/corpus/templates/videos/public/icon-192.svg +0 -1
  1101. package/corpus/templates/videos/public/icon-512.svg +0 -1
  1102. package/corpus/templates/videos/public/manifest.json +0 -21
  1103. package/corpus/templates/videos/public/placeholder.svg +0 -1
  1104. package/corpus/templates/videos/public/robots.txt +0 -14
  1105. package/corpus/templates/videos/react-router.config.ts +0 -7
  1106. package/corpus/templates/videos/server/db/index.ts +0 -37
  1107. package/corpus/templates/videos/server/db/schema.ts +0 -55
  1108. package/corpus/templates/videos/server/middleware/auth.ts +0 -15
  1109. package/corpus/templates/videos/server/plugins/agent-chat.ts +0 -29
  1110. package/corpus/templates/videos/server/plugins/auth.ts +0 -14
  1111. package/corpus/templates/videos/server/plugins/collab.ts +0 -11
  1112. package/corpus/templates/videos/server/plugins/core-routes.ts +0 -22
  1113. package/corpus/templates/videos/server/plugins/db.ts +0 -160
  1114. package/corpus/templates/videos/server/routes/[...page].get.ts +0 -5
  1115. package/corpus/templates/videos/server/routes/[...page].head.ts +0 -1
  1116. package/corpus/templates/videos/server/routes/api/save-composition-defaults.post.ts +0 -274
  1117. package/corpus/templates/videos/shared/api.ts +0 -75
  1118. package/corpus/templates/videos/ssr-entry.ts +0 -15
  1119. package/corpus/templates/videos/tsconfig.json +0 -21
  1120. package/corpus/templates/videos/vite.config.ts +0 -19
  1121. package/corpus/templates/videos/vitest.config.ts +0 -16
  1122. package/docs/content/locales/ar-SA/template-videos.mdx +0 -336
  1123. package/docs/content/locales/de-DE/template-videos.mdx +0 -336
  1124. package/docs/content/locales/es-ES/template-videos.mdx +0 -336
  1125. package/docs/content/locales/fr-FR/template-videos.mdx +0 -336
  1126. package/docs/content/locales/hi-IN/template-videos.mdx +0 -336
  1127. package/docs/content/locales/ja-JP/template-videos.mdx +0 -336
  1128. package/docs/content/locales/ko-KR/template-videos.mdx +0 -336
  1129. package/docs/content/locales/pt-BR/template-videos.mdx +0 -336
  1130. package/docs/content/locales/zh-CN/template-videos.mdx +0 -334
  1131. package/docs/content/locales/zh-TW/template-videos.mdx +0 -334
  1132. package/docs/content/template-videos.mdx +0 -332
@@ -15,7 +15,18 @@ let _migrationExecPromise = null;
15
15
  let _migrationExecRefCount = 0;
16
16
  async function acquireMigrationExec() {
17
17
  if (!_migrationExecPromise) {
18
- _migrationExecPromise = createDbExec({ url: getMigrationDatabaseUrl() });
18
+ const opened = createDbExec({ url: getMigrationDatabaseUrl() });
19
+ _migrationExecPromise = opened;
20
+ opened.catch(() => {
21
+ // Opening the connection failed. Reset the shared state so the next
22
+ // caller retries with a fresh connection instead of awaiting this
23
+ // permanently rejected promise — and zero the ref count, because none
24
+ // of the awaiters that failed here will ever call release.
25
+ if (_migrationExecPromise === opened) {
26
+ _migrationExecPromise = null;
27
+ _migrationExecRefCount = 0;
28
+ }
29
+ });
19
30
  }
20
31
  _migrationExecRefCount++;
21
32
  return _migrationExecPromise;
@@ -149,6 +160,63 @@ function resolveMigrationSql(sql, pg) {
149
160
  const raw = pg ? sql.postgres : sql.sqlite;
150
161
  return raw ?? null;
151
162
  }
163
+ /**
164
+ * Runs a list of migrations against the configured database, gated by a
165
+ * per-table bookkeeping row (`options.table`) so repeated boots only apply
166
+ * new migrations.
167
+ *
168
+ * ## Name-based tracking (why it exists)
169
+ *
170
+ * The legacy gate is purely numeric: `SELECT MAX(version)` from the
171
+ * bookkeeping table, then apply every entry whose `version` is greater. That
172
+ * scheme silently breaks down when **two independent branches each extend the
173
+ * same migration list with different DDL under the same version numbers** —
174
+ * exactly what happened to the analytics template's v75-v83 range. Branch A
175
+ * shipped alert-rule tables as v75-v78; branch B shipped unrelated DDL as its
176
+ * own v75-v83. Whichever branch deployed first recorded "v75..v83 applied"
177
+ * in the bookkeeping table. When the other branch merged and deployed, its
178
+ * migrations at those same version numbers were never applied — `MAX(version)`
179
+ * was already ≥ their version, so the gate treated them as done even though
180
+ * their actual DDL had never run. The result: `analytics_migrations` showed
181
+ * rows for 1..83 with no gaps, yet `analytics_alert_rules`,
182
+ * `analytics_alert_incidents`, and `session_recordings.network_error_count`
183
+ * did not exist in production. Version numbers are not a stable identity —
184
+ * they're just sequence position, and sequence position collides across
185
+ * branches.
186
+ *
187
+ * Name-based tracking fixes this by keying application on a stable, unique
188
+ * **string slug** instead of a position in a shared integer sequence:
189
+ *
190
+ * - Entries with a `name` are recorded in a companion table,
191
+ * `${table}_named` (`name TEXT PRIMARY KEY`), and APPLY IFF their name is
192
+ * absent from that table — completely independent of version numbers or
193
+ * the legacy `MAX(version)` gate. Two branches can both ship a migration
194
+ * named `"analytics-alert-rules-table"` at version 75, or one at version 75
195
+ * and the other at version 90 after a rebase — either way it applies
196
+ * exactly once per database, keyed on the name.
197
+ * - Entries WITHOUT a `name` keep the exact legacy behavior
198
+ * (`version > MAX(recorded version)`), so nothing changes for existing
199
+ * unnamed migrations.
200
+ * - Named migrations still execute in list order, interleaved with unnamed
201
+ * ones exactly as written.
202
+ * - When a named migration's DDL runs, we record BOTH the named row (always)
203
+ * and — if its `version` is greater than the current legacy max — the
204
+ * legacy version row too, in the SAME atomic batch/transaction as the DDL.
205
+ * This keeps the legacy `MAX(version)` gate monotonically advancing for
206
+ * any unnamed migrations that come after it in the list, while ensuring a
207
+ * named migration is never "double recorded" in a way that would let it
208
+ * re-apply.
209
+ * - A duplicate `name` across the migration list throws at startup — that's
210
+ * a programmer error (copy-paste or merge mistake), not a runtime data
211
+ * problem, and failing loud beats silently tracking the wrong row.
212
+ *
213
+ * New migrations should always set a `name`. Legacy unnamed migrations don't
214
+ * need to be renamed retroactively — the two gating strategies coexist in the
215
+ * same list — but if a table is EVER at risk of being shared across parallel
216
+ * branches (any template's own migrations qualify, since branches routinely
217
+ * extend the same list concurrently), giving new entries a name is what makes
218
+ * them immune to the collision class described above.
219
+ */
152
220
  export function runMigrations(migrations, options) {
153
221
  const table = options?.table;
154
222
  if (!table ||
@@ -158,6 +226,21 @@ export function runMigrations(migrations, options) {
158
226
  '(e.g. `{ table: "slides_migrations" }`). See packages/core/src/db/migrations.ts ' +
159
227
  "for why this is required (shared-DB version-collision bug).");
160
228
  }
229
+ // Duplicate-name detection — programmer error, fail loud at startup rather
230
+ // than silently tracking the wrong migration's applied state.
231
+ {
232
+ const seenNames = new Set();
233
+ for (const m of migrations) {
234
+ if (!m.name)
235
+ continue;
236
+ if (seenNames.has(m.name)) {
237
+ throw new Error(`runMigrations: duplicate migration name "${m.name}" in the migration list for table "${table}". ` +
238
+ "Migration names must be unique — pick a different stable slug.");
239
+ }
240
+ seenNames.add(m.name);
241
+ }
242
+ }
243
+ const namedTable = `${table}_named`;
161
244
  return async () => {
162
245
  try {
163
246
  // Check for Cloudflare D1 binding (only if DATABASE_URL not set)
@@ -166,19 +249,39 @@ export function runMigrations(migrations, options) {
166
249
  await d1
167
250
  .prepare(`CREATE TABLE IF NOT EXISTS ${table} (version INTEGER PRIMARY KEY)`)
168
251
  .run();
252
+ await d1
253
+ .prepare(`CREATE TABLE IF NOT EXISTS ${namedTable} (name TEXT PRIMARY KEY, version INTEGER, applied_at TEXT NOT NULL DEFAULT (datetime('now')))`)
254
+ .run();
169
255
  const firstRow = await d1
170
256
  .prepare(`SELECT MAX(version) as v FROM ${table}`)
171
257
  .first();
172
258
  const current = firstRow?.v ?? 0;
173
- for (const m of migrations.filter((m) => m.version > current)) {
259
+ const appliedNamesRows = await d1
260
+ .prepare(`SELECT name FROM ${namedTable}`)
261
+ .all();
262
+ const appliedNames = new Set((appliedNamesRows?.results ?? []).map((r) => String(r.name)));
263
+ const pending = migrations.filter((m) => m.name ? !appliedNames.has(m.name) : m.version > current);
264
+ for (const m of pending) {
174
265
  try {
175
266
  // D1 is SQLite-compatible
176
267
  const raw = resolveMigrationSql(m.sql, false);
268
+ const recordStatements = [
269
+ m.name
270
+ ? d1
271
+ .prepare(`INSERT OR IGNORE INTO ${namedTable} (name, version) VALUES (?, ?)`)
272
+ .bind(m.name, m.version)
273
+ : null,
274
+ m.version > current
275
+ ? d1
276
+ .prepare(`INSERT OR IGNORE INTO ${table} VALUES (?)`)
277
+ .bind(m.version)
278
+ : null,
279
+ ].filter((s) => s != null);
177
280
  if (raw == null) {
178
- await d1
179
- .prepare(`INSERT OR IGNORE INTO ${table} VALUES (?)`)
180
- .bind(m.version)
181
- .run();
281
+ // Dialect-gated migration with no SQL for this dialect; still
282
+ // record it so we don't retry forever.
283
+ for (const stmt of recordStatements)
284
+ await stmt.run();
182
285
  continue;
183
286
  }
184
287
  const originalStatements = splitSqlStatements(raw);
@@ -203,26 +306,22 @@ export function runMigrations(migrations, options) {
203
306
  throw err;
204
307
  }
205
308
  }
206
- await d1
207
- .prepare(`INSERT OR IGNORE INTO ${table} VALUES (?)`)
208
- .bind(m.version)
209
- .run();
309
+ for (const stmt of recordStatements)
310
+ await stmt.run();
210
311
  }
211
312
  else {
212
- // Atomic batch: all statements + version-row insert land in
313
+ // Atomic batch: all statements + bookkeeping inserts land in
213
314
  // the same transaction. A failing statement rolls the whole
214
- // migration back, so we never record a half-applied version.
315
+ // migration back, so we never record a half-applied migration.
215
316
  await d1.batch([
216
317
  ...statements.map((s) => d1.prepare(s.sql)),
217
- d1
218
- .prepare(`INSERT OR IGNORE INTO ${table} VALUES (?)`)
219
- .bind(m.version),
318
+ ...recordStatements,
220
319
  ]);
221
320
  }
222
- console.log(`[db] Applied migration v${m.version} (${statements.length} statement${statements.length === 1 ? "" : "s"})`);
321
+ console.log(`[db] Applied migration ${m.name ? `"${m.name}" ` : ""}v${m.version} (${statements.length} statement${statements.length === 1 ? "" : "s"})`);
223
322
  }
224
323
  catch (err) {
225
- console.error(`[db] Migration v${m.version} FAILED:`, err.message, "\nSQL:", JSON.stringify(m.sql));
324
+ console.error(`[db] Migration ${m.name ? `"${m.name}" ` : ""}v${m.version} FAILED:`, err.message, "\nSQL:", JSON.stringify(m.sql));
226
325
  throw err;
227
326
  }
228
327
  }
@@ -249,6 +348,11 @@ export function runMigrations(migrations, options) {
249
348
  // caller via releaseMigrationExec().
250
349
  // ---------------------------------------------------------------------------
251
350
  let current = -1; // sentinel: "table missing" → treat all as pending
351
+ let namedRowsMissing = false; // sentinel: "named table missing" → no names applied yet
352
+ // Any migration with a `name` is a candidate regardless of version, so
353
+ // the fast-path "anything pending?" check must also account for names.
354
+ const hasNamedMigrations = migrations.some((m) => m.name);
355
+ let appliedNames = new Set();
252
356
  if (pg) {
253
357
  try {
254
358
  const { rows } = await getDbExec().execute(`SELECT MAX(version) as v FROM ${table}`);
@@ -257,11 +361,22 @@ export function runMigrations(migrations, options) {
257
361
  catch {
258
362
  // Table doesn't exist yet — leave current = -1 so all migrations apply.
259
363
  }
364
+ if (hasNamedMigrations) {
365
+ try {
366
+ const { rows } = await getDbExec().execute(`SELECT name FROM ${namedTable}`);
367
+ appliedNames = new Set(rows.map((r) => String(r.name)));
368
+ }
369
+ catch {
370
+ // Named table doesn't exist yet — leave appliedNames empty so all
371
+ // named migrations apply.
372
+ namedRowsMissing = true;
373
+ }
374
+ }
260
375
  }
261
376
  // For SQLite we still use getDbExec() as exec throughout (no pooler concern).
262
377
  // For Postgres we only open the direct exec when there are pending migrations.
263
378
  const pendingFast = pg
264
- ? migrations.filter((m) => m.version > current)
379
+ ? migrations.filter((m) => m.name ? !appliedNames.has(m.name) : m.version > current)
265
380
  : null; // SQLite: compute after table creation below
266
381
  // Short-circuit: Postgres with nothing to do — skip the direct connection entirely.
267
382
  if (pg && pendingFast !== null && pendingFast.length === 0) {
@@ -275,31 +390,71 @@ export function runMigrations(migrations, options) {
275
390
  // Retry initial table creation — SQLITE_BUSY_RECOVERY can occur on HMR
276
391
  // restarts when WAL files from the previous process haven't been released yet.
277
392
  await retrySqliteBusy(() => exec.execute(`CREATE TABLE IF NOT EXISTS ${table} (version INTEGER PRIMARY KEY)`), { maxAttempts: 6, baseDelayMs: 1000, rethrow: true });
393
+ // Companion name-keyed bookkeeping table — never alters the existing
394
+ // `${table}`'s PRIMARY KEY, so legacy version rows keep working exactly
395
+ // as before. See the `runMigrations` doc comment for why this exists.
396
+ await retrySqliteBusy(() => exec.execute(`CREATE TABLE IF NOT EXISTS ${namedTable} (name TEXT PRIMARY KEY, version INTEGER, applied_at ${pg ? "TIMESTAMP NOT NULL DEFAULT now()" : "TEXT NOT NULL DEFAULT (datetime('now'))"})`), { maxAttempts: 6, baseDelayMs: 1000, rethrow: true });
278
397
  // For Postgres, current was already set by the fast-path SELECT above.
279
398
  // For SQLite we run the SELECT now (via the same exec, which is the singleton).
280
399
  if (!pg) {
281
400
  const { rows } = await exec.execute(`SELECT MAX(version) as v FROM ${table}`);
282
401
  current = rows[0]?.v ?? 0;
402
+ if (hasNamedMigrations) {
403
+ const { rows: nameRows } = await exec.execute(`SELECT name FROM ${namedTable}`);
404
+ appliedNames = new Set(nameRows.map((r) => String(r.name)));
405
+ }
283
406
  }
284
- else if (current === -1) {
407
+ else if (current === -1 || (hasNamedMigrations && namedRowsMissing)) {
285
408
  // Fast-path read failed (table was absent on the pooler): re-read via the
286
409
  // direct exec now that CREATE TABLE IF NOT EXISTS has ensured it exists.
287
- const { rows } = await exec.execute(`SELECT MAX(version) as v FROM ${table}`);
288
- current = rows[0]?.v ?? 0;
410
+ if (current === -1) {
411
+ const { rows } = await exec.execute(`SELECT MAX(version) as v FROM ${table}`);
412
+ current = rows[0]?.v ?? 0;
413
+ }
414
+ if (hasNamedMigrations && namedRowsMissing) {
415
+ const { rows: nameRows } = await exec.execute(`SELECT name FROM ${namedTable}`);
416
+ appliedNames = new Set(nameRows.map((r) => String(r.name)));
417
+ }
289
418
  }
290
- const insertSql = pg
419
+ const insertVersionSql = pg
291
420
  ? `INSERT INTO ${table} VALUES (?) ON CONFLICT DO NOTHING`
292
421
  : `INSERT OR IGNORE INTO ${table} VALUES (?)`;
293
- const pending = migrations.filter((m) => m.version > current);
422
+ const insertNamedSql = pg
423
+ ? `INSERT INTO ${namedTable} (name, version) VALUES (?, ?) ON CONFLICT DO NOTHING`
424
+ : `INSERT OR IGNORE INTO ${namedTable} (name, version) VALUES (?, ?)`;
425
+ const pending = migrations.filter((m) => m.name ? !appliedNames.has(m.name) : m.version > current);
294
426
  if (pending.length > 0) {
295
427
  console.log(`[db] Applying ${pending.length} migration(s) on ${pg ? "Postgres" : "SQLite/libsql"}…`);
296
428
  }
297
429
  for (const m of pending) {
298
430
  const raw = resolveMigrationSql(m.sql, pg);
431
+ const label = m.name
432
+ ? `"${m.name}" (v${m.version})`
433
+ : `v${m.version}`;
434
+ // Record BOTH the named row (always, when named) and the legacy
435
+ // version row (only if this migration actually advances the legacy
436
+ // MAX) — atomically with the DDL below. This keeps the legacy gate
437
+ // monotonic for any unnamed migrations later in the list, while a
438
+ // named migration is tracked by name regardless of version.
439
+ const recordSql = [];
440
+ if (m.name) {
441
+ recordSql.push({
442
+ sql: insertNamedSql,
443
+ args: [m.name, m.version],
444
+ });
445
+ }
446
+ if (m.version > current) {
447
+ recordSql.push({ sql: insertVersionSql, args: [m.version] });
448
+ }
299
449
  if (raw == null) {
300
450
  // Dialect-gated migration with no SQL for this dialect; still mark
301
451
  // as applied so we don't retry forever.
302
- await exec.execute({ sql: insertSql, args: [m.version] });
452
+ for (const stmt of recordSql)
453
+ await exec.execute(stmt);
454
+ if (m.version > current)
455
+ current = m.version;
456
+ if (m.name)
457
+ appliedNames.add(m.name);
303
458
  continue;
304
459
  }
305
460
  // Split BEFORE adapting so we can remember which original statements
@@ -326,26 +481,34 @@ export function runMigrations(migrations, options) {
326
481
  throw err;
327
482
  }
328
483
  }
329
- await exec.execute({ sql: insertSql, args: [m.version] });
330
- console.log(`[db] Applied migration v${m.version} (${statements.length} statement${statements.length === 1 ? "" : "s"})`);
484
+ for (const stmt of recordSql)
485
+ await exec.execute(stmt);
486
+ if (m.version > current)
487
+ current = m.version;
488
+ if (m.name)
489
+ appliedNames.add(m.name);
490
+ console.log(`[db] Applied migration ${label} (${statements.length} statement${statements.length === 1 ? "" : "s"})`);
331
491
  }
332
492
  catch (err) {
333
493
  if (pg && isPermissionError(err)) {
334
494
  // The connected role lacks privilege for this migration (e.g. a
335
495
  // permission-limited dev/replica role that doesn't own the table).
336
496
  // Don't crash-loop the whole server over it — warn and STOP here.
337
- // We must NOT continue to later migrations: pending work is computed
338
- // as `version > MAX(recorded version)`, so applying a later migration
339
- // would advance MAX past this unrecorded one and orphan it forever.
340
- // Stopping leaves MAX at the last recorded version, so a properly-
341
- // privileged role resumes from this exact migration, in order.
342
- console.warn(`[db] Migration v${m.version} skipped insufficient privilege: ${err.message}. ` +
497
+ // We must NOT continue to later migrations: unnamed pending work is
498
+ // computed as `version > MAX(recorded version)`, so applying a later
499
+ // unnamed migration would advance MAX past this unrecorded one and
500
+ // orphan it forever. Stopping leaves MAX at the last recorded
501
+ // version, so a properly-privileged role resumes from this exact
502
+ // migration, in order. (A named migration skipped here simply
503
+ // isn't recorded by name either, so it's retried next boot same as
504
+ // the legacy gate — no orphaning risk from name-based tracking.)
505
+ console.warn(`[db] Migration ${label} skipped — insufficient privilege: ${err.message}. ` +
343
506
  `Apply it with a DB role that owns the table. ` +
344
507
  `Halting further migrations so this one isn't orphaned. ` +
345
508
  `Set <APP_NAME>_DATABASE_URL (e.g. PLAN_DATABASE_URL) to a database this app owns — a file: URL uses local SQLite.`, "\nStatement:", currentStmt);
346
509
  break;
347
510
  }
348
- console.error(`[db] Migration v${m.version} FAILED:`, err.message, "\nStatement:", currentStmt);
511
+ console.error(`[db] Migration ${label} FAILED:`, err.message, "\nStatement:", currentStmt);
349
512
  throw err;
350
513
  }
351
514
  }
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/db/migrations.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getDbExec,\n createDbExec,\n isPostgres,\n getDialect,\n getMigrationDatabaseUrl,\n retrySqliteBusy,\n type DbExec,\n} from \"./client.js\";\n\n// ---------------------------------------------------------------------------\n// Shared direct-endpoint exec across concurrent migration runners per boot.\n//\n// On each serverless cold start THREE plugins call runMigrations (core,\n// org, context-xray). Without coordination each would open an independent\n// direct-endpoint Neon connection AND leave it idle for ~10 s after\n// migrations finish. We avoid that by sharing a single direct exec for\n// the duration of the migration window: the first caller opens it,\n// subsequent callers reuse the same promise, and the last caller closes it\n// via reference-counting. The exec is nulled out after the window so a\n// second cold start (e.g. after a Lambda thaw) gets a fresh connection.\n// ---------------------------------------------------------------------------\n\nlet _migrationExecPromise: Promise<DbExec> | null = null;\nlet _migrationExecRefCount = 0;\n\nasync function acquireMigrationExec(): Promise<DbExec> {\n if (!_migrationExecPromise) {\n _migrationExecPromise = createDbExec({ url: getMigrationDatabaseUrl() });\n }\n _migrationExecRefCount++;\n return _migrationExecPromise;\n}\n\nasync function releaseMigrationExec(): Promise<void> {\n _migrationExecRefCount--;\n if (_migrationExecRefCount > 0) return;\n // Last caller — close and reset so next boot gets a fresh connection.\n const execPromise = _migrationExecPromise;\n _migrationExecPromise = null;\n _migrationExecRefCount = 0;\n if (!execPromise) return;\n try {\n const exec = await execPromise;\n await exec.close?.();\n } catch {\n // Swallow close errors — the migrations themselves already succeeded or\n // failed; a cleanup error should not surface as a boot crash.\n }\n}\n\ntype NitroPluginDef = (nitroApp: any) => void | Promise<void>;\n\n/**\n * Rewrite SQLite-specific SQL to Postgres-compatible equivalents.\n * Handles: datetime('now') → CURRENT_TIMESTAMP, AUTOINCREMENT → GENERATED, etc.\n */\nfunction adaptSqlForPostgres(sql: string): string {\n return sql\n .replace(/datetime\\s*\\(\\s*'now'\\s*\\)/gi, \"CURRENT_TIMESTAMP\")\n .replace(/\\bAUTOINCREMENT\\b/gi, \"\")\n .replace(/\\bINTEGER\\b/gi, \"BIGINT\");\n}\n\nconst IF_NOT_EXISTS_ADD_COLUMN_RE = /ADD\\s+COLUMN\\s+IF\\s+NOT\\s+EXISTS/i;\n\n/**\n * Strip Postgres-only syntax that SQLite doesn't support.\n * Handles: ALTER TABLE ... ADD COLUMN IF NOT EXISTS → ADD COLUMN\n *\n * Note: SQLite does not have a native equivalent, so the idempotent\n * semantic is emulated at the executor level by swallowing the\n * \"duplicate column name\" error for statements that originally carried\n * the clause. See `hadIfNotExists` tracking in the run loop.\n */\nfunction adaptSqlForSqlite(sql: string): string {\n return sql.replace(/ADD\\s+COLUMN\\s+IF\\s+NOT\\s+EXISTS/gi, \"ADD COLUMN\");\n}\n\n/**\n * True when an error from `ALTER TABLE ... ADD COLUMN` indicates the\n * column already existed. Recognizes both SQLite (\"duplicate column\n * name\") and Postgres (\"column ... already exists\" — exact text varies\n * by error code 42701, but the substring is stable). Exported so other\n * idempotent column-upgrade loops in the codebase don't reinvent this\n * regex with subtly different shapes.\n */\nexport function isDuplicateColumnError(err: unknown): boolean {\n const msg = (err as Error | undefined)?.message ?? \"\";\n return (\n /duplicate column name/i.test(msg) || /column .* already exists/i.test(msg)\n );\n}\n\n/**\n * True when a migration statement failed because the connected DB ROLE lacks\n * privilege — e.g. a permission-limited dev/replica role that doesn't own the\n * table. Postgres raises SQLSTATE 42501 (\"insufficient_privilege\", routine\n * aclcheck_error, message \"must be owner of table …\"). We treat these as\n * NON-FATAL so a perms-limited database can't crash-loop the whole server: the\n * migration is skipped (left unrecorded) and a properly-privileged role applies\n * it later. Production, where the role owns its tables, never hits this path.\n */\nexport function isPermissionError(err: unknown): boolean {\n const e = err as { code?: string; message?: string } | undefined;\n if (e?.code === \"42501\") return true;\n const msg = e?.message ?? \"\";\n return (\n /must be owner of/i.test(msg) ||\n /permission denied/i.test(msg) ||\n /insufficient privilege/i.test(msg)\n );\n}\n\n/**\n * Split a multi-statement SQL blob into individual statements.\n *\n * libsql's `execute(sql)` only runs the first statement in a multi-statement\n * string. This splitter is intentionally simple: it respects single-quoted\n * string literals (with `''` escaping) and `--` line comments, and splits on\n * top-level `;`. It does NOT attempt to parse `$$`-quoted Postgres function\n * bodies — migrations that define functions/triggers with `;` inside bodies\n * should pass a single-statement migration per entry instead.\n */\nfunction splitSqlStatements(sql: string): string[] {\n const out: string[] = [];\n let buf = \"\";\n let i = 0;\n let inSingle = false;\n while (i < sql.length) {\n const ch = sql[i];\n const next = sql[i + 1];\n if (!inSingle && ch === \"-\" && next === \"-\") {\n // Skip to end of line\n while (i < sql.length && sql[i] !== \"\\n\") i++;\n continue;\n }\n if (ch === \"'\") {\n buf += ch;\n if (inSingle && next === \"'\") {\n buf += next;\n i += 2;\n continue;\n }\n inSingle = !inSingle;\n i++;\n continue;\n }\n if (ch === \";\" && !inSingle) {\n const trimmed = buf.trim();\n if (trimmed) out.push(trimmed);\n buf = \"\";\n i++;\n continue;\n }\n buf += ch;\n i++;\n }\n const tail = buf.trim();\n if (tail) out.push(tail);\n return out;\n}\n\nexport interface RunMigrationsOptions {\n /**\n * Name of the migrations bookkeeping table. REQUIRED — there is intentionally\n * no default. Two templates that share a database (e.g. via the same Neon URL)\n * each have their own version space starting at v1, and a single shared\n * `_migrations` table will silently skip the second template's migrations if\n * the first has already advanced past those version numbers. This caused the\n * design template's migrations to be skipped entirely on a Neon DB that\n * slides had already populated up to v15 (PR #320 era).\n *\n * Use one bookkeeping table per template, e.g. `slides_migrations`. Core\n * feature plugins (e.g. the org module) follow the same convention with\n * their own prefix, e.g. `_org_migrations`.\n */\n table: string;\n}\n\n/**\n * A single migration entry.\n *\n * `sql` can be a string (runs on every dialect) or an object with dialect\n * keys for dialect-gated SQL. Useful when Postgres needs an ALTER that\n * SQLite can't parse.\n *\n * { version: 14, sql: { postgres: \"ALTER TABLE …\" } } // no-op on sqlite\n * { version: 15, sql: { sqlite: \"…\", postgres: \"…\" } } // both dialects\n */\nexport type MigrationSql = string | { postgres?: string; sqlite?: string };\n\nexport interface MigrationEntry {\n version: number;\n sql: MigrationSql;\n}\n\nfunction resolveMigrationSql(sql: MigrationSql, pg: boolean): string | null {\n if (typeof sql === \"string\") return sql;\n const raw = pg ? sql.postgres : sql.sqlite;\n return raw ?? null;\n}\n\nexport function runMigrations(\n migrations: Array<MigrationEntry>,\n options: RunMigrationsOptions,\n): NitroPluginDef {\n const table = options?.table;\n if (\n !table ||\n typeof table !== \"string\" ||\n !/^[A-Za-z_][A-Za-z0-9_]*$/.test(table)\n ) {\n throw new Error(\n \"runMigrations: `table` option is required and must be a valid SQL identifier \" +\n '(e.g. `{ table: \"slides_migrations\" }`). See packages/core/src/db/migrations.ts ' +\n \"for why this is required (shared-DB version-collision bug).\",\n );\n }\n return async () => {\n try {\n // Check for Cloudflare D1 binding (only if DATABASE_URL not set)\n const d1 = getDialect() === \"d1\" ? globalThis.__cf_env?.DB : null;\n if (d1) {\n await d1\n .prepare(\n `CREATE TABLE IF NOT EXISTS ${table} (version INTEGER PRIMARY KEY)`,\n )\n .run();\n const firstRow = await d1\n .prepare(`SELECT MAX(version) as v FROM ${table}`)\n .first<{ v?: number }>();\n const current = (firstRow?.v as number) ?? 0;\n\n for (const m of migrations.filter((m) => m.version > current)) {\n try {\n // D1 is SQLite-compatible\n const raw = resolveMigrationSql(m.sql, false);\n if (raw == null) {\n await d1\n .prepare(`INSERT OR IGNORE INTO ${table} VALUES (?)`)\n .bind(m.version)\n .run();\n continue;\n }\n const originalStatements = splitSqlStatements(raw);\n const statements = originalStatements.map((orig) => ({\n sql: adaptSqlForSqlite(orig),\n hadIfNotExists: IF_NOT_EXISTS_ADD_COLUMN_RE.test(orig),\n }));\n const hasIfNotExists = statements.some((s) => s.hadIfNotExists);\n if (hasIfNotExists) {\n // Per-statement path: we need to swallow \"duplicate column\"\n // errors for statements that originally carried\n // `ADD COLUMN IF NOT EXISTS`, which a batch() can't express.\n // Loses atomicity, but the idempotent-ADD-COLUMN semantic\n // means a partial re-run resolves cleanly on retry.\n for (const { sql: stmt, hadIfNotExists } of statements) {\n try {\n await d1.prepare(stmt).run();\n } catch (err) {\n if (hadIfNotExists && isDuplicateColumnError(err)) continue;\n throw err;\n }\n }\n await d1\n .prepare(`INSERT OR IGNORE INTO ${table} VALUES (?)`)\n .bind(m.version)\n .run();\n } else {\n // Atomic batch: all statements + version-row insert land in\n // the same transaction. A failing statement rolls the whole\n // migration back, so we never record a half-applied version.\n await d1.batch([\n ...statements.map((s) => d1.prepare(s.sql)),\n d1\n .prepare(`INSERT OR IGNORE INTO ${table} VALUES (?)`)\n .bind(m.version),\n ]);\n }\n console.log(\n `[db] Applied migration v${m.version} (${statements.length} statement${statements.length === 1 ? \"\" : \"s\"})`,\n );\n } catch (err) {\n console.error(\n `[db] Migration v${m.version} FAILED:`,\n (err as Error).message,\n \"\\nSQL:\",\n JSON.stringify(m.sql),\n );\n throw err;\n }\n }\n return;\n }\n\n // Generic path — works for libsql and Postgres\n const pg = isPostgres();\n\n // ---------------------------------------------------------------------------\n // Fast-path: read migration state through the regular pooled singleton before\n // opening the direct-endpoint connection.\n //\n // On Postgres every cold start previously opened a fresh direct-endpoint Neon\n // connection (bypassing PgBouncer, which is needed only for DDL), ran\n // CREATE TABLE IF NOT EXISTS + SELECT MAX(version) even with zero pending\n // migrations, and never closed the pool — it idled for ~10 s. Three runners\n // (core, org, context-xray) did this independently per boot.\n //\n // Now: use the pooled singleton (getDbExec) for the bookkeeping SELECT. If\n // the migrations table does not yet exist we treat it as \"all migrations\n // pending\" (current = -1). Only when there are pending migrations do we open\n // the direct-endpoint exec (DDL is the only thing Neon's PgBouncer blocks —\n // documented at getMigrationDatabaseUrl). The direct exec is shared across\n // concurrent runners via acquireMigrationExec() and closed after the last\n // caller via releaseMigrationExec().\n // ---------------------------------------------------------------------------\n\n let current = -1; // sentinel: \"table missing\" → treat all as pending\n\n if (pg) {\n try {\n const { rows } = await getDbExec().execute(\n `SELECT MAX(version) as v FROM ${table}`,\n );\n current = (rows[0]?.v as number) ?? 0;\n } catch {\n // Table doesn't exist yet — leave current = -1 so all migrations apply.\n }\n }\n\n // For SQLite we still use getDbExec() as exec throughout (no pooler concern).\n // For Postgres we only open the direct exec when there are pending migrations.\n const pendingFast = pg\n ? migrations.filter((m) => m.version > current)\n : null; // SQLite: compute after table creation below\n\n // Short-circuit: Postgres with nothing to do — skip the direct connection entirely.\n if (pg && pendingFast !== null && pendingFast.length === 0) {\n return;\n }\n\n // Acquire the exec appropriate for the dialect.\n // For Postgres: the shared direct-endpoint exec (DDL-safe, closed on release).\n // For SQLite/libsql: the singleton pooled exec (no pooler concern).\n const exec = pg ? await acquireMigrationExec() : getDbExec();\n\n try {\n // Retry initial table creation — SQLITE_BUSY_RECOVERY can occur on HMR\n // restarts when WAL files from the previous process haven't been released yet.\n await retrySqliteBusy(\n () =>\n exec.execute(\n `CREATE TABLE IF NOT EXISTS ${table} (version INTEGER PRIMARY KEY)`,\n ),\n { maxAttempts: 6, baseDelayMs: 1000, rethrow: true },\n );\n\n // For Postgres, current was already set by the fast-path SELECT above.\n // For SQLite we run the SELECT now (via the same exec, which is the singleton).\n if (!pg) {\n const { rows } = await exec.execute(\n `SELECT MAX(version) as v FROM ${table}`,\n );\n current = (rows[0]?.v as number) ?? 0;\n } else if (current === -1) {\n // Fast-path read failed (table was absent on the pooler): re-read via the\n // direct exec now that CREATE TABLE IF NOT EXISTS has ensured it exists.\n const { rows } = await exec.execute(\n `SELECT MAX(version) as v FROM ${table}`,\n );\n current = (rows[0]?.v as number) ?? 0;\n }\n\n const insertSql = pg\n ? `INSERT INTO ${table} VALUES (?) ON CONFLICT DO NOTHING`\n : `INSERT OR IGNORE INTO ${table} VALUES (?)`;\n\n const pending = migrations.filter((m) => m.version > current);\n if (pending.length > 0) {\n console.log(\n `[db] Applying ${pending.length} migration(s) on ${pg ? \"Postgres\" : \"SQLite/libsql\"}…`,\n );\n }\n\n for (const m of pending) {\n const raw = resolveMigrationSql(m.sql, pg);\n if (raw == null) {\n // Dialect-gated migration with no SQL for this dialect; still mark\n // as applied so we don't retry forever.\n await exec.execute({ sql: insertSql, args: [m.version] });\n continue;\n }\n // Split BEFORE adapting so we can remember which original statements\n // carried `ADD COLUMN IF NOT EXISTS` — SQLite drops the clause, so we\n // emulate the idempotent semantic by swallowing duplicate-column\n // errors only for those statements.\n const originalStatements = splitSqlStatements(raw);\n const statements = originalStatements.map((orig) => ({\n sql: pg ? adaptSqlForPostgres(orig) : adaptSqlForSqlite(orig),\n hadIfNotExists: IF_NOT_EXISTS_ADD_COLUMN_RE.test(orig),\n }));\n let currentStmt = \"\";\n try {\n for (const { sql: stmt, hadIfNotExists } of statements) {\n currentStmt = stmt;\n try {\n await exec.execute(stmt);\n } catch (err) {\n if (!pg && hadIfNotExists && isDuplicateColumnError(err)) {\n // IF NOT EXISTS semantic: column already present, skip.\n continue;\n }\n throw err;\n }\n }\n await exec.execute({ sql: insertSql, args: [m.version] });\n console.log(\n `[db] Applied migration v${m.version} (${statements.length} statement${statements.length === 1 ? \"\" : \"s\"})`,\n );\n } catch (err) {\n if (pg && isPermissionError(err)) {\n // The connected role lacks privilege for this migration (e.g. a\n // permission-limited dev/replica role that doesn't own the table).\n // Don't crash-loop the whole server over it — warn and STOP here.\n // We must NOT continue to later migrations: pending work is computed\n // as `version > MAX(recorded version)`, so applying a later migration\n // would advance MAX past this unrecorded one and orphan it forever.\n // Stopping leaves MAX at the last recorded version, so a properly-\n // privileged role resumes from this exact migration, in order.\n console.warn(\n `[db] Migration v${m.version} skipped — insufficient privilege: ${(err as Error).message}. ` +\n `Apply it with a DB role that owns the table. ` +\n `Halting further migrations so this one isn't orphaned. ` +\n `Set <APP_NAME>_DATABASE_URL (e.g. PLAN_DATABASE_URL) to a database this app owns — a file: URL uses local SQLite.`,\n \"\\nStatement:\",\n currentStmt,\n );\n break;\n }\n console.error(\n `[db] Migration v${m.version} FAILED:`,\n (err as Error).message,\n \"\\nStatement:\",\n currentStmt,\n );\n throw err;\n }\n }\n } finally {\n // Release the direct-endpoint exec (Postgres only). For SQLite getDbExec()\n // returns the process-lifetime singleton, so releaseMigrationExec is a no-op\n // (refCount never incremented for SQLite path, guard in releaseMigrationExec).\n if (pg) await releaseMigrationExec();\n }\n } catch (err) {\n console.error(\"[db] Migration failed:\", (err as Error).message);\n // In local dev, hard-fail so the developer catches errors immediately.\n // On serverless runtimes (Netlify Functions, Vercel, CF Workers) we\n // keep the process alive — the app will return 500s for routes that\n // depend on the missing tables, but at least other routes still work.\n // Note: Node.js 21+ defines globalThis.navigator, so we check for\n // serverless env vars instead of navigator presence.\n const isServerless =\n !!globalThis.process?.env?.NETLIFY ||\n !!globalThis.process?.env?.AWS_LAMBDA_FUNCTION_NAME ||\n !!globalThis.process?.env?.VERCEL ||\n \"__cf_env\" in globalThis;\n if (typeof globalThis.process?.exit === \"function\" && !isServerless) {\n process.exit(1);\n }\n }\n };\n}\n"]}
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/db/migrations.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getDbExec,\n createDbExec,\n isPostgres,\n getDialect,\n getMigrationDatabaseUrl,\n retrySqliteBusy,\n type DbExec,\n} from \"./client.js\";\n\n// ---------------------------------------------------------------------------\n// Shared direct-endpoint exec across concurrent migration runners per boot.\n//\n// On each serverless cold start THREE plugins call runMigrations (core,\n// org, context-xray). Without coordination each would open an independent\n// direct-endpoint Neon connection AND leave it idle for ~10 s after\n// migrations finish. We avoid that by sharing a single direct exec for\n// the duration of the migration window: the first caller opens it,\n// subsequent callers reuse the same promise, and the last caller closes it\n// via reference-counting. The exec is nulled out after the window so a\n// second cold start (e.g. after a Lambda thaw) gets a fresh connection.\n// ---------------------------------------------------------------------------\n\nlet _migrationExecPromise: Promise<DbExec> | null = null;\nlet _migrationExecRefCount = 0;\n\nasync function acquireMigrationExec(): Promise<DbExec> {\n if (!_migrationExecPromise) {\n const opened = createDbExec({ url: getMigrationDatabaseUrl() });\n _migrationExecPromise = opened;\n opened.catch(() => {\n // Opening the connection failed. Reset the shared state so the next\n // caller retries with a fresh connection instead of awaiting this\n // permanently rejected promise — and zero the ref count, because none\n // of the awaiters that failed here will ever call release.\n if (_migrationExecPromise === opened) {\n _migrationExecPromise = null;\n _migrationExecRefCount = 0;\n }\n });\n }\n _migrationExecRefCount++;\n return _migrationExecPromise;\n}\n\nasync function releaseMigrationExec(): Promise<void> {\n _migrationExecRefCount--;\n if (_migrationExecRefCount > 0) return;\n // Last caller — close and reset so next boot gets a fresh connection.\n const execPromise = _migrationExecPromise;\n _migrationExecPromise = null;\n _migrationExecRefCount = 0;\n if (!execPromise) return;\n try {\n const exec = await execPromise;\n await exec.close?.();\n } catch {\n // Swallow close errors — the migrations themselves already succeeded or\n // failed; a cleanup error should not surface as a boot crash.\n }\n}\n\ntype NitroPluginDef = (nitroApp: any) => void | Promise<void>;\n\n/**\n * Rewrite SQLite-specific SQL to Postgres-compatible equivalents.\n * Handles: datetime('now') → CURRENT_TIMESTAMP, AUTOINCREMENT → GENERATED, etc.\n */\nfunction adaptSqlForPostgres(sql: string): string {\n return sql\n .replace(/datetime\\s*\\(\\s*'now'\\s*\\)/gi, \"CURRENT_TIMESTAMP\")\n .replace(/\\bAUTOINCREMENT\\b/gi, \"\")\n .replace(/\\bINTEGER\\b/gi, \"BIGINT\");\n}\n\nconst IF_NOT_EXISTS_ADD_COLUMN_RE = /ADD\\s+COLUMN\\s+IF\\s+NOT\\s+EXISTS/i;\n\n/**\n * Strip Postgres-only syntax that SQLite doesn't support.\n * Handles: ALTER TABLE ... ADD COLUMN IF NOT EXISTS → ADD COLUMN\n *\n * Note: SQLite does not have a native equivalent, so the idempotent\n * semantic is emulated at the executor level by swallowing the\n * \"duplicate column name\" error for statements that originally carried\n * the clause. See `hadIfNotExists` tracking in the run loop.\n */\nfunction adaptSqlForSqlite(sql: string): string {\n return sql.replace(/ADD\\s+COLUMN\\s+IF\\s+NOT\\s+EXISTS/gi, \"ADD COLUMN\");\n}\n\n/**\n * True when an error from `ALTER TABLE ... ADD COLUMN` indicates the\n * column already existed. Recognizes both SQLite (\"duplicate column\n * name\") and Postgres (\"column ... already exists\" — exact text varies\n * by error code 42701, but the substring is stable). Exported so other\n * idempotent column-upgrade loops in the codebase don't reinvent this\n * regex with subtly different shapes.\n */\nexport function isDuplicateColumnError(err: unknown): boolean {\n const msg = (err as Error | undefined)?.message ?? \"\";\n return (\n /duplicate column name/i.test(msg) || /column .* already exists/i.test(msg)\n );\n}\n\n/**\n * True when a migration statement failed because the connected DB ROLE lacks\n * privilege — e.g. a permission-limited dev/replica role that doesn't own the\n * table. Postgres raises SQLSTATE 42501 (\"insufficient_privilege\", routine\n * aclcheck_error, message \"must be owner of table …\"). We treat these as\n * NON-FATAL so a perms-limited database can't crash-loop the whole server: the\n * migration is skipped (left unrecorded) and a properly-privileged role applies\n * it later. Production, where the role owns its tables, never hits this path.\n */\nexport function isPermissionError(err: unknown): boolean {\n const e = err as { code?: string; message?: string } | undefined;\n if (e?.code === \"42501\") return true;\n const msg = e?.message ?? \"\";\n return (\n /must be owner of/i.test(msg) ||\n /permission denied/i.test(msg) ||\n /insufficient privilege/i.test(msg)\n );\n}\n\n/**\n * Split a multi-statement SQL blob into individual statements.\n *\n * libsql's `execute(sql)` only runs the first statement in a multi-statement\n * string. This splitter is intentionally simple: it respects single-quoted\n * string literals (with `''` escaping) and `--` line comments, and splits on\n * top-level `;`. It does NOT attempt to parse `$$`-quoted Postgres function\n * bodies — migrations that define functions/triggers with `;` inside bodies\n * should pass a single-statement migration per entry instead.\n */\nfunction splitSqlStatements(sql: string): string[] {\n const out: string[] = [];\n let buf = \"\";\n let i = 0;\n let inSingle = false;\n while (i < sql.length) {\n const ch = sql[i];\n const next = sql[i + 1];\n if (!inSingle && ch === \"-\" && next === \"-\") {\n // Skip to end of line\n while (i < sql.length && sql[i] !== \"\\n\") i++;\n continue;\n }\n if (ch === \"'\") {\n buf += ch;\n if (inSingle && next === \"'\") {\n buf += next;\n i += 2;\n continue;\n }\n inSingle = !inSingle;\n i++;\n continue;\n }\n if (ch === \";\" && !inSingle) {\n const trimmed = buf.trim();\n if (trimmed) out.push(trimmed);\n buf = \"\";\n i++;\n continue;\n }\n buf += ch;\n i++;\n }\n const tail = buf.trim();\n if (tail) out.push(tail);\n return out;\n}\n\nexport interface RunMigrationsOptions {\n /**\n * Name of the migrations bookkeeping table. REQUIRED — there is intentionally\n * no default. Two templates that share a database (e.g. via the same Neon URL)\n * each have their own version space starting at v1, and a single shared\n * `_migrations` table will silently skip the second template's migrations if\n * the first has already advanced past those version numbers. This caused the\n * design template's migrations to be skipped entirely on a Neon DB that\n * slides had already populated up to v15 (PR #320 era).\n *\n * Use one bookkeeping table per template, e.g. `slides_migrations`. Core\n * feature plugins (e.g. the org module) follow the same convention with\n * their own prefix, e.g. `_org_migrations`.\n */\n table: string;\n}\n\n/**\n * A single migration entry.\n *\n * `sql` can be a string (runs on every dialect) or an object with dialect\n * keys for dialect-gated SQL. Useful when Postgres needs an ALTER that\n * SQLite can't parse.\n *\n * { version: 14, sql: { postgres: \"ALTER TABLE …\" } } // no-op on sqlite\n * { version: 15, sql: { sqlite: \"…\", postgres: \"…\" } } // both dialects\n *\n * `name` is an optional stable, unique slug that opts a migration into\n * **name-based tracking** instead of the legacy version-number gate. See the\n * \"Name-based tracking\" section on `runMigrations` for why this exists and\n * exactly how the two gating strategies interact.\n */\nexport type MigrationSql = string | { postgres?: string; sqlite?: string };\n\nexport interface MigrationEntry {\n version: number;\n sql: MigrationSql;\n /**\n * Stable, unique slug for this migration (e.g. `\"analytics-alert-rules-table\"`).\n * When present, this migration is tracked by NAME instead of by version\n * number — see the `runMigrations` doc comment for the full rationale and\n * gating rules. Must be unique across the migration list; a duplicate name\n * throws at startup (programmer error, not a runtime data problem).\n */\n name?: string;\n}\n\nfunction resolveMigrationSql(sql: MigrationSql, pg: boolean): string | null {\n if (typeof sql === \"string\") return sql;\n const raw = pg ? sql.postgres : sql.sqlite;\n return raw ?? null;\n}\n\n/**\n * Runs a list of migrations against the configured database, gated by a\n * per-table bookkeeping row (`options.table`) so repeated boots only apply\n * new migrations.\n *\n * ## Name-based tracking (why it exists)\n *\n * The legacy gate is purely numeric: `SELECT MAX(version)` from the\n * bookkeeping table, then apply every entry whose `version` is greater. That\n * scheme silently breaks down when **two independent branches each extend the\n * same migration list with different DDL under the same version numbers** —\n * exactly what happened to the analytics template's v75-v83 range. Branch A\n * shipped alert-rule tables as v75-v78; branch B shipped unrelated DDL as its\n * own v75-v83. Whichever branch deployed first recorded \"v75..v83 applied\"\n * in the bookkeeping table. When the other branch merged and deployed, its\n * migrations at those same version numbers were never applied — `MAX(version)`\n * was already ≥ their version, so the gate treated them as done even though\n * their actual DDL had never run. The result: `analytics_migrations` showed\n * rows for 1..83 with no gaps, yet `analytics_alert_rules`,\n * `analytics_alert_incidents`, and `session_recordings.network_error_count`\n * did not exist in production. Version numbers are not a stable identity —\n * they're just sequence position, and sequence position collides across\n * branches.\n *\n * Name-based tracking fixes this by keying application on a stable, unique\n * **string slug** instead of a position in a shared integer sequence:\n *\n * - Entries with a `name` are recorded in a companion table,\n * `${table}_named` (`name TEXT PRIMARY KEY`), and APPLY IFF their name is\n * absent from that table — completely independent of version numbers or\n * the legacy `MAX(version)` gate. Two branches can both ship a migration\n * named `\"analytics-alert-rules-table\"` at version 75, or one at version 75\n * and the other at version 90 after a rebase — either way it applies\n * exactly once per database, keyed on the name.\n * - Entries WITHOUT a `name` keep the exact legacy behavior\n * (`version > MAX(recorded version)`), so nothing changes for existing\n * unnamed migrations.\n * - Named migrations still execute in list order, interleaved with unnamed\n * ones exactly as written.\n * - When a named migration's DDL runs, we record BOTH the named row (always)\n * and — if its `version` is greater than the current legacy max — the\n * legacy version row too, in the SAME atomic batch/transaction as the DDL.\n * This keeps the legacy `MAX(version)` gate monotonically advancing for\n * any unnamed migrations that come after it in the list, while ensuring a\n * named migration is never \"double recorded\" in a way that would let it\n * re-apply.\n * - A duplicate `name` across the migration list throws at startup — that's\n * a programmer error (copy-paste or merge mistake), not a runtime data\n * problem, and failing loud beats silently tracking the wrong row.\n *\n * New migrations should always set a `name`. Legacy unnamed migrations don't\n * need to be renamed retroactively — the two gating strategies coexist in the\n * same list — but if a table is EVER at risk of being shared across parallel\n * branches (any template's own migrations qualify, since branches routinely\n * extend the same list concurrently), giving new entries a name is what makes\n * them immune to the collision class described above.\n */\nexport function runMigrations(\n migrations: Array<MigrationEntry>,\n options: RunMigrationsOptions,\n): NitroPluginDef {\n const table = options?.table;\n if (\n !table ||\n typeof table !== \"string\" ||\n !/^[A-Za-z_][A-Za-z0-9_]*$/.test(table)\n ) {\n throw new Error(\n \"runMigrations: `table` option is required and must be a valid SQL identifier \" +\n '(e.g. `{ table: \"slides_migrations\" }`). See packages/core/src/db/migrations.ts ' +\n \"for why this is required (shared-DB version-collision bug).\",\n );\n }\n\n // Duplicate-name detection — programmer error, fail loud at startup rather\n // than silently tracking the wrong migration's applied state.\n {\n const seenNames = new Set<string>();\n for (const m of migrations) {\n if (!m.name) continue;\n if (seenNames.has(m.name)) {\n throw new Error(\n `runMigrations: duplicate migration name \"${m.name}\" in the migration list for table \"${table}\". ` +\n \"Migration names must be unique — pick a different stable slug.\",\n );\n }\n seenNames.add(m.name);\n }\n }\n\n const namedTable = `${table}_named`;\n\n return async () => {\n try {\n // Check for Cloudflare D1 binding (only if DATABASE_URL not set)\n const d1 = getDialect() === \"d1\" ? globalThis.__cf_env?.DB : null;\n if (d1) {\n await d1\n .prepare(\n `CREATE TABLE IF NOT EXISTS ${table} (version INTEGER PRIMARY KEY)`,\n )\n .run();\n await d1\n .prepare(\n `CREATE TABLE IF NOT EXISTS ${namedTable} (name TEXT PRIMARY KEY, version INTEGER, applied_at TEXT NOT NULL DEFAULT (datetime('now')))`,\n )\n .run();\n const firstRow = await d1\n .prepare(`SELECT MAX(version) as v FROM ${table}`)\n .first<{ v?: number }>();\n const current = (firstRow?.v as number) ?? 0;\n\n const appliedNamesRows = await d1\n .prepare(`SELECT name FROM ${namedTable}`)\n .all();\n const appliedNames = new Set(\n (appliedNamesRows?.results ?? []).map((r) => String(r.name)),\n );\n\n const pending = migrations.filter((m) =>\n m.name ? !appliedNames.has(m.name) : m.version > current,\n );\n\n for (const m of pending) {\n try {\n // D1 is SQLite-compatible\n const raw = resolveMigrationSql(m.sql, false);\n const recordStatements = [\n m.name\n ? d1\n .prepare(\n `INSERT OR IGNORE INTO ${namedTable} (name, version) VALUES (?, ?)`,\n )\n .bind(m.name, m.version)\n : null,\n m.version > current\n ? d1\n .prepare(`INSERT OR IGNORE INTO ${table} VALUES (?)`)\n .bind(m.version)\n : null,\n ].filter((s): s is NonNullable<typeof s> => s != null);\n\n if (raw == null) {\n // Dialect-gated migration with no SQL for this dialect; still\n // record it so we don't retry forever.\n for (const stmt of recordStatements) await stmt.run();\n continue;\n }\n const originalStatements = splitSqlStatements(raw);\n const statements = originalStatements.map((orig) => ({\n sql: adaptSqlForSqlite(orig),\n hadIfNotExists: IF_NOT_EXISTS_ADD_COLUMN_RE.test(orig),\n }));\n const hasIfNotExists = statements.some((s) => s.hadIfNotExists);\n if (hasIfNotExists) {\n // Per-statement path: we need to swallow \"duplicate column\"\n // errors for statements that originally carried\n // `ADD COLUMN IF NOT EXISTS`, which a batch() can't express.\n // Loses atomicity, but the idempotent-ADD-COLUMN semantic\n // means a partial re-run resolves cleanly on retry.\n for (const { sql: stmt, hadIfNotExists } of statements) {\n try {\n await d1.prepare(stmt).run();\n } catch (err) {\n if (hadIfNotExists && isDuplicateColumnError(err)) continue;\n throw err;\n }\n }\n for (const stmt of recordStatements) await stmt.run();\n } else {\n // Atomic batch: all statements + bookkeeping inserts land in\n // the same transaction. A failing statement rolls the whole\n // migration back, so we never record a half-applied migration.\n await d1.batch([\n ...statements.map((s) => d1.prepare(s.sql)),\n ...recordStatements,\n ]);\n }\n console.log(\n `[db] Applied migration ${m.name ? `\"${m.name}\" ` : \"\"}v${m.version} (${statements.length} statement${statements.length === 1 ? \"\" : \"s\"})`,\n );\n } catch (err) {\n console.error(\n `[db] Migration ${m.name ? `\"${m.name}\" ` : \"\"}v${m.version} FAILED:`,\n (err as Error).message,\n \"\\nSQL:\",\n JSON.stringify(m.sql),\n );\n throw err;\n }\n }\n return;\n }\n\n // Generic path — works for libsql and Postgres\n const pg = isPostgres();\n\n // ---------------------------------------------------------------------------\n // Fast-path: read migration state through the regular pooled singleton before\n // opening the direct-endpoint connection.\n //\n // On Postgres every cold start previously opened a fresh direct-endpoint Neon\n // connection (bypassing PgBouncer, which is needed only for DDL), ran\n // CREATE TABLE IF NOT EXISTS + SELECT MAX(version) even with zero pending\n // migrations, and never closed the pool — it idled for ~10 s. Three runners\n // (core, org, context-xray) did this independently per boot.\n //\n // Now: use the pooled singleton (getDbExec) for the bookkeeping SELECT. If\n // the migrations table does not yet exist we treat it as \"all migrations\n // pending\" (current = -1). Only when there are pending migrations do we open\n // the direct-endpoint exec (DDL is the only thing Neon's PgBouncer blocks —\n // documented at getMigrationDatabaseUrl). The direct exec is shared across\n // concurrent runners via acquireMigrationExec() and closed after the last\n // caller via releaseMigrationExec().\n // ---------------------------------------------------------------------------\n\n let current = -1; // sentinel: \"table missing\" → treat all as pending\n let namedRowsMissing = false; // sentinel: \"named table missing\" → no names applied yet\n\n // Any migration with a `name` is a candidate regardless of version, so\n // the fast-path \"anything pending?\" check must also account for names.\n const hasNamedMigrations = migrations.some((m) => m.name);\n let appliedNames = new Set<string>();\n\n if (pg) {\n try {\n const { rows } = await getDbExec().execute(\n `SELECT MAX(version) as v FROM ${table}`,\n );\n current = (rows[0]?.v as number) ?? 0;\n } catch {\n // Table doesn't exist yet — leave current = -1 so all migrations apply.\n }\n if (hasNamedMigrations) {\n try {\n const { rows } = await getDbExec().execute(\n `SELECT name FROM ${namedTable}`,\n );\n appliedNames = new Set(rows.map((r) => String(r.name)));\n } catch {\n // Named table doesn't exist yet — leave appliedNames empty so all\n // named migrations apply.\n namedRowsMissing = true;\n }\n }\n }\n\n // For SQLite we still use getDbExec() as exec throughout (no pooler concern).\n // For Postgres we only open the direct exec when there are pending migrations.\n const pendingFast = pg\n ? migrations.filter((m) =>\n m.name ? !appliedNames.has(m.name) : m.version > current,\n )\n : null; // SQLite: compute after table creation below\n\n // Short-circuit: Postgres with nothing to do — skip the direct connection entirely.\n if (pg && pendingFast !== null && pendingFast.length === 0) {\n return;\n }\n\n // Acquire the exec appropriate for the dialect.\n // For Postgres: the shared direct-endpoint exec (DDL-safe, closed on release).\n // For SQLite/libsql: the singleton pooled exec (no pooler concern).\n const exec = pg ? await acquireMigrationExec() : getDbExec();\n\n try {\n // Retry initial table creation — SQLITE_BUSY_RECOVERY can occur on HMR\n // restarts when WAL files from the previous process haven't been released yet.\n await retrySqliteBusy(\n () =>\n exec.execute(\n `CREATE TABLE IF NOT EXISTS ${table} (version INTEGER PRIMARY KEY)`,\n ),\n { maxAttempts: 6, baseDelayMs: 1000, rethrow: true },\n );\n // Companion name-keyed bookkeeping table — never alters the existing\n // `${table}`'s PRIMARY KEY, so legacy version rows keep working exactly\n // as before. See the `runMigrations` doc comment for why this exists.\n await retrySqliteBusy(\n () =>\n exec.execute(\n `CREATE TABLE IF NOT EXISTS ${namedTable} (name TEXT PRIMARY KEY, version INTEGER, applied_at ${pg ? \"TIMESTAMP NOT NULL DEFAULT now()\" : \"TEXT NOT NULL DEFAULT (datetime('now'))\"})`,\n ),\n { maxAttempts: 6, baseDelayMs: 1000, rethrow: true },\n );\n\n // For Postgres, current was already set by the fast-path SELECT above.\n // For SQLite we run the SELECT now (via the same exec, which is the singleton).\n if (!pg) {\n const { rows } = await exec.execute(\n `SELECT MAX(version) as v FROM ${table}`,\n );\n current = (rows[0]?.v as number) ?? 0;\n if (hasNamedMigrations) {\n const { rows: nameRows } = await exec.execute(\n `SELECT name FROM ${namedTable}`,\n );\n appliedNames = new Set(nameRows.map((r) => String(r.name)));\n }\n } else if (current === -1 || (hasNamedMigrations && namedRowsMissing)) {\n // Fast-path read failed (table was absent on the pooler): re-read via the\n // direct exec now that CREATE TABLE IF NOT EXISTS has ensured it exists.\n if (current === -1) {\n const { rows } = await exec.execute(\n `SELECT MAX(version) as v FROM ${table}`,\n );\n current = (rows[0]?.v as number) ?? 0;\n }\n if (hasNamedMigrations && namedRowsMissing) {\n const { rows: nameRows } = await exec.execute(\n `SELECT name FROM ${namedTable}`,\n );\n appliedNames = new Set(nameRows.map((r) => String(r.name)));\n }\n }\n\n const insertVersionSql = pg\n ? `INSERT INTO ${table} VALUES (?) ON CONFLICT DO NOTHING`\n : `INSERT OR IGNORE INTO ${table} VALUES (?)`;\n const insertNamedSql = pg\n ? `INSERT INTO ${namedTable} (name, version) VALUES (?, ?) ON CONFLICT DO NOTHING`\n : `INSERT OR IGNORE INTO ${namedTable} (name, version) VALUES (?, ?)`;\n\n const pending = migrations.filter((m) =>\n m.name ? !appliedNames.has(m.name) : m.version > current,\n );\n if (pending.length > 0) {\n console.log(\n `[db] Applying ${pending.length} migration(s) on ${pg ? \"Postgres\" : \"SQLite/libsql\"}…`,\n );\n }\n\n for (const m of pending) {\n const raw = resolveMigrationSql(m.sql, pg);\n const label = m.name\n ? `\"${m.name}\" (v${m.version})`\n : `v${m.version}`;\n\n // Record BOTH the named row (always, when named) and the legacy\n // version row (only if this migration actually advances the legacy\n // MAX) — atomically with the DDL below. This keeps the legacy gate\n // monotonic for any unnamed migrations later in the list, while a\n // named migration is tracked by name regardless of version.\n const recordSql: Array<{ sql: string; args: unknown[] }> = [];\n if (m.name) {\n recordSql.push({\n sql: insertNamedSql,\n args: [m.name, m.version],\n });\n }\n if (m.version > current) {\n recordSql.push({ sql: insertVersionSql, args: [m.version] });\n }\n\n if (raw == null) {\n // Dialect-gated migration with no SQL for this dialect; still mark\n // as applied so we don't retry forever.\n for (const stmt of recordSql) await exec.execute(stmt);\n if (m.version > current) current = m.version;\n if (m.name) appliedNames.add(m.name);\n continue;\n }\n // Split BEFORE adapting so we can remember which original statements\n // carried `ADD COLUMN IF NOT EXISTS` — SQLite drops the clause, so we\n // emulate the idempotent semantic by swallowing duplicate-column\n // errors only for those statements.\n const originalStatements = splitSqlStatements(raw);\n const statements = originalStatements.map((orig) => ({\n sql: pg ? adaptSqlForPostgres(orig) : adaptSqlForSqlite(orig),\n hadIfNotExists: IF_NOT_EXISTS_ADD_COLUMN_RE.test(orig),\n }));\n let currentStmt = \"\";\n try {\n for (const { sql: stmt, hadIfNotExists } of statements) {\n currentStmt = stmt;\n try {\n await exec.execute(stmt);\n } catch (err) {\n if (!pg && hadIfNotExists && isDuplicateColumnError(err)) {\n // IF NOT EXISTS semantic: column already present, skip.\n continue;\n }\n throw err;\n }\n }\n for (const stmt of recordSql) await exec.execute(stmt);\n if (m.version > current) current = m.version;\n if (m.name) appliedNames.add(m.name);\n console.log(\n `[db] Applied migration ${label} (${statements.length} statement${statements.length === 1 ? \"\" : \"s\"})`,\n );\n } catch (err) {\n if (pg && isPermissionError(err)) {\n // The connected role lacks privilege for this migration (e.g. a\n // permission-limited dev/replica role that doesn't own the table).\n // Don't crash-loop the whole server over it — warn and STOP here.\n // We must NOT continue to later migrations: unnamed pending work is\n // computed as `version > MAX(recorded version)`, so applying a later\n // unnamed migration would advance MAX past this unrecorded one and\n // orphan it forever. Stopping leaves MAX at the last recorded\n // version, so a properly-privileged role resumes from this exact\n // migration, in order. (A named migration skipped here simply\n // isn't recorded by name either, so it's retried next boot same as\n // the legacy gate — no orphaning risk from name-based tracking.)\n console.warn(\n `[db] Migration ${label} skipped — insufficient privilege: ${(err as Error).message}. ` +\n `Apply it with a DB role that owns the table. ` +\n `Halting further migrations so this one isn't orphaned. ` +\n `Set <APP_NAME>_DATABASE_URL (e.g. PLAN_DATABASE_URL) to a database this app owns — a file: URL uses local SQLite.`,\n \"\\nStatement:\",\n currentStmt,\n );\n break;\n }\n console.error(\n `[db] Migration ${label} FAILED:`,\n (err as Error).message,\n \"\\nStatement:\",\n currentStmt,\n );\n throw err;\n }\n }\n } finally {\n // Release the direct-endpoint exec (Postgres only). For SQLite getDbExec()\n // returns the process-lifetime singleton, so releaseMigrationExec is a no-op\n // (refCount never incremented for SQLite path, guard in releaseMigrationExec).\n if (pg) await releaseMigrationExec();\n }\n } catch (err) {\n console.error(\"[db] Migration failed:\", (err as Error).message);\n // In local dev, hard-fail so the developer catches errors immediately.\n // On serverless runtimes (Netlify Functions, Vercel, CF Workers) we\n // keep the process alive — the app will return 500s for routes that\n // depend on the missing tables, but at least other routes still work.\n // Note: Node.js 21+ defines globalThis.navigator, so we check for\n // serverless env vars instead of navigator presence.\n const isServerless =\n !!globalThis.process?.env?.NETLIFY ||\n !!globalThis.process?.env?.AWS_LAMBDA_FUNCTION_NAME ||\n !!globalThis.process?.env?.VERCEL ||\n \"__cf_env\" in globalThis;\n if (typeof globalThis.process?.exit === \"function\" && !isServerless) {\n process.exit(1);\n }\n }\n };\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export { listTables, getTableSchema, getRows, applyMutations, runSql, DbAdminConfirmRequiredError, type DbAdminRuntime, } from "./operations.js";
2
+ export type { DbAdminColumn, DbAdminDialect, DbAdminFilter, DbAdminFilterOp, DbAdminForeignKey, DbAdminIndex, DbAdminMutation, DbAdminMutationResult, DbAdminQueryResult, DbAdminRowsRequest, DbAdminRowsResult, DbAdminSort, DbAdminTableSchema, DbAdminTableSummary, } from "./types.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db-admin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,cAAc,EACd,OAAO,EACP,cAAc,EACd,MAAM,EACN,2BAA2B,EAC3B,KAAK,cAAc,GACpB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,aAAa,EACb,cAAc,EACd,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { listTables, getTableSchema, getRows, applyMutations, runSql, DbAdminConfirmRequiredError, } from "./operations.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db-admin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,cAAc,EACd,OAAO,EACP,cAAc,EACd,MAAM,EACN,2BAA2B,GAE5B,MAAM,iBAAiB,CAAC","sourcesContent":["export {\n listTables,\n getTableSchema,\n getRows,\n applyMutations,\n runSql,\n DbAdminConfirmRequiredError,\n type DbAdminRuntime,\n} from \"./operations.js\";\n\nexport type {\n DbAdminColumn,\n DbAdminDialect,\n DbAdminFilter,\n DbAdminFilterOp,\n DbAdminForeignKey,\n DbAdminIndex,\n DbAdminMutation,\n DbAdminMutationResult,\n DbAdminQueryResult,\n DbAdminRowsRequest,\n DbAdminRowsResult,\n DbAdminSort,\n DbAdminTableSchema,\n DbAdminTableSummary,\n} from \"./types.js\";\n"]}
@@ -1,11 +1,32 @@
1
+ /**
2
+ * Database admin operations.
3
+ *
4
+ * Pure, dialect-agnostic, RAW/UNSCOPED helpers backing the Supabase-Studio-like
5
+ * DB admin. These run the FULL database with no per-user `accessFilter`
6
+ * scoping. Callers MUST gate access before invoking them. The built-in core
7
+ * route gates this to dev + localhost; production-reachable surfaces must pass
8
+ * an explicit runtime for the target database and enforce their own admin-only
9
+ * checks before reading or mutating.
10
+ *
11
+ * All access goes through the unified `getDbExec()` client, which uses `?`
12
+ * placeholders (auto-converted to `$1,$2,…` for Postgres) and returns rows
13
+ * keyed by column name. Identifiers are validated against a strict pattern and
14
+ * always double-quoted; values are ALWAYS parameterized — never interpolated.
15
+ */
16
+ import { type DbExec, type Dialect } from "../db/client.js";
1
17
  import type { DbAdminDialect, DbAdminMutation, DbAdminMutationResult, DbAdminQueryResult, DbAdminRowsRequest, DbAdminRowsResult, DbAdminTableSchema, DbAdminTableSummary } from "./types.js";
2
- export declare function listTables(): Promise<{
18
+ export interface DbAdminRuntime {
19
+ db?: DbExec;
20
+ dialect?: Dialect;
21
+ notifyChange?: () => Promise<void>;
22
+ }
23
+ export declare function listTables(runtime?: DbAdminRuntime): Promise<{
3
24
  dialect: DbAdminDialect;
4
25
  tables: DbAdminTableSummary[];
5
26
  }>;
6
- export declare function getTableSchema(table: string): Promise<DbAdminTableSchema>;
7
- export declare function getRows(table: string, req: DbAdminRowsRequest): Promise<DbAdminRowsResult>;
8
- export declare function applyMutations(table: string, m: DbAdminMutation): Promise<DbAdminMutationResult>;
27
+ export declare function getTableSchema(table: string, runtime?: DbAdminRuntime): Promise<DbAdminTableSchema>;
28
+ export declare function getRows(table: string, req: DbAdminRowsRequest, runtime?: DbAdminRuntime): Promise<DbAdminRowsResult>;
29
+ export declare function applyMutations(table: string, m: DbAdminMutation, runtime?: DbAdminRuntime): Promise<DbAdminMutationResult>;
9
30
  /** Error thrown when a destructive statement is run without confirmation. */
10
31
  export declare class DbAdminConfirmRequiredError extends Error {
11
32
  readonly needsConfirm = true;
@@ -13,5 +34,5 @@ export declare class DbAdminConfirmRequiredError extends Error {
13
34
  }
14
35
  export declare function runSql(sql: string, params: unknown[] | undefined, opts?: {
15
36
  confirmDestructive?: boolean;
16
- }): Promise<DbAdminQueryResult>;
37
+ }, runtime?: DbAdminRuntime): Promise<DbAdminQueryResult>;
17
38
  //# sourceMappingURL=operations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/db-admin/operations.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAEV,cAAc,EAId,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAyCpB,wBAAsB,UAAU,IAAI,OAAO,CAAC;IAC1C,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,mBAAmB,EAAE,CAAC;CAC/B,CAAC,CAwCD;AAoBD,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,kBAAkB,CAAC,CAK7B;AAwRD,wBAAsB,OAAO,CAC3B,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,kBAAkB,GACtB,OAAO,CAAC,iBAAiB,CAAC,CA+B5B;AAyDD,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EACb,CAAC,EAAE,eAAe,GACjB,OAAO,CAAC,qBAAqB,CAAC,CA+ChC;AAMD,6EAA6E;AAC7E,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,YAAY,QAAQ;IAC7B,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAmCD,wBAAsB,MAAM,CAC1B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,EAC7B,IAAI,GAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1C,OAAO,CAAC,kBAAkB,CAAC,CAuC7B"}
1
+ {"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/db-admin/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,OAAO,EACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAEV,cAAc,EAId,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAQpB,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AA+CD,wBAAsB,UAAU,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC;IAClE,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,mBAAmB,EAAE,CAAC;CAC/B,CAAC,CAwCD;AAuBD,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,kBAAkB,CAAC,CAK7B;AA+RD,wBAAsB,OAAO,CAC3B,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,kBAAkB,EACvB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,iBAAiB,CAAC,CA+B5B;AAyDD,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EACb,CAAC,EAAE,eAAe,EAClB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,qBAAqB,CAAC,CA+ChC;AAMD,6EAA6E;AAC7E,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,YAAY,QAAQ;IAC7B,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAmCD,wBAAsB,MAAM,CAC1B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,EAC7B,IAAI,GAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAO,EAC3C,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,kBAAkB,CAAC,CAuC7B"}