@qwen-code/qwen-code 0.21.13 → 0.21.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/qc-helper/docs/configuration/settings.md +13 -7
- package/bundled/qc-helper/docs/features/code-review.md +5 -1
- package/bundled/qc-helper/docs/features/commands.md +120 -8
- package/bundled/qc-helper/docs/features/sub-agents.md +2 -2
- package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +1 -1
- package/bundled/qc-helper/docs/qwen-serve.md +20 -3
- package/bundled/review/SKILL.md +50 -30
- package/chunks/{MaxSizedBox-UQALOVVT.js → MaxSizedBox-67IDQILY.js} +24 -23
- package/chunks/{StandaloneSessionPicker-KEGXNUG6.js → StandaloneSessionPicker-G4QJIRMH.js} +41 -40
- package/chunks/{acp-startup-profiler-NMDXYGDN.js → acp-startup-profiler-HUYGO57H.js} +2 -2
- package/chunks/{acpAgent-XPES32S7.js → acpAgent-BS3YYO33.js} +626 -141
- package/chunks/{agent-DPTOZFEM.js → agent-EHHEXKWN.js} +22 -21
- package/chunks/{agent-headless-GJCQMURW.js → agent-headless-UT2ZF76T.js} +22 -21
- package/chunks/{anthropicContentGenerator-G7BVXTKN.js → anthropicContentGenerator-M7XRJMSK.js} +3 -3
- package/chunks/{bridge-YNQBAA4Z.js → bridge-WQ4IL2RF.js} +26 -25
- package/chunks/{ca-4CQ6MYNQ.js → ca-SLZJD6QH.js} +8 -0
- package/chunks/{channel-management-service-GWY2GAIC.js → channel-management-service-X6LCQUAD.js} +1 -1
- package/chunks/{channel-settings-store-WNWYFHG7.js → channel-settings-store-ZDFXY7VY.js} +30 -29
- package/chunks/{channel-worker-group-7LXCMZ77.js → channel-worker-group-TJ35JDPE.js} +2 -2
- package/chunks/{channel-worker-manager-RYEME4ZZ.js → channel-worker-manager-G5LKWGOG.js} +2 -2
- package/chunks/{chunk-4PKCUT7F.js → chunk-2A6VQJYK.js} +6 -6
- package/chunks/chunk-2C6HJMG3.js +757 -0
- package/chunks/chunk-3PWCMXIR.js +9169 -0
- package/chunks/{chunk-BVJS5BSP.js → chunk-3PWNVF6N.js} +1 -1
- package/chunks/{chunk-X26JYGTD.js → chunk-3SL2P3WX.js} +1 -1
- package/chunks/{chunk-ZYBBISBY.js → chunk-3YRVPHT3.js} +15 -12
- package/chunks/{chunk-AS5IN4GK.js → chunk-47L5MLB5.js} +3 -3
- package/chunks/{chunk-3U3VAL47.js → chunk-4SR45OM4.js} +1 -1
- package/chunks/{chunk-OMLJNPBE.js → chunk-4ZMS3JCR.js} +1 -0
- package/chunks/{chunk-UKMR3CKV.js → chunk-4ZS3BLER.js} +3 -3
- package/chunks/{chunk-5EYKMUUY.js → chunk-544KT7X4.js} +1 -1
- package/chunks/{chunk-TUGSVUJB.js → chunk-55VKMB7X.js} +5 -5
- package/chunks/{chunk-GO7STP6N.js → chunk-5IJSFWQO.js} +4 -4
- package/chunks/{chunk-A4QRWUDE.js → chunk-5IYS4WWR.js} +1 -1
- package/chunks/{chunk-TS6625XH.js → chunk-5MK45KZ3.js} +9 -5
- package/chunks/{chunk-MLPXSYXR.js → chunk-6BJSYAML.js} +25 -16
- package/chunks/{chunk-V57QC6WW.js → chunk-6LAPGPVA.js} +5 -3
- package/chunks/{chunk-NNHNLJ2X.js → chunk-6RDZLBSJ.js} +240 -42
- package/chunks/{chunk-ZZO74WKW.js → chunk-73JUK3ZW.js} +24 -18
- package/chunks/{chunk-N5YPT6PH.js → chunk-7VNHO4MN.js} +7 -4
- package/chunks/{chunk-OVZPVYZB.js → chunk-AKBOLMUF.js} +95 -17
- package/chunks/{chunk-NHDR76JX.js → chunk-BQWNIPTE.js} +1 -1
- package/chunks/{chunk-IWPYVAO2.js → chunk-C3T6M24E.js} +2 -2
- package/chunks/{chunk-NM5V5OVW.js → chunk-CEXU72GE.js} +2 -2
- package/chunks/{chunk-AA2BEKV3.js → chunk-CH5OFRV7.js} +1 -1
- package/chunks/{chunk-MS7GNABG.js → chunk-CXJHQVEK.js} +8 -0
- package/chunks/{chunk-E23IPNGS.js → chunk-CZK622ZK.js} +12 -3
- package/chunks/{chunk-K5IDV3PC.js → chunk-D34RDOLP.js} +12 -2
- package/chunks/{chunk-OXCMMLED.js → chunk-DGJ7O55J.js} +1 -1
- package/chunks/{chunk-DGK6P3BQ.js → chunk-DHUPMYMC.js} +10 -10
- package/chunks/{chunk-O4D7SPJN.js → chunk-DRAONPUW.js} +3 -3
- package/chunks/{chunk-P7MPQI75.js → chunk-DVR7XKO5.js} +1 -1
- package/chunks/{chunk-PP4FUZNV.js → chunk-E5WQMF3K.js} +2 -2
- package/chunks/{chunk-4NFY2S7N.js → chunk-E7REAOTN.js} +15 -0
- package/chunks/{chunk-ZYYTZUI2.js → chunk-EOPBFLA5.js} +3 -3
- package/chunks/{chunk-OOQUVWIG.js → chunk-FN6M5WUL.js} +4 -4
- package/chunks/{chunk-DGZEMW5R.js → chunk-FS5NGKWC.js} +1 -1
- package/chunks/{chunk-MRMJCLIY.js → chunk-G6KI5UOJ.js} +2 -2
- package/chunks/{chunk-6ORZ2EDC.js → chunk-H3SHU2XU.js} +1 -1
- package/chunks/{chunk-GMIEIY3Y.js → chunk-I3N2Z25H.js} +1 -1
- package/chunks/{chunk-BHILXOC3.js → chunk-J63PKMYA.js} +1 -1
- package/chunks/{chunk-KD5BOPLP.js → chunk-J6YS7Z25.js} +98 -4
- package/chunks/chunk-K2Y45XXS.js +3887 -0
- package/chunks/{chunk-RVOJ2FBP.js → chunk-KC4WMLZO.js} +1486 -10574
- package/chunks/{chunk-LJQAUZMR.js → chunk-L3T4V5GZ.js} +925 -92
- package/chunks/{chunk-M6NDLY2T.js → chunk-LD5VIJ7S.js} +1 -1
- package/chunks/{chunk-RIAABG2K.js → chunk-LSO6EL4Y.js} +1 -1
- package/chunks/{chunk-XHRY7BXD.js → chunk-MDIGJH5X.js} +3 -3
- package/chunks/{chunk-MC4TLKEI.js → chunk-MVHJZ3FZ.js} +2 -2
- package/chunks/{chunk-YEYY7TEP.js → chunk-N6RSOOWJ.js} +5 -5
- package/chunks/{chunk-OD2WU5QY.js → chunk-NRPXRNN4.js} +1 -1
- package/chunks/{chunk-CKSJECTU.js → chunk-NVRMCWTP.js} +8 -4
- package/chunks/{chunk-Y3YCSWG5.js → chunk-OBJYN4MX.js} +1 -1
- package/chunks/{chunk-GGDBMYGZ.js → chunk-OEYAK5O6.js} +3 -3
- package/chunks/{chunk-6YKYPVDV.js → chunk-OEZCXK7Y.js} +3 -3
- package/chunks/{chunk-4S5337WV.js → chunk-OFTPCOGR.js} +4312 -2704
- package/chunks/{chunk-7UXUJ5T3.js → chunk-OJB5FYVK.js} +1 -1
- package/chunks/{chunk-WFSTRPRO.js → chunk-OJOP26ET.js} +1 -1
- package/chunks/{chunk-TIGA2IVL.js → chunk-OO4FKHLO.js} +2 -2
- package/chunks/{chunk-BZ263IKX.js → chunk-OVY67CYC.js} +1 -1
- package/chunks/{chunk-PQ36L4F5.js → chunk-P3AA6S7O.js} +1 -1
- package/chunks/{chunk-CU6GJD55.js → chunk-PCETXVVV.js} +1 -1
- package/chunks/{chunk-AFSG32D5.js → chunk-PHN4R2ZV.js} +1 -1
- package/chunks/{chunk-QF2NHSPB.js → chunk-PJSD2FOR.js} +233 -184
- package/chunks/{chunk-NEFOOD54.js → chunk-QAVTWAHL.js} +2 -2
- package/chunks/{chunk-AW4TRXOC.js → chunk-QEHH23OM.js} +1 -1
- package/chunks/{chunk-CZBYX5MY.js → chunk-QEJZUXSK.js} +1 -1
- package/chunks/{chunk-XIT3GURH.js → chunk-QRVHGEVY.js} +3 -3
- package/chunks/{chunk-M732YJPW.js → chunk-RXHBTKMG.js} +2 -2
- package/chunks/{chunk-JOOFMXGF.js → chunk-S7N3HUIB.js} +5 -5
- package/chunks/{chunk-76J3IJ3M.js → chunk-SCZU65AI.js} +3 -3
- package/chunks/{chunk-QIH2HAEN.js → chunk-SFJMFZT5.js} +1 -1
- package/chunks/{chunk-JNDY2MDR.js → chunk-SFTKAX4O.js} +1 -1
- package/chunks/{chunk-WSH6GRKG.js → chunk-SLILKYV2.js} +2 -2
- package/chunks/{chunk-DXIBNLBZ.js → chunk-SNQZZ765.js} +1 -1
- package/chunks/{chunk-V26NVGAU.js → chunk-TSMPNGBC.js} +8 -3
- package/chunks/{chunk-QV5YN5YD.js → chunk-U657UZJN.js} +5 -5
- package/chunks/{chunk-QNQAPSN2.js → chunk-UC67T4SF.js} +3 -1
- package/chunks/{chunk-O565M6A4.js → chunk-UYDGFWIJ.js} +199 -14
- package/chunks/{chunk-OY5RNSV4.js → chunk-V6WEMZPD.js} +3 -3
- package/chunks/{chunk-A267JX7H.js → chunk-VFP5YOHJ.js} +6 -6
- package/chunks/{chunk-HUTNYWBG.js → chunk-VTOLYFWM.js} +18 -10
- package/chunks/{chunk-EZ5RP345.js → chunk-W7EYJGN7.js} +40 -9
- package/chunks/{chunk-BKPPWD33.js → chunk-WAO53ZQF.js} +1 -1
- package/chunks/{chunk-S5DWMTHO.js → chunk-WP4WIUOJ.js} +2 -0
- package/chunks/{chunk-25EYDK42.js → chunk-WPVUOVYX.js} +1 -1
- package/chunks/{chunk-AXN7UPYQ.js → chunk-WSSH2BNO.js} +1 -1
- package/chunks/chunk-WZAD4ZNJ.js +59 -0
- package/chunks/{chunk-JUEPY766.js → chunk-XITLNXLX.js} +2 -2
- package/chunks/{chunk-EL5SXY3T.js → chunk-XT4RKHVE.js} +2 -2
- package/chunks/{chunk-IGGGG5CX.js → chunk-XYRBK56E.js} +4635 -1655
- package/chunks/{chunk-UZPM4XHR.js → chunk-Y4RVDOXV.js} +29 -8
- package/chunks/{chunk-QRCNA3SR.js → chunk-Y7QY6DKW.js} +49 -69
- package/chunks/{chunk-FDGGZIYW.js → chunk-YECDICIO.js} +2 -2
- package/chunks/{chunk-46UV252V.js → chunk-YHC2EYYG.js} +35 -38
- package/chunks/{chunk-U3VNBPUO.js → chunk-YHXQK4SR.js} +2 -2
- package/chunks/{chunk-A4MFR4C5.js → chunk-ZIGC3MUS.js} +2 -4
- package/chunks/{computer-use-77C5FHMW.js → computer-use-YORZJQE5.js} +22 -21
- package/chunks/{config-utils-IVHRSXWI.js → config-utils-NJQA5YLJ.js} +2 -2
- package/chunks/{contextCommand-PJ77GBWL.js → contextCommand-PACHGIF4.js} +24 -23
- package/chunks/{core-runtime-7VMIKUTG.js → core-runtime-6HD5DSPX.js} +22 -21
- package/chunks/{create-sub-session-2L5MQRN4.js → create-sub-session-IQFIPUQA.js} +26 -24
- package/chunks/{cron-create-H7UEPDSN.js → cron-create-NFRZEOQX.js} +2 -2
- package/chunks/{cron-delete-6SZK7YFM.js → cron-delete-GFVSVO7C.js} +2 -2
- package/chunks/{cron-list-H25JIHEZ.js → cron-list-NRW34CLU.js} +2 -2
- package/chunks/{daemon-2KTG7ZBN.js → daemon-XH76IXOC.js} +356 -21
- package/chunks/{daemon-git-worktree-guard-DXYIMWFT.js → daemon-git-worktree-guard-6P27GKSU.js} +24 -23
- package/chunks/{daemon-status-provider-ZDOYJCU6.js → daemon-status-provider-SXS66ZIR.js} +31 -30
- package/chunks/{daemon-trust-policy-E67OYUK2.js → daemon-trust-policy-5QJHAS3N.js} +29 -28
- package/chunks/{daemon-trust-policy-monitor-RYYGCQ3J.js → daemon-trust-policy-monitor-JA2WZRZ3.js} +29 -28
- package/chunks/{de-UBEBKG6V.js → de-AH4LGCF5.js} +8 -0
- package/chunks/{deferred-core-runtime-3SGXFXEQ.js → deferred-core-runtime-R2VWOVG3.js} +22 -21
- package/chunks/{discovery-ORA5J7YP.js → discovery-X2NV535U.js} +1 -1
- package/chunks/{dist-WJ4BHIEW.js → dist-ESS34DHC.js} +72 -0
- package/chunks/{earlyInputCapture-KJMLFVQV.js → earlyInputCapture-PQEEOFKJ.js} +22 -21
- package/chunks/{edit-I4LQFAEC.js → edit-RASZHTU2.js} +25 -23
- package/chunks/{en-X6YV7GME.js → en-MD3GP5YL.js} +8 -0
- package/chunks/{enter-worktree-YNPOJSRH.js → enter-worktree-CH5OMHJE.js} +22 -21
- package/chunks/{enterPlanMode-XCPK62ER.js → enterPlanMode-AQKR3CAH.js} +22 -21
- package/chunks/{environment-S7CTIHMX.js → environment-7QRYIEBA.js} +25 -24
- package/chunks/{errors-7HB2AIDS.js → errors-P2LL5452.js} +24 -23
- package/chunks/{exit-worktree-AIIY7SR6.js → exit-worktree-WUDL26CY.js} +22 -21
- package/chunks/{exitPlanMode-R4JY7V2O.js → exitPlanMode-JM75SAUI.js} +22 -21
- package/chunks/{fast-path-NDJV3ZFJ.js → fast-path-KVNSOHVA.js} +3 -3
- package/chunks/{fast-path-settings-LNOFM2YP.js → fast-path-settings-WHX3J3ZI.js} +2 -2
- package/chunks/{fr-VENTC2BS.js → fr-ZEML2JWS.js} +8 -0
- package/chunks/{gemini-RSUFP5OE.js → gemini-ADMD2EOS.js} +62 -61
- package/chunks/{geminiContentGenerator-SQ5XBPZ7.js → geminiContentGenerator-CS3M7SOS.js} +3 -3
- package/chunks/{glob-J4RUJAHX.js → glob-WIJOGYVV.js} +22 -21
- package/chunks/{goal-tools-VHTNVOKK.js → goal-tools-K5OHOJ6B.js} +1 -1
- package/chunks/{grep-VJWPLFOT.js → grep-CIFRQBR7.js} +22 -21
- package/chunks/{handleAutoUpdate-POCX2MNB.js → handleAutoUpdate-KJ4SN7DM.js} +26 -25
- package/chunks/{i18n-RM5YOICI.js → i18n-36SZUO4C.js} +23 -22
- package/chunks/{image-gen-EXECB5XM.js → image-gen-R4B5VUYB.js} +2 -2
- package/chunks/{initializer-Z2AFGBNR.js → initializer-CW5YCAOL.js} +29 -28
- package/chunks/{installationInfo-4I5FXNMH.js → installationInfo-NMQIOUGY.js} +23 -22
- package/chunks/{ja-QHT4EQTO.js → ja-UM5B2HMD.js} +8 -0
- package/chunks/{list-ZMBFIGZA.js → list-HHGT3S4P.js} +32 -31
- package/chunks/{loadedSettingsAdapter-T6TV4YJ7.js → loadedSettingsAdapter-SJ2MJF35.js} +29 -28
- package/chunks/{loggingContentGenerator-WF4ZOJEZ.js → loggingContentGenerator-GR2QQ2C5.js} +12 -10
- package/chunks/{loop-wakeup-WQS6JYAG.js → loop-wakeup-HWVUU5CF.js} +3 -3
- package/chunks/{managed-npm-update-E7IW6N7V.js → managed-npm-update-ADQJHKTO.js} +23 -22
- package/chunks/{mcp-6UNYX4HG.js → mcp-QW3OTL5W.js} +29 -28
- package/chunks/{monitor-EE2UYMGE.js → monitor-RJKPVERH.js} +22 -21
- package/chunks/{nonInteractiveCli-WAY237O4.js → nonInteractiveCli-MROMHSTL.js} +59 -57
- package/chunks/{notebook-edit-NTDY4QDU.js → notebook-edit-2ENWDBZO.js} +26 -24
- package/chunks/{openaiContentGenerator-YNFVJMRJ.js → openaiContentGenerator-Z3GPWJU4.js} +12 -11
- package/chunks/{pidfile-4XSFLYBZ.js → pidfile-5G42YSTP.js} +22 -21
- package/chunks/{processUtils-WDA2MJFD.js → processUtils-ZDMXYKQY.js} +2 -2
- package/chunks/{pt-VL3I5RNY.js → pt-5BMJ3XYH.js} +8 -0
- package/chunks/{qwenContentGenerator-434M7QKY.js → qwenContentGenerator-NLEMBZVU.js} +25 -24
- package/chunks/{qwenOAuth2-GMYZOO6A.js → qwenOAuth2-EBV52DWJ.js} +3 -3
- package/chunks/{read-file-TAFBKMNI.js → read-file-5BYIF53O.js} +9 -7
- package/chunks/{record-artifact-SEYFJEJF.js → record-artifact-GLU3UWBV.js} +3 -1
- package/chunks/{resumeHistoryUtils-EVG3WYK2.js → resumeHistoryUtils-AFTBRS3G.js} +25 -24
- package/chunks/{ripGrep-WOEK2PXS.js → ripGrep-NN7AOLQY.js} +22 -21
- package/chunks/{ru-4RCKL4PY.js → ru-6GL66ORV.js} +8 -0
- package/chunks/{run-qwen-serve-3QSGRXAN.js → run-qwen-serve-UR3DYDAF.js} +49 -40
- package/chunks/{runtime-5MLLZ7DC.js → runtime-PR5RKGNH.js} +32 -31
- package/chunks/{scheduler-RPBJ63CH.js → scheduler-GPMLVKJM.js} +24 -23
- package/chunks/{sdk-exporters-http-XUVP63H6.js → sdk-exporters-http-NC746HLT.js} +2 -2
- package/chunks/{sdk-impl-YXUEN2Z2.js → sdk-impl-YVL7BP6Y.js} +2 -2
- package/chunks/{send-message-VZENRWRH.js → send-message-TNBG5EVA.js} +1 -1
- package/chunks/{serve-HS3XLPXU.js → serve-E7V2JVA2.js} +29 -30
- package/chunks/{server-TC4A7AAZ.js → server-YXB3DBN7.js} +1267 -165
- package/chunks/{session-UBOFXVMN.js → session-DZEAUT7S.js} +60 -58
- package/chunks/{settings-D5644OM5.js → settings-ESZ3NWAP.js} +28 -27
- package/chunks/{shell-3PZULQQV.js → shell-JMSK5WIL.js} +22 -21
- package/chunks/{skill-PEVVXQ3L.js → skill-5K5CSUJV.js} +11 -9
- package/chunks/{skill-settings-J65JKKES.js → skill-settings-V64NIOTI.js} +28 -27
- package/chunks/{spawnChannel-IYGXRHSQ.js → spawnChannel-S63APBZZ.js} +24 -23
- package/chunks/{standalone-update-IFM53PE7.js → standalone-update-P42HDFXX.js} +24 -23
- package/chunks/{startInteractiveUI-3AVH7L6H.js → startInteractiveUI-LFBLFHJ4.js} +262 -191
- package/chunks/{task-create-FCBDX7UH.js → task-create-EILHJJB7.js} +4 -4
- package/chunks/{task-list-YIYIUFUA.js → task-list-WGJR6YL5.js} +18 -4
- package/chunks/{task-update-MYPFVOVM.js → task-update-XZAHVXJ5.js} +79 -8
- package/chunks/{team-create-ZAIA7KAV.js → team-create-EDNOUM2U.js} +23 -23
- package/chunks/{team-delete-6UMU4XLS.js → team-delete-UEP4QOOT.js} +3 -3
- package/chunks/{team-plan-approval-UNIUS7OD.js → team-plan-approval-QRSNK2DX.js} +22 -21
- package/chunks/{terminal-image-renderer-G343P2RV.js → terminal-image-renderer-6J2NPL32.js} +22 -21
- package/chunks/{theme-manager-Z3RIT7DB.js → theme-manager-WJMLRBXS.js} +22 -21
- package/chunks/{todoWrite-U2R4NVF4.js → todoWrite-ATS62CAP.js} +1 -1
- package/chunks/{tool-search-5R2OE4C7.js → tool-search-MZ6WU7DM.js} +9 -7
- package/chunks/{total-session-admission-4KBHMQQ2.js → total-session-admission-DQVW2LIP.js} +26 -25
- package/chunks/{trustedFolders-LK6T4XC7.js → trustedFolders-QMH25GOX.js} +23 -22
- package/chunks/{update-relaunch-UBKROIC6.js → update-relaunch-EG75LLW5.js} +5 -5
- package/chunks/{updateCheck-W4Y2GFSD.js → updateCheck-MTZIVGT5.js} +25 -24
- package/chunks/{useAutoAcceptIndicator-C7BEICBF.js → useAutoAcceptIndicator-IGCW5EPO.js} +31 -30
- package/chunks/{validateNonInterActiveAuth-LTEI2TB6.js → validateNonInterActiveAuth-D5FPAB2C.js} +56 -54
- package/chunks/{version-G5A5DGVS.js → version-UOLDLLRB.js} +1 -1
- package/chunks/{web-fetch-RTEQTR5Z.js → web-fetch-QKKW6CWH.js} +11 -8
- package/chunks/{web-search-5OXHEZPV.js → web-search-JYRBZMCW.js} +2 -2
- package/chunks/{workflow-ISQJHPG2.js → workflow-SR7SEAU7.js} +139 -37
- package/chunks/{workspace-providers-status-2ZPZPUPZ.js → workspace-providers-status-OXGV4EFF.js} +32 -31
- package/chunks/{workspace-registration-store-CYNY6IP6.js → workspace-registration-store-V5EGKLBH.js} +1 -1
- package/chunks/{workspace-registry-34GTUUHB.js → workspace-registry-KJVIYTF5.js} +26 -25
- package/chunks/{workspace-service-XCDQLE2Y.js → workspace-service-6RLSGUB5.js} +33 -32
- package/chunks/{workspace-skills-status-RS4O7AIJ.js → workspace-skills-status-BHFEPDGH.js} +30 -29
- package/chunks/{workspace-trust-reconciler-AYGXC7A3.js → workspace-trust-reconciler-DB5ERSUN.js} +33 -32
- package/chunks/{write-file-EWXKVVXF.js → write-file-IUP4GTZ4.js} +22 -21
- package/chunks/{zh-TW-SQ4HTSCW.js → zh-TW-LVLBK4KF.js} +8 -0
- package/chunks/{zh-LMSTK4WD.js → zh-UBMWS2BJ.js} +8 -0
- package/chunks/{zoom-image-4BFYJ3HG.js → zoom-image-SRBDTIVA.js} +14 -11
- package/cli.js +13 -13
- package/locales/ca.js +13 -0
- package/locales/de.js +12 -0
- package/locales/en.js +11 -0
- package/locales/fr.js +13 -0
- package/locales/ja.js +13 -0
- package/locales/pt.js +12 -0
- package/locales/ru.js +12 -0
- package/locales/zh-TW.js +11 -0
- package/locales/zh.js +11 -0
- package/package.json +3 -3
- package/web-shell/assets/{arc-CgOpDKvm.js → arc-DItbX0DI.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-0Ag_m34F.js → architectureDiagram-3BPJPVTR-CmnIlH8y.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-IwTwFau0.js → blockDiagram-GPEHLZMM-pObnB9kw.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-DLa5GUv8.js → c4Diagram-AAUBKEIU-BNBmMS0Y.js} +1 -1
- package/web-shell/assets/channel-hZnMfWA9.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-DcYP-WFG.js → chunk-2J33WTMH-Dz4JBOO6.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-C8MVPMiQ.js → chunk-4BX2VUAB-Cz2GnvAR.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-BUi4Yfv3.js → chunk-55IACEB6-CC6kOQYx.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-Cy3Su2YY.js → chunk-727SXJPM-Z4lY4gbh.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-Dp8Teqv6.js → chunk-AQP2D5EJ-Yz0hZr3D.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-BDTDM-4j.js → chunk-FMBD7UC4-nKmTWTv9.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-7HfDt0r2.js → chunk-ND2GUHAM-CjZz0f6Y.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-BIBU0uCF.js → chunk-QZHKN3VN-Bab3FpuS.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-BRnxm8DX.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BRnxm8DX.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-DRLdcg9p.js → cose-bilkent-S5V4N54A-BuSAGFox.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-DCCgDwqW.js → dagre-BM42HDAG-CRZXTg3g.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-CsBTBmk3.js → diagram-2AECGRRQ-BFx1Ayrz.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-C9qjH8Lt.js → diagram-5GNKFQAL-B2hMZ3gS.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-Brjs_lj2.js → diagram-KO2AKTUF-DKxAQLmc.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-DtiWCl_F.js → diagram-LMA3HP47-Bo1xGqVY.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-DmfKLkBT.js → diagram-OG6HWLK6-B9NG78d-.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-Bve_4deH.js → erDiagram-TEJ5UH35-DltQKiqQ.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-C2_kXCcV.js → flowDiagram-I6XJVG4X-5xXGmS4I.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-BSBIjiTF.js → ganttDiagram-6RSMTGT7-bhGL5n0l.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-CyebwI55.js → gitGraphDiagram-PVQCEYII-ZYnz9hgh.js} +1 -1
- package/web-shell/assets/{index-d0yfnV1M.js → index-CBBeUArD.js} +1 -1
- package/web-shell/assets/index-CbgU-jUo.css +5 -0
- package/web-shell/assets/index-_nhzXqab.js +1750 -0
- package/web-shell/assets/{infoDiagram-5YYISTIA-CSDGnWxU.js → infoDiagram-5YYISTIA-Cg-jamQf.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-BK4jU13p.js → ishikawaDiagram-YF4QCWOH-CcmvKlyq.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-D_W6j-oF.js → journeyDiagram-JHISSGLW-BRsOQZp1.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-C7xf-SdC.js → kanban-definition-UN3LZRKU-xW-dmEHK.js} +1 -1
- package/web-shell/assets/{linear-DQmzxpxd.js → linear-ClBfEZH2.js} +1 -1
- package/web-shell/assets/{mermaid.core-9P7AGOLG.js → mermaid.core-D65NDkzc.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-DgcgMyPk.js → mindmap-definition-RKZ34NQL-CyvFslYa.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-3wWGb9eG.js → pieDiagram-4H26LBE5-BwSefMyG.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-BeCXnQw9.js → quadrantDiagram-W4KKPZXB-GqBJspFS.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-Bi1UOHDz.js → requirementDiagram-4Y6WPE33-B137PlTJ.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-lrLUjjbb.js → sankeyDiagram-5OEKKPKP-maHkkt8i.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-BFuqKz6Q.js → sequenceDiagram-3UESZ5HK-DJ1mRaG3.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-8DemQLhu.js → stateDiagram-AJRCARHV-aRmP7Q4i.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-Db39gvZ_.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-uzEuVQXg.js → timeline-definition-PNZ67QCA-CIQ3BRPA.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-BQTeZ_-o.js → vennDiagram-CIIHVFJN-DR9VPd5h.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-B6yM5Im7.js → wardley-L42UT6IY-ZcfIbT4D.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-ChM8bmgn.js → wardleyDiagram-YWT4CUSO-D0jgPi4T.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-oNG6HyB1.js → xychartDiagram-2RQKCTM6-BGWU4s5o.js} +1 -1
- package/web-shell/index.html +2 -2
- package/chunks/chunk-MPHPFVKK.js +0 -48
- package/chunks/chunk-RLKC46YT.js +0 -3582
- package/chunks/chunk-UPDOZBWO.js +0 -358
- package/web-shell/assets/channel-BrGVBa2L.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-B5TUzJzI.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-B5TUzJzI.js +0 -1
- package/web-shell/assets/index-CIDsgxTe.js +0 -1792
- package/web-shell/assets/index-DiQnWi_E.css +0 -5
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DhM5ixYd.js +0 -1
- /package/chunks/{chunk-NTTBXH7U.js → chunk-UGK4K2N2.js} +0 -0
package/chunks/chunk-RLKC46YT.js
DELETED
|
@@ -1,3582 +0,0 @@
|
|
|
1
|
-
// Force strict mode and setup for ESM
|
|
2
|
-
"use strict";
|
|
3
|
-
import {
|
|
4
|
-
sanitizeTerminalText
|
|
5
|
-
} from "./chunk-4NFY2S7N.js";
|
|
6
|
-
import {
|
|
7
|
-
formatHistoryGapNotice
|
|
8
|
-
} from "./chunk-3U3VAL47.js";
|
|
9
|
-
import {
|
|
10
|
-
loadUndici
|
|
11
|
-
} from "./chunk-3Z43GZUQ.js";
|
|
12
|
-
import {
|
|
13
|
-
projectGoalStateToLegacy
|
|
14
|
-
} from "./chunk-4S5337WV.js";
|
|
15
|
-
import {
|
|
16
|
-
parseGoalSnapshotV2,
|
|
17
|
-
parseGoalStateCause,
|
|
18
|
-
projectUserTranscriptForDisplay
|
|
19
|
-
} from "./chunk-OMLJNPBE.js";
|
|
20
|
-
import {
|
|
21
|
-
formatVisionBridgeNoticeDisplay,
|
|
22
|
-
isVisionBridgeNoticeDisplay
|
|
23
|
-
} from "./chunk-RVOJ2FBP.js";
|
|
24
|
-
import {
|
|
25
|
-
ToolNames
|
|
26
|
-
} from "./chunk-6HY6IF3Z.js";
|
|
27
|
-
import {
|
|
28
|
-
createDebugLogger
|
|
29
|
-
} from "./chunk-BUQDLC2G.js";
|
|
30
|
-
import {
|
|
31
|
-
writeStderrLine,
|
|
32
|
-
writeStderrLineSafe
|
|
33
|
-
} from "./chunk-KGJGEEVR.js";
|
|
34
|
-
import {
|
|
35
|
-
init_esbuild_shims
|
|
36
|
-
} from "./chunk-5O2XNYP6.js";
|
|
37
|
-
import {
|
|
38
|
-
__name
|
|
39
|
-
} from "./chunk-J2S4EL5Y.js";
|
|
40
|
-
|
|
41
|
-
// packages/cli/src/acp-integration/session/history-replayer.ts
|
|
42
|
-
init_esbuild_shims();
|
|
43
|
-
|
|
44
|
-
// packages/acp-bridge/src/transcript-replay.ts
|
|
45
|
-
init_esbuild_shims();
|
|
46
|
-
|
|
47
|
-
// packages/core/dist/src/goals/goal-wire.js
|
|
48
|
-
init_esbuild_shims();
|
|
49
|
-
|
|
50
|
-
// packages/core/dist/src/goals/goal-protocol.js
|
|
51
|
-
init_esbuild_shims();
|
|
52
|
-
var GOAL_STATE_VERSION = 2;
|
|
53
|
-
var GOAL_CHECKPOINT_CLAIM_LIMIT = 32;
|
|
54
|
-
var GOAL_CHECKPOINT_CLAIM_MAX_CHARACTERS = 2e3;
|
|
55
|
-
var GOAL_CHECKPOINT_CLAIM_MAX_BYTES = 16e3;
|
|
56
|
-
var GOAL_CHECKPOINT_SOURCE_REFERENCE_LIMIT = 32;
|
|
57
|
-
function isGoalLimitKind(value) {
|
|
58
|
-
return value === "evidence_catalog" || value === "checkpoint_request";
|
|
59
|
-
}
|
|
60
|
-
__name(isGoalLimitKind, "isGoalLimitKind");
|
|
61
|
-
function isGoalEvidenceProofKind(value) {
|
|
62
|
-
return value === "user_input" || value === "delivered_output" || value === "external_fact";
|
|
63
|
-
}
|
|
64
|
-
__name(isGoalEvidenceProofKind, "isGoalEvidenceProofKind");
|
|
65
|
-
|
|
66
|
-
// packages/core/dist/src/goals/goal-reducer.js
|
|
67
|
-
init_esbuild_shims();
|
|
68
|
-
var MAX_BLOCKED_AUDIT_COUNT = 3;
|
|
69
|
-
function parseGoalStateRecordPayloadV2(value) {
|
|
70
|
-
if (!isRecord(value) || !hasOnlyKeys(value, [
|
|
71
|
-
"v",
|
|
72
|
-
"cause",
|
|
73
|
-
"snapshot",
|
|
74
|
-
"checkpointPending",
|
|
75
|
-
"blockedAudit"
|
|
76
|
-
]) || value["v"] !== GOAL_STATE_VERSION || !isGoalStateCause(value["cause"]) || !isCheckpointPending(value["checkpointPending"]) || !isBlockedAudit(value["blockedAudit"])) {
|
|
77
|
-
return void 0;
|
|
78
|
-
}
|
|
79
|
-
const parsedSnapshot = parseGoalSnapshotV22(value["snapshot"]);
|
|
80
|
-
if (parsedSnapshot?.activity !== "idle")
|
|
81
|
-
return void 0;
|
|
82
|
-
const checkpointPending = value["checkpointPending"];
|
|
83
|
-
if (checkpointPending && (parsedSnapshot.goal?.status !== "active" || checkpointPending.permit.goalId !== parsedSnapshot.goal.goalId || checkpointPending.permit.revision !== parsedSnapshot.goal.revision || checkpointPending.recordUuid === parsedSnapshot.goal.evidenceCursor.recordId || value["cause"] !== "turn_finished" && value["cause"] !== "verifier_reject")) {
|
|
84
|
-
return void 0;
|
|
85
|
-
}
|
|
86
|
-
return {
|
|
87
|
-
v: GOAL_STATE_VERSION,
|
|
88
|
-
cause: value["cause"],
|
|
89
|
-
snapshot: parsedSnapshot,
|
|
90
|
-
...checkpointPending ? { checkpointPending: structuredClone(checkpointPending) } : {},
|
|
91
|
-
...value["blockedAudit"] ? { blockedAudit: structuredClone(value["blockedAudit"]) } : {}
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
__name(parseGoalStateRecordPayloadV2, "parseGoalStateRecordPayloadV2");
|
|
95
|
-
function parseGoalSnapshotV22(value) {
|
|
96
|
-
if (!isRecord(value) || !hasOnlyKeys(value, ["v", "goal", "activity"]) || value["v"] !== GOAL_STATE_VERSION || !isGoalActivity(value["activity"])) {
|
|
97
|
-
return void 0;
|
|
98
|
-
}
|
|
99
|
-
if (value["goal"] === null) {
|
|
100
|
-
return {
|
|
101
|
-
v: GOAL_STATE_VERSION,
|
|
102
|
-
goal: null,
|
|
103
|
-
activity: value["activity"]
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
const goal = parseGoalRecord(value["goal"]);
|
|
107
|
-
return goal ? { v: GOAL_STATE_VERSION, goal, activity: value["activity"] } : void 0;
|
|
108
|
-
}
|
|
109
|
-
__name(parseGoalSnapshotV22, "parseGoalSnapshotV2");
|
|
110
|
-
function parseGoalStateCause2(value) {
|
|
111
|
-
return isGoalStateCause(value) ? value : void 0;
|
|
112
|
-
}
|
|
113
|
-
__name(parseGoalStateCause2, "parseGoalStateCause");
|
|
114
|
-
function copyCursor(cursor) {
|
|
115
|
-
return { recordId: cursor.recordId };
|
|
116
|
-
}
|
|
117
|
-
__name(copyCursor, "copyCursor");
|
|
118
|
-
function parseGoalRecord(value) {
|
|
119
|
-
if (!isRecord(value) || !hasOnlyKeys(value, [
|
|
120
|
-
"goalId",
|
|
121
|
-
"revision",
|
|
122
|
-
"objective",
|
|
123
|
-
"status",
|
|
124
|
-
"evidenceCursor",
|
|
125
|
-
"turnCount",
|
|
126
|
-
"activeTimeMs",
|
|
127
|
-
"createdAt",
|
|
128
|
-
"updatedAt",
|
|
129
|
-
"evidenceCheckpoint",
|
|
130
|
-
"lastReason",
|
|
131
|
-
"limitKind"
|
|
132
|
-
]) || typeof value["goalId"] !== "string" || !value["goalId"] || !isNonNegativeInteger(value["revision"]) || value["revision"] === 0 || typeof value["objective"] !== "string" || !value["objective"].trim() || !isGoalStatus(value["status"]) || !isTranscriptCursor(value["evidenceCursor"]) || !isNonNegativeInteger(value["turnCount"]) || !isNonNegativeNumber(value["activeTimeMs"]) || !isFiniteNumber(value["createdAt"]) || !isFiniteNumber(value["updatedAt"]) || !isGoalEvidenceCheckpoint(value["evidenceCheckpoint"]) || value["lastReason"] !== void 0 && typeof value["lastReason"] !== "string" || value["limitKind"] !== void 0 && (!isGoalLimitKind(value["limitKind"]) || value["status"] !== "usage_limited")) {
|
|
133
|
-
return void 0;
|
|
134
|
-
}
|
|
135
|
-
if (value["evidenceCheckpoint"] && value["evidenceCursor"].recordId !== value["evidenceCheckpoint"].checkpointId) {
|
|
136
|
-
return void 0;
|
|
137
|
-
}
|
|
138
|
-
return {
|
|
139
|
-
goalId: value["goalId"],
|
|
140
|
-
revision: value["revision"],
|
|
141
|
-
objective: value["objective"],
|
|
142
|
-
status: value["status"],
|
|
143
|
-
evidenceCursor: copyCursor(value["evidenceCursor"]),
|
|
144
|
-
turnCount: value["turnCount"],
|
|
145
|
-
activeTimeMs: value["activeTimeMs"],
|
|
146
|
-
createdAt: value["createdAt"],
|
|
147
|
-
updatedAt: value["updatedAt"],
|
|
148
|
-
...value["evidenceCheckpoint"] === void 0 ? {} : {
|
|
149
|
-
evidenceCheckpoint: structuredClone(value["evidenceCheckpoint"])
|
|
150
|
-
},
|
|
151
|
-
...value["lastReason"] === void 0 ? {} : { lastReason: value["lastReason"] },
|
|
152
|
-
...value["limitKind"] === void 0 ? {} : { limitKind: value["limitKind"] }
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
__name(parseGoalRecord, "parseGoalRecord");
|
|
156
|
-
function isTranscriptCursor(value) {
|
|
157
|
-
return isRecord(value) && hasOnlyKeys(value, ["recordId"]) && (typeof value["recordId"] === "string" || value["recordId"] === null);
|
|
158
|
-
}
|
|
159
|
-
__name(isTranscriptCursor, "isTranscriptCursor");
|
|
160
|
-
function isGoalStatus(value) {
|
|
161
|
-
return value === "active" || value === "paused" || value === "blocked" || value === "usage_limited" || value === "complete";
|
|
162
|
-
}
|
|
163
|
-
__name(isGoalStatus, "isGoalStatus");
|
|
164
|
-
function isGoalActivity(value) {
|
|
165
|
-
return value === "idle" || value === "running" || value === "verifying";
|
|
166
|
-
}
|
|
167
|
-
__name(isGoalActivity, "isGoalActivity");
|
|
168
|
-
function isGoalStateCause(value) {
|
|
169
|
-
return value === "create" || value === "replace" || value === "edit" || value === "pause" || value === "resume" || value === "turn_finished" || value === "checkpoint" || value === "verifier_accept" || value === "verifier_reject" || value === "complete" || value === "blocked" || value === "usage_limited" || value === "clear" || value === "migrated";
|
|
170
|
-
}
|
|
171
|
-
__name(isGoalStateCause, "isGoalStateCause");
|
|
172
|
-
function isGoalEvidenceCheckpoint(value) {
|
|
173
|
-
if (value === void 0)
|
|
174
|
-
return true;
|
|
175
|
-
if (!isRecord(value) || !hasOnlyKeys(value, ["checkpointId", "createdAt", "claims"]) || typeof value["checkpointId"] !== "string" || value["checkpointId"].length === 0 || !isFiniteNumber(value["createdAt"]) || !Array.isArray(value["claims"]) || value["claims"].length === 0 || value["claims"].length > GOAL_CHECKPOINT_CLAIM_LIMIT) {
|
|
176
|
-
return false;
|
|
177
|
-
}
|
|
178
|
-
let checkpointBytes = 0;
|
|
179
|
-
for (const [index, claim] of value["claims"].entries()) {
|
|
180
|
-
if (!isRecord(claim) || !hasOnlyKeys(claim, ["id", "proofKind", "claim", "sourceRefs"]) || claim["id"] !== `${value["checkpointId"]}:${index + 1}` || !isGoalEvidenceProofKind(claim["proofKind"]) || typeof claim["claim"] !== "string" || claim["claim"].trim().length === 0 || [...claim["claim"]].length > GOAL_CHECKPOINT_CLAIM_MAX_CHARACTERS || !Array.isArray(claim["sourceRefs"]) || claim["sourceRefs"].length === 0 || claim["sourceRefs"].length > GOAL_CHECKPOINT_SOURCE_REFERENCE_LIMIT || new Set(claim["sourceRefs"]).size !== claim["sourceRefs"].length || claim["sourceRefs"].some((reference) => typeof reference !== "string" || reference.length === 0)) {
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
checkpointBytes += new TextEncoder().encode(claim["claim"]).byteLength;
|
|
184
|
-
if (checkpointBytes > GOAL_CHECKPOINT_CLAIM_MAX_BYTES)
|
|
185
|
-
return false;
|
|
186
|
-
}
|
|
187
|
-
return true;
|
|
188
|
-
}
|
|
189
|
-
__name(isGoalEvidenceCheckpoint, "isGoalEvidenceCheckpoint");
|
|
190
|
-
function isCheckpointPending(value) {
|
|
191
|
-
return value === void 0 || isRecord(value) && hasOnlyKeys(value, ["permit", "recordUuid"]) && isGoalTurnPermit(value["permit"]) && typeof value["recordUuid"] === "string" && value["recordUuid"].length > 0;
|
|
192
|
-
}
|
|
193
|
-
__name(isCheckpointPending, "isCheckpointPending");
|
|
194
|
-
function isGoalTurnPermit(value) {
|
|
195
|
-
return isRecord(value) && hasOnlyKeys(value, ["goalId", "revision", "turnId"]) && typeof value["goalId"] === "string" && value["goalId"].length > 0 && isNonNegativeInteger(value["revision"]) && value["revision"] > 0 && typeof value["turnId"] === "string" && value["turnId"].length > 0;
|
|
196
|
-
}
|
|
197
|
-
__name(isGoalTurnPermit, "isGoalTurnPermit");
|
|
198
|
-
function isBlockedAudit(value) {
|
|
199
|
-
return value === void 0 || isRecord(value) && hasOnlyKeys(value, ["fingerprint", "count", "turnIds"]) && typeof value["fingerprint"] === "string" && value["fingerprint"].length > 0 && isNonNegativeInteger(value["count"]) && value["count"] > 0 && value["count"] <= MAX_BLOCKED_AUDIT_COUNT && Array.isArray(value["turnIds"]) && value["turnIds"].length === value["count"] && value["turnIds"].every((turnId) => typeof turnId === "string" && turnId.length > 0);
|
|
200
|
-
}
|
|
201
|
-
__name(isBlockedAudit, "isBlockedAudit");
|
|
202
|
-
function isRecord(value) {
|
|
203
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
204
|
-
}
|
|
205
|
-
__name(isRecord, "isRecord");
|
|
206
|
-
function hasOnlyKeys(value, keys) {
|
|
207
|
-
return Object.keys(value).every((key) => keys.includes(key));
|
|
208
|
-
}
|
|
209
|
-
__name(hasOnlyKeys, "hasOnlyKeys");
|
|
210
|
-
function isNonNegativeInteger(value) {
|
|
211
|
-
return typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
212
|
-
}
|
|
213
|
-
__name(isNonNegativeInteger, "isNonNegativeInteger");
|
|
214
|
-
function isNonNegativeNumber(value) {
|
|
215
|
-
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
216
|
-
}
|
|
217
|
-
__name(isNonNegativeNumber, "isNonNegativeNumber");
|
|
218
|
-
function isFiniteNumber(value) {
|
|
219
|
-
return typeof value === "number" && Number.isFinite(value);
|
|
220
|
-
}
|
|
221
|
-
__name(isFiniteNumber, "isFiniteNumber");
|
|
222
|
-
|
|
223
|
-
// packages/core/dist/src/goals/goal-legacy-projection.js
|
|
224
|
-
init_esbuild_shims();
|
|
225
|
-
function projectGoalStateToLegacy2(payload, previousGoal = null) {
|
|
226
|
-
const snapshotGoal = payload.snapshot.goal;
|
|
227
|
-
const displayGoal = snapshotGoal ?? previousGoal;
|
|
228
|
-
const kind = legacyStatusKind(payload);
|
|
229
|
-
const goalStatus = {
|
|
230
|
-
type: "goal_status",
|
|
231
|
-
kind,
|
|
232
|
-
condition: displayGoal?.objective ?? "",
|
|
233
|
-
...displayGoal ? { iterations: displayGoal.turnCount } : {},
|
|
234
|
-
...displayGoal ? { setAt: displayGoal.createdAt } : {},
|
|
235
|
-
...displayGoal ? { durationMs: displayGoal.activeTimeMs } : {},
|
|
236
|
-
...displayGoal?.lastReason === void 0 ? {} : { lastReason: displayGoal.lastReason }
|
|
237
|
-
};
|
|
238
|
-
const terminalKind = kind === "achieved" || kind === "failed" || kind === "aborted" ? kind : void 0;
|
|
239
|
-
return {
|
|
240
|
-
activeGoal: snapshotGoal?.status === "active" ? {
|
|
241
|
-
condition: snapshotGoal.objective,
|
|
242
|
-
iterations: snapshotGoal.turnCount,
|
|
243
|
-
setAt: snapshotGoal.createdAt,
|
|
244
|
-
...snapshotGoal.lastReason === void 0 ? {} : { lastReason: snapshotGoal.lastReason }
|
|
245
|
-
} : null,
|
|
246
|
-
goalStatus,
|
|
247
|
-
goalTerminal: terminalKind && displayGoal ? {
|
|
248
|
-
kind: terminalKind,
|
|
249
|
-
condition: displayGoal.objective,
|
|
250
|
-
iterations: displayGoal.turnCount,
|
|
251
|
-
durationMs: displayGoal.activeTimeMs,
|
|
252
|
-
...displayGoal.lastReason === void 0 ? {} : { lastReason: displayGoal.lastReason }
|
|
253
|
-
} : null
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
__name(projectGoalStateToLegacy2, "projectGoalStateToLegacy");
|
|
257
|
-
function isGoalCheckpointBookkeepingTransition(previous, next) {
|
|
258
|
-
const previousGoal = previous?.goal;
|
|
259
|
-
const nextGoal = next.goal;
|
|
260
|
-
if (!previousGoal || !nextGoal)
|
|
261
|
-
return false;
|
|
262
|
-
return previousGoal.goalId === nextGoal.goalId && previousGoal.revision === nextGoal.revision && previousGoal.objective === nextGoal.objective && previousGoal.status === nextGoal.status && previousGoal.turnCount === nextGoal.turnCount && previousGoal.createdAt === nextGoal.createdAt && previousGoal.lastReason === nextGoal.lastReason;
|
|
263
|
-
}
|
|
264
|
-
__name(isGoalCheckpointBookkeepingTransition, "isGoalCheckpointBookkeepingTransition");
|
|
265
|
-
function isGoalCheckpointBookkeepingCause(cause, previousCause) {
|
|
266
|
-
if (cause === "checkpoint")
|
|
267
|
-
return true;
|
|
268
|
-
return cause === "verifier_reject" && (previousCause === "verifier_reject" || previousCause === "checkpoint");
|
|
269
|
-
}
|
|
270
|
-
__name(isGoalCheckpointBookkeepingCause, "isGoalCheckpointBookkeepingCause");
|
|
271
|
-
function isGoalCheckpointBookkeepingRecord(input) {
|
|
272
|
-
return isGoalCheckpointBookkeepingTransition(input.previous, input.next) && isGoalCheckpointBookkeepingCause(input.cause, input.previousCause);
|
|
273
|
-
}
|
|
274
|
-
__name(isGoalCheckpointBookkeepingRecord, "isGoalCheckpointBookkeepingRecord");
|
|
275
|
-
function legacyStatusKind(payload) {
|
|
276
|
-
switch (payload.cause) {
|
|
277
|
-
case "create":
|
|
278
|
-
case "replace":
|
|
279
|
-
case "edit":
|
|
280
|
-
case "resume":
|
|
281
|
-
return "set";
|
|
282
|
-
case "complete":
|
|
283
|
-
return "achieved";
|
|
284
|
-
case "clear":
|
|
285
|
-
return "cleared";
|
|
286
|
-
// A migrated goal is always persisted `paused` (`createMigratedGoalState`),
|
|
287
|
-
// and nothing drives a paused goal. Projecting it as `set` would re-assert
|
|
288
|
-
// "active" to every client that derives the live goal from the newest card,
|
|
289
|
-
// leaving a phantom running goal behind a resumed pre-v2 transcript.
|
|
290
|
-
case "migrated":
|
|
291
|
-
case "pause":
|
|
292
|
-
return "paused";
|
|
293
|
-
case "blocked":
|
|
294
|
-
case "usage_limited":
|
|
295
|
-
return "aborted";
|
|
296
|
-
case "turn_finished":
|
|
297
|
-
case "checkpoint":
|
|
298
|
-
case "verifier_accept":
|
|
299
|
-
case "verifier_reject":
|
|
300
|
-
return payload.snapshot.goal?.status === "complete" ? "achieved" : payload.snapshot.goal?.status === "blocked" || payload.snapshot.goal?.status === "usage_limited" ? "aborted" : "checking";
|
|
301
|
-
default:
|
|
302
|
-
return assertNever(payload.cause);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
__name(legacyStatusKind, "legacyStatusKind");
|
|
306
|
-
function assertNever(value) {
|
|
307
|
-
throw new Error(`Unsupported Goal state cause: ${String(value)}`);
|
|
308
|
-
}
|
|
309
|
-
__name(assertNever, "assertNever");
|
|
310
|
-
|
|
311
|
-
// packages/acp-bridge/src/transcript-replay.ts
|
|
312
|
-
var MISSING_TRANSCRIPT_TOOL_RESULT_MESSAGE = "Tool result missing from saved history; the previous run likely ended before this tool completed.";
|
|
313
|
-
var TRANSCRIPT_GOAL_STATUS_KINDS = /* @__PURE__ */ new Set([
|
|
314
|
-
"set",
|
|
315
|
-
"achieved",
|
|
316
|
-
"cleared",
|
|
317
|
-
"failed",
|
|
318
|
-
"aborted",
|
|
319
|
-
// A paused goal is not running, and dropping the card here is not neutral:
|
|
320
|
-
// the replay stream is what feeds the goal renderer, so the older `set` card
|
|
321
|
-
// stays newest and every surface keeps claiming autonomous work is under way.
|
|
322
|
-
// Kept in step with `GOAL_STATUS_KINDS`, which the daemon-side reader
|
|
323
|
-
// (`parseGoalStatusItem`) validates the same on-disk cards against.
|
|
324
|
-
"paused",
|
|
325
|
-
"checking"
|
|
326
|
-
]);
|
|
327
|
-
function isObjectRecord(value) {
|
|
328
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
329
|
-
}
|
|
330
|
-
__name(isObjectRecord, "isObjectRecord");
|
|
331
|
-
function replaceTextPartsForDisplay(parts, displayText) {
|
|
332
|
-
const projected = [];
|
|
333
|
-
let replacedText = false;
|
|
334
|
-
for (const part of parts ?? []) {
|
|
335
|
-
if (isObjectRecord(part) && typeof part["text"] === "string") {
|
|
336
|
-
if (!replacedText && displayText.length > 0) {
|
|
337
|
-
projected.push({ text: displayText });
|
|
338
|
-
}
|
|
339
|
-
replacedText = true;
|
|
340
|
-
} else {
|
|
341
|
-
projected.push(part);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
if (!replacedText && displayText.length > 0) {
|
|
345
|
-
projected.push({ text: displayText });
|
|
346
|
-
}
|
|
347
|
-
return projected;
|
|
348
|
-
}
|
|
349
|
-
__name(replaceTextPartsForDisplay, "replaceTextPartsForDisplay");
|
|
350
|
-
function toTranscriptEpochMs(timestamp) {
|
|
351
|
-
if (typeof timestamp === "number") {
|
|
352
|
-
return Number.isFinite(timestamp) ? timestamp : void 0;
|
|
353
|
-
}
|
|
354
|
-
if (typeof timestamp !== "string") return void 0;
|
|
355
|
-
const epochMs = new Date(timestamp).getTime();
|
|
356
|
-
return Number.isFinite(epochMs) ? epochMs : void 0;
|
|
357
|
-
}
|
|
358
|
-
__name(toTranscriptEpochMs, "toTranscriptEpochMs");
|
|
359
|
-
function buildUpdateMeta(options) {
|
|
360
|
-
const timestamp = toTranscriptEpochMs(options.timestamp);
|
|
361
|
-
const sourceRecordIds = dedupeStrings(options.sourceRecordIds ?? []);
|
|
362
|
-
const qwenTranscript = {
|
|
363
|
-
...sourceRecordIds.length > 0 ? { sourceRecordIds } : {},
|
|
364
|
-
...options.planToolCallId ? { planToolCallId: options.planToolCallId } : {}
|
|
365
|
-
};
|
|
366
|
-
const meta = {
|
|
367
|
-
...options.extra ?? {},
|
|
368
|
-
...timestamp !== void 0 ? { timestamp } : {},
|
|
369
|
-
...Object.keys(qwenTranscript).length > 0 ? { qwenTranscript } : {}
|
|
370
|
-
};
|
|
371
|
-
return Object.keys(meta).length > 0 ? meta : void 0;
|
|
372
|
-
}
|
|
373
|
-
__name(buildUpdateMeta, "buildUpdateMeta");
|
|
374
|
-
function createTranscriptMessageUpdate(options) {
|
|
375
|
-
const meta = buildUpdateMeta(options);
|
|
376
|
-
return {
|
|
377
|
-
sessionUpdate: options.role === "user" ? "user_message_chunk" : options.thought ? "agent_thought_chunk" : "agent_message_chunk",
|
|
378
|
-
content: { type: "text", text: options.text },
|
|
379
|
-
...meta ? { _meta: meta } : {}
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
|
-
__name(createTranscriptMessageUpdate, "createTranscriptMessageUpdate");
|
|
383
|
-
function createTranscriptImageUpdate(options) {
|
|
384
|
-
const meta = buildUpdateMeta(options);
|
|
385
|
-
return {
|
|
386
|
-
sessionUpdate: "user_message_chunk",
|
|
387
|
-
content: { type: "image", data: options.data, mimeType: options.mimeType },
|
|
388
|
-
...meta ? { _meta: meta } : {}
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
__name(createTranscriptImageUpdate, "createTranscriptImageUpdate");
|
|
392
|
-
function createTranscriptUsageUpdate(usageMetadata, options = {}) {
|
|
393
|
-
const usage = {
|
|
394
|
-
inputTokens: finiteNumber(usageMetadata.promptTokenCount) ?? 0,
|
|
395
|
-
outputTokens: finiteNumber(usageMetadata.candidatesTokenCount) ?? 0,
|
|
396
|
-
totalTokens: finiteNumber(usageMetadata.totalTokenCount) ?? 0,
|
|
397
|
-
...finiteNumber(usageMetadata.thoughtsTokenCount) !== void 0 ? { thoughtTokens: finiteNumber(usageMetadata.thoughtsTokenCount) } : {},
|
|
398
|
-
...finiteNumber(usageMetadata.cachedContentTokenCount) !== void 0 ? {
|
|
399
|
-
cachedReadTokens: finiteNumber(usageMetadata.cachedContentTokenCount)
|
|
400
|
-
} : {}
|
|
401
|
-
};
|
|
402
|
-
const meta = buildUpdateMeta({
|
|
403
|
-
...options,
|
|
404
|
-
extra: { usage, ...options.extra ?? {} }
|
|
405
|
-
});
|
|
406
|
-
return {
|
|
407
|
-
sessionUpdate: "agent_message_chunk",
|
|
408
|
-
content: { type: "text", text: options.text ?? "" },
|
|
409
|
-
_meta: meta
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
__name(createTranscriptUsageUpdate, "createTranscriptUsageUpdate");
|
|
413
|
-
function createTranscriptToolCallStartUpdate(options) {
|
|
414
|
-
const provenance = resolveToolProvenance(options.toolName);
|
|
415
|
-
return {
|
|
416
|
-
sessionUpdate: options.asUpdate ? "tool_call_update" : "tool_call",
|
|
417
|
-
toolCallId: options.callId,
|
|
418
|
-
status: options.status ?? "pending",
|
|
419
|
-
title: options.metadata.title,
|
|
420
|
-
content: [],
|
|
421
|
-
locations: [...options.metadata.locations],
|
|
422
|
-
kind: options.metadata.kind,
|
|
423
|
-
rawInput: options.args ?? {},
|
|
424
|
-
_meta: buildUpdateMeta({
|
|
425
|
-
...options,
|
|
426
|
-
extra: {
|
|
427
|
-
toolName: options.toolName,
|
|
428
|
-
provenance: provenance.provenance,
|
|
429
|
-
...provenance.serverId ? { serverId: provenance.serverId } : {},
|
|
430
|
-
...options.extra ?? {}
|
|
431
|
-
}
|
|
432
|
-
})
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
__name(createTranscriptToolCallStartUpdate, "createTranscriptToolCallStartUpdate");
|
|
436
|
-
function createTranscriptToolCallResultUpdate(options) {
|
|
437
|
-
const provenance = resolveToolProvenance(options.toolName);
|
|
438
|
-
const content = buildToolResultContent(options);
|
|
439
|
-
const update = {
|
|
440
|
-
sessionUpdate: "tool_call_update",
|
|
441
|
-
toolCallId: options.callId,
|
|
442
|
-
status: options.success ? "completed" : "failed",
|
|
443
|
-
content,
|
|
444
|
-
_meta: buildUpdateMeta({
|
|
445
|
-
...options,
|
|
446
|
-
extra: {
|
|
447
|
-
toolName: options.toolName,
|
|
448
|
-
provenance: provenance.provenance,
|
|
449
|
-
...provenance.serverId ? { serverId: provenance.serverId } : {},
|
|
450
|
-
...options.artifacts && options.artifacts.length > 0 ? { artifacts: options.artifacts } : {},
|
|
451
|
-
...options.extra ?? {}
|
|
452
|
-
}
|
|
453
|
-
})
|
|
454
|
-
};
|
|
455
|
-
if (options.resultDisplay !== void 0 && !isTruncatedSessionDiffDisplay(options.resultDisplay)) {
|
|
456
|
-
update["rawOutput"] = options.resultDisplay;
|
|
457
|
-
}
|
|
458
|
-
return update;
|
|
459
|
-
}
|
|
460
|
-
__name(createTranscriptToolCallResultUpdate, "createTranscriptToolCallResultUpdate");
|
|
461
|
-
function createTranscriptPlanUpdate(todos, cumulativeUsage, options = {}) {
|
|
462
|
-
const meta = buildUpdateMeta({
|
|
463
|
-
...options,
|
|
464
|
-
extra: {
|
|
465
|
-
...cumulativeUsage ? { stats: { ...cumulativeUsage } } : {},
|
|
466
|
-
...options.todoPlanId ? { qwenTodoPlan: { id: options.todoPlanId } } : {},
|
|
467
|
-
...options.extra ?? {}
|
|
468
|
-
}
|
|
469
|
-
});
|
|
470
|
-
return {
|
|
471
|
-
sessionUpdate: "plan",
|
|
472
|
-
entries: todos.map((todo) => ({
|
|
473
|
-
content: todo.content,
|
|
474
|
-
priority: "medium",
|
|
475
|
-
status: todo.status,
|
|
476
|
-
...todo.id || todo.blockedBy ? {
|
|
477
|
-
_meta: {
|
|
478
|
-
qwenTodo: {
|
|
479
|
-
...todo.id ? { id: todo.id } : {},
|
|
480
|
-
...todo.blockedBy ? { blockedBy: [...todo.blockedBy] } : {}
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
} : {}
|
|
484
|
-
})),
|
|
485
|
-
...meta ? { _meta: meta } : {}
|
|
486
|
-
};
|
|
487
|
-
}
|
|
488
|
-
__name(createTranscriptPlanUpdate, "createTranscriptPlanUpdate");
|
|
489
|
-
function extractTranscriptTodoPlan(resultDisplay, args) {
|
|
490
|
-
const fromDisplay = extractTodoPlanFromDisplay(resultDisplay);
|
|
491
|
-
if (fromDisplay) return fromDisplay;
|
|
492
|
-
if (resultDisplay !== null && resultDisplay !== void 0) return null;
|
|
493
|
-
return args && Array.isArray(args["todos"]) ? { todos: normalizeTodos(args["todos"]) } : null;
|
|
494
|
-
}
|
|
495
|
-
__name(extractTranscriptTodoPlan, "extractTranscriptTodoPlan");
|
|
496
|
-
function createTranscriptReplayMachine(options = {}) {
|
|
497
|
-
return new DefaultTranscriptReplayMachine(options);
|
|
498
|
-
}
|
|
499
|
-
__name(createTranscriptReplayMachine, "createTranscriptReplayMachine");
|
|
500
|
-
var DefaultTranscriptReplayMachine = class {
|
|
501
|
-
constructor(options) {
|
|
502
|
-
this.options = options;
|
|
503
|
-
const initialState = parseInitialState(
|
|
504
|
-
options.initialState,
|
|
505
|
-
options.onDiagnostic
|
|
506
|
-
);
|
|
507
|
-
this.usage = { ...initialState.cumulativeUsage };
|
|
508
|
-
this.goalState = initialState.goalState;
|
|
509
|
-
this.goalCause = initialState.goalCause;
|
|
510
|
-
for (const pending of initialState.pendingToolCalls) {
|
|
511
|
-
this.pendingToolCalls.set(pending.callId, pending);
|
|
512
|
-
this.usedToolCallIds.add(pending.callId);
|
|
513
|
-
}
|
|
514
|
-
for (const gap of options.gaps ?? []) {
|
|
515
|
-
if (!this.gapByChild.has(gap.childUuid)) {
|
|
516
|
-
this.gapByChild.set(gap.childUuid, gap);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
static {
|
|
521
|
-
__name(this, "DefaultTranscriptReplayMachine");
|
|
522
|
-
}
|
|
523
|
-
pendingToolCalls = /* @__PURE__ */ new Map();
|
|
524
|
-
usedToolCallIds = /* @__PURE__ */ new Set();
|
|
525
|
-
gapByChild = /* @__PURE__ */ new Map();
|
|
526
|
-
usage;
|
|
527
|
-
finalized = false;
|
|
528
|
-
goalState;
|
|
529
|
-
goalCause;
|
|
530
|
-
*project(record) {
|
|
531
|
-
if (this.finalized) {
|
|
532
|
-
throw new Error(
|
|
533
|
-
"Cannot project records after transcript replay finalize."
|
|
534
|
-
);
|
|
535
|
-
}
|
|
536
|
-
let ordinal = 0;
|
|
537
|
-
const emit = /* @__PURE__ */ __name((update) => ({
|
|
538
|
-
sourceRecordId: record.uuid,
|
|
539
|
-
...record.timestamp ? { sourceTimestamp: record.timestamp } : {},
|
|
540
|
-
emissionOrdinal: ordinal++,
|
|
541
|
-
update
|
|
542
|
-
}), "emit");
|
|
543
|
-
const meta = {
|
|
544
|
-
timestamp: record.timestamp,
|
|
545
|
-
sourceRecordIds: [record.uuid],
|
|
546
|
-
...record.subtype === "realtime_message" ? {
|
|
547
|
-
extra: {
|
|
548
|
-
source: "realtime_voice",
|
|
549
|
-
qwenDiscreteMessage: true
|
|
550
|
-
}
|
|
551
|
-
} : {}
|
|
552
|
-
};
|
|
553
|
-
const gap = this.gapByChild.get(record.uuid);
|
|
554
|
-
if (gap) {
|
|
555
|
-
yield emit(
|
|
556
|
-
createTranscriptMessageUpdate({
|
|
557
|
-
role: "assistant",
|
|
558
|
-
text: this.formatGap(gap),
|
|
559
|
-
...meta,
|
|
560
|
-
extra: { qwenDiscreteMessage: true }
|
|
561
|
-
})
|
|
562
|
-
);
|
|
563
|
-
}
|
|
564
|
-
switch (record.type) {
|
|
565
|
-
case "user":
|
|
566
|
-
yield* this.projectUserRecord(record, emit, meta);
|
|
567
|
-
break;
|
|
568
|
-
case "assistant":
|
|
569
|
-
yield* this.projectAssistantRecord(record, emit, meta);
|
|
570
|
-
break;
|
|
571
|
-
case "tool_result":
|
|
572
|
-
yield* this.projectToolResult(record, emit, meta);
|
|
573
|
-
break;
|
|
574
|
-
case "system":
|
|
575
|
-
yield* this.projectSystemRecord(record, emit, meta);
|
|
576
|
-
break;
|
|
577
|
-
default:
|
|
578
|
-
this.report(
|
|
579
|
-
"unknown_record_or_part",
|
|
580
|
-
"Skipped an unknown transcript record type.",
|
|
581
|
-
record.uuid
|
|
582
|
-
);
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
*finalize() {
|
|
586
|
-
if (this.finalized) return;
|
|
587
|
-
this.finalized = true;
|
|
588
|
-
let ordinal = 0;
|
|
589
|
-
for (const pending of [...this.pendingToolCalls.values()]) {
|
|
590
|
-
this.pendingToolCalls.delete(pending.callId);
|
|
591
|
-
this.report(
|
|
592
|
-
"missing_tool_result",
|
|
593
|
-
"A transcript tool call has no persisted result.",
|
|
594
|
-
pending.sourceRecordId
|
|
595
|
-
);
|
|
596
|
-
yield {
|
|
597
|
-
sourceRecordId: pending.sourceRecordId,
|
|
598
|
-
...pending.sourceTimestamp ? { sourceTimestamp: pending.sourceTimestamp } : {},
|
|
599
|
-
emissionOrdinal: ordinal++,
|
|
600
|
-
update: createTranscriptToolCallResultUpdate({
|
|
601
|
-
toolName: pending.toolName,
|
|
602
|
-
callId: pending.callId,
|
|
603
|
-
success: false,
|
|
604
|
-
errorMessage: MISSING_TRANSCRIPT_TOOL_RESULT_MESSAGE,
|
|
605
|
-
timestamp: pending.sourceTimestamp,
|
|
606
|
-
sourceRecordIds: [pending.sourceRecordId]
|
|
607
|
-
})
|
|
608
|
-
};
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
snapshot() {
|
|
612
|
-
return {
|
|
613
|
-
v: 1,
|
|
614
|
-
pendingToolCalls: [...this.pendingToolCalls.values()].map((pending) => ({
|
|
615
|
-
...pending
|
|
616
|
-
})),
|
|
617
|
-
cumulativeUsage: { ...this.usage },
|
|
618
|
-
...this.goalState ? { goalState: this.goalState } : {},
|
|
619
|
-
...this.goalCause ? { goalCause: this.goalCause } : {}
|
|
620
|
-
};
|
|
621
|
-
}
|
|
622
|
-
*projectUserRecord(record, emit, meta) {
|
|
623
|
-
const payload = isObjectRecord(record.systemPayload) ? record.systemPayload : void 0;
|
|
624
|
-
if (record.subtype === "goal_runtime" || record.subtype === "notification" || record.subtype === "cron" || record.subtype === "mid_turn_user_message") {
|
|
625
|
-
const displayText = payload && typeof payload["displayText"] === "string" ? payload["displayText"] : void 0;
|
|
626
|
-
if (displayText) {
|
|
627
|
-
const isNotification = record.subtype === "notification";
|
|
628
|
-
const backgroundTask = payload && isObjectRecord(payload["backgroundTask"]) ? payload["backgroundTask"] : void 0;
|
|
629
|
-
yield emit(
|
|
630
|
-
createTranscriptMessageUpdate({
|
|
631
|
-
role: "user",
|
|
632
|
-
text: displayText,
|
|
633
|
-
...meta,
|
|
634
|
-
...isNotification ? {
|
|
635
|
-
extra: {
|
|
636
|
-
source: "background_notification",
|
|
637
|
-
qwenDiscreteMessage: true,
|
|
638
|
-
...backgroundTask ? { backgroundTask } : {}
|
|
639
|
-
}
|
|
640
|
-
} : record.subtype === "cron" ? { extra: { source: "cron" } } : {}
|
|
641
|
-
})
|
|
642
|
-
);
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
if (record.subtype !== "mid_turn_user_message") return;
|
|
646
|
-
}
|
|
647
|
-
const projection = projectUserTranscriptForDisplay(record);
|
|
648
|
-
if (projection.displayText !== void 0) {
|
|
649
|
-
yield* this.projectMessageParts(
|
|
650
|
-
record,
|
|
651
|
-
"user",
|
|
652
|
-
emit,
|
|
653
|
-
meta,
|
|
654
|
-
void 0,
|
|
655
|
-
replaceTextPartsForDisplay(
|
|
656
|
-
record.message?.parts,
|
|
657
|
-
projection.displayText
|
|
658
|
-
)
|
|
659
|
-
);
|
|
660
|
-
return;
|
|
661
|
-
}
|
|
662
|
-
yield* this.projectMessageParts(
|
|
663
|
-
record,
|
|
664
|
-
"user",
|
|
665
|
-
emit,
|
|
666
|
-
meta,
|
|
667
|
-
void 0,
|
|
668
|
-
projection.parts
|
|
669
|
-
);
|
|
670
|
-
}
|
|
671
|
-
*projectAssistantRecord(record, emit, meta) {
|
|
672
|
-
const usageMetadata = isObjectRecord(record.usageMetadata) ? record.usageMetadata : void 0;
|
|
673
|
-
let usageEmitted = false;
|
|
674
|
-
const takeUsageUpdate = /* @__PURE__ */ __name(() => {
|
|
675
|
-
if (!usageMetadata || usageEmitted) return void 0;
|
|
676
|
-
usageEmitted = true;
|
|
677
|
-
this.addUsage(usageMetadata);
|
|
678
|
-
return createTranscriptUsageUpdate(usageMetadata, meta);
|
|
679
|
-
}, "takeUsageUpdate");
|
|
680
|
-
yield* this.projectMessageParts(
|
|
681
|
-
record,
|
|
682
|
-
"assistant",
|
|
683
|
-
emit,
|
|
684
|
-
meta,
|
|
685
|
-
takeUsageUpdate
|
|
686
|
-
);
|
|
687
|
-
const trailingUsage = takeUsageUpdate();
|
|
688
|
-
if (trailingUsage) yield emit(trailingUsage);
|
|
689
|
-
}
|
|
690
|
-
*projectMessageParts(record, role, emit, meta, beforeToolCall, partsOverride) {
|
|
691
|
-
const parts = partsOverride ?? record.message?.parts;
|
|
692
|
-
if (!parts) return;
|
|
693
|
-
for (let partIndex = 0; partIndex < parts.length; partIndex += 1) {
|
|
694
|
-
const part = parts[partIndex];
|
|
695
|
-
if (!isObjectRecord(part)) {
|
|
696
|
-
this.report(
|
|
697
|
-
"malformed_part",
|
|
698
|
-
"Skipped a malformed transcript message part.",
|
|
699
|
-
record.uuid,
|
|
700
|
-
`message.parts[${partIndex}]`
|
|
701
|
-
);
|
|
702
|
-
continue;
|
|
703
|
-
}
|
|
704
|
-
let recognized = false;
|
|
705
|
-
if (typeof part["text"] === "string" && part["text"].length > 0) {
|
|
706
|
-
recognized = true;
|
|
707
|
-
yield emit(
|
|
708
|
-
createTranscriptMessageUpdate({
|
|
709
|
-
role,
|
|
710
|
-
text: part["text"],
|
|
711
|
-
thought: role === "assistant" && part["thought"] === true,
|
|
712
|
-
...meta
|
|
713
|
-
})
|
|
714
|
-
);
|
|
715
|
-
}
|
|
716
|
-
const inlineData = isObjectRecord(part["inlineData"]) ? part["inlineData"] : void 0;
|
|
717
|
-
if (inlineData) {
|
|
718
|
-
recognized = true;
|
|
719
|
-
const data = inlineData["data"];
|
|
720
|
-
const mimeType = inlineData["mimeType"];
|
|
721
|
-
if (role === "user" && typeof data === "string" && typeof mimeType === "string" && mimeType.startsWith("image/")) {
|
|
722
|
-
yield emit(createTranscriptImageUpdate({ data, mimeType, ...meta }));
|
|
723
|
-
} else {
|
|
724
|
-
this.report(
|
|
725
|
-
"malformed_part",
|
|
726
|
-
"Skipped an unsupported or malformed inline transcript part.",
|
|
727
|
-
record.uuid,
|
|
728
|
-
`message.parts[${partIndex}].inlineData`
|
|
729
|
-
);
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
const functionCall = isObjectRecord(part["functionCall"]) ? part["functionCall"] : void 0;
|
|
733
|
-
if (functionCall) {
|
|
734
|
-
recognized = true;
|
|
735
|
-
const toolName = typeof functionCall["name"] === "string" ? functionCall["name"] : "";
|
|
736
|
-
const args = isObjectRecord(functionCall["args"]) ? functionCall["args"] : {};
|
|
737
|
-
if (!toolName) {
|
|
738
|
-
this.report(
|
|
739
|
-
"malformed_part",
|
|
740
|
-
"Skipped a tool call without a tool name.",
|
|
741
|
-
record.uuid,
|
|
742
|
-
`message.parts[${partIndex}].functionCall`
|
|
743
|
-
);
|
|
744
|
-
continue;
|
|
745
|
-
}
|
|
746
|
-
const preToolUpdate = beforeToolCall?.();
|
|
747
|
-
if (preToolUpdate) yield emit(preToolUpdate);
|
|
748
|
-
if (toolName === "todo_write") continue;
|
|
749
|
-
const explicitId = typeof functionCall["id"] === "string" && functionCall["id"].length > 0 ? functionCall["id"] : void 0;
|
|
750
|
-
const callId = this.allocateToolCallId(
|
|
751
|
-
explicitId ?? `qwen-replay-tool:${record.uuid}:${partIndex}`
|
|
752
|
-
);
|
|
753
|
-
const update = createTranscriptToolCallStartUpdate({
|
|
754
|
-
toolName,
|
|
755
|
-
callId,
|
|
756
|
-
args,
|
|
757
|
-
status: "in_progress",
|
|
758
|
-
metadata: this.resolveToolMetadata(toolName, args, record.uuid),
|
|
759
|
-
...meta
|
|
760
|
-
});
|
|
761
|
-
yield emit(update);
|
|
762
|
-
if (role === "assistant") {
|
|
763
|
-
this.pendingToolCalls.set(callId, {
|
|
764
|
-
callId,
|
|
765
|
-
toolName,
|
|
766
|
-
sourceRecordId: record.uuid,
|
|
767
|
-
...record.timestamp ? { sourceTimestamp: record.timestamp } : {}
|
|
768
|
-
});
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
if (!recognized && !("functionResponse" in part)) {
|
|
772
|
-
this.report(
|
|
773
|
-
"unknown_record_or_part",
|
|
774
|
-
"Skipped an unknown transcript message part.",
|
|
775
|
-
record.uuid,
|
|
776
|
-
`message.parts[${partIndex}]`
|
|
777
|
-
);
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
*projectToolResult(record, emit, meta) {
|
|
782
|
-
const result = isObjectRecord(record.toolCallResult) ? record.toolCallResult : void 0;
|
|
783
|
-
const toolName = extractToolName(record);
|
|
784
|
-
if (!toolName) {
|
|
785
|
-
this.report(
|
|
786
|
-
"malformed_part",
|
|
787
|
-
"A transcript tool result has no tool name.",
|
|
788
|
-
record.uuid,
|
|
789
|
-
"message.parts"
|
|
790
|
-
);
|
|
791
|
-
}
|
|
792
|
-
const explicitCallId = extractToolResultCallId(record, result);
|
|
793
|
-
const callId = explicitCallId ? this.allocateToolCallId(explicitCallId, true) : this.correlateResultCallId(toolName, record.uuid);
|
|
794
|
-
this.pendingToolCalls.delete(callId);
|
|
795
|
-
const resultDisplay = result?.["resultDisplay"];
|
|
796
|
-
if (toolName === "todo_write") {
|
|
797
|
-
const plan = extractTranscriptTodoPlan(resultDisplay);
|
|
798
|
-
if (plan) {
|
|
799
|
-
yield emit(
|
|
800
|
-
createTranscriptPlanUpdate(plan.todos, this.usage, {
|
|
801
|
-
...meta,
|
|
802
|
-
planToolCallId: callId,
|
|
803
|
-
todoPlanId: plan.planId
|
|
804
|
-
})
|
|
805
|
-
);
|
|
806
|
-
}
|
|
807
|
-
return;
|
|
808
|
-
}
|
|
809
|
-
yield emit(
|
|
810
|
-
createTranscriptToolCallResultUpdate({
|
|
811
|
-
toolName,
|
|
812
|
-
callId,
|
|
813
|
-
success: result?.["status"] === void 0 ? !result?.["error"] : result["status"] === "success" && !result["error"],
|
|
814
|
-
errorMessage: extractErrorMessage(result?.["error"]),
|
|
815
|
-
message: record.message?.parts,
|
|
816
|
-
resultDisplay,
|
|
817
|
-
artifacts: Array.isArray(result?.["artifacts"]) ? result["artifacts"] : void 0,
|
|
818
|
-
contentPrefix: this.buildToolResultContentPrefix(
|
|
819
|
-
resultDisplay,
|
|
820
|
-
record.uuid
|
|
821
|
-
),
|
|
822
|
-
...meta
|
|
823
|
-
})
|
|
824
|
-
);
|
|
825
|
-
if (isTaskExecutionDisplay(resultDisplay)) {
|
|
826
|
-
const usage = usageFromTaskExecution(resultDisplay);
|
|
827
|
-
if (Object.keys(usage).length > 0) {
|
|
828
|
-
this.addUsage(usage);
|
|
829
|
-
yield emit(createTranscriptUsageUpdate(usage, meta));
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
*projectSystemRecord(record, emit, meta) {
|
|
834
|
-
if (record.subtype === "goal_state") {
|
|
835
|
-
const payload2 = parseGoalStateRecordPayloadV2(record.systemPayload);
|
|
836
|
-
if (!payload2) {
|
|
837
|
-
this.report(
|
|
838
|
-
"malformed_goal_state",
|
|
839
|
-
"Skipped a malformed Goal state transcript record.",
|
|
840
|
-
record.uuid,
|
|
841
|
-
"systemPayload"
|
|
842
|
-
);
|
|
843
|
-
return;
|
|
844
|
-
}
|
|
845
|
-
const bookkeepingOnly = isGoalCheckpointBookkeepingRecord({
|
|
846
|
-
cause: payload2.cause,
|
|
847
|
-
previousCause: this.goalCause,
|
|
848
|
-
previous: this.goalState,
|
|
849
|
-
next: payload2.snapshot
|
|
850
|
-
});
|
|
851
|
-
const projection = projectGoalStateToLegacy2(
|
|
852
|
-
payload2,
|
|
853
|
-
this.goalState?.goal ?? null
|
|
854
|
-
);
|
|
855
|
-
this.goalState = payload2.snapshot;
|
|
856
|
-
this.goalCause = payload2.cause;
|
|
857
|
-
if (bookkeepingOnly) return;
|
|
858
|
-
const { type: _type, ...goalStatus } = projection.goalStatus;
|
|
859
|
-
yield emit(
|
|
860
|
-
createTranscriptMessageUpdate({
|
|
861
|
-
role: "assistant",
|
|
862
|
-
text: "",
|
|
863
|
-
...meta,
|
|
864
|
-
extra: {
|
|
865
|
-
goalState: payload2.snapshot,
|
|
866
|
-
goalStatus,
|
|
867
|
-
...projection.goalTerminal ? { goalTerminal: projection.goalTerminal } : {},
|
|
868
|
-
"qwen.session.recordId": record.uuid
|
|
869
|
-
}
|
|
870
|
-
})
|
|
871
|
-
);
|
|
872
|
-
return;
|
|
873
|
-
}
|
|
874
|
-
if (record.subtype !== "slash_command") return;
|
|
875
|
-
const payload = isObjectRecord(record.systemPayload) ? record.systemPayload : void 0;
|
|
876
|
-
if (payload?.["phase"] !== "result") return;
|
|
877
|
-
const items = Array.isArray(payload["outputHistoryItems"]) ? payload["outputHistoryItems"] : [];
|
|
878
|
-
for (const item of items) {
|
|
879
|
-
const goalStatus = parseTranscriptGoalStatus(item);
|
|
880
|
-
if (goalStatus) {
|
|
881
|
-
if (goalStatus.condition.length === 0) {
|
|
882
|
-
this.report(
|
|
883
|
-
"malformed_part",
|
|
884
|
-
"Skipped replay of a goal card whose condition is empty.",
|
|
885
|
-
record.uuid,
|
|
886
|
-
"systemPayload.outputHistoryItems.goalStatus.condition"
|
|
887
|
-
);
|
|
888
|
-
} else if (goalStatus.kind !== "checking") {
|
|
889
|
-
yield emit(
|
|
890
|
-
createTranscriptMessageUpdate({
|
|
891
|
-
role: "assistant",
|
|
892
|
-
text: "",
|
|
893
|
-
...meta,
|
|
894
|
-
extra: { goalStatus }
|
|
895
|
-
})
|
|
896
|
-
);
|
|
897
|
-
}
|
|
898
|
-
continue;
|
|
899
|
-
}
|
|
900
|
-
if (!isObjectRecord(item) || typeof item["text"] !== "string") continue;
|
|
901
|
-
yield emit(
|
|
902
|
-
createTranscriptMessageUpdate({
|
|
903
|
-
role: "assistant",
|
|
904
|
-
text: item["text"].replace(/\n/g, " \n"),
|
|
905
|
-
...meta,
|
|
906
|
-
extra: { source: "slash_command" }
|
|
907
|
-
})
|
|
908
|
-
);
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
addUsage(metadata) {
|
|
912
|
-
this.usage.promptTokens += finiteNumber(metadata["promptTokenCount"]) ?? 0;
|
|
913
|
-
this.usage.candidateTokens += finiteNumber(metadata["candidatesTokenCount"]) ?? 0;
|
|
914
|
-
this.usage.cachedTokens += finiteNumber(metadata["cachedContentTokenCount"]) ?? 0;
|
|
915
|
-
}
|
|
916
|
-
correlateResultCallId(toolName, recordId) {
|
|
917
|
-
const candidates = [...this.pendingToolCalls.values()].filter(
|
|
918
|
-
(pending) => pending.toolName === toolName
|
|
919
|
-
);
|
|
920
|
-
if (candidates.length === 1) return candidates[0].callId;
|
|
921
|
-
this.report(
|
|
922
|
-
"ambiguous_tool_call_correlation",
|
|
923
|
-
"A tool result could not be matched to exactly one pending tool call.",
|
|
924
|
-
recordId
|
|
925
|
-
);
|
|
926
|
-
return this.allocateToolCallId(`qwen-replay-tool:${recordId}:result`);
|
|
927
|
-
}
|
|
928
|
-
allocateToolCallId(candidate, reuse = false) {
|
|
929
|
-
if (reuse && this.pendingToolCalls.has(candidate)) {
|
|
930
|
-
this.usedToolCallIds.add(candidate);
|
|
931
|
-
return candidate;
|
|
932
|
-
}
|
|
933
|
-
if (!this.usedToolCallIds.has(candidate)) {
|
|
934
|
-
this.usedToolCallIds.add(candidate);
|
|
935
|
-
return candidate;
|
|
936
|
-
}
|
|
937
|
-
let occurrence = 2;
|
|
938
|
-
while (this.usedToolCallIds.has(`${candidate}:${occurrence}`)) {
|
|
939
|
-
occurrence += 1;
|
|
940
|
-
}
|
|
941
|
-
const id = `${candidate}:${occurrence}`;
|
|
942
|
-
this.usedToolCallIds.add(id);
|
|
943
|
-
return id;
|
|
944
|
-
}
|
|
945
|
-
resolveToolMetadata(toolName, args, recordId) {
|
|
946
|
-
try {
|
|
947
|
-
return this.options.presentation?.resolveToolMetadata(toolName, args) ?? fallbackToolMetadata(toolName, args);
|
|
948
|
-
} catch {
|
|
949
|
-
this.report(
|
|
950
|
-
"presentation_fallback",
|
|
951
|
-
"Tool presentation metadata fell back to deterministic defaults.",
|
|
952
|
-
recordId,
|
|
953
|
-
void 0,
|
|
954
|
-
false
|
|
955
|
-
);
|
|
956
|
-
return fallbackToolMetadata(toolName, args);
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
formatGap(gap) {
|
|
960
|
-
try {
|
|
961
|
-
return this.options.presentation?.formatHistoryGap(gap) ?? "Some earlier messages are unavailable because the saved history is incomplete.";
|
|
962
|
-
} catch {
|
|
963
|
-
this.report(
|
|
964
|
-
"presentation_fallback",
|
|
965
|
-
"History gap presentation fell back to deterministic defaults.",
|
|
966
|
-
gap.childUuid,
|
|
967
|
-
void 0,
|
|
968
|
-
false
|
|
969
|
-
);
|
|
970
|
-
return "Some earlier messages are unavailable because the saved history is incomplete.";
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
buildToolResultContentPrefix(resultDisplay, recordId) {
|
|
974
|
-
try {
|
|
975
|
-
return this.options.presentation?.buildToolResultContentPrefix?.(
|
|
976
|
-
resultDisplay
|
|
977
|
-
) ?? defaultToolResultContentPrefix(resultDisplay);
|
|
978
|
-
} catch {
|
|
979
|
-
this.report(
|
|
980
|
-
"presentation_fallback",
|
|
981
|
-
"Tool result content presentation fell back to deterministic defaults.",
|
|
982
|
-
recordId,
|
|
983
|
-
void 0,
|
|
984
|
-
false
|
|
985
|
-
);
|
|
986
|
-
return defaultToolResultContentPrefix(resultDisplay);
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
report(code, message, recordId, path2, affectsCompleteness = true) {
|
|
990
|
-
this.options.onDiagnostic?.({
|
|
991
|
-
code,
|
|
992
|
-
severity: affectsCompleteness ? "warning" : "info",
|
|
993
|
-
message,
|
|
994
|
-
affectsCompleteness,
|
|
995
|
-
...recordId ? { recordId } : {},
|
|
996
|
-
...path2 ? { path: path2 } : {}
|
|
997
|
-
});
|
|
998
|
-
}
|
|
999
|
-
};
|
|
1000
|
-
function parseTranscriptGoalStatus(value) {
|
|
1001
|
-
if (!isObjectRecord(value) || value["type"] !== "goal_status") {
|
|
1002
|
-
return void 0;
|
|
1003
|
-
}
|
|
1004
|
-
const kind = value["kind"];
|
|
1005
|
-
const condition = value["condition"];
|
|
1006
|
-
if (typeof kind !== "string" || !TRANSCRIPT_GOAL_STATUS_KINDS.has(kind) || typeof condition !== "string") {
|
|
1007
|
-
return void 0;
|
|
1008
|
-
}
|
|
1009
|
-
const iterations = finiteNumber(value["iterations"]);
|
|
1010
|
-
const setAt = finiteNumber(value["setAt"]);
|
|
1011
|
-
const durationMs = finiteNumber(value["durationMs"]);
|
|
1012
|
-
const lastReason = typeof value["lastReason"] === "string" ? value["lastReason"] : void 0;
|
|
1013
|
-
return {
|
|
1014
|
-
kind,
|
|
1015
|
-
condition,
|
|
1016
|
-
...iterations !== void 0 ? { iterations } : {},
|
|
1017
|
-
...setAt !== void 0 ? { setAt } : {},
|
|
1018
|
-
...durationMs !== void 0 ? { durationMs } : {},
|
|
1019
|
-
...lastReason !== void 0 ? { lastReason } : {}
|
|
1020
|
-
};
|
|
1021
|
-
}
|
|
1022
|
-
__name(parseTranscriptGoalStatus, "parseTranscriptGoalStatus");
|
|
1023
|
-
function defaultToolResultContentPrefix(resultDisplay) {
|
|
1024
|
-
if (!isObjectRecord(resultDisplay) || resultDisplay["type"] !== "vision_bridge_notice" || typeof resultDisplay["summary"] !== "string" || typeof resultDisplay["notice"] !== "string") {
|
|
1025
|
-
return [];
|
|
1026
|
-
}
|
|
1027
|
-
return [
|
|
1028
|
-
{
|
|
1029
|
-
type: "content",
|
|
1030
|
-
content: {
|
|
1031
|
-
type: "text",
|
|
1032
|
-
text: `${resultDisplay["summary"]}
|
|
1033
|
-
${resultDisplay["notice"]}`
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
];
|
|
1037
|
-
}
|
|
1038
|
-
__name(defaultToolResultContentPrefix, "defaultToolResultContentPrefix");
|
|
1039
|
-
function parseInitialState(value, onDiagnostic) {
|
|
1040
|
-
const empty = {
|
|
1041
|
-
v: 1,
|
|
1042
|
-
pendingToolCalls: [],
|
|
1043
|
-
cumulativeUsage: emptyUsage()
|
|
1044
|
-
};
|
|
1045
|
-
if (value === void 0) return empty;
|
|
1046
|
-
if (!isObjectRecord(value)) {
|
|
1047
|
-
throw new TypeError("Invalid transcript replay state.");
|
|
1048
|
-
}
|
|
1049
|
-
if ("v" in value && value["v"] !== 1) {
|
|
1050
|
-
throw new TypeError("Unsupported transcript replay state version.");
|
|
1051
|
-
}
|
|
1052
|
-
const rawPending = Array.isArray(value["pendingToolCalls"]) ? value["pendingToolCalls"] : [];
|
|
1053
|
-
const pendingToolCalls = rawPending.flatMap(
|
|
1054
|
-
(pending) => {
|
|
1055
|
-
if (!isObjectRecord(pending) || typeof pending["callId"] !== "string" || typeof pending["toolName"] !== "string" || typeof pending["sourceRecordId"] !== "string") {
|
|
1056
|
-
onDiagnostic?.({
|
|
1057
|
-
code: "invalid_replay_state",
|
|
1058
|
-
severity: "warning",
|
|
1059
|
-
message: "Dropped a malformed pending tool call from replay state.",
|
|
1060
|
-
affectsCompleteness: true
|
|
1061
|
-
});
|
|
1062
|
-
return [];
|
|
1063
|
-
}
|
|
1064
|
-
return [
|
|
1065
|
-
{
|
|
1066
|
-
callId: pending["callId"],
|
|
1067
|
-
toolName: pending["toolName"],
|
|
1068
|
-
sourceRecordId: pending["sourceRecordId"],
|
|
1069
|
-
...typeof pending["sourceTimestamp"] === "string" ? { sourceTimestamp: pending["sourceTimestamp"] } : {}
|
|
1070
|
-
}
|
|
1071
|
-
];
|
|
1072
|
-
}
|
|
1073
|
-
);
|
|
1074
|
-
const rawUsage = value.cumulativeUsage;
|
|
1075
|
-
const usage = isObjectRecord(rawUsage) ? rawUsage : {};
|
|
1076
|
-
const validUsage = finiteNumber(usage["promptTokens"]) !== void 0 && finiteNumber(usage["cachedTokens"]) !== void 0 && finiteNumber(usage["candidateTokens"]) !== void 0 && finiteNumber(usage["apiTimeMs"]) !== void 0;
|
|
1077
|
-
if (!validUsage) {
|
|
1078
|
-
onDiagnostic?.({
|
|
1079
|
-
code: "invalid_replay_state",
|
|
1080
|
-
severity: "warning",
|
|
1081
|
-
message: "Reset invalid cumulative usage in transcript replay state.",
|
|
1082
|
-
affectsCompleteness: true
|
|
1083
|
-
});
|
|
1084
|
-
}
|
|
1085
|
-
const rawGoalState = value["goalState"];
|
|
1086
|
-
const goalState = rawGoalState === void 0 ? void 0 : parseGoalSnapshotV22(rawGoalState);
|
|
1087
|
-
if (rawGoalState !== void 0 && !goalState) {
|
|
1088
|
-
onDiagnostic?.({
|
|
1089
|
-
code: "invalid_replay_state",
|
|
1090
|
-
severity: "warning",
|
|
1091
|
-
message: "Dropped a malformed Goal state from replay state.",
|
|
1092
|
-
affectsCompleteness: true
|
|
1093
|
-
});
|
|
1094
|
-
}
|
|
1095
|
-
const rawGoalCause = value["goalCause"];
|
|
1096
|
-
const goalCause = rawGoalCause === void 0 ? void 0 : parseGoalStateCause2(rawGoalCause);
|
|
1097
|
-
if (rawGoalCause !== void 0 && !goalCause) {
|
|
1098
|
-
onDiagnostic?.({
|
|
1099
|
-
code: "invalid_replay_state",
|
|
1100
|
-
severity: "warning",
|
|
1101
|
-
message: "Dropped a malformed Goal cause from replay state.",
|
|
1102
|
-
affectsCompleteness: true
|
|
1103
|
-
});
|
|
1104
|
-
}
|
|
1105
|
-
return {
|
|
1106
|
-
v: 1,
|
|
1107
|
-
pendingToolCalls,
|
|
1108
|
-
cumulativeUsage: validUsage ? {
|
|
1109
|
-
promptTokens: usage["promptTokens"],
|
|
1110
|
-
cachedTokens: usage["cachedTokens"],
|
|
1111
|
-
candidateTokens: usage["candidateTokens"],
|
|
1112
|
-
apiTimeMs: usage["apiTimeMs"]
|
|
1113
|
-
} : emptyUsage(),
|
|
1114
|
-
...goalState ? { goalState } : {},
|
|
1115
|
-
...goalCause ? { goalCause } : {}
|
|
1116
|
-
};
|
|
1117
|
-
}
|
|
1118
|
-
__name(parseInitialState, "parseInitialState");
|
|
1119
|
-
function emptyUsage() {
|
|
1120
|
-
return {
|
|
1121
|
-
promptTokens: 0,
|
|
1122
|
-
cachedTokens: 0,
|
|
1123
|
-
candidateTokens: 0,
|
|
1124
|
-
apiTimeMs: 0
|
|
1125
|
-
};
|
|
1126
|
-
}
|
|
1127
|
-
__name(emptyUsage, "emptyUsage");
|
|
1128
|
-
function fallbackToolMetadata(toolName, args) {
|
|
1129
|
-
const description = typeof args["description"] === "string" ? args["description"].trim() : "";
|
|
1130
|
-
return {
|
|
1131
|
-
title: description ? `${toolName}: ${description}` : toolName,
|
|
1132
|
-
locations: [],
|
|
1133
|
-
kind: "other"
|
|
1134
|
-
};
|
|
1135
|
-
}
|
|
1136
|
-
__name(fallbackToolMetadata, "fallbackToolMetadata");
|
|
1137
|
-
function resolveToolProvenance(toolName) {
|
|
1138
|
-
if (toolName.startsWith("mcp__")) {
|
|
1139
|
-
const parts = toolName.split("__");
|
|
1140
|
-
if (parts.length >= 3 && parts[1]) {
|
|
1141
|
-
return { provenance: "mcp", serverId: parts[1] };
|
|
1142
|
-
}
|
|
1143
|
-
}
|
|
1144
|
-
return { provenance: "builtin" };
|
|
1145
|
-
}
|
|
1146
|
-
__name(resolveToolProvenance, "resolveToolProvenance");
|
|
1147
|
-
function buildToolResultContent(options) {
|
|
1148
|
-
const prefix = [...options.contentPrefix ?? []];
|
|
1149
|
-
const diff = extractDiffContent(options.resultDisplay);
|
|
1150
|
-
if (diff) return [...prefix, diff];
|
|
1151
|
-
if (options.errorMessage) {
|
|
1152
|
-
return [
|
|
1153
|
-
...prefix,
|
|
1154
|
-
{
|
|
1155
|
-
type: "content",
|
|
1156
|
-
content: { type: "text", text: options.errorMessage }
|
|
1157
|
-
}
|
|
1158
|
-
];
|
|
1159
|
-
}
|
|
1160
|
-
const content = [...prefix];
|
|
1161
|
-
for (const part of options.message ?? []) {
|
|
1162
|
-
if (!isObjectRecord(part)) continue;
|
|
1163
|
-
if (typeof part["text"] === "string" && part["text"]) {
|
|
1164
|
-
content.push({
|
|
1165
|
-
type: "content",
|
|
1166
|
-
content: { type: "text", text: part["text"] }
|
|
1167
|
-
});
|
|
1168
|
-
}
|
|
1169
|
-
const response = isObjectRecord(part["functionResponse"]) ? part["functionResponse"] : void 0;
|
|
1170
|
-
const payload = response && isObjectRecord(response["response"]) ? response["response"] : void 0;
|
|
1171
|
-
if (!payload) continue;
|
|
1172
|
-
try {
|
|
1173
|
-
const output = payload["output"];
|
|
1174
|
-
const error = payload["error"];
|
|
1175
|
-
const text = typeof output === "string" ? output : typeof error === "string" ? error : JSON.stringify(payload);
|
|
1176
|
-
content.push({
|
|
1177
|
-
type: "content",
|
|
1178
|
-
content: { type: "text", text }
|
|
1179
|
-
});
|
|
1180
|
-
} catch {
|
|
1181
|
-
}
|
|
1182
|
-
}
|
|
1183
|
-
return content;
|
|
1184
|
-
}
|
|
1185
|
-
__name(buildToolResultContent, "buildToolResultContent");
|
|
1186
|
-
function extractDiffContent(resultDisplay) {
|
|
1187
|
-
if (!isObjectRecord(resultDisplay)) return null;
|
|
1188
|
-
if (!("fileName" in resultDisplay) || !("newContent" in resultDisplay)) {
|
|
1189
|
-
return null;
|
|
1190
|
-
}
|
|
1191
|
-
if (isTruncatedSessionDiffDisplay(resultDisplay)) {
|
|
1192
|
-
return {
|
|
1193
|
-
type: "content",
|
|
1194
|
-
content: {
|
|
1195
|
-
type: "text",
|
|
1196
|
-
text: buildTruncatedDiffPreviewText(resultDisplay)
|
|
1197
|
-
}
|
|
1198
|
-
};
|
|
1199
|
-
}
|
|
1200
|
-
return {
|
|
1201
|
-
type: "diff",
|
|
1202
|
-
path: typeof resultDisplay["fileName"] === "string" ? resultDisplay["fileName"] : "",
|
|
1203
|
-
oldText: typeof resultDisplay["originalContent"] === "string" ? resultDisplay["originalContent"] : "",
|
|
1204
|
-
newText: typeof resultDisplay["newContent"] === "string" ? resultDisplay["newContent"] : ""
|
|
1205
|
-
};
|
|
1206
|
-
}
|
|
1207
|
-
__name(extractDiffContent, "extractDiffContent");
|
|
1208
|
-
function isTruncatedSessionDiffDisplay(value) {
|
|
1209
|
-
return isObjectRecord(value) && value["truncatedForSession"] === true && "fileName" in value && "newContent" in value;
|
|
1210
|
-
}
|
|
1211
|
-
__name(isTruncatedSessionDiffDisplay, "isTruncatedSessionDiffDisplay");
|
|
1212
|
-
function buildTruncatedDiffPreviewText(display) {
|
|
1213
|
-
const fileName = typeof display["fileName"] === "string" ? display["fileName"] : "the edited file";
|
|
1214
|
-
const fileDiffLength = typeof display["fileDiffLength"] === "number" ? ` Original fileDiff length: ${display["fileDiffLength"]} chars.` : "";
|
|
1215
|
-
return display["fileDiffTruncated"] === true ? `Full diff omitted from saved session history for ${fileName}.${fileDiffLength}` : `Saved session preview only for ${fileName}; full original and new file contents are unavailable.`;
|
|
1216
|
-
}
|
|
1217
|
-
__name(buildTruncatedDiffPreviewText, "buildTruncatedDiffPreviewText");
|
|
1218
|
-
function extractToolName(record) {
|
|
1219
|
-
for (const part of record.message?.parts ?? []) {
|
|
1220
|
-
if (!isObjectRecord(part) || !isObjectRecord(part["functionResponse"])) {
|
|
1221
|
-
continue;
|
|
1222
|
-
}
|
|
1223
|
-
const name = part["functionResponse"]["name"];
|
|
1224
|
-
if (typeof name === "string") return name;
|
|
1225
|
-
}
|
|
1226
|
-
return "";
|
|
1227
|
-
}
|
|
1228
|
-
__name(extractToolName, "extractToolName");
|
|
1229
|
-
function extractToolResultCallId(record, result) {
|
|
1230
|
-
if (typeof result?.["callId"] === "string" && result["callId"].length > 0) {
|
|
1231
|
-
return result["callId"];
|
|
1232
|
-
}
|
|
1233
|
-
for (const part of record.message?.parts ?? []) {
|
|
1234
|
-
if (!isObjectRecord(part) || !isObjectRecord(part["functionResponse"])) {
|
|
1235
|
-
continue;
|
|
1236
|
-
}
|
|
1237
|
-
const id = part["functionResponse"]["id"];
|
|
1238
|
-
if (typeof id === "string" && id.length > 0) return id;
|
|
1239
|
-
}
|
|
1240
|
-
return void 0;
|
|
1241
|
-
}
|
|
1242
|
-
__name(extractToolResultCallId, "extractToolResultCallId");
|
|
1243
|
-
function extractTodoPlanFromDisplay(value) {
|
|
1244
|
-
if (isObjectRecord(value) && value["type"] === "todo_list") {
|
|
1245
|
-
return Array.isArray(value["todos"]) ? {
|
|
1246
|
-
...typeof value["planId"] === "string" ? { planId: value["planId"] } : {},
|
|
1247
|
-
todos: normalizeTodos(value["todos"])
|
|
1248
|
-
} : null;
|
|
1249
|
-
}
|
|
1250
|
-
if (typeof value !== "string") return null;
|
|
1251
|
-
try {
|
|
1252
|
-
const parsed = JSON.parse(value);
|
|
1253
|
-
return isObjectRecord(parsed) && parsed["type"] === "todo_list" && Array.isArray(parsed["todos"]) ? {
|
|
1254
|
-
...typeof parsed["planId"] === "string" ? { planId: parsed["planId"] } : {},
|
|
1255
|
-
todos: normalizeTodos(parsed["todos"])
|
|
1256
|
-
} : null;
|
|
1257
|
-
} catch {
|
|
1258
|
-
return null;
|
|
1259
|
-
}
|
|
1260
|
-
}
|
|
1261
|
-
__name(extractTodoPlanFromDisplay, "extractTodoPlanFromDisplay");
|
|
1262
|
-
function normalizeTodos(values) {
|
|
1263
|
-
return values.flatMap((value) => {
|
|
1264
|
-
if (!isObjectRecord(value) || typeof value["content"] !== "string")
|
|
1265
|
-
return [];
|
|
1266
|
-
const status = value["status"];
|
|
1267
|
-
if (status !== "pending" && status !== "in_progress" && status !== "completed") {
|
|
1268
|
-
return [];
|
|
1269
|
-
}
|
|
1270
|
-
return [
|
|
1271
|
-
{
|
|
1272
|
-
...typeof value["id"] === "string" ? { id: value["id"] } : {},
|
|
1273
|
-
content: value["content"],
|
|
1274
|
-
status,
|
|
1275
|
-
...Array.isArray(value["blockedBy"]) && value["blockedBy"].every((dependency) => typeof dependency === "string") ? { blockedBy: value["blockedBy"] } : {}
|
|
1276
|
-
}
|
|
1277
|
-
];
|
|
1278
|
-
});
|
|
1279
|
-
}
|
|
1280
|
-
__name(normalizeTodos, "normalizeTodos");
|
|
1281
|
-
function isTaskExecutionDisplay(value) {
|
|
1282
|
-
return isObjectRecord(value) && value["type"] === "task_execution";
|
|
1283
|
-
}
|
|
1284
|
-
__name(isTaskExecutionDisplay, "isTaskExecutionDisplay");
|
|
1285
|
-
function usageFromTaskExecution(display) {
|
|
1286
|
-
const summary = isObjectRecord(display["executionSummary"]) ? display["executionSummary"] : void 0;
|
|
1287
|
-
if (!summary) return {};
|
|
1288
|
-
return {
|
|
1289
|
-
...finiteNumber(summary["inputTokens"]) !== void 0 ? { promptTokenCount: summary["inputTokens"] } : {},
|
|
1290
|
-
...finiteNumber(summary["outputTokens"]) !== void 0 ? { candidatesTokenCount: summary["outputTokens"] } : {},
|
|
1291
|
-
...finiteNumber(summary["thoughtTokens"]) !== void 0 ? { thoughtsTokenCount: summary["thoughtTokens"] } : {},
|
|
1292
|
-
...finiteNumber(summary["cachedTokens"]) !== void 0 ? { cachedContentTokenCount: summary["cachedTokens"] } : {},
|
|
1293
|
-
...finiteNumber(summary["totalTokens"]) !== void 0 ? { totalTokenCount: summary["totalTokens"] } : {}
|
|
1294
|
-
};
|
|
1295
|
-
}
|
|
1296
|
-
__name(usageFromTaskExecution, "usageFromTaskExecution");
|
|
1297
|
-
function finiteNumber(value) {
|
|
1298
|
-
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1299
|
-
}
|
|
1300
|
-
__name(finiteNumber, "finiteNumber");
|
|
1301
|
-
function extractErrorMessage(value) {
|
|
1302
|
-
if (value instanceof Error) return value.message;
|
|
1303
|
-
if (!isObjectRecord(value)) return void 0;
|
|
1304
|
-
return typeof value["message"] === "string" ? value["message"] : void 0;
|
|
1305
|
-
}
|
|
1306
|
-
__name(extractErrorMessage, "extractErrorMessage");
|
|
1307
|
-
function dedupeStrings(values) {
|
|
1308
|
-
return [...new Set(values.filter((value) => value.length > 0))];
|
|
1309
|
-
}
|
|
1310
|
-
__name(dedupeStrings, "dedupeStrings");
|
|
1311
|
-
|
|
1312
|
-
// packages/cli/src/acp-integration/session/emitters/tool-call-emitter.ts
|
|
1313
|
-
init_esbuild_shims();
|
|
1314
|
-
|
|
1315
|
-
// packages/cli/src/acp-integration/session/emitters/base-emitter.ts
|
|
1316
|
-
init_esbuild_shims();
|
|
1317
|
-
var BaseEmitter = class {
|
|
1318
|
-
constructor(ctx) {
|
|
1319
|
-
this.ctx = ctx;
|
|
1320
|
-
}
|
|
1321
|
-
static {
|
|
1322
|
-
__name(this, "BaseEmitter");
|
|
1323
|
-
}
|
|
1324
|
-
/**
|
|
1325
|
-
* Converts an ISO timestamp string or epoch ms to epoch ms number.
|
|
1326
|
-
* Returns undefined if the input is not a valid timestamp.
|
|
1327
|
-
*/
|
|
1328
|
-
static toEpochMs(ts) {
|
|
1329
|
-
if (typeof ts === "number") {
|
|
1330
|
-
return Number.isFinite(ts) ? ts : void 0;
|
|
1331
|
-
}
|
|
1332
|
-
if (typeof ts === "string") {
|
|
1333
|
-
const ms = new Date(ts).getTime();
|
|
1334
|
-
return Number.isFinite(ms) ? ms : void 0;
|
|
1335
|
-
}
|
|
1336
|
-
return void 0;
|
|
1337
|
-
}
|
|
1338
|
-
/**
|
|
1339
|
-
* Sends a session update to the ACP client.
|
|
1340
|
-
* If a message rewriter is configured, updates pass through it first
|
|
1341
|
-
* (original messages are sent as-is, rewritten versions are appended).
|
|
1342
|
-
*/
|
|
1343
|
-
async sendUpdate(update) {
|
|
1344
|
-
if (this.ctx.messageRewriter) {
|
|
1345
|
-
return this.ctx.messageRewriter.interceptUpdate(update);
|
|
1346
|
-
}
|
|
1347
|
-
return this.ctx.sendUpdate(update);
|
|
1348
|
-
}
|
|
1349
|
-
/**
|
|
1350
|
-
* Gets the session ID.
|
|
1351
|
-
*/
|
|
1352
|
-
get sessionId() {
|
|
1353
|
-
return this.ctx.sessionId;
|
|
1354
|
-
}
|
|
1355
|
-
};
|
|
1356
|
-
|
|
1357
|
-
// packages/cli/src/acp-integration/session/emitters/PlanEmitter.ts
|
|
1358
|
-
init_esbuild_shims();
|
|
1359
|
-
var PlanEmitter = class extends BaseEmitter {
|
|
1360
|
-
static {
|
|
1361
|
-
__name(this, "PlanEmitter");
|
|
1362
|
-
}
|
|
1363
|
-
/**
|
|
1364
|
-
* Emits a plan update with the given todo items.
|
|
1365
|
-
*
|
|
1366
|
-
* @param plan - Plan identity and todo items to send as plan entries
|
|
1367
|
-
*/
|
|
1368
|
-
async emitPlan(plan, sourceCallId) {
|
|
1369
|
-
const cumulative = this.ctx.cumulativeUsage;
|
|
1370
|
-
await this.sendUpdate(
|
|
1371
|
-
createTranscriptPlanUpdate(plan.todos, cumulative, {
|
|
1372
|
-
planToolCallId: sourceCallId,
|
|
1373
|
-
todoPlanId: plan.planId
|
|
1374
|
-
})
|
|
1375
|
-
);
|
|
1376
|
-
}
|
|
1377
|
-
/**
|
|
1378
|
-
* Extracts todos from tool result display or args.
|
|
1379
|
-
* Tries multiple sources in priority order:
|
|
1380
|
-
* 1. Result display object with type 'todo_list'
|
|
1381
|
-
* 2. Result display as JSON string
|
|
1382
|
-
* 3. Args with 'todos' array when no result display is available
|
|
1383
|
-
*
|
|
1384
|
-
* @param resultDisplay - The tool result display (object, string, or undefined)
|
|
1385
|
-
* @param args - The tool call arguments (fallback source)
|
|
1386
|
-
* @returns Plan snapshot if found, null otherwise
|
|
1387
|
-
*/
|
|
1388
|
-
extractPlan(resultDisplay, args) {
|
|
1389
|
-
const plan = extractTranscriptTodoPlan(resultDisplay, args);
|
|
1390
|
-
if (!plan) return null;
|
|
1391
|
-
return {
|
|
1392
|
-
...plan.planId ? { planId: plan.planId } : {},
|
|
1393
|
-
todos: plan.todos.map((todo, index) => ({
|
|
1394
|
-
id: todo.id ?? String(index),
|
|
1395
|
-
content: todo.content,
|
|
1396
|
-
status: todo.status,
|
|
1397
|
-
...todo.blockedBy ? { blockedBy: [...todo.blockedBy] } : {}
|
|
1398
|
-
}))
|
|
1399
|
-
};
|
|
1400
|
-
}
|
|
1401
|
-
};
|
|
1402
|
-
|
|
1403
|
-
// packages/cli/src/acp-integration/session/types.ts
|
|
1404
|
-
init_esbuild_shims();
|
|
1405
|
-
function hasFullSessionContext(context) {
|
|
1406
|
-
return "config" in context;
|
|
1407
|
-
}
|
|
1408
|
-
__name(hasFullSessionContext, "hasFullSessionContext");
|
|
1409
|
-
|
|
1410
|
-
// packages/cli/src/acp-integration/session/emitters/tool-call-emitter.ts
|
|
1411
|
-
var KIND_MAP = {
|
|
1412
|
-
["read" /* Read */]: "read",
|
|
1413
|
-
["edit" /* Edit */]: "edit",
|
|
1414
|
-
["delete" /* Delete */]: "delete",
|
|
1415
|
-
["move" /* Move */]: "move",
|
|
1416
|
-
["search" /* Search */]: "search",
|
|
1417
|
-
["execute" /* Execute */]: "execute",
|
|
1418
|
-
["think" /* Think */]: "think",
|
|
1419
|
-
["fetch" /* Fetch */]: "fetch",
|
|
1420
|
-
// ACP defines no 'agent' ToolKind (verified through @agentclientprotocol/sdk
|
|
1421
|
-
// 0.25.1). The daemon's ClientSideConnection Zod-validates every session/update
|
|
1422
|
-
// and session/request_permission from the `qwen --acp` child before fanning out
|
|
1423
|
-
// to SSE clients, so emitting 'agent' is rejected at that hop and the frame is
|
|
1424
|
-
// dropped. Map the internal Kind.Agent to 'other' on the wire to stay
|
|
1425
|
-
// protocol-valid; dedicated agent UI is delivered out-of-band (via _meta.toolName)
|
|
1426
|
-
// in a follow-up rather than via a kind the protocol can't carry.
|
|
1427
|
-
["agent" /* Agent */]: "other",
|
|
1428
|
-
["other" /* Other */]: "other"
|
|
1429
|
-
};
|
|
1430
|
-
var ToolCallEmitter = class _ToolCallEmitter extends BaseEmitter {
|
|
1431
|
-
static {
|
|
1432
|
-
__name(this, "ToolCallEmitter");
|
|
1433
|
-
}
|
|
1434
|
-
planEmitter;
|
|
1435
|
-
preparedCallIds = /* @__PURE__ */ new Set();
|
|
1436
|
-
constructor(ctx) {
|
|
1437
|
-
super(ctx);
|
|
1438
|
-
this.planEmitter = new PlanEmitter(ctx);
|
|
1439
|
-
}
|
|
1440
|
-
/**
|
|
1441
|
-
* Emits a tool call start event.
|
|
1442
|
-
*
|
|
1443
|
-
* @param params - Tool call start parameters
|
|
1444
|
-
* @returns true if event was emitted, false if skipped (e.g., TodoWriteTool)
|
|
1445
|
-
*/
|
|
1446
|
-
async emitStart(params) {
|
|
1447
|
-
if (this.isTodoWriteTool(params.toolName)) {
|
|
1448
|
-
return false;
|
|
1449
|
-
}
|
|
1450
|
-
if (params.phase === "preparing" && this.preparedCallIds.has(params.callId)) {
|
|
1451
|
-
return false;
|
|
1452
|
-
}
|
|
1453
|
-
const { title, locations, kind } = this.resolveToolMetadata(
|
|
1454
|
-
params.toolName,
|
|
1455
|
-
params.args
|
|
1456
|
-
);
|
|
1457
|
-
const provenance = _ToolCallEmitter.resolveToolProvenance(
|
|
1458
|
-
params.toolName,
|
|
1459
|
-
params.subagentMeta
|
|
1460
|
-
);
|
|
1461
|
-
const updatesPreparedCall = params.phase !== "preparing" && this.preparedCallIds.delete(params.callId);
|
|
1462
|
-
await this.sendUpdate(
|
|
1463
|
-
createTranscriptToolCallStartUpdate({
|
|
1464
|
-
toolName: params.toolName,
|
|
1465
|
-
callId: params.callId,
|
|
1466
|
-
status: params.status || "pending",
|
|
1467
|
-
args: params.args,
|
|
1468
|
-
metadata: { title, locations, kind },
|
|
1469
|
-
timestamp: params.timestamp,
|
|
1470
|
-
asUpdate: updatesPreparedCall,
|
|
1471
|
-
extra: {
|
|
1472
|
-
...params.phase ? { phase: params.phase } : {},
|
|
1473
|
-
...params.subagentMeta,
|
|
1474
|
-
provenance: provenance.provenance,
|
|
1475
|
-
...provenance.serverId ? { serverId: provenance.serverId } : {}
|
|
1476
|
-
}
|
|
1477
|
-
})
|
|
1478
|
-
);
|
|
1479
|
-
if (params.phase === "preparing") {
|
|
1480
|
-
this.preparedCallIds.add(params.callId);
|
|
1481
|
-
}
|
|
1482
|
-
return true;
|
|
1483
|
-
}
|
|
1484
|
-
/**
|
|
1485
|
-
* Emits a terminal frame when a prepared tool call is discarded before
|
|
1486
|
-
* execution. TodoWrite remains represented exclusively by plan updates.
|
|
1487
|
-
*
|
|
1488
|
-
* @param callId - ID of the prepared tool call
|
|
1489
|
-
* @param toolName - Name of the prepared tool
|
|
1490
|
-
*/
|
|
1491
|
-
async emitPreparationDiscarded(callId, toolName) {
|
|
1492
|
-
if (this.isTodoWriteTool(toolName)) return;
|
|
1493
|
-
this.preparedCallIds.delete(callId);
|
|
1494
|
-
const provenance = _ToolCallEmitter.resolveToolProvenance(toolName);
|
|
1495
|
-
await this.sendUpdate({
|
|
1496
|
-
sessionUpdate: "tool_call_update",
|
|
1497
|
-
toolCallId: callId,
|
|
1498
|
-
status: "failed",
|
|
1499
|
-
content: [],
|
|
1500
|
-
_meta: {
|
|
1501
|
-
toolName,
|
|
1502
|
-
phase: "preparing",
|
|
1503
|
-
preparationDiscarded: true,
|
|
1504
|
-
provenance: provenance.provenance,
|
|
1505
|
-
...provenance.serverId ? { serverId: provenance.serverId } : {}
|
|
1506
|
-
}
|
|
1507
|
-
});
|
|
1508
|
-
}
|
|
1509
|
-
/**
|
|
1510
|
-
* Emits a tool call result event.
|
|
1511
|
-
* Handles TodoWriteTool specially by routing to plan updates.
|
|
1512
|
-
*
|
|
1513
|
-
* @param params - Tool call result parameters
|
|
1514
|
-
*/
|
|
1515
|
-
async emitResult(params) {
|
|
1516
|
-
if (this.isTodoWriteTool(params.toolName)) {
|
|
1517
|
-
if (params.subagentMeta) return;
|
|
1518
|
-
if (!params.success) return;
|
|
1519
|
-
const plan = this.planEmitter.extractPlan(
|
|
1520
|
-
params.resultDisplay,
|
|
1521
|
-
params.args
|
|
1522
|
-
);
|
|
1523
|
-
if (plan && (plan.todos.length > 0 || params.args && Array.isArray(params.args["todos"]))) {
|
|
1524
|
-
await this.planEmitter.emitPlan(plan, params.callId);
|
|
1525
|
-
}
|
|
1526
|
-
return;
|
|
1527
|
-
}
|
|
1528
|
-
this.preparedCallIds.delete(params.callId);
|
|
1529
|
-
const provenance = _ToolCallEmitter.resolveToolProvenance(
|
|
1530
|
-
params.toolName,
|
|
1531
|
-
params.subagentMeta
|
|
1532
|
-
);
|
|
1533
|
-
await this.sendUpdate(
|
|
1534
|
-
createTranscriptToolCallResultUpdate({
|
|
1535
|
-
toolName: params.toolName,
|
|
1536
|
-
callId: params.callId,
|
|
1537
|
-
success: params.success,
|
|
1538
|
-
message: params.message,
|
|
1539
|
-
resultDisplay: params.resultDisplay,
|
|
1540
|
-
errorMessage: params.error?.message,
|
|
1541
|
-
artifacts: params.artifacts,
|
|
1542
|
-
contentPrefix: buildToolResultContentPrefix(params.resultDisplay),
|
|
1543
|
-
timestamp: params.timestamp,
|
|
1544
|
-
extra: {
|
|
1545
|
-
...params.subagentMeta,
|
|
1546
|
-
provenance: provenance.provenance,
|
|
1547
|
-
...provenance.serverId ? { serverId: provenance.serverId } : {}
|
|
1548
|
-
}
|
|
1549
|
-
})
|
|
1550
|
-
);
|
|
1551
|
-
}
|
|
1552
|
-
/**
|
|
1553
|
-
* Emits a tool call error event.
|
|
1554
|
-
* Use this for explicit error handling when not using emitResult.
|
|
1555
|
-
*
|
|
1556
|
-
* @param callId - The tool call ID
|
|
1557
|
-
* @param toolName - The tool name
|
|
1558
|
-
* @param error - The error that occurred
|
|
1559
|
-
* @param subagentMeta - Optional subagent metadata
|
|
1560
|
-
*/
|
|
1561
|
-
async emitError(callId, toolName, error, subagentMeta) {
|
|
1562
|
-
this.preparedCallIds.delete(callId);
|
|
1563
|
-
const provenance = _ToolCallEmitter.resolveToolProvenance(
|
|
1564
|
-
toolName,
|
|
1565
|
-
subagentMeta
|
|
1566
|
-
);
|
|
1567
|
-
await this.sendUpdate(
|
|
1568
|
-
createTranscriptToolCallResultUpdate({
|
|
1569
|
-
toolName,
|
|
1570
|
-
callId,
|
|
1571
|
-
success: false,
|
|
1572
|
-
errorMessage: error.message,
|
|
1573
|
-
extra: {
|
|
1574
|
-
...subagentMeta,
|
|
1575
|
-
provenance: provenance.provenance,
|
|
1576
|
-
...provenance.serverId ? { serverId: provenance.serverId } : {}
|
|
1577
|
-
}
|
|
1578
|
-
})
|
|
1579
|
-
);
|
|
1580
|
-
}
|
|
1581
|
-
/**
|
|
1582
|
-
* Resolve a tool's provenance for UI dispatch on tool_call events.
|
|
1583
|
-
* The SDK reads `_meta.
|
|
1584
|
-
* provenance` + `_meta.serverId` to render builtin / MCP-server-badge /
|
|
1585
|
-
* subagent-block differently. Without this stamping, the SDK falls
|
|
1586
|
-
* back to string-matching the toolName which can't reliably
|
|
1587
|
-
* distinguish builtin from subagent.
|
|
1588
|
-
*
|
|
1589
|
-
* Resolution rules:
|
|
1590
|
-
* - `subagentMeta` present → `'subagent'` (a Task tool / Codex
|
|
1591
|
-
* subagent / etc. wrapping its own tool calls)
|
|
1592
|
-
* - toolName matches `mcp__<server>__<tool>` → `'mcp'` with
|
|
1593
|
-
* `serverId: <server>`. Naming convention from
|
|
1594
|
-
* `packages/core/src/tools/mcp-tool.ts` in the
|
|
1595
|
-
* `@qwen-code/qwen-code-core` package — mirrors the SDK's same
|
|
1596
|
-
* heuristic fallback so SDK consumers stay consistent with
|
|
1597
|
-
* daemon classification.
|
|
1598
|
-
* - everything else → `'builtin'`
|
|
1599
|
-
*
|
|
1600
|
-
* Static + pure so it can be unit-tested without an emitter
|
|
1601
|
-
* instance. Exported via `ToolCallEmitter.resolveToolProvenance`.
|
|
1602
|
-
*/
|
|
1603
|
-
static resolveToolProvenance(toolName, subagentMeta) {
|
|
1604
|
-
if (subagentMeta !== void 0) {
|
|
1605
|
-
return { provenance: "subagent" };
|
|
1606
|
-
}
|
|
1607
|
-
if (toolName.startsWith("mcp__")) {
|
|
1608
|
-
const parts = toolName.split("__");
|
|
1609
|
-
if (parts.length >= 3 && parts[1] && parts[1].length > 0) {
|
|
1610
|
-
return { provenance: "mcp", serverId: parts[1] };
|
|
1611
|
-
}
|
|
1612
|
-
}
|
|
1613
|
-
return { provenance: "builtin" };
|
|
1614
|
-
}
|
|
1615
|
-
// ==================== Public Utilities ====================
|
|
1616
|
-
/**
|
|
1617
|
-
* Checks if a tool name is the TodoWriteTool.
|
|
1618
|
-
* Exposed for external use in components that need to check this.
|
|
1619
|
-
*/
|
|
1620
|
-
isTodoWriteTool(toolName) {
|
|
1621
|
-
return toolName === ToolNames.TODO_WRITE;
|
|
1622
|
-
}
|
|
1623
|
-
/**
|
|
1624
|
-
* Checks if a tool name is the ExitPlanModeTool.
|
|
1625
|
-
*/
|
|
1626
|
-
isExitPlanModeTool(toolName) {
|
|
1627
|
-
return toolName === ToolNames.EXIT_PLAN_MODE;
|
|
1628
|
-
}
|
|
1629
|
-
/**
|
|
1630
|
-
* Checks if a tool name is the EnterPlanModeTool.
|
|
1631
|
-
*/
|
|
1632
|
-
isEnterPlanModeTool(toolName) {
|
|
1633
|
-
return toolName === ToolNames.ENTER_PLAN_MODE;
|
|
1634
|
-
}
|
|
1635
|
-
/**
|
|
1636
|
-
* Resolves tool metadata from the registry.
|
|
1637
|
-
* Falls back to defaults if tool not found or build fails.
|
|
1638
|
-
*
|
|
1639
|
-
* @param toolName - Name of the tool
|
|
1640
|
-
* @param args - Tool call arguments (used to build invocation)
|
|
1641
|
-
*/
|
|
1642
|
-
resolveToolMetadata(toolName, args) {
|
|
1643
|
-
if (!hasFullSessionContext(this.ctx)) {
|
|
1644
|
-
const description = typeof args?.["description"] === "string" ? args["description"].trim() : "";
|
|
1645
|
-
return {
|
|
1646
|
-
title: description ? `${toolName}: ${description}` : toolName,
|
|
1647
|
-
locations: [],
|
|
1648
|
-
kind: "other"
|
|
1649
|
-
};
|
|
1650
|
-
}
|
|
1651
|
-
const toolRegistry = this.ctx.config.getToolRegistry();
|
|
1652
|
-
const tool = toolRegistry.getTool(toolName);
|
|
1653
|
-
let title = tool?.displayName ?? toolName;
|
|
1654
|
-
let locations = [];
|
|
1655
|
-
let kind = "other";
|
|
1656
|
-
if (tool && args) {
|
|
1657
|
-
try {
|
|
1658
|
-
const invocation = tool.build(args);
|
|
1659
|
-
title = `${title}: ${invocation.getDescription()}`;
|
|
1660
|
-
locations = invocation.toolLocations().map((loc) => ({
|
|
1661
|
-
path: loc.path,
|
|
1662
|
-
line: loc.line ?? null
|
|
1663
|
-
}));
|
|
1664
|
-
kind = this.mapToolKind(tool.kind, toolName);
|
|
1665
|
-
} catch {
|
|
1666
|
-
if (typeof args["description"] === "string") {
|
|
1667
|
-
title = `${title}: ${args["description"]}`;
|
|
1668
|
-
}
|
|
1669
|
-
if (tool.kind) {
|
|
1670
|
-
kind = this.mapToolKind(tool.kind, toolName);
|
|
1671
|
-
}
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
return { title, locations, kind };
|
|
1675
|
-
}
|
|
1676
|
-
/**
|
|
1677
|
-
* Maps core Tool Kind enum to ACP ToolKind string literals.
|
|
1678
|
-
*
|
|
1679
|
-
* @param kind - The core Kind enum value
|
|
1680
|
-
* @param toolName - Optional tool name to handle special cases like exit_plan_mode
|
|
1681
|
-
*/
|
|
1682
|
-
mapToolKind(kind, toolName) {
|
|
1683
|
-
if (toolName && (this.isExitPlanModeTool(toolName) || this.isEnterPlanModeTool(toolName))) {
|
|
1684
|
-
return "switch_mode";
|
|
1685
|
-
}
|
|
1686
|
-
return KIND_MAP[kind] ?? "other";
|
|
1687
|
-
}
|
|
1688
|
-
};
|
|
1689
|
-
function buildToolResultContentPrefix(resultDisplay) {
|
|
1690
|
-
if (!isVisionBridgeNoticeDisplay(resultDisplay)) return [];
|
|
1691
|
-
return [
|
|
1692
|
-
{
|
|
1693
|
-
type: "content",
|
|
1694
|
-
content: {
|
|
1695
|
-
type: "text",
|
|
1696
|
-
text: sanitizeTerminalText(
|
|
1697
|
-
formatVisionBridgeNoticeDisplay(resultDisplay)
|
|
1698
|
-
)
|
|
1699
|
-
}
|
|
1700
|
-
}
|
|
1701
|
-
];
|
|
1702
|
-
}
|
|
1703
|
-
__name(buildToolResultContentPrefix, "buildToolResultContentPrefix");
|
|
1704
|
-
|
|
1705
|
-
// packages/cli/src/acp-integration/session/history-replayer.ts
|
|
1706
|
-
var HistoryReplayer = class {
|
|
1707
|
-
constructor(ctx) {
|
|
1708
|
-
this.ctx = ctx;
|
|
1709
|
-
this.toolCallEmitter = new ToolCallEmitter(ctx);
|
|
1710
|
-
this.machine = this.createMachine();
|
|
1711
|
-
}
|
|
1712
|
-
static {
|
|
1713
|
-
__name(this, "HistoryReplayer");
|
|
1714
|
-
}
|
|
1715
|
-
toolCallEmitter;
|
|
1716
|
-
machine;
|
|
1717
|
-
async replay(records, gaps, options = {}) {
|
|
1718
|
-
try {
|
|
1719
|
-
if (options.goalBootstrap) {
|
|
1720
|
-
const update = {
|
|
1721
|
-
sessionUpdate: "agent_message_chunk",
|
|
1722
|
-
content: { type: "text", text: "" },
|
|
1723
|
-
_meta: {
|
|
1724
|
-
...options.goalBootstrap.goalState ? { goalState: options.goalBootstrap.goalState } : {},
|
|
1725
|
-
goalStatus: options.goalBootstrap.goalStatus
|
|
1726
|
-
}
|
|
1727
|
-
};
|
|
1728
|
-
await this.sendUpdate(update);
|
|
1729
|
-
}
|
|
1730
|
-
await this.replayPage(records, {
|
|
1731
|
-
finalizeDangling: true,
|
|
1732
|
-
gaps,
|
|
1733
|
-
...options.initialGoalState ? { goalState: options.initialGoalState } : {},
|
|
1734
|
-
...options.initialGoalCause ? { goalCause: options.initialGoalCause } : {}
|
|
1735
|
-
});
|
|
1736
|
-
} finally {
|
|
1737
|
-
this.setActiveRecordId(null);
|
|
1738
|
-
}
|
|
1739
|
-
}
|
|
1740
|
-
static v2GoalBootstrap(rawGoalState, rawGoalCause) {
|
|
1741
|
-
const goalState = parseGoalSnapshotV2(rawGoalState);
|
|
1742
|
-
const goalCause = parseGoalStateCause(rawGoalCause);
|
|
1743
|
-
if (!goalState?.goal || goalState.goal.status !== "active" || !goalCause) {
|
|
1744
|
-
return void 0;
|
|
1745
|
-
}
|
|
1746
|
-
const projection = projectGoalStateToLegacy({
|
|
1747
|
-
v: 2,
|
|
1748
|
-
cause: goalCause,
|
|
1749
|
-
snapshot: goalState
|
|
1750
|
-
});
|
|
1751
|
-
const { type: _type, kind, ...goalStatus } = projection.goalStatus;
|
|
1752
|
-
if (kind !== "set" && kind !== "checking") {
|
|
1753
|
-
return void 0;
|
|
1754
|
-
}
|
|
1755
|
-
return { goalStatus: { ...goalStatus, kind }, goalState };
|
|
1756
|
-
}
|
|
1757
|
-
async replayPage(records, options = {}) {
|
|
1758
|
-
this.machine = this.createMachine(options);
|
|
1759
|
-
let replayError;
|
|
1760
|
-
try {
|
|
1761
|
-
for (const record of records) {
|
|
1762
|
-
for (const emission of this.machine.project(record)) {
|
|
1763
|
-
this.setActiveRecordId(
|
|
1764
|
-
emission.sourceRecordId,
|
|
1765
|
-
emission.sourceTimestamp
|
|
1766
|
-
);
|
|
1767
|
-
await this.sendUpdate(emission.update);
|
|
1768
|
-
}
|
|
1769
|
-
}
|
|
1770
|
-
} catch (error) {
|
|
1771
|
-
replayError = error;
|
|
1772
|
-
}
|
|
1773
|
-
let danglingError;
|
|
1774
|
-
if (options.finalizeDangling === true) {
|
|
1775
|
-
for (const emission of this.machine.finalize()) {
|
|
1776
|
-
this.setActiveRecordId(
|
|
1777
|
-
emission.sourceRecordId,
|
|
1778
|
-
emission.sourceTimestamp
|
|
1779
|
-
);
|
|
1780
|
-
try {
|
|
1781
|
-
await this.sendUpdate(emission.update);
|
|
1782
|
-
} catch (error) {
|
|
1783
|
-
danglingError ??= error;
|
|
1784
|
-
}
|
|
1785
|
-
}
|
|
1786
|
-
}
|
|
1787
|
-
const replay = this.machine.snapshot();
|
|
1788
|
-
this.copyCumulativeUsage(replay);
|
|
1789
|
-
const state = {
|
|
1790
|
-
pendingToolCalls: options.finalizeDangling === true ? [] : replay.pendingToolCalls.map(toLegacyPendingToolCall),
|
|
1791
|
-
replay
|
|
1792
|
-
};
|
|
1793
|
-
this.setActiveRecordId(null);
|
|
1794
|
-
if (replayError && danglingError) {
|
|
1795
|
-
throw new AggregateError(
|
|
1796
|
-
[replayError, danglingError],
|
|
1797
|
-
"Replay and dangling-cleanup both failed"
|
|
1798
|
-
);
|
|
1799
|
-
}
|
|
1800
|
-
if (replayError) throw replayError;
|
|
1801
|
-
if (danglingError) throw danglingError;
|
|
1802
|
-
return state;
|
|
1803
|
-
}
|
|
1804
|
-
getPendingToolCalls() {
|
|
1805
|
-
return this.machine.snapshot().pendingToolCalls.map(toLegacyPendingToolCall);
|
|
1806
|
-
}
|
|
1807
|
-
getReplayState() {
|
|
1808
|
-
return this.machine.snapshot();
|
|
1809
|
-
}
|
|
1810
|
-
createMachine(options = {}) {
|
|
1811
|
-
const cumulative = this.ctx.cumulativeUsage;
|
|
1812
|
-
const initialState = {
|
|
1813
|
-
v: 1,
|
|
1814
|
-
pendingToolCalls: (options.pendingToolCalls ?? []).map(
|
|
1815
|
-
toPendingTranscriptToolCall
|
|
1816
|
-
),
|
|
1817
|
-
cumulativeUsage: cumulative ? { ...cumulative } : {
|
|
1818
|
-
promptTokens: 0,
|
|
1819
|
-
cachedTokens: 0,
|
|
1820
|
-
candidateTokens: 0,
|
|
1821
|
-
apiTimeMs: 0
|
|
1822
|
-
},
|
|
1823
|
-
...options.goalState ? { goalState: options.goalState } : {},
|
|
1824
|
-
...options.goalCause ? { goalCause: options.goalCause } : {}
|
|
1825
|
-
};
|
|
1826
|
-
return createTranscriptReplayMachine({
|
|
1827
|
-
initialState,
|
|
1828
|
-
gaps: options.gaps,
|
|
1829
|
-
presentation: this.presentationAdapter(),
|
|
1830
|
-
onDiagnostic: /* @__PURE__ */ __name((diagnostic) => {
|
|
1831
|
-
if (diagnostic.code === "malformed_part" && diagnostic.path === "systemPayload.outputHistoryItems.goalStatus.condition") {
|
|
1832
|
-
writeStderrLineSafe(`qwen: ${diagnostic.message}`);
|
|
1833
|
-
}
|
|
1834
|
-
}, "onDiagnostic")
|
|
1835
|
-
});
|
|
1836
|
-
}
|
|
1837
|
-
presentationAdapter() {
|
|
1838
|
-
return {
|
|
1839
|
-
resolveToolMetadata: /* @__PURE__ */ __name((toolName, args) => this.toolCallEmitter.resolveToolMetadata(toolName, { ...args }), "resolveToolMetadata"),
|
|
1840
|
-
formatHistoryGap: /* @__PURE__ */ __name((gap) => formatHistoryGapNotice(gap), "formatHistoryGap"),
|
|
1841
|
-
buildToolResultContentPrefix
|
|
1842
|
-
};
|
|
1843
|
-
}
|
|
1844
|
-
async sendUpdate(update) {
|
|
1845
|
-
if (this.ctx.messageRewriter) {
|
|
1846
|
-
await this.ctx.messageRewriter.interceptUpdate(update);
|
|
1847
|
-
return;
|
|
1848
|
-
}
|
|
1849
|
-
await this.ctx.sendUpdate(update);
|
|
1850
|
-
}
|
|
1851
|
-
copyCumulativeUsage(state) {
|
|
1852
|
-
const cumulative = this.ctx.cumulativeUsage;
|
|
1853
|
-
if (!cumulative) return;
|
|
1854
|
-
cumulative.promptTokens = state.cumulativeUsage.promptTokens;
|
|
1855
|
-
cumulative.cachedTokens = state.cumulativeUsage.cachedTokens;
|
|
1856
|
-
cumulative.candidateTokens = state.cumulativeUsage.candidateTokens;
|
|
1857
|
-
cumulative.apiTimeMs = state.cumulativeUsage.apiTimeMs;
|
|
1858
|
-
}
|
|
1859
|
-
setActiveRecordId(recordId, timestamp) {
|
|
1860
|
-
this.ctx.setActiveRecordId?.(recordId, timestamp);
|
|
1861
|
-
}
|
|
1862
|
-
};
|
|
1863
|
-
function toPendingTranscriptToolCall(pending) {
|
|
1864
|
-
return {
|
|
1865
|
-
callId: pending.callId,
|
|
1866
|
-
toolName: pending.toolName,
|
|
1867
|
-
sourceRecordId: pending.recordId,
|
|
1868
|
-
...pending.timestamp ? { sourceTimestamp: pending.timestamp } : {}
|
|
1869
|
-
};
|
|
1870
|
-
}
|
|
1871
|
-
__name(toPendingTranscriptToolCall, "toPendingTranscriptToolCall");
|
|
1872
|
-
function toLegacyPendingToolCall(pending) {
|
|
1873
|
-
return {
|
|
1874
|
-
callId: pending.callId,
|
|
1875
|
-
toolName: pending.toolName,
|
|
1876
|
-
recordId: pending.sourceRecordId,
|
|
1877
|
-
...pending.sourceTimestamp ? { timestamp: pending.sourceTimestamp } : {}
|
|
1878
|
-
};
|
|
1879
|
-
}
|
|
1880
|
-
__name(toLegacyPendingToolCall, "toLegacyPendingToolCall");
|
|
1881
|
-
|
|
1882
|
-
// packages/cli/src/services/setup-github.ts
|
|
1883
|
-
init_esbuild_shims();
|
|
1884
|
-
import { promises as fsp } from "node:fs";
|
|
1885
|
-
import * as path from "node:path";
|
|
1886
|
-
|
|
1887
|
-
// packages/cli/src/utils/gitUtils.ts
|
|
1888
|
-
init_esbuild_shims();
|
|
1889
|
-
import * as childProcess from "node:child_process";
|
|
1890
|
-
var debugLogger = createDebugLogger("GIT");
|
|
1891
|
-
async function runGit(args, opts = {}) {
|
|
1892
|
-
return await new Promise((resolve2, reject) => {
|
|
1893
|
-
childProcess.execFile(
|
|
1894
|
-
"git",
|
|
1895
|
-
args,
|
|
1896
|
-
{
|
|
1897
|
-
encoding: "utf-8",
|
|
1898
|
-
...opts.cwd ? { cwd: opts.cwd } : {}
|
|
1899
|
-
},
|
|
1900
|
-
(err, stdout) => {
|
|
1901
|
-
if (err) {
|
|
1902
|
-
reject(err);
|
|
1903
|
-
return;
|
|
1904
|
-
}
|
|
1905
|
-
resolve2(String(stdout ?? "").trim());
|
|
1906
|
-
}
|
|
1907
|
-
);
|
|
1908
|
-
});
|
|
1909
|
-
}
|
|
1910
|
-
__name(runGit, "runGit");
|
|
1911
|
-
var isGitHubRepositoryAsync = /* @__PURE__ */ __name(async (opts = {}) => {
|
|
1912
|
-
try {
|
|
1913
|
-
const remotes = await runGit(["remote", "-v"], opts);
|
|
1914
|
-
return remotes.split("\n").some((line) => {
|
|
1915
|
-
const remoteUrl = line.trim().split(/\s+/)[1];
|
|
1916
|
-
return remoteUrl ? isGitHubRemoteUrl(remoteUrl) : false;
|
|
1917
|
-
});
|
|
1918
|
-
} catch (_error) {
|
|
1919
|
-
debugLogger.debug(`Failed to get git remote:`, _error);
|
|
1920
|
-
return false;
|
|
1921
|
-
}
|
|
1922
|
-
}, "isGitHubRepositoryAsync");
|
|
1923
|
-
function isGitHubRemoteUrl(remoteUrl) {
|
|
1924
|
-
if (remoteUrl.startsWith("git@github.com:")) {
|
|
1925
|
-
return true;
|
|
1926
|
-
}
|
|
1927
|
-
if (remoteUrl.startsWith("git@")) {
|
|
1928
|
-
return false;
|
|
1929
|
-
}
|
|
1930
|
-
try {
|
|
1931
|
-
return new URL(remoteUrl).hostname === "github.com";
|
|
1932
|
-
} catch {
|
|
1933
|
-
return false;
|
|
1934
|
-
}
|
|
1935
|
-
}
|
|
1936
|
-
__name(isGitHubRemoteUrl, "isGitHubRemoteUrl");
|
|
1937
|
-
var getGitRepoRootAsync = /* @__PURE__ */ __name(async (opts = {}) => {
|
|
1938
|
-
const gitRepoRoot = await runGit(["rev-parse", "--show-toplevel"], opts);
|
|
1939
|
-
if (!gitRepoRoot) {
|
|
1940
|
-
throw new Error(`Git repo returned empty value`);
|
|
1941
|
-
}
|
|
1942
|
-
return gitRepoRoot;
|
|
1943
|
-
}, "getGitRepoRootAsync");
|
|
1944
|
-
var getLatestGitHubRelease = /* @__PURE__ */ __name(async (proxy) => {
|
|
1945
|
-
try {
|
|
1946
|
-
const controller = new AbortController();
|
|
1947
|
-
const endpoint = `https://api.github.com/repos/QwenLM/qwen-code-action/releases/latest`;
|
|
1948
|
-
const dispatcher = proxy ? new (await loadUndici()).ProxyAgent(proxy) : void 0;
|
|
1949
|
-
const response = await fetch(endpoint, {
|
|
1950
|
-
method: "GET",
|
|
1951
|
-
headers: {
|
|
1952
|
-
Accept: "application/vnd.github+json",
|
|
1953
|
-
"Content-Type": "application/json",
|
|
1954
|
-
"X-GitHub-Api-Version": "2022-11-28"
|
|
1955
|
-
},
|
|
1956
|
-
dispatcher,
|
|
1957
|
-
signal: AbortSignal.any([AbortSignal.timeout(3e4), controller.signal])
|
|
1958
|
-
});
|
|
1959
|
-
if (!response.ok) {
|
|
1960
|
-
throw new Error(
|
|
1961
|
-
`Invalid response code: ${response.status} - ${response.statusText}`
|
|
1962
|
-
);
|
|
1963
|
-
}
|
|
1964
|
-
const releaseTag = (await response.json()).tag_name;
|
|
1965
|
-
if (!releaseTag) {
|
|
1966
|
-
throw new Error(`Response did not include tag_name field`);
|
|
1967
|
-
}
|
|
1968
|
-
return releaseTag;
|
|
1969
|
-
} catch (_error) {
|
|
1970
|
-
debugLogger.debug(
|
|
1971
|
-
`Failed to determine latest qwen-code-action release:`,
|
|
1972
|
-
_error
|
|
1973
|
-
);
|
|
1974
|
-
throw new Error(
|
|
1975
|
-
`Unable to determine the latest qwen-code-action release on GitHub.`
|
|
1976
|
-
);
|
|
1977
|
-
}
|
|
1978
|
-
}, "getLatestGitHubRelease");
|
|
1979
|
-
async function getGitHubRepoInfoAsync(opts = {}) {
|
|
1980
|
-
return parseGitHubRepoInfo(
|
|
1981
|
-
await runGit(["remote", "get-url", "origin"], opts)
|
|
1982
|
-
);
|
|
1983
|
-
}
|
|
1984
|
-
__name(getGitHubRepoInfoAsync, "getGitHubRepoInfoAsync");
|
|
1985
|
-
function parseGitHubRepoInfo(remoteUrl) {
|
|
1986
|
-
let urlToParse = remoteUrl;
|
|
1987
|
-
if (remoteUrl.startsWith("git@github.com:")) {
|
|
1988
|
-
urlToParse = remoteUrl.replace("git@github.com:", "");
|
|
1989
|
-
} else if (remoteUrl.startsWith("git@")) {
|
|
1990
|
-
throw new Error(
|
|
1991
|
-
`Owner & repo could not be extracted from remote URL: ${remoteUrl}`
|
|
1992
|
-
);
|
|
1993
|
-
}
|
|
1994
|
-
let parsedUrl;
|
|
1995
|
-
try {
|
|
1996
|
-
parsedUrl = new URL(urlToParse, "https://github.com");
|
|
1997
|
-
} catch {
|
|
1998
|
-
throw new Error(
|
|
1999
|
-
`Owner & repo could not be extracted from remote URL: ${remoteUrl}`
|
|
2000
|
-
);
|
|
2001
|
-
}
|
|
2002
|
-
if (parsedUrl.hostname !== "github.com") {
|
|
2003
|
-
throw new Error(
|
|
2004
|
-
`Owner & repo could not be extracted from remote URL: ${remoteUrl}`
|
|
2005
|
-
);
|
|
2006
|
-
}
|
|
2007
|
-
const parts = parsedUrl.pathname.split("/").filter((part) => part !== "");
|
|
2008
|
-
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
2009
|
-
throw new Error(
|
|
2010
|
-
`Owner & repo could not be extracted from remote URL: ${remoteUrl}`
|
|
2011
|
-
);
|
|
2012
|
-
}
|
|
2013
|
-
return { owner: parts[0], repo: parts[1].replace(/\.git$/, "") };
|
|
2014
|
-
}
|
|
2015
|
-
__name(parseGitHubRepoInfo, "parseGitHubRepoInfo");
|
|
2016
|
-
|
|
2017
|
-
// packages/cli/src/services/setup-github.ts
|
|
2018
|
-
var debugLogger2 = createDebugLogger("SETUP_GITHUB");
|
|
2019
|
-
var GITHUB_WORKFLOW_PATHS = [
|
|
2020
|
-
"qwen-dispatch/qwen-dispatch.yml",
|
|
2021
|
-
"qwen-assistant/qwen-invoke.yml",
|
|
2022
|
-
"issue-triage/qwen-triage.yml",
|
|
2023
|
-
"issue-triage/qwen-scheduled-triage.yml",
|
|
2024
|
-
"pr-review/qwen-review.yml"
|
|
2025
|
-
];
|
|
2026
|
-
var GITIGNORE_ENTRIES = [".qwen/", "gha-creds-*.json"];
|
|
2027
|
-
var MAX_WORKFLOW_DOWNLOAD_BYTES = 5 * 1024 * 1024;
|
|
2028
|
-
var SetupGithubError = class extends Error {
|
|
2029
|
-
static {
|
|
2030
|
-
__name(this, "SetupGithubError");
|
|
2031
|
-
}
|
|
2032
|
-
code;
|
|
2033
|
-
status;
|
|
2034
|
-
partial;
|
|
2035
|
-
partialResult;
|
|
2036
|
-
constructor(code, message, status, partialResult) {
|
|
2037
|
-
super(message);
|
|
2038
|
-
this.name = "SetupGithubError";
|
|
2039
|
-
this.code = code;
|
|
2040
|
-
this.status = status;
|
|
2041
|
-
this.partial = partialResult !== void 0;
|
|
2042
|
-
this.partialResult = partialResult;
|
|
2043
|
-
}
|
|
2044
|
-
};
|
|
2045
|
-
function isWorkspaceGenerationClosed(error) {
|
|
2046
|
-
return Boolean(
|
|
2047
|
-
error && typeof error === "object" && "code" in error && error.code === "workspace_generation_closed"
|
|
2048
|
-
);
|
|
2049
|
-
}
|
|
2050
|
-
__name(isWorkspaceGenerationClosed, "isWorkspaceGenerationClosed");
|
|
2051
|
-
var nodeFileOps = {
|
|
2052
|
-
assertCanWrite() {
|
|
2053
|
-
},
|
|
2054
|
-
async ensureWorkflowDirectory(gitRepoRoot) {
|
|
2055
|
-
await fsp.mkdir(path.join(gitRepoRoot, ".github", "workflows"), {
|
|
2056
|
-
recursive: true
|
|
2057
|
-
});
|
|
2058
|
-
},
|
|
2059
|
-
async writeTextFile(gitRepoRoot, relativePath, content) {
|
|
2060
|
-
const target = path.join(gitRepoRoot, relativePath);
|
|
2061
|
-
await fsp.writeFile(target, content, { mode: 420 });
|
|
2062
|
-
return { sizeBytes: Buffer.byteLength(content, "utf8") };
|
|
2063
|
-
},
|
|
2064
|
-
async readTextFile(gitRepoRoot, relativePath) {
|
|
2065
|
-
try {
|
|
2066
|
-
return await fsp.readFile(path.join(gitRepoRoot, relativePath), "utf8");
|
|
2067
|
-
} catch (error) {
|
|
2068
|
-
if (error.code === "ENOENT") {
|
|
2069
|
-
return void 0;
|
|
2070
|
-
}
|
|
2071
|
-
throw error;
|
|
2072
|
-
}
|
|
2073
|
-
}
|
|
2074
|
-
};
|
|
2075
|
-
async function setupGithub(options = {}) {
|
|
2076
|
-
const cwd = options.cwd ?? process.cwd();
|
|
2077
|
-
const fileOps = options.fileOps ?? nodeFileOps;
|
|
2078
|
-
if (!await isGitHubRepositoryAsync({ cwd })) {
|
|
2079
|
-
throw new SetupGithubError(
|
|
2080
|
-
"github_repository_not_found",
|
|
2081
|
-
"Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
|
|
2082
|
-
400
|
|
2083
|
-
);
|
|
2084
|
-
}
|
|
2085
|
-
let gitRepoRoot;
|
|
2086
|
-
try {
|
|
2087
|
-
gitRepoRoot = await getGitRepoRootAsync({ cwd });
|
|
2088
|
-
} catch (error) {
|
|
2089
|
-
debugLogger2.debug("Failed to get git repo root:", error);
|
|
2090
|
-
throw new SetupGithubError(
|
|
2091
|
-
"github_repository_not_found",
|
|
2092
|
-
"Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
|
|
2093
|
-
400
|
|
2094
|
-
);
|
|
2095
|
-
}
|
|
2096
|
-
if (options.workspaceRoot) {
|
|
2097
|
-
const [gitRootReal, workspaceReal] = await Promise.all([
|
|
2098
|
-
realpathOrResolve(gitRepoRoot),
|
|
2099
|
-
realpathOrResolve(options.workspaceRoot)
|
|
2100
|
-
]);
|
|
2101
|
-
if (gitRootReal !== workspaceReal) {
|
|
2102
|
-
throw new SetupGithubError(
|
|
2103
|
-
"github_git_root_mismatch",
|
|
2104
|
-
"The Git repository root must match the daemon workspace root.",
|
|
2105
|
-
400
|
|
2106
|
-
);
|
|
2107
|
-
}
|
|
2108
|
-
}
|
|
2109
|
-
fileOps.assertCanWrite?.();
|
|
2110
|
-
let releaseTag;
|
|
2111
|
-
try {
|
|
2112
|
-
releaseTag = await getLatestGitHubRelease(options.proxy);
|
|
2113
|
-
} catch (error) {
|
|
2114
|
-
writeStderrLine(
|
|
2115
|
-
`qwen setup-github: failed to determine latest qwen-code-action release: ${error instanceof Error ? error.message : String(error)}`
|
|
2116
|
-
);
|
|
2117
|
-
debugLogger2.debug(
|
|
2118
|
-
"Failed to determine latest qwen-code-action release:",
|
|
2119
|
-
error
|
|
2120
|
-
);
|
|
2121
|
-
throw new SetupGithubError(
|
|
2122
|
-
"github_release_lookup_failed",
|
|
2123
|
-
"Unable to determine the latest qwen-code-action release on GitHub.",
|
|
2124
|
-
502
|
|
2125
|
-
);
|
|
2126
|
-
}
|
|
2127
|
-
const readmeUrl = `https://github.com/QwenLM/qwen-code-action/blob/${releaseTag}/README.md#quick-start`;
|
|
2128
|
-
const secretsUrl = await resolveSecretsUrl(cwd);
|
|
2129
|
-
const downloads = await downloadWorkflows({
|
|
2130
|
-
releaseTag,
|
|
2131
|
-
proxy: options.proxy,
|
|
2132
|
-
abortSignal: options.abortSignal,
|
|
2133
|
-
fetchImpl: options.fetchImpl ?? fetch
|
|
2134
|
-
});
|
|
2135
|
-
const result = {
|
|
2136
|
-
kind: "github_setup",
|
|
2137
|
-
workspaceCwd: options.workspaceRoot ?? gitRepoRoot,
|
|
2138
|
-
gitRepoRoot,
|
|
2139
|
-
releaseTag,
|
|
2140
|
-
readmeUrl,
|
|
2141
|
-
...secretsUrl ? { secretsUrl } : {},
|
|
2142
|
-
workflows: [],
|
|
2143
|
-
gitignore: { path: ".gitignore", status: "skipped" },
|
|
2144
|
-
warnings: []
|
|
2145
|
-
};
|
|
2146
|
-
result.gitignore = await updateGitignore(gitRepoRoot, fileOps);
|
|
2147
|
-
if (result.gitignore.status === "failed") {
|
|
2148
|
-
result.warnings.push("Failed to update .gitignore.");
|
|
2149
|
-
}
|
|
2150
|
-
try {
|
|
2151
|
-
await fileOps.ensureWorkflowDirectory(gitRepoRoot);
|
|
2152
|
-
for (const workflow of downloads) {
|
|
2153
|
-
const relativePath = path.posix.join(
|
|
2154
|
-
".github",
|
|
2155
|
-
"workflows",
|
|
2156
|
-
path.posix.basename(workflow.sourcePath)
|
|
2157
|
-
);
|
|
2158
|
-
try {
|
|
2159
|
-
const write = await fileOps.writeTextFile(
|
|
2160
|
-
gitRepoRoot,
|
|
2161
|
-
relativePath,
|
|
2162
|
-
workflow.content
|
|
2163
|
-
);
|
|
2164
|
-
result.workflows.push({
|
|
2165
|
-
sourcePath: workflow.sourcePath,
|
|
2166
|
-
path: relativePath,
|
|
2167
|
-
status: "written",
|
|
2168
|
-
sizeBytes: write.sizeBytes
|
|
2169
|
-
});
|
|
2170
|
-
} catch (error) {
|
|
2171
|
-
if (isWorkspaceGenerationClosed(error)) throw error;
|
|
2172
|
-
result.partial = true;
|
|
2173
|
-
result.workflows.push({
|
|
2174
|
-
sourcePath: workflow.sourcePath,
|
|
2175
|
-
path: relativePath,
|
|
2176
|
-
status: "failed",
|
|
2177
|
-
error: error instanceof Error ? error.message : String(error)
|
|
2178
|
-
});
|
|
2179
|
-
throw new SetupGithubError(
|
|
2180
|
-
"github_workflow_write_failed",
|
|
2181
|
-
`Unable to write ${relativePath}.`,
|
|
2182
|
-
500,
|
|
2183
|
-
result
|
|
2184
|
-
);
|
|
2185
|
-
}
|
|
2186
|
-
}
|
|
2187
|
-
} catch (error) {
|
|
2188
|
-
if (isWorkspaceGenerationClosed(error)) throw error;
|
|
2189
|
-
if (error instanceof SetupGithubError) throw error;
|
|
2190
|
-
throw new SetupGithubError(
|
|
2191
|
-
"github_workflow_write_failed",
|
|
2192
|
-
"Unable to create .github/workflows.",
|
|
2193
|
-
500,
|
|
2194
|
-
result
|
|
2195
|
-
);
|
|
2196
|
-
}
|
|
2197
|
-
return result;
|
|
2198
|
-
}
|
|
2199
|
-
__name(setupGithub, "setupGithub");
|
|
2200
|
-
async function updateGitignore(gitRepoRoot, fileOps = nodeFileOps) {
|
|
2201
|
-
try {
|
|
2202
|
-
const existingContent = await fileOps.readTextFile(
|
|
2203
|
-
gitRepoRoot,
|
|
2204
|
-
".gitignore"
|
|
2205
|
-
);
|
|
2206
|
-
if (existingContent === void 0) {
|
|
2207
|
-
const content = GITIGNORE_ENTRIES.join("\n") + "\n";
|
|
2208
|
-
await fileOps.writeTextFile(gitRepoRoot, ".gitignore", content);
|
|
2209
|
-
return {
|
|
2210
|
-
path: ".gitignore",
|
|
2211
|
-
status: "created",
|
|
2212
|
-
added: [...GITIGNORE_ENTRIES]
|
|
2213
|
-
};
|
|
2214
|
-
}
|
|
2215
|
-
const missingEntries = GITIGNORE_ENTRIES.filter(
|
|
2216
|
-
(entry) => !existingContent.split(/\r?\n/).some((line) => line.split("#")[0].trim() === entry)
|
|
2217
|
-
);
|
|
2218
|
-
if (missingEntries.length === 0) {
|
|
2219
|
-
return { path: ".gitignore", status: "unchanged" };
|
|
2220
|
-
}
|
|
2221
|
-
const nextContent = existingContent + "\n" + missingEntries.join("\n") + "\n";
|
|
2222
|
-
await fileOps.writeTextFile(gitRepoRoot, ".gitignore", nextContent);
|
|
2223
|
-
return {
|
|
2224
|
-
path: ".gitignore",
|
|
2225
|
-
status: "updated",
|
|
2226
|
-
added: missingEntries
|
|
2227
|
-
};
|
|
2228
|
-
} catch (error) {
|
|
2229
|
-
if (isWorkspaceGenerationClosed(error)) throw error;
|
|
2230
|
-
debugLogger2.debug("Failed to update .gitignore:", error);
|
|
2231
|
-
return {
|
|
2232
|
-
path: ".gitignore",
|
|
2233
|
-
status: "failed",
|
|
2234
|
-
error: error instanceof Error ? error.message : String(error)
|
|
2235
|
-
};
|
|
2236
|
-
}
|
|
2237
|
-
}
|
|
2238
|
-
__name(updateGitignore, "updateGitignore");
|
|
2239
|
-
async function downloadWorkflows(options) {
|
|
2240
|
-
const internalAbort = new AbortController();
|
|
2241
|
-
try {
|
|
2242
|
-
const dispatcher = options.proxy ? new (await loadUndici()).ProxyAgent(options.proxy) : void 0;
|
|
2243
|
-
return await Promise.all(
|
|
2244
|
-
GITHUB_WORKFLOW_PATHS.map(async (workflow) => {
|
|
2245
|
-
const endpoint = `https://raw.githubusercontent.com/QwenLM/qwen-code-action/refs/tags/${options.releaseTag}/examples/workflows/${workflow}`;
|
|
2246
|
-
const response = await options.fetchImpl(endpoint, {
|
|
2247
|
-
method: "GET",
|
|
2248
|
-
dispatcher,
|
|
2249
|
-
signal: AbortSignal.any([
|
|
2250
|
-
AbortSignal.timeout(3e4),
|
|
2251
|
-
internalAbort.signal,
|
|
2252
|
-
...options.abortSignal ? [options.abortSignal] : []
|
|
2253
|
-
])
|
|
2254
|
-
});
|
|
2255
|
-
if (!response.ok) {
|
|
2256
|
-
throw new Error(
|
|
2257
|
-
`Invalid response code downloading ${endpoint}: ${response.status} - ${response.statusText}`
|
|
2258
|
-
);
|
|
2259
|
-
}
|
|
2260
|
-
return {
|
|
2261
|
-
sourcePath: workflow,
|
|
2262
|
-
content: await readResponseTextWithLimit(response, workflow)
|
|
2263
|
-
};
|
|
2264
|
-
})
|
|
2265
|
-
);
|
|
2266
|
-
} catch (error) {
|
|
2267
|
-
internalAbort.abort();
|
|
2268
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2269
|
-
debugLogger2.debug("Failed to download qwen-code-action workflows:", error);
|
|
2270
|
-
throw new SetupGithubError(
|
|
2271
|
-
"github_workflow_download_failed",
|
|
2272
|
-
`Unable to download qwen-code-action workflows from GitHub. ${message}`,
|
|
2273
|
-
502
|
|
2274
|
-
);
|
|
2275
|
-
}
|
|
2276
|
-
}
|
|
2277
|
-
__name(downloadWorkflows, "downloadWorkflows");
|
|
2278
|
-
async function readResponseTextWithLimit(response, sourcePath) {
|
|
2279
|
-
const contentLength = response.headers.get("content-length");
|
|
2280
|
-
if (contentLength !== null) {
|
|
2281
|
-
const parsedLength = Number(contentLength);
|
|
2282
|
-
if (Number.isFinite(parsedLength) && parsedLength > MAX_WORKFLOW_DOWNLOAD_BYTES) {
|
|
2283
|
-
throw new Error(
|
|
2284
|
-
`${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
|
|
2285
|
-
);
|
|
2286
|
-
}
|
|
2287
|
-
}
|
|
2288
|
-
if (!response.body) return "";
|
|
2289
|
-
const reader = response.body.getReader();
|
|
2290
|
-
const chunks = [];
|
|
2291
|
-
let totalBytes = 0;
|
|
2292
|
-
try {
|
|
2293
|
-
while (true) {
|
|
2294
|
-
const { done, value } = await reader.read();
|
|
2295
|
-
if (done) break;
|
|
2296
|
-
if (!value) continue;
|
|
2297
|
-
totalBytes += value.byteLength;
|
|
2298
|
-
if (totalBytes > MAX_WORKFLOW_DOWNLOAD_BYTES) {
|
|
2299
|
-
await reader.cancel().catch(() => {
|
|
2300
|
-
});
|
|
2301
|
-
throw new Error(
|
|
2302
|
-
`${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
|
|
2303
|
-
);
|
|
2304
|
-
}
|
|
2305
|
-
chunks.push(value);
|
|
2306
|
-
}
|
|
2307
|
-
} finally {
|
|
2308
|
-
reader.releaseLock();
|
|
2309
|
-
}
|
|
2310
|
-
const body = new Uint8Array(totalBytes);
|
|
2311
|
-
let offset = 0;
|
|
2312
|
-
for (const chunk of chunks) {
|
|
2313
|
-
body.set(chunk, offset);
|
|
2314
|
-
offset += chunk.byteLength;
|
|
2315
|
-
}
|
|
2316
|
-
return new TextDecoder().decode(body);
|
|
2317
|
-
}
|
|
2318
|
-
__name(readResponseTextWithLimit, "readResponseTextWithLimit");
|
|
2319
|
-
async function resolveSecretsUrl(cwd) {
|
|
2320
|
-
try {
|
|
2321
|
-
const repoInfo = await getGitHubRepoInfoAsync({ cwd });
|
|
2322
|
-
return `https://github.com/${repoInfo.owner}/${repoInfo.repo}/settings/secrets/actions`;
|
|
2323
|
-
} catch {
|
|
2324
|
-
return void 0;
|
|
2325
|
-
}
|
|
2326
|
-
}
|
|
2327
|
-
__name(resolveSecretsUrl, "resolveSecretsUrl");
|
|
2328
|
-
async function realpathOrResolve(input) {
|
|
2329
|
-
try {
|
|
2330
|
-
return await fsp.realpath(input);
|
|
2331
|
-
} catch {
|
|
2332
|
-
return path.resolve(input);
|
|
2333
|
-
}
|
|
2334
|
-
}
|
|
2335
|
-
__name(realpathOrResolve, "realpathOrResolve");
|
|
2336
|
-
|
|
2337
|
-
// packages/cli/src/ui/utils/export/collect.ts
|
|
2338
|
-
init_esbuild_shims();
|
|
2339
|
-
import { randomUUID } from "node:crypto";
|
|
2340
|
-
|
|
2341
|
-
// packages/cli/src/utils/chat-record-tool-call-id.ts
|
|
2342
|
-
init_esbuild_shims();
|
|
2343
|
-
function getToolResultCallId(record) {
|
|
2344
|
-
return getExplicitToolResultCallId(record) ?? record.uuid;
|
|
2345
|
-
}
|
|
2346
|
-
__name(getToolResultCallId, "getToolResultCallId");
|
|
2347
|
-
function getExplicitToolResultCallId(record) {
|
|
2348
|
-
const resultCallId = record.toolCallResult?.callId;
|
|
2349
|
-
if (typeof resultCallId === "string" && resultCallId.length > 0) {
|
|
2350
|
-
return resultCallId;
|
|
2351
|
-
}
|
|
2352
|
-
return extractFunctionResponseId(record);
|
|
2353
|
-
}
|
|
2354
|
-
__name(getExplicitToolResultCallId, "getExplicitToolResultCallId");
|
|
2355
|
-
function extractFunctionResponseId(record) {
|
|
2356
|
-
if (!record.message?.parts) {
|
|
2357
|
-
return void 0;
|
|
2358
|
-
}
|
|
2359
|
-
for (const part of record.message.parts) {
|
|
2360
|
-
const id = "functionResponse" in part ? part.functionResponse?.id : void 0;
|
|
2361
|
-
if (typeof id === "string" && id.length > 0) {
|
|
2362
|
-
return id;
|
|
2363
|
-
}
|
|
2364
|
-
}
|
|
2365
|
-
return void 0;
|
|
2366
|
-
}
|
|
2367
|
-
__name(extractFunctionResponseId, "extractFunctionResponseId");
|
|
2368
|
-
|
|
2369
|
-
// packages/cli/src/ui/utils/export/collect.ts
|
|
2370
|
-
function extractToolNameFromRecord(record) {
|
|
2371
|
-
if (!record.message?.parts) {
|
|
2372
|
-
return void 0;
|
|
2373
|
-
}
|
|
2374
|
-
for (const part of record.message.parts) {
|
|
2375
|
-
if ("functionResponse" in part && part.functionResponse?.name) {
|
|
2376
|
-
return part.functionResponse.name;
|
|
2377
|
-
}
|
|
2378
|
-
}
|
|
2379
|
-
return void 0;
|
|
2380
|
-
}
|
|
2381
|
-
__name(extractToolNameFromRecord, "extractToolNameFromRecord");
|
|
2382
|
-
function normalizeFunctionCallArgs(args) {
|
|
2383
|
-
if (args && typeof args === "object") {
|
|
2384
|
-
return args;
|
|
2385
|
-
}
|
|
2386
|
-
if (typeof args === "string") {
|
|
2387
|
-
try {
|
|
2388
|
-
const parsed = JSON.parse(args);
|
|
2389
|
-
if (parsed && typeof parsed === "object") {
|
|
2390
|
-
return parsed;
|
|
2391
|
-
}
|
|
2392
|
-
} catch {
|
|
2393
|
-
}
|
|
2394
|
-
}
|
|
2395
|
-
return void 0;
|
|
2396
|
-
}
|
|
2397
|
-
__name(normalizeFunctionCallArgs, "normalizeFunctionCallArgs");
|
|
2398
|
-
function buildToolCallArgsIndex(records) {
|
|
2399
|
-
const byId = /* @__PURE__ */ new Map();
|
|
2400
|
-
const byName = /* @__PURE__ */ new Map();
|
|
2401
|
-
for (const record of records) {
|
|
2402
|
-
if (record.type !== "assistant" || !record.message?.parts) continue;
|
|
2403
|
-
for (const part of record.message.parts) {
|
|
2404
|
-
if (!("functionCall" in part) || !part.functionCall?.name) continue;
|
|
2405
|
-
const normalizedArgs = normalizeFunctionCallArgs(part.functionCall.args);
|
|
2406
|
-
if (!normalizedArgs) continue;
|
|
2407
|
-
const toolName = part.functionCall.name;
|
|
2408
|
-
const callId = typeof part.functionCall.id === "string" ? part.functionCall.id : null;
|
|
2409
|
-
if (callId) {
|
|
2410
|
-
byId.set(callId, normalizedArgs);
|
|
2411
|
-
}
|
|
2412
|
-
const queue = byName.get(toolName) ?? [];
|
|
2413
|
-
queue.push(normalizedArgs);
|
|
2414
|
-
byName.set(toolName, queue);
|
|
2415
|
-
}
|
|
2416
|
-
}
|
|
2417
|
-
return { byId, byName };
|
|
2418
|
-
}
|
|
2419
|
-
__name(buildToolCallArgsIndex, "buildToolCallArgsIndex");
|
|
2420
|
-
function calculateFileStats(records) {
|
|
2421
|
-
const argsIndex = buildToolCallArgsIndex(records);
|
|
2422
|
-
const byNameCursor = /* @__PURE__ */ new Map();
|
|
2423
|
-
const stats = {
|
|
2424
|
-
filesWritten: 0,
|
|
2425
|
-
linesAdded: 0,
|
|
2426
|
-
linesRemoved: 0,
|
|
2427
|
-
writtenFilePaths: /* @__PURE__ */ new Set()
|
|
2428
|
-
};
|
|
2429
|
-
for (const record of records) {
|
|
2430
|
-
if (record.type !== "tool_result" || !record.toolCallResult) continue;
|
|
2431
|
-
const toolName = extractToolNameFromRecord(record);
|
|
2432
|
-
const callId = getExplicitToolResultCallId(record);
|
|
2433
|
-
const argsFromId = callId && argsIndex.byId.has(callId) ? argsIndex.byId.get(callId) : void 0;
|
|
2434
|
-
let args = argsFromId;
|
|
2435
|
-
if (!args && toolName) {
|
|
2436
|
-
const queue = argsIndex.byName.get(toolName);
|
|
2437
|
-
if (queue && queue.length > 0) {
|
|
2438
|
-
const cursor = byNameCursor.get(toolName) ?? 0;
|
|
2439
|
-
args = queue[cursor];
|
|
2440
|
-
byNameCursor.set(toolName, cursor + 1);
|
|
2441
|
-
}
|
|
2442
|
-
}
|
|
2443
|
-
const { resultDisplay } = record.toolCallResult;
|
|
2444
|
-
if (resultDisplay && typeof resultDisplay === "object" && "fileName" in resultDisplay) {
|
|
2445
|
-
const display = resultDisplay;
|
|
2446
|
-
const hasOriginalContent = "originalContent" in display;
|
|
2447
|
-
const hasNewContent = "newContent" in display;
|
|
2448
|
-
let filePath;
|
|
2449
|
-
if (typeof display.fileName === "string") {
|
|
2450
|
-
filePath = args?.["file_path"] || display.fileName;
|
|
2451
|
-
} else {
|
|
2452
|
-
filePath = "unknown";
|
|
2453
|
-
}
|
|
2454
|
-
if (hasOriginalContent || hasNewContent) {
|
|
2455
|
-
stats.filesWritten++;
|
|
2456
|
-
stats.writtenFilePaths.add(filePath);
|
|
2457
|
-
if (display.diffStat) {
|
|
2458
|
-
stats.linesAdded += display.diffStat.model_added_lines ?? 0;
|
|
2459
|
-
stats.linesRemoved += display.diffStat.model_removed_lines ?? 0;
|
|
2460
|
-
} else if (!display.truncatedForSession) {
|
|
2461
|
-
const oldText = String(display.originalContent ?? "");
|
|
2462
|
-
const newText = String(display.newContent ?? "");
|
|
2463
|
-
const oldLines = oldText.split("\n").filter((line) => line.length > 0).length;
|
|
2464
|
-
const newLines = newText.split("\n").filter((line) => line.length > 0).length;
|
|
2465
|
-
stats.linesAdded += newLines;
|
|
2466
|
-
stats.linesRemoved += oldLines;
|
|
2467
|
-
}
|
|
2468
|
-
}
|
|
2469
|
-
}
|
|
2470
|
-
}
|
|
2471
|
-
return stats;
|
|
2472
|
-
}
|
|
2473
|
-
__name(calculateFileStats, "calculateFileStats");
|
|
2474
|
-
function extractTaskToolTokens(record) {
|
|
2475
|
-
if (record.type !== "tool_result" || !record.toolCallResult?.resultDisplay) {
|
|
2476
|
-
return 0;
|
|
2477
|
-
}
|
|
2478
|
-
const { resultDisplay } = record.toolCallResult;
|
|
2479
|
-
if (typeof resultDisplay === "object" && "type" in resultDisplay && resultDisplay.type === "task_execution" && "executionSummary" in resultDisplay) {
|
|
2480
|
-
const summary = resultDisplay.executionSummary;
|
|
2481
|
-
if (typeof summary.totalTokens === "number") {
|
|
2482
|
-
return summary.totalTokens;
|
|
2483
|
-
}
|
|
2484
|
-
return (summary.inputTokens ?? 0) + (summary.outputTokens ?? 0) + (summary.thoughtTokens ?? 0) + (summary.cachedTokens ?? 0);
|
|
2485
|
-
}
|
|
2486
|
-
return 0;
|
|
2487
|
-
}
|
|
2488
|
-
__name(extractTaskToolTokens, "extractTaskToolTokens");
|
|
2489
|
-
function calculateTokenStats(records) {
|
|
2490
|
-
let totalTokens = 0;
|
|
2491
|
-
let lastValidRecord = null;
|
|
2492
|
-
for (const record of records) {
|
|
2493
|
-
if (record.type === "assistant") {
|
|
2494
|
-
if (record.usageMetadata) {
|
|
2495
|
-
totalTokens += record.usageMetadata.totalTokenCount ?? 0;
|
|
2496
|
-
}
|
|
2497
|
-
if (record.usageMetadata?.totalTokenCount !== void 0 && record.contextWindowSize !== void 0) {
|
|
2498
|
-
lastValidRecord = {
|
|
2499
|
-
totalTokenCount: record.usageMetadata.totalTokenCount,
|
|
2500
|
-
contextWindowSize: record.contextWindowSize
|
|
2501
|
-
};
|
|
2502
|
-
}
|
|
2503
|
-
}
|
|
2504
|
-
const taskTokens = extractTaskToolTokens(record);
|
|
2505
|
-
if (taskTokens > 0) {
|
|
2506
|
-
totalTokens += taskTokens;
|
|
2507
|
-
}
|
|
2508
|
-
}
|
|
2509
|
-
if (lastValidRecord) {
|
|
2510
|
-
const percent = lastValidRecord.totalTokenCount / lastValidRecord.contextWindowSize * 100;
|
|
2511
|
-
return {
|
|
2512
|
-
totalTokens,
|
|
2513
|
-
contextUsagePercent: Math.round(percent * 10) / 10,
|
|
2514
|
-
contextWindowSize: lastValidRecord.contextWindowSize
|
|
2515
|
-
};
|
|
2516
|
-
}
|
|
2517
|
-
const lastAssistantRecord = [...records].reverse().find((r) => r.type === "assistant" && r.contextWindowSize !== void 0);
|
|
2518
|
-
return {
|
|
2519
|
-
totalTokens,
|
|
2520
|
-
contextWindowSize: lastAssistantRecord?.contextWindowSize
|
|
2521
|
-
};
|
|
2522
|
-
}
|
|
2523
|
-
__name(calculateTokenStats, "calculateTokenStats");
|
|
2524
|
-
function createExportSessionConfig(config) {
|
|
2525
|
-
const supportedConfig = {
|
|
2526
|
-
...config,
|
|
2527
|
-
getToolRegistry: /* @__PURE__ */ __name(() => {
|
|
2528
|
-
const registry = config.getToolRegistry?.();
|
|
2529
|
-
return {
|
|
2530
|
-
getTool: /* @__PURE__ */ __name((toolName) => registry?.getTool?.(toolName) ?? null, "getTool")
|
|
2531
|
-
};
|
|
2532
|
-
}, "getToolRegistry")
|
|
2533
|
-
};
|
|
2534
|
-
return new Proxy(supportedConfig, {
|
|
2535
|
-
get(target, prop, receiver) {
|
|
2536
|
-
if (prop in target) {
|
|
2537
|
-
return Reflect.get(target, prop, receiver);
|
|
2538
|
-
}
|
|
2539
|
-
if (typeof prop === "symbol") {
|
|
2540
|
-
return void 0;
|
|
2541
|
-
}
|
|
2542
|
-
throw new Error(
|
|
2543
|
-
`Export session replay config does not implement ${prop}`
|
|
2544
|
-
);
|
|
2545
|
-
}
|
|
2546
|
-
});
|
|
2547
|
-
}
|
|
2548
|
-
__name(createExportSessionConfig, "createExportSessionConfig");
|
|
2549
|
-
async function extractMetadata(conversation, config) {
|
|
2550
|
-
const { sessionId, startTime, messages } = conversation;
|
|
2551
|
-
const firstRecord = messages[0];
|
|
2552
|
-
const cwd = firstRecord?.cwd ?? "";
|
|
2553
|
-
const gitBranch = firstRecord?.gitBranch;
|
|
2554
|
-
let gitRepo;
|
|
2555
|
-
if (cwd) {
|
|
2556
|
-
const { getGitRepoName } = await import("./deferred-core-runtime-3SGXFXEQ.js");
|
|
2557
|
-
gitRepo = getGitRepoName(cwd);
|
|
2558
|
-
}
|
|
2559
|
-
let model;
|
|
2560
|
-
for (const record of messages) {
|
|
2561
|
-
if (record.type === "assistant" && record.model) {
|
|
2562
|
-
model = record.model;
|
|
2563
|
-
break;
|
|
2564
|
-
}
|
|
2565
|
-
}
|
|
2566
|
-
const channel = config.getChannel?.();
|
|
2567
|
-
const promptCount = messages.filter((m) => m.type === "user").length;
|
|
2568
|
-
const fileStats = calculateFileStats(messages);
|
|
2569
|
-
const tokenStats = calculateTokenStats(messages);
|
|
2570
|
-
return {
|
|
2571
|
-
sessionId,
|
|
2572
|
-
startTime,
|
|
2573
|
-
exportTime: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2574
|
-
cwd,
|
|
2575
|
-
gitRepo,
|
|
2576
|
-
gitBranch,
|
|
2577
|
-
model,
|
|
2578
|
-
channel,
|
|
2579
|
-
promptCount,
|
|
2580
|
-
contextUsagePercent: tokenStats.contextUsagePercent,
|
|
2581
|
-
contextWindowSize: tokenStats.contextWindowSize,
|
|
2582
|
-
totalTokens: tokenStats.totalTokens,
|
|
2583
|
-
filesWritten: fileStats.writtenFilePaths.size,
|
|
2584
|
-
linesAdded: fileStats.linesAdded,
|
|
2585
|
-
linesRemoved: fileStats.linesRemoved,
|
|
2586
|
-
uniqueFiles: Array.from(fileStats.writtenFilePaths)
|
|
2587
|
-
};
|
|
2588
|
-
}
|
|
2589
|
-
__name(extractMetadata, "extractMetadata");
|
|
2590
|
-
var ExportSessionContext = class {
|
|
2591
|
-
static {
|
|
2592
|
-
__name(this, "ExportSessionContext");
|
|
2593
|
-
}
|
|
2594
|
-
sessionId;
|
|
2595
|
-
config;
|
|
2596
|
-
messages = [];
|
|
2597
|
-
currentMessage = null;
|
|
2598
|
-
activeRecordId = null;
|
|
2599
|
-
activeRecordTimestamp = null;
|
|
2600
|
-
toolCallMap = /* @__PURE__ */ new Map();
|
|
2601
|
-
constructor(sessionId, config) {
|
|
2602
|
-
this.sessionId = sessionId;
|
|
2603
|
-
this.config = createExportSessionConfig(config);
|
|
2604
|
-
}
|
|
2605
|
-
async sendUpdate(update) {
|
|
2606
|
-
switch (update.sessionUpdate) {
|
|
2607
|
-
case "user_message_chunk":
|
|
2608
|
-
this.handleMessageChunk("user", update.content);
|
|
2609
|
-
break;
|
|
2610
|
-
case "agent_message_chunk": {
|
|
2611
|
-
const usageMeta = update._meta;
|
|
2612
|
-
const usageMetadata = usageMeta?.usage ? {
|
|
2613
|
-
promptTokenCount: usageMeta.usage.inputTokens,
|
|
2614
|
-
candidatesTokenCount: usageMeta.usage.outputTokens,
|
|
2615
|
-
totalTokenCount: usageMeta.usage.totalTokens,
|
|
2616
|
-
thoughtsTokenCount: usageMeta.usage.thoughtTokens,
|
|
2617
|
-
cachedContentTokenCount: usageMeta.usage.cachedReadTokens
|
|
2618
|
-
} : void 0;
|
|
2619
|
-
this.handleMessageChunk(
|
|
2620
|
-
"assistant",
|
|
2621
|
-
update.content,
|
|
2622
|
-
"assistant",
|
|
2623
|
-
usageMetadata
|
|
2624
|
-
);
|
|
2625
|
-
break;
|
|
2626
|
-
}
|
|
2627
|
-
case "agent_thought_chunk":
|
|
2628
|
-
this.handleMessageChunk("assistant", update.content, "thinking");
|
|
2629
|
-
break;
|
|
2630
|
-
case "tool_call":
|
|
2631
|
-
this.flushCurrentMessage();
|
|
2632
|
-
this.handleToolCallStart(update);
|
|
2633
|
-
break;
|
|
2634
|
-
case "tool_call_update":
|
|
2635
|
-
this.handleToolCallUpdate(update);
|
|
2636
|
-
break;
|
|
2637
|
-
case "plan":
|
|
2638
|
-
this.flushCurrentMessage();
|
|
2639
|
-
this.handlePlanUpdate(update);
|
|
2640
|
-
break;
|
|
2641
|
-
default:
|
|
2642
|
-
break;
|
|
2643
|
-
}
|
|
2644
|
-
}
|
|
2645
|
-
setActiveRecordId(recordId, timestamp) {
|
|
2646
|
-
this.activeRecordId = recordId;
|
|
2647
|
-
this.activeRecordTimestamp = timestamp ?? null;
|
|
2648
|
-
}
|
|
2649
|
-
getMessageTimestamp() {
|
|
2650
|
-
return this.activeRecordTimestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
2651
|
-
}
|
|
2652
|
-
getMessageUuid() {
|
|
2653
|
-
return this.activeRecordId ?? randomUUID();
|
|
2654
|
-
}
|
|
2655
|
-
handleMessageChunk(role, content, messageRole = role, usageMetadata) {
|
|
2656
|
-
if (content.type !== "text" || !content.text) return;
|
|
2657
|
-
if (this.currentMessage && (this.currentMessage.type !== role || this.currentMessage.role !== messageRole)) {
|
|
2658
|
-
this.flushCurrentMessage();
|
|
2659
|
-
}
|
|
2660
|
-
if (this.currentMessage && this.currentMessage.type === role && this.currentMessage.role === messageRole) {
|
|
2661
|
-
this.currentMessage.parts.push({ text: content.text });
|
|
2662
|
-
if (usageMetadata && role === "assistant") {
|
|
2663
|
-
this.currentMessage.usageMetadata = usageMetadata;
|
|
2664
|
-
}
|
|
2665
|
-
} else {
|
|
2666
|
-
this.currentMessage = {
|
|
2667
|
-
type: role,
|
|
2668
|
-
role: messageRole,
|
|
2669
|
-
parts: [{ text: content.text }],
|
|
2670
|
-
timestamp: Date.now(),
|
|
2671
|
-
...usageMetadata && role === "assistant" ? { usageMetadata } : {}
|
|
2672
|
-
};
|
|
2673
|
-
}
|
|
2674
|
-
}
|
|
2675
|
-
handleToolCallStart(update) {
|
|
2676
|
-
const toolCall = {
|
|
2677
|
-
toolCallId: update.toolCallId,
|
|
2678
|
-
kind: update.kind || "other",
|
|
2679
|
-
title: typeof update.title === "string" ? update.title : update.title || "",
|
|
2680
|
-
status: update.status || "pending",
|
|
2681
|
-
rawInput: update.rawInput,
|
|
2682
|
-
locations: update.locations,
|
|
2683
|
-
timestamp: Date.now()
|
|
2684
|
-
};
|
|
2685
|
-
this.toolCallMap.set(update.toolCallId, toolCall);
|
|
2686
|
-
const uuid = this.getMessageUuid();
|
|
2687
|
-
this.messages.push({
|
|
2688
|
-
uuid,
|
|
2689
|
-
sessionId: this.sessionId,
|
|
2690
|
-
timestamp: this.getMessageTimestamp(),
|
|
2691
|
-
type: "tool_call",
|
|
2692
|
-
toolCall
|
|
2693
|
-
});
|
|
2694
|
-
}
|
|
2695
|
-
handleToolCallUpdate(update) {
|
|
2696
|
-
const toolCall = this.toolCallMap.get(update.toolCallId);
|
|
2697
|
-
if (toolCall) {
|
|
2698
|
-
if (update.status) toolCall.status = update.status;
|
|
2699
|
-
if (update.content) toolCall.content = update.content;
|
|
2700
|
-
if (update.title)
|
|
2701
|
-
toolCall.title = typeof update.title === "string" ? update.title : "";
|
|
2702
|
-
}
|
|
2703
|
-
}
|
|
2704
|
-
handlePlanUpdate(update) {
|
|
2705
|
-
const uuid = this.getMessageUuid();
|
|
2706
|
-
const timestamp = this.getMessageTimestamp();
|
|
2707
|
-
const todoText = update.entries.map((entry) => {
|
|
2708
|
-
const checkbox = entry.status === "completed" ? "[x]" : entry.status === "in_progress" ? "[-]" : "[ ]";
|
|
2709
|
-
return `- ${checkbox} ${entry.content}`;
|
|
2710
|
-
}).join("\n");
|
|
2711
|
-
const todoContent = [
|
|
2712
|
-
{
|
|
2713
|
-
type: "content",
|
|
2714
|
-
content: {
|
|
2715
|
-
type: "text",
|
|
2716
|
-
text: todoText
|
|
2717
|
-
}
|
|
2718
|
-
}
|
|
2719
|
-
];
|
|
2720
|
-
this.messages.push({
|
|
2721
|
-
uuid,
|
|
2722
|
-
sessionId: this.sessionId,
|
|
2723
|
-
timestamp,
|
|
2724
|
-
type: "tool_call",
|
|
2725
|
-
toolCall: {
|
|
2726
|
-
toolCallId: uuid,
|
|
2727
|
-
// Use the same uuid as toolCallId for plan updates
|
|
2728
|
-
kind: "todowrite",
|
|
2729
|
-
title: "TodoList",
|
|
2730
|
-
status: "completed",
|
|
2731
|
-
content: todoContent,
|
|
2732
|
-
timestamp: Date.parse(timestamp)
|
|
2733
|
-
}
|
|
2734
|
-
});
|
|
2735
|
-
}
|
|
2736
|
-
flushCurrentMessage() {
|
|
2737
|
-
if (!this.currentMessage) return;
|
|
2738
|
-
const uuid = this.getMessageUuid();
|
|
2739
|
-
const exportMessage = {
|
|
2740
|
-
uuid,
|
|
2741
|
-
sessionId: this.sessionId,
|
|
2742
|
-
timestamp: this.getMessageTimestamp(),
|
|
2743
|
-
type: this.currentMessage.type,
|
|
2744
|
-
message: {
|
|
2745
|
-
role: this.currentMessage.role,
|
|
2746
|
-
parts: this.currentMessage.parts
|
|
2747
|
-
}
|
|
2748
|
-
};
|
|
2749
|
-
if (this.currentMessage.type === "assistant" && this.currentMessage.usageMetadata) {
|
|
2750
|
-
exportMessage.usageMetadata = this.currentMessage.usageMetadata;
|
|
2751
|
-
}
|
|
2752
|
-
this.messages.push(exportMessage);
|
|
2753
|
-
this.currentMessage = null;
|
|
2754
|
-
}
|
|
2755
|
-
flushMessages() {
|
|
2756
|
-
this.flushCurrentMessage();
|
|
2757
|
-
}
|
|
2758
|
-
getMessages() {
|
|
2759
|
-
return this.messages;
|
|
2760
|
-
}
|
|
2761
|
-
};
|
|
2762
|
-
async function collectSessionData(conversation, config) {
|
|
2763
|
-
const exportContext = new ExportSessionContext(
|
|
2764
|
-
conversation.sessionId,
|
|
2765
|
-
config
|
|
2766
|
-
);
|
|
2767
|
-
const replayer = new HistoryReplayer(exportContext);
|
|
2768
|
-
await replayer.replay(conversation.messages);
|
|
2769
|
-
exportContext.flushMessages();
|
|
2770
|
-
const messages = exportContext.getMessages();
|
|
2771
|
-
const metadata = await extractMetadata(conversation, config);
|
|
2772
|
-
return {
|
|
2773
|
-
sessionId: conversation.sessionId,
|
|
2774
|
-
startTime: conversation.startTime,
|
|
2775
|
-
messages,
|
|
2776
|
-
metadata
|
|
2777
|
-
};
|
|
2778
|
-
}
|
|
2779
|
-
__name(collectSessionData, "collectSessionData");
|
|
2780
|
-
|
|
2781
|
-
// packages/cli/src/ui/utils/export/normalize.ts
|
|
2782
|
-
init_esbuild_shims();
|
|
2783
|
-
|
|
2784
|
-
// packages/cli/src/utils/truncatedDiffPreview.ts
|
|
2785
|
-
init_esbuild_shims();
|
|
2786
|
-
function buildTruncatedDiffPreviewText2(display) {
|
|
2787
|
-
const fileName = typeof display["fileName"] === "string" ? display["fileName"] : "the edited file";
|
|
2788
|
-
const fileDiffLength = typeof display["fileDiffLength"] === "number" ? ` Original fileDiff length: ${display["fileDiffLength"]} chars.` : "";
|
|
2789
|
-
if (display["fileDiffTruncated"] === true) {
|
|
2790
|
-
return `Full diff omitted from saved session history for ${fileName}.${fileDiffLength}`;
|
|
2791
|
-
}
|
|
2792
|
-
return `Saved session preview only for ${fileName}; full original and new file contents are unavailable.`;
|
|
2793
|
-
}
|
|
2794
|
-
__name(buildTruncatedDiffPreviewText2, "buildTruncatedDiffPreviewText");
|
|
2795
|
-
|
|
2796
|
-
// packages/cli/src/ui/utils/export/normalize.ts
|
|
2797
|
-
function normalizeSessionData(sessionData, originalRecords, config) {
|
|
2798
|
-
const normalized = [...sessionData.messages];
|
|
2799
|
-
const toolCallIndexById = /* @__PURE__ */ new Map();
|
|
2800
|
-
normalized.forEach((message, index) => {
|
|
2801
|
-
if (message.type === "tool_call" && message.toolCall?.toolCallId) {
|
|
2802
|
-
toolCallIndexById.set(message.toolCall.toolCallId, index);
|
|
2803
|
-
}
|
|
2804
|
-
});
|
|
2805
|
-
const assistantMessageIndexByUuid = /* @__PURE__ */ new Map();
|
|
2806
|
-
normalized.forEach((message, index) => {
|
|
2807
|
-
if (message.type === "assistant") {
|
|
2808
|
-
assistantMessageIndexByUuid.set(message.uuid, index);
|
|
2809
|
-
}
|
|
2810
|
-
});
|
|
2811
|
-
for (const record of originalRecords) {
|
|
2812
|
-
if (record.type !== "tool_result") continue;
|
|
2813
|
-
const toolCallMessage = buildToolCallMessageFromResult(record, config);
|
|
2814
|
-
if (!toolCallMessage?.toolCall) continue;
|
|
2815
|
-
const existingIndex = toolCallIndexById.get(
|
|
2816
|
-
toolCallMessage.toolCall.toolCallId
|
|
2817
|
-
);
|
|
2818
|
-
if (existingIndex === void 0) {
|
|
2819
|
-
toolCallIndexById.set(
|
|
2820
|
-
toolCallMessage.toolCall.toolCallId,
|
|
2821
|
-
normalized.length
|
|
2822
|
-
);
|
|
2823
|
-
normalized.push(toolCallMessage);
|
|
2824
|
-
continue;
|
|
2825
|
-
}
|
|
2826
|
-
const existingMessage = normalized[existingIndex];
|
|
2827
|
-
if (existingMessage.type !== "tool_call" || !existingMessage.toolCall) {
|
|
2828
|
-
continue;
|
|
2829
|
-
}
|
|
2830
|
-
mergeToolCallData(existingMessage.toolCall, toolCallMessage.toolCall);
|
|
2831
|
-
}
|
|
2832
|
-
for (const record of originalRecords) {
|
|
2833
|
-
if (record.type !== "assistant") continue;
|
|
2834
|
-
if (!record.usageMetadata) continue;
|
|
2835
|
-
const existingIndex = assistantMessageIndexByUuid.get(record.uuid);
|
|
2836
|
-
if (existingIndex !== void 0) {
|
|
2837
|
-
if (!normalized[existingIndex].usageMetadata) {
|
|
2838
|
-
normalized[existingIndex].usageMetadata = record.usageMetadata;
|
|
2839
|
-
}
|
|
2840
|
-
}
|
|
2841
|
-
}
|
|
2842
|
-
return {
|
|
2843
|
-
...sessionData,
|
|
2844
|
-
messages: normalized
|
|
2845
|
-
};
|
|
2846
|
-
}
|
|
2847
|
-
__name(normalizeSessionData, "normalizeSessionData");
|
|
2848
|
-
function mergeToolCallData(existing, incoming) {
|
|
2849
|
-
if (!existing.content || existing.content.length === 0) {
|
|
2850
|
-
existing.content = incoming.content;
|
|
2851
|
-
}
|
|
2852
|
-
if (existing.status === "pending" || existing.status === "in_progress") {
|
|
2853
|
-
existing.status = incoming.status;
|
|
2854
|
-
}
|
|
2855
|
-
if (!existing.rawInput && incoming.rawInput) {
|
|
2856
|
-
existing.rawInput = incoming.rawInput;
|
|
2857
|
-
}
|
|
2858
|
-
if (!existing.kind || existing.kind === "other") {
|
|
2859
|
-
existing.kind = incoming.kind;
|
|
2860
|
-
}
|
|
2861
|
-
if ((!existing.title || existing.title === "") && incoming.title) {
|
|
2862
|
-
existing.title = incoming.title;
|
|
2863
|
-
}
|
|
2864
|
-
if ((!existing.locations || existing.locations.length === 0) && incoming.locations && incoming.locations.length > 0) {
|
|
2865
|
-
existing.locations = incoming.locations;
|
|
2866
|
-
}
|
|
2867
|
-
}
|
|
2868
|
-
__name(mergeToolCallData, "mergeToolCallData");
|
|
2869
|
-
function buildToolCallMessageFromResult(record, config) {
|
|
2870
|
-
const toolCallResult = record.toolCallResult;
|
|
2871
|
-
const toolName = extractToolNameFromRecord2(record);
|
|
2872
|
-
if (toolName === ToolNames.TODO_WRITE) {
|
|
2873
|
-
return null;
|
|
2874
|
-
}
|
|
2875
|
-
const toolCallId = getToolResultCallId(record);
|
|
2876
|
-
const functionCallArgs = extractFunctionCallArgs(record);
|
|
2877
|
-
const { kind, title, locations } = resolveToolMetadata(
|
|
2878
|
-
config,
|
|
2879
|
-
toolName,
|
|
2880
|
-
functionCallArgs ?? toolCallResult?.args
|
|
2881
|
-
);
|
|
2882
|
-
const rawInput = normalizeRawInput(
|
|
2883
|
-
functionCallArgs ?? toolCallResult?.args
|
|
2884
|
-
);
|
|
2885
|
-
const resultContent = extractDiffContent2(toolCallResult?.resultDisplay) ?? transformPartsToToolCallContent(record.message?.parts ?? []);
|
|
2886
|
-
const content = isVisionBridgeNoticeDisplay(toolCallResult?.resultDisplay) ? [
|
|
2887
|
-
{
|
|
2888
|
-
type: "content",
|
|
2889
|
-
content: {
|
|
2890
|
-
type: "text",
|
|
2891
|
-
text: sanitizeTerminalText(
|
|
2892
|
-
formatVisionBridgeNoticeDisplay(toolCallResult.resultDisplay)
|
|
2893
|
-
)
|
|
2894
|
-
}
|
|
2895
|
-
},
|
|
2896
|
-
...resultContent
|
|
2897
|
-
] : resultContent;
|
|
2898
|
-
return {
|
|
2899
|
-
uuid: record.uuid,
|
|
2900
|
-
parentUuid: record.parentUuid,
|
|
2901
|
-
sessionId: record.sessionId,
|
|
2902
|
-
timestamp: record.timestamp,
|
|
2903
|
-
type: "tool_call",
|
|
2904
|
-
toolCall: {
|
|
2905
|
-
toolCallId,
|
|
2906
|
-
kind,
|
|
2907
|
-
title,
|
|
2908
|
-
status: toolCallResult?.error ? "failed" : "completed",
|
|
2909
|
-
rawInput,
|
|
2910
|
-
content,
|
|
2911
|
-
locations,
|
|
2912
|
-
timestamp: Date.parse(record.timestamp)
|
|
2913
|
-
}
|
|
2914
|
-
};
|
|
2915
|
-
}
|
|
2916
|
-
__name(buildToolCallMessageFromResult, "buildToolCallMessageFromResult");
|
|
2917
|
-
function extractToolNameFromRecord2(record) {
|
|
2918
|
-
if (!record.message?.parts) {
|
|
2919
|
-
return "";
|
|
2920
|
-
}
|
|
2921
|
-
for (const part of record.message.parts) {
|
|
2922
|
-
if ("functionResponse" in part && part.functionResponse?.name) {
|
|
2923
|
-
return part.functionResponse.name;
|
|
2924
|
-
}
|
|
2925
|
-
}
|
|
2926
|
-
return "";
|
|
2927
|
-
}
|
|
2928
|
-
__name(extractToolNameFromRecord2, "extractToolNameFromRecord");
|
|
2929
|
-
function extractFunctionCallArgs(record) {
|
|
2930
|
-
if (!record.message?.parts) {
|
|
2931
|
-
return void 0;
|
|
2932
|
-
}
|
|
2933
|
-
for (const part of record.message.parts) {
|
|
2934
|
-
if ("functionCall" in part && part.functionCall?.args) {
|
|
2935
|
-
return part.functionCall.args;
|
|
2936
|
-
}
|
|
2937
|
-
}
|
|
2938
|
-
return void 0;
|
|
2939
|
-
}
|
|
2940
|
-
__name(extractFunctionCallArgs, "extractFunctionCallArgs");
|
|
2941
|
-
function resolveToolMetadata(config, toolName, args) {
|
|
2942
|
-
const toolRegistry = config.getToolRegistry?.();
|
|
2943
|
-
const tool = toolName ? toolRegistry?.getTool?.(toolName) : void 0;
|
|
2944
|
-
let title = tool?.displayName ?? toolName ?? "tool_call";
|
|
2945
|
-
let locations;
|
|
2946
|
-
const kind = mapToolKind(tool?.kind, toolName);
|
|
2947
|
-
if (tool?.build && args) {
|
|
2948
|
-
try {
|
|
2949
|
-
const invocation = tool.build(args);
|
|
2950
|
-
title = `${title}: ${invocation.getDescription()}`;
|
|
2951
|
-
locations = invocation.toolLocations().map((loc) => ({
|
|
2952
|
-
path: loc.path,
|
|
2953
|
-
line: loc.line ?? null
|
|
2954
|
-
}));
|
|
2955
|
-
} catch {
|
|
2956
|
-
}
|
|
2957
|
-
}
|
|
2958
|
-
return { kind, title, locations };
|
|
2959
|
-
}
|
|
2960
|
-
__name(resolveToolMetadata, "resolveToolMetadata");
|
|
2961
|
-
function mapToolKind(kind, toolName) {
|
|
2962
|
-
if (toolName && (toolName === ToolNames.EXIT_PLAN_MODE || toolName === ToolNames.ENTER_PLAN_MODE)) {
|
|
2963
|
-
return "switch_mode";
|
|
2964
|
-
}
|
|
2965
|
-
if (toolName && toolName === ToolNames.TODO_WRITE) {
|
|
2966
|
-
return "todowrite";
|
|
2967
|
-
}
|
|
2968
|
-
const allowedKinds = /* @__PURE__ */ new Set([
|
|
2969
|
-
"read",
|
|
2970
|
-
"edit",
|
|
2971
|
-
"delete",
|
|
2972
|
-
"move",
|
|
2973
|
-
"search",
|
|
2974
|
-
"execute",
|
|
2975
|
-
"think",
|
|
2976
|
-
"fetch",
|
|
2977
|
-
"other"
|
|
2978
|
-
]);
|
|
2979
|
-
if (kind && allowedKinds.has(kind)) {
|
|
2980
|
-
return kind;
|
|
2981
|
-
}
|
|
2982
|
-
return "other";
|
|
2983
|
-
}
|
|
2984
|
-
__name(mapToolKind, "mapToolKind");
|
|
2985
|
-
function extractDiffContent2(resultDisplay) {
|
|
2986
|
-
if (!resultDisplay || typeof resultDisplay !== "object") {
|
|
2987
|
-
return null;
|
|
2988
|
-
}
|
|
2989
|
-
const display = resultDisplay;
|
|
2990
|
-
if ("fileName" in display && "newContent" in display) {
|
|
2991
|
-
if (display["truncatedForSession"] === true) {
|
|
2992
|
-
return [
|
|
2993
|
-
{
|
|
2994
|
-
type: "content",
|
|
2995
|
-
content: {
|
|
2996
|
-
type: "text",
|
|
2997
|
-
text: buildTruncatedDiffPreviewText2(display)
|
|
2998
|
-
}
|
|
2999
|
-
}
|
|
3000
|
-
];
|
|
3001
|
-
}
|
|
3002
|
-
return [
|
|
3003
|
-
{
|
|
3004
|
-
type: "diff",
|
|
3005
|
-
path: display["fileName"],
|
|
3006
|
-
oldText: display["originalContent"] ?? "",
|
|
3007
|
-
newText: display["newContent"]
|
|
3008
|
-
}
|
|
3009
|
-
];
|
|
3010
|
-
}
|
|
3011
|
-
return null;
|
|
3012
|
-
}
|
|
3013
|
-
__name(extractDiffContent2, "extractDiffContent");
|
|
3014
|
-
function normalizeRawInput(value) {
|
|
3015
|
-
if (typeof value === "string") return value;
|
|
3016
|
-
if (typeof value === "object" && value !== null) return value;
|
|
3017
|
-
return void 0;
|
|
3018
|
-
}
|
|
3019
|
-
__name(normalizeRawInput, "normalizeRawInput");
|
|
3020
|
-
function transformPartsToToolCallContent(parts) {
|
|
3021
|
-
const content = [];
|
|
3022
|
-
for (const part of parts) {
|
|
3023
|
-
if ("text" in part && part.text) {
|
|
3024
|
-
content.push({
|
|
3025
|
-
type: "content",
|
|
3026
|
-
content: { type: "text", text: part.text }
|
|
3027
|
-
});
|
|
3028
|
-
continue;
|
|
3029
|
-
}
|
|
3030
|
-
if ("functionResponse" in part && part.functionResponse) {
|
|
3031
|
-
const response = part.functionResponse.response;
|
|
3032
|
-
const outputField = response?.["output"];
|
|
3033
|
-
const errorField = response?.["error"];
|
|
3034
|
-
const responseText = typeof outputField === "string" ? outputField : typeof errorField === "string" ? errorField : JSON.stringify(response);
|
|
3035
|
-
content.push({
|
|
3036
|
-
type: "content",
|
|
3037
|
-
content: { type: "text", text: responseText }
|
|
3038
|
-
});
|
|
3039
|
-
}
|
|
3040
|
-
}
|
|
3041
|
-
return content;
|
|
3042
|
-
}
|
|
3043
|
-
__name(transformPartsToToolCallContent, "transformPartsToToolCallContent");
|
|
3044
|
-
|
|
3045
|
-
// packages/cli/src/ui/utils/export/formatters/markdown.ts
|
|
3046
|
-
init_esbuild_shims();
|
|
3047
|
-
function toMarkdown(sessionData) {
|
|
3048
|
-
const lines = [];
|
|
3049
|
-
const metadata = sessionData.metadata;
|
|
3050
|
-
lines.push("# Chat Session Export\n");
|
|
3051
|
-
lines.push(`- **Session ID**: \`${sanitizeText(sessionData.sessionId)}\``);
|
|
3052
|
-
lines.push(`- **Start Time**: ${sanitizeText(sessionData.startTime)}`);
|
|
3053
|
-
lines.push(
|
|
3054
|
-
`- **Exported**: ${sanitizeText(metadata?.exportTime ?? (/* @__PURE__ */ new Date()).toISOString())}`
|
|
3055
|
-
);
|
|
3056
|
-
lines.push("");
|
|
3057
|
-
if (metadata?.cwd) {
|
|
3058
|
-
lines.push(`- **Working Directory**: \`${sanitizeText(metadata.cwd)}\``);
|
|
3059
|
-
}
|
|
3060
|
-
if (metadata?.gitRepo) {
|
|
3061
|
-
lines.push(`- **Git Repository**: ${sanitizeText(metadata.gitRepo)}`);
|
|
3062
|
-
}
|
|
3063
|
-
if (metadata?.gitBranch) {
|
|
3064
|
-
lines.push(`- **Git Branch**: \`${sanitizeText(metadata.gitBranch)}\``);
|
|
3065
|
-
}
|
|
3066
|
-
lines.push("");
|
|
3067
|
-
if (metadata?.model) {
|
|
3068
|
-
lines.push(`- **Model**: ${sanitizeText(metadata.model)}`);
|
|
3069
|
-
}
|
|
3070
|
-
if (metadata?.channel) {
|
|
3071
|
-
lines.push(`- **Channel**: ${sanitizeText(metadata.channel)}`);
|
|
3072
|
-
}
|
|
3073
|
-
if (metadata?.promptCount !== void 0) {
|
|
3074
|
-
lines.push(`- **Prompt Count**: ${metadata.promptCount}`);
|
|
3075
|
-
}
|
|
3076
|
-
lines.push("");
|
|
3077
|
-
if (metadata?.totalTokens !== void 0) {
|
|
3078
|
-
lines.push(`- **Total Tokens**: ${metadata.totalTokens}`);
|
|
3079
|
-
}
|
|
3080
|
-
if (metadata?.contextWindowSize !== void 0) {
|
|
3081
|
-
lines.push(`- **Context Window Size**: ${metadata.contextWindowSize}`);
|
|
3082
|
-
}
|
|
3083
|
-
if (metadata?.contextUsagePercent !== void 0) {
|
|
3084
|
-
lines.push(`- **Context Usage**: ${metadata.contextUsagePercent}%`);
|
|
3085
|
-
}
|
|
3086
|
-
lines.push("");
|
|
3087
|
-
if (metadata?.filesWritten !== void 0) {
|
|
3088
|
-
lines.push(`- **Files Written**: ${metadata.filesWritten}`);
|
|
3089
|
-
}
|
|
3090
|
-
if (metadata?.linesAdded !== void 0) {
|
|
3091
|
-
lines.push(`- **Lines Added**: ${metadata.linesAdded}`);
|
|
3092
|
-
}
|
|
3093
|
-
if (metadata?.linesRemoved !== void 0) {
|
|
3094
|
-
lines.push(`- **Lines Removed**: ${metadata.linesRemoved}`);
|
|
3095
|
-
}
|
|
3096
|
-
if (metadata?.uniqueFiles && metadata.uniqueFiles.length > 0) {
|
|
3097
|
-
lines.push("");
|
|
3098
|
-
lines.push("<details>");
|
|
3099
|
-
lines.push(
|
|
3100
|
-
`<summary><strong>Unique Files Referenced (${metadata.uniqueFiles.length})</strong></summary>`
|
|
3101
|
-
);
|
|
3102
|
-
lines.push("");
|
|
3103
|
-
for (const file of metadata.uniqueFiles) {
|
|
3104
|
-
lines.push(`- \`${sanitizeText(file)}\``);
|
|
3105
|
-
}
|
|
3106
|
-
lines.push("</details>");
|
|
3107
|
-
}
|
|
3108
|
-
lines.push("\n---\n");
|
|
3109
|
-
for (const message of sessionData.messages) {
|
|
3110
|
-
if (message.type === "user") {
|
|
3111
|
-
lines.push("## User\n");
|
|
3112
|
-
lines.push(formatMessageContent(message));
|
|
3113
|
-
} else if (message.type === "assistant") {
|
|
3114
|
-
lines.push("## Assistant\n");
|
|
3115
|
-
lines.push(formatMessageContent(message));
|
|
3116
|
-
} else if (message.type === "tool_call") {
|
|
3117
|
-
lines.push(formatToolCall(message));
|
|
3118
|
-
} else if (message.type === "system") {
|
|
3119
|
-
lines.push("### System\n");
|
|
3120
|
-
const text = formatMessageContent(message);
|
|
3121
|
-
lines.push(`> ${text.replace(/\n/g, "\n> ")}`);
|
|
3122
|
-
}
|
|
3123
|
-
lines.push("\n");
|
|
3124
|
-
}
|
|
3125
|
-
return lines.join("\n");
|
|
3126
|
-
}
|
|
3127
|
-
__name(toMarkdown, "toMarkdown");
|
|
3128
|
-
function formatMessageContent(message) {
|
|
3129
|
-
const text = extractTextFromMessage(message);
|
|
3130
|
-
const processedText = text.replace(
|
|
3131
|
-
/--- Content from referenced files ---\n([\s\S]*?)\n--- End of content ---/g,
|
|
3132
|
-
(match, content) => `
|
|
3133
|
-
> **Referenced Files:**
|
|
3134
|
-
|
|
3135
|
-
${createCodeBlock(content)}
|
|
3136
|
-
`
|
|
3137
|
-
);
|
|
3138
|
-
return processedText;
|
|
3139
|
-
}
|
|
3140
|
-
__name(formatMessageContent, "formatMessageContent");
|
|
3141
|
-
function formatToolCall(message) {
|
|
3142
|
-
if (!message.toolCall) return "";
|
|
3143
|
-
const lines = [];
|
|
3144
|
-
const { title, status, rawInput, content, locations } = message.toolCall;
|
|
3145
|
-
const titleStr = typeof title === "string" ? title : JSON.stringify(title);
|
|
3146
|
-
lines.push(`### Tool: ${sanitizeText(titleStr)}`);
|
|
3147
|
-
lines.push(`**Status**: ${sanitizeText(status)}
|
|
3148
|
-
`);
|
|
3149
|
-
if (rawInput) {
|
|
3150
|
-
lines.push("**Input:**");
|
|
3151
|
-
const inputStr = typeof rawInput === "string" ? rawInput : JSON.stringify(rawInput, null, 2);
|
|
3152
|
-
lines.push(createCodeBlock(inputStr, "json"));
|
|
3153
|
-
lines.push("");
|
|
3154
|
-
}
|
|
3155
|
-
if (locations && locations.length > 0) {
|
|
3156
|
-
lines.push("**Affected Files:**");
|
|
3157
|
-
for (const loc of locations) {
|
|
3158
|
-
const lineSuffix = loc.line ? `:${loc.line}` : "";
|
|
3159
|
-
lines.push(`- \`${sanitizeText(loc.path)}${lineSuffix}\``);
|
|
3160
|
-
}
|
|
3161
|
-
lines.push("");
|
|
3162
|
-
}
|
|
3163
|
-
if (content && content.length > 0) {
|
|
3164
|
-
lines.push("**Output:**");
|
|
3165
|
-
for (const item of content) {
|
|
3166
|
-
if (item.type === "content" && item["content"]) {
|
|
3167
|
-
const contentData = item["content"];
|
|
3168
|
-
if (contentData.type === "text" && contentData.text) {
|
|
3169
|
-
let language = "";
|
|
3170
|
-
if (locations && locations.length === 1 && locations[0].path) {
|
|
3171
|
-
language = getLanguageFromPath(locations[0].path);
|
|
3172
|
-
}
|
|
3173
|
-
lines.push(createCodeBlock(contentData.text, language));
|
|
3174
|
-
}
|
|
3175
|
-
} else if (item.type === "diff") {
|
|
3176
|
-
const path2 = item["path"];
|
|
3177
|
-
const diffText = item["newText"];
|
|
3178
|
-
lines.push(`
|
|
3179
|
-
*Diff for \`${sanitizeText(path2)}\`:*`);
|
|
3180
|
-
lines.push(createCodeBlock(diffText, "diff"));
|
|
3181
|
-
}
|
|
3182
|
-
}
|
|
3183
|
-
}
|
|
3184
|
-
return lines.join("\n");
|
|
3185
|
-
}
|
|
3186
|
-
__name(formatToolCall, "formatToolCall");
|
|
3187
|
-
function extractTextFromMessage(message) {
|
|
3188
|
-
if (!message.message?.parts) return "";
|
|
3189
|
-
const textParts = [];
|
|
3190
|
-
for (const part of message.message.parts) {
|
|
3191
|
-
if ("text" in part) {
|
|
3192
|
-
textParts.push(part.text);
|
|
3193
|
-
}
|
|
3194
|
-
}
|
|
3195
|
-
return textParts.join("\n");
|
|
3196
|
-
}
|
|
3197
|
-
__name(extractTextFromMessage, "extractTextFromMessage");
|
|
3198
|
-
function createCodeBlock(content, language = "") {
|
|
3199
|
-
const fence = buildFence(content);
|
|
3200
|
-
return `${fence}${language}
|
|
3201
|
-
${content}
|
|
3202
|
-
${fence}`;
|
|
3203
|
-
}
|
|
3204
|
-
__name(createCodeBlock, "createCodeBlock");
|
|
3205
|
-
function sanitizeText(value) {
|
|
3206
|
-
return (value ?? "").replace(/&/g, "&").replace(/</g, "<");
|
|
3207
|
-
}
|
|
3208
|
-
__name(sanitizeText, "sanitizeText");
|
|
3209
|
-
function buildFence(value) {
|
|
3210
|
-
const matches = (value ?? "").match(/`+/g);
|
|
3211
|
-
const maxRun = matches ? Math.max(...matches.map((match) => match.length)) : 0;
|
|
3212
|
-
const fenceLength = Math.max(3, maxRun + 1);
|
|
3213
|
-
return "`".repeat(fenceLength);
|
|
3214
|
-
}
|
|
3215
|
-
__name(buildFence, "buildFence");
|
|
3216
|
-
function getLanguageFromPath(path2) {
|
|
3217
|
-
const ext = path2.split(".").pop()?.toLowerCase();
|
|
3218
|
-
switch (ext) {
|
|
3219
|
-
case "ts":
|
|
3220
|
-
case "tsx":
|
|
3221
|
-
return "typescript";
|
|
3222
|
-
case "js":
|
|
3223
|
-
case "jsx":
|
|
3224
|
-
case "mjs":
|
|
3225
|
-
case "cjs":
|
|
3226
|
-
return "javascript";
|
|
3227
|
-
case "py":
|
|
3228
|
-
return "python";
|
|
3229
|
-
case "rb":
|
|
3230
|
-
return "ruby";
|
|
3231
|
-
case "go":
|
|
3232
|
-
return "go";
|
|
3233
|
-
case "rs":
|
|
3234
|
-
return "rust";
|
|
3235
|
-
case "java":
|
|
3236
|
-
return "java";
|
|
3237
|
-
case "c":
|
|
3238
|
-
case "cpp":
|
|
3239
|
-
case "h":
|
|
3240
|
-
case "hpp":
|
|
3241
|
-
return "cpp";
|
|
3242
|
-
case "cs":
|
|
3243
|
-
return "csharp";
|
|
3244
|
-
case "html":
|
|
3245
|
-
return "html";
|
|
3246
|
-
case "css":
|
|
3247
|
-
return "css";
|
|
3248
|
-
case "json":
|
|
3249
|
-
return "json";
|
|
3250
|
-
case "md":
|
|
3251
|
-
return "markdown";
|
|
3252
|
-
case "sh":
|
|
3253
|
-
case "bash":
|
|
3254
|
-
case "zsh":
|
|
3255
|
-
return "bash";
|
|
3256
|
-
case "yaml":
|
|
3257
|
-
case "yml":
|
|
3258
|
-
return "yaml";
|
|
3259
|
-
case "xml":
|
|
3260
|
-
return "xml";
|
|
3261
|
-
case "sql":
|
|
3262
|
-
return "sql";
|
|
3263
|
-
default:
|
|
3264
|
-
return "";
|
|
3265
|
-
}
|
|
3266
|
-
}
|
|
3267
|
-
__name(getLanguageFromPath, "getLanguageFromPath");
|
|
3268
|
-
|
|
3269
|
-
// packages/cli/src/ui/utils/export/formatters/html.ts
|
|
3270
|
-
init_esbuild_shims();
|
|
3271
|
-
|
|
3272
|
-
// packages/web-templates/src/index.ts
|
|
3273
|
-
init_esbuild_shims();
|
|
3274
|
-
|
|
3275
|
-
// packages/web-templates/src/generated/insightTemplate.ts
|
|
3276
|
-
init_esbuild_shims();
|
|
3277
|
-
var INSIGHT_JS = '(function(e,O){"use strict";function J({data:t}){const{totalMessages:n=0,totalLinesAdded:l=0,totalLinesRemoved:r=0,totalFiles:a=0}=t,s=Object.keys(t.heatmap||{});let o=0;if(s.length>0){const c=s.map(x=>new Date(x)).map(x=>x.getTime()),d=new Date(Math.min(...c)),g=new Date(Math.max(...c)),E=Math.abs(g.getTime()-d.getTime());o=Math.ceil(E/(1e3*60*60*24))+1}const i=o>0?Math.round(n/o):0;return e.createElement("div",{className:"stats-row"},e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},n),e.createElement("div",{className:"stat-label"},"Messages")),e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},"+",l,"/-",r),e.createElement("div",{className:"stat-label"},"Lines")),e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},a),e.createElement("div",{className:"stat-label"},"Files")),e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},o),e.createElement("div",{className:"stat-label"},"Days")),e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},i),e.createElement("div",{className:"stat-label"},"Msgs/Day")))}/**\n * @license\n * Copyright 2026 Qwen Team\n * SPDX-License-Identifier: Apache-2.0\n */function D(t){const n=t.getFullYear(),l=String(t.getMonth()+1).padStart(2,"0"),r=String(t.getDate()).padStart(2,"0");return`${n}-${l}-${r}`}function Y(t){const[n,l,r]=t.split("-").map(Number);return new Date(n,l-1,r)}function V({insights:t}){return e.createElement("div",{className:"grid gap-4 md:grid-cols-2 md:gap-6"},e.createElement(X,{activeHours:t.activeHours,cardClass:"glass-card p-6",sectionTitleClass:"text-lg font-semibold tracking-tight text-slate-900"}))}function X({activeHours:t,cardClass:n,sectionTitleClass:l}){const a=[{label:"Morning",time:"06:00 - 12:00",hours:[6,7,8,9,10,11],color:"#fbbf24"},{label:"Afternoon",time:"12:00 - 18:00",hours:[12,13,14,15,16,17],color:"#0ea5e9"},{label:"Evening",time:"18:00 - 22:00",hours:[18,19,20,21],color:"#6366f1"},{label:"Night",time:"22:00 - 06:00",hours:[22,23,0,1,2,3,4,5],color:"#475569"}].map(o=>{const i=o.hours.reduce((m,c)=>m+(t[c]||0),0);return{...o,total:i}}),s=Math.max(...a.map(o=>o.total));return e.createElement("div",{className:`${n} h-full flex flex-col min-h-[320px]`},e.createElement("div",{className:"flex items-center justify-between mb-4"},e.createElement("h3",{className:l},"Active Hours")),e.createElement("div",{className:"flex-1 flex flex-col justify-center gap-4"},a.map(o=>e.createElement("div",{key:o.label,className:"space-y-2"},e.createElement("div",{className:"flex justify-between items-center text-sm"},e.createElement("div",{className:"flex items-center gap-2"},e.createElement("span",{className:"rounded-full",style:{width:"12px",height:"12px",backgroundColor:o.color}}),e.createElement("span",{className:"font-medium text-slate-700"},o.label),e.createElement("span",{className:"text-xs text-slate-400 hidden xl:inline"},o.time)),e.createElement("span",{className:"font-semibold text-slate-900"},o.total)),e.createElement("div",{className:"w-full rounded-full overflow-hidden",style:{height:"12px",backgroundColor:"#e2e8f0"}},e.createElement("div",{className:"h-full rounded-full",style:{width:`${s>0?o.total/s*100:0}%`,backgroundColor:o.color}}))))))}function Z({heatmap:t}){return e.createElement("div",{className:"glass-card p-6 mt-4 md:mt-6"},e.createElement("div",{className:"mb-3"},e.createElement("h3",{className:"text-lg font-semibold tracking-tight text-slate-900"},"Activity Heatmap"),e.createElement("p",{className:"text-xs text-slate-500"},"Showing past year of activity")),e.createElement("div",{className:"heatmap-container"},e.createElement("div",{className:"min-w-[720px] rounded-xl bg-white/70"},e.createElement(R,{heatmapData:t}))),e.createElement(ee,null))}function R({heatmapData:t}){const s=new Date,o=new Date(s);o.setFullYear(s.getFullYear()-1);const i=[],m=new Date(o);for(;m<=s;)i.push(new Date(m)),m.setDate(m.getDate()+1);const c=[0,2,4,10,20],d=["#ebedf0","#9be9a8","#40c463","#30a14e","#216e39"];function g(u){if(u===0)return d[0];for(let f=c.length-1;f>=1;f--)if(u>=c[f])return d[f];return d[1]}const E=50,x=20,A=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],w=o.getDay(),j=[];let h=-1,T=-100;return i.forEach((u,f)=>{const C=f+w,_=Math.floor(C/7),v=E+_*16,N=u.getMonth();N!==h&&(v-T>30&&(j.push({x:v,text:A[N]}),T=v),h=N)}),e.createElement("svg",{className:"heatmap-svg",width:1e3,height:130,viewBox:"0 0 1000 130"},i.map((u,f)=>{const C=f+w,_=Math.floor(C/7),v=u.getDay(),N=E+_*16,q=x+v*16,k=D(u),S=t[k]||0,I=g(S);return e.createElement("rect",{key:k,className:"heatmap-day",x:N,y:q,width:14,height:14,rx:"2",fill:I,"data-date":k,"data-count":S},e.createElement("title",null,k,": ",S," activities"))}),j.map((u,f)=>e.createElement("text",{key:f,x:u.x,y:"15",fontSize:"12",fill:"#64748b"},u.text)))}function ee(){const t=["#ebedf0","#9be9a8","#40c463","#30a14e","#216e39"];return e.createElement("div",{className:"flex items-center gap-2 mt-4"},e.createElement("span",{className:"text-xs text-slate-500"},"Less"),t.map((n,l)=>e.createElement("span",{key:l,className:"inline-block rounded",style:{width:"10px",height:"10px",backgroundColor:n}})),e.createElement("span",{className:"text-xs text-slate-500"},"More"))}function p({children:t}){if(!t||typeof t!="string")return t;const n=t.split(/(\\*\\*.*?\\*\\*)/g);return e.createElement(e.Fragment,null,n.map((l,r)=>l.startsWith("**")&&l.endsWith("**")&&l.length>=4?e.createElement("strong",{key:r},l.slice(2,-2)):l))}function H({text:t,label:n="Copy"}){const[l,r]=e.useState(!1),a=()=>{navigator.clipboard.writeText(t).then(()=>{r(!0),setTimeout(()=>r(!1),2e3)})};return e.createElement("button",{className:"copy-btn",onClick:a},l?"Copied!":n)}function te(t){return typeof t=="string"&&t.trim().length>0}function ne({qualitative:t,targetSections:n}){const{atAGlance:l}=t;if(!l)return null;const r=[{key:"wins",label:"What\'s working:",body:l.whats_working,href:"#section-wins",link:"Impressive Things You Did \u2192",showLink:n.wins},{key:"friction",label:"What\'s hindering you:",body:l.whats_hindering,href:"#section-friction",link:"Where Things Go Wrong \u2192",showLink:n.friction},{key:"features",label:"Quick wins to try:",body:l.quick_wins,href:"#section-features",link:"Features to Try \u2192",showLink:n.features},{key:"horizon",label:"Ambitious workflows:",body:l.ambitious_workflows,href:"#section-horizon",link:"On the Horizon \u2192",showLink:n.horizon}].filter(a=>te(a.body));return r.length===0?null:e.createElement("div",{className:"at-a-glance"},e.createElement("div",{className:"glance-title"},"At a Glance"),e.createElement("div",{className:"glance-sections"},r.map(a=>e.createElement("div",{key:a.key,className:"glance-section"},e.createElement("strong",null,a.label)," ",e.createElement(p,null,a.body),a.showLink&&e.createElement("a",{href:a.href,className:"see-more"},a.link)))))}function le({sections:t}){return t.length===0?null:e.createElement("nav",{className:"nav-toc"},t.map(n=>e.createElement("a",{key:n.href,href:n.href},n.label)))}function re({qualitative:t,topGoals:n,topTools:l}){const{projectAreas:r}=t,a=Array.isArray(l)?Object.fromEntries(l):l;return e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-work",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"What You Work On"),Array.isArray(r==null?void 0:r.areas)&&r.areas.length>0&&e.createElement("div",{className:"project-areas mb-6"},r.areas.map((s,o)=>e.createElement("div",{key:o,className:"project-area"},e.createElement("div",{className:"area-header"},e.createElement("span",{className:"area-name"},s.name),e.createElement("span",{className:"area-count"},"~",s.session_count," sessions")),e.createElement("div",{className:"area-desc"},e.createElement(p,null,s.description))))),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, 1fr)",gap:"24px",marginBottom:"24px"}},n&&Object.keys(n).length>0&&e.createElement(M,{data:n,title:"What You Wanted",color:"#0ea5e9"}),a&&Object.keys(a).length>0&&e.createElement(M,{data:a,title:"Top Tools Used",color:"#6366f1"})))}function ae({qualitative:t,insights:n}){const{interactionStyle:l}=t;return l?e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-usage",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"How You Use Qwen Code"),e.createElement("div",{className:"narrative"},e.createElement("p",null,e.createElement(p,null,l.narrative)),l.key_pattern&&e.createElement("div",{className:"key-insight"},e.createElement("strong",null,"Key pattern:")," ",e.createElement(p,null,l.key_pattern))),e.createElement(V,{insights:n}),e.createElement(Z,{heatmap:n.heatmap})):null}function se({qualitative:t,primarySuccess:n,outcomes:l}){const r=t==null?void 0:t.impressiveWorkflows;return e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-wins",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"Impressive Things You Did"),(r==null?void 0:r.intro)&&e.createElement("p",{className:"section-intro"},e.createElement(p,null,r.intro)),r&&e.createElement("div",{className:"big-wins"},Array.isArray(r.impressive_workflows)&&r.impressive_workflows.map((a,s)=>e.createElement("div",{key:s,className:"big-win"},e.createElement("div",{className:"big-win-title"},a.title),e.createElement("div",{className:"big-win-desc"},e.createElement(p,null,a.description))))),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, 1fr)",gap:"24px",marginTop:"24px",marginBottom:"24px"}},n&&Object.keys(n).length>0&&e.createElement(M,{data:n,title:"What Helped Most (Qwen\'s Capabilities)",color:"#3b82f6",allowedKeys:["fast_accurate_search","correct_code_edits","good_explanations","proactive_help","multi_file_changes","good_debugging"]}),l&&Object.keys(l).length>0&&e.createElement(M,{data:l,title:"Outcomes",color:"#8b5cf6",allowedKeys:["fully_achieved","mostly_achieved","partially_achieved","not_achieved","unclear_from_transcript"]})))}function oe(t){return t==="unclear_from_transcript"?"Unclear":t.split("_").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}function M({data:t,title:n,color:l="#3b82f6",allowedKeys:r=null}){if(!t||Object.keys(t).length===0)return null;let a=Object.entries(t).filter(([,o])=>Number.isFinite(o)&&o!==0);if(r&&(a=a.filter(([o])=>r.includes(o))),a.sort((o,i)=>i[1]-o[1]),a=a.slice(0,10),a.length===0)return null;const s=Math.max(...a.map(([,o])=>o));return e.createElement("div",{className:"bar-chart-card",style:{flex:1,minWidth:0,backgroundColor:"#ffffff",borderRadius:"12px",padding:"20px",boxShadow:"0 1px 3px rgba(0, 0, 0, 0.08)",border:"1px solid #e2e8f0"}},e.createElement("h3",{style:{fontSize:"13px",fontWeight:700,color:"#64748b",marginTop:0,marginBottom:"16px",textTransform:"uppercase",letterSpacing:"0.5px"}},n),e.createElement("div",{className:"bar-chart",style:{display:"flex",flexDirection:"column",gap:"10px"}},a.map(([o,i])=>{const m=s>0?i/s*100:0;return e.createElement("div",{key:o,className:"bar-row",style:{display:"flex",alignItems:"center",gap:"12px"}},e.createElement("div",{className:"bar-label",style:{width:"130px",fontSize:"13px",color:"#475569",textAlign:"left",flexShrink:0,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}},oe(o)),e.createElement("div",{className:"bar-wrapper",style:{flex:1,display:"flex",alignItems:"center",gap:"10px",minWidth:0}},e.createElement("div",{className:"bar-bg",style:{flex:1,height:"8px",backgroundColor:"#f1f5f9",borderRadius:"4px",overflow:"hidden"}},e.createElement("div",{className:"bar-fill",style:{width:`${m}%`,height:"100%",backgroundColor:l,borderRadius:"4px",transition:"width 0.3s ease"}})),e.createElement("span",{className:"bar-value",style:{fontSize:"13px",fontWeight:600,color:"#475569",minWidth:"24px",textAlign:"right"}},i)))})))}function ie({qualitative:t,satisfaction:n,friction:l}){const r=t==null?void 0:t.frictionPoints;return e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-friction",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"Where Things Go Wrong"),(r==null?void 0:r.intro)&&e.createElement("p",{className:"section-intro"},e.createElement(p,null,r.intro)),r&&e.createElement("div",{className:"friction-categories"},Array.isArray(r.categories)&&r.categories.map((a,s)=>e.createElement("div",{key:s,className:"friction-category"},e.createElement("div",{className:"friction-title"},a.category),e.createElement("div",{className:"friction-desc"},e.createElement(p,null,a.description)),Array.isArray(a.examples)&&a.examples.length>0&&e.createElement("ul",{className:"friction-examples"},a.examples.map((o,i)=>e.createElement("li",{key:i},e.createElement(p,null,o))))))),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, 1fr)",gap:"24px",marginTop:"24px",marginBottom:"24px"}},l&&Object.keys(l).length>0&&e.createElement(M,{data:l,title:"Primary Friction Types",color:"#ef4444",allowedKeys:["misunderstood_request","wrong_approach","buggy_code","user_rejected_action","excessive_changes"]}),n&&Object.keys(n).length>0&&e.createElement(M,{data:n,title:"Inferred Satisfaction (model-estimated)",color:"#10b981",allowedKeys:["happy","satisfied","likely_satisfied","dissatisfied","frustrated"]})))}function me({additions:t}){const[n,l]=e.useState(new Array(t.length).fill(!0)),[r,a]=e.useState(!1),s=m=>{const c=n.map((d,g)=>g===m?!d:d);l(c)},o=()=>{const m=t.filter((c,d)=>n[d]).map(c=>c.addition).join(`\n\n`);m&&navigator.clipboard.writeText(m).then(()=>{a(!0),setTimeout(()=>a(!1),2e3)})},i=n.filter(Boolean).length;return e.createElement("div",{className:"qwen-md-section"},e.createElement("h3",null,"Suggested QWEN.md Additions"),e.createElement("p",{className:"text-xs text-slate-500 mb-3"},"Just copy this into Qwen Code to add it to your QWEN.md."),e.createElement("div",{className:"qwen-md-actions",style:{marginBottom:"12px"}},e.createElement("button",{className:`copy-all-btn ${r?"copied":""}`,onClick:o,disabled:i===0},r?"Copied All!":`Copy All Checked (${i})`)),t.map((m,c)=>e.createElement("div",{key:c,className:"qwen-md-item"},e.createElement("input",{type:"checkbox",checked:n[c],onChange:()=>s(c),className:"cmd-checkbox"}),e.createElement("div",{style:{flex:1}},e.createElement("code",{className:"cmd-code"},m.addition),e.createElement("div",{className:"cmd-why"},e.createElement(p,null,m.why))),e.createElement(H,{text:m.addition}))))}function ce({qualitative:t}){const{improvements:n}=t;if(!n)return null;const l=Array.isArray(n.Qwen_md_additions)&&n.Qwen_md_additions.length>0||Array.isArray(n.features_to_try)&&n.features_to_try.length>0,r=Array.isArray(n.usage_patterns)&&n.usage_patterns.length>0;return!l&&!r?null:e.createElement(e.Fragment,null,l&&e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-features",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"Existing Qwen Code Features to Try"),Array.isArray(n.Qwen_md_additions)&&n.Qwen_md_additions.length>0&&e.createElement(me,{additions:n.Qwen_md_additions}),e.createElement("p",{className:"text-xs text-slate-500 mb-3"},"Just copy this into Qwen Code and it\'ll set it up for you."),e.createElement("div",{className:"features-section"},Array.isArray(n.features_to_try)&&n.features_to_try.map((a,s)=>e.createElement("div",{key:s,className:"feature-card"},e.createElement("div",{className:"feature-title"},a.feature),e.createElement("div",{className:"feature-oneliner"},e.createElement(p,null,a.one_liner)),e.createElement("div",{className:"feature-why"},e.createElement("strong",null,"Why for you:")," ",e.createElement(p,null,a.why_for_you)),e.createElement("div",{className:"feature-examples"},e.createElement("div",{className:"feature-example"},e.createElement("div",{className:"example-code-row"},e.createElement("code",{className:"example-code"},a.example_code),e.createElement(H,{text:a.example_code})))))))),r&&e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-patterns",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"New Ways to Use Qwen Code"),e.createElement("p",{className:"text-xs text-slate-500 mb-3"},"Just copy this into Qwen Code and it\'ll walk you through it."),e.createElement("div",{className:"patterns-section"},Array.isArray(n.usage_patterns)&&n.usage_patterns.map((a,s)=>e.createElement("div",{key:s,className:"pattern-card"},e.createElement("div",{className:"pattern-title"},a.title),e.createElement("div",{className:"pattern-summary"},e.createElement(p,null,a.suggestion)),e.createElement("div",{className:"pattern-detail"},e.createElement(p,null,a.detail)),e.createElement("div",{className:"copyable-prompt-section"},e.createElement("div",{className:"prompt-label"},"Paste into Qwen Code:"),e.createElement("div",{className:"copyable-prompt-row"},e.createElement("code",{className:"copyable-prompt"},a.copyable_prompt),e.createElement(H,{text:a.copyable_prompt}))))))))}function de({qualitative:t}){const{futureOpportunities:n}=t;return n?e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-horizon",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"On the Horizon"),n.intro&&e.createElement("p",{className:"section-intro"},e.createElement(p,null,n.intro)),e.createElement("div",{className:"horizon-section"},Array.isArray(n.opportunities)&&n.opportunities.map((l,r)=>e.createElement("div",{key:r,className:"horizon-card"},e.createElement("div",{className:"horizon-title"},l.title),e.createElement("div",{className:"horizon-possible"},e.createElement(p,null,l.whats_possible)),e.createElement("div",{className:"horizon-tip"},e.createElement("strong",null,"Getting started:")," ",e.createElement(p,null,l.how_to_try)),e.createElement("div",{className:"pattern-prompt"},e.createElement("div",{className:"prompt-label"},"Paste into Qwen Code:"),e.createElement("div",{style:{display:"flex",alignItems:"flex-start",gap:"8px"}},e.createElement("code",{style:{flex:1}},l.copyable_prompt),e.createElement(H,{text:l.copyable_prompt}))))))):null}function pe({qualitative:t}){const{memorableMoment:n}=t;return n?e.createElement("div",{className:"fun-ending"},e.createElement("div",{className:"fun-headline"},\'"\',n.headline,\'"\'),e.createElement("div",{className:"fun-detail"},e.createElement(p,null,n.detail))):null}const ue={light:{background:"linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)",textPrimary:"#0f172a",textSecondary:"#475569",textMuted:"#64748b",cardBackground:"rgba(255,255,255,0.7)",cardBackgroundSecondary:"rgba(255,255,255,0.5)",borderColor:"#e2e8f0",heatmapColors:["#9be9a8","#40c463","#30a14e","#216e39"],heatmapEmpty:"#ebedf0"},dark:{background:"linear-gradient(135deg, #0f172a 0%, #1e293b 100%)",textPrimary:"#f8fafc",textSecondary:"#e2e8f0",textMuted:"#94a3b8",cardBackground:"rgba(255,255,255,0.05)",cardBackgroundSecondary:"rgba(255,255,255,0.04)",borderColor:"rgba(255,255,255,0.08)",heatmapColors:["#0e4429","#006d32","#26a641","#39d353"],heatmapEmpty:"#2d333b"}};function fe({data:t,theme:n="light"}){var h,T,u,f,C,_;const l=ue[n],{totalMessages:r=0,totalSessions:a=0,totalLinesAdded:s=0,totalLinesRemoved:o=0,totalFiles:i=0,currentStreak:m=0,longestStreak:c=0,activeHours:d={}}=t,g=Object.keys(t.heatmap||{});let E=0,x="";if(g.length>0){E=g.length;const v=g.map(S=>Y(S).getTime()),N=new Date(Math.min(...v)),q=new Date(Math.max(...v)),k=S=>D(S);x=`${k(N)} \u2014 ${k(q)}`}const A=(u=(T=(h=t.qualitative)==null?void 0:h.interactionStyle)==null?void 0:T.key_pattern)!=null?u:null,w=(_=(C=(f=t.qualitative)==null?void 0:f.memorableMoment)==null?void 0:C.headline)!=null?_:null,j=ge(t.heatmap||{},l);return e.createElement("div",{id:"share-card",style:{width:"1200px",background:l.background,color:l.textPrimary,fontFamily:\'ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"\',display:"flex",flexDirection:"column",padding:"48px 56px",position:"absolute",left:"-9999px",top:"-9999px",overflow:"hidden",boxSizing:"border-box"}},e.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:"32px"}},e.createElement("div",null,e.createElement("div",{style:{fontSize:"32px",fontWeight:700,letterSpacing:"-0.02em",lineHeight:1.2}},"Qwen Code Insights"),e.createElement("div",{style:{fontSize:"14px",color:l.textMuted,marginTop:"6px"}},x)),e.createElement("div",{style:{fontSize:"11px",color:l.textMuted,textTransform:"uppercase",letterSpacing:"0.15em",paddingTop:"8px"}},"qwen.ai")),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"repeat(6, 1fr)",gap:"16px",marginBottom:"32px"}},e.createElement(z,{value:String(r),label:"Messages",theme:l}),e.createElement(z,{value:String(a),label:"Sessions",theme:l}),e.createElement(z,{value:`+${s}/-${o}`,label:"Lines Changed",small:!0,theme:l}),e.createElement(z,{value:String(i),label:"Files",theme:l}),e.createElement(z,{value:`${m}d`,label:"Streak",theme:l}),e.createElement(z,{value:`${c}d`,label:"Best Streak",theme:l})),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"24px",marginBottom:"16px"}},e.createElement("div",{style:{background:l.cardBackground,borderRadius:"12px",padding:"20px",display:"flex",flexDirection:"column"}},e.createElement("div",{style:{fontSize:"12px",fontWeight:600,color:l.textMuted,textTransform:"uppercase",letterSpacing:"0.08em",marginBottom:"12px"}},"Activity \xB7 ",E," active days"),e.createElement("div",{style:{flex:1,display:"flex",alignItems:"center",justifyContent:"center"}},e.createElement(xe,{cells:j})),e.createElement(Ee,{theme:l})),e.createElement("div",{style:{display:"flex",flexDirection:"column",gap:"16px"}},e.createElement("div",{style:{background:l.cardBackground,borderRadius:"12px",padding:"20px",display:"flex",flexDirection:"column"}},e.createElement("div",{style:{fontSize:"12px",fontWeight:600,color:l.textMuted,textTransform:"uppercase",letterSpacing:"0.08em",marginBottom:"12px"}},"Active Hours"),e.createElement("div",{style:{flex:1,display:"flex",flexDirection:"column",justifyContent:"center",gap:"10px"}},e.createElement(he,{activeHours:d,theme:l}))),e.createElement("div",{style:{background:l.cardBackgroundSecondary,borderRadius:"12px",padding:"16px 16px",position:"relative"}},e.createElement("div",{style:{position:"absolute",left:"12px",fontSize:"64px",fontWeight:700,color:n==="light"?"rgba(99,102,241,0.15)":"rgba(99,102,241,0.2)",lineHeight:1,fontFamily:\'Georgia, "Times New Roman", serif\',userSelect:"none",pointerEvents:"none"}},"\u201C"),e.createElement("div",{style:{paddingLeft:"40px",position:"relative"}},A&&e.createElement("div",{style:{fontSize:"13px",color:l.textSecondary,lineHeight:1.6,marginBottom:w?"8px":0}},A),w&&e.createElement("div",{style:{fontSize:"12px",color:l.textMuted,lineHeight:1.5,fontStyle:"italic"}},w))))),e.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginTop:"auto",paddingTop:"24px",borderTop:`1px solid ${l.borderColor}`,flexShrink:0}},e.createElement("div",{style:{fontSize:"12px",color:l.textMuted}},"Generated by Qwen Code \xB7 ",D(new Date)),e.createElement("div",{style:{fontSize:"12px",color:l.textMuted}},"github.com/QwenLM/qwen-code")))}function z({value:t,label:n,small:l,theme:r}){return e.createElement("div",{style:{textAlign:"center"}},e.createElement("div",{style:{fontSize:l?"18px":"28px",fontWeight:700,color:r.textPrimary,lineHeight:1.2}},t),e.createElement("div",{style:{fontSize:"11px",color:r.textMuted,textTransform:"uppercase",letterSpacing:"0.05em",marginTop:"4px"}},n))}function he({activeHours:t,theme:n}){const r=[{label:"Morning",time:"06\u201312",hours:[6,7,8,9,10,11],color:"#fbbf24"},{label:"Afternoon",time:"12\u201318",hours:[12,13,14,15,16,17],color:"#0ea5e9"},{label:"Evening",time:"18\u201322",hours:[18,19,20,21],color:"#6366f1"},{label:"Night",time:"22\u201306",hours:[22,23,0,1,2,3,4,5],color:"#475569"}].map(s=>({...s,total:s.hours.reduce((o,i)=>o+(t[i]||0),0)})),a=Math.max(...r.map(s=>s.total),1);return e.createElement(e.Fragment,null,r.map(s=>{const o=a>0?s.total/a*100:0;return e.createElement("div",{key:s.label},e.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",fontSize:"12px",marginBottom:"4px"}},e.createElement("div",{style:{display:"flex",alignItems:"center",gap:"6px"}},e.createElement("span",{style:{width:"8px",height:"8px",borderRadius:"50%",backgroundColor:s.color,display:"inline-block",flexShrink:0}}),e.createElement("span",{style:{color:n.textSecondary,fontWeight:500}},s.label),e.createElement("span",{style:{color:n.textMuted,fontSize:"11px"}},s.time)),e.createElement("span",{style:{color:n.textMuted,fontWeight:600}},s.total)),e.createElement("div",{style:{height:"6px",background:n.borderColor,borderRadius:"3px",overflow:"hidden"}},e.createElement("div",{style:{width:`${o}%`,height:"100%",backgroundColor:s.color,borderRadius:"3px"}})))}))}function ge(t,n){const l=new Date,a=26*7,s=new Date(l);s.setDate(s.getDate()-a+1),s.setDate(s.getDate()-s.getDay());const o=[],i=new Date(l);i.setDate(i.getDate()+(6-i.getDay()));const m=new Date(s);for(;m<=i;){const c=D(m),d=t[c]||0;o.push({color:ye(d,n)}),m.setDate(m.getDate()+1)}return o}function ye(t,n){return t===0?n.heatmapEmpty:t<2?n.heatmapColors[0]:t<4?n.heatmapColors[1]:t<10?n.heatmapColors[2]:n.heatmapColors[3]}function xe({cells:t}){const l=Math.ceil(t.length/7),r=14,a=3,s=l*(r+a),o=7*(r+a);return e.createElement("svg",{width:s,height:o,viewBox:`0 0 ${s} ${o}`},t.map((i,m)=>{const c=Math.floor(m/7),d=m%7;return e.createElement("rect",{key:m,x:c*(r+a),y:d*(r+a),width:r,height:r,rx:2,fill:i.color})}))}function Ee({theme:t}){return e.createElement("div",{style:{display:"flex",alignItems:"center",gap:"8px",marginTop:"12px"}},e.createElement("span",{style:{fontSize:"11px",color:t.textMuted}},"Less"),[t.heatmapEmpty,t.heatmapColors[0],t.heatmapColors[1],t.heatmapColors[2],t.heatmapColors[3]].map((n,l)=>e.createElement("span",{key:l,style:{width:"10px",height:"10px",borderRadius:"2px",backgroundColor:n,display:"inline-block"}})),e.createElement("span",{style:{fontSize:"11px",color:t.textMuted}},"More"))}function b(t){return typeof t=="string"?t.trim().length>0:typeof t=="number"?Number.isFinite(t)&&t!==0:typeof t=="boolean"?t:Array.isArray(t)?t.some(n=>b(n)):t&&typeof t=="object"?Object.values(t).some(n=>b(n)):!1}function W(t){return Array.isArray(t)?t.some(([,n])=>Number.isFinite(n)&&n!==0):!!t&&Object.values(t).some(n=>Number.isFinite(n)&&n!==0)}function $(t){return Array.isArray(t)&&t.some(n=>b(n))}function ve({data:t}){var u,f,C,_,v,N,q,k,S,I,K,U;const[n,l]=e.useState("dark"),r=e.useRef(!1),a=async()=>{const F=document.getElementById("share-card");if(!F||!window.html2canvas){alert("Export functionality is not available.");return}try{const y=F.cloneNode(!0);y.style.position="fixed",y.style.left="-9999px",y.style.top="0",y.style.pointerEvents="none",document.body.appendChild(y);const P=await window.html2canvas(y,{scale:2,useCORS:!0,logging:!1,width:1200,height:y.scrollHeight});document.body.removeChild(y);const G=P.toDataURL("image/png"),L=document.createElement("a");L.href=G,L.download=`qwen-insights-card-${D(new Date)}.png`,L.click()}catch(y){console.error("Export card error:",y),alert("Failed to export card. Please try again.")}};e.useEffect(()=>{r.current&&(r.current=!1,a())},[n]);const s=F=>{F===n?a():(r.current=!0,l(F))};if(!t)return e.createElement("div",{className:"text-center text-slate-600"},"No insight data available");const o=Object.keys(t.heatmap||{});let i="";if(o.length>0){const y=o.map(B=>Y(B)).map(B=>B.getTime()),P=new Date(Math.min(...y)),G=new Date(Math.max(...y)),L=B=>D(B);i=`${L(P)} to ${L(G)}`}const m=b((u=t.qualitative)==null?void 0:u.atAGlance),c=!!t.qualitative&&(b(t.qualitative.projectAreas)||W(t.topGoals)||W(t.topTools)),d=b((f=t.qualitative)==null?void 0:f.interactionStyle),g=!!t.qualitative&&(b(t.qualitative.impressiveWorkflows)||W(t.primarySuccess)||W(t.outcomes)),E=!!t.qualitative&&(b(t.qualitative.frictionPoints)||W(t.satisfaction)||W(t.friction)),x=!!t.qualitative&&($((C=t.qualitative.improvements)==null?void 0:C.Qwen_md_additions)||$((_=t.qualitative.improvements)==null?void 0:_.features_to_try)),A=!!t.qualitative&&$((v=t.qualitative.improvements)==null?void 0:v.usage_patterns),w=b((N=t.qualitative)==null?void 0:N.futureOpportunities),j=b((q=t.qualitative)==null?void 0:q.memorableMoment),h=[];c&&h.push({href:"#section-work",label:"What You Work On"}),d&&h.push({href:"#section-usage",label:"How You Use Qwen Code"}),g&&h.push({href:"#section-wins",label:"Impressive Things"}),E&&h.push({href:"#section-friction",label:"Where Things Go Wrong"}),x&&h.push({href:"#section-features",label:"Features to Try"}),A&&h.push({href:"#section-patterns",label:"New Usage Patterns"}),w&&h.push({href:"#section-horizon",label:"On the Horizon"});const T={wins:g,friction:E,features:x,horizon:w};return e.createElement("div",null,e.createElement("header",{className:"insights-header"},e.createElement("div",{className:"header-content"},e.createElement("div",{className:"header-title-section"},e.createElement("h1",{className:"header-title"},"Qwen Code Insights"),e.createElement("p",{className:"header-subtitle"},t.totalMessages?`${t.totalMessages.toLocaleString()} messages across ${(k=t.totalSessions)==null?void 0:k.toLocaleString()} sessions`:"Your personalized coding journey and patterns",i&&` \xB7 ${i}`)),e.createElement(be,{onExport:s}))),m&&t.qualitative&&e.createElement(ne,{qualitative:t.qualitative,targetSections:T}),h.length>0&&e.createElement(le,{sections:h}),e.createElement(J,{data:t}),c&&t.qualitative&&e.createElement(re,{qualitative:t.qualitative,topGoals:t.topGoals,topTools:t.topTools}),d&&t.qualitative&&e.createElement(ae,{qualitative:t.qualitative,insights:t}),g&&e.createElement(se,{qualitative:t.qualitative,primarySuccess:(S=t.primarySuccess)!=null?S:{},outcomes:(I=t.outcomes)!=null?I:{}}),E&&e.createElement(ie,{qualitative:t.qualitative,satisfaction:(K=t.satisfaction)!=null?K:{},friction:(U=t.friction)!=null?U:{}}),(x||A)&&t.qualitative&&e.createElement(ce,{qualitative:t.qualitative}),w&&t.qualitative&&e.createElement(de,{qualitative:t.qualitative}),j&&t.qualitative&&e.createElement(pe,{qualitative:t.qualitative}),e.createElement(fe,{data:t,theme:n}))}function be({onExport:t}){const[n,l]=e.useState(!1),r=e.useRef(null);e.useEffect(()=>{if(!n)return;const s=o=>{r.current&&!r.current.contains(o.target)&&l(!1)};return document.addEventListener("mousedown",s),()=>document.removeEventListener("mousedown",s)},[n]);const a=s=>{l(!1),t(s)};return e.createElement("div",{className:"export-dropdown-wrapper",ref:r},e.createElement("button",{className:"export-card-btn",onClick:()=>l(!n)},e.createElement("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},e.createElement("path",{d:"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"}),e.createElement("polyline",{points:"16 6 12 2 8 6"}),e.createElement("line",{x1:"12",y1:"2",x2:"12",y2:"15"})),e.createElement("span",null,"Export Card"),e.createElement("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:`export-chevron ${n?"open":""}`},e.createElement("polyline",{points:"6 9 12 15 18 9"}))),n&&e.createElement("div",{className:"export-dropdown"},e.createElement("button",{className:"export-dropdown-item",onClick:()=>a("light")},e.createElement("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},e.createElement("circle",{cx:"12",cy:"12",r:"5"}),e.createElement("line",{x1:"12",y1:"1",x2:"12",y2:"3"}),e.createElement("line",{x1:"12",y1:"21",x2:"12",y2:"23"}),e.createElement("line",{x1:"4.22",y1:"4.22",x2:"5.64",y2:"5.64"}),e.createElement("line",{x1:"18.36",y1:"18.36",x2:"19.78",y2:"19.78"}),e.createElement("line",{x1:"1",y1:"12",x2:"3",y2:"12"}),e.createElement("line",{x1:"21",y1:"12",x2:"23",y2:"12"}),e.createElement("line",{x1:"4.22",y1:"19.78",x2:"5.64",y2:"18.36"}),e.createElement("line",{x1:"18.36",y1:"5.64",x2:"19.78",y2:"4.22"})),e.createElement("span",null,"Light Theme")),e.createElement("button",{className:"export-dropdown-item",onClick:()=>a("dark")},e.createElement("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},e.createElement("path",{d:"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"})),e.createElement("span",null,"Dark Theme"))))}const Q=document.getElementById("react-root");Q&&window.INSIGHT_DATA&&O?O.createRoot(Q).render(e.createElement(ve,{data:window.INSIGHT_DATA})):console.error("Failed to mount React app:",{container:!!Q,data:!!window.INSIGHT_DATA,ReactDOM:!!O})})(React,ReactDOM);';
|
|
3278
|
-
var INSIGHT_CSS = '*,:before,:after,::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: #3b82f680;--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content: ""}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}body{line-height:inherit;margin:0;background-image:linear-gradient(to bottom right,var(--tw-gradient-stops));--tw-gradient-from: #f8fafc var(--tw-gradient-from-position);--tw-gradient-to: #f1f5f9 var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #fff var(--tw-gradient-via-position), var(--tw-gradient-to);--tw-text-opacity: 1;min-height:100vh;color:rgb(15 23 42 / var(--tw-text-opacity, 1));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glass-card{--tw-border-opacity: 1;border-width:1px;border-color:rgb(226 232 240 / var(--tw-border-opacity, 1));--tw-shadow: 0 10px 40px #0f172a14;--tw-shadow-colored: 0 10px 40px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);--tw-backdrop-blur: blur(8px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);background-color:#fff9;border-radius:1rem}.col-span-2{grid-column:span 2 / span 2}.mx-auto{margin-left:auto;margin-right:auto}.mb-8{margin-bottom:2rem}.ml-2{margin-left:.5rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.h-56{height:14rem}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-full{width:100%}.min-w-\\[720px\\]{min-width:720px}.max-w-6xl{max-width:72rem}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-slate-200>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(226 232 240 / var(--tw-divide-opacity, 1))}.overflow-x-auto{overflow-x:auto}.rounded-full{border-radius:9999px}.rounded-xl{border-radius:1.25rem}.border{border-width:1px}.border-slate-100{--tw-border-opacity: 1;border-color:rgb(241 245 249 / var(--tw-border-opacity, 1))}.bg-emerald-50{--tw-bg-opacity: 1;background-color:rgb(236 253 245 / var(--tw-bg-opacity, 1))}.bg-slate-100{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.bg-slate-50{--tw-bg-opacity: 1;background-color:rgb(248 250 252 / var(--tw-bg-opacity, 1))}.bg-slate-900{--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.bg-white\\/70{background-color:#ffffff73}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-slate-50{--tw-gradient-from: #f8fafc var(--tw-gradient-from-position);--tw-gradient-to: #f8fafc00 var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-white{--tw-gradient-to: #ffffff00 var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #ffffff var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-slate-100{--tw-gradient-to: #f1f5f9 var(--tw-gradient-to-position)}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.tracking-\\[0\\.2em\\]{letter-spacing:.2em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-emerald-700{--tw-text-opacity: 1;color:rgb(4 120 87 / var(--tw-text-opacity, 1))}.text-rose-700{--tw-text-opacity: 1;color:rgb(190 18 60 / var(--tw-text-opacity, 1))}.text-slate-200{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-slate-900{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.shadow-inner{--tw-shadow: inset 0 2px 4px 0 #0000000d;--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-soft{--tw-shadow: 0 10px 40px #0f172a14;--tw-shadow-colored: 0 10px 40px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-slate-100{--tw-shadow-color: #f1f5f9;--tw-shadow: var(--tw-shadow-colored)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.hover\\:-translate-y-\\[1px\\]:hover{--tw-translate-y: -1px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\\:shadow-lg:hover{--tw-shadow: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus-visible\\:outline:focus-visible{outline-style:solid}.focus-visible\\:outline-2:focus-visible{outline-width:2px}.focus-visible\\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\\:outline-slate-400:focus-visible{outline-color:#94a3b8}.active\\:translate-y-\\[1px\\]:active{--tw-translate-y: 1px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\\:translate-x-0\\.5{--tw-translate-x: .125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@media (min-width: 768px){.md\\:mt-6{margin-top:1.5rem}.md\\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\\:gap-6{gap:1.5rem}.md\\:py-12{padding-top:3rem;padding-bottom:3rem}.md\\:text-4xl{font-size:2.25rem;line-height:2.5rem}}.heatmap-container{width:100%;overflow-x:auto}.heatmap-svg{min-width:720px}.heatmap-day{cursor:pointer}.heatmap-day:hover{stroke:#00000024;stroke-width:1px}.heatmap-legend{display:flex;align-items:center;gap:4px;font-size:12px;color:#64748b;margin-top:8px}.heatmap-legend-item{width:10px;height:10px;border-radius:2px}.nav-toc{display:flex;flex-wrap:wrap;gap:8px;margin:24px 0 32px;padding:16px;background:#fff;border-radius:8px;border:1px solid #e2e8f0}.nav-toc a{font-size:12px;color:#64748b;text-decoration:none;padding:6px 12px;border-radius:6px;background:#f1f5f9;transition:all .15s}.nav-toc a:hover{background:#e2e8f0;color:#334155}.at-a-glance{background:linear-gradient(135deg,#fef3c7,#fde68a);border:1px solid #f59e0b;border-radius:12px;padding:20px 24px;margin-bottom:32px}.glance-title{font-size:16px;font-weight:700;color:#92400e;margin-bottom:16px}.glance-sections{display:flex;flex-direction:column;gap:12px}.glance-section{font-size:14px;color:#78350f;line-height:1.6}.glance-section strong{color:#92400e;font-weight:700}.see-more{color:#b45309;text-decoration:none;font-size:13px;white-space:nowrap;margin-left:4px}.see-more:hover{text-decoration:underline}.project-areas{display:flex;flex-direction:column;gap:12px;margin-bottom:32px}.project-area{background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:16px}.area-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.area-name{font-weight:600;font-size:15px;color:#0f172a}.area-count{font-size:12px;color:#64748b;background:#f1f5f9;padding:2px 8px;border-radius:4px}.area-desc{font-size:14px;color:#475569;line-height:1.5}.narrative{background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:20px;margin-bottom:24px}.narrative p{margin-top:0;margin-bottom:12px;font-size:14px;color:#475569;line-height:1.7}.key-insight{background:#f0fdf4;border:1px solid #bbf7d0;border-radius:8px;padding:12px 16px;margin-top:12px;font-size:14px;color:#166534}.section-intro{font-size:14px;color:#64748b;margin-bottom:16px}.big-wins{display:flex;flex-direction:column;gap:12px;margin-bottom:24px}.big-win{background:#f0fdf4;border:1px solid #bbf7d0;border-radius:8px;padding:16px}.big-win-title{font-weight:600;font-size:15px;color:#166534;margin-bottom:8px}.big-win-desc{font-size:14px;color:#15803d;line-height:1.5}.friction-categories{display:flex;flex-direction:column;gap:16px;margin-bottom:24px}.friction-category{background:#fef2f2;border:1px solid #fca5a5;border-radius:8px;padding:16px}.friction-title{font-weight:600;font-size:15px;color:#991b1b;margin-bottom:6px}.friction-desc{font-size:13px;color:#7f1d1d;margin-bottom:10px}.friction-examples{margin:0 0 0 10px;padding:0;font-size:13px;color:#334155;list-style-type:disc}.friction-examples li{margin-bottom:4px}.qwen-md-section{background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px;padding:12px;margin-bottom:20px}.qwen-md-section h3{font-size:13px;font-weight:600;color:#1e40af;margin:0 0 8px}.qwen-md-actions{margin-bottom:8px;padding-bottom:8px;border-bottom:1px solid #dbeafe}.copy-all-btn{background:#2563eb;color:#fff;border:none;border-radius:4px;padding:4px 10px;font-size:11px;cursor:pointer;font-weight:500;transition:all .2s}.copy-all-btn:hover{background:#1d4ed8}.copy-all-btn.copied{background:#16a34a}.qwen-md-item{display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px;padding:8px 0;border-bottom:1px solid #dbeafe}.qwen-md-item:last-child{border-bottom:none}.cmd-checkbox{margin-top:2px}.cmd-code{background:#fff;padding:6px 10px;border-radius:4px;font-size:11px;color:#1e40af;border:1px solid #bfdbfe;font-family:monospace;display:block;white-space:pre-wrap;word-break:break-word;flex:1}.cmd-why{font-size:11px;color:#64748b;width:100%;padding-left:20px;margin-top:4px}.features-section,.patterns-section{display:flex;flex-direction:column;gap:12px;margin:16px 0}.feature-card{background:#f0fdf4;border:1px solid #86efac;border-radius:8px;padding:16px}.pattern-card{background:#f0f9ff;border:1px solid #7dd3fc;border-radius:8px;padding:16px}.feature-title,.pattern-title{font-weight:600;font-size:15px;color:#0f172a;margin-bottom:6px}.feature-oneliner,.pattern-summary{font-size:14px;color:#475569;margin-bottom:8px}.feature-why,.pattern-detail{font-size:13px;color:#334155;line-height:1.5}.feature-examples{margin-top:12px}.feature-example{padding:8px 0;border-top:1px solid #d1fae5}.feature-example:first-child{border-top:none}.example-code-row,.copyable-prompt-row{display:flex;align-items:flex-start;gap:8px}.example-code{flex:1;background:#f1f5f9;padding:8px 12px;border-radius:4px;font-family:monospace;font-size:12px;color:#334155;overflow-x:auto;white-space:pre-wrap}.copyable-prompt-section{margin-top:12px;padding-top:12px;border-top:1px solid #e2e8f0}.copyable-prompt{flex:1;background:#f8fafc;padding:10px 12px;border-radius:4px;font-family:monospace;font-size:12px;color:#334155;border:1px solid #e2e8f0;white-space:pre-wrap;line-height:1.5}.prompt-label{font-size:11px;font-weight:600;text-transform:uppercase;color:#64748b;margin-bottom:6px}.copy-btn{background:#e2e8f0;border:none;border-radius:4px;padding:4px 8px;font-size:11px;cursor:pointer;color:#475569;flex-shrink:0;transition:all .2s}.copy-btn:hover{background:#cbd5e1}.horizon-section{display:flex;flex-direction:column;gap:16px}.horizon-card{background:linear-gradient(135deg,#faf5ff,#f5f3ff);border:1px solid #c4b5fd;border-radius:8px;padding:16px}.horizon-title{font-weight:600;font-size:15px;color:#5b21b6;margin-bottom:8px}.horizon-possible{font-size:14px;color:#334155;margin-bottom:10px;line-height:1.5}.horizon-tip{font-size:13px;color:#6b21a8;background:#fff9;padding:8px 12px;border-radius:4px}.pattern-prompt{background:#f8fafc;padding:12px;border-radius:6px;margin-top:12px;border:1px solid #e2e8f0;display:flex;flex-direction:column;gap:8px}.pattern-prompt code{font-family:monospace;font-size:12px;color:#334155;display:block;white-space:pre-wrap}.fun-ending{background:linear-gradient(135deg,#fef3c7,#fde68a);border:1px solid #fbbf24;border-radius:12px;padding:24px;margin-top:40px;text-align:center}.fun-headline{font-size:18px;font-weight:600;color:#78350f;margin-bottom:8px}.fun-detail{font-size:14px;color:#92400e}.stats-row{display:flex;gap:24px;margin-bottom:40px;padding:20px 0;border-top:1px solid #e2e8f0;border-bottom:1px solid #e2e8f0;flex-wrap:wrap}.stat{text-align:center}.stat-value{font-size:24px;font-weight:700;color:#0f172a}.stat-label{font-size:11px;color:#64748b;text-transform:uppercase}@media (max-width: 640px){.stats-row{justify-content:center}}.header-with-action{position:relative}.insights-header{margin-bottom:2rem;padding:1.5rem 0;border-bottom:1px solid #e2e8f0}.header-content{display:flex;justify-content:space-between;align-items:center;gap:1.5rem;flex-wrap:wrap}.header-title-section{flex:1;min-width:0}.header-title{font-size:1.75rem;font-weight:700;color:#0f172a;letter-spacing:-.02em;margin:0 0 .375rem;line-height:1.2}.header-subtitle{font-size:.875rem;color:#64748b;margin:0;font-weight:400}.export-dropdown-wrapper{position:relative}.export-card-btn{display:inline-flex;align-items:center;gap:.5rem;height:36px;padding:0 .875rem;border:1px solid #e2e8f0;border-radius:8px;background:#fff;color:#334155;font-size:.8125rem;font-weight:500;cursor:pointer;transition:all .15s ease}.export-card-btn:hover{background:#f8fafc;border-color:#cbd5e1}.export-card-btn:active{background:#f1f5f9}.export-chevron{transition:transform .15s ease;opacity:.5}.export-chevron.open{transform:rotate(180deg)}.export-dropdown{position:absolute;top:calc(100% + 4px);right:0;min-width:160px;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 4px 16px #00000014;padding:4px;z-index:50}.export-dropdown-item{display:flex;align-items:center;gap:.5rem;width:100%;padding:.5rem .75rem;border:none;border-radius:6px;background:none;color:#334155;font-size:.8125rem;font-weight:400;cursor:pointer;transition:background .1s ease}.export-dropdown-item:hover{background:#f1f5f9}.export-dropdown-item:active{background:#e2e8f0}@media (max-width: 640px){.header-content{flex-direction:column;align-items:flex-start;gap:1rem}.header-title{font-size:1.5rem}}';
|
|
3279
|
-
|
|
3280
|
-
// packages/web-templates/src/generated/exportHtmlTemplate.ts
|
|
3281
|
-
init_esbuild_shims();
|
|
3282
|
-
var HTML_TEMPLATE = '<!doctype html>\n<html lang="en" class="dark">\n <head>\n <meta charset="UTF-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1.0" />\n <link\n rel="icon"\n type="image/svg+xml"\n href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20141.38%20140%22%3E%0A%20%20%3Cpath%0A%20%20%20%20fill%3D%22%23000000%22%0A%20%20%20%20d%3D%22m140.93%2085-16.35-28.33-1.93-3.34%208.66-15a3.323%203.323%200%200%200%200-3.34l-9.62-16.67c-.3-.51-.72-.93-1.22-1.22s-1.07-.45-1.67-.45H82.23l-8.66-15a3.33%203.33%200%200%200-2.89-1.67H51.43c-.59%200-1.17.16-1.66.45-.5.29-.92.71-1.22%201.22L32.19%2029.98l-1.92%203.33H12.96c-.59%200-1.17.16-1.66.45-.5.29-.93.71-1.22%201.22L.45%2051.66a3.323%203.323%200%200%200%200%203.34l18.28%2031.67-8.66%2015a3.32%203.32%200%200%200%200%203.34l9.62%2016.67c.3.51.72.93%201.22%201.22s1.07.45%201.67.45h36.56l8.66%2015a3.35%203.35%200%200%200%202.89%201.67h19.25a3.34%203.34%200%200%200%202.89-1.67l18.28-31.67h17.32c.6%200%201.17-.16%201.67-.45s.92-.71%201.22-1.22l9.62-16.67a3.323%203.323%200%200%200%200-3.34ZM51.44%203.33%2061.07%2020l-9.63%2016.66h76.98l-9.62%2016.66H45.67l-11.54-20zM57.21%20120H22.58l9.63-16.67h19.25l-38.5-66.67h19.25l9.62%2016.67L68.78%20100l-11.55%2020Zm61.59-33.34-9.62-16.67-38.49%2066.67-9.63-16.67%209.63-16.66%2026.94-46.67h23.1l17.32%2030z%22%0A%20%20%2F%3E%0A%3C%2Fsvg%3E"\n />\n <script\n crossorigin\n src="https://unpkg.com/react@18.2.0/umd/react.production.min.js"\n ></script>\n <script\n crossorigin\n src="https://unpkg.com/react-dom@18.2.0/umd/react-dom.production.min.js"\n ></script>\n <script>\n const withKey = (props, key) =>\n key == null ? props : Object.assign({}, props, { key });\n const jsx = (type, props, key) =>\n React.createElement(type, withKey(props, key));\n const jsxRuntime = {\n Fragment: React.Fragment,\n jsx,\n jsxs: jsx,\n jsxDEV: jsx,\n };\n window.ReactJSXRuntime = jsxRuntime;\n window[\'react/jsx-runtime\'] = jsxRuntime;\n window[\'react/jsx-dev-runtime\'] = jsxRuntime;\n </script>\n <script src="https://unpkg.com/@qwen-code/webui@latest/dist/index.umd.js"></script>\n <link\n rel="stylesheet"\n href="https://unpkg.com/@qwen-code/webui@latest/dist/styles.css"\n />\n <title>Qwen Code Chat Export</title>\n <script>\n // Pre-hydrate FOUC guard: must run before <style> below applies layout.\n // The storage key \'qwen-export-theme\' is duplicated here verbatim and\n // MUST stay in sync with EXPORT_THEME_STORAGE_KEY in\n // src/components/useExportTheme.ts.\n (function () {\n try {\n var stored = window.localStorage.getItem(\'qwen-export-theme\');\n var theme = stored === \'light\' || stored === \'dark\' ? stored : \'dark\';\n var root = document.documentElement;\n // Toggle-style writes mirror the React hook\'s effect, so the two\n // code paths converge on identical class state.\n root.classList.toggle(\'light\', theme === \'light\');\n root.classList.toggle(\'dark\', theme === \'dark\');\n } catch (e) {\n // localStorage may be unavailable (private mode, file:// sandbox);\n // the static class="dark" attribute on <html> remains the default.\n }\n })();\n </script>\n <style>\n @font-face {\n font-family: "Press Start 2P";\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url("data:font/woff2;base64,d09GMgABAAAAAALQAAwAAAAABfwAAAKBAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCgGYABUEQgKgkSCDAsOAAE2AiQDDgQgBYRKByAb4QTIBB76Oev9JKW02x5ClpELSxHm1M0JQ+OBJAtDpAAVUQ7i///V+A/YgLVswlGo/7a+lmW3sfnUvoBFcUKzUFEnKo08S0F2T8TiAAJQieDvSGUVdW3smBv2LuCGjSpG3jQTD/m9OI5lTDomdQG1hkoMkCJu1ZYsmL42dEu7W8q5gUan/J6yyO+FX5NO5qQPxaqGnEINZ2q7kDf0+i4UigAXdiQUNMppoJnOzcxnDMwX5lXzinnJPDtkzhQFwjTx0DGrx1zkoNhIYr5LTKHjclcs+z3Frrh2ue3Kvk6bxzoRJLsIQpWcQhW27bgJwoUHYXNi2WWnVRUWaVNS0XMJ1eIUHlSX0l3l7BZOOos1ySk7NUWl6+eobG3Nfpj96g8EvukB3Qjouo4+O6svG9/0b8ZyKmfoZj9gzBqq8I2MS7Pf2JquL9vZwHJ51djyD01vbVHRDxSslvFBZwMHjQvexMxIvz3oyftul2+k9yBS+xGM+l+d+Pvo/zH5fVXMRvsHhG4u9/dRsgQyF67l9+jYgZuy+Ath2O6EUzU7E6BxF41nQk2cgkN8IIlOPKecMgWccSrE4XdaOECf00oUaeTm34EpvHhZIodEEllllBWmWcJLyQmsPjNHAousMEkijVRQR5OgNc4qq7TiZZg89pJCE/G0MM4kPuYqqIOKrQw3WmQBjVQSSLLm1H1NiGmCN21uwK/JpZRuWignd/klmbWXFEtZZIn1o8cmkaDqX5JIJgWNNqYYR9s0GsRFZhhntKJSjI+KTaFDZ+MoRllkjHWK2ADCxilLQGTkJZo4NAJMDwhAiK0CJD+jjKFRwWBapYFh5rdzfogQC/m1XLplXiEFEwAA") format("woff2");\n }\n :root{--bg-primary: #18181b;--bg-secondary: #27272a;--text-primary: #f4f4f5;--text-secondary: #a1a1aa;--border-color: #3f3f46;--accent-color: #3b82f6;--header-bg: rgba(24, 24, 27, .95);--scrollbar-thumb-hover: #52525b}:root.light{--bg-primary: #ffffff;--bg-secondary: #f3f4f6;--text-primary: #1f2937;--text-secondary: #6b7280;--border-color: #e5e7eb;--accent-color: #2563eb;--header-bg: rgba(249, 250, 251, .95);--scrollbar-thumb-hover: #d1d5db;--app-primary-foreground: #1f2937;--app-secondary-foreground: #6b7280;--app-background: #ffffff;--app-primary-background: #ffffff;--app-background-secondary: #f3f4f6;--app-background-tertiary: #e5e7eb;--app-foreground: #1f2937;--app-foreground-secondary: #6b7280;--app-foreground-muted: #9ca3af;--app-border: #e5e7eb;--app-primary-border-color: #e5e7eb;--app-input-background: #ffffff;--app-input-border: #d1d5db;--app-input-placeholder-foreground: #9ca3af;--app-ghost-button-hover-background: rgba(0, 0, 0, .05);--app-header-background: #f9fafb;--app-list-hover-background: rgba(0, 0, 0, .05);--app-list-active-background: #3b82f6;--app-menu-background: #ffffff;--app-menu-border: #e5e7eb;--app-menu-foreground: #1f2937;--app-tool-background: #ffffff;--app-code-background: #f3f4f6;--app-secondary-background: #f3f4f6;--app-input-secondary-background: #f3f4f6;--app-input-foreground: #1f2937;--app-button-background: #e5e7eb;--app-button-secondary-background: #f3f4f6;--app-button-foreground: #1f2937;--app-transparent-inner-border: rgba(0, 0, 0, .1);--app-warning-foreground: #b45309}body{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;margin:0;padding:0;background-color:var(--bg-primary);color:var(--text-primary);line-height:1.6;-webkit-font-smoothing:antialiased}.page-wrapper{min-height:100vh;display:flex;flex-direction:column;align-items:center}.header{width:100%;padding:16px 24px;border-bottom:1px solid var(--border-color);background-color:var(--header-bg);backdrop-filter:blur(8px);position:sticky;top:0;z-index:100;display:flex;justify-content:space-between;align-items:center;box-sizing:border-box}.header-left{display:flex;align-items:center;gap:12px}.header-right{display:flex;align-items:center;gap:8px}.theme-toggle{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;background:transparent;border:1px solid var(--border-color);border-radius:999px;color:var(--text-secondary);cursor:pointer;transition:background-color .15s ease,color .15s ease,border-color .15s ease}.theme-toggle:hover{background-color:var(--bg-secondary);color:var(--text-primary)}.theme-toggle:focus-visible{outline:2px solid var(--accent-color);outline-offset:2px}.theme-toggle:active{transform:scale(.95)}.logo-icon{width:24px;height:24px;flex-shrink:0;display:flex;align-items:center;justify-content:center}.logo-icon svg{width:100%;height:100%}.logo{display:flex;flex-direction:column;line-height:1}.logo-text{font-family:"Press Start 2P",cursive;font-weight:400;font-size:24px;letter-spacing:-.05em;position:relative;color:#fff}.logo-text-inner{background:linear-gradient(to right,#60a5fa,#a855f7);-webkit-background-clip:text;-webkit-text-fill-color:transparent;position:relative;z-index:2}.logo-text:before,.logo-text:after{content:attr(data-text);position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;background:none;-webkit-text-fill-color:transparent;-webkit-text-stroke:1px rgba(96,165,250,.3)}.logo-text:before{transform:translate(2px,2px);-webkit-text-stroke:1px rgba(168,85,247,.3)}.logo-text:after{transform:translate(4px,4px);opacity:.4}.logo-sub{font-size:11px;font-weight:600;color:var(--text-secondary);letter-spacing:.05em;text-transform:uppercase;margin-top:4px}.badge{font-size:11px;padding:2px 8px;border-radius:999px;background-color:var(--bg-secondary);color:var(--text-secondary);border:1px solid var(--border-color);font-weight:500}.meta{display:flex;gap:24px;font-size:13px;color:var(--text-secondary)}.meta-item{display:flex;align-items:center;gap:8px}.meta-label{color:var(--text-secondary)}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{background:var(--bg-primary)}::-webkit-scrollbar-thumb{background:var(--bg-secondary);border-radius:5px;border:2px solid var(--bg-primary)}::-webkit-scrollbar-thumb:hover{background:var(--scrollbar-thumb-hover)}@media (max-width: 768px){.chat-container{max-width:100%;padding:20px 16px}.header{padding:12px 16px}.meta{width:100%;flex-direction:column;gap:6px}}@media (max-width: 480px){.chat-container{padding:16px 12px}}.content-wrapper{display:flex;width:100%;max-width:1600px;height:calc(100vh - 73px)}.chat-container{flex:1;min-width:0;overflow-y:auto;padding:24px;box-sizing:border-box}.metadata-sidebar{width:320px;min-width:320px;padding:12px;border-right:1px solid var(--border-color);background-color:var(--bg-secondary);display:flex;flex-direction:column;gap:12px;overflow-y:auto;height:100%;box-sizing:border-box}.metadata-section{display:flex;flex-direction:column;gap:8px}.metadata-section-title{font-size:10px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.05em;margin:0;padding-bottom:4px;border-bottom:1px solid var(--border-color)}.metadata-section-small{margin-top:auto;padding-top:12px;border-top:1px solid var(--border-color)}.metadata-item{display:flex;flex-direction:column;gap:2px}.metadata-item-empty{font-size:12px;color:var(--text-secondary);margin:0;padding:4px 0}.metadata-content{display:flex;flex-direction:column;gap:2px;min-width:0}.metadata-content .metadata-label{font-size:10px;color:var(--text-secondary)}.metadata-content .metadata-value{font-size:12px;color:var(--text-primary);word-break:break-all;line-height:1.3;cursor:pointer}.metadata-content .metadata-value.multiline{white-space:pre-wrap}.metadata-content .metadata-value.text-green{color:#22c55e}.metadata-content .metadata-value.text-red{color:#ef4444}.metadata-value-with-copy{display:flex;align-items:center;gap:8px}.metadata-value-with-copy .metadata-value{flex:1;min-width:0}.copy-button{display:inline-flex;align-items:center;justify-content:center;padding:4px;background:transparent;border:1px solid var(--border-color, #3f3f46);border-radius:4px;color:var(--text-secondary, #a1a1aa);cursor:pointer;transition:all .15s ease;flex-shrink:0}.copy-button:hover{background:var(--bg-hover, #27272a);color:var(--text-primary, #f4f4f5);border-color:var(--border-hover, #52525b)}.copy-button:active{transform:scale(.95)}@media (max-width: 1024px){.metadata-sidebar{width:320px;min-width:320px;padding:10px}}@media (max-width: 768px){.content-wrapper{flex-direction:column;height:auto}.chat-container{height:auto;min-height:50vh}.metadata-sidebar{width:100%;min-width:100%;height:auto;max-height:none;border-right:none;border-top:1px solid var(--border-color);padding:12px;gap:12px}.metadata-section{flex-direction:row;flex-wrap:wrap;gap:12px}.metadata-section-title{width:100%;border-bottom:none;padding-bottom:0}.metadata-item{flex:1;min-width:140px}.metadata-section-small{margin-top:0;padding-top:0;border-top:none}}.modal-overlay{position:fixed;inset:0;z-index:1000;background-color:#0009;display:flex;align-items:center;justify-content:center;padding:24px}.modal-container{background-color:var(--bg-secondary);border:1px solid var(--border-color);border-radius:12px;width:100%;max-width:800px;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 25px 50px -12px #00000080}.modal-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border-color);flex-shrink:0}.modal-title{font-size:13px;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.modal-close{background:none;border:none;color:var(--text-secondary);cursor:pointer;font-size:16px;padding:4px 8px;border-radius:6px;line-height:1;transition:background-color .15s,color .15s}.modal-close:hover{background-color:var(--border-color);color:var(--text-primary)}.modal-content{margin:0;padding:16px;overflow:auto;font-size:13px;line-height:1.6;color:var(--text-primary);white-space:pre-wrap;word-break:break-word}\n </style>\n </head>\n <body>\n <div id="app"></div>\n\n <script id="chat-data" type="application/json"></script>\n <script>\n (()=>{var f=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 141.38 140">\n <path\n fill="#000000"\n d="m140.93 85-16.35-28.33-1.93-3.34 8.66-15a3.323 3.323 0 0 0 0-3.34l-9.62-16.67c-.3-.51-.72-.93-1.22-1.22s-1.07-.45-1.67-.45H82.23l-8.66-15a3.33 3.33 0 0 0-2.89-1.67H51.43c-.59 0-1.17.16-1.66.45-.5.29-.92.71-1.22 1.22L32.19 29.98l-1.92 3.33H12.96c-.59 0-1.17.16-1.66.45-.5.29-.93.71-1.22 1.22L.45 51.66a3.323 3.323 0 0 0 0 3.34l18.28 31.67-8.66 15a3.32 3.32 0 0 0 0 3.34l9.62 16.67c.3.51.72.93 1.22 1.22s1.07.45 1.67.45h36.56l8.66 15a3.35 3.35 0 0 0 2.89 1.67h19.25a3.34 3.34 0 0 0 2.89-1.67l18.28-31.67h17.32c.6 0 1.17-.16 1.67-.45s.92-.71 1.22-1.22l9.62-16.67a3.323 3.323 0 0 0 0-3.34ZM51.44 3.33 61.07 20l-9.63 16.66h76.98l-9.62 16.66H45.67l-11.54-20zM57.21 120H22.58l9.63-16.67h19.25l-38.5-66.67h19.25l9.62 16.67L68.78 100l-11.55 20Zm61.59-33.34-9.62-16.67-38.49 66.67-9.63-16.67 9.63-16.66 26.94-46.67h23.1l17.32 30z"\n />\n</svg>\n`;var l=window.React,h=({state:e,onClose:t})=>(l.useEffect(()=>{if(e.visible){let o=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=o}}},[e.visible]),e.visible?l.createElement("div",{className:"modal-overlay",onClick:t},l.createElement("div",{className:"modal-container",onClick:o=>o.stopPropagation()},l.createElement("div",{className:"modal-header"},l.createElement("span",{className:"modal-title font-mono"},e.fileName),l.createElement("button",{className:"modal-close",onClick:t,"aria-label":"Close"},"\\u2715")),l.createElement("pre",{className:"modal-content"},e.content))):null),x=()=>{let[e,t]=l.useState({visible:!1,content:"",fileName:""}),o=l.useCallback((n,p="temp")=>{t({visible:!0,content:n,fileName:p})},[]),i=l.useCallback(()=>{t(n=>({...n,visible:!1}))},[]);return{modalState:e,openModal:o,closeModal:i}};var z=window.React,b=()=>{let{modalState:e,openModal:t,closeModal:o}=x();return{platformContext:z.useMemo(()=>({platform:"web",postMessage:n=>{console.log("Posted message:",n)},onMessage:n=>(window.addEventListener("message",n),()=>window.removeEventListener("message",n)),openFile:n=>{console.log("Opening file:",n)},openTempFile:t,getResourceUrl:()=>{},features:{canOpenFile:!1,canOpenTempFile:!0,canCopy:!0}}),[t]),modalState:e,closeModal:o}};var a=({label:e,value:t,valueClass:o})=>t==null||t===""?null:React.createElement("div",{className:"metadata-item"},React.createElement("div",{className:"metadata-content"},React.createElement("span",{className:"metadata-label"},e),React.createElement("span",{className:`metadata-value ${o||""}`,title:typeof t=="string"?t:void 0},t)));var v=e=>!!e&&typeof e=="object",w=()=>{let e=document.getElementById("chat-data");if(!(e!=null&&e.textContent))return{};try{let t=JSON.parse(e.textContent);return t&&typeof t=="object"?t:{}}catch(t){return console.error("Failed to parse chat data.",t),{}}};var y=e=>{if(!e)return"-";try{return new Date(e).toLocaleString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch(t){return e}},k=e=>{if(!e)return"-";try{let o=new Date(e).getTime();if(Number.isNaN(o))return"-";let n=Math.max(0,new Date().getTime()-o),p=Math.floor(n/1e3),c=Math.floor(p/60),d=Math.floor(c/60),s=Math.floor(d/24),m=Math.floor(s/7),g=Math.floor(s/30),u=Math.floor(s/365);return p<60?"just now":c<60?`${c} minute${c===1?"":"s"} ago`:d<24?`${d} hour${d===1?"":"s"} ago`:s<7?`${s} day${s===1?"":"s"} ago`:m<4?`${m} week${m===1?"":"s"} ago`:g<12?`${g} month${g===1?"":"s"} ago`:`${u} year${u===1?"":"s"} ago`}catch(t){return"-"}};var M=e=>{if(e!=null)return e>=1e6?`${(e/1e6).toFixed(e%1e6===0?0:1)}m`:e>=1e3?`${(e/1e3).toFixed(e%1e3===0?0:1)}k`:e.toString()};var T=({metadata:e})=>React.createElement("aside",{className:"metadata-sidebar"},React.createElement("div",{className:"metadata-section"},React.createElement("h3",{className:"metadata-section-title"},"Session Info"),React.createElement(a,{label:"Session created",value:k(e.startTime)}),React.createElement(a,{label:"Project",value:e.cwd,valueClass:"multiline"}),e.gitRepo&&React.createElement(a,{label:"Repository",value:e.gitRepo}),e.gitBranch&&React.createElement(a,{label:"Branch",value:e.gitBranch}),e.model&&React.createElement(a,{label:"Model",value:e.model}),e.channel&&React.createElement(a,{label:"Channel",value:e.channel})),React.createElement("div",{className:"metadata-section"},React.createElement("h3",{className:"metadata-section-title"},"Statistics"),React.createElement(a,{label:"Prompts",value:e.promptCount}),e.contextUsagePercent!==void 0&&e.contextWindowSize!==void 0&&React.createElement(a,{label:"Context",value:`${e.contextUsagePercent>100?">100":e.contextUsagePercent}% of ${M(e.contextWindowSize)}`,valueClass:e.contextUsagePercent>100?"text-red":void 0}),e.totalTokens!==void 0&&React.createElement(a,{label:"Tokens",value:e.totalTokens.toLocaleString()})),React.createElement("div",{className:"metadata-section"},React.createElement("h3",{className:"metadata-section-title"},"File Operations"),e.filesWritten!==void 0&&e.filesWritten>0&&React.createElement(a,{label:"Files modified",value:e.filesWritten}),e.linesAdded!==void 0&&e.linesAdded>0&&React.createElement(a,{label:"Added",value:`+${e.linesAdded}`,valueClass:"text-green"}),e.linesRemoved!==void 0&&e.linesRemoved>0&&React.createElement(a,{label:"Removed",value:`-${e.linesRemoved}`,valueClass:"text-red"}),(e.filesWritten===void 0||e.filesWritten===0)&&(e.linesAdded===void 0||e.linesAdded===0)&&(e.linesRemoved===void 0||e.linesRemoved===0)&&React.createElement("p",{className:"metadata-item metadata-item-empty"},"No file changes")),React.createElement("div",{className:"metadata-section metadata-section-small"},React.createElement(a,{label:"Session ID",value:e.sessionId,valueClass:"font-mono"}),React.createElement(a,{label:"Export Time",value:y(e.exportTime)})));var $=()=>React.createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true"},React.createElement("circle",{cx:"12",cy:"12",r:"4"}),React.createElement("path",{d:"M12 2v2"}),React.createElement("path",{d:"M12 20v2"}),React.createElement("path",{d:"m4.93 4.93 1.41 1.41"}),React.createElement("path",{d:"m17.66 17.66 1.41 1.41"}),React.createElement("path",{d:"M2 12h2"}),React.createElement("path",{d:"M20 12h2"}),React.createElement("path",{d:"m6.34 17.66-1.41 1.41"}),React.createElement("path",{d:"m19.07 4.93-1.41 1.41"})),D=()=>React.createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true"},React.createElement("path",{d:"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"})),C=({theme:e,onToggle:t})=>{let o=e==="light",i=o?"Switch to dark theme":"Switch to light theme";return React.createElement("button",{type:"button",className:"theme-toggle","aria-label":i,"aria-pressed":o,title:i,onClick:t},React.createElement(o?D:$,null))};var L=window.React,{useCallback:j,useEffect:I,useState:W}=L,N="qwen-export-theme",R=e=>e==="light"||e==="dark",F=()=>{try{let e=window.localStorage.getItem(N);if(R(e))return e}catch(e){}return"dark"},O=e=>{let t=document.documentElement;t.classList.toggle("light",e==="light"),t.classList.toggle("dark",e==="dark")},S=()=>{let[e,t]=W(F);I(()=>{O(e);try{window.localStorage.setItem(N,e)}catch(i){}},[e]);let o=j(()=>{t(i=>i==="light"?"dark":"light")},[]);return{theme:e,toggleTheme:o}};var A=window.ReactDOM,r=window.React,{ChatViewer:U,PlatformProvider:V}=QwenCodeWebUI,B=f?f.replace(/<svg([^>]*)>/,\'<svg$1><defs><linearGradient id="qwen-logo-gradient" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#60a5fa" /><stop offset="100%" stop-color="#a855f7" /></linearGradient></defs>\').replace(/fill="[^"]*"/,\'fill="url(#qwen-logo-gradient)"\'):f,H=()=>{let e=w(),o=(Array.isArray(e.messages)?e.messages:[]).filter(v).filter(m=>m.type!=="system"),i=e.metadata,{platformContext:n,modalState:p,closeModal:c}=b(),{theme:d,toggleTheme:s}=S();return r.createElement("div",{className:"page-wrapper"},r.createElement("header",{className:"header"},r.createElement("div",{className:"header-left"},r.createElement("div",{className:"logo-icon","aria-hidden":"true",dangerouslySetInnerHTML:{__html:B}}),r.createElement("div",{className:"logo"},r.createElement("div",{className:"logo-text","data-text":"QWEN"},r.createElement("span",{className:"logo-text-inner"},"QWEN")))),r.createElement("div",{className:"header-right"},r.createElement(C,{theme:d,onToggle:s}))),r.createElement("div",{className:"content-wrapper"},r.createElement("div",{className:"chat-container"},r.createElement(V,{value:n},r.createElement(U,{messages:o,autoScroll:!1,theme:d}))),i&&r.createElement(T,{metadata:i})),r.createElement(h,{state:p,onClose:c}))},E=document.getElementById("app");E?A.createRoot(E).render(r.createElement(H,null)):console.error("App container not found.");})();;\n </script>\n </body>\n</html>\n';
|
|
3283
|
-
|
|
3284
|
-
// packages/cli/src/ui/utils/export/formatters/html.ts
|
|
3285
|
-
function escapeJsonForHtml(json) {
|
|
3286
|
-
return json.replace(/<\/script/gi, "<\\/script").replace(/&/g, "\\u0026").replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
3287
|
-
}
|
|
3288
|
-
__name(escapeJsonForHtml, "escapeJsonForHtml");
|
|
3289
|
-
function loadHtmlTemplate() {
|
|
3290
|
-
return HTML_TEMPLATE;
|
|
3291
|
-
}
|
|
3292
|
-
__name(loadHtmlTemplate, "loadHtmlTemplate");
|
|
3293
|
-
function injectDataIntoHtmlTemplate(template, data) {
|
|
3294
|
-
const jsonData = JSON.stringify(data, null, 2);
|
|
3295
|
-
const escapedJsonData = escapeJsonForHtml(jsonData);
|
|
3296
|
-
const idAttribute = 'id="chat-data"';
|
|
3297
|
-
const idIndex = template.indexOf(idAttribute);
|
|
3298
|
-
if (idIndex === -1) {
|
|
3299
|
-
return template;
|
|
3300
|
-
}
|
|
3301
|
-
const openTagStart = template.lastIndexOf("<script", idIndex);
|
|
3302
|
-
if (openTagStart === -1) {
|
|
3303
|
-
return template;
|
|
3304
|
-
}
|
|
3305
|
-
const openTagEnd = template.indexOf(">", idIndex);
|
|
3306
|
-
if (openTagEnd === -1) {
|
|
3307
|
-
return template;
|
|
3308
|
-
}
|
|
3309
|
-
const closeTagStart = template.indexOf("</script>", openTagEnd);
|
|
3310
|
-
if (closeTagStart === -1) {
|
|
3311
|
-
return template;
|
|
3312
|
-
}
|
|
3313
|
-
const lineStart = template.lastIndexOf("\n", openTagStart);
|
|
3314
|
-
const lineIndent = lineStart === -1 ? "" : template.slice(lineStart + 1, openTagStart);
|
|
3315
|
-
const indentedJson = escapedJsonData.split("\n").map((line) => `${lineIndent}${line}`).join("\n");
|
|
3316
|
-
const before = template.slice(0, openTagEnd + 1);
|
|
3317
|
-
const after = template.slice(closeTagStart);
|
|
3318
|
-
return `${before}
|
|
3319
|
-
${indentedJson}
|
|
3320
|
-
${after}`;
|
|
3321
|
-
}
|
|
3322
|
-
__name(injectDataIntoHtmlTemplate, "injectDataIntoHtmlTemplate");
|
|
3323
|
-
function toHtml(sessionData) {
|
|
3324
|
-
const template = loadHtmlTemplate();
|
|
3325
|
-
return injectDataIntoHtmlTemplate(template, sessionData);
|
|
3326
|
-
}
|
|
3327
|
-
__name(toHtml, "toHtml");
|
|
3328
|
-
|
|
3329
|
-
// packages/cli/src/ui/utils/export/formatters/json.ts
|
|
3330
|
-
init_esbuild_shims();
|
|
3331
|
-
function toJson(sessionData) {
|
|
3332
|
-
return JSON.stringify(sessionData, null, 2);
|
|
3333
|
-
}
|
|
3334
|
-
__name(toJson, "toJson");
|
|
3335
|
-
|
|
3336
|
-
// packages/cli/src/ui/utils/export/formatters/jsonl.ts
|
|
3337
|
-
init_esbuild_shims();
|
|
3338
|
-
function toJsonl(sessionData) {
|
|
3339
|
-
const lines = [];
|
|
3340
|
-
const sourceMetadata = sessionData.metadata;
|
|
3341
|
-
const metadata = {
|
|
3342
|
-
type: "session_metadata",
|
|
3343
|
-
sessionId: sessionData.sessionId,
|
|
3344
|
-
startTime: sessionData.startTime
|
|
3345
|
-
};
|
|
3346
|
-
if (sourceMetadata?.exportTime) {
|
|
3347
|
-
metadata["exportTime"] = sourceMetadata.exportTime;
|
|
3348
|
-
}
|
|
3349
|
-
if (sourceMetadata?.cwd) {
|
|
3350
|
-
metadata["cwd"] = sourceMetadata.cwd;
|
|
3351
|
-
}
|
|
3352
|
-
if (sourceMetadata?.gitRepo) {
|
|
3353
|
-
metadata["gitRepo"] = sourceMetadata.gitRepo;
|
|
3354
|
-
}
|
|
3355
|
-
if (sourceMetadata?.gitBranch) {
|
|
3356
|
-
metadata["gitBranch"] = sourceMetadata.gitBranch;
|
|
3357
|
-
}
|
|
3358
|
-
if (sourceMetadata?.model) {
|
|
3359
|
-
metadata["model"] = sourceMetadata.model;
|
|
3360
|
-
}
|
|
3361
|
-
if (sourceMetadata?.channel) {
|
|
3362
|
-
metadata["channel"] = sourceMetadata.channel;
|
|
3363
|
-
}
|
|
3364
|
-
if (sourceMetadata?.promptCount !== void 0) {
|
|
3365
|
-
metadata["promptCount"] = sourceMetadata.promptCount;
|
|
3366
|
-
}
|
|
3367
|
-
if (sourceMetadata?.contextUsagePercent !== void 0) {
|
|
3368
|
-
metadata["contextUsagePercent"] = sourceMetadata.contextUsagePercent;
|
|
3369
|
-
}
|
|
3370
|
-
if (sourceMetadata?.contextWindowSize !== void 0) {
|
|
3371
|
-
metadata["contextWindowSize"] = sourceMetadata.contextWindowSize;
|
|
3372
|
-
}
|
|
3373
|
-
if (sourceMetadata?.totalTokens !== void 0) {
|
|
3374
|
-
metadata["totalTokens"] = sourceMetadata.totalTokens;
|
|
3375
|
-
}
|
|
3376
|
-
if (sourceMetadata?.filesWritten !== void 0) {
|
|
3377
|
-
metadata["filesWritten"] = sourceMetadata.filesWritten;
|
|
3378
|
-
}
|
|
3379
|
-
if (sourceMetadata?.linesAdded !== void 0) {
|
|
3380
|
-
metadata["linesAdded"] = sourceMetadata.linesAdded;
|
|
3381
|
-
}
|
|
3382
|
-
if (sourceMetadata?.linesRemoved !== void 0) {
|
|
3383
|
-
metadata["linesRemoved"] = sourceMetadata.linesRemoved;
|
|
3384
|
-
}
|
|
3385
|
-
if (sourceMetadata?.uniqueFiles && sourceMetadata.uniqueFiles.length > 0) {
|
|
3386
|
-
metadata["uniqueFiles"] = sourceMetadata.uniqueFiles;
|
|
3387
|
-
}
|
|
3388
|
-
lines.push(JSON.stringify(metadata));
|
|
3389
|
-
for (const message of sessionData.messages) {
|
|
3390
|
-
lines.push(JSON.stringify(message));
|
|
3391
|
-
}
|
|
3392
|
-
return lines.join("\n");
|
|
3393
|
-
}
|
|
3394
|
-
__name(toJsonl, "toJsonl");
|
|
3395
|
-
|
|
3396
|
-
// packages/cli/src/ui/utils/export/utils.ts
|
|
3397
|
-
init_esbuild_shims();
|
|
3398
|
-
function generateExportFilename(extension) {
|
|
3399
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3400
|
-
return `qwen-code-export-${timestamp}.${extension}`;
|
|
3401
|
-
}
|
|
3402
|
-
__name(generateExportFilename, "generateExportFilename");
|
|
3403
|
-
|
|
3404
|
-
// packages/cli/src/ui/utils/export/index.ts
|
|
3405
|
-
init_esbuild_shims();
|
|
3406
|
-
|
|
3407
|
-
// packages/cli/src/utils/json-string-byte-projection.ts
|
|
3408
|
-
init_esbuild_shims();
|
|
3409
|
-
import { Buffer as Buffer2 } from "node:buffer";
|
|
3410
|
-
var JSON_STRING_DELIMITER_BYTES = 2;
|
|
3411
|
-
function jsonPayloadBytesAt(value, index) {
|
|
3412
|
-
const code = value.charCodeAt(index);
|
|
3413
|
-
if (code === 34 || code === 92) return 2;
|
|
3414
|
-
if (code <= 31) {
|
|
3415
|
-
return code === 8 || code === 9 || code === 10 || code === 12 || code === 13 ? 2 : 6;
|
|
3416
|
-
}
|
|
3417
|
-
if (code <= 127) return 1;
|
|
3418
|
-
if (code <= 2047) return 2;
|
|
3419
|
-
if (code >= 55296 && code <= 56319) {
|
|
3420
|
-
const next = value.charCodeAt(index + 1);
|
|
3421
|
-
return next >= 56320 && next <= 57343 ? 4 : 6;
|
|
3422
|
-
}
|
|
3423
|
-
if (code >= 56320 && code <= 57343) return 6;
|
|
3424
|
-
return 3;
|
|
3425
|
-
}
|
|
3426
|
-
__name(jsonPayloadBytesAt, "jsonPayloadBytesAt");
|
|
3427
|
-
function jsonPayloadWidthAt(value, index) {
|
|
3428
|
-
const code = value.charCodeAt(index);
|
|
3429
|
-
if (code < 55296 || code > 56319) return 1;
|
|
3430
|
-
const next = value.charCodeAt(index + 1);
|
|
3431
|
-
return next >= 56320 && next <= 57343 ? 2 : 1;
|
|
3432
|
-
}
|
|
3433
|
-
__name(jsonPayloadWidthAt, "jsonPayloadWidthAt");
|
|
3434
|
-
function jsonStringPayloadByteLength(value, stopAfterBytes = Number.POSITIVE_INFINITY) {
|
|
3435
|
-
let bytes = 0;
|
|
3436
|
-
for (let index = 0; index < value.length; ) {
|
|
3437
|
-
bytes += jsonPayloadBytesAt(value, index);
|
|
3438
|
-
if (bytes > stopAfterBytes) return bytes;
|
|
3439
|
-
index += jsonPayloadWidthAt(value, index);
|
|
3440
|
-
}
|
|
3441
|
-
return bytes;
|
|
3442
|
-
}
|
|
3443
|
-
__name(jsonStringPayloadByteLength, "jsonStringPayloadByteLength");
|
|
3444
|
-
function jsonStringJsonByteLength(value) {
|
|
3445
|
-
return JSON_STRING_DELIMITER_BYTES + jsonStringPayloadByteLength(value);
|
|
3446
|
-
}
|
|
3447
|
-
__name(jsonStringJsonByteLength, "jsonStringJsonByteLength");
|
|
3448
|
-
function jsonPayloadWidthBefore(value, end) {
|
|
3449
|
-
const last = value.charCodeAt(end - 1);
|
|
3450
|
-
if (last >= 56320 && last <= 57343 && end >= 2) {
|
|
3451
|
-
const previous = value.charCodeAt(end - 2);
|
|
3452
|
-
if (previous >= 55296 && previous <= 56319) return 2;
|
|
3453
|
-
}
|
|
3454
|
-
return 1;
|
|
3455
|
-
}
|
|
3456
|
-
__name(jsonPayloadWidthBefore, "jsonPayloadWidthBefore");
|
|
3457
|
-
function selectPrefix(value, budget) {
|
|
3458
|
-
let end = 0;
|
|
3459
|
-
let bytes = 0;
|
|
3460
|
-
while (end < value.length) {
|
|
3461
|
-
const partBytes = jsonPayloadBytesAt(value, end);
|
|
3462
|
-
if (bytes + partBytes > budget) break;
|
|
3463
|
-
bytes += partBytes;
|
|
3464
|
-
end += jsonPayloadWidthAt(value, end);
|
|
3465
|
-
}
|
|
3466
|
-
return end;
|
|
3467
|
-
}
|
|
3468
|
-
__name(selectPrefix, "selectPrefix");
|
|
3469
|
-
function selectSuffix(value, budget) {
|
|
3470
|
-
let start = value.length;
|
|
3471
|
-
let bytes = 0;
|
|
3472
|
-
while (start > 0) {
|
|
3473
|
-
const partWidth = jsonPayloadWidthBefore(value, start);
|
|
3474
|
-
const partBytes = jsonPayloadBytesAt(value, start - partWidth);
|
|
3475
|
-
if (bytes + partBytes > budget) break;
|
|
3476
|
-
bytes += partBytes;
|
|
3477
|
-
start -= partWidth;
|
|
3478
|
-
}
|
|
3479
|
-
return start;
|
|
3480
|
-
}
|
|
3481
|
-
__name(selectSuffix, "selectSuffix");
|
|
3482
|
-
function copyString(value) {
|
|
3483
|
-
return value.split("").join("");
|
|
3484
|
-
}
|
|
3485
|
-
__name(copyString, "copyString");
|
|
3486
|
-
function truncateJsonStringPayload(value, originalPayloadBytes, payloadBudget, marker) {
|
|
3487
|
-
if (originalPayloadBytes <= payloadBudget) return value;
|
|
3488
|
-
const markerPayloadBytes = jsonStringPayloadByteLength(marker);
|
|
3489
|
-
if (payloadBudget < markerPayloadBytes) {
|
|
3490
|
-
return copyString(value.slice(0, selectPrefix(value, payloadBudget)));
|
|
3491
|
-
}
|
|
3492
|
-
const sourceBudget = payloadBudget - markerPayloadBytes;
|
|
3493
|
-
const headBudget = Math.floor(sourceBudget * 0.2);
|
|
3494
|
-
const tailBudget = sourceBudget - headBudget;
|
|
3495
|
-
const headEnd = selectPrefix(value, headBudget);
|
|
3496
|
-
const tailStart = selectSuffix(value, tailBudget);
|
|
3497
|
-
return copyString(value.slice(0, headEnd)) + marker + copyString(value.slice(tailStart));
|
|
3498
|
-
}
|
|
3499
|
-
__name(truncateJsonStringPayload, "truncateJsonStringPayload");
|
|
3500
|
-
function projectJsonStringToByteBudget(value, jsonByteBudget, marker) {
|
|
3501
|
-
const payloadBudget = Math.max(
|
|
3502
|
-
0,
|
|
3503
|
-
jsonByteBudget - JSON_STRING_DELIMITER_BYTES
|
|
3504
|
-
);
|
|
3505
|
-
const payloadBytes = jsonStringPayloadByteLength(value, payloadBudget);
|
|
3506
|
-
if (payloadBytes <= payloadBudget) return value;
|
|
3507
|
-
const projected = truncateJsonStringPayload(
|
|
3508
|
-
value,
|
|
3509
|
-
payloadBytes,
|
|
3510
|
-
payloadBudget,
|
|
3511
|
-
marker
|
|
3512
|
-
);
|
|
3513
|
-
if (Buffer2.byteLength(JSON.stringify(projected), "utf8") <= jsonByteBudget) {
|
|
3514
|
-
return projected;
|
|
3515
|
-
}
|
|
3516
|
-
const fallback = copyString(
|
|
3517
|
-
marker.slice(0, selectPrefix(marker, payloadBudget))
|
|
3518
|
-
);
|
|
3519
|
-
return Buffer2.byteLength(JSON.stringify(fallback), "utf8") <= jsonByteBudget ? fallback : "";
|
|
3520
|
-
}
|
|
3521
|
-
__name(projectJsonStringToByteBudget, "projectJsonStringToByteBudget");
|
|
3522
|
-
|
|
3523
|
-
export {
|
|
3524
|
-
GITHUB_WORKFLOW_PATHS,
|
|
3525
|
-
SetupGithubError,
|
|
3526
|
-
setupGithub,
|
|
3527
|
-
createTranscriptMessageUpdate,
|
|
3528
|
-
createTranscriptUsageUpdate,
|
|
3529
|
-
BaseEmitter,
|
|
3530
|
-
PlanEmitter,
|
|
3531
|
-
hasFullSessionContext,
|
|
3532
|
-
ToolCallEmitter,
|
|
3533
|
-
HistoryReplayer,
|
|
3534
|
-
collectSessionData,
|
|
3535
|
-
normalizeSessionData,
|
|
3536
|
-
toMarkdown,
|
|
3537
|
-
INSIGHT_JS,
|
|
3538
|
-
INSIGHT_CSS,
|
|
3539
|
-
toHtml,
|
|
3540
|
-
toJson,
|
|
3541
|
-
toJsonl,
|
|
3542
|
-
generateExportFilename,
|
|
3543
|
-
JSON_STRING_DELIMITER_BYTES,
|
|
3544
|
-
jsonStringPayloadByteLength,
|
|
3545
|
-
jsonStringJsonByteLength,
|
|
3546
|
-
truncateJsonStringPayload,
|
|
3547
|
-
projectJsonStringToByteBudget
|
|
3548
|
-
};
|
|
3549
|
-
/**
|
|
3550
|
-
* @license
|
|
3551
|
-
* Copyright 2026 Qwen Team
|
|
3552
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
3553
|
-
*/
|
|
3554
|
-
/**
|
|
3555
|
-
* @license
|
|
3556
|
-
* Copyright 2025 Qwen Team
|
|
3557
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
3558
|
-
*/
|
|
3559
|
-
/**
|
|
3560
|
-
* @license
|
|
3561
|
-
* Copyright 2025 Qwen
|
|
3562
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
3563
|
-
*/
|
|
3564
|
-
/**
|
|
3565
|
-
* @license
|
|
3566
|
-
* Copyright 2025 Google LLC
|
|
3567
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
3568
|
-
*/
|
|
3569
|
-
/**
|
|
3570
|
-
* @license
|
|
3571
|
-
* Copyright 2025 Qwen Team
|
|
3572
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
3573
|
-
*
|
|
3574
|
-
* This file is code-generated; do not edit manually.
|
|
3575
|
-
*/
|
|
3576
|
-
/**
|
|
3577
|
-
* @license
|
|
3578
|
-
* Copyright 2025 Qwen Team
|
|
3579
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
3580
|
-
*
|
|
3581
|
-
* This HTML template is code-generated; do not edit manually.
|
|
3582
|
-
*/
|