@agent-native/core 0.93.0 → 0.94.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 (1197) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +31 -0
  3. package/corpus/core/docs/content/a2a-protocol.mdx +21 -5
  4. package/corpus/core/docs/content/actions.mdx +9 -23
  5. package/corpus/core/docs/content/agent-mentions.mdx +31 -29
  6. package/corpus/core/docs/content/agent-native-toolkit.mdx +15 -6
  7. package/corpus/core/docs/content/agent-surfaces.mdx +9 -13
  8. package/corpus/core/docs/content/agent-teams.mdx +1 -0
  9. package/corpus/core/docs/content/authentication.mdx +10 -3
  10. package/corpus/core/docs/content/automation-connectors.mdx +82 -39
  11. package/corpus/core/docs/content/automations.mdx +17 -3
  12. package/corpus/core/docs/content/blueprint-installer.mdx +11 -4
  13. package/corpus/core/docs/content/cli-adapters.mdx +9 -6
  14. package/corpus/core/docs/content/client.mdx +16 -0
  15. package/corpus/core/docs/content/cloneable-saas.mdx +14 -11
  16. package/corpus/core/docs/content/code-agents-ui.mdx +65 -0
  17. package/corpus/core/docs/content/components.mdx +30 -14
  18. package/corpus/core/docs/content/context-awareness.mdx +27 -15
  19. package/corpus/core/docs/content/creating-templates.mdx +15 -9
  20. package/corpus/core/docs/content/cross-app-sso.mdx +16 -6
  21. package/corpus/core/docs/content/data-programs.mdx +1 -1
  22. package/corpus/core/docs/content/database.mdx +17 -5
  23. package/corpus/core/docs/content/deployment.mdx +19 -18
  24. package/corpus/core/docs/content/dispatch.mdx +6 -2
  25. package/corpus/core/docs/content/drop-in-agent.mdx +10 -4
  26. package/corpus/core/docs/content/durable-background-runs.mdx +9 -5
  27. package/corpus/core/docs/content/durable-resume.mdx +9 -4
  28. package/corpus/core/docs/content/embedding-sdk.mdx +26 -8
  29. package/corpus/core/docs/content/evals.mdx +3 -5
  30. package/corpus/core/docs/content/extensions.mdx +22 -9
  31. package/corpus/core/docs/content/external-agents.mdx +25 -34
  32. package/corpus/core/docs/content/faq.mdx +8 -0
  33. package/corpus/core/docs/content/file-uploads.mdx +12 -3
  34. package/corpus/core/docs/content/frames.mdx +16 -0
  35. package/corpus/core/docs/content/generative-ui.mdx +1 -1
  36. package/corpus/core/docs/content/getting-started.mdx +34 -21
  37. package/corpus/core/docs/content/harness-agents.mdx +8 -4
  38. package/corpus/core/docs/content/human-approval.mdx +8 -3
  39. package/corpus/core/docs/content/internationalization.mdx +9 -4
  40. package/corpus/core/docs/content/key-concepts.mdx +13 -20
  41. package/corpus/core/docs/content/local-file-mode.mdx +14 -8
  42. package/corpus/core/docs/content/locales/ar-SA/actions.mdx +2 -2
  43. package/corpus/core/docs/content/locales/ar-SA/agent-native-toolkit.mdx +2 -2
  44. package/corpus/core/docs/content/locales/ar-SA/agent-surfaces.mdx +8 -10
  45. package/corpus/core/docs/content/locales/ar-SA/agent-teams.mdx +1 -0
  46. package/corpus/core/docs/content/locales/ar-SA/authentication.mdx +1 -1
  47. package/corpus/core/docs/content/locales/ar-SA/components.mdx +11 -1
  48. package/corpus/core/docs/content/locales/ar-SA/creating-templates.mdx +3 -7
  49. package/corpus/core/docs/content/locales/ar-SA/cross-app-sso.mdx +16 -6
  50. package/corpus/core/docs/content/locales/ar-SA/deployment.mdx +8 -0
  51. package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +2 -7
  52. package/corpus/core/docs/content/locales/ar-SA/key-concepts.mdx +13 -20
  53. package/corpus/core/docs/content/locales/ar-SA/multi-tenancy.mdx +5 -5
  54. package/corpus/core/docs/content/locales/ar-SA/notifications.mdx +18 -10
  55. package/corpus/core/docs/content/locales/ar-SA/processors.mdx +11 -5
  56. package/corpus/core/docs/content/locales/ar-SA/server.mdx +17 -10
  57. package/corpus/core/docs/content/locales/ar-SA/sharing.mdx +10 -10
  58. package/corpus/core/docs/content/locales/ar-SA/skills-guide.mdx +34 -17
  59. package/corpus/core/docs/content/locales/ar-SA/template-assets.mdx +16 -13
  60. package/corpus/core/docs/content/locales/ar-SA/template-brain.mdx +3 -1
  61. package/corpus/core/docs/content/locales/ar-SA/template-clips.mdx +3 -3
  62. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +3 -1
  63. package/corpus/core/docs/content/locales/ar-SA/template-dispatch.mdx +5 -1
  64. package/corpus/core/docs/content/locales/ar-SA/template-mail.mdx +8 -0
  65. package/corpus/core/docs/content/locales/ar-SA/tracking.mdx +9 -6
  66. package/corpus/core/docs/content/locales/ar-SA/using-your-agent.mdx +0 -7
  67. package/corpus/core/docs/content/locales/ar-SA/voice-input.mdx +6 -0
  68. package/corpus/core/docs/content/locales/ar-SA/workspace-connections.mdx +9 -2
  69. package/corpus/core/docs/content/locales/ar-SA/workspace.mdx +19 -18
  70. package/corpus/core/docs/content/locales/de-DE/actions.mdx +2 -2
  71. package/corpus/core/docs/content/locales/de-DE/agent-native-toolkit.mdx +2 -2
  72. package/corpus/core/docs/content/locales/de-DE/agent-surfaces.mdx +8 -10
  73. package/corpus/core/docs/content/locales/de-DE/agent-teams.mdx +1 -0
  74. package/corpus/core/docs/content/locales/de-DE/authentication.mdx +1 -1
  75. package/corpus/core/docs/content/locales/de-DE/components.mdx +11 -1
  76. package/corpus/core/docs/content/locales/de-DE/creating-templates.mdx +3 -7
  77. package/corpus/core/docs/content/locales/de-DE/cross-app-sso.mdx +16 -6
  78. package/corpus/core/docs/content/locales/de-DE/deployment.mdx +8 -0
  79. package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +3 -7
  80. package/corpus/core/docs/content/locales/de-DE/key-concepts.mdx +13 -20
  81. package/corpus/core/docs/content/locales/de-DE/multi-tenancy.mdx +5 -5
  82. package/corpus/core/docs/content/locales/de-DE/notifications.mdx +18 -10
  83. package/corpus/core/docs/content/locales/de-DE/processors.mdx +11 -5
  84. package/corpus/core/docs/content/locales/de-DE/server.mdx +18 -10
  85. package/corpus/core/docs/content/locales/de-DE/sharing.mdx +10 -10
  86. package/corpus/core/docs/content/locales/de-DE/skills-guide.mdx +34 -17
  87. package/corpus/core/docs/content/locales/de-DE/template-assets.mdx +16 -13
  88. package/corpus/core/docs/content/locales/de-DE/template-brain.mdx +3 -1
  89. package/corpus/core/docs/content/locales/de-DE/template-clips.mdx +3 -3
  90. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +3 -1
  91. package/corpus/core/docs/content/locales/de-DE/template-dispatch.mdx +5 -1
  92. package/corpus/core/docs/content/locales/de-DE/template-mail.mdx +8 -0
  93. package/corpus/core/docs/content/locales/de-DE/tracking.mdx +9 -6
  94. package/corpus/core/docs/content/locales/de-DE/using-your-agent.mdx +0 -7
  95. package/corpus/core/docs/content/locales/de-DE/voice-input.mdx +6 -0
  96. package/corpus/core/docs/content/locales/de-DE/workspace-connections.mdx +9 -2
  97. package/corpus/core/docs/content/locales/de-DE/workspace.mdx +19 -18
  98. package/corpus/core/docs/content/locales/es-ES/actions.mdx +2 -2
  99. package/corpus/core/docs/content/locales/es-ES/agent-native-toolkit.mdx +2 -2
  100. package/corpus/core/docs/content/locales/es-ES/agent-surfaces.mdx +8 -10
  101. package/corpus/core/docs/content/locales/es-ES/agent-teams.mdx +1 -0
  102. package/corpus/core/docs/content/locales/es-ES/authentication.mdx +1 -1
  103. package/corpus/core/docs/content/locales/es-ES/components.mdx +11 -1
  104. package/corpus/core/docs/content/locales/es-ES/creating-templates.mdx +3 -7
  105. package/corpus/core/docs/content/locales/es-ES/cross-app-sso.mdx +16 -6
  106. package/corpus/core/docs/content/locales/es-ES/deployment.mdx +8 -0
  107. package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +3 -7
  108. package/corpus/core/docs/content/locales/es-ES/key-concepts.mdx +13 -20
  109. package/corpus/core/docs/content/locales/es-ES/multi-tenancy.mdx +5 -5
  110. package/corpus/core/docs/content/locales/es-ES/notifications.mdx +18 -10
  111. package/corpus/core/docs/content/locales/es-ES/processors.mdx +11 -5
  112. package/corpus/core/docs/content/locales/es-ES/server.mdx +17 -10
  113. package/corpus/core/docs/content/locales/es-ES/sharing.mdx +10 -10
  114. package/corpus/core/docs/content/locales/es-ES/skills-guide.mdx +34 -17
  115. package/corpus/core/docs/content/locales/es-ES/template-assets.mdx +16 -13
  116. package/corpus/core/docs/content/locales/es-ES/template-brain.mdx +3 -1
  117. package/corpus/core/docs/content/locales/es-ES/template-clips.mdx +3 -3
  118. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +3 -1
  119. package/corpus/core/docs/content/locales/es-ES/template-dispatch.mdx +5 -1
  120. package/corpus/core/docs/content/locales/es-ES/template-mail.mdx +8 -0
  121. package/corpus/core/docs/content/locales/es-ES/tracking.mdx +9 -6
  122. package/corpus/core/docs/content/locales/es-ES/using-your-agent.mdx +0 -7
  123. package/corpus/core/docs/content/locales/es-ES/voice-input.mdx +6 -0
  124. package/corpus/core/docs/content/locales/es-ES/workspace-connections.mdx +9 -2
  125. package/corpus/core/docs/content/locales/es-ES/workspace.mdx +19 -18
  126. package/corpus/core/docs/content/locales/fr-FR/actions.mdx +2 -2
  127. package/corpus/core/docs/content/locales/fr-FR/agent-native-toolkit.mdx +2 -2
  128. package/corpus/core/docs/content/locales/fr-FR/agent-surfaces.mdx +8 -10
  129. package/corpus/core/docs/content/locales/fr-FR/agent-teams.mdx +1 -0
  130. package/corpus/core/docs/content/locales/fr-FR/authentication.mdx +1 -1
  131. package/corpus/core/docs/content/locales/fr-FR/components.mdx +11 -1
  132. package/corpus/core/docs/content/locales/fr-FR/creating-templates.mdx +3 -7
  133. package/corpus/core/docs/content/locales/fr-FR/cross-app-sso.mdx +16 -6
  134. package/corpus/core/docs/content/locales/fr-FR/deployment.mdx +8 -0
  135. package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +3 -7
  136. package/corpus/core/docs/content/locales/fr-FR/key-concepts.mdx +13 -20
  137. package/corpus/core/docs/content/locales/fr-FR/multi-tenancy.mdx +5 -5
  138. package/corpus/core/docs/content/locales/fr-FR/notifications.mdx +18 -10
  139. package/corpus/core/docs/content/locales/fr-FR/processors.mdx +11 -5
  140. package/corpus/core/docs/content/locales/fr-FR/server.mdx +17 -10
  141. package/corpus/core/docs/content/locales/fr-FR/sharing.mdx +10 -10
  142. package/corpus/core/docs/content/locales/fr-FR/skills-guide.mdx +34 -17
  143. package/corpus/core/docs/content/locales/fr-FR/template-assets.mdx +16 -13
  144. package/corpus/core/docs/content/locales/fr-FR/template-brain.mdx +3 -1
  145. package/corpus/core/docs/content/locales/fr-FR/template-clips.mdx +3 -3
  146. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +3 -1
  147. package/corpus/core/docs/content/locales/fr-FR/template-dispatch.mdx +5 -1
  148. package/corpus/core/docs/content/locales/fr-FR/template-mail.mdx +8 -0
  149. package/corpus/core/docs/content/locales/fr-FR/tracking.mdx +9 -6
  150. package/corpus/core/docs/content/locales/fr-FR/using-your-agent.mdx +0 -7
  151. package/corpus/core/docs/content/locales/fr-FR/voice-input.mdx +6 -0
  152. package/corpus/core/docs/content/locales/fr-FR/workspace-connections.mdx +9 -2
  153. package/corpus/core/docs/content/locales/fr-FR/workspace.mdx +19 -18
  154. package/corpus/core/docs/content/locales/hi-IN/actions.mdx +2 -2
  155. package/corpus/core/docs/content/locales/hi-IN/agent-native-toolkit.mdx +2 -2
  156. package/corpus/core/docs/content/locales/hi-IN/agent-surfaces.mdx +8 -10
  157. package/corpus/core/docs/content/locales/hi-IN/agent-teams.mdx +1 -0
  158. package/corpus/core/docs/content/locales/hi-IN/authentication.mdx +1 -1
  159. package/corpus/core/docs/content/locales/hi-IN/components.mdx +11 -1
  160. package/corpus/core/docs/content/locales/hi-IN/creating-templates.mdx +3 -7
  161. package/corpus/core/docs/content/locales/hi-IN/cross-app-sso.mdx +16 -6
  162. package/corpus/core/docs/content/locales/hi-IN/deployment.mdx +8 -0
  163. package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +2 -7
  164. package/corpus/core/docs/content/locales/hi-IN/key-concepts.mdx +13 -20
  165. package/corpus/core/docs/content/locales/hi-IN/multi-tenancy.mdx +5 -5
  166. package/corpus/core/docs/content/locales/hi-IN/notifications.mdx +18 -10
  167. package/corpus/core/docs/content/locales/hi-IN/processors.mdx +11 -5
  168. package/corpus/core/docs/content/locales/hi-IN/server.mdx +17 -10
  169. package/corpus/core/docs/content/locales/hi-IN/sharing.mdx +10 -10
  170. package/corpus/core/docs/content/locales/hi-IN/skills-guide.mdx +34 -17
  171. package/corpus/core/docs/content/locales/hi-IN/template-assets.mdx +16 -13
  172. package/corpus/core/docs/content/locales/hi-IN/template-brain.mdx +3 -1
  173. package/corpus/core/docs/content/locales/hi-IN/template-clips.mdx +3 -3
  174. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +3 -1
  175. package/corpus/core/docs/content/locales/hi-IN/template-dispatch.mdx +5 -1
  176. package/corpus/core/docs/content/locales/hi-IN/template-mail.mdx +8 -0
  177. package/corpus/core/docs/content/locales/hi-IN/tracking.mdx +9 -6
  178. package/corpus/core/docs/content/locales/hi-IN/using-your-agent.mdx +0 -7
  179. package/corpus/core/docs/content/locales/hi-IN/voice-input.mdx +6 -0
  180. package/corpus/core/docs/content/locales/hi-IN/workspace-connections.mdx +9 -2
  181. package/corpus/core/docs/content/locales/hi-IN/workspace.mdx +19 -18
  182. package/corpus/core/docs/content/locales/ja-JP/actions.mdx +2 -2
  183. package/corpus/core/docs/content/locales/ja-JP/agent-native-toolkit.mdx +2 -2
  184. package/corpus/core/docs/content/locales/ja-JP/agent-surfaces.mdx +8 -10
  185. package/corpus/core/docs/content/locales/ja-JP/agent-teams.mdx +1 -0
  186. package/corpus/core/docs/content/locales/ja-JP/authentication.mdx +1 -1
  187. package/corpus/core/docs/content/locales/ja-JP/components.mdx +11 -1
  188. package/corpus/core/docs/content/locales/ja-JP/creating-templates.mdx +3 -7
  189. package/corpus/core/docs/content/locales/ja-JP/cross-app-sso.mdx +16 -6
  190. package/corpus/core/docs/content/locales/ja-JP/deployment.mdx +8 -0
  191. package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +2 -7
  192. package/corpus/core/docs/content/locales/ja-JP/key-concepts.mdx +13 -20
  193. package/corpus/core/docs/content/locales/ja-JP/multi-tenancy.mdx +5 -5
  194. package/corpus/core/docs/content/locales/ja-JP/notifications.mdx +18 -10
  195. package/corpus/core/docs/content/locales/ja-JP/processors.mdx +11 -5
  196. package/corpus/core/docs/content/locales/ja-JP/server.mdx +17 -10
  197. package/corpus/core/docs/content/locales/ja-JP/sharing.mdx +10 -10
  198. package/corpus/core/docs/content/locales/ja-JP/skills-guide.mdx +34 -17
  199. package/corpus/core/docs/content/locales/ja-JP/template-assets.mdx +16 -13
  200. package/corpus/core/docs/content/locales/ja-JP/template-brain.mdx +3 -1
  201. package/corpus/core/docs/content/locales/ja-JP/template-clips.mdx +3 -4
  202. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +3 -1
  203. package/corpus/core/docs/content/locales/ja-JP/template-dispatch.mdx +5 -1
  204. package/corpus/core/docs/content/locales/ja-JP/template-mail.mdx +8 -0
  205. package/corpus/core/docs/content/locales/ja-JP/tracking.mdx +9 -6
  206. package/corpus/core/docs/content/locales/ja-JP/using-your-agent.mdx +0 -7
  207. package/corpus/core/docs/content/locales/ja-JP/voice-input.mdx +6 -0
  208. package/corpus/core/docs/content/locales/ja-JP/workspace-connections.mdx +9 -2
  209. package/corpus/core/docs/content/locales/ja-JP/workspace.mdx +19 -18
  210. package/corpus/core/docs/content/locales/ko-KR/actions.mdx +2 -2
  211. package/corpus/core/docs/content/locales/ko-KR/agent-native-toolkit.mdx +2 -2
  212. package/corpus/core/docs/content/locales/ko-KR/agent-surfaces.mdx +8 -10
  213. package/corpus/core/docs/content/locales/ko-KR/agent-teams.mdx +1 -0
  214. package/corpus/core/docs/content/locales/ko-KR/authentication.mdx +1 -1
  215. package/corpus/core/docs/content/locales/ko-KR/components.mdx +11 -1
  216. package/corpus/core/docs/content/locales/ko-KR/creating-templates.mdx +3 -7
  217. package/corpus/core/docs/content/locales/ko-KR/cross-app-sso.mdx +16 -6
  218. package/corpus/core/docs/content/locales/ko-KR/deployment.mdx +8 -0
  219. package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +2 -7
  220. package/corpus/core/docs/content/locales/ko-KR/key-concepts.mdx +13 -20
  221. package/corpus/core/docs/content/locales/ko-KR/multi-tenancy.mdx +5 -5
  222. package/corpus/core/docs/content/locales/ko-KR/notifications.mdx +18 -10
  223. package/corpus/core/docs/content/locales/ko-KR/processors.mdx +11 -5
  224. package/corpus/core/docs/content/locales/ko-KR/server.mdx +17 -10
  225. package/corpus/core/docs/content/locales/ko-KR/sharing.mdx +10 -10
  226. package/corpus/core/docs/content/locales/ko-KR/skills-guide.mdx +34 -17
  227. package/corpus/core/docs/content/locales/ko-KR/template-assets.mdx +16 -13
  228. package/corpus/core/docs/content/locales/ko-KR/template-brain.mdx +3 -1
  229. package/corpus/core/docs/content/locales/ko-KR/template-clips.mdx +3 -4
  230. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +3 -1
  231. package/corpus/core/docs/content/locales/ko-KR/template-dispatch.mdx +5 -1
  232. package/corpus/core/docs/content/locales/ko-KR/template-mail.mdx +8 -0
  233. package/corpus/core/docs/content/locales/ko-KR/tracking.mdx +9 -6
  234. package/corpus/core/docs/content/locales/ko-KR/using-your-agent.mdx +0 -7
  235. package/corpus/core/docs/content/locales/ko-KR/voice-input.mdx +6 -0
  236. package/corpus/core/docs/content/locales/ko-KR/workspace-connections.mdx +9 -2
  237. package/corpus/core/docs/content/locales/ko-KR/workspace.mdx +19 -18
  238. package/corpus/core/docs/content/locales/pt-BR/actions.mdx +2 -2
  239. package/corpus/core/docs/content/locales/pt-BR/agent-native-toolkit.mdx +2 -2
  240. package/corpus/core/docs/content/locales/pt-BR/agent-surfaces.mdx +8 -10
  241. package/corpus/core/docs/content/locales/pt-BR/agent-teams.mdx +1 -0
  242. package/corpus/core/docs/content/locales/pt-BR/authentication.mdx +1 -1
  243. package/corpus/core/docs/content/locales/pt-BR/components.mdx +11 -1
  244. package/corpus/core/docs/content/locales/pt-BR/creating-templates.mdx +3 -7
  245. package/corpus/core/docs/content/locales/pt-BR/cross-app-sso.mdx +16 -6
  246. package/corpus/core/docs/content/locales/pt-BR/deployment.mdx +8 -0
  247. package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +3 -7
  248. package/corpus/core/docs/content/locales/pt-BR/key-concepts.mdx +13 -20
  249. package/corpus/core/docs/content/locales/pt-BR/multi-tenancy.mdx +5 -5
  250. package/corpus/core/docs/content/locales/pt-BR/notifications.mdx +18 -10
  251. package/corpus/core/docs/content/locales/pt-BR/processors.mdx +11 -5
  252. package/corpus/core/docs/content/locales/pt-BR/server.mdx +17 -10
  253. package/corpus/core/docs/content/locales/pt-BR/sharing.mdx +10 -10
  254. package/corpus/core/docs/content/locales/pt-BR/skills-guide.mdx +34 -17
  255. package/corpus/core/docs/content/locales/pt-BR/template-assets.mdx +16 -13
  256. package/corpus/core/docs/content/locales/pt-BR/template-brain.mdx +3 -1
  257. package/corpus/core/docs/content/locales/pt-BR/template-clips.mdx +3 -3
  258. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +3 -1
  259. package/corpus/core/docs/content/locales/pt-BR/template-dispatch.mdx +5 -1
  260. package/corpus/core/docs/content/locales/pt-BR/template-mail.mdx +8 -0
  261. package/corpus/core/docs/content/locales/pt-BR/tracking.mdx +9 -6
  262. package/corpus/core/docs/content/locales/pt-BR/using-your-agent.mdx +0 -7
  263. package/corpus/core/docs/content/locales/pt-BR/voice-input.mdx +6 -0
  264. package/corpus/core/docs/content/locales/pt-BR/workspace-connections.mdx +9 -2
  265. package/corpus/core/docs/content/locales/pt-BR/workspace.mdx +19 -18
  266. package/corpus/core/docs/content/locales/zh-CN/actions.mdx +2 -2
  267. package/corpus/core/docs/content/locales/zh-CN/agent-native-toolkit.mdx +2 -2
  268. package/corpus/core/docs/content/locales/zh-CN/agent-surfaces.mdx +8 -10
  269. package/corpus/core/docs/content/locales/zh-CN/agent-teams.mdx +1 -0
  270. package/corpus/core/docs/content/locales/zh-CN/authentication.mdx +1 -1
  271. package/corpus/core/docs/content/locales/zh-CN/components.mdx +11 -1
  272. package/corpus/core/docs/content/locales/zh-CN/creating-templates.mdx +3 -7
  273. package/corpus/core/docs/content/locales/zh-CN/cross-app-sso.mdx +16 -6
  274. package/corpus/core/docs/content/locales/zh-CN/deployment.mdx +8 -0
  275. package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +2 -7
  276. package/corpus/core/docs/content/locales/zh-CN/key-concepts.mdx +13 -20
  277. package/corpus/core/docs/content/locales/zh-CN/multi-tenancy.mdx +5 -5
  278. package/corpus/core/docs/content/locales/zh-CN/notifications.mdx +18 -10
  279. package/corpus/core/docs/content/locales/zh-CN/processors.mdx +11 -5
  280. package/corpus/core/docs/content/locales/zh-CN/server.mdx +16 -10
  281. package/corpus/core/docs/content/locales/zh-CN/sharing.mdx +10 -10
  282. package/corpus/core/docs/content/locales/zh-CN/skills-guide.mdx +34 -17
  283. package/corpus/core/docs/content/locales/zh-CN/template-assets.mdx +16 -13
  284. package/corpus/core/docs/content/locales/zh-CN/template-brain.mdx +3 -1
  285. package/corpus/core/docs/content/locales/zh-CN/template-clips.mdx +3 -4
  286. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +3 -1
  287. package/corpus/core/docs/content/locales/zh-CN/template-dispatch.mdx +5 -1
  288. package/corpus/core/docs/content/locales/zh-CN/template-mail.mdx +8 -0
  289. package/corpus/core/docs/content/locales/zh-CN/tracking.mdx +9 -6
  290. package/corpus/core/docs/content/locales/zh-CN/using-your-agent.mdx +0 -7
  291. package/corpus/core/docs/content/locales/zh-CN/voice-input.mdx +6 -0
  292. package/corpus/core/docs/content/locales/zh-CN/workspace-connections.mdx +9 -2
  293. package/corpus/core/docs/content/locales/zh-CN/workspace.mdx +19 -18
  294. package/corpus/core/docs/content/locales/zh-TW/actions.mdx +2 -2
  295. package/corpus/core/docs/content/locales/zh-TW/agent-native-toolkit.mdx +2 -2
  296. package/corpus/core/docs/content/locales/zh-TW/agent-surfaces.mdx +8 -10
  297. package/corpus/core/docs/content/locales/zh-TW/agent-teams.mdx +1 -0
  298. package/corpus/core/docs/content/locales/zh-TW/authentication.mdx +1 -1
  299. package/corpus/core/docs/content/locales/zh-TW/components.mdx +11 -1
  300. package/corpus/core/docs/content/locales/zh-TW/creating-templates.mdx +3 -7
  301. package/corpus/core/docs/content/locales/zh-TW/cross-app-sso.mdx +16 -6
  302. package/corpus/core/docs/content/locales/zh-TW/deployment.mdx +8 -0
  303. package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +2 -7
  304. package/corpus/core/docs/content/locales/zh-TW/key-concepts.mdx +13 -20
  305. package/corpus/core/docs/content/locales/zh-TW/multi-tenancy.mdx +5 -5
  306. package/corpus/core/docs/content/locales/zh-TW/notifications.mdx +18 -10
  307. package/corpus/core/docs/content/locales/zh-TW/processors.mdx +11 -5
  308. package/corpus/core/docs/content/locales/zh-TW/server.mdx +16 -10
  309. package/corpus/core/docs/content/locales/zh-TW/sharing.mdx +10 -10
  310. package/corpus/core/docs/content/locales/zh-TW/skills-guide.mdx +34 -17
  311. package/corpus/core/docs/content/locales/zh-TW/template-assets.mdx +16 -13
  312. package/corpus/core/docs/content/locales/zh-TW/template-brain.mdx +3 -1
  313. package/corpus/core/docs/content/locales/zh-TW/template-clips.mdx +3 -4
  314. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +3 -1
  315. package/corpus/core/docs/content/locales/zh-TW/template-dispatch.mdx +5 -1
  316. package/corpus/core/docs/content/locales/zh-TW/template-mail.mdx +8 -0
  317. package/corpus/core/docs/content/locales/zh-TW/tracking.mdx +9 -6
  318. package/corpus/core/docs/content/locales/zh-TW/using-your-agent.mdx +0 -7
  319. package/corpus/core/docs/content/locales/zh-TW/voice-input.mdx +6 -0
  320. package/corpus/core/docs/content/locales/zh-TW/workspace-connections.mdx +9 -2
  321. package/corpus/core/docs/content/locales/zh-TW/workspace.mdx +19 -18
  322. package/corpus/core/docs/content/mcp-apps.mdx +14 -32
  323. package/corpus/core/docs/content/mcp-clients.mdx +48 -54
  324. package/corpus/core/docs/content/mcp-protocol.mdx +25 -10
  325. package/corpus/core/docs/content/messaging.mdx +19 -11
  326. package/corpus/core/docs/content/multi-app-workspace.mdx +11 -96
  327. package/corpus/core/docs/content/multi-tenancy.mdx +5 -5
  328. package/corpus/core/docs/content/native-chat-ui.mdx +4 -4
  329. package/corpus/core/docs/content/notifications.mdx +19 -12
  330. package/corpus/core/docs/content/observability.mdx +2 -4
  331. package/corpus/core/docs/content/observational-memory.mdx +7 -3
  332. package/corpus/core/docs/content/onboarding.mdx +9 -2
  333. package/corpus/core/docs/content/plan-plugin.mdx +10 -2
  334. package/corpus/core/docs/content/pr-visual-recap.mdx +1 -1
  335. package/corpus/core/docs/content/processors.mdx +11 -5
  336. package/corpus/core/docs/content/pure-agent-apps.mdx +5 -1
  337. package/corpus/core/docs/content/real-time-collaboration.mdx +30 -67
  338. package/corpus/core/docs/content/recurring-jobs.mdx +8 -6
  339. package/corpus/core/docs/content/routing.mdx +3 -4
  340. package/corpus/core/docs/content/sandbox-adapters.mdx +30 -53
  341. package/corpus/core/docs/content/security.mdx +8 -0
  342. package/corpus/core/docs/content/server.mdx +17 -10
  343. package/corpus/core/docs/content/sharing.mdx +10 -10
  344. package/corpus/core/docs/content/skills-guide.mdx +35 -16
  345. package/corpus/core/docs/content/template-analytics.mdx +11 -8
  346. package/corpus/core/docs/content/template-assets.mdx +16 -13
  347. package/corpus/core/docs/content/template-brain.mdx +3 -1
  348. package/corpus/core/docs/content/template-calendar.mdx +12 -4
  349. package/corpus/core/docs/content/template-chat.mdx +4 -4
  350. package/corpus/core/docs/content/template-clips.mdx +3 -3
  351. package/corpus/core/docs/content/template-content.mdx +23 -18
  352. package/corpus/core/docs/content/template-design.mdx +3 -1
  353. package/corpus/core/docs/content/template-dispatch.mdx +5 -1
  354. package/corpus/core/docs/content/template-mail.mdx +14 -2
  355. package/corpus/core/docs/content/template-plan.mdx +22 -15
  356. package/corpus/core/docs/content/template-slides.mdx +11 -3
  357. package/corpus/core/docs/content/toolkit-agent-ux.mdx +46 -3
  358. package/corpus/core/docs/content/toolkit-collaboration.mdx +58 -4
  359. package/corpus/core/docs/content/toolkit-command-navigation.mdx +8 -2
  360. package/corpus/core/docs/content/toolkit-comments-review.mdx +10 -2
  361. package/corpus/core/docs/content/toolkit-history.mdx +8 -3
  362. package/corpus/core/docs/content/toolkit-observability.mdx +48 -2
  363. package/corpus/core/docs/content/toolkit-org-team.mdx +8 -2
  364. package/corpus/core/docs/content/toolkit-resources.mdx +45 -2
  365. package/corpus/core/docs/content/toolkit-settings.mdx +8 -2
  366. package/corpus/core/docs/content/toolkit-setup-connections.mdx +7 -2
  367. package/corpus/core/docs/content/toolkit-sharing.mdx +46 -3
  368. package/corpus/core/docs/content/toolkit-ui.mdx +82 -11
  369. package/corpus/core/docs/content/tracking.mdx +10 -8
  370. package/corpus/core/docs/content/using-your-agent.mdx +0 -12
  371. package/corpus/core/docs/content/voice-input.mdx +7 -1
  372. package/corpus/core/docs/content/what-is-agent-native.mdx +7 -8
  373. package/corpus/core/docs/content/workspace-connections.mdx +16 -23
  374. package/corpus/core/docs/content/workspace-management.mdx +16 -4
  375. package/corpus/core/docs/content/workspace.mdx +19 -18
  376. package/corpus/core/package.json +1 -1
  377. package/corpus/core/src/agent/context-xray/tokenize.ts +6 -1
  378. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +9 -5
  379. package/corpus/core/src/agent/engine/anthropic-engine.ts +2 -4
  380. package/corpus/core/src/agent/engine/builder-engine.ts +5 -7
  381. package/corpus/core/src/agent/engine/index.ts +1 -0
  382. package/corpus/core/src/agent/engine/registry.ts +40 -0
  383. package/corpus/core/src/agent/harness/ai-sdk-adapter.ts +6 -1
  384. package/corpus/core/src/agent/harness/background.ts +96 -19
  385. package/corpus/core/src/agent/harness/index.ts +11 -0
  386. package/corpus/core/src/agent/harness/lifecycle.ts +498 -0
  387. package/corpus/core/src/agent/harness/runner.ts +38 -0
  388. package/corpus/core/src/agent/harness/store.ts +22 -3
  389. package/corpus/core/src/agent/model-config.ts +4 -1
  390. package/corpus/core/src/agent/production-agent.ts +190 -6
  391. package/corpus/core/src/agent/run-manager.ts +5 -1
  392. package/corpus/core/src/application-state/index.ts +1 -0
  393. package/corpus/core/src/application-state/store.ts +32 -0
  394. package/corpus/core/src/cli/code-agent-connector.ts +263 -8
  395. package/corpus/core/src/cli/code-agent-executor.ts +15 -1
  396. package/corpus/core/src/client/AgentPanel.tsx +41 -38
  397. package/corpus/core/src/client/AssistantChat.tsx +98 -6
  398. package/corpus/core/src/client/MultiTabAssistantChat.tsx +33 -40
  399. package/corpus/core/src/client/appearance.ts +8 -5
  400. package/corpus/core/src/client/chat/connectors.ts +293 -29
  401. package/corpus/core/src/client/chat/message-components.tsx +23 -1
  402. package/corpus/core/src/client/chat/runtime.ts +126 -25
  403. package/corpus/core/src/client/chat/tool-call-display.tsx +45 -4
  404. package/corpus/core/src/client/composer/RealtimeVoiceMode.tsx +294 -0
  405. package/corpus/core/src/client/composer/TiptapComposer.tsx +21 -20
  406. package/corpus/core/src/client/composer/VoiceButton.tsx +20 -0
  407. package/corpus/core/src/client/composer/index.ts +22 -0
  408. package/corpus/core/src/client/composer/useRealtimeVoiceMode.tsx +640 -0
  409. package/corpus/core/src/client/guided-questions.tsx +12 -3
  410. package/corpus/core/src/client/index.ts +18 -0
  411. package/corpus/core/src/client/settings/DemoModeSection.tsx +4 -3
  412. package/corpus/core/src/client/settings/SettingsPanel.tsx +4 -0
  413. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +95 -37
  414. package/corpus/core/src/client/use-chat-models.ts +17 -17
  415. package/corpus/core/src/client/use-db-sync.ts +108 -7
  416. package/corpus/core/src/code-agents/background-controller.ts +18 -0
  417. package/corpus/core/src/collab/ydoc-manager.ts +41 -6
  418. package/corpus/core/src/db/migrations.ts +17 -1
  419. package/corpus/core/src/demo/fetch-interceptor.ts +16 -11
  420. package/corpus/core/src/integrations/adapters/slack.ts +41 -2
  421. package/corpus/core/src/integrations/awaiting-input-store.ts +130 -0
  422. package/corpus/core/src/integrations/computer-supervision-store.ts +423 -0
  423. package/corpus/core/src/integrations/computer-supervision.ts +213 -0
  424. package/corpus/core/src/integrations/index.ts +29 -1
  425. package/corpus/core/src/integrations/plugin.ts +231 -2
  426. package/corpus/core/src/integrations/remote-commands-store.ts +334 -3
  427. package/corpus/core/src/integrations/remote-devices-store.ts +68 -9
  428. package/corpus/core/src/integrations/remote-json-safety.ts +127 -0
  429. package/corpus/core/src/integrations/remote-run-events-store.ts +104 -19
  430. package/corpus/core/src/integrations/remote-types.ts +66 -3
  431. package/corpus/core/src/integrations/webhook-handler.ts +161 -2
  432. package/corpus/core/src/localization/default-messages.ts +28 -0
  433. package/corpus/core/src/mcp-client/config.ts +48 -2
  434. package/corpus/core/src/mcp-client/index.ts +35 -2
  435. package/corpus/core/src/mcp-client/tool-policy.ts +182 -0
  436. package/corpus/core/src/secrets/register-framework-secrets.ts +27 -4
  437. package/corpus/core/src/server/agent-chat-plugin.ts +62 -8
  438. package/corpus/core/src/server/index.ts +16 -0
  439. package/corpus/core/src/server/realtime-voice.ts +590 -0
  440. package/corpus/core/src/shared/reasoning-effort.ts +61 -19
  441. package/corpus/core/src/styles/agent-conversation.css +17 -0
  442. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -5
  443. package/corpus/templates/brain/app/lib/settings-navigation.ts +22 -0
  444. package/corpus/templates/brain/app/routes/settings.tsx +367 -252
  445. package/corpus/templates/brain/changelog/2026-07-10-brain-settings-now-separate-assistant-behavior-publishing-re.md +6 -0
  446. package/corpus/templates/brain/changelog/2026-07-10-organization-settings-now-opens-directly-from-the-workspace-.md +6 -0
  447. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +36 -4
  448. package/corpus/templates/calendar/AGENTS.md +4 -0
  449. package/corpus/templates/calendar/actions/create-event.ts +7 -19
  450. package/corpus/templates/calendar/actions/delete-event.ts +10 -3
  451. package/corpus/templates/calendar/actions/rsvp-event.ts +1 -1
  452. package/corpus/templates/calendar/actions/update-event.ts +4 -3
  453. package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +100 -13
  454. package/corpus/templates/calendar/app/components/calendar/DayView.tsx +12 -4
  455. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +3 -3
  456. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +86 -8
  457. package/corpus/templates/calendar/app/components/calendar/EventDialog.tsx +3 -1
  458. package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +12 -4
  459. package/corpus/templates/calendar/app/hooks/use-events.ts +1 -0
  460. package/corpus/templates/calendar/app/lib/event-account-selection.ts +36 -0
  461. package/corpus/templates/calendar/app/lib/event-form-initialization.ts +21 -0
  462. package/corpus/templates/calendar/app/lib/event-mutation-inputs.ts +18 -0
  463. package/corpus/templates/calendar/app/pages/CalendarView.tsx +119 -26
  464. package/corpus/templates/calendar/changelog/2026-07-10-choose-which-connected-google-account-receives-a-new-event-w.md +6 -0
  465. package/corpus/templates/calendar/server/db/schema.ts +2 -0
  466. package/corpus/templates/calendar/server/handlers/bookings.ts +43 -6
  467. package/corpus/templates/calendar/server/handlers/events.ts +28 -9
  468. package/corpus/templates/calendar/server/lib/google-calendar.ts +66 -38
  469. package/corpus/templates/calendar/server/plugins/db.ts +5 -0
  470. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +12 -3
  471. package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +1 -1
  472. package/corpus/templates/clips/AGENTS.md +4 -2
  473. package/corpus/templates/clips/actions/regenerate-title.ts +53 -7
  474. package/corpus/templates/clips/actions/request-transcript.ts +152 -41
  475. package/corpus/templates/clips/actions/save-browser-transcript.ts +11 -9
  476. package/corpus/templates/clips/app/components/player/comments-panel.tsx +101 -53
  477. package/corpus/templates/clips/app/components/player/playback-comment-overlay.tsx +102 -0
  478. package/corpus/templates/clips/app/components/player/video-player.tsx +10 -1
  479. package/corpus/templates/clips/app/hooks/use-auto-title.ts +14 -0
  480. package/corpus/templates/clips/app/routes/embed.$shareId.tsx +2 -0
  481. package/corpus/templates/clips/changelog/2026-07-10-comment-replies-now-open-inline-and-focus-immediately-while-.md +6 -0
  482. package/corpus/templates/clips/changelog/2026-07-10-dismissed-upload-warnings-now-keep-recordings-in-clip-drafts.md +6 -0
  483. package/corpus/templates/clips/changelog/2026-07-10-dragging-the-meeting-recorder-no-longer-opens-the-expanded.md +6 -0
  484. package/corpus/templates/clips/changelog/2026-07-10-finishing-meeting-notes-no-longer-opens-your-browser.md +6 -0
  485. package/corpus/templates/clips/changelog/2026-07-10-meeting-recordings-now-keep-microphone-audio-and-recover-tra.md +6 -0
  486. package/corpus/templates/clips/changelog/2026-07-10-recording-pause-and-resume-controls-now-respond-reliably-on-.md +6 -0
  487. package/corpus/templates/clips/changelog/2026-07-10-starting-and-joining-a-meeting-now-closes-the-desktop-popover.md +6 -0
  488. package/corpus/templates/clips/changelog/2026-07-10-timestamped-comments-now-appear-over-the-video-as-playback-r.md +6 -0
  489. package/corpus/templates/clips/changelog/2026-07-10-transcript-backed-titles-and-summaries-now-finish-after-recording.md +6 -0
  490. package/corpus/templates/clips/changelog/2026-07-10-zoom-meetings-now-open-directly-in-the-desktop-app.md +6 -0
  491. package/corpus/templates/clips/chrome-extension/src/overlay.ts +49 -7
  492. package/corpus/templates/clips/desktop/src/app.tsx +70 -42
  493. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +8 -14
  494. package/corpus/templates/clips/desktop/src/lib/meeting-join-url.ts +33 -0
  495. package/corpus/templates/clips/desktop/src/lib/pause-transition.ts +79 -0
  496. package/corpus/templates/clips/desktop/src/lib/pill-interaction.ts +19 -0
  497. package/corpus/templates/clips/desktop/src/lib/recorder.ts +90 -39
  498. package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +3 -2
  499. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +3 -2
  500. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +32 -6
  501. package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +50 -5
  502. package/corpus/templates/clips/desktop/src/styles.css +11 -19
  503. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -1
  504. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +121 -4
  505. package/corpus/templates/clips/desktop/src-tauri/src/native_speech.rs +97 -17
  506. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +80 -5
  507. package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -1
  508. package/corpus/templates/clips/vitest.config.ts +23 -0
  509. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +28 -9
  510. package/corpus/templates/content/changelog/2026-07-10-open-documents-no-longer-make-constant-background-requests-w.md +6 -0
  511. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +21 -4
  512. package/corpus/templates/design/AGENTS.md +7 -0
  513. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +132 -7
  514. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +73 -18
  515. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +6 -1
  516. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +135 -5
  517. package/corpus/templates/design/app/lib/clipboard-content-lineage.ts +64 -0
  518. package/corpus/templates/design/app/lib/design-clipboard-managed-styles.ts +247 -0
  519. package/corpus/templates/design/app/lib/design-clipboard.ts +60 -3
  520. package/corpus/templates/design/app/lib/design-import.ts +31 -3
  521. package/corpus/templates/design/app/pages/design-editor/latest-write-queue.ts +56 -0
  522. package/corpus/templates/design/app/pages/design-editor/performance-buffer-guard.ts +80 -0
  523. package/corpus/templates/design/changelog/2026-07-10-concurrent-agent-and-artboard-edits-no-longer-show-misleadin.md +6 -0
  524. package/corpus/templates/design/changelog/2026-07-10-designs-with-html-examples-inside-alpine-attributes-or-comme.md +6 -0
  525. package/corpus/templates/design/changelog/2026-07-10-interactive-designs-no-longer-appear-blank-in-the-canvas-whe.md +6 -0
  526. package/corpus/templates/design/changelog/2026-07-10-long-overview-editing-sessions-lots-of-pan-zoom-screen-switc.md +6 -0
  527. package/corpus/templates/design/changelog/2026-07-10-rapid-breakpoint-and-edit-scope-changes-no-longer-jump-back-.md +6 -0
  528. package/corpus/templates/design/changelog/2026-07-10-responsive-breakpoint-previews-stay-visible-while-panning-ac.md +6 -0
  529. package/corpus/templates/design/changelog/2026-07-10-rich-design-clipboard-markers-are-now-accepted-only-from-the.md +6 -0
  530. package/corpus/templates/design/e2e/helpers.ts +16 -5
  531. package/corpus/templates/design/server/source-workspace.ts +28 -2
  532. package/corpus/templates/design/shared/html-integrity.ts +119 -24
  533. package/corpus/templates/dispatch/AGENTS.md +10 -2
  534. package/corpus/templates/dispatch/actions/view-screen.ts +11 -0
  535. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +13 -0
  536. package/corpus/templates/dispatch/app/i18n/zh-TW.ts +3 -0
  537. package/corpus/templates/dispatch/app/i18n-data.ts +37 -1
  538. package/corpus/templates/dispatch/app/routes/operations.tsx +1 -0
  539. package/corpus/templates/dispatch/changelog/2026-07-10-dispatch-now-has-a-cleaner-chat-history-and-quieter-sidebar-.md +6 -0
  540. package/corpus/templates/dispatch/changelog/2026-07-10-operations-console-brings-agent-monitoring-and-database-inspection-tog.md +6 -0
  541. package/corpus/templates/mail/actions/get-integration-statuses.ts +36 -0
  542. package/corpus/templates/mail/app/components/email/EmailThread.tsx +3 -2
  543. package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +3 -3
  544. package/corpus/templates/mail/app/hooks/use-apollo.ts +5 -71
  545. package/corpus/templates/mail/app/hooks/use-draft-queue.ts +1 -1
  546. package/corpus/templates/mail/app/hooks/use-integrations.ts +51 -48
  547. package/corpus/templates/mail/app/lib/integration-status.ts +31 -0
  548. package/corpus/templates/mail/app/lib/sync-invalidation.ts +5 -0
  549. package/corpus/templates/mail/app/pages/SettingsPage.tsx +3 -0
  550. package/corpus/templates/mail/app/root.tsx +22 -12
  551. package/corpus/templates/mail/changelog/2026-07-10-email-content-backgrounds-now-blend-cleanly-with-dark-mode.md +6 -0
  552. package/corpus/templates/mail/changelog/2026-07-10-mail-settings-now-group-drafting-automation-and-connected-se.md +6 -0
  553. package/corpus/templates/mail/changelog/2026-07-10-organization-settings-now-opens-directly-from-the-workspace-.md +6 -0
  554. package/dist/agent/context-xray/tokenize.d.ts.map +1 -1
  555. package/dist/agent/context-xray/tokenize.js +6 -1
  556. package/dist/agent/context-xray/tokenize.js.map +1 -1
  557. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  558. package/dist/agent/engine/ai-sdk-engine.js +8 -3
  559. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  560. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  561. package/dist/agent/engine/anthropic-engine.js +2 -4
  562. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  563. package/dist/agent/engine/builder-engine.d.ts +1 -1
  564. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  565. package/dist/agent/engine/builder-engine.js +2 -3
  566. package/dist/agent/engine/builder-engine.js.map +1 -1
  567. package/dist/agent/engine/index.d.ts +1 -1
  568. package/dist/agent/engine/index.d.ts.map +1 -1
  569. package/dist/agent/engine/index.js +1 -1
  570. package/dist/agent/engine/index.js.map +1 -1
  571. package/dist/agent/engine/registry.d.ts +13 -0
  572. package/dist/agent/engine/registry.d.ts.map +1 -1
  573. package/dist/agent/engine/registry.js +33 -0
  574. package/dist/agent/engine/registry.js.map +1 -1
  575. package/dist/agent/harness/ai-sdk-adapter.d.ts.map +1 -1
  576. package/dist/agent/harness/ai-sdk-adapter.js +3 -1
  577. package/dist/agent/harness/ai-sdk-adapter.js.map +1 -1
  578. package/dist/agent/harness/background.d.ts +9 -9
  579. package/dist/agent/harness/background.d.ts.map +1 -1
  580. package/dist/agent/harness/background.js +77 -19
  581. package/dist/agent/harness/background.js.map +1 -1
  582. package/dist/agent/harness/index.d.ts +1 -0
  583. package/dist/agent/harness/index.d.ts.map +1 -1
  584. package/dist/agent/harness/index.js +1 -0
  585. package/dist/agent/harness/index.js.map +1 -1
  586. package/dist/agent/harness/lifecycle.d.ts +45 -0
  587. package/dist/agent/harness/lifecycle.d.ts.map +1 -0
  588. package/dist/agent/harness/lifecycle.js +318 -0
  589. package/dist/agent/harness/lifecycle.js.map +1 -0
  590. package/dist/agent/harness/runner.d.ts.map +1 -1
  591. package/dist/agent/harness/runner.js +29 -1
  592. package/dist/agent/harness/runner.js.map +1 -1
  593. package/dist/agent/harness/store.d.ts +2 -0
  594. package/dist/agent/harness/store.d.ts.map +1 -1
  595. package/dist/agent/harness/store.js +17 -3
  596. package/dist/agent/harness/store.js.map +1 -1
  597. package/dist/agent/model-config.d.ts +2 -2
  598. package/dist/agent/model-config.d.ts.map +1 -1
  599. package/dist/agent/model-config.js +4 -1
  600. package/dist/agent/model-config.js.map +1 -1
  601. package/dist/agent/production-agent.d.ts +38 -0
  602. package/dist/agent/production-agent.d.ts.map +1 -1
  603. package/dist/agent/production-agent.js +135 -4
  604. package/dist/agent/production-agent.js.map +1 -1
  605. package/dist/agent/run-manager.d.ts.map +1 -1
  606. package/dist/agent/run-manager.js.map +1 -1
  607. package/dist/application-state/index.d.ts +1 -1
  608. package/dist/application-state/index.d.ts.map +1 -1
  609. package/dist/application-state/index.js +1 -1
  610. package/dist/application-state/index.js.map +1 -1
  611. package/dist/application-state/store.d.ts +6 -0
  612. package/dist/application-state/store.d.ts.map +1 -1
  613. package/dist/application-state/store.js +31 -0
  614. package/dist/application-state/store.js.map +1 -1
  615. package/dist/cli/code-agent-connector.d.ts +9 -0
  616. package/dist/cli/code-agent-connector.d.ts.map +1 -1
  617. package/dist/cli/code-agent-connector.js +212 -10
  618. package/dist/cli/code-agent-connector.js.map +1 -1
  619. package/dist/cli/code-agent-executor.d.ts +2 -0
  620. package/dist/cli/code-agent-executor.d.ts.map +1 -1
  621. package/dist/cli/code-agent-executor.js +8 -1
  622. package/dist/cli/code-agent-executor.js.map +1 -1
  623. package/dist/client/AgentPanel.d.ts.map +1 -1
  624. package/dist/client/AgentPanel.js +6 -5
  625. package/dist/client/AgentPanel.js.map +1 -1
  626. package/dist/client/AssistantChat.d.ts +12 -0
  627. package/dist/client/AssistantChat.d.ts.map +1 -1
  628. package/dist/client/AssistantChat.js +71 -5
  629. package/dist/client/AssistantChat.js.map +1 -1
  630. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  631. package/dist/client/MultiTabAssistantChat.js +16 -37
  632. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  633. package/dist/client/appearance.d.ts +4 -2
  634. package/dist/client/appearance.d.ts.map +1 -1
  635. package/dist/client/appearance.js +8 -5
  636. package/dist/client/appearance.js.map +1 -1
  637. package/dist/client/chat/connectors.d.ts.map +1 -1
  638. package/dist/client/chat/connectors.js +206 -28
  639. package/dist/client/chat/connectors.js.map +1 -1
  640. package/dist/client/chat/message-components.d.ts.map +1 -1
  641. package/dist/client/chat/message-components.js +17 -1
  642. package/dist/client/chat/message-components.js.map +1 -1
  643. package/dist/client/chat/runtime.d.ts.map +1 -1
  644. package/dist/client/chat/runtime.js +84 -24
  645. package/dist/client/chat/runtime.js.map +1 -1
  646. package/dist/client/chat/tool-call-display.d.ts +8 -1
  647. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  648. package/dist/client/chat/tool-call-display.js +21 -3
  649. package/dist/client/chat/tool-call-display.js.map +1 -1
  650. package/dist/client/composer/RealtimeVoiceMode.d.ts +54 -0
  651. package/dist/client/composer/RealtimeVoiceMode.d.ts.map +1 -0
  652. package/dist/client/composer/RealtimeVoiceMode.js +63 -0
  653. package/dist/client/composer/RealtimeVoiceMode.js.map +1 -0
  654. package/dist/client/composer/TiptapComposer.d.ts +1 -0
  655. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  656. package/dist/client/composer/TiptapComposer.js +17 -20
  657. package/dist/client/composer/TiptapComposer.js.map +1 -1
  658. package/dist/client/composer/VoiceButton.d.ts.map +1 -1
  659. package/dist/client/composer/VoiceButton.js +9 -0
  660. package/dist/client/composer/VoiceButton.js.map +1 -1
  661. package/dist/client/composer/index.d.ts +2 -0
  662. package/dist/client/composer/index.d.ts.map +1 -1
  663. package/dist/client/composer/index.js +2 -0
  664. package/dist/client/composer/index.js.map +1 -1
  665. package/dist/client/composer/useRealtimeVoiceMode.d.ts +56 -0
  666. package/dist/client/composer/useRealtimeVoiceMode.d.ts.map +1 -0
  667. package/dist/client/composer/useRealtimeVoiceMode.js +492 -0
  668. package/dist/client/composer/useRealtimeVoiceMode.js.map +1 -0
  669. package/dist/client/guided-questions.d.ts.map +1 -1
  670. package/dist/client/guided-questions.js +7 -2
  671. package/dist/client/guided-questions.js.map +1 -1
  672. package/dist/client/index.d.ts +1 -1
  673. package/dist/client/index.d.ts.map +1 -1
  674. package/dist/client/index.js +1 -1
  675. package/dist/client/index.js.map +1 -1
  676. package/dist/client/settings/DemoModeSection.d.ts.map +1 -1
  677. package/dist/client/settings/DemoModeSection.js +4 -3
  678. package/dist/client/settings/DemoModeSection.js.map +1 -1
  679. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  680. package/dist/client/settings/SettingsPanel.js +4 -0
  681. package/dist/client/settings/SettingsPanel.js.map +1 -1
  682. package/dist/client/settings/SettingsTabsPage.d.ts +10 -3
  683. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  684. package/dist/client/settings/SettingsTabsPage.js +49 -11
  685. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  686. package/dist/client/use-chat-models.d.ts.map +1 -1
  687. package/dist/client/use-chat-models.js +6 -14
  688. package/dist/client/use-chat-models.js.map +1 -1
  689. package/dist/client/use-db-sync.d.ts.map +1 -1
  690. package/dist/client/use-db-sync.js +87 -7
  691. package/dist/client/use-db-sync.js.map +1 -1
  692. package/dist/code-agents/background-controller.d.ts +1 -1
  693. package/dist/code-agents/background-controller.d.ts.map +1 -1
  694. package/dist/code-agents/background-controller.js +17 -1
  695. package/dist/code-agents/background-controller.js.map +1 -1
  696. package/dist/collab/struct-routes.d.ts +1 -1
  697. package/dist/collab/ydoc-manager.d.ts +9 -1
  698. package/dist/collab/ydoc-manager.d.ts.map +1 -1
  699. package/dist/collab/ydoc-manager.js +30 -6
  700. package/dist/collab/ydoc-manager.js.map +1 -1
  701. package/dist/db/migrations.d.ts.map +1 -1
  702. package/dist/db/migrations.js +4 -2
  703. package/dist/db/migrations.js.map +1 -1
  704. package/dist/demo/fetch-interceptor.d.ts +5 -1
  705. package/dist/demo/fetch-interceptor.d.ts.map +1 -1
  706. package/dist/demo/fetch-interceptor.js +16 -12
  707. package/dist/demo/fetch-interceptor.js.map +1 -1
  708. package/dist/integrations/adapters/slack.d.ts +2 -0
  709. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  710. package/dist/integrations/adapters/slack.js +38 -2
  711. package/dist/integrations/adapters/slack.js.map +1 -1
  712. package/dist/integrations/awaiting-input-store.d.ts +27 -0
  713. package/dist/integrations/awaiting-input-store.d.ts.map +1 -0
  714. package/dist/integrations/awaiting-input-store.js +112 -0
  715. package/dist/integrations/awaiting-input-store.js.map +1 -0
  716. package/dist/integrations/computer-supervision-store.d.ts +65 -0
  717. package/dist/integrations/computer-supervision-store.d.ts.map +1 -0
  718. package/dist/integrations/computer-supervision-store.js +296 -0
  719. package/dist/integrations/computer-supervision-store.js.map +1 -0
  720. package/dist/integrations/computer-supervision.d.ts +11 -0
  721. package/dist/integrations/computer-supervision.d.ts.map +1 -0
  722. package/dist/integrations/computer-supervision.js +160 -0
  723. package/dist/integrations/computer-supervision.js.map +1 -0
  724. package/dist/integrations/index.d.ts +6 -3
  725. package/dist/integrations/index.d.ts.map +1 -1
  726. package/dist/integrations/index.js +5 -2
  727. package/dist/integrations/index.js.map +1 -1
  728. package/dist/integrations/plugin.d.ts.map +1 -1
  729. package/dist/integrations/plugin.js +205 -3
  730. package/dist/integrations/plugin.js.map +1 -1
  731. package/dist/integrations/remote-commands-store.d.ts +15 -1
  732. package/dist/integrations/remote-commands-store.d.ts.map +1 -1
  733. package/dist/integrations/remote-commands-store.js +273 -3
  734. package/dist/integrations/remote-commands-store.js.map +1 -1
  735. package/dist/integrations/remote-devices-store.d.ts +4 -3
  736. package/dist/integrations/remote-devices-store.d.ts.map +1 -1
  737. package/dist/integrations/remote-devices-store.js +49 -2
  738. package/dist/integrations/remote-devices-store.js.map +1 -1
  739. package/dist/integrations/remote-json-safety.d.ts +6 -0
  740. package/dist/integrations/remote-json-safety.d.ts.map +1 -0
  741. package/dist/integrations/remote-json-safety.js +114 -0
  742. package/dist/integrations/remote-json-safety.js.map +1 -0
  743. package/dist/integrations/remote-run-events-store.d.ts +11 -1
  744. package/dist/integrations/remote-run-events-store.d.ts.map +1 -1
  745. package/dist/integrations/remote-run-events-store.js +85 -17
  746. package/dist/integrations/remote-run-events-store.js.map +1 -1
  747. package/dist/integrations/remote-types.d.ts +54 -3
  748. package/dist/integrations/remote-types.d.ts.map +1 -1
  749. package/dist/integrations/remote-types.js.map +1 -1
  750. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  751. package/dist/integrations/webhook-handler.js +133 -4
  752. package/dist/integrations/webhook-handler.js.map +1 -1
  753. package/dist/localization/default-messages.d.ts +26 -0
  754. package/dist/localization/default-messages.d.ts.map +1 -1
  755. package/dist/localization/default-messages.js +26 -0
  756. package/dist/localization/default-messages.js.map +1 -1
  757. package/dist/mcp-client/config.d.ts.map +1 -1
  758. package/dist/mcp-client/config.js +44 -3
  759. package/dist/mcp-client/config.js.map +1 -1
  760. package/dist/mcp-client/index.d.ts +6 -1
  761. package/dist/mcp-client/index.d.ts.map +1 -1
  762. package/dist/mcp-client/index.js +11 -3
  763. package/dist/mcp-client/index.js.map +1 -1
  764. package/dist/mcp-client/tool-policy.d.ts +24 -0
  765. package/dist/mcp-client/tool-policy.d.ts.map +1 -0
  766. package/dist/mcp-client/tool-policy.js +139 -0
  767. package/dist/mcp-client/tool-policy.js.map +1 -0
  768. package/dist/observability/routes.d.ts +5 -5
  769. package/dist/resources/handlers.d.ts +1 -1
  770. package/dist/secrets/register-framework-secrets.d.ts +3 -4
  771. package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
  772. package/dist/secrets/register-framework-secrets.js +25 -4
  773. package/dist/secrets/register-framework-secrets.js.map +1 -1
  774. package/dist/secrets/routes.d.ts +9 -9
  775. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  776. package/dist/server/agent-chat-plugin.js +53 -6
  777. package/dist/server/agent-chat-plugin.js.map +1 -1
  778. package/dist/server/index.d.ts +2 -1
  779. package/dist/server/index.d.ts.map +1 -1
  780. package/dist/server/index.js +2 -1
  781. package/dist/server/index.js.map +1 -1
  782. package/dist/server/realtime-voice.d.ts +53 -0
  783. package/dist/server/realtime-voice.d.ts.map +1 -0
  784. package/dist/server/realtime-voice.js +404 -0
  785. package/dist/server/realtime-voice.js.map +1 -0
  786. package/dist/server/transcribe-voice.d.ts +1 -1
  787. package/dist/shared/reasoning-effort.d.ts +20 -0
  788. package/dist/shared/reasoning-effort.d.ts.map +1 -1
  789. package/dist/shared/reasoning-effort.js +52 -18
  790. package/dist/shared/reasoning-effort.js.map +1 -1
  791. package/dist/styles/agent-conversation.css +17 -0
  792. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -5
  793. package/docs/content/a2a-protocol.mdx +21 -5
  794. package/docs/content/actions.mdx +9 -23
  795. package/docs/content/agent-mentions.mdx +31 -29
  796. package/docs/content/agent-native-toolkit.mdx +15 -6
  797. package/docs/content/agent-surfaces.mdx +9 -13
  798. package/docs/content/agent-teams.mdx +1 -0
  799. package/docs/content/authentication.mdx +10 -3
  800. package/docs/content/automation-connectors.mdx +82 -39
  801. package/docs/content/automations.mdx +17 -3
  802. package/docs/content/blueprint-installer.mdx +11 -4
  803. package/docs/content/cli-adapters.mdx +9 -6
  804. package/docs/content/client.mdx +16 -0
  805. package/docs/content/cloneable-saas.mdx +14 -11
  806. package/docs/content/code-agents-ui.mdx +65 -0
  807. package/docs/content/components.mdx +30 -14
  808. package/docs/content/context-awareness.mdx +27 -15
  809. package/docs/content/creating-templates.mdx +15 -9
  810. package/docs/content/cross-app-sso.mdx +16 -6
  811. package/docs/content/data-programs.mdx +1 -1
  812. package/docs/content/database.mdx +17 -5
  813. package/docs/content/deployment.mdx +19 -18
  814. package/docs/content/dispatch.mdx +6 -2
  815. package/docs/content/drop-in-agent.mdx +10 -4
  816. package/docs/content/durable-background-runs.mdx +9 -5
  817. package/docs/content/durable-resume.mdx +9 -4
  818. package/docs/content/embedding-sdk.mdx +26 -8
  819. package/docs/content/evals.mdx +3 -5
  820. package/docs/content/extensions.mdx +22 -9
  821. package/docs/content/external-agents.mdx +25 -34
  822. package/docs/content/faq.mdx +8 -0
  823. package/docs/content/file-uploads.mdx +12 -3
  824. package/docs/content/frames.mdx +16 -0
  825. package/docs/content/generative-ui.mdx +1 -1
  826. package/docs/content/getting-started.mdx +34 -21
  827. package/docs/content/harness-agents.mdx +8 -4
  828. package/docs/content/human-approval.mdx +8 -3
  829. package/docs/content/internationalization.mdx +9 -4
  830. package/docs/content/key-concepts.mdx +13 -20
  831. package/docs/content/local-file-mode.mdx +14 -8
  832. package/docs/content/locales/ar-SA/actions.mdx +2 -2
  833. package/docs/content/locales/ar-SA/agent-native-toolkit.mdx +2 -2
  834. package/docs/content/locales/ar-SA/agent-surfaces.mdx +8 -10
  835. package/docs/content/locales/ar-SA/agent-teams.mdx +1 -0
  836. package/docs/content/locales/ar-SA/authentication.mdx +1 -1
  837. package/docs/content/locales/ar-SA/components.mdx +11 -1
  838. package/docs/content/locales/ar-SA/creating-templates.mdx +3 -7
  839. package/docs/content/locales/ar-SA/cross-app-sso.mdx +16 -6
  840. package/docs/content/locales/ar-SA/deployment.mdx +8 -0
  841. package/docs/content/locales/ar-SA/external-agents.mdx +2 -7
  842. package/docs/content/locales/ar-SA/key-concepts.mdx +13 -20
  843. package/docs/content/locales/ar-SA/multi-tenancy.mdx +5 -5
  844. package/docs/content/locales/ar-SA/notifications.mdx +18 -10
  845. package/docs/content/locales/ar-SA/processors.mdx +11 -5
  846. package/docs/content/locales/ar-SA/server.mdx +17 -10
  847. package/docs/content/locales/ar-SA/sharing.mdx +10 -10
  848. package/docs/content/locales/ar-SA/skills-guide.mdx +34 -17
  849. package/docs/content/locales/ar-SA/template-assets.mdx +16 -13
  850. package/docs/content/locales/ar-SA/template-brain.mdx +3 -1
  851. package/docs/content/locales/ar-SA/template-clips.mdx +3 -3
  852. package/docs/content/locales/ar-SA/template-design.mdx +3 -1
  853. package/docs/content/locales/ar-SA/template-dispatch.mdx +5 -1
  854. package/docs/content/locales/ar-SA/template-mail.mdx +8 -0
  855. package/docs/content/locales/ar-SA/tracking.mdx +9 -6
  856. package/docs/content/locales/ar-SA/using-your-agent.mdx +0 -7
  857. package/docs/content/locales/ar-SA/voice-input.mdx +6 -0
  858. package/docs/content/locales/ar-SA/workspace-connections.mdx +9 -2
  859. package/docs/content/locales/ar-SA/workspace.mdx +19 -18
  860. package/docs/content/locales/de-DE/actions.mdx +2 -2
  861. package/docs/content/locales/de-DE/agent-native-toolkit.mdx +2 -2
  862. package/docs/content/locales/de-DE/agent-surfaces.mdx +8 -10
  863. package/docs/content/locales/de-DE/agent-teams.mdx +1 -0
  864. package/docs/content/locales/de-DE/authentication.mdx +1 -1
  865. package/docs/content/locales/de-DE/components.mdx +11 -1
  866. package/docs/content/locales/de-DE/creating-templates.mdx +3 -7
  867. package/docs/content/locales/de-DE/cross-app-sso.mdx +16 -6
  868. package/docs/content/locales/de-DE/deployment.mdx +8 -0
  869. package/docs/content/locales/de-DE/external-agents.mdx +3 -7
  870. package/docs/content/locales/de-DE/key-concepts.mdx +13 -20
  871. package/docs/content/locales/de-DE/multi-tenancy.mdx +5 -5
  872. package/docs/content/locales/de-DE/notifications.mdx +18 -10
  873. package/docs/content/locales/de-DE/processors.mdx +11 -5
  874. package/docs/content/locales/de-DE/server.mdx +18 -10
  875. package/docs/content/locales/de-DE/sharing.mdx +10 -10
  876. package/docs/content/locales/de-DE/skills-guide.mdx +34 -17
  877. package/docs/content/locales/de-DE/template-assets.mdx +16 -13
  878. package/docs/content/locales/de-DE/template-brain.mdx +3 -1
  879. package/docs/content/locales/de-DE/template-clips.mdx +3 -3
  880. package/docs/content/locales/de-DE/template-design.mdx +3 -1
  881. package/docs/content/locales/de-DE/template-dispatch.mdx +5 -1
  882. package/docs/content/locales/de-DE/template-mail.mdx +8 -0
  883. package/docs/content/locales/de-DE/tracking.mdx +9 -6
  884. package/docs/content/locales/de-DE/using-your-agent.mdx +0 -7
  885. package/docs/content/locales/de-DE/voice-input.mdx +6 -0
  886. package/docs/content/locales/de-DE/workspace-connections.mdx +9 -2
  887. package/docs/content/locales/de-DE/workspace.mdx +19 -18
  888. package/docs/content/locales/es-ES/actions.mdx +2 -2
  889. package/docs/content/locales/es-ES/agent-native-toolkit.mdx +2 -2
  890. package/docs/content/locales/es-ES/agent-surfaces.mdx +8 -10
  891. package/docs/content/locales/es-ES/agent-teams.mdx +1 -0
  892. package/docs/content/locales/es-ES/authentication.mdx +1 -1
  893. package/docs/content/locales/es-ES/components.mdx +11 -1
  894. package/docs/content/locales/es-ES/creating-templates.mdx +3 -7
  895. package/docs/content/locales/es-ES/cross-app-sso.mdx +16 -6
  896. package/docs/content/locales/es-ES/deployment.mdx +8 -0
  897. package/docs/content/locales/es-ES/external-agents.mdx +3 -7
  898. package/docs/content/locales/es-ES/key-concepts.mdx +13 -20
  899. package/docs/content/locales/es-ES/multi-tenancy.mdx +5 -5
  900. package/docs/content/locales/es-ES/notifications.mdx +18 -10
  901. package/docs/content/locales/es-ES/processors.mdx +11 -5
  902. package/docs/content/locales/es-ES/server.mdx +17 -10
  903. package/docs/content/locales/es-ES/sharing.mdx +10 -10
  904. package/docs/content/locales/es-ES/skills-guide.mdx +34 -17
  905. package/docs/content/locales/es-ES/template-assets.mdx +16 -13
  906. package/docs/content/locales/es-ES/template-brain.mdx +3 -1
  907. package/docs/content/locales/es-ES/template-clips.mdx +3 -3
  908. package/docs/content/locales/es-ES/template-design.mdx +3 -1
  909. package/docs/content/locales/es-ES/template-dispatch.mdx +5 -1
  910. package/docs/content/locales/es-ES/template-mail.mdx +8 -0
  911. package/docs/content/locales/es-ES/tracking.mdx +9 -6
  912. package/docs/content/locales/es-ES/using-your-agent.mdx +0 -7
  913. package/docs/content/locales/es-ES/voice-input.mdx +6 -0
  914. package/docs/content/locales/es-ES/workspace-connections.mdx +9 -2
  915. package/docs/content/locales/es-ES/workspace.mdx +19 -18
  916. package/docs/content/locales/fr-FR/actions.mdx +2 -2
  917. package/docs/content/locales/fr-FR/agent-native-toolkit.mdx +2 -2
  918. package/docs/content/locales/fr-FR/agent-surfaces.mdx +8 -10
  919. package/docs/content/locales/fr-FR/agent-teams.mdx +1 -0
  920. package/docs/content/locales/fr-FR/authentication.mdx +1 -1
  921. package/docs/content/locales/fr-FR/components.mdx +11 -1
  922. package/docs/content/locales/fr-FR/creating-templates.mdx +3 -7
  923. package/docs/content/locales/fr-FR/cross-app-sso.mdx +16 -6
  924. package/docs/content/locales/fr-FR/deployment.mdx +8 -0
  925. package/docs/content/locales/fr-FR/external-agents.mdx +3 -7
  926. package/docs/content/locales/fr-FR/key-concepts.mdx +13 -20
  927. package/docs/content/locales/fr-FR/multi-tenancy.mdx +5 -5
  928. package/docs/content/locales/fr-FR/notifications.mdx +18 -10
  929. package/docs/content/locales/fr-FR/processors.mdx +11 -5
  930. package/docs/content/locales/fr-FR/server.mdx +17 -10
  931. package/docs/content/locales/fr-FR/sharing.mdx +10 -10
  932. package/docs/content/locales/fr-FR/skills-guide.mdx +34 -17
  933. package/docs/content/locales/fr-FR/template-assets.mdx +16 -13
  934. package/docs/content/locales/fr-FR/template-brain.mdx +3 -1
  935. package/docs/content/locales/fr-FR/template-clips.mdx +3 -3
  936. package/docs/content/locales/fr-FR/template-design.mdx +3 -1
  937. package/docs/content/locales/fr-FR/template-dispatch.mdx +5 -1
  938. package/docs/content/locales/fr-FR/template-mail.mdx +8 -0
  939. package/docs/content/locales/fr-FR/tracking.mdx +9 -6
  940. package/docs/content/locales/fr-FR/using-your-agent.mdx +0 -7
  941. package/docs/content/locales/fr-FR/voice-input.mdx +6 -0
  942. package/docs/content/locales/fr-FR/workspace-connections.mdx +9 -2
  943. package/docs/content/locales/fr-FR/workspace.mdx +19 -18
  944. package/docs/content/locales/hi-IN/actions.mdx +2 -2
  945. package/docs/content/locales/hi-IN/agent-native-toolkit.mdx +2 -2
  946. package/docs/content/locales/hi-IN/agent-surfaces.mdx +8 -10
  947. package/docs/content/locales/hi-IN/agent-teams.mdx +1 -0
  948. package/docs/content/locales/hi-IN/authentication.mdx +1 -1
  949. package/docs/content/locales/hi-IN/components.mdx +11 -1
  950. package/docs/content/locales/hi-IN/creating-templates.mdx +3 -7
  951. package/docs/content/locales/hi-IN/cross-app-sso.mdx +16 -6
  952. package/docs/content/locales/hi-IN/deployment.mdx +8 -0
  953. package/docs/content/locales/hi-IN/external-agents.mdx +2 -7
  954. package/docs/content/locales/hi-IN/key-concepts.mdx +13 -20
  955. package/docs/content/locales/hi-IN/multi-tenancy.mdx +5 -5
  956. package/docs/content/locales/hi-IN/notifications.mdx +18 -10
  957. package/docs/content/locales/hi-IN/processors.mdx +11 -5
  958. package/docs/content/locales/hi-IN/server.mdx +17 -10
  959. package/docs/content/locales/hi-IN/sharing.mdx +10 -10
  960. package/docs/content/locales/hi-IN/skills-guide.mdx +34 -17
  961. package/docs/content/locales/hi-IN/template-assets.mdx +16 -13
  962. package/docs/content/locales/hi-IN/template-brain.mdx +3 -1
  963. package/docs/content/locales/hi-IN/template-clips.mdx +3 -3
  964. package/docs/content/locales/hi-IN/template-design.mdx +3 -1
  965. package/docs/content/locales/hi-IN/template-dispatch.mdx +5 -1
  966. package/docs/content/locales/hi-IN/template-mail.mdx +8 -0
  967. package/docs/content/locales/hi-IN/tracking.mdx +9 -6
  968. package/docs/content/locales/hi-IN/using-your-agent.mdx +0 -7
  969. package/docs/content/locales/hi-IN/voice-input.mdx +6 -0
  970. package/docs/content/locales/hi-IN/workspace-connections.mdx +9 -2
  971. package/docs/content/locales/hi-IN/workspace.mdx +19 -18
  972. package/docs/content/locales/ja-JP/actions.mdx +2 -2
  973. package/docs/content/locales/ja-JP/agent-native-toolkit.mdx +2 -2
  974. package/docs/content/locales/ja-JP/agent-surfaces.mdx +8 -10
  975. package/docs/content/locales/ja-JP/agent-teams.mdx +1 -0
  976. package/docs/content/locales/ja-JP/authentication.mdx +1 -1
  977. package/docs/content/locales/ja-JP/components.mdx +11 -1
  978. package/docs/content/locales/ja-JP/creating-templates.mdx +3 -7
  979. package/docs/content/locales/ja-JP/cross-app-sso.mdx +16 -6
  980. package/docs/content/locales/ja-JP/deployment.mdx +8 -0
  981. package/docs/content/locales/ja-JP/external-agents.mdx +2 -7
  982. package/docs/content/locales/ja-JP/key-concepts.mdx +13 -20
  983. package/docs/content/locales/ja-JP/multi-tenancy.mdx +5 -5
  984. package/docs/content/locales/ja-JP/notifications.mdx +18 -10
  985. package/docs/content/locales/ja-JP/processors.mdx +11 -5
  986. package/docs/content/locales/ja-JP/server.mdx +17 -10
  987. package/docs/content/locales/ja-JP/sharing.mdx +10 -10
  988. package/docs/content/locales/ja-JP/skills-guide.mdx +34 -17
  989. package/docs/content/locales/ja-JP/template-assets.mdx +16 -13
  990. package/docs/content/locales/ja-JP/template-brain.mdx +3 -1
  991. package/docs/content/locales/ja-JP/template-clips.mdx +3 -4
  992. package/docs/content/locales/ja-JP/template-design.mdx +3 -1
  993. package/docs/content/locales/ja-JP/template-dispatch.mdx +5 -1
  994. package/docs/content/locales/ja-JP/template-mail.mdx +8 -0
  995. package/docs/content/locales/ja-JP/tracking.mdx +9 -6
  996. package/docs/content/locales/ja-JP/using-your-agent.mdx +0 -7
  997. package/docs/content/locales/ja-JP/voice-input.mdx +6 -0
  998. package/docs/content/locales/ja-JP/workspace-connections.mdx +9 -2
  999. package/docs/content/locales/ja-JP/workspace.mdx +19 -18
  1000. package/docs/content/locales/ko-KR/actions.mdx +2 -2
  1001. package/docs/content/locales/ko-KR/agent-native-toolkit.mdx +2 -2
  1002. package/docs/content/locales/ko-KR/agent-surfaces.mdx +8 -10
  1003. package/docs/content/locales/ko-KR/agent-teams.mdx +1 -0
  1004. package/docs/content/locales/ko-KR/authentication.mdx +1 -1
  1005. package/docs/content/locales/ko-KR/components.mdx +11 -1
  1006. package/docs/content/locales/ko-KR/creating-templates.mdx +3 -7
  1007. package/docs/content/locales/ko-KR/cross-app-sso.mdx +16 -6
  1008. package/docs/content/locales/ko-KR/deployment.mdx +8 -0
  1009. package/docs/content/locales/ko-KR/external-agents.mdx +2 -7
  1010. package/docs/content/locales/ko-KR/key-concepts.mdx +13 -20
  1011. package/docs/content/locales/ko-KR/multi-tenancy.mdx +5 -5
  1012. package/docs/content/locales/ko-KR/notifications.mdx +18 -10
  1013. package/docs/content/locales/ko-KR/processors.mdx +11 -5
  1014. package/docs/content/locales/ko-KR/server.mdx +17 -10
  1015. package/docs/content/locales/ko-KR/sharing.mdx +10 -10
  1016. package/docs/content/locales/ko-KR/skills-guide.mdx +34 -17
  1017. package/docs/content/locales/ko-KR/template-assets.mdx +16 -13
  1018. package/docs/content/locales/ko-KR/template-brain.mdx +3 -1
  1019. package/docs/content/locales/ko-KR/template-clips.mdx +3 -4
  1020. package/docs/content/locales/ko-KR/template-design.mdx +3 -1
  1021. package/docs/content/locales/ko-KR/template-dispatch.mdx +5 -1
  1022. package/docs/content/locales/ko-KR/template-mail.mdx +8 -0
  1023. package/docs/content/locales/ko-KR/tracking.mdx +9 -6
  1024. package/docs/content/locales/ko-KR/using-your-agent.mdx +0 -7
  1025. package/docs/content/locales/ko-KR/voice-input.mdx +6 -0
  1026. package/docs/content/locales/ko-KR/workspace-connections.mdx +9 -2
  1027. package/docs/content/locales/ko-KR/workspace.mdx +19 -18
  1028. package/docs/content/locales/pt-BR/actions.mdx +2 -2
  1029. package/docs/content/locales/pt-BR/agent-native-toolkit.mdx +2 -2
  1030. package/docs/content/locales/pt-BR/agent-surfaces.mdx +8 -10
  1031. package/docs/content/locales/pt-BR/agent-teams.mdx +1 -0
  1032. package/docs/content/locales/pt-BR/authentication.mdx +1 -1
  1033. package/docs/content/locales/pt-BR/components.mdx +11 -1
  1034. package/docs/content/locales/pt-BR/creating-templates.mdx +3 -7
  1035. package/docs/content/locales/pt-BR/cross-app-sso.mdx +16 -6
  1036. package/docs/content/locales/pt-BR/deployment.mdx +8 -0
  1037. package/docs/content/locales/pt-BR/external-agents.mdx +3 -7
  1038. package/docs/content/locales/pt-BR/key-concepts.mdx +13 -20
  1039. package/docs/content/locales/pt-BR/multi-tenancy.mdx +5 -5
  1040. package/docs/content/locales/pt-BR/notifications.mdx +18 -10
  1041. package/docs/content/locales/pt-BR/processors.mdx +11 -5
  1042. package/docs/content/locales/pt-BR/server.mdx +17 -10
  1043. package/docs/content/locales/pt-BR/sharing.mdx +10 -10
  1044. package/docs/content/locales/pt-BR/skills-guide.mdx +34 -17
  1045. package/docs/content/locales/pt-BR/template-assets.mdx +16 -13
  1046. package/docs/content/locales/pt-BR/template-brain.mdx +3 -1
  1047. package/docs/content/locales/pt-BR/template-clips.mdx +3 -3
  1048. package/docs/content/locales/pt-BR/template-design.mdx +3 -1
  1049. package/docs/content/locales/pt-BR/template-dispatch.mdx +5 -1
  1050. package/docs/content/locales/pt-BR/template-mail.mdx +8 -0
  1051. package/docs/content/locales/pt-BR/tracking.mdx +9 -6
  1052. package/docs/content/locales/pt-BR/using-your-agent.mdx +0 -7
  1053. package/docs/content/locales/pt-BR/voice-input.mdx +6 -0
  1054. package/docs/content/locales/pt-BR/workspace-connections.mdx +9 -2
  1055. package/docs/content/locales/pt-BR/workspace.mdx +19 -18
  1056. package/docs/content/locales/zh-CN/actions.mdx +2 -2
  1057. package/docs/content/locales/zh-CN/agent-native-toolkit.mdx +2 -2
  1058. package/docs/content/locales/zh-CN/agent-surfaces.mdx +8 -10
  1059. package/docs/content/locales/zh-CN/agent-teams.mdx +1 -0
  1060. package/docs/content/locales/zh-CN/authentication.mdx +1 -1
  1061. package/docs/content/locales/zh-CN/components.mdx +11 -1
  1062. package/docs/content/locales/zh-CN/creating-templates.mdx +3 -7
  1063. package/docs/content/locales/zh-CN/cross-app-sso.mdx +16 -6
  1064. package/docs/content/locales/zh-CN/deployment.mdx +8 -0
  1065. package/docs/content/locales/zh-CN/external-agents.mdx +2 -7
  1066. package/docs/content/locales/zh-CN/key-concepts.mdx +13 -20
  1067. package/docs/content/locales/zh-CN/multi-tenancy.mdx +5 -5
  1068. package/docs/content/locales/zh-CN/notifications.mdx +18 -10
  1069. package/docs/content/locales/zh-CN/processors.mdx +11 -5
  1070. package/docs/content/locales/zh-CN/server.mdx +16 -10
  1071. package/docs/content/locales/zh-CN/sharing.mdx +10 -10
  1072. package/docs/content/locales/zh-CN/skills-guide.mdx +34 -17
  1073. package/docs/content/locales/zh-CN/template-assets.mdx +16 -13
  1074. package/docs/content/locales/zh-CN/template-brain.mdx +3 -1
  1075. package/docs/content/locales/zh-CN/template-clips.mdx +3 -4
  1076. package/docs/content/locales/zh-CN/template-design.mdx +3 -1
  1077. package/docs/content/locales/zh-CN/template-dispatch.mdx +5 -1
  1078. package/docs/content/locales/zh-CN/template-mail.mdx +8 -0
  1079. package/docs/content/locales/zh-CN/tracking.mdx +9 -6
  1080. package/docs/content/locales/zh-CN/using-your-agent.mdx +0 -7
  1081. package/docs/content/locales/zh-CN/voice-input.mdx +6 -0
  1082. package/docs/content/locales/zh-CN/workspace-connections.mdx +9 -2
  1083. package/docs/content/locales/zh-CN/workspace.mdx +19 -18
  1084. package/docs/content/locales/zh-TW/actions.mdx +2 -2
  1085. package/docs/content/locales/zh-TW/agent-native-toolkit.mdx +2 -2
  1086. package/docs/content/locales/zh-TW/agent-surfaces.mdx +8 -10
  1087. package/docs/content/locales/zh-TW/agent-teams.mdx +1 -0
  1088. package/docs/content/locales/zh-TW/authentication.mdx +1 -1
  1089. package/docs/content/locales/zh-TW/components.mdx +11 -1
  1090. package/docs/content/locales/zh-TW/creating-templates.mdx +3 -7
  1091. package/docs/content/locales/zh-TW/cross-app-sso.mdx +16 -6
  1092. package/docs/content/locales/zh-TW/deployment.mdx +8 -0
  1093. package/docs/content/locales/zh-TW/external-agents.mdx +2 -7
  1094. package/docs/content/locales/zh-TW/key-concepts.mdx +13 -20
  1095. package/docs/content/locales/zh-TW/multi-tenancy.mdx +5 -5
  1096. package/docs/content/locales/zh-TW/notifications.mdx +18 -10
  1097. package/docs/content/locales/zh-TW/processors.mdx +11 -5
  1098. package/docs/content/locales/zh-TW/server.mdx +16 -10
  1099. package/docs/content/locales/zh-TW/sharing.mdx +10 -10
  1100. package/docs/content/locales/zh-TW/skills-guide.mdx +34 -17
  1101. package/docs/content/locales/zh-TW/template-assets.mdx +16 -13
  1102. package/docs/content/locales/zh-TW/template-brain.mdx +3 -1
  1103. package/docs/content/locales/zh-TW/template-clips.mdx +3 -4
  1104. package/docs/content/locales/zh-TW/template-design.mdx +3 -1
  1105. package/docs/content/locales/zh-TW/template-dispatch.mdx +5 -1
  1106. package/docs/content/locales/zh-TW/template-mail.mdx +8 -0
  1107. package/docs/content/locales/zh-TW/tracking.mdx +9 -6
  1108. package/docs/content/locales/zh-TW/using-your-agent.mdx +0 -7
  1109. package/docs/content/locales/zh-TW/voice-input.mdx +6 -0
  1110. package/docs/content/locales/zh-TW/workspace-connections.mdx +9 -2
  1111. package/docs/content/locales/zh-TW/workspace.mdx +19 -18
  1112. package/docs/content/mcp-apps.mdx +14 -32
  1113. package/docs/content/mcp-clients.mdx +48 -54
  1114. package/docs/content/mcp-protocol.mdx +25 -10
  1115. package/docs/content/messaging.mdx +19 -11
  1116. package/docs/content/multi-app-workspace.mdx +11 -96
  1117. package/docs/content/multi-tenancy.mdx +5 -5
  1118. package/docs/content/native-chat-ui.mdx +4 -4
  1119. package/docs/content/notifications.mdx +19 -12
  1120. package/docs/content/observability.mdx +2 -4
  1121. package/docs/content/observational-memory.mdx +7 -3
  1122. package/docs/content/onboarding.mdx +9 -2
  1123. package/docs/content/plan-plugin.mdx +10 -2
  1124. package/docs/content/pr-visual-recap.mdx +1 -1
  1125. package/docs/content/processors.mdx +11 -5
  1126. package/docs/content/pure-agent-apps.mdx +5 -1
  1127. package/docs/content/real-time-collaboration.mdx +30 -67
  1128. package/docs/content/recurring-jobs.mdx +8 -6
  1129. package/docs/content/routing.mdx +3 -4
  1130. package/docs/content/sandbox-adapters.mdx +30 -53
  1131. package/docs/content/security.mdx +8 -0
  1132. package/docs/content/server.mdx +17 -10
  1133. package/docs/content/sharing.mdx +10 -10
  1134. package/docs/content/skills-guide.mdx +35 -16
  1135. package/docs/content/template-analytics.mdx +11 -8
  1136. package/docs/content/template-assets.mdx +16 -13
  1137. package/docs/content/template-brain.mdx +3 -1
  1138. package/docs/content/template-calendar.mdx +12 -4
  1139. package/docs/content/template-chat.mdx +4 -4
  1140. package/docs/content/template-clips.mdx +3 -3
  1141. package/docs/content/template-content.mdx +23 -18
  1142. package/docs/content/template-design.mdx +3 -1
  1143. package/docs/content/template-dispatch.mdx +5 -1
  1144. package/docs/content/template-mail.mdx +14 -2
  1145. package/docs/content/template-plan.mdx +22 -15
  1146. package/docs/content/template-slides.mdx +11 -3
  1147. package/docs/content/toolkit-agent-ux.mdx +46 -3
  1148. package/docs/content/toolkit-collaboration.mdx +58 -4
  1149. package/docs/content/toolkit-command-navigation.mdx +8 -2
  1150. package/docs/content/toolkit-comments-review.mdx +10 -2
  1151. package/docs/content/toolkit-history.mdx +8 -3
  1152. package/docs/content/toolkit-observability.mdx +48 -2
  1153. package/docs/content/toolkit-org-team.mdx +8 -2
  1154. package/docs/content/toolkit-resources.mdx +45 -2
  1155. package/docs/content/toolkit-settings.mdx +8 -2
  1156. package/docs/content/toolkit-setup-connections.mdx +7 -2
  1157. package/docs/content/toolkit-sharing.mdx +46 -3
  1158. package/docs/content/toolkit-ui.mdx +82 -11
  1159. package/docs/content/tracking.mdx +10 -8
  1160. package/docs/content/using-your-agent.mdx +0 -12
  1161. package/docs/content/voice-input.mdx +7 -1
  1162. package/docs/content/what-is-agent-native.mdx +7 -8
  1163. package/docs/content/workspace-connections.mdx +16 -23
  1164. package/docs/content/workspace-management.mdx +16 -4
  1165. package/docs/content/workspace.mdx +19 -18
  1166. package/package.json +1 -1
  1167. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +39 -5
  1168. package/corpus/core/docs/content/locales/ar-SA/migration-workbench.mdx +0 -76
  1169. package/corpus/core/docs/content/locales/de-DE/migration-workbench.mdx +0 -76
  1170. package/corpus/core/docs/content/locales/es-ES/migration-workbench.mdx +0 -76
  1171. package/corpus/core/docs/content/locales/fr-FR/migration-workbench.mdx +0 -76
  1172. package/corpus/core/docs/content/locales/hi-IN/migration-workbench.mdx +0 -74
  1173. package/corpus/core/docs/content/locales/ja-JP/migration-workbench.mdx +0 -76
  1174. package/corpus/core/docs/content/locales/ko-KR/migration-workbench.mdx +0 -74
  1175. package/corpus/core/docs/content/locales/pt-BR/migration-workbench.mdx +0 -76
  1176. package/corpus/core/docs/content/locales/zh-CN/migration-workbench.mdx +0 -74
  1177. package/corpus/core/docs/content/locales/zh-TW/migration-workbench.mdx +0 -74
  1178. package/corpus/core/docs/content/migration-workbench.mdx +0 -74
  1179. package/corpus/core/docs/content/toolkit-app-adapters.mdx +0 -55
  1180. package/corpus/core/docs/content/toolkit-collaboration-ui.mdx +0 -60
  1181. package/corpus/core/docs/content/toolkit-sharing-ui.mdx +0 -45
  1182. package/corpus/core/docs/content/toolkit-shell-hooks.mdx +0 -36
  1183. package/docs/content/locales/ar-SA/migration-workbench.mdx +0 -76
  1184. package/docs/content/locales/de-DE/migration-workbench.mdx +0 -76
  1185. package/docs/content/locales/es-ES/migration-workbench.mdx +0 -76
  1186. package/docs/content/locales/fr-FR/migration-workbench.mdx +0 -76
  1187. package/docs/content/locales/hi-IN/migration-workbench.mdx +0 -74
  1188. package/docs/content/locales/ja-JP/migration-workbench.mdx +0 -76
  1189. package/docs/content/locales/ko-KR/migration-workbench.mdx +0 -74
  1190. package/docs/content/locales/pt-BR/migration-workbench.mdx +0 -76
  1191. package/docs/content/locales/zh-CN/migration-workbench.mdx +0 -74
  1192. package/docs/content/locales/zh-TW/migration-workbench.mdx +0 -74
  1193. package/docs/content/migration-workbench.mdx +0 -74
  1194. package/docs/content/toolkit-app-adapters.mdx +0 -55
  1195. package/docs/content/toolkit-collaboration-ui.mdx +0 -60
  1196. package/docs/content/toolkit-sharing-ui.mdx +0 -45
  1197. package/docs/content/toolkit-shell-hooks.mdx +0 -36
