@dylanpiercey/work 0.2.70 → 0.2.72

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 (495) hide show
  1. package/bin/cli/session.mjs +36 -4
  2. package/bin/cli/topic.mjs +47 -0
  3. package/dist/_BA1HQgf_.js +2 -0
  4. package/dist/{_COL0wji1.js → _CY_o8akv.js} +112 -112
  5. package/dist/_CfUEaP2Y.js +2 -0
  6. package/dist/{_DK0sGNuL.js → _Ckb53sPe.js} +379 -81
  7. package/dist/{_CSFzm8Kj.js → _D7kw4Cra.js} +100 -11
  8. package/dist/index.mjs +1369 -1241
  9. package/dist/public/assets/_-1drb5Pj.js +1 -0
  10. package/dist/public/assets/{_DouCdQ99.js → _-ZjuKQ69.js} +1 -1
  11. package/dist/public/assets/{_Cu31pL3p.js → _0xMmAO7X.js} +1 -1
  12. package/dist/public/assets/_23an2mBO.js +1 -0
  13. package/dist/public/assets/{_HNyiv6zs.js → _2DDDymAM.js} +1 -1
  14. package/dist/public/assets/_2DDDymAM.js.br +0 -0
  15. package/dist/public/assets/_48yodguc.js +1 -0
  16. package/dist/public/assets/{_DM2ZsY5Z.js → _4SjgYRiO.js} +1 -1
  17. package/dist/public/assets/_4SjgYRiO.js.br +0 -0
  18. package/dist/public/assets/_6wCJdbw1.js +1 -0
  19. package/dist/public/assets/_6x6WVvk7.js +1 -0
  20. package/dist/public/assets/{_DZ0rqa0h.js → _7qU4TZu6.js} +1 -1
  21. package/dist/public/assets/_7qU4TZu6.js.br +0 -0
  22. package/dist/public/assets/_84rKMLYo.js +1 -0
  23. package/dist/public/assets/{_tGE7SNww.js → _8E6znG9c.js} +1 -1
  24. package/dist/public/assets/_8E6znG9c.js.br +0 -0
  25. package/dist/public/assets/_B3kVEqX1.js +1 -0
  26. package/dist/public/assets/{_BQvedQNA.js → _B4FWkW6c.js} +1 -1
  27. package/dist/public/assets/_B4FWkW6c.js.br +0 -0
  28. package/dist/public/assets/{_DORBDQxD.js → _B4Pw3w21.js} +1 -1
  29. package/dist/public/assets/_B4Pw3w21.js.br +0 -0
  30. package/dist/public/assets/_B5LXqXQa.js +1 -0
  31. package/dist/public/assets/_B88eg0Vp.js +1 -0
  32. package/dist/public/assets/_BA8ljwe9.js +1 -0
  33. package/dist/public/assets/{_Bwj1cG6Z.js → _BAM_DI3M.js} +1 -1
  34. package/dist/public/assets/_BAM_DI3M.js.br +0 -0
  35. package/dist/public/assets/_BBlgqy8e.js +1 -0
  36. package/dist/public/assets/{_CCTE_j9L.js → _BCLavcTC.js} +1 -1
  37. package/dist/public/assets/_BCLavcTC.js.br +0 -0
  38. package/dist/public/assets/{_BUpeVCdC.js → _BCZlkGtf.js} +1 -1
  39. package/dist/public/assets/_BCZlkGtf.js.br +0 -0
  40. package/dist/public/assets/{_BC-QJfsn.js → _BDYdp8XC.js} +1 -1
  41. package/dist/public/assets/_BDYdp8XC.js.br +0 -0
  42. package/dist/public/assets/{_DA6CNMAS.js → _BE6OjzQ5.js} +1 -1
  43. package/dist/public/assets/_BE6OjzQ5.js.br +0 -0
  44. package/dist/public/assets/_BEdIKDs7.js +1 -0
  45. package/dist/public/assets/_BEk6jEQX.js +1 -0
  46. package/dist/public/assets/_BFjF8Q35.js +1 -0
  47. package/dist/public/assets/_BGz5DVCA.js +1 -0
  48. package/dist/public/assets/_BHZu9Pes.js +1 -0
  49. package/dist/public/assets/{_CrEFB_dj.js → _BIJdReS1.js} +1 -1
  50. package/dist/public/assets/_BIJdReS1.js.br +0 -0
  51. package/dist/public/assets/{_DO7dqRyj.js → _BIUdZ9U6.js} +1 -1
  52. package/dist/public/assets/_BIUdZ9U6.js.br +0 -0
  53. package/dist/public/assets/{_B9BZLh7B.js → _BK5s3-HD.js} +1 -1
  54. package/dist/public/assets/_BK5s3-HD.js.br +0 -0
  55. package/dist/public/assets/_BKLAcx09.js +1 -0
  56. package/dist/public/assets/_BKa1QXEz.js +1 -0
  57. package/dist/public/assets/{_JMrxKBGN.js → _BLB3aKBl.js} +1 -1
  58. package/dist/public/assets/_BLB3aKBl.js.br +0 -0
  59. package/dist/public/assets/_BM3dB223.js +1 -0
  60. package/dist/public/assets/_BMeMTjvD.js +1 -0
  61. package/dist/public/assets/_BNG7HlYy.js +1 -0
  62. package/dist/public/assets/{_CzBug9-x.js → _BNT9tMv7.js} +1 -1
  63. package/dist/public/assets/_BNT9tMv7.js.br +0 -0
  64. package/dist/public/assets/{_C3RYgw_5.js → _BN_tFhec.js} +1 -1
  65. package/dist/public/assets/_BN_tFhec.js.br +0 -0
  66. package/dist/public/assets/{_D-6O7MKA.js → _BS_9mjxy.js} +1 -1
  67. package/dist/public/assets/_BS_9mjxy.js.br +0 -0
  68. package/dist/public/assets/{_BVOoaIUz.js → _BV2iKZtJ.js} +1 -1
  69. package/dist/public/assets/_BV2iKZtJ.js.br +0 -0
  70. package/dist/public/assets/{_BDmhvLCs.js → _BZoloTjf.js} +1 -1
  71. package/dist/public/assets/_BZoloTjf.js.br +0 -0
  72. package/dist/public/assets/{_DWnX1Z3a.js → _B_KjPtDC.js} +1 -1
  73. package/dist/public/assets/_B_SW9x7P.js +1 -0
  74. package/dist/public/assets/_B_YQn900.js +1 -0
  75. package/dist/public/assets/{_B-ItC5A4.js → _BbfmMaqi.js} +1 -1
  76. package/dist/public/assets/_BbfmMaqi.js.br +0 -0
  77. package/dist/public/assets/{_CDXnpAfh.js → _Bcrj-WQi.js} +1 -1
  78. package/dist/public/assets/_Bcrj-WQi.js.br +0 -0
  79. package/dist/public/assets/{_Dz3s4MY0.js → _BdxYImPi.js} +1 -1
  80. package/dist/public/assets/_BdxYImPi.js.br +0 -0
  81. package/dist/public/assets/_BfzbdDL4.js +1 -0
  82. package/dist/public/assets/{_DGyB0J_Z.js → _Bh08kBGD.js} +1 -1
  83. package/dist/public/assets/_Bh08kBGD.js.br +0 -0
  84. package/dist/public/assets/{_DuuP0rKI.js → _BhZyloI6.js} +1 -1
  85. package/dist/public/assets/_BhZyloI6.js.br +0 -0
  86. package/dist/public/assets/{_0NYkT7Ka.js → _BiFhhlSo.js} +1 -1
  87. package/dist/public/assets/_BiFhhlSo.js.br +0 -0
  88. package/dist/public/assets/{_Cznq4Aee.js → _BkTFwlNW.js} +1 -1
  89. package/dist/public/assets/{_CAUoTaA1.js → _BoV0_nz4.js} +1 -1
  90. package/dist/public/assets/_BoV0_nz4.js.br +0 -0
  91. package/dist/public/assets/{_BEO7OuGG.js → _Bq1Q5Bp9.js} +2 -2
  92. package/dist/public/assets/_Bq1Q5Bp9.js.br +0 -0
  93. package/dist/public/assets/{_CGSo9tnY.js → _Bw1Dl8ii.js} +2 -2
  94. package/dist/public/assets/_Bw1Dl8ii.js.br +0 -0
  95. package/dist/public/assets/{_BjJMzhJj.js → _BwhwM8wK.js} +1 -1
  96. package/dist/public/assets/_BwhwM8wK.js.br +0 -0
  97. package/dist/public/assets/{_YC0QGp9j.js → _Bwoa__lM.js} +1 -1
  98. package/dist/public/assets/_Bwoa__lM.js.br +0 -0
  99. package/dist/public/assets/{_BTJ4QNYJ.js → _C0EKOzW2.js} +1 -1
  100. package/dist/public/assets/_C0EKOzW2.js.br +0 -0
  101. package/dist/public/assets/_C0EvxOwA.js +1 -0
  102. package/dist/public/assets/_C3nC8cyW.js +86 -0
  103. package/dist/public/assets/_C3nC8cyW.js.br +0 -0
  104. package/dist/public/assets/_C4GExord.js +1 -0
  105. package/dist/public/assets/_C4Q2EhDm.js +1 -0
  106. package/dist/public/assets/_C93ESwLa.js +1 -0
  107. package/dist/public/assets/_CA7BE3cv.js +1 -0
  108. package/dist/public/assets/{_CHuWNcjJ.js → _CABwcPvz.js} +1 -1
  109. package/dist/public/assets/_CABwcPvz.js.br +0 -0
  110. package/dist/public/assets/{_jFGgKTYj.js → _CBhwId7p.js} +1 -1
  111. package/dist/public/assets/_CBhwId7p.js.br +0 -0
  112. package/dist/public/assets/{_DyFziHLM.js → _CC60nm2c.js} +1 -1
  113. package/dist/public/assets/_CC60nm2c.js.br +0 -0
  114. package/dist/public/assets/{_Mt6ebGGE.js → _CDnwOQux.js} +10 -10
  115. package/dist/public/assets/_CDnwOQux.js.br +0 -0
  116. package/dist/public/assets/{_BzDLIQE5.js → _CGZrCZgN.js} +1 -1
  117. package/dist/public/assets/_CGZrCZgN.js.br +0 -0
  118. package/dist/public/assets/{_DKgv7Cyq.js → _CHxfvoX5.js} +1 -1
  119. package/dist/public/assets/_CHxfvoX5.js.br +0 -0
  120. package/dist/public/assets/_CJBxV9dM.js +1 -0
  121. package/dist/public/assets/_CJgx4Cuw.js +1 -0
  122. package/dist/public/assets/{_BC7rcYFE.js → _CN1LcGDw.js} +1 -1
  123. package/dist/public/assets/_CN1LcGDw.js.br +0 -0
  124. package/dist/public/assets/{_B3B2tRvZ.js → _CN84SJi7.js} +1 -1
  125. package/dist/public/assets/_CN84SJi7.js.br +0 -0
  126. package/dist/public/assets/_CNQQzFvk.js +1 -0
  127. package/dist/public/assets/{_BCgm7As-.js → _COHPK_wZ.js} +1 -1
  128. package/dist/public/assets/_COHPK_wZ.js.br +0 -0
  129. package/dist/public/assets/{_CcLifUnb.js → _CQrHh_LX.js} +1 -1
  130. package/dist/public/assets/_CQrHh_LX.js.br +0 -0
  131. package/dist/public/assets/{_kkbInDpy.js → _CSfIIlAJ.js} +1 -1
  132. package/dist/public/assets/_CSfIIlAJ.js.br +0 -0
  133. package/dist/public/assets/{_C2Tbc73e.js → _CToytClN.js} +1 -1
  134. package/dist/public/assets/_CToytClN.js.br +0 -0
  135. package/dist/public/assets/_CW4FJBjG.js +1 -0
  136. package/dist/public/assets/_CWeRaLF8.js +1 -0
  137. package/dist/public/assets/_CWeRaLF8.js.br +0 -0
  138. package/dist/public/assets/_CXYObpW6.js +1 -0
  139. package/dist/public/assets/{_6R8pHfHu.js → _CYpg9m-Y.js} +1 -1
  140. package/dist/public/assets/_CYpg9m-Y.js.br +0 -0
  141. package/dist/public/assets/_CZyoQhU2.js +1 -0
  142. package/dist/public/assets/_CbgRLM3d.js +1 -0
  143. package/dist/public/assets/_CfXXie60.js +1 -0
  144. package/dist/public/assets/_CgviVVN4.js +1 -0
  145. package/dist/public/assets/_ChTYYVE5.js +1 -0
  146. package/dist/public/assets/{_HlactPnQ.js → _Cj9wzF5m.js} +1 -1
  147. package/dist/public/assets/_Cj9wzF5m.js.br +0 -0
  148. package/dist/public/assets/{_C8l-PMHJ.js → _CkuR7n9-.js} +1 -1
  149. package/dist/public/assets/_CkuR7n9-.js.br +0 -0
  150. package/dist/public/assets/{_Cp-ZKt1Y.js → _Co7DYbGe.js} +1 -1
  151. package/dist/public/assets/_Co7DYbGe.js.br +0 -0
  152. package/dist/public/assets/_CoHvrBo9.js +1 -0
  153. package/dist/public/assets/_CojwoGTg.js +1 -0
  154. package/dist/public/assets/{_CI8Dmpt-.js → _Cp0oWv6s.js} +1 -1
  155. package/dist/public/assets/_Cp0oWv6s.js.br +0 -0
  156. package/dist/public/assets/_CrMG2Zi8.js +1 -0
  157. package/dist/public/assets/_CwLsydkC.js +1 -0
  158. package/dist/public/assets/_CwnsFHVB.js +1 -0
  159. package/dist/public/assets/_CyIsztnG.js +1 -0
  160. package/dist/public/assets/{_BM9h7XBb.js → _CyM31O-y.js} +1 -1
  161. package/dist/public/assets/_CyM31O-y.js.br +0 -0
  162. package/dist/public/assets/_D17V4n4L.js +12 -0
  163. package/dist/public/assets/_D17V4n4L.js.br +0 -0
  164. package/dist/public/assets/{_BNlAaEUI.js → _D1ESSCiR.js} +1 -1
  165. package/dist/public/assets/_D1ESSCiR.js.br +0 -0
  166. package/dist/public/assets/_D1e45DSK.js +1 -0
  167. package/dist/public/assets/{_BC1pxNUd.js → _D2w-ZcEg.js} +1 -1
  168. package/dist/public/assets/_D2w-ZcEg.js.br +0 -0
  169. package/dist/public/assets/_D33myH3L.js +1 -0
  170. package/dist/public/assets/_D367E1Mb.js +1 -0
  171. package/dist/public/assets/{_B9_Lal-7.js → _D3DciLfu.js} +1 -1
  172. package/dist/public/assets/_D3DciLfu.js.br +0 -0
  173. package/dist/public/assets/_D3orZZBM.js +1 -0
  174. package/dist/public/assets/_D48A92JR.js +1 -0
  175. package/dist/public/assets/{_JcvJ5ACW.js → _D5OB0tUq.js} +1 -1
  176. package/dist/public/assets/_D5OB0tUq.js.br +0 -0
  177. package/dist/public/assets/{_D-XHmBJj.js → _D8M6Gy-r.js} +1 -1
  178. package/dist/public/assets/_D8M6Gy-r.js.br +0 -0
  179. package/dist/public/assets/{_BVN5lLXw.js → _DA4MM0Iy.js} +1 -1
  180. package/dist/public/assets/_DA4MM0Iy.js.br +0 -0
  181. package/dist/public/assets/{_BaULj7kH.js → _DDjwDfu8.js} +1 -1
  182. package/dist/public/assets/_DDjwDfu8.js.br +0 -0
  183. package/dist/public/assets/{_DroY8_no.js → _DFfIOgg5.js} +1 -1
  184. package/dist/public/assets/_DFfIOgg5.js.br +0 -0
  185. package/dist/public/assets/_DGVMsQ3S.js +7 -0
  186. package/dist/public/assets/_DGVMsQ3S.js.br +0 -0
  187. package/dist/public/assets/_DJQtBoc2.js +1 -0
  188. package/dist/public/assets/{_sTT2iThd.js → _DJSAOfAZ.js} +1 -1
  189. package/dist/public/assets/_DJSAOfAZ.js.br +0 -0
  190. package/dist/public/assets/_DJfHxm0Y.js +1 -0
  191. package/dist/public/assets/_DPhQO2sM.js +1 -0
  192. package/dist/public/assets/{_REcALhmt.js → _DQ2mXOKV.js} +1 -1
  193. package/dist/public/assets/_DQ2mXOKV.js.br +0 -0
  194. package/dist/public/assets/_DQ2m_V3a.js +1 -0
  195. package/dist/public/assets/{_BOmZO9bQ.js → _DRXSIVoz.js} +1 -1
  196. package/dist/public/assets/_DRXSIVoz.js.br +0 -0
  197. package/dist/public/assets/{_B-Nak9W-.js → _DRgXNDxv.js} +1 -1
  198. package/dist/public/assets/_DRgXNDxv.js.br +0 -0
  199. package/dist/public/assets/{_TZpNJCj6.js → _DRmwSJU8.js} +1 -1
  200. package/dist/public/assets/_DRmwSJU8.js.br +0 -0
  201. package/dist/public/assets/{_B7THbxch.js → _DSsoNnAR.js} +1 -1
  202. package/dist/public/assets/_DSsoNnAR.js.br +0 -0
  203. package/dist/public/assets/{_Ck0GxYNQ.js → _DUB7vmfa.js} +1 -1
  204. package/dist/public/assets/_DUB7vmfa.js.br +0 -0
  205. package/dist/public/assets/_DVVHMWfv.js +1 -0
  206. package/dist/public/assets/{_Dml0472r.js → _DVnoTRjk.js} +1 -1
  207. package/dist/public/assets/_DVnoTRjk.js.br +0 -0
  208. package/dist/public/assets/{_H1xilHgC.js → _D_2YPXgc.js} +1 -1
  209. package/dist/public/assets/_D_2YPXgc.js.br +0 -0
  210. package/dist/public/assets/_D_5ZOE82.js +1 -0
  211. package/dist/public/assets/_D_VYe-9m.js +1 -0
  212. package/dist/public/assets/_D_VYe-9m.js.br +0 -0
  213. package/dist/public/assets/{_CdDgM-x6.js → _DcTLJKg4.js} +1 -1
  214. package/dist/public/assets/_DcTLJKg4.js.br +0 -0
  215. package/dist/public/assets/{_BvDvgf2D.js → _DciUW68u.js} +1 -1
  216. package/dist/public/assets/_DciUW68u.js.br +0 -0
  217. package/dist/public/assets/_DeoVckIp.js +1 -0
  218. package/dist/public/assets/_Dfu4rkx7.js +1 -0
  219. package/dist/public/assets/{_BmAd0-4z.js → _Dg31RZCE.js} +1 -1
  220. package/dist/public/assets/_DhakvVIs.js +1 -0
  221. package/dist/public/assets/{_DWCS2CFQ.js → _DljYlF-8.js} +1 -1
  222. package/dist/public/assets/_DljYlF-8.js.br +0 -0
  223. package/dist/public/assets/_DnDXrche.js +1 -0
  224. package/dist/public/assets/_DopDesYU.js +1 -0
  225. package/dist/public/assets/{_CbzlAKJK.js → _DrDeie20.js} +1 -1
  226. package/dist/public/assets/_DrDeie20.js.br +0 -0
  227. package/dist/public/assets/_DsaeILQf.js +1 -0
  228. package/dist/public/assets/_DtPiaMYs.js +1 -0
  229. package/dist/public/assets/{__favRwtg.js → _DtnhWr13.js} +1 -1
  230. package/dist/public/assets/_DtnhWr13.js.br +0 -0
  231. package/dist/public/assets/_Duzu1PMH.js +2 -0
  232. package/dist/public/assets/_Duzu1PMH.js.br +0 -0
  233. package/dist/public/assets/{_JSiyuxRJ.js → _DwyGf7Gx.js} +1 -1
  234. package/dist/public/assets/_DwyGf7Gx.js.br +0 -0
  235. package/dist/public/assets/{_VgS7WPcA.js → _DxOMXrRO.js} +1 -1
  236. package/dist/public/assets/_DxOMXrRO.js.br +0 -0
  237. package/dist/public/assets/{_BVIQdL1e.js → _DyIkjTRk.js} +1 -1
  238. package/dist/public/assets/_DyIkjTRk.js.br +0 -0
  239. package/dist/public/assets/{_YATrYiFD.js → _ExbET28R.js} +1 -1
  240. package/dist/public/assets/_ExbET28R.js.br +0 -0
  241. package/dist/public/assets/_FNxT5NPG.js +1 -0
  242. package/dist/public/assets/_Ht88mW2V.js +1 -0
  243. package/dist/public/assets/{_vfD02BWU.js → _N1abJgps.js} +1 -1
  244. package/dist/public/assets/_N1abJgps.js.br +0 -0
  245. package/dist/public/assets/_NYke0RXG.js +1 -0
  246. package/dist/public/assets/_OPhGPyGs.js +1 -0
  247. package/dist/public/assets/_PHljy6ET.js +1 -0
  248. package/dist/public/assets/_PX8hrJdo.js +1 -0
  249. package/dist/public/assets/_S1demnnu.js +1 -0
  250. package/dist/public/assets/_Tmv5uToQ.js +1 -0
  251. package/dist/public/assets/_UtGpQ2_r.js +1 -0
  252. package/dist/public/assets/_Vl5MvQzP.js +1 -0
  253. package/dist/public/assets/{_D_TuAhnN.js → _WCBLRMz2.js} +1 -1
  254. package/dist/public/assets/_WCBLRMz2.js.br +0 -0
  255. package/dist/public/assets/_WKvnll-3.js +1 -0
  256. package/dist/public/assets/{_DJNoam7G.js → _X5WShyfn.js} +1 -1
  257. package/dist/public/assets/_X5WShyfn.js.br +0 -0
  258. package/dist/public/assets/{_L2f5JNlj.js → __DTQHzic.js} +1 -1
  259. package/dist/public/assets/__DTQHzic.js.br +0 -0
  260. package/dist/public/assets/_bnpXob7e.js +1 -0
  261. package/dist/public/assets/{_BJHD6sFy.js → _brQlBqu_.js} +1 -1
  262. package/dist/public/assets/_brQlBqu_.js.br +0 -0
  263. package/dist/public/assets/{_Bo5sqml-.js → _dGfL_QZV.js} +1 -1
  264. package/dist/public/assets/_ealUslfo.js +1 -0
  265. package/dist/public/assets/_jb5T9YfT.js +1 -0
  266. package/dist/public/assets/_kRWDFibl.js +1 -0
  267. package/dist/public/assets/_kRWDFibl.js.br +0 -0
  268. package/dist/public/assets/{_DuaSYpQG.js → _keXpnhe8.js} +1 -1
  269. package/dist/public/assets/_keXpnhe8.js.br +0 -0
  270. package/dist/public/assets/{_COjB6Mds.js → _kuyd26Pt.js} +1 -1
  271. package/dist/public/assets/_kuyd26Pt.js.br +0 -0
  272. package/dist/public/assets/{_DU8DeX60.js → _l5-Jk_5N.js} +1 -1
  273. package/dist/public/assets/_l5-Jk_5N.js.br +0 -0
  274. package/dist/public/assets/{_CcbgX86v.js → _m7SkiXhN.js} +1 -1
  275. package/dist/public/assets/_m7SkiXhN.js.br +0 -0
  276. package/dist/public/assets/{_CWmrlUIL.js → _t-tt2JrE.js} +1 -1
  277. package/dist/public/assets/_t-tt2JrE.js.br +0 -0
  278. package/dist/public/assets/_v1wPCcsu.js +1 -0
  279. package/dist/public/assets/{_C0zpPwSp.js → _xi-HvQW_.js} +1 -1
  280. package/dist/public/assets/_xi-HvQW_.js.br +0 -0
  281. package/dist/public/assets/{_BEg-5EkS.js → _zCvDbozL.js} +1 -1
  282. package/dist/public/assets/_zCvDbozL.js.br +0 -0
  283. package/dist/public/assets/_zKqS326c.js +1 -0
  284. package/dist/public/assets/_zZ0GBANQ.js +1 -0
  285. package/dist/public/assets/files-view-BfBPOGQU.js +2 -0
  286. package/dist/public/assets/manage-workspace-DlVeSck8.js +2 -0
  287. package/dist/public/assets/new-BQed31cs.js +1 -0
  288. package/dist/public/assets/new-workspace-CddwCyow.js +2 -0
  289. package/dist/public/assets/review-view-BW97az9E.js +2 -0
  290. package/dist/public/assets/settings-BQed31cs.js +1 -0
  291. package/dist/public/assets/settings-page-v_dTJ0BH.js +2 -0
  292. package/dist/public/assets/styles-CAhMc10z.css +1 -0
  293. package/dist/public/assets/styles-CAhMc10z.css.br +0 -0
  294. package/dist/public/assets/w-BQed31cs.js +1 -0
  295. package/dist/public/assets/w._-BQed31cs.js +1 -0
  296. package/dist/public/assets/w._-CNxJfUG-.js +1 -0
  297. package/dist/public/assets/w._-CjnUM0Eu.js +1 -0
  298. package/package.json +1 -1
  299. package/dist/_B25P__C4.js +0 -2
  300. package/dist/_wbrwjNyW.js +0 -2
  301. package/dist/public/assets/_0NYkT7Ka.js.br +0 -0
  302. package/dist/public/assets/_18ckOF7L.js +0 -1
  303. package/dist/public/assets/_25qbKqTG.js +0 -1
  304. package/dist/public/assets/_6R8pHfHu.js.br +0 -0
  305. package/dist/public/assets/_8cC5eK8l.js +0 -1
  306. package/dist/public/assets/_8eN6y624.js +0 -1
  307. package/dist/public/assets/_8eN6y624.js.br +0 -0
  308. package/dist/public/assets/_9-vCfD1H.js +0 -1
  309. package/dist/public/assets/_9PSE1hBd.js +0 -1
  310. package/dist/public/assets/_B-ItC5A4.js.br +0 -0
  311. package/dist/public/assets/_B-IuONfT.js +0 -7
  312. package/dist/public/assets/_B-IuONfT.js.br +0 -0
  313. package/dist/public/assets/_B-Nak9W-.js.br +0 -0
  314. package/dist/public/assets/_B0vuJGqQ.js +0 -1
  315. package/dist/public/assets/_B24stjuF.js +0 -86
  316. package/dist/public/assets/_B24stjuF.js.br +0 -0
  317. package/dist/public/assets/_B2HaD9d5.js +0 -1
  318. package/dist/public/assets/_B3B2tRvZ.js.br +0 -0
  319. package/dist/public/assets/_B4oiI3_4.js +0 -1
  320. package/dist/public/assets/_B5CpgKE4.js +0 -1
  321. package/dist/public/assets/_B7Rpwq9e.js +0 -1
  322. package/dist/public/assets/_B7THbxch.js.br +0 -0
  323. package/dist/public/assets/_B9BZLh7B.js.br +0 -0
  324. package/dist/public/assets/_B9_Lal-7.js.br +0 -0
  325. package/dist/public/assets/_BC-QJfsn.js.br +0 -0
  326. package/dist/public/assets/_BC1pxNUd.js.br +0 -0
  327. package/dist/public/assets/_BC7rcYFE.js.br +0 -0
  328. package/dist/public/assets/_BCgm7As-.js.br +0 -0
  329. package/dist/public/assets/_BDmhvLCs.js.br +0 -0
  330. package/dist/public/assets/_BEO7OuGG.js.br +0 -0
  331. package/dist/public/assets/_BEg-5EkS.js.br +0 -0
  332. package/dist/public/assets/_BFTxeP-D.js +0 -1
  333. package/dist/public/assets/_BGCoTA5R.js +0 -1
  334. package/dist/public/assets/_BJHD6sFy.js.br +0 -0
  335. package/dist/public/assets/_BJeQROi4.js +0 -1
  336. package/dist/public/assets/_BJeQROi4.js.br +0 -0
  337. package/dist/public/assets/_BKDJIaLf.js +0 -1
  338. package/dist/public/assets/_BM9h7XBb.js.br +0 -0
  339. package/dist/public/assets/_BNlAaEUI.js.br +0 -0
  340. package/dist/public/assets/_BOmZO9bQ.js.br +0 -0
  341. package/dist/public/assets/_BQvedQNA.js.br +0 -0
  342. package/dist/public/assets/_BTJ4QNYJ.js.br +0 -0
  343. package/dist/public/assets/_BUnVFLfD.js +0 -1
  344. package/dist/public/assets/_BUpeVCdC.js.br +0 -0
  345. package/dist/public/assets/_BVIQdL1e.js.br +0 -0
  346. package/dist/public/assets/_BVN5lLXw.js.br +0 -0
  347. package/dist/public/assets/_BVOoaIUz.js.br +0 -0
  348. package/dist/public/assets/_BYd6ll6G.js +0 -1
  349. package/dist/public/assets/_BZnPwq2i.js +0 -1
  350. package/dist/public/assets/_BaULj7kH.js.br +0 -0
  351. package/dist/public/assets/_BbdvSQaN.js +0 -1
  352. package/dist/public/assets/_BjJMzhJj.js.br +0 -0
  353. package/dist/public/assets/_BkFty1Oi.js +0 -1
  354. package/dist/public/assets/_BryOeCV4.js +0 -1
  355. package/dist/public/assets/_BtAYOnhU.js +0 -1
  356. package/dist/public/assets/_BvDvgf2D.js.br +0 -0
  357. package/dist/public/assets/_Bwj1cG6Z.js.br +0 -0
  358. package/dist/public/assets/_Bwl5RU7m.js +0 -1
  359. package/dist/public/assets/_Bwl5RU7m.js.br +0 -0
  360. package/dist/public/assets/_Bx7eXUeM.js +0 -1
  361. package/dist/public/assets/_Bxw4J8BV.js +0 -1
  362. package/dist/public/assets/_BzDLIQE5.js.br +0 -0
  363. package/dist/public/assets/_BzvCB8DB.js +0 -1
  364. package/dist/public/assets/_C-9WWLQ3.js +0 -1
  365. package/dist/public/assets/_C-_bdY5V.js +0 -1
  366. package/dist/public/assets/_C0zpPwSp.js.br +0 -0
  367. package/dist/public/assets/_C2Tbc73e.js.br +0 -0
  368. package/dist/public/assets/_C3RYgw_5.js.br +0 -0
  369. package/dist/public/assets/_C7P0cxfL.js +0 -1
  370. package/dist/public/assets/_C81AvAMk.js +0 -1
  371. package/dist/public/assets/_C8l-PMHJ.js.br +0 -0
  372. package/dist/public/assets/_CAUoTaA1.js.br +0 -0
  373. package/dist/public/assets/_CCTE_j9L.js.br +0 -0
  374. package/dist/public/assets/_CDXnpAfh.js.br +0 -0
  375. package/dist/public/assets/_CEWoPra5.js +0 -1
  376. package/dist/public/assets/_CGSo9tnY.js.br +0 -0
  377. package/dist/public/assets/_CGsbbcpE.js +0 -1
  378. package/dist/public/assets/_CHuWNcjJ.js.br +0 -0
  379. package/dist/public/assets/_CI0KXyAu.js +0 -1
  380. package/dist/public/assets/_CI8Dmpt-.js.br +0 -0
  381. package/dist/public/assets/_CKmnCHzt.js +0 -1
  382. package/dist/public/assets/_CNY02rQP.js +0 -1
  383. package/dist/public/assets/_COjB6Mds.js.br +0 -0
  384. package/dist/public/assets/_CPGWIVjG.js +0 -1
  385. package/dist/public/assets/_CQ0SDG17.js +0 -1
  386. package/dist/public/assets/_CWmrlUIL.js.br +0 -0
  387. package/dist/public/assets/_CXLLGxAE.js +0 -12
  388. package/dist/public/assets/_CXLLGxAE.js.br +0 -0
  389. package/dist/public/assets/_CXciWQH3.js +0 -1
  390. package/dist/public/assets/_CXjFOElm.js +0 -1
  391. package/dist/public/assets/_CbzlAKJK.js.br +0 -0
  392. package/dist/public/assets/_CcLifUnb.js.br +0 -0
  393. package/dist/public/assets/_CcbgX86v.js.br +0 -0
  394. package/dist/public/assets/_CdDgM-x6.js.br +0 -0
  395. package/dist/public/assets/_Ce53vsUM.js +0 -1
  396. package/dist/public/assets/_CgdBa1Kb.js +0 -1
  397. package/dist/public/assets/_ChxOfm1L.js +0 -1
  398. package/dist/public/assets/_Ck0GxYNQ.js.br +0 -0
  399. package/dist/public/assets/_CmIuIy4h.js +0 -1
  400. package/dist/public/assets/_Cp-ZKt1Y.js.br +0 -0
  401. package/dist/public/assets/_CrEFB_dj.js.br +0 -0
  402. package/dist/public/assets/_CwaUSclh.js +0 -1
  403. package/dist/public/assets/_Cy9eBufF.js +0 -1
  404. package/dist/public/assets/_CynmXPn2.js +0 -1
  405. package/dist/public/assets/_CzBug9-x.js.br +0 -0
  406. package/dist/public/assets/_D-6O7MKA.js.br +0 -0
  407. package/dist/public/assets/_D-JhJZ2C.js +0 -1
  408. package/dist/public/assets/_D-XHmBJj.js.br +0 -0
  409. package/dist/public/assets/_D-neGx47.js +0 -1
  410. package/dist/public/assets/_D5VJGdAr.js +0 -1
  411. package/dist/public/assets/_D6u72i8c.js +0 -1
  412. package/dist/public/assets/_D8tbv6WM.js +0 -1
  413. package/dist/public/assets/_DA6CNMAS.js.br +0 -0
  414. package/dist/public/assets/_DDD7aRxr.js +0 -1
  415. package/dist/public/assets/_DFCbdJTU.js +0 -1
  416. package/dist/public/assets/_DGyB0J_Z.js.br +0 -0
  417. package/dist/public/assets/_DJNoam7G.js.br +0 -0
  418. package/dist/public/assets/_DKgv7Cyq.js.br +0 -0
  419. package/dist/public/assets/_DM2ZsY5Z.js.br +0 -0
  420. package/dist/public/assets/_DO7dqRyj.js.br +0 -0
  421. package/dist/public/assets/_DORBDQxD.js.br +0 -0
  422. package/dist/public/assets/_DOsfhfso.js +0 -1
  423. package/dist/public/assets/_DRC6uiX0.js +0 -1
  424. package/dist/public/assets/_DSWmTo1L.js +0 -1
  425. package/dist/public/assets/_DU8DeX60.js.br +0 -0
  426. package/dist/public/assets/_DUKZkilh.js +0 -1
  427. package/dist/public/assets/_DWCS2CFQ.js.br +0 -0
  428. package/dist/public/assets/_DX71QHMR.js +0 -1
  429. package/dist/public/assets/_DZ0rqa0h.js.br +0 -0
  430. package/dist/public/assets/_D_TuAhnN.js.br +0 -0
  431. package/dist/public/assets/_D_rLfkXR.js +0 -1
  432. package/dist/public/assets/_DeBbHTQf.js +0 -1
  433. package/dist/public/assets/_Dkm85KJF.js +0 -1
  434. package/dist/public/assets/_Dml0472r.js.br +0 -0
  435. package/dist/public/assets/_DroY8_no.js.br +0 -0
  436. package/dist/public/assets/_DtYahvpQ.js +0 -1
  437. package/dist/public/assets/_DuaSYpQG.js.br +0 -0
  438. package/dist/public/assets/_DuuP0rKI.js.br +0 -0
  439. package/dist/public/assets/_DyFziHLM.js.br +0 -0
  440. package/dist/public/assets/_Dz3s4MY0.js.br +0 -0
  441. package/dist/public/assets/_DzZaUh6D.js +0 -1
  442. package/dist/public/assets/_DzhUXE8_.js +0 -1
  443. package/dist/public/assets/_GWc0eYhN.js +0 -1
  444. package/dist/public/assets/_H1xilHgC.js.br +0 -0
  445. package/dist/public/assets/_HNyiv6zs.js.br +0 -0
  446. package/dist/public/assets/_HlactPnQ.js.br +0 -0
  447. package/dist/public/assets/_JMrxKBGN.js.br +0 -0
  448. package/dist/public/assets/_JSiyuxRJ.js.br +0 -0
  449. package/dist/public/assets/_JcvJ5ACW.js.br +0 -0
  450. package/dist/public/assets/_L2f5JNlj.js.br +0 -0
  451. package/dist/public/assets/_LrU9RmZE.js +0 -1
  452. package/dist/public/assets/_Mt6ebGGE.js.br +0 -0
  453. package/dist/public/assets/_Owc9jhpW.js +0 -2
  454. package/dist/public/assets/_Owc9jhpW.js.br +0 -0
  455. package/dist/public/assets/_PevhFQ5V.js +0 -1
  456. package/dist/public/assets/_R1tJA-Qg.js +0 -1
  457. package/dist/public/assets/_REcALhmt.js.br +0 -0
  458. package/dist/public/assets/_TZpNJCj6.js.br +0 -0
  459. package/dist/public/assets/_VDsjaeWW.js +0 -1
  460. package/dist/public/assets/_VgS7WPcA.js.br +0 -0
  461. package/dist/public/assets/_WekB6aHl.js +0 -1
  462. package/dist/public/assets/_X4dvLi1w.js +0 -1
  463. package/dist/public/assets/_XXcCKG6W.js +0 -1
  464. package/dist/public/assets/_Y4miPos6.js +0 -1
  465. package/dist/public/assets/_YATrYiFD.js.br +0 -0
  466. package/dist/public/assets/_YC0QGp9j.js.br +0 -0
  467. package/dist/public/assets/_YG1qePV2.js +0 -1
  468. package/dist/public/assets/_Yiwgrm_C.js +0 -1
  469. package/dist/public/assets/__favRwtg.js.br +0 -0
  470. package/dist/public/assets/_b0whjSZe.js +0 -1
  471. package/dist/public/assets/_cw5fHxTz.js +0 -1
  472. package/dist/public/assets/_gSyGU-mq.js +0 -1
  473. package/dist/public/assets/_j5nRBBVa.js +0 -1
  474. package/dist/public/assets/_jFGgKTYj.js.br +0 -0
  475. package/dist/public/assets/_kkbInDpy.js.br +0 -0
  476. package/dist/public/assets/_mrvWutef.js +0 -1
  477. package/dist/public/assets/_nCxsopgT.js +0 -1
  478. package/dist/public/assets/_pwbytP5z.js +0 -1
  479. package/dist/public/assets/_sTT2iThd.js.br +0 -0
  480. package/dist/public/assets/_tGE7SNww.js.br +0 -0
  481. package/dist/public/assets/_veyGCfhb.js +0 -1
  482. package/dist/public/assets/_vfD02BWU.js.br +0 -0
  483. package/dist/public/assets/files-view-_b8IktQV.js +0 -2
  484. package/dist/public/assets/manage-workspace-Bu8_bkKy.js +0 -2
  485. package/dist/public/assets/new-CGbC3Rki.js +0 -1
  486. package/dist/public/assets/new-workspace-BPq4RG6p.js +0 -2
  487. package/dist/public/assets/review-view-Dwph1tIy.js +0 -2
  488. package/dist/public/assets/settings-CGbC3Rki.js +0 -1
  489. package/dist/public/assets/settings-page-DfjJBEV4.js +0 -2
  490. package/dist/public/assets/styles-DmUe5O9c.css +0 -1
  491. package/dist/public/assets/styles-DmUe5O9c.css.br +0 -0
  492. package/dist/public/assets/w-CGbC3Rki.js +0 -1
  493. package/dist/public/assets/w._-BdlGa_yr.js +0 -1
  494. package/dist/public/assets/w._-CGbC3Rki.js +0 -1
  495. package/dist/public/assets/w._-Cq1MaRMF.js +0 -1
