@seanhogg/builderforce-agents 2026.10.10 → 2026.10.11
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/dist/{acp-cli-DcKpPsJa.js → acp-cli-C23mmrQt.js} +1 -1
- package/dist/{acp-cli-BxH-eUDl.js → acp-cli-D6F-D5JB.js} +1 -1
- package/dist/{agent-cXF-aL0g.js → agent-B-2r1Lr_.js} +1 -1
- package/dist/{agent-wJmvciTM.js → agent-BI9qSnSp.js} +1 -1
- package/dist/{agentbot-cli-Cub3Abbt.js → agentbot-cli-Cyrhr5jX.js} +1 -1
- package/dist/{agentbot-cli-CTRvEfBp.js → agentbot-cli-sC55m-XS.js} +1 -1
- package/dist/{agents-Cr7WO73I.js → agents-CMThT_Bj.js} +1 -1
- package/dist/agents-Chz9nfm2.js +1 -0
- package/dist/{api-key-rotation-CHBjUwUJ.js → api-key-rotation-CyCi-UqR.js} +1 -1
- package/dist/{audio-preflight-CWFuqbao.js → audio-preflight-B411b2-y.js} +1 -1
- package/dist/{audio-preflight-F2e3Y4CW.js → audio-preflight-Cs4eUjQk.js} +1 -1
- package/dist/{audio-preflight-Dm9zyfJq.js → audio-preflight-CvvHdoWy.js} +1 -1
- package/dist/{audit-DGnEhZYe.js → audit-B-USV03V.js} +1 -1
- package/dist/{audit-DBjjjW93.js → audit-SKNPS-K2.js} +1 -1
- package/dist/auth-choice-CChsMy-F.js +1 -0
- package/dist/{auth-choice-9gZuOvPS.js → auth-choice-CCib_yVL.js} +1 -1
- package/dist/auth-choice-DSnpkrMc.js +1 -0
- package/dist/{auth-choice-BoZFVmEa.js → auth-choice-DzBqqq7i.js} +1 -1
- package/dist/auth-choice.apply-6f3Jb_lS.js +1 -0
- package/dist/{auth-choice.apply-CcatXiNo.js → auth-choice.apply-BgOXoS8X.js} +1 -1
- package/dist/{auth-choice.apply-BHLQeym9.js → auth-choice.apply-DBuvopiF.js} +1 -1
- package/dist/auth-choice.apply-DeXnLwVS.js +1 -0
- package/dist/auth-choice.apply.transformers-CZDuBaOr.js +1 -0
- package/dist/{auth-choice.apply.transformers-CIn3fs7K.js → auth-choice.apply.transformers-Df9l_jRz.js} +2 -2
- package/dist/{auth-choice.apply.transformers-1plI0MUg.js → auth-choice.apply.transformers-DmdxpHGz.js} +2 -2
- package/dist/{auth-choice.apply.transformers-D5OrjEHo.js → auth-choice.apply.transformers-dn7l6XyJ.js} +1 -1
- package/dist/{auth-json-D1ite-pW.js → auth-json-BB-VBn5E.js} +1 -1
- package/dist/{auth-json-CN3MWw57.js → auth-json-BVyos95N.js} +1 -1
- package/dist/{auth-json-HGu227VM.js → auth-json-CoOe4tEg.js} +1 -1
- package/dist/{auth-json-DZ7E50Y1.js → auth-json-wrKixZxh.js} +1 -1
- package/dist/{auth-profiles-C1VbcUOm.js → auth-profiles-pt7Tr4HA.js} +1 -1
- package/dist/{auth-token-CyVfNEQb.js → auth-token-BE67qxLw.js} +1 -1
- package/dist/{auth-token-CoQ5ePPl.js → auth-token-BPHeoBAW.js} +1 -1
- package/dist/{banner-DY-L7_eI.js → banner-ErBINvbk.js} +1 -1
- package/dist/{browser-cli-D2O94twn.js → browser-cli-BZc64-Xx.js} +1 -1
- package/dist/{browser-cli-CoRx_4iM.js → browser-cli-CoxVKdon.js} +1 -1
- package/dist/build-info.json +3 -3
- package/dist/{builderforce-2EpP2M8q.js → builderforce-B9187Tm9.js} +4 -4
- package/dist/{builderforce-Cyg20uU8.js → builderforce-BLqHwgeu.js} +4 -4
- package/dist/builderforce-api-DKgXl8BH.js +1 -0
- package/dist/builderforce-api-DcPAGsla.js +1 -0
- package/dist/builderforce-onboarding-CaPJZSvw.js +24 -0
- package/dist/builderforce-onboarding-RXFb0gct.js +24 -0
- package/dist/{builderforcellm-syscheck-CprBhARf.js → builderforcellm-syscheck-9ksvqHYX.js} +1 -1
- package/dist/{builderforcellm-syscheck-DrFJ638L.js → builderforcellm-syscheck-F5JMAr3p.js} +1 -1
- package/dist/{call-DxPWzV-k.js → call-BnAs_SER.js} +1 -1
- package/dist/{call-DFjBq0H2.js → call-D1Opj5ev.js} +1 -1
- package/dist/{call-DmAU4cRX.js → call-Du2LiaX6.js} +1 -1
- package/dist/{call-BbRf8gFM.js → call-T8ciwMTA.js} +1 -1
- package/dist/{channel-options-d4EwVQD0.js → channel-options-B7sRMp2v.js} +1 -1
- package/dist/{channel-options-CDixz6dT.js → channel-options-rhDBCtlp.js} +1 -1
- package/dist/{channel-web-DJa8JC9W.js → channel-web-CcCqUQrJ.js} +1 -1
- package/dist/{channels-cli-BgKy0MbE.js → channels-cli-BjnLW14T.js} +1 -1
- package/dist/{channels-cli-nNW0ezPM.js → channels-cli-DVWUBsmc.js} +1 -1
- package/dist/chrome-Brg9KsB9.js +4 -0
- package/dist/{chrome-BnEbJV3D.js → chrome-CFmcixaE.js} +1 -1
- package/dist/{chrome-a3X9_-nf.js → chrome-DXt86tmV.js} +1 -1
- package/dist/cli/daemon-cli.js +1 -1
- package/dist/{cli-DkWt7p2x.js → cli-BUqtALJK.js} +1 -1
- package/dist/{cli-C5MbcECQ.js → cli-K4reS6IS.js} +1 -1
- package/dist/{coding-tools.policy-NEPm7Mz1.js → coding-tools.policy-D9Ba8eDh.js} +1 -1
- package/dist/{coding-tools.policy-6qh9acJy.js → coding-tools.policy-ZhOdlcEI.js} +1 -1
- package/dist/{command-registry-CDcuHGpx.js → command-registry-B7uAoROP.js} +1 -1
- package/dist/{command-registry-hHegQvBn.js → command-registry-CW16Mk2Y.js} +1 -1
- package/dist/{completion-cli-Bqr0W4L6.js → completion-cli-ZvXrCQqk.js} +1 -1
- package/dist/{completion-cli-Ch9ozmkg.js → completion-cli-gyvx5ZXu.js} +1 -1
- package/dist/{completion-cli-Do4vXo1k.js → completion-cli-n8UsdT91.js} +1 -1
- package/dist/{completion-cli-Ck0FTqPT.js → completion-cli-sKReGv3d.js} +1 -1
- package/dist/{config-_1Ca6jGb.js → config-BgV_FYSq.js} +1 -1
- package/dist/{config-toczWD3q.js → config-BpChMIJ6.js} +1 -1
- package/dist/{config-BTWlKwtB.js → config-D01EgOky.js} +1 -1
- package/dist/{config-27_FNba3.js → config-Dsnbi-a3.js} +1 -1
- package/dist/{config-cli-DeiQz5sY.js → config-cli-Bpo74mE5.js} +1 -1
- package/dist/{config-cli-CfczShaZ.js → config-cli-CF31O_5s.js} +1 -1
- package/dist/{config-guard-CD-Wq8kk.js → config-guard-BRUOk5YL.js} +1 -1
- package/dist/{config-guard-ClVl2FvD.js → config-guard-BUpQiSTW.js} +1 -1
- package/dist/{config-guard-B4in8l8I.js → config-guard-USCN-dq0.js} +1 -1
- package/dist/{config-validation-jpeXzoU3.js → config-validation-BGpSeNbh.js} +1 -1
- package/dist/{config-validation-C6u-z9bJ.js → config-validation-CdBJ-tZq.js} +1 -1
- package/dist/{configure-3W9C5LiT.js → configure-CWr61Ph2.js} +1 -1
- package/dist/configure-DhazB2qh.js +1 -0
- package/dist/{configure-BtXQW7ue.js → configure-DlcO1tWx.js} +1 -1
- package/dist/configure-MXheujvX.js +1 -0
- package/dist/{control-service-CJuuqNOE.js → control-service-2PkCt256.js} +1 -1
- package/dist/{control-service-qKfWP7VD.js → control-service-CcsbseZS.js} +1 -1
- package/dist/{control-service-izGyCWQs.js → control-service-qK1oboMo.js} +1 -1
- package/dist/{control-service-BbsswoMy.js → control-service-y3GYvIBg.js} +1 -1
- package/dist/{cron-cli-BrOM4s6N.js → cron-cli-BYu_lA8i.js} +1 -1
- package/dist/{cron-cli-CwtTX6pg.js → cron-cli-D_Og20iB.js} +1 -1
- package/dist/{daemon-cli-DyVsMf8p.js → daemon-cli-BNzthScZ.js} +1 -1
- package/dist/{daemon-cli-DlwOVDbt.js → daemon-cli-Bh3p0hui.js} +1 -1
- package/dist/{daemon-cli-Br0wu9xQ.js → daemon-cli-DxxKiKVN.js} +1 -1
- package/dist/{daemon-cli-DmicpZED.js → daemon-cli-emNxLkIw.js} +1 -1
- package/dist/{daemon-runtime-CtOr1ncS.js → daemon-runtime-9XitJmIL.js} +1 -1
- package/dist/{daemon-runtime-B4UjqdyJ.js → daemon-runtime-Dx800VUt.js} +1 -1
- package/dist/{deliver-BpLm3ktn.js → deliver--6OBF3LL.js} +1 -1
- package/dist/{deliver-9o_SE4ZK.js → deliver-ADpnRGRf.js} +1 -1
- package/dist/{deliver-D2VAVelb.js → deliver-BM6-damm.js} +1 -1
- package/dist/{deliver-BuZu68tp.js → deliver-CsG0cHbZ.js} +1 -1
- package/dist/{deps-CkJiJ6wc.js → deps-Dg_9rfXK.js} +1 -1
- package/dist/{devices-cli-BfXeDnbx.js → devices-cli-B8DXzcRP.js} +1 -1
- package/dist/{devices-cli-B9G6YOsS.js → devices-cli-BZkdWSx-.js} +1 -1
- package/dist/{directory-cli-BRCaiGOn.js → directory-cli-B78pAVI_.js} +1 -1
- package/dist/{directory-cli-D5ciZ5fY.js → directory-cli-CSaRkkL8.js} +1 -1
- package/dist/{dm-policy-shared-CRZpjRv0.js → dm-policy-shared-B9lW-AsK.js} +1 -1
- package/dist/{dm-policy-shared-Dhw9_6mi.js → dm-policy-shared-DYZ_T-az.js} +1 -1
- package/dist/{dns-cli-CgZ7oMcT.js → dns-cli-CLPGOFA1.js} +1 -1
- package/dist/{dns-cli-C4f4Tyij.js → dns-cli-dr5dHzfI.js} +1 -1
- package/dist/{doctor-completion-BjBTLcoC.js → doctor-completion-94zme499.js} +1 -1
- package/dist/{doctor-completion-Ccs-JEvV.js → doctor-completion-CbF34DIH.js} +1 -1
- package/dist/{embedded-cvG_LpfQ.js → embedded-D-citLF2.js} +6 -6
- package/dist/{embedded-helpers-CEsr3aQ0.js → embedded-helpers-C9jpiwlw.js} +1 -1
- package/dist/{embedded-helpers-DK8_apW0.js → embedded-helpers-DdU30lmt.js} +1 -1
- package/dist/entry.js +1 -1
- package/dist/{exec-approvals-cli-YuOu7mVg.js → exec-approvals-cli-CS_uabo7.js} +1 -1
- package/dist/{exec-approvals-cli-BPFi82B0.js → exec-approvals-cli-ktB7M7WE.js} +1 -1
- package/dist/extensionAPI.js +1 -1
- package/dist/{gateway-cli-CiHNwzdS.js → gateway-cli-CKcoLVMA.js} +5 -5
- package/dist/{gateway-cli-z47dfosr.js → gateway-cli-CuXBDBWe.js} +5 -5
- package/dist/{gateway-rpc-BXR_lVIx.js → gateway-rpc-B02y0PnE.js} +1 -1
- package/dist/{gateway-rpc-ByUcnQ7W.js → gateway-rpc-ff1RVb0_.js} +1 -1
- package/dist/{gemini-auth-CkD5jCPh.js → gemini-auth-DDR12zst.js} +1 -1
- package/dist/health-D0DZmCmh.js +1 -0
- package/dist/{health-yS3NRKvY.js → health-FO8MG5Ur.js} +1 -1
- package/dist/{health-DVo8a9yg.js → health-zrsgFZmR.js} +1 -1
- package/dist/{hooks-cli-B0lVee-j.js → hooks-cli-5Y4hnSX9.js} +1 -1
- package/dist/{hooks-cli-DsVmrQAG.js → hooks-cli-DpHZzRo2.js} +1 -1
- package/dist/index.js +2 -2
- package/dist/{ink-session-BitZ1wcY.js → ink-session-Dt9Q4iH-.js} +2 -2
- package/dist/{ink-session-CyAqXDla.js → ink-session-N8wCBzwk.js} +2 -2
- package/dist/{installs-CWd54ARy.js → installs-B_t2YXgq.js} +1 -1
- package/dist/{installs-C9A8QFiF.js → installs-DFiF4lGy.js} +1 -1
- package/dist/{io-3R_ZyUxB.js → io-BLBq4T2o.js} +1 -1
- package/dist/{io-DSIGyPrT.js → io-CXN4uLS2.js} +1 -1
- package/dist/{io-6jLoKffb.js → io-Ckd4NlvH.js} +1 -1
- package/dist/{io-CohJffHG.js → io-D9hC2aG0.js} +1 -1
- package/dist/{lifecycle-core-BpMvDXy1.js → lifecycle-core-D9Dg5Qps.js} +1 -1
- package/dist/{lifecycle-core-Dwb4gHjZ.js → lifecycle-core-uxjxTzFv.js} +1 -1
- package/dist/login-B3sDAgHb.js +1 -0
- package/dist/{login-C_ZdMOvv.js → login-CwwuaXtb.js} +1 -1
- package/dist/{login-DtDUyFO3.js → login-D1bVUPlv.js} +1 -1
- package/dist/{login-CEnjUo5c.js → login-GLDax56V.js} +1 -1
- package/dist/{login-qr-B9lyIZVD.js → login-qr-CbiUcBLy.js} +1 -1
- package/dist/{login-qr-BCBsxwhT.js → login-qr-Cp0YqK4e.js} +1 -1
- package/dist/{logs-cli-CdM5W3HE.js → logs-cli-Cy11HfSG.js} +1 -1
- package/dist/{logs-cli-jh5Xn3TD.js → logs-cli-nD36c-Y1.js} +1 -1
- package/dist/{manager-CRba8roB.js → manager-BeohB4-8.js} +1 -1
- package/dist/{manager-B3IJ_IKf.js → manager-CTTXDBt3.js} +1 -1
- package/dist/{manager-TGVy_fAb.js → manager-CoQMlcrf.js} +1 -1
- package/dist/{manager-DwywI_5-.js → manager-DSz61dXv.js} +1 -1
- package/dist/{memory-cli-BlayFTAM.js → memory-cli-BpAiRntI.js} +1 -1
- package/dist/{memory-cli-DRz4wtHk.js → memory-cli-CbkWGjRn.js} +1 -1
- package/dist/{memory-cli-PdyTQ84w.js → memory-cli-CrBMLM2P.js} +1 -1
- package/dist/{memory-cli-ivAs7q7v.js → memory-cli-CveeVOWH.js} +1 -1
- package/dist/{model-catalog-CQOdhMUY.js → model-catalog-B29yeBYS.js} +1 -1
- package/dist/{model-catalog-CiiFJX77.js → model-catalog-BeBXvbFm.js} +1 -1
- package/dist/model-catalog-CMKHKuBL.js +1 -0
- package/dist/{model-catalog-C6UrZ0uG.js → model-catalog-DjNiebr7.js} +1 -1
- package/dist/{model-discovery-C9Xm95uL.js → model-discovery-D0i1JpiL.js} +1 -1
- package/dist/{model-picker-swoSwauV.js → model-picker-CGDNPRPc.js} +1 -1
- package/dist/model-picker-CGEF8yhc.js +1 -0
- package/dist/model-picker-DeUNOC78.js +1 -0
- package/dist/{model-picker-BUePD7Zg.js → model-picker-EIhpfOZa.js} +1 -1
- package/dist/{model-selection-9bRFKBI_.js → model-selection-DG9J_VTz.js} +1 -1
- package/dist/{models-BNivsd2o.js → models-BjIzVQYX.js} +2 -2
- package/dist/{models-DQeSIY6M.js → models-JoqOgEF5.js} +1 -1
- package/dist/{models-cli-KokGgWeP.js → models-cli-B2zbchgs.js} +1 -1
- package/dist/{models-cli-BcNxU4P_.js → models-cli-CkFdc8NN.js} +2 -2
- package/dist/{node-cli-DIMh3X2F.js → node-cli-CXnuxiBq.js} +1 -1
- package/dist/{node-cli-EmTU-Gh0.js → node-cli-oVyjVnb7.js} +1 -1
- package/dist/{nodes-cli-BX8TznFK.js → nodes-cli-BBVotxNt.js} +1 -1
- package/dist/{nodes-cli-DyHovdAc.js → nodes-cli-DVMBSUhK.js} +1 -1
- package/dist/{onboard-D4uXN5Ec.js → onboard-BItclJp0.js} +1 -1
- package/dist/{onboard-cB37uVxy.js → onboard-CqvHIvKj.js} +1 -1
- package/dist/{onboard-auth.credentials-yagR-VMG.js → onboard-auth.credentials-DneFSdYg.js} +1 -1
- package/dist/{onboard-auth.credentials-BuT-etnE.js → onboard-auth.credentials-DpitLlzw.js} +1 -1
- package/dist/onboard-channels-B91m5S3w.js +1 -0
- package/dist/onboard-channels-BOoPtYbF.js +1 -0
- package/dist/{onboard-channels-B6QDFkkK.js → onboard-channels-Dn0u5C-C.js} +1 -1
- package/dist/{onboard-channels-C8FCFn29.js → onboard-channels-vhtccaIV.js} +1 -1
- package/dist/onboard-custom-BN0uzSq_.js +1 -0
- package/dist/{onboard-custom-D1nd8Hlu.js → onboard-custom-BYIza2e7.js} +1 -1
- package/dist/onboard-custom-CCFthqto.js +1 -0
- package/dist/{onboard-custom-C_BI0ZXn.js → onboard-custom-Ckf0xKXY.js} +1 -1
- package/dist/{onboard-helpers-CGlLpagb.js → onboard-helpers-B8I5AVyb.js} +1 -1
- package/dist/{onboard-helpers-CckrS8_K.js → onboard-helpers-Ce_c4Raj.js} +1 -1
- package/dist/{onboard-helpers-Cf5dNq7-.js → onboard-helpers-CiHzTaFX.js} +1 -1
- package/dist/{onboard-helpers-BvIZ4-R5.js → onboard-helpers-DC-nMl-V.js} +1 -1
- package/dist/{onboard-interactive-vwqLS6pe.js → onboard-interactive-Cl2K3EYn.js} +1 -1
- package/dist/{onboard-interactive-gvfRcLOt.js → onboard-interactive-JNux9zfA.js} +1 -1
- package/dist/{onboard-interactive-CnXgQrpI.js → onboard-interactive-J_ObFzeW.js} +1 -1
- package/dist/{onboard-interactive-CoFFuSJT.js → onboard-interactive-OUNsvlh0.js} +1 -1
- package/dist/{onboard-remote-D5lR2lVm.js → onboard-remote-0-q7MG9t.js} +1 -1
- package/dist/{onboard-remote-BmSyHww1.js → onboard-remote-CgAAEZpq.js} +1 -1
- package/dist/{onboard-remote-CzzQMZ3X.js → onboard-remote-DKXHDdBD.js} +1 -1
- package/dist/{onboard-remote-DcuX8b2g.js → onboard-remote-cB8j9RG-.js} +1 -1
- package/dist/{onboard-skills-ILHIeg1R.js → onboard-skills-47upVdA2.js} +1 -1
- package/dist/{onboard-skills-BPlNN_-T.js → onboard-skills-9Um4TL2x.js} +1 -1
- package/dist/{onboard-skills-DIhjDMom.js → onboard-skills-DhCmvhJY.js} +1 -1
- package/dist/{onboard-skills-CI1OtWsE.js → onboard-skills-mI2kfvdT.js} +1 -1
- package/dist/{onboarding-DdKW5K8Y.js → onboarding-BSENgR9C.js} +5 -5
- package/dist/{onboarding-B9GqKO5L.js → onboarding-CIaZLNc1.js} +5 -5
- package/dist/{onboarding.finalize-CcuO4Yxw.js → onboarding.finalize-BwOpvoPE.js} +1 -1
- package/dist/{onboarding.finalize-D3mTpOdc.js → onboarding.finalize-yMK-g7Uy.js} +1 -1
- package/dist/{onboarding.gateway-config-Cd7_bXVs.js → onboarding.gateway-config-Kn1O-QFl.js} +1 -1
- package/dist/{onboarding.gateway-config-Bd8HJkso.js → onboarding.gateway-config-huOjFf8D.js} +1 -1
- package/dist/{openai-model-default-Cp3nf21W.js → openai-model-default-CH2-2Hvk.js} +1 -1
- package/dist/{openai-model-default-BMRrqTmH.js → openai-model-default-pfoEzWYJ.js} +1 -1
- package/dist/{outbound-BRInCJD9.js → outbound-BdeHcMAo.js} +1 -1
- package/dist/{outbound-CAtBpFoD.js → outbound-BylJYD7n.js} +1 -1
- package/dist/{outbound-OI-t5zZ0.js → outbound-CAirtWr1.js} +1 -1
- package/dist/{outbound-CnIvOJlU.js → outbound-VNcvF2MG.js} +1 -1
- package/dist/{outbound-send-deps-m6DqOma_.js → outbound-send-deps-B3Lg-uqF.js} +1 -1
- package/dist/{pairing-cli-CEr0yEsc.js → pairing-cli-5RtPvz2i.js} +1 -1
- package/dist/{pairing-cli-Dxfoni-F.js → pairing-cli-C_Mj6Dy4.js} +1 -1
- package/dist/{pairing-labels-3j_iRYOO.js → pairing-labels-BJPrScRl.js} +1 -1
- package/dist/{pairing-labels-BW5jQZlr.js → pairing-labels-oA-nKTaW.js} +1 -1
- package/dist/{pairing-store-QDb6lhIU.js → pairing-store-YRy7EBgI.js} +1 -1
- package/dist/{pairing-store-CbvMJhD3.js → pairing-store-ti3FEkmr.js} +1 -1
- package/dist/{plugin-auto-enable-BV9K9Vhr.js → plugin-auto-enable-Cupr4wbt.js} +1 -1
- package/dist/{plugin-auto-enable-DDry2fA6.js → plugin-auto-enable-D8gKiE3F.js} +1 -1
- package/dist/plugin-registry-BEfyc2f_.js +1 -0
- package/dist/{plugin-registry-C-_GA65s.js → plugin-registry-BoPaef5I.js} +1 -1
- package/dist/{plugin-registry-SAdxNUwm.js → plugin-registry-CxnuHO_n.js} +1 -1
- package/dist/plugin-registry-D0tIqo8L.js +1 -0
- package/dist/plugin-sdk/agent-runtime/src/infra/workflow-telemetry.d.ts +12 -1
- package/dist/{plugins-BIG8NDB9.js → plugins-Cx29kkDj.js} +1 -1
- package/dist/{plugins-iAq-Gr8l.js → plugins-DJqou2hi.js} +1 -1
- package/dist/{plugins-cli-CpaVUv_r.js → plugins-cli-Bu-A8aGy.js} +1 -1
- package/dist/{plugins-cli-CPkSgvdL.js → plugins-cli-CGFsQDVW.js} +1 -1
- package/dist/{program-context-CpxTJP1m.js → program-context-ClBa4lUj.js} +1 -1
- package/dist/{program-BgDciyOQ.js → program-vVCzU0cH.js} +2 -2
- package/dist/{prompt-select-styled-Qb0DubNy.js → prompt-select-styled-BJPGccTJ.js} +1 -1
- package/dist/{prompt-select-styled-Bu7WPMzB.js → prompt-select-styled-BK74z6FF.js} +1 -1
- package/dist/{provider-auth-helpers-BpTnp2Yr.js → provider-auth-helpers-B84m5VMc.js} +1 -1
- package/dist/{provider-auth-helpers-CJTG_tVx.js → provider-auth-helpers-hNwpK_hl.js} +1 -1
- package/dist/{provider-dispatcher-TWwBT2aH.js → provider-dispatcher-BjR5DE3O.js} +1 -1
- package/dist/provider-dispatcher-DgOeVjcL.js +1 -0
- package/dist/{provider-usage-BdrU4cIE.js → provider-usage-B-wPVN_j.js} +1 -1
- package/dist/{provider-usage-Bn4ZrnU7.js → provider-usage-B8lFHp0K.js} +1 -1
- package/dist/{push-apns-C4sJnHbO.js → push-apns-BTPPvY81.js} +1 -1
- package/dist/{push-apns-CiD3rrVv.js → push-apns-CscYUS0D.js} +1 -1
- package/dist/{pw-ai-DSEj1QrV.js → pw-ai-CLS_VZ8p.js} +1 -1
- package/dist/{pw-ai-dNZY-qBs.js → pw-ai-D5og_rIf.js} +1 -1
- package/dist/{pw-ai-D8HJAvv-.js → pw-ai-DaxMmaVL.js} +1 -1
- package/dist/{qr-cli-qr-SFLZW.js → qr-cli-CAquM1Zk.js} +1 -1
- package/dist/{qr-cli-B45dCV0o.js → qr-cli-GsR8n1cm.js} +1 -1
- package/dist/{qr-cli-CMlAIzrD.js → qr-cli-kAKgaL-T.js} +1 -1
- package/dist/{qr-cli-CySNSEFj.js → qr-cli-uyxNf-cQ.js} +1 -1
- package/dist/{register.agent-BA6LIJSb.js → register.agent-BwTCfyeJ.js} +1 -1
- package/dist/{register.agent-D2uCH8jZ.js → register.agent-Dhdo3_7k.js} +1 -1
- package/dist/register.configure-B0m0G3ot.js +1 -0
- package/dist/register.configure-D3cbjmTz.js +1 -0
- package/dist/{register.maintenance-CPnm6L-m.js → register.maintenance-C6ocMld2.js} +1 -1
- package/dist/{register.maintenance-D8WmeEaD.js → register.maintenance-CbE2zSyc.js} +1 -1
- package/dist/{register.message-DiZRRAE5.js → register.message-Jn4u533_.js} +1 -1
- package/dist/{register.message-8iGDhO8h.js → register.message-Tu1hlM0m.js} +1 -1
- package/dist/{register.onboard-DMfqe2nX.js → register.onboard-B34211N6.js} +1 -1
- package/dist/{register.onboard-BoUicPRh.js → register.onboard-S1d2WAE4.js} +1 -1
- package/dist/{register.setup-BK6OEvY3.js → register.setup-CJPyAwCQ.js} +1 -1
- package/dist/{register.setup-CtcAR3JR.js → register.setup-Sg8f3nsH.js} +1 -1
- package/dist/{register.status-health-sessions-D6wdwPwV.js → register.status-health-sessions-BlgVxoZ4.js} +1 -1
- package/dist/{register.status-health-sessions-ZSufYw5j.js → register.status-health-sessions-DwADQJ74.js} +1 -1
- package/dist/{register.subclis-Dl6jPPsc.js → register.subclis-C9V_M-Lk.js} +1 -1
- package/dist/{register.subclis-EScCVgbV.js → register.subclis-pWn9XObB.js} +1 -1
- package/dist/{replies-DbkT_5BV.js → replies-BOGMDhSN.js} +1 -1
- package/dist/{replies-CzV-RFUG.js → replies-BXbV02ik.js} +1 -1
- package/dist/{replies-DIBQzxGp.js → replies-CUv671JF.js} +1 -1
- package/dist/{replies-Bd2RPZwQ.js → replies-DokbEfJD.js} +1 -1
- package/dist/{reply-Cd3vVnD7.js → reply-GY1C8tcv.js} +10 -10
- package/dist/{routes-BzfLvF8W.js → routes-DZntyPY6.js} +1 -1
- package/dist/{routes-lclJHOYY.js → routes-_iZdG1Fo.js} +1 -1
- package/dist/{rpc-BLqXRn5R.js → rpc-CbUnwStf.js} +1 -1
- package/dist/{rpc-DcQNGQlj.js → rpc-Cwm4gchc.js} +1 -1
- package/dist/{run-main-C3lmcvyV.js → run-main-DQMbgbcF.js} +1 -1
- package/dist/{runner-CviGu3Nk.js → runner-COldX-El.js} +3 -3
- package/dist/{runner-DwWmciCt.js → runner-Cu9NJouV.js} +1 -1
- package/dist/{runner-SxCr9kXD.js → runner-eTTUbLAK.js} +1 -1
- package/dist/{sandbox-BZibn6PX.js → sandbox-C4AKi2EX.js} +1 -1
- package/dist/{sandbox-z9t_PRf9.js → sandbox-DvKMuAXL.js} +1 -1
- package/dist/{sandbox-cli-BtGs0dBR.js → sandbox-cli-C0LhzYq_.js} +1 -1
- package/dist/{sandbox-cli-B8FpLgyY.js → sandbox-cli-De0iaoHB.js} +1 -1
- package/dist/{security-cli-D8Q8I7fn.js → security-cli-BvEfiO8m.js} +1 -1
- package/dist/{security-cli-IIMR7Pb4.js → security-cli-BzsQ0XQh.js} +1 -1
- package/dist/{send-DnMzjS7L.js → send-2dRKMWtl.js} +1 -1
- package/dist/{send-DerUBvXW.js → send-Aw8wK3vK.js} +1 -1
- package/dist/{send-BvroeIQ6.js → send-B7H8Ae5j.js} +1 -1
- package/dist/{send-4d9NswaD.js → send-BP5osGBo.js} +1 -1
- package/dist/{send-BU_-BGmf.js → send-BVal50Bi.js} +1 -1
- package/dist/{send-CxG2suVM.js → send-Bbo7TXLx.js} +1 -1
- package/dist/{send-CBBziNqM.js → send-BxoVLIy1.js} +1 -1
- package/dist/{send-dDpSBSBo.js → send-COKUbcqs.js} +1 -1
- package/dist/{send--12DIueA.js → send-CTw3PqN4.js} +1 -1
- package/dist/{send-UFtylOiq.js → send-CYGOPcKq.js} +1 -1
- package/dist/{send-DyF1Xy9K.js → send-ChGpVO3O.js} +1 -1
- package/dist/{send-Q-uTkSFE.js → send-Cqea2UFo.js} +1 -1
- package/dist/{send-j15662lv.js → send-CrFWgJKx.js} +1 -1
- package/dist/{send-gDb60Hk-.js → send-CwK8QBR3.js} +1 -1
- package/dist/{send-CceNWtYE.js → send-DqR7Rxzm.js} +1 -1
- package/dist/{send-CJHXQvVl.js → send-DxwfUIN-.js} +1 -1
- package/dist/{send-ByCVQQVz.js → send-KgN1P41U.js} +1 -1
- package/dist/{send-B1rJLLpr.js → send-bNp87SIq.js} +1 -1
- package/dist/{send-B_1BtyfA.js → send-kkm_zrHQ.js} +1 -1
- package/dist/{send-BJDzwYJN.js → send-l3ge4wkC.js} +1 -1
- package/dist/{server-context-DJZT7Upf.js → server-context-CQ2v4BAx.js} +1 -1
- package/dist/{server-context-owOmmyUM.js → server-context-CttALzrW.js} +1 -1
- package/dist/{server-node-events-54d8Rmjl.js → server-node-events-CIMO6Vae.js} +1 -1
- package/dist/{server-node-events-CSFVqgxX.js → server-node-events-iCF2ngcN.js} +1 -1
- package/dist/{session-BzQdcCqN.js → session-BJHsjD3z.js} +1 -1
- package/dist/{session-4FpEJvkE.js → session-C_b1ttHJ.js} +1 -1
- package/dist/{session-dirs-OxQuIvJW.js → session-dirs-Bvbgw0GC.js} +1 -1
- package/dist/{session-dirs-D_ARkyw0.js → session-dirs-DHaoq7zc.js} +1 -1
- package/dist/{session-utils-GMvum00v.js → session-utils-Dxou8SbO.js} +1 -1
- package/dist/{sessions-Bl1wwotX.js → sessions-BA8Se_bT.js} +1 -1
- package/dist/{sessions-CdanN_ZI.js → sessions-BuZVmOWt.js} +1 -1
- package/dist/{sessions-B5dwRhUC.js → sessions-DvbW0FNJ.js} +1 -1
- package/dist/{sessions-B1t7qeEn.js → sessions-DvqsIg0M.js} +1 -1
- package/dist/{shared-xj-xaKFi.js → shared-BBOiNdjf.js} +1 -1
- package/dist/{shared-BPN3qd7G.js → shared-C2orjbTD.js} +1 -1
- package/dist/{skill-scanner-U3AJgjqc.js → skill-scanner-BEvov9QH.js} +1 -1
- package/dist/{skill-scanner-DEmbPsRh.js → skill-scanner-OTLeRZ_p.js} +1 -1
- package/dist/{skills-cli-CIdnXa3B.js → skills-cli-C1BOgB3y.js} +1 -1
- package/dist/{skills-cli-BXbGr7vl.js → skills-cli-CFT2Aq5R.js} +1 -1
- package/dist/{skills-install-Btw_GHbI.js → skills-install-LlKntDHa.js} +1 -1
- package/dist/{skills-install-DMHQRpIl.js → skills-install-tx5Mahav.js} +1 -1
- package/dist/{status-DXaDS_0w.js → status-Bh8V7kjv.js} +1 -1
- package/dist/{status-BxeKmkVr.js → status-BtBHmhQh.js} +1 -1
- package/dist/{status-BkcmeZg6.js → status-CpwD4y9B.js} +1 -1
- package/dist/status-CqaTmyih.js +1 -0
- package/dist/{status-DouJcFzf.js → status-yXz8PUbL.js} +1 -1
- package/dist/{status.update-C9iy31xr.js → status.update-CdgsLBPg.js} +1 -1
- package/dist/{status.update-KYyRSDZY.js → status.update-hzMro-BT.js} +1 -1
- package/dist/{subagent-registry-Dr20nzwk.js → subagent-registry-CaRUNwCj.js} +1 -1
- package/dist/{subagent-registry-CyGxu3kP.js → subagent-registry-DDEN4oJi.js} +10 -10
- package/dist/{subagent-registry-BiXkIDeh.js → subagent-registry-DYYfeIc3.js} +1 -1
- package/dist/{system-cli-b4YgXPHv.js → system-cli-4aii1JYf.js} +1 -1
- package/dist/{system-cli-C7YzJeP4.js → system-cli-CfkDD3FV.js} +1 -1
- package/dist/{tui-D2sTsa4p.js → tui-DnVRxfI8.js} +2 -2
- package/dist/{tui-DY2oYbxk.js → tui-JfWoLGIV.js} +2 -2
- package/dist/{tui-cli-GW-qybY6.js → tui-cli-CGjg2Eb5.js} +1 -1
- package/dist/{tui-cli-wn3DmvUG.js → tui-cli-cd7Efw5u.js} +1 -1
- package/dist/{tui-setup-check-DJZCJokQ.js → tui-setup-check-BEHm9wwo.js} +1 -1
- package/dist/{tui-setup-check-BABAyl-e.js → tui-setup-check-DK8vdhLI.js} +1 -1
- package/dist/{tui-stream-assembler-ign_cPkv.js → tui-stream-assembler-8ud9oyMK.js} +1 -1
- package/dist/{tui-stream-assembler-q9GANTDr.js → tui-stream-assembler-Br15rhRH.js} +1 -1
- package/dist/{update-BUzcmoDf.js → update-B5yKFeGO.js} +1 -1
- package/dist/{update-D6U-V8Au.js → update-DodoQDCk.js} +1 -1
- package/dist/{update-cli-K5dGZmg8.js → update-cli-CfJJcSUS.js} +1 -1
- package/dist/{update-cli-CN0oxZ_A.js → update-cli-x8Ocbf-0.js} +1 -1
- package/dist/{usage-cli-CfEg1_NZ.js → usage-cli-CN7L1YRG.js} +1 -1
- package/dist/{usage-cli-CpbYMXxS.js → usage-cli-CQmokGkG.js} +1 -1
- package/dist/{web-DONGrYXq.js → web-BQPd6gQJ.js} +1 -1
- package/dist/{web-D-NSyF6b.js → web-BXLk9UT2.js} +1 -1
- package/dist/web-Btgs8oWv.js +1 -0
- package/dist/{webhooks-cli-B_f61rq7.js → webhooks-cli-DIo8p3lk.js} +1 -1
- package/dist/{webhooks-cli-Bi0t3w6P.js → webhooks-cli-DhxEtiFt.js} +1 -1
- package/dist/{whatsapp-actions-JbF2MrTV.js → whatsapp-actions-B7r9AyZN.js} +1 -1
- package/dist/{whatsapp-actions-BkCMhD9X.js → whatsapp-actions-DX2QU6Gs.js} +1 -1
- package/dist/{with-timeout-T07SJo4N.js → with-timeout-B_p5pWDv.js} +1 -1
- package/dist/{with-timeout-Bwq-GyUQ.js → with-timeout-GDLpcjW7.js} +1 -1
- package/dist/workflow-telemetry-BMTg5lPd.js +1 -0
- package/dist/workflow-telemetry-Bg8MVUr_.js +2 -0
- package/dist/workflow-telemetry-Do1UsYwM.js +1 -0
- package/dist/workflow-telemetry-DqBPhVL4.js +2 -0
- package/package.json +1 -1
- package/dist/agents-DsZ5vLKE.js +0 -1
- package/dist/auth-choice-Btd2Rxxd.js +0 -1
- package/dist/auth-choice-CVV9wRFN.js +0 -1
- package/dist/auth-choice.apply-BOK9XRCQ.js +0 -1
- package/dist/auth-choice.apply-Cv-BiV5Q.js +0 -1
- package/dist/auth-choice.apply.transformers-CXywS3GZ.js +0 -1
- package/dist/builderforce-onboarding-C89jVb-9.js +0 -24
- package/dist/builderforce-onboarding-D5A-wEs-.js +0 -24
- package/dist/chrome-DUBgoZpO.js +0 -4
- package/dist/configure-CWBBFk3F.js +0 -1
- package/dist/configure-fHVOAucW.js +0 -1
- package/dist/health-GLcAfqDz.js +0 -1
- package/dist/login-CPyEf5h6.js +0 -1
- package/dist/model-catalog-J7R-tJDu.js +0 -1
- package/dist/model-picker-D2bcWrtu.js +0 -1
- package/dist/model-picker-DO1HtEEm.js +0 -1
- package/dist/onboard-channels-CmqKsAoW.js +0 -1
- package/dist/onboard-channels-Db0P4iWl.js +0 -1
- package/dist/onboard-custom-BABqIYa4.js +0 -1
- package/dist/onboard-custom-VpW3UC8u.js +0 -1
- package/dist/plugin-registry-B-UOeWqM.js +0 -1
- package/dist/plugin-registry-BjMr3yXM.js +0 -1
- package/dist/provider-dispatcher-C4nHaNqn.js +0 -1
- package/dist/register.configure-DAL38e7r.js +0 -1
- package/dist/register.configure-DZG7-WVi.js +0 -1
- package/dist/status-BTYqHVha.js +0 -1
- package/dist/web-P6QsgmSD.js +0 -1
- package/dist/workflow-telemetry-B8Im0mPk.js +0 -1
- package/dist/workflow-telemetry-DLEnm5TI.js +0 -2
- package/dist/workflow-telemetry-Dc_oseV7.js +0 -2
- package/dist/workflow-telemetry-Dkm3mofI.js +0 -1
- /package/dist/{devtools-CI7JyCXv.js → devtools-Cg4F-l9O.js} +0 -0
- /package/dist/{devtools-eMFaIsAT.js → devtools-Dl2DACSO.js} +0 -0
- /package/dist/{github-copilot-token-D3gHtNUu.js → github-copilot-token-BlyiXyTy.js} +0 -0
- /package/dist/{github-copilot-token-DHP2kAiN.js → github-copilot-token-D5sB2AUI.js} +0 -0
- /package/dist/{onboard-hooks-Cenav0eW.js → onboard-hooks-BaOSgxs9.js} +0 -0
- /package/dist/{onboard-hooks-Ce20rwpW.js → onboard-hooks-fO5eeDe_.js} +0 -0
- /package/dist/{qmd-manager-DVd_aWEV.js → qmd-manager-BgplOjHN.js} +0 -0
- /package/dist/{qmd-manager-keHvLmvP.js → qmd-manager-COUi_Fqb.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{P as shouldLogVerbose,d as isRecord,j as logVerbose}from"./utils-BP60e80M.js";import{Kt as requireApiKey,Lt as stripReasoningTagsFromText,Qt as normalizeSecretInput,R as normalizeProviderId,Wt as getApiKeyForModel,qt as resolveApiKeyForProvider,tt as normalizeGoogleModelId,zt as nativeComplete}from"./auth-profiles-
|
|
1
|
+
import{P as shouldLogVerbose,d as isRecord,j as logVerbose}from"./utils-BP60e80M.js";import{Kt as requireApiKey,Lt as stripReasoningTagsFromText,Qt as normalizeSecretInput,R as normalizeProviderId,Wt as getApiKeyForModel,qt as resolveApiKeyForProvider,tt as normalizeGoogleModelId,zt as nativeComplete}from"./auth-profiles-pt7Tr4HA.js";import{t as logDebug}from"./logger-wuOr7HKl.js";import{n as runExec}from"./exec-COgsU9ql.js";import{t as normalizeBaseUrl$1}from"./normalize-base-url-D_sv6Zgt.js";import{i as readSharedEnvVar,n as isTruthyFlag,r as readRuntimeEnvVar,t as isOfflineMode}from"./env-file-DeS6x2OL.js";import{a as ensureBuilderForceAgentsModelsJson,i as discoverModels,r as discoverAuthStorage}from"./model-discovery-D0i1JpiL.js";import{i as modelSupportsVision,r as loadModelCatalog,t as findModelInCatalog}from"./model-catalog-BeBXvbFm.js";import{t as normalizeChatType}from"./chat-type-BSDVym_t.js";import{c as detectMime,f as isAudioFileName,m as kindFromMime,u as getFileExtension}from"./image-ops-CotJhwRR.js";import{r as formatUncaughtError,t as extractErrorCode}from"./errors-tAt19c1E.js";import{W as sanitizeUserFacingText}from"./embedded-helpers-DdU30lmt.js";import{n as collectProviderApiKeysForExecution,r as executeWithApiKeyRotation,t as parseGeminiAuth}from"./gemini-auth-DDR12zst.js";import{n as resolveToolDisplay,t as formatToolDetail}from"./tool-display-Cs4hDP1f.js";import{n as fetchWithTimeout}from"./fetch-timeout-Cb8Yj9Tw.js";import{t as fetchWithSsrFGuard}from"./fetch-guard-DnXqPKae.js";import{n as fetchRemoteMedia,t as MediaFetchError}from"./fetch-Cn_THzz8.js";import process$1 from"node:process";import os from"node:os";import path from"node:path";import{constants}from"node:fs";import crypto from"node:crypto";import{fileURLToPath}from"node:url";import fs$1 from"node:fs/promises";function extractTextFromChatContent(content,opts){let normalize=opts?.normalizeText??(text=>text.replace(/\s+/g,` `).trim()),joinWith=opts?.joinWith??` `;if(typeof content==`string`)return normalize(opts?.sanitizeText?opts.sanitizeText(content):content)||null;if(!Array.isArray(content))return null;let chunks=[];for(let block of content){if(!block||typeof block!=`object`||block.type!==`text`)continue;let text=block.text;if(typeof text!=`string`)continue;let value=opts?.sanitizeText?opts.sanitizeText(text):text;value.trim()&&chunks.push(value)}return normalize(chunks.join(joinWith))||null}function isAssistantMessage(msg){return msg?.role===`assistant`}function stripMinimaxToolCallXml(text){if(!text||!/minimax:tool_call/i.test(text))return text;let cleaned=text.replace(/<invoke\b[^>]*>[\s\S]*?<\/invoke>/gi,``);return cleaned=cleaned.replace(/<\/?minimax:tool_call>/gi,``),cleaned}function stripDowngradedToolCallText(text){if(!text||!/\[Tool (?:Call|Result)/i.test(text)&&!/\[Historical context/i.test(text))return text;let consumeJsonish=(input,start,options)=>{let{allowLeadingNewlines=!1}=options??{},index=start;for(;index<input.length;){let ch=input[index];if(ch===` `||ch===` `){index+=1;continue}if(allowLeadingNewlines&&(ch===`
|
|
2
2
|
`||ch===`\r`)){index+=1;continue}break}if(index>=input.length)return null;let startChar=input[index];if(startChar===`{`||startChar===`[`){let depth=0,inString=!1,escape=!1;for(let i=index;i<input.length;i+=1){let ch=input[i];if(inString){escape?escape=!1:ch===`\\`?escape=!0:ch===`"`&&(inString=!1);continue}if(ch===`"`){inString=!0;continue}if(ch===`{`||ch===`[`){depth+=1;continue}if((ch===`}`||ch===`]`)&&(--depth,depth===0))return i+1}return null}if(startChar===`"`){let escape=!1;for(let i=index+1;i<input.length;i+=1){let ch=input[i];if(escape){escape=!1;continue}if(ch===`\\`){escape=!0;continue}if(ch===`"`)return i+1}return null}let end=index;for(;end<input.length&&input[end]!==`
|
|
3
3
|
`&&input[end]!==`\r`;)end+=1;return end},cleaned=(input=>{let markerRe=/\[Tool Call:[^\]]*\]/gi,result=``,cursor=0;for(let match of input.matchAll(markerRe)){let start=match.index??0;if(start<cursor)continue;result+=input.slice(cursor,start);let index=start+match[0].length;for(;index<input.length&&(input[index]===` `||input[index]===` `);)index+=1;for(input[index]===`\r`&&(index+=1),input[index]===`
|
|
4
4
|
`&&(index+=1);index<input.length&&(input[index]===` `||input[index]===` `);)index+=1;if(input.slice(index,index+9).toLowerCase()===`arguments`){index+=9,input[index]===`:`&&(index+=1),input[index]===` `&&(index+=1);let end=consumeJsonish(input,index,{allowLeadingNewlines:!0});end!==null&&(index=end)}(input[index]===`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{F as shouldLogVerbose,M as logVerbose,f as isRecord}from"./utils-DbaBVFaK.js";import{N as sanitizeUserFacingText}from"./embedded-helpers-
|
|
1
|
+
import{F as shouldLogVerbose,M as logVerbose,f as isRecord}from"./utils-DbaBVFaK.js";import{N as sanitizeUserFacingText}from"./embedded-helpers-C9jpiwlw.js";import{t as logDebug}from"./logger-Bch0bx9c.js";import{n as runExec}from"./exec-DdcIjeyn.js";import{D as normalizeGoogleModelId,dt as nativeComplete,gt as getApiKeyForModel,lt as stripReasoningTagsFromText,mn as normalizeSecretInput,u as normalizeProviderId,vt as requireApiKey,yt as resolveApiKeyForProvider}from"./model-selection-DG9J_VTz.js";import{t as normalizeBaseUrl$1}from"./normalize-base-url-DmugqkQ6.js";import{i as readSharedEnvVar,n as isTruthyFlag,r as readRuntimeEnvVar,t as isOfflineMode}from"./env-file-D1MDi-AM.js";import{t as normalizeChatType}from"./chat-type-Cxpp3yM-.js";import{a as discoverAuthStorage,i as modelSupportsVision,o as discoverModels,r as loadModelCatalog,s as ensureBuilderForceAgentsModelsJson,t as findModelInCatalog}from"./model-catalog-DjNiebr7.js";import{r as formatUncaughtError,t as extractErrorCode}from"./errors-B1MIg3g-.js";import{c as detectMime,f as isAudioFileName,m as kindFromMime,u as getFileExtension}from"./image-ops-C8IUQKjn.js";import{n as resolveToolDisplay,t as formatToolDetail}from"./tool-display-ByOZtWvA.js";import{n as fetchWithTimeout}from"./fetch-timeout-BIqoSVfA.js";import{t as fetchWithSsrFGuard}from"./fetch-guard-8mwt3-hm.js";import{n as executeWithApiKeyRotation,r as parseGeminiAuth,t as collectProviderApiKeysForExecution}from"./api-key-rotation-CyCi-UqR.js";import{n as fetchRemoteMedia,t as MediaFetchError}from"./fetch-BuOLY9KP.js";import process$1 from"node:process";import{fileURLToPath}from"node:url";import{constants}from"node:fs";import os from"node:os";import path from"node:path";import crypto from"node:crypto";import fs$1 from"node:fs/promises";function formatTemplateValue(value){return value==null?``:typeof value==`string`?value:typeof value==`number`||typeof value==`boolean`||typeof value==`bigint`?String(value):typeof value==`symbol`||typeof value==`function`?value.toString():Array.isArray(value)?value.flatMap(entry=>entry==null?[]:typeof entry==`string`?[entry]:typeof entry==`number`||typeof entry==`boolean`||typeof entry==`bigint`?[String(entry)]:[]).join(`,`):``}function applyTemplate(str,ctx){return str?str.replace(/{{\s*(\w+)\s*}}/g,(_,key)=>{let value=ctx[key];return formatTemplateValue(value)}):``}const MB=1024*1024,DEFAULT_MAX_CHARS_BY_CAPABILITY={image:500,audio:void 0,video:500},DEFAULT_MAX_BYTES={image:10*MB,audio:20*MB,video:50*MB},DEFAULT_TIMEOUT_SECONDS={image:60,audio:60,video:120},DEFAULT_PROMPT={image:`Describe the image.`,audio:`Transcribe the audio.`,video:`Describe the video.`};70*MB;const DEFAULT_AUDIO_MODELS={groq:`whisper-large-v3-turbo`,openai:`gpt-4o-mini-transcribe`,deepgram:`nova-3`},AUTO_AUDIO_KEY_PROVIDERS=[`openai`,`groq`,`deepgram`,`google`],AUTO_IMAGE_KEY_PROVIDERS=[`openai`,`anthropic`,`google`,`minimax`,`zai`],AUTO_VIDEO_KEY_PROVIDERS=[`google`],DEFAULT_IMAGE_MODELS={openai:`gpt-5-mini`,anthropic:`claude-opus-4-6`,google:`gemini-3-flash-preview`,minimax:`MiniMax-VL-01`,zai:`glm-4.6v`},CLI_OUTPUT_MAX_BUFFER=5*MB;function coerceApiHost(params){let env=params.env??process.env,raw=params.apiHost?.trim()||env.MINIMAX_API_HOST?.trim()||params.modelBaseUrl?.trim()||`https://api.minimax.io`;try{return new URL(raw).origin}catch{}try{return new URL(`https://${raw}`).origin}catch{return`https://api.minimax.io`}}function pickString(rec,key){let v=rec[key];return typeof v==`string`?v:``}async function minimaxUnderstandImage(params){let apiKey=normalizeSecretInput(params.apiKey);if(!apiKey)throw Error(`MiniMax VLM: apiKey required`);let prompt=params.prompt.trim();if(!prompt)throw Error(`MiniMax VLM: prompt required`);let imageDataUrl=params.imageDataUrl.trim();if(!imageDataUrl)throw Error(`MiniMax VLM: imageDataUrl required`);if(!/^data:image\/(png|jpeg|webp);base64,/i.test(imageDataUrl))throw Error(`MiniMax VLM: imageDataUrl must be a base64 data:image/(png|jpeg|webp) URL`);let host=coerceApiHost({apiHost:params.apiHost,modelBaseUrl:params.modelBaseUrl}),url=new URL(`/v1/coding_plan/vlm`,host).toString(),res=await fetch(url,{method:`POST`,headers:{Authorization:`Bearer ${apiKey}`,"Content-Type":`application/json`,"MM-API-Source":`BuilderForceAgents`},body:JSON.stringify({prompt,image_url:imageDataUrl})}),traceId=res.headers.get(`Trace-Id`)??``;if(!res.ok){let body=await res.text().catch(()=>``),trace=traceId?` Trace-Id: ${traceId}`:``;throw Error(`MiniMax VLM request failed (${res.status} ${res.statusText}).${trace}${body?` Body: ${body.slice(0,400)}`:``}`)}let json=await res.json().catch(()=>null);if(!isRecord(json)){let trace=traceId?` Trace-Id: ${traceId}`:``;throw Error(`MiniMax VLM response was not JSON.${trace}`)}let baseResp=isRecord(json.base_resp)?json.base_resp:{},code=typeof baseResp.status_code==`number`?baseResp.status_code:-1;if(code!==0){let msg=(baseResp.status_msg??``).trim(),trace=traceId?` Trace-Id: ${traceId}`:``;throw Error(`MiniMax VLM API error (${code})${msg?`: ${msg}`:``}.${trace}`)}let content=pickString(json,`content`).trim();if(!content){let trace=traceId?` Trace-Id: ${traceId}`:``;throw Error(`MiniMax VLM returned no content.${trace}`)}return content}function extractTextFromChatContent(content,opts){let normalize=opts?.normalizeText??(text=>text.replace(/\s+/g,` `).trim()),joinWith=opts?.joinWith??` `;if(typeof content==`string`)return normalize(opts?.sanitizeText?opts.sanitizeText(content):content)||null;if(!Array.isArray(content))return null;let chunks=[];for(let block of content){if(!block||typeof block!=`object`||block.type!==`text`)continue;let text=block.text;if(typeof text!=`string`)continue;let value=opts?.sanitizeText?opts.sanitizeText(text):text;value.trim()&&chunks.push(value)}return normalize(chunks.join(joinWith))||null}function isAssistantMessage(msg){return msg?.role===`assistant`}function stripMinimaxToolCallXml(text){if(!text||!/minimax:tool_call/i.test(text))return text;let cleaned=text.replace(/<invoke\b[^>]*>[\s\S]*?<\/invoke>/gi,``);return cleaned=cleaned.replace(/<\/?minimax:tool_call>/gi,``),cleaned}function stripDowngradedToolCallText(text){if(!text||!/\[Tool (?:Call|Result)/i.test(text)&&!/\[Historical context/i.test(text))return text;let consumeJsonish=(input,start,options)=>{let{allowLeadingNewlines=!1}=options??{},index=start;for(;index<input.length;){let ch=input[index];if(ch===` `||ch===` `){index+=1;continue}if(allowLeadingNewlines&&(ch===`
|
|
2
2
|
`||ch===`\r`)){index+=1;continue}break}if(index>=input.length)return null;let startChar=input[index];if(startChar===`{`||startChar===`[`){let depth=0,inString=!1,escape=!1;for(let i=index;i<input.length;i+=1){let ch=input[i];if(inString){escape?escape=!1:ch===`\\`?escape=!0:ch===`"`&&(inString=!1);continue}if(ch===`"`){inString=!0;continue}if(ch===`{`||ch===`[`){depth+=1;continue}if((ch===`}`||ch===`]`)&&(--depth,depth===0))return i+1}return null}if(startChar===`"`){let escape=!1;for(let i=index+1;i<input.length;i+=1){let ch=input[i];if(escape){escape=!1;continue}if(ch===`\\`){escape=!0;continue}if(ch===`"`)return i+1}return null}let end=index;for(;end<input.length&&input[end]!==`
|
|
3
3
|
`&&input[end]!==`\r`;)end+=1;return end},cleaned=(input=>{let markerRe=/\[Tool Call:[^\]]*\]/gi,result=``,cursor=0;for(let match of input.matchAll(markerRe)){let start=match.index??0;if(start<cursor)continue;result+=input.slice(cursor,start);let index=start+match[0].length;for(;index<input.length&&(input[index]===` `||input[index]===` `);)index+=1;for(input[index]===`\r`&&(index+=1),input[index]===`
|
|
4
4
|
`&&(index+=1);index<input.length&&(input[index]===` `||input[index]===` `);)index+=1;if(input.slice(index,index+9).toLowerCase()===`arguments`){index+=9,input[index]===`:`&&(index+=1),input[index]===` `&&(index+=1);let end=consumeJsonish(input,index,{allowLeadingNewlines:!0});end!==null&&(index=end)}(input[index]===`
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as STATE_DIR}from"./paths-5FcIFMsj.js";import{b as resolveUserPath}from"./utils-DbaBVFaK.js";import{d as normalizeAgentId,p as resolveAgentIdFromSessionKey}from"./session-key-EoB0qaG9.js";import{i as defaultRuntime}from"./subsystem-B3TqcCrZ.js";import{t as CHANNEL_IDS}from"./registry-TdK-aV05.js";import{S as DEFAULT_USER_FILENAME,_ as DEFAULT_IDENTITY_FILENAME,b as DEFAULT_SOUL_FILENAME,d as resolveSessionAgentId,g as DEFAULT_HEARTBEAT_FILENAME,h as DEFAULT_BOOTSTRAP_FILENAME,m as DEFAULT_AGENT_WORKSPACE_DIR,p as DEFAULT_AGENTS_FILENAME,r as resolveAgentConfig,w as ensureAgentWorkspace,x as DEFAULT_TOOLS_FILENAME}from"./agent-scope-DPtjOxzp.js";import{t as normalizeBaseUrl}from"./normalize-base-url-DmugqkQ6.js";import{t as formatCliCommand}from"./command-format-D806O2pt.js";import{r as loadConfig}from"./io-3R_ZyUxB.js";import{D as DEFAULT_BUILDERFORCE_AGENTS_BROWSER_PROFILE_NAME,T as DEFAULT_BUILDERFORCE_AGENTS_BROWSER_COLOR,w as DEFAULT_BROWSER_EVALUATE_ENABLED}from"./chrome-a3X9_-nf.js";import{c as safeEqualSecret}from"./auth-lebUHrkd.js";import{r as isLoopbackHost}from"./ws-Bbu03j3h.js";import{a as resolveProfile,m as resolveBrowserControlAuth,p as ensureBrowserControlAuth,t as createBrowserRouteContext}from"./server-context-DJZT7Upf.js";import{d as resolveSandboxInputPath,f as resolveSandboxPath,o as syncSkillsToWorkspace}from"./skills-Ba4ftrB-.js";import{t as registerBrowserRoutes}from"./routes-BzfLvF8W.js";import{L as canonicalizeMainSessionAlias,R as resolveAgentMainSessionKey,nt as acquireSessionWriteLock}from"./sessions-CdanN_ZI.js";import{existsSync,realpathSync}from"node:fs";import path,{posix}from"node:path";import crypto from"node:crypto";import fs$1 from"node:fs/promises";import{spawn}from"node:child_process";import express from"express";const DEFAULT_SANDBOX_WORKSPACE_ROOT=path.join(STATE_DIR,`sandboxes`),DEFAULT_SANDBOX_IMAGE=`builderforce-sandbox:bookworm-slim`,DEFAULT_TOOL_ALLOW=[`exec`,`process`,`read`,`write`,`edit`,`apply_patch`,`image`,`sessions_list`,`sessions_history`,`sessions_send`,`sessions_spawn`,`subagents`,`session_status`],DEFAULT_TOOL_DENY=[`browser`,`canvas`,`nodes`,`cron`,`gateway`,...CHANNEL_IDS],DEFAULT_SANDBOX_BROWSER_IMAGE=`builderforce-sandbox-browser:bookworm-slim`,DEFAULT_SANDBOX_COMMON_IMAGE=`builderforce-sandbox-common:bookworm-slim`,SANDBOX_AGENT_WORKSPACE_MOUNT=`/agent`,SANDBOX_STATE_DIR=path.join(STATE_DIR,`sandbox`),SANDBOX_REGISTRY_PATH=path.join(SANDBOX_STATE_DIR,`containers.json`),SANDBOX_BROWSER_REGISTRY_PATH=path.join(SANDBOX_STATE_DIR,`browsers.json`);function escapeRegex(value){return value.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function compileGlobPattern(params){let normalized=params.normalize(params.raw);return normalized?normalized===`*`?{kind:`all`}:normalized.includes(`*`)?{kind:`regex`,value:RegExp(`^${escapeRegex(normalized).replaceAll(`\\*`,`.*`)}$`)}:{kind:`exact`,value:normalized}:{kind:`exact`,value:``}}function compileGlobPatterns(params){return Array.isArray(params.raw)?params.raw.map(raw=>compileGlobPattern({raw,normalize:params.normalize})).filter(pattern=>pattern.kind!==`exact`||pattern.value):[]}function matchesAnyGlobPattern(value,patterns){for(let pattern of patterns)if(pattern.kind===`all`||pattern.kind===`exact`&&value===pattern.value||pattern.kind===`regex`&&pattern.value.test(value))return!0;return!1}const TOOL_NAME_ALIASES={bash:`exec`,"apply-patch":`apply_patch`,str_replace_editor:`edit`},TOOL_GROUPS={"group:memory":[`memory_search`,`memory_get`],"group:web":[`web_search`,`web_fetch`],"group:fs":[`read`,`write`,`edit`,`apply_patch`],"group:runtime":[`exec`,`process`],"group:sessions":[`sessions_list`,`sessions_history`,`sessions_send`,`sessions_spawn`,`subagents`,`session_status`],"group:ui":[`browser`,`canvas`],"group:automation":[`cron`,`gateway`],"group:messaging":[`message`],"group:nodes":[`nodes`],"group:builderforce":[`browser`,`canvas`,`nodes`,`cron`,`message`,`gateway`,`agents_list`,`sessions_list`,`sessions_history`,`sessions_send`,`sessions_spawn`,`subagents`,`session_status`,`memory_search`,`memory_get`,`web_search`,`web_fetch`,`image`]},OWNER_ONLY_TOOL_NAMES=new Set([`whatsapp_login`]),TOOL_PROFILES={minimal:{allow:[`session_status`]},coding:{allow:[`group:fs`,`group:runtime`,`group:sessions`,`group:memory`,`image`]},messaging:{allow:[`group:messaging`,`sessions_list`,`sessions_history`,`sessions_send`,`session_status`]},full:{}};function normalizeToolName(name){let normalized=name.trim().toLowerCase();return TOOL_NAME_ALIASES[normalized]??normalized}function isOwnerOnlyToolName(name){return OWNER_ONLY_TOOL_NAMES.has(normalizeToolName(name))}function applyOwnerOnlyToolPolicy(tools,senderIsOwner){let withGuard=tools.map(tool=>!isOwnerOnlyToolName(tool.name)||senderIsOwner||!tool.execute?tool:{...tool,execute:async()=>{throw Error(`Tool restricted to owner senders.`)}});return senderIsOwner?withGuard:withGuard.filter(tool=>!isOwnerOnlyToolName(tool.name))}function normalizeToolList(list){return list?list.map(normalizeToolName).filter(Boolean):[]}function expandToolGroups(list){let normalized=normalizeToolList(list),expanded=[];for(let value of normalized){let group=TOOL_GROUPS[value];if(group){expanded.push(...group);continue}expanded.push(value)}return Array.from(new Set(expanded))}function collectExplicitAllowlist(policies){let entries=[];for(let policy of policies)if(policy?.allow)for(let value of policy.allow){if(typeof value!=`string`)continue;let trimmed=value.trim();trimmed&&entries.push(trimmed)}return entries}function buildPluginToolGroups(params){let all=[],byPlugin=new Map;for(let tool of params.tools){let meta=params.toolMeta(tool);if(!meta)continue;let name=normalizeToolName(tool.name);all.push(name);let pluginId=meta.pluginId.toLowerCase(),list=byPlugin.get(pluginId)??[];list.push(name),byPlugin.set(pluginId,list)}return{all,byPlugin}}function expandPluginGroups(list,groups){if(!list||list.length===0)return list;let expanded=[];for(let entry of list){let normalized=normalizeToolName(entry);if(normalized===`group:plugins`){groups.all.length>0?expanded.push(...groups.all):expanded.push(normalized);continue}let tools=groups.byPlugin.get(normalized);if(tools&&tools.length>0){expanded.push(...tools);continue}expanded.push(normalized)}return Array.from(new Set(expanded))}function expandPolicyWithPluginGroups(policy,groups){if(policy)return{allow:expandPluginGroups(policy.allow,groups),deny:expandPluginGroups(policy.deny,groups)}}function stripPluginOnlyAllowlist(policy,groups,coreTools){if(!policy?.allow||policy.allow.length===0)return{policy,unknownAllowlist:[],strippedAllowlist:!1};let normalized=normalizeToolList(policy.allow);if(normalized.length===0)return{policy,unknownAllowlist:[],strippedAllowlist:!1};let pluginIds=new Set(groups.byPlugin.keys()),pluginTools=new Set(groups.all),unknownAllowlist=[],hasCoreEntry=!1;for(let entry of normalized){if(entry===`*`){hasCoreEntry=!0;continue}let isPluginEntry=entry===`group:plugins`||pluginIds.has(entry)||pluginTools.has(entry),isCoreEntry=expandToolGroups([entry]).some(tool=>coreTools.has(tool));isCoreEntry&&(hasCoreEntry=!0),!isCoreEntry&&!isPluginEntry&&unknownAllowlist.push(entry)}let strippedAllowlist=!hasCoreEntry;return{policy:strippedAllowlist?{...policy,allow:void 0}:policy,unknownAllowlist:Array.from(new Set(unknownAllowlist)),strippedAllowlist}}function resolveToolProfilePolicy(profile){if(!profile)return;let resolved=TOOL_PROFILES[profile];if(resolved&&!(!resolved.allow&&!resolved.deny))return{allow:resolved.allow?[...resolved.allow]:void 0,deny:resolved.deny?[...resolved.deny]:void 0}}function mergeAlsoAllowPolicy(policy,alsoAllow){return!policy?.allow||!Array.isArray(alsoAllow)||alsoAllow.length===0?policy:{...policy,allow:Array.from(new Set([...policy.allow,...alsoAllow]))}}function normalizeGlob(value){return value.trim().toLowerCase()}function isToolAllowed(policy,name){let normalized=normalizeGlob(name);if(matchesAnyGlobPattern(normalized,compileGlobPatterns({raw:expandToolGroups(policy.deny??[]),normalize:normalizeGlob})))return!1;let allow=compileGlobPatterns({raw:expandToolGroups(policy.allow??[]),normalize:normalizeGlob});return allow.length===0?!0:matchesAnyGlobPattern(normalized,allow)}function resolveSandboxToolPolicyForAgent(cfg,agentId){let agentConfig=cfg&&agentId?resolveAgentConfig(cfg,agentId):void 0,agentAllow=agentConfig?.tools?.sandbox?.tools?.allow,agentDeny=agentConfig?.tools?.sandbox?.tools?.deny,globalAllow=cfg?.tools?.sandbox?.tools?.allow,globalDeny=cfg?.tools?.sandbox?.tools?.deny,allowSource=Array.isArray(agentAllow)?{source:`agent`,key:`agents.list[].tools.sandbox.tools.allow`}:Array.isArray(globalAllow)?{source:`global`,key:`tools.sandbox.tools.allow`}:{source:`default`,key:`tools.sandbox.tools.allow`},denySource=Array.isArray(agentDeny)?{source:`agent`,key:`agents.list[].tools.sandbox.tools.deny`}:Array.isArray(globalDeny)?{source:`global`,key:`tools.sandbox.tools.deny`}:{source:`default`,key:`tools.sandbox.tools.deny`},deny=Array.isArray(agentDeny)?agentDeny:Array.isArray(globalDeny)?globalDeny:[...DEFAULT_TOOL_DENY],allow=Array.isArray(agentAllow)?agentAllow:Array.isArray(globalAllow)?globalAllow:[...DEFAULT_TOOL_ALLOW],expandedDeny=expandToolGroups(deny),expandedAllow=expandToolGroups(allow);return expandedAllow.length>0&&!expandedDeny.map(v=>v.toLowerCase()).includes(`image`)&&!expandedAllow.map(v=>v.toLowerCase()).includes(`image`)&&(expandedAllow=[...expandedAllow,`image`]),{allow:expandedAllow,deny:expandedDeny,sources:{allow:allowSource,deny:denySource}}}function resolveSandboxBrowserDockerCreateConfig(params){let base={...params.docker,network:`bridge`,image:params.browser.image};return params.browser.binds===void 0?base:{...base,binds:params.browser.binds}}function resolveSandboxScope(params){return params.scope?params.scope:typeof params.perSession==`boolean`?params.perSession?`session`:`shared`:`agent`}function resolveSandboxDockerConfig(params){let agentDocker=params.scope===`shared`?void 0:params.agentDocker,globalDocker=params.globalDocker,env=agentDocker?.env?{...globalDocker?.env??{LANG:`C.UTF-8`},...agentDocker.env}:globalDocker?.env??{LANG:`C.UTF-8`},ulimits=agentDocker?.ulimits?{...globalDocker?.ulimits,...agentDocker.ulimits}:globalDocker?.ulimits,binds=[...globalDocker?.binds??[],...agentDocker?.binds??[]];return{image:agentDocker?.image??globalDocker?.image??DEFAULT_SANDBOX_IMAGE,containerPrefix:agentDocker?.containerPrefix??globalDocker?.containerPrefix??`builderforce-sbx-`,workdir:agentDocker?.workdir??globalDocker?.workdir??`/workspace`,readOnlyRoot:agentDocker?.readOnlyRoot??globalDocker?.readOnlyRoot??!0,tmpfs:agentDocker?.tmpfs??globalDocker?.tmpfs??[`/tmp`,`/var/tmp`,`/run`],network:agentDocker?.network??globalDocker?.network??`none`,user:agentDocker?.user??globalDocker?.user,capDrop:agentDocker?.capDrop??globalDocker?.capDrop??[`ALL`],env,setupCommand:agentDocker?.setupCommand??globalDocker?.setupCommand,pidsLimit:agentDocker?.pidsLimit??globalDocker?.pidsLimit,memory:agentDocker?.memory??globalDocker?.memory,memorySwap:agentDocker?.memorySwap??globalDocker?.memorySwap,cpus:agentDocker?.cpus??globalDocker?.cpus,ulimits,seccompProfile:agentDocker?.seccompProfile??globalDocker?.seccompProfile,apparmorProfile:agentDocker?.apparmorProfile??globalDocker?.apparmorProfile,dns:agentDocker?.dns??globalDocker?.dns,extraHosts:agentDocker?.extraHosts??globalDocker?.extraHosts,binds:binds.length?binds:void 0}}function resolveSandboxBrowserConfig(params){let agentBrowser=params.scope===`shared`?void 0:params.agentBrowser,globalBrowser=params.globalBrowser,binds=[...globalBrowser?.binds??[],...agentBrowser?.binds??[]],bindsConfigured=globalBrowser?.binds!==void 0||agentBrowser?.binds!==void 0;return{enabled:agentBrowser?.enabled??globalBrowser?.enabled??!1,image:agentBrowser?.image??globalBrowser?.image??DEFAULT_SANDBOX_BROWSER_IMAGE,containerPrefix:agentBrowser?.containerPrefix??globalBrowser?.containerPrefix??`builderforce-sbx-browser-`,cdpPort:agentBrowser?.cdpPort??globalBrowser?.cdpPort??9222,vncPort:agentBrowser?.vncPort??globalBrowser?.vncPort??5900,noVncPort:agentBrowser?.noVncPort??globalBrowser?.noVncPort??6080,headless:agentBrowser?.headless??globalBrowser?.headless??!1,enableNoVnc:agentBrowser?.enableNoVnc??globalBrowser?.enableNoVnc??!0,allowHostControl:agentBrowser?.allowHostControl??globalBrowser?.allowHostControl??!1,autoStart:agentBrowser?.autoStart??globalBrowser?.autoStart??!0,autoStartTimeoutMs:agentBrowser?.autoStartTimeoutMs??globalBrowser?.autoStartTimeoutMs??12e3,binds:bindsConfigured?binds:void 0}}function resolveSandboxPruneConfig(params){let agentPrune=params.scope===`shared`?void 0:params.agentPrune,globalPrune=params.globalPrune;return{idleHours:agentPrune?.idleHours??globalPrune?.idleHours??24,maxAgeDays:agentPrune?.maxAgeDays??globalPrune?.maxAgeDays??7}}function resolveSandboxConfigForAgent(cfg,agentId){let agent=cfg?.agents?.defaults?.sandbox,agentSandbox,agentConfig=cfg&&agentId?resolveAgentConfig(cfg,agentId):void 0;agentConfig?.sandbox&&(agentSandbox=agentConfig.sandbox);let scope=resolveSandboxScope({scope:agentSandbox?.scope??agent?.scope,perSession:agentSandbox?.perSession??agent?.perSession}),toolPolicy=resolveSandboxToolPolicyForAgent(cfg,agentId);return{mode:agentSandbox?.mode??agent?.mode??`off`,scope,workspaceAccess:agentSandbox?.workspaceAccess??agent?.workspaceAccess??`none`,workspaceRoot:agentSandbox?.workspaceRoot??agent?.workspaceRoot??DEFAULT_SANDBOX_WORKSPACE_ROOT,docker:resolveSandboxDockerConfig({scope,globalDocker:agent?.docker,agentDocker:agentSandbox?.docker}),browser:resolveSandboxBrowserConfig({scope,globalBrowser:agent?.browser,agentBrowser:agentSandbox?.browser}),tools:{allow:toolPolicy.allow,deny:toolPolicy.deny},prune:resolveSandboxPruneConfig({scope,globalPrune:agent?.prune,agentPrune:agentSandbox?.prune})}}const authByPort=new Map;function setBridgeAuthForPort(port,auth){if(!Number.isFinite(port)||port<=0)return;let token=typeof auth.token==`string`?auth.token.trim():``,password=typeof auth.password==`string`?auth.password.trim():``;authByPort.set(port,{token:token||void 0,password:password||void 0})}function getBridgeAuthForPort(port){if(!(!Number.isFinite(port)||port<=0))return authByPort.get(port)}function deleteBridgeAuthForPort(port){!Number.isFinite(port)||port<=0||authByPort.delete(port)}function firstHeader(value){return Array.isArray(value)?value[0]??``:value??``}function isMutatingMethod(method){let m=(method||``).trim().toUpperCase();return m===`POST`||m===`PUT`||m===`PATCH`||m===`DELETE`}function isLoopbackUrl(value){let v=value.trim();if(!v||v===`null`)return!1;try{return isLoopbackHost(new URL(v).hostname)}catch{return!1}}function shouldRejectBrowserMutation(params){if(!isMutatingMethod(params.method))return!1;if((params.secFetchSite??``).trim().toLowerCase()===`cross-site`)return!0;let origin=(params.origin??``).trim();if(origin)return!isLoopbackUrl(origin);let referer=(params.referer??``).trim();return referer?!isLoopbackUrl(referer):!1}function browserMutationGuardMiddleware(){return(req,res,next)=>{let method=(req.method||``).trim().toUpperCase();if(method===`OPTIONS`)return next();if(shouldRejectBrowserMutation({method,origin:firstHeader(req.headers.origin),referer:firstHeader(req.headers.referer),secFetchSite:firstHeader(req.headers[`sec-fetch-site`])})){res.status(403).send(`Forbidden`);return}next()}}function firstHeaderValue(value){return Array.isArray(value)?value[0]??``:value??``}function parseBearerToken(authorization){if(!(!authorization||!authorization.toLowerCase().startsWith(`bearer `)))return authorization.slice(7).trim()||void 0}function parseBasicPassword(authorization){if(!authorization||!authorization.toLowerCase().startsWith(`basic `))return;let encoded=authorization.slice(6).trim();if(encoded)try{let decoded=Buffer.from(encoded,`base64`).toString(`utf8`),sep=decoded.indexOf(`:`);return sep<0?void 0:decoded.slice(sep+1).trim()||void 0}catch{return}}function isAuthorizedBrowserRequest(req,auth){let authorization=firstHeaderValue(req.headers.authorization).trim();if(auth.token){let bearer=parseBearerToken(authorization);if(bearer&&safeEqualSecret(bearer,auth.token))return!0}if(auth.password){let passwordHeader=(firstHeaderValue(req.headers[`x-builderforce-password`])||firstHeaderValue(req.headers[`x-builderforce-password`])).trim();if(passwordHeader&&safeEqualSecret(passwordHeader,auth.password))return!0;let basicPassword=parseBasicPassword(authorization);if(basicPassword&&safeEqualSecret(basicPassword,auth.password))return!0}return!1}function installBrowserCommonMiddleware(app){app.use((req,res,next)=>{let ctrl=new AbortController,abort=()=>ctrl.abort(Error(`request aborted`));req.once(`aborted`,abort),res.once(`close`,()=>{res.writableEnded||abort()}),Object.defineProperty(req,`signal`,{value:ctrl.signal,configurable:!0,enumerable:!0,writable:!0}),next()}),app.use(express.json({limit:`1mb`})),app.use(browserMutationGuardMiddleware())}function installBrowserAuthMiddleware(app,auth){!auth.token&&!auth.password||app.use((req,res,next)=>{if(isAuthorizedBrowserRequest(req,auth))return next();res.status(401).send(`Unauthorized`)})}async function startBrowserBridgeServer(params){let host=params.host??`127.0.0.1`;if(!isLoopbackHost(host))throw Error(`bridge server must bind to loopback host (got ${host})`);let port=params.port??0,app=express();installBrowserCommonMiddleware(app);let authToken=params.authToken?.trim()||void 0,authPassword=params.authPassword?.trim()||void 0;if(!authToken&&!authPassword)throw Error(`bridge server requires auth (authToken/authPassword missing)`);installBrowserAuthMiddleware(app,{token:authToken,password:authPassword});let state={server:null,port,resolved:params.resolved,profiles:new Map};registerBrowserRoutes(app,createBrowserRouteContext({getState:()=>state,onEnsureAttachTarget:params.onEnsureAttachTarget}));let server=await new Promise((resolve,reject)=>{let s=app.listen(port,host,()=>resolve(s));s.once(`error`,reject)}),resolvedPort=server.address()?.port??port;return state.server=server,state.port=resolvedPort,state.resolved.controlPort=resolvedPort,setBridgeAuthForPort(resolvedPort,{token:authToken,password:authPassword}),{server,port:resolvedPort,baseUrl:`http://${host}:${resolvedPort}`,state}}async function stopBrowserBridgeServer(server){try{let address=server.address();address?.port&&deleteBridgeAuthForPort(address.port)}catch{}await new Promise(resolve=>{server.close(()=>resolve())})}const BROWSER_BRIDGES=new Map;function hashTextSha256(value){return crypto.createHash(`sha256`).update(value).digest(`hex`)}function normalizeForHash(value){if(value!==void 0){if(Array.isArray(value))return value.map(normalizeForHash).filter(item=>item!==void 0);if(value&&typeof value==`object`){let entries=Object.entries(value).toSorted(([a],[b])=>a.localeCompare(b)),normalized={};for(let[key,entryValue]of entries){let next=normalizeForHash(entryValue);next!==void 0&&(normalized[key]=next)}return normalized}return value}}function computeSandboxConfigHash(input){return computeHash(input)}function computeSandboxBrowserConfigHash(input){return computeHash(input)}function computeHash(input){let payload=normalizeForHash(input);return hashTextSha256(JSON.stringify(payload))}const BLOCKED_ENV_VAR_PATTERNS=[/^ANTHROPIC_API_KEY$/i,/^OPENAI_API_KEY$/i,/^GEMINI_API_KEY$/i,/^OPENROUTER_API_KEY$/i,/^MINIMAX_API_KEY$/i,/^ELEVENLABS_API_KEY$/i,/^SYNTHETIC_API_KEY$/i,/^TELEGRAM_BOT_TOKEN$/i,/^DISCORD_BOT_TOKEN$/i,/^SLACK_(BOT|APP)_TOKEN$/i,/^LINE_CHANNEL_SECRET$/i,/^LINE_CHANNEL_ACCESS_TOKEN$/i,/^BUILDERFORCE_AGENTS_GATEWAY_(TOKEN|PASSWORD)$/i,/^AWS_(SECRET_ACCESS_KEY|SECRET_KEY|SESSION_TOKEN)$/i,/^(GH|GITHUB)_TOKEN$/i,/^(AZURE|AZURE_OPENAI|COHERE|AI_GATEWAY|OPENROUTER)_API_KEY$/i,/_?(API_KEY|TOKEN|PASSWORD|PRIVATE_KEY|SECRET)$/i],ALLOWED_ENV_VAR_PATTERNS=[/^LANG$/,/^LC_.*$/i,/^PATH$/i,/^HOME$/i,/^USER$/i,/^SHELL$/i,/^TERM$/i,/^TZ$/i,/^NODE_ENV$/i];function validateEnvVarValue(value){if(value.includes(`\0`))return`Contains null bytes`;if(value.length>32768)return`Value exceeds maximum length`;if(/^[A-Za-z0-9+/=]{80,}$/.test(value))return`Value looks like base64-encoded credential data`}function matchesAnyPattern(value,patterns){return patterns.some(pattern=>pattern.test(value))}function sanitizeEnvVars(envVars,options={}){let allowed={},blocked=[],warnings=[],blockedPatterns=[...BLOCKED_ENV_VAR_PATTERNS,...options.customBlockedPatterns??[]],allowedPatterns=[...ALLOWED_ENV_VAR_PATTERNS,...options.customAllowedPatterns??[]];for(let[rawKey,value]of Object.entries(envVars)){let key=rawKey.trim();if(!key)continue;if(matchesAnyPattern(key,blockedPatterns)){blocked.push(key);continue}if(options.strictMode&&!matchesAnyPattern(key,allowedPatterns)){blocked.push(key);continue}let warning=validateEnvVarValue(value);if(warning){if(warning===`Contains null bytes`){blocked.push(key);continue}warnings.push(`${key}: ${warning}`)}allowed[key]=value}return{allowed,blocked,warnings}}function isRecord(value){return!!value&&typeof value==`object`}function isRegistryEntry(value){return isRecord(value)&&typeof value.containerName==`string`}function isRegistryFile(value){if(!isRecord(value))return!1;let maybeEntries=value.entries;return Array.isArray(maybeEntries)&&maybeEntries.every(isRegistryEntry)}async function withRegistryLock(registryPath,fn){let lock=await acquireSessionWriteLock({sessionFile:registryPath,allowReentrant:!1});try{return await fn()}finally{await lock.release()}}async function readRegistryFromFile(registryPath,mode){try{let raw=await fs$1.readFile(registryPath,`utf-8`),parsed=JSON.parse(raw);if(isRegistryFile(parsed))return parsed;if(mode===`fallback`)return{entries:[]};throw Error(`Invalid sandbox registry format: ${registryPath}`)}catch(error){if(error?.code===`ENOENT`||mode===`fallback`)return{entries:[]};throw error instanceof Error?error:Error(`Failed to read sandbox registry file: ${registryPath}`,{cause:error})}}async function writeRegistryFile(registryPath,registry){await fs$1.mkdir(SANDBOX_STATE_DIR,{recursive:!0});let payload=`${JSON.stringify(registry,null,2)}\n`,registryDir=path.dirname(registryPath),tempPath=path.join(registryDir,`${path.basename(registryPath)}.${crypto.randomUUID()}.tmp`);await fs$1.writeFile(tempPath,payload,`utf-8`);try{await fs$1.rename(tempPath,registryPath)}catch(error){throw await fs$1.rm(tempPath,{force:!0}),error}}async function readRegistry(){return await readRegistryFromFile(SANDBOX_REGISTRY_PATH,`fallback`)}function upsertEntry(entries,entry){let existing=entries.find(item=>item.containerName===entry.containerName),next=entries.filter(item=>item.containerName!==entry.containerName);return next.push({...entry,createdAtMs:existing?.createdAtMs??entry.createdAtMs,image:existing?.image??entry.image,configHash:entry.configHash??existing?.configHash}),next}function removeEntry(entries,containerName){return entries.filter(entry=>entry.containerName!==containerName)}async function withRegistryMutation(registryPath,mutate){await withRegistryLock(registryPath,async()=>{let next=mutate((await readRegistryFromFile(registryPath,`strict`)).entries);next!==null&&await writeRegistryFile(registryPath,{entries:next})})}async function updateRegistry(entry){await withRegistryMutation(SANDBOX_REGISTRY_PATH,entries=>upsertEntry(entries,entry))}async function removeRegistryEntry(containerName){await withRegistryMutation(SANDBOX_REGISTRY_PATH,entries=>{let next=removeEntry(entries,containerName);return next.length===entries.length?null:next})}async function readBrowserRegistry(){return await readRegistryFromFile(SANDBOX_BROWSER_REGISTRY_PATH,`fallback`)}async function updateBrowserRegistry(entry){await withRegistryMutation(SANDBOX_BROWSER_REGISTRY_PATH,entries=>upsertEntry(entries,entry))}async function removeBrowserRegistryEntry(containerName){await withRegistryMutation(SANDBOX_BROWSER_REGISTRY_PATH,entries=>{let next=removeEntry(entries,containerName);return next.length===entries.length?null:next})}function slugifySessionKey(value){let trimmed=value.trim()||`session`,hash=hashTextSha256(trimmed).slice(0,8);return`${trimmed.toLowerCase().replace(/[^a-z0-9._-]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,32)||`session`}-${hash}`}function resolveSandboxWorkspaceDir(root,sessionKey){let resolvedRoot=resolveUserPath(root),slug=slugifySessionKey(sessionKey);return path.join(resolvedRoot,slug)}function resolveSandboxScopeKey(scope,sessionKey){let trimmed=sessionKey.trim()||`main`;return scope===`shared`?`shared`:scope===`session`?trimmed:`agent:${resolveAgentIdFromSessionKey(trimmed)}`}function resolveSandboxAgentId(scopeKey){let trimmed=scopeKey.trim();if(!trimmed||trimmed===`shared`)return;let parts=trimmed.split(`:`).filter(Boolean);return parts[0]===`agent`&&parts[1]?normalizeAgentId(parts[1]):resolveAgentIdFromSessionKey(trimmed)}const BLOCKED_HOST_PATHS=[`/etc`,`/private/etc`,`/proc`,`/sys`,`/dev`,`/root`,`/boot`,`/run`,`/var/run`,`/private/var/run`,`/var/run/docker.sock`,`/private/var/run/docker.sock`,`/run/docker.sock`],BLOCKED_NETWORK_MODES=new Set([`host`]),BLOCKED_SECCOMP_PROFILES=new Set([`unconfined`]),BLOCKED_APPARMOR_PROFILES=new Set([`unconfined`]);function parseBindSourcePath(bind){let trimmed=bind.trim(),firstColon=trimmed.indexOf(`:`);return firstColon<=0?trimmed:trimmed.slice(0,firstColon)}function normalizeHostPath(raw){let trimmed=raw.trim();return normalizeBaseUrl(posix.normalize(trimmed))||`/`}function getBlockedBindReason(bind){let sourceRaw=parseBindSourcePath(bind);return sourceRaw.startsWith(`/`)?getBlockedReasonForSourcePath(normalizeHostPath(sourceRaw)):{kind:`non_absolute`,sourcePath:sourceRaw}}function getBlockedReasonForSourcePath(sourceNormalized){if(sourceNormalized===`/`)return{kind:`covers`,blockedPath:`/`};for(let blocked of BLOCKED_HOST_PATHS)if(sourceNormalized===blocked||sourceNormalized.startsWith(blocked+`/`))return{kind:`targets`,blockedPath:blocked};return null}function tryRealpathAbsolute(path){if(!path.startsWith(`/`)||!existsSync(path))return path;try{return normalizeHostPath(realpathSync.native(path))}catch{return path}}function formatBindBlockedError(params){if(params.reason.kind===`non_absolute`)return Error(`Sandbox security: bind mount "${params.bind}" uses a non-absolute source path "${params.reason.sourcePath}". Only absolute POSIX paths are supported for sandbox binds.`);let verb=params.reason.kind===`covers`?`covers`:`targets`;return Error(`Sandbox security: bind mount "${params.bind}" ${verb} blocked path "${params.reason.blockedPath}". Mounting system directories (or Docker socket paths) into sandbox containers is not allowed. Use project-specific paths instead (e.g. /home/user/myproject).`)}function validateBindMounts(binds){if(binds?.length)for(let rawBind of binds){let bind=rawBind.trim();if(!bind)continue;let blocked=getBlockedBindReason(bind);if(blocked)throw formatBindBlockedError({bind,reason:blocked});let sourceNormalized=normalizeHostPath(parseBindSourcePath(bind)),sourceReal=tryRealpathAbsolute(sourceNormalized);if(sourceReal!==sourceNormalized){let reason=getBlockedReasonForSourcePath(sourceReal);if(reason)throw formatBindBlockedError({bind,reason})}}}function validateNetworkMode(network){if(network&&BLOCKED_NETWORK_MODES.has(network.trim().toLowerCase()))throw Error(`Sandbox security: network mode "${network}" is blocked. Network "host" mode bypasses container network isolation. Use "bridge" or "none" instead.`)}function validateSeccompProfile(profile){if(profile&&BLOCKED_SECCOMP_PROFILES.has(profile.trim().toLowerCase()))throw Error(`Sandbox security: seccomp profile "${profile}" is blocked. Disabling seccomp removes syscall filtering and weakens sandbox isolation. Use a custom seccomp profile file or omit this setting.`)}function validateApparmorProfile(profile){if(profile&&BLOCKED_APPARMOR_PROFILES.has(profile.trim().toLowerCase()))throw Error(`Sandbox security: apparmor profile "${profile}" is blocked. Disabling AppArmor removes mandatory access controls and weakens sandbox isolation. Use a named AppArmor profile or omit this setting.`)}function validateSandboxSecurity(cfg){validateBindMounts(cfg.binds),validateNetworkMode(cfg.network),validateSeccompProfile(cfg.seccompProfile),validateApparmorProfile(cfg.apparmorProfile)}function createAbortError(){let err=Error(`Aborted`);return err.name=`AbortError`,err}function execDockerRaw(args,opts){return new Promise((resolve,reject)=>{let child=spawn(`docker`,args,{stdio:[`pipe`,`pipe`,`pipe`]}),stdoutChunks=[],stderrChunks=[],aborted=!1,signal=opts?.signal,handleAbort=()=>{aborted||(aborted=!0,child.kill(`SIGTERM`))};signal&&(signal.aborted?handleAbort():signal.addEventListener(`abort`,handleAbort,{once:!0})),child.stdout?.on(`data`,chunk=>{stdoutChunks.push(Buffer.isBuffer(chunk)?chunk:Buffer.from(chunk))}),child.stderr?.on(`data`,chunk=>{stderrChunks.push(Buffer.isBuffer(chunk)?chunk:Buffer.from(chunk))}),child.on(`error`,error=>{signal&&signal.removeEventListener(`abort`,handleAbort),reject(error)}),child.on(`close`,code=>{signal&&signal.removeEventListener(`abort`,handleAbort);let stdout=Buffer.concat(stdoutChunks),stderr=Buffer.concat(stderrChunks);if(aborted||signal?.aborted){reject(createAbortError());return}let exitCode=code??0;if(exitCode!==0&&!opts?.allowFailure){let message=stderr.length>0?stderr.toString(`utf8`).trim():``;reject(Object.assign(Error(message||`docker ${args.join(` `)} failed`),{code:exitCode,stdout,stderr}));return}resolve({stdout,stderr,code:exitCode})});let stdin=child.stdin;stdin&&(opts?.input===void 0?stdin.end():stdin.end(opts.input))})}async function execDocker(args,opts){let result=await execDockerRaw(args,opts);return{stdout:result.stdout.toString(`utf8`),stderr:result.stderr.toString(`utf8`),code:result.code}}async function readDockerContainerLabel(containerName,label){let result=await execDocker([`inspect`,`-f`,`{{ index .Config.Labels "${label}" }}`,containerName],{allowFailure:!0});if(result.code!==0)return null;let raw=result.stdout.trim();return!raw||raw===`<no value>`?null:raw}async function readDockerPort(containerName,port){let result=await execDocker([`port`,containerName,`${port}/tcp`],{allowFailure:!0});if(result.code!==0)return null;let match=(result.stdout.trim().split(/\r?\n/)[0]??``).match(/:(\d+)\s*$/);if(!match)return null;let mapped=Number.parseInt(match[1]??``,10);return Number.isFinite(mapped)?mapped:null}async function dockerImageExists(image){let result=await execDocker([`image`,`inspect`,image],{allowFailure:!0});if(result.code===0)return!0;let stderr=result.stderr.trim();if(stderr.includes(`No such image`))return!1;throw Error(`Failed to inspect sandbox image: ${stderr}`)}async function ensureDockerImage(image){if(!await dockerImageExists(image)){if(image===DEFAULT_SANDBOX_IMAGE){await execDocker([`pull`,`debian:bookworm-slim`]),await execDocker([`tag`,`debian:bookworm-slim`,DEFAULT_SANDBOX_IMAGE]);return}throw Error(`Sandbox image not found: ${image}. Build or pull it first.`)}}async function dockerContainerState(name){let result=await execDocker([`inspect`,`-f`,`{{.State.Running}}`,name],{allowFailure:!0});return result.code===0?{exists:!0,running:result.stdout.trim()===`true`}:{exists:!1,running:!1}}function normalizeDockerLimit(value){return value==null?void 0:typeof value==`number`?Number.isFinite(value)?String(value):void 0:value.trim()||void 0}function formatUlimitValue(name,value){if(!name.trim())return null;if(typeof value==`number`||typeof value==`string`){let raw=String(value).trim();return raw?`${name}=${raw}`:null}let soft=typeof value.soft==`number`?Math.max(0,value.soft):void 0,hard=typeof value.hard==`number`?Math.max(0,value.hard):void 0;return soft===void 0&&hard===void 0?null:soft===void 0?`${name}=${hard}`:hard===void 0?`${name}=${soft}`:`${name}=${soft}:${hard}`}function buildSandboxCreateArgs(params){validateSandboxSecurity(params.cfg);let createdAtMs=params.createdAtMs??Date.now(),args=[`create`,`--name`,params.name];args.push(`--label`,`builderforce.sandbox=1`),args.push(`--label`,`builderforce.sessionKey=${params.scopeKey}`),args.push(`--label`,`builderforce.createdAtMs=${createdAtMs}`),params.configHash&&args.push(`--label`,`builderforce.configHash=${params.configHash}`);for(let[key,value]of Object.entries(params.labels??{}))key&&value&&args.push(`--label`,`${key}=${value}`);params.cfg.readOnlyRoot&&args.push(`--read-only`);for(let entry of params.cfg.tmpfs)args.push(`--tmpfs`,entry);params.cfg.network&&args.push(`--network`,params.cfg.network),params.cfg.user&&args.push(`--user`,params.cfg.user);let envSanitization=sanitizeEnvVars(params.cfg.env??{});envSanitization.blocked.length>0&&console.warn(`[Security] Blocked sensitive environment variables:`,envSanitization.blocked.join(`, `)),envSanitization.warnings.length>0&&console.warn(`[Security] Suspicious environment variables:`,envSanitization.warnings);for(let[key,value]of Object.entries(envSanitization.allowed))args.push(`--env`,`${key}=${value}`);for(let cap of params.cfg.capDrop)args.push(`--cap-drop`,cap);args.push(`--security-opt`,`no-new-privileges`),params.cfg.seccompProfile&&args.push(`--security-opt`,`seccomp=${params.cfg.seccompProfile}`),params.cfg.apparmorProfile&&args.push(`--security-opt`,`apparmor=${params.cfg.apparmorProfile}`);for(let entry of params.cfg.dns??[])entry.trim()&&args.push(`--dns`,entry);for(let entry of params.cfg.extraHosts??[])entry.trim()&&args.push(`--add-host`,entry);typeof params.cfg.pidsLimit==`number`&¶ms.cfg.pidsLimit>0&&args.push(`--pids-limit`,String(params.cfg.pidsLimit));let memory=normalizeDockerLimit(params.cfg.memory);memory&&args.push(`--memory`,memory);let memorySwap=normalizeDockerLimit(params.cfg.memorySwap);memorySwap&&args.push(`--memory-swap`,memorySwap),typeof params.cfg.cpus==`number`&¶ms.cfg.cpus>0&&args.push(`--cpus`,String(params.cfg.cpus));for(let[name,value]of Object.entries(params.cfg.ulimits??{})){let formatted=formatUlimitValue(name,value);formatted&&args.push(`--ulimit`,formatted)}if(params.cfg.binds?.length)for(let bind of params.cfg.binds)args.push(`-v`,bind);return args}async function createSandboxContainer(params){let{name,cfg,workspaceDir,scopeKey}=params;await ensureDockerImage(cfg.image);let args=buildSandboxCreateArgs({name,cfg,scopeKey,configHash:params.configHash});args.push(`--workdir`,cfg.workdir);let mainMountSuffix=params.workspaceAccess===`ro`&&workspaceDir===params.agentWorkspaceDir?`:ro`:``;if(args.push(`-v`,`${workspaceDir}:${cfg.workdir}${mainMountSuffix}`),params.workspaceAccess!==`none`&&workspaceDir!==params.agentWorkspaceDir){let agentMountSuffix=params.workspaceAccess===`ro`?`:ro`:``;args.push(`-v`,`${params.agentWorkspaceDir}:${SANDBOX_AGENT_WORKSPACE_MOUNT}${agentMountSuffix}`)}args.push(cfg.image,`sleep`,`infinity`),await execDocker(args),await execDocker([`start`,name]),cfg.setupCommand?.trim()&&await execDocker([`exec`,`-i`,name,`sh`,`-lc`,cfg.setupCommand])}async function readContainerConfigHash(containerName){return await readDockerContainerLabel(containerName,`builderforce.configHash`)}function formatSandboxRecreateHint(params){return params.scope===`session`?formatCliCommand(`builderforce sandbox recreate --session ${params.sessionKey}`):params.scope===`agent`?formatCliCommand(`builderforce sandbox recreate --agent ${resolveSandboxAgentId(params.sessionKey)??`main`}`):formatCliCommand(`builderforce sandbox recreate --all`)}async function ensureSandboxContainer(params){let scopeKey=resolveSandboxScopeKey(params.cfg.scope,params.sessionKey),slug=params.cfg.scope===`shared`?`shared`:slugifySessionKey(scopeKey),containerName=`${params.cfg.docker.containerPrefix}${slug}`.slice(0,63),expectedHash=computeSandboxConfigHash({docker:params.cfg.docker,workspaceAccess:params.cfg.workspaceAccess,workspaceDir:params.workspaceDir,agentWorkspaceDir:params.agentWorkspaceDir}),now=Date.now(),state=await dockerContainerState(containerName),hasContainer=state.exists,running=state.running,currentHash=null,hashMismatch=!1,registryEntry;if(hasContainer&&(registryEntry=(await readRegistry()).entries.find(entry=>entry.containerName===containerName),currentHash=await readContainerConfigHash(containerName),currentHash||=registryEntry?.configHash??null,hashMismatch=!currentHash||currentHash!==expectedHash,hashMismatch)){let lastUsedAtMs=registryEntry?.lastUsedAtMs;if(running&&(typeof lastUsedAtMs!=`number`||now-lastUsedAtMs<3e5)){let hint=formatSandboxRecreateHint({scope:params.cfg.scope,sessionKey:scopeKey});defaultRuntime.log(`Sandbox config changed for ${containerName} (recently used). Recreate to apply: ${hint}`)}else await execDocker([`rm`,`-f`,containerName],{allowFailure:!0}),hasContainer=!1,running=!1}return hasContainer?running||await execDocker([`start`,containerName]):await createSandboxContainer({name:containerName,cfg:params.cfg.docker,workspaceDir:params.workspaceDir,workspaceAccess:params.cfg.workspaceAccess,agentWorkspaceDir:params.agentWorkspaceDir,scopeKey,configHash:expectedHash}),await updateRegistry({containerName,sessionKey:scopeKey,createdAtMs:now,lastUsedAtMs:now,image:params.cfg.docker.image,configHash:hashMismatch&&running?currentHash??void 0:expectedHash}),containerName}async function waitForSandboxCdp(params){let deadline=Date.now()+Math.max(0,params.timeoutMs),url=`http://127.0.0.1:${params.cdpPort}/json/version`;for(;Date.now()<deadline;){try{let ctrl=new AbortController,t=setTimeout(ctrl.abort.bind(ctrl),1e3);try{if((await fetch(url,{signal:ctrl.signal})).ok)return!0}finally{clearTimeout(t)}}catch{}await new Promise(r=>setTimeout(r,150))}return!1}function buildSandboxBrowserResolvedConfig(params){return{enabled:!0,evaluateEnabled:params.evaluateEnabled,controlPort:params.controlPort,cdpProtocol:`http`,cdpHost:`127.0.0.1`,cdpIsLoopback:!0,remoteCdpTimeoutMs:1500,remoteCdpHandshakeTimeoutMs:3e3,color:DEFAULT_BUILDERFORCE_AGENTS_BROWSER_COLOR,executablePath:void 0,headless:params.headless,noSandbox:!1,attachOnly:!0,defaultProfile:DEFAULT_BUILDERFORCE_AGENTS_BROWSER_PROFILE_NAME,extraArgs:[],profiles:{[DEFAULT_BUILDERFORCE_AGENTS_BROWSER_PROFILE_NAME]:{cdpPort:params.cdpPort,color:DEFAULT_BUILDERFORCE_AGENTS_BROWSER_COLOR}}}}async function ensureSandboxBrowserImage(image){if((await execDocker([`image`,`inspect`,image],{allowFailure:!0})).code!==0)throw Error(`Sandbox browser image not found: ${image}. Build it with scripts/sandbox-browser-setup.sh.`)}async function ensureSandboxBrowser(params){if(!params.cfg.browser.enabled||!isToolAllowed(params.cfg.tools,`browser`))return null;let slug=params.cfg.scope===`shared`?`shared`:slugifySessionKey(params.scopeKey),containerName=`${params.cfg.browser.containerPrefix}${slug}`.slice(0,63),state=await dockerContainerState(containerName),browserImage=params.cfg.browser.image??DEFAULT_SANDBOX_BROWSER_IMAGE,browserDockerCfg=resolveSandboxBrowserDockerCreateConfig({docker:params.cfg.docker,browser:{...params.cfg.browser,image:browserImage}}),expectedHash=computeSandboxBrowserConfigHash({docker:browserDockerCfg,browser:{cdpPort:params.cfg.browser.cdpPort,vncPort:params.cfg.browser.vncPort,noVncPort:params.cfg.browser.noVncPort,headless:params.cfg.browser.headless,enableNoVnc:params.cfg.browser.enableNoVnc},workspaceAccess:params.cfg.workspaceAccess,workspaceDir:params.workspaceDir,agentWorkspaceDir:params.agentWorkspaceDir}),now=Date.now(),hasContainer=state.exists,running=state.running,currentHash=null,hashMismatch=!1;if(hasContainer){let registryEntry=(await readBrowserRegistry()).entries.find(entry=>entry.containerName===containerName);if(currentHash=await readDockerContainerLabel(containerName,`builderforce.configHash`),hashMismatch=!currentHash||currentHash!==expectedHash,currentHash||(currentHash=registryEntry?.configHash??null,hashMismatch=!currentHash||currentHash!==expectedHash),hashMismatch){let lastUsedAtMs=registryEntry?.lastUsedAtMs;if(running&&(typeof lastUsedAtMs!=`number`||now-lastUsedAtMs<3e5)){let hint=params.cfg.scope===`session`?`builderforce sandbox recreate --browser --session ${params.scopeKey}`:params.cfg.scope===`agent`?`builderforce sandbox recreate --browser --agent ${resolveSandboxAgentId(params.scopeKey)??`main`}`:`builderforce sandbox recreate --browser --all`;defaultRuntime.log(`Sandbox browser config changed for ${containerName} (recently used). Recreate to apply: ${hint}`)}else await execDocker([`rm`,`-f`,containerName],{allowFailure:!0}),hasContainer=!1,running=!1}}if(hasContainer)running||await execDocker([`start`,containerName]);else{await ensureSandboxBrowserImage(browserImage);let args=buildSandboxCreateArgs({name:containerName,cfg:browserDockerCfg,scopeKey:params.scopeKey,labels:{"builderforce.sandboxBrowser":`1`},configHash:expectedHash}),mainMountSuffix=params.cfg.workspaceAccess===`ro`&¶ms.workspaceDir===params.agentWorkspaceDir?`:ro`:``;if(args.push(`-v`,`${params.workspaceDir}:${params.cfg.docker.workdir}${mainMountSuffix}`),params.cfg.workspaceAccess!==`none`&¶ms.workspaceDir!==params.agentWorkspaceDir){let agentMountSuffix=params.cfg.workspaceAccess===`ro`?`:ro`:``;args.push(`-v`,`${params.agentWorkspaceDir}:${SANDBOX_AGENT_WORKSPACE_MOUNT}${agentMountSuffix}`)}args.push(`-p`,`127.0.0.1::${params.cfg.browser.cdpPort}`),params.cfg.browser.enableNoVnc&&!params.cfg.browser.headless&&args.push(`-p`,`127.0.0.1::${params.cfg.browser.noVncPort}`),args.push(`-e`,`BUILDERFORCE_AGENTS_BROWSER_HEADLESS=${params.cfg.browser.headless?`1`:`0`}`),args.push(`-e`,`BUILDERFORCE_AGENTS_BROWSER_ENABLE_NOVNC=${params.cfg.browser.enableNoVnc?`1`:`0`}`),args.push(`-e`,`BUILDERFORCE_AGENTS_BROWSER_CDP_PORT=${params.cfg.browser.cdpPort}`),args.push(`-e`,`BUILDERFORCE_AGENTS_BROWSER_VNC_PORT=${params.cfg.browser.vncPort}`),args.push(`-e`,`BUILDERFORCE_AGENTS_BROWSER_NOVNC_PORT=${params.cfg.browser.noVncPort}`),args.push(browserImage),await execDocker(args),await execDocker([`start`,containerName])}let mappedCdp=await readDockerPort(containerName,params.cfg.browser.cdpPort);if(!mappedCdp)throw Error(`Failed to resolve CDP port mapping for ${containerName}.`);let mappedNoVnc=params.cfg.browser.enableNoVnc&&!params.cfg.browser.headless?await readDockerPort(containerName,params.cfg.browser.noVncPort):null,existing=BROWSER_BRIDGES.get(params.scopeKey),existingProfile=existing?resolveProfile(existing.bridge.state.resolved,DEFAULT_BUILDERFORCE_AGENTS_BROWSER_PROFILE_NAME):null,desiredAuthToken=params.bridgeAuth?.token?.trim()||void 0,desiredAuthPassword=params.bridgeAuth?.password?.trim()||void 0;!desiredAuthToken&&!desiredAuthPassword&&(desiredAuthToken=existing?.authToken,desiredAuthPassword=existing?.authPassword,!desiredAuthToken&&!desiredAuthPassword&&(desiredAuthToken=crypto.randomBytes(24).toString(`hex`)));let shouldReuse=existing&&existing.containerName===containerName&&existingProfile?.cdpPort===mappedCdp,authMatches=!existing||existing.authToken===desiredAuthToken&&existing.authPassword===desiredAuthPassword;existing&&!shouldReuse&&(await stopBrowserBridgeServer(existing.bridge.server).catch(()=>void 0),BROWSER_BRIDGES.delete(params.scopeKey)),existing&&shouldReuse&&!authMatches&&(await stopBrowserBridgeServer(existing.bridge.server).catch(()=>void 0),BROWSER_BRIDGES.delete(params.scopeKey));let bridge=shouldReuse&&authMatches&&existing?existing.bridge:null,resolvedBridge=await(async()=>{if(bridge)return bridge;let onEnsureAttachTarget=params.cfg.browser.autoStart?async()=>{let state=await dockerContainerState(containerName);if(state.exists&&!state.running&&await execDocker([`start`,containerName]),!await waitForSandboxCdp({cdpPort:mappedCdp,timeoutMs:params.cfg.browser.autoStartTimeoutMs}))throw Error(`Sandbox browser CDP did not become reachable on 127.0.0.1:${mappedCdp} within ${params.cfg.browser.autoStartTimeoutMs}ms.`)}:void 0;return await startBrowserBridgeServer({resolved:buildSandboxBrowserResolvedConfig({controlPort:0,cdpPort:mappedCdp,headless:params.cfg.browser.headless,evaluateEnabled:params.evaluateEnabled??DEFAULT_BROWSER_EVALUATE_ENABLED}),authToken:desiredAuthToken,authPassword:desiredAuthPassword,onEnsureAttachTarget})})();(!shouldReuse||!authMatches)&&BROWSER_BRIDGES.set(params.scopeKey,{bridge:resolvedBridge,containerName,authToken:desiredAuthToken,authPassword:desiredAuthPassword}),await updateBrowserRegistry({containerName,sessionKey:params.scopeKey,createdAtMs:now,lastUsedAtMs:now,image:browserImage,configHash:hashMismatch&&running?currentHash??void 0:expectedHash,cdpPort:mappedCdp,noVncPort:mappedNoVnc??void 0});let noVncUrl=mappedNoVnc&¶ms.cfg.browser.enableNoVnc&&!params.cfg.browser.headless?`http://127.0.0.1:${mappedNoVnc}/vnc.html?autoconnect=1&resize=remote`:void 0;return{bridgeUrl:resolvedBridge.baseUrl,noVncUrl,containerName}}function parseSandboxBindMount(spec){let trimmed=spec.trim();if(!trimmed)return null;let parsed=splitBindSpec(trimmed);if(!parsed)return null;let hostToken=parsed.host.trim(),containerToken=parsed.container.trim();if(!hostToken||!containerToken||!path.posix.isAbsolute(containerToken))return null;let optionsToken=parsed.options.trim().toLowerCase(),writable=!(optionsToken?optionsToken.split(`,`).map(entry=>entry.trim()).filter(Boolean):[]).includes(`ro`);return{hostRoot:path.resolve(hostToken),containerRoot:normalizeContainerPath(containerToken),writable}}function splitBindSpec(spec){let separator=getHostContainerSeparatorIndex(spec);if(separator===-1)return null;let host=spec.slice(0,separator),rest=spec.slice(separator+1),optionsStart=rest.indexOf(`:`);return optionsStart===-1?{host,container:rest,options:``}:{host,container:rest.slice(0,optionsStart),options:rest.slice(optionsStart+1)}}function getHostContainerSeparatorIndex(spec){let hasDriveLetterPrefix=/^[A-Za-z]:[\\/]/.test(spec);for(let i=hasDriveLetterPrefix?2:0;i<spec.length;i+=1)if(spec[i]===`:`)return i;return-1}function buildSandboxFsMounts(sandbox){let mounts=[{hostRoot:path.resolve(sandbox.workspaceDir),containerRoot:normalizeContainerPath(sandbox.containerWorkdir),writable:sandbox.workspaceAccess===`rw`,source:`workspace`}];sandbox.workspaceAccess!==`none`&&path.resolve(sandbox.agentWorkspaceDir)!==path.resolve(sandbox.workspaceDir)&&mounts.push({hostRoot:path.resolve(sandbox.agentWorkspaceDir),containerRoot:SANDBOX_AGENT_WORKSPACE_MOUNT,writable:sandbox.workspaceAccess===`rw`,source:`agent`});for(let bind of sandbox.docker.binds??[]){let parsed=parseSandboxBindMount(bind);parsed&&mounts.push({hostRoot:parsed.hostRoot,containerRoot:parsed.containerRoot,writable:parsed.writable,source:`bind`})}return dedupeMounts(mounts)}function resolveSandboxFsPathWithMounts(params){let mountsByContainer=[...params.mounts].toSorted((a,b)=>b.containerRoot.length-a.containerRoot.length),mountsByHost=[...params.mounts].toSorted((a,b)=>b.hostRoot.length-a.hostRoot.length),input=params.filePath,inputPosix=normalizePosixInput(input);if(path.posix.isAbsolute(inputPosix)){let containerMount=findMountByContainerPath(mountsByContainer,inputPosix);if(containerMount){let rel=path.posix.relative(containerMount.containerRoot,inputPosix);return{hostPath:rel?path.resolve(containerMount.hostRoot,...toHostSegments(rel)):containerMount.hostRoot,containerPath:rel?path.posix.join(containerMount.containerRoot,rel):containerMount.containerRoot,relativePath:toDisplayRelative({containerPath:rel?path.posix.join(containerMount.containerRoot,rel):containerMount.containerRoot,defaultContainerRoot:params.defaultContainerRoot}),writable:containerMount.writable}}}let hostResolved=resolveSandboxInputPath(input,params.cwd),hostMount=findMountByHostPath(mountsByHost,hostResolved);if(hostMount){let relHost=path.relative(hostMount.hostRoot,hostResolved),relPosix=relHost?relHost.split(path.sep).join(path.posix.sep):``,containerPath=relPosix?path.posix.join(hostMount.containerRoot,relPosix):hostMount.containerRoot;return{hostPath:hostResolved,containerPath,relativePath:toDisplayRelative({containerPath,defaultContainerRoot:params.defaultContainerRoot}),writable:hostMount.writable}}throw resolveSandboxPath({filePath:input,cwd:params.cwd,root:params.defaultWorkspaceRoot}),Error(`Path escapes sandbox root (${params.defaultWorkspaceRoot}): ${input}`)}function dedupeMounts(mounts){let seen=new Set,deduped=[];for(let mount of mounts){let key=`${mount.hostRoot}=>${mount.containerRoot}`;seen.has(key)||(seen.add(key),deduped.push(mount))}return deduped}function findMountByContainerPath(mounts,target){for(let mount of mounts)if(isPathInsidePosix(mount.containerRoot,target))return mount;return null}function findMountByHostPath(mounts,target){for(let mount of mounts)if(isPathInsideHost(mount.hostRoot,target))return mount;return null}function isPathInsidePosix(root,target){let rel=path.posix.relative(root,target);return rel?!(rel.startsWith(`..`)||path.posix.isAbsolute(rel)):!0}function isPathInsideHost(root,target){let rel=path.relative(root,target);return rel?!(rel.startsWith(`..`)||path.isAbsolute(rel)):!0}function toHostSegments(relativePosix){return relativePosix.split(`/`).filter(Boolean)}function toDisplayRelative(params){let rel=path.posix.relative(params.defaultContainerRoot,params.containerPath);return rel?!rel.startsWith(`..`)&&!path.posix.isAbsolute(rel)?rel:params.containerPath:``}function normalizeContainerPath(value){let normalized=path.posix.normalize(value);return normalized===`.`?`/`:normalized}function normalizePosixInput(value){return value.replace(/\\/g,`/`).trim()}function createSandboxFsBridge(params){return new SandboxFsBridgeImpl(params.sandbox)}var SandboxFsBridgeImpl=class{constructor(sandbox){this.sandbox=sandbox,this.mounts=buildSandboxFsMounts(sandbox)}resolvePath(params){let target=this.resolveResolvedPath(params);return{hostPath:target.hostPath,relativePath:target.relativePath,containerPath:target.containerPath}}async readFile(params){let target=this.resolveResolvedPath(params);return(await this.runCommand(`set -eu; cat -- "$1"`,{args:[target.containerPath],signal:params.signal})).stdout}async writeFile(params){let target=this.resolveResolvedPath(params);this.ensureWriteAccess(target,`write files`);let buffer=Buffer.isBuffer(params.data)?params.data:Buffer.from(params.data,params.encoding??`utf8`),script=params.mkdir===!1?`set -eu; cat >"$1"`:`set -eu; dir=$(dirname -- "$1"); if [ "$dir" != "." ]; then mkdir -p -- "$dir"; fi; cat >"$1"`;await this.runCommand(script,{args:[target.containerPath],stdin:buffer,signal:params.signal})}async mkdirp(params){let target=this.resolveResolvedPath(params);this.ensureWriteAccess(target,`create directories`),await this.runCommand(`set -eu; mkdir -p -- "$1"`,{args:[target.containerPath],signal:params.signal})}async remove(params){let target=this.resolveResolvedPath(params);this.ensureWriteAccess(target,`remove files`);let flags=[params.force===!1?``:`-f`,params.recursive?`-r`:``].filter(Boolean),rmCommand=flags.length>0?`rm ${flags.join(` `)}`:`rm`;await this.runCommand(`set -eu; ${rmCommand} -- "$1"`,{args:[target.containerPath],signal:params.signal})}async rename(params){let from=this.resolveResolvedPath({filePath:params.from,cwd:params.cwd}),to=this.resolveResolvedPath({filePath:params.to,cwd:params.cwd});this.ensureWriteAccess(from,`rename files`),this.ensureWriteAccess(to,`rename files`),await this.runCommand(`set -eu; dir=$(dirname -- "$2"); if [ "$dir" != "." ]; then mkdir -p -- "$dir"; fi; mv -- "$1" "$2"`,{args:[from.containerPath,to.containerPath],signal:params.signal})}async stat(params){let target=this.resolveResolvedPath(params),result=await this.runCommand(`set -eu; stat -c "%F|%s|%Y" -- "$1"`,{args:[target.containerPath],signal:params.signal,allowFailure:!0});if(result.code!==0){let stderr=result.stderr.toString(`utf8`);if(stderr.includes(`No such file or directory`))return null;let message=stderr.trim()||`stat failed with code ${result.code}`;throw Error(`stat failed for ${target.containerPath}: ${message}`)}let[typeRaw,sizeRaw,mtimeRaw]=result.stdout.toString(`utf8`).trim().split(`|`),size=Number.parseInt(sizeRaw??`0`,10),mtime=Number.parseInt(mtimeRaw??`0`,10)*1e3;return{type:coerceStatType(typeRaw),size:Number.isFinite(size)?size:0,mtimeMs:Number.isFinite(mtime)?mtime:0}}async runCommand(script,options={}){let dockerArgs=[`exec`,`-i`,this.sandbox.containerName,`sh`,`-c`,script,`builderforce-sandbox-fs`];return options.args?.length&&dockerArgs.push(...options.args),execDockerRaw(dockerArgs,{input:options.stdin,allowFailure:options.allowFailure,signal:options.signal})}ensureWriteAccess(target,action){if(!allowsWrites(this.sandbox.workspaceAccess)||!target.writable)throw Error(`Sandbox path is read-only; cannot ${action}: ${target.containerPath}`)}resolveResolvedPath(params){return resolveSandboxFsPathWithMounts({filePath:params.filePath,cwd:params.cwd??this.sandbox.workspaceDir,defaultWorkspaceRoot:this.sandbox.workspaceDir,defaultContainerRoot:this.sandbox.containerWorkdir,mounts:this.mounts})}};function allowsWrites(access){return access===`rw`}function coerceStatType(typeRaw){if(!typeRaw)return`other`;let normalized=typeRaw.trim().toLowerCase();return normalized.includes(`directory`)?`directory`:normalized.includes(`file`)?`file`:`other`}let lastPruneAtMs=0;function shouldPruneSandboxEntry(cfg,now,entry){let idleHours=cfg.prune.idleHours,maxAgeDays=cfg.prune.maxAgeDays;if(idleHours===0&&maxAgeDays===0)return!1;let idleMs=now-entry.lastUsedAtMs,ageMs=now-entry.createdAtMs;return idleHours>0&&idleMs>idleHours*60*60*1e3||maxAgeDays>0&&ageMs>maxAgeDays*24*60*60*1e3}async function pruneSandboxRegistryEntries(params){let now=Date.now();if(params.cfg.prune.idleHours===0&¶ms.cfg.prune.maxAgeDays===0)return;let registry=await params.read();for(let entry of registry.entries)if(shouldPruneSandboxEntry(params.cfg,now,entry))try{await execDocker([`rm`,`-f`,entry.containerName],{allowFailure:!0})}catch{}finally{await params.remove(entry.containerName),await params.onRemoved?.(entry)}}async function pruneSandboxContainers(cfg){await pruneSandboxRegistryEntries({cfg,read:readRegistry,remove:removeRegistryEntry})}async function pruneSandboxBrowsers(cfg){await pruneSandboxRegistryEntries({cfg,read:readBrowserRegistry,remove:removeBrowserRegistryEntry,onRemoved:async entry=>{let bridge=BROWSER_BRIDGES.get(entry.sessionKey);bridge?.containerName===entry.containerName&&(await stopBrowserBridgeServer(bridge.bridge.server).catch(()=>void 0),BROWSER_BRIDGES.delete(entry.sessionKey))}})}async function maybePruneSandboxes(cfg){let now=Date.now();if(!(now-lastPruneAtMs<300*1e3)){lastPruneAtMs=now;try{await pruneSandboxContainers(cfg),await pruneSandboxBrowsers(cfg)}catch(error){let message=error instanceof Error?error.message:typeof error==`string`?error:JSON.stringify(error);defaultRuntime.error?.(`Sandbox prune failed: ${message??`unknown error`}`)}}}function shouldSandboxSession(cfg,sessionKey,mainSessionKey){return cfg.mode===`off`?!1:cfg.mode===`all`?!0:sessionKey.trim()!==mainSessionKey.trim()}function resolveMainSessionKeyForSandbox(params){return params.cfg?.session?.scope===`global`?`global`:resolveAgentMainSessionKey({cfg:params.cfg,agentId:params.agentId})}function resolveComparableSessionKeyForSandbox(params){return canonicalizeMainSessionAlias({cfg:params.cfg,agentId:params.agentId,sessionKey:params.sessionKey})}function resolveSandboxRuntimeStatus(params){let sessionKey=params.sessionKey?.trim()??``,agentId=resolveSessionAgentId({sessionKey,config:params.cfg}),cfg=params.cfg,sandboxCfg=resolveSandboxConfigForAgent(cfg,agentId),mainSessionKey=resolveMainSessionKeyForSandbox({cfg,agentId}),sandboxed=sessionKey?shouldSandboxSession(sandboxCfg,resolveComparableSessionKeyForSandbox({cfg,agentId,sessionKey}),mainSessionKey):!1;return{agentId,sessionKey,mainSessionKey,mode:sandboxCfg.mode,sandboxed,toolPolicy:resolveSandboxToolPolicyForAgent(cfg,agentId)}}function formatSandboxToolPolicyBlockedMessage(params){let tool=params.toolName.trim().toLowerCase();if(!tool)return;let runtime=resolveSandboxRuntimeStatus({cfg:params.cfg,sessionKey:params.sessionKey});if(!runtime.sandboxed)return;let deny=new Set(expandToolGroups(runtime.toolPolicy.deny)),allow=expandToolGroups(runtime.toolPolicy.allow),allowSet=allow.length>0?new Set(allow):null,blockedByDeny=deny.has(tool),blockedByAllow=allowSet?!allowSet.has(tool):!1;if(!blockedByDeny&&!blockedByAllow)return;let reasons=[],fixes=[];blockedByDeny&&(reasons.push(`deny list`),fixes.push(`Remove "${tool}" from ${runtime.toolPolicy.sources.deny.key}.`)),blockedByAllow&&(reasons.push(`allow list`),fixes.push(`Add "${tool}" to ${runtime.toolPolicy.sources.allow.key} (or set it to [] to allow all).`));let lines=[];lines.push(`Tool "${tool}" blocked by sandbox tool policy (mode=${runtime.mode}).`),lines.push(`Session: ${runtime.sessionKey||`(unknown)`}`),lines.push(`Reason: ${reasons.join(` + `)}`),lines.push(`Fix:`),lines.push(`- agents.defaults.sandbox.mode=off (disable sandbox)`);for(let fix of fixes)lines.push(`- ${fix}`);return runtime.mode===`non-main`&&lines.push(`- Use main session key (direct): ${runtime.mainSessionKey}`),lines.push(`- See: ${formatCliCommand(`builderforce sandbox explain --session ${runtime.sessionKey}`)}`),lines.join(`
|
|
1
|
+
import{r as STATE_DIR}from"./paths-5FcIFMsj.js";import{b as resolveUserPath}from"./utils-DbaBVFaK.js";import{d as normalizeAgentId,p as resolveAgentIdFromSessionKey}from"./session-key-EoB0qaG9.js";import{i as defaultRuntime}from"./subsystem-B3TqcCrZ.js";import{t as CHANNEL_IDS}from"./registry-TdK-aV05.js";import{S as DEFAULT_USER_FILENAME,_ as DEFAULT_IDENTITY_FILENAME,b as DEFAULT_SOUL_FILENAME,d as resolveSessionAgentId,g as DEFAULT_HEARTBEAT_FILENAME,h as DEFAULT_BOOTSTRAP_FILENAME,m as DEFAULT_AGENT_WORKSPACE_DIR,p as DEFAULT_AGENTS_FILENAME,r as resolveAgentConfig,w as ensureAgentWorkspace,x as DEFAULT_TOOLS_FILENAME}from"./agent-scope-DPtjOxzp.js";import{t as normalizeBaseUrl}from"./normalize-base-url-DmugqkQ6.js";import{t as formatCliCommand}from"./command-format-D806O2pt.js";import{r as loadConfig}from"./io-BLBq4T2o.js";import{D as DEFAULT_BUILDERFORCE_AGENTS_BROWSER_PROFILE_NAME,T as DEFAULT_BUILDERFORCE_AGENTS_BROWSER_COLOR,w as DEFAULT_BROWSER_EVALUATE_ENABLED}from"./chrome-DXt86tmV.js";import{c as safeEqualSecret}from"./auth-lebUHrkd.js";import{r as isLoopbackHost}from"./ws-Bbu03j3h.js";import{a as resolveProfile,m as resolveBrowserControlAuth,p as ensureBrowserControlAuth,t as createBrowserRouteContext}from"./server-context-CQ2v4BAx.js";import{d as resolveSandboxInputPath,f as resolveSandboxPath,o as syncSkillsToWorkspace}from"./skills-Ba4ftrB-.js";import{t as registerBrowserRoutes}from"./routes-DZntyPY6.js";import{L as canonicalizeMainSessionAlias,R as resolveAgentMainSessionKey,nt as acquireSessionWriteLock}from"./sessions-BuZVmOWt.js";import{existsSync,realpathSync}from"node:fs";import path,{posix}from"node:path";import crypto from"node:crypto";import fs$1 from"node:fs/promises";import{spawn}from"node:child_process";import express from"express";const DEFAULT_SANDBOX_WORKSPACE_ROOT=path.join(STATE_DIR,`sandboxes`),DEFAULT_SANDBOX_IMAGE=`builderforce-sandbox:bookworm-slim`,DEFAULT_TOOL_ALLOW=[`exec`,`process`,`read`,`write`,`edit`,`apply_patch`,`image`,`sessions_list`,`sessions_history`,`sessions_send`,`sessions_spawn`,`subagents`,`session_status`],DEFAULT_TOOL_DENY=[`browser`,`canvas`,`nodes`,`cron`,`gateway`,...CHANNEL_IDS],DEFAULT_SANDBOX_BROWSER_IMAGE=`builderforce-sandbox-browser:bookworm-slim`,DEFAULT_SANDBOX_COMMON_IMAGE=`builderforce-sandbox-common:bookworm-slim`,SANDBOX_AGENT_WORKSPACE_MOUNT=`/agent`,SANDBOX_STATE_DIR=path.join(STATE_DIR,`sandbox`),SANDBOX_REGISTRY_PATH=path.join(SANDBOX_STATE_DIR,`containers.json`),SANDBOX_BROWSER_REGISTRY_PATH=path.join(SANDBOX_STATE_DIR,`browsers.json`);function escapeRegex(value){return value.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function compileGlobPattern(params){let normalized=params.normalize(params.raw);return normalized?normalized===`*`?{kind:`all`}:normalized.includes(`*`)?{kind:`regex`,value:RegExp(`^${escapeRegex(normalized).replaceAll(`\\*`,`.*`)}$`)}:{kind:`exact`,value:normalized}:{kind:`exact`,value:``}}function compileGlobPatterns(params){return Array.isArray(params.raw)?params.raw.map(raw=>compileGlobPattern({raw,normalize:params.normalize})).filter(pattern=>pattern.kind!==`exact`||pattern.value):[]}function matchesAnyGlobPattern(value,patterns){for(let pattern of patterns)if(pattern.kind===`all`||pattern.kind===`exact`&&value===pattern.value||pattern.kind===`regex`&&pattern.value.test(value))return!0;return!1}const TOOL_NAME_ALIASES={bash:`exec`,"apply-patch":`apply_patch`,str_replace_editor:`edit`},TOOL_GROUPS={"group:memory":[`memory_search`,`memory_get`],"group:web":[`web_search`,`web_fetch`],"group:fs":[`read`,`write`,`edit`,`apply_patch`],"group:runtime":[`exec`,`process`],"group:sessions":[`sessions_list`,`sessions_history`,`sessions_send`,`sessions_spawn`,`subagents`,`session_status`],"group:ui":[`browser`,`canvas`],"group:automation":[`cron`,`gateway`],"group:messaging":[`message`],"group:nodes":[`nodes`],"group:builderforce":[`browser`,`canvas`,`nodes`,`cron`,`message`,`gateway`,`agents_list`,`sessions_list`,`sessions_history`,`sessions_send`,`sessions_spawn`,`subagents`,`session_status`,`memory_search`,`memory_get`,`web_search`,`web_fetch`,`image`]},OWNER_ONLY_TOOL_NAMES=new Set([`whatsapp_login`]),TOOL_PROFILES={minimal:{allow:[`session_status`]},coding:{allow:[`group:fs`,`group:runtime`,`group:sessions`,`group:memory`,`image`]},messaging:{allow:[`group:messaging`,`sessions_list`,`sessions_history`,`sessions_send`,`session_status`]},full:{}};function normalizeToolName(name){let normalized=name.trim().toLowerCase();return TOOL_NAME_ALIASES[normalized]??normalized}function isOwnerOnlyToolName(name){return OWNER_ONLY_TOOL_NAMES.has(normalizeToolName(name))}function applyOwnerOnlyToolPolicy(tools,senderIsOwner){let withGuard=tools.map(tool=>!isOwnerOnlyToolName(tool.name)||senderIsOwner||!tool.execute?tool:{...tool,execute:async()=>{throw Error(`Tool restricted to owner senders.`)}});return senderIsOwner?withGuard:withGuard.filter(tool=>!isOwnerOnlyToolName(tool.name))}function normalizeToolList(list){return list?list.map(normalizeToolName).filter(Boolean):[]}function expandToolGroups(list){let normalized=normalizeToolList(list),expanded=[];for(let value of normalized){let group=TOOL_GROUPS[value];if(group){expanded.push(...group);continue}expanded.push(value)}return Array.from(new Set(expanded))}function collectExplicitAllowlist(policies){let entries=[];for(let policy of policies)if(policy?.allow)for(let value of policy.allow){if(typeof value!=`string`)continue;let trimmed=value.trim();trimmed&&entries.push(trimmed)}return entries}function buildPluginToolGroups(params){let all=[],byPlugin=new Map;for(let tool of params.tools){let meta=params.toolMeta(tool);if(!meta)continue;let name=normalizeToolName(tool.name);all.push(name);let pluginId=meta.pluginId.toLowerCase(),list=byPlugin.get(pluginId)??[];list.push(name),byPlugin.set(pluginId,list)}return{all,byPlugin}}function expandPluginGroups(list,groups){if(!list||list.length===0)return list;let expanded=[];for(let entry of list){let normalized=normalizeToolName(entry);if(normalized===`group:plugins`){groups.all.length>0?expanded.push(...groups.all):expanded.push(normalized);continue}let tools=groups.byPlugin.get(normalized);if(tools&&tools.length>0){expanded.push(...tools);continue}expanded.push(normalized)}return Array.from(new Set(expanded))}function expandPolicyWithPluginGroups(policy,groups){if(policy)return{allow:expandPluginGroups(policy.allow,groups),deny:expandPluginGroups(policy.deny,groups)}}function stripPluginOnlyAllowlist(policy,groups,coreTools){if(!policy?.allow||policy.allow.length===0)return{policy,unknownAllowlist:[],strippedAllowlist:!1};let normalized=normalizeToolList(policy.allow);if(normalized.length===0)return{policy,unknownAllowlist:[],strippedAllowlist:!1};let pluginIds=new Set(groups.byPlugin.keys()),pluginTools=new Set(groups.all),unknownAllowlist=[],hasCoreEntry=!1;for(let entry of normalized){if(entry===`*`){hasCoreEntry=!0;continue}let isPluginEntry=entry===`group:plugins`||pluginIds.has(entry)||pluginTools.has(entry),isCoreEntry=expandToolGroups([entry]).some(tool=>coreTools.has(tool));isCoreEntry&&(hasCoreEntry=!0),!isCoreEntry&&!isPluginEntry&&unknownAllowlist.push(entry)}let strippedAllowlist=!hasCoreEntry;return{policy:strippedAllowlist?{...policy,allow:void 0}:policy,unknownAllowlist:Array.from(new Set(unknownAllowlist)),strippedAllowlist}}function resolveToolProfilePolicy(profile){if(!profile)return;let resolved=TOOL_PROFILES[profile];if(resolved&&!(!resolved.allow&&!resolved.deny))return{allow:resolved.allow?[...resolved.allow]:void 0,deny:resolved.deny?[...resolved.deny]:void 0}}function mergeAlsoAllowPolicy(policy,alsoAllow){return!policy?.allow||!Array.isArray(alsoAllow)||alsoAllow.length===0?policy:{...policy,allow:Array.from(new Set([...policy.allow,...alsoAllow]))}}function normalizeGlob(value){return value.trim().toLowerCase()}function isToolAllowed(policy,name){let normalized=normalizeGlob(name);if(matchesAnyGlobPattern(normalized,compileGlobPatterns({raw:expandToolGroups(policy.deny??[]),normalize:normalizeGlob})))return!1;let allow=compileGlobPatterns({raw:expandToolGroups(policy.allow??[]),normalize:normalizeGlob});return allow.length===0?!0:matchesAnyGlobPattern(normalized,allow)}function resolveSandboxToolPolicyForAgent(cfg,agentId){let agentConfig=cfg&&agentId?resolveAgentConfig(cfg,agentId):void 0,agentAllow=agentConfig?.tools?.sandbox?.tools?.allow,agentDeny=agentConfig?.tools?.sandbox?.tools?.deny,globalAllow=cfg?.tools?.sandbox?.tools?.allow,globalDeny=cfg?.tools?.sandbox?.tools?.deny,allowSource=Array.isArray(agentAllow)?{source:`agent`,key:`agents.list[].tools.sandbox.tools.allow`}:Array.isArray(globalAllow)?{source:`global`,key:`tools.sandbox.tools.allow`}:{source:`default`,key:`tools.sandbox.tools.allow`},denySource=Array.isArray(agentDeny)?{source:`agent`,key:`agents.list[].tools.sandbox.tools.deny`}:Array.isArray(globalDeny)?{source:`global`,key:`tools.sandbox.tools.deny`}:{source:`default`,key:`tools.sandbox.tools.deny`},deny=Array.isArray(agentDeny)?agentDeny:Array.isArray(globalDeny)?globalDeny:[...DEFAULT_TOOL_DENY],allow=Array.isArray(agentAllow)?agentAllow:Array.isArray(globalAllow)?globalAllow:[...DEFAULT_TOOL_ALLOW],expandedDeny=expandToolGroups(deny),expandedAllow=expandToolGroups(allow);return expandedAllow.length>0&&!expandedDeny.map(v=>v.toLowerCase()).includes(`image`)&&!expandedAllow.map(v=>v.toLowerCase()).includes(`image`)&&(expandedAllow=[...expandedAllow,`image`]),{allow:expandedAllow,deny:expandedDeny,sources:{allow:allowSource,deny:denySource}}}function resolveSandboxBrowserDockerCreateConfig(params){let base={...params.docker,network:`bridge`,image:params.browser.image};return params.browser.binds===void 0?base:{...base,binds:params.browser.binds}}function resolveSandboxScope(params){return params.scope?params.scope:typeof params.perSession==`boolean`?params.perSession?`session`:`shared`:`agent`}function resolveSandboxDockerConfig(params){let agentDocker=params.scope===`shared`?void 0:params.agentDocker,globalDocker=params.globalDocker,env=agentDocker?.env?{...globalDocker?.env??{LANG:`C.UTF-8`},...agentDocker.env}:globalDocker?.env??{LANG:`C.UTF-8`},ulimits=agentDocker?.ulimits?{...globalDocker?.ulimits,...agentDocker.ulimits}:globalDocker?.ulimits,binds=[...globalDocker?.binds??[],...agentDocker?.binds??[]];return{image:agentDocker?.image??globalDocker?.image??DEFAULT_SANDBOX_IMAGE,containerPrefix:agentDocker?.containerPrefix??globalDocker?.containerPrefix??`builderforce-sbx-`,workdir:agentDocker?.workdir??globalDocker?.workdir??`/workspace`,readOnlyRoot:agentDocker?.readOnlyRoot??globalDocker?.readOnlyRoot??!0,tmpfs:agentDocker?.tmpfs??globalDocker?.tmpfs??[`/tmp`,`/var/tmp`,`/run`],network:agentDocker?.network??globalDocker?.network??`none`,user:agentDocker?.user??globalDocker?.user,capDrop:agentDocker?.capDrop??globalDocker?.capDrop??[`ALL`],env,setupCommand:agentDocker?.setupCommand??globalDocker?.setupCommand,pidsLimit:agentDocker?.pidsLimit??globalDocker?.pidsLimit,memory:agentDocker?.memory??globalDocker?.memory,memorySwap:agentDocker?.memorySwap??globalDocker?.memorySwap,cpus:agentDocker?.cpus??globalDocker?.cpus,ulimits,seccompProfile:agentDocker?.seccompProfile??globalDocker?.seccompProfile,apparmorProfile:agentDocker?.apparmorProfile??globalDocker?.apparmorProfile,dns:agentDocker?.dns??globalDocker?.dns,extraHosts:agentDocker?.extraHosts??globalDocker?.extraHosts,binds:binds.length?binds:void 0}}function resolveSandboxBrowserConfig(params){let agentBrowser=params.scope===`shared`?void 0:params.agentBrowser,globalBrowser=params.globalBrowser,binds=[...globalBrowser?.binds??[],...agentBrowser?.binds??[]],bindsConfigured=globalBrowser?.binds!==void 0||agentBrowser?.binds!==void 0;return{enabled:agentBrowser?.enabled??globalBrowser?.enabled??!1,image:agentBrowser?.image??globalBrowser?.image??DEFAULT_SANDBOX_BROWSER_IMAGE,containerPrefix:agentBrowser?.containerPrefix??globalBrowser?.containerPrefix??`builderforce-sbx-browser-`,cdpPort:agentBrowser?.cdpPort??globalBrowser?.cdpPort??9222,vncPort:agentBrowser?.vncPort??globalBrowser?.vncPort??5900,noVncPort:agentBrowser?.noVncPort??globalBrowser?.noVncPort??6080,headless:agentBrowser?.headless??globalBrowser?.headless??!1,enableNoVnc:agentBrowser?.enableNoVnc??globalBrowser?.enableNoVnc??!0,allowHostControl:agentBrowser?.allowHostControl??globalBrowser?.allowHostControl??!1,autoStart:agentBrowser?.autoStart??globalBrowser?.autoStart??!0,autoStartTimeoutMs:agentBrowser?.autoStartTimeoutMs??globalBrowser?.autoStartTimeoutMs??12e3,binds:bindsConfigured?binds:void 0}}function resolveSandboxPruneConfig(params){let agentPrune=params.scope===`shared`?void 0:params.agentPrune,globalPrune=params.globalPrune;return{idleHours:agentPrune?.idleHours??globalPrune?.idleHours??24,maxAgeDays:agentPrune?.maxAgeDays??globalPrune?.maxAgeDays??7}}function resolveSandboxConfigForAgent(cfg,agentId){let agent=cfg?.agents?.defaults?.sandbox,agentSandbox,agentConfig=cfg&&agentId?resolveAgentConfig(cfg,agentId):void 0;agentConfig?.sandbox&&(agentSandbox=agentConfig.sandbox);let scope=resolveSandboxScope({scope:agentSandbox?.scope??agent?.scope,perSession:agentSandbox?.perSession??agent?.perSession}),toolPolicy=resolveSandboxToolPolicyForAgent(cfg,agentId);return{mode:agentSandbox?.mode??agent?.mode??`off`,scope,workspaceAccess:agentSandbox?.workspaceAccess??agent?.workspaceAccess??`none`,workspaceRoot:agentSandbox?.workspaceRoot??agent?.workspaceRoot??DEFAULT_SANDBOX_WORKSPACE_ROOT,docker:resolveSandboxDockerConfig({scope,globalDocker:agent?.docker,agentDocker:agentSandbox?.docker}),browser:resolveSandboxBrowserConfig({scope,globalBrowser:agent?.browser,agentBrowser:agentSandbox?.browser}),tools:{allow:toolPolicy.allow,deny:toolPolicy.deny},prune:resolveSandboxPruneConfig({scope,globalPrune:agent?.prune,agentPrune:agentSandbox?.prune})}}const authByPort=new Map;function setBridgeAuthForPort(port,auth){if(!Number.isFinite(port)||port<=0)return;let token=typeof auth.token==`string`?auth.token.trim():``,password=typeof auth.password==`string`?auth.password.trim():``;authByPort.set(port,{token:token||void 0,password:password||void 0})}function getBridgeAuthForPort(port){if(!(!Number.isFinite(port)||port<=0))return authByPort.get(port)}function deleteBridgeAuthForPort(port){!Number.isFinite(port)||port<=0||authByPort.delete(port)}function firstHeader(value){return Array.isArray(value)?value[0]??``:value??``}function isMutatingMethod(method){let m=(method||``).trim().toUpperCase();return m===`POST`||m===`PUT`||m===`PATCH`||m===`DELETE`}function isLoopbackUrl(value){let v=value.trim();if(!v||v===`null`)return!1;try{return isLoopbackHost(new URL(v).hostname)}catch{return!1}}function shouldRejectBrowserMutation(params){if(!isMutatingMethod(params.method))return!1;if((params.secFetchSite??``).trim().toLowerCase()===`cross-site`)return!0;let origin=(params.origin??``).trim();if(origin)return!isLoopbackUrl(origin);let referer=(params.referer??``).trim();return referer?!isLoopbackUrl(referer):!1}function browserMutationGuardMiddleware(){return(req,res,next)=>{let method=(req.method||``).trim().toUpperCase();if(method===`OPTIONS`)return next();if(shouldRejectBrowserMutation({method,origin:firstHeader(req.headers.origin),referer:firstHeader(req.headers.referer),secFetchSite:firstHeader(req.headers[`sec-fetch-site`])})){res.status(403).send(`Forbidden`);return}next()}}function firstHeaderValue(value){return Array.isArray(value)?value[0]??``:value??``}function parseBearerToken(authorization){if(!(!authorization||!authorization.toLowerCase().startsWith(`bearer `)))return authorization.slice(7).trim()||void 0}function parseBasicPassword(authorization){if(!authorization||!authorization.toLowerCase().startsWith(`basic `))return;let encoded=authorization.slice(6).trim();if(encoded)try{let decoded=Buffer.from(encoded,`base64`).toString(`utf8`),sep=decoded.indexOf(`:`);return sep<0?void 0:decoded.slice(sep+1).trim()||void 0}catch{return}}function isAuthorizedBrowserRequest(req,auth){let authorization=firstHeaderValue(req.headers.authorization).trim();if(auth.token){let bearer=parseBearerToken(authorization);if(bearer&&safeEqualSecret(bearer,auth.token))return!0}if(auth.password){let passwordHeader=(firstHeaderValue(req.headers[`x-builderforce-password`])||firstHeaderValue(req.headers[`x-builderforce-password`])).trim();if(passwordHeader&&safeEqualSecret(passwordHeader,auth.password))return!0;let basicPassword=parseBasicPassword(authorization);if(basicPassword&&safeEqualSecret(basicPassword,auth.password))return!0}return!1}function installBrowserCommonMiddleware(app){app.use((req,res,next)=>{let ctrl=new AbortController,abort=()=>ctrl.abort(Error(`request aborted`));req.once(`aborted`,abort),res.once(`close`,()=>{res.writableEnded||abort()}),Object.defineProperty(req,`signal`,{value:ctrl.signal,configurable:!0,enumerable:!0,writable:!0}),next()}),app.use(express.json({limit:`1mb`})),app.use(browserMutationGuardMiddleware())}function installBrowserAuthMiddleware(app,auth){!auth.token&&!auth.password||app.use((req,res,next)=>{if(isAuthorizedBrowserRequest(req,auth))return next();res.status(401).send(`Unauthorized`)})}async function startBrowserBridgeServer(params){let host=params.host??`127.0.0.1`;if(!isLoopbackHost(host))throw Error(`bridge server must bind to loopback host (got ${host})`);let port=params.port??0,app=express();installBrowserCommonMiddleware(app);let authToken=params.authToken?.trim()||void 0,authPassword=params.authPassword?.trim()||void 0;if(!authToken&&!authPassword)throw Error(`bridge server requires auth (authToken/authPassword missing)`);installBrowserAuthMiddleware(app,{token:authToken,password:authPassword});let state={server:null,port,resolved:params.resolved,profiles:new Map};registerBrowserRoutes(app,createBrowserRouteContext({getState:()=>state,onEnsureAttachTarget:params.onEnsureAttachTarget}));let server=await new Promise((resolve,reject)=>{let s=app.listen(port,host,()=>resolve(s));s.once(`error`,reject)}),resolvedPort=server.address()?.port??port;return state.server=server,state.port=resolvedPort,state.resolved.controlPort=resolvedPort,setBridgeAuthForPort(resolvedPort,{token:authToken,password:authPassword}),{server,port:resolvedPort,baseUrl:`http://${host}:${resolvedPort}`,state}}async function stopBrowserBridgeServer(server){try{let address=server.address();address?.port&&deleteBridgeAuthForPort(address.port)}catch{}await new Promise(resolve=>{server.close(()=>resolve())})}const BROWSER_BRIDGES=new Map;function hashTextSha256(value){return crypto.createHash(`sha256`).update(value).digest(`hex`)}function normalizeForHash(value){if(value!==void 0){if(Array.isArray(value))return value.map(normalizeForHash).filter(item=>item!==void 0);if(value&&typeof value==`object`){let entries=Object.entries(value).toSorted(([a],[b])=>a.localeCompare(b)),normalized={};for(let[key,entryValue]of entries){let next=normalizeForHash(entryValue);next!==void 0&&(normalized[key]=next)}return normalized}return value}}function computeSandboxConfigHash(input){return computeHash(input)}function computeSandboxBrowserConfigHash(input){return computeHash(input)}function computeHash(input){let payload=normalizeForHash(input);return hashTextSha256(JSON.stringify(payload))}const BLOCKED_ENV_VAR_PATTERNS=[/^ANTHROPIC_API_KEY$/i,/^OPENAI_API_KEY$/i,/^GEMINI_API_KEY$/i,/^OPENROUTER_API_KEY$/i,/^MINIMAX_API_KEY$/i,/^ELEVENLABS_API_KEY$/i,/^SYNTHETIC_API_KEY$/i,/^TELEGRAM_BOT_TOKEN$/i,/^DISCORD_BOT_TOKEN$/i,/^SLACK_(BOT|APP)_TOKEN$/i,/^LINE_CHANNEL_SECRET$/i,/^LINE_CHANNEL_ACCESS_TOKEN$/i,/^BUILDERFORCE_AGENTS_GATEWAY_(TOKEN|PASSWORD)$/i,/^AWS_(SECRET_ACCESS_KEY|SECRET_KEY|SESSION_TOKEN)$/i,/^(GH|GITHUB)_TOKEN$/i,/^(AZURE|AZURE_OPENAI|COHERE|AI_GATEWAY|OPENROUTER)_API_KEY$/i,/_?(API_KEY|TOKEN|PASSWORD|PRIVATE_KEY|SECRET)$/i],ALLOWED_ENV_VAR_PATTERNS=[/^LANG$/,/^LC_.*$/i,/^PATH$/i,/^HOME$/i,/^USER$/i,/^SHELL$/i,/^TERM$/i,/^TZ$/i,/^NODE_ENV$/i];function validateEnvVarValue(value){if(value.includes(`\0`))return`Contains null bytes`;if(value.length>32768)return`Value exceeds maximum length`;if(/^[A-Za-z0-9+/=]{80,}$/.test(value))return`Value looks like base64-encoded credential data`}function matchesAnyPattern(value,patterns){return patterns.some(pattern=>pattern.test(value))}function sanitizeEnvVars(envVars,options={}){let allowed={},blocked=[],warnings=[],blockedPatterns=[...BLOCKED_ENV_VAR_PATTERNS,...options.customBlockedPatterns??[]],allowedPatterns=[...ALLOWED_ENV_VAR_PATTERNS,...options.customAllowedPatterns??[]];for(let[rawKey,value]of Object.entries(envVars)){let key=rawKey.trim();if(!key)continue;if(matchesAnyPattern(key,blockedPatterns)){blocked.push(key);continue}if(options.strictMode&&!matchesAnyPattern(key,allowedPatterns)){blocked.push(key);continue}let warning=validateEnvVarValue(value);if(warning){if(warning===`Contains null bytes`){blocked.push(key);continue}warnings.push(`${key}: ${warning}`)}allowed[key]=value}return{allowed,blocked,warnings}}function isRecord(value){return!!value&&typeof value==`object`}function isRegistryEntry(value){return isRecord(value)&&typeof value.containerName==`string`}function isRegistryFile(value){if(!isRecord(value))return!1;let maybeEntries=value.entries;return Array.isArray(maybeEntries)&&maybeEntries.every(isRegistryEntry)}async function withRegistryLock(registryPath,fn){let lock=await acquireSessionWriteLock({sessionFile:registryPath,allowReentrant:!1});try{return await fn()}finally{await lock.release()}}async function readRegistryFromFile(registryPath,mode){try{let raw=await fs$1.readFile(registryPath,`utf-8`),parsed=JSON.parse(raw);if(isRegistryFile(parsed))return parsed;if(mode===`fallback`)return{entries:[]};throw Error(`Invalid sandbox registry format: ${registryPath}`)}catch(error){if(error?.code===`ENOENT`||mode===`fallback`)return{entries:[]};throw error instanceof Error?error:Error(`Failed to read sandbox registry file: ${registryPath}`,{cause:error})}}async function writeRegistryFile(registryPath,registry){await fs$1.mkdir(SANDBOX_STATE_DIR,{recursive:!0});let payload=`${JSON.stringify(registry,null,2)}\n`,registryDir=path.dirname(registryPath),tempPath=path.join(registryDir,`${path.basename(registryPath)}.${crypto.randomUUID()}.tmp`);await fs$1.writeFile(tempPath,payload,`utf-8`);try{await fs$1.rename(tempPath,registryPath)}catch(error){throw await fs$1.rm(tempPath,{force:!0}),error}}async function readRegistry(){return await readRegistryFromFile(SANDBOX_REGISTRY_PATH,`fallback`)}function upsertEntry(entries,entry){let existing=entries.find(item=>item.containerName===entry.containerName),next=entries.filter(item=>item.containerName!==entry.containerName);return next.push({...entry,createdAtMs:existing?.createdAtMs??entry.createdAtMs,image:existing?.image??entry.image,configHash:entry.configHash??existing?.configHash}),next}function removeEntry(entries,containerName){return entries.filter(entry=>entry.containerName!==containerName)}async function withRegistryMutation(registryPath,mutate){await withRegistryLock(registryPath,async()=>{let next=mutate((await readRegistryFromFile(registryPath,`strict`)).entries);next!==null&&await writeRegistryFile(registryPath,{entries:next})})}async function updateRegistry(entry){await withRegistryMutation(SANDBOX_REGISTRY_PATH,entries=>upsertEntry(entries,entry))}async function removeRegistryEntry(containerName){await withRegistryMutation(SANDBOX_REGISTRY_PATH,entries=>{let next=removeEntry(entries,containerName);return next.length===entries.length?null:next})}async function readBrowserRegistry(){return await readRegistryFromFile(SANDBOX_BROWSER_REGISTRY_PATH,`fallback`)}async function updateBrowserRegistry(entry){await withRegistryMutation(SANDBOX_BROWSER_REGISTRY_PATH,entries=>upsertEntry(entries,entry))}async function removeBrowserRegistryEntry(containerName){await withRegistryMutation(SANDBOX_BROWSER_REGISTRY_PATH,entries=>{let next=removeEntry(entries,containerName);return next.length===entries.length?null:next})}function slugifySessionKey(value){let trimmed=value.trim()||`session`,hash=hashTextSha256(trimmed).slice(0,8);return`${trimmed.toLowerCase().replace(/[^a-z0-9._-]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,32)||`session`}-${hash}`}function resolveSandboxWorkspaceDir(root,sessionKey){let resolvedRoot=resolveUserPath(root),slug=slugifySessionKey(sessionKey);return path.join(resolvedRoot,slug)}function resolveSandboxScopeKey(scope,sessionKey){let trimmed=sessionKey.trim()||`main`;return scope===`shared`?`shared`:scope===`session`?trimmed:`agent:${resolveAgentIdFromSessionKey(trimmed)}`}function resolveSandboxAgentId(scopeKey){let trimmed=scopeKey.trim();if(!trimmed||trimmed===`shared`)return;let parts=trimmed.split(`:`).filter(Boolean);return parts[0]===`agent`&&parts[1]?normalizeAgentId(parts[1]):resolveAgentIdFromSessionKey(trimmed)}const BLOCKED_HOST_PATHS=[`/etc`,`/private/etc`,`/proc`,`/sys`,`/dev`,`/root`,`/boot`,`/run`,`/var/run`,`/private/var/run`,`/var/run/docker.sock`,`/private/var/run/docker.sock`,`/run/docker.sock`],BLOCKED_NETWORK_MODES=new Set([`host`]),BLOCKED_SECCOMP_PROFILES=new Set([`unconfined`]),BLOCKED_APPARMOR_PROFILES=new Set([`unconfined`]);function parseBindSourcePath(bind){let trimmed=bind.trim(),firstColon=trimmed.indexOf(`:`);return firstColon<=0?trimmed:trimmed.slice(0,firstColon)}function normalizeHostPath(raw){let trimmed=raw.trim();return normalizeBaseUrl(posix.normalize(trimmed))||`/`}function getBlockedBindReason(bind){let sourceRaw=parseBindSourcePath(bind);return sourceRaw.startsWith(`/`)?getBlockedReasonForSourcePath(normalizeHostPath(sourceRaw)):{kind:`non_absolute`,sourcePath:sourceRaw}}function getBlockedReasonForSourcePath(sourceNormalized){if(sourceNormalized===`/`)return{kind:`covers`,blockedPath:`/`};for(let blocked of BLOCKED_HOST_PATHS)if(sourceNormalized===blocked||sourceNormalized.startsWith(blocked+`/`))return{kind:`targets`,blockedPath:blocked};return null}function tryRealpathAbsolute(path){if(!path.startsWith(`/`)||!existsSync(path))return path;try{return normalizeHostPath(realpathSync.native(path))}catch{return path}}function formatBindBlockedError(params){if(params.reason.kind===`non_absolute`)return Error(`Sandbox security: bind mount "${params.bind}" uses a non-absolute source path "${params.reason.sourcePath}". Only absolute POSIX paths are supported for sandbox binds.`);let verb=params.reason.kind===`covers`?`covers`:`targets`;return Error(`Sandbox security: bind mount "${params.bind}" ${verb} blocked path "${params.reason.blockedPath}". Mounting system directories (or Docker socket paths) into sandbox containers is not allowed. Use project-specific paths instead (e.g. /home/user/myproject).`)}function validateBindMounts(binds){if(binds?.length)for(let rawBind of binds){let bind=rawBind.trim();if(!bind)continue;let blocked=getBlockedBindReason(bind);if(blocked)throw formatBindBlockedError({bind,reason:blocked});let sourceNormalized=normalizeHostPath(parseBindSourcePath(bind)),sourceReal=tryRealpathAbsolute(sourceNormalized);if(sourceReal!==sourceNormalized){let reason=getBlockedReasonForSourcePath(sourceReal);if(reason)throw formatBindBlockedError({bind,reason})}}}function validateNetworkMode(network){if(network&&BLOCKED_NETWORK_MODES.has(network.trim().toLowerCase()))throw Error(`Sandbox security: network mode "${network}" is blocked. Network "host" mode bypasses container network isolation. Use "bridge" or "none" instead.`)}function validateSeccompProfile(profile){if(profile&&BLOCKED_SECCOMP_PROFILES.has(profile.trim().toLowerCase()))throw Error(`Sandbox security: seccomp profile "${profile}" is blocked. Disabling seccomp removes syscall filtering and weakens sandbox isolation. Use a custom seccomp profile file or omit this setting.`)}function validateApparmorProfile(profile){if(profile&&BLOCKED_APPARMOR_PROFILES.has(profile.trim().toLowerCase()))throw Error(`Sandbox security: apparmor profile "${profile}" is blocked. Disabling AppArmor removes mandatory access controls and weakens sandbox isolation. Use a named AppArmor profile or omit this setting.`)}function validateSandboxSecurity(cfg){validateBindMounts(cfg.binds),validateNetworkMode(cfg.network),validateSeccompProfile(cfg.seccompProfile),validateApparmorProfile(cfg.apparmorProfile)}function createAbortError(){let err=Error(`Aborted`);return err.name=`AbortError`,err}function execDockerRaw(args,opts){return new Promise((resolve,reject)=>{let child=spawn(`docker`,args,{stdio:[`pipe`,`pipe`,`pipe`]}),stdoutChunks=[],stderrChunks=[],aborted=!1,signal=opts?.signal,handleAbort=()=>{aborted||(aborted=!0,child.kill(`SIGTERM`))};signal&&(signal.aborted?handleAbort():signal.addEventListener(`abort`,handleAbort,{once:!0})),child.stdout?.on(`data`,chunk=>{stdoutChunks.push(Buffer.isBuffer(chunk)?chunk:Buffer.from(chunk))}),child.stderr?.on(`data`,chunk=>{stderrChunks.push(Buffer.isBuffer(chunk)?chunk:Buffer.from(chunk))}),child.on(`error`,error=>{signal&&signal.removeEventListener(`abort`,handleAbort),reject(error)}),child.on(`close`,code=>{signal&&signal.removeEventListener(`abort`,handleAbort);let stdout=Buffer.concat(stdoutChunks),stderr=Buffer.concat(stderrChunks);if(aborted||signal?.aborted){reject(createAbortError());return}let exitCode=code??0;if(exitCode!==0&&!opts?.allowFailure){let message=stderr.length>0?stderr.toString(`utf8`).trim():``;reject(Object.assign(Error(message||`docker ${args.join(` `)} failed`),{code:exitCode,stdout,stderr}));return}resolve({stdout,stderr,code:exitCode})});let stdin=child.stdin;stdin&&(opts?.input===void 0?stdin.end():stdin.end(opts.input))})}async function execDocker(args,opts){let result=await execDockerRaw(args,opts);return{stdout:result.stdout.toString(`utf8`),stderr:result.stderr.toString(`utf8`),code:result.code}}async function readDockerContainerLabel(containerName,label){let result=await execDocker([`inspect`,`-f`,`{{ index .Config.Labels "${label}" }}`,containerName],{allowFailure:!0});if(result.code!==0)return null;let raw=result.stdout.trim();return!raw||raw===`<no value>`?null:raw}async function readDockerPort(containerName,port){let result=await execDocker([`port`,containerName,`${port}/tcp`],{allowFailure:!0});if(result.code!==0)return null;let match=(result.stdout.trim().split(/\r?\n/)[0]??``).match(/:(\d+)\s*$/);if(!match)return null;let mapped=Number.parseInt(match[1]??``,10);return Number.isFinite(mapped)?mapped:null}async function dockerImageExists(image){let result=await execDocker([`image`,`inspect`,image],{allowFailure:!0});if(result.code===0)return!0;let stderr=result.stderr.trim();if(stderr.includes(`No such image`))return!1;throw Error(`Failed to inspect sandbox image: ${stderr}`)}async function ensureDockerImage(image){if(!await dockerImageExists(image)){if(image===DEFAULT_SANDBOX_IMAGE){await execDocker([`pull`,`debian:bookworm-slim`]),await execDocker([`tag`,`debian:bookworm-slim`,DEFAULT_SANDBOX_IMAGE]);return}throw Error(`Sandbox image not found: ${image}. Build or pull it first.`)}}async function dockerContainerState(name){let result=await execDocker([`inspect`,`-f`,`{{.State.Running}}`,name],{allowFailure:!0});return result.code===0?{exists:!0,running:result.stdout.trim()===`true`}:{exists:!1,running:!1}}function normalizeDockerLimit(value){return value==null?void 0:typeof value==`number`?Number.isFinite(value)?String(value):void 0:value.trim()||void 0}function formatUlimitValue(name,value){if(!name.trim())return null;if(typeof value==`number`||typeof value==`string`){let raw=String(value).trim();return raw?`${name}=${raw}`:null}let soft=typeof value.soft==`number`?Math.max(0,value.soft):void 0,hard=typeof value.hard==`number`?Math.max(0,value.hard):void 0;return soft===void 0&&hard===void 0?null:soft===void 0?`${name}=${hard}`:hard===void 0?`${name}=${soft}`:`${name}=${soft}:${hard}`}function buildSandboxCreateArgs(params){validateSandboxSecurity(params.cfg);let createdAtMs=params.createdAtMs??Date.now(),args=[`create`,`--name`,params.name];args.push(`--label`,`builderforce.sandbox=1`),args.push(`--label`,`builderforce.sessionKey=${params.scopeKey}`),args.push(`--label`,`builderforce.createdAtMs=${createdAtMs}`),params.configHash&&args.push(`--label`,`builderforce.configHash=${params.configHash}`);for(let[key,value]of Object.entries(params.labels??{}))key&&value&&args.push(`--label`,`${key}=${value}`);params.cfg.readOnlyRoot&&args.push(`--read-only`);for(let entry of params.cfg.tmpfs)args.push(`--tmpfs`,entry);params.cfg.network&&args.push(`--network`,params.cfg.network),params.cfg.user&&args.push(`--user`,params.cfg.user);let envSanitization=sanitizeEnvVars(params.cfg.env??{});envSanitization.blocked.length>0&&console.warn(`[Security] Blocked sensitive environment variables:`,envSanitization.blocked.join(`, `)),envSanitization.warnings.length>0&&console.warn(`[Security] Suspicious environment variables:`,envSanitization.warnings);for(let[key,value]of Object.entries(envSanitization.allowed))args.push(`--env`,`${key}=${value}`);for(let cap of params.cfg.capDrop)args.push(`--cap-drop`,cap);args.push(`--security-opt`,`no-new-privileges`),params.cfg.seccompProfile&&args.push(`--security-opt`,`seccomp=${params.cfg.seccompProfile}`),params.cfg.apparmorProfile&&args.push(`--security-opt`,`apparmor=${params.cfg.apparmorProfile}`);for(let entry of params.cfg.dns??[])entry.trim()&&args.push(`--dns`,entry);for(let entry of params.cfg.extraHosts??[])entry.trim()&&args.push(`--add-host`,entry);typeof params.cfg.pidsLimit==`number`&¶ms.cfg.pidsLimit>0&&args.push(`--pids-limit`,String(params.cfg.pidsLimit));let memory=normalizeDockerLimit(params.cfg.memory);memory&&args.push(`--memory`,memory);let memorySwap=normalizeDockerLimit(params.cfg.memorySwap);memorySwap&&args.push(`--memory-swap`,memorySwap),typeof params.cfg.cpus==`number`&¶ms.cfg.cpus>0&&args.push(`--cpus`,String(params.cfg.cpus));for(let[name,value]of Object.entries(params.cfg.ulimits??{})){let formatted=formatUlimitValue(name,value);formatted&&args.push(`--ulimit`,formatted)}if(params.cfg.binds?.length)for(let bind of params.cfg.binds)args.push(`-v`,bind);return args}async function createSandboxContainer(params){let{name,cfg,workspaceDir,scopeKey}=params;await ensureDockerImage(cfg.image);let args=buildSandboxCreateArgs({name,cfg,scopeKey,configHash:params.configHash});args.push(`--workdir`,cfg.workdir);let mainMountSuffix=params.workspaceAccess===`ro`&&workspaceDir===params.agentWorkspaceDir?`:ro`:``;if(args.push(`-v`,`${workspaceDir}:${cfg.workdir}${mainMountSuffix}`),params.workspaceAccess!==`none`&&workspaceDir!==params.agentWorkspaceDir){let agentMountSuffix=params.workspaceAccess===`ro`?`:ro`:``;args.push(`-v`,`${params.agentWorkspaceDir}:${SANDBOX_AGENT_WORKSPACE_MOUNT}${agentMountSuffix}`)}args.push(cfg.image,`sleep`,`infinity`),await execDocker(args),await execDocker([`start`,name]),cfg.setupCommand?.trim()&&await execDocker([`exec`,`-i`,name,`sh`,`-lc`,cfg.setupCommand])}async function readContainerConfigHash(containerName){return await readDockerContainerLabel(containerName,`builderforce.configHash`)}function formatSandboxRecreateHint(params){return params.scope===`session`?formatCliCommand(`builderforce sandbox recreate --session ${params.sessionKey}`):params.scope===`agent`?formatCliCommand(`builderforce sandbox recreate --agent ${resolveSandboxAgentId(params.sessionKey)??`main`}`):formatCliCommand(`builderforce sandbox recreate --all`)}async function ensureSandboxContainer(params){let scopeKey=resolveSandboxScopeKey(params.cfg.scope,params.sessionKey),slug=params.cfg.scope===`shared`?`shared`:slugifySessionKey(scopeKey),containerName=`${params.cfg.docker.containerPrefix}${slug}`.slice(0,63),expectedHash=computeSandboxConfigHash({docker:params.cfg.docker,workspaceAccess:params.cfg.workspaceAccess,workspaceDir:params.workspaceDir,agentWorkspaceDir:params.agentWorkspaceDir}),now=Date.now(),state=await dockerContainerState(containerName),hasContainer=state.exists,running=state.running,currentHash=null,hashMismatch=!1,registryEntry;if(hasContainer&&(registryEntry=(await readRegistry()).entries.find(entry=>entry.containerName===containerName),currentHash=await readContainerConfigHash(containerName),currentHash||=registryEntry?.configHash??null,hashMismatch=!currentHash||currentHash!==expectedHash,hashMismatch)){let lastUsedAtMs=registryEntry?.lastUsedAtMs;if(running&&(typeof lastUsedAtMs!=`number`||now-lastUsedAtMs<3e5)){let hint=formatSandboxRecreateHint({scope:params.cfg.scope,sessionKey:scopeKey});defaultRuntime.log(`Sandbox config changed for ${containerName} (recently used). Recreate to apply: ${hint}`)}else await execDocker([`rm`,`-f`,containerName],{allowFailure:!0}),hasContainer=!1,running=!1}return hasContainer?running||await execDocker([`start`,containerName]):await createSandboxContainer({name:containerName,cfg:params.cfg.docker,workspaceDir:params.workspaceDir,workspaceAccess:params.cfg.workspaceAccess,agentWorkspaceDir:params.agentWorkspaceDir,scopeKey,configHash:expectedHash}),await updateRegistry({containerName,sessionKey:scopeKey,createdAtMs:now,lastUsedAtMs:now,image:params.cfg.docker.image,configHash:hashMismatch&&running?currentHash??void 0:expectedHash}),containerName}async function waitForSandboxCdp(params){let deadline=Date.now()+Math.max(0,params.timeoutMs),url=`http://127.0.0.1:${params.cdpPort}/json/version`;for(;Date.now()<deadline;){try{let ctrl=new AbortController,t=setTimeout(ctrl.abort.bind(ctrl),1e3);try{if((await fetch(url,{signal:ctrl.signal})).ok)return!0}finally{clearTimeout(t)}}catch{}await new Promise(r=>setTimeout(r,150))}return!1}function buildSandboxBrowserResolvedConfig(params){return{enabled:!0,evaluateEnabled:params.evaluateEnabled,controlPort:params.controlPort,cdpProtocol:`http`,cdpHost:`127.0.0.1`,cdpIsLoopback:!0,remoteCdpTimeoutMs:1500,remoteCdpHandshakeTimeoutMs:3e3,color:DEFAULT_BUILDERFORCE_AGENTS_BROWSER_COLOR,executablePath:void 0,headless:params.headless,noSandbox:!1,attachOnly:!0,defaultProfile:DEFAULT_BUILDERFORCE_AGENTS_BROWSER_PROFILE_NAME,extraArgs:[],profiles:{[DEFAULT_BUILDERFORCE_AGENTS_BROWSER_PROFILE_NAME]:{cdpPort:params.cdpPort,color:DEFAULT_BUILDERFORCE_AGENTS_BROWSER_COLOR}}}}async function ensureSandboxBrowserImage(image){if((await execDocker([`image`,`inspect`,image],{allowFailure:!0})).code!==0)throw Error(`Sandbox browser image not found: ${image}. Build it with scripts/sandbox-browser-setup.sh.`)}async function ensureSandboxBrowser(params){if(!params.cfg.browser.enabled||!isToolAllowed(params.cfg.tools,`browser`))return null;let slug=params.cfg.scope===`shared`?`shared`:slugifySessionKey(params.scopeKey),containerName=`${params.cfg.browser.containerPrefix}${slug}`.slice(0,63),state=await dockerContainerState(containerName),browserImage=params.cfg.browser.image??DEFAULT_SANDBOX_BROWSER_IMAGE,browserDockerCfg=resolveSandboxBrowserDockerCreateConfig({docker:params.cfg.docker,browser:{...params.cfg.browser,image:browserImage}}),expectedHash=computeSandboxBrowserConfigHash({docker:browserDockerCfg,browser:{cdpPort:params.cfg.browser.cdpPort,vncPort:params.cfg.browser.vncPort,noVncPort:params.cfg.browser.noVncPort,headless:params.cfg.browser.headless,enableNoVnc:params.cfg.browser.enableNoVnc},workspaceAccess:params.cfg.workspaceAccess,workspaceDir:params.workspaceDir,agentWorkspaceDir:params.agentWorkspaceDir}),now=Date.now(),hasContainer=state.exists,running=state.running,currentHash=null,hashMismatch=!1;if(hasContainer){let registryEntry=(await readBrowserRegistry()).entries.find(entry=>entry.containerName===containerName);if(currentHash=await readDockerContainerLabel(containerName,`builderforce.configHash`),hashMismatch=!currentHash||currentHash!==expectedHash,currentHash||(currentHash=registryEntry?.configHash??null,hashMismatch=!currentHash||currentHash!==expectedHash),hashMismatch){let lastUsedAtMs=registryEntry?.lastUsedAtMs;if(running&&(typeof lastUsedAtMs!=`number`||now-lastUsedAtMs<3e5)){let hint=params.cfg.scope===`session`?`builderforce sandbox recreate --browser --session ${params.scopeKey}`:params.cfg.scope===`agent`?`builderforce sandbox recreate --browser --agent ${resolveSandboxAgentId(params.scopeKey)??`main`}`:`builderforce sandbox recreate --browser --all`;defaultRuntime.log(`Sandbox browser config changed for ${containerName} (recently used). Recreate to apply: ${hint}`)}else await execDocker([`rm`,`-f`,containerName],{allowFailure:!0}),hasContainer=!1,running=!1}}if(hasContainer)running||await execDocker([`start`,containerName]);else{await ensureSandboxBrowserImage(browserImage);let args=buildSandboxCreateArgs({name:containerName,cfg:browserDockerCfg,scopeKey:params.scopeKey,labels:{"builderforce.sandboxBrowser":`1`},configHash:expectedHash}),mainMountSuffix=params.cfg.workspaceAccess===`ro`&¶ms.workspaceDir===params.agentWorkspaceDir?`:ro`:``;if(args.push(`-v`,`${params.workspaceDir}:${params.cfg.docker.workdir}${mainMountSuffix}`),params.cfg.workspaceAccess!==`none`&¶ms.workspaceDir!==params.agentWorkspaceDir){let agentMountSuffix=params.cfg.workspaceAccess===`ro`?`:ro`:``;args.push(`-v`,`${params.agentWorkspaceDir}:${SANDBOX_AGENT_WORKSPACE_MOUNT}${agentMountSuffix}`)}args.push(`-p`,`127.0.0.1::${params.cfg.browser.cdpPort}`),params.cfg.browser.enableNoVnc&&!params.cfg.browser.headless&&args.push(`-p`,`127.0.0.1::${params.cfg.browser.noVncPort}`),args.push(`-e`,`BUILDERFORCE_AGENTS_BROWSER_HEADLESS=${params.cfg.browser.headless?`1`:`0`}`),args.push(`-e`,`BUILDERFORCE_AGENTS_BROWSER_ENABLE_NOVNC=${params.cfg.browser.enableNoVnc?`1`:`0`}`),args.push(`-e`,`BUILDERFORCE_AGENTS_BROWSER_CDP_PORT=${params.cfg.browser.cdpPort}`),args.push(`-e`,`BUILDERFORCE_AGENTS_BROWSER_VNC_PORT=${params.cfg.browser.vncPort}`),args.push(`-e`,`BUILDERFORCE_AGENTS_BROWSER_NOVNC_PORT=${params.cfg.browser.noVncPort}`),args.push(browserImage),await execDocker(args),await execDocker([`start`,containerName])}let mappedCdp=await readDockerPort(containerName,params.cfg.browser.cdpPort);if(!mappedCdp)throw Error(`Failed to resolve CDP port mapping for ${containerName}.`);let mappedNoVnc=params.cfg.browser.enableNoVnc&&!params.cfg.browser.headless?await readDockerPort(containerName,params.cfg.browser.noVncPort):null,existing=BROWSER_BRIDGES.get(params.scopeKey),existingProfile=existing?resolveProfile(existing.bridge.state.resolved,DEFAULT_BUILDERFORCE_AGENTS_BROWSER_PROFILE_NAME):null,desiredAuthToken=params.bridgeAuth?.token?.trim()||void 0,desiredAuthPassword=params.bridgeAuth?.password?.trim()||void 0;!desiredAuthToken&&!desiredAuthPassword&&(desiredAuthToken=existing?.authToken,desiredAuthPassword=existing?.authPassword,!desiredAuthToken&&!desiredAuthPassword&&(desiredAuthToken=crypto.randomBytes(24).toString(`hex`)));let shouldReuse=existing&&existing.containerName===containerName&&existingProfile?.cdpPort===mappedCdp,authMatches=!existing||existing.authToken===desiredAuthToken&&existing.authPassword===desiredAuthPassword;existing&&!shouldReuse&&(await stopBrowserBridgeServer(existing.bridge.server).catch(()=>void 0),BROWSER_BRIDGES.delete(params.scopeKey)),existing&&shouldReuse&&!authMatches&&(await stopBrowserBridgeServer(existing.bridge.server).catch(()=>void 0),BROWSER_BRIDGES.delete(params.scopeKey));let bridge=shouldReuse&&authMatches&&existing?existing.bridge:null,resolvedBridge=await(async()=>{if(bridge)return bridge;let onEnsureAttachTarget=params.cfg.browser.autoStart?async()=>{let state=await dockerContainerState(containerName);if(state.exists&&!state.running&&await execDocker([`start`,containerName]),!await waitForSandboxCdp({cdpPort:mappedCdp,timeoutMs:params.cfg.browser.autoStartTimeoutMs}))throw Error(`Sandbox browser CDP did not become reachable on 127.0.0.1:${mappedCdp} within ${params.cfg.browser.autoStartTimeoutMs}ms.`)}:void 0;return await startBrowserBridgeServer({resolved:buildSandboxBrowserResolvedConfig({controlPort:0,cdpPort:mappedCdp,headless:params.cfg.browser.headless,evaluateEnabled:params.evaluateEnabled??DEFAULT_BROWSER_EVALUATE_ENABLED}),authToken:desiredAuthToken,authPassword:desiredAuthPassword,onEnsureAttachTarget})})();(!shouldReuse||!authMatches)&&BROWSER_BRIDGES.set(params.scopeKey,{bridge:resolvedBridge,containerName,authToken:desiredAuthToken,authPassword:desiredAuthPassword}),await updateBrowserRegistry({containerName,sessionKey:params.scopeKey,createdAtMs:now,lastUsedAtMs:now,image:browserImage,configHash:hashMismatch&&running?currentHash??void 0:expectedHash,cdpPort:mappedCdp,noVncPort:mappedNoVnc??void 0});let noVncUrl=mappedNoVnc&¶ms.cfg.browser.enableNoVnc&&!params.cfg.browser.headless?`http://127.0.0.1:${mappedNoVnc}/vnc.html?autoconnect=1&resize=remote`:void 0;return{bridgeUrl:resolvedBridge.baseUrl,noVncUrl,containerName}}function parseSandboxBindMount(spec){let trimmed=spec.trim();if(!trimmed)return null;let parsed=splitBindSpec(trimmed);if(!parsed)return null;let hostToken=parsed.host.trim(),containerToken=parsed.container.trim();if(!hostToken||!containerToken||!path.posix.isAbsolute(containerToken))return null;let optionsToken=parsed.options.trim().toLowerCase(),writable=!(optionsToken?optionsToken.split(`,`).map(entry=>entry.trim()).filter(Boolean):[]).includes(`ro`);return{hostRoot:path.resolve(hostToken),containerRoot:normalizeContainerPath(containerToken),writable}}function splitBindSpec(spec){let separator=getHostContainerSeparatorIndex(spec);if(separator===-1)return null;let host=spec.slice(0,separator),rest=spec.slice(separator+1),optionsStart=rest.indexOf(`:`);return optionsStart===-1?{host,container:rest,options:``}:{host,container:rest.slice(0,optionsStart),options:rest.slice(optionsStart+1)}}function getHostContainerSeparatorIndex(spec){let hasDriveLetterPrefix=/^[A-Za-z]:[\\/]/.test(spec);for(let i=hasDriveLetterPrefix?2:0;i<spec.length;i+=1)if(spec[i]===`:`)return i;return-1}function buildSandboxFsMounts(sandbox){let mounts=[{hostRoot:path.resolve(sandbox.workspaceDir),containerRoot:normalizeContainerPath(sandbox.containerWorkdir),writable:sandbox.workspaceAccess===`rw`,source:`workspace`}];sandbox.workspaceAccess!==`none`&&path.resolve(sandbox.agentWorkspaceDir)!==path.resolve(sandbox.workspaceDir)&&mounts.push({hostRoot:path.resolve(sandbox.agentWorkspaceDir),containerRoot:SANDBOX_AGENT_WORKSPACE_MOUNT,writable:sandbox.workspaceAccess===`rw`,source:`agent`});for(let bind of sandbox.docker.binds??[]){let parsed=parseSandboxBindMount(bind);parsed&&mounts.push({hostRoot:parsed.hostRoot,containerRoot:parsed.containerRoot,writable:parsed.writable,source:`bind`})}return dedupeMounts(mounts)}function resolveSandboxFsPathWithMounts(params){let mountsByContainer=[...params.mounts].toSorted((a,b)=>b.containerRoot.length-a.containerRoot.length),mountsByHost=[...params.mounts].toSorted((a,b)=>b.hostRoot.length-a.hostRoot.length),input=params.filePath,inputPosix=normalizePosixInput(input);if(path.posix.isAbsolute(inputPosix)){let containerMount=findMountByContainerPath(mountsByContainer,inputPosix);if(containerMount){let rel=path.posix.relative(containerMount.containerRoot,inputPosix);return{hostPath:rel?path.resolve(containerMount.hostRoot,...toHostSegments(rel)):containerMount.hostRoot,containerPath:rel?path.posix.join(containerMount.containerRoot,rel):containerMount.containerRoot,relativePath:toDisplayRelative({containerPath:rel?path.posix.join(containerMount.containerRoot,rel):containerMount.containerRoot,defaultContainerRoot:params.defaultContainerRoot}),writable:containerMount.writable}}}let hostResolved=resolveSandboxInputPath(input,params.cwd),hostMount=findMountByHostPath(mountsByHost,hostResolved);if(hostMount){let relHost=path.relative(hostMount.hostRoot,hostResolved),relPosix=relHost?relHost.split(path.sep).join(path.posix.sep):``,containerPath=relPosix?path.posix.join(hostMount.containerRoot,relPosix):hostMount.containerRoot;return{hostPath:hostResolved,containerPath,relativePath:toDisplayRelative({containerPath,defaultContainerRoot:params.defaultContainerRoot}),writable:hostMount.writable}}throw resolveSandboxPath({filePath:input,cwd:params.cwd,root:params.defaultWorkspaceRoot}),Error(`Path escapes sandbox root (${params.defaultWorkspaceRoot}): ${input}`)}function dedupeMounts(mounts){let seen=new Set,deduped=[];for(let mount of mounts){let key=`${mount.hostRoot}=>${mount.containerRoot}`;seen.has(key)||(seen.add(key),deduped.push(mount))}return deduped}function findMountByContainerPath(mounts,target){for(let mount of mounts)if(isPathInsidePosix(mount.containerRoot,target))return mount;return null}function findMountByHostPath(mounts,target){for(let mount of mounts)if(isPathInsideHost(mount.hostRoot,target))return mount;return null}function isPathInsidePosix(root,target){let rel=path.posix.relative(root,target);return rel?!(rel.startsWith(`..`)||path.posix.isAbsolute(rel)):!0}function isPathInsideHost(root,target){let rel=path.relative(root,target);return rel?!(rel.startsWith(`..`)||path.isAbsolute(rel)):!0}function toHostSegments(relativePosix){return relativePosix.split(`/`).filter(Boolean)}function toDisplayRelative(params){let rel=path.posix.relative(params.defaultContainerRoot,params.containerPath);return rel?!rel.startsWith(`..`)&&!path.posix.isAbsolute(rel)?rel:params.containerPath:``}function normalizeContainerPath(value){let normalized=path.posix.normalize(value);return normalized===`.`?`/`:normalized}function normalizePosixInput(value){return value.replace(/\\/g,`/`).trim()}function createSandboxFsBridge(params){return new SandboxFsBridgeImpl(params.sandbox)}var SandboxFsBridgeImpl=class{constructor(sandbox){this.sandbox=sandbox,this.mounts=buildSandboxFsMounts(sandbox)}resolvePath(params){let target=this.resolveResolvedPath(params);return{hostPath:target.hostPath,relativePath:target.relativePath,containerPath:target.containerPath}}async readFile(params){let target=this.resolveResolvedPath(params);return(await this.runCommand(`set -eu; cat -- "$1"`,{args:[target.containerPath],signal:params.signal})).stdout}async writeFile(params){let target=this.resolveResolvedPath(params);this.ensureWriteAccess(target,`write files`);let buffer=Buffer.isBuffer(params.data)?params.data:Buffer.from(params.data,params.encoding??`utf8`),script=params.mkdir===!1?`set -eu; cat >"$1"`:`set -eu; dir=$(dirname -- "$1"); if [ "$dir" != "." ]; then mkdir -p -- "$dir"; fi; cat >"$1"`;await this.runCommand(script,{args:[target.containerPath],stdin:buffer,signal:params.signal})}async mkdirp(params){let target=this.resolveResolvedPath(params);this.ensureWriteAccess(target,`create directories`),await this.runCommand(`set -eu; mkdir -p -- "$1"`,{args:[target.containerPath],signal:params.signal})}async remove(params){let target=this.resolveResolvedPath(params);this.ensureWriteAccess(target,`remove files`);let flags=[params.force===!1?``:`-f`,params.recursive?`-r`:``].filter(Boolean),rmCommand=flags.length>0?`rm ${flags.join(` `)}`:`rm`;await this.runCommand(`set -eu; ${rmCommand} -- "$1"`,{args:[target.containerPath],signal:params.signal})}async rename(params){let from=this.resolveResolvedPath({filePath:params.from,cwd:params.cwd}),to=this.resolveResolvedPath({filePath:params.to,cwd:params.cwd});this.ensureWriteAccess(from,`rename files`),this.ensureWriteAccess(to,`rename files`),await this.runCommand(`set -eu; dir=$(dirname -- "$2"); if [ "$dir" != "." ]; then mkdir -p -- "$dir"; fi; mv -- "$1" "$2"`,{args:[from.containerPath,to.containerPath],signal:params.signal})}async stat(params){let target=this.resolveResolvedPath(params),result=await this.runCommand(`set -eu; stat -c "%F|%s|%Y" -- "$1"`,{args:[target.containerPath],signal:params.signal,allowFailure:!0});if(result.code!==0){let stderr=result.stderr.toString(`utf8`);if(stderr.includes(`No such file or directory`))return null;let message=stderr.trim()||`stat failed with code ${result.code}`;throw Error(`stat failed for ${target.containerPath}: ${message}`)}let[typeRaw,sizeRaw,mtimeRaw]=result.stdout.toString(`utf8`).trim().split(`|`),size=Number.parseInt(sizeRaw??`0`,10),mtime=Number.parseInt(mtimeRaw??`0`,10)*1e3;return{type:coerceStatType(typeRaw),size:Number.isFinite(size)?size:0,mtimeMs:Number.isFinite(mtime)?mtime:0}}async runCommand(script,options={}){let dockerArgs=[`exec`,`-i`,this.sandbox.containerName,`sh`,`-c`,script,`builderforce-sandbox-fs`];return options.args?.length&&dockerArgs.push(...options.args),execDockerRaw(dockerArgs,{input:options.stdin,allowFailure:options.allowFailure,signal:options.signal})}ensureWriteAccess(target,action){if(!allowsWrites(this.sandbox.workspaceAccess)||!target.writable)throw Error(`Sandbox path is read-only; cannot ${action}: ${target.containerPath}`)}resolveResolvedPath(params){return resolveSandboxFsPathWithMounts({filePath:params.filePath,cwd:params.cwd??this.sandbox.workspaceDir,defaultWorkspaceRoot:this.sandbox.workspaceDir,defaultContainerRoot:this.sandbox.containerWorkdir,mounts:this.mounts})}};function allowsWrites(access){return access===`rw`}function coerceStatType(typeRaw){if(!typeRaw)return`other`;let normalized=typeRaw.trim().toLowerCase();return normalized.includes(`directory`)?`directory`:normalized.includes(`file`)?`file`:`other`}let lastPruneAtMs=0;function shouldPruneSandboxEntry(cfg,now,entry){let idleHours=cfg.prune.idleHours,maxAgeDays=cfg.prune.maxAgeDays;if(idleHours===0&&maxAgeDays===0)return!1;let idleMs=now-entry.lastUsedAtMs,ageMs=now-entry.createdAtMs;return idleHours>0&&idleMs>idleHours*60*60*1e3||maxAgeDays>0&&ageMs>maxAgeDays*24*60*60*1e3}async function pruneSandboxRegistryEntries(params){let now=Date.now();if(params.cfg.prune.idleHours===0&¶ms.cfg.prune.maxAgeDays===0)return;let registry=await params.read();for(let entry of registry.entries)if(shouldPruneSandboxEntry(params.cfg,now,entry))try{await execDocker([`rm`,`-f`,entry.containerName],{allowFailure:!0})}catch{}finally{await params.remove(entry.containerName),await params.onRemoved?.(entry)}}async function pruneSandboxContainers(cfg){await pruneSandboxRegistryEntries({cfg,read:readRegistry,remove:removeRegistryEntry})}async function pruneSandboxBrowsers(cfg){await pruneSandboxRegistryEntries({cfg,read:readBrowserRegistry,remove:removeBrowserRegistryEntry,onRemoved:async entry=>{let bridge=BROWSER_BRIDGES.get(entry.sessionKey);bridge?.containerName===entry.containerName&&(await stopBrowserBridgeServer(bridge.bridge.server).catch(()=>void 0),BROWSER_BRIDGES.delete(entry.sessionKey))}})}async function maybePruneSandboxes(cfg){let now=Date.now();if(!(now-lastPruneAtMs<300*1e3)){lastPruneAtMs=now;try{await pruneSandboxContainers(cfg),await pruneSandboxBrowsers(cfg)}catch(error){let message=error instanceof Error?error.message:typeof error==`string`?error:JSON.stringify(error);defaultRuntime.error?.(`Sandbox prune failed: ${message??`unknown error`}`)}}}function shouldSandboxSession(cfg,sessionKey,mainSessionKey){return cfg.mode===`off`?!1:cfg.mode===`all`?!0:sessionKey.trim()!==mainSessionKey.trim()}function resolveMainSessionKeyForSandbox(params){return params.cfg?.session?.scope===`global`?`global`:resolveAgentMainSessionKey({cfg:params.cfg,agentId:params.agentId})}function resolveComparableSessionKeyForSandbox(params){return canonicalizeMainSessionAlias({cfg:params.cfg,agentId:params.agentId,sessionKey:params.sessionKey})}function resolveSandboxRuntimeStatus(params){let sessionKey=params.sessionKey?.trim()??``,agentId=resolveSessionAgentId({sessionKey,config:params.cfg}),cfg=params.cfg,sandboxCfg=resolveSandboxConfigForAgent(cfg,agentId),mainSessionKey=resolveMainSessionKeyForSandbox({cfg,agentId}),sandboxed=sessionKey?shouldSandboxSession(sandboxCfg,resolveComparableSessionKeyForSandbox({cfg,agentId,sessionKey}),mainSessionKey):!1;return{agentId,sessionKey,mainSessionKey,mode:sandboxCfg.mode,sandboxed,toolPolicy:resolveSandboxToolPolicyForAgent(cfg,agentId)}}function formatSandboxToolPolicyBlockedMessage(params){let tool=params.toolName.trim().toLowerCase();if(!tool)return;let runtime=resolveSandboxRuntimeStatus({cfg:params.cfg,sessionKey:params.sessionKey});if(!runtime.sandboxed)return;let deny=new Set(expandToolGroups(runtime.toolPolicy.deny)),allow=expandToolGroups(runtime.toolPolicy.allow),allowSet=allow.length>0?new Set(allow):null,blockedByDeny=deny.has(tool),blockedByAllow=allowSet?!allowSet.has(tool):!1;if(!blockedByDeny&&!blockedByAllow)return;let reasons=[],fixes=[];blockedByDeny&&(reasons.push(`deny list`),fixes.push(`Remove "${tool}" from ${runtime.toolPolicy.sources.deny.key}.`)),blockedByAllow&&(reasons.push(`allow list`),fixes.push(`Add "${tool}" to ${runtime.toolPolicy.sources.allow.key} (or set it to [] to allow all).`));let lines=[];lines.push(`Tool "${tool}" blocked by sandbox tool policy (mode=${runtime.mode}).`),lines.push(`Session: ${runtime.sessionKey||`(unknown)`}`),lines.push(`Reason: ${reasons.join(` + `)}`),lines.push(`Fix:`),lines.push(`- agents.defaults.sandbox.mode=off (disable sandbox)`);for(let fix of fixes)lines.push(`- ${fix}`);return runtime.mode===`non-main`&&lines.push(`- Use main session key (direct): ${runtime.mainSessionKey}`),lines.push(`- See: ${formatCliCommand(`builderforce sandbox explain --session ${runtime.sessionKey}`)}`),lines.join(`
|
|
2
2
|
`)}async function ensureSandboxWorkspace(workspaceDir,seedFrom,skipBootstrap){if(await fs$1.mkdir(workspaceDir,{recursive:!0}),seedFrom){let seed=resolveUserPath(seedFrom),files=[DEFAULT_AGENTS_FILENAME,DEFAULT_SOUL_FILENAME,DEFAULT_TOOLS_FILENAME,DEFAULT_IDENTITY_FILENAME,DEFAULT_USER_FILENAME,DEFAULT_BOOTSTRAP_FILENAME,DEFAULT_HEARTBEAT_FILENAME];for(let name of files){let src=path.join(seed,name),dest=path.join(workspaceDir,name);try{await fs$1.access(dest)}catch{try{let content=await fs$1.readFile(src,`utf-8`);await fs$1.writeFile(dest,content,{encoding:`utf-8`,flag:`wx`})}catch{}}}}await ensureAgentWorkspace({dir:workspaceDir,ensureBootstrapFiles:!skipBootstrap})}async function ensureSandboxWorkspaceLayout(params){let{cfg,rawSessionKey}=params,agentWorkspaceDir=resolveUserPath(params.workspaceDir?.trim()||DEFAULT_AGENT_WORKSPACE_DIR),workspaceRoot=resolveUserPath(cfg.workspaceRoot),scopeKey=resolveSandboxScopeKey(cfg.scope,rawSessionKey),sandboxWorkspaceDir=cfg.scope===`shared`?workspaceRoot:resolveSandboxWorkspaceDir(workspaceRoot,scopeKey),workspaceDir=cfg.workspaceAccess===`rw`?agentWorkspaceDir:sandboxWorkspaceDir;if(workspaceDir===sandboxWorkspaceDir){if(await ensureSandboxWorkspace(sandboxWorkspaceDir,agentWorkspaceDir,params.config?.agents?.defaults?.skipBootstrap),cfg.workspaceAccess!==`rw`)try{await syncSkillsToWorkspace({sourceWorkspaceDir:agentWorkspaceDir,targetWorkspaceDir:sandboxWorkspaceDir,config:params.config})}catch(error){let message=error instanceof Error?error.message:JSON.stringify(error);defaultRuntime.error?.(`Sandbox skill sync failed: ${message}`)}}else await fs$1.mkdir(workspaceDir,{recursive:!0});return{agentWorkspaceDir,scopeKey,sandboxWorkspaceDir,workspaceDir}}function resolveSandboxSession(params){let rawSessionKey=params.sessionKey?.trim();if(!rawSessionKey)return null;let runtime=resolveSandboxRuntimeStatus({cfg:params.config,sessionKey:rawSessionKey});return runtime.sandboxed?{rawSessionKey,runtime,cfg:resolveSandboxConfigForAgent(params.config,runtime.agentId)}:null}async function resolveSandboxContext(params){let resolved=resolveSandboxSession(params);if(!resolved)return null;let{rawSessionKey,cfg}=resolved;await maybePruneSandboxes(cfg);let{agentWorkspaceDir,scopeKey,workspaceDir}=await ensureSandboxWorkspaceLayout({cfg,rawSessionKey,config:params.config,workspaceDir:params.workspaceDir}),containerName=await ensureSandboxContainer({sessionKey:rawSessionKey,workspaceDir,agentWorkspaceDir,cfg}),browser=await ensureSandboxBrowser({scopeKey,workspaceDir,agentWorkspaceDir,cfg,evaluateEnabled:params.config?.browser?.evaluateEnabled??DEFAULT_BROWSER_EVALUATE_ENABLED,bridgeAuth:cfg.browser.enabled?await(async()=>{let cfgForAuth=params.config??loadConfig(),browserAuth=resolveBrowserControlAuth(cfgForAuth);try{browserAuth=(await ensureBrowserControlAuth({cfg:cfgForAuth})).auth}catch(error){let message=error instanceof Error?error.message:JSON.stringify(error);defaultRuntime.error?.(`Sandbox browser auth ensure failed: ${message}`)}return browserAuth})():void 0}),sandboxContext={enabled:!0,sessionKey:rawSessionKey,workspaceDir,agentWorkspaceDir,workspaceAccess:cfg.workspaceAccess,containerName,containerWorkdir:cfg.docker.workdir,docker:cfg.docker,tools:cfg.tools,browserAllowHostControl:cfg.browser.allowHostControl,browser:browser??void 0};return sandboxContext.fsBridge=createSandboxFsBridge({sandbox:sandboxContext}),sandboxContext}async function ensureSandboxWorkspaceForSession(params){let resolved=resolveSandboxSession(params);if(!resolved)return null;let{rawSessionKey,cfg}=resolved,{workspaceDir}=await ensureSandboxWorkspaceLayout({cfg,rawSessionKey,config:params.config,workspaceDir:params.workspaceDir});return{workspaceDir,containerWorkdir:cfg.docker.workdir}}async function listSandboxRegistryItems(params){let registry=await params.read(),results=[];for(let entry of registry.entries){let state=await dockerContainerState(entry.containerName),actualImage=entry.image;if(state.exists)try{let result=await execDocker([`inspect`,`-f`,`{{.Config.Image}}`,entry.containerName],{allowFailure:!0});result.code===0&&(actualImage=result.stdout.trim())}catch{}let agentId=resolveSandboxAgentId(entry.sessionKey),configuredImage=params.resolveConfiguredImage(agentId);results.push({...entry,image:actualImage,running:state.running,imageMatch:actualImage===configuredImage})}return results}async function listSandboxContainers(){let config=loadConfig();return listSandboxRegistryItems({read:readRegistry,resolveConfiguredImage:agentId=>resolveSandboxConfigForAgent(config,agentId).docker.image})}async function listSandboxBrowsers(){let config=loadConfig();return listSandboxRegistryItems({read:readBrowserRegistry,resolveConfiguredImage:agentId=>resolveSandboxConfigForAgent(config,agentId).browser.image})}async function removeSandboxContainer(containerName){try{await execDocker([`rm`,`-f`,containerName],{allowFailure:!0})}catch{}await removeRegistryEntry(containerName)}async function removeSandboxBrowserContainer(containerName){try{await execDocker([`rm`,`-f`,containerName],{allowFailure:!0})}catch{}await removeBrowserRegistryEntry(containerName);for(let[sessionKey,bridge]of BROWSER_BRIDGES.entries())bridge.containerName===containerName&&(await stopBrowserBridgeServer(bridge.bridge.server).catch(()=>void 0),BROWSER_BRIDGES.delete(sessionKey))}export{compileGlobPatterns as C,DEFAULT_SANDBOX_IMAGE as D,DEFAULT_SANDBOX_COMMON_IMAGE as E,stripPluginOnlyAllowlist as S,DEFAULT_SANDBOX_BROWSER_IMAGE as T,expandPolicyWithPluginGroups as _,ensureSandboxWorkspaceForSession as a,normalizeToolName as b,resolveSandboxRuntimeStatus as c,resolveSandboxConfigForAgent as d,resolveSandboxScope as f,collectExplicitAllowlist as g,buildPluginToolGroups as h,removeSandboxContainer as i,getBlockedBindReason as l,applyOwnerOnlyToolPolicy as m,listSandboxContainers as n,resolveSandboxContext as o,resolveSandboxToolPolicyForAgent as p,removeSandboxBrowserContainer as r,formatSandboxToolPolicyBlockedMessage as s,listSandboxBrowsers as t,getBridgeAuthForPort as u,expandToolGroups as v,matchesAnyGlobPattern as w,resolveToolProfilePolicy as x,mergeAlsoAllowPolicy as y};
|