convex 1.48.0-alpha.0 → 1.48.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 (353) hide show
  1. package/CHANGELOG.md +28 -4
  2. package/README.md +1 -1
  3. package/dist/browser.bundle.js +1 -1
  4. package/dist/browser.bundle.js.map +1 -1
  5. package/dist/cjs/bundler/context.js +5 -7
  6. package/dist/cjs/bundler/context.js.map +2 -2
  7. package/dist/cjs/bundler/fs.js +6 -47
  8. package/dist/cjs/bundler/fs.js.map +2 -2
  9. package/dist/cjs/cli/aiFiles.js +26 -4
  10. package/dist/cjs/cli/aiFiles.js.map +2 -2
  11. package/dist/cjs/cli/configure.js +2 -15
  12. package/dist/cjs/cli/configure.js.map +2 -2
  13. package/dist/cjs/cli/env.js +6 -3
  14. package/dist/cjs/cli/env.js.map +2 -2
  15. package/dist/cjs/cli/envDefault.js +5 -2
  16. package/dist/cjs/cli/envDefault.js.map +2 -2
  17. package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js +2 -1
  18. package/dist/cjs/cli/lib/aiFiles/guidelinesmd.js.map +2 -2
  19. package/dist/cjs/cli/lib/aiFiles/index.js +13 -2
  20. package/dist/cjs/cli/lib/aiFiles/index.js.map +2 -2
  21. package/dist/cjs/cli/lib/aiFiles/skills.js +6 -5
  22. package/dist/cjs/cli/lib/aiFiles/skills.js.map +2 -2
  23. package/dist/cjs/cli/lib/aiFiles/state.js +1 -1
  24. package/dist/cjs/cli/lib/aiFiles/state.js.map +1 -1
  25. package/dist/cjs/cli/lib/components.js +12 -2
  26. package/dist/cjs/cli/lib/components.js.map +2 -2
  27. package/dist/cjs/cli/lib/deployApi/startPush.js +42 -1
  28. package/dist/cjs/cli/lib/deployApi/startPush.js.map +2 -2
  29. package/dist/cjs/cli/lib/deployment.js +0 -2
  30. package/dist/cjs/cli/lib/deployment.js.map +2 -2
  31. package/dist/cjs/cli/lib/deploymentSelection.js +18 -27
  32. package/dist/cjs/cli/lib/deploymentSelection.js.map +2 -2
  33. package/dist/cjs/cli/lib/env.js +9 -1
  34. package/dist/cjs/cli/lib/env.js.map +2 -2
  35. package/dist/cjs/cli/lib/envvars.js +0 -32
  36. package/dist/cjs/cli/lib/envvars.js.map +2 -2
  37. package/dist/cjs/cli/lib/fsUtils.js +1 -1
  38. package/dist/cjs/cli/lib/fsUtils.js.map +2 -2
  39. package/dist/cjs/cli/lib/generateDocs.js +1 -1
  40. package/dist/cjs/cli/lib/generateDocs.js.map +1 -1
  41. package/dist/cjs/cli/lib/localDeployment/dashboard.js +11 -1
  42. package/dist/cjs/cli/lib/localDeployment/dashboard.js.map +2 -2
  43. package/dist/cjs/cli/lib/localDeployment/download.js +16 -1
  44. package/dist/cjs/cli/lib/localDeployment/download.js.map +2 -2
  45. package/dist/cjs/cli/lib/localDeployment/utils.js +4 -0
  46. package/dist/cjs/cli/lib/localDeployment/utils.js.map +2 -2
  47. package/dist/cjs/cli/lib/login.js +4 -28
  48. package/dist/cjs/cli/lib/login.js.map +2 -2
  49. package/dist/cjs/cli/lib/mcp/requestContext.js +1 -5
  50. package/dist/cjs/cli/lib/mcp/requestContext.js.map +2 -2
  51. package/dist/cjs/cli/lib/utils/aiAgent.js +32 -0
  52. package/dist/cjs/cli/lib/utils/aiAgent.js.map +7 -0
  53. package/dist/cjs/cli/lib/utils/utils.js +9 -18
  54. package/dist/cjs/cli/lib/utils/utils.js.map +2 -2
  55. package/dist/cjs/cli/login.js +114 -213
  56. package/dist/cjs/cli/login.js.map +3 -3
  57. package/dist/cjs/cli/logout.js +12 -113
  58. package/dist/cjs/cli/logout.js.map +3 -3
  59. package/dist/cjs/cli/mcp.js +10 -43
  60. package/dist/cjs/cli/mcp.js.map +3 -3
  61. package/dist/cjs/cli/program.js +1 -2
  62. package/dist/cjs/cli/program.js.map +2 -2
  63. package/dist/cjs/index.js +1 -1
  64. package/dist/cjs/index.js.map +1 -1
  65. package/dist/cjs/server/authentication.js.map +1 -1
  66. package/dist/cjs/server/components/index.js.map +2 -2
  67. package/dist/cjs/server/impl/authentication_impl.js +15 -1
  68. package/dist/cjs/server/impl/authentication_impl.js.map +2 -2
  69. package/dist/cjs/server/impl/registration_impl.js +1 -1
  70. package/dist/cjs/server/impl/registration_impl.js.map +2 -2
  71. package/dist/cjs/server/index.js.map +2 -2
  72. package/dist/cjs/server/meta.js.map +1 -1
  73. package/dist/cjs/server/registration.js.map +1 -1
  74. package/dist/cjs/server/schema.js +0 -2
  75. package/dist/cjs/server/schema.js.map +2 -2
  76. package/dist/cjs/server/storage.js.map +1 -1
  77. package/dist/cjs-types/bundler/context.d.ts +0 -5
  78. package/dist/cjs-types/bundler/context.d.ts.map +1 -1
  79. package/dist/cjs-types/bundler/fs.d.ts +2 -7
  80. package/dist/cjs-types/bundler/fs.d.ts.map +1 -1
  81. package/dist/cjs-types/cli/aiFiles.d.ts.map +1 -1
  82. package/dist/cjs-types/cli/configure.d.ts.map +1 -1
  83. package/dist/cjs-types/cli/env.d.ts.map +1 -1
  84. package/dist/cjs-types/cli/envDefault.d.ts.map +1 -1
  85. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts +3 -1
  86. package/dist/cjs-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -1
  87. package/dist/cjs-types/cli/lib/aiFiles/index.d.ts +11 -1
  88. package/dist/cjs-types/cli/lib/aiFiles/index.d.ts.map +1 -1
  89. package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts +4 -1
  90. package/dist/cjs-types/cli/lib/aiFiles/skills.d.ts.map +1 -1
  91. package/dist/cjs-types/cli/lib/components.d.ts.map +1 -1
  92. package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts +13 -0
  93. package/dist/cjs-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
  94. package/dist/cjs-types/cli/lib/deployment.d.ts +0 -2
  95. package/dist/cjs-types/cli/lib/deployment.d.ts.map +1 -1
  96. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts +1 -2
  97. package/dist/cjs-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  98. package/dist/cjs-types/cli/lib/env.d.ts +1 -0
  99. package/dist/cjs-types/cli/lib/env.d.ts.map +1 -1
  100. package/dist/cjs-types/cli/lib/envvars.d.ts +0 -6
  101. package/dist/cjs-types/cli/lib/envvars.d.ts.map +1 -1
  102. package/dist/cjs-types/cli/lib/fsUtils.d.ts +0 -1
  103. package/dist/cjs-types/cli/lib/fsUtils.d.ts.map +1 -1
  104. package/dist/cjs-types/cli/lib/localDeployment/dashboard.d.ts +6 -0
  105. package/dist/cjs-types/cli/lib/localDeployment/dashboard.d.ts.map +1 -1
  106. package/dist/cjs-types/cli/lib/localDeployment/download.d.ts.map +1 -1
  107. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts +1 -0
  108. package/dist/cjs-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  109. package/dist/cjs-types/cli/lib/login.d.ts +1 -3
  110. package/dist/cjs-types/cli/lib/login.d.ts.map +1 -1
  111. package/dist/cjs-types/cli/lib/mcp/requestContext.d.ts.map +1 -1
  112. package/dist/cjs-types/cli/lib/mcp/tools/insights.d.ts +2 -2
  113. package/dist/cjs-types/cli/lib/utils/aiAgent.d.ts +8 -0
  114. package/dist/cjs-types/cli/lib/utils/aiAgent.d.ts.map +1 -0
  115. package/dist/cjs-types/cli/lib/utils/utils.d.ts +0 -5
  116. package/dist/cjs-types/cli/lib/utils/utils.d.ts.map +1 -1
  117. package/dist/cjs-types/cli/login.d.ts +0 -21
  118. package/dist/cjs-types/cli/login.d.ts.map +1 -1
  119. package/dist/cjs-types/cli/logout.d.ts +1 -8
  120. package/dist/cjs-types/cli/logout.d.ts.map +1 -1
  121. package/dist/cjs-types/cli/mcp.d.ts.map +1 -1
  122. package/dist/cjs-types/cli/program.d.ts.map +1 -1
  123. package/dist/cjs-types/index.d.ts +1 -1
  124. package/dist/cjs-types/index.d.ts.map +1 -1
  125. package/dist/cjs-types/server/authentication.d.ts +65 -0
  126. package/dist/cjs-types/server/authentication.d.ts.map +1 -1
  127. package/dist/cjs-types/server/components/index.d.ts +6 -0
  128. package/dist/cjs-types/server/components/index.d.ts.map +1 -1
  129. package/dist/cjs-types/server/impl/authentication_impl.d.ts +2 -1
  130. package/dist/cjs-types/server/impl/authentication_impl.d.ts.map +1 -1
  131. package/dist/cjs-types/server/index.d.ts +2 -2
  132. package/dist/cjs-types/server/index.d.ts.map +1 -1
  133. package/dist/cjs-types/server/meta.d.ts +8 -0
  134. package/dist/cjs-types/server/meta.d.ts.map +1 -1
  135. package/dist/cjs-types/server/registration.d.ts +5 -3
  136. package/dist/cjs-types/server/registration.d.ts.map +1 -1
  137. package/dist/cjs-types/server/schema.d.ts +0 -2
  138. package/dist/cjs-types/server/schema.d.ts.map +1 -1
  139. package/dist/cjs-types/server/storage.d.ts +28 -25
  140. package/dist/cjs-types/server/storage.d.ts.map +1 -1
  141. package/dist/cli.bundle.cjs +1379 -2142
  142. package/dist/cli.bundle.cjs.map +4 -4
  143. package/dist/esm/bundler/context.js +5 -7
  144. package/dist/esm/bundler/context.js.map +2 -2
  145. package/dist/esm/bundler/fs.js +6 -47
  146. package/dist/esm/bundler/fs.js.map +2 -2
  147. package/dist/esm/cli/aiFiles.js +26 -4
  148. package/dist/esm/cli/aiFiles.js.map +2 -2
  149. package/dist/esm/cli/configure.js +2 -15
  150. package/dist/esm/cli/configure.js.map +2 -2
  151. package/dist/esm/cli/env.js +6 -3
  152. package/dist/esm/cli/env.js.map +2 -2
  153. package/dist/esm/cli/envDefault.js +5 -2
  154. package/dist/esm/cli/envDefault.js.map +2 -2
  155. package/dist/esm/cli/lib/aiFiles/guidelinesmd.js +2 -1
  156. package/dist/esm/cli/lib/aiFiles/guidelinesmd.js.map +2 -2
  157. package/dist/esm/cli/lib/aiFiles/index.js +13 -2
  158. package/dist/esm/cli/lib/aiFiles/index.js.map +2 -2
  159. package/dist/esm/cli/lib/aiFiles/skills.js +6 -5
  160. package/dist/esm/cli/lib/aiFiles/skills.js.map +2 -2
  161. package/dist/esm/cli/lib/aiFiles/state.js +1 -1
  162. package/dist/esm/cli/lib/aiFiles/state.js.map +1 -1
  163. package/dist/esm/cli/lib/components.js +15 -2
  164. package/dist/esm/cli/lib/components.js.map +2 -2
  165. package/dist/esm/cli/lib/deployApi/startPush.js +39 -0
  166. package/dist/esm/cli/lib/deployApi/startPush.js.map +2 -2
  167. package/dist/esm/cli/lib/deployment.js +2 -2
  168. package/dist/esm/cli/lib/deployment.js.map +2 -2
  169. package/dist/esm/cli/lib/deploymentSelection.js +20 -35
  170. package/dist/esm/cli/lib/deploymentSelection.js.map +2 -2
  171. package/dist/esm/cli/lib/env.js +9 -1
  172. package/dist/esm/cli/lib/env.js.map +2 -2
  173. package/dist/esm/cli/lib/envvars.js +1 -35
  174. package/dist/esm/cli/lib/envvars.js.map +2 -2
  175. package/dist/esm/cli/lib/fsUtils.js +1 -1
  176. package/dist/esm/cli/lib/fsUtils.js.map +2 -2
  177. package/dist/esm/cli/lib/generateDocs.js +1 -1
  178. package/dist/esm/cli/lib/generateDocs.js.map +1 -1
  179. package/dist/esm/cli/lib/localDeployment/dashboard.js +9 -0
  180. package/dist/esm/cli/lib/localDeployment/dashboard.js.map +2 -2
  181. package/dist/esm/cli/lib/localDeployment/download.js +16 -1
  182. package/dist/esm/cli/lib/localDeployment/download.js.map +2 -2
  183. package/dist/esm/cli/lib/localDeployment/utils.js +3 -0
  184. package/dist/esm/cli/lib/localDeployment/utils.js.map +2 -2
  185. package/dist/esm/cli/lib/login.js +4 -36
  186. package/dist/esm/cli/lib/login.js.map +2 -2
  187. package/dist/esm/cli/lib/mcp/requestContext.js +1 -5
  188. package/dist/esm/cli/lib/mcp/requestContext.js.map +2 -2
  189. package/dist/esm/cli/lib/utils/aiAgent.js +10 -0
  190. package/dist/esm/cli/lib/utils/aiAgent.js.map +7 -0
  191. package/dist/esm/cli/lib/utils/utils.js +9 -16
  192. package/dist/esm/cli/lib/utils/utils.js.map +2 -2
  193. package/dist/esm/cli/login.js +112 -225
  194. package/dist/esm/cli/login.js.map +3 -3
  195. package/dist/esm/cli/logout.js +13 -110
  196. package/dist/esm/cli/logout.js.map +2 -2
  197. package/dist/esm/cli/mcp.js +10 -34
  198. package/dist/esm/cli/mcp.js.map +2 -2
  199. package/dist/esm/cli/program.js +1 -2
  200. package/dist/esm/cli/program.js.map +2 -2
  201. package/dist/esm/index.js +1 -1
  202. package/dist/esm/index.js.map +1 -1
  203. package/dist/esm/server/components/index.js.map +2 -2
  204. package/dist/esm/server/impl/authentication_impl.js +13 -0
  205. package/dist/esm/server/impl/authentication_impl.js.map +2 -2
  206. package/dist/esm/server/impl/registration_impl.js +2 -2
  207. package/dist/esm/server/impl/registration_impl.js.map +2 -2
  208. package/dist/esm/server/index.js.map +2 -2
  209. package/dist/esm/server/schema.js +0 -2
  210. package/dist/esm/server/schema.js.map +2 -2
  211. package/dist/esm-types/bundler/context.d.ts +0 -5
  212. package/dist/esm-types/bundler/context.d.ts.map +1 -1
  213. package/dist/esm-types/bundler/fs.d.ts +2 -7
  214. package/dist/esm-types/bundler/fs.d.ts.map +1 -1
  215. package/dist/esm-types/cli/aiFiles.d.ts.map +1 -1
  216. package/dist/esm-types/cli/configure.d.ts.map +1 -1
  217. package/dist/esm-types/cli/env.d.ts.map +1 -1
  218. package/dist/esm-types/cli/envDefault.d.ts.map +1 -1
  219. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts +3 -1
  220. package/dist/esm-types/cli/lib/aiFiles/guidelinesmd.d.ts.map +1 -1
  221. package/dist/esm-types/cli/lib/aiFiles/index.d.ts +11 -1
  222. package/dist/esm-types/cli/lib/aiFiles/index.d.ts.map +1 -1
  223. package/dist/esm-types/cli/lib/aiFiles/skills.d.ts +4 -1
  224. package/dist/esm-types/cli/lib/aiFiles/skills.d.ts.map +1 -1
  225. package/dist/esm-types/cli/lib/components.d.ts.map +1 -1
  226. package/dist/esm-types/cli/lib/deployApi/startPush.d.ts +13 -0
  227. package/dist/esm-types/cli/lib/deployApi/startPush.d.ts.map +1 -1
  228. package/dist/esm-types/cli/lib/deployment.d.ts +0 -2
  229. package/dist/esm-types/cli/lib/deployment.d.ts.map +1 -1
  230. package/dist/esm-types/cli/lib/deploymentSelection.d.ts +1 -2
  231. package/dist/esm-types/cli/lib/deploymentSelection.d.ts.map +1 -1
  232. package/dist/esm-types/cli/lib/env.d.ts +1 -0
  233. package/dist/esm-types/cli/lib/env.d.ts.map +1 -1
  234. package/dist/esm-types/cli/lib/envvars.d.ts +0 -6
  235. package/dist/esm-types/cli/lib/envvars.d.ts.map +1 -1
  236. package/dist/esm-types/cli/lib/fsUtils.d.ts +0 -1
  237. package/dist/esm-types/cli/lib/fsUtils.d.ts.map +1 -1
  238. package/dist/esm-types/cli/lib/localDeployment/dashboard.d.ts +6 -0
  239. package/dist/esm-types/cli/lib/localDeployment/dashboard.d.ts.map +1 -1
  240. package/dist/esm-types/cli/lib/localDeployment/download.d.ts.map +1 -1
  241. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts +1 -0
  242. package/dist/esm-types/cli/lib/localDeployment/utils.d.ts.map +1 -1
  243. package/dist/esm-types/cli/lib/login.d.ts +1 -3
  244. package/dist/esm-types/cli/lib/login.d.ts.map +1 -1
  245. package/dist/esm-types/cli/lib/mcp/requestContext.d.ts.map +1 -1
  246. package/dist/esm-types/cli/lib/mcp/tools/insights.d.ts +2 -2
  247. package/dist/esm-types/cli/lib/utils/aiAgent.d.ts +8 -0
  248. package/dist/esm-types/cli/lib/utils/aiAgent.d.ts.map +1 -0
  249. package/dist/esm-types/cli/lib/utils/utils.d.ts +0 -5
  250. package/dist/esm-types/cli/lib/utils/utils.d.ts.map +1 -1
  251. package/dist/esm-types/cli/login.d.ts +0 -21
  252. package/dist/esm-types/cli/login.d.ts.map +1 -1
  253. package/dist/esm-types/cli/logout.d.ts +1 -8
  254. package/dist/esm-types/cli/logout.d.ts.map +1 -1
  255. package/dist/esm-types/cli/mcp.d.ts.map +1 -1
  256. package/dist/esm-types/cli/program.d.ts.map +1 -1
  257. package/dist/esm-types/index.d.ts +1 -1
  258. package/dist/esm-types/index.d.ts.map +1 -1
  259. package/dist/esm-types/server/authentication.d.ts +65 -0
  260. package/dist/esm-types/server/authentication.d.ts.map +1 -1
  261. package/dist/esm-types/server/components/index.d.ts +6 -0
  262. package/dist/esm-types/server/components/index.d.ts.map +1 -1
  263. package/dist/esm-types/server/impl/authentication_impl.d.ts +2 -1
  264. package/dist/esm-types/server/impl/authentication_impl.d.ts.map +1 -1
  265. package/dist/esm-types/server/index.d.ts +2 -2
  266. package/dist/esm-types/server/index.d.ts.map +1 -1
  267. package/dist/esm-types/server/meta.d.ts +8 -0
  268. package/dist/esm-types/server/meta.d.ts.map +1 -1
  269. package/dist/esm-types/server/registration.d.ts +5 -3
  270. package/dist/esm-types/server/registration.d.ts.map +1 -1
  271. package/dist/esm-types/server/schema.d.ts +0 -2
  272. package/dist/esm-types/server/schema.d.ts.map +1 -1
  273. package/dist/esm-types/server/storage.d.ts +28 -25
  274. package/dist/esm-types/server/storage.d.ts.map +1 -1
  275. package/dist/react.bundle.js +1 -1
  276. package/dist/react.bundle.js.map +1 -1
  277. package/package.json +3 -2
  278. package/schemas/convex.schema.json +1 -2
  279. package/src/bundler/context.ts +5 -9
  280. package/src/bundler/fs.ts +5 -54
  281. package/src/cli/aiFiles.ts +30 -4
  282. package/src/cli/configure.ts +2 -18
  283. package/src/cli/env.ts +4 -1
  284. package/src/cli/envDefault.ts +4 -1
  285. package/src/cli/lib/aiFiles/guidelinesmd.ts +7 -2
  286. package/src/cli/lib/aiFiles/index.ts +23 -3
  287. package/src/cli/lib/aiFiles/skills.ts +11 -7
  288. package/src/cli/lib/aiFiles/state.ts +1 -1
  289. package/src/cli/lib/components.ts +18 -3
  290. package/src/cli/lib/deployApi/startPush.ts +64 -0
  291. package/src/cli/lib/deployment.ts +2 -2
  292. package/src/cli/lib/deploymentSelection.ts +18 -37
  293. package/src/cli/lib/env.ts +13 -2
  294. package/src/cli/lib/envvars.ts +1 -43
  295. package/src/cli/lib/fsUtils.ts +2 -5
  296. package/src/cli/lib/generateDocs.ts +1 -1
  297. package/src/cli/lib/localDeployment/dashboard.ts +19 -0
  298. package/src/cli/lib/localDeployment/download.ts +17 -1
  299. package/src/cli/lib/localDeployment/utils.ts +4 -0
  300. package/src/cli/lib/login.ts +3 -47
  301. package/src/cli/lib/mcp/requestContext.ts +1 -7
  302. package/src/cli/lib/utils/aiAgent.ts +15 -0
  303. package/src/cli/lib/utils/utils.ts +15 -19
  304. package/src/cli/login.ts +168 -293
  305. package/src/cli/logout.ts +17 -142
  306. package/src/cli/mcp.ts +11 -48
  307. package/src/cli/program.ts +0 -2
  308. package/src/index.ts +1 -1
  309. package/src/server/authentication.ts +79 -0
  310. package/src/server/components/index.ts +11 -0
  311. package/src/server/impl/authentication_impl.ts +15 -1
  312. package/src/server/impl/registration_impl.ts +2 -2
  313. package/src/server/index.ts +6 -0
  314. package/src/server/meta.ts +0 -8
  315. package/src/server/registration.ts +5 -2
  316. package/src/server/schema.ts +0 -2
  317. package/src/server/storage.ts +29 -42
  318. package/dist/cjs/cli/account.js +0 -237
  319. package/dist/cjs/cli/account.js.map +0 -7
  320. package/dist/cjs/cli/lib/deployKeyWarning.js +0 -43
  321. package/dist/cjs/cli/lib/deployKeyWarning.js.map +0 -7
  322. package/dist/cjs/cli/lib/profileManagement.js +0 -196
  323. package/dist/cjs/cli/lib/profileManagement.js.map +0 -7
  324. package/dist/cjs/cli/lib/profiles.js +0 -333
  325. package/dist/cjs/cli/lib/profiles.js.map +0 -7
  326. package/dist/cjs-types/cli/account.d.ts +0 -6
  327. package/dist/cjs-types/cli/account.d.ts.map +0 -1
  328. package/dist/cjs-types/cli/lib/deployKeyWarning.d.ts +0 -3
  329. package/dist/cjs-types/cli/lib/deployKeyWarning.d.ts.map +0 -1
  330. package/dist/cjs-types/cli/lib/profileManagement.d.ts +0 -10
  331. package/dist/cjs-types/cli/lib/profileManagement.d.ts.map +0 -1
  332. package/dist/cjs-types/cli/lib/profiles.d.ts +0 -59
  333. package/dist/cjs-types/cli/lib/profiles.d.ts.map +0 -1
  334. package/dist/esm/cli/account.js +0 -221
  335. package/dist/esm/cli/account.js.map +0 -7
  336. package/dist/esm/cli/lib/deployKeyWarning.js +0 -27
  337. package/dist/esm/cli/lib/deployKeyWarning.js.map +0 -7
  338. package/dist/esm/cli/lib/profileManagement.js +0 -179
  339. package/dist/esm/cli/lib/profileManagement.js.map +0 -7
  340. package/dist/esm/cli/lib/profiles.js +0 -288
  341. package/dist/esm/cli/lib/profiles.js.map +0 -7
  342. package/dist/esm-types/cli/account.d.ts +0 -6
  343. package/dist/esm-types/cli/account.d.ts.map +0 -1
  344. package/dist/esm-types/cli/lib/deployKeyWarning.d.ts +0 -3
  345. package/dist/esm-types/cli/lib/deployKeyWarning.d.ts.map +0 -1
  346. package/dist/esm-types/cli/lib/profileManagement.d.ts +0 -10
  347. package/dist/esm-types/cli/lib/profileManagement.d.ts.map +0 -1
  348. package/dist/esm-types/cli/lib/profiles.d.ts +0 -59
  349. package/dist/esm-types/cli/lib/profiles.d.ts.map +0 -1
  350. package/src/cli/account.ts +0 -320
  351. package/src/cli/lib/deployKeyWarning.ts +0 -43
  352. package/src/cli/lib/profileManagement.ts +0 -262
  353. package/src/cli/lib/profiles.ts +0 -398
