@qwen-code/qwen-code 0.22.3 → 0.23.0
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 +30 -0
- package/bundled/computer-use/SKILL.md +116 -180
- package/bundled/goal-draft/SKILL.md +5 -1
- package/bundled/qc-helper/docs/common-workflow.md +32 -0
- package/bundled/qc-helper/docs/configuration/auth.md +6 -6
- package/bundled/qc-helper/docs/configuration/model-providers.md +8 -2
- package/bundled/qc-helper/docs/configuration/settings.md +63 -58
- package/bundled/qc-helper/docs/extension/introduction.md +1 -1
- package/bundled/qc-helper/docs/features/_meta.ts +1 -0
- package/bundled/qc-helper/docs/features/approval-mode.md +3 -0
- package/bundled/qc-helper/docs/features/auto-mode.md +34 -17
- package/bundled/qc-helper/docs/features/channels/dingtalk.md +4 -2
- package/bundled/qc-helper/docs/features/channels/dws.md +6 -2
- package/bundled/qc-helper/docs/features/channels/overview.md +5 -2
- package/bundled/qc-helper/docs/features/code-review.md +2 -2
- package/bundled/qc-helper/docs/features/commands.md +79 -1
- package/bundled/qc-helper/docs/features/computer-use.md +2 -2
- package/bundled/qc-helper/docs/features/goals.md +9 -3
- package/bundled/qc-helper/docs/features/headless.md +16 -1
- package/bundled/qc-helper/docs/features/hooks.md +8 -3
- package/bundled/qc-helper/docs/features/memory.md +1 -0
- package/bundled/qc-helper/docs/features/output-styles.md +38 -0
- package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +17 -7
- package/bundled/qc-helper/docs/qwen-serve.md +74 -55
- package/bundled/review/SKILL.md +16 -7
- package/bundled/review/references/posting.md +3 -3
- package/chunks/MaxSizedBox-B3D7545A.js +111 -0
- package/chunks/{StandaloneSessionPicker-2FJAOLGG.js → StandaloneSessionPicker-QUMO4LLQ.js} +88 -86
- package/chunks/{acp-startup-profiler-GNYAL6LI.js → acp-startup-profiler-M4X5F3VK.js} +2 -2
- package/chunks/{acpAgent-2ZMIJAFV.js → acpAgent-2GTFCIEP.js} +2041 -444
- package/chunks/{agent-X5WX3L2I.js → agent-XKF5SZWU.js} +46 -46
- package/chunks/agent-headless-OC2IB55D.js +85 -0
- package/chunks/{anthropicContentGenerator-YVTB6QX7.js → anthropicContentGenerator-L76MR5OR.js} +53 -20
- package/chunks/{artifact-tool-XSMPHZBT.js → artifact-tool-MYCL2QCS.js} +3 -4
- package/chunks/{askUserQuestion-4SWJY65V.js → askUserQuestion-THQZMG44.js} +45 -7
- package/chunks/bridge-IHSBI2YJ.js +118 -0
- package/chunks/{build-INBK7IXX.js → build-63BIOYWK.js} +1 -1
- package/chunks/{ca-7HPYOYSZ.js → ca-BNU7YNDE.js} +3 -0
- package/chunks/{channel-management-service-HQ6KDS7C.js → channel-management-service-4MTCEGJB.js} +4 -4
- package/chunks/channel-settings-store-BVKWAI2T.js +121 -0
- package/chunks/{channel-worker-group-6NA6BBZV.js → channel-worker-group-47F4ISUZ.js} +7 -7
- package/chunks/{channel-worker-manager-NEZ2J6RK.js → channel-worker-manager-I5Y44GYR.js} +51 -10
- package/chunks/{channel-worker-supervisor-FKU7DIHJ.js → channel-worker-supervisor-6VCLUXFE.js} +4 -4
- package/chunks/{chunk-PPKZ7JOE.js → chunk-22UH7VTP.js} +1 -1
- package/chunks/chunk-24FVUD5P.js +49 -0
- package/chunks/{chunk-MZCJWS5Y.js → chunk-2M3EWQNG.js} +20 -0
- package/chunks/{chunk-7T52W4SW.js → chunk-32LU3APX.js} +1 -1
- package/chunks/{chunk-42IDLQWS.js → chunk-373DQUVA.js} +48 -13
- package/chunks/{chunk-MSBO7X2W.js → chunk-37JFWFCD.js} +1 -1
- package/chunks/{chunk-3JXM2CVW.js → chunk-3AKCBZVW.js} +3 -3
- package/chunks/{chunk-TVC6HQ2U.js → chunk-3JQZVCBI.js} +2 -2
- package/chunks/{chunk-2LNNVAUV.js → chunk-3L724BJ5.js} +246 -15
- package/chunks/{chunk-E7REAOTN.js → chunk-47ECGEJC.js} +4 -0
- package/chunks/{chunk-WNPDGUJO.js → chunk-47RYEQW5.js} +2 -3
- package/chunks/{chunk-TZBSGJ6C.js → chunk-4BGDFKQE.js} +7 -7
- package/chunks/{chunk-PZ66FRIC.js → chunk-4F7GQGXB.js} +11772 -4773
- package/chunks/{chunk-DMLVSW7L.js → chunk-4HVH57J3.js} +713 -9
- package/chunks/{chunk-CMHFCLBU.js → chunk-4LIFGNI4.js} +1 -1
- package/chunks/{chunk-3SZC4VP4.js → chunk-4M24B5J5.js} +88 -49
- package/chunks/{chunk-BOWFGCEU.js → chunk-4PSDSCW3.js} +3 -3
- package/chunks/chunk-4UANMABT.js +1026 -0
- package/chunks/{chunk-M3QRM3DE.js → chunk-54C6PIGT.js} +5 -5
- package/chunks/{chunk-HP5LR5HL.js → chunk-5EIOJGCR.js} +4 -4
- package/chunks/{chunk-64REQJJ2.js → chunk-5H5S4UY5.js} +3 -3
- package/chunks/chunk-5IENVM7Z.js +35 -0
- package/chunks/{chunk-I6LYRJPB.js → chunk-5Q5RC2WE.js} +2 -2
- package/chunks/{chunk-WGY3AVGM.js → chunk-5RTTI4GE.js} +79 -5
- package/chunks/{chunk-KID24ZFN.js → chunk-64QH2UC6.js} +13 -1
- package/chunks/{chunk-MF7HCQWZ.js → chunk-65HWLGA7.js} +3 -3
- package/chunks/{chunk-OU5APVWO.js → chunk-6A2D4QSO.js} +13 -7
- package/chunks/chunk-6HUXPLB5.js +110 -0
- package/chunks/{chunk-VQUGEVGR.js → chunk-7IKXTGZT.js} +1 -1
- package/chunks/{chunk-UTLCH2FK.js → chunk-7JMGTOH7.js} +437 -136
- package/chunks/{chunk-7LOELM2I.js → chunk-7RB56BRJ.js} +3 -3
- package/chunks/{chunk-NIFYWDYN.js → chunk-7TBU7PU2.js} +1 -1
- package/chunks/{chunk-V2NDP3I4.js → chunk-7XL4WRXM.js} +2 -2
- package/chunks/chunk-ADJD4LZF.js +210 -0
- package/chunks/{chunk-T7KMERIX.js → chunk-ADYN7P2Y.js} +2 -2
- package/chunks/{chunk-TPI7O7HR.js → chunk-AHYTURFB.js} +1 -1
- package/chunks/{chunk-LUEHOUHM.js → chunk-AI35S34R.js} +3 -3
- package/chunks/{chunk-CIZCL2MW.js → chunk-ALUYNJPM.js} +1486 -2172
- package/chunks/{chunk-ABS25QER.js → chunk-ANVG3BVV.js} +1 -1
- package/chunks/{chunk-6ZPDLGHN.js → chunk-AZJLY2XZ.js} +5 -5
- package/chunks/{chunk-A3LWD5MK.js → chunk-BA4WJC4L.js} +1 -1
- package/chunks/{chunk-W3JH33JE.js → chunk-BFY33IB4.js} +18 -10
- package/chunks/{chunk-N4X7G4J2.js → chunk-BHTYRHJF.js} +1 -1
- package/chunks/{chunk-TEBDFQBZ.js → chunk-BJXCYUGM.js} +11 -6
- package/chunks/{chunk-7VMIMAVB.js → chunk-C2VWOXHS.js} +8 -8
- package/chunks/{chunk-XHF7WQ6B.js → chunk-C4TIXFDZ.js} +16 -5
- package/chunks/chunk-CHEIIBT3.js +40 -0
- package/chunks/chunk-CVX63TFJ.js +348 -0
- package/chunks/{chunk-RXFQM6FQ.js → chunk-DMEUXLSS.js} +16 -1
- package/chunks/{chunk-EKSCLBBF.js → chunk-DQCKVAF5.js} +23 -5
- package/chunks/{chunk-734C6JGI.js → chunk-DSX7KQPM.js} +5195 -666
- package/chunks/{chunk-4CMJKUND.js → chunk-DTVQSSNM.js} +67 -2
- package/chunks/{chunk-BKWNKLZB.js → chunk-DYTW3QVG.js} +24 -9
- package/chunks/{chunk-C2X7KY45.js → chunk-E4JNFXNI.js} +3 -3
- package/chunks/{chunk-UHQFIS7N.js → chunk-EAHOJF6V.js} +28 -4
- package/chunks/{chunk-YLSQLSH7.js → chunk-EBDGRBZX.js} +24 -16
- package/chunks/{chunk-DJBQCO2E.js → chunk-EFTPIZIC.js} +412 -3
- package/chunks/{chunk-6DIGWMGT.js → chunk-EIJT2PQ6.js} +2 -2
- package/chunks/{chunk-4TT3IVGA.js → chunk-EIY7SUPZ.js} +1 -1
- package/chunks/{chunk-XQFT3QUF.js → chunk-ENYUKMFK.js} +1 -1
- package/chunks/{chunk-ZWJDJ6RU.js → chunk-EVFDRBUM.js} +157 -153
- package/chunks/{chunk-4VPCTGH6.js → chunk-EWRW2WQC.js} +15 -9
- package/chunks/{chunk-VBCPNIQD.js → chunk-F33GFWPR.js} +47 -184
- package/chunks/{chunk-ERFDKH32.js → chunk-F47DITLZ.js} +19 -8
- package/chunks/{chunk-73RM4POK.js → chunk-F7NF2IOE.js} +7 -7
- package/chunks/{chunk-EB6QRGHM.js → chunk-FD5SJOWT.js} +10 -7
- package/chunks/{chunk-SS5SDCD3.js → chunk-FRICLXCZ.js} +7 -7
- package/chunks/{chunk-NU7RKEZR.js → chunk-FUO5V5KI.js} +14 -7
- package/chunks/{chunk-G6FECKTJ.js → chunk-G5PBOQWI.js} +9 -6
- package/chunks/{chunk-CAJTKR6W.js → chunk-G7HBEEX7.js} +15 -9
- package/chunks/{chunk-4QHPPXK2.js → chunk-GB4UKWY5.js} +2 -2
- package/chunks/{chunk-QYMAKPY5.js → chunk-GH2S4GD5.js} +350 -12
- package/chunks/{chunk-LHBUKJG2.js → chunk-GXUTFQXK.js} +28 -25
- package/chunks/{chunk-KJO2LBUK.js → chunk-H43PSPYS.js} +5 -5
- package/chunks/{chunk-XSG6G3G6.js → chunk-HJBHMANB.js} +12 -14
- package/chunks/chunk-HRPFBHW7.js +336 -0
- package/chunks/{chunk-6PJOTWAN.js → chunk-HT5S5TRQ.js} +1 -1
- package/chunks/{chunk-HCOBAG2L.js → chunk-HWVUSYSN.js} +3 -8
- package/chunks/{chunk-2OUD5T67.js → chunk-I2TMJPCV.js} +213 -185
- package/chunks/{chunk-CLWO3B77.js → chunk-I4NRYS6A.js} +11 -11
- package/chunks/{chunk-V7EESTJV.js → chunk-I5N4EAS6.js} +1 -1
- package/chunks/{chunk-K5KXUXWC.js → chunk-IG4W5SJR.js} +3 -3
- package/chunks/{chunk-FROAFEFB.js → chunk-IPATA3T2.js} +3 -3
- package/chunks/{chunk-NKLP3DCK.js → chunk-IQAFKVXS.js} +1 -1
- package/chunks/{chunk-AYHQZBJ4.js → chunk-IRKQ4YYX.js} +3 -3
- package/chunks/{chunk-J3NNHTV6.js → chunk-J5TTWBZK.js} +6 -0
- package/chunks/{chunk-QFCDF5PL.js → chunk-JHN7UIDW.js} +1 -1
- package/chunks/{chunk-AVNATYLY.js → chunk-JJKNYRFY.js} +1 -1
- package/chunks/{chunk-CQH5KTKC.js → chunk-JR42V4UY.js} +1 -1
- package/chunks/chunk-JS73NNWF.js +30 -0
- package/chunks/{chunk-NV55WWD6.js → chunk-JUARRUMA.js} +802 -2011
- package/chunks/chunk-JX6XHPTX.js +26 -0
- package/chunks/{chunk-5JTIYALA.js → chunk-JZWOCUZ3.js} +1 -1
- package/chunks/{chunk-P2G476QN.js → chunk-KEVYJSI4.js} +13 -13
- package/chunks/{chunk-B466ZSHZ.js → chunk-KFN2IZYR.js} +3 -3
- package/chunks/{chunk-JWALNCLT.js → chunk-KGV55H53.js} +1 -1
- package/chunks/{chunk-23RFD54N.js → chunk-KHP66DFN.js} +1 -1
- package/chunks/{chunk-2SXSLSQE.js → chunk-KM3XVTMO.js} +12 -6
- package/chunks/{chunk-GPGU4S2N.js → chunk-KMU3ZHH4.js} +3 -3
- package/chunks/chunk-KOGW3YWJ.js +2054 -0
- package/chunks/{chunk-NMOD2FXQ.js → chunk-L26ONV2Y.js} +8 -8
- package/chunks/chunk-L34XSHIZ.js +28 -0
- package/chunks/{chunk-SEONHUS3.js → chunk-LAUEEBDL.js} +2 -0
- package/chunks/{chunk-3WK3QDNV.js → chunk-LB3WQQJK.js} +2 -2
- package/chunks/{chunk-URE3QBBB.js → chunk-LEPCWS5A.js} +3 -3
- package/chunks/{chunk-36GSQ3MM.js → chunk-LHBNR6EU.js} +2 -2
- package/chunks/{chunk-V4264FEG.js → chunk-LKODFJRD.js} +1 -1
- package/chunks/{chunk-PADPMMYM.js → chunk-LOBDDFYK.js} +5 -29
- package/chunks/{chunk-BXDAPVQU.js → chunk-LU77UT4D.js} +28 -4
- package/chunks/{chunk-RFIDDFAL.js → chunk-M4KFODIP.js} +1 -1
- package/chunks/{chunk-CFJY4DGX.js → chunk-M4LBBSVP.js} +4 -2
- package/chunks/{chunk-KYWTPLBJ.js → chunk-MOF6VZN2.js} +2 -2
- package/chunks/{chunk-DJPASAUV.js → chunk-MP6YZ4RK.js} +4829 -3638
- package/chunks/{chunk-T26EAKDL.js → chunk-N2TNM3QB.js} +2 -6
- package/chunks/{chunk-2TNL5KPM.js → chunk-N4QWUPDM.js} +7 -0
- package/chunks/{chunk-7S226YTK.js → chunk-NFIDVZND.js} +11 -1
- package/chunks/{chunk-ZEYFMJQA.js → chunk-NQ4L2CMD.js} +83 -18
- package/chunks/{chunk-ZZUKP7HV.js → chunk-NRL5CUZT.js} +1 -1
- package/chunks/{chunk-WXEA74YB.js → chunk-NSUKQ4DN.js} +9 -3
- package/chunks/chunk-NUHOLAQ6.js +59 -0
- package/chunks/{chunk-DJEZ55D4.js → chunk-NVVJTUSL.js} +336 -140
- package/chunks/{chunk-3XKLXHGK.js → chunk-NXKOVOM5.js} +9 -9
- package/chunks/{chunk-5Q372OFJ.js → chunk-O4KNCAX4.js} +57 -10
- package/chunks/{chunk-GOXKNSDZ.js → chunk-O5CD7T4T.js} +40 -9
- package/chunks/{chunk-XIQ5HQ2F.js → chunk-OBTWL6ZW.js} +1 -1
- package/chunks/{chunk-PDQGMSZK.js → chunk-ODZF64DM.js} +1 -1
- package/chunks/{chunk-5MK45KZ3.js → chunk-OHOO527W.js} +1 -1
- package/chunks/{chunk-36LGBEM6.js → chunk-OHU2H5CS.js} +1 -1
- package/chunks/{chunk-JB4JIVTJ.js → chunk-OKTNXDVO.js} +1 -1
- package/chunks/{chunk-CETB5XY4.js → chunk-ORFIYTI2.js} +1 -1
- package/chunks/{chunk-7E7UCJHS.js → chunk-OSHQMOBS.js} +18 -17
- package/chunks/chunk-OSSTATJF.js +1310 -0
- package/chunks/chunk-P6UIF2OW.js +400 -0
- package/chunks/{chunk-U54AYGEC.js → chunk-PB7JBAHF.js} +15 -49
- package/chunks/{chunk-Y5S7LBOZ.js → chunk-PCRBLMIN.js} +17 -3
- package/chunks/{chunk-WAOIHTJS.js → chunk-PDAKFU7M.js} +1 -1
- package/chunks/{chunk-YTDVNSUQ.js → chunk-QAK5475D.js} +1 -1
- package/chunks/{chunk-ST5MDGH3.js → chunk-QI27MKNQ.js} +27 -19
- package/chunks/{chunk-MK2GIB46.js → chunk-QJGYU5PG.js} +1 -1
- package/chunks/{chunk-SMPR7SPO.js → chunk-QJNDUTOL.js} +45 -239
- package/chunks/{chunk-MQM5PJML.js → chunk-QJVZLILI.js} +1 -1
- package/chunks/{chunk-B5PHIJGI.js → chunk-QKDNS6FU.js} +2 -2
- package/chunks/{chunk-ZU4UDIWX.js → chunk-QQD2GART.js} +15 -9
- package/chunks/{chunk-62GQFYID.js → chunk-RAFQIHN2.js} +3 -3
- package/chunks/{chunk-MO3FC2WT.js → chunk-RJUVTJEZ.js} +1 -1
- package/chunks/{chunk-M6FOJXW3.js → chunk-RKW36UWC.js} +1 -1
- package/chunks/{chunk-GBJBJ4HX.js → chunk-RM4WT2XB.js} +4 -26
- package/chunks/{chunk-VGIFXISB.js → chunk-RN3YGDCA.js} +7 -5
- package/chunks/{chunk-DYXFD5RO.js → chunk-S2T7H5MI.js} +1 -1
- package/chunks/{chunk-FTF2YIZ5.js → chunk-S6H3ELPG.js} +1 -1
- package/chunks/{chunk-4NDLQAY2.js → chunk-SI7WDR3U.js} +524 -16
- package/chunks/{chunk-2YOHKHYR.js → chunk-SRF4KTAG.js} +6 -6
- package/chunks/{chunk-ZZMSC3RG.js → chunk-STCVJXQB.js} +24 -24
- package/chunks/{chunk-ST5V3ZOC.js → chunk-SULZPKTA.js} +3 -3
- package/chunks/{chunk-6X7EU5TI.js → chunk-SX2QIMJV.js} +9 -7
- package/chunks/{chunk-V5J4J5TP.js → chunk-TJYRTS4S.js} +2 -20
- package/chunks/{chunk-C3PEFRKD.js → chunk-TMKTOTMQ.js} +5 -5
- package/chunks/{chunk-ISKH4QX3.js → chunk-TQHPVKO6.js} +4 -4
- package/chunks/{chunk-HVC3PNVC.js → chunk-TSZSGQ3N.js} +1 -1
- package/chunks/{chunk-ICURCKIU.js → chunk-U4DJ5XB3.js} +594 -91
- package/chunks/{chunk-TTX2JUE6.js → chunk-U6D2PPMN.js} +1 -1
- package/chunks/{chunk-GVIVASYK.js → chunk-UAKRDON5.js} +4 -4
- package/chunks/{chunk-D5LUXLUH.js → chunk-UJ4DUYIH.js} +18 -4
- package/chunks/{chunk-VTHREBQM.js → chunk-UKYXYWI2.js} +2 -2
- package/chunks/{chunk-ZYMLPEZQ.js → chunk-UM2FFKXN.js} +3 -3
- package/chunks/{chunk-2OBKDPZZ.js → chunk-UPFRILIL.js} +2 -2
- package/chunks/{chunk-2HYKTO7V.js → chunk-UUASLXHW.js} +55 -6
- package/chunks/chunk-V5U2NZNJ.js +29 -0
- package/chunks/{chunk-P5Y23G2L.js → chunk-V7RNNPGC.js} +1 -18
- package/chunks/{chunk-Q2MSPKIJ.js → chunk-VBWD6C27.js} +1 -1
- package/chunks/chunk-VGHZT6JR.js +51 -0
- package/chunks/{chunk-MPNBVAEU.js → chunk-VNAYZAFX.js} +4 -4
- package/chunks/chunk-VPSIC437.js +780 -0
- package/chunks/{chunk-AIAOIFY4.js → chunk-VWTSRH6C.js} +92 -17
- package/chunks/{chunk-4K7KNVWH.js → chunk-VYIUNFEA.js} +3 -3
- package/chunks/{chunk-EQSBPBZ3.js → chunk-WP4AX3XD.js} +5 -7
- package/chunks/{chunk-BFPESSTR.js → chunk-XEAAO654.js} +1 -1
- package/chunks/{chunk-RU7BK6B3.js → chunk-XLXAZLDR.js} +3 -3
- package/chunks/{chunk-EFWRMA2I.js → chunk-YPWZTR7F.js} +3 -3
- package/chunks/{chunk-XF63PKEN.js → chunk-ZDFQGHZH.js} +1 -1
- package/chunks/{chunk-OZ6KS6KW.js → chunk-ZGCKTAL5.js} +6 -1
- package/chunks/chunk-ZHO2CW6D.js +205 -0
- package/chunks/chunk-ZJ2LM2SI.js +198 -0
- package/chunks/{chunk-AYFA7MZV.js → chunk-ZKFTS3OV.js} +6 -6
- package/chunks/{chunk-HMJ2P3SV.js → chunk-ZL4HFSL6.js} +91 -29
- package/chunks/{chunk-DJECZIJX.js → chunk-ZTPGUFQV.js} +30 -8
- package/chunks/{chunk-7EQQR46F.js → chunk-ZVP4PWBU.js} +1 -1
- package/chunks/chunk-bdqvmfwv-ZTSOWAFE.js +17446 -0
- package/chunks/config-utils-LVSYDLHZ.js +114 -0
- package/chunks/contextCommand-TZD7UAJK.js +107 -0
- package/chunks/{core-runtime-AXB6SK5D.js → core-runtime-B4UKKIAQ.js} +63 -62
- package/chunks/{create-sub-session-23ITIELI.js → create-sub-session-LUPWEUHR.js} +3 -3
- package/chunks/{create-sub-session-4QNE64MR.js → create-sub-session-NJ24B4US.js} +94 -66
- package/chunks/{cron-create-KJ4IY6PP.js → cron-create-CRSPET3H.js} +4 -4
- package/chunks/{cron-delete-MBLQCAYY.js → cron-delete-DB77SZTU.js} +4 -4
- package/chunks/{cron-list-DWH2PQ47.js → cron-list-U2JNYWV6.js} +4 -4
- package/chunks/{daemon-3GNHB3M2.js → daemon-RKDGBFLK.js} +613 -102
- package/chunks/{daemon-git-worktree-guard-IVAJJWYK.js → daemon-git-worktree-guard-O2HPOBAB.js} +62 -61
- package/chunks/daemon-status-provider-GRRVCJFW.js +117 -0
- package/chunks/daemon-trust-policy-YJL442BK.js +113 -0
- package/chunks/{daemon-trust-policy-monitor-KGGROSIV.js → daemon-trust-policy-monitor-JL7F4Y4Q.js} +68 -67
- package/chunks/{de-X6HLSIFE.js → de-T4BLOKEC.js} +3 -0
- package/chunks/deferred-core-runtime-S32AYVZI.js +115 -0
- package/chunks/{devtools-JCG4K2NZ.js → devtools-VDRJYPZF.js} +1 -1
- package/chunks/{discovery-X2NV535U.js → discovery-TUM3ZQ6U.js} +2 -2
- package/chunks/{display-image-BE7I6ZB6.js → display-image-73C7XNRK.js} +5 -5
- package/chunks/{dist-LVZCXVPF.js → dist-62OZ7QXB.js} +44 -26
- package/chunks/{dist-GFN5DCBX.js → dist-EDHQIBYD.js} +152 -63
- package/chunks/{dist-N6W6E753.js → dist-GT64AAUR.js} +135 -26
- package/chunks/{dist-6BPYWHVD.js → dist-JVXT4VUJ.js} +14 -7
- package/chunks/{dist-4WXLCBDR.js → dist-L6URO6CK.js} +12 -5
- package/chunks/{dist-5VXFRTWU.js → dist-LXFYIJNG.js} +866 -172
- package/chunks/{dist-SWQMYP2Q.js → dist-PDGNRVPY.js} +27 -8
- package/chunks/{dist-NSV4NBPK.js → dist-QAF5DO3Y.js} +380 -83
- package/chunks/{dist-HZNT6GQS.js → dist-ZCJLKQSP.js} +28 -14
- package/chunks/earlyInputCapture-BBPCIVZG.js +108 -0
- package/chunks/{edit-LEQLAGPZ.js → edit-SUGXY63Y.js} +47 -47
- package/chunks/{en-YLXBXM4Z.js → en-2RATMNX7.js} +5 -0
- package/chunks/{enter-worktree-35QCAAFP.js → enter-worktree-B6USKSIK.js} +7 -7
- package/chunks/{enterPlanMode-ONQN3WHE.js → enterPlanMode-MDX4RVVL.js} +48 -48
- package/chunks/{environment-UANTR7A4.js → environment-VN6RXDVN.js} +63 -62
- package/chunks/errors-UEY36PIT.js +114 -0
- package/chunks/{exit-worktree-XQD6D543.js → exit-worktree-DLQ73SJH.js} +10 -8
- package/chunks/exitPlanMode-EPHIEDAA.js +83 -0
- package/chunks/{fast-path-WUL7UZ6H.js → fast-path-Y73R42LV.js} +8 -7
- package/chunks/{fast-path-settings-XH426LUU.js → fast-path-settings-MFUR3IWK.js} +3 -3
- package/chunks/{fr-FTZWF462.js → fr-BGHGYX6A.js} +3 -0
- package/chunks/{glob-Y54QUWDY.js → glob-DMGH7EZN.js} +47 -47
- package/chunks/goal-tools-3RF3PXCL.js +99 -0
- package/chunks/{grep-5GPICQBU.js → grep-AJVLCVXC.js} +9 -7
- package/chunks/handleAutoUpdate-HVWQT2AU.js +110 -0
- package/chunks/i18n-5OR7NTRZ.js +125 -0
- package/chunks/{image-gen-J6FDGUZP.js → image-gen-VOIDOHOB.js} +8 -8
- package/chunks/initializer-JE5RQSOE.js +114 -0
- package/chunks/installationInfo-KO3CCSCK.js +108 -0
- package/chunks/{ja-2GL5FKYJ.js → ja-G3FTD5XE.js} +3 -0
- package/chunks/{keychain-token-storage-37XPR34V.js → keychain-token-storage-REZVMJA6.js} +2 -2
- package/chunks/list-3IORSFIY.js +117 -0
- package/chunks/list-agents-SBMONIUK.js +128 -0
- package/chunks/{llm-NSAVK5V3.js → llm-K26SUDVK.js} +223 -140
- package/chunks/{llm-content-generator-AY2QKXHE.js → llm-content-generator-TT6EAUD4.js} +11 -12
- package/chunks/loadedSettingsAdapter-KLLFZF3M.js +111 -0
- package/chunks/{loggingContentGenerator-DSFQHXIF.js → loggingContentGenerator-EYQBA4M4.js} +66 -65
- package/chunks/{loop-wakeup-XJFONSQ7.js → loop-wakeup-QA6SHCZT.js} +5 -5
- package/chunks/{ls-3VAT2J7A.js → ls-HEJNCEYO.js} +4 -4
- package/chunks/{lsp-5W7IRUBH.js → lsp-WOQKNZP6.js} +2 -2
- package/chunks/{managed-npm-update-TSWENTK5.js → managed-npm-update-HIJTODQT.js} +61 -60
- package/chunks/mcp-A2UEHETW.js +111 -0
- package/chunks/{monitor-RW4GWJHB.js → monitor-DKNZQAB2.js} +46 -46
- package/chunks/{node-QKLNSZMX.js → node-UETAYMMO.js} +3 -3
- package/chunks/nonInteractiveCli-YA47F2F4.js +190 -0
- package/chunks/{notebook-edit-CQNYS5OR.js → notebook-edit-MGHTRL2D.js} +47 -47
- package/chunks/{open-with-auth-YN3QZHVM.js → open-with-auth-D6JD6LDS.js} +3 -3
- package/chunks/{openaiContentGenerator-J6QIF7EX.js → openaiContentGenerator-ZJIEQ3ZJ.js} +26 -28
- package/chunks/pidfile-ETHAZNMY.js +112 -0
- package/chunks/{processUtils-GPHNANKZ.js → processUtils-UY3SAJJZ.js} +2 -2
- package/chunks/prompt-terminal-ledger-GZ747VYE.js +106 -0
- package/chunks/{pt-XN2YWJVM.js → pt-D73IFYT7.js} +3 -0
- package/chunks/{qwenContentGenerator-WWDXPYQI.js → qwenContentGenerator-VI4KATRY.js} +58 -58
- package/chunks/{qwenOAuth2-OF5WRBQT.js → qwenOAuth2-7AOCKSOQ.js} +7 -7
- package/chunks/{read-file-FQUQHC6N.js → read-file-P7F4P7LV.js} +11 -13
- package/chunks/{read-mcp-resource-XD257PGJ.js → read-mcp-resource-GLAGB6R7.js} +2 -2
- package/chunks/{record-artifact-VW23GS4F.js → record-artifact-SWVR7NSU.js} +4 -4
- package/chunks/renderer-selection-M4UN63VJ.js +99 -0
- package/chunks/{report-findings-AO5VYFLR.js → report-findings-AL5YW3KI.js} +5 -5
- package/chunks/{request-shutdown-BCLA3JV2.js → request-shutdown-5YK4IZ54.js} +8 -7
- package/chunks/resumeHistoryUtils-DPZKFW24.js +119 -0
- package/chunks/ripGrep-C7LJKUPZ.js +37 -0
- package/chunks/{ru-OLTMFJEW.js → ru-QMISLKRH.js} +3 -0
- package/chunks/{run-qwen-serve-5X6IDZER.js → run-qwen-serve-OGTEEUR2.js} +589 -251
- package/chunks/{runtime-HK27GMPF.js → runtime-LNBLEMZS.js} +73 -72
- package/chunks/scheduled-tasks-FLDYZQOF.js +128 -0
- package/chunks/{scheduler-WD4MHMO5.js → scheduler-73YXGUGW.js} +62 -61
- package/chunks/{sdk-exporters-grpc-G5IT4XS4.js → sdk-exporters-grpc-MXTVSE3C.js} +2 -2
- package/chunks/{sdk-exporters-http-TTU2CHBU.js → sdk-exporters-http-3JO5TJNU.js} +4 -4
- package/chunks/{sdk-impl-UUMVYMAL.js → sdk-impl-HZAUUTHJ.js} +6 -6
- package/chunks/{send-message-AJ4OCUBV.js → send-message-JC7NJTY6.js} +166 -35
- package/chunks/serve-3UR2H4CV.js +119 -0
- package/chunks/{server-GO2N5DH7.js → server-AOYZVVOM.js} +2904 -860
- package/chunks/{session-IFNHTUBT.js → session-UAWFNFGI.js} +119 -114
- package/chunks/session-attachments-root-ZCGXQQTR.js +104 -0
- package/chunks/{session-pr-refresh-I3UBWMVP.js → session-pr-refresh-CT2INROL.js} +157 -88
- package/chunks/{settings-L6N54CU6.js → settings-BHRGDASJ.js} +67 -66
- package/chunks/{shell-4Y5LLW6N.js → shell-YHOGC7TO.js} +46 -46
- package/chunks/{skill-YOWTRAKQ.js → skill-ZGBKNCHQ.js} +131 -97
- package/chunks/skill-settings-AKSP665O.js +119 -0
- package/chunks/spawnChannel-N25MBB6F.js +112 -0
- package/chunks/standalone-update-XGPWJDRN.js +119 -0
- package/chunks/start-opentui-ui-FZ4USOU7.js +55342 -0
- package/chunks/{startInteractiveUI-XDFSHBZD.js → startInteractiveUI-E2WQJUOA.js} +3509 -4706
- package/chunks/{syntheticOutput-ML43GEFN.js → syntheticOutput-HJNZSEHN.js} +3 -3
- package/chunks/{task-create-QN4LYRSE.js → task-create-6RSD54S5.js} +12 -12
- package/chunks/{task-list-JPLGK45U.js → task-list-IQSACPOM.js} +34 -11
- package/chunks/{task-stop-CXEH5L2D.js → task-stop-HE2LRQNW.js} +2 -2
- package/chunks/{task-update-IWEOJFV2.js → task-update-XAJ2NYOA.js} +13 -14
- package/chunks/{team-create-OOPXCDBA.js → team-create-SOKMYSQU.js} +54 -55
- package/chunks/{team-delete-RZVVSGCY.js → team-delete-NGNNKGMG.js} +25 -8
- package/chunks/{team-plan-approval-DSX5EWAT.js → team-plan-approval-U7ZWXYAY.js} +46 -46
- package/chunks/terminal-image-renderer-KKM4OBLO.js +117 -0
- package/chunks/theme-manager-GQHF3A7T.js +103 -0
- package/chunks/{todoWrite-WDJNQEMW.js → todoWrite-5UTVUXHA.js} +39 -9
- package/chunks/{tool-search-J5Q6U7DN.js → tool-search-IAI2RVWT.js} +21 -19
- package/chunks/total-session-admission-G4CGCSTG.js +113 -0
- package/chunks/trustedFolders-D2I3FDPB.js +123 -0
- package/chunks/{update-relaunch-SIKHLHVR.js → update-relaunch-5RWKZAL3.js} +5 -5
- package/chunks/updateCheck-ZXOQDFEI.js +119 -0
- package/chunks/useAutoAcceptIndicator-6EK4QGAH.js +121 -0
- package/chunks/{validateNonInterActiveAuth-JUDQP6V4.js → validateNonInterActiveAuth-QPFEKATS.js} +113 -109
- package/chunks/{version-C63GDDWN.js → version-JKNG7YDH.js} +1 -1
- package/chunks/{web-fetch-FOQZMNSC.js → web-fetch-X3AHIIHW.js} +16 -19
- package/chunks/{web-search-PUJTBFUC.js → web-search-K2FMOGS5.js} +10 -11
- package/chunks/{web-shell-static-HNB4FDOE.js → web-shell-static-POZHGGXE.js} +5 -4
- package/chunks/{workflow-Y5IPINVH.js → workflow-TOLPAK5G.js} +213 -119
- package/chunks/workspace-providers-status-PCJK3RC7.js +115 -0
- package/chunks/{workspace-registration-store-SMJWI2AI.js → workspace-registration-store-KQWVVW4Y.js} +2 -1
- package/chunks/workspace-registry-YNIOB6HJ.js +122 -0
- package/chunks/workspace-runtime-coordinator-WG2RNEN7.js +123 -0
- package/chunks/workspace-service-G4ZNBOFH.js +127 -0
- package/chunks/workspace-skills-status-FMTPPMWC.js +114 -0
- package/chunks/{workspace-trust-reconciler-PLIDLJZX.js → workspace-trust-reconciler-IBDFQBQS.js} +76 -77
- package/chunks/wrapper-JH3IFHT2.js +35 -0
- package/chunks/write-file-YTLFY2S5.js +88 -0
- package/chunks/{zh-UNY63FR3.js → zh-25DF7OGK.js} +5 -0
- package/chunks/{zh-TW-RPTMRTHG.js → zh-TW-5EDMZVGK.js} +5 -0
- package/chunks/{zoom-image-LYQD7BQA.js → zoom-image-IFXSN74N.js} +11 -13
- package/cli.js +131 -90
- package/locales/ca.js +6 -0
- package/locales/de.js +6 -0
- package/locales/en.js +9 -0
- package/locales/fr.js +6 -0
- package/locales/ja.js +6 -0
- package/locales/pt.js +6 -0
- package/locales/ru.js +6 -0
- package/locales/zh-TW.js +9 -0
- package/locales/zh.js +9 -0
- package/package.json +3 -3
- package/web-shell/assets/{abnfDiagram-VCTEODGH-TRCMSA_6.js → abnfDiagram-VCTEODGH-Cxf7xE_Z.js} +1 -1
- package/web-shell/assets/{arc-D9Uls5b3.js → arc-ESi1eNkE.js} +1 -1
- package/web-shell/assets/{architectureDiagram-5GKGNRK7-Bwb8jPXg.js → architectureDiagram-5GKGNRK7-D9l7-bDo.js} +1 -1
- package/web-shell/assets/{blockDiagram-NRAW4CY4-DHj71TSX.js → blockDiagram-NRAW4CY4-Bc8DEasw.js} +1 -1
- package/web-shell/assets/{c4Diagram-UCG6FXSJ-uKBBdbyr.js → c4Diagram-UCG6FXSJ-Dimb2Hmh.js} +1 -1
- package/web-shell/assets/channel-B7ohGDil.js +1 -0
- package/web-shell/assets/{chunk-2Q5K7J3B-BZd0Phrl.js → chunk-2Q5K7J3B-jVDmOpAQ.js} +1 -1
- package/web-shell/assets/{chunk-5VM5RSS4-7KNeNBqN.js → chunk-5VM5RSS4-DbG_SwdB.js} +1 -1
- package/web-shell/assets/{chunk-F27PBJKO-BeboS7Fi.js → chunk-F27PBJKO-QEc4cY1v.js} +1 -1
- package/web-shell/assets/{chunk-G27WJ6UU-RV3JONoj.js → chunk-G27WJ6UU-iJ36lQ3X.js} +1 -1
- package/web-shell/assets/{chunk-JWPE2WC7-Yw9FCFsP.js → chunk-JWPE2WC7-DuArnVtF.js} +1 -1
- package/web-shell/assets/{chunk-LCL6LL3I-GIMnydDe.js → chunk-LCL6LL3I-DxOf1zwL.js} +1 -1
- package/web-shell/assets/{chunk-POPQ4Y6H-Cfrux7bL.js → chunk-POPQ4Y6H-lVLu9Ild.js} +1 -1
- package/web-shell/assets/{chunk-SVP7TREG-BlvIN0CO.js → chunk-SVP7TREG-C6XYlIer.js} +1 -1
- package/web-shell/assets/{chunk-XXDRQBXY-DMs7Rr4t.js → chunk-XXDRQBXY-CiG2j2Ji.js} +1 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DdFpqpfD.js +1 -0
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DdFpqpfD.js +1 -0
- package/web-shell/assets/{cose-bilkent-JH36ORCC-DNGqTNwI.js → cose-bilkent-JH36ORCC-DGVHMMVm.js} +1 -1
- package/web-shell/assets/{cynefin-OW5HDTMX-CojMpaoH.js → cynefin-OW5HDTMX-D6cgpCnH.js} +1 -1
- package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-DF07YXGo.js → cynefinDiagram-5FMLGOSQ-BKv4Z-UX.js} +1 -1
- package/web-shell/assets/{dagre-3AP2YEHR-17-4WtCH.js → dagre-3AP2YEHR-B4ABMIG-.js} +1 -1
- package/web-shell/assets/{diagram-S7CK7UJ4-G3Wuyz9m.js → diagram-S7CK7UJ4-DgCkp_Lm.js} +1 -1
- package/web-shell/assets/{diagram-UQ7AKVKN-nyWIKZ8P.js → diagram-UQ7AKVKN-FG0FNokz.js} +1 -1
- package/web-shell/assets/{diagram-VSXAHHWV-tKHhmYSC.js → diagram-VSXAHHWV-JgkP9qg-.js} +1 -1
- package/web-shell/assets/{diagram-VX7I27RA-CpDf1hYk.js → diagram-VX7I27RA-ADh2x83l.js} +1 -1
- package/web-shell/assets/{diagram-Z3DM3KII-Cah2IFXG.js → diagram-Z3DM3KII-yXqoYF1J.js} +1 -1
- package/web-shell/assets/{ebnfDiagram-PWID7BFC-DNaCkgxy.js → ebnfDiagram-PWID7BFC-Duk83Ek_.js} +1 -1
- package/web-shell/assets/{erDiagram-SSCWMZ5O-CAdRgcf1.js → erDiagram-SSCWMZ5O-DMdvxySG.js} +1 -1
- package/web-shell/assets/{flowDiagram-A5DVABFB-CMUJAShL.js → flowDiagram-A5DVABFB-DHjVgSji.js} +1 -1
- package/web-shell/assets/{ganttDiagram-EL5Y4UJY-o-_MUNey.js → ganttDiagram-EL5Y4UJY-DMM9DkCE.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-_aG-2Z7O.js → gitGraphDiagram-WWUBYQGX-t_ug9vO8.js} +1 -1
- package/web-shell/assets/index-BGZRqbRo.css +36 -0
- package/web-shell/assets/index-DRri_6_x.js +2067 -0
- package/web-shell/assets/{index-BK_NKxiJ.js → index-zqvnpGHv.js} +1 -1
- package/web-shell/assets/{infoDiagram-RXCK75RN-qJPeZbGP.js → infoDiagram-RXCK75RN-eT1fANNm.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-5VMMS53U-7Om4vNo1.js → ishikawaDiagram-5VMMS53U-k3evzZNn.js} +1 -1
- package/web-shell/assets/{journeyDiagram-EYS64GPL-BNtXqmBW.js → journeyDiagram-EYS64GPL-CGim3EAi.js} +1 -1
- package/web-shell/assets/{kanban-definition-3QL26DDD-COgFec8P.js → kanban-definition-3QL26DDD-WHfJo-22.js} +1 -1
- package/web-shell/assets/{layout-B9n81PC9.js → layout-DkqIaFlJ.js} +1 -1
- package/web-shell/assets/{linear-Bb6nXZQq.js → linear-Bdkd3mCz.js} +1 -1
- package/web-shell/assets/{mermaid.core-Cgrm3JVT.js → mermaid.core-CGw0LkT_.js} +6 -6
- package/web-shell/assets/{mindmap-definition-FBJOCRG2-TKwLTjnG.js → mindmap-definition-FBJOCRG2-C9V4rBvo.js} +1 -1
- package/web-shell/assets/{pegDiagram-XKGWAZYB-BJPuvlpi.js → pegDiagram-XKGWAZYB-CwoI2T5G.js} +1 -1
- package/web-shell/assets/{pieDiagram-E7YTZNPT-D01VkNsW.js → pieDiagram-E7YTZNPT-DaTmBmPG.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-AXDQQJYC-C4hHsiv-.js → quadrantDiagram-AXDQQJYC-plh6MyGI.js} +1 -1
- package/web-shell/assets/{railroadDiagram-O6MQD6OU-CuEO4xK2.js → railroadDiagram-O6MQD6OU-D_b-S0iK.js} +1 -1
- package/web-shell/assets/{requirementDiagram-EFPCY7ZU-D5J_vIo5.js → requirementDiagram-EFPCY7ZU-zUzTN7VE.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-P5KCCOFB-DQKY223V.js → sankeyDiagram-P5KCCOFB-m6AhoD0l.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-D27YV_cm.js → sequenceDiagram-WJ2MYXX4-Cwhzsine.js} +1 -1
- package/web-shell/assets/{sizeCapture-X5ZJPWSS-TJg8UcwV.js → sizeCapture-X5ZJPWSS-CcZuKIae.js} +1 -1
- package/web-shell/assets/{stateDiagram-HBIQ2CUA-CmnPzUIx.js → stateDiagram-HBIQ2CUA-CFoiJwD_.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V--H8HdEmk.js +1 -0
- package/web-shell/assets/{swimlanes-XN3QIQJK-ByeP3_Nu.js → swimlanes-XN3QIQJK-CgS9hcaV.js} +1 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-ShE9OIgf.js +8 -0
- package/web-shell/assets/{timeline-definition-24CTP7MA-BsFA5juR.js → timeline-definition-24CTP7MA-Dzzc05t9.js} +1 -1
- package/web-shell/assets/{vennDiagram-4TSXK5OY-DREP2ECo.js → vennDiagram-4TSXK5OY-DemK0f7Y.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-VM6X3IG4-iyd9lKi2.js → wardleyDiagram-VM6X3IG4-CquLxtMr.js} +1 -1
- package/web-shell/assets/{xychartDiagram-S5SC5T6Z-CVr1_j9q.js → xychartDiagram-S5SC5T6Z-BTBKTM5g.js} +1 -1
- package/web-shell/index.html +196 -2
- package/chunks/MaxSizedBox-X42SXBJH.js +0 -110
- package/chunks/agent-headless-IZM25LJA.js +0 -85
- package/chunks/bridge-ME6QXZNA.js +0 -119
- package/chunks/channel-settings-store-PEOI7XCG.js +0 -120
- package/chunks/chunk-7J6OTNGO.js +0 -424
- package/chunks/chunk-BWORX6FA.js +0 -135
- package/chunks/chunk-CPBF7KYF.js +0 -51
- package/chunks/chunk-H72BQNM3.js +0 -645
- package/chunks/chunk-JHYH6PYQ.js +0 -3096
- package/chunks/chunk-SS4MRMKE.js +0 -3525
- package/chunks/chunk-T4EFG2P5.js +0 -113
- package/chunks/chunk-XZA32HII.js +0 -19
- package/chunks/chunk-ZYNTSXWK.js +0 -32
- package/chunks/config-utils-R6M3TA34.js +0 -113
- package/chunks/contextCommand-ZCAP23J6.js +0 -106
- package/chunks/daemon-status-provider-K3SJ5C2U.js +0 -117
- package/chunks/daemon-trust-policy-DOR3YG62.js +0 -112
- package/chunks/deferred-core-runtime-WOYLUQQ7.js +0 -114
- package/chunks/earlyInputCapture-OHBEVO4K.js +0 -107
- package/chunks/errors-WAK6KFBC.js +0 -113
- package/chunks/exitPlanMode-UEYBG6P5.js +0 -83
- package/chunks/goal-tools-PTD3MBA7.js +0 -411
- package/chunks/handleAutoUpdate-FP3NWNSG.js +0 -109
- package/chunks/i18n-INIU5X7A.js +0 -124
- package/chunks/initializer-TYODV6GE.js +0 -113
- package/chunks/installationInfo-AAPKYDSZ.js +0 -107
- package/chunks/list-TUODDN6J.js +0 -116
- package/chunks/list-agents-DI3YFTDT.js +0 -80
- package/chunks/loadedSettingsAdapter-KJCLZ3C4.js +0 -110
- package/chunks/mcp-MWSAPFOL.js +0 -110
- package/chunks/nonInteractiveCli-JXKL343Q.js +0 -185
- package/chunks/pidfile-QOIQZFT2.js +0 -111
- package/chunks/prompt-terminal-ledger-FOMFTYOM.js +0 -105
- package/chunks/resumeHistoryUtils-NSGF3UCB.js +0 -118
- package/chunks/ripGrep-4CAT6SKV.js +0 -39
- package/chunks/scheduled-tasks-MN2ZZ5P6.js +0 -127
- package/chunks/serve-2XCHPPGG.js +0 -118
- package/chunks/skill-settings-ZL4JY5UE.js +0 -118
- package/chunks/spawnChannel-ZST6XJVJ.js +0 -112
- package/chunks/standalone-update-THVU3OKY.js +0 -118
- package/chunks/terminal-image-renderer-KS25G33E.js +0 -114
- package/chunks/theme-manager-YMZNG45F.js +0 -102
- package/chunks/total-session-admission-PVN64JVV.js +0 -114
- package/chunks/trustedFolders-FATSC4YI.js +0 -122
- package/chunks/updateCheck-D3YG2WCD.js +0 -118
- package/chunks/useAutoAcceptIndicator-ILINOSAS.js +0 -120
- package/chunks/workspace-providers-status-IJ4VHFMB.js +0 -114
- package/chunks/workspace-registry-BTGZIMPK.js +0 -123
- package/chunks/workspace-service-SIN67ITC.js +0 -126
- package/chunks/workspace-skills-status-F3RKCUIX.js +0 -113
- package/chunks/write-file-PAIGB33C.js +0 -88
- package/web-shell/assets/channel-CXjVLaBa.js +0 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DANEijO3.js +0 -1
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DANEijO3.js +0 -1
- package/web-shell/assets/index-Ci-z4zWY.js +0 -1913
- package/web-shell/assets/index-LDlXZRHA.css +0 -36
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-DNKPyrDc.js +0 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-ZL1HPC6w.js +0 -8
- /package/chunks/{chunk-FOGQO4FG.js → chunk-JA5CBKRP.js} +0 -0
|
@@ -461,6 +461,7 @@ init_esbuild_shims();
|
|
|
461
461
|
var CHANNEL_PROMPT_DISPLAY_TEXT_META_KEY = "qwen.daemon.promptDisplayText";
|
|
462
462
|
var CHANNEL_PROMPT_AUTHORIZATION_META_KEY = "qwen.daemon.channelPromptAuthorization";
|
|
463
463
|
var CHANNEL_PROMPT_META_KEY = "qwen.channel.prompt";
|
|
464
|
+
var CHANNEL_BTW_METHOD = "qwen/control/session/btw";
|
|
464
465
|
var ACP_PRIVATE_PARENT_CAPABILITY_META_KEY = "qwen-code/private-parent-capability";
|
|
465
466
|
var ACP_PRIVATE_PARENT_CAPABILITY_ENV = "QWEN_CODE_PRIVATE_ACP_CAPABILITY";
|
|
466
467
|
function resolvePromptImages(options) {
|
|
@@ -761,15 +762,29 @@ var AcpBridge = class extends EventEmitter {
|
|
|
761
762
|
});
|
|
762
763
|
void this.registerChannelLoopMcpServer();
|
|
763
764
|
}
|
|
764
|
-
async
|
|
765
|
+
async applySessionApprovalMode(conn, sessionId, approvalMode) {
|
|
766
|
+
if (!approvalMode)
|
|
767
|
+
return;
|
|
768
|
+
try {
|
|
769
|
+
await conn.setSessionMode({ sessionId, modeId: approvalMode });
|
|
770
|
+
} catch (error) {
|
|
771
|
+
await conn.extMethod("qwen/control/session/close", { sessionId }).catch((closeError) => {
|
|
772
|
+
process.stderr.write(`[AcpBridge] Failed to close session ${sanitizeLogText(sessionId, 128)} after approval mode error: ${sanitizeLogText(closeError instanceof Error ? closeError.message : String(closeError), 512)}
|
|
773
|
+
`);
|
|
774
|
+
});
|
|
775
|
+
throw error;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
async newSession(cwd, options, bindingToken) {
|
|
765
779
|
const conn = this.ensureConnection();
|
|
766
780
|
await this.registerChannelLoopMcpServer();
|
|
767
781
|
const response = await conn.newSession({ cwd, mcpServers: [] });
|
|
782
|
+
await this.applySessionApprovalMode(conn, response.sessionId, options?.approvalMode);
|
|
768
783
|
this.knownSessionIds.add(response.sessionId);
|
|
769
784
|
this.sessionBindingTokens.set(response.sessionId, bindingToken);
|
|
770
785
|
return response.sessionId;
|
|
771
786
|
}
|
|
772
|
-
async loadSession(sessionId, cwd,
|
|
787
|
+
async loadSession(sessionId, cwd, options, bindingToken) {
|
|
773
788
|
const conn = this.ensureConnection();
|
|
774
789
|
await this.registerChannelLoopMcpServer();
|
|
775
790
|
await conn.unstable_resumeSession({
|
|
@@ -777,6 +792,7 @@ var AcpBridge = class extends EventEmitter {
|
|
|
777
792
|
cwd,
|
|
778
793
|
mcpServers: []
|
|
779
794
|
});
|
|
795
|
+
await this.applySessionApprovalMode(conn, sessionId, options?.approvalMode);
|
|
780
796
|
this.knownSessionIds.add(sessionId);
|
|
781
797
|
this.sessionBindingTokens.set(sessionId, bindingToken);
|
|
782
798
|
return sessionId;
|
|
@@ -829,6 +845,25 @@ var AcpBridge = class extends EventEmitter {
|
|
|
829
845
|
}
|
|
830
846
|
return chunks.join("") || slashCommandOutput;
|
|
831
847
|
}
|
|
848
|
+
async btw(sessionId, question, signal) {
|
|
849
|
+
if (!this.knownSessionIds.has(sessionId)) {
|
|
850
|
+
throw new Error(`Unknown ACP session ${sessionId}`);
|
|
851
|
+
}
|
|
852
|
+
if (signal?.aborted) {
|
|
853
|
+
throw createAbortError();
|
|
854
|
+
}
|
|
855
|
+
const response = await withAbortSignal(this.ensureConnection().extMethod(CHANNEL_BTW_METHOD, {
|
|
856
|
+
sessionId,
|
|
857
|
+
question
|
|
858
|
+
}), signal);
|
|
859
|
+
if (response["sessionId"] !== sessionId || response["answer"] !== null && typeof response["answer"] !== "string") {
|
|
860
|
+
throw new Error("Invalid BTW response from ACP agent");
|
|
861
|
+
}
|
|
862
|
+
return {
|
|
863
|
+
sessionId,
|
|
864
|
+
answer: response["answer"]
|
|
865
|
+
};
|
|
866
|
+
}
|
|
832
867
|
async cancelSession(sessionId) {
|
|
833
868
|
const conn = this.ensureConnection();
|
|
834
869
|
try {
|
|
@@ -1100,6 +1135,30 @@ async function withTimeout(operation, timeoutMs, message) {
|
|
|
1100
1135
|
}
|
|
1101
1136
|
}
|
|
1102
1137
|
__name(withTimeout, "withTimeout");
|
|
1138
|
+
async function withAbortSignal(operation, signal) {
|
|
1139
|
+
if (!signal)
|
|
1140
|
+
return operation;
|
|
1141
|
+
if (signal.aborted)
|
|
1142
|
+
throw createAbortError();
|
|
1143
|
+
let onAbort;
|
|
1144
|
+
const aborted = new Promise((_, reject) => {
|
|
1145
|
+
onAbort = /* @__PURE__ */ __name(() => reject(createAbortError()), "onAbort");
|
|
1146
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1147
|
+
});
|
|
1148
|
+
try {
|
|
1149
|
+
return await Promise.race([operation, aborted]);
|
|
1150
|
+
} finally {
|
|
1151
|
+
if (onAbort)
|
|
1152
|
+
signal.removeEventListener("abort", onAbort);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
__name(withAbortSignal, "withAbortSignal");
|
|
1156
|
+
function createAbortError() {
|
|
1157
|
+
const error = new Error("BTW request aborted");
|
|
1158
|
+
error.name = "AbortError";
|
|
1159
|
+
return error;
|
|
1160
|
+
}
|
|
1161
|
+
__name(createAbortError, "createAbortError");
|
|
1103
1162
|
function isSkippedMcpRegistration(result) {
|
|
1104
1163
|
return typeof result === "object" && result !== null && result.skipped === true;
|
|
1105
1164
|
}
|
|
@@ -1722,10 +1781,11 @@ var SessionRouter = class {
|
|
|
1722
1781
|
sessionOptions(channelName) {
|
|
1723
1782
|
const approvalMode = this.channelApprovalModes.get(channelName);
|
|
1724
1783
|
const loopsDisabled = this.channelsWithoutLoops.has(channelName);
|
|
1725
|
-
return
|
|
1784
|
+
return {
|
|
1726
1785
|
...approvalMode ? { approvalMode } : {},
|
|
1727
|
-
...loopsDisabled ? { enableChannelLoops: false } : {}
|
|
1728
|
-
|
|
1786
|
+
...loopsDisabled ? { enableChannelLoops: false } : {},
|
|
1787
|
+
sourceId: channelName
|
|
1788
|
+
};
|
|
1729
1789
|
}
|
|
1730
1790
|
async resolve(channelName, senderId, chatId, threadId, cwd, isGroup, options) {
|
|
1731
1791
|
const key = this.routingKey(channelName, senderId, chatId, options?.routingThreadId ?? threadId);
|
|
@@ -1802,7 +1862,7 @@ var SessionRouter = class {
|
|
|
1802
1862
|
async createAndStoreSession(key, input, operation) {
|
|
1803
1863
|
const loadWindow = this.beginSessionLoad();
|
|
1804
1864
|
try {
|
|
1805
|
-
const sessionId = await this.createLiveSession(input.cwd, loadWindow, key, this.sessionOptions(input.channelName), operation
|
|
1865
|
+
const sessionId = await this.createLiveSession(input.cwd, loadWindow, key, this.sessionOptions(input.channelName), operation);
|
|
1806
1866
|
try {
|
|
1807
1867
|
this.assertOperationCurrent(operation);
|
|
1808
1868
|
} catch (error) {
|
|
@@ -1858,7 +1918,7 @@ var SessionRouter = class {
|
|
|
1858
1918
|
} catch (loadError) {
|
|
1859
1919
|
this.assertOperationCurrent(operation);
|
|
1860
1920
|
try {
|
|
1861
|
-
const replacement = await this.createLiveSession(input.cwd, loadWindow, key, this.sessionOptions(input.channelName), operation
|
|
1921
|
+
const replacement = await this.createLiveSession(input.cwd, loadWindow, key, this.sessionOptions(input.channelName), operation);
|
|
1862
1922
|
try {
|
|
1863
1923
|
this.assertOperationCurrent(operation);
|
|
1864
1924
|
} catch (error) {
|
|
@@ -1894,6 +1954,9 @@ var SessionRouter = class {
|
|
|
1894
1954
|
getTarget(sessionId) {
|
|
1895
1955
|
return this.toTarget.get(sessionId);
|
|
1896
1956
|
}
|
|
1957
|
+
isSessionLive(sessionId) {
|
|
1958
|
+
return this.toTarget.has(sessionId) && this.isLive(sessionId);
|
|
1959
|
+
}
|
|
1897
1960
|
getSession(channelName, senderId, chatId, threadId) {
|
|
1898
1961
|
return this.toSession.get(this.routingKey(channelName, senderId, chatId, threadId));
|
|
1899
1962
|
}
|
|
@@ -2339,11 +2402,11 @@ var SessionRouter = class {
|
|
|
2339
2402
|
}
|
|
2340
2403
|
}
|
|
2341
2404
|
}
|
|
2342
|
-
async createLiveSession(cwd, loadWindow, routingKey, options, operation
|
|
2405
|
+
async createLiveSession(cwd, loadWindow, routingKey, options, operation) {
|
|
2343
2406
|
const maxAttempts = 2;
|
|
2344
2407
|
let lastDeadSessionId;
|
|
2345
2408
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
2346
|
-
const sessionId = await this.bridge.newSession(cwd,
|
|
2409
|
+
const sessionId = await this.bridge.newSession(cwd, options, operation);
|
|
2347
2410
|
try {
|
|
2348
2411
|
this.assertOperationCurrent(operation);
|
|
2349
2412
|
} catch (error) {
|
|
@@ -2469,6 +2532,7 @@ var NamedSessionManager = class {
|
|
|
2469
2532
|
isBusy;
|
|
2470
2533
|
now;
|
|
2471
2534
|
registry;
|
|
2535
|
+
taskBySessionId;
|
|
2472
2536
|
ownerOperations = /* @__PURE__ */ new Map();
|
|
2473
2537
|
constructor(options) {
|
|
2474
2538
|
this.channelName = options.channelName;
|
|
@@ -2479,9 +2543,52 @@ var NamedSessionManager = class {
|
|
|
2479
2543
|
this.isBusy = options.isBusy;
|
|
2480
2544
|
this.now = options.now ?? Date.now;
|
|
2481
2545
|
this.registry = this.readRegistry();
|
|
2546
|
+
this.taskBySessionId = this.buildTaskIndex(this.registry);
|
|
2547
|
+
}
|
|
2548
|
+
presentation(sessionId) {
|
|
2549
|
+
const reference = this.taskBySessionId.get(sessionId);
|
|
2550
|
+
return reference ? this.cloneTaskReference(reference) : void 0;
|
|
2551
|
+
}
|
|
2552
|
+
async resolvePresentation(sessionId) {
|
|
2553
|
+
const existing = this.presentation(sessionId);
|
|
2554
|
+
if (existing)
|
|
2555
|
+
return existing;
|
|
2556
|
+
const target = this.router.getTarget(sessionId);
|
|
2557
|
+
if (target?.channelName !== this.channelName || this.router.getSession(this.channelName, target.senderId, target.chatId) !== sessionId) {
|
|
2558
|
+
return void 0;
|
|
2559
|
+
}
|
|
2560
|
+
return this.withOwnerLock(target, async () => {
|
|
2561
|
+
const concurrent = this.presentation(sessionId);
|
|
2562
|
+
if (concurrent)
|
|
2563
|
+
return concurrent;
|
|
2564
|
+
if (this.getOwner(target))
|
|
2565
|
+
return void 0;
|
|
2566
|
+
const routedTarget = this.router.getTarget(sessionId);
|
|
2567
|
+
if (routedTarget?.channelName !== this.channelName || routedTarget.chatId !== target.chatId || routedTarget.senderId !== target.senderId || this.router.getSession(this.channelName, target.senderId, target.chatId) !== sessionId) {
|
|
2568
|
+
return void 0;
|
|
2569
|
+
}
|
|
2570
|
+
const routedCwd = this.router.getSessionCwd(sessionId);
|
|
2571
|
+
if (routedCwd !== void 0 && !this.isCurrentCwd(routedCwd)) {
|
|
2572
|
+
return void 0;
|
|
2573
|
+
}
|
|
2574
|
+
const timestamp = this.nextTimestamp();
|
|
2575
|
+
const task = {
|
|
2576
|
+
name: "default",
|
|
2577
|
+
sessionId,
|
|
2578
|
+
cwd: routedCwd ?? this.cwd,
|
|
2579
|
+
isolation: "shared",
|
|
2580
|
+
status: "open",
|
|
2581
|
+
target: routedTarget,
|
|
2582
|
+
createdAt: timestamp,
|
|
2583
|
+
updatedAt: timestamp,
|
|
2584
|
+
lastSelectedAt: timestamp
|
|
2585
|
+
};
|
|
2586
|
+
this.commitOwner(this.createOwner(routedTarget, task.name, [task]));
|
|
2587
|
+
return this.presentation(sessionId);
|
|
2588
|
+
});
|
|
2482
2589
|
}
|
|
2483
|
-
resolve(input,
|
|
2484
|
-
return this.withOwnerLock(input, () => this.resolveLocked(input,
|
|
2590
|
+
resolve(input, reserve) {
|
|
2591
|
+
return this.withOwnerLock(input, () => this.resolveLocked(input, reserve));
|
|
2485
2592
|
}
|
|
2486
2593
|
resolveAfterPreparation(input, prepare, needsSession, reserve) {
|
|
2487
2594
|
return this.withOwnerLock(input, async () => {
|
|
@@ -2492,7 +2599,7 @@ var NamedSessionManager = class {
|
|
|
2492
2599
|
try {
|
|
2493
2600
|
return {
|
|
2494
2601
|
status: "resolved",
|
|
2495
|
-
sessionId: await this.resolveLocked(input,
|
|
2602
|
+
sessionId: await this.resolveLocked(input, reserve)
|
|
2496
2603
|
};
|
|
2497
2604
|
} catch (error) {
|
|
2498
2605
|
return { status: "resolve_error", error };
|
|
@@ -2516,6 +2623,25 @@ var NamedSessionManager = class {
|
|
|
2516
2623
|
return task ? this.selection(owner, task) : void 0;
|
|
2517
2624
|
});
|
|
2518
2625
|
}
|
|
2626
|
+
lookup(input, name) {
|
|
2627
|
+
return this.withOwnerLock(input, async () => {
|
|
2628
|
+
const owner = await this.ensureOwner(input, false);
|
|
2629
|
+
if (!owner)
|
|
2630
|
+
return void 0;
|
|
2631
|
+
const task = this.findTask(owner, name);
|
|
2632
|
+
return task ? this.selection(owner, task) : void 0;
|
|
2633
|
+
});
|
|
2634
|
+
}
|
|
2635
|
+
resumeReserved(input, sessionId) {
|
|
2636
|
+
return this.withOwnerLock(input, async () => {
|
|
2637
|
+
const owner = await this.ensureOwner(input, false);
|
|
2638
|
+
const task = owner?.tasks.find((candidate) => candidate.sessionId === sessionId && candidate.status === "open");
|
|
2639
|
+
if (!task)
|
|
2640
|
+
return false;
|
|
2641
|
+
await this.loadTask(task, `Could not reload reserved task "${task.name}".`);
|
|
2642
|
+
return true;
|
|
2643
|
+
});
|
|
2644
|
+
}
|
|
2519
2645
|
create(input, name) {
|
|
2520
2646
|
return this.withOwnerLock(input, async () => {
|
|
2521
2647
|
this.validateName(name);
|
|
@@ -2527,7 +2653,6 @@ var NamedSessionManager = class {
|
|
|
2527
2653
|
if (this.openTaskCount(owner) >= MAX_OPEN_TASKS) {
|
|
2528
2654
|
throw new Error("You already have eight open tasks. Close one before creating another.");
|
|
2529
2655
|
}
|
|
2530
|
-
this.assertCanLeaveSelected(owner, void 0);
|
|
2531
2656
|
const timestamp = this.nextTimestamp(owner);
|
|
2532
2657
|
const target = this.target(input);
|
|
2533
2658
|
const sessionId = await this.createSession(target, this.cwd, `Could not create task "${name}".`);
|
|
@@ -2565,10 +2690,6 @@ var NamedSessionManager = class {
|
|
|
2565
2690
|
const task = this.findTask(owner, name);
|
|
2566
2691
|
if (!task)
|
|
2567
2692
|
throw new Error(`Task "${name}" was not found.`);
|
|
2568
|
-
this.assertCanLeaveSelected(owner, task.name);
|
|
2569
|
-
if (this.isBusy(task.sessionId)) {
|
|
2570
|
-
throw new Error(`Task "${task.name}" is still running or waiting for permission.`);
|
|
2571
|
-
}
|
|
2572
2693
|
if (task.status === "closed" && this.openTaskCount(owner) >= MAX_OPEN_TASKS) {
|
|
2573
2694
|
throw new Error("You already have eight open tasks. Close one before reopening another.");
|
|
2574
2695
|
}
|
|
@@ -2612,9 +2733,6 @@ var NamedSessionManager = class {
|
|
|
2612
2733
|
const replacement = wasActive ? owner.tasks.filter((candidate) => candidate.status === "open" && !this.sameName(candidate.name, task.name)).sort((a, b) => b.lastSelectedAt - a.lastSelectedAt)[0] : void 0;
|
|
2613
2734
|
let replacementLoaded = false;
|
|
2614
2735
|
if (replacement) {
|
|
2615
|
-
if (this.isBusy(replacement.sessionId)) {
|
|
2616
|
-
throw new Error(`Task "${replacement.name}" is still running or waiting for permission.`);
|
|
2617
|
-
}
|
|
2618
2736
|
replacementLoaded = await this.loadTask(replacement, `Could not load fallback task "${replacement.name}". Task "${task.name}" was not closed.`);
|
|
2619
2737
|
}
|
|
2620
2738
|
const closedTask = {
|
|
@@ -2751,7 +2869,7 @@ var NamedSessionManager = class {
|
|
|
2751
2869
|
this.router.activateManagedSession(createdSessionId, target, this.cwd);
|
|
2752
2870
|
return created;
|
|
2753
2871
|
}
|
|
2754
|
-
async resolveLocked(input,
|
|
2872
|
+
async resolveLocked(input, reserve) {
|
|
2755
2873
|
const owner = await this.ensureOwner(input, true);
|
|
2756
2874
|
if (!owner?.activeTaskName)
|
|
2757
2875
|
return void 0;
|
|
@@ -2759,9 +2877,6 @@ var NamedSessionManager = class {
|
|
|
2759
2877
|
if (!task || task.status !== "open") {
|
|
2760
2878
|
throw new Error("The selected Channel task is unavailable.");
|
|
2761
2879
|
}
|
|
2762
|
-
if (expectedSessionId !== void 0 && task.sessionId !== expectedSessionId) {
|
|
2763
|
-
return void 0;
|
|
2764
|
-
}
|
|
2765
2880
|
const release = reserve?.(task.sessionId);
|
|
2766
2881
|
try {
|
|
2767
2882
|
await this.loadTask(task, `Could not load task "${task.name}". No replacement session was created.`);
|
|
@@ -2799,15 +2914,6 @@ var NamedSessionManager = class {
|
|
|
2799
2914
|
};
|
|
2800
2915
|
this.commitOwner(this.createOwner(target, task.name, [task]));
|
|
2801
2916
|
}
|
|
2802
|
-
assertCanLeaveSelected(owner, nextTaskName) {
|
|
2803
|
-
if (!owner.activeTaskName || nextTaskName && this.sameName(owner.activeTaskName, nextTaskName)) {
|
|
2804
|
-
return;
|
|
2805
|
-
}
|
|
2806
|
-
const selected = this.findTask(owner, owner.activeTaskName);
|
|
2807
|
-
if (selected && this.isBusy(selected.sessionId)) {
|
|
2808
|
-
throw new Error(`Task "${selected.name}" is still running or waiting for permission.`);
|
|
2809
|
-
}
|
|
2810
|
-
}
|
|
2811
2917
|
async loadTask(task, failureMessage) {
|
|
2812
2918
|
try {
|
|
2813
2919
|
return (await this.router.loadManagedSession(task.sessionId, task.target, task.cwd)).loaded;
|
|
@@ -2919,6 +3025,22 @@ var NamedSessionManager = class {
|
|
|
2919
3025
|
}))
|
|
2920
3026
|
};
|
|
2921
3027
|
}
|
|
3028
|
+
cloneTaskReference(reference) {
|
|
3029
|
+
return { ...reference, target: { ...reference.target } };
|
|
3030
|
+
}
|
|
3031
|
+
buildTaskIndex(registry) {
|
|
3032
|
+
const index = /* @__PURE__ */ new Map();
|
|
3033
|
+
for (const owner of registry.owners) {
|
|
3034
|
+
for (const task of owner.tasks) {
|
|
3035
|
+
index.set(task.sessionId, {
|
|
3036
|
+
taskName: task.name,
|
|
3037
|
+
status: task.status,
|
|
3038
|
+
target: { ...task.target }
|
|
3039
|
+
});
|
|
3040
|
+
}
|
|
3041
|
+
}
|
|
3042
|
+
return index;
|
|
3043
|
+
}
|
|
2922
3044
|
commitOwner(owner) {
|
|
2923
3045
|
const owners = this.registry.owners.map((candidate) => candidate.channelName === owner.channelName && candidate.chatId === owner.chatId && candidate.senderId === owner.senderId ? owner : candidate);
|
|
2924
3046
|
if (!owners.some((candidate) => candidate.channelName === owner.channelName && candidate.chatId === owner.chatId && candidate.senderId === owner.senderId)) {
|
|
@@ -2928,8 +3050,10 @@ var NamedSessionManager = class {
|
|
|
2928
3050
|
if (!this.isRegistry(next)) {
|
|
2929
3051
|
throw new Error("Invalid named-session registry update.");
|
|
2930
3052
|
}
|
|
3053
|
+
const nextTaskBySessionId = this.buildTaskIndex(next);
|
|
2931
3054
|
this.writeRegistry(next);
|
|
2932
3055
|
this.registry = next;
|
|
3056
|
+
this.taskBySessionId = nextTaskBySessionId;
|
|
2933
3057
|
}
|
|
2934
3058
|
readRegistry() {
|
|
2935
3059
|
if (!existsSync4(this.filePath)) {
|
|
@@ -3705,6 +3829,7 @@ var LOOP_ADD_RE = /^"([^"]+)"\s+(.+)$/su;
|
|
|
3705
3829
|
var MAX_LOOP_JOBS_PER_TARGET = 10;
|
|
3706
3830
|
var MAX_LOOP_PROMPT_CHARS = 4e3;
|
|
3707
3831
|
var MAX_DISPLAY_PROJECTION_CHARS = 8e3;
|
|
3832
|
+
var CHANNEL_BTW_MAX_INPUT_LENGTH = 4096;
|
|
3708
3833
|
function parseLoopAddArgs(args) {
|
|
3709
3834
|
const match = args.trim().match(LOOP_ADD_RE);
|
|
3710
3835
|
if (!match)
|
|
@@ -3762,6 +3887,7 @@ var ChannelBase = class {
|
|
|
3762
3887
|
sessionQueues = /* @__PURE__ */ new Map();
|
|
3763
3888
|
queuedTurns = /* @__PURE__ */ new Map();
|
|
3764
3889
|
namedTurnBindings = /* @__PURE__ */ new WeakMap();
|
|
3890
|
+
inboundErrorSourceLabels = /* @__PURE__ */ new WeakMap();
|
|
3765
3891
|
registerBridgeEvents;
|
|
3766
3892
|
bridgeRecovery;
|
|
3767
3893
|
/**
|
|
@@ -3774,6 +3900,7 @@ var ChannelBase = class {
|
|
|
3774
3900
|
pendingChannelMemoryMutationDeliveries = /* @__PURE__ */ new Map();
|
|
3775
3901
|
/** Per-session active prompt tracking for dispatch modes. */
|
|
3776
3902
|
activePrompts = /* @__PURE__ */ new Map();
|
|
3903
|
+
activeBtw = /* @__PURE__ */ new Map();
|
|
3777
3904
|
/** Per-session message buffer for collect mode. */
|
|
3778
3905
|
collectBuffers = /* @__PURE__ */ new Map();
|
|
3779
3906
|
preflightedEnvelopes = /* @__PURE__ */ new WeakSet();
|
|
@@ -3830,15 +3957,34 @@ var ChannelBase = class {
|
|
|
3830
3957
|
this.onToolCall(chatId, event);
|
|
3831
3958
|
}
|
|
3832
3959
|
async dispatchBackgroundResponse(sessionId, text) {
|
|
3833
|
-
|
|
3960
|
+
let target = this.router.getTarget(sessionId);
|
|
3834
3961
|
if (!target || target.channelName !== this.name || text.trim().length === 0) {
|
|
3835
3962
|
return;
|
|
3836
3963
|
}
|
|
3964
|
+
let sourceLabel;
|
|
3965
|
+
if (this.namedSessions) {
|
|
3966
|
+
const presentation = await this.namedSessions.resolvePresentation(sessionId);
|
|
3967
|
+
const currentTarget = this.router.getTarget(sessionId);
|
|
3968
|
+
const currentPresentation = this.namedSessions.presentation(sessionId);
|
|
3969
|
+
if (!presentation || presentation.status !== "open" || !currentTarget || !this.router.isSessionLive(sessionId) || !currentPresentation || currentPresentation.status !== "open" || currentPresentation.taskName !== presentation.taskName || !this.sameTaskOwner(target, currentTarget) || !this.sameTaskOwner(currentTarget, currentPresentation.target)) {
|
|
3970
|
+
throw new Error("Named background response ownership is unavailable.");
|
|
3971
|
+
}
|
|
3972
|
+
target = currentTarget;
|
|
3973
|
+
sourceLabel = this.createSourceLabel(presentation, target);
|
|
3974
|
+
}
|
|
3837
3975
|
if (this.supportsProactiveSend() && this.supportsProactiveTarget(target)) {
|
|
3838
|
-
|
|
3976
|
+
if (sourceLabel) {
|
|
3977
|
+
await this.pushProactive(target, text, sourceLabel);
|
|
3978
|
+
} else {
|
|
3979
|
+
await this.pushProactive(target, text);
|
|
3980
|
+
}
|
|
3839
3981
|
return;
|
|
3840
3982
|
}
|
|
3841
|
-
|
|
3983
|
+
if (sourceLabel) {
|
|
3984
|
+
await this.deliverBackgroundReply(target.chatId, text, sessionId, sourceLabel);
|
|
3985
|
+
} else {
|
|
3986
|
+
await this.deliverBackgroundReply(target.chatId, text, sessionId);
|
|
3987
|
+
}
|
|
3842
3988
|
}
|
|
3843
3989
|
/**
|
|
3844
3990
|
* Fallback delivery of a background response when proactive send is
|
|
@@ -3846,8 +3992,115 @@ var ChannelBase = class {
|
|
|
3846
3992
|
* stay out of turn-scoped streaming state, for example) override only this
|
|
3847
3993
|
* step instead of re-implementing the whole dispatch flow.
|
|
3848
3994
|
*/
|
|
3849
|
-
async deliverBackgroundReply(chatId, text, sessionId) {
|
|
3850
|
-
await this.sendResponseMessage(chatId, text, sessionId);
|
|
3995
|
+
async deliverBackgroundReply(chatId, text, sessionId, sourceLabel) {
|
|
3996
|
+
await this.sendResponseMessage(chatId, text, sessionId, sourceLabel);
|
|
3997
|
+
}
|
|
3998
|
+
async handleBtw(envelope, sessionId, question, sourceLabel) {
|
|
3999
|
+
const target = this.router.getTarget(sessionId);
|
|
4000
|
+
if (!target || target.channelName !== this.name) {
|
|
4001
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Could not resolve the current task for /btw.", sourceLabel);
|
|
4002
|
+
return;
|
|
4003
|
+
}
|
|
4004
|
+
const running = this.activeBtw.get(sessionId);
|
|
4005
|
+
if (running) {
|
|
4006
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `BTW #${running.id} is still running for this task.`, sourceLabel);
|
|
4007
|
+
return;
|
|
4008
|
+
}
|
|
4009
|
+
const reference = this.namedSessions?.presentation(sessionId);
|
|
4010
|
+
const request = {
|
|
4011
|
+
id: randomUUID3().slice(0, 8),
|
|
4012
|
+
bridge: this.bridge,
|
|
4013
|
+
controller: new AbortController(),
|
|
4014
|
+
target: { ...target },
|
|
4015
|
+
chatId: envelope.chatId,
|
|
4016
|
+
...envelope.threadId ? { threadId: envelope.threadId } : {},
|
|
4017
|
+
...sourceLabel ? { sourceLabel } : {},
|
|
4018
|
+
...reference?.status === "open" ? { taskName: reference.taskName } : {}
|
|
4019
|
+
};
|
|
4020
|
+
this.activeBtw.set(sessionId, request);
|
|
4021
|
+
try {
|
|
4022
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `BTW #${request.id} received. The main task will continue.`, sourceLabel);
|
|
4023
|
+
} catch (error) {
|
|
4024
|
+
if (this.activeBtw.get(sessionId) === request) {
|
|
4025
|
+
this.cancelBtw(sessionId);
|
|
4026
|
+
}
|
|
4027
|
+
throw error;
|
|
4028
|
+
}
|
|
4029
|
+
if (!this.isBtwCurrent(sessionId, request)) {
|
|
4030
|
+
if (this.activeBtw.get(sessionId) === request) {
|
|
4031
|
+
this.cancelBtw(sessionId);
|
|
4032
|
+
}
|
|
4033
|
+
return;
|
|
4034
|
+
}
|
|
4035
|
+
void this.deliverBtw(sessionId, question, request).catch((error) => {
|
|
4036
|
+
process.stderr.write(`[${this.name}] BTW delivery failed for session ${sanitizeLogText(sessionId, 128)}: ${this.lifecycleError(error)}
|
|
4037
|
+
`);
|
|
4038
|
+
});
|
|
4039
|
+
}
|
|
4040
|
+
async deliverBtw(sessionId, question, request) {
|
|
4041
|
+
let message;
|
|
4042
|
+
try {
|
|
4043
|
+
let result;
|
|
4044
|
+
try {
|
|
4045
|
+
result = await request.bridge.btw(sessionId, question, request.controller.signal);
|
|
4046
|
+
if (result.sessionId !== sessionId) {
|
|
4047
|
+
throw new Error("BTW response session did not match the request");
|
|
4048
|
+
}
|
|
4049
|
+
const answer = result.answer?.trim();
|
|
4050
|
+
message = answer ? `BTW #${request.id}
|
|
4051
|
+
|
|
4052
|
+
${answer}` : `BTW #${request.id}
|
|
4053
|
+
|
|
4054
|
+
No answer is available from the current conversation context.`;
|
|
4055
|
+
} catch (error) {
|
|
4056
|
+
if (request.controller.signal.aborted)
|
|
4057
|
+
return;
|
|
4058
|
+
process.stderr.write(`[${this.name}] BTW request failed for session ${sanitizeLogText(sessionId, 128)}: ${this.lifecycleError(error)}
|
|
4059
|
+
`);
|
|
4060
|
+
message = `BTW #${request.id} failed. Please try again.`;
|
|
4061
|
+
}
|
|
4062
|
+
if (!this.isBtwCurrent(sessionId, request))
|
|
4063
|
+
return;
|
|
4064
|
+
try {
|
|
4065
|
+
await this.sendThreadMessage(request.chatId, request.threadId, message, request.sourceLabel);
|
|
4066
|
+
} catch (error) {
|
|
4067
|
+
try {
|
|
4068
|
+
await this.sendThreadMessage(request.chatId, request.threadId, `BTW #${request.id} failed. Please try again.`, request.sourceLabel);
|
|
4069
|
+
} catch {
|
|
4070
|
+
}
|
|
4071
|
+
throw error;
|
|
4072
|
+
}
|
|
4073
|
+
} finally {
|
|
4074
|
+
if (this.activeBtw.get(sessionId) === request) {
|
|
4075
|
+
this.activeBtw.delete(sessionId);
|
|
4076
|
+
}
|
|
4077
|
+
}
|
|
4078
|
+
}
|
|
4079
|
+
isBtwCurrent(sessionId, request) {
|
|
4080
|
+
if (request.controller.signal.aborted || this.activeBtw.get(sessionId) !== request || this.bridge !== request.bridge || !this.router.isSessionLive(sessionId)) {
|
|
4081
|
+
return false;
|
|
4082
|
+
}
|
|
4083
|
+
const currentTarget = this.router.getTarget(sessionId);
|
|
4084
|
+
if (!currentTarget || !this.sameTaskOwner(request.target, currentTarget) || request.target.threadId !== currentTarget.threadId) {
|
|
4085
|
+
return false;
|
|
4086
|
+
}
|
|
4087
|
+
if (!request.taskName)
|
|
4088
|
+
return true;
|
|
4089
|
+
const reference = this.namedSessions?.presentation(sessionId);
|
|
4090
|
+
return reference?.status === "open" && reference.taskName === request.taskName && this.sameTaskOwner(currentTarget, reference.target) && currentTarget.threadId === reference.target.threadId;
|
|
4091
|
+
}
|
|
4092
|
+
cancelBtw(sessionId) {
|
|
4093
|
+
const request = this.activeBtw.get(sessionId);
|
|
4094
|
+
if (!request)
|
|
4095
|
+
return;
|
|
4096
|
+
this.activeBtw.delete(sessionId);
|
|
4097
|
+
request.controller.abort();
|
|
4098
|
+
}
|
|
4099
|
+
cancelAllBtw() {
|
|
4100
|
+
const requests = Array.from(this.activeBtw.values());
|
|
4101
|
+
this.activeBtw.clear();
|
|
4102
|
+
for (const request of requests)
|
|
4103
|
+
request.controller.abort();
|
|
3851
4104
|
}
|
|
3852
4105
|
async dispatchPermissionRequest(event) {
|
|
3853
4106
|
const target = this.permissionTargetForEvent(event);
|
|
@@ -3862,12 +4115,59 @@ var ChannelBase = class {
|
|
|
3862
4115
|
}
|
|
3863
4116
|
return;
|
|
3864
4117
|
}
|
|
4118
|
+
let sourceLabel;
|
|
4119
|
+
let taskName;
|
|
4120
|
+
if (this.namedSessions) {
|
|
4121
|
+
let presentation;
|
|
4122
|
+
try {
|
|
4123
|
+
presentation = await this.namedSessions.resolvePresentation(event.sessionId);
|
|
4124
|
+
} catch (err) {
|
|
4125
|
+
try {
|
|
4126
|
+
await this.bridge.respondToPermission?.(event.requestId, {
|
|
4127
|
+
outcome: { outcome: "cancelled" }
|
|
4128
|
+
});
|
|
4129
|
+
} catch (respondErr) {
|
|
4130
|
+
process.stderr.write(`[${this.name}] permission cancellation failed for request ${sanitizeLogText(event.requestId, 128)}: ${this.lifecycleError(respondErr)}
|
|
4131
|
+
`);
|
|
4132
|
+
}
|
|
4133
|
+
throw err;
|
|
4134
|
+
}
|
|
4135
|
+
const currentTarget = this.permissionTargetForEvent(event);
|
|
4136
|
+
const currentPresentation = this.namedSessions.presentation(event.sessionId);
|
|
4137
|
+
if (!presentation || presentation.status !== "open" || !currentTarget || !this.router.isSessionLive(event.sessionId) || !currentPresentation || currentPresentation.status !== "open" || currentPresentation.taskName !== presentation.taskName || !this.sameTaskOwner(target, currentTarget) || !this.sameTaskOwner(currentTarget, currentPresentation.target)) {
|
|
4138
|
+
try {
|
|
4139
|
+
await this.bridge.respondToPermission?.(event.requestId, {
|
|
4140
|
+
outcome: { outcome: "cancelled" }
|
|
4141
|
+
});
|
|
4142
|
+
} catch (respondErr) {
|
|
4143
|
+
process.stderr.write(`[${this.name}] permission cancellation failed for request ${sanitizeLogText(event.requestId, 128)}: ${this.lifecycleError(respondErr)}
|
|
4144
|
+
`);
|
|
4145
|
+
}
|
|
4146
|
+
return;
|
|
4147
|
+
}
|
|
4148
|
+
const active = this.activePrompts.get(event.sessionId);
|
|
4149
|
+
sourceLabel = active ? active.sourceLabel : this.createSourceLabel(presentation, target);
|
|
4150
|
+
if (!sourceLabel) {
|
|
4151
|
+
try {
|
|
4152
|
+
await this.bridge.respondToPermission?.(event.requestId, {
|
|
4153
|
+
outcome: { outcome: "cancelled" }
|
|
4154
|
+
});
|
|
4155
|
+
} catch (respondErr) {
|
|
4156
|
+
process.stderr.write(`[${this.name}] permission cancellation failed for request ${sanitizeLogText(event.requestId, 128)}: ${this.lifecycleError(respondErr)}
|
|
4157
|
+
`);
|
|
4158
|
+
}
|
|
4159
|
+
return;
|
|
4160
|
+
}
|
|
4161
|
+
taskName = presentation.taskName;
|
|
4162
|
+
}
|
|
3865
4163
|
this.removePendingPermission(event.requestId);
|
|
3866
4164
|
const pending = {
|
|
3867
4165
|
requestId: event.requestId,
|
|
3868
4166
|
sessionId: event.sessionId,
|
|
3869
4167
|
target,
|
|
3870
4168
|
request: event.request,
|
|
4169
|
+
...sourceLabel ? { sourceLabel } : {},
|
|
4170
|
+
...taskName ? { taskName } : {},
|
|
3871
4171
|
settlementListeners: /* @__PURE__ */ new Set()
|
|
3872
4172
|
};
|
|
3873
4173
|
this.pendingPermissions.set(event.requestId, pending);
|
|
@@ -3882,9 +4182,9 @@ var ChannelBase = class {
|
|
|
3882
4182
|
}
|
|
3883
4183
|
const text = this.formatPermissionRequest(pending);
|
|
3884
4184
|
if (target.threadId !== void 0 && this.supportsProactiveSend() && this.supportsProactiveTarget(target)) {
|
|
3885
|
-
await this.pushProactive(target, text);
|
|
4185
|
+
await this.pushProactive(target, text, pending.sourceLabel);
|
|
3886
4186
|
} else {
|
|
3887
|
-
await this.sendThreadMessage(target.chatId, target.threadId, text);
|
|
4187
|
+
await this.sendThreadMessage(target.chatId, target.threadId, text, pending.sourceLabel);
|
|
3888
4188
|
}
|
|
3889
4189
|
} catch (err) {
|
|
3890
4190
|
this.removePendingPermission(event.requestId, "cancelled");
|
|
@@ -3914,6 +4214,7 @@ var ChannelBase = class {
|
|
|
3914
4214
|
runId: active.runId,
|
|
3915
4215
|
owner: active.owner,
|
|
3916
4216
|
target: pending.target,
|
|
4217
|
+
...pending.sourceLabel ? { sourceLabel: pending.sourceLabel } : {},
|
|
3917
4218
|
...precedingSegment ? { precedingSegmentId: precedingSegment.segmentId } : {},
|
|
3918
4219
|
questions,
|
|
3919
4220
|
submitOptionId,
|
|
@@ -4097,8 +4398,8 @@ var ChannelBase = class {
|
|
|
4097
4398
|
* on a specific issue/PR. The default falls through to sendMessage(chatId,
|
|
4098
4399
|
* text), ignoring threadId — existing IM adapters are behaviorally unchanged.
|
|
4099
4400
|
*/
|
|
4100
|
-
async sendThreadMessage(chatId, _threadId, text) {
|
|
4101
|
-
await this.sendMessage(chatId, text);
|
|
4401
|
+
async sendThreadMessage(chatId, _threadId, text, sourceLabel) {
|
|
4402
|
+
await this.sendMessage(chatId, this.formatAttributedText(text, sourceLabel));
|
|
4102
4403
|
}
|
|
4103
4404
|
/**
|
|
4104
4405
|
* Adapter hook for task lifecycle events — the canonical way to track task
|
|
@@ -4240,6 +4541,7 @@ var ChannelBase = class {
|
|
|
4240
4541
|
segmentId,
|
|
4241
4542
|
owner: active.owner,
|
|
4242
4543
|
target: resolvedTarget,
|
|
4544
|
+
...active.sourceLabel ? { sourceLabel: active.sourceLabel } : {},
|
|
4243
4545
|
...active.messageId ? { messageId: active.messageId } : {}
|
|
4244
4546
|
};
|
|
4245
4547
|
}
|
|
@@ -4281,11 +4583,11 @@ var ChannelBase = class {
|
|
|
4281
4583
|
supportsProactiveWebhookTarget(target) {
|
|
4282
4584
|
return this.supportsProactiveTarget(target);
|
|
4283
4585
|
}
|
|
4284
|
-
async pushProactive(target, text) {
|
|
4586
|
+
async pushProactive(target, text, sourceLabel) {
|
|
4285
4587
|
if (target.threadId) {
|
|
4286
4588
|
throw new Error("Channel does not support proactive loop messages for threaded targets.");
|
|
4287
4589
|
}
|
|
4288
|
-
await this.sendThreadMessage(target.chatId, target.threadId, text);
|
|
4590
|
+
await this.sendThreadMessage(target.chatId, target.threadId, text, sourceLabel);
|
|
4289
4591
|
}
|
|
4290
4592
|
async pushProactiveDelivery(target, text) {
|
|
4291
4593
|
try {
|
|
@@ -4486,6 +4788,7 @@ var ChannelBase = class {
|
|
|
4486
4788
|
}
|
|
4487
4789
|
/** Replace the bridge instance (used after crash recovery restart). */
|
|
4488
4790
|
setBridge(bridge) {
|
|
4791
|
+
this.cancelAllBtw();
|
|
4489
4792
|
if (this.registerBridgeEvents) {
|
|
4490
4793
|
this.detachBridgeEvents(this.bridge);
|
|
4491
4794
|
}
|
|
@@ -4946,6 +5249,7 @@ ${promptText}` : promptText;
|
|
|
4946
5249
|
})
|
|
4947
5250
|
]);
|
|
4948
5251
|
if (!cancelled) {
|
|
5252
|
+
this.cancelBtw(sessionId);
|
|
4949
5253
|
this.router.removeSessionId(sessionId);
|
|
4950
5254
|
this.instructedSessions.delete(sessionId);
|
|
4951
5255
|
this.unattendedMemorySessions.delete(sessionId);
|
|
@@ -5068,6 +5372,7 @@ ${promptText}` : promptText;
|
|
|
5068
5372
|
onToolCall(_chatId, _event) {
|
|
5069
5373
|
}
|
|
5070
5374
|
onSessionDied(sessionId) {
|
|
5375
|
+
this.cancelBtw(sessionId);
|
|
5071
5376
|
this.router.handleSessionDied(sessionId);
|
|
5072
5377
|
this.instructedSessions.delete(sessionId);
|
|
5073
5378
|
this.unattendedMemorySessions.delete(sessionId);
|
|
@@ -5124,11 +5429,11 @@ ${promptText}` : promptText;
|
|
|
5124
5429
|
*/
|
|
5125
5430
|
onResponseBoundary(_chatId, _sessionId) {
|
|
5126
5431
|
}
|
|
5127
|
-
async sendResponseMessage(chatId, text, sessionId) {
|
|
5432
|
+
async sendResponseMessage(chatId, text, sessionId, sourceLabel) {
|
|
5128
5433
|
const active = this.activePrompts.get(sessionId);
|
|
5129
5434
|
const target = this.router.getTarget(sessionId);
|
|
5130
5435
|
const threadId = active?.threadId ?? target?.threadId;
|
|
5131
|
-
await this.sendThreadMessage(chatId, threadId, text);
|
|
5436
|
+
await this.sendThreadMessage(chatId, threadId, text, sourceLabel ?? active?.sourceLabel);
|
|
5132
5437
|
}
|
|
5133
5438
|
/**
|
|
5134
5439
|
* Adapter hook for delivery-only metadata. The response delivery path can read
|
|
@@ -5143,6 +5448,12 @@ ${promptText}` : promptText;
|
|
|
5143
5448
|
getResponseMetadata(sessionId) {
|
|
5144
5449
|
return this.activePrompts.get(sessionId)?.metadata;
|
|
5145
5450
|
}
|
|
5451
|
+
getResponseSourceLabel(sessionId) {
|
|
5452
|
+
return this.activePrompts.get(sessionId)?.sourceLabel;
|
|
5453
|
+
}
|
|
5454
|
+
getInboundErrorSourceLabel(envelope) {
|
|
5455
|
+
return this.inboundErrorSourceLabels.get(envelope);
|
|
5456
|
+
}
|
|
5146
5457
|
/**
|
|
5147
5458
|
* Returns the active prompt's response thread while it remains available for
|
|
5148
5459
|
* adapter delivery. Falls back to the session target after prompt cleanup.
|
|
@@ -5155,8 +5466,8 @@ ${promptText}` : promptText;
|
|
|
5155
5466
|
* Override to customize delivery (e.g., finalize an AI card).
|
|
5156
5467
|
* Default: sends the full response text.
|
|
5157
5468
|
*/
|
|
5158
|
-
async onResponseComplete(chatId, fullText, sessionId,
|
|
5159
|
-
await this.sendResponseMessage(chatId, fullText, sessionId);
|
|
5469
|
+
async onResponseComplete(chatId, fullText, sessionId, segment) {
|
|
5470
|
+
await this.sendResponseMessage(chatId, fullText, sessionId, segment?.sourceLabel);
|
|
5160
5471
|
}
|
|
5161
5472
|
/**
|
|
5162
5473
|
* Register a slash command handler. Subclasses can call this to add
|
|
@@ -5261,7 +5572,7 @@ ${promptText}` : promptText;
|
|
|
5261
5572
|
}
|
|
5262
5573
|
return "resolved_outside_presenter";
|
|
5263
5574
|
}
|
|
5264
|
-
pendingPermissionForEnvelope(envelope, args) {
|
|
5575
|
+
pendingPermissionForEnvelope(envelope, args, selectedSessionId) {
|
|
5265
5576
|
const trimmed = args.trim();
|
|
5266
5577
|
if (trimmed) {
|
|
5267
5578
|
const explicit = this.pendingPermissions.get(trimmed);
|
|
@@ -5274,7 +5585,7 @@ ${promptText}` : promptText;
|
|
|
5274
5585
|
if (requestIds.length === 0) {
|
|
5275
5586
|
return { kind: "none", explicit: false };
|
|
5276
5587
|
}
|
|
5277
|
-
const matching = requestIds.map((id) => this.pendingPermissions.get(id)).filter((pending) => pending !== void 0 && this.canEnvelopeAnswerPendingPermission(envelope, pending));
|
|
5588
|
+
const matching = requestIds.map((id) => this.pendingPermissions.get(id)).filter((pending) => pending !== void 0 && (selectedSessionId === void 0 || pending.sessionId === selectedSessionId) && this.canEnvelopeAnswerPendingPermission(envelope, pending));
|
|
5278
5589
|
if (matching.length === 0) {
|
|
5279
5590
|
return { kind: "none", explicit: false };
|
|
5280
5591
|
}
|
|
@@ -5291,27 +5602,81 @@ ${promptText}` : promptText;
|
|
|
5291
5602
|
}
|
|
5292
5603
|
formatPermissionRequest(pending) {
|
|
5293
5604
|
const { toolCall } = pending.request;
|
|
5294
|
-
const
|
|
5605
|
+
const parameters = this.permissionParameterSummary(toolCall);
|
|
5606
|
+
const approveLabel = this.permissionOptionLabel(this.approvalOption(pending), "allow once");
|
|
5295
5607
|
const alwaysOption = this.approvalAlwaysOption(pending);
|
|
5608
|
+
const denyLabel = this.permissionOptionLabel(this.denialOption(pending), "deny");
|
|
5609
|
+
const requestSuffix = pending.taskName ? ` ${pending.requestId}` : "";
|
|
5610
|
+
const replyPadding = pending.taskName ? { approve: " ", always: " ", deny: " " } : { approve: " ", always: " ", deny: " " };
|
|
5296
5611
|
const replies = [
|
|
5297
|
-
|
|
5298
|
-
...alwaysOption ? [
|
|
5299
|
-
|
|
5612
|
+
`/approve${requestSuffix}${replyPadding.approve}${approveLabel}`,
|
|
5613
|
+
...alwaysOption ? [
|
|
5614
|
+
`/approve-always${requestSuffix}${replyPadding.always}${alwaysOption.label}`
|
|
5615
|
+
] : [],
|
|
5616
|
+
`/deny${requestSuffix}${replyPadding.deny}${denyLabel}`
|
|
5300
5617
|
];
|
|
5301
|
-
|
|
5618
|
+
return [
|
|
5302
5619
|
"Permission required to run a tool",
|
|
5620
|
+
...pending.taskName ? [`Request: ${pending.requestId}`] : [],
|
|
5303
5621
|
"",
|
|
5304
|
-
|
|
5305
|
-
|
|
5622
|
+
`Tool: ${this.permissionToolName(toolCall)}`,
|
|
5623
|
+
`Action: ${this.permissionTitle(toolCall)}`,
|
|
5624
|
+
...parameters ? [`Parameters: ${parameters}`] : [],
|
|
5306
5625
|
"",
|
|
5307
5626
|
"Reply with:",
|
|
5308
5627
|
...replies
|
|
5309
|
-
];
|
|
5310
|
-
return lines.join("\n");
|
|
5628
|
+
].join("\n");
|
|
5311
5629
|
}
|
|
5312
|
-
|
|
5630
|
+
permissionTitle(toolCall) {
|
|
5631
|
+
const rawTitle = typeof toolCall.title === "string" ? toolCall.title : void 0;
|
|
5632
|
+
return sanitizeQuotedText(rawTitle || "", 160).trim() || "Tool use";
|
|
5633
|
+
}
|
|
5634
|
+
permissionToolName(toolCall) {
|
|
5635
|
+
const rawToolCall = toolCall;
|
|
5636
|
+
const meta = isRecord2(rawToolCall["_meta"]) ? rawToolCall["_meta"] : void 0;
|
|
5637
|
+
for (const candidate of [meta?.["toolName"], rawToolCall["kind"]]) {
|
|
5638
|
+
if (typeof candidate !== "string")
|
|
5639
|
+
continue;
|
|
5640
|
+
const name = sanitizeQuotedText(candidate, 120).trim();
|
|
5641
|
+
if (name)
|
|
5642
|
+
return name;
|
|
5643
|
+
}
|
|
5644
|
+
return "unknown";
|
|
5645
|
+
}
|
|
5646
|
+
permissionParameterSummary(toolCall) {
|
|
5647
|
+
const rawToolCall = toolCall;
|
|
5648
|
+
const rawInput = isRecord2(rawToolCall["rawInput"]) ? rawToolCall["rawInput"] : void 0;
|
|
5649
|
+
if (!rawInput)
|
|
5650
|
+
return void 0;
|
|
5651
|
+
const entries = Object.entries(rawInput);
|
|
5652
|
+
if (entries.length === 0)
|
|
5653
|
+
return void 0;
|
|
5654
|
+
const visible = entries.slice(0, 4).map(([key, value]) => {
|
|
5655
|
+
const safeKey = sanitizeQuotedText(key, 48).trim() || "unknown";
|
|
5656
|
+
if (Array.isArray(value)) {
|
|
5657
|
+
return `${safeKey} (${value.length} ${value.length === 1 ? "item" : "items"})`;
|
|
5658
|
+
}
|
|
5659
|
+
if (isRecord2(value)) {
|
|
5660
|
+
return `${safeKey} (object)`;
|
|
5661
|
+
}
|
|
5662
|
+
return safeKey;
|
|
5663
|
+
});
|
|
5664
|
+
if (entries.length > visible.length) {
|
|
5665
|
+
visible.push(`+${entries.length - visible.length} more`);
|
|
5666
|
+
}
|
|
5667
|
+
return visible.join(", ");
|
|
5668
|
+
}
|
|
5669
|
+
permissionOptionLabel(option, fallback) {
|
|
5670
|
+
const rawLabel = typeof option?.name === "string" ? option.name : "";
|
|
5671
|
+
const label = sanitizeQuotedText(rawLabel, 160).trim();
|
|
5672
|
+
return label || fallback;
|
|
5673
|
+
}
|
|
5674
|
+
approvalOption(pending) {
|
|
5313
5675
|
const options = pending.request.options;
|
|
5314
|
-
return options.find((option) => option.kind === "allow_once")
|
|
5676
|
+
return options.find((option) => option.kind === "allow_once") ?? options.find((option) => option.optionId === "proceed_once" && option.kind === void 0);
|
|
5677
|
+
}
|
|
5678
|
+
approvalOptionId(pending) {
|
|
5679
|
+
return this.approvalOption(pending)?.optionId;
|
|
5315
5680
|
}
|
|
5316
5681
|
approvalAlwaysOption(pending) {
|
|
5317
5682
|
const options = pending.request.options.filter((option2) => option2.kind === "allow_always");
|
|
@@ -5321,7 +5686,7 @@ ${promptText}` : promptText;
|
|
|
5321
5686
|
}
|
|
5322
5687
|
return {
|
|
5323
5688
|
optionId: option.optionId,
|
|
5324
|
-
label: this.approvalAlwaysLabel(option)
|
|
5689
|
+
label: this.permissionOptionLabel(option, this.approvalAlwaysLabel(option))
|
|
5325
5690
|
};
|
|
5326
5691
|
}
|
|
5327
5692
|
findScopedAlwaysOption(options, scope) {
|
|
@@ -5337,39 +5702,54 @@ ${promptText}` : promptText;
|
|
|
5337
5702
|
return "always allow";
|
|
5338
5703
|
}
|
|
5339
5704
|
denialResponse(pending) {
|
|
5340
|
-
const option =
|
|
5705
|
+
const option = this.denialOption(pending);
|
|
5341
5706
|
if (option) {
|
|
5342
5707
|
return { outcome: { outcome: "selected", optionId: option.optionId } };
|
|
5343
5708
|
}
|
|
5344
5709
|
return { outcome: { outcome: "cancelled" } };
|
|
5345
5710
|
}
|
|
5711
|
+
denialOption(pending) {
|
|
5712
|
+
return pending.request.options.find((candidate) => candidate.kind === "reject_once") ?? pending.request.options.find((candidate) => candidate.optionId === "cancel" && candidate.kind === void 0);
|
|
5713
|
+
}
|
|
5346
5714
|
async handlePermissionResponseCommand(envelope, args, decision) {
|
|
5347
5715
|
if (!this.isAuthorizedForSharedSession(envelope)) {
|
|
5348
5716
|
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can answer permission requests in this shared session.");
|
|
5349
5717
|
return true;
|
|
5350
5718
|
}
|
|
5351
|
-
const
|
|
5719
|
+
const namedSessions = this.namedSessions;
|
|
5720
|
+
const bareNamedCommand = namedSessions !== void 0 && args.trim() === "";
|
|
5721
|
+
let selectedTask;
|
|
5722
|
+
if (bareNamedCommand) {
|
|
5723
|
+
try {
|
|
5724
|
+
selectedTask = await namedSessions.current(this.namedSessionOwner(envelope));
|
|
5725
|
+
} catch (error) {
|
|
5726
|
+
await this.sendNamedSessionError(envelope, error);
|
|
5727
|
+
return true;
|
|
5728
|
+
}
|
|
5729
|
+
}
|
|
5730
|
+
const lookup = this.pendingPermissionForEnvelope(envelope, args, bareNamedCommand ? selectedTask?.sessionId ?? null : void 0);
|
|
5352
5731
|
if (lookup.kind === "ambiguous") {
|
|
5353
5732
|
const requestList = lookup.requestIds.slice(0, 6).map((id) => {
|
|
5354
5733
|
const pending2 = this.pendingPermissions.get(id);
|
|
5355
|
-
const title = pending2 ? `: ${
|
|
5356
|
-
|
|
5734
|
+
const title = pending2 ? `: ${this.permissionTitle(pending2.request.toolCall)}` : "";
|
|
5735
|
+
const task = pending2?.taskName ? `Task ${pending2.taskName} \u2014 ` : "";
|
|
5736
|
+
return `- ${task}${sanitizeQuotedText(id, 128)}${title}`;
|
|
5357
5737
|
}).join("\n");
|
|
5358
5738
|
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Multiple permission requests are pending for this chat. Reply with /${decision} <request-id>.
|
|
5359
5739
|
${requestList}`);
|
|
5360
5740
|
return true;
|
|
5361
5741
|
}
|
|
5362
5742
|
if (lookup.kind === "none") {
|
|
5363
|
-
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.");
|
|
5743
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, lookup.explicit ? "No pending permission request with that id for this chat." : selectedTask ? `No pending permission request for selected task "${selectedTask.name}". Use an explicit request ID to answer another task.` : this.namedSessions ? "No task is currently selected. Use an explicit request ID to answer a named task." : "No pending permission request for this chat.");
|
|
5364
5744
|
return true;
|
|
5365
5745
|
}
|
|
5746
|
+
const { pending } = lookup;
|
|
5366
5747
|
if (!this.bridge.respondToPermission) {
|
|
5367
|
-
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Permission relay is not available for this session.");
|
|
5748
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Permission relay is not available for this session.", pending.sourceLabel);
|
|
5368
5749
|
return true;
|
|
5369
5750
|
}
|
|
5370
|
-
const { pending } = lookup;
|
|
5371
5751
|
if (pending.userInputPresented && decision !== "deny") {
|
|
5372
|
-
await this.
|
|
5752
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Submit this question through its interactive card, or use /deny [request-id] to cancel it.", pending.sourceLabel);
|
|
5373
5753
|
return true;
|
|
5374
5754
|
}
|
|
5375
5755
|
const response = (() => {
|
|
@@ -5380,7 +5760,7 @@ ${requestList}`);
|
|
|
5380
5760
|
return optionId ? { outcome: { outcome: "selected", optionId } } : void 0;
|
|
5381
5761
|
})();
|
|
5382
5762
|
if (!response) {
|
|
5383
|
-
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.");
|
|
5763
|
+
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.", pending.sourceLabel);
|
|
5384
5764
|
return true;
|
|
5385
5765
|
}
|
|
5386
5766
|
let accepted;
|
|
@@ -5390,11 +5770,11 @@ ${requestList}`);
|
|
|
5390
5770
|
this.removePendingPermission(pending.requestId);
|
|
5391
5771
|
process.stderr.write(`[${this.name}] permission response failed for request ${sanitizeLogText(pending.requestId, 128)}: ${this.lifecycleError(err)}
|
|
5392
5772
|
`);
|
|
5393
|
-
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Failed to answer the permission request.");
|
|
5773
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Failed to answer the permission request.", pending.sourceLabel);
|
|
5394
5774
|
return true;
|
|
5395
5775
|
}
|
|
5396
5776
|
this.removePendingPermission(pending.requestId);
|
|
5397
|
-
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.");
|
|
5777
|
+
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.", pending.sourceLabel);
|
|
5398
5778
|
return true;
|
|
5399
5779
|
}
|
|
5400
5780
|
namedSessionOwner(envelope) {
|
|
@@ -5461,7 +5841,7 @@ ${requestList}`);
|
|
|
5461
5841
|
if (this.bypassesNamedTurnBinding(envelope))
|
|
5462
5842
|
return true;
|
|
5463
5843
|
try {
|
|
5464
|
-
const sessionId = await namedSessions.resolve(this.namedSessionOwner(envelope),
|
|
5844
|
+
const sessionId = await namedSessions.resolve(this.namedSessionOwner(envelope), (resolvedSessionId) => {
|
|
5465
5845
|
const binding = this.bindNamedTurn(envelope, resolvedSessionId);
|
|
5466
5846
|
return () => this.releaseNamedTurnBinding(binding);
|
|
5467
5847
|
});
|
|
@@ -5541,7 +5921,7 @@ ${requestList}`);
|
|
|
5541
5921
|
}
|
|
5542
5922
|
case "new": {
|
|
5543
5923
|
if (parts.includes("--worktree")) {
|
|
5544
|
-
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Worktree tasks are
|
|
5924
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Worktree tasks are planned for Part 4. Create a shared task with /session new <name>.");
|
|
5545
5925
|
return true;
|
|
5546
5926
|
}
|
|
5547
5927
|
if (parts.length !== 1)
|
|
@@ -5560,13 +5940,34 @@ ${requestList}`);
|
|
|
5560
5940
|
case "close": {
|
|
5561
5941
|
if (parts.length !== 1)
|
|
5562
5942
|
break;
|
|
5943
|
+
const closing = await namedSessions.lookup(owner, parts[0]);
|
|
5563
5944
|
const result = await namedSessions.close(owner, parts[0]);
|
|
5945
|
+
if (closing)
|
|
5946
|
+
this.cancelBtw(closing.sessionId);
|
|
5564
5947
|
await this.sendThreadMessage(envelope.chatId, envelope.threadId, result.active ? `Closed task "${result.closed.name}". Selected "${result.active.name}".` : `Closed task "${result.closed.name}". No task is selected.`);
|
|
5565
5948
|
return true;
|
|
5566
5949
|
}
|
|
5567
|
-
case "cancel":
|
|
5568
|
-
|
|
5950
|
+
case "cancel": {
|
|
5951
|
+
if (parts.length > 1)
|
|
5952
|
+
break;
|
|
5953
|
+
const taskName = parts[0];
|
|
5954
|
+
const task = taskName ? await namedSessions.lookup(owner, taskName) : await namedSessions.current(owner);
|
|
5955
|
+
if (!task) {
|
|
5956
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, taskName ? `Task "${sanitizeQuotedText(taskName, 32)}" was not found.` : "No task is currently selected.");
|
|
5957
|
+
return true;
|
|
5958
|
+
}
|
|
5959
|
+
if (task.status !== "open") {
|
|
5960
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Task "${task.name}" is closed.`);
|
|
5961
|
+
return true;
|
|
5962
|
+
}
|
|
5963
|
+
if (!this.activePrompts.has(task.sessionId)) {
|
|
5964
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `No request is currently running for task "${task.name}".`);
|
|
5965
|
+
return true;
|
|
5966
|
+
}
|
|
5967
|
+
const cancelled = await this.requestActivePromptCancellation(task.sessionId, "cancel_command");
|
|
5968
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, cancelled ? `Cancelled task "${task.name}".` : `Failed to cancel task "${task.name}".`);
|
|
5569
5969
|
return true;
|
|
5970
|
+
}
|
|
5570
5971
|
default:
|
|
5571
5972
|
break;
|
|
5572
5973
|
}
|
|
@@ -5597,6 +5998,7 @@ ${requestList}`);
|
|
|
5597
5998
|
this.clearPendingGroupHistory(envelope);
|
|
5598
5999
|
if (removedIds.length > 0) {
|
|
5599
6000
|
for (const id of removedIds) {
|
|
6001
|
+
this.cancelBtw(id);
|
|
5600
6002
|
if (this.isSharedSession(envelope)) {
|
|
5601
6003
|
const who = sanitizeSenderName(envelope.senderName || envelope.senderId || "unknown");
|
|
5602
6004
|
process.stderr.write(`[${this.name}] shared session ${id} cleared by ${who} (sender ${envelope.senderId})
|
|
@@ -5659,6 +6061,7 @@ ${requestList}`);
|
|
|
5659
6061
|
this.registerCommand("clear", clearHandler);
|
|
5660
6062
|
this.registerCommand("reset", clearHandler);
|
|
5661
6063
|
this.registerCommand("new", clearHandler);
|
|
6064
|
+
this.registerCommand("btw", () => Promise.resolve(false));
|
|
5662
6065
|
if (this.namedSessions) {
|
|
5663
6066
|
this.registerCommand("sessions", (envelope, args) => this.handleNamedSessionsCommand(envelope, args));
|
|
5664
6067
|
this.registerCommand("session", (envelope, args) => this.handleNamedSessionCommand(envelope, args));
|
|
@@ -5697,9 +6100,12 @@ ${requestList}`);
|
|
|
5697
6100
|
"/approve [request-id] \u2014 Approve a pending permission request",
|
|
5698
6101
|
"/approve-always [request-id] \u2014 Always approve a pending permission request",
|
|
5699
6102
|
"/deny [request-id] \u2014 Deny a pending permission request",
|
|
6103
|
+
...this.bridge.btw ? [
|
|
6104
|
+
"/btw <question> \u2014 Ask a side question without interrupting the current task"
|
|
6105
|
+
] : [],
|
|
5700
6106
|
...this.namedSessions ? [
|
|
5701
6107
|
"/sessions [all] \u2014 List your named tasks",
|
|
5702
|
-
"/session current|new|use|close \u2014 Manage your named tasks"
|
|
6108
|
+
"/session current|new|use|close|cancel \u2014 Manage your named tasks"
|
|
5703
6109
|
] : []
|
|
5704
6110
|
];
|
|
5705
6111
|
const sharedCmds = /* @__PURE__ */ new Set([
|
|
@@ -5710,6 +6116,7 @@ ${requestList}`);
|
|
|
5710
6116
|
"approve",
|
|
5711
6117
|
"approve-always",
|
|
5712
6118
|
"deny",
|
|
6119
|
+
"btw",
|
|
5713
6120
|
"remember-channel",
|
|
5714
6121
|
"channel-memory",
|
|
5715
6122
|
"forget-channel",
|
|
@@ -5725,7 +6132,10 @@ ${requestList}`);
|
|
|
5725
6132
|
}
|
|
5726
6133
|
}
|
|
5727
6134
|
const sessionId = await this.currentSessionId(envelope);
|
|
5728
|
-
const agentCommands = sessionId ? this.getAgentCommandsForSession(sessionId) : this.bridge.availableCommands
|
|
6135
|
+
const agentCommands = (sessionId ? this.getAgentCommandsForSession(sessionId) : this.bridge.availableCommands).filter((command) => !this.commands.has(command.name) || // `btw` is registered unconditionally but only handled locally when
|
|
6136
|
+
// the bridge supports it. Without that capability the agent's entry
|
|
6137
|
+
// is the working one, so it must stay listed.
|
|
6138
|
+
command.name === "btw" && !this.bridge.btw);
|
|
5729
6139
|
if (agentCommands.length > 0) {
|
|
5730
6140
|
lines.push("", "Agent commands (forwarded to Qwen Code):");
|
|
5731
6141
|
for (const cmd of agentCommands) {
|
|
@@ -6967,6 +7377,57 @@ ${promptText}`;
|
|
|
6967
7377
|
return void 0;
|
|
6968
7378
|
}
|
|
6969
7379
|
}
|
|
7380
|
+
formatAttributedText(text, sourceLabel) {
|
|
7381
|
+
if (!sourceLabel || text.trim().length === 0)
|
|
7382
|
+
return text;
|
|
7383
|
+
return `${sourceLabel} ${text}`;
|
|
7384
|
+
}
|
|
7385
|
+
formatMarkdownAttributedText(text, sourceLabel) {
|
|
7386
|
+
const escapedLabel = sourceLabel?.replace(/([\\`*_[\]{}()#+\-.!|>~])/gu, "\\$1");
|
|
7387
|
+
if (!escapedLabel || text.trim().length === 0)
|
|
7388
|
+
return text;
|
|
7389
|
+
return `${escapedLabel}
|
|
7390
|
+
${text}`;
|
|
7391
|
+
}
|
|
7392
|
+
sameTaskOwner(a, b) {
|
|
7393
|
+
return a.channelName === b.channelName && a.chatId === b.chatId && a.senderId === b.senderId;
|
|
7394
|
+
}
|
|
7395
|
+
createSourceLabel(reference, target, active) {
|
|
7396
|
+
const activeName = active?.senderName ? this.sanitizeSourceSender(active.senderName) : void 0;
|
|
7397
|
+
const senderLabel = (activeName && activeName !== "unknown" ? activeName : void 0) ?? this.observedSenderLabel(target.chatId, target.senderId) ?? this.sanitizeSourceSender(target.senderId || "unknown");
|
|
7398
|
+
const isGroup = active?.isGroup ?? target.isGroup ?? true;
|
|
7399
|
+
return isGroup ? `[${senderLabel} \xB7 ${reference.taskName}]` : `[${reference.taskName}]`;
|
|
7400
|
+
}
|
|
7401
|
+
observedSenderLabel(chatId, senderId) {
|
|
7402
|
+
const graph = this.persistedObservedContacts();
|
|
7403
|
+
if (!graph)
|
|
7404
|
+
return void 0;
|
|
7405
|
+
const sources = [
|
|
7406
|
+
graph.groups.filter((group) => group.id === chatId).flatMap((group) => group.users).filter((user) => user.id === senderId),
|
|
7407
|
+
graph.users.filter((user) => user.id === senderId)
|
|
7408
|
+
];
|
|
7409
|
+
for (const source of sources) {
|
|
7410
|
+
const candidates = source.sort((a, b) => b.lastObservedAt.localeCompare(a.lastObservedAt));
|
|
7411
|
+
for (const candidate of candidates) {
|
|
7412
|
+
const label = this.sanitizeSourceSender(candidate.label);
|
|
7413
|
+
if (label !== "unknown")
|
|
7414
|
+
return label;
|
|
7415
|
+
}
|
|
7416
|
+
}
|
|
7417
|
+
return void 0;
|
|
7418
|
+
}
|
|
7419
|
+
sanitizeSourceSender(value) {
|
|
7420
|
+
return sanitizeSenderName(value).replace(/\s+/gu, " ").trim() || "unknown";
|
|
7421
|
+
}
|
|
7422
|
+
sourceLabelForTurn(sessionId, envelope) {
|
|
7423
|
+
const reference = this.namedSessions?.presentation(sessionId);
|
|
7424
|
+
if (!reference || reference.status !== "open")
|
|
7425
|
+
return void 0;
|
|
7426
|
+
return this.createSourceLabel(reference, reference.target, {
|
|
7427
|
+
isGroup: envelope.isGroup,
|
|
7428
|
+
senderName: envelope.senderName
|
|
7429
|
+
});
|
|
7430
|
+
}
|
|
6970
7431
|
markPreflighted(envelope) {
|
|
6971
7432
|
this.preflightedEnvelopes.add(envelope);
|
|
6972
7433
|
}
|
|
@@ -6999,12 +7460,13 @@ ${promptText}`;
|
|
|
6999
7460
|
this.onObservedContact(envelope);
|
|
7000
7461
|
}
|
|
7001
7462
|
const displayText = sanitizeDisplayText(envelope.displayText ?? envelope.text, MAX_DISPLAY_PROJECTION_CHARS);
|
|
7002
|
-
|
|
7463
|
+
const parsed = this.parseCommand(envelope.text);
|
|
7464
|
+
let memoryIntent = parsed?.command === "btw" ? null : parseChannelMemoryIntent(envelope.text);
|
|
7003
7465
|
let memoryIntentFromClassifier = false;
|
|
7004
7466
|
if (memoryIntent?.kind === "update" || memoryIntent?.kind === "remove") {
|
|
7005
7467
|
this.deletePendingChannelMemoryMutation(envelope);
|
|
7006
7468
|
}
|
|
7007
|
-
if (!memoryIntent && this.shouldClassifyChannelMemoryIntent(envelope.text)) {
|
|
7469
|
+
if (!memoryIntent && parsed?.command !== "btw" && this.shouldClassifyChannelMemoryIntent(envelope.text)) {
|
|
7008
7470
|
memoryIntent = await this.classifyChannelMemoryIntent(envelope);
|
|
7009
7471
|
memoryIntentFromClassifier = memoryIntent !== null;
|
|
7010
7472
|
}
|
|
@@ -7017,7 +7479,7 @@ ${promptText}`;
|
|
|
7017
7479
|
return;
|
|
7018
7480
|
}
|
|
7019
7481
|
}
|
|
7020
|
-
|
|
7482
|
+
let btwQuestion;
|
|
7021
7483
|
if (parsed) {
|
|
7022
7484
|
const handler = this.commands.get(parsed.command);
|
|
7023
7485
|
if (handler) {
|
|
@@ -7025,6 +7487,25 @@ ${promptText}`;
|
|
|
7025
7487
|
if (handled)
|
|
7026
7488
|
return;
|
|
7027
7489
|
}
|
|
7490
|
+
if (parsed.command === "btw" && this.bridge.btw) {
|
|
7491
|
+
if (!this.isAuthorizedForSharedSession(envelope)) {
|
|
7492
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can use /btw in this shared session.");
|
|
7493
|
+
return;
|
|
7494
|
+
}
|
|
7495
|
+
btwQuestion = parsed.args.trim();
|
|
7496
|
+
if (!btwQuestion) {
|
|
7497
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Usage: /btw <question>");
|
|
7498
|
+
return;
|
|
7499
|
+
}
|
|
7500
|
+
if (btwQuestion.length > CHANNEL_BTW_MAX_INPUT_LENGTH) {
|
|
7501
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `BTW questions are limited to ${CHANNEL_BTW_MAX_INPUT_LENGTH} characters.`);
|
|
7502
|
+
return;
|
|
7503
|
+
}
|
|
7504
|
+
if (envelope.imageBase64 || envelope.attachments?.length) {
|
|
7505
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "/btw supports text-only questions.");
|
|
7506
|
+
return;
|
|
7507
|
+
}
|
|
7508
|
+
}
|
|
7028
7509
|
}
|
|
7029
7510
|
const bangText = envelope.text.trimStart();
|
|
7030
7511
|
if (bangText.startsWith("!")) {
|
|
@@ -7054,19 +7535,20 @@ ${promptText}`;
|
|
|
7054
7535
|
return;
|
|
7055
7536
|
}
|
|
7056
7537
|
try {
|
|
7057
|
-
|
|
7538
|
+
const resumed = await this.namedSessions.resumeReserved(this.namedSessionOwner(envelope), namedTurn.sessionId);
|
|
7539
|
+
sessionId = resumed ? namedTurn.sessionId : void 0;
|
|
7058
7540
|
} catch (error) {
|
|
7059
7541
|
await this.sendNamedSessionError(envelope, error);
|
|
7060
7542
|
return;
|
|
7061
7543
|
}
|
|
7062
7544
|
if (!sessionId) {
|
|
7063
|
-
process.stderr.write(`[${this.name}] dropped collected turn from ${envelope.senderId} for session ${namedTurn.sessionId}:
|
|
7545
|
+
process.stderr.write(`[${this.name}] dropped collected turn from ${envelope.senderId} for session ${namedTurn.sessionId}: reserved task is no longer available
|
|
7064
7546
|
`);
|
|
7065
7547
|
return;
|
|
7066
7548
|
}
|
|
7067
7549
|
} else if (this.namedSessions) {
|
|
7068
7550
|
try {
|
|
7069
|
-
sessionId = await this.namedSessions.resolve(this.namedSessionOwner(envelope),
|
|
7551
|
+
sessionId = await this.namedSessions.resolve(this.namedSessionOwner(envelope), (resolvedSessionId) => {
|
|
7070
7552
|
const binding = this.bindNamedTurn(envelope, resolvedSessionId);
|
|
7071
7553
|
namedTurn = binding;
|
|
7072
7554
|
return () => this.releaseNamedTurnBinding(binding);
|
|
@@ -7082,6 +7564,15 @@ ${promptText}`;
|
|
|
7082
7564
|
} else {
|
|
7083
7565
|
sessionId = await this.router.resolve(this.name, envelope.senderId, envelope.chatId, envelope.threadId, this.config.cwd, envelope.isGroup);
|
|
7084
7566
|
}
|
|
7567
|
+
const sourceLabel = this.namedSessions ? this.sourceLabelForTurn(sessionId, envelope) : void 0;
|
|
7568
|
+
if (this.namedSessions && !sourceLabel) {
|
|
7569
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Could not identify the selected task. Use /sessions, select it again, and retry.");
|
|
7570
|
+
return;
|
|
7571
|
+
}
|
|
7572
|
+
if (btwQuestion !== void 0) {
|
|
7573
|
+
await this.handleBtw(envelope, sessionId, btwQuestion, sourceLabel);
|
|
7574
|
+
return;
|
|
7575
|
+
}
|
|
7085
7576
|
if (bangText.startsWith("!")) {
|
|
7086
7577
|
const cmd = bangText.slice(1).trim();
|
|
7087
7578
|
const bridgeShellCommand = this.bridge.shellCommand;
|
|
@@ -7096,9 +7587,9 @@ ${fence}` : "(no output)";
|
|
|
7096
7587
|
const exitLine = result.exitCode !== null && result.exitCode !== 0 ? `
|
|
7097
7588
|
Exit code: ${result.exitCode}` : "";
|
|
7098
7589
|
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `$ ${cmd}
|
|
7099
|
-
${output}${exitLine}
|
|
7590
|
+
${output}${exitLine}`, sourceLabel);
|
|
7100
7591
|
} catch (error) {
|
|
7101
|
-
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Shell command failed: ${error instanceof Error ? error.message : String(error)}
|
|
7592
|
+
await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Shell command failed: ${error instanceof Error ? error.message : String(error)}`, sourceLabel);
|
|
7102
7593
|
}
|
|
7103
7594
|
return;
|
|
7104
7595
|
}
|
|
@@ -7311,7 +7802,8 @@ ${promptToSend}`;
|
|
|
7311
7802
|
messageId: envelope.messageId,
|
|
7312
7803
|
senderId: envelope.senderId,
|
|
7313
7804
|
senderName: envelope.senderName,
|
|
7314
|
-
metadata: envelope.metadata
|
|
7805
|
+
metadata: envelope.metadata,
|
|
7806
|
+
sourceLabel
|
|
7315
7807
|
};
|
|
7316
7808
|
this.activePrompts.set(sessionId, promptState);
|
|
7317
7809
|
this.emitTaskLifecycle({
|
|
@@ -7328,7 +7820,7 @@ ${promptToSend}`;
|
|
|
7328
7820
|
minChars: this.config.blockStreamingChunk?.minChars ?? 400,
|
|
7329
7821
|
maxChars: this.config.blockStreamingChunk?.maxChars ?? 1e3,
|
|
7330
7822
|
idleMs: this.config.blockStreamingCoalesce?.idleMs ?? 1500,
|
|
7331
|
-
send: /* @__PURE__ */ __name((text) => this.sendResponseMessage(envelope.chatId, text, sessionId), "send")
|
|
7823
|
+
send: /* @__PURE__ */ __name((text) => this.sendResponseMessage(envelope.chatId, text, sessionId, sourceLabel), "send")
|
|
7332
7824
|
}) : null;
|
|
7333
7825
|
promptState.stopStreaming = () => streamer?.stop();
|
|
7334
7826
|
const heldChunks = [];
|
|
@@ -7430,6 +7922,9 @@ ${promptToSend}`;
|
|
|
7430
7922
|
if (promptState.cancelled) {
|
|
7431
7923
|
return;
|
|
7432
7924
|
}
|
|
7925
|
+
if (sourceLabel) {
|
|
7926
|
+
this.inboundErrorSourceLabels.set(envelope, sourceLabel);
|
|
7927
|
+
}
|
|
7433
7928
|
throw err;
|
|
7434
7929
|
} finally {
|
|
7435
7930
|
promptBridge.off("textChunk", onChunk);
|
|
@@ -7830,7 +8325,8 @@ var DaemonChannelBridge = class extends EventEmitter2 {
|
|
|
7830
8325
|
modelServiceId: this.options.modelServiceId,
|
|
7831
8326
|
sessionId,
|
|
7832
8327
|
sessionScope: this.options.sessionScope ?? "thread",
|
|
7833
|
-
...options?.approvalMode ? { approvalMode: options.approvalMode } : {}
|
|
8328
|
+
...options?.approvalMode ? { approvalMode: options.approvalMode } : {},
|
|
8329
|
+
...options?.sourceId ? { sourceId: options.sourceId } : {}
|
|
7834
8330
|
});
|
|
7835
8331
|
if (lifecycleGeneration !== this.lifecycleGeneration) {
|
|
7836
8332
|
await this.rejectStaleSession(session);
|
|
@@ -8035,6 +8531,13 @@ var DaemonChannelBridge = class extends EventEmitter2 {
|
|
|
8035
8531
|
}
|
|
8036
8532
|
}
|
|
8037
8533
|
}
|
|
8534
|
+
async btw(sessionId, question, signal) {
|
|
8535
|
+
const session = this.ensureSession(sessionId);
|
|
8536
|
+
if (!session.btw) {
|
|
8537
|
+
throw new Error("BTW is not supported by this daemon session");
|
|
8538
|
+
}
|
|
8539
|
+
return session.btw(question, signal ? { signal } : void 0);
|
|
8540
|
+
}
|
|
8038
8541
|
async shellCommand(sessionId, command, signal) {
|
|
8039
8542
|
const session = this.ensureSession(sessionId);
|
|
8040
8543
|
if (!session.shellCommand) {
|
|
@@ -8083,7 +8586,7 @@ var DaemonChannelBridge = class extends EventEmitter2 {
|
|
|
8083
8586
|
return false;
|
|
8084
8587
|
}
|
|
8085
8588
|
try {
|
|
8086
|
-
const accepted = await session.respondToPermission(requestId, response);
|
|
8589
|
+
const accepted = this.options.sessionPermissionVote && typeof session.respondToSessionPermission === "function" ? await session.respondToSessionPermission(requestId, response) : await session.respondToPermission(requestId, response);
|
|
8087
8590
|
this.requestToSession.delete(requestId);
|
|
8088
8591
|
if (accepted) {
|
|
8089
8592
|
this.rememberRespondedPermissionRequest(requestId, sessionId);
|