@dylanpiercey/work 0.2.17 → 0.2.19

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 (517) hide show
  1. package/README.md +16 -0
  2. package/bin/cli/README.md +34 -0
  3. package/bin/cli/_progress.mjs +68 -0
  4. package/bin/cli/_repo.mjs +32 -0
  5. package/bin/cli/_target.mjs +49 -0
  6. package/bin/cli/agent.mjs +153 -0
  7. package/bin/cli/branches.mjs +79 -0
  8. package/bin/cli/config.mjs +175 -0
  9. package/bin/cli/host.mjs +142 -0
  10. package/bin/cli/lsp.mjs +117 -0
  11. package/bin/cli/notify.mjs +53 -0
  12. package/bin/cli/open.mjs +37 -0
  13. package/bin/cli/repo.mjs +98 -0
  14. package/bin/cli/session.mjs +296 -0
  15. package/bin/cli/skill.mjs +99 -0
  16. package/bin/cli/stack.mjs +51 -0
  17. package/bin/cli/status.mjs +86 -0
  18. package/bin/cli/topic.mjs +585 -0
  19. package/bin/cli/workspace.mjs +184 -0
  20. package/bin/work.mjs +411 -80
  21. package/dist/{_Bj-WwfnW.js → _CsokArOR.js} +183 -59
  22. package/dist/_L2HNAA_8.js +2 -0
  23. package/dist/__TCdgPY5.js +173 -0
  24. package/dist/index.mjs +3917 -2606
  25. package/dist/public/assets/{_C9jR1P3s.js → _-7Amnss4.js} +1 -1
  26. package/dist/public/assets/_-7Amnss4.js.br +0 -0
  27. package/dist/public/assets/_0XXNUttq.js +1 -0
  28. package/dist/public/assets/{_CIrZGxEf.js → _0sTkxfPx.js} +1 -1
  29. package/dist/public/assets/_0sTkxfPx.js.br +0 -0
  30. package/dist/public/assets/_0zzYbK0A.js +1 -0
  31. package/dist/public/assets/{_CJgqLdsx.js → _1M3oZPSf.js} +1 -1
  32. package/dist/public/assets/_1M3oZPSf.js.br +0 -0
  33. package/dist/public/assets/_2O5HnHht.js +1 -0
  34. package/dist/public/assets/_7WlUaJPH.js +1 -0
  35. package/dist/public/assets/_8Tr7ByPg.js +1 -0
  36. package/dist/public/assets/_9AXMmQSO.js +1 -0
  37. package/dist/public/assets/_B1VqbV-X.js +1 -0
  38. package/dist/public/assets/{_BxS3xvmE.js → _B9I2AEux.js} +1 -1
  39. package/dist/public/assets/_B9I2AEux.js.br +0 -0
  40. package/dist/public/assets/{_DO_4_u2Q.js → _B9qGqvit.js} +1 -1
  41. package/dist/public/assets/{_CIWiehYG.js → _B9xuaMHt.js} +1 -1
  42. package/dist/public/assets/_B9xuaMHt.js.br +0 -0
  43. package/dist/public/assets/{_BqWlTTxo.js → _BAWjkhA8.js} +1 -1
  44. package/dist/public/assets/_BAWjkhA8.js.br +0 -0
  45. package/dist/public/assets/{_CNUs2Gqk.js → _BBCzcNZY.js} +1 -1
  46. package/dist/public/assets/_BBCzcNZY.js.br +0 -0
  47. package/dist/public/assets/_BBW2szHh.js +1 -0
  48. package/dist/public/assets/_BCP2Njnu.js +1 -0
  49. package/dist/public/assets/{_A-jpjc8j.js → _BClUYs-k.js} +1 -1
  50. package/dist/public/assets/_BClUYs-k.js.br +0 -0
  51. package/dist/public/assets/{_B5JxE4Sx.js → _BDdZkZRc.js} +1 -1
  52. package/dist/public/assets/_BDdZkZRc.js.br +0 -0
  53. package/dist/public/assets/_BEDmGSgS.js +1 -0
  54. package/dist/public/assets/_BEDmGSgS.js.br +0 -0
  55. package/dist/public/assets/_BH9BIky6.js +1 -0
  56. package/dist/public/assets/_BH9BIky6.js.br +0 -0
  57. package/dist/public/assets/_BLdi8Ee5.js +1 -0
  58. package/dist/public/assets/{_C449plW0.js → _BPDSQUbl.js} +1 -1
  59. package/dist/public/assets/_BPDSQUbl.js.br +0 -0
  60. package/dist/public/assets/{_B19mS3yM.js → _BQW1kIop.js} +1 -1
  61. package/dist/public/assets/_BQW1kIop.js.br +0 -0
  62. package/dist/public/assets/_BQeoUfFw.js +1 -0
  63. package/dist/public/assets/_BRzroLbh.js +1 -0
  64. package/dist/public/assets/_BSXsTYSe.js +1 -0
  65. package/dist/public/assets/_BTXDT3Na.js +1 -0
  66. package/dist/public/assets/_BXm4xeFI.js +1 -0
  67. package/dist/public/assets/_BY8UeogK.js +1 -0
  68. package/dist/public/assets/_BYpyhp64.js +1 -0
  69. package/dist/public/assets/_BYpyhp64.js.br +0 -0
  70. package/dist/public/assets/_B_Kz7LnY.js +1 -0
  71. package/dist/public/assets/{_DqGOYRpi.js → _Bcc0Xs64.js} +1 -1
  72. package/dist/public/assets/_Bcc0Xs64.js.br +0 -0
  73. package/dist/public/assets/{_Do6b-nfX.js → _BdSsUhCi.js} +1 -1
  74. package/dist/public/assets/_BdSsUhCi.js.br +0 -0
  75. package/dist/public/assets/_BdaWssEH.js +1 -0
  76. package/dist/public/assets/{_BHyWcuOR.js → _BhecGD7y.js} +1 -1
  77. package/dist/public/assets/_BhecGD7y.js.br +0 -0
  78. package/dist/public/assets/_Bj9dpPhN.js +1 -0
  79. package/dist/public/assets/{_DorQTaAa.js → _BjZqS7za.js} +1 -1
  80. package/dist/public/assets/_BjZqS7za.js.br +0 -0
  81. package/dist/public/assets/_BkSUiyHK.js +1 -0
  82. package/dist/public/assets/_BlshXH2Y.js +16 -0
  83. package/dist/public/assets/_BlshXH2Y.js.br +0 -0
  84. package/dist/public/assets/_BmX-VP7w.js +1 -0
  85. package/dist/public/assets/{_v3HPnNBs.js → _BmpOmFbo.js} +1 -1
  86. package/dist/public/assets/_BmpOmFbo.js.br +0 -0
  87. package/dist/public/assets/_Bo6YntUl.js +1 -0
  88. package/dist/public/assets/_BprZx4vg.js +2 -0
  89. package/dist/public/assets/_BprZx4vg.js.br +0 -0
  90. package/dist/public/assets/_Bqm7OnIV.js +1 -0
  91. package/dist/public/assets/_BquBGUNK.js +1 -0
  92. package/dist/public/assets/_BquBGUNK.js.br +0 -0
  93. package/dist/public/assets/_BrB66aRZ.js +1 -0
  94. package/dist/public/assets/{_BA-MNdjL.js → _Bt03HU8S.js} +1 -1
  95. package/dist/public/assets/{_BTWfPOi-.js → _BtedGrGs.js} +1 -1
  96. package/dist/public/assets/_BtedGrGs.js.br +0 -0
  97. package/dist/public/assets/{_DUdEYxV0.js → _C-BYkx5h.js} +1 -1
  98. package/dist/public/assets/_C-BYkx5h.js.br +0 -0
  99. package/dist/public/assets/{_BUW_V5kN.js → _C-DhXiEm.js} +1 -1
  100. package/dist/public/assets/_C-DhXiEm.js.br +0 -0
  101. package/dist/public/assets/_C-NBFnST.js +1 -0
  102. package/dist/public/assets/{_BoTzWlXR.js → _C1RigMYD.js} +1 -1
  103. package/dist/public/assets/_C1RigMYD.js.br +0 -0
  104. package/dist/public/assets/_C2vRS-ES.js +1 -0
  105. package/dist/public/assets/{_CrlNjDih.js → _C3fslTAD.js} +1 -1
  106. package/dist/public/assets/_C3fslTAD.js.br +0 -0
  107. package/dist/public/assets/{_BuMTHEPk.js → _C4EYjWGn.js} +1 -1
  108. package/dist/public/assets/_C4EYjWGn.js.br +0 -0
  109. package/dist/public/assets/{_yp48NYOW.js → _C6Yt6h_R.js} +1 -1
  110. package/dist/public/assets/_C6Yt6h_R.js.br +0 -0
  111. package/dist/public/assets/{_cyorvuL1.js → _C7Y4xApK.js} +1 -1
  112. package/dist/public/assets/_C7Y4xApK.js.br +0 -0
  113. package/dist/public/assets/{_D4CkNo0r.js → _CB52LkYt.js} +1 -1
  114. package/dist/public/assets/_CB52LkYt.js.br +0 -0
  115. package/dist/public/assets/{_CxgPm_xy.js → _CBEKHwUV.js} +1 -1
  116. package/dist/public/assets/_CBEKHwUV.js.br +0 -0
  117. package/dist/public/assets/_CBSLBYQF.js +1 -0
  118. package/dist/public/assets/_CBgzBB_k.js +1 -0
  119. package/dist/public/assets/_CBgzBB_k.js.br +0 -0
  120. package/dist/public/assets/{_CCONYsJT.js → _CCoTlnvb.js} +1 -1
  121. package/dist/public/assets/_CCoTlnvb.js.br +0 -0
  122. package/dist/public/assets/_CD26To-f.js +1 -0
  123. package/dist/public/assets/_CDyWgQ0v.js +6 -0
  124. package/dist/public/assets/_CDyWgQ0v.js.br +0 -0
  125. package/dist/public/assets/{_vX9d6g5Y.js → _CEC5O89D.js} +1 -1
  126. package/dist/public/assets/_CEC5O89D.js.br +0 -0
  127. package/dist/public/assets/_CF2kEAU7.js +1 -0
  128. package/dist/public/assets/_CFURqbmO.js +1 -0
  129. package/dist/public/assets/{_Cwtn28hL.js → _CG383oZY.js} +1 -1
  130. package/dist/public/assets/_CG383oZY.js.br +0 -0
  131. package/dist/public/assets/_CHNJosg3.js +1 -0
  132. package/dist/public/assets/{_Cc_GUPR4.js → _CHmEM8Sm.js} +1 -1
  133. package/dist/public/assets/_CHmEM8Sm.js.br +0 -0
  134. package/dist/public/assets/_CIfCdAzS.js +1 -0
  135. package/dist/public/assets/_CKyzH0fl.js +1 -0
  136. package/dist/public/assets/{_BCB8LQS3.js → _CL8DzBla.js} +1 -1
  137. package/dist/public/assets/_CL8DzBla.js.br +0 -0
  138. package/dist/public/assets/_CNYS94C5.js +1 -0
  139. package/dist/public/assets/_CNhypHJN.js +1 -0
  140. package/dist/public/assets/_CO-FkxlA.js +1 -0
  141. package/dist/public/assets/_COiGBSpO.js +1 -0
  142. package/dist/public/assets/_COvolvRQ.js +1 -0
  143. package/dist/public/assets/{_Di78jTI-.js → _CPaMvBMG.js} +1 -1
  144. package/dist/public/assets/_CPaMvBMG.js.br +0 -0
  145. package/dist/public/assets/{_C7bHTlG1.js → _CPj_VL66.js} +1 -1
  146. package/dist/public/assets/_CPj_VL66.js.br +0 -0
  147. package/dist/public/assets/_CQJC8Vx4.js +1 -0
  148. package/dist/public/assets/_CRHNlzBC.js +1 -0
  149. package/dist/public/assets/{_C1-Nli75.js → _CToqok6Q.js} +1 -1
  150. package/dist/public/assets/_CToqok6Q.js.br +0 -0
  151. package/dist/public/assets/_CUFKkl0B.js +1 -0
  152. package/dist/public/assets/_CZsOUa-q.js +1 -0
  153. package/dist/public/assets/{_D8uBvHXU.js → _C_D5TPb7.js} +1 -1
  154. package/dist/public/assets/_C_D5TPb7.js.br +0 -0
  155. package/dist/public/assets/_CdHI48v6.js +1 -0
  156. package/dist/public/assets/{_BfQeZPXW.js → _CdpmkkzR.js} +1 -1
  157. package/dist/public/assets/_CdpmkkzR.js.br +0 -0
  158. package/dist/public/assets/{_6klEiBhY.js → _CdtjIoUd.js} +1 -1
  159. package/dist/public/assets/_CdtjIoUd.js.br +0 -0
  160. package/dist/public/assets/_Ce9Tv01m.js +1 -0
  161. package/dist/public/assets/_CeC7Lv10.js +1 -0
  162. package/dist/public/assets/{_CYhJ6ae-.js → _CfP0f0PU.js} +1 -1
  163. package/dist/public/assets/_CfP0f0PU.js.br +0 -0
  164. package/dist/public/assets/_Cg7DH3xk.js +1 -0
  165. package/dist/public/assets/_Cg7DH3xk.js.br +0 -0
  166. package/dist/public/assets/_CikNq0z8.js +1 -0
  167. package/dist/public/assets/{_DK-MOyi_.js → _Cl7LTITm.js} +1 -1
  168. package/dist/public/assets/_Cl7LTITm.js.br +0 -0
  169. package/dist/public/assets/{_BT7DMail.js → _Cmtl59QM.js} +1 -1
  170. package/dist/public/assets/_Cmtl59QM.js.br +0 -0
  171. package/dist/public/assets/_CshYq_Dp.js +1 -0
  172. package/dist/public/assets/{_Dj5RDA5P.js → _CspPbDoP.js} +1 -1
  173. package/dist/public/assets/_CspPbDoP.js.br +0 -0
  174. package/dist/public/assets/{_Ca2DTddL.js → _Ctjz3BD9.js} +1 -1
  175. package/dist/public/assets/_Ctjz3BD9.js.br +0 -0
  176. package/dist/public/assets/{_C5c3o9N3.js → _CuglAToi.js} +1 -1
  177. package/dist/public/assets/_CuglAToi.js.br +0 -0
  178. package/dist/public/assets/_CwSoAVRN.js +1 -0
  179. package/dist/public/assets/_D0XQV-Hm.js +1 -0
  180. package/dist/public/assets/{_D_GeNCls.js → _D36PnqCD.js} +1 -1
  181. package/dist/public/assets/_D36PnqCD.js.br +0 -0
  182. package/dist/public/assets/{_DYqx8g78.js → _D3IviZbJ.js} +1 -1
  183. package/dist/public/assets/_D3IviZbJ.js.br +0 -0
  184. package/dist/public/assets/_D6rgUB9O.js +1 -0
  185. package/dist/public/assets/{_Dwe1TUjY.js → _D7qWWxdI.js} +1 -1
  186. package/dist/public/assets/_D7qWWxdI.js.br +0 -0
  187. package/dist/public/assets/{_CPbClwhX.js → _D8ac72_O.js} +1 -1
  188. package/dist/public/assets/_D8ac72_O.js.br +0 -0
  189. package/dist/public/assets/_D9WWxrQR.js +1 -0
  190. package/dist/public/assets/_D9hI5dSA.js +1 -0
  191. package/dist/public/assets/{_DzlXwaiG.js → _DCrPsldZ.js} +1 -1
  192. package/dist/public/assets/_DCrPsldZ.js.br +0 -0
  193. package/dist/public/assets/{_ChPy2IX4.js → _DDcVFyaQ.js} +1 -1
  194. package/dist/public/assets/_DDcVFyaQ.js.br +0 -0
  195. package/dist/public/assets/_DDhkKo8Q.js +1 -0
  196. package/dist/public/assets/{_CY_Z-kV5.js → _DJBR8Qwq.js} +1 -1
  197. package/dist/public/assets/_DJBR8Qwq.js.br +0 -0
  198. package/dist/public/assets/{_CxHuLHdz.js → _DLpa6VYT.js} +1 -1
  199. package/dist/public/assets/_DMqe6rR-.js +1 -0
  200. package/dist/public/assets/{_DbLQjG4R.js → _DN7pTn2g.js} +1 -1
  201. package/dist/public/assets/_DN7pTn2g.js.br +0 -0
  202. package/dist/public/assets/_DP8UuFuJ.js +1 -0
  203. package/dist/public/assets/_DQedUaqM.js +1 -0
  204. package/dist/public/assets/{_DPiemRX1.js → _DSCqWPO0.js} +1 -1
  205. package/dist/public/assets/_DSCqWPO0.js.br +0 -0
  206. package/dist/public/assets/{_BoEcMQmX.js → _DSeQngGR.js} +1 -1
  207. package/dist/public/assets/_DSeQngGR.js.br +0 -0
  208. package/dist/public/assets/{_D-0pUYXq.js → _DTNiWZFr.js} +1 -1
  209. package/dist/public/assets/_DTNiWZFr.js.br +0 -0
  210. package/dist/public/assets/_DThlusXY.js +1 -0
  211. package/dist/public/assets/_DUK16H19.js +1 -0
  212. package/dist/public/assets/_DUZ13t3U.js +1 -0
  213. package/dist/public/assets/{_BHgwN0LC.js → _DWb03VKf.js} +1 -1
  214. package/dist/public/assets/_DWb03VKf.js.br +0 -0
  215. package/dist/public/assets/_DWsyhfgn.js +1 -0
  216. package/dist/public/assets/_DXuzYhW6.js +1 -0
  217. package/dist/public/assets/_DXyOzA2b.js +1 -0
  218. package/dist/public/assets/{_BXcMBVCY.js → _DYUFCi44.js} +1 -1
  219. package/dist/public/assets/_DYUFCi44.js.br +0 -0
  220. package/dist/public/assets/{_BwSXxzqy.js → _DYhs8iJg.js} +12 -12
  221. package/dist/public/assets/_DYhs8iJg.js.br +0 -0
  222. package/dist/public/assets/{_Dhn3A3KJ.js → _D__ojGam.js} +1 -1
  223. package/dist/public/assets/_D__ojGam.js.br +0 -0
  224. package/dist/public/assets/_DaFI_W5D.js +1 -0
  225. package/dist/public/assets/{_BiY8chB-.js → _DbT6uo7W.js} +1 -1
  226. package/dist/public/assets/_DbT6uo7W.js.br +0 -0
  227. package/dist/public/assets/_DhnT0cCE.js +1 -0
  228. package/dist/public/assets/_Dm9OGn2q.js +1 -0
  229. package/dist/public/assets/_DmkeGFoM.js +1 -0
  230. package/dist/public/assets/{_DVLNzEkW.js → _DmoI4cIl.js} +1 -1
  231. package/dist/public/assets/_DmoI4cIl.js.br +0 -0
  232. package/dist/public/assets/{_zcAaK79d.js → _DpbHp8yR.js} +1 -1
  233. package/dist/public/assets/_DpbHp8yR.js.br +0 -0
  234. package/dist/public/assets/_Dqz_HBE1.js +1 -0
  235. package/dist/public/assets/{_DOKecL0e.js → _DsehEuMD.js} +1 -1
  236. package/dist/public/assets/_DsehEuMD.js.br +0 -0
  237. package/dist/public/assets/{_D-pUpBL1.js → _Dtx52FYB.js} +1 -1
  238. package/dist/public/assets/_DuEyirL6.js +1 -0
  239. package/dist/public/assets/_DuuloSIi.js +1 -0
  240. package/dist/public/assets/{_Ch-UiovX.js → _DuyCZnNC.js} +1 -1
  241. package/dist/public/assets/_DuyCZnNC.js.br +0 -0
  242. package/dist/public/assets/{_BQEpu56f.js → _Dw1P6xZJ.js} +1 -1
  243. package/dist/public/assets/_Dw1P6xZJ.js.br +0 -0
  244. package/dist/public/assets/{_C-lB_p3U.js → _DzNFlI0M.js} +1 -1
  245. package/dist/public/assets/_DzNFlI0M.js.br +0 -0
  246. package/dist/public/assets/{_CYQ4srZb.js → _EcMqP1xI.js} +1 -1
  247. package/dist/public/assets/_EcMqP1xI.js.br +0 -0
  248. package/dist/public/assets/{_0KruTMn9.js → _G1BLeMns.js} +1 -1
  249. package/dist/public/assets/_G1BLeMns.js.br +0 -0
  250. package/dist/public/assets/{_FwFz43m8.js → _G8KNSVdM.js} +1 -1
  251. package/dist/public/assets/_G8KNSVdM.js.br +0 -0
  252. package/dist/public/assets/{_3fvr5bU1.js → _J1v2clxU.js} +1 -1
  253. package/dist/public/assets/_J1v2clxU.js.br +0 -0
  254. package/dist/public/assets/{_Depr5Jps.js → _J3wdy6bJ.js} +1 -1
  255. package/dist/public/assets/_J3wdy6bJ.js.br +0 -0
  256. package/dist/public/assets/{_-ycNE92Z.js → _MHZgY1AQ.js} +1 -1
  257. package/dist/public/assets/_MHZgY1AQ.js.br +0 -0
  258. package/dist/public/assets/_NHTZitq1.js +2 -0
  259. package/dist/public/assets/_NHTZitq1.js.br +0 -0
  260. package/dist/public/assets/{_Cw-dmwPJ.js → _PsuNqRL9.js} +20 -20
  261. package/dist/public/assets/_PsuNqRL9.js.br +0 -0
  262. package/dist/public/assets/{_CXVkXsw1.js → _T5HFHZgl.js} +1 -1
  263. package/dist/public/assets/_T5HFHZgl.js.br +0 -0
  264. package/dist/public/assets/{_4_sKOYsy.js → _UZAFx6D8.js} +1 -1
  265. package/dist/public/assets/_UZAFx6D8.js.br +0 -0
  266. package/dist/public/assets/_XA8_RQXF.js +1 -0
  267. package/dist/public/assets/{_BTh4v5Tr.js → _XsB9KmcW.js} +1 -1
  268. package/dist/public/assets/_XsB9KmcW.js.br +0 -0
  269. package/dist/public/assets/{_i4iteLF8.js → _YoXk_8Bl.js} +1 -1
  270. package/dist/public/assets/_YoXk_8Bl.js.br +0 -0
  271. package/dist/public/assets/_YubCdy3Z.js +1 -0
  272. package/dist/public/assets/{_Q5s6o5H4.js → _bDI-pCZR.js} +1 -1
  273. package/dist/public/assets/_bDI-pCZR.js.br +0 -0
  274. package/dist/public/assets/{_TynjiShF.js → _bHL-NcWS.js} +1 -1
  275. package/dist/public/assets/_bHL-NcWS.js.br +0 -0
  276. package/dist/public/assets/_bqRzDYc8.js +1 -0
  277. package/dist/public/assets/{_OpbuiQ7h.js → _briyaWgK.js} +1 -1
  278. package/dist/public/assets/_briyaWgK.js.br +0 -0
  279. package/dist/public/assets/{_pEUCjhqm.js → _dVHSDgPC.js} +1 -1
  280. package/dist/public/assets/_dVHSDgPC.js.br +0 -0
  281. package/dist/public/assets/_gkZjZ9I4.js +1 -0
  282. package/dist/public/assets/_plyCYAnN.js +1 -0
  283. package/dist/public/assets/_q0Z44mWJ.js +1 -0
  284. package/dist/public/assets/_q0Z44mWJ.js.br +0 -0
  285. package/dist/public/assets/{_BPNSknLT.js → _qAsGEOt5.js} +1 -1
  286. package/dist/public/assets/_qAsGEOt5.js.br +0 -0
  287. package/dist/public/assets/{_Dks8YY2K.js → _qxffRpjc.js} +1 -1
  288. package/dist/public/assets/{_BOBYB-cj.js → _uCKs5N6Q.js} +1 -1
  289. package/dist/public/assets/_uCKs5N6Q.js.br +0 -0
  290. package/dist/public/assets/_utWnC80Q.js +1 -0
  291. package/dist/public/assets/_utvzcBHT.js +1 -0
  292. package/dist/public/assets/_v8WbCPI8.js +1 -0
  293. package/dist/public/assets/_yK4b_Bl5.js +1 -0
  294. package/dist/public/assets/_yoQW4BY5.js +1 -0
  295. package/dist/public/assets/_zB6USXHX.js +1 -0
  296. package/dist/public/assets/{_Quh6tl1u.js → _zN8SypHW.js} +1 -1
  297. package/dist/public/assets/_zN8SypHW.js.br +0 -0
  298. package/dist/public/assets/files-view-Fl0rU3Ns.js +2 -0
  299. package/dist/public/assets/manage-workspace-DggRcsXf.js +2 -0
  300. package/dist/public/assets/new-C7NxTJAT.js +1 -0
  301. package/dist/public/assets/new-workspace-C0pw5Iz1.js +2 -0
  302. package/dist/public/assets/review-view-C4YQ0J-X.js +2 -0
  303. package/dist/public/assets/settings-C7NxTJAT.js +1 -0
  304. package/dist/public/assets/settings-page-Cl_1tWCv.js +2 -0
  305. package/dist/public/assets/styles-Vcsj4CA7.css +1 -0
  306. package/dist/public/assets/styles-Vcsj4CA7.css.br +0 -0
  307. package/dist/public/assets/w-C7NxTJAT.js +1 -0
  308. package/dist/public/assets/w._-BbFH2lR-.js +1 -0
  309. package/dist/public/assets/w._-C7NxTJAT.js +1 -0
  310. package/dist/public/assets/w._-YIzLOiyZ.js +1 -0
  311. package/dist/public/sw.js +11 -4
  312. package/dist/public/sw.js.br +0 -0
  313. package/lib/ports/url.d.mts +20 -0
  314. package/lib/ports/url.mjs +80 -0
  315. package/lib/preview/media.d.mts +1 -1
  316. package/lib/preview/media.mjs +15 -2
  317. package/package.json +1 -1
  318. package/dist/_CLoLdV87.js +0 -2
  319. package/dist/_DPpY3UqO.js +0 -167
  320. package/dist/public/assets/_-ycNE92Z.js.br +0 -0
  321. package/dist/public/assets/_0KruTMn9.js.br +0 -0
  322. package/dist/public/assets/_0NH5yJMx.js +0 -1
  323. package/dist/public/assets/_1CAp-NbR.js +0 -1
  324. package/dist/public/assets/_3fvr5bU1.js.br +0 -0
  325. package/dist/public/assets/_4Dkmi0BI.js +0 -1
  326. package/dist/public/assets/_4_sKOYsy.js.br +0 -0
  327. package/dist/public/assets/_6klEiBhY.js.br +0 -0
  328. package/dist/public/assets/_7_64OpLh.js +0 -1
  329. package/dist/public/assets/_7p-zxUs0.js +0 -1
  330. package/dist/public/assets/_8RAv3gFP.js +0 -1
  331. package/dist/public/assets/_9PDxaMA9.js +0 -1
  332. package/dist/public/assets/_9PDxaMA9.js.br +0 -0
  333. package/dist/public/assets/_9mbDrbe7.js +0 -1
  334. package/dist/public/assets/_A-jpjc8j.js.br +0 -0
  335. package/dist/public/assets/_B0JwTeu6.js +0 -1
  336. package/dist/public/assets/_B19mS3yM.js.br +0 -0
  337. package/dist/public/assets/_B1Sfrnda.js +0 -1
  338. package/dist/public/assets/_B3i0wS_I.js +0 -1
  339. package/dist/public/assets/_B5JxE4Sx.js.br +0 -0
  340. package/dist/public/assets/_B9RLcC8I.js +0 -1
  341. package/dist/public/assets/_BCB8LQS3.js.br +0 -0
  342. package/dist/public/assets/_BE7UYyYb.js +0 -1
  343. package/dist/public/assets/_BHgwN0LC.js.br +0 -0
  344. package/dist/public/assets/_BHyWcuOR.js.br +0 -0
  345. package/dist/public/assets/_BIpUDgQH.js +0 -16
  346. package/dist/public/assets/_BIpUDgQH.js.br +0 -0
  347. package/dist/public/assets/_BMlgaRlM.js +0 -1
  348. package/dist/public/assets/_BOBYB-cj.js.br +0 -0
  349. package/dist/public/assets/_BPNSknLT.js.br +0 -0
  350. package/dist/public/assets/_BQEpu56f.js.br +0 -0
  351. package/dist/public/assets/_BT7DMail.js.br +0 -0
  352. package/dist/public/assets/_BTJHQNIz.js +0 -1
  353. package/dist/public/assets/_BTWfPOi-.js.br +0 -0
  354. package/dist/public/assets/_BTh4v5Tr.js.br +0 -0
  355. package/dist/public/assets/_BUW_V5kN.js.br +0 -0
  356. package/dist/public/assets/_BXcMBVCY.js.br +0 -0
  357. package/dist/public/assets/_B_MtJKnj.js +0 -1
  358. package/dist/public/assets/_Bay3D1io.js +0 -1
  359. package/dist/public/assets/_BfQeZPXW.js.br +0 -0
  360. package/dist/public/assets/_BgKjJWz_.js +0 -1
  361. package/dist/public/assets/_BiY8chB-.js.br +0 -0
  362. package/dist/public/assets/_Bk5THQZb.js +0 -1
  363. package/dist/public/assets/_BmeQRnXS.js +0 -1
  364. package/dist/public/assets/_BoEcMQmX.js.br +0 -0
  365. package/dist/public/assets/_BoTzWlXR.js.br +0 -0
  366. package/dist/public/assets/_BqWlTTxo.js.br +0 -0
  367. package/dist/public/assets/_BuMTHEPk.js.br +0 -0
  368. package/dist/public/assets/_BubhcEjq.js +0 -1
  369. package/dist/public/assets/_BwSXxzqy.js.br +0 -0
  370. package/dist/public/assets/_BxS3xvmE.js.br +0 -0
  371. package/dist/public/assets/_ByvA6zJz.js +0 -1
  372. package/dist/public/assets/_Bz2Sejcy.js +0 -1
  373. package/dist/public/assets/_C-lB_p3U.js.br +0 -0
  374. package/dist/public/assets/_C1-Nli75.js.br +0 -0
  375. package/dist/public/assets/_C3mw4T_r.js +0 -1
  376. package/dist/public/assets/_C449plW0.js.br +0 -0
  377. package/dist/public/assets/_C5c3o9N3.js.br +0 -0
  378. package/dist/public/assets/_C7bHTlG1.js.br +0 -0
  379. package/dist/public/assets/_C8mt6nRC.js +0 -1
  380. package/dist/public/assets/_C9jR1P3s.js.br +0 -0
  381. package/dist/public/assets/_CCONYsJT.js.br +0 -0
  382. package/dist/public/assets/_CCZAROAW.js +0 -1
  383. package/dist/public/assets/_CCZAROAW.js.br +0 -0
  384. package/dist/public/assets/_CG3s9pE5.js +0 -1
  385. package/dist/public/assets/_CIWiehYG.js.br +0 -0
  386. package/dist/public/assets/_CIrZGxEf.js.br +0 -0
  387. package/dist/public/assets/_CIurl9jC.js +0 -1
  388. package/dist/public/assets/_CJgqLdsx.js.br +0 -0
  389. package/dist/public/assets/_CMbVHIgP.js +0 -1
  390. package/dist/public/assets/_CNUs2Gqk.js.br +0 -0
  391. package/dist/public/assets/_CPbClwhX.js.br +0 -0
  392. package/dist/public/assets/_CQUlxerJ.js +0 -1
  393. package/dist/public/assets/_CTDYlYHi.js +0 -1
  394. package/dist/public/assets/_CXVkXsw1.js.br +0 -0
  395. package/dist/public/assets/_CY5EBxZ6.js +0 -1
  396. package/dist/public/assets/_CYQ4srZb.js.br +0 -0
  397. package/dist/public/assets/_CY_Z-kV5.js.br +0 -0
  398. package/dist/public/assets/_CYhJ6ae-.js.br +0 -0
  399. package/dist/public/assets/_CZbVK94d.js +0 -1
  400. package/dist/public/assets/_C_A97h_2.js +0 -1
  401. package/dist/public/assets/_C_A97h_2.js.br +0 -0
  402. package/dist/public/assets/_C_Y5Dwzy.js +0 -1
  403. package/dist/public/assets/_Ca2DTddL.js.br +0 -0
  404. package/dist/public/assets/_Cc2nu3_5.js +0 -1
  405. package/dist/public/assets/_Cc_GUPR4.js.br +0 -0
  406. package/dist/public/assets/_CgFUs0bE.js +0 -1
  407. package/dist/public/assets/_Ch-UiovX.js.br +0 -0
  408. package/dist/public/assets/_ChDp0-FJ.js +0 -1
  409. package/dist/public/assets/_ChPy2IX4.js.br +0 -0
  410. package/dist/public/assets/_Chsgo2e1.js +0 -1
  411. package/dist/public/assets/_CjECwrWB.js +0 -1
  412. package/dist/public/assets/_CmW74dH7.js +0 -1
  413. package/dist/public/assets/_CmhAUlqu.js +0 -1
  414. package/dist/public/assets/_CrlNjDih.js.br +0 -0
  415. package/dist/public/assets/_CvzTEaQq.js +0 -1
  416. package/dist/public/assets/_Cw-dmwPJ.js.br +0 -0
  417. package/dist/public/assets/_Cwtn28hL.js.br +0 -0
  418. package/dist/public/assets/_CxgPm_xy.js.br +0 -0
  419. package/dist/public/assets/_D-0pUYXq.js.br +0 -0
  420. package/dist/public/assets/_D-rV-z_T.js +0 -1
  421. package/dist/public/assets/_D4CkNo0r.js.br +0 -0
  422. package/dist/public/assets/_D4fP_viq.js +0 -1
  423. package/dist/public/assets/_D570Sd6p.js +0 -1
  424. package/dist/public/assets/_D6Gudpw8.js +0 -1
  425. package/dist/public/assets/_D8ZTP1ck.js +0 -1
  426. package/dist/public/assets/_D8uBvHXU.js.br +0 -0
  427. package/dist/public/assets/_D8xGEGlm.js +0 -1
  428. package/dist/public/assets/_D9GZHKow.js +0 -1
  429. package/dist/public/assets/_DE0eZjad.js +0 -1
  430. package/dist/public/assets/_DElIEG9n.js +0 -1
  431. package/dist/public/assets/_DF0n9xzn.js +0 -2
  432. package/dist/public/assets/_DF0n9xzn.js.br +0 -0
  433. package/dist/public/assets/_DFX_tXcw.js +0 -1
  434. package/dist/public/assets/_DJ2gfhU_.js +0 -1
  435. package/dist/public/assets/_DK-MOyi_.js.br +0 -0
  436. package/dist/public/assets/_DOKecL0e.js.br +0 -0
  437. package/dist/public/assets/_DPXXIOLX.js +0 -1
  438. package/dist/public/assets/_DPb3t58B.js +0 -1
  439. package/dist/public/assets/_DPiemRX1.js.br +0 -0
  440. package/dist/public/assets/_DPpbgqBC.js +0 -1
  441. package/dist/public/assets/_DRVSLjxA.js +0 -1
  442. package/dist/public/assets/_DTHWnu6M.js +0 -1
  443. package/dist/public/assets/_DUdEYxV0.js.br +0 -0
  444. package/dist/public/assets/_DVLNzEkW.js.br +0 -0
  445. package/dist/public/assets/_DWpx2Uof.js +0 -1
  446. package/dist/public/assets/_DXYEUAmC.js +0 -1
  447. package/dist/public/assets/_DYTVambU.js +0 -1
  448. package/dist/public/assets/_DYqx8g78.js.br +0 -0
  449. package/dist/public/assets/_DZanHI_X.js +0 -1
  450. package/dist/public/assets/_DZanHI_X.js.br +0 -0
  451. package/dist/public/assets/_D_GeNCls.js.br +0 -0
  452. package/dist/public/assets/_DbLQjG4R.js.br +0 -0
  453. package/dist/public/assets/_DbmusecK.js +0 -1
  454. package/dist/public/assets/_DbmusecK.js.br +0 -0
  455. package/dist/public/assets/_DemN-D5U.js +0 -1
  456. package/dist/public/assets/_Depr5Jps.js.br +0 -0
  457. package/dist/public/assets/_DhJfHI4f.js +0 -1
  458. package/dist/public/assets/_Dhn3A3KJ.js.br +0 -0
  459. package/dist/public/assets/_Di78jTI-.js.br +0 -0
  460. package/dist/public/assets/_DiBTtPlu.js +0 -1
  461. package/dist/public/assets/_Dj5RDA5P.js.br +0 -0
  462. package/dist/public/assets/_DkjKARSS.js +0 -1
  463. package/dist/public/assets/_Do6b-nfX.js.br +0 -0
  464. package/dist/public/assets/_DorQTaAa.js.br +0 -0
  465. package/dist/public/assets/_DpxVmwni.js +0 -1
  466. package/dist/public/assets/_DqGOYRpi.js.br +0 -0
  467. package/dist/public/assets/_DsbxQ1i8.js +0 -1
  468. package/dist/public/assets/_Dt_P7K1V.js +0 -6
  469. package/dist/public/assets/_Dt_P7K1V.js.br +0 -0
  470. package/dist/public/assets/_Dwe1TUjY.js.br +0 -0
  471. package/dist/public/assets/_DyROQKS8.js +0 -1
  472. package/dist/public/assets/_DzEUPsq0.js +0 -1
  473. package/dist/public/assets/_DzlXwaiG.js.br +0 -0
  474. package/dist/public/assets/_FwFz43m8.js.br +0 -0
  475. package/dist/public/assets/_OpbuiQ7h.js.br +0 -0
  476. package/dist/public/assets/_Q5s6o5H4.js.br +0 -0
  477. package/dist/public/assets/_Quh6tl1u.js.br +0 -0
  478. package/dist/public/assets/_Rh99sjDe.js +0 -1
  479. package/dist/public/assets/_SEE1XtID.js +0 -1
  480. package/dist/public/assets/_SZjr1kid.js +0 -1
  481. package/dist/public/assets/_T7rMqM5P.js +0 -1
  482. package/dist/public/assets/_TynjiShF.js.br +0 -0
  483. package/dist/public/assets/_UENAEFcY.js +0 -1
  484. package/dist/public/assets/_UwTOb1gP.js +0 -1
  485. package/dist/public/assets/_WrxtT1Ok.js +0 -1
  486. package/dist/public/assets/_WrxtT1Ok.js.br +0 -0
  487. package/dist/public/assets/_bcvRRCkB.js +0 -1
  488. package/dist/public/assets/_cyorvuL1.js.br +0 -0
  489. package/dist/public/assets/_gi--JOq8.js +0 -1
  490. package/dist/public/assets/_i4iteLF8.js.br +0 -0
  491. package/dist/public/assets/_i7vMugBN.js +0 -1
  492. package/dist/public/assets/_j7jPRUEQ.js +0 -2
  493. package/dist/public/assets/_j7jPRUEQ.js.br +0 -0
  494. package/dist/public/assets/_pEUCjhqm.js.br +0 -0
  495. package/dist/public/assets/_qkJuNTl-.js +0 -1
  496. package/dist/public/assets/_uuZJDLIV.js +0 -1
  497. package/dist/public/assets/_v3HPnNBs.js.br +0 -0
  498. package/dist/public/assets/_vX9d6g5Y.js.br +0 -0
  499. package/dist/public/assets/_vhysM7gk.js +0 -1
  500. package/dist/public/assets/_vjwPQHk_.js +0 -1
  501. package/dist/public/assets/_yp48NYOW.js.br +0 -0
  502. package/dist/public/assets/_zcAaK79d.js.br +0 -0
  503. package/dist/public/assets/_zwPrEKxN.js +0 -1
  504. package/dist/public/assets/_zwPrEKxN.js.br +0 -0
  505. package/dist/public/assets/files-view-CzRAql9-.js +0 -2
  506. package/dist/public/assets/manage-workspace-C-c1R4pP.js +0 -2
  507. package/dist/public/assets/new-DWfNwssk.js +0 -1
  508. package/dist/public/assets/new-workspace-B8XAfkIH.js +0 -2
  509. package/dist/public/assets/review-view-DivHZNBf.js +0 -2
  510. package/dist/public/assets/settings-DWfNwssk.js +0 -1
  511. package/dist/public/assets/settings-page-BN9Hj1ui.js +0 -2
  512. package/dist/public/assets/styles-NmwxQh5L.css +0 -1
  513. package/dist/public/assets/styles-NmwxQh5L.css.br +0 -0
  514. package/dist/public/assets/w-DWfNwssk.js +0 -1
  515. package/dist/public/assets/w._-C9dj1aZ0.js +0 -1
  516. package/dist/public/assets/w._-D7_D4HlM.js +0 -1
  517. package/dist/public/assets/w._-DWfNwssk.js +0 -1
