@dylanpiercey/work 0.0.44 → 0.0.45

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 (243) hide show
  1. package/dist/{_B6irorCp.js → _BlvusYIA.js} +2 -2
  2. package/dist/{_Tcoxq_nF.js → _DncwyiYL.js} +17 -17
  3. package/dist/{_Cja4R2gP.js → _P9IsUQm2.js} +58 -59
  4. package/dist/_kABYZA6_.js +2 -0
  5. package/dist/index.mjs +398 -867
  6. package/dist/public/assets/{_D0en76Ej.js → _0jDMZ5Nf.js} +1 -1
  7. package/dist/public/assets/_0jDMZ5Nf.js.br +0 -0
  8. package/dist/public/assets/{_dAPOyRJr.js → _2JIp-AkL.js} +1 -1
  9. package/dist/public/assets/_2JIp-AkL.js.br +0 -0
  10. package/dist/public/assets/{_DAVDeGoR.js → _6t6kjpdU.js} +1 -1
  11. package/dist/public/assets/_6t6kjpdU.js.br +0 -0
  12. package/dist/public/assets/{_D_EzfDaC.js → _7WXyLEhK.js} +1 -1
  13. package/dist/public/assets/_7WXyLEhK.js.br +0 -0
  14. package/dist/public/assets/{_CIVAj2XC.js → _B-HE1A0L.js} +1 -1
  15. package/dist/public/assets/_B-HE1A0L.js.br +0 -0
  16. package/dist/public/assets/{_D5BjTqU42.js → _B-tmCiTe2.js} +1 -1
  17. package/dist/public/assets/_B-tmCiTe2.js.br +0 -0
  18. package/dist/public/assets/{_CcjW-l5T.js → _B1lH2KuX.js} +1 -1
  19. package/dist/public/assets/_B1lH2KuX.js.br +0 -0
  20. package/dist/public/assets/{_DJAJCWgm.js → _B2jdNsMP.js} +5 -5
  21. package/dist/public/assets/_B2jdNsMP.js.br +0 -0
  22. package/dist/public/assets/{_Bd7b48iJ.js → _B6bkX_xw.js} +1 -1
  23. package/dist/public/assets/_B6bkX_xw.js.br +0 -0
  24. package/dist/public/assets/{_FT8jstIj.js → _B7_IQvxy.js} +1 -1
  25. package/dist/public/assets/_B7_IQvxy.js.br +0 -0
  26. package/dist/public/assets/{_ePAxCx7r.js → _BBnPf4LB.js} +1 -1
  27. package/dist/public/assets/_BBnPf4LB.js.br +0 -0
  28. package/dist/public/assets/{_BPvgcQ_P.js → _BEn7bsbI.js} +1 -1
  29. package/dist/public/assets/_BEn7bsbI.js.br +0 -0
  30. package/dist/public/assets/{_Bnp1UtCp2.js → _BKPFmzRa2.js} +1 -1
  31. package/dist/public/assets/_BKPFmzRa2.js.br +0 -0
  32. package/dist/public/assets/{_CJ4aiC36.js → _BKSy9tfl.js} +1 -1
  33. package/dist/public/assets/_BKSy9tfl.js.br +0 -0
  34. package/dist/public/assets/{_Z_Oh39Jb.js → _BPhrpOAd.js} +1 -1
  35. package/dist/public/assets/_BPhrpOAd.js.br +0 -0
  36. package/dist/public/assets/{_DZtm6WF2.js → _BQKEgF_-.js} +1 -1
  37. package/dist/public/assets/_BQKEgF_-.js.br +0 -0
  38. package/dist/public/assets/{_DA_t7MOs2.js → _BVVf3KNx2.js} +1 -1
  39. package/dist/public/assets/_BVVf3KNx2.js.br +0 -0
  40. package/dist/public/assets/{_D0ljGGvp2.js → _BdE0YzeT2.js} +1 -1
  41. package/dist/public/assets/_BdE0YzeT2.js.br +0 -0
  42. package/dist/public/assets/{_BCTR0wV0.js → _BeS7I1tE.js} +1 -1
  43. package/dist/public/assets/_BeS7I1tE.js.br +0 -0
  44. package/dist/public/assets/{_DtMzVsHW2.js → _Bj8eqKyf2.js} +1 -1
  45. package/dist/public/assets/_Bj8eqKyf2.js.br +0 -0
  46. package/dist/public/assets/{_DvsUo16D2.js → _BmpuJc0U2.js} +1 -1
  47. package/dist/public/assets/_BmpuJc0U2.js.br +0 -0
  48. package/dist/public/assets/{_C2OfA6BZ.js → _BrNJO7NC.js} +1 -1
  49. package/dist/public/assets/_BrNJO7NC.js.br +0 -0
  50. package/dist/public/assets/{_BA7PhURg.js → _BsDGIBWi.js} +1 -1
  51. package/dist/public/assets/_BsDGIBWi.js.br +0 -0
  52. package/dist/public/assets/{_BBXJK7fW.js → _BszYFXns.js} +1 -1
  53. package/dist/public/assets/_BszYFXns.js.br +0 -0
  54. package/dist/public/assets/{_DbJRI9_H.js → _C-3_S2jT.js} +1 -1
  55. package/dist/public/assets/_C-3_S2jT.js.br +0 -0
  56. package/dist/public/assets/{_DucRMQLL2.js → _C2a60ukk2.js} +1 -1
  57. package/dist/public/assets/_C2a60ukk2.js.br +0 -0
  58. package/dist/public/assets/{_CasdikBZ2.js → _C5qWivO82.js} +1 -1
  59. package/dist/public/assets/_C5qWivO82.js.br +0 -0
  60. package/dist/public/assets/{_CL84pok8.js → _C7E2sftJ.js} +1 -1
  61. package/dist/public/assets/_C7E2sftJ.js.br +0 -0
  62. package/dist/public/assets/{_Tou5xDB12.js → _C9jJ-zAu2.js} +1 -1
  63. package/dist/public/assets/_C9jJ-zAu2.js.br +0 -0
  64. package/dist/public/assets/{_DbnzsP9f.js → _CBWyaxNg.js} +1 -1
  65. package/dist/public/assets/_CBWyaxNg.js.br +0 -0
  66. package/dist/public/assets/{_CjrYQPNO.js → _CCxiHsg1.js} +1 -1
  67. package/dist/public/assets/_CCxiHsg1.js.br +0 -0
  68. package/dist/public/assets/{_BnN7B1Mb.js → _CMXeuTU3.js} +1 -1
  69. package/dist/public/assets/_CMXeuTU3.js.br +0 -0
  70. package/dist/public/assets/{_DoaHBjpa.js → _COItZVVh.js} +1 -1
  71. package/dist/public/assets/_COItZVVh.js.br +0 -0
  72. package/dist/public/assets/{_DaTkOx5R.js → _CQjfWgLv.js} +1 -1
  73. package/dist/public/assets/_CQjfWgLv.js.br +0 -0
  74. package/dist/public/assets/{_2By3R--W2.js → _CUudFj1k2.js} +1 -1
  75. package/dist/public/assets/_CUudFj1k2.js.br +0 -0
  76. package/dist/public/assets/{__UTjMwX3.js → _CVRoyRZW.js} +1 -1
  77. package/dist/public/assets/_CVRoyRZW.js.br +0 -0
  78. package/dist/public/assets/{_CQRG1j1X.js → _CVpg0dqw.js} +1 -1
  79. package/dist/public/assets/_CVpg0dqw.js.br +0 -0
  80. package/dist/public/assets/{__OpDUxvR.js → _CWcbEhLf.js} +1 -1
  81. package/dist/public/assets/_CWcbEhLf.js.br +0 -0
  82. package/dist/public/assets/{_jDukN6_E2.js → _ChdHZg3q2.js} +1 -1
  83. package/dist/public/assets/_ChdHZg3q2.js.br +0 -0
  84. package/dist/public/assets/{_e1lYvQAo2.js → _Csumg8kE2.js} +1 -1
  85. package/dist/public/assets/_Csumg8kE2.js.br +0 -0
  86. package/dist/public/assets/{_BRP9V2vY.js → _Cu2zWIrA.js} +1 -1
  87. package/dist/public/assets/_Cu2zWIrA.js.br +0 -0
  88. package/dist/public/assets/{_C1uG69PI.js → _CvB8TafR.js} +1 -1
  89. package/dist/public/assets/_CvB8TafR.js.br +0 -0
  90. package/dist/public/assets/{_ZLwlH_XK.js → _CxfUzQkI.js} +1 -1
  91. package/dist/public/assets/_CxfUzQkI.js.br +0 -0
  92. package/dist/public/assets/{_DIezl6EI.js → _D5wyt0NZ.js} +1 -1
  93. package/dist/public/assets/_D5wyt0NZ.js.br +0 -0
  94. package/dist/public/assets/{_BqdeosKn.js → _DAES5BQ6.js} +1 -1
  95. package/dist/public/assets/_DAES5BQ6.js.br +0 -0
  96. package/dist/public/assets/{_jmw7zbFI2.js → _DAp7RKbE2.js} +1 -1
  97. package/dist/public/assets/_DAp7RKbE2.js.br +0 -0
  98. package/dist/public/assets/{_BNDbFEJj.js → _DJIoEU4l.js} +1 -1
  99. package/dist/public/assets/_DJIoEU4l.js.br +0 -0
  100. package/dist/public/assets/{_CQ3pD5r12.js → _DQZT5aYv2.js} +1 -1
  101. package/dist/public/assets/_DQZT5aYv2.js.br +0 -0
  102. package/dist/public/assets/{_Dkmb-8CU.js → _DSfzkPVh.js} +1 -1
  103. package/dist/public/assets/_DSfzkPVh.js.br +0 -0
  104. package/dist/public/assets/{_D861FlLr2.js → _DSl3gnKp2.js} +1 -1
  105. package/dist/public/assets/{_BBdsdafe2.js → _DUwDVnyb2.js} +1 -1
  106. package/dist/public/assets/_DUwDVnyb2.js.br +0 -0
  107. package/dist/public/assets/{_DCD2JMxh2.js → _DYgx29Kq2.js} +1 -1
  108. package/dist/public/assets/{_DS7FwF-J.js → _DbeeD9R1.js} +1 -1
  109. package/dist/public/assets/_DbeeD9R1.js.br +0 -0
  110. package/dist/public/assets/{_CqmPWoAp2.js → _DdvD3pSx2.js} +1 -1
  111. package/dist/public/assets/_DdvD3pSx2.js.br +0 -0
  112. package/dist/public/assets/{_D0PcbpPB.js → _DlEZP4B2.js} +1 -1
  113. package/dist/public/assets/_DlEZP4B2.js.br +0 -0
  114. package/dist/public/assets/{_C9UHqcOT2.js → _DmkxrcNE2.js} +1 -1
  115. package/dist/public/assets/_DmkxrcNE2.js.br +0 -0
  116. package/dist/public/assets/{_DY4GR3La.js → _Dp6GcCez.js} +1 -1
  117. package/dist/public/assets/_Dp6GcCez.js.br +0 -0
  118. package/dist/public/assets/{_E5DvansN.js → _Drob8ol2.js} +1 -1
  119. package/dist/public/assets/_Drob8ol2.js.br +0 -0
  120. package/dist/public/assets/{_4aAs0pvU.js → _Fd6qP3go.js} +1 -1
  121. package/dist/public/assets/_Fd6qP3go.js.br +0 -0
  122. package/dist/public/assets/{_U0PVI62V.js → _GX4ApnkB.js} +1 -1
  123. package/dist/public/assets/_GX4ApnkB.js.br +0 -0
  124. package/dist/public/assets/{_BAQFHOGb.js → _HmwD_O7C.js} +1 -1
  125. package/dist/public/assets/_HmwD_O7C.js.br +0 -0
  126. package/dist/public/assets/{_BdiO50aC2.js → _IiVyZhFQ2.js} +1 -1
  127. package/dist/public/assets/_IiVyZhFQ2.js.br +0 -0
  128. package/dist/public/assets/{_BaIOx6992.js → _M4_M1GCx2.js} +1 -1
  129. package/dist/public/assets/_M4_M1GCx2.js.br +0 -0
  130. package/dist/public/assets/{_D2sFNldb.js → _MbiYJ36s.js} +1 -1
  131. package/dist/public/assets/_MbiYJ36s.js.br +0 -0
  132. package/dist/public/assets/{_BBEMecyM2.js → _NSw61-q82.js} +1 -1
  133. package/dist/public/assets/_NSw61-q82.js.br +0 -0
  134. package/dist/public/assets/{_BRV26aAF.js → _QBVNsQ8h.js} +1 -1
  135. package/dist/public/assets/_QBVNsQ8h.js.br +0 -0
  136. package/dist/public/assets/{_Dyejz2MQ.js → _RcdEaPTX.js} +1 -1
  137. package/dist/public/assets/_RcdEaPTX.js.br +0 -0
  138. package/dist/public/assets/{_BPzHoTu3.js → _Ty6Zi_p6.js} +1 -1
  139. package/dist/public/assets/_Ty6Zi_p6.js.br +0 -0
  140. package/dist/public/assets/{_BculF-XV.js → _WSiIjl8k.js} +1 -1
  141. package/dist/public/assets/{_DbbVTGR82.js → _c4j42n9F2.js} +1 -1
  142. package/dist/public/assets/_c4j42n9F2.js.br +0 -0
  143. package/dist/public/assets/{_CAP_5S-t.js → _cRSAYsIy.js} +1 -1
  144. package/dist/public/assets/_cRSAYsIy.js.br +0 -0
  145. package/dist/public/assets/{_BkeFq1dG2.js → _gqKnRhHm2.js} +1 -1
  146. package/dist/public/assets/_gqKnRhHm2.js.br +0 -0
  147. package/dist/public/assets/{_Bt3B1aEu2.js → _i3m2va9y2.js} +1 -1
  148. package/dist/public/assets/_i3m2va9y2.js.br +0 -0
  149. package/dist/public/assets/{_CMmwGR_Q.js → _rShrll8V.js} +1 -1
  150. package/dist/public/assets/_rShrll8V.js.br +0 -0
  151. package/dist/public/assets/{_BYRkkQxk.js → _wsALS6ya.js} +1 -1
  152. package/dist/public/assets/_wsALS6ya.js.br +0 -0
  153. package/dist/public/assets/{_B7T2AE8L.js → _wx4NAfvC.js} +1 -1
  154. package/dist/public/assets/_wx4NAfvC.js.br +0 -0
  155. package/dist/public/assets/{diff-view-sXFdzozK.css → diff-view-l7q43Ong.css} +1 -1
  156. package/dist/public/assets/diff-view-l7q43Ong.css.br +0 -0
  157. package/dist/public/assets/{index-DKRkgwLo.js → index-BXWsr0DP.js} +4 -4
  158. package/dist/public/assets/index-BXWsr0DP.js.br +0 -0
  159. package/dist/public/assets/index-Du7Hgz2d.css +1 -0
  160. package/dist/public/assets/index-Du7Hgz2d.css.br +0 -0
  161. package/dist/public/assets/{preload-helper-Cioq5Qre.css → preload-helper-Di0vWBYv.css} +1 -1
  162. package/dist/public/assets/preload-helper-Di0vWBYv.css.br +0 -0
  163. package/package.json +1 -1
  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.br +0 -0
  240. package/dist/public/assets/index-DKRkgwLo.js.br +0 -0
  241. package/dist/public/assets/index-c70b3ZMB.css +0 -1
  242. package/dist/public/assets/index-c70b3ZMB.css.br +0 -0
  243. package/dist/public/assets/preload-helper-Cioq5Qre.css.br +0 -0
