@proletariat/cli 0.2.0 → 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 +512 -253
  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,679 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { execSync } from 'node:child_process';
4
+ import inquirer from 'inquirer';
5
+ import chalk from 'chalk';
6
+ import { styles } from '../styles.js';
7
+ import { colors } from '../colors.js';
8
+ import { openWorkspaceDatabase, addRepositoriesToDatabase, getWorkspaceRepositories } from '../database/index.js';
9
+ import { createDevcontainerConfig } from '../execution/devcontainer.js';
10
+ import { findHQRoot } from '../workspace.js';
11
+ /**
12
+ * Check if we're currently in a git repository
13
+ */
14
+ export function isInGitRepo(dir = process.cwd()) {
15
+ try {
16
+ execSync('git rev-parse --git-dir', {
17
+ cwd: dir,
18
+ stdio: 'pipe'
19
+ });
20
+ return true;
21
+ }
22
+ catch {
23
+ // Not in a git repo - git rev-parse exits with non-zero status
24
+ return false;
25
+ }
26
+ }
27
+ /**
28
+ * Get the current repository name
29
+ */
30
+ export function getCurrentRepoName(dir = process.cwd()) {
31
+ if (!isInGitRepo(dir)) {
32
+ return null;
33
+ }
34
+ try {
35
+ const remoteUrl = execSync('git config --get remote.origin.url', {
36
+ cwd: dir,
37
+ stdio: 'pipe',
38
+ encoding: 'utf-8'
39
+ }).trim();
40
+ // Extract repo name from URL
41
+ const match = remoteUrl.match(/\/([^\/]+?)(\.git)?$/);
42
+ if (match) {
43
+ return match[1];
44
+ }
45
+ }
46
+ catch {
47
+ // No remote origin, use directory name
48
+ }
49
+ return path.basename(dir);
50
+ }
51
+ /**
52
+ * Prompt user to add repositories interactively
53
+ */
54
+ export async function promptForRepositories(currentDir = process.cwd(), existingRepos = []) {
55
+ const repos = [];
56
+ const inGitRepo = isInGitRepo(currentDir);
57
+ // Start with current repo if we're in one
58
+ if (inGitRepo) {
59
+ const currentRepoName = getCurrentRepoName(currentDir) || path.basename(currentDir);
60
+ // Check if this repo is already added
61
+ if (!existingRepos.includes(currentRepoName)) {
62
+ const { addCurrent } = await inquirer.prompt([{
63
+ type: 'list',
64
+ name: 'addCurrent',
65
+ message: `Add current repository (${currentRepoName}) to repos/?`,
66
+ choices: [
67
+ { name: 'Yes', value: true },
68
+ { name: 'No', value: false }
69
+ ],
70
+ default: true,
71
+ }]);
72
+ if (addCurrent) {
73
+ // Can only clone (not move) the current repo since we're inside it
74
+ console.log(styles.muted('Note: Current repository will be cloned (cannot move while inside it)'));
75
+ repos.push({ path: currentDir, action: 'clone' });
76
+ }
77
+ }
78
+ }
79
+ // Loop to add more repos
80
+ let addingRepos = true;
81
+ while (addingRepos) {
82
+ const { repoAction } = await inquirer.prompt([{
83
+ type: 'list',
84
+ name: 'repoAction',
85
+ message: repos.length === 0
86
+ ? 'How would you like to add repositories to the HQ?'
87
+ : 'Add another repository?',
88
+ choices: [
89
+ { name: '🔍 Search for repositories on this machine', value: 'search' },
90
+ { name: '📁 Manually enter repository path or Git URL', value: 'manual' },
91
+ { name: '✨ Create new repository', value: 'create' },
92
+ { name: repos.length === 0 ? '⏭️ Skip adding repositories' : '✅ Done adding repositories', value: 'skip' }
93
+ ],
94
+ default: repos.length === 0 ? 'search' : 'skip'
95
+ }]);
96
+ if (repoAction === 'skip') {
97
+ addingRepos = false;
98
+ break;
99
+ }
100
+ if (repoAction === 'create') {
101
+ const newRepo = await createNewRepository();
102
+ if (newRepo) {
103
+ repos.push(newRepo);
104
+ }
105
+ continue;
106
+ }
107
+ if (repoAction === 'search') {
108
+ const foundRepos = await searchForRepositories();
109
+ repos.push(...foundRepos);
110
+ // After search, ask if they want to add more (unless they selected nothing)
111
+ if (foundRepos.length > 0) {
112
+ const { addMoreAfterSearch } = await inquirer.prompt([{
113
+ type: 'list',
114
+ name: 'addMoreAfterSearch',
115
+ message: 'Would you like to add more repositories?',
116
+ choices: [
117
+ { name: 'No', value: false },
118
+ { name: 'Yes', value: true }
119
+ ],
120
+ default: false
121
+ }]);
122
+ if (!addMoreAfterSearch) {
123
+ addingRepos = false;
124
+ break;
125
+ }
126
+ }
127
+ continue;
128
+ }
129
+ // Manual entry (existing logic)
130
+ const { repoPath } = await inquirer.prompt([{
131
+ type: 'input',
132
+ name: 'repoPath',
133
+ message: 'Enter repo path or Git URL:',
134
+ validate: (input) => input.trim() ? true : 'Path or URL required',
135
+ }]);
136
+ const trimmedPath = repoPath.trim();
137
+ if (trimmedPath.startsWith('http://') ||
138
+ trimmedPath.startsWith('https://') ||
139
+ trimmedPath.startsWith('git@')) {
140
+ // Git URL - always clone
141
+ repos.push({ path: trimmedPath, action: 'clone' });
142
+ console.log(styles.muted(`Will clone: ${trimmedPath}`));
143
+ }
144
+ else {
145
+ // Local path - ask move or clone
146
+ const resolvedPath = path.resolve(trimmedPath);
147
+ const repoName = path.basename(resolvedPath);
148
+ // Check if we're currently inside this repo
149
+ const currentlyInside = process.cwd().startsWith(resolvedPath);
150
+ if (currentlyInside) {
151
+ console.log(chalk.yellow(`Cannot move ${repoName} - you're currently inside it. Will clone instead.`));
152
+ repos.push({ path: resolvedPath, action: 'clone' });
153
+ }
154
+ else {
155
+ const { action } = await inquirer.prompt([{
156
+ type: 'list',
157
+ name: 'action',
158
+ message: `${repoName} - Move or Clone?`,
159
+ choices: [
160
+ { name: 'Clone (keep original)', value: 'clone' },
161
+ { name: 'Move (relocate to HQ)', value: 'move' },
162
+ ],
163
+ }]);
164
+ repos.push({ path: resolvedPath, action: action });
165
+ }
166
+ }
167
+ }
168
+ return repos;
169
+ }
170
+ /**
171
+ * Add repositories to HQ
172
+ */
173
+ export async function addRepositoriesToHQ(hqPath, repos) {
174
+ const reposDir = path.join(hqPath, 'repos');
175
+ // Ensure repos directory exists
176
+ if (!fs.existsSync(reposDir)) {
177
+ fs.mkdirSync(reposDir, { recursive: true });
178
+ }
179
+ const addedRepos = [];
180
+ for (const repo of repos) {
181
+ const repoName = path.basename(repo.path).replace(/\.git$/, '');
182
+ const targetPath = path.join(reposDir, repoName);
183
+ // Check if repo already exists
184
+ if (fs.existsSync(targetPath)) {
185
+ console.log(chalk.yellow(`Repository ${repoName} already exists in repos/`));
186
+ continue;
187
+ }
188
+ try {
189
+ if (repo.action === 'move') {
190
+ // Move the repository
191
+ console.log(styles.muted(`Moving ${repo.path} to repos/${repoName}...`));
192
+ fs.renameSync(repo.path, targetPath);
193
+ }
194
+ else {
195
+ // Clone the repository
196
+ console.log(styles.muted(`Cloning ${repo.path} to repos/${repoName}...`));
197
+ execSync(`git clone ${repo.path} ${targetPath}`, {
198
+ stdio: 'inherit'
199
+ });
200
+ }
201
+ addedRepos.push(repoName);
202
+ console.log(chalk.green(`✅ Repository ${repoName} added successfully`));
203
+ }
204
+ catch (error) {
205
+ console.log(chalk.red(`Could not ${repo.action} repository: ${repo.path}`));
206
+ console.log(chalk.red(`Error: ${error}`));
207
+ }
208
+ }
209
+ return addedRepos;
210
+ }
211
+ /**
212
+ * Update HQ config with new repositories
213
+ */
214
+ export function updateHQRepos(hqPath, newRepos) {
215
+ const configPath = path.join(hqPath, '.proletariat', 'config.json');
216
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
217
+ // Add new repos to the list (avoiding duplicates)
218
+ const existingRepos = config.repos || [];
219
+ const uniqueNewRepos = newRepos.filter(r => !existingRepos.includes(r));
220
+ config.repos = [...existingRepos, ...uniqueNewRepos];
221
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
222
+ }
223
+ /**
224
+ * Create a new repository in the HQ
225
+ */
226
+ async function createNewRepository() {
227
+ const { repoName, initWithReadme } = await inquirer.prompt([
228
+ {
229
+ type: 'input',
230
+ name: 'repoName',
231
+ message: 'Repository name:',
232
+ validate: (input) => {
233
+ if (!input.trim())
234
+ return 'Repository name is required';
235
+ if (!/^[a-zA-Z0-9-_]+$/.test(input)) {
236
+ return 'Repository name can only contain letters, numbers, hyphens, and underscores';
237
+ }
238
+ return true;
239
+ }
240
+ },
241
+ {
242
+ type: 'list',
243
+ name: 'initWithReadme',
244
+ message: 'Initialize with README.md?',
245
+ choices: [
246
+ { name: 'Yes', value: true },
247
+ { name: 'No', value: false }
248
+ ],
249
+ default: true
250
+ }
251
+ ]);
252
+ const repoPath = `/tmp/new-repo-${repoName}`;
253
+ try {
254
+ // Create temporary directory for new repo
255
+ fs.mkdirSync(repoPath, { recursive: true });
256
+ // Initialize git repository
257
+ execSync('git init', { cwd: repoPath });
258
+ execSync('git config user.email "init@proletariat.local"', { cwd: repoPath });
259
+ execSync('git config user.name "Proletariat Init"', { cwd: repoPath });
260
+ if (initWithReadme) {
261
+ const readmeContent = `# ${repoName}\n\nCreated by Proletariat CLI\n`;
262
+ fs.writeFileSync(path.join(repoPath, 'README.md'), readmeContent);
263
+ execSync('git add README.md', { cwd: repoPath });
264
+ execSync('git commit -m "Initial commit"', { cwd: repoPath });
265
+ }
266
+ console.log(chalk.green(`✅ Created new repository: ${repoName}`));
267
+ return { path: repoPath, action: 'move' };
268
+ }
269
+ catch (error) {
270
+ console.log(chalk.red(`Failed to create repository ${repoName}: ${error}`));
271
+ return null;
272
+ }
273
+ }
274
+ /**
275
+ * Search for existing git repositories on the machine
276
+ */
277
+ async function searchForRepositories() {
278
+ console.log(chalk.blue('🔍 Searching for git repositories...'));
279
+ // Common development directories to search
280
+ const searchPaths = [
281
+ path.join(process.env.HOME || '~', 'Projects'),
282
+ path.join(process.env.HOME || '~', 'Developer'),
283
+ path.join(process.env.HOME || '~', 'Code'),
284
+ path.join(process.env.HOME || '~', 'workspace'),
285
+ path.join(process.env.HOME || '~', 'src'),
286
+ ].filter(p => fs.existsSync(p));
287
+ if (searchPaths.length === 0) {
288
+ console.log(chalk.yellow('No common development directories found.'));
289
+ return [];
290
+ }
291
+ const foundRepos = [];
292
+ for (const searchPath of searchPaths) {
293
+ try {
294
+ // Find .git directories (limiting depth for performance)
295
+ const result = execSync(`find "${searchPath}" -name ".git" -type d -maxdepth 3`, {
296
+ encoding: 'utf-8',
297
+ stdio: 'pipe'
298
+ }).trim();
299
+ if (result) {
300
+ const gitDirs = result.split('\n');
301
+ const repoPaths = gitDirs.map(gitDir => path.dirname(gitDir));
302
+ foundRepos.push(...repoPaths);
303
+ }
304
+ }
305
+ catch {
306
+ // Skip directories we can't access
307
+ console.log(styles.muted(`Skipped ${searchPath} (no access)`));
308
+ }
309
+ }
310
+ if (foundRepos.length === 0) {
311
+ console.log(chalk.yellow('No git repositories found in common directories.'));
312
+ return [];
313
+ }
314
+ // Remove duplicates and sort alphabetically by repo name
315
+ const uniqueRepos = [...new Set(foundRepos)].sort((a, b) => path.basename(a).toLowerCase().localeCompare(path.basename(b).toLowerCase()));
316
+ const repoChoices = uniqueRepos.map(repoPath => ({
317
+ name: `${path.basename(repoPath)} (${repoPath})`,
318
+ value: repoPath
319
+ }));
320
+ const { selectedRepos } = await inquirer.prompt([{
321
+ type: 'checkbox',
322
+ name: 'selectedRepos',
323
+ message: `Found ${uniqueRepos.length} repositories. Select which ones to add (SPACE to select, ENTER when done):`,
324
+ choices: repoChoices,
325
+ pageSize: 10,
326
+ validate: (choices) => {
327
+ if (choices.length === 0) {
328
+ return 'No repositories selected. Press SPACE to select repositories, or ENTER to continue with none.';
329
+ }
330
+ return true;
331
+ },
332
+ }]);
333
+ console.log(chalk.green(`✅ Selected ${selectedRepos.length} repositories`));
334
+ return selectedRepos.map((repoPath) => ({ path: repoPath, action: 'clone' }));
335
+ }
336
+ /**
337
+ * Find HQ root by traversing upward
338
+ * @deprecated Use findHQRoot from '../workspace.js' instead for PRLT_HQ_PATH support
339
+ */
340
+ export { findHQRoot } from '../workspace.js';
341
+ /**
342
+ * Get workspace repository information
343
+ */
344
+ export function getWorkspaceRepoInfo() {
345
+ const hqPath = findHQRoot();
346
+ if (!hqPath) {
347
+ throw new Error('Not in an HQ directory. Run "prlt init" first.');
348
+ }
349
+ const reposPath = path.join(hqPath, 'repos');
350
+ const dbRepos = getWorkspaceRepositories(hqPath);
351
+ const repositories = dbRepos.map(repo => {
352
+ const fullPath = path.join(hqPath, repo.path);
353
+ return getRepoStatus(repo.name, fullPath, repo);
354
+ });
355
+ return { hqPath, reposPath, repositories };
356
+ }
357
+ /**
358
+ * Get detailed status for a repository
359
+ */
360
+ export function getRepoStatus(name, fullPath, dbRepo) {
361
+ const info = {
362
+ name,
363
+ path: dbRepo?.path || `repos/${name}`,
364
+ fullPath,
365
+ sourceUrl: dbRepo?.source_url,
366
+ status: 'missing',
367
+ commitsAhead: 0,
368
+ commitsBehind: 0,
369
+ addedAt: dbRepo?.added_at
370
+ };
371
+ if (!fs.existsSync(fullPath)) {
372
+ return info;
373
+ }
374
+ try {
375
+ // Get current branch
376
+ info.branch = execSync('git rev-parse --abbrev-ref HEAD', {
377
+ cwd: fullPath,
378
+ stdio: 'pipe',
379
+ encoding: 'utf-8'
380
+ }).trim();
381
+ // Check for uncommitted changes
382
+ const status = execSync('git status --porcelain', {
383
+ cwd: fullPath,
384
+ stdio: 'pipe',
385
+ encoding: 'utf-8'
386
+ }).trim();
387
+ info.status = status.length > 0 ? 'dirty' : 'clean';
388
+ // Get commits ahead/behind
389
+ try {
390
+ const aheadBehind = execSync('git rev-list --left-right --count @{upstream}...HEAD', {
391
+ cwd: fullPath,
392
+ stdio: 'pipe',
393
+ encoding: 'utf-8'
394
+ }).trim();
395
+ const [behind, ahead] = aheadBehind.split('\t').map(Number);
396
+ info.commitsAhead = ahead || 0;
397
+ info.commitsBehind = behind || 0;
398
+ }
399
+ catch {
400
+ // No upstream configured
401
+ }
402
+ }
403
+ catch {
404
+ // Git command failed
405
+ info.status = 'missing';
406
+ }
407
+ return info;
408
+ }
409
+ // =============================================================================
410
+ // Repository CRUD Operations
411
+ // =============================================================================
412
+ /**
413
+ * Add a single repository to the HQ (file system + database + agent worktrees)
414
+ */
415
+ export async function addRepository(hqPath, repoPath, action) {
416
+ const repoName = path.basename(repoPath).replace(/\.git$/, '');
417
+ const reposDir = path.join(hqPath, 'repos');
418
+ const targetPath = path.join(reposDir, repoName);
419
+ // Ensure repos directory exists
420
+ if (!fs.existsSync(reposDir)) {
421
+ fs.mkdirSync(reposDir, { recursive: true });
422
+ }
423
+ // Check if repo already exists
424
+ if (fs.existsSync(targetPath)) {
425
+ return { success: false, name: repoName, error: 'Repository already exists' };
426
+ }
427
+ try {
428
+ // Add to file system
429
+ if (action === 'move') {
430
+ console.log(styles.muted(`Moving ${repoPath} to repos/${repoName}...`));
431
+ fs.renameSync(repoPath, targetPath);
432
+ }
433
+ else {
434
+ console.log(styles.muted(`Cloning ${repoPath} to repos/${repoName}...`));
435
+ execSync(`git clone "${repoPath}" "${targetPath}"`, { stdio: 'inherit' });
436
+ }
437
+ // Add to database
438
+ const dbRepoData = [{
439
+ name: repoName,
440
+ path: `repos/${repoName}`,
441
+ source_url: repoPath,
442
+ action
443
+ }];
444
+ addRepositoriesToDatabase(hqPath, dbRepoData);
445
+ // Create worktrees for existing agents
446
+ await createWorktreesForRepo(hqPath, repoName, targetPath);
447
+ // Create devcontainer config for sandboxed execution in the central repo
448
+ console.log(styles.muted(`Creating devcontainer config for ${repoName}...`));
449
+ createDevcontainerConfig({
450
+ agentName: repoName, // Use repo name as identifier
451
+ agentDir: targetPath,
452
+ repoWorktrees: [], // No nested worktrees - this is the repo itself
453
+ });
454
+ return { success: true, name: repoName };
455
+ }
456
+ catch (error) {
457
+ return {
458
+ success: false,
459
+ name: repoName,
460
+ error: error instanceof Error ? error.message : String(error)
461
+ };
462
+ }
463
+ }
464
+ /**
465
+ * Remove a repository from the HQ
466
+ */
467
+ export async function removeRepository(hqPath, repoName, keepFiles = false) {
468
+ const repoPath = path.join(hqPath, 'repos', repoName);
469
+ try {
470
+ // Remove agent worktrees first
471
+ await removeWorktreesForRepo(hqPath, repoName);
472
+ // Remove from file system (unless keepFiles)
473
+ if (!keepFiles && fs.existsSync(repoPath)) {
474
+ fs.rmSync(repoPath, { recursive: true, force: true });
475
+ }
476
+ // Remove from database
477
+ const db = openWorkspaceDatabase(hqPath);
478
+ db.prepare('DELETE FROM repositories WHERE name = ?').run(repoName);
479
+ db.close();
480
+ return { success: true };
481
+ }
482
+ catch (error) {
483
+ return {
484
+ success: false,
485
+ error: error instanceof Error ? error.message : String(error)
486
+ };
487
+ }
488
+ }
489
+ /**
490
+ * Create worktrees for a repository in all agent directories
491
+ */
492
+ async function createWorktreesForRepo(hqPath, repoName, repoPath) {
493
+ const db = openWorkspaceDatabase(hqPath);
494
+ // Get workspace config for theme info
495
+ const workspace = db.prepare('SELECT theme FROM workspace').get();
496
+ const theme = db.prepare('SELECT workspace_dir FROM themes WHERE name = ?').get(workspace.theme);
497
+ // Get all agents
498
+ const agents = db.prepare('SELECT name FROM agents').all();
499
+ if (agents.length === 0) {
500
+ db.close();
501
+ return;
502
+ }
503
+ const agentsBasePath = path.join(hqPath, 'agents', theme.workspace_dir);
504
+ for (const agent of agents) {
505
+ // Name worktree directory as {repoName}-{agentName} so git creates unique worktree entries
506
+ // e.g., proletariat-branson instead of proletariat (which causes proletariat1, proletariat2, etc.)
507
+ const worktreeDirName = `${repoName}-${agent.name}`;
508
+ const agentRepoPath = path.join(agentsBasePath, agent.name, worktreeDirName);
509
+ const branchName = `agent-${agent.name}`;
510
+ try {
511
+ // Create worktree
512
+ execSync(`git worktree add -b "${branchName}" "${agentRepoPath}"`, {
513
+ cwd: repoPath,
514
+ stdio: 'pipe'
515
+ });
516
+ // Add to database
517
+ db.prepare(`
518
+ INSERT OR REPLACE INTO agent_worktrees
519
+ (agent_name, repo_name, worktree_path, branch, created_at, commits_ahead, is_clean)
520
+ VALUES (?, ?, ?, ?, ?, 0, 1)
521
+ `).run(agent.name, repoName, `agents/${theme.workspace_dir}/${agent.name}/${worktreeDirName}`, branchName, new Date().toISOString());
522
+ }
523
+ catch {
524
+ console.log(chalk.yellow(`Warning: Could not create worktree for ${agent.name}/${repoName}`));
525
+ }
526
+ }
527
+ db.close();
528
+ }
529
+ /**
530
+ * Remove worktrees for a repository from all agent directories
531
+ */
532
+ async function removeWorktreesForRepo(hqPath, repoName) {
533
+ const db = openWorkspaceDatabase(hqPath);
534
+ // Get workspace config for theme info
535
+ const workspace = db.prepare('SELECT theme FROM workspace').get();
536
+ const theme = db.prepare('SELECT workspace_dir FROM themes WHERE name = ?').get(workspace.theme);
537
+ // Get all agents
538
+ const agents = db.prepare('SELECT name FROM agents').all();
539
+ const repoPath = path.join(hqPath, 'repos', repoName);
540
+ const agentsBasePath = path.join(hqPath, 'agents', theme.workspace_dir);
541
+ for (const agent of agents) {
542
+ const agentRepoPath = path.join(agentsBasePath, agent.name, repoName);
543
+ try {
544
+ // Remove worktree from git
545
+ if (fs.existsSync(repoPath)) {
546
+ execSync(`git worktree remove "${agentRepoPath}" --force`, {
547
+ cwd: repoPath,
548
+ stdio: 'pipe'
549
+ });
550
+ }
551
+ else if (fs.existsSync(agentRepoPath)) {
552
+ // Repo doesn't exist but worktree dir does - just remove directory
553
+ fs.rmSync(agentRepoPath, { recursive: true, force: true });
554
+ }
555
+ }
556
+ catch {
557
+ // Try to just remove the directory
558
+ if (fs.existsSync(agentRepoPath)) {
559
+ try {
560
+ fs.rmSync(agentRepoPath, { recursive: true, force: true });
561
+ }
562
+ catch {
563
+ console.log(chalk.yellow(`Warning: Could not remove worktree for ${agent.name}/${repoName}`));
564
+ }
565
+ }
566
+ }
567
+ }
568
+ // Remove from database
569
+ db.prepare('DELETE FROM agent_worktrees WHERE repo_name = ?').run(repoName);
570
+ db.close();
571
+ }
572
+ // =============================================================================
573
+ // Interactive Prompts for Commands
574
+ // =============================================================================
575
+ /**
576
+ * Prompt to add a single repository
577
+ */
578
+ export async function promptAddSingleRepo() {
579
+ const { method } = await inquirer.prompt([{
580
+ type: 'list',
581
+ name: 'method',
582
+ message: 'How would you like to add a repository?',
583
+ choices: [
584
+ { name: '🔍 Search for repositories on this machine', value: 'search' },
585
+ { name: '📁 Enter path or Git URL', value: 'manual' },
586
+ { name: '✨ Create new repository', value: 'create' },
587
+ new inquirer.Separator(),
588
+ { name: '❌ Cancel', value: 'cancel' }
589
+ ]
590
+ }]);
591
+ if (method === 'cancel') {
592
+ return null;
593
+ }
594
+ if (method === 'create') {
595
+ return createNewRepository();
596
+ }
597
+ if (method === 'search') {
598
+ const repos = await searchForRepositories();
599
+ return repos.length > 0 ? repos[0] : null;
600
+ }
601
+ // Manual entry
602
+ const { repoPath } = await inquirer.prompt([{
603
+ type: 'input',
604
+ name: 'repoPath',
605
+ message: 'Enter repo path or Git URL:',
606
+ validate: (input) => input.trim() ? true : 'Path or URL required'
607
+ }]);
608
+ const trimmedPath = repoPath.trim();
609
+ const isUrl = trimmedPath.startsWith('http://') ||
610
+ trimmedPath.startsWith('https://') ||
611
+ trimmedPath.startsWith('git@');
612
+ if (isUrl) {
613
+ return { path: trimmedPath, action: 'clone' };
614
+ }
615
+ const resolvedPath = path.resolve(trimmedPath);
616
+ const repoName = path.basename(resolvedPath);
617
+ const currentlyInside = process.cwd().startsWith(resolvedPath);
618
+ if (currentlyInside) {
619
+ console.log(chalk.yellow(`Cannot move ${repoName} - you're currently inside it. Will clone instead.`));
620
+ return { path: resolvedPath, action: 'clone' };
621
+ }
622
+ const { action } = await inquirer.prompt([{
623
+ type: 'list',
624
+ name: 'action',
625
+ message: `${repoName} - Move or Clone?`,
626
+ choices: [
627
+ { name: 'Clone (keep original)', value: 'clone' },
628
+ { name: 'Move (relocate to HQ)', value: 'move' }
629
+ ]
630
+ }]);
631
+ return { path: resolvedPath, action: action };
632
+ }
633
+ /**
634
+ * Prompt to select a repository from the workspace
635
+ */
636
+ export async function promptSelectRepo(message = 'Select repository:', allowCancel = true) {
637
+ const { repositories } = getWorkspaceRepoInfo();
638
+ if (repositories.length === 0) {
639
+ console.log(colors.warning('No repositories found. Add one with "prlt repo add"'));
640
+ return null;
641
+ }
642
+ const choices = [
643
+ ...repositories.map(repo => ({
644
+ name: `${repo.name} (${repo.status}${repo.commitsAhead > 0 ? `, ${repo.commitsAhead} ahead` : ''})`,
645
+ value: repo.name
646
+ }))
647
+ ];
648
+ if (allowCancel) {
649
+ choices.push(new inquirer.Separator(), { name: '❌ Cancel', value: 'cancel' });
650
+ }
651
+ const { selected } = await inquirer.prompt([{
652
+ type: 'list',
653
+ name: 'selected',
654
+ message,
655
+ choices
656
+ }]);
657
+ return selected === 'cancel' ? null : selected;
658
+ }
659
+ /**
660
+ * Prompt to select multiple repositories
661
+ */
662
+ export async function promptSelectMultipleRepos(message = 'Select repositories:') {
663
+ const { repositories } = getWorkspaceRepoInfo();
664
+ if (repositories.length === 0) {
665
+ console.log(colors.warning('No repositories found.'));
666
+ return [];
667
+ }
668
+ const choices = repositories.map(repo => ({
669
+ name: `${repo.name} (${repo.status}${repo.commitsAhead > 0 ? `, ${repo.commitsAhead} ahead` : ''})`,
670
+ value: repo.name
671
+ }));
672
+ const { selected } = await inquirer.prompt([{
673
+ type: 'checkbox',
674
+ name: 'selected',
675
+ message,
676
+ choices
677
+ }]);
678
+ return selected;
679
+ }