@@ -86,13 +86,11 @@ export const oneoffContext = async (args) => {
86
86
  ctx,
87
87
  !!process.env.CONVEX_IGNORE_SUSPICIOUS_ENV_VARS
88
88
  );
89
- if (!args.skipAuth) {
90
- await initializeBigBrainAuth(ctx, {
91
- url: args.url,
92
- adminKey: args.adminKey,
93
- envFile: args.envFile
94
- });
95
- }
89
+ await initializeBigBrainAuth(ctx, {
90
+ url: args.url,
91
+ adminKey: args.adminKey,
92
+ envFile: args.envFile
93
+ });
96
94
  return ctx;
97
95
  };
98
96
  //# sourceMappingURL=context.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/bundler/context.ts"],
4
- "sourcesContent": ["import * as Sentry from \"@sentry/node\";\nimport { Ora } from \"ora\";\nimport { Filesystem, nodeFs } from \"./fs.js\";\nimport { initializeBigBrainAuth } from \"../cli/lib/deploymentSelection.js\";\nimport { detectSuspiciousEnvironmentVariables } from \"../cli/lib/envvars.js\";\nimport { logFailure, logVerbose } from \"./log.js\";\n// How the error should be handled when running `npx convex dev`.\nexport type ErrorType =\n // The error was likely caused by the state of the developer's local\n // file system (e.g. `tsc` fails due to a syntax error). The `convex dev`\n // command will then print out the error and wait for the file to change before\n // retrying.\n | \"invalid filesystem data\"\n // The error was caused by either the local state (ie schema.ts content)\n // or the state of the db (ie documents not matching the new schema).\n // The `convex dev` command will wait for either file OR table data change\n // to retry (if a table name is specified as the value in this Object).\n | {\n \"invalid filesystem or db data\": {\n tableName: string;\n componentPath?: string;\n } | null;\n }\n // The error was caused by either the local state (ie schema.ts content)\n // or the state of the deployment environment variables.\n // The `convex dev` command will wait for either file OR env var change\n // before retrying.\n | \"invalid filesystem or env vars\"\n // The error was some transient issue (e.g. a network\n // error). This will then cause a retry after an exponential backoff.\n | \"transient\"\n // This error was caught, handled, and now all that needs to happen\n // is for the proces to restart. No error is logged or reported.\n | \"already handled\"\n // This error is truly permanent. Exit `npx convex dev` because the\n // developer will need to take a manual commandline action.\n | \"fatal\";\n\nexport type BigBrainAuth = {\n header: string;\n} & (\n | {\n kind: \"projectKey\";\n projectKey: string;\n }\n | {\n kind: \"deploymentKey\";\n deploymentKey: string;\n }\n | {\n kind: \"previewDeployKey\";\n previewDeployKey: string;\n }\n | {\n kind: \"accessToken\";\n accessToken: string;\n profile?: { name: string; source: string } | null;\n }\n);\n\nexport interface Context {\n fs: Filesystem;\n deprecationMessagePrinted: boolean;\n // Reports to Sentry and either throws FatalError or exits the process.\n // Prints the `printedMessage` if provided\n crash(args: {\n exitCode: number;\n errorType: ErrorType;\n errForSentry?: any;\n printedMessage: string | null;\n }): Promise<never>;\n registerCleanup(fn: (exitCode: number, err?: any) => Promise<void>): string;\n removeCleanup(\n handle: string,\n ): (exitCode: number, err?: any) => Promise<void> | null;\n bigBrainAuth(): BigBrainAuth | null;\n /**\n * Prefer using `updateBigBrainAuthAfterLogin` in `deploymentSelection.ts` instead\n */\n _updateBigBrainAuth(auth: BigBrainAuth | null): void;\n}\n\nasync function flushAndExit(exitCode: number, err?: any) {\n if (err) {\n Sentry.captureException(err);\n }\n await Sentry.close();\n return process.exit(exitCode);\n}\n\nexport type OneoffCtx = Context & {\n // Generally `ctx.crash` is better to use since it handles printing a message\n // for the user, and then calls this.\n //\n // This function reports to Sentry + exits the process, but does not handle\n // printing a message for the user.\n flushAndExit: (exitCode: number, err?: any) => Promise<never>;\n};\n\nclass OneoffContextImpl {\n private _cleanupFns: Record<\n string,\n (exitCode: number, err?: any) => Promise<void>\n > = {};\n public fs: Filesystem = nodeFs;\n public deprecationMessagePrinted: boolean = false;\n public spinner: Ora | undefined = undefined;\n private _bigBrainAuth: BigBrainAuth | null = null;\n\n crash = async (args: {\n exitCode: number;\n errorType?: ErrorType;\n errForSentry?: any;\n printedMessage: string | null;\n }) => {\n if (args.printedMessage !== null) {\n logFailure(args.printedMessage);\n }\n return await this.flushAndExit(args.exitCode, args.errForSentry);\n };\n flushAndExit = async (exitCode: number, err?: any) => {\n logVerbose(\"Flushing and exiting, error:\", err);\n if (err) {\n logVerbose(err.stack);\n }\n const cleanupFns = this._cleanupFns;\n // Clear the cleanup functions so that there's no risk of running them twice\n // if this somehow gets triggered twice.\n this._cleanupFns = {};\n const fns = Object.values(cleanupFns);\n logVerbose(`Running ${fns.length} cleanup functions`);\n for (const fn of fns) {\n await fn(exitCode, err);\n }\n logVerbose(\"All cleanup functions ran\");\n return flushAndExit(exitCode, err);\n };\n registerCleanup(fn: (exitCode: number, err?: any) => Promise<void>) {\n const handle = Math.random().toString(36).slice(2);\n this._cleanupFns[handle] = fn;\n return handle;\n }\n removeCleanup(handle: string) {\n const value = this._cleanupFns[handle];\n delete this._cleanupFns[handle];\n return value ?? null;\n }\n bigBrainAuth(): BigBrainAuth | null {\n return this._bigBrainAuth;\n }\n _updateBigBrainAuth(auth: BigBrainAuth | null): void {\n logVerbose(`Updating big brain auth to ${auth?.kind ?? \"null\"}`);\n this._bigBrainAuth = auth;\n }\n}\n\n/**\n * Install a SIGINT handler that gracefully exits via ctx.flushAndExit.\n *\n * `bun run` and `npm run` can deliver a duplicate SIGINT to the child\n * process immediately while the first handler is still starting cleanup:\n * bun: https://github.com/oven-sh/bun/issues/14799\n * https://github.com/oven-sh/bun/issues/11400\n * npm: https://github.com/npm/cli/issues/5021\n * https://github.com/npm/cli/issues/8164\n * https://github.com/npm/cli/issues/7693\n * We ignore a second signal within 500ms of the first to avoid\n * double-cleanup, but treat a later Ctrl+C as a force-exit escape hatch.\n */\nexport function installSigintHandler(ctx: OneoffCtx) {\n const DUPLICATE_GRACE_MS = 500;\n let cleanupStartTime: number | null = null;\n process.on(\"SIGINT\", async () => {\n if (cleanupStartTime !== null) {\n if (Date.now() - cleanupStartTime < DUPLICATE_GRACE_MS) {\n logVerbose(\n \"Received SIGINT during cleanup, ignoring duplicate signal...\",\n );\n return;\n }\n logVerbose(\"Received SIGINT during cleanup, exiting immediately...\");\n process.exit(130);\n }\n cleanupStartTime = Date.now();\n logVerbose(\"Received SIGINT, cleaning up...\");\n await ctx.flushAndExit(130);\n });\n}\n\nexport const oneoffContext: (args: {\n url?: string | undefined;\n adminKey?: string | undefined;\n envFile?: string | undefined;\n skipAuth?: boolean;\n}) => Promise<OneoffCtx> = async (args) => {\n const ctx = new OneoffContextImpl();\n await detectSuspiciousEnvironmentVariables(\n ctx,\n !!process.env.CONVEX_IGNORE_SUSPICIOUS_ENV_VARS,\n );\n if (!args.skipAuth) {\n await initializeBigBrainAuth(ctx, {\n url: args.url,\n adminKey: args.adminKey,\n envFile: args.envFile,\n });\n }\n return ctx;\n};\n"],
5
- "mappings": ";;;;AAAA,YAAY,YAAY;AAExB,SAAqB,cAAc;AACnC,SAAS,8BAA8B;AACvC,SAAS,4CAA4C;AACrD,SAAS,YAAY,kBAAkB;AA6EvC,eAAe,aAAa,UAAkB,KAAW;AACvD,MAAI,KAAK;AACP,WAAO,iBAAiB,GAAG;AAAA,EAC7B;AACA,QAAM,OAAO,MAAM;AACnB,SAAO,QAAQ,KAAK,QAAQ;AAC9B;AAWA,MAAM,kBAAkB;AAAA,EAAxB;AACE,wBAAQ,eAGJ,CAAC;AACL,wBAAO,MAAiB;AACxB,wBAAO,6BAAqC;AAC5C,wBAAO;AACP,wBAAQ,iBAAqC;AAE7C,iCAAQ,OAAO,SAKT;AACJ,UAAI,KAAK,mBAAmB,MAAM;AAChC,mBAAW,KAAK,cAAc;AAAA,MAChC;AACA,aAAO,MAAM,KAAK,aAAa,KAAK,UAAU,KAAK,YAAY;AAAA,IACjE;AACA,wCAAe,OAAO,UAAkB,QAAc;AACpD,iBAAW,gCAAgC,GAAG;AAC9C,UAAI,KAAK;AACP,mBAAW,IAAI,KAAK;AAAA,MACtB;AACA,YAAM,aAAa,KAAK;AAGxB,WAAK,cAAc,CAAC;AACpB,YAAM,MAAM,OAAO,OAAO,UAAU;AACpC,iBAAW,WAAW,IAAI,MAAM,oBAAoB;AACpD,iBAAW,MAAM,KAAK;AACpB,cAAM,GAAG,UAAU,GAAG;AAAA,MACxB;AACA,iBAAW,2BAA2B;AACtC,aAAO,aAAa,UAAU,GAAG;AAAA,IACnC;AAAA;AAAA,EACA,gBAAgB,IAAoD;AAClE,UAAM,SAAS,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC;AACjD,SAAK,YAAY,MAAM,IAAI;AAC3B,WAAO;AAAA,EACT;AAAA,EACA,cAAc,QAAgB;AAC5B,UAAM,QAAQ,KAAK,YAAY,MAAM;AACrC,WAAO,KAAK,YAAY,MAAM;AAC9B,WAAO,SAAS;AAAA,EAClB;AAAA,EACA,eAAoC;AAClC,WAAO,KAAK;AAAA,EACd;AAAA,EACA,oBAAoB,MAAiC;AACnD,eAAW,8BAA8B,MAAM,QAAQ,MAAM,EAAE;AAC/D,SAAK,gBAAgB;AAAA,EACvB;AACF;AAeO,gBAAS,qBAAqB,KAAgB;AACnD,QAAM,qBAAqB;AAC3B,MAAI,mBAAkC;AACtC,UAAQ,GAAG,UAAU,YAAY;AAC/B,QAAI,qBAAqB,MAAM;AAC7B,UAAI,KAAK,IAAI,IAAI,mBAAmB,oBAAoB;AACtD;AAAA,UACE;AAAA,QACF;AACA;AAAA,MACF;AACA,iBAAW,wDAAwD;AACnE,cAAQ,KAAK,GAAG;AAAA,IAClB;AACA,uBAAmB,KAAK,IAAI;AAC5B,eAAW,iCAAiC;AAC5C,UAAM,IAAI,aAAa,GAAG;AAAA,EAC5B,CAAC;AACH;AAEO,aAAM,gBAKc,OAAO,SAAS;AACzC,QAAM,MAAM,IAAI,kBAAkB;AAClC,QAAM;AAAA,IACJ;AAAA,IACA,CAAC,CAAC,QAAQ,IAAI;AAAA,EAChB;AACA,MAAI,CAAC,KAAK,UAAU;AAClB,UAAM,uBAAuB,KAAK;AAAA,MAChC,KAAK,KAAK;AAAA,MACV,UAAU,KAAK;AAAA,MACf,SAAS,KAAK;AAAA,IAChB,CAAC;AAAA,EACH;AACA,SAAO;AACT;",
4
+ "sourcesContent": ["import * as Sentry from \"@sentry/node\";\nimport { Ora } from \"ora\";\nimport { Filesystem, nodeFs } from \"./fs.js\";\nimport { initializeBigBrainAuth } from \"../cli/lib/deploymentSelection.js\";\nimport { detectSuspiciousEnvironmentVariables } from \"../cli/lib/envvars.js\";\nimport { logFailure, logVerbose } from \"./log.js\";\n// How the error should be handled when running `npx convex dev`.\nexport type ErrorType =\n // The error was likely caused by the state of the developer's local\n // file system (e.g. `tsc` fails due to a syntax error). The `convex dev`\n // command will then print out the error and wait for the file to change before\n // retrying.\n | \"invalid filesystem data\"\n // The error was caused by either the local state (ie schema.ts content)\n // or the state of the db (ie documents not matching the new schema).\n // The `convex dev` command will wait for either file OR table data change\n // to retry (if a table name is specified as the value in this Object).\n | {\n \"invalid filesystem or db data\": {\n tableName: string;\n componentPath?: string;\n } | null;\n }\n // The error was caused by either the local state (ie schema.ts content)\n // or the state of the deployment environment variables.\n // The `convex dev` command will wait for either file OR env var change\n // before retrying.\n | \"invalid filesystem or env vars\"\n // The error was some transient issue (e.g. a network\n // error). This will then cause a retry after an exponential backoff.\n | \"transient\"\n // This error was caught, handled, and now all that needs to happen\n // is for the proces to restart. No error is logged or reported.\n | \"already handled\"\n // This error is truly permanent. Exit `npx convex dev` because the\n // developer will need to take a manual commandline action.\n | \"fatal\";\n\nexport type BigBrainAuth = {\n header: string;\n} & (\n | {\n kind: \"projectKey\";\n projectKey: string;\n }\n | {\n kind: \"deploymentKey\";\n deploymentKey: string;\n }\n | {\n kind: \"previewDeployKey\";\n previewDeployKey: string;\n }\n | {\n kind: \"accessToken\";\n accessToken: string;\n }\n);\n\nexport interface Context {\n fs: Filesystem;\n deprecationMessagePrinted: boolean;\n // Reports to Sentry and either throws FatalError or exits the process.\n // Prints the `printedMessage` if provided\n crash(args: {\n exitCode: number;\n errorType: ErrorType;\n errForSentry?: any;\n printedMessage: string | null;\n }): Promise<never>;\n registerCleanup(fn: (exitCode: number, err?: any) => Promise<void>): string;\n removeCleanup(\n handle: string,\n ): (exitCode: number, err?: any) => Promise<void> | null;\n bigBrainAuth(): BigBrainAuth | null;\n /**\n * Prefer using `updateBigBrainAuthAfterLogin` in `deploymentSelection.ts` instead\n */\n _updateBigBrainAuth(auth: BigBrainAuth | null): void;\n}\n\nasync function flushAndExit(exitCode: number, err?: any) {\n if (err) {\n Sentry.captureException(err);\n }\n await Sentry.close();\n return process.exit(exitCode);\n}\n\nexport type OneoffCtx = Context & {\n // Generally `ctx.crash` is better to use since it handles printing a message\n // for the user, and then calls this.\n //\n // This function reports to Sentry + exits the process, but does not handle\n // printing a message for the user.\n flushAndExit: (exitCode: number, err?: any) => Promise<never>;\n};\n\nclass OneoffContextImpl {\n private _cleanupFns: Record<\n string,\n (exitCode: number, err?: any) => Promise<void>\n > = {};\n public fs: Filesystem = nodeFs;\n public deprecationMessagePrinted: boolean = false;\n public spinner: Ora | undefined = undefined;\n private _bigBrainAuth: BigBrainAuth | null = null;\n\n crash = async (args: {\n exitCode: number;\n errorType?: ErrorType;\n errForSentry?: any;\n printedMessage: string | null;\n }) => {\n if (args.printedMessage !== null) {\n logFailure(args.printedMessage);\n }\n return await this.flushAndExit(args.exitCode, args.errForSentry);\n };\n flushAndExit = async (exitCode: number, err?: any) => {\n logVerbose(\"Flushing and exiting, error:\", err);\n if (err) {\n logVerbose(err.stack);\n }\n const cleanupFns = this._cleanupFns;\n // Clear the cleanup functions so that there's no risk of running them twice\n // if this somehow gets triggered twice.\n this._cleanupFns = {};\n const fns = Object.values(cleanupFns);\n logVerbose(`Running ${fns.length} cleanup functions`);\n for (const fn of fns) {\n await fn(exitCode, err);\n }\n logVerbose(\"All cleanup functions ran\");\n return flushAndExit(exitCode, err);\n };\n registerCleanup(fn: (exitCode: number, err?: any) => Promise<void>) {\n const handle = Math.random().toString(36).slice(2);\n this._cleanupFns[handle] = fn;\n return handle;\n }\n removeCleanup(handle: string) {\n const value = this._cleanupFns[handle];\n delete this._cleanupFns[handle];\n return value ?? null;\n }\n bigBrainAuth(): BigBrainAuth | null {\n return this._bigBrainAuth;\n }\n _updateBigBrainAuth(auth: BigBrainAuth | null): void {\n logVerbose(`Updating big brain auth to ${auth?.kind ?? \"null\"}`);\n this._bigBrainAuth = auth;\n }\n}\n\n/**\n * Install a SIGINT handler that gracefully exits via ctx.flushAndExit.\n *\n * `bun run` and `npm run` can deliver a duplicate SIGINT to the child\n * process immediately while the first handler is still starting cleanup:\n * bun: https://github.com/oven-sh/bun/issues/14799\n * https://github.com/oven-sh/bun/issues/11400\n * npm: https://github.com/npm/cli/issues/5021\n * https://github.com/npm/cli/issues/8164\n * https://github.com/npm/cli/issues/7693\n * We ignore a second signal within 500ms of the first to avoid\n * double-cleanup, but treat a later Ctrl+C as a force-exit escape hatch.\n */\nexport function installSigintHandler(ctx: OneoffCtx) {\n const DUPLICATE_GRACE_MS = 500;\n let cleanupStartTime: number | null = null;\n process.on(\"SIGINT\", async () => {\n if (cleanupStartTime !== null) {\n if (Date.now() - cleanupStartTime < DUPLICATE_GRACE_MS) {\n logVerbose(\n \"Received SIGINT during cleanup, ignoring duplicate signal...\",\n );\n return;\n }\n logVerbose(\"Received SIGINT during cleanup, exiting immediately...\");\n process.exit(130);\n }\n cleanupStartTime = Date.now();\n logVerbose(\"Received SIGINT, cleaning up...\");\n await ctx.flushAndExit(130);\n });\n}\n\nexport const oneoffContext: (args: {\n url?: string | undefined;\n adminKey?: string | undefined;\n envFile?: string | undefined;\n}) => Promise<OneoffCtx> = async (args) => {\n const ctx = new OneoffContextImpl();\n await detectSuspiciousEnvironmentVariables(\n ctx,\n !!process.env.CONVEX_IGNORE_SUSPICIOUS_ENV_VARS,\n );\n await initializeBigBrainAuth(ctx, {\n url: args.url,\n adminKey: args.adminKey,\n envFile: args.envFile,\n });\n return ctx;\n};\n"],
5
+ "mappings": ";;;;AAAA,YAAY,YAAY;AAExB,SAAqB,cAAc;AACnC,SAAS,8BAA8B;AACvC,SAAS,4CAA4C;AACrD,SAAS,YAAY,kBAAkB;AA4EvC,eAAe,aAAa,UAAkB,KAAW;AACvD,MAAI,KAAK;AACP,WAAO,iBAAiB,GAAG;AAAA,EAC7B;AACA,QAAM,OAAO,MAAM;AACnB,SAAO,QAAQ,KAAK,QAAQ;AAC9B;AAWA,MAAM,kBAAkB;AAAA,EAAxB;AACE,wBAAQ,eAGJ,CAAC;AACL,wBAAO,MAAiB;AACxB,wBAAO,6BAAqC;AAC5C,wBAAO;AACP,wBAAQ,iBAAqC;AAE7C,iCAAQ,OAAO,SAKT;AACJ,UAAI,KAAK,mBAAmB,MAAM;AAChC,mBAAW,KAAK,cAAc;AAAA,MAChC;AACA,aAAO,MAAM,KAAK,aAAa,KAAK,UAAU,KAAK,YAAY;AAAA,IACjE;AACA,wCAAe,OAAO,UAAkB,QAAc;AACpD,iBAAW,gCAAgC,GAAG;AAC9C,UAAI,KAAK;AACP,mBAAW,IAAI,KAAK;AAAA,MACtB;AACA,YAAM,aAAa,KAAK;AAGxB,WAAK,cAAc,CAAC;AACpB,YAAM,MAAM,OAAO,OAAO,UAAU;AACpC,iBAAW,WAAW,IAAI,MAAM,oBAAoB;AACpD,iBAAW,MAAM,KAAK;AACpB,cAAM,GAAG,UAAU,GAAG;AAAA,MACxB;AACA,iBAAW,2BAA2B;AACtC,aAAO,aAAa,UAAU,GAAG;AAAA,IACnC;AAAA;AAAA,EACA,gBAAgB,IAAoD;AAClE,UAAM,SAAS,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC;AACjD,SAAK,YAAY,MAAM,IAAI;AAC3B,WAAO;AAAA,EACT;AAAA,EACA,cAAc,QAAgB;AAC5B,UAAM,QAAQ,KAAK,YAAY,MAAM;AACrC,WAAO,KAAK,YAAY,MAAM;AAC9B,WAAO,SAAS;AAAA,EAClB;AAAA,EACA,eAAoC;AAClC,WAAO,KAAK;AAAA,EACd;AAAA,EACA,oBAAoB,MAAiC;AACnD,eAAW,8BAA8B,MAAM,QAAQ,MAAM,EAAE;AAC/D,SAAK,gBAAgB;AAAA,EACvB;AACF;AAeO,gBAAS,qBAAqB,KAAgB;AACnD,QAAM,qBAAqB;AAC3B,MAAI,mBAAkC;AACtC,UAAQ,GAAG,UAAU,YAAY;AAC/B,QAAI,qBAAqB,MAAM;AAC7B,UAAI,KAAK,IAAI,IAAI,mBAAmB,oBAAoB;AACtD;AAAA,UACE;AAAA,QACF;AACA;AAAA,MACF;AACA,iBAAW,wDAAwD;AACnE,cAAQ,KAAK,GAAG;AAAA,IAClB;AACA,uBAAmB,KAAK,IAAI;AAC5B,eAAW,iCAAiC;AAC5C,UAAM,IAAI,aAAa,GAAG;AAAA,EAC5B,CAAC;AACH;AAEO,aAAM,gBAIc,OAAO,SAAS;AACzC,QAAM,MAAM,IAAI,kBAAkB;AAClC,QAAM;AAAA,IACJ;AAAA,IACA,CAAC,CAAC,QAAQ,IAAI;AAAA,EAChB;AACA,QAAM,uBAAuB,KAAK;AAAA,IAChC,KAAK,KAAK;AAAA,IACV,UAAU,KAAK;AAAA,IACf,SAAS,KAAK;AAAA,EAChB,CAAC;AACD,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -80,9 +80,6 @@ export class NodeFs {
80
80
  stat(path2) {
81
81
  return stdFs.statSync(path2);
82
82
  }
