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
@@ -28,12 +28,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var aiFiles_exports = {};
30
30
  __export(aiFiles_exports, {
31
- checkAiFilesStaleness: () => checkAiFilesStaleness,
31
+ attemptSetupAiFiles: () => attemptSetupAiFiles,
32
+ checkAiFilesStalenessAndLog: () => checkAiFilesStalenessAndLog,
33
+ disableAiFiles: () => disableAiFiles,
32
34
  enableAiFiles: () => enableAiFiles,
33
35
  installAiFiles: () => installAiFiles,
34
- maybeSetupAiFiles: () => maybeSetupAiFiles,
35
- removeAiFiles: () => removeAiFiles,
36
- safelyAttemptToDisableAiFiles: () => safelyAttemptToDisableAiFiles
36
+ isAiFilesDisabled: () => isAiFilesDisabled,
37
+ removeAiFiles: () => removeAiFiles
37
38
  });
38
39
  module.exports = __toCommonJS(aiFiles_exports);
39
40
  var Sentry = __toESM(require("@sentry/node"), 1);
@@ -44,7 +45,7 @@ var import_log = require("../../../bundler/log.js");
44
45
  var import_prompts = require("../utils/prompts.js");
45
46
  var import_paths = require("./paths.js");
46
47
  var import_guidelinesmd = require("./guidelinesmd.js");
47
- var import_config = require("./config.js");
48
+ var import_state = require("./state.js");
48
49
  var import_utils = require("./utils.js");
49
50
  var import_agentsmd = require("./agentsmd.js");
50
51
  var import_claudemd = require("./claudemd.js");
