gerege-cli 0.26.5 → 0.26.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/chunks/{MaxSizedBox-VMVLMS4X.js → MaxSizedBox-LSNOJEKM.js} +1 -1
- package/chunks/{StandaloneSessionPicker-UNORCVYY.js → StandaloneSessionPicker-KSYGPMEV.js} +1 -1
- package/chunks/{acp-subagent-executor-623ZUTJT.js → acp-subagent-executor-NSW2MFUI.js} +1 -1
- package/chunks/{acpAgent-MTTDTK2C.js → acpAgent-3DTOHTDM.js} +3 -3
- package/chunks/{advisor-ANUGICJ5.js → advisor-7JGQPS7X.js} +1 -1
- package/chunks/{agent-GNCQDICJ.js → agent-PNKQJGDO.js} +1 -1
- package/chunks/{agent-headless-OPUXAXQM.js → agent-headless-7D33X7QQ.js} +1 -1
- package/chunks/{agent-host-client-K6GRPTFD.js → agent-host-client-3R2MAUVE.js} +1 -1
- package/chunks/{agent-host-connections-MF3YBZU2.js → agent-host-connections-2D7DECAE.js} +1 -1
- package/chunks/{anthropicContentGenerator-OK4PFE5Y.js → anthropicContentGenerator-MGTJJGEQ.js} +1 -1
- package/chunks/{autofix-pr-MABTGEHZ.js → autofix-pr-OIHHZSPQ.js} +1 -1
- package/chunks/{batch-V2NJT3M5.js → batch-6UDAMPAA.js} +1 -1
- package/chunks/{bridge-BJQ627CX.js → bridge-QXVXPNJ6.js} +1 -1
- package/chunks/{channel-settings-store-4JMCI4UR.js → channel-settings-store-P4W4R5SJ.js} +1 -1
- package/chunks/{chunk-ZN57TOVA.js → chunk-2DU2WMTL.js} +1 -1
- package/chunks/{chunk-ISGF3BVD.js → chunk-2J2BQ3PL.js} +2 -2
- package/chunks/{chunk-TQTIEK2W.js → chunk-2LMSDH6P.js} +1 -1
- package/chunks/{chunk-EIILQ6KT.js → chunk-3EZ5GCUT.js} +1 -1
- package/chunks/{chunk-UY2ET2AL.js → chunk-3ICJI5KW.js} +1 -1
- package/chunks/{chunk-VDRE7U3P.js → chunk-4A663FE6.js} +5 -5
- package/chunks/{chunk-2IGE2K5V.js → chunk-4AKTP4MM.js} +1 -1
- package/chunks/{chunk-NO26JN24.js → chunk-4LC4INFI.js} +1 -1
- package/chunks/{chunk-CKZRJP4F.js → chunk-4ME3BUJK.js} +1 -1
- package/chunks/{chunk-3XBJYUWP.js → chunk-4QOVM2LL.js} +1 -1
- package/chunks/{chunk-ZYTG6R7S.js → chunk-4VR4DUUD.js} +1 -1
- package/chunks/{chunk-DE53B2R7.js → chunk-4W27Z3OL.js} +1 -1
- package/chunks/{chunk-QOYRDEXR.js → chunk-53IB4U4E.js} +1 -1
- package/chunks/{chunk-CCOUFBOY.js → chunk-5R2JIZID.js} +1 -1
- package/chunks/{chunk-MPAR4JBP.js → chunk-5TWAP4OG.js} +1 -1
- package/chunks/{chunk-3NQESE5K.js → chunk-6JAXAFX7.js} +1 -1
- package/chunks/{chunk-POA4NX4N.js → chunk-6WV5RKYB.js} +1 -1
- package/chunks/{chunk-KN27BFXM.js → chunk-6YFNUVJR.js} +1 -1
- package/chunks/{chunk-2X3UF2CF.js → chunk-7HFFTOAD.js} +1 -1
- package/chunks/{chunk-KDYUZBZC.js → chunk-ATTJQLQV.js} +1 -1
- package/chunks/{chunk-USJFJZ23.js → chunk-BGELKSQ4.js} +1 -1
- package/chunks/{chunk-X4BFEDWU.js → chunk-BIPPD7W6.js} +1 -1
- package/chunks/{chunk-DEMXCA3K.js → chunk-BVV7UXES.js} +1 -1
- package/chunks/{chunk-2VCDJ6UF.js → chunk-BY46PCWY.js} +1 -1
- package/chunks/{chunk-CXGGC4NO.js → chunk-CDKBM72V.js} +1 -1
- package/chunks/{chunk-5WLKN3GD.js → chunk-CK3OKTTL.js} +1 -1
- package/chunks/{chunk-FHBGTZ4K.js → chunk-DEJ47KJE.js} +1 -1
- package/chunks/{chunk-DTTC4ZKY.js → chunk-DQQN2HOP.js} +1 -1
- package/chunks/{chunk-PN62SUYK.js → chunk-DTX2OVQW.js} +1 -1
- package/chunks/{chunk-IBYFSHBB.js → chunk-DVUKYOCJ.js} +1 -1
- package/chunks/{chunk-Q5E5SOY2.js → chunk-E3KWSRJN.js} +1 -1
- package/chunks/{chunk-IDUGQMTP.js → chunk-EEPNACXJ.js} +1 -1
- package/chunks/{chunk-E5YRAQXM.js → chunk-EKRUF347.js} +1 -1
- package/chunks/{chunk-HSYBIGMS.js → chunk-F5SLLEJY.js} +1 -1
- package/chunks/{chunk-5ZQWQ3RK.js → chunk-F7622ZRQ.js} +1 -1
- package/chunks/{chunk-KKBOCRPF.js → chunk-FKUDVIME.js} +1 -1
- package/chunks/{chunk-62NLMVVT.js → chunk-FRVXSKL4.js} +1 -1
- package/chunks/{chunk-FIM7MM25.js → chunk-FTF2NFLB.js} +1 -1
- package/chunks/{chunk-OHXQYU6S.js → chunk-G4MWPXNY.js} +1 -1
- package/chunks/{chunk-SELRSZFK.js → chunk-GA35LMSX.js} +1 -1
- package/chunks/{chunk-SMYBY353.js → chunk-H34KVVI4.js} +1 -1
- package/chunks/{chunk-NGOIJH7K.js → chunk-H5EXNXGW.js} +1 -1
- package/chunks/{chunk-UBXLQ6TP.js → chunk-HJLRKM3W.js} +1 -1
- package/chunks/{chunk-CAPG7UVH.js → chunk-HVP4UF2Q.js} +1 -1
- package/chunks/{chunk-H57IX45A.js → chunk-HXTYFGSQ.js} +1 -1
- package/chunks/{chunk-55RVKT4O.js → chunk-IIHUDJX7.js} +1 -1
- package/chunks/{chunk-XFLLE2J3.js → chunk-IQMKQKKD.js} +2 -2
- package/chunks/{chunk-SQQORHMS.js → chunk-ISQMHOCC.js} +1 -1
- package/chunks/{chunk-YLAI26PX.js → chunk-IY7M5HKF.js} +1 -1
- package/chunks/{chunk-FDUXQAGW.js → chunk-IZXHCHJD.js} +1 -1
- package/chunks/{chunk-ZOBX6C7E.js → chunk-JHC22BZH.js} +1 -1
- package/chunks/{chunk-26ISBUM7.js → chunk-K7GN4CMV.js} +6 -6
- package/chunks/{chunk-4GC5HJZO.js → chunk-L7LO3YRT.js} +1 -1
- package/chunks/{chunk-ZSVSRF4C.js → chunk-LT3J74BZ.js} +1 -1
- package/chunks/{chunk-2PY7R7GG.js → chunk-LY4XTBL4.js} +1 -1
- package/chunks/{chunk-7IERHQ63.js → chunk-LYFRGP42.js} +1 -1
- package/chunks/{chunk-FPZPCZFS.js → chunk-MDCA4I63.js} +1 -1
- package/chunks/{chunk-2LLPGSUK.js → chunk-MS2XCBPP.js} +1 -1
- package/chunks/{chunk-3Y6LSWEW.js → chunk-MXZXQUVP.js} +1 -1
- package/chunks/{chunk-IH2PFVWO.js → chunk-N4ZQC5HB.js} +1 -1
- package/chunks/{chunk-MTW3A3KT.js → chunk-N6EFYQ7M.js} +1 -1
- package/chunks/{chunk-AQWHCRKY.js → chunk-NHPKD7LY.js} +1 -1
- package/chunks/{chunk-ABJGFEES.js → chunk-NO7VTKRL.js} +1 -1
- package/chunks/{chunk-CNFA5UUM.js → chunk-NPAENNRO.js} +1 -1
- package/chunks/{chunk-IA4K4PGK.js → chunk-NYBYDW6R.js} +1 -1
- package/chunks/{chunk-FNB3DPQZ.js → chunk-O3TUZQP4.js} +1 -1
- package/chunks/{chunk-RVJJFDF3.js → chunk-OZFZBGZG.js} +1 -1
- package/chunks/{chunk-B6D3KTUK.js → chunk-P2MZZMCS.js} +1 -1
- package/chunks/{chunk-GSOBASYW.js → chunk-PMBI46K4.js} +1 -1
- package/chunks/{chunk-WI4UMN3Q.js → chunk-Q5RRVBTY.js} +1 -1
- package/chunks/{chunk-5UZT4SXG.js → chunk-QHYSRPQR.js} +1 -1
- package/chunks/{chunk-2NOMOJWE.js → chunk-QONPET6Y.js} +2 -2
- package/chunks/{chunk-MOPJNP5I.js → chunk-QSPXKBUX.js} +1 -1
- package/chunks/{chunk-C56YJIEI.js → chunk-QTKPC24L.js} +1 -1
- package/chunks/{chunk-6X73W4TL.js → chunk-QTVSPQZQ.js} +1 -1
- package/chunks/{chunk-ADZI3OFT.js → chunk-QVHDM6N7.js} +1 -1
- package/chunks/{chunk-NVSKOSFG.js → chunk-RT6J7PV4.js} +1 -1
- package/chunks/{chunk-7MTBINFX.js → chunk-RULGA7WE.js} +2 -2
- package/chunks/{chunk-AMTFJVDD.js → chunk-SAVYMUU3.js} +1 -1
- package/chunks/{chunk-Z5XENA4A.js → chunk-T3CQ72HC.js} +8 -7
- package/chunks/{chunk-OPYGNTZP.js → chunk-U5YOAOU3.js} +1 -1
- package/chunks/{chunk-HFV6CQWE.js → chunk-ULLW2AYD.js} +1 -1
- package/chunks/{chunk-KGJ47CI5.js → chunk-UM5KBBYP.js} +1 -1
- package/chunks/{chunk-F26LTWDZ.js → chunk-UVMLWDRU.js} +1 -1
- package/chunks/{chunk-BRPJ5EHA.js → chunk-VK7LOUOJ.js} +1 -1
- package/chunks/{chunk-4EQWJTJR.js → chunk-VUNHJ74J.js} +1 -1
- package/chunks/{chunk-WB34KMOT.js → chunk-W2CV36HT.js} +1 -1
- package/chunks/{chunk-ADTFKUH2.js → chunk-WCI33URB.js} +1 -1
- package/chunks/{chunk-4TYTJQWR.js → chunk-WEPC42YR.js} +1 -1
- package/chunks/{chunk-YGHM5CDT.js → chunk-WF7Q3ZSQ.js} +1 -1
- package/chunks/{chunk-UJYOILZR.js → chunk-WK666FGZ.js} +3 -3
- package/chunks/{chunk-3WQPUP5U.js → chunk-WMLYHZZX.js} +1 -1
- package/chunks/{chunk-OCBJCZC2.js → chunk-WSI4G7XC.js} +1 -1
- package/chunks/{chunk-Q6QS5JTK.js → chunk-WXK7Z45R.js} +1 -1
- package/chunks/{chunk-6NI33TVK.js → chunk-X2TY7VTY.js} +1 -1
- package/chunks/{chunk-BBOJUFMW.js → chunk-YWK3E4WJ.js} +1 -1
- package/chunks/{chunk-FNXO5KWB.js → chunk-YY4GWNTU.js} +2 -2
- package/chunks/{chunk-FLJLUMQF.js → chunk-ZFOEVHWG.js} +1 -1
- package/chunks/{codex-subagent-executor-EK3A2WBH.js → codex-subagent-executor-GPTKVP7H.js} +1 -1
- package/chunks/{config-utils-DLOK7OLM.js → config-utils-6B5FHBSF.js} +1 -1
- package/chunks/{contextCommand-AVCUCHQC.js → contextCommand-FGRDE3GA.js} +1 -1
- package/chunks/{core-runtime-QSS4ZTG6.js → core-runtime-OFEHSKDB.js} +1 -1
- package/chunks/{create-sub-session-PNF7QDKC.js → create-sub-session-D2KEWVHQ.js} +1 -1
- package/chunks/{cron-create-C6JOFIU4.js → cron-create-RFGGKTL7.js} +1 -1
- package/chunks/{daemon-git-worktree-guard-5XZAZ7D2.js → daemon-git-worktree-guard-AV752IOZ.js} +1 -1
- package/chunks/{daemon-status-provider-MRNELSNJ.js → daemon-status-provider-GHQBRDMC.js} +1 -1
- package/chunks/{daemon-trust-policy-26CMW3WY.js → daemon-trust-policy-24ENJNTQ.js} +1 -1
- package/chunks/{daemon-trust-policy-monitor-3DWO6NQY.js → daemon-trust-policy-monitor-NMSQAGWV.js} +1 -1
- package/chunks/{deferred-core-runtime-DEC3N46T.js → deferred-core-runtime-5BAMFFOI.js} +1 -1
- package/chunks/{edit-3HMQPCHN.js → edit-XCECLEH3.js} +1 -1
- package/chunks/{enterPlanMode-QHJF4JXZ.js → enterPlanMode-SEN2PMRM.js} +1 -1
- package/chunks/{environment-NGIBJWOT.js → environment-CCPQJYKS.js} +1 -1
- package/chunks/{errors-MSTGCVGJ.js → errors-Y6HHUTGK.js} +1 -1
- package/chunks/{execution-tool-VR4TGOI4.js → execution-tool-HADWGMIG.js} +1 -1
- package/chunks/{execution-worker-EJH7HIE2.js → execution-worker-GZS7WOQL.js} +1 -1
- package/chunks/{exitPlanMode-P25OHQJ6.js → exitPlanMode-76B5HDLT.js} +1 -1
- package/chunks/{fast-path-II433ZDP.js → fast-path-OEV7LQYV.js} +1 -1
- package/chunks/{glob-4Q6DCT3F.js → glob-NLWCQRMS.js} +1 -1
- package/chunks/{goal-tools-FFMAJW6V.js → goal-tools-43XV33BT.js} +1 -1
- package/chunks/{handleAutoUpdate-QNM26NZK.js → handleAutoUpdate-JDQWGSSP.js} +1 -1
- package/chunks/{i18n-L5URVOBB.js → i18n-JW6BVEGF.js} +1 -1
- package/chunks/{initializer-NQ2NECYP.js → initializer-UT6JLZ3O.js} +1 -1
- package/chunks/{installationInfo-BCTXASUM.js → installationInfo-LKWDV3S2.js} +1 -1
- package/chunks/{interactive-mod-session-PPTBI37E.js → interactive-mod-session-2KWKYVPC.js} +1 -1
- package/chunks/{list-7TE5TUZJ.js → list-BKINK3S2.js} +1 -1
- package/chunks/{llm-BWWKUBBZ.js → llm-3RWXAVM2.js} +4 -4
- package/chunks/{llm-content-generator-QOTGPBYC.js → llm-content-generator-MDRBSH73.js} +1 -1
- package/chunks/{loadedSettingsAdapter-THAGI5M2.js → loadedSettingsAdapter-WWJUKWUN.js} +1 -1
- package/chunks/{local-7BTAGV4J.js → local-TT4FLCTR.js} +1 -1
- package/chunks/{local-execution-environment-S3OR4KSC.js → local-execution-environment-OBA6VWYL.js} +1 -1
- package/chunks/{loggingContentGenerator-AXJ5E5RS.js → loggingContentGenerator-CK7IKYQH.js} +1 -1
- package/chunks/{loop-wakeup-AJTLMLRX.js → loop-wakeup-4MSRX3DY.js} +1 -1
- package/chunks/{manage-memory-JHTUVMDJ.js → manage-memory-PX5PZJKZ.js} +1 -1
- package/chunks/{managed-execution-engine-U6GNJ4U4.js → managed-execution-engine-WMAUR3ZK.js} +1 -1
- package/chunks/{managed-local-serve-P4ZXVRBU.js → managed-local-serve-X7REHGB4.js} +1 -1
- package/chunks/{managed-npm-update-UDUILNR5.js → managed-npm-update-6HUVAJH7.js} +1 -1
- package/chunks/{managed-runtime-attestation-worker-P34ZBNRG.js → managed-runtime-attestation-worker-F4AT53M5.js} +1 -1
- package/chunks/{managed-runtime-bootstrap-CLMYNPH5.js → managed-runtime-bootstrap-3BP5JRJX.js} +1 -1
- package/chunks/{managed-runtime-session-worker-7H7AZJBV.js → managed-runtime-session-worker-2PO7J5UK.js} +1 -1
- package/chunks/{managed-runtime-ssh-worker-5KEMC7FD.js → managed-runtime-ssh-worker-4N7EMRSV.js} +1 -1
- package/chunks/{managed-session-authority-CFUZ45HT.js → managed-session-authority-MYOYTUM2.js} +1 -1
- package/chunks/{mcp-YMG4RVMC.js → mcp-5OTEMZ7P.js} +1 -1
- package/chunks/{memory-7STURUXK.js → memory-TNW7RSAV.js} +1 -1
- package/chunks/mn-JMS6SWTO.js +8 -0
- package/chunks/{model-call-collection-WBWTO3EG.js → model-call-collection-KNTWFZQS.js} +1 -1
- package/chunks/{model-configuration-6KCZZSZD.js → model-configuration-U5C5P5UQ.js} +1 -1
- package/chunks/{modelConfigUtils-Z2EKFSPN.js → modelConfigUtils-R4KFI2WK.js} +1 -1
- package/chunks/{monitor-U5E33JO6.js → monitor-RD2PFK42.js} +1 -1
- package/chunks/{nonInteractiveCli-BVCL5I5R.js → nonInteractiveCli-QQ72HZSH.js} +1 -1
- package/chunks/{nonInteractiveToolExecutor-B4EUOMYF.js → nonInteractiveToolExecutor-QPQYR6IS.js} +1 -1
- package/chunks/{notebook-edit-MXKD5J2C.js → notebook-edit-YLRN3UZT.js} +1 -1
- package/chunks/{omni-I5YECZBW.js → omni-CUJ52EW5.js} +1 -1
- package/chunks/{openaiContentGenerator-Q5SINFJJ.js → openaiContentGenerator-6B5MAU54.js} +1 -1
- package/chunks/{openaiResponsesContentGenerator-R3XCZLZY.js → openaiResponsesContentGenerator-I245I3R7.js} +1 -1
- package/chunks/{pidfile-UOGUNUTK.js → pidfile-P2HIGAUA.js} +1 -1
- package/chunks/{processUtils-QGQGZHBA.js → processUtils-JSKN5UGS.js} +1 -1
- package/chunks/{prompt-terminal-ledger-L57JMVSR.js → prompt-terminal-ledger-F5TSXVGU.js} +1 -1
- package/chunks/{qwenContentGenerator-UKZ237LC.js → qwenContentGenerator-IEDZONWG.js} +1 -1
- package/chunks/{reactive-degrade-3OM3HWVA.js → reactive-degrade-FYZBJCF6.js} +1 -1
- package/chunks/{read-file-63ZLWMOW.js → read-file-VNZNSD6X.js} +1 -1
- package/chunks/{resumeHistoryUtils-R5YQS4YQ.js → resumeHistoryUtils-IDPE6N2N.js} +1 -1
- package/chunks/{review-AT6OWVDO.js → review-TBJRZWTD.js} +1 -1
- package/chunks/{ripGrep-7KBZGTPV.js → ripGrep-4W5B5FOE.js} +1 -1
- package/chunks/{run-qwen-serve-CLBG7W6F.js → run-qwen-serve-44X262G5.js} +1 -1
- package/chunks/{runtime-R3QIGB7U.js → runtime-6H6LKD73.js} +1 -1
- package/chunks/{sandboxConfig-PM3ZRQYV.js → sandboxConfig-SQXDRGVN.js} +1 -1
- package/chunks/{scheduled-tasks-PUMNN5XV.js → scheduled-tasks-62IZKHJG.js} +1 -1
- package/chunks/{scheduler-KTPM226B.js → scheduler-QUCXJYRL.js} +1 -1
- package/chunks/{search-memory-7I5MGDNV.js → search-memory-TC2Z34QN.js} +1 -1
- package/chunks/{send-message-J526AEBI.js → send-message-TFZX7KI7.js} +1 -1
- package/chunks/{serve-KLTMPK4W.js → serve-WSICDFGG.js} +1 -1
- package/chunks/{server-VLRNY6KG.js → server-GYYVTNGY.js} +3 -3
- package/chunks/{session-2EB57NXY.js → session-KF3O23ZJ.js} +1 -1
- package/chunks/{session-attachments-root-I7TESMWL.js → session-attachments-root-7HFUSONH.js} +1 -1
- package/chunks/{session-execution-engine-selector-5FAMSPSO.js → session-execution-engine-selector-NVILT6BR.js} +1 -1
- package/chunks/{session-pr-refresh-JCPVQPNJ.js → session-pr-refresh-3KDFTDEV.js} +1 -1
- package/chunks/{sessionService-YRW2IFPR.js → sessionService-XRTFLPDW.js} +1 -1
- package/chunks/{settings-KO2Q47JP.js → settings-QPPK6WXE.js} +1 -1
- package/chunks/{shell-OLZVNTQZ.js → shell-WYQDZWL7.js} +1 -1
- package/chunks/{skill-XW2AQS7M.js → skill-FYPT6AU7.js} +1 -1
- package/chunks/{skill-settings-TKAVQ4XP.js → skill-settings-OGFI5KZF.js} +1 -1
- package/chunks/{spawnChannel-MBGCTK2J.js → spawnChannel-ANOOVPG7.js} +1 -1
- package/chunks/{standalone-update-A3YLLIAN.js → standalone-update-45WTDY4E.js} +1 -1
- package/chunks/{start-opentui-ui-G5ROAR4V.js → start-opentui-ui-TL5WK33V.js} +1 -1
- package/chunks/{startInteractiveUI-PZQR4U53.js → startInteractiveUI-N2IREVBM.js} +1 -1
- package/chunks/{team-create-S5ZY2UMF.js → team-create-R77PRZ5U.js} +1 -1
- package/chunks/{team-plan-approval-KX6RXEST.js → team-plan-approval-6DCRKB5I.js} +1 -1
- package/chunks/{terminal-image-renderer-SCJREXE6.js → terminal-image-renderer-TB7EX2WW.js} +1 -1
- package/chunks/{theme-manager-DZSM4EBR.js → theme-manager-RQDXJGVR.js} +1 -1
- package/chunks/{tool-call-UK56SWCT.js → tool-call-LVB4NCDT.js} +1 -1
- package/chunks/{tool-result-media-JLLSLGFL.js → tool-result-media-LRBB2KS6.js} +1 -1
- package/chunks/{tool-search-OWPFLVV5.js → tool-search-OG73QAQZ.js} +1 -1
- package/chunks/{total-session-admission-NQU4ACKH.js → total-session-admission-A4CUF6AD.js} +1 -1
- package/chunks/{trustedFolders-N7GXFYSF.js → trustedFolders-LSGOYTU2.js} +1 -1
- package/chunks/{update-relaunch-5SPXXHM2.js → update-relaunch-OGC6BZO7.js} +1 -1
- package/chunks/{updateCheck-VXUIX2XG.js → updateCheck-7J3GXTER.js} +1 -1
- package/chunks/{upload-config-OWLL4SRQ.js → upload-config-ML5XEJIF.js} +1 -1
- package/chunks/{useAutoAcceptIndicator-OUYRR56F.js → useAutoAcceptIndicator-6DH6GQ2X.js} +1 -1
- package/chunks/{validateNonInterActiveAuth-PSVJO5HK.js → validateNonInterActiveAuth-KJDAGZCM.js} +1 -1
- package/chunks/{version-C26S7UAW.js → version-7JN2YXL2.js} +1 -1
- package/chunks/{web-fetch-AYOYV7R4.js → web-fetch-42ZR4FEZ.js} +1 -1
- package/chunks/{web-search-DAREKD3Z.js → web-search-74NLPMZJ.js} +1 -1
- package/chunks/{workflow-WBGPKVO6.js → workflow-WNPHX42I.js} +1 -1
- package/chunks/{workflow-ancestor-trust-GEEB53TB.js → workflow-ancestor-trust-HGF6G7LQ.js} +1 -1
- package/chunks/{workspace-agents-IMAQME4W.js → workspace-agents-3YFBFAK3.js} +1 -1
- package/chunks/{workspace-providers-status-VALHVEU2.js → workspace-providers-status-EPJI6KRV.js} +1 -1
- package/chunks/{workspace-recovery-worker-AIAVRDGU.js → workspace-recovery-worker-T3FK5YOD.js} +1 -1
- package/chunks/{workspace-registration-store-FXEGZG3L.js → workspace-registration-store-VEXYBDMA.js} +1 -1
- package/chunks/{workspace-registry-GYFFHWCD.js → workspace-registry-NRZYTP2X.js} +1 -1
- package/chunks/{workspace-runtime-coordinator-VZ462TLU.js → workspace-runtime-coordinator-USNSTP2V.js} +1 -1
- package/chunks/{workspace-service-5DIZM4IZ.js → workspace-service-USATWO56.js} +1 -1
- package/chunks/{workspace-skills-status-DOOBVL5N.js → workspace-skills-status-M5JTSFDL.js} +1 -1
- package/chunks/{workspace-trust-reconciler-LOICVUVW.js → workspace-trust-reconciler-ZUZ2O5WC.js} +1 -1
- package/chunks/{write-file-EJNMAHQD.js → write-file-UMJVKE4S.js} +1 -1
- package/chunks/{zoom-image-S3OARMYP.js → zoom-image-76XYHQ3Z.js} +1 -1
- package/cli.js +2 -2
- package/execution-worker.js +1 -1
- package/export-transcript-document.js +1 -1
- package/gerege.mjs +64 -15
- package/locales/mn.js +2702 -3774
- package/package.json +3 -3
- package/chunks/mn-YH2OTBWJ.js +0 -8
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
-
import{memoryImportReservation,validateMemoryImportBatchProposal}from"./chunk-7IERHQ63.js";import{MEMORY_IMPORT_BUDGET,MemoryImportRequestError,digest,packMemoryImportSections,previewSource}from"./chunk-HSYBIGMS.js";import{rebuildAutoMemoryIndexAtRoot,tokenizeMemoryRecallTerms,tokenizeMemoryRecallText}from"./chunk-Z5XENA4A.js";import{parseAutoMemoryTopicDocument,resolveTrustedMemoryFile,scanAutoMemorySnapshot}from"./chunk-FUBDS3AV.js";import{require_proper_lockfile}from"./chunk-YIW3H46P.js";import{getImportedProjectMemoryRoot,getMemoryRootTrustedAnchor,getUserAutoMemoryRoot}from"./chunk-KVA6DHHF.js";import{Storage}from"./chunk-EPODBRBP.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name,__toESM}from"./chunk-KBWJGX7I.js";init_esbuild_shims();var import_proper_lockfile=__toESM(require_proper_lockfile(),1);import*as fs from"node:fs/promises";import{constants}from"node:fs";import{randomUUID}from"node:crypto";import{AsyncLocalStorage}from"node:async_hooks";import path from"node:path";var MemoryImportNotFoundError=class extends Error{static{__name(this,"MemoryImportNotFoundError")}code="ENOENT"};var ImportBudgetError=class extends Error{static{__name(this,"ImportBudgetError")}};var ImportContextError=class extends Error{static{__name(this,"ImportContextError")}};var heldLocks=new AsyncLocalStorage;var exists=__name(async file=>fs.lstat(file).then(()=>true,error=>{if(error.code==="ENOENT")return false;throw error}),"exists");async function privateDirectory(directory,anchor){const relative=path.relative(anchor,directory);if(relative.startsWith("..")||path.isAbsolute(relative))throw new Error("Import path escapes runtime.");let current=anchor;for(const part of["",...relative.split(path.sep).filter(Boolean)]){if(part)current=path.join(current,part);await fs.mkdir(current,{mode:448}).catch(error=>{if(error.code!=="EEXIST")throw error});const stat=await fs.lstat(current);if(!stat.isDirectory()||stat.isSymbolicLink())throw new Error("Import runtime directory must not be a symlink.")}}__name(privateDirectory,"privateDirectory");async function readJson(file){const handle=await fs.open(file,constants.O_RDONLY|constants.O_NOFOLLOW|constants.O_NONBLOCK);try{const stat=await handle.stat();if(!stat.isFile()||stat.size>16*1024*1024)throw new Error("Invalid import state file.");const buffer=Buffer.alloc(stat.size+1);const{bytesRead}=await handle.read(buffer,0,buffer.length,0);if(bytesRead>stat.size)throw new Error("Import state exceeds the supported limit.");return JSON.parse(buffer.subarray(0,bytesRead).toString("utf8"))}finally{await handle.close()}}__name(readJson,"readJson");async function writeJson(file,value){heldLocks.getStore()?.throwIfAborted();const tmp=`${file}.${randomUUID()}.tmp`;await fs.writeFile(tmp,JSON.stringify(value),{mode:384,flag:"wx"});try{heldLocks.getStore()?.throwIfAborted();await fs.rename(tmp,file)}finally{await fs.rm(tmp,{force:true})}}__name(writeJson,"writeJson");async function abortable(signal,work){signal.throwIfAborted();let abort;const cancelled=new Promise((_resolve,reject)=>{abort=__name(()=>reject(new Error("Import cancelled.")),"abort");signal.addEventListener("abort",abort,{once:true})});try{return await Promise.race([work(),cancelled])}finally{signal.removeEventListener("abort",abort)}}__name(abortable,"abortable");function publicTask(task){const{requestDigest:_requestDigest,...result}=task;return structuredClone({...result,usage:task.usage??{modelCalls:0,reservedTokens:0},budget:task.budget??{maxCalls:0,maxReservedTokens:0},result:{sourceSections:task.items.length,newDocuments:task.items.filter(item=>item.status==="added").reduce((n,item)=>n+(item.refs?.length??0),0),duplicateSections:task.items.filter(item=>item.status==="duplicate").length,conflictSections:task.items.filter(item=>item.status==="conflict").length,failedSections:task.items.filter(item=>item.status==="failed").length}})}__name(publicTask,"publicTask");function selectImportContext(existing,sources){const queries=sources.map(source=>({text:source.normalize("NFKC").toLowerCase(),terms:tokenizeMemoryRecallTerms(source)}));const index=existing.map(item=>{const parsed=parseAutoMemoryTopicDocument("existing.md",item.content);if(!parsed)throw new ImportContextError("Existing memory has no bounded metadata index. Repair its native metadata before importing.");const metadata=JSON.stringify({name:parsed.title,description:parsed.description,type:parsed.type,category:parsed.category,keywords:parsed.keywords,usage_scenarios:parsed.usageScenarios});const words=tokenizeMemoryRecallText([parsed.title,...parsed.keywords].join(" "));const anchors=[parsed.title,parsed.description].map(text=>text.normalize("NFKC").toLowerCase().trim()).filter(text=>tokenizeMemoryRecallText(text).length>=2);const body=parsed.body.normalize("NFKC").toLowerCase().trim();const relevant=queries.some(({text,terms})=>{if(anchors.some(anchor=>text.includes(anchor))||body.length>0&&text.includes(body))return true;const shared=words.filter(word=>terms.has(word));return shared.length>=2&&shared.length>=words.length/2});return{ref:item.ref,content:relevant?item.content:metadata,indexOnly:!relevant}});const context=[];let bytes=2;for(const entry of[...index.filter(item=>!item.indexOnly),...index.filter(item=>item.indexOnly)]){const size=Buffer.byteLength(JSON.stringify(entry))+(context.length?1:0);if(bytes+size>MEMORY_IMPORT_BUDGET.contextBytes){if(!entry.indexOnly)throw new ImportContextError("Relevant existing evidence exceeds the 32 KiB import context budget. Select a narrower source group or consolidate existing memory before retrying. No model call was made.");continue}bytes+=size;context.push(entry)}return context}__name(selectImportContext,"selectImportContext");function respectsImportScope(proposal,scope){return scope!=="user"||proposal.documents.every(content=>{const type=parseAutoMemoryTopicDocument("import.md",content)?.type;return type==="user"||type==="feedback"})}__name(respectsImportScope,"respectsImportScope");var MemoryImportService=class{constructor(options){this.options=options;this.owner=digest(path.resolve(options.projectRoot))}static{__name(this,"MemoryImportService")}base=Storage.getRuntimeBaseDir();state=path.join(this.base,"memory-import");owner;workers=new Map;controllers=new Map;async readState(file){const relative=path.relative(this.base,path.dirname(file));if(relative.startsWith("..")||path.isAbsolute(relative))throw new Error("Import state escapes runtime.");let current=this.base;for(const part of["",...relative.split(path.sep).filter(Boolean)]){if(part)current=path.join(current,part);const stat=await fs.lstat(current);if(!stat.isDirectory()||stat.isSymbolicLink())throw new Error("Invalid import state directory.")}return readJson(file)}taskDir(id){if(!/^[a-f0-9]{64}$/.test(id))throw new MemoryImportRequestError("Invalid import batch ID.");return path.join(this.state,"batches",this.owner,id)}async assertRuntimeOutsideGit(){let current=path.resolve(this.base);while(true){if(await exists(path.join(current,".git")))throw new Error("Memory import requires a runtime directory outside Git checkouts.");const parent=path.dirname(current);if(parent===current)break;current=parent}await fs.mkdir(this.base,{recursive:true,mode:448});current=await fs.realpath(this.base);while(true){if(await exists(path.join(current,".git")))throw new Error("Memory import requires a private runtime outside Git checkouts.");const parent=path.dirname(current);if(parent===current)break;current=parent}}async prepare(){this.options.assertActive();await this.assertRuntimeOutsideGit();await privateDirectory(path.join(this.state,"batches",this.owner),this.base)}async locked(directory,run,signal){await privateDirectory(directory,this.base);const ownership=new AbortController;const parent=heldLocks.getStore();const held=parent?AbortSignal.any([parent,ownership.signal]):ownership.signal;const work=signal?AbortSignal.any([signal,held]):held;let release;while(!release){work.throwIfAborted();this.options.assertActive();try{release=await import_proper_lockfile.default.lock(directory,{realpath:false,stale:12e4,update:1e4,retries:0,onCompromised:__name(()=>{ownership.abort(new Error("Import lock lost."))},"onCompromised")})}catch(error){if(error.code!=="ELOCKED")throw error;await new Promise(resolve=>setTimeout(resolve,250))}}try{work.throwIfAborted();const result=await heldLocks.run(held,()=>run(work));held.throwIfAborted();return result}finally{try{if(!ownership.signal.aborted)await release()}finally{ownership.abort(new Error("Import lock released."))}}}async submit(input,selections,key){this.options.assertActive();const preview=previewSource(input);if(typeof key!=="string"||!/^[\w-]{1,128}$/.test(key)||!Array.isArray(selections)||!selections.length||selections.length>2048)throw new MemoryImportRequestError("Provide an idempotency key and explicit non-empty selection.");const seen=new Set;const selected=selections.map(value=>{if(!value||typeof value!=="object")throw new MemoryImportRequestError("Invalid selection.");const selection=value;const section=preview.sections.find(item=>item.id===selection.id&&item.selectable);if(!section||seen.has(selection.id)||!["project","user"].includes(selection.scope))throw new MemoryImportRequestError("Invalid, duplicate or unavailable section selection.");seen.add(selection.id);return{...section,scope:selection.scope}}).sort((a,b)=>a.id.localeCompare(b.id));const retained=JSON.stringify({sections:selected});if(Buffer.byteLength(retained)>16*1024*1024)throw new MemoryImportRequestError("Selected contextual source exceeds the retained snapshot limit.");const requestDigest=digest(JSON.stringify(selected));const id=digest(`${this.owner}\0${key}`);await this.prepare();const dir=this.taskDir(id);return this.locked(path.join(this.state,"admission",this.owner),async()=>{this.options.assertActive();if(await exists(path.join(dir,"task.json"))){const task2=await this.readState(path.join(dir,"task.json"));if(task2.requestDigest!==requestDigest)throw new MemoryImportRequestError("Idempotency key was already used with a different selection.");this.kick(id);return publicTask(task2)}await privateDirectory(dir,this.base);await writeJson(path.join(dir,"source.json"),{sections:selected});const now=new Date().toISOString();const task={version:1,kind:"task",id,status:"queued",createdAt:now,updatedAt:now,requestDigest,usage:{modelCalls:0,reservedTokens:0},budget:{maxCalls:MEMORY_IMPORT_BUDGET.maxCalls,maxReservedTokens:MEMORY_IMPORT_BUDGET.maxReservedTokens},items:selected.map(section=>({id:section.id,scope:section.scope,status:"pending"}))};await writeJson(path.join(dir,"task.json"),task);this.kick(id);return publicTask(task)})}kick(id){if(this.workers.has(id))return;const worker=heldLocks.exit(()=>this.run(id)).catch(()=>{}).finally(()=>{this.workers.delete(id);this.controllers.delete(id)});this.workers.set(id,worker)}async recover(){this.options.assertActive();const root=path.join(this.state,"batches",this.owner);if(!await exists(root))return;await this.assertRuntimeOutsideGit();await privateDirectory(root,this.base);for(const id of(await fs.readdir(root)).filter(id2=>/^[a-f0-9]{64}$/.test(id2))){const task=await this.readState(path.join(this.taskDir(id),"task.json")).catch(()=>void 0);if(task&&(task.status==="running"||task.status==="queued"))this.kick(id)}}async list(){this.options.assertActive();const root=path.join(this.state,"batches",this.owner);if(!await exists(root))return[];await privateDirectory(root,this.base);const result=[];for(const id of(await fs.readdir(root)).filter(id2=>/^[a-f0-9]{64}$/.test(id2))){const task=await this.get(id).catch(()=>void 0);if(task)result.push(task)}return result.sort((a,b)=>b.createdAt.localeCompare(a.createdAt))}async get(id){this.options.assertActive();const task=await this.readState(path.join(this.taskDir(id),"task.json")).catch(cause=>{if(cause.code==="ENOENT")throw new MemoryImportNotFoundError("Import batch not found.",{cause});throw cause});if(task.status!=="completed"&&await exists(path.join(this.taskDir(id),"cancel.json")))task.status="cancelled";return publicTask(task)}async source(id,sectionId){await this.get(id);const source=await this.readState(path.join(this.taskDir(id),"source.json"));const section=source.sections.find(item=>item.id===sectionId);if(!section)throw new MemoryImportRequestError("Source section not found in this batch.");return section}async cancel(id){this.options.assertActive();this.controllers.get(id)?.abort();const task=await this.get(id);if(task.status==="completed")return task;await writeJson(path.join(this.taskDir(id),"cancel.json"),{cancelled:true});this.controllers.get(id)?.abort();await this.workers.get(id);return this.get(id)}async retry(id){await this.get(id);await this.prepare();await this.workers.get(id);const dir=this.taskDir(id);const result=await this.locked(dir,async()=>{const task=await this.readState(path.join(dir,"task.json"));if(task.status==="completed")return publicTask(task);await fs.rm(path.join(dir,"cancel.json"),{force:true});for(const item of task.items)if(item.status==="failed"){item.status="pending";delete item.reason}task.status="queued";task.updatedAt=new Date().toISOString();await writeJson(path.join(dir,"task.json"),task);return publicTask(task)});this.kick(id);return result}async idle(id){await this.workers.get(id);return this.get(id)}async run(id){const dir=this.taskDir(id);const controller=new AbortController;this.controllers.set(id,controller);await this.locked(dir,async signal=>{const task=await this.readState(path.join(dir,"task.json"));if(!["queued","running"].includes(task.status))return;const source=await this.readState(path.join(dir,"source.json"));if(!task.usage){task.usage={modelCalls:0,reservedTokens:0};task.budget={maxCalls:0,maxReservedTokens:0}}task.budget??={maxCalls:0,maxReservedTokens:0};task.status="running";await writeJson(path.join(dir,"task.json"),task);for(const section of packMemoryImportSections(source.sections).flat()){const item=task.items.find(item2=>item2.id===section.id);if(item.status!=="pending")continue;if(await exists(path.join(dir,"cancel.json")))controller.abort();if(controller.signal.aborted)break;try{this.options.assertActive();Object.assign(item,await this.importSection(section,id,signal,(before,ledger,proposalSignal)=>this.prepareProposal(section,source,task,before,ledger,proposalSignal),async()=>{if(await exists(path.join(dir,"cancel.json")))controller.abort();controller.signal.throwIfAborted();this.options.assertActive()}))}catch(error){if(controller.signal.aborted)break;item.status="failed";item.reason=error instanceof ImportBudgetError||error instanceof ImportContextError?error.message:"Import could not finish. Existing memories were preserved; retry after resolving runtime, model or storage availability."}task.updatedAt=new Date().toISOString();await writeJson(path.join(dir,"task.json"),task)}task.status=controller.signal.aborted?"cancelled":task.items.some(item=>item.status==="failed")?"partial":"completed";task.updatedAt=new Date().toISOString();await writeJson(path.join(dir,"task.json"),task)},controller.signal)}async prepareProposal(section,source,task,before,ledger,signal){const dir=this.taskDir(task.id);const journalFile=path.join(dir,"proposals.json");const journals=await exists(journalFile)?await this.readState(journalFile):[];let journal=journals.find(entry=>entry.scope===section.scope&&entry.sections.some(item=>item.id===section.id));if(journal&&!respectsImportScope(journal.proposal.items.find(item=>item.id===section.id),section.scope)){journal.sections=journal.sections.filter(item=>item.id!==section.id);journal.proposal.items=journal.proposal.items.filter(item=>item.id!==section.id);if(!journal.sections.length)journals.splice(journals.indexOf(journal),1);await writeJson(journalFile,journals);journal=void 0}if(!journal){const eligible=source.sections.filter(candidate=>candidate.scope===section.scope&&candidate.groupId===section.groupId&&task.items.some(item=>item.id===candidate.id&&item.status==="pending")&&!ledger[candidate.id]&&!journals.some(entry=>entry.sections.some(item=>item.id===candidate.id)));const batch=packMemoryImportSections(eligible).find(items=>items.some(item=>item.id===section.id));if(!batch)throw new Error("Source batch is unavailable.");const input={scope:section.scope,sources:batch.map(({id,content})=>({id,content})),existing:selectImportContext(before.existing,batch.map(item=>item.content))};const reserved=memoryImportReservation(input);if(task.usage.modelCalls>=Math.min(task.budget.maxCalls,MEMORY_IMPORT_BUDGET.maxCalls)||task.usage.reservedTokens+reserved>Math.min(task.budget.maxReservedTokens,MEMORY_IMPORT_BUDGET.maxReservedTokens))throw new ImportBudgetError("Import budget exhausted. Retry preserves this budget; split remaining sources into an explicitly confirmed new task.");signal.throwIfAborted();task.usage.modelCalls++;task.usage.reservedTokens+=reserved;await writeJson(path.join(dir,"task.json"),task);let proposal;try{proposal=validateMemoryImportBatchProposal(await abortable(signal,()=>this.options.propose(input,signal)),batch.map(item=>item.id));if(proposal.items.some(item=>!respectsImportScope(item,section.scope)))throw new ImportContextError("Model returned project knowledge for user memory. Retry to request a scope-valid response; consumed budget is retained.")}catch(error){if(!signal.aborted){for(const item of task.items)if(batch.some(section2=>section2.id===item.id)){item.status="failed";item.reason="Model batch failed validation or execution; explicit retry retains its consumed budget."}}throw error}signal.throwIfAborted();journal={scope:section.scope,sections:batch.map(item=>({id:item.id,key:item.id})),baseline:before.existing.map(item=>({ref:item.ref,digest:digest(item.content)})),proposal};journals.push(journal);await writeJson(journalFile,journals)}const expected=new Map(journal.baseline.map(item=>[item.ref,item.digest]));for(const record of Object.values(ledger)){if(record.phase==="committed")for(const output of record.outputs){const ref=`${section.scope}:${output.relativePath}`;if(!expected.has(ref))expected.set(ref,output.digest)}}if(expected.size!==before.existing.length||before.existing.some(item=>expected.get(item.ref)!==digest(item.content)))return{decision:"conflict",reason:"Existing memory changed since this batch was consolidated; retained proposals cannot overwrite edits or restore forgotten knowledge.",documents:[]};return journal.proposal.items.find(item=>item.id===section.id)}async snapshot(scope){const snapshot=await scanAutoMemorySnapshot(this.options.projectRoot,{scopes:[scope],trustedProject:true,uncapped:true});if(!snapshot.sourceStatus.complete)throw new Error("Existing memory scan is incomplete.");const existing=[];for(const doc of snapshot.docs)existing.push({ref:`${scope}:${doc.relativePath}`,content:await fs.readFile(doc.filePath,"utf8")});existing.sort((a,b)=>a.ref.localeCompare(b.ref));return{version:digest(JSON.stringify(existing)),existing}}async importSection(section,batchId,signal,propose,assertCommit){const root=section.scope==="user"?getUserAutoMemoryRoot():getImportedProjectMemoryRoot(this.options.projectRoot,true);const scopeState=path.join(this.state,"scopes",digest(root));return this.locked(scopeState,async signal2=>{signal2.throwIfAborted();this.options.assertActive();if(await exists(root)&&(await fs.lstat(root)).isSymbolicLink())throw new ImportContextError("Memory import does not support a symlinked memory root. Use a non-symlink memory root before retrying; existing memories were not changed.");const ledgerPath=path.join(scopeState,"ledger.json");const ledger=await exists(ledgerPath)?await this.readState(ledgerPath):{};const key=section.id;let previous=ledger[key];const discardUnpublishedIntent=__name(async stage2=>{signal2.throwIfAborted();this.options.assertActive();delete ledger[key];await writeJson(ledgerPath,ledger);heldLocks.getStore()?.throwIfAborted();await fs.rm(stage2,{recursive:true,force:true})},"discardUnpublishedIntent");const outcome=__name((status,reason)=>({id:section.id,scope:section.scope,status,...reason?{reason}:{}}),"outcome");if(previous?.phase==="intent"){const stage2=path.join(scopeState,previous.stage);if(await exists(stage2)&&!await exists(path.join(root,"imported",key))&&(await this.snapshot(section.scope)).version!==previous.memoryVersion){await discardUnpublishedIntent(stage2);previous=void 0}}if(previous){const stage2=path.join(scopeState,previous.stage);const destination=path.join(root,"imported",key);if(previous.phase==="intent"&&await exists(stage2)&&!await exists(destination)){for(const output of previous.outputs){const file=path.join(stage2,path.basename(output.relativePath));if(digest(await fs.readFile(file,"utf8"))!==output.digest)throw new Error("Invalid staged import.")}signal2.throwIfAborted();this.options.assertActive();await privateDirectory(path.join(root,"imported"),this.base);signal2.throwIfAborted();this.options.assertActive();await assertCommit();heldLocks.getStore()?.throwIfAborted();await fs.rename(stage2,destination)}for(const output of previous.outputs){const file=await resolveTrustedMemoryFile(root,getMemoryRootTrustedAnchor(root),output.relativePath);if(!file||digest(await fs.readFile(file,"utf8"))!==output.digest)return outcome("conflict","Previously imported memory was edited or forgotten; it will not be restored.")}previous.phase="committed";await writeJson(ledgerPath,ledger);await rebuildAutoMemoryIndexAtRoot(root,section.scope);if(previous.batchId===batchId)return{...previous.outcome,id:section.id,scope:section.scope};return outcome(previous.outcome.status==="added"?"duplicate":previous.outcome.status,"This source has already been processed.")}const before=await this.snapshot(section.scope);const proposal=await propose(before,ledger,signal2);signal2.throwIfAborted();this.options.assertActive();if((await this.snapshot(section.scope)).version!==before.version)return outcome("conflict","Existing memory changed during consolidation; preview and retry the source.");await assertCommit();if(proposal.decision==="conflict")return outcome("conflict",proposal.reason);if(proposal.decision!=="new"){const result2=outcome(proposal.decision==="skip"?"skipped":"duplicate",proposal.reason);ledger[key]={batchId,phase:"committed",outputs:[],stage:"",outcome:result2};await writeJson(ledgerPath,ledger);return result2}const documents=[];for(const content of new Set(proposal.documents)){const parsed=parseAutoMemoryTopicDocument("import.md",content);if(!parsed)throw new Error("Invalid native memory.");if(section.scope==="user"&&parsed.type!=="user"&&parsed.type!=="feedback")throw new Error("Project knowledge cannot be imported into user memory.");const bodyDigest=digest(parsed.body.trim());for(const[sourceId,record]of Object.entries(ledger)){if(record.outputs.some(output=>output.bodyDigest===bodyDigest)){if(record.phase==="intent"&&!await exists(path.join(root,"imported",sourceId)))continue;for(const output of record.outputs){const file=await resolveTrustedMemoryFile(root,getMemoryRootTrustedAnchor(root),output.relativePath);if(!file||digest(await fs.readFile(file,"utf8"))!==output.digest)return outcome("conflict","Previously edited or forgotten imported knowledge cannot be recreated.")}}}if(before.existing.some(existing=>parseAutoMemoryTopicDocument("existing.md",existing.content)?.body.trim()===parsed.body.trim()))continue;if(!documents.some(existing=>parseAutoMemoryTopicDocument("new.md",existing)?.body.trim()===parsed.body.trim()))documents.push(content)}if(!documents.length){const result2=outcome("duplicate","All proposed knowledge already exists.");ledger[key]={batchId,phase:"committed",outputs:[],stage:"",outcome:result2};await writeJson(ledgerPath,ledger);return result2}const stageName=`stage-${key}`;const stage=path.join(scopeState,stageName);if(await exists(stage)){await privateDirectory(stage,this.base);await fs.rm(stage,{recursive:true})}await privateDirectory(stage,this.base);const outputs=[];for(const[index,content]of documents.entries()){const filename=`${index}.md`;await fs.writeFile(path.join(stage,filename),content,{flag:"wx",mode:384});outputs.push({relativePath:`imported/${key}/${filename}`,digest:digest(content),bodyDigest:digest(parseAutoMemoryTopicDocument("import.md",content).body.trim())})}const result={...outcome("added",proposal.reason),refs:outputs.map(output=>`${section.scope}:${output.relativePath}`)};ledger[key]={batchId,phase:"intent",outputs,stage:stageName,memoryVersion:before.version,outcome:result};await writeJson(ledgerPath,ledger);signal2.throwIfAborted();this.options.assertActive();await privateDirectory(path.join(root,"imported"),this.base);signal2.throwIfAborted();this.options.assertActive();if((await this.snapshot(section.scope)).version!==before.version){await discardUnpublishedIntent(stage);return outcome("conflict","Existing memory changed before publication.")}await assertCommit();heldLocks.getStore()?.throwIfAborted();await fs.rename(stage,path.join(root,"imported",key));ledger[key].phase="committed";await writeJson(ledgerPath,ledger);await rebuildAutoMemoryIndexAtRoot(root,section.scope);return result},signal)}};export{MemoryImportNotFoundError,MemoryImportService};
|
|
3
|
+
import{memoryImportReservation,validateMemoryImportBatchProposal}from"./chunk-LYFRGP42.js";import{MEMORY_IMPORT_BUDGET,MemoryImportRequestError,digest,packMemoryImportSections,previewSource}from"./chunk-F5SLLEJY.js";import{rebuildAutoMemoryIndexAtRoot,tokenizeMemoryRecallTerms,tokenizeMemoryRecallText}from"./chunk-T3CQ72HC.js";import{parseAutoMemoryTopicDocument,resolveTrustedMemoryFile,scanAutoMemorySnapshot}from"./chunk-FUBDS3AV.js";import{require_proper_lockfile}from"./chunk-YIW3H46P.js";import{getImportedProjectMemoryRoot,getMemoryRootTrustedAnchor,getUserAutoMemoryRoot}from"./chunk-KVA6DHHF.js";import{Storage}from"./chunk-EPODBRBP.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name,__toESM}from"./chunk-KBWJGX7I.js";init_esbuild_shims();var import_proper_lockfile=__toESM(require_proper_lockfile(),1);import*as fs from"node:fs/promises";import{constants}from"node:fs";import{randomUUID}from"node:crypto";import{AsyncLocalStorage}from"node:async_hooks";import path from"node:path";var MemoryImportNotFoundError=class extends Error{static{__name(this,"MemoryImportNotFoundError")}code="ENOENT"};var ImportBudgetError=class extends Error{static{__name(this,"ImportBudgetError")}};var ImportContextError=class extends Error{static{__name(this,"ImportContextError")}};var heldLocks=new AsyncLocalStorage;var exists=__name(async file=>fs.lstat(file).then(()=>true,error=>{if(error.code==="ENOENT")return false;throw error}),"exists");async function privateDirectory(directory,anchor){const relative=path.relative(anchor,directory);if(relative.startsWith("..")||path.isAbsolute(relative))throw new Error("Import path escapes runtime.");let current=anchor;for(const part of["",...relative.split(path.sep).filter(Boolean)]){if(part)current=path.join(current,part);await fs.mkdir(current,{mode:448}).catch(error=>{if(error.code!=="EEXIST")throw error});const stat=await fs.lstat(current);if(!stat.isDirectory()||stat.isSymbolicLink())throw new Error("Import runtime directory must not be a symlink.")}}__name(privateDirectory,"privateDirectory");async function readJson(file){const handle=await fs.open(file,constants.O_RDONLY|constants.O_NOFOLLOW|constants.O_NONBLOCK);try{const stat=await handle.stat();if(!stat.isFile()||stat.size>16*1024*1024)throw new Error("Invalid import state file.");const buffer=Buffer.alloc(stat.size+1);const{bytesRead}=await handle.read(buffer,0,buffer.length,0);if(bytesRead>stat.size)throw new Error("Import state exceeds the supported limit.");return JSON.parse(buffer.subarray(0,bytesRead).toString("utf8"))}finally{await handle.close()}}__name(readJson,"readJson");async function writeJson(file,value){heldLocks.getStore()?.throwIfAborted();const tmp=`${file}.${randomUUID()}.tmp`;await fs.writeFile(tmp,JSON.stringify(value),{mode:384,flag:"wx"});try{heldLocks.getStore()?.throwIfAborted();await fs.rename(tmp,file)}finally{await fs.rm(tmp,{force:true})}}__name(writeJson,"writeJson");async function abortable(signal,work){signal.throwIfAborted();let abort;const cancelled=new Promise((_resolve,reject)=>{abort=__name(()=>reject(new Error("Import cancelled.")),"abort");signal.addEventListener("abort",abort,{once:true})});try{return await Promise.race([work(),cancelled])}finally{signal.removeEventListener("abort",abort)}}__name(abortable,"abortable");function publicTask(task){const{requestDigest:_requestDigest,...result}=task;return structuredClone({...result,usage:task.usage??{modelCalls:0,reservedTokens:0},budget:task.budget??{maxCalls:0,maxReservedTokens:0},result:{sourceSections:task.items.length,newDocuments:task.items.filter(item=>item.status==="added").reduce((n,item)=>n+(item.refs?.length??0),0),duplicateSections:task.items.filter(item=>item.status==="duplicate").length,conflictSections:task.items.filter(item=>item.status==="conflict").length,failedSections:task.items.filter(item=>item.status==="failed").length}})}__name(publicTask,"publicTask");function selectImportContext(existing,sources){const queries=sources.map(source=>({text:source.normalize("NFKC").toLowerCase(),terms:tokenizeMemoryRecallTerms(source)}));const index=existing.map(item=>{const parsed=parseAutoMemoryTopicDocument("existing.md",item.content);if(!parsed)throw new ImportContextError("Existing memory has no bounded metadata index. Repair its native metadata before importing.");const metadata=JSON.stringify({name:parsed.title,description:parsed.description,type:parsed.type,category:parsed.category,keywords:parsed.keywords,usage_scenarios:parsed.usageScenarios});const words=tokenizeMemoryRecallText([parsed.title,...parsed.keywords].join(" "));const anchors=[parsed.title,parsed.description].map(text=>text.normalize("NFKC").toLowerCase().trim()).filter(text=>tokenizeMemoryRecallText(text).length>=2);const body=parsed.body.normalize("NFKC").toLowerCase().trim();const relevant=queries.some(({text,terms})=>{if(anchors.some(anchor=>text.includes(anchor))||body.length>0&&text.includes(body))return true;const shared=words.filter(word=>terms.has(word));return shared.length>=2&&shared.length>=words.length/2});return{ref:item.ref,content:relevant?item.content:metadata,indexOnly:!relevant}});const context=[];let bytes=2;for(const entry of[...index.filter(item=>!item.indexOnly),...index.filter(item=>item.indexOnly)]){const size=Buffer.byteLength(JSON.stringify(entry))+(context.length?1:0);if(bytes+size>MEMORY_IMPORT_BUDGET.contextBytes){if(!entry.indexOnly)throw new ImportContextError("Relevant existing evidence exceeds the 32 KiB import context budget. Select a narrower source group or consolidate existing memory before retrying. No model call was made.");continue}bytes+=size;context.push(entry)}return context}__name(selectImportContext,"selectImportContext");function respectsImportScope(proposal,scope){return scope!=="user"||proposal.documents.every(content=>{const type=parseAutoMemoryTopicDocument("import.md",content)?.type;return type==="user"||type==="feedback"})}__name(respectsImportScope,"respectsImportScope");var MemoryImportService=class{constructor(options){this.options=options;this.owner=digest(path.resolve(options.projectRoot))}static{__name(this,"MemoryImportService")}base=Storage.getRuntimeBaseDir();state=path.join(this.base,"memory-import");owner;workers=new Map;controllers=new Map;async readState(file){const relative=path.relative(this.base,path.dirname(file));if(relative.startsWith("..")||path.isAbsolute(relative))throw new Error("Import state escapes runtime.");let current=this.base;for(const part of["",...relative.split(path.sep).filter(Boolean)]){if(part)current=path.join(current,part);const stat=await fs.lstat(current);if(!stat.isDirectory()||stat.isSymbolicLink())throw new Error("Invalid import state directory.")}return readJson(file)}taskDir(id){if(!/^[a-f0-9]{64}$/.test(id))throw new MemoryImportRequestError("Invalid import batch ID.");return path.join(this.state,"batches",this.owner,id)}async assertRuntimeOutsideGit(){let current=path.resolve(this.base);while(true){if(await exists(path.join(current,".git")))throw new Error("Memory import requires a runtime directory outside Git checkouts.");const parent=path.dirname(current);if(parent===current)break;current=parent}await fs.mkdir(this.base,{recursive:true,mode:448});current=await fs.realpath(this.base);while(true){if(await exists(path.join(current,".git")))throw new Error("Memory import requires a private runtime outside Git checkouts.");const parent=path.dirname(current);if(parent===current)break;current=parent}}async prepare(){this.options.assertActive();await this.assertRuntimeOutsideGit();await privateDirectory(path.join(this.state,"batches",this.owner),this.base)}async locked(directory,run,signal){await privateDirectory(directory,this.base);const ownership=new AbortController;const parent=heldLocks.getStore();const held=parent?AbortSignal.any([parent,ownership.signal]):ownership.signal;const work=signal?AbortSignal.any([signal,held]):held;let release;while(!release){work.throwIfAborted();this.options.assertActive();try{release=await import_proper_lockfile.default.lock(directory,{realpath:false,stale:12e4,update:1e4,retries:0,onCompromised:__name(()=>{ownership.abort(new Error("Import lock lost."))},"onCompromised")})}catch(error){if(error.code!=="ELOCKED")throw error;await new Promise(resolve=>setTimeout(resolve,250))}}try{work.throwIfAborted();const result=await heldLocks.run(held,()=>run(work));held.throwIfAborted();return result}finally{try{if(!ownership.signal.aborted)await release()}finally{ownership.abort(new Error("Import lock released."))}}}async submit(input,selections,key){this.options.assertActive();const preview=previewSource(input);if(typeof key!=="string"||!/^[\w-]{1,128}$/.test(key)||!Array.isArray(selections)||!selections.length||selections.length>2048)throw new MemoryImportRequestError("Provide an idempotency key and explicit non-empty selection.");const seen=new Set;const selected=selections.map(value=>{if(!value||typeof value!=="object")throw new MemoryImportRequestError("Invalid selection.");const selection=value;const section=preview.sections.find(item=>item.id===selection.id&&item.selectable);if(!section||seen.has(selection.id)||!["project","user"].includes(selection.scope))throw new MemoryImportRequestError("Invalid, duplicate or unavailable section selection.");seen.add(selection.id);return{...section,scope:selection.scope}}).sort((a,b)=>a.id.localeCompare(b.id));const retained=JSON.stringify({sections:selected});if(Buffer.byteLength(retained)>16*1024*1024)throw new MemoryImportRequestError("Selected contextual source exceeds the retained snapshot limit.");const requestDigest=digest(JSON.stringify(selected));const id=digest(`${this.owner}\0${key}`);await this.prepare();const dir=this.taskDir(id);return this.locked(path.join(this.state,"admission",this.owner),async()=>{this.options.assertActive();if(await exists(path.join(dir,"task.json"))){const task2=await this.readState(path.join(dir,"task.json"));if(task2.requestDigest!==requestDigest)throw new MemoryImportRequestError("Idempotency key was already used with a different selection.");this.kick(id);return publicTask(task2)}await privateDirectory(dir,this.base);await writeJson(path.join(dir,"source.json"),{sections:selected});const now=new Date().toISOString();const task={version:1,kind:"task",id,status:"queued",createdAt:now,updatedAt:now,requestDigest,usage:{modelCalls:0,reservedTokens:0},budget:{maxCalls:MEMORY_IMPORT_BUDGET.maxCalls,maxReservedTokens:MEMORY_IMPORT_BUDGET.maxReservedTokens},items:selected.map(section=>({id:section.id,scope:section.scope,status:"pending"}))};await writeJson(path.join(dir,"task.json"),task);this.kick(id);return publicTask(task)})}kick(id){if(this.workers.has(id))return;const worker=heldLocks.exit(()=>this.run(id)).catch(()=>{}).finally(()=>{this.workers.delete(id);this.controllers.delete(id)});this.workers.set(id,worker)}async recover(){this.options.assertActive();const root=path.join(this.state,"batches",this.owner);if(!await exists(root))return;await this.assertRuntimeOutsideGit();await privateDirectory(root,this.base);for(const id of(await fs.readdir(root)).filter(id2=>/^[a-f0-9]{64}$/.test(id2))){const task=await this.readState(path.join(this.taskDir(id),"task.json")).catch(()=>void 0);if(task&&(task.status==="running"||task.status==="queued"))this.kick(id)}}async list(){this.options.assertActive();const root=path.join(this.state,"batches",this.owner);if(!await exists(root))return[];await privateDirectory(root,this.base);const result=[];for(const id of(await fs.readdir(root)).filter(id2=>/^[a-f0-9]{64}$/.test(id2))){const task=await this.get(id).catch(()=>void 0);if(task)result.push(task)}return result.sort((a,b)=>b.createdAt.localeCompare(a.createdAt))}async get(id){this.options.assertActive();const task=await this.readState(path.join(this.taskDir(id),"task.json")).catch(cause=>{if(cause.code==="ENOENT")throw new MemoryImportNotFoundError("Import batch not found.",{cause});throw cause});if(task.status!=="completed"&&await exists(path.join(this.taskDir(id),"cancel.json")))task.status="cancelled";return publicTask(task)}async source(id,sectionId){await this.get(id);const source=await this.readState(path.join(this.taskDir(id),"source.json"));const section=source.sections.find(item=>item.id===sectionId);if(!section)throw new MemoryImportRequestError("Source section not found in this batch.");return section}async cancel(id){this.options.assertActive();this.controllers.get(id)?.abort();const task=await this.get(id);if(task.status==="completed")return task;await writeJson(path.join(this.taskDir(id),"cancel.json"),{cancelled:true});this.controllers.get(id)?.abort();await this.workers.get(id);return this.get(id)}async retry(id){await this.get(id);await this.prepare();await this.workers.get(id);const dir=this.taskDir(id);const result=await this.locked(dir,async()=>{const task=await this.readState(path.join(dir,"task.json"));if(task.status==="completed")return publicTask(task);await fs.rm(path.join(dir,"cancel.json"),{force:true});for(const item of task.items)if(item.status==="failed"){item.status="pending";delete item.reason}task.status="queued";task.updatedAt=new Date().toISOString();await writeJson(path.join(dir,"task.json"),task);return publicTask(task)});this.kick(id);return result}async idle(id){await this.workers.get(id);return this.get(id)}async run(id){const dir=this.taskDir(id);const controller=new AbortController;this.controllers.set(id,controller);await this.locked(dir,async signal=>{const task=await this.readState(path.join(dir,"task.json"));if(!["queued","running"].includes(task.status))return;const source=await this.readState(path.join(dir,"source.json"));if(!task.usage){task.usage={modelCalls:0,reservedTokens:0};task.budget={maxCalls:0,maxReservedTokens:0}}task.budget??={maxCalls:0,maxReservedTokens:0};task.status="running";await writeJson(path.join(dir,"task.json"),task);for(const section of packMemoryImportSections(source.sections).flat()){const item=task.items.find(item2=>item2.id===section.id);if(item.status!=="pending")continue;if(await exists(path.join(dir,"cancel.json")))controller.abort();if(controller.signal.aborted)break;try{this.options.assertActive();Object.assign(item,await this.importSection(section,id,signal,(before,ledger,proposalSignal)=>this.prepareProposal(section,source,task,before,ledger,proposalSignal),async()=>{if(await exists(path.join(dir,"cancel.json")))controller.abort();controller.signal.throwIfAborted();this.options.assertActive()}))}catch(error){if(controller.signal.aborted)break;item.status="failed";item.reason=error instanceof ImportBudgetError||error instanceof ImportContextError?error.message:"Import could not finish. Existing memories were preserved; retry after resolving runtime, model or storage availability."}task.updatedAt=new Date().toISOString();await writeJson(path.join(dir,"task.json"),task)}task.status=controller.signal.aborted?"cancelled":task.items.some(item=>item.status==="failed")?"partial":"completed";task.updatedAt=new Date().toISOString();await writeJson(path.join(dir,"task.json"),task)},controller.signal)}async prepareProposal(section,source,task,before,ledger,signal){const dir=this.taskDir(task.id);const journalFile=path.join(dir,"proposals.json");const journals=await exists(journalFile)?await this.readState(journalFile):[];let journal=journals.find(entry=>entry.scope===section.scope&&entry.sections.some(item=>item.id===section.id));if(journal&&!respectsImportScope(journal.proposal.items.find(item=>item.id===section.id),section.scope)){journal.sections=journal.sections.filter(item=>item.id!==section.id);journal.proposal.items=journal.proposal.items.filter(item=>item.id!==section.id);if(!journal.sections.length)journals.splice(journals.indexOf(journal),1);await writeJson(journalFile,journals);journal=void 0}if(!journal){const eligible=source.sections.filter(candidate=>candidate.scope===section.scope&&candidate.groupId===section.groupId&&task.items.some(item=>item.id===candidate.id&&item.status==="pending")&&!ledger[candidate.id]&&!journals.some(entry=>entry.sections.some(item=>item.id===candidate.id)));const batch=packMemoryImportSections(eligible).find(items=>items.some(item=>item.id===section.id));if(!batch)throw new Error("Source batch is unavailable.");const input={scope:section.scope,sources:batch.map(({id,content})=>({id,content})),existing:selectImportContext(before.existing,batch.map(item=>item.content))};const reserved=memoryImportReservation(input);if(task.usage.modelCalls>=Math.min(task.budget.maxCalls,MEMORY_IMPORT_BUDGET.maxCalls)||task.usage.reservedTokens+reserved>Math.min(task.budget.maxReservedTokens,MEMORY_IMPORT_BUDGET.maxReservedTokens))throw new ImportBudgetError("Import budget exhausted. Retry preserves this budget; split remaining sources into an explicitly confirmed new task.");signal.throwIfAborted();task.usage.modelCalls++;task.usage.reservedTokens+=reserved;await writeJson(path.join(dir,"task.json"),task);let proposal;try{proposal=validateMemoryImportBatchProposal(await abortable(signal,()=>this.options.propose(input,signal)),batch.map(item=>item.id));if(proposal.items.some(item=>!respectsImportScope(item,section.scope)))throw new ImportContextError("Model returned project knowledge for user memory. Retry to request a scope-valid response; consumed budget is retained.")}catch(error){if(!signal.aborted){for(const item of task.items)if(batch.some(section2=>section2.id===item.id)){item.status="failed";item.reason="Model batch failed validation or execution; explicit retry retains its consumed budget."}}throw error}signal.throwIfAborted();journal={scope:section.scope,sections:batch.map(item=>({id:item.id,key:item.id})),baseline:before.existing.map(item=>({ref:item.ref,digest:digest(item.content)})),proposal};journals.push(journal);await writeJson(journalFile,journals)}const expected=new Map(journal.baseline.map(item=>[item.ref,item.digest]));for(const record of Object.values(ledger)){if(record.phase==="committed")for(const output of record.outputs){const ref=`${section.scope}:${output.relativePath}`;if(!expected.has(ref))expected.set(ref,output.digest)}}if(expected.size!==before.existing.length||before.existing.some(item=>expected.get(item.ref)!==digest(item.content)))return{decision:"conflict",reason:"Existing memory changed since this batch was consolidated; retained proposals cannot overwrite edits or restore forgotten knowledge.",documents:[]};return journal.proposal.items.find(item=>item.id===section.id)}async snapshot(scope){const snapshot=await scanAutoMemorySnapshot(this.options.projectRoot,{scopes:[scope],trustedProject:true,uncapped:true});if(!snapshot.sourceStatus.complete)throw new Error("Existing memory scan is incomplete.");const existing=[];for(const doc of snapshot.docs)existing.push({ref:`${scope}:${doc.relativePath}`,content:await fs.readFile(doc.filePath,"utf8")});existing.sort((a,b)=>a.ref.localeCompare(b.ref));return{version:digest(JSON.stringify(existing)),existing}}async importSection(section,batchId,signal,propose,assertCommit){const root=section.scope==="user"?getUserAutoMemoryRoot():getImportedProjectMemoryRoot(this.options.projectRoot,true);const scopeState=path.join(this.state,"scopes",digest(root));return this.locked(scopeState,async signal2=>{signal2.throwIfAborted();this.options.assertActive();if(await exists(root)&&(await fs.lstat(root)).isSymbolicLink())throw new ImportContextError("Memory import does not support a symlinked memory root. Use a non-symlink memory root before retrying; existing memories were not changed.");const ledgerPath=path.join(scopeState,"ledger.json");const ledger=await exists(ledgerPath)?await this.readState(ledgerPath):{};const key=section.id;let previous=ledger[key];const discardUnpublishedIntent=__name(async stage2=>{signal2.throwIfAborted();this.options.assertActive();delete ledger[key];await writeJson(ledgerPath,ledger);heldLocks.getStore()?.throwIfAborted();await fs.rm(stage2,{recursive:true,force:true})},"discardUnpublishedIntent");const outcome=__name((status,reason)=>({id:section.id,scope:section.scope,status,...reason?{reason}:{}}),"outcome");if(previous?.phase==="intent"){const stage2=path.join(scopeState,previous.stage);if(await exists(stage2)&&!await exists(path.join(root,"imported",key))&&(await this.snapshot(section.scope)).version!==previous.memoryVersion){await discardUnpublishedIntent(stage2);previous=void 0}}if(previous){const stage2=path.join(scopeState,previous.stage);const destination=path.join(root,"imported",key);if(previous.phase==="intent"&&await exists(stage2)&&!await exists(destination)){for(const output of previous.outputs){const file=path.join(stage2,path.basename(output.relativePath));if(digest(await fs.readFile(file,"utf8"))!==output.digest)throw new Error("Invalid staged import.")}signal2.throwIfAborted();this.options.assertActive();await privateDirectory(path.join(root,"imported"),this.base);signal2.throwIfAborted();this.options.assertActive();await assertCommit();heldLocks.getStore()?.throwIfAborted();await fs.rename(stage2,destination)}for(const output of previous.outputs){const file=await resolveTrustedMemoryFile(root,getMemoryRootTrustedAnchor(root),output.relativePath);if(!file||digest(await fs.readFile(file,"utf8"))!==output.digest)return outcome("conflict","Previously imported memory was edited or forgotten; it will not be restored.")}previous.phase="committed";await writeJson(ledgerPath,ledger);await rebuildAutoMemoryIndexAtRoot(root,section.scope);if(previous.batchId===batchId)return{...previous.outcome,id:section.id,scope:section.scope};return outcome(previous.outcome.status==="added"?"duplicate":previous.outcome.status,"This source has already been processed.")}const before=await this.snapshot(section.scope);const proposal=await propose(before,ledger,signal2);signal2.throwIfAborted();this.options.assertActive();if((await this.snapshot(section.scope)).version!==before.version)return outcome("conflict","Existing memory changed during consolidation; preview and retry the source.");await assertCommit();if(proposal.decision==="conflict")return outcome("conflict",proposal.reason);if(proposal.decision!=="new"){const result2=outcome(proposal.decision==="skip"?"skipped":"duplicate",proposal.reason);ledger[key]={batchId,phase:"committed",outputs:[],stage:"",outcome:result2};await writeJson(ledgerPath,ledger);return result2}const documents=[];for(const content of new Set(proposal.documents)){const parsed=parseAutoMemoryTopicDocument("import.md",content);if(!parsed)throw new Error("Invalid native memory.");if(section.scope==="user"&&parsed.type!=="user"&&parsed.type!=="feedback")throw new Error("Project knowledge cannot be imported into user memory.");const bodyDigest=digest(parsed.body.trim());for(const[sourceId,record]of Object.entries(ledger)){if(record.outputs.some(output=>output.bodyDigest===bodyDigest)){if(record.phase==="intent"&&!await exists(path.join(root,"imported",sourceId)))continue;for(const output of record.outputs){const file=await resolveTrustedMemoryFile(root,getMemoryRootTrustedAnchor(root),output.relativePath);if(!file||digest(await fs.readFile(file,"utf8"))!==output.digest)return outcome("conflict","Previously edited or forgotten imported knowledge cannot be recreated.")}}}if(before.existing.some(existing=>parseAutoMemoryTopicDocument("existing.md",existing.content)?.body.trim()===parsed.body.trim()))continue;if(!documents.some(existing=>parseAutoMemoryTopicDocument("new.md",existing)?.body.trim()===parsed.body.trim()))documents.push(content)}if(!documents.length){const result2=outcome("duplicate","All proposed knowledge already exists.");ledger[key]={batchId,phase:"committed",outputs:[],stage:"",outcome:result2};await writeJson(ledgerPath,ledger);return result2}const stageName=`stage-${key}`;const stage=path.join(scopeState,stageName);if(await exists(stage)){await privateDirectory(stage,this.base);await fs.rm(stage,{recursive:true})}await privateDirectory(stage,this.base);const outputs=[];for(const[index,content]of documents.entries()){const filename=`${index}.md`;await fs.writeFile(path.join(stage,filename),content,{flag:"wx",mode:384});outputs.push({relativePath:`imported/${key}/${filename}`,digest:digest(content),bodyDigest:digest(parseAutoMemoryTopicDocument("import.md",content).body.trim())})}const result={...outcome("added",proposal.reason),refs:outputs.map(output=>`${section.scope}:${output.relativePath}`)};ledger[key]={batchId,phase:"intent",outputs,stage:stageName,memoryVersion:before.version,outcome:result};await writeJson(ledgerPath,ledger);signal2.throwIfAborted();this.options.assertActive();await privateDirectory(path.join(root,"imported"),this.base);signal2.throwIfAborted();this.options.assertActive();if((await this.snapshot(section.scope)).version!==before.version){await discardUnpublishedIntent(stage);return outcome("conflict","Existing memory changed before publication.")}await assertCommit();heldLocks.getStore()?.throwIfAborted();await fs.rename(stage,path.join(root,"imported",key));ledger[key].phase="committed";await writeJson(ledgerPath,ledger);await rebuildAutoMemoryIndexAtRoot(root,section.scope);return result},signal)}};export{MemoryImportNotFoundError,MemoryImportService};
|
|
4
4
|
/**
|
|
5
5
|
* @license
|
|
6
6
|
* Copyright 2026 Qwen Team
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
import{resolvePolicyToolSettings}from"./chunk-IV3HAIUN.js";import{MEDIA_MEMORY_FILE_NAME}from"./chunk-XFMPZINJ.js";import{DEFAULT_OMNI_PROCESSING_LIMITS,conditionUsesNamespace,evaluateFixedPolicyCondition}from"./chunk-HN5UYLPU.js";import{OmniJsonCacheFile}from"./chunk-AMGUAA4G.js";import{OBJECT_EXTENSION_RE}from"./chunk-YFTVFH2A.js";import{extensionForMime,hashFileSha256,recognizeMediaFile}from"./chunk-ZBHL2CXR.js";import{createDebugLogger}from"./chunk-JAUJI56S.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();var AUDIO_TOKENS_PER_SECOND=7;var VISUAL_PIXELS_PER_TOKEN=32*32*2;function usable(value){return value!==void 0&&Number.isFinite(value)&&value>0}__name(usable,"usable");function estimateRawResourceTokens(media){const unavailable={estimatedTokenCount:0,method:"raw-resource-v1",status:"unavailable"};switch(media.modality){case"audio":{const durationMs=media.metadata.durationMs;if(!usable(durationMs))return unavailable;return{estimatedTokenCount:Math.ceil(durationMs/1e3*AUDIO_TOKENS_PER_SECOND),method:"raw-resource-v1",status:"ok"}}case"image":{const{width,height,frameCount}=media.metadata;if(!usable(width)||!usable(height))return unavailable;const frames=usable(frameCount)?frameCount:1;return{estimatedTokenCount:Math.ceil(width*height*frames/VISUAL_PIXELS_PER_TOKEN),method:"raw-resource-v1",status:"ok"}}case"video":{const{width,height,durationMs,frameRate}=media.metadata;if(!usable(width)||!usable(height)||!usable(durationMs)||!usable(frameRate)){return unavailable}const frameCount=Math.ceil(durationMs/1e3*frameRate);return{estimatedTokenCount:Math.ceil(width*height*frameCount/VISUAL_PIXELS_PER_TOKEN),method:"raw-resource-v1",status:"ok"}}default:return unavailable}}__name(estimateRawResourceTokens,"estimateRawResourceTokens");init_esbuild_shims();import{createHash}from"node:crypto";import path from"node:path";var MAX_CACHED_DISCLOSURE_LENGTH=2048;var FINGERPRINT_EXCLUDED_KEYS=new Set(["inputPath","outputDir","resourceId"]);function stableStringify(value){if(Array.isArray(value)){return`[${value.map(stableStringify).join(",")}]`}if(typeof value==="object"&&value!==null){const record=value;const body=Object.keys(record).sort().map(k=>`${JSON.stringify(k)}:${stableStringify(record[k])}`).join(",");return`{${body}}`}return JSON.stringify(value)??"null"}__name(stableStringify,"stableStringify");function computePolicyFingerprint(toolName,args,toolVersion="1"){const tunables={};for(const[k,v]of Object.entries(args)){if(!FINGERPRINT_EXCLUDED_KEYS.has(k)&&v!==void 0){tunables[k]=v}}return createHash("sha256").update(`${toolName}
|
|
4
4
|
${stableStringify(tunables)}
|
|
5
|
-
${toolVersion}`).digest("hex")}__name(computePolicyFingerprint,"computePolicyFingerprint");var OmniDegradationCache=class{static{__name(this,"OmniDegradationCache")}file;constructor(omniRootDir){this.file=new OmniJsonCacheFile(path.join(omniRootDir,"policy-cache.json"),"omni:policy-cache")}key(originalSha256,policyFingerprint){return`${originalSha256}|${policyFingerprint}`}async get(originalSha256,policyFingerprint){return this.file.access(null,entries=>{const key=this.key(originalSha256,policyFingerprint);const entry=entries[key];if(!entry)return{result:null};if(!/^[0-9a-f]{64}$/.test(entry.degradedSha256)||typeof entry.extension!=="string"||!OBJECT_EXTENSION_RE.test(entry.extension)||typeof entry.disclosure!=="string"||entry.disclosure.length===0||entry.disclosure.length>MAX_CACHED_DISCLOSURE_LENGTH||typeof entry.mimeType!=="string"||entry.mimeType.length===0||entry.role!==void 0&&(typeof entry.role!=="string"||entry.role.length===0)){delete entries[key];return{result:null,changed:true}}return{result:entry}})}async put(originalSha256,policyFingerprint,entry){return this.file.access(void 0,entries=>{entries[this.key(originalSha256,policyFingerprint)]={...entry,createdAt:new Date().toISOString()};return{result:void 0,changed:true}})}async removeByOriginalSha256(originalSha256){return this.file.access(void 0,entries=>{const prefix=`${originalSha256}|`;let changed=false;for(const k of Object.keys(entries)){if(k.startsWith(prefix)){delete entries[k];changed=true}}return{result:void 0,changed}})}async removeByDegradedSha256(degradedSha256){return this.file.access(void 0,entries=>{let changed=false;for(const[k,v]of Object.entries(entries)){if(v.degradedSha256===degradedSha256){delete entries[k];changed=true}}return{result:void 0,changed}})}};init_esbuild_shims();var DEFAULT_OMNI_MAX_UPLOAD_FILE_BYTES=1024*1024*1024;var OmniTransportGuardError=class extends Error{static{__name(this,"OmniTransportGuardError")}sessionResourceId;constructor(message,options){super(message,options);this.name="OmniTransportGuardError"}};function effectiveMaxUploadFileBytes(config){const configured=config.getOmniMaxUploadFileBytes?.();return configured!==void 0&&configured>0?configured:DEFAULT_OMNI_MAX_UPLOAD_FILE_BYTES}__name(effectiveMaxUploadFileBytes,"effectiveMaxUploadFileBytes");function assertWithinByteLimit(config,sizeBytes,displayName){const maxBytes=effectiveMaxUploadFileBytes(config);if(sizeBytes>maxBytes){throw new OmniTransportGuardError(`${displayName} exceeds the omni upload limit: ${sizeBytes} bytes > ${maxBytes} bytes (omni.processing.transportGuard.maxUploadFileBytes). Reduce the file size before retrying.`)}}__name(assertWithinByteLimit,"assertWithinByteLimit");function assertWithinDurationLimit(config,media,displayName){const maxSeconds=config.getOmniMaxDurationSeconds?.();if(maxSeconds===void 0||maxSeconds<=0)return;const durationMs=media.metadata.durationMs;if(durationMs===void 0||!Number.isFinite(durationMs))return;const seconds=durationMs/1e3;if(seconds>maxSeconds){throw new OmniTransportGuardError(`${displayName} exceeds the omni duration limit: ${Math.round(seconds)}s > ${maxSeconds}s (omni.processing.transportGuard.maxDurationSeconds). Clip a shorter span \u2014 downscaling cannot bring a long file within a duration limit.`)}}__name(assertWithinDurationLimit,"assertWithinDurationLimit");function assertWithinTokenLimit(config,media,displayName){const estimate=estimateRawResourceTokens(media);const maxTokens=config.getOmniMaxEstimatedTokens?.();if(maxTokens===void 0||maxTokens<=0)return estimate;if(estimate.status!=="ok")return estimate;if(estimate.estimatedTokenCount>maxTokens){throw new OmniTransportGuardError(`${displayName} exceeds the omni estimated-token limit: ~${estimate.estimatedTokenCount} tokens (${estimate.method}) > ${maxTokens} (omni.processing.transportGuard.maxEstimatedTokens). Reduce duration/resolution or raise the limit.`)}return estimate}__name(assertWithinTokenLimit,"assertWithinTokenLimit");init_esbuild_shims();import fs from"node:fs/promises";import path2 from"node:path";var debugLogger=createDebugLogger("omni:gc");var OBJECT_NAME_RE=/^([0-9a-f]{64})\.[A-Za-z0-9][A-Za-z0-9.]*$/;var SKIPPED={ran:false,deletedObjects:0,deletedBytes:0,remainingBytes:0,derivationsSuspended:false};var gcOnce=new Map;var suspendedRoots=new Set;function effectiveOmniStorageMaxTotalBytes(config){const configured=config.getOmniStorageMaxTotalBytes();const floor=10*effectiveMaxUploadFileBytes(config);if(configured<floor){debugLogger.warn(`omni.storage.maxTotalBytes (${configured}) is below 10\xD7 the transport guard's single-media limit; using ${floor} bytes instead (the budget must hold at least ten normal uploads).`);return floor}return configured}__name(effectiveOmniStorageMaxTotalBytes,"effectiveOmniStorageMaxTotalBytes");function isOmniDerivationSuspended(omniRootDir){return suspendedRoots.has(path2.resolve(omniRootDir))}__name(isOmniDerivationSuspended,"isOmniDerivationSuspended");async function settleOmniGc(omniRootDir){const existing=gcOnce.get(path2.resolve(omniRootDir));if(existing)await existing}__name(settleOmniGc,"settleOmniGc");async function isRealDirectory(p){try{return(await fs.lstat(p)).isDirectory()}catch{return false}}__name(isRealDirectory,"isRealDirectory");async function listObjects(objectsDir){const out=[];if(!await isRealDirectory(objectsDir))return out;let shards;try{shards=await fs.readdir(objectsDir)}catch{return out}for(const shard of shards){const shardDir=path2.join(objectsDir,shard);if(!await isRealDirectory(shardDir))continue;let names;try{names=await fs.readdir(shardDir)}catch{continue}for(const name of names){const match=OBJECT_NAME_RE.exec(name);if(!match)continue;const filePath=path2.join(shardDir,name);try{const st=await fs.lstat(filePath);if(!st.isFile())continue;out.push({sha256:match[1],filePath,mtimeMs:st.mtimeMs,sizeBytes:st.size})}catch{}}}return out}__name(listObjects,"listObjects");async function deleteObject(object,options){try{await fs.rm(object.filePath,{force:true})}catch(err){debugLogger.debug(`gc: failed to delete ${object.sha256}: ${err instanceof Error?err.message:err}`);return false}try{await options.uploadCache?.removeBySha256(object.sha256)}catch{}try{await options.degradationCache?.removeByOriginalSha256(object.sha256);await options.degradationCache?.removeByDegradedSha256(object.sha256)}catch{}debugLogger.debug(`gc: deleted unreferenced object ${object.sha256} (${object.sizeBytes} bytes)`);return true}__name(deleteObject,"deleteObject");function runOmniGcOnce(options){const rootKey=path2.resolve(options.store.getOmniRootDir());const existing=gcOnce.get(rootKey);if(existing)return existing;const run=sweep(options,rootKey).catch(err=>{debugLogger.debug(`gc: run failed, skipped: ${err instanceof Error?err.message:err}`);return SKIPPED});gcOnce.set(rootKey,run);return run}__name(runOmniGcOnce,"runOmniGcOnce");async function recentlyRecoveredFromCorruption(omniRootDir,retentionDays,nowMs){const prefix=`${MEDIA_MEMORY_FILE_NAME}.corrupt-`;let names;try{names=await fs.readdir(omniRootDir)}catch{return false}const cutoff=nowMs-retentionDays*24*36e5;for(const name of names){if(!name.startsWith(prefix))continue;const stamp=Number(name.slice(prefix.length));if(Number.isFinite(stamp)&&stamp>=cutoff)return true;try{const st=await fs.lstat(path2.join(omniRootDir,name));if(st.mtimeMs>=cutoff)return true}catch{return true}}return false}__name(recentlyRecoveredFromCorruption,"recentlyRecoveredFromCorruption");async function sweep(options,rootKey){const nowMsForGuard=options.nowMs??Date.now();const refs=await options.memoryService.collectManagedRefs();if(refs===null){debugLogger.debug("gc: memory snapshot unreadable, skipping run");return SKIPPED}if(await recentlyRecoveredFromCorruption(options.store.getOmniRootDir(),options.retentionDays,nowMsForGuard)){debugLogger.debug("gc: memory ledger recently recovered from corruption, skipping run");return SKIPPED}const objectsDir=options.store.getObjectsDir();for(const fileRef of options.registry?.activeFileRefs()??[]){const name=path2.basename(fileRef);const match=OBJECT_NAME_RE.exec(name);if(match&&fileRef.startsWith(objectsDir))refs.add(match[1])}const nowMs=options.nowMs??Date.now();const cutoffMs=nowMs-options.retentionDays*24*36e5;const objects=await listObjects(objectsDir);let deletedObjects=0;let deletedBytes=0;const survivors=[];const touchedSinceListing=__name(async(object,freshCutoffMs)=>{try{return(await fs.lstat(object.filePath)).mtimeMs>=freshCutoffMs}catch{return true}},"touchedSinceListing");for(const object of objects){if(refs.has(object.sha256)||object.mtimeMs>=cutoffMs){survivors.push(object);continue}if(await touchedSinceListing(object,cutoffMs)){survivors.push(object);continue}if(await deleteObject(object,options)){deletedObjects+=1;deletedBytes+=object.sizeBytes}else{survivors.push(object)}}let remainingBytes=survivors.reduce((sum,o)=>sum+o.sizeBytes,0);if(remainingBytes>options.maxTotalBytes){const freshRefs=await options.memoryService.collectManagedRefs();if(freshRefs===null){debugLogger.debug("gc: ledger unreadable at budget pass, skipping budget deletions")}else{const unreferenced=survivors.filter(o=>!refs.has(o.sha256)&&!freshRefs.has(o.sha256)).sort((a,b)=>a.mtimeMs-b.mtimeMs);for(const object of unreferenced){if(remainingBytes<=options.maxTotalBytes)break;if(await touchedSinceListing(object,nowMs))continue;if(await deleteObject(object,options)){deletedObjects+=1;deletedBytes+=object.sizeBytes;remainingBytes-=object.sizeBytes}}}}const derivationsSuspended=remainingBytes>options.maxTotalBytes;if(derivationsSuspended){suspendedRoots.add(rootKey);debugLogger.warn(`omni object store over budget with only referenced objects left (${remainingBytes} > ${options.maxTotalBytes} bytes); new policy derivations are suspended for this session. Raise omni.storage.maxTotalBytes or delete memory records you no longer need \u2014 either change takes effect at the next session start (the GC runs once per process).`)}else{suspendedRoots.delete(rootKey)}if(deletedObjects>0){debugLogger.debug(`gc: removed ${deletedObjects} object(s) / ${deletedBytes} bytes; ${remainingBytes} bytes remain`)}return{ran:true,deletedObjects,deletedBytes,remainingBytes,derivationsSuspended}}__name(sweep,"sweep");init_esbuild_shims();import{createHash as createHash2,randomBytes}from"node:crypto";import fs2 from"node:fs/promises";import path3 from"node:path";var debugLogger2=createDebugLogger("omni:policy");var MAX_FILE_ARTIFACT_BYTES=256*1024;var OmniPolicyExecutionError=class extends Error{constructor(message,policyId,options){super(message,options);this.policyId=policyId;this.name="OmniPolicyExecutionError"}static{__name(this,"OmniPolicyExecutionError")}};function resolveArtifactSelector(artifacts,kind,role){if(role!==void 0){const byRole=artifacts[`role:${role}`];if(byRole)return byRole}const byKind=artifacts[`kind:${kind}`];if(byKind)return byKind;return artifacts["*"]??"retain"}__name(resolveArtifactSelector,"resolveArtifactSelector");function resourceConditionContext(recognized,shared){const resource={};const set=__name((field,value)=>{if(typeof value==="number"&&!Number.isNaN(value)){resource[field]=value}},"set");const m=recognized.metadata;set("sizeBytes",recognized.sizeBytes);set("durationMs",m.durationMs);set("width",m.width);set("height",m.height);set("maxWidth",m.width);set("maxHeight",m.height);set("frameRate",m.frameRate);set("frameCount",m.frameCount);set("bitRate",m.bitRate);set("sampleRateHz",m.sampleRateHz);set("channels",m.channels);const estimate=estimateRawResourceTokens(recognized);if(estimate.status==="ok"){set("estimatedTokenCount",estimate.estimatedTokenCount)}return{resource,...shared}}__name(resourceConditionContext,"resourceConditionContext");var MEMORY_ROLE_FIELDS={transcript:"hasTranscript",ocr:"hasOcr",caption:"hasCaption",summary:"hasSummary",keyframe:"hasKeyframes",clip:"hasClip"};async function memoryConditionNamespace(memory,binding){if(!memory||!binding)return void 0;const roles=await memory.service.collectVersionOutputRoles(binding);if(!roles)return void 0;const namespace={};for(const field of Object.values(MEMORY_ROLE_FIELDS)){namespace[field]=0}for(const role of roles){const field=MEMORY_ROLE_FIELDS[role];if(field)namespace[field]=1}return namespace}__name(memoryConditionNamespace,"memoryConditionNamespace");function requestConditionNamespace(items){let total=0;for(const item of items){if(!item.deliver)continue;const estimate=estimateRawResourceTokens(item.recognized);if(estimate.status!=="ok")return void 0;total+=estimate.estimatedTokenCount}return{totalEstimatedMediaTokens:total}}__name(requestConditionNamespace,"requestConditionNamespace");function sortPolicies(policies){return[...policies].sort((a,b)=>b.priority-a.priority||a.id.localeCompare(b.id))}__name(sortPolicies,"sortPolicies");var resourceGates=new Map;async function acquireResourceSlot(rootDir,limit){const effectiveLimit=Math.max(1,Math.floor(limit));let gate=resourceGates.get(rootDir);if(!gate){gate={active:0,waiters:[]};resourceGates.set(rootDir,gate)}const heldGate=gate;if(heldGate.active>=effectiveLimit){await new Promise(resolve=>heldGate.waiters.push(resolve))}else{heldGate.active++}let released=false;return()=>{if(released)return;released=true;const next=heldGate.waiters.shift();if(next){next();return}heldGate.active--;if(heldGate.active===0&&heldGate.waiters.length===0){resourceGates.delete(rootDir)}}}__name(acquireResourceSlot,"acquireResourceSlot");async function runFixedPolicies(config,source,options){const policies=sortPolicies(options.policies);const limits=options.limits??DEFAULT_OMNI_PROCESSING_LIMITS;const releaseSlot=await acquireResourceSlot(options.store.getOmniRootDir(),limits.maxConcurrentResources);try{return await runFixedPoliciesUnbounded(config,source,options,{policies,limits})}finally{releaseSlot()}}__name(runFixedPolicies,"runFixedPolicies");async function runFixedPoliciesUnbounded(config,source,options,normalized){const{policies,limits}=normalized;const cache=options.degradationCache??new OmniDegradationCache(options.store.getOmniRootDir());const records=[];const fileDeliveries=[];const items=[{filePath:source.filePath,recognized:source.recognized,label:source.displayName,origin:source.origin,sha256:source.sha256,memoryBinding:options.memory?.sourceBinding,lineageRuns:new Map,depth:0,deliver:true,process:true}];let runsUsed=0;let artifactsProduced=0;let derivedBytesProduced=0;let budgetExhausted=false;const stopOnBudget=__name((policy,item,reason)=>{budgetExhausted=true;records.push({policyId:policy.id,toolName:policy.toolName,outcome:"budget_exhausted",resource:item.label,error:reason});debugLogger2.debug(`per-root policy budget exhausted on ${item.label}: ${reason}; no further derivation for this root (committed deliveries stand)`)},"stopOnBudget");for(let i=0;i<items.length&&!budgetExhausted;i++){const item=items[i];if(!item.process)continue;if(item.recognized.modality==="image"&&(item.recognized.metadata.frameCount??1)>1){debugLogger2.debug(`animated image ${item.label} (${item.recognized.metadata.frameCount} frames) excluded from policy matching (D9)`);continue}const needsMemoryNamespace=policies.some(policy=>policy.when&&conditionUsesNamespace(policy.when,"memory"));const sharedConditionContext={request:options.conditionContext?.request??requestConditionNamespace(items),session:options.conditionContext?.session,memory:needsMemoryNamespace?await memoryConditionNamespace(options.memory,item.memoryBinding):void 0};for(const policy of policies){if(!policy.mediaTypes.includes(item.recognized.modality))continue;if(!policy.origins.includes(item.origin))continue;const runs=item.lineageRuns.get(policy.id)??0;if(runs>=policy.maxRunsPerLineage)continue;if(policy.when){const evaluation=evaluateFixedPolicyCondition(policy.when,resourceConditionContext(item.recognized,sharedConditionContext));if(evaluation.outcome==="no_match")continue;if(evaluation.outcome==="unavailable"&&policy.onConditionUnavailable==="skip"){records.push({policyId:policy.id,toolName:policy.toolName,outcome:"condition_unavailable",resource:item.label,missingFields:evaluation.missingFields});continue}}if(runsUsed>=limits.maxPolicyRunsPerRoot){stopOnBudget(policy,item,`maxPolicyRunsPerRoot (${limits.maxPolicyRunsPerRoot}) reached`);break}runsUsed++;item.lineageRuns.set(policy.id,runs+1);try{const execution=await executePolicy(config,item,policy,options.store,cache,options.signal,options.memory&&item.memoryBinding?{service:options.memory.service,source:item.memoryBinding}:void 0);records.push({policyId:policy.id,toolName:policy.toolName,outcome:execution.outcome,resource:item.label});if(execution.outcome==="no_op")continue;if(policy.output.source==="omit")item.deliver=false;const childDepth=item.depth+1;const depthAllowsReprocess=childDepth<limits.maxLineageDepth;if(policy.output.reprocessMedia&&!depthAllowsReprocess){debugLogger2.debug(`maxLineageDepth (${limits.maxLineageDepth}) reached under ${item.label}; derivatives deliver but do not re-enter policy matching`)}for(const derived of execution.derived){artifactsProduced++;derivedBytesProduced+=derived.recognized.sizeBytes;items.push({...derived,label:`${item.label} \u2192 ${policy.id}`,origin:"policy",lineageRuns:new Map(item.lineageRuns),depth:childDepth,deliver:resolveArtifactSelector(policy.output.artifacts,derived.recognized.modality,derived.role)==="include",process:policy.output.reprocessMedia&&depthAllowsReprocess})}for(const file of execution.derivedFiles){artifactsProduced++;derivedBytesProduced+=file.sizeBytes;if(resolveArtifactSelector(policy.output.artifacts,"file",file.role)==="include"){fileDeliveries.push(file)}}if(artifactsProduced>limits.maxArtifactsPerRoot){stopOnBudget(policy,item,`maxArtifactsPerRoot (${limits.maxArtifactsPerRoot}) exceeded`);break}if(derivedBytesProduced>limits.maxDerivedBytesPerRoot){stopOnBudget(policy,item,`maxDerivedBytesPerRoot (${limits.maxDerivedBytesPerRoot}) exceeded`);break}}catch(err){if(options.signal?.aborted)throw err;const message=err instanceof Error?err.message:String(err);records.push({policyId:policy.id,toolName:policy.toolName,outcome:"failed",resource:item.label,error:message});debugLogger2.debug(`fixed policy ${policy.id} (${policy.toolName}) failed on ${item.label}: ${message}`);if(policy.onFailure==="abort"||policy.stage==="transport_guard"){throw new OmniPolicyExecutionError(`Fixed policy ${policy.id} failed: ${message}`,policy.id,{cause:err})}}}}return{deliveries:items.filter(item=>item.deliver).map(item=>({filePath:item.filePath,recognized:item.recognized,sha256:item.sha256,disclosure:item.disclosure,degraded:item.degraded,memoryBinding:item.memoryBinding})),fileDeliveries,records}}__name(runFixedPoliciesUnbounded,"runFixedPoliciesUnbounded");async function executePolicy(config,item,policy,store,cache,signal,memory){const tool=config.getToolRegistry().getTool(policy.toolName);const descriptor=tool?.mediaPolicyDescriptor;if(!descriptor){throw new Error(`tool ${policy.toolName} is not a registered media-policy tool`)}item.sha256??=await hashFileSha256(item.filePath,signal);const settingsDefaults=resolvePolicyToolSettings(config,policy.toolName);const effectiveArguments={...settingsDefaults,...policy.arguments};const fingerprint=computePolicyFingerprint(policy.toolName,effectiveArguments,descriptor.version);const startedAt=new Date().toISOString();if(memory){const reusable=await memory.service.findReusableOutputs(item.sha256,fingerprint);const rebuilt=reusable?await rebuildReusedOutputs(reusable,descriptor,store,signal):void 0;if(rebuilt){debugLogger2.debug(`memory reuse hit: policy=${policy.id} sha256=${item.sha256.slice(0,12)}\u2026 outputs=${rebuilt.outputs.length} (tool not executed)`);const commit=await memory.service.commitPolicySucceeded({invocationId:"memory-reuse",source:memory.source,executionOrigin:{kind:"fixed_policy",policyId:policy.id,stage:policy.stage},toolName:policy.toolName,toolVersion:descriptor.version,finalArguments:effectiveArguments,omniConfigHash:fingerprint,startedAt,completedAt:new Date().toISOString(),outputs:rebuilt.outputs});return{outcome:"succeeded",derived:rebuilt.derived.map(d=>({...d,memoryBinding:commit?.mediaBindings.get(d.sha256)})),derivedFiles:rebuilt.derivedFiles}}}const hit=await cache.get(item.sha256,fingerprint);if(hit){try{const objectPath=store.objectPathFor(hit.degradedSha256,hit.extension);const stat=await fs2.lstat(objectPath).catch(()=>void 0);if(stat?.isFile()&&!stat.isSymbolicLink()){const actualSha256=await hashFileSha256(objectPath,signal);if(actualSha256===hit.degradedSha256){const recognized=await recognizeMediaFile(objectPath,{signal});const declared=descriptor.outputs.some(o=>o.kind==="media"&&o.mimeTypes?.includes(recognized.detectedMimeType));if(declared){debugLogger2.debug(`degradation cache hit: policy=${policy.id} sha256=${item.sha256.slice(0,12)}\u2026`);const commit=memory?await memory.service.commitPolicySucceeded({invocationId:"cache-hit",source:memory.source,executionOrigin:{kind:"fixed_policy",policyId:policy.id,stage:policy.stage},toolName:policy.toolName,toolVersion:descriptor.version,finalArguments:effectiveArguments,omniConfigHash:fingerprint,startedAt,completedAt:new Date().toISOString(),outputs:[{kind:"media",objectPath,sha256:hit.degradedSha256,mediaType:recognized.modality,metadata:recognized.metadata,sizeBytes:recognized.sizeBytes,mimeType:recognized.detectedMimeType,role:hit.role,disclosure:hit.disclosure}]}):void 0;return{outcome:"cache_hit",derived:[{filePath:objectPath,recognized,sha256:hit.degradedSha256,disclosure:hit.disclosure,degraded:true,role:hit.role,memoryBinding:commit?.mediaBindings.get(hit.degradedSha256)}],derivedFiles:[]}}debugLogger2.debug(`degradation cache hit for policy=${policy.id} recognized as undeclared media type ${recognized.detectedMimeType}; dropping the entry and re-transcoding`)}}}catch(err){if(signal?.aborted)throw err;debugLogger2.debug(`degradation cache hit could not be verified for policy=${policy.id}: ${err instanceof Error?err.message:String(err)}; dropping the entry and re-transcoding`)}await cache.removeByDegradedSha256(hit.degradedSha256)}await settleOmniGc(store.getOmniRootDir());if(isOmniDerivationSuspended(store.getOmniRootDir())){throw new Error(`omni object store is over its byte budget with only memory-referenced objects left; new policy derivations are suspended. Raise omni.storage.maxTotalBytes or delete memory records you no longer need, then start a new session \u2014 the budget is re-evaluated once per process.`)}const invocationId=randomBytes(8).toString("hex");const stagingDir=await store.createStagingDir(invocationId);let failure;try{const request={callId:invocationId,name:policy.toolName,args:{...effectiveArguments,inputPath:item.filePath,outputDir:stagingDir},isClientInitiated:true,prompt_id:`omni-fixed-policy-${invocationId}`,executionOrigin:{kind:"fixed_policy",policyId:policy.id,stage:policy.stage}};const{executeToolCall}=await import("./nonInteractiveToolExecutor-B4EUOMYF.js");const response=await executeToolCall(config,request,signal??new AbortController().signal,{recordToolResult:false});if(response.error){throw new Error(response.error.message,{cause:response.error})}const batch=response.policyArtifacts;if(!batch||batch.artifacts.length===0){throw new Error(`tool ${policy.toolName} succeeded but produced no policy artifacts`)}const validated=await Promise.all(batch.artifacts.map(artifact=>validateArtifact(artifact,descriptor,stagingDir,signal)));assertRequiredOutputsPresent(descriptor,validated,policy.toolName);if(validated.every(a=>a.sha256===item.sha256)){return{outcome:"no_op",derived:[],derivedFiles:[]}}const promoted=await Promise.all(validated.map(async artifact=>{const mimeType=artifact.kind==="media"?artifact.recognized.detectedMimeType:artifact.mimeType;const put=await store.putFile(artifact.absolutePath,artifact.sha256,extensionForMime(mimeType),signal);return{artifact,objectPath:put.objectPath}}));const derived=[];const derivedFiles=[];for(const{artifact,objectPath}of promoted){if(artifact.kind==="media"){derived.push({filePath:objectPath,recognized:artifact.recognized,sha256:artifact.sha256,disclosure:artifact.disclosure,degraded:artifact.lossy,role:artifact.role})}else{derivedFiles.push({filePath:objectPath,role:artifact.role,mimeType:artifact.mimeType,text:artifact.text,sha256:artifact.sha256,sizeBytes:artifact.sizeBytes,disclosure:artifact.disclosure})}}if(memory){const outputs=promoted.map(({artifact,objectPath})=>artifact.kind==="media"?{kind:"media",objectPath,sha256:artifact.sha256,mediaType:artifact.recognized.modality,metadata:artifact.recognized.metadata,sizeBytes:artifact.recognized.sizeBytes,mimeType:artifact.recognized.detectedMimeType,role:artifact.role,disclosure:artifact.disclosure}:{kind:"text",objectPath,sha256:artifact.sha256,mimeType:artifact.mimeType,text:artifact.text,sizeBytes:artifact.sizeBytes,role:artifact.role,disclosure:artifact.disclosure});const commit=await memory.service.commitPolicySucceeded({invocationId,source:memory.source,executionOrigin:{kind:"fixed_policy",policyId:policy.id,stage:policy.stage},toolName:policy.toolName,toolVersion:descriptor.version,finalArguments:effectiveArguments,omniConfigHash:fingerprint,startedAt,completedAt:new Date().toISOString(),outputs});if(commit){for(const entry of derived){entry.memoryBinding=commit.mediaBindings.get(entry.sha256)}}}if(validated.length===1&&validated[0].kind==="media"&&validated[0].disclosure){await cache.put(item.sha256,fingerprint,{degradedSha256:validated[0].sha256,extension:extensionForMime(validated[0].recognized.detectedMimeType),disclosure:validated[0].disclosure,mimeType:validated[0].recognized.detectedMimeType,...validated[0].role!==void 0?{role:validated[0].role}:{}})}return{outcome:"succeeded",derived,derivedFiles}}catch(err){failure=err;throw err}finally{if(failure===void 0||signal?.aborted){await store.removeStagingDir(invocationId).catch(()=>{})}else{try{await store.quarantineInvocation(invocationId,{policyId:policy.id,toolName:policy.toolName,reason:failure instanceof Error?failure.message:String(failure)})}catch{await store.removeStagingDir(invocationId).catch(()=>{})}}}}__name(executePolicy,"executePolicy");async function rebuildReusedOutputs(reusable,descriptor,store,signal){const outputs=[];const derived=[];const derivedFiles=[];try{for(const record of reusable.outputs){const objectPath=record.objectPath??store.objectPathFor(record.sha256,extensionForMime(record.mimeType));const stat=await fs2.lstat(objectPath).catch(()=>void 0);if(!stat?.isFile()||stat.isSymbolicLink())return void 0;if(await hashFileSha256(objectPath,signal)!==record.sha256){return void 0}if(record.kind==="media"){const recognized=await recognizeMediaFile(objectPath,{signal});const declared=descriptor.outputs.some(o=>o.kind==="media"&&o.mimeTypes?.includes(recognized.detectedMimeType));if(!declared)return void 0;outputs.push({kind:"media",objectPath,sha256:record.sha256,mediaType:recognized.modality,metadata:recognized.metadata,sizeBytes:recognized.sizeBytes,mimeType:recognized.detectedMimeType,role:record.role,disclosure:record.disclosure});derived.push({filePath:objectPath,recognized,sha256:record.sha256,disclosure:record.disclosure,degraded:record.disclosure!==void 0,role:record.role})}else{const text=await fs2.readFile(objectPath,"utf8");outputs.push({kind:"text",objectPath,sha256:record.sha256,mimeType:record.mimeType,text,sizeBytes:record.sizeBytes,role:record.role,disclosure:record.disclosure});derivedFiles.push({filePath:objectPath,role:record.role,mimeType:record.mimeType,text,sha256:record.sha256,sizeBytes:record.sizeBytes,disclosure:record.disclosure})}}}catch(err){if(signal?.aborted)throw err;debugLogger2.debug(`memory reuse could not be verified, re-deriving: ${err instanceof Error?err.message:String(err)}`);return void 0}return{outputs,derived,derivedFiles}}__name(rebuildReusedOutputs,"rebuildReusedOutputs");async function validateArtifact(artifact,descriptor,stagingDir,signal){if(artifact.storage!=="workspace"||!artifact.workspacePath){throw new Error(`policy artifact "${artifact.title}" is not a workspace file`)}const absolutePath=path3.resolve(stagingDir,artifact.workspacePath);if(!absolutePath.startsWith(stagingDir+path3.sep)){throw new Error(`policy artifact "${artifact.title}" escapes the staging directory`)}const stat=await fs2.lstat(absolutePath).catch(()=>void 0);if(!stat?.isFile()||stat.isSymbolicLink()){throw new Error(`policy artifact "${artifact.title}" is missing or not a regular file`)}const rawRole=artifact.metadata?.["omniRole"];const role=typeof rawRole==="string"&&rawRole?rawRole:void 0;const rawDisclosure=artifact.metadata?.["omniDisclosure"];const disclosure=typeof rawDisclosure==="string"&&rawDisclosure?rawDisclosure:void 0;if(artifact.kind==="file"){const spec2=descriptor.outputs.find(o=>o.kind==="file"&&(o.role===void 0||o.role===role)&&artifact.mimeType!==void 0&&o.mimeTypes?.includes(artifact.mimeType));if(!spec2){throw new Error(`policy artifact "${artifact.title}" (file, role ${role??"none"}, ${artifact.mimeType??"no mimeType"}) matches no declared file output`)}if(stat.size>MAX_FILE_ARTIFACT_BYTES){throw new Error(`policy artifact "${artifact.title}" exceeds the file-artifact size budget (${stat.size} > ${MAX_FILE_ARTIFACT_BYTES} bytes)`)}const bytes=await fs2.readFile(absolutePath);let text;try{text=new TextDecoder("utf-8",{fatal:true}).decode(bytes)}catch{throw new Error(`policy artifact "${artifact.title}" is not valid UTF-8 text`)}if(spec2.lossy&&!disclosure){throw new Error(`policy artifact "${artifact.title}" is lossy but carries no omniDisclosure`)}return{kind:"file",absolutePath,mimeType:artifact.mimeType,text,sizeBytes:bytes.byteLength,sha256:createHash2("sha256").update(bytes).digest("hex"),disclosure,lossy:spec2.lossy===true,role}}const recognized=await recognizeMediaFile(absolutePath,{signal});const spec=descriptor.outputs.find(o=>o.kind==="media"&&o.mimeTypes?.includes(recognized.detectedMimeType));if(!spec){throw new Error(`policy artifact "${artifact.title}" has undeclared media type ${recognized.detectedMimeType}`)}if(artifact.kind!==recognized.modality){throw new Error(`policy artifact "${artifact.title}" declares kind ${String(artifact.kind)} but contains ${recognized.modality} content`)}if(spec.lossy&&!disclosure){throw new Error(`policy artifact "${artifact.title}" is lossy but carries no omniDisclosure`)}return{kind:"media",absolutePath,recognized,sha256:await hashFileSha256(absolutePath,signal),disclosure,lossy:spec.lossy===true,role}}__name(validateArtifact,"validateArtifact");function assertRequiredOutputsPresent(descriptor,validated,toolName){for(const spec of descriptor.outputs){if(!spec.required)continue;let produced;if(spec.kind==="media"){produced=validated.some(a=>a.kind==="media"&&spec.mimeTypes?.includes(a.recognized.detectedMimeType))}else if(spec.kind==="file"){produced=validated.some(a=>a.kind==="file"&&(spec.role===void 0||a.role===spec.role)&&spec.mimeTypes?.includes(a.mimeType))}else{continue}if(!produced){throw new Error(`tool ${toolName} did not produce its required ${spec.kind} ${spec.mimeTypes?.join("/")??spec.role??""} output`)}}}__name(assertRequiredOutputsPresent,"assertRequiredOutputsPresent");export{estimateRawResourceTokens,computePolicyFingerprint,OmniDegradationCache,DEFAULT_OMNI_MAX_UPLOAD_FILE_BYTES,OmniTransportGuardError,effectiveMaxUploadFileBytes,assertWithinByteLimit,assertWithinDurationLimit,assertWithinTokenLimit,effectiveOmniStorageMaxTotalBytes,runOmniGcOnce,OmniPolicyExecutionError,runFixedPolicies,validateArtifact,assertRequiredOutputsPresent};
|
|
5
|
+
${toolVersion}`).digest("hex")}__name(computePolicyFingerprint,"computePolicyFingerprint");var OmniDegradationCache=class{static{__name(this,"OmniDegradationCache")}file;constructor(omniRootDir){this.file=new OmniJsonCacheFile(path.join(omniRootDir,"policy-cache.json"),"omni:policy-cache")}key(originalSha256,policyFingerprint){return`${originalSha256}|${policyFingerprint}`}async get(originalSha256,policyFingerprint){return this.file.access(null,entries=>{const key=this.key(originalSha256,policyFingerprint);const entry=entries[key];if(!entry)return{result:null};if(!/^[0-9a-f]{64}$/.test(entry.degradedSha256)||typeof entry.extension!=="string"||!OBJECT_EXTENSION_RE.test(entry.extension)||typeof entry.disclosure!=="string"||entry.disclosure.length===0||entry.disclosure.length>MAX_CACHED_DISCLOSURE_LENGTH||typeof entry.mimeType!=="string"||entry.mimeType.length===0||entry.role!==void 0&&(typeof entry.role!=="string"||entry.role.length===0)){delete entries[key];return{result:null,changed:true}}return{result:entry}})}async put(originalSha256,policyFingerprint,entry){return this.file.access(void 0,entries=>{entries[this.key(originalSha256,policyFingerprint)]={...entry,createdAt:new Date().toISOString()};return{result:void 0,changed:true}})}async removeByOriginalSha256(originalSha256){return this.file.access(void 0,entries=>{const prefix=`${originalSha256}|`;let changed=false;for(const k of Object.keys(entries)){if(k.startsWith(prefix)){delete entries[k];changed=true}}return{result:void 0,changed}})}async removeByDegradedSha256(degradedSha256){return this.file.access(void 0,entries=>{let changed=false;for(const[k,v]of Object.entries(entries)){if(v.degradedSha256===degradedSha256){delete entries[k];changed=true}}return{result:void 0,changed}})}};init_esbuild_shims();var DEFAULT_OMNI_MAX_UPLOAD_FILE_BYTES=1024*1024*1024;var OmniTransportGuardError=class extends Error{static{__name(this,"OmniTransportGuardError")}sessionResourceId;constructor(message,options){super(message,options);this.name="OmniTransportGuardError"}};function effectiveMaxUploadFileBytes(config){const configured=config.getOmniMaxUploadFileBytes?.();return configured!==void 0&&configured>0?configured:DEFAULT_OMNI_MAX_UPLOAD_FILE_BYTES}__name(effectiveMaxUploadFileBytes,"effectiveMaxUploadFileBytes");function assertWithinByteLimit(config,sizeBytes,displayName){const maxBytes=effectiveMaxUploadFileBytes(config);if(sizeBytes>maxBytes){throw new OmniTransportGuardError(`${displayName} exceeds the omni upload limit: ${sizeBytes} bytes > ${maxBytes} bytes (omni.processing.transportGuard.maxUploadFileBytes). Reduce the file size before retrying.`)}}__name(assertWithinByteLimit,"assertWithinByteLimit");function assertWithinDurationLimit(config,media,displayName){const maxSeconds=config.getOmniMaxDurationSeconds?.();if(maxSeconds===void 0||maxSeconds<=0)return;const durationMs=media.metadata.durationMs;if(durationMs===void 0||!Number.isFinite(durationMs))return;const seconds=durationMs/1e3;if(seconds>maxSeconds){throw new OmniTransportGuardError(`${displayName} exceeds the omni duration limit: ${Math.round(seconds)}s > ${maxSeconds}s (omni.processing.transportGuard.maxDurationSeconds). Clip a shorter span \u2014 downscaling cannot bring a long file within a duration limit.`)}}__name(assertWithinDurationLimit,"assertWithinDurationLimit");function assertWithinTokenLimit(config,media,displayName){const estimate=estimateRawResourceTokens(media);const maxTokens=config.getOmniMaxEstimatedTokens?.();if(maxTokens===void 0||maxTokens<=0)return estimate;if(estimate.status!=="ok")return estimate;if(estimate.estimatedTokenCount>maxTokens){throw new OmniTransportGuardError(`${displayName} exceeds the omni estimated-token limit: ~${estimate.estimatedTokenCount} tokens (${estimate.method}) > ${maxTokens} (omni.processing.transportGuard.maxEstimatedTokens). Reduce duration/resolution or raise the limit.`)}return estimate}__name(assertWithinTokenLimit,"assertWithinTokenLimit");init_esbuild_shims();import fs from"node:fs/promises";import path2 from"node:path";var debugLogger=createDebugLogger("omni:gc");var OBJECT_NAME_RE=/^([0-9a-f]{64})\.[A-Za-z0-9][A-Za-z0-9.]*$/;var SKIPPED={ran:false,deletedObjects:0,deletedBytes:0,remainingBytes:0,derivationsSuspended:false};var gcOnce=new Map;var suspendedRoots=new Set;function effectiveOmniStorageMaxTotalBytes(config){const configured=config.getOmniStorageMaxTotalBytes();const floor=10*effectiveMaxUploadFileBytes(config);if(configured<floor){debugLogger.warn(`omni.storage.maxTotalBytes (${configured}) is below 10\xD7 the transport guard's single-media limit; using ${floor} bytes instead (the budget must hold at least ten normal uploads).`);return floor}return configured}__name(effectiveOmniStorageMaxTotalBytes,"effectiveOmniStorageMaxTotalBytes");function isOmniDerivationSuspended(omniRootDir){return suspendedRoots.has(path2.resolve(omniRootDir))}__name(isOmniDerivationSuspended,"isOmniDerivationSuspended");async function settleOmniGc(omniRootDir){const existing=gcOnce.get(path2.resolve(omniRootDir));if(existing)await existing}__name(settleOmniGc,"settleOmniGc");async function isRealDirectory(p){try{return(await fs.lstat(p)).isDirectory()}catch{return false}}__name(isRealDirectory,"isRealDirectory");async function listObjects(objectsDir){const out=[];if(!await isRealDirectory(objectsDir))return out;let shards;try{shards=await fs.readdir(objectsDir)}catch{return out}for(const shard of shards){const shardDir=path2.join(objectsDir,shard);if(!await isRealDirectory(shardDir))continue;let names;try{names=await fs.readdir(shardDir)}catch{continue}for(const name of names){const match=OBJECT_NAME_RE.exec(name);if(!match)continue;const filePath=path2.join(shardDir,name);try{const st=await fs.lstat(filePath);if(!st.isFile())continue;out.push({sha256:match[1],filePath,mtimeMs:st.mtimeMs,sizeBytes:st.size})}catch{}}}return out}__name(listObjects,"listObjects");async function deleteObject(object,options){try{await fs.rm(object.filePath,{force:true})}catch(err){debugLogger.debug(`gc: failed to delete ${object.sha256}: ${err instanceof Error?err.message:err}`);return false}try{await options.uploadCache?.removeBySha256(object.sha256)}catch{}try{await options.degradationCache?.removeByOriginalSha256(object.sha256);await options.degradationCache?.removeByDegradedSha256(object.sha256)}catch{}debugLogger.debug(`gc: deleted unreferenced object ${object.sha256} (${object.sizeBytes} bytes)`);return true}__name(deleteObject,"deleteObject");function runOmniGcOnce(options){const rootKey=path2.resolve(options.store.getOmniRootDir());const existing=gcOnce.get(rootKey);if(existing)return existing;const run=sweep(options,rootKey).catch(err=>{debugLogger.debug(`gc: run failed, skipped: ${err instanceof Error?err.message:err}`);return SKIPPED});gcOnce.set(rootKey,run);return run}__name(runOmniGcOnce,"runOmniGcOnce");async function recentlyRecoveredFromCorruption(omniRootDir,retentionDays,nowMs){const prefix=`${MEDIA_MEMORY_FILE_NAME}.corrupt-`;let names;try{names=await fs.readdir(omniRootDir)}catch{return false}const cutoff=nowMs-retentionDays*24*36e5;for(const name of names){if(!name.startsWith(prefix))continue;const stamp=Number(name.slice(prefix.length));if(Number.isFinite(stamp)&&stamp>=cutoff)return true;try{const st=await fs.lstat(path2.join(omniRootDir,name));if(st.mtimeMs>=cutoff)return true}catch{return true}}return false}__name(recentlyRecoveredFromCorruption,"recentlyRecoveredFromCorruption");async function sweep(options,rootKey){const nowMsForGuard=options.nowMs??Date.now();const refs=await options.memoryService.collectManagedRefs();if(refs===null){debugLogger.debug("gc: memory snapshot unreadable, skipping run");return SKIPPED}if(await recentlyRecoveredFromCorruption(options.store.getOmniRootDir(),options.retentionDays,nowMsForGuard)){debugLogger.debug("gc: memory ledger recently recovered from corruption, skipping run");return SKIPPED}const objectsDir=options.store.getObjectsDir();for(const fileRef of options.registry?.activeFileRefs()??[]){const name=path2.basename(fileRef);const match=OBJECT_NAME_RE.exec(name);if(match&&fileRef.startsWith(objectsDir))refs.add(match[1])}const nowMs=options.nowMs??Date.now();const cutoffMs=nowMs-options.retentionDays*24*36e5;const objects=await listObjects(objectsDir);let deletedObjects=0;let deletedBytes=0;const survivors=[];const touchedSinceListing=__name(async(object,freshCutoffMs)=>{try{return(await fs.lstat(object.filePath)).mtimeMs>=freshCutoffMs}catch{return true}},"touchedSinceListing");for(const object of objects){if(refs.has(object.sha256)||object.mtimeMs>=cutoffMs){survivors.push(object);continue}if(await touchedSinceListing(object,cutoffMs)){survivors.push(object);continue}if(await deleteObject(object,options)){deletedObjects+=1;deletedBytes+=object.sizeBytes}else{survivors.push(object)}}let remainingBytes=survivors.reduce((sum,o)=>sum+o.sizeBytes,0);if(remainingBytes>options.maxTotalBytes){const freshRefs=await options.memoryService.collectManagedRefs();if(freshRefs===null){debugLogger.debug("gc: ledger unreadable at budget pass, skipping budget deletions")}else{const unreferenced=survivors.filter(o=>!refs.has(o.sha256)&&!freshRefs.has(o.sha256)).sort((a,b)=>a.mtimeMs-b.mtimeMs);for(const object of unreferenced){if(remainingBytes<=options.maxTotalBytes)break;if(await touchedSinceListing(object,nowMs))continue;if(await deleteObject(object,options)){deletedObjects+=1;deletedBytes+=object.sizeBytes;remainingBytes-=object.sizeBytes}}}}const derivationsSuspended=remainingBytes>options.maxTotalBytes;if(derivationsSuspended){suspendedRoots.add(rootKey);debugLogger.warn(`omni object store over budget with only referenced objects left (${remainingBytes} > ${options.maxTotalBytes} bytes); new policy derivations are suspended for this session. Raise omni.storage.maxTotalBytes or delete memory records you no longer need \u2014 either change takes effect at the next session start (the GC runs once per process).`)}else{suspendedRoots.delete(rootKey)}if(deletedObjects>0){debugLogger.debug(`gc: removed ${deletedObjects} object(s) / ${deletedBytes} bytes; ${remainingBytes} bytes remain`)}return{ran:true,deletedObjects,deletedBytes,remainingBytes,derivationsSuspended}}__name(sweep,"sweep");init_esbuild_shims();import{createHash as createHash2,randomBytes}from"node:crypto";import fs2 from"node:fs/promises";import path3 from"node:path";var debugLogger2=createDebugLogger("omni:policy");var MAX_FILE_ARTIFACT_BYTES=256*1024;var OmniPolicyExecutionError=class extends Error{constructor(message,policyId,options){super(message,options);this.policyId=policyId;this.name="OmniPolicyExecutionError"}static{__name(this,"OmniPolicyExecutionError")}};function resolveArtifactSelector(artifacts,kind,role){if(role!==void 0){const byRole=artifacts[`role:${role}`];if(byRole)return byRole}const byKind=artifacts[`kind:${kind}`];if(byKind)return byKind;return artifacts["*"]??"retain"}__name(resolveArtifactSelector,"resolveArtifactSelector");function resourceConditionContext(recognized,shared){const resource={};const set=__name((field,value)=>{if(typeof value==="number"&&!Number.isNaN(value)){resource[field]=value}},"set");const m=recognized.metadata;set("sizeBytes",recognized.sizeBytes);set("durationMs",m.durationMs);set("width",m.width);set("height",m.height);set("maxWidth",m.width);set("maxHeight",m.height);set("frameRate",m.frameRate);set("frameCount",m.frameCount);set("bitRate",m.bitRate);set("sampleRateHz",m.sampleRateHz);set("channels",m.channels);const estimate=estimateRawResourceTokens(recognized);if(estimate.status==="ok"){set("estimatedTokenCount",estimate.estimatedTokenCount)}return{resource,...shared}}__name(resourceConditionContext,"resourceConditionContext");var MEMORY_ROLE_FIELDS={transcript:"hasTranscript",ocr:"hasOcr",caption:"hasCaption",summary:"hasSummary",keyframe:"hasKeyframes",clip:"hasClip"};async function memoryConditionNamespace(memory,binding){if(!memory||!binding)return void 0;const roles=await memory.service.collectVersionOutputRoles(binding);if(!roles)return void 0;const namespace={};for(const field of Object.values(MEMORY_ROLE_FIELDS)){namespace[field]=0}for(const role of roles){const field=MEMORY_ROLE_FIELDS[role];if(field)namespace[field]=1}return namespace}__name(memoryConditionNamespace,"memoryConditionNamespace");function requestConditionNamespace(items){let total=0;for(const item of items){if(!item.deliver)continue;const estimate=estimateRawResourceTokens(item.recognized);if(estimate.status!=="ok")return void 0;total+=estimate.estimatedTokenCount}return{totalEstimatedMediaTokens:total}}__name(requestConditionNamespace,"requestConditionNamespace");function sortPolicies(policies){return[...policies].sort((a,b)=>b.priority-a.priority||a.id.localeCompare(b.id))}__name(sortPolicies,"sortPolicies");var resourceGates=new Map;async function acquireResourceSlot(rootDir,limit){const effectiveLimit=Math.max(1,Math.floor(limit));let gate=resourceGates.get(rootDir);if(!gate){gate={active:0,waiters:[]};resourceGates.set(rootDir,gate)}const heldGate=gate;if(heldGate.active>=effectiveLimit){await new Promise(resolve=>heldGate.waiters.push(resolve))}else{heldGate.active++}let released=false;return()=>{if(released)return;released=true;const next=heldGate.waiters.shift();if(next){next();return}heldGate.active--;if(heldGate.active===0&&heldGate.waiters.length===0){resourceGates.delete(rootDir)}}}__name(acquireResourceSlot,"acquireResourceSlot");async function runFixedPolicies(config,source,options){const policies=sortPolicies(options.policies);const limits=options.limits??DEFAULT_OMNI_PROCESSING_LIMITS;const releaseSlot=await acquireResourceSlot(options.store.getOmniRootDir(),limits.maxConcurrentResources);try{return await runFixedPoliciesUnbounded(config,source,options,{policies,limits})}finally{releaseSlot()}}__name(runFixedPolicies,"runFixedPolicies");async function runFixedPoliciesUnbounded(config,source,options,normalized){const{policies,limits}=normalized;const cache=options.degradationCache??new OmniDegradationCache(options.store.getOmniRootDir());const records=[];const fileDeliveries=[];const items=[{filePath:source.filePath,recognized:source.recognized,label:source.displayName,origin:source.origin,sha256:source.sha256,memoryBinding:options.memory?.sourceBinding,lineageRuns:new Map,depth:0,deliver:true,process:true}];let runsUsed=0;let artifactsProduced=0;let derivedBytesProduced=0;let budgetExhausted=false;const stopOnBudget=__name((policy,item,reason)=>{budgetExhausted=true;records.push({policyId:policy.id,toolName:policy.toolName,outcome:"budget_exhausted",resource:item.label,error:reason});debugLogger2.debug(`per-root policy budget exhausted on ${item.label}: ${reason}; no further derivation for this root (committed deliveries stand)`)},"stopOnBudget");for(let i=0;i<items.length&&!budgetExhausted;i++){const item=items[i];if(!item.process)continue;if(item.recognized.modality==="image"&&(item.recognized.metadata.frameCount??1)>1){debugLogger2.debug(`animated image ${item.label} (${item.recognized.metadata.frameCount} frames) excluded from policy matching (D9)`);continue}const needsMemoryNamespace=policies.some(policy=>policy.when&&conditionUsesNamespace(policy.when,"memory"));const sharedConditionContext={request:options.conditionContext?.request??requestConditionNamespace(items),session:options.conditionContext?.session,memory:needsMemoryNamespace?await memoryConditionNamespace(options.memory,item.memoryBinding):void 0};for(const policy of policies){if(!policy.mediaTypes.includes(item.recognized.modality))continue;if(!policy.origins.includes(item.origin))continue;const runs=item.lineageRuns.get(policy.id)??0;if(runs>=policy.maxRunsPerLineage)continue;if(policy.when){const evaluation=evaluateFixedPolicyCondition(policy.when,resourceConditionContext(item.recognized,sharedConditionContext));if(evaluation.outcome==="no_match")continue;if(evaluation.outcome==="unavailable"&&policy.onConditionUnavailable==="skip"){records.push({policyId:policy.id,toolName:policy.toolName,outcome:"condition_unavailable",resource:item.label,missingFields:evaluation.missingFields});continue}}if(runsUsed>=limits.maxPolicyRunsPerRoot){stopOnBudget(policy,item,`maxPolicyRunsPerRoot (${limits.maxPolicyRunsPerRoot}) reached`);break}runsUsed++;item.lineageRuns.set(policy.id,runs+1);try{const execution=await executePolicy(config,item,policy,options.store,cache,options.signal,options.memory&&item.memoryBinding?{service:options.memory.service,source:item.memoryBinding}:void 0);records.push({policyId:policy.id,toolName:policy.toolName,outcome:execution.outcome,resource:item.label});if(execution.outcome==="no_op")continue;if(policy.output.source==="omit")item.deliver=false;const childDepth=item.depth+1;const depthAllowsReprocess=childDepth<limits.maxLineageDepth;if(policy.output.reprocessMedia&&!depthAllowsReprocess){debugLogger2.debug(`maxLineageDepth (${limits.maxLineageDepth}) reached under ${item.label}; derivatives deliver but do not re-enter policy matching`)}for(const derived of execution.derived){artifactsProduced++;derivedBytesProduced+=derived.recognized.sizeBytes;items.push({...derived,label:`${item.label} \u2192 ${policy.id}`,origin:"policy",lineageRuns:new Map(item.lineageRuns),depth:childDepth,deliver:resolveArtifactSelector(policy.output.artifacts,derived.recognized.modality,derived.role)==="include",process:policy.output.reprocessMedia&&depthAllowsReprocess})}for(const file of execution.derivedFiles){artifactsProduced++;derivedBytesProduced+=file.sizeBytes;if(resolveArtifactSelector(policy.output.artifacts,"file",file.role)==="include"){fileDeliveries.push(file)}}if(artifactsProduced>limits.maxArtifactsPerRoot){stopOnBudget(policy,item,`maxArtifactsPerRoot (${limits.maxArtifactsPerRoot}) exceeded`);break}if(derivedBytesProduced>limits.maxDerivedBytesPerRoot){stopOnBudget(policy,item,`maxDerivedBytesPerRoot (${limits.maxDerivedBytesPerRoot}) exceeded`);break}}catch(err){if(options.signal?.aborted)throw err;const message=err instanceof Error?err.message:String(err);records.push({policyId:policy.id,toolName:policy.toolName,outcome:"failed",resource:item.label,error:message});debugLogger2.debug(`fixed policy ${policy.id} (${policy.toolName}) failed on ${item.label}: ${message}`);if(policy.onFailure==="abort"||policy.stage==="transport_guard"){throw new OmniPolicyExecutionError(`Fixed policy ${policy.id} failed: ${message}`,policy.id,{cause:err})}}}}return{deliveries:items.filter(item=>item.deliver).map(item=>({filePath:item.filePath,recognized:item.recognized,sha256:item.sha256,disclosure:item.disclosure,degraded:item.degraded,memoryBinding:item.memoryBinding})),fileDeliveries,records}}__name(runFixedPoliciesUnbounded,"runFixedPoliciesUnbounded");async function executePolicy(config,item,policy,store,cache,signal,memory){const tool=config.getToolRegistry().getTool(policy.toolName);const descriptor=tool?.mediaPolicyDescriptor;if(!descriptor){throw new Error(`tool ${policy.toolName} is not a registered media-policy tool`)}item.sha256??=await hashFileSha256(item.filePath,signal);const settingsDefaults=resolvePolicyToolSettings(config,policy.toolName);const effectiveArguments={...settingsDefaults,...policy.arguments};const fingerprint=computePolicyFingerprint(policy.toolName,effectiveArguments,descriptor.version);const startedAt=new Date().toISOString();if(memory){const reusable=await memory.service.findReusableOutputs(item.sha256,fingerprint);const rebuilt=reusable?await rebuildReusedOutputs(reusable,descriptor,store,signal):void 0;if(rebuilt){debugLogger2.debug(`memory reuse hit: policy=${policy.id} sha256=${item.sha256.slice(0,12)}\u2026 outputs=${rebuilt.outputs.length} (tool not executed)`);const commit=await memory.service.commitPolicySucceeded({invocationId:"memory-reuse",source:memory.source,executionOrigin:{kind:"fixed_policy",policyId:policy.id,stage:policy.stage},toolName:policy.toolName,toolVersion:descriptor.version,finalArguments:effectiveArguments,omniConfigHash:fingerprint,startedAt,completedAt:new Date().toISOString(),outputs:rebuilt.outputs});return{outcome:"succeeded",derived:rebuilt.derived.map(d=>({...d,memoryBinding:commit?.mediaBindings.get(d.sha256)})),derivedFiles:rebuilt.derivedFiles}}}const hit=await cache.get(item.sha256,fingerprint);if(hit){try{const objectPath=store.objectPathFor(hit.degradedSha256,hit.extension);const stat=await fs2.lstat(objectPath).catch(()=>void 0);if(stat?.isFile()&&!stat.isSymbolicLink()){const actualSha256=await hashFileSha256(objectPath,signal);if(actualSha256===hit.degradedSha256){const recognized=await recognizeMediaFile(objectPath,{signal});const declared=descriptor.outputs.some(o=>o.kind==="media"&&o.mimeTypes?.includes(recognized.detectedMimeType));if(declared){debugLogger2.debug(`degradation cache hit: policy=${policy.id} sha256=${item.sha256.slice(0,12)}\u2026`);const commit=memory?await memory.service.commitPolicySucceeded({invocationId:"cache-hit",source:memory.source,executionOrigin:{kind:"fixed_policy",policyId:policy.id,stage:policy.stage},toolName:policy.toolName,toolVersion:descriptor.version,finalArguments:effectiveArguments,omniConfigHash:fingerprint,startedAt,completedAt:new Date().toISOString(),outputs:[{kind:"media",objectPath,sha256:hit.degradedSha256,mediaType:recognized.modality,metadata:recognized.metadata,sizeBytes:recognized.sizeBytes,mimeType:recognized.detectedMimeType,role:hit.role,disclosure:hit.disclosure}]}):void 0;return{outcome:"cache_hit",derived:[{filePath:objectPath,recognized,sha256:hit.degradedSha256,disclosure:hit.disclosure,degraded:true,role:hit.role,memoryBinding:commit?.mediaBindings.get(hit.degradedSha256)}],derivedFiles:[]}}debugLogger2.debug(`degradation cache hit for policy=${policy.id} recognized as undeclared media type ${recognized.detectedMimeType}; dropping the entry and re-transcoding`)}}}catch(err){if(signal?.aborted)throw err;debugLogger2.debug(`degradation cache hit could not be verified for policy=${policy.id}: ${err instanceof Error?err.message:String(err)}; dropping the entry and re-transcoding`)}await cache.removeByDegradedSha256(hit.degradedSha256)}await settleOmniGc(store.getOmniRootDir());if(isOmniDerivationSuspended(store.getOmniRootDir())){throw new Error(`omni object store is over its byte budget with only memory-referenced objects left; new policy derivations are suspended. Raise omni.storage.maxTotalBytes or delete memory records you no longer need, then start a new session \u2014 the budget is re-evaluated once per process.`)}const invocationId=randomBytes(8).toString("hex");const stagingDir=await store.createStagingDir(invocationId);let failure;try{const request={callId:invocationId,name:policy.toolName,args:{...effectiveArguments,inputPath:item.filePath,outputDir:stagingDir},isClientInitiated:true,prompt_id:`omni-fixed-policy-${invocationId}`,executionOrigin:{kind:"fixed_policy",policyId:policy.id,stage:policy.stage}};const{executeToolCall}=await import("./nonInteractiveToolExecutor-QPQYR6IS.js");const response=await executeToolCall(config,request,signal??new AbortController().signal,{recordToolResult:false});if(response.error){throw new Error(response.error.message,{cause:response.error})}const batch=response.policyArtifacts;if(!batch||batch.artifacts.length===0){throw new Error(`tool ${policy.toolName} succeeded but produced no policy artifacts`)}const validated=await Promise.all(batch.artifacts.map(artifact=>validateArtifact(artifact,descriptor,stagingDir,signal)));assertRequiredOutputsPresent(descriptor,validated,policy.toolName);if(validated.every(a=>a.sha256===item.sha256)){return{outcome:"no_op",derived:[],derivedFiles:[]}}const promoted=await Promise.all(validated.map(async artifact=>{const mimeType=artifact.kind==="media"?artifact.recognized.detectedMimeType:artifact.mimeType;const put=await store.putFile(artifact.absolutePath,artifact.sha256,extensionForMime(mimeType),signal);return{artifact,objectPath:put.objectPath}}));const derived=[];const derivedFiles=[];for(const{artifact,objectPath}of promoted){if(artifact.kind==="media"){derived.push({filePath:objectPath,recognized:artifact.recognized,sha256:artifact.sha256,disclosure:artifact.disclosure,degraded:artifact.lossy,role:artifact.role})}else{derivedFiles.push({filePath:objectPath,role:artifact.role,mimeType:artifact.mimeType,text:artifact.text,sha256:artifact.sha256,sizeBytes:artifact.sizeBytes,disclosure:artifact.disclosure})}}if(memory){const outputs=promoted.map(({artifact,objectPath})=>artifact.kind==="media"?{kind:"media",objectPath,sha256:artifact.sha256,mediaType:artifact.recognized.modality,metadata:artifact.recognized.metadata,sizeBytes:artifact.recognized.sizeBytes,mimeType:artifact.recognized.detectedMimeType,role:artifact.role,disclosure:artifact.disclosure}:{kind:"text",objectPath,sha256:artifact.sha256,mimeType:artifact.mimeType,text:artifact.text,sizeBytes:artifact.sizeBytes,role:artifact.role,disclosure:artifact.disclosure});const commit=await memory.service.commitPolicySucceeded({invocationId,source:memory.source,executionOrigin:{kind:"fixed_policy",policyId:policy.id,stage:policy.stage},toolName:policy.toolName,toolVersion:descriptor.version,finalArguments:effectiveArguments,omniConfigHash:fingerprint,startedAt,completedAt:new Date().toISOString(),outputs});if(commit){for(const entry of derived){entry.memoryBinding=commit.mediaBindings.get(entry.sha256)}}}if(validated.length===1&&validated[0].kind==="media"&&validated[0].disclosure){await cache.put(item.sha256,fingerprint,{degradedSha256:validated[0].sha256,extension:extensionForMime(validated[0].recognized.detectedMimeType),disclosure:validated[0].disclosure,mimeType:validated[0].recognized.detectedMimeType,...validated[0].role!==void 0?{role:validated[0].role}:{}})}return{outcome:"succeeded",derived,derivedFiles}}catch(err){failure=err;throw err}finally{if(failure===void 0||signal?.aborted){await store.removeStagingDir(invocationId).catch(()=>{})}else{try{await store.quarantineInvocation(invocationId,{policyId:policy.id,toolName:policy.toolName,reason:failure instanceof Error?failure.message:String(failure)})}catch{await store.removeStagingDir(invocationId).catch(()=>{})}}}}__name(executePolicy,"executePolicy");async function rebuildReusedOutputs(reusable,descriptor,store,signal){const outputs=[];const derived=[];const derivedFiles=[];try{for(const record of reusable.outputs){const objectPath=record.objectPath??store.objectPathFor(record.sha256,extensionForMime(record.mimeType));const stat=await fs2.lstat(objectPath).catch(()=>void 0);if(!stat?.isFile()||stat.isSymbolicLink())return void 0;if(await hashFileSha256(objectPath,signal)!==record.sha256){return void 0}if(record.kind==="media"){const recognized=await recognizeMediaFile(objectPath,{signal});const declared=descriptor.outputs.some(o=>o.kind==="media"&&o.mimeTypes?.includes(recognized.detectedMimeType));if(!declared)return void 0;outputs.push({kind:"media",objectPath,sha256:record.sha256,mediaType:recognized.modality,metadata:recognized.metadata,sizeBytes:recognized.sizeBytes,mimeType:recognized.detectedMimeType,role:record.role,disclosure:record.disclosure});derived.push({filePath:objectPath,recognized,sha256:record.sha256,disclosure:record.disclosure,degraded:record.disclosure!==void 0,role:record.role})}else{const text=await fs2.readFile(objectPath,"utf8");outputs.push({kind:"text",objectPath,sha256:record.sha256,mimeType:record.mimeType,text,sizeBytes:record.sizeBytes,role:record.role,disclosure:record.disclosure});derivedFiles.push({filePath:objectPath,role:record.role,mimeType:record.mimeType,text,sha256:record.sha256,sizeBytes:record.sizeBytes,disclosure:record.disclosure})}}}catch(err){if(signal?.aborted)throw err;debugLogger2.debug(`memory reuse could not be verified, re-deriving: ${err instanceof Error?err.message:String(err)}`);return void 0}return{outputs,derived,derivedFiles}}__name(rebuildReusedOutputs,"rebuildReusedOutputs");async function validateArtifact(artifact,descriptor,stagingDir,signal){if(artifact.storage!=="workspace"||!artifact.workspacePath){throw new Error(`policy artifact "${artifact.title}" is not a workspace file`)}const absolutePath=path3.resolve(stagingDir,artifact.workspacePath);if(!absolutePath.startsWith(stagingDir+path3.sep)){throw new Error(`policy artifact "${artifact.title}" escapes the staging directory`)}const stat=await fs2.lstat(absolutePath).catch(()=>void 0);if(!stat?.isFile()||stat.isSymbolicLink()){throw new Error(`policy artifact "${artifact.title}" is missing or not a regular file`)}const rawRole=artifact.metadata?.["omniRole"];const role=typeof rawRole==="string"&&rawRole?rawRole:void 0;const rawDisclosure=artifact.metadata?.["omniDisclosure"];const disclosure=typeof rawDisclosure==="string"&&rawDisclosure?rawDisclosure:void 0;if(artifact.kind==="file"){const spec2=descriptor.outputs.find(o=>o.kind==="file"&&(o.role===void 0||o.role===role)&&artifact.mimeType!==void 0&&o.mimeTypes?.includes(artifact.mimeType));if(!spec2){throw new Error(`policy artifact "${artifact.title}" (file, role ${role??"none"}, ${artifact.mimeType??"no mimeType"}) matches no declared file output`)}if(stat.size>MAX_FILE_ARTIFACT_BYTES){throw new Error(`policy artifact "${artifact.title}" exceeds the file-artifact size budget (${stat.size} > ${MAX_FILE_ARTIFACT_BYTES} bytes)`)}const bytes=await fs2.readFile(absolutePath);let text;try{text=new TextDecoder("utf-8",{fatal:true}).decode(bytes)}catch{throw new Error(`policy artifact "${artifact.title}" is not valid UTF-8 text`)}if(spec2.lossy&&!disclosure){throw new Error(`policy artifact "${artifact.title}" is lossy but carries no omniDisclosure`)}return{kind:"file",absolutePath,mimeType:artifact.mimeType,text,sizeBytes:bytes.byteLength,sha256:createHash2("sha256").update(bytes).digest("hex"),disclosure,lossy:spec2.lossy===true,role}}const recognized=await recognizeMediaFile(absolutePath,{signal});const spec=descriptor.outputs.find(o=>o.kind==="media"&&o.mimeTypes?.includes(recognized.detectedMimeType));if(!spec){throw new Error(`policy artifact "${artifact.title}" has undeclared media type ${recognized.detectedMimeType}`)}if(artifact.kind!==recognized.modality){throw new Error(`policy artifact "${artifact.title}" declares kind ${String(artifact.kind)} but contains ${recognized.modality} content`)}if(spec.lossy&&!disclosure){throw new Error(`policy artifact "${artifact.title}" is lossy but carries no omniDisclosure`)}return{kind:"media",absolutePath,recognized,sha256:await hashFileSha256(absolutePath,signal),disclosure,lossy:spec.lossy===true,role}}__name(validateArtifact,"validateArtifact");function assertRequiredOutputsPresent(descriptor,validated,toolName){for(const spec of descriptor.outputs){if(!spec.required)continue;let produced;if(spec.kind==="media"){produced=validated.some(a=>a.kind==="media"&&spec.mimeTypes?.includes(a.recognized.detectedMimeType))}else if(spec.kind==="file"){produced=validated.some(a=>a.kind==="file"&&(spec.role===void 0||a.role===spec.role)&&spec.mimeTypes?.includes(a.mimeType))}else{continue}if(!produced){throw new Error(`tool ${toolName} did not produce its required ${spec.kind} ${spec.mimeTypes?.join("/")??spec.role??""} output`)}}}__name(assertRequiredOutputsPresent,"assertRequiredOutputsPresent");export{estimateRawResourceTokens,computePolicyFingerprint,OmniDegradationCache,DEFAULT_OMNI_MAX_UPLOAD_FILE_BYTES,OmniTransportGuardError,effectiveMaxUploadFileBytes,assertWithinByteLimit,assertWithinDurationLimit,assertWithinTokenLimit,effectiveOmniStorageMaxTotalBytes,runOmniGcOnce,OmniPolicyExecutionError,runFixedPolicies,validateArtifact,assertRequiredOutputsPresent};
|
|
6
6
|
/**
|
|
7
7
|
* @license
|
|
8
8
|
* Copyright 2025 Google LLC
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
-
import{DEFAULT_DARK_THEME_NAME,DEFAULT_LIGHT_THEME_NAME}from"./chunk-UWCF7JIF.js";import{customDeepMerge,getSettingsSchema}from"./chunk-
|
|
3
|
+
import{DEFAULT_DARK_THEME_NAME,DEFAULT_LIGHT_THEME_NAME}from"./chunk-UWCF7JIF.js";import{customDeepMerge,getSettingsSchema}from"./chunk-G4MWPXNY.js";import{CONSOLIDATED_DISABLE_KEYS,V1_INDICATOR_KEYS,V1_TO_V2_MIGRATION_MAP,V1_TO_V2_PRESERVE_DISABLE_MAP,V2_CONTAINER_KEYS}from"./chunk-LMUSSYJH.js";import{t}from"./chunk-NO7VTKRL.js";import{SUPPORTED_LANGUAGES,getLanguageNameFromLocale}from"./chunk-U7HZUZKP.js";import{SETTINGS_DIRECTORY_NAME,getHomeEnvFallbackVars,loadEnvironment,preResolveHomeEnvOverrides}from"./chunk-UM5KBBYP.js";import{ENV_CORRUPTED_PATH,ENV_WAS_RECOVERED,applyVerifyPrCoordinateEnv}from"./chunk-N3AQAZ7D.js";import{parseExecutionSandboxSettings,readBareModeOperatorSettings,readOperatorSandboxSettings,require_strip_json_comments,selectOperatorExecutionSandbox,stripUtf8Bom}from"./chunk-DOLUT3XC.js";import{getGlobalQwenDirLite,getSystemDefaultsPath,getSystemSettingsPath,spawnedEnvironmentView}from"./chunk-PTHIQ7ZN.js";import{isWorkspaceTrusted,updateSettingsFilePreservingFormat}from"./chunk-YWK3E4WJ.js";import{isValidAdvisorMaxUses}from"./chunk-T3CQ72HC.js";import{resolveEnvVarsInObject}from"./chunk-ZOTKZI2P.js";import{stripRuntimeSnapshotPrefix}from"./chunk-ET2Z7ZGF.js";import{createDebugLogger}from"./chunk-JAUJI56S.js";import{Storage}from"./chunk-EPODBRBP.js";import{FatalConfigError,getErrorMessage}from"./chunk-XYB7GC5U.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name,__toESM}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import*as fs3 from"node:fs";import*as path2 from"node:path";import{homedir}from"node:os";import process from"node:process";var import_strip_json_comments=__toESM(require_strip_json_comments(),1);init_esbuild_shims();function hasOwnModelProviders(settingsObj){if(!settingsObj||typeof settingsObj!=="object"){return false}const obj=settingsObj;return Object.prototype.hasOwnProperty.call(obj,"modelProviders")}__name(hasOwnModelProviders,"hasOwnModelProviders");function getModelProvidersOwnerScope(settings){if(settings.isTrusted&&hasOwnModelProviders(settings.workspace.settings)){return"Workspace"}if(hasOwnModelProviders(settings.user.settings)){return"User"}return void 0}__name(getModelProvidersOwnerScope,"getModelProvidersOwnerScope");function getPersistScopeForModelSelection(settings){return getModelProvidersOwnerScope(settings)??"User"}__name(getPersistScopeForModelSelection,"getPersistScopeForModelSelection");function getWritableScopes(settings){return settings.isTrusted?["Workspace","User"]:["User"]}__name(getWritableScopes,"getWritableScopes");function getOwnKeyScope(settings,key){for(const scope of getWritableScopes(settings)){const obj=settings.forScope(scope).settings;if(Object.prototype.hasOwnProperty.call(obj,key))return scope}return void 0}__name(getOwnKeyScope,"getOwnKeyScope");init_esbuild_shims();init_esbuild_shims();import*as fs from"node:fs";import*as path from"node:path";var LLM_OUTPUT_LANGUAGE_RULE_FILENAME="output-language.md";var LLM_OUTPUT_LANGUAGE_MARKER_PREFIX="qwen-code:llm-output-language:";var OUTPUT_LANGUAGE_AUTO="auto";function isAutoLanguage(value){return!value||value.toLowerCase()===OUTPUT_LANGUAGE_AUTO}__name(isAutoLanguage,"isAutoLanguage");function normalizeOutputLanguage(language){const normalized=language.trim().replace(/_/g,"-").toLowerCase();const knownLanguageName=SUPPORTED_LANGUAGES.find(supportedLanguage=>supportedLanguage.fullName.toLowerCase()===normalized);if(knownLanguageName){return knownLanguageName.fullName}const knownLocaleCode=SUPPORTED_LANGUAGES.some(supportedLanguage=>{const code=supportedLanguage.code.toLowerCase();const id=supportedLanguage.id.toLowerCase();return normalized===code||normalized===id||normalized.startsWith(`${code}-`)||normalized.startsWith(`${id}-`)||normalized.startsWith(`${code}.`)||normalized.startsWith(`${id}.`)||normalized.startsWith(`${code}@`)||normalized.startsWith(`${id}@`)});if(!knownLocaleCode){return language}return getLanguageNameFromLocale(normalized)}__name(normalizeOutputLanguage,"normalizeOutputLanguage");function resolveOutputLanguage(value){if(isAutoLanguage(value)){throw new Error("resolveOutputLanguage does not accept auto; use resolveOutputLanguageOrPreserveAuto instead.")}return normalizeOutputLanguage(value)}__name(resolveOutputLanguage,"resolveOutputLanguage");function resolveOutputLanguageOrPreserveAuto(value){return isAutoLanguage(value)?OUTPUT_LANGUAGE_AUTO:resolveOutputLanguage(value)}__name(resolveOutputLanguageOrPreserveAuto,"resolveOutputLanguageOrPreserveAuto");function getOutputLanguageFilePath(){return path.join(Storage.getGlobalQwenDir(),LLM_OUTPUT_LANGUAGE_RULE_FILENAME)}__name(getOutputLanguageFilePath,"getOutputLanguageFilePath");function sanitizeForMarker(language){return language.replace(/[\r\n]/g," ").replace(/--!?>/g,"").replace(/--/g,"")}__name(sanitizeForMarker,"sanitizeForMarker");function generateOutputLanguageFileContent(language){const safeLanguage=sanitizeForMarker(language);if(isAutoLanguage(language)){return`# Output language preference: ${OUTPUT_LANGUAGE_AUTO}
|
|
4
4
|
<!-- ${LLM_OUTPUT_LANGUAGE_MARKER_PREFIX} ${OUTPUT_LANGUAGE_AUTO} -->
|
|
5
5
|
|
|
6
6
|
## Rule
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
-
import{projectJsonStringToByteBudget}from"./chunk-WQUA4G2X.js";import{flushOutput}from"./chunk-VURTGFJP.js";import{cpLen,cpSlice,sanitizeTerminalLine,sanitizeTerminalText,stripUnsafeCharacters}from"./chunk-64CA3W6G.js";import{require_semver}from"./chunk-YZUKMJW7.js";import{ENGINE_NODE,MOD_END_TIMEOUT_MS,MOD_MAX_BYTES,ModBudget,adjustRenderTree,assertModDepth,record,validateRenderTree,validateResult}from"./chunk-ZZJXFLVM.js";import{stableJson}from"./chunk-FIXDX63I.js";import{external_exports}from"./chunk-TWP72VRH.js";import{openNoFollow}from"./chunk-QXQGUM3Y.js";import{resolveBundleDir}from"./chunk-4NPYOXJO.js";import{runOutsideAgentContext}from"./chunk-YZFNBUKG.js";import{isInternalPromptId,uiTelemetryService}from"./chunk-ZWPSBU7K.js";import{getGenAiUsageProvenance,outputTokenCount}from"./chunk-4DIWAQ5G.js";import{EVENT_API_RESPONSE}from"./chunk-3XVPZY7X.js";import{registerCleanup}from"./chunk-UY2ET2AL.js";import{stripAnsiAndControl}from"./chunk-DBRQGEEI.js";import{ToolNames}from"./chunk-SBZFGYYS.js";import{createDebugLogger}from"./chunk-JAUJI56S.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name,__toESM}from"./chunk-KBWJGX7I.js";init_esbuild_shims();init_esbuild_shims();import{randomUUID}from"node:crypto";init_esbuild_shims();import{promises as fs}from"node:fs";import path from"node:path";init_esbuild_shims();var import_semver=__toESM(require_semver(),1);var name=external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/);var dependency=external_exports.union([external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]*(?:@[a-zA-Z0-9][a-zA-Z0-9._-]*)?$/),external_exports.object({name,marketplace:name.optional(),version:external_exports.string().optional()}).strict()]);function parseModDependencies(value){const parsed=external_exports.array(dependency).safeParse(value===void 0?[]:value);if(!parsed.success)throw new Error("Invalid Mod dependencies declaration.");return parsed.data.map(item=>{if(typeof item==="string"){const[name2,marketplace]=item.split("@");return{name:name2,marketplace}}if(item.version!==void 0&&!(0,import_semver.validRange)(item.version)){throw new Error(`Invalid Mod dependency version range for ${item.name}.`)}return item})}__name(parseModDependencies,"parseModDependencies");function resolveModDependency(plugins,plugin,dependency2){const marketplace=dependency2.marketplace??plugin.marketplace;const local=plugins.filter(item=>item.name===dependency2.name&&!item.marketplace);const matches=local.length?local:plugins.filter(item=>item.name===dependency2.name&&item.marketplace===marketplace);if(matches.length!==1){throw new Error(`Mod ${plugin.name}: dependency ${dependency2.name} must identify one installed, enabled plugin.`)}const target=matches[0];if(target.marketplace&&dependency2.version&&!(0,import_semver.satisfies)(target.version,dependency2.version)){throw new Error(`Mod ${plugin.name}: dependency ${dependency2.name} has an incompatible installed version.`)}return target}__name(resolveModDependency,"resolveModDependency");function orderModPlugins(plugins){const edges=plugins.map(()=>new Set);const incoming=plugins.map(()=>0);for(const[index,plugin]of plugins.entries()){for(const dependency2 of plugin.dependencies){const targetIndex=plugins.indexOf(resolveModDependency(plugins,plugin,dependency2));if(!edges[index].has(targetIndex)){edges[index].add(targetIndex);incoming[targetIndex]++}}}const ordered=[];const remaining=new Set(plugins.map((_,index)=>index));while(remaining.size){const next=[...remaining].find(index=>incoming[index]===0);if(next===void 0)throw new Error("Mod dependency cycle: activation refused.");remaining.delete(next);ordered.push(plugins[next]);for(const target of edges[next])incoming[target]--}return ordered}__name(orderModPlugins,"orderModPlugins");function isContainedFile(root,file){const relative=path.relative(root,file);return Boolean(relative)&&!path.isAbsolute(relative)&&relative!==".."&&!relative.startsWith(`..${path.sep}`)}__name(isContainedFile,"isContainedFile");async function readModFile(root,file){if(!isContainedFile(root,file)){throw new Error("Mod file must stay inside the installed extension.")}let current=root;for(const part of path.relative(root,file).split(path.sep)){current=path.join(current,part);const stat=await fs.lstat(current);if(stat.isSymbolicLink()){throw new Error("Mod files cannot be symbolic links.")}if(current===file&&!stat.isFile()){throw Object.assign(new Error("Mod input must be a regular file."),{code:stat.isDirectory()?"EISDIR":void 0})}}const entry=await fs.realpath(file);if(!isContainedFile(root,entry)){throw new Error("Mod file must stay inside the installed extension.")}const handle=await openNoFollow(entry);try{const stat=await handle.stat();if(!stat.isFile()||stat.size>MOD_MAX_BYTES){throw new Error("Mod file exceeds the 256 KiB regular-file limit.")}const buffer=Buffer.alloc(MOD_MAX_BYTES+1);const{bytesRead}=await handle.read(buffer,0,buffer.length,0);if(bytesRead>MOD_MAX_BYTES)throw new Error("Mod file is too large.");return{entry,source:buffer.subarray(0,bytesRead).toString("utf8")}}finally{await handle.close()}}__name(readModFile,"readModFile");async function readManifest(root,relative){try{if(path.isAbsolute(relative)){throw new Error("Mod manifest path must be relative to the extension.")}const value=JSON.parse((await readModFile(root,path.resolve(root,relative))).source);if(!value||typeof value!=="object"||Array.isArray(value)){throw new Error("Mod manifest must be a JSON object.")}return value}catch(error){if(error.code==="ENOENT")return void 0;throw error}}__name(readManifest,"readManifest");async function loadModSource(extensionPath){const root=await fs.realpath(extensionPath);const qwen=await readManifest(root,"qwen-extension.json");if(typeof qwen?.["hooks"]==="string"&&(path.isAbsolute(qwen["hooks"])||!isContainedFile(root,path.resolve(root,qwen["hooks"])))){return void 0}const claude=await readManifest(root,".claude-plugin/plugin.json");const hooksPath=typeof qwen?.["hooks"]==="string"?qwen["hooks"]:typeof claude?.["hooks"]==="string"?claude["hooks"]:"hooks/hooks.json";if(path.isAbsolute(hooksPath)||!isContainedFile(root,path.resolve(root,hooksPath))){return void 0}const hooks=await readManifest(root,hooksPath);if(!hooks||!Object.hasOwn(hooks,"modules"))return void 0;const modules=hooks["modules"];if(!Array.isArray(modules)||modules.length!==1||typeof modules[0]!=="string"||path.isAbsolute(modules[0])||!/\.(?:[cm]?js|[cm]?ts|[jt]sx)$/.test(modules[0])){throw new Error("Mods require one relative JavaScript, TypeScript or JSX module.")}const manifest={...claude,...qwen};const entry=path.resolve(root,path.dirname(hooksPath),modules[0]);return{root,...await readModFile(root,entry),userConfig:manifest["userConfig"],dependencies:parseModDependencies(manifest["dependencies"])}}__name(loadModSource,"loadModSource");async function loadModDependencies(extensionPath){const root=await fs.realpath(extensionPath);const qwen=await readManifest(root,"qwen-extension.json");const claude=await readManifest(root,".claude-plugin/plugin.json");return parseModDependencies({...claude,...qwen}["dependencies"])}__name(loadModDependencies,"loadModDependencies");init_esbuild_shims();var option=external_exports.union([external_exports.string(),external_exports.number().finite(),external_exports.boolean(),external_exports.array(external_exports.string())]);var field=external_exports.object({type:external_exports.enum(["string","number","boolean","directory","file"]),title:external_exports.string(),description:external_exports.string(),required:external_exports.boolean().optional(),default:option.optional(),multiple:external_exports.boolean().optional(),sensitive:external_exports.boolean().optional(),min:external_exports.number().finite().optional(),max:external_exports.number().finite().optional(),options:external_exports.array(external_exports.string().min(1).max(64)).nonempty().optional()}).strict().refine(value=>{if(!value.options)return true;return value.type==="string"&&!value.multiple&&!value.sensitive&&value.options.every(item=>item.trim()===item&&!/[\p{Cc}\p{Cf}]/u.test(item))&&new Set(value.options.map(item=>item.toLowerCase())).size===value.options.length&&(value.default===void 0?value.required===true:value.options.includes(value.default))});var schema=external_exports.record(external_exports.string().regex(/^[A-Za-z_]\w*$/),field);var storedOptions=external_exports.record(option);function*pluginConfigurations(scopes,name2,marketplace){const keys=marketplace?[`${name2}@${marketplace}`]:[name2,`${name2}@inline`];for(const scope of scopes){if(scope===void 0)continue;if(!scope||typeof scope!=="object"||Array.isArray(scope)){throw new Error("Invalid Mod pluginConfigs settings.")}for(const key of keys){if(!Object.hasOwn(scope,key))continue;const config=scope[key];if(!config||typeof config!=="object"||Array.isArray(config)){throw new Error("Invalid Mod pluginConfigs entry.")}yield config}}}__name(pluginConfigurations,"pluginConfigurations");function resolveModChoice(scopes,name2,marketplace,key,choices){let choice=choices[0];for(const config of pluginConfigurations(scopes,name2,marketplace)){const value=config[key];if(value===void 0)continue;if(!choices.includes(value))throw new Error(`Invalid Mod ${key}: expected ${choices.join(" or ")}.`);choice=value}return choice}__name(resolveModChoice,"resolveModChoice");function resolveModToolDialect(scopes,name2,marketplace){return resolveModChoice(scopes,name2,marketplace,"toolDialect",["native","claude"])}__name(resolveModToolDialect,"resolveModToolDialect");function resolveModUnsupportedEvents(scopes,name2,marketplace){return resolveModChoice(scopes,name2,marketplace,"unsupportedEvents",["skip","reject"])}__name(resolveModUnsupportedEvents,"resolveModUnsupportedEvents");function resolveModOptions(declaration,scopes,name2,marketplace){const parsed=schema.safeParse(declaration===void 0?{}:declaration);if(!parsed.success)throw new Error("Invalid Mod userConfig declaration.");const fields=Object.entries(parsed.data);if(!fields.length)return{};if(fields.some(([,value])=>value.sensitive)){throw new Error("Sensitive Mod userConfig is not supported yet.")}let stored={};for(const config of pluginConfigurations(scopes,name2,marketplace)){const options=config["options"];if(options===void 0)continue;const values=storedOptions.safeParse(options);if(!values.success)throw new Error(`Invalid Mod configured option: ${String(values.error.issues[0]?.path[0]??"").slice(0,64)}.`);stored={...stored,...values.data}}const result=Object.fromEntries(fields.filter(([,config])=>config.default!==void 0||!config.required).map(([key,config])=>[key,config.default??""]));for(const[key,value]of Object.entries(stored)){const choices=Object.hasOwn(parsed.data,key)?parsed.data[key].options:void 0;if(!choices||choices.includes(value))Object.defineProperty(result,key,{value,enumerable:true,writable:true,configurable:true})}for(const[key,config]of fields){const value=Object.hasOwn(result,key)?result[key]:void 0;if(value===void 0||value===""){if(config.required)throw new Error(`Missing required Mod option: ${key}.`)}else{const valid=config.type==="number"?typeof value==="number"&&(config.min===void 0||value>=config.min)&&(config.max===void 0||value<=config.max):config.type==="boolean"?typeof value==="boolean":typeof value==="string"||config.type==="string"&&config.multiple&&Array.isArray(value);if(!valid)throw new Error(`Invalid Mod option: ${key}.`)}}if(Buffer.byteLength(JSON.stringify(result))>MOD_MAX_BYTES){throw new Error("Mod options exceed the 256 KiB limit.")}return result}__name(resolveModOptions,"resolveModOptions");init_esbuild_shims();import{Worker}from"node:worker_threads";import{existsSync}from"node:fs";import path2 from"node:path";import{createRequire}from"node:module";import{pathToFileURL}from"node:url";function workerEntry(){if(import.meta.url.endsWith(".ts")){return new URL(`data:text/javascript,${encodeURIComponent(`import { register } from ${JSON.stringify(pathToFileURL(createRequire(import.meta.url).resolve("tsx/esm/api")).href)}; register(); await import(${JSON.stringify(new URL("./mod-worker.ts",import.meta.url).href)});`)}`)}const sibling=new URL("./mod-worker.js",import.meta.url);return existsSync(sibling)?sibling:path2.join(resolveBundleDir(import.meta.url),"mod-worker.js")}__name(workerEntry,"workerEntry");var ModRuntime=class _ModRuntime{constructor(log,facts,resolveTool,surface=null,abortTurn,renderHost){this.log=log;this.facts=facts;this.resolveTool=resolveTool;this.surface=surface;this.abortTurn=abortTurn;this.renderHost=renderHost;this.worker=new Worker(workerEntry(),{stdout:true,stderr:true,workerData:this.cancelled.buffer});this.worker.stdout?.resume();this.worker.stderr?.resume();this.worker.on("message",reply=>{const root=this.root;if(!root||reply.root!==root.id)return;if(reply.type==="host-call")this.executeHost(reply);else if(reply.type==="host-cancel"){for(const id of reply.ids)this.tool?.operations.get(id)?.controller.abort()}else if(reply.type==="check-result")this.tool?.checks.get(reply.id)?.(reply);else if(reply.type==="turn-abort")this.answerTurnAbort(reply,root.id);else if(reply.type==="invalidate"){if(reply.event!=="ui.render"||this.failure)return;if(this.early)this.early.add(reply.plugin);else if(this.renders.includes(reply.plugin))this.renderHost?.invalidate(reply.plugin)}else if(reply.type==="activity"){if(reply.phase!==root.phase||reply.revision<=root.revision||reply.operation!==void 0&&reply.operation!==root.native)return;root.revision=reply.revision;root.idle=this.tool?.checks.size?void 0:reply.operation;root.refresh()}else if(reply.type==="log"){if(this.failure)return;try{this.log({text:reply.text,to:reply.to},reply.plugin)}catch(error){this.fail(error instanceof Error?error:new Error(String(error)));void this.worker.terminate()}}else this.pending?.(reply)});this.worker.on("error",error=>this.fail(error));this.worker.on("exit",code=>this.fail(new Error(`Mod worker exited (${code}).`)))}static{__name(this,"ModRuntime")}worker;failure;pending;commands=[];tools=false;turns={start:false,complete:[]};renders=[];early=new Set;noted=new Set;sequence=0;root;tool;cancelled=new Int32Array(new SharedArrayBuffer(4));static async create(source,cwd,log,signal,options={}){return _ModRuntime.createGroup([{id:"mod",name:"mod",source,options}],cwd,log,signal)}static async createGroup(plugins,cwd,log,signal,resolveTool,surface=null,version="unknown",facts,abortTurn,render){if(plugins.length>32||new Set(plugins.map(p=>p.id)).size!==plugins.length)throw new Error("Invalid Mod plugin group.");const startedAt=Date.now();const runtime=new _ModRuntime(log,facts??(()=>({id:"",cwd,root:cwd,model:"",turns:0,usage:{startedAt,context:{tokens:0,window:0},rateLimits:[]}})),plugins.some(plugin=>plugin.toolDialect==="claude")?resolveTool:void 0,surface,abortTurn,render);try{const result=await runtime.request({type:"load",plugins,cwd,surface,version,sites:render?.sites??[]},signal,6e4);const names=__name(value=>Array.isArray(value)&&value.every(name2=>plugins.some(plugin=>plugin.name===name2)),"names");const turnComplete=record(result)?result["turnComplete"]:void 0;const renders=record(result)?result["render"]:void 0;if(!record(result)||typeof result["tools"]!=="boolean"||typeof result["turnStart"]!=="boolean"||!names(turnComplete)||!names(renders))throw new Error("Invalid Mod declarations.");const commands=result["commands"];if(!Array.isArray(commands)||commands.length>64||commands.some(command=>!command||!plugins.some(plugin=>plugin.id===command.plugin)||typeof command.name!=="string"||!/^[a-zA-Z0-9_-]{1,64}$/.test(command.name)||typeof command.description!=="string"||command.argumentHint!==void 0&&typeof command.argumentHint!=="string"))throw new Error("Invalid Mod command declarations.");runtime.commands=commands;runtime.tools=result["tools"];runtime.turns={start:result["turnStart"],complete:turnComplete};runtime.renders=renders;const early=runtime.early;runtime.early=void 0;for(const plugin of early)if(renders.includes(plugin))render?.invalidate(plugin);return runtime}catch(error){await runtime.dispose();throw error}}getCommands(plugin="mod"){return this.commands.filter(command=>command.plugin===plugin).map(({plugin:_plugin,...command})=>command)}get hasToolHooks(){return this.tools}get turnHooks(){return this.turns}get renderHooks(){return this.renders}async render(input,signal){const settled=await this.request({type:"render",input},signal);const owner=this.renders.length===1?this.renders[0]:"hooks";const notes=[];const note=__name((line,key=line)=>{if(this.noted.has(key))return;this.noted.add(key);notes.push(`${owner}: ${line}`)},"note");try{validateRenderTree(settled)}catch(error){note(`ui.render (${input.component}) refused: ${error instanceof Error?error.message:String(error)}; nothing was drawn`);return{tree:ENGINE_NODE,notes}}const adjusted=adjustRenderTree(settled,input.component);for(const{key,text}of adjusted.notes)note(text,`${input.component}\0${key}`);return{tree:adjusted.tree,notes}}async builtinTool(name2){if(!this.resolveTool)return void 0;let builtin=false;switch(name2){case ToolNames.SHELL:builtin=await this.resolveTool(name2)instanceof(await import("./shell-OLZVNTQZ.js")).ShellTool;break;case ToolNames.EDIT:builtin=await this.resolveTool(name2)instanceof(await import("./edit-3HMQPCHN.js")).EditTool;break;case ToolNames.WRITE_FILE:builtin=await this.resolveTool(name2)instanceof(await import("./write-file-EJNMAHQD.js")).WriteFileTool;break;default:return void 0}return builtin?name2:void 0}async runTool(input,next,signal){if(this.tool||this.pending)throw new Error("A Mod dispatch is already running.");const owner={next,controller:new AbortController,operations:new Map,checks:new Map,tail:Promise.resolve()};this.tool=owner;try{const builtinTool=await this.builtinTool(input.tool);const result=await this.request({type:"tool",input,builtinTool},AbortSignal.any([signal,owner.controller.signal]));validateResult("tool.call",result);return result}finally{owner.controller.abort();await Promise.allSettled([...owner.operations.values()].map(operation=>operation.task));this.tool=void 0}}executeHost(reply){const owner=this.tool;const root=this.root;if(!owner||!root||owner.operations.size>=32||owner.operations.has(reply.id)){this.fail(new Error("Invalid Mod host operation."));return}const controller=new AbortController;const signal=AbortSignal.any([owner.controller.signal,controller.signal]);const task=owner.tail.then(async()=>{signal.throwIfAborted();root.native=reply.id;root.phase++;root.idle=void 0;root.refresh();this.post({type:"native",id:reply.id},root.id);const result=await owner.next(reply.input,signal,async(input,verdict,checkSignal)=>{const active=AbortSignal.any([signal,checkSignal]);active.throwIfAborted();const id=++this.sequence;let abort=__name(()=>{},"abort");try{return await new Promise((resolve,reject)=>{abort=__name(()=>reject(new Error("Mod permission check cancelled.")),"abort");owner.checks.set(id,response=>{if(response.error!==void 0)reject(new Error(response.error));else{try{validateResult("tool.check",response.result);resolve({...response.result,ceiling:input.ceiling})}catch(error){reject(error)}}});root.idle=void 0;root.phase++;root.refresh();active.addEventListener("abort",abort,{once:true});this.post({type:"tool-check",id,operation:reply.id,input,verdict},root.id)})}finally{active.removeEventListener("abort",abort);owner.checks.delete(id);root.refresh()}});root.native=void 0;root.phase++;root.idle=void 0;root.refresh();signal.throwIfAborted();this.post({type:"host-result",id:reply.id,result},root.id)}).catch(error=>{root.native=void 0;root.phase++;root.idle=void 0;root.refresh();if(!this.failure)this.post({type:"host-result",id:reply.id,error:String(error).slice(0,4e3)},root.id)}).finally(()=>{owner.operations.delete(reply.id)});owner.operations.set(reply.id,{controller,task});owner.tail=task}post(request,root){if(this.root?.id!==root)return;const json=JSON.stringify(request);if(Buffer.byteLength(json)>MOD_MAX_BYTES+8192)throw new Error("Mod host message is too large.");assertModDepth(json,"Mod host message");this.worker.postMessage({...request,root,phase:this.root.phase})}async runCommand(command,args,signal,presentation){if(!this.commands.some(item=>item.name===command))throw new Error("Unknown Mod command.");const result=await this.request({type:"command",command,args,...this.surface==="terminal"&&presentation?{presentation}:{}},signal);if(!result||typeof result!=="object"||Array.isArray(result)||Object.keys(result).some(key=>key!=="text")||"text"in result&&typeof result.text!=="string"){throw new Error("Invalid Mod command result.")}return"text"in result?result.text:""}async startTurn(input,signal){validateResult("turn.start",await this.request({type:"turn-start",input},signal))}async completeTurn(input,signal){const result=await this.request({type:"turn-complete",input},signal);validateResult("turn.complete",result);return result.text}answerTurnAbort(reply,root){let error;try{if(!this.abortTurn)throw new Error(`$.turn.abort: no turn is running (asked for ${reply.turnId})`);this.abortTurn(reply.turnId)}catch(caught){error=(caught instanceof Error?caught.message:String(caught)).slice(0,4e3)}this.post({type:"turn-abort-result",id:reply.id,error},root)}async end(sessionId,reason,signal){await this.request({type:"end",sessionId,reason},signal,MOD_END_TIMEOUT_MS)}async dispose(){this.fail(new Error("Mod runtime is closed."));await this.worker.terminate();await Promise.allSettled([...this.tool?.operations.values()??[]].map(operation=>operation.task))}fail(error){this.failure??=error;this.tool?.controller.abort();this.pending?.({type:"error",message:this.failure.message})}async request(request,signal,timeoutMs=6e4){signal.throwIfAborted();if(this.failure)throw this.failure;if(this.pending)throw new Error("A Mod dispatch is already running.");const message={...request,facts:this.facts()};const json=JSON.stringify(message);if(Buffer.byteLength(json)>(request.type==="load"?32:1)*MOD_MAX_BYTES+8192)throw new Error("Mod request is too large.");assertModDepth(json,"Mod request");let timer;let cancelTimer;let aborted=false;const budget=new ModBudget(timeoutMs+250);const stop=__name(()=>{this.fail(new Error(aborted?"Mod dispatch cancelled.":"Mod dispatch timed out."));void this.worker.terminate()},"stop");const root={id:++this.sequence,revision:0,phase:0,refresh:__name(()=>{if(aborted||this.root!==root)return;const lending=request.type==="tool"&&root.native!==void 0&&root.idle===root.native&&!this.tool?.checks.size&&!budget.expired;if(lending!==budget.lending){if(lending)budget.pause();else budget.resume()}if(timer)clearTimeout(timer);if(!budget.lending)timer=setTimeout(stop,budget.remainingMs)},"refresh")};this.root=root;const onAbort=__name(()=>{aborted=true;Atomics.store(this.cancelled,0,1);this.tool?.controller.abort();if(timer)clearTimeout(timer);cancelTimer=setTimeout(stop,250)},"onAbort");Atomics.store(this.cancelled,0,0);try{return await new Promise((resolve,reject)=>{this.pending=reply=>{if(this.failure)reject(this.failure);else if(aborted)reject(new Error("Mod dispatch cancelled."));else if(reply.type==="error")reject(new Error(reply.message));else if(reply.type==="result"){try{if(Buffer.byteLength(reply.json)>MOD_MAX_BYTES)throw new Error("Mod reply is too large.");resolve(JSON.parse(reply.json))}catch(error){reject(error)}}};signal.addEventListener("abort",onAbort,{once:true});root.refresh();this.worker.postMessage({...message,root:root.id,phase:root.phase})})}finally{this.root=void 0;if(timer)clearTimeout(timer);if(cancelTimer)clearTimeout(cancelTimer);signal.removeEventListener("abort",onAbort);this.pending=void 0}}};var logger=createDebugLogger("MODS");var RENDER_SETTLE_MS=150;var RENDER_LIVE_MS=34;var RENDER_STEADY_MS=100;var RENDER_SLOW_MS=1e3;var ModSession=class _ModSession{constructor(config,output,optionScopes=[]){this.config=config;this.output=output;this.optionScopes=optionScopes;this.sessionId=config.getSessionId();uiTelemetryService.on("update",this.observe);this.unregisterCleanup=registerCleanup(()=>{this.unregisterCleanup=()=>{};return this.close().then(()=>this.flushOutput())},{first:Boolean(this.terminal)})}static{__name(this,"ModSession")}mods=[];runtime;toolQueue=Promise.resolve();lifetime=new AbortController;endLifetime=new AbortController;initialization;closing;logsReady=false;pendingLogs=[];notes=[];activeCommand;commandSignal;toolSignal;sessionId;adoptedAt=Date.now();startedAt;recorder;context={tokens:0,window:0};turn;observe=__name(update=>runOutsideAgentContext(()=>{if(this.config.getSessionId()!==this.sessionId)return;this.recorder=this.config.getChatRecordingService();this.context={tokens:uiTelemetryService.getLastPromptTokenCount(),window:this.config.getContentGeneratorConfig()?.contextWindowSize||0};const event=update?.event;if(!this.turn||event?.["event.name"]!==EVENT_API_RESPONSE)return;const response=event;if(response.subagent_name===void 0&&!isInternalPromptId(response.prompt_id)&&(this.turn.promptId===void 0||response.prompt_id===this.turn.promptId))this.turn.model=response.model}),"observe");toolGeneration=new AbortController;sites=[];band={state:"idle",again:false,startedAt:-Infinity,steadyUntil:0};unregisterCleanup;static create(config,settings,output){return settings.merged.experimental?.mods?new _ModSession(config,output,[settings.systemDefaults.settings.pluginConfigs,settings.user.settings.pluginConfigs,settings.system.settings.pluginConfigs]):void 0}get terminal(){return"surface"in this.output?this.output:void 0}allowed(){return this.config.isInteractive()===Boolean(this.terminal)&&!this.config.getExperimentalZedIntegration()&&this.config.isTrustedFolder()&&!this.config.getDisableAllHooks()&&!this.config.getBareMode()&&!this.config.isSafeMode()&&!this.config.getExecutionEnvironment()&&!this.config.getExecutionEnvironmentFactory()&&!this.config.getHookSystem()?.isManaged()&&!this.config.getSandbox()&&!this.config.isSessionAgentSession()}async initialize(signal){if(this.closing)throw new Error("Mod session is closed.");if(!this.allowed()){if(this.mods.length){await this.close();throw new Error("Mods are no longer permitted in this session.")}return}this.initialization??=this.load(AbortSignal.any([signal,this.lifetime.signal]));await this.initialization}async load(signal){const sites=this.sites=this.terminal?.sites?.()??[];try{const candidates=[];for(const extension of this.config.getExtensions().filter(item=>item.isActive&&item.format!=="agent-plugins-v1")){signal.throwIfAborted();try{const source=await loadModSource(extension.path);const marketplace=extension.installMetadata?.marketplaceConfig?.name;candidates.push({extension,name:extension.name,version:extension.version,marketplace,source,dependencies:source?.dependencies??[],toolDialect:source?resolveModToolDialect(this.optionScopes,extension.name,marketplace):void 0,unsupportedEvents:source?resolveModUnsupportedEvents(this.optionScopes,extension.name,marketplace):void 0,options:source?resolveModOptions(source.userConfig,this.optionScopes,extension.name,marketplace):{}})}catch(error){throw new Error(`Mod ${extension.name}: ${error instanceof Error?error.message:String(error)}`)}}const pending=candidates.filter(item=>item.source);const reachable=new Set;while(pending.length){signal.throwIfAborted();const plugin=pending.shift();if(reachable.has(plugin))continue;reachable.add(plugin);if(!plugin.source){try{plugin.dependencies=await loadModDependencies(plugin.extension.path)}catch(error){throw new Error(`Mod dependency ${plugin.name}: ${error instanceof Error?error.message:String(error)}`)}}for(const dependency2 of plugin.dependencies){pending.push(resolveModDependency(candidates,plugin,dependency2))}}const selected=candidates.filter(item=>reachable.has(item));orderModPlugins(selected);const mods=selected.filter(item=>item.source).map(plugin=>({...plugin,dependencies:plugin.dependencies.filter(dependency2=>resolveModDependency(selected,plugin,dependency2).source)}));const ordered=orderModPlugins(mods);if(ordered.length){this.runtime=await ModRuntime.createGroup(ordered.map(({extension,source,options,toolDialect,unsupportedEvents})=>({id:extension.id,name:extension.name,source:{root:source.root,entry:source.entry,source:source.source},options,toolDialect,unsupportedEvents})),this.config.getTargetDir(),(entry,plugin)=>{if(this.commandSignal?.aborted||this.toolSignal?.aborted)return;this.pendingLogs.push({...entry,plugin,sessionId:this.sessionId});if(this.logsReady)this.flushLogs()},signal,name2=>this.config.getToolRegistry().ensureTool(name2),this.terminal?.surface??null,this.config.getCliVersion()||"unknown",()=>this.facts(),turnId=>this.abortTurn(turnId),sites.length?{sites,invalidate:__name(()=>this.requestRender(),"invalidate")}:void 0);this.mods.push(...ordered.map(({extension})=>({id:extension.id,name:extension.name})));this.requestRender()}}catch(error){await this.runtime?.dispose();this.mods.length=0;throw error}}async loadCommands(signal){await this.initialize(signal);return this.mods.flatMap(mod=>this.runtime.getCommands(mod.id).map(command=>({name:command.name,description:this.terminal?sanitizeTerminalLine(command.description):command.description,kind:"file",source:"plugin-command",extensionName:this.terminal?sanitizeTerminalLine(mod.name):mod.name,supportedModes:[this.terminal?"interactive":"non_interactive"],argumentHint:this.terminal&&command.argumentHint!==void 0?sanitizeTerminalLine(command.argumentHint):command.argumentHint,modelInvocable:false,action:__name(async(context,args)=>{const active=AbortSignal.any([context.abortSignal??(this.terminal?this.lifetime.signal:signal),this.lifetime.signal]);const task=this.toolQueue.then(async()=>{active.throwIfAborted();if(!this.allowed()||!this.active()||this.closing){await this.runtime.dispose();throw new Error(`Mod ${mod.name} is disabled or its middleware chain changed.`)}if(this.sessionId!==this.config.getSessionId())throw new Error("The Mod command belongs to a previous session.");const controller=new AbortController;this.activeCommand=controller;const commandSignal=AbortSignal.any([active,controller.signal]);this.commandSignal=commandSignal;try{const content=await this.runtime.runCommand(command.name,args,commandSignal,this.terminal?.presentation());commandSignal.throwIfAborted();return{type:"message",messageType:"info",content:this.terminal?sanitizeTerminalText(stripUnsafeCharacters(content)):content}}finally{this.flushLogs();this.activeCommand=void 0;this.commandSignal=void 0}});this.toolQueue=task.catch(()=>{});return task},"action")})))}invalidateTools(){this.toolGeneration.abort();this.pendingLogs.length=0;this.activeCommand?.abort()}async restoreTools(){await this.toolQueue;if(!this.closing&&this.sessionId===this.config.getSessionId()){this.toolGeneration=new AbortController}}captureToolSignal(){return this.toolGeneration.signal}async syncSession(reason){const current=this.config.getSessionId();if(current===this.sessionId){if(this.toolGeneration.signal.aborted)this.toolGeneration=new AbortController;return}this.invalidateTools();const task=this.toolQueue.then(async()=>{if(current===this.sessionId||this.closing)return;await this.end(reason);this.sessionId=current;this.adoptedAt=Date.now();this.startedAt=void 0;this.recorder=void 0;this.context={tokens:0,window:0};this.capture();this.toolGeneration=new AbortController;this.requestRender()});this.toolQueue=task.catch(()=>{});await task}get hasToolHooks(){return this.runtime?.hasToolHooks===true}setRenderInput(input){const band=this.band;const key=[input.viewport?.columns,input.viewport?.isFullscreen,stableJson(input.props)].join("\0");band.input=input;if(key===band.key)return;const size=`${input.viewport?.columns}\0${input.props.maxRows}`;const resized=band.size!==void 0&&size!==band.size;band.key=key;band.size=size;if(resized){clearTimeout(band.settle);band.settle=setTimeout(()=>{band.settle=void 0;this.requestRender()},RENDER_SETTLE_MS)}else this.requestRender()}requestRender(){const band=this.band;if(this.closing||!band.input||!this.sites.includes(band.input.component)||band.settle||band.wait||!this.runtime?.renderHooks.length||band.state==="waiting")return;if(band.state==="running"){band.again=true;return}const now=Date.now();const gap=(now<band.steadyUntil?RENDER_STEADY_MS:RENDER_LIVE_MS)-(now-band.startedAt);if(gap>0){band.wait=setTimeout(()=>{band.wait=void 0;this.requestRender()},gap);return}band.state="waiting";this.toolQueue=this.toolQueue.then(()=>this.render()).catch(error=>logger.debug(`Mod ui.render: ${String(error)}`))}async render(){const band=this.band;const runtime=this.runtime;const owner=runtime.renderHooks.length===1?runtime.renderHooks[0]:"hooks";band.state="running";band.startedAt=Date.now();try{if(this.closing||this.sessionId!==this.config.getSessionId())return;if(!this.allowed()||!this.active()){this.terminal?.draw?.(ENGINE_NODE,owner);return}const{tree,notes}=await runtime.render(band.input,this.lifetime.signal);for(const note of notes)logger.debug(note);if(!this.closing)this.terminal?.draw?.(tree,owner)}catch(error){logger.debug(`Mod ui.render: ${String(error)}`);if(!this.closing)this.terminal?.draw?.(ENGINE_NODE,owner)}finally{if(Date.now()-band.startedAt>RENDER_LIVE_MS)band.steadyUntil=Date.now()+RENDER_SLOW_MS;band.state="idle";if(band.again){band.again=false;this.requestRender()}this.flushLogs()}}toolCall(onRepeat){if(!this.hasToolHooks)return void 0;return(input,next,signal)=>{const generation=this.toolGeneration;const sessionId=this.sessionId;const active=AbortSignal.any([signal,this.lifetime.signal,generation.signal]);const assertAllowed=__name(()=>{active.throwIfAborted();if(generation!==this.toolGeneration||sessionId!==this.config.getSessionId()||!this.allowed()||!this.active()||this.closing)throw new Error("Mod tool middleware is disabled or its chain changed.")},"assertAllowed");const task=this.toolQueue.then(async()=>{assertAllowed();let attempts=0;this.toolSignal=active;try{return await this.runtime.runTool(input,async(changed,hostSignal,check)=>{assertAllowed();if(attempts++)onRepeat();active.throwIfAborted();return next(changed,hostSignal,async(question,verdict,checkSignal)=>{assertAllowed();const result=await check(question,verdict,checkSignal);assertAllowed();checkSignal.throwIfAborted();return result})},active)}finally{if(this.toolSignal===active)this.toolSignal=void 0}});this.toolQueue=task.catch(()=>{});return task}}startTurn(text,signal,abort,promptId){const hooks=this.runtime?.turnHooks;if(!hooks||!hooks.start&&!hooks.complete.length||this.closing)return void 0;const turn={id:randomUUID(),sessionId:this.sessionId,startedAt:Date.now(),abort,aborting:false,streaming:"",answer:"",failed:false,...promptId!==void 0&&{promptId}};this.turn=turn;if(hooks.start){const fitted=fitTurnText(text);const input={text:fitted.text,turnId:turn.id,...fitted.truncated&&{isTextTruncated:true}};void this.queueTurnEvent(turn,lifetime=>this.runtime.startTurn(input,AbortSignal.any([lifetime,signal])))}let ending;return{id:turn.id,saw:__name(event=>this.see(turn,event),"saw"),complete:__name(reason=>ending??=this.completeTurn(turn,reason),"complete")}}see(turn,event){if(turn.ended||!this.runtime?.turnHooks.complete.length)return;switch(event.type){case"content":turn.streaming+=event.value;break;case"finished":turn.answer=turn.streaming;turn.streaming="";turn.usage=addTurnUsage(turn.usage,event.value.usageMetadata,this.config.getContentGeneratorConfig()?.authType);break;case"retry":if(!event.isContinuation)turn.streaming="";else if(!turn.streaming)turn.streaming=turn.answer;break;case"model_fallback":turn.streaming="";break;case"error":case"loop_detected":case"max_session_turns":case"session_token_limit_exceeded":turn.failed=true;break;default:break}}completeTurn(turn,ending){if(turn.ended)return turn.ended;if(this.turn===turn)this.turn=void 0;const plugins=this.runtime?.turnHooks.complete??[];if(!plugins.length)return Promise.resolve();const reason=turn.aborting||ending==="aborted"?"aborted":ending==="error"||turn.failed?"error":"answer";const answer=fitTurnText((turn.streaming||turn.answer).trim());const input={answer:answer.text,durationMs:Date.now()-turn.startedAt,isAborted:reason==="aborted",turnId:turn.id,reason,...turn.usage?{usage:{...turn.usage,model:turn.model??runOutsideAgentContext(()=>this.config.getModel())}}:{},...answer.truncated&&{isAnswerTruncated:true}};const run=__name(async signal=>{const text=await this.runtime.completeTurn(input,signal);if(text===input.answer||!text.trim())return;const note={text:cpLen(text)>4096?`${cpSlice(text,0,4096)}\u2026`:text,to:"transcript",plugin:plugins.join("+"),sessionId:turn.sessionId,isTurnNote:true};if(!this.terminal&&this.config.getOutputFormat()==="text")this.notes.push(`[Mod ${note.plugin}] ${stripAnsiAndControl(note.text)}`);else this.pendingLogs.push(note)},"run");return turn.ended=this.queueTurnEvent(turn,run,true)}queueTurnEvent(turn,run,isEnd=false){const task=this.toolQueue.then(async()=>{if(this.closing&&!isEnd||turn.sessionId!==this.sessionId||!this.allowed()||!this.active())return;try{await run(isEnd?this.endLifetime.signal:this.lifetime.signal)}finally{this.flushLogs()}}).catch(error=>logger.debug(`Mod turn event: ${String(error)}`));this.toolQueue=task;return task}abortTurn(turnId){const turn=this.turn;if(!turn)throw new Error(`$.turn.abort: no turn is running (asked for ${turnId})`);if(turn.id!==turnId)throw new Error(`$.turn.abort: ${turnId} is not the running turn (${turn.id}); a hook ends the turn turn.start told it about`);if(turn.aborting)throw new Error(`$.turn.abort: ${turnId} is already ending`);turn.aborting=true;let cancelled=false;try{cancelled=turn.abort()}finally{turn.aborting=cancelled}if(!cancelled)throw new Error(`$.turn.abort: ${turnId} is already ending`);logger.debug(`$.turn.abort: cancelled turn ${turnId}`)}flushLogs(){this.logsReady=true;for(const entry of this.pendingLogs.splice(0)){logger.debug(`[${entry.plugin}] ${entry.text}`);if(entry.to==="debug")continue;const text=this.terminal?sanitizeTerminalText(stripUnsafeCharacters(entry.text)):stripAnsiAndControl(entry.text);if("surface"in this.output){const{isTurnNote,...log}=entry;this.output.log({...log,text:isTurnNote?text:cpSlice(text,0,2e3)},entry.plugin,entry.sessionId)}else if(this.config.getOutputFormat()==="text"){process.stderr.write(`[Mod ${entry.plugin}] ${text}
|
|
3
|
+
import{projectJsonStringToByteBudget}from"./chunk-WQUA4G2X.js";import{flushOutput}from"./chunk-VURTGFJP.js";import{cpLen,cpSlice,sanitizeTerminalLine,sanitizeTerminalText,stripUnsafeCharacters}from"./chunk-64CA3W6G.js";import{require_semver}from"./chunk-YZUKMJW7.js";import{ENGINE_NODE,MOD_END_TIMEOUT_MS,MOD_MAX_BYTES,ModBudget,adjustRenderTree,assertModDepth,record,validateRenderTree,validateResult}from"./chunk-ZZJXFLVM.js";import{stableJson}from"./chunk-FIXDX63I.js";import{external_exports}from"./chunk-TWP72VRH.js";import{openNoFollow}from"./chunk-QXQGUM3Y.js";import{resolveBundleDir}from"./chunk-4NPYOXJO.js";import{runOutsideAgentContext}from"./chunk-YZFNBUKG.js";import{isInternalPromptId,uiTelemetryService}from"./chunk-ZWPSBU7K.js";import{getGenAiUsageProvenance,outputTokenCount}from"./chunk-4DIWAQ5G.js";import{EVENT_API_RESPONSE}from"./chunk-3XVPZY7X.js";import{registerCleanup}from"./chunk-3ICJI5KW.js";import{stripAnsiAndControl}from"./chunk-DBRQGEEI.js";import{ToolNames}from"./chunk-SBZFGYYS.js";import{createDebugLogger}from"./chunk-JAUJI56S.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name,__toESM}from"./chunk-KBWJGX7I.js";init_esbuild_shims();init_esbuild_shims();import{randomUUID}from"node:crypto";init_esbuild_shims();import{promises as fs}from"node:fs";import path from"node:path";init_esbuild_shims();var import_semver=__toESM(require_semver(),1);var name=external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/);var dependency=external_exports.union([external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]*(?:@[a-zA-Z0-9][a-zA-Z0-9._-]*)?$/),external_exports.object({name,marketplace:name.optional(),version:external_exports.string().optional()}).strict()]);function parseModDependencies(value){const parsed=external_exports.array(dependency).safeParse(value===void 0?[]:value);if(!parsed.success)throw new Error("Invalid Mod dependencies declaration.");return parsed.data.map(item=>{if(typeof item==="string"){const[name2,marketplace]=item.split("@");return{name:name2,marketplace}}if(item.version!==void 0&&!(0,import_semver.validRange)(item.version)){throw new Error(`Invalid Mod dependency version range for ${item.name}.`)}return item})}__name(parseModDependencies,"parseModDependencies");function resolveModDependency(plugins,plugin,dependency2){const marketplace=dependency2.marketplace??plugin.marketplace;const local=plugins.filter(item=>item.name===dependency2.name&&!item.marketplace);const matches=local.length?local:plugins.filter(item=>item.name===dependency2.name&&item.marketplace===marketplace);if(matches.length!==1){throw new Error(`Mod ${plugin.name}: dependency ${dependency2.name} must identify one installed, enabled plugin.`)}const target=matches[0];if(target.marketplace&&dependency2.version&&!(0,import_semver.satisfies)(target.version,dependency2.version)){throw new Error(`Mod ${plugin.name}: dependency ${dependency2.name} has an incompatible installed version.`)}return target}__name(resolveModDependency,"resolveModDependency");function orderModPlugins(plugins){const edges=plugins.map(()=>new Set);const incoming=plugins.map(()=>0);for(const[index,plugin]of plugins.entries()){for(const dependency2 of plugin.dependencies){const targetIndex=plugins.indexOf(resolveModDependency(plugins,plugin,dependency2));if(!edges[index].has(targetIndex)){edges[index].add(targetIndex);incoming[targetIndex]++}}}const ordered=[];const remaining=new Set(plugins.map((_,index)=>index));while(remaining.size){const next=[...remaining].find(index=>incoming[index]===0);if(next===void 0)throw new Error("Mod dependency cycle: activation refused.");remaining.delete(next);ordered.push(plugins[next]);for(const target of edges[next])incoming[target]--}return ordered}__name(orderModPlugins,"orderModPlugins");function isContainedFile(root,file){const relative=path.relative(root,file);return Boolean(relative)&&!path.isAbsolute(relative)&&relative!==".."&&!relative.startsWith(`..${path.sep}`)}__name(isContainedFile,"isContainedFile");async function readModFile(root,file){if(!isContainedFile(root,file)){throw new Error("Mod file must stay inside the installed extension.")}let current=root;for(const part of path.relative(root,file).split(path.sep)){current=path.join(current,part);const stat=await fs.lstat(current);if(stat.isSymbolicLink()){throw new Error("Mod files cannot be symbolic links.")}if(current===file&&!stat.isFile()){throw Object.assign(new Error("Mod input must be a regular file."),{code:stat.isDirectory()?"EISDIR":void 0})}}const entry=await fs.realpath(file);if(!isContainedFile(root,entry)){throw new Error("Mod file must stay inside the installed extension.")}const handle=await openNoFollow(entry);try{const stat=await handle.stat();if(!stat.isFile()||stat.size>MOD_MAX_BYTES){throw new Error("Mod file exceeds the 256 KiB regular-file limit.")}const buffer=Buffer.alloc(MOD_MAX_BYTES+1);const{bytesRead}=await handle.read(buffer,0,buffer.length,0);if(bytesRead>MOD_MAX_BYTES)throw new Error("Mod file is too large.");return{entry,source:buffer.subarray(0,bytesRead).toString("utf8")}}finally{await handle.close()}}__name(readModFile,"readModFile");async function readManifest(root,relative){try{if(path.isAbsolute(relative)){throw new Error("Mod manifest path must be relative to the extension.")}const value=JSON.parse((await readModFile(root,path.resolve(root,relative))).source);if(!value||typeof value!=="object"||Array.isArray(value)){throw new Error("Mod manifest must be a JSON object.")}return value}catch(error){if(error.code==="ENOENT")return void 0;throw error}}__name(readManifest,"readManifest");async function loadModSource(extensionPath){const root=await fs.realpath(extensionPath);const qwen=await readManifest(root,"qwen-extension.json");if(typeof qwen?.["hooks"]==="string"&&(path.isAbsolute(qwen["hooks"])||!isContainedFile(root,path.resolve(root,qwen["hooks"])))){return void 0}const claude=await readManifest(root,".claude-plugin/plugin.json");const hooksPath=typeof qwen?.["hooks"]==="string"?qwen["hooks"]:typeof claude?.["hooks"]==="string"?claude["hooks"]:"hooks/hooks.json";if(path.isAbsolute(hooksPath)||!isContainedFile(root,path.resolve(root,hooksPath))){return void 0}const hooks=await readManifest(root,hooksPath);if(!hooks||!Object.hasOwn(hooks,"modules"))return void 0;const modules=hooks["modules"];if(!Array.isArray(modules)||modules.length!==1||typeof modules[0]!=="string"||path.isAbsolute(modules[0])||!/\.(?:[cm]?js|[cm]?ts|[jt]sx)$/.test(modules[0])){throw new Error("Mods require one relative JavaScript, TypeScript or JSX module.")}const manifest={...claude,...qwen};const entry=path.resolve(root,path.dirname(hooksPath),modules[0]);return{root,...await readModFile(root,entry),userConfig:manifest["userConfig"],dependencies:parseModDependencies(manifest["dependencies"])}}__name(loadModSource,"loadModSource");async function loadModDependencies(extensionPath){const root=await fs.realpath(extensionPath);const qwen=await readManifest(root,"qwen-extension.json");const claude=await readManifest(root,".claude-plugin/plugin.json");return parseModDependencies({...claude,...qwen}["dependencies"])}__name(loadModDependencies,"loadModDependencies");init_esbuild_shims();var option=external_exports.union([external_exports.string(),external_exports.number().finite(),external_exports.boolean(),external_exports.array(external_exports.string())]);var field=external_exports.object({type:external_exports.enum(["string","number","boolean","directory","file"]),title:external_exports.string(),description:external_exports.string(),required:external_exports.boolean().optional(),default:option.optional(),multiple:external_exports.boolean().optional(),sensitive:external_exports.boolean().optional(),min:external_exports.number().finite().optional(),max:external_exports.number().finite().optional(),options:external_exports.array(external_exports.string().min(1).max(64)).nonempty().optional()}).strict().refine(value=>{if(!value.options)return true;return value.type==="string"&&!value.multiple&&!value.sensitive&&value.options.every(item=>item.trim()===item&&!/[\p{Cc}\p{Cf}]/u.test(item))&&new Set(value.options.map(item=>item.toLowerCase())).size===value.options.length&&(value.default===void 0?value.required===true:value.options.includes(value.default))});var schema=external_exports.record(external_exports.string().regex(/^[A-Za-z_]\w*$/),field);var storedOptions=external_exports.record(option);function*pluginConfigurations(scopes,name2,marketplace){const keys=marketplace?[`${name2}@${marketplace}`]:[name2,`${name2}@inline`];for(const scope of scopes){if(scope===void 0)continue;if(!scope||typeof scope!=="object"||Array.isArray(scope)){throw new Error("Invalid Mod pluginConfigs settings.")}for(const key of keys){if(!Object.hasOwn(scope,key))continue;const config=scope[key];if(!config||typeof config!=="object"||Array.isArray(config)){throw new Error("Invalid Mod pluginConfigs entry.")}yield config}}}__name(pluginConfigurations,"pluginConfigurations");function resolveModChoice(scopes,name2,marketplace,key,choices){let choice=choices[0];for(const config of pluginConfigurations(scopes,name2,marketplace)){const value=config[key];if(value===void 0)continue;if(!choices.includes(value))throw new Error(`Invalid Mod ${key}: expected ${choices.join(" or ")}.`);choice=value}return choice}__name(resolveModChoice,"resolveModChoice");function resolveModToolDialect(scopes,name2,marketplace){return resolveModChoice(scopes,name2,marketplace,"toolDialect",["native","claude"])}__name(resolveModToolDialect,"resolveModToolDialect");function resolveModUnsupportedEvents(scopes,name2,marketplace){return resolveModChoice(scopes,name2,marketplace,"unsupportedEvents",["skip","reject"])}__name(resolveModUnsupportedEvents,"resolveModUnsupportedEvents");function resolveModOptions(declaration,scopes,name2,marketplace){const parsed=schema.safeParse(declaration===void 0?{}:declaration);if(!parsed.success)throw new Error("Invalid Mod userConfig declaration.");const fields=Object.entries(parsed.data);if(!fields.length)return{};if(fields.some(([,value])=>value.sensitive)){throw new Error("Sensitive Mod userConfig is not supported yet.")}let stored={};for(const config of pluginConfigurations(scopes,name2,marketplace)){const options=config["options"];if(options===void 0)continue;const values=storedOptions.safeParse(options);if(!values.success)throw new Error(`Invalid Mod configured option: ${String(values.error.issues[0]?.path[0]??"").slice(0,64)}.`);stored={...stored,...values.data}}const result=Object.fromEntries(fields.filter(([,config])=>config.default!==void 0||!config.required).map(([key,config])=>[key,config.default??""]));for(const[key,value]of Object.entries(stored)){const choices=Object.hasOwn(parsed.data,key)?parsed.data[key].options:void 0;if(!choices||choices.includes(value))Object.defineProperty(result,key,{value,enumerable:true,writable:true,configurable:true})}for(const[key,config]of fields){const value=Object.hasOwn(result,key)?result[key]:void 0;if(value===void 0||value===""){if(config.required)throw new Error(`Missing required Mod option: ${key}.`)}else{const valid=config.type==="number"?typeof value==="number"&&(config.min===void 0||value>=config.min)&&(config.max===void 0||value<=config.max):config.type==="boolean"?typeof value==="boolean":typeof value==="string"||config.type==="string"&&config.multiple&&Array.isArray(value);if(!valid)throw new Error(`Invalid Mod option: ${key}.`)}}if(Buffer.byteLength(JSON.stringify(result))>MOD_MAX_BYTES){throw new Error("Mod options exceed the 256 KiB limit.")}return result}__name(resolveModOptions,"resolveModOptions");init_esbuild_shims();import{Worker}from"node:worker_threads";import{existsSync}from"node:fs";import path2 from"node:path";import{createRequire}from"node:module";import{pathToFileURL}from"node:url";function workerEntry(){if(import.meta.url.endsWith(".ts")){return new URL(`data:text/javascript,${encodeURIComponent(`import { register } from ${JSON.stringify(pathToFileURL(createRequire(import.meta.url).resolve("tsx/esm/api")).href)}; register(); await import(${JSON.stringify(new URL("./mod-worker.ts",import.meta.url).href)});`)}`)}const sibling=new URL("./mod-worker.js",import.meta.url);return existsSync(sibling)?sibling:path2.join(resolveBundleDir(import.meta.url),"mod-worker.js")}__name(workerEntry,"workerEntry");var ModRuntime=class _ModRuntime{constructor(log,facts,resolveTool,surface=null,abortTurn,renderHost){this.log=log;this.facts=facts;this.resolveTool=resolveTool;this.surface=surface;this.abortTurn=abortTurn;this.renderHost=renderHost;this.worker=new Worker(workerEntry(),{stdout:true,stderr:true,workerData:this.cancelled.buffer});this.worker.stdout?.resume();this.worker.stderr?.resume();this.worker.on("message",reply=>{const root=this.root;if(!root||reply.root!==root.id)return;if(reply.type==="host-call")this.executeHost(reply);else if(reply.type==="host-cancel"){for(const id of reply.ids)this.tool?.operations.get(id)?.controller.abort()}else if(reply.type==="check-result")this.tool?.checks.get(reply.id)?.(reply);else if(reply.type==="turn-abort")this.answerTurnAbort(reply,root.id);else if(reply.type==="invalidate"){if(reply.event!=="ui.render"||this.failure)return;if(this.early)this.early.add(reply.plugin);else if(this.renders.includes(reply.plugin))this.renderHost?.invalidate(reply.plugin)}else if(reply.type==="activity"){if(reply.phase!==root.phase||reply.revision<=root.revision||reply.operation!==void 0&&reply.operation!==root.native)return;root.revision=reply.revision;root.idle=this.tool?.checks.size?void 0:reply.operation;root.refresh()}else if(reply.type==="log"){if(this.failure)return;try{this.log({text:reply.text,to:reply.to},reply.plugin)}catch(error){this.fail(error instanceof Error?error:new Error(String(error)));void this.worker.terminate()}}else this.pending?.(reply)});this.worker.on("error",error=>this.fail(error));this.worker.on("exit",code=>this.fail(new Error(`Mod worker exited (${code}).`)))}static{__name(this,"ModRuntime")}worker;failure;pending;commands=[];tools=false;turns={start:false,complete:[]};renders=[];early=new Set;noted=new Set;sequence=0;root;tool;cancelled=new Int32Array(new SharedArrayBuffer(4));static async create(source,cwd,log,signal,options={}){return _ModRuntime.createGroup([{id:"mod",name:"mod",source,options}],cwd,log,signal)}static async createGroup(plugins,cwd,log,signal,resolveTool,surface=null,version="unknown",facts,abortTurn,render){if(plugins.length>32||new Set(plugins.map(p=>p.id)).size!==plugins.length)throw new Error("Invalid Mod plugin group.");const startedAt=Date.now();const runtime=new _ModRuntime(log,facts??(()=>({id:"",cwd,root:cwd,model:"",turns:0,usage:{startedAt,context:{tokens:0,window:0},rateLimits:[]}})),plugins.some(plugin=>plugin.toolDialect==="claude")?resolveTool:void 0,surface,abortTurn,render);try{const result=await runtime.request({type:"load",plugins,cwd,surface,version,sites:render?.sites??[]},signal,6e4);const names=__name(value=>Array.isArray(value)&&value.every(name2=>plugins.some(plugin=>plugin.name===name2)),"names");const turnComplete=record(result)?result["turnComplete"]:void 0;const renders=record(result)?result["render"]:void 0;if(!record(result)||typeof result["tools"]!=="boolean"||typeof result["turnStart"]!=="boolean"||!names(turnComplete)||!names(renders))throw new Error("Invalid Mod declarations.");const commands=result["commands"];if(!Array.isArray(commands)||commands.length>64||commands.some(command=>!command||!plugins.some(plugin=>plugin.id===command.plugin)||typeof command.name!=="string"||!/^[a-zA-Z0-9_-]{1,64}$/.test(command.name)||typeof command.description!=="string"||command.argumentHint!==void 0&&typeof command.argumentHint!=="string"))throw new Error("Invalid Mod command declarations.");runtime.commands=commands;runtime.tools=result["tools"];runtime.turns={start:result["turnStart"],complete:turnComplete};runtime.renders=renders;const early=runtime.early;runtime.early=void 0;for(const plugin of early)if(renders.includes(plugin))render?.invalidate(plugin);return runtime}catch(error){await runtime.dispose();throw error}}getCommands(plugin="mod"){return this.commands.filter(command=>command.plugin===plugin).map(({plugin:_plugin,...command})=>command)}get hasToolHooks(){return this.tools}get turnHooks(){return this.turns}get renderHooks(){return this.renders}async render(input,signal){const settled=await this.request({type:"render",input},signal);const owner=this.renders.length===1?this.renders[0]:"hooks";const notes=[];const note=__name((line,key=line)=>{if(this.noted.has(key))return;this.noted.add(key);notes.push(`${owner}: ${line}`)},"note");try{validateRenderTree(settled)}catch(error){note(`ui.render (${input.component}) refused: ${error instanceof Error?error.message:String(error)}; nothing was drawn`);return{tree:ENGINE_NODE,notes}}const adjusted=adjustRenderTree(settled,input.component);for(const{key,text}of adjusted.notes)note(text,`${input.component}\0${key}`);return{tree:adjusted.tree,notes}}async builtinTool(name2){if(!this.resolveTool)return void 0;let builtin=false;switch(name2){case ToolNames.SHELL:builtin=await this.resolveTool(name2)instanceof(await import("./shell-WYQDZWL7.js")).ShellTool;break;case ToolNames.EDIT:builtin=await this.resolveTool(name2)instanceof(await import("./edit-XCECLEH3.js")).EditTool;break;case ToolNames.WRITE_FILE:builtin=await this.resolveTool(name2)instanceof(await import("./write-file-UMJVKE4S.js")).WriteFileTool;break;default:return void 0}return builtin?name2:void 0}async runTool(input,next,signal){if(this.tool||this.pending)throw new Error("A Mod dispatch is already running.");const owner={next,controller:new AbortController,operations:new Map,checks:new Map,tail:Promise.resolve()};this.tool=owner;try{const builtinTool=await this.builtinTool(input.tool);const result=await this.request({type:"tool",input,builtinTool},AbortSignal.any([signal,owner.controller.signal]));validateResult("tool.call",result);return result}finally{owner.controller.abort();await Promise.allSettled([...owner.operations.values()].map(operation=>operation.task));this.tool=void 0}}executeHost(reply){const owner=this.tool;const root=this.root;if(!owner||!root||owner.operations.size>=32||owner.operations.has(reply.id)){this.fail(new Error("Invalid Mod host operation."));return}const controller=new AbortController;const signal=AbortSignal.any([owner.controller.signal,controller.signal]);const task=owner.tail.then(async()=>{signal.throwIfAborted();root.native=reply.id;root.phase++;root.idle=void 0;root.refresh();this.post({type:"native",id:reply.id},root.id);const result=await owner.next(reply.input,signal,async(input,verdict,checkSignal)=>{const active=AbortSignal.any([signal,checkSignal]);active.throwIfAborted();const id=++this.sequence;let abort=__name(()=>{},"abort");try{return await new Promise((resolve,reject)=>{abort=__name(()=>reject(new Error("Mod permission check cancelled.")),"abort");owner.checks.set(id,response=>{if(response.error!==void 0)reject(new Error(response.error));else{try{validateResult("tool.check",response.result);resolve({...response.result,ceiling:input.ceiling})}catch(error){reject(error)}}});root.idle=void 0;root.phase++;root.refresh();active.addEventListener("abort",abort,{once:true});this.post({type:"tool-check",id,operation:reply.id,input,verdict},root.id)})}finally{active.removeEventListener("abort",abort);owner.checks.delete(id);root.refresh()}});root.native=void 0;root.phase++;root.idle=void 0;root.refresh();signal.throwIfAborted();this.post({type:"host-result",id:reply.id,result},root.id)}).catch(error=>{root.native=void 0;root.phase++;root.idle=void 0;root.refresh();if(!this.failure)this.post({type:"host-result",id:reply.id,error:String(error).slice(0,4e3)},root.id)}).finally(()=>{owner.operations.delete(reply.id)});owner.operations.set(reply.id,{controller,task});owner.tail=task}post(request,root){if(this.root?.id!==root)return;const json=JSON.stringify(request);if(Buffer.byteLength(json)>MOD_MAX_BYTES+8192)throw new Error("Mod host message is too large.");assertModDepth(json,"Mod host message");this.worker.postMessage({...request,root,phase:this.root.phase})}async runCommand(command,args,signal,presentation){if(!this.commands.some(item=>item.name===command))throw new Error("Unknown Mod command.");const result=await this.request({type:"command",command,args,...this.surface==="terminal"&&presentation?{presentation}:{}},signal);if(!result||typeof result!=="object"||Array.isArray(result)||Object.keys(result).some(key=>key!=="text")||"text"in result&&typeof result.text!=="string"){throw new Error("Invalid Mod command result.")}return"text"in result?result.text:""}async startTurn(input,signal){validateResult("turn.start",await this.request({type:"turn-start",input},signal))}async completeTurn(input,signal){const result=await this.request({type:"turn-complete",input},signal);validateResult("turn.complete",result);return result.text}answerTurnAbort(reply,root){let error;try{if(!this.abortTurn)throw new Error(`$.turn.abort: no turn is running (asked for ${reply.turnId})`);this.abortTurn(reply.turnId)}catch(caught){error=(caught instanceof Error?caught.message:String(caught)).slice(0,4e3)}this.post({type:"turn-abort-result",id:reply.id,error},root)}async end(sessionId,reason,signal){await this.request({type:"end",sessionId,reason},signal,MOD_END_TIMEOUT_MS)}async dispose(){this.fail(new Error("Mod runtime is closed."));await this.worker.terminate();await Promise.allSettled([...this.tool?.operations.values()??[]].map(operation=>operation.task))}fail(error){this.failure??=error;this.tool?.controller.abort();this.pending?.({type:"error",message:this.failure.message})}async request(request,signal,timeoutMs=6e4){signal.throwIfAborted();if(this.failure)throw this.failure;if(this.pending)throw new Error("A Mod dispatch is already running.");const message={...request,facts:this.facts()};const json=JSON.stringify(message);if(Buffer.byteLength(json)>(request.type==="load"?32:1)*MOD_MAX_BYTES+8192)throw new Error("Mod request is too large.");assertModDepth(json,"Mod request");let timer;let cancelTimer;let aborted=false;const budget=new ModBudget(timeoutMs+250);const stop=__name(()=>{this.fail(new Error(aborted?"Mod dispatch cancelled.":"Mod dispatch timed out."));void this.worker.terminate()},"stop");const root={id:++this.sequence,revision:0,phase:0,refresh:__name(()=>{if(aborted||this.root!==root)return;const lending=request.type==="tool"&&root.native!==void 0&&root.idle===root.native&&!this.tool?.checks.size&&!budget.expired;if(lending!==budget.lending){if(lending)budget.pause();else budget.resume()}if(timer)clearTimeout(timer);if(!budget.lending)timer=setTimeout(stop,budget.remainingMs)},"refresh")};this.root=root;const onAbort=__name(()=>{aborted=true;Atomics.store(this.cancelled,0,1);this.tool?.controller.abort();if(timer)clearTimeout(timer);cancelTimer=setTimeout(stop,250)},"onAbort");Atomics.store(this.cancelled,0,0);try{return await new Promise((resolve,reject)=>{this.pending=reply=>{if(this.failure)reject(this.failure);else if(aborted)reject(new Error("Mod dispatch cancelled."));else if(reply.type==="error")reject(new Error(reply.message));else if(reply.type==="result"){try{if(Buffer.byteLength(reply.json)>MOD_MAX_BYTES)throw new Error("Mod reply is too large.");resolve(JSON.parse(reply.json))}catch(error){reject(error)}}};signal.addEventListener("abort",onAbort,{once:true});root.refresh();this.worker.postMessage({...message,root:root.id,phase:root.phase})})}finally{this.root=void 0;if(timer)clearTimeout(timer);if(cancelTimer)clearTimeout(cancelTimer);signal.removeEventListener("abort",onAbort);this.pending=void 0}}};var logger=createDebugLogger("MODS");var RENDER_SETTLE_MS=150;var RENDER_LIVE_MS=34;var RENDER_STEADY_MS=100;var RENDER_SLOW_MS=1e3;var ModSession=class _ModSession{constructor(config,output,optionScopes=[]){this.config=config;this.output=output;this.optionScopes=optionScopes;this.sessionId=config.getSessionId();uiTelemetryService.on("update",this.observe);this.unregisterCleanup=registerCleanup(()=>{this.unregisterCleanup=()=>{};return this.close().then(()=>this.flushOutput())},{first:Boolean(this.terminal)})}static{__name(this,"ModSession")}mods=[];runtime;toolQueue=Promise.resolve();lifetime=new AbortController;endLifetime=new AbortController;initialization;closing;logsReady=false;pendingLogs=[];notes=[];activeCommand;commandSignal;toolSignal;sessionId;adoptedAt=Date.now();startedAt;recorder;context={tokens:0,window:0};turn;observe=__name(update=>runOutsideAgentContext(()=>{if(this.config.getSessionId()!==this.sessionId)return;this.recorder=this.config.getChatRecordingService();this.context={tokens:uiTelemetryService.getLastPromptTokenCount(),window:this.config.getContentGeneratorConfig()?.contextWindowSize||0};const event=update?.event;if(!this.turn||event?.["event.name"]!==EVENT_API_RESPONSE)return;const response=event;if(response.subagent_name===void 0&&!isInternalPromptId(response.prompt_id)&&(this.turn.promptId===void 0||response.prompt_id===this.turn.promptId))this.turn.model=response.model}),"observe");toolGeneration=new AbortController;sites=[];band={state:"idle",again:false,startedAt:-Infinity,steadyUntil:0};unregisterCleanup;static create(config,settings,output){return settings.merged.experimental?.mods?new _ModSession(config,output,[settings.systemDefaults.settings.pluginConfigs,settings.user.settings.pluginConfigs,settings.system.settings.pluginConfigs]):void 0}get terminal(){return"surface"in this.output?this.output:void 0}allowed(){return this.config.isInteractive()===Boolean(this.terminal)&&!this.config.getExperimentalZedIntegration()&&this.config.isTrustedFolder()&&!this.config.getDisableAllHooks()&&!this.config.getBareMode()&&!this.config.isSafeMode()&&!this.config.getExecutionEnvironment()&&!this.config.getExecutionEnvironmentFactory()&&!this.config.getHookSystem()?.isManaged()&&!this.config.getSandbox()&&!this.config.isSessionAgentSession()}async initialize(signal){if(this.closing)throw new Error("Mod session is closed.");if(!this.allowed()){if(this.mods.length){await this.close();throw new Error("Mods are no longer permitted in this session.")}return}this.initialization??=this.load(AbortSignal.any([signal,this.lifetime.signal]));await this.initialization}async load(signal){const sites=this.sites=this.terminal?.sites?.()??[];try{const candidates=[];for(const extension of this.config.getExtensions().filter(item=>item.isActive&&item.format!=="agent-plugins-v1")){signal.throwIfAborted();try{const source=await loadModSource(extension.path);const marketplace=extension.installMetadata?.marketplaceConfig?.name;candidates.push({extension,name:extension.name,version:extension.version,marketplace,source,dependencies:source?.dependencies??[],toolDialect:source?resolveModToolDialect(this.optionScopes,extension.name,marketplace):void 0,unsupportedEvents:source?resolveModUnsupportedEvents(this.optionScopes,extension.name,marketplace):void 0,options:source?resolveModOptions(source.userConfig,this.optionScopes,extension.name,marketplace):{}})}catch(error){throw new Error(`Mod ${extension.name}: ${error instanceof Error?error.message:String(error)}`)}}const pending=candidates.filter(item=>item.source);const reachable=new Set;while(pending.length){signal.throwIfAborted();const plugin=pending.shift();if(reachable.has(plugin))continue;reachable.add(plugin);if(!plugin.source){try{plugin.dependencies=await loadModDependencies(plugin.extension.path)}catch(error){throw new Error(`Mod dependency ${plugin.name}: ${error instanceof Error?error.message:String(error)}`)}}for(const dependency2 of plugin.dependencies){pending.push(resolveModDependency(candidates,plugin,dependency2))}}const selected=candidates.filter(item=>reachable.has(item));orderModPlugins(selected);const mods=selected.filter(item=>item.source).map(plugin=>({...plugin,dependencies:plugin.dependencies.filter(dependency2=>resolveModDependency(selected,plugin,dependency2).source)}));const ordered=orderModPlugins(mods);if(ordered.length){this.runtime=await ModRuntime.createGroup(ordered.map(({extension,source,options,toolDialect,unsupportedEvents})=>({id:extension.id,name:extension.name,source:{root:source.root,entry:source.entry,source:source.source},options,toolDialect,unsupportedEvents})),this.config.getTargetDir(),(entry,plugin)=>{if(this.commandSignal?.aborted||this.toolSignal?.aborted)return;this.pendingLogs.push({...entry,plugin,sessionId:this.sessionId});if(this.logsReady)this.flushLogs()},signal,name2=>this.config.getToolRegistry().ensureTool(name2),this.terminal?.surface??null,this.config.getCliVersion()||"unknown",()=>this.facts(),turnId=>this.abortTurn(turnId),sites.length?{sites,invalidate:__name(()=>this.requestRender(),"invalidate")}:void 0);this.mods.push(...ordered.map(({extension})=>({id:extension.id,name:extension.name})));this.requestRender()}}catch(error){await this.runtime?.dispose();this.mods.length=0;throw error}}async loadCommands(signal){await this.initialize(signal);return this.mods.flatMap(mod=>this.runtime.getCommands(mod.id).map(command=>({name:command.name,description:this.terminal?sanitizeTerminalLine(command.description):command.description,kind:"file",source:"plugin-command",extensionName:this.terminal?sanitizeTerminalLine(mod.name):mod.name,supportedModes:[this.terminal?"interactive":"non_interactive"],argumentHint:this.terminal&&command.argumentHint!==void 0?sanitizeTerminalLine(command.argumentHint):command.argumentHint,modelInvocable:false,action:__name(async(context,args)=>{const active=AbortSignal.any([context.abortSignal??(this.terminal?this.lifetime.signal:signal),this.lifetime.signal]);const task=this.toolQueue.then(async()=>{active.throwIfAborted();if(!this.allowed()||!this.active()||this.closing){await this.runtime.dispose();throw new Error(`Mod ${mod.name} is disabled or its middleware chain changed.`)}if(this.sessionId!==this.config.getSessionId())throw new Error("The Mod command belongs to a previous session.");const controller=new AbortController;this.activeCommand=controller;const commandSignal=AbortSignal.any([active,controller.signal]);this.commandSignal=commandSignal;try{const content=await this.runtime.runCommand(command.name,args,commandSignal,this.terminal?.presentation());commandSignal.throwIfAborted();return{type:"message",messageType:"info",content:this.terminal?sanitizeTerminalText(stripUnsafeCharacters(content)):content}}finally{this.flushLogs();this.activeCommand=void 0;this.commandSignal=void 0}});this.toolQueue=task.catch(()=>{});return task},"action")})))}invalidateTools(){this.toolGeneration.abort();this.pendingLogs.length=0;this.activeCommand?.abort()}async restoreTools(){await this.toolQueue;if(!this.closing&&this.sessionId===this.config.getSessionId()){this.toolGeneration=new AbortController}}captureToolSignal(){return this.toolGeneration.signal}async syncSession(reason){const current=this.config.getSessionId();if(current===this.sessionId){if(this.toolGeneration.signal.aborted)this.toolGeneration=new AbortController;return}this.invalidateTools();const task=this.toolQueue.then(async()=>{if(current===this.sessionId||this.closing)return;await this.end(reason);this.sessionId=current;this.adoptedAt=Date.now();this.startedAt=void 0;this.recorder=void 0;this.context={tokens:0,window:0};this.capture();this.toolGeneration=new AbortController;this.requestRender()});this.toolQueue=task.catch(()=>{});await task}get hasToolHooks(){return this.runtime?.hasToolHooks===true}setRenderInput(input){const band=this.band;const key=[input.viewport?.columns,input.viewport?.isFullscreen,stableJson(input.props)].join("\0");band.input=input;if(key===band.key)return;const size=`${input.viewport?.columns}\0${input.props.maxRows}`;const resized=band.size!==void 0&&size!==band.size;band.key=key;band.size=size;if(resized){clearTimeout(band.settle);band.settle=setTimeout(()=>{band.settle=void 0;this.requestRender()},RENDER_SETTLE_MS)}else this.requestRender()}requestRender(){const band=this.band;if(this.closing||!band.input||!this.sites.includes(band.input.component)||band.settle||band.wait||!this.runtime?.renderHooks.length||band.state==="waiting")return;if(band.state==="running"){band.again=true;return}const now=Date.now();const gap=(now<band.steadyUntil?RENDER_STEADY_MS:RENDER_LIVE_MS)-(now-band.startedAt);if(gap>0){band.wait=setTimeout(()=>{band.wait=void 0;this.requestRender()},gap);return}band.state="waiting";this.toolQueue=this.toolQueue.then(()=>this.render()).catch(error=>logger.debug(`Mod ui.render: ${String(error)}`))}async render(){const band=this.band;const runtime=this.runtime;const owner=runtime.renderHooks.length===1?runtime.renderHooks[0]:"hooks";band.state="running";band.startedAt=Date.now();try{if(this.closing||this.sessionId!==this.config.getSessionId())return;if(!this.allowed()||!this.active()){this.terminal?.draw?.(ENGINE_NODE,owner);return}const{tree,notes}=await runtime.render(band.input,this.lifetime.signal);for(const note of notes)logger.debug(note);if(!this.closing)this.terminal?.draw?.(tree,owner)}catch(error){logger.debug(`Mod ui.render: ${String(error)}`);if(!this.closing)this.terminal?.draw?.(ENGINE_NODE,owner)}finally{if(Date.now()-band.startedAt>RENDER_LIVE_MS)band.steadyUntil=Date.now()+RENDER_SLOW_MS;band.state="idle";if(band.again){band.again=false;this.requestRender()}this.flushLogs()}}toolCall(onRepeat){if(!this.hasToolHooks)return void 0;return(input,next,signal)=>{const generation=this.toolGeneration;const sessionId=this.sessionId;const active=AbortSignal.any([signal,this.lifetime.signal,generation.signal]);const assertAllowed=__name(()=>{active.throwIfAborted();if(generation!==this.toolGeneration||sessionId!==this.config.getSessionId()||!this.allowed()||!this.active()||this.closing)throw new Error("Mod tool middleware is disabled or its chain changed.")},"assertAllowed");const task=this.toolQueue.then(async()=>{assertAllowed();let attempts=0;this.toolSignal=active;try{return await this.runtime.runTool(input,async(changed,hostSignal,check)=>{assertAllowed();if(attempts++)onRepeat();active.throwIfAborted();return next(changed,hostSignal,async(question,verdict,checkSignal)=>{assertAllowed();const result=await check(question,verdict,checkSignal);assertAllowed();checkSignal.throwIfAborted();return result})},active)}finally{if(this.toolSignal===active)this.toolSignal=void 0}});this.toolQueue=task.catch(()=>{});return task}}startTurn(text,signal,abort,promptId){const hooks=this.runtime?.turnHooks;if(!hooks||!hooks.start&&!hooks.complete.length||this.closing)return void 0;const turn={id:randomUUID(),sessionId:this.sessionId,startedAt:Date.now(),abort,aborting:false,streaming:"",answer:"",failed:false,...promptId!==void 0&&{promptId}};this.turn=turn;if(hooks.start){const fitted=fitTurnText(text);const input={text:fitted.text,turnId:turn.id,...fitted.truncated&&{isTextTruncated:true}};void this.queueTurnEvent(turn,lifetime=>this.runtime.startTurn(input,AbortSignal.any([lifetime,signal])))}let ending;return{id:turn.id,saw:__name(event=>this.see(turn,event),"saw"),complete:__name(reason=>ending??=this.completeTurn(turn,reason),"complete")}}see(turn,event){if(turn.ended||!this.runtime?.turnHooks.complete.length)return;switch(event.type){case"content":turn.streaming+=event.value;break;case"finished":turn.answer=turn.streaming;turn.streaming="";turn.usage=addTurnUsage(turn.usage,event.value.usageMetadata,this.config.getContentGeneratorConfig()?.authType);break;case"retry":if(!event.isContinuation)turn.streaming="";else if(!turn.streaming)turn.streaming=turn.answer;break;case"model_fallback":turn.streaming="";break;case"error":case"loop_detected":case"max_session_turns":case"session_token_limit_exceeded":turn.failed=true;break;default:break}}completeTurn(turn,ending){if(turn.ended)return turn.ended;if(this.turn===turn)this.turn=void 0;const plugins=this.runtime?.turnHooks.complete??[];if(!plugins.length)return Promise.resolve();const reason=turn.aborting||ending==="aborted"?"aborted":ending==="error"||turn.failed?"error":"answer";const answer=fitTurnText((turn.streaming||turn.answer).trim());const input={answer:answer.text,durationMs:Date.now()-turn.startedAt,isAborted:reason==="aborted",turnId:turn.id,reason,...turn.usage?{usage:{...turn.usage,model:turn.model??runOutsideAgentContext(()=>this.config.getModel())}}:{},...answer.truncated&&{isAnswerTruncated:true}};const run=__name(async signal=>{const text=await this.runtime.completeTurn(input,signal);if(text===input.answer||!text.trim())return;const note={text:cpLen(text)>4096?`${cpSlice(text,0,4096)}\u2026`:text,to:"transcript",plugin:plugins.join("+"),sessionId:turn.sessionId,isTurnNote:true};if(!this.terminal&&this.config.getOutputFormat()==="text")this.notes.push(`[Mod ${note.plugin}] ${stripAnsiAndControl(note.text)}`);else this.pendingLogs.push(note)},"run");return turn.ended=this.queueTurnEvent(turn,run,true)}queueTurnEvent(turn,run,isEnd=false){const task=this.toolQueue.then(async()=>{if(this.closing&&!isEnd||turn.sessionId!==this.sessionId||!this.allowed()||!this.active())return;try{await run(isEnd?this.endLifetime.signal:this.lifetime.signal)}finally{this.flushLogs()}}).catch(error=>logger.debug(`Mod turn event: ${String(error)}`));this.toolQueue=task;return task}abortTurn(turnId){const turn=this.turn;if(!turn)throw new Error(`$.turn.abort: no turn is running (asked for ${turnId})`);if(turn.id!==turnId)throw new Error(`$.turn.abort: ${turnId} is not the running turn (${turn.id}); a hook ends the turn turn.start told it about`);if(turn.aborting)throw new Error(`$.turn.abort: ${turnId} is already ending`);turn.aborting=true;let cancelled=false;try{cancelled=turn.abort()}finally{turn.aborting=cancelled}if(!cancelled)throw new Error(`$.turn.abort: ${turnId} is already ending`);logger.debug(`$.turn.abort: cancelled turn ${turnId}`)}flushLogs(){this.logsReady=true;for(const entry of this.pendingLogs.splice(0)){logger.debug(`[${entry.plugin}] ${entry.text}`);if(entry.to==="debug")continue;const text=this.terminal?sanitizeTerminalText(stripUnsafeCharacters(entry.text)):stripAnsiAndControl(entry.text);if("surface"in this.output){const{isTurnNote,...log}=entry;this.output.log({...log,text:isTurnNote?text:cpSlice(text,0,2e3)},entry.plugin,entry.sessionId)}else if(this.config.getOutputFormat()==="text"){process.stderr.write(`[Mod ${entry.plugin}] ${text}
|
|
4
4
|
`)}else{this.output.emitSystemMessage("ui_log",{plugin:entry.plugin,text})}}}async flushOutput(){if(this.notes.length&&!this.terminal)await flushOutput(process.stdout,AbortSignal.timeout(1500));for(const note of this.notes.splice(0))process.stderr.write(`${note}
|
|
5
5
|
`);await this.flushStreams()}async flushStreams(){if(this.terminal)return;const signal=AbortSignal.timeout(1500);await Promise.allSettled([flushOutput(process.stdout,signal),flushOutput(process.stderr,signal)])}capture(){this.observe();if(this.startedAt!==void 0)return this.startedAt;const resumed=this.config.getResumedSessionData()?.conversation;const first=resumed?.sessionId===this.sessionId?Date.parse(resumed.startTime):NaN;return this.startedAt=Number.isFinite(first)?first:this.adoptedAt}facts(){return runOutsideAgentContext(()=>this.readFacts())}readFacts(){const startedAt=this.capture();const{tokens,window}=this.context;return{id:this.sessionId,cwd:this.config.getTargetDir(),root:this.config.getProjectRoot(),model:this.config.getModel(),turns:this.recorder?.getUserTurnCount()??0,usage:{startedAt,context:{tokens,window,...window>0?{percent:Math.min(100,Math.round(tokens/window*100))}:{}},rateLimits:[]}}}active(){const extensions=this.config.getExtensions();return this.mods.every(mod=>extensions.some(extension=>extension.id===mod.id&&extension.isActive))}async end(reason){if(!this.allowed()||!this.active())return;try{await this.runtime?.end(this.sessionId,reason,AbortSignal.timeout(MOD_END_TIMEOUT_MS))}catch(error){logger.warn(`Mod session.end: ${String(error)}`)}}close(){this.closing??=(async()=>{this.unregisterCleanup();uiTelemetryService.off("update",this.observe);clearTimeout(this.band.settle);clearTimeout(this.band.wait);if(this.turn)void this.completeTurn(this.turn,"aborted");const endBudget=setTimeout(()=>this.endLifetime.abort(),MOD_END_TIMEOUT_MS);this.lifetime.abort();this.invalidateTools();await this.initialization?.catch(()=>{});try{await this.toolQueue;clearTimeout(endBudget);await this.end("other")}finally{clearTimeout(endBudget);this.endLifetime.abort();this.lifetime.abort();await this.runtime?.dispose();await this.flushStreams()}})();return this.closing}};function tokenCount(value){return typeof value==="number"&&Number.isFinite(value)&&value>=0?Math.floor(value):0}__name(tokenCount,"tokenCount");function addTurnUsage(usage,metadata,authType){if(!metadata)return usage;const prompt=tokenCount(metadata.promptTokenCount);const read=tokenCount(metadata.cachedContentTokenCount);const written=tokenCount(getGenAiUsageProvenance(metadata)?.cacheCreationInputTokens);const output=outputTokenCount({input:prompt,output:tokenCount(metadata.candidatesTokenCount),thoughts:tokenCount(metadata.thoughtsTokenCount),total:tokenCount(metadata.totalTokenCount)},authType);return{input_tokens:(usage?.input_tokens??0)+Math.max(0,prompt-read-written),output_tokens:(usage?.output_tokens??0)+output,cache_read_input_tokens:(usage?.cache_read_input_tokens??0)+read,cache_creation_input_tokens:(usage?.cache_creation_input_tokens??0)+written}}__name(addTurnUsage,"addTurnUsage");function fitTurnText(text){const fitted=projectJsonStringToByteBudget(text,MOD_MAX_BYTES/2,"\n[... truncated for Mods ...]\n");return{text:fitted,truncated:fitted!==text}}__name(fitTurnText,"fitTurnText");var sessions=new WeakMap;function isModRecoveryCommand(command){return command?.kind==="built-in"&&(command.name==="help"||command.name==="quit")}__name(isModRecoveryCommand,"isModRecoveryCommand");function createInteractiveModSession(config,settings){if(!settings.merged.experimental?.mods||!config.isInteractive())return;let session=sessions.get(config);if(!session){session=new InteractiveModSession(config,settings);sessions.set(config,session)}return session}__name(createInteractiveModSession,"createInteractiveModSession");function getInteractiveModSession(config){return config?sessions.get(config):void 0}__name(getInteractiveModSession,"getInteractiveModSession");var InteractiveModSession=class{constructor(config,settings){this.config=config;this.startup.catch(()=>{});this.session=ModSession.create(config,settings,{surface:"terminal",presentation:__name(()=>this.presentation,"presentation"),sites:__name(()=>this.sites,"sites"),draw:__name((tree,owner)=>{const band=tree.type==="engine"?void 0:{tree,owner,revision:++this.revision};if(!band&&!this.band)return;this.band=band;for(const listener of this.bandListeners)listener()},"draw"),log:__name((entry,plugin,sessionId)=>this.emit(`[Mod ${sanitizeTerminalLine(plugin)}] ${entry.text}`,sessionId),"log")});this.unregisterCleanup=registerCleanup(()=>{this.unregisterCleanup=()=>{};return this.close()})}static{__name(this,"InteractiveModSession")}session;lifetime=new AbortController;resolveStartup;rejectStartup;startup=new Promise((resolve,reject)=>{this.resolveStartup=resolve;this.rejectStartup=reject});initialization;closing;listener;logs=[];presentation={isFullscreen:false,columns:80};sites=[];band;revision=0;bandListeners=new Set;unregisterCleanup;initialize(sites=[]){if(!this.initialization)this.sites=sites;this.initialization??=this.session.initialize(this.lifetime.signal).then(()=>{this.session.flushLogs();this.resolveStartup()},error=>{this.emit(`Mods failed to initialize: ${sanitizeTerminalLine(String(error)).slice(0,2e3)}`,this.config.getSessionId());this.rejectStartup(error);throw error});return this.initialization}get ready(){return this.startup}failStartup(error){if(this.initialization)return;this.initialization=this.startup;this.rejectStartup(error)}async loadCommands(signal){await this.startup;signal.throwIfAborted();return this.session.loadCommands(this.lifetime.signal)}setPresentation(presentation){this.presentation={...presentation}}setRenderInput(input){if(!this.closing)this.session.setRenderInput(input)}subscribeBand=__name(listener=>{this.bandListeners.add(listener);return()=>this.bandListeners.delete(listener)},"subscribeBand");getBand=__name(()=>this.band,"getBand");subscribe(listener){this.listener=listener;for(const entry of this.logs.splice(0))this.emit(entry.text,entry.sessionId);return()=>{if(this.listener===listener)this.listener=void 0}}emit(text,sessionId){if(this.closing||sessionId!==this.config.getSessionId())return;if(this.listener)this.listener(text);else{if(this.logs.length===100)this.logs.shift();this.logs.push({text,sessionId})}}captureToolSignal(){return AbortSignal.any([this.lifetime.signal,this.session.captureToolSignal()])}restoreTools(){return this.session.restoreTools()}invalidateTools(){this.session.invalidateTools()}toolCall(){return this.session.toolCall(()=>{})}syncSession(reason){return this.session.syncSession(reason)}startTurn(text,signal,abort,promptId){return this.closing?void 0:this.session.startTurn(text,signal,abort,promptId)}close(){this.closing??=(async()=>{this.unregisterCleanup();this.lifetime.abort();this.rejectStartup(new Error("Interactive Mod session is closed."));try{await this.session.close()}finally{this.listener=void 0;this.logs.length=0;this.band=void 0;for(const listener of this.bandListeners)listener();if(sessions.get(this.config)===this)sessions.delete(this.config)}})();return this.closing}};export{ModSession,isModRecoveryCommand,createInteractiveModSession,getInteractiveModSession,InteractiveModSession};
|
|
6
6
|
/**
|