convex 1.34.1 → 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 (512) hide show
  1. package/CHANGELOG.md +86 -43
  2. package/dist/browser.bundle.js +8 -2
  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/cli/aiFiles.js +31 -13
  9. package/dist/cjs/cli/aiFiles.js.map +3 -3
  10. package/dist/cjs/cli/codegen_templates/readme.js +14 -1
  11. package/dist/cjs/cli/codegen_templates/readme.js.map +2 -2
  12. package/dist/cjs/cli/configure.js +21 -24
  13. package/dist/cjs/cli/configure.js.map +2 -2
  14. package/dist/cjs/cli/deploy.js +7 -8
  15. package/dist/cjs/cli/deploy.js.map +2 -2
  16. package/dist/cjs/cli/deploymentCreate.js +225 -40
  17. package/dist/cjs/cli/deploymentCreate.js.map +3 -3
  18. package/dist/cjs/cli/deploymentSelect.js +14 -13
  19. package/dist/cjs/cli/deploymentSelect.js.map +2 -2
  20. package/dist/cjs/cli/dev.js +30 -11
  21. package/dist/cjs/cli/dev.js.map +2 -2
  22. package/dist/cjs/cli/docs.js +1 -1
  23. package/dist/cjs/cli/docs.js.map +2 -2
  24. package/dist/cjs/cli/init.js +1 -1
  25. package/dist/cjs/cli/init.js.map +2 -2
  26. package/dist/cjs/cli/lib/aiFiles/agentsmd.js +14 -10
  27. package/dist/cjs/cli/lib/aiFiles/agentsmd.js.map +2 -2
  28. package/dist/cjs/cli/lib/aiFiles/claudemd.js +14 -10
  29. package/dist/cjs/cli/lib/aiFiles/claudemd.js.map +2 -2
  30. package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js +10 -3
  31. package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js.map +2 -2
  32. package/dist/cjs/cli/lib/aiFiles/index.js +70 -86
  33. package/dist/cjs/cli/lib/aiFiles/index.js.map +3 -3
  34. package/dist/cjs/cli/lib/aiFiles/skills.js +28 -12
  35. package/dist/cjs/cli/lib/aiFiles/skills.js.map +2 -2
  36. package/dist/cjs/cli/lib/aiFiles/state.js +96 -0
  37. package/dist/cjs/cli/lib/aiFiles/state.js.map +7 -0
  38. package/dist/cjs/cli/lib/aiFiles/status.js +31 -28
  39. package/dist/cjs/cli/lib/aiFiles/status.js.map +2 -2
  40. package/dist/cjs/cli/lib/aiFiles/utils.js +31 -14
  41. package/dist/cjs/cli/lib/aiFiles/utils.js.map +2 -2
  42. package/dist/cjs/cli/lib/api.js +70 -7
  43. package/dist/cjs/cli/lib/api.js.map +2 -2
  44. package/dist/cjs/cli/lib/command.js +4 -5
  45. package/dist/cjs/cli/lib/command.js.map +2 -2
  46. package/dist/cjs/cli/lib/config.js +41 -4
  47. package/dist/cjs/cli/lib/config.js.map +3 -3
  48. package/dist/cjs/cli/lib/deploy2.js +9 -26
  49. package/dist/cjs/cli/lib/deploy2.js.map +2 -2
  50. package/dist/cjs/cli/lib/deployApi/componentDefinition.js +4 -1
  51. package/dist/cjs/cli/lib/deployApi/componentDefinition.js.map +2 -2
  52. package/dist/cjs/cli/lib/deploymentSelection.js +45 -2
  53. package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
  54. package/dist/cjs/cli/lib/deploymentSelector.js +1 -0
  55. package/dist/cjs/cli/lib/deploymentSelector.js.map +2 -2
  56. package/dist/cjs/cli/lib/dev.js +162 -117
  57. package/dist/cjs/cli/lib/dev.js.map +2 -2
  58. package/dist/cjs/cli/lib/env.js +1 -13
  59. package/dist/cjs/cli/lib/env.js.map +2 -2
  60. package/dist/cjs/cli/lib/expiration.js +104 -0
  61. package/dist/cjs/cli/lib/expiration.js.map +7 -0
  62. package/dist/cjs/cli/lib/generatedFunctionLogsApi.js.map +1 -1
  63. package/dist/cjs/cli/lib/init.js +4 -3
  64. package/dist/cjs/cli/lib/init.js.map +2 -2
  65. package/dist/cjs/cli/lib/insights.js +1 -1
  66. package/dist/cjs/cli/lib/insights.js.map +2 -2
  67. package/dist/cjs/cli/lib/localDeployment/anonymous.js +14 -7
  68. package/dist/cjs/cli/lib/localDeployment/anonymous.js.map +2 -2
  69. package/dist/cjs/cli/lib/localDeployment/localDeployment.js +8 -10
  70. package/dist/cjs/cli/lib/localDeployment/localDeployment.js.map +2 -2
  71. package/dist/cjs/cli/lib/localDeployment/run.js +1 -0
  72. package/dist/cjs/cli/lib/localDeployment/run.js.map +2 -2
  73. package/dist/cjs/cli/lib/localDeployment/upgrade.js +2 -2
  74. package/dist/cjs/cli/lib/localDeployment/upgrade.js.map +2 -2
  75. package/dist/cjs/cli/lib/localDeployment/utils.js +9 -0
  76. package/dist/cjs/cli/lib/localDeployment/utils.js.map +2 -2
  77. package/dist/cjs/cli/lib/mcp/tools/status.js +1 -1
  78. package/dist/cjs/cli/lib/mcp/tools/status.js.map +2 -2
  79. package/dist/cjs/cli/lib/updates.js +8 -9
  80. package/dist/cjs/cli/lib/updates.js.map +2 -2
  81. package/dist/cjs/cli/lib/usage.js +2 -1
  82. package/dist/cjs/cli/lib/usage.js.map +2 -2
  83. package/dist/cjs/cli/lib/utils/prompts.js +2 -1
  84. package/dist/cjs/cli/lib/utils/prompts.js.map +2 -2
  85. package/dist/cjs/cli/lib/utils/utils.js +46 -20
  86. package/dist/cjs/cli/lib/utils/utils.js.map +3 -3
  87. package/dist/cjs/index.js +1 -1
  88. package/dist/cjs/index.js.map +1 -1
  89. package/dist/cjs/react/client.js +43 -6
  90. package/dist/cjs/react/client.js.map +2 -2
  91. package/dist/cjs/react/index.js +2 -0
  92. package/dist/cjs/react/index.js.map +2 -2
  93. package/dist/cjs/react-clerk/ConvexProviderWithClerk.js.map +1 -1
  94. package/dist/cjs/server/api.js.map +2 -2
  95. package/dist/cjs/server/components/definition.js.map +1 -1
  96. package/dist/cjs/server/components/index.js +40 -4
  97. package/dist/cjs/server/components/index.js.map +2 -2
  98. package/dist/cjs/server/data_model.js.map +1 -1
  99. package/dist/cjs/server/impl/meta_impl.js +78 -0
  100. package/dist/cjs/server/impl/meta_impl.js.map +7 -0
  101. package/dist/cjs/server/impl/registration_impl.js +16 -11
  102. package/dist/cjs/server/impl/registration_impl.js.map +2 -2
  103. package/dist/cjs/server/index.js.map +2 -2
  104. package/dist/cjs/server/meta.js +17 -0
  105. package/dist/cjs/server/meta.js.map +7 -0
  106. package/dist/cjs/server/registration.js.map +1 -1
  107. package/dist/cjs-types/browser/index.d.ts +1 -0
  108. package/dist/cjs-types/browser/index.d.ts.map +1 -1
  109. package/dist/cjs-types/browser/query_options.d.ts +12 -9
  110. package/dist/cjs-types/browser/query_options.d.ts.map +1 -1
  111. package/dist/cjs-types/cli/aiFiles.d.ts.map +1 -1
  112. package/dist/cjs-types/cli/codegen_templates/readme.d.ts.map +1 -1
  113. package/dist/cjs-types/cli/configure.d.ts.map +1 -1
  114. package/dist/cjs-types/cli/configure.test.d.ts +2 -0
  115. package/dist/cjs-types/cli/configure.test.d.ts.map +1 -0
  116. package/dist/cjs-types/cli/deploy.d.ts.map +1 -1
  117. package/dist/cjs-types/cli/deploymentCreate.d.ts +1 -0
  118. package/dist/cjs-types/cli/deploymentCreate.d.ts.map +1 -1
  119. package/dist/cjs-types/cli/deploymentSelect.d.ts +2 -1
  120. package/dist/cjs-types/cli/deploymentSelect.d.ts.map +1 -1
  121. package/dist/cjs-types/cli/dev.d.ts +3 -1
  122. package/dist/cjs-types/cli/dev.d.ts.map +1 -1
  123. package/dist/cjs-types/cli/lib/aiFiles/agentsmd.d.ts +5 -5
  124. package/dist/cjs-types/cli/lib/aiFiles/agentsmd.d.ts.map +1 -1
  125. package/dist/cjs-types/cli/lib/aiFiles/claudemd.d.ts +5 -5
  126. package/dist/cjs-types/cli/lib/aiFiles/claudemd.d.ts.map +1 -1
  127. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts +3 -3
  128. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -1
  129. package/dist/cjs-types/cli/lib/aiFiles/index.d.ts +20 -18
  130. package/dist/cjs-types/cli/lib/aiFiles/index.d.ts.map +1 -1
  131. package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts +6 -4
  132. package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts.map +1 -1
  133. package/dist/cjs-types/cli/lib/aiFiles/state.d.ts +38 -0
  134. package/dist/cjs-types/cli/lib/aiFiles/state.d.ts.map +1 -0
  135. package/dist/cjs-types/cli/lib/aiFiles/state.test.d.ts +2 -0
  136. package/dist/cjs-types/cli/lib/aiFiles/state.test.d.ts.map +1 -0
  137. package/dist/cjs-types/cli/lib/aiFiles/status.d.ts +4 -1
  138. package/dist/cjs-types/cli/lib/aiFiles/status.d.ts.map +1 -1
  139. package/dist/cjs-types/cli/lib/aiFiles/utils.d.ts +13 -3
  140. package/dist/cjs-types/cli/lib/aiFiles/utils.d.ts.map +1 -1
  141. package/dist/cjs-types/cli/lib/aiFiles/utils.test.d.ts +2 -0
  142. package/dist/cjs-types/cli/lib/aiFiles/utils.test.d.ts.map +1 -0
  143. package/dist/cjs-types/cli/lib/api.d.ts +3 -3
  144. package/dist/cjs-types/cli/lib/api.d.ts.map +1 -1
  145. package/dist/cjs-types/cli/lib/command.d.ts +2 -1
  146. package/dist/cjs-types/cli/lib/command.d.ts.map +1 -1
  147. package/dist/cjs-types/cli/lib/config.d.ts +17 -6
  148. package/dist/cjs-types/cli/lib/config.d.ts.map +1 -1
  149. package/dist/cjs-types/cli/lib/deploy2.d.ts +5 -2
  150. package/dist/cjs-types/cli/lib/deploy2.d.ts.map +1 -1
  151. package/dist/cjs-types/cli/lib/deployApi/componentDefinition.d.ts +27 -12
  152. package/dist/cjs-types/cli/lib/deployApi/componentDefinition.d.ts.map +1 -1
  153. package/dist/cjs-types/cli/lib/deployApi/definitionConfig.d.ts +24 -24
  154. package/dist/cjs-types/cli/lib/deployApi/modules.d.ts +14 -14
  155. package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts +61 -52
  156. package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
  157. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  158. package/dist/cjs-types/cli/lib/deploymentSelector.d.ts +2 -0
  159. package/dist/cjs-types/cli/lib/deploymentSelector.d.ts.map +1 -1
  160. package/dist/cjs-types/cli/lib/dev.d.ts.map +1 -1
  161. package/dist/cjs-types/cli/lib/env.d.ts +0 -4
  162. package/dist/cjs-types/cli/lib/env.d.ts.map +1 -1
  163. package/dist/cjs-types/cli/lib/expiration.d.ts +35 -0
  164. package/dist/cjs-types/cli/lib/expiration.d.ts.map +1 -0
  165. package/dist/cjs-types/cli/lib/expiration.test.d.ts +2 -0
  166. package/dist/cjs-types/cli/lib/expiration.test.d.ts.map +1 -0
  167. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts +16 -1
  168. package/dist/cjs-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  169. package/dist/cjs-types/cli/lib/init.d.ts.map +1 -1
  170. package/dist/cjs-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  171. package/dist/cjs-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
  172. package/dist/cjs-types/cli/lib/localDeployment/run.d.ts +15 -0
  173. package/dist/cjs-types/cli/lib/localDeployment/run.d.ts.map +1 -1
  174. package/dist/cjs-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  175. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts +7 -0
  176. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  177. package/dist/cjs-types/cli/lib/mcp/requestContext.d.ts +3 -3
  178. package/dist/cjs-types/cli/lib/mcp/tools/insights.d.ts +2 -2
  179. package/dist/cjs-types/cli/lib/updates.d.ts +4 -3
  180. package/dist/cjs-types/cli/lib/updates.d.ts.map +1 -1
  181. package/dist/cjs-types/cli/lib/usage.d.ts.map +1 -1
  182. package/dist/cjs-types/cli/lib/utils/prompts.d.ts +1 -0
  183. package/dist/cjs-types/cli/lib/utils/prompts.d.ts.map +1 -1
  184. package/dist/cjs-types/cli/lib/utils/utils.d.ts +16 -2
  185. package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
  186. package/dist/cjs-types/index.d.ts +1 -1
  187. package/dist/cjs-types/react/client.d.ts +54 -2
  188. package/dist/cjs-types/react/client.d.ts.map +1 -1
  189. package/dist/cjs-types/react/index.d.ts +7 -2
  190. package/dist/cjs-types/react/index.d.ts.map +1 -1
  191. package/dist/cjs-types/react/use_query_object_options.test.d.ts +5 -0
  192. package/dist/cjs-types/react/use_query_object_options.test.d.ts.map +1 -0
  193. package/dist/cjs-types/react/use_query_result.test.d.ts +5 -0
  194. package/dist/cjs-types/react/use_query_result.test.d.ts.map +1 -0
  195. package/dist/cjs-types/react-clerk/ConvexProviderWithClerk.d.ts +1 -1
  196. package/dist/cjs-types/server/api.d.ts +5 -1
  197. package/dist/cjs-types/server/api.d.ts.map +1 -1
  198. package/dist/cjs-types/server/components/definition.d.ts +1 -0
  199. package/dist/cjs-types/server/components/definition.d.ts.map +1 -1
  200. package/dist/cjs-types/server/components/index.d.ts +5 -1
  201. package/dist/cjs-types/server/components/index.d.ts.map +1 -1
  202. package/dist/cjs-types/server/data_model.d.ts +2 -1
  203. package/dist/cjs-types/server/data_model.d.ts.map +1 -1
  204. package/dist/cjs-types/server/impl/meta_impl.d.ts +5 -0
  205. package/dist/cjs-types/server/impl/meta_impl.d.ts.map +1 -0
  206. package/dist/cjs-types/server/impl/registration_impl.d.ts.map +1 -1
  207. package/dist/cjs-types/server/index.d.ts +1 -0
  208. package/dist/cjs-types/server/index.d.ts.map +1 -1
  209. package/dist/cjs-types/server/meta.d.ts +72 -0
  210. package/dist/cjs-types/server/meta.d.ts.map +1 -0
  211. package/dist/cjs-types/server/registration.d.ts.map +1 -1
  212. package/dist/cli.bundle.cjs +1670 -1214
  213. package/dist/cli.bundle.cjs.map +4 -4
  214. package/dist/esm/browser/index-node.js +1 -0
  215. package/dist/esm/browser/index.js +1 -0
  216. package/dist/esm/browser/index.js.map +2 -2
  217. package/dist/esm/browser/query_options.js.map +2 -2
  218. package/dist/esm/cli/aiFiles.js +33 -15
  219. package/dist/esm/cli/aiFiles.js.map +2 -2
  220. package/dist/esm/cli/codegen_templates/readme.js +14 -1
  221. package/dist/esm/cli/codegen_templates/readme.js.map +2 -2
  222. package/dist/esm/cli/configure.js +23 -26
  223. package/dist/esm/cli/configure.js.map +2 -2
  224. package/dist/esm/cli/deploy.js +11 -10
  225. package/dist/esm/cli/deploy.js.map +2 -2
  226. package/dist/esm/cli/deploymentCreate.js +238 -42
  227. package/dist/esm/cli/deploymentCreate.js.map +2 -2
  228. package/dist/esm/cli/deploymentSelect.js +13 -12
  229. package/dist/esm/cli/deploymentSelect.js.map +2 -2
  230. package/dist/esm/cli/dev.js +34 -13
  231. package/dist/esm/cli/dev.js.map +2 -2
  232. package/dist/esm/cli/docs.js +1 -1
  233. package/dist/esm/cli/docs.js.map +2 -2
  234. package/dist/esm/cli/init.js +2 -2
  235. package/dist/esm/cli/init.js.map +2 -2
  236. package/dist/esm/cli/lib/aiFiles/agentsmd.js +13 -9
  237. package/dist/esm/cli/lib/aiFiles/agentsmd.js.map +2 -2
  238. package/dist/esm/cli/lib/aiFiles/claudemd.js +13 -9
  239. package/dist/esm/cli/lib/aiFiles/claudemd.js.map +2 -2
  240. package/dist/esm/cli/lib/aiFiles/guidelinesmd.js +12 -5
  241. package/dist/esm/cli/lib/aiFiles/guidelinesmd.js.map +2 -2
  242. package/dist/esm/cli/lib/aiFiles/index.js +72 -89
  243. package/dist/esm/cli/lib/aiFiles/index.js.map +2 -2
  244. package/dist/esm/cli/lib/aiFiles/skills.js +29 -13
  245. package/dist/esm/cli/lib/aiFiles/skills.js.map +2 -2
  246. package/dist/esm/cli/lib/aiFiles/state.js +60 -0
  247. package/dist/esm/cli/lib/aiFiles/state.js.map +7 -0
  248. package/dist/esm/cli/lib/aiFiles/status.js +32 -29
  249. package/dist/esm/cli/lib/aiFiles/status.js.map +2 -2
  250. package/dist/esm/cli/lib/aiFiles/utils.js +25 -10
  251. package/dist/esm/cli/lib/aiFiles/utils.js.map +2 -2
  252. package/dist/esm/cli/lib/api.js +70 -7
  253. package/dist/esm/cli/lib/api.js.map +2 -2
  254. package/dist/esm/cli/lib/command.js +4 -5
  255. package/dist/esm/cli/lib/command.js.map +2 -2
  256. package/dist/esm/cli/lib/config.js +39 -3
  257. package/dist/esm/cli/lib/config.js.map +2 -2
  258. package/dist/esm/cli/lib/deploy2.js +13 -26
  259. package/dist/esm/cli/lib/deploy2.js.map +2 -2
  260. package/dist/esm/cli/lib/deployApi/componentDefinition.js +4 -1
  261. package/dist/esm/cli/lib/deployApi/componentDefinition.js.map +2 -2
  262. package/dist/esm/cli/lib/deploymentSelection.js +46 -2
  263. package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
  264. package/dist/esm/cli/lib/deploymentSelector.js +1 -0
  265. package/dist/esm/cli/lib/deploymentSelector.js.map +2 -2
  266. package/dist/esm/cli/lib/dev.js +162 -118
  267. package/dist/esm/cli/lib/dev.js.map +2 -2
  268. package/dist/esm/cli/lib/env.js +0 -11
  269. package/dist/esm/cli/lib/env.js.map +2 -2
  270. package/dist/esm/cli/lib/expiration.js +80 -0
  271. package/dist/esm/cli/lib/expiration.js.map +7 -0
  272. package/dist/esm/cli/lib/init.js +4 -3
  273. package/dist/esm/cli/lib/init.js.map +2 -2
  274. package/dist/esm/cli/lib/insights.js +1 -1
  275. package/dist/esm/cli/lib/insights.js.map +2 -2
  276. package/dist/esm/cli/lib/localDeployment/anonymous.js +16 -9
  277. package/dist/esm/cli/lib/localDeployment/anonymous.js.map +2 -2
  278. package/dist/esm/cli/lib/localDeployment/localDeployment.js +9 -11
  279. package/dist/esm/cli/lib/localDeployment/localDeployment.js.map +2 -2
  280. package/dist/esm/cli/lib/localDeployment/run.js +1 -1
  281. package/dist/esm/cli/lib/localDeployment/run.js.map +2 -2
  282. package/dist/esm/cli/lib/localDeployment/upgrade.js +2 -2
  283. package/dist/esm/cli/lib/localDeployment/upgrade.js.map +2 -2
  284. package/dist/esm/cli/lib/localDeployment/utils.js +8 -0
  285. package/dist/esm/cli/lib/localDeployment/utils.js.map +2 -2
  286. package/dist/esm/cli/lib/mcp/tools/status.js +1 -1
  287. package/dist/esm/cli/lib/mcp/tools/status.js.map +2 -2
  288. package/dist/esm/cli/lib/updates.js +11 -9
  289. package/dist/esm/cli/lib/updates.js.map +2 -2
  290. package/dist/esm/cli/lib/usage.js +2 -1
  291. package/dist/esm/cli/lib/usage.js.map +2 -2
  292. package/dist/esm/cli/lib/utils/prompts.js +2 -1
  293. package/dist/esm/cli/lib/utils/prompts.js.map +2 -2
  294. package/dist/esm/cli/lib/utils/utils.js +45 -20
  295. package/dist/esm/cli/lib/utils/utils.js.map +3 -3
  296. package/dist/esm/index.js +1 -1
  297. package/dist/esm/index.js.map +1 -1
  298. package/dist/esm/react/client.js +43 -6
  299. package/dist/esm/react/client.js.map +2 -2
  300. package/dist/esm/react/index.js +1 -0
  301. package/dist/esm/react/index.js.map +2 -2
  302. package/dist/esm/react-clerk/ConvexProviderWithClerk.js.map +1 -1
  303. package/dist/esm/server/api.js.map +2 -2
  304. package/dist/esm/server/components/index.js +40 -4
  305. package/dist/esm/server/components/index.js.map +2 -2
  306. package/dist/esm/server/impl/meta_impl.js +54 -0
  307. package/dist/esm/server/impl/meta_impl.js.map +7 -0
  308. package/dist/esm/server/impl/registration_impl.js +20 -11
  309. package/dist/esm/server/impl/registration_impl.js.map +2 -2
  310. package/dist/esm/server/index.js.map +2 -2
  311. package/dist/esm/server/meta.js +2 -0
  312. package/dist/esm/server/meta.js.map +7 -0
  313. package/dist/esm-types/browser/index.d.ts +1 -0
  314. package/dist/esm-types/browser/index.d.ts.map +1 -1
  315. package/dist/esm-types/browser/query_options.d.ts +12 -9
  316. package/dist/esm-types/browser/query_options.d.ts.map +1 -1
  317. package/dist/esm-types/cli/aiFiles.d.ts.map +1 -1
  318. package/dist/esm-types/cli/codegen_templates/readme.d.ts.map +1 -1
  319. package/dist/esm-types/cli/configure.d.ts.map +1 -1
  320. package/dist/esm-types/cli/configure.test.d.ts +2 -0
  321. package/dist/esm-types/cli/configure.test.d.ts.map +1 -0
  322. package/dist/esm-types/cli/deploy.d.ts.map +1 -1
  323. package/dist/esm-types/cli/deploymentCreate.d.ts +1 -0
  324. package/dist/esm-types/cli/deploymentCreate.d.ts.map +1 -1
  325. package/dist/esm-types/cli/deploymentSelect.d.ts +2 -1
  326. package/dist/esm-types/cli/deploymentSelect.d.ts.map +1 -1
  327. package/dist/esm-types/cli/dev.d.ts +3 -1
  328. package/dist/esm-types/cli/dev.d.ts.map +1 -1
  329. package/dist/esm-types/cli/lib/aiFiles/agentsmd.d.ts +5 -5
  330. package/dist/esm-types/cli/lib/aiFiles/agentsmd.d.ts.map +1 -1
  331. package/dist/esm-types/cli/lib/aiFiles/claudemd.d.ts +5 -5
  332. package/dist/esm-types/cli/lib/aiFiles/claudemd.d.ts.map +1 -1
  333. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts +3 -3
  334. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -1
  335. package/dist/esm-types/cli/lib/aiFiles/index.d.ts +20 -18
  336. package/dist/esm-types/cli/lib/aiFiles/index.d.ts.map +1 -1
  337. package/dist/esm-types/cli/lib/aiFiles/skills.d.ts +6 -4
  338. package/dist/esm-types/cli/lib/aiFiles/skills.d.ts.map +1 -1
  339. package/dist/esm-types/cli/lib/aiFiles/state.d.ts +38 -0
  340. package/dist/esm-types/cli/lib/aiFiles/state.d.ts.map +1 -0
  341. package/dist/esm-types/cli/lib/aiFiles/state.test.d.ts +2 -0
  342. package/dist/esm-types/cli/lib/aiFiles/state.test.d.ts.map +1 -0
  343. package/dist/esm-types/cli/lib/aiFiles/status.d.ts +4 -1
  344. package/dist/esm-types/cli/lib/aiFiles/status.d.ts.map +1 -1
  345. package/dist/esm-types/cli/lib/aiFiles/utils.d.ts +13 -3
  346. package/dist/esm-types/cli/lib/aiFiles/utils.d.ts.map +1 -1
  347. package/dist/esm-types/cli/lib/aiFiles/utils.test.d.ts +2 -0
  348. package/dist/esm-types/cli/lib/aiFiles/utils.test.d.ts.map +1 -0
  349. package/dist/esm-types/cli/lib/api.d.ts +3 -3
  350. package/dist/esm-types/cli/lib/api.d.ts.map +1 -1
  351. package/dist/esm-types/cli/lib/command.d.ts +2 -1
  352. package/dist/esm-types/cli/lib/command.d.ts.map +1 -1
  353. package/dist/esm-types/cli/lib/config.d.ts +17 -6
  354. package/dist/esm-types/cli/lib/config.d.ts.map +1 -1
  355. package/dist/esm-types/cli/lib/deploy2.d.ts +5 -2
  356. package/dist/esm-types/cli/lib/deploy2.d.ts.map +1 -1
  357. package/dist/esm-types/cli/lib/deployApi/componentDefinition.d.ts +27 -12
  358. package/dist/esm-types/cli/lib/deployApi/componentDefinition.d.ts.map +1 -1
  359. package/dist/esm-types/cli/lib/deployApi/definitionConfig.d.ts +24 -24
  360. package/dist/esm-types/cli/lib/deployApi/modules.d.ts +14 -14
  361. package/dist/esm-types/cli/lib/deployApi/startPush.d.ts +61 -52
  362. package/dist/esm-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
  363. package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  364. package/dist/esm-types/cli/lib/deploymentSelector.d.ts +2 -0
  365. package/dist/esm-types/cli/lib/deploymentSelector.d.ts.map +1 -1
  366. package/dist/esm-types/cli/lib/dev.d.ts.map +1 -1
  367. package/dist/esm-types/cli/lib/env.d.ts +0 -4
  368. package/dist/esm-types/cli/lib/env.d.ts.map +1 -1
  369. package/dist/esm-types/cli/lib/expiration.d.ts +35 -0
  370. package/dist/esm-types/cli/lib/expiration.d.ts.map +1 -0
  371. package/dist/esm-types/cli/lib/expiration.test.d.ts +2 -0
  372. package/dist/esm-types/cli/lib/expiration.test.d.ts.map +1 -0
  373. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts +16 -1
  374. package/dist/esm-types/cli/lib/generatedFunctionLogsApi.d.ts.map +1 -1
  375. package/dist/esm-types/cli/lib/init.d.ts.map +1 -1
  376. package/dist/esm-types/cli/lib/localDeployment/anonymous.d.ts.map +1 -1
  377. package/dist/esm-types/cli/lib/localDeployment/localDeployment.d.ts.map +1 -1
  378. package/dist/esm-types/cli/lib/localDeployment/run.d.ts +15 -0
  379. package/dist/esm-types/cli/lib/localDeployment/run.d.ts.map +1 -1
  380. package/dist/esm-types/cli/lib/localDeployment/upgrade.d.ts.map +1 -1
  381. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts +7 -0
  382. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  383. package/dist/esm-types/cli/lib/mcp/requestContext.d.ts +3 -3
  384. package/dist/esm-types/cli/lib/mcp/tools/insights.d.ts +2 -2
  385. package/dist/esm-types/cli/lib/updates.d.ts +4 -3
  386. package/dist/esm-types/cli/lib/updates.d.ts.map +1 -1
  387. package/dist/esm-types/cli/lib/usage.d.ts.map +1 -1
  388. package/dist/esm-types/cli/lib/utils/prompts.d.ts +1 -0
  389. package/dist/esm-types/cli/lib/utils/prompts.d.ts.map +1 -1
  390. package/dist/esm-types/cli/lib/utils/utils.d.ts +16 -2
  391. package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
  392. package/dist/esm-types/index.d.ts +1 -1
  393. package/dist/esm-types/react/client.d.ts +54 -2
  394. package/dist/esm-types/react/client.d.ts.map +1 -1
  395. package/dist/esm-types/react/index.d.ts +7 -2
  396. package/dist/esm-types/react/index.d.ts.map +1 -1
  397. package/dist/esm-types/react/use_query_object_options.test.d.ts +5 -0
  398. package/dist/esm-types/react/use_query_object_options.test.d.ts.map +1 -0
  399. package/dist/esm-types/react/use_query_result.test.d.ts +5 -0
  400. package/dist/esm-types/react/use_query_result.test.d.ts.map +1 -0
  401. package/dist/esm-types/react-clerk/ConvexProviderWithClerk.d.ts +1 -1
  402. package/dist/esm-types/server/api.d.ts +5 -1
  403. package/dist/esm-types/server/api.d.ts.map +1 -1
  404. package/dist/esm-types/server/components/definition.d.ts +1 -0
  405. package/dist/esm-types/server/components/definition.d.ts.map +1 -1
  406. package/dist/esm-types/server/components/index.d.ts +5 -1
  407. package/dist/esm-types/server/components/index.d.ts.map +1 -1
  408. package/dist/esm-types/server/data_model.d.ts +2 -1
  409. package/dist/esm-types/server/data_model.d.ts.map +1 -1
  410. package/dist/esm-types/server/impl/meta_impl.d.ts +5 -0
  411. package/dist/esm-types/server/impl/meta_impl.d.ts.map +1 -0
  412. package/dist/esm-types/server/impl/registration_impl.d.ts.map +1 -1
  413. package/dist/esm-types/server/index.d.ts +1 -0
  414. package/dist/esm-types/server/index.d.ts.map +1 -1
  415. package/dist/esm-types/server/meta.d.ts +72 -0
  416. package/dist/esm-types/server/meta.d.ts.map +1 -0
  417. package/dist/esm-types/server/registration.d.ts.map +1 -1
  418. package/dist/react.bundle.js +50 -7
  419. package/dist/react.bundle.js.map +3 -3
  420. package/package.json +11 -7
  421. package/schemas/convex.schema.json +15 -2
  422. package/src/browser/index.ts +3 -0
  423. package/src/browser/query_options.test.ts +0 -9
  424. package/src/browser/query_options.ts +36 -15
  425. package/src/cli/aiFiles.ts +44 -14
  426. package/src/cli/codegen_templates/readme.ts +14 -1
  427. package/src/cli/configure.test.ts +138 -0
  428. package/src/cli/configure.ts +48 -47
  429. package/src/cli/deploy.ts +12 -9
  430. package/src/cli/deploymentCreate.test.ts +349 -14
  431. package/src/cli/deploymentCreate.ts +268 -41
  432. package/src/cli/deploymentSelect.test.ts +136 -27
  433. package/src/cli/deploymentSelect.ts +50 -41
  434. package/src/cli/deploymentSelection.test.ts +343 -35
  435. package/src/cli/dev.ts +49 -14
  436. package/src/cli/docs.ts +1 -1
  437. package/src/cli/init.ts +2 -2
  438. package/src/cli/lib/aiFiles/agentsmd.ts +15 -11
  439. package/src/cli/lib/aiFiles/claudemd.ts +15 -11
  440. package/src/cli/lib/aiFiles/guidelinesmd.test.ts +12 -2
  441. package/src/cli/lib/aiFiles/guidelinesmd.ts +15 -7
  442. package/src/cli/lib/aiFiles/index.test.ts +188 -222
  443. package/src/cli/lib/aiFiles/index.ts +119 -125
  444. package/src/cli/lib/aiFiles/integration.test.ts +112 -45
  445. package/src/cli/lib/aiFiles/prompt.test.ts +6 -6
  446. package/src/cli/lib/aiFiles/skills.ts +46 -16
  447. package/src/cli/lib/aiFiles/state.test.ts +280 -0
  448. package/src/cli/lib/aiFiles/state.ts +82 -0
  449. package/src/cli/lib/aiFiles/status.ts +45 -39
  450. package/src/cli/lib/aiFiles/utils.test.ts +50 -0
  451. package/src/cli/lib/aiFiles/utils.ts +38 -10
  452. package/src/cli/lib/api.ts +88 -7
  453. package/src/cli/lib/command.ts +12 -7
  454. package/src/cli/lib/config.test.ts +184 -7
  455. package/src/cli/lib/config.ts +67 -7
  456. package/src/cli/lib/deploy2.ts +14 -27
  457. package/src/cli/lib/deployApi/componentDefinition.ts +4 -1
  458. package/src/cli/lib/deploymentSelection.ts +59 -6
  459. package/src/cli/lib/deploymentSelector.test.ts +6 -0
  460. package/src/cli/lib/deploymentSelector.ts +2 -0
  461. package/src/cli/lib/dev.ts +202 -153
  462. package/src/cli/lib/env.ts +0 -15
  463. package/src/cli/lib/expiration.test.ts +159 -0
  464. package/src/cli/lib/expiration.ts +124 -0
  465. package/src/cli/lib/generatedFunctionLogsApi.ts +16 -1
  466. package/src/cli/lib/init.ts +6 -2
  467. package/src/cli/lib/insights.ts +1 -1
  468. package/src/cli/lib/localDeployment/anonymous.ts +19 -9
  469. package/src/cli/lib/localDeployment/localDeployment.ts +9 -11
  470. package/src/cli/lib/localDeployment/run.ts +1 -1
  471. package/src/cli/lib/localDeployment/upgrade.ts +12 -10
  472. package/src/cli/lib/localDeployment/utils.ts +12 -0
  473. package/src/cli/lib/mcp/tools/status.ts +1 -1
  474. package/src/cli/lib/updates.test.ts +102 -75
  475. package/src/cli/lib/updates.ts +14 -12
  476. package/src/cli/lib/usage.ts +3 -1
  477. package/src/cli/lib/utils/prompts.ts +2 -0
  478. package/src/cli/lib/utils/utils.test.ts +6 -6
  479. package/src/cli/lib/utils/utils.ts +66 -27
  480. package/src/index.ts +1 -1
  481. package/src/react/client.test.tsx +65 -0
  482. package/src/react/client.ts +129 -13
  483. package/src/react/index.ts +9 -1
  484. package/src/react/use_query_object_options.test.ts +50 -0
  485. package/src/react/use_query_result.test.ts +41 -0
  486. package/src/react-clerk/ConvexProviderWithClerk.test.tsx +1 -1
  487. package/src/react-clerk/ConvexProviderWithClerk.tsx +1 -1
  488. package/src/server/api.ts +5 -1
  489. package/src/server/components/definition.ts +3 -0
  490. package/src/server/components/index.ts +62 -5
  491. package/src/server/data_model.ts +2 -1
  492. package/src/server/impl/meta_impl.ts +74 -0
  493. package/src/server/impl/registration_impl.ts +21 -9
  494. package/src/server/index.ts +8 -0
  495. package/src/server/meta.ts +76 -0
  496. package/src/server/registration.ts +10 -0
  497. package/src/server/schema.test.ts +78 -1
  498. package/dist/cjs/cli/lib/aiFiles/config.js +0 -171
  499. package/dist/cjs/cli/lib/aiFiles/config.js.map +0 -7
  500. package/dist/cjs-types/cli/lib/aiFiles/config.d.ts +0 -46
  501. package/dist/cjs-types/cli/lib/aiFiles/config.d.ts.map +0 -1
  502. package/dist/cjs-types/cli/lib/aiFiles/config.test.d.ts +0 -2
  503. package/dist/cjs-types/cli/lib/aiFiles/config.test.d.ts.map +0 -1
  504. package/dist/esm/cli/lib/aiFiles/config.js +0 -135
  505. package/dist/esm/cli/lib/aiFiles/config.js.map +0 -7
  506. package/dist/esm-types/cli/lib/aiFiles/config.d.ts +0 -46
  507. package/dist/esm-types/cli/lib/aiFiles/config.d.ts.map +0 -1
  508. package/dist/esm-types/cli/lib/aiFiles/config.test.d.ts +0 -2
  509. package/dist/esm-types/cli/lib/aiFiles/config.test.d.ts.map +0 -1
  510. package/src/cli/lib/aiFiles/config.test.ts +0 -460
  511. package/src/cli/lib/aiFiles/config.ts +0 -188
  512. package/src/values/.claude/settings.local.json +0 -10
