convex 1.34.0 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (607) hide show
  1. package/CHANGELOG.md +98 -43
  2. package/dist/browser.bundle.js +13 -10
  3. package/dist/browser.bundle.js.map +3 -3
  4. package/dist/cjs/browser/index-node.js +3 -1
  5. package/dist/cjs/browser/index.js +3 -1
  6. package/dist/cjs/browser/index.js.map +2 -2
  7. package/dist/cjs/browser/query_options.js.map +2 -2
  8. package/dist/cjs/browser/sync/authentication_manager.js +4 -1
  9. package/dist/cjs/browser/sync/authentication_manager.js.map +2 -2
  10. package/dist/cjs/browser/sync/web_socket_manager.js +1 -7
  11. package/dist/cjs/browser/sync/web_socket_manager.js.map +2 -2
  12. package/dist/cjs/cli/aiFiles.js +39 -20
  13. package/dist/cjs/cli/aiFiles.js.map +3 -3
  14. package/dist/cjs/cli/codegen_templates/readme.js +14 -1
  15. package/dist/cjs/cli/codegen_templates/readme.js.map +2 -2
  16. package/dist/cjs/cli/configure.js +34 -32
  17. package/dist/cjs/cli/configure.js.map +2 -2
  18. package/dist/cjs/cli/deploy.js +7 -8
  19. package/dist/cjs/cli/deploy.js.map +2 -2
  20. package/dist/cjs/cli/deploymentCreate.js +225 -40
  21. package/dist/cjs/cli/deploymentCreate.js.map +3 -3
  22. package/dist/cjs/cli/deploymentSelect.js +14 -13
  23. package/dist/cjs/cli/deploymentSelect.js.map +2 -2
  24. package/dist/cjs/cli/dev.js +30 -11
  25. package/dist/cjs/cli/dev.js.map +2 -2
  26. package/dist/cjs/cli/docs.js +1 -1
  27. package/dist/cjs/cli/docs.js.map +2 -2
  28. package/dist/cjs/cli/init.js +1 -1
  29. package/dist/cjs/cli/init.js.map +2 -2
  30. package/dist/cjs/cli/lib/aiFiles/agentsmd.js +73 -0
  31. package/dist/cjs/cli/lib/aiFiles/agentsmd.js.map +7 -0
  32. package/dist/cjs/cli/lib/aiFiles/claudemd.js +73 -0
  33. package/dist/cjs/cli/lib/aiFiles/claudemd.js.map +7 -0
  34. package/dist/cjs/cli/lib/aiFiles/cursorrules.js +48 -0
  35. package/dist/cjs/cli/lib/aiFiles/cursorrules.js.map +7 -0
  36. package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js +58 -0
  37. package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js.map +7 -0
  38. package/dist/cjs/cli/lib/aiFiles/index.js +215 -0
  39. package/dist/cjs/cli/lib/aiFiles/index.js.map +7 -0
  40. package/dist/cjs/cli/lib/aiFiles/paths.js.map +7 -0
  41. package/dist/cjs/cli/lib/aiFiles/skills.js +196 -0
  42. package/dist/cjs/cli/lib/aiFiles/skills.js.map +7 -0
  43. package/dist/cjs/cli/lib/aiFiles/state.js +96 -0
  44. package/dist/cjs/cli/lib/aiFiles/state.js.map +7 -0
  45. package/dist/cjs/cli/lib/aiFiles/status.js +198 -0
  46. package/dist/cjs/cli/lib/aiFiles/status.js.map +7 -0
  47. package/dist/cjs/cli/lib/aiFiles/utils.js +128 -0
  48. package/dist/cjs/cli/lib/aiFiles/utils.js.map +7 -0
  49. package/dist/cjs/cli/lib/api.js +70 -7
  50. package/dist/cjs/cli/lib/api.js.map +2 -2
  51. package/dist/cjs/cli/lib/command.js +10 -6
  52. package/dist/cjs/cli/lib/command.js.map +2 -2
  53. package/dist/cjs/cli/lib/config.js +43 -7
  54. package/dist/cjs/cli/lib/config.js.map +3 -3
  55. package/dist/cjs/cli/lib/deploy2.js +9 -26
  56. package/dist/cjs/cli/lib/deploy2.js.map +2 -2
  57. package/dist/cjs/cli/lib/deployApi/componentDefinition.js +4 -1
  58. package/dist/cjs/cli/lib/deployApi/componentDefinition.js.map +2 -2
  59. package/dist/cjs/cli/lib/deploymentSelection.js +45 -2
  60. package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
  61. package/dist/cjs/cli/lib/deploymentSelector.js +1 -0
  62. package/dist/cjs/cli/lib/deploymentSelector.js.map +2 -2
  63. package/dist/cjs/cli/lib/dev.js +162 -117
  64. package/dist/cjs/cli/lib/dev.js.map +2 -2
  65. package/dist/cjs/cli/lib/env.js +1 -13
  66. package/dist/cjs/cli/lib/env.js.map +2 -2
  67. package/dist/cjs/cli/lib/expiration.js +104 -0
  68. package/dist/cjs/cli/lib/expiration.js.map +7 -0
  69. package/dist/cjs/cli/lib/generatedFunctionLogsApi.js.map +1 -1
  70. package/dist/cjs/cli/lib/init.js +4 -3
  71. package/dist/cjs/cli/lib/init.js.map +2 -2
  72. package/dist/cjs/cli/lib/insights.js +1 -1
  73. package/dist/cjs/cli/lib/insights.js.map +2 -2
  74. package/dist/cjs/cli/lib/localDeployment/anonymous.js +15 -8
  75. package/dist/cjs/cli/lib/localDeployment/anonymous.js.map +2 -2
  76. package/dist/cjs/cli/lib/localDeployment/localDeployment.js +8 -10
  77. package/dist/cjs/cli/lib/localDeployment/localDeployment.js.map +2 -2
  78. package/dist/cjs/cli/lib/localDeployment/run.js +1 -0
  79. package/dist/cjs/cli/lib/localDeployment/run.js.map +2 -2
  80. package/dist/cjs/cli/lib/localDeployment/upgrade.js +2 -2
  81. package/dist/cjs/cli/lib/localDeployment/upgrade.js.map +2 -2
  82. package/dist/cjs/cli/lib/localDeployment/utils.js +9 -0
  83. package/dist/cjs/cli/lib/localDeployment/utils.js.map +2 -2
  84. package/dist/cjs/cli/lib/mcp/tools/status.js +1 -1
  85. package/dist/cjs/cli/lib/mcp/tools/status.js.map +2 -2
  86. package/dist/cjs/cli/lib/updates.js +12 -13
  87. package/dist/cjs/cli/lib/updates.js.map +2 -2
  88. package/dist/cjs/cli/lib/usage.js +2 -1
  89. package/dist/cjs/cli/lib/usage.js.map +2 -2
  90. package/dist/cjs/cli/lib/utils/prompts.js +2 -1
  91. package/dist/cjs/cli/lib/utils/prompts.js.map +2 -2
  92. package/dist/cjs/cli/lib/utils/utils.js +46 -20
  93. package/dist/cjs/cli/lib/utils/utils.js.map +3 -3
  94. package/dist/cjs/cli/lib/versionApi.js +7 -4
  95. package/dist/cjs/cli/lib/versionApi.js.map +2 -2
  96. package/dist/cjs/cli/lib/workos/workos.js +4 -6
  97. package/dist/cjs/cli/lib/workos/workos.js.map +2 -2
  98. package/dist/cjs/index.js +1 -1
  99. package/dist/cjs/index.js.map +1 -1
  100. package/dist/cjs/react/client.js +43 -6
  101. package/dist/cjs/react/client.js.map +2 -2
  102. package/dist/cjs/react/index.js +2 -0
  103. package/dist/cjs/react/index.js.map +2 -2
  104. package/dist/cjs/react-clerk/ConvexProviderWithClerk.js.map +1 -1
  105. package/dist/cjs/server/api.js.map +2 -2
  106. package/dist/cjs/server/components/definition.js.map +1 -1
  107. package/dist/cjs/server/components/index.js +40 -4
  108. package/dist/cjs/server/components/index.js.map +2 -2
  109. package/dist/cjs/server/data_model.js.map +1 -1
  110. package/dist/cjs/server/impl/meta_impl.js +78 -0
  111. package/dist/cjs/server/impl/meta_impl.js.map +7 -0
  112. package/dist/cjs/server/impl/registration_impl.js +16 -11
  113. package/dist/cjs/server/impl/registration_impl.js.map +2 -2
  114. package/dist/cjs/server/index.js.map +2 -2
  115. package/dist/cjs/server/meta.js +17 -0
  116. package/dist/cjs/server/meta.js.map +7 -0
  117. package/dist/cjs/server/registration.js.map +1 -1
  118. package/dist/cjs-types/browser/index.d.ts +1 -0
  119. package/dist/cjs-types/browser/index.d.ts.map +1 -1
  120. package/dist/cjs-types/browser/query_options.d.ts +12 -9
  121. package/dist/cjs-types/browser/query_options.d.ts.map +1 -1
  122. package/dist/cjs-types/browser/sync/authentication_manager.d.ts.map +1 -1
  123. package/dist/cjs-types/browser/sync/web_socket_manager.d.ts.map +1 -1
  124. package/dist/cjs-types/cli/aiFiles.d.ts.map +1 -1
  125. package/dist/cjs-types/cli/codegen_templates/readme.d.ts.map +1 -1
  126. package/dist/cjs-types/cli/configure.d.ts.map +1 -1
  127. package/dist/cjs-types/cli/configure.test.d.ts +2 -0
  128. package/dist/cjs-types/cli/configure.test.d.ts.map +1 -0
  129. package/dist/cjs-types/cli/deploy.d.ts.map +1 -1
  130. package/dist/cjs-types/cli/deploymentCreate.d.ts +1 -0
  131. package/dist/cjs-types/cli/deploymentCreate.d.ts.map +1 -1
  132. package/dist/cjs-types/cli/deploymentSelect.d.ts +2 -1
  133. package/dist/cjs-types/cli/deploymentSelect.d.ts.map +1 -1
  134. package/dist/cjs-types/cli/dev.d.ts +3 -1
  135. package/dist/cjs-types/cli/dev.d.ts.map +1 -1
  136. package/dist/cjs-types/cli/lib/aiFiles/agentsmd.d.ts +19 -0
  137. package/dist/cjs-types/cli/lib/aiFiles/agentsmd.d.ts.map +1 -0
  138. package/dist/cjs-types/cli/lib/aiFiles/agentsmd.test.d.ts +2 -0
  139. package/dist/cjs-types/cli/lib/aiFiles/agentsmd.test.d.ts.map +1 -0
  140. package/dist/cjs-types/cli/lib/aiFiles/claudemd.d.ts +19 -0
  141. package/dist/cjs-types/cli/lib/aiFiles/claudemd.d.ts.map +1 -0
  142. package/dist/cjs-types/cli/lib/aiFiles/claudemd.test.d.ts +2 -0
  143. package/dist/cjs-types/cli/lib/aiFiles/claudemd.test.d.ts.map +1 -0
  144. package/dist/cjs-types/cli/lib/aiFiles/cursorrules.d.ts +10 -0
  145. package/dist/cjs-types/cli/lib/aiFiles/cursorrules.d.ts.map +1 -0
  146. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts +12 -0
  147. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -0
  148. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.test.d.ts +2 -0
  149. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.test.d.ts.map +1 -0
  150. package/dist/cjs-types/cli/lib/aiFiles/index.d.ts +42 -0
  151. package/dist/cjs-types/cli/lib/aiFiles/index.d.ts.map +1 -0
  152. package/dist/cjs-types/cli/lib/aiFiles/index.test.d.ts.map +1 -0
  153. package/dist/cjs-types/cli/lib/aiFiles/integration.test.d.ts.map +1 -0
  154. package/dist/cjs-types/cli/lib/{ai → aiFiles}/paths.d.ts +4 -0
  155. package/dist/cjs-types/cli/lib/aiFiles/paths.d.ts.map +1 -0
  156. package/dist/cjs-types/cli/lib/aiFiles/prompt.test.d.ts.map +1 -0
  157. package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts +20 -0
  158. package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts.map +1 -0
  159. package/dist/cjs-types/cli/lib/aiFiles/state.d.ts +38 -0
  160. package/dist/cjs-types/cli/lib/aiFiles/state.d.ts.map +1 -0
  161. package/dist/cjs-types/cli/lib/aiFiles/state.test.d.ts +2 -0
  162. package/dist/cjs-types/cli/lib/aiFiles/state.test.d.ts.map +1 -0
  163. package/dist/cjs-types/cli/lib/aiFiles/status.d.ts +6 -0
  164. package/dist/cjs-types/cli/lib/aiFiles/status.d.ts.map +1 -0
  165. package/dist/cjs-types/cli/lib/aiFiles/utils.d.ts +56 -0
  166. package/dist/cjs-types/cli/lib/aiFiles/utils.d.ts.map +1 -0
  167. package/dist/cjs-types/cli/lib/aiFiles/utils.test.d.ts +2 -0
  168. package/dist/cjs-types/cli/lib/aiFiles/utils.test.d.ts.map +1 -0
  169. package/dist/cjs-types/cli/lib/api.d.ts +3 -3
  170. package/dist/cjs-types/cli/lib/api.d.ts.map +1 -1
  171. package/dist/cjs-types/cli/lib/command.d.ts +2 -1
  172. package/dist/cjs-types/cli/lib/command.d.ts.map +1 -1
  173. package/dist/cjs-types/cli/lib/config.d.ts +18 -6
  174. package/dist/cjs-types/cli/lib/config.d.ts.map +1 -1
  175. package/dist/cjs-types/cli/lib/deploy2.d.ts +5 -2
  176. package/dist/cjs-types/cli/lib/deploy2.d.ts.map +1 -1
  177. package/dist/cjs-types/cli/lib/deployApi/componentDefinition.d.ts +27 -12
  178. package/dist/cjs-types/cli/lib/deployApi/componentDefinition.d.ts.map +1 -1
  179. package/dist/cjs-types/cli/lib/deployApi/definitionConfig.d.ts +24 -24
  180. package/dist/cjs-types/cli/lib/deployApi/modules.d.ts +14 -14
  181. package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts +61 -52
  182. package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
  183. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  184. package/dist/cjs-types/cli/lib/deploymentSelector.d.ts +2 -0
  185. package/dist/cjs-types/cli/lib/deploymentSelector.d.ts.map +1 -1
  186. package/dist/cjs-types/cli/lib/dev.d.ts.map +1 -1
  187. package/dist/cjs-types/cli/lib/env.d.ts +0 -4
  188. package/dist/cjs-types/cli/lib/env.d.ts.map +1 -1
  189. package/dist/cjs-types/cli/lib/expiration.d.ts +35 -0
  190. package/dist/cjs-types/cli/lib/expiration.d.ts.map +1 -0
  191. package/dist/cjs-types/cli/lib/expiration.test.d.ts +2 -0
  192. package/dist/cjs-types/cli/lib/expiration.test.d.ts.map +1 -0
  193. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts +16 -1
  194. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  195. package/dist/cjs-types/cli/lib/init.d.ts.map +1 -1
  196. package/dist/cjs-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  197. package/dist/cjs-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
  198. package/dist/cjs-types/cli/lib/localDeployment/run.d.ts +15 -0
  199. package/dist/cjs-types/cli/lib/localDeployment/run.d.ts.map +1 -1
  200. package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  201. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts +7 -0
  202. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  203. package/dist/cjs-types/cli/lib/mcp/requestContext.d.ts +3 -3
  204. package/dist/cjs-types/cli/lib/mcp/tools/insights.d.ts +2 -2
  205. package/dist/cjs-types/cli/lib/updates.d.ts +4 -3
  206. package/dist/cjs-types/cli/lib/updates.d.ts.map +1 -1
  207. package/dist/cjs-types/cli/lib/usage.d.ts.map +1 -1
  208. package/dist/cjs-types/cli/lib/utils/prompts.d.ts +1 -0
  209. package/dist/cjs-types/cli/lib/utils/prompts.d.ts.map +1 -1
  210. package/dist/cjs-types/cli/lib/utils/utils.d.ts +16 -2
  211. package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
  212. package/dist/cjs-types/cli/lib/versionApi.d.ts +7 -1
  213. package/dist/cjs-types/cli/lib/versionApi.d.ts.map +1 -1
  214. package/dist/cjs-types/cli/lib/workos/workos.d.ts.map +1 -1
  215. package/dist/cjs-types/index.d.ts +1 -1
  216. package/dist/cjs-types/react/client.d.ts +54 -2
  217. package/dist/cjs-types/react/client.d.ts.map +1 -1
  218. package/dist/cjs-types/react/index.d.ts +7 -2
  219. package/dist/cjs-types/react/index.d.ts.map +1 -1
  220. package/dist/cjs-types/react/use_query_object_options.test.d.ts +5 -0
  221. package/dist/cjs-types/react/use_query_object_options.test.d.ts.map +1 -0
  222. package/dist/cjs-types/react/use_query_result.test.d.ts +5 -0
  223. package/dist/cjs-types/react/use_query_result.test.d.ts.map +1 -0
  224. package/dist/cjs-types/react-clerk/ConvexProviderWithClerk.d.ts +1 -1
  225. package/dist/cjs-types/server/api.d.ts +5 -1
  226. package/dist/cjs-types/server/api.d.ts.map +1 -1
  227. package/dist/cjs-types/server/components/definition.d.ts +1 -0
  228. package/dist/cjs-types/server/components/definition.d.ts.map +1 -1
  229. package/dist/cjs-types/server/components/index.d.ts +5 -1
  230. package/dist/cjs-types/server/components/index.d.ts.map +1 -1
  231. package/dist/cjs-types/server/data_model.d.ts +2 -1
  232. package/dist/cjs-types/server/data_model.d.ts.map +1 -1
  233. package/dist/cjs-types/server/impl/meta_impl.d.ts +5 -0
  234. package/dist/cjs-types/server/impl/meta_impl.d.ts.map +1 -0
  235. package/dist/cjs-types/server/impl/registration_impl.d.ts.map +1 -1
  236. package/dist/cjs-types/server/index.d.ts +1 -0
  237. package/dist/cjs-types/server/index.d.ts.map +1 -1
  238. package/dist/cjs-types/server/meta.d.ts +72 -0
  239. package/dist/cjs-types/server/meta.d.ts.map +1 -0
  240. package/dist/cjs-types/server/registration.d.ts.map +1 -1
  241. package/dist/cli.bundle.cjs +2446 -1933
  242. package/dist/cli.bundle.cjs.map +4 -4
  243. package/dist/esm/browser/index-node.js +1 -0
  244. package/dist/esm/browser/index.js +1 -0
  245. package/dist/esm/browser/index.js.map +2 -2
  246. package/dist/esm/browser/query_options.js.map +2 -2
  247. package/dist/esm/browser/sync/authentication_manager.js +4 -1
  248. package/dist/esm/browser/sync/authentication_manager.js.map +2 -2
  249. package/dist/esm/browser/sync/web_socket_manager.js +1 -7
  250. package/dist/esm/browser/sync/web_socket_manager.js.map +2 -2
  251. package/dist/esm/cli/aiFiles.js +41 -23
  252. package/dist/esm/cli/aiFiles.js.map +2 -2
  253. package/dist/esm/cli/codegen_templates/readme.js +14 -1
  254. package/dist/esm/cli/codegen_templates/readme.js.map +2 -2
  255. package/dist/esm/cli/configure.js +35 -33
  256. package/dist/esm/cli/configure.js.map +2 -2
  257. package/dist/esm/cli/deploy.js +11 -10
  258. package/dist/esm/cli/deploy.js.map +2 -2
  259. package/dist/esm/cli/deploymentCreate.js +238 -42
  260. package/dist/esm/cli/deploymentCreate.js.map +2 -2
  261. package/dist/esm/cli/deploymentSelect.js +13 -12
  262. package/dist/esm/cli/deploymentSelect.js.map +2 -2
  263. package/dist/esm/cli/dev.js +34 -13
  264. package/dist/esm/cli/dev.js.map +2 -2
  265. package/dist/esm/cli/docs.js +1 -1
  266. package/dist/esm/cli/docs.js.map +2 -2
  267. package/dist/esm/cli/init.js +2 -2
  268. package/dist/esm/cli/init.js.map +2 -2
  269. package/dist/esm/cli/lib/aiFiles/agentsmd.js +56 -0
  270. package/dist/esm/cli/lib/aiFiles/agentsmd.js.map +7 -0
  271. package/dist/esm/cli/lib/aiFiles/claudemd.js +56 -0
  272. package/dist/esm/cli/lib/aiFiles/claudemd.js.map +7 -0
  273. package/dist/esm/cli/lib/aiFiles/cursorrules.js +16 -0
  274. package/dist/esm/cli/lib/aiFiles/cursorrules.js.map +7 -0
  275. package/dist/esm/cli/lib/aiFiles/guidelinesmd.js +35 -0
  276. package/dist/esm/cli/lib/aiFiles/guidelinesmd.js.map +7 -0
  277. package/dist/esm/cli/lib/aiFiles/index.js +193 -0
  278. package/dist/esm/cli/lib/aiFiles/index.js.map +7 -0
  279. package/dist/esm/cli/lib/aiFiles/paths.js.map +7 -0
  280. package/dist/esm/cli/lib/aiFiles/skills.js +163 -0
  281. package/dist/esm/cli/lib/aiFiles/skills.js.map +7 -0
  282. package/dist/esm/cli/lib/aiFiles/state.js +60 -0
  283. package/dist/esm/cli/lib/aiFiles/state.js.map +7 -0
  284. package/dist/esm/cli/lib/aiFiles/status.js +178 -0
  285. package/dist/esm/cli/lib/aiFiles/status.js.map +7 -0
  286. package/dist/esm/cli/lib/aiFiles/utils.js +97 -0
  287. package/dist/esm/cli/lib/aiFiles/utils.js.map +7 -0
  288. package/dist/esm/cli/lib/api.js +70 -7
  289. package/dist/esm/cli/lib/api.js.map +2 -2
  290. package/dist/esm/cli/lib/command.js +10 -6
  291. package/dist/esm/cli/lib/command.js.map +2 -2
  292. package/dist/esm/cli/lib/config.js +41 -6
  293. package/dist/esm/cli/lib/config.js.map +2 -2
  294. package/dist/esm/cli/lib/deploy2.js +13 -26
  295. package/dist/esm/cli/lib/deploy2.js.map +2 -2
  296. package/dist/esm/cli/lib/deployApi/componentDefinition.js +4 -1
  297. package/dist/esm/cli/lib/deployApi/componentDefinition.js.map +2 -2
  298. package/dist/esm/cli/lib/deploymentSelection.js +46 -2
  299. package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
  300. package/dist/esm/cli/lib/deploymentSelector.js +1 -0
  301. package/dist/esm/cli/lib/deploymentSelector.js.map +2 -2
  302. package/dist/esm/cli/lib/dev.js +162 -118
  303. package/dist/esm/cli/lib/dev.js.map +2 -2
  304. package/dist/esm/cli/lib/env.js +0 -11
  305. package/dist/esm/cli/lib/env.js.map +2 -2
  306. package/dist/esm/cli/lib/expiration.js +80 -0
  307. package/dist/esm/cli/lib/expiration.js.map +7 -0
  308. package/dist/esm/cli/lib/init.js +4 -3
  309. package/dist/esm/cli/lib/init.js.map +2 -2
  310. package/dist/esm/cli/lib/insights.js +1 -1
  311. package/dist/esm/cli/lib/insights.js.map +2 -2
  312. package/dist/esm/cli/lib/localDeployment/anonymous.js +16 -9
  313. package/dist/esm/cli/lib/localDeployment/anonymous.js.map +2 -2
  314. package/dist/esm/cli/lib/localDeployment/localDeployment.js +9 -11
  315. package/dist/esm/cli/lib/localDeployment/localDeployment.js.map +2 -2
  316. package/dist/esm/cli/lib/localDeployment/run.js +1 -1
  317. package/dist/esm/cli/lib/localDeployment/run.js.map +2 -2
  318. package/dist/esm/cli/lib/localDeployment/upgrade.js +2 -2
  319. package/dist/esm/cli/lib/localDeployment/upgrade.js.map +2 -2
  320. package/dist/esm/cli/lib/localDeployment/utils.js +8 -0
  321. package/dist/esm/cli/lib/localDeployment/utils.js.map +2 -2
  322. package/dist/esm/cli/lib/mcp/tools/status.js +1 -1
  323. package/dist/esm/cli/lib/mcp/tools/status.js.map +2 -2
  324. package/dist/esm/cli/lib/updates.js +14 -12
  325. package/dist/esm/cli/lib/updates.js.map +2 -2
  326. package/dist/esm/cli/lib/usage.js +2 -1
  327. package/dist/esm/cli/lib/usage.js.map +2 -2
  328. package/dist/esm/cli/lib/utils/prompts.js +2 -1
  329. package/dist/esm/cli/lib/utils/prompts.js.map +2 -2
  330. package/dist/esm/cli/lib/utils/utils.js +45 -20
  331. package/dist/esm/cli/lib/utils/utils.js.map +3 -3
  332. package/dist/esm/cli/lib/versionApi.js +7 -4
  333. package/dist/esm/cli/lib/versionApi.js.map +2 -2
  334. package/dist/esm/cli/lib/workos/workos.js +4 -6
  335. package/dist/esm/cli/lib/workos/workos.js.map +2 -2
  336. package/dist/esm/index.js +1 -1
  337. package/dist/esm/index.js.map +1 -1
  338. package/dist/esm/react/client.js +43 -6
  339. package/dist/esm/react/client.js.map +2 -2
  340. package/dist/esm/react/index.js +1 -0
  341. package/dist/esm/react/index.js.map +2 -2
  342. package/dist/esm/react-clerk/ConvexProviderWithClerk.js.map +1 -1
  343. package/dist/esm/server/api.js.map +2 -2
  344. package/dist/esm/server/components/index.js +40 -4
  345. package/dist/esm/server/components/index.js.map +2 -2
  346. package/dist/esm/server/impl/meta_impl.js +54 -0
  347. package/dist/esm/server/impl/meta_impl.js.map +7 -0
  348. package/dist/esm/server/impl/registration_impl.js +20 -11
  349. package/dist/esm/server/impl/registration_impl.js.map +2 -2
  350. package/dist/esm/server/index.js.map +2 -2
  351. package/dist/esm/server/meta.js +2 -0
  352. package/dist/esm/server/meta.js.map +7 -0
  353. package/dist/esm-types/browser/index.d.ts +1 -0
  354. package/dist/esm-types/browser/index.d.ts.map +1 -1
  355. package/dist/esm-types/browser/query_options.d.ts +12 -9
  356. package/dist/esm-types/browser/query_options.d.ts.map +1 -1
  357. package/dist/esm-types/browser/sync/authentication_manager.d.ts.map +1 -1
  358. package/dist/esm-types/browser/sync/web_socket_manager.d.ts.map +1 -1
  359. package/dist/esm-types/cli/aiFiles.d.ts.map +1 -1
  360. package/dist/esm-types/cli/codegen_templates/readme.d.ts.map +1 -1
  361. package/dist/esm-types/cli/configure.d.ts.map +1 -1
  362. package/dist/esm-types/cli/configure.test.d.ts +2 -0
  363. package/dist/esm-types/cli/configure.test.d.ts.map +1 -0
  364. package/dist/esm-types/cli/deploy.d.ts.map +1 -1
  365. package/dist/esm-types/cli/deploymentCreate.d.ts +1 -0
  366. package/dist/esm-types/cli/deploymentCreate.d.ts.map +1 -1
  367. package/dist/esm-types/cli/deploymentSelect.d.ts +2 -1
  368. package/dist/esm-types/cli/deploymentSelect.d.ts.map +1 -1
  369. package/dist/esm-types/cli/dev.d.ts +3 -1
  370. package/dist/esm-types/cli/dev.d.ts.map +1 -1
  371. package/dist/esm-types/cli/lib/aiFiles/agentsmd.d.ts +19 -0
  372. package/dist/esm-types/cli/lib/aiFiles/agentsmd.d.ts.map +1 -0
  373. package/dist/esm-types/cli/lib/aiFiles/agentsmd.test.d.ts +2 -0
  374. package/dist/esm-types/cli/lib/aiFiles/agentsmd.test.d.ts.map +1 -0
  375. package/dist/esm-types/cli/lib/aiFiles/claudemd.d.ts +19 -0
  376. package/dist/esm-types/cli/lib/aiFiles/claudemd.d.ts.map +1 -0
  377. package/dist/esm-types/cli/lib/aiFiles/claudemd.test.d.ts +2 -0
  378. package/dist/esm-types/cli/lib/aiFiles/claudemd.test.d.ts.map +1 -0
  379. package/dist/esm-types/cli/lib/aiFiles/cursorrules.d.ts +10 -0
  380. package/dist/esm-types/cli/lib/aiFiles/cursorrules.d.ts.map +1 -0
  381. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts +12 -0
  382. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -0
  383. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.test.d.ts +2 -0
  384. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.test.d.ts.map +1 -0
  385. package/dist/esm-types/cli/lib/aiFiles/index.d.ts +42 -0
  386. package/dist/esm-types/cli/lib/aiFiles/index.d.ts.map +1 -0
  387. package/dist/esm-types/cli/lib/aiFiles/index.test.d.ts.map +1 -0
  388. package/dist/esm-types/cli/lib/aiFiles/integration.test.d.ts.map +1 -0
  389. package/dist/esm-types/cli/lib/{ai → aiFiles}/paths.d.ts +4 -0
  390. package/dist/esm-types/cli/lib/aiFiles/paths.d.ts.map +1 -0
  391. package/dist/esm-types/cli/lib/aiFiles/prompt.test.d.ts.map +1 -0
  392. package/dist/esm-types/cli/lib/aiFiles/skills.d.ts +20 -0
  393. package/dist/esm-types/cli/lib/aiFiles/skills.d.ts.map +1 -0
  394. package/dist/esm-types/cli/lib/aiFiles/state.d.ts +38 -0
  395. package/dist/esm-types/cli/lib/aiFiles/state.d.ts.map +1 -0
  396. package/dist/esm-types/cli/lib/aiFiles/state.test.d.ts +2 -0
  397. package/dist/esm-types/cli/lib/aiFiles/state.test.d.ts.map +1 -0
  398. package/dist/esm-types/cli/lib/aiFiles/status.d.ts +6 -0
  399. package/dist/esm-types/cli/lib/aiFiles/status.d.ts.map +1 -0
  400. package/dist/esm-types/cli/lib/aiFiles/utils.d.ts +56 -0
  401. package/dist/esm-types/cli/lib/aiFiles/utils.d.ts.map +1 -0
  402. package/dist/esm-types/cli/lib/aiFiles/utils.test.d.ts +2 -0
  403. package/dist/esm-types/cli/lib/aiFiles/utils.test.d.ts.map +1 -0
  404. package/dist/esm-types/cli/lib/api.d.ts +3 -3
  405. package/dist/esm-types/cli/lib/api.d.ts.map +1 -1
  406. package/dist/esm-types/cli/lib/command.d.ts +2 -1
  407. package/dist/esm-types/cli/lib/command.d.ts.map +1 -1
  408. package/dist/esm-types/cli/lib/config.d.ts +18 -6
  409. package/dist/esm-types/cli/lib/config.d.ts.map +1 -1
  410. package/dist/esm-types/cli/lib/deploy2.d.ts +5 -2
  411. package/dist/esm-types/cli/lib/deploy2.d.ts.map +1 -1
  412. package/dist/esm-types/cli/lib/deployApi/componentDefinition.d.ts +27 -12
  413. package/dist/esm-types/cli/lib/deployApi/componentDefinition.d.ts.map +1 -1
  414. package/dist/esm-types/cli/lib/deployApi/definitionConfig.d.ts +24 -24
  415. package/dist/esm-types/cli/lib/deployApi/modules.d.ts +14 -14
  416. package/dist/esm-types/cli/lib/deployApi/startPush.d.ts +61 -52
  417. package/dist/esm-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
  418. package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  419. package/dist/esm-types/cli/lib/deploymentSelector.d.ts +2 -0
  420. package/dist/esm-types/cli/lib/deploymentSelector.d.ts.map +1 -1
  421. package/dist/esm-types/cli/lib/dev.d.ts.map +1 -1
  422. package/dist/esm-types/cli/lib/env.d.ts +0 -4
  423. package/dist/esm-types/cli/lib/env.d.ts.map +1 -1
  424. package/dist/esm-types/cli/lib/expiration.d.ts +35 -0
  425. package/dist/esm-types/cli/lib/expiration.d.ts.map +1 -0
  426. package/dist/esm-types/cli/lib/expiration.test.d.ts +2 -0
  427. package/dist/esm-types/cli/lib/expiration.test.d.ts.map +1 -0
  428. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts +16 -1
  429. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  430. package/dist/esm-types/cli/lib/init.d.ts.map +1 -1
  431. package/dist/esm-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  432. package/dist/esm-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
  433. package/dist/esm-types/cli/lib/localDeployment/run.d.ts +15 -0
  434. package/dist/esm-types/cli/lib/localDeployment/run.d.ts.map +1 -1
  435. package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  436. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts +7 -0
  437. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  438. package/dist/esm-types/cli/lib/mcp/requestContext.d.ts +3 -3
  439. package/dist/esm-types/cli/lib/mcp/tools/insights.d.ts +2 -2
  440. package/dist/esm-types/cli/lib/updates.d.ts +4 -3
  441. package/dist/esm-types/cli/lib/updates.d.ts.map +1 -1
  442. package/dist/esm-types/cli/lib/usage.d.ts.map +1 -1
  443. package/dist/esm-types/cli/lib/utils/prompts.d.ts +1 -0
  444. package/dist/esm-types/cli/lib/utils/prompts.d.ts.map +1 -1
  445. package/dist/esm-types/cli/lib/utils/utils.d.ts +16 -2
  446. package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
  447. package/dist/esm-types/cli/lib/versionApi.d.ts +7 -1
  448. package/dist/esm-types/cli/lib/versionApi.d.ts.map +1 -1
  449. package/dist/esm-types/cli/lib/workos/workos.d.ts.map +1 -1
  450. package/dist/esm-types/index.d.ts +1 -1
  451. package/dist/esm-types/react/client.d.ts +54 -2
  452. package/dist/esm-types/react/client.d.ts.map +1 -1
  453. package/dist/esm-types/react/index.d.ts +7 -2
  454. package/dist/esm-types/react/index.d.ts.map +1 -1
  455. package/dist/esm-types/react/use_query_object_options.test.d.ts +5 -0
  456. package/dist/esm-types/react/use_query_object_options.test.d.ts.map +1 -0
  457. package/dist/esm-types/react/use_query_result.test.d.ts +5 -0
  458. package/dist/esm-types/react/use_query_result.test.d.ts.map +1 -0
  459. package/dist/esm-types/react-clerk/ConvexProviderWithClerk.d.ts +1 -1
  460. package/dist/esm-types/server/api.d.ts +5 -1
  461. package/dist/esm-types/server/api.d.ts.map +1 -1
  462. package/dist/esm-types/server/components/definition.d.ts +1 -0
  463. package/dist/esm-types/server/components/definition.d.ts.map +1 -1
  464. package/dist/esm-types/server/components/index.d.ts +5 -1
  465. package/dist/esm-types/server/components/index.d.ts.map +1 -1
  466. package/dist/esm-types/server/data_model.d.ts +2 -1
  467. package/dist/esm-types/server/data_model.d.ts.map +1 -1
  468. package/dist/esm-types/server/impl/meta_impl.d.ts +5 -0
  469. package/dist/esm-types/server/impl/meta_impl.d.ts.map +1 -0
  470. package/dist/esm-types/server/impl/registration_impl.d.ts.map +1 -1
  471. package/dist/esm-types/server/index.d.ts +1 -0
  472. package/dist/esm-types/server/index.d.ts.map +1 -1
  473. package/dist/esm-types/server/meta.d.ts +72 -0
  474. package/dist/esm-types/server/meta.d.ts.map +1 -0
  475. package/dist/esm-types/server/registration.d.ts.map +1 -1
  476. package/dist/react.bundle.js +55 -15
  477. package/dist/react.bundle.js.map +3 -3
  478. package/package.json +11 -7
  479. package/schemas/convex.schema.json +22 -3
  480. package/src/browser/index.ts +3 -0
  481. package/src/browser/query_options.test.ts +0 -9
  482. package/src/browser/query_options.ts +36 -15
  483. package/src/browser/sync/authentication_manager.ts +9 -4
  484. package/src/browser/sync/client_node.test.ts +125 -0
  485. package/src/browser/sync/web_socket_manager.ts +1 -7
  486. package/src/cli/aiFiles.ts +56 -33
  487. package/src/cli/codegen_templates/readme.ts +14 -1
  488. package/src/cli/configure.test.ts +138 -0
  489. package/src/cli/configure.ts +62 -55
  490. package/src/cli/deploy.ts +12 -9
  491. package/src/cli/deploymentCreate.test.ts +349 -14
  492. package/src/cli/deploymentCreate.ts +268 -41
  493. package/src/cli/deploymentSelect.test.ts +136 -27
  494. package/src/cli/deploymentSelect.ts +50 -41
  495. package/src/cli/deploymentSelection.test.ts +399 -37
  496. package/src/cli/dev.ts +49 -14
  497. package/src/cli/docs.ts +1 -1
  498. package/src/cli/init.ts +2 -2
  499. package/src/cli/lib/{ai → aiFiles}/MANUAL_TESTING.md +6 -2
  500. package/src/cli/lib/aiFiles/agentsmd.test.ts +133 -0
  501. package/src/cli/lib/aiFiles/agentsmd.ts +81 -0
  502. package/src/cli/lib/aiFiles/claudemd.test.ts +92 -0
  503. package/src/cli/lib/aiFiles/claudemd.ts +81 -0
  504. package/src/cli/lib/aiFiles/cursorrules.ts +25 -0
  505. package/src/cli/lib/aiFiles/guidelinesmd.test.ts +50 -0
  506. package/src/cli/lib/aiFiles/guidelinesmd.ts +49 -0
  507. package/src/cli/lib/{ai → aiFiles}/index.test.ts +343 -516
  508. package/src/cli/lib/aiFiles/index.ts +297 -0
  509. package/src/cli/lib/{ai → aiFiles}/integration.test.ts +195 -158
  510. package/src/cli/lib/{ai → aiFiles}/paths.ts +5 -0
  511. package/src/cli/lib/{ai → aiFiles}/prompt.test.ts +79 -31
  512. package/src/cli/lib/aiFiles/skills.ts +243 -0
  513. package/src/cli/lib/aiFiles/state.test.ts +280 -0
  514. package/src/cli/lib/aiFiles/state.ts +82 -0
  515. package/src/cli/lib/aiFiles/status.ts +246 -0
  516. package/src/cli/lib/aiFiles/utils.test.ts +50 -0
  517. package/src/cli/lib/aiFiles/utils.ts +191 -0
  518. package/src/cli/lib/api.ts +88 -7
  519. package/src/cli/lib/command.ts +18 -8
  520. package/src/cli/lib/config.test.ts +185 -8
  521. package/src/cli/lib/config.ts +73 -12
  522. package/src/cli/lib/deploy2.ts +14 -27
  523. package/src/cli/lib/deployApi/componentDefinition.ts +4 -1
  524. package/src/cli/lib/deploymentSelection.ts +59 -6
  525. package/src/cli/lib/deploymentSelector.test.ts +6 -0
  526. package/src/cli/lib/deploymentSelector.ts +2 -0
  527. package/src/cli/lib/dev.ts +202 -153
  528. package/src/cli/lib/env.ts +0 -15
  529. package/src/cli/lib/expiration.test.ts +159 -0
  530. package/src/cli/lib/expiration.ts +124 -0
  531. package/src/cli/lib/generatedFunctionLogsApi.ts +16 -1
  532. package/src/cli/lib/init.ts +6 -2
  533. package/src/cli/lib/insights.ts +1 -1
  534. package/src/cli/lib/localDeployment/anonymous.ts +19 -9
  535. package/src/cli/lib/localDeployment/localDeployment.ts +9 -11
  536. package/src/cli/lib/localDeployment/run.ts +1 -1
  537. package/src/cli/lib/localDeployment/upgrade.ts +12 -10
  538. package/src/cli/lib/localDeployment/utils.ts +12 -0
  539. package/src/cli/lib/mcp/tools/status.ts +1 -1
  540. package/src/cli/lib/updates.test.ts +97 -60
  541. package/src/cli/lib/updates.ts +17 -15
  542. package/src/cli/lib/usage.ts +3 -1
  543. package/src/cli/lib/utils/prompts.ts +2 -0
  544. package/src/cli/lib/utils/utils.test.ts +6 -6
  545. package/src/cli/lib/utils/utils.ts +66 -27
  546. package/src/cli/lib/versionApi.test.ts +13 -10
  547. package/src/cli/lib/versionApi.ts +13 -5
  548. package/src/cli/lib/workos/workos.ts +4 -5
  549. package/src/index.ts +1 -1
  550. package/src/react/client.test.tsx +65 -0
  551. package/src/react/client.ts +129 -13
  552. package/src/react/index.ts +9 -1
  553. package/src/react/use_query_object_options.test.ts +50 -0
  554. package/src/react/use_query_result.test.ts +41 -0
  555. package/src/react-clerk/ConvexProviderWithClerk.test.tsx +1 -1
  556. package/src/react-clerk/ConvexProviderWithClerk.tsx +1 -1
  557. package/src/server/api.ts +5 -1
  558. package/src/server/components/definition.ts +3 -0
  559. package/src/server/components/index.ts +62 -5
  560. package/src/server/data_model.ts +2 -1
  561. package/src/server/impl/meta_impl.ts +74 -0
  562. package/src/server/impl/registration_impl.ts +21 -9
  563. package/src/server/index.ts +8 -0
  564. package/src/server/meta.ts +76 -0
  565. package/src/server/registration.ts +10 -0
  566. package/src/server/schema.test.ts +78 -1
  567. package/dist/cjs/cli/lib/ai/config.js +0 -144
  568. package/dist/cjs/cli/lib/ai/config.js.map +0 -7
  569. package/dist/cjs/cli/lib/ai/index.js +0 -704
  570. package/dist/cjs/cli/lib/ai/index.js.map +0 -7
  571. package/dist/cjs/cli/lib/ai/paths.js.map +0 -7
  572. package/dist/cjs-types/cli/lib/ai/config.d.ts +0 -50
  573. package/dist/cjs-types/cli/lib/ai/config.d.ts.map +0 -1
  574. package/dist/cjs-types/cli/lib/ai/config.test.d.ts +0 -2
  575. package/dist/cjs-types/cli/lib/ai/config.test.d.ts.map +0 -1
  576. package/dist/cjs-types/cli/lib/ai/index.d.ts +0 -56
  577. package/dist/cjs-types/cli/lib/ai/index.d.ts.map +0 -1
  578. package/dist/cjs-types/cli/lib/ai/index.test.d.ts.map +0 -1
  579. package/dist/cjs-types/cli/lib/ai/integration.test.d.ts.map +0 -1
  580. package/dist/cjs-types/cli/lib/ai/paths.d.ts.map +0 -1
  581. package/dist/cjs-types/cli/lib/ai/prompt.test.d.ts.map +0 -1
  582. package/dist/esm/cli/lib/ai/config.js +0 -109
  583. package/dist/esm/cli/lib/ai/config.js.map +0 -7
  584. package/dist/esm/cli/lib/ai/index.js +0 -684
  585. package/dist/esm/cli/lib/ai/index.js.map +0 -7
  586. package/dist/esm/cli/lib/ai/paths.js.map +0 -7
  587. package/dist/esm-types/cli/lib/ai/config.d.ts +0 -50
  588. package/dist/esm-types/cli/lib/ai/config.d.ts.map +0 -1
  589. package/dist/esm-types/cli/lib/ai/config.test.d.ts +0 -2
  590. package/dist/esm-types/cli/lib/ai/config.test.d.ts.map +0 -1
  591. package/dist/esm-types/cli/lib/ai/index.d.ts +0 -56
  592. package/dist/esm-types/cli/lib/ai/index.d.ts.map +0 -1
  593. package/dist/esm-types/cli/lib/ai/index.test.d.ts.map +0 -1
  594. package/dist/esm-types/cli/lib/ai/integration.test.d.ts.map +0 -1
  595. package/dist/esm-types/cli/lib/ai/paths.d.ts.map +0 -1
  596. package/dist/esm-types/cli/lib/ai/prompt.test.d.ts.map +0 -1
  597. package/src/cli/lib/ai/config.test.ts +0 -338
  598. package/src/cli/lib/ai/config.ts +0 -159
  599. package/src/cli/lib/ai/index.ts +0 -1006
  600. /package/dist/cjs/cli/lib/{ai → aiFiles}/paths.js +0 -0
  601. /package/dist/cjs-types/cli/lib/{ai → aiFiles}/index.test.d.ts +0 -0
  602. /package/dist/cjs-types/cli/lib/{ai → aiFiles}/integration.test.d.ts +0 -0
  603. /package/dist/cjs-types/cli/lib/{ai → aiFiles}/prompt.test.d.ts +0 -0
  604. /package/dist/esm/cli/lib/{ai → aiFiles}/paths.js +0 -0
  605. /package/dist/esm-types/cli/lib/{ai → aiFiles}/index.test.d.ts +0 -0
  606. /package/dist/esm-types/cli/lib/{ai → aiFiles}/integration.test.d.ts +0 -0
  607. /package/dist/esm-types/cli/lib/{ai → aiFiles}/prompt.test.d.ts +0 -0
