@agent-native/core 0.127.3 → 0.128.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 (457) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +101 -0
  3. package/corpus/core/README.md +5 -26
  4. package/corpus/core/docs/content/actions.mdx +47 -4
  5. package/corpus/core/docs/content/native-chat-ui.mdx +7 -0
  6. package/corpus/core/docs/content/organizations-teams-permissions.mdx +109 -3
  7. package/corpus/core/docs/content/template-design-collaboration-and-full-apps.mdx +15 -0
  8. package/corpus/core/docs/content/toolkit-org-team.mdx +72 -12
  9. package/corpus/core/package.json +2 -1
  10. package/corpus/core/src/a2a/artifact-response.ts +36 -29
  11. package/corpus/core/src/action.ts +83 -2
  12. package/corpus/core/src/chat-threads/store.ts +48 -43
  13. package/corpus/core/src/cli/skills-content/design-visual-edit-skill.ts +46 -3
  14. package/corpus/core/src/client/AgentPanel.tsx +26 -6
  15. package/corpus/core/src/client/AssistantChat.tsx +63 -7
  16. package/corpus/core/src/client/DefaultSpinner.tsx +29 -0
  17. package/corpus/core/src/client/org/TeamPage.tsx +161 -6
  18. package/corpus/core/src/client/org/hooks.ts +67 -0
  19. package/corpus/core/src/client/org/index.ts +9 -0
  20. package/corpus/core/src/client/transcription/use-live-transcription.ts +62 -10
  21. package/corpus/core/src/db/client.ts +42 -3
  22. package/corpus/core/src/db/ensure-additive-columns.ts +60 -33
  23. package/corpus/core/src/deploy/build.ts +31 -2
  24. package/corpus/core/src/mcp-client/routes.ts +10 -1
  25. package/corpus/core/src/org/app-roles-handlers.ts +152 -0
  26. package/corpus/core/src/org/app-roles.ts +355 -0
  27. package/corpus/core/src/org/index.ts +27 -1
  28. package/corpus/core/src/org/migrations.ts +22 -0
  29. package/corpus/core/src/org/plugin.ts +27 -0
  30. package/corpus/core/src/org/schema.ts +15 -0
  31. package/corpus/core/src/scripts/docs/search.ts +17 -0
  32. package/corpus/core/src/scripts/docs/source-search.ts +10 -0
  33. package/corpus/core/src/server/agent-chat/script-entries.ts +3 -0
  34. package/corpus/core/src/server/agent-chat-plugin.ts +53 -52
  35. package/corpus/core/src/server/builder-design-systems.ts +299 -82
  36. package/corpus/core/src/server/core-routes-plugin.ts +6 -1
  37. package/corpus/core/src/server/framework-request-handler.ts +44 -6
  38. package/corpus/core/src/server/index.ts +8 -0
  39. package/corpus/core/src/templates/default/.agents/skills/actions/SKILL.md +32 -0
  40. package/corpus/core/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +7 -0
  41. package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +31 -0
  42. package/corpus/core/src/templates/headless/.agents/skills/actions/SKILL.md +32 -0
  43. package/corpus/core/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -0
  44. package/corpus/core/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +7 -0
  45. package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +40 -0
  46. package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +31 -0
  47. package/corpus/core/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +4 -0
  48. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +32 -0
  49. package/corpus/templates/analytics/.agents/skills/security/SKILL.md +31 -0
  50. package/corpus/templates/analytics/.agents/skills/sharing/SKILL.md +4 -0
  51. package/corpus/templates/analytics/_gitignore +2 -0
  52. package/corpus/templates/analytics/actions/data-source-status.ts +21 -12
  53. package/corpus/templates/analytics/app/global.css +7 -7
  54. package/corpus/templates/analytics/app/i18n-data.ts +30 -0
  55. package/corpus/templates/analytics/app/lib/data-source-status.ts +2 -1
  56. package/corpus/templates/analytics/app/pages/DataSources.tsx +54 -10
  57. package/corpus/templates/analytics/changelog/2026-07-28-analytics-pages-load-reliably-with-large-dashboard-workspaces.md +6 -0
  58. package/corpus/templates/analytics/changelog/2026-07-28-dashboard-loading-shimmer-now-flows-smoothly-in-one-directi.md +6 -0
  59. package/corpus/templates/analytics/server/lib/first-party-dashboard-repair.ts +5 -4
  60. package/corpus/templates/analytics/server/plugins/agent-chat.ts +54 -42
  61. package/corpus/templates/analytics/server/plugins/db.ts +1 -18
  62. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +32 -0
  63. package/corpus/templates/assets/.agents/skills/security/SKILL.md +31 -0
  64. package/corpus/templates/assets/.agents/skills/sharing/SKILL.md +4 -0
  65. package/corpus/templates/assets/_gitignore +2 -0
  66. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +32 -0
  67. package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +7 -0
  68. package/corpus/templates/brain/.agents/skills/security/SKILL.md +31 -0
  69. package/corpus/templates/brain/.agents/skills/sharing/SKILL.md +4 -0
  70. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +32 -0
  71. package/corpus/templates/calendar/.agents/skills/security/SKILL.md +31 -0
  72. package/corpus/templates/calendar/.agents/skills/sharing/SKILL.md +4 -0
  73. package/corpus/templates/calendar/_gitignore +2 -0
  74. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +32 -0
  75. package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +7 -0
  76. package/corpus/templates/chat/.agents/skills/security/SKILL.md +31 -0
  77. package/corpus/templates/chat/.agents/skills/sharing/SKILL.md +4 -0
  78. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +32 -0
  79. package/corpus/templates/clips/.agents/skills/security/SKILL.md +31 -0
  80. package/corpus/templates/clips/_gitignore +2 -0
  81. package/corpus/templates/clips/actions/request-transcript.ts +77 -11
  82. package/corpus/templates/clips/actions/save-browser-transcript.ts +28 -7
  83. package/corpus/templates/clips/app/routes/record.tsx +11 -3
  84. package/corpus/templates/clips/changelog/2026-07-28-browser-recordings-no-longer-save-a-truncated-transcript-as-.md +6 -0
  85. package/corpus/templates/clips/changelog/2026-07-28-browser-recordings-no-longer-stop-transcribing-partway-throu.md +6 -0
  86. package/corpus/templates/clips/changelog/2026-07-28-desktop-full-screen-clips-now-get-an-instant-local-transcrip.md +6 -0
  87. package/corpus/templates/clips/changelog/2026-07-28-long-transcriptions-no-longer-show-a-false-transcription-sto.md +6 -0
  88. package/corpus/templates/clips/changelog/2026-07-28-restarting-for-an-update-now-installs-the-newest-release-ins.md +6 -0
  89. package/corpus/templates/clips/changelog/2026-07-28-the-meeting-recording-pill-now-anchors-to-the-right-edge-of-.md +6 -0
  90. package/corpus/templates/clips/desktop/src/lib/audio-meter.ts +31 -2
  91. package/corpus/templates/clips/desktop/src/lib/recorder.ts +114 -13
  92. package/corpus/templates/clips/desktop/src/lib/updater.ts +12 -4
  93. package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +40 -15
  94. package/corpus/templates/clips/desktop/src/styles.css +10 -7
  95. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +21 -14
  96. package/corpus/templates/clips/shared/transcript-status.ts +10 -0
  97. package/corpus/templates/content/.agents/skills/actions/SKILL.md +32 -0
  98. package/corpus/templates/content/.agents/skills/security/SKILL.md +31 -0
  99. package/corpus/templates/content/.agents/skills/sharing/SKILL.md +4 -0
  100. package/corpus/templates/content/_gitignore +2 -0
  101. package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +4 -0
  102. package/corpus/templates/design/.agents/skills/actions/SKILL.md +32 -0
  103. package/corpus/templates/design/.agents/skills/security/SKILL.md +31 -0
  104. package/corpus/templates/design/.agents/skills/sharing/SKILL.md +4 -0
  105. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +46 -3
  106. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +7 -5
  107. package/corpus/templates/design/_gitignore +2 -0
  108. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +2 -2
  109. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +7 -4
  110. package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +1 -1
  111. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +10 -4
  112. package/corpus/templates/design/app/i18n-data.ts +10 -0
  113. package/corpus/templates/design/app/lib/builder-design-system-upload.ts +280 -0
  114. package/corpus/templates/design/app/lib/design-ui-events.ts +5 -0
  115. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +90 -54
  116. package/corpus/templates/design/app/root.tsx +18 -1
  117. package/corpus/templates/design/changelog/2026-07-28-figma-fig-uploads-now-show-indexing-progress-and-an-open-in-.md +6 -0
  118. package/corpus/templates/design/changelog/2026-07-28-show-or-hide-design-editing-chrome-with-cmd-on-apple-devices.md +6 -0
  119. package/corpus/templates/design/server/handlers/design-system-decode-job-status.ts +49 -0
  120. package/corpus/templates/design/server/handlers/design-system-upload-start.ts +87 -0
  121. package/corpus/templates/design/server/handlers/index-design-system-sources.ts +82 -0
  122. package/corpus/templates/design/server/routes/api/design-system-decode-job-status.get.ts +1 -0
  123. package/corpus/templates/design/server/routes/api/design-system-upload-start.post.ts +1 -0
  124. package/corpus/templates/design/server/routes/api/index-design-system-sources.post.ts +1 -0
  125. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +32 -0
  126. package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +31 -0
  127. package/corpus/templates/dispatch/.agents/skills/sharing/SKILL.md +4 -0
  128. package/corpus/templates/dispatch/_gitignore +2 -0
  129. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +32 -0
  130. package/corpus/templates/forms/.agents/skills/security/SKILL.md +31 -0
  131. package/corpus/templates/forms/.agents/skills/sharing/SKILL.md +4 -0
  132. package/corpus/templates/forms/_gitignore +2 -0
  133. package/corpus/templates/macros/.agents/skills/security/SKILL.md +31 -0
  134. package/corpus/templates/macros/.agents/skills/sharing/SKILL.md +4 -0
  135. package/corpus/templates/macros/_gitignore +2 -0
  136. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +32 -0
  137. package/corpus/templates/mail/.agents/skills/security/SKILL.md +31 -0
  138. package/corpus/templates/mail/.agents/skills/sharing/SKILL.md +4 -0
  139. package/corpus/templates/mail/_gitignore +2 -0
  140. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +32 -0
  141. package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +7 -0
  142. package/corpus/templates/plan/.agents/skills/security/SKILL.md +31 -0
  143. package/corpus/templates/plan/.agents/skills/sharing/SKILL.md +4 -0
  144. package/corpus/templates/plan/_gitignore +2 -0
  145. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +32 -0
  146. package/corpus/templates/slides/.agents/skills/security/SKILL.md +31 -0
  147. package/corpus/templates/slides/.agents/skills/sharing/SKILL.md +4 -0
  148. package/corpus/templates/slides/_gitignore +2 -0
  149. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +126 -53
  150. package/corpus/templates/slides/app/components/design-system/builder-design-system-upload.ts +271 -0
  151. package/corpus/templates/slides/app/components/design-system/builder-index-response.ts +1 -1
  152. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  153. package/corpus/templates/slides/server/handlers/design-system-decode-job-status.ts +49 -0
  154. package/corpus/templates/slides/server/handlers/design-system-upload-start.ts +87 -0
  155. package/corpus/templates/slides/server/handlers/index-design-system-sources.ts +79 -0
  156. package/corpus/templates/slides/server/routes/api/design-system-decode-job-status.get.ts +1 -0
  157. package/corpus/templates/slides/server/routes/api/design-system-upload-start.post.ts +1 -0
  158. package/corpus/templates/slides/server/routes/api/index-design-system-sources.post.ts +1 -0
  159. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +32 -0
  160. package/corpus/templates/tasks/.agents/skills/adding-a-feature/SKILL.md +7 -0
  161. package/corpus/templates/tasks/.agents/skills/security/SKILL.md +31 -0
  162. package/corpus/templates/tasks/.agents/skills/sharing/SKILL.md +4 -0
  163. package/corpus/templates/tasks/_gitignore +2 -0
  164. package/dist/a2a/artifact-response.d.ts.map +1 -1
  165. package/dist/a2a/artifact-response.js +30 -29
  166. package/dist/a2a/artifact-response.js.map +1 -1
  167. package/dist/action.d.ts +36 -0
  168. package/dist/action.d.ts.map +1 -1
  169. package/dist/action.js +37 -2
  170. package/dist/action.js.map +1 -1
  171. package/dist/chat-threads/store.d.ts +12 -0
  172. package/dist/chat-threads/store.d.ts.map +1 -1
  173. package/dist/chat-threads/store.js +48 -42
  174. package/dist/chat-threads/store.js.map +1 -1
  175. package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
  176. package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
  177. package/dist/cli/skills-content/design-visual-edit-skill.js +46 -3
  178. package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
  179. package/dist/client/AgentPanel.d.ts +3 -1
  180. package/dist/client/AgentPanel.d.ts.map +1 -1
  181. package/dist/client/AgentPanel.js +11 -9
  182. package/dist/client/AgentPanel.js.map +1 -1
  183. package/dist/client/AssistantChat.d.ts.map +1 -1
  184. package/dist/client/AssistantChat.js +57 -6
  185. package/dist/client/AssistantChat.js.map +1 -1
  186. package/dist/client/DefaultSpinner.d.ts +7 -0
  187. package/dist/client/DefaultSpinner.d.ts.map +1 -1
  188. package/dist/client/DefaultSpinner.js +25 -1
  189. package/dist/client/DefaultSpinner.js.map +1 -1
  190. package/dist/client/org/TeamPage.d.ts +13 -1
  191. package/dist/client/org/TeamPage.d.ts.map +1 -1
  192. package/dist/client/org/TeamPage.js +41 -11
  193. package/dist/client/org/TeamPage.js.map +1 -1
  194. package/dist/client/org/hooks.d.ts +37 -0
  195. package/dist/client/org/hooks.d.ts.map +1 -1
  196. package/dist/client/org/hooks.js +37 -0
  197. package/dist/client/org/hooks.js.map +1 -1
  198. package/dist/client/org/index.d.ts +3 -2
  199. package/dist/client/org/index.d.ts.map +1 -1
  200. package/dist/client/org/index.js +1 -1
  201. package/dist/client/org/index.js.map +1 -1
  202. package/dist/client/transcription/use-live-transcription.d.ts +8 -0
  203. package/dist/client/transcription/use-live-transcription.d.ts.map +1 -1
  204. package/dist/client/transcription/use-live-transcription.js +38 -11
  205. package/dist/client/transcription/use-live-transcription.js.map +1 -1
  206. package/dist/collab/routes.d.ts +1 -1
  207. package/dist/db/client.d.ts +12 -0
  208. package/dist/db/client.d.ts.map +1 -1
  209. package/dist/db/client.js +40 -3
  210. package/dist/db/client.js.map +1 -1
  211. package/dist/db/ensure-additive-columns.d.ts.map +1 -1
  212. package/dist/db/ensure-additive-columns.js +54 -32
  213. package/dist/db/ensure-additive-columns.js.map +1 -1
  214. package/dist/deploy/build.d.ts +1 -0
  215. package/dist/deploy/build.d.ts.map +1 -1
  216. package/dist/deploy/build.js +23 -2
  217. package/dist/deploy/build.js.map +1 -1
  218. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  219. package/dist/mcp-client/routes.d.ts +3 -1
  220. package/dist/mcp-client/routes.d.ts.map +1 -1
  221. package/dist/mcp-client/routes.js +8 -2
  222. package/dist/mcp-client/routes.js.map +1 -1
  223. package/dist/notifications/routes.d.ts +1 -1
  224. package/dist/org/app-roles-handlers.d.ts +27 -0
  225. package/dist/org/app-roles-handlers.d.ts.map +1 -0
  226. package/dist/org/app-roles-handlers.js +125 -0
  227. package/dist/org/app-roles-handlers.js.map +1 -0
  228. package/dist/org/app-roles.d.ts +136 -0
  229. package/dist/org/app-roles.d.ts.map +1 -0
  230. package/dist/org/app-roles.js +216 -0
  231. package/dist/org/app-roles.js.map +1 -0
  232. package/dist/org/index.d.ts +4 -1
  233. package/dist/org/index.d.ts.map +1 -1
  234. package/dist/org/index.js +3 -1
  235. package/dist/org/index.js.map +1 -1
  236. package/dist/org/migrations.d.ts.map +1 -1
  237. package/dist/org/migrations.js +22 -0
  238. package/dist/org/migrations.js.map +1 -1
  239. package/dist/org/plugin.d.ts +2 -0
  240. package/dist/org/plugin.d.ts.map +1 -1
  241. package/dist/org/plugin.js +20 -0
  242. package/dist/org/plugin.js.map +1 -1
  243. package/dist/org/schema.d.ts +143 -0
  244. package/dist/org/schema.d.ts.map +1 -1
  245. package/dist/org/schema.js +14 -0
  246. package/dist/org/schema.js.map +1 -1
  247. package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
  248. package/dist/provider-api/actions/provider-api.d.ts +4 -4
  249. package/dist/scripts/docs/search.d.ts.map +1 -1
  250. package/dist/scripts/docs/search.js +15 -0
  251. package/dist/scripts/docs/search.js.map +1 -1
  252. package/dist/scripts/docs/source-search.d.ts +7 -0
  253. package/dist/scripts/docs/source-search.d.ts.map +1 -1
  254. package/dist/scripts/docs/source-search.js +9 -0
  255. package/dist/scripts/docs/source-search.js.map +1 -1
  256. package/dist/secrets/routes.d.ts +9 -9
  257. package/dist/server/agent-chat/script-entries.d.ts.map +1 -1
  258. package/dist/server/agent-chat/script-entries.js +3 -0
  259. package/dist/server/agent-chat/script-entries.js.map +1 -1
  260. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  261. package/dist/server/agent-chat-plugin.js +46 -48
  262. package/dist/server/agent-chat-plugin.js.map +1 -1
  263. package/dist/server/builder-design-systems.d.ts +49 -0
  264. package/dist/server/builder-design-systems.d.ts.map +1 -1
  265. package/dist/server/builder-design-systems.js +221 -69
  266. package/dist/server/builder-design-systems.js.map +1 -1
  267. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  268. package/dist/server/core-routes-plugin.js +6 -1
  269. package/dist/server/core-routes-plugin.js.map +1 -1
  270. package/dist/server/framework-request-handler.d.ts.map +1 -1
  271. package/dist/server/framework-request-handler.js +42 -6
  272. package/dist/server/framework-request-handler.js.map +1 -1
  273. package/dist/server/index.d.ts +1 -1
  274. package/dist/server/index.d.ts.map +1 -1
  275. package/dist/server/index.js +1 -1
  276. package/dist/server/index.js.map +1 -1
  277. package/dist/server/realtime-token.d.ts +1 -1
  278. package/dist/templates/chat/.agents/skills/actions/SKILL.md +32 -0
  279. package/dist/templates/chat/.agents/skills/adding-a-feature/SKILL.md +7 -0
  280. package/dist/templates/chat/.agents/skills/security/SKILL.md +31 -0
  281. package/dist/templates/chat/.agents/skills/sharing/SKILL.md +4 -0
  282. package/dist/templates/default/.agents/skills/actions/SKILL.md +32 -0
  283. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +7 -0
  284. package/dist/templates/default/.agents/skills/security/SKILL.md +31 -0
  285. package/dist/templates/headless/.agents/skills/actions/SKILL.md +32 -0
  286. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -0
  287. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +7 -0
  288. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +40 -0
  289. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +31 -0
  290. package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +4 -0
  291. package/docs/content/actions.mdx +47 -4
  292. package/docs/content/native-chat-ui.mdx +7 -0
  293. package/docs/content/organizations-teams-permissions.mdx +109 -3
  294. package/docs/content/template-design-collaboration-and-full-apps.mdx +15 -0
  295. package/docs/content/toolkit-org-team.mdx +72 -12
  296. package/package.json +2 -1
  297. package/src/a2a/artifact-response.ts +36 -29
  298. package/src/action.ts +83 -2
  299. package/src/chat-threads/store.ts +48 -43
  300. package/src/cli/skills-content/design-visual-edit-skill.ts +46 -3
  301. package/src/client/AgentPanel.tsx +26 -6
  302. package/src/client/AssistantChat.tsx +63 -7
  303. package/src/client/DefaultSpinner.tsx +29 -0
  304. package/src/client/org/TeamPage.tsx +161 -6
  305. package/src/client/org/hooks.ts +67 -0
  306. package/src/client/org/index.ts +9 -0
  307. package/src/client/transcription/use-live-transcription.ts +62 -10
  308. package/src/db/client.ts +42 -3
  309. package/src/db/ensure-additive-columns.ts +60 -33
  310. package/src/deploy/build.ts +31 -2
  311. package/src/mcp-client/routes.ts +10 -1
  312. package/src/org/app-roles-handlers.ts +152 -0
  313. package/src/org/app-roles.ts +355 -0
  314. package/src/org/index.ts +27 -1
  315. package/src/org/migrations.ts +22 -0
  316. package/src/org/plugin.ts +27 -0
  317. package/src/org/schema.ts +15 -0
  318. package/src/scripts/docs/search.ts +17 -0
  319. package/src/scripts/docs/source-search.ts +10 -0
  320. package/src/server/agent-chat/script-entries.ts +3 -0
  321. package/src/server/agent-chat-plugin.ts +53 -52
  322. package/src/server/builder-design-systems.ts +299 -82
  323. package/src/server/core-routes-plugin.ts +6 -1
  324. package/src/server/framework-request-handler.ts +44 -6
  325. package/src/server/index.ts +8 -0
  326. package/src/templates/chat/.agents/skills/actions/SKILL.md +32 -0
  327. package/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +7 -0
  328. package/src/templates/chat/.agents/skills/security/SKILL.md +31 -0
  329. package/src/templates/chat/.agents/skills/sharing/SKILL.md +4 -0
  330. package/src/templates/default/.agents/skills/actions/SKILL.md +32 -0
  331. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +7 -0
  332. package/src/templates/default/.agents/skills/security/SKILL.md +31 -0
  333. package/src/templates/headless/.agents/skills/actions/SKILL.md +32 -0
  334. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -0
  335. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +7 -0
  336. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +40 -0
  337. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +31 -0
  338. package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +4 -0
  339. package/corpus/core/src/templates/chat/.agents/skills/actions/SKILL.md +0 -530
  340. package/corpus/core/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +0 -191
  341. package/corpus/core/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +0 -115
  342. package/corpus/core/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +0 -177
  343. package/corpus/core/src/templates/chat/.agents/skills/capture-learnings/SKILL.md +0 -89
  344. package/corpus/core/src/templates/chat/.agents/skills/create-skill/SKILL.md +0 -221
  345. package/corpus/core/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +0 -220
  346. package/corpus/core/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +0 -263
  347. package/corpus/core/src/templates/chat/.agents/skills/feature-flags/SKILL.md +0 -169
  348. package/corpus/core/src/templates/chat/.agents/skills/frontend-design/SKILL.md +0 -174
  349. package/corpus/core/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +0 -232
  350. package/corpus/core/src/templates/chat/.agents/skills/security/SKILL.md +0 -282
  351. package/corpus/core/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +0 -119
  352. package/corpus/core/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +0 -123
  353. package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +0 -122
  354. package/corpus/core/src/templates/chat/.env.example +0 -5
  355. package/corpus/core/src/templates/chat/.ignore +0 -0
  356. package/corpus/core/src/templates/chat/.oxfmtrc.json +0 -8
  357. package/corpus/core/src/templates/chat/AGENTS.md +0 -77
  358. package/corpus/core/src/templates/chat/CHANGELOG.md +0 -10
  359. package/corpus/core/src/templates/chat/DEVELOPING.md +0 -185
  360. package/corpus/core/src/templates/chat/README.md +0 -32
  361. package/corpus/core/src/templates/chat/_gitignore +0 -46
  362. package/corpus/core/src/templates/chat/actions/hello.ts +0 -13
  363. package/corpus/core/src/templates/chat/actions/navigate.ts +0 -41
  364. package/corpus/core/src/templates/chat/actions/run.ts +0 -2
  365. package/corpus/core/src/templates/chat/actions/view-screen.ts +0 -31
  366. package/corpus/core/src/templates/chat/app/components/layout/Header.tsx +0 -60
  367. package/corpus/core/src/templates/chat/app/components/layout/Layout.tsx +0 -188
  368. package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +0 -505
  369. package/corpus/core/src/templates/chat/app/components/ui/button.tsx +0 -1
  370. package/corpus/core/src/templates/chat/app/components/ui/card.tsx +0 -1
  371. package/corpus/core/src/templates/chat/app/components/ui/dropdown-menu.tsx +0 -1
  372. package/corpus/core/src/templates/chat/app/components/ui/input.tsx +0 -1
  373. package/corpus/core/src/templates/chat/app/components/ui/label.tsx +0 -1
  374. package/corpus/core/src/templates/chat/app/components/ui/sheet.tsx +0 -1
  375. package/corpus/core/src/templates/chat/app/components/ui/toolkit-provider.tsx +0 -17
  376. package/corpus/core/src/templates/chat/app/components/ui/tooltip.tsx +0 -1
  377. package/corpus/core/src/templates/chat/app/design-system.ts +0 -3
  378. package/corpus/core/src/templates/chat/app/entry.client.tsx +0 -22
  379. package/corpus/core/src/templates/chat/app/entry.server.tsx +0 -10
  380. package/corpus/core/src/templates/chat/app/global.css +0 -93
  381. package/corpus/core/src/templates/chat/app/hooks/use-navigation-state.ts +0 -93
  382. package/corpus/core/src/templates/chat/app/i18n/ar-SA.ts +0 -68
  383. package/corpus/core/src/templates/chat/app/i18n/de-DE.ts +0 -71
  384. package/corpus/core/src/templates/chat/app/i18n/en-US.ts +0 -70
  385. package/corpus/core/src/templates/chat/app/i18n/es-ES.ts +0 -71
  386. package/corpus/core/src/templates/chat/app/i18n/fr-FR.ts +0 -71
  387. package/corpus/core/src/templates/chat/app/i18n/hi-IN.ts +0 -69
  388. package/corpus/core/src/templates/chat/app/i18n/index.ts +0 -34
  389. package/corpus/core/src/templates/chat/app/i18n/ja-JP.ts +0 -70
  390. package/corpus/core/src/templates/chat/app/i18n/ko-KR.ts +0 -70
  391. package/corpus/core/src/templates/chat/app/i18n/pt-BR.ts +0 -71
  392. package/corpus/core/src/templates/chat/app/i18n/zh-CN.ts +0 -66
  393. package/corpus/core/src/templates/chat/app/i18n/zh-TW.ts +0 -66
  394. package/corpus/core/src/templates/chat/app/i18n-data.ts +0 -556
  395. package/corpus/core/src/templates/chat/app/lib/agent-page.tsx +0 -49
  396. package/corpus/core/src/templates/chat/app/lib/app-config.ts +0 -11
  397. package/corpus/core/src/templates/chat/app/lib/tab-id.ts +0 -1
  398. package/corpus/core/src/templates/chat/app/lib/utils.ts +0 -1
  399. package/corpus/core/src/templates/chat/app/root.tsx +0 -173
  400. package/corpus/core/src/templates/chat/app/routes/_index.tsx +0 -94
  401. package/corpus/core/src/templates/chat/app/routes/agent.tsx +0 -24
  402. package/corpus/core/src/templates/chat/app/routes/chat.$threadId.tsx +0 -1
  403. package/corpus/core/src/templates/chat/app/routes/database.tsx +0 -17
  404. package/corpus/core/src/templates/chat/app/routes/extensions.$id.$slug.tsx +0 -2
  405. package/corpus/core/src/templates/chat/app/routes/extensions.$id.tsx +0 -11
  406. package/corpus/core/src/templates/chat/app/routes/extensions._index.tsx +0 -11
  407. package/corpus/core/src/templates/chat/app/routes/extensions.tsx +0 -5
  408. package/corpus/core/src/templates/chat/app/routes/observability.tsx +0 -19
  409. package/corpus/core/src/templates/chat/app/routes/settings.tsx +0 -89
  410. package/corpus/core/src/templates/chat/app/routes/team.tsx +0 -11
  411. package/corpus/core/src/templates/chat/app/routes.ts +0 -4
  412. package/corpus/core/src/templates/chat/app/vite-env.d.ts +0 -6
  413. package/corpus/core/src/templates/chat/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +0 -6
  414. package/corpus/core/src/templates/chat/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +0 -6
  415. package/corpus/core/src/templates/chat/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +0 -6
  416. package/corpus/core/src/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +0 -6
  417. package/corpus/core/src/templates/chat/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +0 -6
  418. package/corpus/core/src/templates/chat/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +0 -5
  419. package/corpus/core/src/templates/chat/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +0 -6
  420. package/corpus/core/src/templates/chat/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +0 -6
  421. package/corpus/core/src/templates/chat/changelog/2026-07-14-chat-opens-reliably-on-hosted-deployments-instead-of-failing.md +0 -6
  422. package/corpus/core/src/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +0 -6
  423. package/corpus/core/src/templates/chat/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +0 -6
  424. package/corpus/core/src/templates/chat/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +0 -6
  425. package/corpus/core/src/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +0 -6
  426. package/corpus/core/src/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +0 -6
  427. package/corpus/core/src/templates/chat/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +0 -6
  428. package/corpus/core/src/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +0 -6
  429. package/corpus/core/src/templates/chat/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +0 -6
  430. package/corpus/core/src/templates/chat/changelog/2026-07-24-borderless-secondary-surfaces.md +0 -6
  431. package/corpus/core/src/templates/chat/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +0 -6
  432. package/corpus/core/src/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +0 -6
  433. package/corpus/core/src/templates/chat/components.json +0 -20
  434. package/corpus/core/src/templates/chat/learnings.defaults.md +0 -5
  435. package/corpus/core/src/templates/chat/netlify.toml +0 -11
  436. package/corpus/core/src/templates/chat/package.json +0 -92
  437. package/corpus/core/src/templates/chat/public/agent-native-icon-dark.svg +0 -10
  438. package/corpus/core/src/templates/chat/public/agent-native-icon-light.svg +0 -10
  439. package/corpus/core/src/templates/chat/public/agent-native-logo-dark.svg +0 -21
  440. package/corpus/core/src/templates/chat/public/agent-native-logo-light.svg +0 -21
  441. package/corpus/core/src/templates/chat/public/favicon.svg +0 -1
  442. package/corpus/core/src/templates/chat/public/icon-180.svg +0 -1
  443. package/corpus/core/src/templates/chat/public/icon-192.svg +0 -1
  444. package/corpus/core/src/templates/chat/public/icon-512.svg +0 -1
  445. package/corpus/core/src/templates/chat/public/manifest.json +0 -21
  446. package/corpus/core/src/templates/chat/react-router.config.ts +0 -7
  447. package/corpus/core/src/templates/chat/server/middleware/auth.ts +0 -15
  448. package/corpus/core/src/templates/chat/server/plugins/agent-chat.ts +0 -21
  449. package/corpus/core/src/templates/chat/server/plugins/auth.ts +0 -17
  450. package/corpus/core/src/templates/chat/server/routes/[...page].get.ts +0 -5
  451. package/corpus/core/src/templates/chat/ssr-entry.ts +0 -15
  452. package/corpus/core/src/templates/chat/tsconfig.json +0 -21
  453. package/corpus/core/src/templates/chat/vite.config.ts +0 -19
  454. package/corpus/templates/design/server/handlers/index-design-system-with-builder.ts +0 -151
  455. package/corpus/templates/design/server/routes/api/index-design-system-with-builder.post.ts +0 -1
  456. package/corpus/templates/slides/server/handlers/index-design-system-with-builder.ts +0 -119
  457. package/corpus/templates/slides/server/routes/api/index-design-system-with-builder.post.ts +0 -1
