@seanhogg/builderforce-agents 2026.10.9 → 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/{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-BmrsVdFw.js → builderforce-B9187Tm9.js} +4 -4
- package/dist/{builderforce-Bwyw0GJ6.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-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-COUcUWby.js → command-registry-B7uAoROP.js} +1 -1
- package/dist/{command-registry-4_K-lfW5.js → command-registry-CW16Mk2Y.js} +1 -1
- package/dist/{completion-cli-DlvHqL86.js → completion-cli-ZvXrCQqk.js} +1 -1
- package/dist/{completion-cli-B2qcVd6q.js → completion-cli-gyvx5ZXu.js} +1 -1
- package/dist/{completion-cli-DpFvU4Qn.js → completion-cli-n8UsdT91.js} +1 -1
- package/dist/{completion-cli-SdcQ-kQj.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-BSotFS6p.js → doctor-completion-94zme499.js} +1 -1
- package/dist/{doctor-completion-DVxbs-74.js → doctor-completion-CbF34DIH.js} +1 -1
- 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/{gateway-cli-D2Bg1Um6.js → gateway-cli-CKcoLVMA.js} +5 -5
- package/dist/{gateway-cli-DFEo8C0z.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-DfMVh1bM.js → onboard-BItclJp0.js} +1 -1
- package/dist/{onboard-BVmZ4jMw.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-DYJttZ2w.js → onboard-interactive-Cl2K3EYn.js} +1 -1
- package/dist/{onboard-interactive-zgjmwJz-.js → onboard-interactive-JNux9zfA.js} +1 -1
- package/dist/{onboard-interactive-B3-KBZbZ.js → onboard-interactive-J_ObFzeW.js} +1 -1
- package/dist/{onboard-interactive-Dc_7URYb.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-D4-HDbmU.js → onboarding-BSENgR9C.js} +5 -5
- package/dist/{onboarding-CP9rrz8y.js → onboarding-CIaZLNc1.js} +5 -5
- package/dist/{onboarding.finalize-C2kZi7F0.js → onboarding.finalize-BwOpvoPE.js} +1 -1
- package/dist/{onboarding.finalize-BfWXPgX7.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/{accounts-Cy3WCbWg.js → accounts-BwreSNAR.js} +1 -1
- package/dist/plugin-sdk/{active-listener-DVWVNlT9.js → active-listener-DpQ7aGYd.js} +1 -1
- package/dist/plugin-sdk/agent-runtime/src/infra/workflow-telemetry.d.ts +12 -1
- package/dist/plugin-sdk/{agent-scope-DgKN27hJ.js → agent-scope-BQByW0cD.js} +1 -1
- package/dist/plugin-sdk/{api-key-rotation-ftXf7mBZ.js → api-key-rotation-7YdImWrh.js} +1 -1
- package/dist/plugin-sdk/{audio-preflight-CfTmmeS-.js → audio-preflight-EbkaATDO.js} +1 -1
- package/dist/plugin-sdk/{auth-json-BrNBg87n.js → auth-json-DK6qod1_.js} +1 -1
- package/dist/plugin-sdk/{bindings-CH-YLOLC.js → bindings-CDEzl4kl.js} +1 -1
- package/dist/plugin-sdk/{channel-web-B6rg0Rbf.js → channel-web-D2KuONp0.js} +1 -1
- package/dist/plugin-sdk/{chrome-CuXP-hes.js → chrome-SOXFIkUM.js} +1 -1
- package/dist/plugin-sdk/{chunk-C94IAOuf.js → chunk-cW0POl22.js} +1 -1
- package/dist/plugin-sdk/{command-format-B3XMq_73.js → command-format-CAX9XFjI.js} +1 -1
- package/dist/plugin-sdk/{common-n0l_XN-S.js → common-BxEWhN2X.js} +1 -1
- package/dist/plugin-sdk/{config-DsXZsCkJ.js → config-v1EU9Ll8.js} +2 -2
- package/dist/plugin-sdk/{fetch-B-GxSYRO.js → fetch-DH0Y8iyO.js} +1 -1
- package/dist/plugin-sdk/index.js +1 -1
- package/dist/plugin-sdk/{login-_my8QwPP.js → login-d1zBgykF.js} +1 -1
- package/dist/plugin-sdk/{login-qr-BaePtXuG.js → login-qr-B6exvQnN.js} +1 -1
- package/dist/plugin-sdk/{manager-BsC-4ymy.js → manager-BH_bmGds.js} +1 -1
- package/dist/plugin-sdk/{markdown-tables-BUfhHgfs.js → markdown-tables-Epim9b-0.js} +1 -1
- package/dist/plugin-sdk/{message-channel-CuZ2xOAM.js → message-channel-sBPQc_-T.js} +1 -1
- package/dist/plugin-sdk/{model-catalog-yuiXVcmw.js → model-catalog-cXsza5GU.js} +1 -1
- package/dist/plugin-sdk/{model-selection-BtgvnqB5.js → model-selection-K82MAGlL.js} +1 -1
- package/dist/plugin-sdk/{outbound-D_attiyO.js → outbound-Chn_H1O7.js} +1 -1
- package/dist/plugin-sdk/{plugins-BdkC9v5E.js → plugins-CaUOZBVb.js} +1 -1
- package/dist/plugin-sdk/{pw-ai-A7Rathx6.js → pw-ai-BIiJF7ZD.js} +1 -1
- package/dist/plugin-sdk/{qmd-manager-Dxn0jCpE.js → qmd-manager-BRe5fGZw.js} +1 -1
- package/dist/plugin-sdk/{registry-CZHRcH-q.js → registry-DJq2Cvo9.js} +1 -1
- package/dist/plugin-sdk/{render-CuA_WRX5.js → render-BUCRXPIk.js} +1 -1
- package/dist/plugin-sdk/{replies-DmLfO-pg.js → replies-Cz5OD3qN.js} +1 -1
- package/dist/plugin-sdk/{reply-3-ne-N_7.js → reply-D5Uk7pUv.js} +9 -9
- package/dist/plugin-sdk/{reply-prefix-w7kAvH11.js → reply-prefix-CCymsmsP.js} +1 -1
- package/dist/plugin-sdk/{resolve-route-0sbvl4ZN.js → resolve-route-DN1J7Wyc.js} +1 -1
- package/dist/plugin-sdk/{runner-4UfrAQnx.js → runner-CYkuO7Fh.js} +4 -4
- package/dist/plugin-sdk/{session-BB-yfDWx.js → session-D5jHDo78.js} +1 -1
- package/dist/plugin-sdk/{sqlite-JjFgDV-H.js → sqlite-BlMLqMl8.js} +1 -1
- package/dist/plugin-sdk/{subsystem-D0Ril4rt.js → subsystem-COTa5Ly_.js} +1 -1
- package/dist/plugin-sdk/{tool-images-WRTP95FT.js → tool-images-DSpchb4x.js} +1 -1
- package/dist/plugin-sdk/{tool-loop-detection-sC_rhJfb.js → tool-loop-detection-BP6u-mbh.js} +1 -1
- package/dist/plugin-sdk/web-BbganhKi.js +1 -0
- package/dist/plugin-sdk/{whatsapp-actions-ThxQ5niy.js → whatsapp-actions-CZUqxmP1.js} +1 -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-BCwL3wlM.js → program-context-ClBa4lUj.js} +1 -1
- package/dist/{program-2w7Ue902.js → program-vVCzU0cH.js} +2 -2
- package/dist/{prompt-select-styled-hB_nLOn1.js → prompt-select-styled-BJPGccTJ.js} +1 -1
- package/dist/{prompt-select-styled-Dd5swW2b.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/{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-BELfCO_C.js → register.maintenance-C6ocMld2.js} +1 -1
- package/dist/{register.maintenance-DukWFS_D.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-B9DMNfHE.js → register.onboard-B34211N6.js} +1 -1
- package/dist/{register.onboard-Dt7rzAq-.js → register.onboard-S1d2WAE4.js} +1 -1
- package/dist/{register.setup-CSF-2ImP.js → register.setup-CJPyAwCQ.js} +1 -1
- package/dist/{register.setup-BRRVPrx7.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-4eDV9jKH.js → register.subclis-C9V_M-Lk.js} +1 -1
- package/dist/{register.subclis-Cr9DoYcv.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-DLcDEJgv.js → run-main-DQMbgbcF.js} +1 -1
- 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-DylWbrDx.js → tui-DnVRxfI8.js} +2 -2
- package/dist/{tui-BwWMByVp.js → tui-JfWoLGIV.js} +2 -2
- package/dist/{tui-cli-C_TTgabr.js → tui-cli-CGjg2Eb5.js} +1 -1
- package/dist/{tui-cli-Bh1V8-w9.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-DUrUIrYQ.js → update-cli-CfJJcSUS.js} +1 -1
- package/dist/{update-cli-CA3LuuJ7.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-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-Dq6VUSKZ.js +0 -24
- package/dist/builderforce-onboarding-DuUfZ6oL.js +0 -24
- 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/plugin-sdk/web-CThgoHQp.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{g as resolveStateDir,m as resolveOAuthDir,o as resolveConfigPath}from"./paths-5FcIFMsj.js";import{d as normalizeAgentId}from"./session-key-EoB0qaG9.js";import{n as runExec}from"./exec-DdcIjeyn.js";import{l as resolveDefaultAgentId}from"./agent-scope-DPtjOxzp.js";import{t as formatCliCommand}from"./command-format-D806O2pt.js";import{F as INCLUDE_KEY,I as MAX_INCLUDE_DEPTH,L as extensionUsesSkippedScannerPath,R as isPathInside,n as createConfigIO}from"./io-3R_ZyUxB.js";import{c as normalizePluginsConfig}from"./manifest-registry-BJCfNV1a.js";import{n as MANIFEST_KEY,t as LEGACY_MANIFEST_KEYS}from"./legacy-names-BXbHg7Rs.js";import{d as resolveSandboxConfigForAgent,l as getBlockedBindReason,p as resolveSandboxToolPolicyForAgent,x as resolveToolProfilePolicy}from"./sandbox-BZibn6PX.js";import{i as resolveGatewayAuth}from"./auth-lebUHrkd.js";import{a as resolveProfile,i as resolveBrowserConfig,m as resolveBrowserControlAuth}from"./server-context-DJZT7Upf.js";import{i as loadWorkspaceSkillEntries}from"./skills-Ba4ftrB-.js";import{n as formatErrorMessage}from"./errors-B1MIg3g-.js";import{et as normalizeStringEntries}from"./sessions-CdanN_ZI.js";import{h as GATEWAY_CLIENT_NAMES,m as GATEWAY_CLIENT_MODES}from"./message-channel-D_jXxXQj.js";import{n as listChannelPlugins}from"./plugins-D5zP6ENo.js";import{t as GatewayClient}from"./client-xfoidwPI.js";import{t as buildGatewayConnectionDetails}from"./call-BbRf8gFM.js";import{i as readChannelAllowFromStore}from"./pairing-store-CbvMJhD3.js";import{c as resolveNativeCommandsEnabled,l as resolveNativeSkillsEnabled,n as isToolAllowedByPolicies,o as pickSandboxToolPolicy,u as listAgentWorkspaceDirs}from"./coding-tools.policy-6qh9acJy.js";import{n as DEFAULT_GATEWAY_HTTP_TOOL_DENY}from"./dangerous-tools-DROxC992.js";import{t as resolveChannelDefaultAccountId}from"./helpers-DTDCy17p.js";import{t as scanDirectoryWithSummary}from"./skill-scanner-U3AJgjqc.js";import{n as isNumericTelegramUserId,r as normalizeTelegramAllowFromEntry,t as resolveDmAllowState}from"./dm-policy-shared-Dhw9_6mi.js";import{t as inferParamBFromIdOrName}from"./model-param-b-347pru8e.js";import os from"node:os";import path from"node:path";import{randomUUID}from"node:crypto";import JSON5 from"json5";import*as fs$1 from"node:fs/promises";import fs from"node:fs/promises";async function probeGateway(opts){let startedAt=Date.now(),instanceId=randomUUID(),connectLatencyMs=null,connectError=null,close=null;return await new Promise(resolve=>{let settled=!1,settle=result=>{settled||(settled=!0,clearTimeout(timer),client.stop(),resolve({url:opts.url,...result}))},client=new GatewayClient({url:opts.url,token:opts.auth?.token,password:opts.auth?.password,clientName:GATEWAY_CLIENT_NAMES.CLI,clientVersion:`dev`,mode:GATEWAY_CLIENT_MODES.PROBE,instanceId,onConnectError:err=>{connectError=formatErrorMessage(err)},onClose:(code,reason)=>{close={code,reason}},onHelloOk:async()=>{connectLatencyMs=Date.now()-startedAt;try{let[health,status,presence,configSnapshot]=await Promise.all([client.request(`health`),client.request(`status`),client.request(`system-presence`),client.request(`config.get`,{})]);settle({ok:!0,connectLatencyMs,error:null,close,health,status,presence:Array.isArray(presence)?presence:null,configSnapshot})}catch(err){settle({ok:!1,connectLatencyMs,error:formatErrorMessage(err),close,health:null,status:null,presence:null,configSnapshot:null})}}}),timer=setTimeout(()=>{settle({ok:!1,connectLatencyMs,error:connectError?`connect failed: ${connectError}`:`timeout`,close,health:null,status:null,presence:null,configSnapshot:null})},Math.max(250,opts.timeoutMs));client.start()})}const CANVAS_COMMANDS=[`canvas.present`,`canvas.hide`,`canvas.navigate`,`canvas.eval`,`canvas.snapshot`,`canvas.a2ui.push`,`canvas.a2ui.pushJSONL`,`canvas.a2ui.reset`],CAMERA_COMMANDS=[`camera.list`],CAMERA_DANGEROUS_COMMANDS=[`camera.snap`,`camera.clip`],SCREEN_DANGEROUS_COMMANDS=[`screen.record`],LOCATION_COMMANDS=[`location.get`],DEVICE_COMMANDS=[`device.info`,`device.status`],CONTACTS_COMMANDS=[`contacts.search`],CONTACTS_DANGEROUS_COMMANDS=[`contacts.add`],CALENDAR_COMMANDS=[`calendar.events`],CALENDAR_DANGEROUS_COMMANDS=[`calendar.add`],REMINDERS_COMMANDS=[`reminders.list`],REMINDERS_DANGEROUS_COMMANDS=[`reminders.add`],PHOTOS_COMMANDS=[`photos.latest`],MOTION_COMMANDS=[`motion.activity`,`motion.pedometer`],SMS_DANGEROUS_COMMANDS=[`sms.send`],IOS_SYSTEM_COMMANDS=[`system.notify`],SYSTEM_COMMANDS=[`system.run`,`system.which`,`system.notify`,`browser.proxy`];[...CAMERA_DANGEROUS_COMMANDS,...SCREEN_DANGEROUS_COMMANDS,...CONTACTS_DANGEROUS_COMMANDS,...CALENDAR_DANGEROUS_COMMANDS,...REMINDERS_DANGEROUS_COMMANDS,...SMS_DANGEROUS_COMMANDS];const PLATFORM_DEFAULTS={ios:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...DEVICE_COMMANDS,...CONTACTS_COMMANDS,...CALENDAR_COMMANDS,...REMINDERS_COMMANDS,...PHOTOS_COMMANDS,...MOTION_COMMANDS,...IOS_SYSTEM_COMMANDS],android:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...DEVICE_COMMANDS,...CONTACTS_COMMANDS,...CALENDAR_COMMANDS,...REMINDERS_COMMANDS,...PHOTOS_COMMANDS,...MOTION_COMMANDS],macos:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...DEVICE_COMMANDS,...CONTACTS_COMMANDS,...CALENDAR_COMMANDS,...REMINDERS_COMMANDS,...PHOTOS_COMMANDS,...MOTION_COMMANDS,...SYSTEM_COMMANDS],linux:[...SYSTEM_COMMANDS],windows:[...SYSTEM_COMMANDS],unknown:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...SYSTEM_COMMANDS]};function normalizePlatformId(platform,deviceFamily){let raw=(platform??``).trim().toLowerCase();if(raw.startsWith(`ios`))return`ios`;if(raw.startsWith(`android`))return`android`;if(raw.startsWith(`mac`)||raw.startsWith(`darwin`))return`macos`;if(raw.startsWith(`win`))return`windows`;if(raw.startsWith(`linux`))return`linux`;let family=(deviceFamily??``).trim().toLowerCase();return family.includes(`iphone`)||family.includes(`ipad`)||family.includes(`ios`)?`ios`:family.includes(`android`)?`android`:family.includes(`mac`)?`macos`:family.includes(`windows`)?`windows`:family.includes(`linux`)?`linux`:`unknown`}function resolveNodeCommandAllowlist(cfg,node){let base=PLATFORM_DEFAULTS[normalizePlatformId(node?.platform,node?.deviceFamily)]??PLATFORM_DEFAULTS.unknown,extra=cfg.gateway?.nodes?.allowCommands??[],deny=new Set(cfg.gateway?.nodes?.denyCommands??[]),allow=new Set([...base,...extra].map(cmd=>cmd.trim()).filter(Boolean));for(let blocked of deny){let trimmed=blocked.trim();trimmed&&allow.delete(trimmed)}return allow}function isNodeCommandAllowed(params){let command=params.command.trim();if(!command)return{ok:!1,reason:`command required`};if(!params.allowlist.has(command))return{ok:!1,reason:`command not allowlisted`};if(Array.isArray(params.declaredCommands)&¶ms.declaredCommands.length>0){if(!params.declaredCommands.includes(command))return{ok:!1,reason:`command not declared by node`}}else return{ok:!1,reason:`node did not declare commands`};return{ok:!0}}function resolveGatewayProbeAuth(params){let env=params.env??process.env,authToken=params.cfg.gateway?.auth?.token,authPassword=params.cfg.gateway?.auth?.password,remote=params.cfg.gateway?.remote;return{token:params.mode===`remote`?typeof remote?.token==`string`&&remote.token.trim()?remote.token.trim():void 0:env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN?.trim()||(typeof authToken==`string`&&authToken.trim()?authToken.trim():void 0),password:env.BUILDERFORCE_AGENTS_GATEWAY_PASSWORD?.trim()||(params.mode===`remote`?typeof remote?.password==`string`&&remote.password.trim()?remote.password.trim():void 0:typeof authPassword==`string`&&authPassword.trim()?authPassword.trim():void 0)}}function normalizeAllowFromList$1(list){return normalizeStringEntries(Array.isArray(list)?list:void 0)}function classifyChannelWarningSeverity(message){let s=message.toLowerCase();return s.includes(`dms: open`)||s.includes(`grouppolicy="open"`)||s.includes(`dmpolicy="open"`)||s.includes(`allows any`)||s.includes(`anyone can dm`)||s.includes(`public`)?`critical`:s.includes(`locked`)||s.includes(`disabled`)?`info`:`warn`}async function collectChannelSecurityFindings(params){let findings=[],coerceNativeSetting=value=>{if(value===!0)return!0;if(value===!1)return!1;if(value===`auto`)return`auto`},warnDmPolicy=async input=>{let policyPath=input.policyPath??`${input.allowFromPath}policy`,{hasWildcard,isMultiUserDm}=await resolveDmAllowState({provider:input.provider,allowFrom:input.allowFrom,normalizeEntry:input.normalizeEntry}),dmScope=params.cfg.session?.dmScope??`main`;if(input.dmPolicy===`open`){let allowFromKey=`${input.allowFromPath}allowFrom`;findings.push({checkId:`channels.${input.provider}.dm.open`,severity:`critical`,title:`${input.label} DMs are open`,detail:`${policyPath}="open" allows anyone to DM the bot.`,remediation:`Use pairing/allowlist; if you really need open DMs, ensure ${allowFromKey} includes "*".`}),hasWildcard||findings.push({checkId:`channels.${input.provider}.dm.open_invalid`,severity:`warn`,title:`${input.label} DM config looks inconsistent`,detail:`"open" requires ${allowFromKey} to include "*".`})}if(input.dmPolicy===`disabled`){findings.push({checkId:`channels.${input.provider}.dm.disabled`,severity:`info`,title:`${input.label} DMs are disabled`,detail:`${policyPath}="disabled" ignores inbound DMs.`});return}dmScope===`main`&&isMultiUserDm&&findings.push({checkId:`channels.${input.provider}.dm.scope_main_multiuser`,severity:`warn`,title:`${input.label} DMs share the main session`,detail:`Multiple DM senders currently share the main session, which can leak context across users.`,remediation:`Run: `+formatCliCommand(`builderforce config set session.dmScope "per-channel-peer"`)+` (or "per-account-channel-peer" for multi-account channels) to isolate DM sessions per sender.`})};for(let plugin of params.plugins){if(!plugin.security)continue;let accountIds=plugin.config.listAccountIds(params.cfg),defaultAccountId=resolveChannelDefaultAccountId({plugin,cfg:params.cfg,accountIds}),account=plugin.config.resolveAccount(params.cfg,defaultAccountId);if(!(!plugin.config.isEnabled||plugin.config.isEnabled(account,params.cfg))||!(!plugin.config.isConfigured||await plugin.config.isConfigured(account,params.cfg)))continue;if(plugin.id===`discord`){let discordCfg=account?.config??{},nativeEnabled=resolveNativeCommandsEnabled({providerId:`discord`,providerSetting:coerceNativeSetting(discordCfg.commands?.native),globalSetting:params.cfg.commands?.native}),nativeSkillsEnabled=resolveNativeSkillsEnabled({providerId:`discord`,providerSetting:coerceNativeSetting(discordCfg.commands?.nativeSkills),globalSetting:params.cfg.commands?.nativeSkills});if(nativeEnabled||nativeSkillsEnabled){let defaultGroupPolicy=params.cfg.channels?.defaults?.groupPolicy,groupPolicy=discordCfg.groupPolicy??defaultGroupPolicy??`allowlist`,guildEntries=discordCfg.guilds??{},guildsConfigured=Object.keys(guildEntries).length>0,hasAnyUserAllowlist=Object.values(guildEntries).some(guild=>{if(!guild||typeof guild!=`object`)return!1;let g=guild;if(Array.isArray(g.users)&&g.users.length>0)return!0;let channels=g.channels;return!channels||typeof channels!=`object`?!1:Object.values(channels).some(channel=>{if(!channel||typeof channel!=`object`)return!1;let c=channel;return Array.isArray(c.users)&&c.users.length>0})}),dmAllowFromRaw=discordCfg.dm?.allowFrom,dmAllowFrom=Array.isArray(dmAllowFromRaw)?dmAllowFromRaw:[],storeAllowFrom=await readChannelAllowFromStore(`discord`).catch(()=>[]),ownerAllowFromConfigured=normalizeAllowFromList$1([...dmAllowFrom,...storeAllowFrom]).length>0,useAccessGroups=params.cfg.commands?.useAccessGroups!==!1;!useAccessGroups&&groupPolicy!==`disabled`&&guildsConfigured&&!hasAnyUserAllowlist?findings.push({checkId:`channels.discord.commands.native.unrestricted`,severity:`critical`,title:`Discord slash commands are unrestricted`,detail:`commands.useAccessGroups=false disables sender allowlists for Discord slash commands unless a per-guild/channel users allowlist is configured; with no users allowlist, any user in allowed guild channels can invoke /… commands.`,remediation:`Set commands.useAccessGroups=true (recommended), or configure channels.discord.guilds.<id>.users (or channels.discord.guilds.<id>.channels.<channel>.users).`}):useAccessGroups&&groupPolicy!==`disabled`&&guildsConfigured&&!ownerAllowFromConfigured&&!hasAnyUserAllowlist&&findings.push({checkId:`channels.discord.commands.native.no_allowlists`,severity:`warn`,title:`Discord slash commands have no allowlists`,detail:`Discord slash commands are enabled, but neither an owner allowFrom list nor any per-guild/channel users allowlist is configured; /… commands will be rejected for everyone.`,remediation:`Add your user id to channels.discord.allowFrom (or approve yourself via pairing), or configure channels.discord.guilds.<id>.users.`})}}if(plugin.id===`slack`){let slackCfg=account?.config??{},nativeEnabled=resolveNativeCommandsEnabled({providerId:`slack`,providerSetting:coerceNativeSetting(slackCfg.commands?.native),globalSetting:params.cfg.commands?.native}),nativeSkillsEnabled=resolveNativeSkillsEnabled({providerId:`slack`,providerSetting:coerceNativeSetting(slackCfg.commands?.nativeSkills),globalSetting:params.cfg.commands?.nativeSkills});if(nativeEnabled||nativeSkillsEnabled||slackCfg.slashCommand?.enabled===!0)if(params.cfg.commands?.useAccessGroups===!1)findings.push({checkId:`channels.slack.commands.slash.useAccessGroups_off`,severity:`critical`,title:`Slack slash commands bypass access groups`,detail:`Slack slash/native commands are enabled while commands.useAccessGroups=false; this can allow unrestricted /… command execution from channels/users you didn't explicitly authorize.`,remediation:`Set commands.useAccessGroups=true (recommended).`});else{let allowFromRaw=account?.config?.allowFrom,legacyAllowFromRaw=account?.dm?.allowFrom,allowFrom=Array.isArray(allowFromRaw)?allowFromRaw:Array.isArray(legacyAllowFromRaw)?legacyAllowFromRaw:[],storeAllowFrom=await readChannelAllowFromStore(`slack`).catch(()=>[]),ownerAllowFromConfigured=normalizeAllowFromList$1([...allowFrom,...storeAllowFrom]).length>0,channels=slackCfg.channels??{},hasAnyChannelUsersAllowlist=Object.values(channels).some(value=>{if(!value||typeof value!=`object`)return!1;let channel=value;return Array.isArray(channel.users)&&channel.users.length>0});!ownerAllowFromConfigured&&!hasAnyChannelUsersAllowlist&&findings.push({checkId:`channels.slack.commands.slash.no_allowlists`,severity:`warn`,title:`Slack slash commands have no allowlists`,detail:`Slack slash/native commands are enabled, but neither an owner allowFrom list nor any channels.<id>.users allowlist is configured; /… commands will be rejected for everyone.`,remediation:`Approve yourself via pairing (recommended), or set channels.slack.allowFrom and/or channels.slack.channels.<id>.users.`})}}let dmPolicy=plugin.security.resolveDmPolicy?.({cfg:params.cfg,accountId:defaultAccountId,account});if(dmPolicy&&await warnDmPolicy({label:plugin.meta.label??plugin.id,provider:plugin.id,dmPolicy:dmPolicy.policy,allowFrom:dmPolicy.allowFrom,policyPath:dmPolicy.policyPath,allowFromPath:dmPolicy.allowFromPath,normalizeEntry:dmPolicy.normalizeEntry}),plugin.security.collectWarnings){let warnings=await plugin.security.collectWarnings({cfg:params.cfg,accountId:defaultAccountId,account});for(let message of warnings??[]){let trimmed=String(message).trim();trimmed&&findings.push({checkId:`channels.${plugin.id}.warning.${findings.length+1}`,severity:classifyChannelWarningSeverity(trimmed),title:`${plugin.meta.label??plugin.id} security warning`,detail:trimmed.replace(/^-\s*/,``)})}}if(plugin.id===`telegram`){if(params.cfg.commands?.text===!1)continue;let telegramCfg=account?.config??{},defaultGroupPolicy=params.cfg.channels?.defaults?.groupPolicy,groupPolicy=telegramCfg.groupPolicy??defaultGroupPolicy??`allowlist`,groups=telegramCfg.groups,groupsConfigured=!!groups&&Object.keys(groups??{}).length>0;if(!(groupPolicy===`open`||groupPolicy===`allowlist`&&groupsConfigured))continue;let storeAllowFrom=await readChannelAllowFromStore(`telegram`).catch(()=>[]),storeHasWildcard=storeAllowFrom.some(v=>String(v).trim()===`*`),invalidTelegramAllowFromEntries=new Set;for(let entry of storeAllowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}let groupAllowFrom=Array.isArray(telegramCfg.groupAllowFrom)?telegramCfg.groupAllowFrom:[],groupAllowFromHasWildcard=groupAllowFrom.some(v=>String(v).trim()===`*`);for(let entry of groupAllowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}let dmAllowFrom=Array.isArray(telegramCfg.allowFrom)?telegramCfg.allowFrom:[];for(let entry of dmAllowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}let anyGroupOverride=!!(groups&&Object.values(groups).some(value=>{if(!value||typeof value!=`object`)return!1;let group=value,allowFrom=Array.isArray(group.allowFrom)?group.allowFrom:[];if(allowFrom.length>0){for(let entry of allowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}return!0}let topics=group.topics;return!topics||typeof topics!=`object`?!1:Object.values(topics).some(topicValue=>{if(!topicValue||typeof topicValue!=`object`)return!1;let topic=topicValue,topicAllow=Array.isArray(topic.allowFrom)?topic.allowFrom:[];for(let entry of topicAllow){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}return topicAllow.length>0})})),hasAnySenderAllowlist=storeAllowFrom.length>0||groupAllowFrom.length>0||anyGroupOverride;if(invalidTelegramAllowFromEntries.size>0){let examples=Array.from(invalidTelegramAllowFromEntries).slice(0,5),more=invalidTelegramAllowFromEntries.size>examples.length?` (+${invalidTelegramAllowFromEntries.size-examples.length} more)`:``;findings.push({checkId:`channels.telegram.allowFrom.invalid_entries`,severity:`warn`,title:`Telegram allowlist contains non-numeric entries`,detail:`Telegram sender authorization requires numeric Telegram user IDs. Found non-numeric allowFrom entries: ${examples.join(`, `)}${more}.`,remediation:`Replace @username entries with numeric Telegram user IDs (use onboarding to resolve), then re-run the audit.`})}if(storeHasWildcard||groupAllowFromHasWildcard){findings.push({checkId:`channels.telegram.groups.allowFrom.wildcard`,severity:`critical`,title:`Telegram group allowlist contains wildcard`,detail:`Telegram group sender allowlist contains "*", which allows any group member to run /… commands and control directives.`,remediation:`Remove "*" from channels.telegram.groupAllowFrom and pairing store; prefer explicit numeric Telegram user IDs.`});continue}if(!hasAnySenderAllowlist){let providerSetting=telegramCfg.commands?.nativeSkills,skillsEnabled=resolveNativeSkillsEnabled({providerId:`telegram`,providerSetting,globalSetting:params.cfg.commands?.nativeSkills});findings.push({checkId:`channels.telegram.groups.allowFrom.missing`,severity:`critical`,title:`Telegram group commands have no sender allowlist`,detail:`Telegram group access is enabled but no sender allowlist is configured; this allows any group member to invoke /… commands`+(skillsEnabled?` (including skill commands).`:`.`),remediation:`Approve yourself via pairing (recommended), or set channels.telegram.groupAllowFrom (or per-group groups.<id>.allowFrom).`})}}}return findings}function summarizeGroupPolicy(cfg){let channels=cfg.channels;if(!channels||typeof channels!=`object`)return{open:0,allowlist:0,other:0};let open=0,allowlist=0,other=0;for(let value of Object.values(channels)){if(!value||typeof value!=`object`)continue;let policy=value.groupPolicy;policy===`open`?open+=1:policy===`allowlist`?allowlist+=1:other+=1}return{open,allowlist,other}}function isProbablySyncedPath(p){let s=p.toLowerCase();return s.includes(`icloud`)||s.includes(`dropbox`)||s.includes(`google drive`)||s.includes(`googledrive`)||s.includes(`onedrive`)}function looksLikeEnvRef(value){let v=value.trim();return v.startsWith("${")&&v.endsWith(`}`)}function isGatewayRemotelyExposed(cfg){if((typeof cfg.gateway?.bind==`string`?cfg.gateway.bind:`loopback`)!==`loopback`)return!0;let tailscaleMode=cfg.gateway?.tailscale?.mode??`off`;return tailscaleMode===`serve`||tailscaleMode===`funnel`}function addModel(models,raw,source){if(typeof raw!=`string`)return;let id=raw.trim();id&&models.push({id,source})}function collectModels(cfg){let out=[];addModel(out,cfg.agents?.defaults?.model?.primary,`agents.defaults.model.primary`);for(let f of cfg.agents?.defaults?.model?.fallbacks??[])addModel(out,f,`agents.defaults.model.fallbacks`);addModel(out,cfg.agents?.defaults?.imageModel?.primary,`agents.defaults.imageModel.primary`);for(let f of cfg.agents?.defaults?.imageModel?.fallbacks??[])addModel(out,f,`agents.defaults.imageModel.fallbacks`);let list=Array.isArray(cfg.agents?.list)?cfg.agents?.list:[];for(let agent of list??[]){if(!agent||typeof agent!=`object`)continue;let id=typeof agent.id==`string`?agent.id:``,model=agent.model;if(typeof model==`string`)addModel(out,model,`agents.list.${id}.model`);else if(model&&typeof model==`object`){addModel(out,model.primary,`agents.list.${id}.model.primary`);let fallbacks=model.fallbacks;if(Array.isArray(fallbacks))for(let f of fallbacks)addModel(out,f,`agents.list.${id}.model.fallbacks`)}}return out}const LEGACY_MODEL_PATTERNS=[{id:`openai.gpt35`,re:/\bgpt-3\.5\b/i,label:`GPT-3.5 family`},{id:`anthropic.claude2`,re:/\bclaude-(instant|2)\b/i,label:`Claude 2/Instant family`},{id:`openai.gpt4_legacy`,re:/\bgpt-4-(0314|0613)\b/i,label:`Legacy GPT-4 snapshots`}],WEAK_TIER_MODEL_PATTERNS=[{id:`anthropic.haiku`,re:/\bhaiku\b/i,label:`Haiku tier (smaller model)`}];function isGptModel(id){return/\bgpt-/i.test(id)}function isGpt5OrHigher(id){return/\bgpt-5(?:\b|[.-])/i.test(id)}function isClaudeModel(id){return/\bclaude-/i.test(id)}function isClaude45OrHigher(id){return/\bclaude-[^\s/]*?(?:-4-?(?:[5-9]|[1-9]\d)\b|4\.(?:[5-9]|[1-9]\d)\b|-[5-9](?:\b|[.-]))/i.test(id)}function extractAgentIdFromSource(source){return source.match(/^agents\.list\.([^.]*)\./)?.[1]??null}function hasConfiguredDockerConfig(docker){return!docker||typeof docker!=`object`?!1:Object.values(docker).some(value=>value!==void 0)}function normalizeNodeCommand(value){return typeof value==`string`?value.trim():``}function listKnownNodeCommands(cfg){let baseCfg={...cfg,gateway:{...cfg.gateway,nodes:{...cfg.gateway?.nodes,denyCommands:[]}}},out=new Set;for(let platform of[`ios`,`android`,`macos`,`linux`,`windows`,`unknown`]){let allow=resolveNodeCommandAllowlist(baseCfg,{platform});for(let cmd of allow){let normalized=normalizeNodeCommand(cmd);normalized&&out.add(normalized)}}return out}function looksLikeNodeCommandPattern(value){return value?/[?*[\]{}(),|]/.test(value)||value.startsWith(`/`)||value.endsWith(`/`)||value.startsWith(`^`)||value.endsWith(`$`)?!0:/\s/.test(value)||value.includes(`group:`):!1}function resolveToolPolicies$1(params){let policies=[],profilePolicy=resolveToolProfilePolicy(params.agentTools?.profile??params.cfg.tools?.profile);profilePolicy&&policies.push(profilePolicy);let globalPolicy=pickSandboxToolPolicy(params.cfg.tools??void 0);globalPolicy&&policies.push(globalPolicy);let agentPolicy=pickSandboxToolPolicy(params.agentTools);if(agentPolicy&&policies.push(agentPolicy),params.sandboxMode===`all`){let sandboxPolicy=resolveSandboxToolPolicyForAgent(params.cfg,params.agentId??void 0);policies.push(sandboxPolicy)}return policies}function hasWebSearchKey(cfg,env){let search=cfg.tools?.web?.search;return!!(search?.apiKey||search?.perplexity?.apiKey||env.BRAVE_API_KEY||env.PERPLEXITY_API_KEY||env.OPENROUTER_API_KEY)}function isWebSearchEnabled(cfg,env){let enabled=cfg.tools?.web?.search?.enabled;return enabled===!1?!1:enabled===!0?!0:hasWebSearchKey(cfg,env)}function isWebFetchEnabled(cfg){return cfg.tools?.web?.fetch?.enabled!==!1}function isBrowserEnabled(cfg){try{return resolveBrowserConfig(cfg.browser,cfg).enabled}catch{return!0}}function listGroupPolicyOpen(cfg){let out=[],channels=cfg.channels;if(!channels||typeof channels!=`object`)return out;for(let[channelId,value]of Object.entries(channels)){if(!value||typeof value!=`object`)continue;let section=value;section.groupPolicy===`open`&&out.push(`channels.${channelId}.groupPolicy`);let accounts=section.accounts;if(accounts&&typeof accounts==`object`)for(let[accountId,accountVal]of Object.entries(accounts))!accountVal||typeof accountVal!=`object`||accountVal.groupPolicy===`open`&&out.push(`channels.${channelId}.accounts.${accountId}.groupPolicy`)}return out}function collectAttackSurfaceSummaryFindings(cfg){let group=summarizeGroupPolicy(cfg),elevated=cfg.tools?.elevated?.enabled!==!1,webhooksEnabled=cfg.hooks?.enabled===!0,internalHooksEnabled=cfg.hooks?.internal?.enabled===!0,browserEnabled=cfg.browser?.enabled??!0;return[{checkId:`summary.attack_surface`,severity:`info`,title:`Attack surface summary`,detail:`groups: open=${group.open}, allowlist=${group.allowlist}\ntools.elevated: ${elevated?`enabled`:`disabled`}\nhooks.webhooks: ${webhooksEnabled?`enabled`:`disabled`}\nhooks.internal: ${internalHooksEnabled?`enabled`:`disabled`}\nbrowser control: ${browserEnabled?`enabled`:`disabled`}`}]}function collectSyncedFolderFindings(params){let findings=[];return(isProbablySyncedPath(params.stateDir)||isProbablySyncedPath(params.configPath))&&findings.push({checkId:`fs.synced_dir`,severity:`warn`,title:`State/config path looks like a synced folder`,detail:`stateDir=${params.stateDir}, configPath=${params.configPath}. Synced folders (iCloud/Dropbox/OneDrive/Google Drive) can leak tokens and transcripts onto other devices.`,remediation:`Keep BUILDERFORCE_AGENTS_STATE_DIR on a local-only volume and re-run "${formatCliCommand(`builderforce security audit --fix`)}".`}),findings}function collectSecretsInConfigFindings(cfg){let findings=[],password=typeof cfg.gateway?.auth?.password==`string`?cfg.gateway.auth.password.trim():``;password&&!looksLikeEnvRef(password)&&findings.push({checkId:`config.secrets.gateway_password_in_config`,severity:`warn`,title:`Gateway password is stored in config`,detail:`gateway.auth.password is set in the config file; prefer environment variables for secrets when possible.`,remediation:`Prefer BUILDERFORCE_AGENTS_GATEWAY_PASSWORD (env) and remove gateway.auth.password from disk.`});let hooksToken=typeof cfg.hooks?.token==`string`?cfg.hooks.token.trim():``;return cfg.hooks?.enabled===!0&&hooksToken&&!looksLikeEnvRef(hooksToken)&&findings.push({checkId:`config.secrets.hooks_token_in_config`,severity:`info`,title:`Hooks token is stored in config`,detail:`hooks.token is set in the config file; keep config perms tight and treat it like an API secret.`}),findings}function collectHooksHardeningFindings(cfg,env=process.env){let findings=[];if(cfg.hooks?.enabled!==!0)return findings;let token=typeof cfg.hooks?.token==`string`?cfg.hooks.token.trim():``;token&&token.length<24&&findings.push({checkId:`hooks.token_too_short`,severity:`warn`,title:`Hooks token looks short`,detail:`hooks.token is ${token.length} chars; prefer a long random token.`});let gatewayAuth=resolveGatewayAuth({authConfig:cfg.gateway?.auth,tailscaleMode:cfg.gateway?.tailscale?.mode??`off`,env}),builderforceGatewayToken=typeof env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN==`string`&&env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN.trim()?env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN.trim():null,gatewayToken=gatewayAuth.mode===`token`&&typeof gatewayAuth.token==`string`&&gatewayAuth.token.trim()?gatewayAuth.token.trim():builderforceGatewayToken||null;token&&gatewayToken&&token===gatewayToken&&findings.push({checkId:`hooks.token_reuse_gateway_token`,severity:`warn`,title:`Hooks token reuses the Gateway token`,detail:`hooks.token matches gateway.auth token; compromise of hooks expands blast radius to the Gateway API.`,remediation:`Use a separate hooks.token dedicated to hook ingress.`}),(typeof cfg.hooks?.path==`string`?cfg.hooks.path.trim():``)===`/`&&findings.push({checkId:`hooks.path_root`,severity:`critical`,title:`Hooks base path is '/'`,detail:`hooks.path='/' would shadow other HTTP endpoints and is unsafe.`,remediation:`Use a dedicated path like '/hooks'.`});let allowRequestSessionKey=cfg.hooks?.allowRequestSessionKey===!0,defaultSessionKey=typeof cfg.hooks?.defaultSessionKey==`string`?cfg.hooks.defaultSessionKey.trim():``,allowedPrefixes=Array.isArray(cfg.hooks?.allowedSessionKeyPrefixes)?cfg.hooks.allowedSessionKeyPrefixes.map(prefix=>prefix.trim()).filter(prefix=>prefix.length>0):[],remoteExposure=isGatewayRemotelyExposed(cfg);return defaultSessionKey||findings.push({checkId:`hooks.default_session_key_unset`,severity:`warn`,title:`hooks.defaultSessionKey is not configured`,detail:`Hook agent runs without explicit sessionKey use generated per-request keys. Set hooks.defaultSessionKey to keep hook ingress scoped to a known session.`,remediation:`Set hooks.defaultSessionKey (for example, "hook:ingress").`}),allowRequestSessionKey&&findings.push({checkId:`hooks.request_session_key_enabled`,severity:remoteExposure?`critical`:`warn`,title:`External hook payloads may override sessionKey`,detail:"hooks.allowRequestSessionKey=true allows `/hooks/agent` callers to choose the session key. Treat hook token holders as full-trust unless you also restrict prefixes.",remediation:`Set hooks.allowRequestSessionKey=false (recommended) or constrain hooks.allowedSessionKeyPrefixes.`}),allowRequestSessionKey&&allowedPrefixes.length===0&&findings.push({checkId:`hooks.request_session_key_prefixes_missing`,severity:remoteExposure?`critical`:`warn`,title:`Request sessionKey override is enabled without prefix restrictions`,detail:`hooks.allowRequestSessionKey=true and hooks.allowedSessionKeyPrefixes is unset/empty, so request payloads can target arbitrary session key shapes.`,remediation:`Set hooks.allowedSessionKeyPrefixes (for example, ["hook:"]) or disable request overrides.`}),findings}function collectGatewayHttpSessionKeyOverrideFindings(cfg){let findings=[],chatCompletionsEnabled=cfg.gateway?.http?.endpoints?.chatCompletions?.enabled===!0,responsesEnabled=cfg.gateway?.http?.endpoints?.responses?.enabled===!0;if(!chatCompletionsEnabled&&!responsesEnabled)return findings;let enabledEndpoints=[chatCompletionsEnabled?`/v1/chat/completions`:null,responsesEnabled?`/v1/responses`:null].filter(entry=>!!entry);return findings.push({checkId:`gateway.http.session_key_override_enabled`,severity:`info`,title:`HTTP API session-key override is enabled`,detail:`${enabledEndpoints.join(`, `)} accept x-builderforce-session-key for per-request session routing. Treat API credential holders as trusted principals.`}),findings}function collectSandboxDockerNoopFindings(cfg){let findings=[],configuredPaths=[],agents=Array.isArray(cfg.agents?.list)?cfg.agents.list:[],defaultsSandbox=cfg.agents?.defaults?.sandbox,hasDefaultDocker=hasConfiguredDockerConfig(defaultsSandbox?.docker),defaultMode=defaultsSandbox?.mode??`off`,hasAnySandboxEnabledAgent=agents.some(entry=>!entry||typeof entry!=`object`||typeof entry.id!=`string`?!1:resolveSandboxConfigForAgent(cfg,entry.id).mode!==`off`);hasDefaultDocker&&defaultMode===`off`&&!hasAnySandboxEnabledAgent&&configuredPaths.push(`agents.defaults.sandbox.docker`);for(let entry of agents)!entry||typeof entry!=`object`||typeof entry.id!=`string`||hasConfiguredDockerConfig(entry.sandbox?.docker)&&resolveSandboxConfigForAgent(cfg,entry.id).mode===`off`&&configuredPaths.push(`agents.list.${entry.id}.sandbox.docker`);return configuredPaths.length===0||findings.push({checkId:`sandbox.docker_config_mode_off`,severity:`warn`,title:`Sandbox docker settings configured while sandbox mode is off`,detail:`These docker settings will not take effect until sandbox mode is enabled:
|
|
1
|
+
import{g as resolveStateDir,m as resolveOAuthDir,o as resolveConfigPath}from"./paths-5FcIFMsj.js";import{d as normalizeAgentId}from"./session-key-EoB0qaG9.js";import{n as runExec}from"./exec-DdcIjeyn.js";import{l as resolveDefaultAgentId}from"./agent-scope-DPtjOxzp.js";import{t as formatCliCommand}from"./command-format-D806O2pt.js";import{F as INCLUDE_KEY,I as MAX_INCLUDE_DEPTH,L as extensionUsesSkippedScannerPath,R as isPathInside,n as createConfigIO}from"./io-BLBq4T2o.js";import{c as normalizePluginsConfig}from"./manifest-registry-BJCfNV1a.js";import{n as MANIFEST_KEY,t as LEGACY_MANIFEST_KEYS}from"./legacy-names-BXbHg7Rs.js";import{d as resolveSandboxConfigForAgent,l as getBlockedBindReason,p as resolveSandboxToolPolicyForAgent,x as resolveToolProfilePolicy}from"./sandbox-C4AKi2EX.js";import{i as resolveGatewayAuth}from"./auth-lebUHrkd.js";import{a as resolveProfile,i as resolveBrowserConfig,m as resolveBrowserControlAuth}from"./server-context-CQ2v4BAx.js";import{i as loadWorkspaceSkillEntries}from"./skills-Ba4ftrB-.js";import{n as formatErrorMessage}from"./errors-B1MIg3g-.js";import{et as normalizeStringEntries}from"./sessions-BuZVmOWt.js";import{h as GATEWAY_CLIENT_NAMES,m as GATEWAY_CLIENT_MODES}from"./message-channel-D_jXxXQj.js";import{n as listChannelPlugins}from"./plugins-D5zP6ENo.js";import{t as GatewayClient}from"./client-xfoidwPI.js";import{t as buildGatewayConnectionDetails}from"./call-T8ciwMTA.js";import{i as readChannelAllowFromStore}from"./pairing-store-ti3FEkmr.js";import{c as resolveNativeCommandsEnabled,l as resolveNativeSkillsEnabled,n as isToolAllowedByPolicies,o as pickSandboxToolPolicy,u as listAgentWorkspaceDirs}from"./coding-tools.policy-ZhOdlcEI.js";import{n as DEFAULT_GATEWAY_HTTP_TOOL_DENY}from"./dangerous-tools-DROxC992.js";import{t as resolveChannelDefaultAccountId}from"./helpers-DTDCy17p.js";import{t as scanDirectoryWithSummary}from"./skill-scanner-BEvov9QH.js";import{n as isNumericTelegramUserId,r as normalizeTelegramAllowFromEntry,t as resolveDmAllowState}from"./dm-policy-shared-DYZ_T-az.js";import{t as inferParamBFromIdOrName}from"./model-param-b-347pru8e.js";import os from"node:os";import path from"node:path";import{randomUUID}from"node:crypto";import JSON5 from"json5";import*as fs$1 from"node:fs/promises";import fs from"node:fs/promises";async function probeGateway(opts){let startedAt=Date.now(),instanceId=randomUUID(),connectLatencyMs=null,connectError=null,close=null;return await new Promise(resolve=>{let settled=!1,settle=result=>{settled||(settled=!0,clearTimeout(timer),client.stop(),resolve({url:opts.url,...result}))},client=new GatewayClient({url:opts.url,token:opts.auth?.token,password:opts.auth?.password,clientName:GATEWAY_CLIENT_NAMES.CLI,clientVersion:`dev`,mode:GATEWAY_CLIENT_MODES.PROBE,instanceId,onConnectError:err=>{connectError=formatErrorMessage(err)},onClose:(code,reason)=>{close={code,reason}},onHelloOk:async()=>{connectLatencyMs=Date.now()-startedAt;try{let[health,status,presence,configSnapshot]=await Promise.all([client.request(`health`),client.request(`status`),client.request(`system-presence`),client.request(`config.get`,{})]);settle({ok:!0,connectLatencyMs,error:null,close,health,status,presence:Array.isArray(presence)?presence:null,configSnapshot})}catch(err){settle({ok:!1,connectLatencyMs,error:formatErrorMessage(err),close,health:null,status:null,presence:null,configSnapshot:null})}}}),timer=setTimeout(()=>{settle({ok:!1,connectLatencyMs,error:connectError?`connect failed: ${connectError}`:`timeout`,close,health:null,status:null,presence:null,configSnapshot:null})},Math.max(250,opts.timeoutMs));client.start()})}const CANVAS_COMMANDS=[`canvas.present`,`canvas.hide`,`canvas.navigate`,`canvas.eval`,`canvas.snapshot`,`canvas.a2ui.push`,`canvas.a2ui.pushJSONL`,`canvas.a2ui.reset`],CAMERA_COMMANDS=[`camera.list`],CAMERA_DANGEROUS_COMMANDS=[`camera.snap`,`camera.clip`],SCREEN_DANGEROUS_COMMANDS=[`screen.record`],LOCATION_COMMANDS=[`location.get`],DEVICE_COMMANDS=[`device.info`,`device.status`],CONTACTS_COMMANDS=[`contacts.search`],CONTACTS_DANGEROUS_COMMANDS=[`contacts.add`],CALENDAR_COMMANDS=[`calendar.events`],CALENDAR_DANGEROUS_COMMANDS=[`calendar.add`],REMINDERS_COMMANDS=[`reminders.list`],REMINDERS_DANGEROUS_COMMANDS=[`reminders.add`],PHOTOS_COMMANDS=[`photos.latest`],MOTION_COMMANDS=[`motion.activity`,`motion.pedometer`],SMS_DANGEROUS_COMMANDS=[`sms.send`],IOS_SYSTEM_COMMANDS=[`system.notify`],SYSTEM_COMMANDS=[`system.run`,`system.which`,`system.notify`,`browser.proxy`];[...CAMERA_DANGEROUS_COMMANDS,...SCREEN_DANGEROUS_COMMANDS,...CONTACTS_DANGEROUS_COMMANDS,...CALENDAR_DANGEROUS_COMMANDS,...REMINDERS_DANGEROUS_COMMANDS,...SMS_DANGEROUS_COMMANDS];const PLATFORM_DEFAULTS={ios:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...DEVICE_COMMANDS,...CONTACTS_COMMANDS,...CALENDAR_COMMANDS,...REMINDERS_COMMANDS,...PHOTOS_COMMANDS,...MOTION_COMMANDS,...IOS_SYSTEM_COMMANDS],android:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...DEVICE_COMMANDS,...CONTACTS_COMMANDS,...CALENDAR_COMMANDS,...REMINDERS_COMMANDS,...PHOTOS_COMMANDS,...MOTION_COMMANDS],macos:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...DEVICE_COMMANDS,...CONTACTS_COMMANDS,...CALENDAR_COMMANDS,...REMINDERS_COMMANDS,...PHOTOS_COMMANDS,...MOTION_COMMANDS,...SYSTEM_COMMANDS],linux:[...SYSTEM_COMMANDS],windows:[...SYSTEM_COMMANDS],unknown:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...SYSTEM_COMMANDS]};function normalizePlatformId(platform,deviceFamily){let raw=(platform??``).trim().toLowerCase();if(raw.startsWith(`ios`))return`ios`;if(raw.startsWith(`android`))return`android`;if(raw.startsWith(`mac`)||raw.startsWith(`darwin`))return`macos`;if(raw.startsWith(`win`))return`windows`;if(raw.startsWith(`linux`))return`linux`;let family=(deviceFamily??``).trim().toLowerCase();return family.includes(`iphone`)||family.includes(`ipad`)||family.includes(`ios`)?`ios`:family.includes(`android`)?`android`:family.includes(`mac`)?`macos`:family.includes(`windows`)?`windows`:family.includes(`linux`)?`linux`:`unknown`}function resolveNodeCommandAllowlist(cfg,node){let base=PLATFORM_DEFAULTS[normalizePlatformId(node?.platform,node?.deviceFamily)]??PLATFORM_DEFAULTS.unknown,extra=cfg.gateway?.nodes?.allowCommands??[],deny=new Set(cfg.gateway?.nodes?.denyCommands??[]),allow=new Set([...base,...extra].map(cmd=>cmd.trim()).filter(Boolean));for(let blocked of deny){let trimmed=blocked.trim();trimmed&&allow.delete(trimmed)}return allow}function isNodeCommandAllowed(params){let command=params.command.trim();if(!command)return{ok:!1,reason:`command required`};if(!params.allowlist.has(command))return{ok:!1,reason:`command not allowlisted`};if(Array.isArray(params.declaredCommands)&¶ms.declaredCommands.length>0){if(!params.declaredCommands.includes(command))return{ok:!1,reason:`command not declared by node`}}else return{ok:!1,reason:`node did not declare commands`};return{ok:!0}}function resolveGatewayProbeAuth(params){let env=params.env??process.env,authToken=params.cfg.gateway?.auth?.token,authPassword=params.cfg.gateway?.auth?.password,remote=params.cfg.gateway?.remote;return{token:params.mode===`remote`?typeof remote?.token==`string`&&remote.token.trim()?remote.token.trim():void 0:env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN?.trim()||(typeof authToken==`string`&&authToken.trim()?authToken.trim():void 0),password:env.BUILDERFORCE_AGENTS_GATEWAY_PASSWORD?.trim()||(params.mode===`remote`?typeof remote?.password==`string`&&remote.password.trim()?remote.password.trim():void 0:typeof authPassword==`string`&&authPassword.trim()?authPassword.trim():void 0)}}function normalizeAllowFromList$1(list){return normalizeStringEntries(Array.isArray(list)?list:void 0)}function classifyChannelWarningSeverity(message){let s=message.toLowerCase();return s.includes(`dms: open`)||s.includes(`grouppolicy="open"`)||s.includes(`dmpolicy="open"`)||s.includes(`allows any`)||s.includes(`anyone can dm`)||s.includes(`public`)?`critical`:s.includes(`locked`)||s.includes(`disabled`)?`info`:`warn`}async function collectChannelSecurityFindings(params){let findings=[],coerceNativeSetting=value=>{if(value===!0)return!0;if(value===!1)return!1;if(value===`auto`)return`auto`},warnDmPolicy=async input=>{let policyPath=input.policyPath??`${input.allowFromPath}policy`,{hasWildcard,isMultiUserDm}=await resolveDmAllowState({provider:input.provider,allowFrom:input.allowFrom,normalizeEntry:input.normalizeEntry}),dmScope=params.cfg.session?.dmScope??`main`;if(input.dmPolicy===`open`){let allowFromKey=`${input.allowFromPath}allowFrom`;findings.push({checkId:`channels.${input.provider}.dm.open`,severity:`critical`,title:`${input.label} DMs are open`,detail:`${policyPath}="open" allows anyone to DM the bot.`,remediation:`Use pairing/allowlist; if you really need open DMs, ensure ${allowFromKey} includes "*".`}),hasWildcard||findings.push({checkId:`channels.${input.provider}.dm.open_invalid`,severity:`warn`,title:`${input.label} DM config looks inconsistent`,detail:`"open" requires ${allowFromKey} to include "*".`})}if(input.dmPolicy===`disabled`){findings.push({checkId:`channels.${input.provider}.dm.disabled`,severity:`info`,title:`${input.label} DMs are disabled`,detail:`${policyPath}="disabled" ignores inbound DMs.`});return}dmScope===`main`&&isMultiUserDm&&findings.push({checkId:`channels.${input.provider}.dm.scope_main_multiuser`,severity:`warn`,title:`${input.label} DMs share the main session`,detail:`Multiple DM senders currently share the main session, which can leak context across users.`,remediation:`Run: `+formatCliCommand(`builderforce config set session.dmScope "per-channel-peer"`)+` (or "per-account-channel-peer" for multi-account channels) to isolate DM sessions per sender.`})};for(let plugin of params.plugins){if(!plugin.security)continue;let accountIds=plugin.config.listAccountIds(params.cfg),defaultAccountId=resolveChannelDefaultAccountId({plugin,cfg:params.cfg,accountIds}),account=plugin.config.resolveAccount(params.cfg,defaultAccountId);if(!(!plugin.config.isEnabled||plugin.config.isEnabled(account,params.cfg))||!(!plugin.config.isConfigured||await plugin.config.isConfigured(account,params.cfg)))continue;if(plugin.id===`discord`){let discordCfg=account?.config??{},nativeEnabled=resolveNativeCommandsEnabled({providerId:`discord`,providerSetting:coerceNativeSetting(discordCfg.commands?.native),globalSetting:params.cfg.commands?.native}),nativeSkillsEnabled=resolveNativeSkillsEnabled({providerId:`discord`,providerSetting:coerceNativeSetting(discordCfg.commands?.nativeSkills),globalSetting:params.cfg.commands?.nativeSkills});if(nativeEnabled||nativeSkillsEnabled){let defaultGroupPolicy=params.cfg.channels?.defaults?.groupPolicy,groupPolicy=discordCfg.groupPolicy??defaultGroupPolicy??`allowlist`,guildEntries=discordCfg.guilds??{},guildsConfigured=Object.keys(guildEntries).length>0,hasAnyUserAllowlist=Object.values(guildEntries).some(guild=>{if(!guild||typeof guild!=`object`)return!1;let g=guild;if(Array.isArray(g.users)&&g.users.length>0)return!0;let channels=g.channels;return!channels||typeof channels!=`object`?!1:Object.values(channels).some(channel=>{if(!channel||typeof channel!=`object`)return!1;let c=channel;return Array.isArray(c.users)&&c.users.length>0})}),dmAllowFromRaw=discordCfg.dm?.allowFrom,dmAllowFrom=Array.isArray(dmAllowFromRaw)?dmAllowFromRaw:[],storeAllowFrom=await readChannelAllowFromStore(`discord`).catch(()=>[]),ownerAllowFromConfigured=normalizeAllowFromList$1([...dmAllowFrom,...storeAllowFrom]).length>0,useAccessGroups=params.cfg.commands?.useAccessGroups!==!1;!useAccessGroups&&groupPolicy!==`disabled`&&guildsConfigured&&!hasAnyUserAllowlist?findings.push({checkId:`channels.discord.commands.native.unrestricted`,severity:`critical`,title:`Discord slash commands are unrestricted`,detail:`commands.useAccessGroups=false disables sender allowlists for Discord slash commands unless a per-guild/channel users allowlist is configured; with no users allowlist, any user in allowed guild channels can invoke /… commands.`,remediation:`Set commands.useAccessGroups=true (recommended), or configure channels.discord.guilds.<id>.users (or channels.discord.guilds.<id>.channels.<channel>.users).`}):useAccessGroups&&groupPolicy!==`disabled`&&guildsConfigured&&!ownerAllowFromConfigured&&!hasAnyUserAllowlist&&findings.push({checkId:`channels.discord.commands.native.no_allowlists`,severity:`warn`,title:`Discord slash commands have no allowlists`,detail:`Discord slash commands are enabled, but neither an owner allowFrom list nor any per-guild/channel users allowlist is configured; /… commands will be rejected for everyone.`,remediation:`Add your user id to channels.discord.allowFrom (or approve yourself via pairing), or configure channels.discord.guilds.<id>.users.`})}}if(plugin.id===`slack`){let slackCfg=account?.config??{},nativeEnabled=resolveNativeCommandsEnabled({providerId:`slack`,providerSetting:coerceNativeSetting(slackCfg.commands?.native),globalSetting:params.cfg.commands?.native}),nativeSkillsEnabled=resolveNativeSkillsEnabled({providerId:`slack`,providerSetting:coerceNativeSetting(slackCfg.commands?.nativeSkills),globalSetting:params.cfg.commands?.nativeSkills});if(nativeEnabled||nativeSkillsEnabled||slackCfg.slashCommand?.enabled===!0)if(params.cfg.commands?.useAccessGroups===!1)findings.push({checkId:`channels.slack.commands.slash.useAccessGroups_off`,severity:`critical`,title:`Slack slash commands bypass access groups`,detail:`Slack slash/native commands are enabled while commands.useAccessGroups=false; this can allow unrestricted /… command execution from channels/users you didn't explicitly authorize.`,remediation:`Set commands.useAccessGroups=true (recommended).`});else{let allowFromRaw=account?.config?.allowFrom,legacyAllowFromRaw=account?.dm?.allowFrom,allowFrom=Array.isArray(allowFromRaw)?allowFromRaw:Array.isArray(legacyAllowFromRaw)?legacyAllowFromRaw:[],storeAllowFrom=await readChannelAllowFromStore(`slack`).catch(()=>[]),ownerAllowFromConfigured=normalizeAllowFromList$1([...allowFrom,...storeAllowFrom]).length>0,channels=slackCfg.channels??{},hasAnyChannelUsersAllowlist=Object.values(channels).some(value=>{if(!value||typeof value!=`object`)return!1;let channel=value;return Array.isArray(channel.users)&&channel.users.length>0});!ownerAllowFromConfigured&&!hasAnyChannelUsersAllowlist&&findings.push({checkId:`channels.slack.commands.slash.no_allowlists`,severity:`warn`,title:`Slack slash commands have no allowlists`,detail:`Slack slash/native commands are enabled, but neither an owner allowFrom list nor any channels.<id>.users allowlist is configured; /… commands will be rejected for everyone.`,remediation:`Approve yourself via pairing (recommended), or set channels.slack.allowFrom and/or channels.slack.channels.<id>.users.`})}}let dmPolicy=plugin.security.resolveDmPolicy?.({cfg:params.cfg,accountId:defaultAccountId,account});if(dmPolicy&&await warnDmPolicy({label:plugin.meta.label??plugin.id,provider:plugin.id,dmPolicy:dmPolicy.policy,allowFrom:dmPolicy.allowFrom,policyPath:dmPolicy.policyPath,allowFromPath:dmPolicy.allowFromPath,normalizeEntry:dmPolicy.normalizeEntry}),plugin.security.collectWarnings){let warnings=await plugin.security.collectWarnings({cfg:params.cfg,accountId:defaultAccountId,account});for(let message of warnings??[]){let trimmed=String(message).trim();trimmed&&findings.push({checkId:`channels.${plugin.id}.warning.${findings.length+1}`,severity:classifyChannelWarningSeverity(trimmed),title:`${plugin.meta.label??plugin.id} security warning`,detail:trimmed.replace(/^-\s*/,``)})}}if(plugin.id===`telegram`){if(params.cfg.commands?.text===!1)continue;let telegramCfg=account?.config??{},defaultGroupPolicy=params.cfg.channels?.defaults?.groupPolicy,groupPolicy=telegramCfg.groupPolicy??defaultGroupPolicy??`allowlist`,groups=telegramCfg.groups,groupsConfigured=!!groups&&Object.keys(groups??{}).length>0;if(!(groupPolicy===`open`||groupPolicy===`allowlist`&&groupsConfigured))continue;let storeAllowFrom=await readChannelAllowFromStore(`telegram`).catch(()=>[]),storeHasWildcard=storeAllowFrom.some(v=>String(v).trim()===`*`),invalidTelegramAllowFromEntries=new Set;for(let entry of storeAllowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}let groupAllowFrom=Array.isArray(telegramCfg.groupAllowFrom)?telegramCfg.groupAllowFrom:[],groupAllowFromHasWildcard=groupAllowFrom.some(v=>String(v).trim()===`*`);for(let entry of groupAllowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}let dmAllowFrom=Array.isArray(telegramCfg.allowFrom)?telegramCfg.allowFrom:[];for(let entry of dmAllowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}let anyGroupOverride=!!(groups&&Object.values(groups).some(value=>{if(!value||typeof value!=`object`)return!1;let group=value,allowFrom=Array.isArray(group.allowFrom)?group.allowFrom:[];if(allowFrom.length>0){for(let entry of allowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}return!0}let topics=group.topics;return!topics||typeof topics!=`object`?!1:Object.values(topics).some(topicValue=>{if(!topicValue||typeof topicValue!=`object`)return!1;let topic=topicValue,topicAllow=Array.isArray(topic.allowFrom)?topic.allowFrom:[];for(let entry of topicAllow){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}return topicAllow.length>0})})),hasAnySenderAllowlist=storeAllowFrom.length>0||groupAllowFrom.length>0||anyGroupOverride;if(invalidTelegramAllowFromEntries.size>0){let examples=Array.from(invalidTelegramAllowFromEntries).slice(0,5),more=invalidTelegramAllowFromEntries.size>examples.length?` (+${invalidTelegramAllowFromEntries.size-examples.length} more)`:``;findings.push({checkId:`channels.telegram.allowFrom.invalid_entries`,severity:`warn`,title:`Telegram allowlist contains non-numeric entries`,detail:`Telegram sender authorization requires numeric Telegram user IDs. Found non-numeric allowFrom entries: ${examples.join(`, `)}${more}.`,remediation:`Replace @username entries with numeric Telegram user IDs (use onboarding to resolve), then re-run the audit.`})}if(storeHasWildcard||groupAllowFromHasWildcard){findings.push({checkId:`channels.telegram.groups.allowFrom.wildcard`,severity:`critical`,title:`Telegram group allowlist contains wildcard`,detail:`Telegram group sender allowlist contains "*", which allows any group member to run /… commands and control directives.`,remediation:`Remove "*" from channels.telegram.groupAllowFrom and pairing store; prefer explicit numeric Telegram user IDs.`});continue}if(!hasAnySenderAllowlist){let providerSetting=telegramCfg.commands?.nativeSkills,skillsEnabled=resolveNativeSkillsEnabled({providerId:`telegram`,providerSetting,globalSetting:params.cfg.commands?.nativeSkills});findings.push({checkId:`channels.telegram.groups.allowFrom.missing`,severity:`critical`,title:`Telegram group commands have no sender allowlist`,detail:`Telegram group access is enabled but no sender allowlist is configured; this allows any group member to invoke /… commands`+(skillsEnabled?` (including skill commands).`:`.`),remediation:`Approve yourself via pairing (recommended), or set channels.telegram.groupAllowFrom (or per-group groups.<id>.allowFrom).`})}}}return findings}function summarizeGroupPolicy(cfg){let channels=cfg.channels;if(!channels||typeof channels!=`object`)return{open:0,allowlist:0,other:0};let open=0,allowlist=0,other=0;for(let value of Object.values(channels)){if(!value||typeof value!=`object`)continue;let policy=value.groupPolicy;policy===`open`?open+=1:policy===`allowlist`?allowlist+=1:other+=1}return{open,allowlist,other}}function isProbablySyncedPath(p){let s=p.toLowerCase();return s.includes(`icloud`)||s.includes(`dropbox`)||s.includes(`google drive`)||s.includes(`googledrive`)||s.includes(`onedrive`)}function looksLikeEnvRef(value){let v=value.trim();return v.startsWith("${")&&v.endsWith(`}`)}function isGatewayRemotelyExposed(cfg){if((typeof cfg.gateway?.bind==`string`?cfg.gateway.bind:`loopback`)!==`loopback`)return!0;let tailscaleMode=cfg.gateway?.tailscale?.mode??`off`;return tailscaleMode===`serve`||tailscaleMode===`funnel`}function addModel(models,raw,source){if(typeof raw!=`string`)return;let id=raw.trim();id&&models.push({id,source})}function collectModels(cfg){let out=[];addModel(out,cfg.agents?.defaults?.model?.primary,`agents.defaults.model.primary`);for(let f of cfg.agents?.defaults?.model?.fallbacks??[])addModel(out,f,`agents.defaults.model.fallbacks`);addModel(out,cfg.agents?.defaults?.imageModel?.primary,`agents.defaults.imageModel.primary`);for(let f of cfg.agents?.defaults?.imageModel?.fallbacks??[])addModel(out,f,`agents.defaults.imageModel.fallbacks`);let list=Array.isArray(cfg.agents?.list)?cfg.agents?.list:[];for(let agent of list??[]){if(!agent||typeof agent!=`object`)continue;let id=typeof agent.id==`string`?agent.id:``,model=agent.model;if(typeof model==`string`)addModel(out,model,`agents.list.${id}.model`);else if(model&&typeof model==`object`){addModel(out,model.primary,`agents.list.${id}.model.primary`);let fallbacks=model.fallbacks;if(Array.isArray(fallbacks))for(let f of fallbacks)addModel(out,f,`agents.list.${id}.model.fallbacks`)}}return out}const LEGACY_MODEL_PATTERNS=[{id:`openai.gpt35`,re:/\bgpt-3\.5\b/i,label:`GPT-3.5 family`},{id:`anthropic.claude2`,re:/\bclaude-(instant|2)\b/i,label:`Claude 2/Instant family`},{id:`openai.gpt4_legacy`,re:/\bgpt-4-(0314|0613)\b/i,label:`Legacy GPT-4 snapshots`}],WEAK_TIER_MODEL_PATTERNS=[{id:`anthropic.haiku`,re:/\bhaiku\b/i,label:`Haiku tier (smaller model)`}];function isGptModel(id){return/\bgpt-/i.test(id)}function isGpt5OrHigher(id){return/\bgpt-5(?:\b|[.-])/i.test(id)}function isClaudeModel(id){return/\bclaude-/i.test(id)}function isClaude45OrHigher(id){return/\bclaude-[^\s/]*?(?:-4-?(?:[5-9]|[1-9]\d)\b|4\.(?:[5-9]|[1-9]\d)\b|-[5-9](?:\b|[.-]))/i.test(id)}function extractAgentIdFromSource(source){return source.match(/^agents\.list\.([^.]*)\./)?.[1]??null}function hasConfiguredDockerConfig(docker){return!docker||typeof docker!=`object`?!1:Object.values(docker).some(value=>value!==void 0)}function normalizeNodeCommand(value){return typeof value==`string`?value.trim():``}function listKnownNodeCommands(cfg){let baseCfg={...cfg,gateway:{...cfg.gateway,nodes:{...cfg.gateway?.nodes,denyCommands:[]}}},out=new Set;for(let platform of[`ios`,`android`,`macos`,`linux`,`windows`,`unknown`]){let allow=resolveNodeCommandAllowlist(baseCfg,{platform});for(let cmd of allow){let normalized=normalizeNodeCommand(cmd);normalized&&out.add(normalized)}}return out}function looksLikeNodeCommandPattern(value){return value?/[?*[\]{}(),|]/.test(value)||value.startsWith(`/`)||value.endsWith(`/`)||value.startsWith(`^`)||value.endsWith(`$`)?!0:/\s/.test(value)||value.includes(`group:`):!1}function resolveToolPolicies$1(params){let policies=[],profilePolicy=resolveToolProfilePolicy(params.agentTools?.profile??params.cfg.tools?.profile);profilePolicy&&policies.push(profilePolicy);let globalPolicy=pickSandboxToolPolicy(params.cfg.tools??void 0);globalPolicy&&policies.push(globalPolicy);let agentPolicy=pickSandboxToolPolicy(params.agentTools);if(agentPolicy&&policies.push(agentPolicy),params.sandboxMode===`all`){let sandboxPolicy=resolveSandboxToolPolicyForAgent(params.cfg,params.agentId??void 0);policies.push(sandboxPolicy)}return policies}function hasWebSearchKey(cfg,env){let search=cfg.tools?.web?.search;return!!(search?.apiKey||search?.perplexity?.apiKey||env.BRAVE_API_KEY||env.PERPLEXITY_API_KEY||env.OPENROUTER_API_KEY)}function isWebSearchEnabled(cfg,env){let enabled=cfg.tools?.web?.search?.enabled;return enabled===!1?!1:enabled===!0?!0:hasWebSearchKey(cfg,env)}function isWebFetchEnabled(cfg){return cfg.tools?.web?.fetch?.enabled!==!1}function isBrowserEnabled(cfg){try{return resolveBrowserConfig(cfg.browser,cfg).enabled}catch{return!0}}function listGroupPolicyOpen(cfg){let out=[],channels=cfg.channels;if(!channels||typeof channels!=`object`)return out;for(let[channelId,value]of Object.entries(channels)){if(!value||typeof value!=`object`)continue;let section=value;section.groupPolicy===`open`&&out.push(`channels.${channelId}.groupPolicy`);let accounts=section.accounts;if(accounts&&typeof accounts==`object`)for(let[accountId,accountVal]of Object.entries(accounts))!accountVal||typeof accountVal!=`object`||accountVal.groupPolicy===`open`&&out.push(`channels.${channelId}.accounts.${accountId}.groupPolicy`)}return out}function collectAttackSurfaceSummaryFindings(cfg){let group=summarizeGroupPolicy(cfg),elevated=cfg.tools?.elevated?.enabled!==!1,webhooksEnabled=cfg.hooks?.enabled===!0,internalHooksEnabled=cfg.hooks?.internal?.enabled===!0,browserEnabled=cfg.browser?.enabled??!0;return[{checkId:`summary.attack_surface`,severity:`info`,title:`Attack surface summary`,detail:`groups: open=${group.open}, allowlist=${group.allowlist}\ntools.elevated: ${elevated?`enabled`:`disabled`}\nhooks.webhooks: ${webhooksEnabled?`enabled`:`disabled`}\nhooks.internal: ${internalHooksEnabled?`enabled`:`disabled`}\nbrowser control: ${browserEnabled?`enabled`:`disabled`}`}]}function collectSyncedFolderFindings(params){let findings=[];return(isProbablySyncedPath(params.stateDir)||isProbablySyncedPath(params.configPath))&&findings.push({checkId:`fs.synced_dir`,severity:`warn`,title:`State/config path looks like a synced folder`,detail:`stateDir=${params.stateDir}, configPath=${params.configPath}. Synced folders (iCloud/Dropbox/OneDrive/Google Drive) can leak tokens and transcripts onto other devices.`,remediation:`Keep BUILDERFORCE_AGENTS_STATE_DIR on a local-only volume and re-run "${formatCliCommand(`builderforce security audit --fix`)}".`}),findings}function collectSecretsInConfigFindings(cfg){let findings=[],password=typeof cfg.gateway?.auth?.password==`string`?cfg.gateway.auth.password.trim():``;password&&!looksLikeEnvRef(password)&&findings.push({checkId:`config.secrets.gateway_password_in_config`,severity:`warn`,title:`Gateway password is stored in config`,detail:`gateway.auth.password is set in the config file; prefer environment variables for secrets when possible.`,remediation:`Prefer BUILDERFORCE_AGENTS_GATEWAY_PASSWORD (env) and remove gateway.auth.password from disk.`});let hooksToken=typeof cfg.hooks?.token==`string`?cfg.hooks.token.trim():``;return cfg.hooks?.enabled===!0&&hooksToken&&!looksLikeEnvRef(hooksToken)&&findings.push({checkId:`config.secrets.hooks_token_in_config`,severity:`info`,title:`Hooks token is stored in config`,detail:`hooks.token is set in the config file; keep config perms tight and treat it like an API secret.`}),findings}function collectHooksHardeningFindings(cfg,env=process.env){let findings=[];if(cfg.hooks?.enabled!==!0)return findings;let token=typeof cfg.hooks?.token==`string`?cfg.hooks.token.trim():``;token&&token.length<24&&findings.push({checkId:`hooks.token_too_short`,severity:`warn`,title:`Hooks token looks short`,detail:`hooks.token is ${token.length} chars; prefer a long random token.`});let gatewayAuth=resolveGatewayAuth({authConfig:cfg.gateway?.auth,tailscaleMode:cfg.gateway?.tailscale?.mode??`off`,env}),builderforceGatewayToken=typeof env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN==`string`&&env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN.trim()?env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN.trim():null,gatewayToken=gatewayAuth.mode===`token`&&typeof gatewayAuth.token==`string`&&gatewayAuth.token.trim()?gatewayAuth.token.trim():builderforceGatewayToken||null;token&&gatewayToken&&token===gatewayToken&&findings.push({checkId:`hooks.token_reuse_gateway_token`,severity:`warn`,title:`Hooks token reuses the Gateway token`,detail:`hooks.token matches gateway.auth token; compromise of hooks expands blast radius to the Gateway API.`,remediation:`Use a separate hooks.token dedicated to hook ingress.`}),(typeof cfg.hooks?.path==`string`?cfg.hooks.path.trim():``)===`/`&&findings.push({checkId:`hooks.path_root`,severity:`critical`,title:`Hooks base path is '/'`,detail:`hooks.path='/' would shadow other HTTP endpoints and is unsafe.`,remediation:`Use a dedicated path like '/hooks'.`});let allowRequestSessionKey=cfg.hooks?.allowRequestSessionKey===!0,defaultSessionKey=typeof cfg.hooks?.defaultSessionKey==`string`?cfg.hooks.defaultSessionKey.trim():``,allowedPrefixes=Array.isArray(cfg.hooks?.allowedSessionKeyPrefixes)?cfg.hooks.allowedSessionKeyPrefixes.map(prefix=>prefix.trim()).filter(prefix=>prefix.length>0):[],remoteExposure=isGatewayRemotelyExposed(cfg);return defaultSessionKey||findings.push({checkId:`hooks.default_session_key_unset`,severity:`warn`,title:`hooks.defaultSessionKey is not configured`,detail:`Hook agent runs without explicit sessionKey use generated per-request keys. Set hooks.defaultSessionKey to keep hook ingress scoped to a known session.`,remediation:`Set hooks.defaultSessionKey (for example, "hook:ingress").`}),allowRequestSessionKey&&findings.push({checkId:`hooks.request_session_key_enabled`,severity:remoteExposure?`critical`:`warn`,title:`External hook payloads may override sessionKey`,detail:"hooks.allowRequestSessionKey=true allows `/hooks/agent` callers to choose the session key. Treat hook token holders as full-trust unless you also restrict prefixes.",remediation:`Set hooks.allowRequestSessionKey=false (recommended) or constrain hooks.allowedSessionKeyPrefixes.`}),allowRequestSessionKey&&allowedPrefixes.length===0&&findings.push({checkId:`hooks.request_session_key_prefixes_missing`,severity:remoteExposure?`critical`:`warn`,title:`Request sessionKey override is enabled without prefix restrictions`,detail:`hooks.allowRequestSessionKey=true and hooks.allowedSessionKeyPrefixes is unset/empty, so request payloads can target arbitrary session key shapes.`,remediation:`Set hooks.allowedSessionKeyPrefixes (for example, ["hook:"]) or disable request overrides.`}),findings}function collectGatewayHttpSessionKeyOverrideFindings(cfg){let findings=[],chatCompletionsEnabled=cfg.gateway?.http?.endpoints?.chatCompletions?.enabled===!0,responsesEnabled=cfg.gateway?.http?.endpoints?.responses?.enabled===!0;if(!chatCompletionsEnabled&&!responsesEnabled)return findings;let enabledEndpoints=[chatCompletionsEnabled?`/v1/chat/completions`:null,responsesEnabled?`/v1/responses`:null].filter(entry=>!!entry);return findings.push({checkId:`gateway.http.session_key_override_enabled`,severity:`info`,title:`HTTP API session-key override is enabled`,detail:`${enabledEndpoints.join(`, `)} accept x-builderforce-session-key for per-request session routing. Treat API credential holders as trusted principals.`}),findings}function collectSandboxDockerNoopFindings(cfg){let findings=[],configuredPaths=[],agents=Array.isArray(cfg.agents?.list)?cfg.agents.list:[],defaultsSandbox=cfg.agents?.defaults?.sandbox,hasDefaultDocker=hasConfiguredDockerConfig(defaultsSandbox?.docker),defaultMode=defaultsSandbox?.mode??`off`,hasAnySandboxEnabledAgent=agents.some(entry=>!entry||typeof entry!=`object`||typeof entry.id!=`string`?!1:resolveSandboxConfigForAgent(cfg,entry.id).mode!==`off`);hasDefaultDocker&&defaultMode===`off`&&!hasAnySandboxEnabledAgent&&configuredPaths.push(`agents.defaults.sandbox.docker`);for(let entry of agents)!entry||typeof entry!=`object`||typeof entry.id!=`string`||hasConfiguredDockerConfig(entry.sandbox?.docker)&&resolveSandboxConfigForAgent(cfg,entry.id).mode===`off`&&configuredPaths.push(`agents.list.${entry.id}.sandbox.docker`);return configuredPaths.length===0||findings.push({checkId:`sandbox.docker_config_mode_off`,severity:`warn`,title:`Sandbox docker settings configured while sandbox mode is off`,detail:`These docker settings will not take effect until sandbox mode is enabled:
|
|
2
2
|
`+configuredPaths.map(entry=>`- ${entry}`).join(`
|
|
3
3
|
`),remediation:'Enable sandbox mode (`agents.defaults.sandbox.mode="non-main"` or `"all"`) where needed, or remove unused docker settings.'}),findings}function collectSandboxDangerousConfigFindings(cfg){let findings=[],agents=Array.isArray(cfg.agents?.list)?cfg.agents.list:[],configs=[],defaultDocker=cfg.agents?.defaults?.sandbox?.docker;defaultDocker&&typeof defaultDocker==`object`&&configs.push({source:`agents.defaults.sandbox.docker`,docker:defaultDocker});for(let entry of agents){if(!entry||typeof entry!=`object`||typeof entry.id!=`string`)continue;let agentDocker=entry.sandbox?.docker;agentDocker&&typeof agentDocker==`object`&&configs.push({source:`agents.list.${entry.id}.sandbox.docker`,docker:agentDocker})}for(let{source,docker}of configs){let binds=Array.isArray(docker.binds)?docker.binds:[];for(let bind of binds){if(typeof bind!=`string`)continue;let blocked=getBlockedBindReason(bind);if(!blocked)continue;if(blocked.kind===`non_absolute`){findings.push({checkId:`sandbox.bind_mount_non_absolute`,severity:`warn`,title:`Sandbox bind mount uses a non-absolute source path`,detail:`${source}.binds contains "${bind}" which uses source path "${blocked.sourcePath}". Non-absolute bind sources are hard to validate safely and may resolve unexpectedly.`,remediation:`Rewrite "${bind}" to use an absolute host path (for example: /home/user/project:/project:ro).`});continue}let verb=blocked.kind===`covers`?`covers`:`targets`;findings.push({checkId:`sandbox.dangerous_bind_mount`,severity:`critical`,title:`Dangerous bind mount in sandbox config`,detail:`${source}.binds contains "${bind}" which ${verb} blocked path "${blocked.blockedPath}". This can expose host system directories or the Docker socket to sandbox containers.`,remediation:`Remove "${bind}" from ${source}.binds. Use project-specific paths instead.`})}let network=typeof docker.network==`string`?docker.network:void 0;network&&network.trim().toLowerCase()===`host`&&findings.push({checkId:`sandbox.dangerous_network_mode`,severity:`critical`,title:`Network host mode in sandbox config`,detail:`${source}.network is "host" which bypasses container network isolation entirely.`,remediation:`Set ${source}.network to "bridge" or "none".`});let seccompProfile=typeof docker.seccompProfile==`string`?docker.seccompProfile:void 0;seccompProfile&&seccompProfile.trim().toLowerCase()===`unconfined`&&findings.push({checkId:`sandbox.dangerous_seccomp_profile`,severity:`critical`,title:`Seccomp unconfined in sandbox config`,detail:`${source}.seccompProfile is "unconfined" which disables syscall filtering.`,remediation:`Remove ${source}.seccompProfile or use a custom seccomp profile file.`});let apparmorProfile=typeof docker.apparmorProfile==`string`?docker.apparmorProfile:void 0;apparmorProfile&&apparmorProfile.trim().toLowerCase()===`unconfined`&&findings.push({checkId:`sandbox.dangerous_apparmor_profile`,severity:`critical`,title:`AppArmor unconfined in sandbox config`,detail:`${source}.apparmorProfile is "unconfined" which disables AppArmor enforcement.`,remediation:`Remove ${source}.apparmorProfile or use a named AppArmor profile.`})}return findings}function collectNodeDenyCommandPatternFindings(cfg){let findings=[],denyListRaw=cfg.gateway?.nodes?.denyCommands;if(!Array.isArray(denyListRaw)||denyListRaw.length===0)return findings;let denyList=denyListRaw.map(normalizeNodeCommand).filter(Boolean);if(denyList.length===0)return findings;let knownCommands=listKnownNodeCommands(cfg),patternLike=denyList.filter(entry=>looksLikeNodeCommandPattern(entry)),unknownExact=denyList.filter(entry=>!looksLikeNodeCommandPattern(entry)&&!knownCommands.has(entry));if(patternLike.length===0&&unknownExact.length===0)return findings;let detailParts=[];patternLike.length>0&&detailParts.push(`Pattern-like entries (not supported by exact matching): ${patternLike.join(`, `)}`),unknownExact.length>0&&detailParts.push(`Unknown command names (not in defaults/allowCommands): ${unknownExact.join(`, `)}`);let examples=Array.from(knownCommands).slice(0,8);return findings.push({checkId:`gateway.nodes.deny_commands_ineffective`,severity:`warn`,title:`Some gateway.nodes.denyCommands entries are ineffective`,detail:`gateway.nodes.denyCommands uses exact command-name matching only.
|
|
4
4
|
`+detailParts.map(entry=>`- ${entry}`).join(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{g as resolveStateDir,m as resolveOAuthDir,o as resolveConfigPath}from"./paths-BHg-VHB4.js";import{t as formatCliCommand}from"./command-format-DTMaGKs7.js";import{d as normalizeAgentId}from"./session-key-CksCYipj.js";import{n as runExec}from"./exec-COgsU9ql.js";import{l as resolveDefaultAgentId}from"./agent-scope-CufEmNj_.js";import{F as INCLUDE_KEY,I as MAX_INCLUDE_DEPTH,L as extensionUsesSkippedScannerPath,R as isPathInside,n as createConfigIO}from"./io-CohJffHG.js";import{c as normalizePluginsConfig}from"./manifest-registry-009gLJ4l.js";import{n as MANIFEST_KEY,t as LEGACY_MANIFEST_KEYS}from"./legacy-names-DloW84CJ.js";import{i as loadWorkspaceSkillEntries}from"./skills-D3MwwPOH.js";import{t as GatewayClient}from"./client-CGgp3zkQ.js";import{t as buildGatewayConnectionDetails}from"./call-DmAU4cRX.js";import{h as GATEWAY_CLIENT_NAMES,m as GATEWAY_CLIENT_MODES}from"./message-channel-z5YRpR2d.js";import{q as normalizeStringEntries}from"./sessions-Bl1wwotX.js";import{n as listChannelPlugins}from"./plugins-1Mn6RiNf.js";import{n as formatErrorMessage}from"./errors-tAt19c1E.js";import{d as resolveSandboxConfigForAgent,l as getBlockedBindReason,p as resolveSandboxToolPolicyForAgent,x as resolveToolProfilePolicy}from"./sandbox-z9t_PRf9.js";import{i as resolveGatewayAuth}from"./auth-ChecwOXS.js";import{a as resolveProfile,i as resolveBrowserConfig,m as resolveBrowserControlAuth}from"./server-context-owOmmyUM.js";import{c as resolveNativeCommandsEnabled,l as resolveNativeSkillsEnabled,n as isToolAllowedByPolicies,o as pickSandboxToolPolicy,u as listAgentWorkspaceDirs}from"./coding-tools.policy-NEPm7Mz1.js";import{i as readChannelAllowFromStore}from"./pairing-store-QDb6lhIU.js";import{n as DEFAULT_GATEWAY_HTTP_TOOL_DENY}from"./dangerous-tools-C0tOMmbD.js";import{t as resolveChannelDefaultAccountId}from"./helpers-DPPVplyk.js";import{t as scanDirectoryWithSummary}from"./skill-scanner-DEmbPsRh.js";import{n as isNumericTelegramUserId,r as normalizeTelegramAllowFromEntry,t as resolveDmAllowState}from"./dm-policy-shared-CRZpjRv0.js";import{t as inferParamBFromIdOrName}from"./model-param-b-B8jBqz40.js";import os from"node:os";import path from"node:path";import{randomUUID}from"node:crypto";import JSON5 from"json5";import*as fs$1 from"node:fs/promises";import fs from"node:fs/promises";async function probeGateway(opts){let startedAt=Date.now(),instanceId=randomUUID(),connectLatencyMs=null,connectError=null,close=null;return await new Promise(resolve=>{let settled=!1,settle=result=>{settled||(settled=!0,clearTimeout(timer),client.stop(),resolve({url:opts.url,...result}))},client=new GatewayClient({url:opts.url,token:opts.auth?.token,password:opts.auth?.password,clientName:GATEWAY_CLIENT_NAMES.CLI,clientVersion:`dev`,mode:GATEWAY_CLIENT_MODES.PROBE,instanceId,onConnectError:err=>{connectError=formatErrorMessage(err)},onClose:(code,reason)=>{close={code,reason}},onHelloOk:async()=>{connectLatencyMs=Date.now()-startedAt;try{let[health,status,presence,configSnapshot]=await Promise.all([client.request(`health`),client.request(`status`),client.request(`system-presence`),client.request(`config.get`,{})]);settle({ok:!0,connectLatencyMs,error:null,close,health,status,presence:Array.isArray(presence)?presence:null,configSnapshot})}catch(err){settle({ok:!1,connectLatencyMs,error:formatErrorMessage(err),close,health:null,status:null,presence:null,configSnapshot:null})}}}),timer=setTimeout(()=>{settle({ok:!1,connectLatencyMs,error:connectError?`connect failed: ${connectError}`:`timeout`,close,health:null,status:null,presence:null,configSnapshot:null})},Math.max(250,opts.timeoutMs));client.start()})}const CANVAS_COMMANDS=[`canvas.present`,`canvas.hide`,`canvas.navigate`,`canvas.eval`,`canvas.snapshot`,`canvas.a2ui.push`,`canvas.a2ui.pushJSONL`,`canvas.a2ui.reset`],CAMERA_COMMANDS=[`camera.list`],CAMERA_DANGEROUS_COMMANDS=[`camera.snap`,`camera.clip`],SCREEN_DANGEROUS_COMMANDS=[`screen.record`],LOCATION_COMMANDS=[`location.get`],DEVICE_COMMANDS=[`device.info`,`device.status`],CONTACTS_COMMANDS=[`contacts.search`],CONTACTS_DANGEROUS_COMMANDS=[`contacts.add`],CALENDAR_COMMANDS=[`calendar.events`],CALENDAR_DANGEROUS_COMMANDS=[`calendar.add`],REMINDERS_COMMANDS=[`reminders.list`],REMINDERS_DANGEROUS_COMMANDS=[`reminders.add`],PHOTOS_COMMANDS=[`photos.latest`],MOTION_COMMANDS=[`motion.activity`,`motion.pedometer`],SMS_DANGEROUS_COMMANDS=[`sms.send`],IOS_SYSTEM_COMMANDS=[`system.notify`],SYSTEM_COMMANDS=[`system.run`,`system.which`,`system.notify`,`browser.proxy`];[...CAMERA_DANGEROUS_COMMANDS,...SCREEN_DANGEROUS_COMMANDS,...CONTACTS_DANGEROUS_COMMANDS,...CALENDAR_DANGEROUS_COMMANDS,...REMINDERS_DANGEROUS_COMMANDS,...SMS_DANGEROUS_COMMANDS];const PLATFORM_DEFAULTS={ios:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...DEVICE_COMMANDS,...CONTACTS_COMMANDS,...CALENDAR_COMMANDS,...REMINDERS_COMMANDS,...PHOTOS_COMMANDS,...MOTION_COMMANDS,...IOS_SYSTEM_COMMANDS],android:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...DEVICE_COMMANDS,...CONTACTS_COMMANDS,...CALENDAR_COMMANDS,...REMINDERS_COMMANDS,...PHOTOS_COMMANDS,...MOTION_COMMANDS],macos:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...DEVICE_COMMANDS,...CONTACTS_COMMANDS,...CALENDAR_COMMANDS,...REMINDERS_COMMANDS,...PHOTOS_COMMANDS,...MOTION_COMMANDS,...SYSTEM_COMMANDS],linux:[...SYSTEM_COMMANDS],windows:[...SYSTEM_COMMANDS],unknown:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...SYSTEM_COMMANDS]};function normalizePlatformId(platform,deviceFamily){let raw=(platform??``).trim().toLowerCase();if(raw.startsWith(`ios`))return`ios`;if(raw.startsWith(`android`))return`android`;if(raw.startsWith(`mac`)||raw.startsWith(`darwin`))return`macos`;if(raw.startsWith(`win`))return`windows`;if(raw.startsWith(`linux`))return`linux`;let family=(deviceFamily??``).trim().toLowerCase();return family.includes(`iphone`)||family.includes(`ipad`)||family.includes(`ios`)?`ios`:family.includes(`android`)?`android`:family.includes(`mac`)?`macos`:family.includes(`windows`)?`windows`:family.includes(`linux`)?`linux`:`unknown`}function resolveNodeCommandAllowlist(cfg,node){let base=PLATFORM_DEFAULTS[normalizePlatformId(node?.platform,node?.deviceFamily)]??PLATFORM_DEFAULTS.unknown,extra=cfg.gateway?.nodes?.allowCommands??[],deny=new Set(cfg.gateway?.nodes?.denyCommands??[]),allow=new Set([...base,...extra].map(cmd=>cmd.trim()).filter(Boolean));for(let blocked of deny){let trimmed=blocked.trim();trimmed&&allow.delete(trimmed)}return allow}function isNodeCommandAllowed(params){let command=params.command.trim();if(!command)return{ok:!1,reason:`command required`};if(!params.allowlist.has(command))return{ok:!1,reason:`command not allowlisted`};if(Array.isArray(params.declaredCommands)&¶ms.declaredCommands.length>0){if(!params.declaredCommands.includes(command))return{ok:!1,reason:`command not declared by node`}}else return{ok:!1,reason:`node did not declare commands`};return{ok:!0}}function resolveGatewayProbeAuth(params){let env=params.env??process.env,authToken=params.cfg.gateway?.auth?.token,authPassword=params.cfg.gateway?.auth?.password,remote=params.cfg.gateway?.remote;return{token:params.mode===`remote`?typeof remote?.token==`string`&&remote.token.trim()?remote.token.trim():void 0:env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN?.trim()||(typeof authToken==`string`&&authToken.trim()?authToken.trim():void 0),password:env.BUILDERFORCE_AGENTS_GATEWAY_PASSWORD?.trim()||(params.mode===`remote`?typeof remote?.password==`string`&&remote.password.trim()?remote.password.trim():void 0:typeof authPassword==`string`&&authPassword.trim()?authPassword.trim():void 0)}}function normalizeAllowFromList$1(list){return normalizeStringEntries(Array.isArray(list)?list:void 0)}function classifyChannelWarningSeverity(message){let s=message.toLowerCase();return s.includes(`dms: open`)||s.includes(`grouppolicy="open"`)||s.includes(`dmpolicy="open"`)||s.includes(`allows any`)||s.includes(`anyone can dm`)||s.includes(`public`)?`critical`:s.includes(`locked`)||s.includes(`disabled`)?`info`:`warn`}async function collectChannelSecurityFindings(params){let findings=[],coerceNativeSetting=value=>{if(value===!0)return!0;if(value===!1)return!1;if(value===`auto`)return`auto`},warnDmPolicy=async input=>{let policyPath=input.policyPath??`${input.allowFromPath}policy`,{hasWildcard,isMultiUserDm}=await resolveDmAllowState({provider:input.provider,allowFrom:input.allowFrom,normalizeEntry:input.normalizeEntry}),dmScope=params.cfg.session?.dmScope??`main`;if(input.dmPolicy===`open`){let allowFromKey=`${input.allowFromPath}allowFrom`;findings.push({checkId:`channels.${input.provider}.dm.open`,severity:`critical`,title:`${input.label} DMs are open`,detail:`${policyPath}="open" allows anyone to DM the bot.`,remediation:`Use pairing/allowlist; if you really need open DMs, ensure ${allowFromKey} includes "*".`}),hasWildcard||findings.push({checkId:`channels.${input.provider}.dm.open_invalid`,severity:`warn`,title:`${input.label} DM config looks inconsistent`,detail:`"open" requires ${allowFromKey} to include "*".`})}if(input.dmPolicy===`disabled`){findings.push({checkId:`channels.${input.provider}.dm.disabled`,severity:`info`,title:`${input.label} DMs are disabled`,detail:`${policyPath}="disabled" ignores inbound DMs.`});return}dmScope===`main`&&isMultiUserDm&&findings.push({checkId:`channels.${input.provider}.dm.scope_main_multiuser`,severity:`warn`,title:`${input.label} DMs share the main session`,detail:`Multiple DM senders currently share the main session, which can leak context across users.`,remediation:`Run: `+formatCliCommand(`builderforce config set session.dmScope "per-channel-peer"`)+` (or "per-account-channel-peer" for multi-account channels) to isolate DM sessions per sender.`})};for(let plugin of params.plugins){if(!plugin.security)continue;let accountIds=plugin.config.listAccountIds(params.cfg),defaultAccountId=resolveChannelDefaultAccountId({plugin,cfg:params.cfg,accountIds}),account=plugin.config.resolveAccount(params.cfg,defaultAccountId);if(!(!plugin.config.isEnabled||plugin.config.isEnabled(account,params.cfg))||!(!plugin.config.isConfigured||await plugin.config.isConfigured(account,params.cfg)))continue;if(plugin.id===`discord`){let discordCfg=account?.config??{},nativeEnabled=resolveNativeCommandsEnabled({providerId:`discord`,providerSetting:coerceNativeSetting(discordCfg.commands?.native),globalSetting:params.cfg.commands?.native}),nativeSkillsEnabled=resolveNativeSkillsEnabled({providerId:`discord`,providerSetting:coerceNativeSetting(discordCfg.commands?.nativeSkills),globalSetting:params.cfg.commands?.nativeSkills});if(nativeEnabled||nativeSkillsEnabled){let defaultGroupPolicy=params.cfg.channels?.defaults?.groupPolicy,groupPolicy=discordCfg.groupPolicy??defaultGroupPolicy??`allowlist`,guildEntries=discordCfg.guilds??{},guildsConfigured=Object.keys(guildEntries).length>0,hasAnyUserAllowlist=Object.values(guildEntries).some(guild=>{if(!guild||typeof guild!=`object`)return!1;let g=guild;if(Array.isArray(g.users)&&g.users.length>0)return!0;let channels=g.channels;return!channels||typeof channels!=`object`?!1:Object.values(channels).some(channel=>{if(!channel||typeof channel!=`object`)return!1;let c=channel;return Array.isArray(c.users)&&c.users.length>0})}),dmAllowFromRaw=discordCfg.dm?.allowFrom,dmAllowFrom=Array.isArray(dmAllowFromRaw)?dmAllowFromRaw:[],storeAllowFrom=await readChannelAllowFromStore(`discord`).catch(()=>[]),ownerAllowFromConfigured=normalizeAllowFromList$1([...dmAllowFrom,...storeAllowFrom]).length>0,useAccessGroups=params.cfg.commands?.useAccessGroups!==!1;!useAccessGroups&&groupPolicy!==`disabled`&&guildsConfigured&&!hasAnyUserAllowlist?findings.push({checkId:`channels.discord.commands.native.unrestricted`,severity:`critical`,title:`Discord slash commands are unrestricted`,detail:`commands.useAccessGroups=false disables sender allowlists for Discord slash commands unless a per-guild/channel users allowlist is configured; with no users allowlist, any user in allowed guild channels can invoke /… commands.`,remediation:`Set commands.useAccessGroups=true (recommended), or configure channels.discord.guilds.<id>.users (or channels.discord.guilds.<id>.channels.<channel>.users).`}):useAccessGroups&&groupPolicy!==`disabled`&&guildsConfigured&&!ownerAllowFromConfigured&&!hasAnyUserAllowlist&&findings.push({checkId:`channels.discord.commands.native.no_allowlists`,severity:`warn`,title:`Discord slash commands have no allowlists`,detail:`Discord slash commands are enabled, but neither an owner allowFrom list nor any per-guild/channel users allowlist is configured; /… commands will be rejected for everyone.`,remediation:`Add your user id to channels.discord.allowFrom (or approve yourself via pairing), or configure channels.discord.guilds.<id>.users.`})}}if(plugin.id===`slack`){let slackCfg=account?.config??{},nativeEnabled=resolveNativeCommandsEnabled({providerId:`slack`,providerSetting:coerceNativeSetting(slackCfg.commands?.native),globalSetting:params.cfg.commands?.native}),nativeSkillsEnabled=resolveNativeSkillsEnabled({providerId:`slack`,providerSetting:coerceNativeSetting(slackCfg.commands?.nativeSkills),globalSetting:params.cfg.commands?.nativeSkills});if(nativeEnabled||nativeSkillsEnabled||slackCfg.slashCommand?.enabled===!0)if(params.cfg.commands?.useAccessGroups===!1)findings.push({checkId:`channels.slack.commands.slash.useAccessGroups_off`,severity:`critical`,title:`Slack slash commands bypass access groups`,detail:`Slack slash/native commands are enabled while commands.useAccessGroups=false; this can allow unrestricted /… command execution from channels/users you didn't explicitly authorize.`,remediation:`Set commands.useAccessGroups=true (recommended).`});else{let allowFromRaw=account?.config?.allowFrom,legacyAllowFromRaw=account?.dm?.allowFrom,allowFrom=Array.isArray(allowFromRaw)?allowFromRaw:Array.isArray(legacyAllowFromRaw)?legacyAllowFromRaw:[],storeAllowFrom=await readChannelAllowFromStore(`slack`).catch(()=>[]),ownerAllowFromConfigured=normalizeAllowFromList$1([...allowFrom,...storeAllowFrom]).length>0,channels=slackCfg.channels??{},hasAnyChannelUsersAllowlist=Object.values(channels).some(value=>{if(!value||typeof value!=`object`)return!1;let channel=value;return Array.isArray(channel.users)&&channel.users.length>0});!ownerAllowFromConfigured&&!hasAnyChannelUsersAllowlist&&findings.push({checkId:`channels.slack.commands.slash.no_allowlists`,severity:`warn`,title:`Slack slash commands have no allowlists`,detail:`Slack slash/native commands are enabled, but neither an owner allowFrom list nor any channels.<id>.users allowlist is configured; /… commands will be rejected for everyone.`,remediation:`Approve yourself via pairing (recommended), or set channels.slack.allowFrom and/or channels.slack.channels.<id>.users.`})}}let dmPolicy=plugin.security.resolveDmPolicy?.({cfg:params.cfg,accountId:defaultAccountId,account});if(dmPolicy&&await warnDmPolicy({label:plugin.meta.label??plugin.id,provider:plugin.id,dmPolicy:dmPolicy.policy,allowFrom:dmPolicy.allowFrom,policyPath:dmPolicy.policyPath,allowFromPath:dmPolicy.allowFromPath,normalizeEntry:dmPolicy.normalizeEntry}),plugin.security.collectWarnings){let warnings=await plugin.security.collectWarnings({cfg:params.cfg,accountId:defaultAccountId,account});for(let message of warnings??[]){let trimmed=String(message).trim();trimmed&&findings.push({checkId:`channels.${plugin.id}.warning.${findings.length+1}`,severity:classifyChannelWarningSeverity(trimmed),title:`${plugin.meta.label??plugin.id} security warning`,detail:trimmed.replace(/^-\s*/,``)})}}if(plugin.id===`telegram`){if(params.cfg.commands?.text===!1)continue;let telegramCfg=account?.config??{},defaultGroupPolicy=params.cfg.channels?.defaults?.groupPolicy,groupPolicy=telegramCfg.groupPolicy??defaultGroupPolicy??`allowlist`,groups=telegramCfg.groups,groupsConfigured=!!groups&&Object.keys(groups??{}).length>0;if(!(groupPolicy===`open`||groupPolicy===`allowlist`&&groupsConfigured))continue;let storeAllowFrom=await readChannelAllowFromStore(`telegram`).catch(()=>[]),storeHasWildcard=storeAllowFrom.some(v=>String(v).trim()===`*`),invalidTelegramAllowFromEntries=new Set;for(let entry of storeAllowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}let groupAllowFrom=Array.isArray(telegramCfg.groupAllowFrom)?telegramCfg.groupAllowFrom:[],groupAllowFromHasWildcard=groupAllowFrom.some(v=>String(v).trim()===`*`);for(let entry of groupAllowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}let dmAllowFrom=Array.isArray(telegramCfg.allowFrom)?telegramCfg.allowFrom:[];for(let entry of dmAllowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}let anyGroupOverride=!!(groups&&Object.values(groups).some(value=>{if(!value||typeof value!=`object`)return!1;let group=value,allowFrom=Array.isArray(group.allowFrom)?group.allowFrom:[];if(allowFrom.length>0){for(let entry of allowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}return!0}let topics=group.topics;return!topics||typeof topics!=`object`?!1:Object.values(topics).some(topicValue=>{if(!topicValue||typeof topicValue!=`object`)return!1;let topic=topicValue,topicAllow=Array.isArray(topic.allowFrom)?topic.allowFrom:[];for(let entry of topicAllow){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}return topicAllow.length>0})})),hasAnySenderAllowlist=storeAllowFrom.length>0||groupAllowFrom.length>0||anyGroupOverride;if(invalidTelegramAllowFromEntries.size>0){let examples=Array.from(invalidTelegramAllowFromEntries).slice(0,5),more=invalidTelegramAllowFromEntries.size>examples.length?` (+${invalidTelegramAllowFromEntries.size-examples.length} more)`:``;findings.push({checkId:`channels.telegram.allowFrom.invalid_entries`,severity:`warn`,title:`Telegram allowlist contains non-numeric entries`,detail:`Telegram sender authorization requires numeric Telegram user IDs. Found non-numeric allowFrom entries: ${examples.join(`, `)}${more}.`,remediation:`Replace @username entries with numeric Telegram user IDs (use onboarding to resolve), then re-run the audit.`})}if(storeHasWildcard||groupAllowFromHasWildcard){findings.push({checkId:`channels.telegram.groups.allowFrom.wildcard`,severity:`critical`,title:`Telegram group allowlist contains wildcard`,detail:`Telegram group sender allowlist contains "*", which allows any group member to run /… commands and control directives.`,remediation:`Remove "*" from channels.telegram.groupAllowFrom and pairing store; prefer explicit numeric Telegram user IDs.`});continue}if(!hasAnySenderAllowlist){let providerSetting=telegramCfg.commands?.nativeSkills,skillsEnabled=resolveNativeSkillsEnabled({providerId:`telegram`,providerSetting,globalSetting:params.cfg.commands?.nativeSkills});findings.push({checkId:`channels.telegram.groups.allowFrom.missing`,severity:`critical`,title:`Telegram group commands have no sender allowlist`,detail:`Telegram group access is enabled but no sender allowlist is configured; this allows any group member to invoke /… commands`+(skillsEnabled?` (including skill commands).`:`.`),remediation:`Approve yourself via pairing (recommended), or set channels.telegram.groupAllowFrom (or per-group groups.<id>.allowFrom).`})}}}return findings}function summarizeGroupPolicy(cfg){let channels=cfg.channels;if(!channels||typeof channels!=`object`)return{open:0,allowlist:0,other:0};let open=0,allowlist=0,other=0;for(let value of Object.values(channels)){if(!value||typeof value!=`object`)continue;let policy=value.groupPolicy;policy===`open`?open+=1:policy===`allowlist`?allowlist+=1:other+=1}return{open,allowlist,other}}function isProbablySyncedPath(p){let s=p.toLowerCase();return s.includes(`icloud`)||s.includes(`dropbox`)||s.includes(`google drive`)||s.includes(`googledrive`)||s.includes(`onedrive`)}function looksLikeEnvRef(value){let v=value.trim();return v.startsWith("${")&&v.endsWith(`}`)}function isGatewayRemotelyExposed(cfg){if((typeof cfg.gateway?.bind==`string`?cfg.gateway.bind:`loopback`)!==`loopback`)return!0;let tailscaleMode=cfg.gateway?.tailscale?.mode??`off`;return tailscaleMode===`serve`||tailscaleMode===`funnel`}function addModel(models,raw,source){if(typeof raw!=`string`)return;let id=raw.trim();id&&models.push({id,source})}function collectModels(cfg){let out=[];addModel(out,cfg.agents?.defaults?.model?.primary,`agents.defaults.model.primary`);for(let f of cfg.agents?.defaults?.model?.fallbacks??[])addModel(out,f,`agents.defaults.model.fallbacks`);addModel(out,cfg.agents?.defaults?.imageModel?.primary,`agents.defaults.imageModel.primary`);for(let f of cfg.agents?.defaults?.imageModel?.fallbacks??[])addModel(out,f,`agents.defaults.imageModel.fallbacks`);let list=Array.isArray(cfg.agents?.list)?cfg.agents?.list:[];for(let agent of list??[]){if(!agent||typeof agent!=`object`)continue;let id=typeof agent.id==`string`?agent.id:``,model=agent.model;if(typeof model==`string`)addModel(out,model,`agents.list.${id}.model`);else if(model&&typeof model==`object`){addModel(out,model.primary,`agents.list.${id}.model.primary`);let fallbacks=model.fallbacks;if(Array.isArray(fallbacks))for(let f of fallbacks)addModel(out,f,`agents.list.${id}.model.fallbacks`)}}return out}const LEGACY_MODEL_PATTERNS=[{id:`openai.gpt35`,re:/\bgpt-3\.5\b/i,label:`GPT-3.5 family`},{id:`anthropic.claude2`,re:/\bclaude-(instant|2)\b/i,label:`Claude 2/Instant family`},{id:`openai.gpt4_legacy`,re:/\bgpt-4-(0314|0613)\b/i,label:`Legacy GPT-4 snapshots`}],WEAK_TIER_MODEL_PATTERNS=[{id:`anthropic.haiku`,re:/\bhaiku\b/i,label:`Haiku tier (smaller model)`}];function isGptModel(id){return/\bgpt-/i.test(id)}function isGpt5OrHigher(id){return/\bgpt-5(?:\b|[.-])/i.test(id)}function isClaudeModel(id){return/\bclaude-/i.test(id)}function isClaude45OrHigher(id){return/\bclaude-[^\s/]*?(?:-4-?(?:[5-9]|[1-9]\d)\b|4\.(?:[5-9]|[1-9]\d)\b|-[5-9](?:\b|[.-]))/i.test(id)}function extractAgentIdFromSource(source){return source.match(/^agents\.list\.([^.]*)\./)?.[1]??null}function hasConfiguredDockerConfig(docker){return!docker||typeof docker!=`object`?!1:Object.values(docker).some(value=>value!==void 0)}function normalizeNodeCommand(value){return typeof value==`string`?value.trim():``}function listKnownNodeCommands(cfg){let baseCfg={...cfg,gateway:{...cfg.gateway,nodes:{...cfg.gateway?.nodes,denyCommands:[]}}},out=new Set;for(let platform of[`ios`,`android`,`macos`,`linux`,`windows`,`unknown`]){let allow=resolveNodeCommandAllowlist(baseCfg,{platform});for(let cmd of allow){let normalized=normalizeNodeCommand(cmd);normalized&&out.add(normalized)}}return out}function looksLikeNodeCommandPattern(value){return value?/[?*[\]{}(),|]/.test(value)||value.startsWith(`/`)||value.endsWith(`/`)||value.startsWith(`^`)||value.endsWith(`$`)?!0:/\s/.test(value)||value.includes(`group:`):!1}function resolveToolPolicies$1(params){let policies=[],profilePolicy=resolveToolProfilePolicy(params.agentTools?.profile??params.cfg.tools?.profile);profilePolicy&&policies.push(profilePolicy);let globalPolicy=pickSandboxToolPolicy(params.cfg.tools??void 0);globalPolicy&&policies.push(globalPolicy);let agentPolicy=pickSandboxToolPolicy(params.agentTools);if(agentPolicy&&policies.push(agentPolicy),params.sandboxMode===`all`){let sandboxPolicy=resolveSandboxToolPolicyForAgent(params.cfg,params.agentId??void 0);policies.push(sandboxPolicy)}return policies}function hasWebSearchKey(cfg,env){let search=cfg.tools?.web?.search;return!!(search?.apiKey||search?.perplexity?.apiKey||env.BRAVE_API_KEY||env.PERPLEXITY_API_KEY||env.OPENROUTER_API_KEY)}function isWebSearchEnabled(cfg,env){let enabled=cfg.tools?.web?.search?.enabled;return enabled===!1?!1:enabled===!0?!0:hasWebSearchKey(cfg,env)}function isWebFetchEnabled(cfg){return cfg.tools?.web?.fetch?.enabled!==!1}function isBrowserEnabled(cfg){try{return resolveBrowserConfig(cfg.browser,cfg).enabled}catch{return!0}}function listGroupPolicyOpen(cfg){let out=[],channels=cfg.channels;if(!channels||typeof channels!=`object`)return out;for(let[channelId,value]of Object.entries(channels)){if(!value||typeof value!=`object`)continue;let section=value;section.groupPolicy===`open`&&out.push(`channels.${channelId}.groupPolicy`);let accounts=section.accounts;if(accounts&&typeof accounts==`object`)for(let[accountId,accountVal]of Object.entries(accounts))!accountVal||typeof accountVal!=`object`||accountVal.groupPolicy===`open`&&out.push(`channels.${channelId}.accounts.${accountId}.groupPolicy`)}return out}function collectAttackSurfaceSummaryFindings(cfg){let group=summarizeGroupPolicy(cfg),elevated=cfg.tools?.elevated?.enabled!==!1,webhooksEnabled=cfg.hooks?.enabled===!0,internalHooksEnabled=cfg.hooks?.internal?.enabled===!0,browserEnabled=cfg.browser?.enabled??!0;return[{checkId:`summary.attack_surface`,severity:`info`,title:`Attack surface summary`,detail:`groups: open=${group.open}, allowlist=${group.allowlist}\ntools.elevated: ${elevated?`enabled`:`disabled`}\nhooks.webhooks: ${webhooksEnabled?`enabled`:`disabled`}\nhooks.internal: ${internalHooksEnabled?`enabled`:`disabled`}\nbrowser control: ${browserEnabled?`enabled`:`disabled`}`}]}function collectSyncedFolderFindings(params){let findings=[];return(isProbablySyncedPath(params.stateDir)||isProbablySyncedPath(params.configPath))&&findings.push({checkId:`fs.synced_dir`,severity:`warn`,title:`State/config path looks like a synced folder`,detail:`stateDir=${params.stateDir}, configPath=${params.configPath}. Synced folders (iCloud/Dropbox/OneDrive/Google Drive) can leak tokens and transcripts onto other devices.`,remediation:`Keep BUILDERFORCE_AGENTS_STATE_DIR on a local-only volume and re-run "${formatCliCommand(`builderforce security audit --fix`)}".`}),findings}function collectSecretsInConfigFindings(cfg){let findings=[],password=typeof cfg.gateway?.auth?.password==`string`?cfg.gateway.auth.password.trim():``;password&&!looksLikeEnvRef(password)&&findings.push({checkId:`config.secrets.gateway_password_in_config`,severity:`warn`,title:`Gateway password is stored in config`,detail:`gateway.auth.password is set in the config file; prefer environment variables for secrets when possible.`,remediation:`Prefer BUILDERFORCE_AGENTS_GATEWAY_PASSWORD (env) and remove gateway.auth.password from disk.`});let hooksToken=typeof cfg.hooks?.token==`string`?cfg.hooks.token.trim():``;return cfg.hooks?.enabled===!0&&hooksToken&&!looksLikeEnvRef(hooksToken)&&findings.push({checkId:`config.secrets.hooks_token_in_config`,severity:`info`,title:`Hooks token is stored in config`,detail:`hooks.token is set in the config file; keep config perms tight and treat it like an API secret.`}),findings}function collectHooksHardeningFindings(cfg,env=process.env){let findings=[];if(cfg.hooks?.enabled!==!0)return findings;let token=typeof cfg.hooks?.token==`string`?cfg.hooks.token.trim():``;token&&token.length<24&&findings.push({checkId:`hooks.token_too_short`,severity:`warn`,title:`Hooks token looks short`,detail:`hooks.token is ${token.length} chars; prefer a long random token.`});let gatewayAuth=resolveGatewayAuth({authConfig:cfg.gateway?.auth,tailscaleMode:cfg.gateway?.tailscale?.mode??`off`,env}),builderforceGatewayToken=typeof env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN==`string`&&env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN.trim()?env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN.trim():null,gatewayToken=gatewayAuth.mode===`token`&&typeof gatewayAuth.token==`string`&&gatewayAuth.token.trim()?gatewayAuth.token.trim():builderforceGatewayToken||null;token&&gatewayToken&&token===gatewayToken&&findings.push({checkId:`hooks.token_reuse_gateway_token`,severity:`warn`,title:`Hooks token reuses the Gateway token`,detail:`hooks.token matches gateway.auth token; compromise of hooks expands blast radius to the Gateway API.`,remediation:`Use a separate hooks.token dedicated to hook ingress.`}),(typeof cfg.hooks?.path==`string`?cfg.hooks.path.trim():``)===`/`&&findings.push({checkId:`hooks.path_root`,severity:`critical`,title:`Hooks base path is '/'`,detail:`hooks.path='/' would shadow other HTTP endpoints and is unsafe.`,remediation:`Use a dedicated path like '/hooks'.`});let allowRequestSessionKey=cfg.hooks?.allowRequestSessionKey===!0,defaultSessionKey=typeof cfg.hooks?.defaultSessionKey==`string`?cfg.hooks.defaultSessionKey.trim():``,allowedPrefixes=Array.isArray(cfg.hooks?.allowedSessionKeyPrefixes)?cfg.hooks.allowedSessionKeyPrefixes.map(prefix=>prefix.trim()).filter(prefix=>prefix.length>0):[],remoteExposure=isGatewayRemotelyExposed(cfg);return defaultSessionKey||findings.push({checkId:`hooks.default_session_key_unset`,severity:`warn`,title:`hooks.defaultSessionKey is not configured`,detail:`Hook agent runs without explicit sessionKey use generated per-request keys. Set hooks.defaultSessionKey to keep hook ingress scoped to a known session.`,remediation:`Set hooks.defaultSessionKey (for example, "hook:ingress").`}),allowRequestSessionKey&&findings.push({checkId:`hooks.request_session_key_enabled`,severity:remoteExposure?`critical`:`warn`,title:`External hook payloads may override sessionKey`,detail:"hooks.allowRequestSessionKey=true allows `/hooks/agent` callers to choose the session key. Treat hook token holders as full-trust unless you also restrict prefixes.",remediation:`Set hooks.allowRequestSessionKey=false (recommended) or constrain hooks.allowedSessionKeyPrefixes.`}),allowRequestSessionKey&&allowedPrefixes.length===0&&findings.push({checkId:`hooks.request_session_key_prefixes_missing`,severity:remoteExposure?`critical`:`warn`,title:`Request sessionKey override is enabled without prefix restrictions`,detail:`hooks.allowRequestSessionKey=true and hooks.allowedSessionKeyPrefixes is unset/empty, so request payloads can target arbitrary session key shapes.`,remediation:`Set hooks.allowedSessionKeyPrefixes (for example, ["hook:"]) or disable request overrides.`}),findings}function collectGatewayHttpSessionKeyOverrideFindings(cfg){let findings=[],chatCompletionsEnabled=cfg.gateway?.http?.endpoints?.chatCompletions?.enabled===!0,responsesEnabled=cfg.gateway?.http?.endpoints?.responses?.enabled===!0;if(!chatCompletionsEnabled&&!responsesEnabled)return findings;let enabledEndpoints=[chatCompletionsEnabled?`/v1/chat/completions`:null,responsesEnabled?`/v1/responses`:null].filter(entry=>!!entry);return findings.push({checkId:`gateway.http.session_key_override_enabled`,severity:`info`,title:`HTTP API session-key override is enabled`,detail:`${enabledEndpoints.join(`, `)} accept x-builderforce-session-key for per-request session routing. Treat API credential holders as trusted principals.`}),findings}function collectSandboxDockerNoopFindings(cfg){let findings=[],configuredPaths=[],agents=Array.isArray(cfg.agents?.list)?cfg.agents.list:[],defaultsSandbox=cfg.agents?.defaults?.sandbox,hasDefaultDocker=hasConfiguredDockerConfig(defaultsSandbox?.docker),defaultMode=defaultsSandbox?.mode??`off`,hasAnySandboxEnabledAgent=agents.some(entry=>!entry||typeof entry!=`object`||typeof entry.id!=`string`?!1:resolveSandboxConfigForAgent(cfg,entry.id).mode!==`off`);hasDefaultDocker&&defaultMode===`off`&&!hasAnySandboxEnabledAgent&&configuredPaths.push(`agents.defaults.sandbox.docker`);for(let entry of agents)!entry||typeof entry!=`object`||typeof entry.id!=`string`||hasConfiguredDockerConfig(entry.sandbox?.docker)&&resolveSandboxConfigForAgent(cfg,entry.id).mode===`off`&&configuredPaths.push(`agents.list.${entry.id}.sandbox.docker`);return configuredPaths.length===0||findings.push({checkId:`sandbox.docker_config_mode_off`,severity:`warn`,title:`Sandbox docker settings configured while sandbox mode is off`,detail:`These docker settings will not take effect until sandbox mode is enabled:
|
|
1
|
+
import{g as resolveStateDir,m as resolveOAuthDir,o as resolveConfigPath}from"./paths-BHg-VHB4.js";import{t as formatCliCommand}from"./command-format-DTMaGKs7.js";import{d as normalizeAgentId}from"./session-key-CksCYipj.js";import{n as runExec}from"./exec-COgsU9ql.js";import{l as resolveDefaultAgentId}from"./agent-scope-CufEmNj_.js";import{F as INCLUDE_KEY,I as MAX_INCLUDE_DEPTH,L as extensionUsesSkippedScannerPath,R as isPathInside,n as createConfigIO}from"./io-D9hC2aG0.js";import{c as normalizePluginsConfig}from"./manifest-registry-009gLJ4l.js";import{n as MANIFEST_KEY,t as LEGACY_MANIFEST_KEYS}from"./legacy-names-DloW84CJ.js";import{i as loadWorkspaceSkillEntries}from"./skills-D3MwwPOH.js";import{t as GatewayClient}from"./client-CGgp3zkQ.js";import{t as buildGatewayConnectionDetails}from"./call-Du2LiaX6.js";import{h as GATEWAY_CLIENT_NAMES,m as GATEWAY_CLIENT_MODES}from"./message-channel-z5YRpR2d.js";import{q as normalizeStringEntries}from"./sessions-BA8Se_bT.js";import{n as listChannelPlugins}from"./plugins-1Mn6RiNf.js";import{n as formatErrorMessage}from"./errors-tAt19c1E.js";import{d as resolveSandboxConfigForAgent,l as getBlockedBindReason,p as resolveSandboxToolPolicyForAgent,x as resolveToolProfilePolicy}from"./sandbox-DvKMuAXL.js";import{i as resolveGatewayAuth}from"./auth-ChecwOXS.js";import{a as resolveProfile,i as resolveBrowserConfig,m as resolveBrowserControlAuth}from"./server-context-CttALzrW.js";import{c as resolveNativeCommandsEnabled,l as resolveNativeSkillsEnabled,n as isToolAllowedByPolicies,o as pickSandboxToolPolicy,u as listAgentWorkspaceDirs}from"./coding-tools.policy-D9Ba8eDh.js";import{i as readChannelAllowFromStore}from"./pairing-store-YRy7EBgI.js";import{n as DEFAULT_GATEWAY_HTTP_TOOL_DENY}from"./dangerous-tools-C0tOMmbD.js";import{t as resolveChannelDefaultAccountId}from"./helpers-DPPVplyk.js";import{t as scanDirectoryWithSummary}from"./skill-scanner-OTLeRZ_p.js";import{n as isNumericTelegramUserId,r as normalizeTelegramAllowFromEntry,t as resolveDmAllowState}from"./dm-policy-shared-B9lW-AsK.js";import{t as inferParamBFromIdOrName}from"./model-param-b-B8jBqz40.js";import os from"node:os";import path from"node:path";import{randomUUID}from"node:crypto";import JSON5 from"json5";import*as fs$1 from"node:fs/promises";import fs from"node:fs/promises";async function probeGateway(opts){let startedAt=Date.now(),instanceId=randomUUID(),connectLatencyMs=null,connectError=null,close=null;return await new Promise(resolve=>{let settled=!1,settle=result=>{settled||(settled=!0,clearTimeout(timer),client.stop(),resolve({url:opts.url,...result}))},client=new GatewayClient({url:opts.url,token:opts.auth?.token,password:opts.auth?.password,clientName:GATEWAY_CLIENT_NAMES.CLI,clientVersion:`dev`,mode:GATEWAY_CLIENT_MODES.PROBE,instanceId,onConnectError:err=>{connectError=formatErrorMessage(err)},onClose:(code,reason)=>{close={code,reason}},onHelloOk:async()=>{connectLatencyMs=Date.now()-startedAt;try{let[health,status,presence,configSnapshot]=await Promise.all([client.request(`health`),client.request(`status`),client.request(`system-presence`),client.request(`config.get`,{})]);settle({ok:!0,connectLatencyMs,error:null,close,health,status,presence:Array.isArray(presence)?presence:null,configSnapshot})}catch(err){settle({ok:!1,connectLatencyMs,error:formatErrorMessage(err),close,health:null,status:null,presence:null,configSnapshot:null})}}}),timer=setTimeout(()=>{settle({ok:!1,connectLatencyMs,error:connectError?`connect failed: ${connectError}`:`timeout`,close,health:null,status:null,presence:null,configSnapshot:null})},Math.max(250,opts.timeoutMs));client.start()})}const CANVAS_COMMANDS=[`canvas.present`,`canvas.hide`,`canvas.navigate`,`canvas.eval`,`canvas.snapshot`,`canvas.a2ui.push`,`canvas.a2ui.pushJSONL`,`canvas.a2ui.reset`],CAMERA_COMMANDS=[`camera.list`],CAMERA_DANGEROUS_COMMANDS=[`camera.snap`,`camera.clip`],SCREEN_DANGEROUS_COMMANDS=[`screen.record`],LOCATION_COMMANDS=[`location.get`],DEVICE_COMMANDS=[`device.info`,`device.status`],CONTACTS_COMMANDS=[`contacts.search`],CONTACTS_DANGEROUS_COMMANDS=[`contacts.add`],CALENDAR_COMMANDS=[`calendar.events`],CALENDAR_DANGEROUS_COMMANDS=[`calendar.add`],REMINDERS_COMMANDS=[`reminders.list`],REMINDERS_DANGEROUS_COMMANDS=[`reminders.add`],PHOTOS_COMMANDS=[`photos.latest`],MOTION_COMMANDS=[`motion.activity`,`motion.pedometer`],SMS_DANGEROUS_COMMANDS=[`sms.send`],IOS_SYSTEM_COMMANDS=[`system.notify`],SYSTEM_COMMANDS=[`system.run`,`system.which`,`system.notify`,`browser.proxy`];[...CAMERA_DANGEROUS_COMMANDS,...SCREEN_DANGEROUS_COMMANDS,...CONTACTS_DANGEROUS_COMMANDS,...CALENDAR_DANGEROUS_COMMANDS,...REMINDERS_DANGEROUS_COMMANDS,...SMS_DANGEROUS_COMMANDS];const PLATFORM_DEFAULTS={ios:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...DEVICE_COMMANDS,...CONTACTS_COMMANDS,...CALENDAR_COMMANDS,...REMINDERS_COMMANDS,...PHOTOS_COMMANDS,...MOTION_COMMANDS,...IOS_SYSTEM_COMMANDS],android:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...DEVICE_COMMANDS,...CONTACTS_COMMANDS,...CALENDAR_COMMANDS,...REMINDERS_COMMANDS,...PHOTOS_COMMANDS,...MOTION_COMMANDS],macos:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...DEVICE_COMMANDS,...CONTACTS_COMMANDS,...CALENDAR_COMMANDS,...REMINDERS_COMMANDS,...PHOTOS_COMMANDS,...MOTION_COMMANDS,...SYSTEM_COMMANDS],linux:[...SYSTEM_COMMANDS],windows:[...SYSTEM_COMMANDS],unknown:[...CANVAS_COMMANDS,...CAMERA_COMMANDS,...LOCATION_COMMANDS,...SYSTEM_COMMANDS]};function normalizePlatformId(platform,deviceFamily){let raw=(platform??``).trim().toLowerCase();if(raw.startsWith(`ios`))return`ios`;if(raw.startsWith(`android`))return`android`;if(raw.startsWith(`mac`)||raw.startsWith(`darwin`))return`macos`;if(raw.startsWith(`win`))return`windows`;if(raw.startsWith(`linux`))return`linux`;let family=(deviceFamily??``).trim().toLowerCase();return family.includes(`iphone`)||family.includes(`ipad`)||family.includes(`ios`)?`ios`:family.includes(`android`)?`android`:family.includes(`mac`)?`macos`:family.includes(`windows`)?`windows`:family.includes(`linux`)?`linux`:`unknown`}function resolveNodeCommandAllowlist(cfg,node){let base=PLATFORM_DEFAULTS[normalizePlatformId(node?.platform,node?.deviceFamily)]??PLATFORM_DEFAULTS.unknown,extra=cfg.gateway?.nodes?.allowCommands??[],deny=new Set(cfg.gateway?.nodes?.denyCommands??[]),allow=new Set([...base,...extra].map(cmd=>cmd.trim()).filter(Boolean));for(let blocked of deny){let trimmed=blocked.trim();trimmed&&allow.delete(trimmed)}return allow}function isNodeCommandAllowed(params){let command=params.command.trim();if(!command)return{ok:!1,reason:`command required`};if(!params.allowlist.has(command))return{ok:!1,reason:`command not allowlisted`};if(Array.isArray(params.declaredCommands)&¶ms.declaredCommands.length>0){if(!params.declaredCommands.includes(command))return{ok:!1,reason:`command not declared by node`}}else return{ok:!1,reason:`node did not declare commands`};return{ok:!0}}function resolveGatewayProbeAuth(params){let env=params.env??process.env,authToken=params.cfg.gateway?.auth?.token,authPassword=params.cfg.gateway?.auth?.password,remote=params.cfg.gateway?.remote;return{token:params.mode===`remote`?typeof remote?.token==`string`&&remote.token.trim()?remote.token.trim():void 0:env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN?.trim()||(typeof authToken==`string`&&authToken.trim()?authToken.trim():void 0),password:env.BUILDERFORCE_AGENTS_GATEWAY_PASSWORD?.trim()||(params.mode===`remote`?typeof remote?.password==`string`&&remote.password.trim()?remote.password.trim():void 0:typeof authPassword==`string`&&authPassword.trim()?authPassword.trim():void 0)}}function normalizeAllowFromList$1(list){return normalizeStringEntries(Array.isArray(list)?list:void 0)}function classifyChannelWarningSeverity(message){let s=message.toLowerCase();return s.includes(`dms: open`)||s.includes(`grouppolicy="open"`)||s.includes(`dmpolicy="open"`)||s.includes(`allows any`)||s.includes(`anyone can dm`)||s.includes(`public`)?`critical`:s.includes(`locked`)||s.includes(`disabled`)?`info`:`warn`}async function collectChannelSecurityFindings(params){let findings=[],coerceNativeSetting=value=>{if(value===!0)return!0;if(value===!1)return!1;if(value===`auto`)return`auto`},warnDmPolicy=async input=>{let policyPath=input.policyPath??`${input.allowFromPath}policy`,{hasWildcard,isMultiUserDm}=await resolveDmAllowState({provider:input.provider,allowFrom:input.allowFrom,normalizeEntry:input.normalizeEntry}),dmScope=params.cfg.session?.dmScope??`main`;if(input.dmPolicy===`open`){let allowFromKey=`${input.allowFromPath}allowFrom`;findings.push({checkId:`channels.${input.provider}.dm.open`,severity:`critical`,title:`${input.label} DMs are open`,detail:`${policyPath}="open" allows anyone to DM the bot.`,remediation:`Use pairing/allowlist; if you really need open DMs, ensure ${allowFromKey} includes "*".`}),hasWildcard||findings.push({checkId:`channels.${input.provider}.dm.open_invalid`,severity:`warn`,title:`${input.label} DM config looks inconsistent`,detail:`"open" requires ${allowFromKey} to include "*".`})}if(input.dmPolicy===`disabled`){findings.push({checkId:`channels.${input.provider}.dm.disabled`,severity:`info`,title:`${input.label} DMs are disabled`,detail:`${policyPath}="disabled" ignores inbound DMs.`});return}dmScope===`main`&&isMultiUserDm&&findings.push({checkId:`channels.${input.provider}.dm.scope_main_multiuser`,severity:`warn`,title:`${input.label} DMs share the main session`,detail:`Multiple DM senders currently share the main session, which can leak context across users.`,remediation:`Run: `+formatCliCommand(`builderforce config set session.dmScope "per-channel-peer"`)+` (or "per-account-channel-peer" for multi-account channels) to isolate DM sessions per sender.`})};for(let plugin of params.plugins){if(!plugin.security)continue;let accountIds=plugin.config.listAccountIds(params.cfg),defaultAccountId=resolveChannelDefaultAccountId({plugin,cfg:params.cfg,accountIds}),account=plugin.config.resolveAccount(params.cfg,defaultAccountId);if(!(!plugin.config.isEnabled||plugin.config.isEnabled(account,params.cfg))||!(!plugin.config.isConfigured||await plugin.config.isConfigured(account,params.cfg)))continue;if(plugin.id===`discord`){let discordCfg=account?.config??{},nativeEnabled=resolveNativeCommandsEnabled({providerId:`discord`,providerSetting:coerceNativeSetting(discordCfg.commands?.native),globalSetting:params.cfg.commands?.native}),nativeSkillsEnabled=resolveNativeSkillsEnabled({providerId:`discord`,providerSetting:coerceNativeSetting(discordCfg.commands?.nativeSkills),globalSetting:params.cfg.commands?.nativeSkills});if(nativeEnabled||nativeSkillsEnabled){let defaultGroupPolicy=params.cfg.channels?.defaults?.groupPolicy,groupPolicy=discordCfg.groupPolicy??defaultGroupPolicy??`allowlist`,guildEntries=discordCfg.guilds??{},guildsConfigured=Object.keys(guildEntries).length>0,hasAnyUserAllowlist=Object.values(guildEntries).some(guild=>{if(!guild||typeof guild!=`object`)return!1;let g=guild;if(Array.isArray(g.users)&&g.users.length>0)return!0;let channels=g.channels;return!channels||typeof channels!=`object`?!1:Object.values(channels).some(channel=>{if(!channel||typeof channel!=`object`)return!1;let c=channel;return Array.isArray(c.users)&&c.users.length>0})}),dmAllowFromRaw=discordCfg.dm?.allowFrom,dmAllowFrom=Array.isArray(dmAllowFromRaw)?dmAllowFromRaw:[],storeAllowFrom=await readChannelAllowFromStore(`discord`).catch(()=>[]),ownerAllowFromConfigured=normalizeAllowFromList$1([...dmAllowFrom,...storeAllowFrom]).length>0,useAccessGroups=params.cfg.commands?.useAccessGroups!==!1;!useAccessGroups&&groupPolicy!==`disabled`&&guildsConfigured&&!hasAnyUserAllowlist?findings.push({checkId:`channels.discord.commands.native.unrestricted`,severity:`critical`,title:`Discord slash commands are unrestricted`,detail:`commands.useAccessGroups=false disables sender allowlists for Discord slash commands unless a per-guild/channel users allowlist is configured; with no users allowlist, any user in allowed guild channels can invoke /… commands.`,remediation:`Set commands.useAccessGroups=true (recommended), or configure channels.discord.guilds.<id>.users (or channels.discord.guilds.<id>.channels.<channel>.users).`}):useAccessGroups&&groupPolicy!==`disabled`&&guildsConfigured&&!ownerAllowFromConfigured&&!hasAnyUserAllowlist&&findings.push({checkId:`channels.discord.commands.native.no_allowlists`,severity:`warn`,title:`Discord slash commands have no allowlists`,detail:`Discord slash commands are enabled, but neither an owner allowFrom list nor any per-guild/channel users allowlist is configured; /… commands will be rejected for everyone.`,remediation:`Add your user id to channels.discord.allowFrom (or approve yourself via pairing), or configure channels.discord.guilds.<id>.users.`})}}if(plugin.id===`slack`){let slackCfg=account?.config??{},nativeEnabled=resolveNativeCommandsEnabled({providerId:`slack`,providerSetting:coerceNativeSetting(slackCfg.commands?.native),globalSetting:params.cfg.commands?.native}),nativeSkillsEnabled=resolveNativeSkillsEnabled({providerId:`slack`,providerSetting:coerceNativeSetting(slackCfg.commands?.nativeSkills),globalSetting:params.cfg.commands?.nativeSkills});if(nativeEnabled||nativeSkillsEnabled||slackCfg.slashCommand?.enabled===!0)if(params.cfg.commands?.useAccessGroups===!1)findings.push({checkId:`channels.slack.commands.slash.useAccessGroups_off`,severity:`critical`,title:`Slack slash commands bypass access groups`,detail:`Slack slash/native commands are enabled while commands.useAccessGroups=false; this can allow unrestricted /… command execution from channels/users you didn't explicitly authorize.`,remediation:`Set commands.useAccessGroups=true (recommended).`});else{let allowFromRaw=account?.config?.allowFrom,legacyAllowFromRaw=account?.dm?.allowFrom,allowFrom=Array.isArray(allowFromRaw)?allowFromRaw:Array.isArray(legacyAllowFromRaw)?legacyAllowFromRaw:[],storeAllowFrom=await readChannelAllowFromStore(`slack`).catch(()=>[]),ownerAllowFromConfigured=normalizeAllowFromList$1([...allowFrom,...storeAllowFrom]).length>0,channels=slackCfg.channels??{},hasAnyChannelUsersAllowlist=Object.values(channels).some(value=>{if(!value||typeof value!=`object`)return!1;let channel=value;return Array.isArray(channel.users)&&channel.users.length>0});!ownerAllowFromConfigured&&!hasAnyChannelUsersAllowlist&&findings.push({checkId:`channels.slack.commands.slash.no_allowlists`,severity:`warn`,title:`Slack slash commands have no allowlists`,detail:`Slack slash/native commands are enabled, but neither an owner allowFrom list nor any channels.<id>.users allowlist is configured; /… commands will be rejected for everyone.`,remediation:`Approve yourself via pairing (recommended), or set channels.slack.allowFrom and/or channels.slack.channels.<id>.users.`})}}let dmPolicy=plugin.security.resolveDmPolicy?.({cfg:params.cfg,accountId:defaultAccountId,account});if(dmPolicy&&await warnDmPolicy({label:plugin.meta.label??plugin.id,provider:plugin.id,dmPolicy:dmPolicy.policy,allowFrom:dmPolicy.allowFrom,policyPath:dmPolicy.policyPath,allowFromPath:dmPolicy.allowFromPath,normalizeEntry:dmPolicy.normalizeEntry}),plugin.security.collectWarnings){let warnings=await plugin.security.collectWarnings({cfg:params.cfg,accountId:defaultAccountId,account});for(let message of warnings??[]){let trimmed=String(message).trim();trimmed&&findings.push({checkId:`channels.${plugin.id}.warning.${findings.length+1}`,severity:classifyChannelWarningSeverity(trimmed),title:`${plugin.meta.label??plugin.id} security warning`,detail:trimmed.replace(/^-\s*/,``)})}}if(plugin.id===`telegram`){if(params.cfg.commands?.text===!1)continue;let telegramCfg=account?.config??{},defaultGroupPolicy=params.cfg.channels?.defaults?.groupPolicy,groupPolicy=telegramCfg.groupPolicy??defaultGroupPolicy??`allowlist`,groups=telegramCfg.groups,groupsConfigured=!!groups&&Object.keys(groups??{}).length>0;if(!(groupPolicy===`open`||groupPolicy===`allowlist`&&groupsConfigured))continue;let storeAllowFrom=await readChannelAllowFromStore(`telegram`).catch(()=>[]),storeHasWildcard=storeAllowFrom.some(v=>String(v).trim()===`*`),invalidTelegramAllowFromEntries=new Set;for(let entry of storeAllowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}let groupAllowFrom=Array.isArray(telegramCfg.groupAllowFrom)?telegramCfg.groupAllowFrom:[],groupAllowFromHasWildcard=groupAllowFrom.some(v=>String(v).trim()===`*`);for(let entry of groupAllowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}let dmAllowFrom=Array.isArray(telegramCfg.allowFrom)?telegramCfg.allowFrom:[];for(let entry of dmAllowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}let anyGroupOverride=!!(groups&&Object.values(groups).some(value=>{if(!value||typeof value!=`object`)return!1;let group=value,allowFrom=Array.isArray(group.allowFrom)?group.allowFrom:[];if(allowFrom.length>0){for(let entry of allowFrom){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}return!0}let topics=group.topics;return!topics||typeof topics!=`object`?!1:Object.values(topics).some(topicValue=>{if(!topicValue||typeof topicValue!=`object`)return!1;let topic=topicValue,topicAllow=Array.isArray(topic.allowFrom)?topic.allowFrom:[];for(let entry of topicAllow){let normalized=normalizeTelegramAllowFromEntry(entry);!normalized||normalized===`*`||isNumericTelegramUserId(normalized)||invalidTelegramAllowFromEntries.add(normalized)}return topicAllow.length>0})})),hasAnySenderAllowlist=storeAllowFrom.length>0||groupAllowFrom.length>0||anyGroupOverride;if(invalidTelegramAllowFromEntries.size>0){let examples=Array.from(invalidTelegramAllowFromEntries).slice(0,5),more=invalidTelegramAllowFromEntries.size>examples.length?` (+${invalidTelegramAllowFromEntries.size-examples.length} more)`:``;findings.push({checkId:`channels.telegram.allowFrom.invalid_entries`,severity:`warn`,title:`Telegram allowlist contains non-numeric entries`,detail:`Telegram sender authorization requires numeric Telegram user IDs. Found non-numeric allowFrom entries: ${examples.join(`, `)}${more}.`,remediation:`Replace @username entries with numeric Telegram user IDs (use onboarding to resolve), then re-run the audit.`})}if(storeHasWildcard||groupAllowFromHasWildcard){findings.push({checkId:`channels.telegram.groups.allowFrom.wildcard`,severity:`critical`,title:`Telegram group allowlist contains wildcard`,detail:`Telegram group sender allowlist contains "*", which allows any group member to run /… commands and control directives.`,remediation:`Remove "*" from channels.telegram.groupAllowFrom and pairing store; prefer explicit numeric Telegram user IDs.`});continue}if(!hasAnySenderAllowlist){let providerSetting=telegramCfg.commands?.nativeSkills,skillsEnabled=resolveNativeSkillsEnabled({providerId:`telegram`,providerSetting,globalSetting:params.cfg.commands?.nativeSkills});findings.push({checkId:`channels.telegram.groups.allowFrom.missing`,severity:`critical`,title:`Telegram group commands have no sender allowlist`,detail:`Telegram group access is enabled but no sender allowlist is configured; this allows any group member to invoke /… commands`+(skillsEnabled?` (including skill commands).`:`.`),remediation:`Approve yourself via pairing (recommended), or set channels.telegram.groupAllowFrom (or per-group groups.<id>.allowFrom).`})}}}return findings}function summarizeGroupPolicy(cfg){let channels=cfg.channels;if(!channels||typeof channels!=`object`)return{open:0,allowlist:0,other:0};let open=0,allowlist=0,other=0;for(let value of Object.values(channels)){if(!value||typeof value!=`object`)continue;let policy=value.groupPolicy;policy===`open`?open+=1:policy===`allowlist`?allowlist+=1:other+=1}return{open,allowlist,other}}function isProbablySyncedPath(p){let s=p.toLowerCase();return s.includes(`icloud`)||s.includes(`dropbox`)||s.includes(`google drive`)||s.includes(`googledrive`)||s.includes(`onedrive`)}function looksLikeEnvRef(value){let v=value.trim();return v.startsWith("${")&&v.endsWith(`}`)}function isGatewayRemotelyExposed(cfg){if((typeof cfg.gateway?.bind==`string`?cfg.gateway.bind:`loopback`)!==`loopback`)return!0;let tailscaleMode=cfg.gateway?.tailscale?.mode??`off`;return tailscaleMode===`serve`||tailscaleMode===`funnel`}function addModel(models,raw,source){if(typeof raw!=`string`)return;let id=raw.trim();id&&models.push({id,source})}function collectModels(cfg){let out=[];addModel(out,cfg.agents?.defaults?.model?.primary,`agents.defaults.model.primary`);for(let f of cfg.agents?.defaults?.model?.fallbacks??[])addModel(out,f,`agents.defaults.model.fallbacks`);addModel(out,cfg.agents?.defaults?.imageModel?.primary,`agents.defaults.imageModel.primary`);for(let f of cfg.agents?.defaults?.imageModel?.fallbacks??[])addModel(out,f,`agents.defaults.imageModel.fallbacks`);let list=Array.isArray(cfg.agents?.list)?cfg.agents?.list:[];for(let agent of list??[]){if(!agent||typeof agent!=`object`)continue;let id=typeof agent.id==`string`?agent.id:``,model=agent.model;if(typeof model==`string`)addModel(out,model,`agents.list.${id}.model`);else if(model&&typeof model==`object`){addModel(out,model.primary,`agents.list.${id}.model.primary`);let fallbacks=model.fallbacks;if(Array.isArray(fallbacks))for(let f of fallbacks)addModel(out,f,`agents.list.${id}.model.fallbacks`)}}return out}const LEGACY_MODEL_PATTERNS=[{id:`openai.gpt35`,re:/\bgpt-3\.5\b/i,label:`GPT-3.5 family`},{id:`anthropic.claude2`,re:/\bclaude-(instant|2)\b/i,label:`Claude 2/Instant family`},{id:`openai.gpt4_legacy`,re:/\bgpt-4-(0314|0613)\b/i,label:`Legacy GPT-4 snapshots`}],WEAK_TIER_MODEL_PATTERNS=[{id:`anthropic.haiku`,re:/\bhaiku\b/i,label:`Haiku tier (smaller model)`}];function isGptModel(id){return/\bgpt-/i.test(id)}function isGpt5OrHigher(id){return/\bgpt-5(?:\b|[.-])/i.test(id)}function isClaudeModel(id){return/\bclaude-/i.test(id)}function isClaude45OrHigher(id){return/\bclaude-[^\s/]*?(?:-4-?(?:[5-9]|[1-9]\d)\b|4\.(?:[5-9]|[1-9]\d)\b|-[5-9](?:\b|[.-]))/i.test(id)}function extractAgentIdFromSource(source){return source.match(/^agents\.list\.([^.]*)\./)?.[1]??null}function hasConfiguredDockerConfig(docker){return!docker||typeof docker!=`object`?!1:Object.values(docker).some(value=>value!==void 0)}function normalizeNodeCommand(value){return typeof value==`string`?value.trim():``}function listKnownNodeCommands(cfg){let baseCfg={...cfg,gateway:{...cfg.gateway,nodes:{...cfg.gateway?.nodes,denyCommands:[]}}},out=new Set;for(let platform of[`ios`,`android`,`macos`,`linux`,`windows`,`unknown`]){let allow=resolveNodeCommandAllowlist(baseCfg,{platform});for(let cmd of allow){let normalized=normalizeNodeCommand(cmd);normalized&&out.add(normalized)}}return out}function looksLikeNodeCommandPattern(value){return value?/[?*[\]{}(),|]/.test(value)||value.startsWith(`/`)||value.endsWith(`/`)||value.startsWith(`^`)||value.endsWith(`$`)?!0:/\s/.test(value)||value.includes(`group:`):!1}function resolveToolPolicies$1(params){let policies=[],profilePolicy=resolveToolProfilePolicy(params.agentTools?.profile??params.cfg.tools?.profile);profilePolicy&&policies.push(profilePolicy);let globalPolicy=pickSandboxToolPolicy(params.cfg.tools??void 0);globalPolicy&&policies.push(globalPolicy);let agentPolicy=pickSandboxToolPolicy(params.agentTools);if(agentPolicy&&policies.push(agentPolicy),params.sandboxMode===`all`){let sandboxPolicy=resolveSandboxToolPolicyForAgent(params.cfg,params.agentId??void 0);policies.push(sandboxPolicy)}return policies}function hasWebSearchKey(cfg,env){let search=cfg.tools?.web?.search;return!!(search?.apiKey||search?.perplexity?.apiKey||env.BRAVE_API_KEY||env.PERPLEXITY_API_KEY||env.OPENROUTER_API_KEY)}function isWebSearchEnabled(cfg,env){let enabled=cfg.tools?.web?.search?.enabled;return enabled===!1?!1:enabled===!0?!0:hasWebSearchKey(cfg,env)}function isWebFetchEnabled(cfg){return cfg.tools?.web?.fetch?.enabled!==!1}function isBrowserEnabled(cfg){try{return resolveBrowserConfig(cfg.browser,cfg).enabled}catch{return!0}}function listGroupPolicyOpen(cfg){let out=[],channels=cfg.channels;if(!channels||typeof channels!=`object`)return out;for(let[channelId,value]of Object.entries(channels)){if(!value||typeof value!=`object`)continue;let section=value;section.groupPolicy===`open`&&out.push(`channels.${channelId}.groupPolicy`);let accounts=section.accounts;if(accounts&&typeof accounts==`object`)for(let[accountId,accountVal]of Object.entries(accounts))!accountVal||typeof accountVal!=`object`||accountVal.groupPolicy===`open`&&out.push(`channels.${channelId}.accounts.${accountId}.groupPolicy`)}return out}function collectAttackSurfaceSummaryFindings(cfg){let group=summarizeGroupPolicy(cfg),elevated=cfg.tools?.elevated?.enabled!==!1,webhooksEnabled=cfg.hooks?.enabled===!0,internalHooksEnabled=cfg.hooks?.internal?.enabled===!0,browserEnabled=cfg.browser?.enabled??!0;return[{checkId:`summary.attack_surface`,severity:`info`,title:`Attack surface summary`,detail:`groups: open=${group.open}, allowlist=${group.allowlist}\ntools.elevated: ${elevated?`enabled`:`disabled`}\nhooks.webhooks: ${webhooksEnabled?`enabled`:`disabled`}\nhooks.internal: ${internalHooksEnabled?`enabled`:`disabled`}\nbrowser control: ${browserEnabled?`enabled`:`disabled`}`}]}function collectSyncedFolderFindings(params){let findings=[];return(isProbablySyncedPath(params.stateDir)||isProbablySyncedPath(params.configPath))&&findings.push({checkId:`fs.synced_dir`,severity:`warn`,title:`State/config path looks like a synced folder`,detail:`stateDir=${params.stateDir}, configPath=${params.configPath}. Synced folders (iCloud/Dropbox/OneDrive/Google Drive) can leak tokens and transcripts onto other devices.`,remediation:`Keep BUILDERFORCE_AGENTS_STATE_DIR on a local-only volume and re-run "${formatCliCommand(`builderforce security audit --fix`)}".`}),findings}function collectSecretsInConfigFindings(cfg){let findings=[],password=typeof cfg.gateway?.auth?.password==`string`?cfg.gateway.auth.password.trim():``;password&&!looksLikeEnvRef(password)&&findings.push({checkId:`config.secrets.gateway_password_in_config`,severity:`warn`,title:`Gateway password is stored in config`,detail:`gateway.auth.password is set in the config file; prefer environment variables for secrets when possible.`,remediation:`Prefer BUILDERFORCE_AGENTS_GATEWAY_PASSWORD (env) and remove gateway.auth.password from disk.`});let hooksToken=typeof cfg.hooks?.token==`string`?cfg.hooks.token.trim():``;return cfg.hooks?.enabled===!0&&hooksToken&&!looksLikeEnvRef(hooksToken)&&findings.push({checkId:`config.secrets.hooks_token_in_config`,severity:`info`,title:`Hooks token is stored in config`,detail:`hooks.token is set in the config file; keep config perms tight and treat it like an API secret.`}),findings}function collectHooksHardeningFindings(cfg,env=process.env){let findings=[];if(cfg.hooks?.enabled!==!0)return findings;let token=typeof cfg.hooks?.token==`string`?cfg.hooks.token.trim():``;token&&token.length<24&&findings.push({checkId:`hooks.token_too_short`,severity:`warn`,title:`Hooks token looks short`,detail:`hooks.token is ${token.length} chars; prefer a long random token.`});let gatewayAuth=resolveGatewayAuth({authConfig:cfg.gateway?.auth,tailscaleMode:cfg.gateway?.tailscale?.mode??`off`,env}),builderforceGatewayToken=typeof env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN==`string`&&env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN.trim()?env.BUILDERFORCE_AGENTS_GATEWAY_TOKEN.trim():null,gatewayToken=gatewayAuth.mode===`token`&&typeof gatewayAuth.token==`string`&&gatewayAuth.token.trim()?gatewayAuth.token.trim():builderforceGatewayToken||null;token&&gatewayToken&&token===gatewayToken&&findings.push({checkId:`hooks.token_reuse_gateway_token`,severity:`warn`,title:`Hooks token reuses the Gateway token`,detail:`hooks.token matches gateway.auth token; compromise of hooks expands blast radius to the Gateway API.`,remediation:`Use a separate hooks.token dedicated to hook ingress.`}),(typeof cfg.hooks?.path==`string`?cfg.hooks.path.trim():``)===`/`&&findings.push({checkId:`hooks.path_root`,severity:`critical`,title:`Hooks base path is '/'`,detail:`hooks.path='/' would shadow other HTTP endpoints and is unsafe.`,remediation:`Use a dedicated path like '/hooks'.`});let allowRequestSessionKey=cfg.hooks?.allowRequestSessionKey===!0,defaultSessionKey=typeof cfg.hooks?.defaultSessionKey==`string`?cfg.hooks.defaultSessionKey.trim():``,allowedPrefixes=Array.isArray(cfg.hooks?.allowedSessionKeyPrefixes)?cfg.hooks.allowedSessionKeyPrefixes.map(prefix=>prefix.trim()).filter(prefix=>prefix.length>0):[],remoteExposure=isGatewayRemotelyExposed(cfg);return defaultSessionKey||findings.push({checkId:`hooks.default_session_key_unset`,severity:`warn`,title:`hooks.defaultSessionKey is not configured`,detail:`Hook agent runs without explicit sessionKey use generated per-request keys. Set hooks.defaultSessionKey to keep hook ingress scoped to a known session.`,remediation:`Set hooks.defaultSessionKey (for example, "hook:ingress").`}),allowRequestSessionKey&&findings.push({checkId:`hooks.request_session_key_enabled`,severity:remoteExposure?`critical`:`warn`,title:`External hook payloads may override sessionKey`,detail:"hooks.allowRequestSessionKey=true allows `/hooks/agent` callers to choose the session key. Treat hook token holders as full-trust unless you also restrict prefixes.",remediation:`Set hooks.allowRequestSessionKey=false (recommended) or constrain hooks.allowedSessionKeyPrefixes.`}),allowRequestSessionKey&&allowedPrefixes.length===0&&findings.push({checkId:`hooks.request_session_key_prefixes_missing`,severity:remoteExposure?`critical`:`warn`,title:`Request sessionKey override is enabled without prefix restrictions`,detail:`hooks.allowRequestSessionKey=true and hooks.allowedSessionKeyPrefixes is unset/empty, so request payloads can target arbitrary session key shapes.`,remediation:`Set hooks.allowedSessionKeyPrefixes (for example, ["hook:"]) or disable request overrides.`}),findings}function collectGatewayHttpSessionKeyOverrideFindings(cfg){let findings=[],chatCompletionsEnabled=cfg.gateway?.http?.endpoints?.chatCompletions?.enabled===!0,responsesEnabled=cfg.gateway?.http?.endpoints?.responses?.enabled===!0;if(!chatCompletionsEnabled&&!responsesEnabled)return findings;let enabledEndpoints=[chatCompletionsEnabled?`/v1/chat/completions`:null,responsesEnabled?`/v1/responses`:null].filter(entry=>!!entry);return findings.push({checkId:`gateway.http.session_key_override_enabled`,severity:`info`,title:`HTTP API session-key override is enabled`,detail:`${enabledEndpoints.join(`, `)} accept x-builderforce-session-key for per-request session routing. Treat API credential holders as trusted principals.`}),findings}function collectSandboxDockerNoopFindings(cfg){let findings=[],configuredPaths=[],agents=Array.isArray(cfg.agents?.list)?cfg.agents.list:[],defaultsSandbox=cfg.agents?.defaults?.sandbox,hasDefaultDocker=hasConfiguredDockerConfig(defaultsSandbox?.docker),defaultMode=defaultsSandbox?.mode??`off`,hasAnySandboxEnabledAgent=agents.some(entry=>!entry||typeof entry!=`object`||typeof entry.id!=`string`?!1:resolveSandboxConfigForAgent(cfg,entry.id).mode!==`off`);hasDefaultDocker&&defaultMode===`off`&&!hasAnySandboxEnabledAgent&&configuredPaths.push(`agents.defaults.sandbox.docker`);for(let entry of agents)!entry||typeof entry!=`object`||typeof entry.id!=`string`||hasConfiguredDockerConfig(entry.sandbox?.docker)&&resolveSandboxConfigForAgent(cfg,entry.id).mode===`off`&&configuredPaths.push(`agents.list.${entry.id}.sandbox.docker`);return configuredPaths.length===0||findings.push({checkId:`sandbox.docker_config_mode_off`,severity:`warn`,title:`Sandbox docker settings configured while sandbox mode is off`,detail:`These docker settings will not take effect until sandbox mode is enabled:
|
|
2
2
|
`+configuredPaths.map(entry=>`- ${entry}`).join(`
|
|
3
3
|
`),remediation:'Enable sandbox mode (`agents.defaults.sandbox.mode="non-main"` or `"all"`) where needed, or remove unused docker settings.'}),findings}function collectSandboxDangerousConfigFindings(cfg){let findings=[],agents=Array.isArray(cfg.agents?.list)?cfg.agents.list:[],configs=[],defaultDocker=cfg.agents?.defaults?.sandbox?.docker;defaultDocker&&typeof defaultDocker==`object`&&configs.push({source:`agents.defaults.sandbox.docker`,docker:defaultDocker});for(let entry of agents){if(!entry||typeof entry!=`object`||typeof entry.id!=`string`)continue;let agentDocker=entry.sandbox?.docker;agentDocker&&typeof agentDocker==`object`&&configs.push({source:`agents.list.${entry.id}.sandbox.docker`,docker:agentDocker})}for(let{source,docker}of configs){let binds=Array.isArray(docker.binds)?docker.binds:[];for(let bind of binds){if(typeof bind!=`string`)continue;let blocked=getBlockedBindReason(bind);if(!blocked)continue;if(blocked.kind===`non_absolute`){findings.push({checkId:`sandbox.bind_mount_non_absolute`,severity:`warn`,title:`Sandbox bind mount uses a non-absolute source path`,detail:`${source}.binds contains "${bind}" which uses source path "${blocked.sourcePath}". Non-absolute bind sources are hard to validate safely and may resolve unexpectedly.`,remediation:`Rewrite "${bind}" to use an absolute host path (for example: /home/user/project:/project:ro).`});continue}let verb=blocked.kind===`covers`?`covers`:`targets`;findings.push({checkId:`sandbox.dangerous_bind_mount`,severity:`critical`,title:`Dangerous bind mount in sandbox config`,detail:`${source}.binds contains "${bind}" which ${verb} blocked path "${blocked.blockedPath}". This can expose host system directories or the Docker socket to sandbox containers.`,remediation:`Remove "${bind}" from ${source}.binds. Use project-specific paths instead.`})}let network=typeof docker.network==`string`?docker.network:void 0;network&&network.trim().toLowerCase()===`host`&&findings.push({checkId:`sandbox.dangerous_network_mode`,severity:`critical`,title:`Network host mode in sandbox config`,detail:`${source}.network is "host" which bypasses container network isolation entirely.`,remediation:`Set ${source}.network to "bridge" or "none".`});let seccompProfile=typeof docker.seccompProfile==`string`?docker.seccompProfile:void 0;seccompProfile&&seccompProfile.trim().toLowerCase()===`unconfined`&&findings.push({checkId:`sandbox.dangerous_seccomp_profile`,severity:`critical`,title:`Seccomp unconfined in sandbox config`,detail:`${source}.seccompProfile is "unconfined" which disables syscall filtering.`,remediation:`Remove ${source}.seccompProfile or use a custom seccomp profile file.`});let apparmorProfile=typeof docker.apparmorProfile==`string`?docker.apparmorProfile:void 0;apparmorProfile&&apparmorProfile.trim().toLowerCase()===`unconfined`&&findings.push({checkId:`sandbox.dangerous_apparmor_profile`,severity:`critical`,title:`AppArmor unconfined in sandbox config`,detail:`${source}.apparmorProfile is "unconfined" which disables AppArmor enforcement.`,remediation:`Remove ${source}.apparmorProfile or use a named AppArmor profile.`})}return findings}function collectNodeDenyCommandPatternFindings(cfg){let findings=[],denyListRaw=cfg.gateway?.nodes?.denyCommands;if(!Array.isArray(denyListRaw)||denyListRaw.length===0)return findings;let denyList=denyListRaw.map(normalizeNodeCommand).filter(Boolean);if(denyList.length===0)return findings;let knownCommands=listKnownNodeCommands(cfg),patternLike=denyList.filter(entry=>looksLikeNodeCommandPattern(entry)),unknownExact=denyList.filter(entry=>!looksLikeNodeCommandPattern(entry)&&!knownCommands.has(entry));if(patternLike.length===0&&unknownExact.length===0)return findings;let detailParts=[];patternLike.length>0&&detailParts.push(`Pattern-like entries (not supported by exact matching): ${patternLike.join(`, `)}`),unknownExact.length>0&&detailParts.push(`Unknown command names (not in defaults/allowCommands): ${unknownExact.join(`, `)}`);let examples=Array.from(knownCommands).slice(0,8);return findings.push({checkId:`gateway.nodes.deny_commands_ineffective`,severity:`warn`,title:`Some gateway.nodes.denyCommands entries are ineffective`,detail:`gateway.nodes.denyCommands uses exact command-name matching only.
|
|
4
4
|
`+detailParts.map(entry=>`- ${entry}`).join(`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./paths-5FcIFMsj.js";import"./utils-DbaBVFaK.js";import"./embedded-helpers-C9jpiwlw.js";import"./reply-GY1C8tcv.js";import"./session-key-EoB0qaG9.js";import"./builderforce-root-D64_sXEi.js";import"./subsystem-B3TqcCrZ.js";import"./registry-TdK-aV05.js";import"./logger-Bch0bx9c.js";import"./exec-DdcIjeyn.js";import"./agent-scope-DPtjOxzp.js";import"./src-CA0fU67C.js";import"./model-selection-DG9J_VTz.js";import"./env-file-D1MDi-AM.js";import"./boolean-Cnh1KNl1.js";import"./env-BIdU5BAp.js";import"./src-DTFqOIQD.js";import"./io-BLBq4T2o.js";import"./manifest-registry-BJCfNV1a.js";import"./config-BgV_FYSq.js";import"./runner-eTTUbLAK.js";import"./model-catalog-DjNiebr7.js";import"./sandbox-C4AKi2EX.js";import"./chrome-DXt86tmV.js";import"./tailscale-DLkpGquM.js";import"./auth-lebUHrkd.js";import"./server-context-CQ2v4BAx.js";import"./frontmatter-3D1EdC1L.js";import"./skills-Ba4ftrB-.js";import"./plugin-skills-B11rggZh.js";import"./routes-DZntyPY6.js";import"./redact-BHdfp2MZ.js";import"./errors-B1MIg3g-.js";import"./paths-cR8ct-Y3.js";import"./ssrf-p9k-iapc.js";import"./image-ops-C8IUQKjn.js";import"./store-CmHBQ-yX.js";import"./ports-DgmEDNOm.js";import"./trash-DD2Hc5oq.js";import"./sessions-BuZVmOWt.js";import"./message-channel-D_jXxXQj.js";import"./plugins-D5zP6ENo.js";import"./accounts-o35LU_iy.js";import"./accounts-rmXEiebi.js";import"./accounts-BLueHgKj.js";import"./bindings-DR59065T.js";import"./send-Aw8wK3vK.js";import"./send-ChGpVO3O.js";import"./paths-DJ6rztqJ.js";import"./tool-images-B7b_OiMz.js";import"./tool-display-ByOZtWvA.js";import"./fetch-guard-8mwt3-hm.js";import"./api-key-rotation-CyCi-UqR.js";import"./fetch-BuOLY9KP.js";import"./sqlite-C39E12XS.js";import"./tokens-CCU3zO-D.js";import"./project-context-store-wcq7lXuI.js";import"./with-timeout-GDLpcjW7.js";import"./deliver--6OBF3LL.js";import"./send-BxoVLIy1.js";import"./workspace-D4LK4thI.js";import"./reply-prefix-zIMgi6K6.js";import"./memory-cli-CbkWGjRn.js";import"./manager-DSz61dXv.js";import"./retry-DlVhg5qu.js";import"./client-xfoidwPI.js";import"./call-T8ciwMTA.js";import"./common-BTbIhLyt.js";import"./chunk-FCBlVOyo.js";import"./markdown-tables-P6uoUSFa.js";import"./ir-5BNoIXZm.js";import"./render-D1dVTEB1.js";import"./builderforcellm-syscheck-F5JMAr3p.js";import"./send-BP5osGBo.js";import"./outbound-attachment-C7wByQO5.js";import"./fetch-DnVtDecb.js";import"./delivery-queue-CXKynF1P.js";import"./channel-activity-CCNDbdD3.js";import"./tables-ERcoWFDp.js";import"./pairing-store-ti3FEkmr.js";import"./links-BgWWaaOT.js";import"./cli-utils-LBYKdNFb.js";import"./help-format-Qfk2vDNX.js";import"./progress-BfOtdN6b.js";import"./resolve-route-D49haUnv.js";import"./replies-DokbEfJD.js";import"./refresh-TiC_kLgE.js";import"./coding-tools.policy-ZhOdlcEI.js";import"./send-l3ge4wkC.js";import"./onboard-helpers-CiHzTaFX.js";import"./prompt-style-BpVK43GK.js";import"./pairing-labels-oA-nKTaW.js";import"./session-cost-usage-BjH7mxVj.js";import"./usage-format-DGf8ZWPH.js";import"./provider-usage-B-wPVN_j.js";import"./active-listener-Dcg19lJG.js";import"./exec-approvals-BpVPDVtV.js";import"./nodes-screen-C3TDIi8d.js";import"./project-context-CJj0Inz-.js";import"./control-service-y3GYvIBg.js";import"./stagger-8EkqkqJv.js";import"./channel-selection-DyAvzlY8.js";import"./mamba-state-engine-CoGqoBTH.js";import"./transformers-stream-D7nRu4Qu.js";import"./shared-C2orjbTD.js";import"./onboard-auth.credentials-DpitLlzw.js";import"./auth-token-BE67qxLw.js";import"./logging-DHa3jQN3.js";import"./provider-auth-helpers-B84m5VMc.js";import{t as applyAuthChoice}from"./auth-choice.apply-DBuvopiF.js";import"./openai-model-default-CH2-2Hvk.js";import"./model-picker-EIhpfOZa.js";import"./auth-choice.apply.transformers-Df9l_jRz.js";import{n as warnIfModelConfigLooksOff,t as resolvePreferredProviderForAuthChoice}from"./auth-choice-CCib_yVL.js";export{applyAuthChoice,resolvePreferredProviderForAuthChoice,warnIfModelConfigLooksOff};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{o as resolveAgentModelPrimary}from"./agent-scope-DPtjOxzp.js";import{$t as listProfilesForProvider,St as resolveModelAuthMode,bn as DEFAULT_PROVIDER,in as ensureAuthProfileStore,m as resolveConfiguredModelRef,yn as DEFAULT_MODEL}from"./model-selection-
|
|
1
|
+
import{o as resolveAgentModelPrimary}from"./agent-scope-DPtjOxzp.js";import{$t as listProfilesForProvider,St as resolveModelAuthMode,bn as DEFAULT_PROVIDER,in as ensureAuthProfileStore,m as resolveConfiguredModelRef,yn as DEFAULT_MODEL}from"./model-selection-DG9J_VTz.js";import{r as loadModelCatalog}from"./model-catalog-DjNiebr7.js";import{s as OPENAI_CODEX_DEFAULT_MODEL}from"./model-picker-EIhpfOZa.js";async function warnIfModelConfigLooksOff(config,prompter,options){let agentModelOverride=options?.agentId?resolveAgentModelPrimary(config,options.agentId):void 0,configWithModel=agentModelOverride&&agentModelOverride.length>0?{...config,agents:{...config.agents,defaults:{...config.agents?.defaults,model:{...typeof config.agents?.defaults?.model==`object`?config.agents.defaults.model:void 0,primary:agentModelOverride}}}}:config,ref=resolveConfiguredModelRef({cfg:configWithModel,defaultProvider:DEFAULT_PROVIDER,defaultModel:DEFAULT_MODEL}),warnings=[],catalog=await loadModelCatalog({config:configWithModel,useCache:!1});catalog.length>0&&(catalog.some(entry=>entry.provider===ref.provider&&entry.id===ref.model)||warnings.push(`Model not found: ${ref.provider}/${ref.model}. Update agents.defaults.model or run /models list.`));let store=await ensureAuthProfileStore(options?.agentDir);await resolveModelAuthMode(ref.provider,configWithModel,store)===`unknown`&&warnings.push(`No auth configured for provider "${ref.provider}". The agent may fail until credentials are added.`),ref.provider===`openai`&&listProfilesForProvider(store,`openai-codex`).length>0&&warnings.push(`Detected OpenAI Codex OAuth. Consider setting agents.defaults.model to ${OPENAI_CODEX_DEFAULT_MODEL}.`),warnings.length>0&&await prompter.note(warnings.join(`
|
|
2
2
|
`),`Model check`)}const PREFERRED_PROVIDER_BY_AUTH_CHOICE={oauth:`anthropic`,"setup-token":`anthropic`,"claude-cli":`anthropic`,token:`anthropic`,apiKey:`anthropic`,builderforcellm:`builderforcellm`,vllm:`vllm`,"openai-codex":`openai-codex`,"codex-cli":`openai-codex`,chutes:`chutes`,"openai-api-key":`openai`,"openrouter-api-key":`openrouter`,"ai-gateway-api-key":`vercel-ai-gateway`,"cloudflare-ai-gateway-api-key":`cloudflare-ai-gateway`,"moonshot-api-key":`moonshot`,"moonshot-api-key-cn":`moonshot`,"kimi-code-api-key":`kimi-coding`,"gemini-api-key":`google`,"google-antigravity":`google-antigravity`,"google-gemini-cli":`google-gemini-cli`,"zai-api-key":`zai`,"zai-coding-global":`zai`,"zai-coding-cn":`zai`,"zai-global":`zai`,"zai-cn":`zai`,"xiaomi-api-key":`xiaomi`,"synthetic-api-key":`synthetic`,"venice-api-key":`venice`,"together-api-key":`together`,"huggingface-api-key":`huggingface`,"github-copilot":`github-copilot`,"copilot-proxy":`copilot-proxy`,"minimax-cloud":`minimax`,"minimax-api":`minimax`,"minimax-api-key-cn":`minimax-cn`,"minimax-api-lightning":`minimax`,minimax:`lmstudio`,"opencode-zen":`opencode`,"xai-api-key":`xai`,"litellm-api-key":`litellm`,"qwen-portal":`qwen-portal`,"minimax-portal":`minimax-portal`,"qianfan-api-key":`qianfan`,"custom-api-key":`custom`};function resolvePreferredProviderForAuthChoice(choice){return PREFERRED_PROVIDER_BY_AUTH_CHOICE[choice]}export{warnIfModelConfigLooksOff as n,resolvePreferredProviderForAuthChoice as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./paths-BHg-VHB4.js";import"./registry-Cv7CoWAs.js";import"./utils-BP60e80M.js";import"./subsystem-C4b1Von0.js";import"./boolean-ssGoaBPk.js";import"./env-BoE8QSib.js";import"./warning-filter-nSTjpMIH.js";import"./auth-profiles-pt7Tr4HA.js";import"./src-DvWaTze9.js";import"./logger-wuOr7HKl.js";import"./session-key-CksCYipj.js";import"./builderforce-root-DY1qbWNX.js";import"./exec-COgsU9ql.js";import"./agent-scope-CufEmNj_.js";import"./env-file-DeS6x2OL.js";import"./src-HrLX5bhG.js";import"./io-D9hC2aG0.js";import"./manifest-registry-009gLJ4l.js";import"./config-BpChMIJ6.js";import"./model-discovery-D0i1JpiL.js";import"./model-catalog-BeBXvbFm.js";import"./frontmatter-CaY7feZm.js";import"./skills-D3MwwPOH.js";import"./plugin-skills-pSFUbhg_.js";import"./refresh-C4vwneXT.js";import"./client-CGgp3zkQ.js";import"./call-Du2LiaX6.js";import"./message-channel-z5YRpR2d.js";import"./subagent-registry-DDEN4oJi.js";import"./sessions-BA8Se_bT.js";import"./project-context-store-CIUcwUP_.js";import"./tokens-CFKkpUIu.js";import"./plugins-1Mn6RiNf.js";import"./accounts-BkTLjSrD.js";import"./bindings-CKSDlQ1i.js";import"./send-B7H8Ae5j.js";import"./send-DqR7Rxzm.js";import"./with-timeout-B_p5pWDv.js";import"./deliver-CsG0cHbZ.js";import"./accounts-Cx82nj4E.js";import"./send-KgN1P41U.js";import"./image-ops-CotJhwRR.js";import"./redact-CgO7wehS.js";import"./errors-tAt19c1E.js";import"./embedded-helpers-DdU30lmt.js";import"./sandbox-DvKMuAXL.js";import"./chrome-CFmcixaE.js";import"./tailscale-DV-yOmYe.js";import"./auth-ChecwOXS.js";import"./server-context-CttALzrW.js";import"./routes-_iZdG1Fo.js";import"./paths-BnOjueoX.js";import"./ssrf-DJXLYZ0d.js";import"./store-DHD2IEgd.js";import"./ports-DTku9NSx.js";import"./trash-C3zmJ_O7.js";import"./accounts-DcoaLXKI.js";import"./paths-ClsbsPQP.js";import"./tool-images-CCpqFtrL.js";import"./workspace-waBqRxiy.js";import"./reply-prefix-Cg7AqaK0.js";import"./sqlite-CIGM1WKg.js";import"./memory-cli-CveeVOWH.js";import"./manager-BeohB4-8.js";import"./gemini-auth-DDR12zst.js";import"./retry-B151Hej5.js";import"./common-BfwMxpLu.js";import"./runner-Cu9NJouV.js";import"./tool-display-Cs4hDP1f.js";import"./chunk-Dly7lM4r.js";import"./markdown-tables-B1Rx8hv6.js";import"./fetch-guard-DnXqPKae.js";import"./fetch-Cn_THzz8.js";import"./ir-CSdQJPqu.js";import"./render-DlHYsbvQ.js";import"./builderforcellm-syscheck-9ksvqHYX.js";import"./session-utils-Dxou8SbO.js";import"./coding-tools.policy-D9Ba8eDh.js";import"./pairing-store-YRy7EBgI.js";import"./fetch-DnWD6ydH.js";import"./exec-approvals-D7ZPAZpt.js";import"./nodes-screen-D6GHv_S0.js";import"./session-cost-usage-S0nkbPoW.js";import"./usage-format-5sp5AMSu.js";import"./provider-usage-B8lFHp0K.js";import"./send-kkm_zrHQ.js";import"./outbound-attachment-BaTYE4qp.js";import"./delivery-queue-Cp3t4Upn.js";import"./project-context-D3Mx4maV.js";import"./control-service-2PkCt256.js";import"./stagger-CRe77dWL.js";import"./channel-selection-BLwXhb9t.js";import"./send-CYGOPcKq.js";import"./resolve-route-DEIW5uKy.js";import"./channel-activity-DX36RadH.js";import"./tables-CojSfTth.js";import"./links-BKzP7VVP.js";import"./cli-utils-C9pW69LF.js";import"./help-format-CfFf-w62.js";import"./progress-Cqb-jAjT.js";import"./replies-BOGMDhSN.js";import"./onboard-helpers-Ce_c4Raj.js";import"./prompt-style-BMWmaqSC.js";import"./pairing-labels-BJPrScRl.js";import"./active-listener-Di9e1YAD.js";import"./mamba-state-engine-CV4nDcCk.js";import"./transformers-stream-Buj40qHl.js";import"./shared-BBOiNdjf.js";import"./onboard-auth.credentials-DneFSdYg.js";import"./auth-token-BPHeoBAW.js";import"./logging-ayt7F7vy.js";import"./provider-auth-helpers-hNwpK_hl.js";import{t as applyAuthChoice}from"./auth-choice.apply-BgOXoS8X.js";import"./openai-model-default-pfoEzWYJ.js";import"./model-picker-CGDNPRPc.js";import"./auth-choice.apply.transformers-DmdxpHGz.js";import{n as warnIfModelConfigLooksOff,t as resolvePreferredProviderForAuthChoice}from"./auth-choice-DzBqqq7i.js";export{applyAuthChoice,resolvePreferredProviderForAuthChoice,warnIfModelConfigLooksOff};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{H as resolveConfiguredModelRef,Xt as resolveModelAuthMode,_n as DEFAULT_PROVIDER,b as ensureAuthProfileStore,gn as DEFAULT_MODEL,h as listProfilesForProvider}from"./auth-profiles-
|
|
1
|
+
import{H as resolveConfiguredModelRef,Xt as resolveModelAuthMode,_n as DEFAULT_PROVIDER,b as ensureAuthProfileStore,gn as DEFAULT_MODEL,h as listProfilesForProvider}from"./auth-profiles-pt7Tr4HA.js";import{o as resolveAgentModelPrimary}from"./agent-scope-CufEmNj_.js";import{r as loadModelCatalog}from"./model-catalog-BeBXvbFm.js";import{s as OPENAI_CODEX_DEFAULT_MODEL}from"./model-picker-CGDNPRPc.js";async function warnIfModelConfigLooksOff(config,prompter,options){let agentModelOverride=options?.agentId?resolveAgentModelPrimary(config,options.agentId):void 0,configWithModel=agentModelOverride&&agentModelOverride.length>0?{...config,agents:{...config.agents,defaults:{...config.agents?.defaults,model:{...typeof config.agents?.defaults?.model==`object`?config.agents.defaults.model:void 0,primary:agentModelOverride}}}}:config,ref=resolveConfiguredModelRef({cfg:configWithModel,defaultProvider:DEFAULT_PROVIDER,defaultModel:DEFAULT_MODEL}),warnings=[],catalog=await loadModelCatalog({config:configWithModel,useCache:!1});catalog.length>0&&(catalog.some(entry=>entry.provider===ref.provider&&entry.id===ref.model)||warnings.push(`Model not found: ${ref.provider}/${ref.model}. Update agents.defaults.model or run /models list.`));let store=await ensureAuthProfileStore(options?.agentDir);await resolveModelAuthMode(ref.provider,configWithModel,store)===`unknown`&&warnings.push(`No auth configured for provider "${ref.provider}". The agent may fail until credentials are added.`),ref.provider===`openai`&&listProfilesForProvider(store,`openai-codex`).length>0&&warnings.push(`Detected OpenAI Codex OAuth. Consider setting agents.defaults.model to ${OPENAI_CODEX_DEFAULT_MODEL}.`),warnings.length>0&&await prompter.note(warnings.join(`
|
|
2
2
|
`),`Model check`)}const PREFERRED_PROVIDER_BY_AUTH_CHOICE={oauth:`anthropic`,"setup-token":`anthropic`,"claude-cli":`anthropic`,token:`anthropic`,apiKey:`anthropic`,builderforcellm:`builderforcellm`,vllm:`vllm`,"openai-codex":`openai-codex`,"codex-cli":`openai-codex`,chutes:`chutes`,"openai-api-key":`openai`,"openrouter-api-key":`openrouter`,"ai-gateway-api-key":`vercel-ai-gateway`,"cloudflare-ai-gateway-api-key":`cloudflare-ai-gateway`,"moonshot-api-key":`moonshot`,"moonshot-api-key-cn":`moonshot`,"kimi-code-api-key":`kimi-coding`,"gemini-api-key":`google`,"google-antigravity":`google-antigravity`,"google-gemini-cli":`google-gemini-cli`,"zai-api-key":`zai`,"zai-coding-global":`zai`,"zai-coding-cn":`zai`,"zai-global":`zai`,"zai-cn":`zai`,"xiaomi-api-key":`xiaomi`,"synthetic-api-key":`synthetic`,"venice-api-key":`venice`,"together-api-key":`together`,"huggingface-api-key":`huggingface`,"github-copilot":`github-copilot`,"copilot-proxy":`copilot-proxy`,"minimax-cloud":`minimax`,"minimax-api":`minimax`,"minimax-api-key-cn":`minimax-cn`,"minimax-api-lightning":`minimax`,minimax:`lmstudio`,"opencode-zen":`opencode`,"xai-api-key":`xai`,"litellm-api-key":`litellm`,"qwen-portal":`qwen-portal`,"minimax-portal":`minimax-portal`,"qianfan-api-key":`qianfan`,"custom-api-key":`custom`};function resolvePreferredProviderForAuthChoice(choice){return PREFERRED_PROVIDER_BY_AUTH_CHOICE[choice]}export{warnIfModelConfigLooksOff as n,resolvePreferredProviderForAuthChoice as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./paths-5FcIFMsj.js";import"./utils-DbaBVFaK.js";import"./embedded-helpers-C9jpiwlw.js";import"./reply-GY1C8tcv.js";import"./session-key-EoB0qaG9.js";import"./builderforce-root-D64_sXEi.js";import"./subsystem-B3TqcCrZ.js";import"./registry-TdK-aV05.js";import"./logger-Bch0bx9c.js";import"./exec-DdcIjeyn.js";import"./agent-scope-DPtjOxzp.js";import"./src-CA0fU67C.js";import"./model-selection-DG9J_VTz.js";import"./env-file-D1MDi-AM.js";import"./boolean-Cnh1KNl1.js";import"./env-BIdU5BAp.js";import"./src-DTFqOIQD.js";import"./io-BLBq4T2o.js";import"./manifest-registry-BJCfNV1a.js";import"./config-BgV_FYSq.js";import"./runner-eTTUbLAK.js";import"./model-catalog-DjNiebr7.js";import"./sandbox-C4AKi2EX.js";import"./chrome-DXt86tmV.js";import"./tailscale-DLkpGquM.js";import"./auth-lebUHrkd.js";import"./server-context-CQ2v4BAx.js";import"./frontmatter-3D1EdC1L.js";import"./skills-Ba4ftrB-.js";import"./plugin-skills-B11rggZh.js";import"./routes-DZntyPY6.js";import"./redact-BHdfp2MZ.js";import"./errors-B1MIg3g-.js";import"./paths-cR8ct-Y3.js";import"./ssrf-p9k-iapc.js";import"./image-ops-C8IUQKjn.js";import"./store-CmHBQ-yX.js";import"./ports-DgmEDNOm.js";import"./trash-DD2Hc5oq.js";import"./sessions-BuZVmOWt.js";import"./message-channel-D_jXxXQj.js";import"./plugins-D5zP6ENo.js";import"./accounts-o35LU_iy.js";import"./accounts-rmXEiebi.js";import"./accounts-BLueHgKj.js";import"./bindings-DR59065T.js";import"./send-Aw8wK3vK.js";import"./send-ChGpVO3O.js";import"./paths-DJ6rztqJ.js";import"./tool-images-B7b_OiMz.js";import"./tool-display-ByOZtWvA.js";import"./fetch-guard-8mwt3-hm.js";import"./api-key-rotation-CyCi-UqR.js";import"./fetch-BuOLY9KP.js";import"./sqlite-C39E12XS.js";import"./tokens-CCU3zO-D.js";import"./project-context-store-wcq7lXuI.js";import"./with-timeout-GDLpcjW7.js";import"./deliver--6OBF3LL.js";import"./send-BxoVLIy1.js";import"./workspace-D4LK4thI.js";import"./reply-prefix-zIMgi6K6.js";import"./memory-cli-CbkWGjRn.js";import"./manager-DSz61dXv.js";import"./retry-DlVhg5qu.js";import"./client-xfoidwPI.js";import"./call-T8ciwMTA.js";import"./common-BTbIhLyt.js";import"./chunk-FCBlVOyo.js";import"./markdown-tables-P6uoUSFa.js";import"./ir-5BNoIXZm.js";import"./render-D1dVTEB1.js";import"./builderforcellm-syscheck-F5JMAr3p.js";import"./send-BP5osGBo.js";import"./outbound-attachment-C7wByQO5.js";import"./fetch-DnVtDecb.js";import"./delivery-queue-CXKynF1P.js";import"./channel-activity-CCNDbdD3.js";import"./tables-ERcoWFDp.js";import"./pairing-store-ti3FEkmr.js";import"./links-BgWWaaOT.js";import"./cli-utils-LBYKdNFb.js";import"./help-format-Qfk2vDNX.js";import"./progress-BfOtdN6b.js";import"./resolve-route-D49haUnv.js";import"./replies-DokbEfJD.js";import"./refresh-TiC_kLgE.js";import"./coding-tools.policy-ZhOdlcEI.js";import"./send-l3ge4wkC.js";import"./onboard-helpers-CiHzTaFX.js";import"./prompt-style-BpVK43GK.js";import"./pairing-labels-oA-nKTaW.js";import"./session-cost-usage-BjH7mxVj.js";import"./usage-format-DGf8ZWPH.js";import"./provider-usage-B-wPVN_j.js";import"./active-listener-Dcg19lJG.js";import"./exec-approvals-BpVPDVtV.js";import"./nodes-screen-C3TDIi8d.js";import"./project-context-CJj0Inz-.js";import"./control-service-y3GYvIBg.js";import"./stagger-8EkqkqJv.js";import"./channel-selection-DyAvzlY8.js";import"./mamba-state-engine-CoGqoBTH.js";import"./transformers-stream-D7nRu4Qu.js";import"./shared-C2orjbTD.js";import"./onboard-auth.credentials-DpitLlzw.js";import"./auth-token-BE67qxLw.js";import"./logging-DHa3jQN3.js";import"./provider-auth-helpers-B84m5VMc.js";import{t as applyAuthChoice}from"./auth-choice.apply-DBuvopiF.js";import"./openai-model-default-CH2-2Hvk.js";import"./model-picker-EIhpfOZa.js";import"./auth-choice.apply.transformers-Df9l_jRz.js";export{applyAuthChoice};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{T as resolveBuilderForceAgentsAgentDir,Yt as resolveEnvApiKey,b as ensureAuthProfileStore,c as CHUTES_AUTHORIZE_ENDPOINT,d as parseOAuthCallbackInput,dn as isHuggingfacePolicyLocked,f as loginOpenAICodex,fn as CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF,gt as SYNTHETIC_DEFAULT_MODEL_REF,l as exchangeChutesCodeForTokens,lt as VENICE_DEFAULT_MODEL_REF,st as resolveOllamaApiBase,t as resolveAuthProfileOrder,u as generateChutesPkce,un as discoverHuggingfaceModels,v as upsertAuthProfile,y as upsertAuthProfileWithLock}from"./auth-profiles-
|
|
1
|
+
import{T as resolveBuilderForceAgentsAgentDir,Yt as resolveEnvApiKey,b as ensureAuthProfileStore,c as CHUTES_AUTHORIZE_ENDPOINT,d as parseOAuthCallbackInput,dn as isHuggingfacePolicyLocked,f as loginOpenAICodex,fn as CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF,gt as SYNTHETIC_DEFAULT_MODEL_REF,l as exchangeChutesCodeForTokens,lt as VENICE_DEFAULT_MODEL_REF,st as resolveOllamaApiBase,t as resolveAuthProfileOrder,u as generateChutesPkce,un as discoverHuggingfaceModels,v as upsertAuthProfile,y as upsertAuthProfileWithLock}from"./auth-profiles-pt7Tr4HA.js";import{a as currentAnthropicModelId}from"./src-DvWaTze9.js";import{c as resolveAgentWorkspaceDir,i as resolveAgentDir,k as resolveDefaultAgentWorkspaceDir,l as resolveDefaultAgentId}from"./agent-scope-CufEmNj_.js";import{t as normalizeBaseUrl$1}from"./normalize-base-url-D_sv6Zgt.js";import{a as upsertSharedEnvVar}from"./env-file-DeS6x2OL.js";import{n as isLoopbackHost}from"./net-DtnXq2dW.js";import{d as openUrl}from"./onboard-helpers-Ce_c4Raj.js";import{t as enablePluginInConfig}from"./enable-vNR-vlAd.js";import{C as setXaiApiKey,D as KIMI_CODING_MODEL_REF,E as writeOAuthCredentials,F as QIANFAN_DEFAULT_MODEL_REF,P as MOONSHOT_DEFAULT_MODEL_REF,R as XAI_DEFAULT_MODEL_REF,S as setVercelAiGatewayApiKey,T as setZaiApiKey,_ as setOpenrouterApiKey,a as VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF,b as setTogetherApiKey,c as setAnthropicApiKey,d as setHuggingfaceApiKey,f as setKimiCodingApiKey,g as setOpencodeZenApiKey,h as setMoonshotApiKey,i as TOGETHER_DEFAULT_MODEL_REF,l as setCloudflareAiGatewayConfig,m as setMinimaxApiKey,n as LITELLM_DEFAULT_MODEL_REF,o as XIAOMI_DEFAULT_MODEL_REF,p as setLitellmApiKey,r as OPENROUTER_DEFAULT_MODEL_REF,s as ZAI_DEFAULT_MODEL_REF,t as HUGGINGFACE_DEFAULT_MODEL_REF,u as setGeminiApiKey,v as setQianfanApiKey,w as setXiaomiApiKey,x as setVeniceApiKey,y as setSyntheticApiKey}from"./onboard-auth.credentials-DneFSdYg.js";import{A as applyXaiConfig,B as applyVercelAiGatewayConfig,C as applyQianfanProviderConfig,D as applyTogetherProviderConfig,E as applyTogetherConfig,F as applyZaiProviderConfig,H as applyAgentDefaultModelPrimary,I as applyLitellmConfig,L as applyLitellmProviderConfig,M as applyXiaomiConfig,N as applyXiaomiProviderConfig,O as applyVeniceConfig,P as applyZaiConfig,R as applyCloudflareAiGatewayConfig,S as applyQianfanConfig,T as applySyntheticProviderConfig,V as applyVercelAiGatewayProviderConfig,_ as applyMoonshotConfigCn,a as applyMinimaxApiConfig,b as applyOpenrouterConfig,c as applyMinimaxApiProviderConfigCn,d as applyAuthProfileConfig,g as applyMoonshotConfig,h as applyKimiCodeProviderConfig,i as applyOpencodeZenProviderConfig,j as applyXaiProviderConfig,k as applyVeniceProviderConfig,l as applyMinimaxConfig,m as applyKimiCodeConfig,n as validateAnthropicSetupToken,o as applyMinimaxApiConfigCn,p as applyHuggingfaceProviderConfig,r as applyOpencodeZenConfig,s as applyMinimaxApiProviderConfig,t as buildTokenProfileId,u as applyMinimaxProviderConfig,v as applyMoonshotProviderConfig,w as applySyntheticConfig,x as applyOpenrouterProviderConfig,y as applyMoonshotProviderConfigCn,z as applyCloudflareAiGatewayProviderConfig}from"./auth-token-BPHeoBAW.js";import{a as createVpsAwareOAuthHandlers,c as githubCopilotLoginCommand,i as resolveProviderMatch,n as mergeConfigPatch,o as isRemoteEnvironment,r as pickAuthMethod,s as resolvePluginProviders,t as applyDefaultModel}from"./provider-auth-helpers-hNwpK_hl.js";import{a as GOOGLE_GEMINI_DEFAULT_MODEL,i as detectZaiEndpoint,n as applyOpenAIConfig,o as applyGoogleGeminiModelDefault,r as applyOpenAIProviderConfig,s as ensureModelAllowlistEntry,t as OPENAI_DEFAULT_MODEL}from"./openai-model-default-pfoEzWYJ.js";import{c as applyOpenAICodexModelDefault,o as promptAndConfigureVllm,r as applyPrimaryModel,s as OPENAI_CODEX_DEFAULT_MODEL}from"./model-picker-CGDNPRPc.js";import{s as applyAuthChoiceTransformers}from"./auth-choice.apply.transformers-DmdxpHGz.js";import{randomBytes}from"node:crypto";import{createServer}from"node:http";const DEFAULT_KEY_PREVIEW={head:4,tail:4};function normalizeApiKeyInput(raw){let trimmed=String(raw??``).trim();if(!trimmed)return``;let assignmentMatch=trimmed.match(/^(?:export\s+)?[A-Za-z_][A-Za-z0-9_]*\s*=\s*(.+)$/),valuePart=assignmentMatch?assignmentMatch[1].trim():trimmed,unquoted=valuePart.length>=2&&(valuePart.startsWith(`"`)&&valuePart.endsWith(`"`)||valuePart.startsWith(`'`)&&valuePart.endsWith(`'`)||valuePart.startsWith("`")&&valuePart.endsWith("`"))?valuePart.slice(1,-1):valuePart;return(unquoted.endsWith(`;`)?unquoted.slice(0,-1):unquoted).trim()}const validateApiKeyInput=value=>normalizeApiKeyInput(value).length>0?void 0:`Required`;function formatApiKeyPreview(raw,opts={}){let trimmed=raw.trim();if(!trimmed)return`…`;let head=opts.head??DEFAULT_KEY_PREVIEW.head,tail=opts.tail??DEFAULT_KEY_PREVIEW.tail;if(trimmed.length<=head+tail){let shortHead=Math.min(2,trimmed.length),shortTail=Math.min(2,trimmed.length-shortHead);return shortTail<=0?`${trimmed.slice(0,shortHead)}…`:`${trimmed.slice(0,shortHead)}…${trimmed.slice(-shortTail)}`}return`${trimmed.slice(0,head)}…${trimmed.slice(-tail)}`}const DEFAULT_ANTHROPIC_MODEL=`anthropic/${currentAnthropicModelId(`sonnet`)}`;async function applyAuthChoiceAnthropic(params){if(params.authChoice===`setup-token`||params.authChoice===`oauth`||params.authChoice===`token`){let nextConfig=params.config;await params.prompter.note(["Run `claude setup-token` in your terminal.",`Then paste the generated token below.`].join(`
|
|
2
2
|
`),`Anthropic setup-token`);let tokenRaw=await params.prompter.text({message:`Paste Anthropic setup-token`,validate:value=>validateAnthropicSetupToken(String(value??``))}),token=String(tokenRaw??``).trim(),profileNameRaw=await params.prompter.text({message:`Token name (blank = default)`,placeholder:`default`}),provider=`anthropic`,namedProfileId=buildTokenProfileId({provider,name:String(profileNameRaw??``)});return await upsertAuthProfile({profileId:namedProfileId,agentDir:params.agentDir,credential:{type:`token`,provider,token}}),nextConfig=applyAuthProfileConfig(nextConfig,{profileId:namedProfileId,provider,mode:`token`}),params.setDefaultModel&&(nextConfig=applyAgentDefaultModelPrimary(nextConfig,DEFAULT_ANTHROPIC_MODEL)),{config:nextConfig}}if(params.authChoice===`apiKey`){if(params.opts?.tokenProvider&¶ms.opts.tokenProvider!==`anthropic`)return null;let nextConfig=params.config,hasCredential=!1,envKey=process.env.ANTHROPIC_API_KEY?.trim();if(params.opts?.token&&(await setAnthropicApiKey(normalizeApiKeyInput(params.opts.token),params.agentDir),hasCredential=!0),!hasCredential&&envKey&&await params.prompter.confirm({message:`Use existing ANTHROPIC_API_KEY (env, ${formatApiKeyPreview(envKey)})?`,initialValue:!0})&&(await setAnthropicApiKey(envKey,params.agentDir),hasCredential=!0),!hasCredential){let key=await params.prompter.text({message:`Enter Anthropic API key`,validate:validateApiKeyInput});await setAnthropicApiKey(normalizeApiKeyInput(String(key??``)),params.agentDir)}return nextConfig=applyAuthProfileConfig(nextConfig,{profileId:`anthropic:default`,provider:`anthropic`,mode:`api_key`}),params.setDefaultModel&&(nextConfig=applyAgentDefaultModelPrimary(nextConfig,DEFAULT_ANTHROPIC_MODEL)),{config:nextConfig}}return null}function createAuthChoiceAgentModelNoter(params){return async model=>{params.agentId&&await params.prompter.note(`Default model set to ${model} for agent "${params.agentId}".`,`Model configured`)}}async function applyDefaultModelChoice(params){if(params.setDefaultModel){let next=params.applyDefaultConfig(params.config);return params.noteDefault&&await params.prompter.note(`Default model set to ${params.noteDefault}`,`Model configured`),{config:next}}let nextWithModel=ensureModelAllowlistEntry({cfg:params.applyProviderConfig(params.config),modelRef:params.defaultModel});return await params.noteAgentModel(params.defaultModel),{config:nextWithModel,agentModelOverride:params.defaultModel}}async function applyAuthChoiceHuggingface(params){if(params.authChoice!==`huggingface-api-key`)return null;let nextConfig=params.config,agentModelOverride,noteAgentModel=createAuthChoiceAgentModelNoter(params),hasCredential=!1,hfKey=``;if(!hasCredential&¶ms.opts?.token&¶ms.opts.tokenProvider===`huggingface`&&(hfKey=normalizeApiKeyInput(params.opts.token),await setHuggingfaceApiKey(hfKey,params.agentDir),hasCredential=!0),hasCredential||await params.prompter.note([`Hugging Face Inference Providers offer OpenAI-compatible chat completions.`,`Create a token at: https://huggingface.co/settings/tokens (fine-grained, 'Make calls to Inference Providers').`].join(`
|
|
3
3
|
`),`Hugging Face`),!hasCredential){let envKey=resolveEnvApiKey(`huggingface`);envKey&&await params.prompter.confirm({message:`Use existing Hugging Face token (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,initialValue:!0})&&(hfKey=envKey.apiKey,await setHuggingfaceApiKey(hfKey,params.agentDir),hasCredential=!0)}if(!hasCredential){let key=await params.prompter.text({message:`Enter Hugging Face API key (HF token)`,validate:validateApiKeyInput});hfKey=normalizeApiKeyInput(String(key??``)),await setHuggingfaceApiKey(hfKey,params.agentDir)}nextConfig=applyAuthProfileConfig(nextConfig,{profileId:`huggingface:default`,provider:`huggingface`,mode:`api_key`});let models=await discoverHuggingfaceModels(hfKey),options=[];for(let m of models){let baseRef=`huggingface/${m.id}`,label=m.name??m.id;options.push({value:baseRef,label}),options.push({value:`${baseRef}:cheapest`,label:`${label} (cheapest)`}),options.push({value:`${baseRef}:fastest`,label:`${label} (fastest)`})}let defaultRef=HUGGINGFACE_DEFAULT_MODEL_REF;options.sort((a,b)=>a.value===defaultRef?-1:b.value===defaultRef?1:a.label.localeCompare(b.label,void 0,{sensitivity:`base`}));let selectedModelRef=options.length===0?defaultRef:options.length===1?options[0].value:await params.prompter.select({message:`Default Hugging Face model`,options,initialValue:options.some(o=>o.value===defaultRef)?defaultRef:options[0].value});isHuggingfacePolicyLocked(selectedModelRef)&&await params.prompter.note(`Provider locked — router will choose backend by cost or speed.`,`Hugging Face`);let applied=await applyDefaultModelChoice({config:nextConfig,setDefaultModel:params.setDefaultModel,defaultModel:selectedModelRef,applyDefaultConfig:config=>{let withProvider=applyHuggingfaceProviderConfig(config),existingModel=withProvider.agents?.defaults?.model;return ensureModelAllowlistEntry({cfg:{...withProvider,agents:{...withProvider.agents,defaults:{...withProvider.agents?.defaults,model:{...existingModel&&typeof existingModel==`object`&&`fallbacks`in existingModel?{fallbacks:existingModel.fallbacks}:{},primary:selectedModelRef}}}},modelRef:selectedModelRef})},applyProviderConfig:applyHuggingfaceProviderConfig,noteDefault:selectedModelRef,noteAgentModel,prompter:params.prompter});return nextConfig=applied.config,agentModelOverride=applied.agentModelOverride??agentModelOverride,{config:nextConfig,agentModelOverride}}async function applyAuthChoiceOpenRouter(params){let nextConfig=params.config,agentModelOverride,noteAgentModel=createAuthChoiceAgentModelNoter(params),store=await ensureAuthProfileStore(params.agentDir,{allowKeychainPrompt:!1}),existingProfileId=resolveAuthProfileOrder({cfg:nextConfig,store,provider:`openrouter`}).find(profileId=>!!store.profiles[profileId]),existingCred=existingProfileId?store.profiles[existingProfileId]:void 0,profileId=`openrouter:default`,mode=`api_key`,hasCredential=!1;if(existingProfileId&&existingCred?.type&&(profileId=existingProfileId,mode=existingCred.type===`oauth`?`oauth`:existingCred.type===`token`?`token`:`api_key`,hasCredential=!0),!hasCredential&¶ms.opts?.token&¶ms.opts?.tokenProvider===`openrouter`&&(await setOpenrouterApiKey(normalizeApiKeyInput(params.opts.token),params.agentDir),hasCredential=!0),!hasCredential){let envKey=resolveEnvApiKey(`openrouter`);envKey&&await params.prompter.confirm({message:`Use existing OPENROUTER_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,initialValue:!0})&&(await setOpenrouterApiKey(envKey.apiKey,params.agentDir),hasCredential=!0)}if(!hasCredential){let key=await params.prompter.text({message:`Enter OpenRouter API key`,validate:validateApiKeyInput});await setOpenrouterApiKey(normalizeApiKeyInput(String(key??``)),params.agentDir),hasCredential=!0}hasCredential&&(nextConfig=applyAuthProfileConfig(nextConfig,{profileId,provider:`openrouter`,mode}));let applied=await applyDefaultModelChoice({config:nextConfig,setDefaultModel:params.setDefaultModel,defaultModel:OPENROUTER_DEFAULT_MODEL_REF,applyDefaultConfig:applyOpenrouterConfig,applyProviderConfig:applyOpenrouterProviderConfig,noteDefault:OPENROUTER_DEFAULT_MODEL_REF,noteAgentModel,prompter:params.prompter});return nextConfig=applied.config,agentModelOverride=applied.agentModelOverride??agentModelOverride,{config:nextConfig,agentModelOverride}}const OPENCODE_ZEN_DEFAULT_MODEL=`opencode/claude-opus-4-6`;async function applyAuthChoiceApiProviders(params){let nextConfig=params.config,agentModelOverride,noteAgentModel=createAuthChoiceAgentModelNoter(params),authChoice=params.authChoice;authChoice===`apiKey`&¶ms.opts?.tokenProvider&¶ms.opts.tokenProvider!==`anthropic`&¶ms.opts.tokenProvider!==`openai`&&(params.opts.tokenProvider===`openrouter`?authChoice=`openrouter-api-key`:params.opts.tokenProvider===`litellm`?authChoice=`litellm-api-key`:params.opts.tokenProvider===`vercel-ai-gateway`?authChoice=`ai-gateway-api-key`:params.opts.tokenProvider===`cloudflare-ai-gateway`?authChoice=`cloudflare-ai-gateway-api-key`:params.opts.tokenProvider===`moonshot`?authChoice=`moonshot-api-key`:params.opts.tokenProvider===`kimi-code`||params.opts.tokenProvider===`kimi-coding`?authChoice=`kimi-code-api-key`:params.opts.tokenProvider===`google`?authChoice=`gemini-api-key`:params.opts.tokenProvider===`zai`?authChoice=`zai-api-key`:params.opts.tokenProvider===`xiaomi`?authChoice=`xiaomi-api-key`:params.opts.tokenProvider===`synthetic`?authChoice=`synthetic-api-key`:params.opts.tokenProvider===`venice`?authChoice=`venice-api-key`:params.opts.tokenProvider===`together`?authChoice=`together-api-key`:params.opts.tokenProvider===`huggingface`?authChoice=`huggingface-api-key`:params.opts.tokenProvider===`opencode`?authChoice=`opencode-zen`:params.opts.tokenProvider===`qianfan`&&(authChoice=`qianfan-api-key`));async function ensureMoonshotApiKeyCredential(promptMessage){let hasCredential=!1;!hasCredential&¶ms.opts?.token&¶ms.opts?.tokenProvider===`moonshot`&&(await setMoonshotApiKey(normalizeApiKeyInput(params.opts.token),params.agentDir),hasCredential=!0);let envKey=resolveEnvApiKey(`moonshot`);if(envKey&&await params.prompter.confirm({message:`Use existing MOONSHOT_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,initialValue:!0})&&(await setMoonshotApiKey(envKey.apiKey,params.agentDir),hasCredential=!0),!hasCredential){let key=await params.prompter.text({message:promptMessage,validate:validateApiKeyInput});await setMoonshotApiKey(normalizeApiKeyInput(String(key??``)),params.agentDir)}}if(authChoice===`openrouter-api-key`)return applyAuthChoiceOpenRouter(params);if(authChoice===`builderforcellm`){await params.prompter.note(`Using BuilderForceAgentsLLM default proxy (no local API key required).`,`BuilderForceAgentsLLM`);let defaultModel=`builderforcellm/auto`,applied=await applyDefaultModelChoice({config:nextConfig,setDefaultModel:params.setDefaultModel,defaultModel,applyDefaultConfig:config=>applyAgentDefaultModelPrimary(config,defaultModel),applyProviderConfig:config=>config,noteDefault:defaultModel,noteAgentModel,prompter:params.prompter});return nextConfig=applied.config,agentModelOverride=applied.agentModelOverride??agentModelOverride,{config:nextConfig,agentModelOverride}}if(authChoice===`litellm-api-key`){let store=await ensureAuthProfileStore(params.agentDir,{allowKeychainPrompt:!1}),existingProfileId=resolveAuthProfileOrder({cfg:nextConfig,store,provider:`litellm`}).find(profileId=>!!store.profiles[profileId]),existingCred=existingProfileId?store.profiles[existingProfileId]:void 0,profileId=`litellm:default`,hasCredential=!1;if(existingProfileId&&existingCred?.type===`api_key`&&(profileId=existingProfileId,hasCredential=!0),!hasCredential&¶ms.opts?.token&¶ms.opts?.tokenProvider===`litellm`&&(await setLitellmApiKey(normalizeApiKeyInput(params.opts.token),params.agentDir),hasCredential=!0),!hasCredential){await params.prompter.note(`LiteLLM provides a unified API to 100+ LLM providers.
|
|
4
4
|
Get your API key from your LiteLLM proxy or https://litellm.ai
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as resolveAgentWorkspaceDir,i as resolveAgentDir,k as resolveDefaultAgentWorkspaceDir,l as resolveDefaultAgentId}from"./agent-scope-DPtjOxzp.js";import{a as currentAnthropicModelId}from"./src-CA0fU67C.js";import{F as VENICE_DEFAULT_MODEL_REF,Ft as isHuggingfacePolicyLocked,H as SYNTHETIC_DEFAULT_MODEL_REF,It as CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF,Jt as generateChutesPkce,Kt as CHUTES_AUTHORIZE_ENDPOINT,N as resolveOllamaApiBase,Pt as discoverHuggingfaceModels,Xt as loginOpenAICodex,Yt as parseOAuthCallbackInput,in as ensureAuthProfileStore,ln as resolveBuilderForceAgentsAgentDir,nn as upsertAuthProfile,qt as exchangeChutesCodeForTokens,rn as upsertAuthProfileWithLock,xt as resolveEnvApiKey,zt as resolveAuthProfileOrder}from"./model-selection-
|
|
1
|
+
import{c as resolveAgentWorkspaceDir,i as resolveAgentDir,k as resolveDefaultAgentWorkspaceDir,l as resolveDefaultAgentId}from"./agent-scope-DPtjOxzp.js";import{a as currentAnthropicModelId}from"./src-CA0fU67C.js";import{F as VENICE_DEFAULT_MODEL_REF,Ft as isHuggingfacePolicyLocked,H as SYNTHETIC_DEFAULT_MODEL_REF,It as CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF,Jt as generateChutesPkce,Kt as CHUTES_AUTHORIZE_ENDPOINT,N as resolveOllamaApiBase,Pt as discoverHuggingfaceModels,Xt as loginOpenAICodex,Yt as parseOAuthCallbackInput,in as ensureAuthProfileStore,ln as resolveBuilderForceAgentsAgentDir,nn as upsertAuthProfile,qt as exchangeChutesCodeForTokens,rn as upsertAuthProfileWithLock,xt as resolveEnvApiKey,zt as resolveAuthProfileOrder}from"./model-selection-DG9J_VTz.js";import{t as normalizeBaseUrl$1}from"./normalize-base-url-DmugqkQ6.js";import{a as upsertSharedEnvVar}from"./env-file-D1MDi-AM.js";import{r as isLoopbackHost}from"./ws-Bbu03j3h.js";import{d as openUrl}from"./onboard-helpers-CiHzTaFX.js";import{t as enablePluginInConfig}from"./enable-Dm2hiZTt.js";import{C as setXaiApiKey,D as KIMI_CODING_MODEL_REF,E as writeOAuthCredentials,F as QIANFAN_DEFAULT_MODEL_REF,P as MOONSHOT_DEFAULT_MODEL_REF,R as XAI_DEFAULT_MODEL_REF,S as setVercelAiGatewayApiKey,T as setZaiApiKey,_ as setOpenrouterApiKey,a as VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF,b as setTogetherApiKey,c as setAnthropicApiKey,d as setHuggingfaceApiKey,f as setKimiCodingApiKey,g as setOpencodeZenApiKey,h as setMoonshotApiKey,i as TOGETHER_DEFAULT_MODEL_REF,l as setCloudflareAiGatewayConfig,m as setMinimaxApiKey,n as LITELLM_DEFAULT_MODEL_REF,o as XIAOMI_DEFAULT_MODEL_REF,p as setLitellmApiKey,r as OPENROUTER_DEFAULT_MODEL_REF,s as ZAI_DEFAULT_MODEL_REF,t as HUGGINGFACE_DEFAULT_MODEL_REF,u as setGeminiApiKey,v as setQianfanApiKey,w as setXiaomiApiKey,x as setVeniceApiKey,y as setSyntheticApiKey}from"./onboard-auth.credentials-DpitLlzw.js";import{A as applyXaiConfig,B as applyVercelAiGatewayConfig,C as applyQianfanProviderConfig,D as applyTogetherProviderConfig,E as applyTogetherConfig,F as applyZaiProviderConfig,H as applyAgentDefaultModelPrimary,I as applyLitellmConfig,L as applyLitellmProviderConfig,M as applyXiaomiConfig,N as applyXiaomiProviderConfig,O as applyVeniceConfig,P as applyZaiConfig,R as applyCloudflareAiGatewayConfig,S as applyQianfanConfig,T as applySyntheticProviderConfig,V as applyVercelAiGatewayProviderConfig,_ as applyMoonshotConfigCn,a as applyMinimaxApiConfig,b as applyOpenrouterConfig,c as applyMinimaxApiProviderConfigCn,d as applyAuthProfileConfig,g as applyMoonshotConfig,h as applyKimiCodeProviderConfig,i as applyOpencodeZenProviderConfig,j as applyXaiProviderConfig,k as applyVeniceProviderConfig,l as applyMinimaxConfig,m as applyKimiCodeConfig,n as validateAnthropicSetupToken,o as applyMinimaxApiConfigCn,p as applyHuggingfaceProviderConfig,r as applyOpencodeZenConfig,s as applyMinimaxApiProviderConfig,t as buildTokenProfileId,u as applyMinimaxProviderConfig,v as applyMoonshotProviderConfig,w as applySyntheticConfig,x as applyOpenrouterProviderConfig,y as applyMoonshotProviderConfigCn,z as applyCloudflareAiGatewayProviderConfig}from"./auth-token-BE67qxLw.js";import{a as createVpsAwareOAuthHandlers,c as githubCopilotLoginCommand,i as resolveProviderMatch,n as mergeConfigPatch,o as isRemoteEnvironment,r as pickAuthMethod,s as resolvePluginProviders,t as applyDefaultModel}from"./provider-auth-helpers-B84m5VMc.js";import{a as GOOGLE_GEMINI_DEFAULT_MODEL,i as detectZaiEndpoint,n as applyOpenAIConfig,o as applyGoogleGeminiModelDefault,r as applyOpenAIProviderConfig,s as ensureModelAllowlistEntry,t as OPENAI_DEFAULT_MODEL}from"./openai-model-default-CH2-2Hvk.js";import{c as applyOpenAICodexModelDefault,o as promptAndConfigureVllm,r as applyPrimaryModel,s as OPENAI_CODEX_DEFAULT_MODEL}from"./model-picker-EIhpfOZa.js";import{s as applyAuthChoiceTransformers}from"./auth-choice.apply.transformers-Df9l_jRz.js";import{randomBytes}from"node:crypto";import{createServer}from"node:http";const DEFAULT_KEY_PREVIEW={head:4,tail:4};function normalizeApiKeyInput(raw){let trimmed=String(raw??``).trim();if(!trimmed)return``;let assignmentMatch=trimmed.match(/^(?:export\s+)?[A-Za-z_][A-Za-z0-9_]*\s*=\s*(.+)$/),valuePart=assignmentMatch?assignmentMatch[1].trim():trimmed,unquoted=valuePart.length>=2&&(valuePart.startsWith(`"`)&&valuePart.endsWith(`"`)||valuePart.startsWith(`'`)&&valuePart.endsWith(`'`)||valuePart.startsWith("`")&&valuePart.endsWith("`"))?valuePart.slice(1,-1):valuePart;return(unquoted.endsWith(`;`)?unquoted.slice(0,-1):unquoted).trim()}const validateApiKeyInput=value=>normalizeApiKeyInput(value).length>0?void 0:`Required`;function formatApiKeyPreview(raw,opts={}){let trimmed=raw.trim();if(!trimmed)return`…`;let head=opts.head??DEFAULT_KEY_PREVIEW.head,tail=opts.tail??DEFAULT_KEY_PREVIEW.tail;if(trimmed.length<=head+tail){let shortHead=Math.min(2,trimmed.length),shortTail=Math.min(2,trimmed.length-shortHead);return shortTail<=0?`${trimmed.slice(0,shortHead)}…`:`${trimmed.slice(0,shortHead)}…${trimmed.slice(-shortTail)}`}return`${trimmed.slice(0,head)}…${trimmed.slice(-tail)}`}const DEFAULT_ANTHROPIC_MODEL=`anthropic/${currentAnthropicModelId(`sonnet`)}`;async function applyAuthChoiceAnthropic(params){if(params.authChoice===`setup-token`||params.authChoice===`oauth`||params.authChoice===`token`){let nextConfig=params.config;await params.prompter.note(["Run `claude setup-token` in your terminal.",`Then paste the generated token below.`].join(`
|
|
2
2
|
`),`Anthropic setup-token`);let tokenRaw=await params.prompter.text({message:`Paste Anthropic setup-token`,validate:value=>validateAnthropicSetupToken(String(value??``))}),token=String(tokenRaw??``).trim(),profileNameRaw=await params.prompter.text({message:`Token name (blank = default)`,placeholder:`default`}),provider=`anthropic`,namedProfileId=buildTokenProfileId({provider,name:String(profileNameRaw??``)});return await upsertAuthProfile({profileId:namedProfileId,agentDir:params.agentDir,credential:{type:`token`,provider,token}}),nextConfig=applyAuthProfileConfig(nextConfig,{profileId:namedProfileId,provider,mode:`token`}),params.setDefaultModel&&(nextConfig=applyAgentDefaultModelPrimary(nextConfig,DEFAULT_ANTHROPIC_MODEL)),{config:nextConfig}}if(params.authChoice===`apiKey`){if(params.opts?.tokenProvider&¶ms.opts.tokenProvider!==`anthropic`)return null;let nextConfig=params.config,hasCredential=!1,envKey=process.env.ANTHROPIC_API_KEY?.trim();if(params.opts?.token&&(await setAnthropicApiKey(normalizeApiKeyInput(params.opts.token),params.agentDir),hasCredential=!0),!hasCredential&&envKey&&await params.prompter.confirm({message:`Use existing ANTHROPIC_API_KEY (env, ${formatApiKeyPreview(envKey)})?`,initialValue:!0})&&(await setAnthropicApiKey(envKey,params.agentDir),hasCredential=!0),!hasCredential){let key=await params.prompter.text({message:`Enter Anthropic API key`,validate:validateApiKeyInput});await setAnthropicApiKey(normalizeApiKeyInput(String(key??``)),params.agentDir)}return nextConfig=applyAuthProfileConfig(nextConfig,{profileId:`anthropic:default`,provider:`anthropic`,mode:`api_key`}),params.setDefaultModel&&(nextConfig=applyAgentDefaultModelPrimary(nextConfig,DEFAULT_ANTHROPIC_MODEL)),{config:nextConfig}}return null}function createAuthChoiceAgentModelNoter(params){return async model=>{params.agentId&&await params.prompter.note(`Default model set to ${model} for agent "${params.agentId}".`,`Model configured`)}}async function applyDefaultModelChoice(params){if(params.setDefaultModel){let next=params.applyDefaultConfig(params.config);return params.noteDefault&&await params.prompter.note(`Default model set to ${params.noteDefault}`,`Model configured`),{config:next}}let nextWithModel=ensureModelAllowlistEntry({cfg:params.applyProviderConfig(params.config),modelRef:params.defaultModel});return await params.noteAgentModel(params.defaultModel),{config:nextWithModel,agentModelOverride:params.defaultModel}}async function applyAuthChoiceHuggingface(params){if(params.authChoice!==`huggingface-api-key`)return null;let nextConfig=params.config,agentModelOverride,noteAgentModel=createAuthChoiceAgentModelNoter(params),hasCredential=!1,hfKey=``;if(!hasCredential&¶ms.opts?.token&¶ms.opts.tokenProvider===`huggingface`&&(hfKey=normalizeApiKeyInput(params.opts.token),await setHuggingfaceApiKey(hfKey,params.agentDir),hasCredential=!0),hasCredential||await params.prompter.note([`Hugging Face Inference Providers offer OpenAI-compatible chat completions.`,`Create a token at: https://huggingface.co/settings/tokens (fine-grained, 'Make calls to Inference Providers').`].join(`
|
|
3
3
|
`),`Hugging Face`),!hasCredential){let envKey=resolveEnvApiKey(`huggingface`);envKey&&await params.prompter.confirm({message:`Use existing Hugging Face token (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,initialValue:!0})&&(hfKey=envKey.apiKey,await setHuggingfaceApiKey(hfKey,params.agentDir),hasCredential=!0)}if(!hasCredential){let key=await params.prompter.text({message:`Enter Hugging Face API key (HF token)`,validate:validateApiKeyInput});hfKey=normalizeApiKeyInput(String(key??``)),await setHuggingfaceApiKey(hfKey,params.agentDir)}nextConfig=applyAuthProfileConfig(nextConfig,{profileId:`huggingface:default`,provider:`huggingface`,mode:`api_key`});let models=await discoverHuggingfaceModels(hfKey),options=[];for(let m of models){let baseRef=`huggingface/${m.id}`,label=m.name??m.id;options.push({value:baseRef,label}),options.push({value:`${baseRef}:cheapest`,label:`${label} (cheapest)`}),options.push({value:`${baseRef}:fastest`,label:`${label} (fastest)`})}let defaultRef=HUGGINGFACE_DEFAULT_MODEL_REF;options.sort((a,b)=>a.value===defaultRef?-1:b.value===defaultRef?1:a.label.localeCompare(b.label,void 0,{sensitivity:`base`}));let selectedModelRef=options.length===0?defaultRef:options.length===1?options[0].value:await params.prompter.select({message:`Default Hugging Face model`,options,initialValue:options.some(o=>o.value===defaultRef)?defaultRef:options[0].value});isHuggingfacePolicyLocked(selectedModelRef)&&await params.prompter.note(`Provider locked — router will choose backend by cost or speed.`,`Hugging Face`);let applied=await applyDefaultModelChoice({config:nextConfig,setDefaultModel:params.setDefaultModel,defaultModel:selectedModelRef,applyDefaultConfig:config=>{let withProvider=applyHuggingfaceProviderConfig(config),existingModel=withProvider.agents?.defaults?.model;return ensureModelAllowlistEntry({cfg:{...withProvider,agents:{...withProvider.agents,defaults:{...withProvider.agents?.defaults,model:{...existingModel&&typeof existingModel==`object`&&`fallbacks`in existingModel?{fallbacks:existingModel.fallbacks}:{},primary:selectedModelRef}}}},modelRef:selectedModelRef})},applyProviderConfig:applyHuggingfaceProviderConfig,noteDefault:selectedModelRef,noteAgentModel,prompter:params.prompter});return nextConfig=applied.config,agentModelOverride=applied.agentModelOverride??agentModelOverride,{config:nextConfig,agentModelOverride}}async function applyAuthChoiceOpenRouter(params){let nextConfig=params.config,agentModelOverride,noteAgentModel=createAuthChoiceAgentModelNoter(params),store=await ensureAuthProfileStore(params.agentDir,{allowKeychainPrompt:!1}),existingProfileId=resolveAuthProfileOrder({cfg:nextConfig,store,provider:`openrouter`}).find(profileId=>!!store.profiles[profileId]),existingCred=existingProfileId?store.profiles[existingProfileId]:void 0,profileId=`openrouter:default`,mode=`api_key`,hasCredential=!1;if(existingProfileId&&existingCred?.type&&(profileId=existingProfileId,mode=existingCred.type===`oauth`?`oauth`:existingCred.type===`token`?`token`:`api_key`,hasCredential=!0),!hasCredential&¶ms.opts?.token&¶ms.opts?.tokenProvider===`openrouter`&&(await setOpenrouterApiKey(normalizeApiKeyInput(params.opts.token),params.agentDir),hasCredential=!0),!hasCredential){let envKey=resolveEnvApiKey(`openrouter`);envKey&&await params.prompter.confirm({message:`Use existing OPENROUTER_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,initialValue:!0})&&(await setOpenrouterApiKey(envKey.apiKey,params.agentDir),hasCredential=!0)}if(!hasCredential){let key=await params.prompter.text({message:`Enter OpenRouter API key`,validate:validateApiKeyInput});await setOpenrouterApiKey(normalizeApiKeyInput(String(key??``)),params.agentDir),hasCredential=!0}hasCredential&&(nextConfig=applyAuthProfileConfig(nextConfig,{profileId,provider:`openrouter`,mode}));let applied=await applyDefaultModelChoice({config:nextConfig,setDefaultModel:params.setDefaultModel,defaultModel:OPENROUTER_DEFAULT_MODEL_REF,applyDefaultConfig:applyOpenrouterConfig,applyProviderConfig:applyOpenrouterProviderConfig,noteDefault:OPENROUTER_DEFAULT_MODEL_REF,noteAgentModel,prompter:params.prompter});return nextConfig=applied.config,agentModelOverride=applied.agentModelOverride??agentModelOverride,{config:nextConfig,agentModelOverride}}const OPENCODE_ZEN_DEFAULT_MODEL=`opencode/claude-opus-4-6`;async function applyAuthChoiceApiProviders(params){let nextConfig=params.config,agentModelOverride,noteAgentModel=createAuthChoiceAgentModelNoter(params),authChoice=params.authChoice;authChoice===`apiKey`&¶ms.opts?.tokenProvider&¶ms.opts.tokenProvider!==`anthropic`&¶ms.opts.tokenProvider!==`openai`&&(params.opts.tokenProvider===`openrouter`?authChoice=`openrouter-api-key`:params.opts.tokenProvider===`litellm`?authChoice=`litellm-api-key`:params.opts.tokenProvider===`vercel-ai-gateway`?authChoice=`ai-gateway-api-key`:params.opts.tokenProvider===`cloudflare-ai-gateway`?authChoice=`cloudflare-ai-gateway-api-key`:params.opts.tokenProvider===`moonshot`?authChoice=`moonshot-api-key`:params.opts.tokenProvider===`kimi-code`||params.opts.tokenProvider===`kimi-coding`?authChoice=`kimi-code-api-key`:params.opts.tokenProvider===`google`?authChoice=`gemini-api-key`:params.opts.tokenProvider===`zai`?authChoice=`zai-api-key`:params.opts.tokenProvider===`xiaomi`?authChoice=`xiaomi-api-key`:params.opts.tokenProvider===`synthetic`?authChoice=`synthetic-api-key`:params.opts.tokenProvider===`venice`?authChoice=`venice-api-key`:params.opts.tokenProvider===`together`?authChoice=`together-api-key`:params.opts.tokenProvider===`huggingface`?authChoice=`huggingface-api-key`:params.opts.tokenProvider===`opencode`?authChoice=`opencode-zen`:params.opts.tokenProvider===`qianfan`&&(authChoice=`qianfan-api-key`));async function ensureMoonshotApiKeyCredential(promptMessage){let hasCredential=!1;!hasCredential&¶ms.opts?.token&¶ms.opts?.tokenProvider===`moonshot`&&(await setMoonshotApiKey(normalizeApiKeyInput(params.opts.token),params.agentDir),hasCredential=!0);let envKey=resolveEnvApiKey(`moonshot`);if(envKey&&await params.prompter.confirm({message:`Use existing MOONSHOT_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,initialValue:!0})&&(await setMoonshotApiKey(envKey.apiKey,params.agentDir),hasCredential=!0),!hasCredential){let key=await params.prompter.text({message:promptMessage,validate:validateApiKeyInput});await setMoonshotApiKey(normalizeApiKeyInput(String(key??``)),params.agentDir)}}if(authChoice===`openrouter-api-key`)return applyAuthChoiceOpenRouter(params);if(authChoice===`builderforcellm`){await params.prompter.note(`Using BuilderForceAgentsLLM default proxy (no local API key required).`,`BuilderForceAgentsLLM`);let defaultModel=`builderforcellm/auto`,applied=await applyDefaultModelChoice({config:nextConfig,setDefaultModel:params.setDefaultModel,defaultModel,applyDefaultConfig:config=>applyAgentDefaultModelPrimary(config,defaultModel),applyProviderConfig:config=>config,noteDefault:defaultModel,noteAgentModel,prompter:params.prompter});return nextConfig=applied.config,agentModelOverride=applied.agentModelOverride??agentModelOverride,{config:nextConfig,agentModelOverride}}if(authChoice===`litellm-api-key`){let store=await ensureAuthProfileStore(params.agentDir,{allowKeychainPrompt:!1}),existingProfileId=resolveAuthProfileOrder({cfg:nextConfig,store,provider:`litellm`}).find(profileId=>!!store.profiles[profileId]),existingCred=existingProfileId?store.profiles[existingProfileId]:void 0,profileId=`litellm:default`,hasCredential=!1;if(existingProfileId&&existingCred?.type===`api_key`&&(profileId=existingProfileId,hasCredential=!0),!hasCredential&¶ms.opts?.token&¶ms.opts?.tokenProvider===`litellm`&&(await setLitellmApiKey(normalizeApiKeyInput(params.opts.token),params.agentDir),hasCredential=!0),!hasCredential){await params.prompter.note(`LiteLLM provides a unified API to 100+ LLM providers.
|
|
4
4
|
Get your API key from your LiteLLM proxy or https://litellm.ai
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./paths-BHg-VHB4.js";import"./registry-Cv7CoWAs.js";import"./utils-BP60e80M.js";import"./subsystem-C4b1Von0.js";import"./boolean-ssGoaBPk.js";import"./env-BoE8QSib.js";import"./warning-filter-nSTjpMIH.js";import"./auth-profiles-pt7Tr4HA.js";import"./src-DvWaTze9.js";import"./logger-wuOr7HKl.js";import"./session-key-CksCYipj.js";import"./builderforce-root-DY1qbWNX.js";import"./exec-COgsU9ql.js";import"./agent-scope-CufEmNj_.js";import"./env-file-DeS6x2OL.js";import"./src-HrLX5bhG.js";import"./io-D9hC2aG0.js";import"./manifest-registry-009gLJ4l.js";import"./config-BpChMIJ6.js";import"./model-discovery-D0i1JpiL.js";import"./model-catalog-BeBXvbFm.js";import"./frontmatter-CaY7feZm.js";import"./skills-D3MwwPOH.js";import"./plugin-skills-pSFUbhg_.js";import"./refresh-C4vwneXT.js";import"./client-CGgp3zkQ.js";import"./call-Du2LiaX6.js";import"./message-channel-z5YRpR2d.js";import"./subagent-registry-DDEN4oJi.js";import"./sessions-BA8Se_bT.js";import"./project-context-store-CIUcwUP_.js";import"./tokens-CFKkpUIu.js";import"./plugins-1Mn6RiNf.js";import"./accounts-BkTLjSrD.js";import"./bindings-CKSDlQ1i.js";import"./send-B7H8Ae5j.js";import"./send-DqR7Rxzm.js";import"./with-timeout-B_p5pWDv.js";import"./deliver-CsG0cHbZ.js";import"./accounts-Cx82nj4E.js";import"./send-KgN1P41U.js";import"./image-ops-CotJhwRR.js";import"./redact-CgO7wehS.js";import"./errors-tAt19c1E.js";import"./embedded-helpers-DdU30lmt.js";import"./sandbox-DvKMuAXL.js";import"./chrome-CFmcixaE.js";import"./tailscale-DV-yOmYe.js";import"./auth-ChecwOXS.js";import"./server-context-CttALzrW.js";import"./routes-_iZdG1Fo.js";import"./paths-BnOjueoX.js";import"./ssrf-DJXLYZ0d.js";import"./store-DHD2IEgd.js";import"./ports-DTku9NSx.js";import"./trash-C3zmJ_O7.js";import"./accounts-DcoaLXKI.js";import"./paths-ClsbsPQP.js";import"./tool-images-CCpqFtrL.js";import"./workspace-waBqRxiy.js";import"./reply-prefix-Cg7AqaK0.js";import"./sqlite-CIGM1WKg.js";import"./memory-cli-CveeVOWH.js";import"./manager-BeohB4-8.js";import"./gemini-auth-DDR12zst.js";import"./retry-B151Hej5.js";import"./common-BfwMxpLu.js";import"./runner-Cu9NJouV.js";import"./tool-display-Cs4hDP1f.js";import"./chunk-Dly7lM4r.js";import"./markdown-tables-B1Rx8hv6.js";import"./fetch-guard-DnXqPKae.js";import"./fetch-Cn_THzz8.js";import"./ir-CSdQJPqu.js";import"./render-DlHYsbvQ.js";import"./builderforcellm-syscheck-9ksvqHYX.js";import"./session-utils-Dxou8SbO.js";import"./coding-tools.policy-D9Ba8eDh.js";import"./pairing-store-YRy7EBgI.js";import"./fetch-DnWD6ydH.js";import"./exec-approvals-D7ZPAZpt.js";import"./nodes-screen-D6GHv_S0.js";import"./session-cost-usage-S0nkbPoW.js";import"./usage-format-5sp5AMSu.js";import"./provider-usage-B8lFHp0K.js";import"./send-kkm_zrHQ.js";import"./outbound-attachment-BaTYE4qp.js";import"./delivery-queue-Cp3t4Upn.js";import"./project-context-D3Mx4maV.js";import"./control-service-2PkCt256.js";import"./stagger-CRe77dWL.js";import"./channel-selection-BLwXhb9t.js";import"./send-CYGOPcKq.js";import"./resolve-route-DEIW5uKy.js";import"./channel-activity-DX36RadH.js";import"./tables-CojSfTth.js";import"./links-BKzP7VVP.js";import"./cli-utils-C9pW69LF.js";import"./help-format-CfFf-w62.js";import"./progress-Cqb-jAjT.js";import"./replies-BOGMDhSN.js";import"./onboard-helpers-Ce_c4Raj.js";import"./prompt-style-BMWmaqSC.js";import"./pairing-labels-BJPrScRl.js";import"./active-listener-Di9e1YAD.js";import"./mamba-state-engine-CV4nDcCk.js";import"./transformers-stream-Buj40qHl.js";import"./shared-BBOiNdjf.js";import"./onboard-auth.credentials-DneFSdYg.js";import"./auth-token-BPHeoBAW.js";import"./logging-ayt7F7vy.js";import"./provider-auth-helpers-hNwpK_hl.js";import{t as applyAuthChoice}from"./auth-choice.apply-BgOXoS8X.js";import"./openai-model-default-pfoEzWYJ.js";import"./model-picker-CGDNPRPc.js";import"./auth-choice.apply.transformers-DmdxpHGz.js";export{applyAuthChoice};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./paths-BHg-VHB4.js";import"./registry-Cv7CoWAs.js";import"./utils-BP60e80M.js";import"./subsystem-C4b1Von0.js";import"./boolean-ssGoaBPk.js";import"./env-BoE8QSib.js";import"./auth-profiles-pt7Tr4HA.js";import"./src-DvWaTze9.js";import"./logger-wuOr7HKl.js";import"./session-key-CksCYipj.js";import"./builderforce-root-DY1qbWNX.js";import"./exec-COgsU9ql.js";import"./agent-scope-CufEmNj_.js";import"./env-file-DeS6x2OL.js";import"./src-HrLX5bhG.js";import"./io-D9hC2aG0.js";import"./manifest-registry-009gLJ4l.js";import"./config-BpChMIJ6.js";import"./model-discovery-D0i1JpiL.js";import"./model-catalog-BeBXvbFm.js";import"./transformers-stream-Buj40qHl.js";import"./shared-BBOiNdjf.js";import"./model-picker-CGDNPRPc.js";import{u as downloadAndWireLocalBrain}from"./auth-choice.apply.transformers-DmdxpHGz.js";export{downloadAndWireLocalBrain};
|