@phnx-labs/agents-cli 0.1.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 (486) hide show
  1. package/CHANGELOG.md +316 -0
  2. package/LICENSE +21 -0
  3. package/README.md +537 -0
  4. package/dist/commands/__tests__/sessions.test.d.ts +2 -0
  5. package/dist/commands/__tests__/sessions.test.d.ts.map +1 -0
  6. package/dist/commands/__tests__/sessions.test.js +636 -0
  7. package/dist/commands/__tests__/sessions.test.js.map +1 -0
  8. package/dist/commands/cloud.d.ts +3 -0
  9. package/dist/commands/cloud.d.ts.map +1 -0
  10. package/dist/commands/cloud.js +322 -0
  11. package/dist/commands/cloud.js.map +1 -0
  12. package/dist/commands/commands.d.ts +3 -0
  13. package/dist/commands/commands.d.ts.map +1 -0
  14. package/dist/commands/commands.js +628 -0
  15. package/dist/commands/commands.js.map +1 -0
  16. package/dist/commands/daemon.d.ts +3 -0
  17. package/dist/commands/daemon.d.ts.map +1 -0
  18. package/dist/commands/daemon.js +110 -0
  19. package/dist/commands/daemon.js.map +1 -0
  20. package/dist/commands/drive.d.ts +3 -0
  21. package/dist/commands/drive.d.ts.map +1 -0
  22. package/dist/commands/drive.js +166 -0
  23. package/dist/commands/drive.js.map +1 -0
  24. package/dist/commands/exec.d.ts +3 -0
  25. package/dist/commands/exec.d.ts.map +1 -0
  26. package/dist/commands/exec.js +241 -0
  27. package/dist/commands/exec.js.map +1 -0
  28. package/dist/commands/fork.d.ts +3 -0
  29. package/dist/commands/fork.d.ts.map +1 -0
  30. package/dist/commands/fork.js +139 -0
  31. package/dist/commands/fork.js.map +1 -0
  32. package/dist/commands/hooks.d.ts +3 -0
  33. package/dist/commands/hooks.d.ts.map +1 -0
  34. package/dist/commands/hooks.js +689 -0
  35. package/dist/commands/hooks.js.map +1 -0
  36. package/dist/commands/init.d.ts +6 -0
  37. package/dist/commands/init.d.ts.map +1 -0
  38. package/dist/commands/init.js +127 -0
  39. package/dist/commands/init.js.map +1 -0
  40. package/dist/commands/mcp.d.ts +3 -0
  41. package/dist/commands/mcp.d.ts.map +1 -0
  42. package/dist/commands/mcp.js +581 -0
  43. package/dist/commands/mcp.js.map +1 -0
  44. package/dist/commands/models.d.ts +3 -0
  45. package/dist/commands/models.d.ts.map +1 -0
  46. package/dist/commands/models.js +158 -0
  47. package/dist/commands/models.js.map +1 -0
  48. package/dist/commands/packages.d.ts +3 -0
  49. package/dist/commands/packages.d.ts.map +1 -0
  50. package/dist/commands/packages.js +541 -0
  51. package/dist/commands/packages.js.map +1 -0
  52. package/dist/commands/permissions.d.ts +3 -0
  53. package/dist/commands/permissions.d.ts.map +1 -0
  54. package/dist/commands/permissions.js +723 -0
  55. package/dist/commands/permissions.js.map +1 -0
  56. package/dist/commands/plugins.d.ts +3 -0
  57. package/dist/commands/plugins.d.ts.map +1 -0
  58. package/dist/commands/plugins.js +382 -0
  59. package/dist/commands/plugins.js.map +1 -0
  60. package/dist/commands/profiles.d.ts +3 -0
  61. package/dist/commands/profiles.d.ts.map +1 -0
  62. package/dist/commands/profiles.js +242 -0
  63. package/dist/commands/profiles.js.map +1 -0
  64. package/dist/commands/pty.d.ts +20 -0
  65. package/dist/commands/pty.d.ts.map +1 -0
  66. package/dist/commands/pty.js +389 -0
  67. package/dist/commands/pty.js.map +1 -0
  68. package/dist/commands/pull.d.ts +3 -0
  69. package/dist/commands/pull.d.ts.map +1 -0
  70. package/dist/commands/pull.js +448 -0
  71. package/dist/commands/pull.js.map +1 -0
  72. package/dist/commands/push.d.ts +3 -0
  73. package/dist/commands/push.d.ts.map +1 -0
  74. package/dist/commands/push.js +180 -0
  75. package/dist/commands/push.js.map +1 -0
  76. package/dist/commands/refresh-memory.d.ts +9 -0
  77. package/dist/commands/refresh-memory.d.ts.map +1 -0
  78. package/dist/commands/refresh-memory.js +45 -0
  79. package/dist/commands/refresh-memory.js.map +1 -0
  80. package/dist/commands/resource-view.d.ts +31 -0
  81. package/dist/commands/resource-view.d.ts.map +1 -0
  82. package/dist/commands/resource-view.js +183 -0
  83. package/dist/commands/resource-view.js.map +1 -0
  84. package/dist/commands/routines.d.ts +3 -0
  85. package/dist/commands/routines.d.ts.map +1 -0
  86. package/dist/commands/routines.js +579 -0
  87. package/dist/commands/routines.js.map +1 -0
  88. package/dist/commands/rules.d.ts +3 -0
  89. package/dist/commands/rules.d.ts.map +1 -0
  90. package/dist/commands/rules.js +488 -0
  91. package/dist/commands/rules.js.map +1 -0
  92. package/dist/commands/secrets.d.ts +3 -0
  93. package/dist/commands/secrets.d.ts.map +1 -0
  94. package/dist/commands/secrets.js +339 -0
  95. package/dist/commands/secrets.js.map +1 -0
  96. package/dist/commands/sessions-picker.d.ts +16 -0
  97. package/dist/commands/sessions-picker.d.ts.map +1 -0
  98. package/dist/commands/sessions-picker.js +256 -0
  99. package/dist/commands/sessions-picker.js.map +1 -0
  100. package/dist/commands/sessions.d.ts +16 -0
  101. package/dist/commands/sessions.d.ts.map +1 -0
  102. package/dist/commands/sessions.js +1077 -0
  103. package/dist/commands/sessions.js.map +1 -0
  104. package/dist/commands/skills.d.ts +3 -0
  105. package/dist/commands/skills.d.ts.map +1 -0
  106. package/dist/commands/skills.js +716 -0
  107. package/dist/commands/skills.js.map +1 -0
  108. package/dist/commands/status.d.ts +3 -0
  109. package/dist/commands/status.d.ts.map +1 -0
  110. package/dist/commands/status.js +19 -0
  111. package/dist/commands/status.js.map +1 -0
  112. package/dist/commands/subagents.d.ts +3 -0
  113. package/dist/commands/subagents.d.ts.map +1 -0
  114. package/dist/commands/subagents.js +350 -0
  115. package/dist/commands/subagents.js.map +1 -0
  116. package/dist/commands/sync.d.ts +3 -0
  117. package/dist/commands/sync.d.ts.map +1 -0
  118. package/dist/commands/sync.js +62 -0
  119. package/dist/commands/sync.js.map +1 -0
  120. package/dist/commands/teams-picker.d.ts +14 -0
  121. package/dist/commands/teams-picker.d.ts.map +1 -0
  122. package/dist/commands/teams-picker.js +278 -0
  123. package/dist/commands/teams-picker.js.map +1 -0
  124. package/dist/commands/teams.d.ts +3 -0
  125. package/dist/commands/teams.d.ts.map +1 -0
  126. package/dist/commands/teams.js +917 -0
  127. package/dist/commands/teams.js.map +1 -0
  128. package/dist/commands/utils.d.ts +39 -0
  129. package/dist/commands/utils.d.ts.map +1 -0
  130. package/dist/commands/utils.js +100 -0
  131. package/dist/commands/utils.js.map +1 -0
  132. package/dist/commands/versions.d.ts +3 -0
  133. package/dist/commands/versions.d.ts.map +1 -0
  134. package/dist/commands/versions.js +700 -0
  135. package/dist/commands/versions.js.map +1 -0
  136. package/dist/commands/view.d.ts +8 -0
  137. package/dist/commands/view.d.ts.map +1 -0
  138. package/dist/commands/view.js +626 -0
  139. package/dist/commands/view.js.map +1 -0
  140. package/dist/index.d.ts +3 -0
  141. package/dist/index.d.ts.map +1 -0
  142. package/dist/index.js +484 -0
  143. package/dist/index.js.map +1 -0
  144. package/dist/lib/__tests__/bugfixes.test.d.ts +2 -0
  145. package/dist/lib/__tests__/bugfixes.test.d.ts.map +1 -0
  146. package/dist/lib/__tests__/bugfixes.test.js +192 -0
  147. package/dist/lib/__tests__/bugfixes.test.js.map +1 -0
  148. package/dist/lib/__tests__/exec.test.d.ts +2 -0
  149. package/dist/lib/__tests__/exec.test.d.ts.map +1 -0
  150. package/dist/lib/__tests__/exec.test.js +446 -0
  151. package/dist/lib/__tests__/exec.test.js.map +1 -0
  152. package/dist/lib/__tests__/git-sync.test.d.ts +2 -0
  153. package/dist/lib/__tests__/git-sync.test.d.ts.map +1 -0
  154. package/dist/lib/__tests__/git-sync.test.js +138 -0
  155. package/dist/lib/__tests__/git-sync.test.js.map +1 -0
  156. package/dist/lib/__tests__/hooks.test.d.ts +2 -0
  157. package/dist/lib/__tests__/hooks.test.d.ts.map +1 -0
  158. package/dist/lib/__tests__/hooks.test.js +203 -0
  159. package/dist/lib/__tests__/hooks.test.js.map +1 -0
  160. package/dist/lib/__tests__/memory-compile.test.d.ts +2 -0
  161. package/dist/lib/__tests__/memory-compile.test.d.ts.map +1 -0
  162. package/dist/lib/__tests__/memory-compile.test.js +95 -0
  163. package/dist/lib/__tests__/memory-compile.test.js.map +1 -0
  164. package/dist/lib/__tests__/models.test.d.ts +2 -0
  165. package/dist/lib/__tests__/models.test.d.ts.map +1 -0
  166. package/dist/lib/__tests__/models.test.js +239 -0
  167. package/dist/lib/__tests__/models.test.js.map +1 -0
  168. package/dist/lib/__tests__/rotate.test.d.ts +2 -0
  169. package/dist/lib/__tests__/rotate.test.d.ts.map +1 -0
  170. package/dist/lib/__tests__/rotate.test.js +80 -0
  171. package/dist/lib/__tests__/rotate.test.js.map +1 -0
  172. package/dist/lib/__tests__/secrets-bundles.test.d.ts +2 -0
  173. package/dist/lib/__tests__/secrets-bundles.test.d.ts.map +1 -0
  174. package/dist/lib/__tests__/secrets-bundles.test.js +104 -0
  175. package/dist/lib/__tests__/secrets-bundles.test.js.map +1 -0
  176. package/dist/lib/__tests__/secrets.test.d.ts +2 -0
  177. package/dist/lib/__tests__/secrets.test.d.ts.map +1 -0
  178. package/dist/lib/__tests__/secrets.test.js +90 -0
  179. package/dist/lib/__tests__/secrets.test.js.map +1 -0
  180. package/dist/lib/__tests__/shims.test.d.ts +2 -0
  181. package/dist/lib/__tests__/shims.test.d.ts.map +1 -0
  182. package/dist/lib/__tests__/shims.test.js +39 -0
  183. package/dist/lib/__tests__/shims.test.js.map +1 -0
  184. package/dist/lib/__tests__/usage.test.d.ts +2 -0
  185. package/dist/lib/__tests__/usage.test.d.ts.map +1 -0
  186. package/dist/lib/__tests__/usage.test.js +220 -0
  187. package/dist/lib/__tests__/usage.test.js.map +1 -0
  188. package/dist/lib/__tests__/versions.test.d.ts +2 -0
  189. package/dist/lib/__tests__/versions.test.d.ts.map +1 -0
  190. package/dist/lib/__tests__/versions.test.js +63 -0
  191. package/dist/lib/__tests__/versions.test.js.map +1 -0
  192. package/dist/lib/agents.d.ts +107 -0
  193. package/dist/lib/agents.d.ts.map +1 -0
  194. package/dist/lib/agents.js +1096 -0
  195. package/dist/lib/agents.js.map +1 -0
  196. package/dist/lib/artifact-actions.d.ts +22 -0
  197. package/dist/lib/artifact-actions.d.ts.map +1 -0
  198. package/dist/lib/artifact-actions.js +55 -0
  199. package/dist/lib/artifact-actions.js.map +1 -0
  200. package/dist/lib/cloud/codex.d.ts +19 -0
  201. package/dist/lib/cloud/codex.d.ts.map +1 -0
  202. package/dist/lib/cloud/codex.js +210 -0
  203. package/dist/lib/cloud/codex.js.map +1 -0
  204. package/dist/lib/cloud/factory.d.ts +26 -0
  205. package/dist/lib/cloud/factory.d.ts.map +1 -0
  206. package/dist/lib/cloud/factory.js +37 -0
  207. package/dist/lib/cloud/factory.js.map +1 -0
  208. package/dist/lib/cloud/registry.d.ts +6 -0
  209. package/dist/lib/cloud/registry.d.ts.map +1 -0
  210. package/dist/lib/cloud/registry.js +56 -0
  211. package/dist/lib/cloud/registry.js.map +1 -0
  212. package/dist/lib/cloud/rush.d.ts +15 -0
  213. package/dist/lib/cloud/rush.d.ts.map +1 -0
  214. package/dist/lib/cloud/rush.js +185 -0
  215. package/dist/lib/cloud/rush.js.map +1 -0
  216. package/dist/lib/cloud/store.d.ts +10 -0
  217. package/dist/lib/cloud/store.d.ts.map +1 -0
  218. package/dist/lib/cloud/store.js +96 -0
  219. package/dist/lib/cloud/store.js.map +1 -0
  220. package/dist/lib/cloud/stream.d.ts +18 -0
  221. package/dist/lib/cloud/stream.d.ts.map +1 -0
  222. package/dist/lib/cloud/stream.js +138 -0
  223. package/dist/lib/cloud/stream.js.map +1 -0
  224. package/dist/lib/cloud/types.d.ts +60 -0
  225. package/dist/lib/cloud/types.d.ts.map +1 -0
  226. package/dist/lib/cloud/types.js +2 -0
  227. package/dist/lib/cloud/types.js.map +1 -0
  228. package/dist/lib/commands.d.ts +121 -0
  229. package/dist/lib/commands.d.ts.map +1 -0
  230. package/dist/lib/commands.js +499 -0
  231. package/dist/lib/commands.js.map +1 -0
  232. package/dist/lib/convert.d.ts +11 -0
  233. package/dist/lib/convert.d.ts.map +1 -0
  234. package/dist/lib/convert.js +45 -0
  235. package/dist/lib/convert.js.map +1 -0
  236. package/dist/lib/daemon.d.ts +22 -0
  237. package/dist/lib/daemon.d.ts.map +1 -0
  238. package/dist/lib/daemon.js +311 -0
  239. package/dist/lib/daemon.js.map +1 -0
  240. package/dist/lib/drive-sync.d.ts +28 -0
  241. package/dist/lib/drive-sync.d.ts.map +1 -0
  242. package/dist/lib/drive-sync.js +193 -0
  243. package/dist/lib/drive-sync.js.map +1 -0
  244. package/dist/lib/exec.d.ts +85 -0
  245. package/dist/lib/exec.d.ts.map +1 -0
  246. package/dist/lib/exec.js +423 -0
  247. package/dist/lib/exec.js.map +1 -0
  248. package/dist/lib/factory.d.ts +57 -0
  249. package/dist/lib/factory.d.ts.map +1 -0
  250. package/dist/lib/factory.js +110 -0
  251. package/dist/lib/factory.js.map +1 -0
  252. package/dist/lib/git.d.ts +146 -0
  253. package/dist/lib/git.d.ts.map +1 -0
  254. package/dist/lib/git.js +635 -0
  255. package/dist/lib/git.js.map +1 -0
  256. package/dist/lib/help.d.ts +3 -0
  257. package/dist/lib/help.d.ts.map +1 -0
  258. package/dist/lib/help.js +63 -0
  259. package/dist/lib/help.js.map +1 -0
  260. package/dist/lib/hooks.d.ts +116 -0
  261. package/dist/lib/hooks.d.ts.map +1 -0
  262. package/dist/lib/hooks.js +837 -0
  263. package/dist/lib/hooks.js.map +1 -0
  264. package/dist/lib/manifest.d.ts +8 -0
  265. package/dist/lib/manifest.d.ts.map +1 -0
  266. package/dist/lib/manifest.js +36 -0
  267. package/dist/lib/manifest.js.map +1 -0
  268. package/dist/lib/markdown.d.ts +5 -0
  269. package/dist/lib/markdown.d.ts.map +1 -0
  270. package/dist/lib/markdown.js +11 -0
  271. package/dist/lib/markdown.js.map +1 -0
  272. package/dist/lib/mcp.d.ts +64 -0
  273. package/dist/lib/mcp.d.ts.map +1 -0
  274. package/dist/lib/mcp.js +327 -0
  275. package/dist/lib/mcp.js.map +1 -0
  276. package/dist/lib/memory-compile.d.ts +56 -0
  277. package/dist/lib/memory-compile.d.ts.map +1 -0
  278. package/dist/lib/memory-compile.js +167 -0
  279. package/dist/lib/memory-compile.js.map +1 -0
  280. package/dist/lib/memory.d.ts +56 -0
  281. package/dist/lib/memory.d.ts.map +1 -0
  282. package/dist/lib/memory.js +267 -0
  283. package/dist/lib/memory.js.map +1 -0
  284. package/dist/lib/models.d.ts +91 -0
  285. package/dist/lib/models.d.ts.map +1 -0
  286. package/dist/lib/models.js +706 -0
  287. package/dist/lib/models.js.map +1 -0
  288. package/dist/lib/permissions.d.ts +204 -0
  289. package/dist/lib/permissions.d.ts.map +1 -0
  290. package/dist/lib/permissions.js +1022 -0
  291. package/dist/lib/permissions.js.map +1 -0
  292. package/dist/lib/picker.d.ts +17 -0
  293. package/dist/lib/picker.d.ts.map +1 -0
  294. package/dist/lib/picker.js +95 -0
  295. package/dist/lib/picker.js.map +1 -0
  296. package/dist/lib/plugins.d.ts +73 -0
  297. package/dist/lib/plugins.d.ts.map +1 -0
  298. package/dist/lib/plugins.js +549 -0
  299. package/dist/lib/plugins.js.map +1 -0
  300. package/dist/lib/profiles-keychain.d.ts +3 -0
  301. package/dist/lib/profiles-keychain.d.ts.map +1 -0
  302. package/dist/lib/profiles-keychain.js +10 -0
  303. package/dist/lib/profiles-keychain.js.map +1 -0
  304. package/dist/lib/profiles-presets.d.ts +15 -0
  305. package/dist/lib/profiles-presets.d.ts.map +1 -0
  306. package/dist/lib/profiles-presets.js +95 -0
  307. package/dist/lib/profiles-presets.js.map +1 -0
  308. package/dist/lib/profiles.d.ts +35 -0
  309. package/dist/lib/profiles.d.ts.map +1 -0
  310. package/dist/lib/profiles.js +123 -0
  311. package/dist/lib/profiles.js.map +1 -0
  312. package/dist/lib/pty-client.d.ts +22 -0
  313. package/dist/lib/pty-client.d.ts.map +1 -0
  314. package/dist/lib/pty-client.js +181 -0
  315. package/dist/lib/pty-client.js.map +1 -0
  316. package/dist/lib/pty-server.d.ts +16 -0
  317. package/dist/lib/pty-server.d.ts.map +1 -0
  318. package/dist/lib/pty-server.js +422 -0
  319. package/dist/lib/pty-server.js.map +1 -0
  320. package/dist/lib/registry.d.ts +28 -0
  321. package/dist/lib/registry.d.ts.map +1 -0
  322. package/dist/lib/registry.js +203 -0
  323. package/dist/lib/registry.js.map +1 -0
  324. package/dist/lib/resources.d.ts +50 -0
  325. package/dist/lib/resources.d.ts.map +1 -0
  326. package/dist/lib/resources.js +103 -0
  327. package/dist/lib/resources.js.map +1 -0
  328. package/dist/lib/rotate.d.ts +52 -0
  329. package/dist/lib/rotate.d.ts.map +1 -0
  330. package/dist/lib/rotate.js +87 -0
  331. package/dist/lib/rotate.js.map +1 -0
  332. package/dist/lib/routines.d.ts +70 -0
  333. package/dist/lib/routines.d.ts.map +1 -0
  334. package/dist/lib/routines.js +325 -0
  335. package/dist/lib/routines.js.map +1 -0
  336. package/dist/lib/runner.d.ts +12 -0
  337. package/dist/lib/runner.d.ts.map +1 -0
  338. package/dist/lib/runner.js +311 -0
  339. package/dist/lib/runner.js.map +1 -0
  340. package/dist/lib/sandbox.d.ts +10 -0
  341. package/dist/lib/sandbox.d.ts.map +1 -0
  342. package/dist/lib/sandbox.js +201 -0
  343. package/dist/lib/sandbox.js.map +1 -0
  344. package/dist/lib/scheduler.d.ts +18 -0
  345. package/dist/lib/scheduler.d.ts.map +1 -0
  346. package/dist/lib/scheduler.js +69 -0
  347. package/dist/lib/scheduler.js.map +1 -0
  348. package/dist/lib/secrets-bundles.d.ts +29 -0
  349. package/dist/lib/secrets-bundles.d.ts.map +1 -0
  350. package/dist/lib/secrets-bundles.js +168 -0
  351. package/dist/lib/secrets-bundles.js.map +1 -0
  352. package/dist/lib/secrets.d.ts +27 -0
  353. package/dist/lib/secrets.d.ts.map +1 -0
  354. package/dist/lib/secrets.js +127 -0
  355. package/dist/lib/secrets.js.map +1 -0
  356. package/dist/lib/session/__tests__/db.test.d.ts +2 -0
  357. package/dist/lib/session/__tests__/db.test.d.ts.map +1 -0
  358. package/dist/lib/session/__tests__/db.test.js +54 -0
  359. package/dist/lib/session/__tests__/db.test.js.map +1 -0
  360. package/dist/lib/session/__tests__/discover.test.d.ts +2 -0
  361. package/dist/lib/session/__tests__/discover.test.d.ts.map +1 -0
  362. package/dist/lib/session/__tests__/discover.test.js +63 -0
  363. package/dist/lib/session/__tests__/discover.test.js.map +1 -0
  364. package/dist/lib/session/__tests__/prompt.test.d.ts +2 -0
  365. package/dist/lib/session/__tests__/prompt.test.d.ts.map +1 -0
  366. package/dist/lib/session/__tests__/prompt.test.js +44 -0
  367. package/dist/lib/session/__tests__/prompt.test.js.map +1 -0
  368. package/dist/lib/session/__tests__/render.test.d.ts +2 -0
  369. package/dist/lib/session/__tests__/render.test.d.ts.map +1 -0
  370. package/dist/lib/session/__tests__/render.test.js +602 -0
  371. package/dist/lib/session/__tests__/render.test.js.map +1 -0
  372. package/dist/lib/session/artifacts.d.ts +5 -0
  373. package/dist/lib/session/artifacts.d.ts.map +1 -0
  374. package/dist/lib/session/artifacts.js +75 -0
  375. package/dist/lib/session/artifacts.js.map +1 -0
  376. package/dist/lib/session/db.d.ts +118 -0
  377. package/dist/lib/session/db.d.ts.map +1 -0
  378. package/dist/lib/session/db.js +576 -0
  379. package/dist/lib/session/db.js.map +1 -0
  380. package/dist/lib/session/discover.d.ts +60 -0
  381. package/dist/lib/session/discover.d.ts.map +1 -0
  382. package/dist/lib/session/discover.js +1272 -0
  383. package/dist/lib/session/discover.js.map +1 -0
  384. package/dist/lib/session/parse.d.ts +23 -0
  385. package/dist/lib/session/parse.d.ts.map +1 -0
  386. package/dist/lib/session/parse.js +650 -0
  387. package/dist/lib/session/parse.js.map +1 -0
  388. package/dist/lib/session/prompt.d.ts +4 -0
  389. package/dist/lib/session/prompt.d.ts.map +1 -0
  390. package/dist/lib/session/prompt.js +64 -0
  391. package/dist/lib/session/prompt.js.map +1 -0
  392. package/dist/lib/session/prompt.test.d.ts +2 -0
  393. package/dist/lib/session/prompt.test.d.ts.map +1 -0
  394. package/dist/lib/session/prompt.test.js +57 -0
  395. package/dist/lib/session/prompt.test.js.map +1 -0
  396. package/dist/lib/session/render.d.ts +90 -0
  397. package/dist/lib/session/render.d.ts.map +1 -0
  398. package/dist/lib/session/render.js +778 -0
  399. package/dist/lib/session/render.js.map +1 -0
  400. package/dist/lib/session/team-filter.d.ts +26 -0
  401. package/dist/lib/session/team-filter.d.ts.map +1 -0
  402. package/dist/lib/session/team-filter.js +66 -0
  403. package/dist/lib/session/team-filter.js.map +1 -0
  404. package/dist/lib/session/team-filter.test.d.ts +2 -0
  405. package/dist/lib/session/team-filter.test.d.ts.map +1 -0
  406. package/dist/lib/session/team-filter.test.js +157 -0
  407. package/dist/lib/session/team-filter.test.js.map +1 -0
  408. package/dist/lib/session/types.d.ts +69 -0
  409. package/dist/lib/session/types.d.ts.map +1 -0
  410. package/dist/lib/session/types.js +2 -0
  411. package/dist/lib/session/types.js.map +1 -0
  412. package/dist/lib/shims.d.ts +228 -0
  413. package/dist/lib/shims.d.ts.map +1 -0
  414. package/dist/lib/shims.js +1170 -0
  415. package/dist/lib/shims.js.map +1 -0
  416. package/dist/lib/skills.d.ts +134 -0
  417. package/dist/lib/skills.d.ts.map +1 -0
  418. package/dist/lib/skills.js +783 -0
  419. package/dist/lib/skills.js.map +1 -0
  420. package/dist/lib/state.d.ts +53 -0
  421. package/dist/lib/state.d.ts.map +1 -0
  422. package/dist/lib/state.js +299 -0
  423. package/dist/lib/state.js.map +1 -0
  424. package/dist/lib/subagents.d.ts +75 -0
  425. package/dist/lib/subagents.d.ts.map +1 -0
  426. package/dist/lib/subagents.js +402 -0
  427. package/dist/lib/subagents.js.map +1 -0
  428. package/dist/lib/teams/agents.d.ts +146 -0
  429. package/dist/lib/teams/agents.d.ts.map +1 -0
  430. package/dist/lib/teams/agents.js +1072 -0
  431. package/dist/lib/teams/agents.js.map +1 -0
  432. package/dist/lib/teams/api.d.ts +77 -0
  433. package/dist/lib/teams/api.d.ts.map +1 -0
  434. package/dist/lib/teams/api.js +229 -0
  435. package/dist/lib/teams/api.js.map +1 -0
  436. package/dist/lib/teams/cloud.d.ts +11 -0
  437. package/dist/lib/teams/cloud.d.ts.map +1 -0
  438. package/dist/lib/teams/cloud.js +169 -0
  439. package/dist/lib/teams/cloud.js.map +1 -0
  440. package/dist/lib/teams/debug.d.ts +2 -0
  441. package/dist/lib/teams/debug.d.ts.map +1 -0
  442. package/dist/lib/teams/debug.js +6 -0
  443. package/dist/lib/teams/debug.js.map +1 -0
  444. package/dist/lib/teams/file_ops.d.ts +6 -0
  445. package/dist/lib/teams/file_ops.d.ts.map +1 -0
  446. package/dist/lib/teams/file_ops.js +59 -0
  447. package/dist/lib/teams/file_ops.js.map +1 -0
  448. package/dist/lib/teams/parsers.d.ts +5 -0
  449. package/dist/lib/teams/parsers.d.ts.map +1 -0
  450. package/dist/lib/teams/parsers.js +826 -0
  451. package/dist/lib/teams/parsers.js.map +1 -0
  452. package/dist/lib/teams/persistence.d.ts +28 -0
  453. package/dist/lib/teams/persistence.d.ts.map +1 -0
  454. package/dist/lib/teams/persistence.js +289 -0
  455. package/dist/lib/teams/persistence.js.map +1 -0
  456. package/dist/lib/teams/ralph.d.ts +8 -0
  457. package/dist/lib/teams/ralph.d.ts.map +1 -0
  458. package/dist/lib/teams/ralph.js +59 -0
  459. package/dist/lib/teams/ralph.js.map +1 -0
  460. package/dist/lib/teams/registry.d.ts +11 -0
  461. package/dist/lib/teams/registry.d.ts.map +1 -0
  462. package/dist/lib/teams/registry.js +56 -0
  463. package/dist/lib/teams/registry.js.map +1 -0
  464. package/dist/lib/teams/summarizer.d.ts +58 -0
  465. package/dist/lib/teams/summarizer.d.ts.map +1 -0
  466. package/dist/lib/teams/summarizer.js +766 -0
  467. package/dist/lib/teams/summarizer.js.map +1 -0
  468. package/dist/lib/template.d.ts +24 -0
  469. package/dist/lib/template.d.ts.map +1 -0
  470. package/dist/lib/template.js +57 -0
  471. package/dist/lib/template.js.map +1 -0
  472. package/dist/lib/types.d.ts +282 -0
  473. package/dist/lib/types.d.ts.map +1 -0
  474. package/dist/lib/types.js +18 -0
  475. package/dist/lib/types.js.map +1 -0
  476. package/dist/lib/usage.d.ts +73 -0
  477. package/dist/lib/usage.d.ts.map +1 -0
  478. package/dist/lib/usage.js +623 -0
  479. package/dist/lib/usage.js.map +1 -0
  480. package/dist/lib/versions.d.ts +248 -0
  481. package/dist/lib/versions.d.ts.map +1 -0
  482. package/dist/lib/versions.js +1737 -0
  483. package/dist/lib/versions.js.map +1 -0
  484. package/package.json +82 -0
  485. package/scripts/postinstall.js +72 -0
  486. package/scripts/rebuild-sqlite.sh +46 -0