@@ -82,35 +82,49 @@ async function loadGetTableConfig() {
82
82
  return getTableConfig;
83
83
  }
84
84
  /**
85
- * Live columns already present on `table`, keyed by column name.
86
- * Postgres: `information_schema.columns` scoped to the table's schema
87
- * (default `public`). SQLite: `PRAGMA table_info(table)`.
88
- *
89
- * Returns `null` when the table itself does not exist (caller no-ops —
90
- * table creation owns that path) or when introspection fails outright.
85
+ * Load every requested Postgres table's live columns in one round trip.
86
+ * Calling information_schema separately for each table adds dozens of
87
+ * serialized network requests to every serverless cold start.
91
88
  */
92
- async function introspectLiveColumns(db, table, schema) {
93
- if (isPostgres()) {
94
- try {
95
- const tableSchema = schema || "public";
96
- const { rows: existsRows } = await db.execute({
97
- sql: `SELECT 1 FROM information_schema.tables
98
- WHERE table_schema = ? AND table_name = ? LIMIT 1`,
99
- args: [tableSchema, table],
100
- });
101
- if (existsRows.length === 0)
102
- return null;
103
- const { rows } = await db.execute({
104
- sql: `SELECT column_name FROM information_schema.columns
105
- WHERE table_schema = ? AND table_name = ?`,
106
- args: [tableSchema, table],
107
- });
108
- return new Set(rows.map((r) => String(r.column_name)));
109
- }
110
- catch {
111
- return null;
89
+ async function introspectPostgresColumns(db, tables) {
90
+ if (tables.length === 0)
91
+ return new Map();
92
+ const pairs = [
93
+ ...new Map(tables.map((table) => {
94
+ const schema = table.schema || "public";
95
+ return [`${schema}.${table.name}`, { schema, table: table.name }];
96
+ })).values(),
97
+ ];
98
+ const args = [];
99
+ const predicates = pairs.map(({ schema, table }) => {
100
+ args.push(schema, table);
101
+ return `(table_schema = ? AND table_name = ?)`;
102
+ });
103
+ try {
104
+ const { rows } = await db.execute({
105
+ sql: `SELECT table_schema, table_name, column_name
106
+ FROM information_schema.columns
107
+ WHERE ${predicates.join(" OR ")}`,
108
+ args,
109
+ });
110
+ const columns = new Map();
111
+ for (const row of rows) {
112
+ const key = `${String(row.table_schema)}.${String(row.table_name)}`;
113
+ const tableColumns = columns.get(key) ?? new Set();
114
+ tableColumns.add(String(row.column_name));
115
+ columns.set(key, tableColumns);
112
116
  }
117
+ return columns;
113
118
  }
119
+ catch {
120
+ return null;
121
+ }
122
+ }
123
+ /**
124
+ * Live SQLite columns already present on `table`, keyed by column name.
125
+ * Returns `null` when the table does not exist or introspection fails.
126
+ */
127
+ async function introspectSqliteLiveColumns(db, table) {
114
128
  // SQLite: PRAGMA table_info returns zero rows for a non-existent table
115
129
  // (no error), so we can't distinguish "missing table" from "no columns"
116
130
  // that way — probe sqlite_master first.
@@ -246,24 +260,32 @@ export async function ensureAdditiveColumns(options) {
246
260
  });
247
261
  return result;
248
262
  }
263
+ const declaredTables = [];
249
264
  for (const tableObj of tables) {
250
- let config;
251
265
  try {
252
- config = getTableConfig(tableObj);
266
+ const config = getTableConfig(tableObj);
267
+ if (config.name && PLAIN_IDENTIFIER.test(config.name)) {
268
+ declaredTables.push(config);
269
+ }
253
270
  }
254
271
  catch (err) {
255
272
  // Not a table this dialect's getTableConfig understands (e.g. a stray
256
273
  // export that isn't a Drizzle table) — skip quietly rather than
257
274
  // erroring the whole run over one bad entry.
258
275
  logger.warn(`[ensure-additive-columns] skipping non-table export: ${err instanceof Error ? err.message : String(err)}`);
259
- continue;
260
276
  }
277
+ }
278
+ const postgresColumns = isPostgres()
279
+ ? await introspectPostgresColumns(db, declaredTables)
280
+ : null;
281
+ for (const config of declaredTables) {
261
282
  const tableName = config.name;
262
- if (!tableName || !PLAIN_IDENTIFIER.test(tableName))
263
- continue;
264
283
  let liveColumns;
265
284
  try {
266
- liveColumns = await introspectLiveColumns(db, tableName, config.schema);
285
+ liveColumns = isPostgres()
286
+ ? (postgresColumns?.get(`${config.schema || "public"}.${tableName}`) ??
287
+ null)
288
+ : await introspectSqliteLiveColumns(db, tableName);
267
289
  }
268
290
  catch (err) {
269
291
  result.errors.push({
@@ -1 +1 @@
1
- {"version":3,"file":"ensure-additive-columns.js","sourceRoot":"","sources":["../../src/db/ensure-additive-columns.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Boot-time convergence for columns Drizzle's schema declares but a\n * pre-existing table is missing.\n *\n * Lives in its own module (like `./widen-columns.js`) so stores/plugins can\n * import it without every `vi.mock(\"../db/client.js\")` test needing to stub\n * it: the helper resolves `isPostgres()` / `getDbExec()` through `client.js`,\n * so a test that mocks the client to SQLite makes the Postgres introspection\n * path a no-op automatically.\n *\n * ## Why\n *\n * `CREATE TABLE IF NOT EXISTS` only runs the CREATE the first time a table is\n * created — once it exists, adding a column to the Drizzle schema (e.g.\n * `schema.ts`) does nothing to already-existing rows unless a hand-written\n * `ALTER TABLE ... ADD COLUMN` migration ships alongside it. Fresh dev\n * databases mask this because the CREATE always includes every declared\n * column; only long-lived, pre-existing production tables are missing the\n * new column. Forgetting the migration turns every query that references the\n * column into a Postgres `42703 (undefined_column)` — e.g.\n * `session_recordings.network_error_count`, which 500'd every\n * `list-session-recordings` call.\n *\n * `ensureAdditiveColumns()` is belt-and-braces for that failure mode: after\n * the authoritative hand-written migrations run, diff each Drizzle table's\n * declared columns against the live table and additively patch any gap. It\n * is NOT a replacement for migrations — it never touches indexes, data\n * transforms, or existing columns, and a hand-written migration should still\n * ship for every schema change. This is a safety net for the case where one\n * doesn't.\n *\n * ## Safety rules (hard)\n *\n * - Additive only: never drops, renames, retypes, or otherwise touches a\n * column that already exists on the live table.\n * - A `NOT NULL` column is only ever added when it has a renderable default\n * (so existing rows get a valid value in the same statement). If it has no\n * renderable default, it is added as nullable when the Drizzle declaration\n * allows null, else the column is SKIPPED entirely with a loud log line\n * naming the column and the reason.\n * - Only simple literal defaults are rendered: numbers, strings, booleans,\n * and `sql` template defaults that stringify to one of a small allow-listed\n * set of safe constants (see `renderDefaultLiteral`). Any other `sql`\n * default is NOT rendered — the column is added without a `DEFAULT` (and\n * without `NOT NULL`, per the rule above) rather than risk interpolating\n * unsafe SQL.\n * - All identifiers (table/column names) are validated against a strict\n * `[A-Za-z_][A-Za-z0-9_]*` pattern and double-quoted; no value from a row or\n * from user data is ever interpolated into the generated SQL.\n * - If the table itself does not exist yet, this is a no-op — table creation\n * owns bringing every declared column into existence for a brand-new table.\n * - Idempotent and best-effort: a failure on one column is logged and does\n * not abort the rest, and a total failure (e.g. `information_schema`\n * unreadable) must never crash boot — the caller decides whether/how to\n * surface `errors` in the returned summary.\n */\n\nimport { isPostgres, type DbExec } from \"./client.js\";\n\nconst PLAIN_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nexport interface EnsureAdditiveColumnsLogger {\n info: (message: string) => void;\n warn: (message: string) => void;\n error: (message: string) => void;\n}\n\nconst defaultLogger: EnsureAdditiveColumnsLogger = {\n info: (message) => console.log(message),\n warn: (message) => console.warn(message),\n error: (message) => console.error(message),\n};\n\n/**\n * Minimal shape this module needs from a Drizzle column — matches both\n * `drizzle-orm/pg-core` and `drizzle-orm/sqlite-core` column instances (and\n * the dialect-agnostic wrappers in `./schema.js`, which delegate to one or\n * the other at runtime).\n */\ninterface DeclaredColumnLike {\n name: string;\n notNull: boolean;\n hasDefault: boolean;\n default: unknown;\n getSQLType(): string;\n}\n\ninterface DeclaredTableLike {\n columns: DeclaredColumnLike[];\n name: string;\n schema?: string;\n}\n\nexport interface EnsureAdditiveColumnsOptions {\n db: DbExec;\n /** Drizzle table objects (from `pgTable`/`sqliteTable`, or the dialect-agnostic `table()` helper). */\n tables: unknown[];\n logger?: EnsureAdditiveColumnsLogger;\n}\n\nexport interface EnsureAdditiveColumnsResult {\n /** `\"table.column\"` entries that were successfully added. */\n applied: string[];\n /** Declared columns that were intentionally left unpatched, with why. */\n skipped: Array<{ column: string; reason: string }>;\n /** `\"table.column\"` entries whose ALTER failed unexpectedly (logged, non-fatal). */\n errors: Array<{ column: string; error: string }>;\n}\n\nfunction emptyResult(): EnsureAdditiveColumnsResult {\n return { applied: [], skipped: [], errors: [] };\n}\n\n/**\n * Resolve `getTableConfig` for the dialect currently in effect. Both\n * `drizzle-orm/pg-core` and `drizzle-orm/sqlite-core` export a function with\n * this name and a compatible-enough shape (`{ columns, name, schema? }`), but\n * each only understands its own table class — calling the wrong one throws.\n * `table()` from `./schema.js` builds a `pgTable` on Postgres and a\n * `sqliteTable` everywhere else, so the same dialect switch used there\n * decides which `getTableConfig` to load here.\n */\nasync function loadGetTableConfig(): Promise<\n (table: unknown) => DeclaredTableLike\n> {\n if (isPostgres()) {\n const { getTableConfig } = await import(\"drizzle-orm/pg-core\");\n return getTableConfig as unknown as (table: unknown) => DeclaredTableLike;\n }\n const { getTableConfig } = await import(\"drizzle-orm/sqlite-core\");\n return getTableConfig as unknown as (table: unknown) => DeclaredTableLike;\n}\n\n/**\n * Live columns already present on `table`, keyed by column name.\n * Postgres: `information_schema.columns` scoped to the table's schema\n * (default `public`). SQLite: `PRAGMA table_info(table)`.\n *\n * Returns `null` when the table itself does not exist (caller no-ops —\n * table creation owns that path) or when introspection fails outright.\n */\nasync function introspectLiveColumns(\n db: DbExec,\n table: string,\n schema: string | undefined,\n): Promise<Set<string> | null> {\n if (isPostgres()) {\n try {\n const tableSchema = schema || \"public\";\n const { rows: existsRows } = await db.execute({\n sql: `SELECT 1 FROM information_schema.tables\n WHERE table_schema = ? AND table_name = ? LIMIT 1`,\n args: [tableSchema, table],\n });\n if (existsRows.length === 0) return null;\n const { rows } = await db.execute({\n sql: `SELECT column_name FROM information_schema.columns\n WHERE table_schema = ? AND table_name = ?`,\n args: [tableSchema, table],\n });\n return new Set(rows.map((r) => String(r.column_name)));\n } catch {\n return null;\n }\n }\n\n // SQLite: PRAGMA table_info returns zero rows for a non-existent table\n // (no error), so we can't distinguish \"missing table\" from \"no columns\"\n // that way — probe sqlite_master first.\n try {\n const { rows: existsRows } = await db.execute({\n sql: `SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ? LIMIT 1`,\n args: [table],\n });\n if (existsRows.length === 0) return null;\n // PRAGMA doesn't support bound parameters; the table name is already\n // validated against PLAIN_IDENTIFIER by the caller before we get here.\n const { rows } = await db.execute(`PRAGMA table_info(\"${table}\")`);\n return new Set(rows.map((r) => String(r.name)));\n } catch {\n return null;\n }\n}\n\n/** Quote a validated identifier for use in generated SQL. */\nfunction quoteIdent(name: string): string {\n return `\"${name}\"`;\n}\n\n/**\n * Render a column's declared default as a SQL literal, or `undefined` if it\n * can't be rendered safely. Only numbers, strings, booleans, and a small\n * allow-list of `sql` template defaults that stringify to a known-safe\n * constant are supported — anything else is deliberately left unrendered so\n * we never interpolate arbitrary SQL.\n */\nfunction renderDefaultLiteral(column: DeclaredColumnLike): string | undefined {\n if (!column.hasDefault) return undefined;\n const value = column.default;\n if (value == null) return undefined;\n\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return String(value);\n }\n if (typeof value === \"boolean\") {\n return isPostgres() ? (value ? \"true\" : \"false\") : value ? \"1\" : \"0\";\n }\n if (typeof value === \"string\") {\n // Escape single quotes for a plain string literal.\n return `'${value.replace(/'/g, \"''\")}'`;\n }\n\n // Drizzle `sql` template defaults (e.g. `now()`, `(datetime('now'))`) carry\n // a `queryChunks`/`toQuery`-style object rather than a plain scalar. Only\n // render the handful of known-safe constants used by this codebase's\n // `now()` helper (see ./schema.ts) — never stringify arbitrary SQL.\n const raw = sqlDefaultText(value);\n if (raw == null) return undefined;\n const normalized = raw.trim().toLowerCase();\n const SAFE_SQL_DEFAULTS = new Set([\n \"now()\",\n \"(datetime('now'))\",\n \"current_timestamp\",\n \"current_date\",\n \"current_time\",\n ]);\n if (SAFE_SQL_DEFAULTS.has(normalized)) {\n return raw.trim();\n }\n return undefined;\n}\n\n/**\n * Best-effort extraction of the raw SQL text from a drizzle `SQL` default\n * object (e.g. the value produced by `` sql`now()` ``). Drizzle's `SQL`\n * class publicly exposes `readonly queryChunks: SQLChunk[]`, where a plain\n * literal chunk is a `StringChunk` with a `.value: string[]`. Only accept the\n * text when EVERY chunk is a plain string literal — if the default embeds any\n * dynamic piece (a bound param, column reference, nested table, etc.) we\n * refuse to stringify it, since that could contain unsafe or unbounded SQL.\n */\nfunction sqlDefaultText(value: unknown): string | undefined {\n if (typeof value === \"string\") return value;\n const chunks = (value as { queryChunks?: unknown } | null)?.queryChunks;\n if (!Array.isArray(chunks)) return undefined;\n const parts: string[] = [];\n for (const chunk of chunks) {\n const stringValues = (chunk as { value?: unknown } | null)?.value;\n if (\n !Array.isArray(stringValues) ||\n !stringValues.every((v) => typeof v === \"string\")\n ) {\n return undefined;\n }\n parts.push(...(stringValues as string[]));\n }\n const text = parts.join(\"\");\n return text || undefined;\n}\n\n/** True when an ALTER ... ADD COLUMN failure indicates the column already exists (race with a concurrent boot). */\nfunction isDuplicateColumnError(err: unknown): boolean {\n const msg = (err as { message?: string } | undefined)?.message ?? \"\";\n return (\n /duplicate column name/i.test(msg) ||\n /column .* already exists/i.test(msg) ||\n (err as { code?: string } | undefined)?.code === \"42701\"\n );\n}\n\n/** Annotate a schema-drift-shaped Postgres error (42703/42P01) so logs read plainly. */\nfunction describeSchemaDriftError(err: unknown): string {\n const code = (err as { code?: string } | undefined)?.code;\n const message =\n (err as { message?: string } | undefined)?.message ?? String(err);\n if (code === \"42703\") {\n return `schema drift (42703 undefined_column): ${message}`;\n }\n if (code === \"42P01\") {\n return `schema drift (42P01 undefined_table): ${message}`;\n }\n return message;\n}\n\n/**\n * Diff each declared Drizzle table's columns against the live database and\n * additively `ALTER TABLE ... ADD COLUMN` any that are missing. See the\n * module docstring for the full safety-rule contract.\n *\n * Call this once at boot, immediately after the authoritative hand-written\n * migrations have run. Never throws — every failure path is captured in the\n * returned summary instead so a boot-time caller can log-and-continue.\n */\nexport async function ensureAdditiveColumns(\n options: EnsureAdditiveColumnsOptions,\n): Promise<EnsureAdditiveColumnsResult> {\n const { db, tables, logger = defaultLogger } = options;\n const result = emptyResult();\n\n let getTableConfig: (table: unknown) => DeclaredTableLike;\n try {\n getTableConfig = await loadGetTableConfig();\n } catch (err) {\n result.errors.push({\n column: \"*\",\n error: `failed to load drizzle-orm table config helper: ${err instanceof Error ? err.message : String(err)}`,\n });\n return result;\n }\n\n for (const tableObj of tables) {\n let config: DeclaredTableLike;\n try {\n config = getTableConfig(tableObj);\n } catch (err) {\n // Not a table this dialect's getTableConfig understands (e.g. a stray\n // export that isn't a Drizzle table) — skip quietly rather than\n // erroring the whole run over one bad entry.\n logger.warn(\n `[ensure-additive-columns] skipping non-table export: ${err instanceof Error ? err.message : String(err)}`,\n );\n continue;\n }\n\n const tableName = config.name;\n if (!tableName || !PLAIN_IDENTIFIER.test(tableName)) continue;\n\n let liveColumns: Set<string> | null;\n try {\n liveColumns = await introspectLiveColumns(db, tableName, config.schema);\n } catch (err) {\n result.errors.push({\n column: `${tableName}.*`,\n error: describeSchemaDriftError(err),\n });\n continue;\n }\n\n // Table doesn't exist yet — the creation path (CREATE TABLE IF NOT\n // EXISTS / a real migration) owns bringing every declared column into\n // existence. Nothing to do here.\n if (liveColumns == null) continue;\n\n for (const column of config.columns) {\n const columnName = column.name;\n if (!columnName || !PLAIN_IDENTIFIER.test(columnName)) continue;\n if (liveColumns.has(columnName)) continue; // untouched — already present\n\n const label = `${tableName}.${columnName}`;\n const sqlType = safeSQLType(column, label, logger);\n if (!sqlType) {\n result.skipped.push({\n column: label,\n reason: \"could not determine a safe SQL type for the column\",\n });\n continue;\n }\n\n const defaultLiteral = renderDefaultLiteral(column);\n let notNullClause = \"\";\n if (column.notNull) {\n if (defaultLiteral != null) {\n notNullClause = \" NOT NULL\";\n } else {\n // Can't safely backfill existing rows — adding NOT NULL without a\n // default would fail immediately on any existing row. Skip the\n // whole column rather than add a nullable column that silently\n // disagrees with the Drizzle declaration's NOT NULL contract in\n // a way that could surprise a future safe-default addition.\n result.skipped.push({\n column: label,\n reason:\n \"declared NOT NULL with no renderable default — cannot backfill existing rows safely\",\n });\n logger.warn(\n `[ensure-additive-columns] SKIPPING ${label}: declared NOT NULL with no renderable default (existing rows have no safe backfill value)`,\n );\n continue;\n }\n }\n\n const defaultClause =\n defaultLiteral != null ? ` DEFAULT ${defaultLiteral}` : \"\";\n const ddl = `ALTER TABLE ${quoteIdent(tableName)} ADD COLUMN ${quoteIdent(columnName)} ${sqlType}${defaultClause}${notNullClause}`;\n\n try {\n await db.execute(ddl);\n result.applied.push(label);\n logger.info(`[ensure-additive-columns] added ${label}`);\n } catch (err) {\n if (isDuplicateColumnError(err)) {\n // A concurrent boot already added it — treat as success.\n result.applied.push(label);\n continue;\n }\n const message = describeSchemaDriftError(err);\n result.errors.push({ column: label, error: message });\n logger.error(\n `[ensure-additive-columns] failed to add ${label}: ${message}`,\n );\n // Continue with the remaining columns/tables — one failure must not\n // abort the rest.\n }\n }\n }\n\n return result;\n}\n\n/**\n * Resolve the SQL type to use for a new column. Prefers the column's own\n * `getSQLType()` (the exact type Drizzle would have used in a fresh CREATE\n * TABLE); falls back to skipping (returns `undefined`) if it throws or\n * returns something empty.\n */\nfunction safeSQLType(\n column: DeclaredColumnLike,\n label: string,\n logger: EnsureAdditiveColumnsLogger,\n): string | undefined {\n try {\n const sqlType = column.getSQLType();\n if (typeof sqlType === \"string\" && sqlType.trim()) return sqlType.trim();\n } catch (err) {\n logger.warn(\n `[ensure-additive-columns] getSQLType() threw for ${label}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return undefined;\n}\n"]}
1
+ {"version":3,"file":"ensure-additive-columns.js","sourceRoot":"","sources":["../../src/db/ensure-additive-columns.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Boot-time convergence for columns Drizzle's schema declares but a\n * pre-existing table is missing.\n *\n * Lives in its own module (like `./widen-columns.js`) so stores/plugins can\n * import it without every `vi.mock(\"../db/client.js\")` test needing to stub\n * it: the helper resolves `isPostgres()` / `getDbExec()` through `client.js`,\n * so a test that mocks the client to SQLite makes the Postgres introspection\n * path a no-op automatically.\n *\n * ## Why\n *\n * `CREATE TABLE IF NOT EXISTS` only runs the CREATE the first time a table is\n * created — once it exists, adding a column to the Drizzle schema (e.g.\n * `schema.ts`) does nothing to already-existing rows unless a hand-written\n * `ALTER TABLE ... ADD COLUMN` migration ships alongside it. Fresh dev\n * databases mask this because the CREATE always includes every declared\n * column; only long-lived, pre-existing production tables are missing the\n * new column. Forgetting the migration turns every query that references the\n * column into a Postgres `42703 (undefined_column)` — e.g.\n * `session_recordings.network_error_count`, which 500'd every\n * `list-session-recordings` call.\n *\n * `ensureAdditiveColumns()` is belt-and-braces for that failure mode: after\n * the authoritative hand-written migrations run, diff each Drizzle table's\n * declared columns against the live table and additively patch any gap. It\n * is NOT a replacement for migrations — it never touches indexes, data\n * transforms, or existing columns, and a hand-written migration should still\n * ship for every schema change. This is a safety net for the case where one\n * doesn't.\n *\n * ## Safety rules (hard)\n *\n * - Additive only: never drops, renames, retypes, or otherwise touches a\n * column that already exists on the live table.\n * - A `NOT NULL` column is only ever added when it has a renderable default\n * (so existing rows get a valid value in the same statement). If it has no\n * renderable default, it is added as nullable when the Drizzle declaration\n * allows null, else the column is SKIPPED entirely with a loud log line\n * naming the column and the reason.\n * - Only simple literal defaults are rendered: numbers, strings, booleans,\n * and `sql` template defaults that stringify to one of a small allow-listed\n * set of safe constants (see `renderDefaultLiteral`). Any other `sql`\n * default is NOT rendered — the column is added without a `DEFAULT` (and\n * without `NOT NULL`, per the rule above) rather than risk interpolating\n * unsafe SQL.\n * - All identifiers (table/column names) are validated against a strict\n * `[A-Za-z_][A-Za-z0-9_]*` pattern and double-quoted; no value from a row or\n * from user data is ever interpolated into the generated SQL.\n * - If the table itself does not exist yet, this is a no-op — table creation\n * owns bringing every declared column into existence for a brand-new table.\n * - Idempotent and best-effort: a failure on one column is logged and does\n * not abort the rest, and a total failure (e.g. `information_schema`\n * unreadable) must never crash boot — the caller decides whether/how to\n * surface `errors` in the returned summary.\n */\n\nimport { isPostgres, type DbExec } from \"./client.js\";\n\nconst PLAIN_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nexport interface EnsureAdditiveColumnsLogger {\n info: (message: string) => void;\n warn: (message: string) => void;\n error: (message: string) => void;\n}\n\nconst defaultLogger: EnsureAdditiveColumnsLogger = {\n info: (message) => console.log(message),\n warn: (message) => console.warn(message),\n error: (message) => console.error(message),\n};\n\n/**\n * Minimal shape this module needs from a Drizzle column — matches both\n * `drizzle-orm/pg-core` and `drizzle-orm/sqlite-core` column instances (and\n * the dialect-agnostic wrappers in `./schema.js`, which delegate to one or\n * the other at runtime).\n */\ninterface DeclaredColumnLike {\n name: string;\n notNull: boolean;\n hasDefault: boolean;\n default: unknown;\n getSQLType(): string;\n}\n\ninterface DeclaredTableLike {\n columns: DeclaredColumnLike[];\n name: string;\n schema?: string;\n}\n\nexport interface EnsureAdditiveColumnsOptions {\n db: DbExec;\n /** Drizzle table objects (from `pgTable`/`sqliteTable`, or the dialect-agnostic `table()` helper). */\n tables: unknown[];\n logger?: EnsureAdditiveColumnsLogger;\n}\n\nexport interface EnsureAdditiveColumnsResult {\n /** `\"table.column\"` entries that were successfully added. */\n applied: string[];\n /** Declared columns that were intentionally left unpatched, with why. */\n skipped: Array<{ column: string; reason: string }>;\n /** `\"table.column\"` entries whose ALTER failed unexpectedly (logged, non-fatal). */\n errors: Array<{ column: string; error: string }>;\n}\n\nfunction emptyResult(): EnsureAdditiveColumnsResult {\n return { applied: [], skipped: [], errors: [] };\n}\n\n/**\n * Resolve `getTableConfig` for the dialect currently in effect. Both\n * `drizzle-orm/pg-core` and `drizzle-orm/sqlite-core` export a function with\n * this name and a compatible-enough shape (`{ columns, name, schema? }`), but\n * each only understands its own table class — calling the wrong one throws.\n * `table()` from `./schema.js` builds a `pgTable` on Postgres and a\n * `sqliteTable` everywhere else, so the same dialect switch used there\n * decides which `getTableConfig` to load here.\n */\nasync function loadGetTableConfig(): Promise<\n (table: unknown) => DeclaredTableLike\n> {\n if (isPostgres()) {\n const { getTableConfig } = await import(\"drizzle-orm/pg-core\");\n return getTableConfig as unknown as (table: unknown) => DeclaredTableLike;\n }\n const { getTableConfig } = await import(\"drizzle-orm/sqlite-core\");\n return getTableConfig as unknown as (table: unknown) => DeclaredTableLike;\n}\n\n/**\n * Load every requested Postgres table's live columns in one round trip.\n * Calling information_schema separately for each table adds dozens of\n * serialized network requests to every serverless cold start.\n */\nasync function introspectPostgresColumns(\n db: DbExec,\n tables: DeclaredTableLike[],\n): Promise<Map<string, Set<string>> | null> {\n if (tables.length === 0) return new Map();\n const pairs = [\n ...new Map(\n tables.map((table) => {\n const schema = table.schema || \"public\";\n return [`${schema}.${table.name}`, { schema, table: table.name }];\n }),\n ).values(),\n ];\n const args: unknown[] = [];\n const predicates = pairs.map(({ schema, table }) => {\n args.push(schema, table);\n return `(table_schema = ? AND table_name = ?)`;\n });\n try {\n const { rows } = await db.execute({\n sql: `SELECT table_schema, table_name, column_name\n FROM information_schema.columns\n WHERE ${predicates.join(\" OR \")}`,\n args,\n });\n const columns = new Map<string, Set<string>>();\n for (const row of rows) {\n const key = `${String(row.table_schema)}.${String(row.table_name)}`;\n const tableColumns = columns.get(key) ?? new Set<string>();\n tableColumns.add(String(row.column_name));\n columns.set(key, tableColumns);\n }\n return columns;\n } catch {\n return null;\n }\n}\n\n/**\n * Live SQLite columns already present on `table`, keyed by column name.\n * Returns `null` when the table does not exist or introspection fails.\n */\nasync function introspectSqliteLiveColumns(\n db: DbExec,\n table: string,\n): Promise<Set<string> | null> {\n // SQLite: PRAGMA table_info returns zero rows for a non-existent table\n // (no error), so we can't distinguish \"missing table\" from \"no columns\"\n // that way — probe sqlite_master first.\n try {\n const { rows: existsRows } = await db.execute({\n sql: `SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ? LIMIT 1`,\n args: [table],\n });\n if (existsRows.length === 0) return null;\n // PRAGMA doesn't support bound parameters; the table name is already\n // validated against PLAIN_IDENTIFIER by the caller before we get here.\n const { rows } = await db.execute(`PRAGMA table_info(\"${table}\")`);\n return new Set(rows.map((r) => String(r.name)));\n } catch {\n return null;\n }\n}\n\n/** Quote a validated identifier for use in generated SQL. */\nfunction quoteIdent(name: string): string {\n return `\"${name}\"`;\n}\n\n/**\n * Render a column's declared default as a SQL literal, or `undefined` if it\n * can't be rendered safely. Only numbers, strings, booleans, and a small\n * allow-list of `sql` template defaults that stringify to a known-safe\n * constant are supported — anything else is deliberately left unrendered so\n * we never interpolate arbitrary SQL.\n */\nfunction renderDefaultLiteral(column: DeclaredColumnLike): string | undefined {\n if (!column.hasDefault) return undefined;\n const value = column.default;\n if (value == null) return undefined;\n\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return String(value);\n }\n if (typeof value === \"boolean\") {\n return isPostgres() ? (value ? \"true\" : \"false\") : value ? \"1\" : \"0\";\n }\n if (typeof value === \"string\") {\n // Escape single quotes for a plain string literal.\n return `'${value.replace(/'/g, \"''\")}'`;\n }\n\n // Drizzle `sql` template defaults (e.g. `now()`, `(datetime('now'))`) carry\n // a `queryChunks`/`toQuery`-style object rather than a plain scalar. Only\n // render the handful of known-safe constants used by this codebase's\n // `now()` helper (see ./schema.ts) — never stringify arbitrary SQL.\n const raw = sqlDefaultText(value);\n if (raw == null) return undefined;\n const normalized = raw.trim().toLowerCase();\n const SAFE_SQL_DEFAULTS = new Set([\n \"now()\",\n \"(datetime('now'))\",\n \"current_timestamp\",\n \"current_date\",\n \"current_time\",\n ]);\n if (SAFE_SQL_DEFAULTS.has(normalized)) {\n return raw.trim();\n }\n return undefined;\n}\n\n/**\n * Best-effort extraction of the raw SQL text from a drizzle `SQL` default\n * object (e.g. the value produced by `` sql`now()` ``). Drizzle's `SQL`\n * class publicly exposes `readonly queryChunks: SQLChunk[]`, where a plain\n * literal chunk is a `StringChunk` with a `.value: string[]`. Only accept the\n * text when EVERY chunk is a plain string literal — if the default embeds any\n * dynamic piece (a bound param, column reference, nested table, etc.) we\n * refuse to stringify it, since that could contain unsafe or unbounded SQL.\n */\nfunction sqlDefaultText(value: unknown): string | undefined {\n if (typeof value === \"string\") return value;\n const chunks = (value as { queryChunks?: unknown } | null)?.queryChunks;\n if (!Array.isArray(chunks)) return undefined;\n const parts: string[] = [];\n for (const chunk of chunks) {\n const stringValues = (chunk as { value?: unknown } | null)?.value;\n if (\n !Array.isArray(stringValues) ||\n !stringValues.every((v) => typeof v === \"string\")\n ) {\n return undefined;\n }\n parts.push(...(stringValues as string[]));\n }\n const text = parts.join(\"\");\n return text || undefined;\n}\n\n/** True when an ALTER ... ADD COLUMN failure indicates the column already exists (race with a concurrent boot). */\nfunction isDuplicateColumnError(err: unknown): boolean {\n const msg = (err as { message?: string } | undefined)?.message ?? \"\";\n return (\n /duplicate column name/i.test(msg) ||\n /column .* already exists/i.test(msg) ||\n (err as { code?: string } | undefined)?.code === \"42701\"\n );\n}\n\n/** Annotate a schema-drift-shaped Postgres error (42703/42P01) so logs read plainly. */\nfunction describeSchemaDriftError(err: unknown): string {\n const code = (err as { code?: string } | undefined)?.code;\n const message =\n (err as { message?: string } | undefined)?.message ?? String(err);\n if (code === \"42703\") {\n return `schema drift (42703 undefined_column): ${message}`;\n }\n if (code === \"42P01\") {\n return `schema drift (42P01 undefined_table): ${message}`;\n }\n return message;\n}\n\n/**\n * Diff each declared Drizzle table's columns against the live database and\n * additively `ALTER TABLE ... ADD COLUMN` any that are missing. See the\n * module docstring for the full safety-rule contract.\n *\n * Call this once at boot, immediately after the authoritative hand-written\n * migrations have run. Never throws — every failure path is captured in the\n * returned summary instead so a boot-time caller can log-and-continue.\n */\nexport async function ensureAdditiveColumns(\n options: EnsureAdditiveColumnsOptions,\n): Promise<EnsureAdditiveColumnsResult> {\n const { db, tables, logger = defaultLogger } = options;\n const result = emptyResult();\n\n let getTableConfig: (table: unknown) => DeclaredTableLike;\n try {\n getTableConfig = await loadGetTableConfig();\n } catch (err) {\n result.errors.push({\n column: \"*\",\n error: `failed to load drizzle-orm table config helper: ${err instanceof Error ? err.message : String(err)}`,\n });\n return result;\n }\n\n const declaredTables: DeclaredTableLike[] = [];\n for (const tableObj of tables) {\n try {\n const config = getTableConfig(tableObj);\n if (config.name && PLAIN_IDENTIFIER.test(config.name)) {\n declaredTables.push(config);\n }\n } catch (err) {\n // Not a table this dialect's getTableConfig understands (e.g. a stray\n // export that isn't a Drizzle table) — skip quietly rather than\n // erroring the whole run over one bad entry.\n logger.warn(\n `[ensure-additive-columns] skipping non-table export: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n const postgresColumns = isPostgres()\n ? await introspectPostgresColumns(db, declaredTables)\n : null;\n\n for (const config of declaredTables) {\n const tableName = config.name;\n let liveColumns: Set<string> | null;\n try {\n liveColumns = isPostgres()\n ? (postgresColumns?.get(`${config.schema || \"public\"}.${tableName}`) ??\n null)\n : await introspectSqliteLiveColumns(db, tableName);\n } catch (err) {\n result.errors.push({\n column: `${tableName}.*`,\n error: describeSchemaDriftError(err),\n });\n continue;\n }\n\n // Table doesn't exist yet — the creation path (CREATE TABLE IF NOT\n // EXISTS / a real migration) owns bringing every declared column into\n // existence. Nothing to do here.\n if (liveColumns == null) continue;\n\n for (const column of config.columns) {\n const columnName = column.name;\n if (!columnName || !PLAIN_IDENTIFIER.test(columnName)) continue;\n if (liveColumns.has(columnName)) continue; // untouched — already present\n\n const label = `${tableName}.${columnName}`;\n const sqlType = safeSQLType(column, label, logger);\n if (!sqlType) {\n result.skipped.push({\n column: label,\n reason: \"could not determine a safe SQL type for the column\",\n });\n continue;\n }\n\n const defaultLiteral = renderDefaultLiteral(column);\n let notNullClause = \"\";\n if (column.notNull) {\n if (defaultLiteral != null) {\n notNullClause = \" NOT NULL\";\n } else {\n // Can't safely backfill existing rows — adding NOT NULL without a\n // default would fail immediately on any existing row. Skip the\n // whole column rather than add a nullable column that silently\n // disagrees with the Drizzle declaration's NOT NULL contract in\n // a way that could surprise a future safe-default addition.\n result.skipped.push({\n column: label,\n reason:\n \"declared NOT NULL with no renderable default — cannot backfill existing rows safely\",\n });\n logger.warn(\n `[ensure-additive-columns] SKIPPING ${label}: declared NOT NULL with no renderable default (existing rows have no safe backfill value)`,\n );\n continue;\n }\n }\n\n const defaultClause =\n defaultLiteral != null ? ` DEFAULT ${defaultLiteral}` : \"\";\n const ddl = `ALTER TABLE ${quoteIdent(tableName)} ADD COLUMN ${quoteIdent(columnName)} ${sqlType}${defaultClause}${notNullClause}`;\n\n try {\n await db.execute(ddl);\n result.applied.push(label);\n logger.info(`[ensure-additive-columns] added ${label}`);\n } catch (err) {\n if (isDuplicateColumnError(err)) {\n // A concurrent boot already added it — treat as success.\n result.applied.push(label);\n continue;\n }\n const message = describeSchemaDriftError(err);\n result.errors.push({ column: label, error: message });\n logger.error(\n `[ensure-additive-columns] failed to add ${label}: ${message}`,\n );\n // Continue with the remaining columns/tables — one failure must not\n // abort the rest.\n }\n }\n }\n\n return result;\n}\n\n/**\n * Resolve the SQL type to use for a new column. Prefers the column's own\n * `getSQLType()` (the exact type Drizzle would have used in a fresh CREATE\n * TABLE); falls back to skipping (returns `undefined`) if it throws or\n * returns something empty.\n */\nfunction safeSQLType(\n column: DeclaredColumnLike,\n label: string,\n logger: EnsureAdditiveColumnsLogger,\n): string | undefined {\n try {\n const sqlType = column.getSQLType();\n if (typeof sqlType === \"string\" && sqlType.trim()) return sqlType.trim();\n } catch (err) {\n logger.warn(\n `[ensure-additive-columns] getSQLType() threw for ${label}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return undefined;\n}\n"]}
@@ -70,6 +70,7 @@ export declare function generateWorkerEntry(routes: DiscoveredRoute[], pluginPat
70
70
  export declare function generateCloudflarePagesStaticShellFromManifest(manifest: ReactRouterAssetManifest, basePath?: string): string;
71
71
  export declare function getNodeBuiltinNames(): string[];
72
72
  export declare function copyDir(src: string, dest: string, ancestorRealPaths?: Set<string>): void;
73
+ export declare function isServerlessNativePlatformPackage(packageName: string): boolean;
73
74
  type ServerlessFfmpegStaticArch = "arm64" | "x64";
74
75
  export declare function shouldBundleFfmpegStaticForServerless(hostPlatform?: NodeJS.Platform, hostArch?: NodeJS.Architecture, targetArch?: ServerlessFfmpegStaticArch | null): boolean;
75
76
  export declare function findInstalledFfmpegStaticPackage(nodeModulesRoots: string[]): string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/deploy/build.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;GAaG;AA6CH,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AAI7B,eAAO,MAAM,yBAAyB,YACpC,mBAAmB,EACnB,mBAAmB,CACX,CAAC;AAEX,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAItE;AAED,eAAO,MAAM,8BAA8B,eAAe,CAAC;AAE3D,wBAAgB,mCAAmC,IAAI,MAAM,CAmD5D;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA2DpE;AAED,wBAAgB,qCAAqC,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAqC7E;AACD,eAAO,MAAM,6BAA6B,UAiBzC,CAAC;AAEF,eAAO,MAAM,mCAAmC,UAiB/C,CAAC;AACF,eAAO,MAAM,8BAA8B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAyFjE,CAAC;AAEF,eAAO,MAAM,sCAAsC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQzE,CAAC;AAEF,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAWvE;AAED,wBAAgB,0CAA0C,CACxD,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GACjB,IAAI,CAgBN;AA6BD,eAAO,MAAM,2CAA2C,EAAE,MAAM,CAC9D,MAAM,EACN,MAAM,CAmSP,CAAC;AAEF,MAAM,WAAW,0BAA0B;IACzC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,UAAU,wBAAwB;IAChC,KAAK,EAAE,6BAA6B,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;IACtD,GAAG,EAAE,MAAM,CAAC;CACb;AAED,UAAU,6BAA6B;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,UAAU,6BAA6B;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAwBD,wBAAgB,wCAAwC,CACtD,WAAW,EAAE,MAAM,EAAE,GACpB,MAAM,CAaR;AAgBD,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAgBvE,wBAAgB,yCAAyC,CACvD,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,WAAW,SAAK,GACf,IAAI,CAQN;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,EAAE,EACzB,WAAW,EAAE,MAAM,EAAE,EACrB,kBAAkB,GAAE,MAAM,EAAO,EACjC,OAAO,GAAE,gBAAgB,EAAO,EAChC,aAAa,GAAE,oBAAoB,GAAG,IAAW,EACjD,mBAAmB,GAAE,MAAM,EAAO,EAClC,gBAAgB,SAAmC,EACnD,OAAO,GAAE,0BAA+B,GACvC,MAAM,CA2rBR;AA4FD,wBAAgB,8CAA8C,CAC5D,QAAQ,EAAE,wBAAwB,EAClC,QAAQ,SAAmC,GAC1C,MAAM,CAiCR;AAseD,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAE9C;AA+GD,wBAAgB,OAAO,CACrB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,iBAAiB,cAAoB,QAoCtC;AAiCD,KAAK,0BAA0B,GAAG,OAAO,GAAG,KAAK,CAAC;AAQlD,wBAAgB,qCAAqC,CACnD,YAAY,GAAE,MAAM,CAAC,QAA2B,EAChD,QAAQ,GAAE,MAAM,CAAC,YAA2B,EAC5C,UAAU,GAAE,0BAA0B,GAAG,IAAgD,GACxF,OAAO,CAOT;AAqED,wBAAgB,gCAAgC,CAC9C,gBAAgB,EAAE,MAAM,EAAE,GACzB,MAAM,GAAG,IAAI,CA8Bf;AAED,wBAAgB,0BAA0B,CACxC,gBAAgB,EAAE,MAAM,EAAE,GACzB,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAqCpD;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gCAAgC,IAAI,OAAO,CAE1D;AAaD,eAAO,MAAM,0CAA0C,gCACxB,CAAC;AAEhC,wBAAgB,yCAAyC,IAAI,OAAO,CAEnE;AAID;;;;;GAKG;AACH,wBAAgB,yCAAyC,CACvD,UAAU,EAAE,MAAM,GACjB,IAAI,CAmGN;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,wBAAgB,2CAA2C,CACzD,UAAU,EAAE,MAAM,GACjB,IAAI,CAoKN;AAED;;;;;GAKG;AACH,wBAAgB,qCAAqC,CACnD,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,IAAI,CAWN;AAED,wBAAgB,oDAAoD,CAClE,UAAU,EAAE,MAAM,GACjB,IAAI,CAoEN;AA8DD;;;;;;GAMG;AACH,wBAAgB,mCAAmC,CACjD,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,MAAM,EAAE,CA0EV;AAED,wBAAgB,sCAAsC,CACpD,UAAU,EAAE,MAAM,GACjB,IAAI,CA2ON;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAsC5E;AAuED;;;;;;GAMG;AACH,wBAAgB,yCAAyC,CACvD,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,IAAI,CAqDN;AA6ID;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,gBAAgB,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,UAAU,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,GAAG,CAAC;IACX,KAAK,EAAE,eAAe,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAkBD;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,YACzC,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,yBAAyB,EACzB,gBAAgB,EAChB,qBAAqB,EACrB,UAAU,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,iBAAiB,CACT,CAAC;AAEX;;;;;GAKG;AACH,wBAAgB,gCAAgC;IAK5C,IAAI;IACJ,SAAS,KAAK,MAAM;IAOpB,IAAI,KAAK,MAAM;EAMlB;AAED;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,YAAI,KAAK,CAAU,CAAC;AAElE;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,CAQpD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,GACnB,IAAI,GAAG,SAAS,MAAM,EAAE,CAS1B"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/deploy/build.ts"],"names":[],"mappings":"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"}
@@ -1389,7 +1389,7 @@ export function generateCloudflarePagesStaticShellFromManifest(manifest, basePat
1389
1389
  const encodedInitialState = rootRoute.hasLoader
1390
1390
  ? DEFAULT_ROOT_LOADER_REACT_ROUTER_TURBO_STREAM
1391
1391
  : EMPTY_REACT_ROUTER_TURBO_STREAM;
1392
- return `<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/><link rel="manifest" href="/manifest.json"/><link rel="icon" type="image/svg+xml" href="/favicon.svg"/>${modulePreloads}${stylesheets}</head><body><div style="display:flex;align-items:center;justify-content:center;height:100vh;width:100%"><svg role="status" aria-label="Loading" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="animation:an-spin 1s linear infinite;opacity:0.7"><path d="M21 12a9 9 0 1 1-6.219-8.56"></path></svg><style>@keyframes an-spin { to { transform: rotate(360deg) } } @media (prefers-color-scheme: dark) { html { background: #09090b; color: #fafafa } }</style></div><script>window.__reactRouterContext = ${JSON.stringify(context)};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());</script><script type="module" async="">${routeModuleScript}</script><!--$--><script>window.__reactRouterContext.streamController.enqueue(${JSON.stringify(encodedInitialState)});</script><!--$--><script>window.__reactRouterContext.streamController.close();</script><!--/$--><!--/$--></body></html>`;
1392
+ return `<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/><link rel="manifest" href="/manifest.json"/><link rel="icon" type="image/svg+xml" href="/favicon.svg"/>${modulePreloads}${stylesheets}</head><body><div style="display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;height:100vh;width:100%"><svg role="status" aria-label="Loading" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="animation:an-spin 1s linear infinite;opacity:0.7"><path d="M21 12a9 9 0 1 1-6.219-8.56"></path></svg><p class="an-stall-hint">Still loading. If this does not finish, reload the page — the browser console may show what failed.</p><style>@keyframes an-spin { to { transform: rotate(360deg) } } @keyframes an-stall-in { to { opacity: 0.6 } } .an-stall-hint { opacity: 0; margin: 0; max-width: 32rem; padding: 0 1.5rem; text-align: center; font-size: 0.875rem; line-height: 1.5; font-family: ui-sans-serif, system-ui, sans-serif; animation: an-stall-in 0.4s ease-out 10s forwards } @media (prefers-reduced-motion: reduce) { .an-stall-hint { animation-duration: 0s } } @media (prefers-color-scheme: dark) { html { background: #09090b; color: #fafafa } }</style></div><script>window.__reactRouterContext = ${JSON.stringify(context)};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());</script><script type="module" async="">${routeModuleScript}</script><!--$--><script>window.__reactRouterContext.streamController.enqueue(${JSON.stringify(encodedInitialState)});</script><!--$--><script>window.__reactRouterContext.streamController.close();</script><!--/$--><!--/$--></body></html>`;
1393
1393
  }
1394
1394
  function writeCloudflarePagesStaticShell({ serverDir, distDir, tmpDir, }) {
1395
1395
  const serverEntry = path.join(serverDir, "index.js");
@@ -1895,6 +1895,22 @@ const LIBSQL_NATIVE_PACKAGE_NAMES = [
1895
1895
  const FFMPEG_STATIC_PACKAGE_NAME = "ffmpeg-static";
1896
1896
  const RESVG_SCOPE = "@resvg";
1897
1897
  const RESVG_PACKAGE_PREFIX = "resvg-js";
1898
+ // Serverless functions only ever run on 64-bit Linux. The darwin/win32/android
1899
+ // and 32-bit-arm prebuilds of these native packages are ~100MB that can never
1900
+ // execute there, and Netlify copies the whole server dir again for every extra
1901
+ // emitted function — so the dead weight is paid once per function. Cold start
1902
+ // scales with bundle size, and a page that opens several requests at once
1903
+ // scales out to that many cold containers, which is how this surfaces: 502/504
1904
+ // on the first burst rather than as an obviously slow deploy.
1905
+ const SERVERLESS_NATIVE_PACKAGE_SUFFIXES = [
1906
+ "linux-x64-gnu",
1907
+ "linux-x64-musl",
1908
+ "linux-arm64-gnu",
1909
+ "linux-arm64-musl",
1910
+ ];
1911
+ export function isServerlessNativePlatformPackage(packageName) {
1912
+ return SERVERLESS_NATIVE_PACKAGE_SUFFIXES.some((suffix) => packageName.endsWith(suffix));
1913
+ }
1898
1914
  const FFMPEG_STATIC_BINARY_NAMES = process.platform === "win32" ? ["ffmpeg.exe", "ffmpeg"] : ["ffmpeg"];
1899
1915
  const SERVERLESS_FFMPEG_STATIC_PLATFORM = "linux";
1900
1916
  const SERVERLESS_FFMPEG_STATIC_ARCHES = new Set([
@@ -2761,6 +2777,8 @@ function copyInstalledLibsqlNativePackages(serverDir) {
2761
2777
  const destScopeDir = path.join(serverDir, "node_modules", "@libsql");
2762
2778
  let copied = 0;
2763
2779
  for (const packageName of LIBSQL_NATIVE_PACKAGE_NAMES) {
2780
+ if (!isServerlessNativePlatformPackage(packageName))
2781
+ continue;
2764
2782
  const src = findInstalledLibsqlNativePackage(nodeModulesRoots, packageName);
2765
2783
  if (!src)
2766
2784
  continue;
@@ -2774,7 +2792,10 @@ function copyInstalledLibsqlNativePackages(serverDir) {
2774
2792
  function copyInstalledResvgPackages(serverDir) {
2775
2793
  if (!serverDir || !fs.existsSync(serverDir))
2776
2794
  return;
2777
- const packages = findInstalledResvgPackages(nodeModulesAncestors(cwd));
2795
+ // `resvg-js` itself is the JS wrapper that gets imported; everything else in
2796
+ // the scope is a per-platform prebuild.
2797
+ const packages = findInstalledResvgPackages(nodeModulesAncestors(cwd)).filter(({ packageName }) => packageName === RESVG_PACKAGE_PREFIX ||
2798
+ isServerlessNativePlatformPackage(packageName));
2778
2799
  if (packages.length === 0)
2779
2800
  return;
2780
2801
  const destScopeDir = path.join(serverDir, "node_modules", RESVG_SCOPE);