83
- lstat(path2) {
84
- return stdFs.lstatSync(path2);
85
- }
86
83
  readUtf8File(path2) {
87
84
  return stdFs.readFileSync(path2, { encoding: "utf-8" });
88
85
  }
@@ -163,8 +160,6 @@ export class RecordingFs {
163
160
  __publicField(this, "observedDirectories", /* @__PURE__ */ new Map());
164
161
  // Absolute path -> observed stat (or null if observed nonexistent)
165
162
  __publicField(this, "observedFiles", /* @__PURE__ */ new Map());
166
- // lstat observes the link itself, while stat observes its target.
167
- __publicField(this, "observedLstats", /* @__PURE__ */ new Map());
168
163
  // Have we noticed that files have changed while recording?
169
164
  __publicField(this, "invalidated", false);
170
165
  __publicField(this, "traceEvents");
@@ -197,19 +192,6 @@ export class RecordingFs {
197
192
  this.observedDirectories.set(absDirPath, observedNames);
198
193
  return entries;
199
194
  }
200
- lstat(filePath) {
201
- const absPath = path.resolve(filePath);
202
- try {
203
- const st = nodeFs.lstat(filePath);
204
- this.registerNormalized(absPath, st, this.observedLstats);
205
- return st;
206
- } catch (err) {
207
- if (err.code === "ENOENT") {
208
- this.registerNormalized(absPath, null, this.observedLstats);
209
- }
210
- throw err;
211
- }
212
- }
213
195
  exists(path2) {
214
196
  try {
215
197
  const st = nodeFs.stat(path2);
@@ -308,8 +290,6 @@ export class RecordingFs {
308
290
  updateOnWrite(absPath) {
309
291
  const newSt = nodeFs.stat(absPath);
310
292
  this.observedFiles.set(absPath, newSt);
311
- if (this.observedLstats.has(absPath))
312
- this.observedLstats.set(absPath, nodeFs.lstat(absPath));
313
293
  const parentPath = path.resolve(path.dirname(absPath));
314
294
  const observedParent = this.observedDirectories.get(parentPath);
315
295
  if (observedParent !== void 0) {
@@ -318,8 +298,6 @@ export class RecordingFs {
318
298
  }
319
299
  updateOnDelete(absPath) {
320
300
  this.observedFiles.set(absPath, null);
321
- if (this.observedLstats.has(absPath))
322
- this.observedLstats.set(absPath, null);
323
301
  const parentPath = path.resolve(path.dirname(absPath));
324
302
  const observedParent = this.observedDirectories.get(parentPath);
325
303
  if (observedParent !== void 0) {
@@ -333,8 +311,8 @@ export class RecordingFs {
333
311
  invalidate() {
334
312
  this.invalidated = true;
335
313
  }
336
- registerNormalized(absPath, observed, observations = this.observedFiles) {
337
- const existing = observations.get(absPath);
314
+ registerNormalized(absPath, observed) {
315
+ const existing = this.observedFiles.get(absPath);
338
316
  if (existing !== void 0) {
339
317
  const stMatch = stMatches(observed, existing);
340
318
  if (!stMatch.matches) {
@@ -350,22 +328,17 @@ export class RecordingFs {
350
328
  this.invalidated = true;
351
329
  }
352
330
  }
353
- observations.set(absPath, observed);
331
+ this.observedFiles.set(absPath, observed);
354
332
  }
355
333
  finalize() {
356
334
  if (this.invalidated) {
357
335
  return "invalidated";
358
336
  }
359
- return new Observations(
360
- this.observedDirectories,
361
- this.observedFiles,
362
- this.observedLstats
363
- );
337
+ return new Observations(this.observedDirectories, this.observedFiles);
364
338
  }
365
339
  }
366
340
  export class Observations {
367
- constructor(directories, files, lstats = /* @__PURE__ */ new Map()) {
368
- this.lstats = lstats;
341
+ constructor(directories, files) {
369
342
  __publicField(this, "directories");
370
343
  __publicField(this, "files");
371
344
  this.directories = directories;
@@ -379,8 +352,7 @@ export class Observations {
379
352
  for (const path2 of this.files.keys()) {
380
353
  out.push(path2);
381
354
  }
382
- for (const path2 of this.lstats.keys()) out.push(path2);
383
- return [...new Set(out)];
355
+ return out;
384
356
  }
385
357
  overlaps({
386
358
  absPath
@@ -403,19 +375,6 @@ export class Observations {
403
375
  return { overlaps: true, reason };
404
376
  }
405
377
  }
406
- const observedLstat = this.lstats.get(absPath);
407
- if (observedLstat !== void 0) {
408
- let currentLstat;
409
- try {
410
- currentLstat = nodeFs.lstat(absPath);
411
- } catch (err) {
412
- if (err.code !== "ENOENT") throw err;
413
- currentLstat = null;
414
- }
415
- const match = stMatches(observedLstat, currentLstat);
416
- if (!match.matches)
417
- return { overlaps: true, reason: `modified (${match.reason})` };
418
- }
419
378
  const parentPath = path.resolve(path.dirname(absPath));
420
379
  const observedParent = this.directories.get(parentPath);
421
380
  if (observedParent !== void 0) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/bundler/fs.ts"],
4
- "sourcesContent": ["// Disable our restriction on `throw` because these aren't developer-facing\n// error messages.\n/* eslint-disable no-restricted-imports */\n/* eslint-disable no-restricted-syntax */\nimport { chalkStderr } from \"chalk\";\nimport stdFs, { Dirent, Mode, ReadStream, Stats } from \"fs\";\nimport * as fsPromises from \"fs/promises\";\nimport os from \"os\";\nimport path from \"path\";\nimport crypto from \"crypto\";\nimport { Readable } from \"stream\";\n\nexport type NormalizedPath = string;\n\nconst tmpDirOverrideVar = \"CONVEX_TMPDIR\";\nfunction tmpDirPath() {\n // Allow users to override the temporary directory path with an environment variable.\n // This override needs to (1) be project-specific, since the user may have projects\n // on different filesystems, but also (2) be device-specific and not checked in, since\n // it's dependent on where the user has checked out their project. So, we don't want\n // this state in the project-specific `convex.json`, which is shared across all\n // devices, or in the top-level `~/.convex` directory, which is shared across all\n // projects on the local machine.\n //\n // Therefore, just let advanced users configure this behavior with an environment\n // variable that they're responsible for managing themselves for now.\n const envTmpDir = process.env[tmpDirOverrideVar];\n return envTmpDir ?? os.tmpdir();\n}\nconst tmpDirRoot = tmpDirPath();\n\nlet warned = false;\nfunction warnCrossFilesystem(dstPath: string) {\n const dstDir = path.dirname(dstPath);\n if (!warned) {\n // It's hard for these to use `logMessage` without creating a circular dependency, so just log directly.\n // eslint-disable-next-line no-console\n console.warn(\n chalkStderr.yellow(\n `Temporary directory '${tmpDirRoot}' and project directory '${dstDir}' are on different filesystems.`,\n ),\n );\n // eslint-disable-next-line no-console\n console.warn(\n chalkStderr.gray(\n ` If you're running into errors with other tools watching the project directory, override the temporary directory location with the ${chalkStderr.bold(\n tmpDirOverrideVar,\n )} environment variable.`,\n ),\n );\n // eslint-disable-next-line no-console\n console.warn(\n chalkStderr.gray(\n ` Be sure to pick a temporary directory that's on the same filesystem as your project.`,\n ),\n );\n warned = true;\n }\n}\n\nexport interface Filesystem {\n listDir(dirPath: string): Dirent[];\n\n exists(path: string): boolean;\n stat(path: string): Stats;\n lstat(path: string): Stats;\n readUtf8File(path: string): string;\n // createReadStream returns a stream for which [Symbol.asyncIterator]\n // yields chunks of size highWaterMark (until the last one), or 64KB if\n // highWaterMark isn't specified.\n // https://nodejs.org/api/stream.html#readablesymbolasynciterator\n createReadStream(\n path: string,\n options: { highWaterMark?: number },\n ): ReadStream;\n access(path: string): void;\n\n writeUtf8File(path: string, contents: string, mode?: Mode): void;\n mkdir(\n dirPath: string,\n options?: { allowExisting?: boolean; recursive?: boolean },\n ): void;\n rmdir(path: string): void;\n unlink(path: string): void;\n swapTmpFile(fromPath: TempPath, toPath: string): void;\n\n registerPath(path: string, st: Stats | null): void;\n invalidate(): void;\n}\n\nexport type TempPath = string & { __tempPath: \"tempPath\" };\n\nexport interface TempDir {\n writeUtf8File(contents: string): TempPath;\n writeFileStream(\n path: TempPath,\n stream: Readable,\n onData?: (chunk: any) => void,\n ): Promise<void>;\n registerTempPath(st: Stats | null): TempPath;\n path: TempPath;\n}\n\nexport async function withTmpDir(\n callback: (tmpDir: TempDir) => Promise<void>,\n): Promise<void> {\n // Create temporary directories inside `tmpDirRoot` of the form `convex-<random>`.\n const tmpPath = stdFs.mkdtempSync(path.join(tmpDirRoot, \"convex\"));\n const tmpDir = {\n writeUtf8File(contents: string): TempPath {\n const filePath = path.join(tmpPath, crypto.randomUUID());\n nodeFs.writeUtf8File(filePath, contents);\n return filePath as TempPath;\n },\n registerTempPath(st: Stats | null): TempPath {\n const filePath = path.join(tmpPath, crypto.randomUUID());\n nodeFs.registerPath(filePath, st);\n return filePath as TempPath;\n },\n writeFileStream(\n path: TempPath,\n stream: Readable,\n onData?: (chunk: any) => void,\n ): Promise<void> {\n return nodeFs.writeFileStream(path, stream, onData);\n },\n path: tmpPath as TempPath,\n };\n try {\n await callback(tmpDir);\n } finally {\n stdFs.rmSync(tmpPath, { force: true, recursive: true });\n }\n}\n\n// Use `nodeFs` when you just want to read and write to the local filesystem\n// and don't care about collecting the paths touched. One-off commands\n// should use the singleton `nodeFs`.\nexport class NodeFs implements Filesystem {\n listDir(dirPath: string) {\n return stdFs.readdirSync(dirPath, { withFileTypes: true });\n }\n exists(path: string) {\n try {\n stdFs.statSync(path);\n return true;\n } catch (e: any) {\n if (e.code === \"ENOENT\") {\n return false;\n }\n throw e;\n }\n }\n stat(path: string) {\n return stdFs.statSync(path);\n }\n lstat(path: string) {\n return stdFs.lstatSync(path);\n }\n readUtf8File(path: string) {\n return stdFs.readFileSync(path, { encoding: \"utf-8\" });\n }\n createReadStream(\n path: string,\n options: { highWaterMark?: number },\n ): ReadStream {\n return stdFs.createReadStream(path, options);\n }\n // To avoid issues with filesystem events triggering for our own streamed file\n // writes, writeFileStream is intentionally not on the Filesystem interface\n // and not implemented by RecordingFs.\n async writeFileStream(\n path: string,\n stream: Readable,\n onData?: (chunk: any) => void,\n ): Promise<void> {\n // 'wx' means O_CREAT | O_EXCL | O_WRONLY\n // 0o644 means owner has readwrite access, everyone else has read access.\n const fileHandle = await fsPromises.open(path, \"wx\", 0o644);\n try {\n for await (const chunk of stream) {\n // For some reason, adding `stream.on(\"data\", onData)` causes issues with\n // the stream, but calling a callback here works.\n if (onData) {\n onData(chunk);\n }\n await fileHandle.write(chunk);\n }\n } finally {\n await fileHandle.close();\n }\n }\n access(path: string) {\n return stdFs.accessSync(path);\n }\n writeUtf8File(path: string, contents: string, mode?: Mode) {\n const fd = stdFs.openSync(path, \"w\", mode);\n try {\n stdFs.writeFileSync(fd, contents, { encoding: \"utf-8\" });\n try {\n stdFs.fsyncSync(fd);\n } catch (e: any) {\n // fsync(2) returns EINVAL on file descriptors that don't support\n // synchronization, e.g. FIFOs/pipes. Some integrations (such as\n // 1Password's Local Environment File) expose `.env.local` as a\n // FIFO so secrets can be streamed on demand; the write itself\n // succeeded, so treat the missing sync as best-effort.\n if (e?.code !== \"EINVAL\") {\n throw e;\n }\n }\n } finally {\n stdFs.closeSync(fd);\n }\n }\n mkdir(\n dirPath: string,\n options?: { allowExisting?: boolean; recursive?: boolean },\n ): void {\n try {\n stdFs.mkdirSync(dirPath, { recursive: options?.recursive });\n } catch (e: any) {\n if (options?.allowExisting && e.code === \"EEXIST\") {\n return;\n }\n throw e;\n }\n }\n rmdir(path: string) {\n stdFs.rmdirSync(path);\n }\n unlink(path: string) {\n return stdFs.unlinkSync(path);\n }\n swapTmpFile(fromPath: TempPath, toPath: string) {\n try {\n return stdFs.renameSync(fromPath, toPath);\n } catch (e: any) {\n // Fallback to copying the file if we're on different volumes.\n if (e.code === \"EXDEV\") {\n warnCrossFilesystem(toPath);\n stdFs.copyFileSync(fromPath, toPath);\n return;\n }\n throw e;\n }\n }\n registerPath(_path: string, _st: Stats | null) {\n // The node filesystem doesn't track reads, so we don't need to do anything here.\n }\n invalidate() {\n // We don't track invalidations for the node filesystem either.\n }\n}\nexport const nodeFs = new NodeFs();\n\n// Filesystem implementation that records all paths observed. This is useful\n// for implementing continuous watch commands that need to manage a filesystem\n// watcher and know when a command's inputs were invalidated.\nexport class RecordingFs implements Filesystem {\n // Absolute path -> Set of observed child names\n private observedDirectories: Map<string, Set<string>> = new Map();\n\n // Absolute path -> observed stat (or null if observed nonexistent)\n private observedFiles: Map<string, Stats | null> = new Map();\n\n // lstat observes the link itself, while stat observes its target.\n private observedLstats: Map<string, Stats | null> = new Map();\n\n // Have we noticed that files have changed while recording?\n private invalidated = false;\n\n private traceEvents: boolean;\n\n constructor(traceEvents: boolean) {\n this.traceEvents = traceEvents;\n }\n\n listDir(dirPath: string): Dirent[] {\n const absDirPath = path.resolve(dirPath);\n\n // Register observing the directory itself.\n const dirSt = nodeFs.stat(absDirPath);\n this.registerNormalized(absDirPath, dirSt);\n\n // List the directory and register observing all of its children.\n const entries = nodeFs.listDir(dirPath);\n for (const entry of entries) {\n const childPath = path.join(absDirPath, entry.name);\n const childSt = nodeFs.stat(childPath);\n this.registerPath(childPath, childSt);\n }\n\n // Register observing the directory's children.\n const observedNames = new Set(entries.map((e) => e.name));\n const existingNames = this.observedDirectories.get(absDirPath);\n if (existingNames) {\n if (!setsEqual(observedNames, existingNames)) {\n if (this.traceEvents) {\n // eslint-disable-next-line no-console\n console.log(\n \"Invalidating due to directory children mismatch\",\n observedNames,\n existingNames,\n );\n }\n this.invalidated = true;\n }\n }\n this.observedDirectories.set(absDirPath, observedNames);\n\n return entries;\n }\n\n lstat(filePath: string): Stats {\n const absPath = path.resolve(filePath);\n try {\n const st = nodeFs.lstat(filePath);\n this.registerNormalized(absPath, st, this.observedLstats);\n return st;\n } catch (err: any) {\n if (err.code === \"ENOENT\") {\n this.registerNormalized(absPath, null, this.observedLstats);\n }\n throw err;\n }\n }\n\n exists(path: string): boolean {\n try {\n const st = nodeFs.stat(path);\n this.registerPath(path, st);\n return true;\n } catch (err: any) {\n if (err.code === \"ENOENT\") {\n this.registerPath(path, null);\n return false;\n }\n throw err;\n }\n }\n stat(path: string): Stats {\n try {\n const st = nodeFs.stat(path);\n this.registerPath(path, st);\n return st;\n } catch (err: any) {\n if (err.code === \"ENOENT\") {\n this.registerPath(path, null);\n }\n throw err;\n }\n }\n readUtf8File(path: string): string {\n try {\n const st = nodeFs.stat(path);\n this.registerPath(path, st);\n return nodeFs.readUtf8File(path);\n } catch (err: any) {\n if (err.code === \"ENOENT\") {\n this.registerPath(path, null);\n }\n throw err;\n }\n }\n createReadStream(\n path: string,\n options: { highWaterMark?: number },\n ): ReadStream {\n try {\n const st = nodeFs.stat(path);\n this.registerPath(path, st);\n return nodeFs.createReadStream(path, options);\n } catch (err: any) {\n if (err.code === \"ENOENT\") {\n this.registerPath(path, null);\n }\n throw err;\n }\n }\n access(path: string) {\n try {\n const st = nodeFs.stat(path);\n this.registerPath(path, st);\n return nodeFs.access(path);\n } catch (err: any) {\n if (err.code === \"ENOENT\") {\n this.registerPath(path, null);\n }\n throw err;\n }\n }\n\n writeUtf8File(filePath: string, contents: string, mode?: Mode) {\n const absPath = path.resolve(filePath);\n\n nodeFs.writeUtf8File(filePath, contents, mode);\n\n this.updateOnWrite(absPath);\n }\n\n mkdir(\n dirPath: string,\n options?: { allowExisting?: boolean; recursive?: boolean },\n ): void {\n const absPath = path.resolve(dirPath);\n try {\n stdFs.mkdirSync(absPath, { recursive: options?.recursive });\n } catch (e: any) {\n if (options?.allowExisting && e.code === \"EEXIST\") {\n const st = nodeFs.stat(absPath);\n this.registerNormalized(absPath, st);\n return;\n }\n throw e;\n }\n this.updateOnWrite(absPath);\n }\n\n rmdir(dirPath: string) {\n const absPath = path.resolve(dirPath);\n stdFs.rmdirSync(absPath);\n this.updateOnDelete(absPath);\n }\n unlink(filePath: string) {\n const absPath = path.resolve(filePath);\n stdFs.unlinkSync(absPath);\n this.updateOnDelete(absPath);\n }\n swapTmpFile(fromPath: TempPath, toPath: string) {\n const absToPath = path.resolve(toPath);\n nodeFs.swapTmpFile(fromPath, absToPath);\n this.updateOnWrite(absToPath);\n }\n\n private updateOnWrite(absPath: string) {\n // Stat the file or dir after writing and make it our expected observation. If we read the file after\n // writing it and it doesn't match this stat (implying a subsequent write), we'll invalidate\n // the current reader.\n const newSt = nodeFs.stat(absPath);\n // Skip invalidation checking since we don't want to conflict if we previously read this file.\n this.observedFiles.set(absPath, newSt);\n if (this.observedLstats.has(absPath))\n this.observedLstats.set(absPath, nodeFs.lstat(absPath));\n\n // If we observed the parent, add our newly created file.\n const parentPath = path.resolve(path.dirname(absPath));\n const observedParent = this.observedDirectories.get(parentPath);\n if (observedParent !== undefined) {\n observedParent.add(path.basename(absPath));\n }\n }\n private updateOnDelete(absPath: string) {\n // Expect this file to be gone.\n this.observedFiles.set(absPath, null);\n if (this.observedLstats.has(absPath))\n this.observedLstats.set(absPath, null);\n\n // Unlink it from our parent if observed.\n const parentPath = path.resolve(path.dirname(absPath));\n const observedParent = this.observedDirectories.get(parentPath);\n if (observedParent !== undefined) {\n observedParent.delete(path.basename(absPath));\n }\n }\n\n registerPath(p: string, st: Stats | null) {\n const absPath = path.resolve(p);\n this.registerNormalized(absPath, st);\n }\n\n invalidate() {\n this.invalidated = true;\n }\n\n registerNormalized(\n absPath: string,\n observed: Stats | null,\n observations = this.observedFiles,\n ): void {\n const existing = observations.get(absPath);\n if (existing !== undefined) {\n const stMatch = stMatches(observed, existing);\n if (!stMatch.matches) {\n if (this.traceEvents) {\n // eslint-disable-next-line no-console\n console.log(\n \"Invalidating due to st mismatch\",\n absPath,\n observed,\n existing,\n stMatch.reason,\n );\n }\n this.invalidated = true;\n }\n }\n observations.set(absPath, observed);\n }\n\n finalize(): Observations | \"invalidated\" {\n if (this.invalidated) {\n return \"invalidated\";\n }\n return new Observations(\n this.observedDirectories,\n this.observedFiles,\n this.observedLstats,\n );\n }\n}\n\nexport type WatchEvent = {\n name: \"add\" | \"addDir\" | \"change\" | \"unlink\" | \"unlinkDir\";\n absPath: string;\n};\n\nexport class Observations {\n directories: Map<string, Set<string>>;\n files: Map<string, Stats | null>;\n\n constructor(\n directories: Map<string, Set<string>>,\n files: Map<string, Stats | null>,\n private lstats: Map<string, Stats | null> = new Map(),\n ) {\n this.directories = directories;\n this.files = files;\n }\n\n paths(): string[] {\n const out = [];\n for (const path of this.directories.keys()) {\n out.push(path);\n }\n for (const path of this.files.keys()) {\n out.push(path);\n }\n for (const path of this.lstats.keys()) out.push(path);\n return [...new Set(out)];\n }\n\n overlaps({\n absPath,\n }: WatchEvent): { overlaps: false } | { overlaps: true; reason: string } {\n let currentSt: null | Stats;\n try {\n currentSt = nodeFs.stat(absPath);\n } catch (e: any) {\n if (e.code === \"ENOENT\") {\n currentSt = null;\n } else {\n throw e;\n }\n }\n\n // First, check to see if we observed `absPath` as a file.\n const observedSt = this.files.get(absPath);\n if (observedSt !== undefined) {\n const stMatch = stMatches(observedSt, currentSt);\n if (!stMatch.matches) {\n const reason = `modified (${stMatch.reason})`;\n return { overlaps: true, reason };\n }\n }\n\n const observedLstat = this.lstats.get(absPath);\n if (observedLstat !== undefined) {\n let currentLstat: Stats | null;\n try {\n currentLstat = nodeFs.lstat(absPath);\n } catch (err: any) {\n if (err.code !== \"ENOENT\") throw err;\n currentLstat = null;\n }\n const match = stMatches(observedLstat, currentLstat);\n if (!match.matches)\n return { overlaps: true, reason: `modified (${match.reason})` };\n }\n\n // Second, check if we listed the directory this file is in.\n const parentPath = path.resolve(path.dirname(absPath));\n const observedParent = this.directories.get(parentPath);\n if (observedParent !== undefined) {\n const filename = path.basename(absPath);\n\n // If the file is gone now, but we observed it in its directory, then\n // it was deleted.\n if (currentSt === null && observedParent.has(filename)) {\n return { overlaps: true, reason: \"deleted\" };\n }\n\n // If the file exists now, but we didn't see it when listing its directory,\n // then it was added.\n if (currentSt !== null && !observedParent.has(filename)) {\n return { overlaps: true, reason: \"added\" };\n }\n }\n\n return { overlaps: false };\n }\n}\n\nfunction setsEqual<T>(a: Set<T>, b: Set<T>): boolean {\n if (a.size !== b.size) {\n return false;\n }\n for (const elem of a.keys()) {\n if (!b.has(elem)) {\n return false;\n }\n }\n return true;\n}\n\nexport function stMatches(\n a: Stats | null,\n b: Stats | null,\n): { matches: true } | { matches: false; reason: string } {\n if (a === null && b === null) {\n return { matches: true };\n }\n if (a !== null && b !== null) {\n if (a.dev !== b.dev) {\n return { matches: false, reason: \"device boundary\" };\n }\n if (a.isFile() || b.isFile()) {\n if (!a.isFile() || !b.isFile()) {\n return { matches: false, reason: \"file type\" };\n }\n if (a.ino !== b.ino) {\n return {\n matches: false,\n reason: `file inode (${a.ino} vs. ${b.ino})`,\n };\n }\n if (a.size !== b.size) {\n return {\n matches: false,\n reason: `file size (${a.size} vs. ${b.size})`,\n };\n }\n if (a.mtimeMs !== b.mtimeMs) {\n return {\n matches: false,\n reason: `file mtime (${a.mtimeMs} vs. ${b.mtimeMs})`,\n };\n }\n return { matches: true };\n }\n if (a.isDirectory() || b.isDirectory()) {\n if (!b.isDirectory() || !b.isDirectory()) {\n return { matches: false, reason: \"dir file type\" };\n }\n if (a.ino !== b.ino) {\n return {\n matches: false,\n reason: `dir inode (${a.ino} vs. ${b.ino})`,\n };\n }\n return { matches: true };\n }\n // If we have something other than a file or directory, just compare inodes.\n if (a.ino !== b.ino) {\n return {\n matches: false,\n reason: `special inode (${a.ino} vs. ${b.ino})`,\n };\n }\n return { matches: true };\n }\n return { matches: false, reason: \"deleted mismatch\" };\n}\n\n// Sort consistent with unix directory listings.\nexport function consistentPathSort(a: Dirent, b: Dirent) {\n for (let i = 0; i < Math.min(a.name.length, b.name.length); i++) {\n if (a.name.charCodeAt(i) !== b.name.charCodeAt(i)) {\n return a.name.charCodeAt(i) - b.name.charCodeAt(i);\n }\n }\n return a.name.length - b.name.length;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Disable our restriction on `throw` because these aren't developer-facing\n// error messages.\n/* eslint-disable no-restricted-imports */\n/* eslint-disable no-restricted-syntax */\nimport { chalkStderr } from \"chalk\";\nimport stdFs, { Dirent, Mode, ReadStream, Stats } from \"fs\";\nimport * as fsPromises from \"fs/promises\";\nimport os from \"os\";\nimport path from \"path\";\nimport crypto from \"crypto\";\nimport { Readable } from \"stream\";\n\nexport type NormalizedPath = string;\n\nconst tmpDirOverrideVar = \"CONVEX_TMPDIR\";\nfunction tmpDirPath() {\n // Allow users to override the temporary directory path with an environment variable.\n // This override needs to (1) be project-specific, since the user may have projects\n // on different filesystems, but also (2) be device-specific and not checked in, since\n // it's dependent on where the user has checked out their project. So, we don't want\n // this state in the project-specific `convex.json`, which is shared across all\n // devices, or in the top-level `~/.convex` directory, which is shared across all\n // projects on the local machine.\n //\n // Therefore, just let advanced users configure this behavior with an environment\n // variable that they're responsible for managing themselves for now.\n const envTmpDir = process.env[tmpDirOverrideVar];\n return envTmpDir ?? os.tmpdir();\n}\nconst tmpDirRoot = tmpDirPath();\n\nlet warned = false;\nfunction warnCrossFilesystem(dstPath: string) {\n const dstDir = path.dirname(dstPath);\n if (!warned) {\n // It's hard for these to use `logMessage` without creating a circular dependency, so just log directly.\n // eslint-disable-next-line no-console\n console.warn(\n chalkStderr.yellow(\n `Temporary directory '${tmpDirRoot}' and project directory '${dstDir}' are on different filesystems.`,\n ),\n );\n // eslint-disable-next-line no-console\n console.warn(\n chalkStderr.gray(\n ` If you're running into errors with other tools watching the project directory, override the temporary directory location with the ${chalkStderr.bold(\n tmpDirOverrideVar,\n )} environment variable.`,\n ),\n );\n // eslint-disable-next-line no-console\n console.warn(\n chalkStderr.gray(\n ` Be sure to pick a temporary directory that's on the same filesystem as your project.`,\n ),\n );\n warned = true;\n }\n}\n\nexport interface Filesystem {\n listDir(dirPath: string): Dirent[];\n\n exists(path: string): boolean;\n stat(path: string): Stats;\n readUtf8File(path: string): string;\n // createReadStream returns a stream for which [Symbol.asyncIterator]\n // yields chunks of size highWaterMark (until the last one), or 64KB if\n // highWaterMark isn't specified.\n // https://nodejs.org/api/stream.html#readablesymbolasynciterator\n createReadStream(\n path: string,\n options: { highWaterMark?: number },\n ): ReadStream;\n access(path: string): void;\n\n writeUtf8File(path: string, contents: string, mode?: Mode): void;\n mkdir(\n dirPath: string,\n options?: { allowExisting?: boolean; recursive?: boolean },\n ): void;\n rmdir(path: string): void;\n unlink(path: string): void;\n swapTmpFile(fromPath: TempPath, toPath: string): void;\n\n registerPath(path: string, st: Stats | null): void;\n invalidate(): void;\n}\n\nexport type TempPath = string & { __tempPath: \"tempPath\" };\n\nexport interface TempDir {\n writeUtf8File(contents: string): TempPath;\n writeFileStream(\n path: TempPath,\n stream: Readable,\n onData?: (chunk: any) => void,\n ): Promise<void>;\n registerTempPath(st: Stats | null): TempPath;\n path: TempPath;\n}\n\nexport async function withTmpDir(\n callback: (tmpDir: TempDir) => Promise<void>,\n): Promise<void> {\n // Create temporary directories inside `tmpDirRoot` of the form `convex-<random>`.\n const tmpPath = stdFs.mkdtempSync(path.join(tmpDirRoot, \"convex\"));\n const tmpDir = {\n writeUtf8File(contents: string): TempPath {\n const filePath = path.join(tmpPath, crypto.randomUUID());\n nodeFs.writeUtf8File(filePath, contents);\n return filePath as TempPath;\n },\n registerTempPath(st: Stats | null): TempPath {\n const filePath = path.join(tmpPath, crypto.randomUUID());\n nodeFs.registerPath(filePath, st);\n return filePath as TempPath;\n },\n writeFileStream(\n path: TempPath,\n stream: Readable,\n onData?: (chunk: any) => void,\n ): Promise<void> {\n return nodeFs.writeFileStream(path, stream, onData);\n },\n path: tmpPath as TempPath,\n };\n try {\n await callback(tmpDir);\n } finally {\n stdFs.rmSync(tmpPath, { force: true, recursive: true });\n }\n}\n\n// Use `nodeFs` when you just want to read and write to the local filesystem\n// and don't care about collecting the paths touched. One-off commands\n// should use the singleton `nodeFs`.\nexport class NodeFs implements Filesystem {\n listDir(dirPath: string) {\n return stdFs.readdirSync(dirPath, { withFileTypes: true });\n }\n exists(path: string) {\n try {\n stdFs.statSync(path);\n return true;\n } catch (e: any) {\n if (e.code === \"ENOENT\") {\n return false;\n }\n throw e;\n }\n }\n stat(path: string) {\n return stdFs.statSync(path);\n }\n readUtf8File(path: string) {\n return stdFs.readFileSync(path, { encoding: \"utf-8\" });\n }\n createReadStream(\n path: string,\n options: { highWaterMark?: number },\n ): ReadStream {\n return stdFs.createReadStream(path, options);\n }\n // To avoid issues with filesystem events triggering for our own streamed file\n // writes, writeFileStream is intentionally not on the Filesystem interface\n // and not implemented by RecordingFs.\n async writeFileStream(\n path: string,\n stream: Readable,\n onData?: (chunk: any) => void,\n ): Promise<void> {\n // 'wx' means O_CREAT | O_EXCL | O_WRONLY\n // 0o644 means owner has readwrite access, everyone else has read access.\n const fileHandle = await fsPromises.open(path, \"wx\", 0o644);\n try {\n for await (const chunk of stream) {\n // For some reason, adding `stream.on(\"data\", onData)` causes issues with\n // the stream, but calling a callback here works.\n if (onData) {\n onData(chunk);\n }\n await fileHandle.write(chunk);\n }\n } finally {\n await fileHandle.close();\n }\n }\n access(path: string) {\n return stdFs.accessSync(path);\n }\n writeUtf8File(path: string, contents: string, mode?: Mode) {\n const fd = stdFs.openSync(path, \"w\", mode);\n try {\n stdFs.writeFileSync(fd, contents, { encoding: \"utf-8\" });\n try {\n stdFs.fsyncSync(fd);\n } catch (e: any) {\n // fsync(2) returns EINVAL on file descriptors that don't support\n // synchronization, e.g. FIFOs/pipes. Some integrations (such as\n // 1Password's Local Environment File) expose `.env.local` as a\n // FIFO so secrets can be streamed on demand; the write itself\n // succeeded, so treat the missing sync as best-effort.\n if (e?.code !== \"EINVAL\") {\n throw e;\n }\n }\n } finally {\n stdFs.closeSync(fd);\n }\n }\n mkdir(\n dirPath: string,\n options?: { allowExisting?: boolean; recursive?: boolean },\n ): void {\n try {\n stdFs.mkdirSync(dirPath, { recursive: options?.recursive });\n } catch (e: any) {\n if (options?.allowExisting && e.code === \"EEXIST\") {\n return;\n }\n throw e;\n }\n }\n rmdir(path: string) {\n stdFs.rmdirSync(path);\n }\n unlink(path: string) {\n return stdFs.unlinkSync(path);\n }\n swapTmpFile(fromPath: TempPath, toPath: string) {\n try {\n return stdFs.renameSync(fromPath, toPath);\n } catch (e: any) {\n // Fallback to copying the file if we're on different volumes.\n if (e.code === \"EXDEV\") {\n warnCrossFilesystem(toPath);\n stdFs.copyFileSync(fromPath, toPath);\n return;\n }\n throw e;\n }\n }\n registerPath(_path: string, _st: Stats | null) {\n // The node filesystem doesn't track reads, so we don't need to do anything here.\n }\n invalidate() {\n // We don't track invalidations for the node filesystem either.\n }\n}\nexport const nodeFs = new NodeFs();\n\n// Filesystem implementation that records all paths observed. This is useful\n// for implementing continuous watch commands that need to manage a filesystem\n// watcher and know when a command's inputs were invalidated.\nexport class RecordingFs implements Filesystem {\n // Absolute path -> Set of observed child names\n private observedDirectories: Map<string, Set<string>> = new Map();\n\n // Absolute path -> observed stat (or null if observed nonexistent)\n private observedFiles: Map<string, Stats | null> = new Map();\n\n // Have we noticed that files have changed while recording?\n private invalidated = false;\n\n private traceEvents: boolean;\n\n constructor(traceEvents: boolean) {\n this.traceEvents = traceEvents;\n }\n\n listDir(dirPath: string): Dirent[] {\n const absDirPath = path.resolve(dirPath);\n\n // Register observing the directory itself.\n const dirSt = nodeFs.stat(absDirPath);\n this.registerNormalized(absDirPath, dirSt);\n\n // List the directory and register observing all of its children.\n const entries = nodeFs.listDir(dirPath);\n for (const entry of entries) {\n const childPath = path.join(absDirPath, entry.name);\n const childSt = nodeFs.stat(childPath);\n this.registerPath(childPath, childSt);\n }\n\n // Register observing the directory's children.\n const observedNames = new Set(entries.map((e) => e.name));\n const existingNames = this.observedDirectories.get(absDirPath);\n if (existingNames) {\n if (!setsEqual(observedNames, existingNames)) {\n if (this.traceEvents) {\n // eslint-disable-next-line no-console\n console.log(\n \"Invalidating due to directory children mismatch\",\n observedNames,\n existingNames,\n );\n }\n this.invalidated = true;\n }\n }\n this.observedDirectories.set(absDirPath, observedNames);\n\n return entries;\n }\n\n exists(path: string): boolean {\n try {\n const st = nodeFs.stat(path);\n this.registerPath(path, st);\n return true;\n } catch (err: any) {\n if (err.code === \"ENOENT\") {\n this.registerPath(path, null);\n return false;\n }\n throw err;\n }\n }\n stat(path: string): Stats {\n try {\n const st = nodeFs.stat(path);\n this.registerPath(path, st);\n return st;\n } catch (err: any) {\n if (err.code === \"ENOENT\") {\n this.registerPath(path, null);\n }\n throw err;\n }\n }\n readUtf8File(path: string): string {\n try {\n const st = nodeFs.stat(path);\n this.registerPath(path, st);\n return nodeFs.readUtf8File(path);\n } catch (err: any) {\n if (err.code === \"ENOENT\") {\n this.registerPath(path, null);\n }\n throw err;\n }\n }\n createReadStream(\n path: string,\n options: { highWaterMark?: number },\n ): ReadStream {\n try {\n const st = nodeFs.stat(path);\n this.registerPath(path, st);\n return nodeFs.createReadStream(path, options);\n } catch (err: any) {\n if (err.code === \"ENOENT\") {\n this.registerPath(path, null);\n }\n throw err;\n }\n }\n access(path: string) {\n try {\n const st = nodeFs.stat(path);\n this.registerPath(path, st);\n return nodeFs.access(path);\n } catch (err: any) {\n if (err.code === \"ENOENT\") {\n this.registerPath(path, null);\n }\n throw err;\n }\n }\n\n writeUtf8File(filePath: string, contents: string, mode?: Mode) {\n const absPath = path.resolve(filePath);\n\n nodeFs.writeUtf8File(filePath, contents, mode);\n\n this.updateOnWrite(absPath);\n }\n\n mkdir(\n dirPath: string,\n options?: { allowExisting?: boolean; recursive?: boolean },\n ): void {\n const absPath = path.resolve(dirPath);\n try {\n stdFs.mkdirSync(absPath, { recursive: options?.recursive });\n } catch (e: any) {\n if (options?.allowExisting && e.code === \"EEXIST\") {\n const st = nodeFs.stat(absPath);\n this.registerNormalized(absPath, st);\n return;\n }\n throw e;\n }\n this.updateOnWrite(absPath);\n }\n\n rmdir(dirPath: string) {\n const absPath = path.resolve(dirPath);\n stdFs.rmdirSync(absPath);\n this.updateOnDelete(absPath);\n }\n unlink(filePath: string) {\n const absPath = path.resolve(filePath);\n stdFs.unlinkSync(absPath);\n this.updateOnDelete(absPath);\n }\n swapTmpFile(fromPath: TempPath, toPath: string) {\n const absToPath = path.resolve(toPath);\n nodeFs.swapTmpFile(fromPath, absToPath);\n this.updateOnWrite(absToPath);\n }\n\n private updateOnWrite(absPath: string) {\n // Stat the file or dir after writing and make it our expected observation. If we read the file after\n // writing it and it doesn't match this stat (implying a subsequent write), we'll invalidate\n // the current reader.\n const newSt = nodeFs.stat(absPath);\n // Skip invalidation checking since we don't want to conflict if we previously read this file.\n this.observedFiles.set(absPath, newSt);\n\n // If we observed the parent, add our newly created file.\n const parentPath = path.resolve(path.dirname(absPath));\n const observedParent = this.observedDirectories.get(parentPath);\n if (observedParent !== undefined) {\n observedParent.add(path.basename(absPath));\n }\n }\n private updateOnDelete(absPath: string) {\n // Expect this file to be gone.\n this.observedFiles.set(absPath, null);\n\n // Unlink it from our parent if observed.\n const parentPath = path.resolve(path.dirname(absPath));\n const observedParent = this.observedDirectories.get(parentPath);\n if (observedParent !== undefined) {\n observedParent.delete(path.basename(absPath));\n }\n }\n\n registerPath(p: string, st: Stats | null) {\n const absPath = path.resolve(p);\n this.registerNormalized(absPath, st);\n }\n\n invalidate() {\n this.invalidated = true;\n }\n\n registerNormalized(absPath: string, observed: Stats | null): void {\n const existing = this.observedFiles.get(absPath);\n if (existing !== undefined) {\n const stMatch = stMatches(observed, existing);\n if (!stMatch.matches) {\n if (this.traceEvents) {\n // eslint-disable-next-line no-console\n console.log(\n \"Invalidating due to st mismatch\",\n absPath,\n observed,\n existing,\n stMatch.reason,\n );\n }\n this.invalidated = true;\n }\n }\n this.observedFiles.set(absPath, observed);\n }\n\n finalize(): Observations | \"invalidated\" {\n if (this.invalidated) {\n return \"invalidated\";\n }\n return new Observations(this.observedDirectories, this.observedFiles);\n }\n}\n\nexport type WatchEvent = {\n name: \"add\" | \"addDir\" | \"change\" | \"unlink\" | \"unlinkDir\";\n absPath: string;\n};\n\nexport class Observations {\n directories: Map<string, Set<string>>;\n files: Map<string, Stats | null>;\n\n constructor(\n directories: Map<string, Set<string>>,\n files: Map<string, Stats | null>,\n ) {\n this.directories = directories;\n this.files = files;\n }\n\n paths(): string[] {\n const out = [];\n for (const path of this.directories.keys()) {\n out.push(path);\n }\n for (const path of this.files.keys()) {\n out.push(path);\n }\n return out;\n }\n\n overlaps({\n absPath,\n }: WatchEvent): { overlaps: false } | { overlaps: true; reason: string } {\n let currentSt: null | Stats;\n try {\n currentSt = nodeFs.stat(absPath);\n } catch (e: any) {\n if (e.code === \"ENOENT\") {\n currentSt = null;\n } else {\n throw e;\n }\n }\n\n // First, check to see if we observed `absPath` as a file.\n const observedSt = this.files.get(absPath);\n if (observedSt !== undefined) {\n const stMatch = stMatches(observedSt, currentSt);\n if (!stMatch.matches) {\n const reason = `modified (${stMatch.reason})`;\n return { overlaps: true, reason };\n }\n }\n\n // Second, check if we listed the directory this file is in.\n const parentPath = path.resolve(path.dirname(absPath));\n const observedParent = this.directories.get(parentPath);\n if (observedParent !== undefined) {\n const filename = path.basename(absPath);\n\n // If the file is gone now, but we observed it in its directory, then\n // it was deleted.\n if (currentSt === null && observedParent.has(filename)) {\n return { overlaps: true, reason: \"deleted\" };\n }\n\n // If the file exists now, but we didn't see it when listing its directory,\n // then it was added.\n if (currentSt !== null && !observedParent.has(filename)) {\n return { overlaps: true, reason: \"added\" };\n }\n }\n\n return { overlaps: false };\n }\n}\n\nfunction setsEqual<T>(a: Set<T>, b: Set<T>): boolean {\n if (a.size !== b.size) {\n return false;\n }\n for (const elem of a.keys()) {\n if (!b.has(elem)) {\n return false;\n }\n }\n return true;\n}\n\nexport function stMatches(\n a: Stats | null,\n b: Stats | null,\n): { matches: true } | { matches: false; reason: string } {\n if (a === null && b === null) {\n return { matches: true };\n }\n if (a !== null && b !== null) {\n if (a.dev !== b.dev) {\n return { matches: false, reason: \"device boundary\" };\n }\n if (a.isFile() || b.isFile()) {\n if (!a.isFile() || !b.isFile()) {\n return { matches: false, reason: \"file type\" };\n }\n if (a.ino !== b.ino) {\n return {\n matches: false,\n reason: `file inode (${a.ino} vs. ${b.ino})`,\n };\n }\n if (a.size !== b.size) {\n return {\n matches: false,\n reason: `file size (${a.size} vs. ${b.size})`,\n };\n }\n if (a.mtimeMs !== b.mtimeMs) {\n return {\n matches: false,\n reason: `file mtime (${a.mtimeMs} vs. ${b.mtimeMs})`,\n };\n }\n return { matches: true };\n }\n if (a.isDirectory() || b.isDirectory()) {\n if (!b.isDirectory() || !b.isDirectory()) {\n return { matches: false, reason: \"dir file type\" };\n }\n if (a.ino !== b.ino) {\n return {\n matches: false,\n reason: `dir inode (${a.ino} vs. ${b.ino})`,\n };\n }\n return { matches: true };\n }\n // If we have something other than a file or directory, just compare inodes.\n if (a.ino !== b.ino) {\n return {\n matches: false,\n reason: `special inode (${a.ino} vs. ${b.ino})`,\n };\n }\n return { matches: true };\n }\n return { matches: false, reason: \"deleted mismatch\" };\n}\n\n// Sort consistent with unix directory listings.\nexport function consistentPathSort(a: Dirent, b: Dirent) {\n for (let i = 0; i < Math.min(a.name.length, b.name.length); i++) {\n if (a.name.charCodeAt(i) !== b.name.charCodeAt(i)) {\n return a.name.charCodeAt(i) - b.name.charCodeAt(i);\n }\n }\n return a.name.length - b.name.length;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["path"]
7
7
  }
@@ -25,8 +25,19 @@ async function resolveProjectPaths() {
25
25
  const aiInstall = new Command("install").summary("Install or refresh Convex AI files").description(
26
26
  "Installs the following (or refreshes them if already present):\n - convex/_generated/ai/guidelines.md\n - AGENTS.md (Convex section only)\n - CLAUDE.md (Convex section only)\n - Agent skills (installed to each coding agent's native path, configured via convex.json)"
27
27
  ).allowExcessArguments(false).action(async () => {
28
- const { projectDir, convexDir, aiFilesConfig } = await resolveProjectPaths();
29
- await installAiFiles({ projectDir, convexDir, aiFilesConfig });
28
+ const { ctx, projectDir, convexDir, aiFilesConfig } = await resolveProjectPaths();
29
+ const result = await installAiFiles({
30
+ projectDir,
31
+ convexDir,
32
+ aiFilesConfig
33
+ });
34
+ if (result.kind === "error") {
35
+ return await ctx.crash({
36
+ exitCode: 1,
37
+ errorType: "fatal",
38
+ printedMessage: result.message
39
+ });
40
+ }
30
41
  logMessage(`${chalkStderr.green("\u2714")} Convex AI files installed.`);
31
42
  });
32
43
  const aiEnable = new Command("enable").summary("Enable Convex AI files").description(
@@ -43,8 +54,19 @@ const aiEnable = new Command("enable").summary("Enable Convex AI files").descrip
43
54
  const aiUpdate = new Command("update").summary("Update Convex AI files to the latest version").description(
44
55
  "Updates the following to their latest versions:\n - convex/_generated/ai/guidelines.md\n - AGENTS.md (Convex section only)\n - CLAUDE.md (Convex section only)\n - Agent skills (installed to each coding agent's native path, configured via convex.json)"
45
56
  ).allowExcessArguments(false).action(async () => {
46
- const { projectDir, convexDir, aiFilesConfig } = await resolveProjectPaths();
47
- await installAiFiles({ projectDir, convexDir, aiFilesConfig });
57
+ const { ctx, projectDir, convexDir, aiFilesConfig } = await resolveProjectPaths();
58
+ const result = await installAiFiles({
59
+ projectDir,
60
+ convexDir,
61
+ aiFilesConfig
62
+ });
63
+ if (result.kind === "error") {
64
+ return await ctx.crash({
65
+ exitCode: 1,
66
+ errorType: "fatal",
67
+ printedMessage: result.message
68
+ });
69
+ }
48
70
  logMessage(`${chalkStderr.green("\u2714")} Convex AI files updated.`);
49
71
  });
50
72
  const aiDisable = new Command("disable").summary("Disable Convex AI files without removing them").description(
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/aiFiles.ts"],
4
- "sourcesContent": ["import path from \"path\";\nimport { Command } from \"@commander-js/extra-typings\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../bundler/log.js\";\nimport { oneoffContext } from \"../bundler/context.js\";\nimport { readProjectConfig } from \"./lib/config.js\";\nimport { functionsDir } from \"./lib/utils/utils.js\";\nimport {\n installAiFiles,\n enableAiFiles,\n disableAiFiles,\n removeAiFiles,\n} from \"./lib/aiFiles/index.js\";\nimport { statusAiFiles } from \"./lib/aiFiles/status.js\";\nimport { writeAiFilesConfig } from \"./lib/config.js\";\n\nasync function resolveProjectPaths() {\n const ctx = await oneoffContext({});\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n const convexDir = path.resolve(functionsDir(configPath, projectConfig));\n const projectDir = path.resolve(path.dirname(configPath));\n const aiFilesConfig = projectConfig.aiFiles;\n return { ctx, projectDir, convexDir, aiFilesConfig, projectConfig };\n}\n\nconst aiInstall = new Command(\"install\")\n .summary(\"Install or refresh Convex AI files\")\n .description(\n \"Installs the following (or refreshes them if already present):\\n\" +\n \" - convex/_generated/ai/guidelines.md\\n\" +\n \" - AGENTS.md (Convex section only)\\n\" +\n \" - CLAUDE.md (Convex section only)\\n\" +\n \" - Agent skills (installed to each coding agent's native path, configured via convex.json)\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { projectDir, convexDir, aiFilesConfig } =\n await resolveProjectPaths();\n await installAiFiles({ projectDir, convexDir, aiFilesConfig });\n\n logMessage(`${chalkStderr.green(\"\u2714\")} Convex AI files installed.`);\n });\n\nconst aiEnable = new Command(\"enable\")\n .summary(\"Enable Convex AI files\")\n .description(\n \"Re-enables Convex AI files by writing `aiFiles.enabled: true` to\\n\" +\n \"`convex.json`, then installs or refreshes the managed AI files.\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { projectDir, convexDir, aiFilesConfig } =\n await resolveProjectPaths();\n\n const newAiFilesConfig = await enableAiFiles({\n projectDir,\n convexDir,\n aiFilesConfig,\n });\n\n await writeAiFilesConfig({ projectDir, aiFiles: newAiFilesConfig });\n });\n\nconst aiUpdate = new Command(\"update\")\n .summary(\"Update Convex AI files to the latest version\")\n .description(\n \"Updates the following to their latest versions:\\n\" +\n \" - convex/_generated/ai/guidelines.md\\n\" +\n \" - AGENTS.md (Convex section only)\\n\" +\n \" - CLAUDE.md (Convex section only)\\n\" +\n \" - Agent skills (installed to each coding agent's native path, configured via convex.json)\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { projectDir, convexDir, aiFilesConfig } =\n await resolveProjectPaths();\n await installAiFiles({ projectDir, convexDir, aiFilesConfig });\n\n logMessage(`${chalkStderr.green(\"\u2714\")} Convex AI files updated.`);\n });\n\nconst aiDisable = new Command(\"disable\")\n .summary(\"Disable Convex AI files without removing them\")\n .description(\n \"Writes `aiFiles.enabled: false` to `convex.json` so `npx convex dev`\\n\" +\n \"stops prompting to install AI files and suppresses staleness messages.\\n\\n\" +\n \"Files already installed are left untouched - use `npx convex ai-files remove`\\n\" +\n \"if you also want to delete them.\\n\\n\" +\n \"Run `npx convex ai-files enable` to re-enable at any time.\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { projectDir, aiFilesConfig } = await resolveProjectPaths();\n\n const newAiFilesConfig = disableAiFiles(aiFilesConfig);\n\n await writeAiFilesConfig({\n projectDir,\n aiFiles: newAiFilesConfig,\n });\n\n logMessage(\n `${chalkStderr.green(`\u2714`)} Convex AI files disabled. Run ${chalkStderr.bold(`npx convex ai-files enable`)} to re-enable.`,\n );\n });\n\nconst aiStatus = new Command(\"status\")\n .summary(\"Show the current status of Convex AI files\")\n .description(\n \"Prints whether Convex AI files are enabled, and for each component:\\n\" +\n \" - convex/_generated/ai/guidelines.md\\n\" +\n \" - AGENTS.md (Convex section)\\n\" +\n \" - CLAUDE.md (if installed by Convex)\\n\" +\n \" - Agent skills\\n\\n\" +\n \"Fetches the latest hashes from version.convex.dev to report whether\\n\" +\n \"each file is up to date. If the network is unavailable the staleness\\n\" +\n \"check is skipped silently.\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { projectDir, convexDir, aiFilesConfig } =\n await resolveProjectPaths();\n\n await statusAiFiles({ projectDir, convexDir, aiFilesConfig });\n });\n\nconst aiRemove = new Command(\"remove\")\n .summary(\"Remove all Convex AI files from the project\")\n .description(\n \"Removes the following:\\n\" +\n \" - convex/_generated/ai/ directory (guidelines.md, ai-files.state.json)\\n\" +\n \" - Convex sections from AGENTS.md and CLAUDE.md\\n\" +\n \" - Agent skills installed by `npx convex ai-files install`\\n\\n\" +\n \"If removing the managed section leaves AGENTS.md or CLAUDE.md empty, the\\n\" +\n \"empty file is deleted. Otherwise the rest of the file is kept.\\n\\n\" +\n \"Skills installed from other sources are not affected.\\n\\n\" +\n \"Note: after `remove`, `npx convex dev` will suggest reinstalling AI files.\\n\" +\n \"Use `npx convex ai-files disable` to opt out entirely without deleting files.\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { ctx, projectDir, convexDir } = await resolveProjectPaths();\n const result = await removeAiFiles({ projectDir, convexDir });\n if (result.kind === \"error\") {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: result.message,\n });\n }\n });\n\nexport const aiFiles = new Command(\"ai-files\")\n .summary(\"Manage Convex AI files\")\n .description(\n \"Convex AI files help AI coding assistants (Cursor, Claude Code, etc.) understand\\n\" +\n \"Convex patterns and APIs. They are set up during your first `npx convex dev`\\n\" +\n \"and can be managed at any time with the commands below.\",\n )\n .addCommand(aiStatus)\n .addCommand(aiInstall)\n .addCommand(aiEnable)\n .addCommand(aiUpdate)\n .addCommand(aiDisable)\n .addCommand(aiRemove)\n .addHelpCommand(false);\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import path from \"path\";\nimport { Command } from \"@commander-js/extra-typings\";\nimport { chalkStderr } from \"chalk\";\nimport { logMessage } from \"../bundler/log.js\";\nimport { oneoffContext } from \"../bundler/context.js\";\nimport { readProjectConfig } from \"./lib/config.js\";\nimport { functionsDir } from \"./lib/utils/utils.js\";\nimport {\n installAiFiles,\n enableAiFiles,\n disableAiFiles,\n removeAiFiles,\n} from \"./lib/aiFiles/index.js\";\nimport { statusAiFiles } from \"./lib/aiFiles/status.js\";\nimport { writeAiFilesConfig } from \"./lib/config.js\";\n\nasync function resolveProjectPaths() {\n const ctx = await oneoffContext({});\n const { configPath, projectConfig } = await readProjectConfig(ctx);\n const convexDir = path.resolve(functionsDir(configPath, projectConfig));\n const projectDir = path.resolve(path.dirname(configPath));\n const aiFilesConfig = projectConfig.aiFiles;\n return { ctx, projectDir, convexDir, aiFilesConfig, projectConfig };\n}\n\nconst aiInstall = new Command(\"install\")\n .summary(\"Install or refresh Convex AI files\")\n .description(\n \"Installs the following (or refreshes them if already present):\\n\" +\n \" - convex/_generated/ai/guidelines.md\\n\" +\n \" - AGENTS.md (Convex section only)\\n\" +\n \" - CLAUDE.md (Convex section only)\\n\" +\n \" - Agent skills (installed to each coding agent's native path, configured via convex.json)\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { ctx, projectDir, convexDir, aiFilesConfig } =\n await resolveProjectPaths();\n\n const result = await installAiFiles({\n projectDir,\n convexDir,\n aiFilesConfig,\n });\n\n if (result.kind === \"error\") {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: result.message,\n });\n }\n\n logMessage(`${chalkStderr.green(\"\u2714\")} Convex AI files installed.`);\n });\n\nconst aiEnable = new Command(\"enable\")\n .summary(\"Enable Convex AI files\")\n .description(\n \"Re-enables Convex AI files by writing `aiFiles.enabled: true` to\\n\" +\n \"`convex.json`, then installs or refreshes the managed AI files.\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { projectDir, convexDir, aiFilesConfig } =\n await resolveProjectPaths();\n\n const newAiFilesConfig = await enableAiFiles({\n projectDir,\n convexDir,\n aiFilesConfig,\n });\n\n await writeAiFilesConfig({ projectDir, aiFiles: newAiFilesConfig });\n });\n\nconst aiUpdate = new Command(\"update\")\n .summary(\"Update Convex AI files to the latest version\")\n .description(\n \"Updates the following to their latest versions:\\n\" +\n \" - convex/_generated/ai/guidelines.md\\n\" +\n \" - AGENTS.md (Convex section only)\\n\" +\n \" - CLAUDE.md (Convex section only)\\n\" +\n \" - Agent skills (installed to each coding agent's native path, configured via convex.json)\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { ctx, projectDir, convexDir, aiFilesConfig } =\n await resolveProjectPaths();\n\n const result = await installAiFiles({\n projectDir,\n convexDir,\n aiFilesConfig,\n });\n\n if (result.kind === \"error\") {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: result.message,\n });\n }\n\n logMessage(`${chalkStderr.green(\"\u2714\")} Convex AI files updated.`);\n });\n\nconst aiDisable = new Command(\"disable\")\n .summary(\"Disable Convex AI files without removing them\")\n .description(\n \"Writes `aiFiles.enabled: false` to `convex.json` so `npx convex dev`\\n\" +\n \"stops prompting to install AI files and suppresses staleness messages.\\n\\n\" +\n \"Files already installed are left untouched - use `npx convex ai-files remove`\\n\" +\n \"if you also want to delete them.\\n\\n\" +\n \"Run `npx convex ai-files enable` to re-enable at any time.\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { projectDir, aiFilesConfig } = await resolveProjectPaths();\n\n const newAiFilesConfig = disableAiFiles(aiFilesConfig);\n\n await writeAiFilesConfig({\n projectDir,\n aiFiles: newAiFilesConfig,\n });\n\n logMessage(\n `${chalkStderr.green(`\u2714`)} Convex AI files disabled. Run ${chalkStderr.bold(`npx convex ai-files enable`)} to re-enable.`,\n );\n });\n\nconst aiStatus = new Command(\"status\")\n .summary(\"Show the current status of Convex AI files\")\n .description(\n \"Prints whether Convex AI files are enabled, and for each component:\\n\" +\n \" - convex/_generated/ai/guidelines.md\\n\" +\n \" - AGENTS.md (Convex section)\\n\" +\n \" - CLAUDE.md (if installed by Convex)\\n\" +\n \" - Agent skills\\n\\n\" +\n \"Fetches the latest hashes from version.convex.dev to report whether\\n\" +\n \"each file is up to date. If the network is unavailable the staleness\\n\" +\n \"check is skipped silently.\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { projectDir, convexDir, aiFilesConfig } =\n await resolveProjectPaths();\n\n await statusAiFiles({ projectDir, convexDir, aiFilesConfig });\n });\n\nconst aiRemove = new Command(\"remove\")\n .summary(\"Remove all Convex AI files from the project\")\n .description(\n \"Removes the following:\\n\" +\n \" - convex/_generated/ai/ directory (guidelines.md, ai-files.state.json)\\n\" +\n \" - Convex sections from AGENTS.md and CLAUDE.md\\n\" +\n \" - Agent skills installed by `npx convex ai-files install`\\n\\n\" +\n \"If removing the managed section leaves AGENTS.md or CLAUDE.md empty, the\\n\" +\n \"empty file is deleted. Otherwise the rest of the file is kept.\\n\\n\" +\n \"Skills installed from other sources are not affected.\\n\\n\" +\n \"Note: after `remove`, `npx convex dev` will suggest reinstalling AI files.\\n\" +\n \"Use `npx convex ai-files disable` to opt out entirely without deleting files.\",\n )\n .allowExcessArguments(false)\n .action(async () => {\n const { ctx, projectDir, convexDir } = await resolveProjectPaths();\n const result = await removeAiFiles({ projectDir, convexDir });\n if (result.kind === \"error\") {\n return await ctx.crash({\n exitCode: 1,\n errorType: \"fatal\",\n printedMessage: result.message,\n });\n }\n });\n\nexport const aiFiles = new Command(\"ai-files\")\n .summary(\"Manage Convex AI files\")\n .description(\n \"Convex AI files help AI coding assistants (Cursor, Claude Code, etc.) understand\\n\" +\n \"Convex patterns and APIs. They are set up during your first `npx convex dev`\\n\" +\n \"and can be managed at any time with the commands below.\",\n )\n .addCommand(aiStatus)\n .addCommand(aiInstall)\n .addCommand(aiEnable)\n .addCommand(aiUpdate)\n .addCommand(aiDisable)\n .addCommand(aiRemove)\n .addHelpCommand(false);\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  import { chalkStderr } from "chalk";
3
- import { handleNoAccessToConfiguredProject } from "./account.js";
4
3
  import {
5
4
  logFailure,
6
5
  logFinishedStep,
@@ -215,23 +214,11 @@ async function handleDeploymentWithinProject(ctx, {
215
214
  );
216
215
  return result;
217
216
  }
218
- let accessResult = await checkAccessToSelectedProject(
217
+ const accessResult = await checkAccessToSelectedProject(
219
218
  ctx,
220
219
  deploymentSelection.targetProject
221
220
  );
222
- while (accessResult.kind === "noAccess") {
223
- const next = cmdOptions.team !== void 0 && cmdOptions.project !== void 0 ? "chooseProject" : await handleNoAccessToConfiguredProject(
224
- ctx,
225
- deploymentSelection.targetProject,
226
- cmdOptions.envFile
227
- );
228
- if (next === "retry") {
229
- accessResult = await checkAccessToSelectedProject(
230
- ctx,
231
- deploymentSelection.targetProject
232
- );
233
- continue;
234
- }
221
+ if (accessResult.kind === "noAccess") {
235
222
  logMessage("You don't have access to the selected project.");
236
223
  const result = await handleChooseProject(
237
224
  ctx,