@@ -1 +1 @@
1
- {"version":3,"file":"background-controller.js","sourceRoot":"","sources":["../../src/code-agents/background-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n executeExistingCodeAgentRun,\n executePendingCodeAgentApproval,\n} from \"../cli/code-agent-executor.js\";\nimport {\n appendCodeAgentTranscriptEvent,\n getCodeAgentRunRecord,\n isActiveCodeAgentRun,\n queueCodeAgentFollowUp,\n updateCodeAgentRunRecord,\n type CodeAgentFollowUpMode,\n type CodeAgentPermissionMode,\n} from \"../cli/code-agent-runs.js\";\nimport type { ReasoningEffort } from \"../shared/reasoning-effort.js\";\nimport {\n getBackgroundAgentRun,\n listBackgroundAgentRuns,\n listBackgroundAgentTranscriptEvents,\n toBackgroundAgentRun,\n type BackgroundAgentRun,\n type BackgroundAgentTranscriptEvent,\n type ListBackgroundAgentRunsOptions,\n} from \"./background-run.js\";\nimport type { AgentPromptAttachment } from \"./prompt-attachments.js\";\n\nexport type BackgroundAgentControlCommand =\n | \"approve\"\n | \"resume\"\n | \"retry\"\n | \"stop\";\n\nexport interface BackgroundAgentControlInput {\n runId: string;\n command: BackgroundAgentControlCommand;\n stdout?: NodeJS.WritableStream;\n}\n\nexport interface BackgroundAgentFollowUpInput {\n runId: string;\n prompt: string;\n mode?: CodeAgentFollowUpMode;\n permissionMode?: CodeAgentPermissionMode;\n model?: string;\n reasoningEffort?: ReasoningEffort;\n source?: string;\n metadata?: Record<string, unknown>;\n stdout?: NodeJS.WritableStream;\n}\n\nexport interface BackgroundAgentControlResult {\n ok: boolean;\n runId: string;\n run: BackgroundAgentRun | null;\n queued?: boolean;\n message?: string;\n error?: string;\n}\n\nexport interface BackgroundAgentController {\n list(\n options?: ListBackgroundAgentRunsOptions,\n ): Promise<BackgroundAgentRun[]> | BackgroundAgentRun[];\n get(\n runId: string,\n ): Promise<BackgroundAgentRun | null> | BackgroundAgentRun | null;\n transcript(\n runId: string,\n ):\n | Promise<BackgroundAgentTranscriptEvent[]>\n | BackgroundAgentTranscriptEvent[];\n sendFollowUp(\n input: BackgroundAgentFollowUpInput,\n ): Promise<BackgroundAgentControlResult>;\n control(\n input: BackgroundAgentControlInput,\n ): Promise<BackgroundAgentControlResult>;\n}\n\nexport function createCompositeBackgroundAgentController(\n controllers: BackgroundAgentController[],\n): BackgroundAgentController {\n const resolveControllerForRun = async (\n runId: string,\n ): Promise<{\n controller: BackgroundAgentController;\n run: BackgroundAgentRun;\n } | null> => {\n for (const controller of controllers) {\n const run = await Promise.resolve(controller.get(runId));\n if (run) return { controller, run };\n }\n return null;\n };\n\n return {\n async list(options?: ListBackgroundAgentRunsOptions) {\n const groups = await Promise.all(\n controllers.map((controller) =>\n Promise.resolve(controller.list(options)).catch(() => []),\n ),\n );\n return groups\n .flat()\n .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));\n },\n async get(runId: string) {\n return (await resolveControllerForRun(runId))?.run ?? null;\n },\n async transcript(runId: string) {\n const match = await resolveControllerForRun(runId);\n if (!match) return [];\n return Promise.resolve(match.controller.transcript(runId));\n },\n async sendFollowUp(input: BackgroundAgentFollowUpInput) {\n const match = await resolveControllerForRun(input.runId);\n if (!match) return missingRunResult(input.runId);\n return match.controller.sendFollowUp(input);\n },\n async control(input: BackgroundAgentControlInput) {\n const match = await resolveControllerForRun(input.runId);\n if (!match) return missingRunResult(input.runId);\n return match.controller.control(input);\n },\n };\n}\n\nexport function createLocalCodeBackgroundAgentController(): BackgroundAgentController {\n return {\n list: listBackgroundAgentRuns,\n get: getBackgroundAgentRun,\n transcript: listBackgroundAgentTranscriptEvents,\n sendFollowUp: sendLocalCodeBackgroundAgentFollowUp,\n control: controlLocalCodeBackgroundAgentRun,\n };\n}\n\nexport const localCodeBackgroundAgentController =\n createLocalCodeBackgroundAgentController();\n\nasync function sendLocalCodeBackgroundAgentFollowUp(\n input: BackgroundAgentFollowUpInput,\n): Promise<BackgroundAgentControlResult> {\n const run = getCodeAgentRunRecord(input.runId);\n if (!run) {\n return missingRunResult(input.runId);\n }\n\n const prompt = input.prompt.trim();\n if (!prompt) {\n return {\n ok: false,\n runId: input.runId,\n run: toBackgroundAgentRun(run),\n error: \"Follow-up prompt is required.\",\n };\n }\n\n const activeRun = input.permissionMode\n ? (updateCodeAgentRunRecord(run.id, {\n permissionMode: input.permissionMode,\n }) ?? run)\n : run;\n const mode = input.mode ?? \"immediate\";\n const shouldQueue =\n activeRun.status === \"queued\" || isActiveCodeAgentRun(activeRun);\n const event = appendCodeAgentTranscriptEvent({\n runId: activeRun.id,\n kind: \"user\",\n message: prompt,\n metadata: {\n ...(input.metadata ?? {}),\n source: input.source ?? \"background-agent-controller\",\n permissionMode: input.permissionMode,\n followUpMode: mode,\n delivery: shouldQueue ? mode : \"run-now\",\n },\n });\n const attachments = promptAttachmentsFromMetadata(\n input.metadata?.attachments,\n );\n\n if (shouldQueue) {\n queueCodeAgentFollowUp({\n runId: activeRun.id,\n prompt,\n mode,\n eventId: event.id,\n permissionMode: input.permissionMode,\n source: input.source ?? \"background-agent-controller\",\n createdAt: event.createdAt,\n attachments,\n });\n return {\n ok: true,\n runId: activeRun.id,\n run: currentBackgroundRun(activeRun.id),\n queued: true,\n message: \"Follow-up queued for the active Agent-Native Code run.\",\n };\n }\n\n const updated = await executeExistingCodeAgentRun(activeRun.id, {\n prompt,\n appendUserEvent: false,\n model: input.model,\n reasoningEffort: input.reasoningEffort,\n attachments,\n stdout: input.stdout,\n });\n return {\n ok: Boolean(updated),\n runId: activeRun.id,\n run: updated\n ? toBackgroundAgentRun(updated)\n : currentBackgroundRun(activeRun.id),\n queued: false,\n message: updated\n ? \"Follow-up executed for the Agent-Native Code run.\"\n : undefined,\n error: updated ? undefined : `Run not found: ${activeRun.id}`,\n };\n}\n\nasync function controlLocalCodeBackgroundAgentRun(\n input: BackgroundAgentControlInput,\n): Promise<BackgroundAgentControlResult> {\n const run = getCodeAgentRunRecord(input.runId);\n if (!run) {\n return missingRunResult(input.runId);\n }\n\n switch (input.command) {\n case \"approve\": {\n const approved = await executePendingCodeAgentApproval(run.id, {\n stdout: input.stdout,\n });\n return {\n ok: Boolean(approved),\n runId: run.id,\n run: approved\n ? toBackgroundAgentRun(approved)\n : currentBackgroundRun(run.id),\n message: approved\n ? \"Pending approval executed for the Agent-Native Code run.\"\n : undefined,\n error: approved ? undefined : `Run not found: ${run.id}`,\n };\n }\n case \"resume\":\n case \"retry\": {\n // A control action must return immediately — awaiting\n // executeExistingCodeAgentRun() runs the entire code session\n // (potentially minutes), which times out the HTTP/IPC caller.\n // Kick the run off in the background; progress is surfaced via the\n // transcript/poll, exactly like the initial run start.\n void executeExistingCodeAgentRun(run.id, {\n stdout: input.stdout,\n }).catch((err) => {\n appendCodeAgentTranscriptEvent({\n runId: run.id,\n kind: \"status\",\n message: `Background ${input.command} failed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n metadata: {\n source: \"background-agent-controller\",\n command: input.command,\n failed: true,\n },\n });\n });\n return {\n ok: true,\n runId: run.id,\n run: currentBackgroundRun(run.id),\n message:\n input.command === \"resume\"\n ? \"Agent-Native Code run resuming in the background.\"\n : \"Agent-Native Code run retrying in the background.\",\n };\n }\n case \"stop\":\n return stopLocalCodeBackgroundAgentRun(run.id);\n default: {\n const exhaustive: never = input.command;\n return {\n ok: false,\n runId: run.id,\n run: currentBackgroundRun(run.id),\n error: `Unsupported control command: ${String(exhaustive)}`,\n };\n }\n }\n}\n\nfunction stopLocalCodeBackgroundAgentRun(\n runId: string,\n): BackgroundAgentControlResult {\n const run = getCodeAgentRunRecord(runId);\n if (!run) {\n return missingRunResult(runId);\n }\n\n if (run.status === \"completed\" || run.status === \"errored\") {\n return {\n ok: true,\n runId,\n run: toBackgroundAgentRun(run),\n message: \"Agent-Native Code run is already finished.\",\n };\n }\n\n appendCodeAgentTranscriptEvent({\n runId,\n kind: \"status\",\n message:\n \"Stop requested for Agent-Native Code run. No process signal was sent.\",\n metadata: {\n source: \"background-agent-controller\",\n stoppedWithoutSignal: true,\n },\n });\n const updated = updateCodeAgentRunRecord(runId, {\n status: \"paused\",\n phase: \"stopped\",\n progress: {\n label: \"Stopped\",\n completed: 0,\n total: 1,\n percent: 0,\n },\n metadata: {\n runnerState: \"stopped\",\n stoppedAt: new Date().toISOString(),\n stoppedBy: \"background-agent-controller\",\n stopSignalSent: false,\n },\n });\n\n return {\n ok: Boolean(updated),\n runId,\n run: updated ? toBackgroundAgentRun(updated) : null,\n message: updated\n ? \"Agent-Native Code run marked stopped without signaling a process.\"\n : undefined,\n error: updated ? undefined : `Run not found: ${runId}`,\n };\n}\n\nfunction promptAttachmentsFromMetadata(\n value: unknown,\n): AgentPromptAttachment[] {\n if (!Array.isArray(value)) return [];\n return value\n .filter((item): item is Record<string, unknown> =>\n Boolean(item && typeof item === \"object\" && !Array.isArray(item)),\n )\n .map((item) => ({\n name: typeof item.name === \"string\" && item.name ? item.name : \"file\",\n ...(typeof item.type === \"string\" ? { type: item.type } : {}),\n ...(typeof item.size === \"number\" ? { size: item.size } : {}),\n ...(typeof item.text === \"string\" ? { text: item.text } : {}),\n ...(typeof item.dataUrl === \"string\" ? { dataUrl: item.dataUrl } : {}),\n }));\n}\n\nfunction currentBackgroundRun(runId: string): BackgroundAgentRun | null {\n const run = getCodeAgentRunRecord(runId);\n return run ? toBackgroundAgentRun(run) : null;\n}\n\nfunction missingRunResult(runId: string): BackgroundAgentControlResult {\n return {\n ok: false,\n runId,\n run: null,\n error: `Run not found: ${runId}`,\n };\n}\n"]}
1
+ {"version":3,"file":"background-controller.js","sourceRoot":"","sources":["../../src/code-agents/background-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n executeDenyCodeAgentApproval,\n executeExistingCodeAgentRun,\n executePendingCodeAgentApproval,\n} from \"../cli/code-agent-executor.js\";\nimport {\n appendCodeAgentTranscriptEvent,\n getCodeAgentRunRecord,\n isActiveCodeAgentRun,\n queueCodeAgentFollowUp,\n updateCodeAgentRunRecord,\n type CodeAgentFollowUpMode,\n type CodeAgentPermissionMode,\n} from \"../cli/code-agent-runs.js\";\nimport type { ReasoningEffort } from \"../shared/reasoning-effort.js\";\nimport {\n getBackgroundAgentRun,\n listBackgroundAgentRuns,\n listBackgroundAgentTranscriptEvents,\n toBackgroundAgentRun,\n type BackgroundAgentRun,\n type BackgroundAgentTranscriptEvent,\n type ListBackgroundAgentRunsOptions,\n} from \"./background-run.js\";\nimport type { AgentPromptAttachment } from \"./prompt-attachments.js\";\n\nexport type BackgroundAgentControlCommand =\n | \"approve\"\n | \"deny\"\n | \"resume\"\n | \"retry\"\n | \"stop\";\n\nexport interface BackgroundAgentControlInput {\n runId: string;\n command: BackgroundAgentControlCommand;\n stdout?: NodeJS.WritableStream;\n}\n\nexport interface BackgroundAgentFollowUpInput {\n runId: string;\n prompt: string;\n mode?: CodeAgentFollowUpMode;\n permissionMode?: CodeAgentPermissionMode;\n model?: string;\n reasoningEffort?: ReasoningEffort;\n source?: string;\n metadata?: Record<string, unknown>;\n stdout?: NodeJS.WritableStream;\n}\n\nexport interface BackgroundAgentControlResult {\n ok: boolean;\n runId: string;\n run: BackgroundAgentRun | null;\n queued?: boolean;\n message?: string;\n error?: string;\n}\n\nexport interface BackgroundAgentController {\n list(\n options?: ListBackgroundAgentRunsOptions,\n ): Promise<BackgroundAgentRun[]> | BackgroundAgentRun[];\n get(\n runId: string,\n ): Promise<BackgroundAgentRun | null> | BackgroundAgentRun | null;\n transcript(\n runId: string,\n ):\n | Promise<BackgroundAgentTranscriptEvent[]>\n | BackgroundAgentTranscriptEvent[];\n sendFollowUp(\n input: BackgroundAgentFollowUpInput,\n ): Promise<BackgroundAgentControlResult>;\n control(\n input: BackgroundAgentControlInput,\n ): Promise<BackgroundAgentControlResult>;\n}\n\nexport function createCompositeBackgroundAgentController(\n controllers: BackgroundAgentController[],\n): BackgroundAgentController {\n const resolveControllerForRun = async (\n runId: string,\n ): Promise<{\n controller: BackgroundAgentController;\n run: BackgroundAgentRun;\n } | null> => {\n for (const controller of controllers) {\n const run = await Promise.resolve(controller.get(runId));\n if (run) return { controller, run };\n }\n return null;\n };\n\n return {\n async list(options?: ListBackgroundAgentRunsOptions) {\n const groups = await Promise.all(\n controllers.map((controller) =>\n Promise.resolve(controller.list(options)).catch(() => []),\n ),\n );\n return groups\n .flat()\n .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));\n },\n async get(runId: string) {\n return (await resolveControllerForRun(runId))?.run ?? null;\n },\n async transcript(runId: string) {\n const match = await resolveControllerForRun(runId);\n if (!match) return [];\n return Promise.resolve(match.controller.transcript(runId));\n },\n async sendFollowUp(input: BackgroundAgentFollowUpInput) {\n const match = await resolveControllerForRun(input.runId);\n if (!match) return missingRunResult(input.runId);\n return match.controller.sendFollowUp(input);\n },\n async control(input: BackgroundAgentControlInput) {\n const match = await resolveControllerForRun(input.runId);\n if (!match) return missingRunResult(input.runId);\n return match.controller.control(input);\n },\n };\n}\n\nexport function createLocalCodeBackgroundAgentController(): BackgroundAgentController {\n return {\n list: listBackgroundAgentRuns,\n get: getBackgroundAgentRun,\n transcript: listBackgroundAgentTranscriptEvents,\n sendFollowUp: sendLocalCodeBackgroundAgentFollowUp,\n control: controlLocalCodeBackgroundAgentRun,\n };\n}\n\nexport const localCodeBackgroundAgentController =\n createLocalCodeBackgroundAgentController();\n\nasync function sendLocalCodeBackgroundAgentFollowUp(\n input: BackgroundAgentFollowUpInput,\n): Promise<BackgroundAgentControlResult> {\n const run = getCodeAgentRunRecord(input.runId);\n if (!run) {\n return missingRunResult(input.runId);\n }\n\n const prompt = input.prompt.trim();\n if (!prompt) {\n return {\n ok: false,\n runId: input.runId,\n run: toBackgroundAgentRun(run),\n error: \"Follow-up prompt is required.\",\n };\n }\n\n const activeRun = input.permissionMode\n ? (updateCodeAgentRunRecord(run.id, {\n permissionMode: input.permissionMode,\n }) ?? run)\n : run;\n const mode = input.mode ?? \"immediate\";\n const shouldQueue =\n activeRun.status === \"queued\" || isActiveCodeAgentRun(activeRun);\n const event = appendCodeAgentTranscriptEvent({\n runId: activeRun.id,\n kind: \"user\",\n message: prompt,\n metadata: {\n ...(input.metadata ?? {}),\n source: input.source ?? \"background-agent-controller\",\n permissionMode: input.permissionMode,\n followUpMode: mode,\n delivery: shouldQueue ? mode : \"run-now\",\n },\n });\n const attachments = promptAttachmentsFromMetadata(\n input.metadata?.attachments,\n );\n\n if (shouldQueue) {\n queueCodeAgentFollowUp({\n runId: activeRun.id,\n prompt,\n mode,\n eventId: event.id,\n permissionMode: input.permissionMode,\n source: input.source ?? \"background-agent-controller\",\n createdAt: event.createdAt,\n attachments,\n });\n return {\n ok: true,\n runId: activeRun.id,\n run: currentBackgroundRun(activeRun.id),\n queued: true,\n message: \"Follow-up queued for the active Agent-Native Code run.\",\n };\n }\n\n const updated = await executeExistingCodeAgentRun(activeRun.id, {\n prompt,\n appendUserEvent: false,\n model: input.model,\n reasoningEffort: input.reasoningEffort,\n attachments,\n stdout: input.stdout,\n });\n return {\n ok: Boolean(updated),\n runId: activeRun.id,\n run: updated\n ? toBackgroundAgentRun(updated)\n : currentBackgroundRun(activeRun.id),\n queued: false,\n message: updated\n ? \"Follow-up executed for the Agent-Native Code run.\"\n : undefined,\n error: updated ? undefined : `Run not found: ${activeRun.id}`,\n };\n}\n\nasync function controlLocalCodeBackgroundAgentRun(\n input: BackgroundAgentControlInput,\n): Promise<BackgroundAgentControlResult> {\n const run = getCodeAgentRunRecord(input.runId);\n if (!run) {\n return missingRunResult(input.runId);\n }\n\n switch (input.command) {\n case \"approve\": {\n const approved = await executePendingCodeAgentApproval(run.id, {\n stdout: input.stdout,\n });\n return {\n ok: Boolean(approved),\n runId: run.id,\n run: approved\n ? toBackgroundAgentRun(approved)\n : currentBackgroundRun(run.id),\n message: approved\n ? \"Pending approval executed for the Agent-Native Code run.\"\n : undefined,\n error: approved ? undefined : `Run not found: ${run.id}`,\n };\n }\n case \"deny\": {\n const denied = await executeDenyCodeAgentApproval(run.id, {\n stdout: input.stdout,\n });\n return {\n ok: Boolean(denied),\n runId: run.id,\n run: denied\n ? toBackgroundAgentRun(denied)\n : currentBackgroundRun(run.id),\n message: denied\n ? \"Pending approval denied for the Agent-Native Code run.\"\n : undefined,\n error: denied ? undefined : `Run not found: ${run.id}`,\n };\n }\n case \"resume\":\n case \"retry\": {\n // A control action must return immediately — awaiting\n // executeExistingCodeAgentRun() runs the entire code session\n // (potentially minutes), which times out the HTTP/IPC caller.\n // Kick the run off in the background; progress is surfaced via the\n // transcript/poll, exactly like the initial run start.\n void executeExistingCodeAgentRun(run.id, {\n stdout: input.stdout,\n }).catch((err) => {\n appendCodeAgentTranscriptEvent({\n runId: run.id,\n kind: \"status\",\n message: `Background ${input.command} failed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n metadata: {\n source: \"background-agent-controller\",\n command: input.command,\n failed: true,\n },\n });\n });\n return {\n ok: true,\n runId: run.id,\n run: currentBackgroundRun(run.id),\n message:\n input.command === \"resume\"\n ? \"Agent-Native Code run resuming in the background.\"\n : \"Agent-Native Code run retrying in the background.\",\n };\n }\n case \"stop\":\n return stopLocalCodeBackgroundAgentRun(run.id);\n default: {\n const exhaustive: never = input.command;\n return {\n ok: false,\n runId: run.id,\n run: currentBackgroundRun(run.id),\n error: `Unsupported control command: ${String(exhaustive)}`,\n };\n }\n }\n}\n\nfunction stopLocalCodeBackgroundAgentRun(\n runId: string,\n): BackgroundAgentControlResult {\n const run = getCodeAgentRunRecord(runId);\n if (!run) {\n return missingRunResult(runId);\n }\n\n if (run.status === \"completed\" || run.status === \"errored\") {\n return {\n ok: true,\n runId,\n run: toBackgroundAgentRun(run),\n message: \"Agent-Native Code run is already finished.\",\n };\n }\n\n appendCodeAgentTranscriptEvent({\n runId,\n kind: \"status\",\n message:\n \"Stop requested for Agent-Native Code run. No process signal was sent.\",\n metadata: {\n source: \"background-agent-controller\",\n stoppedWithoutSignal: true,\n },\n });\n const updated = updateCodeAgentRunRecord(runId, {\n status: \"paused\",\n phase: \"stopped\",\n progress: {\n label: \"Stopped\",\n completed: 0,\n total: 1,\n percent: 0,\n },\n metadata: {\n runnerState: \"stopped\",\n stoppedAt: new Date().toISOString(),\n stoppedBy: \"background-agent-controller\",\n stopSignalSent: false,\n },\n });\n\n return {\n ok: Boolean(updated),\n runId,\n run: updated ? toBackgroundAgentRun(updated) : null,\n message: updated\n ? \"Agent-Native Code run marked stopped without signaling a process.\"\n : undefined,\n error: updated ? undefined : `Run not found: ${runId}`,\n };\n}\n\nfunction promptAttachmentsFromMetadata(\n value: unknown,\n): AgentPromptAttachment[] {\n if (!Array.isArray(value)) return [];\n return value\n .filter((item): item is Record<string, unknown> =>\n Boolean(item && typeof item === \"object\" && !Array.isArray(item)),\n )\n .map((item) => ({\n name: typeof item.name === \"string\" && item.name ? item.name : \"file\",\n ...(typeof item.type === \"string\" ? { type: item.type } : {}),\n ...(typeof item.size === \"number\" ? { size: item.size } : {}),\n ...(typeof item.text === \"string\" ? { text: item.text } : {}),\n ...(typeof item.dataUrl === \"string\" ? { dataUrl: item.dataUrl } : {}),\n }));\n}\n\nfunction currentBackgroundRun(runId: string): BackgroundAgentRun | null {\n const run = getCodeAgentRunRecord(runId);\n return run ? toBackgroundAgentRun(run) : null;\n}\n\nfunction missingRunResult(runId: string): BackgroundAgentControlResult {\n return {\n ok: false,\n runId,\n run: null,\n error: `Run not found: ${runId}`,\n };\n}\n"]}
@@ -13,8 +13,8 @@
13
13
  * Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