@@ -839,6 +839,13 @@ var STEPS = [
839
839
  ALTER TABLE sessions ADD COLUMN typed_at INTEGER;
840
840
  `);
841
841
  }
842
+ },
843
+ {
844
+ version: 16,
845
+ name: "switching sessions",
846
+ up(db) {
847
+ db.exec("ALTER TABLE sessions ADD COLUMN switch_to TEXT;");
848
+ }
842
849
  }
843
850
  ];
844
851
  var LATEST = STEPS.at(-1).version;
@@ -9667,7 +9674,7 @@ function publishChange(sessionId) {
9667
9674
  const row = get("SELECT workspace_id FROM sessions WHERE id = ?", sessionId);
9668
9675
  if (row?.workspace_id) {
9669
9676
  const workspaceId = row.workspace_id;
9670
- import("./_wbrwjNyW.js").then((m) => m.notifySessionsChanged(workspaceId));
9677
+ import("./_BA1HQgf_.js").then((m) => m.notifySessionsChanged(workspaceId));
9671
9678
  return;
9672
9679
  }
9673
9680
  publish("sessions.changed");
@@ -11903,7 +11910,8 @@ onPhaseChange(() => {
11903
11910
  });
11904
11911
  /** Whether files under `dir` may have changed since `since` (ms): an agent
11905
11912
  * of its workspace working now, or anything noted there since. A directory
11906
- * outside every workspace may have, always. */
11913
+ * outside every workspace may have, always. Per workspace, not per folder,
11914
+ * by choice: an agent writes wherever it `cd`s, which nothing here sees. */
11907
11915
  function activeSince(dir, since) {
11908
11916
  const id = workspaceAt(dir);
11909
11917
  if (!id) return true;
@@ -11930,7 +11938,14 @@ function workspaceAt(dir) {
11930
11938
  * each its own process. Kept by size, the least recently used going
11931
11939
  * first; a failure is never kept (the object may simply not be here
11932
11940
  * yet). */
11933
- var MAX_BYTES = 134217728;
11941
+ var MiB = 1048576;
11942
+ /** A thirty-second of the machine's memory, between 128 MiB and 1 GiB. A
11943
+ * load asks for every section's files in turn, so one workspace whose
11944
+ * patches outgrow the cap pushed each out before the next load came back
11945
+ * for it: a fixed 128 MiB held none of a workspace of ~240 MiB, and every
11946
+ * load took the whole diff again (ten seconds). The text is mostly what
11947
+ * the kept diffs hold anyway. */
11948
+ var MAX_BYTES = Math.min(1024 * MiB, Math.max(128 * MiB, Math.floor(os.totalmem() / 32)));
11934
11949
  var kept = /* @__PURE__ */ new Map();
11935
11950
  var total = 0;
11936
11951
  var SHA = /^[0-9a-f]{40,64}$/;
@@ -12060,6 +12075,46 @@ var branchPrs = swr(TTL_MS, async (key, refresh) => {
12060
12075
  async function workspacePrs(fullName, branch, foreign, refresh = false, since) {
12061
12076
  return prsForBranchPrefix(await branchPrs(branchKey(fullName, branch), refresh).catch(() => []), branch, foreign).filter((pr) => !since || pr.state === "OPEN" || !pr.updatedAt || pr.updatedAt >= since);
12062
12077
  }
12078
+ /** Each branch's own PRs, however long ago they finished, by
12079
+ * `fullName#branch`: what `prsForHeads` last found, kept an hour. */
12080
+ var HEADS_TTL_MS = 36e5;
12081
+ var headsFound = /* @__PURE__ */ new Map();
12082
+ /** GitHub refuses a search query past 256 characters; the rest of the
12083
+ * query (`is:pr is:closed sort:updated-desc repo:…`) takes its share. */
12084
+ var HEAD_TERMS_MAX = 160;
12085
+ /** These branches' PRs in one workspace repo, open or finished however
12086
+ * long ago. The workspace's own search keeps only its latest finished PRs
12087
+ * (`CLOSED_FIRST`), so a topic whose squash-merged PR had aged out of it
12088
+ * read as unmerged work for good. Asked for by name, only for the branches
12089
+ * `work topic` cannot otherwise account for: as few searches as the query
12090
+ * length allows (one per branch, run side by side, took GitHub 19 s for
12091
+ * three), and each branch's answer kept an hour. None of it rides the
12092
+ * status tick. */
12093
+ async function prsForHeads(fullName, heads) {
12094
+ const now = Date.now();
12095
+ const stale = heads.filter((h) => {
12096
+ const seen = headsFound.get(branchKey(fullName, h));
12097
+ return !seen || now - seen.at > HEADS_TTL_MS;
12098
+ });
12099
+ if (stale.length) try {
12100
+ const { host, name } = splitRepo(fullName);
12101
+ const upstream = await repoParent(fullName);
12102
+ const repos = upstream ? [name, splitRepo(upstream).name] : [name];
12103
+ const found = new Map(stale.map((h) => [h, []]));
12104
+ const batches = [[]];
12105
+ for (const h of stale) {
12106
+ const batch = batches[batches.length - 1];
12107
+ if (batch.length && [...batch, h].join(" head:").length > HEAD_TERMS_MAX) batches.push([h]);
12108
+ else batch.push(h);
12109
+ }
12110
+ for (const batch of batches) for (const n of await searchPrs(host, repos, batch)) if (ownsNode(n, fullName, upstream)) found.get(n.headRefName)?.push(n);
12111
+ for (const [h, prs] of found) headsFound.set(branchKey(fullName, h), {
12112
+ at: now,
12113
+ prs
12114
+ });
12115
+ } catch {}
12116
+ return heads.flatMap((h) => headsFound.get(branchKey(fullName, h))?.prs ?? []);
12117
+ }
12063
12118
  /** Refresh many repos' PRs with one GraphQL request (vs one `gh pr list`
12064
12119
  * process per repo) — called from the status watcher for active
12065
12120
  * workspaces so open/merge/close flips surface in ~watch-tick time
@@ -12241,7 +12296,8 @@ function sectionFor(list, id) {
12241
12296
  * agent's `git fetch`, in the shared cache, and a commit on a lane in its
12242
12297
  * own worktree. PR heads are the status watcher's. The diff route answers
12243
12298
  * an unchanged stamp with the diff it last took (`workspaceDiff`). */
12244
- async function diffStamp(ws) {
12299
+ async function diffStamp(ws, only) {
12300
+ if (only) return sectionStamp(ws, only);
12245
12301
  const parts = await Promise.all(ws.repos.map(async (repo) => {
12246
12302
  const dir = path.join(ws.path, repo.worktree);
12247
12303
  let out;
@@ -12267,13 +12323,36 @@ async function diffStamp(ws) {
12267
12323
  } catch {
12268
12324
  return `${repo.worktree}\0-`;
12269
12325
  }
12270
- const stats = await Promise.all(changedPaths(out).map((p) => fs$1.lstat(path.join(dir, p)).then((st) => `${st.size}:${st.mtimeMs}`, () => "-")));
12271
- return `${repo.worktree}\0${head}\0${out}\0${refs}\0${stats.join(",")}`;
12326
+ const stats = await statsOf(dir, out);
12327
+ return `${repo.worktree}\0${head}\0${out}\0${refs}\0${stats}`;
12272
12328
  }));
12273
12329
  const hash = createHash("sha1");
12274
12330
  for (const part of parts) hash.update(part).update("\n");
12275
12331
  return hash.digest("base64url");
12276
12332
  }
12333
+ /** One section's stamp (`SectionScope`): its own refs, and the status of
12334
+ * the checkout or worktree its edits are read from. A review showing one
12335
+ * topic stamped the whole workspace, so another topic's agent at work
12336
+ * held it back behind a Refresh for a change it would not show. */
12337
+ async function sectionStamp(ws, only) {
12338
+ const dir = path.join(ws.path, only.worktree);
12339
+ const [refs, head, out] = await Promise.all([
12340
+ git([
12341
+ "for-each-ref",
12342
+ "--format=%(refname) %(objectname)",
12343
+ ...only.refs
12344
+ ], dir).catch(() => ""),
12345
+ headOid(dir).then((h) => only.checkout ? `${h.branch} ${h.oid}` : h.branch, () => ""),
12346
+ only.edits ? statusOf(only.edits).catch(() => "") : ""
12347
+ ]);
12348
+ const stats = only.edits ? await statsOf(only.edits, out) : "";
12349
+ return createHash("sha1").update(`${only.id}\0${head}\0${refs}\0${out}\0${stats}`).digest("base64url");
12350
+ }
12351
+ /** The size and mtime of each path `git status` listed: a file already
12352
+ * modified stays "M" however often it is edited again. */
12353
+ async function statsOf(dir, status) {
12354
+ return (await Promise.all(changedPaths(status).map((p) => fs$1.lstat(path.join(dir, p)).then((st) => `${st.size}:${st.mtimeMs}`, () => "-")))).join(",");
12355
+ }
12277
12356
  /** Each checkout's last `git status`, and when it was begun. The status
12278
12357
  * is most of a stamp's cost (a large repo's untracked files walked, every
12279
12358
  * few seconds while a review is on screen), and it can only have moved if
@@ -13269,9 +13348,44 @@ async function treeContainedInUncached(dir, base, head, baseTree) {
13269
13348
  * the new stamp over the old diff and never reloads it. */
13270
13349
  var diffInFlight = /* @__PURE__ */ new Map();
13271
13350
  function workspaceDiff(ws, stamp, opts = {}) {
13272
- const { sinceReview, ...listed } = opts;
13351
+ const { sinceReview, only, ...listed } = opts;
13273
13352
  const since = !!sinceReview && !opts.rev && opts.scope !== "dirty";
13274
- return listedDiff(ws, stamp, listed).then((sections) => withReview(ws, sections, since));
13353
+ return listedDiff(ws, stamp, {
13354
+ ...listed,
13355
+ only: only?.id
13356
+ }).then((sections) => withReview(ws, sections, since));
13357
+ }
13358
+ /** The section `pick` names, as one to show alone (`SectionScope`); null
13359
+ * where it names none the strip would list (client branch-state
13360
+ * `inStrip`), which the review then shows with every other. Read from the
13361
+ * one repo's section listing (`repoSectionList`, kept by its refs), so a
13362
+ * stamp asked every few seconds costs no more than its own repo's. */
13363
+ async function sectionScope(ws, pick) {
13364
+ const worktree = pick.split(/[@#]/)[0];
13365
+ const repo = ws.repos.find((r) => r.worktree === worktree);
13366
+ if (!repo) return null;
13367
+ const { dir, list } = await repoSectionList(ws, repo, otherWorkspaceBranches(ws.id));
13368
+ const id = sectionFor(list, pick);
13369
+ const s = id ? list.find((x) => x.id === id) : void 0;
13370
+ if (!id || !s) return null;
13371
+ const head = s.pr?.headRefName ?? s.headRef ?? s.branch;
13372
+ const checkout = head === s.branch;
13373
+ const edits = checkout ? dir : (await laneWorktrees(dir)).get(head);
13374
+ if (!s.pr && s.contained && !(edits && await editsOf(edits))) return null;
13375
+ const own = [head, s.parent].filter((b) => !!b);
13376
+ const bases = [
13377
+ s.pr?.baseRefName,
13378
+ repo.base_branch,
13379
+ repo.default_branch
13380
+ ];
13381
+ const refs = [...own.flatMap((b) => [`refs/heads/${b}`, `refs/remotes/origin/${b}`]), ...bases.flatMap((b) => b ? [`refs/remotes/origin/${b}`] : [])];
13382
+ return {
13383
+ id,
13384
+ worktree,
13385
+ refs: [...new Set(refs)],
13386
+ checkout,
13387
+ ...edits && { edits }
13388
+ };
13275
13389
  }
13276
13390
  function listedDiff(ws, stamp, opts) {
13277
13391
  const { refresh, ...asked } = opts;
@@ -13289,7 +13403,7 @@ function listedDiff(ws, stamp, opts) {
13289
13403
  if (running) return running;
13290
13404
  const last = diffKept.get(which);
13291
13405
  if (last && !refresh && last.stamp === stamp && Date.now() - last.at < DIFF_KEEP_MS) return last.sections;
13292
- const run = computeWorkspaceDiff(ws, opts).finally(() => {
13406
+ const run = (opts.only ? scopedDiff(ws, opts, opts.only) : computeWorkspaceDiff(ws, opts)).finally(() => {
13293
13407
  diffInFlight.delete(key);
13294
13408
  });
13295
13409
  diffInFlight.set(key, run);
@@ -13305,6 +13419,35 @@ function listedDiff(ws, stamp, opts) {
13305
13419
  });
13306
13420
  return run;
13307
13421
  }
13422
+ /** One section's diff (`only`), with every other section the review
13423
+ * names listed beside it without its files (`workspaceSections`, the
13424
+ * listing Files' strip reads), so the strip and its picks stay whole. A
13425
+ * workspace of eighty topics took ten seconds and sent ninety megabytes
13426
+ * for a review showing one of them. */
13427
+ async function scopedDiff(ws, opts, only) {
13428
+ const [own, listing] = await Promise.all([computeWorkspaceDiff(ws, opts), workspaceSections(ws)]);
13429
+ const got = own.find((s) => s.id === only);
13430
+ if (!got) return computeWorkspaceDiff(ws, {
13431
+ ...opts,
13432
+ only: void 0
13433
+ });
13434
+ const out = listing.map((s) => {
13435
+ if (s.id === only) {
13436
+ const { nextToLand, ...rest } = got;
13437
+ return {
13438
+ ...rest,
13439
+ ...s.nextToLand && { nextToLand: true }
13440
+ };
13441
+ }
13442
+ return {
13443
+ ...s,
13444
+ topic: topicOf(s, ws.branch),
13445
+ omitted: true
13446
+ };
13447
+ });
13448
+ if (!listing.some((s) => s.id === only)) out.push(got);
13449
+ return out;
13450
+ }
13308
13451
  /** How long a workspace's last diff answers for an unchanged stamp, and
13309
13452
  * how many are kept (a workspace's scopes and one-commit views). */
13310
13453
  var DIFF_KEEP_MS = 6e4;
@@ -13332,9 +13475,9 @@ function withReview(ws, sections, since) {
13332
13475
  const reviewed = {
13333
13476
  ...s,
13334
13477
  reviewed: point.at,
13335
- ...point.snap === s.snap && { upToDate: true }
13478
+ ...s.snap && point.snap === s.snap && { upToDate: true }
13336
13479
  };
13337
- return since ? sinceReviewed(ws, reviewed, point.snap) : reviewed;
13480
+ return since && !s.omitted ? sinceReviewed(ws, reviewed, point.snap) : reviewed;
13338
13481
  }));
13339
13482
  kept.clear();
13340
13483
  kept.set(key, run);
@@ -13454,10 +13597,11 @@ async function replayed(dir, snap, against) {
13454
13597
  });
13455
13598
  }
13456
13599
  async function computeWorkspaceDiff(ws, opts = {}) {
13457
- const { baseRef, scope = "committed", pr: focus, refresh = false, rev } = opts;
13600
+ const { baseRef, scope = "committed", pr: focus, refresh = false, rev, only } = opts;
13458
13601
  if (refresh) for (const repo of ws.repos) lastFetch.delete(repo.full_name);
13459
13602
  const foreign = otherWorkspaceBranches(ws.id);
13460
- return (await Promise.all(ws.repos.map(async (repo) => {
13603
+ const repos = only ? ws.repos.filter((r) => r.worktree === only.split(/[@#]/)[0]) : ws.repos;
13604
+ return (await Promise.all(repos.map(async (repo) => {
13461
13605
  const dir = path.join(ws.path, repo.worktree);
13462
13606
  const [{ oid: localHead, branch }, prs] = await Promise.all([headOid(dir), workspacePrs(repo.full_name, ws.branch, foreign, refresh, ws.imported_at)]);
13463
13607
  const merged = mergedTips(prs);
@@ -13483,19 +13627,24 @@ async function computeWorkspaceDiff(ws, opts = {}) {
13483
13627
  ], ws.id, refresh);
13484
13628
  const tips = refresh ? await familyBranches(dir, ws, foreign) : found;
13485
13629
  const [places, trees] = await Promise.all([stackParents(dir, ws, repo, tips, open), laneWorktrees(dir)]);
13630
+ const wanted = (id) => !only || id === only;
13631
+ const prId = (p) => `${repo.worktree}#${p.number}`;
13486
13632
  const jobs = tips.names.flatMap((name) => {
13487
13633
  const prs = open.filter((p) => p.headRefName === name);
13488
- if (prs.length) return prs.map((p) => () => pr(p));
13634
+ if (prs.length) return prs.filter((p) => wanted(prId(p))).map((p) => () => pr(p));
13635
+ const id = sectionId(repo.worktree, name, ws.branch);
13636
+ if (!wanted(id)) return [];
13489
13637
  const parent = places.get(name)?.parent;
13490
- if (name === branch) return [() => local(sectionId(repo.worktree, name, ws.branch), parent)];
13638
+ if (name === branch) return [() => local(id, parent)];
13491
13639
  return [() => branchDiff(dir, ws, repo, name, branch, foreign, scope, rev, parent, trees.get(name), merged)];
13492
13640
  });
13493
- for (const p of open) if (!tips.names.includes(p.headRefName)) jobs.push(() => pr(p));
13641
+ for (const p of open) if (!tips.names.includes(p.headRefName) && wanted(prId(p))) jobs.push(() => pr(p));
13494
13642
  list = placeInStacks((await Promise.all(jobs.map((job) => job()))).filter((s) => !!s), tips.names, places, ws.branch, repo.base_branch);
13495
13643
  await markEdits(list, trees, dir, () => editsLanded(ws.id));
13496
13644
  } else if (open.length) list = await Promise.all(open.map(pr));
13497
13645
  else if (focus) list = [];
13498
13646
  else list = [await local()];
13647
+ if (only) list = list.filter((s) => s.id === only);
13499
13648
  for (const s of list) s.topic = topicOf(s, ws.branch);
13500
13649
  if (family.length) await Promise.all(list.map((s) => markPushed(dir, s)));
13501
13650
  return list;
@@ -14701,47 +14850,111 @@ async function readBlobAt(dir, rev, filePath) {
14701
14850
  proc.on("close", (code) => resolve(over || code !== 0 ? null : Buffer.concat(chunks)));
14702
14851
  });
14703
14852
  }
14704
- /** `sections` as a response under `budget` characters of patch text: past
14705
- * it, the largest patches are left out (`deferred`, a hash of each to know
14706
- * it by) until the rest fit. A workspace of many topics over a large repo
14707
- * sent tens of megabytes, which a phone's tab could not hold: iOS killed
14708
- * it, reloaded it into the same request, and gave up. Small files stay
14709
- * whole, so most of a review reads as it did; the page fetches a large
14710
- * one as it comes on screen. The same sections at the same budget come
14711
- * back as the same object, for the route's hash. */
14712
- function withinBudget(sections, budget) {
14853
+ /** `sections` as a response under `budget` characters of patch text.
14854
+ * Past it each topic gets an even share — what a small topic leaves
14855
+ * unused going to the larger ones — and a topic over its share leaves
14856
+ * out its largest patches (`deferred`, a hash of each to know it by) until
14857
+ * the rest fit. A workspace of many topics over a large repo sent tens of
14858
+ * megabytes, which a phone's tab could not hold: iOS killed it, reloaded
14859
+ * it into the same request, and gave up. One cut across the whole review
14860
+ * let a few topics that regenerate thousands of snapshots push every file
14861
+ * over a kilobyte out of every other topic, a topic of 23 files included;
14862
+ * shared out, a small topic reads whole however large its neighbours are.
14863
+ * The page fetches a left-out file as it comes on screen, by its hash
14864
+ * (`deferredPatch`, kept here for `wsId`). The same sections at the same
14865
+ * budget come back as the same object, for the route's hash. */
14866
+ function withinBudget(sections, budget, wsId) {
14713
14867
  let byBudget = budgeted.get(sections);
14714
14868
  if (!byBudget) budgeted.set(sections, byBudget = /* @__PURE__ */ new Map());
14715
- const kept = byBudget.get(budget);
14716
- if (kept) return kept;
14717
- const sizes = sections.flatMap((s) => s.files.flatMap((f) => f.patch ? [f.patch.length] : []));
14718
- let total = sizes.reduce((a, n) => a + n, 0);
14719
- let out = sections;
14720
- if (total > budget) {
14721
- sizes.sort((a, b) => b - a);
14869
+ let kept = byBudget.get(budget);
14870
+ if (!kept) {
14871
+ kept = cutToBudget(sections, budget);
14872
+ byBudget.set(budget, kept);
14873
+ }
14874
+ if (kept.deferred.size) holdDeferred(wsId, kept.deferred);
14875
+ return kept.out;
14876
+ }
14877
+ var budgeted = /* @__PURE__ */ new WeakMap();
14878
+ function cutToBudget(sections, budget) {
14879
+ const deferred = /* @__PURE__ */ new Map();
14880
+ const keyOf = (s) => s.topic ?? s.id;
14881
+ const totals = /* @__PURE__ */ new Map();
14882
+ let total = 0;
14883
+ for (const s of sections) for (const f of s.files) {
14884
+ const n = f.patch?.length ?? 0;
14885
+ totals.set(keyOf(s), (totals.get(keyOf(s)) ?? 0) + n);
14886
+ total += n;
14887
+ }
14888
+ if (total <= budget) return {
14889
+ out: sections,
14890
+ deferred
14891
+ };
14892
+ const sizes = [...totals.values()].sort((a, b) => a - b);
14893
+ let left = budget;
14894
+ let share = 0;
14895
+ for (let i = 0; i < sizes.length; i++) {
14896
+ const even = left / (sizes.length - i);
14897
+ if (sizes[i] > even) {
14898
+ share = even;
14899
+ break;
14900
+ }
14901
+ left -= sizes[i];
14902
+ }
14903
+ const cuts = /* @__PURE__ */ new Map();
14904
+ for (const [topic, size] of totals) {
14905
+ if (size <= share) continue;
14906
+ const lengths = sections.filter((s) => keyOf(s) === topic).flatMap((s) => s.files.flatMap((f) => f.patch ? [f.patch.length] : [])).sort((a, b) => b - a);
14907
+ let kept = size;
14722
14908
  let cut = Infinity;
14723
- for (const n of sizes) {
14724
- if (total <= budget) break;
14725
- total -= n;
14909
+ for (const n of lengths) {
14910
+ if (kept <= share) break;
14911
+ kept -= n;
14726
14912
  cut = n;
14727
14913
  }
14728
- out = sections.map((s) => ({
14729
- ...s,
14730
- files: s.files.map((f) => {
14731
- if (!f.patch || f.patch.length < cut) return f;
14732
- const { patch, ...rest } = f;
14733
- return {
14734
- ...rest,
14735
- deferred: true,
14736
- patchHash: createHash("sha1").update(patch).digest("base64url")
14737
- };
14738
- })
14739
- }));
14914
+ cuts.set(topic, cut);
14915
+ }
14916
+ return {
14917
+ out: sections.map((s) => {
14918
+ const cut = cuts.get(keyOf(s));
14919
+ if (cut === void 0) return s;
14920
+ return {
14921
+ ...s,
14922
+ files: s.files.map((f) => {
14923
+ if (!f.patch || f.patch.length < cut) return f;
14924
+ const { patch, ...rest } = f;
14925
+ const patchHash = createHash("sha1").update(patch).digest("base64url");
14926
+ deferred.set(patchHash, patch);
14927
+ return {
14928
+ ...rest,
14929
+ deferred: true,
14930
+ patchHash
14931
+ };
14932
+ })
14933
+ };
14934
+ }),
14935
+ deferred
14936
+ };
14937
+ }
14938
+ /** Each workspace's last few responses' left-out patches, newest first
14939
+ * (New and Diff, a phone's budget and a desktop's): a page asking for one
14940
+ * as it comes on screen is answered from here by its hash, with no stamp
14941
+ * taken and no diff looked up — a diff kept past its minute was taken
14942
+ * again whole for one file, ten seconds on a workspace of many topics.
14943
+ * The text is the kept diffs' own, not a copy. */
14944
+ var deferredHeld = /* @__PURE__ */ new Map();
14945
+ var DEFERRED_HELD = 4;
14946
+ function holdDeferred(wsId, patches) {
14947
+ const list = (deferredHeld.get(wsId) ?? []).filter((m) => m !== patches);
14948
+ list.unshift(patches);
14949
+ deferredHeld.set(wsId, list.slice(0, DEFERRED_HELD));
14950
+ }
14951
+ /** A patch a response to `wsId` left out, by its hash (`withinBudget`). */
14952
+ function deferredPatch(wsId, hash) {
14953
+ for (const patches of deferredHeld.get(wsId) ?? []) {
14954
+ const patch = patches.get(hash);
14955
+ if (patch !== void 0) return patch;
14740
14956
  }
14741
- byBudget.set(budget, out);
14742
- return out;
14743
14957
  }
14744
- var budgeted = /* @__PURE__ */ new WeakMap();
14745
14958
  /** One file's patch in `sections`, for a page that was sent it deferred. */
14746
14959
  function patchIn(sections, section, file) {
14747
14960
  return sections.find((s) => s.id === section)?.files.find((f) => f.path === file)?.patch;
@@ -17793,13 +18006,25 @@ async function killSession(id, keepChildren = false, how = "closed") {
17793
18006
  if (!session) return [];
17794
18007
  const family = keepChildren ? [id] : [id, ...descendantsOf(id)];
17795
18008
  db.prepare(`DELETE FROM closed_sessions WHERE closed_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '${REOPEN_WITHIN}')`).run();
17796
- for (const member of family) {
17797
- keepClosed(member, member === id ? how : "closed");
17798
- await disposeSession(member);
17799
- }
18009
+ linkPastUnkept(family, new Map(family.map((m) => [m, getSession(m)?.parent_id ?? null])), new Set(family.filter((m) => keepClosed(m, m === id ? how : "closed"))));
18010
+ for (const member of family) await disposeSession(member);
17800
18011
  notifySessionsChanged(session.workspace_id);
17801
18012
  return family;
17802
18013
  }
18014
+ /** A member kept under one that was not (a shell, a session whose
18015
+ * conversation work never learned) is linked to the nearest member above
18016
+ * it that was, so `reopenTeam` still reaches it: under a parent that never
18017
+ * comes back it would stand alone. */
18018
+ function linkPastUnkept(family, parents, kept) {
18019
+ const inFamily = new Set(family);
18020
+ for (const member of kept) {
18021
+ const own = parents.get(member);
18022
+ if (!own || !inFamily.has(own) || kept.has(own)) continue;
18023
+ let up = parents.get(own) ?? null;
18024
+ while (up && inFamily.has(up) && !kept.has(up)) up = parents.get(up) ?? null;
18025
+ if (up && kept.has(up)) db.prepare("UPDATE closed_sessions SET parent_id = ? WHERE id = ?").run(up, member);
18026
+ }
18027
+ }
17803
18028
  /** How long a closed session can be started again: a lead's follow-ups
17804
18029
  * come as the user reviews its result, the same day or so. */
17805
18030
  var REOPEN_WITHIN = "-7 days";
@@ -17807,6 +18032,28 @@ var REOPEN_WITHIN = "-7 days";
17807
18032
  function noteConversation(id, conversation) {
17808
18033
  db.prepare("UPDATE sessions SET conversation = ? WHERE id = ? AND conversation IS NOT ?").run(conversation, id, conversation);
17809
18034
  }
18035
+ /** The sessions closed with `id` and still kept (`reopenTeam`): down its
18036
+ * parent links, each closed no earlier than it — one closed on its own
18037
+ * before its lead went is not part of that close — parents before their
18038
+ * children. */
18039
+ function closedTeam(id) {
18040
+ const lead = closedSession(id);
18041
+ if (!lead) return [];
18042
+ const rows = all(`SELECT * FROM closed_sessions WHERE workspace_id = ? AND id != ? AND closed_at >= ?
18043
+ AND closed_at >= strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '${REOPEN_WITHIN}')
18044
+ ORDER BY closed_at, created_at`, lead.workspace_id, id, lead.closed_at);
18045
+ const team = [];
18046
+ const reached = /* @__PURE__ */ new Set([id]);
18047
+ for (let grew = true; grew;) {
18048
+ grew = false;
18049
+ for (const r of rows) if (!reached.has(r.id) && r.parent_id && reached.has(r.parent_id)) {
18050
+ reached.add(r.id);
18051
+ team.push(r);
18052
+ grew = true;
18053
+ }
18054
+ }
18055
+ return team;
18056
+ }
17810
18057
  /** A closed session that can still be started again (`reopenSession`). */
17811
18058
  function closedSession(id) {
17812
18059
  return get(`SELECT * FROM closed_sessions WHERE id = ?
@@ -17819,12 +18066,14 @@ function reopenable(s) {
17819
18066
  }
17820
18067
  /** Keep `id` as it is in closed_sessions, about to close. One closed for
17821
18068
  * being done is kept whatever it is, so a message to it can say why it
17822
- * does not reopen; any other only if it can be started again. */
18069
+ * does not reopen; any other only if it can be started again. Whether it
18070
+ * was kept. */
17823
18071
  function keepClosed(id, how) {
17824
18072
  const s = getSession(id);
17825
- if (!s?.workspace_id || how === "closed" && !reopenable(s)) return;
18073
+ if (!s?.workspace_id || how === "closed" && !reopenable(s)) return false;
17826
18074
  db.prepare(`INSERT OR REPLACE INTO closed_sessions (id, workspace_id, agent, title, parent_id, launch_dir, launch_mode, summary, conversation, created_at, how)
17827
18075
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(s.id, s.workspace_id, s.agent, s.title, s.parent_id, s.launch_dir, s.launch_mode, s.summary, s.conversation, s.created_at, how);
18076
+ return true;
17828
18077
  }
17829
18078
  /** Close a session work is done with (server/team), keeping what starts
17830
18079
  * it again on its own conversation (`reopenSession`): the lead that
@@ -17874,11 +18123,20 @@ async function reopenSession(id, opts = {}) {
17874
18123
  notifySessionsChanged(closed.workspace_id);
17875
18124
  return session;
17876
18125
  }
17877
- /** Start a running session's CLI again on its own conversation, as
17878
- * `agent` if given (`resumeAs`): one stuck at its prompt because its
17879
- * account hit a limit goes on as another account's. Its row, what is
17880
- * queued for it and what it owes stay (server/messages keeps them). */
17881
- async function restartSession(id, agent) {
18126
+ /** Restarts in flight, by session (`restartOf`): an attach that ends
18127
+ * meanwhile was ended by the restart, not by its agent, so term-ws tells
18128
+ * its page to come back rather than that the session ended, and a page
18129
+ * that connects meanwhile waits for the new pane. Kept a beat past the
18130
+ * restart, since an old attach hears its end only as tmux gets to it. */
18131
+ var restarts = /* @__PURE__ */ new Map();
18132
+ var RESTART_LINGER_MS = 3e3;
18133
+ function restartOf(id) {
18134
+ return restarts.get(id);
18135
+ }
18136
+ /** What `restartSession` would start `id` as, or why it cannot: asked
18137
+ * before a switch is scheduled (server/messages `reopen`), so a request
18138
+ * that cannot work fails as it is made, not when it comes due. */
18139
+ function restartPlan(id, agent) {
17882
18140
  const s = getSession(id);
17883
18141
  if (!s) throw httpError(404, `no session ${id}`);
17884
18142
  if (!reopenable(s)) throw httpError(409, `${id} cannot start again on its conversation: ${canResume(s.agent) ? "work has not learned it yet (it comes with the first prompt's hook)" : `${agentLabel(s.agent)} cannot resume one`}`);
@@ -17886,26 +18144,61 @@ async function restartSession(id, agent) {
17886
18144
  const wsPath = workspacePath(s.workspace_id);
17887
18145
  if (!wsPath) throw httpError(409, `${id}'s workspace is gone`);
17888
18146
  if (s.launch_dir && launchDir(s, wsPath) === wsPath) throw httpError(409, `${id} ran in ${s.launch_dir}, which is gone, and its conversation with it: ${START_AGAIN}`);
17889
- const env = cleanEnv();
17890
- await tmux([
17891
- "kill-session",
17892
- "-t",
17893
- tmuxName(id)
17894
- ], env).catch(() => {});
17895
- forgetPanes();
17896
- clearTmuxStarted(id);
17897
- clearAgentPhase(id);
17898
- db.prepare("UPDATE sessions SET agent = ? WHERE id = ?").run(next, id);
17899
- const session = getSession(id);
17900
- await ensureTmuxServer();
17901
- await launchDetached(session, wsPath, env, { resume: s.conversation });
17902
- if (!await paneAlive(id, env)) {
17903
- db.prepare("UPDATE sessions SET agent = ? WHERE id = ?").run(s.agent, id);
18147
+ return {
18148
+ s,
18149
+ next,
18150
+ wsPath
18151
+ };
18152
+ }
18153
+ /** Start a running session's CLI again on its own conversation, as
18154
+ * `agent` if given (`resumeAs`): one stuck at its prompt because its
18155
+ * account hit a limit goes on as another account's. Its row, what is
18156
+ * queued for it and what it owes stay (server/messages keeps them), and a
18157
+ * switch it was waiting on is done. */
18158
+ async function restartSession(id, agent) {
18159
+ const { s, next, wsPath } = restartPlan(id, agent);
18160
+ let finish;
18161
+ const pending = new Promise((resolve) => finish = resolve);
18162
+ restarts.set(id, pending);
18163
+ try {
18164
+ const env = cleanEnv();
18165
+ await tmux([
18166
+ "kill-session",
18167
+ "-t",
18168
+ tmuxName(id)
18169
+ ], env).catch(() => {});
18170
+ forgetPanes();
18171
+ clearTmuxStarted(id);
18172
+ clearAgentPhase(id);
18173
+ db.prepare("UPDATE sessions SET agent = ?, switch_to = NULL WHERE id = ?").run(next, id);
18174
+ const session = getSession(id);
18175
+ await ensureTmuxServer();
18176
+ await launchDetached(session, wsPath, env, { resume: s.conversation });
18177
+ if (!await paneAlive(id, env)) {
18178
+ db.prepare("UPDATE sessions SET agent = ? WHERE id = ?").run(s.agent, id);
18179
+ notifySessionsChanged(s.workspace_id);
18180
+ throw httpError(409, `${id}'s ${agentLabel(next)} could not resume its conversation (${s.conversation})${next === s.agent ? "" : `: ${next} may keep its conversations apart from ${s.agent}'s`}, and its pane has closed: \`work session reopen ${id}\` tries again`);
18181
+ }
17904
18182
  notifySessionsChanged(s.workspace_id);
17905
- throw httpError(409, `${id}'s ${agentLabel(next)} could not resume its conversation (${s.conversation})${next === s.agent ? "" : `: ${next} may keep its conversations apart from ${s.agent}'s`}, and its pane has closed: \`work session reopen ${id}\` tries again`);
18183
+ return session;
18184
+ } finally {
18185
+ finish();
18186
+ setTimeout(() => {
18187
+ if (restarts.get(id) === pending) restarts.delete(id);
18188
+ }, RESTART_LINGER_MS).unref?.();
17906
18189
  }
18190
+ }
18191
+ /** Ask for `id` to move to `agent` once it is idle (server/messages
18192
+ * `switchWhenIdle`), or take that ask back (`agent` null). */
18193
+ function setSwitch(id, agent) {
18194
+ const s = getSession(id);
18195
+ if (!s) return;
18196
+ db.prepare("UPDATE sessions SET switch_to = ? WHERE id = ?").run(agent, id);
17907
18197
  notifySessionsChanged(s.workspace_id);
17908
- return session;
18198
+ }
18199
+ /** Sessions waiting to move to another instance once idle. */
18200
+ function pendingSwitches() {
18201
+ return all("SELECT id, switch_to FROM sessions WHERE switch_to IS NOT NULL");
17909
18202
  }
17910
18203
  /** What a session is, open or closed (`work session list <id>`, `log`):
17911
18204
  * undefined for one work does not know, or no longer keeps. */
@@ -17925,6 +18218,8 @@ function sessionInfo(id) {
17925
18218
  kept: !!live?.keep,
17926
18219
  /** Since when it is to close once nothing is lost by it (`retire`). */
17927
18220
  retiring: live?.retire_at ?? null,
18221
+ /** The instance it moves to once it is idle (`reopen --agent`). */
18222
+ switching: live?.switch_to ?? null,
17928
18223
  /** How and when it closed; null while open. */
17929
18224
  closed: closed ? {
17930
18225
  how: closed.how,
@@ -18069,7 +18364,7 @@ function notifySessionsChanged(workspaceId) {
18069
18364
  async function emitSessionsChanged(workspaceId) {
18070
18365
  try {
18071
18366
  const states = await sessionStates();
18072
- const { teamsOf } = await import("./_B25P__C4.js");
18367
+ const { teamsOf } = await import("./_CfUEaP2Y.js");
18073
18368
  publish("sessions.changed", {
18074
18369
  workspaceId,
18075
18370
  sessions: listSessions(workspaceId).map((s) => ({
@@ -20074,7 +20369,10 @@ ${repoLines}
20074
20369
  Claude or Codex one reopens it on its own conversation; one closed
20075
20370
  otherwise (with its lead, by the user), or stuck on its account's limit,
20076
20371
  \`work session reopen <id> [--agent <another instance>]\` starts again
20077
- on it, and \`work session log [<id>]\` shows what went to and from
20372
+ on it, a busy one once it is idle. To move yourself to another account
20373
+ (\`reopen $WORK_SESSION_ID --agent claude2\`), it happens as this turn
20374
+ ends, your conversation, team and queue kept: say where you are, then
20375
+ end the turn. \`work session log [<id>]\` shows what went to and from
20078
20376
  one and how each message went. \`kill\` and \`skip\` end the turn under
20079
20377
  way and what its pane runs; to lose nothing, \`forget <id>\` stops
20080
20378
  waiting on a reply, \`unsend <id>\` takes back a message not yet typed
@@ -20098,4 +20396,4 @@ ${repoLines}
20098
20396
  `;
20099
20397
  }
20100
20398
  //#endregion
20101
- export { paneJobs as $, turnSince as $n, TOOLS as $r, setPoints as $t, clearTmuxStarted as A, interruptedSinceReport as An, PREF_MAX as Ar, lspEnabled as At, killSession as B, onFinished as Bn, preferredAgent as Br, logoutGithub as Bt, workspaceBranches as C, git as Ci, inside as Cn, configuredHosts as Cr, stopServers as Ct, agentCaller as D, withLock as Di, clearAgentPhase as Dn, normalizeHost as Dr, forgetProbes as Dt, hookToken as E, swr as Ei, agentPhase as En, isValidHost as Er, forgetCustomServer as Et, disposeSessions as F, notePermissionMode as Fn, deleteSetting as Fr, whileInstalling as Ft, listSessions as G, setAgentPhase as Gn, doctor as Gr, fileChanges as Gt, launchDir as H, onTurnEnd as Hn, setPref as Hr, removeTool as Ht, ensureTmuxServer as I, noteTurnFailed as In, disabledAgents as Ir, authGithub as It, newSessionArgs as J, setSessionViewers as Jn, miseVersions as Jr, readFileAt as Jt, markTmuxStarted as K, setExpecting as Kn, ghKnownHosts as Kr, patchIn as Kt, forgetPanes as L, noteTyped as Ln, enabledAgents as Lr, installAgent as Lt, createSession as M, noteActivity$1 as Mn, agentChoices as Mr, serverById as Mt, creationOf as N, noteBackground as Nn, allPrefs as Nr, serverList as Nt, beginCreation as O, hookPhase as On, removeHost as Or, installKey as Ot, descendantsOf as P, noteInterrupt as Pn, changePref as Pr, sharing as Pt, ownWorkspaceOnly as Q, turnSettling as Qn, PROJECT_TOOLS as Qr, workspaceSections as Qt, getSession as R, noteUserAnswered as Rn, getSetting as Rr, installMise as Rt, withProgressOp as S, TMUX_SOCKET as Si, cleanSummary as Sn, addHost as Sr, stopAllServers as St, ensureAllPushHooks as T, config as Ti, activityOf as Tn, forgetToken as Tr, allServers as Tt, listPanes as U, onTurnFailed as Un, setSetting as Ur, runStreaming as Ut, killWorkspaceSessions as V, onPhaseChange as Vn, setDisabledAgents as Vr, refreshGithub as Vt, listPanesWithin as W, sessionWatched as Wn, discoverAgents as Wr, updateTool as Wt, notifySessionsChanged as X, summaryOf as Xn, bornOut as Xr, withinBudget as Xt, noteConversation as Y, settleQuietWorking as Yn, which as Yr, reviewWaiting as Yt, onSessionDispose as Z, turnPhase as Zn, firewallProbe as Zr, workspaceDiff as Zt, retryMaterialize as _, get as _i, steerKeys as _n, pendingSsoOrgs as _r, lspQuery as _t, ensureUntrackedCache as a, applyPrefChange as ai, dismissPr as an, ACCENT_RE as ar, restartSession as at, sweepTrash as b, ensureAllCacheConfig as bi, readCache as bn, repoDefaultBranch as br, lspWarm as bt, insertPendingWorkspace as c, checked as ci, refreshPrsBatch as cn, manifest as cr, sessionInfo as ct, progress as d, publish as di, noteActivity as dn, deleteSubscription as dr, tmuxWasStarted as dt, agentById as ei, startSnapSweep as en, agentBadge as er, panePids as et, progressSince as f, publishJson as fi, AGENTS as fn, pushPublicKey as fr, killWorkspaceProc as ft, resumePendingWorkspaces as g, db as gi, reportsWorking as gn, headOid as gr, lspDiagnostics as gt, removeRepo as h, all as hi, readHookPayload as hn, validSubscription as hr, killServers as ht, deleteWorkspace as i, toolById as ii, sectionFor as in, agentMeta as ir, reopenable as it, closedSession as j, lastTypedAt as jn, WORKSPACE_PREFS as jr, removeServer as jt, cleanEnv as k, hookReportedAt as kn, unreachableRepos as kr, installServer as kt, listWorkspaces as l, httpError as li, withoutDismissed as ln, normalizeAccent as lr, sessionStates as lt, queueMaterialize as m, subscriberCount as mi, quotesPastes as mn, sendPush as mr, workspaceProcs as mt, barePath as n, catalogPin as ni, commentFolder as nn, agentFromCommand as nr, renameSession as nt, gcBares as o, FRAME_ANCESTORS as oi, hotBatchMinMs as on, getInstance as or, retireSession as ot, pruneLaneBranch as p, subscribe as pi, interruptKeys as pn, saveSubscription as pr, portsByWorkspace as pt, moveSession as q, setScrapedPhase as qn, miseInstalls as qr, readBlobAt as qt, createWorkspace as r, parseAgentId as ri, markBranch as rn, agentLabel as rr, reopenSession as rt, getWorkspace as s, FRAME_HEADERS as si, notePushActivity as sn, iconSvg as sr, sendToSession as st, addRepo as t, agentLabel$1 as ti, diffStamp as tn, agentFamily as tr, pasteToSession as tt, otherWorkspaceBranches as u, readBody as ui, workspacePrs as un, setInstance as ur, tmuxName as ut, revParse as v, workspacePath as vi, blankRow as vn, repoBranches as vr, lspQueryOf as vt, startTmpSweep as w, tmux as wi, realInside as wn, ensureGitCredentials as wr, addCustomServer as wt, syncAgentsMd as x, SCRATCH_TMUX as xi, writeCache as xn, DEFAULT_HOST as xr, runningServers as xt, setWorkspaceStatus as y, ownsBranchOf as yi, credentialStamp as yn, repoCatalog as yr, lspUses as yt, interruptSession as z, notifyEventOn as zn, isKnownAgent as zr, installTool as zt };
20399
+ export { ownWorkspaceOnly as $, setAgentPhase as $n, doctor as $r, readBlobAt as $t, clearTmuxStarted as A, TMUX_SOCKET as Ai, cleanSummary as An, addHost as Ar, allServers as At, interruptSession as B, noteActivity$1 as Bn, agentChoices as Br, whileInstalling as Bt, workspaceBranches as C, all as Ci, readHookPayload as Cn, validSubscription as Cr, lspQueryOf as Ct, agentCaller as D, ownsBranchOf as Di, credentialStamp as Dn, repoCatalog as Dr, stopAllServers as Dt, hookToken as E, workspacePath as Ei, blankRow as En, repoBranches as Er, runningServers as Et, descendantsOf as F, withLock as Fi, clearAgentPhase as Fn, normalizeHost as Fr, lspEnabled as Ft, listPanesWithin as G, noteTyped as Gn, enabledAgents as Gr, logoutGithub as Gt, killWorkspaceSessions as H, noteInterrupt as Hn, changePref as Hr, installAgent as Ht, disposeSessions as I, hookPhase as In, removeHost as Ir, removeServer as It, moveSession as J, onFinished as Jn, preferredAgent as Jr, runStreaming as Jt, listSessions as K, noteUserAnswered as Kn, getSetting as Kr, refreshGithub as Kt, ensureTmuxServer as L, hookReportedAt as Ln, unreachableRepos as Lr, serverById as Lt, closedTeam as M, tmux as Mi, realInside as Mn, ensureGitCredentials as Mr, forgetProbes as Mt, createSession as N, config as Ni, activityOf as Nn, forgetToken as Nr, installKey as Nt, beginCreation as O, ensureAllCacheConfig as Oi, readCache as On, repoDefaultBranch as Or, stopServers as Ot, creationOf as P, swr as Pi, agentPhase as Pn, isValidHost as Pr, installServer as Pt, onSessionDispose as Q, sessionWatched as Qn, discoverAgents as Qr, patchIn as Qt, forgetPanes as R, interruptedSinceReport as Rn, PREF_MAX as Rr, serverList as Rt, withProgressOp as S, subscriberCount as Si, quotesPastes as Sn, sendPush as Sr, lspQuery as St, ensureAllPushHooks as T, get as Ti, steerKeys as Tn, pendingSsoOrgs as Tr, lspWarm as Tt, launchDir as U, notePermissionMode as Un, deleteSetting as Ur, installMise as Ut, killSession as V, noteBackground as Vn, allPrefs as Vr, authGithub as Vt, listPanes as W, noteTurnFailed as Wn, disabledAgents as Wr, installTool as Wt, noteConversation as X, onTurnEnd as Xn, setPref as Xr, deferredPatch as Xt, newSessionArgs as Y, onPhaseChange as Yn, setDisabledAgents as Yr, updateTool as Yt, notifySessionsChanged as Z, onTurnFailed as Zn, setSetting as Zr, fileChanges as Zt, retryMaterialize as _, httpError as _i, withoutDismissed as _n, normalizeAccent as _r, killWorkspaceProc as _t, ensureUntrackedCache as a, firewallProbe as ai, workspaceSections as an, turnPhase as ar, reopenSession as at, sweepTrash as b, publishJson as bi, AGENTS as bn, pushPublicKey as br, killServers as bt, insertPendingWorkspace as c, agentById as ci, diffStamp as cn, agentBadge as cr, restartPlan as ct, progress as d, parseAgentId as di, sectionFor as dn, agentLabel as dr, sendToSession as dt, ghKnownHosts as ei, readFileAt as en, setExpecting as er, paneJobs as et, progressSince as f, toolById as fi, dismissPr as fn, agentMeta as fr, sessionInfo as ft, resumePendingWorkspaces as g, checked as gi, refreshPrsBatch as gn, manifest as gr, tmuxWasStarted as gt, removeRepo as h, FRAME_HEADERS as hi, prsForHeads as hn, iconSvg as hr, tmuxName as ht, deleteWorkspace as i, bornOut as ii, workspaceDiff as in, summaryOf as ir, renameSession as it, closedSession as j, git as ji, inside as jn, configuredHosts as jr, forgetCustomServer as jt, cleanEnv as k, SCRATCH_TMUX as ki, writeCache as kn, DEFAULT_HOST as kr, addCustomServer as kt, listWorkspaces as l, agentLabel$1 as li, commentFolder as ln, agentFamily as lr, restartSession as lt, queueMaterialize as m, FRAME_ANCESTORS as mi, notePushActivity as mn, getInstance as mr, setSwitch as mt, barePath as n, miseVersions as ni, sectionScope as nn, setSessionViewers as nr, pasteToSession as nt, gcBares as o, PROJECT_TOOLS as oi, setPoints as on, turnSettling as or, reopenable as ot, pruneLaneBranch as p, applyPrefChange as pi, hotBatchMinMs as pn, ACCENT_RE as pr, sessionStates as pt, markTmuxStarted as q, notifyEventOn as qn, isKnownAgent as qr, removeTool as qt, createWorkspace as r, which as ri, withinBudget as rn, settleQuietWorking as rr, pendingSwitches as rt, getWorkspace as s, TOOLS as si, startSnapSweep as sn, turnSince as sr, restartOf as st, addRepo as t, miseInstalls as ti, reviewWaiting as tn, setScrapedPhase as tr, panePids as tt, otherWorkspaceBranches as u, catalogPin as ui, markBranch as un, agentFromCommand as ur, retireSession as ut, revParse as v, readBody as vi, workspacePrs as vn, setInstance as vr, portsByWorkspace as vt, startTmpSweep as w, db as wi, reportsWorking as wn, headOid as wr, lspUses as wt, syncAgentsMd as x, subscribe as xi, interruptKeys as xn, saveSubscription as xr, lspDiagnostics as xt, setWorkspaceStatus as y, publish as yi, noteActivity as yn, deleteSubscription as yr, workspaceProcs as yt, getSession as z, lastTypedAt as zn, WORKSPACE_PREFS as zr, sharing as zt };