@dylanpiercey/work 0.2.68 → 0.2.70

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 (493) hide show
  1. package/bin/cli/topic.mjs +374 -23
  2. package/dist/_B25P__C4.js +2 -0
  3. package/dist/{_iwl-plYP.js → _COL0wji1.js} +113 -113
  4. package/dist/{_D3vayu01.js → _CSFzm8Kj.js} +1 -1
  5. package/dist/{_KNWFiRfu.js → _DK0sGNuL.js} +341 -17
  6. package/dist/_wbrwjNyW.js +2 -0
  7. package/dist/index.mjs +906 -868
  8. package/dist/public/assets/{_wvT-w49n.js → _0NYkT7Ka.js} +1 -1
  9. package/dist/public/assets/_0NYkT7Ka.js.br +0 -0
  10. package/dist/public/assets/_18ckOF7L.js +1 -0
  11. package/dist/public/assets/_25qbKqTG.js +1 -0
  12. package/dist/public/assets/{_CcA9L8Uv.js → _6R8pHfHu.js} +1 -1
  13. package/dist/public/assets/_6R8pHfHu.js.br +0 -0
  14. package/dist/public/assets/_8cC5eK8l.js +1 -0
  15. package/dist/public/assets/_8eN6y624.js +1 -0
  16. package/dist/public/assets/_8eN6y624.js.br +0 -0
  17. package/dist/public/assets/_9-vCfD1H.js +1 -0
  18. package/dist/public/assets/_9PSE1hBd.js +1 -0
  19. package/dist/public/assets/{_BpXuBLlJ.js → _B-ItC5A4.js} +1 -1
  20. package/dist/public/assets/_B-ItC5A4.js.br +0 -0
  21. package/dist/public/assets/{_Dr-IU6HK.js → _B-IuONfT.js} +5 -5
  22. package/dist/public/assets/_B-IuONfT.js.br +0 -0
  23. package/dist/public/assets/_B-Nak9W-.js +1 -0
  24. package/dist/public/assets/_B-Nak9W-.js.br +0 -0
  25. package/dist/public/assets/_B0vuJGqQ.js +1 -0
  26. package/dist/public/assets/{_BKxZiX8Y.js → _B24stjuF.js} +5 -5
  27. package/dist/public/assets/_B24stjuF.js.br +0 -0
  28. package/dist/public/assets/_B2HaD9d5.js +1 -0
  29. package/dist/public/assets/{_CDUHEtRr.js → _B3B2tRvZ.js} +1 -1
  30. package/dist/public/assets/_B3B2tRvZ.js.br +0 -0
  31. package/dist/public/assets/_B4oiI3_4.js +1 -0
  32. package/dist/public/assets/_B5CpgKE4.js +1 -0
  33. package/dist/public/assets/_B7Rpwq9e.js +1 -0
  34. package/dist/public/assets/{_Cv3jQpwd.js → _B7THbxch.js} +1 -1
  35. package/dist/public/assets/_B7THbxch.js.br +0 -0
  36. package/dist/public/assets/{_CHyLG_jb.js → _B9BZLh7B.js} +1 -1
  37. package/dist/public/assets/_B9BZLh7B.js.br +0 -0
  38. package/dist/public/assets/{_Cd0WqXuH.js → _B9_Lal-7.js} +1 -1
  39. package/dist/public/assets/_B9_Lal-7.js.br +0 -0
  40. package/dist/public/assets/{_CWUZ37Z2.js → _BC-QJfsn.js} +1 -1
  41. package/dist/public/assets/_BC-QJfsn.js.br +0 -0
  42. package/dist/public/assets/{_Cn1d1sxS.js → _BC1pxNUd.js} +1 -1
  43. package/dist/public/assets/_BC1pxNUd.js.br +0 -0
  44. package/dist/public/assets/{_BWcGdDBZ.js → _BC7rcYFE.js} +1 -1
  45. package/dist/public/assets/_BC7rcYFE.js.br +0 -0
  46. package/dist/public/assets/{_DPT6h_sp.js → _BCgm7As-.js} +1 -1
  47. package/dist/public/assets/_BCgm7As-.js.br +0 -0
  48. package/dist/public/assets/{_BmgC95YK.js → _BDmhvLCs.js} +1 -1
  49. package/dist/public/assets/_BDmhvLCs.js.br +0 -0
  50. package/dist/public/assets/{_BDJY1Xd1.js → _BEO7OuGG.js} +2 -2
  51. package/dist/public/assets/_BEO7OuGG.js.br +0 -0
  52. package/dist/public/assets/{_BtZdp5Pb.js → _BEg-5EkS.js} +1 -1
  53. package/dist/public/assets/_BEg-5EkS.js.br +0 -0
  54. package/dist/public/assets/_BFTxeP-D.js +1 -0
  55. package/dist/public/assets/_BGCoTA5R.js +1 -0
  56. package/dist/public/assets/{_CpU0Rdtw.js → _BJHD6sFy.js} +1 -1
  57. package/dist/public/assets/_BJHD6sFy.js.br +0 -0
  58. package/dist/public/assets/_BJeQROi4.js +1 -0
  59. package/dist/public/assets/_BJeQROi4.js.br +0 -0
  60. package/dist/public/assets/_BKDJIaLf.js +1 -0
  61. package/dist/public/assets/{_Dju_1f03.js → _BM9h7XBb.js} +1 -1
  62. package/dist/public/assets/_BM9h7XBb.js.br +0 -0
  63. package/dist/public/assets/{_Dqo4vWfH.js → _BNlAaEUI.js} +1 -1
  64. package/dist/public/assets/_BNlAaEUI.js.br +0 -0
  65. package/dist/public/assets/{_DWu6n0v3.js → _BOmZO9bQ.js} +1 -1
  66. package/dist/public/assets/_BOmZO9bQ.js.br +0 -0
  67. package/dist/public/assets/{_CI7eaQDi.js → _BQvedQNA.js} +1 -1
  68. package/dist/public/assets/_BQvedQNA.js.br +0 -0
  69. package/dist/public/assets/{_BByUXZCR.js → _BTJ4QNYJ.js} +1 -1
  70. package/dist/public/assets/_BTJ4QNYJ.js.br +0 -0
  71. package/dist/public/assets/_BUnVFLfD.js +1 -0
  72. package/dist/public/assets/{_DM3cX6sN.js → _BUpeVCdC.js} +1 -1
  73. package/dist/public/assets/_BUpeVCdC.js.br +0 -0
  74. package/dist/public/assets/{_CrHoYLWK.js → _BVIQdL1e.js} +1 -1
  75. package/dist/public/assets/_BVIQdL1e.js.br +0 -0
  76. package/dist/public/assets/{_TY_Pdc3F.js → _BVN5lLXw.js} +1 -1
  77. package/dist/public/assets/_BVN5lLXw.js.br +0 -0
  78. package/dist/public/assets/{_RyUSIajb.js → _BVOoaIUz.js} +1 -1
  79. package/dist/public/assets/_BVOoaIUz.js.br +0 -0
  80. package/dist/public/assets/_BYd6ll6G.js +1 -0
  81. package/dist/public/assets/_BZnPwq2i.js +1 -0
  82. package/dist/public/assets/{_kdC_mk_s.js → _BaULj7kH.js} +1 -1
  83. package/dist/public/assets/_BaULj7kH.js.br +0 -0
  84. package/dist/public/assets/_BbdvSQaN.js +1 -0
  85. package/dist/public/assets/{_BTK0j-x0.js → _BjJMzhJj.js} +1 -1
  86. package/dist/public/assets/_BjJMzhJj.js.br +0 -0
  87. package/dist/public/assets/_BkFty1Oi.js +1 -0
  88. package/dist/public/assets/{_BGVrbRXU.js → _BmAd0-4z.js} +1 -1
  89. package/dist/public/assets/{_CjsopDcM.js → _Bo5sqml-.js} +1 -1
  90. package/dist/public/assets/_BryOeCV4.js +1 -0
  91. package/dist/public/assets/_BtAYOnhU.js +1 -0
  92. package/dist/public/assets/{_D46vZBR0.js → _BvDvgf2D.js} +1 -1
  93. package/dist/public/assets/_BvDvgf2D.js.br +0 -0
  94. package/dist/public/assets/{_CTwtnjHT.js → _Bwj1cG6Z.js} +1 -1
  95. package/dist/public/assets/_Bwj1cG6Z.js.br +0 -0
  96. package/dist/public/assets/{_LDz6VXdO.js → _Bwl5RU7m.js} +1 -1
  97. package/dist/public/assets/_Bwl5RU7m.js.br +0 -0
  98. package/dist/public/assets/_Bx7eXUeM.js +1 -0
  99. package/dist/public/assets/_Bxw4J8BV.js +1 -0
  100. package/dist/public/assets/{_CWw2xrr5.js → _BzDLIQE5.js} +1 -1
  101. package/dist/public/assets/_BzDLIQE5.js.br +0 -0
  102. package/dist/public/assets/_BzvCB8DB.js +1 -0
  103. package/dist/public/assets/_C-9WWLQ3.js +1 -0
  104. package/dist/public/assets/_C-_bdY5V.js +1 -0
  105. package/dist/public/assets/{_DyYt1xor.js → _C0zpPwSp.js} +1 -1
  106. package/dist/public/assets/_C0zpPwSp.js.br +0 -0
  107. package/dist/public/assets/{_CJYGh-X3.js → _C2Tbc73e.js} +1 -1
  108. package/dist/public/assets/_C2Tbc73e.js.br +0 -0
  109. package/dist/public/assets/{_uwuCbs_Z.js → _C3RYgw_5.js} +1 -1
  110. package/dist/public/assets/_C3RYgw_5.js.br +0 -0
  111. package/dist/public/assets/_C7P0cxfL.js +1 -0
  112. package/dist/public/assets/_C81AvAMk.js +1 -0
  113. package/dist/public/assets/{_2WOV-Xxm.js → _C8l-PMHJ.js} +1 -1
  114. package/dist/public/assets/_C8l-PMHJ.js.br +0 -0
  115. package/dist/public/assets/{_D7kyaI0s.js → _CAUoTaA1.js} +1 -1
  116. package/dist/public/assets/_CAUoTaA1.js.br +0 -0
  117. package/dist/public/assets/{_D8G71X2r.js → _CCTE_j9L.js} +1 -1
  118. package/dist/public/assets/_CCTE_j9L.js.br +0 -0
  119. package/dist/public/assets/{_rKxafATp.js → _CDXnpAfh.js} +1 -1
  120. package/dist/public/assets/_CDXnpAfh.js.br +0 -0
  121. package/dist/public/assets/_CEWoPra5.js +1 -0
  122. package/dist/public/assets/{_C8Nimh8k.js → _CGSo9tnY.js} +2 -2
  123. package/dist/public/assets/_CGSo9tnY.js.br +0 -0
  124. package/dist/public/assets/_CGsbbcpE.js +1 -0
  125. package/dist/public/assets/{_DA-5OGva.js → _CHuWNcjJ.js} +1 -1
  126. package/dist/public/assets/_CHuWNcjJ.js.br +0 -0
  127. package/dist/public/assets/_CI0KXyAu.js +1 -0
  128. package/dist/public/assets/{_Cs2Zd8pI.js → _CI8Dmpt-.js} +1 -1
  129. package/dist/public/assets/_CI8Dmpt-.js.br +0 -0
  130. package/dist/public/assets/_CKmnCHzt.js +1 -0
  131. package/dist/public/assets/_CNY02rQP.js +1 -0
  132. package/dist/public/assets/{_BiHBXSk1.js → _COjB6Mds.js} +1 -1
  133. package/dist/public/assets/_COjB6Mds.js.br +0 -0
  134. package/dist/public/assets/_CPGWIVjG.js +1 -0
  135. package/dist/public/assets/_CQ0SDG17.js +1 -0
  136. package/dist/public/assets/{_BdeQis2A.js → _CWmrlUIL.js} +1 -1
  137. package/dist/public/assets/_CWmrlUIL.js.br +0 -0
  138. package/dist/public/assets/{_CHy8Yzm5.js → _CXLLGxAE.js} +4 -4
  139. package/dist/public/assets/_CXLLGxAE.js.br +0 -0
  140. package/dist/public/assets/_CXciWQH3.js +1 -0
  141. package/dist/public/assets/_CXjFOElm.js +1 -0
  142. package/dist/public/assets/{_BWZsCsQQ.js → _CbzlAKJK.js} +1 -1
  143. package/dist/public/assets/_CbzlAKJK.js.br +0 -0
  144. package/dist/public/assets/{_BpDpZv1R.js → _CcLifUnb.js} +1 -1
  145. package/dist/public/assets/_CcLifUnb.js.br +0 -0
  146. package/dist/public/assets/{_-mM4yo3H.js → _CcbgX86v.js} +1 -1
  147. package/dist/public/assets/_CcbgX86v.js.br +0 -0
  148. package/dist/public/assets/{_C_VkFQv_.js → _CdDgM-x6.js} +1 -1
  149. package/dist/public/assets/_CdDgM-x6.js.br +0 -0
  150. package/dist/public/assets/_Ce53vsUM.js +1 -0
  151. package/dist/public/assets/_CgdBa1Kb.js +1 -0
  152. package/dist/public/assets/_ChxOfm1L.js +1 -0
  153. package/dist/public/assets/{_CLWpBKoo.js → _Ck0GxYNQ.js} +1 -1
  154. package/dist/public/assets/_Ck0GxYNQ.js.br +0 -0
  155. package/dist/public/assets/_CmIuIy4h.js +1 -0
  156. package/dist/public/assets/{_CRd8czom.js → _Cp-ZKt1Y.js} +1 -1
  157. package/dist/public/assets/_Cp-ZKt1Y.js.br +0 -0
  158. package/dist/public/assets/{_DTseWZHC.js → _CrEFB_dj.js} +1 -1
  159. package/dist/public/assets/_CrEFB_dj.js.br +0 -0
  160. package/dist/public/assets/{_zuaxHefE.js → _Cu31pL3p.js} +1 -1
  161. package/dist/public/assets/_CwaUSclh.js +1 -0
  162. package/dist/public/assets/_Cy9eBufF.js +1 -0
  163. package/dist/public/assets/_CynmXPn2.js +1 -0
  164. package/dist/public/assets/{_DHOPvA0j.js → _CzBug9-x.js} +1 -1
  165. package/dist/public/assets/_CzBug9-x.js.br +0 -0
  166. package/dist/public/assets/{_B60HnTYs.js → _Cznq4Aee.js} +1 -1
  167. package/dist/public/assets/{_D67YJBwp.js → _D-6O7MKA.js} +1 -1
  168. package/dist/public/assets/_D-6O7MKA.js.br +0 -0
  169. package/dist/public/assets/_D-JhJZ2C.js +1 -0
  170. package/dist/public/assets/{_BtEy3x8_.js → _D-XHmBJj.js} +1 -1
  171. package/dist/public/assets/_D-XHmBJj.js.br +0 -0
  172. package/dist/public/assets/_D-neGx47.js +1 -0
  173. package/dist/public/assets/_D5VJGdAr.js +1 -0
  174. package/dist/public/assets/_D6u72i8c.js +1 -0
  175. package/dist/public/assets/_D8tbv6WM.js +1 -0
  176. package/dist/public/assets/{_DfZ3Abt5.js → _DA6CNMAS.js} +1 -1
  177. package/dist/public/assets/_DA6CNMAS.js.br +0 -0
  178. package/dist/public/assets/_DDD7aRxr.js +1 -0
  179. package/dist/public/assets/_DFCbdJTU.js +1 -0
  180. package/dist/public/assets/{_ZDh1oKQp.js → _DGyB0J_Z.js} +1 -1
  181. package/dist/public/assets/_DGyB0J_Z.js.br +0 -0
  182. package/dist/public/assets/{_BoQsdJdV.js → _DJNoam7G.js} +1 -1
  183. package/dist/public/assets/_DJNoam7G.js.br +0 -0
  184. package/dist/public/assets/{_F61IFRtr.js → _DKgv7Cyq.js} +1 -1
  185. package/dist/public/assets/_DKgv7Cyq.js.br +0 -0
  186. package/dist/public/assets/{_D9YIljl9.js → _DM2ZsY5Z.js} +1 -1
  187. package/dist/public/assets/_DM2ZsY5Z.js.br +0 -0
  188. package/dist/public/assets/{_DgHgR-hZ.js → _DO7dqRyj.js} +1 -1
  189. package/dist/public/assets/_DO7dqRyj.js.br +0 -0
  190. package/dist/public/assets/{_D-1h5Hss.js → _DORBDQxD.js} +1 -1
  191. package/dist/public/assets/_DORBDQxD.js.br +0 -0
  192. package/dist/public/assets/_DOsfhfso.js +1 -0
  193. package/dist/public/assets/_DRC6uiX0.js +1 -0
  194. package/dist/public/assets/_DSWmTo1L.js +1 -0
  195. package/dist/public/assets/{_C--f0OAN.js → _DU8DeX60.js} +1 -1
  196. package/dist/public/assets/_DU8DeX60.js.br +0 -0
  197. package/dist/public/assets/_DUKZkilh.js +1 -0
  198. package/dist/public/assets/{_CCAfK1VU.js → _DWCS2CFQ.js} +1 -1
  199. package/dist/public/assets/_DWCS2CFQ.js.br +0 -0
  200. package/dist/public/assets/_DWnX1Z3a.js +1 -0
  201. package/dist/public/assets/_DX71QHMR.js +1 -0
  202. package/dist/public/assets/{_pthxQoj7.js → _DZ0rqa0h.js} +1 -1
  203. package/dist/public/assets/_DZ0rqa0h.js.br +0 -0
  204. package/dist/public/assets/{_DDmNNj38.js → _D_TuAhnN.js} +1 -1
  205. package/dist/public/assets/_D_TuAhnN.js.br +0 -0
  206. package/dist/public/assets/_D_rLfkXR.js +1 -0
  207. package/dist/public/assets/_DeBbHTQf.js +1 -0
  208. package/dist/public/assets/_Dkm85KJF.js +1 -0
  209. package/dist/public/assets/{_DdnBcgjI.js → _Dml0472r.js} +1 -1
  210. package/dist/public/assets/_Dml0472r.js.br +0 -0
  211. package/dist/public/assets/{_BEhDrcww.js → _DouCdQ99.js} +1 -1
  212. package/dist/public/assets/{_CZa0gQzH.js → _DroY8_no.js} +1 -1
  213. package/dist/public/assets/_DroY8_no.js.br +0 -0
  214. package/dist/public/assets/_DtYahvpQ.js +1 -0
  215. package/dist/public/assets/{_Dzr8Nbyu.js → _DuaSYpQG.js} +1 -1
  216. package/dist/public/assets/_DuaSYpQG.js.br +0 -0
  217. package/dist/public/assets/{_SH68xtR9.js → _DuuP0rKI.js} +1 -1
  218. package/dist/public/assets/_DuuP0rKI.js.br +0 -0
  219. package/dist/public/assets/{_0L7GeCf8.js → _DyFziHLM.js} +1 -1
  220. package/dist/public/assets/_DyFziHLM.js.br +0 -0
  221. package/dist/public/assets/_Dz3s4MY0.js +1 -0
  222. package/dist/public/assets/_Dz3s4MY0.js.br +0 -0
  223. package/dist/public/assets/_DzZaUh6D.js +1 -0
  224. package/dist/public/assets/_DzhUXE8_.js +1 -0
  225. package/dist/public/assets/_GWc0eYhN.js +1 -0
  226. package/dist/public/assets/{_BL5Y2CUw.js → _H1xilHgC.js} +1 -1
  227. package/dist/public/assets/_H1xilHgC.js.br +0 -0
  228. package/dist/public/assets/{_Bd9f_2h4.js → _HNyiv6zs.js} +1 -1
  229. package/dist/public/assets/_HNyiv6zs.js.br +0 -0
  230. package/dist/public/assets/{_D-jzW1eS.js → _HlactPnQ.js} +1 -1
  231. package/dist/public/assets/_HlactPnQ.js.br +0 -0
  232. package/dist/public/assets/{_2xmggEiI.js → _JMrxKBGN.js} +1 -1
  233. package/dist/public/assets/_JMrxKBGN.js.br +0 -0
  234. package/dist/public/assets/{_DTQWFGgt.js → _JSiyuxRJ.js} +1 -1
  235. package/dist/public/assets/_JSiyuxRJ.js.br +0 -0
  236. package/dist/public/assets/{_DMsquaig.js → _JcvJ5ACW.js} +1 -1
  237. package/dist/public/assets/_JcvJ5ACW.js.br +0 -0
  238. package/dist/public/assets/{_PMnGojaw.js → _L2f5JNlj.js} +1 -1
  239. package/dist/public/assets/_L2f5JNlj.js.br +0 -0
  240. package/dist/public/assets/_LrU9RmZE.js +1 -0
  241. package/dist/public/assets/{_DAt5J6M_.js → _Mt6ebGGE.js} +10 -10
  242. package/dist/public/assets/_Mt6ebGGE.js.br +0 -0
  243. package/dist/public/assets/_Owc9jhpW.js +2 -0
  244. package/dist/public/assets/_Owc9jhpW.js.br +0 -0
  245. package/dist/public/assets/_PevhFQ5V.js +1 -0
  246. package/dist/public/assets/_R1tJA-Qg.js +1 -0
  247. package/dist/public/assets/{_DHQVtSUu.js → _REcALhmt.js} +1 -1
  248. package/dist/public/assets/_REcALhmt.js.br +0 -0
  249. package/dist/public/assets/{_BFlHBfEr.js → _TZpNJCj6.js} +1 -1
  250. package/dist/public/assets/_TZpNJCj6.js.br +0 -0
  251. package/dist/public/assets/_VDsjaeWW.js +1 -0
  252. package/dist/public/assets/{_DtsqwD_h.js → _VgS7WPcA.js} +1 -1
  253. package/dist/public/assets/_VgS7WPcA.js.br +0 -0
  254. package/dist/public/assets/_WekB6aHl.js +1 -0
  255. package/dist/public/assets/_X4dvLi1w.js +1 -0
  256. package/dist/public/assets/_XXcCKG6W.js +1 -0
  257. package/dist/public/assets/_Y4miPos6.js +1 -0
  258. package/dist/public/assets/{_CbkvJoJj.js → _YATrYiFD.js} +1 -1
  259. package/dist/public/assets/_YATrYiFD.js.br +0 -0
  260. package/dist/public/assets/{_DBn4INpY.js → _YC0QGp9j.js} +1 -1
  261. package/dist/public/assets/_YC0QGp9j.js.br +0 -0
  262. package/dist/public/assets/_YG1qePV2.js +1 -0
  263. package/dist/public/assets/_Yiwgrm_C.js +1 -0
  264. package/dist/public/assets/{_BSZnP2C1.js → __favRwtg.js} +1 -1
  265. package/dist/public/assets/__favRwtg.js.br +0 -0
  266. package/dist/public/assets/_b0whjSZe.js +1 -0
  267. package/dist/public/assets/_cw5fHxTz.js +1 -0
  268. package/dist/public/assets/_gSyGU-mq.js +1 -0
  269. package/dist/public/assets/_j5nRBBVa.js +1 -0
  270. package/dist/public/assets/{_8KVmX-ec.js → _jFGgKTYj.js} +1 -1
  271. package/dist/public/assets/_jFGgKTYj.js.br +0 -0
  272. package/dist/public/assets/{_BmhJ-bQi.js → _kkbInDpy.js} +1 -1
  273. package/dist/public/assets/_kkbInDpy.js.br +0 -0
  274. package/dist/public/assets/_mrvWutef.js +1 -0
  275. package/dist/public/assets/_nCxsopgT.js +1 -0
  276. package/dist/public/assets/_pwbytP5z.js +1 -0
  277. package/dist/public/assets/{_Be760Oeq.js → _sTT2iThd.js} +1 -1
  278. package/dist/public/assets/_sTT2iThd.js.br +0 -0
  279. package/dist/public/assets/{_Xei7jbG-.js → _tGE7SNww.js} +1 -1
  280. package/dist/public/assets/_tGE7SNww.js.br +0 -0
  281. package/dist/public/assets/_veyGCfhb.js +1 -0
  282. package/dist/public/assets/{_7kj3hOfH.js → _vfD02BWU.js} +1 -1
  283. package/dist/public/assets/_vfD02BWU.js.br +0 -0
  284. package/dist/public/assets/files-view-_b8IktQV.js +2 -0
  285. package/dist/public/assets/manage-workspace-Bu8_bkKy.js +2 -0
  286. package/dist/public/assets/new-CGbC3Rki.js +1 -0
  287. package/dist/public/assets/new-workspace-BPq4RG6p.js +2 -0
  288. package/dist/public/assets/review-view-Dwph1tIy.js +2 -0
  289. package/dist/public/assets/settings-CGbC3Rki.js +1 -0
  290. package/dist/public/assets/settings-page-DfjJBEV4.js +2 -0
  291. package/dist/public/assets/styles-DmUe5O9c.css +1 -0
  292. package/dist/public/assets/styles-DmUe5O9c.css.br +0 -0
  293. package/dist/public/assets/w-CGbC3Rki.js +1 -0
  294. package/dist/public/assets/w._-BdlGa_yr.js +1 -0
  295. package/dist/public/assets/w._-CGbC3Rki.js +1 -0
  296. package/dist/public/assets/w._-Cq1MaRMF.js +1 -0
  297. package/package.json +1 -1
  298. package/dist/_tFH4KiOy.js +0 -2
  299. package/dist/_xm4j4quQ.js +0 -2
  300. package/dist/public/assets/_-mM4yo3H.js.br +0 -0
  301. package/dist/public/assets/_0L7GeCf8.js.br +0 -0
  302. package/dist/public/assets/_2WOV-Xxm.js.br +0 -0
  303. package/dist/public/assets/_2xmggEiI.js.br +0 -0
  304. package/dist/public/assets/_5LaG-HZE.js +0 -1
  305. package/dist/public/assets/_7QNxfo9o.js +0 -1
  306. package/dist/public/assets/_7kj3hOfH.js.br +0 -0
  307. package/dist/public/assets/_8AEeEwwI.js +0 -1
  308. package/dist/public/assets/_8KVmX-ec.js.br +0 -0
  309. package/dist/public/assets/_B1J5kQMX.js +0 -1
  310. package/dist/public/assets/_B1ZJGMvk.js +0 -1
  311. package/dist/public/assets/_B3DCz1-b.js +0 -1
  312. package/dist/public/assets/_B3DCz1-b.js.br +0 -0
  313. package/dist/public/assets/_BAD_W-gb.js +0 -1
  314. package/dist/public/assets/_BByUXZCR.js.br +0 -0
  315. package/dist/public/assets/_BDJY1Xd1.js.br +0 -0
  316. package/dist/public/assets/_BFlHBfEr.js.br +0 -0
  317. package/dist/public/assets/_BG6nf7-6.js +0 -1
  318. package/dist/public/assets/_BG6nf7-6.js.br +0 -0
  319. package/dist/public/assets/_BHdwQo1r.js +0 -1
  320. package/dist/public/assets/_BJz1J7VL.js +0 -1
  321. package/dist/public/assets/_BKxZiX8Y.js.br +0 -0
  322. package/dist/public/assets/_BL5Y2CUw.js.br +0 -0
  323. package/dist/public/assets/_BOA9wu9y.js +0 -1
  324. package/dist/public/assets/_BQ6HGMiz.js +0 -1
  325. package/dist/public/assets/_BSZnP2C1.js.br +0 -0
  326. package/dist/public/assets/_BTK0j-x0.js.br +0 -0
  327. package/dist/public/assets/_BWZsCsQQ.js.br +0 -0
  328. package/dist/public/assets/_BWcGdDBZ.js.br +0 -0
  329. package/dist/public/assets/_BX6XuUUI.js +0 -1
  330. package/dist/public/assets/_BYImhKdQ.js +0 -1
  331. package/dist/public/assets/_Bcog8Mvw.js +0 -1
  332. package/dist/public/assets/_Bd9f_2h4.js.br +0 -0
  333. package/dist/public/assets/_BdViCDP-.js +0 -1
  334. package/dist/public/assets/_BdeQis2A.js.br +0 -0
  335. package/dist/public/assets/_Be760Oeq.js.br +0 -0
  336. package/dist/public/assets/_Bf8StQtP.js +0 -1
  337. package/dist/public/assets/_BgqsGerF.js +0 -1
  338. package/dist/public/assets/_BiHBXSk1.js.br +0 -0
  339. package/dist/public/assets/_Bic7QDJn.js +0 -1
  340. package/dist/public/assets/_Bje2UlWb.js +0 -1
  341. package/dist/public/assets/_BmgC95YK.js.br +0 -0
  342. package/dist/public/assets/_BmhJ-bQi.js.br +0 -0
  343. package/dist/public/assets/_BnQVcrhX.js +0 -1
  344. package/dist/public/assets/_BoQsdJdV.js.br +0 -0
  345. package/dist/public/assets/_BoTUkl_N.js +0 -1
  346. package/dist/public/assets/_BpDpZv1R.js.br +0 -0
  347. package/dist/public/assets/_BpGZbbmD.js +0 -1
  348. package/dist/public/assets/_BpXuBLlJ.js.br +0 -0
  349. package/dist/public/assets/_BsRfLR4Y.js +0 -1
  350. package/dist/public/assets/_BtEy3x8_.js.br +0 -0
  351. package/dist/public/assets/_BtZdp5Pb.js.br +0 -0
  352. package/dist/public/assets/_BxFn7bBG.js +0 -1
  353. package/dist/public/assets/_C--f0OAN.js.br +0 -0
  354. package/dist/public/assets/_C-_4KAMq.js +0 -1
  355. package/dist/public/assets/_C3lI_Twn.js +0 -1
  356. package/dist/public/assets/_C51h13b-.js +0 -1
  357. package/dist/public/assets/_C8Nimh8k.js.br +0 -0
  358. package/dist/public/assets/_C9UFsOy1.js +0 -1
  359. package/dist/public/assets/_CBK_SY_j.js +0 -1
  360. package/dist/public/assets/_CCAfK1VU.js.br +0 -0
  361. package/dist/public/assets/_CCw4Mih7.js +0 -1
  362. package/dist/public/assets/_CDUHEtRr.js.br +0 -0
  363. package/dist/public/assets/_CHy8Yzm5.js.br +0 -0
  364. package/dist/public/assets/_CHyLG_jb.js.br +0 -0
  365. package/dist/public/assets/_CI7eaQDi.js.br +0 -0
  366. package/dist/public/assets/_CIwfNMk3.js +0 -1
  367. package/dist/public/assets/_CJYGh-X3.js.br +0 -0
  368. package/dist/public/assets/_CLWpBKoo.js.br +0 -0
  369. package/dist/public/assets/_CPlovKCM.js +0 -1
  370. package/dist/public/assets/_CQDgAaDD.js +0 -1
  371. package/dist/public/assets/_CRd8czom.js.br +0 -0
  372. package/dist/public/assets/_CTwtnjHT.js.br +0 -0
  373. package/dist/public/assets/_CWUZ37Z2.js.br +0 -0
  374. package/dist/public/assets/_CWYdWpGf.js +0 -1
  375. package/dist/public/assets/_CWw2xrr5.js.br +0 -0
  376. package/dist/public/assets/_CZa0gQzH.js.br +0 -0
  377. package/dist/public/assets/_C_VkFQv_.js.br +0 -0
  378. package/dist/public/assets/_Cb5fameO.js +0 -1
  379. package/dist/public/assets/_Cb5znfXe.js +0 -1
  380. package/dist/public/assets/_CbkvJoJj.js.br +0 -0
  381. package/dist/public/assets/_CcA9L8Uv.js.br +0 -0
  382. package/dist/public/assets/_CcmYHRo2.js +0 -1
  383. package/dist/public/assets/_Cd0WqXuH.js.br +0 -0
  384. package/dist/public/assets/_Ci9OrA31.js +0 -1
  385. package/dist/public/assets/_CigEUN1Y.js +0 -1
  386. package/dist/public/assets/_CmCzrX8O.js +0 -1
  387. package/dist/public/assets/_Cn1d1sxS.js.br +0 -0
  388. package/dist/public/assets/_CpU0Rdtw.js.br +0 -0
  389. package/dist/public/assets/_CrHoYLWK.js.br +0 -0
  390. package/dist/public/assets/_CrLAwqeM.js +0 -1
  391. package/dist/public/assets/_Cs2Zd8pI.js.br +0 -0
  392. package/dist/public/assets/_Cs5YLsyh.js +0 -1
  393. package/dist/public/assets/_Cskv-lte.js +0 -1
  394. package/dist/public/assets/_CuZT7B5b.js +0 -1
  395. package/dist/public/assets/_Cv3jQpwd.js.br +0 -0
  396. package/dist/public/assets/_CzKQcLq6.js +0 -1
  397. package/dist/public/assets/_D-1h5Hss.js.br +0 -0
  398. package/dist/public/assets/_D-jzW1eS.js.br +0 -0
  399. package/dist/public/assets/_D3R3E-lW.js +0 -1
  400. package/dist/public/assets/_D3t8fBvV.js +0 -1
  401. package/dist/public/assets/_D46vZBR0.js.br +0 -0
  402. package/dist/public/assets/_D5_5gquy.js +0 -1
  403. package/dist/public/assets/_D624R74e.js +0 -1
  404. package/dist/public/assets/_D67YJBwp.js.br +0 -0
  405. package/dist/public/assets/_D7kyaI0s.js.br +0 -0
  406. package/dist/public/assets/_D8G71X2r.js.br +0 -0
  407. package/dist/public/assets/_D8mUHp4g.js +0 -1
  408. package/dist/public/assets/_D9YIljl9.js.br +0 -0
  409. package/dist/public/assets/_DA-5OGva.js.br +0 -0
  410. package/dist/public/assets/_DAt5J6M_.js.br +0 -0
  411. package/dist/public/assets/_DBn4INpY.js.br +0 -0
  412. package/dist/public/assets/_DBqrfSYd.js +0 -1
  413. package/dist/public/assets/_DDmNNj38.js.br +0 -0
  414. package/dist/public/assets/_DGF9MW5D.js +0 -1
  415. package/dist/public/assets/_DHOPvA0j.js.br +0 -0
  416. package/dist/public/assets/_DHQVtSUu.js.br +0 -0
  417. package/dist/public/assets/_DHTvNsC9.js +0 -1
  418. package/dist/public/assets/_DHafZUX3.js +0 -1
  419. package/dist/public/assets/_DM3cX6sN.js.br +0 -0
  420. package/dist/public/assets/_DMsquaig.js.br +0 -0
  421. package/dist/public/assets/_DNiHEIwz.js +0 -1
  422. package/dist/public/assets/_DPT6h_sp.js.br +0 -0
  423. package/dist/public/assets/_DQaRo0_Z.js +0 -1
  424. package/dist/public/assets/_DSjhAsHE.js +0 -1
  425. package/dist/public/assets/_DTQWFGgt.js.br +0 -0
  426. package/dist/public/assets/_DTseWZHC.js.br +0 -0
  427. package/dist/public/assets/_DULNepbq.js +0 -2
  428. package/dist/public/assets/_DULNepbq.js.br +0 -0
  429. package/dist/public/assets/_DVmk0cGb.js +0 -1
  430. package/dist/public/assets/_DVu8SG8S.js +0 -1
  431. package/dist/public/assets/_DWu6n0v3.js.br +0 -0
  432. package/dist/public/assets/_DYIJgXao.js +0 -1
  433. package/dist/public/assets/_DcDp1vYe.js +0 -1
  434. package/dist/public/assets/_DdnBcgjI.js.br +0 -0
  435. package/dist/public/assets/_DeqyAtmP.js +0 -1
  436. package/dist/public/assets/_DfZ3Abt5.js.br +0 -0
  437. package/dist/public/assets/_DgHgR-hZ.js.br +0 -0
  438. package/dist/public/assets/_Dhk4fgzB.js +0 -1
  439. package/dist/public/assets/_DiNKSmxI.js +0 -1
  440. package/dist/public/assets/_DiUWhWrq.js +0 -1
  441. package/dist/public/assets/_Dj1leKJH.js +0 -1
  442. package/dist/public/assets/_DjpGYd1p.js +0 -1
  443. package/dist/public/assets/_Dju_1f03.js.br +0 -0
  444. package/dist/public/assets/_DmGRSsUt.js +0 -1
  445. package/dist/public/assets/_Dqo4vWfH.js.br +0 -0
  446. package/dist/public/assets/_Dr-IU6HK.js.br +0 -0
  447. package/dist/public/assets/_DrqKhRAQ.js +0 -1
  448. package/dist/public/assets/_DtsqwD_h.js.br +0 -0
  449. package/dist/public/assets/_DyYt1xor.js.br +0 -0
  450. package/dist/public/assets/_DzFqbsGy.js +0 -1
  451. package/dist/public/assets/_Dzr8Nbyu.js.br +0 -0
  452. package/dist/public/assets/_EaUViMxr.js +0 -1
  453. package/dist/public/assets/_F61IFRtr.js.br +0 -0
  454. package/dist/public/assets/_JBpSIlgX.js +0 -1
  455. package/dist/public/assets/_JoAwMfkR.js +0 -1
  456. package/dist/public/assets/_LDz6VXdO.js.br +0 -0
  457. package/dist/public/assets/_Lop0HV3P.js +0 -1
  458. package/dist/public/assets/_Lop0HV3P.js.br +0 -0
  459. package/dist/public/assets/_Mg9GxHtB.js +0 -1
  460. package/dist/public/assets/_NwIYFT5B.js +0 -1
  461. package/dist/public/assets/_NwIYFT5B.js.br +0 -0
  462. package/dist/public/assets/_PMnGojaw.js.br +0 -0
  463. package/dist/public/assets/_RyUSIajb.js.br +0 -0
  464. package/dist/public/assets/_SH68xtR9.js.br +0 -0
  465. package/dist/public/assets/_TY_Pdc3F.js.br +0 -0
  466. package/dist/public/assets/_U6p2S3Z0.js +0 -1
  467. package/dist/public/assets/_V56TvjWJ.js +0 -1
  468. package/dist/public/assets/_Xei7jbG-.js.br +0 -0
  469. package/dist/public/assets/_ZDh1oKQp.js.br +0 -0
  470. package/dist/public/assets/__rjIklzT.js +0 -1
  471. package/dist/public/assets/_asNggv5C.js +0 -1
  472. package/dist/public/assets/_cSxqqciM.js +0 -1
  473. package/dist/public/assets/_hYHHWgXz.js +0 -1
  474. package/dist/public/assets/_kdC_mk_s.js.br +0 -0
  475. package/dist/public/assets/_pthxQoj7.js.br +0 -0
  476. package/dist/public/assets/_qss_F0VZ.js +0 -1
  477. package/dist/public/assets/_rKxafATp.js.br +0 -0
  478. package/dist/public/assets/_uwuCbs_Z.js.br +0 -0
  479. package/dist/public/assets/_wBNa2EL1.js +0 -1
  480. package/dist/public/assets/_wvT-w49n.js.br +0 -0
  481. package/dist/public/assets/files-view-D5Fv0SIK.js +0 -2
  482. package/dist/public/assets/manage-workspace-Cb9sMIjp.js +0 -2
  483. package/dist/public/assets/new-5AQb7ar3.js +0 -1
  484. package/dist/public/assets/new-workspace-o3VxyV3X.js +0 -2
  485. package/dist/public/assets/review-view-BNRZ1rgz.js +0 -2
  486. package/dist/public/assets/settings-5AQb7ar3.js +0 -1
  487. package/dist/public/assets/settings-page-6pXaU21j.js +0 -2
  488. package/dist/public/assets/styles-6nJ2WylG.css +0 -1
  489. package/dist/public/assets/styles-6nJ2WylG.css.br +0 -0
  490. package/dist/public/assets/w-5AQb7ar3.js +0 -1
  491. package/dist/public/assets/w._-5AQb7ar3.js +0 -1
  492. package/dist/public/assets/w._-6Uhhy1cN.js +0 -1
  493. package/dist/public/assets/w._-BdCzUYn6.js +0 -1
