@proletariat/cli 0.1.4 → 0.3.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 (526) hide show
  1. package/README.md +510 -255
  2. package/bin/dev.cmd +3 -0
  3. package/bin/dev.js +5 -0
  4. package/bin/run.cmd +3 -0
  5. package/bin/run.js +23 -0
  6. package/dist/commands/action/create.d.ts +21 -0
  7. package/dist/commands/action/create.js +126 -0
  8. package/dist/commands/action/delete.d.ts +17 -0
  9. package/dist/commands/action/delete.js +78 -0
  10. package/dist/commands/action/index.d.ts +15 -0
  11. package/dist/commands/action/index.js +107 -0
  12. package/dist/commands/action/list.d.ts +14 -0
  13. package/dist/commands/action/list.js +89 -0
  14. package/dist/commands/action/run.d.ts +19 -0
  15. package/dist/commands/action/run.js +179 -0
  16. package/dist/commands/action/show.d.ts +15 -0
  17. package/dist/commands/action/show.js +47 -0
  18. package/dist/commands/action/update.d.ts +22 -0
  19. package/dist/commands/action/update.js +168 -0
  20. package/dist/commands/agent/index.d.ts +13 -0
  21. package/dist/commands/agent/index.js +131 -0
  22. package/dist/commands/agent/list.d.ts +7 -0
  23. package/dist/commands/agent/list.js +126 -0
  24. package/dist/commands/agent/login.d.ts +16 -0
  25. package/dist/commands/agent/login.js +146 -0
  26. package/dist/commands/agent/rebuild.d.ts +18 -0
  27. package/dist/commands/agent/rebuild.js +133 -0
  28. package/dist/commands/agent/restart.d.ts +17 -0
  29. package/dist/commands/agent/restart.js +116 -0
  30. package/dist/commands/agent/shell.d.ts +23 -0
  31. package/dist/commands/agent/shell.js +378 -0
  32. package/dist/commands/agent/staff/add.d.ts +15 -0
  33. package/dist/commands/agent/staff/add.js +281 -0
  34. package/dist/commands/agent/staff/index.d.ts +14 -0
  35. package/dist/commands/agent/staff/index.js +90 -0
  36. package/dist/commands/agent/staff/list.d.ts +7 -0
  37. package/dist/commands/agent/staff/list.js +90 -0
  38. package/dist/commands/agent/staff/remove.d.ts +16 -0
  39. package/dist/commands/agent/staff/remove.js +137 -0
  40. package/dist/commands/agent/status.d.ts +17 -0
  41. package/dist/commands/agent/status.js +139 -0
  42. package/dist/commands/agent/temp/cleanup.d.ts +23 -0
  43. package/dist/commands/agent/temp/cleanup.js +388 -0
  44. package/dist/commands/agent/temp/index.d.ts +14 -0
  45. package/dist/commands/agent/temp/index.js +82 -0
  46. package/dist/commands/agent/temp/list.d.ts +7 -0
  47. package/dist/commands/agent/temp/list.js +108 -0
  48. package/dist/commands/agent/themes/add-names.d.ts +10 -0
  49. package/dist/commands/agent/themes/add-names.js +67 -0
  50. package/dist/commands/agent/themes/create.d.ts +13 -0
  51. package/dist/commands/agent/themes/create.js +66 -0
  52. package/dist/commands/agent/themes/index.d.ts +9 -0
  53. package/dist/commands/agent/themes/index.js +194 -0
  54. package/dist/commands/agent/themes/list.d.ts +6 -0
  55. package/dist/commands/agent/themes/list.js +41 -0
  56. package/dist/commands/agent/themes/set.d.ts +12 -0
  57. package/dist/commands/agent/themes/set.js +77 -0
  58. package/dist/commands/agent/visit.d.ts +16 -0
  59. package/dist/commands/agent/visit.js +88 -0
  60. package/dist/commands/autocomplete/setup.d.ts +14 -0
  61. package/dist/commands/autocomplete/setup.js +154 -0
  62. package/dist/commands/board/index.d.ts +17 -0
  63. package/dist/commands/board/index.js +255 -0
  64. package/dist/commands/board/watch.d.ts +13 -0
  65. package/dist/commands/board/watch.js +52 -0
  66. package/dist/commands/branch/create.d.ts +50 -0
  67. package/dist/commands/branch/create.js +624 -0
  68. package/dist/commands/branch/index.d.ts +13 -0
  69. package/dist/commands/branch/index.js +50 -0
  70. package/dist/commands/branch/list.d.ts +17 -0
  71. package/dist/commands/branch/list.js +120 -0
  72. package/dist/commands/branch/validate.d.ts +15 -0
  73. package/dist/commands/branch/validate.js +73 -0
  74. package/dist/commands/commit.d.ts +71 -0
  75. package/dist/commands/commit.js +499 -0
  76. package/dist/commands/docker/clean.d.ts +13 -0
  77. package/dist/commands/docker/clean.js +224 -0
  78. package/dist/commands/docker/index.d.ts +19 -0
  79. package/dist/commands/docker/index.js +274 -0
  80. package/dist/commands/docker/list.d.ts +16 -0
  81. package/dist/commands/docker/list.js +200 -0
  82. package/dist/commands/docker/logs.d.ts +14 -0
  83. package/dist/commands/docker/logs.js +118 -0
  84. package/dist/commands/docker/prune.d.ts +14 -0
  85. package/dist/commands/docker/prune.js +211 -0
  86. package/dist/commands/docker/restart.d.ts +14 -0
  87. package/dist/commands/docker/restart.js +129 -0
  88. package/dist/commands/docker/shell.d.ts +14 -0
  89. package/dist/commands/docker/shell.js +103 -0
  90. package/dist/commands/docker/start.d.ts +12 -0
  91. package/dist/commands/docker/start.js +92 -0
  92. package/dist/commands/docker/status.d.ts +7 -0
  93. package/dist/commands/docker/status.js +40 -0
  94. package/dist/commands/docker/stop.d.ts +14 -0
  95. package/dist/commands/docker/stop.js +134 -0
  96. package/dist/commands/docker/sync.d.ts +15 -0
  97. package/dist/commands/docker/sync.js +112 -0
  98. package/dist/commands/epic/activate.d.ts +13 -0
  99. package/dist/commands/epic/activate.js +118 -0
  100. package/dist/commands/epic/archive.d.ts +14 -0
  101. package/dist/commands/epic/archive.js +132 -0
  102. package/dist/commands/epic/create.d.ts +15 -0
  103. package/dist/commands/epic/create.js +137 -0
  104. package/dist/commands/epic/index.d.ts +13 -0
  105. package/dist/commands/epic/index.js +88 -0
  106. package/dist/commands/epic/link/block.d.ts +14 -0
  107. package/dist/commands/epic/link/block.js +79 -0
  108. package/dist/commands/epic/link/duplicates.d.ts +14 -0
  109. package/dist/commands/epic/link/duplicates.js +66 -0
  110. package/dist/commands/epic/link/index.d.ts +19 -0
  111. package/dist/commands/epic/link/index.js +242 -0
  112. package/dist/commands/epic/link/relates.d.ts +14 -0
  113. package/dist/commands/epic/link/relates.js +66 -0
  114. package/dist/commands/epic/link/remove.d.ts +16 -0
  115. package/dist/commands/epic/link/remove.js +89 -0
  116. package/dist/commands/epic/list.d.ts +11 -0
  117. package/dist/commands/epic/list.js +87 -0
  118. package/dist/commands/epic/move.d.ts +15 -0
  119. package/dist/commands/epic/move.js +184 -0
  120. package/dist/commands/epic/progress.d.ts +16 -0
  121. package/dist/commands/epic/progress.js +166 -0
  122. package/dist/commands/epic/project.d.ts +15 -0
  123. package/dist/commands/epic/project.js +219 -0
  124. package/dist/commands/epic/reorder.d.ts +21 -0
  125. package/dist/commands/epic/reorder.js +160 -0
  126. package/dist/commands/epic/spec.d.ts +15 -0
  127. package/dist/commands/epic/spec.js +191 -0
  128. package/dist/commands/epic/ticket.d.ts +18 -0
  129. package/dist/commands/epic/ticket.js +291 -0
  130. package/dist/commands/epic/view.d.ts +13 -0
  131. package/dist/commands/epic/view.js +117 -0
  132. package/dist/commands/execution/index.d.ts +13 -0
  133. package/dist/commands/execution/index.js +70 -0
  134. package/dist/commands/execution/list.d.ts +15 -0
  135. package/dist/commands/execution/list.js +144 -0
  136. package/dist/commands/execution/logs.d.ts +18 -0
  137. package/dist/commands/execution/logs.js +161 -0
  138. package/dist/commands/execution/stop.d.ts +22 -0
  139. package/dist/commands/execution/stop.js +248 -0
  140. package/dist/commands/gh/index.d.ts +9 -0
  141. package/dist/commands/gh/index.js +53 -0
  142. package/dist/commands/gh/login.d.ts +6 -0
  143. package/dist/commands/gh/login.js +57 -0
  144. package/dist/commands/gh/status.d.ts +6 -0
  145. package/dist/commands/gh/status.js +48 -0
  146. package/dist/commands/gh/token.d.ts +6 -0
  147. package/dist/commands/gh/token.js +59 -0
  148. package/dist/commands/init.d.ts +26 -0
  149. package/dist/commands/init.js +200 -0
  150. package/dist/commands/phase/create.d.ts +22 -0
  151. package/dist/commands/phase/create.js +123 -0
  152. package/dist/commands/phase/delete.d.ts +17 -0
  153. package/dist/commands/phase/delete.js +73 -0
  154. package/dist/commands/phase/list.d.ts +12 -0
  155. package/dist/commands/phase/list.js +76 -0
  156. package/dist/commands/phase/move.d.ts +17 -0
  157. package/dist/commands/phase/move.js +115 -0
  158. package/dist/commands/phase/template/apply.d.ts +17 -0
  159. package/dist/commands/phase/template/apply.js +106 -0
  160. package/dist/commands/phase/template/create.d.ts +16 -0
  161. package/dist/commands/phase/template/create.js +58 -0
  162. package/dist/commands/phase/template/delete.d.ts +17 -0
  163. package/dist/commands/phase/template/delete.js +98 -0
  164. package/dist/commands/phase/template/index.d.ts +15 -0
  165. package/dist/commands/phase/template/index.js +128 -0
  166. package/dist/commands/phase/template/list.d.ts +16 -0
  167. package/dist/commands/phase/template/list.js +95 -0
  168. package/dist/commands/phase/template/update.d.ts +17 -0
  169. package/dist/commands/phase/template/update.js +89 -0
  170. package/dist/commands/phase/update.d.ts +23 -0
  171. package/dist/commands/phase/update.js +174 -0
  172. package/dist/commands/pmo/init.d.ts +25 -0
  173. package/dist/commands/pmo/init.js +341 -0
  174. package/dist/commands/pr/create.d.ts +17 -0
  175. package/dist/commands/pr/create.js +242 -0
  176. package/dist/commands/pr/index.d.ts +9 -0
  177. package/dist/commands/pr/index.js +68 -0
  178. package/dist/commands/pr/link.d.ts +14 -0
  179. package/dist/commands/pr/link.js +212 -0
  180. package/dist/commands/pr/status.d.ts +12 -0
  181. package/dist/commands/pr/status.js +161 -0
  182. package/dist/commands/project/archive.d.ts +17 -0
  183. package/dist/commands/project/archive.js +83 -0
  184. package/dist/commands/project/create.d.ts +22 -0
  185. package/dist/commands/project/create.js +143 -0
  186. package/dist/commands/project/delete.d.ts +17 -0
  187. package/dist/commands/project/delete.js +128 -0
  188. package/dist/commands/project/index.d.ts +13 -0
  189. package/dist/commands/project/index.js +64 -0
  190. package/dist/commands/project/list.d.ts +14 -0
  191. package/dist/commands/project/list.js +96 -0
  192. package/dist/commands/project/spec.d.ts +18 -0
  193. package/dist/commands/project/spec.js +216 -0
  194. package/dist/commands/project/unarchive.d.ts +15 -0
  195. package/dist/commands/project/unarchive.js +35 -0
  196. package/dist/commands/project/view.d.ts +16 -0
  197. package/dist/commands/project/view.js +94 -0
  198. package/dist/commands/repo/add.d.ts +21 -0
  199. package/dist/commands/repo/add.js +118 -0
  200. package/dist/commands/repo/index.d.ts +13 -0
  201. package/dist/commands/repo/index.js +114 -0
  202. package/dist/commands/repo/list.d.ts +13 -0
  203. package/dist/commands/repo/list.js +96 -0
  204. package/dist/commands/repo/remove.d.ts +23 -0
  205. package/dist/commands/repo/remove.js +217 -0
  206. package/dist/commands/repo/view.d.ts +15 -0
  207. package/dist/commands/repo/view.js +99 -0
  208. package/dist/commands/session/attach.d.ts +40 -0
  209. package/dist/commands/session/attach.js +307 -0
  210. package/dist/commands/session/index.d.ts +13 -0
  211. package/dist/commands/session/index.js +64 -0
  212. package/dist/commands/session/list.d.ts +21 -0
  213. package/dist/commands/session/list.js +181 -0
  214. package/dist/commands/spec/create.d.ts +19 -0
  215. package/dist/commands/spec/create.js +130 -0
  216. package/dist/commands/spec/index.d.ts +13 -0
  217. package/dist/commands/spec/index.js +68 -0
  218. package/dist/commands/spec/link/depends.d.ts +14 -0
  219. package/dist/commands/spec/link/depends.js +64 -0
  220. package/dist/commands/spec/link/duplicates.d.ts +14 -0
  221. package/dist/commands/spec/link/duplicates.js +63 -0
  222. package/dist/commands/spec/link/index.d.ts +19 -0
  223. package/dist/commands/spec/link/index.js +200 -0
  224. package/dist/commands/spec/link/relates.d.ts +14 -0
  225. package/dist/commands/spec/link/relates.js +63 -0
  226. package/dist/commands/spec/link/remove.d.ts +16 -0
  227. package/dist/commands/spec/link/remove.js +94 -0
  228. package/dist/commands/spec/list.d.ts +12 -0
  229. package/dist/commands/spec/list.js +75 -0
  230. package/dist/commands/spec/plan.d.ts +15 -0
  231. package/dist/commands/spec/plan.js +108 -0
  232. package/dist/commands/spec/ticket.d.ts +18 -0
  233. package/dist/commands/spec/ticket.js +160 -0
  234. package/dist/commands/spec/view.d.ts +15 -0
  235. package/dist/commands/spec/view.js +163 -0
  236. package/dist/commands/status/create.d.ts +21 -0
  237. package/dist/commands/status/create.js +140 -0
  238. package/dist/commands/status/delete.d.ts +13 -0
  239. package/dist/commands/status/delete.js +77 -0
  240. package/dist/commands/status/index.d.ts +14 -0
  241. package/dist/commands/status/index.js +91 -0
  242. package/dist/commands/status/list.d.ts +12 -0
  243. package/dist/commands/status/list.js +93 -0
  244. package/dist/commands/status/move.d.ts +14 -0
  245. package/dist/commands/status/move.js +120 -0
  246. package/dist/commands/status/update.d.ts +20 -0
  247. package/dist/commands/status/update.js +180 -0
  248. package/dist/commands/template/delete.d.ts +15 -0
  249. package/dist/commands/template/delete.js +142 -0
  250. package/dist/commands/template/index.d.ts +10 -0
  251. package/dist/commands/template/index.js +64 -0
  252. package/dist/commands/template/list.d.ts +18 -0
  253. package/dist/commands/template/list.js +157 -0
  254. package/dist/commands/template/phase/apply.d.ts +14 -0
  255. package/dist/commands/template/phase/apply.js +41 -0
  256. package/dist/commands/template/phase/create.d.ts +12 -0
  257. package/dist/commands/template/phase/create.js +29 -0
  258. package/dist/commands/template/phase/delete.d.ts +13 -0
  259. package/dist/commands/template/phase/delete.js +34 -0
  260. package/dist/commands/template/phase/index.d.ts +10 -0
  261. package/dist/commands/template/phase/index.js +62 -0
  262. package/dist/commands/template/phase/list.d.ts +11 -0
  263. package/dist/commands/template/phase/list.js +34 -0
  264. package/dist/commands/template/phase/update.d.ts +13 -0
  265. package/dist/commands/template/phase/update.js +35 -0
  266. package/dist/commands/template/ticket/apply.d.ts +17 -0
  267. package/dist/commands/template/ticket/apply.js +58 -0
  268. package/dist/commands/template/ticket/delete.d.ts +13 -0
  269. package/dist/commands/template/ticket/delete.js +34 -0
  270. package/dist/commands/template/ticket/index.d.ts +10 -0
  271. package/dist/commands/template/ticket/index.js +62 -0
  272. package/dist/commands/template/ticket/list.d.ts +11 -0
  273. package/dist/commands/template/ticket/list.js +34 -0
  274. package/dist/commands/template/ticket/save.d.ts +13 -0
  275. package/dist/commands/template/ticket/save.js +35 -0
  276. package/dist/commands/ticket/bulk.d.ts +13 -0
  277. package/dist/commands/ticket/bulk.js +145 -0
  278. package/dist/commands/ticket/complete.d.ts +16 -0
  279. package/dist/commands/ticket/complete.js +170 -0
  280. package/dist/commands/ticket/create.d.ts +22 -0
  281. package/dist/commands/ticket/create.js +390 -0
  282. package/dist/commands/ticket/delete.d.ts +16 -0
  283. package/dist/commands/ticket/delete.js +178 -0
  284. package/dist/commands/ticket/edit.d.ts +27 -0
  285. package/dist/commands/ticket/edit.js +322 -0
  286. package/dist/commands/ticket/epic.d.ts +20 -0
  287. package/dist/commands/ticket/epic.js +333 -0
  288. package/dist/commands/ticket/index.d.ts +13 -0
  289. package/dist/commands/ticket/index.js +103 -0
  290. package/dist/commands/ticket/link/block.d.ts +14 -0
  291. package/dist/commands/ticket/link/block.js +94 -0
  292. package/dist/commands/ticket/link/duplicates.d.ts +14 -0
  293. package/dist/commands/ticket/link/duplicates.js +93 -0
  294. package/dist/commands/ticket/link/index.d.ts +19 -0
  295. package/dist/commands/ticket/link/index.js +239 -0
  296. package/dist/commands/ticket/link/relates.d.ts +14 -0
  297. package/dist/commands/ticket/link/relates.js +93 -0
  298. package/dist/commands/ticket/link/remove.d.ts +16 -0
  299. package/dist/commands/ticket/link/remove.js +128 -0
  300. package/dist/commands/ticket/list.d.ts +24 -0
  301. package/dist/commands/ticket/list.js +431 -0
  302. package/dist/commands/ticket/move.d.ts +18 -0
  303. package/dist/commands/ticket/move.js +212 -0
  304. package/dist/commands/ticket/project.d.ts +18 -0
  305. package/dist/commands/ticket/project.js +254 -0
  306. package/dist/commands/ticket/reassign.d.ts +19 -0
  307. package/dist/commands/ticket/reassign.js +279 -0
  308. package/dist/commands/ticket/spec.d.ts +18 -0
  309. package/dist/commands/ticket/spec.js +259 -0
  310. package/dist/commands/ticket/status.d.ts +13 -0
  311. package/dist/commands/ticket/status.js +87 -0
  312. package/dist/commands/ticket/template/apply.d.ts +25 -0
  313. package/dist/commands/ticket/template/apply.js +249 -0
  314. package/dist/commands/ticket/template/create.d.ts +19 -0
  315. package/dist/commands/ticket/template/create.js +210 -0
  316. package/dist/commands/ticket/template/delete.d.ts +17 -0
  317. package/dist/commands/ticket/template/delete.js +92 -0
  318. package/dist/commands/ticket/template/index.d.ts +15 -0
  319. package/dist/commands/ticket/template/index.js +118 -0
  320. package/dist/commands/ticket/template/list.d.ts +16 -0
  321. package/dist/commands/ticket/template/list.js +110 -0
  322. package/dist/commands/ticket/template/save.d.ts +14 -0
  323. package/dist/commands/ticket/template/save.js +110 -0
  324. package/dist/commands/ticket/update.d.ts +18 -0
  325. package/dist/commands/ticket/update.js +325 -0
  326. package/dist/commands/ticket/view.d.ts +13 -0
  327. package/dist/commands/ticket/view.js +80 -0
  328. package/dist/commands/whoami.d.ts +9 -0
  329. package/dist/commands/whoami.js +103 -0
  330. package/dist/commands/work/complete.d.ts +13 -0
  331. package/dist/commands/work/complete.js +121 -0
  332. package/dist/commands/work/index.d.ts +13 -0
  333. package/dist/commands/work/index.js +70 -0
  334. package/dist/commands/work/ready.d.ts +24 -0
  335. package/dist/commands/work/ready.js +290 -0
  336. package/dist/commands/work/revise.d.ts +19 -0
  337. package/dist/commands/work/revise.js +377 -0
  338. package/dist/commands/work/spawn-all.d.ts +17 -0
  339. package/dist/commands/work/spawn-all.js +58 -0
  340. package/dist/commands/work/spawn.d.ts +29 -0
  341. package/dist/commands/work/spawn.js +728 -0
  342. package/dist/commands/work/start.d.ts +39 -0
  343. package/dist/commands/work/start.js +1393 -0
  344. package/dist/commands/work/watch.d.ts +31 -0
  345. package/dist/commands/work/watch.js +359 -0
  346. package/dist/commands/workflow/create.d.ts +18 -0
  347. package/dist/commands/workflow/create.js +119 -0
  348. package/dist/commands/workflow/delete.d.ts +17 -0
  349. package/dist/commands/workflow/delete.js +119 -0
  350. package/dist/commands/workflow/index.d.ts +15 -0
  351. package/dist/commands/workflow/index.js +75 -0
  352. package/dist/commands/workflow/list.d.ts +15 -0
  353. package/dist/commands/workflow/list.js +75 -0
  354. package/dist/commands/workflow/switch.d.ts +13 -0
  355. package/dist/commands/workflow/switch.js +117 -0
  356. package/dist/commands/workflow/view.d.ts +16 -0
  357. package/dist/commands/workflow/view.js +114 -0
  358. package/dist/commands/workspace/add.d.ts +12 -0
  359. package/dist/commands/workspace/add.js +74 -0
  360. package/dist/commands/workspace/list.d.ts +9 -0
  361. package/dist/commands/workspace/list.js +153 -0
  362. package/dist/commands/workspace/remove.d.ts +13 -0
  363. package/dist/commands/workspace/remove.js +98 -0
  364. package/dist/commands/workspace/use.d.ts +12 -0
  365. package/dist/commands/workspace/use.js +111 -0
  366. package/dist/hooks/init.d.ts +11 -0
  367. package/dist/hooks/init.js +57 -0
  368. package/dist/index.d.ts +1 -0
  369. package/dist/index.js +1 -0
  370. package/dist/lib/agents/commands.d.ts +189 -0
  371. package/dist/lib/agents/commands.js +893 -0
  372. package/dist/lib/agents/index.d.ts +54 -0
  373. package/dist/lib/agents/index.js +382 -0
  374. package/dist/lib/branch/index.d.ts +120 -0
  375. package/dist/lib/branch/index.js +334 -0
  376. package/dist/lib/colors.d.ts +94 -0
  377. package/dist/lib/colors.js +68 -0
  378. package/dist/lib/commands/docker-command.d.ts +21 -0
  379. package/dist/lib/commands/docker-command.js +27 -0
  380. package/dist/lib/database/index.d.ts +176 -0
  381. package/dist/lib/database/index.js +581 -0
  382. package/dist/lib/docker/resolve.d.ts +38 -0
  383. package/dist/lib/docker/resolve.js +175 -0
  384. package/dist/lib/execution/config.d.ts +150 -0
  385. package/dist/lib/execution/config.js +541 -0
  386. package/dist/lib/execution/devcontainer.d.ts +85 -0
  387. package/dist/lib/execution/devcontainer.js +594 -0
  388. package/dist/lib/execution/index.d.ts +10 -0
  389. package/dist/lib/execution/index.js +10 -0
  390. package/dist/lib/execution/runners.d.ts +53 -0
  391. package/dist/lib/execution/runners.js +1182 -0
  392. package/dist/lib/execution/spawner.d.ts +85 -0
  393. package/dist/lib/execution/spawner.js +548 -0
  394. package/dist/lib/execution/storage.d.ts +159 -0
  395. package/dist/lib/execution/storage.js +425 -0
  396. package/dist/lib/execution/types.d.ts +145 -0
  397. package/dist/lib/execution/types.js +157 -0
  398. package/dist/lib/init/index.d.ts +75 -0
  399. package/dist/lib/init/index.js +355 -0
  400. package/dist/lib/machine-config.d.ts +170 -0
  401. package/dist/lib/machine-config.js +386 -0
  402. package/dist/lib/pmo/base-command.d.ts +195 -0
  403. package/dist/lib/pmo/base-command.js +319 -0
  404. package/dist/lib/pmo/create-spec-folders.d.ts +43 -0
  405. package/dist/lib/pmo/create-spec-folders.js +64 -0
  406. package/dist/lib/pmo/epic-files.d.ts +56 -0
  407. package/dist/lib/pmo/epic-files.js +195 -0
  408. package/dist/lib/pmo/find-pmo.d.ts +14 -0
  409. package/dist/lib/pmo/find-pmo.js +172 -0
  410. package/dist/lib/pmo/index.d.ts +109 -0
  411. package/dist/lib/pmo/index.js +501 -0
  412. package/dist/lib/pmo/markdown.d.ts +31 -0
  413. package/dist/lib/pmo/markdown.js +245 -0
  414. package/dist/lib/pmo/pmo-context.d.ts +27 -0
  415. package/dist/lib/pmo/pmo-context.js +44 -0
  416. package/dist/lib/pmo/schema.d.ts +82 -0
  417. package/dist/lib/pmo/schema.js +531 -0
  418. package/dist/lib/pmo/spec-parser.d.ts +25 -0
  419. package/dist/lib/pmo/spec-parser.js +205 -0
  420. package/dist/lib/pmo/spec-types.d.ts +43 -0
  421. package/dist/lib/pmo/spec-types.js +7 -0
  422. package/dist/lib/pmo/storage/actions.d.ts +34 -0
  423. package/dist/lib/pmo/storage/actions.js +177 -0
  424. package/dist/lib/pmo/storage/base.d.ts +47 -0
  425. package/dist/lib/pmo/storage/base.js +858 -0
  426. package/dist/lib/pmo/storage/dependencies.d.ts +61 -0
  427. package/dist/lib/pmo/storage/dependencies.js +267 -0
  428. package/dist/lib/pmo/storage/epics.d.ts +46 -0
  429. package/dist/lib/pmo/storage/epics.js +243 -0
  430. package/dist/lib/pmo/storage/helpers.d.ts +33 -0
  431. package/dist/lib/pmo/storage/helpers.js +148 -0
  432. package/dist/lib/pmo/storage/index.d.ts +186 -0
  433. package/dist/lib/pmo/storage/index.js +689 -0
  434. package/dist/lib/pmo/storage/phases.d.ts +65 -0
  435. package/dist/lib/pmo/storage/phases.js +392 -0
  436. package/dist/lib/pmo/storage/projects.d.ts +79 -0
  437. package/dist/lib/pmo/storage/projects.js +303 -0
  438. package/dist/lib/pmo/storage/specs.d.ts +77 -0
  439. package/dist/lib/pmo/storage/specs.js +389 -0
  440. package/dist/lib/pmo/storage/statuses.d.ts +63 -0
  441. package/dist/lib/pmo/storage/statuses.js +404 -0
  442. package/dist/lib/pmo/storage/subtasks.d.ts +37 -0
  443. package/dist/lib/pmo/storage/subtasks.js +184 -0
  444. package/dist/lib/pmo/storage/templates.d.ts +40 -0
  445. package/dist/lib/pmo/storage/templates.js +210 -0
  446. package/dist/lib/pmo/storage/tickets.d.ts +57 -0
  447. package/dist/lib/pmo/storage/tickets.js +453 -0
  448. package/dist/lib/pmo/storage/types.d.ts +200 -0
  449. package/dist/lib/pmo/storage/types.js +5 -0
  450. package/dist/lib/pmo/storage/views.d.ts +44 -0
  451. package/dist/lib/pmo/storage/views.js +355 -0
  452. package/dist/lib/pmo/storage-sqlite.d.ts +7 -0
  453. package/dist/lib/pmo/storage-sqlite.js +7 -0
  454. package/dist/lib/pmo/sync-manager.d.ts +92 -0
  455. package/dist/lib/pmo/sync-manager.js +229 -0
  456. package/dist/lib/pmo/types.d.ts +710 -0
  457. package/dist/lib/pmo/types.js +108 -0
  458. package/dist/lib/pmo/utils.d.ts +122 -0
  459. package/dist/lib/pmo/utils.js +174 -0
  460. package/dist/lib/pmo/watcher.d.ts +43 -0
  461. package/dist/lib/pmo/watcher.js +208 -0
  462. package/dist/lib/pr/index.d.ts +150 -0
  463. package/dist/lib/pr/index.js +483 -0
  464. package/dist/lib/prompt-json.d.ts +231 -0
  465. package/dist/lib/prompt-json.js +213 -0
  466. package/dist/lib/repos/index.d.ts +81 -0
  467. package/dist/lib/repos/index.js +679 -0
  468. package/dist/lib/styles.d.ts +98 -0
  469. package/dist/lib/styles.js +195 -0
  470. package/dist/lib/themes.d.ts +128 -0
  471. package/dist/lib/themes.js +301 -0
  472. package/dist/lib/ui/BoardUI.d.ts +21 -0
  473. package/dist/lib/ui/BoardUI.js +85 -0
  474. package/dist/lib/ui/ClaimTicketUI.d.ts +17 -0
  475. package/dist/lib/ui/ClaimTicketUI.js +64 -0
  476. package/dist/lib/ui/CreateTicketUI.d.ts +13 -0
  477. package/dist/lib/ui/CreateTicketUI.js +101 -0
  478. package/dist/lib/workspace.d.ts +66 -0
  479. package/dist/lib/workspace.js +204 -0
  480. package/oclif.manifest.json +10593 -0
  481. package/package.json +104 -52
  482. package/LICENSE +0 -21
  483. package/dist/bin/prlt.d.ts +0 -11
  484. package/dist/bin/prlt.d.ts.map +0 -1
  485. package/dist/bin/prlt.js +0 -144
  486. package/dist/bin/prlt.js.map +0 -1
  487. package/dist/lib/config/index.d.ts +0 -14
  488. package/dist/lib/config/index.d.ts.map +0 -1
  489. package/dist/lib/config/index.js +0 -139
  490. package/dist/lib/config/index.js.map +0 -1
  491. package/dist/lib/config/upgrade.d.ts +0 -2
  492. package/dist/lib/config/upgrade.d.ts.map +0 -1
  493. package/dist/lib/config/upgrade.js +0 -173
  494. package/dist/lib/config/upgrade.js.map +0 -1
  495. package/dist/lib/themes/index.d.ts +0 -8
  496. package/dist/lib/themes/index.d.ts.map +0 -1
  497. package/dist/lib/themes/index.js +0 -80
  498. package/dist/lib/themes/index.js.map +0 -1
  499. package/dist/lib/utils/helpers.d.ts +0 -4
  500. package/dist/lib/utils/helpers.d.ts.map +0 -1
  501. package/dist/lib/utils/helpers.js +0 -39
  502. package/dist/lib/utils/helpers.js.map +0 -1
  503. package/dist/lib/utils/logger.d.ts +0 -4
  504. package/dist/lib/utils/logger.d.ts.map +0 -1
  505. package/dist/lib/utils/logger.js +0 -28
  506. package/dist/lib/utils/logger.js.map +0 -1
  507. package/dist/lib/workspace/index.d.ts +0 -13
  508. package/dist/lib/workspace/index.d.ts.map +0 -1
  509. package/dist/lib/workspace/index.js +0 -116
  510. package/dist/lib/workspace/index.js.map +0 -1
  511. package/dist/lib/worktree/index.d.ts +0 -7
  512. package/dist/lib/worktree/index.d.ts.map +0 -1
  513. package/dist/lib/worktree/index.js +0 -362
  514. package/dist/lib/worktree/index.js.map +0 -1
  515. package/dist/lib/worktree/migrate.d.ts +0 -2
  516. package/dist/lib/worktree/migrate.d.ts.map +0 -1
  517. package/dist/lib/worktree/migrate.js +0 -212
  518. package/dist/lib/worktree/migrate.js.map +0 -1
  519. package/dist/lib/worktree/repair.d.ts +0 -3
  520. package/dist/lib/worktree/repair.d.ts.map +0 -1
  521. package/dist/lib/worktree/repair.js +0 -140
  522. package/dist/lib/worktree/repair.js.map +0 -1
  523. package/dist/types/index.d.ts +0 -57
  524. package/dist/types/index.d.ts.map +0 -1
  525. package/dist/types/index.js +0 -3
  526. package/dist/types/index.js.map +0 -1
