@dylanpiercey/work 0.2.18 → 0.2.20

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 (509) hide show
  1. package/README.md +6 -1
  2. package/bin/cli/plan.mjs +85 -0
  3. package/bin/cli/session.mjs +406 -41
  4. package/bin/cli/topic.mjs +63 -40
  5. package/bin/work.mjs +10 -1
  6. package/dist/_BHlbSSAl.js +182 -0
  7. package/dist/_C9c_BxRk.js +787 -0
  8. package/dist/_DrEeyoLF.js +2 -0
  9. package/dist/_E0fWorAK.js +2 -0
  10. package/dist/{_BlLEM8du.js → _Hb3LeA5Q.js} +321 -67
  11. package/dist/index.mjs +3447 -1913
  12. package/dist/public/assets/_-TUXzZ5j.js +1 -0
  13. package/dist/public/assets/_-TUXzZ5j.js.br +0 -0
  14. package/dist/public/assets/_0BO-2AH8.js +1 -0
  15. package/dist/public/assets/_1MkpPhCv.js +1 -0
  16. package/dist/public/assets/_2Czzn44S.js +2 -0
  17. package/dist/public/assets/_2Czzn44S.js.br +0 -0
  18. package/dist/public/assets/{_Dh9434oc.js → _2M3NjHcy.js} +1 -1
  19. package/dist/public/assets/_3J3NCTfA.js +1 -0
  20. package/dist/public/assets/_3yfaou9w.js +1 -0
  21. package/dist/public/assets/{_B-H6ABVZ.js → _6fcPfRKt.js} +1 -1
  22. package/dist/public/assets/_6fcPfRKt.js.br +0 -0
  23. package/dist/public/assets/_9kzNcuvf.js +1 -0
  24. package/dist/public/assets/_AbxeWvtk.js +1 -0
  25. package/dist/public/assets/{_DjYscMjF.js → _B1AH7m_8.js} +1 -1
  26. package/dist/public/assets/_B1AH7m_8.js.br +0 -0
  27. package/dist/public/assets/{_HpxvfbM2.js → _B2zs9J9f.js} +1 -1
  28. package/dist/public/assets/_B2zs9J9f.js.br +0 -0
  29. package/dist/public/assets/_B4Tl4g-I.js +1 -0
  30. package/dist/public/assets/_B6GPBTnX.js +1 -0
  31. package/dist/public/assets/{_w-MAJku6.js → _B7u83Fqc.js} +1 -1
  32. package/dist/public/assets/_B89z0EK7.js +1 -0
  33. package/dist/public/assets/{_Df-N1G_n.js → _BCYHTWZd.js} +1 -1
  34. package/dist/public/assets/_BCYHTWZd.js.br +0 -0
  35. package/dist/public/assets/_BD01_px3.js +1 -0
  36. package/dist/public/assets/_BDt0PKxz.js +1 -0
  37. package/dist/public/assets/{_RudCGuBM.js → _BFD3zDfn.js} +1 -1
  38. package/dist/public/assets/_BFD3zDfn.js.br +0 -0
  39. package/dist/public/assets/{_9JG-F3GR.js → _BH5TfgM7.js} +1 -1
  40. package/dist/public/assets/_BH5TfgM7.js.br +0 -0
  41. package/dist/public/assets/_BHEzkZBl.js +1 -0
  42. package/dist/public/assets/{_CPqT91JX.js → _BHxaJLxf.js} +1 -1
  43. package/dist/public/assets/_BHxaJLxf.js.br +0 -0
  44. package/dist/public/assets/{_DXvsvUmJ.js → _BJc28pt5.js} +1 -1
  45. package/dist/public/assets/_BJc28pt5.js.br +0 -0
  46. package/dist/public/assets/{_CpVeIwQ4.js → _BJpqJK9r.js} +1 -1
  47. package/dist/public/assets/_BJpqJK9r.js.br +0 -0
  48. package/dist/public/assets/_BKSNShOz.js +1 -0
  49. package/dist/public/assets/{_B-iOtMg6.js → _BKcc-iTi.js} +1 -1
  50. package/dist/public/assets/_BKcc-iTi.js.br +0 -0
  51. package/dist/public/assets/{_DG3L8-RO.js → _BMXIDoUj.js} +1 -1
  52. package/dist/public/assets/_BMXIDoUj.js.br +0 -0
  53. package/dist/public/assets/{_B3Z1kRpD.js → _BQMwlV-0.js} +1 -1
  54. package/dist/public/assets/_BQMwlV-0.js.br +0 -0
  55. package/dist/public/assets/_BUjgl28E.js +1 -0
  56. package/dist/public/assets/_BYUg95ML.js +1 -0
  57. package/dist/public/assets/{_BIUaA4Nl.js → _B_LxZatx.js} +1 -1
  58. package/dist/public/assets/_B_LxZatx.js.br +0 -0
  59. package/dist/public/assets/{_Bs_MPTBZ.js → _BeQUut65.js} +1 -1
  60. package/dist/public/assets/_BeQUut65.js.br +0 -0
  61. package/dist/public/assets/{_B4hn3NNW.js → _Bf7EsJwj.js} +1 -1
  62. package/dist/public/assets/_Bf7EsJwj.js.br +0 -0
  63. package/dist/public/assets/_BfVmvTXe.js +1 -0
  64. package/dist/public/assets/_BfqDnPV7.js +1 -0
  65. package/dist/public/assets/{_CUxBk_RE.js → _Bfuu6mAX.js} +1 -1
  66. package/dist/public/assets/_Bfuu6mAX.js.br +0 -0
  67. package/dist/public/assets/{_DNrRZhO7.js → _BgBUZElB.js} +1 -1
  68. package/dist/public/assets/_BgBUZElB.js.br +0 -0
  69. package/dist/public/assets/{_B26gPL08.js → _Bgbj7Vl5.js} +1 -1
  70. package/dist/public/assets/_Bgbj7Vl5.js.br +0 -0
  71. package/dist/public/assets/{_DRpsUHP5.js → _BhrCWDl2.js} +1 -1
  72. package/dist/public/assets/_BhrCWDl2.js.br +0 -0
  73. package/dist/public/assets/_Bjsevhjr.js +1 -0
  74. package/dist/public/assets/_BjzBYn47.js +1 -0
  75. package/dist/public/assets/_BmyB1F-C.js +1 -0
  76. package/dist/public/assets/{_BXHggM8M.js → _BpGvpggY.js} +1 -1
  77. package/dist/public/assets/_BpGvpggY.js.br +0 -0
  78. package/dist/public/assets/_BpjknrsF.js +1 -0
  79. package/dist/public/assets/{_WOU8TCkO.js → _BpunB-I_.js} +1 -1
  80. package/dist/public/assets/_BpunB-I_.js.br +0 -0
  81. package/dist/public/assets/{_CcINcTUt.js → _Bqgtb-fc.js} +1 -1
  82. package/dist/public/assets/_Bqgtb-fc.js.br +0 -0
  83. package/dist/public/assets/_BtkDWVh9.js +1 -0
  84. package/dist/public/assets/{_5tN48iuJ.js → _BvEJgNLp.js} +1 -1
  85. package/dist/public/assets/_BvEJgNLp.js.br +0 -0
  86. package/dist/public/assets/_BvYgAZl3.js +1 -0
  87. package/dist/public/assets/_C0Bfz_Is.js +1 -0
  88. package/dist/public/assets/_C1Aa6bJ9.js +1 -0
  89. package/dist/public/assets/_C3i3LRNx.js +1 -0
  90. package/dist/public/assets/_C4RHKQLq.js +1 -0
  91. package/dist/public/assets/{_Cfts4mFJ.js → _C5Wk6L8u.js} +1 -1
  92. package/dist/public/assets/_C5Wk6L8u.js.br +0 -0
  93. package/dist/public/assets/_C7N1s7w_.js +1 -0
  94. package/dist/public/assets/_C7N1s7w_.js.br +0 -0
  95. package/dist/public/assets/_C96lrIeU.js +1 -0
  96. package/dist/public/assets/{_B6VtVybz.js → _CAhkFk0k.js} +1 -1
  97. package/dist/public/assets/_CAhkFk0k.js.br +0 -0
  98. package/dist/public/assets/{_BD1SQU0V.js → _CCmHKlXX.js} +1 -1
  99. package/dist/public/assets/_CCmHKlXX.js.br +0 -0
  100. package/dist/public/assets/{_C9k00otG.js → _CEY_n10t.js} +1 -1
  101. package/dist/public/assets/_CEY_n10t.js.br +0 -0
  102. package/dist/public/assets/_CEejNMib.js +1 -0
  103. package/dist/public/assets/_CFo4GZR9.js +1 -0
  104. package/dist/public/assets/{_vG7bXn-C.js → _CGH2Busx.js} +1 -1
  105. package/dist/public/assets/_CGH2Busx.js.br +0 -0
  106. package/dist/public/assets/{_BJpBnuvv.js → _CHwp4prQ.js} +1 -1
  107. package/dist/public/assets/_CHwp4prQ.js.br +0 -0
  108. package/dist/public/assets/{_BXPUZfKX.js → _CN7Wz2eA.js} +1 -1
  109. package/dist/public/assets/_CN7Wz2eA.js.br +0 -0
  110. package/dist/public/assets/_CP58TjsV.js +1 -0
  111. package/dist/public/assets/_CP58TjsV.js.br +0 -0
  112. package/dist/public/assets/_CPruMiA4.js +1 -0
  113. package/dist/public/assets/_CQEZuOE_.js +1 -0
  114. package/dist/public/assets/_CSMoDPwM.js +16 -0
  115. package/dist/public/assets/_CSMoDPwM.js.br +0 -0
  116. package/dist/public/assets/{_GK8r-gEu.js → _CVEabnQh.js} +1 -1
  117. package/dist/public/assets/_CVEabnQh.js.br +0 -0
  118. package/dist/public/assets/{_CLV83hY7.js → _CWTelCGM.js} +1 -1
  119. package/dist/public/assets/_CWTelCGM.js.br +0 -0
  120. package/dist/public/assets/_CXpplsaj.js +1 -0
  121. package/dist/public/assets/{_C46o3wQ8.js → _CY0xLX0Y.js} +1 -1
  122. package/dist/public/assets/_CY0xLX0Y.js.br +0 -0
  123. package/dist/public/assets/{_DG_QOtsx.js → _CZNztOn6.js} +1 -1
  124. package/dist/public/assets/_CZNztOn6.js.br +0 -0
  125. package/dist/public/assets/{_Bt4cxzaP.js → _Cabq459u.js} +1 -1
  126. package/dist/public/assets/_Cb593OOX.js +1 -0
  127. package/dist/public/assets/_Cbis2WSl.js +1 -0
  128. package/dist/public/assets/{_10dZ1R0m.js → _CeZa36O-.js} +1 -1
  129. package/dist/public/assets/_CeZa36O-.js.br +0 -0
  130. package/dist/public/assets/{_DZqoQxTm.js → _ChTMXnIu.js} +1 -1
  131. package/dist/public/assets/_ChTMXnIu.js.br +0 -0
  132. package/dist/public/assets/_Cig63HLr.js +1 -0
  133. package/dist/public/assets/_CjkPh72t.js +1 -0
  134. package/dist/public/assets/_Cm6nigjK.js +1 -0
  135. package/dist/public/assets/_CnAEQUMb.js +1 -0
  136. package/dist/public/assets/{_CX5VOdNU.js → _Coroy2lI.js} +1 -1
  137. package/dist/public/assets/_Coroy2lI.js.br +0 -0
  138. package/dist/public/assets/_CpAeLnqO.js +1 -0
  139. package/dist/public/assets/_CpAeLnqO.js.br +0 -0
  140. package/dist/public/assets/_Cpkby1iI.js +1 -0
  141. package/dist/public/assets/_Cs0Q8LaN.js +1 -0
  142. package/dist/public/assets/_Ct2pbvTU.js +1 -0
  143. package/dist/public/assets/{_DUH5o_iN.js → _CtC83UyG.js} +1 -1
  144. package/dist/public/assets/_CtC83UyG.js.br +0 -0
  145. package/dist/public/assets/_CtVSUTWd.js +1 -0
  146. package/dist/public/assets/_Ctf0pL3c.js +1 -0
  147. package/dist/public/assets/_CtvMc-Fn.js +1 -0
  148. package/dist/public/assets/_Cv7TctYK.js +1 -0
  149. package/dist/public/assets/_Cv7TctYK.js.br +0 -0
  150. package/dist/public/assets/{_CIDjLk1A.js → _CvKDzuxc.js} +1 -1
  151. package/dist/public/assets/_CvKDzuxc.js.br +0 -0
  152. package/dist/public/assets/_CvxhsaLv.js +1 -0
  153. package/dist/public/assets/_CwxTh04m.js +1 -0
  154. package/dist/public/assets/_CyMRBJfa.js +1 -0
  155. package/dist/public/assets/{_DDWIDZyP.js → _D-wwbDX7.js} +1 -1
  156. package/dist/public/assets/_D-wwbDX7.js.br +0 -0
  157. package/dist/public/assets/_D02jmNge.js +1 -0
  158. package/dist/public/assets/{_DJwY_zBh.js → _D0gWUr-E.js} +1 -1
  159. package/dist/public/assets/_D0gWUr-E.js.br +0 -0
  160. package/dist/public/assets/_D2wtQpHN.js +1 -0
  161. package/dist/public/assets/_D2wtQpHN.js.br +0 -0
  162. package/dist/public/assets/_D3uCXh8z.js +2 -0
  163. package/dist/public/assets/_D3uCXh8z.js.br +0 -0
  164. package/dist/public/assets/_D5GW0gg0.js +1 -0
  165. package/dist/public/assets/_D5GW0gg0.js.br +0 -0
  166. package/dist/public/assets/{_ClHeQc6g.js → _D6YVA8vA.js} +1 -1
  167. package/dist/public/assets/_D6YVA8vA.js.br +0 -0
  168. package/dist/public/assets/_D85prZ-z.js +1 -0
  169. package/dist/public/assets/_D8QlsPTv.js +1 -0
  170. package/dist/public/assets/_D8QlsPTv.js.br +0 -0
  171. package/dist/public/assets/_D8rDqOqJ.js +1 -0
  172. package/dist/public/assets/{_B0FhzjB2.js → _DAcmaIgY.js} +1 -1
  173. package/dist/public/assets/_DAcmaIgY.js.br +0 -0
  174. package/dist/public/assets/_DBlahxfT.js +1 -0
  175. package/dist/public/assets/_DCPGqAo6.js +1 -0
  176. package/dist/public/assets/{_DUmYv8Kf.js → _DDBuDrkA.js} +1 -1
  177. package/dist/public/assets/_DDBuDrkA.js.br +0 -0
  178. package/dist/public/assets/_DDfwtidv.js +1 -0
  179. package/dist/public/assets/_DDfwtidv.js.br +0 -0
  180. package/dist/public/assets/_DEqzNO7a.js +1 -0
  181. package/dist/public/assets/_DEyhBnnd.js +1 -0
  182. package/dist/public/assets/{_CZsqsL_m.js → _DG1LpTGX.js} +1 -1
  183. package/dist/public/assets/_DG1LpTGX.js.br +0 -0
  184. package/dist/public/assets/_DJK-MioE.js +1 -0
  185. package/dist/public/assets/{_BSRsPQTe.js → _DLCgfhNS.js} +1 -1
  186. package/dist/public/assets/_DLCgfhNS.js.br +0 -0
  187. package/dist/public/assets/_DLYvRpNz.js +6 -0
  188. package/dist/public/assets/_DLYvRpNz.js.br +0 -0
  189. package/dist/public/assets/_DPzjUc1B.js +1 -0
  190. package/dist/public/assets/_DRDW7RgT.js +1 -0
  191. package/dist/public/assets/{_Cq4DpL3R.js → _DSoJ6ck3.js} +1 -1
  192. package/dist/public/assets/_DSoJ6ck3.js.br +0 -0
  193. package/dist/public/assets/{_i6YkSowH.js → _DW92UwGh.js} +1 -1
  194. package/dist/public/assets/_DW92UwGh.js.br +0 -0
  195. package/dist/public/assets/{_DYxQeog7.js → _DYIjiPYY.js} +1 -1
  196. package/dist/public/assets/_DYIjiPYY.js.br +0 -0
  197. package/dist/public/assets/_DZeeRtLs.js +1 -0
  198. package/dist/public/assets/{_CcflXOTj.js → _DZzucnmx.js} +1 -1
  199. package/dist/public/assets/_DZzucnmx.js.br +0 -0
  200. package/dist/public/assets/{_8_DzkMgB.js → _D_AjKzkm.js} +1 -1
  201. package/dist/public/assets/_D_AjKzkm.js.br +0 -0
  202. package/dist/public/assets/{_DHYIZWev.js → _DdVG8Rbg.js} +116 -116
  203. package/dist/public/assets/_DdVG8Rbg.js.br +0 -0
  204. package/dist/public/assets/{_tJgkkxOD.js → _DdcPtDZz.js} +1 -1
  205. package/dist/public/assets/_DdcPtDZz.js.br +0 -0
  206. package/dist/public/assets/{_DKlB-yMq.js → _De_msLFQ.js} +1 -1
  207. package/dist/public/assets/_De_msLFQ.js.br +0 -0
  208. package/dist/public/assets/_DeiCZJcm.js +1 -0
  209. package/dist/public/assets/_DeiCZJcm.js.br +0 -0
  210. package/dist/public/assets/{_YDyNvOET.js → _DfNM5GDo.js} +1 -1
  211. package/dist/public/assets/_DfNM5GDo.js.br +0 -0
  212. package/dist/public/assets/{_Dku55Ypt.js → _Dg6OsRrR.js} +1 -1
  213. package/dist/public/assets/_Dg6OsRrR.js.br +0 -0
  214. package/dist/public/assets/_DgrmX7cI.js +1 -0
  215. package/dist/public/assets/_DiPK_ps-.js +1 -0
  216. package/dist/public/assets/{_BI45WgW9.js → _Dow17jzJ.js} +1 -1
  217. package/dist/public/assets/_Dow17jzJ.js.br +0 -0
  218. package/dist/public/assets/{_vHqiFYsh.js → _DpSZYTyI.js} +1 -1
  219. package/dist/public/assets/_DpSZYTyI.js.br +0 -0
  220. package/dist/public/assets/_DpXO9fPK.js +1 -0
  221. package/dist/public/assets/_DpXO9fPK.js.br +0 -0
  222. package/dist/public/assets/{_XWw1j8vS.js → _DqiBcDpF.js} +1 -1
  223. package/dist/public/assets/_DqiBcDpF.js.br +0 -0
  224. package/dist/public/assets/_DqkJjiCU.js +1 -0
  225. package/dist/public/assets/{_ahCaQNeo.js → _Draa__tn.js} +1 -1
  226. package/dist/public/assets/_Draa__tn.js.br +0 -0
  227. package/dist/public/assets/_Drs3T7dh.js +1 -0
  228. package/dist/public/assets/_Drs3T7dh.js.br +0 -0
  229. package/dist/public/assets/_DtBGe4AJ.js +1 -0
  230. package/dist/public/assets/{_B8joFpf1.js → _DxSnjCPi.js} +1 -1
  231. package/dist/public/assets/_DxSnjCPi.js.br +0 -0
  232. package/dist/public/assets/{_DGRgLaG-.js → _DyEhTpVE.js} +1 -1
  233. package/dist/public/assets/_DyEhTpVE.js.br +0 -0
  234. package/dist/public/assets/{_DMCVOg7x.js → _DyFcXAXE.js} +1 -1
  235. package/dist/public/assets/_DyFcXAXE.js.br +0 -0
  236. package/dist/public/assets/_FPItrlZz.js +1 -0
  237. package/dist/public/assets/{_o8mJsMHw.js → _HGP7qpI4.js} +1 -1
  238. package/dist/public/assets/_HGP7qpI4.js.br +0 -0
  239. package/dist/public/assets/{_f8D86HXZ.js → _L-b7Vsug.js} +1 -1
  240. package/dist/public/assets/_L-b7Vsug.js.br +0 -0
  241. package/dist/public/assets/{_B5NleRC6.js → _LWpc-K1g.js} +1 -1
  242. package/dist/public/assets/_LWpc-K1g.js.br +0 -0
  243. package/dist/public/assets/{_hbXd8Ogo.js → _MwkLbzHQ.js} +1 -1
  244. package/dist/public/assets/_MwkLbzHQ.js.br +0 -0
  245. package/dist/public/assets/_O4DIriLZ.js +1 -0
  246. package/dist/public/assets/{_C-z8Ntse.js → _T0Ktx7Km.js} +1 -1
  247. package/dist/public/assets/_T0Ktx7Km.js.br +0 -0
  248. package/dist/public/assets/_T6O8KX0b.js +1 -0
  249. package/dist/public/assets/_TWZgGi12.js +1 -0
  250. package/dist/public/assets/{_BxKDE6Ct.js → _UBgRR4E9.js} +1 -1
  251. package/dist/public/assets/_UBgRR4E9.js.br +0 -0
  252. package/dist/public/assets/_X3T0JcUM.js +87 -0
  253. package/dist/public/assets/_X3T0JcUM.js.br +0 -0
  254. package/dist/public/assets/_YtP2gTmD.js +1 -0
  255. package/dist/public/assets/{_sSKEak2x.js → __1UtPhZb.js} +1 -1
  256. package/dist/public/assets/__1UtPhZb.js.br +0 -0
  257. package/dist/public/assets/__WDcLOp3.js +1 -0
  258. package/dist/public/assets/{_DnUBW0Qq.js → __cyNMcUU.js} +1 -1
  259. package/dist/public/assets/{_rv9KtZHz.js → _csFWQzWs.js} +1 -1
  260. package/dist/public/assets/_csFWQzWs.js.br +0 -0
  261. package/dist/public/assets/_eURsGF_D.js +1 -0
  262. package/dist/public/assets/_fEPizk9T.js +1 -0
  263. package/dist/public/assets/{_DB7_Yora.js → _hC5RUmrf.js} +1 -1
  264. package/dist/public/assets/_hC5RUmrf.js.br +0 -0
  265. package/dist/public/assets/_hfgYVPfe.js +1 -0
  266. package/dist/public/assets/_i51v5tw8.js +1 -0
  267. package/dist/public/assets/{_CYcgwayF.js → _k1uZxEJ-.js} +1 -1
  268. package/dist/public/assets/_k1uZxEJ-.js.br +0 -0
  269. package/dist/public/assets/_l4nNKr9o.js +1 -0
  270. package/dist/public/assets/{_l9xpLTP_.js → _lA6BOkV1.js} +1 -1
  271. package/dist/public/assets/_lA6BOkV1.js.br +0 -0
  272. package/dist/public/assets/_qyrPXpIj.js +1 -0
  273. package/dist/public/assets/{_B2DHvTZR.js → _sLUOjXIk.js} +1 -1
  274. package/dist/public/assets/{_BLeLpnYL.js → _sjeWoc5X.js} +1 -1
  275. package/dist/public/assets/_sjeWoc5X.js.br +0 -0
  276. package/dist/public/assets/_tByKwKUc.js +1 -0
  277. package/dist/public/assets/{_BkHLXMjq.js → _tFVcmmKI.js} +1 -1
  278. package/dist/public/assets/_tFVcmmKI.js.br +0 -0
  279. package/dist/public/assets/{_oVsjszGq.js → _txvO7pXr.js} +1 -1
  280. package/dist/public/assets/_txvO7pXr.js.br +0 -0
  281. package/dist/public/assets/_um7Vy7NX.js +1 -0
  282. package/dist/public/assets/_veNUvOqP.js +1 -0
  283. package/dist/public/assets/{_BkGAUdMd.js → _w8hTnp0H.js} +1 -1
  284. package/dist/public/assets/_w8hTnp0H.js.br +0 -0
  285. package/dist/public/assets/_wGWNa6Sp.js +1 -0
  286. package/dist/public/assets/_wxbEv1JK.js +1 -0
  287. package/dist/public/assets/files-view-BOE5HTrF.js +2 -0
  288. package/dist/public/assets/manage-workspace-ClwsrQ4a.js +2 -0
  289. package/dist/public/assets/new-CJ6ZElay.js +1 -0
  290. package/dist/public/assets/new-workspace-DWSBO4Vx.js +2 -0
  291. package/dist/public/assets/review-view-DffAZHOz.js +2 -0
  292. package/dist/public/assets/settings-CJ6ZElay.js +1 -0
  293. package/dist/public/assets/settings-page-CYL_T3Vf.js +2 -0
  294. package/dist/public/assets/styles-taHUfRpm.css +1 -0
  295. package/dist/public/assets/styles-taHUfRpm.css.br +0 -0
  296. package/dist/public/assets/w-CJ6ZElay.js +1 -0
  297. package/dist/public/assets/w._-CJ6ZElay.js +1 -0
  298. package/dist/public/assets/w._-ChCIRlhY.js +1 -0
  299. package/dist/public/assets/w._-WsR2-skZ.js +1 -0
  300. package/lib/preview/media.d.mts +1 -1
  301. package/lib/preview/media.mjs +15 -2
  302. package/package.json +1 -1
  303. package/dist/_BAJGOEa1.js +0 -168
  304. package/dist/_t9VsALwo.js +0 -2
  305. package/dist/public/assets/_10dZ1R0m.js.br +0 -0
  306. package/dist/public/assets/_1EPD0XJG.js +0 -1
  307. package/dist/public/assets/_1jA3fFvQ.js +0 -1
  308. package/dist/public/assets/_4Sj6a8Ya.js +0 -1
  309. package/dist/public/assets/_4Sj6a8Ya.js.br +0 -0
  310. package/dist/public/assets/_5tN48iuJ.js.br +0 -0
  311. package/dist/public/assets/_8_DzkMgB.js.br +0 -0
  312. package/dist/public/assets/_9JG-F3GR.js.br +0 -0
  313. package/dist/public/assets/_9KUM3Nch.js +0 -2
  314. package/dist/public/assets/_9KUM3Nch.js.br +0 -0
  315. package/dist/public/assets/_B-H6ABVZ.js.br +0 -0
  316. package/dist/public/assets/_B-iOtMg6.js.br +0 -0
  317. package/dist/public/assets/_B0FhzjB2.js.br +0 -0
  318. package/dist/public/assets/_B26gPL08.js.br +0 -0
  319. package/dist/public/assets/_B3Z1kRpD.js.br +0 -0
  320. package/dist/public/assets/_B3sH8Usv.js +0 -1
  321. package/dist/public/assets/_B3sH8Usv.js.br +0 -0
  322. package/dist/public/assets/_B42hLH2K.js +0 -1
  323. package/dist/public/assets/_B4hn3NNW.js.br +0 -0
  324. package/dist/public/assets/_B5NleRC6.js.br +0 -0
  325. package/dist/public/assets/_B5fRGxPQ.js +0 -1
  326. package/dist/public/assets/_B5fRGxPQ.js.br +0 -0
  327. package/dist/public/assets/_B65yR5Ej.js +0 -1
  328. package/dist/public/assets/_B6Sh9WEH.js +0 -1
  329. package/dist/public/assets/_B6VtVybz.js.br +0 -0
  330. package/dist/public/assets/_B7rJ4n9b.js +0 -1
  331. package/dist/public/assets/_B8M-AD29.js +0 -1
  332. package/dist/public/assets/_B8joFpf1.js.br +0 -0
  333. package/dist/public/assets/_B9nA-Uh1.js +0 -1
  334. package/dist/public/assets/_B9nA-Uh1.js.br +0 -0
  335. package/dist/public/assets/_BA6X_Aj6.js +0 -1
  336. package/dist/public/assets/_BBFJV2Bx.js +0 -1
  337. package/dist/public/assets/_BCW5GFMW.js +0 -1
  338. package/dist/public/assets/_BD1SQU0V.js.br +0 -0
  339. package/dist/public/assets/_BEpd9Y1R.js +0 -1
  340. package/dist/public/assets/_BEy7R4W_.js +0 -1
  341. package/dist/public/assets/_BFGJOHQb.js +0 -1
  342. package/dist/public/assets/_BI45WgW9.js.br +0 -0
  343. package/dist/public/assets/_BIKvQKWe.js +0 -1
  344. package/dist/public/assets/_BIPnL2aI.js +0 -1
  345. package/dist/public/assets/_BIUaA4Nl.js.br +0 -0
  346. package/dist/public/assets/_BJpBnuvv.js.br +0 -0
  347. package/dist/public/assets/_BLeLpnYL.js.br +0 -0
  348. package/dist/public/assets/_BMb5ANTv.js +0 -1
  349. package/dist/public/assets/_BSRsPQTe.js.br +0 -0
  350. package/dist/public/assets/_BVuerXin.js +0 -6
  351. package/dist/public/assets/_BVuerXin.js.br +0 -0
  352. package/dist/public/assets/_BWV8aSlZ.js +0 -1
  353. package/dist/public/assets/_BXHggM8M.js.br +0 -0
  354. package/dist/public/assets/_BXPUZfKX.js.br +0 -0
  355. package/dist/public/assets/_BYebhygn.js +0 -1
  356. package/dist/public/assets/_BZgCxd-U.js +0 -1
  357. package/dist/public/assets/_BZgCxd-U.js.br +0 -0
  358. package/dist/public/assets/_B_W51WxU.js +0 -1
  359. package/dist/public/assets/_B_jFFNyT.js +0 -1
  360. package/dist/public/assets/_Ba9OQzPV.js +0 -1
  361. package/dist/public/assets/_Ba9OQzPV.js.br +0 -0
  362. package/dist/public/assets/_BayiY7GU.js +0 -1
  363. package/dist/public/assets/_BcDMeS82.js +0 -1
  364. package/dist/public/assets/_BdD1sZp_.js +0 -1
  365. package/dist/public/assets/_Bg_WwlL2.js +0 -1
  366. package/dist/public/assets/_BhHzv4g0.js +0 -1
  367. package/dist/public/assets/_BjEinMEe.js +0 -1
  368. package/dist/public/assets/_BjEinMEe.js.br +0 -0
  369. package/dist/public/assets/_BkGAUdMd.js.br +0 -0
  370. package/dist/public/assets/_BkHLXMjq.js.br +0 -0
  371. package/dist/public/assets/_BmSWsZvV.js +0 -1
  372. package/dist/public/assets/_Bn6y2_ex.js +0 -1
  373. package/dist/public/assets/_Bn6y2_ex.js.br +0 -0
  374. package/dist/public/assets/_Bp2gqUaf.js +0 -1
  375. package/dist/public/assets/_Bs6oYKkD.js +0 -1
  376. package/dist/public/assets/_Bs_MPTBZ.js.br +0 -0
  377. package/dist/public/assets/_Bt13j1ev.js +0 -1
  378. package/dist/public/assets/_BwlnYt-t.js +0 -1
  379. package/dist/public/assets/_Bx9aUXTG.js +0 -1
  380. package/dist/public/assets/_BxKDE6Ct.js.br +0 -0
  381. package/dist/public/assets/_BymFDqKj.js +0 -1
  382. package/dist/public/assets/_C-z8Ntse.js.br +0 -0
  383. package/dist/public/assets/_C0XUbqWe.js +0 -1
  384. package/dist/public/assets/_C1upDwBv.js +0 -1
  385. package/dist/public/assets/_C3f4huqn.js +0 -1
  386. package/dist/public/assets/_C46o3wQ8.js.br +0 -0
  387. package/dist/public/assets/_C4_3qKLX.js +0 -1
  388. package/dist/public/assets/_C7tG4xwv.js +0 -1
  389. package/dist/public/assets/_C8LciIOa.js +0 -1
  390. package/dist/public/assets/_C9k00otG.js.br +0 -0
  391. package/dist/public/assets/_CBG92pZO.js +0 -1
  392. package/dist/public/assets/_CBfI2lSr.js +0 -1
  393. package/dist/public/assets/_CFKwHn62.js +0 -1
  394. package/dist/public/assets/_CFKwHn62.js.br +0 -0
  395. package/dist/public/assets/_CHDvRNgn.js +0 -1
  396. package/dist/public/assets/_CIDjLk1A.js.br +0 -0
  397. package/dist/public/assets/_CLV83hY7.js.br +0 -0
  398. package/dist/public/assets/_CO8ZosDU.js +0 -1
  399. package/dist/public/assets/_CPqT91JX.js.br +0 -0
  400. package/dist/public/assets/_CRZ03hrO.js +0 -1
  401. package/dist/public/assets/_CUKvJRmi.js +0 -1
  402. package/dist/public/assets/_CU_FKEsy.js +0 -1
  403. package/dist/public/assets/_CUxBk_RE.js.br +0 -0
  404. package/dist/public/assets/_CW_vyZfo.js +0 -1
  405. package/dist/public/assets/_CX5VOdNU.js.br +0 -0
  406. package/dist/public/assets/_CYcgwayF.js.br +0 -0
  407. package/dist/public/assets/_CZsqsL_m.js.br +0 -0
  408. package/dist/public/assets/_C_a8QggH.js +0 -1
  409. package/dist/public/assets/_C_ymFHNL.js +0 -1
  410. package/dist/public/assets/_CaU4irFc.js +0 -1
  411. package/dist/public/assets/_Cb3fSi2R.js +0 -1
  412. package/dist/public/assets/_CcINcTUt.js.br +0 -0
  413. package/dist/public/assets/_CcflXOTj.js.br +0 -0
  414. package/dist/public/assets/_Cfts4mFJ.js.br +0 -0
  415. package/dist/public/assets/_ClHeQc6g.js.br +0 -0
  416. package/dist/public/assets/_CnSlVcEh.js +0 -1
  417. package/dist/public/assets/_Co71-HWR.js +0 -1
  418. package/dist/public/assets/_CpEeHKyF.js +0 -1
  419. package/dist/public/assets/_CpVeIwQ4.js.br +0 -0
  420. package/dist/public/assets/_Cq4DpL3R.js.br +0 -0
  421. package/dist/public/assets/_CvxsvMFa.js +0 -1
  422. package/dist/public/assets/_Cwdn40Q2.js +0 -1
  423. package/dist/public/assets/_Cwdn40Q2.js.br +0 -0
  424. package/dist/public/assets/_CzN0wC_5.js +0 -16
  425. package/dist/public/assets/_CzN0wC_5.js.br +0 -0
  426. package/dist/public/assets/_D3ieGLoq.js +0 -1
  427. package/dist/public/assets/_D4wF26fk.js +0 -1
  428. package/dist/public/assets/_D9a9nY1Q.js +0 -1
  429. package/dist/public/assets/_DB7_Yora.js.br +0 -0
  430. package/dist/public/assets/_DDWIDZyP.js.br +0 -0
  431. package/dist/public/assets/_DG3L8-RO.js.br +0 -0
  432. package/dist/public/assets/_DGRgLaG-.js.br +0 -0
  433. package/dist/public/assets/_DG_QOtsx.js.br +0 -0
  434. package/dist/public/assets/_DHYIZWev.js.br +0 -0
  435. package/dist/public/assets/_DJwY_zBh.js.br +0 -0
  436. package/dist/public/assets/_DKlB-yMq.js.br +0 -0
  437. package/dist/public/assets/_DMCVOg7x.js.br +0 -0
  438. package/dist/public/assets/_DMXnrdYy.js +0 -1
  439. package/dist/public/assets/_DMXnrdYy.js.br +0 -0
  440. package/dist/public/assets/_DNrRZhO7.js.br +0 -0
  441. package/dist/public/assets/_DPdb5l-Z.js +0 -1
  442. package/dist/public/assets/_DRpsUHP5.js.br +0 -0
  443. package/dist/public/assets/_DUH5o_iN.js.br +0 -0
  444. package/dist/public/assets/_DUmYv8Kf.js.br +0 -0
  445. package/dist/public/assets/_DXvsvUmJ.js.br +0 -0
  446. package/dist/public/assets/_DYxQeog7.js.br +0 -0
  447. package/dist/public/assets/_DZIDdpeW.js +0 -1
  448. package/dist/public/assets/_DZqoQxTm.js.br +0 -0
  449. package/dist/public/assets/_D_4RJnk0.js +0 -2
  450. package/dist/public/assets/_D_4RJnk0.js.br +0 -0
  451. package/dist/public/assets/_DclJXqwW.js +0 -1
  452. package/dist/public/assets/_Debmjz1c.js +0 -1
  453. package/dist/public/assets/_DeiCZCO_.js +0 -1
  454. package/dist/public/assets/_Df-N1G_n.js.br +0 -0
  455. package/dist/public/assets/_Df_3rEok.js +0 -86
  456. package/dist/public/assets/_Df_3rEok.js.br +0 -0
  457. package/dist/public/assets/_DjYscMjF.js.br +0 -0
  458. package/dist/public/assets/_Dku55Ypt.js.br +0 -0
  459. package/dist/public/assets/_Dm8TVkBX.js +0 -1
  460. package/dist/public/assets/_DoOPrRIy.js +0 -1
  461. package/dist/public/assets/_DqJvxlYV.js +0 -1
  462. package/dist/public/assets/_Drle66GA.js +0 -1
  463. package/dist/public/assets/_DtrvrAfl.js +0 -1
  464. package/dist/public/assets/_DwTaEsY5.js +0 -1
  465. package/dist/public/assets/_DwTaEsY5.js.br +0 -0
  466. package/dist/public/assets/_Dypj9l-z.js +0 -1
  467. package/dist/public/assets/_DyvwMfCp.js +0 -1
  468. package/dist/public/assets/_GK8r-gEu.js.br +0 -0
  469. package/dist/public/assets/_HpxvfbM2.js.br +0 -0
  470. package/dist/public/assets/_RudCGuBM.js.br +0 -0
  471. package/dist/public/assets/_UbfI3k4y.js +0 -1
  472. package/dist/public/assets/_WOU8TCkO.js.br +0 -0
  473. package/dist/public/assets/_XWw1j8vS.js.br +0 -0
  474. package/dist/public/assets/_YDyNvOET.js.br +0 -0
  475. package/dist/public/assets/_ahCaQNeo.js.br +0 -0
  476. package/dist/public/assets/_f8D86HXZ.js.br +0 -0
  477. package/dist/public/assets/_hbXd8Ogo.js.br +0 -0
  478. package/dist/public/assets/_i6YkSowH.js.br +0 -0
  479. package/dist/public/assets/_k1ciacDf.js +0 -1
  480. package/dist/public/assets/_k6nXIP-i.js +0 -1
  481. package/dist/public/assets/_keX09TNx.js +0 -1
  482. package/dist/public/assets/_l9xpLTP_.js.br +0 -0
  483. package/dist/public/assets/_n9Rb26YX.js +0 -1
  484. package/dist/public/assets/_o8mJsMHw.js.br +0 -0
  485. package/dist/public/assets/_oVsjszGq.js.br +0 -0
  486. package/dist/public/assets/_pM8W420Q.js +0 -1
  487. package/dist/public/assets/_rv9KtZHz.js.br +0 -0
  488. package/dist/public/assets/_sSKEak2x.js.br +0 -0
  489. package/dist/public/assets/_tJgkkxOD.js.br +0 -0
  490. package/dist/public/assets/_uP3LGOtV.js +0 -1
  491. package/dist/public/assets/_vG7bXn-C.js.br +0 -0
  492. package/dist/public/assets/_vHqiFYsh.js.br +0 -0
  493. package/dist/public/assets/_vXJ7nP0d.js +0 -1
  494. package/dist/public/assets/_wvhU__5f.js +0 -1
  495. package/dist/public/assets/_xFMpRp_e.js +0 -1
  496. package/dist/public/assets/_yXimF5vw.js +0 -1
  497. package/dist/public/assets/files-view-BennlUmP.js +0 -2
  498. package/dist/public/assets/manage-workspace-CaESLJdc.js +0 -2
  499. package/dist/public/assets/new-BNH4m99d.js +0 -1
  500. package/dist/public/assets/new-workspace-CwiZjHNn.js +0 -2
  501. package/dist/public/assets/review-view-BdbMyVt7.js +0 -2
  502. package/dist/public/assets/settings-BNH4m99d.js +0 -1
  503. package/dist/public/assets/settings-page-CU3aC70Q.js +0 -2
  504. package/dist/public/assets/styles-ctr-Sxsj.css +0 -1
  505. package/dist/public/assets/styles-ctr-Sxsj.css.br +0 -0
  506. package/dist/public/assets/w-BNH4m99d.js +0 -1
  507. package/dist/public/assets/w._-BNH4m99d.js +0 -1
  508. package/dist/public/assets/w._-CLYxMMR4.js +0 -1
  509. package/dist/public/assets/w._-_w8eUYMy.js +0 -1
