@dylanpiercey/work 0.0.222 → 0.1.0

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 (547) hide show
  1. package/README.md +9 -31
  2. package/bin/work.mjs +121 -122
  3. package/dist/{_DNhDGBkH.js → _Bq7to522.js} +544 -254
  4. package/dist/_CkwTsHKB.js +2 -0
  5. package/dist/index.mjs +2813 -3240
  6. package/dist/public/assets/_1RHVsAcK.js +1 -0
  7. package/dist/public/assets/_4CShjaLP.js +1 -0
  8. package/dist/public/assets/_68JtNDO1.js +1 -0
  9. package/dist/public/assets/{_CtQ-4c6a.js → _8G2Mv7jG.js} +1 -1
  10. package/dist/public/assets/_8G2Mv7jG.js.br +0 -0
  11. package/dist/public/assets/{_DYBhy6q4.js → _8dvK2NDJ.js} +1 -1
  12. package/dist/public/assets/_8dvK2NDJ.js.br +0 -0
  13. package/dist/public/assets/_94L2SIJF.js +1 -0
  14. package/dist/public/assets/_9AnDb3YH.js +1 -0
  15. package/dist/public/assets/{_BJk5sqrB.js → _9kX9D09B.js} +1 -1
  16. package/dist/public/assets/_9kX9D09B.js.br +0 -0
  17. package/dist/public/assets/_9lErVegn.js +1 -0
  18. package/dist/public/assets/_B0oyGUU5.js +1 -0
  19. package/dist/public/assets/_B0oyGUU5.js.br +0 -0
  20. package/dist/public/assets/_B1mPnLlp.js +1 -0
  21. package/dist/public/assets/_B4fi2SSA.js +1 -0
  22. package/dist/public/assets/{_OZcBKgKS.js → _B582D2rg.js} +1 -1
  23. package/dist/public/assets/{_DYm1j3HZ.js → _B7GwDeKK.js} +1 -1
  24. package/dist/public/assets/_B7Qx25UP.js +1 -0
  25. package/dist/public/assets/_B7b8EVjA.js +1 -0
  26. package/dist/public/assets/{_Cp1dT7ox.js → _BBWaxDkO.js} +1 -1
  27. package/dist/public/assets/_BBWaxDkO.js.br +0 -0
  28. package/dist/public/assets/{_BYHfXvmU.js → _BDa-iwuj.js} +1 -1
  29. package/dist/public/assets/_BDa-iwuj.js.br +0 -0
  30. package/dist/public/assets/_BEKHKNmM.js +1 -0
  31. package/dist/public/assets/{_BHkMvOuI.js → _BE_Jyvqd.js} +1 -1
  32. package/dist/public/assets/_BE_Jyvqd.js.br +0 -0
  33. package/dist/public/assets/_BFU-kJkk.js +1 -0
  34. package/dist/public/assets/_BGCK5I_O.js +1 -0
  35. package/dist/public/assets/_BGCK5I_O.js.br +0 -0
  36. package/dist/public/assets/_BIJ2O2oU.js +1 -0
  37. package/dist/public/assets/_BJ59XAZ9.js +1 -0
  38. package/dist/public/assets/_BKqRYfOI.js +15 -0
  39. package/dist/public/assets/_BKqRYfOI.js.br +0 -0
  40. package/dist/public/assets/_BKr9Dzz1.js +1 -0
  41. package/dist/public/assets/_BN7xvxS_.js +1 -0
  42. package/dist/public/assets/_BNQTVBlH.js +1 -0
  43. package/dist/public/assets/{_DFiA_pht.js → _BNW5Jiec.js} +1 -1
  44. package/dist/public/assets/_BNW5Jiec.js.br +0 -0
  45. package/dist/public/assets/{_DW6AnxDW.js → _BOGkzMx9.js} +1 -1
  46. package/dist/public/assets/_BOGkzMx9.js.br +0 -0
  47. package/dist/public/assets/_BUEpqQ_m.js +1 -0
  48. package/dist/public/assets/{_BJIAaIh4.js → _BUvqweu0.js} +1 -1
  49. package/dist/public/assets/_BUvqweu0.js.br +0 -0
  50. package/dist/public/assets/_BZKB4fhr.js +1 -0
  51. package/dist/public/assets/_BZKB4fhr.js.br +0 -0
  52. package/dist/public/assets/_BZo9BjDF.js +1 -0
  53. package/dist/public/assets/{_4KGVbuYs.js → _BbbOvNRH.js} +1 -1
  54. package/dist/public/assets/_BbbOvNRH.js.br +0 -0
  55. package/dist/public/assets/_BdUNnSlC.js +1 -0
  56. package/dist/public/assets/{_KM7EGl2R.js → _Bf8WYPfh.js} +1 -1
  57. package/dist/public/assets/_Bf8WYPfh.js.br +0 -0
  58. package/dist/public/assets/{_buuWf96L.js → _Bhx319Hi.js} +1 -1
  59. package/dist/public/assets/_Bhx319Hi.js.br +0 -0
  60. package/dist/public/assets/{_BYgxEDpq.js → _Bm4SHrNp.js} +1 -1
  61. package/dist/public/assets/_Bm4SHrNp.js.br +0 -0
  62. package/dist/public/assets/_Bmrqq8Ro.js +2 -0
  63. package/dist/public/assets/_Bmrqq8Ro.js.br +0 -0
  64. package/dist/public/assets/_BnHZ6Npj.js +1 -0
  65. package/dist/public/assets/{_NGfZeYAt.js → _BoDxRJLS.js} +1 -1
  66. package/dist/public/assets/_BoDxRJLS.js.br +0 -0
  67. package/dist/public/assets/_Bo_Ru664.js +1 -0
  68. package/dist/public/assets/{_BxpaVKca.js → _Bp8-V8yl.js} +1 -1
  69. package/dist/public/assets/_Bp8-V8yl.js.br +0 -0
  70. package/dist/public/assets/{_Ct2VbISZ.js → _BpoeUr5j.js} +1 -1
  71. package/dist/public/assets/_BpoeUr5j.js.br +0 -0
  72. package/dist/public/assets/_Bq2G_Tid.js +1 -0
  73. package/dist/public/assets/_BsyoLB_D.js +1 -0
  74. package/dist/public/assets/{_CdWPIocC.js → _Bv3e3rg8.js} +1 -1
  75. package/dist/public/assets/_Bv3e3rg8.js.br +0 -0
  76. package/dist/public/assets/{_D74J3kwJ.js → _Bv3qNE1b.js} +1 -1
  77. package/dist/public/assets/{_BSliyqkf.js → _BvXp6HpX.js} +1 -1
  78. package/dist/public/assets/_BvXp6HpX.js.br +0 -0
  79. package/dist/public/assets/{_DNqoI_cd.js → _BwP07uVS.js} +1 -1
  80. package/dist/public/assets/_BwP07uVS.js.br +0 -0
  81. package/dist/public/assets/{_D93v6VDe.js → _Bx1CW-sF.js} +1 -1
  82. package/dist/public/assets/_Bx1CW-sF.js.br +0 -0
  83. package/dist/public/assets/{_DZLJGzpN.js → _BywcP-As.js} +1 -1
  84. package/dist/public/assets/_BywcP-As.js.br +0 -0
  85. package/dist/public/assets/_Bzgtwt3G.js +1 -0
  86. package/dist/public/assets/_Bzgtwt3G.js.br +0 -0
  87. package/dist/public/assets/{_U2n8Yyqy.js → _C0_s45qg.js} +1 -1
  88. package/dist/public/assets/_C0_s45qg.js.br +0 -0
  89. package/dist/public/assets/_C0ePgF6b.js +1 -0
  90. package/dist/public/assets/_C0oVtTqO.js +1 -0
  91. package/dist/public/assets/_C0oVtTqO.js.br +0 -0
  92. package/dist/public/assets/{_TxnhYSE5.js → _C654p96Z.js} +1 -1
  93. package/dist/public/assets/_C654p96Z.js.br +0 -0
  94. package/dist/public/assets/_C8_1Y2-z.js +1 -0
  95. package/dist/public/assets/_C8_1Y2-z.js.br +0 -0
  96. package/dist/public/assets/_C8v1AZFP.js +1 -0
  97. package/dist/public/assets/{_Dns259C4.js → _CAkPJLeF.js} +1 -1
  98. package/dist/public/assets/{_Dns259C4.js.br → _CAkPJLeF.js.br} +0 -0
  99. package/dist/public/assets/_CB0D5cRH.js +1 -0
  100. package/dist/public/assets/_CD05JUTh.js +1 -0
  101. package/dist/public/assets/{_BIul3uoC.js → _CEJUcePr.js} +1 -1
  102. package/dist/public/assets/_CEJUcePr.js.br +0 -0
  103. package/dist/public/assets/{_CN5iw4cA.js → _CEXHZd73.js} +1 -1
  104. package/dist/public/assets/_CEXHZd73.js.br +0 -0
  105. package/dist/public/assets/_CHcUMVR7.js +1 -0
  106. package/dist/public/assets/{_Dtx2usNe.js → _CHuLFr1f.js} +1 -1
  107. package/dist/public/assets/_CHuLFr1f.js.br +0 -0
  108. package/dist/public/assets/{_9xYWGqfi.js → _CIb7xw_1.js} +1 -1
  109. package/dist/public/assets/_CIb7xw_1.js.br +0 -0
  110. package/dist/public/assets/{_C1JRCVnT.js → _CMSBfO6u.js} +1 -1
  111. package/dist/public/assets/_CMSBfO6u.js.br +0 -0
  112. package/dist/public/assets/_CN7GPyBo.js +1 -0
  113. package/dist/public/assets/{_Cnl5owe1.js → _COcePo2y.js} +1 -1
  114. package/dist/public/assets/_COcePo2y.js.br +0 -0
  115. package/dist/public/assets/{_B7nG9Ktb.js → _CTINBWaG.js} +1 -1
  116. package/dist/public/assets/_CTINBWaG.js.br +0 -0
  117. package/dist/public/assets/_CTWrnAbz.js +1 -0
  118. package/dist/public/assets/{_CKwCTsbp.js → _CUXajOKj.js} +1 -1
  119. package/dist/public/assets/_CUXajOKj.js.br +0 -0
  120. package/dist/public/assets/{_BY6ayWBy.js → _CVru3vzC.js} +1 -1
  121. package/dist/public/assets/{_cSsv1ZjH.js → _CYjE__ml.js} +1 -1
  122. package/dist/public/assets/_CYjE__ml.js.br +0 -0
  123. package/dist/public/assets/{_BlSF31Ck.js → _CZ_OWtIT.js} +1 -1
  124. package/dist/public/assets/_CZ_OWtIT.js.br +0 -0
  125. package/dist/public/assets/{_CrV4JiE4.js → _C_37_B6u.js} +1 -1
  126. package/dist/public/assets/_C_37_B6u.js.br +0 -0
  127. package/dist/public/assets/_C_CIQL7J.js +1 -0
  128. package/dist/public/assets/_C_CIQL7J.js.br +0 -0
  129. package/dist/public/assets/_C_WdpYbK.js +1 -0
  130. package/dist/public/assets/_CaiH3VN9.js +1 -0
  131. package/dist/public/assets/{_BXU-ZvQb.js → _CamWDaoG.js} +1 -1
  132. package/dist/public/assets/_CamWDaoG.js.br +0 -0
  133. package/dist/public/assets/_CdDElA0V.js +1 -0
  134. package/dist/public/assets/_CfnsClzZ.js +1 -0
  135. package/dist/public/assets/_Cgo1fRhJ.js +1 -0
  136. package/dist/public/assets/_Cgo1fRhJ.js.br +0 -0
  137. package/dist/public/assets/_CjhGrlf3.js +1 -0
  138. package/dist/public/assets/_CjlbL4C_.js +1 -0
  139. package/dist/public/assets/_CjogTUXK.js +1 -0
  140. package/dist/public/assets/{_BS0AEB1V.js → _ClldMY37.js} +1 -1
  141. package/dist/public/assets/_ClldMY37.js.br +0 -0
  142. package/dist/public/assets/_CmFq6Gtp.js +1 -0
  143. package/dist/public/assets/_CoAPOKiP.js +1 -0
  144. package/dist/public/assets/_CoUUgh9P.js +1 -0
  145. package/dist/public/assets/{_BDCQoRmq.js → _CpjSCB1I.js} +1 -1
  146. package/dist/public/assets/_CpjSCB1I.js.br +0 -0
  147. package/dist/public/assets/{_CEvca0JK.js → _Ct3RF80L.js} +1 -1
  148. package/dist/public/assets/_Ct3RF80L.js.br +0 -0
  149. package/dist/public/assets/_CtYy5eZs.js +1 -0
  150. package/dist/public/assets/{_DvqvHR7_.js → _CxAPL49a.js} +1 -1
  151. package/dist/public/assets/_CxAPL49a.js.br +0 -0
  152. package/dist/public/assets/{_D_joWBEC.js → _CyBCIknf.js} +1 -1
  153. package/dist/public/assets/_CyBCIknf.js.br +0 -0
  154. package/dist/public/assets/{_KpWeECPp.js → _Cz5BPBG8.js} +1 -1
  155. package/dist/public/assets/_Cz5BPBG8.js.br +0 -0
  156. package/dist/public/assets/_D-eEFXaI.js +1 -0
  157. package/dist/public/assets/{_DPIQzOUl.js → _D0aoEFRx.js} +1 -1
  158. package/dist/public/assets/_D0aoEFRx.js.br +0 -0
  159. package/dist/public/assets/{_CluEtmrQ.js → _D1uRW1qz.js} +1 -1
  160. package/dist/public/assets/_D1uRW1qz.js.br +0 -0
  161. package/dist/public/assets/_D2oIr2T2.js +1 -0
  162. package/dist/public/assets/{_Bpf0Nyqk.js → _D2un443j.js} +1 -1
  163. package/dist/public/assets/_D2un443j.js.br +0 -0
  164. package/dist/public/assets/_D3MPx4-f.js +1 -0
  165. package/dist/public/assets/{_B-992FUw.js → _D4dJ2qEE.js} +1 -1
  166. package/dist/public/assets/{_CB-I9KUl.js → _D4q8XSMI.js} +1 -1
  167. package/dist/public/assets/_D4q8XSMI.js.br +0 -0
  168. package/dist/public/assets/{_BNPo3NaH.js → _D4quFMVQ.js} +1 -1
  169. package/dist/public/assets/_D4quFMVQ.js.br +0 -0
  170. package/dist/public/assets/{_6FNzwUcm.js → _D4rOX-Fa.js} +1 -1
  171. package/dist/public/assets/_D4rOX-Fa.js.br +0 -0
  172. package/dist/public/assets/_D5edrSyA.js +1 -0
  173. package/dist/public/assets/{_DJnXBrlD.js → _D6kktUFn.js} +1 -1
  174. package/dist/public/assets/_D6kktUFn.js.br +0 -0
  175. package/dist/public/assets/_D80-qtVY.js +1 -0
  176. package/dist/public/assets/_D9-3EVA4.js +1 -0
  177. package/dist/public/assets/{_Ca3bfNZI.js → _D9sS4J_w.js} +1 -1
  178. package/dist/public/assets/_D9sS4J_w.js.br +0 -0
  179. package/dist/public/assets/_DBLpxTDi.js +1 -0
  180. package/dist/public/assets/{_gP9nLV2Y.js → _DByHQ7nW.js} +117 -117
  181. package/dist/public/assets/_DByHQ7nW.js.br +0 -0
  182. package/dist/public/assets/{_C-oO7X9P.js → _DC-78WeM.js} +1 -1
  183. package/dist/public/assets/_DC-78WeM.js.br +0 -0
  184. package/dist/public/assets/{_SHB9zmh2.js → _DDl8KSWJ.js} +1 -1
  185. package/dist/public/assets/_DDl8KSWJ.js.br +0 -0
  186. package/dist/public/assets/{_CPMD0qdL.js → _DFWOMF-B.js} +1 -1
  187. package/dist/public/assets/_DFWOMF-B.js.br +0 -0
  188. package/dist/public/assets/_DKb-rt9n.js +1 -0
  189. package/dist/public/assets/_DMnSJCF_.js +1 -0
  190. package/dist/public/assets/_DOOIlrPh.js +1 -0
  191. package/dist/public/assets/_DPW-0yKP.js +1 -0
  192. package/dist/public/assets/_DR3BmvWU.js +1 -0
  193. package/dist/public/assets/{_BpLwQ1O8.js → _DSVLaMWS.js} +1 -1
  194. package/dist/public/assets/_DSVLaMWS.js.br +0 -0
  195. package/dist/public/assets/_DYNGNKLk.js +1 -0
  196. package/dist/public/assets/_DZnEgCbj.js +1 -0
  197. package/dist/public/assets/{_CgsPFJZy.js → _DaMVRI8f.js} +1 -1
  198. package/dist/public/assets/_DaMVRI8f.js.br +0 -0
  199. package/dist/public/assets/_DbvaGqOl.js +1 -0
  200. package/dist/public/assets/_DbvaGqOl.js.br +0 -0
  201. package/dist/public/assets/{_ItervcuA.js → _DcMIlvz-.js} +1 -1
  202. package/dist/public/assets/_DcMIlvz-.js.br +0 -0
  203. package/dist/public/assets/{_D5yRmwZD.js → _Dd6X3e7w.js} +1 -1
  204. package/dist/public/assets/_Dd6X3e7w.js.br +0 -0
  205. package/dist/public/assets/{_BxAKVWw-.js → _De7P3jUH.js} +1 -1
  206. package/dist/public/assets/_De7P3jUH.js.br +0 -0
  207. package/dist/public/assets/_DeiFEAar.js +1 -0
  208. package/dist/public/assets/{_tqD_68em.js → _DfI982PI.js} +1 -1
  209. package/dist/public/assets/_DfI982PI.js.br +0 -0
  210. package/dist/public/assets/_DfZ6emcw.js +1 -0
  211. package/dist/public/assets/{_M94yp4jo.js → _Dj1lZ1pa.js} +12 -12
  212. package/dist/public/assets/_Dj1lZ1pa.js.br +0 -0
  213. package/dist/public/assets/{_BCTeDxHC.js → _DkCaEf_h.js} +1 -1
  214. package/dist/public/assets/_DkCaEf_h.js.br +0 -0
  215. package/dist/public/assets/_DonAis0J.js +1 -0
  216. package/dist/public/assets/{_DktieTrd.js → _Dp3IZdH8.js} +1 -1
  217. package/dist/public/assets/_Dp3IZdH8.js.br +0 -0
  218. package/dist/public/assets/_DqYih4xk.js +1 -0
  219. package/dist/public/assets/_DqYih4xk.js.br +0 -0
  220. package/dist/public/assets/{_B9Ukk65G.js → _DqhphdU4.js} +1 -1
  221. package/dist/public/assets/_DqhphdU4.js.br +0 -0
  222. package/dist/public/assets/{_DLJu1hcD.js → _DrIgZJzN.js} +1 -1
  223. package/dist/public/assets/_DrIgZJzN.js.br +0 -0
  224. package/dist/public/assets/_Dt4hHR05.js +1 -0
  225. package/dist/public/assets/_DtTbTraA.js +1 -0
  226. package/dist/public/assets/_DwMxAJKP.js +1 -0
  227. package/dist/public/assets/{_LgS0G0uH.js → _DxEm-Gwj.js} +1 -1
  228. package/dist/public/assets/_DxEm-Gwj.js.br +0 -0
  229. package/dist/public/assets/{_C4KQv1VW.js → _Dytf99zx.js} +1 -1
  230. package/dist/public/assets/_Dytf99zx.js.br +0 -0
  231. package/dist/public/assets/_EAgv5jR9.js +1 -0
  232. package/dist/public/assets/_Iecpd0kS.js +1 -0
  233. package/dist/public/assets/_Iecpd0kS.js.br +0 -0
  234. package/dist/public/assets/{_QlXMW-cP.js → _MCwIJAuJ.js} +1 -1
  235. package/dist/public/assets/_MCwIJAuJ.js.br +0 -0
  236. package/dist/public/assets/_NM79Lu3L.js +6 -0
  237. package/dist/public/assets/_NM79Lu3L.js.br +0 -0
  238. package/dist/public/assets/_QpNKKuS9.js +1 -0
  239. package/dist/public/assets/{_B29iioj9.js → _SGDxiwE1.js} +1 -1
  240. package/dist/public/assets/_SGDxiwE1.js.br +0 -0
  241. package/dist/public/assets/_TA8pE7z9.js +1 -0
  242. package/dist/public/assets/_bE4sNDeU.js +1 -0
  243. package/dist/public/assets/{_Bk_g_9Bn.js → _bcsuBP7T.js} +1 -1
  244. package/dist/public/assets/_bcsuBP7T.js.br +0 -0
  245. package/dist/public/assets/_cdcAU4yY.js +1 -0
  246. package/dist/public/assets/{_aAORMS0u.js → _ch_yXAap.js} +1 -1
  247. package/dist/public/assets/_ch_yXAap.js.br +0 -0
  248. package/dist/public/assets/{_ByqDCoAZ.js → _d5u7EI97.js} +1 -1
  249. package/dist/public/assets/_d5u7EI97.js.br +0 -0
  250. package/dist/public/assets/{_i6oi77xC.js → _eoa1EOU-.js} +1 -1
  251. package/dist/public/assets/_eoa1EOU-.js.br +0 -0
  252. package/dist/public/assets/{_H7TtilBa.js → _j2tDSMvo.js} +1 -1
  253. package/dist/public/assets/_j2tDSMvo.js.br +0 -0
  254. package/dist/public/assets/_jNhIFgbc.js +1 -0
  255. package/dist/public/assets/_kDYiTaag.js +1 -0
  256. package/dist/public/assets/_lNMVVbUx.js +1 -0
  257. package/dist/public/assets/_nwJ7Hu3S.js +1 -0
  258. package/dist/public/assets/_tmDtUACa.js +1 -0
  259. package/dist/public/assets/_tmDtUACa.js.br +0 -0
  260. package/dist/public/assets/_wXDh-Z2N.js +1 -0
  261. package/dist/public/assets/_wXDh-Z2N.js.br +0 -0
  262. package/dist/public/assets/{_C3E24F_T.js → _wcshV0sZ.js} +1 -1
  263. package/dist/public/assets/_wcshV0sZ.js.br +0 -0
  264. package/dist/public/assets/_x-NwqgCn.js +1 -0
  265. package/dist/public/assets/{_DZD7yzH2.js → _xyw_DS5P.js} +1 -1
  266. package/dist/public/assets/_xyw_DS5P.js.br +0 -0
  267. package/dist/public/assets/{_CsicaM6z.js → _zSAfqXcm.js} +1 -1
  268. package/dist/public/assets/_zSAfqXcm.js.br +0 -0
  269. package/dist/public/assets/app-shell-ChQoVC5b.css +1 -0
  270. package/dist/public/assets/app-shell-ChQoVC5b.css.br +0 -0
  271. package/dist/public/assets/files-view-CLtLp_BW.js +2 -0
  272. package/dist/public/assets/files-view-CNHQapdI.css +1 -0
  273. package/dist/public/assets/files-view-CNHQapdI.css.br +0 -0
  274. package/dist/public/assets/group.css.ts-BG82htKb.css +1 -0
  275. package/dist/public/assets/group.css.ts-BG82htKb.css.br +0 -0
  276. package/dist/public/assets/icon-folder-DJOHuEpD.css +1 -0
  277. package/dist/public/assets/icon-folder-DJOHuEpD.css.br +0 -0
  278. package/dist/public/assets/{icon-search-C6A4IBPq.css → icon-search-DsJuFXUJ.css} +1 -1
  279. package/dist/public/assets/icon-search-DsJuFXUJ.css.br +0 -0
  280. package/dist/public/assets/manage-workspace-NBcFDyrB.js +2 -0
  281. package/dist/public/assets/manage-workspace-f_Np32TD.css +1 -0
  282. package/dist/public/assets/{modal-view-BY2E8mw2.css → modal-view-KVNBpNYi.css} +1 -1
  283. package/dist/public/assets/modal-view-KVNBpNYi.css.br +0 -0
  284. package/dist/public/assets/new-DHI77GvL.js +1 -0
  285. package/dist/public/assets/new-workspace-BFE-HpD_.css +1 -0
  286. package/dist/public/assets/new-workspace-BFE-HpD_.css.br +0 -0
  287. package/dist/public/assets/new-workspace-BRzimdd5.js +2 -0
  288. package/dist/public/assets/port-chip-CUUIDOVM.css +1 -0
  289. package/dist/public/assets/port-chip-CUUIDOVM.css.br +0 -0
  290. package/dist/public/assets/prompt-dialog-BGs6RXOV.css +1 -0
  291. package/dist/public/assets/prompt-dialog-BGs6RXOV.css.br +0 -0
  292. package/dist/public/assets/quick-open-Gx4so1bl.css +1 -0
  293. package/dist/public/assets/quick-open-Gx4so1bl.css.br +0 -0
  294. package/dist/public/assets/repo-picker-CUhd0vJN.css +1 -0
  295. package/dist/public/assets/repo-picker-CUhd0vJN.css.br +4 -0
  296. package/dist/public/assets/review-view-DFEK9VBa.js +2 -0
  297. package/dist/public/assets/review-view-deUY3OE5.css +1 -0
  298. package/dist/public/assets/review-view-deUY3OE5.css.br +0 -0
  299. package/dist/public/assets/section-CziSOSBR.css +1 -0
  300. package/dist/public/assets/section-CziSOSBR.css.br +0 -0
  301. package/dist/public/assets/settings-DHI77GvL.js +1 -0
  302. package/dist/public/assets/settings-page-OOtPOzIn.js +2 -0
  303. package/dist/public/assets/settings-page-wZhd7FLi.css +1 -0
  304. package/dist/public/assets/settings-page-wZhd7FLi.css.br +0 -0
  305. package/dist/public/assets/skill-row-BoCyFIXg.css +1 -0
  306. package/dist/public/assets/sso-auth-DV76tTpE.css +1 -0
  307. package/dist/public/assets/sso-auth-DV76tTpE.css.br +0 -0
  308. package/dist/public/assets/w-DHI77GvL.js +1 -0
  309. package/dist/public/assets/w._-DHI77GvL.js +1 -0
  310. package/dist/public/assets/w._-DsTgq3-C.js +1 -0
  311. package/dist/public/assets/w._-igEOSPR-.js +1 -0
  312. package/install.sh +1 -1
  313. package/lib/review/markdown.mjs +5 -5
  314. package/lib/setup/bridge.d.mts +10 -0
  315. package/lib/setup/bridge.mjs +84 -0
  316. package/lib/setup/catalog.d.mts +3 -0
  317. package/lib/setup/catalog.mjs +17 -0
  318. package/lib/setup/doctor.d.mts +6 -0
  319. package/lib/setup/doctor.mjs +50 -5
  320. package/lib/setup/install.d.mts +1 -0
  321. package/lib/setup/install.mjs +21 -1
  322. package/lib/setup/listen.mjs +2 -2
  323. package/lib/share/manifest.mjs +3 -2
  324. package/package.json +4 -5
  325. package/dist/_u9qRCTjI.js +0 -2
  326. package/dist/public/assets/_43qHqm_h.js +0 -1
  327. package/dist/public/assets/_4KGVbuYs.js.br +0 -0
  328. package/dist/public/assets/_4hbCil9D.js +0 -1
  329. package/dist/public/assets/_4hbCil9D.js.br +0 -0
  330. package/dist/public/assets/_69GBvJfT.js +0 -1
  331. package/dist/public/assets/_6FNzwUcm.js.br +0 -0
  332. package/dist/public/assets/_8SWI_CIk.js +0 -1
  333. package/dist/public/assets/_8SWI_CIk.js.br +0 -0
  334. package/dist/public/assets/_9fKCaxLn.js +0 -1
  335. package/dist/public/assets/_9xYWGqfi.js.br +0 -0
  336. package/dist/public/assets/_AKwHRUw2.js +0 -1
  337. package/dist/public/assets/_B29iioj9.js.br +0 -0
  338. package/dist/public/assets/_B3bcGOWb.js +0 -1
  339. package/dist/public/assets/_B3fa8s0p.js +0 -1
  340. package/dist/public/assets/_B6-AgBRx.js +0 -1
  341. package/dist/public/assets/_B6-AgBRx.js.br +0 -0
  342. package/dist/public/assets/_B68mxQgf.js +0 -15
  343. package/dist/public/assets/_B68mxQgf.js.br +0 -0
  344. package/dist/public/assets/_B7lNd0Fe.js +0 -1
  345. package/dist/public/assets/_B7nG9Ktb.js.br +0 -0
  346. package/dist/public/assets/_B9Ukk65G.js.br +0 -0
  347. package/dist/public/assets/_BCTeDxHC.js.br +0 -0
  348. package/dist/public/assets/_BDCQoRmq.js.br +0 -0
  349. package/dist/public/assets/_BHkMvOuI.js.br +0 -0
  350. package/dist/public/assets/_BIul3uoC.js.br +0 -0
  351. package/dist/public/assets/_BJIAaIh4.js.br +0 -5
  352. package/dist/public/assets/_BJk5sqrB.js.br +0 -0
  353. package/dist/public/assets/_BLOE-kpM.js +0 -1
  354. package/dist/public/assets/_BNK4RUnx.js +0 -1
  355. package/dist/public/assets/_BNPo3NaH.js.br +0 -0
  356. package/dist/public/assets/_BPMmLRzt.js +0 -1
  357. package/dist/public/assets/_BQ91qGf-.js +0 -1
  358. package/dist/public/assets/_BS0AEB1V.js.br +0 -0
  359. package/dist/public/assets/_BS66ieXF.js +0 -1
  360. package/dist/public/assets/_BSb0QOJN.js +0 -1
  361. package/dist/public/assets/_BSliyqkf.js.br +0 -0
  362. package/dist/public/assets/_BSydNGAC.js +0 -2
  363. package/dist/public/assets/_BSydNGAC.js.br +0 -0
  364. package/dist/public/assets/_BXU-ZvQb.js.br +0 -0
  365. package/dist/public/assets/_BYHfXvmU.js.br +0 -0
  366. package/dist/public/assets/_BYcB3W24.js +0 -1
  367. package/dist/public/assets/_BYgxEDpq.js.br +0 -0
  368. package/dist/public/assets/_BYi6z1C9.js +0 -1
  369. package/dist/public/assets/_BbM04KlN.js +0 -1
  370. package/dist/public/assets/_Bc5E_ez3.js +0 -1
  371. package/dist/public/assets/_BcWZ_-iA.js +0 -1
  372. package/dist/public/assets/_BkXPpVmm.js +0 -1
  373. package/dist/public/assets/_Bk_g_9Bn.js.br +0 -0
  374. package/dist/public/assets/_BlSF31Ck.js.br +0 -0
  375. package/dist/public/assets/_Bn4xIRpG.js +0 -1
  376. package/dist/public/assets/_BpLwQ1O8.js.br +0 -0
  377. package/dist/public/assets/_BpVNeKi-.js +0 -1
  378. package/dist/public/assets/_BpdpbMex.js +0 -1
  379. package/dist/public/assets/_Bpf0Nyqk.js.br +0 -0
  380. package/dist/public/assets/_BwBNAwDG.js +0 -1
  381. package/dist/public/assets/_BxAKVWw-.js.br +0 -0
  382. package/dist/public/assets/_BxpaVKca.js.br +0 -0
  383. package/dist/public/assets/_ByqDCoAZ.js.br +0 -0
  384. package/dist/public/assets/_Bzg_Rzcf.js +0 -1
  385. package/dist/public/assets/_C-oO7X9P.js.br +0 -0
  386. package/dist/public/assets/_C0KvehwH.js +0 -1
  387. package/dist/public/assets/_C1JRCVnT.js.br +0 -0
  388. package/dist/public/assets/_C2U9mANP.js +0 -1
  389. package/dist/public/assets/_C3E24F_T.js.br +0 -0
  390. package/dist/public/assets/_C4KQv1VW.js.br +0 -0
  391. package/dist/public/assets/_C5MTb3MY.js +0 -1
  392. package/dist/public/assets/_C7ha2DpU.js +0 -1
  393. package/dist/public/assets/_C7ha2DpU.js.br +0 -0
  394. package/dist/public/assets/_CAaW1fUv.js +0 -1
  395. package/dist/public/assets/_CB-I9KUl.js.br +0 -0
  396. package/dist/public/assets/_CEvca0JK.js.br +0 -0
  397. package/dist/public/assets/_CGZs9U_g.js +0 -1
  398. package/dist/public/assets/_CK6p4Zj1.js +0 -1
  399. package/dist/public/assets/_CK6p4Zj1.js.br +0 -0
  400. package/dist/public/assets/_CKwCTsbp.js.br +0 -0
  401. package/dist/public/assets/_CKyRgnW2.js +0 -1
  402. package/dist/public/assets/_CN5iw4cA.js.br +0 -0
  403. package/dist/public/assets/_CPAGQRmF.js +0 -1
  404. package/dist/public/assets/_CPMD0qdL.js.br +0 -0
  405. package/dist/public/assets/_CRi7-Tyh.js +0 -1
  406. package/dist/public/assets/_CU2T7o-W.js +0 -1
  407. package/dist/public/assets/_CVSAwdO1.js +0 -1
  408. package/dist/public/assets/_CZzsPgfD.js +0 -1
  409. package/dist/public/assets/_C_jQehPQ.js +0 -1
  410. package/dist/public/assets/_Ca3bfNZI.js.br +0 -0
  411. package/dist/public/assets/_CdWPIocC.js.br +0 -0
  412. package/dist/public/assets/_CeFqvzt1.js +0 -1
  413. package/dist/public/assets/_CgsPFJZy.js.br +0 -0
  414. package/dist/public/assets/_ClgoCZxV.js +0 -6
  415. package/dist/public/assets/_ClgoCZxV.js.br +0 -0
  416. package/dist/public/assets/_CluEtmrQ.js.br +0 -0
  417. package/dist/public/assets/_Cnl5owe1.js.br +0 -0
  418. package/dist/public/assets/_Cp1dT7ox.js.br +0 -0
  419. package/dist/public/assets/_Cpyx7Ldm.js +0 -1
  420. package/dist/public/assets/_Cq4-AZ6O.js +0 -1
  421. package/dist/public/assets/_CrV4JiE4.js.br +0 -0
  422. package/dist/public/assets/_Csdgg-p8.js +0 -1
  423. package/dist/public/assets/_Csdgg-p8.js.br +0 -0
  424. package/dist/public/assets/_CsicaM6z.js.br +0 -0
  425. package/dist/public/assets/_Ct2VbISZ.js.br +0 -0
  426. package/dist/public/assets/_CtQ-4c6a.js.br +0 -0
  427. package/dist/public/assets/_Cyfdf5Zc.js +0 -1
  428. package/dist/public/assets/_D1qsYd77.js +0 -1
  429. package/dist/public/assets/_D1qsYd77.js.br +0 -0
  430. package/dist/public/assets/_D5yRmwZD.js.br +0 -0
  431. package/dist/public/assets/_D78O__dl.js +0 -1
  432. package/dist/public/assets/_D93v6VDe.js.br +0 -0
  433. package/dist/public/assets/_DDfizRXp.js +0 -1
  434. package/dist/public/assets/_DDfizRXp.js.br +0 -0
  435. package/dist/public/assets/_DFiA_pht.js.br +0 -0
  436. package/dist/public/assets/_DGDsfGXN.js +0 -1
  437. package/dist/public/assets/_DGDsfGXN.js.br +0 -0
  438. package/dist/public/assets/_DJnXBrlD.js.br +0 -0
  439. package/dist/public/assets/_DKiEZYX8.js +0 -1
  440. package/dist/public/assets/_DLEnV6cR.js +0 -1
  441. package/dist/public/assets/_DLJu1hcD.js.br +0 -0
  442. package/dist/public/assets/_DL_rHJtD.js +0 -1
  443. package/dist/public/assets/_DNFF24hk.js +0 -1
  444. package/dist/public/assets/_DNqoI_cd.js.br +0 -0
  445. package/dist/public/assets/_DOLRYXID.js +0 -1
  446. package/dist/public/assets/_DPIQzOUl.js.br +0 -0
  447. package/dist/public/assets/_DQWcu2Z_.js +0 -1
  448. package/dist/public/assets/_DW6AnxDW.js.br +0 -0
  449. package/dist/public/assets/_DWYjkjOA.js +0 -1
  450. package/dist/public/assets/_DXE83VZw.js +0 -1
  451. package/dist/public/assets/_DYBhy6q4.js.br +0 -0
  452. package/dist/public/assets/_DYKZ1zvC.js +0 -1
  453. package/dist/public/assets/_DYbmgf-P.js +0 -1
  454. package/dist/public/assets/_DZD7yzH2.js.br +0 -0
  455. package/dist/public/assets/_DZLJGzpN.js.br +0 -0
  456. package/dist/public/assets/_D_joWBEC.js.br +0 -0
  457. package/dist/public/assets/_D_qiANiM.js +0 -1
  458. package/dist/public/assets/_D_qiANiM.js.br +0 -0
  459. package/dist/public/assets/_DhhUcrza.js +0 -1
  460. package/dist/public/assets/_Dik2fbTK.js +0 -1
  461. package/dist/public/assets/_Dik2fbTK.js.br +0 -0
  462. package/dist/public/assets/_DjGbHRs7.js +0 -1
  463. package/dist/public/assets/_DjdPagIm.js +0 -1
  464. package/dist/public/assets/_Djnp5vRt.js +0 -1
  465. package/dist/public/assets/_DktieTrd.js.br +0 -0
  466. package/dist/public/assets/_Dr2zRKuC.js +0 -1
  467. package/dist/public/assets/_Dtx2usNe.js.br +0 -0
  468. package/dist/public/assets/_DvnFb18d.js +0 -1
  469. package/dist/public/assets/_DvqvHR7_.js.br +0 -0
  470. package/dist/public/assets/_Dy57KGoU.js +0 -1
  471. package/dist/public/assets/_Dy57KGoU.js.br +0 -0
  472. package/dist/public/assets/_FdygZebO.js +0 -1
  473. package/dist/public/assets/_H7TtilBa.js.br +0 -0
  474. package/dist/public/assets/_HwOcVvTN.js +0 -1
  475. package/dist/public/assets/_ICJfUHY2.js +0 -1
  476. package/dist/public/assets/_ItervcuA.js.br +0 -0
  477. package/dist/public/assets/_JGwf6udl.js +0 -1
  478. package/dist/public/assets/_KM7EGl2R.js.br +0 -0
  479. package/dist/public/assets/_KpWeECPp.js.br +0 -0
  480. package/dist/public/assets/_LgS0G0uH.js.br +0 -0
  481. package/dist/public/assets/_M94yp4jo.js.br +0 -0
  482. package/dist/public/assets/_NGfZeYAt.js.br +0 -0
  483. package/dist/public/assets/_QlXMW-cP.js.br +0 -0
  484. package/dist/public/assets/_SHB9zmh2.js.br +0 -0
  485. package/dist/public/assets/_TSA_v82C.js +0 -1
  486. package/dist/public/assets/_TxnhYSE5.js.br +0 -0
  487. package/dist/public/assets/_U2n8Yyqy.js.br +0 -0
  488. package/dist/public/assets/_Vhpht63x.js +0 -1
  489. package/dist/public/assets/_Z9CaLBvo.js +0 -1
  490. package/dist/public/assets/__-FQNLs7.js +0 -1
  491. package/dist/public/assets/__CN8nA63.js +0 -1
  492. package/dist/public/assets/_aAORMS0u.js.br +0 -0
  493. package/dist/public/assets/_buuWf96L.js.br +0 -0
  494. package/dist/public/assets/_cSsv1ZjH.js.br +0 -0
  495. package/dist/public/assets/_gP9nLV2Y.js.br +0 -0
  496. package/dist/public/assets/_i6oi77xC.js.br +0 -0
  497. package/dist/public/assets/_jb3Fwzol.js +0 -1
  498. package/dist/public/assets/_lmVJ3O6t.js +0 -1
  499. package/dist/public/assets/_mloSZbwk.js +0 -1
  500. package/dist/public/assets/_sYOWcsEI.js +0 -1
  501. package/dist/public/assets/_tqD_68em.js.br +0 -0
  502. package/dist/public/assets/_y4SZiKqE.js +0 -1
  503. package/dist/public/assets/_y4SZiKqE.js.br +0 -0
  504. package/dist/public/assets/_zMYJngRw.js +0 -1
  505. package/dist/public/assets/_zTWXKPCk.js +0 -1
  506. package/dist/public/assets/app-shell-BXDHei7B.css +0 -1
  507. package/dist/public/assets/app-shell-BXDHei7B.css.br +0 -0
  508. package/dist/public/assets/files-view-BCnw4-08.js +0 -2
  509. package/dist/public/assets/files-view-Ds4k9TjY.css +0 -1
  510. package/dist/public/assets/files-view-Ds4k9TjY.css.br +0 -0
  511. package/dist/public/assets/group.css.ts-CZcH3cNI.css +0 -1
  512. package/dist/public/assets/group.css.ts-CZcH3cNI.css.br +0 -0
  513. package/dist/public/assets/icon-folder-De3LJVaT.css +0 -1
  514. package/dist/public/assets/icon-folder-De3LJVaT.css.br +0 -0
  515. package/dist/public/assets/icon-search-C6A4IBPq.css.br +0 -0
  516. package/dist/public/assets/manage-workspace-B2IJyc-s.js +0 -2
  517. package/dist/public/assets/manage-workspace-BYotHuev.css +0 -1
  518. package/dist/public/assets/modal-view-BY2E8mw2.css.br +0 -0
  519. package/dist/public/assets/new-workspace-9FQTNRn4.css +0 -1
  520. package/dist/public/assets/new-workspace-9FQTNRn4.css.br +0 -0
  521. package/dist/public/assets/new-workspace-B_6v9CYu.js +0 -2
  522. package/dist/public/assets/new-zQDWH4FQ.js +0 -1
  523. package/dist/public/assets/port-chip-V2q_q3UM.css +0 -1
  524. package/dist/public/assets/port-chip-V2q_q3UM.css.br +0 -0
  525. package/dist/public/assets/prompt-dialog-C_kDiYmC.css +0 -1
  526. package/dist/public/assets/prompt-dialog-C_kDiYmC.css.br +0 -0
  527. package/dist/public/assets/quick-open-IkoNJ7wT.css +0 -1
  528. package/dist/public/assets/quick-open-IkoNJ7wT.css.br +0 -0
  529. package/dist/public/assets/repo-picker-CMHPjNaZ.css +0 -1
  530. package/dist/public/assets/repo-picker-CMHPjNaZ.css.br +0 -0
  531. package/dist/public/assets/review-view-CqIbovDm.css +0 -1
  532. package/dist/public/assets/review-view-CqIbovDm.css.br +0 -0
  533. package/dist/public/assets/review-view-DJ3TxEP8.js +0 -2
  534. package/dist/public/assets/section-Bjoist2N.css +0 -1
  535. package/dist/public/assets/section-Bjoist2N.css.br +0 -0
  536. package/dist/public/assets/settings-page-CA4M6Hig.css +0 -1
  537. package/dist/public/assets/settings-page-CA4M6Hig.css.br +0 -0
  538. package/dist/public/assets/settings-page-Gf4hmpSr.js +0 -2
  539. package/dist/public/assets/settings-zQDWH4FQ.js +0 -1
  540. package/dist/public/assets/skill-row-y-AJuVyg.css +0 -1
  541. package/dist/public/assets/sso-auth-DCSrkI2L.css +0 -1
  542. package/dist/public/assets/sso-auth-DCSrkI2L.css.br +0 -0
  543. package/dist/public/assets/w-zQDWH4FQ.js +0 -1
  544. package/dist/public/assets/w._-B47BqhrV.js +0 -1
  545. package/dist/public/assets/w._-D0upu6g5.js +0 -1
  546. package/dist/public/assets/w._-zQDWH4FQ.js +0 -1
  547. package/scripts/migrate.mjs +0 -824