package/bin/cli/topic.mjs CHANGED
@@ -6,6 +6,7 @@
6
6
  // plus the server's workspace rows (bases) and status (PRs).
7
7
  import { spawnSync } from "node:child_process";
8
8
  import fs from "node:fs";
9
+ import os from "node:os";
9
10
  import path from "node:path";
10
11
 
11
12
  /** A topic's name: a word, or `<group>.<topic>` (folded into one review
@@ -24,11 +25,12 @@ const INSTALLERS = [
24
25
  ["Gemfile.lock", "bundle install"],
25
26
  ];
26
27
 
27
- function git(cwd, args, { allowFail = false } = {}) {
28
+ function git(cwd, args, { allowFail = false, env = {}, input } = {}) {
28
29
  const r = spawnSync("git", args, {
29
30
  cwd,
30
31
  encoding: "utf8",
31
- env: { ...process.env, GIT_TERMINAL_PROMPT: "0" },
32
+ env: { ...process.env, GIT_TERMINAL_PROMPT: "0", ...env },
33
+ input,
32
34
  });
33
35
  if (r.status !== 0 && !allowFail) {
34
36
  const why = (r.stderr || r.stdout || "").trim() || `exit ${r.status}`;
@@ -106,6 +108,27 @@ function aheadBehind(dir, base, tip) {
106
108
  return { ahead, behind };
107
109
  }
108
110
 
111
+ /** Its changes are all in `base` already though its commits are not —
112
+ * squashed into another PR, cherry-picked, folded in by hand: merging it
113
+ * there would change nothing, or every one of its commits' patches is
114
+ * there. Either way nothing is lost by putting it away, where ancestry
115
+ * alone called it unmerged for good. */
116
+ function landedIn(dir, base, tip) {
117
+ const merged = git(dir, ["merge-tree", "--write-tree", base, tip], {
118
+ allowFail: true,
119
+ });
120
+ // A clean merge prints its tree alone; one with conflicts exits 1.
121
+ if (merged.ok && merged.out === oid(dir, `${base}^{tree}`)) return true;
122
+ // Each commit's patch already there (`-`), even where the base has moved
123
+ // the same lines on since and the merge would conflict.
124
+ const cherry = git(dir, ["cherry", base, tip], { allowFail: true });
125
+ return (
126
+ cherry.ok &&
127
+ cherry.out !== "" &&
128
+ cherry.out.split("\n").every((l) => l.startsWith("- "))
129
+ );
130
+ }
131
+
109
132
  /** Where the workspace and its repos are, the other workspaces' branches
110
133
  * (whose topics are not this one's), and each repo's PRs — dismissed ones
111
134
  * too: a merged chip the user dismissed is still the merge that lets
@@ -374,6 +397,7 @@ function topicsIn(ws, repo, foreign) {
374
397
  // What `topic new` recorded for gh: the branch it stacks on, else the
375
398
  // repo's base.
376
399
  const recorded = mergeBases(repo.dir);
400
+ const dropped = droppedBranches(repo.dir);
377
401
  const bases = new Map();
378
402
  return [...branches].sort().map((branch) => {
379
403
  const name = branch.slice(prefix.length);
@@ -389,6 +413,7 @@ function topicsIn(ws, repo, foreign) {
389
413
  : { ahead: null, behind: null };
390
414
  const worktree = trees.get(branch) || null;
391
415
  const pr = prFor(repo, branch);
416
+ const contained = !!base && ahead === 0;
392
417
  return {
393
418
  topic: name,
394
419
  repo: repo.worktree,
@@ -424,7 +449,12 @@ function topicsIn(ws, repo, foreign) {
424
449
  // Nothing of its own past the base: either merged as it was, or a
425
450
  // topic with no commits yet. Either way, nothing is lost by
426
451
  // putting its worktree away.
427
- contained: !!base && ahead === 0,
452
+ contained,
453
+ // Commits of its own, but none of its changes the base lacks.
454
+ landed: !!base && !contained && landedIn(repo.dir, base, tip),
455
+ // Dropped here (`topic drop`), its local branch gone: what is left is
456
+ // origin's copy, which drop leaves alone.
457
+ dropped: !local && dropped.has(branch),
428
458
  link: link(ws, repo, name),
429
459
  };
430
460
  });
@@ -433,9 +463,11 @@ function topicsIn(ws, repo, foreign) {
433
463
  async function topicList(ctx) {
434
464
  const { ws, repos, foreign } = await context(ctx, ctx.has("--fresh"));
435
465
  const all = repos.flatMap((repo) => topicsIn(ws, repo, foreign));
436
- // Put away: merged (or nothing past its base) with no worktree left —
437
- // its branch kept, as the after-merge chores leave it. Listed on asking.
438
- const away = (t) => !t.worktree && (t.merged || t.contained);
466
+ // Put away: merged (or nothing of it its base lacks) with no worktree
467
+ // left — its branch kept, as the after-merge chores leave it — or dropped
468
+ // here. Listed on asking.
469
+ const away = (t) =>
470
+ t.dropped || (!t.worktree && (t.merged || t.contained || t.landed));
439
471
  const rows = ctx.has("--all") ? all : all.filter((t) => !away(t));
440
472
  const hidden = all.length - rows.length;
441
473
  ctx.out(rows, (list) => {
@@ -450,7 +482,9 @@ async function topicList(ctx) {
450
482
  ? `no ${t.baseBranch} or origin/${t.baseBranch} here to count against`
451
483
  : t.contained
452
484
  ? `nothing past ${t.base}`
453
- : `${t.ahead} ahead, ${t.behind} behind ${t.base}`;
485
+ : t.landed
486
+ ? `landed in ${t.base} (by other commits: ${t.ahead} of its own, none of its changes missing there)`
487
+ : `${t.ahead} ahead, ${t.behind} behind ${t.base}`;
454
488
  const flags = [
455
489
  t.dirty ? `${t.dirty} uncommitted` : null,
456
490
  t.local && !t.onOrigin && t.ahead ? "not pushed" : null,
@@ -458,7 +492,8 @@ async function topicList(ctx) {
458
492
  t.local && t.onOrigin && !t.unpushed && !t.pushed
459
493
  ? "origin has newer"
460
494
  : null,
461
- !t.local ? "only on origin" : null,
495
+ t.dropped ? "dropped here, origin keeps it" : null,
496
+ !t.local && !t.dropped ? "only on origin" : null,
462
497
  ].filter(Boolean);
463
498
  const pr = t.pr
464
499
  ? ` #${t.pr.number} ${t.pr.state === "OPEN" ? (t.pr.draft ? "draft" : "open") : t.pr.state.toLowerCase()}`
@@ -471,7 +506,7 @@ async function topicList(ctx) {
471
506
  }
472
507
  if (hidden)
473
508
  console.log(
474
- `${hidden} put away (merged, worktree removed): --all lists them`,
509
+ `${hidden} put away (merged or landed with its worktree removed, or dropped): --all lists them`,
475
510
  );
476
511
  });
477
512
  }
@@ -483,7 +518,7 @@ async function topicList(ctx) {
483
518
  * PR's head, or past what origin has of it. */