@@ -0,0 +1,728 @@
1
+ import { Flags } from '@oclif/core';
2
+ import * as path from 'node:path';
3
+ import inquirer from 'inquirer';
4
+ import Database from 'better-sqlite3';
5
+ import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../lib/pmo/index.js';
6
+ import { styles } from '../../lib/styles.js';
7
+ import { getWorkspaceInfo, getTicketTmuxSession, killTmuxSession } from '../../lib/agents/commands.js';
8
+ import { ExecutionStorage } from '../../lib/execution/storage.js';
9
+ import { isDockerRunning } from '../../lib/execution/runners.js';
10
+ import { shouldOutputJson, outputPromptAsJson, outputSuccessAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
11
+ export default class WorkSpawn extends PMOCommand {
12
+ static description = 'Spawn work for multiple tickets by column (batch mode)';
13
+ static strict = false; // Allow multiple ticket ID args without defining them
14
+ static examples = [
15
+ '<%= config.bin %> <%= command.id %> # Interactive: All or Many',
16
+ '<%= config.bin %> <%= command.id %> --all # All tickets in selected column',
17
+ '<%= config.bin %> <%= command.id %> --column Backlog # All tickets in Backlog',
18
+ '<%= config.bin %> <%= command.id %> --many # Multi-select specific tickets',
19
+ '<%= config.bin %> <%= command.id %> TKT-001 TKT-002 # Spawn specific tickets by ID',
20
+ '<%= config.bin %> <%= command.id %> --dry-run # Preview without executing',
21
+ '<%= config.bin %> <%= command.id %> --many --json # Output ticket choices as JSON (for agents)',
22
+ ];
23
+ static flags = {
24
+ ...pmoBaseFlags,
25
+ json: Flags.boolean({
26
+ description: 'Output prompt configuration as JSON (for AI agents/scripts)',
27
+ default: false,
28
+ }),
29
+ all: Flags.boolean({
30
+ char: 'a',
31
+ description: 'Spawn all tickets tickets in a column',
32
+ default: false,
33
+ }),
34
+ many: Flags.boolean({
35
+ description: 'Multi-select specific tickets to spawn',
36
+ default: false,
37
+ }),
38
+ column: Flags.string({
39
+ char: 'c',
40
+ description: 'Column name to spawn tickets from (used with --all)',
41
+ }),
42
+ strategy: Flags.string({
43
+ char: 's',
44
+ description: 'Agent selection strategy',
45
+ options: ['round-robin', 'least-busy', 'random'],
46
+ default: 'round-robin',
47
+ }),
48
+ 'dry-run': Flags.boolean({
49
+ description: 'Show what would be spawned without executing',
50
+ default: false,
51
+ }),
52
+ mode: Flags.string({
53
+ char: 'm',
54
+ description: 'Runtime mode for spawned agents',
55
+ options: ['foreground', 'background', 'tmux', 'terminal', 'devcontainer', 'docker', 'vm'],
56
+ }),
57
+ executor: Flags.string({
58
+ char: 'e',
59
+ description: 'Override executor',
60
+ options: ['claude-code', 'codex', 'aider', 'custom'],
61
+ }),
62
+ force: Flags.boolean({
63
+ char: 'f',
64
+ description: 'Start even if work already in progress',
65
+ default: false,
66
+ }),
67
+ 'run-on-host': Flags.boolean({
68
+ description: 'Run on host even if devcontainer exists (bypasses sandbox)',
69
+ default: false,
70
+ }),
71
+ limit: Flags.integer({
72
+ char: 'l',
73
+ description: 'Maximum number of tickets to spawn',
74
+ }),
75
+ yes: Flags.boolean({
76
+ char: 'y',
77
+ description: 'Skip confirmation prompt',
78
+ default: false,
79
+ }),
80
+ 'per-ticket': Flags.boolean({
81
+ description: 'Prompt for settings per ticket (default: batch mode with same settings for all)',
82
+ default: false,
83
+ }),
84
+ output: Flags.string({
85
+ char: 'o',
86
+ description: 'Output mode (batch mode only)',
87
+ options: ['interactive', 'print'],
88
+ }),
89
+ 'skip-permissions': Flags.boolean({
90
+ description: 'Skip permission prompts - danger mode (batch mode only)',
91
+ default: false,
92
+ }),
93
+ 'create-pr': Flags.boolean({
94
+ description: 'Create PR when work is ready (batch mode only)',
95
+ default: false,
96
+ }),
97
+ 'no-pr': Flags.boolean({
98
+ description: 'Do not create PR when work is ready (batch mode only)',
99
+ default: false,
100
+ }),
101
+ action: Flags.string({
102
+ description: 'Action to perform (e.g., groom, implement, review). Prompts if not provided.',
103
+ }),
104
+ session: Flags.string({
105
+ description: 'Session manager inside container (tmux runs agent in tmux inside container)',
106
+ options: ['tmux', 'direct'],
107
+ default: 'tmux',
108
+ }),
109
+ };
110
+ async execute() {
111
+ const { flags, argv } = await this.parse(WorkSpawn);
112
+ // This command requires project context
113
+ const projectId = await this.requireProject();
114
+ // Check if JSON output mode is active
115
+ const jsonMode = shouldOutputJson(flags);
116
+ // Helper to handle errors in JSON mode
117
+ const handleError = (code, message) => {
118
+ if (jsonMode) {
119
+ outputErrorAsJson(code, message, createMetadata('work spawn', flags));
120
+ this.exit(1);
121
+ }
122
+ this.error(message);
123
+ };
124
+ // Parse ticket IDs from args (everything after flags)
125
+ const ticketIdArgs = argv;
126
+ // Note: Docker check is handled by work:start command when spawning each ticket
127
+ // This allows for the interactive devcontainer/host selection with retry loop
128
+ // Get workspace info (for agent worktree paths)
129
+ let workspaceInfo;
130
+ try {
131
+ workspaceInfo = getWorkspaceInfo();
132
+ }
133
+ catch {
134
+ return handleError('NOT_IN_WORKSPACE', 'Not in a workspace. Run "prlt init" first.');
135
+ }
136
+ // Open database for execution storage
137
+ const dbPath = path.join(workspaceInfo.path, '.proletariat', 'workspace.db');
138
+ const db = new Database(dbPath);
139
+ const executionStorage = new ExecutionStorage(db);
140
+ try {
141
+ // Get board to list available columns
142
+ const board = await this.storage.getBoard(projectId);
143
+ const columnNames = board.columns.map(col => col.name);
144
+ if (columnNames.length === 0) {
145
+ db.close();
146
+ return handleError('NO_COLUMNS', 'No columns found on the board.');
147
+ }
148
+ // Get all tickets (no assignee filter - show ALL tickets per ticket requirements)
149
+ const allTickets = await this.storage.listTickets(projectId);
150
+ if (allTickets.length === 0) {
151
+ db.close();
152
+ if (jsonMode) {
153
+ outputErrorAsJson('NO_TICKETS', 'No tickets found to spawn.', createMetadata('work spawn', flags));
154
+ return;
155
+ }
156
+ this.log(styles.muted('No tickets found to spawn.'));
157
+ return;
158
+ }
159
+ // Note: With ephemeral agents, we no longer need to check for available pre-registered agents
160
+ // Agents are created on-demand when spawning
161
+ // Determine spawn mode: All, Many, or Args (positional ticket IDs)
162
+ let spawnMode = 'all';
163
+ if (ticketIdArgs.length > 0) {
164
+ // Ticket IDs provided as positional args
165
+ spawnMode = 'args';
166
+ }
167
+ else if (flags.all) {
168
+ spawnMode = 'all';
169
+ }
170
+ else if (flags.many) {
171
+ spawnMode = 'many';
172
+ }
173
+ else if (!flags.column) {
174
+ // In JSON mode without explicit flags, output the mode selection prompt
175
+ if (jsonMode) {
176
+ outputPromptAsJson(buildPromptConfig('list', 'mode', 'How would you like to spawn work?', [
177
+ { name: 'All - Spawn all tickets tickets in a column', value: 'all' },
178
+ { name: 'Many - Select specific tickets to spawn', value: 'many' },
179
+ ]), createMetadata('work spawn', flags));
180
+ db.close();
181
+ return;
182
+ }
183
+ // Interactive: ask user
184
+ const { mode } = await inquirer.prompt([
185
+ {
186
+ type: 'list',
187
+ name: 'mode',
188
+ message: 'How would you like to spawn work?',
189
+ choices: [
190
+ { name: '📦 All - Spawn all tickets tickets in a column', value: 'all' },
191
+ { name: '✅ Many - Select specific tickets to spawn', value: 'many' },
192
+ ],
193
+ },
194
+ ]);
195
+ spawnMode = mode;
196
+ }
197
+ let ticketsToSpawn = [];
198
+ if (spawnMode === 'args') {
199
+ // ARGS MODE: Spawn specific tickets by ID
200
+ // Look up tickets by ID (don't filter by assignee - allow forcing assigned tickets)
201
+ for (const ticketId of ticketIdArgs) {
202
+ const ticket = allTickets.find(t => t.id.toLowerCase() === ticketId.toLowerCase());
203
+ if (ticket) {
204
+ ticketsToSpawn.push(ticket);
205
+ }
206
+ else {
207
+ if (!jsonMode) {
208
+ this.warn(`Ticket "${ticketId}" not found, skipping.`);
209
+ }
210
+ }
211
+ }
212
+ if (ticketsToSpawn.length === 0) {
213
+ db.close();
214
+ return handleError('NO_VALID_TICKETS', 'No valid tickets found from provided IDs.');
215
+ }
216
+ // In JSON mode with explicit tickets, output success
217
+ if (jsonMode) {
218
+ outputSuccessAsJson({
219
+ ticketsSelected: ticketsToSpawn.map(t => ({
220
+ id: t.id,
221
+ title: t.title,
222
+ status: t.statusName,
223
+ })),
224
+ count: ticketsToSpawn.length,
225
+ }, createMetadata('work spawn', flags));
226
+ db.close();
227
+ return;
228
+ }
229
+ this.log('');
230
+ this.log(styles.header(`🚀 Spawn: ${ticketsToSpawn.length} ticket(s)`));
231
+ this.log(styles.muted(`Tickets: ${ticketsToSpawn.map(t => t.id).join(', ')}`));
232
+ }
233
+ else if (spawnMode === 'all') {
234
+ // ALL MODE: Column picker, then spawn all tickets in that column
235
+ let targetColumn = flags.column;
236
+ if (!targetColumn) {
237
+ // Show columns with ticket counts
238
+ const columnChoices = columnNames.map(name => {
239
+ const count = allTickets.filter(t => t.statusName === name).length;
240
+ return {
241
+ name: `${name} (${count} tickets)`,
242
+ value: name,
243
+ };
244
+ });
245
+ // In JSON mode, output the column selection prompt
246
+ if (jsonMode) {
247
+ outputPromptAsJson(buildPromptConfig('list', 'selectedColumn', 'Select column to spawn all tickets tickets from:', columnChoices), createMetadata('work spawn', flags));
248
+ db.close();
249
+ return;
250
+ }
251
+ const { selectedColumn } = await inquirer.prompt([
252
+ {
253
+ type: 'list',
254
+ name: 'selectedColumn',
255
+ message: 'Select column to spawn all tickets tickets from:',
256
+ choices: columnChoices,
257
+ },
258
+ ]);
259
+ targetColumn = selectedColumn;
260
+ }
261
+ // Verify column exists
262
+ const matchedColumn = columnNames.find(c => c.toLowerCase() === targetColumn.toLowerCase());
263
+ if (!matchedColumn) {
264
+ db.close();
265
+ return handleError('COLUMN_NOT_FOUND', `Column "${targetColumn}" not found.\nAvailable columns: ${columnNames.join(', ')}`);
266
+ }
267
+ ticketsToSpawn = allTickets.filter(t => t.statusName === matchedColumn);
268
+ if (ticketsToSpawn.length === 0) {
269
+ db.close();
270
+ if (jsonMode) {
271
+ outputErrorAsJson('NO_TICKETS_IN_COLUMN', `No tickets tickets in column "${matchedColumn}".`, createMetadata('work spawn', flags));
272
+ return;
273
+ }
274
+ this.log(styles.muted(`No tickets tickets in column "${matchedColumn}".`));
275
+ return;
276
+ }
277
+ this.log('');
278
+ this.log(styles.header(`🚀 Spawn All from: ${matchedColumn}`));
279
+ }
280
+ else {
281
+ // MANY MODE: First pick column (or all), then multi-select tickets
282
+ // In JSON mode with --many, output the ticket selection prompt directly
283
+ // (skip column selection for simplicity - show all tickets)
284
+ if (jsonMode) {
285
+ // Build choices from all tickets tickets
286
+ const ticketChoices = allTickets.map(ticket => {
287
+ const priority = ticket.priority ? `[${ticket.priority}] ` : '';
288
+ return {
289
+ name: `${priority}${ticket.id} - ${ticket.title} (${ticket.statusName || 'No Status'})`,
290
+ value: ticket.id,
291
+ };
292
+ });
293
+ outputPromptAsJson(buildPromptConfig('checkbox', 'selectedTickets', 'Select tickets to spawn (provide ticket IDs as positional args to execute):', ticketChoices), createMetadata('work spawn', flags));
294
+ db.close();
295
+ return;
296
+ }
297
+ // Build column choices with counts - show ALL columns even if empty
298
+ const columnChoices = [
299
+ { name: '🌐 All columns (select from anywhere)', value: '__ALL__' },
300
+ ];
301
+ for (const name of columnNames) {
302
+ const count = allTickets.filter(t => t.statusName === name).length;
303
+ columnChoices.push({
304
+ name: count > 0 ? `${name} (${count} tickets)` : `${name} (0)`,
305
+ value: name,
306
+ });
307
+ }
308
+ const { manyColumn } = await inquirer.prompt([
309
+ {
310
+ type: 'list',
311
+ name: 'manyColumn',
312
+ message: 'Select from which column:',
313
+ choices: columnChoices,
314
+ },
315
+ ]);
316
+ // Filter tickets based on column selection
317
+ const ticketsForSelection = manyColumn === '__ALL__'
318
+ ? allTickets
319
+ : allTickets.filter(t => t.statusName === manyColumn);
320
+ if (ticketsForSelection.length === 0) {
321
+ db.close();
322
+ this.log(styles.muted('No tickets tickets in that column.'));
323
+ return;
324
+ }
325
+ // Group tickets by priority for display
326
+ const PRIORITY_ORDER = ['P0', 'P1', 'P2', 'P3', 'None'];
327
+ const ticketsByPriority = new Map();
328
+ for (const priority of PRIORITY_ORDER) {
329
+ ticketsByPriority.set(priority, []);
330
+ }
331
+ for (const ticket of ticketsForSelection) {
332
+ const priority = ticket.priority || 'None';
333
+ if (!ticketsByPriority.has(priority)) {
334
+ ticketsByPriority.set(priority, []);
335
+ }
336
+ ticketsByPriority.get(priority).push(ticket);
337
+ }
338
+ // Build choices with priority separators
339
+ const choices = [];
340
+ for (const priority of PRIORITY_ORDER) {
341
+ const tickets = ticketsByPriority.get(priority) || [];
342
+ if (tickets.length === 0)
343
+ continue;
344
+ choices.push(new inquirer.Separator(`── ${priority} (${tickets.length}) ──`));
345
+ for (const ticket of tickets) {
346
+ const statusBadge = ticket.statusName ? ` [${ticket.statusName}]` : '';
347
+ choices.push({
348
+ name: `[${priority}] ${ticket.id} - ${ticket.title}${statusBadge}`,
349
+ value: ticket.id,
350
+ });
351
+ }
352
+ }
353
+ const { selectedTicketIds } = await inquirer.prompt([
354
+ {
355
+ type: 'checkbox',
356
+ name: 'selectedTicketIds',
357
+ message: 'Select tickets to spawn (space to toggle, enter to confirm):',
358
+ choices,
359
+ validate: (input) => {
360
+ if (input.length === 0) {
361
+ return 'Please select at least one ticket';
362
+ }
363
+ return true;
364
+ },
365
+ },
366
+ ]);
367
+ ticketsToSpawn = allTickets.filter(t => selectedTicketIds.includes(t.id));
368
+ this.log('');
369
+ this.log(styles.header(`🚀 Spawn Many: ${ticketsToSpawn.length} tickets`));
370
+ }
371
+ // Apply limit if specified
372
+ if (flags.limit && flags.limit > 0) {
373
+ ticketsToSpawn = ticketsToSpawn.slice(0, flags.limit);
374
+ }
375
+ this.log('');
376
+ // Note: With ephemeral agents, we don't need to check availability
377
+ // Each ticket will get its own ephemeral agent created on-demand
378
+ // Check for tickets with existing tmux sessions (active work)
379
+ const ticketsWithActiveSessions = [];
380
+ const ticketsToProcess = [];
381
+ for (const ticket of ticketsToSpawn) {
382
+ const session = getTicketTmuxSession(ticket.id);
383
+ if (session) {
384
+ ticketsWithActiveSessions.push({
385
+ ticketId: ticket.id,
386
+ sessionName: session.sessionName,
387
+ agent: session.agent
388
+ });
389
+ }
390
+ else {
391
+ ticketsToProcess.push(ticket);
392
+ }
393
+ }
394
+ // Handle tickets with active sessions
395
+ if (ticketsWithActiveSessions.length > 0 && !jsonMode) {
396
+ this.log(styles.warning(`Found ${ticketsWithActiveSessions.length} ticket(s) with active tmux sessions:`));
397
+ for (const { ticketId, agent } of ticketsWithActiveSessions) {
398
+ this.log(styles.muted(` ${ticketId} → ${agent}`));
399
+ }
400
+ this.log('');
401
+ const { sessionAction } = await inquirer.prompt([
402
+ {
403
+ type: 'list',
404
+ name: 'sessionAction',
405
+ message: 'What would you like to do with these tickets?',
406
+ choices: [
407
+ { name: 'Skip them (only spawn tickets without active sessions)', value: 'skip' },
408
+ { name: 'Kill sessions and respawn with new agents', value: 'kill' },
409
+ { name: 'Cancel', value: 'cancel' },
410
+ ],
411
+ },
412
+ ]);
413
+ if (sessionAction === 'cancel') {
414
+ db.close();
415
+ this.log(styles.muted('Cancelled.'));
416
+ return;
417
+ }
418
+ if (sessionAction === 'kill') {
419
+ // Kill existing sessions and add those tickets back to process list
420
+ for (const { ticketId, sessionName } of ticketsWithActiveSessions) {
421
+ killTmuxSession(sessionName);
422
+ const ticket = ticketsToSpawn.find(t => t.id === ticketId);
423
+ if (ticket) {
424
+ ticketsToProcess.push(ticket);
425
+ }
426
+ }
427
+ this.log(styles.success(`Killed ${ticketsWithActiveSessions.length} session(s)`));
428
+ }
429
+ }
430
+ // Update ticketsToSpawn to only include tickets we'll process
431
+ ticketsToSpawn = ticketsToProcess;
432
+ if (ticketsToSpawn.length === 0) {
433
+ db.close();
434
+ this.log(styles.muted('No tickets to spawn (all have active sessions).'));
435
+ return;
436
+ }
437
+ this.log(styles.muted(`Tickets: ${ticketsToSpawn.map(t => t.id).join(', ')}`));
438
+ this.log(styles.muted(`Agents: Ephemeral (unique per ticket)`));
439
+ this.log('');
440
+ // Note: Removed redundant confirmation - user already selected tickets
441
+ // Use --dry-run to preview without executing
442
+ // Dry run - just show what would happen
443
+ if (flags['dry-run']) {
444
+ db.close();
445
+ this.log(styles.success(`Dry run complete: would spawn ${ticketsToSpawn.length} tickets with ephemeral agents`));
446
+ return;
447
+ }
448
+ // Batch mode settings - prompt once for all tickets
449
+ let batchMode = flags.mode;
450
+ let batchOutput = flags.output;
451
+ let batchSkipPermissions = flags['skip-permissions'];
452
+ let batchCreatePr = flags['create-pr'];
453
+ let batchNoPr = flags['no-pr'];
454
+ let batchRunOnHost = flags['run-on-host'];
455
+ let batchAction = flags.action;
456
+ // Track display mode separately for devcontainer (needs to be outside the if block)
457
+ let batchDisplayMode;
458
+ // For ephemeral agents, we'll create devcontainers on-demand
459
+ // Default to devcontainer support (can be overridden by --run-on-host)
460
+ const hasDevcontainer = true; // Ephemeral agents always get devcontainer config
461
+ // Will be populated after action is selected/confirmed
462
+ let selectedActionDetails = null;
463
+ if (!flags['per-ticket']) {
464
+ this.log(styles.header('Batch Settings (applies to all tickets)'));
465
+ this.log('');
466
+ // Prompt for action selection first (unless explicitly provided via --action flag)
467
+ if (!flags.action) {
468
+ // Get available actions from database
469
+ const actions = await this.storage.listActions();
470
+ const actionChoices = actions
471
+ .filter(a => a.isBuiltin)
472
+ .map(a => ({
473
+ name: `${a.id.padEnd(12)} - ${a.description || a.name}`,
474
+ value: a.id,
475
+ }));
476
+ const { selectedAction } = await inquirer.prompt([
477
+ {
478
+ type: 'list',
479
+ name: 'selectedAction',
480
+ message: 'What action should agents perform?',
481
+ choices: actionChoices,
482
+ default: 'implement',
483
+ },
484
+ ]);
485
+ batchAction = selectedAction;
486
+ }
487
+ // Now fetch action details after selection is made
488
+ selectedActionDetails = await this.storage.getAction(batchAction || 'implement');
489
+ // Check if any explicit settings were provided via flags
490
+ const hasExplicitSettings = flags.mode || flags.output || flags['skip-permissions'] ||
491
+ flags['create-pr'] || flags['no-pr'] || flags['run-on-host'];
492
+ // Offer to use default settings if no explicit flags provided
493
+ if (!hasExplicitSettings) {
494
+ const actionName = batchAction || 'implement';
495
+ const modifiesCode = selectedActionDetails?.modifiesCode ?? true;
496
+ const defaultsDescription = modifiesCode
497
+ ? 'devcontainer, terminal, interactive, safe permissions, create PRs'
498
+ : 'devcontainer, terminal, interactive, safe permissions, no PRs';
499
+ const { useDefaults } = await inquirer.prompt([
500
+ {
501
+ type: 'list',
502
+ name: 'useDefaults',
503
+ message: `Use default settings for "${actionName}"?`,
504
+ choices: [
505
+ { name: `✓ Yes - Use defaults (${defaultsDescription})`, value: true },
506
+ { name: '✗ No - Configure each setting', value: false },
507
+ ],
508
+ default: true,
509
+ },
510
+ ]);
511
+ if (useDefaults) {
512
+ // Apply defaults
513
+ if (hasDevcontainer) {
514
+ batchMode = 'devcontainer';
515
+ batchDisplayMode = 'terminal';
516
+ }
517
+ else {
518
+ batchMode = 'terminal';
519
+ }
520
+ batchOutput = 'interactive';
521
+ batchSkipPermissions = false;
522
+ // For non-code-modifying actions, don't create PRs
523
+ if (modifiesCode) {
524
+ batchCreatePr = true;
525
+ batchNoPr = false;
526
+ }
527
+ else {
528
+ batchCreatePr = false;
529
+ batchNoPr = true;
530
+ }
531
+ this.log('');
532
+ }
533
+ }
534
+ // Prompt for environment (devcontainer vs host) if devcontainer available and not already set
535
+ if (hasDevcontainer && !batchRunOnHost && !batchMode) {
536
+ let environmentSelected = false;
537
+ while (!environmentSelected) {
538
+ const { selectedEnvironment } = await inquirer.prompt([
539
+ {
540
+ type: 'list',
541
+ name: 'selectedEnvironment',
542
+ message: 'Where should agents run?',
543
+ choices: [
544
+ { name: '🐳 devcontainer (sandboxed, recommended)', value: 'devcontainer' },
545
+ { name: '💻 host (runs directly on your machine)', value: 'host' },
546
+ { name: '✗ cancel', value: 'cancel' },
547
+ ],
548
+ default: 'devcontainer',
549
+ },
550
+ ]);
551
+ if (selectedEnvironment === 'cancel') {
552
+ db.close();
553
+ this.log(styles.muted('Cancelled.'));
554
+ return;
555
+ }
556
+ if (selectedEnvironment === 'devcontainer') {
557
+ if (!isDockerRunning()) {
558
+ this.log('');
559
+ this.warn('Docker is not running.\n' +
560
+ 'Docker is required for devcontainer execution.\n' +
561
+ 'Please start Docker Desktop or select "host" to run directly on your machine.');
562
+ this.log('');
563
+ continue;
564
+ }
565
+ batchMode = 'devcontainer';
566
+ environmentSelected = true;
567
+ // For devcontainer, prompt for display mode
568
+ // Simplified: tmux is always used inside container for session persistence
569
+ const { selectedDisplay } = await inquirer.prompt([
570
+ {
571
+ type: 'list',
572
+ name: 'selectedDisplay',
573
+ message: 'How should agent output be displayed?',
574
+ choices: [
575
+ { name: '🖥️ New tab - Opens in new terminal tab (recommended)', value: 'terminal' },
576
+ { name: '📦 Background - Runs detached, reattach with: prlt session attach', value: 'background' },
577
+ ],
578
+ default: 'terminal',
579
+ },
580
+ ]);
581
+ batchDisplayMode = selectedDisplay;
582
+ // Always use tmux inside container for session persistence
583
+ flags.session = 'tmux';
584
+ }
585
+ else {
586
+ batchRunOnHost = true;
587
+ environmentSelected = true;
588
+ }
589
+ }
590
+ }
591
+ // Prompt for display mode if not already set (for host mode without devcontainer)
592
+ if (!batchMode) {
593
+ const { selectedMode } = await inquirer.prompt([
594
+ {
595
+ type: 'list',
596
+ name: 'selectedMode',
597
+ message: 'How should agent output be displayed?',
598
+ choices: [
599
+ { name: '🖥️ New tab - Opens in new terminal tab (recommended)', value: 'terminal' },
600
+ { name: '📦 Background - Runs detached, reattach with: prlt session attach', value: 'background' },
601
+ ],
602
+ },
603
+ ]);
604
+ batchMode = selectedMode;
605
+ }
606
+ // Default to interactive output mode (streaming UI)
607
+ // Can be overridden via --output flag if needed
608
+ if (!batchOutput) {
609
+ batchOutput = 'interactive';
610
+ }
611
+ // Prompt for permissions mode if not provided
612
+ if (!batchSkipPermissions) {
613
+ const { permissionMode } = await inquirer.prompt([
614
+ {
615
+ type: 'list',
616
+ name: 'permissionMode',
617
+ message: 'Permission mode for Claude Code:',
618
+ choices: [
619
+ { name: '⚠️ danger - Skip permission checks (faster, container provides isolation)', value: 'danger' },
620
+ { name: '🔒 safe - Requires approval for dangerous operations', value: 'safe' },
621
+ ],
622
+ default: 'danger',
623
+ },
624
+ ]);
625
+ batchSkipPermissions = permissionMode === 'danger';
626
+ }
627
+ // Prompt for PR creation if not provided AND action modifies code
628
+ // Skip this prompt entirely for non-code-modifying actions (like groom)
629
+ const actionModifiesCode = selectedActionDetails?.modifiesCode ?? true;
630
+ if (!batchCreatePr && !batchNoPr) {
631
+ if (actionModifiesCode) {
632
+ const { prChoice } = await inquirer.prompt([
633
+ {
634
+ type: 'list',
635
+ name: 'prChoice',
636
+ message: 'Create pull requests when work is ready?',
637
+ choices: [
638
+ { name: '✓ Yes - Create PR for each ticket', value: 'yes' },
639
+ { name: '✗ No - Just move tickets to review', value: 'no' },
640
+ ],
641
+ default: 'yes',
642
+ },
643
+ ]);
644
+ batchCreatePr = prChoice === 'yes';
645
+ batchNoPr = prChoice === 'no';
646
+ }
647
+ else {
648
+ // Non-code-modifying action - no PR needed
649
+ batchCreatePr = false;
650
+ batchNoPr = true;
651
+ }
652
+ }
653
+ this.log('');
654
+ }
655
+ else {
656
+ // Per-ticket mode - still need to get action details if action flag was provided
657
+ if (batchAction) {
658
+ selectedActionDetails = await this.storage.getAction(batchAction);
659
+ }
660
+ }
661
+ // Spawn each ticket - work:start will create ephemeral agents on-demand
662
+ let successCount = 0;
663
+ let failCount = 0;
664
+ for (const ticket of ticketsToSpawn) {
665
+ try {
666
+ this.log(styles.muted(`Starting ${ticket.id} with ephemeral agent...`));
667
+ // Build args for work:start
668
+ // IMPORTANT: Pass --project to avoid re-prompting for project selection
669
+ // Pass --ephemeral to signal work:start should create an ephemeral agent
670
+ const startArgs = [ticket.id, '--project', projectId, '--ephemeral'];
671
+ if (flags['per-ticket']) {
672
+ // Per-ticket mode: only pass mode flag, let start prompt for the rest
673
+ if (batchMode)
674
+ startArgs.push('--mode', batchMode);
675
+ if (batchDisplayMode)
676
+ startArgs.push('--display', batchDisplayMode);
677
+ if (flags.executor)
678
+ startArgs.push('--executor', flags.executor);
679
+ if (batchRunOnHost)
680
+ startArgs.push('--run-on-host');
681
+ if (flags.force)
682
+ startArgs.push('--force');
683
+ }
684
+ else {
685
+ // Batch mode: pass all settings to skip prompts
686
+ if (batchMode)
687
+ startArgs.push('--mode', batchMode);
688
+ if (batchDisplayMode)
689
+ startArgs.push('--display', batchDisplayMode);
690
+ if (flags.executor)
691
+ startArgs.push('--executor', flags.executor);
692
+ if (batchRunOnHost)
693
+ startArgs.push('--run-on-host');
694
+ if (flags.force)
695
+ startArgs.push('--force');
696
+ if (batchOutput)
697
+ startArgs.push('--output', batchOutput);
698
+ if (batchSkipPermissions)
699
+ startArgs.push('--skip-permissions');
700
+ if (batchCreatePr)
701
+ startArgs.push('--create-pr');
702
+ if (batchNoPr)
703
+ startArgs.push('--no-pr');
704
+ // Pass action flag (from prompt or flag)
705
+ startArgs.push('--action', batchAction || 'implement');
706
+ // Pass session manager (tmux inside container by default)
707
+ if (flags.session)
708
+ startArgs.push('--session', flags.session);
709
+ }
710
+ await this.config.runCommand('work:start', startArgs);
711
+ successCount++;
712
+ }
713
+ catch (error) {
714
+ failCount++;
715
+ this.log(styles.error(`Failed to start ${ticket.id}: ${error instanceof Error ? error.message : error}`));
716
+ }
717
+ }
718
+ await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
719
+ db.close();
720
+ this.log('');
721
+ this.log(styles.success(`✓ Spawn results: ${successCount} started, ${failCount} failed`));
722
+ }
723
+ catch (error) {
724
+ db.close();
725
+ throw error;
726
+ }
727
+ }
728
+ }