@proletariat/cli 0.2.0 → 0.3.1

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 +561 -251
  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 +103 -56
  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 -142
  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 -248
  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 -214
  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 -320
  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,219 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import inquirer from 'inquirer';
3
+ import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../lib/pmo/index.js';
4
+ import { styles } from '../../lib/styles.js';
5
+ import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
6
+ export default class EpicProject extends PMOCommand {
7
+ static description = 'Move an epic to a different project (optionally with its tickets)';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %> EPIC-001 new-project',
10
+ '<%= config.bin %> <%= command.id %> EPIC-001 new-project --with-tickets',
11
+ '<%= config.bin %> <%= command.id %> EPIC-001',
12
+ '<%= config.bin %> <%= command.id %>',
13
+ ];
14
+ static args = {
15
+ epicId: Args.string({
16
+ description: 'Epic ID',
17
+ required: false,
18
+ }),
19
+ targetProject: Args.string({
20
+ description: 'Target project ID',
21
+ required: false,
22
+ }),
23
+ };
24
+ static flags = {
25
+ ...pmoBaseFlags,
26
+ json: Flags.boolean({
27
+ description: 'Output prompt configuration as JSON (for AI agents/scripts)',
28
+ default: false,
29
+ }),
30
+ 'with-tickets': Flags.boolean({
31
+ char: 't',
32
+ description: 'Also move all tickets assigned to this epic',
33
+ default: false,
34
+ }),
35
+ };
36
+ async execute() {
37
+ const { args, flags } = await this.parse(EpicProject);
38
+ // Check if JSON output mode is active
39
+ const jsonMode = shouldOutputJson(flags);
40
+ // Helper to handle errors in JSON mode
41
+ const handleError = (code, message) => {
42
+ if (jsonMode) {
43
+ outputErrorAsJson(code, message, createMetadata('epic project', flags));
44
+ this.exit(1);
45
+ }
46
+ this.error(message);
47
+ };
48
+ const sourceProjectId = await this.requireProject();
49
+ // Get epic ID
50
+ let epicId = args.epicId;
51
+ if (!epicId) {
52
+ const epics = await this.storage.listEpics(sourceProjectId);
53
+ if (epics.length === 0) {
54
+ if (jsonMode) {
55
+ outputErrorAsJson('NO_EPICS', 'No epics found in this project.', createMetadata('epic project', flags));
56
+ return;
57
+ }
58
+ this.log(styles.muted('\nNo epics found in this project.'));
59
+ return;
60
+ }
61
+ // In JSON mode, output epic selection prompt
62
+ if (jsonMode) {
63
+ const epicChoices = epics.map(e => ({ name: `${e.id} - ${e.title} (${e.status})`, value: e.id }));
64
+ outputPromptAsJson(buildPromptConfig('list', 'epicId', 'Select epic to move:', epicChoices), createMetadata('epic project', flags));
65
+ return;
66
+ }
67
+ const { selected } = await inquirer.prompt([{
68
+ type: 'list',
69
+ name: 'selected',
70
+ message: 'Select epic to move:',
71
+ choices: epics.map(e => ({
72
+ name: `${e.id} - ${e.title} (${e.status})`,
73
+ value: e.id,
74
+ })),
75
+ }]);
76
+ epicId = selected;
77
+ }
78
+ // Get epic details
79
+ const epic = await this.storage.getEpic(epicId);
80
+ if (!epic) {
81
+ return handleError('EPIC_NOT_FOUND', `Epic not found: ${epicId}`);
82
+ }
83
+ // Get all projects
84
+ const projects = await this.storage.listProjects();
85
+ const otherProjects = projects.filter(p => p.id !== sourceProjectId);
86
+ if (otherProjects.length === 0) {
87
+ if (jsonMode) {
88
+ const actionChoices = [
89
+ { name: 'Create a new project', value: 'create' },
90
+ { name: 'Cancel', value: 'cancel' },
91
+ ];
92
+ outputPromptAsJson(buildPromptConfig('list', 'action', 'No other projects to move to. What would you like to do?', actionChoices), createMetadata('epic project', flags));
93
+ return;
94
+ }
95
+ this.log(styles.muted('\nNo other projects to move to.'));
96
+ const { action } = await inquirer.prompt([{
97
+ type: 'list',
98
+ name: 'action',
99
+ message: 'What would you like to do?',
100
+ choices: [
101
+ { name: 'Create a new project', value: 'create' },
102
+ { name: 'Cancel', value: 'cancel' },
103
+ ],
104
+ }]);
105
+ if (action === 'create') {
106
+ await this.config.runCommand('project:create', []);
107
+ }
108
+ return;
109
+ }
110
+ // Get target project
111
+ let targetProjectId = args.targetProject;
112
+ if (!targetProjectId) {
113
+ // In JSON mode, output project selection prompt
114
+ if (jsonMode) {
115
+ const projectChoices = otherProjects.map(p => ({ name: `${p.id} - ${p.name} (${p.status})`, value: p.id }));
116
+ outputPromptAsJson(buildPromptConfig('list', 'targetProject', 'Select target project:', projectChoices), createMetadata('epic project', flags));
117
+ return;
118
+ }
119
+ const { selected } = await inquirer.prompt([{
120
+ type: 'list',
121
+ name: 'selected',
122
+ message: 'Select target project:',
123
+ choices: otherProjects.map(p => ({
124
+ name: `${p.id} - ${p.name} (${p.status})`,
125
+ value: p.id,
126
+ })),
127
+ }]);
128
+ targetProjectId = selected;
129
+ }
130
+ // Validate target project
131
+ const targetProject = projects.find(p => p.id === targetProjectId);
132
+ if (!targetProject) {
133
+ this.error(`Project not found: ${targetProjectId}`);
134
+ }
135
+ if (targetProjectId === sourceProjectId) {
136
+ this.log(styles.muted('\nEpic is already in this project.'));
137
+ return;
138
+ }
139
+ // Get database for direct updates
140
+ const db = this.storage.db;
141
+ // Get tickets associated with this epic
142
+ const epicTickets = await this.storage.getTicketsForEpic(sourceProjectId, epicId);
143
+ // Handle tickets
144
+ let moveTickets = flags['with-tickets'];
145
+ if (epicTickets.length > 0 && !flags['with-tickets']) {
146
+ // In JSON mode, output ticket handling prompt
147
+ if (jsonMode) {
148
+ const ticketActionChoices = [
149
+ { name: 'Move tickets with epic', value: 'move' },
150
+ { name: 'Keep tickets in source project (unlink from epic)', value: 'unlink' },
151
+ { name: 'Cancel', value: 'cancel' },
152
+ ];
153
+ outputPromptAsJson(buildPromptConfig('list', 'ticketAction', `Epic has ${epicTickets.length} ticket(s) assigned. How to handle tickets?`, ticketActionChoices), createMetadata('epic project', flags));
154
+ return;
155
+ }
156
+ this.log(styles.warning(`\nEpic has ${epicTickets.length} ticket(s) assigned.`));
157
+ const { action } = await inquirer.prompt([{
158
+ type: 'list',
159
+ name: 'action',
160
+ message: 'How to handle tickets?',
161
+ choices: [
162
+ { name: 'Move tickets with epic', value: 'move' },
163
+ { name: 'Keep tickets in source project (unlink from epic)', value: 'unlink' },
164
+ { name: 'Cancel', value: 'cancel' },
165
+ ],
166
+ }]);
167
+ if (action === 'cancel') {
168
+ return;
169
+ }
170
+ moveTickets = action === 'move';
171
+ }
172
+ // Move epic to new project
173
+ db.prepare(`
174
+ UPDATE pmo_epics
175
+ SET project_id = ?, updated_at = ?
176
+ WHERE id = ?
177
+ `).run(targetProjectId, Date.now(), epicId);
178
+ // Handle tickets
179
+ const movedTicketIds = [];
180
+ if (epicTickets.length > 0) {
181
+ // Get target project's default status
182
+ const targetBoard = await this.storage.getProjectBoard(targetProjectId);
183
+ const targetStatusId = targetBoard?.columns[0]?.id;
184
+ for (const ticket of epicTickets) {
185
+ if (moveTickets) {
186
+ // Move ticket to target project with its default status
187
+ db.prepare(`
188
+ UPDATE pmo_tickets
189
+ SET project_id = ?, status_id = ?, updated_at = ?
190
+ WHERE id = ?
191
+ `).run(targetProjectId, targetStatusId, Date.now(), ticket.id);
192
+ movedTicketIds.push(ticket.id);
193
+ }
194
+ else {
195
+ // Unlink ticket from epic (keep in source project)
196
+ db.prepare(`
197
+ UPDATE pmo_tickets
198
+ SET epic_id = NULL, updated_at = ?
199
+ WHERE id = ?
200
+ `).run(Date.now(), ticket.id);
201
+ }
202
+ }
203
+ }
204
+ await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
205
+ this.log(styles.success(`\n✅ Moved epic ${styles.emphasis(epicId)} to project ${styles.emphasis(targetProjectId)}`));
206
+ this.log(styles.muted(` From: ${sourceProjectId}`));
207
+ this.log(styles.muted(` To: ${targetProjectId}`));
208
+ if (movedTicketIds.length > 0) {
209
+ this.log(styles.muted(`\n Moved ${movedTicketIds.length} ticket(s) with epic:`));
210
+ for (const ticketId of movedTicketIds) {
211
+ this.log(styles.muted(` - ${ticketId}`));
212
+ }
213
+ }
214
+ else if (epicTickets.length > 0) {
215
+ this.log(styles.muted(`\n ${epicTickets.length} ticket(s) unlinked and kept in source project.`));
216
+ }
217
+ this.log(styles.muted(`\nView epic: prlt epic view ${epicId}`));
218
+ }
219
+ }
@@ -0,0 +1,21 @@
1
+ import { PMOCommand } from '../../lib/pmo/index.js';
2
+ export default class EpicReorder extends PMOCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
7
+ position: import("@oclif/core/interfaces").Arg<number | undefined, {
8
+ max?: number;
9
+ min?: number;
10
+ }>;
11
+ };
12
+ static flags: {
13
+ first: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ last: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ after: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ before: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
18
+ project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
+ };
20
+ execute(): Promise<void>;
21
+ }
@@ -0,0 +1,160 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import inquirer from 'inquirer';
3
+ import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
4
+ import { styles } from '../../lib/styles.js';
5
+ import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
6
+ export default class EpicReorder extends PMOCommand {
7
+ static description = 'Reorder epic priority/rank';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %> EPIC-001 1',
10
+ '<%= config.bin %> <%= command.id %> EPIC-003 --first',
11
+ '<%= config.bin %> <%= command.id %> EPIC-002 --after EPIC-001',
12
+ ];
13
+ static args = {
14
+ id: Args.string({
15
+ description: 'Epic ID to reorder',
16
+ required: false,
17
+ }),
18
+ position: Args.integer({
19
+ description: 'New position (1-based rank)',
20
+ required: false,
21
+ }),
22
+ };
23
+ static flags = {
24
+ ...pmoBaseFlags,
25
+ first: Flags.boolean({
26
+ description: 'Move to first position (highest priority)',
27
+ exclusive: ['last', 'after', 'before'],
28
+ }),
29
+ last: Flags.boolean({
30
+ description: 'Move to last position (lowest priority)',
31
+ exclusive: ['first', 'after', 'before'],
32
+ }),
33
+ after: Flags.string({
34
+ description: 'Move after this epic ID',
35
+ exclusive: ['first', 'last', 'before'],
36
+ }),
37
+ before: Flags.string({
38
+ description: 'Move before this epic ID',
39
+ exclusive: ['first', 'last', 'after'],
40
+ }),
41
+ json: Flags.boolean({
42
+ description: 'Output prompt configuration as JSON (for AI agents/scripts)',
43
+ default: false,
44
+ }),
45
+ };
46
+ async execute() {
47
+ const { args, flags } = await this.parse(EpicReorder);
48
+ // Check if JSON output mode is active
49
+ const jsonMode = shouldOutputJson(flags);
50
+ // Helper to handle errors in JSON mode
51
+ const handleError = (code, message) => {
52
+ if (jsonMode) {
53
+ outputErrorAsJson(code, message, createMetadata('epic reorder', flags));
54
+ this.exit(1);
55
+ }
56
+ this.error(message);
57
+ };
58
+ const projectId = await this.requireProject();
59
+ // Get all epics for context
60
+ const epics = await this.storage.listEpics(projectId, { status: 'active' });
61
+ if (epics.length === 0) {
62
+ if (jsonMode) {
63
+ outputErrorAsJson('NO_ACTIVE_EPICS', 'No active epics to reorder.', createMetadata('epic reorder', flags));
64
+ return;
65
+ }
66
+ this.log(styles.muted('\nNo active epics to reorder.'));
67
+ return;
68
+ }
69
+ let epicId = args.id;
70
+ // If no ID provided, prompt for selection
71
+ if (!epicId) {
72
+ const choices = epics.map((e, i) => ({
73
+ name: `#${i + 1} ${e.id} - ${e.title}`,
74
+ value: e.id,
75
+ }));
76
+ // In JSON mode, output epic selection prompt
77
+ if (jsonMode) {
78
+ outputPromptAsJson(buildPromptConfig('list', 'id', 'Select epic to reorder:', choices), createMetadata('epic reorder', flags));
79
+ return;
80
+ }
81
+ const { selected } = await inquirer.prompt([{
82
+ type: 'list',
83
+ name: 'selected',
84
+ message: 'Select epic to reorder:',
85
+ choices,
86
+ }]);
87
+ epicId = selected;
88
+ }
89
+ const epic = await this.storage.getEpic(epicId);
90
+ if (!epic) {
91
+ return handleError('EPIC_NOT_FOUND', `Epic not found: ${epicId}`);
92
+ }
93
+ // Determine new position
94
+ let newPosition;
95
+ if (flags.first) {
96
+ newPosition = 0;
97
+ }
98
+ else if (flags.last) {
99
+ newPosition = epics.length - 1;
100
+ }
101
+ else if (flags.after) {
102
+ const afterEpic = epics.find(e => e.id === flags.after);
103
+ if (!afterEpic) {
104
+ this.error(`Epic not found: ${flags.after}`);
105
+ }
106
+ newPosition = afterEpic.position + 1;
107
+ }
108
+ else if (flags.before) {
109
+ const beforeEpic = epics.find(e => e.id === flags.before);
110
+ if (!beforeEpic) {
111
+ this.error(`Epic not found: ${flags.before}`);
112
+ }
113
+ newPosition = beforeEpic.position;
114
+ }
115
+ else if (args.position !== undefined) {
116
+ // Convert 1-based rank to 0-based position
117
+ newPosition = args.position - 1;
118
+ if (newPosition < 0)
119
+ newPosition = 0;
120
+ if (newPosition >= epics.length)
121
+ newPosition = epics.length - 1;
122
+ }
123
+ else {
124
+ // In JSON mode, output rank input prompt
125
+ if (jsonMode) {
126
+ outputPromptAsJson(buildPromptConfig('input', 'rank', `New rank for ${epicId} (1-${epics.length}):`, undefined, String(epic.position + 1)), createMetadata('epic reorder', flags));
127
+ return;
128
+ }
129
+ // Interactive: show current order and ask for new position
130
+ this.log(`\nCurrent order:`);
131
+ epics.forEach((e, i) => {
132
+ const marker = e.id === epicId ? ' ◀' : '';
133
+ this.log(` #${i + 1} ${e.id} - ${e.title}${marker}`);
134
+ });
135
+ const { rank } = await inquirer.prompt([{
136
+ type: 'number',
137
+ name: 'rank',
138
+ message: `New rank for ${epicId} (1-${epics.length}):`,
139
+ default: epic.position + 1,
140
+ validate: (input) => {
141
+ if (input < 1 || input > epics.length) {
142
+ return `Please enter a number between 1 and ${epics.length}`;
143
+ }
144
+ return true;
145
+ },
146
+ }]);
147
+ newPosition = rank - 1;
148
+ }
149
+ // Perform reorder
150
+ await this.storage.reorderEpic(projectId, epicId, newPosition);
151
+ // Show new order
152
+ const updatedEpics = await this.storage.listEpics(projectId, { status: 'active' });
153
+ this.log(styles.success(`\n✅ Reordered ${epicId}`));
154
+ this.log(`\nNew priority order:`);
155
+ updatedEpics.forEach((e, i) => {
156
+ const marker = e.id === epicId ? styles.emphasis(' ◀') : '';
157
+ this.log(` #${i + 1} ${e.id} - ${e.title}${marker}`);
158
+ });
159
+ }
160
+ }
@@ -0,0 +1,15 @@
1
+ import { PMOCommand } from '../../lib/pmo/index.js';
2
+ export default class EpicSpec extends PMOCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ epicId: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
7
+ specId: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
8
+ };
9
+ static flags: {
10
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ unlink: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ };
14
+ execute(): Promise<void>;
15
+ }
@@ -0,0 +1,191 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import inquirer from 'inquirer';
3
+ import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
4
+ import { styles } from '../../lib/styles.js';
5
+ import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
6
+ export default class EpicSpec extends PMOCommand {
7
+ static description = 'Assign a spec to an epic (design document)';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %> EPIC-001 SPEC-001',
10
+ '<%= config.bin %> <%= command.id %> EPIC-001',
11
+ '<%= config.bin %> <%= command.id %>',
12
+ '<%= config.bin %> <%= command.id %> EPIC-001 --unlink',
13
+ ];
14
+ static args = {
15
+ epicId: Args.string({
16
+ description: 'Epic ID',
17
+ required: false,
18
+ }),
19
+ specId: Args.string({
20
+ description: 'Spec ID to link',
21
+ required: false,
22
+ }),
23
+ };
24
+ static flags = {
25
+ ...pmoBaseFlags,
26
+ json: Flags.boolean({
27
+ description: 'Output prompt configuration as JSON (for AI agents/scripts)',
28
+ default: false,
29
+ }),
30
+ unlink: Flags.boolean({
31
+ char: 'u',
32
+ description: 'Remove spec from epic instead of adding',
33
+ default: false,
34
+ }),
35
+ };
36
+ async execute() {
37
+ const { args, flags } = await this.parse(EpicSpec);
38
+ // Check if JSON output mode is active
39
+ const jsonMode = shouldOutputJson(flags);
40
+ // Helper to handle errors in JSON mode
41
+ const handleError = (code, message) => {
42
+ if (jsonMode) {
43
+ outputErrorAsJson(code, message, createMetadata('epic spec', flags));
44
+ this.exit(1);
45
+ }
46
+ this.error(message);
47
+ };
48
+ const projectId = await this.requireProject();
49
+ // Get all epics
50
+ const epics = await this.storage.listEpics(projectId);
51
+ if (epics.length === 0) {
52
+ if (jsonMode) {
53
+ outputErrorAsJson('NO_EPICS', 'No epics found.', createMetadata('epic spec', flags));
54
+ return;
55
+ }
56
+ this.log(styles.muted('\nNo epics found. Create one with: prlt epic create'));
57
+ return;
58
+ }
59
+ let epicId = args.epicId;
60
+ // If no epic ID provided, prompt for selection
61
+ if (!epicId) {
62
+ const epicChoices = epics.map(e => {
63
+ const specLabel = e.specId ? ` [spec: ${e.specId}]` : '';
64
+ return {
65
+ name: `${e.id} ${e.title} (${e.status})${specLabel}`,
66
+ value: e.id,
67
+ };
68
+ });
69
+ // In JSON mode, output epic selection prompt
70
+ if (jsonMode) {
71
+ outputPromptAsJson(buildPromptConfig('list', 'epicId', 'Select epic:', epicChoices), createMetadata('epic spec', flags));
72
+ return;
73
+ }
74
+ const { selected } = await inquirer.prompt([{
75
+ type: 'list',
76
+ name: 'selected',
77
+ message: 'Select epic:',
78
+ choices: epicChoices,
79
+ }]);
80
+ epicId = selected;
81
+ }
82
+ // Validate epic exists
83
+ const epic = epics.find(e => e.id === epicId);
84
+ if (!epic) {
85
+ return handleError('EPIC_NOT_FOUND', `Epic not found: ${epicId}`);
86
+ }
87
+ // Handle unlink
88
+ if (flags.unlink) {
89
+ if (!epic.specId) {
90
+ this.log(styles.muted(`\nEpic ${epicId} is not linked to any spec.`));
91
+ }
92
+ else {
93
+ const oldSpecId = epic.specId;
94
+ await this.storage.updateEpic(epicId, { specId: undefined });
95
+ this.log(styles.success(`\n✅ Unlinked spec "${styles.emphasis(oldSpecId)}" from epic ${styles.emphasis(epicId)} "${epic.title}"`));
96
+ }
97
+ return;
98
+ }
99
+ // Get all specs
100
+ const specs = await this.storage.listSpecs();
101
+ if (specs.length === 0) {
102
+ if (jsonMode) {
103
+ outputErrorAsJson('NO_SPECS', 'No specs found.', createMetadata('epic spec', flags));
104
+ return;
105
+ }
106
+ this.log(styles.muted('\nNo specs found. Create one with: prlt spec create'));
107
+ return;
108
+ }
109
+ let specId = args.specId;
110
+ // If no spec ID provided, prompt for selection
111
+ if (!specId) {
112
+ const specChoices = specs.map(s => ({
113
+ name: `${s.id} - ${s.title} (${s.status})`,
114
+ value: s.id,
115
+ }));
116
+ // In JSON mode, output spec selection prompt
117
+ if (jsonMode) {
118
+ outputPromptAsJson(buildPromptConfig('list', 'specId', `Select spec to link to ${epicId}:`, specChoices), createMetadata('epic spec', flags));
119
+ return;
120
+ }
121
+ const { selected } = await inquirer.prompt([{
122
+ type: 'list',
123
+ name: 'selected',
124
+ message: `Select spec to link to ${epicId}:`,
125
+ choices: specChoices,
126
+ }]);
127
+ specId = selected;
128
+ }
129
+ // Validate spec exists
130
+ const spec = specs.find(s => s.id === specId);
131
+ if (!spec) {
132
+ this.error(`Spec not found: ${specId}`);
133
+ }
134
+ // Check if already linked
135
+ if (epic.specId === specId) {
136
+ this.log(styles.muted(`\nEpic "${epicId}" is already linked to spec "${specId}".`));
137
+ return;
138
+ }
139
+ // Warn if epic has different spec
140
+ if (epic.specId) {
141
+ this.log(styles.warning(`Epic "${epicId}" is currently linked to spec "${epic.specId}"`));
142
+ this.log(styles.muted(`This will replace the existing spec link.`));
143
+ }
144
+ // Reconciliation: Check if epic's tickets have different specs
145
+ const epicTickets = await this.storage.getTicketsForEpic(projectId, epicId);
146
+ const ticketsWithDifferentSpec = epicTickets.filter(t => t.specId && t.specId !== specId);
147
+ if (ticketsWithDifferentSpec.length > 0) {
148
+ // In JSON mode, output spec mismatch handling prompt
149
+ if (jsonMode) {
150
+ const mismatchChoices = [
151
+ { name: 'Update epic only (tickets keep their specs)', value: 'epic_only' },
152
+ { name: `Update epic AND align all tickets to "${specId}"`, value: 'align_all' },
153
+ { name: 'Cancel', value: 'cancel' },
154
+ ];
155
+ outputPromptAsJson(buildPromptConfig('list', 'specMismatchAction', `${ticketsWithDifferentSpec.length} ticket(s) in this epic have different specs. How to handle spec mismatch?`, mismatchChoices), createMetadata('epic spec', flags));
156
+ return;
157
+ }
158
+ this.log(styles.warning(`\n⚠️ ${ticketsWithDifferentSpec.length} ticket(s) in this epic have different specs:`));
159
+ for (const t of ticketsWithDifferentSpec.slice(0, 5)) {
160
+ this.log(styles.muted(` - ${t.id}: spec "${t.specId}"`));
161
+ }
162
+ if (ticketsWithDifferentSpec.length > 5) {
163
+ this.log(styles.muted(` ... and ${ticketsWithDifferentSpec.length - 5} more`));
164
+ }
165
+ const { action } = await inquirer.prompt([{
166
+ type: 'list',
167
+ name: 'action',
168
+ message: 'How to handle spec mismatch?',
169
+ choices: [
170
+ { name: 'Update epic only (tickets keep their specs)', value: 'epic_only' },
171
+ { name: `Update epic AND align all tickets to "${specId}"`, value: 'align_all' },
172
+ { name: 'Cancel', value: 'cancel' },
173
+ ],
174
+ }]);
175
+ if (action === 'cancel') {
176
+ return;
177
+ }
178
+ if (action === 'align_all') {
179
+ for (const t of ticketsWithDifferentSpec) {
180
+ await this.storage.updateTicket(t.id, { specId });
181
+ this.log(styles.muted(` Updated ${t.id} to spec "${specId}"`));
182
+ }
183
+ }
184
+ }
185
+ // Link spec to epic
186
+ await this.storage.updateEpic(epicId, { specId });
187
+ this.log(styles.success(`\n✅ Linked epic ${styles.emphasis(epicId)} "${epic.title}" to spec ${styles.emphasis(specId)}`));
188
+ this.log(styles.muted(` Spec: ${spec.title}`));
189
+ this.log(styles.muted(`\nView epic: prlt epic view ${epicId}`));
190
+ }
191
+ }
@@ -0,0 +1,18 @@
1
+ import { PMOCommand } from '../../lib/pmo/index.js';
2
+ export default class EpicTicket extends PMOCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
7
+ tickets: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
8
+ };
9
+ static strict: boolean;
10
+ static flags: {
11
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ unlink: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
+ spec: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
+ 'unlink-spec': import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ };
17
+ execute(): Promise<void>;
18
+ }