@swarmify/agents-cli 1.13.4 → 1.14.2

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 (567) hide show
  1. package/README.md +4 -319
  2. package/bin/agents.js +2 -0
  3. package/package.json +13 -79
  4. package/scripts/postinstall.js +4 -71
  5. package/CHANGELOG.md +0 -316
  6. package/LICENSE +0 -21
  7. package/dist/commands/__tests__/sessions-tail.test.d.ts +0 -2
  8. package/dist/commands/__tests__/sessions-tail.test.d.ts.map +0 -1
  9. package/dist/commands/__tests__/sessions-tail.test.js +0 -108
  10. package/dist/commands/__tests__/sessions-tail.test.js.map +0 -1
  11. package/dist/commands/__tests__/sessions.test.d.ts +0 -2
  12. package/dist/commands/__tests__/sessions.test.d.ts.map +0 -1
  13. package/dist/commands/__tests__/sessions.test.js +0 -636
  14. package/dist/commands/__tests__/sessions.test.js.map +0 -1
  15. package/dist/commands/cloud.d.ts +0 -11
  16. package/dist/commands/cloud.d.ts.map +0 -1
  17. package/dist/commands/cloud.js +0 -363
  18. package/dist/commands/cloud.js.map +0 -1
  19. package/dist/commands/commands.d.ts +0 -12
  20. package/dist/commands/commands.d.ts.map +0 -1
  21. package/dist/commands/commands.js +0 -629
  22. package/dist/commands/commands.js.map +0 -1
  23. package/dist/commands/daemon.d.ts +0 -11
  24. package/dist/commands/daemon.d.ts.map +0 -1
  25. package/dist/commands/daemon.js +0 -119
  26. package/dist/commands/daemon.js.map +0 -1
  27. package/dist/commands/drive.d.ts +0 -11
  28. package/dist/commands/drive.d.ts.map +0 -1
  29. package/dist/commands/drive.js +0 -175
  30. package/dist/commands/drive.js.map +0 -1
  31. package/dist/commands/exec.d.ts +0 -11
  32. package/dist/commands/exec.d.ts.map +0 -1
  33. package/dist/commands/exec.js +0 -251
  34. package/dist/commands/exec.js.map +0 -1
  35. package/dist/commands/factory.d.ts +0 -11
  36. package/dist/commands/factory.d.ts.map +0 -1
  37. package/dist/commands/factory.js +0 -445
  38. package/dist/commands/factory.js.map +0 -1
  39. package/dist/commands/fork.d.ts +0 -11
  40. package/dist/commands/fork.d.ts.map +0 -1
  41. package/dist/commands/fork.js +0 -147
  42. package/dist/commands/fork.js.map +0 -1
  43. package/dist/commands/hooks.d.ts +0 -12
  44. package/dist/commands/hooks.d.ts.map +0 -1
  45. package/dist/commands/hooks.js +0 -690
  46. package/dist/commands/hooks.js.map +0 -1
  47. package/dist/commands/init.d.ts +0 -15
  48. package/dist/commands/init.d.ts.map +0 -1
  49. package/dist/commands/init.js +0 -137
  50. package/dist/commands/init.js.map +0 -1
  51. package/dist/commands/mcp.d.ts +0 -12
  52. package/dist/commands/mcp.d.ts.map +0 -1
  53. package/dist/commands/mcp.js +0 -583
  54. package/dist/commands/mcp.js.map +0 -1
  55. package/dist/commands/models.d.ts +0 -11
  56. package/dist/commands/models.d.ts.map +0 -1
  57. package/dist/commands/models.js +0 -170
  58. package/dist/commands/models.js.map +0 -1
  59. package/dist/commands/packages.d.ts +0 -11
  60. package/dist/commands/packages.d.ts.map +0 -1
  61. package/dist/commands/packages.js +0 -551
  62. package/dist/commands/packages.js.map +0 -1
  63. package/dist/commands/permissions.d.ts +0 -12
  64. package/dist/commands/permissions.d.ts.map +0 -1
  65. package/dist/commands/permissions.js +0 -724
  66. package/dist/commands/permissions.js.map +0 -1
  67. package/dist/commands/plugins.d.ts +0 -11
  68. package/dist/commands/plugins.d.ts.map +0 -1
  69. package/dist/commands/plugins.js +0 -393
  70. package/dist/commands/plugins.js.map +0 -1
  71. package/dist/commands/profiles.d.ts +0 -12
  72. package/dist/commands/profiles.d.ts.map +0 -1
  73. package/dist/commands/profiles.js +0 -255
  74. package/dist/commands/profiles.js.map +0 -1
  75. package/dist/commands/pty.d.ts +0 -21
  76. package/dist/commands/pty.d.ts.map +0 -1
  77. package/dist/commands/pty.js +0 -391
  78. package/dist/commands/pty.js.map +0 -1
  79. package/dist/commands/pull.d.ts +0 -11
  80. package/dist/commands/pull.d.ts.map +0 -1
  81. package/dist/commands/pull.js +0 -456
  82. package/dist/commands/pull.js.map +0 -1
  83. package/dist/commands/push.d.ts +0 -11
  84. package/dist/commands/push.d.ts.map +0 -1
  85. package/dist/commands/push.js +0 -188
  86. package/dist/commands/push.js.map +0 -1
  87. package/dist/commands/refresh-memory.d.ts +0 -16
  88. package/dist/commands/refresh-memory.d.ts.map +0 -1
  89. package/dist/commands/refresh-memory.js +0 -52
  90. package/dist/commands/refresh-memory.js.map +0 -1
  91. package/dist/commands/resource-view.d.ts +0 -39
  92. package/dist/commands/resource-view.d.ts.map +0 -1
  93. package/dist/commands/resource-view.js +0 -197
  94. package/dist/commands/resource-view.js.map +0 -1
  95. package/dist/commands/routines.d.ts +0 -11
  96. package/dist/commands/routines.d.ts.map +0 -1
  97. package/dist/commands/routines.js +0 -590
  98. package/dist/commands/routines.js.map +0 -1
  99. package/dist/commands/rules.d.ts +0 -12
  100. package/dist/commands/rules.d.ts.map +0 -1
  101. package/dist/commands/rules.js +0 -489
  102. package/dist/commands/rules.js.map +0 -1
  103. package/dist/commands/secrets.d.ts +0 -11
  104. package/dist/commands/secrets.d.ts.map +0 -1
  105. package/dist/commands/secrets.js +0 -352
  106. package/dist/commands/secrets.js.map +0 -1
  107. package/dist/commands/sessions-picker.d.ts +0 -18
  108. package/dist/commands/sessions-picker.d.ts.map +0 -1
  109. package/dist/commands/sessions-picker.js +0 -265
  110. package/dist/commands/sessions-picker.js.map +0 -1
  111. package/dist/commands/sessions-tail.d.ts +0 -20
  112. package/dist/commands/sessions-tail.d.ts.map +0 -1
  113. package/dist/commands/sessions-tail.js +0 -236
  114. package/dist/commands/sessions-tail.js.map +0 -1
  115. package/dist/commands/sessions.d.ts +0 -18
  116. package/dist/commands/sessions.d.ts.map +0 -1
  117. package/dist/commands/sessions.js +0 -1173
  118. package/dist/commands/sessions.js.map +0 -1
  119. package/dist/commands/skills.d.ts +0 -12
  120. package/dist/commands/skills.d.ts.map +0 -1
  121. package/dist/commands/skills.js +0 -717
  122. package/dist/commands/skills.js.map +0 -1
  123. package/dist/commands/status.d.ts +0 -10
  124. package/dist/commands/status.d.ts.map +0 -1
  125. package/dist/commands/status.js +0 -26
  126. package/dist/commands/status.js.map +0 -1
  127. package/dist/commands/subagents.d.ts +0 -11
  128. package/dist/commands/subagents.d.ts.map +0 -1
  129. package/dist/commands/subagents.js +0 -361
  130. package/dist/commands/subagents.js.map +0 -1
  131. package/dist/commands/sync.d.ts +0 -11
  132. package/dist/commands/sync.d.ts.map +0 -1
  133. package/dist/commands/sync.js +0 -70
  134. package/dist/commands/sync.js.map +0 -1
  135. package/dist/commands/teams-picker.d.ts +0 -18
  136. package/dist/commands/teams-picker.d.ts.map +0 -1
  137. package/dist/commands/teams-picker.js +0 -290
  138. package/dist/commands/teams-picker.js.map +0 -1
  139. package/dist/commands/teams.d.ts +0 -18
  140. package/dist/commands/teams.d.ts.map +0 -1
  141. package/dist/commands/teams.js +0 -1144
  142. package/dist/commands/teams.js.map +0 -1
  143. package/dist/commands/utils.d.ts +0 -45
  144. package/dist/commands/utils.d.ts.map +0 -1
  145. package/dist/commands/utils.js +0 -106
  146. package/dist/commands/utils.js.map +0 -1
  147. package/dist/commands/versions.d.ts +0 -11
  148. package/dist/commands/versions.d.ts.map +0 -1
  149. package/dist/commands/versions.js +0 -701
  150. package/dist/commands/versions.js.map +0 -1
  151. package/dist/commands/view.d.ts +0 -43
  152. package/dist/commands/view.d.ts.map +0 -1
  153. package/dist/commands/view.js +0 -894
  154. package/dist/commands/view.js.map +0 -1
  155. package/dist/index.d.ts +0 -9
  156. package/dist/index.d.ts.map +0 -1
  157. package/dist/index.js +0 -496
  158. package/dist/index.js.map +0 -1
  159. package/dist/lib/__tests__/bugfixes.test.d.ts +0 -2
  160. package/dist/lib/__tests__/bugfixes.test.d.ts.map +0 -1
  161. package/dist/lib/__tests__/bugfixes.test.js +0 -192
  162. package/dist/lib/__tests__/bugfixes.test.js.map +0 -1
  163. package/dist/lib/__tests__/exec.test.d.ts +0 -2
  164. package/dist/lib/__tests__/exec.test.d.ts.map +0 -1
  165. package/dist/lib/__tests__/exec.test.js +0 -446
  166. package/dist/lib/__tests__/exec.test.js.map +0 -1
  167. package/dist/lib/__tests__/git-sync.test.d.ts +0 -2
  168. package/dist/lib/__tests__/git-sync.test.d.ts.map +0 -1
  169. package/dist/lib/__tests__/git-sync.test.js +0 -138
  170. package/dist/lib/__tests__/git-sync.test.js.map +0 -1
  171. package/dist/lib/__tests__/hooks.test.d.ts +0 -2
  172. package/dist/lib/__tests__/hooks.test.d.ts.map +0 -1
  173. package/dist/lib/__tests__/hooks.test.js +0 -203
  174. package/dist/lib/__tests__/hooks.test.js.map +0 -1
  175. package/dist/lib/__tests__/memory-compile.test.d.ts +0 -2
  176. package/dist/lib/__tests__/memory-compile.test.d.ts.map +0 -1
  177. package/dist/lib/__tests__/memory-compile.test.js +0 -95
  178. package/dist/lib/__tests__/memory-compile.test.js.map +0 -1
  179. package/dist/lib/__tests__/models.test.d.ts +0 -2
  180. package/dist/lib/__tests__/models.test.d.ts.map +0 -1
  181. package/dist/lib/__tests__/models.test.js +0 -239
  182. package/dist/lib/__tests__/models.test.js.map +0 -1
  183. package/dist/lib/__tests__/rotate.test.d.ts +0 -2
  184. package/dist/lib/__tests__/rotate.test.d.ts.map +0 -1
  185. package/dist/lib/__tests__/rotate.test.js +0 -80
  186. package/dist/lib/__tests__/rotate.test.js.map +0 -1
  187. package/dist/lib/__tests__/secrets-bundles.test.d.ts +0 -2
  188. package/dist/lib/__tests__/secrets-bundles.test.d.ts.map +0 -1
  189. package/dist/lib/__tests__/secrets-bundles.test.js +0 -104
  190. package/dist/lib/__tests__/secrets-bundles.test.js.map +0 -1
  191. package/dist/lib/__tests__/secrets.test.d.ts +0 -2
  192. package/dist/lib/__tests__/secrets.test.d.ts.map +0 -1
  193. package/dist/lib/__tests__/secrets.test.js +0 -90
  194. package/dist/lib/__tests__/secrets.test.js.map +0 -1
  195. package/dist/lib/__tests__/shims.test.d.ts +0 -2
  196. package/dist/lib/__tests__/shims.test.d.ts.map +0 -1
  197. package/dist/lib/__tests__/shims.test.js +0 -57
  198. package/dist/lib/__tests__/shims.test.js.map +0 -1
  199. package/dist/lib/__tests__/usage.test.d.ts +0 -2
  200. package/dist/lib/__tests__/usage.test.d.ts.map +0 -1
  201. package/dist/lib/__tests__/usage.test.js +0 -220
  202. package/dist/lib/__tests__/usage.test.js.map +0 -1
  203. package/dist/lib/__tests__/versions.test.d.ts +0 -2
  204. package/dist/lib/__tests__/versions.test.d.ts.map +0 -1
  205. package/dist/lib/__tests__/versions.test.js +0 -63
  206. package/dist/lib/__tests__/versions.test.js.map +0 -1
  207. package/dist/lib/agents.d.ts +0 -158
  208. package/dist/lib/agents.d.ts.map +0 -1
  209. package/dist/lib/agents.js +0 -1159
  210. package/dist/lib/agents.js.map +0 -1
  211. package/dist/lib/artifact-actions.d.ts +0 -27
  212. package/dist/lib/artifact-actions.d.ts.map +0 -1
  213. package/dist/lib/artifact-actions.js +0 -58
  214. package/dist/lib/artifact-actions.js.map +0 -1
  215. package/dist/lib/cloud/codex.d.ts +0 -26
  216. package/dist/lib/cloud/codex.d.ts.map +0 -1
  217. package/dist/lib/cloud/codex.js +0 -237
  218. package/dist/lib/cloud/codex.js.map +0 -1
  219. package/dist/lib/cloud/factory.d.ts +0 -32
  220. package/dist/lib/cloud/factory.d.ts.map +0 -1
  221. package/dist/lib/cloud/factory.js +0 -43
  222. package/dist/lib/cloud/factory.js.map +0 -1
  223. package/dist/lib/cloud/registry.d.ts +0 -16
  224. package/dist/lib/cloud/registry.d.ts.map +0 -1
  225. package/dist/lib/cloud/registry.js +0 -68
  226. package/dist/lib/cloud/registry.js.map +0 -1
  227. package/dist/lib/cloud/rush.d.ts +0 -37
  228. package/dist/lib/cloud/rush.d.ts.map +0 -1
  229. package/dist/lib/cloud/rush.js +0 -230
  230. package/dist/lib/cloud/rush.js.map +0 -1
  231. package/dist/lib/cloud/rush.test.d.ts +0 -2
  232. package/dist/lib/cloud/rush.test.d.ts.map +0 -1
  233. package/dist/lib/cloud/rush.test.js +0 -63
  234. package/dist/lib/cloud/rush.test.js.map +0 -1
  235. package/dist/lib/cloud/store.d.ts +0 -23
  236. package/dist/lib/cloud/store.d.ts.map +0 -1
  237. package/dist/lib/cloud/store.js +0 -116
  238. package/dist/lib/cloud/store.js.map +0 -1
  239. package/dist/lib/cloud/stream.d.ts +0 -24
  240. package/dist/lib/cloud/stream.d.ts.map +0 -1
  241. package/dist/lib/cloud/stream.js +0 -145
  242. package/dist/lib/cloud/stream.js.map +0 -1
  243. package/dist/lib/cloud/types.d.ts +0 -109
  244. package/dist/lib/cloud/types.d.ts.map +0 -1
  245. package/dist/lib/cloud/types.js +0 -33
  246. package/dist/lib/cloud/types.js.map +0 -1
  247. package/dist/lib/cloud/types.test.d.ts +0 -2
  248. package/dist/lib/cloud/types.test.d.ts.map +0 -1
  249. package/dist/lib/cloud/types.test.js +0 -41
  250. package/dist/lib/cloud/types.test.js.map +0 -1
  251. package/dist/lib/commands.d.ts +0 -141
  252. package/dist/lib/commands.d.ts.map +0 -1
  253. package/dist/lib/commands.js +0 -514
  254. package/dist/lib/commands.js.map +0 -1
  255. package/dist/lib/convert.d.ts +0 -21
  256. package/dist/lib/convert.d.ts.map +0 -1
  257. package/dist/lib/convert.js +0 -54
  258. package/dist/lib/convert.js.map +0 -1
  259. package/dist/lib/daemon.d.ts +0 -43
  260. package/dist/lib/daemon.d.ts.map +0 -1
  261. package/dist/lib/daemon.js +0 -332
  262. package/dist/lib/daemon.js.map +0 -1
  263. package/dist/lib/drive-sync.d.ts +0 -46
  264. package/dist/lib/drive-sync.d.ts.map +0 -1
  265. package/dist/lib/drive-sync.js +0 -209
  266. package/dist/lib/drive-sync.js.map +0 -1
  267. package/dist/lib/exec.d.ts +0 -101
  268. package/dist/lib/exec.d.ts.map +0 -1
  269. package/dist/lib/exec.js +0 -450
  270. package/dist/lib/exec.js.map +0 -1
  271. package/dist/lib/factory/__tests__/config.test.d.ts +0 -2
  272. package/dist/lib/factory/__tests__/config.test.d.ts.map +0 -1
  273. package/dist/lib/factory/__tests__/config.test.js +0 -128
  274. package/dist/lib/factory/__tests__/config.test.js.map +0 -1
  275. package/dist/lib/factory/config.d.ts +0 -49
  276. package/dist/lib/factory/config.d.ts.map +0 -1
  277. package/dist/lib/factory/config.js +0 -127
  278. package/dist/lib/factory/config.js.map +0 -1
  279. package/dist/lib/factory.d.ts +0 -57
  280. package/dist/lib/factory.d.ts.map +0 -1
  281. package/dist/lib/factory.js +0 -107
  282. package/dist/lib/factory.js.map +0 -1
  283. package/dist/lib/git.d.ts +0 -157
  284. package/dist/lib/git.d.ts.map +0 -1
  285. package/dist/lib/git.js +0 -647
  286. package/dist/lib/git.js.map +0 -1
  287. package/dist/lib/help.d.ts +0 -10
  288. package/dist/lib/help.d.ts.map +0 -1
  289. package/dist/lib/help.js +0 -66
  290. package/dist/lib/help.js.map +0 -1
  291. package/dist/lib/hooks.d.ts +0 -125
  292. package/dist/lib/hooks.d.ts.map +0 -1
  293. package/dist/lib/hooks.js +0 -846
  294. package/dist/lib/hooks.js.map +0 -1
  295. package/dist/lib/ledger/__tests__/local.test.d.ts +0 -2
  296. package/dist/lib/ledger/__tests__/local.test.d.ts.map +0 -1
  297. package/dist/lib/ledger/__tests__/local.test.js +0 -177
  298. package/dist/lib/ledger/__tests__/local.test.js.map +0 -1
  299. package/dist/lib/ledger/__tests__/sync.test.d.ts +0 -2
  300. package/dist/lib/ledger/__tests__/sync.test.d.ts.map +0 -1
  301. package/dist/lib/ledger/__tests__/sync.test.js +0 -117
  302. package/dist/lib/ledger/__tests__/sync.test.js.map +0 -1
  303. package/dist/lib/ledger/index.d.ts +0 -18
  304. package/dist/lib/ledger/index.d.ts.map +0 -1
  305. package/dist/lib/ledger/index.js +0 -32
  306. package/dist/lib/ledger/index.js.map +0 -1
  307. package/dist/lib/ledger/local.d.ts +0 -22
  308. package/dist/lib/ledger/local.d.ts.map +0 -1
  309. package/dist/lib/ledger/local.js +0 -333
  310. package/dist/lib/ledger/local.js.map +0 -1
  311. package/dist/lib/ledger/r2.d.ts +0 -41
  312. package/dist/lib/ledger/r2.d.ts.map +0 -1
  313. package/dist/lib/ledger/r2.js +0 -335
  314. package/dist/lib/ledger/r2.js.map +0 -1
  315. package/dist/lib/ledger/sync.d.ts +0 -33
  316. package/dist/lib/ledger/sync.d.ts.map +0 -1
  317. package/dist/lib/ledger/sync.js +0 -106
  318. package/dist/lib/ledger/sync.js.map +0 -1
  319. package/dist/lib/ledger/types.d.ts +0 -100
  320. package/dist/lib/ledger/types.d.ts.map +0 -1
  321. package/dist/lib/ledger/types.js +0 -21
  322. package/dist/lib/ledger/types.js.map +0 -1
  323. package/dist/lib/manifest.d.ts +0 -14
  324. package/dist/lib/manifest.d.ts.map +0 -1
  325. package/dist/lib/manifest.js +0 -48
  326. package/dist/lib/manifest.js.map +0 -1
  327. package/dist/lib/markdown.d.ts +0 -5
  328. package/dist/lib/markdown.d.ts.map +0 -1
  329. package/dist/lib/markdown.js +0 -17
  330. package/dist/lib/markdown.js.map +0 -1
  331. package/dist/lib/mcp.d.ts +0 -64
  332. package/dist/lib/mcp.d.ts.map +0 -1
  333. package/dist/lib/mcp.js +0 -327
  334. package/dist/lib/mcp.js.map +0 -1
  335. package/dist/lib/memory-compile.d.ts +0 -65
  336. package/dist/lib/memory-compile.d.ts.map +0 -1
  337. package/dist/lib/memory-compile.js +0 -174
  338. package/dist/lib/memory-compile.js.map +0 -1
  339. package/dist/lib/memory.d.ts +0 -64
  340. package/dist/lib/memory.d.ts.map +0 -1
  341. package/dist/lib/memory.js +0 -275
  342. package/dist/lib/memory.js.map +0 -1
  343. package/dist/lib/models.d.ts +0 -98
  344. package/dist/lib/models.d.ts.map +0 -1
  345. package/dist/lib/models.js +0 -728
  346. package/dist/lib/models.js.map +0 -1
  347. package/dist/lib/permissions.d.ts +0 -227
  348. package/dist/lib/permissions.d.ts.map +0 -1
  349. package/dist/lib/permissions.js +0 -1085
  350. package/dist/lib/permissions.js.map +0 -1
  351. package/dist/lib/picker.d.ts +0 -27
  352. package/dist/lib/picker.d.ts.map +0 -1
  353. package/dist/lib/picker.js +0 -110
  354. package/dist/lib/picker.js.map +0 -1
  355. package/dist/lib/plugins.d.ts +0 -80
  356. package/dist/lib/plugins.d.ts.map +0 -1
  357. package/dist/lib/plugins.js +0 -556
  358. package/dist/lib/plugins.js.map +0 -1
  359. package/dist/lib/profiles-keychain.d.ts +0 -11
  360. package/dist/lib/profiles-keychain.d.ts.map +0 -1
  361. package/dist/lib/profiles-keychain.js +0 -14
  362. package/dist/lib/profiles-keychain.js.map +0 -1
  363. package/dist/lib/profiles-presets.d.ts +0 -25
  364. package/dist/lib/profiles-presets.d.ts.map +0 -1
  365. package/dist/lib/profiles-presets.js +0 -104
  366. package/dist/lib/profiles-presets.js.map +0 -1
  367. package/dist/lib/profiles.d.ts +0 -70
  368. package/dist/lib/profiles.d.ts.map +0 -1
  369. package/dist/lib/profiles.js +0 -145
  370. package/dist/lib/profiles.js.map +0 -1
  371. package/dist/lib/pty-client.d.ts +0 -23
  372. package/dist/lib/pty-client.d.ts.map +0 -1
  373. package/dist/lib/pty-client.js +0 -181
  374. package/dist/lib/pty-client.js.map +0 -1
  375. package/dist/lib/pty-server.d.ts +0 -21
  376. package/dist/lib/pty-server.d.ts.map +0 -1
  377. package/dist/lib/pty-server.js +0 -427
  378. package/dist/lib/pty-server.js.map +0 -1
  379. package/dist/lib/registry.d.ts +0 -45
  380. package/dist/lib/registry.d.ts.map +0 -1
  381. package/dist/lib/registry.js +0 -220
  382. package/dist/lib/registry.js.map +0 -1
  383. package/dist/lib/resources.d.ts +0 -55
  384. package/dist/lib/resources.d.ts.map +0 -1
  385. package/dist/lib/resources.js +0 -103
  386. package/dist/lib/resources.js.map +0 -1
  387. package/dist/lib/rotate.d.ts +0 -58
  388. package/dist/lib/rotate.d.ts.map +0 -1
  389. package/dist/lib/rotate.js +0 -93
  390. package/dist/lib/rotate.js.map +0 -1
  391. package/dist/lib/routines.d.ts +0 -99
  392. package/dist/lib/routines.d.ts.map +0 -1
  393. package/dist/lib/routines.js +0 -352
  394. package/dist/lib/routines.js.map +0 -1
  395. package/dist/lib/runner.d.ts +0 -26
  396. package/dist/lib/runner.d.ts.map +0 -1
  397. package/dist/lib/runner.js +0 -325
  398. package/dist/lib/runner.js.map +0 -1
  399. package/dist/lib/sandbox.d.ts +0 -26
  400. package/dist/lib/sandbox.d.ts.map +0 -1
  401. package/dist/lib/sandbox.js +0 -218
  402. package/dist/lib/sandbox.js.map +0 -1
  403. package/dist/lib/scheduler.d.ts +0 -26
  404. package/dist/lib/scheduler.d.ts.map +0 -1
  405. package/dist/lib/scheduler.js +0 -77
  406. package/dist/lib/scheduler.js.map +0 -1
  407. package/dist/lib/secrets-bundles.d.ts +0 -38
  408. package/dist/lib/secrets-bundles.d.ts.map +0 -1
  409. package/dist/lib/secrets-bundles.js +0 -176
  410. package/dist/lib/secrets-bundles.js.map +0 -1
  411. package/dist/lib/secrets.d.ts +0 -53
  412. package/dist/lib/secrets.d.ts.map +0 -1
  413. package/dist/lib/secrets.js +0 -140
  414. package/dist/lib/secrets.js.map +0 -1
  415. package/dist/lib/session/__tests__/db.test.d.ts +0 -2
  416. package/dist/lib/session/__tests__/db.test.d.ts.map +0 -1
  417. package/dist/lib/session/__tests__/db.test.js +0 -54
  418. package/dist/lib/session/__tests__/db.test.js.map +0 -1
  419. package/dist/lib/session/__tests__/discover.test.d.ts +0 -2
  420. package/dist/lib/session/__tests__/discover.test.d.ts.map +0 -1
  421. package/dist/lib/session/__tests__/discover.test.js +0 -63
  422. package/dist/lib/session/__tests__/discover.test.js.map +0 -1
  423. package/dist/lib/session/__tests__/prompt.test.d.ts +0 -2
  424. package/dist/lib/session/__tests__/prompt.test.d.ts.map +0 -1
  425. package/dist/lib/session/__tests__/prompt.test.js +0 -44
  426. package/dist/lib/session/__tests__/prompt.test.js.map +0 -1
  427. package/dist/lib/session/__tests__/render.test.d.ts +0 -2
  428. package/dist/lib/session/__tests__/render.test.d.ts.map +0 -1
  429. package/dist/lib/session/__tests__/render.test.js +0 -602
  430. package/dist/lib/session/__tests__/render.test.js.map +0 -1
  431. package/dist/lib/session/active.d.ts +0 -44
  432. package/dist/lib/session/active.d.ts.map +0 -1
  433. package/dist/lib/session/active.js +0 -379
  434. package/dist/lib/session/active.js.map +0 -1
  435. package/dist/lib/session/artifacts.d.ts +0 -15
  436. package/dist/lib/session/artifacts.d.ts.map +0 -1
  437. package/dist/lib/session/artifacts.js +0 -86
  438. package/dist/lib/session/artifacts.js.map +0 -1
  439. package/dist/lib/session/db.d.ts +0 -140
  440. package/dist/lib/session/db.d.ts.map +0 -1
  441. package/dist/lib/session/db.js +0 -599
  442. package/dist/lib/session/db.js.map +0 -1
  443. package/dist/lib/session/discover.d.ts +0 -72
  444. package/dist/lib/session/discover.d.ts.map +0 -1
  445. package/dist/lib/session/discover.js +0 -1315
  446. package/dist/lib/session/discover.js.map +0 -1
  447. package/dist/lib/session/parse.d.ts +0 -34
  448. package/dist/lib/session/parse.d.ts.map +0 -1
  449. package/dist/lib/session/parse.js +0 -663
  450. package/dist/lib/session/parse.js.map +0 -1
  451. package/dist/lib/session/prompt.d.ts +0 -13
  452. package/dist/lib/session/prompt.d.ts.map +0 -1
  453. package/dist/lib/session/prompt.js +0 -79
  454. package/dist/lib/session/prompt.js.map +0 -1
  455. package/dist/lib/session/prompt.test.d.ts +0 -2
  456. package/dist/lib/session/prompt.test.d.ts.map +0 -1
  457. package/dist/lib/session/prompt.test.js +0 -57
  458. package/dist/lib/session/prompt.test.js.map +0 -1
  459. package/dist/lib/session/render.d.ts +0 -103
  460. package/dist/lib/session/render.d.ts.map +0 -1
  461. package/dist/lib/session/render.js +0 -798
  462. package/dist/lib/session/render.js.map +0 -1
  463. package/dist/lib/session/team-filter.d.ts +0 -35
  464. package/dist/lib/session/team-filter.d.ts.map +0 -1
  465. package/dist/lib/session/team-filter.js +0 -75
  466. package/dist/lib/session/team-filter.js.map +0 -1
  467. package/dist/lib/session/team-filter.test.d.ts +0 -2
  468. package/dist/lib/session/team-filter.test.d.ts.map +0 -1
  469. package/dist/lib/session/team-filter.test.js +0 -157
  470. package/dist/lib/session/team-filter.test.js.map +0 -1
  471. package/dist/lib/session/types.d.ts +0 -84
  472. package/dist/lib/session/types.d.ts.map +0 -1
  473. package/dist/lib/session/types.js +0 -11
  474. package/dist/lib/session/types.js.map +0 -1
  475. package/dist/lib/shims.d.ts +0 -272
  476. package/dist/lib/shims.d.ts.map +0 -1
  477. package/dist/lib/shims.js +0 -1322
  478. package/dist/lib/shims.js.map +0 -1
  479. package/dist/lib/skills.d.ts +0 -142
  480. package/dist/lib/skills.d.ts.map +0 -1
  481. package/dist/lib/skills.js +0 -791
  482. package/dist/lib/skills.js.map +0 -1
  483. package/dist/lib/state.d.ts +0 -87
  484. package/dist/lib/state.d.ts.map +0 -1
  485. package/dist/lib/state.js +0 -333
  486. package/dist/lib/state.js.map +0 -1
  487. package/dist/lib/subagents.d.ts +0 -84
  488. package/dist/lib/subagents.d.ts.map +0 -1
  489. package/dist/lib/subagents.js +0 -410
  490. package/dist/lib/subagents.js.map +0 -1
  491. package/dist/lib/teams/__tests__/oracle.test.d.ts +0 -2
  492. package/dist/lib/teams/__tests__/oracle.test.d.ts.map +0 -1
  493. package/dist/lib/teams/__tests__/oracle.test.js +0 -89
  494. package/dist/lib/teams/__tests__/oracle.test.js.map +0 -1
  495. package/dist/lib/teams/__tests__/supervisor.test.d.ts +0 -2
  496. package/dist/lib/teams/__tests__/supervisor.test.d.ts.map +0 -1
  497. package/dist/lib/teams/__tests__/supervisor.test.js +0 -179
  498. package/dist/lib/teams/__tests__/supervisor.test.js.map +0 -1
  499. package/dist/lib/teams/agents.d.ts +0 -247
  500. package/dist/lib/teams/agents.d.ts.map +0 -1
  501. package/dist/lib/teams/agents.js +0 -1244
  502. package/dist/lib/teams/agents.js.map +0 -1
  503. package/dist/lib/teams/api.d.ts +0 -91
  504. package/dist/lib/teams/api.d.ts.map +0 -1
  505. package/dist/lib/teams/api.js +0 -239
  506. package/dist/lib/teams/api.js.map +0 -1
  507. package/dist/lib/teams/cloud.d.ts +0 -11
  508. package/dist/lib/teams/cloud.d.ts.map +0 -1
  509. package/dist/lib/teams/cloud.js +0 -169
  510. package/dist/lib/teams/cloud.js.map +0 -1
  511. package/dist/lib/teams/debug.d.ts +0 -8
  512. package/dist/lib/teams/debug.d.ts.map +0 -1
  513. package/dist/lib/teams/debug.js +0 -12
  514. package/dist/lib/teams/debug.js.map +0 -1
  515. package/dist/lib/teams/file_ops.d.ts +0 -13
  516. package/dist/lib/teams/file_ops.d.ts.map +0 -1
  517. package/dist/lib/teams/file_ops.js +0 -66
  518. package/dist/lib/teams/file_ops.js.map +0 -1
  519. package/dist/lib/teams/index.d.ts +0 -16
  520. package/dist/lib/teams/index.d.ts.map +0 -1
  521. package/dist/lib/teams/index.js +0 -15
  522. package/dist/lib/teams/index.js.map +0 -1
  523. package/dist/lib/teams/oracle.d.ts +0 -20
  524. package/dist/lib/teams/oracle.d.ts.map +0 -1
  525. package/dist/lib/teams/oracle.js +0 -59
  526. package/dist/lib/teams/oracle.js.map +0 -1
  527. package/dist/lib/teams/parsers.d.ts +0 -9
  528. package/dist/lib/teams/parsers.d.ts.map +0 -1
  529. package/dist/lib/teams/parsers.js +0 -837
  530. package/dist/lib/teams/parsers.js.map +0 -1
  531. package/dist/lib/teams/persistence.d.ts +0 -43
  532. package/dist/lib/teams/persistence.d.ts.map +0 -1
  533. package/dist/lib/teams/persistence.js +0 -299
  534. package/dist/lib/teams/persistence.js.map +0 -1
  535. package/dist/lib/teams/ralph.d.ts +0 -8
  536. package/dist/lib/teams/ralph.d.ts.map +0 -1
  537. package/dist/lib/teams/ralph.js +0 -59
  538. package/dist/lib/teams/ralph.js.map +0 -1
  539. package/dist/lib/teams/registry.d.ts +0 -18
  540. package/dist/lib/teams/registry.d.ts.map +0 -1
  541. package/dist/lib/teams/registry.js +0 -68
  542. package/dist/lib/teams/registry.js.map +0 -1
  543. package/dist/lib/teams/summarizer.d.ts +0 -73
  544. package/dist/lib/teams/summarizer.d.ts.map +0 -1
  545. package/dist/lib/teams/summarizer.js +0 -780
  546. package/dist/lib/teams/summarizer.js.map +0 -1
  547. package/dist/lib/teams/supervisor.d.ts +0 -49
  548. package/dist/lib/teams/supervisor.d.ts.map +0 -1
  549. package/dist/lib/teams/supervisor.js +0 -74
  550. package/dist/lib/teams/supervisor.js.map +0 -1
  551. package/dist/lib/template.d.ts +0 -27
  552. package/dist/lib/template.d.ts.map +0 -1
  553. package/dist/lib/template.js +0 -60
  554. package/dist/lib/template.js.map +0 -1
  555. package/dist/lib/types.d.ts +0 -331
  556. package/dist/lib/types.d.ts.map +0 -1
  557. package/dist/lib/types.js +0 -29
  558. package/dist/lib/types.js.map +0 -1
  559. package/dist/lib/usage.d.ts +0 -105
  560. package/dist/lib/usage.d.ts.map +0 -1
  561. package/dist/lib/usage.js +0 -686
  562. package/dist/lib/usage.js.map +0 -1
  563. package/dist/lib/versions.d.ts +0 -253
  564. package/dist/lib/versions.d.ts.map +0 -1
  565. package/dist/lib/versions.js +0 -1796
  566. package/dist/lib/versions.js.map +0 -1
  567. package/scripts/rebuild-sqlite.sh +0 -46
