@dylanpiercey/work 0.1.1 → 0.2.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 (486) hide show
  1. package/README.md +28 -0
  2. package/bin/work.mjs +244 -4
  3. package/dist/_BO3_WJb5.js +169 -0
  4. package/dist/{_Dzz52ZtI.js → _CzOrFOdN.js} +344 -12
  5. package/dist/_DiOv9AKj.js +2 -0
  6. package/dist/index.mjs +8631 -7573
  7. package/dist/public/assets/{_DX5u6Wvm.js → _3hcTpTUc.js} +1 -1
  8. package/dist/public/assets/_3hcTpTUc.js.br +0 -0
  9. package/dist/public/assets/_88jVvZ6C.js +1 -0
  10. package/dist/public/assets/{_DRHCy0UF.js → _B0FtZL3L.js} +1 -1
  11. package/dist/public/assets/_B0FtZL3L.js.br +0 -0
  12. package/dist/public/assets/{_BKIx7IZP.js → _B0rj5kOY.js} +1 -1
  13. package/dist/public/assets/_B0rj5kOY.js.br +0 -0
  14. package/dist/public/assets/{_DUs3ZGbj.js → _B3aw0q8p.js} +1 -1
  15. package/dist/public/assets/_B3aw0q8p.js.br +0 -0
  16. package/dist/public/assets/{__cyRVmTO.js → _B42XfAog.js} +1 -1
  17. package/dist/public/assets/_B42XfAog.js.br +0 -0
  18. package/dist/public/assets/_B5Ih3Lwt.js +1 -0
  19. package/dist/public/assets/_B6jh-_o_.js +1 -0
  20. package/dist/public/assets/_B8FHVXDZ.js +1 -0
  21. package/dist/public/assets/_BBJYNk03.js +1 -0
  22. package/dist/public/assets/{_CKLGAGKJ.js → _BBk5_vEh.js} +1 -1
  23. package/dist/public/assets/_BBk5_vEh.js.br +0 -0
  24. package/dist/public/assets/{_TrcWRD8T.js → _BCS_gQxR.js} +7 -7
  25. package/dist/public/assets/_BCS_gQxR.js.br +0 -0
  26. package/dist/public/assets/{_C8bqYk4J.js → _BDBxSbjY.js} +1 -1
  27. package/dist/public/assets/_BDBxSbjY.js.br +0 -0
  28. package/dist/public/assets/_BDkqB224.js +1 -0
  29. package/dist/public/assets/{_DQyjuXTi.js → _BEtl4C9q.js} +1 -1
  30. package/dist/public/assets/_BEtl4C9q.js.br +0 -0
  31. package/dist/public/assets/{_Cmmdd2e3.js → _BJZwk-Pf.js} +1 -1
  32. package/dist/public/assets/_BJZwk-Pf.js.br +0 -0
  33. package/dist/public/assets/{_BzGHediB.js → _BM8qop28.js} +1 -1
  34. package/dist/public/assets/_BM8qop28.js.br +0 -0
  35. package/dist/public/assets/_BNL2e5az.js +1 -0
  36. package/dist/public/assets/{_HmkI4Rfn.js → _BODl5Jdc.js} +1 -1
  37. package/dist/public/assets/_BODl5Jdc.js.br +0 -0
  38. package/dist/public/assets/{_C81nSl09.js → _BOe3voZI.js} +1 -1
  39. package/dist/public/assets/_BOe3voZI.js.br +0 -0
  40. package/dist/public/assets/{_CiYQhf81.js → _BPW-OoaM.js} +1 -1
  41. package/dist/public/assets/_BPW-OoaM.js.br +0 -0
  42. package/dist/public/assets/{_CqCenHOp.js → _BSHUa-H0.js} +1 -1
  43. package/dist/public/assets/_BSHUa-H0.js.br +0 -0
  44. package/dist/public/assets/_BTXURtlK.js +1 -0
  45. package/dist/public/assets/{_BLfzQY-3.js → _BU4lH-F3.js} +1 -1
  46. package/dist/public/assets/_BU4lH-F3.js.br +0 -0
  47. package/dist/public/assets/{_CHdpLB95.js → _BVGSrb9C.js} +1 -1
  48. package/dist/public/assets/_BVGSrb9C.js.br +0 -0
  49. package/dist/public/assets/{_BSFJEuJX.js → _BXyDScMX.js} +1 -1
  50. package/dist/public/assets/_BXyDScMX.js.br +0 -0
  51. package/dist/public/assets/{_CfGEGt_k.js → _BZXtyNwD.js} +1 -1
  52. package/dist/public/assets/_BZXtyNwD.js.br +0 -0
  53. package/dist/public/assets/{_BRQ6iQ5p.js → _B_iUZxSk.js} +1 -1
  54. package/dist/public/assets/_B_iUZxSk.js.br +0 -0
  55. package/dist/public/assets/_B_klvcQs.js +1 -0
  56. package/dist/public/assets/{_DZvkgS3V.js → _BaNsw5pr.js} +1 -1
  57. package/dist/public/assets/_BaNsw5pr.js.br +0 -0
  58. package/dist/public/assets/_BbPq34k8.js +1 -0
  59. package/dist/public/assets/{_UaKPY71M.js → _BfDaM2KU.js} +1 -1
  60. package/dist/public/assets/_BfDaM2KU.js.br +0 -0
  61. package/dist/public/assets/_Bk1naXp4.js +1 -0
  62. package/dist/public/assets/{_kWQ0dtYZ.js → _BkNKadGd.js} +1 -1
  63. package/dist/public/assets/_BkNKadGd.js.br +0 -0
  64. package/dist/public/assets/{_1JXC9nFp.js → _BkztnqUW.js} +1 -1
  65. package/dist/public/assets/_BkztnqUW.js.br +0 -0
  66. package/dist/public/assets/_BlNBDTvP.js +1 -0
  67. package/dist/public/assets/_BlNBDTvP.js.br +0 -0
  68. package/dist/public/assets/_BlUmx1wN.js +1 -0
  69. package/dist/public/assets/_Ble8b9gd.js +1 -0
  70. package/dist/public/assets/{_B7VYILLZ.js → _BpEvAl9E.js} +1 -1
  71. package/dist/public/assets/_BpEvAl9E.js.br +0 -0
  72. package/dist/public/assets/_Bqyvdrqf.js +1 -0
  73. package/dist/public/assets/_BsA2bpua.js +1 -0
  74. package/dist/public/assets/_BsA2bpua.js.br +0 -0
  75. package/dist/public/assets/_BsAVia13.js +1 -0
  76. package/dist/public/assets/_BtxLmMRq.js +1 -0
  77. package/dist/public/assets/{_B1-W0Sn2.js → _Byfemjjt.js} +1 -1
  78. package/dist/public/assets/_Byfemjjt.js.br +0 -0
  79. package/dist/public/assets/{_Do1ltY2a.js → _Bz94qqXL.js} +1 -1
  80. package/dist/public/assets/_Bz94qqXL.js.br +0 -0
  81. package/dist/public/assets/_C-HIZYIZ.js +1 -0
  82. package/dist/public/assets/{_Di1ccq_2.js → _C-UGjoFi.js} +1 -1
  83. package/dist/public/assets/_C-UGjoFi.js.br +0 -0
  84. package/dist/public/assets/{_DM60dKRs.js → _C-jXvDAe.js} +1 -1
  85. package/dist/public/assets/_C-jXvDAe.js.br +0 -0
  86. package/dist/public/assets/{_DomK7Scb.js → _C2b1kmvc.js} +1 -1
  87. package/dist/public/assets/_C2b1kmvc.js.br +0 -0
  88. package/dist/public/assets/{_pXG8fRON.js → _C3PIXMJF.js} +1 -1
  89. package/dist/public/assets/_C3PIXMJF.js.br +0 -0
  90. package/dist/public/assets/_C6eXJBpX.js +1 -0
  91. package/dist/public/assets/{_EefWj858.js → _C7Xd05b1.js} +1 -1
  92. package/dist/public/assets/_C7Xd05b1.js.br +0 -0
  93. package/dist/public/assets/_C8jPP8tm.js +1 -0
  94. package/dist/public/assets/{_CWG813ur.js → _CB9BGKKP.js} +1 -1
  95. package/dist/public/assets/_CB9BGKKP.js.br +0 -0
  96. package/dist/public/assets/{_CCVkYcN5.js → _CD44YUtO.js} +1 -1
  97. package/dist/public/assets/_CD44YUtO.js.br +0 -0
  98. package/dist/public/assets/{_CxA3Yab0.js → _CEXagH_p.js} +1 -1
  99. package/dist/public/assets/_CEXagH_p.js.br +0 -0
  100. package/dist/public/assets/{_m2tRa0jk.js → _CFOiLJdu.js} +1 -1
  101. package/dist/public/assets/_CFOiLJdu.js.br +0 -0
  102. package/dist/public/assets/{_C-EkQeP_.js → _CGrClLsS.js} +1 -1
  103. package/dist/public/assets/_CGrClLsS.js.br +0 -0
  104. package/dist/public/assets/_CHJuzFIS.js +1 -0
  105. package/dist/public/assets/{_CDY0RpYX.js → _CJ7DGNLC.js} +1 -1
  106. package/dist/public/assets/_CJ7DGNLC.js.br +0 -0
  107. package/dist/public/assets/_CJG7LF4o.js +1 -0
  108. package/dist/public/assets/{_B3NfNm8M.js → _CK0tdQ6M.js} +13 -13
  109. package/dist/public/assets/_CK0tdQ6M.js.br +0 -0
  110. package/dist/public/assets/{_BSWN-v3P.js → _CKcab_6c.js} +1 -1
  111. package/dist/public/assets/_CKcab_6c.js.br +0 -0
  112. package/dist/public/assets/{_DBD57l1T.js → _CKpSd2DN.js} +1 -1
  113. package/dist/public/assets/_CKpSd2DN.js.br +0 -0
  114. package/dist/public/assets/{_FlITqTCo.js → _CKy2HduV.js} +1 -1
  115. package/dist/public/assets/_CKy2HduV.js.br +0 -0
  116. package/dist/public/assets/{_DL3w8c_p.js → _CLikwAg5.js} +1 -1
  117. package/dist/public/assets/_CLikwAg5.js.br +0 -0
  118. package/dist/public/assets/{_ClHPjF-1.js → _CM-AIl7T.js} +1 -1
  119. package/dist/public/assets/_CM-AIl7T.js.br +0 -0
  120. package/dist/public/assets/{_DxD_AC3a.js → _CMwrJ1ju.js} +1 -1
  121. package/dist/public/assets/_CMwrJ1ju.js.br +0 -0
  122. package/dist/public/assets/_CQG-EbMi.js +1 -0
  123. package/dist/public/assets/_CUl36Gcx.js +1 -0
  124. package/dist/public/assets/{_7YrArFMB.js → _CUq2djIT.js} +1 -1
  125. package/dist/public/assets/_CUq2djIT.js.br +0 -0
  126. package/dist/public/assets/{_DgWKSW-Y.js → _CWSGdqC2.js} +1 -1
  127. package/dist/public/assets/_CWSGdqC2.js.br +0 -0
  128. package/dist/public/assets/_CXK3AUqn.js +1 -0
  129. package/dist/public/assets/{_JEvx8ub4.js → _CYYRiJuo.js} +1 -1
  130. package/dist/public/assets/_CYYRiJuo.js.br +0 -0
  131. package/dist/public/assets/_CYr8GcJI.js +1 -0
  132. package/dist/public/assets/{_B1D0PIz3.js → _CaFhYr8X.js} +1 -1
  133. package/dist/public/assets/_CaFhYr8X.js.br +0 -0
  134. package/dist/public/assets/_CbzGfu_I.js +1 -0
  135. package/dist/public/assets/{_iutZ4EDe.js → _Cd85Xtd1.js} +1 -1
  136. package/dist/public/assets/_Cd85Xtd1.js.br +0 -0
  137. package/dist/public/assets/_Ch-bwiFD.js +1 -0
  138. package/dist/public/assets/_ClGAsZdo.js +1 -0
  139. package/dist/public/assets/_ClGAsZdo.js.br +0 -0
  140. package/dist/public/assets/_ClhDmYWO.js +1 -0
  141. package/dist/public/assets/_ClhDmYWO.js.br +0 -0
  142. package/dist/public/assets/{_B_0C2_RO.js → _Cm85V2m3.js} +1 -1
  143. package/dist/public/assets/_Cm85V2m3.js.br +0 -0
  144. package/dist/public/assets/_Cp4ZjGeg.js +1 -0
  145. package/dist/public/assets/{_3aBl7SEn.js → _CsRnEvC3.js} +1 -1
  146. package/dist/public/assets/_CsRnEvC3.js.br +0 -0
  147. package/dist/public/assets/_CtFo1511.js +1 -0
  148. package/dist/public/assets/{_dsj7vMTW.js → _CtIpOiCk.js} +1 -1
  149. package/dist/public/assets/_CtIpOiCk.js.br +0 -0
  150. package/dist/public/assets/{_DSUBv-Bl.js → _CwOgQx7H.js} +1 -1
  151. package/dist/public/assets/_CwOgQx7H.js.br +0 -0
  152. package/dist/public/assets/_CwtVecVY.js +1 -0
  153. package/dist/public/assets/_Cxuln-KJ.js +1 -0
  154. package/dist/public/assets/_CyYNC4Ow.js +1 -0
  155. package/dist/public/assets/{_HM_QqtJi.js → _Cy_g0woP.js} +1 -1
  156. package/dist/public/assets/_Cy_g0woP.js.br +0 -0
  157. package/dist/public/assets/{_DEOryr7w.js → _CzDRlITT.js} +1 -1
  158. package/dist/public/assets/_CzDRlITT.js.br +0 -0
  159. package/dist/public/assets/_Czq9fyjZ.js +1 -0
  160. package/dist/public/assets/{_BDUjU8Ev.js → _D1Rh4MKD.js} +1 -1
  161. package/dist/public/assets/_D2edy8B-.js +1 -0
  162. package/dist/public/assets/_D2edy8B-.js.br +0 -0
  163. package/dist/public/assets/_D2pdXUO3.js +1 -0
  164. package/dist/public/assets/_D4M5BFEU.js +1 -0
  165. package/dist/public/assets/{_Cb_k_JA_.js → _D749nUfQ.js} +1 -1
  166. package/dist/public/assets/_D749nUfQ.js.br +0 -0
  167. package/dist/public/assets/_D7mcWce0.js +2 -0
  168. package/dist/public/assets/_D7mcWce0.js.br +0 -0
  169. package/dist/public/assets/{_BsJZPHmz.js → _D81sIY4I.js} +1 -1
  170. package/dist/public/assets/_D81sIY4I.js.br +0 -0
  171. package/dist/public/assets/{_Dbm6zAQS.js → _D8Opg0DA.js} +1 -1
  172. package/dist/public/assets/_D8Opg0DA.js.br +0 -0
  173. package/dist/public/assets/{_BtZ2AatF.js → _DCJrZQ6J.js} +1 -1
  174. package/dist/public/assets/_DEPHQNx4.js +1 -0
  175. package/dist/public/assets/_DEtYVOe1.js +1 -0
  176. package/dist/public/assets/_DJ4gN7dQ.js +1 -0
  177. package/dist/public/assets/_DJ9NEjwG.js +1 -0
  178. package/dist/public/assets/{_BkcPY2j0.js → _DJUeUZKF.js} +1 -1
  179. package/dist/public/assets/_DJUeUZKF.js.br +0 -0
  180. package/dist/public/assets/_DLZswhbS.js +1 -0
  181. package/dist/public/assets/{_DJqEBkNd.js → _DMEtxMrc.js} +1 -1
  182. package/dist/public/assets/_DMEtxMrc.js.br +0 -0
  183. package/dist/public/assets/{_CfdK8EeQ.js → _DOr6ubI-.js} +1 -1
  184. package/dist/public/assets/_DOr6ubI-.js.br +0 -0
  185. package/dist/public/assets/{_BPSTqkJn.js → _DQu5M2GV.js} +1 -1
  186. package/dist/public/assets/_DQu5M2GV.js.br +0 -0
  187. package/dist/public/assets/_DUvup9ew.js +1 -0
  188. package/dist/public/assets/{_DvKnakqk.js → _DWrhUk5T.js} +1 -1
  189. package/dist/public/assets/_DWrhUk5T.js.br +0 -0
  190. package/dist/public/assets/{_BHU5aikZ.js → _DXOx4zKx.js} +1 -1
  191. package/dist/public/assets/_D_1b7pob.js +1 -0
  192. package/dist/public/assets/_Daap2skI.js +1 -0
  193. package/dist/public/assets/{_DifjKObE.js → _DcktT8yN.js} +1 -1
  194. package/dist/public/assets/_DcktT8yN.js.br +0 -0
  195. package/dist/public/assets/{_1xOByopP.js → _Ddc9Y9a_.js} +1 -1
  196. package/dist/public/assets/_Ddc9Y9a_.js.br +0 -0
  197. package/dist/public/assets/{_DMJHTH74.js → _Dfjlzo9W.js} +1 -1
  198. package/dist/public/assets/_Dfjlzo9W.js.br +0 -0
  199. package/dist/public/assets/_Dh30YzVM.js +1 -0
  200. package/dist/public/assets/_DhohfuPc.js +1 -0
  201. package/dist/public/assets/_DjQz8h-q.js +1 -0
  202. package/dist/public/assets/_DjX1BGKn.js +1 -0
  203. package/dist/public/assets/_DjiaxzEs.js +1 -0
  204. package/dist/public/assets/_Dkg-QEnz.js +1 -0
  205. package/dist/public/assets/{_Cx_aJfDp.js → _Dl46-33v.js} +1 -1
  206. package/dist/public/assets/_Dl46-33v.js.br +0 -0
  207. package/dist/public/assets/{_VPLoEBTS.js → _DlvIY6aE.js} +1 -1
  208. package/dist/public/assets/{_BKHtiW96.js → _Dmi6AQP3.js} +1 -1
  209. package/dist/public/assets/_Dmi6AQP3.js.br +0 -0
  210. package/dist/public/assets/{_CFUREq1M.js → _Dmj0vHNs.js} +1 -1
  211. package/dist/public/assets/_Dmj0vHNs.js.br +0 -0
  212. package/dist/public/assets/{_CY87Y7QL.js → _DnYboxB9.js} +1 -1
  213. package/dist/public/assets/_DnYboxB9.js.br +0 -0
  214. package/dist/public/assets/{_-5UNb9-C.js → _Do6MGycg.js} +1 -1
  215. package/dist/public/assets/_Do6MGycg.js.br +0 -0
  216. package/dist/public/assets/{_DzKW89Sx.js → _DtZ-vebM.js} +1 -1
  217. package/dist/public/assets/_DtZ-vebM.js.br +0 -0
  218. package/dist/public/assets/_DuNisSjT.js +1 -0
  219. package/dist/public/assets/_Dvk-TlMq.js +1 -0
  220. package/dist/public/assets/_Dvk-TlMq.js.br +0 -0
  221. package/dist/public/assets/_DwdnhMjL.js +1 -0
  222. package/dist/public/assets/_DwydmxSi.js +1 -0
  223. package/dist/public/assets/_DzgHDUu0.js +1 -0
  224. package/dist/public/assets/{_CtqGSS84.js → _G-e2JHHS.js} +1 -1
  225. package/dist/public/assets/_G-e2JHHS.js.br +0 -0
  226. package/dist/public/assets/_IOS0xG1B.js +1 -0
  227. package/dist/public/assets/_IiZnk_jc.js +1 -0
  228. package/dist/public/assets/{_CUsrMpdL.js → _KYdxhRVL.js} +1 -1
  229. package/dist/public/assets/_KYdxhRVL.js.br +0 -0
  230. package/dist/public/assets/_LY1sEEvJ.js +1 -0
  231. package/dist/public/assets/_MATnTPAL.js +1 -0
  232. package/dist/public/assets/_MATnTPAL.js.br +0 -0
  233. package/dist/public/assets/_OVl4e0V3.js +1 -0
  234. package/dist/public/assets/{_vcLBrU2m.js → _Sv1HjkeK.js} +1 -1
  235. package/dist/public/assets/_Sv1HjkeK.js.br +0 -0
  236. package/dist/public/assets/_Syg4UyQU.js +86 -0
  237. package/dist/public/assets/_Syg4UyQU.js.br +0 -0
  238. package/dist/public/assets/_TJCslr2g.js +1 -0
  239. package/dist/public/assets/_UcXY-7XH.js +2 -0
  240. package/dist/public/assets/_UcXY-7XH.js.br +0 -0
  241. package/dist/public/assets/{_BVQosHjY.js → _VM9JbUGP.js} +1 -1
  242. package/dist/public/assets/_VM9JbUGP.js.br +0 -0
  243. package/dist/public/assets/{_C98JZr09.js → _YOjtJWMK.js} +1 -1
  244. package/dist/public/assets/_YOjtJWMK.js.br +10 -0
  245. package/dist/public/assets/_YPt61819.js +1 -0
  246. package/dist/public/assets/{_yUmRJIJ6.js → _Zh4-3iG-.js} +1 -1
  247. package/dist/public/assets/_Zh4-3iG-.js.br +0 -0
  248. package/dist/public/assets/{_DcOkTFth.js → _ZptG1LQC.js} +1 -1
  249. package/dist/public/assets/_brnakAIx.js +1 -0
  250. package/dist/public/assets/_bsxJ1YDE.js +1 -0
  251. package/dist/public/assets/_f5wPpUkq.js +1 -0
  252. package/dist/public/assets/_fPqLhj85.js +1 -0
  253. package/dist/public/assets/_g3oXW6NQ.js +1 -0
  254. package/dist/public/assets/_iHPPeFV7.js +1 -0
  255. package/dist/public/assets/_iJwEKWn1.js +1 -0
  256. package/dist/public/assets/_jtFrcV5d.js +1 -0
  257. package/dist/public/assets/{_C0Ib7MZF.js → _kQ9qYC7a.js} +1 -1
  258. package/dist/public/assets/_kQ9qYC7a.js.br +0 -0
  259. package/dist/public/assets/_kQki_UDN.js +1 -0
  260. package/dist/public/assets/_lRRU15CX.js +1 -0
  261. package/dist/public/assets/_lRRU15CX.js.br +0 -0
  262. package/dist/public/assets/_mKx7UwEC.js +1 -0
  263. package/dist/public/assets/_nnKb_fyX.js +6 -0
  264. package/dist/public/assets/_nnKb_fyX.js.br +0 -0
  265. package/dist/public/assets/_p44jCyhe.js +1 -0
  266. package/dist/public/assets/_pAx6IPLY.js +1 -0
  267. package/dist/public/assets/_psqSIrEM.js +1 -0
  268. package/dist/public/assets/{_D9r_Fn0I.js → _w_IRrfdL.js} +1 -1
  269. package/dist/public/assets/_w_IRrfdL.js.br +0 -0
  270. package/dist/public/assets/_wxSNlWQ_.js +1 -0
  271. package/dist/public/assets/_xPBJn0Hx.js +1 -0
  272. package/dist/public/assets/_xPBJn0Hx.js.br +0 -0
  273. package/dist/public/assets/_yP2G9NCR.js +1 -0
  274. package/dist/public/assets/files-view-SzdFekvc.js +2 -0
  275. package/dist/public/assets/manage-workspace-DIY2p0qY.js +2 -0
  276. package/dist/public/assets/new-dBLsQZ5Y.js +1 -0
  277. package/dist/public/assets/new-workspace-D6YmZcwM.js +2 -0
  278. package/dist/public/assets/review-view-Dr5gLqyl.js +2 -0
  279. package/dist/public/assets/settings-dBLsQZ5Y.js +1 -0
  280. package/dist/public/assets/settings-page-COg15zf5.js +2 -0
  281. package/dist/public/assets/styles-DqimleOa.css +1 -0
  282. package/dist/public/assets/styles-DqimleOa.css.br +0 -0
  283. package/dist/public/assets/w-dBLsQZ5Y.js +1 -0
  284. package/dist/public/assets/w._-BbJyr8oS.js +1 -0
  285. package/dist/public/assets/w._-Bbhvn-OV.js +1 -0
  286. package/dist/public/assets/w._-dBLsQZ5Y.js +1 -0
  287. package/dist/rtc-helper.mjs +1170 -0
  288. package/lib/preview/media.mjs +5 -4
  289. package/lib/setup/doctor.d.mts +11 -0
  290. package/lib/setup/doctor.mjs +23 -2
  291. package/lib/setup/firewall.d.mts +76 -0
  292. package/lib/setup/firewall.mjs +598 -0
  293. package/package.json +3 -2
  294. package/dist/_D1C-XIqT.js +0 -168
  295. package/dist/_HbAW5Cbt.js +0 -2
  296. package/dist/public/assets/_-5UNb9-C.js.br +0 -0
  297. package/dist/public/assets/_06rtP_SB.js +0 -1
  298. package/dist/public/assets/_14yhXek7.js +0 -1
  299. package/dist/public/assets/_14yhXek7.js.br +0 -0
  300. package/dist/public/assets/_1JXC9nFp.js.br +0 -0
  301. package/dist/public/assets/_1Yit_Y5R.js +0 -1
  302. package/dist/public/assets/_1ZPfR2B8.js +0 -6
  303. package/dist/public/assets/_1ZPfR2B8.js.br +0 -0
  304. package/dist/public/assets/_1xOByopP.js.br +0 -0
  305. package/dist/public/assets/_3aBl7SEn.js.br +0 -0
  306. package/dist/public/assets/_5aMLV2Vy.js +0 -1
  307. package/dist/public/assets/_7YrArFMB.js.br +0 -0
  308. package/dist/public/assets/_B1-W0Sn2.js.br +0 -0
  309. package/dist/public/assets/_B1D0PIz3.js.br +0 -0
  310. package/dist/public/assets/_B1agoKUa.js +0 -1
  311. package/dist/public/assets/_B3NfNm8M.js.br +0 -0
  312. package/dist/public/assets/_B7VYILLZ.js.br +0 -0
  313. package/dist/public/assets/_B7sPBy0J.js +0 -1
  314. package/dist/public/assets/_B81p6DSw.js +0 -1
  315. package/dist/public/assets/_BAkSKCkz.js +0 -1
  316. package/dist/public/assets/_BHZPTv1U.js +0 -1
  317. package/dist/public/assets/_BKHtiW96.js.br +0 -0
  318. package/dist/public/assets/_BKIx7IZP.js.br +0 -0
  319. package/dist/public/assets/_BLfzQY-3.js.br +0 -0
  320. package/dist/public/assets/_BPSTqkJn.js.br +0 -0
  321. package/dist/public/assets/_BQZOimBB.js +0 -1
  322. package/dist/public/assets/_BRQ6iQ5p.js.br +0 -0
  323. package/dist/public/assets/_BRVURc4u.js +0 -1
  324. package/dist/public/assets/_BSFJEuJX.js.br +0 -0
  325. package/dist/public/assets/_BSWN-v3P.js.br +0 -0
  326. package/dist/public/assets/_BTVAQr2c.js +0 -1
  327. package/dist/public/assets/_BUD1pBC0.js +0 -1
  328. package/dist/public/assets/_BVGzCczb.js +0 -1
  329. package/dist/public/assets/_BVQosHjY.js.br +0 -0
  330. package/dist/public/assets/_B_0C2_RO.js.br +0 -0
  331. package/dist/public/assets/_BaA31ms5.js +0 -1
  332. package/dist/public/assets/_BgCHJGlO.js +0 -1
  333. package/dist/public/assets/_BhpRLDbL.js +0 -1
  334. package/dist/public/assets/_BhpRLDbL.js.br +0 -0
  335. package/dist/public/assets/_BkKcjMAC.js +0 -1
  336. package/dist/public/assets/_BkcPY2j0.js.br +0 -0
  337. package/dist/public/assets/_BlTVd_3d.js +0 -1
  338. package/dist/public/assets/_BlqlLmEY.js +0 -1
  339. package/dist/public/assets/_BoNfxc9P.js +0 -1
  340. package/dist/public/assets/_BoPk1gXL.js +0 -1
  341. package/dist/public/assets/_BqswW9B9.js +0 -1
  342. package/dist/public/assets/_BricqzsO.js +0 -1
  343. package/dist/public/assets/_BrreckIa.js +0 -1
  344. package/dist/public/assets/_BsJZPHmz.js.br +0 -0
  345. package/dist/public/assets/_BtRYwaBb.js +0 -1
  346. package/dist/public/assets/_BvPBKjRP.js +0 -1
  347. package/dist/public/assets/_BvPBKjRP.js.br +0 -0
  348. package/dist/public/assets/_ByrrjMU9.js +0 -1
  349. package/dist/public/assets/_BzGHediB.js.br +0 -0
  350. package/dist/public/assets/_BzvTKm92.js +0 -1
  351. package/dist/public/assets/_C-EkQeP_.js.br +0 -0
  352. package/dist/public/assets/_C0Ib7MZF.js.br +0 -0
  353. package/dist/public/assets/_C2p1Z5Lf.js +0 -86
  354. package/dist/public/assets/_C2p1Z5Lf.js.br +0 -0
  355. package/dist/public/assets/_C3iiOlxd.js +0 -1
  356. package/dist/public/assets/_C81nSl09.js.br +0 -0
  357. package/dist/public/assets/_C8bqYk4J.js.br +0 -0
  358. package/dist/public/assets/_C98JZr09.js.br +0 -0
  359. package/dist/public/assets/_CB4VkmGZ.js +0 -1
  360. package/dist/public/assets/_CCVkYcN5.js.br +0 -0
  361. package/dist/public/assets/_CDY0RpYX.js.br +0 -0
  362. package/dist/public/assets/_CE2GEqMx.js +0 -1
  363. package/dist/public/assets/_CE2GEqMx.js.br +0 -0
  364. package/dist/public/assets/_CFUREq1M.js.br +0 -0
  365. package/dist/public/assets/_CHdh6bII.js +0 -1
  366. package/dist/public/assets/_CHdpLB95.js.br +0 -0
  367. package/dist/public/assets/_CKLGAGKJ.js.br +0 -0
  368. package/dist/public/assets/_CMRt2lyQ.js +0 -1
  369. package/dist/public/assets/_CN1zW1AT.js +0 -1
  370. package/dist/public/assets/_CN1zW1AT.js.br +0 -0
  371. package/dist/public/assets/_CUILmj9R.js +0 -1
  372. package/dist/public/assets/_CUhP8KQ8.js +0 -1
  373. package/dist/public/assets/_CUsrMpdL.js.br +0 -0
  374. package/dist/public/assets/_CVG0_w9T.js +0 -1
  375. package/dist/public/assets/_CWG813ur.js.br +0 -0
  376. package/dist/public/assets/_CY87Y7QL.js.br +0 -0
  377. package/dist/public/assets/_CYAsKva_.js +0 -1
  378. package/dist/public/assets/_CajKYNSY.js +0 -1
  379. package/dist/public/assets/_Cb_k_JA_.js.br +0 -0
  380. package/dist/public/assets/_Ce8PlfMD.js +0 -1
  381. package/dist/public/assets/_CfGEGt_k.js.br +0 -0
  382. package/dist/public/assets/_CfdK8EeQ.js.br +0 -0
  383. package/dist/public/assets/_CgOKmAwr.js +0 -1
  384. package/dist/public/assets/_CiYQhf81.js.br +0 -0
  385. package/dist/public/assets/_Cj9DHPRL.js +0 -1
  386. package/dist/public/assets/_ClHPjF-1.js.br +0 -0
  387. package/dist/public/assets/_Cmmdd2e3.js.br +0 -0
  388. package/dist/public/assets/_Cn9Ia4SS.js +0 -1
  389. package/dist/public/assets/_Cn9Ia4SS.js.br +0 -0
  390. package/dist/public/assets/_CnTzFbuG.js +0 -1
  391. package/dist/public/assets/_CqCenHOp.js.br +0 -0
  392. package/dist/public/assets/_CtqGSS84.js.br +0 -0
  393. package/dist/public/assets/_CttfwM-c.js +0 -1
  394. package/dist/public/assets/_CxA3Yab0.js.br +0 -0
  395. package/dist/public/assets/_Cx_aJfDp.js.br +0 -0
  396. package/dist/public/assets/_D2L_ILOW.js +0 -1
  397. package/dist/public/assets/_D47lCu0c.js +0 -1
  398. package/dist/public/assets/_D5W-uGIK.js +0 -1
  399. package/dist/public/assets/_D6BbZLrc.js +0 -1
  400. package/dist/public/assets/_D6RVeCAn.js +0 -1
  401. package/dist/public/assets/_D75V4jV-.js +0 -1
  402. package/dist/public/assets/_D9r_Fn0I.js.br +0 -0
  403. package/dist/public/assets/_DBD57l1T.js.br +0 -0
  404. package/dist/public/assets/_DCWILZgL.js +0 -1
  405. package/dist/public/assets/_DEOryr7w.js.br +0 -0
  406. package/dist/public/assets/_DF54Iz7o.js +0 -1
  407. package/dist/public/assets/_DFamU2Uj.js +0 -2
  408. package/dist/public/assets/_DFamU2Uj.js.br +0 -0
  409. package/dist/public/assets/_DHmBuyCO.js +0 -1
  410. package/dist/public/assets/_DHmBuyCO.js.br +0 -0
  411. package/dist/public/assets/_DJqEBkNd.js.br +0 -0
  412. package/dist/public/assets/_DL3w8c_p.js.br +0 -0
  413. package/dist/public/assets/_DLVL-4MP.js +0 -1
  414. package/dist/public/assets/_DM60dKRs.js.br +0 -0
  415. package/dist/public/assets/_DMJHTH74.js.br +0 -0
  416. package/dist/public/assets/_DMLv6KA6.js +0 -1
  417. package/dist/public/assets/_DQYpgyzr.js +0 -1
  418. package/dist/public/assets/_DQYpgyzr.js.br +0 -0
  419. package/dist/public/assets/_DQyjuXTi.js.br +0 -0
  420. package/dist/public/assets/_DRHCy0UF.js.br +0 -0
  421. package/dist/public/assets/_DSUBv-Bl.js.br +0 -0
  422. package/dist/public/assets/_DUFM9qLV.js +0 -1
  423. package/dist/public/assets/_DUFM9qLV.js.br +0 -0
  424. package/dist/public/assets/_DUs3ZGbj.js.br +0 -0
  425. package/dist/public/assets/_DX5u6Wvm.js.br +0 -0
  426. package/dist/public/assets/_DZvkgS3V.js.br +0 -0
  427. package/dist/public/assets/_Dbm6zAQS.js.br +0 -0
  428. package/dist/public/assets/_Ddf1gumD.js +0 -1
  429. package/dist/public/assets/_De6E9M7R.js +0 -1
  430. package/dist/public/assets/_DgWKSW-Y.js.br +0 -0
  431. package/dist/public/assets/_DhEN6T4v.js +0 -1
  432. package/dist/public/assets/_Di1ccq_2.js.br +0 -0
  433. package/dist/public/assets/_DifjKObE.js.br +0 -0
  434. package/dist/public/assets/_Dn10ABa-.js +0 -1
  435. package/dist/public/assets/_Do1ltY2a.js.br +0 -0
  436. package/dist/public/assets/_DomK7Scb.js.br +0 -0
  437. package/dist/public/assets/_DtWggCxt.js +0 -1
  438. package/dist/public/assets/_DtqqybyQ.js +0 -1
  439. package/dist/public/assets/_DvKnakqk.js.br +0 -0
  440. package/dist/public/assets/_DxD_AC3a.js.br +0 -0
  441. package/dist/public/assets/_Dxo7m9cG.js +0 -1
  442. package/dist/public/assets/_DzKW89Sx.js.br +0 -0
  443. package/dist/public/assets/_DzTHCioH.js +0 -1
  444. package/dist/public/assets/_EefWj858.js.br +0 -0
  445. package/dist/public/assets/_FlITqTCo.js.br +0 -0
  446. package/dist/public/assets/_GkEw2S0T.js +0 -1
  447. package/dist/public/assets/_HM_QqtJi.js.br +0 -0
  448. package/dist/public/assets/_HmkI4Rfn.js.br +0 -0
  449. package/dist/public/assets/_JEvx8ub4.js.br +0 -0
  450. package/dist/public/assets/_JOb8B3tz.js +0 -1
  451. package/dist/public/assets/_LEIhjFrO.js +0 -1
  452. package/dist/public/assets/_STJhwy7U.js +0 -1
  453. package/dist/public/assets/_TrcWRD8T.js.br +0 -0
  454. package/dist/public/assets/_UaKPY71M.js.br +0 -0
  455. package/dist/public/assets/_UhK3lkm0.js +0 -1
  456. package/dist/public/assets/_Zeftz3t1.js +0 -1
  457. package/dist/public/assets/__cyRVmTO.js.br +0 -0
  458. package/dist/public/assets/_awfYTHit.js +0 -1
  459. package/dist/public/assets/_dsj7vMTW.js.br +0 -0
  460. package/dist/public/assets/_eqpiOhSM.js +0 -1
  461. package/dist/public/assets/_iutZ4EDe.js.br +0 -0
  462. package/dist/public/assets/_kWQ0dtYZ.js.br +0 -0
  463. package/dist/public/assets/_knvMqXQh.js +0 -1
  464. package/dist/public/assets/_lwC7sIgC.js +0 -1
  465. package/dist/public/assets/_m2tRa0jk.js.br +0 -0
  466. package/dist/public/assets/_pXG8fRON.js.br +0 -0
  467. package/dist/public/assets/_r541ENtr.js +0 -1
  468. package/dist/public/assets/_rrUx1wn3.js +0 -1
  469. package/dist/public/assets/_tJvcu7sD.js +0 -1
  470. package/dist/public/assets/_vcLBrU2m.js.br +0 -0
  471. package/dist/public/assets/_xZC4Vm70.js +0 -1
  472. package/dist/public/assets/_yAr5r-uL.js +0 -1
  473. package/dist/public/assets/_yUmRJIJ6.js.br +0 -0
  474. package/dist/public/assets/files-view-CTadakLK.js +0 -2
  475. package/dist/public/assets/manage-workspace-HUAS6qjy.js +0 -2
  476. package/dist/public/assets/new-CirJkJFl.js +0 -1
  477. package/dist/public/assets/new-workspace-C3t1nA6z.js +0 -2
  478. package/dist/public/assets/review-view-DKPNtgmc.js +0 -2
  479. package/dist/public/assets/settings-CirJkJFl.js +0 -1
  480. package/dist/public/assets/settings-page-DH-9cN-8.js +0 -2
  481. package/dist/public/assets/styles-CIeNhVxC.css +0 -1
  482. package/dist/public/assets/styles-CIeNhVxC.css.br +0 -0
  483. package/dist/public/assets/w-CirJkJFl.js +0 -1
  484. package/dist/public/assets/w._-BnShhzdq.js +0 -1
  485. package/dist/public/assets/w._-CirJkJFl.js +0 -1
  486. package/dist/public/assets/w._-aCTYfruH.js +0 -1
