@dylanpiercey/work 0.1.1 → 0.2.1
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.
- package/README.md +28 -0
- package/bin/work.mjs +244 -4
- package/dist/{_Dzz52ZtI.js → _KRMk2duX.js} +378 -12
- package/dist/_ZwD1NY8D.js +2 -0
- package/dist/_h48l7A55.js +169 -0
- package/dist/index.mjs +8621 -7550
- package/dist/public/assets/_0vrYNi0q.js +1 -0
- package/dist/public/assets/{_DvKnakqk.js → _1nwEHbOU.js} +1 -1
- package/dist/public/assets/_1nwEHbOU.js.br +0 -0
- package/dist/public/assets/_3qg1gNHu.js +1 -0
- package/dist/public/assets/_6_cAsPFk.js +1 -0
- package/dist/public/assets/_8mmvS8Ic.js +1 -0
- package/dist/public/assets/{_DX5u6Wvm.js → _9s8_FJP0.js} +1 -1
- package/dist/public/assets/_9s8_FJP0.js.br +0 -0
- package/dist/public/assets/_B0cZNayr.js +1 -0
- package/dist/public/assets/_B23wGSFP.js +1 -0
- package/dist/public/assets/_B4BVKmh0.js +1 -0
- package/dist/public/assets/_B6oF-RIK.js +1 -0
- package/dist/public/assets/_B7SrX3Jp.js +1 -0
- package/dist/public/assets/{_BzGHediB.js → _B7cXT0VU.js} +1 -1
- package/dist/public/assets/_B7cXT0VU.js.br +0 -0
- package/dist/public/assets/{_DcOkTFth.js → _B8zhI-xd.js} +1 -1
- package/dist/public/assets/_B9epMiSr.js +1 -0
- package/dist/public/assets/{_B1D0PIz3.js → _BAYrWdA-.js} +1 -1
- package/dist/public/assets/_BAYrWdA-.js.br +0 -0
- package/dist/public/assets/{_pXG8fRON.js → _BAeMnj2l.js} +1 -1
- package/dist/public/assets/_BAeMnj2l.js.br +0 -0
- package/dist/public/assets/_BAs5Ke57.js +1 -0
- package/dist/public/assets/{_DomK7Scb.js → _BDkvoJS4.js} +1 -1
- package/dist/public/assets/_BDkvoJS4.js.br +0 -0
- package/dist/public/assets/{_TrcWRD8T.js → _BE2H3NPA.js} +7 -7
- package/dist/public/assets/_BE2H3NPA.js.br +0 -0
- package/dist/public/assets/{_-5UNb9-C.js → _BEL3zCP_.js} +1 -1
- package/dist/public/assets/_BEL3zCP_.js.br +0 -0
- package/dist/public/assets/{_FlITqTCo.js → _BGYXkARu.js} +1 -1
- package/dist/public/assets/_BGYXkARu.js.br +0 -0
- package/dist/public/assets/{_CxA3Yab0.js → _BHL0M4hx.js} +1 -1
- package/dist/public/assets/_BHL0M4hx.js.br +0 -0
- package/dist/public/assets/{_1JXC9nFp.js → _BIN7xPBA.js} +1 -1
- package/dist/public/assets/_BIN7xPBA.js.br +0 -0
- package/dist/public/assets/{_CFUREq1M.js → _BPa71So4.js} +1 -1
- package/dist/public/assets/_BPa71So4.js.br +0 -0
- package/dist/public/assets/_BQgqTOA6.js +1 -0
- package/dist/public/assets/_BVOSK21c.js +1 -0
- package/dist/public/assets/{_BVQosHjY.js → _BWdb49DN.js} +1 -1
- package/dist/public/assets/_BWdb49DN.js.br +0 -0
- package/dist/public/assets/{_C-EkQeP_.js → _BZMc12pa.js} +1 -1
- package/dist/public/assets/_BZMc12pa.js.br +0 -0
- package/dist/public/assets/{_BkcPY2j0.js → _BcS532Mh.js} +1 -1
- package/dist/public/assets/_BcS532Mh.js.br +0 -0
- package/dist/public/assets/_Bd3RfEz5.js +1 -0
- package/dist/public/assets/{_yUmRJIJ6.js → _BdS-SIP5.js} +1 -1
- package/dist/public/assets/_BdS-SIP5.js.br +0 -0
- package/dist/public/assets/{_B3NfNm8M.js → _BfU4-P5_.js} +13 -13
- package/dist/public/assets/_BfU4-P5_.js.br +0 -0
- package/dist/public/assets/{_DUs3ZGbj.js → _BidDqDX-.js} +1 -1
- package/dist/public/assets/_BidDqDX-.js.br +0 -0
- package/dist/public/assets/{_Cx_aJfDp.js → _Blw8tTg6.js} +1 -1
- package/dist/public/assets/_Blw8tTg6.js.br +0 -0
- package/dist/public/assets/{_CfGEGt_k.js → _BnIxui8m.js} +1 -1
- package/dist/public/assets/_BnIxui8m.js.br +0 -0
- package/dist/public/assets/{_DRHCy0UF.js → _BnnnKUB5.js} +1 -1
- package/dist/public/assets/_BnnnKUB5.js.br +0 -0
- package/dist/public/assets/_BoFnbJY1.js +1 -0
- package/dist/public/assets/{_Cb_k_JA_.js → _BotYlEwM.js} +1 -1
- package/dist/public/assets/_BotYlEwM.js.br +0 -0
- package/dist/public/assets/_BphDw0sE.js +1 -0
- package/dist/public/assets/_BqeBwjz2.js +1 -0
- package/dist/public/assets/{_BtZ2AatF.js → _Bs2mrt6D.js} +1 -1
- package/dist/public/assets/{_BRQ6iQ5p.js → _BtNwLErW.js} +1 -1
- package/dist/public/assets/_BtNwLErW.js.br +0 -0
- package/dist/public/assets/_Bv7YPgSd.js +1 -0
- package/dist/public/assets/{_CWG813ur.js → _BvrmMS2E.js} +1 -1
- package/dist/public/assets/_BvrmMS2E.js.br +0 -0
- package/dist/public/assets/{_DgWKSW-Y.js → _BwX_PmTl.js} +1 -1
- package/dist/public/assets/_BwX_PmTl.js.br +0 -0
- package/dist/public/assets/{_DEOryr7w.js → _C05-oJk8.js} +1 -1
- package/dist/public/assets/_C05-oJk8.js.br +0 -0
- package/dist/public/assets/{_CCVkYcN5.js → _C2yU1dLq.js} +1 -1
- package/dist/public/assets/_C2yU1dLq.js.br +0 -0
- package/dist/public/assets/{_CKLGAGKJ.js → _C2z40jpl.js} +1 -1
- package/dist/public/assets/_C2z40jpl.js.br +0 -0
- package/dist/public/assets/_C6HTijVG.js +1 -0
- package/dist/public/assets/{_1xOByopP.js → _C6lJdZzj.js} +1 -1
- package/dist/public/assets/_C6lJdZzj.js.br +0 -0
- package/dist/public/assets/_C7vMBzAL.js +1 -0
- package/dist/public/assets/_C7vMBzAL.js.br +0 -0
- package/dist/public/assets/{_B_0C2_RO.js → _C8pXYUZJ.js} +1 -1
- package/dist/public/assets/_C8pXYUZJ.js.br +0 -0
- package/dist/public/assets/_C9zPmOH2.js +2 -0
- package/dist/public/assets/_C9zPmOH2.js.br +0 -0
- package/dist/public/assets/_CA7mM4qX.js +1 -0
- package/dist/public/assets/{_DM60dKRs.js → _CBENFdjy.js} +1 -1
- package/dist/public/assets/_CBENFdjy.js.br +0 -0
- package/dist/public/assets/_CDlUndl3.js +1 -0
- package/dist/public/assets/_CDlUndl3.js.br +0 -0
- package/dist/public/assets/_CEPIxYBN.js +86 -0
- package/dist/public/assets/_CEPIxYBN.js.br +0 -0
- package/dist/public/assets/{_B7VYILLZ.js → _CFHivO5W.js} +1 -1
- package/dist/public/assets/_CFHivO5W.js.br +0 -0
- package/dist/public/assets/{_C98JZr09.js → _CGylDsvz.js} +1 -1
- package/dist/public/assets/_CGylDsvz.js.br +0 -0
- package/dist/public/assets/_CISImxw1.js +1 -0
- package/dist/public/assets/{_m2tRa0jk.js → _CJAgrixe.js} +1 -1
- package/dist/public/assets/_CJAgrixe.js.br +0 -0
- package/dist/public/assets/_CJEPkQp1.js +1 -0
- package/dist/public/assets/_CLF8kSpu.js +1 -0
- package/dist/public/assets/{_DxD_AC3a.js → _CMe89-TR.js} +1 -1
- package/dist/public/assets/_CMe89-TR.js.br +0 -0
- package/dist/public/assets/{_CY87Y7QL.js → _CQl6IKdI.js} +1 -1
- package/dist/public/assets/_CQl6IKdI.js.br +0 -0
- package/dist/public/assets/_CR1lhMQ3.js +1 -0
- package/dist/public/assets/_CRBiqW8E.js +1 -0
- package/dist/public/assets/{_UaKPY71M.js → _CRvIHvZK.js} +1 -1
- package/dist/public/assets/_CRvIHvZK.js.br +0 -0
- package/dist/public/assets/_CT-EgIiU.js +1 -0
- package/dist/public/assets/_CVXUwEfP.js +1 -0
- package/dist/public/assets/_CW5A7nA-.js +1 -0
- package/dist/public/assets/{_Do1ltY2a.js → _CWuvWHgA.js} +1 -1
- package/dist/public/assets/_CWuvWHgA.js.br +0 -0
- package/dist/public/assets/{_CfdK8EeQ.js → _CXSkYGoG.js} +1 -1
- package/dist/public/assets/_CXSkYGoG.js.br +0 -0
- package/dist/public/assets/_CYtwao4w.js +1 -0
- package/dist/public/assets/{_CUsrMpdL.js → _CZTHGPNy.js} +1 -1
- package/dist/public/assets/_CZTHGPNy.js.br +0 -0
- package/dist/public/assets/{_HM_QqtJi.js → _CappgGwi.js} +1 -1
- package/dist/public/assets/_CappgGwi.js.br +0 -0
- package/dist/public/assets/_CeARoEjl.js +1 -0
- package/dist/public/assets/_CeARoEjl.js.br +0 -0
- package/dist/public/assets/{_BDUjU8Ev.js → _Cf7js-r0.js} +1 -1
- package/dist/public/assets/{_Dbm6zAQS.js → _ChJB1hf1.js} +1 -1
- package/dist/public/assets/_ChJB1hf1.js.br +0 -0
- package/dist/public/assets/_ChkvWPVl.js +1 -0
- package/dist/public/assets/{_C0Ib7MZF.js → _CkLUNG6d.js} +1 -1
- package/dist/public/assets/_CkLUNG6d.js.br +0 -0
- package/dist/public/assets/_Cm2gzAKb.js +1 -0
- package/dist/public/assets/_CmCI2k_X.js +1 -0
- package/dist/public/assets/{_D9r_Fn0I.js → _CnIFQPqM.js} +1 -1
- package/dist/public/assets/_CnIFQPqM.js.br +0 -0
- package/dist/public/assets/_CpzkPBcd.js +1 -0
- package/dist/public/assets/{_DL3w8c_p.js → _Cqij7P1t.js} +1 -1
- package/dist/public/assets/_Cqij7P1t.js.br +0 -0
- package/dist/public/assets/_CsGBY_OR.js +1 -0
- package/dist/public/assets/_Cvq7oyHi.js +1 -0
- package/dist/public/assets/_CxQnabfk.js +6 -0
- package/dist/public/assets/_CxQnabfk.js.br +0 -0
- package/dist/public/assets/_Cxuln-KJ.js +1 -0
- package/dist/public/assets/{_DifjKObE.js → _CzjTMNNg.js} +1 -1
- package/dist/public/assets/_CzjTMNNg.js.br +0 -0
- package/dist/public/assets/{_CiYQhf81.js → _D-ewgB-g.js} +1 -1
- package/dist/public/assets/_D-ewgB-g.js.br +0 -0
- package/dist/public/assets/_D-lSuOqN.js +1 -0
- package/dist/public/assets/{_kWQ0dtYZ.js → _D0toMFV3.js} +1 -1
- package/dist/public/assets/_D0toMFV3.js.br +0 -0
- package/dist/public/assets/{_JEvx8ub4.js → _D1SAzhRo.js} +1 -1
- package/dist/public/assets/_D1SAzhRo.js.br +0 -0
- package/dist/public/assets/{_ClHPjF-1.js → _D2NPwpCK.js} +1 -1
- package/dist/public/assets/_D2NPwpCK.js.br +0 -0
- package/dist/public/assets/_D2pdXUO3.js +1 -0
- package/dist/public/assets/{_DzKW89Sx.js → _D36AHDIn.js} +1 -1
- package/dist/public/assets/_D36AHDIn.js.br +0 -0
- package/dist/public/assets/{_EefWj858.js → _D39T9Hc3.js} +1 -1
- package/dist/public/assets/_D39T9Hc3.js.br +0 -0
- package/dist/public/assets/{_DJqEBkNd.js → _D4iaGiBC.js} +1 -1
- package/dist/public/assets/_D4iaGiBC.js.br +0 -0
- package/dist/public/assets/{_BPSTqkJn.js → _D60_NLSK.js} +1 -1
- package/dist/public/assets/_D60_NLSK.js.br +0 -0
- package/dist/public/assets/{_Di1ccq_2.js → _D6O591m8.js} +1 -1
- package/dist/public/assets/_D6O591m8.js.br +0 -0
- package/dist/public/assets/_D6OrE8WN.js +1 -0
- package/dist/public/assets/_D6b9irVv.js +1 -0
- package/dist/public/assets/_D7e9Ia7P.js +1 -0
- package/dist/public/assets/_D95nSKbk.js +1 -0
- package/dist/public/assets/_D9qcWm-q.js +1 -0
- package/dist/public/assets/_D9uiExWV.js +1 -0
- package/dist/public/assets/{__cyRVmTO.js → _DAPIaEl7.js} +1 -1
- package/dist/public/assets/_DAPIaEl7.js.br +0 -0
- package/dist/public/assets/_DBOZe4SW.js +1 -0
- package/dist/public/assets/{_Cmmdd2e3.js → _DCfgIXDZ.js} +1 -1
- package/dist/public/assets/_DCfgIXDZ.js.br +0 -0
- package/dist/public/assets/_DDrn7T44.js +1 -0
- package/dist/public/assets/{_DQyjuXTi.js → _DDs3ube1.js} +1 -1
- package/dist/public/assets/_DDs3ube1.js.br +0 -0
- package/dist/public/assets/_DEKJL8_K.js +1 -0
- package/dist/public/assets/_DJOVMSj1.js +1 -0
- package/dist/public/assets/{_CqCenHOp.js → _DJSmALSy.js} +1 -1
- package/dist/public/assets/_DJSmALSy.js.br +0 -0
- package/dist/public/assets/_DLFpqsl0.js +1 -0
- package/dist/public/assets/_DOyEaX0U.js +1 -0
- package/dist/public/assets/{_B1-W0Sn2.js → _DQd4Gai0.js} +1 -1
- package/dist/public/assets/_DQd4Gai0.js.br +0 -0
- package/dist/public/assets/_DQlvpXhI.js +1 -0
- package/dist/public/assets/_DQlvpXhI.js.br +0 -0
- package/dist/public/assets/{_DZvkgS3V.js → _DRTaehFU.js} +1 -1
- package/dist/public/assets/_DRTaehFU.js.br +0 -0
- package/dist/public/assets/_DTKyMAAU.js +1 -0
- package/dist/public/assets/{_3aBl7SEn.js → _DWuVY-5K.js} +1 -1
- package/dist/public/assets/_DWuVY-5K.js.br +0 -0
- package/dist/public/assets/_DXAMCgpo.js +1 -0
- package/dist/public/assets/_DXAMCgpo.js.br +0 -0
- package/dist/public/assets/{_BSWN-v3P.js → _DXBIA5Jf.js} +1 -1
- package/dist/public/assets/_DXBIA5Jf.js.br +0 -0
- package/dist/public/assets/_Da14xaff.js +1 -0
- package/dist/public/assets/_Da14xaff.js.br +0 -0
- package/dist/public/assets/_DbXR2mlf.js +1 -0
- package/dist/public/assets/{_HmkI4Rfn.js → _Dbp_FIBr.js} +1 -1
- package/dist/public/assets/_Dbp_FIBr.js.br +0 -0
- package/dist/public/assets/_Dc_Ittsm.js +1 -0
- package/dist/public/assets/_DdYt8SWd.js +1 -0
- package/dist/public/assets/{_vcLBrU2m.js → _DgWkLH_d.js} +1 -1
- package/dist/public/assets/_DgWkLH_d.js.br +0 -0
- package/dist/public/assets/_Dh5xTE2G.js +1 -0
- package/dist/public/assets/{_CDY0RpYX.js → _DiE4MtP8.js} +1 -1
- package/dist/public/assets/_DiE4MtP8.js.br +0 -0
- package/dist/public/assets/_DjGr7GRl.js +1 -0
- package/dist/public/assets/_DjGr7GRl.js.br +0 -0
- package/dist/public/assets/_DotQ0YLh.js +2 -0
- package/dist/public/assets/_DotQ0YLh.js.br +0 -0
- package/dist/public/assets/_DqAfN3OQ.js +1 -0
- package/dist/public/assets/{_BKIx7IZP.js → _DqMNzDjo.js} +1 -1
- package/dist/public/assets/_DqMNzDjo.js.br +0 -0
- package/dist/public/assets/{_BsJZPHmz.js → _Dqqxf-zK.js} +1 -1
- package/dist/public/assets/_Dqqxf-zK.js.br +0 -0
- package/dist/public/assets/{_dsj7vMTW.js → _Dufbr-KL.js} +1 -1
- package/dist/public/assets/_Dufbr-KL.js.br +0 -0
- package/dist/public/assets/_Dv-q-Ej7.js +1 -0
- package/dist/public/assets/{_BHU5aikZ.js → _Dvfi_oP5.js} +1 -1
- package/dist/public/assets/_DvyJx5yW.js +1 -0
- package/dist/public/assets/_DvyJx5yW.js.br +0 -0
- package/dist/public/assets/_DxMb2QV8.js +1 -0
- package/dist/public/assets/{_BKHtiW96.js → _DyYpJ-H0.js} +1 -1
- package/dist/public/assets/_DyYpJ-H0.js.br +0 -0
- package/dist/public/assets/_DyhlHfZJ.js +1 -0
- package/dist/public/assets/_Dz053N5t.js +1 -0
- package/dist/public/assets/{_BLfzQY-3.js → _L54I8aS4.js} +1 -1
- package/dist/public/assets/_L54I8aS4.js.br +0 -0
- package/dist/public/assets/_Ly-2Xkdk.js +1 -0
- package/dist/public/assets/{_BSFJEuJX.js → _NN0jQCcG.js} +1 -1
- package/dist/public/assets/_NN0jQCcG.js.br +0 -0
- package/dist/public/assets/{_7YrArFMB.js → _OzsIhJyG.js} +1 -1
- package/dist/public/assets/_OzsIhJyG.js.br +0 -0
- package/dist/public/assets/_QJUmfZ1o.js +1 -0
- package/dist/public/assets/{_iutZ4EDe.js → _VdeOc79W.js} +1 -1
- package/dist/public/assets/_VdeOc79W.js.br +0 -0
- package/dist/public/assets/_VkEFwEn-.js +1 -0
- package/dist/public/assets/_ahp1rb5o.js +1 -0
- package/dist/public/assets/{_VPLoEBTS.js → _aqBpT1uJ.js} +1 -1
- package/dist/public/assets/{_DBD57l1T.js → _bgu_OKRO.js} +1 -1
- package/dist/public/assets/_bgu_OKRO.js.br +0 -0
- package/dist/public/assets/{_C81nSl09.js → _fqHAtYJz.js} +1 -1
- package/dist/public/assets/_fqHAtYJz.js.br +0 -0
- package/dist/public/assets/_hdoOlF1z.js +1 -0
- package/dist/public/assets/{_CtqGSS84.js → _iFV4welK.js} +1 -1
- package/dist/public/assets/_iFV4welK.js.br +0 -0
- package/dist/public/assets/_ihgadrBp.js +1 -0
- package/dist/public/assets/_lJgrZjR9.js +1 -0
- package/dist/public/assets/_lJgrZjR9.js.br +0 -0
- package/dist/public/assets/_oNShN50G.js +1 -0
- package/dist/public/assets/{_C8bqYk4J.js → _oR1qIlrw.js} +1 -1
- package/dist/public/assets/_oR1qIlrw.js.br +0 -0
- package/dist/public/assets/_pxC2PRJZ.js +1 -0
- package/dist/public/assets/_q6iLcLGY.js +1 -0
- package/dist/public/assets/_qnKDgwVg.js +1 -0
- package/dist/public/assets/_rYWHy2XX.js +1 -0
- package/dist/public/assets/{_CHdpLB95.js → _snlh9j-I.js} +1 -1
- package/dist/public/assets/_snlh9j-I.js.br +0 -0
- package/dist/public/assets/_uGH3cvIZ.js +1 -0
- package/dist/public/assets/_uRhnGFfv.js +1 -0
- package/dist/public/assets/{_DMJHTH74.js → _wOX1zfjU.js} +1 -1
- package/dist/public/assets/_wOX1zfjU.js.br +0 -0
- package/dist/public/assets/_xMc_vDaT.js +1 -0
- package/dist/public/assets/{_DSUBv-Bl.js → _zGPxyhe6.js} +1 -1
- package/dist/public/assets/_zGPxyhe6.js.br +0 -0
- package/dist/public/assets/files-view-dOlOeiFQ.js +2 -0
- package/dist/public/assets/manage-workspace-CO4jGUSH.js +2 -0
- package/dist/public/assets/new-hhTJEH33.js +1 -0
- package/dist/public/assets/new-workspace-w6SV5jo2.js +2 -0
- package/dist/public/assets/review-view-DhbS4oNh.js +2 -0
- package/dist/public/assets/settings-hhTJEH33.js +1 -0
- package/dist/public/assets/settings-page-DpRlMZTu.js +2 -0
- package/dist/public/assets/styles-BfKP6xyD.css +1 -0
- package/dist/public/assets/styles-BfKP6xyD.css.br +0 -0
- package/dist/public/assets/w-hhTJEH33.js +1 -0
- package/dist/public/assets/w._-DSFmri_t.js +1 -0
- package/dist/public/assets/w._-hhTJEH33.js +1 -0
- package/dist/public/assets/w._-kFbho4FJ.js +1 -0
- package/dist/rtc-helper.mjs +1170 -0
- package/lib/preview/media.mjs +5 -4
- package/lib/setup/doctor.d.mts +11 -0
- package/lib/setup/doctor.mjs +23 -2
- package/lib/setup/firewall.d.mts +76 -0
- package/lib/setup/firewall.mjs +598 -0
- package/package.json +3 -2
- package/dist/_D1C-XIqT.js +0 -168
- package/dist/_HbAW5Cbt.js +0 -2
- package/dist/public/assets/_-5UNb9-C.js.br +0 -0
- package/dist/public/assets/_06rtP_SB.js +0 -1
- package/dist/public/assets/_14yhXek7.js +0 -1
- package/dist/public/assets/_14yhXek7.js.br +0 -0
- package/dist/public/assets/_1JXC9nFp.js.br +0 -0
- package/dist/public/assets/_1Yit_Y5R.js +0 -1
- package/dist/public/assets/_1ZPfR2B8.js +0 -6
- package/dist/public/assets/_1ZPfR2B8.js.br +0 -0
- package/dist/public/assets/_1xOByopP.js.br +0 -0
- package/dist/public/assets/_3aBl7SEn.js.br +0 -0
- package/dist/public/assets/_5aMLV2Vy.js +0 -1
- package/dist/public/assets/_7YrArFMB.js.br +0 -0
- package/dist/public/assets/_B1-W0Sn2.js.br +0 -0
- package/dist/public/assets/_B1D0PIz3.js.br +0 -0
- package/dist/public/assets/_B1agoKUa.js +0 -1
- package/dist/public/assets/_B3NfNm8M.js.br +0 -0
- package/dist/public/assets/_B7VYILLZ.js.br +0 -0
- package/dist/public/assets/_B7sPBy0J.js +0 -1
- package/dist/public/assets/_B81p6DSw.js +0 -1
- package/dist/public/assets/_BAkSKCkz.js +0 -1
- package/dist/public/assets/_BHZPTv1U.js +0 -1
- package/dist/public/assets/_BKHtiW96.js.br +0 -0
- package/dist/public/assets/_BKIx7IZP.js.br +0 -0
- package/dist/public/assets/_BLfzQY-3.js.br +0 -0
- package/dist/public/assets/_BPSTqkJn.js.br +0 -0
- package/dist/public/assets/_BQZOimBB.js +0 -1
- package/dist/public/assets/_BRQ6iQ5p.js.br +0 -0
- package/dist/public/assets/_BRVURc4u.js +0 -1
- package/dist/public/assets/_BSFJEuJX.js.br +0 -0
- package/dist/public/assets/_BSWN-v3P.js.br +0 -0
- package/dist/public/assets/_BTVAQr2c.js +0 -1
- package/dist/public/assets/_BUD1pBC0.js +0 -1
- package/dist/public/assets/_BVGzCczb.js +0 -1
- package/dist/public/assets/_BVQosHjY.js.br +0 -0
- package/dist/public/assets/_B_0C2_RO.js.br +0 -0
- package/dist/public/assets/_BaA31ms5.js +0 -1
- package/dist/public/assets/_BgCHJGlO.js +0 -1
- package/dist/public/assets/_BhpRLDbL.js +0 -1
- package/dist/public/assets/_BhpRLDbL.js.br +0 -0
- package/dist/public/assets/_BkKcjMAC.js +0 -1
- package/dist/public/assets/_BkcPY2j0.js.br +0 -0
- package/dist/public/assets/_BlTVd_3d.js +0 -1
- package/dist/public/assets/_BlqlLmEY.js +0 -1
- package/dist/public/assets/_BoNfxc9P.js +0 -1
- package/dist/public/assets/_BoPk1gXL.js +0 -1
- package/dist/public/assets/_BqswW9B9.js +0 -1
- package/dist/public/assets/_BricqzsO.js +0 -1
- package/dist/public/assets/_BrreckIa.js +0 -1
- package/dist/public/assets/_BsJZPHmz.js.br +0 -0
- package/dist/public/assets/_BtRYwaBb.js +0 -1
- package/dist/public/assets/_BvPBKjRP.js +0 -1
- package/dist/public/assets/_BvPBKjRP.js.br +0 -0
- package/dist/public/assets/_ByrrjMU9.js +0 -1
- package/dist/public/assets/_BzGHediB.js.br +0 -0
- package/dist/public/assets/_BzvTKm92.js +0 -1
- package/dist/public/assets/_C-EkQeP_.js.br +0 -0
- package/dist/public/assets/_C0Ib7MZF.js.br +0 -0
- package/dist/public/assets/_C2p1Z5Lf.js +0 -86
- package/dist/public/assets/_C2p1Z5Lf.js.br +0 -0
- package/dist/public/assets/_C3iiOlxd.js +0 -1
- package/dist/public/assets/_C81nSl09.js.br +0 -0
- package/dist/public/assets/_C8bqYk4J.js.br +0 -0
- package/dist/public/assets/_C98JZr09.js.br +0 -0
- package/dist/public/assets/_CB4VkmGZ.js +0 -1
- package/dist/public/assets/_CCVkYcN5.js.br +0 -0
- package/dist/public/assets/_CDY0RpYX.js.br +0 -0
- package/dist/public/assets/_CE2GEqMx.js +0 -1
- package/dist/public/assets/_CE2GEqMx.js.br +0 -0
- package/dist/public/assets/_CFUREq1M.js.br +0 -0
- package/dist/public/assets/_CHdh6bII.js +0 -1
- package/dist/public/assets/_CHdpLB95.js.br +0 -0
- package/dist/public/assets/_CKLGAGKJ.js.br +0 -0
- package/dist/public/assets/_CMRt2lyQ.js +0 -1
- package/dist/public/assets/_CN1zW1AT.js +0 -1
- package/dist/public/assets/_CN1zW1AT.js.br +0 -0
- package/dist/public/assets/_CUILmj9R.js +0 -1
- package/dist/public/assets/_CUhP8KQ8.js +0 -1
- package/dist/public/assets/_CUsrMpdL.js.br +0 -0
- package/dist/public/assets/_CVG0_w9T.js +0 -1
- package/dist/public/assets/_CWG813ur.js.br +0 -0
- package/dist/public/assets/_CY87Y7QL.js.br +0 -0
- package/dist/public/assets/_CYAsKva_.js +0 -1
- package/dist/public/assets/_CajKYNSY.js +0 -1
- package/dist/public/assets/_Cb_k_JA_.js.br +0 -0
- package/dist/public/assets/_Ce8PlfMD.js +0 -1
- package/dist/public/assets/_CfGEGt_k.js.br +0 -0
- package/dist/public/assets/_CfdK8EeQ.js.br +0 -0
- package/dist/public/assets/_CgOKmAwr.js +0 -1
- package/dist/public/assets/_CiYQhf81.js.br +0 -0
- package/dist/public/assets/_Cj9DHPRL.js +0 -1
- package/dist/public/assets/_ClHPjF-1.js.br +0 -0
- package/dist/public/assets/_Cmmdd2e3.js.br +0 -0
- package/dist/public/assets/_Cn9Ia4SS.js +0 -1
- package/dist/public/assets/_Cn9Ia4SS.js.br +0 -0
- package/dist/public/assets/_CnTzFbuG.js +0 -1
- package/dist/public/assets/_CqCenHOp.js.br +0 -0
- package/dist/public/assets/_CtqGSS84.js.br +0 -0
- package/dist/public/assets/_CttfwM-c.js +0 -1
- package/dist/public/assets/_CxA3Yab0.js.br +0 -0
- package/dist/public/assets/_Cx_aJfDp.js.br +0 -0
- package/dist/public/assets/_D2L_ILOW.js +0 -1
- package/dist/public/assets/_D47lCu0c.js +0 -1
- package/dist/public/assets/_D5W-uGIK.js +0 -1
- package/dist/public/assets/_D6BbZLrc.js +0 -1
- package/dist/public/assets/_D6RVeCAn.js +0 -1
- package/dist/public/assets/_D75V4jV-.js +0 -1
- package/dist/public/assets/_D9r_Fn0I.js.br +0 -0
- package/dist/public/assets/_DBD57l1T.js.br +0 -0
- package/dist/public/assets/_DCWILZgL.js +0 -1
- package/dist/public/assets/_DEOryr7w.js.br +0 -0
- package/dist/public/assets/_DF54Iz7o.js +0 -1
- package/dist/public/assets/_DFamU2Uj.js +0 -2
- package/dist/public/assets/_DFamU2Uj.js.br +0 -0
- package/dist/public/assets/_DHmBuyCO.js +0 -1
- package/dist/public/assets/_DHmBuyCO.js.br +0 -0
- package/dist/public/assets/_DJqEBkNd.js.br +0 -0
- package/dist/public/assets/_DL3w8c_p.js.br +0 -0
- package/dist/public/assets/_DLVL-4MP.js +0 -1
- package/dist/public/assets/_DM60dKRs.js.br +0 -0
- package/dist/public/assets/_DMJHTH74.js.br +0 -0
- package/dist/public/assets/_DMLv6KA6.js +0 -1
- package/dist/public/assets/_DQYpgyzr.js +0 -1
- package/dist/public/assets/_DQYpgyzr.js.br +0 -0
- package/dist/public/assets/_DQyjuXTi.js.br +0 -0
- package/dist/public/assets/_DRHCy0UF.js.br +0 -0
- package/dist/public/assets/_DSUBv-Bl.js.br +0 -0
- package/dist/public/assets/_DUFM9qLV.js +0 -1
- package/dist/public/assets/_DUFM9qLV.js.br +0 -0
- package/dist/public/assets/_DUs3ZGbj.js.br +0 -0
- package/dist/public/assets/_DX5u6Wvm.js.br +0 -0
- package/dist/public/assets/_DZvkgS3V.js.br +0 -0
- package/dist/public/assets/_Dbm6zAQS.js.br +0 -0
- package/dist/public/assets/_Ddf1gumD.js +0 -1
- package/dist/public/assets/_De6E9M7R.js +0 -1
- package/dist/public/assets/_DgWKSW-Y.js.br +0 -0
- package/dist/public/assets/_DhEN6T4v.js +0 -1
- package/dist/public/assets/_Di1ccq_2.js.br +0 -0
- package/dist/public/assets/_DifjKObE.js.br +0 -0
- package/dist/public/assets/_Dn10ABa-.js +0 -1
- package/dist/public/assets/_Do1ltY2a.js.br +0 -0
- package/dist/public/assets/_DomK7Scb.js.br +0 -0
- package/dist/public/assets/_DtWggCxt.js +0 -1
- package/dist/public/assets/_DtqqybyQ.js +0 -1
- package/dist/public/assets/_DvKnakqk.js.br +0 -0
- package/dist/public/assets/_DxD_AC3a.js.br +0 -0
- package/dist/public/assets/_Dxo7m9cG.js +0 -1
- package/dist/public/assets/_DzKW89Sx.js.br +0 -0
- package/dist/public/assets/_DzTHCioH.js +0 -1
- package/dist/public/assets/_EefWj858.js.br +0 -0
- package/dist/public/assets/_FlITqTCo.js.br +0 -0
- package/dist/public/assets/_GkEw2S0T.js +0 -1
- package/dist/public/assets/_HM_QqtJi.js.br +0 -0
- package/dist/public/assets/_HmkI4Rfn.js.br +0 -0
- package/dist/public/assets/_JEvx8ub4.js.br +0 -0
- package/dist/public/assets/_JOb8B3tz.js +0 -1
- package/dist/public/assets/_LEIhjFrO.js +0 -1
- package/dist/public/assets/_STJhwy7U.js +0 -1
- package/dist/public/assets/_TrcWRD8T.js.br +0 -0
- package/dist/public/assets/_UaKPY71M.js.br +0 -0
- package/dist/public/assets/_UhK3lkm0.js +0 -1
- package/dist/public/assets/_Zeftz3t1.js +0 -1
- package/dist/public/assets/__cyRVmTO.js.br +0 -0
- package/dist/public/assets/_awfYTHit.js +0 -1
- package/dist/public/assets/_dsj7vMTW.js.br +0 -0
- package/dist/public/assets/_eqpiOhSM.js +0 -1
- package/dist/public/assets/_iutZ4EDe.js.br +0 -0
- package/dist/public/assets/_kWQ0dtYZ.js.br +0 -0
- package/dist/public/assets/_knvMqXQh.js +0 -1
- package/dist/public/assets/_lwC7sIgC.js +0 -1
- package/dist/public/assets/_m2tRa0jk.js.br +0 -0
- package/dist/public/assets/_pXG8fRON.js.br +0 -0
- package/dist/public/assets/_r541ENtr.js +0 -1
- package/dist/public/assets/_rrUx1wn3.js +0 -1
- package/dist/public/assets/_tJvcu7sD.js +0 -1
- package/dist/public/assets/_vcLBrU2m.js.br +0 -0
- package/dist/public/assets/_xZC4Vm70.js +0 -1
- package/dist/public/assets/_yAr5r-uL.js +0 -1
- package/dist/public/assets/_yUmRJIJ6.js.br +0 -0
- package/dist/public/assets/files-view-CTadakLK.js +0 -2
- package/dist/public/assets/manage-workspace-HUAS6qjy.js +0 -2
- package/dist/public/assets/new-CirJkJFl.js +0 -1
- package/dist/public/assets/new-workspace-C3t1nA6z.js +0 -2
- package/dist/public/assets/review-view-DKPNtgmc.js +0 -2
- package/dist/public/assets/settings-CirJkJFl.js +0 -1
- package/dist/public/assets/settings-page-DH-9cN-8.js +0 -2
- package/dist/public/assets/styles-CIeNhVxC.css +0 -1
- package/dist/public/assets/styles-CIeNhVxC.css.br +0 -0
- package/dist/public/assets/w-CirJkJFl.js +0 -1
- package/dist/public/assets/w._-BnShhzdq.js +0 -1
- package/dist/public/assets/w._-CirJkJFl.js +0 -1
- package/dist/public/assets/w._-aCTYfruH.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
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dylanpiercey/work",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Web GUI for agentic dev workspaces",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,13 +26,14 @@
|
|
|
26
26
|
"scripts": {
|
|
27
27
|
"dev": "marko-run dev src/entry.ts",
|
|
28
28
|
"postinstall": "chmod +x node_modules/node-pty/prebuilds/*/spawn-helper node_modules/node-pty/build/Release/spawn-helper 2>/dev/null || true",
|
|
29
|
-
"build": "node scripts/agents-catalog.mjs && marko-run build src/entry.ts",
|
|
29
|
+
"build": "node scripts/agents-catalog.mjs && marko-run build src/entry.ts && node scripts/build-rtc-helper.mjs",
|
|
30
30
|
"check": "node scripts/agents-catalog.mjs && rm -f tsconfig.tsbuildinfo && mtc",
|
|
31
31
|
"preview": "PORT=7171 node dist/index.mjs",
|
|
32
32
|
"format": "prettier . -w",
|
|
33
33
|
"format:check": "prettier --check ."
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"node-datachannel": "0.33.4",
|
|
36
37
|
"node-pty": "1.2.0-beta.15"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|