@@ -2209,8 +2209,8 @@ var icon_sidebar_default = _template("R", (input) => {
2209
2209
  });
2210
2210
  _serialize_if($scope0_reason, 0) && writeScope($scope0_id, { a: _existing_scope($childScope) });
2211
2211
  });
2212
- var findInput = "_fl _e";
2213
- var findIconBtn = "_fo _y";
2212
+ var findInput = "_e8 _e";
2213
+ var findIconBtn = "_fa _y";
2214
2214
  //#endregion
2215
2215
  //#region src/tags/icons/icon-search.marko
2216
2216
  var icon_search_default = _template("P", (input) => {
@@ -1,4 +1,4 @@
1
- import { $ as _subscribe, A as _el_resume, B as _peek_scope_id, C as _attr_style, E as _content_resume, G as _scope_with_id, H as _resume_branch, J as _serialize_guard, K as _script, L as _html, M as _existing_scope, O as _el, P as _for_of, Q as _show_start, S as _attr_select_value, 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, a as diffTreeOpen, at as attrTag, b as _attr_input_value, d as icon_base_default, et as _template, f as fuzzy, i as icon_sidebar_default, j as _escape, k as _el_read_error, m as toast_default, n as findIconBtn, o as diffUncommitted, q as _sep, r as findInput, st as writeScope, t as icon_search_default, u as icon_refresh_default, v as _attr_class, x as _attr_option_value, y as _attr_details_or_dialog_open, z as _if } from "./_B6irorCp.js";
1
+ import { $ as _subscribe, A as _el_resume, B as _peek_scope_id, C as _attr_style, E as _content_resume, G as _scope_with_id, H as _resume_branch, J as _serialize_guard, K as _script, L as _html, M as _existing_scope, O as _el, P as _for_of, Q as _show_start, S as _attr_select_value, 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, a as diffTreeOpen, at as attrTag, b as _attr_input_value, d as icon_base_default, et as _template, f as fuzzy, i as icon_sidebar_default, j as _escape, k as _el_read_error, m as toast_default, n as findIconBtn, o as diffUncommitted, q as _sep, r as findInput, st as writeScope, t as icon_search_default, u as icon_refresh_default, v as _attr_class, x as _attr_option_value, y as _attr_details_or_dialog_open, z as _if } from "./_BlvusYIA.js";
2
2
  //#region src/client/clipboard.ts
3
3
  /** Copy text to the clipboard. `navigator.clipboard` needs a secure
4
4
  * context — absent over plain-http LAN origins — so fall back to a hidden
@@ -283,7 +283,7 @@ var icon_back_default = _template("A", (input) => {
283
283
  });
284
284
  _serialize_if($scope0_reason, 0) && writeScope($scope0_id, { a: _existing_scope($childScope) });
285
285
  });
286
- var fileFilter = "_eZ _e";
286
+ var fileFilter = "_eU _e";
287
287
  //#endregion
288
288
  //#region src/tags/file-filter.marko
289
289
  var file_filter_default = _template("j", (input) => {
@@ -313,7 +313,7 @@ var file_filter_default = _template("j", (input) => {
313
313
  pending = v;
314
314
  box.timer = setTimeout(flush, 150);
315
315
  }, "j2", $scope0_id);
316
- _html(`<div${_attr_class("_eY")}><input${_attr_input_value($scope0_id, "b", draft, _resume(function(v) {
316
+ _html(`<div${_attr_class("_eT")}><input${_attr_input_value($scope0_id, "b", draft, _resume(function(v) {
317
317
  type(v);
318
318
  }, "j0", $scope0_id))}${_attr_class(fileFilter)} type=search placeholder="Filter files…" aria-label="Filter files">${_el_resume($scope0_id, "b")}</div>`);
319
319
  _script($scope0_id, "j3");
@@ -339,7 +339,7 @@ var diff_send_default = _template("g", (input) => {
339
339
  let sendTarget = null;
340
340
  const sessions = input.sessions || [];
341
341
  const sendPick = sessions.some((s) => s.id === sendTarget) ? sendTarget : sessions[0]?.id ?? null;
342
- _html(`<span${_attr_class("_eT")}><button type=button${_attr_class("_f")} title="Copy comments as markdown">Copy${_el_resume($scope0_id, "c")}</button>${_el_resume($scope0_id, "b")}`);
342
+ _html(`<span${_attr_class("_fi")}><button type=button${_attr_class("_f")} title="Copy comments as markdown">Copy${_el_resume($scope0_id, "c")}</button>${_el_resume($scope0_id, "b")}`);
343
343
  _if(() => {
344
344
  if (sessions.length === 1) {
345
345
  const $scope1_id = _scope_id();
@@ -349,11 +349,11 @@ var diff_send_default = _template("g", (input) => {
349
349
  return 0;
350
350
  } else if (sessions.length) {
351
351
  const $scope2_id = _scope_id();
352
- _html(`<span${_attr_class("_eU")}><button type=button${_attr_class("_eV")}${_attr("disabled", sending)}>Send to${_el_resume($scope2_id, "c")}</button>${_el_resume($scope2_id, "b")}`);
352
+ _html(`<span${_attr_class("_fj")}><button type=button${_attr_class("_fk")}${_attr("disabled", sending)}>Send to${_el_resume($scope2_id, "c")}</button>${_el_resume($scope2_id, "b")}`);
353
353
  _attr_select_value($scope2_id, "d", sendTarget, _resume((_new_sendTarget) => {
354
354
  sendTarget = _new_sendTarget;
355
355
  }, "g0", $scope2_id), () => {
356
- _html(`<select${_attr_class("_eW")} aria-label="Send comments to session"${_attr("disabled", sending)}>`);
356
+ _html(`<select${_attr_class("_fl")} aria-label="Send comments to session"${_attr("disabled", sending)}>`);
357
357
  _for_of(sessions, (s) => {
358
358
  const $scope3_id = _scope_id();
359
359
  _html(`<option${_attr_option_value(s.id)}>${_escape(s.title || s.agent)}${_el_resume($scope3_id, "b", $sg__input_sessions)}</option>${_el_resume($scope3_id, "a", $sg__input_sessions)}`);
@@ -1889,9 +1889,9 @@ var diff_find_default = _template("f", (input) => {
1889
1889
  el.select();
1890
1890
  }, 0);
1891
1891
  }, "f5", $scope0_id);
1892
- _html(`<div${_attr_class(["_fk", !open && "_fj"])} aria-hidden=${open ? "false" : "true"}><input${_attr_input_value($scope0_id, "b", query || "", _resume(function(v) {
1892
+ _html(`<div${_attr_class(["_e7", !open && "_e6"])} aria-hidden=${open ? "false" : "true"}><input${_attr_input_value($scope0_id, "b", query || "", _resume(function(v) {
1893
1893
  type(v);
1894
- }, "f0", $scope0_id))}${_attr_class(findInput)} type=search enterkeyhint=search autocomplete=off tabindex=${open ? "0" : "-1"} placeholder="Find in diffs" aria-label="Find in diffs">${_el_resume($scope0_id, "b")}<span${_attr_class("_fn")}>${open && (query || "").trim() ? hits.length ? `${_escape(`${at + 1}`)}/${_escape(`${hits.length}`)}` : "0/0" : ""}${_el_resume($scope0_id, "d")}</span><button type=button${_attr_class(findIconBtn)} title="Previous match"${_attr("disabled", !hits.length || !open)} tabindex=${open ? "0" : "-1"}>↑</button>${_el_resume($scope0_id, "e")}<button type=button${_attr_class(findIconBtn)} title="Next match"${_attr("disabled", !hits.length || !open)} tabindex=${open ? "0" : "-1"}>↓</button>${_el_resume($scope0_id, "f")}<button type=button${_attr_class(findIconBtn)} title="Close find" tabindex=${open ? "0" : "-1"}>×</button>${_el_resume($scope0_id, "g")}</div>${_el_resume($scope0_id, "a")}`);
1894
+ }, "f0", $scope0_id))}${_attr_class(findInput)} type=search enterkeyhint=search autocomplete=off tabindex=${open ? "0" : "-1"} placeholder="Find in diffs" aria-label="Find in diffs">${_el_resume($scope0_id, "b")}<span${_attr_class("_e_")}>${open && (query || "").trim() ? hits.length ? `${_escape(`${at + 1}`)}/${_escape(`${hits.length}`)}` : "0/0" : ""}${_el_resume($scope0_id, "d")}</span><button type=button${_attr_class(findIconBtn)} title="Previous match"${_attr("disabled", !hits.length || !open)} tabindex=${open ? "0" : "-1"}>↑</button>${_el_resume($scope0_id, "e")}<button type=button${_attr_class(findIconBtn)} title="Next match"${_attr("disabled", !hits.length || !open)} tabindex=${open ? "0" : "-1"}>↓</button>${_el_resume($scope0_id, "f")}<button type=button${_attr_class(findIconBtn)} title="Close find" tabindex=${open ? "0" : "-1"}>×</button>${_el_resume($scope0_id, "g")}</div>${_el_resume($scope0_id, "a")}`);
1895
1895
  _script($scope0_id, "f6");
1896
1896
  _script($scope0_id, "f7");
1897
1897
  _script($scope0_id, "f8");
@@ -1930,7 +1930,7 @@ var diff_file_default = _template("e", (input) => {
1930
1930
  _scope_reason();
1931
1931
  const $scope0_id = _scope_id();
1932
1932
  _el($scope0_id, "e0");
1933
- _html(`<div${_attr_class(["_eX", input.class])}></div>${_el_resume($scope0_id, "a")}`);
1933
+ _html(`<div${_attr_class(["_eV", input.class])}></div>${_el_resume($scope0_id, "a")}`);
1934
1934
  _script($scope0_id, "e1");
1935
1935
  writeScope($scope0_id, {
1936
1936
  e: input.file,
@@ -1959,10 +1959,10 @@ var diff_tree_default = _template("h", (input) => {
1959
1959
  let openedRepos = input.openedRepos;
1960
1960
  let collapsedDirs = /* @__PURE__ */ new Set();
1961
1961
  const commentKeys = input.commentKeys || /* @__PURE__ */ new Set();
1962
- _html(`<aside${_attr_class(["_fa", { ["_e_"]: input.open === false }])}>`);
1962
+ _html(`<aside${_attr_class(["_fn", { ["_fm"]: input.open === false }])}>`);
1963
1963
  _for_of(input.sections, (section) => {
1964
1964
  const $scope1_id = _scope_id();
1965
- _html(`<div${_attr_class("_fb")}><button type=button${_attr_class(["_fc", { ["_e_"]: collapsedRepos.has(section.id) }])}><span${_attr_class("_fh")}>${collapsedRepos.has(section.id) ? "▸" : "▾"}${_el_resume($scope1_id, "d")}</span>${_sep($sg__input_sections)}${_escape(section.label)}${_el_resume($scope1_id, "e", $sg__input_sections)}</button>${_el_resume($scope1_id, "b")}`);
1965
+ _html(`<div${_attr_class("_fo")}><button type=button${_attr_class(["_fp", { ["_fm"]: collapsedRepos.has(section.id) }])}><span${_attr_class("_fu")}>${collapsedRepos.has(section.id) ? "▸" : "▾"}${_el_resume($scope1_id, "d")}</span>${_sep($sg__input_sections)}${_escape(section.label)}${_el_resume($scope1_id, "e", $sg__input_sections)}</button>${_el_resume($scope1_id, "b")}`);
1966
1966
  _if(() => {
1967
1967
  if (!collapsedRepos.has(section.id) || openedRepos.has(section.id)) {
1968
1968
  const $scope2_id = _scope_id();
@@ -1989,17 +1989,17 @@ var diff_tree_default = _template("h", (input) => {
1989
1989
  _if(() => {
1990
1990
  if (!hiddenByCollapse(row) && row.kind === "dir") {
1991
1991
  const $scope5_id = _scope_id();
1992
- _html(`<button type=button${_attr_class(["_fd", { ["_e_"]: collapsedDirs.has(dirKey(row.path)) }])}${_attr("title", row.path)}${_attr_style(`padding-left:${.35 + row.depth * .75}rem`)}><span${_attr_class("_fh")}>${collapsedDirs.has(dirKey(row.path)) ? "▸" : "▾"}${_el_resume($scope5_id, "c")}</span>${_escape(row.label)}${_el_resume($scope5_id, "d", $sg__input_sections)}/</button>${_el_resume($scope5_id, "a")}`);
1992
+ _html(`<button type=button${_attr_class(["_fq", { ["_fm"]: collapsedDirs.has(dirKey(row.path)) }])}${_attr("title", row.path)}${_attr_style(`padding-left:${.35 + row.depth * .75}rem`)}><span${_attr_class("_fu")}>${collapsedDirs.has(dirKey(row.path)) ? "▸" : "▾"}${_el_resume($scope5_id, "c")}</span>${_escape(row.label)}${_el_resume($scope5_id, "d", $sg__input_sections)}/</button>${_el_resume($scope5_id, "a")}`);
1993
1993
  _script($scope5_id, "h3");
1994
1994
  _subscribe($si__input_sections && $if_content__dirKey__closures, _subscribe($collapsedDirs__closures, writeScope($scope5_id, { Cv: 1 })));
1995
1995
  return 0;
1996
1996
  } else if (!hiddenByCollapse(row) && row.kind !== "dir") {
1997
1997
  const $scope4_id = _scope_id();
1998
- _html(`<button type=button${_attr_class("_fe")}${_attr("title", row.file.path)}${_attr_style(`padding-left:${.5 + row.depth * .75}rem`)}><span${_attr_class("_fi")}${_attr("data-status", row.file.status)}>${_escape(row.file.status)}${_el_resume($scope4_id, "c", $sg__input_sections)}</span>${_el_resume($scope4_id, "b", $sg__input_sections)}<span${_attr_class("_ff")}>${_escape(row.name)}${_el_resume($scope4_id, "e", $sg__input_sections)}</span>`);
1998
+ _html(`<button type=button${_attr_class("_fr")}${_attr("title", row.file.path)}${_attr_style(`padding-left:${.5 + row.depth * .75}rem`)}><span${_attr_class("_fv")}${_attr("data-status", row.file.status)}>${_escape(row.file.status)}${_el_resume($scope4_id, "c", $sg__input_sections)}</span>${_el_resume($scope4_id, "b", $sg__input_sections)}<span${_attr_class("_fs")}>${_escape(row.name)}${_el_resume($scope4_id, "e", $sg__input_sections)}</span>`);
1999
1999
  _if(() => {
2000
2000
  if (commentKeys.has(row.file.key)) {
2001
2001
  const $scope6_id = _scope_id();
2002
- _html(`<span${_attr_class("_fg")}>💬</span>`);
2002
+ _html(`<span${_attr_class("_ft")}>💬</span>`);
2003
2003
  _serialize_if($scope0_reason, 0) && writeScope($scope6_id, {});
2004
2004
  return 0;
2005
2005
  }
@@ -2060,7 +2060,7 @@ var diff_tree_default = _template("h", (input) => {
2060
2060
  });
2061
2061
  //#endregion
2062
2062
  //#region src/tags/diff-file-sheet.css.ts
2063
- var iconBtn = "_e0 _y";
2063
+ var iconBtn = "_eW _y";
2064
2064
  //#endregion
2065
2065
  //#region src/tags/diff-file-sheet.marko
2066
2066
  var diff_file_sheet_default = _template("d", (input) => {
@@ -2073,10 +2073,10 @@ var diff_file_sheet_default = _template("d", (input) => {
2073
2073
  _if(() => {
2074
2074
  if (open) {
2075
2075
  const $scope1_id = _scope_id();
2076
- _html(`<div${_attr_class("_e2")}></div>${_el_resume($scope1_id, "a")}<div${_attr_class("_e3")} role=dialog aria-label="Jump to file"><div${_attr_class("_e4")}><strong${_attr_class("_e1")}>Files</strong><span${_attr_class("_e5")}>${_escape(input.files.length)}${_el_resume($scope1_id, "f", _serialize_guard($scope0_reason, 6))}${_sep($sg__input_total__OR__input_files_length)}${input.files.length !== total ? ` / ${_escape(`${total}`)}` : ""}${_el_resume($scope1_id, "g", $sg__input_total__OR__input_files_length)}</span><button type=button${_attr_class(iconBtn)} title=Close aria-label=Close>×</button>${_el_resume($scope1_id, "h")}</div><div${_attr_class("_e6")}>`);
2076
+ _html(`<div${_attr_class("_eY")}></div>${_el_resume($scope1_id, "a")}<div${_attr_class("_eZ")} role=dialog aria-label="Jump to file"><div${_attr_class("_e0")}><strong${_attr_class("_eX")}>Files</strong><span${_attr_class("_e1")}>${_escape(input.files.length)}${_el_resume($scope1_id, "f", _serialize_guard($scope0_reason, 6))}${_sep($sg__input_total__OR__input_files_length)}${input.files.length !== total ? ` / ${_escape(`${total}`)}` : ""}${_el_resume($scope1_id, "g", $sg__input_total__OR__input_files_length)}</span><button type=button${_attr_class(iconBtn)} title=Close aria-label=Close>×</button>${_el_resume($scope1_id, "h")}</div><div${_attr_class("_e2")}>`);
2077
2077
  _for_of(input.files, (file) => {
2078
2078
  const $scope2_id = _scope_id();
2079
- _html(`<button type=button${_attr_class(["_e7", "_o"])}><span${_attr_class("_e9")}${_attr("data-status", file.status)}>${_escape(file.status)}${_el_resume($scope2_id, "c", $sg__input_files)}</span>${_el_resume($scope2_id, "b", $sg__input_files)}<span${_attr_class("_e8")}${_attr("title", file.key)}><bdi>${_escape(file.key)}${_el_resume($scope2_id, "e", $sg__input_files)}</bdi></span>${_el_resume($scope2_id, "d", $sg__input_files)}`);
2079
+ _html(`<button type=button${_attr_class(["_e3", "_o"])}><span${_attr_class("_e5")}${_attr("data-status", file.status)}>${_escape(file.status)}${_el_resume($scope2_id, "c", $sg__input_files)}</span>${_el_resume($scope2_id, "b", $sg__input_files)}<span${_attr_class("_e4")}${_attr("title", file.key)}><bdi>${_escape(file.key)}${_el_resume($scope2_id, "e", $sg__input_files)}</bdi></span>${_el_resume($scope2_id, "d", $sg__input_files)}`);
2080
2080
  _if(() => {
2081
2081
  if (commentKeys.has(file.key)) {
2082
2082
  const $scope3_id = _scope_id();
@@ -124,10 +124,19 @@ function publish(type, data) {
124
124
  console.error("[work] event listener error", err);
125
125
  }
126
126
  }
127
+ var joins = 0;
127
128
  function subscribe(listener) {
128
129
  listeners.add(listener);
130
+ joins++;
129
131
  return () => listeners.delete(listener);
130
132
  }
133
+ /** Count of subscriptions ever made. A watcher that publishes only what
134
+ * changed has to send everything to a listener that was not there for the
135
+ * earlier ones — including a reconnect, which arrives here as a new
136
+ * subscription and would otherwise sit on whatever it missed. */
137
+ function subscriberJoins() {
138
+ return joins;
139
+ }
131
140
  /** Connected SSE clients — lets background watchers idle when no one
132
141
  * is listening. */
133
142
  function subscriberCount() {
@@ -135,7 +144,8 @@ function subscriberCount() {
135
144
  }
136
145
  //#endregion
137
146
  //#region src/server/exec.ts
138
- /** Dedicated tmux server so we never touch herdr's or the user's default tmux. */
147
+ /** Dedicated tmux server so we never touch another multiplexer's or the
148
+ * user's default tmux. */
139
149
  var TMUX_SOCKET = "work";
140
150
  var execFileAsync = promisify(execFile);
141
151
  async function run(cmd, args, cwd, env) {
@@ -5903,6 +5913,18 @@ var NOTIFICATION_LABELS = {
5903
5913
  elicitation_dialog: "Asking a question",
5904
5914
  elicitation_url_dialog: "Needs a browser sign-in"
5905
5915
  };
5916
+ /** Notifications that mean the agent is nudging about an idle session
5917
+ * rather than blocking on one. The hook cannot tell them apart when it
5918
+ * fires — it reports every notification the same way — so the kind has to
5919
+ * come out of the payload, or a session that merely sat there reads as
5920
+ * stuck and paints the nav red. */
5921
+ var NUDGE_NOTIFICATIONS = /* @__PURE__ */ new Set(["idle_prompt"]);
5922
+ /** The reason a hook's `waiting` actually carries, given its payload. */
5923
+ function reasonFromHookPayload(payload, reported) {
5924
+ if (reported !== "attention" || !payload || typeof payload !== "object") return reported;
5925
+ const kind = payload.notification_type;
5926
+ return typeof kind === "string" && NUDGE_NOTIFICATIONS.has(kind) ? "done" : reported;
5927
+ }
5906
5928
  /** First meaningful line(s) of an agent message, markdown chrome stripped,
5907
5929
  * sized for a push notification. */
5908
5930
  function cleanSummary(text) {
@@ -5911,11 +5933,23 @@ function cleanSummary(text) {
5911
5933
  return flat.length > 180 ? `${flat.slice(0, 177)}…` : flat;
5912
5934
  }
5913
5935
  function setAgentPhase(sessionId, phase, reason, summary) {
5914
- if (phase === "waiting" && reason) reasons.set(sessionId, reason);
5936
+ if (phase === "waiting" && reason === "done") {
5937
+ if (summary) summaries.set(sessionId, summary);
5938
+ if (Date.now() - bootedAt > BOOT_GRACE_MS) notify(sessionId, "done");
5939
+ if (phases.has(sessionId)) applyChange(sessionId, () => {
5940
+ phases.delete(sessionId);
5941
+ reasons.delete(sessionId);
5942
+ });
5943
+ return;
5944
+ }
5915
5945
  if (phase === "waiting" && summary) summaries.set(sessionId, summary);
5916
5946
  else if (phase === "working") summaries.delete(sessionId);
5917
- if (phases.get(sessionId) === phase) return;
5918
- applyChange(sessionId, () => phases.set(sessionId, phase));
5947
+ const next = phase === "waiting" && reason ? reason : reasons.get(sessionId);
5948
+ if (phases.get(sessionId) === phase && reasons.get(sessionId) === next) return;
5949
+ applyChange(sessionId, () => {
5950
+ phases.set(sessionId, phase);
5951
+ if (phase === "waiting" && reason) reasons.set(sessionId, reason);
5952
+ });
5919
5953
  }
5920
5954
  /** Live visible-terminal count per session, reported by the term server;
5921
5955
  * a session someone is watching does not push notifications. */
@@ -5923,35 +5957,20 @@ function setSessionViewers(sessionId, count) {
5923
5957
  if (count > 0) viewers.set(sessionId, count);
5924
5958
  else viewers.delete(sessionId);
5925
5959
  }
5926
- /** Terminal-scraped phase (see scraper.ts). Hooks win when both exist,
5927
- * except a scraped "waiting" outranks a hook "working" — a permission
5928
- * prompt on screen is ground truth the hook may never report. */
5929
- function setScrapedPhase(sessionId, phase, blockerText) {
5930
- if (phase === "waiting") {
5931
- reasons.set(sessionId, "attention");
5932
- if (blockerText) scrapedSummaries.set(sessionId, blockerText);
5933
- } else scrapedSummaries.delete(sessionId);
5934
- const stalePin = phase === "working" && phases.get(sessionId) === "waiting" && (reasons.get(sessionId) === "done" || scraped.get(sessionId) === "waiting");
5935
- if (scraped.get(sessionId) === phase && !stalePin) return;
5960
+ function setScrapedPhase(sessionId, phase) {
5961
+ if (scraped.get(sessionId) === phase) return;
5936
5962
  applyChange(sessionId, () => {
5937
- if (stalePin) {
5938
- phases.delete(sessionId);
5939
- summaries.delete(sessionId);
5940
- reasons.delete(sessionId);
5941
- }
5942
5963
  if (phase) scraped.set(sessionId, phase);
5943
5964
  else scraped.delete(sessionId);
5944
5965
  });
5945
5966
  }
5946
- var scrapedSummaries = /* @__PURE__ */ new Map();
5947
- async function notifyWaiting(sessionId) {
5967
+ async function notify(sessionId, reason) {
5948
5968
  const row = get(`SELECT s.agent, s.title, s.workspace_id, w.name FROM sessions s
5949
5969
  JOIN workspaces w ON w.id = s.workspace_id WHERE s.id = ?`, sessionId);
5950
5970
  if (!row) return;
5951
5971
  if ((viewers.get(sessionId) ?? 0) > 0) return;
5952
5972
  const waiting = [.../* @__PURE__ */ new Set([...phases.keys(), ...scraped.keys()])].filter((id) => agentPhase(id) === "waiting").length;
5953
- const reason = reasons.get(sessionId) ?? "attention";
5954
- const summary = summaries.get(sessionId) || scrapedSummaries.get(sessionId) || await paneExcerpt(sessionId) || await paneTitle(sessionId, row.agent);
5973
+ const summary = summaries.get(sessionId);
5955
5974
  const label = reason === "done" ? "✔ Finished" : "⚠ Needs attention";
5956
5975
  sendPush({
5957
5976
  title: `${row.name} · ${row.title || row.agent}`,
@@ -5964,33 +5983,6 @@ async function notifyWaiting(sessionId) {
5964
5983
  }
5965
5984
  }).catch(() => {});
5966
5985
  }
5967
- /** The agent's own OSC title, spinner and agent-name chrome stripped —
5968
- * usually a one-line summary of what it worked on (herdr's trick). */
5969
- async function paneTitle(sessionId, agent) {
5970
- const cleaned = (await tmux([
5971
- "display-message",
5972
- "-p",
5973
- "-t",
5974
- `wk-${sessionId}`,
5975
- "#{pane_title}"
5976
- ]).catch(() => "")).trim().replace(/^[⠀-⣿✳✻·*✽◐◑◒◓]+\s*/u, "").replace(/\s*[-·–]\s*(grok|claude|codex|copilot|cursor(-agent)?)$/i, "").replace(/^[-·–]\s*/, "").trim();
5977
- if (!cleaned || cleaned.toLowerCase() === agent.toLowerCase()) return "";
5978
- if (/^(bash|zsh|sh|fish|tmux)\b/i.test(cleaned)) return "";
5979
- return cleaned.slice(0, 140);
5980
- }
5981
- /** Last meaningful line(s) of the session's screen — what the agent just
5982
- * said/asked — with prompt-box chrome and hint bars filtered out. */
5983
- async function paneExcerpt(sessionId) {
5984
- return (await tmux([
5985
- "capture-pane",
5986
- "-p",
5987
- "-J",
5988
- "-t",
5989
- `wk-${sessionId}`,
5990
- "-S",
5991
- "-25"
5992
- ]).catch(() => "")).split("\n").map((line) => line.trim()).filter((line) => line && !/^[╭╰│─━┃❯>✳·. ]+$/.test(line) && !/^[╭╰][─ ]/.test(line) && !/(ctrl\+|esc to|shift\+tab|\? for help|tab next|bypass permissions)/i.test(line) && !/^[⎿└├]?\s*tip:/i.test(line) && !/^[✳✻✽◐◑◒◓⠀-⣿]\s/.test(line) && !/^[A-Z0-9_-]{2,14}$/.test(line)).map((line) => line.replace(/^[│┃⎿└├]\s*/, "").replace(/\s*[│┃]$/, "").trim()).filter(Boolean).slice(-2).join(" — ").slice(0, 180);
5993
- }
5994
5986
  function clearAgentPhase(sessionId) {
5995
5987
  if (!phases.has(sessionId) && !scraped.has(sessionId)) return;
5996
5988
  applyChange(sessionId, () => {
@@ -5998,14 +5990,12 @@ function clearAgentPhase(sessionId) {
5998
5990
  scraped.delete(sessionId);
5999
5991
  reasons.delete(sessionId);
6000
5992
  summaries.delete(sessionId);
6001
- scrapedSummaries.delete(sessionId);
6002
5993
  });
6003
5994
  }
5995
+ /** What a session is doing. The hook wins where there is one: it reports
5996
+ * the turn itself, where tmux only sees the pane still moving after it. */
6004
5997
  function agentPhase(sessionId) {
6005
- const hook = phases.get(sessionId);
6006
- const seen = scraped.get(sessionId);
6007
- if (seen === "waiting" && hook === "working") return "waiting";
6008
- return hook ?? seen;
5998
+ return phases.get(sessionId) ?? scraped.get(sessionId);
6009
5999
  }
6010
6000
  /** Freshly booted servers re-discover already-waiting sessions on the
6011
6001
  * first scan — that must not re-buzz every device after a deploy. */
@@ -6017,13 +6007,13 @@ function applyChange(sessionId, mutate) {
6017
6007
  const after = agentPhase(sessionId);
6018
6008
  if (before === after) return;
6019
6009
  publishChange(sessionId);
6020
- if (after === "waiting" && before !== "waiting" && Date.now() - bootedAt > BOOT_GRACE_MS) notifyWaiting(sessionId);
6010
+ if (after === "waiting" && before !== "waiting" && Date.now() - bootedAt > BOOT_GRACE_MS) notify(sessionId, reasons.get(sessionId) ?? "attention");
6021
6011
  }
6022
6012
  function publishChange(sessionId) {
6023
6013
  const row = get("SELECT workspace_id FROM sessions WHERE id = ?", sessionId);
6024
6014
  if (row?.workspace_id) {
6025
6015
  const workspaceId = row.workspace_id;
6026
- import("./_L15vvgS1.js").then((m) => m.notifySessionsChanged(workspaceId));
6016
+ import("./_kABYZA6_.js").then((m) => m.notifySessionsChanged(workspaceId));
6027
6017
  return;
6028
6018
  }
6029
6019
  publish("sessions.changed");
@@ -6035,11 +6025,20 @@ function publishChange(sessionId) {
6035
6025
  * JSON (--settings accepts a JSON string); Codex takes its notify command
6036
6026
  * via `-c` (its turn-complete payload carries last-assistant-message).
6037
6027
  * Grok, Cursor and Copilot expose no file-free hook mechanism, so their
6038
- * state comes from terminal scraping (see scrape/). */
6028
+ * sessions get working/idle from pane activity (see scraper.ts) and
6029
+ * nothing else — a stopped turn and a question look the same. */
6039
6030
  function stateCurl(state, reason) {
6040
6031
  const qs = `session=$WORK_SESSION_ID&state=${state}` + (reason ? `&reason=${reason}` : "");
6041
6032
  return `[ -n "$WORK_SESSION_ID" ] && curl -sf -m 3 -X POST "http://127.0.0.1:\${WORK_APP_PORT:-${config.appPort}}/api/agent-state?${qs}" -H 'content-type: application/json' --data-binary @- >/dev/null 2>&1; exit 0`;
6042
6033
  }
6034
+ /** Whether the agent says when it *starts* working, not just when it stops.
6035
+ * Codex's notify only fires on turn-complete, so the screen is the only
6036
+ * thing that can tell us it picked up again; Claude announces it, and
6037
+ * believing the screen over that costs it the state its own hook just
6038
+ * reported. */
6039
+ function reportsWorking(agent) {
6040
+ return agent === "claude";
6041
+ }
6043
6042
  /** Extra argv for an agent CLI so it reports working/waiting state. */
6044
6043
  function agentLaunchFlags(agent) {
6045
6044
  if (agent === "claude") {
@@ -6390,4 +6389,4 @@ function sleep(ms) {
6390
6389
  return new Promise((resolve) => setTimeout(resolve, ms));
6391
6390
  }
6392
6391
  //#endregion
6393
- export { git as A, config as B, AGENTS as C, setSetting as D, setPref as E, subscriberCount as F, all as I, db as L, tmux as M, publish as N, TMUX_SOCKET as O, subscribe as P, get as R, saveSubscription as S, preferredAgent as T, setScrapedPhase as _, killSession as a, deleteSubscription as b, newSessionArgs as c, renameSession as d, sendToSession as f, setAgentPhase as g, clearAgentPhase as h, getSession as i, run as j, gh as k, notifySessionsChanged as l, tmuxName as m, createSession as n, killWorkspaceSessions as o, sessionStates as p, ensureTmuxServer as r, listSessions as s, cleanEnv as t, panePids as u, setSessionViewers as v, allPrefs as w, pushPublicKey as x, summaryFromHookPayload as y, workspacePath as z };
6392
+ export { TMUX_SOCKET as A, db as B, pushPublicKey as C, preferredAgent as D, allPrefs as E, publish as F, workspacePath as H, subscribe as I, subscriberCount as L, git as M, run as N, setPref as O, tmux as P, subscriberJoins as R, deleteSubscription as S, AGENTS as T, config as U, get as V, reasonFromHookPayload as _, killSession as a, setSessionViewers as b, newSessionArgs as c, renameSession as d, sendToSession as f, clearAgentPhase as g, reportsWorking as h, getSession as i, gh as j, setSetting as k, notifySessionsChanged as l, tmuxName as m, createSession as n, killWorkspaceSessions as o, sessionStates as p, ensureTmuxServer as r, listSessions as s, cleanEnv as t, panePids as u, setAgentPhase as v, saveSubscription as w, summaryFromHookPayload as x, setScrapedPhase as y, all as z };
@@ -0,0 +1,2 @@
1
+ import { l as notifySessionsChanged } from "./_P9IsUQm2.js";
2
+ export { notifySessionsChanged };