package/README.md CHANGED
@@ -90,6 +90,31 @@ the same tailnet. `work setup --tailscale` does it without asking and
90
90
  as it is. A serve config already pointing at work only has its name
91
91
  allowed, and `work doctor` says which of these holds.
92
92
 
93
+ **Direct connections.** Behind a proxy, a tunnel or a relay, terminals
94
+ move to a direct WebRTC connection to this machine when it is measurably
95
+ faster than the path through the proxy (Settings → Terminal → Direct
96
+ connection: Auto by default, Always, or Off, one setting for every device). Pages,
97
+ the API and sign-in still go through your proxy; the direct path is set up
98
+ over the app's authenticated events socket, carries terminal traffic
99
+ alone, encrypted (DTLS), to UDP port `WORK_RTC_PORT` (by default the app's
100
+ port number), and ends when that login does. That port is held by a helper
101
+ process of work's own, only while direct connections are in use: it
102
+ starts at the first one and exits ten minutes after the last. Proxy-side inspection or
103
+ logging does not see terminal traffic that goes direct: turn the feature
104
+ off (per device in Settings, or `WORK_RTC=off` for the machine) where it
105
+ must. On the LAN the direct path needs nothing more; from another network
106
+ (a phone on cellular) the UDP port has to be reachable through your router.
107
+ Settings → Terminal can allow work to open it on the router when needed
108
+ (UPnP, off by default): only after a device failed to connect without it,
109
+ leased, and given back once unused. A host firewall has to let the port
110
+ in too: `work doctor` says when one likely drops it (firewalld's
111
+ FedoraServer zone does, for one), with the command that admits it, and
112
+ `work setup` offers to add that rule, named `work` so it is removed as one
113
+ (`--firewall` adds it without asking, `--no-firewall` skips the question).
114
+ macOS's firewall admits programs rather than ports, so there it is the
115
+ node the service runs that `work doctor` checks and `work setup` lets in. `WORK_RTC_STUN` names the STUN servers that find this machine's
116
+ public address (Cloudflare's by default; empty for none).
117
+
93
118
  **Opening workspace ports remotely.** The port chips in the sidebar link to
94
119
  `http://<host>:<port>`, which only works where the machine is reachable
95
120
  directly — under a tailnet name too, since `tailscale serve` has no
@@ -159,6 +184,9 @@ targeting that branch.
159
184
  | `WORK_PORT_HOSTS` | `sub` | Port-chip hostname shape: `sub` / `dash` (see above) |
160
185
  | `WORK_USER` / `WORK_HOST` | current user/host | Branch-name prefix parts |
161
186
  | `WORK_BRANCH_PREFIX` | `<user>-<host>` | Whole branch-name prefix, overriding the parts |
187
+ | `WORK_RTC` | on | `off` turns direct connections off (see Access) |
188
+ | `WORK_RTC_PORT` | the app port | UDP port of direct connections |
189
+ | `WORK_RTC_STUN` | Cloudflare's STUN | Their STUN servers, comma-separated (empty: none) |
162
190
 
163
191
  The usage panel (and `work usage`) reads plan/quota windows straight from each
164
192
  agent CLI's own credentials on disk — Claude, Codex, Cursor, Grok, and Copilot
package/bin/work.mjs CHANGED
@@ -3,7 +3,10 @@
3
3
  //
4
4
  // work setup install missing tools, sign in, install/refresh the background service
5
5
  // (--tailscale serves work on the tailnet with `tailscale serve`, which
6
- // it otherwise offers when Tailscale is logged in; --no-tailscale skips that)
6
+ // it otherwise offers when Tailscale is logged in; --no-tailscale skips that;
7
+ // --firewall adds a `work` rule for direct connections' UDP port to a host
8
+ // firewall that likely drops it, or on macOS lets the service's node in,
9
+ // which it otherwise offers; --no-firewall skips that)
7
10
  // work doctor report machine readiness (--json, --fix to install what's missing)
8
11
  // work start run the server in the foreground
9
12
  // work update upgrade the npm package and refresh the service
@@ -36,9 +39,15 @@ import {
36
39
  formatDoctor,
37
40
  setupPath,
38
41
  tailscaleProbe,
42
+ tilde,
39
43
  which,
40
44
  } from "../lib/setup/doctor.mjs";
41
45
  import { allowHost, stateText } from "../lib/setup/tailscale.mjs";
46
+ import {
47
+ applyPlan,
48
+ firewallProbe,
49
+ serviceNode,
50
+ } from "../lib/setup/firewall.mjs";
42
51
  import { installTool, repairGhHelpers } from "../lib/setup/install.mjs";
43
52
  import { bridgeCommands, bridgeIfNeeded } from "../lib/setup/bridge.mjs";
44
53
  import { dialHost, listenStream } from "../lib/setup/listen.mjs";
@@ -654,6 +663,7 @@ async function setup() {
654
663
  // Before the service is written: a tailnet name to answer goes into the
655
664
  // WORK_ALLOWED_HOSTS it carries.
656
665
  const tailnet = await tailscale(d.tailscale);
666
+ await firewall();
657
667
 
658
668
  const running = installService();
659
669
  const port = serviceEnv().PORT;
@@ -745,7 +755,11 @@ async function update() {
745
755
  sh("work", [
746
756
  "setup",
747
757
  ...(yes ? ["--yes"] : []),
748
- ...args.filter((a) => a === "--tailscale" || a === "--no-tailscale"),
758
+ ...args.filter((a) =>
759
+ ["--tailscale", "--no-tailscale", "--firewall", "--no-firewall"].includes(
760
+ a,
761
+ ),
762
+ ),
749
763
  ]);
750
764
  }
751
765
 
@@ -756,23 +770,175 @@ async function doctorCmd() {
756
770
  await fix(d);
757
771
  d = await doctor(doctorOpts());
758
772
  }
773
+ const installs = await workInstalls();
759
774
  if (args.includes("--json")) {
760
- console.log(JSON.stringify(d, null, 2));
775
+ console.log(JSON.stringify({ ...d, work: installs }, null, 2));
761
776
  } else {
762
777
  console.log(formatDoctor(d));
763
778
  const access = accessNote();
764
779
  if (access) warn(access);
780
+ for (const note of installNotes(installs)) warn(note);
765
781
  }
766
782
  // exitCode, not exit(): a pipe on macOS is written asynchronously, and
767
783
  // exiting at once can cut the JSON short for whatever reads it.
768
784
  if (!d.ready) process.exitCode = 1;
769
785
  }
770
786
 
787
+ /**
788
+ * This `work`, every other one on PATH (the first is what `work` runs),
789
+ * each with its version, and the version the running service reports
790
+ * (null when none answers). A package manager's global left behind — a
791
+ * Homebrew node's under mise's — shadows the one kept up to date, and the
792
+ * doctor it runs is then old code describing a machine it no longer knows.
793
+ */
794
+ async function workInstalls() {
795
+ const self = realpathOr(fileURLToPath(import.meta.url));
796
+ const onPath = [];
797
+ const seen = new Set();
798
+ for (const dir of (process.env.PATH || "").split(path.delimiter)) {
799
+ if (!dir) continue;
800
+ const file = path.join(dir, "work");
801
+ let real;
802
+ try {
803
+ if (!fs.statSync(file).isFile()) continue;
804
+ real = fs.realpathSync(file);
805
+ } catch {
806
+ continue;
807
+ }
808
+ if (seen.has(real)) continue;
809
+ seen.add(real);
810
+ onPath.push({ path: file, real, version: installVersion(real, file) });
811
+ }
812
+ let service = null;
813
+ try {
814
+ const res = await fetch(`${serverUrl()}/api/boot`, {
815
+ signal: AbortSignal.timeout(2000),
816
+ });
817
+ if (res.ok) service = (await res.json()).version ?? null;
818
+ } catch {}
819
+ return { self: { path: self, version: pkg.version }, onPath, service };
820
+ }
821
+
822
+ function realpathOr(file) {
823
+ try {
824
+ return fs.realpathSync(file);
825
+ } catch {
826
+ return file;
827
+ }
828
+ }
829
+
830
+ /** An install's version: an npm global's bin links into the package, whose
831
+ * package.json says; a shim (mise's) is asked. */
832
+ function installVersion(real, file) {
833
+ let dir = path.dirname(real);
834
+ for (let i = 0; i < 3; i++) {
835
+ try {
836
+ const p = JSON.parse(fs.readFileSync(path.join(dir, "package.json")));
837
+ if (p.name === "@dylanpiercey/work") return p.version ?? null;
838
+ } catch {}
839
+ dir = path.dirname(dir);
840
+ }
841
+ const out = spawnSync(file, ["version"], { encoding: "utf8", timeout: 5000 });
842
+ return /^\d+\.\d+\.\d+\S*/.exec((out.stdout || "").trim())?.[0] ?? null;
843
+ }
844
+
845
+ /** How to remove an install: the npm beside the node whose global it is. */
846
+ function removeHint(real) {
847
+ const m =
848
+ /^(.*)\/lib\/node_modules\/@dylanpiercey\/work\/bin\/work\.mjs$/.exec(real);
849
+ return m
850
+ ? `${m[1]}/bin/npm uninstall -g @dylanpiercey/work`
851
+ : `remove ${real}`;
852
+ }
853
+
854
+ function newest(versions) {
855
+ const parts = (v) => (v || "0").split(/[.-]/).map((n) => Number(n) || 0);
856
+ return versions.reduce((a, b) => {
857
+ const [x, y] = [parts(a), parts(b)];
858
+ for (let i = 0; i < 3; i++) if (x[i] !== y[i]) return x[i] > y[i] ? a : b;
859
+ return a;
860
+ }, null);
861
+ }
862
+
863
+ /** The doctor's warnings about which `work` this is. */
864
+ function installNotes({ self, onPath, service }) {
865
+ const notes = [];
866
+ if (service && service !== self.version) {
867
+ const theirs = onPath.find((w) => w.version === service);
868
+ notes.push(
869
+ `this work is ${self.version} (${tilde(self.path)}), but the running service is ${service}, so what this doctor says is an older or newer release's${theirs ? `: the service's is ${tilde(theirs.path)}` : ""}`,
870
+ );
871
+ }
872
+ if (onPath.length > 1) {
873
+ // A stray is one at another release than the service's (or, with no
874
+ // service answering, than the newest here).
875
+ const current = service ?? newest(onPath.map((w) => w.version));
876
+ const lines = onPath.map(
877
+ (w, i) =>
878
+ ` ${tilde(w.path)} → ${w.version ?? "unknown version"}${i === 0 ? " (what \`work\` runs)" : ""}${w.version === current ? "" : `\n remove: ${removeHint(w.real)}`}`,
879
+ );
880
+ notes.push(`more than one work is on PATH:\n${lines.join("\n")}`);
881
+ }
882
+ return notes;
883
+ }
884
+
771
885
  /** What the doctor's Tailscale probe checks against: the port and allowed
772
886
  * names the service runs with (or will, after `work setup`). */
773
887
  function doctorOpts() {
774
888
  const env = serviceEnv();
775
- return { port: env.PORT, allowedHosts: env.WORK_ALLOWED_HOSTS || "" };
889
+ return {
890
+ port: env.PORT,
891
+ allowedHosts: env.WORK_ALLOWED_HOSTS || "",
892
+ rtcPort: env.WORK_RTC_PORT || "",
893
+ listen: env.WORK_LISTEN,
894
+ rtc: env.WORK_RTC || "",
895
+ firewall: serviceFirewall(),
896
+ };
897
+ }
898
+
899
+ /**
900
+ * The host firewall as the service meets it. macOS's admits programs, so
901
+ * the node that counts is the one the service runs, which need not be this
902
+ * shell's: asked of the running server first (`GET /api/direct`, its own
903
+ * reading), else read here for the node its definition runs
904
+ * (`serviceNode`), else for this one's, which the result says
905
+ * (`nodeFrom`). `fresh` skips the server's few minutes of keeping it.
906
+ */
907
+ async function serviceFirewall({ fresh = false } = {}) {
908
+ const env = serviceEnv();
909
+ try {
910
+ const res = await fetch(
911
+ `${serverUrl()}/api/direct${fresh ? "?fresh=1" : ""}`,
912
+ { signal: AbortSignal.timeout(3000) },
913
+ );
914
+ const live = res.ok ? await res.json() : null;
915
+ if (live && "firewall" in live)
916
+ return (
917
+ live.firewall && {
918
+ ...live.firewall,
919
+ node: live.firewall.node ?? live.node,
920
+ nodeFrom: "service",
921
+ }
922
+ );
923
+ } catch {}
924
+ let definition = null;
925
+ try {
926
+ definition = fs.readFileSync(serviceFile(), "utf8");
927
+ } catch {}
928
+ const fromUnit =
929
+ definition &&
930
+ serviceNode(definition, { PATH: installedServiceEnv().PATH || "" });
931
+ const node = fromUnit || process.execPath;
932
+ const f = await firewallProbe({
933
+ rtcPort: env.WORK_RTC_PORT,
934
+ appPort: env.PORT,
935
+ listen: env.WORK_LISTEN,
936
+ rtc: env.WORK_RTC,
937
+ node,
938
+ });
939
+ return (
940
+ f && { ...f, node: f.node ?? node, nodeFrom: fromUnit ? "unit" : "shell" }
941
+ );
776
942
  }
777
943
 
778
944
  /** Said when the service listens beyond this machine with nothing declared
@@ -984,6 +1150,9 @@ function serviceEnv() {
984
1150
  "WORK_ALLOWED_HOSTS",
985
1151
  "WORK_LISTEN",
986
1152
  "WORK_TRUSTED_PROXIES",
1153
+ "WORK_RTC",
1154
+ "WORK_RTC_PORT",
1155
+ "WORK_RTC_STUN",
987
1156
  ]) {
988
1157
  // `in` rather than a truthy check, so `WORK_ALLOWED_HOSTS= work setup`
989
1158
  // can deliberately clear a setting the installed service still carries.
@@ -1440,6 +1609,77 @@ local Tailscale daemon to port ${port}.${ts.https === false ? "\nHTTPS certifica
1440
1609
  return allowTailnet(after.serve) ? servedAt(after.serve.url) : null;
1441
1610
  }
1442
1611
 
1612
+ /**
1613
+ * A rule in the host firewall for direct connections' UDP port (and the
1614
+ * app's TCP port too when the service listens beyond this machine), named
1615
+ * `work` so it is found and removed as one: a firewalld service enabled in
1616
+ * the active zone, or ufw rules with that comment (lib/setup/firewall.mjs);
1617
+ * on macOS, whose firewall admits programs, the service's node let in
1618
+ * (`serviceFirewall`; "Block all incoming connections" is only said).
1619
+ * Added with sudo, and only on an explicit yes, the prompt's or
1620
+ * `--firewall`: `--yes` is how the installer, `work update` and the app's
1621
+ * own update run setup unattended, and none of them asked for it. What it
1622
+ * runs is printed as it runs.
1623
+ */
1624
+ async function firewall() {
1625
+ if (args.includes("--no-firewall")) return;
1626
+ const asked = args.includes("--firewall");
1627
+ const env = serviceEnv();
1628
+ const f = await serviceFirewall();
1629
+ if (!f) {
1630
+ if (asked && env.WORK_RTC !== "off")
1631
+ log("no active host firewall: nothing to add");
1632
+ return;
1633
+ }
1634
+ if (f.admits) {
1635
+ if (asked) log(`${f.what} already admits UDP ${f.port}`);
1636
+ return;
1637
+ }
1638
+ const drops = `${f.what} ${f.exact ? "drops" : "likely drops"} UDP ${f.port}${f.why ? ` (${f.why})` : ""}, which direct connections from your other devices use`;
1639
+ if (!f.plan.length) {
1640
+ if (asked || !yes) warn(`${drops}: ${f.fix}`);
1641
+ return;
1642
+ }
1643
+ // macOS's firewall admits a program: the service's node, as found.
1644
+ const adds =
1645
+ f.kind === "macos" ? `let ${f.node} in` : "add a rule named `work`";
1646
+ if (f.kind === "macos" && f.nodeFrom === "shell")
1647
+ warn(
1648
+ `neither a running service nor its definition said which node it runs: this is for this shell's, ${f.node}`,
1649
+ );
1650
+ const input = yes || asked ? null : terminal();
1651
+ try {
1652
+ if (!asked) {
1653
+ if (!input) {
1654
+ log(`${drops}: \`work setup --firewall\` can ${adds}`);
1655
+ return;
1656
+ }
1657
+ console.log(`
1658
+ ${drops}.
1659
+ \`work setup\` can ${adds} for it, with sudo:
1660
+ ${f.plan.map((cmd) => cmd.join(" ")).join("\n ")}`);
1661
+ if (!(await confirm(input, "Add it? [y/N] "))) {
1662
+ log(
1663
+ "left the firewall as it was (work setup --firewall adds it later; --no-firewall skips this question)",
1664
+ );
1665
+ return;
1666
+ }
1667
+ }
1668
+ } finally {
1669
+ if (input && input !== process.stdin) input.destroy();
1670
+ }
1671
+ const applied = applyPlan(f.plan, log);
1672
+ if (!applied.ok) {
1673
+ warn(
1674
+ `\`${applied.failed?.join(" ")}\` failed, so the rule may be part-made: run the rest of\n ${f.plan.map((c) => c.join(" ")).join("\n ")}`,
1675
+ );
1676
+ return;
1677
+ }
1678
+ const after = await serviceFirewall({ fresh: true });
1679
+ if (after?.admits) log(`${after.what} admits UDP ${after.port}`);
1680
+ else warn(`${f.what} still looks shut to UDP ${f.port}: see work doctor`);
1681
+ }
1682
+
1443
1683
  function servedAt(url) {
1444
1684
  log(`Tailscale serves work at ${url} (tailnet only)`);
1445
1685
  return url;
@@ -0,0 +1,169 @@
1
+ var glyphBadgeNum = "_y _x";
2
+ var usageInk = {
3
+ ok: "_z",
4
+ mid: "_A",
5
+ warm: "_B",
6
+ hot: "_C"
7
+ };
8
+ var usageFill = {
9
+ ok: "_D",
10
+ mid: "_E",
11
+ warm: "_F",
12
+ hot: "_G"
13
+ };
14
+ var prTone = {
15
+ open: "_H",
16
+ draft: "_I",
17
+ merged: "_J",
18
+ closed: "_K"
19
+ };
20
+ var phaseIcon = {
21
+ working: "_X _W",
22
+ waiting: "_Y _W",
23
+ idle: "_Z _W",
24
+ off: "_0 _W"
25
+ };
26
+ var btnSm = "_7 _r";
27
+ var btnLg = "_8 _r";
28
+ var tone = {
29
+ accent: "_bb",
30
+ ok: "_bc",
31
+ warn: "_bd",
32
+ danger: "_be",
33
+ merged: "_bf",
34
+ closed: "_bg"
35
+ };
36
+ var inputLg = "_bk _bj";
37
+ var iconBtnXs = "_bo _m";
38
+ var iconBtnRow = "_bp _m";
39
+ var iconBtnLg = "_bq _m";
40
+ var chipBtn = "_br _m";
41
+ var tocDot = "_cS _U";
42
+ //#endregion
43
+ //#region src/styles/tokens.css.ts
44
+ var color = {
45
+ ok: "light-dark(#1a7f37, #57d364)",
46
+ okStrong: "light-dark(#116329, #7ee787)",
47
+ warn: "light-dark(#bf8700, #d4a72c)",
48
+ warnStrong: "light-dark(#8a5a00, #f0b84a)",
49
+ merged: "light-dark(#8250df, #a371f7)",
50
+ closed: "light-dark(#cf222e, #f85149)",
51
+ onAccent: "#fff",
52
+ onDanger: "#fff",
53
+ accentDefault: "light-dark(#4f5bd5, #6470e6)",
54
+ bg: "var(--bg)",
55
+ panel: "var(--panel)",
56
+ border: "var(--border)",
57
+ text: "var(--text)",
58
+ dim: "var(--dim)",
59
+ accent: "var(--accent)",
60
+ accentFill: "var(--accent-fill)",
61
+ accentText: "var(--accent-text)",
62
+ danger: "var(--danger)",
63
+ fieldBorder: "var(--field-border)",
64
+ raised: "color-mix(in srgb, var(--panel) 94%, var(--text))",
65
+ raisedHover: "color-mix(in srgb, var(--panel) 90%, var(--text))",
66
+ onScrim: "#fff"
67
+ };
68
+ var sans = "Inter, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif";
69
+ var iconSize = {
70
+ sm: 12,
71
+ md: 14,
72
+ lg: 16,
73
+ xl: 18
74
+ };
75
+ var toastKind = {
76
+ error: "_bJ",
77
+ warn: "_bK",
78
+ info: "_bL"
79
+ };
80
+ var toastTitle = {
81
+ error: "_bM",
82
+ warn: "_bN",
83
+ info: "_bO"
84
+ };
85
+ //#endregion
86
+ //#region src/tags/settings-agents.css.ts
87
+ var agentRow = "_d4 _dK";
88
+ var list$3 = "_dO _du _dJ _dM";
89
+ var metaChip = "_d2 _bi _bh";
90
+ var sectionCount = "_dr _9 __";
91
+ var usageNote = "_j2 _bh";
92
+ var pop$2 = "_hR _bw";
93
+ var spinner = "_hU _bm _2";
94
+ var toolLead = "_gv _dX";
95
+ var name$4 = "_gZ _dX";
96
+ var desc$1 = "_g0 _dY";
97
+ //#endregion
98
+ //#region src/tags/lsp-add-dialog.css.ts
99
+ var addDlg = "_ka _bV";
100
+ var key$1 = "_kD _kB";
101
+ var addTile = "_kF _kB";
102
+ var field$2 = "_kQ _bj";
103
+ var keyField = "_kR _kQ _bj";
104
+ var labelField = "_kS _kQ _bj";
105
+ var detailsToggle = "_hz _P";
106
+ var themeSeg = "_fS _bA";
107
+ var checkList = "_hd _ds";
108
+ //#endregion
109
+ //#region src/tags/prompt-dialog.css.ts
110
+ var promptDlg = "_bZ _bV";
111
+ var item$1 = "_b4 _m";
112
+ var glance = "_eU _m";
113
+ //#endregion
114
+ //#region src/tags/side-nav.css.ts
115
+ var iconBtn = "_cY _m";
116
+ var settingsDot = "_cZ _bz";
117
+ var notifyBtn = "_c4 _m";
118
+ //#endregion
119
+ //#region src/styles/session-pop.css.ts
120
+ var sessionPop = "_c6 _bw";
121
+ var sessionPopBtn = "_c7 _4";
122
+ var wsBtn = "_gJ _4";
123
+ var rowIcon = "_gL _bo _m";
124
+ var prChip = "_lr _v _ll";
125
+ var readyChip = "_ls _v";
126
+ var prDot = "_lu _lt";
127
+ //#endregion
128
+ //#region src/tags/port-chip.css.ts
129
+ var port = "_nm _v _ll";
130
+ var open = "_k0 _4";
131
+ var action = "_k4 _br _m";
132
+ var toggle = "_e6 _P";
133
+ var fold = "_e7 _dL";
134
+ var item = "_jO _4";
135
+ var menu = "_mj _c6 _bw";
136
+ var menuItem = "_ml _4";
137
+ var findBtn$1 = "_iX _h0 _bp _m";
138
+ var tool = "_h0 _bp _m";
139
+ var pop$1 = "_lh _c6 _bw";
140
+ var fileFilter = "_nq _o";
141
+ var findInput = "_ew _o";
142
+ var keybarIconBtn = "_eF _br _m";
143
+ var repoTitle = "_lZ _L";
144
+ var input = "_b9 _o";
145
+ var group = "_cb _P";
146
+ var hint$1 = "_lQ _9 _M";
147
+ var sheetDir = "_mI _by";
148
+ var upBtn = "_ih _bp _m";
149
+ var findBtn = "_il _h0 _bp _m";
150
+ var goBtn = "_im _h0 _bp _m";
151
+ var note = "_lk _bh";
152
+ //#endregion
153
+ //#region src/tags/manage-workspace.css.ts
154
+ var procCmd = "_gi _dX";
155
+ var factCopy = "_gp _br _m";
156
+ var resultRow = "_kk _4";
157
+ var resultBranch = "_kl _d2 _bi _bh _bo _m";
158
+ var urlAction = "_km _d2 _bi _bh _d3";
159
+ var curRow = "_e1 _dR";
160
+ //#endregion
161
+ //#region src/tags/join-dialog.css.ts
162
+ var dlg = "_k7 _bV";
163
+ var hint = "_k8 _bh";
164
+ var kbtn = "_cu _bq _m";
165
+ var repeat = "_cx _cw";
166
+ var dpadUser = "_cA _cw";
167
+ var dpadEsc = "_cB _cw";
168
+ //#endregion
169
+ export { field$2 as $, item as A, tone as At, wsBtn as B, keybarIconBtn as C, glyphBadgeNum as Ct, findBtn$1 as D, inputLg as Dt, tool as E, iconBtnXs as Et, port as F, settingsDot as G, sessionPopBtn as H, prChip as I, promptDlg as J, glance as K, prDot as L, toggle as M, usageInk as Mt, action as N, menu as O, phaseIcon as Ot, open as P, addTile as Q, readyChip as R, findInput as S, chipBtn as St, pop$1 as T, iconBtnRow as Tt, iconBtn as U, sessionPop as V, notifyBtn as W, themeSeg as X, checkList as Y, detailsToggle as Z, sheetDir as _, iconSize as _t, dlg as a, name$4 as at, input as b, btnLg as bt, resultBranch as c, spinner as ct, factCopy as d, list$3 as dt, key$1 as et, procCmd as f, metaChip as ft, upBtn as g, color as gt, goBtn as h, toastTitle as ht, repeat as i, desc$1 as it, fold as j, usageFill as jt, menuItem as k, prTone as kt, resultRow as l, usageNote as lt, findBtn as m, toastKind as mt, dpadUser as n, labelField as nt, hint as o, toolLead as ot, note as p, agentRow as pt, item$1 as q, kbtn as r, addDlg as rt, curRow as s, pop$2 as st, dpadEsc as t, keyField as tt, urlAction as u, sectionCount as ut, hint$1 as v, sans as vt, fileFilter as w, iconBtnLg as wt, repoTitle as x, btnSm as xt, group as y, tocDot as yt, rowIcon as z };