@@ -1,10 +1,10 @@
1
1
  import { describe, test, expect, vi, beforeEach, afterEach } from "vitest";
2
2
  import { logMessage } from "../../../bundler/log.js";
3
3
  import {
4
- readAiConfig,
5
- writeAiConfig,
6
- writeAiEnabledToProjectConfig,
7
- } from "./config.js";
4
+ attemptReadAiState,
5
+ readAiStateOrDefault,
6
+ writeAiState,
7
+ } from "./state.js";
8
8
  import {
9
9
  downloadGuidelines,
10
10
  fetchAgentSkillsSha,
@@ -14,10 +14,9 @@ import fs from "fs";
14
14
  import os from "os";
15
15
  import path from "path";
16
16
  import {
17
- checkAiFilesStaleness,
17
+ checkAiFilesStalenessAndLog,
18
18
  installAiFiles,
19
19
  removeAiFiles,
20
- safelyAttemptToDisableAiFiles,
21
20
  } from "./index.js";
22
21
  import { statusAiFiles } from "./status.js";
23
22
  import {
@@ -42,10 +41,11 @@ vi.mock("../../../bundler/log.js", () => ({
42
41
  logMessage: vi.fn(),
43
42
  }));
44
43
 
45
- vi.mock("./config.js", () => ({
46
- readAiConfig: vi.fn(),
47
- writeAiConfig: vi.fn(),
48
- writeAiEnabledToProjectConfig: vi.fn(),
44
+ vi.mock("./state.js", () => ({
45
+ attemptReadAiState: vi.fn(),
46
+ readAiStateOrDefault: vi.fn(),
47
+ writeAiState: vi.fn(),
48
+ hasAiState: vi.fn().mockResolvedValue(false),
49
49
  }));
50
50
 
51
51
  vi.mock("../versionApi.js", () => ({
@@ -69,23 +69,20 @@ vi.mock("child_process", () => ({
69
69
  }));
70
70
 
71
71
  const mockLogMessage = vi.mocked(logMessage);
72
- const mockReadAiConfig = vi.mocked(readAiConfig);
73
- const mockWriteAiConfig = vi.mocked(writeAiConfig);
74
- const mockWriteAiEnabledToProjectConfig = vi.mocked(
75
- writeAiEnabledToProjectConfig,
76
- );
72
+ const mockAttemptReadAiState = vi.mocked(attemptReadAiState);
73
+ const mockReadAiStateOrDefault = vi.mocked(readAiStateOrDefault);
74
+ const mockWriteAiState = vi.mocked(writeAiState);
77
75
  const mockDownloadGuidelines = vi.mocked(downloadGuidelines);
78
76
  const mockFetchAgentSkillsSha = vi.mocked(fetchAgentSkillsSha);
79
77
  const mockGetVersion = vi.mocked(getVersion);
80
78
 
81
- /** Minimal valid config used across tests; includes all required fields. */
82
- const baseConfig = {
79
+ /** Minimal valid state used across tests; includes all required fields. */
80
+ const baseState = {
83
81
  guidelinesHash: null,
84
82
  agentsMdSectionHash: null,
85
83
  claudeMdHash: null,
86
84
  agentSkillsSha: null,
87
85
  installedSkillNames: [] as string[],
88
- enabled: true,
89
86
  };
90
87
 
91
88
  // ---------------------------------------------------------------------------
@@ -93,7 +90,9 @@ const baseConfig = {
93
90
  // ---------------------------------------------------------------------------
94
91
 
95
92
  describe("checkAiFilesStaleness", () => {
96
- beforeEach(() => vi.clearAllMocks());
93
+ beforeEach(() => {
94
+ vi.clearAllMocks();
95
+ });
97
96
  afterEach(() => {
98
97
  vi.unstubAllEnvs();
99
98
  vi.resetAllMocks();
@@ -103,16 +102,16 @@ describe("checkAiFilesStaleness", () => {
103
102
  const dummyConvexDir = "/tmp/test-project/convex";
104
103
 
105
104
  test("logs install nudge when no state file exists, even with null canonical values", async () => {
106
- mockReadAiConfig.mockResolvedValue(null);
105
+ mockAttemptReadAiState.mockResolvedValue({ kind: "no-file" });
107
106
 
108
- await checkAiFilesStaleness({
107
+ await checkAiFilesStalenessAndLog({
109
108
  canonicalGuidelinesHash: null,
110
109
  canonicalAgentSkillsSha: null,
111
110
  projectDir: dummyProjectDir,
112
111
  convexDir: dummyConvexDir,
113
112
  });
114
113
 
115
- expect(mockReadAiConfig).toHaveBeenCalled();
114
+ expect(mockAttemptReadAiState).toHaveBeenCalled();
116
115
  expect(mockLogMessage).toHaveBeenCalledWith(
117
116
  expect.stringContaining("npx convex ai-files install"),
118
117
  );
@@ -121,13 +120,13 @@ describe("checkAiFilesStaleness", () => {
121
120
  );
122
121
  });
123
122
 
124
- test("does nothing when both canonical values are null but config exists (version server unavailable)", async () => {
125
- mockReadAiConfig.mockResolvedValue({
126
- ...baseConfig,
127
- guidelinesHash: "some-hash",
123
+ test("does nothing when both canonical values are null but state exists (version server unavailable)", async () => {
124
+ mockAttemptReadAiState.mockResolvedValue({
125
+ kind: "ok",
126
+ state: { ...baseState, guidelinesHash: "some-hash" },
128
127
  });
129
128
 
130
- await checkAiFilesStaleness({
129
+ await checkAiFilesStalenessAndLog({
131
130
  canonicalGuidelinesHash: null,
132
131
  canonicalAgentSkillsSha: null,
133
132
  projectDir: dummyProjectDir,
@@ -138,9 +137,9 @@ describe("checkAiFilesStaleness", () => {
138
137
  });
139
138
 
140
139
  test("logs install nudge when no state file exists, even if canonical hashes are available", async () => {
141
- mockReadAiConfig.mockResolvedValue(null);
140
+ mockAttemptReadAiState.mockResolvedValue({ kind: "no-file" });
142
141
 
143
- await checkAiFilesStaleness({
142
+ await checkAiFilesStalenessAndLog({
144
143
  canonicalGuidelinesHash: "canonical-hash",
145
144
  canonicalAgentSkillsSha: null,
146
145
  projectDir: dummyProjectDir,
@@ -159,14 +158,12 @@ describe("checkAiFilesStaleness", () => {
159
158
  });
160
159
 
161
160
  test("does nothing when config has enabled=false (user opted out)", async () => {
162
- mockReadAiConfig.mockResolvedValue({
163
- ...baseConfig,
164
- enabled: false,
165
- });
161
+ mockAttemptReadAiState.mockResolvedValue({ kind: "no-file" });
166
162
 
167
- await checkAiFilesStaleness({
163
+ await checkAiFilesStalenessAndLog({
168
164
  canonicalGuidelinesHash: "canonical-hash",
169
165
  canonicalAgentSkillsSha: null,
166
+ aiFilesConfig: { enabled: false },
170
167
  projectDir: dummyProjectDir,
171
168
  convexDir: dummyConvexDir,
172
169
  });
@@ -175,12 +172,12 @@ describe("checkAiFilesStaleness", () => {
175
172
  });
176
173
 
177
174
  test("does nothing when stored guidelines hash matches canonical", async () => {
178
- mockReadAiConfig.mockResolvedValue({
179
- ...baseConfig,
180
- guidelinesHash: "same-hash",
175
+ mockAttemptReadAiState.mockResolvedValue({
176
+ kind: "ok",
177
+ state: { ...baseState, guidelinesHash: "same-hash" },
181
178
  });
182
179
 
183
- await checkAiFilesStaleness({
180
+ await checkAiFilesStalenessAndLog({
184
181
  canonicalGuidelinesHash: "same-hash",
185
182
  canonicalAgentSkillsSha: null,
186
183
  projectDir: dummyProjectDir,
@@ -191,12 +188,12 @@ describe("checkAiFilesStaleness", () => {
191
188
  });
192
189
 
193
190
  test("logs nag message when guidelines hash is stale", async () => {
194
- mockReadAiConfig.mockResolvedValue({
195
- ...baseConfig,
196
- guidelinesHash: "old-hash",
191
+ mockAttemptReadAiState.mockResolvedValue({
192
+ kind: "ok",
193
+ state: { ...baseState, guidelinesHash: "old-hash" },
197
194
  });
198
195
 
199
- await checkAiFilesStaleness({
196
+ await checkAiFilesStalenessAndLog({
200
197
  canonicalGuidelinesHash: "new-canonical-hash",
201
198
  canonicalAgentSkillsSha: null,
202
199
  projectDir: dummyProjectDir,
@@ -209,13 +206,16 @@ describe("checkAiFilesStaleness", () => {
209
206
  });
210
207
 
211
208
  test("logs nag message when agent skills SHA is stale", async () => {
212
- mockReadAiConfig.mockResolvedValue({
213
- ...baseConfig,
214
- guidelinesHash: "current-hash",
215
- agentSkillsSha: "old-sha",
209
+ mockAttemptReadAiState.mockResolvedValue({
210
+ kind: "ok",
211
+ state: {
212
+ ...baseState,
213
+ guidelinesHash: "current-hash",
214
+ agentSkillsSha: "old-sha",
215
+ },
216
216
  });
217
217
 
218
- await checkAiFilesStaleness({
218
+ await checkAiFilesStalenessAndLog({
219
219
  canonicalGuidelinesHash: "current-hash",
220
220
  canonicalAgentSkillsSha: "new-sha",
221
221
  projectDir: dummyProjectDir,
@@ -228,9 +228,12 @@ describe("checkAiFilesStaleness", () => {
228
228
  });
229
229
 
230
230
  test("does nothing when stored guidelinesHash is null (never written)", async () => {
231
- mockReadAiConfig.mockResolvedValue(baseConfig);
231
+ mockAttemptReadAiState.mockResolvedValue({
232
+ kind: "ok",
233
+ state: baseState,
234
+ });
232
235
 
233
- await checkAiFilesStaleness({
236
+ await checkAiFilesStalenessAndLog({
234
237
  canonicalGuidelinesHash: "some-hash",
235
238
  canonicalAgentSkillsSha: "some-sha",
236
239
  projectDir: dummyProjectDir,
@@ -261,8 +264,8 @@ describe("installAiFiles", () => {
261
264
  });
262
265
  afterEach(() => vi.resetAllMocks());
263
266
 
264
- test("runs full init and installs skills when no config exists", async () => {
265
- mockReadAiConfig.mockResolvedValue(null);
267
+ test("runs full init and installs skills when no state exists", async () => {
268
+ mockReadAiStateOrDefault.mockResolvedValue(baseState);
266
269
 
267
270
  const tmpDir = fs.mkdtempSync(`${os.tmpdir()}${path.sep}`);
268
271
  const convexDir = path.join(tmpDir, "convex");
@@ -309,16 +312,16 @@ describe("installAiFiles", () => {
309
312
  }
310
313
 
311
314
  mockDownloadGuidelines.mockResolvedValue(null);
312
- mockReadAiConfig.mockResolvedValue({
313
- ...baseConfig,
315
+ mockReadAiStateOrDefault.mockResolvedValue({
316
+ ...baseState,
314
317
  agentSkillsSha: "old-sha",
315
318
  });
316
319
 
317
320
  await installAiFiles({ projectDir: tmpDir, convexDir });
318
321
 
319
- expect(mockWriteAiConfig).toHaveBeenCalledWith(
322
+ expect(mockWriteAiState).toHaveBeenCalledWith(
320
323
  expect.objectContaining({
321
- config: expect.objectContaining({
324
+ state: expect.objectContaining({
322
325
  agentSkillsSha: "canonical-sha-abc123",
323
326
  installedSkillNames: ["migration-helper", "schema-builder"],
324
327
  }),
@@ -329,71 +332,11 @@ describe("installAiFiles", () => {
329
332
  }
330
333
  });
331
334
 
332
- test("update does not clear enabled=false when set", async () => {
333
- const tmpDir = fs.mkdtempSync(`${os.tmpdir()}${path.sep}`);
334
- const convexDir = path.join(tmpDir, "convex");
335
- try {
336
- mockReadAiConfig.mockResolvedValue({
337
- ...baseConfig,
338
- enabled: false,
339
- });
340
- mockDownloadGuidelines.mockResolvedValue(null);
341
-
342
- await installAiFiles({ projectDir: tmpDir, convexDir });
343
-
344
- expect(mockWriteAiConfig).toHaveBeenCalledWith(
345
- expect.objectContaining({
346
- config: expect.objectContaining({ enabled: false }),
347
- }),
348
- );
349
- } finally {
350
- fs.rmSync(tmpDir, { recursive: true, force: true });
351
- }
352
- });
353
-
354
- test("update recreates convex/_generated/ai when only disable config exists", async () => {
355
- const tmpDir = fs.mkdtempSync(`${os.tmpdir()}${path.sep}`);
356
- const convexDir = path.join(tmpDir, "convex");
357
- try {
358
- fs.mkdirSync(convexDir, { recursive: true });
359
- fs.writeFileSync(path.join(convexDir, "schema.ts"), "");
360
- fs.writeFileSync(path.join(tmpDir, "convex.json"), "{}");
361
- mockReadAiConfig.mockResolvedValue({
362
- ...baseConfig,
363
- enabled: false,
364
- guidelinesHash: null,
365
- });
366
- mockDownloadGuidelines.mockResolvedValue("fresh guidelines");
367
-
368
- await installAiFiles({ projectDir: tmpDir, convexDir });
369
-
370
- expect(fs.existsSync(path.join(convexDir, "_generated", "ai"))).toBe(
371
- true,
372
- );
373
- expect(
374
- fs.existsSync(
375
- path.join(convexDir, "_generated", "ai", "guidelines.md"),
376
- ),
377
- ).toBe(true);
378
- expect(mockWriteAiConfig).toHaveBeenCalledWith(
379
- expect.objectContaining({
380
- config: expect.objectContaining({
381
- enabled: false,
382
- guidelinesHash: expect.any(String),
383
- }),
384
- projectDir: tmpDir,
385
- }),
386
- );
387
- } finally {
388
- fs.rmSync(tmpDir, { recursive: true, force: true });
389
- }
390
- });
391
-
392
335
  test("logs warning when guidelines download is unavailable", async () => {
393
336
  const tmpDir = fs.mkdtempSync(`${os.tmpdir()}${path.sep}`);
394
337
  const convexDir = path.join(tmpDir, "convex");
395
338
  try {
396
- mockReadAiConfig.mockResolvedValue(baseConfig);
339
+ mockReadAiStateOrDefault.mockResolvedValue(baseState);
397
340
  mockDownloadGuidelines.mockResolvedValue(null);
398
341
 
399
342
  await installAiFiles({ projectDir: tmpDir, convexDir });
@@ -410,7 +353,7 @@ describe("installAiFiles", () => {
410
353
  const tmpDir = fs.mkdtempSync(`${os.tmpdir()}${path.sep}`);
411
354
  const convexDir = path.join(tmpDir, "convex");
412
355
  try {
413
- mockReadAiConfig.mockResolvedValue(baseConfig);
356
+ mockReadAiStateOrDefault.mockResolvedValue(baseState);
414
357
  mockDownloadGuidelines.mockResolvedValue("guidelines content");
415
358
  mockGetVersion.mockResolvedValue({
416
359
  kind: "ok",
@@ -470,28 +413,33 @@ describe("removeAiFiles", () => {
470
413
  vi.resetAllMocks();
471
414
  });
472
415
 
473
- function writeConfig(override: Partial<typeof baseConfig> = {}) {
474
- const config = { ...baseConfig, ...override };
475
- fs.writeFileSync(
476
- path.join(tmpDir, "convex", "_generated", "ai", "ai-files.state.json"),
477
- JSON.stringify(config, null, 2) + "\n",
478
- "utf8",
416
+ test("logs nothing-to-remove when no state and no artifacts exist", async () => {
417
+ mockAttemptReadAiState.mockResolvedValue({ kind: "no-file" });
418
+ fs.rmSync(path.join(convexDir, "_generated", "ai"), { recursive: true });
419
+
420
+ await removeAiFiles({ projectDir: tmpDir, convexDir });
421
+
422
+ expect(mockLogMessage).toHaveBeenCalledWith(
423
+ expect.stringContaining("nothing to remove"),
479
424
  );
480
- }
425
+ });
481
426
 
482
- test("logs nothing-to-remove when no config exists", async () => {
483
- mockReadAiConfig.mockResolvedValue(null);
427
+ test("removes ai dir even when no state file exists", async () => {
428
+ mockAttemptReadAiState.mockResolvedValue({ kind: "no-file" });
484
429
 
485
430
  await removeAiFiles({ projectDir: tmpDir, convexDir });
486
431
 
487
432
  expect(mockLogMessage).toHaveBeenCalledWith(
488
- expect.stringContaining("nothing to remove"),
433
+ expect.stringContaining("Convex AI files removed"),
489
434
  );
435
+ expect(fs.existsSync(path.join(convexDir, "_generated", "ai"))).toBe(false);
490
436
  });
491
437
 
492
438
  test("deletes AGENTS.md if stripping the Convex section leaves it empty", async () => {
493
- writeConfig();
494
- mockReadAiConfig.mockResolvedValue(baseConfig);
439
+ mockAttemptReadAiState.mockResolvedValue({
440
+ kind: "ok",
441
+ state: baseState,
442
+ });
495
443
 
496
444
  const agentsMdContent = `${AGENTS_MD_START_MARKER}\n## Convex\nGuidelines.\n${AGENTS_MD_END_MARKER}\n`;
497
445
  fs.writeFileSync(path.join(tmpDir, "AGENTS.md"), agentsMdContent, "utf8");
@@ -502,8 +450,10 @@ describe("removeAiFiles", () => {
502
450
  });
503
451
 
504
452
  test("strips Convex section from AGENTS.md", async () => {
505
- writeConfig();
506
- mockReadAiConfig.mockResolvedValue(baseConfig);
453
+ mockAttemptReadAiState.mockResolvedValue({
454
+ kind: "ok",
455
+ state: baseState,
456
+ });
507
457
 
508
458
  const agentsMdContent =
509
459
  `# My project\n\n` +
@@ -521,8 +471,10 @@ describe("removeAiFiles", () => {
521
471
  });
522
472
 
523
473
  test("deletes CLAUDE.md when it only contains the managed section", async () => {
524
- writeConfig();
525
- mockReadAiConfig.mockResolvedValue(baseConfig);
474
+ mockAttemptReadAiState.mockResolvedValue({
475
+ kind: "ok",
476
+ state: baseState,
477
+ });
526
478
  const managed = `${CLAUDE_MD_START_MARKER}\n## Convex\nRead guidelines.\n${CLAUDE_MD_END_MARKER}\n`;
527
479
  fs.writeFileSync(path.join(tmpDir, "CLAUDE.md"), managed, "utf8");
528
480
 
@@ -532,8 +484,10 @@ describe("removeAiFiles", () => {
532
484
  });
533
485
 
534
486
  test("leaves CLAUDE.md when it has no managed markers", async () => {
535
- writeConfig();
536
- mockReadAiConfig.mockResolvedValue(baseConfig);
487
+ mockAttemptReadAiState.mockResolvedValue({
488
+ kind: "ok",
489
+ state: baseState,
490
+ });
537
491
 
538
492
  fs.writeFileSync(path.join(tmpDir, "CLAUDE.md"), "User content\n", "utf8");
539
493
 
@@ -543,8 +497,10 @@ describe("removeAiFiles", () => {
543
497
  });
544
498
 
545
499
  test("strips only the Convex section from CLAUDE.md", async () => {
546
- writeConfig();
547
- mockReadAiConfig.mockResolvedValue(baseConfig);
500
+ mockAttemptReadAiState.mockResolvedValue({
501
+ kind: "ok",
502
+ state: baseState,
503
+ });
548
504
  const managed = `${CLAUDE_MD_START_MARKER}\n## Convex\nRead guidelines.\n${CLAUDE_MD_END_MARKER}`;
549
505
  fs.writeFileSync(
550
506
  path.join(tmpDir, "CLAUDE.md"),
@@ -562,9 +518,9 @@ describe("removeAiFiles", () => {
562
518
  });
563
519
 
564
520
  test("leaves CLAUDE.md alone when it has no managed markers (legacy)", async () => {
565
- mockReadAiConfig.mockResolvedValue({
566
- ...baseConfig,
567
- claudeMdHash: "some-hash",
521
+ mockAttemptReadAiState.mockResolvedValue({
522
+ kind: "ok",
523
+ state: { ...baseState, claudeMdHash: "some-hash" },
568
524
  });
569
525
 
570
526
  fs.writeFileSync(
@@ -583,9 +539,9 @@ describe("removeAiFiles", () => {
583
539
 
584
540
  test("calls skills remove for each tracked skill name", async () => {
585
541
  const skillNames = ["migration-helper", "schema-builder"];
586
- mockReadAiConfig.mockResolvedValue({
587
- ...baseConfig,
588
- installedSkillNames: skillNames,
542
+ mockAttemptReadAiState.mockResolvedValue({
543
+ kind: "ok",
544
+ state: { ...baseState, installedSkillNames: skillNames },
589
545
  });
590
546
 
591
547
  await removeAiFiles({ projectDir: tmpDir, convexDir });
@@ -602,10 +558,9 @@ describe("removeAiFiles", () => {
602
558
 
603
559
  test("deletes skills-lock.json if it becomes empty after removing our skills", async () => {
604
560
  const skillNames = ["migration-helper"];
605
- writeConfig({ installedSkillNames: skillNames });
606
- mockReadAiConfig.mockResolvedValue({
607
- ...baseConfig,
608
- installedSkillNames: skillNames,
561
+ mockAttemptReadAiState.mockResolvedValue({
562
+ kind: "ok",
563
+ state: { ...baseState, installedSkillNames: skillNames },
609
564
  });
610
565
 
611
566
  const lockfileContent = {
@@ -627,10 +582,9 @@ describe("removeAiFiles", () => {
627
582
 
628
583
  test("preserves skills-lock.json if it contains other skills", async () => {
629
584
  const skillNames = ["migration-helper"];
630
- writeConfig({ installedSkillNames: skillNames });
631
- mockReadAiConfig.mockResolvedValue({
632
- ...baseConfig,
633
- installedSkillNames: skillNames,
585
+ mockAttemptReadAiState.mockResolvedValue({
586
+ kind: "ok",
587
+ state: { ...baseState, installedSkillNames: skillNames },
634
588
  });
635
589
 
636
590
  const lockfileContent = {
@@ -653,9 +607,9 @@ describe("removeAiFiles", () => {
653
607
 
654
608
  test("skips skills remove when server kill switch is enabled", async () => {
655
609
  const skillNames = ["migration-helper"];
656
- mockReadAiConfig.mockResolvedValue({
657
- ...baseConfig,
658
- installedSkillNames: skillNames,
610
+ mockAttemptReadAiState.mockResolvedValue({
611
+ kind: "ok",
612
+ state: { ...baseState, installedSkillNames: skillNames },
659
613
  });
660
614
  mockGetVersion.mockResolvedValue({
661
615
  kind: "ok",
@@ -680,45 +634,15 @@ describe("removeAiFiles", () => {
680
634
  );
681
635
  });
682
636
 
683
- test("does NOT write a disabled config after plain remove", async () => {
684
- writeConfig();
685
- mockReadAiConfig.mockResolvedValue(baseConfig);
686
-
687
- await removeAiFiles({ projectDir: tmpDir, convexDir });
688
-
689
- expect(mockWriteAiConfig).not.toHaveBeenCalled();
690
- });
691
-
692
- test("safelyAttemptToDisableAiFiles writes enabled=false without removing files", async () => {
693
- writeConfig({ guidelinesHash: null });
694
- mockReadAiConfig.mockResolvedValue(baseConfig);
695
-
696
- fs.writeFileSync(
697
- path.join(convexDir, "_generated", "ai", "guidelines.md"),
698
- "guidelines content",
699
- "utf8",
700
- );
701
-
702
- await safelyAttemptToDisableAiFiles(tmpDir);
703
-
704
- expect(mockWriteAiEnabledToProjectConfig).toHaveBeenCalledWith({
705
- enabled: false,
706
- projectDir: tmpDir,
637
+ test("does NOT write state after plain remove", async () => {
638
+ mockAttemptReadAiState.mockResolvedValue({
639
+ kind: "ok",
640
+ state: baseState,
707
641
  });
708
- expect(
709
- fs.existsSync(path.join(convexDir, "_generated", "ai", "guidelines.md")),
710
- ).toBe(true);
711
- });
712
-
713
- test("safelyAttemptToDisableAiFiles writes config to project root, not convex dir", async () => {
714
- mockReadAiConfig.mockResolvedValue(null);
715
642
 
716
- await safelyAttemptToDisableAiFiles(tmpDir);
643
+ await removeAiFiles({ projectDir: tmpDir, convexDir });
717
644
 
718
- expect(mockWriteAiEnabledToProjectConfig).toHaveBeenCalledWith({
719
- enabled: false,
720
- projectDir: tmpDir,
721
- });
645
+ expect(mockWriteAiState).not.toHaveBeenCalled();
722
646
  });
723
647
  });
724
648
 
@@ -744,8 +668,8 @@ describe("statusAiFiles", () => {
744
668
  });
745
669
  afterEach(() => vi.resetAllMocks());
746
670
 
747
- test("reports not installed when config is null", async () => {
748
- mockReadAiConfig.mockResolvedValue(null);
671
+ test("reports not installed when state is missing", async () => {
672
+ mockAttemptReadAiState.mockResolvedValue({ kind: "no-file" });
749
673
 
750
674
  await statusAiFiles({
751
675
  projectDir: dummyProjectDir,
@@ -761,14 +685,10 @@ describe("statusAiFiles", () => {
761
685
  });
762
686
 
763
687
  test("reports disabled when config has enabled=false", async () => {
764
- mockReadAiConfig.mockResolvedValue({
765
- ...baseConfig,
766
- enabled: false,
767
- });
768
-
769
688
  await statusAiFiles({
770
689
  projectDir: dummyProjectDir,
771
690
  convexDir: dummyConvexDir,
691
+ aiFilesConfig: { enabled: false },
772
692
  });
773
693
 
774
694
  expect(mockLogMessage).toHaveBeenCalledWith(
@@ -779,8 +699,11 @@ describe("statusAiFiles", () => {
779
699
  );
780
700
  });
781
701
 
782
- test("reports enabled when config exists and enabled=true", async () => {
783
- mockReadAiConfig.mockResolvedValue(baseConfig);
702
+ test("reports enabled when state exists and messages are not disabled", async () => {
703
+ mockAttemptReadAiState.mockResolvedValue({
704
+ kind: "ok",
705
+ state: baseState,
706
+ });
784
707
 
785
708
  await statusAiFiles({
786
709
  projectDir: dummyProjectDir,
@@ -809,9 +732,9 @@ describe("statusAiFiles", () => {
809
732
  "utf8",
810
733
  );
811
734
 
812
- mockReadAiConfig.mockResolvedValue({
813
- ...baseConfig,
814
- guidelinesHash: hash,
735
+ mockAttemptReadAiState.mockResolvedValue({
736
+ kind: "ok",
737
+ state: { ...baseState, guidelinesHash: hash },
815
738
  });
816
739
  mockGetVersion.mockResolvedValue({
817
740
  kind: "ok",
@@ -850,9 +773,9 @@ describe("statusAiFiles", () => {
850
773
  "utf8",
851
774
  );
852
775
 
853
- mockReadAiConfig.mockResolvedValue({
854
- ...baseConfig,
855
- guidelinesHash: hashSha256(content),
776
+ mockAttemptReadAiState.mockResolvedValue({
777
+ kind: "ok",
778
+ state: { ...baseState, guidelinesHash: hashSha256(content) },
856
779
  });
857
780
  mockGetVersion.mockResolvedValue({
858
781
  kind: "ok",
@@ -892,9 +815,12 @@ describe("statusAiFiles", () => {
892
815
  "utf8",
893
816
  );
894
817
 
895
- mockReadAiConfig.mockResolvedValue({
896
- ...baseConfig,
897
- guidelinesHash: hashSha256("original content"),
818
+ mockAttemptReadAiState.mockResolvedValue({
819
+ kind: "ok",
820
+ state: {
821
+ ...baseState,
822
+ guidelinesHash: hashSha256("original content"),
823
+ },
898
824
  });
899
825
 
900
826
  await statusAiFiles({ projectDir: tmpDir, convexDir });
@@ -907,11 +833,42 @@ describe("statusAiFiles", () => {
907
833
  }
908
834
  });
909
835
 
836
+ test("reports guidelines as missing when guidelines.md is empty", async () => {
837
+ const tmpDir = fs.mkdtempSync(`${os.tmpdir()}${path.sep}`);
838
+ const convexDir = path.join(tmpDir, "convex");
839
+ try {
840
+ fs.mkdirSync(path.join(convexDir, "_generated", "ai"), {
841
+ recursive: true,
842
+ });
843
+ fs.writeFileSync(
844
+ path.join(convexDir, "_generated", "ai", "guidelines.md"),
845
+ "",
846
+ "utf8",
847
+ );
848
+
849
+ mockAttemptReadAiState.mockResolvedValue({
850
+ kind: "ok",
851
+ state: baseState,
852
+ });
853
+
854
+ await statusAiFiles({ projectDir: tmpDir, convexDir });
855
+
856
+ expect(mockLogMessage).toHaveBeenCalledWith(
857
+ expect.stringContaining("guidelines.md: not on disk"),
858
+ );
859
+ } finally {
860
+ fs.rmSync(tmpDir, { recursive: true, force: true });
861
+ }
862
+ });
863
+
910
864
  test("reports agent skills as out of date when SHA differs from canonical", async () => {
911
- mockReadAiConfig.mockResolvedValue({
912
- ...baseConfig,
913
- installedSkillNames: ["migration-helper"],
914
- agentSkillsSha: "old-sha",
865
+ mockAttemptReadAiState.mockResolvedValue({
866
+ kind: "ok",
867
+ state: {
868
+ ...baseState,
869
+ installedSkillNames: ["migration-helper"],
870
+ agentSkillsSha: "old-sha",
871
+ },
915
872
  });
916
873
  mockGetVersion.mockResolvedValue({
917
874
  kind: "ok",
@@ -937,11 +894,14 @@ describe("statusAiFiles", () => {
937
894
  });
938
895
 
939
896
  test("skips staleness check when network is unavailable", async () => {
940
- mockReadAiConfig.mockResolvedValue({
941
- ...baseConfig,
942
- guidelinesHash: "old-hash",
943
- agentSkillsSha: "old-sha",
944
- installedSkillNames: ["migration-helper"],
897
+ mockAttemptReadAiState.mockResolvedValue({
898
+ kind: "ok",
899
+ state: {
900
+ ...baseState,
901
+ guidelinesHash: "old-hash",
902
+ agentSkillsSha: "old-sha",
903
+ installedSkillNames: ["migration-helper"],
904
+ },
945
905
  });
946
906
  mockGetVersion.mockResolvedValue({ kind: "error" });
947
907
 
@@ -955,10 +915,13 @@ describe("statusAiFiles", () => {
955
915
  });
956
916
 
957
917
  test("reports skills with names when installed", async () => {
958
- mockReadAiConfig.mockResolvedValue({
959
- ...baseConfig,
960
- installedSkillNames: ["migration-helper", "schema-builder"],
961
- agentSkillsSha: "canonical-skills-sha",
918
+ mockAttemptReadAiState.mockResolvedValue({
919
+ kind: "ok",
920
+ state: {
921
+ ...baseState,
922
+ installedSkillNames: ["migration-helper", "schema-builder"],
923
+ agentSkillsSha: "canonical-skills-sha",
924
+ },
962
925
  });
963
926
 
964
927
  await statusAiFiles({
@@ -983,7 +946,10 @@ describe("statusAiFiles", () => {
983
946
  "User content\n",
984
947
  "utf8",
985
948
  );
986
- mockReadAiConfig.mockResolvedValue(baseConfig);
949
+ mockAttemptReadAiState.mockResolvedValue({
950
+ kind: "ok",
951
+ state: baseState,
952
+ });
987
953
 
988
954
  await statusAiFiles({ projectDir: tmpDir, convexDir });
989
955