@dylanpiercey/work 0.0.44 → 0.0.46

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 (245) hide show
  1. package/dist/{_Tcoxq_nF.js → _BlRAjywT.js} +58 -58
  2. package/dist/{_B6irorCp.js → _CWl3Ch5X.js} +2 -2
  3. package/dist/{_Cja4R2gP.js → _P9IsUQm2.js} +58 -59
  4. package/dist/_kABYZA6_.js +2 -0
  5. package/dist/index.mjs +452 -920
  6. package/dist/public/assets/{_2By3R--W2.js → _2M21bg3q2.js} +1 -1
  7. package/dist/public/assets/_2M21bg3q2.js.br +0 -0
  8. package/dist/public/assets/{_E5DvansN.js → _352AdLA5.js} +1 -1
  9. package/dist/public/assets/_352AdLA5.js.br +0 -0
  10. package/dist/public/assets/{_D2sFNldb.js → _3Ix19RVv.js} +1 -1
  11. package/dist/public/assets/_3Ix19RVv.js.br +0 -0
  12. package/dist/public/assets/{_ePAxCx7r.js → _7EJ8kgH9.js} +1 -1
  13. package/dist/public/assets/_7EJ8kgH9.js.br +0 -0
  14. package/dist/public/assets/{_Bnp1UtCp2.js → _7QGssl5Y2.js} +1 -1
  15. package/dist/public/assets/_7QGssl5Y2.js.br +0 -0
  16. package/dist/public/assets/{_BdiO50aC2.js → _AnY5lXmz2.js} +1 -1
  17. package/dist/public/assets/_AnY5lXmz2.js.br +0 -0
  18. package/dist/public/assets/{_CcjW-l5T.js → _B0-W17hf.js} +1 -1
  19. package/dist/public/assets/_B0-W17hf.js.br +0 -0
  20. package/dist/public/assets/{_4aAs0pvU.js → _B5-VBCs9.js} +1 -1
  21. package/dist/public/assets/_B5-VBCs9.js.br +0 -0
  22. package/dist/public/assets/{_jmw7zbFI2.js → _BAm2L16s2.js} +1 -1
  23. package/dist/public/assets/_BAm2L16s2.js.br +0 -0
  24. package/dist/public/assets/{_DbnzsP9f.js → _BBEhnK4G.js} +1 -1
  25. package/dist/public/assets/_BBEhnK4G.js.br +0 -0
  26. package/dist/public/assets/{_DIezl6EI.js → _BEK6FWxR.js} +1 -1
  27. package/dist/public/assets/_BEK6FWxR.js.br +0 -0
  28. package/dist/public/assets/{_B7T2AE8L.js → _BIoq-ERW.js} +1 -1
  29. package/dist/public/assets/_BIoq-ERW.js.br +0 -0
  30. package/dist/public/assets/{_D0PcbpPB.js → _BKoNtf_F.js} +1 -1
  31. package/dist/public/assets/_BKoNtf_F.js.br +0 -0
  32. package/dist/public/assets/{_Dyejz2MQ.js → _BRlDlrsI.js} +1 -1
  33. package/dist/public/assets/_BRlDlrsI.js.br +0 -0
  34. package/dist/public/assets/{_DtMzVsHW2.js → _BXfL26ye2.js} +1 -1
  35. package/dist/public/assets/_BXfL26ye2.js.br +0 -0
  36. package/dist/public/assets/{_CQ3pD5r12.js → _BYauXu-72.js} +1 -1
  37. package/dist/public/assets/_BYauXu-72.js.br +0 -0
  38. package/dist/public/assets/{_DZtm6WF2.js → _B_q23_II.js} +1 -1
  39. package/dist/public/assets/_B_q23_II.js.br +0 -0
  40. package/dist/public/assets/{_BAQFHOGb.js → _BfHpfaZ_.js} +1 -1
  41. package/dist/public/assets/_BfHpfaZ_.js.br +0 -0
  42. package/dist/public/assets/{_CQRG1j1X.js → _BgEZ4VVT.js} +1 -1
  43. package/dist/public/assets/_BgEZ4VVT.js.br +0 -0
  44. package/dist/public/assets/{_CMmwGR_Q.js → _BjNNABN4.js} +1 -1
  45. package/dist/public/assets/_BjNNABN4.js.br +0 -0
  46. package/dist/public/assets/{_D_EzfDaC.js → _Bl1lbp_w.js} +1 -1
  47. package/dist/public/assets/_Bl1lbp_w.js.br +0 -0
  48. package/dist/public/assets/{_Tou5xDB12.js → _BpdQAAz52.js} +1 -1
  49. package/dist/public/assets/_BpdQAAz52.js.br +0 -0
  50. package/dist/public/assets/{_DbbVTGR82.js → _Buzw695T2.js} +1 -1
  51. package/dist/public/assets/_Buzw695T2.js.br +0 -0
  52. package/dist/public/assets/{_CasdikBZ2.js → _BwiRBnwa2.js} +1 -1
  53. package/dist/public/assets/_BwiRBnwa2.js.br +0 -0
  54. package/dist/public/assets/{_DY4GR3La.js → _Bwvf5O5m.js} +1 -1
  55. package/dist/public/assets/_Bwvf5O5m.js.br +0 -0
  56. package/dist/public/assets/{_BRP9V2vY.js → _BxoEzgEZ.js} +1 -1
  57. package/dist/public/assets/_BxoEzgEZ.js.br +0 -0
  58. package/dist/public/assets/{_BCTR0wV0.js → _C2_FIDzy.js} +1 -1
  59. package/dist/public/assets/_C2_FIDzy.js.br +0 -0
  60. package/dist/public/assets/{_DoaHBjpa.js → _C7ePJdWG.js} +1 -1
  61. package/dist/public/assets/_C7ePJdWG.js.br +0 -0
  62. package/dist/public/assets/{_DucRMQLL2.js → _C8Et1SyI2.js} +1 -1
  63. package/dist/public/assets/_C8Et1SyI2.js.br +0 -0
  64. package/dist/public/assets/{_BaIOx6992.js → _C8ZyCmzP2.js} +1 -1
  65. package/dist/public/assets/_C8ZyCmzP2.js.br +0 -0
  66. package/dist/public/assets/{_DvsUo16D2.js → _CCEQHCkw2.js} +1 -1
  67. package/dist/public/assets/_CCEQHCkw2.js.br +0 -0
  68. package/dist/public/assets/{_CJ4aiC36.js → _CF8Ye5Pr.js} +1 -1
  69. package/dist/public/assets/_CF8Ye5Pr.js.br +0 -0
  70. package/dist/public/assets/{_BNDbFEJj.js → _CG1U-TrX.js} +1 -1
  71. package/dist/public/assets/_CG1U-TrX.js.br +0 -0
  72. package/dist/public/assets/{_D861FlLr2.js → _CHF-A3pQ2.js} +1 -1
  73. package/dist/public/assets/{_BRV26aAF.js → _CIWR8COm.js} +1 -1
  74. package/dist/public/assets/_CIWR8COm.js.br +0 -0
  75. package/dist/public/assets/{_BBXJK7fW.js → _CJb-25b5.js} +1 -1
  76. package/dist/public/assets/_CJb-25b5.js.br +0 -0
  77. package/dist/public/assets/{_C2OfA6BZ.js → _CNkHd20B.js} +1 -1
  78. package/dist/public/assets/_CNkHd20B.js.br +0 -0
  79. package/dist/public/assets/{_D0en76Ej.js → _CPintIPn.js} +1 -1
  80. package/dist/public/assets/_CPintIPn.js.br +0 -0
  81. package/dist/public/assets/{__OpDUxvR.js → _CV-6NFPr.js} +1 -1
  82. package/dist/public/assets/_CV-6NFPr.js.br +0 -0
  83. package/dist/public/assets/{_BA7PhURg.js → _CcKgVKPB.js} +1 -1
  84. package/dist/public/assets/_CcKgVKPB.js.br +0 -0
  85. package/dist/public/assets/{_ZLwlH_XK.js → _Cjul82Zq.js} +1 -1
  86. package/dist/public/assets/_Cjul82Zq.js.br +0 -0
  87. package/dist/public/assets/{_DJAJCWgm.js → _ClIws-96.js} +33 -33
  88. package/dist/public/assets/_ClIws-96.js.br +0 -0
  89. package/dist/public/assets/{_Bd7b48iJ.js → _CovynO6D.js} +1 -1
  90. package/dist/public/assets/_CovynO6D.js.br +0 -0
  91. package/dist/public/assets/{_FT8jstIj.js → _CulCcVql.js} +1 -1
  92. package/dist/public/assets/_CulCcVql.js.br +0 -0
  93. package/dist/public/assets/{_BkeFq1dG2.js → _D1PGPveJ2.js} +1 -1
  94. package/dist/public/assets/_D1PGPveJ2.js.br +0 -0
  95. package/dist/public/assets/{_CL84pok8.js → _D6gJIVAe.js} +1 -1
  96. package/dist/public/assets/_D6gJIVAe.js.br +0 -0
  97. package/dist/public/assets/{_DA_t7MOs2.js → _DCWsqkZv2.js} +1 -1
  98. package/dist/public/assets/_DCWsqkZv2.js.br +0 -0
  99. package/dist/public/assets/{_Bt3B1aEu2.js → _DCm-_PJn2.js} +1 -1
  100. package/dist/public/assets/_DCm-_PJn2.js.br +0 -0
  101. package/dist/public/assets/{_C9UHqcOT2.js → _DEwU7Qht2.js} +1 -1
  102. package/dist/public/assets/_DEwU7Qht2.js.br +0 -0
  103. package/dist/public/assets/{_DAVDeGoR.js → _DGWBK-es.js} +1 -1
  104. package/dist/public/assets/_DGWBK-es.js.br +0 -0
  105. package/dist/public/assets/{_DCD2JMxh2.js → _DHGqWb3U2.js} +1 -1
  106. package/dist/public/assets/{_D0ljGGvp2.js → _DNzVvAp22.js} +1 -1
  107. package/dist/public/assets/_DNzVvAp22.js.br +0 -0
  108. package/dist/public/assets/{_Dkmb-8CU.js → _DTpbGvLK.js} +1 -1
  109. package/dist/public/assets/_DTpbGvLK.js.br +0 -0
  110. package/dist/public/assets/{_D5BjTqU42.js → _DXcwnV6_2.js} +1 -1
  111. package/dist/public/assets/_DXcwnV6_2.js.br +0 -0
  112. package/dist/public/assets/{__UTjMwX3.js → _DXwZkY0g.js} +1 -1
  113. package/dist/public/assets/_DXwZkY0g.js.br +0 -0
  114. package/dist/public/assets/{_dAPOyRJr.js → _DXyHmj0W.js} +1 -1
  115. package/dist/public/assets/_DXyHmj0W.js.br +0 -0
  116. package/dist/public/assets/{_BBdsdafe2.js → _Da-7IlQ12.js} +1 -1
  117. package/dist/public/assets/_Da-7IlQ12.js.br +0 -0
  118. package/dist/public/assets/{_CAP_5S-t.js → _Da05VMNb.js} +1 -1
  119. package/dist/public/assets/_Da05VMNb.js.br +0 -0
  120. package/dist/public/assets/{_BqdeosKn.js → _DbNaSvXF.js} +1 -1
  121. package/dist/public/assets/_DbNaSvXF.js.br +0 -0
  122. package/dist/public/assets/{_jDukN6_E2.js → _DfrjsE1y2.js} +1 -1
  123. package/dist/public/assets/_DfrjsE1y2.js.br +0 -0
  124. package/dist/public/assets/{_BBEMecyM2.js → _DqtgQ2KQ2.js} +1 -1
  125. package/dist/public/assets/_DqtgQ2KQ2.js.br +0 -0
  126. package/dist/public/assets/{_DaTkOx5R.js → _EuJYsBIp.js} +1 -1
  127. package/dist/public/assets/_EuJYsBIp.js.br +0 -0
  128. package/dist/public/assets/{_CjrYQPNO.js → _KWAohXQr.js} +1 -1
  129. package/dist/public/assets/_KWAohXQr.js.br +0 -0
  130. package/dist/public/assets/{_BPvgcQ_P.js → _XYmpEKpu.js} +1 -1
  131. package/dist/public/assets/_XYmpEKpu.js.br +0 -0
  132. package/dist/public/assets/{_CIVAj2XC.js → _YewM841C.js} +1 -1
  133. package/dist/public/assets/_YewM841C.js.br +0 -0
  134. package/dist/public/assets/{_U0PVI62V.js → _apOz5w70.js} +1 -1
  135. package/dist/public/assets/_apOz5w70.js.br +0 -0
  136. package/dist/public/assets/{_BPzHoTu3.js → _bnyHmBSB.js} +1 -1
  137. package/dist/public/assets/_bnyHmBSB.js.br +0 -0
  138. package/dist/public/assets/{_CqmPWoAp2.js → _cEH-PUtq2.js} +1 -1
  139. package/dist/public/assets/_cEH-PUtq2.js.br +0 -0
  140. package/dist/public/assets/{_C1uG69PI.js → _dqrrRyjM.js} +1 -1
  141. package/dist/public/assets/_dqrrRyjM.js.br +0 -0
  142. package/dist/public/assets/{_DbJRI9_H.js → _eKiwGFGI.js} +1 -1
  143. package/dist/public/assets/_eKiwGFGI.js.br +0 -0
  144. package/dist/public/assets/{_e1lYvQAo2.js → _iIzVA4u72.js} +1 -1
  145. package/dist/public/assets/_iIzVA4u72.js.br +0 -0
  146. package/dist/public/assets/{_DS7FwF-J.js → _iTZwOiw8.js} +1 -1
  147. package/dist/public/assets/_iTZwOiw8.js.br +0 -0
  148. package/dist/public/assets/{_BnN7B1Mb.js → _nYIFwHU2.js} +1 -1
  149. package/dist/public/assets/_nYIFwHU2.js.br +0 -0
  150. package/dist/public/assets/{_Z_Oh39Jb.js → _qriUiiqP.js} +1 -1
  151. package/dist/public/assets/_qriUiiqP.js.br +0 -0
  152. package/dist/public/assets/{_BYRkkQxk.js → _qsL2FxXl.js} +1 -1
  153. package/dist/public/assets/_qsL2FxXl.js.br +0 -0
  154. package/dist/public/assets/{_BculF-XV.js → _wqvH6a9w.js} +1 -1
  155. package/dist/public/assets/diff-view-C8mNAKSm.css +1 -0
  156. package/dist/public/assets/diff-view-C8mNAKSm.css.br +0 -0
  157. package/dist/public/assets/index-7WlgwCwh.css +1 -0
  158. package/dist/public/assets/index-7WlgwCwh.css.br +0 -0
  159. package/dist/public/assets/index-BffJzCDz.js +86 -0
  160. package/dist/public/assets/index-BffJzCDz.js.br +0 -0
  161. package/dist/public/assets/{preload-helper-Cioq5Qre.css → preload-helper-EAZGOO6u.css} +1 -1
  162. package/dist/public/assets/preload-helper-EAZGOO6u.css.br +0 -0
  163. package/package.json +1 -2
  164. package/scripts/migrate.mjs +93 -0
  165. package/dist/_L15vvgS1.js +0 -2
  166. package/dist/public/assets/_2By3R--W2.js.br +0 -0
  167. package/dist/public/assets/_4aAs0pvU.js.br +0 -0
  168. package/dist/public/assets/_B7T2AE8L.js.br +0 -0
  169. package/dist/public/assets/_BA7PhURg.js.br +0 -0
  170. package/dist/public/assets/_BAQFHOGb.js.br +0 -0
  171. package/dist/public/assets/_BBEMecyM2.js.br +0 -0
  172. package/dist/public/assets/_BBXJK7fW.js.br +0 -0
  173. package/dist/public/assets/_BBdsdafe2.js.br +0 -0
  174. package/dist/public/assets/_BCTR0wV0.js.br +0 -0
  175. package/dist/public/assets/_BNDbFEJj.js.br +0 -0
  176. package/dist/public/assets/_BPvgcQ_P.js.br +0 -0
  177. package/dist/public/assets/_BPzHoTu3.js.br +0 -0
  178. package/dist/public/assets/_BRP9V2vY.js.br +0 -0
  179. package/dist/public/assets/_BRV26aAF.js.br +0 -0
  180. package/dist/public/assets/_BYRkkQxk.js.br +0 -0
  181. package/dist/public/assets/_BaIOx6992.js.br +0 -0
  182. package/dist/public/assets/_Bd7b48iJ.js.br +0 -0
  183. package/dist/public/assets/_BdiO50aC2.js.br +0 -0
  184. package/dist/public/assets/_BkeFq1dG2.js.br +0 -0
  185. package/dist/public/assets/_BnN7B1Mb.js.br +0 -0
  186. package/dist/public/assets/_Bnp1UtCp2.js.br +0 -0
  187. package/dist/public/assets/_BqdeosKn.js.br +0 -0
  188. package/dist/public/assets/_Bt3B1aEu2.js.br +0 -0
  189. package/dist/public/assets/_C1uG69PI.js.br +0 -0
  190. package/dist/public/assets/_C2OfA6BZ.js.br +0 -0
  191. package/dist/public/assets/_C9UHqcOT2.js.br +0 -0
  192. package/dist/public/assets/_CAP_5S-t.js.br +0 -0
  193. package/dist/public/assets/_CIVAj2XC.js.br +0 -0
  194. package/dist/public/assets/_CJ4aiC36.js.br +0 -0
  195. package/dist/public/assets/_CL84pok8.js.br +0 -0
  196. package/dist/public/assets/_CMmwGR_Q.js.br +0 -0
  197. package/dist/public/assets/_CQ3pD5r12.js.br +0 -0
  198. package/dist/public/assets/_CQRG1j1X.js.br +0 -0
  199. package/dist/public/assets/_CasdikBZ2.js.br +0 -0
  200. package/dist/public/assets/_CcjW-l5T.js.br +0 -0
  201. package/dist/public/assets/_CjrYQPNO.js.br +0 -0
  202. package/dist/public/assets/_CqmPWoAp2.js.br +0 -0
  203. package/dist/public/assets/_D0PcbpPB.js.br +0 -0
  204. package/dist/public/assets/_D0en76Ej.js.br +0 -0
  205. package/dist/public/assets/_D0ljGGvp2.js.br +0 -0
  206. package/dist/public/assets/_D2sFNldb.js.br +0 -0
  207. package/dist/public/assets/_D5BjTqU42.js.br +0 -0
  208. package/dist/public/assets/_DAVDeGoR.js.br +0 -0
  209. package/dist/public/assets/_DA_t7MOs2.js.br +0 -0
  210. package/dist/public/assets/_DIezl6EI.js.br +0 -0
  211. package/dist/public/assets/_DJAJCWgm.js.br +0 -0
  212. package/dist/public/assets/_DS7FwF-J.js.br +0 -0
  213. package/dist/public/assets/_DY4GR3La.js.br +0 -0
  214. package/dist/public/assets/_DZtm6WF2.js.br +0 -0
  215. package/dist/public/assets/_D_EzfDaC.js.br +0 -0
  216. package/dist/public/assets/_DaTkOx5R.js.br +0 -0
  217. package/dist/public/assets/_DbJRI9_H.js.br +0 -0
  218. package/dist/public/assets/_DbbVTGR82.js.br +0 -0
  219. package/dist/public/assets/_DbnzsP9f.js.br +0 -0
  220. package/dist/public/assets/_Dkmb-8CU.js.br +0 -0
  221. package/dist/public/assets/_DoaHBjpa.js.br +0 -0
  222. package/dist/public/assets/_DtMzVsHW2.js.br +0 -0
  223. package/dist/public/assets/_DucRMQLL2.js.br +0 -0
  224. package/dist/public/assets/_DvsUo16D2.js.br +0 -0
  225. package/dist/public/assets/_Dyejz2MQ.js.br +0 -0
  226. package/dist/public/assets/_E5DvansN.js.br +0 -0
  227. package/dist/public/assets/_FT8jstIj.js.br +0 -0
  228. package/dist/public/assets/_Tou5xDB12.js.br +0 -0
  229. package/dist/public/assets/_U0PVI62V.js.br +0 -0
  230. package/dist/public/assets/_ZLwlH_XK.js.br +0 -0
  231. package/dist/public/assets/_Z_Oh39Jb.js.br +0 -0
  232. package/dist/public/assets/__OpDUxvR.js.br +0 -0
  233. package/dist/public/assets/__UTjMwX3.js.br +0 -0
  234. package/dist/public/assets/_dAPOyRJr.js.br +0 -0
  235. package/dist/public/assets/_e1lYvQAo2.js.br +0 -0
  236. package/dist/public/assets/_ePAxCx7r.js.br +0 -0
  237. package/dist/public/assets/_jDukN6_E2.js.br +0 -0
  238. package/dist/public/assets/_jmw7zbFI2.js.br +0 -0
  239. package/dist/public/assets/diff-view-sXFdzozK.css +0 -1
  240. package/dist/public/assets/diff-view-sXFdzozK.css.br +0 -0
  241. package/dist/public/assets/index-DKRkgwLo.js +0 -86
  242. package/dist/public/assets/index-DKRkgwLo.js.br +0 -0
  243. package/dist/public/assets/index-c70b3ZMB.css +0 -1
  244. package/dist/public/assets/index-c70b3ZMB.css.br +0 -0
  245. package/dist/public/assets/preload-helper-Cioq5Qre.css.br +0 -0
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM, r as __exportAll, t as __commonJSMin } from "./_BMI-E3GI.js";
2
- import { A as git, B as config, C as AGENTS, D as setSetting, E as setPref, F as subscriberCount, I as all, L as db, M as tmux, N as publish, O as TMUX_SOCKET, P as subscribe, R as get, S as saveSubscription, T as preferredAgent, _ as setScrapedPhase, a as killSession, b as deleteSubscription, c as newSessionArgs, d as renameSession, f as sendToSession, g as setAgentPhase, h as clearAgentPhase, i as getSession, j as run, k as gh, m as tmuxName, n as createSession, o as killWorkspaceSessions, p as sessionStates, r as ensureTmuxServer, s as listSessions, t as cleanEnv, u as panePids, v as setSessionViewers, w as allPrefs, x as pushPublicKey, y as summaryFromHookPayload, z as workspacePath } from "./_Cja4R2gP.js";
3
- import { $ as _subscribe, A as _el_resume, B as _peek_scope_id, C as _attr_style, D as _dynamic_tag, E as _content_resume, F as _hoist, G as _scope_with_id, H as _resume_branch, I as _hoist_read_error, J as _serialize_guard, K as _script, L as _html, M as _existing_scope, N as _flush_head, P as _for_of, Q as _show_start, R as _id, S as _attr_select_value, T as _content, U as _scope_id, V as _resume, W as _scope_reason, X as _set_serialize_reason, Y as _serialize_if, Z as _show_end, _ as _attr, at as attrTag, b as _attr_input_value, c as sideNavOpen, d as icon_base_default, et as _template, f as fuzzy, g as $global, h as phase, i as icon_sidebar_default, it as _var, j as _escape, k as _el_read_error, l as workspaceTab, m as toast_default, n as findIconBtn, nt as _trailers, ot as withPageAssets, p as rankRepos, q as _sep, r as findInput, rt as _try, s as setWorkspaceTab, st as writeScope, tt as _to_text, u as icon_refresh_default, v as _attr_class, w as _await, x as _attr_option_value, z as _if } from "./_B6irorCp.js";
2
+ import { A as TMUX_SOCKET, B as db, C as pushPublicKey, D as preferredAgent, E as allPrefs, F as publish, H as workspacePath, I as subscribe, L as subscriberCount, M as git, N as run, O as setPref, P as tmux, R as subscriberJoins, S as deleteSubscription, T as AGENTS, U as config, V as get, _ as reasonFromHookPayload, a as killSession, b as setSessionViewers, c as newSessionArgs, d as renameSession, f as sendToSession, g as clearAgentPhase, h as reportsWorking, i as getSession, j as gh, k as setSetting, m as tmuxName, n as createSession, o as killWorkspaceSessions, p as sessionStates, r as ensureTmuxServer, s as listSessions, t as cleanEnv, u as panePids, v as setAgentPhase, w as saveSubscription, x as summaryFromHookPayload, y as setScrapedPhase, z as all } from "./_P9IsUQm2.js";
3
+ import { $ as _subscribe, A as _el_resume, B as _peek_scope_id, C as _attr_style, D as _dynamic_tag, E as _content_resume, F as _hoist, G as _scope_with_id, H as _resume_branch, I as _hoist_read_error, J as _serialize_guard, K as _script, L as _html, M as _existing_scope, N as _flush_head, P as _for_of, Q as _show_start, R as _id, S as _attr_select_value, T as _content, U as _scope_id, V as _resume, W as _scope_reason, X as _set_serialize_reason, Y as _serialize_if, Z as _show_end, _ as _attr, at as attrTag, b as _attr_input_value, c as sideNavOpen, d as icon_base_default, et as _template, f as fuzzy, g as $global, h as phase, i as icon_sidebar_default, it as _var, j as _escape, k as _el_read_error, l as workspaceTab, m as toast_default, n as findIconBtn, nt as _trailers, ot as withPageAssets, p as rankRepos, q as _sep, r as findInput, rt as _try, s as setWorkspaceTab, st as writeScope, tt as _to_text, u as icon_refresh_default, v as _attr_class, w as _await, x as _attr_option_value, z as _if } from "./_CWl3Ch5X.js";
4
4
  import fs from "node:fs";
