@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,824 +0,0 @@
1
- #!/usr/bin/env node
2
- // migrate.mjs — one-shot cleanups for changes between versions, run by
3
- // `work setup` and `work migrate` (update.sh) so the runtime stays free of
4
- // legacy handling.
5
- import crypto from "node:crypto";
6
- import { execFileSync } from "node:child_process";
7
- import fs from "node:fs";
8
- import os from "node:os";
9
- import path from "node:path";
10
- import { DatabaseSync } from "node:sqlite";
11
- import { dialHost } from "../lib/setup/listen.mjs";
12
-
13
- const dataDir =
14
- process.env.WORK_DATA_DIR ||
15
- path.join(
16
- process.env.XDG_DATA_HOME || path.join(os.homedir(), ".local", "share"),
17
- "work",
18
- );
19
- const dbPath = path.join(dataDir, "work.db");
20
-
21
- // Machine repairs that need no db come first: a fresh install, or one whose
22
- // data dir this environment does not name, stops at the check below.
23
-
24
- // `gh auth setup-git` bakes the absolute path of the gh binary into
25
- // ~/.gitconfig, and git runs that string literally rather than looking gh up
26
- // on PATH. Where gh came from a version manager that path dies on the next gh
27
- // upgrade, and every https push fails with "could not read Username" — a
28
- // break with no visible cause, since `gh` itself still works. Repoint any
29
- // helper naming a gh that no longer exists at the launcher on PATH.
30
- {
31
- const versioned = /\/(installs|Cellar|versions|toolchains)\//;
32
- const git = (args) => execFileSync("git", args, { encoding: "utf8" }).trim();
33
- try {
34
- let gh = "";
35
- try {
36
- // Quietly: with no gh there is nothing to repair, and this runs on
37
- // every setup, fresh installs included.
38
- gh = execFileSync("which", ["gh"], {
39
- encoding: "utf8",
40
- stdio: ["ignore", "pipe", "ignore"],
41
- }).trim();
42
- } catch {}
43
- if (gh && !versioned.test(gh)) {
44
- let lines = [];
45
- try {
46
- lines = git([
47
- "config",
48
- "--global",
49
- "--get-regexp",
50
- String.raw`^credential\..*\.helper$`,
51
- ])
52
- .split("\n")
53
- .filter(Boolean);
54
- } catch {} // no such entries — nothing to repair
55
- let fixed = 0;
56
- for (const line of lines) {
57
- const sp = line.indexOf(" ");
58
- const [key, value] = [line.slice(0, sp), line.slice(sp + 1)];
59
- const bin = /^!(\S+) auth git-credential$/.exec(value)?.[1];
60
- if (!bin || bin === gh || fs.existsSync(bin)) continue;
61
- git([
62
- "config",
63
- "--global",
64
- "--replace-all",
65
- key,
66
- `!${gh} auth git-credential`,
67
- "auth git-credential",
68
- ]);
69
- fixed++;
70
- }
71
- if (fixed)
72
- console.log(
73
- `==> migrate: repaired ${fixed} stale gh credential helper(s)`,
74
- );
75
- }
76
- } catch {}
77
- }
78
-
79
- // Grok's hook registry ($GROK_HOME/hooks-paths) names work's hook file by
80
- // absolute path. A line left by a data dir since moved or removed (a
81
- // scratch server's temp dir, an uninstall) names nothing, and Grok's
82
- // sandbox refuses to start while one does. The app drops them as it
83
- // registers; this reaches machines that stopped launching Grok. Keep in
84
- // sync with registerHooks in src/agents/grok/index.ts.
85
- {
86
- try {
87
- const registry = path.join(
88
- process.env.GROK_HOME || path.join(os.homedir(), ".grok"),
89
- "hooks-paths",
90
- );
91
- const current = fs.readFileSync(registry, "utf8");
92
- const lines = current.split("\n");
93
- const kept = lines.filter((line) => {
94
- const target = line.trim();
95
- return !target.endsWith("/grok-hooks.json") || fs.existsSync(target);
96
- });
97
- if (kept.length !== lines.length) {
98
- fs.writeFileSync(registry, kept.join("\n"));
99
- console.log(
100
- `==> migrate: dropped ${lines.length - kept.length} stale Grok hook registry line(s)`,
101
- );
102
- }
103
- } catch {} // no registry — nothing to clean
104
- }
105
-
106
- if (!fs.existsSync(dbPath)) process.exit(0);
107
- const db = new DatabaseSync(dbPath, { readOnly: true });
108
-
109
- /** A write connection that waits out the running server's transactions, as
110
- * db.ts does: setup and update.sh migrate while the old server still runs,
111
- * and a lock thrown here would end the script before every later sweep. */
112
- function writer() {
113
- const wr = new DatabaseSync(dbPath);
114
- wr.exec("PRAGMA busy_timeout = 5000");
115
- return wr;
116
- }
117
-
118
- // Pre-scrape versions wrote agent hook files into every workspace
119
- // (identified by their agent-state callback); state now comes from
120
- // terminal scraping and launch flags, so sweep them out.
121
- const LEGACY_HOOK_FILES = [
122
- ".claude/settings.json",
123
- ".codex/hooks.json",
124
- ".cursor/hooks.json",
125
- ".cursor/hooks/work-working.sh",
126
- ".cursor/hooks/work-done.sh",
127
- ".github/hooks/work-agent-state.json",
128
- ];
129
-
130
- let removed = 0;
131
- for (const { path: wsPath } of db
132
- .prepare("SELECT path FROM workspaces")
133
- .all()) {
134
- for (const rel of LEGACY_HOOK_FILES) {
135
- const file = path.join(wsPath, rel);
136
- try {
137
- const text = fs.readFileSync(file, "utf8");
138
- if (
139
- !text.includes("/api/agent-state") &&
140
- !text.includes(".cursor/hooks/work-")
141
- ) {
142
- continue;
143
- }
144
- fs.rmSync(file);
145
- removed++;
146
- // Prune now-empty dirs the old version created.
147
- for (
148
- let dir = path.dirname(file);
149
- dir !== wsPath && !fs.readdirSync(dir).length;
150
- dir = path.dirname(dir)
151
- ) {
152
- fs.rmdirSync(dir);
153
- }
154
- } catch {}
155
- }
156
- }
157
- if (removed) console.log(`==> migrate: removed ${removed} legacy hook file(s)`);
158
-
159
- // A workspace's AGENTS.md is only rewritten when its repos change, so
160
- // existing ones never learn that the stash is shared between worktrees of
161
- // the same bare cache. Splice the bullet in ahead of the push one (keep in
162
- // sync with writeAgentsMd in src/server/workspaces.ts).
163
- const STASH_BULLET =
164
- "- **No `git stash`:** every workspace using a repo shares one stash stack, so\n" +
165
- " a pop can take another workspace's work. Commit WIP to your branch instead.\n";
166
- let noted = 0;
167
- for (const { path: wsPath } of db
168
- .prepare("SELECT path FROM workspaces")
169
- .all()) {
170
- const file = path.join(wsPath, "AGENTS.md");
171
- try {
172
- const text = fs.readFileSync(file, "utf8");
173
- const at = text.indexOf("- **Push:**");
174
- if (at < 0 || text.includes("git stash")) continue;
175
- fs.writeFileSync(file, text.slice(0, at) + STASH_BULLET + text.slice(at));
176
- noted++;
177
- } catch {}
178
- }
179
- if (noted)
180
- console.log(`==> migrate: noted the shared stash in ${noted} AGENTS.md`);
181
-
182
- // The review is commit-to-commit by default; fold that into the stash
183
- // bullet rather than appending another one. Keep in sync with writeAgentsMd.
184
- const OLD_STASH_END = "Commit WIP to your branch instead.";
185
- const NEW_STASH_END =
186
- "Commit as you go — uncommitted work isn't part of the review.";
187
- let restated = 0;
188
- for (const { path: wsPath } of db
189
- .prepare("SELECT path FROM workspaces")
190
- .all()) {
191
- const file = path.join(wsPath, "AGENTS.md");
192
- try {
193
- const text = fs.readFileSync(file, "utf8");
194
- if (!text.includes(OLD_STASH_END)) continue;
195
- fs.writeFileSync(file, text.replace(OLD_STASH_END, NEW_STASH_END));
196
- restated++;
197
- } catch {}
198
- }
199
- if (restated)
200
- console.log(
201
- `==> migrate: restated the stash bullet in ${restated} AGENTS.md`,
202
- );
203
-
204
- // Same rewrite-on-create-only problem: existing AGENTS.md never learn to
205
- // rebase after a squash-merge. Keep in sync with writeAgentsMd.
206
- const REBASE_BULLET =
207
- "- **Rebase after merge:** when `origin/<base>` (or a stacked parent) moves,\n" +
208
- " rebase onto it. A squash-merge does not move the fork point, so the review\n" +
209
- " keeps showing landed work until you do.\n";
210
- let rebased = 0;
211
- for (const { path: wsPath } of db
212
- .prepare("SELECT path FROM workspaces")
213
- .all()) {
214
- const file = path.join(wsPath, "AGENTS.md");
215
- try {
216
- const text = fs.readFileSync(file, "utf8");
217
- const at = text.indexOf("- **PRs:**");
218
- if (at < 0 || text.includes("Rebase after merge")) continue;
219
- fs.writeFileSync(file, text.slice(0, at) + REBASE_BULLET + text.slice(at));
220
- rebased++;
221
- } catch {}
222
- }
223
- if (rebased)
224
- console.log(`==> migrate: noted rebase-after-merge in ${rebased} AGENTS.md`);
225
-
226
- // Branch rules: stay on the workspace branch; reset it after it lands;
227
- // topic lanes only when that branch must stay open. Replaces both the
228
- // original "cut a lane per PR" parallel text and the later "need more
229
- // than one? stack" wording. Keep in sync with writeAgentsMd.
230
- let restatedBranches = 0;
231
- for (const { path: wsPath } of db
232
- .prepare("SELECT path FROM workspaces")
233
- .all()) {
234
- const file = path.join(wsPath, "AGENTS.md");
235
- try {
236
- let text = fs.readFileSync(file, "utf8");
237
- const found = text.match(/Workspace branch: \*\*`([^`]+)`\*\*/);
238
- if (!found || text.includes("must stay unmerged")) continue;
239
- const branch = found[1];
240
- const branches =
241
- `- **Branches:** stay on \`${branch}\` and keep pushing it — one open PR, more\n` +
242
- ` commits. After it lands, \`git fetch\` and reset \`${branch}\` to\n` +
243
- ` \`origin/<base>\` so the next change reuses this branch. Do not cut a\n` +
244
- ` \`${branch}-<topic>\` just to start the next piece of work.\n` +
245
- ` A topic lane is only for when \`${branch}\` must stay unmerged (a larger\n` +
246
- ` change) and you need a second PR on top of it. Then push every repo's\n` +
247
- ` workspace branch first, cut from the parent —\n` +
248
- ` \`git switch -c ${branch}-<topic> origin/${branch}\` — and keep the prefix.\n` +
249
- ` Only two levels: never \`${branch}-a-b\`. Tooling finds PRs by that prefix,\n` +
250
- ` so a branch named anything else is invisible: never invent one.\n`;
251
- const rebase =
252
- `- **Rebase after merge:** when \`${branch}\` is still open and \`origin/<base>\`\n` +
253
- " moves, rebase onto it — a squash-merge does not move the fork point, so the\n" +
254
- " review keeps showing landed work until you do. On a topic lane, rebase onto\n" +
255
- ` \`${branch}\` when the parent moves; after the parent merges: \`git fetch\n` +
256
- " --prune`, rebase onto `origin/<base>`, and retarget (`gh pr edit --base\n" +
257
- " <base>`).\n";
258
- const prs =
259
- "- **PRs:** the description covers only what is in the diff — a few sentences on\n" +
260
- " what changed and why. No verification logs or file-by-file detail. A topic\n" +
261
- ` lane's PR is \`gh pr create --base ${branch}\` — GitHub will otherwise target\n` +
262
- " the repo default, and the local review will disagree with the files tab.\n";
263
- const next = text
264
- .replace(/- \*\*Branches:\*\*[\s\S]*?never invent one.\n/, branches)
265
- .replace(/- \*\*PRs:\*\*[\s\S]*?file-by-file detail\.\n/, prs);
266
- const withRebase = next.includes("- **Rebase after merge:**")
267
- ? next.replace(
268
- /- \*\*Rebase after merge:\*\*[\s\S]*?(?:until you do|<base>`\)\.)\n/,
269
- rebase,
270
- )
271
- : next;
272
- if (withRebase === text) continue;
273
- fs.writeFileSync(file, withRebase);
274
- restatedBranches++;
275
- } catch {}
276
- }
277
- if (restatedBranches) {
278
- console.log(
279
- `==> migrate: restated branch rules in ${restatedBranches} AGENTS.md`,
280
- );
281
- }
282
-
283
- // Topic lanes come in two kinds: stacked on the workspace branch, or
284
- // independent, cut from the base (a separate fix that lands on its own).
285
- // Existing AGENTS.md only describe stacked lanes, whose PR targets the
286
- // workspace branch. Keep in sync with writeAgentsMd.
287
- let twoLaneKinds = 0;
288
- for (const { path: wsPath } of db
289
- .prepare("SELECT path FROM workspaces")
290
- .all()) {
291
- const file = path.join(wsPath, "AGENTS.md");
292
- try {
293
- const text = fs.readFileSync(file, "utf8");
294
- const found = text.match(/Workspace branch: \*\*`([^`]+)`\*\*/);
295
- if (!found || text.includes("**Independent**")) continue;
296
- const branch = found[1];
297
- const lanes =
298
- " A topic lane is a second change beside it, and is one of two kinds.\n" +
299
- ` **Stacked**: it needs \`${branch}\`, which must stay unmerged (a larger\n` +
300
- " change). Push every repo's workspace branch first, then cut from it\n" +
301
- ` (\`git switch -c ${branch}-<topic> origin/${branch}\`).\n` +
302
- " **Independent**: it stands on its own and can land before or without\n" +
303
- ` \`${branch}\` (a separate fix found along the way). Cut from the base\n` +
304
- ` (\`git switch -c ${branch}-<topic> origin/<base>\`).\n` +
305
- " Keep the prefix either way: tooling finds branches by it and tells the\n" +
306
- " two kinds apart from their history, so a branch named anything else is\n" +
307
- ` invisible: never invent one. Only two levels: never \`${branch}-a-b\`.\n`;
308
- const rebaseLanes =
309
- "An independent lane\n" +
310
- " rebases onto `origin/<base>` the same way. A stacked lane rebases onto\n" +
311
- ` \`${branch}\` when the parent moves; after the parent merges: \`git fetch\n` +
312
- " --prune`, rebase onto `origin/<base>`, and retarget (`gh pr edit --base\n" +
313
- " <base>`).\n";
314
- const prLanes =
315
- "A stacked\n" +
316
- ` lane's PR is \`gh pr create --base ${branch}\`: GitHub would otherwise\n` +
317
- " target the repo default, and the local review would disagree with the\n" +
318
- " files tab. An independent lane's PR targets the base, GitHub's default.\n";
319
- const next = text
320
- // The lane sentences of the branch bullet, up to its last line.
321
- .replace(
322
- / A topic lane is only for when[\s\S]*?never invent one\.\n/,
323
- lanes,
324
- )
325
- .replace(
326
- /On a topic lane, rebase onto\n[\s\S]*?<base>`\)\.\n/,
327
- rebaseLanes,
328
- )
329
- .replace(
330
- /A topic\n lane's PR is `gh pr create --base [^`]+`[\s\S]*?files tab\.\n/,
331
- prLanes,
332
- );
333
- if (next === text) continue;
334
- fs.writeFileSync(file, next);
335
- twoLaneKinds++;
336
- } catch {}
337
- }
338
- if (twoLaneKinds) {
339
- console.log(
340
- `==> migrate: described independent lanes in ${twoLaneKinds} AGENTS.md`,
341
- );
342
- }
343
-
344
- // Default review base/algorithm changed (workspace branch vs origin/<base>,
345
- // containment empty-check, then commit-to-commit). Existing comments and
346
- // viewed flags are keyed only by path+line, so they would silently
347
- // re-anchor. Wipe once — this script runs on every update. db.ts sets the
348
- // flag on a db it creates, which has no such comments to wipe.
349
- {
350
- const wr = writer();
351
- try {
352
- const FLAG = "review-cleared-diff-v2";
353
- const seen = wr.prepare("SELECT 1 FROM settings WHERE key = ?").get(FLAG);
354
- if (!seen) {
355
- const comments = wr.prepare("DELETE FROM review_comments").run();
356
- const viewed = wr.prepare("DELETE FROM review_viewed").run();
357
- wr.prepare("INSERT INTO settings (key, value) VALUES (?, '1')").run(FLAG);
358
- if (comments.changes || viewed.changes) {
359
- console.log(
360
- `==> migrate: cleared ${comments.changes} review comment(s) and ${viewed.changes} viewed flag(s)`,
361
- );
362
- }
363
- }
364
- } finally {
365
- wr.close();
366
- }
367
- }
368
-
369
- // The review flagged what moved since the reviewer's last visit, from a
370
- // head per section kept in `review.seen:<ws>`. Viewed marks replace it
371
- // (review_marks, src/server/viewed.ts): each head becomes a visit to its
372
- // section's branch, which the server turns into per-file marks at that
373
- // head when it next shows the section (a PR's under `#<number>`, the
374
- // only name its section had). The working-tree hashes beside the heads
375
- // name no branch's change and go. So does the table of the flags the
376
- // sweep above cleared, which nothing reads.
377
- {
378
- const wr = writer();
379
- try {
380
- // Keep in sync with src/server/db.ts: the server running this update
381
- // may predate the table.
382
- wr.exec(`CREATE TABLE IF NOT EXISTS review_marks (
383
- workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
384
- worktree TEXT NOT NULL,
385
- branch TEXT NOT NULL,
386
- path TEXT NOT NULL,
387
- fingerprint TEXT NOT NULL,
388
- PRIMARY KEY (workspace_id, worktree, branch, path)
389
- )`);
390
- const insert = wr.prepare(
391
- "INSERT OR IGNORE INTO review_marks (workspace_id, worktree, branch, path, fingerprint) VALUES (?, ?, ?, '', ?)",
392
- );
393
- let visits = 0;
394
- for (const { key, value } of wr
395
- .prepare("SELECT key, value FROM settings WHERE key GLOB 'review.seen:*'")
396
- .all()) {
397
- const id = key.slice("review.seen:".length);
398
- const ws = wr
399
- .prepare("SELECT branch FROM workspaces WHERE id = ?")
400
- .get(id);
401
- let heads = {};
402
- try {
403
- heads = JSON.parse(value)?.heads ?? {};
404
- } catch {}
405
- for (const [section, head] of Object.entries(ws ? heads : {})) {
406
- // `worktree`, `worktree@topic` or `worktree#pr`.
407
- const m = /^([^@#]+)(?:@(.+)|#(\d+))?$/.exec(section);
408
- if (!m || typeof head !== "string" || !/^[0-9a-f]{40,64}$/.test(head))
409
- continue;
410
- const branch = m[2]
411
- ? `${ws.branch}-${m[2]}`
412
- : m[3]
413
- ? `#${m[3]}`
414
- : ws.branch;
415
- insert.run(id, m[1], branch, `seen:${head}`);
416
- visits++;
417
- }
418
- wr.prepare("DELETE FROM settings WHERE key = ?").run(key);
419
- }
420
- if (visits)
421
- console.log(
422
- `==> migrate: carried ${visits} review visit(s) over to Viewed marks`,
423
- );
424
- wr.exec("DROP TABLE IF EXISTS review_viewed");
425
- } finally {
426
- wr.close();
427
- }
428
- }
429
-
430
- // Backfill the push-signal hook into bare caches that predate it (new
431
- // caches get it from ensureBare — keep this script in sync with
432
- // src/server/repo-events.ts).
433
- const workRoot = process.env.WORK_ROOT || path.join(os.homedir(), "work");
434
- const gitHost = "github.com";
435
- const appPort = Number(process.env.WORK_APP_PORT || 7171);
436
- // Same token file the server uses (src/server/hook-token.ts) — hooks ride
437
- // the public port and the endpoint refuses pings without it. dataDir is
438
- // declared at the top of this script.
439
- const tokenFile = path.join(dataDir, "hook-token");
440
- let hookTokenValue = "";
441
- try {
442
- hookTokenValue = fs.readFileSync(tokenFile, "utf8").trim();
443
- } catch {}
444
- if (!hookTokenValue) {
445
- hookTokenValue = crypto.randomBytes(16).toString("hex");
446
- fs.mkdirSync(dataDir, { recursive: true });
447
- fs.writeFileSync(tokenFile, `${hookTokenValue}\n`, { mode: 0o600 });
448
- }
449
- const cacheHost = path.join(workRoot, ".cache", gitHost);
450
- let hooked = 0;
451
- try {
452
- for (const owner of fs.readdirSync(cacheHost)) {
453
- const ownerDir = path.join(cacheHost, owner);
454
- for (const repoDir of fs.readdirSync(ownerDir)) {
455
- if (!repoDir.endsWith(".git")) continue;
456
- const fullName = `${owner}/${repoDir.slice(0, -4)}`;
457
- const script =
458
- `#!/bin/sh\n` +
459
- `# installed by work: signals ref updates to the app server.\n` +
460
- `[ "$1" = "committed" ] || exit 0\n` +
461
- `refs=$(cat)\n` +
462
- `case "$refs" in *"refs/remotes/origin/"*) ;; *) exit 0 ;; esac\n` +
463
- `printf '%s\\n' "$refs" | curl -sf -m 2 -X POST --data-binary @- "http://${dialHost(process.env.WORK_LISTEN)}:${appPort}` +
464
- `/api/repo-pushed?repo=${encodeURIComponent(fullName)}&token=${hookTokenValue}" >/dev/null 2>&1 &\n` +
465
- `exit 0\n`;
466
- const file = path.join(
467
- ownerDir,
468
- repoDir,
469
- "hooks",
470
- "reference-transaction",
471
- );
472
- try {
473
- if (fs.readFileSync(file, "utf8") === script) continue;
474
- } catch {}
475
- try {
476
- fs.mkdirSync(path.dirname(file), { recursive: true });
477
- fs.writeFileSync(file, script, { mode: 0o755 });
478
- hooked++;
479
- } catch {}
480
- }
481
- }
482
- } catch {}
483
- if (hooked)
484
- console.log(`==> migrate: installed push hook in ${hooked} cache repo(s)`);
485
-
486
- // Lane branches used to accumulate in the bare caches: nothing deleted one
487
- // when its PR finished, only removing the repo or the whole workspace did,
488
- // and a long-lived workspace here reached 66 of them against a single live
489
- // branch. The app now prunes a lane when its merged PR is dismissed (see
490
- // pruneLaneBranch in src/server/workspaces.ts), which only reaches lanes
491
- // finished from here on — so sweep the backlog once, with the same guards.
492
- // Best-effort: without gh, a token, or the network this does nothing.
493
- const laneWorkspaces = db
494
- .prepare("SELECT id, branch FROM workspaces")
495
- .all()
496
- .map((w) => ({ ...w, repos: [] }));
497
- for (const row of db
498
- .prepare("SELECT workspace_id, full_name FROM repos")
499
- .all()) {
500
- laneWorkspaces
501
- .find((w) => w.id === row.workspace_id)
502
- ?.repos.push(row.full_name);
503
- }
504
- const ownsRef = (ref, prefix) => ref === prefix || ref.startsWith(`${prefix}-`);
505
- const gitIn = (dir, args) =>
506
- execFileSync("git", ["-C", dir, ...args], {
507
- encoding: "utf8",
508
- stdio: ["ignore", "pipe", "ignore"],
509
- });
510
-
511
- // Candidate lanes: owned by a workspace branch, not the branch itself, not
512
- // claimed by another workspace whose branch extends this one's prefix, and
513
- // not checked out in a worktree.
514
- const candidates = [];
515
- for (const ws of laneWorkspaces) {
516
- const others = laneWorkspaces
517
- .filter((w) => w.id !== ws.id)
518
- .map((w) => w.branch);
519
- for (const fullName of ws.repos) {
520
- const bare = path.join(cacheHost, `${fullName}.git`);
521
- let refs, checkedOut;
522
- try {
523
- refs = gitIn(bare, [
524
- "for-each-ref",
525
- "--format=%(refname:short) %(objectname)",
526
- "refs/heads/",
527
- ])
528
- .split("\n")
529
- .filter(Boolean)
530
- .map((line) => line.split(" "));
531
- checkedOut = new Set(
532
- gitIn(bare, ["worktree", "list", "--porcelain"])
533
- .split("\n")
534
- .filter((l) => l.startsWith("branch refs/heads/"))
535
- .map((l) => l.slice("branch refs/heads/".length)),
536
- );
537
- } catch {
538
- continue;
539
- }
540
- for (const [lane, oid] of refs) {
541
- if (lane === ws.branch || !ownsRef(lane, ws.branch)) continue;
542
- if (others.some((b) => ownsRef(lane, b)) || checkedOut.has(lane))
543
- continue;
544
- candidates.push({ bare, fullName, lane, oid });
545
- }
546
- }
547
- }
548
-
549
- let pruned = 0;
550
- for (let i = 0; i < candidates.length; i += 40) {
551
- const chunk = candidates.slice(i, i + 40);
552
- // One aliased query per chunk rather than a request per lane.
553
- const query =
554
- "query {" +
555
- chunk
556
- .map(({ fullName, lane }, n) => {
557
- const [owner, name] = fullName.split("/");
558
- return (
559
- `l${n}: repository(owner: ${JSON.stringify(owner)}, name: ${JSON.stringify(name)}) {` +
560
- ` pullRequests(headRefName: ${JSON.stringify(lane)}, first: 5) {` +
561
- " nodes { state headRefOid } } }"
562
- );
563
- })
564
- .join(" ") +
565
- "}";
566
- let data;
567
- try {
568
- data = JSON.parse(
569
- execFileSync("gh", ["api", "graphql", "-f", `query=${query}`], {
570
- encoding: "utf8",
571
- stdio: ["ignore", "pipe", "ignore"],
572
- }),
573
- ).data;
574
- } catch {
575
- break;
576
- }
577
- chunk.forEach((c, n) => {
578
- const nodes = data?.[`l${n}`]?.pullRequests?.nodes;
579
- if (!nodes?.length || nodes.some((p) => p.state === "OPEN")) return;
580
- // The lane has to still be sitting on the finished PR's head: anything
581
- // further along is work that PR never carried, and deleting it here
582
- // would be the only copy.
583
- if (!nodes.some((p) => p.state !== "OPEN" && p.headRefOid === c.oid))
584
- return;
585
- try {
586
- gitIn(c.bare, ["branch", "-D", c.lane]);
587
- pruned++;
588
- } catch {}
589
- });
590
- }
591
- if (pruned)
592
- console.log(`==> migrate: pruned ${pruned} finished lane branch(es)`);
593
-
594
- // Caches made with `git clone --bare` (every cache before init+fetch in
595
- // ensureBare) copied each remote branch into refs/heads, so a cache carries
596
- // every branch anyone ever pushed as a local head of its own. Drop the
597
- // mirrors: a head that no worktree checks out, no workspace here owns,
598
- // and that still sits exactly on its origin counterpart — the last guard
599
- // keeps anything with local-only commits, whoever made it.
600
- const ownedPrefixes = db
601
- .prepare("SELECT branch FROM workspaces")
602
- .all()
603
- .map((w) => w.branch);
604
- let mirrors = 0;
605
- try {
606
- const cacheRoot = path.join(workRoot, ".cache");
607
- for (const host of fs.readdirSync(cacheRoot)) {
608
- const hostDir = path.join(cacheRoot, host);
609
- if (!fs.statSync(hostDir).isDirectory()) continue;
610
- for (const owner of fs.readdirSync(hostDir)) {
611
- const ownerDir = path.join(hostDir, owner);
612
- if (!fs.statSync(ownerDir).isDirectory()) continue;
613
- for (const repoDir of fs.readdirSync(ownerDir)) {
614
- if (!repoDir.endsWith(".git")) continue;
615
- const bare = path.join(ownerDir, repoDir);
616
- let heads, remotes, checkedOut;
617
- try {
618
- const refLines = (glob) =>
619
- gitIn(bare, [
620
- "for-each-ref",
621
- "--format=%(refname) %(objectname)",
622
- glob,
623
- ])
624
- .split("\n")
625
- .filter(Boolean)
626
- .map((l) => l.split(" "));
627
- heads = refLines("refs/heads/");
628
- remotes = new Map(
629
- refLines("refs/remotes/origin/").map(([ref, oid]) => [
630
- ref.slice("refs/remotes/origin/".length),
631
- oid,
632
- ]),
633
- );
634
- checkedOut = new Set(
635
- gitIn(bare, ["worktree", "list", "--porcelain"])
636
- .split("\n")
637
- .filter((l) => l.startsWith("branch refs/heads/"))
638
- .map((l) => l.slice("branch refs/heads/".length)),
639
- );
640
- } catch {
641
- continue;
642
- }
643
- for (const [ref, oid] of heads) {
644
- const name = ref.slice("refs/heads/".length);
645
- if (checkedOut.has(name)) continue;
646
- if (ownedPrefixes.some((b) => ownsRef(name, b))) continue;
647
- if (remotes.get(name) !== oid) continue;
648
- try {
649
- gitIn(bare, ["branch", "-D", name]);
650
- mirrors++;
651
- } catch {}
652
- }
653
- }
654
- }
655
- }
656
- } catch {}
657
- if (mirrors)
658
- console.log(`==> migrate: dropped ${mirrors} mirrored remote branch(es)`);
659
-
660
- // Existing AGENTS.md never learn about the `work` CLI read commands. Keep in
661
- // sync with writeAgentsMd.
662
- const WORK_CLI_BULLET =
663
- "- **Ask `work` for facts:** the `work` CLI answers from the same data as\n" +
664
- " the app: `work workspace` (this workspace: repos, base branches, open PRs,\n" +
665
- " sessions, running procs/ports), `work repos`, `work procs`,\n" +
666
- " `work workspaces`, `work doctor` (installed tools / agents / GitHub\n" +
667
- " sign-in), `work usage` (agent plan quotas). Add `--json` for machine\n" +
668
- " output. Prefer these over guessing from the filesystem or calling GitHub.\n";
669
- let cliNoted = 0;
670
- for (const { path: wsPath } of db
671
- .prepare("SELECT path FROM workspaces")
672
- .all()) {
673
- const file = path.join(wsPath, "AGENTS.md");
674
- try {
675
- const text = fs.readFileSync(file, "utf8");
676
- if (text.includes("Ask `work` for facts")) continue;
677
- fs.writeFileSync(file, text.trimEnd() + "\n" + WORK_CLI_BULLET);
678
- cliNoted++;
679
- } catch {}
680
- }
681
- if (cliNoted)
682
- console.log(`==> migrate: pointed ${cliNoted} AGENTS.md at the work CLI`);
683
-
684
- // Existing AGENTS.md never learn that a repo's own agents file is required
685
- // reading. Splice it in after the repo list (ahead of the stash bullet), so
686
- // it sits with the repos it is about. Keep in sync with writeAgentsMd.
687
- const REPO_AGENTS_BULLET =
688
- "- **Repo agents files:** you **MUST** read a repo's `AGENTS.md` (or\n" +
689
- " `CLAUDE.md`) before doing any work in it. It is not loaded for you.\n";
690
- let repoNoted = 0;
691
- for (const { path: wsPath } of db
692
- .prepare("SELECT path FROM workspaces")
693
- .all()) {
694
- const file = path.join(wsPath, "AGENTS.md");
695
- try {
696
- const text = fs.readFileSync(file, "utf8");
697
- const at = text.indexOf("- **No `git stash`:**");
698
- if (at < 0 || text.includes("**Repo agents files:**")) continue;
699
- fs.writeFileSync(
700
- file,
701
- text.slice(0, at) + REPO_AGENTS_BULLET + text.slice(at),
702
- );
703
- repoNoted++;
704
- } catch {}
705
- }
706
- if (repoNoted)
707
- console.log(
708
- `==> migrate: required repo agents files in ${repoNoted} AGENTS.md`,
709
- );
710
-
711
- // Per-workspace UI prefs were never swept on delete; they ride every SSR
712
- // document via allPrefs(). Prune orphans once — runtime delete handles new ones.
713
- {
714
- const wr = writer();
715
- try {
716
- const live = new Set(
717
- wr
718
- .prepare("SELECT id FROM workspaces")
719
- .all()
720
- .map((r) => r.id),
721
- );
722
- // Kept equal to WORKSPACE_PREFS in src/server/settings.ts, a .ts file
723
- // this plain script cannot import.
724
- const prefixes = [
725
- "tab",
726
- "diff-filter",
727
- "diff-folded",
728
- "diff-collapsed",
729
- "diff-focus",
730
- "diff-pos",
731
- "files-recent",
732
- ].map((name) => `ui.${name}:`);
733
- let pruned = 0;
734
- for (const prefix of prefixes) {
735
- for (const { key } of wr
736
- .prepare("SELECT key FROM settings WHERE key GLOB ?")
737
- .all(prefix + "*")) {
738
- if (live.has(key.slice(prefix.length))) continue;
739
- wr.prepare("DELETE FROM settings WHERE key = ?").run(key);
740
- pruned++;
741
- }
742
- }
743
- if (pruned)
744
- console.log(`==> migrate: pruned ${pruned} orphaned ui pref(s)`);
745
- } finally {
746
- wr.close();
747
- }
748
- }
749
-
750
- // The review's two-way toggle (`ui.diff-uncommitted`) became the three-way
751
- // `diff-scope` pref, and nothing reads the old row: drop it, since it rides
752
- // every SSR prefs payload. Not folded into the scope: that would switch
753
- // long-time users to uncommitted changes without their asking.
754
- {
755
- const wr = writer();
756
- try {
757
- const dropped = wr
758
- .prepare(
759
- "DELETE FROM settings WHERE key IN ('ui.diff-uncommitted', 'diff-uncommitted')",
760
- )
761
- .run();
762
- if (dropped.changes)
763
- console.log("==> migrate: dropped the old diff-uncommitted pref");
764
- } finally {
765
- wr.close();
766
- }
767
- }
768
-
769
- // The terminal's two text sizes were one JSON pref (`term-font`), which a
770
- // device rewrote whole from a stale copy when it set its own size. Split
771
- // it into the per-device prefs once (keep in sync with termFontPref in
772
- // src/client/prefs.ts).
773
- {
774
- const wr = writer();
775
- try {
776
- const legacy = wr
777
- .prepare("SELECT value FROM settings WHERE key = 'ui.term-font'")
778
- .get();
779
- if (legacy) {
780
- let sizes = {};
781
- try {
782
- sizes = JSON.parse(legacy.value) ?? {};
783
- } catch {}
784
- for (const [field, key] of [
785
- ["desktop", "ui.term-font-desktop"],
786
- ["touch", "ui.term-font-touch"],
787
- ]) {
788
- if (!Number.isInteger(sizes[field])) continue;
789
- wr.prepare(
790
- "INSERT OR IGNORE INTO settings (key, value) VALUES (?, ?)",
791
- ).run(key, String(sizes[field]));
792
- }
793
- wr.prepare("DELETE FROM settings WHERE key = 'ui.term-font'").run();
794
- console.log("==> migrate: split term-font into per-device prefs");
795
- }
796
- } finally {
797
- wr.close();
798
- }
799
- }
800
-
801
- // The phone pad's pref was once a bare list of the keys after the pad's
802
- // own nine. It is `{ base, extra }` now, and a change to one key
803
- // (src/client/pref-change.ts) finds no `extra` in a list, so it would
804
- // start the pad afresh. Wrap such a list once.
805
- {
806
- const wr = writer();
807
- try {
808
- const row = wr
809
- .prepare("SELECT value FROM settings WHERE key = 'ui.phone-keys'")
810
- .get();
811
- let keys;
812
- try {
813
- keys = row && JSON.parse(row.value);
814
- } catch {}
815
- if (Array.isArray(keys)) {
816
- wr.prepare(
817
- "UPDATE settings SET value = ? WHERE key = 'ui.phone-keys'",
818
- ).run(JSON.stringify({ base: [], extra: keys }));
819
- console.log("==> migrate: moved the phone pad's keys into its new shape");
820
- }
821
- } finally {
822
- wr.close();
823
- }
824
- }