package/dist/lib/shims.js DELETED
@@ -1,1322 +0,0 @@
1
- /**
2
- * Shim generation and config symlink management for agent version switching.
3
- *
4
- * Shims are small shell scripts placed in ~/.agents/shims/ that resolve the
5
- * active agent version (project-level or user-default), then exec the real
6
- * binary. Config isolation is achieved by symlinking ~/.{agent} into the
7
- * per-version home directory. This module also handles versioned aliases
8
- * (e.g., claude@2.0.65), PATH setup, conflict detection during migration,
9
- * and resource diffing between versions.
10
- */
11
- import * as fs from 'fs';
12
- import * as path from 'path';
13
- import * as os from 'os';
14
- import { confirm, select } from '@inquirer/prompts';
15
- import { getShimsDir, getVersionsDir, getBackupsDir, ensureAgentsDir } from './state.js';
16
- export { getShimsDir };
17
- import { AGENTS } from './agents.js';
18
- /**
19
- * Files and directories to always skip during conflict detection and migration.
20
- * These are never user config that should be migrated.
21
- */
22
- const MIGRATION_IGNORE_LIST = new Set([
23
- 'node_modules',
24
- '.git',
25
- 'bun.lock',
26
- 'bun.lockb',
27
- 'package-lock.json',
28
- 'yarn.lock',
29
- 'pnpm-lock.yaml',
30
- '.DS_Store',
31
- 'Thumbs.db',
32
- ]);
33
- /**
34
- * Check if a file/directory should be ignored during migration.
35
- */
36
- function shouldIgnore(name) {
37
- if (MIGRATION_IGNORE_LIST.has(name))
38
- return true;
39
- if (name.endsWith('.backup'))
40
- return true;
41
- return false;
42
- }
43
- /**
44
- * Detect conflicting files between source and destination directories.
45
- * Returns list of filenames that exist in both locations (excluding symlinks in dest).
46
- */
47
- export function detectConflicts(src, dest, prefix = '') {
48
- const conflicts = [];
49
- if (!fs.existsSync(src) || !fs.existsSync(dest)) {
50
- return conflicts;
51
- }
52
- // Skip if dest is a symlink (managed resources)
53
- try {
54
- const destStat = fs.lstatSync(dest);
55
- if (destStat.isSymbolicLink()) {
56
- return conflicts;
57
- }
58
- }
59
- catch {
60
- /* dest not accessible, no conflicts to report */
61
- return conflicts;
62
- }
63
- const entries = fs.readdirSync(src, { withFileTypes: true });
64
- for (const entry of entries) {
65
- // Skip files/directories that should never be migrated
66
- if (shouldIgnore(entry.name)) {
67
- continue;
68
- }
69
- const srcPath = path.join(src, entry.name);
70
- const destPath = path.join(dest, entry.name);
71
- const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
72
- // Skip if dest entry is a symlink (managed resource)
73
- try {
74
- const entryDestStat = fs.lstatSync(destPath);
75
- if (entryDestStat.isSymbolicLink()) {
76
- continue;
77
- }
78
- if (entry.isDirectory()) {
79
- // Recurse into subdirectories
80
- conflicts.push(...detectConflicts(srcPath, destPath, relativePath));
81
- }
82
- else {
83
- // File exists in both - it's a conflict
84
- conflicts.push(relativePath);
85
- }
86
- }
87
- catch {
88
- // dest entry doesn't exist, not a conflict
89
- }
90
- }
91
- return conflicts;
92
- }
93
- /**
94
- * Prompt user for conflict resolution strategy.
95
- */
96
- export async function promptConflictStrategy(conflictInfos) {
97
- const totalConflicts = conflictInfos.reduce((sum, info) => sum + info.conflicts.length, 0);
98
- if (totalConflicts === 0) {
99
- return null; // No conflicts, no prompt needed
100
- }
101
- // Show what has conflicts with clear paths
102
- console.log('\nFile conflicts detected:');
103
- for (const info of conflictInfos) {
104
- const agentConfig = AGENTS[info.agent];
105
- const configDir = agentConfig.configDir; // e.g., ".opencode"
106
- console.log(` ${info.conflicts.length} file(s) conflict between:`);
107
- console.log(` ~/${configDir}/ (your config)`);
108
- console.log(` ${agentConfig.name}@${info.version} (managed version)`);
109
- }
110
- console.log();
111
- // Build choice labels with agent info for clarity
112
- const firstInfo = conflictInfos[0];
113
- const firstAgent = AGENTS[firstInfo.agent];
114
- const versionLabel = conflictInfos.length === 1
115
- ? `${firstAgent.name}@${firstInfo.version}`
116
- : 'version';
117
- const strategy = await select({
118
- message: 'Which files should be kept?',
119
- choices: [
120
- {
121
- value: 'keep-dest',
122
- name: `Keep ${versionLabel} files (recommended)`,
123
- },
124
- {
125
- value: 'overwrite',
126
- name: conflictInfos.length === 1
127
- ? `Keep ~/${firstAgent.configDir}/ files`
128
- : 'Keep my config files',
129
- },
130
- {
131
- value: 'ask-per-file',
132
- name: `Decide per file (${totalConflicts} file${totalConflicts === 1 ? '' : 's'})`,
133
- },
134
- ],
135
- default: 'keep-dest',
136
- });
137
- return strategy;
138
- }
139
- /**
140
- * Generate the shim script content for an agent.
141
- *
142
- * The shim resolves the version in order:
143
- * 1. agents.yaml in project root (walk up from $PWD, skip ~/.agents/agents.yaml)
144
- * 2. ~/.agents/agents.yaml default
145
- *
146
- * If version is specified but not installed, auto-installs it.
147
- *
148
- * Config isolation is handled via symlinks:
149
- * ~/.{agent} -> ~/.agents/versions/{agent}/{version}/home/.{agent}/
150
- */
151
- /**
152
- * Current shim schema version. Bump whenever `generateShimScript` changes
153
- * in a way that requires existing on-disk shims to be regenerated (new
154
- * flags, fixed argument parsing, new hooks, etc.). `isShimCurrent` reads
155
- * this marker out of existing shims to decide whether to regenerate.
156
- *
157
- * History:
158
- * v1 — initial shim (implicit, no marker).
159
- * v2 — `--version=...` form in sync/refresh-memory calls; refresh-memory
160
- * shim hook for non-@-capable agents.
161
- * v3 — sync/refresh-memory flag renamed `--version` → `--agent-version`
162
- * so it no longer collides with commander's top-level `--version`.
163
- * v4 — project version marker changed from `.agents-version` to a
164
- * root-level `agents.yaml`; shim now skips ~/.agents/agents.yaml
165
- * when walking up for a project marker.
166
- * v5 — emit CODEX_HOME for codex shims so the versioned config (permissions,
167
- * sandbox_mode, rules/agents-deny.rules) is actually read by the codex
168
- * binary instead of $HOME/.codex.
169
- */
170
- export const SHIM_SCHEMA_VERSION = 5;
171
- /** Internal marker string used to embed the schema version in shim scripts. */
172
- const SHIM_VERSION_MARKER = 'agents-shim-version:';
173
- /**
174
- * Generate the full bash shim script for the given agent. The returned string
175
- * is written to ~/.agents/shims/{cliCommand} and made executable.
176
- */
177
- export function generateShimScript(agent) {
178
- const agentConfig = AGENTS[agent];
179
- const cliCommand = agentConfig.cliCommand;
180
- const configDirName = `.${agent}`;
181
- const managedEnv = agent === 'claude'
182
- ? `
183
- # Claude stores OAuth credentials in the macOS keychain. Scope them to the
184
- # selected version's config directory so switching versions also switches the
185
- # live Claude account.
186
- export CLAUDE_CONFIG_DIR="$VERSION_DIR/home/${configDirName}"
187
- `
188
- : agent === 'codex'
189
- ? `
190
- # Codex reads its config (approval_policy, sandbox_mode, MCP servers, rules)
191
- # from CODEX_HOME. Point it at the versioned home so permissions/rules
192
- # written by agents-cli actually take effect.
193
- export CODEX_HOME="$VERSION_DIR/home/${configDirName}"
194
- `
195
- : '';
196
- // Agents that don't natively resolve @-imports in their memory file need
197
- // agents-cli to recompile when the user edits a rule/preset file. The
198
- // check is fast (sha256 of ~8 small files) and skips the recompile when
199
- // sources haven't changed.
200
- const refreshMemoryCall = !agentConfig.capabilities.memoryImports
201
- ? `
202
- # Recompile memory if any rule/preset source has changed since last sync.
203
- # Fast-path check (~10-20ms) when nothing changed; full recompile only on
204
- # actual diff. Non-blocking failure — if the refresh errors, we still launch.
205
- agents refresh-memory --agent "$AGENT" --agent-version "$VERSION" --quiet 2>/dev/null || true
206
- `
207
- : '';
208
- return `#!/bin/bash
209
- # Auto-generated by agents-cli - do not edit
210
- # Shim for ${agentConfig.name}
211
- # ${SHIM_VERSION_MARKER} ${SHIM_SCHEMA_VERSION}
212
-
213
- AGENTS_DIR="$HOME/.agents"
214
- AGENT="${agent}"
215
- CLI_COMMAND="${cliCommand}"
216
-
217
- # Find project agents.yaml walking up from cwd (skip ~/.agents/agents.yaml)
218
- find_project_version() {
219
- local dir="$PWD"
220
- local user_agents_yaml="$HOME/.agents/agents.yaml"
221
- while [ "$dir" != "/" ]; do
222
- local candidate="$dir/agents.yaml"
223
- if [ -f "$candidate" ] && [ "$candidate" != "$user_agents_yaml" ]; then
224
- # Parse agents: section — same shape as resolve_default_version()
225
- local version
226
- version=$(awk -v agent="$AGENT" '
227
- /^agents:/ { in_agents=1; next }
228
- in_agents && /^[^ ]/ { in_agents=0 }
229
- in_agents && $0 ~ "^ " agent ":" { gsub(/.*:[[:space:]]*["'"'"']?|["'"'"']?[[:space:]]*$/, ""); print; exit }
230
- ' "$candidate")
231
- if [ -n "$version" ]; then
232
- echo "$version"
233
- return 0
234
- fi
235
- fi
236
- dir=$(dirname "$dir")
237
- done
238
- return 1
239
- }
240
-
241
- # Resolve version from agents.yaml (user default)
242
- resolve_default_version() {
243
- local meta="$AGENTS_DIR/agents.yaml"
244
- if [ -f "$meta" ]; then
245
- awk -v agent="$AGENT" '
246
- /^agents:/ { in_agents=1; next }
247
- in_agents && /^[^ ]/ { in_agents=0 }
248
- in_agents && $0 ~ "^ " agent ":" { gsub(/.*:[[:space:]]*["'"'"']?|["'"'"']?[[:space:]]*$/, ""); print; exit }
249
- ' "$meta"
250
- fi
251
- }
252
-
253
- # Find project-scoped .agents directory (stop at agents.yaml or .git)
254
- find_project_agents_dir() {
255
- local dir="$PWD"
256
- while [ "$dir" != "/" ]; do
257
- if [ -d "$dir/.agents" ]; then
258
- echo "$dir/.agents"
259
- return 0
260
- fi
261
- if [ -f "$dir/agents.yaml" ] || [ -d "$dir/.git" ] || [ -f "$dir/.git" ]; then
262
- break
263
- fi
264
- dir=$(dirname "$dir")
265
- done
266
- return 1
267
- }
268
-
269
- # Try project version first, then global default
270
- VERSION=$(find_project_version)
271
- VERSION_SOURCE="project"
272
- if [ -z "$VERSION" ]; then
273
- VERSION=$(resolve_default_version)
274
- VERSION_SOURCE="default"
275
- fi
276
-
277
- if [ -z "$VERSION" ]; then
278
- echo "agents: no version of $AGENT configured" >&2
279
- echo "Run: agents add $AGENT@<version>" >&2
280
- exit 1
281
- fi
282
-
283
- VERSION_DIR="$AGENTS_DIR/versions/$AGENT/$VERSION"
284
- BINARY="$VERSION_DIR/node_modules/.bin/$CLI_COMMAND"
285
-
286
- # Auto-install if not present
287
- if [ ! -x "$BINARY" ]; then
288
- if [ "$VERSION_SOURCE" = "project" ]; then
289
- echo "agents: $AGENT@$VERSION required by agents.yaml but not installed" >&2
290
-
291
- # Spinner animation
292
- spin() {
293
- local pid=$1
294
- local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
295
- local i=0
296
- while kill -0 "$pid" 2>/dev/null; do
297
- printf "\\r %s Installing $AGENT@$VERSION..." "\${chars:i++%\${#chars}:1}" >&2
298
- sleep 0.1
299
- done
300
- printf "\\r" >&2
301
- }
302
-
303
- # Run install in background with spinner
304
- agents add "$AGENT@$VERSION" --yes >/dev/null 2>&1 &
305
- install_pid=$!
306
- spin $install_pid
307
- wait $install_pid
308
- install_status=$?
309
-
310
- if [ $install_status -eq 0 ]; then
311
- echo " ✔ Installed $AGENT@$VERSION" >&2
312
- else
313
- echo " ✗ Failed to install $AGENT@$VERSION" >&2
314
- exit 1
315
- fi
316
- else
317
- echo "agents: $AGENT@$VERSION not installed" >&2
318
- echo "Run: agents add $AGENT@$VERSION" >&2
319
- exit 1
320
- fi
321
- fi
322
-
323
- # Sync project-scoped resources into version home if a project .agents/ is present
324
- PROJECT_AGENTS_DIR=$(find_project_agents_dir)
325
- if [ -n "$PROJECT_AGENTS_DIR" ]; then
326
- agents sync --agent "$AGENT" --agent-version "$VERSION" --project-dir "$PROJECT_AGENTS_DIR" --quiet >/dev/null 2>&1
327
- fi
328
- ${refreshMemoryCall}${managedEnv}
329
-
330
- exec "$BINARY" "$@"
331
- `;
332
- }
333
- /**
334
- * Create a shim for an agent.
335
- */
336
- export function createShim(agent) {
337
- ensureAgentsDir();
338
- const shimsDir = getShimsDir();
339
- const agentConfig = AGENTS[agent];
340
- const shimPath = path.join(shimsDir, agentConfig.cliCommand);
341
- const script = generateShimScript(agent);
342
- fs.writeFileSync(shimPath, script, { mode: 0o755 });
343
- return shimPath;
344
- }
345
- /**
346
- * Remove the shim for an agent.
347
- */
348
- export function removeShim(agent) {
349
- const shimsDir = getShimsDir();
350
- const agentConfig = AGENTS[agent];
351
- const shimPath = path.join(shimsDir, agentConfig.cliCommand);
352
- if (fs.existsSync(shimPath)) {
353
- fs.unlinkSync(shimPath);
354
- return true;
355
- }
356
- return false;
357
- }
358
- /**
359
- * Current versioned-alias schema. Bump whenever `generateVersionedAliasScript`
360
- * changes in a way that requires existing on-disk aliases to be regenerated.
361
- *
362
- * History:
363
- * v1 — implicit (no marker); no CLAUDE_CONFIG_DIR export, so direct
364
- * `claude@X` invocations leaked into ~/.claude (the default version's
365
- * symlinked home) and `agents view` never saw the login.
366
- * v2 — emit CLAUDE_CONFIG_DIR for claude aliases so each version has its
367
- * own isolated config/OAuth slot; stamp a version marker so stale
368
- * aliases can be detected and regenerated.
369
- * v3 — emit CODEX_HOME for codex aliases so direct `codex@X` invocations
370
- * read the versioned permissions/rules instead of $HOME/.codex.
371
- */
372
- export const VERSIONED_ALIAS_SCHEMA_VERSION = 3;
373
- /** Internal marker string used to embed the schema version in versioned alias scripts. */
374
- const VERSIONED_ALIAS_VERSION_MARKER = 'agents-versioned-alias-version:';
375
- /**
376
- * Generate a versioned alias script that directly execs a specific version.
377
- * e.g., claude@2.0.65 -> directly runs that version's binary
378
- */
379
- export function generateVersionedAliasScript(agent, version) {
380
- const agentConfig = AGENTS[agent];
381
- const configDirName = `.${agent}`;
382
- const managedEnv = agent === 'claude'
383
- ? `
384
- # Claude stores OAuth credentials in the macOS keychain. Scope them to this
385
- # version's config directory so direct aliases also switch the live account.
386
- export CLAUDE_CONFIG_DIR="$HOME/.agents/versions/${agent}/${version}/home/${configDirName}"
387
- `
388
- : agent === 'codex'
389
- ? `
390
- # Codex reads its config (approval_policy, sandbox_mode, MCP servers, rules)
391
- # from CODEX_HOME. Point direct aliases at the versioned home so permissions
392
- # and rules written by agents-cli actually take effect.
393
- export CODEX_HOME="$HOME/.agents/versions/${agent}/${version}/home/${configDirName}"
394
- `
395
- : '';
396
- return `#!/bin/bash
397
- # Auto-generated by agents-cli - do not edit
398
- # ${VERSIONED_ALIAS_VERSION_MARKER} ${VERSIONED_ALIAS_SCHEMA_VERSION}
399
- # Direct alias for ${agentConfig.name}@${version}
400
-
401
- BINARY="$HOME/.agents/versions/${agent}/${version}/node_modules/.bin/${agentConfig.cliCommand}"
402
-
403
- if [ ! -x "$BINARY" ]; then
404
- echo "agents: ${agent}@${version} not installed" >&2
405
- exit 1
406
- fi
407
- ${managedEnv}
408
-
409
- exec "$BINARY" "$@"
410
- `;
411
- }
412
- /**
413
- * Read the schema version of an on-disk versioned alias. Returns null if the
414
- * alias doesn't exist or is a pre-v2 alias (no marker — treated as stale).
415
- */
416
- export function readVersionedAliasSchemaVersion(agent, version) {
417
- const aliasPath = getVersionedAliasPath(agent, version);
418
- if (!fs.existsSync(aliasPath))
419
- return null;
420
- try {
421
- const content = fs.readFileSync(aliasPath, 'utf8');
422
- const header = content.split('\n', 10).join('\n');
423
- const match = header.match(new RegExp(VERSIONED_ALIAS_VERSION_MARKER + '\\s*(\\d+)'));
424
- if (!match)
425
- return null;
426
- return Number(match[1]);
427
- }
428
- catch {
429
- return null;
430
- }
431
- }
432
- /**
433
- * True if the on-disk versioned alias matches the current schema version.
434
- */
435
- export function isVersionedAliasCurrent(agent, version) {
436
- return readVersionedAliasSchemaVersion(agent, version) === VERSIONED_ALIAS_SCHEMA_VERSION;
437
- }
438
- /**
439
- * Regenerate a versioned alias if missing or stale. Mirrors ensureShimCurrent
440
- * for the main shim — callers can surface a one-line notice when something
441
- * was upgraded.
442
- */
443
- export function ensureVersionedAliasCurrent(agent, version) {
444
- const aliasPath = getVersionedAliasPath(agent, version);
445
- if (!fs.existsSync(aliasPath)) {
446
- createVersionedAlias(agent, version);
447
- return 'created';
448
- }
449
- if (!isVersionedAliasCurrent(agent, version)) {
450
- createVersionedAlias(agent, version);
451
- return 'updated';
452
- }
453
- return 'current';
454
- }
455
- /**
456
- * Get the filesystem path for a versioned alias script.
457
- */
458
- export function getVersionedAliasPath(agent, version) {
459
- return path.join(getShimsDir(), `${AGENTS[agent].cliCommand}@${version}`);
460
- }
461
- /**
462
- * Create a versioned alias for a specific agent version.
463
- * e.g., claude@2.0.65
464
- */
465
- export function createVersionedAlias(agent, version) {
466
- ensureAgentsDir();
467
- const shimsDir = getShimsDir();
468
- const agentConfig = AGENTS[agent];
469
- const aliasPath = path.join(shimsDir, `${agentConfig.cliCommand}@${version}`);
470
- const script = generateVersionedAliasScript(agent, version);
471
- fs.writeFileSync(aliasPath, script, { mode: 0o755 });
472
- return aliasPath;
473
- }
474
- /**
475
- * Remove a versioned alias for a specific agent version.
476
- */
477
- export function removeVersionedAlias(agent, version) {
478
- const shimsDir = getShimsDir();
479
- const agentConfig = AGENTS[agent];
480
- const aliasPath = path.join(shimsDir, `${agentConfig.cliCommand}@${version}`);
481
- if (fs.existsSync(aliasPath)) {
482
- fs.unlinkSync(aliasPath);
483
- return true;
484
- }
485
- return false;
486
- }
487
- /**
488
- * Check if a versioned alias exists.
489
- */
490
- export function versionedAliasExists(agent, version) {
491
- const shimsDir = getShimsDir();
492
- const agentConfig = AGENTS[agent];
493
- const aliasPath = path.join(shimsDir, `${agentConfig.cliCommand}@${version}`);
494
- return fs.existsSync(aliasPath);
495
- }
496
- /**
497
- * Get the path to the agent's config directory in HOME.
498
- * e.g., ~/.claude for claude, ~/.codex for codex
499
- */
500
- function getAgentConfigPath(agent) {
501
- const agentConfig = AGENTS[agent];
502
- const home = process.env.AGENTS_REAL_HOME || os.homedir();
503
- return agentConfig.configDir.replace(os.homedir(), home);
504
- }
505
- /**
506
- * Get the path to the version's config directory.
507
- * e.g., ~/.agents/versions/claude/2.0.65/home/.claude/
508
- */
509
- function getVersionConfigPath(agent, version) {
510
- const agentConfig = AGENTS[agent];
511
- const versionsDir = getVersionsDir();
512
- const configDirName = `.${agent}`; // .claude, .codex, etc.
513
- return path.join(versionsDir, agent, version, 'home', configDirName);
514
- }
515
- /**
516
- * Detect conflicts that would occur when switching config symlink for an agent/version.
517
- * This allows collecting conflicts upfront before prompting for a strategy.
518
- *
519
- * Returns null if no migration is needed (already symlink or doesn't exist),
520
- * or ConflictInfo with the list of conflicting files.
521
- */
522
- export function detectMigrationConflicts(agent, version) {
523
- const configPath = getAgentConfigPath(agent);
524
- const versionConfigPath = getVersionConfigPath(agent, version);
525
- try {
526
- const stat = fs.lstatSync(configPath);
527
- if (stat.isSymbolicLink()) {
528
- // Already a symlink - no migration needed, no conflicts
529
- return null;
530
- }
531
- else if (stat.isDirectory()) {
532
- // Real directory exists - would need migration
533
- // Detect conflicts between user's current config and version home
534
- const conflicts = detectConflicts(configPath, versionConfigPath);
535
- return {
536
- agent,
537
- version,
538
- conflicts,
539
- };
540
- }
541
- // Not a directory or symlink - unusual, no conflicts to report
542
- return null;
543
- }
544
- catch (err) {
545
- if (err.code === 'ENOENT') {
546
- // Config path doesn't exist - no migration needed
547
- return null;
548
- }
549
- return null;
550
- }
551
- }
552
- /**
553
- * Switch the agent's config symlink to point to a specific version.
554
- * e.g., ~/.claude -> ~/.agents/versions/claude/2.0.65/home/.claude/
555
- *
556
- * If a real directory exists at the config path, it will be backed up
557
- * to ~/.agents/backups/{agent}/{timestamp}/ and replaced with a symlink.
558
- *
559
- * @param agent - The agent ID
560
- * @param version - The version to switch to
561
- *
562
- * Returns: { success: boolean, backupPath?: string, error?: string }
563
- */
564
- export async function switchConfigSymlink(agent, version) {
565
- const configPath = getAgentConfigPath(agent);
566
- const versionConfigPath = getVersionConfigPath(agent, version);
567
- // Ensure version config directory exists
568
- if (!fs.existsSync(versionConfigPath)) {
569
- fs.mkdirSync(versionConfigPath, { recursive: true });
570
- }
571
- try {
572
- const stat = fs.lstatSync(configPath);
573
- if (stat.isSymbolicLink()) {
574
- // Already a symlink - check if it points to the correct target
575
- const currentTarget = fs.readlinkSync(configPath);
576
- const resolvedCurrent = path.resolve(path.dirname(configPath), currentTarget);
577
- const resolvedTarget = path.resolve(versionConfigPath);
578
- if (resolvedCurrent === resolvedTarget) {
579
- // Already pointing to correct target, no-op
580
- return { success: true };
581
- }
582
- // Different target - update it
583
- fs.unlinkSync(configPath);
584
- fs.symlinkSync(versionConfigPath, configPath);
585
- return { success: true };
586
- }
587
- else if (stat.isDirectory()) {
588
- // Real directory exists - backup and replace with symlink
589
- const timestamp = Date.now();
590
- // Move to backup location
591
- const backupsDir = getBackupsDir();
592
- const agentBackupDir = path.join(backupsDir, agent);
593
- const finalBackupPath = path.join(agentBackupDir, String(timestamp));
594
- fs.mkdirSync(agentBackupDir, { recursive: true });
595
- fs.renameSync(configPath, finalBackupPath);
596
- // Create symlink
597
- fs.symlinkSync(versionConfigPath, configPath);
598
- return { success: true, backupPath: finalBackupPath };
599
- }
600
- else {
601
- return { success: false, error: `${configPath} exists but is not a directory or symlink` };
602
- }
603
- }
604
- catch (err) {
605
- if (err.code === 'ENOENT') {
606
- // Config path doesn't exist - create symlink
607
- fs.symlinkSync(versionConfigPath, configPath);
608
- return { success: true };
609
- }
610
- return { success: false, error: err.message };
611
- }
612
- }
613
- /**
614
- * Switch home-level files (outside the config dir) to per-version symlinks.
615
- * e.g., ~/.claude.json -> ~/.agents/versions/claude/2.0.65/home/.claude.json
616
- *
617
- * Uses atomic rename to avoid data loss if another session is running.
618
- * On first migration (real file -> symlink), merges global auth into
619
- * ALL installed versions so they inherit the current account.
620
- */
621
- export function switchHomeFileSymlinks(agent, version) {
622
- const agentConfig = AGENTS[agent];
623
- const homeFiles = agentConfig.homeFiles;
624
- if (!homeFiles || homeFiles.length === 0)
625
- return { switched: [], errors: [] };
626
- const home = process.env.AGENTS_REAL_HOME || os.homedir();
627
- const versionsDir = getVersionsDir();
628
- const switched = [];
629
- const errors = [];
630
- // For Claude, Claude's binary reads CLAUDE_CONFIG_DIR/.claude.json (INSIDE
631
- // the per-version .claude dir) — not the home-level file this function
632
- // manages. Reconcile all installed Claude versions so INSIDE is a symlink
633
- // to OUTSIDE, making OUTSIDE the single source of truth.
634
- if (agent === 'claude') {
635
- const reconcile = ensureAllClaudeInsideSymlinks();
636
- for (const e of reconcile.errors)
637
- errors.push(e);
638
- }
639
- for (const fileName of homeFiles) {
640
- const globalPath = path.join(home, fileName);
641
- const versionFilePath = path.join(versionsDir, agent, version, 'home', fileName);
642
- try {
643
- // Ensure version home dir exists
644
- const versionFileDir = path.dirname(versionFilePath);
645
- if (!fs.existsSync(versionFileDir)) {
646
- fs.mkdirSync(versionFileDir, { recursive: true });
647
- }
648
- let stat = null;
649
- try {
650
- stat = fs.lstatSync(globalPath);
651
- }
652
- catch {
653
- // File doesn't exist at global path — just create symlink
654
- if (!fs.existsSync(versionFilePath)) {
655
- fs.writeFileSync(versionFilePath, '{}');
656
- }
657
- fs.symlinkSync(versionFilePath, globalPath);
658
- switched.push(fileName);
659
- continue;
660
- }
661
- if (stat.isSymbolicLink()) {
662
- // Already a symlink — retarget atomically
663
- const currentTarget = fs.readlinkSync(globalPath);
664
- const resolvedCurrent = path.resolve(path.dirname(globalPath), currentTarget);
665
- const resolvedTarget = path.resolve(versionFilePath);
666
- if (resolvedCurrent === resolvedTarget) {
667
- switched.push(fileName);
668
- continue; // Already correct
669
- }
670
- // Atomic retarget: create temp symlink, rename over existing
671
- if (!fs.existsSync(versionFilePath)) {
672
- fs.writeFileSync(versionFilePath, '{}');
673
- }
674
- const tmpPath = `${globalPath}.agents-tmp-${process.pid}`;
675
- fs.symlinkSync(versionFilePath, tmpPath);
676
- fs.renameSync(tmpPath, globalPath);
677
- switched.push(fileName);
678
- }
679
- else if (stat.isFile()) {
680
- // Real file — first-time migration
681
- // Read the global file content
682
- const globalContent = JSON.parse(fs.readFileSync(globalPath, 'utf-8'));
683
- // Merge auth into ALL installed version files for this agent
684
- const agentVersionsDir = path.join(versionsDir, agent);
685
- if (fs.existsSync(agentVersionsDir)) {
686
- for (const ver of fs.readdirSync(agentVersionsDir)) {
687
- const verFilePath = path.join(agentVersionsDir, ver, 'home', fileName);
688
- const verFileDir = path.dirname(verFilePath);
689
- if (!fs.existsSync(verFileDir)) {
690
- fs.mkdirSync(verFileDir, { recursive: true });
691
- }
692
- if (fs.existsSync(verFilePath)) {
693
- // Merge: version-specific fields + global auth fields
694
- try {
695
- const verContent = JSON.parse(fs.readFileSync(verFilePath, 'utf-8'));
696
- const merged = { ...globalContent, ...verContent };
697
- // Ensure auth from global always wins
698
- if (globalContent.oauthAccount) {
699
- merged.oauthAccount = globalContent.oauthAccount;
700
- }
701
- fs.writeFileSync(verFilePath, JSON.stringify(merged, null, 2));
702
- }
703
- catch {
704
- // If version file is invalid JSON, overwrite with global
705
- fs.writeFileSync(verFilePath, JSON.stringify(globalContent, null, 2));
706
- }
707
- }
708
- else {
709
- // No version file — copy global wholesale
710
- fs.writeFileSync(verFilePath, JSON.stringify(globalContent, null, 2));
711
- }
712
- }
713
- }
714
- // Atomic swap: create temp symlink to target version, rename over real file
715
- const tmpPath = `${globalPath}.agents-tmp-${process.pid}`;
716
- fs.symlinkSync(versionFilePath, tmpPath);
717
- fs.renameSync(tmpPath, globalPath);
718
- switched.push(fileName);
719
- }
720
- }
721
- catch (err) {
722
- errors.push(`${fileName}: ${err.message}`);
723
- }
724
- }
725
- return { switched, errors };
726
- }
727
- /**
728
- * Claude reads `.claude.json` at `$CLAUDE_CONFIG_DIR/.claude.json`. Our shim
729
- * points CLAUDE_CONFIG_DIR at `<ver>/home/.claude`, so Claude's real config
730
- * file lives at `<ver>/home/.claude/.claude.json` (INSIDE), while
731
- * `switchHomeFileSymlinks` manages `<ver>/home/.claude.json` (OUTSIDE).
732
- *
733
- * To keep both views consistent we make INSIDE a symlink to OUTSIDE. Claude's
734
- * atomic write (`Uf6`) resolves symlinks before the tmp+rename cycle, so the
735
- * symlink survives across writes and OUTSIDE remains the single source of
736
- * truth that agents-cli's home-file machinery already manages.
737
- *
738
- * This function idempotently reconciles one version:
739
- * - INSIDE missing: create symlink -> `../.claude.json` (create OUTSIDE if needed).
740
- * - INSIDE already symlink to OUTSIDE: no-op.
741
- * - INSIDE is a real file: it's the authoritative auth state (Claude was
742
- * writing to it). Move its content to OUTSIDE (merging with OUTSIDE,
743
- * INSIDE wins for `oauthAccount`), then replace INSIDE with the symlink.
744
- * - Symlink points elsewhere: replace it.
745
- */
746
- export function ensureClaudeInsideSymlink(version) {
747
- const versionsDir = getVersionsDir();
748
- const versionHome = path.join(versionsDir, 'claude', version, 'home');
749
- const outsidePath = path.join(versionHome, '.claude.json');
750
- const insideDir = path.join(versionHome, '.claude');
751
- const insidePath = path.join(insideDir, '.claude.json');
752
- const linkTarget = '../.claude.json'; // relative so version dir can be moved
753
- if (!fs.existsSync(insideDir)) {
754
- fs.mkdirSync(insideDir, { recursive: true });
755
- }
756
- let insideStat = null;
757
- try {
758
- insideStat = fs.lstatSync(insidePath);
759
- }
760
- catch {
761
- /* INSIDE does not exist */
762
- }
763
- if (insideStat?.isSymbolicLink()) {
764
- const currentTarget = fs.readlinkSync(insidePath);
765
- if (currentTarget === linkTarget)
766
- return;
767
- // Wrong target — replace.
768
- if (!fs.existsSync(outsidePath))
769
- fs.writeFileSync(outsidePath, '{}');
770
- fs.unlinkSync(insidePath);
771
- fs.symlinkSync(linkTarget, insidePath);
772
- return;
773
- }
774
- if (insideStat?.isFile()) {
775
- // INSIDE is the authoritative file — Claude has been reading/writing it.
776
- // Merge INSIDE into OUTSIDE, with INSIDE winning on every field, then
777
- // replace INSIDE with a symlink.
778
- let insideContent = {};
779
- try {
780
- insideContent = JSON.parse(fs.readFileSync(insidePath, 'utf-8'));
781
- }
782
- catch {
783
- /* INSIDE corrupt — treat as empty; OUTSIDE preserved as-is */
784
- }
785
- let outsideContent = {};
786
- if (fs.existsSync(outsidePath)) {
787
- try {
788
- outsideContent = JSON.parse(fs.readFileSync(outsidePath, 'utf-8'));
789
- }
790
- catch {
791
- /* OUTSIDE corrupt — drop it */
792
- }
793
- }
794
- const merged = { ...outsideContent, ...insideContent };
795
- fs.writeFileSync(outsidePath, JSON.stringify(merged, null, 2));
796
- fs.unlinkSync(insidePath);
797
- fs.symlinkSync(linkTarget, insidePath);
798
- return;
799
- }
800
- // INSIDE missing — ensure OUTSIDE exists, then create symlink.
801
- if (!fs.existsSync(outsidePath))
802
- fs.writeFileSync(outsidePath, '{}');
803
- fs.symlinkSync(linkTarget, insidePath);
804
- }
805
- /**
806
- * Apply `ensureClaudeInsideSymlink` to every installed Claude version.
807
- * Safe to call repeatedly; per-version calls are idempotent.
808
- */
809
- export function ensureAllClaudeInsideSymlinks() {
810
- const versionsDir = getVersionsDir();
811
- const claudeVersionsDir = path.join(versionsDir, 'claude');
812
- const migrated = [];
813
- const errors = [];
814
- if (!fs.existsSync(claudeVersionsDir))
815
- return { migrated, errors };
816
- for (const entry of fs.readdirSync(claudeVersionsDir, { withFileTypes: true })) {
817
- if (!entry.isDirectory())
818
- continue;
819
- try {
820
- ensureClaudeInsideSymlink(entry.name);
821
- migrated.push(entry.name);
822
- }
823
- catch (err) {
824
- errors.push(`${entry.name}: ${err.message}`);
825
- }
826
- }
827
- return { migrated, errors };
828
- }
829
- /**
830
- * Get the current config symlink target version, if any.
831
- */
832
- export function getConfigSymlinkVersion(agent) {
833
- const configPath = getAgentConfigPath(agent);
834
- try {
835
- const stat = fs.lstatSync(configPath);
836
- if (!stat.isSymbolicLink()) {
837
- return null;
838
- }
839
- const target = fs.readlinkSync(configPath);
840
- // Extract version from path like ~/.agents/versions/claude/2.0.65/home/.claude
841
- const match = target.match(/versions\/[^/]+\/([^/]+)\/home/);
842
- return match ? match[1] : null;
843
- }
844
- catch {
845
- /* config path not accessible or not a symlink */
846
- return null;
847
- }
848
- }
849
- /**
850
- * Copy directory contents with configurable conflict strategy.
851
- * Skips when dest is a symlink (managed resources that shouldn't be overwritten).
852
- *
853
- * @param src - Source directory
854
- * @param dest - Destination directory
855
- * @param strategy - How to handle conflicts: 'keep-dest', 'overwrite', or 'ask-per-file'
856
- * @param context - Agent/version context for prompts (only used when strategy is 'ask-per-file')
857
- */
858
- async function copyDirContents(src, dest, strategy = 'keep-dest', context) {
859
- // If dest is a symlink, skip - these are managed resources (skills, commands, etc.)
860
- // that link to central ~/.agents/ and shouldn't be overwritten with local copies
861
- try {
862
- const destStat = fs.lstatSync(dest);
863
- if (destStat.isSymbolicLink()) {
864
- return; // Skip - don't copy into symlinked directories
865
- }
866
- }
867
- catch {
868
- // dest doesn't exist, that's fine
869
- }
870
- if (!fs.existsSync(dest)) {
871
- fs.mkdirSync(dest, { recursive: true });
872
- }
873
- const entries = fs.readdirSync(src, { withFileTypes: true });
874
- for (const entry of entries) {
875
- // Skip files/directories that should never be migrated
876
- if (shouldIgnore(entry.name)) {
877
- continue;
878
- }
879
- const srcPath = path.join(src, entry.name);
880
- const destPath = path.join(dest, entry.name);
881
- // Skip if dest entry is a symlink (managed resource)
882
- try {
883
- const entryDestStat = fs.lstatSync(destPath);
884
- if (entryDestStat.isSymbolicLink()) {
885
- continue; // Skip - managed resource
886
- }
887
- }
888
- catch {
889
- // dest entry doesn't exist, that's fine
890
- }
891
- if (entry.isDirectory()) {
892
- await copyDirContents(srcPath, destPath, strategy, context);
893
- }
894
- else if (entry.isSymbolicLink()) {
895
- const linkTarget = fs.readlinkSync(srcPath);
896
- if (fs.existsSync(destPath)) {
897
- fs.unlinkSync(destPath);
898
- }
899
- fs.symlinkSync(linkTarget, destPath);
900
- }
901
- else {
902
- // File - check for conflict
903
- if (fs.existsSync(destPath)) {
904
- // Handle based on strategy
905
- if (strategy === 'keep-dest') {
906
- // Keep existing file, skip copying
907
- continue;
908
- }
909
- else if (strategy === 'overwrite') {
910
- // Back up and overwrite
911
- fs.copyFileSync(destPath, `${destPath}.backup`);
912
- }
913
- else if (strategy === 'ask-per-file') {
914
- // Back up dest file
915
- fs.copyFileSync(destPath, `${destPath}.backup`);
916
- // Ask user with context - use clear path-based terminology
917
- const agentConfig = context ? AGENTS[context.agent] : null;
918
- const versionLabel = agentConfig
919
- ? `${agentConfig.name}@${context.version}`
920
- : 'version';
921
- const useMyFile = await confirm({
922
- message: `${entry.name}: Use your config file instead of ${versionLabel}?`,
923
- default: false, // Default to keep version (safer)
924
- });
925
- if (!useMyFile) {
926
- continue; // Keep dest (version file), skip copying src
927
- }
928
- }
929
- }
930
- fs.copyFileSync(srcPath, destPath);
931
- }
932
- }
933
- }
934
- /**
935
- * Check if shim exists for an agent.
936
- */
937
- export function shimExists(agent) {
938
- const shimsDir = getShimsDir();
939
- const agentConfig = AGENTS[agent];
940
- const shimPath = path.join(shimsDir, agentConfig.cliCommand);
941
- return fs.existsSync(shimPath);
942
- }
943
- /**
944
- * Read the schema version embedded in an existing on-disk shim. Returns
945
- * `null` if the shim doesn't exist or has no version marker (pre-v2 shim).
946
- */
947
- export function readShimSchemaVersion(agent) {
948
- if (!shimExists(agent))
949
- return null;
950
- try {
951
- const content = fs.readFileSync(getShimPath(agent), 'utf8');
952
- // Look at the first ~10 lines only — the marker lives in the header.
953
- const header = content.split('\n', 10).join('\n');
954
- const match = header.match(new RegExp(SHIM_VERSION_MARKER + '\\s*(\\d+)'));
955
- if (!match)
956
- return null;
957
- return Number(match[1]);
958
- }
959
- catch {
960
- return null;
961
- }
962
- }
963
- /**
964
- * True if the on-disk shim's schema version matches `SHIM_SCHEMA_VERSION`.
965
- * False means either the shim is missing, is pre-v2 (no marker), or is an
966
- * older version that needs regeneration.
967
- */
968
- export function isShimCurrent(agent) {
969
- const version = readShimSchemaVersion(agent);
970
- return version === SHIM_SCHEMA_VERSION;
971
- }
972
- /**
973
- * Regenerate the shim if it's missing or outdated. Returns a status describing
974
- * what happened — callers can surface a one-line notice to the user ("Updated
975
- * shim for codex") when appropriate.
976
- */
977
- export function ensureShimCurrent(agent) {
978
- if (!shimExists(agent)) {
979
- createShim(agent);
980
- return 'created';
981
- }
982
- if (!isShimCurrent(agent)) {
983
- createShim(agent);
984
- return 'updated';
985
- }
986
- return 'current';
987
- }
988
- /**
989
- * Get the path to the shim for an agent.
990
- */
991
- export function getShimPath(agent) {
992
- const shimsDir = getShimsDir();
993
- const agentConfig = AGENTS[agent];
994
- return path.join(shimsDir, agentConfig.cliCommand);
995
- }
996
- /**
997
- * Return the first executable path that would be launched for this agent when
998
- * resolving against PATH, excluding the managed shim itself.
999
- */
1000
- export function getPathShadowingExecutable(agent) {
1001
- const pathDirs = (process.env.PATH || '').split(path.delimiter).filter(Boolean);
1002
- const shimPath = path.resolve(getShimPath(agent));
1003
- const cliCommand = AGENTS[agent].cliCommand;
1004
- for (const dir of pathDirs) {
1005
- const candidate = path.resolve(dir, cliCommand);
1006
- if (!fs.existsSync(candidate)) {
1007
- continue;
1008
- }
1009
- return candidate === shimPath ? null : candidate;
1010
- }
1011
- return null;
1012
- }
1013
- /**
1014
- * Check if shims directory is in PATH.
1015
- */
1016
- export function isShimsInPath() {
1017
- const shimsDir = getShimsDir();
1018
- const pathDirs = (process.env.PATH || '').split(path.delimiter);
1019
- return pathDirs.some((dir) => path.resolve(dir) === path.resolve(shimsDir));
1020
- }
1021
- /**
1022
- * Get the shell rc file path for the current shell.
1023
- */
1024
- function getShellRcFile() {
1025
- const shell = process.env.SHELL || '/bin/bash';
1026
- const shellName = path.basename(shell);
1027
- let rcFile;
1028
- switch (shellName) {
1029
- case 'zsh':
1030
- rcFile = '.zshrc';
1031
- break;
1032
- case 'fish':
1033
- rcFile = '.config/fish/config.fish';
1034
- break;
1035
- case 'bash':
1036
- default:
1037
- rcFile = '.bashrc';
1038
- break;
1039
- }
1040
- return {
1041
- rcFile,
1042
- rcPath: path.join(os.homedir(), rcFile),
1043
- shell: shellName,
1044
- };
1045
- }
1046
- /**
1047
- * Get shell configuration instructions for adding shims to PATH.
1048
- */
1049
- export function getPathSetupInstructions() {
1050
- const shimsDir = getShimsDir();
1051
- const { rcFile, shell } = getShellRcFile();
1052
- if (shell === 'fish') {
1053
- return `Add to ~/.config/fish/config.fish:
1054
- fish_add_path ${shimsDir}`;
1055
- }
1056
- return `Add to ~/${rcFile} (BEFORE any nvm/node setup):
1057
- export PATH="${shimsDir}:$PATH"
1058
-
1059
- IMPORTANT: Shims must come FIRST in PATH to override global installs.
1060
-
1061
- Then restart your shell or run:
1062
- source ~/${rcFile}`;
1063
- }
1064
- /**
1065
- * Add shims directory to shell PATH configuration.
1066
- * Returns true if added, false if already present or failed.
1067
- */
1068
- export function addShimsToPath() {
1069
- const shimsDir = getShimsDir();
1070
- const { rcFile, rcPath, shell } = getShellRcFile();
1071
- // Read current rc file content
1072
- let content = '';
1073
- try {
1074
- if (fs.existsSync(rcPath)) {
1075
- content = fs.readFileSync(rcPath, 'utf-8');
1076
- }
1077
- }
1078
- catch (err) {
1079
- return { success: false, error: `Could not read ${rcFile}: ${err.message}` };
1080
- }
1081
- // Check if shims path already in file
1082
- if (content.includes(shimsDir) || content.includes('$HOME/.agents/shims')) {
1083
- return { success: true, alreadyPresent: true, rcFile };
1084
- }
1085
- // Generate the export line
1086
- let exportLine;
1087
- if (shell === 'fish') {
1088
- exportLine = `\n# agents-cli: version-managed agent CLIs\nfish_add_path ${shimsDir}\n`;
1089
- }
1090
- else {
1091
- exportLine = `\n# agents-cli: version-managed agent CLIs\nexport PATH="${shimsDir}:$PATH"\n`;
1092
- }
1093
- // Find insertion point - BEFORE nvm/node setup if possible
1094
- // Look for common patterns that should come AFTER our shims
1095
- const insertBeforePatterns = [
1096
- /^export NVM_DIR=/m,
1097
- /^source.*nvm/m,
1098
- /^\[ -s.*nvm/m,
1099
- /^eval.*fnm/m,
1100
- /^export PATH.*node/m,
1101
- /^export PATH.*npm/m,
1102
- ];
1103
- let insertIndex = -1;
1104
- for (const pattern of insertBeforePatterns) {
1105
- const match = content.match(pattern);
1106
- if (match && match.index !== undefined) {
1107
- // Find start of this line
1108
- let lineStart = match.index;
1109
- while (lineStart > 0 && content[lineStart - 1] !== '\n') {
1110
- lineStart--;
1111
- }
1112
- if (insertIndex === -1 || lineStart < insertIndex) {
1113
- insertIndex = lineStart;
1114
- }
1115
- }
1116
- }
1117
- // Write the updated content
1118
- try {
1119
- // Ensure parent directories exist (especially for fish: ~/.config/fish/)
1120
- const rcDir = path.dirname(rcPath);
1121
- if (!fs.existsSync(rcDir)) {
1122
- fs.mkdirSync(rcDir, { recursive: true });
1123
- }
1124
- let newContent;
1125
- if (insertIndex >= 0) {
1126
- // Insert before nvm/node setup (handles index 0 correctly)
1127
- newContent = content.slice(0, insertIndex) + exportLine + content.slice(insertIndex);
1128
- }
1129
- else {
1130
- // Append to end
1131
- newContent = content + exportLine;
1132
- }
1133
- fs.writeFileSync(rcPath, newContent, 'utf-8');
1134
- return { success: true, rcFile };
1135
- }
1136
- catch (err) {
1137
- return { success: false, error: `Could not write ${rcFile}: ${err.message}` };
1138
- }
1139
- }
1140
- /**
1141
- * Create shims for all installed agents.
1142
- */
1143
- export function ensureAllShims() {
1144
- const versionsDir = getVersionsDir();
1145
- if (!fs.existsSync(versionsDir)) {
1146
- return;
1147
- }
1148
- const entries = fs.readdirSync(versionsDir, { withFileTypes: true });
1149
- for (const entry of entries) {
1150
- if (entry.isDirectory() && AGENTS[entry.name]) {
1151
- const agent = entry.name;
1152
- const agentVersionsDir = path.join(versionsDir, agent);
1153
- const versions = fs.readdirSync(agentVersionsDir, { withFileTypes: true })
1154
- .filter((e) => e.isDirectory());
1155
- if (versions.length > 0 && !shimExists(agent)) {
1156
- createShim(agent);
1157
- }
1158
- }
1159
- }
1160
- }
1161
- /**
1162
- * Compare resources between two versions.
1163
- * Returns resources that exist in currentVersion but not in targetVersion.
1164
- */
1165
- export function compareVersionResources(agent, currentVersion, targetVersion) {
1166
- const agentConfig = AGENTS[agent];
1167
- const currentPath = getVersionConfigPath(agent, currentVersion);
1168
- const targetPath = getVersionConfigPath(agent, targetVersion);
1169
- const diff = {
1170
- commands: [],
1171
- skills: [],
1172
- hooks: [],
1173
- memory: [],
1174
- mcp: [],
1175
- };
1176
- // Helper to list directory contents (names only)
1177
- const listDir = (dir) => {
1178
- if (!fs.existsSync(dir))
1179
- return [];
1180
- try {
1181
- return fs.readdirSync(dir).filter(f => !f.startsWith('.'));
1182
- }
1183
- catch {
1184
- /* directory not readable */
1185
- return [];
1186
- }
1187
- };
1188
- // Helper to count lines in a file
1189
- const countLines = (filePath) => {
1190
- if (!fs.existsSync(filePath))
1191
- return 0;
1192
- try {
1193
- return fs.readFileSync(filePath, 'utf-8').split('\n').length;
1194
- }
1195
- catch {
1196
- /* file not readable */
1197
- return 0;
1198
- }
1199
- };
1200
- // Compare commands
1201
- const currentCommands = listDir(path.join(currentPath, agentConfig.commandsSubdir));
1202
- const targetCommands = new Set(listDir(path.join(targetPath, agentConfig.commandsSubdir)));
1203
- diff.commands = currentCommands.filter(c => !targetCommands.has(c)).map(c => c.replace(/\.(md|toml)$/, ''));
1204
- // Compare skills
1205
- const currentSkills = listDir(path.join(currentPath, 'skills'));
1206
- const targetSkills = new Set(listDir(path.join(targetPath, 'skills')));
1207
- diff.skills = currentSkills.filter(s => !targetSkills.has(s));
1208
- // Compare hooks
1209
- const currentHooks = listDir(path.join(currentPath, 'hooks'));
1210
- const targetHooks = new Set(listDir(path.join(targetPath, 'hooks')));
1211
- diff.hooks = currentHooks.filter(h => !targetHooks.has(h));
1212
- // Compare memory files (instructionsFile like CLAUDE.md)
1213
- const memoryFile = agentConfig.instructionsFile;
1214
- const currentMemoryPath = path.join(currentPath, memoryFile);
1215
- const targetMemoryPath = path.join(targetPath, memoryFile);
1216
- const currentLines = countLines(currentMemoryPath);
1217
- const targetLines = countLines(targetMemoryPath);
1218
- if (currentLines > 0 && currentLines !== targetLines) {
1219
- diff.memory.push({ file: memoryFile, currentLines, targetLines });
1220
- }
1221
- // Compare MCP servers (from settings.json)
1222
- const readMcpServers = (configPath) => {
1223
- const settingsPath = path.join(configPath, 'settings.json');
1224
- if (!fs.existsSync(settingsPath))
1225
- return [];
1226
- try {
1227
- const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
1228
- return Object.keys(settings.mcpServers || {});
1229
- }
1230
- catch {
1231
- /* settings.json corrupt or unreadable */
1232
- return [];
1233
- }
1234
- };
1235
- const currentMcp = readMcpServers(currentPath);
1236
- const targetMcp = new Set(readMcpServers(targetPath));
1237
- diff.mcp = currentMcp.filter(m => !targetMcp.has(m));
1238
- return diff;
1239
- }
1240
- /**
1241
- * Check if a ResourceDiff has any differences.
1242
- */
1243
- export function hasResourceDiff(diff) {
1244
- return (diff.commands.length > 0 ||
1245
- diff.skills.length > 0 ||
1246
- diff.hooks.length > 0 ||
1247
- diff.memory.length > 0 ||
1248
- diff.mcp.length > 0);
1249
- }
1250
- /**
1251
- * Copy resources from one version to another.
1252
- * Only copies resources listed in the diff (i.e., ones missing in target).
1253
- */
1254
- export function copyResourcesToVersion(agent, fromVersion, toVersion, diff) {
1255
- const agentConfig = AGENTS[agent];
1256
- const fromPath = getVersionConfigPath(agent, fromVersion);
1257
- const toPath = getVersionConfigPath(agent, toVersion);
1258
- // Helper to copy a file or directory
1259
- const copyItem = (srcDir, destDir, name) => {
1260
- const srcPath = path.join(srcDir, name);
1261
- const destPath = path.join(destDir, name);
1262
- if (!fs.existsSync(srcPath))
1263
- return;
1264
- fs.mkdirSync(destDir, { recursive: true });
1265
- const stat = fs.statSync(srcPath);
1266
- if (stat.isDirectory()) {
1267
- copyDirContents(srcPath, destPath);
1268
- }
1269
- else {
1270
- fs.copyFileSync(srcPath, destPath);
1271
- }
1272
- };
1273
- // Copy missing commands
1274
- const commandsSubdir = agentConfig.commandsSubdir;
1275
- const ext = agentConfig.format === 'toml' ? '.toml' : '.md';
1276
- for (const cmd of diff.commands) {
1277
- copyItem(path.join(fromPath, commandsSubdir), path.join(toPath, commandsSubdir), `${cmd}${ext}`);
1278
- }
1279
- // Copy missing skills
1280
- for (const skill of diff.skills) {
1281
- copyItem(path.join(fromPath, 'skills'), path.join(toPath, 'skills'), skill);
1282
- }
1283
- // Copy missing hooks
1284
- for (const hook of diff.hooks) {
1285
- copyItem(path.join(fromPath, 'hooks'), path.join(toPath, 'hooks'), hook);
1286
- }
1287
- // Copy memory file if different
1288
- for (const mem of diff.memory) {
1289
- const srcPath = path.join(fromPath, mem.file);
1290
- const destPath = path.join(toPath, mem.file);
1291
- if (fs.existsSync(srcPath)) {
1292
- fs.copyFileSync(srcPath, destPath);
1293
- }
1294
- }
1295
- // Merge MCP servers into target settings.json
1296
- if (diff.mcp.length > 0) {
1297
- const fromSettingsPath = path.join(fromPath, 'settings.json');
1298
- const toSettingsPath = path.join(toPath, 'settings.json');
1299
- if (fs.existsSync(fromSettingsPath)) {
1300
- try {
1301
- const fromSettings = JSON.parse(fs.readFileSync(fromSettingsPath, 'utf-8'));
1302
- let toSettings = {};
1303
- if (fs.existsSync(toSettingsPath)) {
1304
- toSettings = JSON.parse(fs.readFileSync(toSettingsPath, 'utf-8'));
1305
- }
1306
- if (!toSettings.mcpServers) {
1307
- toSettings.mcpServers = {};
1308
- }
1309
- for (const serverName of diff.mcp) {
1310
- if (fromSettings.mcpServers?.[serverName]) {
1311
- toSettings.mcpServers[serverName] = fromSettings.mcpServers[serverName];
1312
- }
1313
- }
1314
- fs.writeFileSync(toSettingsPath, JSON.stringify(toSettings, null, 2));
1315
- }
1316
- catch {
1317
- /* settings.json parse error, skip MCP merge */
1318
- }
1319
- }
1320
- }
1321
- }
1322
- //# sourceMappingURL=shims.js.map