package/README.md CHANGED
@@ -59,7 +59,12 @@ work-source # status
59
59
  Everything the app's pages do has a `work` command too, so an agent — or a
60
60
  script — can use and set up work from a terminal: `work help` lists them.
61
61
  Inside a workspace, `work branches`, `work session`, `work topic`,
62
- `work review`, `work notify` and `work open`; to change things,
62
+ `work review`, `work notify` and `work open`; agents start and message each
63
+ other with `work session new|send|wait` — any vendor's, each in a tab of its
64
+ own the user watches, its last message as a turn ends coming back to the
65
+ one that asked as a prompt — and run groups of them with
66
+ `work session fanout` and `work plan`, which the session list shows as a
67
+ lead's team; to change things,
63
68
  `work workspace create`, `work repo add`, `work config get|set` (checked
64
69
  against what each setting takes; `work config schema` lists them),
65
70
  `work agent|skill|lsp|host` and `work gh login`; `work status` sums the
@@ -0,0 +1,85 @@
1
+ // `work plan`: the phases a lead agent's fan-outs fall under, and a line
2
+ // of what it is doing as it goes (server/team.ts). It is what the team
3
+ // view draws over the groups — the job as the lead sees it — and nothing
4
+ // runs from it: the lead starts each phase's groups itself, with
5
+ // `work session fanout --phase`.
6
+
7
+ /** The session a command means: --session's, else this pane's own. */
8
+ function sessionId(ctx) {
9
+ const id = ctx.flag("--session") || process.env.WORK_SESSION_ID;
10
+ if (!id)
11
+ ctx.die(
12
+ "a plan is a session's: run this in one (WORK_SESSION_ID is unset) or pass --session <id>",
13
+ );
14
+ return id;
15
+ }
16
+
17
+ /** `--phase "Title"` or `--phase "Title: what it does"`. */
18
+ function phaseOf(text) {
19
+ const at = text.indexOf(":");
20
+ return at > 0
21
+ ? { title: text.slice(0, at).trim(), detail: text.slice(at + 1).trim() }
22
+ : { title: text.trim() };
23
+ }
24
+
25
+ export const commands = [
26
+ {
27
+ name: "plan",
28
+ summary: "a lead's phases and progress log, over its fan-outs",
29
+ help: `work plan [--json]
30
+ This session's plan: its phases, and the last lines it logged.
31
+ work plan new "<name>" --phase "<title>[: what it does]" [--phase …]
32
+ Start a plan (ending this session's last): the phases its fan-outs fall
33
+ under, in order. \`work session fanout --phase <title>\` files a group
34
+ under one; the user sees each phase's members and how far they are.
35
+ work plan log "<line>"
36
+ Say what you are doing, over the phases ("3 of 6 fixes pass;
37
+ reviewing them") — a narrator line, not a message to anyone.
38
+ work plan done
39
+ End the plan.`,
40
+ async run(ctx) {
41
+ const [verb, ...rest] = ctx.parse(["--phase", "--session"]);
42
+ const me = sessionId(ctx);
43
+ switch (verb) {
44
+ case undefined: {
45
+ const plan = await ctx.api.get(`/api/sessions/${me}/plan`);
46
+ return ctx.out(plan, (p) => {
47
+ if (!p) return console.log('no plan: `work plan new "<name>"`');
48
+ console.log(`${p.name}${p.done ? " (done)" : ""}`);
49
+ for (const ph of p.phases)
50
+ console.log(` ${ph.title}${ph.detail ? ` — ${ph.detail}` : ""}`);
51
+ for (const l of p.log) console.log(` · ${l.text}`);
52
+ });
53
+ }
54
+ case "new": {
55
+ const name = rest.join(" ").trim();
56
+ if (!name)
57
+ ctx.die('usage: work plan new "<name>" --phase "<title>" […]');
58
+ const plan = await ctx.api.post(`/api/sessions/${me}/plan`, {
59
+ name,
60
+ phases: ctx.flags("--phase").map(phaseOf),
61
+ });
62
+ return ctx.out(plan, (p) =>
63
+ console.log(
64
+ `plan "${p.name}": ${p.phases.map((x) => x.title).join(" → ") || "no phases"}`,
65
+ ),
66
+ );
67
+ }
68
+ case "log": {
69
+ const line = rest.join(" ").trim();
70
+ if (!line) ctx.die('usage: work plan log "<line>"');
71
+ await ctx.api.patch(`/api/sessions/${me}/plan`, { log: line });
72
+ return ctx.out({ logged: line }, () =>
73
+ console.log(`logged: ${line}`),
74
+ );
75
+ }
76
+ case "done": {
77
+ await ctx.api.patch(`/api/sessions/${me}/plan`, { done: true });
78
+ return ctx.out({ done: true }, () => console.log("plan done"));
79
+ }
80
+ default:
81
+ ctx.die(`no \`work plan ${verb}\` (see: work help plan)`);
82
+ }
83
+ },
84
+ },
85
+ ];
@@ -1,9 +1,13 @@
1
1
  // `work session`: which session this is (an agent's own pane, by
