@agentuity/cli 0.1.9 → 0.1.11

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 (323) hide show
  1. package/README.md +2 -2
  2. package/bin/cli.ts +8 -0
  3. package/dist/cache/index.d.ts +2 -0
  4. package/dist/cache/index.d.ts.map +1 -0
  5. package/dist/cache/index.js +2 -0
  6. package/dist/cache/index.js.map +1 -0
  7. package/dist/cache/resource-region.d.ts +46 -0
  8. package/dist/cache/resource-region.d.ts.map +1 -0
  9. package/dist/cache/resource-region.js +115 -0
  10. package/dist/cache/resource-region.js.map +1 -0
  11. package/dist/cli.d.ts.map +1 -1
  12. package/dist/cli.js +44 -32
  13. package/dist/cli.js.map +1 -1
  14. package/dist/cmd/ai/capabilities/show.d.ts.map +1 -1
  15. package/dist/cmd/ai/capabilities/show.js +12 -15
  16. package/dist/cmd/ai/capabilities/show.js.map +1 -1
  17. package/dist/cmd/ai/prompt/llm.js +5 -5
  18. package/dist/cmd/ai/prompt/llm.js.map +1 -1
  19. package/dist/cmd/auth/logout.d.ts.map +1 -1
  20. package/dist/cmd/auth/logout.js +5 -2
  21. package/dist/cmd/auth/logout.js.map +1 -1
  22. package/dist/cmd/build/ast.d.ts.map +1 -1
  23. package/dist/cmd/build/ast.js +87 -1
  24. package/dist/cmd/build/ast.js.map +1 -1
  25. package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -1
  26. package/dist/cmd/build/vite/vite-asset-server-config.js +8 -3
  27. package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -1
  28. package/dist/cmd/build/vite/vite-asset-server.d.ts.map +1 -1
  29. package/dist/cmd/build/vite/vite-asset-server.js +5 -3
  30. package/dist/cmd/build/vite/vite-asset-server.js.map +1 -1
  31. package/dist/cmd/cloud/db/delete.d.ts.map +1 -1
  32. package/dist/cmd/cloud/db/delete.js +69 -11
  33. package/dist/cmd/cloud/db/delete.js.map +1 -1
  34. package/dist/cmd/cloud/db/get.d.ts.map +1 -1
  35. package/dist/cmd/cloud/db/get.js +23 -7
  36. package/dist/cmd/cloud/db/get.js.map +1 -1
  37. package/dist/cmd/cloud/db/list.d.ts.map +1 -1
  38. package/dist/cmd/cloud/db/list.js +15 -7
  39. package/dist/cmd/cloud/db/list.js.map +1 -1
  40. package/dist/cmd/cloud/db/logs.d.ts.map +1 -1
  41. package/dist/cmd/cloud/db/logs.js +24 -4
  42. package/dist/cmd/cloud/db/logs.js.map +1 -1
  43. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  44. package/dist/cmd/cloud/deploy.js +38 -0
  45. package/dist/cmd/cloud/deploy.js.map +1 -1
  46. package/dist/cmd/cloud/env/delete.d.ts.map +1 -1
  47. package/dist/cmd/cloud/env/delete.js +30 -13
  48. package/dist/cmd/cloud/env/delete.js.map +1 -1
  49. package/dist/cmd/cloud/env/get.d.ts.map +1 -1
  50. package/dist/cmd/cloud/env/get.js +27 -30
  51. package/dist/cmd/cloud/env/get.js.map +1 -1
  52. package/dist/cmd/cloud/env/import.d.ts.map +1 -1
  53. package/dist/cmd/cloud/env/import.js +41 -48
  54. package/dist/cmd/cloud/env/import.js.map +1 -1
  55. package/dist/cmd/cloud/env/index.d.ts.map +1 -1
  56. package/dist/cmd/cloud/env/index.js +6 -2
  57. package/dist/cmd/cloud/env/index.js.map +1 -1
  58. package/dist/cmd/cloud/env/list.d.ts.map +1 -1
  59. package/dist/cmd/cloud/env/list.js +51 -28
  60. package/dist/cmd/cloud/env/list.js.map +1 -1
  61. package/dist/cmd/cloud/env/pull.d.ts.map +1 -1
  62. package/dist/cmd/cloud/env/pull.js +3 -3
  63. package/dist/cmd/cloud/env/pull.js.map +1 -1
  64. package/dist/cmd/cloud/env/push.d.ts.map +1 -1
  65. package/dist/cmd/cloud/env/push.js +31 -11
  66. package/dist/cmd/cloud/env/push.js.map +1 -1
  67. package/dist/cmd/cloud/env/set.d.ts.map +1 -1
  68. package/dist/cmd/cloud/env/set.js +41 -26
  69. package/dist/cmd/cloud/env/set.js.map +1 -1
  70. package/dist/cmd/cloud/index.d.ts.map +1 -1
  71. package/dist/cmd/cloud/index.js +0 -2
  72. package/dist/cmd/cloud/index.js.map +1 -1
  73. package/dist/cmd/cloud/region-lookup.d.ts +18 -0
  74. package/dist/cmd/cloud/region-lookup.d.ts.map +1 -0
  75. package/dist/cmd/cloud/region-lookup.js +64 -0
  76. package/dist/cmd/cloud/region-lookup.js.map +1 -0
  77. package/dist/cmd/cloud/sandbox/cp.d.ts.map +1 -1
  78. package/dist/cmd/cloud/sandbox/cp.js +5 -3
  79. package/dist/cmd/cloud/sandbox/cp.js.map +1 -1
  80. package/dist/cmd/cloud/sandbox/create.d.ts.map +1 -1
  81. package/dist/cmd/cloud/sandbox/create.js +43 -6
  82. package/dist/cmd/cloud/sandbox/create.js.map +1 -1
  83. package/dist/cmd/cloud/sandbox/delete.d.ts.map +1 -1
  84. package/dist/cmd/cloud/sandbox/delete.js +5 -3
  85. package/dist/cmd/cloud/sandbox/delete.js.map +1 -1
  86. package/dist/cmd/cloud/sandbox/download.d.ts.map +1 -1
  87. package/dist/cmd/cloud/sandbox/download.js +4 -3
  88. package/dist/cmd/cloud/sandbox/download.js.map +1 -1
  89. package/dist/cmd/cloud/sandbox/env.d.ts.map +1 -1
  90. package/dist/cmd/cloud/sandbox/env.js +4 -3
  91. package/dist/cmd/cloud/sandbox/env.js.map +1 -1
  92. package/dist/cmd/cloud/sandbox/exec.d.ts.map +1 -1
  93. package/dist/cmd/cloud/sandbox/exec.js +4 -3
  94. package/dist/cmd/cloud/sandbox/exec.js.map +1 -1
  95. package/dist/cmd/cloud/sandbox/execution/get.js +4 -4
  96. package/dist/cmd/cloud/sandbox/execution/get.js.map +1 -1
  97. package/dist/cmd/cloud/sandbox/execution/index.js +1 -1
  98. package/dist/cmd/cloud/sandbox/execution/index.js.map +1 -1
  99. package/dist/cmd/cloud/sandbox/execution/list.d.ts.map +1 -1
  100. package/dist/cmd/cloud/sandbox/execution/list.js +4 -3
  101. package/dist/cmd/cloud/sandbox/execution/list.js.map +1 -1
  102. package/dist/cmd/cloud/sandbox/get.d.ts.map +1 -1
  103. package/dist/cmd/cloud/sandbox/get.js +9 -4
  104. package/dist/cmd/cloud/sandbox/get.js.map +1 -1
  105. package/dist/cmd/cloud/sandbox/index.js +1 -1
  106. package/dist/cmd/cloud/sandbox/index.js.map +1 -1
  107. package/dist/cmd/cloud/sandbox/list.js +4 -4
  108. package/dist/cmd/cloud/sandbox/list.js.map +1 -1
  109. package/dist/cmd/cloud/sandbox/ls.d.ts.map +1 -1
  110. package/dist/cmd/cloud/sandbox/ls.js +4 -3
  111. package/dist/cmd/cloud/sandbox/ls.js.map +1 -1
  112. package/dist/cmd/cloud/sandbox/mkdir.d.ts.map +1 -1
  113. package/dist/cmd/cloud/sandbox/mkdir.js +4 -3
  114. package/dist/cmd/cloud/sandbox/mkdir.js.map +1 -1
  115. package/dist/cmd/cloud/sandbox/rm.d.ts.map +1 -1
  116. package/dist/cmd/cloud/sandbox/rm.js +4 -3
  117. package/dist/cmd/cloud/sandbox/rm.js.map +1 -1
  118. package/dist/cmd/cloud/sandbox/rmdir.d.ts.map +1 -1
  119. package/dist/cmd/cloud/sandbox/rmdir.js +4 -3
  120. package/dist/cmd/cloud/sandbox/rmdir.js.map +1 -1
  121. package/dist/cmd/cloud/sandbox/run.d.ts.map +1 -1
  122. package/dist/cmd/cloud/sandbox/run.js +44 -6
  123. package/dist/cmd/cloud/sandbox/run.js.map +1 -1
  124. package/dist/cmd/cloud/sandbox/runtime/index.js +1 -1
  125. package/dist/cmd/cloud/sandbox/runtime/index.js.map +1 -1
  126. package/dist/cmd/cloud/sandbox/runtime/list.js +4 -4
  127. package/dist/cmd/cloud/sandbox/runtime/list.js.map +1 -1
  128. package/dist/cmd/cloud/sandbox/snapshot/build.d.ts +5 -0
  129. package/dist/cmd/cloud/sandbox/snapshot/build.d.ts.map +1 -0
  130. package/dist/cmd/cloud/sandbox/snapshot/build.js +574 -0
  131. package/dist/cmd/cloud/sandbox/snapshot/build.js.map +1 -0
  132. package/dist/cmd/cloud/sandbox/snapshot/create.d.ts.map +1 -1
  133. package/dist/cmd/cloud/sandbox/snapshot/create.js +5 -3
  134. package/dist/cmd/cloud/sandbox/snapshot/create.js.map +1 -1
  135. package/dist/cmd/cloud/sandbox/snapshot/delete.js +4 -4
  136. package/dist/cmd/cloud/sandbox/snapshot/delete.js.map +1 -1
  137. package/dist/cmd/cloud/sandbox/snapshot/generate.d.ts +3 -0
  138. package/dist/cmd/cloud/sandbox/snapshot/generate.d.ts.map +1 -0
  139. package/dist/cmd/cloud/sandbox/snapshot/generate.js +127 -0
  140. package/dist/cmd/cloud/sandbox/snapshot/generate.js.map +1 -0
  141. package/dist/cmd/cloud/sandbox/snapshot/get.d.ts.map +1 -1
  142. package/dist/cmd/cloud/sandbox/snapshot/get.js +20 -4
  143. package/dist/cmd/cloud/sandbox/snapshot/get.js.map +1 -1
  144. package/dist/cmd/cloud/sandbox/snapshot/index.d.ts.map +1 -1
  145. package/dist/cmd/cloud/sandbox/snapshot/index.js +20 -2
  146. package/dist/cmd/cloud/sandbox/snapshot/index.js.map +1 -1
  147. package/dist/cmd/cloud/sandbox/snapshot/list.js +4 -4
  148. package/dist/cmd/cloud/sandbox/snapshot/list.js.map +1 -1
  149. package/dist/cmd/cloud/sandbox/snapshot/tag.d.ts.map +1 -1
  150. package/dist/cmd/cloud/sandbox/snapshot/tag.js +4 -4
  151. package/dist/cmd/cloud/sandbox/snapshot/tag.js.map +1 -1
  152. package/dist/cmd/cloud/sandbox/upload.d.ts.map +1 -1
  153. package/dist/cmd/cloud/sandbox/upload.js +4 -3
  154. package/dist/cmd/cloud/sandbox/upload.js.map +1 -1
  155. package/dist/cmd/cloud/sandbox/util.d.ts +13 -0
  156. package/dist/cmd/cloud/sandbox/util.d.ts.map +1 -1
  157. package/dist/cmd/cloud/sandbox/util.js +40 -1
  158. package/dist/cmd/cloud/sandbox/util.js.map +1 -1
  159. package/dist/cmd/cloud/scp/download.d.ts.map +1 -1
  160. package/dist/cmd/cloud/scp/download.js +6 -2
  161. package/dist/cmd/cloud/scp/download.js.map +1 -1
  162. package/dist/cmd/cloud/scp/upload.d.ts.map +1 -1
  163. package/dist/cmd/cloud/scp/upload.js +6 -2
  164. package/dist/cmd/cloud/scp/upload.js.map +1 -1
  165. package/dist/cmd/cloud/session/get.js +4 -4
  166. package/dist/cmd/cloud/session/get.js.map +1 -1
  167. package/dist/cmd/cloud/session/list.js +4 -4
  168. package/dist/cmd/cloud/session/list.js.map +1 -1
  169. package/dist/cmd/cloud/ssh.d.ts.map +1 -1
  170. package/dist/cmd/cloud/ssh.js +7 -2
  171. package/dist/cmd/cloud/ssh.js.map +1 -1
  172. package/dist/cmd/cloud/storage/delete.d.ts.map +1 -1
  173. package/dist/cmd/cloud/storage/delete.js +46 -10
  174. package/dist/cmd/cloud/storage/delete.js.map +1 -1
  175. package/dist/cmd/cloud/storage/download.d.ts.map +1 -1
  176. package/dist/cmd/cloud/storage/download.js +19 -6
  177. package/dist/cmd/cloud/storage/download.js.map +1 -1
  178. package/dist/cmd/cloud/storage/get.d.ts.map +1 -1
  179. package/dist/cmd/cloud/storage/get.js +19 -6
  180. package/dist/cmd/cloud/storage/get.js.map +1 -1
  181. package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
  182. package/dist/cmd/cloud/storage/list.js +17 -7
  183. package/dist/cmd/cloud/storage/list.js.map +1 -1
  184. package/dist/cmd/cloud/storage/upload.d.ts.map +1 -1
  185. package/dist/cmd/cloud/storage/upload.js +19 -6
  186. package/dist/cmd/cloud/storage/upload.js.map +1 -1
  187. package/dist/cmd/cloud/thread/delete.js +4 -4
  188. package/dist/cmd/cloud/thread/delete.js.map +1 -1
  189. package/dist/cmd/cloud/thread/get.js +4 -4
  190. package/dist/cmd/cloud/thread/get.js.map +1 -1
  191. package/dist/cmd/cloud/thread/list.js +4 -4
  192. package/dist/cmd/cloud/thread/list.js.map +1 -1
  193. package/dist/cmd/project/auth/init.d.ts.map +1 -1
  194. package/dist/cmd/project/auth/init.js +6 -3
  195. package/dist/cmd/project/auth/init.js.map +1 -1
  196. package/dist/cmd/project/auth/shared.d.ts +6 -2
  197. package/dist/cmd/project/auth/shared.d.ts.map +1 -1
  198. package/dist/cmd/project/auth/shared.js +41 -13
  199. package/dist/cmd/project/auth/shared.js.map +1 -1
  200. package/dist/config.d.ts +37 -0
  201. package/dist/config.d.ts.map +1 -1
  202. package/dist/config.js +55 -8
  203. package/dist/config.js.map +1 -1
  204. package/dist/env-util.d.ts +25 -2
  205. package/dist/env-util.d.ts.map +1 -1
  206. package/dist/env-util.js +44 -4
  207. package/dist/env-util.js.map +1 -1
  208. package/dist/utils/apt-validator.d.ts +20 -0
  209. package/dist/utils/apt-validator.d.ts.map +1 -0
  210. package/dist/utils/apt-validator.js +157 -0
  211. package/dist/utils/apt-validator.js.map +1 -0
  212. package/package.json +6 -6
  213. package/src/cache/index.ts +11 -0
  214. package/src/cache/resource-region.ts +183 -0
  215. package/src/cli.ts +47 -38
  216. package/src/cmd/ai/capabilities/show.ts +12 -15
  217. package/src/cmd/ai/prompt/llm.ts +5 -5
  218. package/src/cmd/auth/logout.ts +5 -2
  219. package/src/cmd/build/ast.ts +160 -1
  220. package/src/cmd/build/vite/vite-asset-server-config.ts +7 -3
  221. package/src/cmd/build/vite/vite-asset-server.ts +6 -3
  222. package/src/cmd/cloud/db/delete.ts +83 -11
  223. package/src/cmd/cloud/db/get.ts +29 -7
  224. package/src/cmd/cloud/db/list.ts +16 -7
  225. package/src/cmd/cloud/db/logs.ts +33 -4
  226. package/src/cmd/cloud/deploy.ts +49 -0
  227. package/src/cmd/cloud/env/delete.ts +36 -12
  228. package/src/cmd/cloud/env/get.ts +28 -27
  229. package/src/cmd/cloud/env/import.ts +43 -56
  230. package/src/cmd/cloud/env/index.ts +6 -2
  231. package/src/cmd/cloud/env/list.ts +57 -30
  232. package/src/cmd/cloud/env/pull.ts +9 -3
  233. package/src/cmd/cloud/env/push.ts +44 -11
  234. package/src/cmd/cloud/env/set.ts +49 -30
  235. package/src/cmd/cloud/index.ts +0 -2
  236. package/src/cmd/cloud/region-lookup.ts +89 -0
  237. package/src/cmd/cloud/sandbox/cp.ts +5 -3
  238. package/src/cmd/cloud/sandbox/create.ts +50 -6
  239. package/src/cmd/cloud/sandbox/delete.ts +6 -3
  240. package/src/cmd/cloud/sandbox/download.ts +4 -3
  241. package/src/cmd/cloud/sandbox/env.ts +4 -3
  242. package/src/cmd/cloud/sandbox/exec.ts +4 -3
  243. package/src/cmd/cloud/sandbox/execution/get.ts +4 -4
  244. package/src/cmd/cloud/sandbox/execution/index.ts +1 -1
  245. package/src/cmd/cloud/sandbox/execution/list.ts +4 -3
  246. package/src/cmd/cloud/sandbox/get.ts +10 -4
  247. package/src/cmd/cloud/sandbox/index.ts +1 -1
  248. package/src/cmd/cloud/sandbox/list.ts +4 -4
  249. package/src/cmd/cloud/sandbox/ls.ts +4 -3
  250. package/src/cmd/cloud/sandbox/mkdir.ts +4 -3
  251. package/src/cmd/cloud/sandbox/rm.ts +4 -3
  252. package/src/cmd/cloud/sandbox/rmdir.ts +4 -3
  253. package/src/cmd/cloud/sandbox/run.ts +51 -6
  254. package/src/cmd/cloud/sandbox/runtime/index.ts +1 -1
  255. package/src/cmd/cloud/sandbox/runtime/list.ts +4 -4
  256. package/src/cmd/cloud/sandbox/snapshot/build.ts +696 -0
  257. package/src/cmd/cloud/sandbox/snapshot/create.ts +11 -5
  258. package/src/cmd/cloud/sandbox/snapshot/delete.ts +4 -4
  259. package/src/cmd/cloud/sandbox/snapshot/generate.ts +134 -0
  260. package/src/cmd/cloud/sandbox/snapshot/get.ts +23 -4
  261. package/src/cmd/cloud/sandbox/snapshot/index.ts +20 -2
  262. package/src/cmd/cloud/sandbox/snapshot/list.ts +4 -4
  263. package/src/cmd/cloud/sandbox/snapshot/tag.ts +7 -5
  264. package/src/cmd/cloud/sandbox/upload.ts +4 -3
  265. package/src/cmd/cloud/sandbox/util.ts +60 -1
  266. package/src/cmd/cloud/scp/download.ts +14 -2
  267. package/src/cmd/cloud/scp/upload.ts +14 -2
  268. package/src/cmd/cloud/session/get.ts +4 -4
  269. package/src/cmd/cloud/session/list.ts +4 -4
  270. package/src/cmd/cloud/ssh.ts +15 -2
  271. package/src/cmd/cloud/storage/delete.ts +61 -10
  272. package/src/cmd/cloud/storage/download.ts +31 -6
  273. package/src/cmd/cloud/storage/get.ts +31 -6
  274. package/src/cmd/cloud/storage/list.ts +18 -7
  275. package/src/cmd/cloud/storage/upload.ts +31 -6
  276. package/src/cmd/cloud/thread/delete.ts +4 -4
  277. package/src/cmd/cloud/thread/get.ts +4 -4
  278. package/src/cmd/cloud/thread/list.ts +4 -4
  279. package/src/cmd/project/auth/init.ts +7 -3
  280. package/src/cmd/project/auth/shared.ts +53 -14
  281. package/src/config.ts +69 -8
  282. package/src/env-util.ts +50 -5
  283. package/src/utils/apt-validator.ts +215 -0
  284. package/dist/cmd/cloud/secret/delete.d.ts +0 -2
  285. package/dist/cmd/cloud/secret/delete.d.ts.map +0 -1
  286. package/dist/cmd/cloud/secret/delete.js +0 -53
  287. package/dist/cmd/cloud/secret/delete.js.map +0 -1
  288. package/dist/cmd/cloud/secret/get.d.ts +0 -2
  289. package/dist/cmd/cloud/secret/get.d.ts.map +0 -1
  290. package/dist/cmd/cloud/secret/get.js +0 -73
  291. package/dist/cmd/cloud/secret/get.js.map +0 -1
  292. package/dist/cmd/cloud/secret/import.d.ts +0 -2
  293. package/dist/cmd/cloud/secret/import.d.ts.map +0 -1
  294. package/dist/cmd/cloud/secret/import.js +0 -91
  295. package/dist/cmd/cloud/secret/import.js.map +0 -1
  296. package/dist/cmd/cloud/secret/index.d.ts +0 -3
  297. package/dist/cmd/cloud/secret/index.d.ts.map +0 -1
  298. package/dist/cmd/cloud/secret/index.js +0 -33
  299. package/dist/cmd/cloud/secret/index.js.map +0 -1
  300. package/dist/cmd/cloud/secret/list.d.ts +0 -2
  301. package/dist/cmd/cloud/secret/list.d.ts.map +0 -1
  302. package/dist/cmd/cloud/secret/list.js +0 -65
  303. package/dist/cmd/cloud/secret/list.js.map +0 -1
  304. package/dist/cmd/cloud/secret/pull.d.ts +0 -2
  305. package/dist/cmd/cloud/secret/pull.d.ts.map +0 -1
  306. package/dist/cmd/cloud/secret/pull.js +0 -82
  307. package/dist/cmd/cloud/secret/pull.js.map +0 -1
  308. package/dist/cmd/cloud/secret/push.d.ts +0 -2
  309. package/dist/cmd/cloud/secret/push.d.ts.map +0 -1
  310. package/dist/cmd/cloud/secret/push.js +0 -61
  311. package/dist/cmd/cloud/secret/push.js.map +0 -1
  312. package/dist/cmd/cloud/secret/set.d.ts +0 -2
  313. package/dist/cmd/cloud/secret/set.d.ts.map +0 -1
  314. package/dist/cmd/cloud/secret/set.js +0 -63
  315. package/dist/cmd/cloud/secret/set.js.map +0 -1
  316. package/src/cmd/cloud/secret/delete.ts +0 -65
  317. package/src/cmd/cloud/secret/get.ts +0 -77
  318. package/src/cmd/cloud/secret/import.ts +0 -110
  319. package/src/cmd/cloud/secret/index.ts +0 -33
  320. package/src/cmd/cloud/secret/list.ts +0 -70
  321. package/src/cmd/cloud/secret/pull.ts +0 -92
  322. package/src/cmd/cloud/secret/push.ts +0 -69
  323. package/src/cmd/cloud/secret/set.ts +0 -76
