@qwen-code/qwen-code 0.21.1-simplify-system-prompt.0 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/qc-helper/docs/configuration/model-providers.md +2 -0
- package/bundled/qc-helper/docs/configuration/settings.md +38 -28
- package/bundled/qc-helper/docs/features/channels/_meta.ts +1 -0
- package/bundled/qc-helper/docs/features/channels/github.md +107 -0
- package/bundled/qc-helper/docs/features/channels/overview.md +61 -6
- package/bundled/qc-helper/docs/features/code-review.md +1 -1
- package/bundled/qc-helper/docs/features/hooks.md +52 -15
- package/bundled/qc-helper/docs/features/mcp.md +9 -1
- package/bundled/qc-helper/docs/features/scheduled-tasks.md +3 -1
- package/bundled/qc-helper/docs/features/sub-agents.md +20 -0
- package/bundled/qc-helper/docs/qwen-serve.md +4 -2
- package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +2 -2
- package/bundled/qc-helper/docs/support/troubleshooting.md +2 -1
- package/bundled/review/DESIGN.md +19 -0
- package/bundled/review/SKILL.md +120 -61
- package/chunks/MaxSizedBox-VI3ROJJA.js +84 -0
- package/chunks/{StandaloneSessionPicker-O6RKBPU4.js → StandaloneSessionPicker-LYXKD2EV.js} +66 -68
- package/chunks/{acp-startup-profiler-RV3IV562.js → acp-startup-profiler-DFVPFQ6C.js} +2 -2
- package/chunks/{acpAgent-HYFVXVDR.js → acpAgent-WN5SRDQO.js} +1317 -542
- package/chunks/agent-K6ECSM64.js +80 -0
- package/chunks/agent-headless-NO4Y2HOE.js +74 -0
- package/chunks/{anthropicContentGenerator-LXUXMOE7.js → anthropicContentGenerator-V2QOGVYD.js} +61 -20
- package/chunks/{artifact-tool-Y5T7GG7F.js → artifact-tool-6K6U7XYJ.js} +4 -4
- package/chunks/{askUserQuestion-2H6747FR.js → askUserQuestion-GD2IJJ7I.js} +4 -4
- package/chunks/bridge-3KJEWDNE.js +90 -0
- package/chunks/{build-RV63TIRH.js → build-S6DO7LMM.js} +1 -1
- package/chunks/{ca-25EDXPFZ.js → ca-6W3SK7OQ.js} +6 -1
- package/chunks/{channel-management-service-G74LFADV.js → channel-management-service-XR7GZSWF.js} +4 -4
- package/chunks/channel-settings-store-HW4FXXUA.js +87 -0
- package/chunks/{channel-worker-group-PTJIJSKC.js → channel-worker-group-XDPTDWTX.js} +9 -5
- package/chunks/{channel-worker-manager-WIMGM2FD.js → channel-worker-manager-YYEHVRRE.js} +9 -5
- package/chunks/{channel-worker-supervisor-KUFTR6P5.js → channel-worker-supervisor-74HTWA2G.js} +5 -4
- package/chunks/{chunk-M5JM7OSF.js → chunk-2DN4J57Y.js} +2 -3
- package/chunks/{chunk-WDSWXQU3.js → chunk-2FAK6PNM.js} +2 -2
- package/chunks/{chunk-BPJSQIJX.js → chunk-2J3OJGTL.js} +0 -2
- package/chunks/{chunk-EPDRMGT4.js → chunk-2LKVPASC.js} +4 -28
- package/chunks/{chunk-PWTZEM3C.js → chunk-2LQTH543.js} +3 -37
- package/chunks/{chunk-PANH4R3B.js → chunk-2N7CODY5.js} +18 -12
- package/chunks/{chunk-ER5LWJR6.js → chunk-2XSLTRFZ.js} +3 -3
- package/chunks/{chunk-6PSLCFQ2.js → chunk-3EFXSQCM.js} +18 -9
- package/chunks/{chunk-HIJQF5B5.js → chunk-3L2SPEBH.js} +1 -1
- package/chunks/{chunk-BIQWWWJN.js → chunk-4G2BISNC.js} +1 -1
- package/chunks/{chunk-B4UMZKMU.js → chunk-52ZSWYEG.js} +1 -1
- package/chunks/{chunk-YAF5VNU7.js → chunk-5KTQXHPY.js} +4 -5
- package/chunks/{chunk-2YZJCM5T.js → chunk-5MKRTI4T.js} +4 -4
- package/chunks/{chunk-DHHOYAPR.js → chunk-5TBMQLGG.js} +7 -7
- package/chunks/{chunk-A4UCTEB5.js → chunk-5WV5S2GT.js} +0 -1
- package/chunks/{chunk-FY3M44RD.js → chunk-5YKDXHUY.js} +3 -3
- package/chunks/{chunk-TF2X2WCT.js → chunk-5ZF5XXTS.js} +2 -2
- package/chunks/{chunk-K4XWPEWB.js → chunk-64LQLPL7.js} +4 -33
- package/chunks/{chunk-B7QDM6Z7.js → chunk-657BH7VM.js} +2 -2
- package/chunks/{chunk-5THCYPLO.js → chunk-65PQENQP.js} +14 -7
- package/chunks/{chunk-J6D3VXCC.js → chunk-6PE7N3A4.js} +17 -6
- package/chunks/{chunk-JZA3JUDJ.js → chunk-6QIGFD5W.js} +1 -1
- package/chunks/{chunk-Z5BLYMZM.js → chunk-6RPMI2AB.js} +6 -6
- package/chunks/{chunk-OHNBB4XR.js → chunk-75GFAX4R.js} +1 -1
- package/chunks/{chunk-BO4XCS7P.js → chunk-75MIQ3LV.js} +20 -85
- package/chunks/{chunk-52O2CIUL.js → chunk-7AEJDLRA.js} +130 -5
- package/chunks/{chunk-BYFNTGKI.js → chunk-7BAU433D.js} +2287 -941
- package/chunks/{chunk-ZE5WPL4I.js → chunk-7DXQIJID.js} +3 -3
- package/chunks/{chunk-ML52PL6O.js → chunk-7I5GTCT4.js} +483 -248
- package/chunks/{chunk-A5L3JMUA.js → chunk-7XATOOE7.js} +18 -4
- package/chunks/{chunk-C3NS4F2Q.js → chunk-A2D5BAVP.js} +1 -1
- package/chunks/{chunk-5I2IWRSH.js → chunk-A3NDJ5SB.js} +2 -2
- package/chunks/{chunk-2JM6GZ5D.js → chunk-A4COXFB3.js} +8 -13
- package/chunks/{chunk-CC4N4M36.js → chunk-AQIDMUGU.js} +1 -1
- package/chunks/{chunk-PJIZUQVC.js → chunk-AZQ3DT76.js} +2 -2
- package/chunks/{chunk-UH3WSE5L.js → chunk-B4AJNNOL.js} +1 -6
- package/chunks/{chunk-BJX6ZSUK.js → chunk-BCZFQXWK.js} +2 -2
- package/chunks/{chunk-SRZ6DXVG.js → chunk-BGTQCTQW.js} +44 -136
- package/chunks/{chunk-PSWQZHEA.js → chunk-BMFALVGQ.js} +1 -1
- package/chunks/{chunk-XHRTVPG2.js → chunk-BNWB5CYE.js} +7 -7
- package/chunks/{chunk-P5V4T7NK.js → chunk-BPZKP57P.js} +11 -3
- package/chunks/{chunk-2OM7GEXO.js → chunk-CAPPWD3X.js} +3 -3
- package/chunks/{chunk-LNURQEMZ.js → chunk-CQL64ESB.js} +7 -7
- package/chunks/{chunk-TOFQCPDC.js → chunk-CVHIL5IG.js} +4 -5
- package/chunks/{chunk-XVNQMZ2I.js → chunk-DGEIYUC3.js} +0 -1
- package/chunks/{chunk-BPZALHVR.js → chunk-DI35ZN7T.js} +1 -1
- package/chunks/{chunk-SQBYH7PX.js → chunk-DZLYR4U3.js} +1 -1
- package/chunks/{chunk-JALU3ZDU.js → chunk-EIF3FXTB.js} +117 -24
- package/chunks/{chunk-TQCBGUHN.js → chunk-EJGJIBRS.js} +5 -5
- package/chunks/{chunk-5U4IPFBR.js → chunk-EVKE2FZL.js} +4 -4
- package/chunks/{chunk-OKY7HXPG.js → chunk-FNMZK765.js} +2 -2
- package/chunks/{chunk-KU5XMLDK.js → chunk-FTD6DP4T.js} +3 -1
- package/chunks/chunk-FYJ7W2PI.js +194 -0
- package/chunks/{chunk-L5UHQJTJ.js → chunk-GATT5TKW.js} +1 -1
- package/chunks/{chunk-MVS3NS2N.js → chunk-GEBV2JGB.js} +28 -5
- package/chunks/{chunk-VAK25FTU.js → chunk-GKX7E4CO.js} +1 -1
- package/chunks/{chunk-LS77BEZP.js → chunk-GLCZKT5V.js} +1 -5
- package/chunks/{chunk-N3FAY5CM.js → chunk-GNR2RNMP.js} +157 -4
- package/chunks/{chunk-YH6G52F2.js → chunk-GXIJHV66.js} +4 -4
- package/chunks/{chunk-HV3G62R6.js → chunk-GZ3RCT54.js} +1 -1
- package/chunks/{chunk-QY5MMZ6O.js → chunk-HMRM2A3U.js} +3 -3
- package/chunks/chunk-HV26XH34.js +319 -0
- package/chunks/{chunk-M4UKFCZ2.js → chunk-J7OACQDE.js} +193 -155
- package/chunks/{chunk-3HBZKBMQ.js → chunk-JFMA7Y5M.js} +5 -5
- package/chunks/{chunk-OJGCZBB7.js → chunk-JHNRZMHI.js} +41 -36
- package/chunks/{chunk-63P4EL5V.js → chunk-JMONIXMJ.js} +1 -1
- package/chunks/{chunk-L26JL52R.js → chunk-JSD33JG6.js} +47 -64
- package/chunks/{chunk-KIUFNBHR.js → chunk-JTV5K7NH.js} +1 -1
- package/chunks/{chunk-PHVR5UUY.js → chunk-JX27F6QS.js} +1 -1
- package/chunks/chunk-JYBU6YUE.js +378 -0
- package/chunks/{chunk-A6UO2C7C.js → chunk-KAMYKP7E.js} +167 -81
- package/chunks/{chunk-LG4GZIVV.js → chunk-KCO4FLFJ.js} +4 -4
- package/chunks/{chunk-2W3OOD4W.js → chunk-L55JWS76.js} +6 -3
- package/chunks/{chunk-RHLZR4E5.js → chunk-LGAOC3ZS.js} +1 -1
- package/chunks/{chunk-DM22XS4K.js → chunk-LO4ROVP4.js} +261 -15
- package/chunks/{chunk-NH6KE4JX.js → chunk-LW3RFMG7.js} +3 -3
- package/chunks/{chunk-J56UI34H.js → chunk-M7OONWYU.js} +2 -2
- package/chunks/{chunk-V6VRAM7B.js → chunk-MHAIJPTD.js} +12 -12
- package/chunks/{chunk-FODK6UMO.js → chunk-MPHPFVKK.js} +0 -2
- package/chunks/{chunk-LZEMEFKY.js → chunk-MR5EAQ5M.js} +1 -1
- package/chunks/{chunk-JESCGQM3.js → chunk-NAVJD2PQ.js} +8 -7
- package/chunks/{chunk-H5FFA6TH.js → chunk-NOKIVHOL.js} +16 -3
- package/chunks/{chunk-6OUGMXDC.js → chunk-NWNEANAT.js} +7 -7
- package/chunks/{chunk-B6ZJ7SI6.js → chunk-OCESJA77.js} +391 -328
- package/chunks/chunk-OCPBI7J5.js +18 -0
- package/chunks/{chunk-E5TUC6CA.js → chunk-OKF7JF3R.js} +3 -3
- package/chunks/{chunk-2Q3OT4OV.js → chunk-P4WOAOJW.js} +141 -64
- package/chunks/{chunk-4M377AZG.js → chunk-PB3MBFKG.js} +6 -6
- package/chunks/{chunk-QPDRAXDJ.js → chunk-PLDQBIO6.js} +1 -1
- package/chunks/{chunk-FNQ6T3CV.js → chunk-PONHVBRT.js} +10 -7
- package/chunks/{chunk-RWS5VYWC.js → chunk-PT722TDT.js} +267 -378
- package/chunks/chunk-Q43KPN7X.js +2196 -0
- package/chunks/{chunk-VDDGDZMA.js → chunk-QHWCP53L.js} +14 -7
- package/chunks/{chunk-SASBXAQL.js → chunk-QIZKCVM3.js} +4 -4
- package/chunks/{chunk-32MVHM4T.js → chunk-RCUQIPTN.js} +1 -1
- package/chunks/{chunk-6FGBXPWM.js → chunk-RPLGZJV2.js} +38 -44
- package/chunks/{chunk-3IXOIAKE.js → chunk-S4WJVPZW.js} +18 -6
- package/chunks/{chunk-6AM5D4ME.js → chunk-S6LOFUVP.js} +0 -12
- package/chunks/{chunk-INADJJGW.js → chunk-S7W2GKIO.js} +0 -2
- package/chunks/{chunk-MUP3T3AD.js → chunk-SGFT55XI.js} +1 -35
- package/chunks/{chunk-VYPFXUCB.js → chunk-SZ3KHTDR.js} +1 -1
- package/chunks/chunk-T26EAKDL.js +13 -0
- package/chunks/{chunk-3MSHSCSN.js → chunk-T2QMKU3R.js} +79 -1
- package/chunks/{chunk-VFSJ5VRH.js → chunk-T3O2B4XO.js} +3 -3
- package/chunks/{chunk-MSLKI6C2.js → chunk-T4TXDL7G.js} +32 -21
- package/chunks/{chunk-E5WH5O3C.js → chunk-TBBV36Y4.js} +4 -4
- package/chunks/{chunk-VV6XU5L7.js → chunk-TCIFAA7K.js} +16 -11
- package/chunks/{chunk-DN6ZX5AY.js → chunk-TDL6LB4K.js} +46 -11
- package/chunks/{chunk-W4CQXHT6.js → chunk-TFRMVU6R.js} +1 -1
- package/chunks/{chunk-GDIPH4JY.js → chunk-TV64SXKD.js} +6 -6
- package/chunks/{chunk-FQK6JAFG.js → chunk-U3E3UQAA.js} +4 -4
- package/chunks/{chunk-7FZEBPKS.js → chunk-UBEPNVDI.js} +23 -18
- package/chunks/{chunk-NL7LTRLR.js → chunk-UHUSJ6X7.js} +29 -68
- package/chunks/{chunk-ZOIFNCKL.js → chunk-UPUG4GXM.js} +3 -23
- package/chunks/{chunk-6GMVPFB2.js → chunk-UWMLWVCA.js} +19 -6
- package/chunks/{chunk-U7TXFVUN.js → chunk-VCPIZRYH.js} +118 -95
- package/chunks/{chunk-LNARWLZQ.js → chunk-VWOOBLTY.js} +2 -2
- package/chunks/{chunk-I7XZ3RY5.js → chunk-VYOXCEPJ.js} +1 -1
- package/chunks/{chunk-USTWD7QV.js → chunk-W4MIWP6M.js} +26 -16
- package/chunks/{chunk-DLWL3Z7A.js → chunk-WBSMNTSV.js} +3 -3
- package/chunks/{chunk-G4WFQUYQ.js → chunk-WUZ7H6DP.js} +1 -1
- package/chunks/{chunk-2JZBVYTU.js → chunk-WZRWHXFE.js} +1 -8
- package/chunks/{chunk-DM4Q4JJH.js → chunk-X5WNMMIA.js} +22506 -33611
- package/chunks/{chunk-MK7VQDN3.js → chunk-XBYYDKAZ.js} +7 -6
- package/chunks/{chunk-COH43MRJ.js → chunk-XCGIMOLN.js} +27 -1
- package/chunks/{chunk-BRRAJXPA.js → chunk-XFZYFU3I.js} +1 -1
- package/chunks/{chunk-3QMGYBFN.js → chunk-XWWKIXVD.js} +1 -80
- package/chunks/{chunk-3SJ43L4W.js → chunk-XZC5VLBZ.js} +2 -0
- package/chunks/{chunk-UUUTRMI2.js → chunk-Y4IHBGBP.js} +1 -1
- package/chunks/{chunk-PR75REBZ.js → chunk-Y6AXW2OG.js} +12 -82
- package/chunks/{chunk-IPUUTYMV.js → chunk-YDLJGZHL.js} +1 -1
- package/chunks/{chunk-3JAQDSXN.js → chunk-YGF33UXG.js} +70 -8
- package/chunks/chunk-Z4X5MTRT.js +133 -0
- package/chunks/{chunk-UW5EOVUN.js → chunk-ZBVS26BY.js} +4 -4
- package/chunks/{chunk-ZD6UTE4A.js → chunk-ZHBO7WVX.js} +1 -1
- package/chunks/{chunk-HTO4JFDZ.js → chunk-ZPJWUGCS.js} +0 -1
- package/chunks/{chunk-66RMLJHC.js → chunk-ZURDMIDR.js} +355 -143
- package/chunks/{computer-use-DOFAHZAB.js → computer-use-ZTIDHMMA.js} +48 -50
- package/chunks/{config-utils-VFQXVGNR.js → config-utils-NYSXDMEQ.js} +4 -4
- package/chunks/contextCommand-2PIEU37Z.js +79 -0
- package/chunks/core-runtime-3XEYLQFK.js +133 -0
- package/chunks/{create-sub-session-7543K2QA.js → create-sub-session-R76FVXCI.js} +45 -47
- package/chunks/{create-sub-session-IWW2IZ2T.js → create-sub-session-SBYUMSSS.js} +3 -3
- package/chunks/{cron-create-YIID5XAW.js → cron-create-2QK6TCEC.js} +6 -6
- package/chunks/{cron-delete-ZVHYCEP2.js → cron-delete-FDCDFYMG.js} +5 -5
- package/chunks/{cron-list-XEGS463Q.js → cron-list-XN3WVBTP.js} +6 -6
- package/chunks/{daemon-VOMQW7KZ.js → daemon-Q2AB5Z23.js} +167 -15
- package/chunks/daemon-status-provider-3XJI6CAL.js +89 -0
- package/chunks/daemon-trust-policy-ILUDTLHD.js +84 -0
- package/chunks/daemon-trust-policy-monitor-HS3PKKRO.js +171 -0
- package/chunks/{de-HGRCYDEJ.js → de-SY6O76BF.js} +6 -1
- package/chunks/deferred-core-runtime-X4QV662U.js +88 -0
- package/chunks/dist-BSTVRPMT.js +4227 -0
- package/chunks/{dist-NNVBBOGU.js → dist-DOLYHMXE.js} +2 -2
- package/chunks/{dist-RTJFMNEZ.js → dist-HVRQ2CFL.js} +271 -11
- package/chunks/{dist-ANLAT3GS.js → dist-IXQEQWRG.js} +2 -1
- package/chunks/{dist-BRB6EXK4.js → dist-SSU66DM4.js} +3 -3
- package/chunks/{dist-KTYYJ2C5.js → dist-SV7Q3AWJ.js} +1 -1
- package/chunks/{dist-K6Y4E7FX.js → dist-YGBBMK3Z.js} +1 -1
- package/chunks/earlyInputCapture-XKLZT7ZD.js +81 -0
- package/chunks/{edit-RIEOJWKB.js → edit-HHGIOTQ2.js} +47 -49
- package/chunks/{en-MTWBNGDO.js → en-NBK3JKCE.js} +9 -1
- package/chunks/{enter-worktree-OGK5FQ3R.js → enter-worktree-ZN7PUQ46.js} +47 -49
- package/chunks/{enterPlanMode-IWZYALIB.js → enterPlanMode-EIFIDSIV.js} +47 -49
- package/chunks/{environment-VZ7BRI4Q.js → environment-XXQ75D2Q.js} +47 -49
- package/chunks/errors-4GMVU7CK.js +87 -0
- package/chunks/esm-K5FARBNI.js +5548 -0
- package/chunks/{exit-worktree-4TEYVIVP.js → exit-worktree-GXMI4ATY.js} +47 -49
- package/chunks/exitPlanMode-34UVY7M6.js +72 -0
- package/chunks/{fast-path-HYE7IFEV.js → fast-path-VPIVA7L6.js} +13 -3
- package/chunks/{fr-45RLL55O.js → fr-4KG5V7UT.js} +6 -1
- package/chunks/{gemini-NGRQX3YJ.js → gemini-4BWIK4WD.js} +103 -103
- package/chunks/{geminiContentGenerator-FQHPFZSR.js → geminiContentGenerator-3XVV5MSS.js} +7 -7
- package/chunks/{getMachineId-bsd-V7W3GODC.js → getMachineId-bsd-FG7IUY6U.js} +1 -1
- package/chunks/{getMachineId-darwin-TDO75DQP.js → getMachineId-darwin-GLCJI2RA.js} +1 -1
- package/chunks/{getMachineId-linux-TF43WQT2.js → getMachineId-linux-O6OPPAKO.js} +1 -1
- package/chunks/{getMachineId-unsupported-ZGUO3TXT.js → getMachineId-unsupported-S6CKYVGC.js} +1 -1
- package/chunks/{getMachineId-win-ECFYZZFQ.js → getMachineId-win-X5SRNEH7.js} +1 -1
- package/chunks/{glob-FRTM3X2E.js → glob-TZ2ABCJG.js} +47 -49
- package/chunks/{grep-RKWVROCW.js → grep-BEF463NA.js} +49 -50
- package/chunks/handleAutoUpdate-L6ERF36Y.js +80 -0
- package/chunks/i18n-FMM5FDXR.js +96 -0
- package/chunks/{image-gen-WIEM7KZA.js → image-gen-HHVLF7HS.js} +12 -12
- package/chunks/initializer-625TIAIO.js +85 -0
- package/chunks/installationInfo-6AM4I2Y3.js +79 -0
- package/chunks/{ja-B7DF7DFG.js → ja-F3GSQXMF.js} +6 -1
- package/chunks/{keychain-token-storage-MDTG3WRM.js → keychain-token-storage-72IYCAZV.js} +3 -3
- package/chunks/lib-RUF3WZA6.js +9 -0
- package/chunks/list-L2GA674Y.js +88 -0
- package/chunks/{list-agents-5KJJHR6I.js → list-agents-R6KDXQR3.js} +3 -3
- package/chunks/loadedSettingsAdapter-SPUTNKAV.js +82 -0
- package/chunks/{loggingContentGenerator-WGM27QAW.js → loggingContentGenerator-LKOF7XI7.js} +31 -30
- package/chunks/{loop-wakeup-FXKNNYSY.js → loop-wakeup-3IQKCYAH.js} +7 -7
- package/chunks/{ls-NTK6VOQJ.js → ls-DKZ37A7N.js} +5 -5
- package/chunks/{lsp-2JI24STP.js → lsp-QNWN7KN3.js} +3 -3
- package/chunks/{managed-npm-update-JQ2CG3RH.js → managed-npm-update-ACQGGIN5.js} +46 -48
- package/chunks/mcp-SZLHKFJW.js +82 -0
- package/chunks/{monitor-7FEWXX5F.js → monitor-DF52UVHI.js} +47 -49
- package/chunks/nonInteractiveCli-5T7KYKLK.js +144 -0
- package/chunks/{notebook-edit-JGJV2K6J.js → notebook-edit-FCWS4XVN.js} +47 -49
- package/chunks/{openaiContentGenerator-JPVXDTAO.js → openaiContentGenerator-7LDK3DCJ.js} +25 -27
- package/chunks/pidfile-6ERW3DF4.js +85 -0
- package/chunks/process-registry-2CHQBXH5.js +157 -0
- package/chunks/{processUtils-V2LCK6T6.js → processUtils-COKZAMUP.js} +2 -2
- package/chunks/{pt-22Q3FP73.js → pt-EQ33KWEN.js} +6 -1
- package/chunks/{qwenContentGenerator-TICV2W2Z.js → qwenContentGenerator-TKWUMR7N.js} +51 -53
- package/chunks/{qwenOAuth2-XGFI5XJG.js → qwenOAuth2-7HMU47SF.js} +10 -10
- package/chunks/read-file-X6DRC574.js +29 -0
- package/chunks/{read-mcp-resource-4DKQWGHD.js → read-mcp-resource-GFTWYXMK.js} +4 -4
- package/chunks/{record-artifact-RQKFYO5B.js → record-artifact-XAMSFSW4.js} +3 -3
- package/chunks/resumeHistoryUtils-PFPM2GWM.js +90 -0
- package/chunks/ripGrep-OWV2IVJC.js +72 -0
- package/chunks/{ru-FZCNZHDC.js → ru-7OZAUKGG.js} +6 -1
- package/chunks/{run-qwen-serve-3VCV4I7E.js → run-qwen-serve-TSTCO4XE.js} +917 -249
- package/chunks/{runtime-AXJWIEDU.js → runtime-DAUPSUKI.js} +55 -57
- package/chunks/{scheduler-RS2I6RU5.js → scheduler-KMADMT26.js} +45 -47
- package/chunks/{sdk-exporters-grpc-AK3LGHNO.js → sdk-exporters-grpc-54L4LS5L.js} +4 -4
- package/chunks/{sdk-exporters-http-FS6ZV7MF.js → sdk-exporters-http-WO556XNU.js} +7 -7
- package/chunks/{sdk-impl-7FZSCSXB.js → sdk-impl-LPAVACSF.js} +10 -10
- package/chunks/{send-message-Q6OOR6BR.js → send-message-SAWK4DZX.js} +6 -6
- package/chunks/serve-NNRWS6F4.js +88 -0
- package/chunks/{server-HRZ23U7M.js → server-WEH7DVCH.js} +3304 -842
- package/chunks/{session-7XHZKTVV.js → session-WXC56V2I.js} +94 -94
- package/chunks/{settings-7ZGZDXAS.js → settings-DJDXFDZ3.js} +54 -56
- package/chunks/shell-JN5VRQXD.js +82 -0
- package/chunks/{skill-LIWXNLDW.js → skill-SGXPKJCS.js} +20 -22
- package/chunks/skill-settings-VJ5PDMZI.js +90 -0
- package/chunks/spawnChannel-ETMJW7YX.js +81 -0
- package/chunks/standalone-update-MK3Z7KBI.js +91 -0
- package/chunks/{startInteractiveUI-IW3CSKHA.js → startInteractiveUI-ZCGIXPGT.js} +715 -373
- package/chunks/{syntheticOutput-I3757IWH.js → syntheticOutput-355CB6CJ.js} +4 -4
- package/chunks/{task-create-N7WQSGYA.js → task-create-INGWNUG4.js} +10 -10
- package/chunks/{task-list-FOPULZEP.js → task-list-5XNNGTF4.js} +7 -7
- package/chunks/{task-stop-H6RHXFVQ.js → task-stop-4ROAOBXH.js} +3 -3
- package/chunks/{task-update-M57TFZJT.js → task-update-CRK5VWWZ.js} +10 -10
- package/chunks/{team-create-O2FROQ4R.js → team-create-QQGAJG7P.js} +49 -51
- package/chunks/{team-delete-QE2UXJL7.js → team-delete-S2RCXA4P.js} +7 -7
- package/chunks/{team-plan-approval-Q6WDBXTQ.js → team-plan-approval-RT7Q5R6O.js} +47 -49
- package/chunks/theme-manager-EEWIQJ7J.js +76 -0
- package/chunks/{todoWrite-VQ7FKOHL.js → todoWrite-7WM3VDMY.js} +7 -7
- package/chunks/{tool-search-APECNQ3Z.js → tool-search-Z3Z4AYKP.js} +19 -21
- package/chunks/total-session-admission-44JKRWQD.js +84 -0
- package/chunks/{tree-sitter-FS4VPMZA.js → tree-sitter-4D7QS7F6.js} +1 -1
- package/chunks/{tree-sitter-bash-6B46JJCV.js → tree-sitter-bash-VEJGF5XF.js} +1 -1
- package/chunks/trustedFolders-X2JEIO57.js +94 -0
- package/chunks/{update-relaunch-ON5MDJQG.js → update-relaunch-VWNPYDIP.js} +5 -5
- package/chunks/updateCheck-KAQH67DV.js +91 -0
- package/chunks/useAutoAcceptIndicator-JH6BCF7S.js +92 -0
- package/chunks/{validateNonInterActiveAuth-JBLKBKRD.js → validateNonInterActiveAuth-GIUJ2UFS.js} +88 -88
- package/chunks/{version-LTNUBQJY.js → version-BGLYIJUY.js} +1 -1
- package/chunks/{web-fetch-L5UTI53V.js → web-fetch-OTDU4VQF.js} +19 -21
- package/chunks/{web-search-KM33JOS3.js → web-search-FP6SIHPR.js} +13 -13
- package/chunks/{workflow-K7FAWV77.js → workflow-YCIVBYSB.js} +48 -50
- package/chunks/workspace-providers-status-S35YAIUS.js +85 -0
- package/chunks/{workspace-registration-store-6TGVDJV5.js → workspace-registration-store-OTMS3H4C.js} +1 -1
- package/chunks/workspace-registry-O63R6IZ4.js +92 -0
- package/chunks/workspace-service-M6LLHKJ5.js +99 -0
- package/chunks/workspace-skills-status-C2V7BAIS.js +85 -0
- package/chunks/workspace-trust-reconciler-IBUPOUJN.js +345 -0
- package/chunks/write-file-3BZC3EAE.js +72 -0
- package/chunks/xterm-headless-NTYVIBT3.js +3475 -0
- package/chunks/{zh-LUIGBD55.js → zh-H3YDK5QW.js} +9 -1
- package/chunks/{zh-TW-F5KG2IYD.js → zh-TW-JYCP7XUA.js} +9 -1
- package/chunks/zoom-image-TZ6S2O57.js +351 -0
- package/cli.js +13 -13
- package/locales/ca.js +7 -2
- package/locales/de.js +7 -2
- package/locales/en.js +10 -2
- package/locales/fr.js +7 -2
- package/locales/ja.js +7 -2
- package/locales/pt.js +7 -2
- package/locales/ru.js +7 -2
- package/locales/zh-TW.js +10 -2
- package/locales/zh.js +10 -2
- package/package.json +5 -4
- package/web-shell/assets/{arc-BbHijhiN.js → arc-75-Wdeo3.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-Cb4B_JD0.js → architectureDiagram-3BPJPVTR-FKeXQbyP.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-Dsjlh3H-.js → blockDiagram-GPEHLZMM-CY0vc-A3.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-Cp5AeR4U.js → c4Diagram-AAUBKEIU-CNP-A-8u.js} +1 -1
- package/web-shell/assets/channel-DPYMT76A.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-CLcY7W2e.js → chunk-2J33WTMH-GybS4Gii.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-BUhvY2LR.js → chunk-4BX2VUAB-02H91V8v.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-kDIFC_71.js → chunk-55IACEB6-D3M-2VT6.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-CIBO15f2.js → chunk-727SXJPM-CCu29u4H.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-BJ_T_slV.js → chunk-AQP2D5EJ-CaFKWgrn.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-BEkW35J8.js → chunk-FMBD7UC4-ZZpPqIwQ.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-GGPxofay.js → chunk-ND2GUHAM-D22DqGs8.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-Bifllrb6.js → chunk-QZHKN3VN-Bu85S0fw.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK--JstsIgL.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2--JstsIgL.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-C-Add_Dp.js → cose-bilkent-S5V4N54A-f1CK1Gwe.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-B7MfwNq2.js → dagre-BM42HDAG-D0Ow8F_n.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-CY_0zuDz.js → diagram-2AECGRRQ-BPrmTWp8.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-VyYSbCgA.js → diagram-5GNKFQAL-HccuFAzy.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-CBiIZ2PL.js → diagram-KO2AKTUF-BrS76mbA.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-BL3CrVOx.js → diagram-LMA3HP47-V7T9lU-5.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-CZUPx96P.js → diagram-OG6HWLK6-DKidyJMR.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-B81xHr1-.js → erDiagram-TEJ5UH35-DBadZIkp.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-EZWhir-J.js → flowDiagram-I6XJVG4X-BymfqdNJ.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-CVFSuIAg.js → ganttDiagram-6RSMTGT7-DOw340jf.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-C1H2uQDv.js → gitGraphDiagram-PVQCEYII-_8EiD8sl.js} +1 -1
- package/web-shell/assets/{index-BYo99NBH.js → index-CKIadvET.js} +1 -1
- package/web-shell/assets/index-D1eXNRHe.js +1389 -0
- package/web-shell/assets/index-DVLD4CQq.css +5 -0
- package/web-shell/assets/{infoDiagram-5YYISTIA-BwyFMlF8.js → infoDiagram-5YYISTIA-D61KYQBu.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-CQ7Yhn2Y.js → ishikawaDiagram-YF4QCWOH-CsiXSpNx.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-CJn2sf0l.js → journeyDiagram-JHISSGLW-Sdfionyh.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-DaNRqwVN.js → kanban-definition-UN3LZRKU-C3WI3Cnl.js} +1 -1
- package/web-shell/assets/{linear-DCKODZe2.js → linear-Dpigcc62.js} +1 -1
- package/web-shell/assets/{mermaid.core-CTGJOk27.js → mermaid.core-Ct97pqgW.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-BKU3_3rg.js → mindmap-definition-RKZ34NQL-BzeaN0rB.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-COcwBJ82.js → pieDiagram-4H26LBE5-CvjgcbVD.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-CQnQ443x.js → quadrantDiagram-W4KKPZXB-BUzgTNdH.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-CZ2oj5cD.js → requirementDiagram-4Y6WPE33-B7zKlgUQ.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-BxAv5mNu.js → sankeyDiagram-5OEKKPKP-Bb9CQgrT.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-CztaySPs.js → sequenceDiagram-3UESZ5HK-DJ6V7itG.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-CTQT1oGD.js → stateDiagram-AJRCARHV-IImflERY.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CYI_YoNR.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-K9Mkex5A.js → timeline-definition-PNZ67QCA-6Q_uWHKh.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-B2rVIw76.js → vennDiagram-CIIHVFJN-TmyKyjwv.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-Z1w2JR4M.js → wardley-L42UT6IY-CRh9uiPv.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-CIX9aKXf.js → wardleyDiagram-YWT4CUSO-59TKAW8w.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-CI9DLIKB.js → xychartDiagram-2RQKCTM6-GCSUIK2L.js} +1 -1
- package/web-shell/index.html +2 -2
- package/chunks/MaxSizedBox-INHRH72H.js +0 -86
- package/chunks/agent-VXDAN5JK.js +0 -82
- package/chunks/agent-headless-K4ZMMNBD.js +0 -76
- package/chunks/bridge-LGPZCFHO.js +0 -91
- package/chunks/channel-settings-store-CHCDRTPY.js +0 -89
- package/chunks/chunk-SZRN75WQ.js +0 -29
- package/chunks/chunk-UGYMA4EI.js +0 -219
- package/chunks/chunk-VCBZUOSI.js +0 -8575
- package/chunks/contextCommand-QIZYHDR5.js +0 -81
- package/chunks/daemon-status-provider-OS5UWBHV.js +0 -90
- package/chunks/earlyInputCapture-WQT24RWD.js +0 -83
- package/chunks/errors-PCX25DVP.js +0 -89
- package/chunks/exitPlanMode-GHPUHBZJ.js +0 -423
- package/chunks/handleAutoUpdate-2CZQRJ66.js +0 -82
- package/chunks/i18n-XEQVMRKN.js +0 -98
- package/chunks/initializer-OVGZ4FLY.js +0 -87
- package/chunks/installationInfo-5UUQJI6Y.js +0 -81
- package/chunks/list-HODU6RXD.js +0 -90
- package/chunks/loadedSettingsAdapter-TYNLBALY.js +0 -84
- package/chunks/mcp-J3DFWX4A.js +0 -84
- package/chunks/nonInteractiveCli-F4GYSMHT.js +0 -144
- package/chunks/pidfile-4VNAR3EP.js +0 -87
- package/chunks/read-file-LZXUR4TO.js +0 -31
- package/chunks/resumeHistoryUtils-65OX3SGJ.js +0 -92
- package/chunks/ripGrep-2U2FRGMV.js +0 -74
- package/chunks/serve-W2GC47CM.js +0 -90
- package/chunks/shell-45IPBDP5.js +0 -84
- package/chunks/spawnChannel-PVXQ5AGV.js +0 -83
- package/chunks/src-AY65BYR7.js +0 -3166
- package/chunks/standalone-update-ZMFNKAEY.js +0 -93
- package/chunks/theme-manager-YYPZFBAH.js +0 -78
- package/chunks/total-session-admission-JXES723M.js +0 -85
- package/chunks/trustedFolders-HVI7IXUH.js +0 -94
- package/chunks/updateCheck-WUJGHWZZ.js +0 -93
- package/chunks/useAutoAcceptIndicator-CHSTZLZD.js +0 -94
- package/chunks/workspace-providers-status-GAKSF4LL.js +0 -87
- package/chunks/workspace-registry-A7NQUONG.js +0 -89
- package/chunks/workspace-service-STGVSO4N.js +0 -99
- package/chunks/workspace-skills-status-66AK3DUA.js +0 -86
- package/chunks/write-file-HUUCEG4P.js +0 -74
- package/web-shell/assets/channel-Bzdx6E8P.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-Cd6wbiuK.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-Cd6wbiuK.js +0 -1
- package/web-shell/assets/index-B2bXx96W.js +0 -1249
- package/web-shell/assets/index-_8mKjx8q.css +0 -5
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BjMdT6E_.js +0 -1
- package/chunks/{chunk-TARRHLLG.js → chunk-QUGAUQGJ.js} +25 -25
- package/chunks/{chunk-U7ZFW55U.js → chunk-VOQXFAY5.js} +977 -977
- /package/chunks/{chunk-LXXMOYPL.js → chunk-VXZBKKQR.js} +0 -0
|
@@ -12,6 +12,163 @@ import {
|
|
|
12
12
|
__name
|
|
13
13
|
} from "./chunk-J2S4EL5Y.js";
|
|
14
14
|
|
|
15
|
+
// packages/channels/base/dist/ChannelLoopTools.js
|
|
16
|
+
init_esbuild_shims();
|
|
17
|
+
var CHANNEL_LOOP_MCP_SERVER_NAME = "channel_loop";
|
|
18
|
+
var CLIENT_MCP_MESSAGE_METHOD = "qwen/control/client_mcp/message";
|
|
19
|
+
var WORKSPACE_MCP_RUNTIME_ADD_METHOD = "qwen/control/workspace/mcp/runtime-add";
|
|
20
|
+
var CLIENT_MCP_OVER_WS_CONFIG_FLAG = "__clientMcpOverWs";
|
|
21
|
+
var createTool = {
|
|
22
|
+
name: "channel_loop_create",
|
|
23
|
+
description: "Create a recurring proactive reminder or scheduled prompt for the current channel chat. Use this in channel sessions instead of cron_create.",
|
|
24
|
+
inputSchema: {
|
|
25
|
+
type: "object",
|
|
26
|
+
properties: {
|
|
27
|
+
cron: {
|
|
28
|
+
type: "string",
|
|
29
|
+
description: 'Standard 5-field cron expression in local time, for example "*/5 * * * *".'
|
|
30
|
+
},
|
|
31
|
+
prompt: {
|
|
32
|
+
type: "string",
|
|
33
|
+
description: "The message or instruction to run and proactively push to this channel chat."
|
|
34
|
+
},
|
|
35
|
+
recurring: {
|
|
36
|
+
type: "boolean",
|
|
37
|
+
description: "Whether the loop recurs. Defaults to true."
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
required: ["cron", "prompt"]
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var listTool = {
|
|
44
|
+
name: "channel_loop_list",
|
|
45
|
+
description: "List proactive loops for the current channel chat.",
|
|
46
|
+
inputSchema: { type: "object", properties: {} }
|
|
47
|
+
};
|
|
48
|
+
var cancelTool = {
|
|
49
|
+
name: "channel_loop_cancel",
|
|
50
|
+
description: "Cancel a proactive loop for the current channel chat.",
|
|
51
|
+
inputSchema: {
|
|
52
|
+
type: "object",
|
|
53
|
+
properties: {
|
|
54
|
+
id: { type: "string", description: "Loop id to cancel." }
|
|
55
|
+
},
|
|
56
|
+
required: ["id"]
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
var CHANNEL_LOOP_MCP_TOOLS = [createTool, listTool, cancelTool];
|
|
60
|
+
var ChannelLoopMcpServer = class {
|
|
61
|
+
static {
|
|
62
|
+
__name(this, "ChannelLoopMcpServer");
|
|
63
|
+
}
|
|
64
|
+
handler;
|
|
65
|
+
constructor(handler) {
|
|
66
|
+
this.handler = handler;
|
|
67
|
+
}
|
|
68
|
+
async handleMessage(message, context) {
|
|
69
|
+
const id = message["id"];
|
|
70
|
+
if (id === void 0 || id === null) {
|
|
71
|
+
return void 0;
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const result = await this.dispatch(message, context);
|
|
75
|
+
return { jsonrpc: "2.0", id, result };
|
|
76
|
+
} catch (error) {
|
|
77
|
+
return {
|
|
78
|
+
jsonrpc: "2.0",
|
|
79
|
+
id,
|
|
80
|
+
error: {
|
|
81
|
+
code: -32603,
|
|
82
|
+
message: error instanceof Error ? error.message : String(error)
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async dispatch(message, context) {
|
|
88
|
+
switch (message["method"]) {
|
|
89
|
+
case "initialize":
|
|
90
|
+
return {
|
|
91
|
+
protocolVersion: "2024-11-05",
|
|
92
|
+
capabilities: { tools: {} },
|
|
93
|
+
serverInfo: { name: CHANNEL_LOOP_MCP_SERVER_NAME, version: "0.0.1" }
|
|
94
|
+
};
|
|
95
|
+
case "tools/list":
|
|
96
|
+
return { tools: CHANNEL_LOOP_MCP_TOOLS };
|
|
97
|
+
case "tools/call":
|
|
98
|
+
return this.callTool(message["params"], context);
|
|
99
|
+
case "ping":
|
|
100
|
+
return {};
|
|
101
|
+
default:
|
|
102
|
+
throw new Error(`Method not found: ${String(message["method"])}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async callTool(rawParams, context) {
|
|
106
|
+
if (!context.sessionId) {
|
|
107
|
+
throw new Error("Missing channel session id.");
|
|
108
|
+
}
|
|
109
|
+
if (typeof rawParams !== "object" || rawParams === null) {
|
|
110
|
+
throw new Error("Invalid tools/call params.");
|
|
111
|
+
}
|
|
112
|
+
const params = rawParams;
|
|
113
|
+
const name = params["name"];
|
|
114
|
+
const args = typeof params["arguments"] === "object" && params["arguments"] !== null ? params["arguments"] : {};
|
|
115
|
+
let toolResult;
|
|
116
|
+
switch (name) {
|
|
117
|
+
case createTool.name:
|
|
118
|
+
toolResult = await this.handler.create(context.sessionId, readCreateInput(args));
|
|
119
|
+
break;
|
|
120
|
+
case listTool.name:
|
|
121
|
+
toolResult = await this.handler.list(context.sessionId);
|
|
122
|
+
break;
|
|
123
|
+
case cancelTool.name:
|
|
124
|
+
toolResult = await this.handler.cancel(context.sessionId, readId(args));
|
|
125
|
+
break;
|
|
126
|
+
default:
|
|
127
|
+
throw new Error(`Unknown channel loop tool: ${String(name)}`);
|
|
128
|
+
}
|
|
129
|
+
const result = typeof toolResult === "string" ? { text: toolResult } : toolResult;
|
|
130
|
+
return {
|
|
131
|
+
content: [{ type: "text", text: result.text }],
|
|
132
|
+
...result.isError ? { isError: true } : {}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
function readCreateInput(args) {
|
|
137
|
+
const cron = args["cron"];
|
|
138
|
+
const prompt = args["prompt"];
|
|
139
|
+
if (typeof cron !== "string" || cron.trim().length === 0) {
|
|
140
|
+
throw new Error("cron must be a non-empty string.");
|
|
141
|
+
}
|
|
142
|
+
if (typeof prompt !== "string" || prompt.trim().length === 0) {
|
|
143
|
+
throw new Error("prompt must be a non-empty string.");
|
|
144
|
+
}
|
|
145
|
+
const recurring = readRecurring(args["recurring"]);
|
|
146
|
+
return {
|
|
147
|
+
cron: cron.trim(),
|
|
148
|
+
prompt: prompt.trim(),
|
|
149
|
+
...recurring !== void 0 ? { recurring } : {}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
__name(readCreateInput, "readCreateInput");
|
|
153
|
+
function readRecurring(value) {
|
|
154
|
+
if (typeof value === "boolean")
|
|
155
|
+
return value;
|
|
156
|
+
if (value === "false" || value === 0)
|
|
157
|
+
return false;
|
|
158
|
+
if (value === "true" || value === 1)
|
|
159
|
+
return true;
|
|
160
|
+
return void 0;
|
|
161
|
+
}
|
|
162
|
+
__name(readRecurring, "readRecurring");
|
|
163
|
+
function readId(args) {
|
|
164
|
+
const id = args["id"];
|
|
165
|
+
if (typeof id !== "string" || id.trim().length === 0) {
|
|
166
|
+
throw new Error("id must be a non-empty string.");
|
|
167
|
+
}
|
|
168
|
+
return id.trim();
|
|
169
|
+
}
|
|
170
|
+
__name(readId, "readId");
|
|
171
|
+
|
|
15
172
|
// packages/channels/base/dist/sanitize.js
|
|
16
173
|
init_esbuild_shims();
|
|
17
174
|
var PROMPT_UNSAFE_INVISIBLES = new RegExp("[\\u0080-\\u009f\\p{Cf}\\u2028\\u2029]|\\p{Variation_Selector}", "gu");
|
|
@@ -294,166 +451,8 @@ import { spawn } from "node:child_process";
|
|
|
294
451
|
import { randomUUID } from "node:crypto";
|
|
295
452
|
import { Readable, Writable } from "node:stream";
|
|
296
453
|
import { EventEmitter } from "node:events";
|
|
297
|
-
|
|
298
|
-
// packages/channels/base/dist/ChannelLoopTools.js
|
|
299
|
-
init_esbuild_shims();
|
|
300
|
-
var CHANNEL_LOOP_MCP_SERVER_NAME = "channel_loop";
|
|
301
|
-
var CLIENT_MCP_MESSAGE_METHOD = "qwen/control/client_mcp/message";
|
|
302
|
-
var WORKSPACE_MCP_RUNTIME_ADD_METHOD = "qwen/control/workspace/mcp/runtime-add";
|
|
303
|
-
var CLIENT_MCP_OVER_WS_CONFIG_FLAG = "__clientMcpOverWs";
|
|
304
|
-
var createTool = {
|
|
305
|
-
name: "channel_loop_create",
|
|
306
|
-
description: "Create a recurring proactive reminder or scheduled prompt for the current channel chat. Use this in channel sessions instead of cron_create.",
|
|
307
|
-
inputSchema: {
|
|
308
|
-
type: "object",
|
|
309
|
-
properties: {
|
|
310
|
-
cron: {
|
|
311
|
-
type: "string",
|
|
312
|
-
description: 'Standard 5-field cron expression in local time, for example "*/5 * * * *".'
|
|
313
|
-
},
|
|
314
|
-
prompt: {
|
|
315
|
-
type: "string",
|
|
316
|
-
description: "The message or instruction to run and proactively push to this channel chat."
|
|
317
|
-
},
|
|
318
|
-
recurring: {
|
|
319
|
-
type: "boolean",
|
|
320
|
-
description: "Whether the loop recurs. Defaults to true."
|
|
321
|
-
}
|
|
322
|
-
},
|
|
323
|
-
required: ["cron", "prompt"]
|
|
324
|
-
}
|
|
325
|
-
};
|
|
326
|
-
var listTool = {
|
|
327
|
-
name: "channel_loop_list",
|
|
328
|
-
description: "List proactive loops for the current channel chat.",
|
|
329
|
-
inputSchema: { type: "object", properties: {} }
|
|
330
|
-
};
|
|
331
|
-
var cancelTool = {
|
|
332
|
-
name: "channel_loop_cancel",
|
|
333
|
-
description: "Cancel a proactive loop for the current channel chat.",
|
|
334
|
-
inputSchema: {
|
|
335
|
-
type: "object",
|
|
336
|
-
properties: {
|
|
337
|
-
id: { type: "string", description: "Loop id to cancel." }
|
|
338
|
-
},
|
|
339
|
-
required: ["id"]
|
|
340
|
-
}
|
|
341
|
-
};
|
|
342
|
-
var CHANNEL_LOOP_MCP_TOOLS = [createTool, listTool, cancelTool];
|
|
343
|
-
var ChannelLoopMcpServer = class {
|
|
344
|
-
static {
|
|
345
|
-
__name(this, "ChannelLoopMcpServer");
|
|
346
|
-
}
|
|
347
|
-
handler;
|
|
348
|
-
constructor(handler) {
|
|
349
|
-
this.handler = handler;
|
|
350
|
-
}
|
|
351
|
-
async handleMessage(message, context) {
|
|
352
|
-
const id = message["id"];
|
|
353
|
-
if (id === void 0 || id === null) {
|
|
354
|
-
return void 0;
|
|
355
|
-
}
|
|
356
|
-
try {
|
|
357
|
-
const result = await this.dispatch(message, context);
|
|
358
|
-
return { jsonrpc: "2.0", id, result };
|
|
359
|
-
} catch (error) {
|
|
360
|
-
return {
|
|
361
|
-
jsonrpc: "2.0",
|
|
362
|
-
id,
|
|
363
|
-
error: {
|
|
364
|
-
code: -32603,
|
|
365
|
-
message: error instanceof Error ? error.message : String(error)
|
|
366
|
-
}
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
async dispatch(message, context) {
|
|
371
|
-
switch (message["method"]) {
|
|
372
|
-
case "initialize":
|
|
373
|
-
return {
|
|
374
|
-
protocolVersion: "2024-11-05",
|
|
375
|
-
capabilities: { tools: {} },
|
|
376
|
-
serverInfo: { name: CHANNEL_LOOP_MCP_SERVER_NAME, version: "0.0.1" }
|
|
377
|
-
};
|
|
378
|
-
case "tools/list":
|
|
379
|
-
return { tools: CHANNEL_LOOP_MCP_TOOLS };
|
|
380
|
-
case "tools/call":
|
|
381
|
-
return this.callTool(message["params"], context);
|
|
382
|
-
case "ping":
|
|
383
|
-
return {};
|
|
384
|
-
default:
|
|
385
|
-
throw new Error(`Method not found: ${String(message["method"])}`);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
async callTool(rawParams, context) {
|
|
389
|
-
if (!context.sessionId) {
|
|
390
|
-
throw new Error("Missing channel session id.");
|
|
391
|
-
}
|
|
392
|
-
if (typeof rawParams !== "object" || rawParams === null) {
|
|
393
|
-
throw new Error("Invalid tools/call params.");
|
|
394
|
-
}
|
|
395
|
-
const params = rawParams;
|
|
396
|
-
const name = params["name"];
|
|
397
|
-
const args = typeof params["arguments"] === "object" && params["arguments"] !== null ? params["arguments"] : {};
|
|
398
|
-
let toolResult;
|
|
399
|
-
switch (name) {
|
|
400
|
-
case createTool.name:
|
|
401
|
-
toolResult = await this.handler.create(context.sessionId, readCreateInput(args));
|
|
402
|
-
break;
|
|
403
|
-
case listTool.name:
|
|
404
|
-
toolResult = await this.handler.list(context.sessionId);
|
|
405
|
-
break;
|
|
406
|
-
case cancelTool.name:
|
|
407
|
-
toolResult = await this.handler.cancel(context.sessionId, readId(args));
|
|
408
|
-
break;
|
|
409
|
-
default:
|
|
410
|
-
throw new Error(`Unknown channel loop tool: ${String(name)}`);
|
|
411
|
-
}
|
|
412
|
-
const result = typeof toolResult === "string" ? { text: toolResult } : toolResult;
|
|
413
|
-
return {
|
|
414
|
-
content: [{ type: "text", text: result.text }],
|
|
415
|
-
...result.isError ? { isError: true } : {}
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
};
|
|
419
|
-
function readCreateInput(args) {
|
|
420
|
-
const cron = args["cron"];
|
|
421
|
-
const prompt = args["prompt"];
|
|
422
|
-
if (typeof cron !== "string" || cron.trim().length === 0) {
|
|
423
|
-
throw new Error("cron must be a non-empty string.");
|
|
424
|
-
}
|
|
425
|
-
if (typeof prompt !== "string" || prompt.trim().length === 0) {
|
|
426
|
-
throw new Error("prompt must be a non-empty string.");
|
|
427
|
-
}
|
|
428
|
-
const recurring = readRecurring(args["recurring"]);
|
|
429
|
-
return {
|
|
430
|
-
cron: cron.trim(),
|
|
431
|
-
prompt: prompt.trim(),
|
|
432
|
-
...recurring !== void 0 ? { recurring } : {}
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
__name(readCreateInput, "readCreateInput");
|
|
436
|
-
function readRecurring(value) {
|
|
437
|
-
if (typeof value === "boolean")
|
|
438
|
-
return value;
|
|
439
|
-
if (value === "false" || value === 0)
|
|
440
|
-
return false;
|
|
441
|
-
if (value === "true" || value === 1)
|
|
442
|
-
return true;
|
|
443
|
-
return void 0;
|
|
444
|
-
}
|
|
445
|
-
__name(readRecurring, "readRecurring");
|
|
446
|
-
function readId(args) {
|
|
447
|
-
const id = args["id"];
|
|
448
|
-
if (typeof id !== "string" || id.trim().length === 0) {
|
|
449
|
-
throw new Error("id must be a non-empty string.");
|
|
450
|
-
}
|
|
451
|
-
return id.trim();
|
|
452
|
-
}
|
|
453
|
-
__name(readId, "readId");
|
|
454
|
-
|
|
455
|
-
// packages/channels/base/dist/AcpBridge.js
|
|
456
454
|
var MID_TURN_QUEUE_DRAIN_METHOD = "craft/drainMidTurnQueue";
|
|
455
|
+
var TODO_STOP_GUARD_CONTINUATION_CLAIM_METHOD = "craft/claimTodoStopGuardContinuation";
|
|
457
456
|
var ACP_EVENT_LOOP_STALL_RESTART_MS = 5 * 60 * 1e3;
|
|
458
457
|
var ACP_PERMISSION_RESPONSE_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
459
458
|
var ACP_EVENT_LOOP_STALL_RE = /^\[perf\] acp agent event loop stall: max=(\d+(?:\.\d+)?)ms/m;
|
|
@@ -480,6 +479,8 @@ var AcpBridge = class extends EventEmitter {
|
|
|
480
479
|
_availableCommands = [];
|
|
481
480
|
channelLoopMcpServer;
|
|
482
481
|
channelLoopToolHandlers = [];
|
|
482
|
+
knownSessionIds = /* @__PURE__ */ new Set();
|
|
483
|
+
sessionBindingTokens = /* @__PURE__ */ new Map();
|
|
483
484
|
channelLoopMcpRegistered = false;
|
|
484
485
|
channelLoopMcpRegistration = null;
|
|
485
486
|
pendingPermissions = /* @__PURE__ */ new Map();
|
|
@@ -518,6 +519,8 @@ var AcpBridge = class extends EventEmitter {
|
|
|
518
519
|
process.stderr.write(`[AcpBridge] Process exited (code=${code}, signal=${signal})
|
|
519
520
|
`);
|
|
520
521
|
this.resolvePendingPermissions();
|
|
522
|
+
this.knownSessionIds.clear();
|
|
523
|
+
this.sessionBindingTokens.clear();
|
|
521
524
|
this.connection = null;
|
|
522
525
|
this.child = null;
|
|
523
526
|
this.emit("disconnected", code, signal);
|
|
@@ -556,21 +559,25 @@ var AcpBridge = class extends EventEmitter {
|
|
|
556
559
|
});
|
|
557
560
|
void this.registerChannelLoopMcpServer();
|
|
558
561
|
}
|
|
559
|
-
async newSession(cwd) {
|
|
562
|
+
async newSession(cwd, _options, bindingToken) {
|
|
560
563
|
const conn = this.ensureConnection();
|
|
561
564
|
await this.registerChannelLoopMcpServer();
|
|
562
565
|
const response = await conn.newSession({ cwd, mcpServers: [] });
|
|
566
|
+
this.knownSessionIds.add(response.sessionId);
|
|
567
|
+
this.sessionBindingTokens.set(response.sessionId, bindingToken);
|
|
563
568
|
return response.sessionId;
|
|
564
569
|
}
|
|
565
|
-
async loadSession(sessionId, cwd) {
|
|
570
|
+
async loadSession(sessionId, cwd, _options, bindingToken) {
|
|
566
571
|
const conn = this.ensureConnection();
|
|
567
572
|
await this.registerChannelLoopMcpServer();
|
|
568
|
-
|
|
573
|
+
await conn.loadSession({
|
|
569
574
|
sessionId,
|
|
570
575
|
cwd,
|
|
571
576
|
mcpServers: []
|
|
572
577
|
});
|
|
573
|
-
|
|
578
|
+
this.knownSessionIds.add(sessionId);
|
|
579
|
+
this.sessionBindingTokens.set(sessionId, bindingToken);
|
|
580
|
+
return sessionId;
|
|
574
581
|
}
|
|
575
582
|
async prompt(sessionId, text, options) {
|
|
576
583
|
const conn = this.ensureConnection();
|
|
@@ -622,6 +629,19 @@ var AcpBridge = class extends EventEmitter {
|
|
|
622
629
|
this.resolvePendingPermissions(sessionId);
|
|
623
630
|
}
|
|
624
631
|
}
|
|
632
|
+
async discardSession(sessionId, expectedBindingToken) {
|
|
633
|
+
if (expectedBindingToken !== void 0 && this.sessionBindingTokens.get(sessionId) !== expectedBindingToken) {
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
if (!this.knownSessionIds.delete(sessionId))
|
|
637
|
+
return;
|
|
638
|
+
this.sessionBindingTokens.delete(sessionId);
|
|
639
|
+
this.resolvePendingPermissions(sessionId);
|
|
640
|
+
const conn = this.connection;
|
|
641
|
+
if (!conn || !this.isConnected)
|
|
642
|
+
return;
|
|
643
|
+
await conn.extMethod("qwen/control/session/close", { sessionId });
|
|
644
|
+
}
|
|
625
645
|
async respondToPermission(requestId, response) {
|
|
626
646
|
const pending = this.pendingPermissions.get(requestId);
|
|
627
647
|
if (!pending) {
|
|
@@ -638,6 +658,8 @@ var AcpBridge = class extends EventEmitter {
|
|
|
638
658
|
}
|
|
639
659
|
stop() {
|
|
640
660
|
this.resolvePendingPermissions();
|
|
661
|
+
this.knownSessionIds.clear();
|
|
662
|
+
this.sessionBindingTokens.clear();
|
|
641
663
|
if (this.child) {
|
|
642
664
|
this.child.kill();
|
|
643
665
|
this.child = null;
|
|
@@ -814,7 +836,14 @@ var AcpBridge = class extends EventEmitter {
|
|
|
814
836
|
return this.handleClientMcpMessage(params);
|
|
815
837
|
}
|
|
816
838
|
if (method === MID_TURN_QUEUE_DRAIN_METHOD) {
|
|
817
|
-
return { messages: [] };
|
|
839
|
+
return { messages: [], hasQueuedPrompt: false };
|
|
840
|
+
}
|
|
841
|
+
if (method === TODO_STOP_GUARD_CONTINUATION_CLAIM_METHOD) {
|
|
842
|
+
const sessionId = typeof params["sessionId"] === "string" ? params["sessionId"] : "";
|
|
843
|
+
return {
|
|
844
|
+
claimed: this.knownSessionIds.has(sessionId),
|
|
845
|
+
hasQueuedPrompt: false
|
|
846
|
+
};
|
|
818
847
|
}
|
|
819
848
|
throw new Error(`Method not found: ${method}`);
|
|
820
849
|
}
|
|
@@ -948,6 +977,10 @@ var DaemonChannelBridge = class extends EventEmitter2 {
|
|
|
948
977
|
activePromptControllers = /* @__PURE__ */ new Map();
|
|
949
978
|
availableCommandsBySession = /* @__PURE__ */ new Map();
|
|
950
979
|
turnBarriers = /* @__PURE__ */ new Map();
|
|
980
|
+
channelLoopToolHandlers = [];
|
|
981
|
+
registeredChannelLoopMcpSessions = /* @__PURE__ */ new Set();
|
|
982
|
+
channelLoopMcpRegistrations = /* @__PURE__ */ new Map();
|
|
983
|
+
channelLoopMcpServer;
|
|
951
984
|
connected = false;
|
|
952
985
|
lifecycleGeneration = 0;
|
|
953
986
|
latestAvailableCommandsSessionId;
|
|
@@ -998,6 +1031,7 @@ var DaemonChannelBridge = class extends EventEmitter2 {
|
|
|
998
1031
|
await this.rejectStaleSession(session);
|
|
999
1032
|
}
|
|
1000
1033
|
this.attachSession(session, bindingToken);
|
|
1034
|
+
await this.registerChannelLoopMcpForSession(session.sessionId);
|
|
1001
1035
|
return session.sessionId;
|
|
1002
1036
|
}
|
|
1003
1037
|
async loadSession(sessionId, cwd, options, bindingToken) {
|
|
@@ -1019,8 +1053,22 @@ var DaemonChannelBridge = class extends EventEmitter2 {
|
|
|
1019
1053
|
throw new Error(`Daemon returned session ${session.sessionId} while loading ${sessionId}`);
|
|
1020
1054
|
}
|
|
1021
1055
|
this.attachSession(session, bindingToken);
|
|
1056
|
+
await this.registerChannelLoopMcpForSession(session.sessionId);
|
|
1022
1057
|
return session.sessionId;
|
|
1023
1058
|
}
|
|
1059
|
+
registerChannelLoopToolHandler(handler) {
|
|
1060
|
+
if (!this.channelLoopToolHandlers.includes(handler)) {
|
|
1061
|
+
this.channelLoopToolHandlers.push(handler);
|
|
1062
|
+
}
|
|
1063
|
+
this.channelLoopMcpServer ??= new ChannelLoopMcpServer({
|
|
1064
|
+
create: /* @__PURE__ */ __name((sessionId, input) => this.resolveChannelLoopToolHandler(sessionId).create(sessionId, input), "create"),
|
|
1065
|
+
list: /* @__PURE__ */ __name((sessionId) => this.resolveChannelLoopToolHandler(sessionId).list(sessionId), "list"),
|
|
1066
|
+
cancel: /* @__PURE__ */ __name((sessionId, id) => this.resolveChannelLoopToolHandler(sessionId).cancel(sessionId, id), "cancel")
|
|
1067
|
+
});
|
|
1068
|
+
for (const sessionId of this.sessions.keys()) {
|
|
1069
|
+
void this.registerChannelLoopMcpForSession(sessionId);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1024
1072
|
async prompt(sessionId, text, options) {
|
|
1025
1073
|
const session = this.ensureSession(sessionId);
|
|
1026
1074
|
if (this.activePrompts.has(sessionId)) {
|
|
@@ -1177,7 +1225,7 @@ var DaemonChannelBridge = class extends EventEmitter2 {
|
|
|
1177
1225
|
return this.connected;
|
|
1178
1226
|
}
|
|
1179
1227
|
attachSession(session, bindingToken) {
|
|
1180
|
-
const replacedSession = this.removeSessionBinding(session.sessionId);
|
|
1228
|
+
const replacedSession = this.removeSessionBinding(session.sessionId, false);
|
|
1181
1229
|
if (replacedSession) {
|
|
1182
1230
|
void this.releaseSessionClient(replacedSession).catch((error) => {
|
|
1183
1231
|
this.lastError = error;
|
|
@@ -1441,7 +1489,7 @@ var DaemonChannelBridge = class extends EventEmitter2 {
|
|
|
1441
1489
|
}
|
|
1442
1490
|
this.emit("sessionDied", { sessionId, reason });
|
|
1443
1491
|
}
|
|
1444
|
-
removeSessionBinding(sessionId) {
|
|
1492
|
+
removeSessionBinding(sessionId, unregisterChannelLoopMcp = true) {
|
|
1445
1493
|
const session = this.sessions.get(sessionId);
|
|
1446
1494
|
if (!session)
|
|
1447
1495
|
return void 0;
|
|
@@ -1466,8 +1514,51 @@ var DaemonChannelBridge = class extends EventEmitter2 {
|
|
|
1466
1514
|
this.respondedRequestToSession.delete(requestId);
|
|
1467
1515
|
}
|
|
1468
1516
|
}
|
|
1517
|
+
if (unregisterChannelLoopMcp) {
|
|
1518
|
+
this.unregisterChannelLoopMcpForSession(sessionId);
|
|
1519
|
+
}
|
|
1469
1520
|
return session;
|
|
1470
1521
|
}
|
|
1522
|
+
async registerChannelLoopMcpForSession(sessionId) {
|
|
1523
|
+
const host = this.options.channelLoopMcpHost;
|
|
1524
|
+
const server = this.channelLoopMcpServer;
|
|
1525
|
+
if (!host || !server || this.registeredChannelLoopMcpSessions.has(sessionId)) {
|
|
1526
|
+
return;
|
|
1527
|
+
}
|
|
1528
|
+
const pending = this.channelLoopMcpRegistrations.get(sessionId);
|
|
1529
|
+
if (pending) {
|
|
1530
|
+
await pending;
|
|
1531
|
+
return;
|
|
1532
|
+
}
|
|
1533
|
+
const registration = host.register(sessionId, (message) => server.handleMessage(message, { sessionId })).then(async () => {
|
|
1534
|
+
if (this.sessions.has(sessionId)) {
|
|
1535
|
+
this.registeredChannelLoopMcpSessions.add(sessionId);
|
|
1536
|
+
} else {
|
|
1537
|
+
await host.unregister(sessionId);
|
|
1538
|
+
}
|
|
1539
|
+
}).catch((error) => {
|
|
1540
|
+
this.lastError = error;
|
|
1541
|
+
}).finally(() => {
|
|
1542
|
+
if (this.channelLoopMcpRegistrations.get(sessionId) === registration) {
|
|
1543
|
+
this.channelLoopMcpRegistrations.delete(sessionId);
|
|
1544
|
+
}
|
|
1545
|
+
});
|
|
1546
|
+
this.channelLoopMcpRegistrations.set(sessionId, registration);
|
|
1547
|
+
await registration;
|
|
1548
|
+
}
|
|
1549
|
+
unregisterChannelLoopMcpForSession(sessionId) {
|
|
1550
|
+
if (!this.registeredChannelLoopMcpSessions.delete(sessionId))
|
|
1551
|
+
return;
|
|
1552
|
+
void this.options.channelLoopMcpHost?.unregister(sessionId).catch((error) => {
|
|
1553
|
+
this.lastError = error;
|
|
1554
|
+
});
|
|
1555
|
+
}
|
|
1556
|
+
resolveChannelLoopToolHandler(sessionId) {
|
|
1557
|
+
const handler = this.channelLoopToolHandlers.find((candidate) => candidate.canHandle?.(sessionId) === true || this.channelLoopToolHandlers.length === 1 && !candidate.canHandle);
|
|
1558
|
+
if (handler)
|
|
1559
|
+
return handler;
|
|
1560
|
+
throw new Error(`No channel loop handler matched session ${sessionId}.`);
|
|
1561
|
+
}
|
|
1471
1562
|
getStringField(data, field, fallback) {
|
|
1472
1563
|
return isRecord(data) && typeof data[field] === "string" ? data[field] : fallback;
|
|
1473
1564
|
}
|
|
@@ -1963,6 +2054,9 @@ var SenderGate = class {
|
|
|
1963
2054
|
this.allowedUsers = new Set(allowedUsers);
|
|
1964
2055
|
this.pairingStore = pairingStore || null;
|
|
1965
2056
|
}
|
|
2057
|
+
replaceAllowedUsers(users) {
|
|
2058
|
+
this.allowedUsers = new Set(users);
|
|
2059
|
+
}
|
|
1966
2060
|
isAllowed(senderId) {
|
|
1967
2061
|
switch (this.policy) {
|
|
1968
2062
|
case "open":
|
|
@@ -2051,6 +2145,8 @@ var SessionRouter = class {
|
|
|
2051
2145
|
switch (scope) {
|
|
2052
2146
|
case "thread":
|
|
2053
2147
|
return `${channelName}:${threadId || chatId}`;
|
|
2148
|
+
case "chat_thread":
|
|
2149
|
+
return threadId ? `${channelName}:${chatId}:${threadId}` : `${channelName}:${chatId}`;
|
|
2054
2150
|
case "single":
|
|
2055
2151
|
return `${channelName}:__single__`;
|
|
2056
2152
|
case "user":
|
|
@@ -3425,7 +3521,7 @@ var ChannelBase = class {
|
|
|
3425
3521
|
if (target.threadId !== void 0 && this.supportsProactiveSend() && this.supportsProactiveTarget(target)) {
|
|
3426
3522
|
await this.pushProactive(target, text);
|
|
3427
3523
|
} else {
|
|
3428
|
-
await this.
|
|
3524
|
+
await this.sendThreadMessage(target.chatId, target.threadId, text);
|
|
3429
3525
|
}
|
|
3430
3526
|
} catch (err) {
|
|
3431
3527
|
this.removePendingPermission(event.requestId);
|
|
@@ -3494,6 +3590,14 @@ var ChannelBase = class {
|
|
|
3494
3590
|
this.attachBridgeEvents(bridge);
|
|
3495
3591
|
}
|
|
3496
3592
|
}
|
|
3593
|
+
/**
|
|
3594
|
+
* Thread-targeted delivery. Polling adapters override this to post comments
|
|
3595
|
+
* on a specific issue/PR. The default falls through to sendMessage(chatId,
|
|
3596
|
+
* text), ignoring threadId — existing IM adapters are behaviorally unchanged.
|
|
3597
|
+
*/
|
|
3598
|
+
async sendThreadMessage(chatId, _threadId, text) {
|
|
3599
|
+
await this.sendMessage(chatId, text);
|
|
3600
|
+
}
|
|
3497
3601
|
/**
|
|
3498
3602
|
* Adapter hook for task lifecycle events — the canonical way to track task
|
|
3499
3603
|
* state (onPromptStart/onPromptEnd are retained for back-compat). The prompt
|
|
@@ -3624,7 +3728,7 @@ var ChannelBase = class {
|
|
|
3624
3728
|
if (target.threadId) {
|
|
3625
3729
|
throw new Error("Channel does not support proactive loop messages for threaded targets.");
|
|
3626
3730
|
}
|
|
3627
|
-
await this.
|
|
3731
|
+
await this.sendThreadMessage(target.chatId, target.threadId, text);
|
|
3628
3732
|
}
|
|
3629
3733
|
async pushProactiveDelivery(target, text) {
|
|
3630
3734
|
try {
|
|
@@ -3807,6 +3911,7 @@ var ChannelBase = class {
|
|
|
3807
3911
|
alreadyPrefixed: true,
|
|
3808
3912
|
referencedText: void 0,
|
|
3809
3913
|
attachments: void 0,
|
|
3914
|
+
metadata: void 0,
|
|
3810
3915
|
imageBase64: void 0,
|
|
3811
3916
|
imageMimeType: void 0
|
|
3812
3917
|
};
|
|
@@ -4274,6 +4379,7 @@ ${promptText}` : promptText;
|
|
|
4274
4379
|
this.router.removeSessionId(sessionId);
|
|
4275
4380
|
this.instructedSessions.delete(sessionId);
|
|
4276
4381
|
this.unattendedMemorySessions.delete(sessionId);
|
|
4382
|
+
this.discardRetiredSession(promptBridge, sessionId, `timed-out loop ${jobId}`);
|
|
4277
4383
|
process.stderr.write(`[${this.name}] retired timed out loop ${jobId} session ${sessionId} after cancel did not settle
|
|
4278
4384
|
`);
|
|
4279
4385
|
}
|
|
@@ -4284,6 +4390,19 @@ ${promptText}` : promptText;
|
|
|
4284
4390
|
clearTimeout(graceTimer);
|
|
4285
4391
|
}
|
|
4286
4392
|
}
|
|
4393
|
+
discardRetiredSession(promptBridge, sessionId, reason) {
|
|
4394
|
+
const safeSessionId = sanitizeLogText(sessionId, 64);
|
|
4395
|
+
const safeReason = sanitizeLogText(reason, 128);
|
|
4396
|
+
try {
|
|
4397
|
+
void promptBridge.discardSession?.(sessionId).catch((err) => {
|
|
4398
|
+
process.stderr.write(`[${this.name}] failed to discard ${safeReason} session ${safeSessionId}: ${this.lifecycleError(err)}
|
|
4399
|
+
`);
|
|
4400
|
+
});
|
|
4401
|
+
} catch (err) {
|
|
4402
|
+
process.stderr.write(`[${this.name}] failed to discard ${safeReason} session ${safeSessionId}: ${this.lifecycleError(err)}
|
|
4403
|
+
`);
|
|
4404
|
+
}
|
|
4405
|
+
}
|
|
4287
4406
|
requestActivePromptCancellation(sessionId, reason = "cancel_command") {
|
|
4288
4407
|
const active = this.activePrompts.get(sessionId);
|
|
4289
4408
|
if (!active) {
|
|
@@ -4422,8 +4541,11 @@ ${promptText}` : promptText;
|
|
|
4422
4541
|
*/
|
|
4423
4542
|
onResponseBoundary(_chatId, _sessionId) {
|
|
4424
4543
|
}
|
|
4425
|
-
async sendResponseMessage(chatId, text,
|
|
4426
|
-
|
|
4544
|
+
async sendResponseMessage(chatId, text, sessionId) {
|
|
4545
|
+
const active = this.activePrompts.get(sessionId);
|
|
4546
|
+
const target = this.router.getTarget(sessionId);
|
|
4547
|
+
const threadId = active?.threadId ?? target?.threadId;
|
|
4548
|
+
await this.sendThreadMessage(chatId, threadId, text);
|
|
4427
4549
|
}
|
|
4428
4550
|
/**
|
|
4429
4551
|
* Called when the agent's full response is ready.
|
|
@@ -4444,21 +4566,21 @@ ${promptText}` : promptText;
|
|
|
4444
4566
|
registerCancelCommand(name = "cancel") {
|
|
4445
4567
|
this.registerCommand(name, async (envelope) => {
|
|
4446
4568
|
if (!this.isAuthorizedForSharedSession(envelope)) {
|
|
4447
|
-
await this.
|
|
4569
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can cancel requests in this shared session.");
|
|
4448
4570
|
return true;
|
|
4449
4571
|
}
|
|
4450
4572
|
const activeSessionId = this.findActiveSessionId(envelope);
|
|
4451
4573
|
if (!activeSessionId) {
|
|
4452
|
-
await this.
|
|
4574
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No request is currently running.");
|
|
4453
4575
|
return true;
|
|
4454
4576
|
}
|
|
4455
4577
|
const active = this.activePrompts.get(activeSessionId);
|
|
4456
4578
|
if (!active) {
|
|
4457
|
-
await this.
|
|
4579
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No request is currently running.");
|
|
4458
4580
|
return true;
|
|
4459
4581
|
}
|
|
4460
4582
|
const cancelSucceeded = await this.requestActivePromptCancellation(activeSessionId, "cancel_command");
|
|
4461
|
-
await this.
|
|
4583
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, cancelSucceeded ? "Cancelled current request." : "Failed to cancel current request.");
|
|
4462
4584
|
return true;
|
|
4463
4585
|
});
|
|
4464
4586
|
}
|
|
@@ -4590,7 +4712,7 @@ ${promptText}` : promptText;
|
|
|
4590
4712
|
}
|
|
4591
4713
|
async handlePermissionResponseCommand(envelope, args, decision) {
|
|
4592
4714
|
if (!this.isAuthorizedForSharedSession(envelope)) {
|
|
4593
|
-
await this.
|
|
4715
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can answer permission requests in this shared session.");
|
|
4594
4716
|
return true;
|
|
4595
4717
|
}
|
|
4596
4718
|
const lookup = this.pendingPermissionForEnvelope(envelope, args);
|
|
@@ -4600,16 +4722,16 @@ ${promptText}` : promptText;
|
|
|
4600
4722
|
const title = pending2 ? `: ${sanitizeQuotedText(pending2.request.toolCall.title || "Tool use", 160)}` : "";
|
|
4601
4723
|
return `- ${sanitizeQuotedText(id, 128)}${title}`;
|
|
4602
4724
|
}).join("\n");
|
|
4603
|
-
await this.
|
|
4725
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Multiple permission requests are pending for this chat. Reply with /${decision} <request-id>.
|
|
4604
4726
|
${requestList}`);
|
|
4605
4727
|
return true;
|
|
4606
4728
|
}
|
|
4607
4729
|
if (lookup.kind === "none") {
|
|
4608
|
-
await this.
|
|
4730
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, lookup.explicit ? "No pending permission request with that id for this chat." : "No pending permission request for this chat.");
|
|
4609
4731
|
return true;
|
|
4610
4732
|
}
|
|
4611
4733
|
if (!this.bridge.respondToPermission) {
|
|
4612
|
-
await this.
|
|
4734
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Permission relay is not available for this session.");
|
|
4613
4735
|
return true;
|
|
4614
4736
|
}
|
|
4615
4737
|
const { pending } = lookup;
|
|
@@ -4621,7 +4743,7 @@ ${requestList}`);
|
|
|
4621
4743
|
return optionId ? { outcome: { outcome: "selected", optionId } } : void 0;
|
|
4622
4744
|
})();
|
|
4623
4745
|
if (!response) {
|
|
4624
|
-
await this.
|
|
4746
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, decision === "approve-always" ? "This permission request has no always-allow option." : "This permission request has no approvable option.");
|
|
4625
4747
|
return true;
|
|
4626
4748
|
}
|
|
4627
4749
|
let accepted;
|
|
@@ -4631,11 +4753,11 @@ ${requestList}`);
|
|
|
4631
4753
|
this.removePendingPermission(pending.requestId);
|
|
4632
4754
|
process.stderr.write(`[${this.name}] permission response failed for request ${sanitizeLogText(pending.requestId, 128)}: ${this.lifecycleError(err)}
|
|
4633
4755
|
`);
|
|
4634
|
-
await this.
|
|
4756
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Failed to answer the permission request.");
|
|
4635
4757
|
return true;
|
|
4636
4758
|
}
|
|
4637
4759
|
this.removePendingPermission(pending.requestId);
|
|
4638
|
-
await this.
|
|
4760
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, accepted ? decision === "approve" ? "Permission approved." : decision === "approve-always" ? "Permission approved always." : "Permission denied." : "Permission request is no longer pending.");
|
|
4639
4761
|
return true;
|
|
4640
4762
|
}
|
|
4641
4763
|
/** Register shared slash commands. Called from constructor. */
|
|
@@ -4685,19 +4807,20 @@ ${requestList}`);
|
|
|
4685
4807
|
} else {
|
|
4686
4808
|
this.sessionGenerations.delete(id);
|
|
4687
4809
|
}
|
|
4810
|
+
this.discardRetiredSession(this.bridge, id, "cleared");
|
|
4688
4811
|
}
|
|
4689
|
-
await this.
|
|
4812
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Session cleared. The next message starts a fresh conversation.");
|
|
4690
4813
|
} else {
|
|
4691
|
-
await this.
|
|
4814
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No active session to clear.");
|
|
4692
4815
|
}
|
|
4693
4816
|
}, "doClear");
|
|
4694
4817
|
const clearHandler = /* @__PURE__ */ __name(async (envelope, args) => {
|
|
4695
4818
|
if (!this.isAuthorizedForSharedSession(envelope)) {
|
|
4696
|
-
await this.
|
|
4819
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can clear this shared session.");
|
|
4697
4820
|
return true;
|
|
4698
4821
|
}
|
|
4699
4822
|
if (this.isSharedSession(envelope) && args.toLowerCase() !== "confirm") {
|
|
4700
|
-
await this.
|
|
4823
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, 'This clears the shared session for everyone who shares it. Re-send with "confirm" (e.g. /clear confirm) to proceed.');
|
|
4701
4824
|
return true;
|
|
4702
4825
|
}
|
|
4703
4826
|
await doClear(envelope);
|
|
@@ -4711,12 +4834,12 @@ ${requestList}`);
|
|
|
4711
4834
|
this.registerCommand("deny", (envelope, args) => this.handlePermissionResponseCommand(envelope, args, "deny"));
|
|
4712
4835
|
this.registerCommand("who", async (envelope) => {
|
|
4713
4836
|
if (!this.isAuthorizedForSharedSession(envelope)) {
|
|
4714
|
-
await this.
|
|
4837
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can view this shared session.");
|
|
4715
4838
|
return true;
|
|
4716
4839
|
}
|
|
4717
4840
|
const active = this.router.hasSession(this.name, envelope.senderId, envelope.chatId, envelope.threadId);
|
|
4718
4841
|
const scopeNote = this.config.sessionScope === "single" ? " (shared channel-wide)" : this.isSharedSession(envelope) ? envelope.isGroup ? " (shared by this group)" : "" : envelope.isGroup ? " (private to you)" : "";
|
|
4719
|
-
await this.
|
|
4842
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, [
|
|
4720
4843
|
`Channel: ${this.name}`,
|
|
4721
4844
|
// Identity/memory lines only for channels that opted in — keep
|
|
4722
4845
|
// unconfigured channels' output unchanged.
|
|
@@ -4770,12 +4893,12 @@ ${requestList}`);
|
|
|
4770
4893
|
}
|
|
4771
4894
|
}
|
|
4772
4895
|
lines.push("", "Send any text to chat with the agent.");
|
|
4773
|
-
await this.
|
|
4896
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, lines.join("\n"));
|
|
4774
4897
|
return true;
|
|
4775
4898
|
});
|
|
4776
4899
|
this.registerCommand("status", async (envelope) => {
|
|
4777
4900
|
if (!this.isAuthorizedForSharedSession(envelope)) {
|
|
4778
|
-
await this.
|
|
4901
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can view this shared session.");
|
|
4779
4902
|
return true;
|
|
4780
4903
|
}
|
|
4781
4904
|
const hasSession = this.router.hasSession(this.name, envelope.senderId, envelope.chatId, envelope.threadId);
|
|
@@ -4789,18 +4912,18 @@ ${requestList}`);
|
|
|
4789
4912
|
`Memory: ${this.memoryScope.mode}`
|
|
4790
4913
|
] : []
|
|
4791
4914
|
];
|
|
4792
|
-
await this.
|
|
4915
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, lines.join("\n"));
|
|
4793
4916
|
return true;
|
|
4794
4917
|
});
|
|
4795
4918
|
this.registerCommand("loop", async (envelope, args) => this.handleLoopCommand(envelope, args));
|
|
4796
4919
|
}
|
|
4797
4920
|
async handleLoopCommand(envelope, args) {
|
|
4798
4921
|
if (!this.loopController) {
|
|
4799
|
-
await this.
|
|
4922
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Loops are not available.");
|
|
4800
4923
|
return true;
|
|
4801
4924
|
}
|
|
4802
4925
|
if (!this.isAuthorizedForSharedSession(envelope)) {
|
|
4803
|
-
await this.
|
|
4926
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can use loops in this shared session.");
|
|
4804
4927
|
return true;
|
|
4805
4928
|
}
|
|
4806
4929
|
const [subcommand = "", ...rest] = args.trim().split(/\s+/u);
|
|
@@ -4814,7 +4937,7 @@ ${requestList}`);
|
|
|
4814
4937
|
case "cancel":
|
|
4815
4938
|
return this.handleLoopCancel(envelope, rest[0]);
|
|
4816
4939
|
default:
|
|
4817
|
-
await this.
|
|
4940
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, 'Usage: /loop add "<cron>" <prompt> | /loop list | /loop inspect <id> | /loop cancel <id>');
|
|
4818
4941
|
return true;
|
|
4819
4942
|
}
|
|
4820
4943
|
}
|
|
@@ -4822,32 +4945,32 @@ ${requestList}`);
|
|
|
4822
4945
|
if (!this.loopController)
|
|
4823
4946
|
return true;
|
|
4824
4947
|
if (!this.supportsProactiveSend()) {
|
|
4825
|
-
await this.
|
|
4948
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "This channel does not support proactive loop messages.");
|
|
4826
4949
|
return true;
|
|
4827
4950
|
}
|
|
4828
4951
|
if (this.config.sessionScope === "single") {
|
|
4829
|
-
await this.
|
|
4952
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Loops are not supported when sessionScope is single.");
|
|
4830
4953
|
return true;
|
|
4831
4954
|
}
|
|
4832
4955
|
const parsed = parseLoopAddArgs(args);
|
|
4833
4956
|
if (!parsed) {
|
|
4834
|
-
await this.
|
|
4957
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, 'Usage: /loop add "<cron>" <prompt>');
|
|
4835
4958
|
return true;
|
|
4836
4959
|
}
|
|
4837
4960
|
try {
|
|
4838
4961
|
this.loopController.validateCron(parsed.cron);
|
|
4839
4962
|
} catch (err) {
|
|
4840
|
-
await this.
|
|
4963
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Invalid cron expression: ${err instanceof Error ? err.message : String(err)}`);
|
|
4841
4964
|
return true;
|
|
4842
4965
|
}
|
|
4843
4966
|
const target = this.loopTargetFromEnvelope(envelope);
|
|
4844
4967
|
if (!this.supportsProactiveTarget(target)) {
|
|
4845
|
-
await this.
|
|
4968
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "This channel does not support proactive loop messages for this chat target.");
|
|
4846
4969
|
return true;
|
|
4847
4970
|
}
|
|
4848
4971
|
const prompt = sanitizePromptText(parsed.prompt.trim());
|
|
4849
4972
|
if (Array.from(prompt).length > MAX_LOOP_PROMPT_CHARS) {
|
|
4850
|
-
await this.
|
|
4973
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Loop prompt is too long; keep it under ${MAX_LOOP_PROMPT_CHARS} characters.`);
|
|
4851
4974
|
return true;
|
|
4852
4975
|
}
|
|
4853
4976
|
const input = {
|
|
@@ -4870,10 +4993,10 @@ ${requestList}`);
|
|
|
4870
4993
|
}
|
|
4871
4994
|
}
|
|
4872
4995
|
if (!job) {
|
|
4873
|
-
await this.
|
|
4996
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Too many loops for this chat. Cancel an existing loop before adding another.`);
|
|
4874
4997
|
return true;
|
|
4875
4998
|
}
|
|
4876
|
-
await this.
|
|
4999
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Loop ${job.id}: ${job.cron}`);
|
|
4877
5000
|
return true;
|
|
4878
5001
|
}
|
|
4879
5002
|
async createLoopFromTool(sessionId, input) {
|
|
@@ -4975,23 +5098,23 @@ ${requestList}`);
|
|
|
4975
5098
|
return true;
|
|
4976
5099
|
const jobs = await this.loopController.listForTarget(this.name, this.loopTargetFromEnvelope(envelope));
|
|
4977
5100
|
if (jobs.length === 0) {
|
|
4978
|
-
await this.
|
|
5101
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No loops.");
|
|
4979
5102
|
return true;
|
|
4980
5103
|
}
|
|
4981
|
-
await this.
|
|
5104
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, jobs.map((job) => this.formatLoopListLine(job)).join("\n"));
|
|
4982
5105
|
return true;
|
|
4983
5106
|
}
|
|
4984
5107
|
async handleLoopInspect(envelope, id) {
|
|
4985
5108
|
if (!this.loopController)
|
|
4986
5109
|
return true;
|
|
4987
5110
|
if (!id) {
|
|
4988
|
-
await this.
|
|
5111
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Usage: /loop inspect <id>");
|
|
4989
5112
|
return true;
|
|
4990
5113
|
}
|
|
4991
5114
|
const jobs = await this.loopController.listForTarget(this.name, this.loopTargetFromEnvelope(envelope));
|
|
4992
5115
|
const job = jobs.find((candidate) => candidate.id === id);
|
|
4993
5116
|
if (!job) {
|
|
4994
|
-
await this.
|
|
5117
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `No loop ${id}.`);
|
|
4995
5118
|
return true;
|
|
4996
5119
|
}
|
|
4997
5120
|
const lines = [
|
|
@@ -5013,7 +5136,7 @@ ${requestList}`);
|
|
|
5013
5136
|
lines.push(`Last result: ${job.lastResultPreview}`);
|
|
5014
5137
|
}
|
|
5015
5138
|
lines.push(`Prompt: ${job.prompt}`);
|
|
5016
|
-
await this.
|
|
5139
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, lines.join("\n"));
|
|
5017
5140
|
return true;
|
|
5018
5141
|
}
|
|
5019
5142
|
formatLoopListLine(job) {
|
|
@@ -5045,17 +5168,17 @@ ${requestList}`);
|
|
|
5045
5168
|
if (!this.loopController)
|
|
5046
5169
|
return true;
|
|
5047
5170
|
if (!id) {
|
|
5048
|
-
await this.
|
|
5171
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Usage: /loop cancel <id>");
|
|
5049
5172
|
return true;
|
|
5050
5173
|
}
|
|
5051
5174
|
const jobs = await this.loopController.listForTarget(this.name, this.loopTargetFromEnvelope(envelope));
|
|
5052
5175
|
const match = jobs.find((job) => job.id === id);
|
|
5053
5176
|
if (!match) {
|
|
5054
|
-
await this.
|
|
5177
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `No loop ${id}.`);
|
|
5055
5178
|
return true;
|
|
5056
5179
|
}
|
|
5057
5180
|
const disabled = await this.loopController.disable(id);
|
|
5058
|
-
await this.
|
|
5181
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, disabled ? `Cancelled loop ${id}.` : `Failed to cancel loop ${id}.`);
|
|
5059
5182
|
return true;
|
|
5060
5183
|
}
|
|
5061
5184
|
loopTargetFromEnvelope(envelope) {
|
|
@@ -5172,7 +5295,7 @@ ${requestList}`);
|
|
|
5172
5295
|
}
|
|
5173
5296
|
async getChannelMemory(envelope) {
|
|
5174
5297
|
if (!this.channelMemory) {
|
|
5175
|
-
await this.
|
|
5298
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Channel memory is not configured for this channel.");
|
|
5176
5299
|
return void 0;
|
|
5177
5300
|
}
|
|
5178
5301
|
return this.channelMemory;
|
|
@@ -5190,7 +5313,7 @@ ${requestList}`);
|
|
|
5190
5313
|
}
|
|
5191
5314
|
async handleChannelMemoryIntent(envelope, intent, options = {}) {
|
|
5192
5315
|
if (intent.kind === "no_match") {
|
|
5193
|
-
await this.
|
|
5316
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No matching channel memory entry.");
|
|
5194
5317
|
return;
|
|
5195
5318
|
}
|
|
5196
5319
|
if (intent.kind === "ambiguous") {
|
|
@@ -5202,11 +5325,11 @@ ${requestList}`);
|
|
|
5202
5325
|
entries = await channelMemory2.listChannelMemoryEntries(this.channelMemoryTarget(envelope));
|
|
5203
5326
|
} catch (error) {
|
|
5204
5327
|
this.logChannelMemoryError("read", envelope, this.channelMemoryErrorMessage(error));
|
|
5205
|
-
await this.
|
|
5328
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Failed to read channel memory: ${this.channelMemoryUserErrorMessage()}`);
|
|
5206
5329
|
return;
|
|
5207
5330
|
}
|
|
5208
5331
|
const selected = this.entriesForChannelMemoryIds(entries, intent.ids);
|
|
5209
|
-
await this.
|
|
5332
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, [
|
|
5210
5333
|
"Multiple channel memory entries match:",
|
|
5211
5334
|
...this.renderChannelMemoryCandidates(selected)
|
|
5212
5335
|
].join("\n"));
|
|
@@ -5221,11 +5344,11 @@ ${requestList}`);
|
|
|
5221
5344
|
entries = await channelMemory2.listChannelMemoryEntries(this.channelMemoryTarget(envelope));
|
|
5222
5345
|
} catch (error) {
|
|
5223
5346
|
this.logChannelMemoryError("read", envelope, this.channelMemoryErrorMessage(error));
|
|
5224
|
-
await this.
|
|
5347
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Failed to read channel memory: ${this.channelMemoryUserErrorMessage()}`);
|
|
5225
5348
|
return;
|
|
5226
5349
|
}
|
|
5227
5350
|
const selected = this.entriesForChannelMemoryIds(entries, intent.ids);
|
|
5228
|
-
await this.
|
|
5351
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, [
|
|
5229
5352
|
"Channel memory (page 1/1):",
|
|
5230
5353
|
...this.renderChannelMemoryCandidates(selected)
|
|
5231
5354
|
].join("\n"));
|
|
@@ -5238,7 +5361,7 @@ ${requestList}`);
|
|
|
5238
5361
|
if (intent.kind === "update_confirm" || intent.kind === "remove_confirm") {
|
|
5239
5362
|
const pending = intent.kind === "update_confirm" ? this.takePendingChannelMemoryMutation(envelope, "update") : this.takePendingChannelMemoryMutation(envelope, "remove");
|
|
5240
5363
|
if (!pending) {
|
|
5241
|
-
await this.
|
|
5364
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, intent.kind === "update_confirm" ? "No pending channel memory update. Start a new update request first." : "No pending channel memory removal. Start a new removal request first.");
|
|
5242
5365
|
return;
|
|
5243
5366
|
}
|
|
5244
5367
|
const channelMemory2 = await this.getChannelMemory(envelope);
|
|
@@ -5262,15 +5385,15 @@ ${requestList}`);
|
|
|
5262
5385
|
} catch (error) {
|
|
5263
5386
|
const message = this.channelMemoryErrorMessage(error);
|
|
5264
5387
|
this.logChannelMemoryError(isUpdate ? "update" : "remove", envelope, message);
|
|
5265
|
-
await this.
|
|
5388
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, message === "Channel memory entry changed" ? "That channel memory entry changed since it was selected. View channel memory and start the operation again." : `Failed to ${isUpdate ? "update" : "remove"} channel memory: ${this.channelMemoryUserErrorMessage()}`);
|
|
5266
5389
|
return;
|
|
5267
5390
|
}
|
|
5268
5391
|
if (!changed) {
|
|
5269
|
-
await this.
|
|
5392
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `No channel memory entry ${pending.id}.`);
|
|
5270
5393
|
return;
|
|
5271
5394
|
}
|
|
5272
5395
|
this.invalidateUnattendedMemory(envelope);
|
|
5273
|
-
await this.
|
|
5396
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Channel memory ${pending.id} ${isUpdate ? "updated" : "removed"}.`);
|
|
5274
5397
|
return;
|
|
5275
5398
|
}
|
|
5276
5399
|
if (intent.kind === "natural_update") {
|
|
@@ -5310,7 +5433,7 @@ ${requestList}`);
|
|
|
5310
5433
|
} catch (error) {
|
|
5311
5434
|
const message = this.channelMemoryErrorMessage(error);
|
|
5312
5435
|
this.logChannelMemoryError("save", envelope, message);
|
|
5313
|
-
await this.
|
|
5436
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Failed to save channel memory: ${this.channelMemoryUserErrorMessage()}`);
|
|
5314
5437
|
return;
|
|
5315
5438
|
}
|
|
5316
5439
|
if (result.changed) {
|
|
@@ -5321,11 +5444,11 @@ ${requestList}`);
|
|
|
5321
5444
|
}
|
|
5322
5445
|
if (result.added.length > 0) {
|
|
5323
5446
|
const ids = result.added.map((entry) => entry.id);
|
|
5324
|
-
await this.
|
|
5447
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, result.duplicateIds.length > 0 ? `Channel memory saved: ${ids.join(", ")}. Skipped duplicates: ${result.duplicateIds.join(", ")}.` : ids.length === 1 ? `Channel memory ${ids[0]} saved.` : `Channel memory saved: ${ids.join(", ")}.`);
|
|
5325
5448
|
} else if (result.duplicateIds.length > 0) {
|
|
5326
|
-
await this.
|
|
5449
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Channel memory already contains ${result.duplicateIds.join(", ")}.`);
|
|
5327
5450
|
} else {
|
|
5328
|
-
await this.
|
|
5451
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Channel memory updated.");
|
|
5329
5452
|
}
|
|
5330
5453
|
return;
|
|
5331
5454
|
}
|
|
@@ -5336,27 +5459,27 @@ ${requestList}`);
|
|
|
5336
5459
|
} catch (error) {
|
|
5337
5460
|
const message = this.channelMemoryErrorMessage(error);
|
|
5338
5461
|
this.logChannelMemoryError("read", envelope, message);
|
|
5339
|
-
await this.
|
|
5462
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Failed to read channel memory: ${this.channelMemoryUserErrorMessage()}`);
|
|
5340
5463
|
return;
|
|
5341
5464
|
}
|
|
5342
5465
|
if (intent.kind === "inspect") {
|
|
5343
5466
|
const entry = entries.find((candidate) => candidate.id === intent.id);
|
|
5344
|
-
await this.
|
|
5467
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, entry ? `Channel memory ${entry.id}:
|
|
5345
5468
|
${sanitizePromptText(entry.text).trim()}` : `No channel memory entry ${intent.id}.`);
|
|
5346
5469
|
return;
|
|
5347
5470
|
}
|
|
5348
5471
|
const totalPages = Math.max(1, Math.ceil(entries.length / CHANNEL_MEMORY_PAGE_SIZE));
|
|
5349
5472
|
if (intent.page > totalPages) {
|
|
5350
|
-
await this.
|
|
5473
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Channel memory page ${intent.page} does not exist.`);
|
|
5351
5474
|
return;
|
|
5352
5475
|
}
|
|
5353
5476
|
if (entries.length === 0) {
|
|
5354
|
-
await this.
|
|
5477
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No channel memory saved.");
|
|
5355
5478
|
return;
|
|
5356
5479
|
}
|
|
5357
5480
|
const pageStart = (intent.page - 1) * CHANNEL_MEMORY_PAGE_SIZE;
|
|
5358
5481
|
const lines = entries.slice(pageStart, pageStart + CHANNEL_MEMORY_PAGE_SIZE).map((entry) => this.renderChannelMemoryCandidate(entry));
|
|
5359
|
-
await this.
|
|
5482
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, [`Channel memory (page ${intent.page}/${totalPages}):`, ...lines].join("\n"));
|
|
5360
5483
|
return;
|
|
5361
5484
|
}
|
|
5362
5485
|
if (intent.kind === "update" || intent.kind === "remove") {
|
|
@@ -5372,21 +5495,21 @@ ${sanitizePromptText(entry.text).trim()}` : `No channel memory entry ${intent.id
|
|
|
5372
5495
|
} catch (error) {
|
|
5373
5496
|
const message = this.channelMemoryErrorMessage(error);
|
|
5374
5497
|
this.logChannelMemoryError(isUpdate ? "update" : "remove", envelope, message);
|
|
5375
|
-
await this.
|
|
5498
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Failed to ${isUpdate ? "update" : "remove"} channel memory: ${this.channelMemoryUserErrorMessage()}`);
|
|
5376
5499
|
return;
|
|
5377
5500
|
}
|
|
5378
5501
|
if (!changed) {
|
|
5379
|
-
await this.
|
|
5502
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `No channel memory entry ${id}.`);
|
|
5380
5503
|
return;
|
|
5381
5504
|
}
|
|
5382
5505
|
this.invalidateUnattendedMemory(envelope);
|
|
5383
|
-
await this.
|
|
5506
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Channel memory ${id} ${isUpdate ? "updated" : "removed"}.`);
|
|
5384
5507
|
return;
|
|
5385
5508
|
}
|
|
5386
5509
|
if (intent.kind === "clear_confirm") {
|
|
5387
5510
|
const pending = this.takePendingChannelMemoryMutation(envelope, "clear");
|
|
5388
5511
|
if (!pending) {
|
|
5389
|
-
await this.
|
|
5512
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, 'No pending clear request. Say "\u6E05\u7A7A\u8BB0\u5FC6" first.');
|
|
5390
5513
|
return;
|
|
5391
5514
|
}
|
|
5392
5515
|
let result;
|
|
@@ -5395,13 +5518,13 @@ ${sanitizePromptText(entry.text).trim()}` : `No channel memory entry ${intent.id
|
|
|
5395
5518
|
} catch (error) {
|
|
5396
5519
|
const message = this.channelMemoryErrorMessage(error);
|
|
5397
5520
|
this.logChannelMemoryError("clear", envelope, message);
|
|
5398
|
-
await this.
|
|
5521
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Failed to clear channel memory: ${this.channelMemoryUserErrorMessage()}`);
|
|
5399
5522
|
return;
|
|
5400
5523
|
}
|
|
5401
5524
|
if (result.changed) {
|
|
5402
5525
|
this.invalidateUnattendedMemory(envelope);
|
|
5403
5526
|
}
|
|
5404
|
-
await this.
|
|
5527
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, result.changed ? "Channel memory cleared." : "No channel memory saved.");
|
|
5405
5528
|
return;
|
|
5406
5529
|
}
|
|
5407
5530
|
const unhandled = intent;
|
|
@@ -5430,7 +5553,7 @@ ${sanitizePromptText(entry.text).trim()}` : `No channel memory entry ${intent.id
|
|
|
5430
5553
|
const key = this.channelMemoryPendingKey(envelope);
|
|
5431
5554
|
this.pendingChannelMemoryMutationDeliveries.set(key, mutation);
|
|
5432
5555
|
try {
|
|
5433
|
-
await this.
|
|
5556
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, message);
|
|
5434
5557
|
} catch (error) {
|
|
5435
5558
|
if (this.pendingChannelMemoryMutationDeliveries.get(key) === mutation) {
|
|
5436
5559
|
this.pendingChannelMemoryMutationDeliveries.delete(key);
|
|
@@ -5584,15 +5707,17 @@ ${sanitizePromptText(entry.text).trim()}` : `No channel memory entry ${intent.id
|
|
|
5584
5707
|
* Whether the resolved session is SHARED across senders. `single` collapses
|
|
5585
5708
|
* the whole channel to one `__single__` session for EVERY sender — group OR
|
|
5586
5709
|
* DM — so it is ALWAYS shared (even a DM maps to `__single__`). `thread` is
|
|
5587
|
-
* shared only in a group (a DM maps to the lone caller's own chat).
|
|
5588
|
-
*
|
|
5589
|
-
*
|
|
5710
|
+
* shared only in a group (a DM maps to the lone caller's own chat).
|
|
5711
|
+
* `chat_thread` is always shared: it scopes by chat+thread, and a thread
|
|
5712
|
+
* (issue/PR discussion) can carry multiple participants even outside a
|
|
5713
|
+
* group. `user` is per-sender, never shared. Drives both the
|
|
5714
|
+
* destructive-/clear confirm gate and the host-shell (`!`) gate.
|
|
5590
5715
|
*/
|
|
5591
5716
|
isSharedSession(envelope) {
|
|
5592
5717
|
return this.isSharedSessionTarget(envelope);
|
|
5593
5718
|
}
|
|
5594
5719
|
isSharedSessionTarget(target) {
|
|
5595
|
-
return this.config.sessionScope === "single" || target.isGroup === true && this.config.sessionScope === "thread";
|
|
5720
|
+
return this.config.sessionScope === "single" || this.config.sessionScope === "chat_thread" || target.isGroup === true && this.config.sessionScope === "thread";
|
|
5596
5721
|
}
|
|
5597
5722
|
/**
|
|
5598
5723
|
* Whether `envelope.senderId` may act on the resolved session's destructive or
|
|
@@ -5849,7 +5974,7 @@ ${promptText}`;
|
|
|
5849
5974
|
if (!result.allowed) {
|
|
5850
5975
|
if (result.pairingCode !== void 0) {
|
|
5851
5976
|
this.logPreflightRejected("sender_pairing_required");
|
|
5852
|
-
return this.onPairingRequired(envelope.chatId, result.pairingCode).then(() => false).catch((err) => {
|
|
5977
|
+
return this.onPairingRequired(envelope.chatId, result.pairingCode, envelope.threadId).then(() => false).catch((err) => {
|
|
5853
5978
|
process.stderr.write(`[Channel:${this.name}] pairing notification failed: ${sanitizeLogText(err instanceof Error ? err.message : String(err), 200)}
|
|
5854
5979
|
`);
|
|
5855
5980
|
return false;
|
|
@@ -5962,11 +6087,11 @@ ${promptText}`;
|
|
|
5962
6087
|
`);
|
|
5963
6088
|
}
|
|
5964
6089
|
if (envelope.isGroup) {
|
|
5965
|
-
await this.
|
|
6090
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Shell commands (`!`) are disabled in group chats.");
|
|
5966
6091
|
return;
|
|
5967
6092
|
}
|
|
5968
6093
|
if (this.isSharedSession(envelope)) {
|
|
5969
|
-
await this.
|
|
6094
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Shell commands (`!`) are disabled in shared sessions.");
|
|
5970
6095
|
return;
|
|
5971
6096
|
}
|
|
5972
6097
|
}
|
|
@@ -5984,10 +6109,10 @@ ${result.output}
|
|
|
5984
6109
|
${fence}` : "(no output)";
|
|
5985
6110
|
const exitLine = result.exitCode !== null && result.exitCode !== 0 ? `
|
|
5986
6111
|
Exit code: ${result.exitCode}` : "";
|
|
5987
|
-
await this.
|
|
6112
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `$ ${cmd}
|
|
5988
6113
|
${output}${exitLine}`);
|
|
5989
6114
|
} catch (error) {
|
|
5990
|
-
await this.
|
|
6115
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Shell command failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
5991
6116
|
}
|
|
5992
6117
|
return;
|
|
5993
6118
|
}
|
|
@@ -6023,6 +6148,9 @@ ${promptText}`;
|
|
|
6023
6148
|
promptText = promptText + "\n\n" + filePaths.join("\n");
|
|
6024
6149
|
}
|
|
6025
6150
|
}
|
|
6151
|
+
if (envelope.metadata) {
|
|
6152
|
+
promptText = promptText + "\n\n" + sanitizePromptText(envelope.metadata);
|
|
6153
|
+
}
|
|
6026
6154
|
const groupCfg = envelope.isGroup ? this.config.groups[envelope.chatId] || this.config.groups["*"] : void 0;
|
|
6027
6155
|
const mode = groupCfg?.dispatchMode || this.config.dispatchMode || "steer";
|
|
6028
6156
|
const active = this.activePrompts.get(sessionId);
|
|
@@ -6300,6 +6428,7 @@ ${promptToSend}`;
|
|
|
6300
6428
|
// Clear attachments/references — already resolved in original text
|
|
6301
6429
|
referencedText: void 0,
|
|
6302
6430
|
attachments: void 0,
|
|
6431
|
+
metadata: void 0,
|
|
6303
6432
|
imageBase64: void 0,
|
|
6304
6433
|
imageMimeType: void 0
|
|
6305
6434
|
};
|
|
@@ -6315,14 +6444,14 @@ ${promptToSend}`;
|
|
|
6315
6444
|
}));
|
|
6316
6445
|
await current;
|
|
6317
6446
|
}
|
|
6318
|
-
async onPairingRequired(chatId, code) {
|
|
6447
|
+
async onPairingRequired(chatId, code, threadId) {
|
|
6319
6448
|
if (code) {
|
|
6320
|
-
await this.
|
|
6449
|
+
await this.sendThreadMessage(chatId, threadId, `Your pairing code is: ${code}
|
|
6321
6450
|
|
|
6322
6451
|
Ask the bot operator to approve you with:
|
|
6323
6452
|
qwen channel pairing approve ${this.name} ${code}`);
|
|
6324
6453
|
} else {
|
|
6325
|
-
await this.
|
|
6454
|
+
await this.sendThreadMessage(chatId, threadId, "Too many pending pairing requests. Please try again later.");
|
|
6326
6455
|
}
|
|
6327
6456
|
}
|
|
6328
6457
|
};
|
|
@@ -6535,9 +6664,114 @@ function isTerminalTaskLifecycleType(type) {
|
|
|
6535
6664
|
}
|
|
6536
6665
|
__name(isTerminalTaskLifecycleType, "isTerminalTaskLifecycleType");
|
|
6537
6666
|
|
|
6667
|
+
// packages/channels/base/dist/PollingChannelBase.js
|
|
6668
|
+
init_esbuild_shims();
|
|
6669
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
6670
|
+
import { mkdirSync as mkdirSync4, readFileSync as readFileSync4, renameSync as renameSync4, writeFileSync as writeFileSync4 } from "node:fs";
|
|
6671
|
+
import { join as join6 } from "node:path";
|
|
6672
|
+
import process3 from "node:process";
|
|
6673
|
+
var INITIAL_BACKOFF = 2e3;
|
|
6674
|
+
var MAX_BACKOFF = 3e4;
|
|
6675
|
+
var PollingChannelBase = class extends ChannelBase {
|
|
6676
|
+
static {
|
|
6677
|
+
__name(this, "PollingChannelBase");
|
|
6678
|
+
}
|
|
6679
|
+
cursor;
|
|
6680
|
+
abortController = new AbortController();
|
|
6681
|
+
running = false;
|
|
6682
|
+
consecutiveErrors = 0;
|
|
6683
|
+
abortableSleep(ms) {
|
|
6684
|
+
const signal = this.abortController.signal;
|
|
6685
|
+
return new Promise((resolve3) => {
|
|
6686
|
+
if (signal.aborted) {
|
|
6687
|
+
resolve3();
|
|
6688
|
+
return;
|
|
6689
|
+
}
|
|
6690
|
+
const timer = setTimeout(() => {
|
|
6691
|
+
signal.removeEventListener("abort", onAbort);
|
|
6692
|
+
resolve3();
|
|
6693
|
+
}, ms);
|
|
6694
|
+
const onAbort = /* @__PURE__ */ __name(() => {
|
|
6695
|
+
clearTimeout(timer);
|
|
6696
|
+
resolve3();
|
|
6697
|
+
}, "onAbort");
|
|
6698
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
6699
|
+
});
|
|
6700
|
+
}
|
|
6701
|
+
constructor(name, config, bridge, options) {
|
|
6702
|
+
super(name, config, bridge, options);
|
|
6703
|
+
this.cursor = this.loadCursorFromDisk() ?? this.createInitialCursor();
|
|
6704
|
+
}
|
|
6705
|
+
validateCursor(parsed) {
|
|
6706
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
6707
|
+
return null;
|
|
6708
|
+
return parsed;
|
|
6709
|
+
}
|
|
6710
|
+
get pollInterval() {
|
|
6711
|
+
const configured = this.config.pollInterval;
|
|
6712
|
+
if (typeof configured === "number" && Number.isFinite(configured) && configured > 0) {
|
|
6713
|
+
return configured;
|
|
6714
|
+
}
|
|
6715
|
+
return 6e4;
|
|
6716
|
+
}
|
|
6717
|
+
saveCursor() {
|
|
6718
|
+
const path4 = this.cursorPath();
|
|
6719
|
+
mkdirSync4(join6(getGlobalQwenDir(), "channels"), { recursive: true });
|
|
6720
|
+
const tmp = `${path4}.tmp`;
|
|
6721
|
+
writeFileSync4(tmp, JSON.stringify(this.cursor) + "\n", "utf-8");
|
|
6722
|
+
renameSync4(tmp, path4);
|
|
6723
|
+
}
|
|
6724
|
+
startPollLoop() {
|
|
6725
|
+
if (this.running)
|
|
6726
|
+
return;
|
|
6727
|
+
this.running = true;
|
|
6728
|
+
this.consecutiveErrors = 0;
|
|
6729
|
+
this.abortController = new AbortController();
|
|
6730
|
+
this.runLoop();
|
|
6731
|
+
}
|
|
6732
|
+
stopPollLoop() {
|
|
6733
|
+
this.running = false;
|
|
6734
|
+
this.abortController.abort();
|
|
6735
|
+
}
|
|
6736
|
+
async runLoop() {
|
|
6737
|
+
const signal = this.abortController.signal;
|
|
6738
|
+
while (this.running && !signal.aborted) {
|
|
6739
|
+
try {
|
|
6740
|
+
await this.pollOnce();
|
|
6741
|
+
this.saveCursor();
|
|
6742
|
+
this.consecutiveErrors = 0;
|
|
6743
|
+
} catch (err) {
|
|
6744
|
+
this.consecutiveErrors++;
|
|
6745
|
+
const backoff = Math.min(INITIAL_BACKOFF * 2 ** (this.consecutiveErrors - 1), MAX_BACKOFF);
|
|
6746
|
+
process3.stderr.write(`[Channel:${this.name}] poll error (attempt ${this.consecutiveErrors}), backing off ${backoff}ms: ${err}
|
|
6747
|
+
`);
|
|
6748
|
+
await this.abortableSleep(backoff);
|
|
6749
|
+
continue;
|
|
6750
|
+
}
|
|
6751
|
+
await this.abortableSleep(this.pollInterval);
|
|
6752
|
+
}
|
|
6753
|
+
}
|
|
6754
|
+
loadCursorFromDisk() {
|
|
6755
|
+
try {
|
|
6756
|
+
const raw = readFileSync4(this.cursorPath(), "utf-8").trim();
|
|
6757
|
+
if (!raw)
|
|
6758
|
+
return null;
|
|
6759
|
+
return this.validateCursor(JSON.parse(raw));
|
|
6760
|
+
} catch {
|
|
6761
|
+
return null;
|
|
6762
|
+
}
|
|
6763
|
+
}
|
|
6764
|
+
cursorPath() {
|
|
6765
|
+
const encoded = this.name.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 200);
|
|
6766
|
+
const hash = createHash2("sha256").update(this.name).digest("hex").slice(0, 16);
|
|
6767
|
+
return join6(getGlobalQwenDir(), "channels", `${encoded}-${hash}-poll-cursor.json`);
|
|
6768
|
+
}
|
|
6769
|
+
};
|
|
6770
|
+
|
|
6538
6771
|
export {
|
|
6539
6772
|
resolvePath,
|
|
6540
6773
|
getGlobalQwenDir,
|
|
6774
|
+
CHANNEL_LOOP_MCP_SERVER_NAME,
|
|
6541
6775
|
sanitizeSenderName,
|
|
6542
6776
|
sanitizePromptText,
|
|
6543
6777
|
sanitizeLogText,
|
|
@@ -6550,7 +6784,8 @@ export {
|
|
|
6550
6784
|
ChannelLoopScheduler,
|
|
6551
6785
|
ChannelBase,
|
|
6552
6786
|
ChannelLoopStore,
|
|
6553
|
-
isTerminalTaskLifecycleType
|
|
6787
|
+
isTerminalTaskLifecycleType,
|
|
6788
|
+
PollingChannelBase
|
|
6554
6789
|
};
|
|
6555
6790
|
/**
|
|
6556
6791
|
* @license
|