5
5
  import { createServer } from "node:http";
6
6
  import path from "node:path";
@@ -1958,6 +1958,46 @@ async function workspaceBranches(bare, branch, exclude) {
1958
1958
  "refs/heads/"
1959
1959
  ], bare).catch(() => "")).split("\n").filter((b) => ownsBranch(b, branch) && !exclude.some((x) => ownsBranch(b, x)));
1960
1960
  }
1961
+ /** Delete a finished lane's local branch from the shared bare cache.
1962
+ *
1963
+ * Only a `-topic` lane, never the workspace branch itself: that one is
1964
+ * reused for the next change, so it outlives every PR opened from it.
1965
+ *
1966
+ * `headOid` is the finished PR's own head commit, and the local tip has to
1967
+ * still be sitting on it. That is what separates "this branch is the PR you
1968
+ * just finished with" from "this branch has commits you never pushed" — the
1969
+ * former stays reachable through the PR on GitHub (`refs/pull/N/head`
1970
+ * outlives both the merge and the branch, so a closed-unmerged lane is as
1971
+ * recoverable as a merged one), the latter would be gone for good. The
1972
+ * remote ref is not the test: GitHub prunes it on merge exactly when
1973
+ * pruning is safest.
1974
+ *
1975
+ * `-D` rather than `-d` because a squash-merged lane is not an ancestor of
1976
+ * its base, so git cannot see the merge that GitHub reports. It is also
1977
+ * what refuses when the lane is still checked out in a worktree — that
1978
+ * returns false rather than raising, a lane you are standing on being a
1979
+ * reason to keep it, not an error. */
1980
+ async function pruneLaneBranch(workspaceId, fullName, lane, headOid) {
1981
+ const ws = getWorkspace(workspaceId);
1982
+ if (!ws || !headOid || lane === ws.branch) return false;
1983
+ if (!ownsBranch(lane, ws.branch)) return false;
1984
+ if (otherWorkspaceBranches(workspaceId).some((b) => ownsBranch(lane, b))) return false;
1985
+ if (!ws.repos.some((r) => r.full_name === fullName)) return false;
1986
+ return withRepoLock(fullName, async () => {
1987
+ const bare = barePath(fullName);
1988
+ const local = await git([
1989
+ "rev-parse",
1990
+ "--verify",
1991
+ `refs/heads/${lane}`
1992
+ ], bare).catch(() => "");
1993
+ if (!local || local !== headOid) return false;
1994
+ return git([
1995
+ "branch",
1996
+ "-D",
1997
+ lane
1998
+ ], bare).then(() => true, () => false);
1999
+ });
2000
+ }
1961
2001
  /** Directory/branch-safe prefix for a workspace name. Decomposing first keeps
1962
2002
  * accented Latin readable (é → e); a name with nothing ASCII left (another
1963
2003
  * script, emoji) falls back to a generic prefix — the random id is what makes
@@ -2118,10 +2158,7 @@ function swr(ttlMs, load, seed) {
2118
2158
  }
2119
2159
  //#endregion
2120
2160
  //#region src/server/prs.ts
2121
- var PR_JSON = "number,title,url,headRefName,baseRefName,headRefOid,isDraft,state";
2122
2161
  var TTL_MS$3 = 12e4;
2123
- /** PRs in every state for a repo, stale-while-revalidate cached. */
2124
- var prs = swr(TTL_MS$3, fetchPrs);
2125
2162
  /** PRs whose head is the workspace branch or one of its `-topic` lanes.
2126
2163
  * `exclude` lists other workspaces' branches — slugs are user-chosen, so
2127
2164
  * another workspace's branch can extend this prefix and its PRs must not
@@ -2130,51 +2167,21 @@ function prsForBranchPrefix(prs, prefix, exclude = []) {
2130
2167
  const owns = (ref, b) => ref === b || ref.startsWith(`${b}-`);
2131
2168
  return prs.filter((pr) => owns(pr.headRefName, prefix) && !exclude.some((x) => owns(pr.headRefName, x)));
2132
2169
  }
2133
- /** Exact head-branch lookup. The windowed lists below (100 most recently
2134
- * created / 50 most recently updated) lose an older workspace PR on a
2135
- * busy repo, so the workspace branch itself is always queried directly.
2136
- * Lane branches (`-topic`) are actively worked and stay inside the
2137
- * windows. Key: `fullName#branch`. */
2138
- var headPrs = swr(TTL_MS$3, async (key) => {
2170
+ var branchKey = (fullName, branch) => `${fullName}#${branch}`;
2171
+ /** One workspace's PRs in one repo its branch and every `-topic` lane, in
2172
+ * every state. Asking for the workspace's own branches is what keeps this
2173
+ * proportional to the workspace rather than to the repo: the alternative,
2174
+ * a recency window over all of a repo's PRs, fetched roughly twice what it
2175
+ * kept here and still aged a quiet workspace out on a busy repo.
2176
+ * Key: `fullName#branch`. */
2177
+ var branchPrs = swr(TTL_MS$3, (key, refresh) => {
2139
2178
  const sep = key.indexOf("#");
2140
- const fullName = key.slice(0, sep);
2141
- const branch = key.slice(sep + 1);
2142
- return repoPrs(fullName, 20, [
2143
- "pr",
2144
- "list",
2145
- "--repo",
2146
- fullName,
2147
- "--head",
2148
- branch,
2149
- "--state",
2150
- "all",
2151
- "--limit",
2152
- "20",
2153
- "--json",
2154
- PR_JSON
2155
- ], branch);
2179
+ return searchPrs([key.slice(0, sep)], [key.slice(sep + 1)], refresh);
2156
2180
  });
2157
- /** A workspace repo's PRs: the recency-windowed list filtered to the
2158
- * branch prefix, plus the exact-head lookup merged in. */
2181
+ /** A workspace repo's PRs, minus any belonging to a workspace whose branch
2182
+ * extends this one's. */
2159
2183
  async function workspacePrs(fullName, branch, foreign, refresh = false) {
2160
- const [windowed, exact] = await Promise.all([prs(fullName, refresh), headPrs(`${fullName}#${branch}`, refresh)]);
2161
- const list = prsForBranchPrefix(windowed, branch, foreign);
2162
- for (const pr of prsForBranchPrefix(exact, branch, foreign)) if (!list.some((p) => p.number === pr.number)) list.push(pr);
2163
- return list;
2164
- }
2165
- async function fetchPrs(fullName) {
2166
- return repoPrs(fullName, 100, [
2167
- "pr",
2168
- "list",
2169
- "--repo",
2170
- fullName,
2171
- "--state",
2172
- "all",
2173
- "--limit",
2174
- "100",
2175
- "--json",
2176
- PR_JSON
2177
- ]);
2184
+ return prsForBranchPrefix(await branchPrs(branchKey(fullName, branch), refresh).catch(() => []), branch, foreign);
2178
2185
  }
2179
2186
  /** Refresh many repos' PRs with one GraphQL request (vs one `gh pr list`
2180
2187
  * process per repo) — called from the status watcher for active
@@ -2194,59 +2201,61 @@ function notePushActivity() {
2194
2201
  function inHotWindow() {
2195
2202
  return Date.now() < hotUntil;
2196
2203
  }
2197
- /** `headRefOid` is the PR's own head commit, which is what `gh pr list`
2198
- * reports and what the UI compares against. Reaching through `headRef` gets
2199
- * the branch's *current* tip instead — a different commit entirely once a
2200
- * workspace branch is reused, and `headRef { oid }` is not even a field, so
2201
- * GitHub answers 200 with an `errors` array and no `data`. */
2204
+ /** `headRefOid` is the PR's own head commit, which is what the UI compares
2205
+ * against. Reaching through `headRef` gets the branch's *current* tip
2206
+ * instead — a different commit entirely once a workspace branch is reused,
2207
+ * and `headRef { oid }` is not even a field, so GitHub answers 200 with an
2208
+ * `errors` array and no `data`. */
2202
2209
  var GQL_PR_FIELDS = "number title url headRefName baseRefName isDraft state headRefOid";
2203
- /** One repo's PRs, newest-created first the order `gh pr list` returns and
2204
- * that `prsForBranchPrefix`'s windowing assumes. */
2205
- function repoPrsQuery(fullName, first, headRefName) {
2206
- const [owner, name] = fullName.split("/");
2207
- const head = headRefName ? ` headRefName: ${JSON.stringify(headRefName)}` : "";
2208
- return `query { repository(owner: ${JSON.stringify(owner)}, name: ${JSON.stringify(name)}) { pullRequests(first: ${first}${head}, orderBy: {field: CREATED_AT, direction: DESC}) { nodes { ${GQL_PR_FIELDS} } } } }`;
2209
- }
2210
- /** GraphQL first, `gh` if that cannot be reached at all — a machine whose
2211
- * credential lives somewhere only `gh` knows about keeps working. */
2212
- async function repoPrs(fullName, first, ghArgs, headRefName) {
2213
- try {
2214
- return (await graphql(repoPrsQuery(fullName, first, headRefName))).repository?.pullRequests.nodes ?? [];
2215
- } catch {
2216
- const out = await gh(ghArgs).catch(() => "[]");
2217
- return JSON.parse(out);
2210
+ /** Search's `head:` matches a branch *and* its `-topic` lanes, so one term
2211
+ * covers a whole workspace, and repeated terms are OR'd within a qualifier
2212
+ * while different qualifiers are AND'd — `repo:a repo:b head:x head:y`
2213
+ * reads as (a|b) and (x|y). That is what lets every workspace share one
2214
+ * request instead of needing an alias per repo and per branch. */
2215
+ function searchTerms(repos, branches) {
2216
+ return [...repos.map((r) => `repo:${r}`), ...branches.map((b) => `head:${b}`)].join(" ");
2217
+ }
2218
+ /** Finished PRs are asked for by recency, open ones are not: a merged PR
2219
+ * only has to outlive its dismissal, while an open PR must stay visible
2220
+ * however long it has sat idle — which is exactly what a recency window
2221
+ * over the whole repo got wrong. */
2222
+ var CLOSED_FIRST = 60;
2223
+ var OPEN_FIRST = 100;
2224
+ /** Search pages at 100. Open PRs are the page that can genuinely overflow
2225
+ * (every workspace's, in one request), so it is followed — bounded, because
2226
+ * an unbounded follow is a way to hang the status tick on a bad query. */
2227
+ var MAX_OPEN_PAGES = 4;
2228
+ var searchField = (alias, query, first, after) => `${alias}: search(query: ${JSON.stringify(query)}, type: ISSUE, first: ${first}${after ? `, after: ${JSON.stringify(after)}` : ""}) { pageInfo { hasNextPage endCursor } nodes { ... on PullRequest { ${GQL_PR_FIELDS} repository { nameWithOwner } } } }`;
2229
+ /** Every PR on the given branches (and their lanes) across the given repos.
2230
+ * `refresh` is accepted for the swr signature; freshness here is GitHub's,
2231
+ * not ours. */
2232
+ async function searchPrs(repos, branches, _refresh) {
2233
+ const terms = searchTerms(repos, branches);
2234
+ const out = [];
2235
+ let cursor;
2236
+ for (let page = 0; page < MAX_OPEN_PAGES; page++) {
2237
+ const data = await graphql("query {" + searchField("open", `is:pr is:open ${terms}`, OPEN_FIRST, cursor) + (page === 0 ? " " + searchField("done", `is:pr is:closed sort:updated-desc ${terms}`, CLOSED_FIRST) : "") + "}");
2238
+ const open = data.open;
2239
+ const done = data.done;
2240
+ for (const node of [...open?.nodes ?? [], ...done?.nodes ?? []]) if (node?.number) out.push(node);
2241
+ if (!open?.pageInfo.hasNextPage || !open.pageInfo.endCursor) break;
2242
+ cursor = open.pageInfo.endCursor;
2218
2243
  }
2244
+ return out;
2219
2245
  }
2220
- async function refreshPrsBatch(fullNames, force = false) {
2221
- const names = [...new Set(fullNames)].filter((n) => n.includes("/"));
2246
+ async function refreshPrsBatch(targets, force = false) {
2247
+ const wanted = [...new Map(targets.filter((t) => t.fullName.includes("/") && t.branch).map((t) => [branchKey(t.fullName, t.branch), t])).values()];
2222
2248
  const minMs = force ? 2e3 : Date.now() < hotUntil ? HOT_MIN_MS : BATCH_MIN_MS;
2223
- if (!names.length || Date.now() - lastBatch < minMs) return false;
2249
+ if (!wanted.length || Date.now() - lastBatch < minMs) return false;
2224
2250
  const prevBatch = lastBatch;
2225
2251
  lastBatch = Date.now();
2226
2252
  try {
2227
- const query = "query {" + names.map((fullName, i) => {
2228
- const [owner, name] = fullName.split("/");
2229
- return `r${i}: repository(owner: ${JSON.stringify(owner)}, name: ${JSON.stringify(name)}) { pullRequests(first: 50, orderBy: {field: UPDATED_AT, direction: DESC}) { nodes { ${GQL_PR_FIELDS} } } }`;
2230
- }).join(" ") + "}";
2231
- const data = await graphql(query).catch(async (err) => {
2232
- const out = await gh([
2233
- "api",
2234
- "graphql",
2235
- "-f",
2236
- `query=${query}`
2237
- ]).catch((e) => {
2238
- if (!e.stdout) throw err;
2239
- return e.stdout;
2240
- });
2241
- const parsed = JSON.parse(out).data;
2242
- if (!parsed) throw err;
2243
- return parsed;
2244
- });
2245
- names.forEach((fullName, i) => {
2246
- const repo = data[`r${i}`];
2247
- if (!repo) return;
2248
- prs.set(fullName, repo.pullRequests.nodes);
2249
- });
2253
+ const nodes = await searchPrs([...new Set(wanted.map((t) => t.fullName))], [...new Set(wanted.map((t) => t.branch))]);
2254
+ const branches = [...new Set(wanted.map((t) => t.branch))];
2255
+ for (const target of wanted) {
2256
+ const foreign = branches.filter((b) => b !== target.branch);
2257
+ branchPrs.set(branchKey(target.fullName, target.branch), prsForBranchPrefix(nodes.filter((n) => n.repository.nameWithOwner === target.fullName), target.branch, foreign));
2258
+ }
2250
2259
  return true;
2251
2260
  } catch (err) {
2252
2261
  lastBatch = prevBatch;
@@ -2263,6 +2272,62 @@ function withoutDismissed(workspaceId, fullName, list) {
2263
2272
  return list.filter((pr) => pr.state === "OPEN" || !dismissed.has(pr.number));
2264
2273
  }
2265
2274
  //#endregion
2275
+ //#region src/server/git-refs.ts
2276
+ /** The checked-out commit of a worktree, read off disk instead of spawned.
2277
+ *
2278
+ * Every status tick needs this for every repo of every active workspace —
2279
+ * it is what tells an open review that an agent committed, since a local
2280
+ * commit reaches GitHub through nothing the app can be told about. As a
2281
+ * process per repo per tick that was the bulk of the git the server ran;
2282
+ * the same answer is three small file reads.
2283
+ *
2284
+ * `git` stays the authority for anything this cannot read confidently: a
2285
+ * ref backend it does not understand, a chain that does not end in an oid,
2286
+ * a layout it has never seen. Being slower is better than being wrong,
2287
+ * because the drift banner reads a stale oid as "your checkout differs
2288
+ * from the review". */
2289
+ async function headOid(dir) {
2290
+ return await readHead(dir).catch(() => "") || spawnHead(dir);
2291
+ }
2292
+ var spawnHead = (dir) => git(["rev-parse", "HEAD"], dir).catch(() => "");
2293
+ /** Both hash algorithms, since a repo may be SHA-256. */
2294
+ var OID = /^[0-9a-f]{40}(?:[0-9a-f]{24})?$/;
2295
+ /** A symref chain that runs this long is a loop, not a layout. */
2296
+ var MAX_HOPS = 5;
2297
+ async function readHead(dir) {
2298
+ const { gitDir, common } = await gitDirs(dir);
2299
+ if (await exists(path.join(common, "reftable"))) return "";
2300
+ let ref = (await fsp.readFile(path.join(gitDir, "HEAD"), "utf8")).trim();
2301
+ for (let hop = 0; ref.startsWith("ref: ") && hop < MAX_HOPS; hop++) {
2302
+ const name = ref.slice(5).trim();
2303
+ const loose = await read(path.join(gitDir, name)) ?? await read(path.join(common, name));
2304
+ if (loose !== void 0) {
2305
+ ref = loose.trim();
2306
+ continue;
2307
+ }
2308
+ const packed = await read(path.join(common, "packed-refs"));
2309
+ if (packed === void 0) return "";
2310
+ const line = packed.split("\n").find((l) => !l.startsWith("^") && l.endsWith(` ${name}`));
2311
+ if (!line) return "";
2312
+ ref = line.slice(0, line.indexOf(" "));
2313
+ }
2314
+ return OID.test(ref) ? ref : "";
2315
+ }
2316
+ /** A worktree's `.git` is a file pointing at its admin directory inside the
2317
+ * shared bare cache, which in turn points back at the common ref store. */
2318
+ async function gitDirs(dir) {
2319
+ const dotGit = path.join(dir, ".git");
2320
+ const gitDir = await isDir(dotGit) ? dotGit : path.resolve(dir, (await fsp.readFile(dotGit, "utf8")).replace(/^gitdir:/, "").trim());
2321
+ const commonRef = await read(path.join(gitDir, "commondir"));
2322
+ return {
2323
+ gitDir,
2324
+ common: commonRef ? path.resolve(gitDir, commonRef.trim()) : gitDir
2325
+ };
2326
+ }
2327
+ var read = (file) => fsp.readFile(file, "utf8").catch(() => void 0);
2328
+ var exists = (file) => fsp.stat(file).then(() => true, () => false);
2329
+ var isDir = (file) => fsp.stat(file).then((s) => s.isDirectory(), () => false);
2330
+ //#endregion
2266
2331
  //#region src/server/status.ts
2267
2332
  var TTL_MS$2 = 2e3;
2268
2333
  var snapshot = null;
@@ -2302,17 +2367,30 @@ var WATCH_MS = 1e4;
2302
2367
  * fast so the badge lands while it still feels immediate. */
2303
2368
  var WATCH_HOT_MS = 4e3;
2304
2369
  var watching = false;
2305
- var lastPushed = "";
2370
+ /** Last published state per workspace, so a tick can publish the ones that
2371
+ * actually moved. Comparing the whole snapshot instead meant one agent's
2372
+ * commit — or any session, port or PR flip in a workspace nobody is
2373
+ * looking at — pushed every workspace to every client, which each then
2374
+ * re-rendered and re-fingerprinted to conclude nothing of theirs had
2375
+ * changed. That amplification grows with the number of workspaces. */
2376
+ var lastPushed = /* @__PURE__ */ new Map();
2377
+ var lastJoins = -1;
2306
2378
  async function watchTick() {
2307
2379
  if (!subscriberCount()) return;
2308
2380
  try {
2309
- if (await refreshPrsBatch(activeRepoNames()).catch(() => false)) invalidateSnapshot();
2381
+ if (await refreshPrsBatch(activeRepoTargets()).catch(() => false)) invalidateSnapshot();
2310
2382
  const value = await statusForAll();
2311
- const json = JSON.stringify(value);
2312
- if (json !== lastPushed) {
2313
- lastPushed = json;
2314
- publish("status.changed", value);
2315
- }
2383
+ const joins = subscriberJoins();
2384
+ const everything = joins !== lastJoins;
2385
+ lastJoins = joins;
2386
+ const changed = {};
2387
+ for (const [id, ws] of Object.entries(value)) {
2388
+ const json = JSON.stringify(ws);
2389
+ if (everything || lastPushed.get(id) !== json) changed[id] = ws;
2390
+ lastPushed.set(id, json);
2391
+ }
2392
+ for (const id of lastPushed.keys()) if (!(id in value)) lastPushed.delete(id);
2393
+ if (Object.keys(changed).length) publish("status.changed", changed);
2316
2394
  } catch {}
2317
2395
  }
2318
2396
  var watchTimer;
@@ -2340,14 +2418,20 @@ function startStatusWatch() {
2340
2418
  watching = true;
2341
2419
  scheduleTick(WATCH_MS);
2342
2420
  }
2343
- function activeRepoNames() {
2344
- return listWorkspaces().filter((ws) => ws.status === "active").flatMap((ws) => ws.repos.map((r) => r.full_name));
2421
+ /** Every active workspace's repos, paired with the branch that workspace
2422
+ * works on the batch refreshes both the recency window and the exact-head
2423
+ * lookup for each, in one request. */
2424
+ function activeRepoTargets() {
2425
+ return listWorkspaces().filter((ws) => ws.status === "active").flatMap((ws) => ws.repos.map((r) => ({
2426
+ fullName: r.full_name,
2427
+ branch: ws.branch
2428
+ })));
2345
2429
  }
2346
2430
  /** Status with PRs refetched first (throttled): a client returning to the
2347
2431
  * foreground wants current PR state — merges/closes happen on GitHub and
2348
2432
  * send no local signal, so without this they wait out the slow poll. */
2349
2433
  async function statusForAllFresh() {
2350
- if (await refreshPrsBatch(activeRepoNames(), true).catch(() => false)) invalidateSnapshot();
2434
+ if (await refreshPrsBatch(activeRepoTargets(), true).catch(() => false)) invalidateSnapshot();
2351
2435
  return statusForAll();
2352
2436
  }
2353
2437
  /** RSS here is the Node + Marko baseline (~80 MB empty, ~115 MB loaded),
@@ -2373,7 +2457,7 @@ async function computeStatus() {
2373
2457
  }
2374
2458
  async function repoStatus(ws, repo, foreign) {
2375
2459
  const dir = path.join(ws.path, repo.worktree);
2376
- const [repoPrs, localHead] = await Promise.all([workspacePrs(repo.full_name, ws.branch, foreign).then((list) => withoutDismissed(ws.id, repo.full_name, list)), git(["rev-parse", "HEAD"], dir).catch(() => "")]);
2460
+ const [repoPrs, localHead] = await Promise.all([workspacePrs(repo.full_name, ws.branch, foreign).then((list) => withoutDismissed(ws.id, repo.full_name, list)), headOid(dir)]);
2377
2461
  return {
2378
2462
  full_name: repo.full_name,
2379
2463
  worktree: repo.worktree,
@@ -2679,17 +2763,17 @@ var palette_default = _template("o", (input) => {
2679
2763
  _if(() => {
2680
2764
  if (!input.inline) {
2681
2765
  const $scope5_id = _scope_id();
2682
- _html(`<div${_attr_class("_V")}></div>${_el_resume($scope5_id, "a")}`);
2766
+ _html(`<div${_attr_class("_bo")}></div>${_el_resume($scope5_id, "a")}`);
2683
2767
  _script($scope5_id, "o4");
2684
2768
  writeScope($scope5_id, {});
2685
2769
  return 0;
2686
2770
  }
2687
2771
  }, $scope0_id, "a", $sg__input_inline, $sg__input_inline, 1, 0, 1);
2688
- _html(`<div${_attr_class(["_X", { ["_W"]: input.inline }])} data-palette${input.inline ? " data-inline" : ""} role=dialog aria-label=Workspaces>`);
2772
+ _html(`<div${_attr_class(["_bq", { ["_bp"]: input.inline }])} data-palette${input.inline ? " data-inline" : ""} role=dialog aria-label=Workspaces>`);
2689
2773
  _if(() => {
2690
2774
  if (input.inline && !input.workspaces.length) {
2691
2775
  const $scope8_id = _scope_id();
2692
- _html(`<div${_attr_class("_5")}><p${_attr_class("_bg")}>A <strong>workspace</strong> checks out one or more repos as git worktrees on a shared branch and gives each agent session its own terminal. Create one to get started.</p><p${_attr_class("_bg")}>Pick your preferred agent below — new sessions and the quick-create button use it. GitHub access uses your <code>gh</code> login.</p></div>`);
2776
+ _html(`<div${_attr_class("_by")}><p${_attr_class("_bK")}>A <strong>workspace</strong> checks out one or more repos as git worktrees on a shared branch and gives each agent session its own terminal. Create one to get started.</p><p${_attr_class("_bK")}>Pick your preferred agent below — new sessions and the quick-create button use it. GitHub access uses your <code>gh</code> login.</p></div>`);
2693
2777
  _serialize_if($scope0_reason, 0) && writeScope($scope8_id, {});
2694
2778
  return 0;
2695
2779
  }
@@ -2697,33 +2781,33 @@ var palette_default = _template("o", (input) => {
2697
2781
  _html(`<input${_attr_input_value($scope0_id, "d", query || "", _resume(function(v) {
2698
2782
  query = v;
2699
2783
  hiRaw = 0;
2700
- }, "o0", $scope0_id))}${_attr_class("_be")} autofocus placeholder="Jump to workspace…" aria-label="Filter workspaces">${_el_resume($scope0_id, "d")}<ul${_attr_class(["_Y", !input.inline && "_bf"])}>`);
2784
+ }, "o0", $scope0_id))}${_attr_class("_bI")} autofocus placeholder="Jump to workspace…" aria-label="Filter workspaces">${_el_resume($scope0_id, "d")}<ul${_attr_class(["_br", !input.inline && "_bJ"])}>`);
2701
2785
  _for_of(rows$1, (row$1, i) => {
2702
2786
  const $scope1_id = _scope_id();
2703
- _html(`<li><div${_attr_class("_Z")}><button${_attr_class(["_2", {
2704
- ["_1"]: i === hi,
2705
- ["_0"]: row$1.kind === "ws" && row$1.archived
2787
+ _html(`<li><div${_attr_class("_bs")}><button${_attr_class(["_bv", {
2788
+ ["_bu"]: i === hi,
2789
+ ["_bt"]: row$1.kind === "ws" && row$1.archived
2706
2790
  }])}>`);
2707
2791
  _if(() => {
2708
2792
  if (row$1.kind === "new") {
2709
2793
  const $scope10_id = _scope_id();
2710
- _html(`<span${_attr_class("_6")}>+ New workspace</span>`);
2794
+ _html(`<span${_attr_class("_bz")}>+ New workspace</span>`);
2711
2795
  writeScope($scope10_id, {});
2712
2796
  return 0;
2713
2797
  } else if (row$1.kind === "cmd") {
2714
2798
  const $scope9_id = _scope_id();
2715
- _html(`<span${_attr_class(["_6", "_4"])}>▸ <!>${_escape(row$1.label)}${_el_resume($scope9_id, "b")}</span>`);
2799
+ _html(`<span${_attr_class(["_bz", "_bx"])}>▸ <!>${_escape(row$1.label)}${_el_resume($scope9_id, "b")}</span>`);
2716
2800
  writeScope($scope9_id, {});
2717
2801
  return 1;
2718
2802
  } else {
2719
2803
  const $scope2_id = _scope_id();
2720
2804
  const st = input.status[row$1.ws.id];
2721
2805
  const rowPrs = (st?.repos || []).flatMap((r) => r.prs || []);
2722
- _html(`<span${_attr_class("_6")}><span${_attr_class(["_q", phase[phaseOf(st)]])}></span>${_el_resume($scope2_id, "b")}<span${_attr_class("_7")}>${_escape(row$1.ws.name)}${_el_resume($scope2_id, "d")}</span>`);
2806
+ _html(`<span${_attr_class("_bz")}><span${_attr_class(["_q", phase[phaseOf(st)]])}></span>${_el_resume($scope2_id, "b")}<span${_attr_class("_bA")}>${_escape(row$1.ws.name)}${_el_resume($scope2_id, "d")}</span>`);
2723
2807
  _if(() => {
2724
2808
  if (row$1.ws.id === input.selectedId) {
2725
2809
  const $scope14_id = _scope_id();
2726
- _html(`<span${_attr_class(["_j", "_9"])}>open</span>`);
2810
+ _html(`<span${_attr_class(["_j", "_bC"])}>open</span>`);
2727
2811
  writeScope($scope14_id, {});
2728
2812
  return 0;
2729
2813
  }
@@ -2736,11 +2820,11 @@ var palette_default = _template("o", (input) => {
2736
2820
  return 0;
2737
2821
  }
2738
2822
  }, $scope2_id, "f", 1, 1, 1, 0, 1);
2739
- _html(`<span${_attr_class("_8")}>`);
2823
+ _html(`<span${_attr_class("_bB")}>`);
2740
2824
  _if(() => {
2741
2825
  if (st?.agents) {
2742
2826
  const $scope11_id = _scope_id();
2743
- _html(`<span${_attr_class(["_j", "__"])}${_attr("title", `${st.agents} running session${st.agents === 1 ? "" : "s"}${st.working ? ` — ${st.working} working` : ""}${st.waiting ? ` — ${st.waiting} waiting on you` : ""}`)}>${_escape(st.agents)}${_el_resume($scope11_id, "b")}</span>${_el_resume($scope11_id, "a")}`);
2827
+ _html(`<span${_attr_class(["_j", "_bD"])}${_attr("title", `${st.agents} running session${st.agents === 1 ? "" : "s"}${st.working ? ` — ${st.working} working` : ""}${st.waiting ? ` — ${st.waiting} waiting on you` : ""}`)}>${_escape(st.agents)}${_el_resume($scope11_id, "b")}</span>${_el_resume($scope11_id, "a")}`);
2744
2828
  writeScope($scope11_id, {});
2745
2829
  return 0;
2746
2830
  }
@@ -2748,7 +2832,7 @@ var palette_default = _template("o", (input) => {
2748
2832
  _if(() => {
2749
2833
  if (rowPrs.length) {
2750
2834
  const $scope13_id = _scope_id();
2751
- _html(`<span${_attr_class(["_j", "__"])}${_attr("title", `${rowPrs.length} open PR${rowPrs.length === 1 ? "" : "s"}`)}>${_escape(rowPrs.length)}${_el_resume($scope13_id, "b")} PR<!>${rowPrs.length === 1 ? "" : "s"}${_el_resume($scope13_id, "c")}</span>${_el_resume($scope13_id, "a")}`);
2835
+ _html(`<span${_attr_class(["_j", "_bD"])}${_attr("title", `${rowPrs.length} open PR${rowPrs.length === 1 ? "" : "s"}`)}>${_escape(rowPrs.length)}${_el_resume($scope13_id, "b")} PR<!>${rowPrs.length === 1 ? "" : "s"}${_el_resume($scope13_id, "c")}</span>${_el_resume($scope13_id, "a")}`);
2752
2836
  writeScope($scope13_id, {});
2753
2837
  return 0;
2754
2838
  }
@@ -2756,12 +2840,12 @@ var palette_default = _template("o", (input) => {
2756
2840
  _if(() => {
2757
2841
  if ((st?.ports || []).length) {
2758
2842
  const $scope12_id = _scope_id();
2759
- _html(`<span${_attr_class(["_j", "__"])}${_attr("title", st.ports.map((p) => `:${p.port} ${p.cmd}`).join("\n"))}>:<!>${_escape(st.ports.length)}${_el_resume($scope12_id, "b")}</span>${_el_resume($scope12_id, "a")}`);
2843
+ _html(`<span${_attr_class(["_j", "_bD"])}${_attr("title", st.ports.map((p) => `:${p.port} ${p.cmd}`).join("\n"))}>:<!>${_escape(st.ports.length)}${_el_resume($scope12_id, "b")}</span>${_el_resume($scope12_id, "a")}`);
2760
2844
  writeScope($scope12_id, {});
2761
2845
  return 0;
2762
2846
  }
2763
2847
  }, $scope2_id, "j", 1, 1, 1, 0, 1);
2764
- _html(`</span></span><span${_attr_class("_ba")}>`);
2848
+ _html(`</span></span><span${_attr_class("_bE")}>`);
2765
2849
  _for_of(st?.repos || row$1.ws.repos, (repo) => {
2766
2850
  const $scope16_id = _scope_id();
2767
2851
  _html(`<span${_attr_class("_o")}>${_escape(repo.worktree)}${_el_resume($scope16_id, "b")}</span>`);
@@ -2781,13 +2865,13 @@ var palette_default = _template("o", (input) => {
2781
2865
  _if(() => {
2782
2866
  if (row$1.kind === "ws") {
2783
2867
  const $scope3_id = _scope_id();
2784
- _html(`<button${_attr_class("_3")} title="Review changes">`);
2868
+ _html(`<button${_attr_class("_bw")} title="Review changes">`);
2785
2869
  icon_diff_default({ size: 13 });
2786
- _html(`</button>${_el_resume($scope3_id, "a")}<button${_attr_class("_3")} title="Manage workspace">`);
2870
+ _html(`</button>${_el_resume($scope3_id, "a")}<button${_attr_class("_bw")} title="Manage workspace">`);
2787
2871
  icon_manage_default({ size: 13 });
2788
2872
  const newPopId = _id();
2789
2873
  let pickerReady = false;
2790
- _html(`</button>${_el_resume($scope3_id, "c")}<button${_attr_class("_3")} title="New session"${_attr("popovertarget", newPopId)}>`);
2874
+ _html(`</button>${_el_resume($scope3_id, "c")}<button${_attr_class("_bw")} title="New session"${_attr("popovertarget", newPopId)}>`);
2791
2875
  icon_plus_default({ size: 13 });
2792
2876
  _html(`</button>${_el_resume($scope3_id, "e")}<div${_attr("id", newPopId)} popover=auto${_attr_class("_bM")}>`);
2793
2877
  _for_of([], (agent) => {
@@ -2828,13 +2912,13 @@ var palette_default = _template("o", (input) => {
2828
2912
  _if(() => {
2829
2913
  if (archived.length && !query) {
2830
2914
  const $scope7_id = _scope_id();
2831
- _html(`<button${_attr_class("_bd")}>${`archived (${_escape(`${archived.length}`)})`}${_el_resume($scope7_id, "b")}</button>${_el_resume($scope7_id, "a")}`);
2915
+ _html(`<button${_attr_class("_bH")}>${`archived (${_escape(`${archived.length}`)})`}${_el_resume($scope7_id, "b")}</button>${_el_resume($scope7_id, "a")}`);
2832
2916
  _script($scope7_id, "o8");
2833
2917
  writeScope($scope7_id, {});
2834
2918
  return 0;
2835
2919
  }
2836
2920
  }, $scope0_id, "f", 1, 1, 1, 0, 1);
2837
- _html(`<div${_attr_class("_bb")}><span></span><span${_attr_class("_bc")}>↑↓ navigate · ↵ open · ⌘1–9 switch · esc close</span>`);
2921
+ _html(`<div${_attr_class("_bF")}><span></span><span${_attr_class("_bG")}>↑↓ navigate · ↵ open · ⌘1–9 switch · esc close</span>`);
2838
2922
  _if(() => {
2839
2923
  if (settings) {
2840
2924
  const $scope6_id = _scope_id();
@@ -2850,7 +2934,7 @@ var palette_default = _template("o", (input) => {
2850
2934
  body: JSON.stringify({ preferredAgent: v })
2851
2935
  }).catch(() => {});
2852
2936
  }, "o1", $scope6_id), () => {
2853
- _html(`<select${_attr_class("_bh")} aria-label="Preferred agent">`);
2937
+ _html(`<select${_attr_class("_bL")} aria-label="Preferred agent">`);
2854
2938
  _for_of(settings.agents, (agent) => {
2855
2939
  const $scope17_id = _scope_id();
2856
2940
  _html(`<option${_attr_option_value(agent)}>${_escape(agent)}${_el_resume($scope17_id, "b")}</option>${_el_resume($scope17_id, "a")}`);
@@ -2911,8 +2995,8 @@ var palette_default = _template("o", (input) => {
2911
2995
  });
2912
2996
  //#endregion
2913
2997
  //#region src/tags/new-workspace.css.ts
2914
- var content$2 = "_bi _O";
2915
- var iconBtn$3 = "_bl _y";
2998
+ var content$2 = "_V _O";
2999
+ var iconBtn$3 = "_Y _y";
2916
3000
  //#endregion
2917
3001
  //#region src/tags/repo-picker.marko
2918
3002
  var api$6;
@@ -2962,14 +3046,14 @@ var repo_picker_default = _template("q", (input) => {
2962
3046
  input.onError?.(String(err.message || err));
2963
3047
  }
2964
3048
  }, "q5", $scope0_id);
2965
- _html(`<div${_attr_class("_cr")}><input${_attr_input_value($scope0_id, "b", filter, _resume(function(v) {
3049
+ _html(`<div${_attr_class("_bZ")}><input${_attr_input_value($scope0_id, "b", filter, _resume(function(v) {
2966
3050
  filter = v;
2967
3051
  highlight = 0;
2968
- }, "q0", $scope0_id))}${_attr_class("_cD")} placeholder="Add a repo…" aria-label="Add a repo"${_attr("disabled", input.disabled)}>${_el_resume($scope0_id, "b")}`);
3052
+ }, "q0", $scope0_id))}${_attr_class("_ca")} placeholder="Add a repo…" aria-label="Add a repo"${_attr("disabled", input.disabled)}>${_el_resume($scope0_id, "b")}`);
2969
3053
  _if(() => {
2970
3054
  if (filter && !catalog) {
2971
3055
  const $scope8_id = _scope_id();
2972
- _html(`<p${_attr_class("_cC")}>Loading repos…</p>`);
3056
+ _html(`<p${_attr_class("_b_")}>Loading repos…</p>`);
2973
3057
  writeScope($scope8_id, {});
2974
3058
  return 0;
2975
3059
  }
@@ -2977,23 +3061,23 @@ var repo_picker_default = _template("q", (input) => {
2977
3061
  _if(() => {
2978
3062
  if (results.length) {
2979
3063
  const $scope2_id = _scope_id();
2980
- _html(`<ul${_attr_class("_cs")}>`);
3064
+ _html(`<ul${_attr_class("_b0")}>`);
2981
3065
  _for_of(results, (repo, i) => {
2982
3066
  const $scope3_id = _scope_id();
2983
- _html(`<li><div${_attr_class(["_cu", { ["_ct"]: i === highlight }])}><button${_attr_class("_cv")}>`);
3067
+ _html(`<li><div${_attr_class(["_b2", { ["_b1"]: i === highlight }])}><button${_attr_class("_b3")}>`);
2984
3068
  icon_plus_default({
2985
3069
  size: 12,
2986
- class: "_cA"
3070
+ class: "_b8"
2987
3071
  });
2988
- _html(`<span${_attr_class("_cB")}>${_escape(repo.nameWithOwner)}${_el_resume($scope3_id, "e")}</span></button>${_el_resume($scope3_id, "b")}<button${_attr_class(["_cx", { ["_cw"]: branchesFor === repo.nameWithOwner }])}${_attr("title", `Pick a base branch for ${repo.nameWithOwner}`)}${_attr("aria-label", `Pick a base branch for ${repo.nameWithOwner}`)}>⎇</button>${_el_resume($scope3_id, "f")}</div>${_el_resume($scope3_id, "a")}`);
3072
+ _html(`<span${_attr_class("_b9")}>${_escape(repo.nameWithOwner)}${_el_resume($scope3_id, "e")}</span></button>${_el_resume($scope3_id, "b")}<button${_attr_class(["_b5", { ["_b4"]: branchesFor === repo.nameWithOwner }])}${_attr("title", `Pick a base branch for ${repo.nameWithOwner}`)}${_attr("aria-label", `Pick a base branch for ${repo.nameWithOwner}`)}>⎇</button>${_el_resume($scope3_id, "f")}</div>${_el_resume($scope3_id, "a")}`);
2989
3073
  _if(() => {
2990
3074
  if (branchesFor === repo.nameWithOwner) {
2991
3075
  const $scope4_id = _scope_id();
2992
- _html(`<div${_attr_class("_cy")}>`);
3076
+ _html(`<div${_attr_class("_b6")}>`);
2993
3077
  _if(() => {
2994
3078
  if (!branches) {
2995
3079
  const $scope9_id = _scope_id();
2996
- _html(`<p${_attr_class("_cC")}><span${_attr_class("_w")}></span> Loading branches…</p>`);
3080
+ _html(`<p${_attr_class("_b_")}><span${_attr_class("_w")}></span> Loading branches…</p>`);
2997
3081
  writeScope($scope9_id, {});
2998
3082
  return 0;
2999
3083
  } else {
@@ -3003,24 +3087,24 @@ var repo_picker_default = _template("q", (input) => {
3003
3087
  const $scope6_id = _scope_id();
3004
3088
  _html(`<input${_attr_input_value($scope6_id, "a", branchFilter, _resume((_new_branchFilter) => {
3005
3089
  branchFilter = _new_branchFilter;
3006
- }, "q1", $scope6_id))}${_attr_class("_cE")} placeholder="Filter branches…" aria-label="Filter branches" autofocus>${_el_resume($scope6_id, "a")}`);
3090
+ }, "q1", $scope6_id))}${_attr_class("_cb")} placeholder="Filter branches…" aria-label="Filter branches" autofocus>${_el_resume($scope6_id, "a")}`);
3007
3091
  _script($scope6_id, "q6");
3008
3092
  _subscribe($branchFilter__closures, writeScope($scope6_id, { Ca9: 1 }));
3009
3093
  return 0;
3010
3094
  }
3011
3095
  }, $scope5_id, "a", 1, 1, 1, 0, 1);
3012
3096
  const shown = (branchFilter ? branches.filter((b) => b.toLowerCase().includes(branchFilter.toLowerCase())) : branches).slice(0, 12);
3013
- _html(`<ul${_attr_class("_cz")}>`);
3097
+ _html(`<ul${_attr_class("_b7")}>`);
3014
3098
  _for_of(shown, (branch) => {
3015
3099
  const $scope7_id = _scope_id();
3016
- _html(`<li><button${_attr_class(["_cv", "_cF"])}><span${_attr_class(["_cB", "_o"])}>${_escape(branch)}${_el_resume($scope7_id, "c")}</span></button>${_el_resume($scope7_id, "a")}</li>`);
3100
+ _html(`<li><button${_attr_class(["_b3", "_cc"])}><span${_attr_class(["_b9", "_o"])}>${_escape(branch)}${_el_resume($scope7_id, "c")}</span></button>${_el_resume($scope7_id, "a")}</li>`);
3017
3101
  _script($scope7_id, "q7");
3018
3102
  writeScope($scope7_id, { e: branch });
3019
3103
  }, (b) => b, $scope5_id, "c", 1, 1, 1, 0, 1);
3020
3104
  _if(() => {
3021
3105
  if (!shown.length) {
3022
3106
  const $scope10_id = _scope_id();
3023
- _html(`<li><p${_attr_class("_cC")}>No branches match.</p></li>`);
3107
+ _html(`<li><p${_attr_class("_b_")}>No branches match.</p></li>`);
3024
3108
  writeScope($scope10_id, {});
3025
3109
  return 0;
3026
3110
  }
@@ -3045,7 +3129,7 @@ var repo_picker_default = _template("q", (input) => {
3045
3129
  return 0;
3046
3130
  } else if (filter && catalog) {
3047
3131
  const $scope1_id = _scope_id();
3048
- _html(`<p${_attr_class("_cC")}>No repos match "<!>${_escape(filter)}${_el_resume($scope1_id, "b")}".</p>`);
3132
+ _html(`<p${_attr_class("_b_")}>No repos match "<!>${_escape(filter)}${_el_resume($scope1_id, "b")}".</p>`);
3049
3133
  writeScope($scope1_id, {});
3050
3134
  return 1;
3051
3135
  }
@@ -3196,28 +3280,28 @@ var new_workspace_default = _template("m", (input) => {
3196
3280
  return 0;
3197
3281
  }
3198
3282
  }, $scope0_id, "h", 1, 1, 1, 0, 1);
3199
- _html(`<label${_attr_class("_bm")}><span${_attr_class("_bH")}>Name</span><input${_attr_input_value($scope0_id, "k", name, _resume((_new_name) => {
3283
+ _html(`<label${_attr_class("_Z")}><span${_attr_class("_bj")}>Name</span><input${_attr_input_value($scope0_id, "k", name, _resume((_new_name) => {
3200
3284
  name = _new_name;
3201
- }, "m0", $scope0_id))}${_attr_class("_bI")} placeholder=my-feature${_attr("disabled", busy)} autofocus>${_el_resume($scope0_id, "k")}</label><section${_attr_class("_bn")}><div${_attr_class("_bo")}><h2${_attr_class("_bJ")}>Repos</h2><button${_attr_class(iconBtn$3)} title="Refresh repo list" aria-label="Refresh repo list"${_attr("disabled", catalogRefreshing)}>`);
3285
+ }, "m0", $scope0_id))}${_attr_class("_bk")} placeholder=my-feature${_attr("disabled", busy)} autofocus>${_el_resume($scope0_id, "k")}</label><section${_attr_class("_0")}><div${_attr_class("_1")}><h2${_attr_class("_bl")}>Repos</h2><button${_attr_class(iconBtn$3)} title="Refresh repo list" aria-label="Refresh repo list"${_attr("disabled", catalogRefreshing)}>`);
3202
3286
  _set_serialize_reason(1);
3203
3287
  const $childScope = _peek_scope_id();
3204
3288
  icon_refresh_default({
3205
3289
  size: 14,
3206
3290
  class: catalogRefreshing && "_v"
3207
3291
  });
3208
- _html(`</button>${_el_resume($scope0_id, "o")}</div><ul${_attr_class("_bp")}>`);
3292
+ _html(`</button>${_el_resume($scope0_id, "o")}</div><ul${_attr_class("_2")}>`);
3209
3293
  _for_of(selected, (repo) => {
3210
3294
  const $scope1_id = _scope_id();
3211
- _html(`<li${_attr_class("_bq")}><span${_attr_class("_br")}>${_escape(repo.fullName)}${_el_resume($scope1_id, "c")}</span>`);
3295
+ _html(`<li${_attr_class("_3")}><span${_attr_class("_4")}>${_escape(repo.fullName)}${_el_resume($scope1_id, "c")}</span>`);
3212
3296
  _if(() => {
3213
3297
  if (repo.baseBranch) {
3214
3298
  const $scope8_id = _scope_id();
3215
- _html(`<span${_attr_class(["_bs", "_o"])} title="Base branch">⎇ <!>${_escape(repo.baseBranch)}${_el_resume($scope8_id, "b")}</span>`);
3299
+ _html(`<span${_attr_class(["_5", "_o"])} title="Base branch">⎇ <!>${_escape(repo.baseBranch)}${_el_resume($scope8_id, "b")}</span>`);
3216
3300
  writeScope($scope8_id, {});
3217
3301
  return 0;
3218
3302
  }
3219
3303
  }, $scope1_id, "d", 1, 1, 1, 0, 1);
3220
- _html(`<button${_attr_class("_bt")}${_attr("title", `Remove ${repo.fullName}`)}${_attr("disabled", busy)}>×</button>${_el_resume($scope1_id, "e")}</li>`);
3304
+ _html(`<button${_attr_class("_6")}${_attr("title", `Remove ${repo.fullName}`)}${_attr("disabled", busy)}>×</button>${_el_resume($scope1_id, "e")}</li>`);
3221
3305
  _script($scope1_id, "m11");
3222
3306
  writeScope($scope1_id, {
3223
3307
  h: repo?.fullName,
@@ -3227,7 +3311,7 @@ var new_workspace_default = _template("m", (input) => {
3227
3311
  _if(() => {
3228
3312
  if (!selected.length) {
3229
3313
  const $scope9_id = _scope_id();
3230
- _html(`<li${_attr_class("_bu")}>No repos yet — search below to add one (or create empty).</li>`);
3314
+ _html(`<li${_attr_class("_7")}>No repos yet — search below to add one (or create empty).</li>`);
3231
3315
  writeScope($scope9_id, {});
3232
3316
  return 0;
3233
3317
  }
@@ -3252,10 +3336,10 @@ var new_workspace_default = _template("m", (input) => {
3252
3336
  _if(() => {
3253
3337
  if (busy && steps$1.length) {
3254
3338
  const $scope6_id = _scope_id();
3255
- _html(`<ul${_attr_class("_bv")}>`);
3339
+ _html(`<ul${_attr_class("_8")}>`);
3256
3340
  _for_of(steps$1, (step$1, i) => {
3257
3341
  const $scope7_id = _scope_id();
3258
- _html(`<li${_attr_class(["_bK", { ["_bw"]: i === steps$1.length - 1 }])}>`);
3342
+ _html(`<li${_attr_class(["_bm", { ["_9"]: i === steps$1.length - 1 }])}>`);
3259
3343
  _if(() => {
3260
3344
  if (i === steps$1.length - 1) {
3261
3345
  const $scope10_id = _scope_id();
@@ -3264,7 +3348,7 @@ var new_workspace_default = _template("m", (input) => {
3264
3348
  return 0;
3265
3349
  } else {
3266
3350
  const $scope11_id = _scope_id();
3267
- _html(`<span${_attr_class("_bx")}>✓</span>`);
3351
+ _html(`<span${_attr_class("__")}>✓</span>`);
3268
3352
  writeScope($scope11_id, {});
3269
3353
  return 1;
3270
3354
  }
@@ -3276,19 +3360,19 @@ var new_workspace_default = _template("m", (input) => {
3276
3360
  return 0;
3277
3361
  }
3278
3362
  }, $scope0_id, "v", 1, 1, 1, 0, 1);
3279
- _html(`<div${_attr_class("_bj")}><button type=button${_attr_class(["_f", "_bL"])}${_attr("disabled", busy || !!restoring)}>Cancel</button>${_el_resume($scope0_id, "x")}<button type=button${_attr_class([
3363
+ _html(`<div${_attr_class("_W")}><button type=button${_attr_class(["_f", "_bn"])}${_attr("disabled", busy || !!restoring)}>Cancel</button>${_el_resume($scope0_id, "x")}<button type=button${_attr_class([
3280
3364
  "_f",
3281
3365
  "_g",
3282
- "_bk",
3283
- "_bL"
3366
+ "_X",
3367
+ "_bn"
3284
3368
  ])}${_attr("disabled", busy || !!restoring || !name.trim())}>${busy ? "Creating…" : "Create workspace"}${_el_resume($scope0_id, "z")}</button>${_el_resume($scope0_id, "y")}</div>`);
3285
3369
  _if(() => {
3286
3370
  if (archived$2.length) {
3287
3371
  const $scope2_id = _scope_id();
3288
- _html(`<section${_attr_class("_by")}><div${_attr_class("_bo")}><h2${_attr_class("_bJ")}>Archived</h2><span${_attr_class("_bz")}>${_escape(archived$2.length)}${_el_resume($scope2_id, "e", $sg__input_workspaces)}</span></div><p${_attr_class("_bA")}>Restore a parked space instead of creating a new one.</p><ul${_attr_class("_bB")}>`);
3372
+ _html(`<section${_attr_class("_ba")}><div${_attr_class("_1")}><h2${_attr_class("_bl")}>Archived</h2><span${_attr_class("_bb")}>${_escape(archived$2.length)}${_el_resume($scope2_id, "e", $sg__input_workspaces)}</span></div><p${_attr_class("_bc")}>Restore a parked space instead of creating a new one.</p><ul${_attr_class("_bd")}>`);
3289
3373
  _for_of(archived$2, (ws) => {
3290
3374
  const $scope3_id = _scope_id();
3291
- _html(`<li${_attr_class("_bC")}><div${_attr_class("_bD")}><span${_attr_class("_bE")}>${_escape(ws.name)}${_el_resume($scope3_id, "d", $sg__input_workspaces)}</span><span${_attr_class(["_bF", "_o"])}${_attr("title", ws.display_path || ws.path)}>${_escape(ws.display_path || ws.path)}${_el_resume($scope3_id, "f", $sg__input_workspaces)}</span>${_el_resume($scope3_id, "e", $sg__input_workspaces)}</div><button type=button${_attr_class(["_f", "_bG"])}${_attr("disabled", busy || !!restoring)}>`);
3375
+ _html(`<li${_attr_class("_be")}><div${_attr_class("_bf")}><span${_attr_class("_bg")}>${_escape(ws.name)}${_el_resume($scope3_id, "d", $sg__input_workspaces)}</span><span${_attr_class(["_bh", "_o"])}${_attr("title", ws.display_path || ws.path)}>${_escape(ws.display_path || ws.path)}${_el_resume($scope3_id, "f", $sg__input_workspaces)}</span>${_el_resume($scope3_id, "e", $sg__input_workspaces)}</div><button type=button${_attr_class(["_f", "_bi"])}${_attr("disabled", busy || !!restoring)}>`);
3292
3376
  _if(() => {
3293
3377
  if (restoring === ws.id) {
3294
3378
  const $scope12_id = _scope_id();
@@ -3410,8 +3494,8 @@ function vapidKey(base64) {
3410
3494
  const raw = atob(padded.replace(/-/g, "+").replace(/_/g, "/"));
3411
3495
  return Uint8Array.from(raw, (c) => c.charCodeAt(0));
3412
3496
  }
3413
- var iconBtn$2 = "_c8 _y";
3414
- var navToggle = "_db _y";
3497
+ var iconBtn$2 = "_c_ _y";
3498
+ var navToggle = "_dd _y";
3415
3499
  _template("C", (input) => {
3416
3500
  const $scope0_reason = _scope_reason(), $sg__input_size__OR__input_class = _serialize_guard($scope0_reason, 0);
3417
3501
  const $scope0_id = _scope_id();
@@ -3444,7 +3528,7 @@ var icon_gauge_default = _template("J", (input) => {
3444
3528
  });
3445
3529
  _serialize_if($scope0_reason, 0) && writeScope($scope0_id, { a: _existing_scope($childScope) });
3446
3530
  });
3447
- var railBtn = "_fz _y";
3531
+ var railBtn = "_fB _y";
3448
3532
  //#endregion
3449
3533
  //#region src/tags/icons/icon-edit.marko
3450
3534
  var icon_edit_default = _template("H", (input) => {
@@ -3462,12 +3546,12 @@ var icon_edit_default = _template("H", (input) => {
3462
3546
  });
3463
3547
  _serialize_if($scope0_reason, 0) && writeScope($scope0_id, { a: _existing_scope($childScope) });
3464
3548
  });
3465
- var prChip = "_fZ _j _fY";
3466
- var portChip = "_f0 _j _fY";
3549
+ var prChip = "_f1 _j _f0";
3550
+ var portChip = "_f2 _j _f0";
3467
3551
  var prState = {
3468
- open: "_f5",
3469
- merged: "_f6",
3470
- closed: "_f7"
3552
+ open: "_f7",
3553
+ merged: "_f8",
3554
+ closed: "_f9"
3471
3555
  };
3472
3556
  //#endregion
3473
3557
  //#region src/tags/icons/icon-xmark.marko
@@ -3531,7 +3615,7 @@ var side_nav_chips_default = _template("r", (input) => {
3531
3615
  const name = repo.full_name.split("/")[1];
3532
3616
  return repos.some((r) => r.full_name !== repo.full_name && r.full_name.split("/")[1] === name) ? repo.full_name : name;
3533
3617
  }, "r2", $scope1_id);
3534
- _html(`<div${_attr_class("_fX")}>`);
3618
+ _html(`<div${_attr_class("_fZ")}>`);
3535
3619
  _for_of(repos, (repo) => {
3536
3620
  const $scope2_id = _scope_id();
3537
3621
  _for_of(repo.prs || [], (pr) => {
@@ -3546,11 +3630,11 @@ var side_nav_chips_default = _template("r", (input) => {
3546
3630
  [prState.merged]: pr.state === "MERGED",
3547
3631
  [prState.closed]: pr.state === "CLOSED"
3548
3632
  }
3549
- ])}${_attr("title", prTitle(repo, pr))}><a${_attr_class(["_f1", { ["_f9"]: !open }])}${_attr("href", pr.url)} target=_blank rel=noopener>${_escape(repoLabel(repo))}${_el_resume($scope3_id, "c", $sg__input_status_repos)}#${_sep($sg__input_status_repos)}${_escape(pr.number)}${_el_resume($scope3_id, "d", $sg__input_status_repos)}</a>${_el_resume($scope3_id, "b", $sg__input_status_repos)}`);
3633
+ ])}${_attr("title", prTitle(repo, pr))}><a${_attr_class(["_f3", { ["_ga"]: !open }])}${_attr("href", pr.url)} target=_blank rel=noopener>${_escape(repoLabel(repo))}${_el_resume($scope3_id, "c", $sg__input_status_repos)}#${_sep($sg__input_status_repos)}${_escape(pr.number)}${_el_resume($scope3_id, "d", $sg__input_status_repos)}</a>${_el_resume($scope3_id, "b", $sg__input_status_repos)}`);
3550
3634
  _if(() => {
3551
3635
  if (open) {
3552
3636
  const $scope4_id = _scope_id();
3553
- _html(`<button type=button${_attr_class(["_f1", "_f2"])}${_attr("title", `Review #${pr.number} diff`)}>`);
3637
+ _html(`<button type=button${_attr_class(["_f3", "_f4"])}${_attr("title", `Review #${pr.number} diff`)}>`);
3554
3638
  icon_diff_default({ size: 12 });
3555
3639
  _html(`</button>${_el_resume($scope4_id, "a")}`);
3556
3640
  _script($scope4_id, "r3");
@@ -3559,9 +3643,9 @@ var side_nav_chips_default = _template("r", (input) => {
3559
3643
  } else {
3560
3644
  const $scope6_id = _scope_id();
3561
3645
  _html(`<button type=button${_attr_class([
3562
- "_f1",
3563
- "_f2",
3564
- "_f3"
3646
+ "_f3",
3647
+ "_f4",
3648
+ "_f5"
3565
3649
  ])}${_attr("title", `Clear #${pr.number} from this list`)}>`);
3566
3650
  icon_xmark_default({ size: 12 });
3567
3651
  _html(`</button>${_el_resume($scope6_id, "a")}`);
@@ -3585,11 +3669,11 @@ var side_nav_chips_default = _template("r", (input) => {
3585
3669
  }, "full_name", $scope1_id, "b", $sg__input_status_repos, $sg__input_status_repos, $sg__input_status_repos__OR__input_status_ports);
3586
3670
  _for_of(ports, (p) => {
3587
3671
  const $scope5_id = _scope_id();
3588
- _html(`<span${_attr_class(["_j", portChip])}${_attr("title", p.cmd)}><button type=button${_attr_class(["_f1", "_f8"])}${_attr("title", `Open http://${typeof location === "undefined" ? "localhost" : location.hostname}:${p.port}`)}>:${_sep($sg__input_status_ports)}${_escape(p.port)}${_el_resume($scope5_id, "c", $sg__input_status_ports)}</button>${_el_resume($scope5_id, "b")}<button type=button${_attr_class([
3589
- "_f1",
3590
- "_f2",
3672
+ _html(`<span${_attr_class(["_j", portChip])}${_attr("title", p.cmd)}><button type=button${_attr_class(["_f3", "_f_"])}${_attr("title", `Open http://${typeof location === "undefined" ? "localhost" : location.hostname}:${p.port}`)}>:${_sep($sg__input_status_ports)}${_escape(p.port)}${_el_resume($scope5_id, "c", $sg__input_status_ports)}</button>${_el_resume($scope5_id, "b")}<button type=button${_attr_class([
3591
3673
  "_f3",
3592
- { ["_f4"]: armedPid === p.pid }
3674
+ "_f4",
3675
+ "_f5",
3676
+ { ["_f6"]: armedPid === p.pid }
3593
3677
  ])}${armedPid === p.pid ? _attr("title", `Really kill ${p.cmd}?`) : _attr("title", `Kill ${p.cmd} (pid ${p.pid})`)}>`);
3594
3678
  icon_xmark_default({ size: 12 });
3595
3679
  _html(`</button>${_el_resume($scope5_id, "d")}</span>${_el_resume($scope5_id, "a", $sg__input_status_ports)}`);
@@ -3671,10 +3755,10 @@ var side_nav_item_default = _template("s", (input) => {
3671
3755
  _if(() => {
3672
3756
  if (input.rail) {
3673
3757
  const $scope2_id = _scope_id();
3674
- _html(`<button${_attr_class([railBtn, { ["_fw"]: input.current }])}${_attr("title", ws$1.name)}>${_escape((input.index ?? 0) + 1)}${_el_resume($scope2_id, "b", _serialize_guard($scope0_reason, 17))}<span${_attr_class([
3758
+ _html(`<button${_attr_class([railBtn, { ["_fy"]: input.current }])}${_attr("title", ws$1.name)}>${_escape((input.index ?? 0) + 1)}${_el_resume($scope2_id, "b", _serialize_guard($scope0_reason, 17))}<span${_attr_class([
3675
3759
  "_q",
3676
3760
  phase[dot],
3677
- "_fA"
3761
+ "_fC"
3678
3762
  ])}></span>${_el_resume($scope2_id, "c", $sg__input_workspaceId__OR__input_status)}</button>${_el_resume($scope2_id, "a")}`);
3679
3763
  _script($scope2_id, "s3");
3680
3764
  _subscribe($si__input_workspaces__OR__input_workspaceId && $ws_name__closures, _subscribe($si__input_index && $input_index__closures, _subscribe($si__input_current && $input_current__closures, writeScope($scope2_id, { _: _scope_with_id($scope1_id) }))));
@@ -3683,14 +3767,14 @@ var side_nav_item_default = _template("s", (input) => {
3683
3767
  const $scope3_id = _scope_id();
3684
3768
  const sessions$1 = input.sessions || [];
3685
3769
  const phaseLabel = dot === "working" ? "Working" : dot === "waiting" ? "Needs you" : dot === "idle" ? "Idle" : "Off";
3686
- _html(`<section${_attr_class(["_fC", {
3687
- ["_fw"]: input.current,
3688
- ["_fD"]: input.railPop,
3689
- ["_fB"]: input.page
3690
- }])}><div${_attr_class("_fE")}><button${_attr_class("_fF")}><span${_attr_class([
3770
+ _html(`<section${_attr_class(["_fE", {
3771
+ ["_fy"]: input.current,
3772
+ ["_fF"]: input.railPop,
3773
+ ["_fD"]: input.page
3774
+ }])}><div${_attr_class("_fG")}><button${_attr_class("_fH")}><span${_attr_class([
3691
3775
  "_q",
3692
3776
  phase[dot],
3693
- "_fP"
3777
+ "_fR"
3694
3778
  ])}></span>${_el_resume($scope3_id, "d", $sg__input_workspaceId__OR__input_status)}`);
3695
3779
  _if(() => {
3696
3780
  if (sessions$1.length === 1) {
@@ -3703,7 +3787,7 @@ var side_nav_item_default = _template("s", (input) => {
3703
3787
  icon_agent_default({
3704
3788
  agent: activeAgent(sessions$1[0]),
3705
3789
  size: 12,
3706
- class: "_fK"
3790
+ class: "_fM"
3707
3791
  });
3708
3792
  $si__input_sessions && writeScope($scope12_id, {
3709
3793
  _: _scope_with_id($scope3_id),
@@ -3713,11 +3797,11 @@ var side_nav_item_default = _template("s", (input) => {
3713
3797
  }
3714
3798
  }, $scope3_id, "e", $sg__input_sessions, $sg__input_sessions, $sg__input_workspaceId__OR__input_status__OR__input_sessions__OR__input_page);
3715
3799
  const metaText = sessions$1.length === 0 ? phaseLabel : sessions$1.length === 1 ? sessions$1[0].title || "" : `${sessions$1.length} sessions`;
3716
- _html(`<span${_attr_class("_fL")}><span${_attr_class("_fM")}>${_escape(ws$1.name)}${_el_resume($scope3_id, "h", $sg__input_workspaces__OR__input_workspaceId)}</span>`);
3800
+ _html(`<span${_attr_class("_fN")}><span${_attr_class("_fO")}>${_escape(ws$1.name)}${_el_resume($scope3_id, "h", $sg__input_workspaces__OR__input_workspaceId)}</span>`);
3717
3801
  _if(() => {
3718
3802
  if (input.page && metaText) {
3719
3803
  const $scope13_id = _scope_id();
3720
- _html(`<span${_attr_class("_fN")}>${_escape(metaText)}${_el_resume($scope13_id, "b", _serialize_guard($scope0_reason, 5))}</span>`);
3804
+ _html(`<span${_attr_class("_fP")}>${_escape(metaText)}${_el_resume($scope13_id, "b", _serialize_guard($scope0_reason, 5))}</span>`);
3721
3805
  $si__input_workspaceId__OR__input_status__OR__input_sessions__OR__input_page && writeScope($scope13_id, { _: _serialize_if($scope0_reason, 5) && _scope_with_id($scope3_id) });
3722
3806
  return 0;
3723
3807
  }
@@ -3726,7 +3810,7 @@ var side_nav_item_default = _template("s", (input) => {
3726
3810
  _if(() => {
3727
3811
  if (input.page) {
3728
3812
  const $scope4_id = _scope_id();
3729
- _html(`<span${_attr_class("_fO")}>${input.current ? "Open" : ""}${_el_resume($scope4_id, "b", _serialize_guard($scope0_reason, 16))}</span>`);
3813
+ _html(`<span${_attr_class("_fQ")}>${input.current ? "Open" : ""}${_el_resume($scope4_id, "b", _serialize_guard($scope0_reason, 16))}</span>`);
3730
3814
  $si__input_workspaces__OR__input_workspaceId__OR__input_rail__OR__input_current__OR__input_page && _subscribe($si__input_current && $input_current__closures, writeScope($scope4_id, {
3731
3815
  _: _scope_with_id($scope3_id),
3732
3816
  Cab: $si__input_current && 2
@@ -3738,13 +3822,13 @@ var side_nav_item_default = _template("s", (input) => {
3738
3822
  _if(() => {
3739
3823
  if (!input.page) {
3740
3824
  const $scope5_id = _scope_id();
3741
- _html(`<div${_attr_class("_fG")}>`);
3825
+ _html(`<div${_attr_class("_fI")}>`);
3742
3826
  _if(() => {
3743
3827
  if (input.onNewSession) {
3744
3828
  const $scope6_id = _scope_id();
3745
3829
  const newPopId = _id();
3746
3830
  let pickerReady = false;
3747
- _html(`<button${_attr_class("_fI")} title="New session"${_attr("popovertarget", newPopId)}>`);
3831
+ _html(`<button${_attr_class("_fK")} title="New session"${_attr("popovertarget", newPopId)}>`);
3748
3832
  icon_agent_default({
3749
3833
  agent: "shell",
3750
3834
  size: 12
@@ -3777,7 +3861,7 @@ var side_nav_item_default = _template("s", (input) => {
3777
3861
  _if(() => {
3778
3862
  if (input.onReview) {
3779
3863
  const $scope8_id = _scope_id();
3780
- _html(`<button${_attr_class("_fI")} title="Review changes">`);
3864
+ _html(`<button${_attr_class("_fK")} title="Review changes">`);
3781
3865
  icon_diff_default({ size: 12 });
3782
3866
  _html(`</button>${_el_resume($scope8_id, "a")}`);
3783
3867
  _script($scope8_id, "s6");
@@ -3785,7 +3869,7 @@ var side_nav_item_default = _template("s", (input) => {
3785
3869
  return 0;
3786
3870
  }
3787
3871
  }, $scope5_id, "c", $sg__input_onReview, $sg__input_onReview, $sg__input_onNewSession__OR__input_onReview, 0, 1);
3788
- _html(`<button${_attr_class(["_fI", { ["_fx"]: input.managing }])} title="Manage workspace" aria-pressed=${input.managing ? "true" : "false"}>`);
3872
+ _html(`<button${_attr_class(["_fK", { ["_fz"]: input.managing }])} title="Manage workspace" aria-pressed=${input.managing ? "true" : "false"}>`);
3789
3873
  icon_manage_default({ size: 12 });
3790
3874
  _html(`</button>${_el_resume($scope5_id, "d")}</div>`);
3791
3875
  _script($scope5_id, "s7");
@@ -3793,17 +3877,17 @@ var side_nav_item_default = _template("s", (input) => {
3793
3877
  return 0;
3794
3878
  }
3795
3879
  }, $scope3_id, "k", $sg__input_page, $sg__input_page, $sg__input_workspaceId__OR__input_status__OR__input_sessions__OR__input_page, 0, 1);
3796
- _html(`</div><div${_attr_class("_fU")}>`);
3880
+ _html(`</div><div${_attr_class("_fW")}>`);
3797
3881
  _for_of(sessions$1.length > 1 ? sessions$1 : [], (s) => {
3798
3882
  const $scope9_id = _scope_id();
3799
- _html(`<div${_attr_class(["_fH", { ["_fw"]: s.id === input.currentTab }])}>`);
3883
+ _html(`<div${_attr_class(["_fJ", { ["_fy"]: s.id === input.currentTab }])}>`);
3800
3884
  _if(() => {
3801
3885
  if (renamingId === s.id) {
3802
3886
  const $scope11_id = _scope_id();
3803
3887
  _html(`<span${_attr_class([
3804
3888
  "_q",
3805
3889
  phase[sessionPhase(s.state)],
3806
- "_fS"
3890
+ "_fU"
3807
3891
  ])}></span>${_el_resume($scope11_id, "a", $sg__input_sessions)}`);
3808
3892
  _set_serialize_reason({
3809
3893
  1: $sg__input_sessions,
@@ -3813,17 +3897,17 @@ var side_nav_item_default = _template("s", (input) => {
3813
3897
  icon_agent_default({
3814
3898
  agent: activeAgent(s),
3815
3899
  size: 13,
3816
- class: "_fW"
3900
+ class: "_fY"
3817
3901
  });
3818
3902
  _html(`<input${_attr_input_value($scope11_id, "c", renameValue, _resume((_new_renameValue) => {
3819
3903
  renameValue = _new_renameValue;
3820
- }, "s0", $scope11_id))}${_attr_class("_fT")} aria-label="Session name">${_el_resume($scope11_id, "c")}`);
3904
+ }, "s0", $scope11_id))}${_attr_class("_fV")} aria-label="Session name">${_el_resume($scope11_id, "c")}`);
3821
3905
  _script($scope11_id, "s8");
3822
3906
  _subscribe($renameValue__closures, writeScope($scope11_id, { b: $si__input_sessions && _existing_scope($childScope3) }));
3823
3907
  return 0;
3824
3908
  } else {
3825
3909
  const $scope10_id = _scope_id();
3826
- _html(`<button${_attr_class("_fV")}><span${_attr_class(["_q", phase[sessionPhase(s.state)]])}></span>${_el_resume($scope10_id, "b", $sg__input_sessions)}`);
3910
+ _html(`<button${_attr_class("_fX")}><span${_attr_class(["_q", phase[sessionPhase(s.state)]])}></span>${_el_resume($scope10_id, "b", $sg__input_sessions)}`);
3827
3911
  _set_serialize_reason({
3828
3912
  1: $sg__input_sessions,
3829
3913
  2: $sg__input_sessions
@@ -3832,11 +3916,11 @@ var side_nav_item_default = _template("s", (input) => {
3832
3916
  icon_agent_default({
3833
3917
  agent: activeAgent(s),
3834
3918
  size: 13,
3835
- class: "_fW"
3919
+ class: "_fY"
3836
3920
  });
3837
- _html(`<span${_attr_class("_fQ")}>${_escape(s.title || activeAgent(s))}${_el_resume($scope10_id, "e", $sg__input_sessions)}</span></button>${_el_resume($scope10_id, "a")}<div${_attr_class("_fR")}><button${_attr_class("_fI")} title="Rename session">`);
3921
+ _html(`<span${_attr_class("_fS")}>${_escape(s.title || activeAgent(s))}${_el_resume($scope10_id, "e", $sg__input_sessions)}</span></button>${_el_resume($scope10_id, "a")}<div${_attr_class("_fT")}><button${_attr_class("_fK")} title="Rename session">`);
3838
3922
  icon_edit_default({ size: 12 });
3839
- _html(`</button>${_el_resume($scope10_id, "g")}<button${_attr_class(["_fJ", { ["_fy"]: armedKill === s.id }])} title=${armedKill === s.id ? "\"Really kill this session?\"" : "\"Kill session\""}>×</button>${_el_resume($scope10_id, "i")}</div>`);
3923
+ _html(`</button>${_el_resume($scope10_id, "g")}<button${_attr_class(["_fL", { ["_fA"]: armedKill === s.id }])} title=${armedKill === s.id ? "\"Really kill this session?\"" : "\"Kill session\""}>×</button>${_el_resume($scope10_id, "i")}</div>`);
3840
3924
  _script($scope10_id, "s9");
3841
3925
  _subscribe($armedKill__closures, writeScope($scope10_id, { c: $si__input_sessions && _existing_scope($childScope4) }));
3842
3926
  return 1;
@@ -4017,19 +4101,19 @@ var side_nav_default = _template("t", (input) => {
4017
4101
  const wsSelected = view !== "usage" && view !== "new";
4018
4102
  const otherIds = itemIds.filter((id) => id !== ws.id);
4019
4103
  const listIds = isPage ? [ws.id, ...otherIds] : itemIds;
4020
- _html(`<aside${_attr_class(["_da", {
4021
- ["_c9"]: !navOpen,
4022
- ["_c_"]: isPage
4104
+ _html(`<aside${_attr_class(["_dc", {
4105
+ ["_da"]: !navOpen,
4106
+ ["_db"]: isPage
4023
4107
  }])}${_attr("hidden", view === "diff")}>`);
4024
4108
  _if(() => {
4025
4109
  if (isPage) {
4026
4110
  const $scope1_id = _scope_id();
4027
- _html(`<header${_attr_class("_dd")}><h1${_attr_class("_de")}>Workspaces</h1><div${_attr_class("_df")}>`);
4111
+ _html(`<header${_attr_class("_df")}><h1${_attr_class("_dg")}>Workspaces</h1><div${_attr_class("_dh")}>`);
4028
4112
  _if(() => {}, $scope1_id, "d", 1, 1, 1, 0, 1);
4029
4113
  _html(`<button${_attr_class([
4030
4114
  iconBtn$2,
4031
- "_dg",
4032
- { ["_c7"]: view === "usage" }
4115
+ "_di",
4116
+ { ["_c9"]: view === "usage" }
4033
4117
  ])} title=Usage aria-pressed=${view === "usage" ? "true" : "false"}>`);
4034
4118
  icon_gauge_default({ size: 16 });
4035
4119
  _html(`</button>${_el_resume($scope1_id, "e")}</div></header>`);
@@ -4038,13 +4122,13 @@ var side_nav_default = _template("t", (input) => {
4038
4122
  return 0;
4039
4123
  }
4040
4124
  }, $scope0_id, "b", 1, 1, 1, 0, 1);
4041
- _html(`<div${_attr_class("_dj")}>`);
4125
+ _html(`<div${_attr_class("_dl")}>`);
4042
4126
  _for_of(listIds, (wsId) => {
4043
4127
  const $scope2_id = _scope_id();
4044
4128
  _if(() => {
4045
4129
  if (isPage && wsId === ws.id) {
4046
4130
  const $scope10_id = _scope_id();
4047
- _html(`<h2${_attr_class("_dh")}>Current</h2>`);
4131
+ _html(`<h2${_attr_class("_dj")}>Current</h2>`);
4048
4132
  writeScope($scope10_id, {});
4049
4133
  return 0;
4050
4134
  }
@@ -4052,7 +4136,7 @@ var side_nav_default = _template("t", (input) => {
4052
4136
  _if(() => {
4053
4137
  if (isPage && wsId !== ws.id && wsId === otherIds[0]) {
4054
4138
  const $scope11_id = _scope_id();
4055
- _html(`<h2${_attr_class("_dh")}>Other spaces</h2>`);
4139
+ _html(`<h2${_attr_class("_dj")}>Other spaces</h2>`);
4056
4140
  writeScope($scope11_id, {});
4057
4141
  return 0;
4058
4142
  }
@@ -4150,7 +4234,7 @@ var side_nav_default = _template("t", (input) => {
4150
4234
  railHover = null;
4151
4235
  }, 150);
4152
4236
  }, "t9", $scope3_id);
4153
- _html(`<div${_attr_class("_dk")}>`);
4237
+ _html(`<div${_attr_class("_dm")}>`);
4154
4238
  _for_of(itemIds, (wsId, i) => {
4155
4239
  const $scope4_id = _scope_id();
4156
4240
  _html("<span>");
@@ -4197,7 +4281,7 @@ var side_nav_default = _template("t", (input) => {
4197
4281
  if (railHover) {
4198
4282
  const $scope5_id = _scope_id();
4199
4283
  const hoverId = railHover.id;
4200
- _html(`<div${_attr_class("_dn")}${_attr_style(`top:${railHover.top}px;left:${railHover.left}px`)}>`);
4284
+ _html(`<div${_attr_class("_dp")}${_attr_style(`top:${railHover.top}px;left:${railHover.left}px`)}>`);
4201
4285
  _set_serialize_reason({
4202
4286
  0: 1,
4203
4287
  1: 1,
@@ -4300,11 +4384,11 @@ var side_nav_default = _template("t", (input) => {
4300
4384
  return 0;
4301
4385
  }
4302
4386
  }, $scope0_id, "d");
4303
- _html(`<div${_attr_class("_dl")}>`);
4387
+ _html(`<div${_attr_class("_dn")}>`);
4304
4388
  _if(() => {
4305
4389
  if (isPage) {
4306
4390
  const $scope6_id = _scope_id();
4307
- _html(`<button${_attr_class(["_di", { ["_c7"]: view === "new" }])} title="New workspace" aria-pressed=${view === "new" ? "true" : "false"}>`);
4391
+ _html(`<button${_attr_class(["_dk", { ["_c9"]: view === "new" }])} title="New workspace" aria-pressed=${view === "new" ? "true" : "false"}>`);
4308
4392
  icon_folder_plus_default({ size: 16 });
4309
4393
  _html(` New workspace</button>${_el_resume($scope6_id, "a")}`);
4310
4394
  _script($scope6_id, "t21");
@@ -4326,11 +4410,11 @@ var side_nav_default = _template("t", (input) => {
4326
4410
  return 1;
4327
4411
  }
4328
4412
  }, $scope7_id, "a", 1, 1, 1, "</button>", 1);
4329
- _html(`<div${_attr_class(["_p", "_dm"])}></div>`);
4413
+ _html(`<div${_attr_class(["_p", "_do"])}></div>`);
4330
4414
  _if(() => {}, $scope7_id, "c", 1, 1, 1, 0, 1);
4331
- _html(`<button${_attr_class([iconBtn$2, { ["_c7"]: view === "usage" }])} title=Usage aria-pressed=${view === "usage" ? "true" : "false"}>`);
4415
+ _html(`<button${_attr_class([iconBtn$2, { ["_c9"]: view === "usage" }])} title=Usage aria-pressed=${view === "usage" ? "true" : "false"}>`);
4332
4416
  icon_gauge_default({ size: 15 });
4333
- _html(`</button>${_el_resume($scope7_id, "d")}<button${_attr_class([iconBtn$2, { ["_c7"]: view === "new" }])} title="New workspace" aria-pressed=${view === "new" ? "true" : "false"}>`);
4417
+ _html(`</button>${_el_resume($scope7_id, "d")}<button${_attr_class([iconBtn$2, { ["_c9"]: view === "new" }])} title="New workspace" aria-pressed=${view === "new" ? "true" : "false"}>`);
4334
4418
  icon_folder_plus_default({ size: 16 });
4335
4419
  _html(`</button>${_el_resume($scope7_id, "f")}`);
4336
4420
  _script($scope7_id, "t23");
@@ -4397,9 +4481,9 @@ var side_nav_default = _template("t", (input) => {
4397
4481
  });
4398
4482
  //#endregion
4399
4483
  //#region src/tags/manage-workspace.css.ts
4400
- var content$1 = "_bX _O";
4401
- var pageMeta = "_bY _T";
4402
- var iconBtn$1 = "_cp _y";
4484
+ var content$1 = "_cE _O";
4485
+ var pageMeta = "_cF _T";
4486
+ var iconBtn$1 = "_c7 _y";
4403
4487
  //#endregion
4404
4488
  //#region src/tags/manage-workspace.marko
4405
4489
  var api$3;
@@ -4493,16 +4577,16 @@ var manage_workspace_default = _template("k", (input) => {
4493
4577
  setTimeout(() => loadProcs(void 0), 500);
4494
4578
  }, "k5", $scope0_id);
4495
4579
  const titleId = _id();
4496
- _html(`<div${_attr_class("_M")} role=region${_attr("aria-labelledby", titleId)}><div${_attr_class("_N")}><div${_attr_class(content$1)}><header${_attr_class("_Q")}><div${_attr_class("_S")}><h1${_attr("id", titleId)}${_attr_class("_R")}>Manage</h1><p${_attr_class(pageMeta)}${_attr("title", ws.display_path || ws.path)}><span${_attr_class("_bZ")}>${_escape(ws.name)}${_el_resume($scope0_id, "i")}</span>`);
4580
+ _html(`<div${_attr_class("_M")} role=region${_attr("aria-labelledby", titleId)}><div${_attr_class("_N")}><div${_attr_class(content$1)}><header${_attr_class("_Q")}><div${_attr_class("_S")}><h1${_attr("id", titleId)}${_attr_class("_R")}>Manage</h1><p${_attr_class(pageMeta)}${_attr("title", ws.display_path || ws.path)}><span${_attr_class("_cG")}>${_escape(ws.name)}${_el_resume($scope0_id, "i")}</span>`);
4497
4581
  _if(() => {
4498
4582
  if (ws.status !== "active") {
4499
4583
  const $scope10_id = _scope_id();
4500
- _html(`<span${_attr_class(["_b2", "_b3"])}>Archived</span>`);
4584
+ _html(`<span${_attr_class(["_cJ", "_cK"])}>Archived</span>`);
4501
4585
  writeScope($scope10_id, {});
4502
4586
  return 0;
4503
4587
  }
4504
4588
  }, $scope0_id, "j", 1, 1, 1, 0, 1);
4505
- _html(`<span${_attr_class("_b0")} aria-hidden=true>·</span><span${_attr_class(["_b1", "_o"])}>${_escape(ws.display_path || ws.path)}${_el_resume($scope0_id, "m")}</span></p>${_el_resume($scope0_id, "g")}</div></header>`);
4589
+ _html(`<span${_attr_class("_cH")} aria-hidden=true>·</span><span${_attr_class(["_cI", "_o"])}>${_escape(ws.display_path || ws.path)}${_el_resume($scope0_id, "m")}</span></p>${_el_resume($scope0_id, "g")}</div></header>`);
4506
4590
  _if(() => {
4507
4591
  if (error) {
4508
4592
  const $scope2_id = _scope_id();
@@ -4526,26 +4610,26 @@ var manage_workspace_default = _template("k", (input) => {
4526
4610
  _if(() => {
4527
4611
  if (pendingAction && actionStep) {
4528
4612
  const $scope7_id = _scope_id();
4529
- _html(`<p${_attr_class("_b4")}><span${_attr_class("_w")}></span><!>${_escape(actionStep)}${_el_resume($scope7_id, "c")}</p>`);
4613
+ _html(`<p${_attr_class("_cL")}><span${_attr_class("_w")}></span><!>${_escape(actionStep)}${_el_resume($scope7_id, "c")}</p>`);
4530
4614
  writeScope($scope7_id, {});
4531
4615
  return 0;
4532
4616
  }
4533
4617
  }, $scope0_id, "o", 1, 1, 1, 0, 1);
4534
- _html(`<section${_attr_class("_b5")}><div${_attr_class("_b6")}><h2${_attr_class("_cq")}>Repos</h2><span${_attr_class("_b7")}>${_escape(ws.repos.length)}${_el_resume($scope0_id, "t")}</span><div${_attr_class("_p")}></div><button${_attr_class(iconBtn$1)} title="Refresh repo list" aria-label="Refresh repo list"${_attr("disabled", catalogRefreshing)}>`);
4618
+ _html(`<section${_attr_class("_cM")}><div${_attr_class("_cN")}><h2${_attr_class("_c8")}>Repos</h2><span${_attr_class("_cO")}>${_escape(ws.repos.length)}${_el_resume($scope0_id, "t")}</span><div${_attr_class("_p")}></div><button${_attr_class(iconBtn$1)} title="Refresh repo list" aria-label="Refresh repo list"${_attr("disabled", catalogRefreshing)}>`);
4535
4619
  _set_serialize_reason(1);
4536
4620
  const $childScope = _peek_scope_id();
4537
4621
  icon_refresh_default({
4538
4622
  size: 14,
4539
4623
  class: catalogRefreshing && "_v"
4540
4624
  });
4541
- _html(`</button>${_el_resume($scope0_id, "v")}</div><ul${_attr_class("_b9")}>`);
4625
+ _html(`</button>${_el_resume($scope0_id, "v")}</div><ul${_attr_class("_cQ")}>`);
4542
4626
  _for_of(ws.repos, (row) => {
4543
4627
  const $scope1_id = _scope_id();
4544
- _html(`<li${_attr_class("_ca")}><div${_attr_class("_cb")}><span${_attr_class(["_cc", "_o"])}>${_escape(row.worktree)}${_el_resume($scope1_id, "d")}/</span><span${_attr_class("_cd")}><span${_attr_class("_ce")}>${_escape(row.full_name)}${_el_resume($scope1_id, "g")}</span>`);
4628
+ _html(`<li${_attr_class("_cS")}><div${_attr_class("_cT")}><span${_attr_class(["_cU", "_o"])}>${_escape(row.worktree)}${_el_resume($scope1_id, "d")}/</span><span${_attr_class("_cV")}><span${_attr_class("_cW")}>${_escape(row.full_name)}${_el_resume($scope1_id, "g")}</span>`);
4545
4629
  _if(() => {
4546
4630
  if (row.base_branch !== row.default_branch) {
4547
4631
  const $scope11_id = _scope_id();
4548
- _html(`<span${_attr_class(["_cf", "_o"])} title="Base branch">⎇ <!>${_escape(row.base_branch)}${_el_resume($scope11_id, "b")}</span>`);
4632
+ _html(`<span${_attr_class(["_cX", "_o"])} title="Base branch">⎇ <!>${_escape(row.base_branch)}${_el_resume($scope11_id, "b")}</span>`);
4549
4633
  writeScope($scope11_id, {});
4550
4634
  return 0;
4551
4635
  }
@@ -4560,9 +4644,9 @@ var manage_workspace_default = _template("k", (input) => {
4560
4644
  } else {
4561
4645
  const $scope6_id = _scope_id();
4562
4646
  _html(`<button${_attr_class([
4563
- "_cg",
4564
- "_ci",
4565
- { ["_ch"]: confirmingRemove === row.full_name }
4647
+ "_cY",
4648
+ "_c0",
4649
+ { ["_cZ"]: confirmingRemove === row.full_name }
4566
4650
  ])}${confirmingRemove === row.full_name ? _attr("title", `Really remove ${row.worktree}/? Uncommitted changes are lost.`) : _attr("title", `Remove ${row.worktree}/`)}>${confirmingRemove === row.full_name ? "Remove?" : "×"}${_el_resume($scope6_id, "b")}</button>${_el_resume($scope6_id, "a")}`);
4567
4651
  _script($scope6_id, "k11");
4568
4652
  _subscribe($confirmingRemove__closures, writeScope($scope6_id, {}));
@@ -4579,19 +4663,19 @@ var manage_workspace_default = _template("k", (input) => {
4579
4663
  }, "full_name", $scope0_id, "y", 1, 1, 1, 0, 1);
4580
4664
  _for_of([...busy].filter((n) => !inWorkspace.has(n)), (name) => {
4581
4665
  const $scope13_id = _scope_id();
4582
- _html(`<li${_attr_class(["_ca", "_b_"])}><span${_attr_class("_w")}></span><div${_attr_class("_cb")}><span${_attr_class("_ce")}>Adding <!>${_escape(name)}${_el_resume($scope13_id, "e")}…</span></div></li>`);
4666
+ _html(`<li${_attr_class(["_cS", "_cR"])}><span${_attr_class("_w")}></span><div${_attr_class("_cT")}><span${_attr_class("_cW")}>Adding <!>${_escape(name)}${_el_resume($scope13_id, "e")}…</span></div></li>`);
4583
4667
  writeScope($scope13_id, {});
4584
4668
  }, (n) => n, $scope0_id, "z", 1, 1, 1, 0, 1);
4585
4669
  _html("</ul>");
4586
4670
  _if(() => {
4587
4671
  if (!ws.repos.length && !busy.size) {
4588
4672
  const $scope14_id = _scope_id();
4589
- _html(`<p${_attr_class("_ck")}>No repos yet — search below to add one.</p>`);
4673
+ _html(`<p${_attr_class("_c2")}>No repos yet — search below to add one.</p>`);
4590
4674
  writeScope($scope14_id, {});
4591
4675
  return 0;
4592
4676
  }
4593
4677
  }, $scope0_id, "a0", 1, 1, 1, 0, 1);
4594
- _html(`<div${_attr_class("_b8")}>`);
4678
+ _html(`<div${_attr_class("_cP")}>`);
4595
4679
  const $childScope2 = _peek_scope_id();
4596
4680
  let refreshCatalog = repo_picker_default({
4597
4681
  exclude: inWorkspace,
@@ -4611,17 +4695,17 @@ var manage_workspace_default = _template("k", (input) => {
4611
4695
  _if(() => {
4612
4696
  if (running.length) {
4613
4697
  const $scope8_id = _scope_id();
4614
- _html(`<section${_attr_class("_b5")}><div${_attr_class("_b6")}><h2${_attr_class("_cq")}>Running</h2><span${_attr_class("_b7")}>${_escape(running.length)}${_el_resume($scope8_id, "e")}</span></div><ul${_attr_class("_b9")}>`);
4698
+ _html(`<section${_attr_class("_cM")}><div${_attr_class("_cN")}><h2${_attr_class("_c8")}>Running</h2><span${_attr_class("_cO")}>${_escape(running.length)}${_el_resume($scope8_id, "e")}</span></div><ul${_attr_class("_cQ")}>`);
4615
4699
  _for_of(running, (p) => {
4616
4700
  const $scope9_id = _scope_id();
4617
- _html(`<li${_attr_class("_ca")}><div${_attr_class("_cb")}${_attr("title", p.args)}><span${_attr_class(["_cc", "_o"])}>${_escape(p.cmd)}${_el_resume($scope9_id, "d")}</span>`);
4701
+ _html(`<li${_attr_class("_cS")}><div${_attr_class("_cT")}${_attr("title", p.args)}><span${_attr_class(["_cU", "_o"])}>${_escape(p.cmd)}${_el_resume($scope9_id, "d")}</span>`);
4618
4702
  _if(() => {
4619
4703
  if (p.ports.length) {
4620
4704
  const $scope15_id = _scope_id();
4621
- _html(`<span${_attr_class("_cd")}>`);
4705
+ _html(`<span${_attr_class("_cV")}>`);
4622
4706
  _for_of(p.ports, (port) => {
4623
4707
  const $scope16_id = _scope_id();
4624
- _html(`<button${_attr_class(["_j", "_cj"])}${_attr("title", `Open http://${typeof location === "undefined" ? "localhost" : location.hostname}:${port}`)}>:<!>${_escape(port)}${_el_resume($scope16_id, "b")}</button>${_el_resume($scope16_id, "a")}`);
4708
+ _html(`<button${_attr_class(["_j", "_c1"])}${_attr("title", `Open http://${typeof location === "undefined" ? "localhost" : location.hostname}:${port}`)}>:<!>${_escape(port)}${_el_resume($scope16_id, "b")}</button>${_el_resume($scope16_id, "a")}`);
4625
4709
  _script($scope16_id, "k13");
4626
4710
  writeScope($scope16_id, { d: port });
4627
4711
  }, (x) => String(x), $scope15_id, "a", 1, 1, 1, "</span>", 1);
@@ -4629,7 +4713,7 @@ var manage_workspace_default = _template("k", (input) => {
4629
4713
  return 0;
4630
4714
  }
4631
4715
  }, $scope9_id, "e", 1, 1, 1, 0, 1);
4632
- _html(`</div>${_el_resume($scope9_id, "b")}<button${_attr_class(["_cg", "_ci"])} type=button${_attr("title", `Kill ${p.pid}`)}${_attr("aria-label", `Kill process ${p.pid}`)}>×</button>${_el_resume($scope9_id, "f")}</li>`);
4716
+ _html(`</div>${_el_resume($scope9_id, "b")}<button${_attr_class(["_cY", "_c0"])} type=button${_attr("title", `Kill ${p.pid}`)}${_attr("aria-label", `Kill process ${p.pid}`)}>×</button>${_el_resume($scope9_id, "f")}</li>`);
4633
4717
  _script($scope9_id, "k14");
4634
4718
  writeScope($scope9_id, {
4635
4719
  k: p?.ports,
@@ -4641,17 +4725,17 @@ var manage_workspace_default = _template("k", (input) => {
4641
4725
  return 0;
4642
4726
  }
4643
4727
  }, $scope0_id, "a4", 1, 1, 1, 0, 1);
4644
- _html(`<section${_attr_class(["_b5", "_cl"])}><div${_attr_class("_b6")}><h2${_attr_class("_cq")}>Workspace</h2></div><div${_attr_class("_cm")}>`);
4728
+ _html(`<section${_attr_class(["_cM", "_c3"])}><div${_attr_class("_cN")}><h2${_attr_class("_c8")}>Workspace</h2></div><div${_attr_class("_c4")}>`);
4645
4729
  _if(() => {
4646
4730
  if (ws.status === "active") {
4647
4731
  const $scope4_id = _scope_id();
4648
- _html(`<button type=button${_attr_class(["_f", "_cn"])}${_attr("disabled", !!pendingAction)}>${pendingAction === "archive" ? "Archiving…" : "Archive"}${_el_resume($scope4_id, "b")}</button>${_el_resume($scope4_id, "a")}`);
4732
+ _html(`<button type=button${_attr_class(["_f", "_c5"])}${_attr("disabled", !!pendingAction)}>${pendingAction === "archive" ? "Archiving…" : "Archive"}${_el_resume($scope4_id, "b")}</button>${_el_resume($scope4_id, "a")}`);
4649
4733
  _script($scope4_id, "k15");
4650
4734
  writeScope($scope4_id, {});
4651
4735
  return 0;
4652
4736
  } else {
4653
4737
  const $scope5_id = _scope_id();
4654
- _html(`<button type=button${_attr_class(["_f", "_cn"])}${_attr("disabled", !!pendingAction)}>Restore</button>${_el_resume($scope5_id, "a")}`);
4738
+ _html(`<button type=button${_attr_class(["_f", "_c5"])}${_attr("disabled", !!pendingAction)}>Restore</button>${_el_resume($scope5_id, "a")}`);
4655
4739
  _script($scope5_id, "k16");
4656
4740
  writeScope($scope5_id, {});
4657
4741
  return 1;
@@ -4660,9 +4744,9 @@ var manage_workspace_default = _template("k", (input) => {
4660
4744
  _html(`<button type=button${_attr_class([
4661
4745
  "_f",
4662
4746
  "_i",
4663
- "_cn",
4747
+ "_c5",
4664
4748
  { ["_h"]: confirmingDelete }
4665
- ])}${_attr("disabled", !!pendingAction)}>${pendingAction === "delete" ? "Deleting…" : "Delete"}${_el_resume($scope0_id, "ab")}</button>${_el_resume($scope0_id, "aa")}</div><p${_attr_class("_co")}>Archive hides the space from the list. Delete removes it and its worktrees.</p></section></div></div></div>`);
4749
+ ])}${_attr("disabled", !!pendingAction)}>${pendingAction === "delete" ? "Deleting…" : "Delete"}${_el_resume($scope0_id, "ab")}</button>${_el_resume($scope0_id, "aa")}</div><p${_attr_class("_c6")}>Archive hides the space from the list. Delete removes it and its worktrees.</p></section></div></div></div>`);
4666
4750
  _script($scope0_id, "k17");
4667
4751
  _script($scope0_id, "k18");
4668
4752
  writeScope($scope0_id, {
@@ -4699,8 +4783,8 @@ var manage_workspace_default = _template("k", (input) => {
4699
4783
  });
4700
4784
  //#endregion
4701
4785
  //#region src/tags/usage-stats.css.ts
4702
- var content = "_cG _O _P";
4703
- var iconBtn = "_cH _y";
4786
+ var content = "_cd _O _P";
4787
+ var iconBtn = "_ce _y";
4704
4788
  //#endregion
4705
4789
  //#region src/tags/usage-stats.marko
4706
4790
  var api$2;
@@ -4735,7 +4819,7 @@ var usage_stats_default = _template("x", (input) => {
4735
4819
  refreshing = false;
4736
4820
  }, "x1", $scope0_id);
4737
4821
  const titleId = _id();
4738
- _html(`<div${_attr_class("_M")} role=region${_attr("aria-labelledby", titleId)}><div${_attr_class("_N")}><div${_attr_class(content)}><header${_attr_class("_Q")}><div${_attr_class("_S")}><h1${_attr("id", titleId)}${_attr_class("_R")}>Usage</h1><p${_attr_class("_T")}>Provider plan windows across your agents.</p></div><div${_attr_class("_U")}><button${_attr_class([iconBtn, "_cI"])} title="Refresh usage" aria-label="Refresh usage"${_attr("disabled", refreshing)}>`);
4822
+ _html(`<div${_attr_class("_M")} role=region${_attr("aria-labelledby", titleId)}><div${_attr_class("_N")}><div${_attr_class(content)}><header${_attr_class("_Q")}><div${_attr_class("_S")}><h1${_attr("id", titleId)}${_attr_class("_R")}>Usage</h1><p${_attr_class("_T")}>Provider plan windows across your agents.</p></div><div${_attr_class("_U")}><button${_attr_class([iconBtn, "_cf"])} title="Refresh usage" aria-label="Refresh usage"${_attr("disabled", refreshing)}>`);
4739
4823
  _set_serialize_reason(1);
4740
4824
  const $childScope = _peek_scope_id();
4741
4825
  icon_refresh_default({
@@ -4746,24 +4830,24 @@ var usage_stats_default = _template("x", (input) => {
4746
4830
  _if(() => {
4747
4831
  if (!usage) {
4748
4832
  const $scope3_id = _scope_id();
4749
- _html(`<p${_attr_class(["_n", "_cJ"])}><span${_attr_class("_w")}></span> Loading usage…</p>`);
4833
+ _html(`<p${_attr_class(["_n", "_cg"])}><span${_attr_class("_w")}></span> Loading usage…</p>`);
4750
4834
  writeScope($scope3_id, {});
4751
4835
  return 0;
4752
4836
  } else if (usage.error) {
4753
4837
  const $scope1_id = _scope_id();
4754
- _html(`<p${_attr_class(["_n", "_cJ"])}>${_escape(usage.error)}${_el_resume($scope1_id, "b")}</p>`);
4838
+ _html(`<p${_attr_class(["_n", "_cg"])}>${_escape(usage.error)}${_el_resume($scope1_id, "b")}</p>`);
4755
4839
  writeScope($scope1_id, {});
4756
4840
  return 1;
4757
4841
  } else {
4758
4842
  const $scope2_id = _scope_id();
4759
- _html(`<div${_attr_class("_cK")}>`);
4843
+ _html(`<div${_attr_class("_ch")}>`);
4760
4844
  _for_of(usage.agents || [], (agent) => {
4761
4845
  const $scope4_id = _scope_id();
4762
- _html(`<div${_attr_class("_cL")}><div${_attr_class("_cM")}><strong${_attr_class("_c5")}>${_escape(agent.agent)}${_el_resume($scope4_id, "d")}</strong>`);
4846
+ _html(`<div${_attr_class("_ci")}><div${_attr_class("_cj")}><strong${_attr_class("_cC")}>${_escape(agent.agent)}${_el_resume($scope4_id, "d")}</strong>`);
4763
4847
  _if(() => {
4764
4848
  if (agent.plan) {
4765
4849
  const $scope5_id = _scope_id();
4766
- _html(`<span${_attr_class("_cN")}>${_escape(agent.plan.replace(/^default_/, "").replaceAll("_", " "))}${_el_resume($scope5_id, "b")}</span>`);
4850
+ _html(`<span${_attr_class("_ck")}>${_escape(agent.plan.replace(/^default_/, "").replaceAll("_", " "))}${_el_resume($scope5_id, "b")}</span>`);
4767
4851
  writeScope($scope5_id, {});
4768
4852
  return 0;
4769
4853
  }
@@ -4771,25 +4855,25 @@ var usage_stats_default = _template("x", (input) => {
4771
4855
  _if(() => {
4772
4856
  if (agent.stale_seconds != null) {
4773
4857
  const $scope6_id = _scope_id();
4774
- _html(`<span${_attr_class("_cO")}${_attr("title", `${agent.note || "couldn't reach this provider"} — these are the last cached numbers, ${duration(agent.stale_seconds * 1e3)} old`)}>⚠ <!>${_escape(duration(agent.stale_seconds * 1e3))}${_el_resume($scope6_id, "b")} old</span>${_el_resume($scope6_id, "a")}`);
4858
+ _html(`<span${_attr_class("_cl")}${_attr("title", `${agent.note || "couldn't reach this provider"} — these are the last cached numbers, ${duration(agent.stale_seconds * 1e3)} old`)}>⚠ <!>${_escape(duration(agent.stale_seconds * 1e3))}${_el_resume($scope6_id, "b")} old</span>${_el_resume($scope6_id, "a")}`);
4775
4859
  writeScope($scope6_id, {});
4776
4860
  return 0;
4777
4861
  }
4778
4862
  }, $scope4_id, "f", 1, 1, 1, 0, 1);
4779
- _html(`</div><div${_attr_class(["_cP", { ["_c6"]: agent.stale_seconds != null }])}>`);
4863
+ _html(`</div><div${_attr_class(["_cm", { ["_cD"]: agent.stale_seconds != null }])}>`);
4780
4864
  _for_of(agent.windows || [], (win) => {
4781
4865
  const $scope7_id = _scope_id();
4782
4866
  const pct = Math.round(win.used_percent);
4783
4867
  const label = resetLabel(win.resets_at, agent.stale_seconds != null);
4784
- const fillClass = win.used_percent >= 90 ? "_cY" : win.used_percent >= 70 ? "_cX" : win.used_percent >= 40 ? "_cW" : "_cV";
4785
- const pctClass = win.used_percent >= 90 ? "_c3" : win.used_percent >= 70 ? "_c2" : win.used_percent >= 40 ? "_c1" : "_c0";
4786
- _html(`<div${_attr_class("_cR")}${_attr("title", `${win.window}: ${pct}% used${win.resets_at ? ` — resets ${new Date(win.resets_at).toLocaleString()}` : ""}`)}><span${_attr_class("_cS")}>${_escape(win.window)}${_el_resume($scope7_id, "c")}</span><span${_attr_class("_cT")}><span${_attr_class(["_cU", fillClass])}${_attr_style(`width:${Math.min(100, Math.max(2, win.used_percent))}%`)}></span>${_el_resume($scope7_id, "e")}</span><span${_attr_class(["_cZ", pctClass])}>${_escape(pct)}${_el_resume($scope7_id, "g")}%</span>${_el_resume($scope7_id, "f")}<span${_attr_class("_c4")}>${label ? `↻ ${_escape(`${_to_text(label)}`)}` : ""}${_el_resume($scope7_id, "i")}</span></div>${_el_resume($scope7_id, "a")}`);
4868
+ const fillClass = win.used_percent >= 90 ? "_cv" : win.used_percent >= 70 ? "_cu" : win.used_percent >= 40 ? "_ct" : "_cs";
4869
+ const pctClass = win.used_percent >= 90 ? "_cA" : win.used_percent >= 70 ? "_cz" : win.used_percent >= 40 ? "_cy" : "_cx";
4870
+ _html(`<div${_attr_class("_co")}${_attr("title", `${win.window}: ${pct}% used${win.resets_at ? ` — resets ${new Date(win.resets_at).toLocaleString()}` : ""}`)}><span${_attr_class("_cp")}>${_escape(win.window)}${_el_resume($scope7_id, "c")}</span><span${_attr_class("_cq")}><span${_attr_class(["_cr", fillClass])}${_attr_style(`width:${Math.min(100, Math.max(2, win.used_percent))}%`)}></span>${_el_resume($scope7_id, "e")}</span><span${_attr_class(["_cw", pctClass])}>${_escape(pct)}${_el_resume($scope7_id, "g")}%</span>${_el_resume($scope7_id, "f")}<span${_attr_class("_cB")}>${label ? `↻ ${_escape(`${_to_text(label)}`)}` : ""}${_el_resume($scope7_id, "i")}</span></div>${_el_resume($scope7_id, "a")}`);
4787
4871
  writeScope($scope7_id, {});
4788
4872
  }, "window", $scope4_id, "h", 1, 1, 1, 0, 1);
4789
4873
  _if(() => {
4790
4874
  if (agent.note) {
4791
4875
  const $scope8_id = _scope_id();
4792
- _html(`<p${_attr_class("_cQ")}>${_escape(agent.note)}${_el_resume($scope8_id, "b")}</p>`);
4876
+ _html(`<p${_attr_class("_cn")}>${_escape(agent.note)}${_el_resume($scope8_id, "b")}</p>`);
4793
4877
  writeScope($scope8_id, {});
4794
4878
  return 0;
4795
4879
  }
@@ -4853,15 +4937,15 @@ var term_find_default = _template("u", (input) => {
4853
4937
  const canStep = hasQuery && open;
4854
4938
  const keybar = input.placement === "keybar";
4855
4939
  _html(`<div${_attr_class([
4856
- "_fp",
4857
- keybar ? "_fr" : "_fq",
4858
- !open && "_ft"
4859
- ])} aria-hidden=${open ? "false" : "true"}><div${_attr_class(["_fk", keybar ? "_fs" : "_fm"])}><input${_attr_input_value($scope0_id, "c", query, _resume(function(v) {
4940
+ "_e2",
4941
+ keybar ? "_e4" : "_e3",
4942
+ !open && "_e6"
4943
+ ])} aria-hidden=${open ? "false" : "true"}><div${_attr_class(["_eX", keybar ? "_e5" : "_eZ"])}><input${_attr_input_value($scope0_id, "c", query, _resume(function(v) {
4860
4944
  if (!open) return;
4861
4945
  query = v;
4862
4946
  live.query = v;
4863
4947
  run(0);
4864
- }, "u0", $scope0_id))}${_attr_class([findInput, keybar && "_fu"])} type=search enterkeyhint=search autocomplete=off tabindex=${open ? "0" : "-1"} placeholder="Find in terminal" aria-label="Find in terminal">${_el_resume($scope0_id, "c")}<button type=button${_attr_class([findIconBtn, keybar && "_fv"])} title="Previous match"${_attr("disabled", !canStep)} tabindex=${open ? "0" : "-1"}>↑</button>${_el_resume($scope0_id, "d")}<button type=button${_attr_class([findIconBtn, keybar && "_fv"])} title="Next match"${_attr("disabled", !canStep)} tabindex=${open ? "0" : "-1"}>↓</button>${_el_resume($scope0_id, "e")}<button type=button${_attr_class([findIconBtn, keybar && "_fv"])} title="Close find" tabindex=${open ? "0" : "-1"}>×</button>${_el_resume($scope0_id, "f")}</div>${_el_resume($scope0_id, "b", _serialize_guard($scope0_reason, 2))}</div>${_el_resume($scope0_id, "a")}`);
4948
+ }, "u0", $scope0_id))}${_attr_class([findInput, keybar && "_e7"])} type=search enterkeyhint=search autocomplete=off tabindex=${open ? "0" : "-1"} placeholder="Find in terminal" aria-label="Find in terminal">${_el_resume($scope0_id, "c")}<button type=button${_attr_class([findIconBtn, keybar && "_e8"])} title="Previous match"${_attr("disabled", !canStep)} tabindex=${open ? "0" : "-1"}>↑</button>${_el_resume($scope0_id, "d")}<button type=button${_attr_class([findIconBtn, keybar && "_e8"])} title="Next match"${_attr("disabled", !canStep)} tabindex=${open ? "0" : "-1"}>↓</button>${_el_resume($scope0_id, "e")}<button type=button${_attr_class([findIconBtn, keybar && "_e8"])} title="Close find" tabindex=${open ? "0" : "-1"}>×</button>${_el_resume($scope0_id, "f")}</div>${_el_resume($scope0_id, "b", _serialize_guard($scope0_reason, 2))}</div>${_el_resume($scope0_id, "a")}`);
4865
4949
  _script($scope0_id, "u4");
4866
4950
  _script($scope0_id, "u5");
4867
4951
  _script($scope0_id, "u6");
@@ -5130,7 +5214,7 @@ var term_default = _template("v", (input) => {
5130
5214
  trapOpen = true;
5131
5215
  }
5132
5216
  }, "v14", $scope0_id);
5133
- _html(`<div${_attr("hidden", !onTermPage)}${_attr_class("_dp")}><div${_attr_class("_dq")}></div>${_el_resume($scope0_id, "b")}`);
5217
+ _html(`<div${_attr("hidden", !onTermPage)}${_attr_class("_dr")}><div${_attr_class("_ds")}></div>${_el_resume($scope0_id, "b")}`);
5134
5218
  _if(() => {
5135
5219
  if (findOpen) {
5136
5220
  const $scope11_id = _scope_id();
@@ -5157,7 +5241,7 @@ var term_default = _template("v", (input) => {
5157
5241
  _if(() => {
5158
5242
  if (uploading) {
5159
5243
  const $scope18_id = _scope_id();
5160
- _html(`<div${_attr_class("_du")}>uploading…</div>`);
5244
+ _html(`<div${_attr_class("_dw")}>uploading…</div>`);
5161
5245
  writeScope($scope18_id, {});
5162
5246
  return 0;
5163
5247
  }
@@ -5165,7 +5249,7 @@ var term_default = _template("v", (input) => {
5165
5249
  _if(() => {
5166
5250
  if (copiedFlash) {
5167
5251
  const $scope19_id = _scope_id();
5168
- _html(`<div${_attr_class("_dt")}>Copied</div>`);
5252
+ _html(`<div${_attr_class("_dv")}>Copied</div>`);
5169
5253
  writeScope($scope19_id, {});
5170
5254
  return 0;
5171
5255
  }
@@ -5174,7 +5258,7 @@ var term_default = _template("v", (input) => {
5174
5258
  _if(() => {
5175
5259
  if (trapOpen) {
5176
5260
  const $scope10_id = _scope_id();
5177
- _html(`<div${_attr_class("_dv")}><div${_attr_class("_dw")}><p${_attr_class("_d0")}>Long-press below and choose Paste</p><input placeholder="Paste here…">${_el_resume($scope10_id, "d")}<button${_attr_class("_f")}>Cancel</button>${_el_resume($scope10_id, "e")}</div>${_el_resume($scope10_id, "b")}</div>${_el_resume($scope10_id, "a")}`);
5261
+ _html(`<div${_attr_class("_dx")}><div${_attr_class("_dy")}><p${_attr_class("_d2")}>Long-press below and choose Paste</p><input placeholder="Paste here…">${_el_resume($scope10_id, "d")}<button${_attr_class("_f")}>Cancel</button>${_el_resume($scope10_id, "e")}</div>${_el_resume($scope10_id, "b")}</div>${_el_resume($scope10_id, "a")}`);
5178
5262
  _script($scope10_id, "v23");
5179
5263
  _script($scope10_id, "v24");
5180
5264
  writeScope($scope10_id, {});
@@ -5279,7 +5363,7 @@ var work_view_default = _template("y", (input) => {
5279
5363
  let DiffView = null;
5280
5364
  const loadDiffView = _resume(() => {
5281
5365
  if (DiffView) return;
5282
- import("./_Tcoxq_nF.js").then((m) => {
5366
+ import("./_BlRAjywT.js").then((m) => {
5283
5367
  DiffView = m.default;
5284
5368
  });
5285
5369
  }, "y4", $scope0_id);
@@ -5595,8 +5679,7 @@ var work_view_default = _template("y", (input) => {
5595
5679
  const $scope4_id = _scope_id();
5596
5680
  _for_of(shownSessions, (s) => {
5597
5681
  const $scope5_id = _scope_id();
5598
- const $show5 = s.id === curTab;
5599
- _show_start($show5, 1);
5682
+ _html(`<div${_attr_class(["_bU", { ["_bV"]: s.id === curTab }])}>`);
5600
5683
  _set_serialize_reason({
5601
5684
  0: 1,
5602
5685
  1: 1,
@@ -5654,16 +5737,16 @@ var work_view_default = _template("y", (input) => {
5654
5737
  toggleReviewFind();
5655
5738
  }, "y46", $scope5_id)
5656
5739
  });
5657
- _show_end($scope5_id, "d", $show5);
5740
+ _html(`</div>${_el_resume($scope5_id, "a")}`);
5658
5741
  _subscribe($newSession2__closures, _subscribe($renameSession2__closures, _subscribe($closeSession2__closures, _subscribe($toggleReviewFind2__closures, _subscribe($curTab__closures, _subscribe($shownSessions__closures, _subscribe($si__input_workspace && $ws_name__closures, _subscribe($si__input_workspace && $ws_id__closures, _subscribe($reviewFindOpen__closures, _subscribe($view__closures, _subscribe($si__input_agents && $input_agents__closures, _subscribe($si__input_active && $input_active__closures, writeScope($scope5_id, {
5659
- g: s?.id,
5742
+ e: s?.id,
5660
5743
  b: _existing_scope($childScope4)
5661
5744
  })))))))))))));
5662
- }, "id", $scope4_id, "a");
5745
+ }, "id", $scope4_id, "a", 1, 1, 1, 0, 1);
5663
5746
  _if(() => {
5664
5747
  if (!shownSessions.length) {
5665
5748
  const $scope6_id = _scope_id();
5666
- _html(`<div${_attr_class("_bV")}><p${_attr_class("_bW")}>No sessions in this workspace.</p><button${_attr_class(["_f", "_g"])}${_attr("disabled", spawning)}>${spawning ? "Starting…" : `Start ${_escape(`${input.preferred || "claude"}`)}`}${_el_resume($scope6_id, "d")}</button>${_el_resume($scope6_id, "c")}</div>`);
5749
+ _html(`<div${_attr_class("_bX")}><p${_attr_class("_bY")}>No sessions in this workspace.</p><button${_attr_class(["_f", "_g"])}${_attr("disabled", spawning)}>${spawning ? "Starting…" : `Start ${_escape(`${input.preferred || "claude"}`)}`}${_el_resume($scope6_id, "d")}</button>${_el_resume($scope6_id, "c")}</div>`);
5667
5750
  _script($scope6_id, "y48");
5668
5751
  _subscribe($spawning__closures, _subscribe($si__input_preferred && $input_preferred__closures, writeScope($scope6_id, {})));
5669
5752
  return 0;
@@ -5673,7 +5756,7 @@ var work_view_default = _template("y", (input) => {
5673
5756
  return 0;
5674
5757
  } else {
5675
5758
  const $scope10_id = _scope_id();
5676
- _html(`<p${_attr_class("_bU")}>Loading sessions…</p>`);
5759
+ _html(`<p${_attr_class("_bW")}>Loading sessions…</p>`);
5677
5760
  writeScope($scope10_id, {});
5678
5761
  return 1;
5679
5762
  }
@@ -6818,7 +6901,7 @@ var postHandler$11 = normalizeHandler(Run.POST({ search: (value) => parse(Query$
6818
6901
  if (q.session && q.state) {
6819
6902
  const payload = await ctx.request.json().catch(() => void 0);
6820
6903
  if (q.state === "idle") clearAgentPhase(q.session);
6821
- else setAgentPhase(q.session, q.state, q.reason, summaryFromHookPayload(payload));
6904
+ else setAgentPhase(q.session, q.state, reasonFromHookPayload(payload, q.reason), summaryFromHookPayload(payload));
6822
6905
  return Response.json({ ok: true });
6823
6906
  }
6824
6907
  const body = parse(AgentState, await ctx.request.json());
@@ -6832,668 +6915,90 @@ function post2(context) {
6832
6915
  return call(mware4, __postHandler, context);
6833
6916
  }
6834
6917
  //#endregion
6835
- //#region src/server/scrape/engine.ts
6836
- function detect(manifest, input) {
6837
- let winner;
6838
- let winnerText = "";
6839
- for (const rule of manifest.rules) {
6840
- if (winner && rule.priority <= winner.priority) continue;
6841
- const text = region(input, rule.region);
6842
- if (gateMatches(rule, text, text.toLowerCase())) {
6843
- winner = rule;
6844
- winnerText = text;
6845
- }
6846
- }
6847
- if (!winner) return {};
6848
- if (winner.skip_state_update) return { skip: true };
6849
- return {
6850
- state: winner.state === "unknown" ? void 0 : winner.state,
6851
- blockerText: winner.visible_blocker && winner.region !== "osc_title" ? winnerText : void 0
6852
- };
6853
- }
6854
- function gateMatches(gate, text, lower) {
6855
- if (gate.contains?.some((n) => !lower.includes(n.toLowerCase()))) return false;
6856
- if (gate.regex?.some((p) => !compile(p).test(text))) return false;
6857
- if (gate.line_regex?.some((p) => {
6858
- const re = compile(p);
6859
- return !text.split("\n").some((line) => re.test(line));
6860
- })) return false;
6861
- if (gate.all?.some((g) => !gateMatches(g, text, lower))) return false;
6862
- if (gate.any?.length && !gate.any.some((g) => gateMatches(g, text, lower))) return false;
6863
- if (gate.not?.some((g) => gateMatches(g, text, lower))) return false;
6864
- return true;
6865
- }
6866
- /** Rust-regex → JS: translate \x{..} escapes and leading inline flags.
6867
- * Compiled patterns are memoized (manifests are static data). */
6868
- var compiled = /* @__PURE__ */ new Map();
6869
- function compile(pattern) {
6870
- let re = compiled.get(pattern);
6871
- if (!re) {
6872
- let source = pattern;
6873
- let flags = "u";
6874
- const inline = source.match(/^\(\?([ims]+)\)/);
6875
- if (inline) {
6876
- flags += inline[1];
6877
- source = source.slice(inline[0].length);
6878
- }
6879
- source = source.replaceAll(/\\x\{([0-9a-fA-F]+)\}/g, "\\u{$1}").replaceAll("\\A", "^");
6880
- try {
6881
- re = new RegExp(source, flags);
6882
- } catch {
6883
- re = new RegExp(source, flags.replace("u", ""));
6884
- }
6885
- compiled.set(pattern, re);
6886
- }
6887
- return re;
6888
- }
6889
- function region(input, spec) {
6890
- const trimmed = spec.trim();
6891
- if (trimmed === "osc_title") return input.oscTitle;
6892
- if (trimmed === "osc_progress") return "";
6893
- const content = input.screen;
6894
- switch (trimmed) {
6895
- case "whole_recent": return content;
6896
- case "after_last_prompt_marker": return afterLastPromptMarker(content);
6897
- case "prompt_box_body": return promptBoxBody(content);
6898
- case "above_prompt_box": return abovePromptBox(content);
6899
- case "last_non_empty_above_prompt_box": return lastNonEmptyLine(abovePromptBox(content));
6900
- case "after_last_horizontal_rule": return afterLastHorizontalRule(content);
6901
- }
6902
- const bottom = regionCount(trimmed, "bottom_non_empty_lines");
6903
- if (bottom !== void 0) return bottomNonEmptyLines(content, bottom);
6904
- const bottomAll = regionCount(trimmed, "bottom_lines");
6905
- if (bottomAll !== void 0) return content.split("\n").slice(-bottomAll).join("\n");
6906
- const top = regionCount(trimmed, "top_non_empty_lines");
6907
- if (top !== void 0) return topNonEmptyLines(content, top);
6908
- return "";
6909
- }
6910
- function regionCount(spec, name) {
6911
- const match = spec.match(new RegExp(`^${name}\\((\\d+)\\)$`));
6912
- return match ? Number(match[1]) : void 0;
6913
- }
6914
- function bottomNonEmptyLines(content, count) {
6915
- const lines = content.split("\n");
6916
- let seen = 0;
6917
- for (let i = lines.length - 1; i >= 0; i--) if (lines[i].trim()) {
6918
- seen++;
6919
- if (seen === count) return lines.slice(i).join("\n");
6920
- }
6921
- return seen ? lines.join("\n") : "";
6922
- }
6923
- function topNonEmptyLines(content, count) {
6924
- const lines = content.split("\n");
6925
- let seen = 0;
6926
- for (let i = 0; i < lines.length; i++) if (lines[i].trim()) {
6927
- seen++;
6928
- if (seen === count) return lines.slice(0, i + 1).join("\n");
6929
- }
6930
- return seen ? lines.join("\n") : "";
6931
- }
6932
- /** Codex draws its prompt as a "›" line; content after the last one is the
6933
- * live tail of the turn. */
6934
- function afterLastPromptMarker(content) {
6935
- const lines = content.split("\n");
6936
- for (let i = lines.length - 1; i >= 0; i--) if (lines[i] === "›" || lines[i].startsWith("› ")) return lines.slice(i + 1).join("\n");
6937
- return content;
6938
- }
6939
- function isHorizontalRule(line) {
6940
- const trimmed = line.trim();
6941
- if (!trimmed) return false;
6942
- let rule = 0;
6943
- for (const ch of trimmed) if (ch === "─") rule++;
6944
- else break;
6945
- if (!rule) return false;
6946
- return !trimmed.slice(rule).trimStart() || rule >= 3;
6947
- }
6948
- function afterLastHorizontalRule(content) {
6949
- const lines = content.split("\n");
6950
- for (let i = lines.length - 1; i >= 0; i--) if (isHorizontalRule(lines[i])) return lines.slice(i + 1).join("\n");
6951
- return content;
6952
- }
6953
- /** The prompt box's inner text: between the last two horizontal rules
6954
- * (its borders), scanning bottom-up. */
6955
- function promptBoxTopBorderIndex(lines) {
6956
- let borders = 0;
6957
- for (let i = lines.length - 1; i >= 0; i--) if (isHorizontalRule(lines[i])) {
6958
- borders++;
6959
- if (borders === 2) return i;
6960
- }
6961
- }
6962
- function promptBoxBody(content) {
6963
- const lines = content.split("\n");
6964
- const top = promptBoxTopBorderIndex(lines);
6965
- if (top === void 0) return "";
6966
- let end = lines.length;
6967
- for (let i = top + 1; i < lines.length; i++) if (isHorizontalRule(lines[i])) {
6968
- end = i;
6969
- break;
6970
- }
6971
- return lines.slice(top + 1, end).join("\n");
6972
- }
6973
- function abovePromptBox(content) {
6974
- const lines = content.split("\n");
6975
- const top = promptBoxTopBorderIndex(lines);
6976
- return top === void 0 ? content : lines.slice(0, top).join("\n");
6977
- }
6978
- function lastNonEmptyLine(content) {
6979
- const lines = content.split("\n");
6980
- for (let i = lines.length - 1; i >= 0; i--) if (lines[i].trim()) return lines[i];
6981
- return "";
6982
- }
6983
- /** Session agent kind → manifest ("shell" has none). */
6984
- var MANIFESTS = {
6985
- claude: {
6986
- id: "claude",
6987
- rules: [
6988
- {
6989
- id: "osc_title_working",
6990
- state: "working",
6991
- priority: 1100,
6992
- region: "osc_title",
6993
- regex: ["^[\\x{2800}-\\x{28FF}] "]
6994
- },
6995
- {
6996
- id: "btw_overlay_working",
6997
- state: "working",
6998
- priority: 975,
6999
- region: "bottom_non_empty_lines(5)",
7000
- line_regex: ["^\\s*/btw(?:\\s|$)", "(?i)esc to close\\s*$"]
7001
- },
7002
- {
7003
- id: "transcript_viewer",
7004
- state: "unknown",
7005
- priority: 1e3,
7006
- region: "bottom_non_empty_lines(3)",
7007
- skip_state_update: true,
7008
- contains: ["showing detailed transcript"],
7009
- any: [
7010
- { contains: ["ctrl+o", "to toggle"] },
7011
- { contains: ["ctrl+e", "show all"] },
7012
- { contains: ["ctrl+e", "collapse"] },
7013
- { contains: ["↑↓ scroll"] },
7014
- { contains: ["? for shortcuts"] }
7015
- ]
7016
- },
7017
- {
7018
- id: "live_blocked_form",
7019
- state: "blocked",
7020
- priority: 980,
7021
- region: "after_last_horizontal_rule",
7022
- visible_blocker: true,
7023
- contains: ["esc to cancel"],
7024
- any: [{ contains: ["enter to confirm"] }, {
7025
- contains: ["enter to select"],
7026
- any: [
7027
- { contains: ["tab/arrow keys to navigate"] },
7028
- { contains: ["arrow keys to navigate"] },
7029
- { contains: ["arrows to navigate"] },
7030
- { contains: ["↑/↓ to navigate"] },
7031
- { contains: ["↑↓ to navigate"] }
7032
- ]
7033
- }]
7034
- },
7035
- {
7036
- id: "dynamic_workflow_prompt",
7037
- state: "blocked",
7038
- priority: 980,
7039
- region: "whole_recent",
7040
- visible_blocker: true,
7041
- contains: ["run a dynamic workflow?", "esc to cancel"]
7042
- },
7043
- {
7044
- id: "live_prompt_box",
7045
- state: "idle",
7046
- priority: 950,
7047
- region: "prompt_box_body",
7048
- line_regex: ["^\\s*❯"],
7049
- not: [
7050
- { contains: ["enter to select"] },
7051
- { contains: ["esc to cancel"] },
7052
- { contains: ["tab/arrow keys"] },
7053
- { contains: ["arrow keys to navigate"] },
7054
- { contains: ["↑/↓ to navigate"] }
7055
- ]
7056
- },
7057
- {
7058
- id: "model_picker_menu",
7059
- state: "unknown",
7060
- priority: 900,
7061
- region: "whole_recent",
7062
- skip_state_update: true,
7063
- contains: [
7064
- "select model",
7065
- "enter to set as default",
7066
- "esc to cancel"
7067
- ],
7068
- not: [{ contains: ["do you want to proceed?"] }, { contains: ["enter to select"] }]
7069
- },
7070
- {
7071
- id: "bash_permission_prompt",
7072
- state: "blocked",
7073
- priority: 850,
7074
- region: "whole_recent",
7075
- visible_blocker: true,
7076
- contains: ["do you want to proceed?"],
7077
- any: [
7078
- { contains: ["bash command"] },
7079
- { contains: ["bash("] },
7080
- { contains: ["contains expansion"] },
7081
- { contains: ["tab to amend"] },
7082
- { contains: ["ctrl+e to explain"] }
7083
- ],
7084
- all: [{ any: [
7085
- { line_regex: ["(?i)^\\s*❯?\\s*yes\\b"] },
7086
- { line_regex: ["(?i)^\\s*1\\.\\s*yes\\b"] },
7087
- { line_regex: ["(?i)^\\s*2\\.\\s*no\\b"] }
7088
- ] }]
7089
- },
7090
- {
7091
- id: "generic_permission_prompt",
7092
- state: "blocked",
7093
- priority: 840,
7094
- region: "after_last_horizontal_rule",
7095
- visible_blocker: true,
7096
- contains: ["do you want to proceed?", "esc to cancel"],
7097
- all: [{ any: [
7098
- { line_regex: ["(?i)^\\s*❯?\\s*1\\.\\s*yes\\b"] },
7099
- { line_regex: ["(?i)^\\s*2\\.\\s*yes\\b"] },
7100
- { line_regex: ["(?i)^\\s*2\\.\\s*no\\b"] },
7101
- { line_regex: ["(?i)^\\s*3\\.\\s*no\\b"] }
7102
- ] }]
7103
- },
7104
- {
7105
- id: "legacy_no_prompt_blocker",
7106
- state: "blocked",
7107
- priority: 300,
7108
- region: "whole_recent",
7109
- any: [
7110
- {
7111
- contains: ["do you want to"],
7112
- any: [{ contains: ["yes"] }, { contains: ["❯"] }]
7113
- },
7114
- {
7115
- contains: ["would you like to"],
7116
- any: [{ contains: ["yes"] }, { contains: ["❯"] }]
7117
- },
7118
- { contains: ["waiting for permission"] },
7119
- { contains: ["do you want to allow this connection?"] },
7120
- { contains: ["tab to amend"] },
7121
- { contains: ["ctrl+e to explain"] },
7122
- { contains: ["do you want to proceed?", "esc to cancel"] },
7123
- { contains: ["review your answers"] },
7124
- { contains: ["skip interview and plan immediately"] }
7125
- ],
7126
- not: [{ regex: ["(?m)^\\s*❯\\s*$"] }]
7127
- },
7128
- {
7129
- id: "osc_title_idle",
7130
- state: "idle",
7131
- priority: 250,
7132
- region: "osc_title",
7133
- regex: ["^\\x{2733} "]
7134
- },
7135
- {
7136
- id: "osc_progress_idle",
7137
- state: "idle",
7138
- priority: 250,
7139
- region: "osc_progress",
7140
- regex: ["^4;0"]
7141
- }
7142
- ]
7143
- },
7144
- codex: {
7145
- id: "codex",
7146
- rules: [
7147
- {
7148
- id: "osc_title_blocked",
7149
- state: "blocked",
7150
- priority: 1100,
7151
- region: "osc_title",
7152
- visible_blocker: true,
7153
- contains: ["Action Required"]
7154
- },
7155
- {
7156
- id: "osc_title_working",
7157
- state: "working",
7158
- priority: 1050,
7159
- region: "osc_title",
7160
- regex: ["(?:^| )[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏](?: |$)"]
7161
- },
7162
- {
7163
- id: "transcript_viewer",
7164
- state: "unknown",
7165
- priority: 1e3,
7166
- region: "after_last_prompt_marker",
7167
- skip_state_update: true,
7168
- contains: [
7169
- "↑/↓ to scroll",
7170
- "pgup/pgdn to",
7171
- "home/end to jump",
7172
- "q to quit"
7173
- ],
7174
- any: [{ contains: ["esc to edit prev"] }, { contains: ["esc/← to edit prev"] }]
7175
- },
7176
- {
7177
- id: "trust_directory",
7178
- state: "blocked",
7179
- priority: 950,
7180
- region: "top_non_empty_lines(20)",
7181
- visible_blocker: true,
7182
- all: [{ regex: ["^> You are in [^\\r\\n]+(?:\\r?\\n|$)"] }, { regex: ["(?s)Do\\s+you\\s+trust\\s+the\\s+contents\\s+of\\s+this\\s+directory\\?"] }]
7183
- },
7184
- {
7185
- id: "live_strong_blocker",
7186
- state: "blocked",
7187
- priority: 900,
7188
- region: "after_last_prompt_marker",
7189
- visible_blocker: true,
7190
- any: [
7191
- { contains: ["press enter to confirm or esc to cancel"] },
7192
- { contains: ["enter to submit answer"] },
7193
- { contains: ["enter to submit all"] },
7194
- { contains: ["allow command?"] }
7195
- ]
7196
- },
7197
- {
7198
- id: "weak_blocker",
7199
- state: "blocked",
7200
- priority: 600,
7201
- region: "whole_recent",
7202
- any: [
7203
- { contains: ["[y/n]"] },
7204
- { contains: ["yes (y)"] },
7205
- {
7206
- contains: ["do you want to"],
7207
- any: [{ contains: ["yes"] }, { contains: ["❯"] }]
7208
- },
7209
- {
7210
- contains: ["would you like to"],
7211
- any: [{ contains: ["yes"] }, { contains: ["❯"] }]
7212
- }
7213
- ]
7214
- },
7215
- {
7216
- id: "screen_working_fallback",
7217
- state: "working",
7218
- priority: 500,
7219
- region: "bottom_non_empty_lines(3)",
7220
- line_regex: ["^[•◦]\\s+Working \\([^)]*esc to interrupt\\)(?: · .*)?$"],
7221
- not: [{ contains: ["■ Conversation interrupted"] }]
7222
- },
7223
- {
7224
- id: "osc_title_idle",
7225
- state: "idle",
7226
- priority: 100,
7227
- region: "osc_title",
7228
- regex: ["\\S"],
7229
- not: [{ regex: ["(?:^| )[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏](?: |$)"] }, { contains: ["Action Required"] }]
7230
- }
7231
- ]
7232
- },
7233
- cursor: {
7234
- id: "cursor",
7235
- rules: [
7236
- {
7237
- id: "write_file_approval",
7238
- state: "blocked",
7239
- priority: 320,
7240
- region: "bottom_non_empty_lines(8)",
7241
- visible_blocker: true,
7242
- contains: ["write to this file?", "proceed (y)"],
7243
- any: [
7244
- { contains: ["reject & propose changes"] },
7245
- { contains: ["esc or n or p"] },
7246
- { contains: ["add write("] }
7247
- ]
7248
- },
7249
- {
7250
- id: "approval_prompt",
7251
- state: "blocked",
7252
- priority: 300,
7253
- region: "whole_recent",
7254
- visible_blocker: true,
7255
- any: [
7256
- {
7257
- contains: ["waiting for approval", "run this command?"],
7258
- any: [{ contains: ["run (once) (y)"] }, { contains: ["skip (esc or n)"] }]
7259
- },
7260
- { contains: ["(y) (enter)"] },
7261
- { line_regex: ["(?i)^\\s*allow .*\\(y\\)"] },
7262
- { contains: ["keep (n)"] },
7263
- { contains: ["skip (esc or n)"] },
7264
- { line_regex: ["(?i)^\\s*(?:→\\s*)?run .*\\(y\\)"] }
7265
- ]
7266
- },
7267
- {
7268
- id: "stop_hint_working",
7269
- state: "working",
7270
- priority: 100,
7271
- region: "bottom_non_empty_lines(6)",
7272
- contains: ["ctrl+c to stop"]
7273
- },
7274
- {
7275
- id: "background_task_status_working",
7276
- state: "working",
7277
- priority: 95,
7278
- region: "bottom_non_empty_lines(5)",
7279
- line_regex: ["(?i)\\b[1-9][0-9]*\\s+background\\s+tasks?\\b"]
7280
- },
7281
- {
7282
- id: "spinner_working",
7283
- state: "working",
7284
- priority: 90,
7285
- region: "bottom_non_empty_lines(8)",
7286
- line_regex: ["^\\s*(⬡|⬢|[\\x{2800}-\\x{28FF}]+)\\s+\\p{Alphabetic}+\\w*ing\\b"]
7287
- }
7288
- ]
7289
- },
7290
- grok: {
7291
- id: "grok",
7292
- rules: [
7293
- {
7294
- id: "osc_title_blocked",
7295
- state: "blocked",
7296
- priority: 1300,
7297
- region: "osc_title",
7298
- visible_blocker: true,
7299
- contains: ["Action Required"]
7300
- },
7301
- {
7302
- id: "option_dialog_blocked",
7303
- state: "blocked",
7304
- priority: 1200,
7305
- region: "whole_recent",
7306
- visible_blocker: true,
7307
- line_regex: ["^\\s*┃\\s+[0-9a-z]+\\s+\\([●○]\\)\\s"]
7308
- },
7309
- {
7310
- id: "permission_hints_blocked",
7311
- state: "blocked",
7312
- priority: 1190,
7313
- region: "bottom_non_empty_lines(2)",
7314
- visible_blocker: true,
7315
- contains: [
7316
- ":select",
7317
- "ctrl+o:yolo",
7318
- "ctrl+c:cancel"
7319
- ]
7320
- },
7321
- {
7322
- id: "question_dialog_hints_blocked",
7323
- state: "blocked",
7324
- priority: 1185,
7325
- region: "bottom_non_empty_lines(2)",
7326
- visible_blocker: true,
7327
- contains: ["tab:scrollback", "shift+x:dismiss"]
7328
- },
7329
- {
7330
- id: "permission_scope_selector",
7331
- state: "blocked",
7332
- priority: 1180,
7333
- region: "whole_recent",
7334
- visible_blocker: true,
7335
- contains: ["yes, proceed", "no, reject"],
7336
- any: [{ contains: ["use ← → to choose permission whitelist scope"] }, { contains: ["←/→:scope"] }]
7337
- },
7338
- {
7339
- id: "background_work_chip_working",
7340
- state: "working",
7341
- priority: 1170,
7342
- region: "top_non_empty_lines(1)",
7343
- line_regex: ["[⋅:⸬⁙.·]\\s+[1-9][0-9]*\\s+│"]
7344
- },
7345
- {
7346
- id: "osc_progress_working",
7347
- state: "working",
7348
- priority: 1150,
7349
- region: "osc_progress",
7350
- regex: ["^4;1;-1$"]
7351
- },
7352
- {
7353
- id: "osc_title_idle",
7354
- state: "idle",
7355
- priority: 1100,
7356
- region: "osc_title",
7357
- regex: ["(?:^| - )grok$"],
7358
- not: [{ regex: ["[\\x{2800}-\\x{28FF}]"] }]
7359
- },
7360
- {
7361
- id: "osc_title_working",
7362
- state: "working",
7363
- priority: 1e3,
7364
- region: "osc_title",
7365
- regex: ["\\S"]
7366
- },
7367
- {
7368
- id: "osc_progress_idle",
7369
- state: "idle",
7370
- priority: 950,
7371
- region: "osc_progress",
7372
- regex: ["^4;0;0$"]
7373
- },
7374
- {
7375
- id: "spinner_status_working",
7376
- state: "working",
7377
- priority: 200,
7378
- region: "whole_recent",
7379
- line_regex: ["^\\s*[\\x{2801}-\\x{28FF}]\\s.*\\[stop\\]\\s*$"]
7380
- },
7381
- {
7382
- id: "esc_cancel_hints_working",
7383
- state: "working",
7384
- priority: 190,
7385
- region: "bottom_non_empty_lines(2)",
7386
- contains: ["esc:cancel", "ctrl+.:shortcuts"]
7387
- },
7388
- {
7389
- id: "waiting_tool_working",
7390
- state: "working",
7391
- priority: 120,
7392
- region: "whole_recent",
7393
- any: [{ all: [{ contains: ["ctrl+c:cancel", "ctrl+enter:interject"] }, { contains: ["waiting"] }] }, { line_regex: ["^\\s*[\\x{2801}-\\x{28FF}]\\s+(Run|Read|Search|List)\\b"] }]
7394
- },
7395
- {
7396
- id: "prompt_hints_idle",
7397
- state: "idle",
7398
- priority: 100,
7399
- region: "bottom_non_empty_lines(2)",
7400
- contains: ["ctrl+.:shortcuts"],
7401
- not: [{ contains: ["esc:cancel"] }, { contains: ["ctrl+c:cancel"] }]
7402
- }
7403
- ]
7404
- },
7405
- copilot: {
7406
- id: "copilot",
7407
- rules: [{
7408
- id: "selection_blocker",
7409
- state: "blocked",
7410
- priority: 300,
7411
- region: "whole_recent",
7412
- visible_blocker: true,
7413
- all: [{ any: [{ contains: ["esc to cancel"] }, { contains: ["esc cancel"] }] }, { any: [
7414
- { contains: ["enter to select"] },
7415
- { contains: ["enter to confirm"] },
7416
- { contains: ["enter to submit"] },
7417
- { contains: ["enter accept"] }
7418
- ] }]
7419
- }, {
7420
- id: "working_cancel_hint",
7421
- state: "working",
7422
- priority: 100,
7423
- region: "whole_recent",
7424
- any: [
7425
- { contains: ["esc to cancel"] },
7426
- { contains: ["esc cancel"] },
7427
- { contains: ["esc again to cancel"] },
7428
- { contains: ["esc interrupt"] }
7429
- ]
7430
- }]
7431
- }
7432
- };
7433
- //#endregion
7434
6918
  //#region src/server/scraper.ts
7435
- /** Herdr-style terminal scraping: agent state read from each session's
7436
- * pane title (set by the CLI via OSC) and rendered screen, matched against
7437
- * herdr's per-agent detection manifests (see scrape/manifests.ts). This is
7438
- * the primary state source for every agent CLI; Claude and Codex
7439
- * additionally report through launch-flag hooks (agent-flags.ts), which
7440
- * carry clean notification text. */
6919
+ /** Whether an agent session is doing anything, from tmux alone.
6920
+ *
6921
+ * tmux stamps every pane with the time it last produced output, and that
6922
+ * is the whole signal here: a pane that is writing is a turn in progress,
6923
+ * one that has gone quiet is a turn that ended. Nothing reads what is on
6924
+ * the screen.
6925
+ *
6926
+ * Only agents that cannot say it themselves are watched. An agent whose
6927
+ * hooks report both starting and stopping is left alone entirely — asking
6928
+ * two sources about one fact means arbitrating them when they disagree,
6929
+ * and the screen always disagrees last, because it is still painting the
6930
+ * reply after the hook has said the turn is over.
6931
+ *
6932
+ * What is given up: a CLI with no hooks looks the same stopped on a
6933
+ * question as it does finished, since a pane waiting for an answer is
6934
+ * silent either way. What is gained: one `list-panes` a tick whatever the
6935
+ * session count, and no rules to keep matching five CLIs that redecorate
6936
+ * whenever they like. */
7441
6937
  var POLL_MS = 2e3;
7442
- /** With no scrapeable sessions there's nothing to watch — idle at a slow
7443
- * tick instead of waking every 2s forever. */
6938
+ /** Nothing to watch — idle at a slow tick instead of waking every 2s. */
7444
6939
  var IDLE_POLL_MS = 15e3;
6940
+ /** Quiet for this long is a stopped turn. Comfortably above one poll, so a
6941
+ * pane that writes in bursts is not called idle between them, and above
6942
+ * tmux's one-second stamp resolution. */
6943
+ var IDLE_AFTER_MS = 4e3;
6944
+ /** Opening a session sizes the tmux window to the browser, and an agent
6945
+ * TUI repaints itself on the resize. That repaint moves the stamp exactly
6946
+ * as output would, so a session reads busy the moment you look at it.
6947
+ *
6948
+ * What separates them is *when*: the repaint carries the second the attach
6949
+ * happened, while anything the agent goes on to write carries a later one.
6950
+ * So the attach is recorded, and for a short while after it a stamp from
6951
+ * that same second is not treated as output — but a later one still is, so
6952
+ * a session you open and immediately give work to still lights up. */
6953
+ var ATTACH_SETTLE_MS = 8e3;
6954
+ /** tmux stamps whole seconds, so the repaint can land in the second after
6955
+ * the attach as easily as the one it happened in. */
6956
+ var ATTACH_GRACE_MS = 1500;
6957
+ var attachedAt = /* @__PURE__ */ new Map();
6958
+ function noteViewerAttached(sessionId) {
6959
+ attachedAt.set(sessionId, Date.now());
6960
+ }
7445
6961
  function startScraper() {
7446
6962
  if (started) return;
7447
6963
  started = true;
7448
6964
  const tick = async () => {
7449
- const scanned = await scan().catch(() => false);
7450
- setTimeout(tick, scanned ? POLL_MS : IDLE_POLL_MS).unref?.();
6965
+ const watching = await scan().catch(() => false);
6966
+ setTimeout(tick, watching ? POLL_MS : IDLE_POLL_MS).unref?.();
7451
6967
  };
7452
6968
  tick();
7453
6969
  }
7454
6970
  var started = false;
7455
- /** Returns whether there was anything to scrape (drives the poll cadence). */
6971
+ /** Returns whether there was anything to watch (drives the poll cadence). */
7456
6972
  async function scan() {
7457
- const sessions = all("SELECT id, agent FROM sessions").filter((session) => session.agent in MANIFESTS);
6973
+ const sessions = all("SELECT id, agent FROM sessions").filter((session) => session.agent !== "shell" && !reportsWorking(session.agent));
7458
6974
  if (!sessions.length) return false;
7459
- const panes = /* @__PURE__ */ new Map();
7460
6975
  const out = await tmux([
7461
6976
  "list-panes",
7462
6977
  "-a",
7463
6978
  "-F",
7464
- "#{session_name} #{pane_title}"
6979
+ "#{session_name} #{window_activity}"
7465
6980
  ]).catch(() => null);
7466
6981
  if (out === null) return false;
6982
+ const wroteAt = /* @__PURE__ */ new Map();
7467
6983
  for (const line of out.split("\n")) {
7468
- const [name, ...title] = line.split(" ");
7469
- if (name?.startsWith("wk-")) panes.set(name.slice(3), title.join(" "));
6984
+ const [name, stamp] = line.split(" ");
6985
+ if (name?.startsWith("wk-")) wroteAt.set(name.slice(3), Number(stamp) * 1e3);
7470
6986
  }
6987
+ const now = Date.now();
6988
+ let live = 0;
7471
6989
  for (const session of sessions) {
7472
- if (panes.has(session.id)) continue;
7473
- clearAgentPhase(session.id);
6990
+ const wrote = wroteAt.get(session.id);
6991
+ if (wrote === void 0) {
6992
+ clearAgentPhase(session.id);
6993
+ attachedAt.delete(session.id);
6994
+ continue;
6995
+ }
6996
+ live++;
6997
+ const attached = attachedAt.get(session.id);
6998
+ const busy = !(attached !== void 0 && now - attached < ATTACH_SETTLE_MS && wrote <= attached + ATTACH_GRACE_MS) && Number.isFinite(wrote) && now - wrote < IDLE_AFTER_MS;
6999
+ setScrapedPhase(session.id, busy ? "working" : void 0);
7474
7000
  }
7475
- const live = sessions.filter((session) => panes.has(session.id));
7476
- await Promise.all(live.map(async (session) => {
7477
- const screen = await tmux([
7478
- "capture-pane",
7479
- "-p",
7480
- "-J",
7481
- "-t",
7482
- `wk-${session.id}`
7483
- ]).catch(() => "");
7484
- const result = detect(MANIFESTS[session.agent], {
7485
- screen,
7486
- oscTitle: panes.get(session.id)
7487
- });
7488
- if (result.skip) return;
7489
- setScrapedPhase(session.id, result.state === "working" ? "working" : result.state === "blocked" ? "waiting" : void 0, result.blockerText && blockerSummary(result.blockerText));
7490
- }));
7491
- return live.length > 0;
7492
- }
7493
- /** Human-readable line(s) from a blocker region: the question the agent is
7494
- * asking, with box borders, option lists, and hint bars stripped. */
7495
- function blockerSummary(region) {
7496
- return region.split("\n").map((line) => line.replace(/^[│┃⎿└├]\s*/, "").replace(/\s*[│┃]$/, "").trim()).filter((line) => line && !/^[╭╰│─━┃❯>✳·. ]+$/.test(line) && !/^❯?\s*\d+\.\s/.test(line) && !/^[0-9a-z]+\s+\([●○]\)\s/.test(line) && !/(ctrl\+|esc to|esc or|esc:|:select|shift\+|\(y\)|\(n\)|y\/n|arrow keys|↑|↓|tab to|enter to)/i.test(line)).slice(0, 2).join(" — ").slice(0, 180) || void 0;
7001
+ return live > 0;
7497
7002
  }
7498
7003
  //#endregion
7499
7004
  //#region src/server/boot.ts
@@ -7640,7 +7145,11 @@ var Query = /* @__PURE__ */ object({
7640
7145
  var postHandler$8 = normalizeHandler(Run.POST({ search: (value) => parse(Query, value) }, async (ctx) => {
7641
7146
  if (ctx.search.token !== hookToken()) return Response.json({ error: "bad token" }, { status: 403 });
7642
7147
  notePushActivity();
7643
- await refreshPrsBatch([ctx.search.repo], true).catch(() => {});
7148
+ const targets = activeRepoTargets().filter((t) => t.fullName === ctx.search.repo);
7149
+ await refreshPrsBatch(targets.length ? targets : [{
7150
+ fullName: ctx.search.repo,
7151
+ branch: ""
7152
+ }], true).catch(() => {});
7644
7153
  pokeStatusWatch();
7645
7154
  return Response.json({ ok: true });
7646
7155
  }), "POST");
@@ -8827,7 +8336,7 @@ async function workspaceDiff(ws, opts = {}) {
8827
8336
  "--abbrev-ref",
8828
8337
  "HEAD"
8829
8338
  ], dir).catch(() => "HEAD");
8830
- const localHead = await git(["rev-parse", "HEAD"], dir).catch(() => "");
8339
+ const localHead = await headOid(dir);
8831
8340
  const open = (await workspacePrs(repo.full_name, ws.branch, foreign, refresh)).filter((p) => p.state === "OPEN" && p.baseRefName && p.headRefName && (!focus || focus === `${repo.worktree}/${p.number}`));
8832
8341
  if (open.length) return Promise.all(open.map((p) => prDiff(dir, repo, p, {
8833
8342
  uncommitted: uncommitted && branch === p.headRefName,
@@ -9158,11 +8667,31 @@ var Dismiss = /* @__PURE__ */ object({
9158
8667
  number: /* @__PURE__ */ pipe(/* @__PURE__ */ number(), /* @__PURE__ */ integer())
9159
8668
  });
9160
8669
  var POST$3 = Run.POST({ json: Dismiss }, async (ctx) => {
8670
+ const ws = ctx.data.workspace;
9161
8671
  const body = await readBody(ctx);
9162
- dismissPr(ctx.data.workspace.id, body.fullName, body.number);
8672
+ dismissPr(ws.id, body.fullName, body.number);
8673
+ await pruneDismissedLane(ws, body.fullName, body.number);
9163
8674
  pokeStatusWatch();
9164
- return Response.json(await listPrs(ctx.data.workspace, false));
8675
+ return Response.json(await listPrs(ws, false));
9165
8676
  });
8677
+ /** Dismissing a finished lane's chip is the point at which the user says
8678
+ * they are done with it, so take the local branch with it — otherwise a
8679
+ * lane's ref lives in the shared bare cache until the whole workspace is
8680
+ * deleted, and they accumulate for as long as the workspace does.
8681
+ *
8682
+ * The workspace's open PRs are fetched without a recency bound, so this
8683
+ * list settles whether anything else still needs the branch without asking
8684
+ * GitHub again. Best-effort throughout: a lane that cannot be pruned is
8685
+ * left alone rather than failing the dismissal the user asked for. */
8686
+ async function pruneDismissedLane(ws, fullName, number) {
8687
+ try {
8688
+ const list = await workspacePrs(fullName, ws.branch, otherWorkspaceBranches(ws.id));
8689
+ const pr = list.find((p) => p.number === number);
8690
+ if (!pr || pr.state === "OPEN" || !pr.headRefOid) return;
8691
+ if (list.some((p) => p.headRefName === pr.headRefName && p.state === "OPEN")) return;
8692
+ await pruneLaneBranch(ws.id, fullName, pr.headRefName, pr.headRefOid);
8693
+ } catch {}
8694
+ }
9166
8695
  async function listPrs(ws, refresh) {
9167
8696
  const foreign = otherWorkspaceBranches(ws.id);
9168
8697
  return Promise.all(ws.repos.map(async (repo) => ({
@@ -13538,6 +13067,7 @@ var lastForced = /* @__PURE__ */ new Map();
13538
13067
  * notifications skip sessions someone is actively watching. */
13539
13068
  var viewerCounts = /* @__PURE__ */ new Map();
13540
13069
  function trackViewer(sessionId, delta) {
13070
+ if (delta > 0) noteViewerAttached(sessionId);
13541
13071
  const count = Math.max(0, (viewerCounts.get(sessionId) ?? 0) + delta);
13542
13072
  if (count > 0) viewerCounts.set(sessionId, count);
13543
13073
  else viewerCounts.delete(sessionId);
@@ -13612,7 +13142,9 @@ function attachTermServer(server) {
13612
13142
  let dims = [cols, rows];
13613
13143
  const forceWindowSize = () => {
13614
13144
  if (!visible) return;
13615
- lastForced.set(session.id, `${dims[0]}x${dims[1]}`);
13145
+ const key = `${dims[0]}x${dims[1]}`;
13146
+ if (lastForced.get(session.id) === key) return;
13147
+ lastForced.set(session.id, key);
13616
13148
  tmux([
13617
13149
  "resize-window",
13618
13150
  "-t",
@@ -13811,4 +13343,4 @@ server.listen(port, () => {
13811
13343
  //#endregion
13812
13344
  export {};
13813
13345
 
13814
- ;var __MARKO_MANIFEST__={"esfPH6H":{"block":[2,"stylesheet#/assets/preload-helper-Cioq5Qre.css",6,"<link",0," rel=\"stylesheet\" crossorigin href=\"",1,"assets/preload-helper-Cioq5Qre.css\"",">",2,"stylesheet#/assets/index-c70b3ZMB.css",6,"<link",0," rel=\"stylesheet\" crossorigin href=\"",1,"assets/index-c70b3ZMB.css\"",">"],"defer":[2,"/assets/index-DKRkgwLo.js",6,"<script",0," async type=\"module\" crossorigin src=\"",1,"assets/index-DKRkgwLo.js\"","></script>",2,"modulepreload#/assets/_CIVAj2XC.js",6,"<link",0," rel=\"modulepreload\" crossorigin href=\"",1,"assets/_CIVAj2XC.js\"",">"]}};
13346
+ ;var __MARKO_MANIFEST__={"esfPH6H":{"block":[2,"stylesheet#/assets/preload-helper-EAZGOO6u.css",6,"<link",0," rel=\"stylesheet\" crossorigin href=\"",1,"assets/preload-helper-EAZGOO6u.css\"",">",2,"stylesheet#/assets/index-7WlgwCwh.css",6,"<link",0," rel=\"stylesheet\" crossorigin href=\"",1,"assets/index-7WlgwCwh.css\"",">"],"defer":[2,"/assets/index-BffJzCDz.js",6,"<script",0," async type=\"module\" crossorigin src=\"",1,"assets/index-BffJzCDz.js\"","></script>",2,"modulepreload#/assets/_YewM841C.js",6,"<link",0," rel=\"modulepreload\" crossorigin href=\"",1,"assets/_YewM841C.js\"",">"]}};