@@ -59,33 +60,16 @@ async function hasExistingAiFilesArtifacts({
59
60
  async function installAiFiles({
60
61
  projectDir,
61
62
  convexDir,
62
- shouldWriteGuidelines = true,
63
- shouldWriteAgentsMd = true,
64
- shouldWriteClaudeMd = true,
65
- shouldWriteSkills = true
63
+ aiFilesConfig
66
64
  }) {
67
- await import_fs.promises.mkdir((0, import_paths.aiDirForConvexDir)(convexDir), { recursive: true });
68
- const config = await (0, import_config.readAiConfig)({
69
- projectDir,
70
- convexDir
71
- }) ?? {
72
- enabled: true,
73
- guidelinesHash: null,
74
- agentsMdSectionHash: null,
75
- claudeMdHash: null,
76
- agentSkillsSha: null,
77
- installedSkillNames: []
78
- };
79
- if (shouldWriteGuidelines) await (0, import_guidelinesmd.installGuidelinesFile)({ convexDir, config });
80
65
  const convexDirName = import_path.default.relative(projectDir, convexDir);
81
- if (shouldWriteAgentsMd)
82
- await (0, import_agentsmd.applyAgentsMdSection)({ projectDir, config, convexDirName });
83
- if (shouldWriteClaudeMd)
84
- await (0, import_claudemd.applyClaudeMdSection)({ projectDir, config, convexDirName });
85
- if (shouldWriteSkills) await (0, import_skills.installSkills)({ projectDir, config });
66
+ const state = await (0, import_state.readAiStateOrDefault)(convexDir);
67
+ await (0, import_guidelinesmd.installGuidelinesFile)({ convexDir, state });
68
+ await (0, import_agentsmd.applyAgentsMdSection)({ projectDir, state, convexDirName });
69
+ await (0, import_claudemd.applyClaudeMdSection)({ projectDir, state, convexDirName });
70
+ await (0, import_skills.installSkills)({ projectDir, state, aiFilesConfig });
86
71
  await (0, import_cursorrules.removeLegacyCursorRulesFile)(projectDir);
87
- await (0, import_config.writeAiConfig)({ config, projectDir, convexDir });
88
- (0, import_log.logMessage)(`${import_chalk.chalkStderr.green("\u2714")} Convex AI files installed.`);
72
+ await (0, import_state.writeAiState)({ state, convexDir });
89
73
  }
90
74
  async function attemptToInstallAiFiles(opts) {
91
75
  try {
@@ -94,28 +78,38 @@ async function attemptToInstallAiFiles(opts) {
94
78
  Sentry.captureException(error);
95
79
  }
96
80
  }
81
+ function isAiFilesDisabled(aiFilesConfig) {
82
+ if (aiFilesConfig?.enabled !== void 0)
83
+ return aiFilesConfig.enabled === false;
84
+ return aiFilesConfig?.disableStalenessMessage === true;
85
+ }
97
86
  async function determineAiFilesStaleness({
98
87
  canonicalGuidelinesHash,
99
88
  canonicalAgentSkillsSha,
89
+ aiFilesConfig,
100
90
  projectDir,
101
91
  convexDir
102
92
  }) {
103
- const config = await (0, import_config.readAiConfig)({ projectDir, convexDir });
104
- if (config === null) {
93
+ if (isAiFilesDisabled(aiFilesConfig)) return "silent";
94
+ const result = await (0, import_state.attemptReadAiState)(convexDir);
95
+ if (result.kind === "no-file" || result.kind === "parse-error") {
105
96
  const hasArtifacts = await hasExistingAiFilesArtifacts({
106
97
  projectDir,
107
98
  convexDir
108
99
  });
109
- return hasArtifacts ? "has-artifacts" : "not-installed";
100
+ return hasArtifacts ? "silent" : "not-installed";
110
101
  }
111
- if (!config.enabled) return "disabled";
112
- if (canonicalGuidelinesHash === null && canonicalAgentSkillsSha === null)
113
- return "up-to-date";
114
- const guidelinesStale = canonicalGuidelinesHash !== null && config.guidelinesHash !== null && config.guidelinesHash !== canonicalGuidelinesHash;
115
- const skillsStale = canonicalAgentSkillsSha !== null && config.agentSkillsSha !== null && config.agentSkillsSha !== canonicalAgentSkillsSha;
116
- return guidelinesStale || skillsStale ? "stale" : "up-to-date";
102
+ if (result.kind === "ok") {
103
+ const { state } = result;
104
+ if (canonicalGuidelinesHash === null && canonicalAgentSkillsSha === null)
105
+ return "silent";
106
+ const guidelinesStale = canonicalGuidelinesHash !== null && state.guidelinesHash !== null && state.guidelinesHash !== canonicalGuidelinesHash;
107
+ const skillsStale = canonicalAgentSkillsSha !== null && state.agentSkillsSha !== null && state.agentSkillsSha !== canonicalAgentSkillsSha;
108
+ return guidelinesStale || skillsStale ? "stale" : "silent";
109
+ }
110
+ return (0, import_utils.exhaustiveCheck)(result);
117
111
  }
118
- async function checkAiFilesStaleness(opts) {
112
+ async function checkAiFilesStalenessAndLog(opts) {
119
113
  const status = await determineAiFilesStaleness(opts);
120
114
  if (status === "not-installed") {
121
115
  (0, import_log.logMessage)(
@@ -123,6 +117,7 @@ async function checkAiFilesStaleness(opts) {
123
117
  `Convex AI files are not installed. Run ${import_chalk.chalkStderr.bold(`npx convex ai-files install`)} to get started or ${import_chalk.chalkStderr.bold(`npx convex ai-files disable`)} to hide this message.`
124
118
  )
125
119
  );
120
+ return;
126
121
  }
127
122
  if (status === "stale") {
128
123
  (0, import_log.logMessage)(
@@ -130,61 +125,42 @@ async function checkAiFilesStaleness(opts) {
130
125
  `Your Convex AI files are out of date. Run ${import_chalk.chalkStderr.bold(`npx convex ai-files update`)} to get the latest.`
131
126
  )
132
127
  );
128
+ return;
133
129
  }
130
+ if (status === "silent") return;
131
+ (0, import_utils.exhaustiveCheck)(status);
134
132
  }
135
133
  async function enableAiFiles({
136
134
  projectDir,
137
- convexDir
135
+ convexDir,
136
+ aiFilesConfig
138
137
  }) {
139
- await installAiFiles({ projectDir, convexDir });
140
- const config = await (0, import_config.readAiConfig)({ projectDir, convexDir });
141
- if (config === null) return;
142
- config.enabled = true;
143
- await (0, import_config.writeAiConfig)({
144
- config,
145
- projectDir,
146
- convexDir,
147
- options: { persistEnabledPreference: "always" }
148
- });
138
+ await installAiFiles({ projectDir, convexDir, aiFilesConfig });
139
+ const { disableStalenessMessage: _, ...rest } = aiFilesConfig ?? {};
140
+ return { ...rest, enabled: true };
141
+ }
142
+ function disableAiFiles(aiFilesConfig) {
143
+ const { disableStalenessMessage: _, ...rest } = aiFilesConfig ?? {};
144
+ return { ...rest, enabled: false };
149
145
  }
150
146
  async function removeAiFiles({
151
147
  projectDir,
152
148
  convexDir
153
149
  }) {
154
- const config = await (0, import_config.readAiConfig)({ projectDir, convexDir });
155
- if (config === null) {
156
- (0, import_log.logMessage)("No Convex AI files found \u2014 nothing to remove.");
157
- return;
158
- }
150
+ const result = await (0, import_state.attemptReadAiState)(convexDir);
151
+ const installedSkillNames = result.kind === "ok" ? result.state.installedSkillNames : result.kind === "no-file" || result.kind === "parse-error" ? [] : (0, import_utils.exhaustiveCheck)(result);
159
152
  const removals = [
160
- await (0, import_agentsmd.removeAgentsMdSection)(projectDir),
161
- await (0, import_claudemd.removeClaudeMdSection)(projectDir),
153
+ await (0, import_agentsmd.attemptToRemoveAgentsMdSection)(projectDir),
154
+ await (0, import_claudemd.attemptToRemoveClaudeMdSection)(projectDir),
162
155
  await (0, import_skills.removeInstalledSkills)({
163
156
  projectDir,
164
- skillNames: config.installedSkillNames
157
+ skillNames: installedSkillNames
165
158
  }),
166
159
  await (0, import_cursorrules.removeLegacyCursorRulesFile)(projectDir),
167
160
  await attemptToDeleteAiDir({ projectDir, convexDir })
168
161
  ];
169
162
  if (removals.some(Boolean)) (0, import_log.logMessage)("Convex AI files removed.");
170
- }
171
- async function safelyAttemptToDisableAiFiles(projectDir) {
172
- try {
173
- await (0, import_config.writeAiEnabledToProjectConfig)({
174
- projectDir,
175
- enabled: false
176
- });
177
- (0, import_log.logMessage)(
178
- `${import_chalk.chalkStderr.green(`\u2714`)} Convex AI files disabled. Run ${import_chalk.chalkStderr.bold(`npx convex ai-files enable`)} to re-enable.`
179
- );
180
- } catch (error) {
181
- Sentry.captureException(error);
182
- (0, import_log.logMessage)(
183
- import_chalk.chalkStderr.yellow(
184
- "Could not write AI message suppression config. Message may reappear."
185
- )
186
- );
187
- }
163
+ else (0, import_log.logMessage)("No Convex AI files found \u2014 nothing to remove.");
188
164
  }
189
165
  async function attemptToDeleteAiDir({
190
166
  projectDir,
@@ -193,10 +169,11 @@ async function attemptToDeleteAiDir({
193
169
  const aiDir = (0, import_paths.aiDirForConvexDir)(convexDir);
194
170
  const relPath = import_path.default.relative(projectDir, aiDir);
195
171
  try {
196
- await import_fs.promises.rm(aiDir, { recursive: true, force: true });
172
+ await import_fs.promises.rm(aiDir, { recursive: true });
197
173
  (0, import_log.logMessage)(`${import_chalk.chalkStderr.green("\u2714")} Deleted ${relPath}/`);
198
174
  return true;
199
175
  } catch (error) {
176
+ if (error.code === "ENOENT") return false;
200
177
  Sentry.captureException(error);
201
178
  (0, import_log.logMessage)(
202
179
  import_chalk.chalkStderr.yellow(`Could not delete ${relPath}/. Remove it manually.`)
@@ -206,26 +183,33 @@ async function attemptToDeleteAiDir({
206
183
  }
207
184
  async function hasAiFilesBeenInstalledBefore({
208
185
  projectDir,
209
- convexDir
186
+ convexDir,
187
+ aiFilesConfig
210
188
  }) {
211
- return await (0, import_config.hasAiFilesConfig)({ projectDir, convexDir }) || await hasExistingAiFilesArtifacts({ projectDir, convexDir });
189
+ if (isAiFilesDisabled(aiFilesConfig)) return false;
190
+ return await (0, import_state.hasAiState)(convexDir) || await hasExistingAiFilesArtifacts({ projectDir, convexDir });
212
191
  }
213
- async function maybeSetupAiFiles({
192
+ async function attemptSetupAiFiles({
214
193
  ctx,
215
194
  convexDir,
216
- projectDir
195
+ projectDir,
196
+ aiFilesConfig
217
197
  }) {
218
198
  if (!(0, import_utils.isInInteractiveTerminal)()) return;
219
- const config = await (0, import_config.readAiConfig)({ projectDir, convexDir });
220
- if (config !== null && !config.enabled) return;
221
- if (await hasAiFilesBeenInstalledBefore({ projectDir, convexDir })) {
222
- await attemptToInstallAiFiles({ projectDir, convexDir });
199
+ if (isAiFilesDisabled(aiFilesConfig)) return;
200
+ if (await hasAiFilesBeenInstalledBefore({
201
+ projectDir,
202
+ convexDir,
203
+ aiFilesConfig
204
+ })) {
205
+ await attemptToInstallAiFiles({ projectDir, convexDir, aiFilesConfig });
223
206
  return;
224
207
  }
225
208
  const shouldInstall = await (0, import_prompts.promptYesNo)(ctx, {
226
209
  message: "Set up Convex AI files? (guidelines, AGENTS.md, agent skills)",
227
210
  default: true
228
211
  });
229
- if (shouldInstall) await attemptToInstallAiFiles({ projectDir, convexDir });
212
+ if (shouldInstall)
213
+ await attemptToInstallAiFiles({ projectDir, convexDir, aiFilesConfig });
230
214
  }
231
215
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/cli/lib/aiFiles/index.ts"],
4
- "sourcesContent": ["import * as Sentry from \"@sentry/node\";\nimport path from \"path\";\nimport { Context } from \"../../../bundler/context.js\";\n// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { promptYesNo } from \"../utils/prompts.js\";\nimport { type AiFilesPaths, aiDirForConvexDir } from \"./paths.js\";\nimport {\n installGuidelinesFile,\n hasGuidelinesInstalled,\n} from \"./guidelinesmd.js\";\nimport {\n type AiFilesConfig,\n hasAiFilesConfig,\n readAiConfig,\n writeAiConfig,\n writeAiEnabledToProjectConfig,\n} from \"./config.js\";\nimport { isInInteractiveTerminal } from \"./utils.js\";\nimport {\n hasAgentsMdInstalled,\n applyAgentsMdSection,\n removeAgentsMdSection,\n} from \"./agentsmd.js\";\nimport {\n hasClaudeMdInstalled,\n applyClaudeMdSection,\n removeClaudeMdSection,\n} from \"./claudemd.js\";\nimport { installSkills, removeInstalledSkills } from \"./skills.js\";\nimport { removeLegacyCursorRulesFile as removeLegacyCursorRules } from \"./cursorrules.js\";\nasync function hasExistingAiFilesArtifacts({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<boolean> {\n return (\n (await hasGuidelinesInstalled(convexDir)) ||\n (await hasAgentsMdInstalled(projectDir)) ||\n (await hasClaudeMdInstalled(projectDir))\n );\n}\n\n/**\n * Install or refresh all Convex AI files.\n *\n * Reads the existing config if present, or starts from a blank one for a\n * fresh install. Each component can be individually skipped via the optional\n * flags (all default to true).\n */\nexport async function installAiFiles({\n projectDir,\n convexDir,\n shouldWriteGuidelines = true,\n shouldWriteAgentsMd = true,\n shouldWriteClaudeMd = true,\n shouldWriteSkills = true,\n}: AiFilesPaths & {\n shouldWriteGuidelines?: boolean;\n shouldWriteAgentsMd?: boolean;\n shouldWriteClaudeMd?: boolean;\n shouldWriteSkills?: boolean;\n}): Promise<void> {\n await fs.mkdir(aiDirForConvexDir(convexDir), { recursive: true });\n\n const config: AiFilesConfig = (await readAiConfig({\n projectDir,\n convexDir,\n })) ?? {\n enabled: true,\n guidelinesHash: null,\n agentsMdSectionHash: null,\n claudeMdHash: null,\n agentSkillsSha: null,\n installedSkillNames: [],\n };\n\n if (shouldWriteGuidelines) await installGuidelinesFile({ convexDir, config });\n\n const convexDirName = path.relative(projectDir, convexDir);\n\n if (shouldWriteAgentsMd)\n await applyAgentsMdSection({ projectDir, config, convexDirName });\n\n if (shouldWriteClaudeMd)\n await applyClaudeMdSection({ projectDir, config, convexDirName });\n\n if (shouldWriteSkills) await installSkills({ projectDir, config });\n\n await removeLegacyCursorRules(projectDir);\n await writeAiConfig({ config, projectDir, convexDir });\n\n logMessage(`${chalkStderr.green(\"\u2714\")} Convex AI files installed.`);\n}\n\nasync function attemptToInstallAiFiles(\n opts: Parameters<typeof installAiFiles>[0],\n): Promise<void> {\n try {\n await installAiFiles(opts);\n } catch (error) {\n Sentry.captureException(error);\n }\n}\n\ntype AiFilesStalenessStatus =\n | \"not-installed\" // no config AND no artifacts \u2014 show install nag\n | \"has-artifacts\" // no config but files exist on disk (e.g. fresh checkout) \u2014 stay quiet\n | \"disabled\" // user opted out of nag messages\n | \"stale\" // one or more files are out of date\n | \"up-to-date\"; // everything looks fine\n\nasync function determineAiFilesStaleness({\n canonicalGuidelinesHash,\n canonicalAgentSkillsSha,\n projectDir,\n convexDir,\n}: {\n canonicalGuidelinesHash: string | null;\n canonicalAgentSkillsSha: string | null;\n} & AiFilesPaths): Promise<AiFilesStalenessStatus> {\n const config = await readAiConfig({ projectDir, convexDir });\n\n if (config === null) {\n const hasArtifacts = await hasExistingAiFilesArtifacts({\n projectDir,\n convexDir,\n });\n return hasArtifacts ? \"has-artifacts\" : \"not-installed\";\n }\n\n if (!config.enabled) return \"disabled\";\n\n if (canonicalGuidelinesHash === null && canonicalAgentSkillsSha === null)\n return \"up-to-date\";\n\n const guidelinesStale =\n canonicalGuidelinesHash !== null &&\n config.guidelinesHash !== null &&\n config.guidelinesHash !== canonicalGuidelinesHash;\n\n const skillsStale =\n canonicalAgentSkillsSha !== null &&\n config.agentSkillsSha !== null &&\n config.agentSkillsSha !== canonicalAgentSkillsSha;\n\n return guidelinesStale || skillsStale ? \"stale\" : \"up-to-date\";\n}\n\n/**\n * Check whether the Convex AI files are out of date and log a nag message\n * if so.\n */\nexport async function checkAiFilesStaleness(\n opts: {\n canonicalGuidelinesHash: string | null;\n canonicalAgentSkillsSha: string | null;\n } & AiFilesPaths,\n): Promise<void> {\n const status = await determineAiFilesStaleness(opts);\n\n if (status === \"not-installed\") {\n logMessage(\n chalkStderr.yellow(\n `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.`,\n ),\n );\n }\n\n if (status === \"stale\") {\n logMessage(\n chalkStderr.yellow(\n `Your Convex AI files are out of date. Run ${chalkStderr.bold(`npx convex ai-files update`)} to get the latest.`,\n ),\n );\n }\n}\n\nexport async function enableAiFiles({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<void> {\n await installAiFiles({ projectDir, convexDir });\n const config = await readAiConfig({ projectDir, convexDir });\n if (config === null) return;\n config.enabled = true;\n await writeAiConfig({\n config,\n projectDir,\n convexDir,\n options: { persistEnabledPreference: \"always\" },\n });\n}\n\n/**\n * Remove all Convex AI files from the project.\n * Called by `npx convex ai-files remove`.\n */\nexport async function removeAiFiles({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<void> {\n const config = await readAiConfig({ projectDir, convexDir });\n if (config === null) {\n logMessage(\"No Convex AI files found \u2014 nothing to remove.\");\n return;\n }\n\n const removals = [\n await removeAgentsMdSection(projectDir),\n await removeClaudeMdSection(projectDir),\n await removeInstalledSkills({\n projectDir,\n skillNames: config.installedSkillNames,\n }),\n await removeLegacyCursorRules(projectDir),\n await attemptToDeleteAiDir({ projectDir, convexDir }),\n ];\n\n if (removals.some(Boolean)) logMessage(\"Convex AI files removed.\");\n}\n\n/**\n * Called by `npx convex ai-files disable`.\n *\n * Writes a suppression flag into `convex.json` so `npx convex dev` stops\n * showing AI files install/staleness messages. Files are left in place.\n */\nexport async function safelyAttemptToDisableAiFiles(\n projectDir: string,\n): Promise<void> {\n try {\n await writeAiEnabledToProjectConfig({\n projectDir,\n enabled: false,\n });\n logMessage(\n `${chalkStderr.green(`\u2714`)} Convex AI files disabled. Run ${chalkStderr.bold(`npx convex ai-files enable`)} to re-enable.`,\n );\n } catch (error) {\n Sentry.captureException(error);\n logMessage(\n chalkStderr.yellow(\n \"Could not write AI message suppression config. Message may reappear.\",\n ),\n );\n }\n}\n\nasync function attemptToDeleteAiDir({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<boolean> {\n const aiDir = aiDirForConvexDir(convexDir);\n const relPath = path.relative(projectDir, aiDir);\n try {\n await fs.rm(aiDir, { recursive: true, force: true });\n logMessage(`${chalkStderr.green(\"\u2714\")} Deleted ${relPath}/`);\n return true;\n } catch (error) {\n Sentry.captureException(error);\n logMessage(\n chalkStderr.yellow(`Could not delete ${relPath}/. Remove it manually.`),\n );\n return false;\n }\n}\n\nasync function hasAiFilesBeenInstalledBefore({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<boolean> {\n return (\n (await hasAiFilesConfig({ projectDir, convexDir })) ||\n (await hasExistingAiFilesArtifacts({ projectDir, convexDir }))\n );\n}\n\nexport async function maybeSetupAiFiles({\n ctx,\n convexDir,\n projectDir,\n}: {\n ctx: Context;\n} & AiFilesPaths): Promise<void> {\n if (!isInInteractiveTerminal()) return;\n\n const config = await readAiConfig({ projectDir, convexDir });\n if (config !== null && !config.enabled) return;\n\n if (await hasAiFilesBeenInstalledBefore({ projectDir, convexDir })) {\n await attemptToInstallAiFiles({ projectDir, convexDir });\n return;\n }\n\n const shouldInstall = await promptYesNo(ctx, {\n message: \"Set up Convex AI files? (guidelines, AGENTS.md, agent skills)\",\n default: true,\n });\n\n if (shouldInstall) await attemptToInstallAiFiles({ projectDir, convexDir });\n}\n"],
5
- "mappings": "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",
6
- "names": ["fs", "path", "removeLegacyCursorRules"]
4
+ "sourcesContent": ["import * as Sentry from \"@sentry/node\";\nimport path from \"path\";\nimport { Context } from \"../../../bundler/context.js\";\n// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { promptYesNo } from \"../utils/prompts.js\";\nimport { type AiFilesPaths, aiDirForConvexDir } from \"./paths.js\";\nimport {\n installGuidelinesFile,\n hasGuidelinesInstalled,\n} from \"./guidelinesmd.js\";\nimport {\n attemptReadAiState,\n readAiStateOrDefault,\n writeAiState,\n hasAiState,\n} from \"./state.js\";\nimport { type AiFilesProjectConfig } from \"../config.js\";\nimport { exhaustiveCheck, isInInteractiveTerminal } from \"./utils.js\";\nimport {\n hasAgentsMdInstalled,\n applyAgentsMdSection,\n attemptToRemoveAgentsMdSection,\n} from \"./agentsmd.js\";\nimport {\n hasClaudeMdInstalled,\n applyClaudeMdSection,\n attemptToRemoveClaudeMdSection,\n} from \"./claudemd.js\";\nimport { installSkills, removeInstalledSkills } from \"./skills.js\";\nimport { removeLegacyCursorRulesFile as removeLegacyCursorRules } from \"./cursorrules.js\";\n\nasync function hasExistingAiFilesArtifacts({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<boolean> {\n return (\n (await hasGuidelinesInstalled(convexDir)) ||\n (await hasAgentsMdInstalled(projectDir)) ||\n (await hasClaudeMdInstalled(projectDir))\n );\n}\n\n/**\n * Install or refresh all Convex AI files.\n *\n * Reads the existing state if present, or starts from a blank one for a\n * fresh install.\n */\nexport async function installAiFiles({\n projectDir,\n convexDir,\n aiFilesConfig,\n}: AiFilesPaths & {\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n}): Promise<void> {\n const convexDirName = path.relative(projectDir, convexDir);\n const state = await readAiStateOrDefault(convexDir);\n\n await installGuidelinesFile({ convexDir, state });\n await applyAgentsMdSection({ projectDir, state, convexDirName });\n await applyClaudeMdSection({ projectDir, state, convexDirName });\n await installSkills({ projectDir, state, aiFilesConfig });\n await removeLegacyCursorRules(projectDir);\n await writeAiState({ state, convexDir });\n}\n\nasync function attemptToInstallAiFiles(\n opts: Parameters<typeof installAiFiles>[0],\n): Promise<void> {\n try {\n await installAiFiles(opts);\n } catch (error) {\n Sentry.captureException(error);\n }\n}\n\ntype AiFilesStalenessStatus = \"not-installed\" | \"stale\" | \"silent\";\n\nexport function isAiFilesDisabled(\n aiFilesConfig: AiFilesProjectConfig | undefined,\n): boolean {\n if (aiFilesConfig?.enabled !== undefined)\n return aiFilesConfig.enabled === false;\n return aiFilesConfig?.disableStalenessMessage === true;\n}\n\nasync function determineAiFilesStaleness({\n canonicalGuidelinesHash,\n canonicalAgentSkillsSha,\n aiFilesConfig,\n projectDir,\n convexDir,\n}: {\n canonicalGuidelinesHash: string | null;\n canonicalAgentSkillsSha: string | null;\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n} & AiFilesPaths): Promise<AiFilesStalenessStatus> {\n if (isAiFilesDisabled(aiFilesConfig)) return \"silent\";\n\n const result = await attemptReadAiState(convexDir);\n\n if (result.kind === \"no-file\" || result.kind === \"parse-error\") {\n const hasArtifacts = await hasExistingAiFilesArtifacts({\n projectDir,\n convexDir,\n });\n return hasArtifacts ? \"silent\" : \"not-installed\";\n }\n\n if (result.kind === \"ok\") {\n const { state } = result;\n\n if (canonicalGuidelinesHash === null && canonicalAgentSkillsSha === null)\n return \"silent\";\n\n const guidelinesStale =\n canonicalGuidelinesHash !== null &&\n state.guidelinesHash !== null &&\n state.guidelinesHash !== canonicalGuidelinesHash;\n\n const skillsStale =\n canonicalAgentSkillsSha !== null &&\n state.agentSkillsSha !== null &&\n state.agentSkillsSha !== canonicalAgentSkillsSha;\n\n return guidelinesStale || skillsStale ? \"stale\" : \"silent\";\n }\n\n return exhaustiveCheck(result);\n}\n\n/**\n * Check whether the Convex AI files are out of date and log a nag message\n * if so.\n */\nexport async function checkAiFilesStalenessAndLog(\n opts: {\n canonicalGuidelinesHash: string | null;\n canonicalAgentSkillsSha: string | null;\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n } & AiFilesPaths,\n): Promise<void> {\n const status = await determineAiFilesStaleness(opts);\n\n if (status === \"not-installed\") {\n logMessage(\n chalkStderr.yellow(\n `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.`,\n ),\n );\n return;\n }\n\n if (status === \"stale\") {\n logMessage(\n chalkStderr.yellow(\n `Your Convex AI files are out of date. Run ${chalkStderr.bold(`npx convex ai-files update`)} to get the latest.`,\n ),\n );\n return;\n }\n\n if (status === \"silent\") return;\n\n exhaustiveCheck(status);\n}\n\n/**\n * Installs AI files and returns the aiFiles config to write.\n */\nexport async function enableAiFiles({\n projectDir,\n convexDir,\n aiFilesConfig,\n}: AiFilesPaths & {\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n}): Promise<AiFilesProjectConfig> {\n await installAiFiles({ projectDir, convexDir, aiFilesConfig });\n // Deleting the deprecated disableStalenessMessage key\n const { disableStalenessMessage: _, ...rest } = aiFilesConfig ?? {};\n return { ...rest, enabled: true };\n}\n\n/**\n * Returns the aiFiles config to write when disabling AI files.\n */\nexport function disableAiFiles(\n aiFilesConfig?: AiFilesProjectConfig | undefined,\n): AiFilesProjectConfig {\n // Deleting the deprecated disableStalenessMessage key\n const { disableStalenessMessage: _, ...rest } = aiFilesConfig ?? {};\n return { ...rest, enabled: false };\n}\n\n/**\n * Remove all Convex AI files from the project.\n * Called by `npx convex ai-files remove`.\n */\nexport async function removeAiFiles({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<void> {\n const result = await attemptReadAiState(convexDir);\n\n // Skill names are only known when the state file exists and parses.\n // All other artifacts (AGENTS.md, CLAUDE.md sections, ai dir) can exist\n // independently, so we always attempt their removal.\n const installedSkillNames =\n result.kind === \"ok\"\n ? result.state.installedSkillNames\n : result.kind === \"no-file\" || result.kind === \"parse-error\"\n ? []\n : exhaustiveCheck(result);\n\n const removals = [\n await attemptToRemoveAgentsMdSection(projectDir),\n await attemptToRemoveClaudeMdSection(projectDir),\n await removeInstalledSkills({\n projectDir,\n skillNames: installedSkillNames,\n }),\n await removeLegacyCursorRules(projectDir),\n await attemptToDeleteAiDir({ projectDir, convexDir }),\n ];\n\n if (removals.some(Boolean)) logMessage(\"Convex AI files removed.\");\n else logMessage(\"No Convex AI files found \u2014 nothing to remove.\");\n}\n\nasync function attemptToDeleteAiDir({\n projectDir,\n convexDir,\n}: AiFilesPaths): Promise<boolean> {\n const aiDir = aiDirForConvexDir(convexDir);\n const relPath = path.relative(projectDir, aiDir);\n try {\n await fs.rm(aiDir, { recursive: true });\n logMessage(`${chalkStderr.green(\"\u2714\")} Deleted ${relPath}/`);\n return true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n Sentry.captureException(error);\n logMessage(\n chalkStderr.yellow(`Could not delete ${relPath}/. Remove it manually.`),\n );\n return false;\n }\n}\n\nasync function hasAiFilesBeenInstalledBefore({\n projectDir,\n convexDir,\n aiFilesConfig,\n}: AiFilesPaths & {\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n}): Promise<boolean> {\n if (isAiFilesDisabled(aiFilesConfig)) return false;\n return (\n (await hasAiState(convexDir)) ||\n (await hasExistingAiFilesArtifacts({ projectDir, convexDir }))\n );\n}\n\nexport async function attemptSetupAiFiles({\n ctx,\n convexDir,\n projectDir,\n aiFilesConfig,\n}: {\n ctx: Context;\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n} & AiFilesPaths): Promise<void> {\n if (!isInInteractiveTerminal()) return;\n if (isAiFilesDisabled(aiFilesConfig)) return;\n\n if (\n await hasAiFilesBeenInstalledBefore({\n projectDir,\n convexDir,\n aiFilesConfig,\n })\n ) {\n await attemptToInstallAiFiles({ projectDir, convexDir, aiFilesConfig });\n return;\n }\n\n const shouldInstall = await promptYesNo(ctx, {\n message: \"Set up Convex AI files? (guidelines, AGENTS.md, agent skills)\",\n default: true,\n });\n\n if (shouldInstall)\n await attemptToInstallAiFiles({ projectDir, convexDir, aiFilesConfig });\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["path", "removeLegacyCursorRules", "fs"]
7
7
  }
@@ -53,7 +53,7 @@ async function readInstalledSkillNames(projectDir) {
53
53
  const names = [];
54
54
  for (const entry of entries) {
55
55
  const skillMdPath = import_path.default.join(skillsDir, entry, "SKILL.md");
56
- const content = await (0, import_utils.readFileSafe)(skillMdPath);
56
+ const content = await (0, import_utils.readFileOrNull)(skillMdPath);
57
57
  if (content === null) continue;
58
58
  const match = content.match(/^---[\s\S]*?^name:\s*(.+?)\s*$/m);
59
59
  if (match) {
@@ -62,8 +62,16 @@ async function readInstalledSkillNames(projectDir) {
62
62
  }
63
63
  return names;
64
64
  }
65
- function runSkillsAdd(cwd) {
66
- return runSkillsCommand(cwd, ["add", "get-convex/agent-skills", "--yes"]);
65
+ function configuredSkillAgents(aiFilesConfig) {
66
+ const defaultAgents = ["claude-code", "codex"];
67
+ return aiFilesConfig?.skills?.agents ?? defaultAgents;
68
+ }
69
+ function runSkillsAdd(cwd, agents) {
70
+ const args = ["add", "get-convex/agent-skills", "--yes"];
71
+ for (const agent of agents) {
72
+ args.push("--agent", agent);
73
+ }
74
+ return runSkillsCommand(cwd, args);
67
75
  }
68
76
  function runSkillsRemove({
69
77
  cwd,
@@ -74,11 +82,14 @@ function runSkillsRemove({
74
82
  async function shouldRunSkillsCli() {
75
83
  const versionData = await (0, import_versionApi.getVersion)();
76
84
  if (versionData.kind === "error") return true;
77
- if (versionData.data.disableSkillsCli) {
78
- (0, import_log.logMessage)(import_chalk.chalkStderr.yellow(`Agent skills are temporarily disabled.`));
79
- return false;
85
+ if (versionData.kind === "ok") {
86
+ if (versionData.data.disableSkillsCli) {
87
+ (0, import_log.logMessage)(import_chalk.chalkStderr.yellow(`Agent skills are temporarily disabled.`));
88
+ return false;
89
+ }
90
+ return true;
80
91
  }
81
- return true;
92
+ return (0, import_utils.exhaustiveCheck)(versionData);
82
93
  }
83
94
  async function removeSkillsLockIfEmpty({
84
95
  projectDir,
@@ -105,11 +116,14 @@ async function removeSkillsLockIfEmpty({
105
116
  }
106
117
  async function installSkills({
107
118
  projectDir,
108
- config
119
+ state,
120
+ aiFilesConfig
109
121
  }) {
110
122
  if (!await shouldRunSkillsCli()) return;
123
+ const agents = configuredSkillAgents(aiFilesConfig);
124
+ if (agents.length === 0) return;
111
125
  (0, import_log.logMessage)("Installing Convex agent skills...");
112
- const skillsOk = await runSkillsAdd(projectDir);
126
+ const skillsOk = await runSkillsAdd(projectDir, agents);
113
127
  if (!skillsOk) {
114
128
  (0, import_log.logMessage)(
115
129
  import_chalk.chalkStderr.yellow(
@@ -119,15 +133,17 @@ async function installSkills({
119
133
  return;
120
134
  }
121
135
  const sha = await (0, import_versionApi.fetchAgentSkillsSha)();
122
- if (sha) config.agentSkillsSha = sha;
136
+ if (sha) state.agentSkillsSha = sha;
123
137
  const names = await readInstalledSkillNames(projectDir);
124
- if (names.length > 0) config.installedSkillNames = names;
138
+ if (names.length > 0) state.installedSkillNames = names;
139
+ (0, import_log.logMessage)(`${import_chalk.chalkStderr.green("\u2714")} Skills installed`);
125
140
  }
126
141
  async function removeInstalledSkills({
127
142
  projectDir,
128
143
  skillNames
129
144
  }) {
130
- if (skillNames.length === 0 || !await shouldRunSkillsCli()) return false;
145
+ if (skillNames.length === 0) return false;
146
+ if (!await shouldRunSkillsCli()) return false;
131
147
  (0, import_log.logMessage)(`Removing Convex agent skills: ${skillNames.join(", ")}`);
132
148
  const skillsOk = await runSkillsRemove({ cwd: projectDir, skillNames });
133
149
  if (!skillsOk) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/cli/lib/aiFiles/skills.ts"],
4
- "sourcesContent": ["import child_process from \"child_process\";\nimport path from \"path\";\n// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { getVersion, fetchAgentSkillsSha } from \"../versionApi.js\";\nimport { type AiFilesConfig } from \"./config.js\";\nimport { iife, readFileSafe } from \"./utils.js\";\n\n/**\n * Read the frontmatter `name:` values from skills installed by the skills CLI.\n */\nasync function readInstalledSkillNames(projectDir: string): Promise<string[]> {\n const skillsDir = path.join(projectDir, \".agents\", \"skills\");\n const entries = await iife(async () => {\n try {\n const dirents = await fs.readdir(skillsDir, { withFileTypes: true });\n return dirents\n .filter((d) => d.isDirectory() || d.isSymbolicLink())\n .map((d) => d.name);\n } catch {\n return [] as string[];\n }\n });\n if (entries.length === 0) return [];\n\n const names: string[] = [];\n for (const entry of entries) {\n const skillMdPath = path.join(skillsDir, entry, \"SKILL.md\");\n const content = await readFileSafe(skillMdPath);\n if (content === null) continue;\n const match = content.match(/^---[\\s\\S]*?^name:\\s*(.+?)\\s*$/m);\n if (match) {\n names.push(match[1]);\n }\n }\n return names;\n}\n\n/**\n * Runs `npx skills add get-convex/agent-skills --yes` in the given directory.\n * Returns true on success, false if the process fails or cannot be started.\n */\nfunction runSkillsAdd(cwd: string): Promise<boolean> {\n return runSkillsCommand(cwd, [\"add\", \"get-convex/agent-skills\", \"--yes\"]);\n}\n\n/**\n * Runs `npx skills remove <name...> --yes` to surgically remove only the\n * Convex-managed skills, leaving any skills from other sources intact.\n */\nfunction runSkillsRemove({\n cwd,\n skillNames,\n}: {\n cwd: string;\n skillNames: string[];\n}): Promise<boolean> {\n return runSkillsCommand(cwd, [\"remove\", ...skillNames, \"--yes\"]);\n}\n\n/**\n * This function exists so we have a way to disable skills installs without pushing a new\n * version of the convex CLI\n */\nasync function shouldRunSkillsCli(): Promise<boolean> {\n const versionData = await getVersion();\n\n if (versionData.kind === \"error\") return true;\n\n if (versionData.data.disableSkillsCli) {\n logMessage(chalkStderr.yellow(`Agent skills are temporarily disabled.`));\n return false;\n }\n\n return true;\n}\n\n/**\n * Remove the skills-lock.json file if it only contains skills that we\n * are removing. The `npx skills remove` command leaves the lockfile behind\n * even when it's logically empty.\n */\nasync function removeSkillsLockIfEmpty({\n projectDir,\n removedSkillNames,\n}: {\n projectDir: string;\n removedSkillNames: string[];\n}): Promise<boolean> {\n const lockPath = path.join(projectDir, \"skills-lock.json\");\n try {\n const content = await fs.readFile(lockPath, \"utf8\");\n const lock = JSON.parse(content);\n\n if (\n !lock ||\n typeof lock !== \"object\" ||\n !lock.skills ||\n typeof lock.skills !== \"object\"\n ) {\n return false;\n }\n\n const remainingSkills = Object.keys(lock.skills).filter(\n (name) => !removedSkillNames.includes(name),\n );\n\n if (remainingSkills.length === 0) {\n await fs.unlink(lockPath);\n return true;\n }\n return false;\n } catch {\n return false;\n }\n}\n\n/**\n * Install Convex agent skills and record the SHA and names into the config.\n * Handles the kill-switch check and all logging internally.\n */\nexport async function installSkills({\n projectDir,\n config,\n}: {\n projectDir: string;\n config: AiFilesConfig;\n}): Promise<void> {\n if (!(await shouldRunSkillsCli())) return;\n\n logMessage(\"Installing Convex agent skills...\");\n const skillsOk = await runSkillsAdd(projectDir);\n if (!skillsOk) {\n logMessage(\n chalkStderr.yellow(\n \"Could not install agent skills. You can retry manually with: npx skills add get-convex/agent-skills\",\n ),\n );\n return;\n }\n\n const sha = await fetchAgentSkillsSha();\n if (sha) config.agentSkillsSha = sha;\n\n const names = await readInstalledSkillNames(projectDir);\n if (names.length > 0) config.installedSkillNames = names;\n}\n\n/**\n * Remove Convex-managed agent skills and clean up the lock file if empty.\n * Returns true if any removal occurred.\n */\nexport async function removeInstalledSkills({\n projectDir,\n skillNames,\n}: {\n projectDir: string;\n skillNames: string[];\n}): Promise<boolean> {\n if (skillNames.length === 0 || !(await shouldRunSkillsCli())) return false;\n\n logMessage(`Removing Convex agent skills: ${skillNames.join(\", \")}`);\n const skillsOk = await runSkillsRemove({ cwd: projectDir, skillNames });\n if (!skillsOk) {\n logMessage(\n chalkStderr.yellow(\n \"Could not remove agent skills automatically. Remove them manually with: npx skills remove\",\n ),\n );\n return false;\n }\n\n const lockRemoved = await removeSkillsLockIfEmpty({\n projectDir,\n removedSkillNames: skillNames,\n });\n if (lockRemoved)\n logMessage(`${chalkStderr.green(\"\u2714\")} Deleted skills-lock.json.`);\n return true;\n}\n\nfunction runSkillsCommand(cwd: string, args: string[]): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = child_process.spawn(\n \"npx\",\n [\"--yes\", \"skills@latest\", ...args],\n {\n cwd,\n stdio: \"pipe\",\n // .cmd files on Windows require shell execution.\n shell: process.platform === \"win32\",\n },\n );\n let capturedOutput = \"\";\n proc.stdout?.on(\"data\", (chunk) => {\n capturedOutput += chunk.toString();\n });\n proc.stderr?.on(\"data\", (chunk) => {\n capturedOutput += chunk.toString();\n });\n proc.on(\"close\", (code) => {\n if (code !== 0 && capturedOutput.trim().length > 0) {\n const lines = capturedOutput.trim().split(/\\r?\\n/);\n const tail = lines.slice(-10).join(\"\\n\");\n logMessage(chalkStderr.gray(`skills output (tail):\\n${tail}`));\n }\n resolve(code === 0);\n });\n proc.on(\"error\", () => resolve(false));\n });\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import child_process from \"child_process\";\nimport path from \"path\";\n// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../../../bundler/log.js\";\nimport { getVersion, fetchAgentSkillsSha } from \"../versionApi.js\";\nimport { type AiFilesState } from \"./state.js\";\nimport { exhaustiveCheck, iife, readFileOrNull } from \"./utils.js\";\n\nimport { type AiFilesProjectConfig } from \"../config.js\";\n\n/**\n * Read the frontmatter `name:` values from skills installed by the skills CLI.\n */\nasync function readInstalledSkillNames(projectDir: string): Promise<string[]> {\n const skillsDir = path.join(projectDir, \".agents\", \"skills\");\n const entries = await iife(async () => {\n try {\n const dirents = await fs.readdir(skillsDir, { withFileTypes: true });\n return dirents\n .filter((d) => d.isDirectory() || d.isSymbolicLink())\n .map((d) => d.name);\n } catch {\n return [] as string[];\n }\n });\n if (entries.length === 0) return [];\n\n const names: string[] = [];\n for (const entry of entries) {\n const skillMdPath = path.join(skillsDir, entry, \"SKILL.md\");\n const content = await readFileOrNull(skillMdPath);\n if (content === null) continue;\n const match = content.match(/^---[\\s\\S]*?^name:\\s*(.+?)\\s*$/m);\n if (match) {\n names.push(match[1]);\n }\n }\n return names;\n}\n\n/**\n * Resolve the configured agent list, falling back to defaults.\n */\nfunction configuredSkillAgents(\n aiFilesConfig?: AiFilesProjectConfig | undefined,\n): string[] {\n // We default to the two most popular agents for now, \"codex\" installs to `.agents` which also\n // covers cursor and many other tools. See: https://github.com/vercel-labs/skills?tab=readme-ov-file#supported-agents\n const defaultAgents = [\"claude-code\", \"codex\"];\n return aiFilesConfig?.skills?.agents ?? defaultAgents;\n}\n\n/**\n * Runs `npx skills add get-convex/agent-skills --yes` in the given directory.\n * Returns true on success, false if the process fails or cannot be started.\n */\nfunction runSkillsAdd(cwd: string, agents: string[]): Promise<boolean> {\n const args = [\"add\", \"get-convex/agent-skills\", \"--yes\"];\n for (const agent of agents) {\n args.push(\"--agent\", agent);\n }\n return runSkillsCommand(cwd, args);\n}\n\n/**\n * Runs `npx skills remove <name...> --yes` to surgically remove only the\n * Convex-managed skills, leaving any skills from other sources intact.\n */\nfunction runSkillsRemove({\n cwd,\n skillNames,\n}: {\n cwd: string;\n skillNames: string[];\n}): Promise<boolean> {\n return runSkillsCommand(cwd, [\"remove\", ...skillNames, \"--yes\"]);\n}\n\n/**\n * This function exists so we have a way to disable skills installs without pushing a new\n * version of the convex CLI\n */\nasync function shouldRunSkillsCli(): Promise<boolean> {\n const versionData = await getVersion();\n\n if (versionData.kind === \"error\") return true;\n\n if (versionData.kind === \"ok\") {\n if (versionData.data.disableSkillsCli) {\n logMessage(chalkStderr.yellow(`Agent skills are temporarily disabled.`));\n return false;\n }\n return true;\n }\n\n return exhaustiveCheck(versionData);\n}\n\n/**\n * Remove the skills-lock.json file if it only contains skills that we\n * are removing. The `npx skills remove` command leaves the lockfile behind\n * even when it's logically empty.\n */\nasync function removeSkillsLockIfEmpty({\n projectDir,\n removedSkillNames,\n}: {\n projectDir: string;\n removedSkillNames: string[];\n}): Promise<boolean> {\n const lockPath = path.join(projectDir, \"skills-lock.json\");\n try {\n const content = await fs.readFile(lockPath, \"utf8\");\n const lock = JSON.parse(content);\n\n if (\n !lock ||\n typeof lock !== \"object\" ||\n !lock.skills ||\n typeof lock.skills !== \"object\"\n ) {\n return false;\n }\n\n const remainingSkills = Object.keys(lock.skills).filter(\n (name) => !removedSkillNames.includes(name),\n );\n\n if (remainingSkills.length === 0) {\n await fs.unlink(lockPath);\n return true;\n }\n return false;\n } catch {\n return false;\n }\n}\n\n/**\n * Install Convex agent skills and record the SHA and names into the state.\n * Handles the kill-switch check and all logging internally.\n */\nexport async function installSkills({\n projectDir,\n state,\n aiFilesConfig,\n}: {\n projectDir: string;\n state: AiFilesState;\n aiFilesConfig?: AiFilesProjectConfig | undefined;\n}): Promise<void> {\n if (!(await shouldRunSkillsCli())) return;\n const agents = configuredSkillAgents(aiFilesConfig);\n if (agents.length === 0) return;\n\n logMessage(\"Installing Convex agent skills...\");\n const skillsOk = await runSkillsAdd(projectDir, agents);\n if (!skillsOk) {\n logMessage(\n chalkStderr.yellow(\n \"Could not install agent skills. You can retry manually with: npx skills add get-convex/agent-skills\",\n ),\n );\n return;\n }\n\n const sha = await fetchAgentSkillsSha();\n if (sha) state.agentSkillsSha = sha;\n\n const names = await readInstalledSkillNames(projectDir);\n if (names.length > 0) state.installedSkillNames = names;\n\n logMessage(`${chalkStderr.green(\"\u2714\")} Skills installed`);\n}\n\n/**\n * Remove Convex-managed agent skills and clean up the lock file if empty.\n * Returns true if any removal occurred.\n */\nexport async function removeInstalledSkills({\n projectDir,\n skillNames,\n}: {\n projectDir: string;\n skillNames: string[];\n}): Promise<boolean> {\n if (skillNames.length === 0) return false;\n if (!(await shouldRunSkillsCli())) return false;\n\n logMessage(`Removing Convex agent skills: ${skillNames.join(\", \")}`);\n const skillsOk = await runSkillsRemove({ cwd: projectDir, skillNames });\n if (!skillsOk) {\n logMessage(\n chalkStderr.yellow(\n \"Could not remove agent skills automatically. Remove them manually with: npx skills remove\",\n ),\n );\n return false;\n }\n\n const lockRemoved = await removeSkillsLockIfEmpty({\n projectDir,\n removedSkillNames: skillNames,\n });\n\n if (lockRemoved)\n logMessage(`${chalkStderr.green(\"\u2714\")} Deleted skills-lock.json.`);\n\n return true;\n}\n\nfunction runSkillsCommand(cwd: string, args: string[]): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = child_process.spawn(\n \"npx\",\n [\"--yes\", \"skills@latest\", ...args],\n {\n cwd,\n stdio: \"pipe\",\n // .cmd files on Windows require shell execution.\n shell: process.platform === \"win32\",\n },\n );\n let capturedOutput = \"\";\n proc.stdout?.on(\"data\", (chunk) => {\n capturedOutput += chunk.toString();\n });\n proc.stderr?.on(\"data\", (chunk) => {\n capturedOutput += chunk.toString();\n });\n proc.on(\"close\", (code) => {\n if (code !== 0 && capturedOutput.trim().length > 0) {\n const lines = capturedOutput.trim().split(/\\r?\\n/);\n const tail = lines.slice(-10).join(\"\\n\");\n logMessage(chalkStderr.gray(`skills output (tail):\\n${tail}`));\n }\n resolve(code === 0);\n });\n proc.on(\"error\", () => resolve(false));\n });\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["path", "fs", "child_process"]
7
7
  }
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var state_exports = {};
30
+ __export(state_exports, {
31
+ aiFilesStateSchema: () => aiFilesStateSchema,
32
+ attemptReadAiState: () => attemptReadAiState,
33
+ hasAiState: () => hasAiState,
34
+ readAiStateOrDefault: () => readAiStateOrDefault,
35
+ writeAiState: () => writeAiState
36
+ });
37
+ module.exports = __toCommonJS(state_exports);
38
+ var Sentry = __toESM(require("@sentry/node"), 1);
39
+ var import_fs = require("fs");
40
+ var import_zod = require("zod");
41
+ var import_paths = require("./paths.js");
42
+ var import_utils = require("./utils.js");
43
+ const aiFilesStateSchema = import_zod.z.object({
44
+ guidelinesHash: import_zod.z.string().nullable(),
45
+ agentsMdSectionHash: import_zod.z.string().nullable(),
46
+ claudeMdHash: import_zod.z.string().nullable(),
47
+ // Commit SHA from get-convex/agent-skills that was current when skills were
48
+ // last installed. Used to detect when newer skills are available.
49
+ agentSkillsSha: import_zod.z.string().nullable(),
50
+ // Names of skills installed by `npx skills add`, used by `remove` to
51
+ // only remove Convex-managed skills.
52
+ installedSkillNames: import_zod.z.array(import_zod.z.string()).default([])
53
+ });
54
+ const DEFAULT_AI_STATE = {
55
+ guidelinesHash: null,
56
+ agentsMdSectionHash: null,
57
+ claudeMdHash: null,
58
+ agentSkillsSha: null,
59
+ installedSkillNames: []
60
+ };
61
+ async function attemptReadAiState(convexDir) {
62
+ const result = await (0, import_utils.attemptReadFile)((0, import_paths.aiFilesStatePathForConvexDir)(convexDir));
63
+ if (result.kind === "not-found" || result.kind === "empty")
64
+ return { kind: "no-file" };
65
+ try {
66
+ const state = aiFilesStateSchema.parse(JSON.parse(result.content));
67
+ return { kind: "ok", state };
68
+ } catch (error) {
69
+ Sentry.captureException(error);
70
+ return { kind: "parse-error", error };
71
+ }
72
+ }
73
+ async function readAiStateOrDefault(convexDir) {
74
+ const result = await attemptReadAiState(convexDir);
75
+ if (result.kind === "ok") return result.state;
76
+ if (result.kind === "no-file") return { ...DEFAULT_AI_STATE };
77
+ if (result.kind === "parse-error") return { ...DEFAULT_AI_STATE };
78
+ return (0, import_utils.exhaustiveCheck)(result);
79
+ }
80
+ async function hasAiState(convexDir) {
81
+ const result = await attemptReadAiState(convexDir);
82
+ return result.kind === "ok";
83
+ }
84
+ async function writeAiState({
85
+ state,
86
+ convexDir
87
+ }) {
88
+ const validated = aiFilesStateSchema.parse(state);
89
+ await import_fs.promises.mkdir((0, import_paths.aiDirForConvexDir)(convexDir), { recursive: true });
90
+ await import_fs.promises.writeFile(
91
+ (0, import_paths.aiFilesStatePathForConvexDir)(convexDir),
92
+ JSON.stringify(validated, null, 2) + "\n",
93
+ "utf8"
94
+ );
95
+ }
96
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/cli/lib/aiFiles/state.ts"],
4
+ "sourcesContent": ["import * as Sentry from \"@sentry/node\";\n// Use raw fs (not ctx.fs) so these operations run asynchronously and don't\n// interfere with the file-watcher used by `convex dev`.\n// eslint-disable-next-line no-restricted-imports\nimport { promises as fs } from \"fs\";\nimport { z } from \"zod\";\nimport { aiDirForConvexDir, aiFilesStatePathForConvexDir } from \"./paths.js\";\nimport { attemptReadFile, exhaustiveCheck } from \"./utils.js\";\n\nexport const aiFilesStateSchema = z.object({\n guidelinesHash: z.string().nullable(),\n agentsMdSectionHash: z.string().nullable(),\n claudeMdHash: z.string().nullable(),\n // Commit SHA from get-convex/agent-skills that was current when skills were\n // last installed. Used to detect when newer skills are available.\n agentSkillsSha: z.string().nullable(),\n // Names of skills installed by `npx skills add`, used by `remove` to\n // only remove Convex-managed skills.\n installedSkillNames: z.array(z.string()).default([]),\n});\n\nexport type AiFilesState = z.infer<typeof aiFilesStateSchema>;\n\nconst DEFAULT_AI_STATE: AiFilesState = {\n guidelinesHash: null,\n agentsMdSectionHash: null,\n claudeMdHash: null,\n agentSkillsSha: null,\n installedSkillNames: [],\n};\n\nexport type AttemptReadAiStateResult =\n | { kind: \"no-file\" }\n | { kind: \"ok\"; state: AiFilesState }\n | { kind: \"parse-error\"; error: unknown };\n\nexport async function attemptReadAiState(\n convexDir: string,\n): Promise<AttemptReadAiStateResult> {\n const result = await attemptReadFile(aiFilesStatePathForConvexDir(convexDir));\n if (result.kind === \"not-found\" || result.kind === \"empty\")\n return { kind: \"no-file\" };\n\n try {\n const state = aiFilesStateSchema.parse(JSON.parse(result.content));\n return { kind: \"ok\", state };\n } catch (error) {\n Sentry.captureException(error);\n return { kind: \"parse-error\", error };\n }\n}\n\nexport async function readAiStateOrDefault(\n convexDir: string,\n): Promise<AiFilesState> {\n const result = await attemptReadAiState(convexDir);\n if (result.kind === \"ok\") return result.state;\n if (result.kind === \"no-file\") return { ...DEFAULT_AI_STATE };\n if (result.kind === \"parse-error\") return { ...DEFAULT_AI_STATE };\n return exhaustiveCheck(result);\n}\n\nexport async function hasAiState(convexDir: string): Promise<boolean> {\n const result = await attemptReadAiState(convexDir);\n return result.kind === \"ok\";\n}\n\nexport async function writeAiState({\n state,\n convexDir,\n}: {\n state: AiFilesState;\n convexDir: string;\n}): Promise<void> {\n const validated = aiFilesStateSchema.parse(state);\n await fs.mkdir(aiDirForConvexDir(convexDir), { recursive: true });\n await fs.writeFile(\n aiFilesStatePathForConvexDir(convexDir),\n JSON.stringify(validated, null, 2) + \"\\n\",\n \"utf8\",\n );\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAAwB;AAIxB,gBAA+B;AAC/B,iBAAkB;AAClB,mBAAgE;AAChE,mBAAiD;AAE1C,MAAM,qBAAqB,aAAE,OAAO;AAAA,EACzC,gBAAgB,aAAE,OAAO,EAAE,SAAS;AAAA,EACpC,qBAAqB,aAAE,OAAO,EAAE,SAAS;AAAA,EACzC,cAAc,aAAE,OAAO,EAAE,SAAS;AAAA;AAAA;AAAA,EAGlC,gBAAgB,aAAE,OAAO,EAAE,SAAS;AAAA;AAAA;AAAA,EAGpC,qBAAqB,aAAE,MAAM,aAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AACrD,CAAC;AAID,MAAM,mBAAiC;AAAA,EACrC,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,qBAAqB,CAAC;AACxB;AAOA,eAAsB,mBACpB,WACmC;AACnC,QAAM,SAAS,UAAM,kCAAgB,2CAA6B,SAAS,CAAC;AAC5E,MAAI,OAAO,SAAS,eAAe,OAAO,SAAS;AACjD,WAAO,EAAE,MAAM,UAAU;AAE3B,MAAI;AACF,UAAM,QAAQ,mBAAmB,MAAM,KAAK,MAAM,OAAO,OAAO,CAAC;AACjE,WAAO,EAAE,MAAM,MAAM,MAAM;AAAA,EAC7B,SAAS,OAAO;AACd,WAAO,iBAAiB,KAAK;AAC7B,WAAO,EAAE,MAAM,eAAe,MAAM;AAAA,EACtC;AACF;AAEA,eAAsB,qBACpB,WACuB;AACvB,QAAM,SAAS,MAAM,mBAAmB,SAAS;AACjD,MAAI,OAAO,SAAS,KAAM,QAAO,OAAO;AACxC,MAAI,OAAO,SAAS,UAAW,QAAO,EAAE,GAAG,iBAAiB;AAC5D,MAAI,OAAO,SAAS,cAAe,QAAO,EAAE,GAAG,iBAAiB;AAChE,aAAO,8BAAgB,MAAM;AAC/B;AAEA,eAAsB,WAAW,WAAqC;AACpE,QAAM,SAAS,MAAM,mBAAmB,SAAS;AACjD,SAAO,OAAO,SAAS;AACzB;AAEA,eAAsB,aAAa;AAAA,EACjC;AAAA,EACA;AACF,GAGkB;AAChB,QAAM,YAAY,mBAAmB,MAAM,KAAK;AAChD,QAAM,UAAAA,SAAG,UAAM,gCAAkB,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AAChE,QAAM,UAAAA,SAAG;AAAA,QACP,2CAA6B,SAAS;AAAA,IACtC,KAAK,UAAU,WAAW,MAAM,CAAC,IAAI;AAAA,IACrC;AAAA,EACF;AACF;",
6
+ "names": ["fs"]
7
+ }