@@ -0,0 +1,917 @@
1
+ import chalk from 'chalk';
2
+ import * as fs from 'fs/promises';
3
+ import * as path from 'path';
4
+ import { AgentManager, checkAllClis, getAgentsDir, } from '../lib/teams/agents.js';
5
+ import { handleSpawn, handleStatus, handleStop, handleTasks, } from '../lib/teams/api.js';
6
+ import { createTeam, ensureTeam, loadTeams, removeTeam, teamExists, } from '../lib/teams/registry.js';
7
+ import { isVersionInstalled } from '../lib/versions.js';
8
+ import { discoverSessions, parseTimeFilter, resolveSessionById } from '../lib/session/discover.js';
9
+ import { buildPreview as buildSessionPreview } from './sessions-picker.js';
10
+ import { parseExecEnv } from '../lib/exec.js';
11
+ import { teamPicker, printTeamTable } from './teams-picker.js';
12
+ import { itemPicker } from '../lib/picker.js';
13
+ import { isPromptCancelled, isInteractiveTerminal, requireDestructiveArg, requireInteractiveSelection, } from './utils.js';
14
+ const AGENT_NAMES = {
15
+ claude: 'Claude',
16
+ codex: 'Codex',
17
+ gemini: 'Gemini',
18
+ cursor: 'Cursor',
19
+ opencode: 'OpenCode',
20
+ };
21
+ const VALID_AGENTS = Object.keys(AGENT_NAMES);
22
+ const VALID_MODES = ['plan', 'edit', 'full'];
23
+ const VALID_EFFORTS = ['low', 'medium', 'high', 'xhigh', 'max', 'auto'];
24
+ // Auto-enable JSON mode when piped / not a TTY so AI agent consumers get
25
+ // parseable output by default.
26
+ function isJsonMode(opts) {
27
+ return Boolean(opts.json) || !process.stdout.isTTY;
28
+ }
29
+ function die(msg, code = 1) {
30
+ console.error(chalk.red(msg));
31
+ process.exit(code);
32
+ }
33
+ function statusColor(status) {
34
+ switch (status) {
35
+ case 'pending': return chalk.blue;
36
+ case 'running': return chalk.yellow;
37
+ case 'completed': return chalk.green;
38
+ case 'failed': return chalk.red;
39
+ case 'stopped': return chalk.gray;
40
+ default: return chalk.white;
41
+ }
42
+ }
43
+ function relTime(iso) {
44
+ const secs = Math.floor((Date.now() - new Date(iso).getTime()) / 1000);
45
+ if (secs < 10)
46
+ return 'just now';
47
+ if (secs < 60)
48
+ return `${secs}s ago`;
49
+ if (secs < 3600)
50
+ return `${Math.floor(secs / 60)}m ago`;
51
+ if (secs < 86400)
52
+ return `${Math.floor(secs / 3600)}h ago`;
53
+ return `${Math.floor(secs / 86400)}d ago`;
54
+ }
55
+ function truncate(s, n) {
56
+ if (s.length <= n)
57
+ return s;
58
+ return s.slice(0, n - 1) + '…';
59
+ }
60
+ function fullName(type, version) {
61
+ const name = AGENT_NAMES[type];
62
+ return version ? `${name} ${version}` : name;
63
+ }
64
+ function parseTeammate(spec) {
65
+ const [name, version] = spec.split('@');
66
+ if (!VALID_AGENTS.includes(name)) {
67
+ die(`Unknown teammate '${name}'. Available: ${VALID_AGENTS.join(', ')}.\n` +
68
+ ` Use the form 'claude' or 'claude@2.1.112' (see 'agents view' for installed versions).`);
69
+ }
70
+ return { agent: name, version: version || null };
71
+ }
72
+ function shortId(id) {
73
+ return id.slice(0, 8);
74
+ }
75
+ // Pick the display handle for a teammate: their given name if they have one,
76
+ // otherwise the 8-char UUID prefix.
77
+ function handle(a) {
78
+ return a.name || shortId(a.agent_id);
79
+ }
80
+ // Resolve a teammate reference (name / UUID / UUID prefix) by scanning every
81
+ // meta.json under the agents dir. Team hint narrows the search.
82
+ async function resolveTeammateAcrossTeams(base, ref, teamHint) {
83
+ let entries = [];
84
+ try {
85
+ entries = await fs.readdir(base);
86
+ }
87
+ catch {
88
+ return { kind: 'none' };
89
+ }
90
+ // Cheap path: exact UUID or unique UUID prefix match by directory name.
91
+ const byDir = entries.filter((e) => e === ref || e.startsWith(ref));
92
+ if (byDir.length === 1 && byDir[0] === ref) {
93
+ return { kind: 'ok', agentId: ref };
94
+ }
95
+ // Otherwise scan meta.json files to match on name as well, and respect the
96
+ // team hint if given.
97
+ const candidates = [];
98
+ for (const dir of entries) {
99
+ try {
100
+ const meta = JSON.parse(await fs.readFile(path.join(base, dir, 'meta.json'), 'utf-8'));
101
+ if (teamHint && meta.task_name !== teamHint)
102
+ continue;
103
+ const matchesName = meta.name && meta.name === ref;
104
+ const matchesPrefix = dir.startsWith(ref);
105
+ if (matchesName || matchesPrefix) {
106
+ candidates.push({
107
+ team: meta.task_name || '(none)',
108
+ agentId: dir,
109
+ display: meta.name || shortId(dir),
110
+ name: meta.name || null,
111
+ });
112
+ }
113
+ }
114
+ catch {
115
+ /* skip entries without readable meta.json */
116
+ }
117
+ }
118
+ if (candidates.length === 0)
119
+ return { kind: 'none' };
120
+ if (candidates.length === 1)
121
+ return { kind: 'ok', agentId: candidates[0].agentId };
122
+ // If multiple match but one is an exact name hit, prefer it.
123
+ const exactName = candidates.filter((c) => c.name === ref);
124
+ if (exactName.length === 1)
125
+ return { kind: 'ok', agentId: exactName[0].agentId };
126
+ return { kind: 'ambiguous', candidates };
127
+ }
128
+ // Print a teammate block using the same session preview the sessions picker
129
+ // uses — one canonical renderer across `agents sessions`, teams picker
130
+ // preview, and teams status output.
131
+ //
132
+ // Layout:
133
+ // alice claude COMPLETED · 5.0 minutes
134
+ // after: bob
135
+ // <buildSessionPreview output> (when the session file was found)
136
+ // ! reported an error (if flagged)
137
+ // PR: <url> (if set)
138
+ function printAgentDetail(a, session) {
139
+ const label = statusColor(a.status)(a.status.toUpperCase());
140
+ const who = fullName(a.agent_type, a.version);
141
+ const h = handle(a);
142
+ const secondary = a.name ? chalk.gray(`(${shortId(a.agent_id)})`) : '';
143
+ const duration = a.duration ? `${chalk.gray(' · ')}${chalk.white(a.duration)}` : '';
144
+ console.log(` ${chalk.cyan(h.padEnd(10))} ${secondary.padEnd(11)} ${who.padEnd(18)} ${label}${duration}`);
145
+ if (a.after && a.after.length) {
146
+ console.log(` ${chalk.gray('after ')} ${a.after.join(', ')}`);
147
+ }
148
+ // If the agent's internal session id differs from ours (non-Claude), show
149
+ // it as a hint for `agents sessions <id>`.
150
+ if (a.remote_session_id && a.remote_session_id !== a.agent_id) {
151
+ console.log(` ${chalk.gray('session ')} ${chalk.gray(a.remote_session_id)}`);
152
+ }
153
+ if (session) {
154
+ // Hand off to the same renderer the sessions picker uses. Indent so the
155
+ // block visually belongs to this teammate.
156
+ const preview = buildSessionPreview(session);
157
+ for (const line of preview.split('\n')) {
158
+ console.log(line ? ` ${line}` : '');
159
+ }
160
+ }
161
+ else {
162
+ // Session file not yet on disk (e.g. teammate is pending, or their
163
+ // agent type writes sessions elsewhere). Fall back to a compact summary
164
+ // derived from the live status payload.
165
+ const activity = [];
166
+ if (a.files_modified.length)
167
+ activity.push(`${a.files_modified.length} modified`);
168
+ if (a.files_created.length)
169
+ activity.push(`${a.files_created.length} created`);
170
+ if (a.files_read.length)
171
+ activity.push(`${a.files_read.length} read`);
172
+ if (a.tool_count)
173
+ activity.push(`${a.tool_count} tools`);
174
+ if (activity.length) {
175
+ console.log(` ${chalk.gray(activity.join(' · '))}`);
176
+ }
177
+ const lastMsg = a.last_messages[a.last_messages.length - 1];
178
+ if (lastMsg) {
179
+ const firstLine = lastMsg.split(/\r?\n/).find((l) => l.trim()) || '';
180
+ if (firstLine)
181
+ console.log(` ${chalk.gray('> ' + truncate(firstLine, 96))}`);
182
+ }
183
+ }
184
+ if (a.has_errors)
185
+ console.log(` ${chalk.red('! reported an error')}`);
186
+ if (a.pr_url)
187
+ console.log(` ${chalk.gray('PR ')}${a.pr_url}`);
188
+ }
189
+ // Resolve each live teammate to its on-disk session (Claude/Codex/Gemini/
190
+ // OpenCode all write parseable session files). `agent_id === remote_session_id`
191
+ // for Claude teammates; non-Claude agents may carry their own session UUID on
192
+ // `remote_session_id`. We try both.
193
+ async function resolveTeammateSessions(agents) {
194
+ const map = new Map();
195
+ if (agents.length === 0)
196
+ return map;
197
+ // Scan every project dir — team teammates may have run from anywhere.
198
+ const all = await discoverSessions({ all: true, limit: 5000 });
199
+ for (const a of agents) {
200
+ const candidates = [a.remote_session_id, a.agent_id].filter(Boolean);
201
+ let found = null;
202
+ for (const id of candidates) {
203
+ const hits = resolveSessionById(all, id);
204
+ if (hits.length) {
205
+ found = hits[0];
206
+ break;
207
+ }
208
+ }
209
+ map.set(a.agent_id, found);
210
+ }
211
+ return map;
212
+ }
213
+ // Render a team's status in the same format the `status` subcommand uses, so
214
+ // the interactive picker's Enter action drops the user into a familiar view.
215
+ async function printTeamStatus(team, result) {
216
+ const { summary, agents } = result;
217
+ console.log(chalk.bold(`Team ${chalk.cyan(team)} `) +
218
+ chalk.gray(summary.pending > 0
219
+ ? `(${summary.pending} pending, ${summary.running} working, ${summary.completed} done, ${summary.failed} failed, ${summary.stopped} stopped)`
220
+ : `(${summary.running} working, ${summary.completed} done, ${summary.failed} failed, ${summary.stopped} stopped)`));
221
+ if (agents.length === 0) {
222
+ console.log(chalk.gray(' (no teammates yet — add one with `agents teams add`)'));
223
+ }
224
+ else {
225
+ const sessions = await resolveTeammateSessions(agents);
226
+ const width = Math.min(process.stdout.columns || 80, 80);
227
+ const divider = chalk.gray('┈'.repeat(width));
228
+ for (let i = 0; i < agents.length; i++) {
229
+ console.log();
230
+ if (i > 0) {
231
+ console.log(divider);
232
+ console.log();
233
+ }
234
+ printAgentDetail(agents[i], sessions.get(agents[i].agent_id) ?? null);
235
+ }
236
+ }
237
+ console.log();
238
+ console.log(chalk.gray(`cursor: ${result.cursor}`));
239
+ }
240
+ // Classify a team into a single bucket for --status filtering.
241
+ // - empty: no teammates (created but nobody added yet)
242
+ // - waiting: only staged teammates — call `teams start` to kick them off
243
+ // - working: at least one teammate still running
244
+ // - failed: at least one teammate failed or was stopped (any failure wins —
245
+ // even if others finished, you want to know about the failure)
246
+ // - done: everyone finished successfully, no failures
247
+ function classifyTeamStatus(t) {
248
+ if (t.agent_count === 0)
249
+ return 'empty';
250
+ if (t.running > 0)
251
+ return 'working';
252
+ if (t.failed + t.stopped > 0)
253
+ return 'failed';
254
+ // At this point nobody is running/failed/stopped. If there's any pending
255
+ // teammate (agent_count > running+completed+failed+stopped), it's "waiting".
256
+ const accounted = t.running + t.completed + t.failed + t.stopped;
257
+ if (accounted < t.agent_count)
258
+ return 'waiting';
259
+ return 'done';
260
+ }
261
+ // Merge persistent team registry with tasks derived from live agents so empty
262
+ // teams (created but no teammates yet) still show up.
263
+ function mergeTeams(registry, tasks) {
264
+ const byName = new Map();
265
+ for (const t of tasks)
266
+ byName.set(t.task_name, t);
267
+ for (const [name, meta] of Object.entries(registry)) {
268
+ if (!byName.has(name)) {
269
+ byName.set(name, {
270
+ task_name: name,
271
+ agent_count: 0,
272
+ pending: 0,
273
+ running: 0,
274
+ completed: 0,
275
+ failed: 0,
276
+ stopped: 0,
277
+ workspace_dir: null,
278
+ created_at: meta.created_at,
279
+ modified_at: meta.created_at,
280
+ });
281
+ }
282
+ }
283
+ return Array.from(byName.values()).sort((a, b) => new Date(b.modified_at).getTime() - new Date(a.modified_at).getTime());
284
+ }
285
+ // Build the same enriched rows the `list` picker uses. Shared between `list`
286
+ // (interactive default) and the picker fallback for `status` / `start`.
287
+ async function loadTeamRows(mgr) {
288
+ const [tasks, registry] = await Promise.all([handleTasks(mgr, 1000), loadTeams()]);
289
+ const merged = mergeTeams(registry, tasks.tasks);
290
+ const rows = await Promise.all(merged.map(async (team) => {
291
+ let agents = [];
292
+ try {
293
+ const res = await handleStatus(mgr, team.task_name, 'all');
294
+ agents = res.agents;
295
+ }
296
+ catch {
297
+ // Empty teams (no live agents) throw in some code paths.
298
+ }
299
+ return { team, agents, description: registry[team.task_name]?.description };
300
+ }));
301
+ return { rows, names: merged.map((t) => t.task_name) };
302
+ }
303
+ // Picker fallback for `teams logs` when the teammate ref is omitted. Shows a
304
+ // flat list of every teammate with their team context; Enter picks one.
305
+ async function pickTeammateOr(mgr, command) {
306
+ if (!isInteractiveTerminal()) {
307
+ requireInteractiveSelection(`Picking a teammate for \`${command}\``, [
308
+ `${command} <teammate>`,
309
+ `agents teams list # to see teammates per team`,
310
+ ]);
311
+ }
312
+ const all = await mgr.listAll();
313
+ if (all.length === 0) {
314
+ console.log(chalk.gray('No teammates on any team yet.'));
315
+ console.log(chalk.gray(' Add one with: agents teams add <team> <agent> <task>'));
316
+ return null;
317
+ }
318
+ const nameW = Math.max(8, ...all.map((a) => (a.name || shortId(a.agentId)).length));
319
+ const teamW = Math.max(6, ...all.map((a) => a.taskName.length));
320
+ try {
321
+ const picked = await itemPicker({
322
+ message: 'Select a teammate:',
323
+ items: all,
324
+ filter: (query) => {
325
+ const q = query.trim().toLowerCase();
326
+ if (!q)
327
+ return all;
328
+ return all.filter((a) => {
329
+ const hay = [a.name ?? '', a.agentId, a.taskName, a.agentType, a.status].join(' ').toLowerCase();
330
+ return hay.includes(q);
331
+ });
332
+ },
333
+ labelFor: (a) => {
334
+ const h = (a.name || shortId(a.agentId)).padEnd(nameW);
335
+ const team = a.taskName.padEnd(teamW);
336
+ const who = fullName(a.agentType, a.version);
337
+ return `${chalk.cyan(h)} ${chalk.gray(team)} ${who} ${statusColor(a.status)(a.status)}`;
338
+ },
339
+ shortIdFor: (a) => a.name || shortId(a.agentId),
340
+ pageSize: 10,
341
+ emptyMessage: 'No teammates match.',
342
+ enterHint: 'view log',
343
+ });
344
+ if (!picked)
345
+ return null;
346
+ return { agentId: picked.item.agentId, team: picked.item.taskName };
347
+ }
348
+ catch (err) {
349
+ if (isPromptCancelled(err))
350
+ return null;
351
+ throw err;
352
+ }
353
+ }
354
+ // Fallback for read-only / constructive subcommands when the user omits the
355
+ // team argument. In a TTY, show the picker and return the chosen team. Outside
356
+ // a TTY, hard-fail with a clear error so scripts surface the missing arg.
357
+ async function pickTeamOr(mgr, command) {
358
+ if (!isInteractiveTerminal()) {
359
+ requireInteractiveSelection(`Picking a team for \`${command}\``, [
360
+ `${command} <team>`,
361
+ `agents teams list # to see your teams`,
362
+ ]);
363
+ }
364
+ const { rows } = await loadTeamRows(mgr);
365
+ if (rows.length === 0) {
366
+ console.log(chalk.gray("You haven't started any teams yet."));
367
+ console.log(chalk.gray(' Start one with: agents teams create <name>'));
368
+ return null;
369
+ }
370
+ try {
371
+ const picked = await teamPicker(rows);
372
+ return picked?.team ?? null;
373
+ }
374
+ catch (err) {
375
+ if (isPromptCancelled(err))
376
+ return null;
377
+ throw err;
378
+ }
379
+ }
380
+ export function registerTeamsCommands(program) {
381
+ const teams = program
382
+ .command('teams')
383
+ .description('Organize AI coding agents into teams that collaborate on a shared task')
384
+ .addHelpText('after', `
385
+ A team is a named group of agents working together on a shared task. Each teammate
386
+ runs in the background; you use 'status' to check in on progress. Use --after to
387
+ create DAG-style dependencies (one teammate waits for another to finish first).
388
+
389
+ Teammate sessions appear in 'agents sessions --teams' with a [team/name · mode] tag.
390
+
391
+ Examples:
392
+ # Start a new team for a feature
393
+ agents teams create auth-feature
394
+
395
+ # Add Alice (Claude) to work on the backend
396
+ agents teams add auth-feature claude "Add JWT auth middleware" --name alice
397
+
398
+ # Add Bob (Codex 0.116.0) to write tests, but wait for Alice to finish first
399
+ agents teams add auth-feature codex@0.116.0 "Write integration tests" --name bob --after alice
400
+
401
+ # Kick off any staged teammates whose dependencies are satisfied
402
+ agents teams start auth-feature
403
+
404
+ # Check in on progress (delta polling with --since for efficiency)
405
+ agents teams status auth-feature
406
+ agents teams status auth-feature --since 2026-04-19T10:30:00Z
407
+
408
+ # Let Alice go when she's done
409
+ agents teams remove auth-feature alice
410
+
411
+ # Wind down the whole team when work is complete
412
+ agents teams disband auth-feature
413
+
414
+ Short aliases:
415
+ teams c = create teams a = add teams s = status
416
+ teams rm = remove teams d = disband teams ls = list
417
+
418
+ Teammate syntax (same as the rest of agents-cli):
419
+ 'claude' -> the default Claude version on this machine
420
+ 'claude@2.1.112' -> a specific installed version (see 'agents view')
421
+
422
+ Name teammates with --name alice to refer to them as 'alice' instead of a UUID.
423
+ `);
424
+ // list
425
+ teams
426
+ .command('list [query]')
427
+ .alias('ls')
428
+ .description('List your teams, most recent activity first')
429
+ .option('-a, --agent <agent>', 'Filter: only teams with this agent (e.g. claude or claude@2.1.112)')
430
+ .option('--status <status>', 'Filter: only teams with this status (working, done, failed, or empty)')
431
+ .option('--since <time>', 'Filter: teams active after this time (e.g. "2h", "7d", or ISO date)')
432
+ .option('--until <time>', 'Filter: teams active before this time (e.g. "30d", or ISO date)')
433
+ .option('-n, --limit <n>', 'Show at most this many teams (default: 20)', '20')
434
+ .option('--json', 'Output machine-readable JSON instead of formatted table')
435
+ .action(async (query, opts) => {
436
+ const mgr = new AgentManager();
437
+ const limit = Math.max(1, parseInt(opts.limit, 10) || 20);
438
+ const [tasks, registry, everyAgent] = await Promise.all([
439
+ handleTasks(mgr, 1000),
440
+ loadTeams(),
441
+ mgr.listAll(),
442
+ ]);
443
+ // Group agents by team so we can filter on agent-type / version.
444
+ const byTeam = new Map();
445
+ for (const a of everyAgent) {
446
+ const arr = byTeam.get(a.taskName) || [];
447
+ arr.push({ agent_type: a.agentType, version: a.version });
448
+ byTeam.set(a.taskName, arr);
449
+ }
450
+ let merged = mergeTeams(registry, tasks.tasks);
451
+ // --- query: substring match on team name ---
452
+ if (query) {
453
+ const q = query.toLowerCase();
454
+ merged = merged.filter((t) => t.task_name.toLowerCase().includes(q));
455
+ }
456
+ // --- --agent: filter teams containing a matching teammate ---
457
+ if (opts.agent) {
458
+ const [wantType, wantVersion] = opts.agent.split('@');
459
+ merged = merged.filter((t) => {
460
+ const teammates = byTeam.get(t.task_name) || [];
461
+ return teammates.some((m) => m.agent_type === wantType && (!wantVersion || m.version === wantVersion));
462
+ });
463
+ }
464
+ // --- --status: classify each team, filter ---
465
+ if (opts.status) {
466
+ const want = opts.status.toLowerCase();
467
+ const validStatuses = ['working', 'done', 'failed', 'empty'];
468
+ if (!validStatuses.includes(want)) {
469
+ die(`Invalid --status '${opts.status}'. Use one of: ${validStatuses.join(', ')}`);
470
+ }
471
+ merged = merged.filter((t) => classifyTeamStatus(t) === want);
472
+ }
473
+ // --- --since / --until: filter by activity window ---
474
+ if (opts.since) {
475
+ const cutoff = parseTimeFilter(opts.since);
476
+ if (!cutoff)
477
+ die(`Could not parse --since '${opts.since}'`);
478
+ merged = merged.filter((t) => new Date(t.modified_at).getTime() >= cutoff);
479
+ }
480
+ if (opts.until) {
481
+ const cutoff = parseTimeFilter(opts.until);
482
+ if (!cutoff)
483
+ die(`Could not parse --until '${opts.until}'`);
484
+ merged = merged.filter((t) => new Date(t.modified_at).getTime() <= cutoff);
485
+ }
486
+ merged = merged.slice(0, limit);
487
+ if (isJsonMode(opts)) {
488
+ console.log(JSON.stringify({ teams: merged }, null, 2));
489
+ return;
490
+ }
491
+ if (merged.length === 0) {
492
+ if (query || opts.agent || opts.status || opts.since || opts.until) {
493
+ console.log(chalk.gray('No teams match those filters.'));
494
+ }
495
+ else {
496
+ console.log(chalk.gray("You haven't started any teams yet."));
497
+ console.log(chalk.gray(' Start one with: agents teams create <name>'));
498
+ }
499
+ return;
500
+ }
501
+ // Enrich teams with teammate details for the picker's preview pane.
502
+ const rows = await Promise.all(merged.map(async (team) => {
503
+ let agents = [];
504
+ try {
505
+ const res = await handleStatus(mgr, team.task_name, 'all');
506
+ agents = res.agents;
507
+ }
508
+ catch {
509
+ // Empty teams (no live agents) throw in some code paths — preview
510
+ // will just show "no teammates yet".
511
+ }
512
+ return { team, agents, description: registry[team.task_name]?.description };
513
+ }));
514
+ if (isInteractiveTerminal()) {
515
+ try {
516
+ const picked = await teamPicker(rows, query);
517
+ if (picked) {
518
+ // Fall through to the status subcommand's action for the picked team.
519
+ const result = await handleStatus(mgr, picked.team, 'all');
520
+ await printTeamStatus(picked.team, result);
521
+ }
522
+ }
523
+ catch (err) {
524
+ if (!isPromptCancelled(err))
525
+ throw err;
526
+ }
527
+ return;
528
+ }
529
+ // Non-interactive fallback: rows flow without a header, matching the
530
+ // shape of `agents sessions` when piped.
531
+ printTeamTable(rows);
532
+ });
533
+ // create
534
+ teams
535
+ .command('create <team>')
536
+ .aliases(['c', 'new'])
537
+ .description('Start a new team. No teammates yet; add them with `teams add`.')
538
+ .option('-d, --description <text>', 'One-line summary of what this team is working on')
539
+ .option('--json', 'Output machine-readable JSON')
540
+ .action(async (team, opts) => {
541
+ try {
542
+ const meta = await createTeam(team, opts.description);
543
+ if (isJsonMode(opts)) {
544
+ console.log(JSON.stringify({ team, ...meta }, null, 2));
545
+ return;
546
+ }
547
+ console.log(chalk.green(`New team: ${chalk.cyan(team)}`));
548
+ if (meta.description)
549
+ console.log(chalk.gray(` ${meta.description}`));
550
+ console.log();
551
+ console.log(chalk.gray('Add your first teammate:'));
552
+ console.log(chalk.gray(` agents teams add ${team} claude "your task here"`));
553
+ }
554
+ catch (err) {
555
+ die(err.message);
556
+ }
557
+ });
558
+ // add
559
+ teams
560
+ .command('add <team> <teammate> <task>')
561
+ .alias('a')
562
+ .description("Add a teammate to work on a task. Runs in background; returns immediately. Use 'status' to check in.")
563
+ .option('-n, --name <name>', 'Friendly name for this teammate (e.g. alice). Required if using --after. Unique within team.')
564
+ .option('-m, --mode <mode>', `Permissions: plan (read-only) | edit (can write files) | full (write + skip permission prompts)`, 'edit')
565
+ .option('-e, --effort <effort>', `Reasoning intensity: ${VALID_EFFORTS.join('|')}`, 'medium')
566
+ .option('--model <model>', 'Override the effort tier and use this specific model (e.g. claude-opus-4-6)')
567
+ .option('--env <key=value>', 'Set an environment variable for this teammate (repeatable for multiple vars)', (val, prev) => [...prev, val], [])
568
+ .option('--cwd <dir>', 'Working directory for this teammate (default: current directory)')
569
+ .option('--after <names>', "DAG dependencies: comma-separated teammate names to wait for. Stages as PENDING; run 'teams start' to launch when ready.")
570
+ .option('--json', 'Output machine-readable JSON')
571
+ .action(async (team, teammate, task, opts) => {
572
+ if (!VALID_MODES.includes(opts.mode)) {
573
+ die(`Invalid mode '${opts.mode}'. Use one of: ${VALID_MODES.join(', ')}`);
574
+ }
575
+ if (!VALID_EFFORTS.includes(opts.effort)) {
576
+ die(`Invalid effort '${opts.effort}'. Use one of: ${VALID_EFFORTS.join(', ')}`);
577
+ }
578
+ const { agent, version } = parseTeammate(teammate);
579
+ if (version && !isVersionInstalled(agent, version)) {
580
+ die(`${AGENT_NAMES[agent]} ${version} isn't installed.\n` +
581
+ ` Install it: agents add ${agent}@${version}\n` +
582
+ ` Or see what's installed: agents view ${agent}`);
583
+ }
584
+ if (opts.name !== undefined) {
585
+ if (!opts.name || !/^[A-Za-z0-9_-]+$/.test(opts.name)) {
586
+ die(`Invalid teammate name '${opts.name}'. Use letters, numbers, '-', or '_'.`);
587
+ }
588
+ }
589
+ const after = opts.after
590
+ ? opts.after.split(',').map((s) => s.trim()).filter(Boolean)
591
+ : [];
592
+ if (after.length > 0 && !opts.name) {
593
+ die("--after requires --name (dependencies reference teammates by name).");
594
+ }
595
+ let envOverrides;
596
+ try {
597
+ envOverrides = parseExecEnv(opts.env);
598
+ }
599
+ catch (err) {
600
+ die(err.message);
601
+ }
602
+ // Auto-create the team if it doesn't exist yet (friendlier UX than erroring).
603
+ await ensureTeam(team);
604
+ const cwd = opts.cwd ?? process.cwd();
605
+ const mgr = new AgentManager();
606
+ try {
607
+ const result = await handleSpawn(mgr, team, agent, task, cwd, opts.mode, opts.effort, null, cwd, version, opts.name ?? null, after, opts.model ?? null, envOverrides ?? null);
608
+ if (isJsonMode(opts)) {
609
+ console.log(JSON.stringify(result, null, 2));
610
+ return;
611
+ }
612
+ const who = fullName(agent, version);
613
+ const staged = result.status === 'pending';
614
+ const verb = staged ? 'Staged' : 'Welcomed';
615
+ const greeting = result.name
616
+ ? `${verb} ${chalk.cyan(result.name)} (${who}) ${staged ? 'in' : 'to'} team ${chalk.cyan(team)}`
617
+ : `${verb} ${who} ${staged ? 'in' : 'to'} team ${chalk.cyan(team)}`;
618
+ console.log(chalk.green(greeting));
619
+ if (result.name) {
620
+ console.log(` ${chalk.gray('name ')} ${chalk.cyan(result.name)}`);
621
+ }
622
+ console.log(` ${chalk.gray('agent_id')} ${chalk.cyan(shortId(result.agent_id))} ${chalk.gray(`(${result.agent_id})`)}`);
623
+ console.log(` ${chalk.gray('status ')} ${statusColor(result.status)(result.status)}`);
624
+ console.log(` ${chalk.gray('mode ')} ${opts.mode}`);
625
+ console.log(` ${chalk.gray('working ')} ${cwd}`);
626
+ if (result.after && result.after.length) {
627
+ console.log(` ${chalk.gray('after ')} ${result.after.join(', ')}`);
628
+ }
629
+ console.log();
630
+ if (staged) {
631
+ console.log(chalk.gray(`Start the ready teammates: agents teams start ${team}`));
632
+ }
633
+ else {
634
+ console.log(chalk.gray(`Check in later: agents teams status ${team}`));
635
+ }
636
+ }
637
+ catch (err) {
638
+ die(`Could not add ${fullName(agent, version)} to ${team}: ${err.message}`);
639
+ }
640
+ });
641
+ // status
642
+ teams
643
+ .command('status [team]')
644
+ .aliases(['s', 'st', 'check'])
645
+ .description("Check in on a team: who's working, what files they touched, recent commands, last output. Pass --since for efficient delta polling.")
646
+ .option('-f, --filter <state>', 'Show only teammates in this state: working, completed, failed, stopped, or all (default: all)', 'all')
647
+ .option('-s, --since <iso>', 'Cursor from a previous status call; only show updates after this timestamp (enables efficient polling)')
648
+ .option('--agent-id <id>', 'Show only this one teammate (by UUID or UUID prefix)')
649
+ .option('--json', 'Output machine-readable JSON')
650
+ .action(async (team, opts) => {
651
+ // Map friendly 'working' → internal 'running' for filter.
652
+ const filter = opts.filter === 'working' ? 'running' : opts.filter;
653
+ const mgr = new AgentManager();
654
+ // No team given → drop into the picker (TTY) or fail clearly (script).
655
+ if (!team) {
656
+ const picked = await pickTeamOr(mgr, 'agents teams status');
657
+ if (!picked)
658
+ return;
659
+ team = picked;
660
+ }
661
+ try {
662
+ const result = await handleStatus(mgr, team, filter, opts.since);
663
+ const agents = opts.agentId
664
+ ? result.agents.filter((a) => a.agent_id.startsWith(opts.agentId))
665
+ : result.agents;
666
+ if (isJsonMode(opts)) {
667
+ console.log(JSON.stringify({ ...result, agents }, null, 2));
668
+ return;
669
+ }
670
+ const exists = await teamExists(team);
671
+ if (!exists && result.agents.length === 0) {
672
+ console.log(chalk.yellow(`No team called '${team}'. Create it with: agents teams create ${team}`));
673
+ return;
674
+ }
675
+ await printTeamStatus(team, { ...result, agents });
676
+ }
677
+ catch (err) {
678
+ die(`Could not check on team ${team}: ${err.message}`);
679
+ }
680
+ });
681
+ // start — fire any staged teammates whose --after deps have all completed
682
+ teams
683
+ .command('start [team]')
684
+ .description('Launch any pending teammates whose --after dependencies are satisfied. Re-run to advance the DAG as teammates finish.')
685
+ .option('--json', 'Output machine-readable JSON')
686
+ .action(async (team, opts) => {
687
+ const mgr = new AgentManager();
688
+ if (!team) {
689
+ const picked = await pickTeamOr(mgr, 'agents teams start');
690
+ if (!picked)
691
+ return;
692
+ team = picked;
693
+ }
694
+ const launched = await mgr.startReady(team);
695
+ // Also compute which teammates are still pending + why, so the user
696
+ // knows what's being waited on.
697
+ const all = await mgr.listByTask(team);
698
+ const stillPending = all.filter((a) => a.status === 'pending');
699
+ if (isJsonMode(opts)) {
700
+ console.log(JSON.stringify({
701
+ team,
702
+ launched: launched.map((a) => ({
703
+ agent_id: a.agentId,
704
+ name: a.name,
705
+ after: a.after,
706
+ })),
707
+ still_pending: stillPending.map((a) => ({
708
+ agent_id: a.agentId,
709
+ name: a.name,
710
+ after: a.after,
711
+ })),
712
+ }, null, 2));
713
+ return;
714
+ }
715
+ if (launched.length === 0 && stillPending.length === 0) {
716
+ console.log(chalk.gray(`No pending teammates in team ${team}.`));
717
+ return;
718
+ }
719
+ if (launched.length > 0) {
720
+ console.log(chalk.green(`Launched ${launched.length} teammate(s) in team ${chalk.cyan(team)}:`));
721
+ for (const a of launched) {
722
+ const who = fullName(a.agentType, a.version);
723
+ const h = a.name || shortId(a.agentId);
724
+ console.log(` ${chalk.cyan(h)} ${who}`);
725
+ }
726
+ }
727
+ if (stillPending.length > 0) {
728
+ console.log();
729
+ console.log(chalk.gray(`Still pending (${stillPending.length}):`));
730
+ for (const a of stillPending) {
731
+ const h = a.name || shortId(a.agentId);
732
+ console.log(` ${chalk.blue(h)} ${chalk.gray('after')} ${a.after.join(', ')}`);
733
+ }
734
+ }
735
+ });
736
+ // remove
737
+ teams
738
+ .command('remove [team] [teammate]')
739
+ .alias('rm')
740
+ .description("Remove a teammate from the team. Stops them cleanly if still working. Accepts name, UUID, or UUID prefix.")
741
+ .option('--keep-logs', 'Keep their log files on disk (default: delete them)')
742
+ .option('--json', 'Output machine-readable JSON')
743
+ .action(async (team, ref, opts) => {
744
+ const mgr = new AgentManager();
745
+ if (!team) {
746
+ const { names } = await loadTeamRows(mgr);
747
+ requireDestructiveArg({
748
+ argName: 'team',
749
+ command: 'agents teams remove',
750
+ itemNoun: 'team',
751
+ available: names,
752
+ emptyHint: "You don't have any teams yet.",
753
+ });
754
+ }
755
+ if (!ref) {
756
+ const roster = await mgr.listByTask(team);
757
+ requireDestructiveArg({
758
+ argName: 'teammate',
759
+ command: `agents teams remove ${team}`,
760
+ itemNoun: 'teammate',
761
+ available: roster.map((a) => a.name || shortId(a.agentId)),
762
+ emptyHint: `Team ${team} has no teammates.`,
763
+ });
764
+ }
765
+ const lookup = await mgr.resolveAgentIdInTask(team, ref);
766
+ if (lookup.kind === 'none') {
767
+ die(`No teammate matching '${ref}' in team ${team}`, 2);
768
+ }
769
+ if (lookup.kind === 'ambiguous') {
770
+ const shorts = lookup.matches.map(shortId).join(', ');
771
+ die(`'${ref}' matches multiple teammates: ${shorts}. Use more characters or a name.`, 2);
772
+ }
773
+ const agentId = lookup.agentId;
774
+ // Look up the display handle (name if they had one) before we tear down.
775
+ const agent = await mgr.get(agentId);
776
+ const display = agent?.name || shortId(agentId);
777
+ const stopRes = await handleStop(mgr, team, agentId);
778
+ if ('error' in stopRes)
779
+ die(stopRes.error);
780
+ if (!opts.keepLogs && stopRes.not_found.length === 0) {
781
+ try {
782
+ const dir = path.join(await getAgentsDir(), agentId);
783
+ await fs.rm(dir, { recursive: true, force: true });
784
+ }
785
+ catch {
786
+ // best-effort cleanup
787
+ }
788
+ }
789
+ if (isJsonMode(opts)) {
790
+ console.log(JSON.stringify({ team, agent_id: agentId, name: agent?.name ?? null, result: stopRes }, null, 2));
791
+ return;
792
+ }
793
+ if (stopRes.stopped.length) {
794
+ console.log(chalk.green(`${display} has left team ${chalk.cyan(team)} (was working, now stopped).`));
795
+ }
796
+ else {
797
+ console.log(chalk.green(`${display} has left team ${chalk.cyan(team)}.`));
798
+ }
799
+ });
800
+ // disband
801
+ teams
802
+ .command('disband [team]')
803
+ .alias('d')
804
+ .description('Disband the team. Stops all teammates cleanly and removes the team registry entry.')
805
+ .option('--keep-logs', 'Keep all teammate logs on disk (default: delete them)')
806
+ .option('--json', 'Output machine-readable JSON')
807
+ .action(async (team, opts) => {
808
+ const mgr = new AgentManager();
809
+ if (!team) {
810
+ const { names } = await loadTeamRows(mgr);
811
+ requireDestructiveArg({
812
+ argName: 'team',
813
+ command: 'agents teams disband',
814
+ itemNoun: 'team',
815
+ available: names,
816
+ emptyHint: "You don't have any teams to disband.",
817
+ });
818
+ }
819
+ const stopRes = await handleStop(mgr, team);
820
+ if ('error' in stopRes)
821
+ die(stopRes.error);
822
+ const status = await handleStatus(mgr, team, 'all');
823
+ const removedIds = [];
824
+ if (!opts.keepLogs) {
825
+ const base = await getAgentsDir();
826
+ for (const a of status.agents) {
827
+ try {
828
+ await fs.rm(path.join(base, a.agent_id), { recursive: true, force: true });
829
+ removedIds.push(a.agent_id);
830
+ }
831
+ catch { /* best-effort */ }
832
+ }
833
+ }
834
+ const existed = await removeTeam(team);
835
+ if (isJsonMode(opts)) {
836
+ console.log(JSON.stringify({ team, existed, stopped: stopRes.stopped, removed_members: removedIds }, null, 2));
837
+ return;
838
+ }
839
+ if (!existed && stopRes.stopped.length === 0 && status.agents.length === 0) {
840
+ die(`No team called '${team}'`, 2);
841
+ }
842
+ console.log(chalk.green(`Team ${chalk.cyan(team)} disbanded.`));
843
+ if (stopRes.stopped.length)
844
+ console.log(chalk.gray(` Stopped ${stopRes.stopped.length} working teammate(s).`));
845
+ if (removedIds.length)
846
+ console.log(chalk.gray(` Cleared ${removedIds.length} teammate log(s).`));
847
+ });
848
+ // logs
849
+ teams
850
+ .command('logs [teammate]')
851
+ .alias('log')
852
+ .description("Read a teammate's raw log output. Accepts name, UUID, or UUID prefix.")
853
+ .option('-n, --tail <n>', 'Show only the last N lines instead of the full log')
854
+ .option('--team <team>', 'Disambiguate when the same name appears in multiple teams')
855
+ .action(async (ref, opts) => {
856
+ const base = await getAgentsDir();
857
+ // No teammate → picker in TTY, hard fail outside.
858
+ let agentId;
859
+ if (!ref) {
860
+ const mgr = new AgentManager();
861
+ const picked = await pickTeammateOr(mgr, 'agents teams logs');
862
+ if (!picked)
863
+ return;
864
+ agentId = picked.agentId;
865
+ }
866
+ else {
867
+ const resolved = await resolveTeammateAcrossTeams(base, ref, opts.team);
868
+ if (resolved.kind === 'none') {
869
+ die(`No notes on record for teammate '${ref}'`, 2);
870
+ }
871
+ if (resolved.kind === 'ambiguous') {
872
+ const hints = resolved.candidates.map((c) => `${c.team}/${c.display}`).join(', ');
873
+ die(`'${ref}' matches multiple teammates: ${hints}.\n` +
874
+ ` Narrow it with --team <team>, or pass a UUID prefix.`, 2);
875
+ }
876
+ agentId = resolved.agentId;
877
+ }
878
+ const logPath = path.join(base, agentId, 'stdout.log');
879
+ try {
880
+ const content = await fs.readFile(logPath, 'utf-8');
881
+ if (!opts.tail) {
882
+ process.stdout.write(content);
883
+ return;
884
+ }
885
+ const n = Math.max(1, parseInt(opts.tail, 10) || 50);
886
+ const lines = content.split('\n');
887
+ process.stdout.write(lines.slice(-n).join('\n'));
888
+ }
889
+ catch {
890
+ die(`No notes on record for teammate '${ref ?? agentId}' (looked in ${logPath})`, 2);
891
+ }
892
+ });
893
+ // doctor
894
+ teams
895
+ .command('doctor')
896
+ .alias('dr')
897
+ .description('Check which agents are installed and available to join a team. Verifies CLI paths.')
898
+ .option('--json', 'Output machine-readable JSON')
899
+ .action(async (opts) => {
900
+ const info = checkAllClis();
901
+ if (isJsonMode(opts)) {
902
+ console.log(JSON.stringify(info, null, 2));
903
+ return;
904
+ }
905
+ console.log(chalk.bold('Who can join a team:'));
906
+ for (const [name, entry] of Object.entries(info)) {
907
+ const pretty = AGENT_NAMES[name] || name;
908
+ if (entry.installed) {
909
+ console.log(` ${chalk.green('ready')} ${pretty.padEnd(10)} ${chalk.gray(entry.path || '')}`);
910
+ }
911
+ else {
912
+ console.log(` ${chalk.red('no ')} ${pretty.padEnd(10)} ${chalk.gray(entry.error || 'not installed')}`);
913
+ }
914
+ }
915
+ });
916
+ }
917
+ //# sourceMappingURL=teams.js.map