@qwen-code/qwen-code 0.19.12 → 0.20.0-nightly.20260721.cda0e0348
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/qc-helper/docs/configuration/settings.md +1 -1
- package/bundled/qc-helper/docs/features/commands.md +54 -0
- package/bundled/qc-helper/docs/integration-github-action.md +1 -1
- package/bundled/qc-helper/docs/qwen-serve.md +44 -6
- package/bundled/review/DESIGN.md +2 -2
- package/bundled/review/SKILL.md +13 -9
- package/chunks/{MaxSizedBox-QOXLJGAF.js → MaxSizedBox-EE76OHAP.js} +30 -27
- package/chunks/{StandaloneSessionPicker-FLV6CGYJ.js → StandaloneSessionPicker-WZH4PC3K.js} +50 -45
- package/chunks/{acpAgent-OB2CTF3P.js → acpAgent-2ATF4LMP.js} +437 -156
- package/chunks/{agent-CKSI7BTR.js → agent-KTOOFWMV.js} +22 -22
- package/chunks/{agent-headless-U36LIYTU.js → agent-headless-WVJCQ27D.js} +22 -22
- package/chunks/{anthropicContentGenerator-ZZRGFEES.js → anthropicContentGenerator-W4JLNYWQ.js} +6 -5
- package/chunks/{artifact-tool-PHO5XEGZ.js → artifact-tool-WBCAMD3O.js} +2 -2
- package/chunks/{askUserQuestion-CEPBT47X.js → askUserQuestion-6DZC4UV5.js} +2 -2
- package/chunks/{bridge-AIKTINJG.js → bridge-T4TLAZSJ.js} +25 -25
- package/chunks/build-SSCNEHZZ.js +62 -0
- package/chunks/{ca-2SL2BXTK.js → ca-ISKASTR5.js} +606 -200
- package/chunks/{channel-worker-group-NEUVTPB2.js → channel-worker-group-QZV2SP5U.js} +4 -4
- package/chunks/{channel-worker-manager-7CQVOVWV.js → channel-worker-manager-3GMAU45H.js} +4 -4
- package/chunks/{channel-worker-supervisor-3BU2KNCZ.js → channel-worker-supervisor-QCXSXCRY.js} +3 -3
- package/chunks/{chunk-6ETOSWAO.js → chunk-246TW4IX.js} +3 -3
- package/chunks/{chunk-2CCDMJM7.js → chunk-25Y6JSH2.js} +3 -3
- package/chunks/{chunk-XSEWNUMZ.js → chunk-2CWOJ2FA.js} +8 -8
- package/chunks/{chunk-UZC5VPOJ.js → chunk-2GFRA3MN.js} +3 -3
- package/chunks/chunk-2GOPPEHK.js +442 -0
- package/chunks/{chunk-MRE77ST5.js → chunk-2ITGJJE2.js} +69 -2216
- package/chunks/{chunk-BABX5XRO.js → chunk-2LI23QA6.js} +1 -1
- package/chunks/{chunk-EFAXBOQO.js → chunk-32F7BZSK.js} +7 -7
- package/chunks/chunk-43T5WDQ7.js +127 -0
- package/chunks/{chunk-DJ4VHAFJ.js → chunk-4CWPMWCD.js} +7 -3
- package/chunks/{chunk-GMUPIMHF.js → chunk-4RA7PWIY.js} +3 -3
- package/chunks/{chunk-6IITZE7O.js → chunk-5JX5EWR5.js} +7 -7
- package/chunks/{chunk-OBSLEYCD.js → chunk-5PZ6R37W.js} +29 -2
- package/chunks/{chunk-HTHUX2T5.js → chunk-5QWWOFGG.js} +0 -1
- package/chunks/{chunk-3DJY4IFO.js → chunk-5SCI6E3E.js} +1 -1
- package/chunks/{chunk-GSPWDTYY.js → chunk-5WG2K5RH.js} +53 -16
- package/chunks/{chunk-NPMVLWYL.js → chunk-5YVZ2XLV.js} +6 -6
- package/chunks/{chunk-TKASNYDS.js → chunk-6DHWO5ZF.js} +3 -3
- package/chunks/{chunk-4CHDYDG3.js → chunk-6EFTQYW7.js} +1 -1
- package/chunks/{chunk-RKUMFUFM.js → chunk-6MC5ASQK.js} +4 -4
- package/chunks/{chunk-HZ4M2UQD.js → chunk-6RVJRVQR.js} +1 -1
- package/chunks/{chunk-W6CQPLWM.js → chunk-6ZBPS62S.js} +1 -1
- package/chunks/chunk-7KGXAXF7.js +114 -0
- package/chunks/{chunk-PK7COE5O.js → chunk-ABIL4ZQU.js} +1 -1
- package/chunks/{chunk-OEHCAWUA.js → chunk-ACW3VNUE.js} +2 -2
- package/chunks/{chunk-APOFULHK.js → chunk-AWVS63WA.js} +7 -6
- package/chunks/{chunk-KGWA7XYL.js → chunk-AY3CSB6F.js} +6 -226
- package/chunks/{chunk-XAAEDML2.js → chunk-AYCDXHZB.js} +1 -1
- package/chunks/{chunk-42VIHAYT.js → chunk-B452RETY.js} +1 -1
- package/chunks/{chunk-VAJS2E2D.js → chunk-BDBMYST4.js} +1 -1
- package/chunks/{chunk-5N7M4XYN.js → chunk-BUKOHGBE.js} +5 -5
- package/chunks/{chunk-F2RR4HO2.js → chunk-BVLROR2T.js} +1 -1
- package/chunks/{chunk-WIYV7CSF.js → chunk-BWK3FX3K.js} +3 -3
- package/chunks/{chunk-UE5TZ55T.js → chunk-C27BYUX6.js} +29 -2
- package/chunks/{chunk-KRMARA3A.js → chunk-CG2HPAVD.js} +29 -13
- package/chunks/{chunk-UOA2IHRI.js → chunk-CPCVCKKF.js} +1 -1
- package/chunks/{chunk-HD6EGS5K.js → chunk-CUJX3F4X.js} +31 -6
- package/chunks/{chunk-4RPARQ5D.js → chunk-D2VIDMVM.js} +2 -2
- package/chunks/{chunk-PUKUUASO.js → chunk-DMRO4GU2.js} +1 -1
- package/chunks/{chunk-64GC5EMF.js → chunk-DZZIOIVF.js} +1 -1
- package/chunks/{chunk-FUSMC3SZ.js → chunk-E5QFCC4X.js} +13 -8
- package/chunks/{chunk-LKR7QQ63.js → chunk-EAUYY7SS.js} +3 -3
- package/chunks/{chunk-NE6HHLL3.js → chunk-EDMGFJ3E.js} +2 -2
- package/chunks/{chunk-J2MKYJKZ.js → chunk-EIAK6Q2B.js} +2 -2
- package/chunks/{chunk-WEPXQKGP.js → chunk-EZVDJFZ7.js} +1 -1
- package/chunks/{chunk-NALRQ3SG.js → chunk-FCUUJKZF.js} +394 -128
- package/chunks/{chunk-4XCVGEEX.js → chunk-FSL5W5TI.js} +3 -3
- package/chunks/{chunk-CHPQFLW6.js → chunk-FYA3Y5JR.js} +5 -5
- package/chunks/{chunk-V4PCIS25.js → chunk-FZVSFBNW.js} +69 -7
- package/chunks/{chunk-4MPYGENG.js → chunk-G45NOBV7.js} +6 -6
- package/chunks/{chunk-OSSDHJDU.js → chunk-G45X5TRN.js} +1 -1
- package/chunks/{chunk-3B6PSWHE.js → chunk-GH7OEOYU.js} +4 -4
- package/chunks/{chunk-KANTXY7B.js → chunk-GKY2OJ7R.js} +2 -2
- package/chunks/chunk-GMGDLUC7.js +37 -0
- package/chunks/{chunk-2476XGOU.js → chunk-GPILFVPY.js} +1 -1
- package/chunks/{chunk-EISVEV45.js → chunk-H24SOJIQ.js} +2 -2
- package/chunks/{chunk-J6NT5YTN.js → chunk-H2XVO6NE.js} +1 -289
- package/chunks/{chunk-QIFTJDBY.js → chunk-IM2A6YO3.js} +1 -1
- package/chunks/{chunk-R3EDIMYZ.js → chunk-IYZENXFW.js} +1 -1
- package/chunks/{chunk-LPHGXXZX.js → chunk-JD3MKVKL.js} +1 -1
- package/chunks/{chunk-NUHSLBJZ.js → chunk-JNWZQ27S.js} +15 -9
- package/chunks/{chunk-ETN2G32U.js → chunk-JPRLCXAO.js} +4 -4
- package/chunks/{chunk-WHQNBBWW.js → chunk-JQMBPGOU.js} +2 -2
- package/chunks/{chunk-5QSVANRT.js → chunk-JR6UJ24K.js} +2 -2
- package/chunks/{chunk-VLHQMOZK.js → chunk-JRW46GQX.js} +3 -3
- package/chunks/{chunk-DUR7BZYK.js → chunk-KRI4VCHX.js} +53 -28
- package/chunks/{chunk-PR5XQ73G.js → chunk-KTNIZG2C.js} +2 -2
- package/chunks/{chunk-QSG4ZFG4.js → chunk-KTUQMDEP.js} +1 -1
- package/chunks/{chunk-HVGJWOR6.js → chunk-L4YSPHR4.js} +2 -2
- package/chunks/{chunk-BEZPRKD3.js → chunk-LC5CAVMS.js} +160 -2
- package/chunks/{chunk-67Q33DQY.js → chunk-LLDGOZMJ.js} +4 -4
- package/chunks/{chunk-UCTCDLDS.js → chunk-LWQ4IAOJ.js} +136 -4
- package/chunks/{chunk-GEHSF7MS.js → chunk-NEEB7UEN.js} +2545 -1974
- package/chunks/{chunk-GCY7QTCE.js → chunk-NO6XTCYT.js} +1822 -424
- package/chunks/{chunk-JCJPZMJV.js → chunk-OOCI5VVU.js} +1 -1
- package/chunks/{chunk-XSPFQQRE.js → chunk-OONJNQ42.js} +3 -3
- package/chunks/{chunk-ANRANWVE.js → chunk-OP4MOGXF.js} +1 -1
- package/chunks/{chunk-GW7BONBU.js → chunk-OV2KB55J.js} +5 -5
- package/chunks/{chunk-CPU6I5YV.js → chunk-P64HXIC5.js} +115 -32
- package/chunks/{chunk-SGPFJMRP.js → chunk-PBATSWUQ.js} +1 -1
- package/chunks/{chunk-GXFYV7MP.js → chunk-PFKNXN67.js} +1106 -592
- package/chunks/{chunk-KNGZ5EYL.js → chunk-PYNCSQSI.js} +198 -120
- package/chunks/{chunk-I7RRHHYG.js → chunk-QKTHJXCS.js} +1 -1
- package/chunks/chunk-QKYTTBYW.js +624 -0
- package/chunks/{chunk-76BFY7AF.js → chunk-QTERJVPZ.js} +1 -6
- package/chunks/{chunk-W4UN42YP.js → chunk-R3VZNHRX.js} +85 -21
- package/chunks/chunk-R5N7NF5D.js +1187 -0
- package/chunks/{chunk-ZSDFNE6Y.js → chunk-RF34V75B.js} +3 -3
- package/chunks/{chunk-HCCR43AY.js → chunk-RFIAR4YL.js} +1 -1
- package/chunks/chunk-RS7MT2QG.js +305 -0
- package/chunks/{chunk-BKNPMEN6.js → chunk-RVLZCXEE.js} +162 -17
- package/chunks/chunk-SV5PQVQE.js +71 -0
- package/chunks/{chunk-3ESL7JXA.js → chunk-U4VGYZN7.js} +3 -3
- package/chunks/{chunk-4CA4WUMS.js → chunk-UEY4AYUL.js} +2 -2
- package/chunks/{chunk-ZGT623SG.js → chunk-USTF7LPI.js} +12 -12
- package/chunks/chunk-V7RNNPGC.js +44 -0
- package/chunks/{chunk-VEFR4XJQ.js → chunk-W3BKN3LO.js} +1 -1
- package/chunks/{chunk-4SJJT466.js → chunk-WQQDJE2P.js} +94 -177
- package/chunks/{chunk-KMJOMWHE.js → chunk-WRRF6TEQ.js} +1 -1
- package/chunks/{chunk-GLH2NTPB.js → chunk-XCHUDLER.js} +1 -1
- package/chunks/{chunk-7SX6WZNO.js → chunk-XVVH63JG.js} +3 -3
- package/chunks/{chunk-N47VAEAJ.js → chunk-XZOBDSDG.js} +2379 -1291
- package/chunks/chunk-YGIUIIIF.js +125 -0
- package/chunks/{chunk-335ECZTA.js → chunk-ZEOZL37W.js} +1 -1
- package/chunks/{computer-use-4PUGCUQK.js → computer-use-M6MGRJF2.js} +22 -22
- package/chunks/{config-utils-6PJUXHLI.js → config-utils-MOGE4EVB.js} +3 -3
- package/chunks/{contextCommand-C57KTWFV.js → contextCommand-HTRJJYNE.js} +25 -26
- package/chunks/{create-sub-session-5Q42XR6I.js → create-sub-session-MB35IHCR.js} +22 -22
- package/chunks/{create-sub-session-DIJOV6HV.js → create-sub-session-P26FE5GG.js} +2 -2
- package/chunks/{cron-create-X462ERYA.js → cron-create-JWFHBDRQ.js} +4 -4
- package/chunks/{cron-delete-SL5UJUM3.js → cron-delete-GDX4E26G.js} +4 -4
- package/chunks/{cron-list-3MD6SVXI.js → cron-list-USMAIWPT.js} +4 -4
- package/chunks/{daemon-ZW6LHOXT.js → daemon-KLPTQIE4.js} +287 -143
- package/chunks/{daemon-status-provider-YPV3UXHT.js → daemon-status-provider-67EKK6S3.js} +29 -29
- package/chunks/{dist-NUXRQHC5.js → dist-OAV7LJGJ.js} +1 -1
- package/chunks/{dist-XLE6ODMB.js → dist-OMW6WDEO.js} +1 -1
- package/chunks/{dist-J2H4KTLB.js → dist-PJLG2XYX.js} +1 -1
- package/chunks/{dist-IEQSDXS7.js → dist-UIFWIFRO.js} +2 -2
- package/chunks/{dist-IGZMVS5R.js → dist-VGJTZL4E.js} +33 -22
- package/chunks/{dist-3DQNQJ6H.js → dist-XBJVSWS2.js} +1 -1
- package/chunks/{earlyInputCapture-5VDWSYAM.js → earlyInputCapture-7QJX25AC.js} +23 -23
- package/chunks/{edit-GORZTX2U.js → edit-BTPQWGAA.js} +23 -23
- package/chunks/{enter-worktree-LJB2AW4L.js → enter-worktree-N3SEYKOO.js} +22 -22
- package/chunks/{enterPlanMode-LIIPP37T.js → enterPlanMode-TN2JV5MY.js} +28 -23
- package/chunks/{environment-HQ2UHJ35.js → environment-HP6RK262.js} +24 -24
- package/chunks/{errors-6JD5VMVQ.js → errors-VHGRDDOQ.js} +24 -24
- package/chunks/{exit-worktree-IEP2WHOV.js → exit-worktree-FI3SQY3U.js} +22 -22
- package/chunks/{exitPlanMode-U5Z6XBLO.js → exitPlanMode-NZWRVIIY.js} +22 -22
- package/chunks/{fast-path-HFKNMP23.js → fast-path-EGP7AXNR.js} +3 -2
- package/chunks/{gemini-C2SCJH3N.js → gemini-AN5YMD5O.js} +70 -68
- package/chunks/{geminiContentGenerator-ADZTXEKV.js → geminiContentGenerator-ABTMU4FE.js} +4 -4
- package/chunks/{glob-GOAPGD6G.js → glob-5YABOPJB.js} +22 -22
- package/chunks/{grep-HZLSTX7D.js → grep-U67FKUJT.js} +22 -22
- package/chunks/{handleAutoUpdate-UF74WGFE.js → handleAutoUpdate-OOKBP5VD.js} +27 -28
- package/chunks/{i18n-FMXIYUOC.js → i18n-GMQV324P.js} +23 -23
- package/chunks/{initializer-ERDBM3DU.js → initializer-NWALZGQ5.js} +28 -28
- package/chunks/{installationInfo-LROMXYLX.js → installationInfo-Y3M433E7.js} +25 -23
- package/chunks/{keychain-token-storage-K23CFKGN.js → keychain-token-storage-DWRJMNH3.js} +2 -2
- package/chunks/{list-6JPJROU5.js → list-CQDDWHTS.js} +30 -30
- package/chunks/{loadedSettingsAdapter-QCWYUBBF.js → loadedSettingsAdapter-I5KG37EI.js} +27 -27
- package/chunks/{loop-wakeup-6H7OENTB.js → loop-wakeup-5GLTUBHA.js} +5 -5
- package/chunks/{ls-APTSOOS5.js → ls-FHBY3Y7I.js} +4 -4
- package/chunks/{lsp-HPACPJAN.js → lsp-B6VMEW6Y.js} +2 -2
- package/chunks/{mcp-3P3KWYWO.js → mcp-24HHCBSP.js} +27 -27
- package/chunks/{monitor-LMYKCF6R.js → monitor-Z7NZNNRC.js} +22 -22
- package/chunks/nonInteractiveCli-GVF2XDJT.js +126 -0
- package/chunks/{notebook-edit-IBEOVZ6A.js → notebook-edit-GFOYAQAZ.js} +23 -23
- package/chunks/{openaiContentGenerator-42PZKET5.js → openaiContentGenerator-XAAYV6WR.js} +11 -11
- package/chunks/{pidfile-VTBDIGOH.js → pidfile-ILI37KRQ.js} +23 -23
- package/chunks/{processUtils-L7ZKOGDG.js → processUtils-LIPJMLVZ.js} +2 -2
- package/chunks/{qwenContentGenerator-VR2CNFGI.js → qwenContentGenerator-DLJ3KKGZ.js} +24 -24
- package/chunks/{qwenOAuth2-6LS2T3Q6.js → qwenOAuth2-J47FU5PW.js} +11 -11
- package/chunks/react-SG7JAQSZ.js +8 -0
- package/chunks/{read-file-VSKOE22I.js → read-file-LCQ2KNNP.js} +8 -8
- package/chunks/{read-mcp-resource-C6NT52T6.js → read-mcp-resource-AKCL7I43.js} +2 -2
- package/chunks/{record-artifact-ENCU7QCL.js → record-artifact-PEUB7727.js} +2 -2
- package/chunks/resumeHistoryUtils-PSCSAKA6.js +78 -0
- package/chunks/{ripGrep-5V5FLW2A.js → ripGrep-Y2XW4EFC.js} +22 -22
- package/chunks/{run-qwen-serve-LSOPP4R2.js → run-qwen-serve-DQ5ZIR36.js} +1459 -148
- package/chunks/{runtime-LT7R4CS5.js → runtime-6MQFF2A6.js} +33 -31
- package/chunks/{scheduler-YOWQ7KZP.js → scheduler-K4S7NY3G.js} +22 -22
- package/chunks/{send-message-5GZ4FX2V.js → send-message-3RHE7HSM.js} +3 -3
- package/chunks/{serve-VWLBXKGK.js → serve-JFAAPC5J.js} +27 -27
- package/chunks/{server-3RW3FYOH.js → server-QB6CHRZN.js} +866 -271
- package/chunks/{session-ZONXFOBQ.js → session-FKPVXAAB.js} +79 -163
- package/chunks/{settings-JC3VC53L.js → settings-CADELKSU.js} +26 -26
- package/chunks/{shell-2NGEMAVM.js → shell-EON6WVVH.js} +22 -22
- package/chunks/{skill-3U2T6H3E.js → skill-FKSYXJ5U.js} +10 -10
- package/chunks/{spawnChannel-QEAUPARQ.js → spawnChannel-VM5IHLJO.js} +24 -24
- package/chunks/{src-75ZPXO7B.js → src-Q4XB6SVD.js} +66 -22
- package/chunks/{standalone-update-UUJWJWYY.js → standalone-update-KGZHPBMA.js} +24 -24
- package/chunks/{startInteractiveUI-V7XISPQ6.js → startInteractiveUI-EYDJIIIZ.js} +5484 -2045
- package/chunks/{syntheticOutput-ULOVVLY4.js → syntheticOutput-FG5PQKIR.js} +3 -3
- package/chunks/{task-create-DUE2PMNI.js → task-create-HX32YXO7.js} +7 -7
- package/chunks/{task-list-WVPNX7BZ.js → task-list-QWSY4ZIU.js} +5 -5
- package/chunks/{task-stop-CPEQWOT6.js → task-stop-GWC6UWAL.js} +2 -2
- package/chunks/{task-update-HY2LNFFB.js → task-update-NCTAB73Q.js} +7 -7
- package/chunks/{team-create-R6AXDYPG.js → team-create-CYP3YKYT.js} +22 -22
- package/chunks/{team-delete-JJV6IUOA.js → team-delete-KK37HTOG.js} +5 -5
- package/chunks/{team-plan-approval-O2ZPPT64.js → team-plan-approval-5LXIFKNV.js} +22 -22
- package/chunks/{theme-manager-YIX2IC2D.js → theme-manager-QOUMDWMP.js} +23 -23
- package/chunks/{todoWrite-JHHIDOIV.js → todoWrite-ERCAMLFS.js} +4 -4
- package/chunks/{tool-search-5IE2VO7X.js → tool-search-Q27QHQU3.js} +9 -9
- package/chunks/{total-session-admission-K6APQYEF.js → total-session-admission-HWVCZ2WR.js} +25 -25
- package/chunks/{trustedFolders-GPSSPVBF.js → trustedFolders-C6664IQC.js} +23 -23
- package/chunks/{update-relaunch-4BVAPX6Y.js → update-relaunch-QC3E4FZW.js} +9 -9
- package/chunks/{updateCheck-AHTHWLAM.js → updateCheck-MVUKJMBX.js} +33 -26
- package/chunks/useAutoAcceptIndicator-J234IFIS.js +80 -0
- package/chunks/{validateNonInterActiveAuth-UKAPCWDM.js → validateNonInterActiveAuth-YPPEKX4N.js} +61 -63
- package/chunks/{version-EXGWKKQE.js → version-5IXFQ4PT.js} +1 -1
- package/chunks/{web-fetch-ZDNE6FF2.js → web-fetch-L62NQVKN.js} +10 -10
- package/chunks/{workflow-G7U6OQWS.js → workflow-6MHBBFQU.js} +23 -23
- package/chunks/{workspace-providers-status-W6CEA6YM.js → workspace-providers-status-ZTW2B5QU.js} +30 -30
- package/chunks/{workspace-registration-store-OGBMWCLC.js → workspace-registration-store-P6QHCSMU.js} +7 -1
- package/chunks/{workspace-registry-ZUWQM44P.js → workspace-registry-R54M5O3W.js} +25 -25
- package/chunks/{workspace-service-UXX5P7GU.js → workspace-service-WYLRGM4A.js} +32 -32
- package/chunks/{workspace-skills-status-635B5R7N.js → workspace-skills-status-NN5QFU3A.js} +28 -28
- package/chunks/{write-file-DR3HN7IH.js → write-file-EAT3CHUK.js} +23 -23
- package/cli.js +11 -11
- package/locales/ca.js +763 -201
- package/package.json +3 -3
- package/web-shell/assets/{arc-_dVIKMdB.js → arc-B0iTWRo2.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-MuN3nKpL.js → architectureDiagram-3BPJPVTR-DSQP4-9D.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-BtmvJjzx.js → blockDiagram-GPEHLZMM-BNPVXVT3.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-Dvi58_BU.js → c4Diagram-AAUBKEIU-DEHfJFiD.js} +1 -1
- package/web-shell/assets/channel-tVz-qNSq.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-YqxOVhS1.js → chunk-2J33WTMH-VZ0uL1p9.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-DoBgbC9z.js → chunk-4BX2VUAB-D5TKmvwG.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-3NEQrBAr.js → chunk-55IACEB6-BDW1Lcq-.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-DrCZQxp0.js → chunk-727SXJPM-Cj4h85iM.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-m_g3zjgv.js → chunk-AQP2D5EJ-5LeqiOhZ.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-D1_crABJ.js → chunk-FMBD7UC4-BaTgsco7.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-BdhgVtBx.js → chunk-ND2GUHAM-t3uGlIUk.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-BlmThhm-.js → chunk-QZHKN3VN-rOnNXL2Q.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-CWuaBxYV.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CWuaBxYV.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-Cbjm_00Z.js → cose-bilkent-S5V4N54A-CcqXykgA.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-C39QNVgC.js → dagre-BM42HDAG-Dkjrchoy.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-DNXSAixC.js → diagram-2AECGRRQ-B6lcra9M.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-BCbGUPEA.js → diagram-5GNKFQAL-bAIzq3PT.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-1eujKSDC.js → diagram-KO2AKTUF-G9MAZDNW.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-DUMKXgql.js → diagram-LMA3HP47-DVLF1uWZ.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-BFktU3_u.js → diagram-OG6HWLK6-Cf7y20Tc.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-BvJC7DLk.js → erDiagram-TEJ5UH35-C7ETZB3o.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-Cgu3PlOt.js → flowDiagram-I6XJVG4X-Cl2xgL6J.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-DLNXN5Xh.js → ganttDiagram-6RSMTGT7-BgjbMs3q.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-BQFRDv6R.js → gitGraphDiagram-PVQCEYII-JVX34Omm.js} +1 -1
- package/web-shell/assets/index-48bIcdqF.js +1197 -0
- package/web-shell/assets/{index-CdC3pjP3.js → index-BG7Zc4f_.js} +1 -1
- package/web-shell/assets/index-BI-JAO07.css +5 -0
- package/web-shell/assets/{infoDiagram-5YYISTIA-DT2mOSvp.js → infoDiagram-5YYISTIA-3NYyMeZU.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-9fy_K4bd.js → ishikawaDiagram-YF4QCWOH-C03VCu-U.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-CoGSEuhE.js → journeyDiagram-JHISSGLW-C9PuBRZW.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-BP9hHYIj.js → kanban-definition-UN3LZRKU-C3LvioWR.js} +1 -1
- package/web-shell/assets/{linear-uIroDsmp.js → linear-Du6Yw8N_.js} +1 -1
- package/web-shell/assets/{mermaid.core-BUwoStsA.js → mermaid.core-BXY5D2-X.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-DZB-FWim.js → mindmap-definition-RKZ34NQL-2UrHLaDp.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-YPptloKl.js → pieDiagram-4H26LBE5-dC03ml45.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-dgk3DSzm.js → quadrantDiagram-W4KKPZXB-CD6jARrp.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-BH2En2i9.js → requirementDiagram-4Y6WPE33-BrK8aXfv.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-BB98feeI.js → sankeyDiagram-5OEKKPKP-B5Vitki_.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-CunAIGh8.js → sequenceDiagram-3UESZ5HK-CBy2t6Bo.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-DTJs_-I2.js → stateDiagram-AJRCARHV-Enrka6T2.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DUtYfXpW.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-Cd4AN7O0.js → timeline-definition-PNZ67QCA-CwFq78ss.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-xIG-rUU9.js → vennDiagram-CIIHVFJN-BkOidM0g.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-D1UyjIcG.js → wardley-L42UT6IY-D_j13hQW.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-BVM0Mb99.js → wardleyDiagram-YWT4CUSO-7EveB1w6.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-BX31JDSz.js → xychartDiagram-2RQKCTM6-DRkBhMXr.js} +1 -1
- package/web-shell/index.html +2 -2
- package/chunks/chunk-EDFD7VOX.js +0 -368
- package/chunks/chunk-GFYFLDEG.js +0 -709
- package/chunks/chunk-LUJQUNKY.js +0 -3288
- package/chunks/nonInteractiveCli-YURFHZV5.js +0 -129
- package/web-shell/assets/channel-Bi5TehaT.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-BKhhRdd1.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BKhhRdd1.js +0 -1
- package/web-shell/assets/index-C_ouplMQ.js +0 -1187
- package/web-shell/assets/index-XGDFJE-X.css +0 -5
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DrfFMYta.js +0 -1
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
computeCpuPercent
|
|
6
6
|
} from "./chunk-HGT6JR3U.js";
|
|
7
7
|
import {
|
|
8
|
+
ACCESS_LOG_CONTROLLER_LOCAL,
|
|
8
9
|
CAPABILITIES_SCHEMA_VERSION,
|
|
9
10
|
ClientMcpSenderRegistry,
|
|
10
11
|
PathMutexRegistry,
|
|
@@ -29,7 +30,7 @@ import {
|
|
|
29
30
|
require_express,
|
|
30
31
|
resolveWebShellDir,
|
|
31
32
|
setDeferredRuntimeRequestTiming
|
|
32
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-LC5CAVMS.js";
|
|
33
34
|
import {
|
|
34
35
|
isLoopbackBind
|
|
35
36
|
} from "./chunk-RXFQM6FQ.js";
|
|
@@ -46,7 +47,7 @@ import {
|
|
|
46
47
|
import "./chunk-WBL3FJEU.js";
|
|
47
48
|
import {
|
|
48
49
|
resolveChannelCwd
|
|
49
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-6ZBPS62S.js";
|
|
50
51
|
import {
|
|
51
52
|
loadServeFastPathSettings,
|
|
52
53
|
preResolveServeFastPathHomeEnvOverrides
|
|
@@ -55,16 +56,16 @@ import {
|
|
|
55
56
|
MAX_REGISTERED_WORKSPACES,
|
|
56
57
|
resolveWorkspaceInputs,
|
|
57
58
|
workspaceRegistrationId
|
|
58
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-LWQ4IAOJ.js";
|
|
59
60
|
import {
|
|
60
61
|
canonicalizeWorkspace
|
|
61
62
|
} from "./chunk-W7FJ3N32.js";
|
|
62
|
-
import "./chunk-
|
|
63
|
-
import "./chunk-
|
|
63
|
+
import "./chunk-ACW3VNUE.js";
|
|
64
|
+
import "./chunk-H24SOJIQ.js";
|
|
64
65
|
import {
|
|
65
66
|
ChannelWebhookEnqueueError,
|
|
66
67
|
QWEN_SERVER_TOKEN_ENV
|
|
67
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-QKTHJXCS.js";
|
|
68
69
|
import {
|
|
69
70
|
channelSelectionNames
|
|
70
71
|
} from "./chunk-TJTKSVIV.js";
|
|
@@ -73,7 +74,7 @@ import "./chunk-5HBA2Z7V.js";
|
|
|
73
74
|
import "./chunk-T2NCM2ET.js";
|
|
74
75
|
import {
|
|
75
76
|
sanitizeLogText
|
|
76
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-RVLZCXEE.js";
|
|
77
78
|
import "./chunk-UDXSXLER.js";
|
|
78
79
|
import "./chunk-GOXKNSDZ.js";
|
|
79
80
|
import {
|
|
@@ -83,7 +84,7 @@ import {
|
|
|
83
84
|
import "./chunk-QRUIS3DN.js";
|
|
84
85
|
import {
|
|
85
86
|
getCliVersion
|
|
86
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-XCHUDLER.js";
|
|
87
88
|
import "./chunk-VJNBRRZG.js";
|
|
88
89
|
import "./chunk-ALGGS7UH.js";
|
|
89
90
|
import {
|
|
@@ -96,7 +97,9 @@ import {
|
|
|
96
97
|
import "./chunk-5M6IDOMF.js";
|
|
97
98
|
import "./chunk-T4TZQJ7W.js";
|
|
98
99
|
import "./chunk-H6XPXXMH.js";
|
|
99
|
-
import
|
|
100
|
+
import {
|
|
101
|
+
require_proper_lockfile
|
|
102
|
+
} from "./chunk-E2UVIFI2.js";
|
|
100
103
|
import "./chunk-CR3C7WXL.js";
|
|
101
104
|
import "./chunk-XWRJCPHC.js";
|
|
102
105
|
import {
|
|
@@ -122,7 +125,7 @@ import * as fs from "node:fs";
|
|
|
122
125
|
import * as https from "node:https";
|
|
123
126
|
import * as path from "node:path";
|
|
124
127
|
import * as os from "node:os";
|
|
125
|
-
import { monitorEventLoopDelay, performance } from "node:perf_hooks";
|
|
128
|
+
import { monitorEventLoopDelay, performance as performance2 } from "node:perf_hooks";
|
|
126
129
|
|
|
127
130
|
// packages/cli/src/serve/permission-audit.ts
|
|
128
131
|
init_esbuild_shims();
|
|
@@ -243,9 +246,11 @@ __name(createPermissionAuditPublisher, "createPermissionAuditPublisher");
|
|
|
243
246
|
|
|
244
247
|
// packages/cli/src/serve/daemon-logger.ts
|
|
245
248
|
init_esbuild_shims();
|
|
249
|
+
var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
|
|
246
250
|
import * as nodeFs from "node:fs";
|
|
247
251
|
import * as nodePath from "node:path";
|
|
248
252
|
import * as crypto from "node:crypto";
|
|
253
|
+
import { performance } from "node:perf_hooks";
|
|
249
254
|
var FIXED_CTX_ORDER = [
|
|
250
255
|
"route",
|
|
251
256
|
"sessionId",
|
|
@@ -254,6 +259,31 @@ var FIXED_CTX_ORDER = [
|
|
|
254
259
|
"channelId"
|
|
255
260
|
];
|
|
256
261
|
var FIXED_CTX_SET = new Set(FIXED_CTX_ORDER);
|
|
262
|
+
var ISSUE_ORDER = [
|
|
263
|
+
"init_failed",
|
|
264
|
+
"rotation_failed",
|
|
265
|
+
"retention_failed",
|
|
266
|
+
"queue_overflow",
|
|
267
|
+
"write_failed",
|
|
268
|
+
"lease_compromised"
|
|
269
|
+
];
|
|
270
|
+
var DEFAULT_POLICY = {
|
|
271
|
+
maxBytes: 10 * 1024 * 1024,
|
|
272
|
+
maxArchives: 4,
|
|
273
|
+
maxRecordBytes: 256 * 1024,
|
|
274
|
+
maxPendingBytes: 4 * 1024 * 1024,
|
|
275
|
+
stableAcquireBudgetMs: 1e3,
|
|
276
|
+
maintenanceAcquireBudgetMs: 250,
|
|
277
|
+
lockStaleMs: 6e4,
|
|
278
|
+
lockUpdateMs: 1e4,
|
|
279
|
+
rotationRetryIntervalMs: 6e4,
|
|
280
|
+
closeDrainBudgetMs: 2e3
|
|
281
|
+
};
|
|
282
|
+
var ARCHIVE_RE = /^daemon-(\d{12})-(\d{8}T\d{9}Z)-([0-9a-f]{8})\.log$/;
|
|
283
|
+
var FALLBACK_DIR_RE = /^run-[0-9a-f]{32}$/;
|
|
284
|
+
var ARCHIVE_NAME_ATTEMPTS = 3;
|
|
285
|
+
var FILE_MODE = 384;
|
|
286
|
+
var DIRECTORY_MODE = 448;
|
|
257
287
|
function renderCtxValue(value) {
|
|
258
288
|
const s = String(value);
|
|
259
289
|
return /[\s=]/.test(s) ? JSON.stringify(s) : s;
|
|
@@ -269,7 +299,7 @@ function renderCtx(ctx) {
|
|
|
269
299
|
}
|
|
270
300
|
}
|
|
271
301
|
const extraKeys = Object.keys(ctx).filter(
|
|
272
|
-
(
|
|
302
|
+
(key) => !FIXED_CTX_SET.has(key) && ctx[key] !== void 0 && ctx[key] !== null
|
|
273
303
|
).sort();
|
|
274
304
|
for (const key of extraKeys) {
|
|
275
305
|
parts.push(`${key}=${renderCtxValue(ctx[key])}`);
|
|
@@ -280,7 +310,7 @@ __name(renderCtx, "renderCtx");
|
|
|
280
310
|
function renderErr(err) {
|
|
281
311
|
if (!err) return "";
|
|
282
312
|
const body = err.stack ?? `${err.name ?? "Error"}: ${err.message}`;
|
|
283
|
-
return body.split("\n").map((
|
|
313
|
+
return body.split("\n").map((line) => ` ${line}`).join("\n") + "\n";
|
|
284
314
|
}
|
|
285
315
|
__name(renderErr, "renderErr");
|
|
286
316
|
function buildDaemonLogLine(args) {
|
|
@@ -290,19 +320,17 @@ function buildDaemonLogLine(args) {
|
|
|
290
320
|
${renderErr(args.err)}`;
|
|
291
321
|
}
|
|
292
322
|
__name(buildDaemonLogLine, "buildDaemonLogLine");
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
flush: /* @__PURE__ */ __name(() => Promise.resolve(), "flush")
|
|
305
|
-
};
|
|
323
|
+
function buildDaemonFileLogLine(args, runId, pid) {
|
|
324
|
+
const callerCtx = args.ctx ? Object.fromEntries(
|
|
325
|
+
Object.entries(args.ctx).filter(
|
|
326
|
+
([key]) => key !== "runId" && key !== "pid"
|
|
327
|
+
)
|
|
328
|
+
) : void 0;
|
|
329
|
+
const ctxStr = renderCtx(callerCtx);
|
|
330
|
+
return `${args.now.toISOString()} [${args.level}] [DAEMON] runId=${runId} pid=${pid} ${ctxStr}${args.message}
|
|
331
|
+
${renderErr(args.err)}`;
|
|
332
|
+
}
|
|
333
|
+
__name(buildDaemonFileLogLine, "buildDaemonFileLogLine");
|
|
306
334
|
function getRuntimeBaseDir(runtimeOutputDir, cwd) {
|
|
307
335
|
const envDir = process.env["QWEN_RUNTIME_DIR"];
|
|
308
336
|
if (envDir) return resolveConfigPathLite(envDir);
|
|
@@ -314,19 +342,6 @@ function resolveDaemonLogBaseDir(runtimeOutputDir, cwd) {
|
|
|
314
342
|
return nodePath.join(getRuntimeBaseDir(runtimeOutputDir, cwd), "debug");
|
|
315
343
|
}
|
|
316
344
|
__name(resolveDaemonLogBaseDir, "resolveDaemonLogBaseDir");
|
|
317
|
-
async function updateSymlinkBestEffort(linkPath, targetPath) {
|
|
318
|
-
const linkDir = nodePath.dirname(linkPath);
|
|
319
|
-
const relativeTarget = nodePath.relative(linkDir, targetPath);
|
|
320
|
-
try {
|
|
321
|
-
await nodeFs.promises.unlink(linkPath);
|
|
322
|
-
} catch {
|
|
323
|
-
}
|
|
324
|
-
try {
|
|
325
|
-
await nodeFs.promises.symlink(relativeTarget, linkPath);
|
|
326
|
-
} catch {
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
__name(updateSymlinkBestEffort, "updateSymlinkBestEffort");
|
|
330
345
|
function isOptedOut() {
|
|
331
346
|
const raw = process.env["QWEN_DAEMON_LOG_FILE"];
|
|
332
347
|
if (!raw) return false;
|
|
@@ -341,73 +356,1252 @@ function computeDaemonId(pid) {
|
|
|
341
356
|
return `daemon:${pid}`;
|
|
342
357
|
}
|
|
343
358
|
__name(computeDaemonId, "computeDaemonId");
|
|
344
|
-
function
|
|
345
|
-
return
|
|
359
|
+
function isErrno(error, code) {
|
|
360
|
+
return error instanceof Error && "code" in error && error.code === code;
|
|
346
361
|
}
|
|
347
|
-
__name(
|
|
348
|
-
function
|
|
349
|
-
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
362
|
+
__name(isErrno, "isErrno");
|
|
363
|
+
function resolvePolicy(overrides) {
|
|
364
|
+
const policy = { ...DEFAULT_POLICY, ...overrides };
|
|
365
|
+
for (const [name, value] of Object.entries(policy)) {
|
|
366
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
367
|
+
throw new TypeError(`Invalid daemon logger policy ${name}=${value}`);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (policy.maxBytes === 0 || policy.maxArchives === 0 || policy.maxRecordBytes === 0 || policy.maxPendingBytes === 0) {
|
|
371
|
+
throw new TypeError(
|
|
372
|
+
"Daemon logger size/count policy values must be positive"
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
if (policy.maxRecordBytes > policy.maxBytes) {
|
|
376
|
+
throw new TypeError(
|
|
377
|
+
"Daemon logger maxRecordBytes must not exceed maxBytes"
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
if (policy.maxRecordBytes > policy.maxPendingBytes) {
|
|
381
|
+
throw new TypeError(
|
|
382
|
+
"Daemon logger maxRecordBytes must not exceed maxPendingBytes"
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
return policy;
|
|
386
|
+
}
|
|
387
|
+
__name(resolvePolicy, "resolvePolicy");
|
|
388
|
+
function statusSnapshot(runId, mode, issues, droppedRecords, droppedBytes) {
|
|
389
|
+
return {
|
|
390
|
+
runId,
|
|
391
|
+
mode,
|
|
392
|
+
health: issues.size === 0 ? "ok" : "degraded",
|
|
393
|
+
issues: ISSUE_ORDER.filter((issue) => issues.has(issue)),
|
|
394
|
+
droppedRecords,
|
|
395
|
+
droppedBytes
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
__name(statusSnapshot, "statusSnapshot");
|
|
399
|
+
function createStderrOnlyLogger(input) {
|
|
400
|
+
const tee = /* @__PURE__ */ __name((level, message, ctx, err) => {
|
|
401
|
+
input.stderr(
|
|
402
|
+
buildDaemonLogLine({
|
|
403
|
+
level,
|
|
404
|
+
message,
|
|
405
|
+
now: input.now(),
|
|
406
|
+
ctx,
|
|
407
|
+
err
|
|
408
|
+
}).trimEnd()
|
|
409
|
+
);
|
|
410
|
+
}, "tee");
|
|
411
|
+
return {
|
|
412
|
+
info: /* @__PURE__ */ __name((message, ctx) => tee("INFO", message, ctx), "info"),
|
|
413
|
+
warn: /* @__PURE__ */ __name((message, ctx) => tee("WARN", message, ctx), "warn"),
|
|
414
|
+
error: /* @__PURE__ */ __name((message, err, ctx) => tee("ERROR", message, ctx, err ?? void 0), "error"),
|
|
415
|
+
raw: /* @__PURE__ */ __name(() => {
|
|
416
|
+
}, "raw"),
|
|
417
|
+
getLogPath: /* @__PURE__ */ __name(() => "", "getLogPath"),
|
|
418
|
+
getDaemonId: /* @__PURE__ */ __name(() => input.daemonId, "getDaemonId"),
|
|
419
|
+
getStatus: /* @__PURE__ */ __name(() => statusSnapshot(input.runId, "stderr-only", input.issues, 0, 0), "getStatus"),
|
|
420
|
+
flush: /* @__PURE__ */ __name(() => Promise.resolve(), "flush"),
|
|
421
|
+
close: /* @__PURE__ */ __name(() => Promise.resolve(), "close")
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
__name(createStderrOnlyLogger, "createStderrOnlyLogger");
|
|
425
|
+
function capUtf8Record(record, maxBytes) {
|
|
426
|
+
const bytes = Buffer.from(record, "utf8");
|
|
427
|
+
if (bytes.length <= maxBytes) return record;
|
|
428
|
+
const marker = `
|
|
429
|
+
[truncated originalBytes=${bytes.length}]
|
|
430
|
+
`;
|
|
431
|
+
const markerBytes = Buffer.from(marker, "utf8");
|
|
432
|
+
if (markerBytes.length >= maxBytes) {
|
|
433
|
+
return Buffer.from("[truncated]\n", "utf8").subarray(0, maxBytes).toString("utf8");
|
|
434
|
+
}
|
|
435
|
+
let prefixBytes = maxBytes - markerBytes.length;
|
|
436
|
+
while (prefixBytes > 0 && (bytes[prefixBytes] & 192) === 128) {
|
|
437
|
+
prefixBytes -= 1;
|
|
438
|
+
}
|
|
439
|
+
return bytes.subarray(0, prefixBytes).toString("utf8") + marker;
|
|
440
|
+
}
|
|
441
|
+
__name(capUtf8Record, "capUtf8Record");
|
|
442
|
+
async function ensureRealDirectory(fs2, dirPath, mutationAllowed = () => true) {
|
|
443
|
+
try {
|
|
444
|
+
const existing = await fs2.lstat(dirPath);
|
|
445
|
+
if (!existing.isDirectory() || existing.isSymbolicLink()) {
|
|
446
|
+
throw new Error(`${dirPath} is not a real directory`);
|
|
447
|
+
}
|
|
448
|
+
return;
|
|
449
|
+
} catch (error) {
|
|
450
|
+
if (!isErrno(error, "ENOENT")) throw error;
|
|
451
|
+
}
|
|
452
|
+
if (!mutationAllowed()) {
|
|
453
|
+
throw new Error(`File mutation is no longer allowed for ${dirPath}`);
|
|
454
|
+
}
|
|
455
|
+
await fs2.mkdir(dirPath, { recursive: true, mode: DIRECTORY_MODE });
|
|
456
|
+
const created = await fs2.lstat(dirPath);
|
|
457
|
+
if (!created.isDirectory() || created.isSymbolicLink()) {
|
|
458
|
+
throw new Error(`${dirPath} is not a real directory`);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
__name(ensureRealDirectory, "ensureRealDirectory");
|
|
462
|
+
async function activeFileSize(fs2, activePath) {
|
|
358
463
|
try {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
464
|
+
const stat = await fs2.lstat(activePath);
|
|
465
|
+
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
466
|
+
throw new Error(`${activePath} is not a regular file`);
|
|
467
|
+
}
|
|
468
|
+
return stat.size;
|
|
469
|
+
} catch (error) {
|
|
470
|
+
if (isErrno(error, "ENOENT")) return 0;
|
|
471
|
+
throw error;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
__name(activeFileSize, "activeFileSize");
|
|
475
|
+
async function lastByteIsNewline(fs2, activePath, size) {
|
|
476
|
+
if (size === 0) return true;
|
|
477
|
+
const handle = await fs2.open(activePath, "r");
|
|
478
|
+
try {
|
|
479
|
+
const buffer = Buffer.allocUnsafe(1);
|
|
480
|
+
const result = await handle.read(buffer, 0, 1, size - 1);
|
|
481
|
+
return result.bytesRead === 1 && buffer[0] === 10;
|
|
482
|
+
} finally {
|
|
483
|
+
await handle.close();
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
__name(lastByteIsNewline, "lastByteIsNewline");
|
|
487
|
+
function archiveTimestamp(now) {
|
|
488
|
+
return now.toISOString().replace(/[-:.]/g, "");
|
|
489
|
+
}
|
|
490
|
+
__name(archiveTimestamp, "archiveTimestamp");
|
|
491
|
+
async function scanArchives(fs2, archiveDir) {
|
|
492
|
+
const entries = await fs2.readdir(archiveDir, { withFileTypes: true });
|
|
493
|
+
const archives = [];
|
|
494
|
+
for (const entry of entries) {
|
|
495
|
+
if (!entry.isFile()) continue;
|
|
496
|
+
const match = ARCHIVE_RE.exec(entry.name);
|
|
497
|
+
if (!match) continue;
|
|
498
|
+
archives.push({ name: entry.name, generation: Number(match[1]) });
|
|
499
|
+
}
|
|
500
|
+
archives.sort(
|
|
501
|
+
(a, b) => a.generation - b.generation || a.name.localeCompare(b.name)
|
|
502
|
+
);
|
|
503
|
+
return archives;
|
|
504
|
+
}
|
|
505
|
+
__name(scanArchives, "scanArchives");
|
|
506
|
+
function lockRetries(maxRetryTime) {
|
|
507
|
+
if (maxRetryTime <= 0) return 0;
|
|
508
|
+
return {
|
|
509
|
+
retries: 4,
|
|
510
|
+
factor: 2,
|
|
511
|
+
minTimeout: 50,
|
|
512
|
+
maxTimeout: 400,
|
|
513
|
+
randomize: true,
|
|
514
|
+
maxRetryTime
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
__name(lockRetries, "lockRetries");
|
|
518
|
+
async function acquireLease(input) {
|
|
519
|
+
const lease = {
|
|
520
|
+
compromised: false,
|
|
521
|
+
released: false,
|
|
522
|
+
release: /* @__PURE__ */ __name(async () => {
|
|
523
|
+
}, "release")
|
|
524
|
+
};
|
|
525
|
+
const release = await input.acquireLock(input.targetPath, {
|
|
526
|
+
lockfilePath: input.lockPath,
|
|
527
|
+
realpath: true,
|
|
528
|
+
stale: input.policy.lockStaleMs,
|
|
529
|
+
update: input.policy.lockUpdateMs,
|
|
530
|
+
retries: lockRetries(input.retryBudgetMs),
|
|
531
|
+
onCompromised: /* @__PURE__ */ __name((error) => {
|
|
532
|
+
if (lease.released) return;
|
|
533
|
+
lease.compromised = true;
|
|
534
|
+
try {
|
|
535
|
+
input.onCompromised?.(error);
|
|
536
|
+
} catch {
|
|
537
|
+
}
|
|
538
|
+
}, "onCompromised")
|
|
539
|
+
});
|
|
540
|
+
try {
|
|
541
|
+
if (lease.compromised) {
|
|
542
|
+
throw new Error(
|
|
543
|
+
`Lease was compromised while acquiring ${input.lockPath}`
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
await input.fs.chmod(input.lockPath, DIRECTORY_MODE);
|
|
547
|
+
} catch (error) {
|
|
548
|
+
lease.released = true;
|
|
549
|
+
await release().catch(() => {
|
|
365
550
|
});
|
|
366
|
-
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
|
|
551
|
+
throw error;
|
|
552
|
+
}
|
|
553
|
+
lease.release = async () => {
|
|
554
|
+
if (lease.released) return;
|
|
555
|
+
lease.released = true;
|
|
556
|
+
await release();
|
|
557
|
+
};
|
|
558
|
+
return lease;
|
|
559
|
+
}
|
|
560
|
+
__name(acquireLease, "acquireLease");
|
|
561
|
+
async function updateLatestBestEffort(fs2, daemonDir, targetPath, mutationAllowed) {
|
|
562
|
+
const linkPath = nodePath.join(daemonDir, "latest");
|
|
563
|
+
if (!mutationAllowed()) return;
|
|
564
|
+
try {
|
|
565
|
+
await fs2.unlink(linkPath);
|
|
566
|
+
} catch {
|
|
567
|
+
}
|
|
568
|
+
if (!mutationAllowed()) return;
|
|
569
|
+
try {
|
|
570
|
+
await fs2.symlink(nodePath.relative(daemonDir, targetPath), linkPath);
|
|
571
|
+
} catch {
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
__name(updateLatestBestEffort, "updateLatestBestEffort");
|
|
575
|
+
async function readRecentFallback(fs2, runsDir) {
|
|
576
|
+
try {
|
|
577
|
+
const raw = await fs2.readFile(
|
|
578
|
+
nodePath.join(runsDir, "recent-fallback"),
|
|
579
|
+
"utf8"
|
|
370
580
|
);
|
|
371
|
-
|
|
581
|
+
const name = raw.trim();
|
|
582
|
+
return FALLBACK_DIR_RE.test(name) ? name : void 0;
|
|
583
|
+
} catch {
|
|
584
|
+
return void 0;
|
|
372
585
|
}
|
|
586
|
+
}
|
|
587
|
+
__name(readRecentFallback, "readRecentFallback");
|
|
588
|
+
async function writeRecentFallback(fs2, runsDir, name, mutationAllowed = () => true) {
|
|
589
|
+
const locatorPath = nodePath.join(runsDir, "recent-fallback");
|
|
590
|
+
if (!name) {
|
|
591
|
+
if (!mutationAllowed()) {
|
|
592
|
+
throw new Error("Fallback locator mutation is no longer allowed");
|
|
593
|
+
}
|
|
594
|
+
try {
|
|
595
|
+
await fs2.unlink(locatorPath);
|
|
596
|
+
} catch (error) {
|
|
597
|
+
if (!isErrno(error, "ENOENT")) throw error;
|
|
598
|
+
}
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
if (!FALLBACK_DIR_RE.test(name)) {
|
|
602
|
+
throw new Error(`Invalid fallback locator target: ${name}`);
|
|
603
|
+
}
|
|
604
|
+
const tempPath = nodePath.join(runsDir, ".recent-fallback.tmp");
|
|
373
605
|
try {
|
|
374
|
-
const
|
|
375
|
-
|
|
606
|
+
const tempStat = await fs2.lstat(tempPath);
|
|
607
|
+
if (!tempStat.isFile() || tempStat.isSymbolicLink()) {
|
|
608
|
+
throw new Error(`${tempPath} is not a regular file`);
|
|
609
|
+
}
|
|
610
|
+
if (!mutationAllowed()) {
|
|
611
|
+
throw new Error("Fallback locator mutation is no longer allowed");
|
|
612
|
+
}
|
|
613
|
+
await fs2.unlink(tempPath);
|
|
614
|
+
} catch (error) {
|
|
615
|
+
if (!isErrno(error, "ENOENT")) throw error;
|
|
616
|
+
}
|
|
617
|
+
if (!mutationAllowed()) {
|
|
618
|
+
throw new Error("Fallback locator mutation is no longer allowed");
|
|
619
|
+
}
|
|
620
|
+
await fs2.writeFile(tempPath, `${name}
|
|
621
|
+
`, {
|
|
622
|
+
encoding: "utf8",
|
|
623
|
+
mode: FILE_MODE,
|
|
624
|
+
flag: "wx"
|
|
625
|
+
});
|
|
626
|
+
if (!mutationAllowed()) {
|
|
627
|
+
throw new Error("Fallback locator mutation is no longer allowed");
|
|
628
|
+
}
|
|
629
|
+
await fs2.rename(tempPath, locatorPath);
|
|
630
|
+
}
|
|
631
|
+
__name(writeRecentFallback, "writeRecentFallback");
|
|
632
|
+
async function listFallbackDirectories(fs2, runsDir) {
|
|
633
|
+
const entries = await fs2.readdir(runsDir, { withFileTypes: true });
|
|
634
|
+
return entries.filter((entry) => entry.isDirectory() && FALLBACK_DIR_RE.test(entry.name)).map((entry) => entry.name).sort();
|
|
635
|
+
}
|
|
636
|
+
__name(listFallbackDirectories, "listFallbackDirectories");
|
|
637
|
+
async function fallbackActivityMtime(fs2, familyDir) {
|
|
638
|
+
try {
|
|
639
|
+
return (await fs2.lstat(nodePath.join(familyDir, "daemon.log"))).mtimeMs;
|
|
640
|
+
} catch (error) {
|
|
641
|
+
if (!isErrno(error, "ENOENT")) throw error;
|
|
642
|
+
return (await fs2.lstat(familyDir)).mtimeMs;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
__name(fallbackActivityMtime, "fallbackActivityMtime");
|
|
646
|
+
async function cleanupFallbackFamilies(input) {
|
|
647
|
+
const mutationAllowed = input.mutationAllowed ?? (() => true);
|
|
648
|
+
const locator = await readRecentFallback(input.fs, input.runsDir);
|
|
649
|
+
const names = await listFallbackDirectories(input.fs, input.runsDir);
|
|
650
|
+
const live = /* @__PURE__ */ new Set();
|
|
651
|
+
const inactive = [];
|
|
652
|
+
try {
|
|
653
|
+
for (const name of names) {
|
|
654
|
+
if (!mutationAllowed()) {
|
|
655
|
+
throw new Error("Fallback cleanup lease was compromised");
|
|
656
|
+
}
|
|
657
|
+
const familyDir = nodePath.join(input.runsDir, name);
|
|
658
|
+
let lease;
|
|
659
|
+
try {
|
|
660
|
+
lease = await acquireLease({
|
|
661
|
+
fs: input.fs,
|
|
662
|
+
acquireLock: input.acquireLock,
|
|
663
|
+
targetPath: familyDir,
|
|
664
|
+
lockPath: nodePath.join(familyDir, ".owner.lock"),
|
|
665
|
+
policy: input.policy,
|
|
666
|
+
retryBudgetMs: 0
|
|
667
|
+
});
|
|
668
|
+
if (!mutationAllowed()) {
|
|
669
|
+
throw new Error("Fallback cleanup lease was compromised");
|
|
670
|
+
}
|
|
671
|
+
if (lease.compromised) {
|
|
672
|
+
await lease.release().catch(() => {
|
|
673
|
+
});
|
|
674
|
+
throw new Error(`Fallback owner lease was compromised: ${familyDir}`);
|
|
675
|
+
}
|
|
676
|
+
inactive.push({
|
|
677
|
+
name,
|
|
678
|
+
mtimeMs: await fallbackActivityMtime(input.fs, familyDir),
|
|
679
|
+
lease
|
|
680
|
+
});
|
|
681
|
+
} catch (error) {
|
|
682
|
+
await lease?.release().catch(() => {
|
|
683
|
+
});
|
|
684
|
+
if (isErrno(error, "ELOCKED")) {
|
|
685
|
+
live.add(name);
|
|
686
|
+
continue;
|
|
687
|
+
}
|
|
688
|
+
throw error;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
const inactiveNames = new Set(inactive.map((entry) => entry.name));
|
|
692
|
+
const retainedInactive = (input.preferredInactive && inactiveNames.has(input.preferredInactive) ? input.preferredInactive : void 0) ?? (locator && inactiveNames.has(locator) ? locator : void 0) ?? inactive.slice().sort(
|
|
693
|
+
(a, b) => b.mtimeMs - a.mtimeMs || b.name.localeCompare(a.name)
|
|
694
|
+
)[0]?.name;
|
|
695
|
+
for (const entry of inactive) {
|
|
696
|
+
await entry.lease.release();
|
|
697
|
+
if (entry.name === retainedInactive) continue;
|
|
698
|
+
if (!mutationAllowed()) {
|
|
699
|
+
throw new Error("Fallback cleanup lease was compromised");
|
|
700
|
+
}
|
|
701
|
+
await input.fs.rm(nodePath.join(input.runsDir, entry.name), {
|
|
702
|
+
recursive: true,
|
|
703
|
+
force: true
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
const remaining = [...live, ...retainedInactive ? [retainedInactive] : []].filter((name, index, all) => all.indexOf(name) === index).sort();
|
|
707
|
+
const nextLocator = retainedInactive ?? (locator && remaining.includes(locator) ? locator : remaining.at(-1));
|
|
708
|
+
if (locator !== nextLocator) {
|
|
709
|
+
await writeRecentFallback(
|
|
710
|
+
input.fs,
|
|
711
|
+
input.runsDir,
|
|
712
|
+
nextLocator,
|
|
713
|
+
mutationAllowed
|
|
714
|
+
).catch(() => {
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
} finally {
|
|
718
|
+
await Promise.all(
|
|
719
|
+
inactive.filter((entry) => !entry.lease.released).map((entry) => entry.lease.release().catch(() => {
|
|
720
|
+
}))
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
__name(cleanupFallbackFamilies, "cleanupFallbackFamilies");
|
|
725
|
+
async function acquireMaintenanceLease(input) {
|
|
726
|
+
await ensureRealDirectory(input.fs, input.runsDir);
|
|
727
|
+
return acquireLease({
|
|
728
|
+
fs: input.fs,
|
|
729
|
+
acquireLock: input.acquireLock,
|
|
730
|
+
targetPath: input.runsDir,
|
|
731
|
+
lockPath: nodePath.join(input.runsDir, ".maintenance.lock"),
|
|
732
|
+
policy: input.policy,
|
|
733
|
+
retryBudgetMs: input.retryBudgetMs
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
__name(acquireMaintenanceLease, "acquireMaintenanceLease");
|
|
737
|
+
async function allocateFallbackFamily(input) {
|
|
738
|
+
const runsDir = nodePath.join(input.daemonDir, "runs");
|
|
739
|
+
const maintenance = await acquireMaintenanceLease({
|
|
740
|
+
...input,
|
|
741
|
+
runsDir,
|
|
742
|
+
retryBudgetMs: input.policy.maintenanceAcquireBudgetMs
|
|
743
|
+
});
|
|
744
|
+
let familyDir;
|
|
745
|
+
let familyCreated = false;
|
|
746
|
+
let lease;
|
|
747
|
+
const maintenanceAllowsMutation = /* @__PURE__ */ __name(() => !maintenance.compromised && !maintenance.released, "maintenanceAllowsMutation");
|
|
748
|
+
try {
|
|
749
|
+
if (!maintenanceAllowsMutation()) {
|
|
750
|
+
throw new Error("Fallback maintenance lease was compromised");
|
|
751
|
+
}
|
|
752
|
+
await cleanupFallbackFamilies({
|
|
753
|
+
...input,
|
|
754
|
+
runsDir,
|
|
755
|
+
mutationAllowed: maintenanceAllowsMutation
|
|
756
|
+
});
|
|
757
|
+
if (!maintenanceAllowsMutation()) {
|
|
758
|
+
throw new Error("Fallback maintenance lease was compromised");
|
|
759
|
+
}
|
|
760
|
+
const name = `run-${input.runId}`;
|
|
761
|
+
familyDir = nodePath.join(runsDir, name);
|
|
762
|
+
await input.fs.mkdir(familyDir, { mode: DIRECTORY_MODE });
|
|
763
|
+
familyCreated = true;
|
|
764
|
+
if (!maintenanceAllowsMutation()) {
|
|
765
|
+
throw new Error("Fallback maintenance lease was compromised");
|
|
766
|
+
}
|
|
767
|
+
lease = await acquireLease({
|
|
768
|
+
fs: input.fs,
|
|
769
|
+
acquireLock: input.acquireLock,
|
|
770
|
+
targetPath: familyDir,
|
|
771
|
+
lockPath: nodePath.join(familyDir, ".owner.lock"),
|
|
772
|
+
policy: input.policy,
|
|
773
|
+
retryBudgetMs: 0,
|
|
774
|
+
onCompromised: input.onCompromised
|
|
775
|
+
});
|
|
776
|
+
if (!maintenanceAllowsMutation()) {
|
|
777
|
+
throw new Error("Fallback maintenance lease was compromised");
|
|
778
|
+
}
|
|
779
|
+
} catch (error) {
|
|
780
|
+
await lease?.release().catch(() => {
|
|
781
|
+
});
|
|
782
|
+
if (familyCreated && familyDir && maintenanceAllowsMutation()) {
|
|
783
|
+
await input.fs.rm(familyDir, { recursive: true, force: true }).catch(() => {
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
await maintenance.release().catch(() => {
|
|
787
|
+
});
|
|
788
|
+
throw error;
|
|
789
|
+
}
|
|
790
|
+
try {
|
|
791
|
+
await maintenance.release();
|
|
792
|
+
} catch (error) {
|
|
793
|
+
await lease.release().catch(() => {
|
|
794
|
+
});
|
|
795
|
+
throw error;
|
|
796
|
+
}
|
|
797
|
+
return {
|
|
798
|
+
mode: "fallback",
|
|
799
|
+
activePath: nodePath.join(familyDir, "daemon.log"),
|
|
800
|
+
archiveDir: nodePath.join(familyDir, "archive"),
|
|
801
|
+
familyDir,
|
|
802
|
+
lease,
|
|
803
|
+
releaseLease: lease.release
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
__name(allocateFallbackFamily, "allocateFallbackFamily");
|
|
807
|
+
async function removeFailedFallbackBestEffort(input) {
|
|
808
|
+
if (input.family.lease.compromised) {
|
|
809
|
+
await input.family.releaseLease().catch(() => {
|
|
810
|
+
});
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
const runsDir = nodePath.dirname(input.family.familyDir);
|
|
814
|
+
let maintenance;
|
|
815
|
+
try {
|
|
816
|
+
maintenance = await acquireMaintenanceLease({
|
|
817
|
+
...input,
|
|
818
|
+
runsDir,
|
|
819
|
+
retryBudgetMs: 0
|
|
820
|
+
});
|
|
376
821
|
} catch {
|
|
822
|
+
await input.family.releaseLease().catch(() => {
|
|
823
|
+
});
|
|
824
|
+
return;
|
|
377
825
|
}
|
|
826
|
+
try {
|
|
827
|
+
if (maintenance.compromised) {
|
|
828
|
+
await input.family.releaseLease().catch(() => {
|
|
829
|
+
});
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
try {
|
|
833
|
+
await input.family.releaseLease();
|
|
834
|
+
} catch {
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
if (maintenance.compromised || input.family.lease.compromised) return;
|
|
838
|
+
await input.fs.rm(input.family.familyDir, { recursive: true, force: true }).catch(() => {
|
|
839
|
+
});
|
|
840
|
+
} finally {
|
|
841
|
+
await maintenance.release().catch(() => {
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
__name(removeFailedFallbackBestEffort, "removeFailedFallbackBestEffort");
|
|
846
|
+
async function closeFallbackFamily(input) {
|
|
847
|
+
if (input.family.lease.compromised) {
|
|
848
|
+
await input.family.releaseLease().catch(() => {
|
|
849
|
+
});
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
const runsDir = nodePath.dirname(input.family.familyDir);
|
|
853
|
+
let maintenance;
|
|
854
|
+
try {
|
|
855
|
+
maintenance = await acquireMaintenanceLease({
|
|
856
|
+
...input,
|
|
857
|
+
runsDir,
|
|
858
|
+
retryBudgetMs: 0
|
|
859
|
+
});
|
|
860
|
+
} catch {
|
|
861
|
+
await input.family.releaseLease().catch(input.onRetentionError);
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
864
|
+
try {
|
|
865
|
+
if (maintenance.compromised) {
|
|
866
|
+
throw new Error("Fallback maintenance lease was compromised");
|
|
867
|
+
}
|
|
868
|
+
await input.family.releaseLease();
|
|
869
|
+
const name = nodePath.basename(input.family.familyDir);
|
|
870
|
+
const mutationAllowed = /* @__PURE__ */ __name(() => !maintenance.compromised && !input.family.lease.compromised, "mutationAllowed");
|
|
871
|
+
await cleanupFallbackFamilies({
|
|
872
|
+
...input,
|
|
873
|
+
runsDir,
|
|
874
|
+
preferredInactive: name,
|
|
875
|
+
mutationAllowed
|
|
876
|
+
});
|
|
877
|
+
await writeRecentFallback(input.fs, runsDir, name, mutationAllowed);
|
|
878
|
+
} catch (error) {
|
|
879
|
+
await input.family.releaseLease().catch(input.onRetentionError);
|
|
880
|
+
input.onRetentionError(error);
|
|
881
|
+
} finally {
|
|
882
|
+
await maintenance.release().catch(input.onRetentionError);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
__name(closeFallbackFamily, "closeFallbackFamily");
|
|
886
|
+
async function cleanupFallbacksBestEffort(input) {
|
|
887
|
+
const runsDir = nodePath.join(input.daemonDir, "runs");
|
|
888
|
+
try {
|
|
889
|
+
const stat = await input.fs.lstat(runsDir);
|
|
890
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
891
|
+
throw new Error(`${runsDir} is not a real directory`);
|
|
892
|
+
}
|
|
893
|
+
} catch (error) {
|
|
894
|
+
if (isErrno(error, "ENOENT")) return;
|
|
895
|
+
input.onRetentionError(error);
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
let maintenance;
|
|
899
|
+
try {
|
|
900
|
+
const currentMaintenance = await acquireMaintenanceLease({
|
|
901
|
+
...input,
|
|
902
|
+
runsDir,
|
|
903
|
+
retryBudgetMs: 0
|
|
904
|
+
});
|
|
905
|
+
maintenance = currentMaintenance;
|
|
906
|
+
const mutationAllowed = /* @__PURE__ */ __name(() => !currentMaintenance.compromised && !currentMaintenance.released && (input.mutationAllowed?.() ?? true), "mutationAllowed");
|
|
907
|
+
if (!mutationAllowed()) {
|
|
908
|
+
throw new Error("Fallback maintenance lease was compromised");
|
|
909
|
+
}
|
|
910
|
+
await cleanupFallbackFamilies({
|
|
911
|
+
...input,
|
|
912
|
+
runsDir,
|
|
913
|
+
mutationAllowed
|
|
914
|
+
});
|
|
915
|
+
} catch (error) {
|
|
916
|
+
if (!isErrno(error, "ELOCKED")) input.onRetentionError(error);
|
|
917
|
+
} finally {
|
|
918
|
+
await maintenance?.release().catch(input.onRetentionError);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
__name(cleanupFallbacksBestEffort, "cleanupFallbacksBestEffort");
|
|
922
|
+
function createConcreteLogger(input) {
|
|
378
923
|
let pending = Promise.resolve();
|
|
379
|
-
let
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
924
|
+
let pendingBytes = 0;
|
|
925
|
+
let droppedRecords = 0;
|
|
926
|
+
let droppedBytes = 0;
|
|
927
|
+
let reportedDroppedRecords = 0;
|
|
928
|
+
let reportedDroppedBytes = 0;
|
|
929
|
+
let overflowEpisode = false;
|
|
930
|
+
let dropSummaryPending = false;
|
|
931
|
+
let acceptingFileRecords = true;
|
|
932
|
+
let closePromise;
|
|
933
|
+
const markDropped = /* @__PURE__ */ __name((bytes, queueOverflow = false) => {
|
|
934
|
+
droppedRecords += 1;
|
|
935
|
+
droppedBytes += bytes;
|
|
936
|
+
if (queueOverflow) {
|
|
937
|
+
input.issues.add("queue_overflow");
|
|
938
|
+
if (!overflowEpisode) {
|
|
939
|
+
overflowEpisode = true;
|
|
940
|
+
input.stderr(
|
|
941
|
+
"qwen serve: daemon log queue limit reached; dropping file copies until capacity recovers"
|
|
942
|
+
);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
}, "markDropped");
|
|
946
|
+
const markRotationFailure = /* @__PURE__ */ __name((message, error) => {
|
|
947
|
+
input.issues.add("rotation_failed");
|
|
948
|
+
input.state.nextRotationRetryAt = input.monotonicNow() + input.policy.rotationRetryIntervalMs;
|
|
949
|
+
input.warnOnce(
|
|
950
|
+
`rotation:${message}`,
|
|
951
|
+
`qwen serve: daemon log rotation failed; ${message}${error ? `: ${error instanceof Error ? error.message : String(error)}` : ""}`
|
|
952
|
+
);
|
|
953
|
+
}, "markRotationFailure");
|
|
954
|
+
const markRetentionFailure = /* @__PURE__ */ __name((error) => {
|
|
955
|
+
input.issues.add("retention_failed");
|
|
956
|
+
input.warnOnce(
|
|
957
|
+
"retention",
|
|
958
|
+
`qwen serve: daemon log retention cleanup failed: ${error instanceof Error ? error.message : String(error)}`
|
|
959
|
+
);
|
|
960
|
+
}, "markRetentionFailure");
|
|
961
|
+
const fileMutationAllowed = /* @__PURE__ */ __name(() => !input.state.poisoned && !input.family.lease.compromised && !input.family.lease.released, "fileMutationAllowed");
|
|
962
|
+
const prepareArchives = /* @__PURE__ */ __name(async () => {
|
|
963
|
+
if (!input.state.archiveAvailable && input.monotonicNow() < input.state.nextRotationRetryAt) {
|
|
964
|
+
return false;
|
|
965
|
+
}
|
|
966
|
+
try {
|
|
967
|
+
await ensureRealDirectory(
|
|
968
|
+
input.fs,
|
|
969
|
+
input.family.archiveDir,
|
|
970
|
+
fileMutationAllowed
|
|
971
|
+
);
|
|
972
|
+
if (!fileMutationAllowed()) return false;
|
|
973
|
+
input.state.archives = await scanArchives(
|
|
974
|
+
input.fs,
|
|
975
|
+
input.family.archiveDir
|
|
976
|
+
);
|
|
977
|
+
input.state.nextArchiveGeneration = (input.state.archives.at(-1)?.generation ?? 0) + 1;
|
|
978
|
+
input.state.archiveAvailable = true;
|
|
979
|
+
input.state.nextRotationRetryAt = 0;
|
|
980
|
+
return true;
|
|
981
|
+
} catch (error) {
|
|
982
|
+
if (!fileMutationAllowed()) return false;
|
|
983
|
+
input.state.archiveAvailable = false;
|
|
984
|
+
markRotationFailure("continuing without file rotation", error);
|
|
985
|
+
return false;
|
|
986
|
+
}
|
|
987
|
+
}, "prepareArchives");
|
|
988
|
+
const pruneForRotation = /* @__PURE__ */ __name(async () => {
|
|
989
|
+
while (input.state.archives.length >= input.policy.maxArchives) {
|
|
990
|
+
if (!fileMutationAllowed()) return false;
|
|
991
|
+
const oldest = input.state.archives[0];
|
|
992
|
+
try {
|
|
993
|
+
await input.fs.unlink(
|
|
994
|
+
nodePath.join(input.family.archiveDir, oldest.name)
|
|
995
|
+
);
|
|
996
|
+
input.state.archives.shift();
|
|
997
|
+
} catch (error) {
|
|
998
|
+
if (isErrno(error, "ENOENT")) {
|
|
999
|
+
input.state.archives.shift();
|
|
1000
|
+
continue;
|
|
388
1001
|
}
|
|
389
|
-
|
|
1002
|
+
markRetentionFailure(error);
|
|
1003
|
+
input.state.nextRotationRetryAt = input.monotonicNow() + input.policy.rotationRetryIntervalMs;
|
|
1004
|
+
return false;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
return true;
|
|
1008
|
+
}, "pruneForRotation");
|
|
1009
|
+
const archivePath = /* @__PURE__ */ __name(async () => {
|
|
1010
|
+
const generation = input.state.nextArchiveGeneration;
|
|
1011
|
+
if (generation > 999999999999) {
|
|
1012
|
+
markRotationFailure("archive generation limit reached");
|
|
1013
|
+
return void 0;
|
|
1014
|
+
}
|
|
1015
|
+
for (let attempt = 0; attempt < ARCHIVE_NAME_ATTEMPTS; attempt += 1) {
|
|
1016
|
+
let name;
|
|
1017
|
+
try {
|
|
1018
|
+
name = `daemon-${String(generation).padStart(12, "0")}-${archiveTimestamp(input.now())}-${crypto.randomBytes(4).toString("hex")}.log`;
|
|
1019
|
+
} catch (error) {
|
|
1020
|
+
markRotationFailure("archive filename generation failed", error);
|
|
1021
|
+
return void 0;
|
|
1022
|
+
}
|
|
1023
|
+
const candidate = nodePath.join(input.family.archiveDir, name);
|
|
1024
|
+
try {
|
|
1025
|
+
await input.fs.lstat(candidate);
|
|
1026
|
+
} catch (error) {
|
|
1027
|
+
if (isErrno(error, "ENOENT")) return { name, generation };
|
|
1028
|
+
markRotationFailure("archive target validation failed", error);
|
|
1029
|
+
return void 0;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
markRotationFailure("archive filename collision limit reached");
|
|
1033
|
+
return void 0;
|
|
1034
|
+
}, "archivePath");
|
|
1035
|
+
const appendActive = /* @__PURE__ */ __name(async (record, forceRotation = false) => {
|
|
1036
|
+
if (!fileMutationAllowed()) return "dropped";
|
|
1037
|
+
const bytes = Buffer.byteLength(record, "utf8");
|
|
1038
|
+
const needsRotation = input.state.currentBytes > 0 && (forceRotation || input.state.currentBytes + bytes > input.policy.maxBytes);
|
|
1039
|
+
if (needsRotation) {
|
|
1040
|
+
if (input.monotonicNow() < input.state.nextRotationRetryAt) {
|
|
1041
|
+
return "dropped";
|
|
1042
|
+
}
|
|
1043
|
+
if (!await prepareArchives()) return "dropped";
|
|
1044
|
+
if (!fileMutationAllowed()) return "dropped";
|
|
1045
|
+
if (!await pruneForRotation()) return "dropped";
|
|
1046
|
+
const archive = await archivePath();
|
|
1047
|
+
if (!archive) return "dropped";
|
|
1048
|
+
if (!fileMutationAllowed()) return "dropped";
|
|
1049
|
+
try {
|
|
1050
|
+
await input.fs.rename(
|
|
1051
|
+
input.family.activePath,
|
|
1052
|
+
nodePath.join(input.family.archiveDir, archive.name)
|
|
1053
|
+
);
|
|
1054
|
+
} catch (error) {
|
|
1055
|
+
markRotationFailure("active file rename failed", error);
|
|
1056
|
+
return "dropped";
|
|
1057
|
+
}
|
|
1058
|
+
input.state.archives.push(archive);
|
|
1059
|
+
input.state.archives.sort(
|
|
1060
|
+
(a, b) => a.generation - b.generation || a.name.localeCompare(b.name)
|
|
1061
|
+
);
|
|
1062
|
+
input.state.nextArchiveGeneration = archive.generation + 1;
|
|
1063
|
+
input.state.currentBytes = 0;
|
|
1064
|
+
if (!fileMutationAllowed()) return "dropped";
|
|
1065
|
+
}
|
|
1066
|
+
if (!fileMutationAllowed()) return "dropped";
|
|
1067
|
+
try {
|
|
1068
|
+
if (input.state.exclusiveBootCreate) {
|
|
1069
|
+
await input.fs.writeFile(input.family.activePath, record, {
|
|
1070
|
+
encoding: "utf8",
|
|
1071
|
+
mode: FILE_MODE,
|
|
1072
|
+
flag: "wx"
|
|
1073
|
+
});
|
|
1074
|
+
input.state.exclusiveBootCreate = false;
|
|
1075
|
+
} else {
|
|
1076
|
+
await input.fs.appendFile(input.family.activePath, record, {
|
|
1077
|
+
encoding: "utf8",
|
|
1078
|
+
mode: FILE_MODE,
|
|
1079
|
+
flag: "a"
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
1082
|
+
input.state.currentBytes += bytes;
|
|
1083
|
+
return "written";
|
|
1084
|
+
} catch (error) {
|
|
1085
|
+
input.state.poisoned = true;
|
|
1086
|
+
input.issues.add("write_failed");
|
|
1087
|
+
input.warnOnce(
|
|
1088
|
+
"write-failed",
|
|
1089
|
+
`qwen serve: daemon log write failed; file logging disabled for this run: ${error instanceof Error ? error.message : String(error)}`
|
|
1090
|
+
);
|
|
1091
|
+
return "unknown";
|
|
1092
|
+
}
|
|
1093
|
+
}, "appendActive");
|
|
1094
|
+
const unreportedDropRecord = /* @__PURE__ */ __name(() => {
|
|
1095
|
+
const records = droppedRecords - reportedDroppedRecords;
|
|
1096
|
+
const bytes = droppedBytes - reportedDroppedBytes;
|
|
1097
|
+
if (records <= 0) return void 0;
|
|
1098
|
+
return capUtf8Record(
|
|
1099
|
+
buildDaemonFileLogLine(
|
|
1100
|
+
{
|
|
1101
|
+
level: "WARN",
|
|
1102
|
+
message: "daemon file log records dropped",
|
|
1103
|
+
now: input.now(),
|
|
1104
|
+
ctx: { droppedRecords: records, droppedBytes: bytes }
|
|
1105
|
+
},
|
|
1106
|
+
input.runId,
|
|
1107
|
+
input.pid
|
|
1108
|
+
),
|
|
1109
|
+
input.policy.maxRecordBytes
|
|
390
1110
|
);
|
|
391
|
-
}, "
|
|
392
|
-
const
|
|
393
|
-
const
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
1111
|
+
}, "unreportedDropRecord");
|
|
1112
|
+
const enqueueRecord = /* @__PURE__ */ __name((record, callerOriginated, onSettled) => {
|
|
1113
|
+
const bytes = Buffer.byteLength(record, "utf8");
|
|
1114
|
+
if (pendingBytes + bytes > input.policy.maxPendingBytes) {
|
|
1115
|
+
if (callerOriginated) markDropped(bytes, true);
|
|
1116
|
+
return false;
|
|
1117
|
+
}
|
|
1118
|
+
pendingBytes += bytes;
|
|
1119
|
+
pending = pending.then(async () => {
|
|
1120
|
+
let outcome = "unknown";
|
|
1121
|
+
try {
|
|
1122
|
+
outcome = await appendActive(record);
|
|
1123
|
+
if (callerOriginated && outcome === "dropped") markDropped(bytes);
|
|
1124
|
+
} catch (error) {
|
|
1125
|
+
input.state.poisoned = true;
|
|
1126
|
+
input.issues.add("write_failed");
|
|
1127
|
+
input.warnOnce(
|
|
1128
|
+
"queue-failed",
|
|
1129
|
+
`qwen serve: daemon log queue failed; file logging disabled for this run: ${error instanceof Error ? error.message : String(error)}`
|
|
1130
|
+
);
|
|
1131
|
+
} finally {
|
|
1132
|
+
onSettled?.(outcome);
|
|
1133
|
+
}
|
|
1134
|
+
}).catch(() => {
|
|
1135
|
+
}).finally(() => {
|
|
1136
|
+
pendingBytes -= bytes;
|
|
1137
|
+
});
|
|
1138
|
+
return true;
|
|
1139
|
+
}, "enqueueRecord");
|
|
1140
|
+
const enqueueDropSummary = /* @__PURE__ */ __name(() => {
|
|
1141
|
+
if (dropSummaryPending) return;
|
|
1142
|
+
const summary = unreportedDropRecord();
|
|
1143
|
+
if (!summary) return;
|
|
1144
|
+
const summaryRecords = droppedRecords;
|
|
1145
|
+
const summaryBytes = droppedBytes;
|
|
1146
|
+
if (enqueueRecord(summary, false, (outcome) => {
|
|
1147
|
+
if (outcome === "written") {
|
|
1148
|
+
reportedDroppedRecords = summaryRecords;
|
|
1149
|
+
reportedDroppedBytes = summaryBytes;
|
|
1150
|
+
}
|
|
1151
|
+
dropSummaryPending = false;
|
|
1152
|
+
})) {
|
|
1153
|
+
dropSummaryPending = true;
|
|
1154
|
+
overflowEpisode = false;
|
|
1155
|
+
}
|
|
1156
|
+
}, "enqueueDropSummary");
|
|
1157
|
+
const submitFileRecord = /* @__PURE__ */ __name((record) => {
|
|
1158
|
+
if (!acceptingFileRecords) return;
|
|
1159
|
+
const bytes = Buffer.byteLength(record, "utf8");
|
|
1160
|
+
if (!fileMutationAllowed()) {
|
|
1161
|
+
markDropped(bytes);
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
enqueueDropSummary();
|
|
1165
|
+
enqueueRecord(record, true);
|
|
1166
|
+
}, "submitFileRecord");
|
|
1167
|
+
const tee = /* @__PURE__ */ __name((level, message, ctx, err) => {
|
|
1168
|
+
const timestamp = input.now();
|
|
1169
|
+
input.stderr(
|
|
1170
|
+
buildDaemonLogLine({
|
|
1171
|
+
level,
|
|
1172
|
+
message,
|
|
1173
|
+
now: timestamp,
|
|
1174
|
+
ctx,
|
|
1175
|
+
err
|
|
1176
|
+
}).trimEnd()
|
|
1177
|
+
);
|
|
1178
|
+
submitFileRecord(
|
|
1179
|
+
capUtf8Record(
|
|
1180
|
+
buildDaemonFileLogLine(
|
|
1181
|
+
{ level, message, now: timestamp, ctx, err },
|
|
1182
|
+
input.runId,
|
|
1183
|
+
input.pid
|
|
1184
|
+
),
|
|
1185
|
+
input.policy.maxRecordBytes
|
|
1186
|
+
)
|
|
1187
|
+
);
|
|
1188
|
+
}, "tee");
|
|
1189
|
+
const finalize = /* @__PURE__ */ __name(async () => {
|
|
1190
|
+
await pending;
|
|
1191
|
+
const summary = unreportedDropRecord();
|
|
1192
|
+
if (summary && !input.state.poisoned && !input.family.lease.compromised) {
|
|
1193
|
+
if (await appendActive(summary) === "written") {
|
|
1194
|
+
reportedDroppedRecords = droppedRecords;
|
|
1195
|
+
reportedDroppedBytes = droppedBytes;
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
if (input.family.mode === "fallback") {
|
|
1199
|
+
await closeFallbackFamily({
|
|
1200
|
+
...input,
|
|
1201
|
+
onRetentionError: markRetentionFailure
|
|
1202
|
+
});
|
|
1203
|
+
} else {
|
|
1204
|
+
await input.family.releaseLease().catch((error) => {
|
|
1205
|
+
input.warnOnce(
|
|
1206
|
+
"release-failed",
|
|
1207
|
+
`qwen serve: daemon log lease release failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1208
|
+
);
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
}, "finalize");
|
|
1212
|
+
const logger = {
|
|
1213
|
+
info: /* @__PURE__ */ __name((message, ctx) => tee("INFO", message, ctx), "info"),
|
|
1214
|
+
warn: /* @__PURE__ */ __name((message, ctx) => tee("WARN", message, ctx), "warn"),
|
|
1215
|
+
error: /* @__PURE__ */ __name((message, err, ctx) => tee("ERROR", message, ctx, err ?? void 0), "error"),
|
|
401
1216
|
raw: /* @__PURE__ */ __name((line, level = "info") => {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
1217
|
+
submitFileRecord(
|
|
1218
|
+
capUtf8Record(
|
|
1219
|
+
buildDaemonFileLogLine(
|
|
1220
|
+
{
|
|
1221
|
+
level: level.toUpperCase(),
|
|
1222
|
+
message: line,
|
|
1223
|
+
now: input.now()
|
|
1224
|
+
},
|
|
1225
|
+
input.runId,
|
|
1226
|
+
input.pid
|
|
1227
|
+
),
|
|
1228
|
+
input.policy.maxRecordBytes
|
|
1229
|
+
)
|
|
1230
|
+
);
|
|
406
1231
|
}, "raw"),
|
|
407
|
-
getLogPath: /* @__PURE__ */ __name(() =>
|
|
408
|
-
getDaemonId: /* @__PURE__ */ __name(() => daemonId, "getDaemonId"),
|
|
409
|
-
|
|
1232
|
+
getLogPath: /* @__PURE__ */ __name(() => input.family.activePath, "getLogPath"),
|
|
1233
|
+
getDaemonId: /* @__PURE__ */ __name(() => input.daemonId, "getDaemonId"),
|
|
1234
|
+
getStatus: /* @__PURE__ */ __name(() => statusSnapshot(
|
|
1235
|
+
input.runId,
|
|
1236
|
+
input.family.mode,
|
|
1237
|
+
input.issues,
|
|
1238
|
+
droppedRecords,
|
|
1239
|
+
droppedBytes
|
|
1240
|
+
), "getStatus"),
|
|
1241
|
+
flush: /* @__PURE__ */ __name(() => pending, "flush"),
|
|
1242
|
+
close: /* @__PURE__ */ __name(() => {
|
|
1243
|
+
if (closePromise) return closePromise;
|
|
1244
|
+
acceptingFileRecords = false;
|
|
1245
|
+
const finalizer = finalize().catch((error) => {
|
|
1246
|
+
try {
|
|
1247
|
+
input.warnOnce(
|
|
1248
|
+
"close-failed",
|
|
1249
|
+
`qwen serve: daemon log close failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1250
|
+
);
|
|
1251
|
+
} catch {
|
|
1252
|
+
}
|
|
1253
|
+
});
|
|
1254
|
+
let timeout;
|
|
1255
|
+
const deadline = new Promise((resolve) => {
|
|
1256
|
+
timeout = setTimeout(() => {
|
|
1257
|
+
try {
|
|
1258
|
+
input.warnOnce(
|
|
1259
|
+
"close-timeout",
|
|
1260
|
+
`qwen serve: daemon log close drain exceeded ${input.policy.closeDrainBudgetMs}ms; ownership will release after pending I/O settles or process exit`
|
|
1261
|
+
);
|
|
1262
|
+
} catch {
|
|
1263
|
+
} finally {
|
|
1264
|
+
resolve();
|
|
1265
|
+
}
|
|
1266
|
+
}, input.policy.closeDrainBudgetMs);
|
|
1267
|
+
timeout.unref();
|
|
1268
|
+
});
|
|
1269
|
+
closePromise = Promise.race([finalizer, deadline]).then(() => {
|
|
1270
|
+
if (timeout) clearTimeout(timeout);
|
|
1271
|
+
});
|
|
1272
|
+
return closePromise;
|
|
1273
|
+
}, "close")
|
|
410
1274
|
};
|
|
1275
|
+
return { logger, writeInitialRecord: appendActive };
|
|
1276
|
+
}
|
|
1277
|
+
__name(createConcreteLogger, "createConcreteLogger");
|
|
1278
|
+
async function initDaemonLogger(opts) {
|
|
1279
|
+
const pid = opts.pid ?? process.pid;
|
|
1280
|
+
const now = opts.now ?? (() => /* @__PURE__ */ new Date());
|
|
1281
|
+
const monotonicNow = opts.monotonicNow ?? (() => performance.now());
|
|
1282
|
+
const stderr = opts.stderr ?? writeStderrLine;
|
|
1283
|
+
const baseDir = opts.baseDir ?? resolveDaemonLogBaseDir();
|
|
1284
|
+
const runId = opts.runId ?? crypto.randomBytes(16).toString("hex");
|
|
1285
|
+
const policy = resolvePolicy(opts.policy);
|
|
1286
|
+
const fs2 = opts.fs ?? nodeFs.promises;
|
|
1287
|
+
const acquireLock = opts.acquireLock ?? import_proper_lockfile.default.lock;
|
|
1288
|
+
const issues = /* @__PURE__ */ new Set();
|
|
1289
|
+
const warned = /* @__PURE__ */ new Set();
|
|
1290
|
+
const warnOnce = /* @__PURE__ */ __name((key, message) => {
|
|
1291
|
+
if (warned.has(key)) return;
|
|
1292
|
+
warned.add(key);
|
|
1293
|
+
try {
|
|
1294
|
+
stderr(message);
|
|
1295
|
+
} catch {
|
|
1296
|
+
}
|
|
1297
|
+
}, "warnOnce");
|
|
1298
|
+
if (isOptedOut()) {
|
|
1299
|
+
return createStderrOnlyLogger({
|
|
1300
|
+
runId,
|
|
1301
|
+
daemonId: computeDaemonId(pid),
|
|
1302
|
+
now,
|
|
1303
|
+
stderr,
|
|
1304
|
+
issues
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
const daemonDir = nodePath.join(baseDir, "daemon");
|
|
1308
|
+
try {
|
|
1309
|
+
await ensureRealDirectory(fs2, daemonDir);
|
|
1310
|
+
} catch (error) {
|
|
1311
|
+
issues.add("init_failed");
|
|
1312
|
+
warnOnce(
|
|
1313
|
+
"init",
|
|
1314
|
+
`qwen serve: daemon log disabled \u2014 init failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1315
|
+
);
|
|
1316
|
+
return createStderrOnlyLogger({
|
|
1317
|
+
runId,
|
|
1318
|
+
daemonId: computeDaemonId(pid),
|
|
1319
|
+
now,
|
|
1320
|
+
stderr,
|
|
1321
|
+
issues
|
|
1322
|
+
});
|
|
1323
|
+
}
|
|
1324
|
+
let currentState;
|
|
1325
|
+
const onCompromised = /* @__PURE__ */ __name((error) => {
|
|
1326
|
+
issues.add("lease_compromised");
|
|
1327
|
+
if (currentState) currentState.poisoned = true;
|
|
1328
|
+
warnOnce(
|
|
1329
|
+
"lease-compromised",
|
|
1330
|
+
`qwen serve: daemon log lease compromised; file logging disabled for this run: ${error.message}`
|
|
1331
|
+
);
|
|
1332
|
+
}, "onCompromised");
|
|
1333
|
+
const tryFamily = /* @__PURE__ */ __name(async (family) => {
|
|
1334
|
+
let state;
|
|
1335
|
+
try {
|
|
1336
|
+
const currentBytes = await activeFileSize(fs2, family.activePath);
|
|
1337
|
+
if (family.mode === "fallback" && currentBytes !== 0) {
|
|
1338
|
+
throw new Error(
|
|
1339
|
+
"New fallback family unexpectedly contains an active log"
|
|
1340
|
+
);
|
|
1341
|
+
}
|
|
1342
|
+
const completeTail = await lastByteIsNewline(
|
|
1343
|
+
fs2,
|
|
1344
|
+
family.activePath,
|
|
1345
|
+
currentBytes
|
|
1346
|
+
);
|
|
1347
|
+
let archiveAvailable = true;
|
|
1348
|
+
let archives = [];
|
|
1349
|
+
const familyMutationAllowed = /* @__PURE__ */ __name(() => !family.lease.compromised && !family.lease.released, "familyMutationAllowed");
|
|
1350
|
+
try {
|
|
1351
|
+
await ensureRealDirectory(fs2, family.archiveDir, familyMutationAllowed);
|
|
1352
|
+
if (!familyMutationAllowed()) {
|
|
1353
|
+
throw new Error("Daemon log family lease was compromised");
|
|
1354
|
+
}
|
|
1355
|
+
archives = await scanArchives(fs2, family.archiveDir);
|
|
1356
|
+
} catch (error) {
|
|
1357
|
+
archiveAvailable = false;
|
|
1358
|
+
if (familyMutationAllowed()) {
|
|
1359
|
+
issues.add("rotation_failed");
|
|
1360
|
+
warnOnce(
|
|
1361
|
+
`archive-init:${family.mode}`,
|
|
1362
|
+
`qwen serve: daemon log archive unavailable; active file will remain bounded: ${error instanceof Error ? error.message : String(error)}`
|
|
1363
|
+
);
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
state = {
|
|
1367
|
+
currentBytes,
|
|
1368
|
+
archives,
|
|
1369
|
+
nextArchiveGeneration: (archives.at(-1)?.generation ?? 0) + 1,
|
|
1370
|
+
archiveAvailable,
|
|
1371
|
+
exclusiveBootCreate: family.mode === "fallback",
|
|
1372
|
+
poisoned: false,
|
|
1373
|
+
nextRotationRetryAt: archiveAvailable ? 0 : monotonicNow() + policy.rotationRetryIntervalMs
|
|
1374
|
+
};
|
|
1375
|
+
currentState = state;
|
|
1376
|
+
const concrete = createConcreteLogger({
|
|
1377
|
+
fs: fs2,
|
|
1378
|
+
acquireLock,
|
|
1379
|
+
policy,
|
|
1380
|
+
family,
|
|
1381
|
+
state,
|
|
1382
|
+
runId,
|
|
1383
|
+
pid,
|
|
1384
|
+
daemonId: computeDaemonId(pid),
|
|
1385
|
+
now,
|
|
1386
|
+
monotonicNow,
|
|
1387
|
+
stderr,
|
|
1388
|
+
issues,
|
|
1389
|
+
warnOnce
|
|
1390
|
+
});
|
|
1391
|
+
const bootCtx = {
|
|
1392
|
+
workspace: opts.boundWorkspace,
|
|
1393
|
+
workspaceHash: computeWorkspaceHash(opts.boundWorkspace)
|
|
1394
|
+
};
|
|
1395
|
+
const bootTime = now();
|
|
1396
|
+
const plainBoot = capUtf8Record(
|
|
1397
|
+
buildDaemonFileLogLine(
|
|
1398
|
+
{
|
|
1399
|
+
level: "INFO",
|
|
1400
|
+
message: "daemon started",
|
|
1401
|
+
now: bootTime,
|
|
1402
|
+
ctx: bootCtx
|
|
1403
|
+
},
|
|
1404
|
+
runId,
|
|
1405
|
+
pid
|
|
1406
|
+
),
|
|
1407
|
+
policy.maxRecordBytes
|
|
1408
|
+
);
|
|
1409
|
+
const incompleteTailBoot = !completeTail ? `
|
|
1410
|
+
${capUtf8Record(
|
|
1411
|
+
buildDaemonFileLogLine(
|
|
1412
|
+
{
|
|
1413
|
+
level: "INFO",
|
|
1414
|
+
message: "daemon started",
|
|
1415
|
+
now: bootTime,
|
|
1416
|
+
ctx: { ...bootCtx, previousTailIncomplete: true }
|
|
1417
|
+
},
|
|
1418
|
+
runId,
|
|
1419
|
+
pid
|
|
1420
|
+
),
|
|
1421
|
+
policy.maxRecordBytes - 1
|
|
1422
|
+
)}` : plainBoot;
|
|
1423
|
+
const wouldRotate = currentBytes > 0 && currentBytes + Buffer.byteLength(incompleteTailBoot, "utf8") > policy.maxBytes;
|
|
1424
|
+
const bootRecord = !completeTail && !wouldRotate ? incompleteTailBoot : plainBoot;
|
|
1425
|
+
const bootOutcome = await concrete.writeInitialRecord(
|
|
1426
|
+
bootRecord,
|
|
1427
|
+
wouldRotate
|
|
1428
|
+
);
|
|
1429
|
+
if (bootOutcome !== "written" || state.poisoned || family.lease.compromised) {
|
|
1430
|
+
return void 0;
|
|
1431
|
+
}
|
|
1432
|
+
if (state.archiveAvailable && state.archives.length > policy.maxArchives) {
|
|
1433
|
+
try {
|
|
1434
|
+
while (state.archives.length > policy.maxArchives) {
|
|
1435
|
+
if (family.lease.compromised || family.lease.released) break;
|
|
1436
|
+
const oldest = state.archives[0];
|
|
1437
|
+
if (!oldest) break;
|
|
1438
|
+
try {
|
|
1439
|
+
await fs2.unlink(nodePath.join(family.archiveDir, oldest.name));
|
|
1440
|
+
} catch (error) {
|
|
1441
|
+
if (!isErrno(error, "ENOENT")) throw error;
|
|
1442
|
+
}
|
|
1443
|
+
state.archives.shift();
|
|
1444
|
+
}
|
|
1445
|
+
} catch (error) {
|
|
1446
|
+
issues.add("retention_failed");
|
|
1447
|
+
state.nextRotationRetryAt = monotonicNow() + policy.rotationRetryIntervalMs;
|
|
1448
|
+
warnOnce(
|
|
1449
|
+
"startup-retention",
|
|
1450
|
+
`qwen serve: daemon log retention cleanup failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1451
|
+
);
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
return concrete.logger;
|
|
1455
|
+
} catch (error) {
|
|
1456
|
+
warnOnce(
|
|
1457
|
+
`family-init:${family.mode}`,
|
|
1458
|
+
`qwen serve: daemon ${family.mode} log initialization failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1459
|
+
);
|
|
1460
|
+
return void 0;
|
|
1461
|
+
}
|
|
1462
|
+
}, "tryFamily");
|
|
1463
|
+
try {
|
|
1464
|
+
const stableLease = await acquireLease({
|
|
1465
|
+
fs: fs2,
|
|
1466
|
+
acquireLock,
|
|
1467
|
+
targetPath: daemonDir,
|
|
1468
|
+
lockPath: nodePath.join(daemonDir, ".stable-writer.lock"),
|
|
1469
|
+
policy,
|
|
1470
|
+
retryBudgetMs: policy.stableAcquireBudgetMs,
|
|
1471
|
+
onCompromised
|
|
1472
|
+
});
|
|
1473
|
+
const stableFamily = {
|
|
1474
|
+
mode: "stable",
|
|
1475
|
+
activePath: nodePath.join(daemonDir, "daemon.log"),
|
|
1476
|
+
archiveDir: nodePath.join(daemonDir, "archive"),
|
|
1477
|
+
familyDir: daemonDir,
|
|
1478
|
+
lease: stableLease,
|
|
1479
|
+
releaseLease: stableLease.release
|
|
1480
|
+
};
|
|
1481
|
+
const stableLogger = await tryFamily(stableFamily);
|
|
1482
|
+
if (stableLogger) {
|
|
1483
|
+
if (!stableLease.compromised && !stableLease.released) {
|
|
1484
|
+
await updateLatestBestEffort(
|
|
1485
|
+
fs2,
|
|
1486
|
+
daemonDir,
|
|
1487
|
+
stableFamily.activePath,
|
|
1488
|
+
() => !stableLease.compromised && !stableLease.released
|
|
1489
|
+
);
|
|
1490
|
+
}
|
|
1491
|
+
if (!stableLease.compromised && !stableLease.released) {
|
|
1492
|
+
await cleanupFallbacksBestEffort({
|
|
1493
|
+
fs: fs2,
|
|
1494
|
+
acquireLock,
|
|
1495
|
+
policy,
|
|
1496
|
+
daemonDir,
|
|
1497
|
+
mutationAllowed: /* @__PURE__ */ __name(() => !stableLease.compromised && !stableLease.released, "mutationAllowed"),
|
|
1498
|
+
onRetentionError: /* @__PURE__ */ __name((error) => {
|
|
1499
|
+
issues.add("retention_failed");
|
|
1500
|
+
warnOnce(
|
|
1501
|
+
"fallback-retention",
|
|
1502
|
+
`qwen serve: daemon fallback log cleanup failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1503
|
+
);
|
|
1504
|
+
}, "onRetentionError")
|
|
1505
|
+
});
|
|
1506
|
+
}
|
|
1507
|
+
return stableLogger;
|
|
1508
|
+
}
|
|
1509
|
+
issues.add("init_failed");
|
|
1510
|
+
try {
|
|
1511
|
+
await stableLease.release();
|
|
1512
|
+
} catch (error) {
|
|
1513
|
+
warnOnce(
|
|
1514
|
+
"stable-release",
|
|
1515
|
+
`qwen serve: daemon stable log lease release failed; trying fallback: ${error instanceof Error ? error.message : String(error)}`
|
|
1516
|
+
);
|
|
1517
|
+
}
|
|
1518
|
+
} catch (error) {
|
|
1519
|
+
if (isErrno(error, "ELOCKED")) {
|
|
1520
|
+
warnOnce(
|
|
1521
|
+
"stable-contention",
|
|
1522
|
+
`qwen serve: daemon stable log is owned by another daemon instance; using a fallback log for runId=${runId}`
|
|
1523
|
+
);
|
|
1524
|
+
} else {
|
|
1525
|
+
issues.add("init_failed");
|
|
1526
|
+
warnOnce(
|
|
1527
|
+
"stable-lock",
|
|
1528
|
+
`qwen serve: daemon stable log unavailable; trying a fallback: ${error instanceof Error ? error.message : String(error)}`
|
|
1529
|
+
);
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
let fallbackFamily;
|
|
1533
|
+
try {
|
|
1534
|
+
fallbackFamily = await allocateFallbackFamily({
|
|
1535
|
+
fs: fs2,
|
|
1536
|
+
acquireLock,
|
|
1537
|
+
policy,
|
|
1538
|
+
daemonDir,
|
|
1539
|
+
runId,
|
|
1540
|
+
onCompromised
|
|
1541
|
+
});
|
|
1542
|
+
const activeFallbackFamily = fallbackFamily;
|
|
1543
|
+
const fallbackLogger = await tryFamily(activeFallbackFamily);
|
|
1544
|
+
if (!fallbackLogger) {
|
|
1545
|
+
issues.add("init_failed");
|
|
1546
|
+
await removeFailedFallbackBestEffort({
|
|
1547
|
+
fs: fs2,
|
|
1548
|
+
acquireLock,
|
|
1549
|
+
policy,
|
|
1550
|
+
family: activeFallbackFamily
|
|
1551
|
+
});
|
|
1552
|
+
return createStderrOnlyLogger({
|
|
1553
|
+
runId,
|
|
1554
|
+
daemonId: computeDaemonId(pid),
|
|
1555
|
+
now,
|
|
1556
|
+
stderr,
|
|
1557
|
+
issues
|
|
1558
|
+
});
|
|
1559
|
+
}
|
|
1560
|
+
const runsDir = nodePath.dirname(activeFallbackFamily.familyDir);
|
|
1561
|
+
try {
|
|
1562
|
+
if (activeFallbackFamily.lease.compromised) return fallbackLogger;
|
|
1563
|
+
const maintenance = await acquireMaintenanceLease({
|
|
1564
|
+
fs: fs2,
|
|
1565
|
+
acquireLock,
|
|
1566
|
+
policy,
|
|
1567
|
+
runsDir,
|
|
1568
|
+
retryBudgetMs: 0
|
|
1569
|
+
});
|
|
1570
|
+
try {
|
|
1571
|
+
if (!activeFallbackFamily.lease.compromised) {
|
|
1572
|
+
await writeRecentFallback(
|
|
1573
|
+
fs2,
|
|
1574
|
+
runsDir,
|
|
1575
|
+
nodePath.basename(activeFallbackFamily.familyDir),
|
|
1576
|
+
() => !maintenance.compromised && !maintenance.released && !activeFallbackFamily.lease.compromised
|
|
1577
|
+
);
|
|
1578
|
+
}
|
|
1579
|
+
} finally {
|
|
1580
|
+
await maintenance.release();
|
|
1581
|
+
}
|
|
1582
|
+
} catch (error) {
|
|
1583
|
+
warnOnce(
|
|
1584
|
+
"fallback-locator",
|
|
1585
|
+
`qwen serve: daemon fallback locator update failed; use ${activeFallbackFamily.activePath}: ${error instanceof Error ? error.message : String(error)}`
|
|
1586
|
+
);
|
|
1587
|
+
}
|
|
1588
|
+
return fallbackLogger;
|
|
1589
|
+
} catch (error) {
|
|
1590
|
+
issues.add("init_failed");
|
|
1591
|
+
await fallbackFamily?.releaseLease().catch(() => {
|
|
1592
|
+
});
|
|
1593
|
+
warnOnce(
|
|
1594
|
+
"fallback-init",
|
|
1595
|
+
`qwen serve: daemon log disabled \u2014 fallback init failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1596
|
+
);
|
|
1597
|
+
return createStderrOnlyLogger({
|
|
1598
|
+
runId,
|
|
1599
|
+
daemonId: computeDaemonId(pid),
|
|
1600
|
+
now,
|
|
1601
|
+
stderr,
|
|
1602
|
+
issues
|
|
1603
|
+
});
|
|
1604
|
+
}
|
|
411
1605
|
}
|
|
412
1606
|
__name(initDaemonLogger, "initDaemonLogger");
|
|
413
1607
|
|
|
@@ -941,6 +2135,30 @@ var QWEN_SERVE_CDP_TUNNEL_OVER_WS_ENV = "QWEN_SERVE_CDP_TUNNEL_OVER_WS";
|
|
|
941
2135
|
var QWEN_SERVE_PROMPT_DEADLINE_MS_ENV = "QWEN_SERVE_PROMPT_DEADLINE_MS";
|
|
942
2136
|
var QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS_ENV = "QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS";
|
|
943
2137
|
var SHUTDOWN_FORCE_CLOSE_MS = 5e3;
|
|
2138
|
+
var DAEMON_LOG_FORCED_FLUSH_BUDGET_MS = 250;
|
|
2139
|
+
async function flushDaemonLogBounded(daemonLog, budgetMs) {
|
|
2140
|
+
let timer;
|
|
2141
|
+
try {
|
|
2142
|
+
await Promise.race([
|
|
2143
|
+
daemonLog.flush().catch(() => {
|
|
2144
|
+
}),
|
|
2145
|
+
new Promise((resolve) => {
|
|
2146
|
+
timer = setTimeout(resolve, budgetMs);
|
|
2147
|
+
timer.unref();
|
|
2148
|
+
})
|
|
2149
|
+
]);
|
|
2150
|
+
} finally {
|
|
2151
|
+
if (timer) clearTimeout(timer);
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
__name(flushDaemonLogBounded, "flushDaemonLogBounded");
|
|
2155
|
+
function writeDaemonLifecycleBestEffort(write) {
|
|
2156
|
+
try {
|
|
2157
|
+
write();
|
|
2158
|
+
} catch {
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
__name(writeDaemonLifecycleBestEffort, "writeDaemonLifecycleBestEffort");
|
|
944
2162
|
function daemonPipeDirection(direction) {
|
|
945
2163
|
switch (direction) {
|
|
946
2164
|
case "sent":
|
|
@@ -1139,12 +2357,12 @@ __name(withSettingsLock, "withSettingsLock");
|
|
|
1139
2357
|
var channelWorkerRuntimePromise;
|
|
1140
2358
|
async function loadChannelWorkerRuntime() {
|
|
1141
2359
|
channelWorkerRuntimePromise ??= Promise.all([
|
|
1142
|
-
import("./channel-worker-supervisor-
|
|
1143
|
-
import("./pidfile-
|
|
1144
|
-
import("./runtime-
|
|
2360
|
+
import("./channel-worker-supervisor-QCXSXCRY.js"),
|
|
2361
|
+
import("./pidfile-ILI37KRQ.js"),
|
|
2362
|
+
import("./runtime-6MQFF2A6.js"),
|
|
1145
2363
|
import("./cli-entry-path-4VJ3Y6T2.js"),
|
|
1146
|
-
import("./channel-worker-group-
|
|
1147
|
-
import("./channel-worker-manager-
|
|
2364
|
+
import("./channel-worker-group-QZV2SP5U.js"),
|
|
2365
|
+
import("./channel-worker-manager-3GMAU45H.js")
|
|
1148
2366
|
]).then(
|
|
1149
2367
|
([
|
|
1150
2368
|
supervisor,
|
|
@@ -1249,7 +2467,7 @@ function shouldPreheatBridge(deps) {
|
|
|
1249
2467
|
__name(shouldPreheatBridge, "shouldPreheatBridge");
|
|
1250
2468
|
var coreRuntimePromise;
|
|
1251
2469
|
function loadCoreRuntime() {
|
|
1252
|
-
coreRuntimePromise ??= import("./src-
|
|
2470
|
+
coreRuntimePromise ??= import("./src-Q4XB6SVD.js");
|
|
1253
2471
|
return coreRuntimePromise;
|
|
1254
2472
|
}
|
|
1255
2473
|
__name(loadCoreRuntime, "loadCoreRuntime");
|
|
@@ -1279,10 +2497,10 @@ __name(resolveDaemonLogBaseDirForRun, "resolveDaemonLogBaseDirForRun");
|
|
|
1279
2497
|
var settingsRuntimePromise;
|
|
1280
2498
|
function loadSettingsRuntimeModules() {
|
|
1281
2499
|
settingsRuntimePromise ??= Promise.all([
|
|
1282
|
-
import("./settings-
|
|
1283
|
-
import("./environment-
|
|
1284
|
-
import("./loadedSettingsAdapter-
|
|
1285
|
-
import("./trustedFolders-
|
|
2500
|
+
import("./settings-CADELKSU.js"),
|
|
2501
|
+
import("./environment-HP6RK262.js"),
|
|
2502
|
+
import("./loadedSettingsAdapter-I5KG37EI.js"),
|
|
2503
|
+
import("./trustedFolders-C6664IQC.js")
|
|
1286
2504
|
]).then(([settings, environment, loadedSettingsAdapter, trustedFolders]) => ({
|
|
1287
2505
|
settings,
|
|
1288
2506
|
environment,
|
|
@@ -1295,8 +2513,8 @@ __name(loadSettingsRuntimeModules, "loadSettingsRuntimeModules");
|
|
|
1295
2513
|
var channelWebhookConfigRuntimePromise;
|
|
1296
2514
|
function loadChannelWebhookConfigRuntime() {
|
|
1297
2515
|
channelWebhookConfigRuntimePromise ??= Promise.all([
|
|
1298
|
-
import("./runtime-
|
|
1299
|
-
import("./config-utils-
|
|
2516
|
+
import("./runtime-6MQFF2A6.js"),
|
|
2517
|
+
import("./config-utils-MOGE4EVB.js")
|
|
1300
2518
|
]).then(([channelRuntime, configUtils]) => ({
|
|
1301
2519
|
loadChannelsConfig: channelRuntime.loadChannelsConfig,
|
|
1302
2520
|
parseChannelWebhookConfig: configUtils.parseChannelWebhookConfig
|
|
@@ -1320,16 +2538,16 @@ async function loadServeRuntimeModules() {
|
|
|
1320
2538
|
totalSessionAdmissionModule,
|
|
1321
2539
|
workspaceRegistryModule
|
|
1322
2540
|
] = await Promise.all([
|
|
1323
|
-
import("./server-
|
|
1324
|
-
import("./bridge-
|
|
1325
|
-
import("./spawnChannel-
|
|
1326
|
-
import("./workspace-service-
|
|
2541
|
+
import("./server-QB6CHRZN.js"),
|
|
2542
|
+
import("./bridge-T4TLAZSJ.js"),
|
|
2543
|
+
import("./spawnChannel-VM5IHLJO.js"),
|
|
2544
|
+
import("./workspace-service-WYLRGM4A.js"),
|
|
1327
2545
|
import("./types-ML3TRJQ5.js"),
|
|
1328
|
-
import("./daemon-status-provider-
|
|
1329
|
-
import("./workspace-providers-status-
|
|
1330
|
-
import("./workspace-skills-status-
|
|
1331
|
-
import("./total-session-admission-
|
|
1332
|
-
import("./workspace-registry-
|
|
2546
|
+
import("./daemon-status-provider-67EKK6S3.js"),
|
|
2547
|
+
import("./workspace-providers-status-ZTW2B5QU.js"),
|
|
2548
|
+
import("./workspace-skills-status-NN5QFU3A.js"),
|
|
2549
|
+
import("./total-session-admission-HWVCZ2WR.js"),
|
|
2550
|
+
import("./workspace-registry-R54M5O3W.js")
|
|
1333
2551
|
]);
|
|
1334
2552
|
return {
|
|
1335
2553
|
createServeApp: serverModule.createServeApp,
|
|
@@ -1640,12 +2858,21 @@ function createBootstrapServeApp(input) {
|
|
|
1640
2858
|
severity: "warning",
|
|
1641
2859
|
message: "Daemon runtime is still starting."
|
|
1642
2860
|
};
|
|
2861
|
+
const daemonLogStatus = daemonLog.getStatus();
|
|
2862
|
+
const issues = [issue];
|
|
2863
|
+
if (daemonLogStatus.health === "degraded") {
|
|
2864
|
+
issues.push({
|
|
2865
|
+
code: "daemon_log_degraded",
|
|
2866
|
+
severity: "warning",
|
|
2867
|
+
message: "Daemon file logging is degraded; inspect full status for details."
|
|
2868
|
+
});
|
|
2869
|
+
}
|
|
1643
2870
|
const response = {
|
|
1644
2871
|
v: 1,
|
|
1645
2872
|
detail: detail.detail,
|
|
1646
2873
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1647
2874
|
status: runtimeFailed ? "error" : "warning",
|
|
1648
|
-
issues
|
|
2875
|
+
issues,
|
|
1649
2876
|
daemon: {
|
|
1650
2877
|
pid: process.pid,
|
|
1651
2878
|
uptimeMs: Math.round(process.uptime() * 1e3),
|
|
@@ -1657,7 +2884,15 @@ function createBootstrapServeApp(input) {
|
|
|
1657
2884
|
},
|
|
1658
2885
|
...qwenCodeVersion ? { qwenCodeVersion } : {},
|
|
1659
2886
|
...daemonLog.getDaemonId() ? { daemonId: daemonLog.getDaemonId() } : {},
|
|
1660
|
-
|
|
2887
|
+
runId: daemonLogStatus.runId,
|
|
2888
|
+
logMode: daemonLogStatus.mode,
|
|
2889
|
+
logHealth: daemonLogStatus.health,
|
|
2890
|
+
...detail.detail === "full" && daemonLog.getLogPath() ? { logPath: daemonLog.getLogPath() } : {},
|
|
2891
|
+
...detail.detail === "full" ? {
|
|
2892
|
+
logIssues: daemonLogStatus.issues,
|
|
2893
|
+
logDroppedRecords: daemonLogStatus.droppedRecords,
|
|
2894
|
+
logDroppedBytes: daemonLogStatus.droppedBytes
|
|
2895
|
+
} : {}
|
|
1661
2896
|
},
|
|
1662
2897
|
security: {
|
|
1663
2898
|
tokenConfigured: Boolean(opts.token),
|
|
@@ -1761,7 +2996,7 @@ function createDelegatingServeApp(bootstrapApp, getRuntimeApp, options = {}) {
|
|
|
1761
2996
|
const dispatch = /* @__PURE__ */ __name(async () => {
|
|
1762
2997
|
let target = getRuntimeApp();
|
|
1763
2998
|
if (!target && options.waitForDeferredRuntimeRoutes === true && !isBootstrapServeRoute(req) && !isCorsPreflightRequest(req) && options.startRuntime && options.runtimeReady) {
|
|
1764
|
-
const waitStartedAt =
|
|
2999
|
+
const waitStartedAt = performance2.now();
|
|
1765
3000
|
const timing = {
|
|
1766
3001
|
startedAt: /* @__PURE__ */ new Date(),
|
|
1767
3002
|
path: "joined"
|
|
@@ -1781,7 +3016,7 @@ function createDelegatingServeApp(bootstrapApp, getRuntimeApp, options = {}) {
|
|
|
1781
3016
|
await options.runtimeReady;
|
|
1782
3017
|
} catch {
|
|
1783
3018
|
} finally {
|
|
1784
|
-
timing.waitMs = Math.round((
|
|
3019
|
+
timing.waitMs = Math.round((performance2.now() - waitStartedAt) * 100) / 100;
|
|
1785
3020
|
}
|
|
1786
3021
|
target = getRuntimeApp();
|
|
1787
3022
|
}
|
|
@@ -1894,7 +3129,37 @@ function runSynchronousRequestGate(handler, req, res, next) {
|
|
|
1894
3129
|
}
|
|
1895
3130
|
__name(runSynchronousRequestGate, "runSynchronousRequestGate");
|
|
1896
3131
|
async function runQwenServe(optsIn, deps = {}) {
|
|
1897
|
-
|
|
3132
|
+
let daemonLog;
|
|
3133
|
+
let owner = "startup";
|
|
3134
|
+
try {
|
|
3135
|
+
return await runQwenServeImpl(optsIn, deps, {
|
|
3136
|
+
initialized: /* @__PURE__ */ __name((logger) => {
|
|
3137
|
+
daemonLog = logger;
|
|
3138
|
+
}, "initialized"),
|
|
3139
|
+
published: /* @__PURE__ */ __name(() => {
|
|
3140
|
+
if (owner === "startup") owner = "handle";
|
|
3141
|
+
}, "published"),
|
|
3142
|
+
signalOwned: /* @__PURE__ */ __name(() => {
|
|
3143
|
+
if (owner === "startup") owner = "signal";
|
|
3144
|
+
}, "signalOwned")
|
|
3145
|
+
});
|
|
3146
|
+
} catch (error) {
|
|
3147
|
+
if (daemonLog && owner === "startup") {
|
|
3148
|
+
const startupLog = daemonLog;
|
|
3149
|
+
writeDaemonLifecycleBestEffort(
|
|
3150
|
+
() => startupLog.error(
|
|
3151
|
+
"daemon startup failed",
|
|
3152
|
+
error instanceof Error ? error : new Error(String(error))
|
|
3153
|
+
)
|
|
3154
|
+
);
|
|
3155
|
+
await startupLog.close();
|
|
3156
|
+
}
|
|
3157
|
+
throw error;
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
__name(runQwenServe, "runQwenServe");
|
|
3161
|
+
async function runQwenServeImpl(optsIn, deps, loggerLifecycle) {
|
|
3162
|
+
const runStartedAt = performance2.now();
|
|
1898
3163
|
const shouldPreheat = !deps.bridge && shouldPreheatBridge(deps);
|
|
1899
3164
|
const startup = {
|
|
1900
3165
|
processStartedAt: new Date(
|
|
@@ -2120,6 +3385,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2120
3385
|
const workspaceInputs = rawWorkspaces.map((workspace) => ({
|
|
2121
3386
|
raw: workspace,
|
|
2122
3387
|
cwd: validateAndCanonicalizeWorkspace(workspace),
|
|
3388
|
+
displayName: void 0,
|
|
2123
3389
|
removable: false,
|
|
2124
3390
|
registrationIds: []
|
|
2125
3391
|
}));
|
|
@@ -2160,7 +3426,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2160
3426
|
}
|
|
2161
3427
|
let workspaceRegistrationStore = deps.workspaceRegistrationStore;
|
|
2162
3428
|
if (workspaceRegistrationStore === void 0 && process.env["QWEN_SERVE_NO_PERSISTENT_REGISTRATION"] !== "1") {
|
|
2163
|
-
const { WorkspaceRegistrationStore } = await import("./workspace-registration-store-
|
|
3429
|
+
const { WorkspaceRegistrationStore } = await import("./workspace-registration-store-P6QHCSMU.js");
|
|
2164
3430
|
workspaceRegistrationStore = new WorkspaceRegistrationStore(boundWorkspace);
|
|
2165
3431
|
}
|
|
2166
3432
|
if (workspaceRegistrationStore) {
|
|
@@ -2168,6 +3434,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2168
3434
|
const stored = await workspaceRegistrationStore.read();
|
|
2169
3435
|
for (const storedWorkspace of stored.workspaces) {
|
|
2170
3436
|
const registrationId = workspaceRegistrationId(storedWorkspace);
|
|
3437
|
+
const displayName = stored.displayNames?.[registrationId];
|
|
2171
3438
|
let cwd;
|
|
2172
3439
|
try {
|
|
2173
3440
|
cwd = validateAndCanonicalizeWorkspace(storedWorkspace);
|
|
@@ -2184,6 +3451,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2184
3451
|
);
|
|
2185
3452
|
if (existingInput) {
|
|
2186
3453
|
existingInput.registrationIds.push(registrationId);
|
|
3454
|
+
existingInput.displayName ??= displayName;
|
|
2187
3455
|
continue;
|
|
2188
3456
|
}
|
|
2189
3457
|
const nested = workspaceInputs.some(
|
|
@@ -2208,6 +3476,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2208
3476
|
workspaceInputs.push({
|
|
2209
3477
|
raw: storedWorkspace,
|
|
2210
3478
|
cwd,
|
|
3479
|
+
displayName,
|
|
2211
3480
|
removable: true,
|
|
2212
3481
|
registrationIds: [registrationId]
|
|
2213
3482
|
});
|
|
@@ -2251,10 +3520,13 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2251
3520
|
bootSettings,
|
|
2252
3521
|
boundWorkspace
|
|
2253
3522
|
});
|
|
2254
|
-
const daemonLog = initDaemonLogger({
|
|
3523
|
+
const daemonLog = await initDaemonLogger({
|
|
2255
3524
|
boundWorkspace,
|
|
2256
3525
|
baseDir: daemonLogBaseDir
|
|
2257
3526
|
});
|
|
3527
|
+
loggerLifecycle.initialized(daemonLog);
|
|
3528
|
+
let loggerPublished = false;
|
|
3529
|
+
let loggerSignalOwned = false;
|
|
2258
3530
|
writeStderrLine(
|
|
2259
3531
|
`qwen serve: daemon log \u2192 ${daemonLog.getLogPath() || "(disabled)"}`
|
|
2260
3532
|
);
|
|
@@ -2337,6 +3609,14 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2337
3609
|
);
|
|
2338
3610
|
}
|
|
2339
3611
|
}
|
|
3612
|
+
if (opts.initializeTimeoutMs !== void 0) {
|
|
3613
|
+
if (!isPositiveIntegerMs(opts.initializeTimeoutMs)) {
|
|
3614
|
+
throw new TypeError(
|
|
3615
|
+
`Invalid initializeTimeoutMs: ${opts.initializeTimeoutMs}. Must be a positive integer (milliseconds).`
|
|
3616
|
+
);
|
|
3617
|
+
}
|
|
3618
|
+
assertTimerDelayInRange("initializeTimeoutMs", opts.initializeTimeoutMs);
|
|
3619
|
+
}
|
|
2340
3620
|
if (opts.permissionResponseTimeoutMs !== void 0) {
|
|
2341
3621
|
if (!Number.isFinite(opts.permissionResponseTimeoutMs) || !Number.isInteger(opts.permissionResponseTimeoutMs) || opts.permissionResponseTimeoutMs < 0) {
|
|
2342
3622
|
throw new TypeError(
|
|
@@ -3008,7 +4288,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3008
4288
|
);
|
|
3009
4289
|
}
|
|
3010
4290
|
}), "persistSettingsFn");
|
|
3011
|
-
const { createSubSessionLauncher } = await import("./create-sub-session-
|
|
4291
|
+
const { createSubSessionLauncher } = await import("./create-sub-session-MB35IHCR.js");
|
|
3012
4292
|
const subSessionLauncher = createSubSessionLauncher({
|
|
3013
4293
|
getBridge: /* @__PURE__ */ __name(() => bridgeRef, "getBridge"),
|
|
3014
4294
|
boundWorkspace
|
|
@@ -3025,6 +4305,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3025
4305
|
...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
|
|
3026
4306
|
...opts.compactedReplayMaxBytes !== void 0 ? { compactedReplayMaxBytes: opts.compactedReplayMaxBytes } : {},
|
|
3027
4307
|
...opts.channelIdleTimeoutMs !== void 0 ? { channelIdleTimeoutMs: opts.channelIdleTimeoutMs } : {},
|
|
4308
|
+
...opts.initializeTimeoutMs !== void 0 ? { initializeTimeoutMs: opts.initializeTimeoutMs } : {},
|
|
3028
4309
|
...opts.sessionReapIntervalMs !== void 0 ? { sessionReapIntervalMs: opts.sessionReapIntervalMs } : {},
|
|
3029
4310
|
...opts.sessionIdleTimeoutMs !== void 0 ? { sessionIdleTimeoutMs: opts.sessionIdleTimeoutMs } : {},
|
|
3030
4311
|
...opts.permissionResponseTimeoutMs !== void 0 ? { permissionResponseTimeoutMs: opts.permissionResponseTimeoutMs } : {},
|
|
@@ -3138,6 +4419,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3138
4419
|
{
|
|
3139
4420
|
workspaceId: daemonWorkspaceHash,
|
|
3140
4421
|
workspaceCwd: boundWorkspace,
|
|
4422
|
+
...workspaceInputs[0]?.displayName ? { displayName: workspaceInputs[0].displayName } : {},
|
|
3141
4423
|
primary: true,
|
|
3142
4424
|
trusted: trustedWorkspace,
|
|
3143
4425
|
removable: false,
|
|
@@ -3257,6 +4539,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3257
4539
|
...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
|
|
3258
4540
|
...opts.compactedReplayMaxBytes !== void 0 ? { compactedReplayMaxBytes: opts.compactedReplayMaxBytes } : {},
|
|
3259
4541
|
...opts.channelIdleTimeoutMs !== void 0 ? { channelIdleTimeoutMs: opts.channelIdleTimeoutMs } : {},
|
|
4542
|
+
...opts.initializeTimeoutMs !== void 0 ? { initializeTimeoutMs: opts.initializeTimeoutMs } : {},
|
|
3260
4543
|
...opts.sessionReapIntervalMs !== void 0 ? { sessionReapIntervalMs: opts.sessionReapIntervalMs } : {},
|
|
3261
4544
|
...opts.sessionIdleTimeoutMs !== void 0 ? { sessionIdleTimeoutMs: opts.sessionIdleTimeoutMs } : {},
|
|
3262
4545
|
...opts.permissionResponseTimeoutMs !== void 0 ? { permissionResponseTimeoutMs: opts.permissionResponseTimeoutMs } : {},
|
|
@@ -3356,6 +4639,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3356
4639
|
workspaceRuntimes.push({
|
|
3357
4640
|
workspaceId: secondaryWorkspaceHash,
|
|
3358
4641
|
workspaceCwd: workspaceInput.cwd,
|
|
4642
|
+
...workspaceInput.displayName ? { displayName: workspaceInput.displayName } : {},
|
|
3359
4643
|
primary: false,
|
|
3360
4644
|
trusted: secondaryTrusted,
|
|
3361
4645
|
removable: workspaceInput.removable,
|
|
@@ -3516,6 +4800,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3516
4800
|
...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
|
|
3517
4801
|
...opts.compactedReplayMaxBytes !== void 0 ? { compactedReplayMaxBytes: opts.compactedReplayMaxBytes } : {},
|
|
3518
4802
|
...opts.channelIdleTimeoutMs !== void 0 ? { channelIdleTimeoutMs: opts.channelIdleTimeoutMs } : {},
|
|
4803
|
+
...opts.initializeTimeoutMs !== void 0 ? { initializeTimeoutMs: opts.initializeTimeoutMs } : {},
|
|
3519
4804
|
...opts.sessionReapIntervalMs !== void 0 ? { sessionReapIntervalMs: opts.sessionReapIntervalMs } : {},
|
|
3520
4805
|
...opts.sessionIdleTimeoutMs !== void 0 ? { sessionIdleTimeoutMs: opts.sessionIdleTimeoutMs } : {},
|
|
3521
4806
|
...opts.permissionResponseTimeoutMs !== void 0 ? { permissionResponseTimeoutMs: opts.permissionResponseTimeoutMs } : {},
|
|
@@ -4004,7 +5289,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
4004
5289
|
startup.listenerReadyAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4005
5290
|
startup.processToListenMs = Math.round(process.uptime() * 1e3);
|
|
4006
5291
|
startup.runQwenServeToListenMs = Math.round(
|
|
4007
|
-
|
|
5292
|
+
performance2.now() - runStartedAt
|
|
4008
5293
|
);
|
|
4009
5294
|
profileCheckpoint("serve_listener_ready");
|
|
4010
5295
|
finalizeStartupProfile(`serve-${process.pid}`);
|
|
@@ -4340,17 +5625,17 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
4340
5625
|
}, "completeRuntimeStartup");
|
|
4341
5626
|
const startBridgePreheat = /* @__PURE__ */ __name((bridge) => {
|
|
4342
5627
|
startup.preheat.status = "running";
|
|
4343
|
-
const preheatStartedAt =
|
|
5628
|
+
const preheatStartedAt = performance2.now();
|
|
4344
5629
|
bridge.preheat().then(() => {
|
|
4345
5630
|
startup.preheat.status = "succeeded";
|
|
4346
5631
|
startup.preheat.durationMs = Math.round(
|
|
4347
|
-
|
|
5632
|
+
performance2.now() - preheatStartedAt
|
|
4348
5633
|
);
|
|
4349
5634
|
}).catch((err) => {
|
|
4350
5635
|
const message = err instanceof Error ? err.message : String(err);
|
|
4351
5636
|
startup.preheat.status = "failed";
|
|
4352
5637
|
startup.preheat.durationMs = Math.round(
|
|
4353
|
-
|
|
5638
|
+
performance2.now() - preheatStartedAt
|
|
4354
5639
|
);
|
|
4355
5640
|
startup.preheat.error = message;
|
|
4356
5641
|
writeStderrLine(
|
|
@@ -4430,28 +5715,33 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
4430
5715
|
err instanceof Error ? err : null
|
|
4431
5716
|
);
|
|
4432
5717
|
}
|
|
4433
|
-
await
|
|
4434
|
-
|
|
5718
|
+
await flushDaemonLogBounded(
|
|
5719
|
+
daemonLog,
|
|
5720
|
+
DAEMON_LOG_FORCED_FLUSH_BUDGET_MS
|
|
5721
|
+
);
|
|
4435
5722
|
process.exit(1);
|
|
4436
5723
|
return;
|
|
4437
5724
|
}
|
|
5725
|
+
if (!loggerPublished) {
|
|
5726
|
+
loggerSignalOwned = true;
|
|
5727
|
+
loggerLifecycle.signalOwned();
|
|
5728
|
+
}
|
|
4438
5729
|
daemonLog.warn(`received ${signal}, draining`);
|
|
4439
5730
|
try {
|
|
4440
5731
|
await handle.close();
|
|
4441
|
-
await daemonLog.flush();
|
|
4442
5732
|
process.exit(runtimeStartupError === void 0 ? 0 : 1);
|
|
4443
5733
|
} catch (err) {
|
|
4444
5734
|
daemonLog.error("shutdown error", err instanceof Error ? err : null);
|
|
4445
|
-
await daemonLog.flush().catch(() => {
|
|
4446
|
-
});
|
|
4447
5735
|
if (channelWorkerManager?.state().enabled) {
|
|
4448
5736
|
daemonLog.error(
|
|
4449
5737
|
"refusing to exit while a channel worker or service lease remains; signal again to retry after the child exits (another signal during that retry forces exit)"
|
|
4450
5738
|
);
|
|
4451
|
-
await daemonLog.flush().catch(() => {
|
|
4452
|
-
});
|
|
4453
5739
|
return;
|
|
4454
5740
|
}
|
|
5741
|
+
await flushDaemonLogBounded(
|
|
5742
|
+
daemonLog,
|
|
5743
|
+
DAEMON_LOG_FORCED_FLUSH_BUDGET_MS
|
|
5744
|
+
);
|
|
4455
5745
|
process.exit(1);
|
|
4456
5746
|
}
|
|
4457
5747
|
}, "onSignal");
|
|
@@ -4484,6 +5774,8 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
4484
5774
|
const finish = /* @__PURE__ */ __name((err) => {
|
|
4485
5775
|
if (settled) return;
|
|
4486
5776
|
settled = true;
|
|
5777
|
+
const accessLogController = (runtimeApp ?? runtimeAppForCleanup)?.locals?.[ACCESS_LOG_CONTROLLER_LOCAL];
|
|
5778
|
+
accessLogController?.sealAndFlushSuppressed();
|
|
4487
5779
|
const preserveSignalHandlers = channelWorkerShutdownError !== void 0 && channelWorkerManager?.state().enabled === true;
|
|
4488
5780
|
if (!preserveSignalHandlers) {
|
|
4489
5781
|
process.removeListener("SIGINT", onSignal);
|
|
@@ -4497,19 +5789,28 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
4497
5789
|
writeStderrLine(
|
|
4498
5790
|
`qwen serve: telemetry shutdown error: ${telemetryErr instanceof Error ? telemetryErr.message : String(telemetryErr)}`
|
|
4499
5791
|
);
|
|
4500
|
-
}).finally(
|
|
4501
|
-
})).finally(() => {
|
|
5792
|
+
}).finally(async () => {
|
|
4502
5793
|
const finalErr = err ?? bridgeShutdownError ?? channelWorkerShutdownError;
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
5794
|
+
const retryableChannelClose = channelWorkerShutdownError !== void 0 && channelWorkerManager?.state().enabled === true;
|
|
5795
|
+
if (retryableChannelClose) {
|
|
5796
|
+
await flushDaemonLogBounded(
|
|
5797
|
+
daemonLog,
|
|
5798
|
+
DAEMON_LOG_FORCED_FLUSH_BUDGET_MS
|
|
5799
|
+
);
|
|
5800
|
+
closePromise = void 0;
|
|
5801
|
+
shuttingDown = false;
|
|
5802
|
+
channelControlDraining = false;
|
|
4509
5803
|
rej(finalErr);
|
|
4510
|
-
|
|
4511
|
-
|
|
5804
|
+
return;
|
|
5805
|
+
}
|
|
5806
|
+
if (loggerPublished || loggerSignalOwned) {
|
|
5807
|
+
writeDaemonLifecycleBestEffort(
|
|
5808
|
+
() => daemonLog.info("daemon stopped")
|
|
5809
|
+
);
|
|
5810
|
+
await daemonLog.close();
|
|
4512
5811
|
}
|
|
5812
|
+
if (finalErr) rej(finalErr);
|
|
5813
|
+
else res();
|
|
4513
5814
|
});
|
|
4514
5815
|
}, "finish");
|
|
4515
5816
|
void (coreRuntimePromise ? coreRuntimePromise.then((core) => core.forceFlushMetrics()) : Promise.resolve()).catch((flushErr) => {
|
|
@@ -4638,23 +5939,33 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
4638
5939
|
startRuntime();
|
|
4639
5940
|
}
|
|
4640
5941
|
if (deps.resolveOnListen) {
|
|
5942
|
+
loggerPublished = true;
|
|
5943
|
+
loggerLifecycle.published();
|
|
4641
5944
|
resolve(handle);
|
|
4642
5945
|
} else {
|
|
4643
5946
|
void runtimeReady.then(
|
|
4644
|
-
() =>
|
|
5947
|
+
() => {
|
|
5948
|
+
loggerPublished = true;
|
|
5949
|
+
loggerLifecycle.published();
|
|
5950
|
+
resolve(handle);
|
|
5951
|
+
},
|
|
4645
5952
|
(err) => {
|
|
4646
5953
|
void handle.close().then(
|
|
4647
5954
|
() => {
|
|
4648
5955
|
reject(err instanceof Error ? err : new Error(String(err)));
|
|
4649
5956
|
},
|
|
4650
5957
|
(closeErr) => {
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
5958
|
+
writeDaemonLifecycleBestEffort(
|
|
5959
|
+
() => daemonLog.error(
|
|
5960
|
+
"shutdown after runtime startup error failed",
|
|
5961
|
+
closeErr instanceof Error ? closeErr : null
|
|
5962
|
+
)
|
|
4654
5963
|
);
|
|
4655
5964
|
if (channelWorkerManager?.state().enabled) {
|
|
4656
|
-
|
|
4657
|
-
|
|
5965
|
+
writeDaemonLifecycleBestEffort(
|
|
5966
|
+
() => daemonLog.error(
|
|
5967
|
+
"runtime startup failed, but qwen serve remains alive to retain the channel service lease until worker exit is confirmed"
|
|
5968
|
+
)
|
|
4658
5969
|
);
|
|
4659
5970
|
return;
|
|
4660
5971
|
}
|
|
@@ -4714,7 +6025,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
4714
6025
|
tryListen(opts.port, 0);
|
|
4715
6026
|
});
|
|
4716
6027
|
}
|
|
4717
|
-
__name(
|
|
6028
|
+
__name(runQwenServeImpl, "runQwenServeImpl");
|
|
4718
6029
|
export {
|
|
4719
6030
|
InvalidPolicyConfigError,
|
|
4720
6031
|
createDisabledChannelWorkerSupervisor,
|