@@ -0,0 +1,20 @@
1
+ import { type Logger } from '@agentuity/core';
2
+ import type { Config } from '../types';
3
+ export interface InvalidPackage {
4
+ package: string;
5
+ error: string;
6
+ requestedVersion?: string;
7
+ availableVersions?: string[];
8
+ searchUrl: string;
9
+ }
10
+ export interface AptValidationResult {
11
+ valid: string[];
12
+ invalid: InvalidPackage[];
13
+ }
14
+ /**
15
+ * Validate apt dependencies against the Debian package repository.
16
+ * Uses a local cache to avoid redundant API calls.
17
+ * Calls the app API which checks packages against snapshot.debian.org.
18
+ */
19
+ export declare function validateAptDependencies(packages: string[], region: string, config: Config | null, logger: Logger): Promise<AptValidationResult>;
20
+ //# sourceMappingURL=apt-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apt-validator.d.ts","sourceRoot":"","sources":["../../src/utils/apt-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAiBvC,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,cAAc,EAAE,CAAC;CAC1B;AAyED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC5C,QAAQ,EAAE,MAAM,EAAE,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,mBAAmB,CAAC,CAsG9B"}
@@ -0,0 +1,157 @@
1
+ import { StructuredError } from '@agentuity/core';
2
+ import { getAPIBaseURL } from '@agentuity/server';
3
+ import { getUserAgent } from '../api';
4
+ import { getDefaultConfigDir } from '../config';
5
+ import { join, dirname } from 'node:path';
6
+ import { mkdir } from 'node:fs/promises';
7
+ import { z } from 'zod';
8
+ const AptValidationError = StructuredError('AptValidationError');
9
+ const AptValidationAPIError = StructuredError('AptValidationAPIError')();
10
+ const AptValidationResponseError = StructuredError('AptValidationResponseError')();
11
+ const InvalidPackageSchema = z.object({
12
+ package: z.string(),
13
+ error: z.string(),
14
+ requestedVersion: z.string().optional(),
15
+ availableVersions: z.array(z.string()).optional(),
16
+ searchUrl: z.string(),
17
+ });
18
+ const ValidateAptDependenciesResponseSchema = z.object({
19
+ success: z.boolean(),
20
+ data: z
21
+ .object({
22
+ valid: z.array(z.string()),
23
+ invalid: z.array(InvalidPackageSchema),
24
+ })
25
+ .optional(),
26
+ message: z.string().optional(),
27
+ });
28
+ const REQUEST_TIMEOUT_MS = 30000; // 30 seconds client-side timeout
29
+ const CacheEntrySchema = z.object({
30
+ timestamp: z.number(),
31
+ });
32
+ const ValidationCacheSchema = z.object({
33
+ version: z.number(),
34
+ entries: z.record(z.string(), CacheEntrySchema),
35
+ });
36
+ const CACHE_VERSION = 1;
37
+ const CACHE_TTL_MS = 90 * 24 * 60 * 60 * 1000; // 90 days
38
+ function getCachePath() {
39
+ return join(getDefaultConfigDir(), 'dependency-validation.json');
40
+ }
41
+ async function loadCache(logger) {
42
+ const cachePath = getCachePath();
43
+ try {
44
+ const file = Bun.file(cachePath);
45
+ if (await file.exists()) {
46
+ const content = await file.json();
47
+ const parsed = ValidationCacheSchema.safeParse(content);
48
+ if (parsed.success && parsed.data.version === CACHE_VERSION) {
49
+ return parsed.data;
50
+ }
51
+ logger.debug('Cache invalid or version mismatch, starting fresh');
52
+ }
53
+ }
54
+ catch (err) {
55
+ logger.debug('Failed to load validation cache: %s', err);
56
+ }
57
+ return { version: CACHE_VERSION, entries: {} };
58
+ }
59
+ async function saveCache(cache, logger) {
60
+ const cachePath = getCachePath();
61
+ try {
62
+ await mkdir(dirname(cachePath), { recursive: true });
63
+ await Bun.write(cachePath, JSON.stringify(cache, null, 2));
64
+ }
65
+ catch (err) {
66
+ logger.debug('Failed to save validation cache: %s', err);
67
+ }
68
+ }
69
+ function isCacheEntryValid(entry) {
70
+ return Date.now() - entry.timestamp < CACHE_TTL_MS;
71
+ }
72
+ /**
73
+ * Validate apt dependencies against the Debian package repository.
74
+ * Uses a local cache to avoid redundant API calls.
75
+ * Calls the app API which checks packages against snapshot.debian.org.
76
+ */
77
+ export async function validateAptDependencies(packages, region, config, logger) {
78
+ if (packages.length === 0) {
79
+ return { valid: [], invalid: [] };
80
+ }
81
+ const cache = await loadCache(logger);
82
+ const now = Date.now();
83
+ const cachedValid = [];
84
+ const uncachedPackages = [];
85
+ // Check cache for each package (only valid packages are cached)
86
+ for (const pkg of packages) {
87
+ const entry = cache.entries[pkg];
88
+ if (entry && isCacheEntryValid(entry)) {
89
+ cachedValid.push(pkg);
90
+ logger.debug('Cache hit (valid): %s', pkg);
91
+ }
92
+ else {
93
+ uncachedPackages.push(pkg);
94
+ logger.debug('Cache miss: %s', pkg);
95
+ }
96
+ }
97
+ // If all packages are cached, return immediately
98
+ if (uncachedPackages.length === 0) {
99
+ logger.debug('All %d packages found in cache', packages.length);
100
+ return { valid: cachedValid, invalid: [] };
101
+ }
102
+ logger.debug('Validating %d uncached packages (%d cached)', uncachedPackages.length, packages.length - uncachedPackages.length);
103
+ const apiBaseUrl = getAPIBaseURL(region, config?.overrides ?? undefined);
104
+ const url = `${apiBaseUrl}/cli/validate/apt-dependencies`;
105
+ const response = await fetch(url, {
106
+ method: 'POST',
107
+ headers: {
108
+ 'Content-Type': 'application/json',
109
+ 'User-Agent': getUserAgent(config),
110
+ },
111
+ body: JSON.stringify({ packages: uncachedPackages }),
112
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
113
+ });
114
+ if (!response.ok) {
115
+ const text = await response.text();
116
+ throw new AptValidationAPIError({
117
+ message: `Failed to validate apt dependencies: HTTP ${response.status}`,
118
+ status: response.status,
119
+ body: text,
120
+ });
121
+ }
122
+ let json;
123
+ try {
124
+ json = await response.json();
125
+ }
126
+ catch (err) {
127
+ throw new AptValidationResponseError({
128
+ message: 'Invalid JSON in API response',
129
+ parseError: err instanceof Error ? err.message : String(err),
130
+ });
131
+ }
132
+ const parsed = ValidateAptDependenciesResponseSchema.safeParse(json);
133
+ if (!parsed.success) {
134
+ throw new AptValidationResponseError({
135
+ message: 'Invalid API response structure',
136
+ parseError: parsed.error.message,
137
+ });
138
+ }
139
+ const result = parsed.data;
140
+ if (!result.success || !result.data) {
141
+ throw new AptValidationError({
142
+ message: result.message ?? 'Failed to validate apt dependencies',
143
+ });
144
+ }
145
+ // Update cache with valid results only (don't cache invalid packages)
146
+ for (const pkg of result.data.valid) {
147
+ cache.entries[pkg] = { timestamp: now };
148
+ }
149
+ await saveCache(cache, logger);
150
+ logger.debug('Apt validation complete: %d valid, %d invalid (from API)', result.data.valid.length, result.data.invalid.length);
151
+ // Combine cached and fresh results
152
+ return {
153
+ valid: [...cachedValid, ...result.data.valid],
154
+ invalid: result.data.invalid,
155
+ };
156
+ }
157
+ //# sourceMappingURL=apt-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apt-validator.js","sourceRoot":"","sources":["../../src/utils/apt-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAe,MAAM,iBAAiB,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,kBAAkB,GAAG,eAAe,CAAC,oBAAoB,CAAC,CAAC;AACjE,MAAM,qBAAqB,GAAG,eAAe,CAAC,uBAAuB,CAAC,EAGlE,CAAC;AACL,MAAM,0BAA0B,GAAG,eAAe,CAAC,4BAA4B,CAAC,EAE5E,CAAC;AAeL,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACvC,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACjD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACrB,CAAC,CAAC;AAEH,MAAM,qCAAqC,GAAG,CAAC,CAAC,MAAM,CAAC;IACtD,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,IAAI,EAAE,CAAC;SACL,MAAM,CAAC;QACP,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC;KACtC,CAAC;SACD,QAAQ,EAAE;IACZ,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,KAAK,CAAC,CAAC,iCAAiC;AAEnE,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACrB,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC;CAC/C,CAAC,CAAC;AAIH,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,UAAU;AAEzD,SAAS,YAAY;IACpB,OAAO,IAAI,CAAC,mBAAmB,EAAE,EAAE,4BAA4B,CAAC,CAAC;AAClE,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,MAAc;IACtC,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,qBAAqB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACxD,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,KAAK,aAAa,EAAE,CAAC;gBAC7D,OAAO,MAAM,CAAC,IAAI,CAAC;YACpB,CAAC;YACD,MAAM,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,CAAC;IACF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,CAAC,KAAK,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AAChD,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,KAAsB,EAAE,MAAc;IAC9D,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,IAAI,CAAC;QACJ,MAAM,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,MAAM,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,CAAC,KAAK,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAAC;IAC1D,CAAC;AACF,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAuC;IACjE,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,YAAY,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC5C,QAAkB,EAClB,MAAc,EACd,MAAqB,EACrB,MAAc;IAEd,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACnC,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,gBAAgB,GAAa,EAAE,CAAC;IAEtC,gEAAgE;IAChE,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,KAAK,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACtB,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACP,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC3B,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC;IACF,CAAC;IAED,iDAAiD;IACjD,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAChE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,CAAC,KAAK,CACX,6CAA6C,EAC7C,gBAAgB,CAAC,MAAM,EACvB,QAAQ,CAAC,MAAM,GAAG,gBAAgB,CAAC,MAAM,CACzC,CAAC;IAEF,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,IAAI,SAAS,CAAC,CAAC;IACzE,MAAM,GAAG,GAAG,GAAG,UAAU,gCAAgC,CAAC;IAE1D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QACjC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACR,cAAc,EAAE,kBAAkB;YAClC,YAAY,EAAE,YAAY,CAAC,MAAM,CAAC;SAClC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;QACpD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;KAC/C,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,qBAAqB,CAAC;YAC/B,OAAO,EAAE,6CAA6C,QAAQ,CAAC,MAAM,EAAE;YACvE,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,IAAI,EAAE,IAAI;SACV,CAAC,CAAC;IACJ,CAAC;IAED,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACJ,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,IAAI,0BAA0B,CAAC;YACpC,OAAO,EAAE,8BAA8B;YACvC,UAAU,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SAC5D,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,qCAAqC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAErE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,0BAA0B,CAAC;YACpC,OAAO,EAAE,gCAAgC;YACzC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO;SAChC,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC;IAE3B,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,IAAI,kBAAkB,CAAC;YAC5B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,qCAAqC;SAChE,CAAC,CAAC;IACJ,CAAC;IAED,sEAAsE;IACtE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACrC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAE/B,MAAM,CAAC,KAAK,CACX,0DAA0D,EAC1D,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EACxB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAC1B,CAAC;IAEF,mCAAmC;IACnC,OAAO;QACN,KAAK,EAAE,CAAC,GAAG,WAAW,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAC7C,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO;KAC5B,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentuity/cli",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Agentuity employees and contributors",
6
6
  "type": "module",
