@dylanpiercey/work 0.1.0 → 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 (522) hide show
  1. package/README.md +45 -5
  2. package/bin/work.mjs +449 -10
  3. package/dist/_BO3_WJb5.js +169 -0
  4. package/dist/{_Bq7to522.js → _CzOrFOdN.js} +527 -56
  5. package/dist/_DiOv9AKj.js +2 -0
  6. package/dist/index.mjs +8916 -7891
  7. package/dist/public/assets/{_Dytf99zx.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/{_DrIgZJzN.js → _B0FtZL3L.js} +1 -1
  11. package/dist/public/assets/_B0FtZL3L.js.br +0 -0
  12. package/dist/public/assets/{_C0_s45qg.js → _B0rj5kOY.js} +1 -1
  13. package/dist/public/assets/_B0rj5kOY.js.br +0 -0
  14. package/dist/public/assets/{_BNW5Jiec.js → _B3aw0q8p.js} +1 -1
  15. package/dist/public/assets/_B3aw0q8p.js.br +0 -0
  16. package/dist/public/assets/{_Bhx319Hi.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/{_D4q8XSMI.js → _BBk5_vEh.js} +1 -1
  23. package/dist/public/assets/_BBk5_vEh.js.br +0 -0
  24. package/dist/public/assets/_BCS_gQxR.js +15 -0
  25. package/dist/public/assets/_BCS_gQxR.js.br +0 -0
  26. package/dist/public/assets/{_BvXp6HpX.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/{_SGDxiwE1.js → _BEtl4C9q.js} +1 -1
  30. package/dist/public/assets/_BEtl4C9q.js.br +0 -0
  31. package/dist/public/assets/{_DDl8KSWJ.js → _BJZwk-Pf.js} +1 -1
  32. package/dist/public/assets/_BJZwk-Pf.js.br +0 -0
  33. package/dist/public/assets/{_CpjSCB1I.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/{_CEXHZd73.js → _BODl5Jdc.js} +1 -1
  37. package/dist/public/assets/_BODl5Jdc.js.br +0 -0
  38. package/dist/public/assets/{_De7P3jUH.js → _BOe3voZI.js} +1 -1
  39. package/dist/public/assets/_BOe3voZI.js.br +0 -0
  40. package/dist/public/assets/{_eoa1EOU-.js → _BPW-OoaM.js} +1 -1
  41. package/dist/public/assets/_BPW-OoaM.js.br +0 -0
  42. package/dist/public/assets/{_BE_Jyvqd.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/{_Bp8-V8yl.js → _BU4lH-F3.js} +1 -1
  46. package/dist/public/assets/_BU4lH-F3.js.br +0 -0
  47. package/dist/public/assets/{_wcshV0sZ.js → _BVGSrb9C.js} +1 -1
  48. package/dist/public/assets/_BVGSrb9C.js.br +0 -0
  49. package/dist/public/assets/{_CTINBWaG.js → _BXyDScMX.js} +1 -1
  50. package/dist/public/assets/_BXyDScMX.js.br +0 -0
  51. package/dist/public/assets/{_Bm4SHrNp.js → _BZXtyNwD.js} +1 -1
  52. package/dist/public/assets/_BZXtyNwD.js.br +0 -0
  53. package/dist/public/assets/{_DfI982PI.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/{_CHuLFr1f.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/{_CAkPJLeF.js → _BfDaM2KU.js} +1 -1
  60. package/dist/public/assets/{_CAkPJLeF.js.br → _BfDaM2KU.js.br} +0 -0
  61. package/dist/public/assets/_Bk1naXp4.js +1 -0
  62. package/dist/public/assets/{_BOGkzMx9.js → _BkNKadGd.js} +1 -1
  63. package/dist/public/assets/_BkNKadGd.js.br +0 -0
  64. package/dist/public/assets/_BkztnqUW.js +1 -0
  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/{_BDa-iwuj.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/{_ClldMY37.js → _Byfemjjt.js} +1 -1
  78. package/dist/public/assets/_Byfemjjt.js.br +0 -0
  79. package/dist/public/assets/{_MCwIJAuJ.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/{_D4quFMVQ.js → _C-UGjoFi.js} +1 -1
  83. package/dist/public/assets/_C-UGjoFi.js.br +0 -0
  84. package/dist/public/assets/{_wXDh-Z2N.js → _C-jXvDAe.js} +1 -1
  85. package/dist/public/assets/_C-jXvDAe.js.br +0 -0
  86. package/dist/public/assets/{_Ct3RF80L.js → _C2b1kmvc.js} +1 -1
  87. package/dist/public/assets/_C2b1kmvc.js.br +0 -0
  88. package/dist/public/assets/{_CIb7xw_1.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/{_C654p96Z.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/{_CamWDaoG.js → _CB9BGKKP.js} +1 -1
  95. package/dist/public/assets/_CB9BGKKP.js.br +0 -0
  96. package/dist/public/assets/{_bcsuBP7T.js → _CD44YUtO.js} +1 -1
  97. package/dist/public/assets/_CD44YUtO.js.br +0 -0
  98. package/dist/public/assets/{_D6kktUFn.js → _CEXagH_p.js} +1 -1
  99. package/dist/public/assets/_CEXagH_p.js.br +0 -0
  100. package/dist/public/assets/_CFOiLJdu.js +1 -0
  101. package/dist/public/assets/_CFOiLJdu.js.br +0 -0
  102. package/dist/public/assets/{_D1uRW1qz.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/{_DC-78WeM.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/_CK0tdQ6M.js +1591 -0
  109. package/dist/public/assets/_CK0tdQ6M.js.br +0 -0
  110. package/dist/public/assets/{_CMSBfO6u.js → _CKcab_6c.js} +1 -1
  111. package/dist/public/assets/_CKcab_6c.js.br +0 -0
  112. package/dist/public/assets/{_8G2Mv7jG.js → _CKpSd2DN.js} +1 -1
  113. package/dist/public/assets/_CKpSd2DN.js.br +0 -0
  114. package/dist/public/assets/{_zSAfqXcm.js → _CKy2HduV.js} +1 -1
  115. package/dist/public/assets/_CKy2HduV.js.br +0 -0
  116. package/dist/public/assets/{_BUvqweu0.js → _CLikwAg5.js} +1 -1
  117. package/dist/public/assets/_CLikwAg5.js.br +0 -0
  118. package/dist/public/assets/{_CxAPL49a.js → _CM-AIl7T.js} +1 -1
  119. package/dist/public/assets/_CM-AIl7T.js.br +0 -0
  120. package/dist/public/assets/_CMwrJ1ju.js +1 -0
  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/{_BwP07uVS.js → _CUq2djIT.js} +1 -1
  125. package/dist/public/assets/_CUq2djIT.js.br +0 -0
  126. package/dist/public/assets/{_DFWOMF-B.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/{_d5u7EI97.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/{_8dvK2NDJ.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/{_CZ_OWtIT.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/{_9kX9D09B.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/{_C_37_B6u.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/{_DcMIlvz-.js → _CtIpOiCk.js} +1 -1
  149. package/dist/public/assets/_CtIpOiCk.js.br +0 -0
  150. package/dist/public/assets/{_D4rOX-Fa.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/{_Dd6X3e7w.js → _Cy_g0woP.js} +1 -1
  156. package/dist/public/assets/_Cy_g0woP.js.br +0 -0
  157. package/dist/public/assets/{_COcePo2y.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/{_B582D2rg.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/{_D0aoEFRx.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/{_BpoeUr5j.js → _D81sIY4I.js} +1 -1
  170. package/dist/public/assets/_D81sIY4I.js.br +0 -0
  171. package/dist/public/assets/{_D9sS4J_w.js → _D8Opg0DA.js} +1 -1
  172. package/dist/public/assets/_D8Opg0DA.js.br +0 -0
  173. package/dist/public/assets/{_B7GwDeKK.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/{_xyw_DS5P.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/{_BywcP-As.js → _DMEtxMrc.js} +1 -1
  182. package/dist/public/assets/_DMEtxMrc.js.br +0 -0
  183. package/dist/public/assets/{_DqhphdU4.js → _DOr6ubI-.js} +1 -1
  184. package/dist/public/assets/_DOr6ubI-.js.br +0 -0
  185. package/dist/public/assets/{_ch_yXAap.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/{_CEJUcePr.js → _DWrhUk5T.js} +1 -1
  189. package/dist/public/assets/_DWrhUk5T.js.br +0 -0
  190. package/dist/public/assets/{_Bv3qNE1b.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/{_CUXajOKj.js → _DcktT8yN.js} +1 -1
  194. package/dist/public/assets/_DcktT8yN.js.br +0 -0
  195. package/dist/public/assets/{_D2un443j.js → _Ddc9Y9a_.js} +1 -1
  196. package/dist/public/assets/_Ddc9Y9a_.js.br +0 -0
  197. package/dist/public/assets/{_BBWaxDkO.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/{_Bx1CW-sF.js → _Dl46-33v.js} +1 -1
  206. package/dist/public/assets/_Dl46-33v.js.br +0 -0
  207. package/dist/public/assets/_DlvIY6aE.js +1 -0
  208. package/dist/public/assets/{_DxEm-Gwj.js → _Dmi6AQP3.js} +1 -1
  209. package/dist/public/assets/_Dmi6AQP3.js.br +0 -0
  210. package/dist/public/assets/{_BbbOvNRH.js → _Dmj0vHNs.js} +1 -1
  211. package/dist/public/assets/{_BbbOvNRH.js.br → _Dmj0vHNs.js.br} +0 -0
  212. package/dist/public/assets/{_DSVLaMWS.js → _DnYboxB9.js} +1 -1
  213. package/dist/public/assets/_DnYboxB9.js.br +0 -0
  214. package/dist/public/assets/{_Cz5BPBG8.js → _Do6MGycg.js} +1 -1
  215. package/dist/public/assets/_Do6MGycg.js.br +0 -0
  216. package/dist/public/assets/{_DkCaEf_h.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/{_Dp3IZdH8.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/{_DaMVRI8f.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/{_Bf8WYPfh.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/{_j2tDSMvo.js → _VM9JbUGP.js} +1 -1
  242. package/dist/public/assets/_VM9JbUGP.js.br +0 -0
  243. package/dist/public/assets/_YOjtJWMK.js +1 -0
  244. package/dist/public/assets/_YOjtJWMK.js.br +10 -0
  245. package/dist/public/assets/_YPt61819.js +1 -0
  246. package/dist/public/assets/{_DbvaGqOl.js → _Zh4-3iG-.js} +1 -1
  247. package/dist/public/assets/_Zh4-3iG-.js.br +0 -0
  248. package/dist/public/assets/{_D4dJ2qEE.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/{_Bv3e3rg8.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/{_CyBCIknf.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/app-shell-CVYlktwa.css +1 -0
  275. package/dist/public/assets/app-shell-CVYlktwa.css.br +0 -0
  276. package/dist/public/assets/files-view-SzdFekvc.js +2 -0
  277. package/dist/public/assets/manage-workspace-DIY2p0qY.js +2 -0
  278. package/dist/public/assets/new-dBLsQZ5Y.js +1 -0
  279. package/dist/public/assets/new-workspace-D6YmZcwM.js +2 -0
  280. package/dist/public/assets/review-view-Dr5gLqyl.js +2 -0
  281. package/dist/public/assets/settings-dBLsQZ5Y.js +1 -0
  282. package/dist/public/assets/settings-page-COg15zf5.js +2 -0
  283. package/dist/public/assets/styles-DqimleOa.css +1 -0
  284. package/dist/public/assets/styles-DqimleOa.css.br +0 -0
  285. package/dist/public/assets/w-dBLsQZ5Y.js +1 -0
  286. package/dist/public/assets/w._-BbJyr8oS.js +1 -0
  287. package/dist/public/assets/w._-Bbhvn-OV.js +1 -0
  288. package/dist/public/assets/w._-dBLsQZ5Y.js +1 -0
  289. package/dist/rtc-helper.mjs +1170 -0
  290. package/lib/preview/media.mjs +5 -4
  291. package/lib/setup/doctor.d.mts +23 -1
  292. package/lib/setup/doctor.mjs +75 -9
  293. package/lib/setup/firewall.d.mts +76 -0
  294. package/lib/setup/firewall.mjs +598 -0
  295. package/lib/setup/tailscale.d.mts +53 -0
  296. package/lib/setup/tailscale.mjs +179 -0
  297. package/package.json +3 -2
  298. package/dist/_CkwTsHKB.js +0 -2
  299. package/dist/public/assets/_1RHVsAcK.js +0 -1
  300. package/dist/public/assets/_4CShjaLP.js +0 -1
  301. package/dist/public/assets/_68JtNDO1.js +0 -1
  302. package/dist/public/assets/_8G2Mv7jG.js.br +0 -0
  303. package/dist/public/assets/_8dvK2NDJ.js.br +0 -0
  304. package/dist/public/assets/_94L2SIJF.js +0 -1
  305. package/dist/public/assets/_9AnDb3YH.js +0 -1
  306. package/dist/public/assets/_9kX9D09B.js.br +0 -0
  307. package/dist/public/assets/_9lErVegn.js +0 -1
  308. package/dist/public/assets/_B0oyGUU5.js +0 -1
  309. package/dist/public/assets/_B0oyGUU5.js.br +0 -0
  310. package/dist/public/assets/_B1mPnLlp.js +0 -1
  311. package/dist/public/assets/_B4fi2SSA.js +0 -1
  312. package/dist/public/assets/_B7Qx25UP.js +0 -1
  313. package/dist/public/assets/_B7b8EVjA.js +0 -1
  314. package/dist/public/assets/_BBWaxDkO.js.br +0 -0
  315. package/dist/public/assets/_BDa-iwuj.js.br +0 -0
  316. package/dist/public/assets/_BEKHKNmM.js +0 -1
  317. package/dist/public/assets/_BE_Jyvqd.js.br +0 -0
  318. package/dist/public/assets/_BFU-kJkk.js +0 -1
  319. package/dist/public/assets/_BIJ2O2oU.js +0 -1
  320. package/dist/public/assets/_BJ59XAZ9.js +0 -1
  321. package/dist/public/assets/_BKqRYfOI.js +0 -15
  322. package/dist/public/assets/_BKqRYfOI.js.br +0 -0
  323. package/dist/public/assets/_BKr9Dzz1.js +0 -1
  324. package/dist/public/assets/_BN7xvxS_.js +0 -1
  325. package/dist/public/assets/_BNQTVBlH.js +0 -1
  326. package/dist/public/assets/_BNW5Jiec.js.br +0 -0
  327. package/dist/public/assets/_BOGkzMx9.js.br +0 -0
  328. package/dist/public/assets/_BUEpqQ_m.js +0 -1
  329. package/dist/public/assets/_BUvqweu0.js.br +0 -0
  330. package/dist/public/assets/_BZKB4fhr.js +0 -1
  331. package/dist/public/assets/_BZKB4fhr.js.br +0 -0
  332. package/dist/public/assets/_BZo9BjDF.js +0 -1
  333. package/dist/public/assets/_BdUNnSlC.js +0 -1
  334. package/dist/public/assets/_Bf8WYPfh.js.br +0 -0
  335. package/dist/public/assets/_Bhx319Hi.js.br +0 -0
  336. package/dist/public/assets/_Bm4SHrNp.js.br +0 -0
  337. package/dist/public/assets/_Bmrqq8Ro.js +0 -2
  338. package/dist/public/assets/_Bmrqq8Ro.js.br +0 -0
  339. package/dist/public/assets/_BnHZ6Npj.js +0 -1
  340. package/dist/public/assets/_BoDxRJLS.js +0 -1
  341. package/dist/public/assets/_BoDxRJLS.js.br +0 -0
  342. package/dist/public/assets/_BoPk1gXL.js +0 -1
  343. package/dist/public/assets/_Bo_Ru664.js +0 -1
  344. package/dist/public/assets/_Bp8-V8yl.js.br +0 -0
  345. package/dist/public/assets/_BpoeUr5j.js.br +0 -0
  346. package/dist/public/assets/_Bq2G_Tid.js +0 -1
  347. package/dist/public/assets/_BsyoLB_D.js +0 -1
  348. package/dist/public/assets/_Bv3e3rg8.js.br +0 -0
  349. package/dist/public/assets/_BvXp6HpX.js.br +0 -0
  350. package/dist/public/assets/_BwP07uVS.js.br +0 -0
  351. package/dist/public/assets/_Bx1CW-sF.js.br +0 -0
  352. package/dist/public/assets/_BywcP-As.js.br +0 -0
  353. package/dist/public/assets/_Bzgtwt3G.js +0 -1
  354. package/dist/public/assets/_Bzgtwt3G.js.br +0 -0
  355. package/dist/public/assets/_C0_s45qg.js.br +0 -0
  356. package/dist/public/assets/_C0ePgF6b.js +0 -1
  357. package/dist/public/assets/_C0oVtTqO.js +0 -1
  358. package/dist/public/assets/_C0oVtTqO.js.br +0 -0
  359. package/dist/public/assets/_C654p96Z.js.br +0 -0
  360. package/dist/public/assets/_C8_1Y2-z.js +0 -1
  361. package/dist/public/assets/_C8_1Y2-z.js.br +0 -0
  362. package/dist/public/assets/_C8v1AZFP.js +0 -1
  363. package/dist/public/assets/_CB0D5cRH.js +0 -1
  364. package/dist/public/assets/_CD05JUTh.js +0 -1
  365. package/dist/public/assets/_CEJUcePr.js.br +0 -0
  366. package/dist/public/assets/_CEXHZd73.js.br +0 -0
  367. package/dist/public/assets/_CHcUMVR7.js +0 -1
  368. package/dist/public/assets/_CHuLFr1f.js.br +0 -0
  369. package/dist/public/assets/_CIb7xw_1.js.br +0 -0
  370. package/dist/public/assets/_CMSBfO6u.js.br +0 -0
  371. package/dist/public/assets/_CN7GPyBo.js +0 -1
  372. package/dist/public/assets/_COcePo2y.js.br +0 -0
  373. package/dist/public/assets/_CTINBWaG.js.br +0 -0
  374. package/dist/public/assets/_CTWrnAbz.js +0 -1
  375. package/dist/public/assets/_CUXajOKj.js.br +0 -0
  376. package/dist/public/assets/_CVru3vzC.js +0 -1
  377. package/dist/public/assets/_CYjE__ml.js +0 -1
  378. package/dist/public/assets/_CYjE__ml.js.br +0 -0
  379. package/dist/public/assets/_CZ_OWtIT.js.br +0 -0
  380. package/dist/public/assets/_C_37_B6u.js.br +0 -0
  381. package/dist/public/assets/_C_CIQL7J.js +0 -1
  382. package/dist/public/assets/_C_CIQL7J.js.br +0 -0
  383. package/dist/public/assets/_C_WdpYbK.js +0 -1
  384. package/dist/public/assets/_CaiH3VN9.js +0 -1
  385. package/dist/public/assets/_CamWDaoG.js.br +0 -0
  386. package/dist/public/assets/_CdDElA0V.js +0 -1
  387. package/dist/public/assets/_CfnsClzZ.js +0 -1
  388. package/dist/public/assets/_Cgo1fRhJ.js +0 -1
  389. package/dist/public/assets/_Cgo1fRhJ.js.br +0 -0
  390. package/dist/public/assets/_CjhGrlf3.js +0 -1
  391. package/dist/public/assets/_CjlbL4C_.js +0 -1
  392. package/dist/public/assets/_CjogTUXK.js +0 -1
  393. package/dist/public/assets/_ClldMY37.js.br +0 -0
  394. package/dist/public/assets/_CmFq6Gtp.js +0 -1
  395. package/dist/public/assets/_CoAPOKiP.js +0 -1
  396. package/dist/public/assets/_CoUUgh9P.js +0 -1
  397. package/dist/public/assets/_CpjSCB1I.js.br +0 -0
  398. package/dist/public/assets/_Ct3RF80L.js.br +0 -0
  399. package/dist/public/assets/_CtYy5eZs.js +0 -1
  400. package/dist/public/assets/_CxAPL49a.js.br +0 -0
  401. package/dist/public/assets/_CyBCIknf.js.br +0 -0
  402. package/dist/public/assets/_Cz5BPBG8.js.br +0 -0
  403. package/dist/public/assets/_D-eEFXaI.js +0 -1
  404. package/dist/public/assets/_D0aoEFRx.js.br +0 -0
  405. package/dist/public/assets/_D1uRW1qz.js.br +0 -0
  406. package/dist/public/assets/_D2oIr2T2.js +0 -1
  407. package/dist/public/assets/_D2un443j.js.br +0 -0
  408. package/dist/public/assets/_D3MPx4-f.js +0 -1
  409. package/dist/public/assets/_D4q8XSMI.js.br +0 -0
  410. package/dist/public/assets/_D4quFMVQ.js.br +0 -0
  411. package/dist/public/assets/_D4rOX-Fa.js.br +0 -0
  412. package/dist/public/assets/_D5edrSyA.js +0 -1
  413. package/dist/public/assets/_D6kktUFn.js.br +0 -0
  414. package/dist/public/assets/_D80-qtVY.js +0 -1
  415. package/dist/public/assets/_D9-3EVA4.js +0 -1
  416. package/dist/public/assets/_D9sS4J_w.js.br +0 -0
  417. package/dist/public/assets/_DBLpxTDi.js +0 -1
  418. package/dist/public/assets/_DByHQ7nW.js +0 -1591
  419. package/dist/public/assets/_DByHQ7nW.js.br +0 -0
  420. package/dist/public/assets/_DC-78WeM.js.br +0 -0
  421. package/dist/public/assets/_DDl8KSWJ.js.br +0 -0
  422. package/dist/public/assets/_DFWOMF-B.js.br +0 -0
  423. package/dist/public/assets/_DKb-rt9n.js +0 -1
  424. package/dist/public/assets/_DMnSJCF_.js +0 -1
  425. package/dist/public/assets/_DOOIlrPh.js +0 -1
  426. package/dist/public/assets/_DPW-0yKP.js +0 -1
  427. package/dist/public/assets/_DR3BmvWU.js +0 -1
  428. package/dist/public/assets/_DSVLaMWS.js.br +0 -0
  429. package/dist/public/assets/_DYNGNKLk.js +0 -1
  430. package/dist/public/assets/_DZnEgCbj.js +0 -1
  431. package/dist/public/assets/_DaMVRI8f.js.br +0 -0
  432. package/dist/public/assets/_DbvaGqOl.js.br +0 -0
  433. package/dist/public/assets/_DcMIlvz-.js.br +0 -0
  434. package/dist/public/assets/_Dd6X3e7w.js.br +0 -0
  435. package/dist/public/assets/_De7P3jUH.js.br +0 -0
  436. package/dist/public/assets/_DeiFEAar.js +0 -1
  437. package/dist/public/assets/_DfI982PI.js.br +0 -0
  438. package/dist/public/assets/_DfZ6emcw.js +0 -1
  439. package/dist/public/assets/_Dj1lZ1pa.js +0 -86
  440. package/dist/public/assets/_Dj1lZ1pa.js.br +0 -0
  441. package/dist/public/assets/_DkCaEf_h.js.br +0 -0
  442. package/dist/public/assets/_DonAis0J.js +0 -1
  443. package/dist/public/assets/_Dp3IZdH8.js.br +0 -0
  444. package/dist/public/assets/_DqYih4xk.js +0 -1
  445. package/dist/public/assets/_DqYih4xk.js.br +0 -0
  446. package/dist/public/assets/_DqhphdU4.js.br +0 -0
  447. package/dist/public/assets/_DrIgZJzN.js.br +0 -0
  448. package/dist/public/assets/_Dt4hHR05.js +0 -1
  449. package/dist/public/assets/_DtTbTraA.js +0 -1
  450. package/dist/public/assets/_DwMxAJKP.js +0 -1
  451. package/dist/public/assets/_DxEm-Gwj.js.br +0 -0
  452. package/dist/public/assets/_Dytf99zx.js.br +0 -0
  453. package/dist/public/assets/_EAgv5jR9.js +0 -1
  454. package/dist/public/assets/_Iecpd0kS.js +0 -1
  455. package/dist/public/assets/_Iecpd0kS.js.br +0 -0
  456. package/dist/public/assets/_MCwIJAuJ.js.br +0 -0
  457. package/dist/public/assets/_NM79Lu3L.js +0 -6
  458. package/dist/public/assets/_NM79Lu3L.js.br +0 -0
  459. package/dist/public/assets/_QpNKKuS9.js +0 -1
  460. package/dist/public/assets/_SGDxiwE1.js.br +0 -0
  461. package/dist/public/assets/_TA8pE7z9.js +0 -1
  462. package/dist/public/assets/_bE4sNDeU.js +0 -1
  463. package/dist/public/assets/_bcsuBP7T.js.br +0 -0
  464. package/dist/public/assets/_cdcAU4yY.js +0 -1
  465. package/dist/public/assets/_ch_yXAap.js.br +0 -0
  466. package/dist/public/assets/_d5u7EI97.js.br +0 -0
  467. package/dist/public/assets/_eoa1EOU-.js.br +0 -0
  468. package/dist/public/assets/_j2tDSMvo.js.br +0 -0
  469. package/dist/public/assets/_jNhIFgbc.js +0 -1
  470. package/dist/public/assets/_kDYiTaag.js +0 -1
  471. package/dist/public/assets/_lNMVVbUx.js +0 -1
  472. package/dist/public/assets/_nwJ7Hu3S.js +0 -1
  473. package/dist/public/assets/_tmDtUACa.js +0 -1
  474. package/dist/public/assets/_tmDtUACa.js.br +0 -0
  475. package/dist/public/assets/_wXDh-Z2N.js.br +0 -0
  476. package/dist/public/assets/_wcshV0sZ.js.br +0 -0
  477. package/dist/public/assets/_x-NwqgCn.js +0 -1
  478. package/dist/public/assets/_xyw_DS5P.js.br +0 -0
  479. package/dist/public/assets/_zSAfqXcm.js.br +0 -0
  480. package/dist/public/assets/app-shell-ChQoVC5b.css +0 -1
  481. package/dist/public/assets/app-shell-ChQoVC5b.css.br +0 -0
  482. package/dist/public/assets/files-view-CLtLp_BW.js +0 -2
  483. package/dist/public/assets/files-view-CNHQapdI.css +0 -1
  484. package/dist/public/assets/files-view-CNHQapdI.css.br +0 -0
  485. package/dist/public/assets/group.css.ts-BG82htKb.css +0 -1
  486. package/dist/public/assets/group.css.ts-BG82htKb.css.br +0 -0
  487. package/dist/public/assets/icon-folder-DJOHuEpD.css +0 -1
  488. package/dist/public/assets/icon-folder-DJOHuEpD.css.br +0 -0
  489. package/dist/public/assets/icon-search-DsJuFXUJ.css +0 -1
  490. package/dist/public/assets/icon-search-DsJuFXUJ.css.br +0 -0
  491. package/dist/public/assets/manage-workspace-NBcFDyrB.js +0 -2
  492. package/dist/public/assets/manage-workspace-f_Np32TD.css +0 -1
  493. package/dist/public/assets/modal-view-KVNBpNYi.css +0 -1
  494. package/dist/public/assets/modal-view-KVNBpNYi.css.br +0 -0
  495. package/dist/public/assets/new-DHI77GvL.js +0 -1
  496. package/dist/public/assets/new-workspace-BFE-HpD_.css +0 -1
  497. package/dist/public/assets/new-workspace-BFE-HpD_.css.br +0 -0
  498. package/dist/public/assets/new-workspace-BRzimdd5.js +0 -2
  499. package/dist/public/assets/port-chip-CUUIDOVM.css +0 -1
  500. package/dist/public/assets/port-chip-CUUIDOVM.css.br +0 -0
  501. package/dist/public/assets/prompt-dialog-BGs6RXOV.css +0 -1
  502. package/dist/public/assets/prompt-dialog-BGs6RXOV.css.br +0 -0
  503. package/dist/public/assets/quick-open-Gx4so1bl.css +0 -1
  504. package/dist/public/assets/quick-open-Gx4so1bl.css.br +0 -0
  505. package/dist/public/assets/repo-picker-CUhd0vJN.css +0 -1
  506. package/dist/public/assets/repo-picker-CUhd0vJN.css.br +0 -4
  507. package/dist/public/assets/review-view-DFEK9VBa.js +0 -2
  508. package/dist/public/assets/review-view-deUY3OE5.css +0 -1
  509. package/dist/public/assets/review-view-deUY3OE5.css.br +0 -0
  510. package/dist/public/assets/section-CziSOSBR.css +0 -1
  511. package/dist/public/assets/section-CziSOSBR.css.br +0 -0
  512. package/dist/public/assets/settings-DHI77GvL.js +0 -1
  513. package/dist/public/assets/settings-page-OOtPOzIn.js +0 -2
  514. package/dist/public/assets/settings-page-wZhd7FLi.css +0 -1
  515. package/dist/public/assets/settings-page-wZhd7FLi.css.br +0 -0
  516. package/dist/public/assets/skill-row-BoCyFIXg.css +0 -1
  517. package/dist/public/assets/sso-auth-DV76tTpE.css +0 -1
  518. package/dist/public/assets/sso-auth-DV76tTpE.css.br +0 -0
  519. package/dist/public/assets/w-DHI77GvL.js +0 -1
  520. package/dist/public/assets/w._-DHI77GvL.js +0 -1
  521. package/dist/public/assets/w._-DsTgq3-C.js +0 -1
  522. package/dist/public/assets/w._-igEOSPR-.js +0 -1
@@ -0,0 +1,598 @@
1
+ // The host firewall in front of direct connections' UDP port
2
+ // (src/server/rtc): what `work doctor` says about it, the rule `work setup`
3
+ // offers to add, and what a page whose direct path never connected is
4
+ // told. Read without root: firewalld's daemon says which zones are active
5
+ // and which services it knows, and a zone's own definition is world-readable
6
+ // where it was never changed (its shipped copy); ufw's switch and default
7
+ // policy are in world-readable files; macOS's socketfilterfw and codesign
8
+ // answer any user. What root alone can read — a zone as changed, ufw's
9
+ // rules — makes the answer "likely", not "does". macOS's firewall admits
10
+ // programs, not ports, so its answer is for one node: the one the service
11
+ // runs (`node`), which the CLI asks the running server for, or reads from
12
+ // the service's definition (`serviceNode`). Plain node, no dependencies.
13
+ import { execFile, spawnSync } from "node:child_process";
14
+ import fs from "node:fs";
15
+ import path from "node:path";
16
+
17
+ /** The name work's own rule goes by: a firewalld service, a ufw comment. */
18
+ export const RULE = "work";
19
+
20
+ const SOCKETFILTERFW = "usr/libexec/ApplicationFirewall/socketfilterfw";
21
+ const CODESIGN = "usr/bin/codesign";
22
+
23
+ /**
24
+ * The active host firewall and whether it admits UDP `rtcPort`, or null
25
+ * when none is active (or direct connections are off, `rtc` = "off").
26
+ * `appPort` joins the rule when `listen` is beyond this machine, since the
27
+ * app's own TCP port then has to be reachable too. `node` is the program
28
+ * macOS's firewall is asked about (this process's by default: the server
29
+ * asking for itself). `root` is where /etc and /usr are read from, and
30
+ * `platform` the system taken for this one (a test's stand-ins).
31
+ */
32
+ export async function firewallProbe({
33
+ rtcPort,
34
+ appPort,
35
+ listen = "127.0.0.1",
36
+ rtc,
37
+ node = process.execPath,
38
+ root = "/",
39
+ platform = process.platform,
40
+ } = {}) {
41
+ if (rtc === "off") return null;
42
+ const port = Number(rtcPort) || Number(appPort) || 7171;
43
+ const tcp = loopback(listen) ? null : Number(appPort) || port;
44
+ const at = (p) => path.join(root, p);
45
+ if (platform === "darwin") return macos(port, node, at);
46
+ return (await firewalld(port, tcp, at)) ?? ufw(port, tcp, at);
47
+ }
48
+
49
+ async function firewalld(port, tcp, at) {
50
+ const bin = findBin("firewall-cmd");
51
+ if (!bin) return null;
52
+ const active = await run(bin, ["--get-active-zones"]);
53
+ // Not running: the daemon did not answer.
54
+ if (!active.ok || !active.stdout.trim()) return null;
55
+ const zones = active.stdout
56
+ .split("\n")
57
+ .filter((line) => line && !/^\s/.test(line))
58
+ .map((line) => line.trim().split(/\s+/)[0]);
59
+ const byDefault = /^(\S+)\s+\(default\)/m.exec(active.stdout)?.[1];
60
+ const zone = byDefault && zones.includes(byDefault) ? byDefault : zones[0];
61
+ const services = await run(bin, ["--get-services"]);
62
+ const ruled = services.ok && services.stdout.split(/\s+/).includes(RULE);
63
+ // The zone as changed is root's to read; its shipped definition is what
64
+ // it is unless someone changed it.
65
+ const changed = readXml(at(`etc/firewalld/zones/${zone}.xml`));
66
+ const def = changed ?? readXml(at(`usr/lib/firewalld/zones/${zone}.xml`));
67
+ const exact = changed !== null;
68
+ const admits = ruled || (def !== null && zoneAdmits(def, port, at));
69
+ const likely = !admits;
70
+ const plan = [
71
+ ...(ruled
72
+ ? []
73
+ : [
74
+ sudo("firewall-cmd", "--permanent", `--new-service=${RULE}`),
75
+ sudo(
76
+ "firewall-cmd",
77
+ "--permanent",
78
+ `--service=${RULE}`,
79
+ `--set-short=${RULE}`,
80
+ ),
81
+ ]),
82
+ sudo(
83
+ "firewall-cmd",
84
+ "--permanent",
85
+ `--service=${RULE}`,
86
+ `--add-port=${port}/udp`,
87
+ ),
88
+ ...(tcp
89
+ ? [
90
+ sudo(
91
+ "firewall-cmd",
92
+ "--permanent",
93
+ `--service=${RULE}`,
94
+ `--add-port=${tcp}/tcp`,
95
+ ),
96
+ ]
97
+ : []),
98
+ sudo(
99
+ "firewall-cmd",
100
+ "--permanent",
101
+ `--zone=${zone}`,
102
+ `--add-service=${RULE}`,
103
+ ),
104
+ sudo("firewall-cmd", "--reload"),
105
+ ];
106
+ return result({
107
+ kind: "firewalld",
108
+ what: `firewalld (zone ${zone})`,
109
+ zone,
110
+ port,
111
+ admits,
112
+ likely,
113
+ exact,
114
+ ruled,
115
+ why: admits || exact ? null : "by the zone's definition as shipped",
116
+ plan: admits ? [] : plan,
117
+ });
118
+ }
119
+
120
+ function ufw(port, tcp, at) {
121
+ let conf = "";
122
+ try {
123
+ conf = fs.readFileSync(at("etc/ufw/ufw.conf"), "utf8");
124
+ } catch {
125
+ return null;
126
+ }
127
+ if (!/^\s*ENABLED\s*=\s*yes/m.test(conf)) return null;
128
+ let policy = "DROP";
129
+ try {
130
+ policy =
131
+ /^\s*DEFAULT_INPUT_POLICY\s*=\s*"?(\w+)/m.exec(
132
+ fs.readFileSync(at("etc/default/ufw"), "utf8"),
133
+ )?.[1] ?? policy;
134
+ } catch {}
135
+ // Its rules are root's to read, usually; where they are not, they say.
136
+ let rules = null;
137
+ try {
138
+ rules = fs.readFileSync(at("etc/ufw/user.rules"), "utf8");
139
+ } catch {}
140
+ const ruled =
141
+ !!rules &&
142
+ new RegExp(`### tuple ### allow udp ${port} \\S+ \\S+ \\S+ in\\b`).test(
143
+ rules,
144
+ );
145
+ const admits = policy === "ACCEPT" || ruled;
146
+ const plan = [
147
+ sudo("ufw", "allow", `${port}/udp`, "comment", RULE),
148
+ ...(tcp ? [sudo("ufw", "allow", `${tcp}/tcp`, "comment", RULE)] : []),
149
+ ];
150
+ return result({
151
+ kind: "ufw",
152
+ what: "ufw",
153
+ port,
154
+ admits,
155
+ likely: !admits,
156
+ exact: rules !== null,
157
+ ruled,
158
+ why:
159
+ admits || rules !== null
160
+ ? null
161
+ : `by its default input policy, ${policy}`,
162
+ plan: admits ? [] : plan,
163
+ });
164
+ }
165
+
166
+ /** macOS's application firewall filters by program, not port: what counts
167
+ * is whether the node the server runs (`node`) may take connections. All
168
+ * of it reads without root — the switch, "Block all incoming
169
+ * connections", whether signed software is let in by itself, node's own
170
+ * entry, and node's signature — and each parser takes what it can
171
+ * recognise and leaves the rest unknown (`macosVerdict`), since the
172
+ * wording has changed across releases. */
173
+ async function macos(port, node, at) {
174
+ const bin = at(SOCKETFILTERFW);
175
+ if (!fs.existsSync(bin)) return null;
176
+ const real = realpath(node);
177
+ const said = (r) => `${r.stdout}\n${r.stderr}`;
178
+ const [state, blockAll, signed, blocked, apps, sign] = await Promise.all(
179
+ [
180
+ ["--getglobalstate"],
181
+ ["--getblockall"],
182
+ ["--getallowsigned"],
183
+ ["--getappblocked", real],
184
+ ["--listapps"],
185
+ ]
186
+ .map((a) => run(bin, a).then(said))
187
+ .concat(run(at(CODESIGN), ["-dv", real]).then(said)),
188
+ );
189
+ const v = macosVerdict({
190
+ state,
191
+ blockAll,
192
+ signed,
193
+ blocked,
194
+ apps,
195
+ sign,
196
+ paths: [...new Set([node, real])],
197
+ });
198
+ if (!v) return null;
199
+ const sfw = (...a) => sudo(bin, ...a);
200
+ const plan =
201
+ v.needs === "unblock"
202
+ ? [sfw("--unblockapp", real)]
203
+ : v.needs === "add"
204
+ ? [sfw("--add", real), sfw("--unblockapp", real)]
205
+ : [];
206
+ return result({
207
+ kind: "macos",
208
+ what: "the macOS firewall",
209
+ port,
210
+ admits: v.admits,
211
+ likely: !v.admits,
212
+ exact: v.exact,
213
+ ruled: false,
214
+ why: v.why,
215
+ node: real,
216
+ plan,
217
+ fix: v.needs === "blockall" ? BLOCK_ALL_FIX : undefined,
218
+ });
219
+ }
220
+
221
+ const BLOCK_ALL_FIX =
222
+ "turn off “Block all incoming connections” (System Settings → Network → Firewall → Options); no rule for one program opens anything while it is on";
223
+
224
+ /**
225
+ * The macOS firewall's verdict on node from what socketfilterfw and
226
+ * codesign said (their stdout and stderr, as text): null when the firewall
227
+ * is off or its state could not be read. `needs` names the fix: `blockall`
228
+ * (a setting only the user should change), `unblock` (node is listed and
229
+ * blocked), `add` (node is not listed).
230
+ */
231
+ export function macosVerdict({
232
+ state,
233
+ blockAll,
234
+ signed,
235
+ blocked,
236
+ apps,
237
+ sign,
238
+ paths,
239
+ }) {
240
+ if (globalOn(state) !== true) return null;
241
+ if (blockAllOn(blockAll) ?? /State\s*=\s*2\b/.test(state))
242
+ return {
243
+ admits: false,
244
+ exact: true,
245
+ why: "“Block all incoming connections” is on",
246
+ needs: "blockall",
247
+ };
248
+ const entry = listedAs(apps, paths) ?? appBlocked(blocked);
249
+ if (entry === "block")
250
+ return {
251
+ admits: false,
252
+ exact: true,
253
+ why: "node is blocked in it",
254
+ needs: "unblock",
255
+ };
256
+ if (entry === "allow")
257
+ return {
258
+ admits: true,
259
+ exact: true,
260
+ why: "node is allowed in it",
261
+ needs: null,
262
+ };
263
+ const signature = signatureOf(sign);
264
+ const auto = allowSigned(signed);
265
+ if (
266
+ (signature === "developer-id" && auto.downloaded) ||
267
+ (signature === "apple" && auto.builtIn)
268
+ )
269
+ return {
270
+ admits: true,
271
+ exact: false,
272
+ why: `node is not listed, but it is ${signature === "apple" ? "Apple" : "Developer ID"}-signed and signed ${signature === "apple" ? "built-in" : "downloaded"} software is let in`,
273
+ needs: null,
274
+ };
275
+ return {
276
+ admits: false,
277
+ exact: false,
278
+ why: `node is not listed, and ${
279
+ signature === "developer-id" || signature === "apple"
280
+ ? "signed software is not let in by itself"
281
+ : signature === "adhoc"
282
+ ? "an ad-hoc-signed program is not let in by itself"
283
+ : signature === "unsigned"
284
+ ? "an unsigned program is not let in by itself"
285
+ : signature
286
+ ? "a program not Developer ID-signed is not let in by itself"
287
+ : "its signature could not be read"
288
+ }, so its connections are dropped or asked about on the Mac's screen`,
289
+ needs: "add",
290
+ };
291
+ }
292
+
293
+ /** `--getglobalstate`: "Firewall is enabled. (State = 1)", "Firewall is
294
+ * disabled. (State = 0)"; 2 is on with everything blocked. */
295
+ export function globalOn(text = "") {
296
+ const n = /State\s*=\s*(\d)/i.exec(text);
297
+ if (n) return n[1] !== "0";
298
+ if (/\bdisabled\b|\boff\b/i.test(text)) return false;
299
+ if (/\benabled\b|\bon\b/i.test(text)) return true;
300
+ return null;
301
+ }
302
+
303
+ /** `--getblockall`: "Block all ENABLED!" / "Block all DISABLED!", or
304
+ * "Firewall has block all state set to enabled." / "… disabled." */
305
+ export function blockAllOn(text = "") {
306
+ if (!/block\s*all/i.test(text)) return null;
307
+ if (/\bdisabled\b|\boff\b/i.test(text)) return false;
308
+ if (/\benabled\b|\bon\b/i.test(text)) return true;
309
+ return null;
310
+ }
311
+
312
+ /** `--getallowsigned`: "Automatically allow built-in signed software
313
+ * ENABLED." and "Automatically allow downloaded signed software
314
+ * ENABLED." (older: "… allow signed built-in software …", or one "… allow
315
+ * signed software …" switch for both). */
316
+ export function allowSigned(text = "") {
317
+ const out = { builtIn: null, downloaded: null };
318
+ for (const line of text.split("\n")) {
319
+ if (!/signed/i.test(line)) continue;
320
+ const on = /\bdisabled\b|\boff\b/i.test(line)
321
+ ? false
322
+ : /\benabled\b|\bon\b/i.test(line)
323
+ ? true
324
+ : null;
325
+ if (on === null) continue;
326
+ if (/download/i.test(line)) out.downloaded = on;
327
+ else if (/built-?\s?in/i.test(line)) out.builtIn = on;
328
+ else out.builtIn = out.downloaded = on;
329
+ }
330
+ return out;
331
+ }
332
+
333
+ /** `--listapps`: "ALF: total number of apps = 2", then per app "1 :
334
+ * /path" and, on its next line or after the path, "( Allow incoming
335
+ * connections )" or "( Block incoming connections )". */
336
+ export function listedAs(text = "", paths = []) {
337
+ const lines = text.split("\n");
338
+ for (let i = 0; i < lines.length; i++) {
339
+ const m = /^\s*\d+\s*:\s*(.+?)\s*(?:\(([^)]*)\))?\s*$/.exec(lines[i]);
340
+ if (!m || !paths.includes(m[1].trim())) continue;
341
+ for (const said of [m[2] ?? "", ...lines.slice(i + 1, i + 4)]) {
342
+ if (/^\s*\d+\s*:/.test(said)) break;
343
+ if (/\bblock/i.test(said)) return "block";
344
+ if (/\b(allow|permit)/i.test(said)) return "allow";
345
+ }
346
+ }
347
+ return null;
348
+ }
349
+
350
+ /** `--getappblocked <path>`: "… is permitted" / "… is blocked", or that it
351
+ * is not part of the firewall (not listed). */
352
+ export function appBlocked(text = "") {
353
+ if (
354
+ /not part of|isn['’]?t part|not (?:a )?(?:listed|found|in the)|no such|does not exist/i.test(
355
+ text,
356
+ )
357
+ )
358
+ return null;
359
+ if (/\bpermitted\b|\ballowed\b|\bunblocked\b|\bnot blocked\b/i.test(text))
360
+ return "allow";
361
+ if (/\bblocked\b/i.test(text)) return "block";
362
+ return null;
363
+ }
364
+
365
+ /** `codesign -dv <path>` (on stderr): "Authority=Developer ID
366
+ * Application: …", Apple's own ("Authority=Software Signing"),
367
+ * "Signature=adhoc", or "code object is not signed at all". */
368
+ export function signatureOf(text = "") {
369
+ if (/not signed at all/i.test(text)) return "unsigned";
370
+ if (/^Authority=Developer ID Application\b/im.test(text))
371
+ return "developer-id";
372
+ if (
373
+ /^Authority=(Software Signing|Apple Code Signing|Apple Mac OS Application Signing)\b/im.test(
374
+ text,
375
+ )
376
+ )
377
+ return "apple";
378
+ if (/^Signature=adhoc\b|\badhoc\b/im.test(text)) return "adhoc";
379
+ if (/^Authority=/im.test(text)) return "other";
380
+ return null;
381
+ }
382
+
383
+ function result(r) {
384
+ return {
385
+ ...r,
386
+ fix: r.fix ?? (r.plan.length ? r.plan.map(shell).join(" && ") : null),
387
+ };
388
+ }
389
+
390
+ /** Whether a firewalld zone definition lets UDP `port` in: by its target,
391
+ * a port range of its own, or a service it names (a readable one). */
392
+ function zoneAdmits(xml, port, at) {
393
+ if (/<zone[^>]*\btarget="ACCEPT"/.test(xml)) return true;
394
+ if (portsAdmit(xml, port)) return true;
395
+ for (const [, name] of xml.matchAll(/<service\s+name="([^"]+)"/g)) {
396
+ const svc =
397
+ readXml(at(`etc/firewalld/services/${name}.xml`)) ??
398
+ readXml(at(`usr/lib/firewalld/services/${name}.xml`));
399
+ if (svc && portsAdmit(svc, port)) return true;
400
+ }
401
+ return false;
402
+ }
403
+
404
+ function portsAdmit(xml, port) {
405
+ for (const [tag] of xml.matchAll(/<port\b[^>]*>/g)) {
406
+ const proto = /protocol="(\w+)"/.exec(tag)?.[1];
407
+ const range = /port="(\d+)(?:-(\d+))?"/.exec(tag);
408
+ if (proto !== "udp" || !range) continue;
409
+ const lo = Number(range[1]);
410
+ const hi = Number(range[2] ?? range[1]);
411
+ if (port >= lo && port <= hi) return true;
412
+ }
413
+ return false;
414
+ }
415
+
416
+ /** Run a probe's plan, each command printed (`log`) as it runs and its
417
+ * sudo prompt on this terminal; stops at the first that fails. */
418
+ export function applyPlan(plan, log) {
419
+ for (const cmd of plan) {
420
+ log(cmd.join(" "));
421
+ const done = spawnSync(cmd[0], cmd.slice(1), { stdio: "inherit" });
422
+ if (done.status !== 0) return { ok: false, failed: cmd };
423
+ }
424
+ return { ok: true };
425
+ }
426
+
427
+ /** `work doctor`'s line, or null with nothing to say. Never a failure of
428
+ * readiness: work runs either way, and only devices on the network lose
429
+ * the direct path. macOS's answer is for one node, so the line says when
430
+ * it had to be this shell's (`nodeFrom`, set by the CLI). */
431
+ export function firewallLine(f) {
432
+ if (!f) return null;
433
+ const head = "firewall".padEnd(11);
434
+ const why = f.ruled
435
+ ? ` (work's rule, \`${RULE}\`)`
436
+ : f.why
437
+ ? ` (${f.why})`
438
+ : "";
439
+ const whose =
440
+ f.kind === "macos" && f.nodeFrom === "shell"
441
+ ? `; read for this shell's node, ${f.node}, as neither a running service nor its definition said which it runs`
442
+ : "";
443
+ if (f.admits)
444
+ return `${head}✓ ${f.what} admits UDP ${f.port}${why}, which direct connections use${whose}`;
445
+ const how = !f.plan.length
446
+ ? f.fix
447
+ : f.kind === "macos"
448
+ ? `work setup --firewall lets node in, running: ${f.fix}`
449
+ : `work setup --firewall adds a rule named \`${RULE}\`, running: ${f.fix}`;
450
+ return `${head}– ${f.what} ${f.exact ? "drops" : "likely drops"} UDP ${f.port}${why}, which direct connections from other devices use: ${how}${whose}`;
451
+ }
452
+
453
+ /**
454
+ * The node a service definition runs (`text`: the launchd plist or systemd
455
+ * unit `work setup` writes): its program when that is node; else, for a
456
+ * script (the CLI, or a checkout's run-local.sh, after any wrapper such as
457
+ * caffeinate), the node its shebang names or the first on the PATH the
458
+ * definition gives it. A version manager's shim on that PATH is passed
459
+ * over: it is not the program the firewall sees. Null when the definition
460
+ * names no program.
461
+ */
462
+ export function serviceNode(text, { PATH = "" } = {}) {
463
+ const argv = programOf(text);
464
+ if (!argv.length) return null;
465
+ const onPath = () => {
466
+ for (const dir of PATH.split(path.delimiter)) {
467
+ if (!dir) continue;
468
+ const file = path.join(dir, "node");
469
+ if (isNode(realpath(file)) && executable(file)) return file;
470
+ }
471
+ return null;
472
+ };
473
+ for (const arg of argv) {
474
+ if (isNode(arg)) return arg;
475
+ const line = shebang(arg);
476
+ // A wrapper's flag, or a program with no shebang (caffeinate).
477
+ if (!line) continue;
478
+ const [interp, first] = line.split(/\s+/);
479
+ if (isNode(interp)) return interp;
480
+ if (
481
+ path.basename(interp) === "env" &&
482
+ first &&
483
+ isNode(first) &&
484
+ first.includes("/")
485
+ )
486
+ return first;
487
+ return onPath();
488
+ }
489
+ return onPath();
490
+ }
491
+
492
+ function programOf(text) {
493
+ const plist =
494
+ /<key>ProgramArguments<\/key>\s*<array>([\s\S]*?)<\/array>/.exec(text);
495
+ if (plist)
496
+ return [...plist[1].matchAll(/<string>([^<]*)<\/string>/g)].map(([, v]) =>
497
+ v.replace(/&(amp|lt|gt|quot|apos);/g, (_, n) => XML[n]),
498
+ );
499
+ const exec = /^ExecStart=[-@+!:]*(.*)$/m.exec(text);
500
+ if (!exec) return [];
501
+ return [...exec[1].matchAll(/"([^"]*)"|(\S+)/g)].map(([, q, b]) => q ?? b);
502
+ }
503
+
504
+ const XML = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'" };
505
+
506
+ function isNode(file) {
507
+ return /^node(?:\d+)?$/.test(path.basename(file));
508
+ }
509
+
510
+ function shebang(file) {
511
+ let fd;
512
+ try {
513
+ fd = fs.openSync(file, "r");
514
+ const buf = Buffer.alloc(256);
515
+ const head = buf.subarray(0, fs.readSync(fd, buf, 0, 256, 0)).toString();
516
+ return head.startsWith("#!") ? head.slice(2).split("\n")[0].trim() : null;
517
+ } catch {
518
+ return null;
519
+ } finally {
520
+ if (fd !== undefined) fs.closeSync(fd);
521
+ }
522
+ }
523
+
524
+ function executable(file) {
525
+ try {
526
+ fs.accessSync(file, fs.constants.X_OK);
527
+ return fs.statSync(file).isFile();
528
+ } catch {
529
+ return false;
530
+ }
531
+ }
532
+
533
+ function realpath(file) {
534
+ try {
535
+ return fs.realpathSync(file);
536
+ } catch {
537
+ return file;
538
+ }
539
+ }
540
+
541
+ function sudo(...args) {
542
+ return ["sudo", ...args];
543
+ }
544
+
545
+ function shell(argv) {
546
+ return argv
547
+ .map((a) =>
548
+ /^[\w@%+=:,./-]+$/.test(a) ? a : `'${a.replace(/'/g, "'\\''")}'`,
549
+ )
550
+ .join(" ");
551
+ }
552
+
553
+ function loopback(listen) {
554
+ return (
555
+ !listen ||
556
+ listen === "::1" ||
557
+ /^127\./.test(listen) ||
558
+ listen === "localhost"
559
+ );
560
+ }
561
+
562
+ function readXml(file) {
563
+ try {
564
+ return fs.readFileSync(file, "utf8");
565
+ } catch {
566
+ return null;
567
+ }
568
+ }
569
+
570
+ /** A program on PATH, or in the sbin directories a user's PATH can leave
571
+ * out. */
572
+ function findBin(name) {
573
+ const dirs = [
574
+ ...(process.env.PATH || "").split(path.delimiter),
575
+ "/usr/sbin",
576
+ "/sbin",
577
+ ];
578
+ for (const dir of dirs) {
579
+ if (!dir) continue;
580
+ const full = path.join(dir, name);
581
+ try {
582
+ if (fs.statSync(full).isFile()) return full;
583
+ } catch {}
584
+ }
585
+ return null;
586
+ }
587
+
588
+ function run(cmd, args) {
589
+ return new Promise((resolve) =>
590
+ execFile(cmd, args, { timeout: 5000 }, (err, stdout, stderr) =>
591
+ resolve({
592
+ ok: !err,
593
+ stdout: String(stdout || ""),
594
+ stderr: String(stderr || ""),
595
+ }),
596
+ ),
597
+ );
598
+ }
@@ -0,0 +1,53 @@
1
+ export const SERVE_SINCE: string;
2
+ export function parseVersion(text: string | undefined): string | null;
3
+ export interface TailscaleServe {
4
+ /** What a browser opens: `https://<name>/`. */
5
+ url: string;
6
+ host: string;
7
+ /** Funnel publishes it to the internet. */
8
+ funnel: boolean;
9
+ }
10
+ export interface TailscaleProbe {
11
+ installed: boolean;
12
+ path?: string;
13
+ /** The CLI's version (`1.76.1`). */
14
+ version?: string | null;
15
+ /** The CLI takes `tailscale serve --bg <port>` (SERVE_SINCE). */
16
+ serveCli?: boolean;
17
+ /** tailscaled's BackendState (`Running`, `NeedsLogin`, `Stopped`, …);
18
+ * null when it did not answer. */
19
+ state?: string | null;
20
+ /** Logged in and connected, with a MagicDNS name. */
21
+ running?: boolean;
22
+ /** This machine's MagicDNS name, `<machine>.<tailnet>.ts.net`. */
23
+ name?: string | null;
24
+ /** HTTPS certificates are on for the tailnet; null when unknown. */
25
+ https?: boolean | null;
26
+ /** work's port, as probed. */
27
+ port?: string;
28
+ /** Where the serve config serves work's port, and whether work answers
29
+ * that name (WORK_ALLOWED_HOSTS). */
30
+ serve?: (TailscaleServe & { allowed: boolean }) | null;
31
+ /** What `https://<name>/` serves when it is not work. */
32
+ rootTaken?: string | null;
33
+ }
34
+ export function serveOf(
35
+ config: unknown,
36
+ port: string | number,
37
+ ): TailscaleServe | null;
38
+ export function allowHost(
39
+ value: string | undefined,
40
+ name: string,
41
+ allow?: boolean,
42
+ ): string;
43
+ export function readTailscale(
44
+ raw: {
45
+ path: string;
46
+ version: string;
47
+ status: Record<string, any> | null;
48
+ serve: Record<string, any> | null;
49
+ },
50
+ opts: { port: string | number; allowedHosts?: string },
51
+ ): TailscaleProbe;
52
+ export function stateText(t: TailscaleProbe): string;
53
+ export function tailscaleLine(t: TailscaleProbe): string;