484
519
  function leftover(repo, t, pr) {
485
520
  const local = oid(repo.dir, `refs/heads/${t.branch}`);
486
- if (!local || t.contained) return null;
521
+ if (!local || t.contained || t.landed) return null;
487
522
  let head = pr?.headRefOid || null;
488
523
  if (head && !has(repo.dir, `${head}^{commit}`)) {
489
524
  // A squash-merged PR's head lives on in GitHub's pull ref.
@@ -532,15 +567,18 @@ async function topicDone(ctx) {
532
567
  const t = topicsIn(ws, repo, foreign).find((x) => x.branch === branch);
533
568
  if (!t) continue;
534
569
  const pr = prFor(repo, branch);
535
- if (!t.merged && !t.contained) {
570
+ if (!t.merged && !t.contained && !t.landed) {
536
571
  const prState = t.pr
537
572
  ? ` (#${t.pr.number} is ${t.pr.state.toLowerCase()})`
538
573
  : "";
574
+ // An abandoned topic is never merged: say how it goes instead.
539
575
  result.refused.push({
540
576
  repo: repo.worktree,
541
- why: t.base
542
- ? `${branch} is not merged${prState} and has ${t.ahead} commit(s) ${t.base} does not`
543
- : `${branch} is not merged${prState}, and there is no ${t.baseBranch} or origin/${t.baseBranch} here to check it against`,
577
+ why: `${
578
+ t.base
579
+ ? `${branch} is not merged${prState} and has changes in ${t.ahead} commit(s) ${t.base} lacks`
580
+ : `${branch} is not merged${prState}, and there is no ${t.baseBranch} or origin/${t.baseBranch} here to check it against`
581
+ } (to abandon it: work topic drop ${name})`,
544
582
  });
545
583
  continue;
546
584
  }
@@ -603,7 +641,8 @@ async function topicDone(ctx) {
603
641
  }
604
642
  // Nothing of its own: left where it is, unless what it stacks on
605
643
  // moved out from under it.
606
- if (other.contained && !moved.has(other.baseBranch)) continue;
644
+ if ((other.contained || other.landed) && !moved.has(other.baseBranch))
645
+ continue;
607
646
  const base = restack ? t.base : other.base;
608
647
  if (!other.local || !base) continue;
609
648
  const { behind } = aheadBehind(repo.dir, base, other.branch);
@@ -684,6 +723,307 @@ async function topicDone(ctx) {
684
723
  process.exitCode = 1;
685
724
  }
686
725
 
726
+ // -- drop --------------------------------------------------------------------
727
+
728
+ /** Where a dropped topic's last tip is kept, a ref per drop
729
+ * (`<branch>/<UTC stamp>`): outside `refs/work/<workspace>/`, whose
730
+ * snapshots the server prunes, and in no push. */
731
+ const DROPPED = "refs/work-dropped/";
732
+ /** How long a dropped topic can be brought back. */
733
+ const KEEP_DROPPED_DAYS = 30;
734
+ const DAY = 86_400_000;
735
+
736
+ const stampOf = (d) =>
737
+ d
738
+ .toISOString()
739
+ .replace(/[-:]/g, "")
740
+ .replace(/\.\d+Z$/, "Z");
741
+
742
+ function stampTime(stamp) {
743
+ const m = /^(\d{4})(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)Z$/.exec(stamp);
744
+ return m ? Date.UTC(+m[1], +m[2] - 1, +m[3], +m[4], +m[5], +m[6]) : null;
745
+ }
746
+
747
+ /** Each dropped ref: its branch, the time of its drop. */
748
+ function droppedRefs(dir) {
749
+ return git(dir, ["for-each-ref", "--format=%(refname)", DROPPED], {
750
+ allowFail: true,
751
+ })
752
+ .out.split("\n")
753
+ .filter(Boolean)
754
+ .map((ref) => {
755
+ const rest = ref.slice(DROPPED.length);
756
+ const cut = rest.lastIndexOf("/");
757
+ return {
758
+ ref,
759
+ branch: rest.slice(0, cut),
760
+ at: stampTime(rest.slice(cut + 1)),
761
+ };
762
+ })
763
+ .filter((r) => r.branch && r.at !== null);
764
+ }
765
+
766
+ /** The branches dropped here (within their keep). */
767
+ function droppedBranches(dir) {
768
+ return new Set(droppedRefs(dir).map((r) => r.branch));
769
+ }
770
+
771
+ /** Dropped refs past their keep, gone: every workspace's on this repo,
772
+ * since its cache is shared and a deleted workspace drops nothing again. */
773
+ function pruneDropped(dir, now = Date.now()) {
774
+ const gone = droppedRefs(dir).filter(
775
+ (r) => r.at < now - KEEP_DROPPED_DAYS * DAY,
776
+ );
777
+ if (gone.length)
778
+ git(dir, ["update-ref", "--stdin"], {
779
+ allowFail: true,
780
+ input: gone.map((r) => `delete ${r.ref}\n`).join(""),
781
+ });
782
+ return gone.length;
783
+ }
784
+
785
+ /** A worktree as it is — uncommitted and untracked files too — as a commit
786
+ * on its HEAD, made through an index of its own so the worktree and its
787
+ * index are untouched: a forced drop keeps what it discards. */
788
+ function snapshotOf(worktree, message) {
789
+ const index = path.join(
790
+ os.tmpdir(),
791
+ `work-topic-drop-${process.pid}-${Date.now()}.index`,
792
+ );
793
+ // An identity of its own (a machine with none set still drops) and no
794
+ // signing (a key's passphrase prompt would hang a script).
795
+ const env = {
796
+ GIT_INDEX_FILE: index,
797
+ GIT_AUTHOR_NAME: "work",
798
+ GIT_AUTHOR_EMAIL: "work@localhost",
799
+ GIT_COMMITTER_NAME: "work",
800
+ GIT_COMMITTER_EMAIL: "work@localhost",
801
+ };
802
+ try {
803
+ git(worktree, ["read-tree", "HEAD"], { env });
804
+ git(worktree, ["add", "-A"], { env });
805
+ const tree = git(worktree, ["write-tree"], { env }).out;
806
+ return git(
807
+ worktree,
808
+ ["commit-tree", "--no-gpg-sign", tree, "-p", "HEAD", "-m", message],
809
+ { env },
810
+ ).out;
811
+ } finally {
812
+ fs.rmSync(index, { force: true });
813
+ }
814
+ }
815
+
816
+ const real = (p) => {
817
+ try {
818
+ return fs.realpathSync(p);
819
+ } catch {
820
+ return path.resolve(p);
821
+ }
822
+ };
823
+ const within = (dir, root) => dir === root || dir.startsWith(root + path.sep);
824
+
825
+ /** Everything about dropping the topic in one repo, before any of it is
826
+ * done: what goes, what would be lost, and what stands in the way —
827
+ * `blocks` give way to --yes, `stops` never do. */
828
+ function planDrop(ctx, ws, repo, t, sessions, topics) {
829
+ const plan = { repo, t, lost: [], blocks: [], stops: [], dirty: [] };
830
+ plan.local = oid(repo.dir, `refs/heads/${t.branch}`);
831
+ if (!plan.local) return plan;
832
+ if (t.worktree && real(t.worktree) === real(repo.dir))
833
+ plan.stops.push(
834
+ `${t.branch} is checked out in the workspace's own checkout (${repo.dir}): switch that off it first`,
835
+ );
836
+ if (t.worktree) {
837
+ plan.dirty = dirtyIn(t.worktree);
838
+ if (plan.dirty.length)
839
+ plan.blocks.push(
840
+ `${t.worktree} has ${plan.dirty.length} uncommitted change(s):\n ${plan.dirty.slice(0, 10).join("\n ")}`,
841
+ );
842
+ const here = real(t.worktree);
843
+ for (const s of sessions)
844
+ if (
845
+ s.state?.alive &&
846
+ s.launch_dir &&
847
+ within(real(path.resolve(ws.path, s.launch_dir)), here)
848
+ )
849
+ plan.blocks.push(
850
+ `session ${s.id}${s.title ? ` ("${s.title}")` : ""} is working in ${t.worktree}`,
851
+ );
852
+ }
853
+ // What the drop discards: none of it when its base holds every change.
854
+ const merged = t.merged && !leftover(repo, t, prFor(repo, t.branch));
855
+ if (!t.contained && !t.landed && !merged) {
856
+ if (!t.base)
857
+ plan.blocks.push(
858
+ `there is no ${t.baseBranch} or origin/${t.baseBranch} here to tell what of ${t.branch} would be lost`,
859
+ );
860
+ else {
861
+ plan.lost = git(repo.dir, [
862
+ "log",
863
+ "--format=%h %s",
864
+ `${t.base}..${plan.local}`,
865
+ ]).out.split("\n");
866
+ plan.blocks.push(
867
+ `${t.branch} has ${plan.lost.length} commit(s) whose changes ${t.base} lacks${
868
+ t.unpushed
869
+ ? `, ${t.onOrigin ? t.unpushed : "all"} of them on no remote`
870
+ : ""
871
+ }:\n ${plan.lost.slice(0, 10).join("\n ")}`,
872
+ );
873
+ }
874
+ }
875
+ if (t.pr?.state === "OPEN")
876
+ plan.blocks.push(
877
+ `#${t.pr.number} is open (the drop leaves the PR and origin's copy as they are)`,
878
+ );
879
+ plan.stacked = topics.filter(
880
+ (o) => o.branch !== t.branch && o.local && o.baseBranch === t.branch,
881
+ );
882
+ for (const o of plan.stacked)
883
+ plan.blocks.push(
884
+ `${o.branch} stacks on it (with --yes it is counted against ${t.baseBranch} instead, still carrying ${t.branch}'s commits)`,
885
+ );
886
+ return plan;
887
+ }
888
+
889
+ async function topicDrop(ctx) {
890
+ const [name] = ctx.parse([]);
891
+ if (!name) ctx.die("usage: work topic drop <name> [--yes] [--json]");
892
+ const { ws, repos, foreign } = await context(ctx, false);
893
+ const branch = `${ws.branch}-${name}`;
894
+ const touched = repos.filter(
895
+ (r) =>
896
+ has(r.dir, `refs/heads/${branch}`) ||
897
+ has(r.dir, `refs/remotes/origin/${branch}`),
898
+ );
899
+ if (!touched.length)
900
+ ctx.die(`no topic ${name} in ${ws.name} (see: work topic list)`);
901
+ const sessions = await ctx.api
902
+ .get(`/api/workspaces/${ws.id}/sessions`)
903
+ .catch(() => []);
904
+ // Every repo is planned before any is touched: half a topic dropped is
905
+ // worse than none.
906
+ const plans = [];
907
+ for (const repo of touched) {
908
+ // A fetch that fails (offline) only leaves the base older, which can
909
+ // only find more to lose.
910
+ ctx.log(`fetching ${repo.full_name}…`);
911
+ if (
912
+ !git(repo.dir, ["fetch", "--prune", "--quiet", "origin"], {
913
+ allowFail: true,
914
+ }).ok
915
+ )
916
+ ctx.warn(
917
+ `${repo.worktree}: could not fetch origin; counting against what is here`,
918
+ );
919
+ const topics = topicsIn(ws, repo, foreign);
920
+ const t = topics.find((x) => x.branch === branch);
921
+ if (t) plans.push(planDrop(ctx, ws, repo, t, sessions, topics));
922
+ }
923
+ const result = {
924
+ topic: name,
925
+ dropped: [],
926
+ skipped: [],
927
+ refused: [],
928
+ restacked: [],
929
+ };
930
+ for (const p of plans) {
931
+ for (const why of p.stops)
932
+ result.refused.push({ repo: p.repo.worktree, why });
933
+ if (!ctx.yes)
934
+ for (const why of p.blocks)
935
+ result.refused.push({ repo: p.repo.worktree, why });
936
+ }
937
+ if (!result.refused.length) {
938
+ const at = new Date();
939
+ for (const p of plans) {
940
+ const { repo, t } = p;
941
+ if (!p.local) {
942
+ result.skipped.push({
943
+ repo: repo.worktree,
944
+ why: `${branch} is only on origin: nothing here to drop (git push origin --delete ${branch} removes it there)`,
945
+ });
946
+ continue;
947
+ }
948
+ pruneDropped(repo.dir, at.getTime());
949
+ const keep = p.dirty.length
950
+ ? snapshotOf(
951
+ t.worktree,
952
+ `work topic drop: ${branch} with its uncommitted changes`,
953
+ )
954
+ : p.local;
955
+ const ref = `${DROPPED}${branch}/${stampOf(at)}`;
956
+ git(repo.dir, ["update-ref", ref, keep]);
957
+ if (t.worktree) {
958
+ git(repo.dir, [
959
+ "worktree",
960
+ "remove",
961
+ ...(p.dirty.length ? ["--force"] : []),
962
+ t.worktree,
963
+ ]);
964
+ // The topic's own folder, once its last repo's worktree is gone.
965
+ try {
966
+ fs.rmdirSync(path.dirname(t.worktree));
967
+ } catch {}
968
+ }
969
+ for (const o of p.stacked) {
970
+ git(repo.dir, [
971
+ "config",
972
+ `branch.${o.branch}.gh-merge-base`,
973
+ t.baseBranch,
974
+ ]);
975
+ result.restacked.push({
976
+ repo: repo.worktree,
977
+ branch: o.branch,
978
+ base: t.baseBranch,
979
+ });
980
+ }
981
+ // Its config (the recorded base) goes with it.
982
+ git(repo.dir, ["branch", "-D", branch]);
983
+ result.dropped.push({
984
+ repo: repo.worktree,
985
+ branch,
986
+ worktree: t.worktree,
987
+ commits: p.lost.filter(Boolean).length,
988
+ unpushed: p.lost.length ? t.unpushed : 0,
989
+ uncommitted: p.dirty.length,
990
+ kept: ref,
991
+ keptDays: KEEP_DROPPED_DAYS,
992
+ restore: `git -C ${repo.dir} branch ${branch} ${ref}`,
993
+ onOrigin: t.onOrigin,
994
+ });
995
+ }
996
+ }
997
+ ctx.out(result, (r) => {
998
+ for (const x of r.dropped) {
999
+ const lost = [
1000
+ x.commits ? `${x.commits} commit(s) its base lacks` : null,
1001
+ x.uncommitted ? `${x.uncommitted} uncommitted change(s)` : null,
1002
+ ].filter(Boolean);
1003
+ console.log(
1004
+ `${x.repo}: dropped ${x.branch}${lost.length ? ` (${lost.join(", ")})` : ""}`,
1005
+ );
1006
+ if (x.worktree) console.log(` removed ${x.worktree}`);
1007
+ console.log(
1008
+ ` kept as ${x.kept} for ${x.keptDays} days; to bring it back: ${x.restore}${x.uncommitted ? " (its top commit holds the uncommitted changes)" : ""}`,
1009
+ );
1010
+ if (x.onOrigin)
1011
+ console.log(
1012
+ ` origin/${x.branch} is still on origin (git push origin --delete ${x.branch} removes it)`,
1013
+ );
1014
+ }
1015
+ for (const x of r.skipped) console.log(`${x.repo}: ${x.why}`);
1016
+ for (const x of r.restacked)
1017
+ console.log(`${x.repo}: ${x.branch} now counts against ${x.base}`);
1018
+ for (const x of r.refused) console.log(`${x.repo}: ${x.why}`);
1019
+ if (r.refused.length)
1020
+ console.log(
1021
+ `nothing dropped${ctx.yes ? "" : `: pass --yes to drop it anyway (its tip and uncommitted changes are kept ${KEEP_DROPPED_DAYS} days)`}`,
1022
+ );
1023
+ });
1024
+ if (result.refused.length) process.exitCode = 1;
1025
+ }
1026
+
687
1027
  // -- command -----------------------------------------------------------------
688
1028
 
689
1029
  const HELP = `work topic new <name> [--repo <repo>]… [--from <ref>] [--install]
@@ -703,17 +1043,27 @@ work topic list [--all] [--fresh] [--json]
703
1043
  answer.
704
1044
  work topic done <name> [--rebase] [--json]
705
1045
  after its PR merged, or once its base holds all of it (merged there
706
- by hand, say): fetch --prune, remove its worktree (only if clean, and
707
- only if the merge took every commit), keep the branch, and list the
708
- other open topics to rebase, each onto its own base — one stacked on
709
- this topic onto this one's, which becomes its base. --rebase does it
710
- where the worktree is clean, aborting on conflict. Never touches the
711
- workspace's own checkout.`;
1046
+ by hand, say) or all of its changes by other commits (squashed into
1047
+ another PR, cherry-picked): fetch --prune, remove its worktree (only
1048
+ if clean, and only if the merge took every commit), keep the branch,
1049
+ and list the other open topics to rebase, each onto its own base — one
1050
+ stacked on this topic onto this one's, which becomes its base.
1051
+ --rebase does it where the worktree is clean, aborting on conflict.
1052
+ Never touches the workspace's own checkout.
1053
+ work topic drop <name> [--yes] [--json]
1054
+ abandon a topic: remove its worktree and delete its local branch,
1055
+ keeping its tip (with any uncommitted changes) as
1056
+ refs/work-dropped/<branch>/<when> for ${KEEP_DROPPED_DAYS} days; the output says how to
1057
+ bring it back. Refuses, unless --yes, whatever would discard work:
1058
+ commits whose changes its base lacks (and which of them no remote has),
1059
+ uncommitted changes, a session working in it, a topic stacked on it, an
1060
+ open PR. Origin's copy and any PR are left as they are. Never touches
1061
+ the workspace's own checkout.`;
712
1062
 
713
1063
  export const commands = [
714
1064
  {
715
1065
  name: "topic",
716
- summary: "start, list and put away topic branches (work help topic)",
1066
+ summary: "start, list, put away and drop topic branches (work help topic)",
717
1067
  help: HELP,
718
1068
  async run(ctx) {
719
1069
  const [verb] = ctx.positional;
@@ -725,11 +1075,12 @@ export const commands = [
725
1075
  if (verb === "list" || verb === "ls" || !verb)
726
1076
  return await topicList(sub);
727
1077
  if (verb === "done") return await topicDone(sub);
1078
+ if (verb === "drop") return await topicDrop(sub);
728
1079
  } catch (err) {
729
1080
  ctx.die(err instanceof Error ? err.message : String(err));
730
1081
  }
731
1082
  ctx.die(
732
- `no \`work topic ${verb}\`: new, list or done (see: work help topic)`,
1083
+ `no \`work topic ${verb}\`: new, list, done or drop (see: work help topic)`,
733
1084
  );
734
1085
  },
735
1086
  },
@@ -0,0 +1,2 @@
1
+ import { h as teamsOf } from "./_CSFzm8Kj.js";
2
+ export { teamsOf };