@@ -1,28 +1,103 @@
1
1
  import { i as __require, o as __toESM, t as __commonJSMin } from "./_BMI-E3GI.js";
2
2
  import { r as require_inherits, t as require_src$1 } from "./_xlrdOUsL.js";
3
3
  import { t as require_safe_buffer } from "./_BmSjjJ2E.js";
4
+ import { createRequire } from "node:module";
4
5
  import fs from "node:fs";
5
6
  import path from "node:path";
6
- import { execFile, execFileSync } from "node:child_process";
7
+ import { execFile, execFileSync, spawnSync } from "node:child_process";
8
+ import fs$1 from "node:fs/promises";
7
9
  import os from "node:os";
8
10
  import { promisify } from "node:util";
9
11
  import { DatabaseSync } from "node:sqlite";
10
12
  import { createHash } from "node:crypto";
11
- //#region src/server/http.ts
12
- /** Error whose `status` the API error-boundary middleware uses for the response. */
13
- function httpError(status, message) {
14
- return Object.assign(new Error(message), { status });
13
+ //#region src/server/cache.ts
14
+ /** Keyed stale-while-revalidate cache: a cached value is served immediately
15
+ * (revalidating in the background when older than `ttlMs`); loads are deduped
16
+ * per key, and `refresh` bypasses both the cache and any in-flight load. */
17
+ function swr(ttlMs, load, seed) {
18
+ const cache = /* @__PURE__ */ new Map();
19
+ const inflight = /* @__PURE__ */ new Map();
20
+ function start(key, refresh) {
21
+ const startedAt = Date.now();
22
+ const promise = load(key, refresh).then((value) => {
23
+ const existing = cache.get(key);
24
+ if (!existing || existing.at <= startedAt) cache.set(key, {
25
+ at: Date.now(),
26
+ value
27
+ });
28
+ return value;
29
+ }).finally(() => {
30
+ if (inflight.get(key)?.promise === promise) inflight.delete(key);
31
+ });
32
+ inflight.set(key, {
33
+ promise,
34
+ refresh
35
+ });
36
+ return promise;
37
+ }
38
+ const read = (key, refresh = false) => {
39
+ if (refresh) {
40
+ const current = inflight.get(key);
41
+ return current?.refresh ? current.promise : start(key, true);
42
+ }
43
+ let cached = cache.get(key);
44
+ if (!cached && seed) {
45
+ cached = seed(key);
46
+ if (cached) cache.set(key, cached);
47
+ }
48
+ if (cached) {
49
+ if (Date.now() - cached.at >= ttlMs && !inflight.has(key)) start(key, false).catch(() => {});
50
+ return Promise.resolve(cached.value);
51
+ }
52
+ return inflight.get(key)?.promise ?? start(key, false);
53
+ };
54
+ /** Inject an externally fetched value (e.g. from a batched load). */
55
+ read.set = (key, value) => {
56
+ cache.set(key, {
57
+ at: Date.now(),
58
+ value
59
+ });
60
+ };
61
+ /** Current cached value, if any — used when a batch update must merge
62
+ * with a richer per-key load rather than replace it. */
63
+ read.get = (key) => cache.get(key)?.value;
64
+ return read;
15
65
  }
16
- /** The value of a Standard Schema `[value, issues]` pair, or a thrown 400
17
- * built from the issues. */
18
- function checked(result, what = "request") {
19
- const [value, issues] = result;
20
- if (issues) throw httpError(400, `invalid ${what}: ${issues.map((issue) => issue.message).join("; ")}`);
21
- return value;
66
+ /** Serialize async work per key: calls for one key run in submission order,
67
+ * each starting only after the previous settled. The stored tail is the
68
+ * all-settled form, so a rejection neither blocks the next caller nor leaves
69
+ * the entry behind — the map holds only keys with work still in flight. */
70
+ var locks = /* @__PURE__ */ new Map();
71
+ function withLock(key, fn) {
72
+ const run = (locks.get(key) ?? Promise.resolve()).then(fn);
73
+ const tail = run.then(() => {}, () => {});
74
+ locks.set(key, tail);
75
+ tail.then(() => {
76
+ if (locks.get(key) === tail) locks.delete(key);
77
+ });
78
+ return run;
22
79
  }
23
- /** Validated request body, or a thrown 400 built from the valibot issues. */
24
- async function readBody(ctx) {
25
- return checked(await ctx.body, "request body");
80
+ /** One load at a time, and a short reuse window: callers join the in-flight
81
+ * load, and a result younger than `ttlMs` is served without one. For an
82
+ * expensive process sweep (lsof, ps, list-panes) whose answer does not
83
+ * change within the window — `ttlMs` of 0 still collapses concurrent
84
+ * callers onto a single spawn. */
85
+ function shared(fn, ttlMs) {
86
+ let inflight = null;
87
+ let last = null;
88
+ return () => {
89
+ if (last && Date.now() - last.at < ttlMs) return Promise.resolve(last.value);
90
+ if (!inflight) inflight = fn().then((value) => {
91
+ last = {
92
+ at: Date.now(),
93
+ value
94
+ };
95
+ return value;
96
+ }).finally(() => {
97
+ inflight = null;
98
+ });
99
+ return inflight;
100
+ };
26
101
  }
27
102
  //#endregion
28
103
  //#region lib/setup/listen.mjs
@@ -66,8 +141,9 @@ var config = {
66
141
  appPort: Number(process.env.WORK_APP_PORT || 7171),
67
142
  /** How a workspace port is named in a hostname the app proxies
68
143
  * (server/port-proxy.ts): `sub` is `3000.work.example.com`, `dash` is
69
- * `3000-work.example.com`. The server accepts both; this only picks
70
- * which one the port chips link to. `dash` stays one label under the
144
+ * `3000-work.example.com`. The port chips link to this one; the server
145
+ * takes `sub` either way, and `dash` only when it is picked
146
+ * (server/access.ts `dashPortName`). `dash` stays one label under the
71
147
  * zone, which is what a free Cloudflare certificate covers. */
72
148
  portHosts: process.env.WORK_PORT_HOSTS === "dash" ? "dash" : "sub",
73
149
  /** The address the server listens on: this machine only, unless set
@@ -92,6 +168,11 @@ function list(value) {
92
168
  return (value || "").split(",").map((s) => s.trim()).filter(Boolean);
93
169
  }
94
170
  fs.mkdirSync(config.dataDir, { recursive: true });
171
+ try {
172
+ fs.chmodSync(config.dataDir, 448);
173
+ } catch (err) {
174
+ console.warn(`[work] could not make ${config.dataDir} private: ${err.message}`);
175
+ }
95
176
  //#endregion
96
177
  //#region src/server/exec.ts
97
178
  /** Dedicated tmux server so we never touch another multiplexer's or the
@@ -131,21 +212,25 @@ var GIT_NETWORK_MS = {
131
212
  push: 3e5,
132
213
  "ls-remote": 6e4
133
214
  };
134
- /** Never let git wait on a terminal it doesn't have — a missing credential
135
- * fails with a message instead of hanging the clone forever. Optional
136
- * locks are off because most of what runs here is a background probe (the
137
- * review's stamp poll, Files, the language servers' change feed): a
138
- * `git status` refreshing the index holds `index.lock`, and an agent's
139
- * `git commit` or rebase step landing in that moment fails on it. */
215
+ /** What every git process work starts runs with, `extra` on top: `git`
216
+ * below, and the diff's streaming reads, which spawn their own. Never let
217
+ * git wait on a terminal it doesn't have — a missing credential fails with
218
+ * a message instead of hanging the clone forever. Optional locks are off
219
+ * because most of what runs here is a background probe (the review's
220
+ * stamp poll, Files, the language servers' change feed): a `git status`
221
+ * refreshing the index holds `index.lock`, and an agent's `git commit` or
222
+ * rebase step landing in that moment fails on it. */
223
+ var gitEnv = (extra) => ({
224
+ ...process.env,
225
+ GIT_TERMINAL_PROMPT: "0",
226
+ GIT_OPTIONAL_LOCKS: "0",
227
+ ...extra
228
+ });
140
229
  var git = async (args, cwd) => {
141
230
  const verb = args.find((a) => !a.startsWith("-")) ?? "";
142
231
  const timeoutMs = GIT_NETWORK_MS[verb];
143
232
  try {
144
- return await run$1("git", args, cwd, {
145
- ...process.env,
146
- GIT_TERMINAL_PROMPT: "0",
147
- GIT_OPTIONAL_LOCKS: "0"
148
- }, timeoutMs ? { timeoutMs } : void 0);
233
+ return await run$1("git", args, cwd, gitEnv(), timeoutMs ? { timeoutMs } : void 0);
149
234
  } catch (err) {
150
235
  if (timeoutMs && err.killed) throw new Error(`git ${verb} timed out after ${Math.round(timeoutMs / 1e3)}s`);
151
236
  throw err;
@@ -201,11 +286,281 @@ function utf8Locale(env) {
201
286
  for (const [key, value] of Object.entries(env)) if (value !== void 0) out[key] = value;
202
287
  return forceUtf8Locale(out);
203
288
  }
289
+ /** The release that brings a database to the baseline. WORK_BRIDGE_SPEC
290
+ * names another (an `npm pack` tarball of it) to try the bridge before it
291
+ * is published. */
292
+ function bridgeSpec() {
293
+ return process.env.WORK_BRIDGE_SPEC || "@dylanpiercey/work@0.0.223";
294
+ }
295
+ /** What to run by hand for the database in `dataDir`: its data dir named
296
+ * outright, since the shell running it may not have the service's. */
297
+ function bridgeCommands(dataDir) {
298
+ return [`WORK_DATA_DIR=${/^[\w@%+=:,./-]+$/.test(dataDir) ? dataDir : `'${dataDir.replace(/'/g, `'\\''`)}'`} npx -y -p ${bridgeSpec()} work migrate`, "work setup"];
299
+ }
300
+ /** Whether the database at `file` predates the baseline: it has tables and
301
+ * no version. A missing or empty one is simply new. node:sqlite is loaded
302
+ * here, not at the top: it warns on load under older node, and every other
303
+ * CLI command would say so. */
304
+ function needsBridge(file) {
305
+ if (!fs.existsSync(file)) return false;
306
+ const { DatabaseSync } = createRequire(import.meta.url)("node:sqlite");
307
+ const db = new DatabaseSync(file, { readOnly: true });
308
+ try {
309
+ const { user_version } = db.prepare("PRAGMA user_version").get();
310
+ const tables = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table'").get();
311
+ return user_version < 1 && !!tables;
312
+ } finally {
313
+ db.close();
314
+ }
315
+ }
316
+ /** Bring the database in `dataDir` to the baseline when it predates it,
317
+ * with `env` (the service's) so the sweeps see the same data dir and
318
+ * workspaces root the server does. True when it is there (or never needed
319
+ * to be). The package's install scripts are skipped: `migrate` needs none,
320
+ * and a native build that fails would fail the bridge with it. */
321
+ function bridgeIfNeeded(dataDir, env, log = () => {}) {
322
+ const file = path.join(dataDir, "work.db");
323
+ if (!needsBridge(file)) return true;
324
+ log(`${file} predates 0.1: bringing it forward once with ${bridgeSpec()} (a one-time download)`);
325
+ const sibling = path.join(path.dirname(process.execPath), "npx");
326
+ const npx = fs.existsSync(sibling) ? sibling : "npx";
327
+ spawnSync(npx, [
328
+ "-y",
329
+ "-p",
330
+ bridgeSpec(),
331
+ "work",
332
+ "migrate"
333
+ ], {
334
+ stdio: "inherit",
335
+ env: {
336
+ ...env,
337
+ WORK_DATA_DIR: dataDir,
338
+ npm_config_ignore_scripts: "true"
339
+ }
340
+ });
341
+ return !needsBridge(file);
342
+ }
343
+ /** The server's bridge, for db.ts to hand the migrations: with the server's
344
+ * own environment, before the database is opened, once per start. */
345
+ function bridgeForServer(dataDir) {
346
+ return bridgeIfNeeded(dataDir, process.env, (line) => console.log(`[work] ${line}`));
347
+ }
348
+ //#endregion
349
+ //#region src/server/migrations.ts
350
+ var STEPS = [{
351
+ version: 1,
352
+ name: "baseline",
353
+ up(db) {
354
+ db.exec(`
355
+ CREATE TABLE workspaces (
356
+ id TEXT PRIMARY KEY,
357
+ name TEXT NOT NULL,
358
+ path TEXT NOT NULL UNIQUE,
359
+ branch TEXT NOT NULL,
360
+ status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'archived')),
361
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
362
+ materialized INTEGER NOT NULL DEFAULT 1,
363
+ origin_branch TEXT,
364
+ imported_at TEXT
365
+ );
366
+
367
+ CREATE TABLE repos (
368
+ workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
369
+ full_name TEXT NOT NULL,
370
+ worktree TEXT NOT NULL,
371
+ base_branch TEXT NOT NULL,
372
+ default_branch TEXT NOT NULL,
373
+ PRIMARY KEY (workspace_id, full_name)
374
+ );
375
+
376
+ CREATE TABLE sessions (
377
+ id TEXT PRIMARY KEY,
378
+ workspace_id TEXT REFERENCES workspaces(id) ON DELETE SET NULL,
379
+ agent TEXT NOT NULL,
380
+ title TEXT,
381
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
382
+ );
383
+
384
+ CREATE TABLE settings (
385
+ key TEXT PRIMARY KEY,
386
+ value TEXT NOT NULL
387
+ );
388
+
389
+ CREATE TABLE review_comments (
390
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
391
+ workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
392
+ worktree TEXT NOT NULL,
393
+ path TEXT NOT NULL,
394
+ side TEXT NOT NULL DEFAULT 'additions',
395
+ line_start INTEGER NOT NULL,
396
+ line_end INTEGER NOT NULL,
397
+ text TEXT NOT NULL,
398
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
399
+ head TEXT,
400
+ snippet TEXT
401
+ );
402
+
403
+ CREATE TABLE push_subscriptions (
404
+ endpoint TEXT PRIMARY KEY,
405
+ data TEXT NOT NULL
406
+ );
407
+
408
+ CREATE TABLE dismissed_prs (
409
+ workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
410
+ full_name TEXT NOT NULL,
411
+ number INTEGER NOT NULL,
412
+ PRIMARY KEY (workspace_id, full_name, number)
413
+ );
414
+
415
+ CREATE TABLE review_marks (
416
+ workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
417
+ worktree TEXT NOT NULL,
418
+ branch TEXT NOT NULL,
419
+ path TEXT NOT NULL,
420
+ fingerprint TEXT NOT NULL,
421
+ PRIMARY KEY (workspace_id, worktree, branch, path)
422
+ );
423
+ `);
424
+ }
425
+ }, {
426
+ version: 2,
427
+ name: "drop what 0.0.x kept for its upgrades",
428
+ up(db) {
429
+ db.exec(`
430
+ DELETE FROM review_marks WHERE path = '';
431
+ DELETE FROM settings
432
+ WHERE key IN ('review-cleared-diff-v2', 'ui.diff-uncommitted', 'diff-uncommitted')
433
+ OR key GLOB 'review.seen:*';
434
+ `);
435
+ for (const name of [
436
+ "tab",
437
+ "diff-filter",
438
+ "diff-folded",
439
+ "diff-collapsed",
440
+ "diff-focus",
441
+ "diff-pos",
442
+ "files-recent"
443
+ ]) {
444
+ const prefix = `ui.${name}:`;
445
+ db.prepare("DELETE FROM settings WHERE key GLOB ? AND substr(key, ?) NOT IN (SELECT id FROM workspaces)").run(`${prefix}*`, prefix.length + 1);
446
+ }
447
+ const pref = (key) => db.prepare("SELECT value FROM settings WHERE key = ?").get(key)?.value;
448
+ const parse = (text) => {
449
+ try {
450
+ return text === void 0 ? void 0 : JSON.parse(text);
451
+ } catch {
452
+ return;
453
+ }
454
+ };
455
+ const font = parse(pref("ui.term-font"));
456
+ if (font && typeof font === "object") {
457
+ for (const device of ["desktop", "touch"]) if (Number.isInteger(font[device])) db.prepare("INSERT OR IGNORE INTO settings (key, value) VALUES (?, ?)").run(`ui.term-font-${device}`, String(font[device]));
458
+ }
459
+ db.exec("DELETE FROM settings WHERE key = 'ui.term-font'");
460
+ const keys = parse(pref("ui.phone-keys"));
461
+ if (Array.isArray(keys)) db.prepare("UPDATE settings SET value = ? WHERE key = 'ui.phone-keys'").run(JSON.stringify({
462
+ base: [],
463
+ extra: keys
464
+ }));
465
+ }
466
+ }];
467
+ var LATEST = STEPS.at(-1).version;
468
+ /** The database at `file`, at the latest version: an empty one is built by
469
+ * every step, an existing one gets those it lacks — each in a transaction
470
+ * of its own with its version stamp inside it, after a copy of the whole
471
+ * file (`work.db.v<from>.bak` beside it, the newest two kept). One from
472
+ * before the baseline is handed to `bridge` first, when given (the
473
+ * server's: lib/setup/bridge.mjs). Throws, with what to do in its message,
474
+ * for a database this code cannot open: one still from before the
475
+ * baseline, one from a newer release, or one a step failed on (rolled back
476
+ * to the step before). */
477
+ function openDatabase(file, { bridge } = {}) {
478
+ if (bridge && needsBridge(file)) bridge(path.dirname(file));
479
+ const db = new DatabaseSync(file);
480
+ try {
481
+ db.exec("PRAGMA busy_timeout = 5000");
482
+ db.exec("PRAGMA journal_mode = WAL");
483
+ migrate(db, file);
484
+ db.exec("PRAGMA foreign_keys = ON");
485
+ return db;
486
+ } catch (err) {
487
+ db.close();
488
+ throw err;
489
+ }
490
+ }
491
+ function versionOf(db) {
492
+ return db.prepare("PRAGMA user_version").get().user_version;
493
+ }
494
+ function migrate(db, file) {
495
+ const from = versionOf(db);
496
+ const empty = !db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table'").get();
497
+ if (from < 1 && !empty) throw new Error(`${file} predates 0.1 and has not been brought forward (once, with the network: \`work setup\`, or this server on its next start). By hand:\n ${bridgeCommands(path.dirname(file)).join("\n ")}`);
498
+ if (from > LATEST) {
499
+ const backup = newestBackup(file, LATEST);
500
+ throw new Error(`${file} is at schema version ${from}, and this work knows up to ${LATEST}: a newer release upgraded it. Update work (\`work update\`)${backup ? `, or restore ${backup}, the copy taken before it did` : ""}.`);
501
+ }
502
+ const pending = STEPS.filter((s) => s.version > from);
503
+ if (!pending.length) return;
504
+ const backup = empty ? null : snapshot(db, file, from);
505
+ for (const step of pending) {
506
+ db.exec("BEGIN IMMEDIATE");
507
+ try {
508
+ if (versionOf(db) >= step.version) {
509
+ db.exec("ROLLBACK");
510
+ continue;
511
+ }
512
+ step.up(db);
513
+ db.exec(`PRAGMA user_version = ${step.version}`);
514
+ db.exec("COMMIT");
515
+ } catch (err) {
516
+ try {
517
+ db.exec("ROLLBACK");
518
+ } catch {}
519
+ throw new Error(`${file}: step ${step.version} (${step.name}) failed and was rolled back, leaving the database at version ${versionOf(db)}: ${err.message}${backup ? `. The copy from before this upgrade is ${backup}` : ""}`);
520
+ }
521
+ }
522
+ }
523
+ var backupName = (file, version) => `${path.basename(file)}.v${version}.bak`;
524
+ /** The file's backups, newest version first. */
525
+ function backups(file) {
526
+ const dir = path.dirname(file);
527
+ const re = new RegExp(`^${path.basename(file).replace(/\./g, "\\.")}\\.v(\\d+)\\.bak$`);
528
+ let names = [];
529
+ try {
530
+ names = fs.readdirSync(dir);
531
+ } catch {}
532
+ return names.map((name) => re.exec(name)).filter((m) => !!m).map((m) => ({
533
+ file: path.join(dir, m[0]),
534
+ version: Number(m[1])
535
+ })).sort((a, b) => b.version - a.version);
536
+ }
537
+ function newestBackup(file, atMost) {
538
+ return backups(file).find((b) => b.version <= atMost)?.file ?? null;
539
+ }
540
+ /** A copy of the whole database as it is before an upgrade from `version`,
541
+ * which a release that knows `version` can open. */
542
+ function snapshot(db, file, version) {
543
+ const dest = path.join(path.dirname(file), backupName(file, version));
544
+ fs.rmSync(dest, { force: true });
545
+ db.prepare("VACUUM INTO ?").run(dest);
546
+ for (const old of backups(file).slice(2)) fs.rmSync(old.file, { force: true });
547
+ return dest;
548
+ }
204
549
  //#endregion
205
550
  //#region src/server/db.ts
206
551
  if (!path.isAbsolute(config.dataDir)) throw new Error(`data dir must be absolute, got "${config.dataDir}" — check WORK_DATA_DIR and $HOME`);
207
- var db = new DatabaseSync(path.join(config.dataDir, "work.db"));
208
- db.exec("PRAGMA busy_timeout = 5000");
552
+ /** The app's database, at the latest schema version before anything reads
553
+ * it (server/migrations.ts), one from before 0.1 bridged first. One this
554
+ * release cannot open stops the server here, saying what to do: a stack
555
+ * trace would bury that under itself. */
556
+ var db = (() => {
557
+ try {
558
+ return openDatabase(path.join(config.dataDir, "work.db"), { bridge: bridgeForServer });
559
+ } catch (err) {
560
+ console.error(`[work] ${err.message}`);
561
+ process.exit(1);
562
+ }
563
+ })();
209
564
  /** Prepared statements, kept by their SQL: preparing is most of a small
210
565
  * query's cost (10 µs against 4), and a status build runs hundreds. The
211
566
  * texts are the call sites' own, so the set is small; the cap covers any
@@ -229,90 +584,33 @@ function get(sql, ...params) {
229
584
  function workspacePath(id) {
230
585
  return get("SELECT path FROM workspaces WHERE id = ?", id)?.path;
231
586
  }
232
- var freshReview = !db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'review_comments'").get();
233
- db.exec(`
234
- PRAGMA journal_mode = WAL;
235
- PRAGMA foreign_keys = ON;
236
-
237
- CREATE TABLE IF NOT EXISTS workspaces (
238
- id TEXT PRIMARY KEY,
239
- name TEXT NOT NULL,
240
- path TEXT NOT NULL UNIQUE,
241
- branch TEXT NOT NULL,
242
- status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'archived')),
243
- created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
244
- );
245
-
246
- CREATE TABLE IF NOT EXISTS repos (
247
- workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
248
- full_name TEXT NOT NULL,
249
- worktree TEXT NOT NULL,
250
- base_branch TEXT NOT NULL,
251
- default_branch TEXT NOT NULL,
252
- PRIMARY KEY (workspace_id, full_name)
253
- );
254
-
255
- CREATE TABLE IF NOT EXISTS sessions (
256
- id TEXT PRIMARY KEY,
257
- workspace_id TEXT REFERENCES workspaces(id) ON DELETE SET NULL,
258
- agent TEXT NOT NULL,
259
- title TEXT,
260
- created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
261
- );
262
-
263
- CREATE TABLE IF NOT EXISTS settings (
264
- key TEXT PRIMARY KEY,
265
- value TEXT NOT NULL
266
- );
267
-
268
- CREATE TABLE IF NOT EXISTS review_comments (
269
- id INTEGER PRIMARY KEY AUTOINCREMENT,
270
- workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
271
- worktree TEXT NOT NULL,
272
- path TEXT NOT NULL,
273
- side TEXT NOT NULL DEFAULT 'additions',
274
- line_start INTEGER NOT NULL,
275
- line_end INTEGER NOT NULL,
276
- text TEXT NOT NULL,
277
- created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
278
- );
279
-
280
- CREATE TABLE IF NOT EXISTS push_subscriptions (
281
- endpoint TEXT PRIMARY KEY,
282
- data TEXT NOT NULL
283
- );
284
-
285
- CREATE TABLE IF NOT EXISTS dismissed_prs (
286
- workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
287
- full_name TEXT NOT NULL,
288
- number INTEGER NOT NULL,
289
- PRIMARY KEY (workspace_id, full_name, number)
290
- );
291
-
292
- -- Viewed marks (server/viewed.ts): a file of a branch, and its change
293
- -- as it was when marked. Keep in sync with scripts/migrate.mjs, which
294
- -- creates it too.
295
- CREATE TABLE IF NOT EXISTS review_marks (
296
- workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
297
- worktree TEXT NOT NULL,
298
- branch TEXT NOT NULL,
299
- path TEXT NOT NULL,
300
- fingerprint TEXT NOT NULL,
301
- PRIMARY KEY (workspace_id, worktree, branch, path)
302
- );
303
- `);
304
- if (freshReview) db.prepare("INSERT OR IGNORE INTO settings (key, value) VALUES ('review-cleared-diff-v2', '1')").run();
305
- /** Additive schema changes: `CREATE TABLE IF NOT EXISTS` never revisits a
306
- * table that already exists, so a column added after a release has to be
307
- * bolted on here for databases created before it. */
308
- function ensureColumn(table, column, decl) {
309
- if (!db.prepare(`PRAGMA table_info(${table})`).all().some((c) => c.name === column)) db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${decl}`);
310
- }
311
- ensureColumn("review_comments", "head", "TEXT");
312
- ensureColumn("review_comments", "snippet", "TEXT");
313
- ensureColumn("workspaces", "materialized", "INTEGER NOT NULL DEFAULT 1");
314
- ensureColumn("workspaces", "origin_branch", "TEXT");
315
- ensureColumn("workspaces", "imported_at", "TEXT");
587
+ //#endregion
588
+ //#region src/server/http.ts
589
+ /** Who may frame the app's own responses: the app alone (the review's PDF
590
+ * preview). A page elsewhere that frames it can dress a click on it as a
591
+ * click on something of its own. A route that sends a
592
+ * Content-Security-Policy of its own replaces this one, so it names
593
+ * `FRAME_ANCESTORS` too. */
594
+ var FRAME_ANCESTORS = "frame-ancestors 'self'";
595
+ var FRAME_HEADERS = {
596
+ "content-security-policy": FRAME_ANCESTORS,
597
+ "x-frame-options": "SAMEORIGIN"
598
+ };
599
+ /** Error whose `status` the API error-boundary middleware uses for the response. */
600
+ function httpError(status, message) {
601
+ return Object.assign(new Error(message), { status });
602
+ }
603
+ /** The value of a Standard Schema `[value, issues]` pair, or a thrown 400
604
+ * built from the issues. */
605
+ function checked(result, what = "request") {
606
+ const [value, issues] = result;
607
+ if (issues) throw httpError(400, `invalid ${what}: ${issues.map((issue) => issue.message).join("; ")}`);
608
+ return value;
609
+ }
610
+ /** Validated request body, or a thrown 400 built from the valibot issues. */
611
+ async function readBody(ctx) {
612
+ return checked(await ctx.body, "request body");
613
+ }
316
614
  //#endregion
317
615
  //#region src/client/pref-change.ts
318
616
  /** The stored text after `change`, or null when nothing is left. A value
@@ -642,6 +940,18 @@ var DEFAULT_GITHUB_HOST = "github.com";
642
940
  function toolById(id) {
643
941
  return TOOLS.find((t) => t.id === id) || PROJECT_TOOLS.find((t) => t.id === id) || null;
644
942
  }
943
+ /** A version that is only a version (`latest`, `lts`, `22`, `1.2.3-rc.1`),
944
+ * not one of mise's forms that build from a git ref or point at a path
945
+ * (`ref:`, `path:`, `prefix:`). */
946
+ var PLAIN_VERSION = /^(?!-)[\w.+-]+$/;
947
+ /** Whether a mise pin is one of the tools above, as they install, at a
948
+ * plain version: what a restore takes without asking. Any other name —
949
+ * a registry tool the catalog does not list, a backend (`npm:`, `ubi:`,
950
+ * `github:`, `cargo:`, `go:`, `pipx:` …), a URL — installs and runs
951
+ * whatever it names, so a restore takes it only when it is named. */
952
+ function catalogPin(name, version) {
953
+ return [...TOOLS, ...PROJECT_TOOLS].some((t) => t.mise === name) && PLAIN_VERSION.test(version);
954
+ }
645
955
  function agentById(id) {
646
956
  return AGENTS$1.find((a) => a.id === id) || null;
647
957
  }
@@ -711,8 +1021,9 @@ function setupDirs() {
711
1021
  };
712
1022
  return dirsFor.dirs;
713
1023
  }
714
- /** `~/…` for anything under the home directory — every path here is for
715
- * display (Settings rows, `work doctor`), never re-used to exec. */
1024
+ /** `~/…` for anything under the home directory — every path given it is
1025
+ * for display (Settings rows, `work doctor`, a language server's
1026
+ * definition outside every checkout), never re-used to exec. */
716
1027
  function tilde(p) {
717
1028
  if (!p) return p;
718
1029
  return p === home ? "~" : p.startsWith(home + path.sep) ? "~" + p.slice(home.length) : p;
@@ -779,6 +1090,40 @@ async function readMiseInstalls() {
779
1090
  } catch {}
780
1091
  return out;
781
1092
  }
1093
+ /** A path owned by one release of a version manager — mise/asdf
1094
+ * `installs`, homebrew's `Cellar`, nvm's `versions` — which that tool
1095
+ * deletes on its next update. */
1096
+ var VERSIONED_PATH = /\/(installs|Cellar|versions|toolchains)\//;
1097
+ /** The gh for git to run as a credential helper: the launcher on PATH
1098
+ * (mise's shim, /usr/bin/gh), when it is not itself one release's. Still an
1099
+ * absolute path, so it works for GUI clients and cron jobs that never
1100
+ * sourced a shell profile, but one that follows upgrades. */
1101
+ function stableGh() {
1102
+ const gh = which("gh");
1103
+ return gh && !VERSIONED_PATH.test(gh) ? gh : null;
1104
+ }
1105
+ /** Credential helpers in ~/.gitconfig that run a gh which is gone, by
1106
+ * config key. `gh auth setup-git` writes the absolute path of the gh that
1107
+ * ran it, and git runs that string literally: once a version manager's
1108
+ * upgrade deletes it, every https push fails with "could not read
1109
+ * Username" while `gh` itself still works. Listed only when there is a
1110
+ * stable gh to point them at, which `work setup` does. */
1111
+ async function staleGhHelpers() {
1112
+ if (!stableGh()) return [];
1113
+ const { stdout } = await run("git", [
1114
+ "config",
1115
+ "--global",
1116
+ "--get-regexp",
1117
+ String.raw`^credential\..*\.helper$`
1118
+ ]);
1119
+ const keys = /* @__PURE__ */ new Set();
1120
+ for (const line of stdout.split("\n")) {
1121
+ const sp = line.indexOf(" ");
1122
+ const bin = /^!(\S+) auth git-credential$/.exec(line.slice(sp + 1))?.[1];
1123
+ if (sp > 0 && bin && !fs.existsSync(bin)) keys.add(line.slice(0, sp));
1124
+ }
1125
+ return [...keys];
1126
+ }
782
1127
  /** Hosts `gh` knows about (~/.config/gh/hosts.yml top-level keys) — the
783
1128
  * source of truth for "which GitHub hosts has this machine signed in to",
784
1129
  * merged with whatever the caller has configured. */
@@ -949,11 +1294,12 @@ async function doctor(opts = {}) {
949
1294
  ...opts.hosts || [],
950
1295
  ...ghKnownHosts()
951
1296
  ]);
952
- const [versions, github, awake, extensions] = await Promise.all([
1297
+ const [versions, github, awake, extensions, helpers] = await Promise.all([
953
1298
  miseVersions(),
954
1299
  Promise.all([...hostSet].map(githubHostStatus)),
955
1300
  canStayAwake(),
956
- ghExtensions()
1301
+ ghExtensions(),
1302
+ staleGhHelpers()
957
1303
  ]);
958
1304
  const tools = TOOLS.map((t) => {
959
1305
  if (t.ghExtension) {
@@ -994,7 +1340,8 @@ async function doctor(opts = {}) {
994
1340
  tools,
995
1341
  agents,
996
1342
  github,
997
- awake
1343
+ awake,
1344
+ staleGhHelpers: helpers
998
1345
  };
999
1346
  }
1000
1347
  //#endregion
@@ -1017,8 +1364,7 @@ var PREF_MAX = 4096;
1017
1364
  /** The prefs kept per workspace, keyed `<name>:<workspace id>`. They ride
1018
1365
  * every page's HTML, so they go with the workspace (`deleteWorkspacePrefs`)
1019
1366
  * and /api/prefs refuses them for one that is gone; one missing here
1020
- * outlives its workspace for good. `scripts/migrate.mjs` prunes orphans of
1021
- * the same list. */
1367
+ * outlives its workspace for good. */
1022
1368
  var WORKSPACE_PREFS = [
1023
1369
  "tab",
1024
1370
  "diff-filter",
@@ -1106,96 +1452,6 @@ function preferredAgent(enabled = enabledAgents()) {
1106
1452
  return enabled[0] || "shell";
1107
1453
  }
1108
1454
  //#endregion
1109
- //#region src/server/cache.ts
1110
- /** Keyed stale-while-revalidate cache: a cached value is served immediately
1111
- * (revalidating in the background when older than `ttlMs`); loads are deduped
1112
- * per key, and `refresh` bypasses both the cache and any in-flight load. */
1113
- function swr(ttlMs, load, seed) {
1114
- const cache = /* @__PURE__ */ new Map();
1115
- const inflight = /* @__PURE__ */ new Map();
1116
- function start(key, refresh) {
1117
- const startedAt = Date.now();
1118
- const promise = load(key, refresh).then((value) => {
1119
- const existing = cache.get(key);
1120
- if (!existing || existing.at <= startedAt) cache.set(key, {
1121
- at: Date.now(),
1122
- value
1123
- });
1124
- return value;
1125
- }).finally(() => {
1126
- if (inflight.get(key)?.promise === promise) inflight.delete(key);
1127
- });
1128
- inflight.set(key, {
1129
- promise,
1130
- refresh
1131
- });
1132
- return promise;
1133
- }
1134
- const read = (key, refresh = false) => {
1135
- if (refresh) {
1136
- const current = inflight.get(key);
1137
- return current?.refresh ? current.promise : start(key, true);
1138
- }
1139
- let cached = cache.get(key);
1140
- if (!cached && seed) {
1141
- cached = seed(key);
1142
- if (cached) cache.set(key, cached);
1143
- }
1144
- if (cached) {
1145
- if (Date.now() - cached.at >= ttlMs && !inflight.has(key)) start(key, false).catch(() => {});
1146
- return Promise.resolve(cached.value);
1147
- }
1148
- return inflight.get(key)?.promise ?? start(key, false);
1149
- };
1150
- /** Inject an externally fetched value (e.g. from a batched load). */
1151
- read.set = (key, value) => {
1152
- cache.set(key, {
1153
- at: Date.now(),
1154
- value
1155
- });
1156
- };
1157
- /** Current cached value, if any — used when a batch update must merge
1158
- * with a richer per-key load rather than replace it. */
1159
- read.get = (key) => cache.get(key)?.value;
1160
- return read;
1161
- }
1162
- /** Serialize async work per key: calls for one key run in submission order,
1163
- * each starting only after the previous settled. The stored tail is the
1164
- * all-settled form, so a rejection neither blocks the next caller nor leaves
1165
- * the entry behind — the map holds only keys with work still in flight. */
1166
- var locks = /* @__PURE__ */ new Map();
1167
- function withLock(key, fn) {
1168
- const run = (locks.get(key) ?? Promise.resolve()).then(fn);
1169
- const tail = run.then(() => {}, () => {});
1170
- locks.set(key, tail);
1171
- tail.then(() => {
1172
- if (locks.get(key) === tail) locks.delete(key);
1173
- });
1174
- return run;
1175
- }
1176
- /** One load at a time, and a short reuse window: callers join the in-flight
1177
- * load, and a result younger than `ttlMs` is served without one. For an
1178
- * expensive process sweep (lsof, ps, list-panes) whose answer does not
1179
- * change within the window — `ttlMs` of 0 still collapses concurrent
1180
- * callers onto a single spawn. */
1181
- function shared(fn, ttlMs) {
1182
- let inflight = null;
1183
- let last = null;
1184
- return () => {
1185
- if (last && Date.now() - last.at < ttlMs) return Promise.resolve(last.value);
1186
- if (!inflight) inflight = fn().then((value) => {
1187
- last = {
1188
- at: Date.now(),
1189
- value
1190
- };
1191
- return value;
1192
- }).finally(() => {
1193
- inflight = null;
1194
- });
1195
- return inflight;
1196
- };
1197
- }
1198
- //#endregion
1199
1455
  //#region src/server/events.ts
1200
1456
  var listeners$1 = /* @__PURE__ */ new Set();
1201
1457
  function publish(type, data) {
@@ -1219,7 +1475,7 @@ function subscribe(listener) {
1219
1475
  listeners$1.add(listener);
1220
1476
  return () => listeners$1.delete(listener);
1221
1477
  }
1222
- /** Connected SSE clients — lets background watchers idle when no one
1478
+ /** Connected events-bus clients — lets background watchers idle when no one
1223
1479
  * is listening. */
1224
1480
  function subscriberCount() {
1225
1481
  return listeners$1.size;
@@ -7177,7 +7433,7 @@ var background = /* @__PURE__ */ new Map();
7177
7433
  /** A turn's end is pushed once it has stayed ended this long. Stop fires
7178
7434
  * again each time something sends the agent back to work (a stop hook
7179
7435
  * that continues it, a goal loop, background subagents reporting in), and
7180
- * each of those ends was a "Finished" on the phone while it carried on. */
7436
+ * each of those ends would be a "Finished" on the phone while it carries on. */
7181
7437
  var DONE_SETTLE_MS = 3e3;
7182
7438
  var listeners = /* @__PURE__ */ new Set();
7183
7439
  /** Called on every phase transition (the status snapshot drops itself). */
@@ -7350,7 +7606,7 @@ function publishChange(sessionId) {
7350
7606
  const row = get("SELECT workspace_id FROM sessions WHERE id = ?", sessionId);
7351
7607
  if (row?.workspace_id) {
7352
7608
  const workspaceId = row.workspace_id;
7353
- import("./_u9qRCTjI.js").then((m) => m.notifySessionsChanged(workspaceId));
7609
+ import("./_CkwTsHKB.js").then((m) => m.notifySessionsChanged(workspaceId));
7354
7610
  return;
7355
7611
  }
7356
7612
  publish("sessions.changed");
@@ -7760,10 +8016,10 @@ async function fetchUsage$3(account) {
7760
8016
  var PROFILE_TTL_MS = 36e5;
7761
8017
  var profiles = /* @__PURE__ */ new Map();
7762
8018
  /** The account's plan as Anthropic has it now. `.claude.json` holds what
7763
- * Claude Code saw at sign-in, and it only asks again on a new login, so an
7764
- * upgrade (Max 5x → 20x) kept reading as the old plan until then. Asked
7765
- * with the same token as the usage; the cached plan stands in when it
7766
- * cannot be. */
8019
+ * Claude Code saw at sign-in, and it only asks again on a new login, so
8020
+ * from it alone an upgrade (Max 5x → 20x) reads as the old plan until
8021
+ * then. Asked with the same token as the usage; the cached plan stands in
8022
+ * when it cannot be. */
7767
8023
  async function livePlan(account) {
7768
8024
  const hit = profiles.get(account.dir);
7769
8025
  if (hit && Date.now() - hit.at < PROFILE_TTL_MS) return hit.plan;
@@ -8664,6 +8920,47 @@ var cursor = {
8664
8920
  usage: () => cursorRow().then((row) => [row])
8665
8921
  };
8666
8922
  //#endregion
8923
+ //#region src/server/paths.ts
8924
+ /** Whether `target` is `root` or somewhere under it, by name alone. Both
8925
+ * are normalised first, so `..` and a trailing slash count as the
8926
+ * filesystem would count them, and the separator after `root` is the
8927
+ * whole point: a sibling `…/work-2` is not in `…/work`. A relative
8928
+ * `target` is in nothing — an empty one is a process cwd that could not
8929
+ * be read, not the root. A symlink under `root` can still lead out: what
8930
+ * is read through one wants `realInside`. */
8931
+ function inside(target, root) {
8932
+ if (!path.isAbsolute(target)) return false;
8933
+ const top = path.resolve(root);
8934
+ const full = path.resolve(target);
8935
+ return full === top || full.startsWith(top.endsWith(path.sep) ? top : top + path.sep);
8936
+ }
8937
+ /** Where `file` — named from `root`, as git and the pages name a
8938
+ * checkout's files, or absolute — really leads through every symlink,
8939
+ * when that is still `root` or under it; null when it leads out or is not
8940
+ * there. The check by name alone lets a symlink in a repo, which a branch
8941
+ * can add, point a read at any file on the machine. */
8942
+ async function realInside(file, root) {
8943
+ const full = path.resolve(root, file);
8944
+ if (!inside(full, root)) return null;
8945
+ try {
8946
+ const [top, real] = await Promise.all([fs$1.realpath(root), fs$1.realpath(full)]);
8947
+ return inside(real, top) ? real : null;
8948
+ } catch {
8949
+ return null;
8950
+ }
8951
+ }
8952
+ /** `realInside` for a caller that cannot wait. */
8953
+ function realInsideSync(file, root) {
8954
+ const full = path.resolve(root, file);
8955
+ if (!inside(full, root)) return null;
8956
+ try {
8957
+ const real = fs.realpathSync(full);
8958
+ return inside(real, fs.realpathSync(root)) ? real : null;
8959
+ } catch {
8960
+ return null;
8961
+ }
8962
+ }
8963
+ //#endregion
8667
8964
  //#region src/agents/grok/usage.ts
8668
8965
  var AUTH = path.join(HOME, ".grok", "auth.json");
8669
8966
  var LOG = path.join(HOME, ".grok", "logs", "unified.jsonl");
@@ -8836,7 +9133,7 @@ function scratch() {
8836
9133
  return os.tmpdir();
8837
9134
  }
8838
9135
  })();
8839
- return hookFile().startsWith(tmp + path.sep);
9136
+ return inside(hookFile(), tmp);
8840
9137
  }
8841
9138
  /** Whether Grok's hook registry names work's hook file — without it Grok
8842
9139
  * reports nothing and the screen has to speak for it. Read from disk, not
@@ -9364,10 +9661,10 @@ function tmuxWasStarted(id) {
9364
9661
  function clearTmuxStarted(id) {
9365
9662
  tmuxStarted.delete(id);
9366
9663
  }
9367
- /** SSE payload: session rows + live tmux/hook state so clients don't refetch.
9368
- * Coalesced per workspace: a turn boundary lands as a burst of phase
9369
- * transitions (hook, then scrape), and each one cost a list-panes spawn
9370
- * and a broadcast for a list that came out the same. */
9664
+ /** Events-bus payload: session rows + live tmux/hook state so clients
9665
+ * don't refetch. Coalesced per workspace: a turn boundary lands as a burst
9666
+ * of phase transitions (hook, then scrape), and each one cost a list-panes
9667
+ * spawn and a broadcast for a list that came out the same. */
9371
9668
  var EMIT_DEBOUNCE_MS = 50;
9372
9669
  var pendingEmits = /* @__PURE__ */ new Map();
9373
9670
  function notifySessionsChanged(workspaceId) {
@@ -9394,8 +9691,14 @@ async function emitSessionsChanged(workspaceId) {
9394
9691
  async function killWorkspaceSessions(workspaceId) {
9395
9692
  for (const session of listSessions(workspaceId)) await killSession(session.id);
9396
9693
  }
9694
+ /** Control characters a paste never means: C0 but tab and line breaks,
9695
+ * ESC, DEL and C1. The text can quote a reviewed file, which is repo
9696
+ * content, and an ESC in it can end the bracketed paste early on a tmux
9697
+ * that passes one through, typing the rest into the pane as keys. */
9698
+ var PASTE_UNSAFE = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/g;
9397
9699
  /** Type text into a session's tmux (bracketed paste + Enter), creating it if needed. */
9398
- async function sendToSession(id, text, size) {
9700
+ async function sendToSession(id, raw, size) {
9701
+ const text = raw.replace(PASTE_UNSAFE, "");
9399
9702
  const session = getSession(id);
9400
9703
  if (!session) throw new Error("unknown session");
9401
9704
  const wsPath = workspacePath(session.workspace_id);
@@ -9534,28 +9837,12 @@ async function listPanesNow() {
9534
9837
  };
9535
9838
  return panes;
9536
9839
  }
9537
- /** Cleared once per process — boot already runs this, and a server we
9538
- * create below never has PORT set, so re-running on every attach only
9539
- * unsets something already unset. */
9540
- var portCleared = false;
9541
9840
  /** Start the tmux server in its own systemd user unit so it escapes this
9542
9841
  * service's cgroup — otherwise `systemctl restart work` kills every
9543
9842
  * session with it. A hidden "work-keeper" session pins the server alive
9544
9843
  * (tmux exits when its last session closes). */
9545
9844
  async function ensureTmuxServer() {
9546
- if (await tmux(["has-session"]).then(() => true, () => false)) {
9547
- if (!portCleared) {
9548
- await tmux([
9549
- "set-environment",
9550
- "-g",
9551
- "-u",
9552
- "PORT"
9553
- ]).catch(() => {});
9554
- portCleared = true;
9555
- }
9556
- return;
9557
- }
9558
- portCleared = true;
9845
+ if (await tmux(["has-session"]).then(() => true, () => false)) return;
9559
9846
  await run$1("systemd-run", [
9560
9847
  "--user",
9561
9848
  `--unit=${TMUX_SOCKET === "work" ? "work-tmux" : `work-tmux-${TMUX_SOCKET.replace(/[^\w.:-]/g, "_")}`}`,
@@ -9573,68 +9860,71 @@ async function ensureTmuxServer() {
9573
9860
  ], os.homedir()).catch(() => {});
9574
9861
  }
9575
9862
  /** Full tmux command (options + new-session) for creating/attaching a
9576
- * session's tmux; `mode` is "-d" (create detached) or "-A" (attach-or-create). */
9863
+ * session's tmux; `mode` is "-d" (create detached) or "-A" (attach-or-create).
9864
+ * Every `set-option` is `-q`: one failed command drops the rest of a `;`
9865
+ * chain, new-session included, and a tmux older than an option
9866
+ * (`fill-character`, `extended-keys-format`) rejects its name. */
9577
9867
  function newSessionArgs(session, wsPath, mode, initialPrompt, size) {
9578
9868
  return [
9579
9869
  "start-server",
9580
9870
  ";",
9581
9871
  "set-option",
9582
- "-g",
9872
+ "-gq",
9583
9873
  "status",
9584
9874
  "off",
9585
9875
  ";",
9586
9876
  "set-option",
9587
- "-g",
9877
+ "-gq",
9588
9878
  "mouse",
9589
9879
  "on",
9590
9880
  ";",
9591
9881
  "set-option",
9592
- "-g",
9882
+ "-gq",
9593
9883
  "history-limit",
9594
9884
  "5000",
9595
9885
  ";",
9596
9886
  "set-option",
9597
- "-g",
9887
+ "-gq",
9598
9888
  "fill-character",
9599
9889
  " ",
9600
9890
  ";",
9601
9891
  "set-option",
9602
- "-s",
9892
+ "-sq",
9603
9893
  "set-clipboard",
9604
9894
  "on",
9605
9895
  ";",
9606
9896
  "set-option",
9607
- "-g",
9897
+ "-gq",
9608
9898
  "focus-events",
9609
9899
  "on",
9610
9900
  ";",
9611
9901
  "set-option",
9612
- "-s",
9902
+ "-sq",
9613
9903
  "extended-keys",
9614
9904
  "on",
9615
9905
  ";",
9616
9906
  "set-option",
9617
- "-s",
9907
+ "-sq",
9618
9908
  "extended-keys-format",
9619
9909
  "csi-u",
9620
9910
  ";",
9621
9911
  "set-option",
9622
- "-s",
9912
+ "-sq",
9623
9913
  "terminal-features[100]",
9624
9914
  "*:hyperlinks",
9625
9915
  ";",
9626
9916
  "set-option",
9627
- "-s",
9917
+ "-sq",
9628
9918
  "terminal-features[101]",
9629
9919
  "*:clipboard",
9630
9920
  ";",
9631
9921
  "set-option",
9632
- "-s",
9922
+ "-sq",
9633
9923
  "terminal-features[102]",
9634
9924
  "*:sync:RGB",
9635
9925
  ";",
9636
9926
  "set-option",
9637
- "-s",
9927
+ "-sq",
9638
9928
  "terminal-features[103]",
9639
9929
  "*:sixel",
9640
9930
  ";",
@@ -9825,4 +10115,4 @@ function sleep(ms) {
9825
10115
  return new Promise((resolve) => setTimeout(resolve, ms));
9826
10116
  }
9827
10117
  //#endregion
9828
- export { publish as $, noteBackground as A, agentLabel$1 as At, agentLabel as B, run$1 as Bt, readHookPayload as C, miseVersions as Ct, clearAgentPhase as D, PROJECT_TOOLS as Dt, agentPhase as E, DEFAULT_GITHUB_HOST as Et, setSessionViewers as F, get as Ft, manifest as G, readBody as Gt, ACCENT_RE as H, config as Ht, settleQuietWorking as I, workspacePath as It, deleteSubscription as J, normalizeAccent as K, agentBadge as L, TMUX_SOCKET as Lt, onPhaseChange as M, applyPrefChange as Mt, setAgentPhase as N, all as Nt, hookPhase as O, TOOLS as Ot, setScrapedPhase as P, db as Pt, validSubscription as Q, agentFamily as R, gh as Rt, AGENTS as S, miseInstalls as St, blankRow as T, which as Tt, getInstance as U, checked as Ut, agentMeta as V, tmux as Vt, iconSvg as W, httpError as Wt, saveSubscription as X, pushPublicKey as Y, sendPush as Z, renameSession as _, setPref as _t, ensureTmuxServer as a, withLock as at, tmuxName as b, doctor as bt, killSession as c, agentChoices as ct, listPanesWithin as d, deleteWorkspacePrefs as dt, publishJson as et, listSessions as f, disabledAgents as ft, panePids as g, setDisabledAgents as gt, notifySessionsChanged as h, preferredAgent as ht, disposeSessions as i, swr as it, noteUserAnswered as j, toolById as jt, hookReportedAt as k, agentById as kt, killWorkspaceSessions as l, allPrefs as lt, newSessionArgs as m, getSetting as mt, clearTmuxStarted as n, subscriberCount as nt, forgetPanes as o, PREF_MAX as ot, markTmuxStarted as p, enabledAgents as pt, setInstance as q, createSession as r, shared as rt, getSession as s, WORKSPACE_PREFS as st, cleanEnv as t, subscribe as tt, listPanes as u, changePref as ut, sendToSession as v, setSetting as vt, reportsWorking as w, setupPath as wt, tmuxWasStarted as x, ghKnownHosts as xt, sessionStates as y, discoverAgents as yt, agentFromCommand as z, git as zt };
10118
+ export { saveSubscription as $, swr as $t, clearAgentPhase as A, TOOLS as At, agentBadge as B, readBody as Bt, readHookPayload as C, miseVersions as Ct, realInsideSync as D, which as Dt, realInside as E, tilde as Et, onPhaseChange as F, applyPrefChange as Ft, ACCENT_RE as G, TMUX_SOCKET as Gt, agentFromCommand as H, db as Ht, setAgentPhase as I, FRAME_ANCESTORS as It, manifest as J, gitEnv as Jt, getInstance as K, gh as Kt, setScrapedPhase as L, FRAME_HEADERS as Lt, hookReportedAt as M, agentLabel$1 as Mt, noteBackground as N, catalogPin as Nt, blankRow as O, DEFAULT_GITHUB_HOST as Ot, noteUserAnswered as P, toolById as Pt, pushPublicKey as Q, shared as Qt, setSessionViewers as R, checked as Rt, AGENTS as S, miseInstalls as St, inside as T, stableGh as Tt, agentLabel as U, get as Ut, agentFamily as V, all as Vt, agentMeta as W, workspacePath as Wt, setInstance as X, tmux as Xt, normalizeAccent as Y, run$1 as Yt, deleteSubscription as Z, config as Zt, renameSession as _, setPref as _t, ensureTmuxServer as a, subscriberCount as at, tmuxName as b, doctor as bt, killSession as c, agentChoices as ct, listPanesWithin as d, deleteWorkspacePrefs as dt, withLock as en, sendPush as et, listSessions as f, disabledAgents as ft, panePids as g, setDisabledAgents as gt, notifySessionsChanged as h, preferredAgent as ht, disposeSessions as i, subscribe as it, hookPhase as j, agentById as jt, agentPhase as k, PROJECT_TOOLS as kt, killWorkspaceSessions as l, allPrefs as lt, newSessionArgs as m, getSetting as mt, clearTmuxStarted as n, publish as nt, forgetPanes as o, PREF_MAX as ot, markTmuxStarted as p, enabledAgents as pt, iconSvg as q, git as qt, createSession as r, publishJson as rt, getSession as s, WORKSPACE_PREFS as st, cleanEnv as t, validSubscription as tt, listPanes as u, changePref as ut, sendToSession as v, setSetting as vt, reportsWorking as w, setupPath as wt, tmuxWasStarted as x, ghKnownHosts as xt, sessionStates as y, discoverAgents as yt, settleQuietWorking as z, httpError as zt };