2
2
  // WORK_SESSION_ID), its name in the session list, and the workspace's
3
- // other sessions — starting one, sending it a prompt, closing it.
3
+ // other sessions — starting one or a fan-out of them, messaging one and
4
+ // waiting on replies, closing them (server/messages.ts, server/team.ts).
5
+ import path from "node:path";
6
+ import { makeTopics, topicRepos } from "./topic.mjs";
4
7
 
5
- /** More sessions than this in one workspace is an agent starting them in
6
- * a loop, not a plan: past it, `new` wants --force. */
8
+ /** More sessions than this running in one workspace is an agent starting
9
+ * them in a loop, not a plan: past it, `new` wants --force. A fan-out's
10
+ * members go through its pool instead. */
7
11
  const SESSION_CAP = 8;
8
12
 
9
13
  /** The session a command means: --session's, else this pane's own. */
@@ -16,27 +20,147 @@ function sessionId(ctx) {
16
20
  return id;
17
21
  }
18
22
 
19
- /** The workspace's sessions with their state, this pane's marked. */
23
+ /** How long `wait` waits by default: inside an agent's own tool limit
24
+ * (ten minutes for most), so it ends saying who is still working rather
25
+ * than being killed. */
26
+ const WAIT_S = 540;
27
+ const POLL_MS = 1500;
28
+
29
+ /** The workspace's sessions with their state, this pane's marked, each
30
+ * after the session that started it (as the sidebar lists them). */
20
31
  async function sessionsOf(ctx, wsId) {
21
32
  const me = process.env.WORK_SESSION_ID;
22
33
  const list = await ctx.api.get(`/api/workspaces/${wsId}/sessions`);
23
- return list.map((s) => ({
34
+ const rows = list.map((s) => ({
24
35
  id: s.id,
25
36
  agent: s.agent,
26
37
  title: s.title || null,
27
38
  phase: s.state?.phase || (s.state?.alive ? "idle" : "off"),
39
+ parent: s.parent_id || null,
40
+ waitingOn: s.messages?.waitingOn ?? [],
41
+ queued: s.messages?.queued ?? 0,
28
42
  self: s.id === me,
29
43
  }));
44
+ const ids = new Set(rows.map((s) => s.id));
45
+ const out = [];
46
+ const walk = (s, depth) => {
47
+ if (out.some((o) => o.id === s.id)) return;
48
+ out.push({ ...s, depth });
49
+ for (const c of rows) if (c.parent === s.id) walk(c, depth + 1);
50
+ };
51
+ for (const s of rows) if (!s.parent || !ids.has(s.parent)) walk(s, 0);
52
+ for (const s of rows) walk(s, 0);
53
+ return out;
30
54
  }
31
55
 
32
56
  function sessionLine(ctx, s) {
33
- return `${ctx.pad(s.id, 9)} ${ctx.pad(s.agent, 10)} ${ctx.pad(s.phase, 8)} ${s.title || ""}${s.self ? " (this session)" : ""}`;
57
+ const notes = [
58
+ s.waitingOn.length && `waiting on ${s.waitingOn.join(", ")}`,
59
+ s.queued && `${s.queued} queued for it`,
60
+ s.self && "this session",
61
+ ].filter(Boolean);
62
+ return `${" ".repeat(s.depth ?? 0)}${ctx.pad(s.id, 9)} ${ctx.pad(s.agent, 10)} ${ctx.pad(s.phase, 8)} ${s.title || ""}${notes.length ? ` (${notes.join("; ")})` : ""}`;
63
+ }
64
+
65
+ /** A flag's value, "-" (stdin) included, which ctx.flag takes for a
66
+ * flag of its own. */
67
+ function valueOf(ctx, flag) {
68
+ const i = ctx.args.indexOf(flag);
69
+ if (i >= 0 && ctx.args[i + 1] === "-") return "-";
70
+ return ctx.flag(flag);
71
+ }
72
+
73
+ /** The text itself, or stdin's for "-": a heredoc carries a long prompt
74
+ * with quotes in it, which an argument mangles. */
75
+ async function textOf(value) {
76
+ if (value !== "-") return value;
77
+ const chunks = [];
78
+ for await (const chunk of process.stdin) chunks.push(chunk);
79
+ return Buffer.concat(chunks).toString("utf8").replace(/\n$/, "");
80
+ }
81
+
82
+ /** What became of a message, for the sender. */
83
+ function sentText(id, r) {
84
+ const lines = [
85
+ r.delivered
86
+ ? `sent to ${id}`
87
+ : `queued for ${id} (${r.queued}): typed in once it is at its prompt`,
88
+ ];
89
+ if (r.wantsReply)
90
+ lines.push(
91
+ `Its last message, as that turn ends, comes back to you as a prompt: end your turn to wait for it, or run \`work session wait ${id}\`.`,
92
+ );
93
+ return lines.join("\n");
94
+ }
95
+
96
+ function printReply(r) {
97
+ const head =
98
+ r.kind === "reply" ? `${r.label} replied:` : `${r.label}: ${r.text}`;
99
+ console.log(head);
100
+ if (r.kind === "reply") console.log(`${r.text}\n`);
101
+ }
102
+
103
+ /** Start folders for `count` sessions, a topic each (`<topic>`, or
104
+ * `<topic>-1`… for several) in the repos `--repo` names (else the cwd's):
105
+ * a member's worktree is its own, so their edits never meet. Relative
106
+ * to the workspace: a repo's worktree for one repo, the topic's folder
107
+ * for several. */
108
+ async function topicDirs(ctx, topic, count) {
109
+ const { ws, picked } = await topicRepos(ctx);
110
+ const names =
111
+ count === 1
112
+ ? [topic]
113
+ : Array.from({ length: count }, (_, i) => `${topic}-${i + 1}`);
114
+ const made = makeTopics(ctx, ws, picked, names, {
115
+ install: ctx.has("--install"),
116
+ });
117
+ return {
118
+ names,
119
+ dirs: names.map((name) => {
120
+ const rows = made.filter((m) => m.topic === name);
121
+ const dir = rows.length === 1 ? rows[0].path : path.dirname(rows[0].path);
122
+ return path.relative(ws.path, dir);
123
+ }),
124
+ links: made.map((m) => m.link),
125
+ };
126
+ }
127
+
128
+ const STATUS_MARK = {
129
+ queued: "◌",
130
+ starting: "◔",
131
+ working: "⟳",
132
+ waiting: "⚠",
133
+ idle: "·",
134
+ done: "✓",
135
+ closed: "✕",
136
+ };
137
+
138
+ /** One group of `work session team`: its head, then a line a member. */
139
+ function printGroup(ctx, g) {
140
+ const c = g.counts;
141
+ const left = c.queued + c.starting + c.working + c.waiting + c.idle;
142
+ const parts = [
143
+ `${c.done}/${g.members.length} done`,
144
+ c.working && `${c.working} working`,
145
+ c.waiting && `${c.waiting} waiting on the user`,
146
+ c.starting && `${c.starting} starting`,
147
+ c.queued && `${c.queued} queued`,
148
+ c.closed && `${c.closed} closed`,
149
+ ].filter(Boolean);
150
+ console.log(
151
+ `${g.phase ? `[${g.phase}] ` : ""}${g.id} "${g.title}" ${parts.join(" · ")} (${g.parallel} at a time, ${g.fanIn ? (left ? "replies held until all answer" : "replies sent as one") : "replies as each comes"})`,
152
+ );
153
+ for (const m of g.members)
154
+ console.log(
155
+ ` ${STATUS_MARK[m.status] ?? "?"} ${ctx.pad(m.status, 8)} ${ctx.pad(m.id, 9)} ${ctx.pad(m.session ?? "-", 9)} ${ctx.pad(m.agent, 8)} ${m.title}${m.line ? ` — ${m.line}` : ""}`,
156
+ );
34
157
  }
35
158
 
36
159
  export const commands = [
37
160
  {
38
161
  name: "session",
39
- summary: "this session and the workspace's others: title, new, send, kill",
162
+ summary:
163
+ "this session and the workspace's others: new, fanout, send, wait, team, kill",
40
164
  help: `work session [--json]
41
165
  This session (WORK_SESSION_ID): its id, agent, name, state, and the
42
166
  workspace it is in (id, name, path) — what a link names (/w/<id>/…).
@@ -44,14 +168,60 @@ work session list [id|name] [--json]
44
168
  The workspace's sessions, this one marked.
45
169
  work session title "<name>" [--session <id>]
46
170
  Name a session in the session list (empty clears it).
47
- work session new [--agent <id>] [--title "<name>"] [--prompt "<text>"] [--workspace <id|name>] [--force]
48
- Start a session (the default agent unless --agent; "shell" for a
49
- terminal), name it, and hand it a first prompt. Past ${SESSION_CAP} sessions
50
- in the workspace it wants --force.
51
- work session send <id> "<text>"
52
- Type text into a session and press Enter, as the review's Send does.
53
- work session kill <id> --yes
54
- Close a session and the process in it.`,
171
+ work session new [--agent <id>] [--title "<name>"] [--prompt "<text>"|-] [--no-reply] [--keep] [--topic <name> [--repo <repo>…] [--install]] [--workspace <id|name>] [--force]
172
+ Start a session (the default agent unless --agent, any vendor's; "shell"
173
+ for a terminal) in a tab of its own, where the user can watch it, name
174
+ it, and hand it a first prompt ("-": read it from stdin). Started from
175
+ another session it is listed under that one, runs in its permission
176
+ mode (it is an agent's to drive: nobody waits on it to answer a prompt),
177
+ and the prompt is a message from it (below). --topic starts it in a
178
+ topic branch of its own (\`work topic new\`). It closes once it has
179
+ answered and is done with — when your job finishes, or after ten idle
180
+ minutes — unless --keep, it is on the user's screen, or they have typed
181
+ into it. Past ${SESSION_CAP} running sessions in the workspace it wants --force.
182
+ work session fanout --agent <id> [--agent <id>…] [--count <n>] --prompt "<text>"|- [<item>…] [--title "<name>"] [--phase "<phase>"] [--parallel <n>] [--stream] [--close-done|--keep] [--topic <name> [--repo <repo>…] [--install]]
183
+ Start a group of sessions from this one: each --agent once (or --count
184
+ times), or once for each <item> with {} in the prompt replaced by it
185
+ ({i} is the member's number). They queue and start --parallel at a time
186
+ (4), however many there are. Their replies come back to you as one
187
+ prompt once every member has answered (--stream: each as it comes); end
188
+ your turn to wait, or \`work session wait <group>\`. A member's session
189
+ closes once done with, as \`new\`'s does (its result is kept);
190
+ --close-done closes it as soon as it answers, --keep never;
191
+ --topic gives each member a topic branch of its own (<name>-1, -2, …),
192
+ side by side in Review; --phase files the group under that phase of your
193
+ plan (\`work plan\`). For a quick sweep inside your own CLI, its own
194
+ subagents are cheaper: this is for other vendors, long work, or work the
195
+ user may want to watch.
196
+ work session team [--json]
197
+ This session's plan and groups: each member (its id, then its
198
+ session's), its state and its last line (what it is doing, or its
199
+ result).
200
+ work session retry <member>
201
+ Rerun a closed member in a fresh session: its group waits for it again.
202
+ work session skip <member>
203
+ Stop a member: a queued one never starts, a running one's session
204
+ closes; either way its group no longer waits on it.
205
+ work session send <id> "<text>"|- [--no-reply]
206
+ Message an agent session: typed in, headed with who it is from, once
207
+ it is at its prompt — never into a turn under way, a question it asks,
208
+ or a draft someone is typing. From an agent's session it wants a reply
209
+ unless --no-reply: the recipient's last message as that turn ends,
210
+ typed into this session as a prompt of its own. End your turn to wait
211
+ for it. A file's path says more than its text pasted in.
212
+ work session wait [<id>|<group>...] [--any] [--timeout <seconds>]
213
+ Wait for the replies owed to this session (by those sessions or groups,
214
+ else by any), printing each as it comes; a reply printed here is not
215
+ typed in too. A group's come once all its members have answered, unless
216
+ --any: then whatever is in, as soon as anything is. Exits 124 if some
217
+ are still working after --timeout (${WAIT_S} s).
218
+ work session kill <id> [--keep-children] --yes
219
+ Close a session and the process in it, and the sessions it started
220
+ with theirs, unless --keep-children (they then stand on their own).
221
+ Whoever waits on a reply from one is told.
222
+ work session kill --done
223
+ Close now the sessions this one started that are done with (answered,
224
+ idle, not the user's): fan-out results stay in \`work session team\`.`,
55
225
  async run(ctx) {
56
226
  const [verb, ...rest] = ctx.parse([
57
227
  "--agent",
@@ -59,6 +229,12 @@ work session kill <id> --yes
59
229
  "--prompt",
60
230
  "--workspace",
61
231
  "--session",
232
+ "--timeout",
233
+ "--topic",
234
+ "--repo",
235
+ "--count",
236
+ "--parallel",
237
+ "--phase",
62
238
  ]);
63
239
  switch (verb) {
64
240
  case undefined: {
@@ -68,6 +244,7 @@ work session kill <id> --yes
68
244
  if (!me) ctx.die(`no session ${id} in ${ws.name}`);
69
245
  const out = {
70
246
  ...me,
247
+ depth: undefined,
71
248
  workspace: {
72
249
  id: ws.id,
73
250
  name: ws.name,
@@ -77,7 +254,7 @@ work session kill <id> --yes
77
254
  };
78
255
  return ctx.out(out, (s) => {
79
256
  console.log(
80
- `${s.id} ${s.agent} ${s.phase}${s.title ? ` "${s.title}"` : ""}`,
257
+ `${s.id} ${s.agent} ${s.phase}${s.title ? ` "${s.title}"` : ""}${s.waitingOn.length ? ` (waiting on ${s.waitingOn.join(", ")})` : ""}`,
81
258
  );
82
259
  console.log(
83
260
  `workspace ${s.workspace.name} (${s.workspace.id}) ${s.workspace.path}`,
@@ -104,59 +281,247 @@ work session kill <id> --yes
104
281
  }
105
282
  case "new": {
106
283
  const { ws } = await ctx.resolveWorkspace(ctx.flag("--workspace"));
107
- const existing = await sessionsOf(ctx, ws.id);
108
- if (existing.length >= SESSION_CAP && !ctx.has("--force"))
284
+ const running = (await sessionsOf(ctx, ws.id)).filter(
285
+ (s) => s.phase !== "off",
286
+ );
287
+ if (running.length >= SESSION_CAP && !ctx.has("--force"))
109
288
  ctx.die(
110
- `${ws.name} already has ${existing.length} sessions: pass --force to start another`,
289
+ `${ws.name} already has ${running.length} sessions running: pass --force to start another (a group of them is \`work session fanout\`, which queues)`,
111
290
  );
112
291
  const agent = ctx.flag("--agent");
292
+ const me = process.env.WORK_SESSION_ID;
293
+ const prompt = await textOf(valueOf(ctx, "--prompt"));
294
+ const topic = ctx.flag("--topic");
295
+ const at = topic ? await topicDirs(ctx, topic, 1) : null;
113
296
  const created = await ctx.api.post(
114
297
  `/api/workspaces/${ws.id}/sessions`,
115
- agent ? { agent } : {},
298
+ {
299
+ ...(agent ? { agent } : {}),
300
+ ...(me ? { parent: me } : {}),
301
+ ...(at ? { dir: at.dirs[0] } : {}),
302
+ ...(ctx.has("--keep") ? { keep: true } : {}),
303
+ },
116
304
  );
117
305
  const title = ctx.flag("--title");
118
306
  if (title)
119
307
  await ctx.api.patch(`/api/sessions/${created.id}`, { title });
120
- const prompt = ctx.flag("--prompt");
121
308
  // Sent, the session starts (detached) with it as its first
122
309
  // prompt; otherwise it starts when someone opens it.
123
- if (prompt)
124
- await ctx.api.post(`/api/sessions/${created.id}/send`, {
125
- text: prompt,
126
- });
310
+ const sent = prompt
311
+ ? await ctx.api.post(`/api/sessions/${created.id}/messages`, {
312
+ text: prompt,
313
+ ...(me ? { from: me } : {}),
314
+ reply: !ctx.has("--no-reply"),
315
+ })
316
+ : null;
127
317
  const out = {
128
318
  id: created.id,
129
319
  agent: created.agent,
130
320
  title: title || null,
131
321
  workspace: ws.id,
132
- prompted: !!prompt,
322
+ parent: created.parent_id ?? null,
323
+ topic: topic ?? null,
324
+ prompted: !!sent?.delivered,
325
+ queued: sent?.queued ?? null,
326
+ wantsReply: !!sent?.wantsReply,
133
327
  href: `/w/${ws.id}?s=${created.id}`,
134
328
  };
135
- return ctx.out(out, (s) =>
329
+ return ctx.out(out, (s) => {
136
330
  console.log(
137
- `started ${s.id} (${s.agent})${s.prompted ? " with its prompt" : ""}: [${s.title || s.agent}](${s.href})`,
138
- ),
331
+ `started ${s.id} (${s.agent})${s.prompted ? " with its prompt" : ""}${s.topic ? ` on topic ${s.topic}` : ""}: [${s.title || s.agent}](${s.href})`,
332
+ );
333
+ if (s.queued)
334
+ console.log(`its prompt waits to be typed in: ${s.queued}`);
335
+ if (s.wantsReply)
336
+ console.log(
337
+ `Its last message, as that turn ends, comes back to you as a prompt: end your turn to wait for it, or run \`work session wait ${s.id}\`.`,
338
+ );
339
+ });
340
+ }
341
+ case "fanout": {
342
+ const me = sessionId(ctx);
343
+ const agents = ctx.flags("--agent");
344
+ if (!agents.length)
345
+ ctx.die(
346
+ 'usage: work session fanout --agent <id> [--agent <id>…] --prompt "<text>"|- [<item>…] (see: work help session)',
347
+ );
348
+ const prompt = await textOf(valueOf(ctx, "--prompt"));
349
+ if (!prompt) ctx.die("a fan-out needs a --prompt");
350
+ // A "-" is --prompt's stdin, not an item.
351
+ const items = rest.filter((i) => i !== "-");
352
+ const count = ctx.has("--count") ? Number(ctx.flag("--count")) : 1;
353
+ if (!Number.isInteger(count) || count < 1)
354
+ ctx.die("--count is a whole number of members per agent");
355
+ if (items.length && ctx.has("--count"))
356
+ ctx.die("--count or items, not both: items already say how many");
357
+ const parallel = ctx.has("--parallel")
358
+ ? Number(ctx.flag("--parallel"))
359
+ : undefined;
360
+ if (
361
+ parallel !== undefined &&
362
+ (!Number.isInteger(parallel) || parallel < 1)
363
+ )
364
+ ctx.die("--parallel is a whole number of members at once");
365
+ // Members in the server's order: by agent, then by item or number.
366
+ const total = new Set(agents).size * (items.length || count);
367
+ const topic = ctx.flag("--topic");
368
+ const at = topic ? await topicDirs(ctx, topic, total) : null;
369
+ const g = await ctx.api.post(`/api/sessions/${me}/groups`, {
370
+ title: ctx.flag("--title") ?? "",
371
+ prompt,
372
+ agents,
373
+ ...(items.length ? { items } : { count }),
374
+ ...(parallel ? { parallel } : {}),
375
+ ...(ctx.has("--phase") ? { phase: ctx.flag("--phase") } : {}),
376
+ fanIn: !ctx.has("--stream"),
377
+ closeDone: ctx.has("--close-done"),
378
+ keep: ctx.has("--keep"),
379
+ ...(at ? { dirs: at.dirs } : {}),
380
+ });
381
+ return ctx.out({ ...g, topics: at?.names ?? null }, (g) => {
382
+ console.log(
383
+ `fanned out ${g.id} "${g.title}": ${g.members.length} ${g.members.length === 1 ? "member" : "members"}, ${g.parallel} at a time`,
384
+ );
385
+ for (const m of g.members)
386
+ console.log(
387
+ ` ${ctx.pad(m.id, 10)} ${ctx.pad(m.agent, 8)} ${m.title}`,
388
+ );
389
+ if (at) for (const l of at.links) console.log(` review: ${l}`);
390
+ console.log(
391
+ g.fanIn
392
+ ? `Their replies come back to you as one prompt once every member has answered: end your turn to wait, or run \`work session wait ${g.id}\`. \`work session team\` shows how far they are.`
393
+ : `Each reply comes back to you as a prompt as it comes: end your turn to wait, or run \`work session wait ${g.id} --any\`.`,
394
+ );
395
+ });
396
+ }
397
+ case "team": {
398
+ const me = sessionId(ctx);
399
+ const t = await ctx.api.get(`/api/sessions/${me}/team`);
400
+ return ctx.out(t, (t) => {
401
+ if (!t.plan && !t.groups.length)
402
+ return console.log(
403
+ "no plan or groups: `work session fanout` starts one",
404
+ );
405
+ if (t.plan) {
406
+ console.log(
407
+ `plan "${t.plan.name}"${t.plan.done ? " (done)" : ""}: ${t.plan.phases.map((p) => p.title).join(" → ") || "no phases"}`,
408
+ );
409
+ for (const l of t.plan.log) console.log(` · ${l.text}`);
410
+ }
411
+ for (const g of t.groups) printGroup(ctx, g);
412
+ });
413
+ }
414
+ case "retry":
415
+ case "skip": {
416
+ const [member] = rest;
417
+ if (!member) ctx.die(`usage: work session ${verb} <member>`);
418
+ await ctx.api.post(`/api/members/${member}/${verb}`);
419
+ return ctx.out(
420
+ { member, [verb === "retry" ? "retried" : "skipped"]: true },
421
+ () =>
422
+ console.log(
423
+ verb === "retry"
424
+ ? `queued ${member} again`
425
+ : `skipped ${member}`,
426
+ ),
139
427
  );
140
428
  }
141
429
  case "send": {
142
430
  const [id, ...words] = rest;
143
- const text = words.join(" ");
144
- if (!id || !text) ctx.die('usage: work session send <id> "<text>"');
145
- await ctx.api.post(`/api/sessions/${id}/send`, { text });
146
- return ctx.out({ id, sent: true }, () =>
147
- console.log(`sent to ${id}`),
148
- );
431
+ const text = await textOf(words.join(" "));
432
+ if (!id || !text)
433
+ ctx.die('usage: work session send <id> "<text>"|- [--no-reply]');
434
+ const me = process.env.WORK_SESSION_ID;
435
+ const r = await ctx.api.post(`/api/sessions/${id}/messages`, {
436
+ text,
437
+ ...(me ? { from: me } : {}),
438
+ reply: !ctx.has("--no-reply"),
439
+ });
440
+ return ctx.out({ id, ...r }, (r) => console.log(sentText(id, r)));
441
+ }
442
+ case "wait": {
443
+ const me = sessionId(ctx);
444
+ const raw = ctx.flag("--timeout");
445
+ const seconds = raw === undefined ? WAIT_S : Number(raw);
446
+ if (!Number.isFinite(seconds) || seconds < 0)
447
+ ctx.die("--timeout is a number of seconds");
448
+ const any = ctx.has("--any");
449
+ const until = Date.now() + seconds * 1000;
450
+ const body = { ...(rest.length ? { from: rest } : {}), any };
451
+ const replies = [];
452
+ let owing = [];
453
+ for (;;) {
454
+ const r = await ctx.api.post(`/api/sessions/${me}/replies`, body);
455
+ replies.push(...r.replies);
456
+ if (!ctx.json) r.replies.forEach(printReply);
457
+ owing = r.owing;
458
+ if (!owing.length || Date.now() >= until) break;
459
+ if (any && replies.length) break;
460
+ await new Promise((res) => setTimeout(res, POLL_MS));
461
+ }
462
+ if (ctx.json)
463
+ console.log(JSON.stringify({ replies, owing }, null, 2));
464
+ else if (!replies.length && !owing.length)
465
+ console.log(
466
+ rest.length
467
+ ? `nothing owed by ${rest.join(", ")}: a reply already typed in is in your prompt`
468
+ : "no session owes this one a reply",
469
+ );
470
+ if (owing.length && !(any && replies.length)) {
471
+ ctx.warn(
472
+ `still working: ${owing.map((o) => o.label).join(", ")} (wait again, or end your turn: the reply comes as a prompt)`,
473
+ );
474
+ process.exitCode = 124;
475
+ } else if (owing.length && !ctx.json)
476
+ console.log(
477
+ `still working: ${owing.map((o) => o.label).join(", ")}`,
478
+ );
479
+ return;
149
480
  }
150
481
  case "kill": {
482
+ if (ctx.has("--done")) {
483
+ const me = sessionId(ctx);
484
+ const { closed } = await ctx.api.post(
485
+ `/api/sessions/${me}/close-done`,
486
+ );
487
+ return ctx.out({ closed }, () =>
488
+ console.log(
489
+ closed
490
+ ? `closed ${closed} finished ${closed === 1 ? "session" : "sessions"}`
491
+ : "none of the sessions this one started is done with",
492
+ ),
493
+ );
494
+ }
151
495
  const [id] = rest;
152
- if (!id) ctx.die("usage: work session kill <id> --yes");
153
- if (!ctx.yes)
496
+ if (!id)
497
+ ctx.die(
498
+ "usage: work session kill <id> [--keep-children] --yes, or --done",
499
+ );
500
+ const keep = ctx.has("--keep-children");
501
+ if (!ctx.yes) {
502
+ // Said before it happens: what else goes with it.
503
+ const { ws } = await ctx.resolveWorkspace(ctx.flag("--workspace"));
504
+ const list = await sessionsOf(ctx, ws.id);
505
+ const family = [id];
506
+ for (let i = 0; i < family.length; i++)
507
+ for (const s of list)
508
+ if (s.parent === family[i] && !family.includes(s.id))
509
+ family.push(s.id);
510
+ const others = keep ? 0 : family.length - 1;
154
511
  ctx.die(
155
- `closing ${id} ends the process in it${id === process.env.WORK_SESSION_ID ? " — this session, the one running this command" : ""}: pass --yes`,
512
+ `closing ${id} ends the process in it${others ? ` and in the ${others} ${others === 1 ? "session" : "sessions"} it started (${family.slice(1).join(", ")}; --keep-children keeps them)` : ""}${(keep ? [id] : family).includes(process.env.WORK_SESSION_ID) ? " — this session, the one running this command, among them" : ""}: pass --yes`,
156
513
  );
157
- await ctx.api.del(`/api/sessions/${id}`);
158
- return ctx.out({ id, killed: true }, () =>
159
- console.log(`closed ${id}`),
514
+ }
515
+ const r = await ctx.api.del(
516
+ `/api/sessions/${id}${keep ? "?children=keep" : ""}`,
517
+ );
518
+ const closed = r?.closed ?? [id];
519
+ return ctx.out({ id, killed: true, closed }, () =>
520
+ console.log(
521
+ closed.length > 1
522
+ ? `closed ${id} and the sessions it started: ${closed.slice(1).join(", ")}`
523
+ : `closed ${id}`,
524
+ ),
160
525
  );
161
526
  }
162
527
  default: