squidclaw 3.0.3 → 3.0.4
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/{audio-preflight-BTYxAJjy.js → audio-preflight-BKgdc7dS.js} +4 -4
- package/dist/{audio-preflight-Dkl6Z32z.js → audio-preflight-DpCWFB4z.js} +4 -4
- package/dist/{audio-transcription-runner-Gi_h5HEE.js → audio-transcription-runner-B2BdTEps.js} +1 -1
- package/dist/{audio-transcription-runner-DBkDgluo.js → audio-transcription-runner-BnbdYMDl.js} +1 -1
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +6 -6
- package/dist/bundled/session-memory/handler.js +6 -6
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{chrome-CAd6FQEn.js → chrome-BQDCalPp.js} +8 -8
- package/dist/{chrome-pBkBuWci.js → chrome-CjxCwFA9.js} +8 -8
- package/dist/{command-registry-CvgCFxfY.js → command-registry-CxiSVXru.js} +6 -6
- package/dist/{completion-cli-BGM1V6EN.js → completion-cli-s0fxD0OE.js} +2 -2
- package/dist/{completion-cli-OrgUDc2S.js → completion-cli-slzdOlRV.js} +1 -1
- package/dist/{config-cli-DbBvjvpS.js → config-cli-C0mk9eRl.js} +1 -1
- package/dist/{config-cli-uIP4r17f.js → config-cli-DhHEA_Nc.js} +1 -1
- package/dist/{configure-BGvoAfbs.js → configure-CeLdVVyh.js} +8 -1
- package/dist/{configure-BOsTXjBw.js → configure-FRd92XZ8.js} +8 -1
- package/dist/{deliver-DBXe-ZmL.js → deliver-D-f6Wa3i.js} +1 -1
- package/dist/{deliver-BJuiq0GS.js → deliver-aL8yOYS1.js} +1 -1
- package/dist/{deliver-runtime-DHKcNQzq.js → deliver-runtime-ChVR6sR3.js} +3 -3
- package/dist/{deliver-runtime-GlnBJNCj.js → deliver-runtime-_egya0QZ.js} +3 -3
- package/dist/{deps-send-whatsapp.runtime-DdxKewuy.js → deps-send-whatsapp.runtime-CZj97m5A.js} +7 -7
- package/dist/{deps-send-whatsapp.runtime-CslTuV47.js → deps-send-whatsapp.runtime-CiG6xd2e.js} +7 -7
- package/dist/{doctor-completion-42wcUATu.js → doctor-completion-I-WDZUs1.js} +1 -1
- package/dist/{doctor-completion-D6RGDBD5.js → doctor-completion-mnJOkoQ_.js} +1 -1
- package/dist/entry.js +2 -2
- package/dist/extensionAPI.js +6 -6
- package/dist/{gateway-cli-CG3mshpO.js → gateway-cli-B5rTNvd7.js} +1 -1
- package/dist/{gateway-cli-BbPfLLT6.js → gateway-cli-BHfkbI0u.js} +1 -1
- package/dist/{image-j_UomzVG.js → image-C-C7hQ26.js} +1 -1
- package/dist/{image-sRW3RpTY.js → image-DKZCmkET.js} +1 -1
- package/dist/{image-runtime-BNh3IfMj.js → image-runtime-D7n4dID4.js} +3 -3
- package/dist/{image-runtime-SUtf9jqh.js → image-runtime-poRypm-b.js} +3 -3
- package/dist/index.js +1 -1
- package/dist/llm-slug-generator.js +6 -6
- package/dist/{onboard-ChxvwUze.js → onboard-BP2Cr_Xy.js} +1 -1
- package/dist/{onboard-1KfKwvMR.js → onboard-CCJCvPgf.js} +1 -1
- package/dist/{onboarding-D6kMb3yv.js → onboarding-D5G87dvM.js} +1 -1
- package/dist/{onboarding-DuUMPrqA.js → onboarding-D7CIbxzd.js} +1 -1
- package/dist/{onboarding.finalize-KTOhO1-l.js → onboarding.finalize-B1MmYTFV.js} +4 -4
- package/dist/{onboarding.finalize-bphDUwZy.js → onboarding.finalize-Cxzl-fYU.js} +3 -3
- package/dist/{pi-embedded-BP2UlUm_.js → pi-embedded-CHzwPt6X.js} +24 -24
- package/dist/{pi-embedded-BGz_qdCc.js → pi-embedded-MktS4l8v.js} +24 -24
- package/dist/{pi-embedded-helpers-CmLnmKlb.js → pi-embedded-helpers-Bse_QhEf.js} +3 -3
- package/dist/{pi-embedded-helpers-BruaFB5l.js → pi-embedded-helpers-DYWYzEOC.js} +3 -3
- package/dist/plugin-sdk/accounts-BNuRM3rG.js +288 -0
- package/dist/plugin-sdk/accounts-CGTYP7Rh.js +46 -0
- package/dist/plugin-sdk/accounts-CcS9IAhD.js +35 -0
- package/dist/plugin-sdk/{accounts-YTdQYQFr.js → accounts-CxUSDHsT.js} +3 -3
- package/dist/plugin-sdk/{accounts-h__dTrLK.js → accounts-PSzw-z3S.js} +2 -2
- package/dist/plugin-sdk/{accounts-DghIDNk2.js → accounts-kr-Gz1hk.js} +2 -2
- package/dist/plugin-sdk/{active-listener-_PRYjtJv.js → active-listener-BQNrTcR3.js} +2 -2
- package/dist/plugin-sdk/active-listener-CTsLn1AX.js +50 -0
- package/dist/plugin-sdk/{api-key-rotation-mVDSAkKQ.js → api-key-rotation-Bhck7wki.js} +2 -2
- package/dist/plugin-sdk/api-key-rotation-DE4gr5YM.js +181 -0
- package/dist/plugin-sdk/audio-preflight-CRGLqp-g.js +69 -0
- package/dist/plugin-sdk/{audio-preflight-BZlQM-qX.js → audio-preflight-_xgGaeho.js} +26 -26
- package/dist/plugin-sdk/{audio-transcription-runner-CrYTX8py.js → audio-transcription-runner-Dwc0Eh-B.js} +11 -11
- package/dist/plugin-sdk/audio-transcription-runner-RXsskMMk.js +2176 -0
- package/dist/plugin-sdk/audit-membership-runtime-B9b-zRwg.js +58 -0
- package/dist/plugin-sdk/{audit-membership-runtime-Xl20kCBe.js → audit-membership-runtime-DHQDvH4u.js} +2 -2
- package/dist/plugin-sdk/{channel-activity-gwxRn4wF.js → channel-activity-XajEg_DL.js} +3 -3
- package/dist/plugin-sdk/channel-activity-gPvD1D7S.js +94 -0
- package/dist/plugin-sdk/{channel-web-1WF-Nabe.js → channel-web-KtqCp4mz.js} +18 -18
- package/dist/plugin-sdk/channel-web-LGl1zPJt.js +2256 -0
- package/dist/plugin-sdk/chrome-9Y_LcUg1.js +2415 -0
- package/dist/plugin-sdk/{chrome-BXbYwXRH.js → chrome-diV5m81I.js} +6 -6
- package/dist/plugin-sdk/commands-registry-CcdEPxVg.js +1125 -0
- package/dist/plugin-sdk/{commands-registry-0w-aZenK.js → commands-registry-DwZAJuut.js} +4 -4
- package/dist/plugin-sdk/{common-DBOCt6Yv.js → common-CqnO92P8.js} +2 -2
- package/dist/plugin-sdk/config-CrQ5bCrw.js +17912 -0
- package/dist/plugin-sdk/{config-pRtEoVyZ.js → config-DYbtdrsT.js} +7 -7
- package/dist/plugin-sdk/deliver-D3xr5AkB.js +1694 -0
- package/dist/plugin-sdk/{deliver-FjlJrtZk.js → deliver-DG_7Uagn.js} +10 -10
- package/dist/plugin-sdk/deliver-runtime-B79ZQu69.js +32 -0
- package/dist/plugin-sdk/deliver-runtime-BdTC7uKE.js +32 -0
- package/dist/plugin-sdk/deps-send-discord.runtime-BOQZIqC8.js +23 -0
- package/dist/plugin-sdk/deps-send-discord.runtime-CObCNMt3.js +23 -0
- package/dist/plugin-sdk/deps-send-imessage.runtime-CuHOc9Ka.js +22 -0
- package/dist/plugin-sdk/deps-send-imessage.runtime-DlWgi2DH.js +22 -0
- package/dist/plugin-sdk/deps-send-signal.runtime-Cz7FT8J8.js +21 -0
- package/dist/plugin-sdk/deps-send-signal.runtime-iPynghkE.js +21 -0
- package/dist/plugin-sdk/deps-send-slack.runtime-D4vDoRsg.js +19 -0
- package/dist/plugin-sdk/deps-send-slack.runtime-DNTbE5jS.js +19 -0
- package/dist/plugin-sdk/deps-send-telegram.runtime-7CR-xtCF.js +24 -0
- package/dist/plugin-sdk/deps-send-telegram.runtime-DjTVED_m.js +24 -0
- package/dist/plugin-sdk/deps-send-whatsapp.runtime-CRWOIKRC.js +57 -0
- package/dist/plugin-sdk/deps-send-whatsapp.runtime-bUi8kghi.js +57 -0
- package/dist/plugin-sdk/diagnostic-BXkLYs_9.js +319 -0
- package/dist/plugin-sdk/{diagnostic-Dt2i3afe.js → diagnostic-CT7v_kM2.js} +2 -2
- package/dist/plugin-sdk/{errors-CgRPdp3o.js → errors-9oVz7reJ.js} +1 -1
- package/dist/plugin-sdk/errors-B8oJXuCF.js +54 -0
- package/dist/plugin-sdk/fetch-guard-C55uvn27.js +156 -0
- package/dist/plugin-sdk/{fetch-guard-DyPZh8r2.js → fetch-guard-Or5BCq0E.js} +2 -2
- package/dist/plugin-sdk/{fs-safe-DqCO1D4C.js → fs-safe-DFbwq9CS.js} +3 -3
- package/dist/plugin-sdk/fs-safe-Dqmpk-Fr.js +352 -0
- package/dist/plugin-sdk/image-3xW7IJdq.js +2310 -0
- package/dist/plugin-sdk/image-ops-BjK2qZZn.js +584 -0
- package/dist/plugin-sdk/{image-ops-sw0uZ0GN.js → image-ops-CMsocOob.js} +2 -2
- package/dist/plugin-sdk/image-runtime-CZZJJqcW.js +25 -0
- package/dist/plugin-sdk/image-runtime-Cjz368oj.js +25 -0
- package/dist/plugin-sdk/{image-CQ9TZ9vq.js → image-rycGCqJO.js} +6 -6
- package/dist/plugin-sdk/index.js +50 -50
- package/dist/plugin-sdk/ir-CS7uuQhN.js +1296 -0
- package/dist/plugin-sdk/{ir-BVZ5kUMb.js → ir-DihI2SIz.js} +7 -7
- package/dist/plugin-sdk/{local-roots-fO3ZgW3G.js → local-roots-1xVosTZ4.js} +4 -4
- package/dist/plugin-sdk/local-roots-DmOKwiNW.js +186 -0
- package/dist/plugin-sdk/{logger-DIb2cGHp.js → logger-Bg4vIUJn.js} +2 -2
- package/dist/plugin-sdk/logger-DDdrdbDu.js +1163 -0
- package/dist/plugin-sdk/login-BSEeU27Y.js +57 -0
- package/dist/plugin-sdk/{login-Dg5cxB_3.js → login-YhFrVUWo.js} +4 -4
- package/dist/plugin-sdk/login-qr-BwWJsDSj.js +320 -0
- package/dist/plugin-sdk/{login-qr-C3Vn30cq.js → login-qr-SpUTuwYv.js} +5 -5
- package/dist/plugin-sdk/manager-DiXPCubI.js +3917 -0
- package/dist/plugin-sdk/{manager-BR-TwWTH.js → manager-DrzOPeMD.js} +8 -8
- package/dist/plugin-sdk/manager-runtime-CF55pBNe.js +15 -0
- package/dist/plugin-sdk/manager-runtime-Ct0m9UJC.js +15 -0
- package/dist/plugin-sdk/mattermost.js +3 -3
- package/dist/plugin-sdk/{outbound-1a3Z_QJ2.js → outbound-Cc4cUn9K.js} +5 -5
- package/dist/plugin-sdk/outbound-attachment-BoFx05zw.js +19 -0
- package/dist/plugin-sdk/{outbound-attachment-BTQjD4YE.js → outbound-attachment-Dtp3hQgc.js} +2 -2
- package/dist/plugin-sdk/outbound-cpqK1GFe.js +212 -0
- package/dist/plugin-sdk/{path-alias-guards-TnxupPQC.js → path-alias-guards-DA0MhfkG.js} +1 -1
- package/dist/plugin-sdk/path-alias-guards-gBhrAn14.js +43 -0
- package/dist/plugin-sdk/paths-C6W4VHoa.js +166 -0
- package/dist/plugin-sdk/{paths-B7_75Pdr.js → paths-CP67O8eN.js} +1 -1
- package/dist/plugin-sdk/{pi-embedded-helpers-DZRNadD8.js → pi-embedded-helpers-BDJ_4Plh.js} +16 -16
- package/dist/plugin-sdk/pi-embedded-helpers-C-B9B6Sp.js +9627 -0
- package/dist/plugin-sdk/pi-model-discovery-BGEeoPzN.js +134 -0
- package/dist/plugin-sdk/{pi-model-discovery-DGh6xekX.js → pi-model-discovery-Mk0GTDJl.js} +1 -1
- package/dist/plugin-sdk/pi-model-discovery-runtime-BHZ_Htob.js +8 -0
- package/dist/plugin-sdk/pi-model-discovery-runtime-BrwtJHPU.js +8 -0
- package/dist/plugin-sdk/pi-tools.before-tool-call.runtime-ByN_xThw.js +354 -0
- package/dist/plugin-sdk/{pi-tools.before-tool-call.runtime-BZ9XgG_x.js → pi-tools.before-tool-call.runtime-DV72wTDb.js} +4 -4
- package/dist/plugin-sdk/plugins-D5cdn70e.js +864 -0
- package/dist/plugin-sdk/{plugins-B8pWVYug.js → plugins-DSs2-fnK.js} +4 -4
- package/dist/plugin-sdk/{proxy-env-BOlkiW1-.js → proxy-env-Ib4-LUh-.js} +1 -1
- package/dist/plugin-sdk/{proxy-fetch-Dt5BedH8.js → proxy-fetch-Cf3IUSDw.js} +1 -1
- package/dist/plugin-sdk/proxy-fetch-ZPEvp58f.js +38 -0
- package/dist/plugin-sdk/pw-ai-C_QOIuin.js +1938 -0
- package/dist/plugin-sdk/{pw-ai-C17A1o4w.js → pw-ai-DIx2wpkY.js} +9 -9
- package/dist/plugin-sdk/qmd-manager-6bozlfFg.js +1448 -0
- package/dist/plugin-sdk/{qmd-manager-Bei6TaFq.js → qmd-manager-Ov9ElEfG.js} +7 -7
- package/dist/plugin-sdk/{query-expansion-POz2za8a.js → query-expansion-CzjwW461.js} +4 -4
- package/dist/plugin-sdk/query-expansion-eeVz_aEm.js +1011 -0
- package/dist/plugin-sdk/{redact-9WsNyb7S.js → redact-BoNEjbpF.js} +1 -1
- package/dist/plugin-sdk/redact-DfACyt0X.js +319 -0
- package/dist/plugin-sdk/reply-CQUX_haM.js +98828 -0
- package/dist/plugin-sdk/{reply-BFbijn6_.js → reply-CWWUd_JS.js} +73 -73
- package/dist/plugin-sdk/{resolve-outbound-target-B9iFEh0y.js → resolve-outbound-target-BOkvxZtM.js} +2 -2
- package/dist/plugin-sdk/resolve-outbound-target-Dbz0O8cR.js +40 -0
- package/dist/plugin-sdk/run-with-concurrency-5DMu9szx.js +1994 -0
- package/dist/plugin-sdk/{run-with-concurrency-DmTrN5JG.js → run-with-concurrency-kVooFCVo.js} +1 -1
- package/dist/plugin-sdk/runtime-whatsapp-login.runtime-DitS0I1z.js +10 -0
- package/dist/plugin-sdk/runtime-whatsapp-login.runtime-OthrtsLL.js +10 -0
- package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-CYCr6A3v.js +19 -0
- package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-Q2HL0zL3.js +19 -0
- package/dist/plugin-sdk/send-BACEu1Un.js +414 -0
- package/dist/plugin-sdk/{send-BGZo6HW1.js → send-BP1fSEBR.js} +5 -5
- package/dist/plugin-sdk/send-BU4OoR7u.js +2587 -0
- package/dist/plugin-sdk/{send-BqkUDZed.js → send-BeLBlAsQ.js} +13 -13
- package/dist/plugin-sdk/{send-BisREGBZ.js → send-D9CSOGul.js} +6 -6
- package/dist/plugin-sdk/{send-D6_nNvi0.js → send-DLKxJJYV.js} +8 -8
- package/dist/plugin-sdk/send-DbxOJ_BC.js +3135 -0
- package/dist/plugin-sdk/{send-Dj7XEcZN.js → send-XZ6IXCtL.js} +7 -7
- package/dist/plugin-sdk/send-n932vjT5.js +540 -0
- package/dist/plugin-sdk/send-uCPS53j8.js +503 -0
- package/dist/plugin-sdk/session-DenDKR_-.js +169 -0
- package/dist/plugin-sdk/{session-D4KDs7Hq.js → session-DtLUYWvY.js} +3 -3
- package/dist/plugin-sdk/skill-commands-BK1KDKmS.js +342 -0
- package/dist/plugin-sdk/{skill-commands-D_xeseiI.js → skill-commands-Bv7EZypt.js} +4 -4
- package/dist/plugin-sdk/{skills-Bs2b3JfV.js → skills-BzXN4uev.js} +6 -6
- package/dist/plugin-sdk/skills-D4am-zkO.js +1428 -0
- package/dist/plugin-sdk/slash-commands.runtime-Bx1K1iqP.js +13 -0
- package/dist/plugin-sdk/slash-commands.runtime-DWfFqMZw.js +13 -0
- package/dist/plugin-sdk/slash-dispatch.runtime-DVn338JI.js +52 -0
- package/dist/plugin-sdk/slash-dispatch.runtime-pnWH5AjM.js +52 -0
- package/dist/plugin-sdk/slash-skill-commands.runtime-Dbi_YzPO.js +16 -0
- package/dist/plugin-sdk/slash-skill-commands.runtime-DxvNWv_E.js +16 -0
- package/dist/plugin-sdk/ssrf-2WBi1Tzx.js +202 -0
- package/dist/plugin-sdk/store-BKDMuvyn.js +81 -0
- package/dist/plugin-sdk/{store-B7ESm9_L.js → store-DnJhFFW5.js} +2 -2
- package/dist/plugin-sdk/subagent-registry-runtime-FhP0l-Rw.js +52 -0
- package/dist/plugin-sdk/subagent-registry-runtime-hH9ADku1.js +52 -0
- package/dist/plugin-sdk/{tables-1vhBJPK_.js → tables-CpmqssLF.js} +1 -1
- package/dist/plugin-sdk/tables-CrDYcv_b.js +55 -0
- package/dist/plugin-sdk/target-errors-aOwE-MIU.js +195 -0
- package/dist/plugin-sdk/{thinking-DjaClmzi.js → thinking-1UCPuD9d.js} +7 -7
- package/dist/plugin-sdk/thinking-D41FMh9T.js +1206 -0
- package/dist/plugin-sdk/{tokens-CLE20fRI.js → tokens-CTIYTLWu.js} +1 -1
- package/dist/plugin-sdk/tokens-DAL_5WHL.js +52 -0
- package/dist/plugin-sdk/{tool-images-B95xcwiR.js → tool-images-CWc54lpI.js} +2 -2
- package/dist/plugin-sdk/tool-images-RX4QTMnt.js +274 -0
- package/dist/plugin-sdk/web-AtEy-48y.js +56 -0
- package/dist/plugin-sdk/web-DjKONHqF.js +56 -0
- package/dist/plugin-sdk/{whatsapp-actions-BYpcWkTN.js → whatsapp-actions-BF6ih4Gi.js} +17 -17
- package/dist/plugin-sdk/whatsapp-actions-DEZcm_CZ.js +80 -0
- package/dist/plugin-sdk/whatsapp.js +50 -50
- package/dist/{program-xNEHPhT8.js → program-2J-jgdfk.js} +2 -2
- package/dist/{program-context-J_FyEsaS.js → program-context-SjYSWx_N.js} +8 -8
- package/dist/{prompt-select-styled-B1LjjgQ0.js → prompt-select-styled-Baiu3mAU.js} +1 -1
- package/dist/{prompt-select-styled-BRiogP_P.js → prompt-select-styled-DPnVmH8f.js} +1 -1
- package/dist/{pw-ai-7kHgUGj0.js → pw-ai-BwRP3TWc.js} +1 -1
- package/dist/{pw-ai-BmGrTicP.js → pw-ai-zFPBSxaL.js} +1 -1
- package/dist/{register.configure-DezZ4Q1p.js → register.configure-Ao1K2uze.js} +1 -1
- package/dist/{register.configure-C4p9ad2q.js → register.configure-CCkfhF-7.js} +1 -1
- package/dist/{register.maintenance-CzMKTC2a.js → register.maintenance-DMbs8w2m.js} +4 -4
- package/dist/{register.maintenance-CTvFmkAm.js → register.maintenance-pLpE2oF-.js} +5 -5
- package/dist/{register.onboard-C39xhpv1.js → register.onboard-Cb8xLIye.js} +2 -2
- package/dist/{register.onboard-DZt2kSAg.js → register.onboard-IMrHOeW_.js} +2 -2
- package/dist/{register.setup-04L_8wfA.js → register.setup-CX8IUmew.js} +2 -2
- package/dist/{register.setup-DWctFmOd.js → register.setup-DU7IDzAv.js} +2 -2
- package/dist/{register.subclis-C3TphbCF.js → register.subclis-BIbL6FBV.js} +3 -3
- package/dist/{run-main-7tknx04F.js → run-main-CpDZPsC_.js} +5 -5
- package/dist/{slash-dispatch.runtime-BL3qA1O3.js → slash-dispatch.runtime-DkcAYuyK.js} +6 -6
- package/dist/{slash-dispatch.runtime-Dh2L_3Tg.js → slash-dispatch.runtime-DuJRl-LD.js} +6 -6
- package/dist/{subagent-registry-runtime-MtjBCcgn.js → subagent-registry-runtime-BlRAnw80.js} +6 -6
- package/dist/{subagent-registry-runtime-BRNDawlJ.js → subagent-registry-runtime-COygB9b1.js} +6 -6
- package/dist/{update-cli-0UiUaT3q.js → update-cli-BwhvSo1R.js} +5 -5
- package/dist/{update-cli-C-uyQcFS.js → update-cli-TQEfxhWF.js} +4 -4
- package/dist/{web-D1ZoRVB0.js → web-DddJa7ZT.js} +6 -6
- package/dist/{web-B7kbCskR.js → web-DyCuTR9b.js} +6 -6
- package/package.json +7 -7
- package/dist/plugin-sdk/deliver-runtime-DEzvpBW1.js +0 -32
- package/dist/plugin-sdk/deps-send-discord.runtime-Bhusa_Hi.js +0 -23
- package/dist/plugin-sdk/deps-send-imessage.runtime-bmakPm5f.js +0 -22
- package/dist/plugin-sdk/deps-send-signal.runtime-n00sfFto.js +0 -21
- package/dist/plugin-sdk/deps-send-slack.runtime-BvM3Z-Mr.js +0 -19
- package/dist/plugin-sdk/deps-send-telegram.runtime-CPuMkcmo.js +0 -24
- package/dist/plugin-sdk/deps-send-whatsapp.runtime-BzO6S-KX.js +0 -57
- package/dist/plugin-sdk/image-runtime-17_mTqsy.js +0 -25
- package/dist/plugin-sdk/manager-runtime-CvI9wF8N.js +0 -15
- package/dist/plugin-sdk/pi-model-discovery-runtime-DjjBdPYt.js +0 -8
- package/dist/plugin-sdk/runtime-whatsapp-login.runtime-DzhkSmLi.js +0 -10
- package/dist/plugin-sdk/runtime-whatsapp-outbound.runtime-DyILWezU.js +0 -19
- package/dist/plugin-sdk/slash-commands.runtime-CUb5sqqf.js +0 -13
- package/dist/plugin-sdk/slash-dispatch.runtime-DCB6bGjB.js +0 -52
- package/dist/plugin-sdk/slash-skill-commands.runtime-BqEweE4K.js +0 -16
- package/dist/plugin-sdk/subagent-registry-runtime-CCUW4SbM.js +0 -52
- package/dist/plugin-sdk/web-DeRmHQ4_.js +0 -56
|
@@ -0,0 +1,1994 @@
|
|
|
1
|
+
import { c as resolveStateDir, d as resolveRequiredHomeDir } from "./paths-8xF5kDne.js";
|
|
2
|
+
import { C as pathExists$1, E as resolveUserPath, F as danger, a as createSubsystemLogger, n as logError, t as logDebug, z as shouldLogVerbose } from "./logger-DDdrdbDu.js";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import os from "node:os";
|
|
6
|
+
import fs$1 from "node:fs/promises";
|
|
7
|
+
import { promisify } from "node:util";
|
|
8
|
+
import { execFile, spawn } from "node:child_process";
|
|
9
|
+
import process$1 from "node:process";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
|
|
12
|
+
//#region src/sessions/session-key-utils.ts
|
|
13
|
+
/**
|
|
14
|
+
* Parse agent-scoped session keys in a canonical, case-insensitive way.
|
|
15
|
+
* Returned values are normalized to lowercase for stable comparisons/routing.
|
|
16
|
+
*/
|
|
17
|
+
function parseAgentSessionKey(sessionKey) {
|
|
18
|
+
const raw = (sessionKey ?? "").trim().toLowerCase();
|
|
19
|
+
if (!raw) return null;
|
|
20
|
+
const parts = raw.split(":").filter(Boolean);
|
|
21
|
+
if (parts.length < 3) return null;
|
|
22
|
+
if (parts[0] !== "agent") return null;
|
|
23
|
+
const agentId = parts[1]?.trim();
|
|
24
|
+
const rest = parts.slice(2).join(":");
|
|
25
|
+
if (!agentId || !rest) return null;
|
|
26
|
+
return {
|
|
27
|
+
agentId,
|
|
28
|
+
rest
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Best-effort chat-type extraction from session keys across canonical and legacy formats.
|
|
33
|
+
*/
|
|
34
|
+
function deriveSessionChatType(sessionKey) {
|
|
35
|
+
const raw = (sessionKey ?? "").trim().toLowerCase();
|
|
36
|
+
if (!raw) return "unknown";
|
|
37
|
+
const scoped = parseAgentSessionKey(raw)?.rest ?? raw;
|
|
38
|
+
const tokens = new Set(scoped.split(":").filter(Boolean));
|
|
39
|
+
if (tokens.has("group")) return "group";
|
|
40
|
+
if (tokens.has("channel")) return "channel";
|
|
41
|
+
if (tokens.has("direct") || tokens.has("dm")) return "direct";
|
|
42
|
+
if (/^discord:(?:[^:]+:)?guild-[^:]+:channel-[^:]+$/.test(scoped)) return "channel";
|
|
43
|
+
return "unknown";
|
|
44
|
+
}
|
|
45
|
+
function isCronSessionKey(sessionKey) {
|
|
46
|
+
const parsed = parseAgentSessionKey(sessionKey);
|
|
47
|
+
if (!parsed) return false;
|
|
48
|
+
return parsed.rest.toLowerCase().startsWith("cron:");
|
|
49
|
+
}
|
|
50
|
+
function isSubagentSessionKey(sessionKey) {
|
|
51
|
+
const raw = (sessionKey ?? "").trim();
|
|
52
|
+
if (!raw) return false;
|
|
53
|
+
if (raw.toLowerCase().startsWith("subagent:")) return true;
|
|
54
|
+
const parsed = parseAgentSessionKey(raw);
|
|
55
|
+
return Boolean((parsed?.rest ?? "").toLowerCase().startsWith("subagent:"));
|
|
56
|
+
}
|
|
57
|
+
function getSubagentDepth(sessionKey) {
|
|
58
|
+
const raw = (sessionKey ?? "").trim().toLowerCase();
|
|
59
|
+
if (!raw) return 0;
|
|
60
|
+
return raw.split(":subagent:").length - 1;
|
|
61
|
+
}
|
|
62
|
+
function isAcpSessionKey(sessionKey) {
|
|
63
|
+
const raw = (sessionKey ?? "").trim();
|
|
64
|
+
if (!raw) return false;
|
|
65
|
+
if (raw.toLowerCase().startsWith("acp:")) return true;
|
|
66
|
+
const parsed = parseAgentSessionKey(raw);
|
|
67
|
+
return Boolean((parsed?.rest ?? "").toLowerCase().startsWith("acp:"));
|
|
68
|
+
}
|
|
69
|
+
const THREAD_SESSION_MARKERS = [":thread:", ":topic:"];
|
|
70
|
+
function resolveThreadParentSessionKey(sessionKey) {
|
|
71
|
+
const raw = (sessionKey ?? "").trim();
|
|
72
|
+
if (!raw) return null;
|
|
73
|
+
const normalized = raw.toLowerCase();
|
|
74
|
+
let idx = -1;
|
|
75
|
+
for (const marker of THREAD_SESSION_MARKERS) {
|
|
76
|
+
const candidate = normalized.lastIndexOf(marker);
|
|
77
|
+
if (candidate > idx) idx = candidate;
|
|
78
|
+
}
|
|
79
|
+
if (idx <= 0) return null;
|
|
80
|
+
const parent = raw.slice(0, idx).trim();
|
|
81
|
+
return parent ? parent : null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/infra/prototype-keys.ts
|
|
86
|
+
const BLOCKED_OBJECT_KEYS = new Set([
|
|
87
|
+
"__proto__",
|
|
88
|
+
"prototype",
|
|
89
|
+
"constructor"
|
|
90
|
+
]);
|
|
91
|
+
function isBlockedObjectKey(key) {
|
|
92
|
+
return BLOCKED_OBJECT_KEYS.has(key);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region src/routing/account-id.ts
|
|
97
|
+
const DEFAULT_ACCOUNT_ID = "default";
|
|
98
|
+
const VALID_ID_RE$1 = /^[a-z0-9][a-z0-9_-]{0,63}$/i;
|
|
99
|
+
const INVALID_CHARS_RE$1 = /[^a-z0-9_-]+/g;
|
|
100
|
+
const LEADING_DASH_RE$1 = /^-+/;
|
|
101
|
+
const TRAILING_DASH_RE$1 = /-+$/;
|
|
102
|
+
const ACCOUNT_ID_CACHE_MAX = 512;
|
|
103
|
+
const normalizeAccountIdCache = /* @__PURE__ */ new Map();
|
|
104
|
+
const normalizeOptionalAccountIdCache = /* @__PURE__ */ new Map();
|
|
105
|
+
function canonicalizeAccountId(value) {
|
|
106
|
+
if (VALID_ID_RE$1.test(value)) return value.toLowerCase();
|
|
107
|
+
return value.toLowerCase().replace(INVALID_CHARS_RE$1, "-").replace(LEADING_DASH_RE$1, "").replace(TRAILING_DASH_RE$1, "").slice(0, 64);
|
|
108
|
+
}
|
|
109
|
+
function normalizeCanonicalAccountId(value) {
|
|
110
|
+
const canonical = canonicalizeAccountId(value);
|
|
111
|
+
if (!canonical || isBlockedObjectKey(canonical)) return;
|
|
112
|
+
return canonical;
|
|
113
|
+
}
|
|
114
|
+
function normalizeAccountId(value) {
|
|
115
|
+
const trimmed = (value ?? "").trim();
|
|
116
|
+
if (!trimmed) return DEFAULT_ACCOUNT_ID;
|
|
117
|
+
const cached = normalizeAccountIdCache.get(trimmed);
|
|
118
|
+
if (cached) return cached;
|
|
119
|
+
const normalized = normalizeCanonicalAccountId(trimmed) || DEFAULT_ACCOUNT_ID;
|
|
120
|
+
setNormalizeCache(normalizeAccountIdCache, trimmed, normalized);
|
|
121
|
+
return normalized;
|
|
122
|
+
}
|
|
123
|
+
function normalizeOptionalAccountId(value) {
|
|
124
|
+
const trimmed = (value ?? "").trim();
|
|
125
|
+
if (!trimmed) return;
|
|
126
|
+
if (normalizeOptionalAccountIdCache.has(trimmed)) return normalizeOptionalAccountIdCache.get(trimmed);
|
|
127
|
+
const normalized = normalizeCanonicalAccountId(trimmed) || void 0;
|
|
128
|
+
setNormalizeCache(normalizeOptionalAccountIdCache, trimmed, normalized);
|
|
129
|
+
return normalized;
|
|
130
|
+
}
|
|
131
|
+
function setNormalizeCache(cache, key, value) {
|
|
132
|
+
cache.set(key, value);
|
|
133
|
+
if (cache.size <= ACCOUNT_ID_CACHE_MAX) return;
|
|
134
|
+
const oldest = cache.keys().next();
|
|
135
|
+
if (!oldest.done) cache.delete(oldest.value);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region src/routing/session-key.ts
|
|
140
|
+
const DEFAULT_AGENT_ID = "main";
|
|
141
|
+
const DEFAULT_MAIN_KEY = "main";
|
|
142
|
+
const VALID_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i;
|
|
143
|
+
const INVALID_CHARS_RE = /[^a-z0-9_-]+/g;
|
|
144
|
+
const LEADING_DASH_RE = /^-+/;
|
|
145
|
+
const TRAILING_DASH_RE = /-+$/;
|
|
146
|
+
function normalizeToken(value) {
|
|
147
|
+
return (value ?? "").trim().toLowerCase();
|
|
148
|
+
}
|
|
149
|
+
function scopedHeartbeatWakeOptions(sessionKey, wakeOptions) {
|
|
150
|
+
return parseAgentSessionKey(sessionKey) ? {
|
|
151
|
+
...wakeOptions,
|
|
152
|
+
sessionKey
|
|
153
|
+
} : wakeOptions;
|
|
154
|
+
}
|
|
155
|
+
function normalizeMainKey(value) {
|
|
156
|
+
const trimmed = (value ?? "").trim();
|
|
157
|
+
return trimmed ? trimmed.toLowerCase() : DEFAULT_MAIN_KEY;
|
|
158
|
+
}
|
|
159
|
+
function resolveAgentIdFromSessionKey(sessionKey) {
|
|
160
|
+
return normalizeAgentId(parseAgentSessionKey(sessionKey)?.agentId ?? DEFAULT_AGENT_ID);
|
|
161
|
+
}
|
|
162
|
+
function classifySessionKeyShape(sessionKey) {
|
|
163
|
+
const raw = (sessionKey ?? "").trim();
|
|
164
|
+
if (!raw) return "missing";
|
|
165
|
+
if (parseAgentSessionKey(raw)) return "agent";
|
|
166
|
+
return raw.toLowerCase().startsWith("agent:") ? "malformed_agent" : "legacy_or_alias";
|
|
167
|
+
}
|
|
168
|
+
function normalizeAgentId(value) {
|
|
169
|
+
const trimmed = (value ?? "").trim();
|
|
170
|
+
if (!trimmed) return DEFAULT_AGENT_ID;
|
|
171
|
+
if (VALID_ID_RE.test(trimmed)) return trimmed.toLowerCase();
|
|
172
|
+
return trimmed.toLowerCase().replace(INVALID_CHARS_RE, "-").replace(LEADING_DASH_RE, "").replace(TRAILING_DASH_RE, "").slice(0, 64) || DEFAULT_AGENT_ID;
|
|
173
|
+
}
|
|
174
|
+
function isValidAgentId(value) {
|
|
175
|
+
const trimmed = (value ?? "").trim();
|
|
176
|
+
return Boolean(trimmed) && VALID_ID_RE.test(trimmed);
|
|
177
|
+
}
|
|
178
|
+
function sanitizeAgentId(value) {
|
|
179
|
+
return normalizeAgentId(value);
|
|
180
|
+
}
|
|
181
|
+
function buildAgentMainSessionKey(params) {
|
|
182
|
+
return `agent:${normalizeAgentId(params.agentId)}:${normalizeMainKey(params.mainKey)}`;
|
|
183
|
+
}
|
|
184
|
+
function buildAgentPeerSessionKey(params) {
|
|
185
|
+
const peerKind = params.peerKind ?? "direct";
|
|
186
|
+
if (peerKind === "direct") {
|
|
187
|
+
const dmScope = params.dmScope ?? "main";
|
|
188
|
+
let peerId = (params.peerId ?? "").trim();
|
|
189
|
+
const linkedPeerId = dmScope === "main" ? null : resolveLinkedPeerId({
|
|
190
|
+
identityLinks: params.identityLinks,
|
|
191
|
+
channel: params.channel,
|
|
192
|
+
peerId
|
|
193
|
+
});
|
|
194
|
+
if (linkedPeerId) peerId = linkedPeerId;
|
|
195
|
+
peerId = peerId.toLowerCase();
|
|
196
|
+
if (dmScope === "per-account-channel-peer" && peerId) {
|
|
197
|
+
const channel = (params.channel ?? "").trim().toLowerCase() || "unknown";
|
|
198
|
+
const accountId = normalizeAccountId(params.accountId);
|
|
199
|
+
return `agent:${normalizeAgentId(params.agentId)}:${channel}:${accountId}:direct:${peerId}`;
|
|
200
|
+
}
|
|
201
|
+
if (dmScope === "per-channel-peer" && peerId) {
|
|
202
|
+
const channel = (params.channel ?? "").trim().toLowerCase() || "unknown";
|
|
203
|
+
return `agent:${normalizeAgentId(params.agentId)}:${channel}:direct:${peerId}`;
|
|
204
|
+
}
|
|
205
|
+
if (dmScope === "per-peer" && peerId) return `agent:${normalizeAgentId(params.agentId)}:direct:${peerId}`;
|
|
206
|
+
return buildAgentMainSessionKey({
|
|
207
|
+
agentId: params.agentId,
|
|
208
|
+
mainKey: params.mainKey
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
const channel = (params.channel ?? "").trim().toLowerCase() || "unknown";
|
|
212
|
+
const peerId = ((params.peerId ?? "").trim() || "unknown").toLowerCase();
|
|
213
|
+
return `agent:${normalizeAgentId(params.agentId)}:${channel}:${peerKind}:${peerId}`;
|
|
214
|
+
}
|
|
215
|
+
function resolveLinkedPeerId(params) {
|
|
216
|
+
const identityLinks = params.identityLinks;
|
|
217
|
+
if (!identityLinks) return null;
|
|
218
|
+
const peerId = params.peerId.trim();
|
|
219
|
+
if (!peerId) return null;
|
|
220
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
221
|
+
const rawCandidate = normalizeToken(peerId);
|
|
222
|
+
if (rawCandidate) candidates.add(rawCandidate);
|
|
223
|
+
const channel = normalizeToken(params.channel);
|
|
224
|
+
if (channel) {
|
|
225
|
+
const scopedCandidate = normalizeToken(`${channel}:${peerId}`);
|
|
226
|
+
if (scopedCandidate) candidates.add(scopedCandidate);
|
|
227
|
+
}
|
|
228
|
+
if (candidates.size === 0) return null;
|
|
229
|
+
for (const [canonical, ids] of Object.entries(identityLinks)) {
|
|
230
|
+
const canonicalName = canonical.trim();
|
|
231
|
+
if (!canonicalName) continue;
|
|
232
|
+
if (!Array.isArray(ids)) continue;
|
|
233
|
+
for (const id of ids) {
|
|
234
|
+
const normalized = normalizeToken(id);
|
|
235
|
+
if (normalized && candidates.has(normalized)) return canonicalName;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
function buildGroupHistoryKey(params) {
|
|
241
|
+
const channel = normalizeToken(params.channel) || "unknown";
|
|
242
|
+
const accountId = normalizeAccountId(params.accountId);
|
|
243
|
+
const peerId = params.peerId.trim().toLowerCase() || "unknown";
|
|
244
|
+
return `${channel}:${accountId}:${params.peerKind}:${peerId}`;
|
|
245
|
+
}
|
|
246
|
+
function resolveThreadSessionKeys(params) {
|
|
247
|
+
const threadId = (params.threadId ?? "").trim();
|
|
248
|
+
if (!threadId) return {
|
|
249
|
+
sessionKey: params.baseSessionKey,
|
|
250
|
+
parentSessionKey: void 0
|
|
251
|
+
};
|
|
252
|
+
const normalizedThreadId = (params.normalizeThreadId ?? ((value) => value.toLowerCase()))(threadId);
|
|
253
|
+
return {
|
|
254
|
+
sessionKey: params.useSuffix ?? true ? `${params.baseSessionKey}:thread:${normalizedThreadId}` : params.baseSessionKey,
|
|
255
|
+
parentSessionKey: params.parentSessionKey
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
//#endregion
|
|
260
|
+
//#region src/config/model-input.ts
|
|
261
|
+
function resolveAgentModelPrimaryValue(model) {
|
|
262
|
+
if (typeof model === "string") return model.trim() || void 0;
|
|
263
|
+
if (!model || typeof model !== "object") return;
|
|
264
|
+
return model.primary?.trim() || void 0;
|
|
265
|
+
}
|
|
266
|
+
function resolveAgentModelFallbackValues(model) {
|
|
267
|
+
if (!model || typeof model !== "object") return [];
|
|
268
|
+
return Array.isArray(model.fallbacks) ? model.fallbacks : [];
|
|
269
|
+
}
|
|
270
|
+
function toAgentModelListLike(model) {
|
|
271
|
+
if (typeof model === "string") {
|
|
272
|
+
const primary = model.trim();
|
|
273
|
+
return primary ? { primary } : void 0;
|
|
274
|
+
}
|
|
275
|
+
if (!model || typeof model !== "object") return;
|
|
276
|
+
return model;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
//#endregion
|
|
280
|
+
//#region src/agents/skills/filter.ts
|
|
281
|
+
function normalizeSkillFilter(skillFilter) {
|
|
282
|
+
if (skillFilter === void 0) return;
|
|
283
|
+
return skillFilter.map((entry) => String(entry).trim()).filter(Boolean);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
//#endregion
|
|
287
|
+
//#region src/infra/path-guards.ts
|
|
288
|
+
const NOT_FOUND_CODES = new Set(["ENOENT", "ENOTDIR"]);
|
|
289
|
+
const SYMLINK_OPEN_CODES = new Set([
|
|
290
|
+
"ELOOP",
|
|
291
|
+
"EINVAL",
|
|
292
|
+
"ENOTSUP"
|
|
293
|
+
]);
|
|
294
|
+
function normalizeWindowsPathForComparison(input) {
|
|
295
|
+
let normalized = path.win32.normalize(input);
|
|
296
|
+
if (normalized.startsWith("\\\\?\\")) {
|
|
297
|
+
normalized = normalized.slice(4);
|
|
298
|
+
if (normalized.toUpperCase().startsWith("UNC\\")) normalized = `\\\\${normalized.slice(4)}`;
|
|
299
|
+
}
|
|
300
|
+
return normalized.replaceAll("/", "\\").toLowerCase();
|
|
301
|
+
}
|
|
302
|
+
function isNodeError(value) {
|
|
303
|
+
return Boolean(value && typeof value === "object" && "code" in value);
|
|
304
|
+
}
|
|
305
|
+
function hasNodeErrorCode(value, code) {
|
|
306
|
+
return isNodeError(value) && value.code === code;
|
|
307
|
+
}
|
|
308
|
+
function isNotFoundPathError(value) {
|
|
309
|
+
return isNodeError(value) && typeof value.code === "string" && NOT_FOUND_CODES.has(value.code);
|
|
310
|
+
}
|
|
311
|
+
function isSymlinkOpenError(value) {
|
|
312
|
+
return isNodeError(value) && typeof value.code === "string" && SYMLINK_OPEN_CODES.has(value.code);
|
|
313
|
+
}
|
|
314
|
+
function isPathInside(root, target) {
|
|
315
|
+
const resolvedRoot = path.resolve(root);
|
|
316
|
+
const resolvedTarget = path.resolve(target);
|
|
317
|
+
if (process.platform === "win32") {
|
|
318
|
+
const rootForCompare = normalizeWindowsPathForComparison(resolvedRoot);
|
|
319
|
+
const targetForCompare = normalizeWindowsPathForComparison(resolvedTarget);
|
|
320
|
+
const relative = path.win32.relative(rootForCompare, targetForCompare);
|
|
321
|
+
return relative === "" || !relative.startsWith("..") && !path.win32.isAbsolute(relative);
|
|
322
|
+
}
|
|
323
|
+
const relative = path.relative(resolvedRoot, resolvedTarget);
|
|
324
|
+
return relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
//#endregion
|
|
328
|
+
//#region src/infra/boundary-path.ts
|
|
329
|
+
const BOUNDARY_PATH_ALIAS_POLICIES = {
|
|
330
|
+
strict: Object.freeze({
|
|
331
|
+
allowFinalSymlinkForUnlink: false,
|
|
332
|
+
allowFinalHardlinkForUnlink: false
|
|
333
|
+
}),
|
|
334
|
+
unlinkTarget: Object.freeze({
|
|
335
|
+
allowFinalSymlinkForUnlink: true,
|
|
336
|
+
allowFinalHardlinkForUnlink: true
|
|
337
|
+
})
|
|
338
|
+
};
|
|
339
|
+
async function resolveBoundaryPath(params) {
|
|
340
|
+
const rootPath = path.resolve(params.rootPath);
|
|
341
|
+
const absolutePath = path.resolve(params.absolutePath);
|
|
342
|
+
const context = createBoundaryResolutionContext({
|
|
343
|
+
resolveParams: params,
|
|
344
|
+
rootPath,
|
|
345
|
+
absolutePath,
|
|
346
|
+
rootCanonicalPath: params.rootCanonicalPath ? path.resolve(params.rootCanonicalPath) : await resolvePathViaExistingAncestor(rootPath),
|
|
347
|
+
outsideLexicalCanonicalPath: await resolveOutsideLexicalCanonicalPathAsync({
|
|
348
|
+
rootPath,
|
|
349
|
+
absolutePath
|
|
350
|
+
})
|
|
351
|
+
});
|
|
352
|
+
const outsideResult = await resolveOutsideBoundaryPathAsync({
|
|
353
|
+
boundaryLabel: params.boundaryLabel,
|
|
354
|
+
context
|
|
355
|
+
});
|
|
356
|
+
if (outsideResult) return outsideResult;
|
|
357
|
+
return resolveBoundaryPathLexicalAsync({
|
|
358
|
+
params,
|
|
359
|
+
absolutePath: context.absolutePath,
|
|
360
|
+
rootPath: context.rootPath,
|
|
361
|
+
rootCanonicalPath: context.rootCanonicalPath
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
function resolveBoundaryPathSync(params) {
|
|
365
|
+
const rootPath = path.resolve(params.rootPath);
|
|
366
|
+
const absolutePath = path.resolve(params.absolutePath);
|
|
367
|
+
const context = createBoundaryResolutionContext({
|
|
368
|
+
resolveParams: params,
|
|
369
|
+
rootPath,
|
|
370
|
+
absolutePath,
|
|
371
|
+
rootCanonicalPath: params.rootCanonicalPath ? path.resolve(params.rootCanonicalPath) : resolvePathViaExistingAncestorSync(rootPath),
|
|
372
|
+
outsideLexicalCanonicalPath: resolveOutsideLexicalCanonicalPathSync({
|
|
373
|
+
rootPath,
|
|
374
|
+
absolutePath
|
|
375
|
+
})
|
|
376
|
+
});
|
|
377
|
+
const outsideResult = resolveOutsideBoundaryPathSync({
|
|
378
|
+
boundaryLabel: params.boundaryLabel,
|
|
379
|
+
context
|
|
380
|
+
});
|
|
381
|
+
if (outsideResult) return outsideResult;
|
|
382
|
+
return resolveBoundaryPathLexicalSync({
|
|
383
|
+
params,
|
|
384
|
+
absolutePath: context.absolutePath,
|
|
385
|
+
rootPath: context.rootPath,
|
|
386
|
+
rootCanonicalPath: context.rootCanonicalPath
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
function isPromiseLike(value) {
|
|
390
|
+
return Boolean(value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function");
|
|
391
|
+
}
|
|
392
|
+
function createLexicalTraversalState(params) {
|
|
393
|
+
return {
|
|
394
|
+
segments: path.relative(params.rootPath, params.absolutePath).split(path.sep).filter(Boolean),
|
|
395
|
+
allowFinalSymlink: params.params.policy?.allowFinalSymlinkForUnlink === true,
|
|
396
|
+
canonicalCursor: params.rootCanonicalPath,
|
|
397
|
+
lexicalCursor: params.rootPath,
|
|
398
|
+
preserveFinalSymlink: false
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
function assertLexicalCursorInsideBoundary(params) {
|
|
402
|
+
assertInsideBoundary({
|
|
403
|
+
boundaryLabel: params.params.boundaryLabel,
|
|
404
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
405
|
+
candidatePath: params.candidatePath,
|
|
406
|
+
absolutePath: params.absolutePath
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
function applyMissingSuffixToCanonicalCursor(params) {
|
|
410
|
+
const missingSuffix = params.state.segments.slice(params.missingFromIndex);
|
|
411
|
+
params.state.canonicalCursor = path.resolve(params.state.canonicalCursor, ...missingSuffix);
|
|
412
|
+
assertLexicalCursorInsideBoundary({
|
|
413
|
+
params: params.params,
|
|
414
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
415
|
+
candidatePath: params.state.canonicalCursor,
|
|
416
|
+
absolutePath: params.absolutePath
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
function advanceCanonicalCursorForSegment(params) {
|
|
420
|
+
params.state.canonicalCursor = path.resolve(params.state.canonicalCursor, params.segment);
|
|
421
|
+
assertLexicalCursorInsideBoundary({
|
|
422
|
+
params: params.params,
|
|
423
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
424
|
+
candidatePath: params.state.canonicalCursor,
|
|
425
|
+
absolutePath: params.absolutePath
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
function finalizeLexicalResolution(params) {
|
|
429
|
+
assertLexicalCursorInsideBoundary({
|
|
430
|
+
params: params.params,
|
|
431
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
432
|
+
candidatePath: params.state.canonicalCursor,
|
|
433
|
+
absolutePath: params.absolutePath
|
|
434
|
+
});
|
|
435
|
+
return buildResolvedBoundaryPath({
|
|
436
|
+
absolutePath: params.absolutePath,
|
|
437
|
+
canonicalPath: params.state.canonicalCursor,
|
|
438
|
+
rootPath: params.rootPath,
|
|
439
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
440
|
+
kind: params.kind
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
function handleLexicalLstatFailure(params) {
|
|
444
|
+
if (!isNotFoundPathError(params.error)) return false;
|
|
445
|
+
applyMissingSuffixToCanonicalCursor({
|
|
446
|
+
state: params.state,
|
|
447
|
+
missingFromIndex: params.missingFromIndex,
|
|
448
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
449
|
+
params: params.resolveParams,
|
|
450
|
+
absolutePath: params.absolutePath
|
|
451
|
+
});
|
|
452
|
+
return true;
|
|
453
|
+
}
|
|
454
|
+
function handleLexicalStatReadFailure(params) {
|
|
455
|
+
if (handleLexicalLstatFailure({
|
|
456
|
+
error: params.error,
|
|
457
|
+
state: params.state,
|
|
458
|
+
missingFromIndex: params.missingFromIndex,
|
|
459
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
460
|
+
resolveParams: params.resolveParams,
|
|
461
|
+
absolutePath: params.absolutePath
|
|
462
|
+
})) return null;
|
|
463
|
+
throw params.error;
|
|
464
|
+
}
|
|
465
|
+
function handleLexicalStatDisposition(params) {
|
|
466
|
+
if (!params.isSymbolicLink) {
|
|
467
|
+
advanceCanonicalCursorForSegment({
|
|
468
|
+
state: params.state,
|
|
469
|
+
segment: params.segment,
|
|
470
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
471
|
+
params: params.resolveParams,
|
|
472
|
+
absolutePath: params.absolutePath
|
|
473
|
+
});
|
|
474
|
+
return "continue";
|
|
475
|
+
}
|
|
476
|
+
if (params.state.allowFinalSymlink && params.isLast) {
|
|
477
|
+
params.state.preserveFinalSymlink = true;
|
|
478
|
+
advanceCanonicalCursorForSegment({
|
|
479
|
+
state: params.state,
|
|
480
|
+
segment: params.segment,
|
|
481
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
482
|
+
params: params.resolveParams,
|
|
483
|
+
absolutePath: params.absolutePath
|
|
484
|
+
});
|
|
485
|
+
return "break";
|
|
486
|
+
}
|
|
487
|
+
return "resolve-link";
|
|
488
|
+
}
|
|
489
|
+
function applyResolvedSymlinkHop(params) {
|
|
490
|
+
if (!isPathInside(params.rootCanonicalPath, params.linkCanonical)) throw symlinkEscapeError({
|
|
491
|
+
boundaryLabel: params.boundaryLabel,
|
|
492
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
493
|
+
symlinkPath: params.state.lexicalCursor
|
|
494
|
+
});
|
|
495
|
+
params.state.canonicalCursor = params.linkCanonical;
|
|
496
|
+
params.state.lexicalCursor = params.linkCanonical;
|
|
497
|
+
}
|
|
498
|
+
function readLexicalStat(params) {
|
|
499
|
+
try {
|
|
500
|
+
const stat = params.read(params.state.lexicalCursor);
|
|
501
|
+
if (isPromiseLike(stat)) return Promise.resolve(stat).catch((error) => handleLexicalStatReadFailure({
|
|
502
|
+
...params,
|
|
503
|
+
error
|
|
504
|
+
}));
|
|
505
|
+
return stat;
|
|
506
|
+
} catch (error) {
|
|
507
|
+
return handleLexicalStatReadFailure({
|
|
508
|
+
...params,
|
|
509
|
+
error
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
function resolveAndApplySymlinkHop(params) {
|
|
514
|
+
const linkCanonical = params.resolveLinkCanonical(params.state.lexicalCursor);
|
|
515
|
+
if (isPromiseLike(linkCanonical)) return Promise.resolve(linkCanonical).then((value) => applyResolvedSymlinkHop({
|
|
516
|
+
state: params.state,
|
|
517
|
+
linkCanonical: value,
|
|
518
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
519
|
+
boundaryLabel: params.boundaryLabel
|
|
520
|
+
}));
|
|
521
|
+
applyResolvedSymlinkHop({
|
|
522
|
+
state: params.state,
|
|
523
|
+
linkCanonical,
|
|
524
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
525
|
+
boundaryLabel: params.boundaryLabel
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
function* iterateLexicalTraversal(state) {
|
|
529
|
+
for (let idx = 0; idx < state.segments.length; idx += 1) {
|
|
530
|
+
const segment = state.segments[idx] ?? "";
|
|
531
|
+
const isLast = idx === state.segments.length - 1;
|
|
532
|
+
state.lexicalCursor = path.join(state.lexicalCursor, segment);
|
|
533
|
+
yield {
|
|
534
|
+
idx,
|
|
535
|
+
segment,
|
|
536
|
+
isLast
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
async function resolveBoundaryPathLexicalAsync(params) {
|
|
541
|
+
const state = createLexicalTraversalState(params);
|
|
542
|
+
const sharedStepParams = {
|
|
543
|
+
state,
|
|
544
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
545
|
+
resolveParams: params.params,
|
|
546
|
+
absolutePath: params.absolutePath
|
|
547
|
+
};
|
|
548
|
+
for (const { idx, segment, isLast } of iterateLexicalTraversal(state)) {
|
|
549
|
+
const stat = await readLexicalStat({
|
|
550
|
+
...sharedStepParams,
|
|
551
|
+
missingFromIndex: idx,
|
|
552
|
+
read: (cursor) => fs$1.lstat(cursor)
|
|
553
|
+
});
|
|
554
|
+
if (!stat) break;
|
|
555
|
+
const disposition = handleLexicalStatDisposition({
|
|
556
|
+
...sharedStepParams,
|
|
557
|
+
isSymbolicLink: stat.isSymbolicLink(),
|
|
558
|
+
segment,
|
|
559
|
+
isLast
|
|
560
|
+
});
|
|
561
|
+
if (disposition === "continue") continue;
|
|
562
|
+
if (disposition === "break") break;
|
|
563
|
+
await resolveAndApplySymlinkHop({
|
|
564
|
+
state,
|
|
565
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
566
|
+
boundaryLabel: params.params.boundaryLabel,
|
|
567
|
+
resolveLinkCanonical: (cursor) => resolveSymlinkHopPath(cursor)
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
const kind = await getPathKind(params.absolutePath, state.preserveFinalSymlink);
|
|
571
|
+
return finalizeLexicalResolution({
|
|
572
|
+
...params,
|
|
573
|
+
state,
|
|
574
|
+
kind
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
function resolveBoundaryPathLexicalSync(params) {
|
|
578
|
+
const state = createLexicalTraversalState(params);
|
|
579
|
+
for (let idx = 0; idx < state.segments.length; idx += 1) {
|
|
580
|
+
const segment = state.segments[idx] ?? "";
|
|
581
|
+
const isLast = idx === state.segments.length - 1;
|
|
582
|
+
state.lexicalCursor = path.join(state.lexicalCursor, segment);
|
|
583
|
+
const maybeStat = readLexicalStat({
|
|
584
|
+
state,
|
|
585
|
+
missingFromIndex: idx,
|
|
586
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
587
|
+
resolveParams: params.params,
|
|
588
|
+
absolutePath: params.absolutePath,
|
|
589
|
+
read: (cursor) => fs.lstatSync(cursor)
|
|
590
|
+
});
|
|
591
|
+
if (isPromiseLike(maybeStat)) throw new Error("Unexpected async lexical stat");
|
|
592
|
+
const stat = maybeStat;
|
|
593
|
+
if (!stat) break;
|
|
594
|
+
const disposition = handleLexicalStatDisposition({
|
|
595
|
+
state,
|
|
596
|
+
isSymbolicLink: stat.isSymbolicLink(),
|
|
597
|
+
segment,
|
|
598
|
+
isLast,
|
|
599
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
600
|
+
resolveParams: params.params,
|
|
601
|
+
absolutePath: params.absolutePath
|
|
602
|
+
});
|
|
603
|
+
if (disposition === "continue") continue;
|
|
604
|
+
if (disposition === "break") break;
|
|
605
|
+
if (isPromiseLike(resolveAndApplySymlinkHop({
|
|
606
|
+
state,
|
|
607
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
608
|
+
boundaryLabel: params.params.boundaryLabel,
|
|
609
|
+
resolveLinkCanonical: (cursor) => resolveSymlinkHopPathSync(cursor)
|
|
610
|
+
}))) throw new Error("Unexpected async symlink resolution");
|
|
611
|
+
}
|
|
612
|
+
const kind = getPathKindSync(params.absolutePath, state.preserveFinalSymlink);
|
|
613
|
+
return finalizeLexicalResolution({
|
|
614
|
+
...params,
|
|
615
|
+
state,
|
|
616
|
+
kind
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
function resolveCanonicalOutsideLexicalPath(params) {
|
|
620
|
+
return params.outsideLexicalCanonicalPath ?? params.absolutePath;
|
|
621
|
+
}
|
|
622
|
+
function createBoundaryResolutionContext(params) {
|
|
623
|
+
const lexicalInside = isPathInside(params.rootPath, params.absolutePath);
|
|
624
|
+
const canonicalOutsideLexicalPath = resolveCanonicalOutsideLexicalPath({
|
|
625
|
+
absolutePath: params.absolutePath,
|
|
626
|
+
outsideLexicalCanonicalPath: params.outsideLexicalCanonicalPath
|
|
627
|
+
});
|
|
628
|
+
assertLexicalBoundaryOrCanonicalAlias({
|
|
629
|
+
skipLexicalRootCheck: params.resolveParams.skipLexicalRootCheck,
|
|
630
|
+
lexicalInside,
|
|
631
|
+
canonicalOutsideLexicalPath,
|
|
632
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
633
|
+
boundaryLabel: params.resolveParams.boundaryLabel,
|
|
634
|
+
rootPath: params.rootPath,
|
|
635
|
+
absolutePath: params.absolutePath
|
|
636
|
+
});
|
|
637
|
+
return {
|
|
638
|
+
rootPath: params.rootPath,
|
|
639
|
+
absolutePath: params.absolutePath,
|
|
640
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
641
|
+
lexicalInside,
|
|
642
|
+
canonicalOutsideLexicalPath
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
async function resolveOutsideBoundaryPathAsync(params) {
|
|
646
|
+
if (params.context.lexicalInside) return null;
|
|
647
|
+
const kind = await getPathKind(params.context.absolutePath, false);
|
|
648
|
+
return buildOutsideLexicalBoundaryPath({
|
|
649
|
+
boundaryLabel: params.boundaryLabel,
|
|
650
|
+
rootCanonicalPath: params.context.rootCanonicalPath,
|
|
651
|
+
absolutePath: params.context.absolutePath,
|
|
652
|
+
canonicalOutsideLexicalPath: params.context.canonicalOutsideLexicalPath,
|
|
653
|
+
rootPath: params.context.rootPath,
|
|
654
|
+
kind
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
function resolveOutsideBoundaryPathSync(params) {
|
|
658
|
+
if (params.context.lexicalInside) return null;
|
|
659
|
+
const kind = getPathKindSync(params.context.absolutePath, false);
|
|
660
|
+
return buildOutsideLexicalBoundaryPath({
|
|
661
|
+
boundaryLabel: params.boundaryLabel,
|
|
662
|
+
rootCanonicalPath: params.context.rootCanonicalPath,
|
|
663
|
+
absolutePath: params.context.absolutePath,
|
|
664
|
+
canonicalOutsideLexicalPath: params.context.canonicalOutsideLexicalPath,
|
|
665
|
+
rootPath: params.context.rootPath,
|
|
666
|
+
kind
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
async function resolveOutsideLexicalCanonicalPathAsync(params) {
|
|
670
|
+
if (isPathInside(params.rootPath, params.absolutePath)) return;
|
|
671
|
+
return await resolvePathViaExistingAncestor(params.absolutePath);
|
|
672
|
+
}
|
|
673
|
+
function resolveOutsideLexicalCanonicalPathSync(params) {
|
|
674
|
+
if (isPathInside(params.rootPath, params.absolutePath)) return;
|
|
675
|
+
return resolvePathViaExistingAncestorSync(params.absolutePath);
|
|
676
|
+
}
|
|
677
|
+
function buildOutsideLexicalBoundaryPath(params) {
|
|
678
|
+
assertInsideBoundary({
|
|
679
|
+
boundaryLabel: params.boundaryLabel,
|
|
680
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
681
|
+
candidatePath: params.canonicalOutsideLexicalPath,
|
|
682
|
+
absolutePath: params.absolutePath
|
|
683
|
+
});
|
|
684
|
+
return buildResolvedBoundaryPath({
|
|
685
|
+
absolutePath: params.absolutePath,
|
|
686
|
+
canonicalPath: params.canonicalOutsideLexicalPath,
|
|
687
|
+
rootPath: params.rootPath,
|
|
688
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
689
|
+
kind: params.kind
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
function assertLexicalBoundaryOrCanonicalAlias(params) {
|
|
693
|
+
if (params.skipLexicalRootCheck || params.lexicalInside) return;
|
|
694
|
+
if (isPathInside(params.rootCanonicalPath, params.canonicalOutsideLexicalPath)) return;
|
|
695
|
+
throw pathEscapeError({
|
|
696
|
+
boundaryLabel: params.boundaryLabel,
|
|
697
|
+
rootPath: params.rootPath,
|
|
698
|
+
absolutePath: params.absolutePath
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
function buildResolvedBoundaryPath(params) {
|
|
702
|
+
return {
|
|
703
|
+
absolutePath: params.absolutePath,
|
|
704
|
+
canonicalPath: params.canonicalPath,
|
|
705
|
+
rootPath: params.rootPath,
|
|
706
|
+
rootCanonicalPath: params.rootCanonicalPath,
|
|
707
|
+
relativePath: relativeInsideRoot(params.rootCanonicalPath, params.canonicalPath),
|
|
708
|
+
exists: params.kind.exists,
|
|
709
|
+
kind: params.kind.kind
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
async function resolvePathViaExistingAncestor(targetPath) {
|
|
713
|
+
const normalized = path.resolve(targetPath);
|
|
714
|
+
let cursor = normalized;
|
|
715
|
+
const missingSuffix = [];
|
|
716
|
+
while (!isFilesystemRoot(cursor) && !await pathExists(cursor)) {
|
|
717
|
+
missingSuffix.unshift(path.basename(cursor));
|
|
718
|
+
const parent = path.dirname(cursor);
|
|
719
|
+
if (parent === cursor) break;
|
|
720
|
+
cursor = parent;
|
|
721
|
+
}
|
|
722
|
+
if (!await pathExists(cursor)) return normalized;
|
|
723
|
+
try {
|
|
724
|
+
const resolvedAncestor = path.resolve(await fs$1.realpath(cursor));
|
|
725
|
+
if (missingSuffix.length === 0) return resolvedAncestor;
|
|
726
|
+
return path.resolve(resolvedAncestor, ...missingSuffix);
|
|
727
|
+
} catch {
|
|
728
|
+
return normalized;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
function resolvePathViaExistingAncestorSync(targetPath) {
|
|
732
|
+
const normalized = path.resolve(targetPath);
|
|
733
|
+
let cursor = normalized;
|
|
734
|
+
const missingSuffix = [];
|
|
735
|
+
while (!isFilesystemRoot(cursor) && !fs.existsSync(cursor)) {
|
|
736
|
+
missingSuffix.unshift(path.basename(cursor));
|
|
737
|
+
const parent = path.dirname(cursor);
|
|
738
|
+
if (parent === cursor) break;
|
|
739
|
+
cursor = parent;
|
|
740
|
+
}
|
|
741
|
+
if (!fs.existsSync(cursor)) return normalized;
|
|
742
|
+
try {
|
|
743
|
+
const resolvedAncestor = path.resolve(fs.realpathSync(cursor));
|
|
744
|
+
if (missingSuffix.length === 0) return resolvedAncestor;
|
|
745
|
+
return path.resolve(resolvedAncestor, ...missingSuffix);
|
|
746
|
+
} catch {
|
|
747
|
+
return normalized;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
async function getPathKind(absolutePath, preserveFinalSymlink) {
|
|
751
|
+
try {
|
|
752
|
+
return {
|
|
753
|
+
exists: true,
|
|
754
|
+
kind: toResolvedKind(preserveFinalSymlink ? await fs$1.lstat(absolutePath) : await fs$1.stat(absolutePath))
|
|
755
|
+
};
|
|
756
|
+
} catch (error) {
|
|
757
|
+
if (isNotFoundPathError(error)) return {
|
|
758
|
+
exists: false,
|
|
759
|
+
kind: "missing"
|
|
760
|
+
};
|
|
761
|
+
throw error;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
function getPathKindSync(absolutePath, preserveFinalSymlink) {
|
|
765
|
+
try {
|
|
766
|
+
return {
|
|
767
|
+
exists: true,
|
|
768
|
+
kind: toResolvedKind(preserveFinalSymlink ? fs.lstatSync(absolutePath) : fs.statSync(absolutePath))
|
|
769
|
+
};
|
|
770
|
+
} catch (error) {
|
|
771
|
+
if (isNotFoundPathError(error)) return {
|
|
772
|
+
exists: false,
|
|
773
|
+
kind: "missing"
|
|
774
|
+
};
|
|
775
|
+
throw error;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
function toResolvedKind(stat) {
|
|
779
|
+
if (stat.isFile()) return "file";
|
|
780
|
+
if (stat.isDirectory()) return "directory";
|
|
781
|
+
if (stat.isSymbolicLink()) return "symlink";
|
|
782
|
+
return "other";
|
|
783
|
+
}
|
|
784
|
+
function relativeInsideRoot(rootPath, targetPath) {
|
|
785
|
+
const relative = path.relative(path.resolve(rootPath), path.resolve(targetPath));
|
|
786
|
+
if (!relative || relative === ".") return "";
|
|
787
|
+
if (relative.startsWith("..") || path.isAbsolute(relative)) return "";
|
|
788
|
+
return relative;
|
|
789
|
+
}
|
|
790
|
+
function assertInsideBoundary(params) {
|
|
791
|
+
if (isPathInside(params.rootCanonicalPath, params.candidatePath)) return;
|
|
792
|
+
throw new Error(`Path resolves outside ${params.boundaryLabel} (${shortPath(params.rootCanonicalPath)}): ${shortPath(params.absolutePath)}`);
|
|
793
|
+
}
|
|
794
|
+
function pathEscapeError(params) {
|
|
795
|
+
return /* @__PURE__ */ new Error(`Path escapes ${params.boundaryLabel} (${shortPath(params.rootPath)}): ${shortPath(params.absolutePath)}`);
|
|
796
|
+
}
|
|
797
|
+
function symlinkEscapeError(params) {
|
|
798
|
+
return /* @__PURE__ */ new Error(`Symlink escapes ${params.boundaryLabel} (${shortPath(params.rootCanonicalPath)}): ${shortPath(params.symlinkPath)}`);
|
|
799
|
+
}
|
|
800
|
+
function shortPath(value) {
|
|
801
|
+
const home = os.homedir();
|
|
802
|
+
if (value.startsWith(home)) return `~${value.slice(home.length)}`;
|
|
803
|
+
return value;
|
|
804
|
+
}
|
|
805
|
+
function isFilesystemRoot(candidate) {
|
|
806
|
+
return path.parse(candidate).root === candidate;
|
|
807
|
+
}
|
|
808
|
+
async function pathExists(targetPath) {
|
|
809
|
+
try {
|
|
810
|
+
await fs$1.lstat(targetPath);
|
|
811
|
+
return true;
|
|
812
|
+
} catch (error) {
|
|
813
|
+
if (isNotFoundPathError(error)) return false;
|
|
814
|
+
throw error;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
async function resolveSymlinkHopPath(symlinkPath) {
|
|
818
|
+
try {
|
|
819
|
+
return path.resolve(await fs$1.realpath(symlinkPath));
|
|
820
|
+
} catch (error) {
|
|
821
|
+
if (!isNotFoundPathError(error)) throw error;
|
|
822
|
+
const linkTarget = await fs$1.readlink(symlinkPath);
|
|
823
|
+
return resolvePathViaExistingAncestor(path.resolve(path.dirname(symlinkPath), linkTarget));
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
function resolveSymlinkHopPathSync(symlinkPath) {
|
|
827
|
+
try {
|
|
828
|
+
return path.resolve(fs.realpathSync(symlinkPath));
|
|
829
|
+
} catch (error) {
|
|
830
|
+
if (!isNotFoundPathError(error)) throw error;
|
|
831
|
+
const linkTarget = fs.readlinkSync(symlinkPath);
|
|
832
|
+
return resolvePathViaExistingAncestorSync(path.resolve(path.dirname(symlinkPath), linkTarget));
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
//#endregion
|
|
837
|
+
//#region src/infra/file-identity.ts
|
|
838
|
+
function isZero(value) {
|
|
839
|
+
return value === 0 || value === 0n;
|
|
840
|
+
}
|
|
841
|
+
function sameFileIdentity$1(left, right, platform = process.platform) {
|
|
842
|
+
if (left.ino !== right.ino) return false;
|
|
843
|
+
if (left.dev === right.dev) return true;
|
|
844
|
+
return platform === "win32" && (isZero(left.dev) || isZero(right.dev));
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
//#endregion
|
|
848
|
+
//#region src/infra/safe-open-sync.ts
|
|
849
|
+
function isExpectedPathError(error) {
|
|
850
|
+
const code = typeof error === "object" && error !== null && "code" in error ? String(error.code) : "";
|
|
851
|
+
return code === "ENOENT" || code === "ENOTDIR" || code === "ELOOP";
|
|
852
|
+
}
|
|
853
|
+
function sameFileIdentity(left, right) {
|
|
854
|
+
return sameFileIdentity$1(left, right);
|
|
855
|
+
}
|
|
856
|
+
function openVerifiedFileSync(params) {
|
|
857
|
+
const ioFs = params.ioFs ?? fs;
|
|
858
|
+
const allowedType = params.allowedType ?? "file";
|
|
859
|
+
const openReadFlags = ioFs.constants.O_RDONLY | (typeof ioFs.constants.O_NOFOLLOW === "number" ? ioFs.constants.O_NOFOLLOW : 0);
|
|
860
|
+
let fd = null;
|
|
861
|
+
try {
|
|
862
|
+
if (params.rejectPathSymlink) {
|
|
863
|
+
if (ioFs.lstatSync(params.filePath).isSymbolicLink()) return {
|
|
864
|
+
ok: false,
|
|
865
|
+
reason: "validation"
|
|
866
|
+
};
|
|
867
|
+
}
|
|
868
|
+
const realPath = params.resolvedPath ?? ioFs.realpathSync(params.filePath);
|
|
869
|
+
const preOpenStat = ioFs.lstatSync(realPath);
|
|
870
|
+
if (!isAllowedType(preOpenStat, allowedType)) return {
|
|
871
|
+
ok: false,
|
|
872
|
+
reason: "validation"
|
|
873
|
+
};
|
|
874
|
+
if (params.rejectHardlinks && preOpenStat.isFile() && preOpenStat.nlink > 1) return {
|
|
875
|
+
ok: false,
|
|
876
|
+
reason: "validation"
|
|
877
|
+
};
|
|
878
|
+
if (params.maxBytes !== void 0 && preOpenStat.isFile() && preOpenStat.size > params.maxBytes) return {
|
|
879
|
+
ok: false,
|
|
880
|
+
reason: "validation"
|
|
881
|
+
};
|
|
882
|
+
fd = ioFs.openSync(realPath, openReadFlags);
|
|
883
|
+
const openedStat = ioFs.fstatSync(fd);
|
|
884
|
+
if (!isAllowedType(openedStat, allowedType)) return {
|
|
885
|
+
ok: false,
|
|
886
|
+
reason: "validation"
|
|
887
|
+
};
|
|
888
|
+
if (params.rejectHardlinks && openedStat.isFile() && openedStat.nlink > 1) return {
|
|
889
|
+
ok: false,
|
|
890
|
+
reason: "validation"
|
|
891
|
+
};
|
|
892
|
+
if (params.maxBytes !== void 0 && openedStat.isFile() && openedStat.size > params.maxBytes) return {
|
|
893
|
+
ok: false,
|
|
894
|
+
reason: "validation"
|
|
895
|
+
};
|
|
896
|
+
if (!sameFileIdentity(preOpenStat, openedStat)) return {
|
|
897
|
+
ok: false,
|
|
898
|
+
reason: "validation"
|
|
899
|
+
};
|
|
900
|
+
const opened = {
|
|
901
|
+
ok: true,
|
|
902
|
+
path: realPath,
|
|
903
|
+
fd,
|
|
904
|
+
stat: openedStat
|
|
905
|
+
};
|
|
906
|
+
fd = null;
|
|
907
|
+
return opened;
|
|
908
|
+
} catch (error) {
|
|
909
|
+
if (isExpectedPathError(error)) return {
|
|
910
|
+
ok: false,
|
|
911
|
+
reason: "path",
|
|
912
|
+
error
|
|
913
|
+
};
|
|
914
|
+
return {
|
|
915
|
+
ok: false,
|
|
916
|
+
reason: "io",
|
|
917
|
+
error
|
|
918
|
+
};
|
|
919
|
+
} finally {
|
|
920
|
+
if (fd !== null) ioFs.closeSync(fd);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
function isAllowedType(stat, allowedType) {
|
|
924
|
+
if (allowedType === "directory") return stat.isDirectory();
|
|
925
|
+
return stat.isFile();
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
//#endregion
|
|
929
|
+
//#region src/infra/boundary-file-read.ts
|
|
930
|
+
function canUseBoundaryFileOpen(ioFs) {
|
|
931
|
+
return typeof ioFs.openSync === "function" && typeof ioFs.closeSync === "function" && typeof ioFs.fstatSync === "function" && typeof ioFs.lstatSync === "function" && typeof ioFs.realpathSync === "function" && typeof ioFs.readFileSync === "function" && typeof ioFs.constants === "object" && ioFs.constants !== null;
|
|
932
|
+
}
|
|
933
|
+
function openBoundaryFileSync(params) {
|
|
934
|
+
const ioFs = params.ioFs ?? fs;
|
|
935
|
+
const resolved = resolveBoundaryFilePathGeneric({
|
|
936
|
+
absolutePath: params.absolutePath,
|
|
937
|
+
resolve: (absolutePath) => resolveBoundaryPathSync({
|
|
938
|
+
absolutePath,
|
|
939
|
+
rootPath: params.rootPath,
|
|
940
|
+
rootCanonicalPath: params.rootRealPath,
|
|
941
|
+
boundaryLabel: params.boundaryLabel,
|
|
942
|
+
skipLexicalRootCheck: params.skipLexicalRootCheck
|
|
943
|
+
})
|
|
944
|
+
});
|
|
945
|
+
if (resolved instanceof Promise) return toBoundaryValidationError(/* @__PURE__ */ new Error("Unexpected async boundary resolution"));
|
|
946
|
+
return finalizeBoundaryFileOpen({
|
|
947
|
+
resolved,
|
|
948
|
+
maxBytes: params.maxBytes,
|
|
949
|
+
rejectHardlinks: params.rejectHardlinks,
|
|
950
|
+
allowedType: params.allowedType,
|
|
951
|
+
ioFs
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
function openBoundaryFileResolved(params) {
|
|
955
|
+
const opened = openVerifiedFileSync({
|
|
956
|
+
filePath: params.absolutePath,
|
|
957
|
+
resolvedPath: params.resolvedPath,
|
|
958
|
+
rejectHardlinks: params.rejectHardlinks ?? true,
|
|
959
|
+
maxBytes: params.maxBytes,
|
|
960
|
+
allowedType: params.allowedType,
|
|
961
|
+
ioFs: params.ioFs
|
|
962
|
+
});
|
|
963
|
+
if (!opened.ok) return opened;
|
|
964
|
+
return {
|
|
965
|
+
ok: true,
|
|
966
|
+
path: opened.path,
|
|
967
|
+
fd: opened.fd,
|
|
968
|
+
stat: opened.stat,
|
|
969
|
+
rootRealPath: params.rootRealPath
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
function finalizeBoundaryFileOpen(params) {
|
|
973
|
+
if ("ok" in params.resolved) return params.resolved;
|
|
974
|
+
return openBoundaryFileResolved({
|
|
975
|
+
absolutePath: params.resolved.absolutePath,
|
|
976
|
+
resolvedPath: params.resolved.resolvedPath,
|
|
977
|
+
rootRealPath: params.resolved.rootRealPath,
|
|
978
|
+
maxBytes: params.maxBytes,
|
|
979
|
+
rejectHardlinks: params.rejectHardlinks,
|
|
980
|
+
allowedType: params.allowedType,
|
|
981
|
+
ioFs: params.ioFs
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
async function openBoundaryFile(params) {
|
|
985
|
+
const ioFs = params.ioFs ?? fs;
|
|
986
|
+
const maybeResolved = resolveBoundaryFilePathGeneric({
|
|
987
|
+
absolutePath: params.absolutePath,
|
|
988
|
+
resolve: (absolutePath) => resolveBoundaryPath({
|
|
989
|
+
absolutePath,
|
|
990
|
+
rootPath: params.rootPath,
|
|
991
|
+
rootCanonicalPath: params.rootRealPath,
|
|
992
|
+
boundaryLabel: params.boundaryLabel,
|
|
993
|
+
policy: params.aliasPolicy,
|
|
994
|
+
skipLexicalRootCheck: params.skipLexicalRootCheck
|
|
995
|
+
})
|
|
996
|
+
});
|
|
997
|
+
return finalizeBoundaryFileOpen({
|
|
998
|
+
resolved: maybeResolved instanceof Promise ? await maybeResolved : maybeResolved,
|
|
999
|
+
maxBytes: params.maxBytes,
|
|
1000
|
+
rejectHardlinks: params.rejectHardlinks,
|
|
1001
|
+
allowedType: params.allowedType,
|
|
1002
|
+
ioFs
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
1005
|
+
function toBoundaryValidationError(error) {
|
|
1006
|
+
return {
|
|
1007
|
+
ok: false,
|
|
1008
|
+
reason: "validation",
|
|
1009
|
+
error
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
function mapResolvedBoundaryPath(absolutePath, resolved) {
|
|
1013
|
+
return {
|
|
1014
|
+
absolutePath,
|
|
1015
|
+
resolvedPath: resolved.canonicalPath,
|
|
1016
|
+
rootRealPath: resolved.rootCanonicalPath
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
function resolveBoundaryFilePathGeneric(params) {
|
|
1020
|
+
const absolutePath = path.resolve(params.absolutePath);
|
|
1021
|
+
try {
|
|
1022
|
+
const resolved = params.resolve(absolutePath);
|
|
1023
|
+
if (resolved instanceof Promise) return resolved.then((value) => mapResolvedBoundaryPath(absolutePath, value)).catch((error) => toBoundaryValidationError(error));
|
|
1024
|
+
return mapResolvedBoundaryPath(absolutePath, resolved);
|
|
1025
|
+
} catch (error) {
|
|
1026
|
+
return toBoundaryValidationError(error);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
//#endregion
|
|
1031
|
+
//#region src/process/spawn-utils.ts
|
|
1032
|
+
const DEFAULT_RETRY_CODES = ["EBADF"];
|
|
1033
|
+
function resolveCommandStdio(params) {
|
|
1034
|
+
return [
|
|
1035
|
+
params.hasInput ? "pipe" : params.preferInherit ? "inherit" : "pipe",
|
|
1036
|
+
"pipe",
|
|
1037
|
+
"pipe"
|
|
1038
|
+
];
|
|
1039
|
+
}
|
|
1040
|
+
function shouldRetry(err, codes) {
|
|
1041
|
+
const code = err && typeof err === "object" && "code" in err ? String(err.code) : "";
|
|
1042
|
+
return code.length > 0 && codes.includes(code);
|
|
1043
|
+
}
|
|
1044
|
+
async function spawnAndWaitForSpawn(spawnImpl, argv, options) {
|
|
1045
|
+
const child = spawnImpl(argv[0], argv.slice(1), options);
|
|
1046
|
+
return await new Promise((resolve, reject) => {
|
|
1047
|
+
let settled = false;
|
|
1048
|
+
const cleanup = () => {
|
|
1049
|
+
child.removeListener("error", onError);
|
|
1050
|
+
child.removeListener("spawn", onSpawn);
|
|
1051
|
+
};
|
|
1052
|
+
const finishResolve = () => {
|
|
1053
|
+
if (settled) return;
|
|
1054
|
+
settled = true;
|
|
1055
|
+
cleanup();
|
|
1056
|
+
resolve(child);
|
|
1057
|
+
};
|
|
1058
|
+
const onError = (err) => {
|
|
1059
|
+
if (settled) return;
|
|
1060
|
+
settled = true;
|
|
1061
|
+
cleanup();
|
|
1062
|
+
reject(err);
|
|
1063
|
+
};
|
|
1064
|
+
const onSpawn = () => {
|
|
1065
|
+
finishResolve();
|
|
1066
|
+
};
|
|
1067
|
+
child.once("error", onError);
|
|
1068
|
+
child.once("spawn", onSpawn);
|
|
1069
|
+
process.nextTick(() => {
|
|
1070
|
+
if (typeof child.pid === "number") finishResolve();
|
|
1071
|
+
});
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
async function spawnWithFallback(params) {
|
|
1075
|
+
const spawnImpl = params.spawnImpl ?? spawn;
|
|
1076
|
+
const retryCodes = params.retryCodes ?? DEFAULT_RETRY_CODES;
|
|
1077
|
+
const baseOptions = { ...params.options };
|
|
1078
|
+
const fallbacks = params.fallbacks ?? [];
|
|
1079
|
+
const attempts = [{ options: baseOptions }, ...fallbacks.map((fallback) => ({
|
|
1080
|
+
label: fallback.label,
|
|
1081
|
+
options: {
|
|
1082
|
+
...baseOptions,
|
|
1083
|
+
...fallback.options
|
|
1084
|
+
}
|
|
1085
|
+
}))];
|
|
1086
|
+
let lastError;
|
|
1087
|
+
for (let index = 0; index < attempts.length; index += 1) {
|
|
1088
|
+
const attempt = attempts[index];
|
|
1089
|
+
try {
|
|
1090
|
+
return {
|
|
1091
|
+
child: await spawnAndWaitForSpawn(spawnImpl, params.argv, attempt.options),
|
|
1092
|
+
usedFallback: index > 0,
|
|
1093
|
+
fallbackLabel: attempt.label
|
|
1094
|
+
};
|
|
1095
|
+
} catch (err) {
|
|
1096
|
+
lastError = err;
|
|
1097
|
+
const nextFallback = fallbacks[index];
|
|
1098
|
+
if (!nextFallback || !shouldRetry(err, retryCodes)) throw err;
|
|
1099
|
+
params.onFallback?.(err, nextFallback);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
throw lastError;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
//#endregion
|
|
1106
|
+
//#region src/process/exec.ts
|
|
1107
|
+
const execFileAsync = promisify(execFile);
|
|
1108
|
+
const WINDOWS_UNSAFE_CMD_CHARS_RE = /[&|<>^%\r\n]/;
|
|
1109
|
+
function isWindowsBatchCommand(resolvedCommand) {
|
|
1110
|
+
if (process$1.platform !== "win32") return false;
|
|
1111
|
+
const ext = path.extname(resolvedCommand).toLowerCase();
|
|
1112
|
+
return ext === ".cmd" || ext === ".bat";
|
|
1113
|
+
}
|
|
1114
|
+
function escapeForCmdExe(arg) {
|
|
1115
|
+
if (WINDOWS_UNSAFE_CMD_CHARS_RE.test(arg)) throw new Error(`Unsafe Windows cmd.exe argument detected: ${JSON.stringify(arg)}. Pass an explicit shell-wrapper argv at the call site instead.`);
|
|
1116
|
+
if (!arg.includes(" ") && !arg.includes("\"")) return arg;
|
|
1117
|
+
return `"${arg.replace(/"/g, "\"\"")}"`;
|
|
1118
|
+
}
|
|
1119
|
+
function buildCmdExeCommandLine(resolvedCommand, args) {
|
|
1120
|
+
return [escapeForCmdExe(resolvedCommand), ...args.map(escapeForCmdExe)].join(" ");
|
|
1121
|
+
}
|
|
1122
|
+
/**
|
|
1123
|
+
* On Windows, Node 18.20.2+ (CVE-2024-27980) rejects spawning .cmd/.bat directly
|
|
1124
|
+
* without shell, causing EINVAL. Resolve npm/npx to node + cli script so we
|
|
1125
|
+
* spawn node.exe instead of npm.cmd.
|
|
1126
|
+
*/
|
|
1127
|
+
function resolveNpmArgvForWindows(argv) {
|
|
1128
|
+
if (process$1.platform !== "win32" || argv.length === 0) return null;
|
|
1129
|
+
const basename = path.basename(argv[0]).toLowerCase().replace(/\.(cmd|exe|bat)$/, "");
|
|
1130
|
+
const cliName = basename === "npx" ? "npx-cli.js" : basename === "npm" ? "npm-cli.js" : null;
|
|
1131
|
+
if (!cliName) return null;
|
|
1132
|
+
const nodeDir = path.dirname(process$1.execPath);
|
|
1133
|
+
const cliPath = path.join(nodeDir, "node_modules", "npm", "bin", cliName);
|
|
1134
|
+
if (!fs.existsSync(cliPath)) return null;
|
|
1135
|
+
return [
|
|
1136
|
+
process$1.execPath,
|
|
1137
|
+
cliPath,
|
|
1138
|
+
...argv.slice(1)
|
|
1139
|
+
];
|
|
1140
|
+
}
|
|
1141
|
+
/**
|
|
1142
|
+
* Resolves a command for Windows compatibility.
|
|
1143
|
+
* On Windows, non-.exe commands (like pnpm, yarn) are resolved to .cmd; npm/npx
|
|
1144
|
+
* are handled by resolveNpmArgvForWindows to avoid spawn EINVAL (no direct .cmd).
|
|
1145
|
+
*/
|
|
1146
|
+
function resolveCommand(command) {
|
|
1147
|
+
if (process$1.platform !== "win32") return command;
|
|
1148
|
+
const basename = path.basename(command).toLowerCase();
|
|
1149
|
+
if (path.extname(basename)) return command;
|
|
1150
|
+
if (["pnpm", "yarn"].includes(basename)) return `${command}.cmd`;
|
|
1151
|
+
return command;
|
|
1152
|
+
}
|
|
1153
|
+
function shouldSpawnWithShell(params) {
|
|
1154
|
+
return false;
|
|
1155
|
+
}
|
|
1156
|
+
async function runExec(command, args, opts = 1e4) {
|
|
1157
|
+
const options = typeof opts === "number" ? {
|
|
1158
|
+
timeout: opts,
|
|
1159
|
+
encoding: "utf8"
|
|
1160
|
+
} : {
|
|
1161
|
+
timeout: opts.timeoutMs,
|
|
1162
|
+
maxBuffer: opts.maxBuffer,
|
|
1163
|
+
cwd: opts.cwd,
|
|
1164
|
+
encoding: "utf8"
|
|
1165
|
+
};
|
|
1166
|
+
try {
|
|
1167
|
+
const argv = [command, ...args];
|
|
1168
|
+
let execCommand;
|
|
1169
|
+
let execArgs;
|
|
1170
|
+
if (process$1.platform === "win32") {
|
|
1171
|
+
const resolved = resolveNpmArgvForWindows(argv);
|
|
1172
|
+
if (resolved) {
|
|
1173
|
+
execCommand = resolved[0] ?? "";
|
|
1174
|
+
execArgs = resolved.slice(1);
|
|
1175
|
+
} else {
|
|
1176
|
+
execCommand = resolveCommand(command);
|
|
1177
|
+
execArgs = args;
|
|
1178
|
+
}
|
|
1179
|
+
} else {
|
|
1180
|
+
execCommand = resolveCommand(command);
|
|
1181
|
+
execArgs = args;
|
|
1182
|
+
}
|
|
1183
|
+
const { stdout, stderr } = isWindowsBatchCommand(execCommand) ? await execFileAsync(process$1.env.ComSpec ?? "cmd.exe", [
|
|
1184
|
+
"/d",
|
|
1185
|
+
"/s",
|
|
1186
|
+
"/c",
|
|
1187
|
+
buildCmdExeCommandLine(execCommand, execArgs)
|
|
1188
|
+
], {
|
|
1189
|
+
...options,
|
|
1190
|
+
windowsVerbatimArguments: true
|
|
1191
|
+
}) : await execFileAsync(execCommand, execArgs, options);
|
|
1192
|
+
if (shouldLogVerbose()) {
|
|
1193
|
+
if (stdout.trim()) logDebug(stdout.trim());
|
|
1194
|
+
if (stderr.trim()) logError(stderr.trim());
|
|
1195
|
+
}
|
|
1196
|
+
return {
|
|
1197
|
+
stdout,
|
|
1198
|
+
stderr
|
|
1199
|
+
};
|
|
1200
|
+
} catch (err) {
|
|
1201
|
+
if (shouldLogVerbose()) logError(danger(`Command failed: ${command} ${args.join(" ")}`));
|
|
1202
|
+
throw err;
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
function resolveCommandEnv(params) {
|
|
1206
|
+
const baseEnv = params.baseEnv ?? process$1.env;
|
|
1207
|
+
const argv = params.argv;
|
|
1208
|
+
const shouldSuppressNpmFund = (() => {
|
|
1209
|
+
const cmd = path.basename(argv[0] ?? "");
|
|
1210
|
+
if (cmd === "npm" || cmd === "npm.cmd" || cmd === "npm.exe") return true;
|
|
1211
|
+
if (cmd === "node" || cmd === "node.exe") return (argv[1] ?? "").includes("npm-cli.js");
|
|
1212
|
+
return false;
|
|
1213
|
+
})();
|
|
1214
|
+
const mergedEnv = params.env ? {
|
|
1215
|
+
...baseEnv,
|
|
1216
|
+
...params.env
|
|
1217
|
+
} : { ...baseEnv };
|
|
1218
|
+
const resolvedEnv = Object.fromEntries(Object.entries(mergedEnv).filter(([, value]) => value !== void 0).map(([key, value]) => [key, String(value)]));
|
|
1219
|
+
if (shouldSuppressNpmFund) {
|
|
1220
|
+
if (resolvedEnv.NPM_CONFIG_FUND == null) resolvedEnv.NPM_CONFIG_FUND = "false";
|
|
1221
|
+
if (resolvedEnv.npm_config_fund == null) resolvedEnv.npm_config_fund = "false";
|
|
1222
|
+
}
|
|
1223
|
+
return resolvedEnv;
|
|
1224
|
+
}
|
|
1225
|
+
async function runCommandWithTimeout(argv, optionsOrTimeout) {
|
|
1226
|
+
const options = typeof optionsOrTimeout === "number" ? { timeoutMs: optionsOrTimeout } : optionsOrTimeout;
|
|
1227
|
+
const { timeoutMs, cwd, input, env, noOutputTimeoutMs } = options;
|
|
1228
|
+
const { windowsVerbatimArguments } = options;
|
|
1229
|
+
const hasInput = input !== void 0;
|
|
1230
|
+
const resolvedEnv = resolveCommandEnv({
|
|
1231
|
+
argv,
|
|
1232
|
+
env
|
|
1233
|
+
});
|
|
1234
|
+
const stdio = resolveCommandStdio({
|
|
1235
|
+
hasInput,
|
|
1236
|
+
preferInherit: true
|
|
1237
|
+
});
|
|
1238
|
+
const finalArgv = process$1.platform === "win32" ? resolveNpmArgvForWindows(argv) ?? argv : argv;
|
|
1239
|
+
const resolvedCommand = finalArgv !== argv ? finalArgv[0] ?? "" : resolveCommand(argv[0] ?? "");
|
|
1240
|
+
const useCmdWrapper = isWindowsBatchCommand(resolvedCommand);
|
|
1241
|
+
const child = spawn(useCmdWrapper ? process$1.env.ComSpec ?? "cmd.exe" : resolvedCommand, useCmdWrapper ? [
|
|
1242
|
+
"/d",
|
|
1243
|
+
"/s",
|
|
1244
|
+
"/c",
|
|
1245
|
+
buildCmdExeCommandLine(resolvedCommand, finalArgv.slice(1))
|
|
1246
|
+
] : finalArgv.slice(1), {
|
|
1247
|
+
stdio,
|
|
1248
|
+
cwd,
|
|
1249
|
+
env: resolvedEnv,
|
|
1250
|
+
windowsVerbatimArguments: useCmdWrapper ? true : windowsVerbatimArguments,
|
|
1251
|
+
...shouldSpawnWithShell({
|
|
1252
|
+
resolvedCommand,
|
|
1253
|
+
platform: process$1.platform
|
|
1254
|
+
}) ? { shell: true } : {}
|
|
1255
|
+
});
|
|
1256
|
+
return await new Promise((resolve, reject) => {
|
|
1257
|
+
let stdout = "";
|
|
1258
|
+
let stderr = "";
|
|
1259
|
+
let settled = false;
|
|
1260
|
+
let timedOut = false;
|
|
1261
|
+
let noOutputTimedOut = false;
|
|
1262
|
+
let noOutputTimer = null;
|
|
1263
|
+
const shouldTrackOutputTimeout = typeof noOutputTimeoutMs === "number" && Number.isFinite(noOutputTimeoutMs) && noOutputTimeoutMs > 0;
|
|
1264
|
+
const clearNoOutputTimer = () => {
|
|
1265
|
+
if (!noOutputTimer) return;
|
|
1266
|
+
clearTimeout(noOutputTimer);
|
|
1267
|
+
noOutputTimer = null;
|
|
1268
|
+
};
|
|
1269
|
+
const armNoOutputTimer = () => {
|
|
1270
|
+
if (!shouldTrackOutputTimeout || settled) return;
|
|
1271
|
+
clearNoOutputTimer();
|
|
1272
|
+
noOutputTimer = setTimeout(() => {
|
|
1273
|
+
if (settled) return;
|
|
1274
|
+
noOutputTimedOut = true;
|
|
1275
|
+
if (typeof child.kill === "function") child.kill("SIGKILL");
|
|
1276
|
+
}, Math.floor(noOutputTimeoutMs));
|
|
1277
|
+
};
|
|
1278
|
+
const timer = setTimeout(() => {
|
|
1279
|
+
timedOut = true;
|
|
1280
|
+
if (typeof child.kill === "function") child.kill("SIGKILL");
|
|
1281
|
+
}, timeoutMs);
|
|
1282
|
+
armNoOutputTimer();
|
|
1283
|
+
if (hasInput && child.stdin) {
|
|
1284
|
+
child.stdin.write(input ?? "");
|
|
1285
|
+
child.stdin.end();
|
|
1286
|
+
}
|
|
1287
|
+
child.stdout?.on("data", (d) => {
|
|
1288
|
+
stdout += d.toString();
|
|
1289
|
+
armNoOutputTimer();
|
|
1290
|
+
});
|
|
1291
|
+
child.stderr?.on("data", (d) => {
|
|
1292
|
+
stderr += d.toString();
|
|
1293
|
+
armNoOutputTimer();
|
|
1294
|
+
});
|
|
1295
|
+
child.on("error", (err) => {
|
|
1296
|
+
if (settled) return;
|
|
1297
|
+
settled = true;
|
|
1298
|
+
clearTimeout(timer);
|
|
1299
|
+
clearNoOutputTimer();
|
|
1300
|
+
reject(err);
|
|
1301
|
+
});
|
|
1302
|
+
child.on("close", (code, signal) => {
|
|
1303
|
+
if (settled) return;
|
|
1304
|
+
settled = true;
|
|
1305
|
+
clearTimeout(timer);
|
|
1306
|
+
clearNoOutputTimer();
|
|
1307
|
+
const termination = noOutputTimedOut ? "no-output-timeout" : timedOut ? "timeout" : signal != null ? "signal" : "exit";
|
|
1308
|
+
resolve({
|
|
1309
|
+
pid: child.pid ?? void 0,
|
|
1310
|
+
stdout,
|
|
1311
|
+
stderr,
|
|
1312
|
+
code,
|
|
1313
|
+
signal,
|
|
1314
|
+
killed: child.killed,
|
|
1315
|
+
termination,
|
|
1316
|
+
noOutputTimedOut
|
|
1317
|
+
});
|
|
1318
|
+
});
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
//#endregion
|
|
1323
|
+
//#region src/infra/squidclaw-root.ts
|
|
1324
|
+
const CORE_PACKAGE_NAMES = new Set(["squidclaw"]);
|
|
1325
|
+
async function readPackageName(dir) {
|
|
1326
|
+
try {
|
|
1327
|
+
const raw = await fs$1.readFile(path.join(dir, "package.json"), "utf-8");
|
|
1328
|
+
const parsed = JSON.parse(raw);
|
|
1329
|
+
return typeof parsed.name === "string" ? parsed.name : null;
|
|
1330
|
+
} catch {
|
|
1331
|
+
return null;
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
function readPackageNameSync(dir) {
|
|
1335
|
+
try {
|
|
1336
|
+
const raw = fs.readFileSync(path.join(dir, "package.json"), "utf-8");
|
|
1337
|
+
const parsed = JSON.parse(raw);
|
|
1338
|
+
return typeof parsed.name === "string" ? parsed.name : null;
|
|
1339
|
+
} catch {
|
|
1340
|
+
return null;
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
async function findPackageRoot(startDir, maxDepth = 12) {
|
|
1344
|
+
for (const current of iterAncestorDirs(startDir, maxDepth)) {
|
|
1345
|
+
const name = await readPackageName(current);
|
|
1346
|
+
if (name && CORE_PACKAGE_NAMES.has(name)) return current;
|
|
1347
|
+
}
|
|
1348
|
+
return null;
|
|
1349
|
+
}
|
|
1350
|
+
function findPackageRootSync(startDir, maxDepth = 12) {
|
|
1351
|
+
for (const current of iterAncestorDirs(startDir, maxDepth)) {
|
|
1352
|
+
const name = readPackageNameSync(current);
|
|
1353
|
+
if (name && CORE_PACKAGE_NAMES.has(name)) return current;
|
|
1354
|
+
}
|
|
1355
|
+
return null;
|
|
1356
|
+
}
|
|
1357
|
+
function* iterAncestorDirs(startDir, maxDepth) {
|
|
1358
|
+
let current = path.resolve(startDir);
|
|
1359
|
+
for (let i = 0; i < maxDepth; i += 1) {
|
|
1360
|
+
yield current;
|
|
1361
|
+
const parent = path.dirname(current);
|
|
1362
|
+
if (parent === current) break;
|
|
1363
|
+
current = parent;
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
function candidateDirsFromArgv1(argv1) {
|
|
1367
|
+
const normalized = path.resolve(argv1);
|
|
1368
|
+
const candidates = [path.dirname(normalized)];
|
|
1369
|
+
try {
|
|
1370
|
+
const resolved = fs.realpathSync(normalized);
|
|
1371
|
+
if (resolved !== normalized) candidates.push(path.dirname(resolved));
|
|
1372
|
+
} catch {}
|
|
1373
|
+
const parts = normalized.split(path.sep);
|
|
1374
|
+
const binIndex = parts.lastIndexOf(".bin");
|
|
1375
|
+
if (binIndex > 0 && parts[binIndex - 1] === "node_modules") {
|
|
1376
|
+
const binName = path.basename(normalized);
|
|
1377
|
+
const nodeModulesDir = parts.slice(0, binIndex).join(path.sep);
|
|
1378
|
+
candidates.push(path.join(nodeModulesDir, binName));
|
|
1379
|
+
}
|
|
1380
|
+
return candidates;
|
|
1381
|
+
}
|
|
1382
|
+
async function resolveSquidClawPackageRoot(opts) {
|
|
1383
|
+
for (const candidate of buildCandidates(opts)) {
|
|
1384
|
+
const found = await findPackageRoot(candidate);
|
|
1385
|
+
if (found) return found;
|
|
1386
|
+
}
|
|
1387
|
+
return null;
|
|
1388
|
+
}
|
|
1389
|
+
function resolveSquidClawPackageRootSync(opts) {
|
|
1390
|
+
for (const candidate of buildCandidates(opts)) {
|
|
1391
|
+
const found = findPackageRootSync(candidate);
|
|
1392
|
+
if (found) return found;
|
|
1393
|
+
}
|
|
1394
|
+
return null;
|
|
1395
|
+
}
|
|
1396
|
+
function buildCandidates(opts) {
|
|
1397
|
+
const candidates = [];
|
|
1398
|
+
if (opts.moduleUrl) candidates.push(path.dirname(fileURLToPath(opts.moduleUrl)));
|
|
1399
|
+
if (opts.argv1) candidates.push(...candidateDirsFromArgv1(opts.argv1));
|
|
1400
|
+
if (opts.cwd) candidates.push(opts.cwd);
|
|
1401
|
+
return candidates;
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
//#endregion
|
|
1405
|
+
//#region src/agents/workspace-templates.ts
|
|
1406
|
+
const FALLBACK_TEMPLATE_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../docs/reference/templates");
|
|
1407
|
+
let cachedTemplateDir;
|
|
1408
|
+
let resolvingTemplateDir;
|
|
1409
|
+
async function resolveWorkspaceTemplateDir(opts) {
|
|
1410
|
+
if (cachedTemplateDir) return cachedTemplateDir;
|
|
1411
|
+
if (resolvingTemplateDir) return resolvingTemplateDir;
|
|
1412
|
+
resolvingTemplateDir = (async () => {
|
|
1413
|
+
const moduleUrl = opts?.moduleUrl ?? import.meta.url;
|
|
1414
|
+
const argv1 = opts?.argv1 ?? process.argv[1];
|
|
1415
|
+
const cwd = opts?.cwd ?? process.cwd();
|
|
1416
|
+
const packageRoot = await resolveSquidClawPackageRoot({
|
|
1417
|
+
moduleUrl,
|
|
1418
|
+
argv1,
|
|
1419
|
+
cwd
|
|
1420
|
+
});
|
|
1421
|
+
const candidates = [
|
|
1422
|
+
packageRoot ? path.join(packageRoot, "docs", "reference", "templates") : null,
|
|
1423
|
+
cwd ? path.resolve(cwd, "docs", "reference", "templates") : null,
|
|
1424
|
+
FALLBACK_TEMPLATE_DIR
|
|
1425
|
+
].filter(Boolean);
|
|
1426
|
+
for (const candidate of candidates) if (await pathExists$1(candidate)) {
|
|
1427
|
+
cachedTemplateDir = candidate;
|
|
1428
|
+
return candidate;
|
|
1429
|
+
}
|
|
1430
|
+
cachedTemplateDir = candidates[0] ?? FALLBACK_TEMPLATE_DIR;
|
|
1431
|
+
return cachedTemplateDir;
|
|
1432
|
+
})();
|
|
1433
|
+
try {
|
|
1434
|
+
return await resolvingTemplateDir;
|
|
1435
|
+
} finally {
|
|
1436
|
+
resolvingTemplateDir = void 0;
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
//#endregion
|
|
1441
|
+
//#region src/agents/workspace.ts
|
|
1442
|
+
function resolveDefaultAgentWorkspaceDir(env = process.env, homedir = os.homedir) {
|
|
1443
|
+
const home = resolveRequiredHomeDir(env, homedir);
|
|
1444
|
+
const profile = env.SQUIDCLAW_PROFILE?.trim();
|
|
1445
|
+
if (profile && profile.toLowerCase() !== "default") return path.join(home, ".squidclaw", `workspace-${profile}`);
|
|
1446
|
+
return path.join(home, ".squidclaw", "workspace");
|
|
1447
|
+
}
|
|
1448
|
+
const DEFAULT_AGENT_WORKSPACE_DIR = resolveDefaultAgentWorkspaceDir();
|
|
1449
|
+
const DEFAULT_AGENTS_FILENAME = "AGENTS.md";
|
|
1450
|
+
const DEFAULT_SOUL_FILENAME = "SOUL.md";
|
|
1451
|
+
const DEFAULT_TOOLS_FILENAME = "TOOLS.md";
|
|
1452
|
+
const DEFAULT_IDENTITY_FILENAME = "IDENTITY.md";
|
|
1453
|
+
const DEFAULT_USER_FILENAME = "USER.md";
|
|
1454
|
+
const DEFAULT_HEARTBEAT_FILENAME = "HEARTBEAT.md";
|
|
1455
|
+
const DEFAULT_BOOTSTRAP_FILENAME = "BOOTSTRAP.md";
|
|
1456
|
+
const DEFAULT_MEMORY_FILENAME = "MEMORY.md";
|
|
1457
|
+
const DEFAULT_MEMORY_ALT_FILENAME = "memory.md";
|
|
1458
|
+
const WORKSPACE_STATE_DIRNAME = ".squidclaw";
|
|
1459
|
+
const WORKSPACE_STATE_FILENAME = "workspace-state.json";
|
|
1460
|
+
const WORKSPACE_STATE_VERSION = 1;
|
|
1461
|
+
const workspaceTemplateCache = /* @__PURE__ */ new Map();
|
|
1462
|
+
let gitAvailabilityPromise = null;
|
|
1463
|
+
const MAX_WORKSPACE_BOOTSTRAP_FILE_BYTES = 2 * 1024 * 1024;
|
|
1464
|
+
const workspaceFileCache = /* @__PURE__ */ new Map();
|
|
1465
|
+
function workspaceFileIdentity(stat, canonicalPath) {
|
|
1466
|
+
return `${canonicalPath}|${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeMs}`;
|
|
1467
|
+
}
|
|
1468
|
+
async function readWorkspaceFileWithGuards(params) {
|
|
1469
|
+
const opened = await openBoundaryFile({
|
|
1470
|
+
absolutePath: params.filePath,
|
|
1471
|
+
rootPath: params.workspaceDir,
|
|
1472
|
+
boundaryLabel: "workspace root",
|
|
1473
|
+
maxBytes: MAX_WORKSPACE_BOOTSTRAP_FILE_BYTES
|
|
1474
|
+
});
|
|
1475
|
+
if (!opened.ok) {
|
|
1476
|
+
workspaceFileCache.delete(params.filePath);
|
|
1477
|
+
return opened;
|
|
1478
|
+
}
|
|
1479
|
+
const identity = workspaceFileIdentity(opened.stat, opened.path);
|
|
1480
|
+
const cached = workspaceFileCache.get(params.filePath);
|
|
1481
|
+
if (cached && cached.identity === identity) {
|
|
1482
|
+
fs.closeSync(opened.fd);
|
|
1483
|
+
return {
|
|
1484
|
+
ok: true,
|
|
1485
|
+
content: cached.content
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1488
|
+
try {
|
|
1489
|
+
const content = fs.readFileSync(opened.fd, "utf-8");
|
|
1490
|
+
workspaceFileCache.set(params.filePath, {
|
|
1491
|
+
content,
|
|
1492
|
+
identity
|
|
1493
|
+
});
|
|
1494
|
+
return {
|
|
1495
|
+
ok: true,
|
|
1496
|
+
content
|
|
1497
|
+
};
|
|
1498
|
+
} catch (error) {
|
|
1499
|
+
workspaceFileCache.delete(params.filePath);
|
|
1500
|
+
return {
|
|
1501
|
+
ok: false,
|
|
1502
|
+
reason: "io",
|
|
1503
|
+
error
|
|
1504
|
+
};
|
|
1505
|
+
} finally {
|
|
1506
|
+
fs.closeSync(opened.fd);
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
function stripFrontMatter(content) {
|
|
1510
|
+
if (!content.startsWith("---")) return content;
|
|
1511
|
+
const endIndex = content.indexOf("\n---", 3);
|
|
1512
|
+
if (endIndex === -1) return content;
|
|
1513
|
+
const start = endIndex + 4;
|
|
1514
|
+
let trimmed = content.slice(start);
|
|
1515
|
+
trimmed = trimmed.replace(/^\s+/, "");
|
|
1516
|
+
return trimmed;
|
|
1517
|
+
}
|
|
1518
|
+
async function loadTemplate(name) {
|
|
1519
|
+
const cached = workspaceTemplateCache.get(name);
|
|
1520
|
+
if (cached) return cached;
|
|
1521
|
+
const pending = (async () => {
|
|
1522
|
+
const templateDir = await resolveWorkspaceTemplateDir();
|
|
1523
|
+
const templatePath = path.join(templateDir, name);
|
|
1524
|
+
try {
|
|
1525
|
+
return stripFrontMatter(await fs$1.readFile(templatePath, "utf-8"));
|
|
1526
|
+
} catch {
|
|
1527
|
+
throw new Error(`Missing workspace template: ${name} (${templatePath}). Ensure docs/reference/templates are packaged.`);
|
|
1528
|
+
}
|
|
1529
|
+
})();
|
|
1530
|
+
workspaceTemplateCache.set(name, pending);
|
|
1531
|
+
try {
|
|
1532
|
+
return await pending;
|
|
1533
|
+
} catch (error) {
|
|
1534
|
+
workspaceTemplateCache.delete(name);
|
|
1535
|
+
throw error;
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
async function writeFileIfMissing(filePath, content) {
|
|
1539
|
+
try {
|
|
1540
|
+
await fs$1.writeFile(filePath, content, {
|
|
1541
|
+
encoding: "utf-8",
|
|
1542
|
+
flag: "wx"
|
|
1543
|
+
});
|
|
1544
|
+
return true;
|
|
1545
|
+
} catch (err) {
|
|
1546
|
+
if (err.code !== "EEXIST") throw err;
|
|
1547
|
+
return false;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
async function fileExists(filePath) {
|
|
1551
|
+
try {
|
|
1552
|
+
await fs$1.access(filePath);
|
|
1553
|
+
return true;
|
|
1554
|
+
} catch {
|
|
1555
|
+
return false;
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
function resolveWorkspaceStatePath(dir) {
|
|
1559
|
+
return path.join(dir, WORKSPACE_STATE_DIRNAME, WORKSPACE_STATE_FILENAME);
|
|
1560
|
+
}
|
|
1561
|
+
function parseWorkspaceOnboardingState(raw) {
|
|
1562
|
+
try {
|
|
1563
|
+
const parsed = JSON.parse(raw);
|
|
1564
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
1565
|
+
return {
|
|
1566
|
+
version: WORKSPACE_STATE_VERSION,
|
|
1567
|
+
bootstrapSeededAt: typeof parsed.bootstrapSeededAt === "string" ? parsed.bootstrapSeededAt : void 0,
|
|
1568
|
+
onboardingCompletedAt: typeof parsed.onboardingCompletedAt === "string" ? parsed.onboardingCompletedAt : void 0
|
|
1569
|
+
};
|
|
1570
|
+
} catch {
|
|
1571
|
+
return null;
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
async function readWorkspaceOnboardingState(statePath) {
|
|
1575
|
+
try {
|
|
1576
|
+
return parseWorkspaceOnboardingState(await fs$1.readFile(statePath, "utf-8")) ?? { version: WORKSPACE_STATE_VERSION };
|
|
1577
|
+
} catch (err) {
|
|
1578
|
+
if (err.code !== "ENOENT") throw err;
|
|
1579
|
+
return { version: WORKSPACE_STATE_VERSION };
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
async function writeWorkspaceOnboardingState(statePath, state) {
|
|
1583
|
+
await fs$1.mkdir(path.dirname(statePath), { recursive: true });
|
|
1584
|
+
const payload = `${JSON.stringify(state, null, 2)}\n`;
|
|
1585
|
+
const tmpPath = `${statePath}.tmp-${process.pid}-${Date.now().toString(36)}`;
|
|
1586
|
+
try {
|
|
1587
|
+
await fs$1.writeFile(tmpPath, payload, { encoding: "utf-8" });
|
|
1588
|
+
await fs$1.rename(tmpPath, statePath);
|
|
1589
|
+
} catch (err) {
|
|
1590
|
+
await fs$1.unlink(tmpPath).catch(() => {});
|
|
1591
|
+
throw err;
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
async function hasGitRepo(dir) {
|
|
1595
|
+
try {
|
|
1596
|
+
await fs$1.stat(path.join(dir, ".git"));
|
|
1597
|
+
return true;
|
|
1598
|
+
} catch {
|
|
1599
|
+
return false;
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
async function isGitAvailable() {
|
|
1603
|
+
if (gitAvailabilityPromise) return gitAvailabilityPromise;
|
|
1604
|
+
gitAvailabilityPromise = (async () => {
|
|
1605
|
+
try {
|
|
1606
|
+
return (await runCommandWithTimeout(["git", "--version"], { timeoutMs: 2e3 })).code === 0;
|
|
1607
|
+
} catch {
|
|
1608
|
+
return false;
|
|
1609
|
+
}
|
|
1610
|
+
})();
|
|
1611
|
+
return gitAvailabilityPromise;
|
|
1612
|
+
}
|
|
1613
|
+
async function ensureGitRepo(dir, isBrandNewWorkspace) {
|
|
1614
|
+
if (!isBrandNewWorkspace) return;
|
|
1615
|
+
if (await hasGitRepo(dir)) return;
|
|
1616
|
+
if (!await isGitAvailable()) return;
|
|
1617
|
+
try {
|
|
1618
|
+
await runCommandWithTimeout(["git", "init"], {
|
|
1619
|
+
cwd: dir,
|
|
1620
|
+
timeoutMs: 1e4
|
|
1621
|
+
});
|
|
1622
|
+
} catch {}
|
|
1623
|
+
}
|
|
1624
|
+
async function ensureAgentWorkspace(params) {
|
|
1625
|
+
const dir = resolveUserPath(params?.dir?.trim() ? params.dir.trim() : DEFAULT_AGENT_WORKSPACE_DIR);
|
|
1626
|
+
await fs$1.mkdir(dir, { recursive: true });
|
|
1627
|
+
if (!params?.ensureBootstrapFiles) return { dir };
|
|
1628
|
+
const agentsPath = path.join(dir, DEFAULT_AGENTS_FILENAME);
|
|
1629
|
+
const soulPath = path.join(dir, DEFAULT_SOUL_FILENAME);
|
|
1630
|
+
const toolsPath = path.join(dir, DEFAULT_TOOLS_FILENAME);
|
|
1631
|
+
const identityPath = path.join(dir, DEFAULT_IDENTITY_FILENAME);
|
|
1632
|
+
const userPath = path.join(dir, DEFAULT_USER_FILENAME);
|
|
1633
|
+
const heartbeatPath = path.join(dir, DEFAULT_HEARTBEAT_FILENAME);
|
|
1634
|
+
const bootstrapPath = path.join(dir, DEFAULT_BOOTSTRAP_FILENAME);
|
|
1635
|
+
const statePath = resolveWorkspaceStatePath(dir);
|
|
1636
|
+
const isBrandNewWorkspace = await (async () => {
|
|
1637
|
+
const templatePaths = [
|
|
1638
|
+
agentsPath,
|
|
1639
|
+
soulPath,
|
|
1640
|
+
toolsPath,
|
|
1641
|
+
identityPath,
|
|
1642
|
+
userPath,
|
|
1643
|
+
heartbeatPath
|
|
1644
|
+
];
|
|
1645
|
+
const userContentPaths = [
|
|
1646
|
+
path.join(dir, "memory"),
|
|
1647
|
+
path.join(dir, DEFAULT_MEMORY_FILENAME),
|
|
1648
|
+
path.join(dir, ".git")
|
|
1649
|
+
];
|
|
1650
|
+
const paths = [...templatePaths, ...userContentPaths];
|
|
1651
|
+
return (await Promise.all(paths.map(async (p) => {
|
|
1652
|
+
try {
|
|
1653
|
+
await fs$1.access(p);
|
|
1654
|
+
return true;
|
|
1655
|
+
} catch {
|
|
1656
|
+
return false;
|
|
1657
|
+
}
|
|
1658
|
+
}))).every((v) => !v);
|
|
1659
|
+
})();
|
|
1660
|
+
const agentsTemplate = await loadTemplate(DEFAULT_AGENTS_FILENAME);
|
|
1661
|
+
const soulTemplate = await loadTemplate(DEFAULT_SOUL_FILENAME);
|
|
1662
|
+
const toolsTemplate = await loadTemplate(DEFAULT_TOOLS_FILENAME);
|
|
1663
|
+
const identityTemplate = await loadTemplate(DEFAULT_IDENTITY_FILENAME);
|
|
1664
|
+
const userTemplate = await loadTemplate(DEFAULT_USER_FILENAME);
|
|
1665
|
+
const heartbeatTemplate = await loadTemplate(DEFAULT_HEARTBEAT_FILENAME);
|
|
1666
|
+
await writeFileIfMissing(agentsPath, agentsTemplate);
|
|
1667
|
+
await writeFileIfMissing(soulPath, soulTemplate);
|
|
1668
|
+
await writeFileIfMissing(toolsPath, toolsTemplate);
|
|
1669
|
+
await writeFileIfMissing(identityPath, identityTemplate);
|
|
1670
|
+
await writeFileIfMissing(userPath, userTemplate);
|
|
1671
|
+
await writeFileIfMissing(heartbeatPath, heartbeatTemplate);
|
|
1672
|
+
let state = await readWorkspaceOnboardingState(statePath);
|
|
1673
|
+
let stateDirty = false;
|
|
1674
|
+
const markState = (next) => {
|
|
1675
|
+
state = {
|
|
1676
|
+
...state,
|
|
1677
|
+
...next
|
|
1678
|
+
};
|
|
1679
|
+
stateDirty = true;
|
|
1680
|
+
};
|
|
1681
|
+
const nowIso = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
1682
|
+
let bootstrapExists = await fileExists(bootstrapPath);
|
|
1683
|
+
if (!state.bootstrapSeededAt && bootstrapExists) markState({ bootstrapSeededAt: nowIso() });
|
|
1684
|
+
if (!state.onboardingCompletedAt && state.bootstrapSeededAt && !bootstrapExists) markState({ onboardingCompletedAt: nowIso() });
|
|
1685
|
+
if (!state.bootstrapSeededAt && !state.onboardingCompletedAt && !bootstrapExists) {
|
|
1686
|
+
const [identityContent, userContent] = await Promise.all([fs$1.readFile(identityPath, "utf-8"), fs$1.readFile(userPath, "utf-8")]);
|
|
1687
|
+
const hasUserContent = await (async () => {
|
|
1688
|
+
const indicators = [
|
|
1689
|
+
path.join(dir, "memory"),
|
|
1690
|
+
path.join(dir, DEFAULT_MEMORY_FILENAME),
|
|
1691
|
+
path.join(dir, ".git")
|
|
1692
|
+
];
|
|
1693
|
+
for (const indicator of indicators) try {
|
|
1694
|
+
await fs$1.access(indicator);
|
|
1695
|
+
return true;
|
|
1696
|
+
} catch {}
|
|
1697
|
+
return false;
|
|
1698
|
+
})();
|
|
1699
|
+
if (identityContent !== identityTemplate || userContent !== userTemplate || hasUserContent) markState({ onboardingCompletedAt: nowIso() });
|
|
1700
|
+
else {
|
|
1701
|
+
if (!await writeFileIfMissing(bootstrapPath, await loadTemplate(DEFAULT_BOOTSTRAP_FILENAME))) bootstrapExists = await fileExists(bootstrapPath);
|
|
1702
|
+
else bootstrapExists = true;
|
|
1703
|
+
if (bootstrapExists && !state.bootstrapSeededAt) markState({ bootstrapSeededAt: nowIso() });
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
if (stateDirty) await writeWorkspaceOnboardingState(statePath, state);
|
|
1707
|
+
await ensureGitRepo(dir, isBrandNewWorkspace);
|
|
1708
|
+
return {
|
|
1709
|
+
dir,
|
|
1710
|
+
agentsPath,
|
|
1711
|
+
soulPath,
|
|
1712
|
+
toolsPath,
|
|
1713
|
+
identityPath,
|
|
1714
|
+
userPath,
|
|
1715
|
+
heartbeatPath,
|
|
1716
|
+
bootstrapPath
|
|
1717
|
+
};
|
|
1718
|
+
}
|
|
1719
|
+
async function resolveMemoryBootstrapEntries(resolvedDir) {
|
|
1720
|
+
const candidates = [DEFAULT_MEMORY_FILENAME, DEFAULT_MEMORY_ALT_FILENAME];
|
|
1721
|
+
const entries = [];
|
|
1722
|
+
for (const name of candidates) {
|
|
1723
|
+
const filePath = path.join(resolvedDir, name);
|
|
1724
|
+
try {
|
|
1725
|
+
await fs$1.access(filePath);
|
|
1726
|
+
entries.push({
|
|
1727
|
+
name,
|
|
1728
|
+
filePath
|
|
1729
|
+
});
|
|
1730
|
+
} catch {}
|
|
1731
|
+
}
|
|
1732
|
+
if (entries.length <= 1) return entries;
|
|
1733
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1734
|
+
const deduped = [];
|
|
1735
|
+
for (const entry of entries) {
|
|
1736
|
+
let key = entry.filePath;
|
|
1737
|
+
try {
|
|
1738
|
+
key = await fs$1.realpath(entry.filePath);
|
|
1739
|
+
} catch {}
|
|
1740
|
+
if (seen.has(key)) continue;
|
|
1741
|
+
seen.add(key);
|
|
1742
|
+
deduped.push(entry);
|
|
1743
|
+
}
|
|
1744
|
+
return deduped;
|
|
1745
|
+
}
|
|
1746
|
+
async function loadWorkspaceBootstrapFiles(dir) {
|
|
1747
|
+
const resolvedDir = resolveUserPath(dir);
|
|
1748
|
+
const entries = [
|
|
1749
|
+
{
|
|
1750
|
+
name: DEFAULT_AGENTS_FILENAME,
|
|
1751
|
+
filePath: path.join(resolvedDir, DEFAULT_AGENTS_FILENAME)
|
|
1752
|
+
},
|
|
1753
|
+
{
|
|
1754
|
+
name: DEFAULT_SOUL_FILENAME,
|
|
1755
|
+
filePath: path.join(resolvedDir, DEFAULT_SOUL_FILENAME)
|
|
1756
|
+
},
|
|
1757
|
+
{
|
|
1758
|
+
name: DEFAULT_TOOLS_FILENAME,
|
|
1759
|
+
filePath: path.join(resolvedDir, DEFAULT_TOOLS_FILENAME)
|
|
1760
|
+
},
|
|
1761
|
+
{
|
|
1762
|
+
name: DEFAULT_IDENTITY_FILENAME,
|
|
1763
|
+
filePath: path.join(resolvedDir, DEFAULT_IDENTITY_FILENAME)
|
|
1764
|
+
},
|
|
1765
|
+
{
|
|
1766
|
+
name: DEFAULT_USER_FILENAME,
|
|
1767
|
+
filePath: path.join(resolvedDir, DEFAULT_USER_FILENAME)
|
|
1768
|
+
},
|
|
1769
|
+
{
|
|
1770
|
+
name: DEFAULT_HEARTBEAT_FILENAME,
|
|
1771
|
+
filePath: path.join(resolvedDir, DEFAULT_HEARTBEAT_FILENAME)
|
|
1772
|
+
},
|
|
1773
|
+
{
|
|
1774
|
+
name: DEFAULT_BOOTSTRAP_FILENAME,
|
|
1775
|
+
filePath: path.join(resolvedDir, DEFAULT_BOOTSTRAP_FILENAME)
|
|
1776
|
+
}
|
|
1777
|
+
];
|
|
1778
|
+
entries.push(...await resolveMemoryBootstrapEntries(resolvedDir));
|
|
1779
|
+
const result = [];
|
|
1780
|
+
for (const entry of entries) {
|
|
1781
|
+
const loaded = await readWorkspaceFileWithGuards({
|
|
1782
|
+
filePath: entry.filePath,
|
|
1783
|
+
workspaceDir: resolvedDir
|
|
1784
|
+
});
|
|
1785
|
+
if (loaded.ok) result.push({
|
|
1786
|
+
name: entry.name,
|
|
1787
|
+
path: entry.filePath,
|
|
1788
|
+
content: loaded.content,
|
|
1789
|
+
missing: false
|
|
1790
|
+
});
|
|
1791
|
+
else result.push({
|
|
1792
|
+
name: entry.name,
|
|
1793
|
+
path: entry.filePath,
|
|
1794
|
+
missing: true
|
|
1795
|
+
});
|
|
1796
|
+
}
|
|
1797
|
+
return result;
|
|
1798
|
+
}
|
|
1799
|
+
const MINIMAL_BOOTSTRAP_ALLOWLIST = new Set([
|
|
1800
|
+
DEFAULT_AGENTS_FILENAME,
|
|
1801
|
+
DEFAULT_TOOLS_FILENAME,
|
|
1802
|
+
DEFAULT_SOUL_FILENAME,
|
|
1803
|
+
DEFAULT_IDENTITY_FILENAME,
|
|
1804
|
+
DEFAULT_USER_FILENAME
|
|
1805
|
+
]);
|
|
1806
|
+
function filterBootstrapFilesForSession(files, sessionKey) {
|
|
1807
|
+
if (!sessionKey || !isSubagentSessionKey(sessionKey) && !isCronSessionKey(sessionKey)) return files;
|
|
1808
|
+
return files.filter((file) => MINIMAL_BOOTSTRAP_ALLOWLIST.has(file.name));
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
//#endregion
|
|
1812
|
+
//#region src/agents/agent-scope.ts
|
|
1813
|
+
const log = createSubsystemLogger("agent-scope");
|
|
1814
|
+
/** Strip null bytes from paths to prevent ENOTDIR errors. */
|
|
1815
|
+
function stripNullBytes(s) {
|
|
1816
|
+
return s.replace(/\0/g, "");
|
|
1817
|
+
}
|
|
1818
|
+
let defaultAgentWarned = false;
|
|
1819
|
+
function listAgentEntries(cfg) {
|
|
1820
|
+
const list = cfg.agents?.list;
|
|
1821
|
+
if (!Array.isArray(list)) return [];
|
|
1822
|
+
return list.filter((entry) => Boolean(entry && typeof entry === "object"));
|
|
1823
|
+
}
|
|
1824
|
+
function listAgentIds(cfg) {
|
|
1825
|
+
const agents = listAgentEntries(cfg);
|
|
1826
|
+
if (agents.length === 0) return [DEFAULT_AGENT_ID];
|
|
1827
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1828
|
+
const ids = [];
|
|
1829
|
+
for (const entry of agents) {
|
|
1830
|
+
const id = normalizeAgentId(entry?.id);
|
|
1831
|
+
if (seen.has(id)) continue;
|
|
1832
|
+
seen.add(id);
|
|
1833
|
+
ids.push(id);
|
|
1834
|
+
}
|
|
1835
|
+
return ids.length > 0 ? ids : [DEFAULT_AGENT_ID];
|
|
1836
|
+
}
|
|
1837
|
+
function resolveDefaultAgentId(cfg) {
|
|
1838
|
+
const agents = listAgentEntries(cfg);
|
|
1839
|
+
if (agents.length === 0) return DEFAULT_AGENT_ID;
|
|
1840
|
+
const defaults = agents.filter((agent) => agent?.default);
|
|
1841
|
+
if (defaults.length > 1 && !defaultAgentWarned) {
|
|
1842
|
+
defaultAgentWarned = true;
|
|
1843
|
+
log.warn("Multiple agents marked default=true; using the first entry as default.");
|
|
1844
|
+
}
|
|
1845
|
+
const chosen = (defaults[0] ?? agents[0])?.id?.trim();
|
|
1846
|
+
return normalizeAgentId(chosen || DEFAULT_AGENT_ID);
|
|
1847
|
+
}
|
|
1848
|
+
function resolveSessionAgentIds(params) {
|
|
1849
|
+
const defaultAgentId = resolveDefaultAgentId(params.config ?? {});
|
|
1850
|
+
const explicitAgentIdRaw = typeof params.agentId === "string" ? params.agentId.trim().toLowerCase() : "";
|
|
1851
|
+
const explicitAgentId = explicitAgentIdRaw ? normalizeAgentId(explicitAgentIdRaw) : null;
|
|
1852
|
+
const sessionKey = params.sessionKey?.trim();
|
|
1853
|
+
const normalizedSessionKey = sessionKey ? sessionKey.toLowerCase() : void 0;
|
|
1854
|
+
const parsed = normalizedSessionKey ? parseAgentSessionKey(normalizedSessionKey) : null;
|
|
1855
|
+
return {
|
|
1856
|
+
defaultAgentId,
|
|
1857
|
+
sessionAgentId: explicitAgentId ?? (parsed?.agentId ? normalizeAgentId(parsed.agentId) : defaultAgentId)
|
|
1858
|
+
};
|
|
1859
|
+
}
|
|
1860
|
+
function resolveSessionAgentId(params) {
|
|
1861
|
+
return resolveSessionAgentIds(params).sessionAgentId;
|
|
1862
|
+
}
|
|
1863
|
+
function resolveAgentEntry(cfg, agentId) {
|
|
1864
|
+
const id = normalizeAgentId(agentId);
|
|
1865
|
+
return listAgentEntries(cfg).find((entry) => normalizeAgentId(entry.id) === id);
|
|
1866
|
+
}
|
|
1867
|
+
function resolveAgentConfig(cfg, agentId) {
|
|
1868
|
+
const entry = resolveAgentEntry(cfg, normalizeAgentId(agentId));
|
|
1869
|
+
if (!entry) return;
|
|
1870
|
+
return {
|
|
1871
|
+
name: typeof entry.name === "string" ? entry.name : void 0,
|
|
1872
|
+
workspace: typeof entry.workspace === "string" ? entry.workspace : void 0,
|
|
1873
|
+
agentDir: typeof entry.agentDir === "string" ? entry.agentDir : void 0,
|
|
1874
|
+
model: typeof entry.model === "string" || entry.model && typeof entry.model === "object" ? entry.model : void 0,
|
|
1875
|
+
skills: Array.isArray(entry.skills) ? entry.skills : void 0,
|
|
1876
|
+
memorySearch: entry.memorySearch,
|
|
1877
|
+
humanDelay: entry.humanDelay,
|
|
1878
|
+
heartbeat: entry.heartbeat,
|
|
1879
|
+
identity: entry.identity,
|
|
1880
|
+
groupChat: entry.groupChat,
|
|
1881
|
+
subagents: typeof entry.subagents === "object" && entry.subagents ? entry.subagents : void 0,
|
|
1882
|
+
sandbox: entry.sandbox,
|
|
1883
|
+
tools: entry.tools
|
|
1884
|
+
};
|
|
1885
|
+
}
|
|
1886
|
+
function resolveAgentSkillsFilter(cfg, agentId) {
|
|
1887
|
+
return normalizeSkillFilter(resolveAgentConfig(cfg, agentId)?.skills);
|
|
1888
|
+
}
|
|
1889
|
+
function resolveModelPrimary(raw) {
|
|
1890
|
+
if (typeof raw === "string") return raw.trim() || void 0;
|
|
1891
|
+
if (!raw || typeof raw !== "object") return;
|
|
1892
|
+
const primary = raw.primary;
|
|
1893
|
+
if (typeof primary !== "string") return;
|
|
1894
|
+
return primary.trim() || void 0;
|
|
1895
|
+
}
|
|
1896
|
+
function resolveAgentExplicitModelPrimary(cfg, agentId) {
|
|
1897
|
+
const raw = resolveAgentConfig(cfg, agentId)?.model;
|
|
1898
|
+
return resolveModelPrimary(raw);
|
|
1899
|
+
}
|
|
1900
|
+
function resolveAgentEffectiveModelPrimary(cfg, agentId) {
|
|
1901
|
+
return resolveAgentExplicitModelPrimary(cfg, agentId) ?? resolveModelPrimary(cfg.agents?.defaults?.model);
|
|
1902
|
+
}
|
|
1903
|
+
function resolveAgentModelFallbacksOverride(cfg, agentId) {
|
|
1904
|
+
const raw = resolveAgentConfig(cfg, agentId)?.model;
|
|
1905
|
+
if (!raw || typeof raw === "string") return;
|
|
1906
|
+
if (!Object.hasOwn(raw, "fallbacks")) return;
|
|
1907
|
+
return Array.isArray(raw.fallbacks) ? raw.fallbacks : void 0;
|
|
1908
|
+
}
|
|
1909
|
+
function resolveFallbackAgentId(params) {
|
|
1910
|
+
const explicitAgentId = typeof params.agentId === "string" ? params.agentId.trim() : "";
|
|
1911
|
+
if (explicitAgentId) return normalizeAgentId(explicitAgentId);
|
|
1912
|
+
return resolveAgentIdFromSessionKey(params.sessionKey);
|
|
1913
|
+
}
|
|
1914
|
+
function resolveRunModelFallbacksOverride(params) {
|
|
1915
|
+
if (!params.cfg) return;
|
|
1916
|
+
return resolveAgentModelFallbacksOverride(params.cfg, resolveFallbackAgentId({
|
|
1917
|
+
agentId: params.agentId,
|
|
1918
|
+
sessionKey: params.sessionKey
|
|
1919
|
+
}));
|
|
1920
|
+
}
|
|
1921
|
+
function hasConfiguredModelFallbacks(params) {
|
|
1922
|
+
const fallbacksOverride = resolveRunModelFallbacksOverride(params);
|
|
1923
|
+
const defaultFallbacks = resolveAgentModelFallbackValues(params.cfg?.agents?.defaults?.model);
|
|
1924
|
+
return (fallbacksOverride ?? defaultFallbacks).length > 0;
|
|
1925
|
+
}
|
|
1926
|
+
function resolveEffectiveModelFallbacks(params) {
|
|
1927
|
+
const agentFallbacksOverride = resolveAgentModelFallbacksOverride(params.cfg, params.agentId);
|
|
1928
|
+
if (!params.hasSessionModelOverride) return agentFallbacksOverride;
|
|
1929
|
+
const defaultFallbacks = resolveAgentModelFallbackValues(params.cfg.agents?.defaults?.model);
|
|
1930
|
+
return agentFallbacksOverride ?? defaultFallbacks;
|
|
1931
|
+
}
|
|
1932
|
+
function resolveAgentWorkspaceDir(cfg, agentId) {
|
|
1933
|
+
const id = normalizeAgentId(agentId);
|
|
1934
|
+
const configured = resolveAgentConfig(cfg, id)?.workspace?.trim();
|
|
1935
|
+
if (configured) return stripNullBytes(resolveUserPath(configured));
|
|
1936
|
+
if (id === resolveDefaultAgentId(cfg)) {
|
|
1937
|
+
const fallback = cfg.agents?.defaults?.workspace?.trim();
|
|
1938
|
+
if (fallback) return stripNullBytes(resolveUserPath(fallback));
|
|
1939
|
+
return stripNullBytes(resolveDefaultAgentWorkspaceDir(process.env));
|
|
1940
|
+
}
|
|
1941
|
+
const stateDir = resolveStateDir(process.env);
|
|
1942
|
+
return stripNullBytes(path.join(stateDir, `workspace-${id}`));
|
|
1943
|
+
}
|
|
1944
|
+
function resolveAgentDir(cfg, agentId) {
|
|
1945
|
+
const id = normalizeAgentId(agentId);
|
|
1946
|
+
const configured = resolveAgentConfig(cfg, id)?.agentDir?.trim();
|
|
1947
|
+
if (configured) return resolveUserPath(configured);
|
|
1948
|
+
const root = resolveStateDir(process.env);
|
|
1949
|
+
return path.join(root, "agents", id, "agent");
|
|
1950
|
+
}
|
|
1951
|
+
|
|
1952
|
+
//#endregion
|
|
1953
|
+
//#region src/utils/run-with-concurrency.ts
|
|
1954
|
+
async function runTasksWithConcurrency(params) {
|
|
1955
|
+
const { tasks, limit, onTaskError } = params;
|
|
1956
|
+
const errorMode = params.errorMode ?? "continue";
|
|
1957
|
+
if (tasks.length === 0) return {
|
|
1958
|
+
results: [],
|
|
1959
|
+
firstError: void 0,
|
|
1960
|
+
hasError: false
|
|
1961
|
+
};
|
|
1962
|
+
const resolvedLimit = Math.max(1, Math.min(limit, tasks.length));
|
|
1963
|
+
const results = Array.from({ length: tasks.length });
|
|
1964
|
+
let next = 0;
|
|
1965
|
+
let firstError = void 0;
|
|
1966
|
+
let hasError = false;
|
|
1967
|
+
const workers = Array.from({ length: resolvedLimit }, async () => {
|
|
1968
|
+
while (true) {
|
|
1969
|
+
if (errorMode === "stop" && hasError) return;
|
|
1970
|
+
const index = next;
|
|
1971
|
+
next += 1;
|
|
1972
|
+
if (index >= tasks.length) return;
|
|
1973
|
+
try {
|
|
1974
|
+
results[index] = await tasks[index]();
|
|
1975
|
+
} catch (error) {
|
|
1976
|
+
if (!hasError) {
|
|
1977
|
+
firstError = error;
|
|
1978
|
+
hasError = true;
|
|
1979
|
+
}
|
|
1980
|
+
onTaskError?.(error, index);
|
|
1981
|
+
if (errorMode === "stop") return;
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
});
|
|
1985
|
+
await Promise.allSettled(workers);
|
|
1986
|
+
return {
|
|
1987
|
+
results,
|
|
1988
|
+
firstError,
|
|
1989
|
+
hasError
|
|
1990
|
+
};
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1993
|
+
//#endregion
|
|
1994
|
+
export { normalizeAgentId as $, canUseBoundaryFileOpen as A, isSymlinkOpenError as B, filterBootstrapFilesForSession as C, runCommandWithTimeout as D, resolveSquidClawPackageRootSync as E, resolveBoundaryPath as F, toAgentModelListLike as G, normalizeSkillFilter as H, resolvePathViaExistingAncestorSync as I, buildAgentMainSessionKey as J, DEFAULT_AGENT_ID as K, hasNodeErrorCode as L, openBoundaryFileSync as M, sameFileIdentity$1 as N, runExec as O, BOUNDARY_PATH_ALIAS_POLICIES as P, isValidAgentId as Q, isNotFoundPathError as R, ensureAgentWorkspace as S, resolveSquidClawPackageRoot as T, resolveAgentModelFallbackValues as U, normalizeWindowsPathForComparison as V, resolveAgentModelPrimaryValue as W, buildGroupHistoryKey as X, buildAgentPeerSessionKey as Y, classifySessionKeyShape as Z, DEFAULT_HEARTBEAT_FILENAME as _, resolveAgentDir as a, DEFAULT_ACCOUNT_ID as at, DEFAULT_TOOLS_FILENAME as b, resolveAgentWorkspaceDir as c, isBlockedObjectKey as ct, resolveRunModelFallbacksOverride as d, isAcpSessionKey as dt, normalizeMainKey as et, resolveSessionAgentId as f, isCronSessionKey as ft, DEFAULT_BOOTSTRAP_FILENAME as g, DEFAULT_AGENT_WORKSPACE_DIR as h, resolveThreadParentSessionKey as ht, resolveAgentConfig as i, scopedHeartbeatWakeOptions as it, openBoundaryFile as j, spawnWithFallback as k, resolveDefaultAgentId as l, deriveSessionChatType as lt, DEFAULT_AGENTS_FILENAME as m, parseAgentSessionKey as mt, hasConfiguredModelFallbacks as n, resolveThreadSessionKeys as nt, resolveAgentEffectiveModelPrimary as o, normalizeAccountId as ot, resolveSessionAgentIds as p, isSubagentSessionKey as pt, DEFAULT_MAIN_KEY as q, listAgentIds as r, sanitizeAgentId as rt, resolveAgentSkillsFilter as s, normalizeOptionalAccountId as st, runTasksWithConcurrency as t, resolveAgentIdFromSessionKey as tt, resolveEffectiveModelFallbacks as u, getSubagentDepth as ut, DEFAULT_IDENTITY_FILENAME as v, loadWorkspaceBootstrapFiles as w, DEFAULT_USER_FILENAME as x, DEFAULT_SOUL_FILENAME as y, isPathInside as z };
|