@qwen-code/qwen-code 0.19.6-nightly.20260707.bcdb44c5d → 0.19.6-preview.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/qc-helper/docs/features/channels/_meta.ts +1 -0
- package/bundled/qc-helper/docs/features/channels/overview.md +17 -9
- package/bundled/qc-helper/docs/features/channels/wecom.md +111 -0
- package/bundled/qc-helper/docs/features/code-review.md +0 -4
- package/bundled/review/DESIGN.md +0 -4
- package/bundled/review/SKILL.md +2 -29
- package/chunks/{MaxSizedBox-EFDCCPYQ.js → MaxSizedBox-2JOX4MMR.js} +11 -9
- package/chunks/{StandaloneSessionPicker-5TQG34MY.js → StandaloneSessionPicker-Z2G37ETA.js} +24 -21
- package/chunks/{acpAgent-KQT52XWB.js → acpAgent-MQJT2H4Y.js} +74 -49
- package/chunks/{agent-RL2YOM2V.js → agent-HEVJ76EO.js} +6 -6
- package/chunks/{agent-headless-SCVFLRZ3.js → agent-headless-UNB5SWYC.js} +6 -6
- package/chunks/{anthropicContentGenerator-PPPLABT5.js → anthropicContentGenerator-AKYPSZIV.js} +3 -3
- package/chunks/{artifact-tool-H2TNPNP5.js → artifact-tool-D233YJFH.js} +25 -6
- package/chunks/{bridge-G3LFYH2D.js → bridge-GX2LGQDS.js} +11 -9
- package/chunks/{channel-worker-supervisor-B7MSMB5K.js → channel-worker-supervisor-CRCVYQIE.js} +1 -1
- package/chunks/{chunk-XUYYEFCM.js → chunk-27QGW3BK.js} +5 -5
- package/chunks/{chunk-HLJMZYTD.js → chunk-2D5Q33PT.js} +3 -3
- package/chunks/{chunk-TNIZ2HCQ.js → chunk-2MDHTI6A.js} +2 -2
- package/chunks/{chunk-VCKMHAEZ.js → chunk-2MJAXDFK.js} +6 -6
- package/chunks/{chunk-WSVZFWN4.js → chunk-2NPS2UDH.js} +305 -97
- package/chunks/{chunk-WAVK7GV6.js → chunk-2X3ZVAAT.js} +2 -2
- package/chunks/chunk-332PWN27.js +19 -0
- package/chunks/{chunk-FVMWEHWU.js → chunk-3B26UVCX.js} +114 -12
- package/chunks/{chunk-XZ2LJL4O.js → chunk-43W4YSO6.js} +1 -12
- package/chunks/{chunk-DLHOIROF.js → chunk-44NROQYV.js} +4 -2
- package/chunks/{chunk-65P5ZXUE.js → chunk-4XV2MRNK.js} +1 -1
- package/chunks/{chunk-DS6NG7SB.js → chunk-5HMMLTUD.js} +11 -11
- package/chunks/{chunk-A2CS67WK.js → chunk-5IGNZP2J.js} +1 -1
- package/chunks/{chunk-N7BUPX4V.js → chunk-6GHEZDDX.js} +1 -1
- package/chunks/{chunk-QU6OLW25.js → chunk-7O6DD2ES.js} +1 -1
- package/chunks/{chunk-RXDYWLOG.js → chunk-7R62CLMI.js} +4 -4
- package/chunks/{chunk-2BJWUJCW.js → chunk-7SAH6M3Y.js} +3 -3
- package/chunks/{chunk-OGAC66WF.js → chunk-7VCI24VZ.js} +4 -107
- package/chunks/chunk-A2X3KLC3.js +3807 -0
- package/chunks/chunk-A3ZQMFO6.js +949 -0
- package/chunks/{chunk-AY7CP32Q.js → chunk-A7UKINBT.js} +7 -7
- package/chunks/{chunk-72DDO73Z.js → chunk-ADO6IDOZ.js} +8 -8
- package/chunks/{chunk-UOGOM4NJ.js → chunk-AJ3CEJRJ.js} +10 -5
- package/chunks/{chunk-NCFY7PWS.js → chunk-CCGOFQV3.js} +51 -2
- package/chunks/{chunk-YFE4YEDW.js → chunk-DB7CZERZ.js} +1 -1
- package/chunks/{chunk-UECJ7AG2.js → chunk-DF74IL3R.js} +4 -4
- package/chunks/{chunk-7YLLBKDB.js → chunk-FCEHOKYP.js} +5 -5
- package/chunks/{chunk-JO6RDLLE.js → chunk-FRR5I3SQ.js} +1 -1
- package/chunks/{chunk-2NL7ED5Q.js → chunk-FV7425LN.js} +22 -1
- package/chunks/{chunk-NCOLCOA6.js → chunk-GPLKAQUX.js} +8 -8
- package/chunks/{chunk-AKGA72ZM.js → chunk-GV2S4F6Q.js} +5 -3
- package/chunks/{chunk-V63Q7BVE.js → chunk-GW67O5SO.js} +1 -1
- package/chunks/{chunk-2A6XOMBQ.js → chunk-HW4N45EE.js} +0 -44
- package/chunks/{chunk-S6PM5JQZ.js → chunk-IFDJAMJW.js} +484 -1222
- package/chunks/{chunk-B2FUQ22Z.js → chunk-ILFQAFWH.js} +1 -1
- package/chunks/chunk-JYFZFWSL.js +167 -0
- package/chunks/{chunk-CA373SPN.js → chunk-K56RTEBN.js} +1 -1
- package/chunks/chunk-LGFAYIKX.js +115 -0
- package/chunks/{chunk-6JESGXWU.js → chunk-LLTFLVFK.js} +4 -4
- package/chunks/{chunk-3A4MUHRP.js → chunk-MZWODTEA.js} +5 -13
- package/chunks/{chunk-IPKM25FZ.js → chunk-N33JAGJ7.js} +505 -62
- package/chunks/{chunk-B2NCNYBK.js → chunk-NVQVIJMO.js} +112 -42
- package/chunks/{chunk-INNPK6XG.js → chunk-O6T7PBUM.js} +30 -6
- package/chunks/{chunk-RN36CE4M.js → chunk-P452E6XF.js} +2 -2
- package/chunks/chunk-PS2NG7KU.js +262 -0
- package/chunks/{chunk-FTEFJT6V.js → chunk-QM4FKX7H.js} +2 -2
- package/chunks/chunk-RODQXLGZ.js +28 -0
- package/chunks/{chunk-KSPVDFE4.js → chunk-SAIILPQ3.js} +0 -3
- package/chunks/{chunk-EKDTGEX4.js → chunk-SJ3QRPN2.js} +14 -8
- package/chunks/{chunk-R57UD732.js → chunk-SKO6VJHG.js} +16 -4
- package/chunks/{chunk-66KNL43D.js → chunk-TBAZMRW3.js} +1 -1
- package/chunks/{chunk-H2UZO2II.js → chunk-TPTG52XG.js} +1 -1
- package/chunks/chunk-UIDXQNMV.js +13 -0
- package/chunks/chunk-VP2FB7OC.js +8223 -0
- package/chunks/{chunk-32KIF557.js → chunk-WKBA74DD.js} +1 -1
- package/chunks/{chunk-IEFMDFCG.js → chunk-WKTLDGD6.js} +1 -1
- package/chunks/{chunk-HT553O4R.js → chunk-WRLMLPWI.js} +3 -3
- package/chunks/{chunk-CYXPEKVN.js → chunk-XXICIIS5.js} +5 -5
- package/chunks/{chunk-5GSUPP7K.js → chunk-Y3QQV7WE.js} +2 -2
- package/chunks/{chunk-CKBRK552.js → chunk-ZKX7IBXU.js} +4 -4
- package/chunks/{chunk-CCPKBMZ4.js → chunk-ZOSL7K3L.js} +203 -38
- package/chunks/{chunk-KD4KV6XW.js → chunk-ZWFS7YCB.js} +4505 -3850
- package/chunks/{computer-use-NKJX6RTG.js → computer-use-IQ46C3YP.js} +6 -6
- package/chunks/{contextCommand-BCABFW4A.js → contextCommand-TTT6AP2W.js} +10 -9
- package/chunks/{cron-create-DDYU4DIR.js → cron-create-JSXEIPVS.js} +1 -1
- package/chunks/{cron-delete-DFKOUZWN.js → cron-delete-OIFVEPGU.js} +1 -1
- package/chunks/{cron-list-ME5QGAR5.js → cron-list-D4ZX4IOE.js} +1 -1
- package/chunks/{daemon-XWG2EGFX.js → daemon-F3I2RXP6.js} +23 -3
- package/chunks/{daemon-status-provider-V7BMA4EH.js → daemon-status-provider-5GAWK65R.js} +13 -12
- package/chunks/dist-573HNSVO.js +3217 -0
- package/chunks/{dist-VHBP2PIG.js → dist-FQ5WRJPL.js} +2 -2
- package/chunks/{dist-LPVU3L2M.js → dist-IMFFBMAT.js} +6 -3792
- package/chunks/{dist-7GU63KI5.js → dist-OT7G2WNM.js} +1 -1
- package/chunks/{dist-H4HHZYCI.js → dist-PKFTNUHO.js} +2 -2
- package/chunks/{dist-3UDX5T4T.js → dist-YTRKAVUB.js} +1 -1
- package/chunks/{earlyInputCapture-TVECMHWI.js → earlyInputCapture-LAGZUGGV.js} +6 -6
- package/chunks/{edit-VKUCEX2N.js → edit-Q5BUQC2S.js} +6 -6
- package/chunks/{en-AXARKOWO.js → en-GA2RMXY5.js} +5 -1
- package/chunks/{enter-worktree-TF6N7GA7.js → enter-worktree-DC4FHMVF.js} +6 -6
- package/chunks/{enterPlanMode-XXQGZP5T.js → enterPlanMode-5BGJBWIY.js} +6 -6
- package/chunks/{errors-LLC2B5D6.js → errors-EGX5DECS.js} +8 -8
- package/chunks/{exit-worktree-YBOMMZLI.js → exit-worktree-2EOSZNZI.js} +6 -6
- package/chunks/{exitPlanMode-74D7EOBH.js → exitPlanMode-JAQ35ELJ.js} +6 -6
- package/chunks/{fast-path-OGY4P74O.js → fast-path-QEWDA6O6.js} +5 -2
- package/chunks/{fr-MBMNQSQ6.js → fr-GWNQG4XH.js} +4 -0
- package/chunks/{gemini-IL6H4VNW.js → gemini-TQ5XANRS.js} +64 -187
- package/chunks/{geminiContentGenerator-O7OCAUQU.js → geminiContentGenerator-DCM2XGDQ.js} +1 -1
- package/chunks/{glob-X5XFJTAC.js → glob-7JLTQ4IQ.js} +6 -6
- package/chunks/{grep-53GLRSNS.js → grep-CAUXEO7Q.js} +6 -6
- package/chunks/handleAutoUpdate-XKXULZQX.js +65 -0
- package/chunks/{initializer-YBUEYP6D.js → initializer-3NRWU5JV.js} +12 -10
- package/chunks/{ja-HFV5QCHR.js → ja-2HOTA47X.js} +4 -0
- package/chunks/{list-2F3FSN46.js → list-NWO6QBDQ.js} +12 -12
- package/chunks/{loadedSettingsAdapter-AJBE627U.js → loadedSettingsAdapter-PJ77LGFS.js} +10 -10
- package/chunks/{loop-wakeup-ZW5P6VPY.js → loop-wakeup-OHWEMFP5.js} +2 -2
- package/chunks/{mcp-SEE2Z7TA.js → mcp-VFEHVF5A.js} +10 -10
- package/chunks/{monitor-YQW2M3DL.js → monitor-FY2ITVSC.js} +14 -9
- package/chunks/{nonInteractiveCli-TGWJDY47.js → nonInteractiveCli-KPCXTVWY.js} +41 -36
- package/chunks/{notebook-edit-O5G3EBYN.js → notebook-edit-BSJMXIWX.js} +6 -6
- package/chunks/{openaiContentGenerator-WAO7PPR6.js → openaiContentGenerator-BA6NWY4S.js} +5 -5
- package/chunks/{pidfile-XMDB2SF7.js → pidfile-WXMRN6QF.js} +6 -6
- package/chunks/{qwenContentGenerator-5NZ5EHRA.js → qwenContentGenerator-U4ZSLGFN.js} +8 -8
- package/chunks/{read-file-KJTMBLFF.js → read-file-VMVHNOMA.js} +2 -2
- package/chunks/{ripGrep-BCDYVQQR.js → ripGrep-NC6MUWXN.js} +6 -6
- package/chunks/{run-qwen-serve-LIWM3CMV.js → run-qwen-serve-NQH6LQTH.js} +124 -31
- package/chunks/{scheduler-VETDW3HX.js → scheduler-35T3E2UQ.js} +6 -6
- package/chunks/{serve-XKFTUZET.js → serve-C36LOB5N.js} +10 -10
- package/chunks/{server-W64GXOEJ.js → server-TDFPIDC3.js} +858 -105
- package/chunks/{session-GXNRZGVF.js → session-STHNQGRJ.js} +42 -37
- package/chunks/{settings-TIQCDHBZ.js → settings-GIE22AYF.js} +9 -9
- package/chunks/{shell-3ZZLLA35.js → shell-JD52AIMU.js} +6 -6
- package/chunks/{skill-TOX5QGBX.js → skill-L4IFKRQ5.js} +14 -4
- package/chunks/{spawnChannel-JBLAIP7L.js → spawnChannel-HGMOEPM7.js} +8 -8
- package/chunks/{src-Q7BIRWUP.js → src-3SNF3G3V.js} +15 -7
- package/chunks/{startInteractiveUI-PP72WI64.js → startInteractiveUI-C7DCDHGF.js} +4981 -13173
- package/chunks/{team-create-S44Z3N62.js → team-create-NYL7KAMA.js} +6 -6
- package/chunks/{team-plan-approval-2YPLSLO5.js → team-plan-approval-LH65JBEH.js} +6 -6
- package/chunks/{theme-manager-4MJVYHPB.js → theme-manager-ANKQO5DR.js} +6 -6
- package/chunks/{tool-search-4LSRQ24Z.js → tool-search-WZEGJFO4.js} +4 -21
- package/chunks/{trustedFolders-XMKLRQDH.js → trustedFolders-HECAG3S3.js} +7 -7
- package/chunks/updateCheck-72BBAE5V.js +65 -0
- package/chunks/{validateNonInterActiveAuth-MMMRF6WS.js → validateNonInterActiveAuth-PDQCPSNA.js} +38 -33
- package/chunks/{version-6HMEMR4K.js → version-VSEUTPNM.js} +2 -1
- package/chunks/{workflow-VYBLLOLC.js → workflow-DPF2CL7U.js} +7 -7
- package/chunks/{workspace-providers-status-5LSCQPWQ.js → workspace-providers-status-TQ23DQ2D.js} +12 -12
- package/chunks/{workspace-service-HBMBWJ4K.js → workspace-service-D34UDMEY.js} +14 -14
- package/chunks/{workspace-skills-status-TLBAQWKQ.js → workspace-skills-status-4DR5UNNC.js} +11 -11
- package/chunks/{write-file-QMAWLWCT.js → write-file-VFNAKGYM.js} +6 -6
- package/chunks/{zh-RS3HZHFH.js → zh-7XVVRTDH.js} +5 -1
- package/chunks/{zh-TW-L5GRQ4S4.js → zh-TW-DPH554OG.js} +5 -1
- package/cli.js +11 -11
- package/locales/en.js +8 -2
- package/locales/fr.js +6 -0
- package/locales/ja.js +6 -0
- package/locales/zh-TW.js +8 -2
- package/locales/zh.js +8 -2
- package/node_modules/@qwen-code/audio-capture/package.json +1 -1
- package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-arm64/@qwen-code+audio-capture.node +0 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-x64/@qwen-code+audio-capture.node +0 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/win32-x64/@qwen-code+audio-capture.node +0 -0
- package/package.json +3 -3
- package/web-shell/assets/{arc-CqwzD3ok.js → arc-C7hjaa7g.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-BfA-P0-O.js → architectureDiagram-3BPJPVTR-pm9KtMZY.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-DNTzkXRp.js → blockDiagram-GPEHLZMM-CApElKsU.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-D5axQoXQ.js → c4Diagram-AAUBKEIU-BeDe0-9N.js} +1 -1
- package/web-shell/assets/channel-BNf1dW-j.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-CV0P48eN.js → chunk-2J33WTMH-DJEkmLdl.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-CghJNPCS.js → chunk-4BX2VUAB-DXX8gdpe.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-BrD-776x.js → chunk-55IACEB6-DORmk1kQ.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-DLKkI5Yu.js → chunk-727SXJPM-DWmO4mCZ.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-C0HWhZNK.js → chunk-AQP2D5EJ-C7LRaYw2.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-Cg6PsiNL.js → chunk-FMBD7UC4-CCdXgyC5.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-B1pCuSlf.js → chunk-ND2GUHAM-SyL_xvWc.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-CkE8llI2.js → chunk-QZHKN3VN-BzOuCKxa.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-uOIGlzgi.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-uOIGlzgi.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-Btr-W-vN.js → cose-bilkent-S5V4N54A-BMPWyDKc.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-CAhjVa5L.js → dagre-BM42HDAG-B_GnPWik.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-eUQodUXw.js → diagram-2AECGRRQ-fJqMc3S_.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-BiPKbH6E.js → diagram-5GNKFQAL-ximV3O9D.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-DxuwR-Pu.js → diagram-KO2AKTUF-2vVyjzqw.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-nz9SQ3Az.js → diagram-LMA3HP47-Dckcx1sT.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-UBbYk-Jq.js → diagram-OG6HWLK6-BAVv47ga.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-BLpRQmgi.js → erDiagram-TEJ5UH35-Bn3nf5J0.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-C5Qqg1hx.js → flowDiagram-I6XJVG4X-BIbGF9JT.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-BMdf3kjL.js → ganttDiagram-6RSMTGT7-CDbhb3AH.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-D9qG7BKD.js → gitGraphDiagram-PVQCEYII-CbKG1a_w.js} +1 -1
- package/web-shell/assets/index-CnE2ur2L.js +779 -0
- package/web-shell/assets/index-hSKXrlSE.css +5 -0
- package/web-shell/assets/{infoDiagram-5YYISTIA-CtDBPJM8.js → infoDiagram-5YYISTIA-DUFxTy8m.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-BQaS7H3_.js → ishikawaDiagram-YF4QCWOH-D69hrBG8.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-CEEujCNX.js → journeyDiagram-JHISSGLW-DsvEw51Y.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-B3QqyyNi.js → kanban-definition-UN3LZRKU-lFFjZEYd.js} +1 -1
- package/web-shell/assets/{linear-DC2Azd_6.js → linear-Bo5bWzvo.js} +1 -1
- package/web-shell/assets/{mermaid.core-DL5PRmh-.js → mermaid.core-C_HKMJx5.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-DGlkd_fb.js → mindmap-definition-RKZ34NQL-DlV-NUTs.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-Dew4R8DT.js → pieDiagram-4H26LBE5-B2e6FH2a.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-Bk02Tejc.js → quadrantDiagram-W4KKPZXB-D75kSk-b.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-BkWJE-6M.js → requirementDiagram-4Y6WPE33-CQ6xakhM.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-BM9bZAuM.js → sankeyDiagram-5OEKKPKP-J_XTKrcY.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-IaE2rOTu.js → sequenceDiagram-3UESZ5HK-D7jTcBtf.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-CQH-ENFJ.js → stateDiagram-AJRCARHV-CrlM_OT3.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-Bs4TK_84.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-DVH5FaeF.js → timeline-definition-PNZ67QCA-5oZi76Ef.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-ChT6J8JT.js → vennDiagram-CIIHVFJN-DO5YptPK.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-D9W5AEjE.js → wardley-L42UT6IY-4t1eJDvM.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-cNYKmuIA.js → wardleyDiagram-YWT4CUSO-DKZc661S.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-BleLm4BJ.js → xychartDiagram-2RQKCTM6-su9hp08G.js} +1 -1
- package/web-shell/index.html +2 -2
- package/web-shell/assets/channel-EyH7BS8F.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-CPWvwYMM.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CPWvwYMM.js +0 -1
- package/web-shell/assets/index-CgttHpqB.js +0 -763
- package/web-shell/assets/index-sVELoa_9.css +0 -5
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CFqBlFdE.js +0 -1
|
@@ -3,10 +3,7 @@
|
|
|
3
3
|
import {
|
|
4
4
|
isValidSessionId,
|
|
5
5
|
validateAuthMethod
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import {
|
|
8
|
-
contextCommand
|
|
9
|
-
} from "./chunk-7YLLBKDB.js";
|
|
6
|
+
} from "./chunk-ZOSL7K3L.js";
|
|
10
7
|
import {
|
|
11
8
|
VSCODE_SHIFT_ENTER_SEQUENCE,
|
|
12
9
|
calculateCost,
|
|
@@ -18,25 +15,32 @@ import {
|
|
|
18
15
|
levelLabel,
|
|
19
16
|
useKeypress,
|
|
20
17
|
writeOsc52
|
|
21
|
-
} from "./chunk-
|
|
22
|
-
import {
|
|
23
|
-
isTerminalGoalStatusKind
|
|
24
|
-
} from "./chunk-KSPVDFE4.js";
|
|
18
|
+
} from "./chunk-GPLKAQUX.js";
|
|
25
19
|
import {
|
|
26
20
|
Text
|
|
27
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-MZWODTEA.js";
|
|
22
|
+
import {
|
|
23
|
+
isKittyProtocolEnabled
|
|
24
|
+
} from "./chunk-JZSY4WP3.js";
|
|
25
|
+
import {
|
|
26
|
+
contextCommand
|
|
27
|
+
} from "./chunk-FCEHOKYP.js";
|
|
28
|
+
import {
|
|
29
|
+
getInstallationInfo,
|
|
30
|
+
rollbackStandaloneUpdate
|
|
31
|
+
} from "./chunk-A3ZQMFO6.js";
|
|
32
|
+
import {
|
|
33
|
+
isTerminalGoalStatusKind
|
|
34
|
+
} from "./chunk-SAIILPQ3.js";
|
|
28
35
|
import {
|
|
29
36
|
require_react
|
|
30
37
|
} from "./chunk-KYMBIKIW.js";
|
|
31
38
|
import {
|
|
32
39
|
themeManager
|
|
33
40
|
} from "./chunk-PC4ZXHU2.js";
|
|
34
|
-
import {
|
|
35
|
-
isKittyProtocolEnabled
|
|
36
|
-
} from "./chunk-JZSY4WP3.js";
|
|
37
41
|
import {
|
|
38
42
|
getErrorMessage as getErrorMessage2
|
|
39
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-2X3ZVAAT.js";
|
|
40
44
|
import {
|
|
41
45
|
GITHUB_WORKFLOW_PATHS,
|
|
42
46
|
INSIGHT_CSS,
|
|
@@ -49,19 +53,16 @@ import {
|
|
|
49
53
|
toJson,
|
|
50
54
|
toJsonl,
|
|
51
55
|
toMarkdown
|
|
52
|
-
} from "./chunk-
|
|
53
|
-
import {
|
|
54
|
-
require_undici
|
|
55
|
-
} from "./chunk-54YZOP7P.js";
|
|
56
|
+
} from "./chunk-AJ3CEJRJ.js";
|
|
56
57
|
import {
|
|
57
58
|
stripUnsafeCharacters,
|
|
58
59
|
toCodePoints
|
|
59
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-7VCI24VZ.js";
|
|
60
61
|
import {
|
|
61
62
|
getExtendedSystemInfo,
|
|
62
63
|
getGitVersion,
|
|
63
64
|
getNpmVersion
|
|
64
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-2D5Q33PT.js";
|
|
65
66
|
import {
|
|
66
67
|
formatDuration,
|
|
67
68
|
formatMemoryUsage,
|
|
@@ -70,7 +71,7 @@ import {
|
|
|
70
71
|
import {
|
|
71
72
|
isInlineModelOverrideAllowed,
|
|
72
73
|
parseAcpModelOption
|
|
73
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-QM4FKX7H.js";
|
|
74
75
|
import {
|
|
75
76
|
formatUnsupportedVoiceModelMessage,
|
|
76
77
|
getVoiceSettingsScope,
|
|
@@ -78,7 +79,7 @@ import {
|
|
|
78
79
|
isVoiceEnabled,
|
|
79
80
|
readVoiceMode,
|
|
80
81
|
readVoiceModel
|
|
81
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-ILFQAFWH.js";
|
|
82
83
|
import {
|
|
83
84
|
OUTPUT_LANGUAGE_AUTO,
|
|
84
85
|
getAllSettingKeys,
|
|
@@ -90,7 +91,7 @@ import {
|
|
|
90
91
|
resolveOutputLanguage,
|
|
91
92
|
validateSettingValue,
|
|
92
93
|
writeOutputLanguageAndRegisterPath
|
|
93
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-O6T7PBUM.js";
|
|
94
95
|
import {
|
|
95
96
|
SUPPORTED_LANGUAGES,
|
|
96
97
|
getCurrentLanguage,
|
|
@@ -98,11 +99,11 @@ import {
|
|
|
98
99
|
resolveSupportedLanguage,
|
|
99
100
|
setLanguageAsync,
|
|
100
101
|
t
|
|
101
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-2MJAXDFK.js";
|
|
102
103
|
import {
|
|
103
104
|
isFolderTrustEnabled,
|
|
104
105
|
loadTrustedFolders
|
|
105
|
-
} from "./chunk-
|
|
106
|
+
} from "./chunk-WKBA74DD.js";
|
|
106
107
|
import {
|
|
107
108
|
require_strip_json_comments
|
|
108
109
|
} from "./chunk-QYUE6W3T.js";
|
|
@@ -118,7 +119,6 @@ import {
|
|
|
118
119
|
SESSION_TITLE_MAX_LENGTH,
|
|
119
120
|
SessionService,
|
|
120
121
|
ShellExecutionService,
|
|
121
|
-
So,
|
|
122
122
|
appendToLastTextPart,
|
|
123
123
|
buildBackgroundEntryLabel,
|
|
124
124
|
buildBareRememberPrompt,
|
|
@@ -150,7 +150,6 @@ import {
|
|
|
150
150
|
glob,
|
|
151
151
|
hookEventSupportsMatcher,
|
|
152
152
|
ideContextStore,
|
|
153
|
-
isGitRepository,
|
|
154
153
|
isImageCapable,
|
|
155
154
|
isSuccessStatus,
|
|
156
155
|
isTerminalStatus,
|
|
@@ -176,7 +175,7 @@ import {
|
|
|
176
175
|
stripStartupContext,
|
|
177
176
|
tryGenerateSessionTitle,
|
|
178
177
|
unregisterGoalHook
|
|
179
|
-
} from "./chunk-
|
|
178
|
+
} from "./chunk-ZWFS7YCB.js";
|
|
180
179
|
import {
|
|
181
180
|
external_exports
|
|
182
181
|
} from "./chunk-K5PGHDBN.js";
|
|
@@ -207,7 +206,7 @@ import {
|
|
|
207
206
|
recordSkillInvocation,
|
|
208
207
|
resolveOpenAILogDir,
|
|
209
208
|
uiTelemetryService
|
|
210
|
-
} from "./chunk-
|
|
209
|
+
} from "./chunk-N33JAGJ7.js";
|
|
211
210
|
import {
|
|
212
211
|
getAutoMemoryRoot
|
|
213
212
|
} from "./chunk-4KJ2BPIT.js";
|
|
@@ -234,7 +233,7 @@ import {
|
|
|
234
233
|
isCpuProfileRecording,
|
|
235
234
|
startCpuProfile,
|
|
236
235
|
stopCpuProfile
|
|
237
|
-
} from "./chunk-
|
|
236
|
+
} from "./chunk-TPTG52XG.js";
|
|
238
237
|
import {
|
|
239
238
|
init_esbuild_shims
|
|
240
239
|
} from "./chunk-A4BMJM77.js";
|
|
@@ -281,7 +280,7 @@ var isBtwCommand = /* @__PURE__ */ __name((query) => {
|
|
|
281
280
|
}, "isBtwCommand");
|
|
282
281
|
var debugLogger = createDebugLogger("COMMAND_UTILS");
|
|
283
282
|
var copyToClipboard = /* @__PURE__ */ __name(async (text) => {
|
|
284
|
-
const run = /* @__PURE__ */ __name((cmd, args, options) => new Promise((
|
|
283
|
+
const run = /* @__PURE__ */ __name((cmd, args, options) => new Promise((resolve4, reject) => {
|
|
285
284
|
const child = options ? spawn(cmd, args, options) : spawn(cmd, args);
|
|
286
285
|
let stderr = "";
|
|
287
286
|
if (child.stderr) {
|
|
@@ -289,7 +288,7 @@ var copyToClipboard = /* @__PURE__ */ __name(async (text) => {
|
|
|
289
288
|
}
|
|
290
289
|
child.on("error", reject);
|
|
291
290
|
child.on("close", (code) => {
|
|
292
|
-
if (code === 0) return
|
|
291
|
+
if (code === 0) return resolve4();
|
|
293
292
|
const errorMsg = stderr.trim();
|
|
294
293
|
reject(
|
|
295
294
|
new Error(
|
|
@@ -455,6 +454,7 @@ init_esbuild_shims();
|
|
|
455
454
|
|
|
456
455
|
// packages/cli/src/utils/commands.ts
|
|
457
456
|
init_esbuild_shims();
|
|
457
|
+
var MAX_STACKED_SKILLS = 5;
|
|
458
458
|
var parseSlashCommand = /* @__PURE__ */ __name((query, commands) => {
|
|
459
459
|
const trimmed = query.trim();
|
|
460
460
|
const commandText = trimmed.substring(1).trim();
|
|
@@ -490,6 +490,55 @@ var parseSlashCommand = /* @__PURE__ */ __name((query, commands) => {
|
|
|
490
490
|
const args = commandToExecute ? commandText.slice(argsStart).trim() : parts.slice(pathIndex).join(" ");
|
|
491
491
|
return { commandToExecute, args, canonicalPath };
|
|
492
492
|
}, "parseSlashCommand");
|
|
493
|
+
var parseStackedSlashCommands = /* @__PURE__ */ __name((query, commands) => {
|
|
494
|
+
const trimmed = query.trim();
|
|
495
|
+
if (!trimmed.startsWith("/")) {
|
|
496
|
+
return { skills: [], remainingText: trimmed, exceededMax: false };
|
|
497
|
+
}
|
|
498
|
+
const commandText = trimmed.substring(1);
|
|
499
|
+
const skills = [];
|
|
500
|
+
let pos = 0;
|
|
501
|
+
let restPos = 0;
|
|
502
|
+
let exceededMax = false;
|
|
503
|
+
while (pos < commandText.length) {
|
|
504
|
+
while (pos < commandText.length && /\s/.test(commandText[pos])) pos++;
|
|
505
|
+
if (pos >= commandText.length) {
|
|
506
|
+
restPos = pos;
|
|
507
|
+
break;
|
|
508
|
+
}
|
|
509
|
+
const tokenStart = pos;
|
|
510
|
+
while (pos < commandText.length && !/\s/.test(commandText[pos])) pos++;
|
|
511
|
+
const token = commandText.slice(tokenStart, pos);
|
|
512
|
+
if (skills.length === 0) {
|
|
513
|
+
if (token.startsWith("/")) break;
|
|
514
|
+
const cmd2 = findCommandByName(token, commands);
|
|
515
|
+
if (!cmd2 || cmd2.kind !== "skill" /* SKILL */) break;
|
|
516
|
+
skills.push(cmd2);
|
|
517
|
+
restPos = pos;
|
|
518
|
+
continue;
|
|
519
|
+
}
|
|
520
|
+
if (!token.startsWith("/")) break;
|
|
521
|
+
const name = token.substring(1);
|
|
522
|
+
if (!name) break;
|
|
523
|
+
const cmd = findCommandByName(name, commands);
|
|
524
|
+
if (!cmd || cmd.kind !== "skill" /* SKILL */) break;
|
|
525
|
+
if (skills.length >= MAX_STACKED_SKILLS) {
|
|
526
|
+
exceededMax = true;
|
|
527
|
+
break;
|
|
528
|
+
}
|
|
529
|
+
skills.push(cmd);
|
|
530
|
+
restPos = pos;
|
|
531
|
+
}
|
|
532
|
+
if (skills.length < 2) {
|
|
533
|
+
return { skills: [], remainingText: trimmed, exceededMax: false };
|
|
534
|
+
}
|
|
535
|
+
const afterSkills = commandText.slice(restPos).trim();
|
|
536
|
+
return { skills, remainingText: afterSkills, exceededMax };
|
|
537
|
+
}, "parseStackedSlashCommands");
|
|
538
|
+
function findCommandByName(name, commands) {
|
|
539
|
+
return commands.find((cmd) => cmd.name === name) ?? commands.find((cmd) => cmd.altNames?.includes(name));
|
|
540
|
+
}
|
|
541
|
+
__name(findCommandByName, "findCommandByName");
|
|
493
542
|
|
|
494
543
|
// packages/cli/src/services/CommandService.ts
|
|
495
544
|
init_esbuild_shims();
|
|
@@ -4355,7 +4404,7 @@ function writeMemoryHeapSnapshot({
|
|
|
4355
4404
|
}
|
|
4356
4405
|
__name(writeMemoryHeapSnapshot, "writeMemoryHeapSnapshot");
|
|
4357
4406
|
function defaultWait(ms) {
|
|
4358
|
-
return new Promise((
|
|
4407
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
4359
4408
|
}
|
|
4360
4409
|
__name(defaultWait, "defaultWait");
|
|
4361
4410
|
function normalizeSampleCount(sampleCount) {
|
|
@@ -4560,925 +4609,6 @@ function formatMemoryDiagnostics(diagnostics) {
|
|
|
4560
4609
|
}
|
|
4561
4610
|
__name(formatMemoryDiagnostics, "formatMemoryDiagnostics");
|
|
4562
4611
|
|
|
4563
|
-
// packages/cli/src/utils/standalone-update.ts
|
|
4564
|
-
init_esbuild_shims();
|
|
4565
|
-
var import_undici = __toESM(require_undici(), 1);
|
|
4566
|
-
import { createHash } from "node:crypto";
|
|
4567
|
-
import * as fs5 from "node:fs";
|
|
4568
|
-
import * as os3 from "node:os";
|
|
4569
|
-
import * as path5 from "node:path";
|
|
4570
|
-
import { Readable, Transform } from "node:stream";
|
|
4571
|
-
import { spawn as spawn2, execFile } from "node:child_process";
|
|
4572
|
-
import { pipeline } from "node:stream/promises";
|
|
4573
|
-
|
|
4574
|
-
// packages/cli/src/utils/standalone-update-verify.ts
|
|
4575
|
-
init_esbuild_shims();
|
|
4576
|
-
import { createPublicKey, verify } from "node:crypto";
|
|
4577
|
-
var RELEASE_PUBLIC_KEY_DER_B64 = "MCowBQYDK2VwAyEAr9WRFLDauibZQKCe1oKfuFZn6zRMaEkD5+KVqN6mKM4=";
|
|
4578
|
-
function verifySignature(sha256sumsContent, signatureBase64) {
|
|
4579
|
-
const key = createPublicKey({
|
|
4580
|
-
key: Buffer.from(RELEASE_PUBLIC_KEY_DER_B64, "base64"),
|
|
4581
|
-
format: "der",
|
|
4582
|
-
type: "spki"
|
|
4583
|
-
});
|
|
4584
|
-
const signature = Buffer.from(signatureBase64, "base64");
|
|
4585
|
-
if (signature.length !== 64) {
|
|
4586
|
-
throw new Error(
|
|
4587
|
-
`Invalid signature length: expected 64 bytes, got ${signature.length}`
|
|
4588
|
-
);
|
|
4589
|
-
}
|
|
4590
|
-
const valid = verify(null, Buffer.from(sha256sumsContent), key, signature);
|
|
4591
|
-
if (!valid) {
|
|
4592
|
-
throw new Error(
|
|
4593
|
-
"SHA256SUMS signature verification failed \u2014 possible tampering detected"
|
|
4594
|
-
);
|
|
4595
|
-
}
|
|
4596
|
-
}
|
|
4597
|
-
__name(verifySignature, "verifySignature");
|
|
4598
|
-
|
|
4599
|
-
// packages/cli/src/utils/standalone-update.ts
|
|
4600
|
-
var debugLogger6 = createDebugLogger("STANDALONE_UPDATE");
|
|
4601
|
-
var OSS_BASE = "https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/releases/qwen-code";
|
|
4602
|
-
var GITHUB_BASE = "https://github.com/QwenLM/qwen-code/releases/download";
|
|
4603
|
-
var FETCH_TIMEOUT_MS = 3e4;
|
|
4604
|
-
var ARCHIVE_TIMEOUT_MS = 3e5;
|
|
4605
|
-
var VALID_TARGETS = /* @__PURE__ */ new Set([
|
|
4606
|
-
"darwin-arm64",
|
|
4607
|
-
"darwin-x64",
|
|
4608
|
-
"linux-arm64",
|
|
4609
|
-
"linux-x64",
|
|
4610
|
-
"win-x64"
|
|
4611
|
-
]);
|
|
4612
|
-
var SEMVER_RE = /^v?\d+\.\d+\.\d+(-[\w.]+)?$/;
|
|
4613
|
-
function normalizeVersion(version) {
|
|
4614
|
-
if (!SEMVER_RE.test(version)) {
|
|
4615
|
-
throw new Error(`Invalid version format: ${version}`);
|
|
4616
|
-
}
|
|
4617
|
-
return version.startsWith("v") ? version : `v${version}`;
|
|
4618
|
-
}
|
|
4619
|
-
__name(normalizeVersion, "normalizeVersion");
|
|
4620
|
-
function validateTarget(target) {
|
|
4621
|
-
if (!VALID_TARGETS.has(target)) {
|
|
4622
|
-
throw new Error(`Unknown target: ${target}`);
|
|
4623
|
-
}
|
|
4624
|
-
}
|
|
4625
|
-
__name(validateTarget, "validateTarget");
|
|
4626
|
-
function archiveFilename(target) {
|
|
4627
|
-
const ext = target.startsWith("win") ? "zip" : "tar.gz";
|
|
4628
|
-
return `qwen-code-${target}.${ext}`;
|
|
4629
|
-
}
|
|
4630
|
-
__name(archiveFilename, "archiveFilename");
|
|
4631
|
-
function escapePS(s) {
|
|
4632
|
-
return s.replace(/'/g, "''");
|
|
4633
|
-
}
|
|
4634
|
-
__name(escapePS, "escapePS");
|
|
4635
|
-
async function tryFetch(url, timeoutMs = FETCH_TIMEOUT_MS) {
|
|
4636
|
-
try {
|
|
4637
|
-
const res = await (0, import_undici.fetch)(url, {
|
|
4638
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
4639
|
-
});
|
|
4640
|
-
if (res.ok) return { response: res };
|
|
4641
|
-
await res.body?.cancel().catch(() => {
|
|
4642
|
-
});
|
|
4643
|
-
return { error: new Error(`HTTP ${res.status} ${res.statusText}`) };
|
|
4644
|
-
} catch (err) {
|
|
4645
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
4646
|
-
debugLogger6.debug(`Fetch failed for ${url}: ${error.message}`);
|
|
4647
|
-
return { error };
|
|
4648
|
-
}
|
|
4649
|
-
}
|
|
4650
|
-
__name(tryFetch, "tryFetch");
|
|
4651
|
-
async function downloadWithFallback(versionPath, filename, timeoutMs = FETCH_TIMEOUT_MS) {
|
|
4652
|
-
const ossUrl = `${OSS_BASE}/${versionPath}/${filename}`;
|
|
4653
|
-
const ossResult = await tryFetch(ossUrl, timeoutMs);
|
|
4654
|
-
if (ossResult.response) return ossResult.response;
|
|
4655
|
-
const ghUrl = `${GITHUB_BASE}/${versionPath}/${filename}`;
|
|
4656
|
-
const ghResult = await tryFetch(ghUrl, timeoutMs);
|
|
4657
|
-
if (ghResult.response) return ghResult.response;
|
|
4658
|
-
throw new Error(
|
|
4659
|
-
`Failed to download ${filename}: OSS (${ossResult.error?.message ?? "unknown"}), GitHub (${ghResult.error?.message ?? "unknown"})`
|
|
4660
|
-
);
|
|
4661
|
-
}
|
|
4662
|
-
__name(downloadWithFallback, "downloadWithFallback");
|
|
4663
|
-
async function verifyChecksum(actualHash, filename, versionPath) {
|
|
4664
|
-
const response = await downloadWithFallback(versionPath, "SHA256SUMS");
|
|
4665
|
-
const text = await response.text();
|
|
4666
|
-
const requireSig = process.env["QWEN_REQUIRE_SIGNATURE"] === "1";
|
|
4667
|
-
let sigResponse;
|
|
4668
|
-
try {
|
|
4669
|
-
sigResponse = await downloadWithFallback(versionPath, "SHA256SUMS.sig");
|
|
4670
|
-
} catch (err) {
|
|
4671
|
-
debugLogger6.debug("SHA256SUMS.sig not available:", err);
|
|
4672
|
-
}
|
|
4673
|
-
if (sigResponse) {
|
|
4674
|
-
const sigContent = await sigResponse.text();
|
|
4675
|
-
verifySignature(text, sigContent.trim());
|
|
4676
|
-
debugLogger6.info("SHA256SUMS signature verified.");
|
|
4677
|
-
} else if (requireSig) {
|
|
4678
|
-
throw new Error(
|
|
4679
|
-
"SHA256SUMS.sig not found and QWEN_REQUIRE_SIGNATURE=1 is set"
|
|
4680
|
-
);
|
|
4681
|
-
} else {
|
|
4682
|
-
debugLogger6.warn(
|
|
4683
|
-
"SHA256SUMS.sig not available \u2014 update integrity relies on SHA256 checksum only. Set QWEN_REQUIRE_SIGNATURE=1 to enforce signature verification."
|
|
4684
|
-
);
|
|
4685
|
-
}
|
|
4686
|
-
const expectedLine = text.split("\n").find((line) => {
|
|
4687
|
-
const parts = line.trim().split(/\s+/);
|
|
4688
|
-
if (parts.length < 2) return false;
|
|
4689
|
-
const name = parts[parts.length - 1].replace(/^\*/, "");
|
|
4690
|
-
return name === filename;
|
|
4691
|
-
});
|
|
4692
|
-
if (!expectedLine) {
|
|
4693
|
-
throw new Error(`No checksum found for ${filename} in SHA256SUMS`);
|
|
4694
|
-
}
|
|
4695
|
-
const expectedHash = expectedLine.trim().split(/\s+/)[0];
|
|
4696
|
-
if (actualHash !== expectedHash) {
|
|
4697
|
-
throw new Error(
|
|
4698
|
-
`Checksum mismatch: expected ${expectedHash}, got ${actualHash}`
|
|
4699
|
-
);
|
|
4700
|
-
}
|
|
4701
|
-
}
|
|
4702
|
-
__name(verifyChecksum, "verifyChecksum");
|
|
4703
|
-
var MAX_DOWNLOAD_BYTES = 512 * 1024 * 1024;
|
|
4704
|
-
async function downloadToFile(versionPath, filename, destPath) {
|
|
4705
|
-
const response = await downloadWithFallback(
|
|
4706
|
-
versionPath,
|
|
4707
|
-
filename,
|
|
4708
|
-
ARCHIVE_TIMEOUT_MS
|
|
4709
|
-
);
|
|
4710
|
-
const body = response.body;
|
|
4711
|
-
if (!body) throw new Error("Empty response body");
|
|
4712
|
-
const contentLength = response.headers.get("content-length");
|
|
4713
|
-
if (contentLength && parseInt(contentLength, 10) > MAX_DOWNLOAD_BYTES) {
|
|
4714
|
-
await body.cancel().catch(() => {
|
|
4715
|
-
});
|
|
4716
|
-
throw new Error(
|
|
4717
|
-
`Download too large: ${contentLength} bytes exceeds ${MAX_DOWNLOAD_BYTES} limit`
|
|
4718
|
-
);
|
|
4719
|
-
}
|
|
4720
|
-
const hash = createHash("sha256");
|
|
4721
|
-
let bytesWritten = 0;
|
|
4722
|
-
const dest = fs5.createWriteStream(destPath);
|
|
4723
|
-
const sizeGuard = new Transform({
|
|
4724
|
-
transform(chunk, _encoding, callback) {
|
|
4725
|
-
bytesWritten += chunk.length;
|
|
4726
|
-
if (bytesWritten > MAX_DOWNLOAD_BYTES) {
|
|
4727
|
-
callback(
|
|
4728
|
-
new Error(`Download exceeded ${MAX_DOWNLOAD_BYTES} byte limit`)
|
|
4729
|
-
);
|
|
4730
|
-
} else {
|
|
4731
|
-
hash.update(chunk);
|
|
4732
|
-
callback(null, chunk);
|
|
4733
|
-
}
|
|
4734
|
-
}
|
|
4735
|
-
});
|
|
4736
|
-
await pipeline(Readable.fromWeb(body), sizeGuard, dest);
|
|
4737
|
-
return hash.digest("hex");
|
|
4738
|
-
}
|
|
4739
|
-
__name(downloadToFile, "downloadToFile");
|
|
4740
|
-
function validateExtractedPaths(resolvedDest) {
|
|
4741
|
-
const entries = fs5.readdirSync(resolvedDest, {
|
|
4742
|
-
recursive: true,
|
|
4743
|
-
withFileTypes: true
|
|
4744
|
-
});
|
|
4745
|
-
for (const entry of entries) {
|
|
4746
|
-
const fullPath = path5.join(
|
|
4747
|
-
String(entry.parentPath || entry.path),
|
|
4748
|
-
entry.name
|
|
4749
|
-
);
|
|
4750
|
-
const resolved = fs5.realpathSync(fullPath);
|
|
4751
|
-
if (!resolved.startsWith(resolvedDest + path5.sep) && resolved !== resolvedDest) {
|
|
4752
|
-
fs5.rmSync(resolvedDest, { recursive: true, force: true });
|
|
4753
|
-
throw new Error(
|
|
4754
|
-
`Path traversal detected in archive: ${entry.name} resolves to ${resolved}`
|
|
4755
|
-
);
|
|
4756
|
-
}
|
|
4757
|
-
}
|
|
4758
|
-
}
|
|
4759
|
-
__name(validateExtractedPaths, "validateExtractedPaths");
|
|
4760
|
-
function isSafeTarEntryPath(entryPath) {
|
|
4761
|
-
if (entryPath.length === 0) return false;
|
|
4762
|
-
if (path5.posix.isAbsolute(entryPath) || path5.win32.isAbsolute(entryPath)) {
|
|
4763
|
-
return false;
|
|
4764
|
-
}
|
|
4765
|
-
return !entryPath.split(/[\\/]+/).includes("..");
|
|
4766
|
-
}
|
|
4767
|
-
__name(isSafeTarEntryPath, "isSafeTarEntryPath");
|
|
4768
|
-
async function extractArchive(archivePath, destDir, target) {
|
|
4769
|
-
fs5.mkdirSync(destDir, { recursive: true });
|
|
4770
|
-
if (target.startsWith("win")) {
|
|
4771
|
-
await new Promise((resolve5, reject) => {
|
|
4772
|
-
const ps = spawn2(
|
|
4773
|
-
"powershell.exe",
|
|
4774
|
-
[
|
|
4775
|
-
"-NoProfile",
|
|
4776
|
-
"-Command",
|
|
4777
|
-
`Expand-Archive -Path '${escapePS(archivePath)}' -DestinationPath '${escapePS(destDir)}' -Force`
|
|
4778
|
-
],
|
|
4779
|
-
{ stdio: "ignore" }
|
|
4780
|
-
);
|
|
4781
|
-
ps.on(
|
|
4782
|
-
"close",
|
|
4783
|
-
(code) => code === 0 ? resolve5() : reject(new Error(`Expand-Archive exited with code ${code}`))
|
|
4784
|
-
);
|
|
4785
|
-
ps.on("error", reject);
|
|
4786
|
-
});
|
|
4787
|
-
const resolvedDest = fs5.realpathSync(destDir);
|
|
4788
|
-
validateExtractedPaths(resolvedDest);
|
|
4789
|
-
} else {
|
|
4790
|
-
const resolvedDest = path5.resolve(destDir);
|
|
4791
|
-
await So({
|
|
4792
|
-
file: archivePath,
|
|
4793
|
-
cwd: destDir,
|
|
4794
|
-
preservePaths: false,
|
|
4795
|
-
filter: /* @__PURE__ */ __name((p, entry) => {
|
|
4796
|
-
if (!isSafeTarEntryPath(p)) return false;
|
|
4797
|
-
if ("type" in entry && entry.type === "SymbolicLink" && "linkpath" in entry) {
|
|
4798
|
-
const linkTarget = path5.resolve(
|
|
4799
|
-
resolvedDest,
|
|
4800
|
-
path5.dirname(p),
|
|
4801
|
-
String(entry.linkpath)
|
|
4802
|
-
);
|
|
4803
|
-
if (!linkTarget.startsWith(resolvedDest + path5.sep) && linkTarget !== resolvedDest) {
|
|
4804
|
-
return false;
|
|
4805
|
-
}
|
|
4806
|
-
}
|
|
4807
|
-
return true;
|
|
4808
|
-
}, "filter")
|
|
4809
|
-
});
|
|
4810
|
-
validateExtractedPaths(fs5.realpathSync(destDir));
|
|
4811
|
-
}
|
|
4812
|
-
}
|
|
4813
|
-
__name(extractArchive, "extractArchive");
|
|
4814
|
-
function spawnAndCapture(command, args, timeoutMs) {
|
|
4815
|
-
return new Promise((resolve5, reject) => {
|
|
4816
|
-
let settled = false;
|
|
4817
|
-
const child = execFile(
|
|
4818
|
-
command,
|
|
4819
|
-
args,
|
|
4820
|
-
{ timeout: timeoutMs },
|
|
4821
|
-
(err, out, stderr) => {
|
|
4822
|
-
if (settled) return;
|
|
4823
|
-
settled = true;
|
|
4824
|
-
if (err && ("killed" in err && err.killed || "signal" in err && err.signal)) {
|
|
4825
|
-
reject(new Error("Smoke test timed out"));
|
|
4826
|
-
return;
|
|
4827
|
-
}
|
|
4828
|
-
if (err) {
|
|
4829
|
-
const exitCode = "code" in err && typeof err.code === "number" ? err.code : 1;
|
|
4830
|
-
resolve5({ exitCode, stdout: out || "", stderr: stderr || "" });
|
|
4831
|
-
return;
|
|
4832
|
-
}
|
|
4833
|
-
resolve5({ exitCode: 0, stdout: out || "", stderr: stderr || "" });
|
|
4834
|
-
}
|
|
4835
|
-
);
|
|
4836
|
-
child.on("error", (e) => {
|
|
4837
|
-
if (settled) return;
|
|
4838
|
-
settled = true;
|
|
4839
|
-
reject(e);
|
|
4840
|
-
});
|
|
4841
|
-
});
|
|
4842
|
-
}
|
|
4843
|
-
__name(spawnAndCapture, "spawnAndCapture");
|
|
4844
|
-
async function smokeTest(newInstallDir, target) {
|
|
4845
|
-
const resolvedInstallDir = path5.resolve(newInstallDir);
|
|
4846
|
-
const nodeBin = target.startsWith("win") ? path5.join(resolvedInstallDir, "node", "node.exe") : path5.join(resolvedInstallDir, "node", "bin", "node");
|
|
4847
|
-
const cliBin = path5.join(resolvedInstallDir, "lib", "cli.js");
|
|
4848
|
-
if (!fs5.existsSync(nodeBin)) {
|
|
4849
|
-
throw new Error(`Smoke test failed: node binary not found at ${nodeBin}`);
|
|
4850
|
-
}
|
|
4851
|
-
if (!fs5.existsSync(cliBin)) {
|
|
4852
|
-
throw new Error(`Smoke test failed: cli.js not found at ${cliBin}`);
|
|
4853
|
-
}
|
|
4854
|
-
const { exitCode, stdout, stderr } = await spawnAndCapture(
|
|
4855
|
-
nodeBin,
|
|
4856
|
-
[cliBin, "--version"],
|
|
4857
|
-
1e4
|
|
4858
|
-
);
|
|
4859
|
-
if (exitCode !== 0) {
|
|
4860
|
-
const detail = stderr.trim() ? `: ${stderr.trim()}` : "";
|
|
4861
|
-
throw new Error(
|
|
4862
|
-
`Smoke test failed: new binary exited with code ${exitCode}${detail}`
|
|
4863
|
-
);
|
|
4864
|
-
}
|
|
4865
|
-
const version = stdout.trim();
|
|
4866
|
-
if (!SEMVER_RE.test(version)) {
|
|
4867
|
-
throw new Error(
|
|
4868
|
-
`Smoke test failed: unexpected version output "${version}"`
|
|
4869
|
-
);
|
|
4870
|
-
}
|
|
4871
|
-
debugLogger6.info(`Smoke test passed: ${version}`);
|
|
4872
|
-
}
|
|
4873
|
-
__name(smokeTest, "smokeTest");
|
|
4874
|
-
function acquireLock(lockPath) {
|
|
4875
|
-
try {
|
|
4876
|
-
fs5.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
4877
|
-
return true;
|
|
4878
|
-
} catch {
|
|
4879
|
-
try {
|
|
4880
|
-
const pidStr = fs5.readFileSync(lockPath, "utf-8").trim();
|
|
4881
|
-
const pid = parseInt(pidStr, 10);
|
|
4882
|
-
if (Number.isNaN(pid) || !isProcessAlive(pid)) {
|
|
4883
|
-
fs5.unlinkSync(lockPath);
|
|
4884
|
-
try {
|
|
4885
|
-
fs5.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
|
|
4886
|
-
return true;
|
|
4887
|
-
} catch {
|
|
4888
|
-
return false;
|
|
4889
|
-
}
|
|
4890
|
-
}
|
|
4891
|
-
} catch {
|
|
4892
|
-
}
|
|
4893
|
-
return false;
|
|
4894
|
-
}
|
|
4895
|
-
}
|
|
4896
|
-
__name(acquireLock, "acquireLock");
|
|
4897
|
-
function releaseLock(lockPath) {
|
|
4898
|
-
try {
|
|
4899
|
-
fs5.unlinkSync(lockPath);
|
|
4900
|
-
} catch {
|
|
4901
|
-
}
|
|
4902
|
-
}
|
|
4903
|
-
__name(releaseLock, "releaseLock");
|
|
4904
|
-
function cleanupEmptyStandaloneDir(standaloneDir) {
|
|
4905
|
-
const manifestPath = path5.join(standaloneDir, "manifest.json");
|
|
4906
|
-
if (fs5.existsSync(standaloneDir) && !fs5.existsSync(manifestPath)) {
|
|
4907
|
-
fs5.rmSync(standaloneDir, { recursive: true, force: true });
|
|
4908
|
-
}
|
|
4909
|
-
}
|
|
4910
|
-
__name(cleanupEmptyStandaloneDir, "cleanupEmptyStandaloneDir");
|
|
4911
|
-
var UNSAFE_SHELL_CHARS = /["`$\\;\n\r]/;
|
|
4912
|
-
var UNSAFE_CMD_CHARS = /[&|<>^%!"`\n\r]/;
|
|
4913
|
-
function assertSafeForShellEmbed(p, context) {
|
|
4914
|
-
if (UNSAFE_SHELL_CHARS.test(p)) {
|
|
4915
|
-
throw new Error(
|
|
4916
|
-
`${context} contains characters unsafe for shell embedding: ${p}`
|
|
4917
|
-
);
|
|
4918
|
-
}
|
|
4919
|
-
}
|
|
4920
|
-
__name(assertSafeForShellEmbed, "assertSafeForShellEmbed");
|
|
4921
|
-
function isProcessAlive(pid) {
|
|
4922
|
-
try {
|
|
4923
|
-
process.kill(pid, 0);
|
|
4924
|
-
return true;
|
|
4925
|
-
} catch {
|
|
4926
|
-
return false;
|
|
4927
|
-
}
|
|
4928
|
-
}
|
|
4929
|
-
__name(isProcessAlive, "isProcessAlive");
|
|
4930
|
-
function atomicReplace(standaloneDir, newDir, lockPath) {
|
|
4931
|
-
const oldDir = `${standaloneDir}.old`;
|
|
4932
|
-
const pendingDir = `${standaloneDir}.new`;
|
|
4933
|
-
if (fs5.existsSync(oldDir)) {
|
|
4934
|
-
fs5.rmSync(oldDir, { recursive: true, force: true });
|
|
4935
|
-
}
|
|
4936
|
-
if (os3.platform() === "win32") {
|
|
4937
|
-
if (UNSAFE_CMD_CHARS.test(standaloneDir) || UNSAFE_CMD_CHARS.test(oldDir) || UNSAFE_CMD_CHARS.test(pendingDir)) {
|
|
4938
|
-
throw new Error(
|
|
4939
|
-
"Installation path contains characters unsafe for deferred update script"
|
|
4940
|
-
);
|
|
4941
|
-
}
|
|
4942
|
-
if (fs5.existsSync(pendingDir)) {
|
|
4943
|
-
fs5.rmSync(pendingDir, { recursive: true, force: true });
|
|
4944
|
-
}
|
|
4945
|
-
fs5.renameSync(newDir, pendingDir);
|
|
4946
|
-
const lockFile = lockPath;
|
|
4947
|
-
const logFile = path5.join(path5.dirname(standaloneDir), "qwen-update.log");
|
|
4948
|
-
const script = [
|
|
4949
|
-
"@echo off",
|
|
4950
|
-
"set /a TRIES=0",
|
|
4951
|
-
":wait",
|
|
4952
|
-
"set /a TRIES+=1",
|
|
4953
|
-
"if %TRIES% GTR 30 goto proceed",
|
|
4954
|
-
`tasklist /FI "PID eq ${process.pid}" 2>nul | find "${process.pid}" >nul && (timeout /t 1 >nul & goto wait)`,
|
|
4955
|
-
":proceed",
|
|
4956
|
-
`echo [%DATE% %TIME%] starting swap >> "${logFile}"`,
|
|
4957
|
-
`move /Y "${standaloneDir}" "${oldDir}"`,
|
|
4958
|
-
"if errorlevel 1 goto move1_failed",
|
|
4959
|
-
`move /Y "${pendingDir}" "${standaloneDir}"`,
|
|
4960
|
-
"if errorlevel 1 goto move2_failed",
|
|
4961
|
-
`echo [%DATE% %TIME%] swap completed >> "${logFile}"`,
|
|
4962
|
-
"goto cleanup",
|
|
4963
|
-
":move1_failed",
|
|
4964
|
-
`echo [%DATE% %TIME%] ERROR: failed to rename install to .old (errorlevel %errorlevel%) >> "${logFile}"`,
|
|
4965
|
-
"goto cleanup",
|
|
4966
|
-
":move2_failed",
|
|
4967
|
-
`echo [%DATE% %TIME%] ERROR: failed to promote .new; rolling back >> "${logFile}"`,
|
|
4968
|
-
`move /Y "${oldDir}" "${standaloneDir}"`,
|
|
4969
|
-
"if errorlevel 1 (",
|
|
4970
|
-
` echo [%DATE% %TIME%] CRITICAL: rollback also failed; manual recovery: move "${oldDir}" "${standaloneDir}" >> "${logFile}"`,
|
|
4971
|
-
") else (",
|
|
4972
|
-
` echo [%DATE% %TIME%] rollback succeeded >> "${logFile}"`,
|
|
4973
|
-
")",
|
|
4974
|
-
":cleanup",
|
|
4975
|
-
`del /F /Q "${lockFile}" 2>nul`,
|
|
4976
|
-
`del "%~f0"`
|
|
4977
|
-
].join("\r\n");
|
|
4978
|
-
const scriptPath = path5.join(
|
|
4979
|
-
path5.dirname(standaloneDir),
|
|
4980
|
-
"qwen-update.bat"
|
|
4981
|
-
);
|
|
4982
|
-
fs5.writeFileSync(scriptPath, script);
|
|
4983
|
-
spawn2("cmd.exe", ["/c", scriptPath], {
|
|
4984
|
-
detached: true,
|
|
4985
|
-
stdio: "ignore",
|
|
4986
|
-
windowsHide: true
|
|
4987
|
-
}).unref();
|
|
4988
|
-
return "deferred";
|
|
4989
|
-
} else {
|
|
4990
|
-
fs5.renameSync(standaloneDir, oldDir);
|
|
4991
|
-
try {
|
|
4992
|
-
fs5.renameSync(newDir, standaloneDir);
|
|
4993
|
-
} catch (promoteErr) {
|
|
4994
|
-
try {
|
|
4995
|
-
fs5.renameSync(oldDir, standaloneDir);
|
|
4996
|
-
} catch (rollbackErr) {
|
|
4997
|
-
const detail = `Standalone update failed AND rollback failed.
|
|
4998
|
-
Original error: ${promoteErr.message}
|
|
4999
|
-
Rollback error: ${rollbackErr.message}
|
|
5000
|
-
Manual recovery: mv "${oldDir}" "${standaloneDir}"`;
|
|
5001
|
-
throw new Error(detail);
|
|
5002
|
-
}
|
|
5003
|
-
throw promoteErr;
|
|
5004
|
-
}
|
|
5005
|
-
return "done";
|
|
5006
|
-
}
|
|
5007
|
-
}
|
|
5008
|
-
__name(atomicReplace, "atomicReplace");
|
|
5009
|
-
function ensureBinWrapper(standaloneDir, target) {
|
|
5010
|
-
const binDir = path5.join(path5.dirname(standaloneDir), "..", "bin");
|
|
5011
|
-
try {
|
|
5012
|
-
fs5.mkdirSync(binDir, { recursive: true });
|
|
5013
|
-
if (target.startsWith("win")) {
|
|
5014
|
-
if (UNSAFE_CMD_CHARS.test(standaloneDir)) {
|
|
5015
|
-
throw new Error(
|
|
5016
|
-
"standaloneDir contains characters unsafe for cmd.exe wrapper"
|
|
5017
|
-
);
|
|
5018
|
-
}
|
|
5019
|
-
const wrapperPath = path5.join(binDir, "qwen.cmd");
|
|
5020
|
-
if (!fs5.existsSync(wrapperPath)) {
|
|
5021
|
-
const content = `@echo off\r
|
|
5022
|
-
call "${standaloneDir}\\bin\\qwen.cmd" %*\r
|
|
5023
|
-
`;
|
|
5024
|
-
fs5.writeFileSync(wrapperPath, content);
|
|
5025
|
-
}
|
|
5026
|
-
} else {
|
|
5027
|
-
assertSafeForShellEmbed(standaloneDir, "standaloneDir");
|
|
5028
|
-
const wrapperPath = path5.join(binDir, "qwen");
|
|
5029
|
-
if (!fs5.existsSync(wrapperPath)) {
|
|
5030
|
-
const content = `#!/bin/sh
|
|
5031
|
-
exec "${standaloneDir}/bin/qwen" "$@"
|
|
5032
|
-
`;
|
|
5033
|
-
fs5.writeFileSync(wrapperPath, content, { mode: 493 });
|
|
5034
|
-
}
|
|
5035
|
-
ensurePathInShellRc(binDir);
|
|
5036
|
-
}
|
|
5037
|
-
} catch (err) {
|
|
5038
|
-
debugLogger6.warn("Failed to create bin wrapper:", err);
|
|
5039
|
-
}
|
|
5040
|
-
}
|
|
5041
|
-
__name(ensureBinWrapper, "ensureBinWrapper");
|
|
5042
|
-
function ensurePathInShellRc(binDir) {
|
|
5043
|
-
assertSafeForShellEmbed(binDir, "binDir");
|
|
5044
|
-
const shell = process.env["SHELL"] || "";
|
|
5045
|
-
let rcFile = null;
|
|
5046
|
-
const home = process.env["HOME"] || os3.homedir();
|
|
5047
|
-
if (shell.endsWith("/zsh")) {
|
|
5048
|
-
rcFile = path5.join(home, ".zshrc");
|
|
5049
|
-
} else if (shell.endsWith("/bash")) {
|
|
5050
|
-
const bashrc = path5.join(home, ".bashrc");
|
|
5051
|
-
const profile = path5.join(home, ".bash_profile");
|
|
5052
|
-
if (os3.platform() === "darwin") {
|
|
5053
|
-
rcFile = fs5.existsSync(profile) ? profile : bashrc;
|
|
5054
|
-
} else {
|
|
5055
|
-
rcFile = bashrc;
|
|
5056
|
-
}
|
|
5057
|
-
} else if (shell.endsWith("/fish")) {
|
|
5058
|
-
rcFile = path5.join(home, ".config", "fish", "config.fish");
|
|
5059
|
-
}
|
|
5060
|
-
if (!rcFile) return;
|
|
5061
|
-
try {
|
|
5062
|
-
const content = fs5.existsSync(rcFile) ? fs5.readFileSync(rcFile, "utf-8") : "";
|
|
5063
|
-
const marker = "# Added by Qwen Code standalone installer";
|
|
5064
|
-
if (content.includes(marker)) return;
|
|
5065
|
-
const exportLine = shell.endsWith("/fish") ? `
|
|
5066
|
-
${marker}
|
|
5067
|
-
fish_add_path "${binDir}"
|
|
5068
|
-
` : `
|
|
5069
|
-
${marker}
|
|
5070
|
-
export PATH="${binDir}:$PATH"
|
|
5071
|
-
`;
|
|
5072
|
-
fs5.appendFileSync(rcFile, exportLine);
|
|
5073
|
-
debugLogger6.info(`Added ${binDir} to ${rcFile}`);
|
|
5074
|
-
} catch (err) {
|
|
5075
|
-
debugLogger6.debug("Failed to update shell rc:", err);
|
|
5076
|
-
}
|
|
5077
|
-
}
|
|
5078
|
-
__name(ensurePathInShellRc, "ensurePathInShellRc");
|
|
5079
|
-
function detectTarget() {
|
|
5080
|
-
const platform3 = os3.platform();
|
|
5081
|
-
const arch2 = os3.arch();
|
|
5082
|
-
if (platform3 === "darwin") {
|
|
5083
|
-
return arch2 === "arm64" ? "darwin-arm64" : "darwin-x64";
|
|
5084
|
-
}
|
|
5085
|
-
if (platform3 === "win32") return "win-x64";
|
|
5086
|
-
if (platform3 === "linux") {
|
|
5087
|
-
if (arch2 === "arm64") return "linux-arm64";
|
|
5088
|
-
if (arch2 === "x64") return "linux-x64";
|
|
5089
|
-
}
|
|
5090
|
-
throw new Error(`Unsupported platform: ${platform3}-${arch2}`);
|
|
5091
|
-
}
|
|
5092
|
-
__name(detectTarget, "detectTarget");
|
|
5093
|
-
async function performStandaloneUpdate(standaloneDir, newVersion) {
|
|
5094
|
-
const versionPath = normalizeVersion(newVersion);
|
|
5095
|
-
let target;
|
|
5096
|
-
let isFirstTimeMigration = false;
|
|
5097
|
-
const manifestPath = path5.join(standaloneDir, "manifest.json");
|
|
5098
|
-
if (fs5.existsSync(manifestPath)) {
|
|
5099
|
-
const manifestRaw = fs5.readFileSync(manifestPath, "utf-8");
|
|
5100
|
-
const manifest = JSON.parse(manifestRaw);
|
|
5101
|
-
target = manifest.target ?? detectTarget();
|
|
5102
|
-
} else if (fs5.existsSync(standaloneDir)) {
|
|
5103
|
-
throw new Error(
|
|
5104
|
-
`${standaloneDir} exists but is not a Qwen Code standalone install. Remove it manually to proceed.`
|
|
5105
|
-
);
|
|
5106
|
-
} else {
|
|
5107
|
-
target = detectTarget();
|
|
5108
|
-
isFirstTimeMigration = true;
|
|
5109
|
-
}
|
|
5110
|
-
validateTarget(target);
|
|
5111
|
-
const filename = archiveFilename(target);
|
|
5112
|
-
const parentDir = path5.dirname(standaloneDir);
|
|
5113
|
-
fs5.mkdirSync(parentDir, { recursive: true });
|
|
5114
|
-
const lockPath = path5.join(parentDir, ".qwen-update.lock");
|
|
5115
|
-
if (!acquireLock(lockPath)) {
|
|
5116
|
-
throw new Error("Another update is already in progress");
|
|
5117
|
-
}
|
|
5118
|
-
if (isFirstTimeMigration) {
|
|
5119
|
-
fs5.mkdirSync(standaloneDir, { recursive: true });
|
|
5120
|
-
}
|
|
5121
|
-
const tempDir = fs5.mkdtempSync(path5.join(os3.tmpdir(), "qwen-code-update-"));
|
|
5122
|
-
let extractDir;
|
|
5123
|
-
let updateResult;
|
|
5124
|
-
try {
|
|
5125
|
-
extractDir = fs5.mkdtempSync(path5.join(parentDir, ".qwen-code-update-"));
|
|
5126
|
-
} catch (err) {
|
|
5127
|
-
fs5.rmSync(tempDir, { recursive: true, force: true });
|
|
5128
|
-
releaseLock(lockPath);
|
|
5129
|
-
throw err;
|
|
5130
|
-
}
|
|
5131
|
-
try {
|
|
5132
|
-
const archivePath = path5.join(tempDir, filename);
|
|
5133
|
-
debugLogger6.info(`Downloading ${filename} (${versionPath})...`);
|
|
5134
|
-
const archiveHash = await downloadToFile(
|
|
5135
|
-
versionPath,
|
|
5136
|
-
filename,
|
|
5137
|
-
archivePath
|
|
5138
|
-
);
|
|
5139
|
-
debugLogger6.info("Verifying checksum...");
|
|
5140
|
-
await verifyChecksum(archiveHash, filename, versionPath);
|
|
5141
|
-
debugLogger6.info("Extracting archive...");
|
|
5142
|
-
await extractArchive(archivePath, extractDir, target);
|
|
5143
|
-
const newInstallDir = path5.join(extractDir, "qwen-code");
|
|
5144
|
-
if (!fs5.existsSync(path5.join(newInstallDir, "manifest.json"))) {
|
|
5145
|
-
throw new Error(
|
|
5146
|
-
"Extracted archive does not contain expected qwen-code directory"
|
|
5147
|
-
);
|
|
5148
|
-
}
|
|
5149
|
-
debugLogger6.info("Running smoke test...");
|
|
5150
|
-
await smokeTest(newInstallDir, target);
|
|
5151
|
-
debugLogger6.info("Replacing installation...");
|
|
5152
|
-
updateResult = atomicReplace(standaloneDir, newInstallDir, lockPath);
|
|
5153
|
-
const oldDir = `${standaloneDir}.old`;
|
|
5154
|
-
if (fs5.existsSync(oldDir)) {
|
|
5155
|
-
if (isFirstTimeMigration) {
|
|
5156
|
-
fs5.rmSync(oldDir, { recursive: true, force: true });
|
|
5157
|
-
} else {
|
|
5158
|
-
try {
|
|
5159
|
-
const oldManifestPath = path5.join(oldDir, "manifest.json");
|
|
5160
|
-
let oldVersion = "unknown";
|
|
5161
|
-
if (fs5.existsSync(oldManifestPath)) {
|
|
5162
|
-
const oldManifest = JSON.parse(
|
|
5163
|
-
fs5.readFileSync(oldManifestPath, "utf-8")
|
|
5164
|
-
);
|
|
5165
|
-
oldVersion = oldManifest.version || "unknown";
|
|
5166
|
-
}
|
|
5167
|
-
const rollbackInfo = {
|
|
5168
|
-
preservedVersion: oldVersion,
|
|
5169
|
-
updatedTo: versionPath,
|
|
5170
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5171
|
-
reason: "auto-update"
|
|
5172
|
-
};
|
|
5173
|
-
fs5.writeFileSync(
|
|
5174
|
-
path5.join(oldDir, ".qwen-rollback-info.json"),
|
|
5175
|
-
JSON.stringify(rollbackInfo, null, 2)
|
|
5176
|
-
);
|
|
5177
|
-
} catch {
|
|
5178
|
-
}
|
|
5179
|
-
}
|
|
5180
|
-
}
|
|
5181
|
-
ensureBinWrapper(standaloneDir, target);
|
|
5182
|
-
debugLogger6.info("Standalone update complete.");
|
|
5183
|
-
return updateResult;
|
|
5184
|
-
} catch (err) {
|
|
5185
|
-
const pendingDir = `${standaloneDir}.new`;
|
|
5186
|
-
if (fs5.existsSync(pendingDir)) {
|
|
5187
|
-
fs5.rmSync(pendingDir, { recursive: true, force: true });
|
|
5188
|
-
}
|
|
5189
|
-
cleanupEmptyStandaloneDir(standaloneDir);
|
|
5190
|
-
throw err;
|
|
5191
|
-
} finally {
|
|
5192
|
-
if (updateResult !== "deferred") {
|
|
5193
|
-
releaseLock(lockPath);
|
|
5194
|
-
}
|
|
5195
|
-
try {
|
|
5196
|
-
fs5.rmSync(tempDir, { recursive: true, force: true });
|
|
5197
|
-
} catch {
|
|
5198
|
-
}
|
|
5199
|
-
try {
|
|
5200
|
-
fs5.rmSync(extractDir, { recursive: true, force: true });
|
|
5201
|
-
} catch {
|
|
5202
|
-
}
|
|
5203
|
-
}
|
|
5204
|
-
}
|
|
5205
|
-
__name(performStandaloneUpdate, "performStandaloneUpdate");
|
|
5206
|
-
function rollbackStandaloneUpdate(standaloneDir) {
|
|
5207
|
-
const lockPath = path5.join(path5.dirname(standaloneDir), ".qwen-update.lock");
|
|
5208
|
-
try {
|
|
5209
|
-
const pidStr = fs5.readFileSync(lockPath, "utf-8").trim();
|
|
5210
|
-
const pid = parseInt(pidStr, 10);
|
|
5211
|
-
if (!Number.isNaN(pid) && isProcessAlive(pid)) {
|
|
5212
|
-
return {
|
|
5213
|
-
ok: false,
|
|
5214
|
-
reason: "rename-failed",
|
|
5215
|
-
detail: "An auto-update is currently in progress. Wait for it to finish before rolling back."
|
|
5216
|
-
};
|
|
5217
|
-
}
|
|
5218
|
-
} catch {
|
|
5219
|
-
}
|
|
5220
|
-
const oldDir = `${standaloneDir}.old`;
|
|
5221
|
-
if (!fs5.existsSync(oldDir)) {
|
|
5222
|
-
return { ok: false, reason: "no-old", detail: `${oldDir} does not exist` };
|
|
5223
|
-
}
|
|
5224
|
-
const oldManifest = path5.join(oldDir, "manifest.json");
|
|
5225
|
-
if (!fs5.existsSync(oldManifest)) {
|
|
5226
|
-
debugLogger6.error("Rollback failed: .old directory has no manifest.json");
|
|
5227
|
-
return {
|
|
5228
|
-
ok: false,
|
|
5229
|
-
reason: "no-manifest",
|
|
5230
|
-
detail: `${oldDir}/manifest.json missing \u2014 .old may be corrupt`
|
|
5231
|
-
};
|
|
5232
|
-
}
|
|
5233
|
-
const failedDir = `${standaloneDir}.failed`;
|
|
5234
|
-
try {
|
|
5235
|
-
if (fs5.existsSync(failedDir)) {
|
|
5236
|
-
fs5.rmSync(failedDir, { recursive: true, force: true });
|
|
5237
|
-
}
|
|
5238
|
-
fs5.renameSync(standaloneDir, failedDir);
|
|
5239
|
-
fs5.renameSync(oldDir, standaloneDir);
|
|
5240
|
-
debugLogger6.info("Rollback successful.");
|
|
5241
|
-
try {
|
|
5242
|
-
fs5.rmSync(failedDir, { recursive: true, force: true });
|
|
5243
|
-
} catch {
|
|
5244
|
-
debugLogger6.debug(`Leftover .failed dir at ${failedDir}, safe to delete`);
|
|
5245
|
-
}
|
|
5246
|
-
return { ok: true };
|
|
5247
|
-
} catch (err) {
|
|
5248
|
-
debugLogger6.error("Rollback failed:", err);
|
|
5249
|
-
if (!fs5.existsSync(standaloneDir) && fs5.existsSync(failedDir)) {
|
|
5250
|
-
try {
|
|
5251
|
-
fs5.renameSync(failedDir, standaloneDir);
|
|
5252
|
-
return {
|
|
5253
|
-
ok: false,
|
|
5254
|
-
reason: "rename-failed",
|
|
5255
|
-
detail: `Filesystem error: ${err.message}. Current installation was restored automatically.`
|
|
5256
|
-
};
|
|
5257
|
-
} catch {
|
|
5258
|
-
}
|
|
5259
|
-
}
|
|
5260
|
-
return {
|
|
5261
|
-
ok: false,
|
|
5262
|
-
reason: "rename-failed",
|
|
5263
|
-
detail: `Filesystem error: ${err.message}. Manual recovery: mv "${oldDir}" "${standaloneDir}"`
|
|
5264
|
-
};
|
|
5265
|
-
}
|
|
5266
|
-
}
|
|
5267
|
-
__name(rollbackStandaloneUpdate, "rollbackStandaloneUpdate");
|
|
5268
|
-
|
|
5269
|
-
// packages/cli/src/utils/installationInfo.ts
|
|
5270
|
-
init_esbuild_shims();
|
|
5271
|
-
import * as fs6 from "node:fs";
|
|
5272
|
-
import * as path6 from "node:path";
|
|
5273
|
-
import * as childProcess from "node:child_process";
|
|
5274
|
-
var debugLogger7 = createDebugLogger("INSTALLATION_INFO");
|
|
5275
|
-
var STANDALONE_UNIX_INSTALLER = "https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen-standalone.sh";
|
|
5276
|
-
var STANDALONE_WINDOWS_INSTALLER = "https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen-standalone.ps1";
|
|
5277
|
-
function getInstallationInfo(projectRoot, isAutoUpdateEnabled) {
|
|
5278
|
-
const cliPath = process.argv[1];
|
|
5279
|
-
if (!cliPath) {
|
|
5280
|
-
return { packageManager: "unknown" /* UNKNOWN */, isGlobal: false };
|
|
5281
|
-
}
|
|
5282
|
-
try {
|
|
5283
|
-
const realPath = fs6.realpathSync(cliPath).replace(/\\/g, "/");
|
|
5284
|
-
const normalizedProjectRoot = projectRoot?.replace(/\\/g, "/");
|
|
5285
|
-
const isGit = isGitRepository(process.cwd());
|
|
5286
|
-
if (isGit && normalizedProjectRoot && isSamePathOrInside(realPath, normalizedProjectRoot) && !realPath.includes("/node_modules/")) {
|
|
5287
|
-
return {
|
|
5288
|
-
packageManager: "unknown" /* UNKNOWN */,
|
|
5289
|
-
// Not managed by a package manager in this sense
|
|
5290
|
-
isGlobal: false,
|
|
5291
|
-
updateMessage: 'Running from a local git clone. Please update with "git pull".'
|
|
5292
|
-
};
|
|
5293
|
-
}
|
|
5294
|
-
if (realPath.includes("/.npm/_npx") || realPath.includes("/npm/_npx")) {
|
|
5295
|
-
return {
|
|
5296
|
-
packageManager: "npx" /* NPX */,
|
|
5297
|
-
isGlobal: false,
|
|
5298
|
-
updateMessage: "Running via npx, update not applicable."
|
|
5299
|
-
};
|
|
5300
|
-
}
|
|
5301
|
-
if (realPath.includes("/.pnpm/_pnpx")) {
|
|
5302
|
-
return {
|
|
5303
|
-
packageManager: "pnpx" /* PNPX */,
|
|
5304
|
-
isGlobal: false,
|
|
5305
|
-
updateMessage: "Running via pnpx, update not applicable."
|
|
5306
|
-
};
|
|
5307
|
-
}
|
|
5308
|
-
const standaloneInfo = getStandaloneInstallInfo(
|
|
5309
|
-
realPath,
|
|
5310
|
-
isAutoUpdateEnabled
|
|
5311
|
-
);
|
|
5312
|
-
if (standaloneInfo) {
|
|
5313
|
-
return standaloneInfo;
|
|
5314
|
-
}
|
|
5315
|
-
if (process.platform === "darwin") {
|
|
5316
|
-
try {
|
|
5317
|
-
childProcess.execSync('brew list -1 | grep -q "^qwen-code$"', {
|
|
5318
|
-
stdio: "ignore"
|
|
5319
|
-
});
|
|
5320
|
-
return {
|
|
5321
|
-
packageManager: "homebrew" /* HOMEBREW */,
|
|
5322
|
-
isGlobal: true,
|
|
5323
|
-
updateMessage: 'Installed via Homebrew. Please update with "brew upgrade".'
|
|
5324
|
-
};
|
|
5325
|
-
} catch (_error) {
|
|
5326
|
-
}
|
|
5327
|
-
}
|
|
5328
|
-
if (realPath.includes("/.pnpm/global")) {
|
|
5329
|
-
const updateCommand2 = "pnpm add -g @qwen-code/qwen-code@latest";
|
|
5330
|
-
return {
|
|
5331
|
-
packageManager: "pnpm" /* PNPM */,
|
|
5332
|
-
isGlobal: true,
|
|
5333
|
-
updateCommand: updateCommand2,
|
|
5334
|
-
updateMessage: isAutoUpdateEnabled ? "Installed with pnpm. Attempting to automatically update now..." : `Please run ${updateCommand2} to update`
|
|
5335
|
-
};
|
|
5336
|
-
}
|
|
5337
|
-
if (realPath.includes("/.yarn/global")) {
|
|
5338
|
-
const updateCommand2 = "yarn global add @qwen-code/qwen-code@latest";
|
|
5339
|
-
return {
|
|
5340
|
-
packageManager: "yarn" /* YARN */,
|
|
5341
|
-
isGlobal: true,
|
|
5342
|
-
updateCommand: updateCommand2,
|
|
5343
|
-
updateMessage: isAutoUpdateEnabled ? "Installed with yarn. Attempting to automatically update now..." : `Please run ${updateCommand2} to update`
|
|
5344
|
-
};
|
|
5345
|
-
}
|
|
5346
|
-
if (realPath.includes("/.bun/install/cache")) {
|
|
5347
|
-
return {
|
|
5348
|
-
packageManager: "bunx" /* BUNX */,
|
|
5349
|
-
isGlobal: false,
|
|
5350
|
-
updateMessage: "Running via bunx, update not applicable."
|
|
5351
|
-
};
|
|
5352
|
-
}
|
|
5353
|
-
if (realPath.includes("/.bun/bin")) {
|
|
5354
|
-
const updateCommand2 = "bun add -g @qwen-code/qwen-code@latest";
|
|
5355
|
-
return {
|
|
5356
|
-
packageManager: "bun" /* BUN */,
|
|
5357
|
-
isGlobal: true,
|
|
5358
|
-
updateCommand: updateCommand2,
|
|
5359
|
-
updateMessage: isAutoUpdateEnabled ? "Installed with bun. Attempting to automatically update now..." : `Please run ${updateCommand2} to update`
|
|
5360
|
-
};
|
|
5361
|
-
}
|
|
5362
|
-
if (normalizedProjectRoot && isSamePathOrInside(realPath, `${normalizedProjectRoot}/node_modules`)) {
|
|
5363
|
-
let pm = "npm" /* NPM */;
|
|
5364
|
-
if (fs6.existsSync(path6.join(projectRoot, "yarn.lock"))) {
|
|
5365
|
-
pm = "yarn" /* YARN */;
|
|
5366
|
-
} else if (fs6.existsSync(path6.join(projectRoot, "pnpm-lock.yaml"))) {
|
|
5367
|
-
pm = "pnpm" /* PNPM */;
|
|
5368
|
-
} else if (fs6.existsSync(path6.join(projectRoot, "bun.lockb"))) {
|
|
5369
|
-
pm = "bun" /* BUN */;
|
|
5370
|
-
}
|
|
5371
|
-
return {
|
|
5372
|
-
packageManager: pm,
|
|
5373
|
-
isGlobal: false,
|
|
5374
|
-
updateMessage: "Locally installed. Please update via your project's package.json."
|
|
5375
|
-
};
|
|
5376
|
-
}
|
|
5377
|
-
const npmPackageDir = path6.dirname(path6.dirname(realPath));
|
|
5378
|
-
let npmPrefixWritable = false;
|
|
5379
|
-
try {
|
|
5380
|
-
fs6.accessSync(npmPackageDir, fs6.constants.W_OK);
|
|
5381
|
-
npmPrefixWritable = true;
|
|
5382
|
-
} catch {
|
|
5383
|
-
}
|
|
5384
|
-
if (!npmPrefixWritable) {
|
|
5385
|
-
return {
|
|
5386
|
-
packageManager: "npm" /* NPM */,
|
|
5387
|
-
isGlobal: true,
|
|
5388
|
-
updateMessage: "Update requires sudo. Please run: sudo npm install -g @qwen-code/qwen-code@latest"
|
|
5389
|
-
};
|
|
5390
|
-
}
|
|
5391
|
-
const updateCommand = "npm install -g @qwen-code/qwen-code@latest";
|
|
5392
|
-
return {
|
|
5393
|
-
packageManager: "npm" /* NPM */,
|
|
5394
|
-
isGlobal: true,
|
|
5395
|
-
updateCommand,
|
|
5396
|
-
updateMessage: isAutoUpdateEnabled ? "Installed with npm. Attempting to automatically update now..." : `Please run ${updateCommand} to update`
|
|
5397
|
-
};
|
|
5398
|
-
} catch (error) {
|
|
5399
|
-
debugLogger7.error("Failed to detect installation info:", error);
|
|
5400
|
-
return { packageManager: "unknown" /* UNKNOWN */, isGlobal: false };
|
|
5401
|
-
}
|
|
5402
|
-
}
|
|
5403
|
-
__name(getInstallationInfo, "getInstallationInfo");
|
|
5404
|
-
function stripTrailingSlashes(value) {
|
|
5405
|
-
return value.replace(/\/+$/, "") || "/";
|
|
5406
|
-
}
|
|
5407
|
-
__name(stripTrailingSlashes, "stripTrailingSlashes");
|
|
5408
|
-
function isSamePathOrInside(candidate, parent) {
|
|
5409
|
-
const normalizedCandidate = stripTrailingSlashes(candidate);
|
|
5410
|
-
const normalizedParent = stripTrailingSlashes(parent);
|
|
5411
|
-
if (normalizedParent === "/") {
|
|
5412
|
-
return normalizedCandidate === "/" || normalizedCandidate.startsWith("/");
|
|
5413
|
-
}
|
|
5414
|
-
return normalizedCandidate === normalizedParent || normalizedCandidate.startsWith(`${normalizedParent}/`);
|
|
5415
|
-
}
|
|
5416
|
-
__name(isSamePathOrInside, "isSamePathOrInside");
|
|
5417
|
-
function getStandaloneInstallInfo(realPath, isAutoUpdateEnabled) {
|
|
5418
|
-
const installDir = standaloneInstallDirForCliPath(realPath);
|
|
5419
|
-
if (!installDir || !isStandaloneInstallDir(installDir)) {
|
|
5420
|
-
return null;
|
|
5421
|
-
}
|
|
5422
|
-
const updateCommand = process.platform === "win32" ? `powershell -ExecutionPolicy Bypass -c "irm ${STANDALONE_WINDOWS_INSTALLER} | iex"` : `curl -fsSL ${STANDALONE_UNIX_INSTALLER} | bash`;
|
|
5423
|
-
return {
|
|
5424
|
-
packageManager: "standalone" /* STANDALONE */,
|
|
5425
|
-
isGlobal: true,
|
|
5426
|
-
isStandalone: true,
|
|
5427
|
-
standaloneDir: installDir,
|
|
5428
|
-
updateMessage: isAutoUpdateEnabled ? "Standalone install detected. Attempting to automatically update now..." : `Standalone install detected. Please rerun the standalone installer to update: ${updateCommand}`
|
|
5429
|
-
};
|
|
5430
|
-
}
|
|
5431
|
-
__name(getStandaloneInstallInfo, "getStandaloneInstallInfo");
|
|
5432
|
-
function standaloneInstallDirForCliPath(realPath) {
|
|
5433
|
-
const normalized = realPath.replace(/\\/g, "/");
|
|
5434
|
-
const suffix = "/lib/cli.js";
|
|
5435
|
-
if (!normalized.endsWith(suffix)) {
|
|
5436
|
-
return null;
|
|
5437
|
-
}
|
|
5438
|
-
return realPath.slice(0, -suffix.length);
|
|
5439
|
-
}
|
|
5440
|
-
__name(standaloneInstallDirForCliPath, "standaloneInstallDirForCliPath");
|
|
5441
|
-
function isStandaloneInstallDir(installDir) {
|
|
5442
|
-
try {
|
|
5443
|
-
const manifestPath = path6.join(installDir, "manifest.json");
|
|
5444
|
-
if (!fs6.existsSync(manifestPath)) {
|
|
5445
|
-
return false;
|
|
5446
|
-
}
|
|
5447
|
-
const manifest = JSON.parse(fs6.readFileSync(manifestPath, "utf8"));
|
|
5448
|
-
if (manifest.name !== "@qwen-code/qwen-code" || typeof manifest.target !== "string" || !isStandaloneTargetForCurrentPlatform(manifest.target)) {
|
|
5449
|
-
return false;
|
|
5450
|
-
}
|
|
5451
|
-
const qwenBin = process.platform === "win32" ? path6.join(installDir, "bin", "qwen.cmd") : path6.join(installDir, "bin", "qwen");
|
|
5452
|
-
const nodeBin = process.platform === "win32" ? path6.join(installDir, "node", "node.exe") : path6.join(installDir, "node", "bin", "node");
|
|
5453
|
-
return fs6.existsSync(qwenBin) && fs6.existsSync(nodeBin) && isStandaloneRuntimeFile(qwenBin) && isStandaloneRuntimeFile(nodeBin);
|
|
5454
|
-
} catch (err) {
|
|
5455
|
-
debugLogger7.error("Standalone detection failed:", installDir, err);
|
|
5456
|
-
return false;
|
|
5457
|
-
}
|
|
5458
|
-
}
|
|
5459
|
-
__name(isStandaloneInstallDir, "isStandaloneInstallDir");
|
|
5460
|
-
function isStandaloneTargetForCurrentPlatform(target) {
|
|
5461
|
-
switch (process.platform) {
|
|
5462
|
-
case "darwin":
|
|
5463
|
-
return /^darwin-(arm64|x64)$/.test(target);
|
|
5464
|
-
case "linux":
|
|
5465
|
-
return /^linux-(arm64|x64)$/.test(target);
|
|
5466
|
-
case "win32":
|
|
5467
|
-
return /^win-(arm64|x64)$/.test(target);
|
|
5468
|
-
default:
|
|
5469
|
-
return false;
|
|
5470
|
-
}
|
|
5471
|
-
}
|
|
5472
|
-
__name(isStandaloneTargetForCurrentPlatform, "isStandaloneTargetForCurrentPlatform");
|
|
5473
|
-
function isStandaloneRuntimeFile(filePath) {
|
|
5474
|
-
const stats = fs6.lstatSync(filePath);
|
|
5475
|
-
if (!stats.isFile() || stats.isSymbolicLink()) {
|
|
5476
|
-
return false;
|
|
5477
|
-
}
|
|
5478
|
-
return process.platform === "win32" || (stats.mode & 73) !== 0;
|
|
5479
|
-
}
|
|
5480
|
-
__name(isStandaloneRuntimeFile, "isStandaloneRuntimeFile");
|
|
5481
|
-
|
|
5482
4612
|
// packages/cli/src/ui/commands/doctorCommand.ts
|
|
5483
4613
|
var MEMORY_SUBCOMMAND = "memory";
|
|
5484
4614
|
var CPU_PROFILE_SUBCOMMAND = "cpu-profile";
|
|
@@ -5921,14 +5051,14 @@ async function cpuProfileDoctorAction(context, args = "") {
|
|
|
5921
5051
|
})
|
|
5922
5052
|
});
|
|
5923
5053
|
}
|
|
5924
|
-
await new Promise((
|
|
5925
|
-
const timer = setTimeout(
|
|
5054
|
+
await new Promise((resolve4) => {
|
|
5055
|
+
const timer = setTimeout(resolve4, durationSec * 1e3);
|
|
5926
5056
|
if (abortSignal) {
|
|
5927
5057
|
abortSignal.addEventListener(
|
|
5928
5058
|
"abort",
|
|
5929
5059
|
() => {
|
|
5930
5060
|
clearTimeout(timer);
|
|
5931
|
-
|
|
5061
|
+
resolve4();
|
|
5932
5062
|
},
|
|
5933
5063
|
{ once: true }
|
|
5934
5064
|
);
|
|
@@ -6128,10 +5258,10 @@ var effortCommand = {
|
|
|
6128
5258
|
|
|
6129
5259
|
// packages/cli/src/ui/commands/exportCommand.ts
|
|
6130
5260
|
init_esbuild_shims();
|
|
6131
|
-
import * as
|
|
6132
|
-
import
|
|
5261
|
+
import * as fs5 from "node:fs/promises";
|
|
5262
|
+
import path5 from "node:path";
|
|
6133
5263
|
var EXPORT_DIR_OUT_OF_CWD = "Export directory must be within the project working directory.";
|
|
6134
|
-
var
|
|
5264
|
+
var debugLogger6 = createDebugLogger("EXPORT_COMMAND");
|
|
6135
5265
|
function formatExportTargetContext(target) {
|
|
6136
5266
|
return `target: "${target.outputDir}", cwd: "${target.resolvedCwd}"`;
|
|
6137
5267
|
}
|
|
@@ -6143,16 +5273,16 @@ __name(formatMissingCwdError, "formatMissingCwdError");
|
|
|
6143
5273
|
function resolveExportTarget(cwd, args, extension) {
|
|
6144
5274
|
const filename = generateExportFilename(extension);
|
|
6145
5275
|
const outputDirArg = args.trim();
|
|
6146
|
-
const resolvedCwd =
|
|
6147
|
-
const outputDir = outputDirArg ?
|
|
6148
|
-
const filepath =
|
|
5276
|
+
const resolvedCwd = path5.resolve(cwd);
|
|
5277
|
+
const outputDir = outputDirArg ? path5.resolve(resolvedCwd, outputDirArg) : resolvedCwd;
|
|
5278
|
+
const filepath = path5.join(outputDir, filename);
|
|
6149
5279
|
const isDefaultOutputDir = outputDir === resolvedCwd;
|
|
6150
5280
|
const isInsideCwd = isSubpath(resolvedCwd, outputDir);
|
|
6151
5281
|
const outputDirKind = outputDirArg && !isDefaultOutputDir ? "custom" : "default";
|
|
6152
5282
|
return {
|
|
6153
5283
|
filepath,
|
|
6154
5284
|
outputDir,
|
|
6155
|
-
displayPath: isDefaultOutputDir ? filename :
|
|
5285
|
+
displayPath: isDefaultOutputDir ? filename : path5.join(outputDirArg, filename),
|
|
6156
5286
|
resolvedCwd,
|
|
6157
5287
|
outputDirKind,
|
|
6158
5288
|
isInsideCwd
|
|
@@ -6160,7 +5290,7 @@ function resolveExportTarget(cwd, args, extension) {
|
|
|
6160
5290
|
}
|
|
6161
5291
|
__name(resolveExportTarget, "resolveExportTarget");
|
|
6162
5292
|
async function validateExportTargetWithinCwd(target) {
|
|
6163
|
-
|
|
5293
|
+
debugLogger6.debug(
|
|
6164
5294
|
"Validating export target realpath:",
|
|
6165
5295
|
formatExportTargetContext(target)
|
|
6166
5296
|
);
|
|
@@ -6168,12 +5298,12 @@ async function validateExportTargetWithinCwd(target) {
|
|
|
6168
5298
|
let realOutputDir;
|
|
6169
5299
|
try {
|
|
6170
5300
|
[realCwd, realOutputDir] = await Promise.all([
|
|
6171
|
-
|
|
6172
|
-
|
|
5301
|
+
fs5.realpath(target.resolvedCwd),
|
|
5302
|
+
fs5.realpath(target.outputDir)
|
|
6173
5303
|
]);
|
|
6174
5304
|
} catch (error) {
|
|
6175
5305
|
if (error.code === "ENOENT") {
|
|
6176
|
-
|
|
5306
|
+
debugLogger6.debug(
|
|
6177
5307
|
"Export target realpath validation failed: missing path",
|
|
6178
5308
|
formatExportTargetContext(target)
|
|
6179
5309
|
);
|
|
@@ -6188,7 +5318,7 @@ async function validateExportTargetWithinCwd(target) {
|
|
|
6188
5318
|
throw error;
|
|
6189
5319
|
}
|
|
6190
5320
|
if (!isSubpath(realCwd, realOutputDir)) {
|
|
6191
|
-
|
|
5321
|
+
debugLogger6.debug("Export target realpath escaped cwd:", {
|
|
6192
5322
|
realCwd,
|
|
6193
5323
|
realOutputDir,
|
|
6194
5324
|
target
|
|
@@ -6206,24 +5336,24 @@ async function validateExportTargetWithinCwd(target) {
|
|
|
6206
5336
|
__name(validateExportTargetWithinCwd, "validateExportTargetWithinCwd");
|
|
6207
5337
|
async function realpathNearestExisting(outputDir, resolvedCwd) {
|
|
6208
5338
|
let currentPath = outputDir;
|
|
6209
|
-
|
|
5339
|
+
debugLogger6.debug("Resolving nearest existing export parent:", {
|
|
6210
5340
|
outputDir,
|
|
6211
5341
|
resolvedCwd
|
|
6212
5342
|
});
|
|
6213
5343
|
while (isSubpath(resolvedCwd, currentPath)) {
|
|
6214
5344
|
try {
|
|
6215
|
-
const realCurrentPath = await
|
|
6216
|
-
|
|
5345
|
+
const realCurrentPath = await fs5.realpath(currentPath);
|
|
5346
|
+
debugLogger6.debug("Resolved nearest existing export parent:", {
|
|
6217
5347
|
currentPath,
|
|
6218
5348
|
realCurrentPath
|
|
6219
5349
|
});
|
|
6220
5350
|
return realCurrentPath;
|
|
6221
5351
|
} catch (error) {
|
|
6222
5352
|
if (error.code !== "ENOENT") {
|
|
6223
|
-
|
|
5353
|
+
debugLogger6.debug("Failed to resolve existing export parent:", error);
|
|
6224
5354
|
throw error;
|
|
6225
5355
|
}
|
|
6226
|
-
const parentPath =
|
|
5356
|
+
const parentPath = path5.dirname(currentPath);
|
|
6227
5357
|
if (parentPath === currentPath) {
|
|
6228
5358
|
break;
|
|
6229
5359
|
}
|
|
@@ -6234,13 +5364,13 @@ async function realpathNearestExisting(outputDir, resolvedCwd) {
|
|
|
6234
5364
|
}
|
|
6235
5365
|
__name(realpathNearestExisting, "realpathNearestExisting");
|
|
6236
5366
|
async function validateExistingExportParentWithinCwd(target) {
|
|
6237
|
-
|
|
5367
|
+
debugLogger6.debug(
|
|
6238
5368
|
"Validating existing export parent realpath:",
|
|
6239
5369
|
formatExportTargetContext(target)
|
|
6240
5370
|
);
|
|
6241
5371
|
let realCwd;
|
|
6242
5372
|
try {
|
|
6243
|
-
realCwd = await
|
|
5373
|
+
realCwd = await fs5.realpath(target.resolvedCwd);
|
|
6244
5374
|
} catch (error) {
|
|
6245
5375
|
if (error.code === "ENOENT") {
|
|
6246
5376
|
throw new Error(formatMissingCwdError(target.resolvedCwd));
|
|
@@ -6252,7 +5382,7 @@ async function validateExistingExportParentWithinCwd(target) {
|
|
|
6252
5382
|
target.resolvedCwd
|
|
6253
5383
|
);
|
|
6254
5384
|
if (!isSubpath(realCwd, realExistingParent)) {
|
|
6255
|
-
|
|
5385
|
+
debugLogger6.debug("Existing export parent escaped cwd:", {
|
|
6256
5386
|
realCwd,
|
|
6257
5387
|
realExistingParent,
|
|
6258
5388
|
target
|
|
@@ -6288,7 +5418,7 @@ async function exportSessionAction(context, args, exportFormat) {
|
|
|
6288
5418
|
}
|
|
6289
5419
|
const target = resolveExportTarget(cwd, args, exportFormat.extension);
|
|
6290
5420
|
const targetFilepath = target.filepath;
|
|
6291
|
-
|
|
5421
|
+
debugLogger6.debug("Resolved export target:", {
|
|
6292
5422
|
format: exportFormat.displayName,
|
|
6293
5423
|
cwd,
|
|
6294
5424
|
outputDirArg: args.trim(),
|
|
@@ -6297,7 +5427,7 @@ async function exportSessionAction(context, args, exportFormat) {
|
|
|
6297
5427
|
filepath: target.filepath
|
|
6298
5428
|
});
|
|
6299
5429
|
if (!target.isInsideCwd) {
|
|
6300
|
-
|
|
5430
|
+
debugLogger6.debug(
|
|
6301
5431
|
"Export target rejected before realpath validation:",
|
|
6302
5432
|
formatExportTargetContext(target)
|
|
6303
5433
|
);
|
|
@@ -6314,17 +5444,17 @@ async function exportSessionAction(context, args, exportFormat) {
|
|
|
6314
5444
|
if (initialValidationError) {
|
|
6315
5445
|
return initialValidationError;
|
|
6316
5446
|
}
|
|
6317
|
-
|
|
5447
|
+
debugLogger6.debug("Export target validation passed:", {
|
|
6318
5448
|
format: exportFormat.displayName,
|
|
6319
5449
|
outputDir: target.outputDir,
|
|
6320
5450
|
outputDirKind: target.outputDirKind
|
|
6321
5451
|
});
|
|
6322
5452
|
const sessionService = new SessionService(cwd);
|
|
6323
5453
|
const sessionId = config.getSessionId();
|
|
6324
|
-
|
|
5454
|
+
debugLogger6.debug("Loading session for export:", { sessionId, cwd });
|
|
6325
5455
|
const sessionData = await sessionService.loadSession(sessionId);
|
|
6326
5456
|
if (!sessionData) {
|
|
6327
|
-
|
|
5457
|
+
debugLogger6.debug("No active session found for export:", {
|
|
6328
5458
|
sessionId,
|
|
6329
5459
|
cwd
|
|
6330
5460
|
});
|
|
@@ -6344,12 +5474,12 @@ async function exportSessionAction(context, args, exportFormat) {
|
|
|
6344
5474
|
const content = exportFormat.format(normalizedData);
|
|
6345
5475
|
if (target.outputDirKind === "custom") {
|
|
6346
5476
|
try {
|
|
6347
|
-
|
|
5477
|
+
debugLogger6.debug("Creating export directory:", {
|
|
6348
5478
|
outputDir: target.outputDir
|
|
6349
5479
|
});
|
|
6350
|
-
await
|
|
5480
|
+
await fs5.mkdir(target.outputDir, { recursive: true, mode: 448 });
|
|
6351
5481
|
} catch (error) {
|
|
6352
|
-
|
|
5482
|
+
debugLogger6.debug("Failed to create export directory:", error);
|
|
6353
5483
|
return {
|
|
6354
5484
|
type: "message",
|
|
6355
5485
|
messageType: "error",
|
|
@@ -6363,7 +5493,7 @@ async function exportSessionAction(context, args, exportFormat) {
|
|
|
6363
5493
|
return writeValidationError;
|
|
6364
5494
|
}
|
|
6365
5495
|
} catch (error) {
|
|
6366
|
-
|
|
5496
|
+
debugLogger6.debug("Export path validation failed before write:", error);
|
|
6367
5497
|
return {
|
|
6368
5498
|
type: "message",
|
|
6369
5499
|
messageType: "error",
|
|
@@ -6371,26 +5501,26 @@ async function exportSessionAction(context, args, exportFormat) {
|
|
|
6371
5501
|
};
|
|
6372
5502
|
}
|
|
6373
5503
|
try {
|
|
6374
|
-
|
|
5504
|
+
debugLogger6.debug("Writing export file:", {
|
|
6375
5505
|
format: exportFormat.displayName,
|
|
6376
5506
|
filepath: target.filepath
|
|
6377
5507
|
});
|
|
6378
|
-
await
|
|
5508
|
+
await fs5.writeFile(target.filepath, content, {
|
|
6379
5509
|
encoding: "utf-8",
|
|
6380
5510
|
mode: 384
|
|
6381
5511
|
});
|
|
6382
|
-
await
|
|
6383
|
-
|
|
5512
|
+
await fs5.chmod(target.filepath, 384).catch((error) => {
|
|
5513
|
+
debugLogger6.debug("Failed to tighten export file permissions:", error);
|
|
6384
5514
|
});
|
|
6385
5515
|
} catch (error) {
|
|
6386
|
-
|
|
5516
|
+
debugLogger6.debug("Failed to write export file:", error);
|
|
6387
5517
|
return {
|
|
6388
5518
|
type: "message",
|
|
6389
5519
|
messageType: "error",
|
|
6390
5520
|
content: `Failed to export session: ${error instanceof Error ? error.message : String(error)} (${exportFormat.displayName} target: "${targetFilepath}")`
|
|
6391
5521
|
};
|
|
6392
5522
|
}
|
|
6393
|
-
|
|
5523
|
+
debugLogger6.debug("Session export completed:", {
|
|
6394
5524
|
format: exportFormat.displayName,
|
|
6395
5525
|
filepath: target.filepath
|
|
6396
5526
|
});
|
|
@@ -6400,7 +5530,7 @@ async function exportSessionAction(context, args, exportFormat) {
|
|
|
6400
5530
|
content: `Session exported to ${exportFormat.displayName}: ${target.displayPath}`
|
|
6401
5531
|
};
|
|
6402
5532
|
} catch (error) {
|
|
6403
|
-
|
|
5533
|
+
debugLogger6.debug("Session export failed:", {
|
|
6404
5534
|
format: exportFormat.displayName,
|
|
6405
5535
|
target,
|
|
6406
5536
|
error
|
|
@@ -6496,7 +5626,7 @@ var exportCommand = {
|
|
|
6496
5626
|
|
|
6497
5627
|
// packages/cli/src/ui/commands/forkCommand.ts
|
|
6498
5628
|
init_esbuild_shims();
|
|
6499
|
-
var
|
|
5629
|
+
var debugLogger7 = createDebugLogger("FORK_COMMAND");
|
|
6500
5630
|
function deriveForkDescription(directive) {
|
|
6501
5631
|
const oneLine = directive.replace(/\s+/g, " ").trim();
|
|
6502
5632
|
return oneLine.length > 60 ? `${oneLine.slice(0, 57)}\u2026` : oneLine;
|
|
@@ -6552,7 +5682,7 @@ var forkCommand = {
|
|
|
6552
5682
|
try {
|
|
6553
5683
|
hasHistory = (config.getGeminiClient().getHistoryShallow() ?? []).length > 0;
|
|
6554
5684
|
} catch (error) {
|
|
6555
|
-
|
|
5685
|
+
debugLogger7.debug("Failed to read history before /fork:", error);
|
|
6556
5686
|
hasHistory = false;
|
|
6557
5687
|
}
|
|
6558
5688
|
if (!hasHistory) {
|
|
@@ -6612,7 +5742,7 @@ var forkCommand = {
|
|
|
6612
5742
|
]
|
|
6613
5743
|
});
|
|
6614
5744
|
} catch (error) {
|
|
6615
|
-
|
|
5745
|
+
debugLogger7.debug("Failed to record fork event in history:", error);
|
|
6616
5746
|
}
|
|
6617
5747
|
return {
|
|
6618
5748
|
type: "message",
|
|
@@ -6626,7 +5756,7 @@ var forkCommand = {
|
|
|
6626
5756
|
|
|
6627
5757
|
// packages/cli/src/ui/commands/extensionsCommand.ts
|
|
6628
5758
|
init_esbuild_shims();
|
|
6629
|
-
var
|
|
5759
|
+
var debugLogger8 = createDebugLogger("EXTENSIONS_COMMAND");
|
|
6630
5760
|
var EXTENSION_EXPLORE_URL = {
|
|
6631
5761
|
Gemini: "https://geminicli.com/extensions/",
|
|
6632
5762
|
ClaudeCode: "https://claudemarketplaces.com/"
|
|
@@ -6789,7 +5919,7 @@ async function installAction(context, args) {
|
|
|
6789
5919
|
}
|
|
6790
5920
|
const extensionManager = context.services.config?.getExtensionManager();
|
|
6791
5921
|
if (!(extensionManager instanceof ExtensionManager)) {
|
|
6792
|
-
|
|
5922
|
+
debugLogger8.error(
|
|
6793
5923
|
`Cannot ${context.invocation?.name} extensions in this environment`
|
|
6794
5924
|
);
|
|
6795
5925
|
return;
|
|
@@ -7727,7 +6857,7 @@ var hooksCommand = {
|
|
|
7727
6857
|
|
|
7728
6858
|
// packages/cli/src/ui/commands/ideCommand.ts
|
|
7729
6859
|
init_esbuild_shims();
|
|
7730
|
-
import
|
|
6860
|
+
import path6 from "node:path";
|
|
7731
6861
|
function getIdeStatusMessage(ideClient) {
|
|
7732
6862
|
const connection = ideClient.getConnectionStatus();
|
|
7733
6863
|
switch (connection.status) {
|
|
@@ -7757,13 +6887,13 @@ __name(getIdeStatusMessage, "getIdeStatusMessage");
|
|
|
7757
6887
|
function formatFileList(openFiles) {
|
|
7758
6888
|
const basenameCounts = /* @__PURE__ */ new Map();
|
|
7759
6889
|
for (const file of openFiles) {
|
|
7760
|
-
const basename3 =
|
|
6890
|
+
const basename3 = path6.basename(file.path);
|
|
7761
6891
|
basenameCounts.set(basename3, (basenameCounts.get(basename3) || 0) + 1);
|
|
7762
6892
|
}
|
|
7763
6893
|
const fileList = openFiles.map((file) => {
|
|
7764
|
-
const basename3 =
|
|
6894
|
+
const basename3 = path6.basename(file.path);
|
|
7765
6895
|
const isDuplicate = (basenameCounts.get(basename3) || 0) > 1;
|
|
7766
|
-
const parentDir =
|
|
6896
|
+
const parentDir = path6.basename(path6.dirname(file.path));
|
|
7767
6897
|
const displayName = isDuplicate ? `${basename3} (/${parentDir})` : basename3;
|
|
7768
6898
|
return ` - ${displayName}${file.isActive ? " (active)" : ""}`;
|
|
7769
6899
|
}).join("\n");
|
|
@@ -7925,7 +7055,7 @@ var ideCommand = /* @__PURE__ */ __name(async () => {
|
|
|
7925
7055
|
if (ideClient.getConnectionStatus().status === "connected" /* Connected */) {
|
|
7926
7056
|
break;
|
|
7927
7057
|
}
|
|
7928
|
-
await new Promise((
|
|
7058
|
+
await new Promise((resolve4) => setTimeout(resolve4, 500));
|
|
7929
7059
|
}
|
|
7930
7060
|
const { messageType, content } = getIdeStatusMessage(ideClient);
|
|
7931
7061
|
if (messageType === "error") {
|
|
@@ -8015,9 +7145,9 @@ init_esbuild_shims();
|
|
|
8015
7145
|
|
|
8016
7146
|
// packages/cli/src/config/claudeMcpImport.ts
|
|
8017
7147
|
init_esbuild_shims();
|
|
8018
|
-
import * as
|
|
8019
|
-
import * as
|
|
8020
|
-
import * as
|
|
7148
|
+
import * as fs6 from "node:fs";
|
|
7149
|
+
import * as os3 from "node:os";
|
|
7150
|
+
import * as path7 from "node:path";
|
|
8021
7151
|
var import_strip_json_comments = __toESM(require_strip_json_comments(), 1);
|
|
8022
7152
|
function isRecord(value) {
|
|
8023
7153
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
@@ -8038,7 +7168,7 @@ __name(emptyServerRecord, "emptyServerRecord");
|
|
|
8038
7168
|
function readJsonObject(filePath) {
|
|
8039
7169
|
let raw;
|
|
8040
7170
|
try {
|
|
8041
|
-
raw =
|
|
7171
|
+
raw = fs6.readFileSync(filePath, "utf-8");
|
|
8042
7172
|
} catch (error) {
|
|
8043
7173
|
if (isReadableConfigError(error) && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
|
|
8044
7174
|
return { found: false };
|
|
@@ -8087,7 +7217,7 @@ function copyMcpServers(value, sourcePath, servers, errors) {
|
|
|
8087
7217
|
}
|
|
8088
7218
|
__name(copyMcpServers, "copyMcpServers");
|
|
8089
7219
|
function normalizeProjectPath(projectPath) {
|
|
8090
|
-
return
|
|
7220
|
+
return path7.resolve(projectPath);
|
|
8091
7221
|
}
|
|
8092
7222
|
__name(normalizeProjectPath, "normalizeProjectPath");
|
|
8093
7223
|
function getClaudeProjectSettings(projects, cwd) {
|
|
@@ -8103,17 +7233,17 @@ function getClaudeProjectSettings(projects, cwd) {
|
|
|
8103
7233
|
return void 0;
|
|
8104
7234
|
}
|
|
8105
7235
|
__name(getClaudeProjectSettings, "getClaudeProjectSettings");
|
|
8106
|
-
function getClaudeCodeConfigPath(homeDir =
|
|
8107
|
-
return
|
|
7236
|
+
function getClaudeCodeConfigPath(homeDir = os3.homedir()) {
|
|
7237
|
+
return path7.join(homeDir, ".claude.json");
|
|
8108
7238
|
}
|
|
8109
7239
|
__name(getClaudeCodeConfigPath, "getClaudeCodeConfigPath");
|
|
8110
|
-
function getClaudeDesktopConfigPath(homeDir =
|
|
8111
|
-
if (
|
|
8112
|
-
const appData = env["APPDATA"] ??
|
|
8113
|
-
return
|
|
7240
|
+
function getClaudeDesktopConfigPath(homeDir = os3.homedir(), platform2 = process.platform, env = process.env) {
|
|
7241
|
+
if (platform2 === "win32") {
|
|
7242
|
+
const appData = env["APPDATA"] ?? path7.win32.join(homeDir, "AppData", "Roaming");
|
|
7243
|
+
return path7.win32.join(appData, "Claude", "claude_desktop_config.json");
|
|
8114
7244
|
}
|
|
8115
|
-
if (
|
|
8116
|
-
return
|
|
7245
|
+
if (platform2 === "darwin") {
|
|
7246
|
+
return path7.join(
|
|
8117
7247
|
homeDir,
|
|
8118
7248
|
"Library",
|
|
8119
7249
|
"Application Support",
|
|
@@ -8121,7 +7251,7 @@ function getClaudeDesktopConfigPath(homeDir = os4.homedir(), platform3 = process
|
|
|
8121
7251
|
"claude_desktop_config.json"
|
|
8122
7252
|
);
|
|
8123
7253
|
}
|
|
8124
|
-
return
|
|
7254
|
+
return path7.join(homeDir, ".config", "Claude", "claude_desktop_config.json");
|
|
8125
7255
|
}
|
|
8126
7256
|
__name(getClaudeDesktopConfigPath, "getClaudeDesktopConfigPath");
|
|
8127
7257
|
function loadMcpServersFromSettingsFile(filePath, label, source) {
|
|
@@ -8213,7 +7343,7 @@ __name(loadClaudeCodeJsonMcpServers, "loadClaudeCodeJsonMcpServers");
|
|
|
8213
7343
|
function loadClaudeCodeMcpSources(homeDir, cwd, scope) {
|
|
8214
7344
|
const candidates = scope === "project" ? [
|
|
8215
7345
|
loadMcpServersFromSettingsFile(
|
|
8216
|
-
|
|
7346
|
+
path7.join(cwd, ".claude", "settings.json"),
|
|
8217
7347
|
"Claude Code project settings",
|
|
8218
7348
|
"claude-code"
|
|
8219
7349
|
),
|
|
@@ -8221,7 +7351,7 @@ function loadClaudeCodeMcpSources(homeDir, cwd, scope) {
|
|
|
8221
7351
|
] : [
|
|
8222
7352
|
loadClaudeCodeJsonMcpServers(homeDir, cwd, scope),
|
|
8223
7353
|
loadMcpServersFromSettingsFile(
|
|
8224
|
-
|
|
7354
|
+
path7.join(homeDir, ".claude", "settings.json"),
|
|
8225
7355
|
"Claude Code global settings",
|
|
8226
7356
|
"claude-code"
|
|
8227
7357
|
)
|
|
@@ -8236,8 +7366,8 @@ function loadClaudeCodeMcpSources(homeDir, cwd, scope) {
|
|
|
8236
7366
|
});
|
|
8237
7367
|
}
|
|
8238
7368
|
__name(loadClaudeCodeMcpSources, "loadClaudeCodeMcpSources");
|
|
8239
|
-
function loadClaudeDesktopMcpServers(homeDir,
|
|
8240
|
-
const filePath = getClaudeDesktopConfigPath(homeDir,
|
|
7369
|
+
function loadClaudeDesktopMcpServers(homeDir, platform2, env) {
|
|
7370
|
+
const filePath = getClaudeDesktopConfigPath(homeDir, platform2, env);
|
|
8241
7371
|
const errors = [];
|
|
8242
7372
|
const servers = emptyServerRecord();
|
|
8243
7373
|
const parsed = readJsonObject(filePath);
|
|
@@ -8273,14 +7403,14 @@ function loadClaudeDesktopMcpServers(homeDir, platform3, env) {
|
|
|
8273
7403
|
}
|
|
8274
7404
|
__name(loadClaudeDesktopMcpServers, "loadClaudeDesktopMcpServers");
|
|
8275
7405
|
function loadClaudeMcpSources(options) {
|
|
8276
|
-
const homeDir = options.homeDir ??
|
|
7406
|
+
const homeDir = options.homeDir ?? os3.homedir();
|
|
8277
7407
|
const cwd = options.cwd ?? process.cwd();
|
|
8278
|
-
const
|
|
7408
|
+
const platform2 = options.platform ?? process.platform;
|
|
8279
7409
|
const env = options.env ?? process.env;
|
|
8280
7410
|
const scope = options.scope ?? "user";
|
|
8281
7411
|
const sources = options.source === "all" ? ["claude-code", "claude-desktop"] : [options.source];
|
|
8282
7412
|
return sources.flatMap(
|
|
8283
|
-
(source) => source === "claude-code" ? loadClaudeCodeMcpSources(homeDir, cwd, scope) : [loadClaudeDesktopMcpServers(homeDir,
|
|
7413
|
+
(source) => source === "claude-code" ? loadClaudeCodeMcpSources(homeDir, cwd, scope) : [loadClaudeDesktopMcpServers(homeDir, platform2, env)]
|
|
8284
7414
|
);
|
|
8285
7415
|
}
|
|
8286
7416
|
__name(loadClaudeMcpSources, "loadClaudeMcpSources");
|
|
@@ -8633,8 +7763,8 @@ ${usage()}`
|
|
|
8633
7763
|
|
|
8634
7764
|
// packages/cli/src/ui/commands/initCommand.ts
|
|
8635
7765
|
init_esbuild_shims();
|
|
8636
|
-
import * as
|
|
8637
|
-
import * as
|
|
7766
|
+
import * as fs7 from "node:fs";
|
|
7767
|
+
import * as path8 from "node:path";
|
|
8638
7768
|
var import_react2 = __toESM(require_react(), 1);
|
|
8639
7769
|
var initCommand = {
|
|
8640
7770
|
name: "init",
|
|
@@ -8653,11 +7783,11 @@ var initCommand = {
|
|
|
8653
7783
|
}
|
|
8654
7784
|
const targetDir = context.services.config.getTargetDir();
|
|
8655
7785
|
const contextFileName = getCurrentGeminiMdFilename();
|
|
8656
|
-
const contextFilePath =
|
|
7786
|
+
const contextFilePath = path8.join(targetDir, contextFileName);
|
|
8657
7787
|
try {
|
|
8658
|
-
if (
|
|
7788
|
+
if (fs7.existsSync(contextFilePath)) {
|
|
8659
7789
|
try {
|
|
8660
|
-
const existing =
|
|
7790
|
+
const existing = fs7.readFileSync(contextFilePath, "utf8");
|
|
8661
7791
|
if (existing && existing.trim().length > 0) {
|
|
8662
7792
|
if (!context.overwriteConfirmed) {
|
|
8663
7793
|
return {
|
|
@@ -8679,7 +7809,7 @@ var initCommand = {
|
|
|
8679
7809
|
}
|
|
8680
7810
|
}
|
|
8681
7811
|
try {
|
|
8682
|
-
|
|
7812
|
+
fs7.writeFileSync(contextFilePath, "", "utf8");
|
|
8683
7813
|
context.ui.addItem(
|
|
8684
7814
|
{
|
|
8685
7815
|
type: "info",
|
|
@@ -8744,7 +7874,7 @@ Write the complete content to the \`${contextFileName}\` file. The output must b
|
|
|
8744
7874
|
|
|
8745
7875
|
// packages/cli/src/ui/commands/languageCommand.ts
|
|
8746
7876
|
init_esbuild_shims();
|
|
8747
|
-
var
|
|
7877
|
+
var debugLogger9 = createDebugLogger("LANGUAGE_COMMAND");
|
|
8748
7878
|
function getCurrentOutputLanguage(context) {
|
|
8749
7879
|
const settingValue = context?.services?.settings?.merged?.general?.outputLanguage || OUTPUT_LANGUAGE_AUTO;
|
|
8750
7880
|
const resolved = resolveOutputLanguage(settingValue);
|
|
@@ -8775,7 +7905,7 @@ async function setUiLanguage(context, lang) {
|
|
|
8775
7905
|
try {
|
|
8776
7906
|
services.settings.setValue("User" /* User */, "general.language", lang);
|
|
8777
7907
|
} catch (error) {
|
|
8778
|
-
|
|
7908
|
+
debugLogger9.warn("Failed to save language setting:", error);
|
|
8779
7909
|
}
|
|
8780
7910
|
}
|
|
8781
7911
|
context.ui.reloadCommands();
|
|
@@ -8802,7 +7932,7 @@ async function setOutputLanguage(context, language) {
|
|
|
8802
7932
|
settingValue
|
|
8803
7933
|
);
|
|
8804
7934
|
} catch (error) {
|
|
8805
|
-
|
|
7935
|
+
debugLogger9.warn("Failed to save output language setting:", error);
|
|
8806
7936
|
}
|
|
8807
7937
|
}
|
|
8808
7938
|
const config = context.services.config;
|
|
@@ -8811,7 +7941,7 @@ async function setOutputLanguage(context, language) {
|
|
|
8811
7941
|
await config.refreshHierarchicalMemory();
|
|
8812
7942
|
await config.getGeminiClient().refreshSystemInstruction();
|
|
8813
7943
|
} catch (error) {
|
|
8814
|
-
|
|
7944
|
+
debugLogger9.warn(
|
|
8815
7945
|
"Failed to apply output language to running session:",
|
|
8816
7946
|
error
|
|
8817
7947
|
);
|
|
@@ -9035,7 +8165,7 @@ var mcpCommand = {
|
|
|
9035
8165
|
|
|
9036
8166
|
// packages/cli/src/ui/commands/dreamCommand.ts
|
|
9037
8167
|
init_esbuild_shims();
|
|
9038
|
-
import * as
|
|
8168
|
+
import * as path9 from "node:path";
|
|
9039
8169
|
var dreamCommand = {
|
|
9040
8170
|
name: "dream",
|
|
9041
8171
|
get description() {
|
|
@@ -9055,7 +8185,7 @@ var dreamCommand = {
|
|
|
9055
8185
|
try {
|
|
9056
8186
|
const projectRoot = config.getProjectRoot();
|
|
9057
8187
|
const memoryRoot = getAutoMemoryRoot(projectRoot);
|
|
9058
|
-
const transcriptDir =
|
|
8188
|
+
const transcriptDir = path9.join(
|
|
9059
8189
|
new Storage(projectRoot).getProjectDir(),
|
|
9060
8190
|
"chats"
|
|
9061
8191
|
);
|
|
@@ -9156,17 +8286,44 @@ init_esbuild_shims();
|
|
|
9156
8286
|
var MAIN_MODEL_CONFIGURATION_HINT = "Configure models in settings.modelProviders and ensure the required environment variables are set. In interactive mode, run /auth to configure or switch providers, or run /model without arguments to choose from configured models.";
|
|
9157
8287
|
var FAST_MODEL_CONFIGURATION_HINT = "Configure models in settings.modelProviders and ensure the required environment variables are set. In interactive mode, run /auth to configure or switch providers, or run /model --fast without a model to choose from configured models.";
|
|
9158
8288
|
var VISION_MODEL_CONFIGURATION_HINT = "Configure an image-capable model in settings.modelProviders and ensure the required environment variables are set. Run /model --vision <model-id> to set it, or leave it unset to auto-pick a same-provider vision model.";
|
|
8289
|
+
function parseScopeFlags(args) {
|
|
8290
|
+
let scopeOverride;
|
|
8291
|
+
let remaining = args;
|
|
8292
|
+
const hasProject = /(?:^|\s)--project(?:\s|$)/.test(remaining);
|
|
8293
|
+
const hasGlobal = /(?:^|\s)--global(?:\s|$)/.test(remaining);
|
|
8294
|
+
if (hasProject) {
|
|
8295
|
+
scopeOverride = "Workspace" /* Workspace */;
|
|
8296
|
+
remaining = remaining.replace(/(?:^|\s)--project(?:\s|$)/, " ").trim();
|
|
8297
|
+
} else if (hasGlobal) {
|
|
8298
|
+
scopeOverride = "User" /* User */;
|
|
8299
|
+
remaining = remaining.replace(/(?:^|\s)--global(?:\s|$)/, " ").trim();
|
|
8300
|
+
}
|
|
8301
|
+
return { scopeOverride, remaining, hasProject, hasGlobal };
|
|
8302
|
+
}
|
|
8303
|
+
__name(parseScopeFlags, "parseScopeFlags");
|
|
8304
|
+
function resolveScope(settings, scopeOverride) {
|
|
8305
|
+
return scopeOverride ?? getPersistScopeForModelSelection(settings);
|
|
8306
|
+
}
|
|
8307
|
+
__name(resolveScope, "resolveScope");
|
|
8308
|
+
function persistScopeSpread(scopeOverride) {
|
|
8309
|
+
if (scopeOverride === "Workspace" /* Workspace */)
|
|
8310
|
+
return { persistScope: "workspace" };
|
|
8311
|
+
if (scopeOverride === "User" /* User */)
|
|
8312
|
+
return { persistScope: "user" };
|
|
8313
|
+
return {};
|
|
8314
|
+
}
|
|
8315
|
+
__name(persistScopeSpread, "persistScopeSpread");
|
|
9159
8316
|
function formatVisionModelSettingForDisplay(setting) {
|
|
9160
8317
|
const parsed = parseVisionModelSetting(setting);
|
|
9161
8318
|
if (!parsed) return setting.replace(/\0/g, "\\0");
|
|
9162
8319
|
return parsed.baseUrl ? `${parsed.selector} (${parsed.baseUrl})` : parsed.selector;
|
|
9163
8320
|
}
|
|
9164
8321
|
__name(formatVisionModelSettingForDisplay, "formatVisionModelSettingForDisplay");
|
|
9165
|
-
function persistSetting(settings,
|
|
9166
|
-
settings.setValue(
|
|
8322
|
+
function persistSetting(settings, path18, value, scopeOverride) {
|
|
8323
|
+
settings.setValue(resolveScope(settings, scopeOverride), path18, value);
|
|
9167
8324
|
}
|
|
9168
8325
|
__name(persistSetting, "persistSetting");
|
|
9169
|
-
async function switchMainModel(config, settings, currentAuthType, modelArg) {
|
|
8326
|
+
async function switchMainModel(config, settings, currentAuthType, modelArg, scopeOverride) {
|
|
9170
8327
|
const parsed = parseAcpModelOption(modelArg);
|
|
9171
8328
|
if (parsed.authType) {
|
|
9172
8329
|
await config.switchModel(
|
|
@@ -9174,14 +8331,19 @@ async function switchMainModel(config, settings, currentAuthType, modelArg) {
|
|
|
9174
8331
|
parsed.modelId,
|
|
9175
8332
|
parsed.authType !== currentAuthType && parsed.authType === "qwen-oauth" /* QWEN_OAUTH */ ? { requireCachedCredentials: true } : void 0
|
|
9176
8333
|
);
|
|
9177
|
-
persistSetting(
|
|
9178
|
-
|
|
9179
|
-
|
|
8334
|
+
persistSetting(
|
|
8335
|
+
settings,
|
|
8336
|
+
"security.auth.selectedType",
|
|
8337
|
+
parsed.authType,
|
|
8338
|
+
scopeOverride
|
|
8339
|
+
);
|
|
8340
|
+
persistSetting(settings, "model.name", parsed.modelId, scopeOverride);
|
|
8341
|
+
persistSetting(settings, "model.baseUrl", "", scopeOverride);
|
|
9180
8342
|
return parsed.modelId;
|
|
9181
8343
|
}
|
|
9182
8344
|
await config.switchModel(currentAuthType, modelArg, void 0);
|
|
9183
|
-
persistSetting(settings, "model.name", modelArg);
|
|
9184
|
-
persistSetting(settings, "model.baseUrl", "");
|
|
8345
|
+
persistSetting(settings, "model.name", modelArg, scopeOverride);
|
|
8346
|
+
persistSetting(settings, "model.baseUrl", "", scopeOverride);
|
|
9185
8347
|
return modelArg;
|
|
9186
8348
|
}
|
|
9187
8349
|
__name(switchMainModel, "switchMainModel");
|
|
@@ -9287,10 +8449,10 @@ var modelCommand = {
|
|
|
9287
8449
|
completionPriority: 100,
|
|
9288
8450
|
get description() {
|
|
9289
8451
|
return t(
|
|
9290
|
-
"Switch the model for this session (--fast for suggestion model, --voice for voice transcription model, --vision for the vision bridge model, [model-id] to switch immediately, or [model-id] [prompt] to run a one-off prompt on another model; the inline prompt is sent verbatim without @file expansion)."
|
|
8452
|
+
"Switch the model for this session (--fast for suggestion model, --voice for voice transcription model, --vision for the vision bridge model, --project to persist to project settings, --global to persist to user settings, [model-id] to switch immediately, or [model-id] [prompt] to run a one-off prompt on another model; the inline prompt is sent verbatim without @file expansion)."
|
|
9291
8453
|
);
|
|
9292
8454
|
},
|
|
9293
|
-
argumentHint: "[--fast|--voice|--vision] [<model-id>] | <model-id> <prompt>",
|
|
8455
|
+
argumentHint: "[--fast|--voice|--vision] [--project|--global] [<model-id>] | <model-id> <prompt>",
|
|
9294
8456
|
kind: "built-in" /* BUILT_IN */,
|
|
9295
8457
|
supportedModes: ["interactive", "non_interactive", "acp"],
|
|
9296
8458
|
completion: /* @__PURE__ */ __name(async (context, partialArg) => {
|
|
@@ -9311,6 +8473,18 @@ var modelCommand = {
|
|
|
9311
8473
|
description: t(
|
|
9312
8474
|
"Set the image-capable model used to transcribe images for a text-only main model"
|
|
9313
8475
|
)
|
|
8476
|
+
},
|
|
8477
|
+
{
|
|
8478
|
+
value: "--project",
|
|
8479
|
+
description: t(
|
|
8480
|
+
"Persist the model selection to the project settings (workspace scope)"
|
|
8481
|
+
)
|
|
8482
|
+
},
|
|
8483
|
+
{
|
|
8484
|
+
value: "--global",
|
|
8485
|
+
description: t(
|
|
8486
|
+
"Persist the model selection to the user settings (global scope)"
|
|
8487
|
+
)
|
|
9314
8488
|
}
|
|
9315
8489
|
].filter((item) => item.value.startsWith(partialArg));
|
|
9316
8490
|
if (flagCompletions.length > 0) {
|
|
@@ -9319,17 +8493,10 @@ var modelCommand = {
|
|
|
9319
8493
|
const trimmed = partialArg.trim();
|
|
9320
8494
|
if (trimmed) {
|
|
9321
8495
|
let mode = "main";
|
|
9322
|
-
|
|
9323
|
-
if (
|
|
9324
|
-
|
|
9325
|
-
|
|
9326
|
-
} else if (trimmed.startsWith("--voice ")) {
|
|
9327
|
-
mode = "voice";
|
|
9328
|
-
modelPrefix = trimmed.slice("--voice ".length);
|
|
9329
|
-
} else if (trimmed.startsWith("--vision ")) {
|
|
9330
|
-
mode = "vision";
|
|
9331
|
-
modelPrefix = trimmed.slice("--vision ".length);
|
|
9332
|
-
}
|
|
8496
|
+
const modelPrefix = trimmed.replace(/(?:^|\s)--fast(?:\s|$)/, " ").replace(/(?:^|\s)--voice(?:\s|$)/, " ").replace(/(?:^|\s)--vision(?:\s|$)/, " ").replace(/(?:^|\s)--project(?:\s|$)/, " ").replace(/(?:^|\s)--global(?:\s|$)/, " ").trim();
|
|
8497
|
+
if (/(?:^|\s)--fast(?:\s|$)/.test(trimmed)) mode = "fast";
|
|
8498
|
+
else if (/(?:^|\s)--voice(?:\s|$)/.test(trimmed)) mode = "voice";
|
|
8499
|
+
else if (/(?:^|\s)--vision(?:\s|$)/.test(trimmed)) mode = "vision";
|
|
9333
8500
|
return getAvailableModelIds(context, mode).filter(
|
|
9334
8501
|
(id) => id.startsWith(modelPrefix)
|
|
9335
8502
|
);
|
|
@@ -9349,7 +8516,30 @@ var modelCommand = {
|
|
|
9349
8516
|
content: t("Configuration not available.")
|
|
9350
8517
|
};
|
|
9351
8518
|
}
|
|
9352
|
-
const
|
|
8519
|
+
const rawArgs = context.invocation?.args?.trim() || actionArgs.trim();
|
|
8520
|
+
const {
|
|
8521
|
+
scopeOverride,
|
|
8522
|
+
remaining: args,
|
|
8523
|
+
hasProject,
|
|
8524
|
+
hasGlobal
|
|
8525
|
+
} = parseScopeFlags(rawArgs);
|
|
8526
|
+
if (hasProject && hasGlobal) {
|
|
8527
|
+
return {
|
|
8528
|
+
type: "message",
|
|
8529
|
+
messageType: "error",
|
|
8530
|
+
content: t(
|
|
8531
|
+
"Cannot use both --project and --global. Choose one scope flag."
|
|
8532
|
+
)
|
|
8533
|
+
};
|
|
8534
|
+
}
|
|
8535
|
+
if (scopeOverride === "Workspace" /* Workspace */ && settings && !settings.isTrusted) {
|
|
8536
|
+
return {
|
|
8537
|
+
type: "message",
|
|
8538
|
+
messageType: "error",
|
|
8539
|
+
content: t("Workspace is untrusted; run /trust first or use --global.")
|
|
8540
|
+
};
|
|
8541
|
+
}
|
|
8542
|
+
const scopeSuffix = scopeOverride === "Workspace" /* Workspace */ ? t(" (this project)") : scopeOverride === "User" /* User */ ? t(" (global)") : "";
|
|
9353
8543
|
const isVoiceModelCommand = args === "--voice" || args.startsWith("--voice ");
|
|
9354
8544
|
if (isVoiceModelCommand) {
|
|
9355
8545
|
const modelName2 = args.replace("--voice", "").trim();
|
|
@@ -9367,7 +8557,8 @@ var modelCommand = {
|
|
|
9367
8557
|
}
|
|
9368
8558
|
return {
|
|
9369
8559
|
type: "dialog",
|
|
9370
|
-
dialog: "voice-model"
|
|
8560
|
+
dialog: "voice-model",
|
|
8561
|
+
...persistScopeSpread(scopeOverride)
|
|
9371
8562
|
};
|
|
9372
8563
|
}
|
|
9373
8564
|
if (!settings) {
|
|
@@ -9406,11 +8597,11 @@ var modelCommand = {
|
|
|
9406
8597
|
content: formatUnsupportedVoiceModelMessage(modelName2)
|
|
9407
8598
|
};
|
|
9408
8599
|
}
|
|
9409
|
-
persistSetting(settings, "voiceModel", modelName2);
|
|
8600
|
+
persistSetting(settings, "voiceModel", modelName2, scopeOverride);
|
|
9410
8601
|
return {
|
|
9411
8602
|
type: "message",
|
|
9412
8603
|
messageType: "info",
|
|
9413
|
-
content: t("Voice Model") + ": " + modelName2
|
|
8604
|
+
content: t("Voice Model") + ": " + modelName2 + scopeSuffix
|
|
9414
8605
|
};
|
|
9415
8606
|
}
|
|
9416
8607
|
const isFastModelCommand = args === "--fast" || args.startsWith("--fast ");
|
|
@@ -9428,7 +8619,8 @@ Use "/model --fast <model-id>" to set fast model.`
|
|
|
9428
8619
|
}
|
|
9429
8620
|
return {
|
|
9430
8621
|
type: "dialog",
|
|
9431
|
-
dialog: "fast-model"
|
|
8622
|
+
dialog: "fast-model",
|
|
8623
|
+
...persistScopeSpread(scopeOverride)
|
|
9432
8624
|
};
|
|
9433
8625
|
}
|
|
9434
8626
|
if (!settings) {
|
|
@@ -9474,12 +8666,12 @@ Use "/model --fast <model-id>" to set fast model.`
|
|
|
9474
8666
|
) : formatUnavailableFastModelMessage(modelName2, availableModels)
|
|
9475
8667
|
};
|
|
9476
8668
|
}
|
|
9477
|
-
persistSetting(settings, "fastModel", modelName2);
|
|
8669
|
+
persistSetting(settings, "fastModel", modelName2, scopeOverride);
|
|
9478
8670
|
config.setFastModel(modelName2);
|
|
9479
8671
|
return {
|
|
9480
8672
|
type: "message",
|
|
9481
8673
|
messageType: "info",
|
|
9482
|
-
content: t("Fast Model") + ": " + modelName2
|
|
8674
|
+
content: t("Fast Model") + ": " + modelName2 + scopeSuffix
|
|
9483
8675
|
};
|
|
9484
8676
|
}
|
|
9485
8677
|
const isVisionModelCommand = args === "--vision" || args.startsWith("--vision ");
|
|
@@ -9501,7 +8693,8 @@ Use "/model --fast <model-id>" to set fast model.`
|
|
|
9501
8693
|
}
|
|
9502
8694
|
return {
|
|
9503
8695
|
type: "dialog",
|
|
9504
|
-
dialog: "vision-model"
|
|
8696
|
+
dialog: "vision-model",
|
|
8697
|
+
...persistScopeSpread(scopeOverride)
|
|
9505
8698
|
};
|
|
9506
8699
|
}
|
|
9507
8700
|
if (!settings) {
|
|
@@ -9561,14 +8754,14 @@ Use "/model --fast <model-id>" to set fast model.`
|
|
|
9561
8754
|
}
|
|
9562
8755
|
const qualifiedModelName = `${selector.authType ?? matched.authType}:${selector.modelId}`;
|
|
9563
8756
|
const visionModel = matched.baseUrl ? `${qualifiedModelName}\0${matched.baseUrl}` : qualifiedModelName;
|
|
9564
|
-
persistSetting(settings, "visionModel", visionModel);
|
|
8757
|
+
persistSetting(settings, "visionModel", visionModel, scopeOverride);
|
|
9565
8758
|
config.setVisionModel(visionModel);
|
|
9566
8759
|
const visionWarning = isImageCapable(matched) ? "" : `
|
|
9567
8760
|
${formatNonVisionModelWarning(modelName2)}`;
|
|
9568
8761
|
return {
|
|
9569
8762
|
type: "message",
|
|
9570
8763
|
messageType: "info",
|
|
9571
|
-
content: t("Vision Model") + ": " + modelName2 + visionWarning
|
|
8764
|
+
content: t("Vision Model") + ": " + modelName2 + scopeSuffix + visionWarning
|
|
9572
8765
|
};
|
|
9573
8766
|
}
|
|
9574
8767
|
const contentGeneratorConfig = config.getContentGeneratorConfig();
|
|
@@ -9618,6 +8811,17 @@ ${formatNonVisionModelWarning(modelName2)}`;
|
|
|
9618
8811
|
)
|
|
9619
8812
|
};
|
|
9620
8813
|
}
|
|
8814
|
+
if (scopeOverride) {
|
|
8815
|
+
const scopeFlag = hasProject ? "--project" : hasGlobal ? "--global" : "";
|
|
8816
|
+
return {
|
|
8817
|
+
type: "message",
|
|
8818
|
+
messageType: "error",
|
|
8819
|
+
content: t(
|
|
8820
|
+
"Cannot combine {{flag}} with an inline prompt. Run '/model {{flag}} {{model}}' first, then send your prompt.",
|
|
8821
|
+
{ flag: scopeFlag }
|
|
8822
|
+
)
|
|
8823
|
+
};
|
|
8824
|
+
}
|
|
9621
8825
|
const sameAuthType = targetAuthType === authType;
|
|
9622
8826
|
if (!sameAuthType || !isInlineModelOverrideAllowed(config, parsed.modelId)) {
|
|
9623
8827
|
return {
|
|
@@ -9646,12 +8850,13 @@ ${formatNonVisionModelWarning(modelName2)}`;
|
|
|
9646
8850
|
config,
|
|
9647
8851
|
settings,
|
|
9648
8852
|
authType,
|
|
9649
|
-
modelName
|
|
8853
|
+
modelName,
|
|
8854
|
+
scopeOverride
|
|
9650
8855
|
);
|
|
9651
8856
|
return {
|
|
9652
8857
|
type: "message",
|
|
9653
8858
|
messageType: "info",
|
|
9654
|
-
content: t("Model") + ": " + effectiveModelName
|
|
8859
|
+
content: t("Model") + ": " + effectiveModelName + scopeSuffix
|
|
9655
8860
|
};
|
|
9656
8861
|
}
|
|
9657
8862
|
if (context.executionMode !== "interactive") {
|
|
@@ -9659,13 +8864,16 @@ ${formatNonVisionModelWarning(modelName2)}`;
|
|
|
9659
8864
|
return {
|
|
9660
8865
|
type: "message",
|
|
9661
8866
|
messageType: "info",
|
|
9662
|
-
content:
|
|
9663
|
-
|
|
8867
|
+
content: t(
|
|
8868
|
+
'Current model: {{model}}\nUse "/model <model-id>" to switch models, "/model --fast <model-id>" to set the fast model, "/model --project <model-id>" to persist to project settings, or "/model --global <model-id>" to persist to user settings.',
|
|
8869
|
+
{ model: currentModel }
|
|
8870
|
+
)
|
|
9664
8871
|
};
|
|
9665
8872
|
}
|
|
9666
8873
|
return {
|
|
9667
8874
|
type: "dialog",
|
|
9668
|
-
dialog: "model"
|
|
8875
|
+
dialog: "model",
|
|
8876
|
+
...persistScopeSpread(scopeOverride)
|
|
9669
8877
|
};
|
|
9670
8878
|
}, "action")
|
|
9671
8879
|
};
|
|
@@ -10097,8 +9305,8 @@ var renameCommand = {
|
|
|
10097
9305
|
|
|
10098
9306
|
// packages/cli/src/ui/commands/restoreCommand.ts
|
|
10099
9307
|
init_esbuild_shims();
|
|
10100
|
-
import * as
|
|
10101
|
-
import
|
|
9308
|
+
import * as fs8 from "node:fs/promises";
|
|
9309
|
+
import path10 from "node:path";
|
|
10102
9310
|
async function restoreAction(context, args) {
|
|
10103
9311
|
const { services, ui } = context;
|
|
10104
9312
|
const { config } = services;
|
|
@@ -10112,8 +9320,8 @@ async function restoreAction(context, args) {
|
|
|
10112
9320
|
};
|
|
10113
9321
|
}
|
|
10114
9322
|
try {
|
|
10115
|
-
await
|
|
10116
|
-
const files = await
|
|
9323
|
+
await fs8.mkdir(checkpointDir, { recursive: true });
|
|
9324
|
+
const files = await fs8.readdir(checkpointDir);
|
|
10117
9325
|
const jsonFiles = files.filter((file) => file.endsWith(".json"));
|
|
10118
9326
|
if (!args) {
|
|
10119
9327
|
if (jsonFiles.length === 0) {
|
|
@@ -10148,8 +9356,8 @@ ${fileList}`
|
|
|
10148
9356
|
content: `File not found: ${selectedFile}`
|
|
10149
9357
|
};
|
|
10150
9358
|
}
|
|
10151
|
-
const filePath =
|
|
10152
|
-
const data = await
|
|
9359
|
+
const filePath = path10.join(checkpointDir, selectedFile);
|
|
9360
|
+
const data = await fs8.readFile(filePath, "utf-8");
|
|
10153
9361
|
const toolCallData = JSON.parse(data);
|
|
10154
9362
|
if (toolCallData.commitHash && !toolCallData.promptId) {
|
|
10155
9363
|
return {
|
|
@@ -10235,7 +9443,7 @@ async function completion(context, _partialArg) {
|
|
|
10235
9443
|
return [];
|
|
10236
9444
|
}
|
|
10237
9445
|
try {
|
|
10238
|
-
const files = await
|
|
9446
|
+
const files = await fs8.readdir(checkpointDir);
|
|
10239
9447
|
return files.filter((file) => file.endsWith(".json")).map((file) => file.replace(".json", ""));
|
|
10240
9448
|
} catch (_err) {
|
|
10241
9449
|
return [];
|
|
@@ -10422,9 +9630,9 @@ ${lines.join("\n")}`
|
|
|
10422
9630
|
|
|
10423
9631
|
// packages/cli/src/ui/commands/statsCommand.ts
|
|
10424
9632
|
init_esbuild_shims();
|
|
10425
|
-
import * as
|
|
9633
|
+
import * as fs9 from "node:fs/promises";
|
|
10426
9634
|
import { randomUUID } from "node:crypto";
|
|
10427
|
-
import
|
|
9635
|
+
import path11 from "node:path";
|
|
10428
9636
|
var VALID_EXPORT_FORMATS = /* @__PURE__ */ new Set(["csv", "json"]);
|
|
10429
9637
|
var EMPTY_SKILL_METRICS = {
|
|
10430
9638
|
totalCalls: 0,
|
|
@@ -10621,12 +9829,12 @@ async function realpathNearestExisting2(targetDirectory, cwd) {
|
|
|
10621
9829
|
let currentDirectory = targetDirectory;
|
|
10622
9830
|
while (isSubpath(cwd, currentDirectory)) {
|
|
10623
9831
|
try {
|
|
10624
|
-
return await
|
|
9832
|
+
return await fs9.realpath(currentDirectory);
|
|
10625
9833
|
} catch (error) {
|
|
10626
9834
|
if (!isNotFoundError(error)) {
|
|
10627
9835
|
throw error;
|
|
10628
9836
|
}
|
|
10629
|
-
const parentDirectory =
|
|
9837
|
+
const parentDirectory = path11.dirname(currentDirectory);
|
|
10630
9838
|
if (parentDirectory === currentDirectory) {
|
|
10631
9839
|
break;
|
|
10632
9840
|
}
|
|
@@ -10640,7 +9848,7 @@ async function realpathNearestExisting2(targetDirectory, cwd) {
|
|
|
10640
9848
|
__name(realpathNearestExisting2, "realpathNearestExisting");
|
|
10641
9849
|
async function validateStatsExportExistingParent(cwd, outputDirectory) {
|
|
10642
9850
|
const [realCwd, realExistingParent] = await Promise.all([
|
|
10643
|
-
|
|
9851
|
+
fs9.realpath(cwd),
|
|
10644
9852
|
realpathNearestExisting2(outputDirectory, cwd)
|
|
10645
9853
|
]);
|
|
10646
9854
|
if (!isSubpath(realCwd, realExistingParent)) {
|
|
@@ -10651,8 +9859,8 @@ async function validateStatsExportExistingParent(cwd, outputDirectory) {
|
|
|
10651
9859
|
__name(validateStatsExportExistingParent, "validateStatsExportExistingParent");
|
|
10652
9860
|
async function validateStatsExportDirectory(cwd, outputDirectory) {
|
|
10653
9861
|
const [realCwd, realOutputDirectory] = await Promise.all([
|
|
10654
|
-
|
|
10655
|
-
|
|
9862
|
+
fs9.realpath(cwd),
|
|
9863
|
+
fs9.realpath(outputDirectory)
|
|
10656
9864
|
]);
|
|
10657
9865
|
if (!isSubpath(realCwd, realOutputDirectory)) {
|
|
10658
9866
|
return statsExportPathError();
|
|
@@ -10661,7 +9869,7 @@ async function validateStatsExportDirectory(cwd, outputDirectory) {
|
|
|
10661
9869
|
}
|
|
10662
9870
|
__name(validateStatsExportDirectory, "validateStatsExportDirectory");
|
|
10663
9871
|
function validateStatsExportPathShape(targetPath) {
|
|
10664
|
-
if (process.platform === "win32" &&
|
|
9872
|
+
if (process.platform === "win32" && path11.basename(targetPath).includes(":")) {
|
|
10665
9873
|
return statsExportPathError();
|
|
10666
9874
|
}
|
|
10667
9875
|
return void 0;
|
|
@@ -10669,7 +9877,7 @@ function validateStatsExportPathShape(targetPath) {
|
|
|
10669
9877
|
__name(validateStatsExportPathShape, "validateStatsExportPathShape");
|
|
10670
9878
|
async function validateStatsExportFileTarget(targetPath) {
|
|
10671
9879
|
try {
|
|
10672
|
-
const stats = await
|
|
9880
|
+
const stats = await fs9.lstat(targetPath);
|
|
10673
9881
|
if (stats.isSymbolicLink() || !stats.isFile()) {
|
|
10674
9882
|
return statsExportPathError();
|
|
10675
9883
|
}
|
|
@@ -10685,7 +9893,7 @@ __name(validateStatsExportFileTarget, "validateStatsExportFileTarget");
|
|
|
10685
9893
|
async function validateStatsExportFinalFile(cwd, targetPath) {
|
|
10686
9894
|
let stats;
|
|
10687
9895
|
try {
|
|
10688
|
-
stats = await
|
|
9896
|
+
stats = await fs9.lstat(targetPath);
|
|
10689
9897
|
} catch (error) {
|
|
10690
9898
|
if (isNotFoundError(error)) {
|
|
10691
9899
|
return statsExportTargetMissingError(targetPath);
|
|
@@ -10696,8 +9904,8 @@ async function validateStatsExportFinalFile(cwd, targetPath) {
|
|
|
10696
9904
|
return statsExportPathError();
|
|
10697
9905
|
}
|
|
10698
9906
|
const [realCwd, realTargetPath] = await Promise.all([
|
|
10699
|
-
|
|
10700
|
-
|
|
9907
|
+
fs9.realpath(cwd),
|
|
9908
|
+
fs9.realpath(targetPath)
|
|
10701
9909
|
]);
|
|
10702
9910
|
if (!isSubpath(realCwd, realTargetPath)) {
|
|
10703
9911
|
return statsExportPathError();
|
|
@@ -10706,9 +9914,9 @@ async function validateStatsExportFinalFile(cwd, targetPath) {
|
|
|
10706
9914
|
}
|
|
10707
9915
|
__name(validateStatsExportFinalFile, "validateStatsExportFinalFile");
|
|
10708
9916
|
function createTemporaryExportPath(outputDirectory, targetPath) {
|
|
10709
|
-
return
|
|
9917
|
+
return path11.join(
|
|
10710
9918
|
outputDirectory,
|
|
10711
|
-
`.${
|
|
9919
|
+
`.${path11.basename(targetPath)}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`
|
|
10712
9920
|
);
|
|
10713
9921
|
}
|
|
10714
9922
|
__name(createTemporaryExportPath, "createTemporaryExportPath");
|
|
@@ -10718,8 +9926,8 @@ function isSamePath(leftPath, rightPath) {
|
|
|
10718
9926
|
__name(isSamePath, "isSamePath");
|
|
10719
9927
|
async function validateStatsExportDirectoryIdentity(cwd, outputDirectory, expectedRealOutputDirectory) {
|
|
10720
9928
|
const [realCwd, realOutputDirectory] = await Promise.all([
|
|
10721
|
-
|
|
10722
|
-
|
|
9929
|
+
fs9.realpath(cwd),
|
|
9930
|
+
fs9.realpath(outputDirectory)
|
|
10723
9931
|
]);
|
|
10724
9932
|
if (!isSubpath(realCwd, realOutputDirectory) || !isSamePath(expectedRealOutputDirectory, realOutputDirectory)) {
|
|
10725
9933
|
return statsExportPathError();
|
|
@@ -10736,12 +9944,12 @@ async function writeStatsExportFileAtomically(cwd, outputDirectory, targetPath,
|
|
|
10736
9944
|
return initialDirectoryError;
|
|
10737
9945
|
}
|
|
10738
9946
|
const [realCwd, realOutputDirectory] = await Promise.all([
|
|
10739
|
-
|
|
10740
|
-
|
|
9947
|
+
fs9.realpath(cwd),
|
|
9948
|
+
fs9.realpath(outputDirectory)
|
|
10741
9949
|
]);
|
|
10742
|
-
const realTargetPath =
|
|
9950
|
+
const realTargetPath = path11.join(
|
|
10743
9951
|
realOutputDirectory,
|
|
10744
|
-
|
|
9952
|
+
path11.basename(targetPath)
|
|
10745
9953
|
);
|
|
10746
9954
|
if (!isSubpath(realCwd, realTargetPath)) {
|
|
10747
9955
|
return statsExportPathError();
|
|
@@ -10767,7 +9975,7 @@ async function writeStatsExportFileAtomically(cwd, outputDirectory, targetPath,
|
|
|
10767
9975
|
if (preTempFileError) {
|
|
10768
9976
|
return preTempFileError;
|
|
10769
9977
|
}
|
|
10770
|
-
const file = await
|
|
9978
|
+
const file = await fs9.open(tempPath, "wx", 384);
|
|
10771
9979
|
try {
|
|
10772
9980
|
await file.writeFile(content, { encoding: "utf-8" });
|
|
10773
9981
|
} finally {
|
|
@@ -10789,7 +9997,7 @@ async function writeStatsExportFileAtomically(cwd, outputDirectory, targetPath,
|
|
|
10789
9997
|
if (preRenameFileError) {
|
|
10790
9998
|
return preRenameFileError;
|
|
10791
9999
|
}
|
|
10792
|
-
await
|
|
10000
|
+
await fs9.rename(tempPath, realTargetPath);
|
|
10793
10001
|
tempPath = void 0;
|
|
10794
10002
|
return validateStatsExportFinalFile(cwd, realTargetPath);
|
|
10795
10003
|
} catch (error) {
|
|
@@ -10799,7 +10007,7 @@ async function writeStatsExportFileAtomically(cwd, outputDirectory, targetPath,
|
|
|
10799
10007
|
throw error;
|
|
10800
10008
|
} finally {
|
|
10801
10009
|
if (tempPath) {
|
|
10802
|
-
await
|
|
10010
|
+
await fs9.rm(tempPath, { force: true }).catch(() => void 0);
|
|
10803
10011
|
}
|
|
10804
10012
|
}
|
|
10805
10013
|
}
|
|
@@ -10891,10 +10099,10 @@ async function writeStatsExport(context, args) {
|
|
|
10891
10099
|
});
|
|
10892
10100
|
const content = parsed.format === "json" ? formatTokenUsageSummaryAsJson(summary) : `${formatTokenUsageSummaryAsCsv(summary)}
|
|
10893
10101
|
`;
|
|
10894
|
-
const cwd =
|
|
10102
|
+
const cwd = path11.resolve(getConfigCwd(context));
|
|
10895
10103
|
const defaultFilename = `qwen-token-usage-${summary.period}-${summary.value}.${parsed.format}`;
|
|
10896
|
-
const targetPath =
|
|
10897
|
-
const outputDirectory =
|
|
10104
|
+
const targetPath = path11.resolve(cwd, parsed.outputPath || defaultFilename);
|
|
10105
|
+
const outputDirectory = path11.dirname(targetPath);
|
|
10898
10106
|
if (!isSubpath(cwd, targetPath) || !isSubpath(cwd, outputDirectory)) {
|
|
10899
10107
|
return statsExportPathError();
|
|
10900
10108
|
}
|
|
@@ -10909,7 +10117,7 @@ async function writeStatsExport(context, args) {
|
|
|
10909
10117
|
if (parentError) {
|
|
10910
10118
|
return parentError;
|
|
10911
10119
|
}
|
|
10912
|
-
await
|
|
10120
|
+
await fs9.mkdir(outputDirectory, { recursive: true });
|
|
10913
10121
|
const postMkdirError = await validateStatsExportDirectory(
|
|
10914
10122
|
cwd,
|
|
10915
10123
|
outputDirectory
|
|
@@ -10933,7 +10141,7 @@ async function writeStatsExport(context, args) {
|
|
|
10933
10141
|
return asMessage(
|
|
10934
10142
|
t("Token usage exported to {{format}}: {{path}}", {
|
|
10935
10143
|
format: parsed.format.toUpperCase(),
|
|
10936
|
-
path:
|
|
10144
|
+
path: path11.relative(cwd, targetPath)
|
|
10937
10145
|
})
|
|
10938
10146
|
);
|
|
10939
10147
|
} catch (error) {
|
|
@@ -11144,7 +10352,7 @@ var statsCommand = {
|
|
|
11144
10352
|
// packages/cli/src/ui/commands/summaryCommand.ts
|
|
11145
10353
|
init_esbuild_shims();
|
|
11146
10354
|
import * as fsPromises from "fs/promises";
|
|
11147
|
-
import
|
|
10355
|
+
import path12 from "path";
|
|
11148
10356
|
var summaryCommand = {
|
|
11149
10357
|
name: "summary",
|
|
11150
10358
|
get description() {
|
|
@@ -11237,12 +10445,12 @@ var summaryCommand = {
|
|
|
11237
10445
|
}, "generateSummaryMarkdown");
|
|
11238
10446
|
const saveSummaryToDisk = /* @__PURE__ */ __name(async (markdownSummary) => {
|
|
11239
10447
|
const projectRoot = config.getProjectRoot();
|
|
11240
|
-
const qwenDir =
|
|
10448
|
+
const qwenDir = path12.join(projectRoot, ".qwen");
|
|
11241
10449
|
try {
|
|
11242
10450
|
await fsPromises.mkdir(qwenDir, { recursive: true });
|
|
11243
10451
|
} catch (_err) {
|
|
11244
10452
|
}
|
|
11245
|
-
const summaryPath =
|
|
10453
|
+
const summaryPath = path12.join(qwenDir, "PROJECT_SUMMARY.md");
|
|
11246
10454
|
const summaryContent = `${markdownSummary}
|
|
11247
10455
|
|
|
11248
10456
|
---
|
|
@@ -11398,12 +10606,12 @@ init_esbuild_shims();
|
|
|
11398
10606
|
|
|
11399
10607
|
// packages/cli/src/ui/utils/terminalSetup.ts
|
|
11400
10608
|
init_esbuild_shims();
|
|
11401
|
-
import { promises as
|
|
11402
|
-
import * as
|
|
11403
|
-
import * as
|
|
10609
|
+
import { promises as fs10 } from "node:fs";
|
|
10610
|
+
import * as os4 from "node:os";
|
|
10611
|
+
import * as path13 from "node:path";
|
|
11404
10612
|
import { exec } from "node:child_process";
|
|
11405
10613
|
import { promisify } from "node:util";
|
|
11406
|
-
var
|
|
10614
|
+
var debugLogger10 = createDebugLogger("TERMINAL_SETUP");
|
|
11407
10615
|
var execAsync = promisify(exec);
|
|
11408
10616
|
function stripJsonComments2(content) {
|
|
11409
10617
|
return content.replace(/^\s*\/\/.*$/gm, "");
|
|
@@ -11423,7 +10631,7 @@ async function detectTerminal() {
|
|
|
11423
10631
|
if (termProgram === "vscode" || process.env["VSCODE_GIT_IPC_HANDLE"]) {
|
|
11424
10632
|
return "vscode";
|
|
11425
10633
|
}
|
|
11426
|
-
if (
|
|
10634
|
+
if (os4.platform() !== "win32") {
|
|
11427
10635
|
try {
|
|
11428
10636
|
const { stdout } = await execAsync("ps -o comm= -p $PPID");
|
|
11429
10637
|
const parentName = stdout.trim();
|
|
@@ -11436,7 +10644,7 @@ async function detectTerminal() {
|
|
|
11436
10644
|
if (parentName.includes("trae") || parentName.includes("Trae"))
|
|
11437
10645
|
return "trae";
|
|
11438
10646
|
} catch (error) {
|
|
11439
|
-
|
|
10647
|
+
debugLogger10.debug("Parent process detection failed:", error);
|
|
11440
10648
|
}
|
|
11441
10649
|
}
|
|
11442
10650
|
return null;
|
|
@@ -11446,29 +10654,29 @@ async function backupFile(filePath) {
|
|
|
11446
10654
|
try {
|
|
11447
10655
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
11448
10656
|
const backupPath = `${filePath}.backup.${timestamp}`;
|
|
11449
|
-
await
|
|
10657
|
+
await fs10.copyFile(filePath, backupPath);
|
|
11450
10658
|
} catch (error) {
|
|
11451
|
-
|
|
10659
|
+
debugLogger10.warn(`Failed to create backup of ${filePath}:`, error);
|
|
11452
10660
|
}
|
|
11453
10661
|
}
|
|
11454
10662
|
__name(backupFile, "backupFile");
|
|
11455
10663
|
function getVSCodeStyleConfigDir(appName) {
|
|
11456
|
-
const
|
|
11457
|
-
if (
|
|
11458
|
-
return
|
|
11459
|
-
|
|
10664
|
+
const platform2 = os4.platform();
|
|
10665
|
+
if (platform2 === "darwin") {
|
|
10666
|
+
return path13.join(
|
|
10667
|
+
os4.homedir(),
|
|
11460
10668
|
"Library",
|
|
11461
10669
|
"Application Support",
|
|
11462
10670
|
appName,
|
|
11463
10671
|
"User"
|
|
11464
10672
|
);
|
|
11465
|
-
} else if (
|
|
10673
|
+
} else if (platform2 === "win32") {
|
|
11466
10674
|
if (!process.env["APPDATA"]) {
|
|
11467
10675
|
return null;
|
|
11468
10676
|
}
|
|
11469
|
-
return
|
|
10677
|
+
return path13.join(process.env["APPDATA"], appName, "User");
|
|
11470
10678
|
} else {
|
|
11471
|
-
return
|
|
10679
|
+
return path13.join(os4.homedir(), ".config", appName, "User");
|
|
11472
10680
|
}
|
|
11473
10681
|
}
|
|
11474
10682
|
__name(getVSCodeStyleConfigDir, "getVSCodeStyleConfigDir");
|
|
@@ -11483,12 +10691,12 @@ async function configureVSCodeStyle(terminalName, appName) {
|
|
|
11483
10691
|
)
|
|
11484
10692
|
};
|
|
11485
10693
|
}
|
|
11486
|
-
const keybindingsFile =
|
|
10694
|
+
const keybindingsFile = path13.join(configDir, "keybindings.json");
|
|
11487
10695
|
try {
|
|
11488
|
-
await
|
|
10696
|
+
await fs10.mkdir(configDir, { recursive: true });
|
|
11489
10697
|
let keybindings = [];
|
|
11490
10698
|
try {
|
|
11491
|
-
const content = await
|
|
10699
|
+
const content = await fs10.readFile(keybindingsFile, "utf8");
|
|
11492
10700
|
await backupFile(keybindingsFile);
|
|
11493
10701
|
try {
|
|
11494
10702
|
const cleanContent = stripJsonComments2(content);
|
|
@@ -11562,7 +10770,7 @@ async function configureVSCodeStyle(terminalName, appName) {
|
|
|
11562
10770
|
if (!hasOurShiftEnter || !hasOurCtrlEnter) {
|
|
11563
10771
|
if (!hasOurShiftEnter) keybindings.unshift(shiftEnterBinding);
|
|
11564
10772
|
if (!hasOurCtrlEnter) keybindings.unshift(ctrlEnterBinding);
|
|
11565
|
-
await
|
|
10773
|
+
await fs10.writeFile(keybindingsFile, JSON.stringify(keybindings, null, 4));
|
|
11566
10774
|
return {
|
|
11567
10775
|
success: true,
|
|
11568
10776
|
message: t(
|
|
@@ -11757,7 +10965,7 @@ init_esbuild_shims();
|
|
|
11757
10965
|
|
|
11758
10966
|
// packages/cli/src/ui/voice/voice-availability.ts
|
|
11759
10967
|
init_esbuild_shims();
|
|
11760
|
-
import { existsSync as
|
|
10968
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
11761
10969
|
import process5 from "node:process";
|
|
11762
10970
|
var SUPPORTED_PLATFORMS = [
|
|
11763
10971
|
"darwin",
|
|
@@ -11772,14 +10980,14 @@ function getVoiceUnavailableReason(environment = {
|
|
|
11772
10980
|
platform: process5.platform,
|
|
11773
10981
|
env: process5.env
|
|
11774
10982
|
}) {
|
|
11775
|
-
const { platform:
|
|
11776
|
-
const fileExists = environment.fileExists ??
|
|
11777
|
-
if (!SUPPORTED_PLATFORMS.includes(
|
|
10983
|
+
const { platform: platform2, env } = environment;
|
|
10984
|
+
const fileExists = environment.fileExists ?? existsSync2;
|
|
10985
|
+
if (!SUPPORTED_PLATFORMS.includes(platform2)) {
|
|
11778
10986
|
return t("Voice dictation is not supported on {{platform}}.", {
|
|
11779
|
-
platform:
|
|
10987
|
+
platform: platform2
|
|
11780
10988
|
});
|
|
11781
10989
|
}
|
|
11782
|
-
if (
|
|
10990
|
+
if (platform2 === "linux" && isWsl(env) && !env["PULSE_SERVER"] && !fileExists("/mnt/wslg/PulseServer")) {
|
|
11783
10991
|
return t(
|
|
11784
10992
|
"Voice dictation needs microphone access, which is unavailable in this WSL session. Use WSLg/PulseAudio, or run Qwen Code on a host with a microphone."
|
|
11785
10993
|
);
|
|
@@ -11936,18 +11144,18 @@ var setupGithubCommand = {
|
|
|
11936
11144
|
|
|
11937
11145
|
// packages/cli/src/ui/commands/insightCommand.ts
|
|
11938
11146
|
init_esbuild_shims();
|
|
11939
|
-
import { join as
|
|
11147
|
+
import { join as join7 } from "path";
|
|
11940
11148
|
import { pathToFileURL } from "node:url";
|
|
11941
11149
|
|
|
11942
11150
|
// packages/cli/src/services/insight/generators/StaticInsightGenerator.ts
|
|
11943
11151
|
init_esbuild_shims();
|
|
11944
|
-
import
|
|
11945
|
-
import
|
|
11152
|
+
import fs12 from "fs/promises";
|
|
11153
|
+
import path15 from "path";
|
|
11946
11154
|
|
|
11947
11155
|
// packages/cli/src/services/insight/generators/DataProcessor.ts
|
|
11948
11156
|
init_esbuild_shims();
|
|
11949
|
-
import
|
|
11950
|
-
import
|
|
11157
|
+
import fs11 from "fs/promises";
|
|
11158
|
+
import path14 from "path";
|
|
11951
11159
|
|
|
11952
11160
|
// packages/cli/node_modules/p-limit/index.js
|
|
11953
11161
|
init_esbuild_shims();
|
|
@@ -12047,27 +11255,27 @@ function pLimit(concurrency) {
|
|
|
12047
11255
|
activeCount--;
|
|
12048
11256
|
resumeNext();
|
|
12049
11257
|
}, "next");
|
|
12050
|
-
const run = /* @__PURE__ */ __name(async (function_,
|
|
11258
|
+
const run = /* @__PURE__ */ __name(async (function_, resolve4, arguments_) => {
|
|
12051
11259
|
const result = (async () => function_(...arguments_))();
|
|
12052
|
-
|
|
11260
|
+
resolve4(result);
|
|
12053
11261
|
try {
|
|
12054
11262
|
await result;
|
|
12055
11263
|
} catch {
|
|
12056
11264
|
}
|
|
12057
11265
|
next();
|
|
12058
11266
|
}, "run");
|
|
12059
|
-
const enqueue = /* @__PURE__ */ __name((function_,
|
|
11267
|
+
const enqueue = /* @__PURE__ */ __name((function_, resolve4, reject, arguments_) => {
|
|
12060
11268
|
const queueItem = { reject };
|
|
12061
11269
|
new Promise((internalResolve) => {
|
|
12062
11270
|
queueItem.run = internalResolve;
|
|
12063
11271
|
queue.enqueue(queueItem);
|
|
12064
|
-
}).then(run.bind(void 0, function_,
|
|
11272
|
+
}).then(run.bind(void 0, function_, resolve4, arguments_));
|
|
12065
11273
|
if (activeCount < concurrency) {
|
|
12066
11274
|
resumeNext();
|
|
12067
11275
|
}
|
|
12068
11276
|
}, "enqueue");
|
|
12069
|
-
const generator = /* @__PURE__ */ __name((function_, ...arguments_) => new Promise((
|
|
12070
|
-
enqueue(function_,
|
|
11277
|
+
const generator = /* @__PURE__ */ __name((function_, ...arguments_) => new Promise((resolve4, reject) => {
|
|
11278
|
+
enqueue(function_, resolve4, reject, arguments_);
|
|
12071
11279
|
}), "generator");
|
|
12072
11280
|
Object.defineProperties(generator, {
|
|
12073
11281
|
activeCount: {
|
|
@@ -12901,19 +12109,19 @@ None captured`;
|
|
|
12901
12109
|
async scanChatFiles(baseDir) {
|
|
12902
12110
|
const allChatFiles = [];
|
|
12903
12111
|
try {
|
|
12904
|
-
const projectDirs = await
|
|
12112
|
+
const projectDirs = await fs11.readdir(baseDir);
|
|
12905
12113
|
for (const projectDir of projectDirs) {
|
|
12906
|
-
const projectPath =
|
|
12907
|
-
const stats = await
|
|
12114
|
+
const projectPath = path14.join(baseDir, projectDir);
|
|
12115
|
+
const stats = await fs11.stat(projectPath);
|
|
12908
12116
|
if (stats.isDirectory()) {
|
|
12909
|
-
const chatsDir =
|
|
12117
|
+
const chatsDir = path14.join(projectPath, "chats");
|
|
12910
12118
|
try {
|
|
12911
|
-
const files = await
|
|
12119
|
+
const files = await fs11.readdir(chatsDir);
|
|
12912
12120
|
const chatFiles = files.filter((file) => file.endsWith(".jsonl"));
|
|
12913
12121
|
for (const file of chatFiles) {
|
|
12914
|
-
const filePath =
|
|
12122
|
+
const filePath = path14.join(chatsDir, file);
|
|
12915
12123
|
try {
|
|
12916
|
-
const fileStats = await
|
|
12124
|
+
const fileStats = await fs11.stat(filePath);
|
|
12917
12125
|
allChatFiles.push({ path: filePath, mtime: fileStats.mtimeMs });
|
|
12918
12126
|
} catch (e) {
|
|
12919
12127
|
logger.error(`Failed to stat file ${filePath}:`, e);
|
|
@@ -13008,7 +12216,7 @@ None captured`;
|
|
|
13008
12216
|
overallProgress
|
|
13009
12217
|
);
|
|
13010
12218
|
}
|
|
13011
|
-
await new Promise((
|
|
12219
|
+
await new Promise((resolve4) => setTimeout(resolve4, 0));
|
|
13012
12220
|
}
|
|
13013
12221
|
const streakData = this.calculateStreaks(Object.keys(heatmap));
|
|
13014
12222
|
let longestWorkDuration = 0;
|
|
@@ -13091,12 +12299,12 @@ None captured`;
|
|
|
13091
12299
|
if (records.length > 0 && facetsOutputDir) {
|
|
13092
12300
|
const sessionId = records[0].sessionId;
|
|
13093
12301
|
if (sessionId) {
|
|
13094
|
-
const existingFacetPath =
|
|
12302
|
+
const existingFacetPath = path14.join(
|
|
13095
12303
|
facetsOutputDir,
|
|
13096
12304
|
`${sessionId}.json`
|
|
13097
12305
|
);
|
|
13098
12306
|
try {
|
|
13099
|
-
const existingData = await
|
|
12307
|
+
const existingData = await fs11.readFile(
|
|
13100
12308
|
existingFacetPath,
|
|
13101
12309
|
"utf-8"
|
|
13102
12310
|
);
|
|
@@ -13114,7 +12322,7 @@ None captured`;
|
|
|
13114
12322
|
const normalizedData = JSON.stringify(normalizedFacet, null, 2);
|
|
13115
12323
|
if (existingData !== normalizedData) {
|
|
13116
12324
|
try {
|
|
13117
|
-
await
|
|
12325
|
+
await fs11.writeFile(
|
|
13118
12326
|
existingFacetPath,
|
|
13119
12327
|
normalizedData,
|
|
13120
12328
|
"utf-8"
|
|
@@ -13149,11 +12357,11 @@ None captured`;
|
|
|
13149
12357
|
const facet = await this.analyzeSession(records);
|
|
13150
12358
|
if (facet && facetsOutputDir) {
|
|
13151
12359
|
try {
|
|
13152
|
-
const facetPath =
|
|
12360
|
+
const facetPath = path14.join(
|
|
13153
12361
|
facetsOutputDir,
|
|
13154
12362
|
`${facet.session_id}.json`
|
|
13155
12363
|
);
|
|
13156
|
-
await
|
|
12364
|
+
await fs11.writeFile(
|
|
13157
12365
|
facetPath,
|
|
13158
12366
|
JSON.stringify(facet, null, 2),
|
|
13159
12367
|
"utf-8"
|
|
@@ -13251,8 +12459,8 @@ var StaticInsightGenerator = class {
|
|
|
13251
12459
|
}
|
|
13252
12460
|
// Ensure the output directory exists
|
|
13253
12461
|
async ensureOutputDirectory() {
|
|
13254
|
-
const outputDir =
|
|
13255
|
-
await
|
|
12462
|
+
const outputDir = path15.join(Storage.getRuntimeBaseDir(), "insights");
|
|
12463
|
+
await fs12.mkdir(outputDir, { recursive: true });
|
|
13256
12464
|
return outputDir;
|
|
13257
12465
|
}
|
|
13258
12466
|
// Generate timestamped filename with collision detection
|
|
@@ -13260,23 +12468,23 @@ var StaticInsightGenerator = class {
|
|
|
13260
12468
|
const now = /* @__PURE__ */ new Date();
|
|
13261
12469
|
const date = now.toISOString().split("T")[0];
|
|
13262
12470
|
const time = now.toTimeString().slice(0, 8).replace(/:/g, "");
|
|
13263
|
-
let outputPath =
|
|
12471
|
+
let outputPath = path15.join(outputDir, `insight-${date}.html`);
|
|
13264
12472
|
try {
|
|
13265
|
-
await
|
|
13266
|
-
outputPath =
|
|
12473
|
+
await fs12.access(outputPath);
|
|
12474
|
+
outputPath = path15.join(outputDir, `insight-${date}-${time}.html`);
|
|
13267
12475
|
} catch {
|
|
13268
12476
|
}
|
|
13269
12477
|
return outputPath;
|
|
13270
12478
|
}
|
|
13271
12479
|
async updateInsightSymlink(outputDir, targetPath) {
|
|
13272
|
-
const latestPath =
|
|
12480
|
+
const latestPath = path15.join(outputDir, "insight.html");
|
|
13273
12481
|
await updateSymlink(latestPath, targetPath);
|
|
13274
12482
|
}
|
|
13275
12483
|
// Generate the static insight HTML file
|
|
13276
12484
|
async generateStaticInsight(baseDir, onProgress) {
|
|
13277
12485
|
const outputDir = await this.ensureOutputDirectory();
|
|
13278
|
-
const facetsDir =
|
|
13279
|
-
await
|
|
12486
|
+
const facetsDir = path15.join(outputDir, "facets");
|
|
12487
|
+
await fs12.mkdir(facetsDir, { recursive: true });
|
|
13280
12488
|
const insights = await this.dataProcessor.generateInsights(
|
|
13281
12489
|
baseDir,
|
|
13282
12490
|
facetsDir,
|
|
@@ -13284,7 +12492,7 @@ var StaticInsightGenerator = class {
|
|
|
13284
12492
|
);
|
|
13285
12493
|
const html = await this.templateRenderer.renderInsightHTML(insights);
|
|
13286
12494
|
const outputPath = await this.generateOutputPath(outputDir);
|
|
13287
|
-
await
|
|
12495
|
+
await fs12.writeFile(outputPath, html, "utf-8");
|
|
13288
12496
|
await this.updateInsightSymlink(outputDir, outputPath);
|
|
13289
12497
|
return outputPath;
|
|
13290
12498
|
}
|
|
@@ -13304,7 +12512,7 @@ var insightCommand = {
|
|
|
13304
12512
|
action: /* @__PURE__ */ __name(async (context) => {
|
|
13305
12513
|
try {
|
|
13306
12514
|
context.ui.setDebugMessage(t("Generating insights..."));
|
|
13307
|
-
const projectsDir =
|
|
12515
|
+
const projectsDir = join7(Storage.getRuntimeBaseDir(), "projects");
|
|
13308
12516
|
if (!context.services.config) {
|
|
13309
12517
|
if (context.executionMode !== "interactive") {
|
|
13310
12518
|
return {
|
|
@@ -13347,12 +12555,12 @@ var insightCommand = {
|
|
|
13347
12555
|
let isComplete = false;
|
|
13348
12556
|
let resume = null;
|
|
13349
12557
|
const flushResume = /* @__PURE__ */ __name(() => {
|
|
13350
|
-
const
|
|
13351
|
-
if (!
|
|
12558
|
+
const resolve4 = resume;
|
|
12559
|
+
if (!resolve4) {
|
|
13352
12560
|
return;
|
|
13353
12561
|
}
|
|
13354
12562
|
resume = null;
|
|
13355
|
-
|
|
12563
|
+
resolve4();
|
|
13356
12564
|
}, "flushResume");
|
|
13357
12565
|
const pushMessage = /* @__PURE__ */ __name((message) => {
|
|
13358
12566
|
pendingMessages.push(message);
|
|
@@ -13361,8 +12569,8 @@ var insightCommand = {
|
|
|
13361
12569
|
const streamMessages = /* @__PURE__ */ __name(async function* () {
|
|
13362
12570
|
while (!isComplete || pendingMessages.length > 0) {
|
|
13363
12571
|
if (pendingMessages.length === 0) {
|
|
13364
|
-
await new Promise((
|
|
13365
|
-
resume =
|
|
12572
|
+
await new Promise((resolve4) => {
|
|
12573
|
+
resume = resolve4;
|
|
13366
12574
|
});
|
|
13367
12575
|
}
|
|
13368
12576
|
while (pendingMessages.length > 0) {
|
|
@@ -13720,8 +12928,8 @@ var BuiltinCommandLoader = class {
|
|
|
13720
12928
|
|
|
13721
12929
|
// packages/cli/src/services/BundledSkillLoader.ts
|
|
13722
12930
|
init_esbuild_shims();
|
|
13723
|
-
import { dirname as
|
|
13724
|
-
var
|
|
12931
|
+
import { dirname as dirname2 } from "node:path";
|
|
12932
|
+
var debugLogger11 = createDebugLogger("BUNDLED_SKILL_LOADER");
|
|
13725
12933
|
var BundledSkillLoader = class {
|
|
13726
12934
|
constructor(config) {
|
|
13727
12935
|
this.config = config;
|
|
@@ -13731,12 +12939,12 @@ var BundledSkillLoader = class {
|
|
|
13731
12939
|
}
|
|
13732
12940
|
async loadCommands(_signal) {
|
|
13733
12941
|
if (this.config?.getBareMode?.()) {
|
|
13734
|
-
|
|
12942
|
+
debugLogger11.debug("Bare mode enabled, skipping bundled skills");
|
|
13735
12943
|
return [];
|
|
13736
12944
|
}
|
|
13737
12945
|
const skillManager = this.config?.getSkillManager();
|
|
13738
12946
|
if (!skillManager) {
|
|
13739
|
-
|
|
12947
|
+
debugLogger11.debug("SkillManager not available, skipping bundled skills");
|
|
13740
12948
|
return [];
|
|
13741
12949
|
}
|
|
13742
12950
|
try {
|
|
@@ -13744,7 +12952,7 @@ var BundledSkillLoader = class {
|
|
|
13744
12952
|
const cronEnabled = this.config?.isCronEnabled() ?? false;
|
|
13745
12953
|
const cronVisible = allSkills.filter((skill) => {
|
|
13746
12954
|
if (!cronEnabled && skill.allowedTools?.some((t2) => t2.startsWith("cron_"))) {
|
|
13747
|
-
|
|
12955
|
+
debugLogger11.debug(
|
|
13748
12956
|
`Hiding skill "${skill.name}" because cron is not enabled`
|
|
13749
12957
|
);
|
|
13750
12958
|
return false;
|
|
@@ -13755,7 +12963,7 @@ var BundledSkillLoader = class {
|
|
|
13755
12963
|
const skills = cronVisible.filter(
|
|
13756
12964
|
(skill) => !disabled.has(skill.name.toLowerCase())
|
|
13757
12965
|
);
|
|
13758
|
-
|
|
12966
|
+
debugLogger11.debug(
|
|
13759
12967
|
`Loaded ${skills.length} bundled skill(s) as slash commands; ${cronVisible.length - skills.length} hidden by skills.disabled`
|
|
13760
12968
|
);
|
|
13761
12969
|
return skills.map((skill) => ({
|
|
@@ -13792,7 +13000,7 @@ ${body}`;
|
|
|
13792
13000
|
}
|
|
13793
13001
|
}
|
|
13794
13002
|
const skillPrompt = buildSkillLlmContent(
|
|
13795
|
-
|
|
13003
|
+
dirname2(skill.filePath),
|
|
13796
13004
|
body
|
|
13797
13005
|
);
|
|
13798
13006
|
const content = context.invocation?.args ? appendToLastTextPart(
|
|
@@ -13806,7 +13014,7 @@ ${body}`;
|
|
|
13806
13014
|
}, "action")
|
|
13807
13015
|
}));
|
|
13808
13016
|
} catch (error) {
|
|
13809
|
-
|
|
13017
|
+
debugLogger11.error("Failed to load bundled skills:", error);
|
|
13810
13018
|
return [];
|
|
13811
13019
|
}
|
|
13812
13020
|
}
|
|
@@ -13815,9 +13023,9 @@ ${body}`;
|
|
|
13815
13023
|
// packages/cli/src/services/FileCommandLoader.ts
|
|
13816
13024
|
init_esbuild_shims();
|
|
13817
13025
|
var import_toml = __toESM(require_toml(), 1);
|
|
13818
|
-
import { promises as
|
|
13026
|
+
import { promises as fs13 } from "node:fs";
|
|
13819
13027
|
import * as fsSync from "node:fs";
|
|
13820
|
-
import
|
|
13028
|
+
import path17 from "node:path";
|
|
13821
13029
|
|
|
13822
13030
|
// packages/cli/src/services/markdown-command-parser.ts
|
|
13823
13031
|
init_esbuild_shims();
|
|
@@ -13862,7 +13070,7 @@ __name(parseMarkdownCommand, "parseMarkdownCommand");
|
|
|
13862
13070
|
|
|
13863
13071
|
// packages/cli/src/services/command-factory.ts
|
|
13864
13072
|
init_esbuild_shims();
|
|
13865
|
-
import
|
|
13073
|
+
import path16 from "node:path";
|
|
13866
13074
|
|
|
13867
13075
|
// packages/cli/src/services/prompt-processors/argumentProcessor.ts
|
|
13868
13076
|
init_esbuild_shims();
|
|
@@ -14086,7 +13294,7 @@ var ShellProcessor = class {
|
|
|
14086
13294
|
|
|
14087
13295
|
// packages/cli/src/services/prompt-processors/atFileProcessor.ts
|
|
14088
13296
|
init_esbuild_shims();
|
|
14089
|
-
var
|
|
13297
|
+
var debugLogger12 = createDebugLogger("AT_FILE_PROCESSOR");
|
|
14090
13298
|
var AtFileProcessor = class {
|
|
14091
13299
|
constructor(commandName) {
|
|
14092
13300
|
this.commandName = commandName;
|
|
@@ -14132,7 +13340,7 @@ var AtFileProcessor = class {
|
|
|
14132
13340
|
} catch (error) {
|
|
14133
13341
|
const message = error instanceof Error ? error.message : String(error);
|
|
14134
13342
|
const uiMessage = `Failed to inject content for '@{${pathStr}}': ${message}`;
|
|
14135
|
-
|
|
13343
|
+
debugLogger12.error(
|
|
14136
13344
|
`[AtFileProcessor] ${uiMessage}. Leaving placeholder in prompt.`
|
|
14137
13345
|
);
|
|
14138
13346
|
context.ui.addItem(
|
|
@@ -14157,15 +13365,15 @@ var AtFileProcessor = class {
|
|
|
14157
13365
|
};
|
|
14158
13366
|
|
|
14159
13367
|
// packages/cli/src/services/command-factory.ts
|
|
14160
|
-
var
|
|
13368
|
+
var debugLogger13 = createDebugLogger("COMMAND_FACTORY");
|
|
14161
13369
|
function createSlashCommandFromDefinition(filePath, baseDir, definition, extensionName, fileExtension) {
|
|
14162
|
-
const relativePathWithExt =
|
|
13370
|
+
const relativePathWithExt = path16.relative(baseDir, filePath);
|
|
14163
13371
|
const relativePath = relativePathWithExt.substring(
|
|
14164
13372
|
0,
|
|
14165
13373
|
relativePathWithExt.length - fileExtension.length
|
|
14166
13374
|
);
|
|
14167
|
-
const baseCommandName = relativePath.split(
|
|
14168
|
-
const defaultDescription = `Custom command from ${
|
|
13375
|
+
const baseCommandName = relativePath.split(path16.sep).map((segment) => segment.replaceAll(":", "_")).join(":");
|
|
13376
|
+
const defaultDescription = `Custom command from ${path16.basename(filePath)}`;
|
|
14169
13377
|
let description = definition.description || defaultDescription;
|
|
14170
13378
|
if (extensionName) {
|
|
14171
13379
|
description = `[${extensionName}] ${description}`;
|
|
@@ -14201,7 +13409,7 @@ function createSlashCommandFromDefinition(filePath, baseDir, definition, extensi
|
|
|
14201
13409
|
whenToUse: definition.whenToUse,
|
|
14202
13410
|
action: /* @__PURE__ */ __name(async (context, _args) => {
|
|
14203
13411
|
if (!context.invocation) {
|
|
14204
|
-
|
|
13412
|
+
debugLogger13.error(
|
|
14205
13413
|
`[FileCommandLoader] Critical error: Command '${baseCommandName}' was executed without invocation context.`
|
|
14206
13414
|
);
|
|
14207
13415
|
return {
|
|
@@ -14239,7 +13447,7 @@ function createSlashCommandFromDefinition(filePath, baseDir, definition, extensi
|
|
|
14239
13447
|
__name(createSlashCommandFromDefinition, "createSlashCommandFromDefinition");
|
|
14240
13448
|
|
|
14241
13449
|
// packages/cli/src/services/FileCommandLoader.ts
|
|
14242
|
-
var
|
|
13450
|
+
var debugLogger14 = createDebugLogger("FILE_COMMAND_LOADER");
|
|
14243
13451
|
var TomlCommandDefSchema = external_exports.object({
|
|
14244
13452
|
prompt: external_exports.string({
|
|
14245
13453
|
required_error: "The 'prompt' field is required.",
|
|
@@ -14273,7 +13481,7 @@ var FileCommandLoader = class {
|
|
|
14273
13481
|
*/
|
|
14274
13482
|
async loadCommands(signal) {
|
|
14275
13483
|
if (this.config?.getBareMode?.()) {
|
|
14276
|
-
|
|
13484
|
+
debugLogger14.debug("Bare mode enabled, skipping auto-discovered commands");
|
|
14277
13485
|
return [];
|
|
14278
13486
|
}
|
|
14279
13487
|
const allCommands = [];
|
|
@@ -14299,14 +13507,14 @@ var FileCommandLoader = class {
|
|
|
14299
13507
|
}
|
|
14300
13508
|
const tomlCommandPromises = tomlFiles.map(
|
|
14301
13509
|
(file) => this.parseAndAdaptTomlFile(
|
|
14302
|
-
|
|
13510
|
+
path17.join(dirInfo.path, file),
|
|
14303
13511
|
dirInfo.path,
|
|
14304
13512
|
dirInfo.extensionName
|
|
14305
13513
|
)
|
|
14306
13514
|
);
|
|
14307
13515
|
const mdCommandPromises = mdFiles.map(
|
|
14308
13516
|
(file) => this.parseAndAdaptMarkdownFile(
|
|
14309
|
-
|
|
13517
|
+
path17.join(dirInfo.path, file),
|
|
14310
13518
|
dirInfo.path,
|
|
14311
13519
|
dirInfo.extensionName
|
|
14312
13520
|
)
|
|
@@ -14317,7 +13525,7 @@ var FileCommandLoader = class {
|
|
|
14317
13525
|
const isEnoent = error.code === "ENOENT";
|
|
14318
13526
|
const isAbortError = error instanceof Error && error.name === "AbortError";
|
|
14319
13527
|
if (!isEnoent && !isAbortError) {
|
|
14320
|
-
|
|
13528
|
+
debugLogger14.error(
|
|
14321
13529
|
`[FileCommandLoader] Error loading commands from ${dirInfo.path}:`,
|
|
14322
13530
|
error
|
|
14323
13531
|
);
|
|
@@ -14356,14 +13564,14 @@ var FileCommandLoader = class {
|
|
|
14356
13564
|
*/
|
|
14357
13565
|
getExtensionCommandsPaths(ext) {
|
|
14358
13566
|
try {
|
|
14359
|
-
const configPath =
|
|
13567
|
+
const configPath = path17.join(ext.path, EXTENSIONS_CONFIG_FILENAME);
|
|
14360
13568
|
if (fsSync.existsSync(configPath)) {
|
|
14361
13569
|
const configContent = fsSync.readFileSync(configPath, "utf-8");
|
|
14362
13570
|
const config = JSON.parse(configContent);
|
|
14363
13571
|
if (config.commands) {
|
|
14364
13572
|
const commandsArray = Array.isArray(config.commands) ? config.commands : [config.commands];
|
|
14365
13573
|
return commandsArray.map(
|
|
14366
|
-
(cmdPath) =>
|
|
13574
|
+
(cmdPath) => path17.isAbsolute(cmdPath) ? cmdPath : path17.join(ext.path, cmdPath)
|
|
14367
13575
|
).filter((cmdPath) => {
|
|
14368
13576
|
try {
|
|
14369
13577
|
return fsSync.existsSync(cmdPath);
|
|
@@ -14374,12 +13582,12 @@ var FileCommandLoader = class {
|
|
|
14374
13582
|
}
|
|
14375
13583
|
}
|
|
14376
13584
|
} catch (error) {
|
|
14377
|
-
|
|
13585
|
+
debugLogger14.warn(
|
|
14378
13586
|
`Failed to read extension config for ${ext.name}:`,
|
|
14379
13587
|
error
|
|
14380
13588
|
);
|
|
14381
13589
|
}
|
|
14382
|
-
const defaultPath =
|
|
13590
|
+
const defaultPath = path17.join(ext.path, "commands");
|
|
14383
13591
|
try {
|
|
14384
13592
|
if (fsSync.existsSync(defaultPath)) {
|
|
14385
13593
|
return [defaultPath];
|
|
@@ -14398,9 +13606,9 @@ var FileCommandLoader = class {
|
|
|
14398
13606
|
async parseAndAdaptTomlFile(filePath, baseDir, extensionName) {
|
|
14399
13607
|
let fileContent;
|
|
14400
13608
|
try {
|
|
14401
|
-
fileContent = await
|
|
13609
|
+
fileContent = await fs13.readFile(filePath, "utf-8");
|
|
14402
13610
|
} catch (error) {
|
|
14403
|
-
|
|
13611
|
+
debugLogger14.error(
|
|
14404
13612
|
`[FileCommandLoader] Failed to read file ${filePath}:`,
|
|
14405
13613
|
error instanceof Error ? error.message : String(error)
|
|
14406
13614
|
);
|
|
@@ -14410,7 +13618,7 @@ var FileCommandLoader = class {
|
|
|
14410
13618
|
try {
|
|
14411
13619
|
parsed = import_toml.default.parse(fileContent);
|
|
14412
13620
|
} catch (error) {
|
|
14413
|
-
|
|
13621
|
+
debugLogger14.error(
|
|
14414
13622
|
`[FileCommandLoader] Failed to parse TOML file ${filePath}:`,
|
|
14415
13623
|
error instanceof Error ? error.message : String(error)
|
|
14416
13624
|
);
|
|
@@ -14418,7 +13626,7 @@ var FileCommandLoader = class {
|
|
|
14418
13626
|
}
|
|
14419
13627
|
const validationResult = TomlCommandDefSchema.safeParse(parsed);
|
|
14420
13628
|
if (!validationResult.success) {
|
|
14421
|
-
|
|
13629
|
+
debugLogger14.error(
|
|
14422
13630
|
`[FileCommandLoader] Skipping invalid command file: ${filePath}. Validation errors:`,
|
|
14423
13631
|
validationResult.error.flatten()
|
|
14424
13632
|
);
|
|
@@ -14443,9 +13651,9 @@ var FileCommandLoader = class {
|
|
|
14443
13651
|
async parseAndAdaptMarkdownFile(filePath, baseDir, extensionName) {
|
|
14444
13652
|
let fileContent;
|
|
14445
13653
|
try {
|
|
14446
|
-
fileContent = await
|
|
13654
|
+
fileContent = await fs13.readFile(filePath, "utf-8");
|
|
14447
13655
|
} catch (error) {
|
|
14448
|
-
|
|
13656
|
+
debugLogger14.error(
|
|
14449
13657
|
`[FileCommandLoader] Failed to read file ${filePath}:`,
|
|
14450
13658
|
error instanceof Error ? error.message : String(error)
|
|
14451
13659
|
);
|
|
@@ -14455,7 +13663,7 @@ var FileCommandLoader = class {
|
|
|
14455
13663
|
try {
|
|
14456
13664
|
parsed = parseMarkdownCommand(fileContent);
|
|
14457
13665
|
} catch (error) {
|
|
14458
|
-
|
|
13666
|
+
debugLogger14.error(
|
|
14459
13667
|
`[FileCommandLoader] Failed to parse Markdown file ${filePath}:`,
|
|
14460
13668
|
error instanceof Error ? error.message : String(error)
|
|
14461
13669
|
);
|
|
@@ -14463,7 +13671,7 @@ var FileCommandLoader = class {
|
|
|
14463
13671
|
}
|
|
14464
13672
|
const validationResult = MarkdownCommandDefSchema.safeParse(parsed);
|
|
14465
13673
|
if (!validationResult.success) {
|
|
14466
|
-
|
|
13674
|
+
debugLogger14.error(
|
|
14467
13675
|
`[FileCommandLoader] Skipping invalid command file: ${filePath}. Validation errors:`,
|
|
14468
13676
|
validationResult.error.flatten()
|
|
14469
13677
|
);
|
|
@@ -14489,7 +13697,7 @@ var FileCommandLoader = class {
|
|
|
14489
13697
|
|
|
14490
13698
|
// packages/cli/src/services/saved-workflow-loader.ts
|
|
14491
13699
|
init_esbuild_shims();
|
|
14492
|
-
var
|
|
13700
|
+
var debugLogger15 = createDebugLogger("SavedWorkflowLoader");
|
|
14493
13701
|
var SavedWorkflowLoader = class {
|
|
14494
13702
|
constructor(config) {
|
|
14495
13703
|
this.config = config;
|
|
@@ -14508,7 +13716,7 @@ var SavedWorkflowLoader = class {
|
|
|
14508
13716
|
try {
|
|
14509
13717
|
entries = await listSavedWorkflows(this.config);
|
|
14510
13718
|
} catch (e) {
|
|
14511
|
-
|
|
13719
|
+
debugLogger15.debug(`listSavedWorkflows failed: ${e}`);
|
|
14512
13720
|
return [];
|
|
14513
13721
|
}
|
|
14514
13722
|
if (signal.aborted) return [];
|
|
@@ -14805,8 +14013,8 @@ var McpPromptLoader = class {
|
|
|
14805
14013
|
|
|
14806
14014
|
// packages/cli/src/services/SkillCommandLoader.ts
|
|
14807
14015
|
init_esbuild_shims();
|
|
14808
|
-
import { dirname as
|
|
14809
|
-
var
|
|
14016
|
+
import { dirname as dirname3 } from "node:path";
|
|
14017
|
+
var debugLogger16 = createDebugLogger("SKILL_COMMAND_LOADER");
|
|
14810
14018
|
var SkillCommandLoader = class {
|
|
14811
14019
|
constructor(config) {
|
|
14812
14020
|
this.config = config;
|
|
@@ -14816,12 +14024,12 @@ var SkillCommandLoader = class {
|
|
|
14816
14024
|
}
|
|
14817
14025
|
async loadCommands(_signal) {
|
|
14818
14026
|
if (this.config?.getBareMode?.()) {
|
|
14819
|
-
|
|
14027
|
+
debugLogger16.debug("Bare mode enabled, skipping skill commands");
|
|
14820
14028
|
return [];
|
|
14821
14029
|
}
|
|
14822
14030
|
const skillManager = this.config?.getSkillManager();
|
|
14823
14031
|
if (!skillManager) {
|
|
14824
|
-
|
|
14032
|
+
debugLogger16.debug("SkillManager not available, skipping skill commands");
|
|
14825
14033
|
return [];
|
|
14826
14034
|
}
|
|
14827
14035
|
try {
|
|
@@ -14838,7 +14046,7 @@ var SkillCommandLoader = class {
|
|
|
14838
14046
|
const nonUserInvocableCount = visibleSkills.filter(
|
|
14839
14047
|
(skill) => skill.userInvocable === false
|
|
14840
14048
|
).length;
|
|
14841
|
-
|
|
14049
|
+
debugLogger16.debug(
|
|
14842
14050
|
`Loaded ${userSkills.length} user + ${projectSkills.length} project + ${extensionSkills.length} extension skill(s) as slash commands; ${allSkills.length - visibleSkills.length} hidden by skills.disabled; ${nonUserInvocableCount} marked non-user-invocable`
|
|
14843
14051
|
);
|
|
14844
14052
|
return visibleSkills.map((skill) => {
|
|
@@ -14869,7 +14077,7 @@ var SkillCommandLoader = class {
|
|
|
14869
14077
|
skill.allowedTools
|
|
14870
14078
|
);
|
|
14871
14079
|
const body = buildSkillLlmContent(
|
|
14872
|
-
|
|
14080
|
+
dirname3(skill.filePath),
|
|
14873
14081
|
skill.body
|
|
14874
14082
|
);
|
|
14875
14083
|
const content = context.invocation?.args ? appendToLastTextPart([{ text: body }], context.invocation.raw) : [{ text: body }];
|
|
@@ -14881,7 +14089,7 @@ var SkillCommandLoader = class {
|
|
|
14881
14089
|
};
|
|
14882
14090
|
});
|
|
14883
14091
|
} catch (error) {
|
|
14884
|
-
|
|
14092
|
+
debugLogger16.error("Failed to load skill commands:", error);
|
|
14885
14093
|
return [];
|
|
14886
14094
|
}
|
|
14887
14095
|
}
|
|
@@ -14956,7 +14164,7 @@ function formatUserPromptExpansionBlockedMessage(reason) {
|
|
|
14956
14164
|
__name(formatUserPromptExpansionBlockedMessage, "formatUserPromptExpansionBlockedMessage");
|
|
14957
14165
|
|
|
14958
14166
|
// packages/cli/src/nonInteractiveCliCommands.ts
|
|
14959
|
-
var
|
|
14167
|
+
var debugLogger17 = createDebugLogger("NON_INTERACTIVE_COMMANDS");
|
|
14960
14168
|
function getSkillCommandName(command) {
|
|
14961
14169
|
return command.skillDetail?.name ?? command.name;
|
|
14962
14170
|
}
|
|
@@ -15167,6 +14375,60 @@ var handleSlashCommand = /* @__PURE__ */ __name(async (rawQuery, abortController
|
|
|
15167
14375
|
rawQuery,
|
|
15168
14376
|
filteredCommands
|
|
15169
14377
|
);
|
|
14378
|
+
const stackedResult = parseStackedSlashCommands(rawQuery, filteredCommands);
|
|
14379
|
+
if (stackedResult.skills.length >= 2) {
|
|
14380
|
+
const combinedContent = [];
|
|
14381
|
+
let firstModelOverride;
|
|
14382
|
+
const onCompleteCallbacks = [];
|
|
14383
|
+
for (const skill of stackedResult.skills) {
|
|
14384
|
+
if (!skill.action) continue;
|
|
14385
|
+
const skillContext = {
|
|
14386
|
+
executionMode,
|
|
14387
|
+
invocation: {
|
|
14388
|
+
raw: `/${skill.name}`,
|
|
14389
|
+
name: skill.name,
|
|
14390
|
+
args: ""
|
|
14391
|
+
},
|
|
14392
|
+
services: { config, settings, logger: null }
|
|
14393
|
+
};
|
|
14394
|
+
const skillResult = await skill.action(skillContext, "");
|
|
14395
|
+
if (skillResult?.type === "submit_prompt") {
|
|
14396
|
+
combinedContent.push(skillResult.content);
|
|
14397
|
+
firstModelOverride ??= skillResult.modelOverride;
|
|
14398
|
+
if (skillResult.onComplete) {
|
|
14399
|
+
onCompleteCallbacks.push(skillResult.onComplete);
|
|
14400
|
+
}
|
|
14401
|
+
}
|
|
14402
|
+
recordSkillInvocation(config, {
|
|
14403
|
+
skillName: getSkillCommandName(skill),
|
|
14404
|
+
success: skillResult?.type === "submit_prompt"
|
|
14405
|
+
});
|
|
14406
|
+
}
|
|
14407
|
+
if (stackedResult.remainingText) {
|
|
14408
|
+
combinedContent.push([{ text: stackedResult.remainingText }]);
|
|
14409
|
+
}
|
|
14410
|
+
const mergedContent = combinedContent.flat();
|
|
14411
|
+
const hookResult = await fireUserPromptExpansionHook(
|
|
14412
|
+
config,
|
|
14413
|
+
stackedResult.skills.map((s) => s.name).join(" "),
|
|
14414
|
+
stackedResult.remainingText,
|
|
14415
|
+
mergedContent,
|
|
14416
|
+
abortController.signal
|
|
14417
|
+
);
|
|
14418
|
+
if (hookResult.blockedResult) {
|
|
14419
|
+
return hookResult.blockedResult;
|
|
14420
|
+
}
|
|
14421
|
+
return {
|
|
14422
|
+
type: "submit_prompt",
|
|
14423
|
+
content: hookResult.content,
|
|
14424
|
+
...firstModelOverride ? { modelOverride: firstModelOverride } : {},
|
|
14425
|
+
...onCompleteCallbacks.length ? {
|
|
14426
|
+
onComplete: /* @__PURE__ */ __name(async () => {
|
|
14427
|
+
for (const cb of onCompleteCallbacks) await cb();
|
|
14428
|
+
}, "onComplete")
|
|
14429
|
+
} : {}
|
|
14430
|
+
};
|
|
14431
|
+
}
|
|
15170
14432
|
if (!commandToExecute) {
|
|
15171
14433
|
const { commandToExecute: knownCommand } = parseSlashCommand(
|
|
15172
14434
|
rawQuery,
|
|
@@ -15305,14 +14567,14 @@ var getAvailableCommands = /* @__PURE__ */ __name(async (config, abortSignal, mo
|
|
|
15305
14567
|
);
|
|
15306
14568
|
return commandService.getCommandsForMode(mode);
|
|
15307
14569
|
} catch (error) {
|
|
15308
|
-
|
|
14570
|
+
debugLogger17.error("Error loading available commands:", error);
|
|
15309
14571
|
return [];
|
|
15310
14572
|
}
|
|
15311
14573
|
}, "getAvailableCommands");
|
|
15312
14574
|
|
|
15313
14575
|
// packages/cli/src/utils/nonInteractiveHelpers.ts
|
|
15314
14576
|
init_esbuild_shims();
|
|
15315
|
-
var
|
|
14577
|
+
var debugLogger18 = createDebugLogger("NON_INTERACTIVE");
|
|
15316
14578
|
function normalizePartList(parts) {
|
|
15317
14579
|
if (!parts) {
|
|
15318
14580
|
return [];
|
|
@@ -15410,7 +14672,7 @@ async function loadSlashCommandNames(config) {
|
|
|
15410
14672
|
);
|
|
15411
14673
|
return commands.map((cmd) => cmd.name).sort();
|
|
15412
14674
|
} catch (error) {
|
|
15413
|
-
|
|
14675
|
+
debugLogger18.error(
|
|
15414
14676
|
"[buildSystemMessage] Failed to load slash commands:",
|
|
15415
14677
|
error
|
|
15416
14678
|
);
|
|
@@ -15435,7 +14697,7 @@ async function buildSystemMessage(config, sessionId, permissionMode) {
|
|
|
15435
14697
|
const subagents = await subagentManager.listSubagents();
|
|
15436
14698
|
agentNames = subagents.map((subagent) => subagent.name);
|
|
15437
14699
|
} catch (error) {
|
|
15438
|
-
|
|
14700
|
+
debugLogger18.error("[buildSystemMessage] Failed to load subagents:", error);
|
|
15439
14701
|
}
|
|
15440
14702
|
const systemMessage = {
|
|
15441
14703
|
type: "system",
|
|
@@ -15596,7 +14858,9 @@ function functionResponsePartsToString(parts) {
|
|
|
15596
14858
|
__name(functionResponsePartsToString, "functionResponsePartsToString");
|
|
15597
14859
|
|
|
15598
14860
|
export {
|
|
14861
|
+
MAX_STACKED_SKILLS,
|
|
15599
14862
|
parseSlashCommand,
|
|
14863
|
+
parseStackedSlashCommands,
|
|
15600
14864
|
CommandService,
|
|
15601
14865
|
useAutoAcceptIndicator,
|
|
15602
14866
|
formatApprovalModeName,
|
|
@@ -15611,8 +14875,6 @@ export {
|
|
|
15611
14875
|
findMidInputSlashCommand,
|
|
15612
14876
|
getBestSlashCommandMatch,
|
|
15613
14877
|
findSlashCommandTokens,
|
|
15614
|
-
performStandaloneUpdate,
|
|
15615
|
-
getInstallationInfo,
|
|
15616
14878
|
recordGoalStatusItem,
|
|
15617
14879
|
restoreGoalFromHistory,
|
|
15618
14880
|
getTranslatedSourceDisplayMap,
|