package/README.md CHANGED
@@ -54,6 +54,22 @@ work-source prod # global @dylanpiercey/work again
54
54
  work-source # status
55
55
  ```
56
56
 
57
+ ### From the command line (and agents)
58
+
59
+ Everything the app's pages do has a `work` command too, so an agent — or a
60
+ script — can use and set up work from a terminal: `work help` lists them.
61
+ Inside a workspace, `work branches`, `work session`, `work topic`,
62
+ `work review`, `work notify` and `work open`; agents start and message each
63
+ other with `work session new|send|wait` — any vendor's, each in a tab of its
64
+ own the user watches, its last message as a turn ends coming back to the
65
+ one that asked as a prompt; to change things,
66
+ `work workspace create`, `work repo add`, `work config get|set` (checked
67
+ against what each setting takes; `work config schema` lists them),
68
+ `work agent|skill|lsp|host` and `work gh login`; `work status` sums the
69
+ machine up, and `work procs` prints each workspace port's link as the
70
+ user's browser would open it. Every command takes `--json` (JSON alone on
71
+ stdout) and never prompts under it or `--non-interactive`.
72
+
57
73
  ### Access
58
74
 
59
75
  work has no login of its own — it runs agents and terminals as you, so it
@@ -0,0 +1,34 @@
1
+ # bin/cli
2
+
3
+ `work` commands beyond the core ones in `bin/work.mjs`, one file each. A
4
+ file here (not starting with `_`) exports `commands`, and `work` finds it at
5
+ run time; `work help` lists it.
6
+
7
+ ```js
8
+ /** @type {import("./_types").Command[]} */
9
+ export const commands = [
10
+ {
11
+ // One word (`branches`), or a core command's word and a verb of its own
12
+ // (`workspace create`, which `work ws create` also reaches).
13
+ name: "branches",
14
+ aliases: [],
15
+ summary: "one line for `work help`",
16
+ help: "the whole text for `work help branches`",
17
+ async run(ctx) {
18
+ // ctx.positional — the words after the command's own name
19
+ // ctx.parse(["--agent"]) — positionals with those flags' values left out
20
+ // ctx.has("--fresh"), ctx.flag("--agent"), ctx.flags("--repo")
21
+ // ctx.json — --json was passed: print JSON alone (ctx.out does)
22
+ // ctx.api.get/post/put/patch/del(path, body) — the running server;
23
+ // a non-2xx answer or `{error}` dies with the server's reason
24
+ // ctx.resolveWorkspace(arg) — { ws, status }: the named one, else the
25
+ // session's (WORK_SESSION_ID), else the one holding the cwd
26
+ // ctx.out(data, (data) => print text), ctx.log, ctx.warn, ctx.die
27
+ },
28
+ },
29
+ ];
30
+ ```
31
+
32
+ Plain node, no dependencies: it ships in the npm package as it is. Under
33
+ `--json` stdout is the JSON alone (`ctx.log` and `ctx.warn` go to stderr);
34
+ a failure exits non-zero with its reason (`ctx.die`).
@@ -0,0 +1,68 @@
1
+ // Following a long request's progress lines from the terminal, as the
2
+ // app's own views follow them (src/client/progress.ts).
3
+
4
+ /** How often a lane's line said again further on (a clone's percentage)
5
+ * is printed: it moves every few hundred ms, and each is a line here. */
6
+ const REPLACE_EVERY_MS = 3000;
7
+
8
+ /** Run `request` (a long POST) while printing on stderr the progress lines
9
+ * the server tags with `op`, read from a cursor taken first so none is
10
+ * missed or replayed. `onLine` sees each line too (a sign-in's code).
11
+ * Polled rather than taken off the events socket: plain node has no
12
+ * WebSocket client to spare, and the app polls the same route itself
13
+ * where a proxy holds the socket back. */
14
+ export async function follow(ctx, op, request, onLine) {
15
+ const base = ctx.serverUrl();
16
+ const get = async (q) => {
17
+ try {
18
+ const res = await fetch(`${base}/api/progress${q}`, {
19
+ signal: AbortSignal.timeout(10_000),
20
+ });
21
+ return res.ok ? await res.json() : null;
22
+ } catch {
23
+ return null;
24
+ }
25
+ };
26
+ let last = (await get(""))?.seq ?? 0;
27
+ /** Each lane's last printed line and when: a line said again is printed
28
+ * only when it says something new, and not more often than the above. */
29
+ const said = new Map();
30
+ const take = async () => {
31
+ const r = await get(`?since=${last}&op=${encodeURIComponent(op)}`);
32
+ for (const e of r?.messages ?? []) {
33
+ if (e.seq <= last) continue;
34
+ last = e.seq;
35
+ if (e.done || !e.message) continue;
36
+ const lane = e.lane ?? "";
37
+ const prev = said.get(lane);
38
+ if (e.replace) {
39
+ // The line back as it began (a fetch done) says nothing new.
40
+ if (prev?.text === e.message) continue;
41
+ if (prev && Date.now() - prev.at < REPLACE_EVERY_MS) continue;
42
+ }
43
+ said.set(lane, { text: e.message, at: Date.now() });
44
+ process.stderr.write(` ${e.message}\n`);
45
+ onLine?.(e.message);
46
+ }
47
+ };
48
+ let settled = false;
49
+ const result = request().finally(() => {
50
+ settled = true;
51
+ });
52
+ const poll = (async () => {
53
+ while (!settled) {
54
+ await new Promise((r) => setTimeout(r, 800));
55
+ if (!settled) await take();
56
+ }
57
+ })();
58
+ const value = await result;
59
+ await poll;
60
+ // Lines that came between the last poll and the answer.
61
+ await take();
62
+ return value;
63
+ }
64
+
65
+ /** An id for one operation's progress lines (the server takes ≤ 40). */
66
+ export function opId() {
67
+ return `cli-${Math.random().toString(36).slice(2, 10)}`;
68
+ }
@@ -0,0 +1,32 @@
1
+ // A repo as a command line names it, the way the app's repo picker reads
2
+ // a pasted one (src/client/github.ts parseRepoUrl, mirrored here: plain
3
+ // node, no imports from src/).
4
+
5
+ const FULL_NAME = /^(?:[\w.-]+\/)?[\w.-]+\/[\w.-]+$/;
6
+
7
+ /** `owner/name`, `host/owner/name` or a clone URL (`https://host/o/n(.git)`,
8
+ * `ssh://git@host/o/n`, `git@host:o/n.git`) → `[host/]owner/name`, the
9
+ * host left out for github.com; null when it is none of those. */
10
+ export function repoName(text) {
11
+ const t = String(text || "").trim();
12
+ const m =
13
+ /^(?:https?|ssh):\/\/(?:[^@/\s]+@)?([a-z0-9.-]+)(?::\d+)?\/([\w.-]+)\/([\w.-]*?)(?:\.git)?\/?$/i.exec(
14
+ t,
15
+ ) || /^[\w.-]+@([a-z0-9.-]+):([\w.-]+)\/([\w.-]*?)(?:\.git)?$/i.exec(t);
16
+ if (m) {
17
+ const host = m[1].toLowerCase();
18
+ if (!host.includes(".") || !m[3]) return null;
19
+ const name = `${m[2]}/${m[3]}`;
20
+ return host === "github.com" ? name : `${host}/${name}`;
21
+ }
22
+ const bare = t.replace(/\.git$/, "").replace(/^github\.com\//i, "");
23
+ return FULL_NAME.test(bare) ? bare : null;
24
+ }
25
+
26
+ /** Whether `key` (as `--base <key>=…` names a repo) means `fullName`: the
27
+ * whole name, `owner/name`, or the name alone. */
28
+ export function namesRepo(key, fullName) {
29
+ const k = key.toLowerCase();
30
+ const f = fullName.toLowerCase();
31
+ return f === k || f.endsWith(`/${k}`);
32
+ }
@@ -0,0 +1,49 @@
1
+ // What `work open` and `work notify --link` name, as the link the user's
2
+ // page opens: an app page as it is, a web page as it is, or a path in the
3
+ // workspace as its Files page — resolved by the server as a terminal's
4
+ // printed path is (`/term-paths`: the session's directory, its checkout,
5
+ // the workspace, each repo; files and folders inside its checkouts and
6
+ // .share/ only).
7
+ import os from "node:os";
8
+ import path from "node:path";
9
+
10
+ /**
11
+ * @param {any} ctx a bin/cli context
12
+ * @param {{ id: string }} ws
13
+ * @param {string} raw `/w/…`, `http(s)://…`, or a path (`src/a.ts:12`,
14
+ * `.share/shots/`, an absolute one)
15
+ * @returns {Promise<{ link: string, label: string } | null>}
16
+ */
17
+ export async function resolveTarget(ctx, ws, raw) {
18
+ if (/^\/w\//.test(raw)) return { link: raw, label: raw };
19
+ if (/^https?:\/\//i.test(raw)) return { link: raw, label: raw };
20
+ // `name:42` is a line in it, as editors and the terminal's links take it.
21
+ const m = /^(.*?):(\d+)(?::\d+)?$/.exec(raw);
22
+ const target = m ? m[1] : raw;
23
+ const line = m ? Number(m[2]) : null;
24
+ const home = target.startsWith("~/")
25
+ ? path.join(os.homedir(), target.slice(2))
26
+ : target;
27
+ // This shell's own directory first; then as typed, which the server
28
+ // tries against the session's, the workspace and each repo.
29
+ const abs = path.resolve(process.cwd(), home);
30
+ const answers = await ctx.api.post(`/api/workspaces/${ws.id}/term-paths`, {
31
+ ...(process.env.WORK_SESSION_ID && {
32
+ session: process.env.WORK_SESSION_ID,
33
+ }),
34
+ paths: [abs, home],
35
+ });
36
+ const hit = answers?.[0] ?? answers?.[1];
37
+ if (!hit) return null;
38
+ const q = new URLSearchParams({ file: hit.key });
39
+ if (line && !hit.key.endsWith("/")) q.set("line", String(line));
40
+ return {
41
+ link: `/w/${ws.id}/files?${q}`,
42
+ label: `${hit.key}${line && !hit.key.endsWith("/") ? `:${line}` : ""}`,
43
+ };
44
+ }
45
+
46
+ /** Why a target named nothing, said once for both commands. */
47
+ export function unresolved(raw) {
48
+ return `nothing at ${raw} in this workspace: a file or folder in its checkouts or its .share/, an app page (/w/…), or a URL`;
49
+ }
@@ -0,0 +1,153 @@
1
+ // `work agent`: the agent CLIs this machine has, as Settings → Agents
2
+ // lists and switches them.
3
+ import { follow } from "./_progress.mjs";
4
+
5
+ /** What both lists are read from: the machine's agents (installed or
6
+ * not, each binary on PATH an instance) and the app's choices among them
7
+ * (the default, the ones switched off). */
8
+ async function snapshot(ctx) {
9
+ const [setup, settings] = await Promise.all([
10
+ ctx.api.get("/api/setup"),
11
+ ctx.api.get("/api/settings"),
12
+ ]);
13
+ const off = new Set(settings.disabledAgents || []);
14
+ return {
15
+ default: settings.preferredAgent ?? null,
16
+ agents: (setup.agents || []).map((a) => ({
17
+ id: a.id,
18
+ label: a.label,
19
+ installed: a.installed,
20
+ installable: a.installable,
21
+ instances: (a.instances || []).map((i) => ({
22
+ id: i.id,
23
+ command: i.command,
24
+ path: i.path,
25
+ enabled: !off.has(i.id),
26
+ })),
27
+ })),
28
+ catalog: settings.catalog || [],
29
+ };
30
+ }
31
+
32
+ function printList(s) {
33
+ console.log(`default: ${s.default ?? "(none)"}`);
34
+ const w = Math.max(5, ...s.agents.map((a) => a.id.length));
35
+ for (const a of s.agents) {
36
+ if (!a.instances.length) {
37
+ console.log(
38
+ `${a.id.padEnd(w)} ${a.label} — not installed${a.installable ? " (work agent install " + a.id + ")" : ""}`,
39
+ );
40
+ continue;
41
+ }
42
+ const each = a.instances
43
+ .map((i) => `${i.id}${i.enabled ? "" : " (off)"}`)
44
+ .join(", ");
45
+ console.log(`${a.id.padEnd(w)} ${a.label} — ${each}`);
46
+ }
47
+ }
48
+
49
+ /** An instance id the machine has (`claude`, `claude2`), or the command
50
+ * dies naming the ones it does. */
51
+ function instance(ctx, s, id) {
52
+ if (!id) ctx.die("name the agent: an instance id from work agent list");
53
+ const hit = s.catalog.find((c) => c.id === id && c.id !== "shell");
54
+ if (!hit) {
55
+ const have = s.catalog
56
+ .filter((c) => c.id !== "shell")
57
+ .map((c) => c.id)
58
+ .join(", ");
59
+ ctx.die(`no installed agent ${id} (installed: ${have || "none"})`);
60
+ }
61
+ return hit;
62
+ }
63
+
64
+ /** @type {Array<{name: string, summary: string, help: string, run: (ctx: any) => Promise<void>}>} */
65
+ export const commands = [
66
+ {
67
+ name: "agent",
68
+ summary: "agent CLIs: list | install | enable | disable | default",
69
+ help: `work agent [list]
70
+ The agent CLIs this machine knows: each family, whether it is installed,
71
+ its instances (one per binary on PATH: claude, claude2) and which are
72
+ switched off, and the default new sessions start with.
73
+ work agent install <family>
74
+ Install an agent CLI the machine lacks (claude, codex, …), as Settings
75
+ does; its installer's output goes to stderr.
76
+ work agent enable|disable <instance>
77
+ Show or hide an installed instance in the app's pickers (it stays
78
+ installed).
79
+ work agent default <instance>
80
+ The agent new sessions start with: an installed instance that is
81
+ switched on (with none, new sessions are a plain shell).`,
82
+ async run(ctx) {
83
+ const [verb = "list", id] = ctx.parse();
84
+ if (verb === "list") {
85
+ const s = await snapshot(ctx);
86
+ const { catalog, ...shown } = s;
87
+ return ctx.out(shown, printList);
88
+ }
89
+ if (verb === "install") {
90
+ const s = await snapshot(ctx);
91
+ const fam = s.agents.find((a) => a.id === id);
92
+ if (!fam)
93
+ ctx.die(
94
+ `no agent family ${id ?? ""} (known: ${s.agents.map((a) => a.id).join(", ")})`,
95
+ );
96
+ if (fam.installed) {
97
+ ctx.out({ id: fam.id, installed: true }, () =>
98
+ console.log(`${fam.label} is already installed`),
99
+ );
100
+ return;
101
+ }
102
+ if (!fam.installable)
103
+ ctx.die(`${fam.label} has no installer work can run here`);
104
+ const setup = await follow(ctx, `setup:${fam.id}`, () =>
105
+ ctx.api.post(`/api/setup/${encodeURIComponent(fam.id)}`, {
106
+ action: "install",
107
+ }),
108
+ );
109
+ const now = (setup.agents || []).find((a) => a.id === fam.id);
110
+ ctx.out({ id: fam.id, installed: !!now?.installed }, () =>
111
+ console.log(
112
+ now?.installed
113
+ ? `installed ${fam.label}`
114
+ : `${fam.label} still is not on PATH (see the output above)`,
115
+ ),
116
+ );
117
+ return;
118
+ }
119
+ if (verb === "enable" || verb === "disable") {
120
+ const s = await snapshot(ctx);
121
+ const inst = instance(ctx, s, id);
122
+ await ctx.api.put("/api/settings", {
123
+ agent: { id: inst.id, enabled: verb === "enable" },
124
+ });
125
+ ctx.out({ id: inst.id, enabled: verb === "enable" }, () =>
126
+ console.log(
127
+ `${inst.id} ${verb === "enable" ? "shows in" : "is hidden from"} the app's pickers`,
128
+ ),
129
+ );
130
+ return;
131
+ }
132
+ if (verb === "default") {
133
+ if (!id) ctx.die("name the agent: work agent default <instance>");
134
+ const s = await snapshot(ctx);
135
+ const inst = instance(ctx, s, id);
136
+ // The server keeps a default only while it is switched on; one that
137
+ // is off would be stored and then read back as another.
138
+ if (!inst.enabled)
139
+ ctx.die(`${id} is switched off: work agent enable ${id} first`);
140
+ const after = await ctx.api.put("/api/settings", {
141
+ preferredAgent: id,
142
+ });
143
+ ctx.out({ default: after.preferredAgent }, () =>
144
+ console.log(`new sessions start with ${after.preferredAgent}`),
145
+ );
146
+ return;
147
+ }
148
+ ctx.die(
149
+ `no agent verb ${verb} (list, install, enable, disable, default)`,
150
+ );
151
+ },
152
+ },
153
+ ];
@@ -0,0 +1,79 @@
1
+ // `work branches`: the workspace's sections as the review lists them —
2
+ // each repo's checkout, its topic branches (lanes), their PRs — with the
3
+ // id a review link names and the link itself, so an agent links and
4
+ // rebases what is there rather than guessing names from a convention.
5
+
6
+ /** What a section is up to, in a few words. */
7
+ function stateOf(s) {
8
+ const parts = [];
9
+ if (s.pr)
10
+ parts.push(
11
+ `PR #${s.pr.number}${s.pr.isDraft ? " draft" : ""}: ${s.pr.title}`,
12
+ );
13
+ else if (s.unborn) parts.push("no commits yet");
14
+ else if (s.contained) parts.push("nothing of its own (merged, or not begun)");
15
+ else if (s.unpushed) parts.push(`${s.unpushed} unpushed`);
16
+ else if (s.ready) parts.push("pushed, no PR");
17
+ if (s.edits) parts.push(`${s.edits} uncommitted`);
18
+ if (s.stack) parts.push(`layer ${s.stack.index + 1} of ${s.stack.size}`);
19
+ return parts.join(" · ") || "—";
20
+ }
21
+
22
+ /** Whether a checkout's own section says anything: one with nothing of
23
+ * its own and no edits is every idle repo of a large workspace. */
24
+ function worthListing(s, all) {
25
+ if (s.id.includes("@") || s.id.includes("#")) return true;
26
+ return all || !s.contained || !!s.edits || !!s.pr;
27
+ }
28
+
29
+ export const commands = [
30
+ {
31
+ name: "branches",
32
+ summary: "the workspace's branches and PRs, with each one's review link",
33
+ help: `work branches [id|name] [--all] [--fresh] [--json]
34
+ The workspace's sections as the review lists them: each repo's checkout
35
+ (only one with something of its own, unless --all), its topic branches
36
+ (\`repo@topic\`) and open PRs (\`repo#123\`), each with its state (PR,
37
+ unpushed commits, uncommitted edits, merged) and the Markdown link that
38
+ opens it in the review: [topic](/w/<id>/review?section=repo@topic).
39
+ --fresh asks GitHub again rather than the PR cache (~2 min old).`,
40
+ async run(ctx) {
41
+ const [arg] = ctx.positional;
42
+ const { ws } = await ctx.resolveWorkspace(arg);
43
+ const sections = await ctx.api.get(`/api/workspaces/${ws.id}/sections`);
44
+ const all = ctx.has("--all");
45
+ const rows = sections
46
+ .filter((s) => worthListing(s, all))
47
+ .map((s) => {
48
+ const label = s.id.includes("@")
49
+ ? s.id.slice(s.id.indexOf("@") + 1)
50
+ : s.id;
51
+ // `@` as itself, as the links agents are told to write spell it;
52
+ // a PR section's `#` must be escaped.
53
+ const href = `/w/${ws.id}/review?section=${encodeURIComponent(s.id).replace(/%40/g, "@")}`;
54
+ return {
55
+ id: s.id,
56
+ repo: s.worktree,
57
+ branch: s.headRef || s.pr?.headRefName || s.branch,
58
+ base: s.base,
59
+ state: stateOf(s),
60
+ pr: s.pr ? { number: s.pr.number, url: s.pr.url } : null,
61
+ unpushed: s.unpushed || 0,
62
+ edits: s.edits || 0,
63
+ merged: !!s.contained && !s.pr,
64
+ link: `[${label}](${href})`,
65
+ href,
66
+ };
67
+ });
68
+ ctx.out(rows, (list) => {
69
+ if (!list.length)
70
+ return console.log("nothing of its own on any branch");
71
+ const w = Math.max(...list.map((r) => r.id.length));
72
+ for (const r of list)
73
+ console.log(
74
+ `${ctx.pad(r.id, w)} ${r.branch} ${r.state}\n${" ".repeat(w + 2)}${r.link}`,
75
+ );
76
+ });
77
+ },
78
+ },
79
+ ];
@@ -0,0 +1,175 @@
1
+ // `work config`: every setting the app's Settings pages change, read and
2
+ // written through the running server's one registry of them
3
+ // (src/server/settings-registry.ts), which checks each value — so an agent
4
+ // can turn on language servers or pick the default agent without a browser,
5
+ // and a wrong value is refused with what the setting takes.
6
+
7
+ /** A value as a person reads it. */
8
+ export function shown(value) {
9
+ if (value === null || value === undefined) return "(unset)";
10
+ if (typeof value === "boolean") return value ? "on" : "off";
11
+ if (Array.isArray(value)) return value.length ? value.join(",") : "(none)";
12
+ if (typeof value === "object") return JSON.stringify(value);
13
+ if (value === "") return "(empty)";
14
+ return String(value);
15
+ }
16
+
17
+ const SCOPES = [
18
+ ["machine", "machine (every device)"],
19
+ ["device", "one kind of device"],
20
+ ["ui-state", "page state"],
21
+ ];
22
+
23
+ /** `key = value` and, when changed, what it would otherwise be; the
24
+ * description under it. */
25
+ function printEntries(entries) {
26
+ for (const [scope, title] of SCOPES) {
27
+ const rows = entries.filter((e) => e.scope === scope);
28
+ if (!rows.length) continue;
29
+ console.log(`\n${title}`);
30
+ for (const e of rows) {
31
+ const was = e.isDefault
32
+ ? ""
33
+ : ` (default ${e.defaultText ?? shown(e.default)})`;
34
+ const managed = e.managed ? ` [set with ${e.managed}]` : "";
35
+ console.log(` ${e.key} = ${shown(e.value)}${was}${managed}`);
36
+ console.log(` ${e.description}`);
37
+ }
38
+ }
39
+ }
40
+
41
+ /** What a setting takes, in a few words. */
42
+ function takes(d) {
43
+ switch (d.type) {
44
+ case "bool":
45
+ return "on|off";
46
+ case "enum":
47
+ return d.values.join("|");
48
+ case "int":
49
+ return `${d.min}–${d.max}`;
50
+ case "list":
51
+ return d.values?.length ? `list of ${d.values.join("|")}` : "list";
52
+ case "json":
53
+ return "JSON object";
54
+ default:
55
+ return d.maxLength ? `text ≤${d.maxLength}` : "text";
56
+ }
57
+ }
58
+
59
+ const KEY = (ctx, verb) => {
60
+ const key = ctx.positional[0];
61
+ if (!key) ctx.die(`usage: work config ${verb} <key> (see: work config list)`);
62
+ return key;
63
+ };
64
+
65
+ const list = {
66
+ summary: "every setting with its value (--all adds page state)",
67
+ async run(ctx) {
68
+ const entries = await ctx.api.get(
69
+ `/api/settings/values${ctx.has("--all") ? "?all" : ""}`,
70
+ );
71
+ ctx.out(entries, printEntries);
72
+ },
73
+ };
74
+
75
+ export const commands = [
76
+ {
77
+ name: "config",
78
+ ...list,
79
+ async run(ctx) {
80
+ // `work config theme` is a typo for get or set, not a list.
81
+ if (ctx.positional[0])
82
+ ctx.die(
83
+ `no \`work config ${ctx.positional[0]}\`: list, get, set, unset or schema (see: work help config)`,
84
+ );
85
+ return list.run(ctx);
86
+ },
87
+ help: `work config [list] [--all] [--json]
88
+ every setting the app's Settings change: its value, its default when
89
+ changed from it, and what it does (--all adds each page's own state)
90
+ work config get <key> one setting's value (--json: the whole entry)
91
+ work config set <key> <value> change one: on|off, a number, one of its
92
+ values, a list as a,b (or the items as
93
+ separate args), a JSON object; refused with
94
+ what it takes when the value does not fit
95
+ work config unset <key> put one back to its default
96
+ work config schema [--json] every setting: its type, what it takes, its
97
+ default, whose it is and what it does`,
98
+ },
99
+ { name: "config list", ...list, help: "work config list [--all] [--json]" },
100
+ {
101
+ name: "config get",
102
+ summary: "one setting's value",
103
+ help: "work config get <key> [--json]",
104
+ async run(ctx) {
105
+ const key = KEY(ctx, "get");
106
+ const e = await ctx.api.get(
107
+ `/api/settings/values?key=${encodeURIComponent(key)}`,
108
+ );
109
+ ctx.out(e, () => console.log(shown(e.value)));
110
+ },
111
+ },
112
+ {
113
+ name: "config set",
114
+ summary: "change one setting (checked against what it takes)",
115
+ help: `work config set <key> <value…> [--json]
116
+ work config set lsp on
117
+ work config set theme dark
118
+ work config set lsp-off typescript,marko
119
+ work config set command.claude "claude --verbose"
120
+ work config set keys '{"palette": "Mod+K"}'`,
121
+ async run(ctx) {
122
+ const key = KEY(ctx, "set");
123
+ const words = ctx.positional.slice(1);
124
+ if (!words.length)
125
+ ctx.die(
126
+ `usage: work config set ${key} <value> (work config unset ${key} for its default)`,
127
+ );
128
+ const e = await ctx.api.post("/api/settings/values", {
129
+ key,
130
+ value: words.length > 1 ? words : words[0],
131
+ });
132
+ ctx.out(e, () => console.log(`${e.key} = ${shown(e.value)}`));
133
+ },
134
+ },
135
+ {
136
+ name: "config unset",
137
+ summary: "put one setting back to its default",
138
+ help: "work config unset <key> [--json]",
139
+ async run(ctx) {
140
+ const key = KEY(ctx, "unset");
141
+ const e = await ctx.api.post("/api/settings/values", {
142
+ key,
143
+ value: null,
144
+ });
145
+ ctx.out(e, () => console.log(`${e.key} = ${shown(e.value)}`));
146
+ },
147
+ },
148
+ {
149
+ name: "config schema",
150
+ summary: "every setting's type, values, default and scope",
151
+ help: "work config schema [--json]",
152
+ async run(ctx) {
153
+ const schema = await ctx.api.get("/api/settings/schema");
154
+ ctx.out(schema, () => {
155
+ for (const [scope, title] of SCOPES) {
156
+ const rows = schema.filter((d) => d.scope === scope);
157
+ if (!rows.length) continue;
158
+ console.log(`\n${title}`);
159
+ for (const d of rows) {
160
+ const dflt = d.defaultText ?? shown(d.default);
161
+ const extra = [
162
+ `default ${dflt}`,
163
+ d.backup && "in backups",
164
+ d.managed && `set with ${d.managed}`,
165
+ ]
166
+ .filter(Boolean)
167
+ .join(", ");
168
+ console.log(` ${d.key} ${takes(d)} (${extra})`);
169
+ console.log(` ${d.description}`);
170
+ }
171
+ }
172
+ });
173
+ },
174
+ },
175
+ ];