@@ -1,1006 +0,0 @@
1
- import * as Sentry from "@sentry/node";
2
- import child_process from "child_process";
3
- import path from "path";
4
- import { Context } from "../../../bundler/context.js";
5
- // Use raw fs (not ctx.fs) so these operations run asynchronously and don't
6
- // interfere with the file-watcher used by `convex dev`.
7
- // eslint-disable-next-line no-restricted-imports
8
- import { promises as fs } from "fs";
9
- import { chalkStderr } from "chalk";
10
- import { logMessage } from "../../../bundler/log.js";
11
- import {
12
- AGENTS_MD_START_MARKER,
13
- AGENTS_MD_END_MARKER,
14
- agentsMdConvexSection,
15
- } from "../../codegen_templates/agentsmd.js";
16
- import {
17
- CLAUDE_MD_END_MARKER,
18
- CLAUDE_MD_START_MARKER,
19
- claudeMdConvexSection,
20
- } from "../../codegen_templates/claudemd.js";
21
- import {
22
- downloadGuidelines,
23
- fetchAgentSkillsSha,
24
- getVersion,
25
- } from "../versionApi.js";
26
- import { promptYesNo } from "../utils/prompts.js";
27
- import { hashSha256 } from "../utils/hash.js";
28
- import {
29
- aiDirForConvexDir,
30
- agentsMdPath,
31
- claudeMdPath,
32
- guidelinesPathForConvexDir,
33
- } from "./paths.js";
34
- import {
35
- type AiFilesConfig,
36
- readAiConfig,
37
- writeAiConfig,
38
- writeAiDisabledToProjectConfig,
39
- } from "./config.js";
40
-
41
- function isAgentMode(): boolean {
42
- return process.env.CONVEX_AGENT_MODE !== undefined;
43
- }
44
-
45
- // ---------------------------------------------------------------------------
46
- // AGENTS.md helpers
47
- // ---------------------------------------------------------------------------
48
-
49
- export async function injectAgentsMdSection(
50
- section: string,
51
- projectDir?: string,
52
- ): Promise<string | null> {
53
- const filePath = agentsMdPath(projectDir);
54
- let existing = "";
55
- try {
56
- existing = await fs.readFile(filePath, "utf8");
57
- } catch {
58
- // File doesn't exist — we'll create it.
59
- }
60
-
61
- let updated: string;
62
- const startIdx = existing.indexOf(AGENTS_MD_START_MARKER);
63
- const endIdx = existing.indexOf(AGENTS_MD_END_MARKER);
64
-
65
- if (startIdx !== -1 && endIdx !== -1) {
66
- // Replace existing Convex section.
67
- updated =
68
- existing.slice(0, startIdx) +
69
- section +
70
- existing.slice(endIdx + AGENTS_MD_END_MARKER.length);
71
- } else if (existing.length > 0) {
72
- // Append to existing file (with a blank line separator).
73
- updated = existing.trimEnd() + "\n\n" + section + "\n";
74
- } else {
75
- // Create new file.
76
- updated = section + "\n";
77
- }
78
-
79
- await fs.writeFile(filePath, updated, "utf8");
80
- return hashSha256(section);
81
- }
82
-
83
- type InjectClaudeSectionResult = {
84
- sectionHash: string;
85
- didWrite: boolean;
86
- };
87
-
88
- export async function injectClaudeMdSection(
89
- section: string,
90
- projectDir?: string,
91
- ): Promise<InjectClaudeSectionResult> {
92
- const filePath = claudeMdPath(projectDir);
93
- let existing = "";
94
- try {
95
- existing = await fs.readFile(filePath, "utf8");
96
- } catch {
97
- // File doesn't exist - we'll create it.
98
- }
99
-
100
- let updated: string;
101
- const startIdx = existing.indexOf(CLAUDE_MD_START_MARKER);
102
- const endIdx = existing.indexOf(CLAUDE_MD_END_MARKER);
103
-
104
- if (startIdx !== -1 && endIdx !== -1) {
105
- // Replace existing Convex section.
106
- updated =
107
- existing.slice(0, startIdx) +
108
- section +
109
- existing.slice(endIdx + CLAUDE_MD_END_MARKER.length);
110
- } else if (existing.length > 0) {
111
- // Append to existing file (with a blank line separator).
112
- updated = existing.trimEnd() + "\n\n" + section + "\n";
113
- } else {
114
- // Create new file.
115
- updated = section + "\n";
116
- }
117
-
118
- const didWrite = updated !== existing;
119
- if (didWrite) {
120
- await fs.writeFile(filePath, updated, "utf8");
121
- }
122
- return {
123
- sectionHash: hashSha256(section),
124
- didWrite,
125
- };
126
- }
127
-
128
- // ---------------------------------------------------------------------------
129
- // Public API
130
- // ---------------------------------------------------------------------------
131
-
132
- /**
133
- * Write/update all Convex AI files (guidelines, AGENTS.md, CLAUDE.md, skills).
134
- *
135
- * @param convexDir - absolute path to the project's convex functions directory
136
- * (e.g. `/home/user/myapp/convex`). Used to build the `_generated/ai/` subdirectory.
137
- */
138
- export async function writeAiFiles(
139
- convexDir: string,
140
- installSkills: boolean = false,
141
- skillsOutputMode: "verbose" | "quiet" = "verbose",
142
- projectDirOverride?: string,
143
- ): Promise<void> {
144
- const projectDir = path.resolve(
145
- projectDirOverride ?? path.dirname(convexDir),
146
- );
147
-
148
- try {
149
- // Ensure convex/_generated/ai/ directory exists.
150
- await fs.mkdir(aiDirForConvexDir(convexDir), { recursive: true });
151
-
152
- const config: AiFilesConfig = {
153
- disableStalenessMessage: false,
154
- guidelinesHash: null,
155
- agentsMdSectionHash: null,
156
- claudeMdHash: null,
157
- agentSkillsSha: null,
158
- installedSkillNames: [],
159
- };
160
-
161
- // Write guidelines.
162
- const guidelines = await downloadGuidelines();
163
- if (guidelines !== null) {
164
- await fs.writeFile(
165
- guidelinesPathForConvexDir(convexDir),
166
- guidelines,
167
- "utf8",
168
- );
169
- config.guidelinesHash = hashSha256(guidelines);
170
- } else {
171
- logMessage(
172
- chalkStderr.yellow(
173
- "Could not download Convex AI guidelines right now. You can retry with: npx convex ai-files install",
174
- ),
175
- );
176
- }
177
-
178
- // Inject Convex section into AGENTS.md.
179
- const convexDirName = path.relative(projectDir, convexDir);
180
- const section = agentsMdConvexSection(convexDirName);
181
- config.agentsMdSectionHash = await injectAgentsMdSection(
182
- section,
183
- projectDir,
184
- );
185
-
186
- // Inject Convex section into CLAUDE.md.
187
- const claudeSection = claudeMdConvexSection(convexDirName);
188
- const claudeInjectResult = await injectClaudeMdSection(
189
- claudeSection,
190
- projectDir,
191
- );
192
- config.claudeMdHash = claudeInjectResult.sectionHash;
193
-
194
- if (installSkills) {
195
- if (await shouldRunSkillsCli()) {
196
- logMessage("Installing Convex agent skills...");
197
- const skillsOk = await runSkillsAdd(projectDir, skillsOutputMode);
198
- if (skillsOk) {
199
- // Record the canonical SHA for staleness detection.
200
- const sha = await fetchAgentSkillsSha();
201
- if (sha) {
202
- config.agentSkillsSha = sha;
203
- }
204
- const names = await readInstalledSkillNames(projectDir);
205
- if (names.length > 0) {
206
- config.installedSkillNames = names;
207
- }
208
- } else {
209
- logMessage(
210
- chalkStderr.yellow(
211
- "Could not install agent skills. You can retry manually with: npx skills add get-convex/agent-skills",
212
- ),
213
- );
214
- }
215
- }
216
- }
217
-
218
- // Clean up the legacy `.cursor/rules/convex_rules.mdc` file if present.
219
- // It was written by the old cursor rules auto-update and is now superseded
220
- // by `convex/_generated/ai/guidelines.md`.
221
- const removedLegacy = await removeLegacyCursorRulesFile(projectDir);
222
- if (removedLegacy) {
223
- logMessage(
224
- `${chalkStderr.green(`✔`)} Removed legacy .cursor/rules/convex_rules.mdc (superseded by convex/_generated/ai/guidelines.md).`,
225
- );
226
- }
227
-
228
- await writeAiConfig(config, projectDir, convexDir);
229
-
230
- logMessage(
231
- `${chalkStderr.green(`✔`)} Wrote Convex AI files to ${path.relative(projectDir, aiDirForConvexDir(convexDir))}/`,
232
- );
233
- } catch (error) {
234
- Sentry.captureException(error);
235
- // Non-fatal — don't break the init flow.
236
- }
237
- }
238
-
239
- /**
240
- * Check whether the Convex AI files are out of date and log a nag message
241
- * if so.
242
- */
243
- export async function checkAiFilesStaleness(
244
- canonicalGuidelinesHash: string | null,
245
- canonicalAgentSkillsSha: string | null,
246
- projectDir: string,
247
- convexDir: string,
248
- ): Promise<void> {
249
- const config = await readAiConfig(projectDir, convexDir);
250
-
251
- if (config === null) {
252
- // No state file means AI files have not been set up yet. Keep nudging until
253
- // the user either installs them or explicitly disables the nag with
254
- // `npx convex ai-files disable`.
255
- logMessage(
256
- chalkStderr.yellow(
257
- isAgentMode()
258
- ? `Convex AI files are not installed. If you are an agent tell the human to run ${chalkStderr.bold(`npx convex ai-files install`)} to get started or ${chalkStderr.bold(`npx convex ai-files disable`)} to hide this message.`
259
- : `Convex AI files are not installed. Run ${chalkStderr.bold(`npx convex ai-files install`)} to get started or ${chalkStderr.bold(`npx convex ai-files disable`)} to hide this message.`,
260
- ),
261
- );
262
- return;
263
- }
264
-
265
- if (config.disableStalenessMessage) {
266
- // User explicitly suppressed staleness/install messages.
267
- return;
268
- }
269
-
270
- // No version data from server — skip staleness check (non-fatal).
271
- if (canonicalGuidelinesHash === null && canonicalAgentSkillsSha === null) {
272
- return;
273
- }
274
-
275
- const guidelinesStale =
276
- canonicalGuidelinesHash !== null &&
277
- config.guidelinesHash !== null &&
278
- config.guidelinesHash !== canonicalGuidelinesHash;
279
-
280
- const skillsStale =
281
- canonicalAgentSkillsSha !== null &&
282
- config.agentSkillsSha !== null &&
283
- config.agentSkillsSha !== canonicalAgentSkillsSha;
284
-
285
- if (guidelinesStale || skillsStale) {
286
- logMessage(
287
- chalkStderr.yellow(
288
- `Your Convex AI files are out of date. Run ${chalkStderr.bold(`npx convex ai-files update`)} to get the latest.`,
289
- ),
290
- );
291
- }
292
- }
293
-
294
- /**
295
- * Update all Convex AI files to their latest versions.
296
- *
297
- * Files the user has modified (detected via hash comparison) are skipped
298
- * with a warning rather than silently overwritten.
299
- *
300
- * @param projectDir - absolute path to the project root directory.
301
- * @param convexDir - absolute path to the Convex functions directory.
302
- */
303
- export async function updateAiFiles(
304
- projectDir: string,
305
- convexDir: string,
306
- ): Promise<void> {
307
- const config = await readAiConfig(projectDir, convexDir);
308
- if (config === null) {
309
- // No config yet — run the full init and install skills.
310
- await writeAiFiles(convexDir, true, "verbose", projectDir);
311
- return;
312
- }
313
-
314
- // Config can exist (for example, disableStalenessMessage in convex.json) even
315
- // when convex/_generated/ai/ was removed. Recreate it so reinstall/update
316
- // paths do not fail when writing guidelines/state.
317
- await fs.mkdir(aiDirForConvexDir(convexDir), { recursive: true });
318
-
319
- let updatedCount = 0;
320
- let skippedCount = 0;
321
-
322
- // Update guidelines.
323
- const guidelines = await downloadGuidelines();
324
- if (guidelines !== null) {
325
- const newHash = hashSha256(guidelines);
326
- if (newHash === config.guidelinesHash) {
327
- logMessage("Convex AI guidelines are already up to date.");
328
- } else {
329
- const currentContent = await readFileSafe(
330
- guidelinesPathForConvexDir(convexDir),
331
- );
332
- if (
333
- currentContent !== null &&
334
- config.guidelinesHash !== null &&
335
- hashSha256(currentContent) !== config.guidelinesHash
336
- ) {
337
- logMessage(
338
- chalkStderr.yellow(
339
- `Skipping ${path.relative(projectDir, guidelinesPathForConvexDir(convexDir))} — file has been modified locally.`,
340
- ),
341
- );
342
- skippedCount++;
343
- } else {
344
- await fs.writeFile(
345
- guidelinesPathForConvexDir(convexDir),
346
- guidelines,
347
- "utf8",
348
- );
349
- config.guidelinesHash = newHash;
350
- updatedCount++;
351
- }
352
- }
353
- } else {
354
- logMessage(
355
- chalkStderr.yellow(
356
- "Could not download Convex AI guidelines right now. Keeping your existing guidelines file.",
357
- ),
358
- );
359
- }
360
-
361
- // Update AGENTS.md section. The dir name is hardcoded to match paths.ts
362
- // (the only non-standard case was create-react-app which is dead).
363
- const convexDirName = path.relative(projectDir, convexDir);
364
- const section = agentsMdConvexSection(convexDirName);
365
- const newSectionHash = hashSha256(section);
366
-
367
- if (newSectionHash !== config.agentsMdSectionHash) {
368
- config.agentsMdSectionHash = await injectAgentsMdSection(
369
- section,
370
- projectDir,
371
- );
372
- updatedCount++;
373
- }
374
-
375
- // The skills CLI streams its own output, so we don't count this in
376
- // updatedCount.
377
- if (await shouldRunSkillsCli()) {
378
- logMessage("Installing Convex agent skills...");
379
- const skillsOk = await runSkillsAdd(projectDir);
380
- if (skillsOk) {
381
- // Record the canonical SHA for staleness detection.
382
- const sha = await fetchAgentSkillsSha();
383
- if (sha) {
384
- config.agentSkillsSha = sha;
385
- }
386
- // Track installed skill names so `convex ai-files remove` can pass them
387
- // to `npx skills remove`.
388
- const names = await readInstalledSkillNames(projectDir);
389
- if (names.length > 0) {
390
- config.installedSkillNames = names;
391
- }
392
- } else {
393
- logMessage(
394
- chalkStderr.yellow(
395
- "Could not install agent skills. You can retry manually with: npx skills add get-convex/agent-skills",
396
- ),
397
- );
398
- }
399
- }
400
-
401
- // Clean up the legacy `.cursor/rules/convex_rules.mdc` file if present.
402
- // It was written by the old cursor rules auto-update and is now superseded
403
- // by `convex/_generated/ai/guidelines.md`.
404
- const removedLegacy = await removeLegacyCursorRulesFile(projectDir);
405
- if (removedLegacy) {
406
- logMessage(
407
- `${chalkStderr.green(`✔`)} Removed legacy .cursor/rules/convex_rules.mdc (superseded by convex/_generated/ai/guidelines.md).`,
408
- );
409
- updatedCount++;
410
- }
411
-
412
- // Update/inject the Convex-managed CLAUDE.md section.
413
- const claudeSection = claudeMdConvexSection(convexDirName);
414
- const claudeInjectResult = await injectClaudeMdSection(
415
- claudeSection,
416
- projectDir,
417
- );
418
- config.claudeMdHash = claudeInjectResult.sectionHash;
419
- if (claudeInjectResult.didWrite) {
420
- updatedCount++;
421
- }
422
-
423
- await writeAiConfig(config, projectDir, convexDir);
424
-
425
- if (updatedCount > 0) {
426
- logMessage(
427
- `${chalkStderr.green(`✔`)} Updated ${updatedCount} Convex AI file${updatedCount === 1 ? "" : "s"}.`,
428
- );
429
- }
430
- if (skippedCount > 0) {
431
- logMessage(
432
- chalkStderr.yellow(
433
- `Skipped ${skippedCount} file${skippedCount === 1 ? "" : "s"} with local modifications.`,
434
- ),
435
- );
436
- }
437
- if (updatedCount === 0 && skippedCount === 0) {
438
- logMessage("Convex AI files are already up to date.");
439
- }
440
- }
441
-
442
- export async function enableAiFiles(
443
- projectDir: string,
444
- convexDir: string,
445
- ): Promise<void> {
446
- await updateAiFiles(projectDir, convexDir);
447
- const config = await readAiConfig(projectDir, convexDir);
448
- if (config === null) {
449
- return;
450
- }
451
- config.disableStalenessMessage = false;
452
- await writeAiConfig(config, projectDir, convexDir, {
453
- persistDisabledPreference: "always",
454
- });
455
- }
456
-
457
- /**
458
- * Remove the Convex-managed section from AGENTS.md (between the start/end
459
- * markers). If the file becomes empty or only whitespace after removal it is
460
- * deleted. Returns true if a section was found and removed.
461
- */
462
- async function stripAgentsMdSection(projectDir: string): Promise<boolean> {
463
- const filePath = agentsMdPath(projectDir);
464
- let content: string;
465
- try {
466
- content = await fs.readFile(filePath, "utf8");
467
- } catch {
468
- return false;
469
- }
470
- const startIdx = content.indexOf(AGENTS_MD_START_MARKER);
471
- const endIdx = content.indexOf(AGENTS_MD_END_MARKER);
472
- if (startIdx === -1 || endIdx === -1) {
473
- return false;
474
- }
475
- const before = content.slice(0, startIdx).trimEnd();
476
- const after = content.slice(endIdx + AGENTS_MD_END_MARKER.length).trimStart();
477
- const updated = [before, after].filter(Boolean).join("\n\n");
478
-
479
- if (!updated.trim()) {
480
- try {
481
- await fs.unlink(filePath);
482
- } catch {
483
- // Ignore errors
484
- }
485
- } else {
486
- await fs.writeFile(filePath, updated + "\n", "utf8");
487
- }
488
- return true;
489
- }
490
-
491
- /**
492
- * Remove the Convex-managed section from CLAUDE.md (between start/end markers).
493
- * If the file becomes empty after removal, delete it.
494
- */
495
- async function stripClaudeMdSection(
496
- projectDir: string,
497
- ): Promise<"none" | "section" | "file"> {
498
- const filePath = claudeMdPath(projectDir);
499
- let content: string;
500
- try {
501
- content = await fs.readFile(filePath, "utf8");
502
- } catch {
503
- return "none";
504
- }
505
- const startIdx = content.indexOf(CLAUDE_MD_START_MARKER);
506
- const endIdx = content.indexOf(CLAUDE_MD_END_MARKER);
507
- if (startIdx === -1 || endIdx === -1) {
508
- return "none";
509
- }
510
- const before = content.slice(0, startIdx).trimEnd();
511
- const after = content.slice(endIdx + CLAUDE_MD_END_MARKER.length).trimStart();
512
- const updated = [before, after].filter(Boolean).join("\n\n");
513
-
514
- if (!updated.trim()) {
515
- try {
516
- await fs.unlink(filePath);
517
- } catch {
518
- // Ignore errors.
519
- }
520
- return "file";
521
- }
522
- await fs.writeFile(filePath, updated + "\n", "utf8");
523
- return "section";
524
- }
525
-
526
- /**
527
- * Remove all Convex AI files from the project.
528
- * Called by `npx convex ai-files remove`.
529
- *
530
- * - Strips the Convex section from AGENTS.md (deletes file if empty)
531
- * - Strips the Convex section from CLAUDE.md (deletes file if empty)
532
- * - Runs `npx skills remove <name...> --yes` for each tracked skill
533
- * - Deletes the `convex/_generated/ai/` directory
534
- */
535
- export async function removeAiFiles(
536
- projectDir: string,
537
- convexDir: string,
538
- ): Promise<void> {
539
- const config = await readAiConfig(projectDir, convexDir);
540
-
541
- if (config === null) {
542
- logMessage("No Convex AI files found — nothing to remove.");
543
- return;
544
- }
545
-
546
- let removedCount = 0;
547
-
548
- // Strip Convex section from AGENTS.md.
549
- const stripped = await stripAgentsMdSection(projectDir);
550
- if (stripped) {
551
- logMessage(
552
- `${chalkStderr.green(`✔`)} Removed Convex section from AGENTS.md.`,
553
- );
554
- removedCount++;
555
- }
556
-
557
- // Strip Convex section from CLAUDE.md if present.
558
- // If the file is empty after stripping, it's deleted automatically.
559
- const strippedClaude = await stripClaudeMdSection(projectDir);
560
- if (strippedClaude === "section") {
561
- logMessage(
562
- `${chalkStderr.green(`✔`)} Removed Convex section from CLAUDE.md.`,
563
- );
564
- removedCount++;
565
- } else if (strippedClaude === "file") {
566
- logMessage(`${chalkStderr.green(`✔`)} Deleted CLAUDE.md.`);
567
- removedCount++;
568
- }
569
-
570
- // Remove installed skills via the skills CLI.
571
- if (config.installedSkillNames.length > 0) {
572
- if (await shouldRunSkillsCli()) {
573
- logMessage(
574
- `Removing Convex agent skills: ${config.installedSkillNames.join(", ")}`,
575
- );
576
- const skillsOk = await runSkillsRemove(
577
- projectDir,
578
- config.installedSkillNames,
579
- );
580
- if (!skillsOk) {
581
- logMessage(
582
- chalkStderr.yellow(
583
- "Could not remove agent skills automatically. Remove them manually with: npx skills remove",
584
- ),
585
- );
586
- } else {
587
- const removedLock = await removeSkillsLockIfEmpty(
588
- projectDir,
589
- config.installedSkillNames,
590
- );
591
- if (removedLock) {
592
- logMessage(`${chalkStderr.green(`✔`)} Deleted skills-lock.json.`);
593
- removedCount++;
594
- }
595
- }
596
- }
597
- }
598
-
599
- // Clean up the legacy `.cursor/rules/convex_rules.mdc` file if present.
600
- const removedLegacy = await removeLegacyCursorRulesFile(projectDir);
601
- if (removedLegacy) {
602
- logMessage(
603
- `${chalkStderr.green(`✔`)} Removed legacy .cursor/rules/convex_rules.mdc.`,
604
- );
605
- removedCount++;
606
- }
607
-
608
- // Delete the convex/_generated/ai/ directory.
609
- try {
610
- await fs.rm(aiDirForConvexDir(convexDir), { recursive: true, force: true });
611
- logMessage(
612
- `${chalkStderr.green(`✔`)} Deleted ${path.relative(projectDir, aiDirForConvexDir(convexDir))}/`,
613
- );
614
- removedCount++;
615
- } catch (error) {
616
- Sentry.captureException(error);
617
- logMessage(
618
- chalkStderr.yellow(
619
- `Could not delete ${path.relative(projectDir, aiDirForConvexDir(convexDir))}/. Remove it manually.`,
620
- ),
621
- );
622
- }
623
-
624
- if (removedCount > 0) {
625
- logMessage("Convex AI files removed.");
626
- }
627
- }
628
-
629
- /**
630
- * Called by `npx convex ai-files disable`.
631
- *
632
- * Writes a suppression flag into `convex.json` (`aiFiles.disableStalenessMessage`) so
633
- * `npx convex dev` stops showing AI files install/staleness messages.
634
- * Files are left in place - use `remove` to delete them.
635
- * The user can re-enable at any time with `npx convex ai-files enable`.
636
- */
637
- export async function disableAiFiles(projectDir: string): Promise<void> {
638
- try {
639
- await writeAiDisabledToProjectConfig(true, projectDir);
640
- logMessage(
641
- `${chalkStderr.green(`✔`)} Convex AI file staleness/install messages disabled. Run ${chalkStderr.bold(`npx convex ai-files enable`)} to re-enable.`,
642
- );
643
- } catch (error) {
644
- Sentry.captureException(error);
645
- logMessage(
646
- chalkStderr.yellow(
647
- "Could not write AI message suppression config. Message may reappear.",
648
- ),
649
- );
650
- }
651
- }
652
-
653
- /**
654
- * Print the current status of Convex AI files to the terminal.
655
- */
656
- export async function statusAiFiles(
657
- projectDir: string,
658
- convexDir: string,
659
- ): Promise<void> {
660
- const convexDirName = path.relative(projectDir, convexDir);
661
- const guidelinesRelPath = path.relative(
662
- projectDir,
663
- guidelinesPathForConvexDir(convexDir),
664
- );
665
-
666
- const config = await readAiConfig(projectDir, convexDir);
667
-
668
- if (config === null) {
669
- logMessage(`Convex AI files: ${chalkStderr.yellow("not installed")}`);
670
- logMessage(
671
- ` Run ${chalkStderr.bold("npx convex ai-files install")} to get started, ` +
672
- `or ${chalkStderr.bold("npx convex ai-files disable")} to silence this message.`,
673
- );
674
- return;
675
- }
676
-
677
- if (config.disableStalenessMessage) {
678
- logMessage(
679
- `Convex AI files: ${chalkStderr.yellow("staleness/install messages disabled")}`,
680
- );
681
- logMessage(
682
- ` Run ${chalkStderr.bold("npx convex ai-files enable")} to re-enable.`,
683
- );
684
- return;
685
- }
686
-
687
- logMessage(`Convex AI files: ${chalkStderr.green("enabled")}`);
688
-
689
- // Fetch canonical version data in parallel with the file reads below
690
- // (best-effort — network may be unavailable in CI or offline envs).
691
- const [versionData, guidelinesFile, agentsContent, claudeContent] =
692
- await Promise.all([
693
- getVersion(),
694
- readFileSafe(guidelinesPathForConvexDir(convexDir)),
695
- readFileSafe(agentsMdPath(projectDir)),
696
- readFileSafe(claudeMdPath(projectDir)),
697
- ]);
698
-
699
- const canonicalGuidelinesHash = versionData?.guidelinesHash ?? null;
700
- const canonicalAgentSkillsSha = versionData?.agentSkillsSha ?? null;
701
- const networkAvailable = versionData !== null;
702
-
703
- // --- convex/_generated/ai/guidelines.md ---
704
- if (guidelinesFile === null) {
705
- logMessage(
706
- ` ${chalkStderr.yellow("⚠")} ${guidelinesRelPath}: not on disk — run ${chalkStderr.bold("npx convex ai-files install")} to reinstall`,
707
- );
708
- } else if (
709
- config.guidelinesHash !== null &&
710
- hashSha256(guidelinesFile) !== config.guidelinesHash
711
- ) {
712
- logMessage(
713
- ` ${chalkStderr.yellow("⚠")} ${guidelinesRelPath}: installed, modified locally (Convex updates will be skipped)`,
714
- );
715
- } else if (
716
- networkAvailable &&
717
- canonicalGuidelinesHash !== null &&
718
- config.guidelinesHash !== null &&
719
- config.guidelinesHash !== canonicalGuidelinesHash
720
- ) {
721
- logMessage(
722
- ` ${chalkStderr.yellow("⚠")} ${guidelinesRelPath}: installed, out of date — run ${chalkStderr.bold("npx convex ai-files update")}`,
723
- );
724
- } else {
725
- logMessage(
726
- ` ${chalkStderr.green("✔")} ${guidelinesRelPath}: installed${networkAvailable ? ", up to date" : ""}`,
727
- );
728
- }
729
-
730
- // --- AGENTS.md (Convex section) ---
731
- const hasAgentsSection =
732
- agentsContent !== null &&
733
- agentsContent.includes(AGENTS_MD_START_MARKER) &&
734
- agentsContent.includes(AGENTS_MD_END_MARKER);
735
-
736
- if (!hasAgentsSection) {
737
- logMessage(
738
- ` ${chalkStderr.yellow("⚠")} AGENTS.md: Convex section missing — run ${chalkStderr.bold("npx convex ai-files install")} to reinstall`,
739
- );
740
- } else {
741
- // Staleness is locally computable from the template — no network needed.
742
- const currentSectionHash = hashSha256(agentsMdConvexSection(convexDirName));
743
- if (
744
- config.agentsMdSectionHash !== null &&
745
- config.agentsMdSectionHash !== currentSectionHash
746
- ) {
747
- logMessage(
748
- ` ${chalkStderr.yellow("⚠")} AGENTS.md: Convex section out of date — run ${chalkStderr.bold("npx convex ai-files update")}`,
749
- );
750
- } else {
751
- logMessage(
752
- ` ${chalkStderr.green("✔")} AGENTS.md: Convex section present, up to date`,
753
- );
754
- }
755
- }
756
-
757
- // --- CLAUDE.md (Convex section) ---
758
- const hasClaudeSection =
759
- claudeContent !== null &&
760
- claudeContent.includes(CLAUDE_MD_START_MARKER) &&
761
- claudeContent.includes(CLAUDE_MD_END_MARKER);
762
-
763
- if (!hasClaudeSection) {
764
- if (claudeContent === null) {
765
- logMessage(
766
- ` ${chalkStderr.yellow("⚠")} CLAUDE.md: missing - run ${chalkStderr.bold("npx convex ai-files install")} to create it`,
767
- );
768
- } else {
769
- logMessage(
770
- ` ${chalkStderr.yellow("⚠")} CLAUDE.md: no Convex section present - run ${chalkStderr.bold("npx convex ai-files update")} to add it`,
771
- );
772
- }
773
- } else {
774
- // Staleness is locally computable from the template — no network needed.
775
- const currentSectionHash = hashSha256(claudeMdConvexSection(convexDirName));
776
- if (
777
- config.claudeMdHash !== null &&
778
- config.claudeMdHash !== currentSectionHash
779
- ) {
780
- logMessage(
781
- ` ${chalkStderr.yellow("⚠")} CLAUDE.md: Convex section out of date - run ${chalkStderr.bold("npx convex ai-files update")}`,
782
- );
783
- } else {
784
- logMessage(
785
- ` ${chalkStderr.green("✔")} CLAUDE.md: Convex section present, up to date`,
786
- );
787
- }
788
- }
789
-
790
- // --- Agent skills ---
791
- if (config.installedSkillNames.length === 0) {
792
- logMessage(
793
- ` ${chalkStderr.yellow("⚠")} Agent skills: not installed — run ${chalkStderr.bold("npx convex ai-files install")} to install`,
794
- );
795
- } else {
796
- const skillsStale =
797
- networkAvailable &&
798
- canonicalAgentSkillsSha !== null &&
799
- config.agentSkillsSha !== null &&
800
- config.agentSkillsSha !== canonicalAgentSkillsSha;
801
- const skillsList = config.installedSkillNames.join(", ");
802
- if (skillsStale) {
803
- logMessage(
804
- ` ${chalkStderr.yellow("⚠")} Agent skills: ${skillsList} — out of date, run ${chalkStderr.bold("npx convex ai-files update")}`,
805
- );
806
- } else {
807
- logMessage(
808
- ` ${chalkStderr.green("✔")} Agent skills: ${skillsList}${networkAvailable ? " (up to date)" : ""}`,
809
- );
810
- }
811
- }
812
- }
813
-
814
- export async function maybeSetupAiFiles(
815
- ctx: Context,
816
- convexDir: string,
817
- projectDir: string,
818
- ): Promise<void> {
819
- if (isAgentMode()) {
820
- return;
821
- }
822
-
823
- // Non-interactive (no TTY) is almost always an AI agent, not CI
824
- // (CI uses `npx convex deploy`). Default to installing so agents
825
- // get context automatically.
826
- let wantsAiFiles = true;
827
- if (process.stdin.isTTY) {
828
- wantsAiFiles = await promptYesNo(ctx, {
829
- message: "Set up Convex AI files? (guidelines, AGENTS.md, agent skills)",
830
- default: true,
831
- });
832
- }
833
- if (wantsAiFiles) {
834
- await writeAiFiles(convexDir, true, "quiet", projectDir);
835
- }
836
- }
837
-
838
- /**
839
- * Remove the legacy `.cursor/rules/convex_rules.mdc` file if it exists.
840
- * This file was written by the old cursor rules auto-update feature (removed
841
- * in favour of the AI files system). We clean it up unconditionally
842
- * during `writeAiFiles`, `convex ai-files update`, and `convex ai-files remove` since it was always
843
- * auto-managed and is now superseded by `convex/_generated/ai/guidelines.md`.
844
- */
845
- async function removeLegacyCursorRulesFile(
846
- projectDir: string,
847
- ): Promise<boolean> {
848
- const filePath = path.join(
849
- projectDir,
850
- ".cursor",
851
- "rules",
852
- "convex_rules.mdc",
853
- );
854
- try {
855
- await fs.unlink(filePath);
856
- return true;
857
- } catch {
858
- return false;
859
- }
860
- }
861
-
862
- /**
863
- * Remove the skills-lock.json file if it only contains skills that we
864
- * are removing. The `npx skills remove` command leaves the lockfile behind
865
- * even when it's logically empty.
866
- */
867
- async function removeSkillsLockIfEmpty(
868
- projectDir: string,
869
- removedSkillNames: string[],
870
- ): Promise<boolean> {
871
- const lockPath = path.join(projectDir, "skills-lock.json");
872
- try {
873
- const content = await fs.readFile(lockPath, "utf8");
874
- const lock = JSON.parse(content);
875
-
876
- // If the file doesn't match the expected structure, leave it alone.
877
- if (
878
- !lock ||
879
- typeof lock !== "object" ||
880
- !lock.skills ||
881
- typeof lock.skills !== "object"
882
- ) {
883
- return false;
884
- }
885
-
886
- const remainingSkills = Object.keys(lock.skills).filter(
887
- (name) => !removedSkillNames.includes(name),
888
- );
889
-
890
- if (remainingSkills.length === 0) {
891
- await fs.unlink(lockPath);
892
- return true;
893
- }
894
- return false;
895
- } catch {
896
- return false;
897
- }
898
- }
899
-
900
- async function readFileSafe(filePath: string): Promise<string | null> {
901
- try {
902
- return await fs.readFile(filePath, "utf8");
903
- } catch {
904
- return null;
905
- }
906
- }
907
-
908
- /**
909
- * Read the frontmatter `name:` values from skills installed by the skills CLI.
910
- */
911
- async function readInstalledSkillNames(projectDir: string): Promise<string[]> {
912
- const skillsDir = path.join(projectDir, ".agents", "skills");
913
- let entries: string[];
914
- try {
915
- const dirents = await fs.readdir(skillsDir, { withFileTypes: true });
916
- entries = dirents
917
- .filter((d) => d.isDirectory() || d.isSymbolicLink())
918
- .map((d) => d.name);
919
- } catch {
920
- return [];
921
- }
922
-
923
- const names: string[] = [];
924
- for (const entry of entries) {
925
- const skillMdPath = path.join(skillsDir, entry, "SKILL.md");
926
- const content = await readFileSafe(skillMdPath);
927
- if (content === null) continue;
928
- // Extract `name: <value>` from YAML frontmatter (between the --- delimiters).
929
- const match = content.match(/^---[\s\S]*?^name:\s*(.+?)\s*$/m);
930
- if (match) {
931
- names.push(match[1]);
932
- }
933
- }
934
- return names;
935
- }
936
-
937
- /**
938
- * Runs `npx skills add get-convex/agent-skills --yes` in the given directory.
939
- * Output mode controls whether the skills CLI output is streamed live.
940
- * Returns true on success, false if the process fails or cannot be started.
941
- */
942
- function runSkillsAdd(
943
- cwd: string,
944
- outputMode: "verbose" | "quiet" = "verbose",
945
- ): Promise<boolean> {
946
- return runSkillsCommand(
947
- cwd,
948
- ["add", "get-convex/agent-skills", "--yes"],
949
- outputMode,
950
- );
951
- }
952
-
953
- /**
954
- * Runs `npx skills remove <name...> --yes` to surgically remove only the
955
- * Convex-managed skills, leaving any skills from other sources intact.
956
- */
957
- function runSkillsRemove(cwd: string, skillNames: string[]): Promise<boolean> {
958
- return runSkillsCommand(cwd, ["remove", ...skillNames, "--yes"]);
959
- }
960
-
961
- async function shouldRunSkillsCli(): Promise<boolean> {
962
- const versionData = await getVersion();
963
- if (versionData === null || versionData === undefined) {
964
- logMessage(chalkStderr.yellow(`Agent skills are temporarily disabled.`));
965
- return false;
966
- }
967
- if (versionData.disableSkillsCli) {
968
- logMessage(chalkStderr.yellow(`Agent skills are temporarily disabled.`));
969
- return false;
970
- }
971
- return true;
972
- }
973
-
974
- function runSkillsCommand(
975
- cwd: string,
976
- args: string[],
977
- outputMode: "verbose" | "quiet" = "verbose",
978
- ): Promise<boolean> {
979
- return new Promise((resolve) => {
980
- const quiet = outputMode === "quiet";
981
- const proc = child_process.spawn("npx", ["skills@latest", ...args], {
982
- cwd,
983
- stdio: quiet ? "pipe" : "inherit",
984
- // shell: true is required on Windows to resolve `npx` from PATH.
985
- shell: process.platform === "win32",
986
- });
987
- let capturedOutput = "";
988
- if (quiet) {
989
- proc.stdout?.on("data", (chunk) => {
990
- capturedOutput += chunk.toString();
991
- });
992
- proc.stderr?.on("data", (chunk) => {
993
- capturedOutput += chunk.toString();
994
- });
995
- }
996
- proc.on("close", (code) => {
997
- if (quiet && code !== 0 && capturedOutput.trim().length > 0) {
998
- const lines = capturedOutput.trim().split(/\r?\n/);
999
- const tail = lines.slice(-10).join("\n");
1000
- logMessage(chalkStderr.gray(`skills output (tail):\n${tail}`));
1001
- }
1002
- resolve(code === 0);
1003
- });
1004
- proc.on("error", () => resolve(false));
1005
- });
1006
- }