14
14
  */
15
15
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
- ok?: undefined;
17
16
  error: string;
17
+ ok?: undefined;
18
18
  } | {
19
19
  error?: undefined;
20
20
  ok: boolean;
@@ -41,7 +41,15 @@ export declare function applyUpdate(docId: string, update: Uint8Array, requestSo
41
41
  *
42
42
  * Returns the text snapshot after the update.
43
43
  */
44
- export declare function applyText(docId: string, newText: string, fieldName?: string, requestSource?: string): Promise<string>;
44
+ export declare function applyText(docId: string, newText: string, fieldName?: string, requestSource?: string, options?: {
45
+ /**
46
+ * Validate the fully converged text after cross-process Yjs updates have
47
+ * merged, but before the state is persisted or broadcast. A rejected
48
+ * candidate is discarded from this process's cache so the next read
49
+ * reloads the last durable state instead of leaking an uncommitted merge.
50
+ */
51
+ validateSnapshot?: (snapshot: string) => void;
52
+ }): Promise<string>;
45
53
  /**
46
54
  * Search-and-replace text within a Y.XmlFragment (ProseMirror tree).
47
55
  * Produces minimal Yjs operations for cursor-preserving updates.
@@ -1 +1 @@
1
- {"version":3,"file":"ydoc-manager.d.ts","sourceRoot":"","sources":["../../src/collab/ydoc-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAGzB,OAAO,EAKL,KAAK,OAAO,EACb,MAAM,kBAAkB,CAAC;AAmC1B;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,CAqBnD;AAuHD;;GAEG;AACH,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAoC1D;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,UAAU,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAsB,EACjC,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC,CAoBjB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC,CAkCjD;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAsB,GAChC,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAGjE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,UAAU,GAC5B,OAAO,CAAC,UAAU,CAAC,CAGrB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,MAAsB,GAChC,OAAO,CAAC,IAAI,CAAC,CAYf;AAID;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,GAAG,EACZ,SAAS,GAAE,MAAe,EAC1B,KAAK,GAAE,KAAK,GAAG,OAAe,EAC9B,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,OAAO,EAAE,EACd,SAAS,GAAE,MAAe,EAC1B,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAe,GACzB,OAAO,CAAC,GAAG,CAAC,CAGd;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,GAAG,EACT,SAAS,GAAE,MAAe,EAC1B,IAAI,GAAE,KAAK,GAAG,OAAe,GAC5B,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAM9C"}
1
+ {"version":3,"file":"ydoc-manager.d.ts","sourceRoot":"","sources":["../../src/collab/ydoc-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAGzB,OAAO,EAKL,KAAK,OAAO,EACb,MAAM,kBAAkB,CAAC;AAmC1B;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,CAqBnD;AA4HD;;GAEG;AACH,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAoC1D;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,UAAU,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAsB,EACjC,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,GAAE;IACP;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C,GACL,OAAO,CAAC,MAAM,CAAC,CAyCjB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC,CAkCjD;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAsB,GAChC,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAGjE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,UAAU,GAC5B,OAAO,CAAC,UAAU,CAAC,CAGrB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,MAAsB,GAChC,OAAO,CAAC,IAAI,CAAC,CAYf;AAID;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,GAAG,EACZ,SAAS,GAAE,MAAe,EAC1B,KAAK,GAAE,KAAK,GAAG,OAAe,EAC9B,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,OAAO,EAAE,EACd,SAAS,GAAE,MAAe,EAC1B,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAe,GACzB,OAAO,CAAC,GAAG,CAAC,CAGd;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,GAAG,EACT,SAAS,GAAE,MAAe,EAC1B,IAAI,GAAE,KAAK,GAAG,OAAe,GAC5B,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAM9C"}
@@ -137,7 +137,7 @@ function buildStateToStore(doc, storedByteCount) {
137
137
  * from OTHER processes. Within this process, the in-memory doc is already
138
138
  * up-to-date because mutations are serialized by withDocWriteLock.
139
139
  */
140
- async function persistMergedState(docId, doc, getTextSnapshot) {
140
+ async function persistMergedState(docId, doc, getTextSnapshot, validateTextSnapshot) {
141
141
  for (let attempt = 0; attempt < 5; attempt++) {
142
142
  // One DB read per persist attempt. On first attempt this is the only read
143
143
  // on the write path (previously there was an unconditional second read
@@ -148,12 +148,16 @@ async function persistMergedState(docId, doc, getTextSnapshot) {
148
148
  Y.applyUpdate(doc, latest.state);
149
149
  }
150
150
  const stateToStore = buildStateToStore(doc, latest?.state?.length ?? 0);
151
- const saved = await trySaveYDocState(docId, stateToStore, getTextSnapshot(), latest?.version ?? null);
151
+ const textSnapshot = getTextSnapshot();
152
+ validateTextSnapshot?.(textSnapshot);
153
+ const saved = await trySaveYDocState(docId, stateToStore, textSnapshot, latest?.version ?? null);
152
154
  if (saved)
153
155
  return;
154
156
  }
155
157
  // All CAS attempts failed — fall back to unconditional save.
156
- await saveYDocState(docId, Y.encodeStateAsUpdate(doc), getTextSnapshot());
158
+ const textSnapshot = getTextSnapshot();
159
+ validateTextSnapshot?.(textSnapshot);
160
+ await saveYDocState(docId, Y.encodeStateAsUpdate(doc), textSnapshot);
157
161
  }
158
162
  /**
159
163
  * Get or load a Yjs document by ID. Creates a new empty doc if none exists.
@@ -213,15 +217,35 @@ export async function applyUpdate(docId, update, requestSource) {
213
217
  *
214
218
  * Returns the text snapshot after the update.
215
219
  */
216
- export async function applyText(docId, newText, fieldName = DEFAULT_FIELD, requestSource) {
220
+ export async function applyText(docId, newText, fieldName = DEFAULT_FIELD, requestSource, options = {}) {
217
221
  return withDocWriteLock(docId, async () => {
218
222
  const doc = await getDoc(docId);
219
223
  const oldText = doc.getText(fieldName).toString();
220
224
  const update = applyTextToYDoc(doc, fieldName, newText, "server");
221
225
  if (update.length === 0) {
222
- return doc.getText(fieldName).toString();
226
+ const snapshot = doc.getText(fieldName).toString();
227
+ try {
228
+ options.validateSnapshot?.(snapshot);
229
+ }
230
+ catch (error) {
231
+ releaseDoc(docId);
232
+ throw error;
233
+ }
234
+ return snapshot;
235
+ }
236
+ try {
237
+ await persistMergedState(docId, doc, () => doc.getText(fieldName).toString(), options.validateSnapshot);
238
+ }
239
+ catch (error) {
240
+ if (options.validateSnapshot) {
241
+ // The target diff and any cross-process state merged during the CAS
242
+ // read now live only in this cached Y.Doc. Destroy it before throwing:
243
+ // neither the rejected update nor a compensating rollback should ever
244
+ // be persisted/emitted to connected clients.
245
+ releaseDoc(docId);
246
+ }
247
+ throw error;
223
248
  }
224
- await persistMergedState(docId, doc, () => doc.getText(fieldName).toString());
225
249
  emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);
226
250
  touchAgentPresence(docId, requestSource, {
227
251
  descriptor: computeTextEditDescriptor(oldText, newText),
@@ -1 +1 @@
1
- {"version":3,"file":"ydoc-manager.js","sourceRoot":"","sources":["../../src/collab/ydoc-manager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Server-side Yjs document manager with LRU caching and SQL persistence.\n *\n * Performance notes:\n * - `getDoc()` loads from the DB once on cache miss; subsequent calls return\n * the cached Y.Doc directly with no DB I/O.\n * - Mutations no longer call `applyStoredState()` unconditionally on every\n * write. The defensive re-read from the DB happens only inside\n * `persistMergedState` (needed for the CAS version read), not as a\n * separate SELECT before applying the new update. This removes the\n * redundant double-read that the previous implementation performed on\n * every write even on a hot cache.\n * - Compaction: when the stored blob is >4x the freshly encoded state, the\n * GC'd encoding is stored instead (removes accumulated Yjs tombstones,\n * preventing unbounded blob growth without any background jobs).\n */\n\nimport * as Y from \"yjs\";\n\nimport { emitCollabUpdate } from \"./emitter.js\";\nimport {\n applyJsonDiff,\n applyJsonPatch,\n yDocToJson,\n initYDocWithJson,\n type PatchOp,\n} from \"./json-to-yjs.js\";\nimport {\n loadYDocRecord,\n loadYDocState,\n saveYDocState,\n trySaveYDocState,\n} from \"./storage.js\";\nimport { uint8ArrayToBase64 } from \"./storage.js\";\nimport { applyTextToYDoc, initYDocWithText } from \"./text-to-yjs.js\";\nimport { searchAndReplaceInYXml, extractTextFromYXml } from \"./xml-ops.js\";\n\nconst DEFAULT_FIELD = \"content\";\nconst MAX_CACHE = 50;\n\n/**\n * Auto-presence: any agent-sourced write produces visible presence and\n * lingering edit attribution without the calling action having to wire\n * agentEnterDocument/agentLeaveDocument itself. Dynamic import avoids a\n * static cycle (agent-presence.ts imports searchAndReplace from this module).\n */\nfunction touchAgentPresence(\n docId: string,\n requestSource: string | undefined,\n edit: { descriptor: Record<string, unknown>; label?: string } | null,\n): void {\n if (requestSource !== \"agent\") return;\n import(\"./agent-presence.js\")\n .then((mod) => {\n mod.agentTouchDocument(docId, edit ? { edit: edit as any } : undefined);\n })\n .catch(() => {\n // Presence is best-effort; never fail the write for it.\n });\n}\n\n/**\n * Compute a small \"what changed\" descriptor from a text diff by trimming the\n * common prefix/suffix. Used for lingering edit highlights client-side.\n */\nexport function computeTextEditDescriptor(\n oldText: string,\n newText: string,\n): { kind: \"text\"; quote: string } | { kind: \"doc\" } {\n let start = 0;\n const maxStart = Math.min(oldText.length, newText.length);\n while (start < maxStart && oldText[start] === newText[start]) start++;\n\n let endOld = oldText.length;\n let endNew = newText.length;\n while (\n endOld > start &&\n endNew > start &&\n oldText[endOld - 1] === newText[endNew - 1]\n ) {\n endOld--;\n endNew--;\n }\n\n const inserted = newText.slice(start, endNew).trim();\n if (inserted.length > 0) {\n return { kind: \"text\", quote: inserted.slice(0, 120) };\n }\n return { kind: \"doc\" };\n}\n\n/**\n * Compaction ratio threshold. When the stored state byte count exceeds\n * COMPACTION_RATIO × the freshly encoded state, write the compact form\n * (strips accumulated tombstones). A value of 4 means: compact when the\n * stored blob is 4× larger than necessary.\n */\nconst COMPACTION_RATIO = 4;\n\ninterface CacheEntry {\n doc: Y.Doc;\n lastAccess: number;\n}\n\nconst _cache = new Map<string, CacheEntry>();\nconst _writeLocks = new Map<string, Promise<void>>();\n// Coalesces concurrent cache-miss loads for the same docId. Without this, two\n// simultaneous getDoc() callers both miss the cache, both build a Y.Doc and\n// apply stored state, and the second _cache.set silently orphans the first\n// doc (a memory leak that grows with concurrent read traffic).\nconst _loadLocks = new Map<string, Promise<Y.Doc>>();\n\nfunction evictIfNeeded(): void {\n if (_cache.size <= MAX_CACHE) return;\n // Evict least-recently-accessed entry\n let oldest: string | null = null;\n let oldestTime = Infinity;\n for (const [id, entry] of _cache) {\n if (entry.lastAccess < oldestTime) {\n oldestTime = entry.lastAccess;\n oldest = id;\n }\n }\n if (oldest) {\n const entry = _cache.get(oldest);\n entry?.doc.destroy();\n _cache.delete(oldest);\n }\n}\n\nasync function withDocWriteLock<T>(\n docId: string,\n fn: () => Promise<T>,\n): Promise<T> {\n const previous = _writeLocks.get(docId) ?? Promise.resolve();\n let release!: () => void;\n const current = new Promise<void>((resolve) => {\n release = resolve;\n });\n const chained = previous.catch(() => {}).then(() => current);\n _writeLocks.set(docId, chained);\n\n await previous.catch(() => {});\n try {\n return await fn();\n } finally {\n release();\n if (_writeLocks.get(docId) === chained) {\n _writeLocks.delete(docId);\n }\n }\n}\n\n/**\n * Build state to persist. If the stored blob is significantly larger than\n * the freshly encoded state, store the compact (GC'd) form instead to\n * prevent unbounded blob growth from accumulated tombstones.\n */\nfunction buildStateToStore(doc: Y.Doc, storedByteCount: number): Uint8Array {\n const encoded = Y.encodeStateAsUpdate(doc);\n if (\n storedByteCount > 0 &&\n storedByteCount > encoded.length * COMPACTION_RATIO\n ) {\n // Stored blob is much larger than needed — return the GC'd encoding.\n return encoded;\n }\n return encoded;\n}\n\n/**\n * Persist the merged doc state with CAS retry on conflict.\n *\n * REMOVED: the unconditional `applyStoredState()` that was called on every\n * write path before this function. The only DB read is the `loadYDocRecord`\n * call here — needed to get the CAS version and merge any concurrent writes\n * from OTHER processes. Within this process, the in-memory doc is already\n * up-to-date because mutations are serialized by withDocWriteLock.\n */\nasync function persistMergedState(\n docId: string,\n doc: Y.Doc,\n getTextSnapshot: () => string,\n): Promise<void> {\n for (let attempt = 0; attempt < 5; attempt++) {\n // One DB read per persist attempt. On first attempt this is the only read\n // on the write path (previously there was an unconditional second read\n // before the update was applied). On retry attempts it re-reads to get the\n // latest version after a CAS conflict.\n const latest = await loadYDocRecord(docId);\n if (latest?.state && latest.state.length > 0) {\n Y.applyUpdate(doc, latest.state);\n }\n\n const stateToStore = buildStateToStore(doc, latest?.state?.length ?? 0);\n const saved = await trySaveYDocState(\n docId,\n stateToStore,\n getTextSnapshot(),\n latest?.version ?? null,\n );\n if (saved) return;\n }\n\n // All CAS attempts failed — fall back to unconditional save.\n await saveYDocState(docId, Y.encodeStateAsUpdate(doc), getTextSnapshot());\n}\n\n/**\n * Get or load a Yjs document by ID. Creates a new empty doc if none exists.\n */\nexport async function getDoc(docId: string): Promise<Y.Doc> {\n const cached = _cache.get(docId);\n if (cached) {\n cached.lastAccess = Date.now();\n return cached.doc;\n }\n\n const inFlight = _loadLocks.get(docId);\n if (inFlight) return inFlight;\n\n const load = (async () => {\n // Re-check the cache: a concurrent writer (or loader) may have populated it\n // between our miss above and acquiring this load slot.\n const reCached = _cache.get(docId);\n if (reCached) {\n reCached.lastAccess = Date.now();\n return reCached.doc;\n }\n\n const doc = new Y.Doc();\n const stored = await loadYDocState(docId);\n if (stored && stored.length > 0) {\n Y.applyUpdate(doc, stored);\n }\n\n evictIfNeeded();\n _cache.set(docId, { doc, lastAccess: Date.now() });\n return doc;\n })();\n\n _loadLocks.set(docId, load);\n try {\n return await load;\n } finally {\n _loadLocks.delete(docId);\n }\n}\n\n/**\n * Apply a binary Yjs update (from a client) to a document.\n * Persists the result and emits a change event.\n */\nexport async function applyUpdate(\n docId: string,\n update: Uint8Array,\n requestSource?: string,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n // The cached doc is already up-to-date from the initial load or a previous\n // write in this process. No redundant applyStoredState() here — cross-\n // process writes are merged inside persistMergedState when needed.\n Y.applyUpdate(doc, update);\n\n await persistMergedState(docId, doc, () =>\n doc.getText(DEFAULT_FIELD).toString(),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n });\n}\n\n/**\n * Apply a text change to a document. Computes the minimal diff and\n * converts it to Yjs operations.\n *\n * Returns the text snapshot after the update.\n */\nexport async function applyText(\n docId: string,\n newText: string,\n fieldName: string = DEFAULT_FIELD,\n requestSource?: string,\n): Promise<string> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n const oldText = doc.getText(fieldName).toString();\n const update = applyTextToYDoc(doc, fieldName, newText, \"server\");\n\n if (update.length === 0) {\n return doc.getText(fieldName).toString();\n }\n\n await persistMergedState(docId, doc, () =>\n doc.getText(fieldName).toString(),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n touchAgentPresence(docId, requestSource, {\n descriptor: computeTextEditDescriptor(oldText, newText),\n });\n return doc.getText(fieldName).toString();\n });\n}\n\n/**\n * Search-and-replace text within a Y.XmlFragment (ProseMirror tree).\n * Produces minimal Yjs operations for cursor-preserving updates.\n *\n * Returns whether the text was found and the binary update.\n */\nexport async function searchAndReplace(\n docId: string,\n find: string,\n replace: string,\n requestSource?: string,\n): Promise<{ found: boolean; update: Uint8Array }> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n const fragment = doc.getXmlFragment(\"default\");\n\n // Capture the update produced by the transaction\n let update: Uint8Array = new Uint8Array(0);\n const handler = (u: Uint8Array) => {\n update = u;\n };\n doc.on(\"update\", handler);\n\n let found = false;\n doc.transact(() => {\n found = searchAndReplaceInYXml(fragment, find, replace);\n }, \"agent\");\n\n doc.off(\"update\", handler);\n\n if (!found || update.length === 0) {\n return { found: false, update: new Uint8Array(0) };\n }\n\n await persistMergedState(docId, doc, () => extractTextFromYXml(fragment));\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n touchAgentPresence(docId, requestSource, {\n descriptor: {\n kind: \"text\",\n quote: (replace || find).slice(0, 120),\n },\n });\n\n return { found: true, update };\n });\n}\n\n/**\n * Get the current text content of a document field.\n */\nexport async function getText(\n docId: string,\n fieldName: string = DEFAULT_FIELD,\n): Promise<string> {\n const doc = await getDoc(docId);\n return doc.getText(fieldName).toString();\n}\n\n/**\n * Get the full document state as a Uint8Array.\n */\nexport async function getState(docId: string): Promise<Uint8Array> {\n const doc = await getDoc(docId);\n return Y.encodeStateAsUpdate(doc);\n}\n\n/**\n * Get an incremental update relative to a client's state vector.\n */\nexport async function getIncUpdate(\n docId: string,\n clientStateVector: Uint8Array,\n): Promise<Uint8Array> {\n const doc = await getDoc(docId);\n return Y.encodeStateAsUpdate(doc, clientStateVector);\n}\n\n/**\n * Seed a document from existing text content (for migration).\n * Only seeds if no collab state exists yet.\n */\nexport async function seedFromText(\n docId: string,\n text: string,\n fieldName: string = DEFAULT_FIELD,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const existing = await loadYDocState(docId);\n if (existing && existing.length > 0) return; // Already seeded\n\n const { doc, state } = initYDocWithText(fieldName, text);\n await saveYDocState(docId, state, text);\n\n // Cache the doc\n evictIfNeeded();\n _cache.set(docId, { doc, lastAccess: Date.now() });\n });\n}\n\n// ─── Structured JSON Operations ─────────────────────────────────────\n\n/**\n * Apply a full JSON update to a document. Computes the minimal diff\n * and converts it to Yjs operations on Y.Map/Y.Array.\n */\nexport async function applyJson(\n docId: string,\n newJson: any,\n fieldName: string = \"data\",\n _type: \"map\" | \"array\" = \"map\",\n requestSource?: string,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n const update = applyJsonDiff(doc, fieldName, newJson, \"server\");\n\n if (update.length === 0) return;\n\n // Snapshot the doc's actual post-merge state, not the caller-supplied\n // `newJson` — persistMergedState may re-apply newer DB state to resolve\n // concurrent writes, so `newJson` can be stale. Matches applyPatchOps.\n await persistMergedState(docId, doc, () =>\n JSON.stringify(yDocToJson(doc, fieldName)),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n touchAgentPresence(docId, requestSource, { descriptor: { kind: \"doc\" } });\n });\n}\n\n/**\n * Apply surgical JSON patch operations to a document.\n */\nexport async function applyPatchOps(\n docId: string,\n ops: PatchOp[],\n fieldName: string = \"data\",\n requestSource?: string,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n const update = applyJsonPatch(doc, fieldName, ops, \"server\");\n\n if (update.length === 0) return;\n\n await persistMergedState(docId, doc, () =>\n JSON.stringify(yDocToJson(doc, fieldName)),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n touchAgentPresence(docId, requestSource, {\n descriptor: {\n kind: \"paths\",\n paths: ops.slice(0, 5).map((op) => op.path),\n },\n });\n });\n}\n\n/**\n * Get the current JSON state of a document field.\n */\nexport async function getJson(\n docId: string,\n fieldName: string = \"data\",\n): Promise<any> {\n const doc = await getDoc(docId);\n return yDocToJson(doc, fieldName);\n}\n\n/**\n * Seed a document from existing JSON content (for migration).\n * Only seeds if no collab state exists yet.\n */\nexport async function seedFromJson(\n docId: string,\n json: any,\n fieldName: string = \"data\",\n type: \"map\" | \"array\" = \"map\",\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const existing = await loadYDocState(docId);\n if (existing && existing.length > 0) return; // Already seeded\n\n const { doc, state } = initYDocWithJson(fieldName, json, type);\n await saveYDocState(docId, state, JSON.stringify(json));\n\n // Cache the doc\n evictIfNeeded();\n _cache.set(docId, { doc, lastAccess: Date.now() });\n });\n}\n\n/**\n * Release a document from the in-memory cache.\n */\nexport function releaseDoc(docId: string): void {\n const entry = _cache.get(docId);\n if (entry) {\n entry.doc.destroy();\n _cache.delete(docId);\n }\n}\n"]}
1
+ {"version":3,"file":"ydoc-manager.js","sourceRoot":"","sources":["../../src/collab/ydoc-manager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Server-side Yjs document manager with LRU caching and SQL persistence.\n *\n * Performance notes:\n * - `getDoc()` loads from the DB once on cache miss; subsequent calls return\n * the cached Y.Doc directly with no DB I/O.\n * - Mutations no longer call `applyStoredState()` unconditionally on every\n * write. The defensive re-read from the DB happens only inside\n * `persistMergedState` (needed for the CAS version read), not as a\n * separate SELECT before applying the new update. This removes the\n * redundant double-read that the previous implementation performed on\n * every write even on a hot cache.\n * - Compaction: when the stored blob is >4x the freshly encoded state, the\n * GC'd encoding is stored instead (removes accumulated Yjs tombstones,\n * preventing unbounded blob growth without any background jobs).\n */\n\nimport * as Y from \"yjs\";\n\nimport { emitCollabUpdate } from \"./emitter.js\";\nimport {\n applyJsonDiff,\n applyJsonPatch,\n yDocToJson,\n initYDocWithJson,\n type PatchOp,\n} from \"./json-to-yjs.js\";\nimport {\n loadYDocRecord,\n loadYDocState,\n saveYDocState,\n trySaveYDocState,\n} from \"./storage.js\";\nimport { uint8ArrayToBase64 } from \"./storage.js\";\nimport { applyTextToYDoc, initYDocWithText } from \"./text-to-yjs.js\";\nimport { searchAndReplaceInYXml, extractTextFromYXml } from \"./xml-ops.js\";\n\nconst DEFAULT_FIELD = \"content\";\nconst MAX_CACHE = 50;\n\n/**\n * Auto-presence: any agent-sourced write produces visible presence and\n * lingering edit attribution without the calling action having to wire\n * agentEnterDocument/agentLeaveDocument itself. Dynamic import avoids a\n * static cycle (agent-presence.ts imports searchAndReplace from this module).\n */\nfunction touchAgentPresence(\n docId: string,\n requestSource: string | undefined,\n edit: { descriptor: Record<string, unknown>; label?: string } | null,\n): void {\n if (requestSource !== \"agent\") return;\n import(\"./agent-presence.js\")\n .then((mod) => {\n mod.agentTouchDocument(docId, edit ? { edit: edit as any } : undefined);\n })\n .catch(() => {\n // Presence is best-effort; never fail the write for it.\n });\n}\n\n/**\n * Compute a small \"what changed\" descriptor from a text diff by trimming the\n * common prefix/suffix. Used for lingering edit highlights client-side.\n */\nexport function computeTextEditDescriptor(\n oldText: string,\n newText: string,\n): { kind: \"text\"; quote: string } | { kind: \"doc\" } {\n let start = 0;\n const maxStart = Math.min(oldText.length, newText.length);\n while (start < maxStart && oldText[start] === newText[start]) start++;\n\n let endOld = oldText.length;\n let endNew = newText.length;\n while (\n endOld > start &&\n endNew > start &&\n oldText[endOld - 1] === newText[endNew - 1]\n ) {\n endOld--;\n endNew--;\n }\n\n const inserted = newText.slice(start, endNew).trim();\n if (inserted.length > 0) {\n return { kind: \"text\", quote: inserted.slice(0, 120) };\n }\n return { kind: \"doc\" };\n}\n\n/**\n * Compaction ratio threshold. When the stored state byte count exceeds\n * COMPACTION_RATIO × the freshly encoded state, write the compact form\n * (strips accumulated tombstones). A value of 4 means: compact when the\n * stored blob is 4× larger than necessary.\n */\nconst COMPACTION_RATIO = 4;\n\ninterface CacheEntry {\n doc: Y.Doc;\n lastAccess: number;\n}\n\nconst _cache = new Map<string, CacheEntry>();\nconst _writeLocks = new Map<string, Promise<void>>();\n// Coalesces concurrent cache-miss loads for the same docId. Without this, two\n// simultaneous getDoc() callers both miss the cache, both build a Y.Doc and\n// apply stored state, and the second _cache.set silently orphans the first\n// doc (a memory leak that grows with concurrent read traffic).\nconst _loadLocks = new Map<string, Promise<Y.Doc>>();\n\nfunction evictIfNeeded(): void {\n if (_cache.size <= MAX_CACHE) return;\n // Evict least-recently-accessed entry\n let oldest: string | null = null;\n let oldestTime = Infinity;\n for (const [id, entry] of _cache) {\n if (entry.lastAccess < oldestTime) {\n oldestTime = entry.lastAccess;\n oldest = id;\n }\n }\n if (oldest) {\n const entry = _cache.get(oldest);\n entry?.doc.destroy();\n _cache.delete(oldest);\n }\n}\n\nasync function withDocWriteLock<T>(\n docId: string,\n fn: () => Promise<T>,\n): Promise<T> {\n const previous = _writeLocks.get(docId) ?? Promise.resolve();\n let release!: () => void;\n const current = new Promise<void>((resolve) => {\n release = resolve;\n });\n const chained = previous.catch(() => {}).then(() => current);\n _writeLocks.set(docId, chained);\n\n await previous.catch(() => {});\n try {\n return await fn();\n } finally {\n release();\n if (_writeLocks.get(docId) === chained) {\n _writeLocks.delete(docId);\n }\n }\n}\n\n/**\n * Build state to persist. If the stored blob is significantly larger than\n * the freshly encoded state, store the compact (GC'd) form instead to\n * prevent unbounded blob growth from accumulated tombstones.\n */\nfunction buildStateToStore(doc: Y.Doc, storedByteCount: number): Uint8Array {\n const encoded = Y.encodeStateAsUpdate(doc);\n if (\n storedByteCount > 0 &&\n storedByteCount > encoded.length * COMPACTION_RATIO\n ) {\n // Stored blob is much larger than needed — return the GC'd encoding.\n return encoded;\n }\n return encoded;\n}\n\n/**\n * Persist the merged doc state with CAS retry on conflict.\n *\n * REMOVED: the unconditional `applyStoredState()` that was called on every\n * write path before this function. The only DB read is the `loadYDocRecord`\n * call here — needed to get the CAS version and merge any concurrent writes\n * from OTHER processes. Within this process, the in-memory doc is already\n * up-to-date because mutations are serialized by withDocWriteLock.\n */\nasync function persistMergedState(\n docId: string,\n doc: Y.Doc,\n getTextSnapshot: () => string,\n validateTextSnapshot?: (snapshot: string) => void,\n): Promise<void> {\n for (let attempt = 0; attempt < 5; attempt++) {\n // One DB read per persist attempt. On first attempt this is the only read\n // on the write path (previously there was an unconditional second read\n // before the update was applied). On retry attempts it re-reads to get the\n // latest version after a CAS conflict.\n const latest = await loadYDocRecord(docId);\n if (latest?.state && latest.state.length > 0) {\n Y.applyUpdate(doc, latest.state);\n }\n\n const stateToStore = buildStateToStore(doc, latest?.state?.length ?? 0);\n const textSnapshot = getTextSnapshot();\n validateTextSnapshot?.(textSnapshot);\n const saved = await trySaveYDocState(\n docId,\n stateToStore,\n textSnapshot,\n latest?.version ?? null,\n );\n if (saved) return;\n }\n\n // All CAS attempts failed — fall back to unconditional save.\n const textSnapshot = getTextSnapshot();\n validateTextSnapshot?.(textSnapshot);\n await saveYDocState(docId, Y.encodeStateAsUpdate(doc), textSnapshot);\n}\n\n/**\n * Get or load a Yjs document by ID. Creates a new empty doc if none exists.\n */\nexport async function getDoc(docId: string): Promise<Y.Doc> {\n const cached = _cache.get(docId);\n if (cached) {\n cached.lastAccess = Date.now();\n return cached.doc;\n }\n\n const inFlight = _loadLocks.get(docId);\n if (inFlight) return inFlight;\n\n const load = (async () => {\n // Re-check the cache: a concurrent writer (or loader) may have populated it\n // between our miss above and acquiring this load slot.\n const reCached = _cache.get(docId);\n if (reCached) {\n reCached.lastAccess = Date.now();\n return reCached.doc;\n }\n\n const doc = new Y.Doc();\n const stored = await loadYDocState(docId);\n if (stored && stored.length > 0) {\n Y.applyUpdate(doc, stored);\n }\n\n evictIfNeeded();\n _cache.set(docId, { doc, lastAccess: Date.now() });\n return doc;\n })();\n\n _loadLocks.set(docId, load);\n try {\n return await load;\n } finally {\n _loadLocks.delete(docId);\n }\n}\n\n/**\n * Apply a binary Yjs update (from a client) to a document.\n * Persists the result and emits a change event.\n */\nexport async function applyUpdate(\n docId: string,\n update: Uint8Array,\n requestSource?: string,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n // The cached doc is already up-to-date from the initial load or a previous\n // write in this process. No redundant applyStoredState() here — cross-\n // process writes are merged inside persistMergedState when needed.\n Y.applyUpdate(doc, update);\n\n await persistMergedState(docId, doc, () =>\n doc.getText(DEFAULT_FIELD).toString(),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n });\n}\n\n/**\n * Apply a text change to a document. Computes the minimal diff and\n * converts it to Yjs operations.\n *\n * Returns the text snapshot after the update.\n */\nexport async function applyText(\n docId: string,\n newText: string,\n fieldName: string = DEFAULT_FIELD,\n requestSource?: string,\n options: {\n /**\n * Validate the fully converged text after cross-process Yjs updates have\n * merged, but before the state is persisted or broadcast. A rejected\n * candidate is discarded from this process's cache so the next read\n * reloads the last durable state instead of leaking an uncommitted merge.\n */\n validateSnapshot?: (snapshot: string) => void;\n } = {},\n): Promise<string> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n const oldText = doc.getText(fieldName).toString();\n const update = applyTextToYDoc(doc, fieldName, newText, \"server\");\n\n if (update.length === 0) {\n const snapshot = doc.getText(fieldName).toString();\n try {\n options.validateSnapshot?.(snapshot);\n } catch (error) {\n releaseDoc(docId);\n throw error;\n }\n return snapshot;\n }\n\n try {\n await persistMergedState(\n docId,\n doc,\n () => doc.getText(fieldName).toString(),\n options.validateSnapshot,\n );\n } catch (error) {\n if (options.validateSnapshot) {\n // The target diff and any cross-process state merged during the CAS\n // read now live only in this cached Y.Doc. Destroy it before throwing:\n // neither the rejected update nor a compensating rollback should ever\n // be persisted/emitted to connected clients.\n releaseDoc(docId);\n }\n throw error;\n }\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n touchAgentPresence(docId, requestSource, {\n descriptor: computeTextEditDescriptor(oldText, newText),\n });\n return doc.getText(fieldName).toString();\n });\n}\n\n/**\n * Search-and-replace text within a Y.XmlFragment (ProseMirror tree).\n * Produces minimal Yjs operations for cursor-preserving updates.\n *\n * Returns whether the text was found and the binary update.\n */\nexport async function searchAndReplace(\n docId: string,\n find: string,\n replace: string,\n requestSource?: string,\n): Promise<{ found: boolean; update: Uint8Array }> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n const fragment = doc.getXmlFragment(\"default\");\n\n // Capture the update produced by the transaction\n let update: Uint8Array = new Uint8Array(0);\n const handler = (u: Uint8Array) => {\n update = u;\n };\n doc.on(\"update\", handler);\n\n let found = false;\n doc.transact(() => {\n found = searchAndReplaceInYXml(fragment, find, replace);\n }, \"agent\");\n\n doc.off(\"update\", handler);\n\n if (!found || update.length === 0) {\n return { found: false, update: new Uint8Array(0) };\n }\n\n await persistMergedState(docId, doc, () => extractTextFromYXml(fragment));\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n touchAgentPresence(docId, requestSource, {\n descriptor: {\n kind: \"text\",\n quote: (replace || find).slice(0, 120),\n },\n });\n\n return { found: true, update };\n });\n}\n\n/**\n * Get the current text content of a document field.\n */\nexport async function getText(\n docId: string,\n fieldName: string = DEFAULT_FIELD,\n): Promise<string> {\n const doc = await getDoc(docId);\n return doc.getText(fieldName).toString();\n}\n\n/**\n * Get the full document state as a Uint8Array.\n */\nexport async function getState(docId: string): Promise<Uint8Array> {\n const doc = await getDoc(docId);\n return Y.encodeStateAsUpdate(doc);\n}\n\n/**\n * Get an incremental update relative to a client's state vector.\n */\nexport async function getIncUpdate(\n docId: string,\n clientStateVector: Uint8Array,\n): Promise<Uint8Array> {\n const doc = await getDoc(docId);\n return Y.encodeStateAsUpdate(doc, clientStateVector);\n}\n\n/**\n * Seed a document from existing text content (for migration).\n * Only seeds if no collab state exists yet.\n */\nexport async function seedFromText(\n docId: string,\n text: string,\n fieldName: string = DEFAULT_FIELD,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const existing = await loadYDocState(docId);\n if (existing && existing.length > 0) return; // Already seeded\n\n const { doc, state } = initYDocWithText(fieldName, text);\n await saveYDocState(docId, state, text);\n\n // Cache the doc\n evictIfNeeded();\n _cache.set(docId, { doc, lastAccess: Date.now() });\n });\n}\n\n// ─── Structured JSON Operations ─────────────────────────────────────\n\n/**\n * Apply a full JSON update to a document. Computes the minimal diff\n * and converts it to Yjs operations on Y.Map/Y.Array.\n */\nexport async function applyJson(\n docId: string,\n newJson: any,\n fieldName: string = \"data\",\n _type: \"map\" | \"array\" = \"map\",\n requestSource?: string,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n const update = applyJsonDiff(doc, fieldName, newJson, \"server\");\n\n if (update.length === 0) return;\n\n // Snapshot the doc's actual post-merge state, not the caller-supplied\n // `newJson` — persistMergedState may re-apply newer DB state to resolve\n // concurrent writes, so `newJson` can be stale. Matches applyPatchOps.\n await persistMergedState(docId, doc, () =>\n JSON.stringify(yDocToJson(doc, fieldName)),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n touchAgentPresence(docId, requestSource, { descriptor: { kind: \"doc\" } });\n });\n}\n\n/**\n * Apply surgical JSON patch operations to a document.\n */\nexport async function applyPatchOps(\n docId: string,\n ops: PatchOp[],\n fieldName: string = \"data\",\n requestSource?: string,\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const doc = await getDoc(docId);\n const update = applyJsonPatch(doc, fieldName, ops, \"server\");\n\n if (update.length === 0) return;\n\n await persistMergedState(docId, doc, () =>\n JSON.stringify(yDocToJson(doc, fieldName)),\n );\n\n emitCollabUpdate(docId, uint8ArrayToBase64(update), requestSource);\n touchAgentPresence(docId, requestSource, {\n descriptor: {\n kind: \"paths\",\n paths: ops.slice(0, 5).map((op) => op.path),\n },\n });\n });\n}\n\n/**\n * Get the current JSON state of a document field.\n */\nexport async function getJson(\n docId: string,\n fieldName: string = \"data\",\n): Promise<any> {\n const doc = await getDoc(docId);\n return yDocToJson(doc, fieldName);\n}\n\n/**\n * Seed a document from existing JSON content (for migration).\n * Only seeds if no collab state exists yet.\n */\nexport async function seedFromJson(\n docId: string,\n json: any,\n fieldName: string = \"data\",\n type: \"map\" | \"array\" = \"map\",\n): Promise<void> {\n return withDocWriteLock(docId, async () => {\n const existing = await loadYDocState(docId);\n if (existing && existing.length > 0) return; // Already seeded\n\n const { doc, state } = initYDocWithJson(fieldName, json, type);\n await saveYDocState(docId, state, JSON.stringify(json));\n\n // Cache the doc\n evictIfNeeded();\n _cache.set(docId, { doc, lastAccess: Date.now() });\n });\n}\n\n/**\n * Release a document from the in-memory cache.\n */\nexport function releaseDoc(docId: string): void {\n const entry = _cache.get(docId);\n if (entry) {\n entry.doc.destroy();\n _cache.delete(docId);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/db/migrations.ts"],"names":[],"mappings":"AA8DA,KAAK,cAAc,GAAG,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AA4B9D;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAK5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CASvD;AAmDD,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;;;;;OAYG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,YAAY,CAAC;IAClB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,KAAK,CAAC,cAAc,CAAC,EACjC,OAAO,EAAE,oBAAoB,GAC5B,cAAc,CAmYhB"}
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/db/migrations.ts"],"names":[],"mappings":"AA2EA,KAAK,cAAc,GAAG,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AA4B9D;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAK5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CASvD;AAmDD,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;;;;;OAYG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,YAAY,CAAC;IAClB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,KAAK,CAAC,cAAc,CAAC,EACjC,OAAO,EAAE,oBAAoB,GAC5B,cAAc,CAsYhB"}
@@ -1,4 +1,4 @@
1
- import { getDbExec, createDbExec, isPostgres, getDialect, getMigrationDatabaseUrl, retrySqliteBusy, } from "./client.js";
1
+ import { getDbExec, createDbExec, isPostgres, getDialect, getMigrationDatabaseUrl, getCloudflareD1Binding, retrySqliteBusy, } from "./client.js";
2
2
  // ---------------------------------------------------------------------------
3
3
  // Shared direct-endpoint exec across concurrent migration runners per boot.
4
4
  //
@@ -244,7 +244,9 @@ export function runMigrations(migrations, options) {
244
244
  return async () => {
245
245
  try {
246
246
  // Check for Cloudflare D1 binding (only if DATABASE_URL not set)
247
- const d1 = getDialect() === "d1" ? globalThis.__cf_env?.DB : null;
247
+ const d1 = getDialect() === "d1"
248
+ ? getCloudflareD1Binding()
249
+ : null;
248
250
  if (d1) {
249
251
  await d1
250
252
  .prepare(`CREATE TABLE IF NOT EXISTS ${table} (version INTEGER PRIMARY KEY)`)
@@ -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 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"]}
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 getCloudflareD1Binding,\n retrySqliteBusy,\n type DbExec,\n} from \"./client.js\";\n\ninterface D1PreparedStatementLike {\n bind(...values: unknown[]): D1PreparedStatementLike;\n all(): Promise<{ results: Record<string, unknown>[] }>;\n first<T = Record<string, unknown>>(): Promise<T | null>;\n run(): Promise<unknown>;\n}\n\ninterface D1DatabaseLike {\n prepare(query: string): D1PreparedStatementLike;\n batch(statements: D1PreparedStatementLike[]): Promise<unknown>;\n}\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 =\n getDialect() === \"d1\"\n ? (getCloudflareD1Binding() as D1DatabaseLike | undefined)\n : 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"]}