@swarmify/agents-cli 1.13.4 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (567) hide show
  1. package/README.md +2 -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
@@ -1,1244 +0,0 @@
1
- /**
2
- * Teams agent lifecycle management.
3
- *
4
- * Defines the AgentProcess and AgentManager classes that handle spawning,
5
- * monitoring, stopping, and persisting teammate processes across all supported
6
- * agent CLIs (Claude, Codex, Gemini, Cursor, OpenCode). Supports DAG-based
7
- * dependency scheduling via --after, per-teammate model/effort overrides, and
8
- * multiple permission modes (plan, edit, full).
9
- */
10
- import { spawn, execSync } from 'child_process';
11
- import * as fs from 'fs/promises';
12
- import * as path from 'path';
13
- import * as os from 'os';
14
- import { randomUUID } from 'crypto';
15
- import { resolveAgentsDir } from './persistence.js';
16
- import { normalizeEvents } from './parsers.js';
17
- import { debug } from './debug.js';
18
- import { buildReasoningFlags } from '../models.js';
19
- /**
20
- * Compute the Lowest Common Ancestor (LCA) of multiple file paths.
21
- * Returns the deepest common directory shared by all paths.
22
- * Returns null if paths is empty or paths have no common ancestor (different roots).
23
- */
24
- export function computePathLCA(paths) {
25
- const validPaths = paths.filter(p => p && p.trim());
26
- if (validPaths.length === 0)
27
- return null;
28
- if (validPaths.length === 1)
29
- return validPaths[0];
30
- // Normalize and split all paths into segments
31
- const splitPaths = validPaths.map(p => {
32
- const normalized = path.resolve(p);
33
- // Split by path separator, filter empty segments
34
- return normalized.split(path.sep).filter(seg => seg);
35
- });
36
- // Find minimum length
37
- const minLen = Math.min(...splitPaths.map(p => p.length));
38
- // Find common prefix
39
- const commonSegments = [];
40
- for (let i = 0; i < minLen; i++) {
41
- const segment = splitPaths[0][i];
42
- const allMatch = splitPaths.every(p => p[i] === segment);
43
- if (allMatch) {
44
- commonSegments.push(segment);
45
- }
46
- else {
47
- break;
48
- }
49
- }
50
- if (commonSegments.length === 0)
51
- return null;
52
- // Reconstruct path (add leading separator for absolute paths)
53
- const lca = path.sep + commonSegments.join(path.sep);
54
- return lca;
55
- }
56
- /** Lifecycle status of a teammate process. */
57
- export var AgentStatus;
58
- (function (AgentStatus) {
59
- AgentStatus["PENDING"] = "pending";
60
- AgentStatus["RUNNING"] = "running";
61
- AgentStatus["COMPLETED"] = "completed";
62
- AgentStatus["FAILED"] = "failed";
63
- AgentStatus["STOPPED"] = "stopped";
64
- })(AgentStatus || (AgentStatus = {}));
65
- export const VALID_TASK_TYPES = [
66
- 'plan', 'implement', 'test', 'review', 'bugfix', 'docs',
67
- ];
68
- /**
69
- * Walk the `after` chain from `startName` within the given map; returns true
70
- * if `targetName` appears anywhere in the transitive dependency closure.
71
- * Used to detect cycles before adding a new --after edge.
72
- */
73
- function hasTransitiveDep(byName, startName, targetName, seen = new Set()) {
74
- if (seen.has(startName))
75
- return false;
76
- seen.add(startName);
77
- const node = byName.get(startName);
78
- if (!node)
79
- return false;
80
- for (const dep of node.after) {
81
- if (dep === targetName)
82
- return true;
83
- if (hasTransitiveDep(byName, dep, targetName, seen))
84
- return true;
85
- }
86
- return false;
87
- }
88
- // Base commands for plan mode (read-only, may prompt for confirmation)
89
- export const AGENT_COMMANDS = {
90
- codex: ['codex', 'exec', '--sandbox', 'workspace-write', '{prompt}', '--json'],
91
- cursor: ['cursor-agent', '-p', '--output-format', 'stream-json', '{prompt}'],
92
- gemini: ['gemini', '{prompt}', '--output-format', 'stream-json', '--approval-mode', 'plan'],
93
- claude: ['claude', '-p', '--verbose', '{prompt}', '--output-format', 'stream-json', '--permission-mode', 'plan'],
94
- opencode: ['opencode', 'run', '--format', 'json', '{prompt}'],
95
- };
96
- // Minimal defaults — no per-effort model map. Configs on disk may still have
97
- // a model pinned; launchProcess picks it up from agent.model when set.
98
- function loadDefaultAgentConfigs() {
99
- return {
100
- claude: { command: 'claude -p \'{prompt}\' --output-format stream-json --json', enabled: true, model: null, provider: 'anthropic' },
101
- codex: { command: 'codex exec --sandbox workspace-write \'{prompt}\' --json', enabled: true, model: null, provider: 'openai' },
102
- gemini: { command: 'gemini \'{prompt}\' --output-format stream-json', enabled: true, model: null, provider: 'google' },
103
- cursor: { command: 'cursor-agent -p --output-format stream-json \'{prompt}\'', enabled: true, model: null, provider: 'custom' },
104
- opencode: { command: 'opencode run --format json \'{prompt}\'', enabled: true, model: null, provider: 'custom' },
105
- };
106
- }
107
- // Suffix appended to all prompts to ensure agents provide a summary
108
- const PROMPT_SUFFIX = `
109
-
110
- When you're done, provide a brief summary of:
111
- 1. What you did (1-2 sentences)
112
- 2. Key files modified and why
113
- 3. Any important classes, functions, or components you added/changed`;
114
- // Prefix for Claude agents in plan mode - explains the headless plan mode restrictions
115
- const CLAUDE_PLAN_MODE_PREFIX = `You are running in HEADLESS PLAN MODE. This mode works like normal plan mode with one exception: you cannot write to ~/.claude/plans/ directory. Instead of writing a plan file, output your complete plan/response as your final message.
116
-
117
- `;
118
- const VALID_MODES = ['plan', 'edit', 'full'];
119
- function normalizeModeValue(modeValue) {
120
- if (!modeValue)
121
- return null;
122
- const normalized = modeValue.trim().toLowerCase();
123
- if (VALID_MODES.includes(normalized)) {
124
- return normalized;
125
- }
126
- return null;
127
- }
128
- function defaultModeFromEnv() {
129
- for (const envVar of ['AGENTS_MCP_MODE', 'AGENTS_MCP_DEFAULT_MODE']) {
130
- const rawValue = process.env[envVar];
131
- const parsed = normalizeModeValue(rawValue);
132
- if (parsed) {
133
- return parsed;
134
- }
135
- if (rawValue) {
136
- console.warn(`Invalid ${envVar}='${rawValue}'. Use 'plan' or 'edit'. Falling back to plan mode.`);
137
- }
138
- }
139
- return 'plan';
140
- }
141
- function coerceDate(value) {
142
- if (value === null || value === undefined)
143
- return null;
144
- if (typeof value === 'number' && Number.isFinite(value)) {
145
- const ms = value < 1e12 ? value * 1000 : value;
146
- const date = new Date(ms);
147
- return Number.isNaN(date.getTime()) ? null : date;
148
- }
149
- if (typeof value === 'string') {
150
- const trimmed = value.trim();
151
- if (!trimmed)
152
- return null;
153
- const numeric = Number(trimmed);
154
- if (!Number.isNaN(numeric)) {
155
- const ms = numeric < 1e12 ? numeric * 1000 : numeric;
156
- const date = new Date(ms);
157
- if (!Number.isNaN(date.getTime()))
158
- return date;
159
- }
160
- const date = new Date(trimmed);
161
- return Number.isNaN(date.getTime()) ? null : date;
162
- }
163
- return null;
164
- }
165
- function extractTimestamp(raw) {
166
- if (!raw || typeof raw !== 'object')
167
- return null;
168
- const candidates = [
169
- raw.timestamp,
170
- raw.time,
171
- raw.created_at,
172
- raw.createdAt,
173
- raw.ts,
174
- raw.started_at,
175
- raw.startedAt,
176
- ];
177
- for (const candidate of candidates) {
178
- const date = coerceDate(candidate);
179
- if (date)
180
- return date;
181
- }
182
- return null;
183
- }
184
- /** Resolve a mode string to a validated Mode, falling back to the given default. */
185
- export function resolveMode(requestedMode, defaultMode = 'plan') {
186
- const normalizedDefault = normalizeModeValue(defaultMode);
187
- if (!normalizedDefault) {
188
- throw new Error(`Invalid default mode '${defaultMode}'. Use 'plan' or 'edit'.`);
189
- }
190
- if (requestedMode !== null && requestedMode !== undefined) {
191
- const normalizedMode = normalizeModeValue(requestedMode);
192
- if (!normalizedMode) {
193
- throw new Error(`Invalid mode '${requestedMode}'. Valid modes: 'plan' (read-only) or 'edit' (can write).`);
194
- }
195
- return normalizedMode;
196
- }
197
- return normalizedDefault;
198
- }
199
- /** Ensure Gemini's settings.json has experimental.plan enabled for headless plan mode. */
200
- export async function ensureGeminiPlanMode() {
201
- const settingsPath = path.join(os.homedir(), '.gemini', 'settings.json');
202
- try {
203
- let settings = {};
204
- try {
205
- const raw = await fs.readFile(settingsPath, 'utf-8');
206
- settings = JSON.parse(raw);
207
- }
208
- catch {
209
- // No settings file or invalid JSON
210
- }
211
- if (settings.experimental?.plan === true)
212
- return;
213
- settings.experimental = { ...settings.experimental, plan: true };
214
- await fs.mkdir(path.dirname(settingsPath), { recursive: true });
215
- await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2) + '\n');
216
- console.error('[Swarm] Enabled Gemini experimental.plan in', settingsPath);
217
- }
218
- catch (err) {
219
- console.warn('[Swarm] Could not enable Gemini plan mode:', err);
220
- }
221
- }
222
- /** Check whether the CLI binary for a given agent type exists in PATH. Returns [available, pathOrError]. */
223
- export function checkCliAvailable(agentType) {
224
- const cmdTemplate = AGENT_COMMANDS[agentType];
225
- if (!cmdTemplate) {
226
- return [false, `Unknown agent type: ${agentType}`];
227
- }
228
- const executable = cmdTemplate[0];
229
- try {
230
- const whichPath = execSync(`which ${executable}`, { encoding: 'utf-8' }).trim();
231
- return [true, whichPath];
232
- }
233
- catch {
234
- return [false, `CLI tool '${executable}' not found in PATH. Install it first.`];
235
- }
236
- }
237
- /** Check availability of all known agent CLIs. Returns a map of agent type to install status. */
238
- export function checkAllClis() {
239
- const results = {};
240
- for (const agentType of Object.keys(AGENT_COMMANDS)) {
241
- const [available, pathOrError] = checkCliAvailable(agentType);
242
- if (available) {
243
- results[agentType] = { installed: true, path: pathOrError, error: null };
244
- }
245
- else {
246
- results[agentType] = { installed: false, path: null, error: pathOrError };
247
- }
248
- }
249
- return results;
250
- }
251
- let AGENTS_DIR = null;
252
- /** Resolve and cache the base directory where teammate process data is stored. */
253
- export async function getAgentsDir() {
254
- if (!AGENTS_DIR) {
255
- AGENTS_DIR = await resolveAgentsDir();
256
- }
257
- return AGENTS_DIR;
258
- }
259
- /**
260
- * Represents a single teammate process within a team.
261
- *
262
- * Tracks process metadata (PID, status, timestamps), reads incremental
263
- * stdout events, persists state to disk as meta.json, and can be
264
- * reconstituted from disk via loadFromDisk().
265
- */
266
- export class AgentProcess {
267
- agentId;
268
- taskName;
269
- agentType;
270
- prompt;
271
- cwd;
272
- workspaceDir;
273
- mode = 'plan';
274
- pid = null;
275
- status = AgentStatus.RUNNING;
276
- startedAt = new Date();
277
- completedAt = null;
278
- parentSessionId = null;
279
- cloudSessionId = null;
280
- cloudProvider = null;
281
- prUrl = null;
282
- version = null;
283
- remoteSessionId = null;
284
- name = null;
285
- // Names of teammates in the same team that this teammate is waiting on.
286
- // Empty array = no deps = can run immediately. Populated by `teams add --after`.
287
- after = [];
288
- // Reasoning-intensity knob wired into buildReasoningFlags at launch time.
289
- // Resolved late so config/effort-default changes between spawn and launch
290
- // are honored for teammates staged via `teams add --after`.
291
- effort = null;
292
- // Pinned model for this teammate. When null, the agent's CLI picks its
293
- // own default (no --model forwarded).
294
- model = null;
295
- // Extra env vars passed through to the child process (from --env KEY=VALUE).
296
- envOverrides = null;
297
- // Factory task-type label. When set, drives planner fan-out and the
298
- // test-oracle loop. Null for plain teammates — no behavioral change.
299
- taskType = null;
300
- // Repo/branch for cloud dispatches that stage behind --after. Captured
301
- // at spawn time so startReady() can invoke the dispatcher with the same
302
- // options the user originally supplied.
303
- cloudRepo = null;
304
- cloudBranch = null;
305
- eventsCache = [];
306
- lastReadPos = 0;
307
- baseDir = null;
308
- constructor(agentId, taskName, agentType, prompt, cwd = null, mode = 'plan', pid = null, status = AgentStatus.RUNNING, startedAt = new Date(), completedAt = null, baseDir = null, parentSessionId = null, workspaceDir = null, cloudSessionId = null, cloudProvider = null, prUrl = null, version = null, remoteSessionId = null, name = null, after = [], effort = null, model = null, envOverrides = null, taskType = null, cloudRepo = null, cloudBranch = null) {
309
- this.agentId = agentId;
310
- this.remoteSessionId = remoteSessionId;
311
- this.name = name;
312
- this.after = after;
313
- this.effort = effort;
314
- this.model = model;
315
- this.envOverrides = envOverrides;
316
- this.taskType = taskType;
317
- this.cloudRepo = cloudRepo;
318
- this.cloudBranch = cloudBranch;
319
- this.taskName = taskName;
320
- this.agentType = agentType;
321
- this.prompt = prompt;
322
- this.cwd = cwd;
323
- this.workspaceDir = workspaceDir;
324
- this.mode = mode;
325
- this.pid = pid;
326
- this.status = status;
327
- this.startedAt = startedAt;
328
- this.completedAt = completedAt;
329
- this.baseDir = baseDir;
330
- this.parentSessionId = parentSessionId;
331
- this.cloudSessionId = cloudSessionId;
332
- this.cloudProvider = cloudProvider;
333
- this.prUrl = prUrl;
334
- this.version = version;
335
- }
336
- get isEditMode() {
337
- return this.mode === 'edit' || this.mode === 'full';
338
- }
339
- async getAgentDir() {
340
- const base = this.baseDir || await getAgentsDir();
341
- return path.join(base, this.agentId);
342
- }
343
- /**
344
- * Dump the subset of state the Ledger sync hook needs. Keeps sync.ts
345
- * free of any teams-internal imports.
346
- */
347
- async toSnapshot() {
348
- return {
349
- agent_id: this.agentId,
350
- team_id: this.taskName,
351
- teammate_name: this.name,
352
- agent_type: this.agentType,
353
- task_type: this.taskType,
354
- status: this.status,
355
- started_at: this.startedAt.toISOString(),
356
- completed_at: this.completedAt?.toISOString() ?? null,
357
- after: this.after,
358
- cloud_provider: this.cloudProvider,
359
- cloud_session_id: this.cloudSessionId,
360
- cloud_repo: this.cloudRepo,
361
- cloud_branch: this.cloudBranch,
362
- agent_dir: await this.getAgentDir(),
363
- cwd: this.cwd,
364
- };
365
- }
366
- async getStdoutPath() {
367
- return path.join(await this.getAgentDir(), 'stdout.log');
368
- }
369
- async getMetaPath() {
370
- return path.join(await this.getAgentDir(), 'meta.json');
371
- }
372
- toDict() {
373
- return {
374
- agent_id: this.agentId,
375
- task_name: this.taskName,
376
- agent_type: this.agentType,
377
- status: this.status,
378
- started_at: this.startedAt.toISOString(),
379
- completed_at: this.completedAt?.toISOString() || null,
380
- event_count: this.events.length,
381
- duration: this.duration(),
382
- mode: this.mode,
383
- parent_session_id: this.parentSessionId,
384
- workspace_dir: this.workspaceDir,
385
- cloud_session_id: this.cloudSessionId,
386
- cloud_provider: this.cloudProvider,
387
- pr_url: this.prUrl,
388
- version: this.version,
389
- remote_session_id: this.remoteSessionId,
390
- name: this.name,
391
- after: this.after,
392
- effort: this.effort,
393
- model: this.model,
394
- env_overrides: this.envOverrides,
395
- task_type: this.taskType,
396
- cloud_repo: this.cloudRepo,
397
- cloud_branch: this.cloudBranch,
398
- };
399
- }
400
- duration() {
401
- let seconds;
402
- if (this.completedAt) {
403
- seconds = (this.completedAt.getTime() - this.startedAt.getTime()) / 1000;
404
- }
405
- else if (this.status === AgentStatus.RUNNING) {
406
- seconds = (Date.now() - this.startedAt.getTime()) / 1000;
407
- }
408
- else {
409
- return null;
410
- }
411
- if (seconds < 60) {
412
- return `${Math.floor(seconds)} seconds`;
413
- }
414
- else {
415
- const minutes = seconds / 60;
416
- return `${minutes.toFixed(1)} minutes`;
417
- }
418
- }
419
- get events() {
420
- return this.eventsCache;
421
- }
422
- /**
423
- * Return the latest timestamp we have seen in the agent's events.
424
- * Falls back to null when none are available.
425
- */
426
- getLatestEventTime() {
427
- let latest = null;
428
- for (const event of this.eventsCache) {
429
- const ts = event?.timestamp;
430
- if (!ts)
431
- continue;
432
- const parsed = new Date(ts);
433
- if (!Number.isNaN(parsed.getTime())) {
434
- if (!latest || parsed > latest) {
435
- latest = parsed;
436
- }
437
- }
438
- }
439
- return latest;
440
- }
441
- async readNewEvents() {
442
- const stdoutPath = await this.getStdoutPath();
443
- try {
444
- const stats = await fs.stat(stdoutPath).catch(() => null);
445
- if (!stats)
446
- return;
447
- const fallbackTimestamp = (stats.mtime || new Date()).toISOString();
448
- const fd = await fs.open(stdoutPath, 'r');
449
- const buffer = Buffer.alloc(1024 * 1024);
450
- const { bytesRead } = await fd.read(buffer, 0, buffer.length, this.lastReadPos);
451
- await fd.close();
452
- if (bytesRead === 0)
453
- return;
454
- const newContent = buffer.toString('utf-8', 0, bytesRead);
455
- this.lastReadPos += bytesRead;
456
- const lines = newContent.split('\n').map(l => l.trim()).filter(l => l);
457
- for (const line of lines) {
458
- try {
459
- const rawEvent = JSON.parse(line);
460
- const events = normalizeEvents(this.agentType, rawEvent);
461
- const resolvedTimestamp = extractTimestamp(rawEvent)?.toISOString() || fallbackTimestamp;
462
- for (const event of events) {
463
- event.timestamp = resolvedTimestamp;
464
- this.eventsCache.push(event);
465
- // Capture the agent's own session/thread id the first time we see
466
- // it. For Claude it's the same uuid we passed via --session-id;
467
- // for others (Codex thread_id, Gemini/Cursor/OpenCode sessionID)
468
- // it's their internal id, which lets us cross-reference with
469
- // `agents sessions <id>`.
470
- if (!this.remoteSessionId && event.session_id) {
471
- this.remoteSessionId = event.session_id;
472
- }
473
- if (event.type === 'result' || event.type === 'turn.completed' || event.type === 'thread.completed') {
474
- if (event.status === 'success' || event.type === 'turn.completed') {
475
- this.status = AgentStatus.COMPLETED;
476
- this.completedAt = event.timestamp ? new Date(event.timestamp) : new Date();
477
- }
478
- else if (event.status === 'error') {
479
- this.status = AgentStatus.FAILED;
480
- this.completedAt = event.timestamp ? new Date(event.timestamp) : new Date();
481
- }
482
- }
483
- }
484
- }
485
- catch {
486
- this.eventsCache.push({
487
- type: 'raw',
488
- content: line,
489
- timestamp: fallbackTimestamp,
490
- });
491
- }
492
- }
493
- }
494
- catch (err) {
495
- console.error(`Error reading events for agent ${this.agentId}:`, err);
496
- }
497
- }
498
- async saveMeta() {
499
- const agentDir = await this.getAgentDir();
500
- await fs.mkdir(agentDir, { recursive: true });
501
- const meta = {
502
- agent_id: this.agentId,
503
- task_name: this.taskName,
504
- agent_type: this.agentType,
505
- prompt: this.prompt,
506
- cwd: this.cwd,
507
- workspace_dir: this.workspaceDir,
508
- mode: this.mode,
509
- pid: this.pid,
510
- status: this.status,
511
- started_at: this.startedAt.toISOString(),
512
- completed_at: this.completedAt?.toISOString() || null,
513
- parent_session_id: this.parentSessionId,
514
- cloud_session_id: this.cloudSessionId,
515
- cloud_provider: this.cloudProvider,
516
- pr_url: this.prUrl,
517
- version: this.version,
518
- remote_session_id: this.remoteSessionId,
519
- name: this.name,
520
- after: this.after,
521
- effort: this.effort,
522
- model: this.model,
523
- env_overrides: this.envOverrides,
524
- task_type: this.taskType,
525
- cloud_repo: this.cloudRepo,
526
- cloud_branch: this.cloudBranch,
527
- };
528
- const metaPath = await this.getMetaPath();
529
- await fs.writeFile(metaPath, JSON.stringify(meta, null, 2));
530
- }
531
- static async loadFromDisk(agentId, baseDir = null) {
532
- const base = baseDir || await getAgentsDir();
533
- const agentDir = path.join(base, agentId);
534
- const metaPath = path.join(agentDir, 'meta.json');
535
- try {
536
- await fs.access(metaPath);
537
- }
538
- catch {
539
- return null;
540
- }
541
- try {
542
- const metaContent = await fs.readFile(metaPath, 'utf-8');
543
- const meta = JSON.parse(metaContent);
544
- // Legacy teammates may have mode='ralph' or 'cloud' from before modes
545
- // were narrowed. Coerce to the closest current mode so they still load.
546
- const modeMap = {
547
- edit: 'edit',
548
- full: 'full',
549
- ralph: 'full', // ralph used the same "no-permission" flags as full
550
- cloud: 'edit', // cloud teammates had edit-level write access
551
- };
552
- const resolvedMode = modeMap[meta.mode] || 'plan';
553
- // AgentStatus is a string enum. Validate meta.status against its VALUES
554
- // (not its keys) — `AgentStatus["pending"]` is undefined but
555
- // `AgentStatus.PENDING === "pending"` works.
556
- const validStatuses = Object.values(AgentStatus);
557
- const resolvedStatus = validStatuses.includes(meta.status)
558
- ? meta.status
559
- : AgentStatus.RUNNING;
560
- const agent = new AgentProcess(meta.agent_id, meta.task_name || 'default', meta.agent_type, meta.prompt, meta.cwd || null, resolvedMode, meta.pid || null, resolvedStatus, new Date(meta.started_at), meta.completed_at ? new Date(meta.completed_at) : null, baseDir, meta.parent_session_id || null, meta.workspace_dir || null, meta.cloud_session_id || null, meta.cloud_provider || null, meta.pr_url || null, meta.version || null, meta.remote_session_id || null, meta.name || null, Array.isArray(meta.after) ? meta.after : [], meta.effort || null, meta.model || null, meta.env_overrides || null, meta.task_type && VALID_TASK_TYPES.includes(meta.task_type)
561
- ? meta.task_type
562
- : null, meta.cloud_repo || null, meta.cloud_branch || null);
563
- return agent;
564
- }
565
- catch {
566
- return null;
567
- }
568
- }
569
- isProcessAlive() {
570
- if (!this.pid)
571
- return false;
572
- try {
573
- process.kill(this.pid, 0);
574
- return true;
575
- }
576
- catch {
577
- return false;
578
- }
579
- }
580
- async updateStatusFromProcess() {
581
- if (!this.pid)
582
- return;
583
- if (this.isProcessAlive()) {
584
- await this.readNewEvents();
585
- return;
586
- }
587
- if (this.status === AgentStatus.RUNNING) {
588
- const exitCode = await this.reapProcess();
589
- await this.readNewEvents();
590
- if (this.status === AgentStatus.RUNNING) {
591
- const fallbackCompletion = this.getLatestEventTime() || this.startedAt || new Date();
592
- if (exitCode !== null && exitCode !== 0) {
593
- this.status = AgentStatus.FAILED;
594
- }
595
- else {
596
- this.status = AgentStatus.COMPLETED;
597
- }
598
- this.completedAt = fallbackCompletion;
599
- }
600
- }
601
- else if (!this.completedAt) {
602
- await this.readNewEvents();
603
- const fallbackCompletion = this.getLatestEventTime() || this.startedAt || new Date();
604
- this.completedAt = fallbackCompletion;
605
- }
606
- await this.saveMeta();
607
- }
608
- async reapProcess() {
609
- if (!this.pid)
610
- return null;
611
- try {
612
- process.kill(this.pid, 0);
613
- return null;
614
- }
615
- catch {
616
- return 1;
617
- }
618
- }
619
- }
620
- export class AgentManager {
621
- agents = new Map();
622
- maxAgents;
623
- maxConcurrent;
624
- agentsDir = '';
625
- filterByCwd;
626
- cleanupAgeDays;
627
- defaultMode;
628
- agentConfigs;
629
- constructorAgentConfigs = null;
630
- initPromise = null;
631
- cloudDispatcher = null;
632
- completionHook = null;
633
- syncedAgents = new Set();
634
- constructorAgentsDir = null;
635
- constructor(maxAgents = 50, maxConcurrent = 10, agentsDir = null, defaultMode = null, filterByCwd = null, cleanupAgeDays = 7, agentConfigs = null) {
636
- this.maxAgents = maxAgents;
637
- this.maxConcurrent = maxConcurrent;
638
- this.constructorAgentsDir = agentsDir;
639
- this.filterByCwd = filterByCwd;
640
- this.cleanupAgeDays = cleanupAgeDays;
641
- const resolvedDefaultMode = defaultMode ? normalizeModeValue(defaultMode) : defaultModeFromEnv();
642
- if (!resolvedDefaultMode) {
643
- throw new Error(`Invalid default_mode '${defaultMode}'. Use 'plan' or 'edit'.`);
644
- }
645
- this.defaultMode = resolvedDefaultMode;
646
- this.constructorAgentConfigs = agentConfigs;
647
- this.initPromise = this.doInitialize();
648
- }
649
- async initialize() {
650
- if (!this.initPromise) {
651
- this.initPromise = this.doInitialize();
652
- }
653
- return this.initPromise;
654
- }
655
- async doInitialize() {
656
- this.agentsDir = this.constructorAgentsDir || await getAgentsDir();
657
- await fs.mkdir(this.agentsDir, { recursive: true });
658
- this.agentConfigs = this.constructorAgentConfigs ?? loadDefaultAgentConfigs();
659
- await this.loadExistingAgents();
660
- }
661
- getDefaultMode() {
662
- return this.defaultMode;
663
- }
664
- setModelOverrides(agentConfigs) {
665
- this.agentConfigs = agentConfigs;
666
- }
667
- /**
668
- * Register the callback used to dispatch cloud-backed teammates when their
669
- * --after deps resolve. Called once at CLI startup by `agents teams`.
670
- */
671
- setCloudDispatcher(fn) {
672
- this.cloudDispatcher = fn;
673
- }
674
- /**
675
- * Register a hook to run once per teammate the first time it lands in a
676
- * terminal status (completed / failed / stopped). The hook fires during
677
- * listAll() / listByTask() status polling, so any CLI or MCP command that
678
- * touches status triggers sync automatically.
679
- */
680
- setCompletionHook(fn) {
681
- this.completionHook = fn;
682
- }
683
- registerAgent(agent) {
684
- this.agents.set(agent.agentId, agent);
685
- }
686
- /**
687
- * Scan the agents dir for meta.json files not already in the in-memory
688
- * cache and load them. Needed when another process (e.g. a Planner
689
- * teammate running `agents teams add`) creates new teammates while this
690
- * manager is alive — the supervisor loop calls this each wave so
691
- * dynamically-added teammates get picked up.
692
- *
693
- * Does not modify or re-load agents already in the cache; that path is
694
- * covered by updateStatusFromProcess() which re-reads stdout.log.
695
- */
696
- async rescanFromDisk() {
697
- await this.initialize();
698
- try {
699
- await fs.access(this.agentsDir);
700
- }
701
- catch {
702
- return 0;
703
- }
704
- const entries = await fs.readdir(this.agentsDir);
705
- let added = 0;
706
- for (const entry of entries) {
707
- if (this.agents.has(entry))
708
- continue;
709
- const agentDir = path.join(this.agentsDir, entry);
710
- const stat = await fs.stat(agentDir).catch(() => null);
711
- if (!stat || !stat.isDirectory())
712
- continue;
713
- const agent = await AgentProcess.loadFromDisk(entry, this.agentsDir);
714
- if (!agent)
715
- continue;
716
- if (this.filterByCwd !== null && agent.cwd !== this.filterByCwd)
717
- continue;
718
- this.agents.set(entry, agent);
719
- added++;
720
- }
721
- return added;
722
- }
723
- async loadExistingAgents() {
724
- try {
725
- await fs.access(this.agentsDir);
726
- }
727
- catch {
728
- return;
729
- }
730
- const cutoffDate = new Date(Date.now() - this.cleanupAgeDays * 24 * 60 * 60 * 1000);
731
- let loadedCount = 0;
732
- let skippedCwd = 0;
733
- let cleanedOld = 0;
734
- const entries = await fs.readdir(this.agentsDir);
735
- for (const entry of entries) {
736
- const agentDir = path.join(this.agentsDir, entry);
737
- const stat = await fs.stat(agentDir).catch(() => null);
738
- if (!stat || !stat.isDirectory())
739
- continue;
740
- const agentId = entry;
741
- const agent = await AgentProcess.loadFromDisk(agentId, this.agentsDir);
742
- if (!agent)
743
- continue;
744
- if (agent.completedAt && agent.completedAt < cutoffDate) {
745
- try {
746
- await fs.rm(agentDir, { recursive: true });
747
- cleanedOld++;
748
- }
749
- catch (err) {
750
- console.warn(`Failed to cleanup old agent ${agentId}:`, err);
751
- }
752
- continue;
753
- }
754
- if (this.filterByCwd !== null) {
755
- const agentCwd = agent.cwd;
756
- if (agentCwd !== this.filterByCwd) {
757
- skippedCwd++;
758
- continue;
759
- }
760
- }
761
- await agent.updateStatusFromProcess();
762
- this.agents.set(agentId, agent);
763
- loadedCount++;
764
- }
765
- if (cleanedOld > 0) {
766
- debug(`Cleaned up ${cleanedOld} old agents (older than ${this.cleanupAgeDays} days)`);
767
- }
768
- if (skippedCwd > 0) {
769
- debug(`Skipped ${skippedCwd} agents (different CWD)`);
770
- }
771
- debug(`Loaded ${loadedCount} agents from disk`);
772
- }
773
- async spawn(taskName, agentType, prompt, cwd = null, mode = null, effort = 'medium', parentSessionId = null, workspaceDir = null, version = null, name = null, after = [], model = null, envOverrides = null, taskType = null, cloudProvider = null, cloudSessionId = null, cloudRepo = null, cloudBranch = null) {
774
- await this.initialize();
775
- const resolvedMode = resolveMode(mode, this.defaultMode);
776
- // Enforce: teammate names are unique within a team.
777
- const siblings = await this.listByTask(taskName);
778
- if (name && siblings.some((a) => a.name === name)) {
779
- throw new Error(`Team '${taskName}' already has a teammate named '${name}'. Pick another name or leave --name off.`);
780
- }
781
- // --- dependency validation ---
782
- const cleanAfter = after.filter((s) => s && s.trim());
783
- if (cleanAfter.length > 0) {
784
- if (!name) {
785
- throw new Error("Can't use --after without --name. Dependencies reference teammates by name.");
786
- }
787
- // Every --after entry must resolve to an existing teammate name.
788
- const siblingNames = new Set(siblings.map((a) => a.name).filter(Boolean));
789
- const missing = cleanAfter.filter((dep) => !siblingNames.has(dep));
790
- if (missing.length > 0) {
791
- throw new Error(`Team '${taskName}' has no teammate named ${missing.map((m) => `'${m}'`).join(', ')} yet.\n` +
792
- ` Add them first, then add this one.`);
793
- }
794
- // Cycle check: walk the transitive deps of each --after entry; if the
795
- // new teammate's own name shows up, we'd create a cycle.
796
- const byName = new Map(siblings.filter((a) => a.name).map((a) => [a.name, a]));
797
- for (const dep of cleanAfter) {
798
- if (hasTransitiveDep(byName, dep, name)) {
799
- throw new Error(`Adding '${name}' after '${dep}' would create a cycle (${dep} already depends on ${name}).`);
800
- }
801
- }
802
- }
803
- // Resolve and validate cwd
804
- let resolvedCwd = null;
805
- if (cwd !== null) {
806
- resolvedCwd = path.resolve(cwd);
807
- const stat = await fs.stat(resolvedCwd).catch(() => null);
808
- if (!stat) {
809
- throw new Error(`Working directory does not exist: ${cwd}`);
810
- }
811
- if (!stat.isDirectory()) {
812
- throw new Error(`Working directory is not a directory: ${cwd}`);
813
- }
814
- }
815
- // Cloud-backed teammates run on remote infrastructure; we don't need the
816
- // local CLI for them (the pod has its own). The caller has already
817
- // dispatched via the cloud provider and passed us the provider + session.
818
- const isCloudBacked = Boolean(cloudProvider);
819
- if (!isCloudBacked) {
820
- const [available, pathOrError] = checkCliAvailable(agentType);
821
- if (!available) {
822
- throw new Error(pathOrError || 'CLI tool not available');
823
- }
824
- }
825
- // Use a full UUIDv4 as the canonical agent_id. For Claude, we pass it via
826
- // --session-id so it's also Claude's session id (unified identity).
827
- const agentId = randomUUID();
828
- const isStaged = cleanAfter.length > 0;
829
- const agent = new AgentProcess(agentId, taskName, agentType, prompt, resolvedCwd, resolvedMode, null, isStaged ? AgentStatus.PENDING : AgentStatus.RUNNING, new Date(), null, this.agentsDir, parentSessionId, workspaceDir, cloudSessionId, cloudProvider, null, version, null, name, cleanAfter, effort, model, envOverrides && Object.keys(envOverrides).length > 0 ? envOverrides : null, taskType, cloudRepo, cloudBranch);
830
- const agentDir = await agent.getAgentDir();
831
- try {
832
- await fs.mkdir(agentDir, { recursive: true });
833
- }
834
- catch (err) {
835
- throw new Error(`Failed to create agent directory: ${err.message}`);
836
- }
837
- await agent.saveMeta();
838
- this.agents.set(agentId, agent);
839
- if (isStaged) {
840
- debug(`Staged ${agentType} teammate '${name}' in team '${taskName}' (after: ${cleanAfter.join(', ')})`);
841
- }
842
- else if (isCloudBacked) {
843
- // Cloud-backed teammate: the provider already dispatched a remote task.
844
- // No local process to launch; status polling walks the provider instead.
845
- debug(`Cloud-backed ${agentType} teammate via ${cloudProvider} (session=${cloudSessionId})`);
846
- }
847
- else {
848
- await this.launchProcess(agent);
849
- }
850
- await this.cleanupOldAgents();
851
- return agent;
852
- }
853
- /**
854
- * Actually spawn the OS process for a teammate. Extracted from spawn() so
855
- * staged teammates can be launched later by startReady().
856
- */
857
- async launchProcess(agent) {
858
- const running = await this.listRunning();
859
- if (running.length >= this.maxConcurrent) {
860
- throw new Error(`Maximum concurrent agents (${this.maxConcurrent}) reached. Wait for an agent to complete or stop one first.`);
861
- }
862
- const effort = agent.effort ?? 'medium';
863
- // Falls back to the pinned model in agentConfigs; null means "let the
864
- // CLI pick its own default" (no --model flag forwarded). Effort is a
865
- // separate knob wired into buildReasoningFlags inside buildCommand.
866
- const resolvedModel = agent.model ?? this.agentConfigs[agent.agentType]?.model ?? null;
867
- const cmd = this.buildCommand(agent.agentType, agent.prompt, agent.mode, resolvedModel, agent.cwd, agent.agentId, effort);
868
- if (agent.version && cmd.length > 0) {
869
- cmd[0] = `${cmd[0]}@${agent.version}`;
870
- }
871
- debug(`Launching ${agent.agentType} agent ${agent.agentId} [${agent.mode}]: ${cmd.slice(0, 3).join(' ')}...`);
872
- try {
873
- const stdoutPath = await agent.getStdoutPath();
874
- const stdoutFile = await fs.open(stdoutPath, 'w');
875
- const stdoutFd = stdoutFile.fd;
876
- const childProcess = spawn(cmd[0], cmd.slice(1), {
877
- stdio: ['ignore', stdoutFd, stdoutFd],
878
- cwd: agent.cwd || undefined,
879
- detached: true,
880
- env: agent.envOverrides
881
- ? { ...process.env, ...agent.envOverrides }
882
- : process.env,
883
- });
884
- childProcess.unref();
885
- stdoutFile.close().catch(() => { });
886
- agent.pid = childProcess.pid || null;
887
- agent.status = AgentStatus.RUNNING;
888
- agent.startedAt = new Date();
889
- await agent.saveMeta();
890
- }
891
- catch (err) {
892
- await this.cleanupPartialAgent(agent);
893
- console.error(`Failed to spawn agent ${agent.agentId}:`, err);
894
- throw new Error(`Failed to spawn agent: ${err.message}`);
895
- }
896
- debug(`Launched agent ${agent.agentId} with PID ${agent.pid}`);
897
- }
898
- /**
899
- * Fire any pending teammates in the given team whose `after` deps have all
900
- * completed. Returns the list of teammates just launched. Repeatable:
901
- * call it once per DAG wave. Safe to call on teams with no pending work
902
- * (returns empty list).
903
- */
904
- async startReady(taskName) {
905
- await this.initialize();
906
- const teammates = await this.listByTask(taskName);
907
- const byName = new Map(teammates.filter((a) => a.name).map((a) => [a.name, a]));
908
- const launched = [];
909
- for (const agent of teammates) {
910
- if (agent.status !== AgentStatus.PENDING)
911
- continue;
912
- const depsReady = agent.after.every((depName) => {
913
- const dep = byName.get(depName);
914
- return dep && dep.status === AgentStatus.COMPLETED;
915
- });
916
- if (!depsReady)
917
- continue;
918
- try {
919
- if (agent.cloudProvider) {
920
- if (!this.cloudDispatcher) {
921
- console.error(`Cannot start cloud-backed teammate ${agent.agentId}: no dispatcher registered.`);
922
- continue;
923
- }
924
- const { cloudSessionId } = await this.cloudDispatcher(agent);
925
- agent.cloudSessionId = cloudSessionId;
926
- agent.status = AgentStatus.RUNNING;
927
- agent.startedAt = new Date();
928
- await agent.saveMeta();
929
- launched.push(agent);
930
- }
931
- else {
932
- await this.launchProcess(agent);
933
- launched.push(agent);
934
- }
935
- }
936
- catch (err) {
937
- console.error(`Could not launch ${agent.agentId}:`, err);
938
- }
939
- }
940
- return launched;
941
- }
942
- buildCommand(agentType, prompt, mode, model, cwd = null, sessionId = null, effort = 'medium') {
943
- const cmdTemplate = AGENT_COMMANDS[agentType];
944
- if (!cmdTemplate) {
945
- throw new Error(`Unknown agent type: ${agentType}`);
946
- }
947
- const isEditMode = mode === 'edit';
948
- // Build the full prompt with prefix (for plan mode) and suffix
949
- let fullPrompt = prompt + PROMPT_SUFFIX;
950
- // For Claude in plan mode, add prefix explaining headless plan mode restrictions
951
- if (agentType === 'claude' && !isEditMode) {
952
- fullPrompt = CLAUDE_PLAN_MODE_PREFIX + fullPrompt;
953
- }
954
- let cmd = cmdTemplate.map(part => part.replace('{prompt}', fullPrompt));
955
- if (agentType === 'claude') {
956
- // Grant access to the working directory.
957
- if (cwd) {
958
- cmd.push('--add-dir', cwd);
959
- }
960
- // Pin Claude's session UUID to our agent_id so the session file lands
961
- // at ~/.claude/projects/.../<agent_id>.jsonl — unified identity.
962
- if (sessionId) {
963
- cmd.push('--session-id', sessionId);
964
- }
965
- // Note: we deliberately do NOT pass --settings here. The agents-cli
966
- // shim exports CLAUDE_CONFIG_DIR scoped to the version being spawned,
967
- // which makes Claude read settings.json, commands/, skills/, hooks/,
968
- // and MCP config from that version's home. Passing a fixed
969
- // ~/.claude/settings.json would override that and bind settings to the
970
- // *default* version rather than the one this teammate is running.
971
- }
972
- // Add model flag for each agent type only when the teammate has a pinned
973
- // model. When null, the agent's CLI picks its own default.
974
- if (model) {
975
- if (agentType === 'codex') {
976
- const execIndex = cmd.indexOf('exec');
977
- const sandboxIndex = cmd.indexOf('--sandbox');
978
- const insertIndex = sandboxIndex !== -1 ? sandboxIndex : execIndex + 1;
979
- cmd.splice(insertIndex, 0, '--model', model);
980
- }
981
- else if (agentType === 'cursor') {
982
- cmd.push('--model', model);
983
- }
984
- else if (agentType === 'gemini' || agentType === 'claude') {
985
- cmd.push('--model', model);
986
- }
987
- else if (agentType === 'opencode') {
988
- cmd.push('--model', model);
989
- }
990
- }
991
- if (agentType === 'opencode') {
992
- const opencodeAgent = mode === 'edit' || mode === 'full' ? 'build' : 'plan';
993
- const promptIndex = cmd.indexOf(fullPrompt);
994
- if (promptIndex !== -1) {
995
- cmd.splice(promptIndex + 1, 0, '--agent', opencodeAgent);
996
- }
997
- }
998
- // Inject reasoning-intensity flags for agents that support them. Claude
999
- // gets --effort appended; Codex gets `-c model_reasoning_effort=...`
1000
- // inserted before `exec` so it's parsed as a global config override.
1001
- const reasoningFlags = buildReasoningFlags(agentType, effort);
1002
- if (reasoningFlags.length > 0) {
1003
- if (agentType === 'codex') {
1004
- const execIndex = cmd.indexOf('exec');
1005
- const insertIndex = execIndex !== -1 ? execIndex : 1;
1006
- cmd.splice(insertIndex, 0, ...reasoningFlags);
1007
- }
1008
- else {
1009
- cmd.push(...reasoningFlags);
1010
- }
1011
- }
1012
- if (mode === 'full') {
1013
- cmd = this.applyFullMode(agentType, cmd);
1014
- }
1015
- else if (isEditMode) {
1016
- cmd = this.applyEditMode(agentType, cmd);
1017
- }
1018
- return cmd;
1019
- }
1020
- applyEditMode(agentType, cmd) {
1021
- const editCmd = [...cmd];
1022
- switch (agentType) {
1023
- case 'codex':
1024
- editCmd.push('--full-auto');
1025
- break;
1026
- case 'cursor':
1027
- editCmd.push('-f');
1028
- break;
1029
- case 'gemini': {
1030
- const approvalIndex = editCmd.indexOf('--approval-mode');
1031
- if (approvalIndex !== -1) {
1032
- editCmd.splice(approvalIndex, 2);
1033
- }
1034
- editCmd.push('--yolo');
1035
- break;
1036
- }
1037
- case 'claude':
1038
- const permModeIndex = editCmd.indexOf('--permission-mode');
1039
- if (permModeIndex !== -1 && permModeIndex + 1 < editCmd.length) {
1040
- editCmd[permModeIndex + 1] = 'acceptEdits';
1041
- }
1042
- break;
1043
- }
1044
- return editCmd;
1045
- }
1046
- // "full" mode: edit-level write access with permission gates bypassed.
1047
- // For Claude that's --dangerously-skip-permissions; other agents already
1048
- // lack gates in edit mode so their commands match applyEditMode.
1049
- applyFullMode(agentType, cmd) {
1050
- const fullCmd = [...cmd];
1051
- switch (agentType) {
1052
- case 'codex':
1053
- fullCmd.push('--full-auto');
1054
- break;
1055
- case 'cursor':
1056
- fullCmd.push('-f');
1057
- break;
1058
- case 'gemini': {
1059
- const approvalIndex = fullCmd.indexOf('--approval-mode');
1060
- if (approvalIndex !== -1) {
1061
- fullCmd.splice(approvalIndex, 2);
1062
- }
1063
- fullCmd.push('--yolo');
1064
- break;
1065
- }
1066
- case 'claude':
1067
- // Replace --permission-mode plan with --dangerously-skip-permissions
1068
- const permModeIndex = fullCmd.indexOf('--permission-mode');
1069
- if (permModeIndex !== -1) {
1070
- fullCmd.splice(permModeIndex, 2); // Remove --permission-mode and its value
1071
- }
1072
- fullCmd.push('--dangerously-skip-permissions');
1073
- break;
1074
- }
1075
- return fullCmd;
1076
- }
1077
- async get(agentId) {
1078
- await this.initialize();
1079
- let agent = this.agents.get(agentId) || null;
1080
- if (agent) {
1081
- await agent.readNewEvents();
1082
- await agent.updateStatusFromProcess();
1083
- return agent;
1084
- }
1085
- agent = await AgentProcess.loadFromDisk(agentId, this.agentsDir);
1086
- if (agent) {
1087
- await agent.readNewEvents();
1088
- await agent.updateStatusFromProcess();
1089
- this.agents.set(agentId, agent);
1090
- return agent;
1091
- }
1092
- return null;
1093
- }
1094
- /**
1095
- * Resolve a teammate reference to a single agent_id within a team.
1096
- * Accepts (in priority order):
1097
- * 1. exact teammate name ("alice")
1098
- * 2. exact UUID ("b2438499-dc25-4a5e-9e02-9916012580b8")
1099
- * 3. UUID prefix, if unique ("b2438499")
1100
- *
1101
- * Returns:
1102
- * - { kind: 'ok', agentId } when exactly one teammate matches
1103
- * - { kind: 'none' } when nothing matches
1104
- * - { kind: 'ambiguous', matches } when the prefix matches multiple ids
1105
- */
1106
- async resolveAgentIdInTask(taskName, ref) {
1107
- const agents = await this.listByTask(taskName);
1108
- const byName = agents.find((a) => a.name === ref);
1109
- if (byName)
1110
- return { kind: 'ok', agentId: byName.agentId };
1111
- const exact = agents.find((a) => a.agentId === ref);
1112
- if (exact)
1113
- return { kind: 'ok', agentId: exact.agentId };
1114
- const prefix = agents.filter((a) => a.agentId.startsWith(ref));
1115
- if (prefix.length === 1)
1116
- return { kind: 'ok', agentId: prefix[0].agentId };
1117
- if (prefix.length === 0)
1118
- return { kind: 'none' };
1119
- return { kind: 'ambiguous', matches: prefix.map((a) => a.agentId) };
1120
- }
1121
- async listAll() {
1122
- await this.initialize();
1123
- const agents = Array.from(this.agents.values());
1124
- for (const agent of agents) {
1125
- await agent.readNewEvents();
1126
- await agent.updateStatusFromProcess();
1127
- await this.maybeFireCompletionHook(agent);
1128
- }
1129
- return agents;
1130
- }
1131
- /**
1132
- * Fire the completion hook exactly once per teammate when it transitions
1133
- * into a terminal state. Errors are logged but never thrown — a ledger
1134
- * backend outage must not break status polling.
1135
- */
1136
- async maybeFireCompletionHook(agent) {
1137
- if (!this.completionHook)
1138
- return;
1139
- const terminal = agent.status === AgentStatus.COMPLETED ||
1140
- agent.status === AgentStatus.FAILED ||
1141
- agent.status === AgentStatus.STOPPED;
1142
- if (!terminal)
1143
- return;
1144
- if (this.syncedAgents.has(agent.agentId))
1145
- return;
1146
- this.syncedAgents.add(agent.agentId);
1147
- try {
1148
- await this.completionHook(agent);
1149
- }
1150
- catch (err) {
1151
- console.warn(`[ledger sync] completion hook failed for ${agent.agentId}:`, err);
1152
- }
1153
- }
1154
- async listRunning() {
1155
- const all = await this.listAll();
1156
- return all.filter(a => a.status === AgentStatus.RUNNING);
1157
- }
1158
- async listCompleted() {
1159
- const all = await this.listAll();
1160
- return all.filter(a => a.status !== AgentStatus.RUNNING);
1161
- }
1162
- async listByTask(taskName) {
1163
- const all = await this.listAll();
1164
- return all.filter(a => a.taskName === taskName);
1165
- }
1166
- async listByParentSession(parentSessionId) {
1167
- const all = await this.listAll();
1168
- return all.filter(a => a.parentSessionId === parentSessionId);
1169
- }
1170
- async stopByTask(taskName) {
1171
- const agents = await this.listByTask(taskName);
1172
- const stopped = [];
1173
- const alreadyStopped = [];
1174
- for (const agent of agents) {
1175
- if (agent.status === AgentStatus.RUNNING) {
1176
- const success = await this.stop(agent.agentId);
1177
- if (success) {
1178
- stopped.push(agent.agentId);
1179
- }
1180
- }
1181
- else {
1182
- alreadyStopped.push(agent.agentId);
1183
- }
1184
- }
1185
- return { stopped, alreadyStopped };
1186
- }
1187
- async stop(agentId) {
1188
- await this.initialize();
1189
- const agent = this.agents.get(agentId);
1190
- if (!agent) {
1191
- return false;
1192
- }
1193
- if (agent.pid && agent.status === AgentStatus.RUNNING) {
1194
- try {
1195
- process.kill(-agent.pid, 'SIGTERM');
1196
- debug(`Sent SIGTERM to agent ${agentId} (PID ${agent.pid})`);
1197
- await new Promise(resolve => setTimeout(resolve, 2000));
1198
- if (agent.isProcessAlive()) {
1199
- process.kill(-agent.pid, 'SIGKILL');
1200
- debug(`Sent SIGKILL to agent ${agentId}`);
1201
- }
1202
- }
1203
- catch {
1204
- }
1205
- agent.status = AgentStatus.STOPPED;
1206
- agent.completedAt = new Date();
1207
- await agent.saveMeta();
1208
- debug(`Stopped agent ${agentId}`);
1209
- return true;
1210
- }
1211
- return false;
1212
- }
1213
- async cleanupPartialAgent(agent) {
1214
- this.agents.delete(agent.agentId);
1215
- try {
1216
- const agentDir = await agent.getAgentDir();
1217
- await fs.rm(agentDir, { recursive: true });
1218
- }
1219
- catch (err) {
1220
- console.warn(`Failed to clean up agent directory:`, err);
1221
- }
1222
- }
1223
- async cleanupOldAgents() {
1224
- const completed = await this.listCompleted();
1225
- if (completed.length > this.maxAgents) {
1226
- completed.sort((a, b) => {
1227
- const aTime = a.completedAt?.getTime() || 0;
1228
- const bTime = b.completedAt?.getTime() || 0;
1229
- return aTime - bTime;
1230
- });
1231
- for (const agent of completed.slice(0, completed.length - this.maxAgents)) {
1232
- this.agents.delete(agent.agentId);
1233
- try {
1234
- const agentDir = await agent.getAgentDir();
1235
- await fs.rm(agentDir, { recursive: true });
1236
- }
1237
- catch (err) {
1238
- console.warn(`Failed to cleanup old agent ${agent.agentId}:`, err);
1239
- }
1240
- }
1241
- }
1242
- }
1243
- }
1244
- //# sourceMappingURL=agents.js.map