@@ -40,9 +40,9 @@
40
40
  "prepublishOnly": "bun run clean && bun run build"
41
41
  },
42
42
  "dependencies": {
43
- "@agentuity/auth": "0.1.9",
44
- "@agentuity/core": "0.1.9",
45
- "@agentuity/server": "0.1.9",
43
+ "@agentuity/auth": "0.1.11",
44
+ "@agentuity/core": "0.1.11",
45
+ "@agentuity/server": "0.1.11",
46
46
  "@datasert/cronjs-parser": "^1.4.0",
47
47
  "@terascope/fetch-github-release": "^2.2.1",
48
48
  "@vitejs/plugin-react": "^5.1.2",
@@ -60,10 +60,10 @@
60
60
  "typescript": "^5.9.0",
61
61
  "vite": "^7.2.7",
62
62
  "zod": "^4.3.5",
63
- "@agentuity/frontend": "0.1.9"
63
+ "@agentuity/frontend": "0.1.11"
64
64
  },
65
65
  "devDependencies": {
66
- "@agentuity/test-utils": "0.1.9",
66
+ "@agentuity/test-utils": "0.1.11",
67
67
  "@types/adm-zip": "^0.5.7",
68
68
  "@types/bun": "latest",
69
69
  "@types/tar-fs": "^2.0.4",
@@ -0,0 +1,11 @@
1
+ export {
2
+ getResourceInfo,
3
+ getResourceRegion,
4
+ setResourceInfo,
5
+ setResourceRegion,
6
+ deleteResourceRegion,
7
+ clearProfileCache,
8
+ closeDatabase,
9
+ type ResourceType,
10
+ type ResourceInfo,
11
+ } from './resource-region';
@@ -0,0 +1,183 @@
1
+ import { Database } from 'bun:sqlite';
2
+ import { join } from 'node:path';
3
+ import { mkdir } from 'node:fs/promises';
4
+ import { getDefaultConfigDir } from '../config';
5
+
6
+ const TTL_DAYS = 7;
7
+ const TTL_MS = TTL_DAYS * 24 * 60 * 60 * 1000;
8
+
9
+ let db: Database | null = null;
10
+
11
+ async function getDatabase(): Promise<Database> {
12
+ if (db) {
13
+ return db;
14
+ }
15
+
16
+ const configDir = getDefaultConfigDir();
17
+ await mkdir(configDir, { recursive: true });
18
+
19
+ const dbPath = join(configDir, 'resource.db');
20
+ db = new Database(dbPath);
21
+
22
+ db.run(`
23
+ CREATE TABLE IF NOT EXISTS resource_region_cache (
24
+ resource_type TEXT NOT NULL,
25
+ profile TEXT NOT NULL,
26
+ id TEXT NOT NULL,
27
+ region TEXT NOT NULL,
28
+ org_id TEXT,
29
+ last_updated INTEGER NOT NULL,
30
+ PRIMARY KEY (resource_type, profile, id)
31
+ )
32
+ `);
33
+
34
+ db.run(`
35
+ CREATE INDEX IF NOT EXISTS idx_last_updated
36
+ ON resource_region_cache(last_updated)
37
+ `);
38
+
39
+ return db;
40
+ }
41
+
42
+ function pruneOldEntries(database: Database): void {
43
+ const cutoff = Date.now() - TTL_MS;
44
+ database.run('DELETE FROM resource_region_cache WHERE last_updated < ?', [cutoff]);
45
+ }
46
+
47
+ export type ResourceType = 'sandbox' | 'bucket' | 'db' | 'project' | 'deployment';
48
+
49
+ /**
50
+ * Resource info returned from cache lookup
51
+ */
52
+ export interface ResourceInfo {
53
+ region: string;
54
+ orgId?: string;
55
+ }
56
+
57
+ /**
58
+ * Get the cached info (region and orgId) for a resource.
59
+ * Returns null if not found or expired.
60
+ */
61
+ export async function getResourceInfo(
62
+ type: ResourceType,
63
+ profile: string,
64
+ id: string
65
+ ): Promise<ResourceInfo | null> {
66
+ const database = await getDatabase();
67
+ const cutoff = Date.now() - TTL_MS;
68
+
69
+ const row = database
70
+ .query<
71
+ { region: string; org_id: string | null; last_updated: number },
72
+ [string, string, string]
73
+ >('SELECT region, org_id, last_updated FROM resource_region_cache WHERE resource_type = ? AND profile = ? AND id = ?')
74
+ .get(type, profile, id);
75
+
76
+ if (!row) {
77
+ return null;
78
+ }
79
+
80
+ // Check if entry is expired
81
+ if (row.last_updated < cutoff) {
82
+ // Remove stale entry
83
+ database.run(
84
+ 'DELETE FROM resource_region_cache WHERE resource_type = ? AND profile = ? AND id = ?',
85
+ [type, profile, id]
86
+ );
87
+ return null;
88
+ }
89
+
90
+ return {
91
+ region: row.region,
92
+ orgId: row.org_id ?? undefined,
93
+ };
94
+ }
95
+
96
+ /**
97
+ * Get the cached region for a resource.
98
+ * Returns null if not found or expired.
99
+ * @deprecated Use getResourceInfo() to get both region and orgId
100
+ */
101
+ export async function getResourceRegion(
102
+ type: ResourceType,
103
+ profile: string,
104
+ id: string
105
+ ): Promise<string | null> {
106
+ const info = await getResourceInfo(type, profile, id);
107
+ return info?.region ?? null;
108
+ }
109
+
110
+ /**
111
+ * Set the cached info for a resource.
112
+ * Uses INSERT OR REPLACE to upsert.
113
+ */
114
+ export async function setResourceInfo(
115
+ type: ResourceType,
116
+ profile: string,
117
+ id: string,
118
+ region: string,
119
+ orgId?: string
120
+ ): Promise<void> {
121
+ const database = await getDatabase();
122
+
123
+ pruneOldEntries(database);
124
+
125
+ database.run(
126
+ `INSERT OR REPLACE INTO resource_region_cache
127
+ (resource_type, profile, id, region, org_id, last_updated)
128
+ VALUES (?, ?, ?, ?, ?, ?)`,
129
+ [type, profile, id, region, orgId ?? null, Date.now()]
130
+ );
131
+ }
132
+
133
+ /**
134
+ * Set the cached region for a resource.
135
+ * Uses INSERT OR REPLACE to upsert.
136
+ * @deprecated Use setResourceInfo() to set both region and orgId
137
+ */
138
+ export async function setResourceRegion(
139
+ type: ResourceType,
140
+ profile: string,
141
+ id: string,
142
+ region: string
143
+ ): Promise<void> {
144
+ await setResourceInfo(type, profile, id, region);
145
+ }
146
+
147
+ /**
148
+ * Delete the cached info for a resource.
149
+ * Called when a resource is deleted.
150
+ */
151
+ export async function deleteResourceRegion(
152
+ type: ResourceType,
153
+ profile: string,
154
+ id: string
155
+ ): Promise<void> {
156
+ const database = await getDatabase();
157
+
158
+ database.run(
159
+ 'DELETE FROM resource_region_cache WHERE resource_type = ? AND profile = ? AND id = ?',
160
+ [type, profile, id]
161
+ );
162
+ }
163
+
164
+ /**
165
+ * Clear all cached entries for a specific profile.
166
+ * Useful when switching profiles or logging out.
167
+ */
168
+ export async function clearProfileCache(profile: string): Promise<void> {
169
+ const database = await getDatabase();
170
+
171
+ database.run('DELETE FROM resource_region_cache WHERE profile = ?', [profile]);
172
+ }
173
+
174
+ /**
175
+ * Close the database connection.
176
+ * Should be called on CLI exit for clean shutdown.
177
+ */
178
+ export function closeDatabase(): void {
179
+ if (db) {
180
+ db.close();
181
+ db = null;
182
+ }
183
+ }
package/src/cli.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { mkdir } from 'node:fs/promises';
1
+ import { mkdir, unlink } from 'node:fs/promises';
2
2
  import { homedir } from 'node:os';
3
3
  import { resolve, join } from 'node:path';
4
4
  import { Command } from 'commander';
@@ -369,7 +369,7 @@ function handleProjectConfigError(
369
369
  error &&
370
370
  typeof error === 'object' &&
371
371
  'name' in error &&
372
- error.name === 'ProjectConfigNotFoundExpection'
372
+ error.name === 'ProjectConfigNotFoundException'
373
373
  ) {
374
374
  exitWithError(
375
375
  createError(ErrorCode.PROJECT_NOT_FOUND, 'Invalid project folder', undefined, [
@@ -685,91 +685,100 @@ async function getRegion(regions: RegionList): Promise<string> {
685
685
  interface ResolveRegionOptions {
686
686
  options: Record<string, unknown>;
687
687
  apiClient: APIClientType;
688
- apiUrl: string;
688
+ profileName: string;
689
689
  logger: Logger;
690
690
  required: boolean;
691
691
  region?: string;
692
692
  }
693
693
 
694
- const REGIONS_CACHE_FILE = 'regions.json';
695
694
  const REGIONS_CACHE_MAX_AGE_MS = 5 * 24 * 60 * 60 * 1000; // 5 days
695
+ const LEGACY_REGIONS_CACHE_FILE = 'regions.json';
696
+
697
+ function getRegionsCacheFile(profileName: string): string {
698
+ return `regions-${profileName}.json`;
699
+ }
700
+
701
+ async function removeLegacyRegionsCache(logger: Logger): Promise<void> {
702
+ try {
703
+ const legacyPath = join(getDefaultConfigDir(), LEGACY_REGIONS_CACHE_FILE);
704
+ const file = Bun.file(legacyPath);
705
+ if (await file.exists()) {
706
+ await unlink(legacyPath);
707
+ logger.trace('removed legacy regions cache file');
708
+ }
709
+ } catch {
710
+ // Ignore errors when removing legacy file
711
+ }
712
+ }
696
713
 
697
714
  interface RegionsCacheData {
698
715
  timestamp: number;
699
716
  regions: RegionList;
700
- apiUrl?: string; // Added to make cache profile-aware
701
717
  }
702
718
 
703
- async function getCachedRegions(apiUrl: string, logger: Logger): Promise<RegionList | null> {
719
+ async function getCachedRegions(profileName: string, logger: Logger): Promise<RegionList | null> {
704
720
  try {
705
- const cachePath = join(getDefaultConfigDir(), REGIONS_CACHE_FILE);
721
+ // Clean up legacy single-file cache from older versions
722
+ await removeLegacyRegionsCache(logger);
723
+
724
+ const cachePath = join(getDefaultConfigDir(), getRegionsCacheFile(profileName));
706
725
  const file = Bun.file(cachePath);
707
726
  if (!(await file.exists())) {
708
727
  return null;
709
728
  }
710
729
  const data: RegionsCacheData = await file.json();
711
- // Check if cache is for the same API URL (profile-aware)
712
- if (data.apiUrl && data.apiUrl !== apiUrl) {
713
- logger.trace(
714
- 'regions cache is for different API URL (cached: %s, current: %s)',
715
- data.apiUrl,
716
- apiUrl
717
- );
718
- return null;
719
- }
720
730
  const age = Date.now() - data.timestamp;
721
731
  if (age > REGIONS_CACHE_MAX_AGE_MS) {
722
- logger.trace('regions cache expired (age: %dms)', age);
732
+ logger.trace('regions cache expired for profile %s (age: %dms)', profileName, age);
723
733
  return null;
724
734
  }
725
- logger.trace('using cached regions (age: %dms)', age);
735
+ logger.trace('using cached regions for profile %s (age: %dms)', profileName, age);
726
736
  return data.regions;
727
737
  } catch (error) {
728
- logger.trace('failed to read regions cache: %s', error);
738
+ logger.trace('failed to read regions cache for profile %s: %s', profileName, error);
729
739
  return null;
730
740
  }
731
741
  }
732
742
 
733
743
  async function saveRegionsCache(
734
- apiUrl: string,
744
+ profileName: string,
735
745
  regions: RegionList,
736
746
  logger: Logger
737
747
  ): Promise<void> {
738
748
  try {
739
749
  const cacheDir = getDefaultConfigDir();
740
750
  await mkdir(cacheDir, { recursive: true });
741
- const cachePath = join(cacheDir, REGIONS_CACHE_FILE);
751
+ const cachePath = join(cacheDir, getRegionsCacheFile(profileName));
742
752
  const data: RegionsCacheData = {
743
753
  timestamp: Date.now(),
744
754
  regions,
745
- apiUrl,
746
755
  };
747
756
  await Bun.write(cachePath, JSON.stringify(data));
748
- logger.trace('saved regions cache for %s', apiUrl);
757
+ logger.trace('saved regions cache for profile %s', profileName);
749
758
  } catch (error) {
750
- logger.trace('failed to save regions cache: %s', error);
759
+ logger.trace('failed to save regions cache for profile %s: %s', profileName, error);
751
760
  }
752
761
  }
753
762
 
754
763
  async function fetchRegionsWithCache(
755
- apiUrl: string,
764
+ profileName: string,
756
765
  apiClient: APIClientType,
757
766
  logger: Logger
758
767
  ): Promise<RegionList> {
759
- const cached = await getCachedRegions(apiUrl, logger);
768
+ const cached = await getCachedRegions(profileName, logger);
760
769
  if (cached) {
761
770
  return cached;
762
771
  }
763
772
  const regions = await listRegions(apiClient);
764
- await saveRegionsCache(apiUrl, regions, logger);
773
+ await saveRegionsCache(profileName, regions, logger);
765
774
  return regions;
766
775
  }
767
776
 
768
777
  async function resolveRegion(opts: ResolveRegionOptions): Promise<string | undefined> {
769
- const { options, apiClient, apiUrl, logger, required } = opts;
778
+ const { options, apiClient, profileName, logger, required } = opts;
770
779
 
771
780
  // Fetch regions (with caching)
772
- const regions = await fetchRegionsWithCache(apiUrl, apiClient, logger);
781
+ const regions = await fetchRegionsWithCache(profileName, apiClient, logger);
773
782
 
774
783
  // No regions available
775
784
  if (regions.length === 0) {
@@ -1129,7 +1138,7 @@ async function registerSubcommand(
1129
1138
  error &&
1130
1139
  typeof error === 'object' &&
1131
1140
  'name' in error &&
1132
- error.name === 'ProjectConfigNotFoundExpection'
1141
+ error.name === 'ProjectConfigNotFoundException'
1133
1142
  ) {
1134
1143
  // If TTY is available, prompt user to select a project
1135
1144
  const hasTTY = process.stdin.isTTY && process.stdout.isTTY;
@@ -1237,7 +1246,7 @@ async function registerSubcommand(
1237
1246
  return resolveRegion({
1238
1247
  options: options as Record<string, unknown>,
1239
1248
  apiClient,
1240
- apiUrl: getAPIBaseURL(baseCtx.config),
1249
+ profileName: baseCtx.config?.name ?? defaultProfileName,
1241
1250
  logger: baseCtx.logger,
1242
1251
  required: !!normalized.requiresRegion,
1243
1252
  region: project?.region,
@@ -1306,7 +1315,7 @@ async function registerSubcommand(
1306
1315
  return resolveRegion({
1307
1316
  options: options as Record<string, unknown>,
1308
1317
  apiClient,
1309
- apiUrl: getAPIBaseURL(baseCtx.config),
1318
+ profileName: baseCtx.config?.name ?? defaultProfileName,
1310
1319
  logger: baseCtx.logger,
1311
1320
  required: !!normalized.requiresRegion,
1312
1321
  region: project?.region,
@@ -1420,7 +1429,7 @@ async function registerSubcommand(
1420
1429
  const region = await resolveRegion({
1421
1430
  options: options as Record<string, unknown>,
1422
1431
  apiClient,
1423
- apiUrl: getAPIBaseURL(baseCtx.config),
1432
+ profileName: baseCtx.config?.name ?? defaultProfileName,
1424
1433
  logger: baseCtx.logger,
1425
1434
  required: !!normalized.requiresRegion,
1426
1435
  region: project?.region,
@@ -1485,7 +1494,7 @@ async function registerSubcommand(
1485
1494
  const region = await resolveRegion({
1486
1495
  options: options as Record<string, unknown>,
1487
1496
  apiClient,
1488
- apiUrl: getAPIBaseURL(baseCtx.config),
1497
+ profileName: baseCtx.config?.name ?? defaultProfileName,
1489
1498
  logger: baseCtx.logger,
1490
1499
  required: !!normalized.requiresRegion,
1491
1500
  });
@@ -1597,7 +1606,7 @@ async function registerSubcommand(
1597
1606
  const region = await resolveRegion({
1598
1607
  options: options as Record<string, unknown>,
1599
1608
  apiClient,
1600
- apiUrl: getAPIBaseURL(baseCtx.config),
1609
+ profileName: baseCtx.config?.name ?? defaultProfileName,
1601
1610
  logger: baseCtx.logger,
1602
1611
  required: !!normalized.requiresRegion,
1603
1612
  region: project?.region,
@@ -1726,7 +1735,7 @@ export async function registerCommands(
1726
1735
  const region = await resolveRegion({
1727
1736
  options: baseCtx.options as unknown as Record<string, unknown>,
1728
1737
  apiClient,
1729
- apiUrl: getAPIBaseURL(baseCtx.config),
1738
+ profileName: baseCtx.config?.name ?? defaultProfileName,
1730
1739
  logger: baseCtx.logger,
1731
1740
  required: !!normalized.requiresRegion,
1732
1741
  });
@@ -1784,7 +1793,7 @@ export async function registerCommands(
1784
1793
  const region = await resolveRegion({
1785
1794
  options: baseCtx.options as unknown as Record<string, unknown>,
1786
1795
  apiClient,
1787
- apiUrl: getAPIBaseURL(baseCtx.config),
1796
+ profileName: baseCtx.config?.name ?? defaultProfileName,
1788
1797
  logger: baseCtx.logger,
1789
1798
  required: !!normalized.requiresRegion,
1790
1799
  });
@@ -1805,7 +1814,7 @@ export async function registerCommands(
1805
1814
  const region = await resolveRegion({
1806
1815
  options: baseCtx.options as unknown as Record<string, unknown>,
1807
1816
  apiClient,
1808
- apiUrl: getAPIBaseURL(baseCtx.config),
1817
+ profileName: baseCtx.config?.name ?? defaultProfileName,
1809
1818
  logger: baseCtx.logger,
1810
1819
  required: !!normalized.requiresRegion,
1811
1820
  });