@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
@@ -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 };