@qwen-code/qwen-code 0.23.1-preview.2 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/computer-use/SKILL.md +189 -116
- package/bundled/goal-draft/SKILL.md +23 -13
- package/bundled/qc-helper/docs/_meta.ts +1 -0
- package/bundled/qc-helper/docs/configuration/model-providers.md +47 -1
- package/bundled/qc-helper/docs/configuration/settings.md +50 -0
- package/bundled/qc-helper/docs/conversations-recovery.md +102 -0
- package/bundled/qc-helper/docs/features/channels/overview.md +1 -1
- package/bundled/qc-helper/docs/features/computer-use.md +9 -7
- package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
- package/bundled/qc-helper/docs/features/goals.md +15 -3
- package/bundled/qc-helper/docs/qwen-serve.md +19 -1
- package/chunks/{MaxSizedBox-IYIQ43IZ.js → MaxSizedBox-UDO6Y7RB.js} +20 -20
- package/chunks/{StandaloneSessionPicker-AWB2OHX6.js → StandaloneSessionPicker-D4CUOO4H.js} +38 -38
- package/chunks/{acp-startup-profiler-BAL4LJTN.js → acp-startup-profiler-KEU6VAYR.js} +2 -2
- package/chunks/{acpAgent-ZC57OLS4.js → acpAgent-KWLJFADK.js} +118 -91
- package/chunks/{agent-GEBPAEJS.js → agent-GSUPGEOL.js} +13 -13
- package/chunks/{agent-headless-63ZEYAJK.js → agent-headless-HNYCQUJB.js} +13 -13
- package/chunks/{anthropicContentGenerator-6XDHXIII.js → anthropicContentGenerator-I7LQZH26.js} +30 -7
- package/chunks/{askUserQuestion-3KAYLLMM.js → askUserQuestion-I5W5S3D6.js} +1 -1
- package/chunks/{bridge-MHWO5I5T.js → bridge-B7CV6RVI.js} +23 -23
- package/chunks/{channel-management-service-NFRZXQFO.js → channel-management-service-TRTLQTSV.js} +4 -4
- package/chunks/{channel-settings-store-T7PMIHKC.js → channel-settings-store-FW45IRUP.js} +31 -31
- package/chunks/{channel-worker-group-O2BWK5F7.js → channel-worker-group-PIYPVCTF.js} +6 -6
- package/chunks/{channel-worker-manager-4WP7VJOD.js → channel-worker-manager-FQHEDTD2.js} +6 -6
- package/chunks/{channel-worker-supervisor-CCUXD6J5.js → channel-worker-supervisor-XJPZZ3VK.js} +3 -3
- package/chunks/{chunk-KTLT7VCX.js → chunk-25CBAK3H.js} +2 -2
- package/chunks/{chunk-SHX2HIE7.js → chunk-27LTEY6D.js} +1 -1
- package/chunks/{chunk-ZT3XUGSU.js → chunk-2TMJRF46.js} +86 -9
- package/chunks/{chunk-HWZOOSEB.js → chunk-2YS3NU4A.js} +3 -3
- package/chunks/chunk-2Z3T52OC.js +82 -0
- package/chunks/{chunk-QW7BUOSI.js → chunk-2ZFO5JD7.js} +20 -3
- package/chunks/{chunk-RH344FKI.js → chunk-3BTHHXXE.js} +1 -1
- package/chunks/{chunk-OFB36ZBA.js → chunk-3LPJ776W.js} +1 -1
- package/chunks/{chunk-GEV66YGE.js → chunk-3VDLQUR2.js} +1 -1
- package/chunks/{chunk-RRCNEW2A.js → chunk-3VWPPK5Q.js} +58 -4
- package/chunks/{chunk-L36LLVA5.js → chunk-3YQMUBTS.js} +3 -3
- package/chunks/{chunk-LTCI6ZOJ.js → chunk-45ROPFQY.js} +1 -1
- package/chunks/{chunk-W4LL5RZO.js → chunk-4ALNJDHL.js} +52 -13
- package/chunks/{chunk-4OCYWXKF.js → chunk-5CVY5Q2P.js} +3 -3
- package/chunks/{chunk-ZRVFHLLK.js → chunk-5DQ4YTIZ.js} +1 -1
- package/chunks/{chunk-FWH4736Q.js → chunk-5IL2BZHW.js} +3 -3
- package/chunks/{chunk-537SQ2AI.js → chunk-5WC2ECUK.js} +104 -16
- package/chunks/{chunk-3K65MUKD.js → chunk-65I7S4Z3.js} +2 -1
- package/chunks/{chunk-RUMSY4ES.js → chunk-66JBCTJF.js} +8 -7
- package/chunks/{chunk-YLFICBYK.js → chunk-6JXHO7LG.js} +3 -3
- package/chunks/{chunk-TDHVOZ65.js → chunk-6QILGINT.js} +2 -2
- package/chunks/{chunk-WQBR7LN5.js → chunk-6QV7Z74P.js} +1 -1
- package/chunks/{chunk-RSU3I6UL.js → chunk-6SADVYQQ.js} +1 -1
- package/chunks/{chunk-AIMZIXZM.js → chunk-6TPVIESH.js} +5 -7
- package/chunks/{chunk-2LD5U7Q3.js → chunk-6YEOCHSE.js} +29 -1
- package/chunks/{chunk-7PMKXGRP.js → chunk-75LBC7SV.js} +66 -9
- package/chunks/{chunk-B5FF3LRF.js → chunk-7SL55L5H.js} +22 -15
- package/chunks/{chunk-I7UNCY24.js → chunk-ARYNBBBM.js} +3 -3
- package/chunks/{chunk-QQGAR64U.js → chunk-B3EL44K3.js} +4 -4
- package/chunks/{chunk-KAZWXVI3.js → chunk-CABDNUJ4.js} +2 -2
- package/chunks/{chunk-R7TKFIQO.js → chunk-CALNF3Z3.js} +1 -1
- package/chunks/{chunk-75UQFGFE.js → chunk-CHVU543W.js} +1 -1
- package/chunks/{chunk-C4NXRR7T.js → chunk-CIKL2DQP.js} +2 -2
- package/chunks/{chunk-LD53HMPV.js → chunk-CRZBDVP2.js} +1 -0
- package/chunks/{chunk-SHK2SIR5.js → chunk-D6AQNMUA.js} +4 -4
- package/chunks/{chunk-EPZWBYQI.js → chunk-DO5SMV52.js} +8 -6
- package/chunks/{chunk-P5Z7VD23.js → chunk-DXQ6Z7AH.js} +106 -39
- package/chunks/{chunk-3RMVM33U.js → chunk-DZ6D4B3K.js} +5 -5
- package/chunks/{chunk-T7TP5UQL.js → chunk-E7XSUYCZ.js} +4 -4
- package/chunks/{chunk-2C3XDBGL.js → chunk-EEKU6COG.js} +4 -4
- package/chunks/{chunk-AX23QSX3.js → chunk-EHTKOO6W.js} +4 -4
- package/chunks/{chunk-XNC2TCUO.js → chunk-ENZDGHGJ.js} +4 -4
- package/chunks/{chunk-733KQL63.js → chunk-EOET4H7C.js} +3 -3
- package/chunks/{chunk-37SOBIA3.js → chunk-ERXNTINK.js} +1 -1
- package/chunks/{chunk-F47DITLZ.js → chunk-FAWTMDX7.js} +14 -0
- package/chunks/{chunk-5JLQWQK6.js → chunk-FV4DM2M4.js} +2 -2
- package/chunks/{chunk-UTVIIA7N.js → chunk-FW4E4QPG.js} +1 -1
- package/chunks/{chunk-REDVV5NC.js → chunk-FWRRUITH.js} +7 -7
- package/chunks/{chunk-5V4B3EWA.js → chunk-GM44O6F7.js} +1 -1
- package/chunks/{chunk-Z6DDPSGJ.js → chunk-GNY7B3CA.js} +1 -1
- package/chunks/{chunk-ERMAXPXA.js → chunk-HIXUUCGY.js} +187 -12
- package/chunks/{chunk-EJNYBDYC.js → chunk-HNLMYDQE.js} +1 -1
- package/chunks/{chunk-XX4MBBFW.js → chunk-HUX2DOTF.js} +3 -3
- package/chunks/{chunk-RCUWMVN3.js → chunk-HZ2HUXX7.js} +1 -1
- package/chunks/{chunk-RD3VPM4E.js → chunk-IKG2YVRZ.js} +2 -2
- package/chunks/{chunk-IMWCUWQT.js → chunk-J3TJH52D.js} +1 -1
- package/chunks/{chunk-ZJ2LM2SI.js → chunk-JGDRB4FP.js} +104 -33
- package/chunks/{chunk-ANVC5CSK.js → chunk-L7V52QEZ.js} +10 -10
- package/chunks/{chunk-MFCWL4LI.js → chunk-LNCNUMJ5.js} +451 -396
- package/chunks/{chunk-AUJOWIT5.js → chunk-LZGFVUWZ.js} +3 -3
- package/chunks/{chunk-6KYWU726.js → chunk-M73KHGNR.js} +13 -66
- package/chunks/{chunk-ADJD4LZF.js → chunk-MA5OUNN6.js} +1 -1
- package/chunks/{chunk-I67KJGM6.js → chunk-MFYH2VXV.js} +3 -3
- package/chunks/{chunk-PLUAIHZO.js → chunk-N7YQEKGX.js} +6 -6
- package/chunks/{chunk-JOV46WGX.js → chunk-NB3NDQQK.js} +1 -1
- package/chunks/chunk-NOO4QFXM.js +171 -0
- package/chunks/{chunk-VYCJITND.js → chunk-O2JBJQCF.js} +1 -1
- package/chunks/{chunk-RQNAO42A.js → chunk-OESZTXTG.js} +1 -1
- package/chunks/{chunk-UKADFFL2.js → chunk-OFVAS4AR.js} +1 -1
- package/chunks/{chunk-Y3C5COGI.js → chunk-OPMKGOLD.js} +1 -1
- package/chunks/{chunk-TSLRORQR.js → chunk-PDUMGZ2P.js} +1467 -1323
- package/chunks/{chunk-Z6KFLEG7.js → chunk-PSPAM24S.js} +1 -0
- package/chunks/{chunk-5FYGZ7E3.js → chunk-QK4K76T6.js} +2 -2
- package/chunks/{chunk-NUQFUXOG.js → chunk-QTNCGZHQ.js} +2 -0
- package/chunks/{chunk-WFXD5OZH.js → chunk-QZOXVQPK.js} +1 -1
- package/chunks/{chunk-QJVZLILI.js → chunk-R7OO56VZ.js} +1 -1
- package/chunks/{chunk-KP5QK3FB.js → chunk-RNYENHN5.js} +397 -54
- package/chunks/{chunk-22QOQKG4.js → chunk-RXT4QBDX.js} +1 -1
- package/chunks/{chunk-LYHYXJJ3.js → chunk-S6QVI3MV.js} +3 -3
- package/chunks/{chunk-NXWYCSPL.js → chunk-SOA4HKRJ.js} +1 -1
- package/chunks/{chunk-IGOIYZBG.js → chunk-T2IHCZLS.js} +2 -2
- package/chunks/{chunk-C55CR5I4.js → chunk-TGC4264Q.js} +6 -6
- package/chunks/{chunk-EGRFCIXD.js → chunk-TWAMIEQ2.js} +79 -18
- package/chunks/{chunk-PMGWY6ZP.js → chunk-TWWS7XUW.js} +13 -10
- package/chunks/{chunk-RGAQDQ3Z.js → chunk-UHUT4IDM.js} +18 -9
- package/chunks/{chunk-HPE4LEWX.js → chunk-USN6VNTO.js} +1 -1
- package/chunks/{chunk-BNWIX6BM.js → chunk-UXDVUFKU.js} +3 -3
- package/chunks/{chunk-HY3DXYZK.js → chunk-UYDQYDW2.js} +1 -1
- package/chunks/{chunk-3K456UJF.js → chunk-VF6D6EGV.js} +12 -4
- package/chunks/{chunk-ZNI3V2XA.js → chunk-WAASYFPK.js} +2 -2
- package/chunks/{chunk-OHOO527W.js → chunk-WG7BL3FY.js} +52 -2
- package/chunks/{chunk-C7M445SS.js → chunk-WJDXKQIO.js} +1 -1
- package/chunks/{chunk-HZS3JRQW.js → chunk-WNISCNTA.js} +40 -2
- package/chunks/{chunk-AWDF462I.js → chunk-WQMUGQ6G.js} +2 -2
- package/chunks/{chunk-VU7O7CGQ.js → chunk-XDNFODER.js} +1 -1
- package/chunks/{chunk-65GHQ4FX.js → chunk-XVTCSVBK.js} +514 -47
- package/chunks/{chunk-SI6Q52UI.js → chunk-XZ3Z43XL.js} +3 -3
- package/chunks/{chunk-SD7Y2PMC.js → chunk-YAC7H4K3.js} +2 -2
- package/chunks/{chunk-FXYNIZPW.js → chunk-YCEKI7QX.js} +51 -10
- package/chunks/{chunk-7IKXTGZT.js → chunk-YI2YCNSP.js} +1 -1
- package/chunks/{chunk-E4VX6LXB.js → chunk-YZTGGCEE.js} +10 -2
- package/chunks/{chunk-VMFPZXRT.js → chunk-ZNO5BUAD.js} +43 -31
- package/chunks/{chunk-WLZRMF3C.js → chunk-ZPL2TZNA.js} +353 -11
- package/chunks/{chunk-TXAEXF2B.js → chunk-ZU2T5JIS.js} +21 -8
- package/chunks/{config-utils-F4CFJ4MW.js → config-utils-KTDSQ4MU.js} +24 -24
- package/chunks/{contextCommand-OIIGGOMU.js → contextCommand-UQ3KRYGK.js} +22 -22
- package/chunks/{core-runtime-JEHLOGMB.js → core-runtime-JR34JAFH.js} +20 -20
- package/chunks/{create-sub-session-MVFBE5RA.js → create-sub-session-RGPJOI4S.js} +21 -21
- package/chunks/{daemon-LCUELM6E.js → daemon-UI6SQSBV.js} +1 -1
- package/chunks/{daemon-git-worktree-guard-5FTKLJOU.js → daemon-git-worktree-guard-H3OA26KQ.js} +20 -20
- package/chunks/{daemon-status-provider-P6A5MPMW.js → daemon-status-provider-6WZLKSZU.js} +27 -27
- package/chunks/{daemon-trust-policy-ZJ3NFYUO.js → daemon-trust-policy-3EDP2BYD.js} +27 -27
- package/chunks/{daemon-trust-policy-monitor-6SDLEW7S.js → daemon-trust-policy-monitor-CRHZPK52.js} +27 -27
- package/chunks/{deferred-core-runtime-DWOXIU5S.js → deferred-core-runtime-LO5NTQQ4.js} +20 -20
- package/chunks/{discovery-TUM3ZQ6U.js → discovery-XP4RMDUM.js} +4 -2
- package/chunks/{dist-NXW4DUUX.js → dist-24TCWK5H.js} +1 -1
- package/chunks/{dist-I74QLLQS.js → dist-5I4HLUTO.js} +1 -1
- package/chunks/{dist-XINEKB5A.js → dist-FDISN4AK.js} +1 -1
- package/chunks/{dist-VCAS67N5.js → dist-M4CBX53H.js} +1 -1
- package/chunks/{dist-AI25RVRA.js → dist-NQ2636VT.js} +1 -1
- package/chunks/{dist-3H3WODVS.js → dist-OR2ZQTXZ.js} +1 -1
- package/chunks/{dist-P6YWBITG.js → dist-STAGIFNB.js} +430 -51
- package/chunks/{dist-YNQU4CKC.js → dist-WZTUKIDR.js} +2 -2
- package/chunks/{dist-T4PRA5EZ.js → dist-XJ25G6OH.js} +1 -1
- package/chunks/{edit-WPVXLL3T.js → edit-LB7Z7XK5.js} +13 -13
- package/chunks/{enter-worktree-5A6VW6BN.js → enter-worktree-YFTKHXHZ.js} +2 -2
- package/chunks/{enterPlanMode-JSODW7E2.js → enterPlanMode-P6TVUFIY.js} +13 -13
- package/chunks/{environment-5LLJ3I3W.js → environment-QATJNNKI.js} +23 -23
- package/chunks/{errors-IQT3YZEP.js → errors-3XJ37PS2.js} +22 -22
- package/chunks/{exit-worktree-QV7E7KP6.js → exit-worktree-NF2XEMES.js} +3 -3
- package/chunks/{exitPlanMode-DDVFYNW4.js → exitPlanMode-A3OKL5UO.js} +13 -13
- package/chunks/{fast-path-PAUQQEVU.js → fast-path-DBIT5YQQ.js} +3 -3
- package/chunks/{fast-path-settings-ISEJPRYE.js → fast-path-settings-SATXY3PD.js} +3 -3
- package/chunks/{glob-SQ7CTZ7F.js → glob-73EDTXUE.js} +13 -13
- package/chunks/{goal-tools-UWZRCLQB.js → goal-tools-DFI6YMSD.js} +13 -13
- package/chunks/{handleAutoUpdate-RUPZZTSG.js → handleAutoUpdate-2FUNJO3B.js} +23 -23
- package/chunks/{i18n-SF5MPWEB.js → i18n-FDIA6KFI.js} +23 -21
- package/chunks/{image-gen-Q3RUTVKR.js → image-gen-XP4NNIYG.js} +4 -4
- package/chunks/{initializer-CK4WPYZG.js → initializer-4MJTJOTW.js} +27 -27
- package/chunks/{installationInfo-IRPQEYRF.js → installationInfo-232RA2OK.js} +20 -20
- package/chunks/{list-E3PS3EBJ.js → list-WN6WSGEB.js} +30 -30
- package/chunks/{llm-JQKBOYAF.js → llm-UDFWQWZA.js} +62 -62
- package/chunks/{llm-content-generator-2QWGBW42.js → llm-content-generator-VLMZ2A7A.js} +23 -8
- package/chunks/{loadedSettingsAdapter-DGXGVYZS.js → loadedSettingsAdapter-OBQEIXM7.js} +27 -27
- package/chunks/{loggingContentGenerator-ZYURLJKK.js → loggingContentGenerator-RGVUMUVX.js} +14 -14
- package/chunks/{managed-npm-update-HTHR63EA.js → managed-npm-update-QBAJYCFU.js} +20 -20
- package/chunks/{mcp-I7G2AEWS.js → mcp-OTIZZCPY.js} +27 -27
- package/chunks/{monitor-4R76BCRZ.js → monitor-BV5XF6LL.js} +13 -13
- package/chunks/{nonInteractiveCli-24OQ3VP2.js → nonInteractiveCli-W6MUKDVJ.js} +64 -61
- package/chunks/{notebook-edit-PPSH7FEX.js → notebook-edit-HGBEKGTE.js} +13 -13
- package/chunks/{openaiContentGenerator-K7V5EO7F.js → openaiContentGenerator-NSU3ERBH.js} +8 -8
- package/chunks/{pidfile-TGIUY2GG.js → pidfile-LE3TU4GE.js} +20 -20
- package/chunks/{processUtils-3USXUQWX.js → processUtils-YFBGJK67.js} +2 -2
- package/chunks/{prompt-terminal-ledger-XHVZRXJI.js → prompt-terminal-ledger-4W4W7DSO.js} +21 -21
- package/chunks/{qwenContentGenerator-MPBOQB64.js → qwenContentGenerator-HTA57WFC.js} +16 -16
- package/chunks/{qwenOAuth2-BS5D2LYV.js → qwenOAuth2-KX6LVYQ3.js} +4 -4
- package/chunks/{read-file-R256LDWQ.js → read-file-KHPQ2MB6.js} +2 -2
- package/chunks/{resumeHistoryUtils-S43LTFHD.js → resumeHistoryUtils-K7RV3QBN.js} +23 -23
- package/chunks/{ripGrep-L7HPZ75Y.js → ripGrep-NBBVCMG4.js} +3 -3
- package/chunks/{run-qwen-serve-CTFL5R6U.js → run-qwen-serve-A3JBOZCM.js} +58 -60
- package/chunks/{runtime-FS5TL6P7.js → runtime-7YOU2KJ3.js} +32 -32
- package/chunks/{scheduled-tasks-QXPV3Q35.js → scheduled-tasks-52LXK7LN.js} +25 -25
- package/chunks/{scheduler-EXU5HMVK.js → scheduler-J44M72VM.js} +22 -22
- package/chunks/{send-message-GQKXGMPI.js → send-message-AWKUDJBH.js} +1 -1
- package/chunks/{serve-ITJC7WNN.js → serve-TRC6XJUB.js} +27 -27
- package/chunks/{server-6JQY3PTU.js → server-YPNTJLX2.js} +1296 -822
- package/chunks/{session-PJDEKXD4.js → session-FMMIBFYX.js} +63 -62
- package/chunks/{session-attachments-root-L37ORSST.js → session-attachments-root-LDJMNK7K.js} +20 -20
- package/chunks/{session-pr-refresh-WIFD52YL.js → session-pr-refresh-NLR4EK2J.js} +24 -24
- package/chunks/{settings-LO6J5SAZ.js → settings-A46L577J.js} +26 -26
- package/chunks/{shell-ANAFVYGR.js → shell-Q5LSQPPY.js} +13 -13
- package/chunks/{skill-SHJWKSPH.js → skill-75KPJRCM.js} +2 -2
- package/chunks/{skill-settings-GX3XHZ5Q.js → skill-settings-775YT4YR.js} +26 -26
- package/chunks/{spawnChannel-WE42VBKM.js → spawnChannel-XY73I5CU.js} +20 -20
- package/chunks/{standalone-update-CWDIKJRP.js → standalone-update-L46XXNQ2.js} +22 -22
- package/chunks/{start-opentui-ui-BBHGFOTF.js → start-opentui-ui-WLV43247.js} +1991 -986
- package/chunks/{startInteractiveUI-FQX7LUYP.js → startInteractiveUI-F5DKMLOV.js} +1119 -1478
- package/chunks/{team-create-WKTPCH6D.js → team-create-2PATB77U.js} +13 -13
- package/chunks/{team-plan-approval-Y23DL7WR.js → team-plan-approval-QTANEWOS.js} +13 -13
- package/chunks/{terminal-image-renderer-B646HBDW.js → terminal-image-renderer-OGULCFNF.js} +20 -20
- package/chunks/{theme-manager-BNWESY26.js → theme-manager-CNO3QERP.js} +20 -20
- package/chunks/{tool-search-PVQ5O5Y2.js → tool-search-VXWEOZE7.js} +2 -2
- package/chunks/{total-session-admission-P5Z43KNW.js → total-session-admission-4KAADZPB.js} +24 -24
- package/chunks/{trustedFolders-FH2LT2MZ.js → trustedFolders-PPJSOPOT.js} +21 -21
- package/chunks/{update-relaunch-WOWTKJSN.js → update-relaunch-4PT4MW7B.js} +5 -5
- package/chunks/{updateCheck-3MYFMM35.js → updateCheck-WAVFLWNG.js} +22 -22
- package/chunks/{useAutoAcceptIndicator-Q7ZRRRKO.js → useAutoAcceptIndicator-XNED4NRB.js} +29 -29
- package/chunks/{validateNonInterActiveAuth-MYEWJX3G.js → validateNonInterActiveAuth-J676DUQ2.js} +59 -58
- package/chunks/{version-RO2FPO76.js → version-J6SRRQB2.js} +1 -1
- package/chunks/{web-fetch-QAKY2LUA.js → web-fetch-FMZZYX44.js} +5 -5
- package/chunks/{web-search-XA5Z4ZCD.js → web-search-3G2KXCX5.js} +18 -7
- package/chunks/{workflow-QFIOCMDM.js → workflow-PPZZICQ7.js} +15 -15
- package/chunks/{workspace-providers-status-B2UD7RAG.js → workspace-providers-status-IIYTAQST.js} +29 -29
- package/chunks/{workspace-registration-store-VZLRTI3Q.js → workspace-registration-store-VHCDXAV7.js} +1 -1
- package/chunks/{workspace-registry-GYOGG6TM.js → workspace-registry-I7VQIPS2.js} +24 -24
- package/chunks/{workspace-runtime-coordinator-7KRXGQ4V.js → workspace-runtime-coordinator-DBGNY32G.js} +24 -24
- package/chunks/{workspace-service-DJEYGJE4.js → workspace-service-QSKB2T54.js} +31 -31
- package/chunks/{workspace-skills-status-MOKNESUC.js → workspace-skills-status-T7GPT65J.js} +27 -27
- package/chunks/{workspace-trust-reconciler-AXOSUTQW.js → workspace-trust-reconciler-2PKRDAU4.js} +31 -31
- package/chunks/{write-file-QOYVHAKK.js → write-file-L76CGFTQ.js} +14 -14
- package/chunks/{zoom-image-UCCLGFNC.js → zoom-image-TDJJY2VZ.js} +2 -2
- package/cli.js +13 -13
- package/export-transcript-document.js +126 -122
- package/package.json +3 -3
- package/web-shell/assets/{abnfDiagram-VCTEODGH-CTstZpXw.js → abnfDiagram-VCTEODGH-DHc6plZn.js} +1 -1
- package/web-shell/assets/{arc-DKW0mbPo.js → arc-BQ9m8TDV.js} +1 -1
- package/web-shell/assets/{architectureDiagram-5GKGNRK7-DkMpJ42t.js → architectureDiagram-5GKGNRK7-D5ap3oVB.js} +1 -1
- package/web-shell/assets/{blockDiagram-NRAW4CY4-7Cp1_4i3.js → blockDiagram-NRAW4CY4-BIbnyNph.js} +1 -1
- package/web-shell/assets/{c4Diagram-UCG6FXSJ-BfaoSlBK.js → c4Diagram-UCG6FXSJ-BRsdx_iG.js} +1 -1
- package/web-shell/assets/channel-uMMdTrYk.js +1 -0
- package/web-shell/assets/{chunk-2Q5K7J3B-_n1qzAio.js → chunk-2Q5K7J3B-3lf1fNlx.js} +1 -1
- package/web-shell/assets/{chunk-5VM5RSS4-0cira5ZV.js → chunk-5VM5RSS4-DP8VNRc4.js} +1 -1
- package/web-shell/assets/{chunk-F27PBJKO-DseRXSHC.js → chunk-F27PBJKO-DrohDmZ6.js} +1 -1
- package/web-shell/assets/{chunk-G27WJ6UU-BehQWin0.js → chunk-G27WJ6UU-UZ2QhSx6.js} +1 -1
- package/web-shell/assets/{chunk-JWPE2WC7-B5ftg1Bb.js → chunk-JWPE2WC7-BIMHVcZK.js} +1 -1
- package/web-shell/assets/{chunk-LCL6LL3I-D7rnbVdk.js → chunk-LCL6LL3I-izRxdSDd.js} +1 -1
- package/web-shell/assets/{chunk-POPQ4Y6H-2Bp-Orju.js → chunk-POPQ4Y6H-CXADD4PP.js} +1 -1
- package/web-shell/assets/{chunk-SVP7TREG-CD2goGva.js → chunk-SVP7TREG-B96d8Y_1.js} +1 -1
- package/web-shell/assets/{chunk-XXDRQBXY-DzQt-Rji.js → chunk-XXDRQBXY-CF2sVQpv.js} +1 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DcY-26Ig.js +1 -0
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DcY-26Ig.js +1 -0
- package/web-shell/assets/{cose-bilkent-JH36ORCC-C-BZXSUn.js → cose-bilkent-JH36ORCC-CT6tXVAS.js} +1 -1
- package/web-shell/assets/csv-CX7rUNeC.svg +1 -0
- package/web-shell/assets/{cynefin-OW5HDTMX-BTcvowe1.js → cynefin-OW5HDTMX-X1NS4vtV.js} +1 -1
- package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-BoUE6K81.js → cynefinDiagram-5FMLGOSQ-DNsKNOT4.js} +1 -1
- package/web-shell/assets/{dagre-3AP2YEHR-BHxy9xeB.js → dagre-3AP2YEHR-9-AHKqsb.js} +1 -1
- package/web-shell/assets/{diagram-S7CK7UJ4-DMiJIvDT.js → diagram-S7CK7UJ4-Bjgms7j6.js} +1 -1
- package/web-shell/assets/{diagram-UQ7AKVKN-DXV09Aes.js → diagram-UQ7AKVKN-h6bCprbE.js} +1 -1
- package/web-shell/assets/{diagram-VSXAHHWV-CocpRomV.js → diagram-VSXAHHWV-4SbQXVLt.js} +1 -1
- package/web-shell/assets/{diagram-VX7I27RA-DL7nqtb4.js → diagram-VX7I27RA-B5gPCzzB.js} +1 -1
- package/web-shell/assets/{diagram-Z3DM3KII-CPZ2Jux_.js → diagram-Z3DM3KII-DFJXIA3A.js} +1 -1
- package/web-shell/assets/{ebnfDiagram-PWID7BFC-BX-eVNsX.js → ebnfDiagram-PWID7BFC-FwyaU7VY.js} +1 -1
- package/web-shell/assets/{erDiagram-SSCWMZ5O-CPy_Ir6y.js → erDiagram-SSCWMZ5O-8vJQh2te.js} +1 -1
- package/web-shell/assets/{flowDiagram-A5DVABFB-eknAOte9.js → flowDiagram-A5DVABFB-BzA_1gMN.js} +1 -1
- package/web-shell/assets/{ganttDiagram-EL5Y4UJY-crAxw_t7.js → ganttDiagram-EL5Y4UJY-Co-ABbVX.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-M29pa3Tc.js → gitGraphDiagram-WWUBYQGX-DW_FcyrX.js} +1 -1
- package/web-shell/assets/{index-C9R-iojE.js → index-BbMXfhNG.js} +1 -1
- package/web-shell/assets/{index-B4TLaxWs.js → index-Bu-rZoJ-.js} +462 -454
- package/web-shell/assets/index-CsPwZ1ut.css +36 -0
- package/web-shell/assets/{infoDiagram-RXCK75RN-XqspXdOU.js → infoDiagram-RXCK75RN-BEgfhUFN.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-5VMMS53U-C5KFS-7j.js → ishikawaDiagram-5VMMS53U-DCsMxQmc.js} +1 -1
- package/web-shell/assets/{journeyDiagram-EYS64GPL-Cc57LVRo.js → journeyDiagram-EYS64GPL-DyIEYoHz.js} +1 -1
- package/web-shell/assets/{kanban-definition-3QL26DDD-C81OG-AI.js → kanban-definition-3QL26DDD-CkxjqCNr.js} +1 -1
- package/web-shell/assets/{layout-CFVu37BB.js → layout-BEWc0Al9.js} +1 -1
- package/web-shell/assets/{linear-ChBxdtWf.js → linear-CNuNxirL.js} +1 -1
- package/web-shell/assets/{mermaid.core-CMLfue0w.js → mermaid.core-DZBre674.js} +6 -6
- package/web-shell/assets/{mindmap-definition-FBJOCRG2-DFsvJThp.js → mindmap-definition-FBJOCRG2-CpafFz_F.js} +1 -1
- package/web-shell/assets/{pegDiagram-XKGWAZYB-BzpRzM4F.js → pegDiagram-XKGWAZYB-DfZqk_dq.js} +1 -1
- package/web-shell/assets/{pieDiagram-E7YTZNPT-Cv0Kankl.js → pieDiagram-E7YTZNPT-S0UWXlgC.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-AXDQQJYC-Bh2BJ3Ay.js → quadrantDiagram-AXDQQJYC-dd37_Ohj.js} +1 -1
- package/web-shell/assets/{railroadDiagram-O6MQD6OU-y8rNDdDS.js → railroadDiagram-O6MQD6OU-CH8NJZ7u.js} +1 -1
- package/web-shell/assets/{requirementDiagram-EFPCY7ZU-C0m2DKJ_.js → requirementDiagram-EFPCY7ZU-CFdqWYih.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-P5KCCOFB-BzdGnSF4.js → sankeyDiagram-P5KCCOFB-CsddcEGD.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-DPzAVmzz.js → sequenceDiagram-WJ2MYXX4-BZ270mGw.js} +1 -1
- package/web-shell/assets/{sizeCapture-X5ZJPWSS-LcHG28Zh.js → sizeCapture-X5ZJPWSS-CGaS4DBV.js} +1 -1
- package/web-shell/assets/{stateDiagram-HBIQ2CUA-C1Bzy3IT.js → stateDiagram-HBIQ2CUA-COpIzMu6.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-D6qEVAji.js +1 -0
- package/web-shell/assets/{swimlanes-XN3QIQJK-Bftk8V64.js → swimlanes-XN3QIQJK-CMF889m3.js} +1 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-mem5Jj4m.js +8 -0
- package/web-shell/assets/{timeline-definition-24CTP7MA-BfXHcN1A.js → timeline-definition-24CTP7MA-BelnxYz5.js} +1 -1
- package/web-shell/assets/{vennDiagram-4TSXK5OY-DRSlI9-V.js → vennDiagram-4TSXK5OY-CU-NRqIB.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-VM6X3IG4-CaLmqGau.js → wardleyDiagram-VM6X3IG4-CDNKqWh-.js} +1 -1
- package/web-shell/assets/{xychartDiagram-S5SC5T6Z-8lgUT6e8.js → xychartDiagram-S5SC5T6Z-CLqguL5D.js} +1 -1
- package/web-shell/index.html +2 -2
- package/chunks/chunk-3UMWOKJC.js +0 -78
- package/chunks/chunk-IQAFKVXS.js +0 -22
- package/web-shell/assets/channel-CQx7VSAp.js +0 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-C-Uz8hHk.js +0 -1
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-C-Uz8hHk.js +0 -1
- package/web-shell/assets/index-CCrkEbzz.css +0 -36
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-LuuL5byY.js +0 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-COmnNq8s.js +0 -8
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
shouldSuppressRememberErrorDetails,
|
|
21
21
|
workspaceMemoryFailureCode,
|
|
22
22
|
workspaceMemoryFailureDiagnostics
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-XZ3Z43XL.js";
|
|
24
24
|
import {
|
|
25
25
|
SetupGithubError,
|
|
26
26
|
collectSessionData,
|
|
@@ -32,13 +32,13 @@ import {
|
|
|
32
32
|
toJson,
|
|
33
33
|
toJsonl,
|
|
34
34
|
toMarkdown
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-TWWS7XUW.js";
|
|
36
36
|
import {
|
|
37
37
|
OBSERVED_CONTACT_MAX_FRESH_WITHIN_SECONDS,
|
|
38
38
|
ObservedChannelContactStore
|
|
39
39
|
} from "./chunk-M3JGHRMQ.js";
|
|
40
40
|
import "./chunk-VFFQAOPR.js";
|
|
41
|
-
import "./chunk-
|
|
41
|
+
import "./chunk-ERXNTINK.js";
|
|
42
42
|
import {
|
|
43
43
|
escapeAnsiCtrlCodes
|
|
44
44
|
} from "./chunk-47ECGEJC.js";
|
|
@@ -54,7 +54,6 @@ import {
|
|
|
54
54
|
AcpPreAttachBudget,
|
|
55
55
|
CAPABILITIES_SCHEMA_VERSION,
|
|
56
56
|
ClientMcpSenderRegistry,
|
|
57
|
-
ConversationRuntimeOwnershipError,
|
|
58
57
|
CredentialStore,
|
|
59
58
|
DeviceFlowRegistry,
|
|
60
59
|
LocalPathOpenUnavailableError,
|
|
@@ -73,10 +72,6 @@ import {
|
|
|
73
72
|
bearerAuth,
|
|
74
73
|
brandSecret,
|
|
75
74
|
buildDaemonStatusResponse,
|
|
76
|
-
conversationRootCompromisedError,
|
|
77
|
-
conversationRuntimeInUseError,
|
|
78
|
-
conversationRuntimeOwnershipCompromisedError,
|
|
79
|
-
conversationRuntimeUnavailableError,
|
|
80
75
|
createBridgeFileSystemAdapter,
|
|
81
76
|
createClientMcpServerProvider,
|
|
82
77
|
createManagedScratchDirectory,
|
|
@@ -114,7 +109,7 @@ import {
|
|
|
114
109
|
singleTokenCredentials,
|
|
115
110
|
tagListener,
|
|
116
111
|
unsafeRevealSecret
|
|
117
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-M73KHGNR.js";
|
|
118
113
|
import {
|
|
119
114
|
ConversationDirectoryIdentityError,
|
|
120
115
|
getConversationDirectoryName,
|
|
@@ -125,15 +120,16 @@ import {
|
|
|
125
120
|
import "./chunk-UXEO7E3V.js";
|
|
126
121
|
import {
|
|
127
122
|
createTotalSessionAdmissionController
|
|
128
|
-
} from "./chunk-
|
|
123
|
+
} from "./chunk-YI2YCNSP.js";
|
|
129
124
|
import {
|
|
130
125
|
assertValidChannelSecretUpdates
|
|
131
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-LZGFVUWZ.js";
|
|
132
127
|
import {
|
|
133
128
|
AONE_MAX_MR_VIEW_CALLS_PER_RUN,
|
|
134
129
|
DaemonDrainingError,
|
|
135
130
|
InvalidCursorError,
|
|
136
131
|
SessionArchiveCoordinator,
|
|
132
|
+
acquireWorktreeOwnershipOp,
|
|
137
133
|
archiveDaemonSessions,
|
|
138
134
|
assertSessionArchived,
|
|
139
135
|
assertSessionLoadable,
|
|
@@ -156,7 +152,7 @@ import {
|
|
|
156
152
|
runWithWorkspaceRuntimeStorage,
|
|
157
153
|
searchWorkspaceSessionsForResponse,
|
|
158
154
|
unarchiveDaemonSessions
|
|
159
|
-
} from "./chunk-
|
|
155
|
+
} from "./chunk-ZPL2TZNA.js";
|
|
160
156
|
import {
|
|
161
157
|
LIVE_SESSION_SOURCE_PREFIX,
|
|
162
158
|
isCompatibleLiveSessionSource,
|
|
@@ -208,17 +204,17 @@ import {
|
|
|
208
204
|
import {
|
|
209
205
|
evaluateDaemonWorkspaceTrust,
|
|
210
206
|
readDaemonTrustPolicySnapshot
|
|
211
|
-
} from "./chunk-
|
|
207
|
+
} from "./chunk-EOET4H7C.js";
|
|
212
208
|
import {
|
|
213
209
|
readRecentPromptTerminals,
|
|
214
210
|
reconcileDanglingPromptTerminals,
|
|
215
211
|
withPromptTerminals
|
|
216
|
-
} from "./chunk-
|
|
212
|
+
} from "./chunk-IKG2YVRZ.js";
|
|
217
213
|
import {
|
|
218
214
|
WorkspaceGenerationClosedError,
|
|
219
215
|
createSingleWorkspaceRegistry,
|
|
220
216
|
createWorkspaceSessionOwnerIndex
|
|
221
|
-
} from "./chunk-
|
|
217
|
+
} from "./chunk-R7OO56VZ.js";
|
|
222
218
|
import {
|
|
223
219
|
sessionAttachmentsRoots
|
|
224
220
|
} from "./chunk-XWJFDJZK.js";
|
|
@@ -244,11 +240,11 @@ import {
|
|
|
244
240
|
sendUntrustedWorkspaceResponse,
|
|
245
241
|
sendWorkspaceRuntimeUnavailable,
|
|
246
242
|
setWorkspaceRouteContext
|
|
247
|
-
} from "./chunk-
|
|
243
|
+
} from "./chunk-B3EL44K3.js";
|
|
248
244
|
import {
|
|
249
245
|
normalizeChannelDelivery,
|
|
250
246
|
parseChannelDelivery
|
|
251
|
-
} from "./chunk-
|
|
247
|
+
} from "./chunk-WAASYFPK.js";
|
|
252
248
|
import {
|
|
253
249
|
isValidSessionId,
|
|
254
250
|
normalizeSessionIdForLookup,
|
|
@@ -263,7 +259,7 @@ import {
|
|
|
263
259
|
getWorkspaceRuntimeCoordinator,
|
|
264
260
|
getWorkspaceRuntimeCoordinatorIfSupported,
|
|
265
261
|
supportsWorkspaceRuntimeLifecycle
|
|
266
|
-
} from "./chunk-
|
|
262
|
+
} from "./chunk-HZ2HUXX7.js";
|
|
267
263
|
import "./chunk-OIBUG24X.js";
|
|
268
264
|
import {
|
|
269
265
|
MAX_SESSION_RESTORE_TIMEOUT_MS,
|
|
@@ -285,14 +281,14 @@ import {
|
|
|
285
281
|
validateWorkspaceSkillName,
|
|
286
282
|
validateWorkspaceVoiceState,
|
|
287
283
|
voiceSettingsScopeToWire
|
|
288
|
-
} from "./chunk-
|
|
284
|
+
} from "./chunk-FWRRUITH.js";
|
|
289
285
|
import {
|
|
290
286
|
PermissionRulesValidationError,
|
|
291
287
|
buildPermissionSettings,
|
|
292
288
|
isPermissionRuleType,
|
|
293
289
|
normalizePermissionRules,
|
|
294
290
|
readPermissionRuleSet
|
|
295
|
-
} from "./chunk-
|
|
291
|
+
} from "./chunk-CHVU543W.js";
|
|
296
292
|
import {
|
|
297
293
|
assertVoiceBaseUrlNetworkAllowed,
|
|
298
294
|
isStreamingVoiceModel,
|
|
@@ -300,18 +296,18 @@ import {
|
|
|
300
296
|
resolveVoiceTranscriptionConfig,
|
|
301
297
|
sanitizeVoiceErrorMessage,
|
|
302
298
|
transcribeVoiceAudio
|
|
303
|
-
} from "./chunk-
|
|
299
|
+
} from "./chunk-GNY7B3CA.js";
|
|
304
300
|
import {
|
|
305
301
|
isVoiceEnabled,
|
|
306
302
|
isVoiceMode,
|
|
307
303
|
readVoiceModel
|
|
308
|
-
} from "./chunk-
|
|
304
|
+
} from "./chunk-NB3NDQQK.js";
|
|
309
305
|
import "./chunk-Y53DG2HA.js";
|
|
310
306
|
import {
|
|
311
307
|
createDaemonStatusProvider
|
|
312
|
-
} from "./chunk-
|
|
313
|
-
import "./chunk-
|
|
314
|
-
import "./chunk-
|
|
308
|
+
} from "./chunk-OESZTXTG.js";
|
|
309
|
+
import "./chunk-5IL2BZHW.js";
|
|
310
|
+
import "./chunk-6QILGINT.js";
|
|
315
311
|
import "./chunk-JS73NNWF.js";
|
|
316
312
|
import {
|
|
317
313
|
SessionArtifactAuthorizationError,
|
|
@@ -320,7 +316,7 @@ import {
|
|
|
320
316
|
extractErrorCode,
|
|
321
317
|
extractErrorMessage,
|
|
322
318
|
parseSessionSource
|
|
323
|
-
} from "./chunk-
|
|
319
|
+
} from "./chunk-2TMJRF46.js";
|
|
324
320
|
import {
|
|
325
321
|
EVENT_SCHEMA_VERSION,
|
|
326
322
|
EventBus,
|
|
@@ -333,21 +329,21 @@ import {
|
|
|
333
329
|
} from "./chunk-KA5HR3G2.js";
|
|
334
330
|
import {
|
|
335
331
|
createWorkspaceProvidersStatusProvider
|
|
336
|
-
} from "./chunk-
|
|
332
|
+
} from "./chunk-DO5SMV52.js";
|
|
337
333
|
import {
|
|
338
334
|
PERSIST_REASONING_SELECTION_META_KEY,
|
|
339
335
|
REASONING_SELECTION_PERSISTED_META_KEY
|
|
340
|
-
} from "./chunk-
|
|
336
|
+
} from "./chunk-JGDRB4FP.js";
|
|
341
337
|
import {
|
|
342
338
|
getAuthTypeFromEnv,
|
|
343
339
|
resolveCliGenerationConfig
|
|
344
|
-
} from "./chunk-
|
|
340
|
+
} from "./chunk-ARYNBBBM.js";
|
|
345
341
|
import {
|
|
346
342
|
snapshotProcessEnv
|
|
347
343
|
} from "./chunk-6RZX2HIH.js";
|
|
348
344
|
import {
|
|
349
345
|
createWorkspaceSkillsStatusProvider
|
|
350
|
-
} from "./chunk-
|
|
346
|
+
} from "./chunk-QK4K76T6.js";
|
|
351
347
|
import "./chunk-BHTYRHJF.js";
|
|
352
348
|
import {
|
|
353
349
|
BridgeTimeoutError,
|
|
@@ -366,29 +362,35 @@ import {
|
|
|
366
362
|
WorkspaceSkillNotFoundError,
|
|
367
363
|
mapWorkspaceSkillToggleError
|
|
368
364
|
} from "./chunk-FTJMWDND.js";
|
|
369
|
-
import "./chunk-
|
|
365
|
+
import "./chunk-5WC2ECUK.js";
|
|
370
366
|
import {
|
|
371
367
|
daemonObservedContactsPath,
|
|
372
368
|
loadChannelsConfig
|
|
373
|
-
} from "./chunk-
|
|
374
|
-
import "./chunk-
|
|
369
|
+
} from "./chunk-DZ6D4B3K.js";
|
|
370
|
+
import "./chunk-EEKU6COG.js";
|
|
375
371
|
import "./chunk-57OAHC2Y.js";
|
|
376
372
|
import {
|
|
377
373
|
parseChannelWebhookConfigLenient
|
|
378
|
-
} from "./chunk-
|
|
374
|
+
} from "./chunk-UXDVUFKU.js";
|
|
379
375
|
import {
|
|
380
376
|
supportedChannelCatalog
|
|
381
|
-
} from "./chunk-
|
|
382
|
-
import "./chunk-
|
|
377
|
+
} from "./chunk-UHUT4IDM.js";
|
|
378
|
+
import "./chunk-3BTHHXXE.js";
|
|
383
379
|
import "./chunk-V6WHFGST.js";
|
|
384
380
|
import {
|
|
381
|
+
assertLiveDiscoveryPublisher,
|
|
385
382
|
getStableLiveDiscoveryBaseDir
|
|
386
|
-
} from "./chunk-
|
|
383
|
+
} from "./chunk-WG7BL3FY.js";
|
|
387
384
|
import {
|
|
385
|
+
ConversationRuntimeOwnershipError,
|
|
388
386
|
LIVE_HOST_BUNDLE_ID,
|
|
389
387
|
LIVE_HOST_PROTOCOL_VERSION,
|
|
390
|
-
LIVE_INPUT_AUDIO_EPOCH_BYTES
|
|
391
|
-
|
|
388
|
+
LIVE_INPUT_AUDIO_EPOCH_BYTES,
|
|
389
|
+
conversationRootCompromisedError,
|
|
390
|
+
conversationRuntimeInUseError,
|
|
391
|
+
conversationRuntimeOwnershipCompromisedError,
|
|
392
|
+
conversationRuntimeUnavailableError
|
|
393
|
+
} from "./chunk-2Z3T52OC.js";
|
|
392
394
|
import "./chunk-ZL4HFSL6.js";
|
|
393
395
|
import "./chunk-K6KS3LTN.js";
|
|
394
396
|
import "./chunk-OSHQMOBS.js";
|
|
@@ -399,13 +401,13 @@ import {
|
|
|
399
401
|
WorkspaceRegistrationStoreLimitError,
|
|
400
402
|
normalizeWorkspaceDisplayName,
|
|
401
403
|
workspaceRegistrationId
|
|
402
|
-
} from "./chunk-
|
|
404
|
+
} from "./chunk-QZOXVQPK.js";
|
|
403
405
|
import {
|
|
404
406
|
CHANNEL_PROMPT_META_KEY,
|
|
405
407
|
DAEMON_PROMPT_DISPLAY_TEXT_META_KEY,
|
|
406
408
|
REQUESTED_SESSION_ID_META_KEY,
|
|
407
409
|
gradeActiveWorkCoverage
|
|
408
|
-
} from "./chunk-
|
|
410
|
+
} from "./chunk-PSPAM24S.js";
|
|
409
411
|
import {
|
|
410
412
|
BranchWhilePromptActiveError,
|
|
411
413
|
BridgeChannelQuarantinedError,
|
|
@@ -431,6 +433,7 @@ import {
|
|
|
431
433
|
SessionLimitExceededError,
|
|
432
434
|
SessionNotArchivedError,
|
|
433
435
|
SessionNotFoundError,
|
|
436
|
+
SessionResetPendingError,
|
|
434
437
|
SessionShellClientRequiredError,
|
|
435
438
|
SessionShellDisabledError,
|
|
436
439
|
StandaloneSessionSpawnError,
|
|
@@ -441,7 +444,7 @@ import {
|
|
|
441
444
|
WorkspaceInitRaceError,
|
|
442
445
|
WorkspaceInitSymlinkError,
|
|
443
446
|
WorkspaceMismatchError
|
|
444
|
-
} from "./chunk-
|
|
447
|
+
} from "./chunk-FAWTMDX7.js";
|
|
445
448
|
import {
|
|
446
449
|
MAX_WORKSPACE_PATH_LENGTH,
|
|
447
450
|
canonicalizeWorkspace,
|
|
@@ -461,7 +464,7 @@ import {
|
|
|
461
464
|
} from "./chunk-STUJ7IMZ.js";
|
|
462
465
|
import {
|
|
463
466
|
normalizeWorkerDiagnostic
|
|
464
|
-
} from "./chunk-
|
|
467
|
+
} from "./chunk-GM44O6F7.js";
|
|
465
468
|
import {
|
|
466
469
|
QWEN_SERVER_TOKEN_ENV
|
|
467
470
|
} from "./chunk-GYTKQYDB.js";
|
|
@@ -479,7 +482,7 @@ import {
|
|
|
479
482
|
import "./chunk-3VUENPWF.js";
|
|
480
483
|
import {
|
|
481
484
|
sanitizeLogText
|
|
482
|
-
} from "./chunk-
|
|
485
|
+
} from "./chunk-XVTCSVBK.js";
|
|
483
486
|
import "./chunk-IW6RQPQB.js";
|
|
484
487
|
import "./chunk-5HBA2Z7V.js";
|
|
485
488
|
import {
|
|
@@ -494,8 +497,8 @@ import {
|
|
|
494
497
|
resolveOutputLanguageOrPreserveAuto,
|
|
495
498
|
updateOutputLanguageFile,
|
|
496
499
|
validateSettingValue
|
|
497
|
-
} from "./chunk-
|
|
498
|
-
import "./chunk-
|
|
500
|
+
} from "./chunk-66JBCTJF.js";
|
|
501
|
+
import "./chunk-2ZFO5JD7.js";
|
|
499
502
|
import "./chunk-RKUWKYED.js";
|
|
500
503
|
import "./chunk-BW4333PP.js";
|
|
501
504
|
import "./chunk-IDS7MSUP.js";
|
|
@@ -504,18 +507,18 @@ import {
|
|
|
504
507
|
getCurrentLanguage,
|
|
505
508
|
resolveLanguageSetting,
|
|
506
509
|
setLanguageAsync
|
|
507
|
-
} from "./chunk-
|
|
510
|
+
} from "./chunk-CRZBDVP2.js";
|
|
508
511
|
import {
|
|
509
512
|
SUPPORTED_LANGUAGES,
|
|
510
513
|
resolveSupportedLanguage
|
|
511
514
|
} from "./chunk-5EJZE3FP.js";
|
|
512
|
-
import "./chunk-
|
|
513
|
-
import "./chunk-
|
|
514
|
-
import "./chunk-
|
|
515
|
+
import "./chunk-5CVY5Q2P.js";
|
|
516
|
+
import "./chunk-QTNCGZHQ.js";
|
|
517
|
+
import "./chunk-27LTEY6D.js";
|
|
515
518
|
import "./chunk-W3N5XAZ6.js";
|
|
516
519
|
import {
|
|
517
520
|
getWorkspaceTrustStatus
|
|
518
|
-
} from "./chunk-
|
|
521
|
+
} from "./chunk-3VDLQUR2.js";
|
|
519
522
|
import "./chunk-NPQ5ZKRP.js";
|
|
520
523
|
import {
|
|
521
524
|
isWithinRoot as isWithinRoot2
|
|
@@ -532,20 +535,21 @@ import {
|
|
|
532
535
|
loadIgnoreRules,
|
|
533
536
|
shouldShowStep,
|
|
534
537
|
writeWorkspaceContextFile
|
|
535
|
-
} from "./chunk-
|
|
538
|
+
} from "./chunk-ZU2T5JIS.js";
|
|
536
539
|
import "./chunk-GELRJXE2.js";
|
|
537
540
|
import "./chunk-32CM56LO.js";
|
|
538
|
-
import "./chunk-
|
|
541
|
+
import "./chunk-WJDXKQIO.js";
|
|
539
542
|
import "./chunk-2EKVPSIJ.js";
|
|
540
543
|
import "./chunk-LJZSMWOH.js";
|
|
541
544
|
import {
|
|
545
|
+
clearWorktreeSession,
|
|
542
546
|
readWorktreeSession,
|
|
543
547
|
readWorktreeSessionStrict,
|
|
544
548
|
writeWorktreeSession
|
|
545
|
-
} from "./chunk-
|
|
546
|
-
import "./chunk-
|
|
549
|
+
} from "./chunk-YZTGGCEE.js";
|
|
550
|
+
import "./chunk-6SADVYQQ.js";
|
|
547
551
|
import "./chunk-DJXSOEFB.js";
|
|
548
|
-
import "./chunk-
|
|
552
|
+
import "./chunk-25CBAK3H.js";
|
|
549
553
|
import "./chunk-J3VZF2AL.js";
|
|
550
554
|
import "./chunk-OWCFKIFQ.js";
|
|
551
555
|
import "./chunk-ZPJWUGCS.js";
|
|
@@ -559,8 +563,8 @@ import {
|
|
|
559
563
|
isDeviceAuthorizationSuccess,
|
|
560
564
|
isDeviceTokenPending,
|
|
561
565
|
isDeviceTokenSuccess
|
|
562
|
-
} from "./chunk-
|
|
563
|
-
import "./chunk-
|
|
566
|
+
} from "./chunk-XDNFODER.js";
|
|
567
|
+
import "./chunk-YAC7H4K3.js";
|
|
564
568
|
import "./chunk-VNOVK4I7.js";
|
|
565
569
|
import {
|
|
566
570
|
BuiltinAgentRegistry,
|
|
@@ -644,9 +648,9 @@ import {
|
|
|
644
648
|
toSessionPrInfo,
|
|
645
649
|
upsertSessionPr,
|
|
646
650
|
watchRepoBranch
|
|
647
|
-
} from "./chunk-
|
|
651
|
+
} from "./chunk-PDUMGZ2P.js";
|
|
648
652
|
import "./chunk-GOFAQQZA.js";
|
|
649
|
-
import "./chunk-
|
|
653
|
+
import "./chunk-65I7S4Z3.js";
|
|
650
654
|
import "./chunk-6HUXPLB5.js";
|
|
651
655
|
import "./chunk-TWPJO254.js";
|
|
652
656
|
import "./chunk-CQ35AJ4Z.js";
|
|
@@ -655,9 +659,11 @@ import "./chunk-LYT2OU7D.js";
|
|
|
655
659
|
import "./chunk-B54PFQS5.js";
|
|
656
660
|
import {
|
|
657
661
|
GitWorktreeService,
|
|
662
|
+
WorktreeMarkerCommittedError,
|
|
658
663
|
createWorktreeSessionMarkerExclusive,
|
|
659
|
-
readWorktreeSessionMarkerStrict
|
|
660
|
-
|
|
664
|
+
readWorktreeSessionMarkerStrict,
|
|
665
|
+
transferWorktreeSessionMarkerOwner
|
|
666
|
+
} from "./chunk-HIXUUCGY.js";
|
|
661
667
|
import "./chunk-6PVPNMXU.js";
|
|
662
668
|
import "./chunk-565U2ANU.js";
|
|
663
669
|
import "./chunk-FDOGGKAA.js";
|
|
@@ -688,25 +694,25 @@ import {
|
|
|
688
694
|
validateSkillName
|
|
689
695
|
} from "./chunk-CLKE4IY3.js";
|
|
690
696
|
import "./chunk-ZSTCM3MX.js";
|
|
691
|
-
import "./chunk-
|
|
697
|
+
import "./chunk-SOA4HKRJ.js";
|
|
692
698
|
import "./chunk-MLXTMF7H.js";
|
|
693
|
-
import "./chunk-
|
|
699
|
+
import "./chunk-3LPJ776W.js";
|
|
694
700
|
import {
|
|
695
701
|
findGitRoot
|
|
696
702
|
} from "./chunk-3CZ2BQV6.js";
|
|
697
703
|
import "./chunk-PQEISIKS.js";
|
|
698
|
-
import "./chunk-
|
|
704
|
+
import "./chunk-VF6D6EGV.js";
|
|
699
705
|
import "./chunk-H3Q3RSKZ.js";
|
|
700
706
|
import "./chunk-S6LOFUVP.js";
|
|
701
707
|
import "./chunk-NAVJD2PQ.js";
|
|
702
|
-
import "./chunk-
|
|
703
|
-
import "./chunk-
|
|
708
|
+
import "./chunk-OFVAS4AR.js";
|
|
709
|
+
import "./chunk-HNLMYDQE.js";
|
|
704
710
|
import "./chunk-QHMLYMMS.js";
|
|
705
711
|
import "./chunk-CFKIH3D3.js";
|
|
706
|
-
import "./chunk-
|
|
712
|
+
import "./chunk-6YEOCHSE.js";
|
|
707
713
|
import "./chunk-DJ2GSRLV.js";
|
|
708
|
-
import "./chunk-
|
|
709
|
-
import "./chunk-
|
|
714
|
+
import "./chunk-4ALNJDHL.js";
|
|
715
|
+
import "./chunk-NOO4QFXM.js";
|
|
710
716
|
import "./chunk-KFFCDLKV.js";
|
|
711
717
|
import {
|
|
712
718
|
addDaemonRequestAttribute,
|
|
@@ -724,7 +730,7 @@ import "./chunk-XWRJCPHC.js";
|
|
|
724
730
|
import {
|
|
725
731
|
parseLineTolerant,
|
|
726
732
|
read
|
|
727
|
-
} from "./chunk-
|
|
733
|
+
} from "./chunk-6QV7Z74P.js";
|
|
728
734
|
import "./chunk-5ETULJLP.js";
|
|
729
735
|
import "./chunk-XBVNNDPK.js";
|
|
730
736
|
import "./chunk-VGC4I5JJ.js";
|
|
@@ -742,7 +748,7 @@ import "./chunk-HD7O6WLV.js";
|
|
|
742
748
|
import "./chunk-WZAD4ZNJ.js";
|
|
743
749
|
import "./chunk-FPGTNKCP.js";
|
|
744
750
|
import "./chunk-TIGXX4PA.js";
|
|
745
|
-
import "./chunk-
|
|
751
|
+
import "./chunk-N7YQEKGX.js";
|
|
746
752
|
import "./chunk-XFFRI3WM.js";
|
|
747
753
|
import "./chunk-4HOEU2OR.js";
|
|
748
754
|
import "./chunk-HHJLM3WQ.js";
|
|
@@ -6220,7 +6226,7 @@ __name(createRequestedSessionIdAdmission, "createRequestedSessionIdAdmission");
|
|
|
6220
6226
|
|
|
6221
6227
|
// packages/cli/src/serve/conversations/standalone-session-service.ts
|
|
6222
6228
|
init_esbuild_shims();
|
|
6223
|
-
import { randomUUID as
|
|
6229
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
6224
6230
|
|
|
6225
6231
|
// packages/cli/src/serve/server/session-export.ts
|
|
6226
6232
|
init_esbuild_shims();
|
|
@@ -6289,473 +6295,10 @@ __name(exportSessionTranscript, "exportSessionTranscript");
|
|
|
6289
6295
|
|
|
6290
6296
|
// packages/cli/src/serve/conversations/standalone-deletion-journal.ts
|
|
6291
6297
|
init_esbuild_shims();
|
|
6292
|
-
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
6293
|
-
import { constants as fsConstants3 } from "node:fs";
|
|
6294
|
-
import * as fs2 from "node:fs/promises";
|
|
6295
|
-
import * as path8 from "node:path";
|
|
6296
|
-
|
|
6297
|
-
// packages/cli/src/serve/conversations/conversation-runtime-ownership.ts
|
|
6298
|
-
init_esbuild_shims();
|
|
6299
6298
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
6300
6299
|
import { constants as fsConstants2 } from "node:fs";
|
|
6301
6300
|
import * as fs from "node:fs/promises";
|
|
6302
6301
|
import * as path7 from "node:path";
|
|
6303
|
-
var OWNER_DIRECTORY = "conversations";
|
|
6304
|
-
var OWNER_FILE = "runtime-owner.json";
|
|
6305
|
-
var OWNER_LOCK = ".runtime-owner.lock";
|
|
6306
|
-
var MAX_OWNER_BYTES = 4 * 1024;
|
|
6307
|
-
var NONCE_PATTERN = /^[A-Za-z0-9_-]{16,256}$/;
|
|
6308
|
-
var DEFAULT_HANDOFF_GRACE_MS = 1e3;
|
|
6309
|
-
var UnsafeOwnershipStateError = class extends Error {
|
|
6310
|
-
static {
|
|
6311
|
-
__name(this, "UnsafeOwnershipStateError");
|
|
6312
|
-
}
|
|
6313
|
-
};
|
|
6314
|
-
function getConversationRuntimeOwnerPath(stableBaseDir) {
|
|
6315
|
-
return path7.join(stableBaseDir, OWNER_DIRECTORY, OWNER_FILE);
|
|
6316
|
-
}
|
|
6317
|
-
__name(getConversationRuntimeOwnerPath, "getConversationRuntimeOwnerPath");
|
|
6318
|
-
function processIsAlive(pid) {
|
|
6319
|
-
try {
|
|
6320
|
-
process.kill(pid, 0);
|
|
6321
|
-
return true;
|
|
6322
|
-
} catch (error2) {
|
|
6323
|
-
return error2.code !== "ESRCH";
|
|
6324
|
-
}
|
|
6325
|
-
}
|
|
6326
|
-
__name(processIsAlive, "processIsAlive");
|
|
6327
|
-
function delay(milliseconds) {
|
|
6328
|
-
return new Promise((resolve7) => {
|
|
6329
|
-
setTimeout(resolve7, milliseconds);
|
|
6330
|
-
});
|
|
6331
|
-
}
|
|
6332
|
-
__name(delay, "delay");
|
|
6333
|
-
function isMissing(error2) {
|
|
6334
|
-
return error2.code === "ENOENT";
|
|
6335
|
-
}
|
|
6336
|
-
__name(isMissing, "isMissing");
|
|
6337
|
-
function assertOwnerRecord(value) {
|
|
6338
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
6339
|
-
throw new UnsafeOwnershipStateError();
|
|
6340
|
-
}
|
|
6341
|
-
const keys = Object.keys(value).sort();
|
|
6342
|
-
if (keys.length !== 3 || keys[0] !== "instanceNonce" || keys[1] !== "pid" || keys[2] !== "version") {
|
|
6343
|
-
throw new UnsafeOwnershipStateError();
|
|
6344
|
-
}
|
|
6345
|
-
const record = value;
|
|
6346
|
-
if (record["version"] !== 1 || !Number.isSafeInteger(record["pid"]) || record["pid"] <= 0 || typeof record["instanceNonce"] !== "string" || !NONCE_PATTERN.test(record["instanceNonce"])) {
|
|
6347
|
-
throw new UnsafeOwnershipStateError();
|
|
6348
|
-
}
|
|
6349
|
-
return {
|
|
6350
|
-
version: 1,
|
|
6351
|
-
pid: record["pid"],
|
|
6352
|
-
instanceNonce: record["instanceNonce"]
|
|
6353
|
-
};
|
|
6354
|
-
}
|
|
6355
|
-
__name(assertOwnerRecord, "assertOwnerRecord");
|
|
6356
|
-
function sameRecord(left, right) {
|
|
6357
|
-
return left.version === right.version && left.pid === right.pid && left.instanceNonce === right.instanceNonce;
|
|
6358
|
-
}
|
|
6359
|
-
__name(sameRecord, "sameRecord");
|
|
6360
|
-
async function inspectDirectory(directory, requirePrivateMode) {
|
|
6361
|
-
const stat3 = await fs.lstat(directory);
|
|
6362
|
-
if (!stat3.isDirectory() || stat3.isSymbolicLink()) {
|
|
6363
|
-
throw new UnsafeOwnershipStateError();
|
|
6364
|
-
}
|
|
6365
|
-
if (process.platform !== "win32" && (typeof process.getuid === "function" && stat3.uid !== process.getuid() || requirePrivateMode && (stat3.mode & 511) !== 448)) {
|
|
6366
|
-
throw new UnsafeOwnershipStateError();
|
|
6367
|
-
}
|
|
6368
|
-
return { dev: stat3.dev, ino: stat3.ino };
|
|
6369
|
-
}
|
|
6370
|
-
__name(inspectDirectory, "inspectDirectory");
|
|
6371
|
-
async function ensureDirectory(directory, requirePrivateMode) {
|
|
6372
|
-
try {
|
|
6373
|
-
return await inspectDirectory(directory, requirePrivateMode);
|
|
6374
|
-
} catch (error2) {
|
|
6375
|
-
if (error2 instanceof UnsafeOwnershipStateError || !isMissing(error2)) {
|
|
6376
|
-
throw error2;
|
|
6377
|
-
}
|
|
6378
|
-
}
|
|
6379
|
-
const parent = path7.dirname(directory);
|
|
6380
|
-
if (parent === directory) throw new UnsafeOwnershipStateError();
|
|
6381
|
-
const parentIdentity = await ensureDirectory(parent, false);
|
|
6382
|
-
await assertDirectoryIdentity(parent, parentIdentity, false);
|
|
6383
|
-
let created = false;
|
|
6384
|
-
try {
|
|
6385
|
-
await fs.mkdir(directory, { mode: 448 });
|
|
6386
|
-
created = true;
|
|
6387
|
-
} catch (error2) {
|
|
6388
|
-
if (error2.code !== "EEXIST") throw error2;
|
|
6389
|
-
}
|
|
6390
|
-
if (created && process.platform !== "win32") {
|
|
6391
|
-
await fs.chmod(directory, 448);
|
|
6392
|
-
}
|
|
6393
|
-
await assertDirectoryIdentity(parent, parentIdentity, false);
|
|
6394
|
-
return inspectDirectory(directory, requirePrivateMode);
|
|
6395
|
-
}
|
|
6396
|
-
__name(ensureDirectory, "ensureDirectory");
|
|
6397
|
-
async function assertDirectoryIdentity(directory, expected, requirePrivateMode = true) {
|
|
6398
|
-
const current = await inspectDirectory(directory, requirePrivateMode);
|
|
6399
|
-
if (current.dev !== expected.dev || current.ino !== expected.ino) {
|
|
6400
|
-
throw new UnsafeOwnershipStateError();
|
|
6401
|
-
}
|
|
6402
|
-
}
|
|
6403
|
-
__name(assertDirectoryIdentity, "assertDirectoryIdentity");
|
|
6404
|
-
async function assertLockShapeIfPresent(lockPath) {
|
|
6405
|
-
let stat3;
|
|
6406
|
-
try {
|
|
6407
|
-
stat3 = await fs.lstat(lockPath);
|
|
6408
|
-
} catch (error2) {
|
|
6409
|
-
if (isMissing(error2)) return;
|
|
6410
|
-
throw error2;
|
|
6411
|
-
}
|
|
6412
|
-
if (!stat3.isDirectory() || stat3.isSymbolicLink() || process.platform !== "win32" && typeof process.getuid === "function" && stat3.uid !== process.getuid()) {
|
|
6413
|
-
throw new UnsafeOwnershipStateError();
|
|
6414
|
-
}
|
|
6415
|
-
}
|
|
6416
|
-
__name(assertLockShapeIfPresent, "assertLockShapeIfPresent");
|
|
6417
|
-
async function readOwnerRecord(ownerPath) {
|
|
6418
|
-
let pathStat;
|
|
6419
|
-
try {
|
|
6420
|
-
pathStat = await fs.lstat(ownerPath);
|
|
6421
|
-
} catch (error2) {
|
|
6422
|
-
if (isMissing(error2)) return void 0;
|
|
6423
|
-
throw error2;
|
|
6424
|
-
}
|
|
6425
|
-
if (!pathStat.isFile() || pathStat.isSymbolicLink() || pathStat.nlink !== 1 || pathStat.size <= 0 || pathStat.size > MAX_OWNER_BYTES || process.platform !== "win32" && ((pathStat.mode & 511) !== 384 || typeof process.getuid === "function" && pathStat.uid !== process.getuid())) {
|
|
6426
|
-
throw new UnsafeOwnershipStateError();
|
|
6427
|
-
}
|
|
6428
|
-
let handle;
|
|
6429
|
-
try {
|
|
6430
|
-
handle = await fs.open(
|
|
6431
|
-
ownerPath,
|
|
6432
|
-
process.platform === "win32" ? fsConstants2.O_RDONLY : fsConstants2.O_RDONLY | fsConstants2.O_NOFOLLOW
|
|
6433
|
-
);
|
|
6434
|
-
} catch (error2) {
|
|
6435
|
-
if (error2.code === "ELOOP") {
|
|
6436
|
-
throw new UnsafeOwnershipStateError(void 0, { cause: error2 });
|
|
6437
|
-
}
|
|
6438
|
-
throw error2;
|
|
6439
|
-
}
|
|
6440
|
-
try {
|
|
6441
|
-
const handleStat = await handle.stat();
|
|
6442
|
-
if (!handleStat.isFile() || handleStat.nlink !== 1 || handleStat.dev !== pathStat.dev || handleStat.ino !== pathStat.ino || handleStat.size !== pathStat.size || process.platform !== "win32" && ((handleStat.mode & 511) !== 384 || typeof process.getuid === "function" && handleStat.uid !== process.getuid())) {
|
|
6443
|
-
throw new UnsafeOwnershipStateError();
|
|
6444
|
-
}
|
|
6445
|
-
const serialized = await handle.readFile("utf8");
|
|
6446
|
-
let parsed;
|
|
6447
|
-
try {
|
|
6448
|
-
parsed = JSON.parse(serialized);
|
|
6449
|
-
} catch (error2) {
|
|
6450
|
-
throw new UnsafeOwnershipStateError(void 0, { cause: error2 });
|
|
6451
|
-
}
|
|
6452
|
-
return assertOwnerRecord(parsed);
|
|
6453
|
-
} finally {
|
|
6454
|
-
await handle.close();
|
|
6455
|
-
}
|
|
6456
|
-
}
|
|
6457
|
-
__name(readOwnerRecord, "readOwnerRecord");
|
|
6458
|
-
async function syncDirectory(directory) {
|
|
6459
|
-
if (process.platform === "win32") return;
|
|
6460
|
-
const handle = await fs.open(directory, fsConstants2.O_RDONLY);
|
|
6461
|
-
try {
|
|
6462
|
-
await handle.sync();
|
|
6463
|
-
} finally {
|
|
6464
|
-
await handle.close();
|
|
6465
|
-
}
|
|
6466
|
-
}
|
|
6467
|
-
__name(syncDirectory, "syncDirectory");
|
|
6468
|
-
var FileConversationRuntimeOwnership = class {
|
|
6469
|
-
static {
|
|
6470
|
-
__name(this, "FileConversationRuntimeOwnership");
|
|
6471
|
-
}
|
|
6472
|
-
stableBaseDir;
|
|
6473
|
-
ownerDirectory;
|
|
6474
|
-
ownerPath;
|
|
6475
|
-
lockPath;
|
|
6476
|
-
current;
|
|
6477
|
-
isProcessAlive;
|
|
6478
|
-
wait;
|
|
6479
|
-
handoffGraceMs;
|
|
6480
|
-
lockOptions;
|
|
6481
|
-
state = "unclaimed";
|
|
6482
|
-
terminalError;
|
|
6483
|
-
acquirePending;
|
|
6484
|
-
releasePending;
|
|
6485
|
-
constructor(options) {
|
|
6486
|
-
this.stableBaseDir = options.stableBaseDir;
|
|
6487
|
-
this.ownerDirectory = path7.dirname(
|
|
6488
|
-
getConversationRuntimeOwnerPath(options.stableBaseDir)
|
|
6489
|
-
);
|
|
6490
|
-
this.ownerPath = getConversationRuntimeOwnerPath(options.stableBaseDir);
|
|
6491
|
-
this.lockPath = path7.join(this.ownerDirectory, OWNER_LOCK);
|
|
6492
|
-
this.current = {
|
|
6493
|
-
version: 1,
|
|
6494
|
-
pid: options.pid,
|
|
6495
|
-
instanceNonce: options.instanceNonce
|
|
6496
|
-
};
|
|
6497
|
-
this.isProcessAlive = options.isProcessAlive ?? processIsAlive;
|
|
6498
|
-
this.wait = options.wait ?? delay;
|
|
6499
|
-
this.handoffGraceMs = options.handoffGraceMs ?? DEFAULT_HANDOFF_GRACE_MS;
|
|
6500
|
-
this.lockOptions = options.lockOptions ?? {
|
|
6501
|
-
stale: 5e3,
|
|
6502
|
-
update: 1e3,
|
|
6503
|
-
retries: {
|
|
6504
|
-
retries: 40,
|
|
6505
|
-
minTimeout: 10,
|
|
6506
|
-
maxTimeout: 50,
|
|
6507
|
-
factor: 1.2,
|
|
6508
|
-
randomize: true
|
|
6509
|
-
}
|
|
6510
|
-
};
|
|
6511
|
-
}
|
|
6512
|
-
acquire() {
|
|
6513
|
-
if (this.acquirePending) return this.acquirePending;
|
|
6514
|
-
const pending = this.acquireOnce().finally(() => {
|
|
6515
|
-
if (this.acquirePending === pending) this.acquirePending = void 0;
|
|
6516
|
-
});
|
|
6517
|
-
this.acquirePending = pending;
|
|
6518
|
-
return pending;
|
|
6519
|
-
}
|
|
6520
|
-
release() {
|
|
6521
|
-
if (this.releasePending) return this.releasePending;
|
|
6522
|
-
const pending = this.releaseOnce().finally(() => {
|
|
6523
|
-
if (this.releasePending === pending) this.releasePending = void 0;
|
|
6524
|
-
});
|
|
6525
|
-
this.releasePending = pending;
|
|
6526
|
-
return pending;
|
|
6527
|
-
}
|
|
6528
|
-
async acquireOnce() {
|
|
6529
|
-
if (this.terminalError) throw this.terminalError;
|
|
6530
|
-
if (this.state === "released") {
|
|
6531
|
-
throw this.compromise();
|
|
6532
|
-
}
|
|
6533
|
-
if (this.releasePending) {
|
|
6534
|
-
await this.releasePending.catch(() => void 0);
|
|
6535
|
-
throw this.compromise();
|
|
6536
|
-
}
|
|
6537
|
-
const identity = await this.prepareOwnerDirectory();
|
|
6538
|
-
let releaseLock;
|
|
6539
|
-
let operationError;
|
|
6540
|
-
let reclaimed = false;
|
|
6541
|
-
let lockCompromise;
|
|
6542
|
-
try {
|
|
6543
|
-
await assertLockShapeIfPresent(this.lockPath);
|
|
6544
|
-
const lockfile = (await import("./proper-lockfile-3LHWIM44.js")).default;
|
|
6545
|
-
releaseLock = await lockfile.lock(this.ownerDirectory, {
|
|
6546
|
-
realpath: false,
|
|
6547
|
-
lockfilePath: this.lockPath,
|
|
6548
|
-
...this.lockOptions,
|
|
6549
|
-
onCompromised: /* @__PURE__ */ __name((error2) => {
|
|
6550
|
-
lockCompromise = error2;
|
|
6551
|
-
}, "onCompromised")
|
|
6552
|
-
});
|
|
6553
|
-
await assertLockShapeIfPresent(this.lockPath);
|
|
6554
|
-
await assertDirectoryIdentity(this.ownerDirectory, identity);
|
|
6555
|
-
if (lockCompromise) throw new UnsafeOwnershipStateError();
|
|
6556
|
-
const existing = await readOwnerRecord(this.ownerPath);
|
|
6557
|
-
const commitOwner = /* @__PURE__ */ __name(async () => {
|
|
6558
|
-
if (this.state === "owned") {
|
|
6559
|
-
if (!existing || !sameRecord(existing, this.current)) {
|
|
6560
|
-
throw new UnsafeOwnershipStateError();
|
|
6561
|
-
}
|
|
6562
|
-
} else if (existing && sameRecord(existing, this.current)) {
|
|
6563
|
-
this.state = "provisional";
|
|
6564
|
-
} else if (existing) {
|
|
6565
|
-
if (existing.pid === this.current.pid || this.isProcessAlive(existing.pid)) {
|
|
6566
|
-
throw conversationRuntimeInUseError();
|
|
6567
|
-
}
|
|
6568
|
-
reclaimed = true;
|
|
6569
|
-
await this.commitRecord(identity, existing);
|
|
6570
|
-
} else {
|
|
6571
|
-
await this.commitRecord(identity, void 0);
|
|
6572
|
-
}
|
|
6573
|
-
}, "commitOwner");
|
|
6574
|
-
const liveDiscovery = await import("./discovery-TUM3ZQ6U.js");
|
|
6575
|
-
const handoff = await liveDiscovery.handoffLiveDiscoveryOwner(
|
|
6576
|
-
this.stableBaseDir,
|
|
6577
|
-
this.current,
|
|
6578
|
-
commitOwner,
|
|
6579
|
-
{
|
|
6580
|
-
isProcessAlive: this.isProcessAlive,
|
|
6581
|
-
waitForHandoffGrace: false
|
|
6582
|
-
}
|
|
6583
|
-
);
|
|
6584
|
-
reclaimed ||= handoff.reclaimed;
|
|
6585
|
-
} catch (error2) {
|
|
6586
|
-
operationError = error2;
|
|
6587
|
-
}
|
|
6588
|
-
let releaseError;
|
|
6589
|
-
if (releaseLock) {
|
|
6590
|
-
try {
|
|
6591
|
-
await releaseLock();
|
|
6592
|
-
} catch (error2) {
|
|
6593
|
-
releaseError = error2;
|
|
6594
|
-
}
|
|
6595
|
-
}
|
|
6596
|
-
if (lockCompromise || releaseError) {
|
|
6597
|
-
throw this.compromise(lockCompromise ?? releaseError);
|
|
6598
|
-
}
|
|
6599
|
-
if (operationError) {
|
|
6600
|
-
throw this.mapAcquireError(operationError);
|
|
6601
|
-
}
|
|
6602
|
-
if (reclaimed) {
|
|
6603
|
-
try {
|
|
6604
|
-
await this.wait(this.handoffGraceMs);
|
|
6605
|
-
} catch (error2) {
|
|
6606
|
-
throw this.compromise(error2);
|
|
6607
|
-
}
|
|
6608
|
-
}
|
|
6609
|
-
if (this.state === "provisional") this.state = "owned";
|
|
6610
|
-
return { reclaimed };
|
|
6611
|
-
}
|
|
6612
|
-
async releaseOnce() {
|
|
6613
|
-
if (this.acquirePending) {
|
|
6614
|
-
await this.acquirePending.catch(() => void 0);
|
|
6615
|
-
}
|
|
6616
|
-
if (this.state === "unclaimed" || this.state === "released") return false;
|
|
6617
|
-
if (this.state === "provisional" || this.terminalError) {
|
|
6618
|
-
throw this.terminalError ?? this.compromise();
|
|
6619
|
-
}
|
|
6620
|
-
const identity = await this.prepareOwnerDirectory();
|
|
6621
|
-
let releaseLock;
|
|
6622
|
-
let operationError;
|
|
6623
|
-
let lockCompromise;
|
|
6624
|
-
try {
|
|
6625
|
-
await assertLockShapeIfPresent(this.lockPath);
|
|
6626
|
-
const lockfile = (await import("./proper-lockfile-3LHWIM44.js")).default;
|
|
6627
|
-
releaseLock = await lockfile.lock(this.ownerDirectory, {
|
|
6628
|
-
realpath: false,
|
|
6629
|
-
lockfilePath: this.lockPath,
|
|
6630
|
-
...this.lockOptions,
|
|
6631
|
-
onCompromised: /* @__PURE__ */ __name((error2) => {
|
|
6632
|
-
lockCompromise = error2;
|
|
6633
|
-
}, "onCompromised")
|
|
6634
|
-
});
|
|
6635
|
-
await assertLockShapeIfPresent(this.lockPath);
|
|
6636
|
-
await assertDirectoryIdentity(this.ownerDirectory, identity);
|
|
6637
|
-
const existing = await readOwnerRecord(this.ownerPath);
|
|
6638
|
-
if (lockCompromise || !existing || !sameRecord(existing, this.current)) {
|
|
6639
|
-
throw new UnsafeOwnershipStateError();
|
|
6640
|
-
}
|
|
6641
|
-
await assertDirectoryIdentity(this.ownerDirectory, identity);
|
|
6642
|
-
await fs.unlink(this.ownerPath);
|
|
6643
|
-
this.state = "released";
|
|
6644
|
-
await syncDirectory(this.ownerDirectory);
|
|
6645
|
-
} catch (error2) {
|
|
6646
|
-
operationError = error2;
|
|
6647
|
-
}
|
|
6648
|
-
let releaseError;
|
|
6649
|
-
if (releaseLock) {
|
|
6650
|
-
try {
|
|
6651
|
-
await releaseLock();
|
|
6652
|
-
} catch (error2) {
|
|
6653
|
-
releaseError = error2;
|
|
6654
|
-
}
|
|
6655
|
-
}
|
|
6656
|
-
if (lockCompromise || releaseError) {
|
|
6657
|
-
if (this.state !== "released") this.compromise(lockCompromise);
|
|
6658
|
-
throw conversationRuntimeOwnershipCompromisedError(
|
|
6659
|
-
lockCompromise ?? releaseError
|
|
6660
|
-
);
|
|
6661
|
-
}
|
|
6662
|
-
if (operationError) {
|
|
6663
|
-
if (this.state === "released") {
|
|
6664
|
-
throw conversationRuntimeOwnershipCompromisedError(operationError);
|
|
6665
|
-
}
|
|
6666
|
-
if (operationError instanceof UnsafeOwnershipStateError) {
|
|
6667
|
-
throw this.compromise(operationError);
|
|
6668
|
-
}
|
|
6669
|
-
throw conversationRuntimeUnavailableError(operationError);
|
|
6670
|
-
}
|
|
6671
|
-
return true;
|
|
6672
|
-
}
|
|
6673
|
-
async prepareOwnerDirectory() {
|
|
6674
|
-
try {
|
|
6675
|
-
if (this.state === "unclaimed") {
|
|
6676
|
-
await ensureDirectory(this.stableBaseDir, false);
|
|
6677
|
-
return await ensureDirectory(this.ownerDirectory, true);
|
|
6678
|
-
}
|
|
6679
|
-
await inspectDirectory(this.stableBaseDir, false);
|
|
6680
|
-
return await inspectDirectory(this.ownerDirectory, true);
|
|
6681
|
-
} catch (error2) {
|
|
6682
|
-
if (error2 instanceof UnsafeOwnershipStateError || this.state !== "unclaimed" && isMissing(error2)) {
|
|
6683
|
-
throw this.compromise(error2);
|
|
6684
|
-
}
|
|
6685
|
-
throw conversationRuntimeUnavailableError(error2);
|
|
6686
|
-
}
|
|
6687
|
-
}
|
|
6688
|
-
async commitRecord(identity, expected) {
|
|
6689
|
-
const temporaryPath = path7.join(
|
|
6690
|
-
this.ownerDirectory,
|
|
6691
|
-
`.runtime-owner.${this.current.pid}.${randomUUID3()}.tmp`
|
|
6692
|
-
);
|
|
6693
|
-
let handle;
|
|
6694
|
-
let renamed = false;
|
|
6695
|
-
try {
|
|
6696
|
-
handle = await fs.open(temporaryPath, "wx", 384);
|
|
6697
|
-
await handle.writeFile(`${JSON.stringify(this.current)}
|
|
6698
|
-
`, "utf8");
|
|
6699
|
-
await handle.sync();
|
|
6700
|
-
if (process.platform !== "win32") await handle.chmod(384);
|
|
6701
|
-
await handle.close();
|
|
6702
|
-
handle = void 0;
|
|
6703
|
-
await assertDirectoryIdentity(this.ownerDirectory, identity);
|
|
6704
|
-
const observed = await readOwnerRecord(this.ownerPath);
|
|
6705
|
-
if (expected === void 0 && observed !== void 0 || expected !== void 0 && (!observed || !sameRecord(observed, expected))) {
|
|
6706
|
-
throw new UnsafeOwnershipStateError();
|
|
6707
|
-
}
|
|
6708
|
-
await assertDirectoryIdentity(this.ownerDirectory, identity);
|
|
6709
|
-
if (process.platform === "win32" && observed) {
|
|
6710
|
-
await fs.unlink(this.ownerPath);
|
|
6711
|
-
try {
|
|
6712
|
-
await fs.rename(temporaryPath, this.ownerPath);
|
|
6713
|
-
} catch (error2) {
|
|
6714
|
-
await this.wait(this.handoffGraceMs);
|
|
6715
|
-
throw error2;
|
|
6716
|
-
}
|
|
6717
|
-
} else {
|
|
6718
|
-
await fs.rename(temporaryPath, this.ownerPath);
|
|
6719
|
-
}
|
|
6720
|
-
renamed = true;
|
|
6721
|
-
this.state = "provisional";
|
|
6722
|
-
await syncDirectory(this.ownerDirectory);
|
|
6723
|
-
} finally {
|
|
6724
|
-
await handle?.close().catch(() => void 0);
|
|
6725
|
-
if (!renamed) {
|
|
6726
|
-
await fs.unlink(temporaryPath).catch(() => void 0);
|
|
6727
|
-
}
|
|
6728
|
-
}
|
|
6729
|
-
}
|
|
6730
|
-
mapAcquireError(error2) {
|
|
6731
|
-
if (error2 instanceof ConversationRuntimeOwnershipError) return error2;
|
|
6732
|
-
if (error2 instanceof Error && error2.name === "LiveDiscoveryOwnerActiveError") {
|
|
6733
|
-
return conversationRuntimeInUseError();
|
|
6734
|
-
}
|
|
6735
|
-
if (error2 instanceof UnsafeOwnershipStateError) {
|
|
6736
|
-
return this.compromise(error2);
|
|
6737
|
-
}
|
|
6738
|
-
if (this.state === "provisional" || error2 instanceof Error && error2.name === "LiveDiscoveryStateError") {
|
|
6739
|
-
return this.compromise(error2);
|
|
6740
|
-
}
|
|
6741
|
-
const code = error2.code;
|
|
6742
|
-
if (code === "ECOMPROMISED") return this.compromise(error2);
|
|
6743
|
-
return conversationRuntimeUnavailableError(error2);
|
|
6744
|
-
}
|
|
6745
|
-
compromise(cause) {
|
|
6746
|
-
this.terminalError ??= conversationRuntimeOwnershipCompromisedError(cause);
|
|
6747
|
-
return this.terminalError;
|
|
6748
|
-
}
|
|
6749
|
-
};
|
|
6750
|
-
function createConversationRuntimeOwnership(options) {
|
|
6751
|
-
if (!path7.isAbsolute(options.stableBaseDir) || !Number.isSafeInteger(options.pid) || options.pid <= 0 || !NONCE_PATTERN.test(options.instanceNonce) || !Number.isSafeInteger(options.handoffGraceMs ?? DEFAULT_HANDOFF_GRACE_MS) || (options.handoffGraceMs ?? DEFAULT_HANDOFF_GRACE_MS) < 0) {
|
|
6752
|
-
throw new TypeError("Invalid Conversations runtime ownership options.");
|
|
6753
|
-
}
|
|
6754
|
-
return new FileConversationRuntimeOwnership(options);
|
|
6755
|
-
}
|
|
6756
|
-
__name(createConversationRuntimeOwnership, "createConversationRuntimeOwnership");
|
|
6757
|
-
|
|
6758
|
-
// packages/cli/src/serve/conversations/standalone-deletion-journal.ts
|
|
6759
6302
|
var JOURNAL_DIRECTORY = "deletions";
|
|
6760
6303
|
var MAX_RECORD_BYTES = 8 * 1024;
|
|
6761
6304
|
var STORAGE_SESSION_ID_PATTERN = /^[0-9a-fA-F-]{32,36}$/;
|
|
@@ -6770,10 +6313,10 @@ var StandaloneDeletionJournalError = class extends Error {
|
|
|
6770
6313
|
}
|
|
6771
6314
|
name = "StandaloneDeletionJournalError";
|
|
6772
6315
|
};
|
|
6773
|
-
function
|
|
6316
|
+
function isMissing(error2) {
|
|
6774
6317
|
return error2.code === "ENOENT";
|
|
6775
6318
|
}
|
|
6776
|
-
__name(
|
|
6319
|
+
__name(isMissing, "isMissing");
|
|
6777
6320
|
function parseSessionId(value) {
|
|
6778
6321
|
const parsed = parseCallerSuppliedSessionId(value);
|
|
6779
6322
|
if (parsed.kind !== "valid") {
|
|
@@ -6804,7 +6347,7 @@ function parseIdentity(value, pathField) {
|
|
|
6804
6347
|
if (!isIdentityNumber(value["device"]) || !isIdentityNumber(value["inode"]) || typeof value["inodeVerifiable"] !== "boolean" || (value["inodeVerifiable"] ? value["inode"] === 0 : value["inode"] !== 0)) {
|
|
6805
6348
|
return void 0;
|
|
6806
6349
|
}
|
|
6807
|
-
if (pathField && (typeof value["canonicalPath"] !== "string" || value["canonicalPath"].length === 0 || value["canonicalPath"].length > 4096 || !
|
|
6350
|
+
if (pathField && (typeof value["canonicalPath"] !== "string" || value["canonicalPath"].length === 0 || value["canonicalPath"].length > 4096 || !path7.isAbsolute(value["canonicalPath"]))) {
|
|
6808
6351
|
return void 0;
|
|
6809
6352
|
}
|
|
6810
6353
|
return {
|
|
@@ -6899,25 +6442,26 @@ function sameImmutableRecord(prepared, staged) {
|
|
|
6899
6442
|
}
|
|
6900
6443
|
__name(sameImmutableRecord, "sameImmutableRecord");
|
|
6901
6444
|
var StandaloneDeletionJournal = class {
|
|
6445
|
+
constructor(stableBaseDir) {
|
|
6446
|
+
this.stableBaseDir = stableBaseDir;
|
|
6447
|
+
if (!path7.isAbsolute(stableBaseDir)) {
|
|
6448
|
+
throw new TypeError("Standalone deletion journal base must be absolute.");
|
|
6449
|
+
}
|
|
6450
|
+
this.stateDirectory = path7.join(stableBaseDir, "conversations");
|
|
6451
|
+
this.journalDirectory = path7.join(this.stateDirectory, JOURNAL_DIRECTORY);
|
|
6452
|
+
}
|
|
6902
6453
|
static {
|
|
6903
6454
|
__name(this, "StandaloneDeletionJournal");
|
|
6904
6455
|
}
|
|
6905
|
-
|
|
6456
|
+
stateDirectory;
|
|
6906
6457
|
journalDirectory;
|
|
6458
|
+
directoryIdentities = /* @__PURE__ */ new Map();
|
|
6459
|
+
canonicalBaseDir;
|
|
6907
6460
|
pendingClears = /* @__PURE__ */ new Map();
|
|
6908
|
-
constructor(stableBaseDir) {
|
|
6909
|
-
if (!path8.isAbsolute(stableBaseDir)) {
|
|
6910
|
-
throw new TypeError("Standalone deletion journal base must be absolute.");
|
|
6911
|
-
}
|
|
6912
|
-
this.ownerDirectory = path8.dirname(
|
|
6913
|
-
getConversationRuntimeOwnerPath(stableBaseDir)
|
|
6914
|
-
);
|
|
6915
|
-
this.journalDirectory = path8.join(this.ownerDirectory, JOURNAL_DIRECTORY);
|
|
6916
|
-
}
|
|
6917
6461
|
async hasRecord(rawSessionId) {
|
|
6918
6462
|
const sessionId = parseSessionId(rawSessionId);
|
|
6919
|
-
if (this.pendingClears.has(sessionId)) return true;
|
|
6920
6463
|
const identity = await this.inspectJournalDirectory();
|
|
6464
|
+
if (this.pendingClears.has(sessionId)) return true;
|
|
6921
6465
|
if (!identity) return false;
|
|
6922
6466
|
const exists = await this.pathExists(this.recordPath(sessionId, "prepared")) || await this.pathExists(this.recordPath(sessionId, "staged"));
|
|
6923
6467
|
await this.assertDirectoryIdentity(this.journalDirectory, identity);
|
|
@@ -6931,9 +6475,9 @@ var StandaloneDeletionJournal = class {
|
|
|
6931
6475
|
}
|
|
6932
6476
|
let names;
|
|
6933
6477
|
try {
|
|
6934
|
-
names = await
|
|
6478
|
+
names = await fs.readdir(this.journalDirectory);
|
|
6935
6479
|
} catch (error2) {
|
|
6936
|
-
if (
|
|
6480
|
+
if (isMissing(error2)) {
|
|
6937
6481
|
return [...ids].sort().slice(0, Math.max(0, limit));
|
|
6938
6482
|
}
|
|
6939
6483
|
throw error2;
|
|
@@ -6947,11 +6491,11 @@ var StandaloneDeletionJournal = class {
|
|
|
6947
6491
|
}
|
|
6948
6492
|
async read(rawSessionId, currentRoot) {
|
|
6949
6493
|
const sessionId = parseSessionId(rawSessionId);
|
|
6494
|
+
const identity = await this.inspectJournalDirectory();
|
|
6950
6495
|
const pending = this.pendingClears.get(sessionId);
|
|
6951
6496
|
if (pending) {
|
|
6952
6497
|
return this.validatePendingEntry(pending.entry, currentRoot);
|
|
6953
6498
|
}
|
|
6954
|
-
const identity = await this.inspectJournalDirectory();
|
|
6955
6499
|
if (!identity) return void 0;
|
|
6956
6500
|
const prepared = await this.readPhase(sessionId, "prepared", currentRoot);
|
|
6957
6501
|
const staged = await this.readPhase(sessionId, "staged", currentRoot);
|
|
@@ -6994,6 +6538,7 @@ var StandaloneDeletionJournal = class {
|
|
|
6994
6538
|
}
|
|
6995
6539
|
async clear(rawSessionId, currentRoot) {
|
|
6996
6540
|
const sessionId = parseSessionId(rawSessionId);
|
|
6541
|
+
await this.inspectJournalDirectory();
|
|
6997
6542
|
const pending = this.pendingClears.get(sessionId);
|
|
6998
6543
|
if (pending) {
|
|
6999
6544
|
this.validatePendingEntry(pending.entry, currentRoot);
|
|
@@ -7045,7 +6590,7 @@ var StandaloneDeletionJournal = class {
|
|
|
7045
6590
|
return { prepared, ...staged ? { staged } : {} };
|
|
7046
6591
|
}
|
|
7047
6592
|
recordPath(sessionId, phase) {
|
|
7048
|
-
return
|
|
6593
|
+
return path7.join(
|
|
7049
6594
|
this.journalDirectory,
|
|
7050
6595
|
`delete-${sessionId}.${phase}.json`
|
|
7051
6596
|
);
|
|
@@ -7054,17 +6599,17 @@ var StandaloneDeletionJournal = class {
|
|
|
7054
6599
|
const filePath = this.recordPath(sessionId, phase);
|
|
7055
6600
|
let pathStat;
|
|
7056
6601
|
try {
|
|
7057
|
-
pathStat = await
|
|
6602
|
+
pathStat = await fs.lstat(filePath);
|
|
7058
6603
|
} catch (error2) {
|
|
7059
|
-
if (
|
|
6604
|
+
if (isMissing(error2)) return void 0;
|
|
7060
6605
|
throw error2;
|
|
7061
6606
|
}
|
|
7062
6607
|
this.assertRecordFile(pathStat);
|
|
7063
6608
|
let handle;
|
|
7064
6609
|
try {
|
|
7065
|
-
handle = await
|
|
6610
|
+
handle = await fs.open(
|
|
7066
6611
|
filePath,
|
|
7067
|
-
|
|
6612
|
+
fsConstants2.O_RDONLY | (process.platform === "win32" ? 0 : fsConstants2.O_NOFOLLOW ?? 0)
|
|
7068
6613
|
);
|
|
7069
6614
|
} catch (error2) {
|
|
7070
6615
|
if (error2.code === "ELOOP") {
|
|
@@ -7099,9 +6644,9 @@ var StandaloneDeletionJournal = class {
|
|
|
7099
6644
|
const identity = await this.ensureJournalDirectory();
|
|
7100
6645
|
const target = this.recordPath(record.sessionId, record.phase);
|
|
7101
6646
|
await this.assertPathAbsent(target);
|
|
7102
|
-
const temporary =
|
|
6647
|
+
const temporary = path7.join(
|
|
7103
6648
|
this.journalDirectory,
|
|
7104
|
-
`.${
|
|
6649
|
+
`.${path7.basename(target)}.${randomUUID3()}.tmp`
|
|
7105
6650
|
);
|
|
7106
6651
|
const directory = await this.openDurableDirectory(
|
|
7107
6652
|
this.journalDirectory,
|
|
@@ -7110,9 +6655,9 @@ var StandaloneDeletionJournal = class {
|
|
|
7110
6655
|
let handle;
|
|
7111
6656
|
try {
|
|
7112
6657
|
await this.assertDirectoryIdentity(this.journalDirectory, identity);
|
|
7113
|
-
handle = await
|
|
6658
|
+
handle = await fs.open(
|
|
7114
6659
|
temporary,
|
|
7115
|
-
|
|
6660
|
+
fsConstants2.O_CREAT | fsConstants2.O_EXCL | fsConstants2.O_WRONLY | (process.platform === "win32" ? 0 : fsConstants2.O_NOFOLLOW ?? 0),
|
|
7116
6661
|
384
|
|
7117
6662
|
);
|
|
7118
6663
|
await handle.writeFile(serialized, "utf8");
|
|
@@ -7121,12 +6666,12 @@ var StandaloneDeletionJournal = class {
|
|
|
7121
6666
|
handle = void 0;
|
|
7122
6667
|
await this.assertDirectoryIdentity(this.journalDirectory, identity);
|
|
7123
6668
|
await this.assertPathAbsent(target);
|
|
7124
|
-
await
|
|
7125
|
-
if (process.platform !== "win32") await
|
|
6669
|
+
await fs.rename(temporary, target);
|
|
6670
|
+
if (process.platform !== "win32") await fs.chmod(target, 384);
|
|
7126
6671
|
await this.syncDurableDirectory(directory);
|
|
7127
6672
|
} catch (error2) {
|
|
7128
6673
|
await handle?.close().catch(() => void 0);
|
|
7129
|
-
await
|
|
6674
|
+
await fs.unlink(temporary).catch(() => void 0);
|
|
7130
6675
|
if (error2.code === "EEXIST") {
|
|
7131
6676
|
throw new StandaloneDeletionJournalError("conflict");
|
|
7132
6677
|
}
|
|
@@ -7136,48 +6681,107 @@ var StandaloneDeletionJournal = class {
|
|
|
7136
6681
|
}
|
|
7137
6682
|
}
|
|
7138
6683
|
async ensureJournalDirectory() {
|
|
7139
|
-
|
|
6684
|
+
await this.ensureStateDirectory(this.stableBaseDir, false);
|
|
6685
|
+
const owner = await this.ensureStateDirectory(this.stateDirectory, true);
|
|
7140
6686
|
const ownerHandle = await this.openDurableDirectory(
|
|
7141
|
-
this.
|
|
6687
|
+
this.stateDirectory,
|
|
7142
6688
|
owner
|
|
7143
6689
|
);
|
|
7144
6690
|
try {
|
|
7145
6691
|
let created = false;
|
|
7146
6692
|
try {
|
|
7147
|
-
await
|
|
6693
|
+
await fs.mkdir(this.journalDirectory, { mode: 448 });
|
|
7148
6694
|
created = true;
|
|
7149
6695
|
} catch (error2) {
|
|
7150
6696
|
if (error2.code !== "EEXIST") throw error2;
|
|
7151
6697
|
}
|
|
7152
6698
|
if (created && process.platform !== "win32") {
|
|
7153
|
-
await
|
|
6699
|
+
await fs.chmod(this.journalDirectory, 448);
|
|
7154
6700
|
}
|
|
7155
6701
|
await this.syncDurableDirectory(ownerHandle);
|
|
7156
6702
|
} finally {
|
|
7157
6703
|
await ownerHandle.handle.close().catch(() => void 0);
|
|
7158
6704
|
}
|
|
7159
|
-
return this.
|
|
6705
|
+
return await this.inspectJournalDirectory();
|
|
6706
|
+
}
|
|
6707
|
+
async ensureStateDirectory(directory, requirePrivate) {
|
|
6708
|
+
try {
|
|
6709
|
+
return await this.inspectPrivateDirectory(directory, requirePrivate);
|
|
6710
|
+
} catch (error2) {
|
|
6711
|
+
if (!isMissing(error2)) throw error2;
|
|
6712
|
+
}
|
|
6713
|
+
const parent = path7.dirname(directory);
|
|
6714
|
+
if (parent === directory)
|
|
6715
|
+
throw new StandaloneDeletionJournalError("compromised");
|
|
6716
|
+
const before = await this.ensureStateDirectory(parent, false);
|
|
6717
|
+
let created = false;
|
|
6718
|
+
try {
|
|
6719
|
+
await fs.mkdir(directory, { mode: 448 });
|
|
6720
|
+
created = true;
|
|
6721
|
+
} catch (error2) {
|
|
6722
|
+
if (error2.code !== "EEXIST") throw error2;
|
|
6723
|
+
}
|
|
6724
|
+
if (created && process.platform !== "win32")
|
|
6725
|
+
await fs.chmod(directory, 448);
|
|
6726
|
+
const after = await this.inspectPrivateDirectory(parent, false);
|
|
6727
|
+
if (!sameDirectoryIdentity(before, after)) {
|
|
6728
|
+
throw new StandaloneDeletionJournalError("compromised");
|
|
6729
|
+
}
|
|
6730
|
+
const handle = await fs.open(parent, fsConstants2.O_RDONLY);
|
|
6731
|
+
try {
|
|
6732
|
+
if (process.platform !== "win32") await handle.sync();
|
|
6733
|
+
} finally {
|
|
6734
|
+
await handle.close();
|
|
6735
|
+
}
|
|
6736
|
+
return this.inspectPrivateDirectory(directory, requirePrivate);
|
|
6737
|
+
}
|
|
6738
|
+
async inspectStateParent() {
|
|
6739
|
+
await this.inspectPrivateDirectory(this.stableBaseDir, false);
|
|
6740
|
+
const canonical = await fs.realpath(this.stableBaseDir);
|
|
6741
|
+
if (this.canonicalBaseDir !== void 0 && this.canonicalBaseDir !== canonical) {
|
|
6742
|
+
throw new StandaloneDeletionJournalError("compromised");
|
|
6743
|
+
}
|
|
6744
|
+
this.canonicalBaseDir = canonical;
|
|
6745
|
+
await this.inspectPrivateDirectory(this.stateDirectory);
|
|
7160
6746
|
}
|
|
7161
6747
|
async inspectJournalDirectory() {
|
|
7162
6748
|
try {
|
|
6749
|
+
await this.inspectStateParent();
|
|
7163
6750
|
return await this.inspectPrivateDirectory(this.journalDirectory);
|
|
7164
6751
|
} catch (error2) {
|
|
7165
|
-
if (
|
|
6752
|
+
if (isMissing(error2)) return void 0;
|
|
7166
6753
|
throw error2;
|
|
7167
6754
|
}
|
|
7168
6755
|
}
|
|
7169
|
-
async inspectPrivateDirectory(directory) {
|
|
7170
|
-
|
|
7171
|
-
|
|
6756
|
+
async inspectPrivateDirectory(directory, requirePrivate = true) {
|
|
6757
|
+
let stat3;
|
|
6758
|
+
try {
|
|
6759
|
+
stat3 = await fs.lstat(directory);
|
|
6760
|
+
} catch (error2) {
|
|
6761
|
+
if (isMissing(error2) && this.directoryIdentities.has(directory)) {
|
|
6762
|
+
throw new StandaloneDeletionJournalError("compromised");
|
|
6763
|
+
}
|
|
6764
|
+
throw error2;
|
|
6765
|
+
}
|
|
6766
|
+
if (!stat3.isDirectory() || stat3.isSymbolicLink() || process.platform !== "win32" && (requirePrivate && (stat3.mode & 511) !== 448 || typeof process.getuid === "function" && stat3.uid !== process.getuid())) {
|
|
7172
6767
|
throw new StandaloneDeletionJournalError("compromised");
|
|
7173
6768
|
}
|
|
7174
|
-
|
|
6769
|
+
const identity = {
|
|
7175
6770
|
device: stat3.dev,
|
|
7176
6771
|
inode: normalizedInode(stat3.ino),
|
|
7177
6772
|
inodeVerifiable: hasVerifiableInode(stat3.ino)
|
|
7178
6773
|
};
|
|
6774
|
+
if (directory === this.stableBaseDir || directory === this.stateDirectory || directory === this.journalDirectory) {
|
|
6775
|
+
const expected = this.directoryIdentities.get(directory);
|
|
6776
|
+
if (expected && !sameDirectoryIdentity(identity, expected)) {
|
|
6777
|
+
throw new StandaloneDeletionJournalError("compromised");
|
|
6778
|
+
}
|
|
6779
|
+
this.directoryIdentities.set(directory, identity);
|
|
6780
|
+
}
|
|
6781
|
+
return identity;
|
|
7179
6782
|
}
|
|
7180
6783
|
async assertDirectoryIdentity(directory, expected) {
|
|
6784
|
+
await this.inspectStateParent();
|
|
7181
6785
|
const current = await this.inspectPrivateDirectory(directory);
|
|
7182
6786
|
if (!sameDirectoryIdentity(current, expected)) {
|
|
7183
6787
|
throw new StandaloneDeletionJournalError("compromised");
|
|
@@ -7190,35 +6794,35 @@ var StandaloneDeletionJournal = class {
|
|
|
7190
6794
|
}
|
|
7191
6795
|
async assertPathAbsent(filePath) {
|
|
7192
6796
|
try {
|
|
7193
|
-
await
|
|
6797
|
+
await fs.lstat(filePath);
|
|
7194
6798
|
} catch (error2) {
|
|
7195
|
-
if (
|
|
6799
|
+
if (isMissing(error2)) return;
|
|
7196
6800
|
throw error2;
|
|
7197
6801
|
}
|
|
7198
6802
|
throw new StandaloneDeletionJournalError("conflict");
|
|
7199
6803
|
}
|
|
7200
6804
|
async pathExists(filePath) {
|
|
7201
6805
|
try {
|
|
7202
|
-
await
|
|
6806
|
+
await fs.lstat(filePath);
|
|
7203
6807
|
return true;
|
|
7204
6808
|
} catch (error2) {
|
|
7205
|
-
if (
|
|
6809
|
+
if (isMissing(error2)) return false;
|
|
7206
6810
|
throw error2;
|
|
7207
6811
|
}
|
|
7208
6812
|
}
|
|
7209
6813
|
async unlinkIfExists(filePath) {
|
|
7210
6814
|
try {
|
|
7211
|
-
await
|
|
6815
|
+
await fs.unlink(filePath);
|
|
7212
6816
|
} catch (error2) {
|
|
7213
|
-
if (!
|
|
6817
|
+
if (!isMissing(error2)) throw error2;
|
|
7214
6818
|
}
|
|
7215
6819
|
}
|
|
7216
6820
|
async openDurableDirectory(directory, expected) {
|
|
7217
6821
|
let handle;
|
|
7218
6822
|
try {
|
|
7219
|
-
handle = await
|
|
6823
|
+
handle = await fs.open(
|
|
7220
6824
|
directory,
|
|
7221
|
-
|
|
6825
|
+
fsConstants2.O_RDONLY | (process.platform === "win32" ? 0 : fsConstants2.O_NOFOLLOW ?? 0)
|
|
7222
6826
|
);
|
|
7223
6827
|
const opened = await handle.stat();
|
|
7224
6828
|
const openedIdentity = {
|
|
@@ -7375,6 +6979,7 @@ function mergeLiveStandaloneSummary(persisted, live) {
|
|
|
7375
6979
|
updatedAt: laterTimestamp(live.updatedAt, persisted.updatedAt),
|
|
7376
6980
|
clientCount: live.clientCount,
|
|
7377
6981
|
hasActivePrompt: live.hasActivePrompt,
|
|
6982
|
+
...live.activeWorkState !== void 0 ? { activeWorkState: live.activeWorkState } : {},
|
|
7378
6983
|
...live.isWaitingForPermission !== void 0 ? { isWaitingForPermission: live.isWaitingForPermission } : {},
|
|
7379
6984
|
...live.isWaitingForUserQuestion !== void 0 ? { isWaitingForUserQuestion: live.isWaitingForUserQuestion } : {},
|
|
7380
6985
|
...live.pendingInteractionCount !== void 0 ? { pendingInteractionCount: live.pendingInteractionCount } : {},
|
|
@@ -7586,7 +7191,7 @@ var StandaloneSessionService = class {
|
|
|
7586
7191
|
});
|
|
7587
7192
|
}
|
|
7588
7193
|
async repairDirectory(rawSessionId) {
|
|
7589
|
-
const clientId =
|
|
7194
|
+
const clientId = randomUUID4();
|
|
7590
7195
|
const restored = await this.restore("resume", rawSessionId, { clientId });
|
|
7591
7196
|
try {
|
|
7592
7197
|
await this.cleanupDisconnectedRestore(restored);
|
|
@@ -9058,7 +8663,7 @@ var StandaloneSessionService = class {
|
|
|
9058
8663
|
}
|
|
9059
8664
|
return { ...created, initialPrompt: created.initialPrompt };
|
|
9060
8665
|
}
|
|
9061
|
-
async createInternal(request2, prompt, parentSessionId, promptId =
|
|
8666
|
+
async createInternal(request2, prompt, parentSessionId, promptId = randomUUID4()) {
|
|
9062
8667
|
const { sessionId } = parseRequiredSessionId(request2.sessionId);
|
|
9063
8668
|
let entry;
|
|
9064
8669
|
try {
|
|
@@ -9601,8 +9206,8 @@ var StandaloneSessionService = class {
|
|
|
9601
9206
|
|
|
9602
9207
|
// packages/cli/src/serve/workspace-memory.ts
|
|
9603
9208
|
init_esbuild_shims();
|
|
9604
|
-
import { promises as
|
|
9605
|
-
import * as
|
|
9209
|
+
import { promises as fs2 } from "node:fs";
|
|
9210
|
+
import * as path8 from "node:path";
|
|
9606
9211
|
function requireTrustedWorkspace2(deps, res) {
|
|
9607
9212
|
if (deps.isWorkspaceTrusted?.() !== false) return true;
|
|
9608
9213
|
res.status(403).json({
|
|
@@ -9925,9 +9530,9 @@ async function collectWorkspaceMemoryStatus(boundWorkspace) {
|
|
|
9925
9530
|
files.push(...workspaceFiles);
|
|
9926
9531
|
const globalDir = Storage.getGlobalQwenDir();
|
|
9927
9532
|
for (const filename of filenames) {
|
|
9928
|
-
const candidate =
|
|
9533
|
+
const candidate = path8.join(globalDir, filename);
|
|
9929
9534
|
try {
|
|
9930
|
-
const stat3 = await
|
|
9535
|
+
const stat3 = await fs2.stat(candidate);
|
|
9931
9536
|
if (stat3.isFile()) {
|
|
9932
9537
|
files.push({
|
|
9933
9538
|
absolutePath: candidate,
|
|
@@ -9974,9 +9579,9 @@ __name(collectWorkspaceMemoryStatus, "collectWorkspaceMemoryStatus");
|
|
|
9974
9579
|
async function walkWorkspaceForMemory(start, filenames, errors) {
|
|
9975
9580
|
const out = [];
|
|
9976
9581
|
for (const filename of filenames) {
|
|
9977
|
-
const candidate =
|
|
9582
|
+
const candidate = path8.join(start, filename);
|
|
9978
9583
|
try {
|
|
9979
|
-
const stat3 = await
|
|
9584
|
+
const stat3 = await fs2.stat(candidate);
|
|
9980
9585
|
if (stat3.isFile()) {
|
|
9981
9586
|
out.push({
|
|
9982
9587
|
absolutePath: candidate,
|
|
@@ -10006,7 +9611,7 @@ __name(isEnoent, "isEnoent");
|
|
|
10006
9611
|
|
|
10007
9612
|
// packages/cli/src/serve/workspace-agents.ts
|
|
10008
9613
|
init_esbuild_shims();
|
|
10009
|
-
import { promises as
|
|
9614
|
+
import { promises as fs3 } from "node:fs";
|
|
10010
9615
|
import { isDeepStrictEqual } from "node:util";
|
|
10011
9616
|
var AGENT_TYPE_PATTERN = /^[\p{L}\p{N}_-]+$/u;
|
|
10012
9617
|
var AGENT_TYPE_MAX_LENGTH = 64;
|
|
@@ -10459,7 +10064,7 @@ function mountWorkspaceAgentsRoutes(app, deps) {
|
|
|
10459
10064
|
continue;
|
|
10460
10065
|
}
|
|
10461
10066
|
try {
|
|
10462
|
-
await
|
|
10067
|
+
await fs3.access(found.filePath);
|
|
10463
10068
|
remaining.push(found);
|
|
10464
10069
|
} catch {
|
|
10465
10070
|
removed.push(found);
|
|
@@ -10808,7 +10413,7 @@ function mountWorkspaceQualifiedAgentsRoutes(app, deps) {
|
|
|
10808
10413
|
}
|
|
10809
10414
|
if (existing?.filePath) {
|
|
10810
10415
|
try {
|
|
10811
|
-
await
|
|
10416
|
+
await fs3.access(existing.filePath);
|
|
10812
10417
|
writeStderrLine(
|
|
10813
10418
|
`qwen serve: DELETE /workspaces/:workspace/agents/${safeLogValue(agentType)} partial \u2014 remaining=${existing.level}:${existing.filePath}`
|
|
10814
10419
|
);
|
|
@@ -13383,6 +12988,7 @@ var AcpDispatcher = class {
|
|
|
13383
12988
|
...s.sourceId !== void 0 ? { sourceId: s.sourceId } : {},
|
|
13384
12989
|
clientCount: s.clientCount,
|
|
13385
12990
|
hasActivePrompt: s.hasActivePrompt,
|
|
12991
|
+
...s.activeWorkState !== void 0 ? { activeWorkState: s.activeWorkState } : {},
|
|
13386
12992
|
isArchived: s.isArchived === true,
|
|
13387
12993
|
...s.isPinned !== void 0 ? { isPinned: s.isPinned } : {},
|
|
13388
12994
|
...s.pinnedAt !== void 0 ? { pinnedAt: s.pinnedAt } : {},
|
|
@@ -15704,6 +15310,7 @@ var AcpDispatcher = class {
|
|
|
15704
15310
|
bridge: this.bridge,
|
|
15705
15311
|
coordinator: this.archiveCoordinator,
|
|
15706
15312
|
assertCanMutate: assertGenerationOpen,
|
|
15313
|
+
runtimeWorkspaceCwd: this.boundWorkspace,
|
|
15707
15314
|
onError: /* @__PURE__ */ __name(({ phase, sessionId, error: error2 }) => {
|
|
15708
15315
|
const safeSessionId = logSafe(sessionId.slice(0, 8));
|
|
15709
15316
|
const safeMessage = logSafe(error2);
|
|
@@ -16382,7 +15989,7 @@ var AcpDispatcher = class {
|
|
|
16382
15989
|
|
|
16383
15990
|
// packages/cli/src/serve/acp-http/connection-registry.ts
|
|
16384
15991
|
init_esbuild_shims();
|
|
16385
|
-
import { randomUUID as
|
|
15992
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
16386
15993
|
var DEFAULT_MAX_CONNECTIONS = 64;
|
|
16387
15994
|
var AcpConnection = class {
|
|
16388
15995
|
constructor(connectionId, fromLoopback, onAbandonPending, onDetachSession, preAttachBudget = new AcpPreAttachBudget(), onFatalConnection, maxFramesPerConnection = ACP_PRE_ATTACH_MAX_FRAMES_PER_CONNECTION, maxPayloadBytesPerConnection = ACP_PRE_ATTACH_MAX_PAYLOAD_BYTES_PER_CONNECTION, onPreAttachGuardFailure) {
|
|
@@ -16393,8 +16000,8 @@ var AcpConnection = class {
|
|
|
16393
16000
|
this.maxFramesPerConnection = maxFramesPerConnection;
|
|
16394
16001
|
this.maxPayloadBytesPerConnection = maxPayloadBytesPerConnection;
|
|
16395
16002
|
this.onPreAttachGuardFailure = onPreAttachGuardFailure;
|
|
16396
|
-
this.connectionId = connectionId ??
|
|
16397
|
-
this.clientId =
|
|
16003
|
+
this.connectionId = connectionId ?? randomUUID5();
|
|
16004
|
+
this.clientId = randomUUID5();
|
|
16398
16005
|
this.fromLoopback = fromLoopback;
|
|
16399
16006
|
}
|
|
16400
16007
|
static {
|
|
@@ -18445,6 +18052,23 @@ var CdpBrowserEmulator = class {
|
|
|
18445
18052
|
});
|
|
18446
18053
|
case "Target.getDevToolsTarget":
|
|
18447
18054
|
return this.cb.reply({ id, result: {} });
|
|
18055
|
+
// Target mutations the tunnel cannot perform: behind it is ONE tab the
|
|
18056
|
+
// user already has open, so there is nothing to create, close, or
|
|
18057
|
+
// isolate. These must not fall through to the empty ack below — a CDP
|
|
18058
|
+
// client reads `targetId` out of the createTarget result and then waits
|
|
18059
|
+
// for a target that never appears, so a fake success turns "open a new
|
|
18060
|
+
// page" into a protocol timeout instead of an immediate refusal.
|
|
18061
|
+
case "Target.createTarget":
|
|
18062
|
+
case "Target.closeTarget":
|
|
18063
|
+
case "Target.createBrowserContext":
|
|
18064
|
+
case "Target.disposeBrowserContext":
|
|
18065
|
+
return this.cb.reply({
|
|
18066
|
+
id,
|
|
18067
|
+
error: {
|
|
18068
|
+
code: SERVER_ERROR,
|
|
18069
|
+
message: `${method} is not supported by the CDP tunnel: it drives a single existing tab`
|
|
18070
|
+
}
|
|
18071
|
+
});
|
|
18448
18072
|
case "Target.attachToTarget": {
|
|
18449
18073
|
const targetId = params?.["targetId"];
|
|
18450
18074
|
if (targetId !== PAGE_TARGET_ID) {
|
|
@@ -18804,10 +18428,10 @@ function isAcpChannelUnavailable(err) {
|
|
|
18804
18428
|
return err?.data?.errorKind === "acp_channel_unavailable";
|
|
18805
18429
|
}
|
|
18806
18430
|
__name(isAcpChannelUnavailable, "isAcpChannelUnavailable");
|
|
18807
|
-
function
|
|
18431
|
+
function delay(ms) {
|
|
18808
18432
|
return new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
18809
18433
|
}
|
|
18810
|
-
__name(
|
|
18434
|
+
__name(delay, "delay");
|
|
18811
18435
|
function buildChromeDevToolsMcpRuntimeConfig(localPort, hostname, env) {
|
|
18812
18436
|
if (localPort === void 0 || !Number.isInteger(localPort) || localPort <= 0) {
|
|
18813
18437
|
return void 0;
|
|
@@ -19068,7 +18692,7 @@ function mountAcpHttp(app, bridge, opts) {
|
|
|
19068
18692
|
if (!isAcpChannelUnavailable(err) || attempt >= RUNTIME_MCP_RETRY_ATTEMPTS || !opts.cdpTunnelRegistry?.hasActive()) {
|
|
19069
18693
|
throw err;
|
|
19070
18694
|
}
|
|
19071
|
-
await
|
|
18695
|
+
await delay(RUNTIME_MCP_RETRY_DELAY_MS);
|
|
19072
18696
|
}
|
|
19073
18697
|
}
|
|
19074
18698
|
if (result.skipped) {
|
|
@@ -22061,9 +21685,9 @@ __name(registerWorkspaceAuthRoutes, "registerWorkspaceAuthRoutes");
|
|
|
22061
21685
|
// packages/cli/src/serve/routes/workspace-extensions.ts
|
|
22062
21686
|
init_esbuild_shims();
|
|
22063
21687
|
import * as crypto2 from "node:crypto";
|
|
22064
|
-
import * as
|
|
21688
|
+
import * as fs4 from "node:fs/promises";
|
|
22065
21689
|
import * as os from "node:os";
|
|
22066
|
-
import * as
|
|
21690
|
+
import * as path9 from "node:path";
|
|
22067
21691
|
var import_express2 = __toESM(require_express(), 1);
|
|
22068
21692
|
|
|
22069
21693
|
// packages/cli/src/serve/extension-operation-scheduler.ts
|
|
@@ -22431,14 +22055,18 @@ function createExtensionsController(deps) {
|
|
|
22431
22055
|
async (release) => {
|
|
22432
22056
|
assertGenerationOpen?.();
|
|
22433
22057
|
return await task((generation) => {
|
|
22434
|
-
|
|
22058
|
+
if (!options.skipRefresh) {
|
|
22059
|
+
reconciliationReservation ??= options.reserveRuntimeReconciliation?.();
|
|
22060
|
+
}
|
|
22435
22061
|
committedGeneration = generation;
|
|
22436
22062
|
release();
|
|
22437
22063
|
});
|
|
22438
22064
|
}
|
|
22439
22065
|
);
|
|
22440
22066
|
if (committedGeneration === void 0) {
|
|
22441
|
-
|
|
22067
|
+
if (!options.skipRefresh) {
|
|
22068
|
+
reconciliationReservation ??= options.reserveRuntimeReconciliation?.();
|
|
22069
|
+
}
|
|
22442
22070
|
committedGeneration = result.generation;
|
|
22443
22071
|
}
|
|
22444
22072
|
for (const warning of result.warnings ?? []) {
|
|
@@ -22846,7 +22474,7 @@ var extensionArchiveBodyParser = import_express2.default.raw({
|
|
|
22846
22474
|
});
|
|
22847
22475
|
var assertDaemonExtensionInstallSource = /* @__PURE__ */ __name((installMetadata, source, ref, autoUpdate) => {
|
|
22848
22476
|
if (installMetadata.type === "local") {
|
|
22849
|
-
if (!
|
|
22477
|
+
if (!path9.isAbsolute(source)) {
|
|
22850
22478
|
throw new Error(
|
|
22851
22479
|
"Local extension sources must be absolute daemon-host paths; relative paths are not supported over the daemon endpoint."
|
|
22852
22480
|
);
|
|
@@ -23302,11 +22930,6 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
23302
22930
|
reserveRuntimeReconciliation,
|
|
23303
22931
|
onRuntimeReconciled
|
|
23304
22932
|
} : {}, "globalReconciliationOptions");
|
|
23305
|
-
const workspaceReconciliationOptions = /* @__PURE__ */ __name(() => workspaceRegistry ? {
|
|
23306
|
-
refreshRuntimes: [workspaceRegistry.primary],
|
|
23307
|
-
reserveRuntimeReconciliation,
|
|
23308
|
-
onRuntimeReconciled
|
|
23309
|
-
} : {}, "workspaceReconciliationOptions");
|
|
23310
22933
|
const mutationClientBridges = /* @__PURE__ */ __name((runtimes) => (typeof runtimes === "function" ? runtimes() : runtimes ?? workspaceRegistry?.listAll())?.map((runtime) => runtime.bridge) ?? [bridge], "mutationClientBridges");
|
|
23311
22934
|
if (workspaceRegistry) {
|
|
23312
22935
|
let observedGeneration;
|
|
@@ -23558,14 +23181,14 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
23558
23181
|
let result;
|
|
23559
23182
|
let failure;
|
|
23560
23183
|
try {
|
|
23561
|
-
uploadDir = await
|
|
23562
|
-
|
|
23184
|
+
uploadDir = await fs4.mkdtemp(
|
|
23185
|
+
path9.join(os.tmpdir(), "qwen-extension-upload-")
|
|
23563
23186
|
);
|
|
23564
|
-
const archivePath =
|
|
23187
|
+
const archivePath = path9.join(
|
|
23565
23188
|
uploadDir,
|
|
23566
23189
|
`extension${archiveName.suffix}`
|
|
23567
23190
|
);
|
|
23568
|
-
await
|
|
23191
|
+
await fs4.writeFile(archivePath, archive);
|
|
23569
23192
|
archive = void 0;
|
|
23570
23193
|
const prepared = await context.prepare(async (signal) => {
|
|
23571
23194
|
supersedeActiveInstallOperations(ctrl, operationId);
|
|
@@ -23598,7 +23221,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
23598
23221
|
}
|
|
23599
23222
|
if (uploadDir) {
|
|
23600
23223
|
try {
|
|
23601
|
-
await
|
|
23224
|
+
await fs4.rm(uploadDir, { recursive: true, force: true });
|
|
23602
23225
|
} catch (error2) {
|
|
23603
23226
|
failure ??= sanitizeUploadError(error2);
|
|
23604
23227
|
}
|
|
@@ -23962,7 +23585,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
23962
23585
|
return { status: "enabled", name: extension.name };
|
|
23963
23586
|
},
|
|
23964
23587
|
{
|
|
23965
|
-
|
|
23588
|
+
skipRefresh: true
|
|
23966
23589
|
}
|
|
23967
23590
|
);
|
|
23968
23591
|
} catch (err) {
|
|
@@ -24009,7 +23632,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
24009
23632
|
return { status: "disabled", name: extension.name };
|
|
24010
23633
|
},
|
|
24011
23634
|
{
|
|
24012
|
-
|
|
23635
|
+
skipRefresh: true
|
|
24013
23636
|
}
|
|
24014
23637
|
);
|
|
24015
23638
|
} catch (err) {
|
|
@@ -24298,6 +23921,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
24298
23921
|
};
|
|
24299
23922
|
},
|
|
24300
23923
|
{
|
|
23924
|
+
skipRefresh: true,
|
|
24301
23925
|
...workspaceRegistry ? { refreshRuntimes: /* @__PURE__ */ __name(() => workspaceRegistry.listAll(), "refreshRuntimes") } : {}
|
|
24302
23926
|
}
|
|
24303
23927
|
);
|
|
@@ -24338,6 +23962,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
24338
23962
|
};
|
|
24339
23963
|
},
|
|
24340
23964
|
{
|
|
23965
|
+
skipRefresh: true,
|
|
24341
23966
|
...workspaceRegistry ? { refreshRuntimes: /* @__PURE__ */ __name(() => workspaceRegistry.listAll(), "refreshRuntimes") } : {}
|
|
24342
23967
|
}
|
|
24343
23968
|
);
|
|
@@ -24858,6 +24483,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
24858
24483
|
};
|
|
24859
24484
|
},
|
|
24860
24485
|
{
|
|
24486
|
+
skipRefresh: true,
|
|
24861
24487
|
refreshRuntimes: [runtime],
|
|
24862
24488
|
assertGenerationOpen: /* @__PURE__ */ __name(() => runtime.generationGuard?.assertOpen(), "assertGenerationOpen")
|
|
24863
24489
|
}
|
|
@@ -24904,6 +24530,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
24904
24530
|
};
|
|
24905
24531
|
},
|
|
24906
24532
|
{
|
|
24533
|
+
skipRefresh: true,
|
|
24907
24534
|
refreshRuntimes: [runtime],
|
|
24908
24535
|
assertGenerationOpen: /* @__PURE__ */ __name(() => runtime.generationGuard?.assertOpen(), "assertGenerationOpen")
|
|
24909
24536
|
}
|
|
@@ -24949,6 +24576,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
24949
24576
|
return { status: activation.effective, name: extension.name };
|
|
24950
24577
|
},
|
|
24951
24578
|
{
|
|
24579
|
+
skipRefresh: true,
|
|
24952
24580
|
refreshRuntimes: [runtime],
|
|
24953
24581
|
assertGenerationOpen: /* @__PURE__ */ __name(() => runtime.generationGuard?.assertOpen(), "assertGenerationOpen")
|
|
24954
24582
|
}
|
|
@@ -24987,7 +24615,7 @@ __name(registerWorkspaceExtensionRoutes, "registerWorkspaceExtensionRoutes");
|
|
|
24987
24615
|
// packages/cli/src/serve/routes/workspace-file-write.ts
|
|
24988
24616
|
init_esbuild_shims();
|
|
24989
24617
|
var import_express3 = __toESM(require_express(), 1);
|
|
24990
|
-
import * as
|
|
24618
|
+
import * as path10 from "node:path";
|
|
24991
24619
|
function getFsFactory3(req, res) {
|
|
24992
24620
|
const context = getWorkspaceRouteContext(req);
|
|
24993
24621
|
if (context) return context.runtime.routeFileSystemFactory;
|
|
@@ -25420,8 +25048,8 @@ function fileUploadAdmission(deps, opts) {
|
|
|
25420
25048
|
sendParseError(res, ROUTE2, "`path` query parameter is required");
|
|
25421
25049
|
return;
|
|
25422
25050
|
}
|
|
25423
|
-
const dir =
|
|
25424
|
-
const basename9 =
|
|
25051
|
+
const dir = path10.dirname(queryPath);
|
|
25052
|
+
const basename9 = path10.basename(queryPath);
|
|
25425
25053
|
if (queryPath.endsWith("/") || basename9.length === 0 || basename9 === "." || basename9 === "..") {
|
|
25426
25054
|
sendParseError(res, ROUTE2, "`path` must name a file");
|
|
25427
25055
|
return;
|
|
@@ -25542,11 +25170,11 @@ async function handlePostFileUpload(req, res) {
|
|
|
25542
25170
|
);
|
|
25543
25171
|
return;
|
|
25544
25172
|
}
|
|
25545
|
-
const candidateAbs =
|
|
25173
|
+
const candidateAbs = path10.join(resolvedDir, candidateBasename);
|
|
25546
25174
|
let resolved;
|
|
25547
25175
|
try {
|
|
25548
25176
|
resolved = await fs10.resolve(
|
|
25549
|
-
|
|
25177
|
+
path10.join(queryDir, candidateBasename),
|
|
25550
25178
|
"write"
|
|
25551
25179
|
);
|
|
25552
25180
|
} catch (err) {
|
|
@@ -25901,6 +25529,12 @@ var legacySessionTelemetryRoutes = [
|
|
|
25901
25529
|
attribution: "handler_resolved",
|
|
25902
25530
|
route: "POST /session/:id/resume"
|
|
25903
25531
|
},
|
|
25532
|
+
{
|
|
25533
|
+
method: "POST",
|
|
25534
|
+
path: "/session/:id/worktree-reset",
|
|
25535
|
+
attribution: "handler_resolved",
|
|
25536
|
+
route: "POST /session/:id/worktree-reset"
|
|
25537
|
+
},
|
|
25904
25538
|
{
|
|
25905
25539
|
method: "POST",
|
|
25906
25540
|
path: "/session/:id/branch",
|
|
@@ -26876,11 +26510,92 @@ __name(registerPermissionRoutes, "registerPermissionRoutes");
|
|
|
26876
26510
|
// packages/cli/src/serve/routes/session.ts
|
|
26877
26511
|
init_esbuild_shims();
|
|
26878
26512
|
import * as crypto3 from "node:crypto";
|
|
26879
|
-
import * as
|
|
26880
|
-
import * as
|
|
26513
|
+
import * as fs6 from "node:fs";
|
|
26514
|
+
import * as path11 from "node:path";
|
|
26881
26515
|
import { inspect } from "node:util";
|
|
26882
26516
|
var import_express4 = __toESM(require_express(), 1);
|
|
26883
26517
|
|
|
26518
|
+
// packages/cli/src/serve/server/worktree-reset-errors.ts
|
|
26519
|
+
init_esbuild_shims();
|
|
26520
|
+
var WorktreeSessionSupersededError = class extends Error {
|
|
26521
|
+
static {
|
|
26522
|
+
__name(this, "WorktreeSessionSupersededError");
|
|
26523
|
+
}
|
|
26524
|
+
sessionId;
|
|
26525
|
+
replacementSessionId;
|
|
26526
|
+
constructor(sessionId, replacementSessionId) {
|
|
26527
|
+
super(
|
|
26528
|
+
`Session ${sessionId} was superseded by a worktree reset; restore the replacement session instead`
|
|
26529
|
+
);
|
|
26530
|
+
this.name = "WorktreeSessionSupersededError";
|
|
26531
|
+
this.sessionId = sessionId;
|
|
26532
|
+
this.replacementSessionId = replacementSessionId;
|
|
26533
|
+
}
|
|
26534
|
+
};
|
|
26535
|
+
var WorktreeMarkerMissingError = class extends Error {
|
|
26536
|
+
static {
|
|
26537
|
+
__name(this, "WorktreeMarkerMissingError");
|
|
26538
|
+
}
|
|
26539
|
+
sessionId;
|
|
26540
|
+
constructor(sessionId) {
|
|
26541
|
+
super(
|
|
26542
|
+
`Worktree ownership marker for session ${sessionId} is missing; reset the task to recreate it`
|
|
26543
|
+
);
|
|
26544
|
+
this.name = "WorktreeMarkerMissingError";
|
|
26545
|
+
this.sessionId = sessionId;
|
|
26546
|
+
}
|
|
26547
|
+
};
|
|
26548
|
+
var WorktreeResetInterruptedError = class extends Error {
|
|
26549
|
+
static {
|
|
26550
|
+
__name(this, "WorktreeResetInterruptedError");
|
|
26551
|
+
}
|
|
26552
|
+
sessionId;
|
|
26553
|
+
constructor(sessionId) {
|
|
26554
|
+
super(
|
|
26555
|
+
"A previous worktree reset was interrupted; retry the reset against the superseded session to finish or roll it back"
|
|
26556
|
+
);
|
|
26557
|
+
this.name = "WorktreeResetInterruptedError";
|
|
26558
|
+
this.sessionId = sessionId;
|
|
26559
|
+
}
|
|
26560
|
+
};
|
|
26561
|
+
var WorktreeResetActiveError = class extends Error {
|
|
26562
|
+
static {
|
|
26563
|
+
__name(this, "WorktreeResetActiveError");
|
|
26564
|
+
}
|
|
26565
|
+
sessionId;
|
|
26566
|
+
constructor(sessionId) {
|
|
26567
|
+
super(
|
|
26568
|
+
`Session ${sessionId} has a prompt in progress; wait for it to finish before resetting`
|
|
26569
|
+
);
|
|
26570
|
+
this.name = "WorktreeResetActiveError";
|
|
26571
|
+
this.sessionId = sessionId;
|
|
26572
|
+
}
|
|
26573
|
+
};
|
|
26574
|
+
var WorktreeResetUnsupportedError = class extends Error {
|
|
26575
|
+
static {
|
|
26576
|
+
__name(this, "WorktreeResetUnsupportedError");
|
|
26577
|
+
}
|
|
26578
|
+
sessionId;
|
|
26579
|
+
constructor(sessionId) {
|
|
26580
|
+
super(`Session ${sessionId} is not a worktree session`);
|
|
26581
|
+
this.name = "WorktreeResetUnsupportedError";
|
|
26582
|
+
this.sessionId = sessionId;
|
|
26583
|
+
}
|
|
26584
|
+
};
|
|
26585
|
+
var WorktreeResetInvalidStateError = class extends Error {
|
|
26586
|
+
static {
|
|
26587
|
+
__name(this, "WorktreeResetInvalidStateError");
|
|
26588
|
+
}
|
|
26589
|
+
sessionId;
|
|
26590
|
+
constructor(sessionId) {
|
|
26591
|
+
super(
|
|
26592
|
+
`Session ${sessionId}'s worktree ownership state is invalid; the reset made no destructive change`
|
|
26593
|
+
);
|
|
26594
|
+
this.name = "WorktreeResetInvalidStateError";
|
|
26595
|
+
this.sessionId = sessionId;
|
|
26596
|
+
}
|
|
26597
|
+
};
|
|
26598
|
+
|
|
26884
26599
|
// packages/cli/src/serve/server/prompt-deadline.ts
|
|
26885
26600
|
init_esbuild_shims();
|
|
26886
26601
|
function resolvePromptDeadlineMs(serverMs, requestMs) {
|
|
@@ -27005,7 +26720,7 @@ __name(deleteBranch, "deleteBranch");
|
|
|
27005
26720
|
|
|
27006
26721
|
// packages/cli/src/serve/virtual-subagent-sessions.ts
|
|
27007
26722
|
init_esbuild_shims();
|
|
27008
|
-
import * as
|
|
26723
|
+
import * as fs5 from "node:fs/promises";
|
|
27009
26724
|
import { createReadStream } from "node:fs";
|
|
27010
26725
|
import readline from "node:readline";
|
|
27011
26726
|
var PREFIX = "subagent.";
|
|
@@ -27215,7 +26930,7 @@ var VirtualSubagentTarget = class _VirtualSubagentTarget {
|
|
|
27215
26930
|
async readNewRecords(endOffset) {
|
|
27216
26931
|
let handle;
|
|
27217
26932
|
try {
|
|
27218
|
-
handle = await
|
|
26933
|
+
handle = await fs5.open(this.task.outputFile, "r");
|
|
27219
26934
|
const stat3 = await handle.stat();
|
|
27220
26935
|
const identity = `${stat3.dev}:${stat3.ino}`;
|
|
27221
26936
|
if (this.transcriptIdentity !== void 0 && this.transcriptIdentity !== identity || stat3.size < this.offset) {
|
|
@@ -27259,7 +26974,7 @@ var VirtualSubagentTarget = class _VirtualSubagentTarget {
|
|
|
27259
26974
|
const filePath = `${this.task.outputFile}.stream`;
|
|
27260
26975
|
let handle;
|
|
27261
26976
|
try {
|
|
27262
|
-
handle = await
|
|
26977
|
+
handle = await fs5.open(filePath, "r");
|
|
27263
26978
|
const stat3 = await handle.stat();
|
|
27264
26979
|
const identity = `${stat3.dev}:${stat3.ino}`;
|
|
27265
26980
|
if (this.streamIdentity !== void 0 && this.streamIdentity !== identity) {
|
|
@@ -27424,7 +27139,7 @@ var VirtualSubagentTarget = class _VirtualSubagentTarget {
|
|
|
27424
27139
|
async captureReadBounds() {
|
|
27425
27140
|
const size = /* @__PURE__ */ __name(async (filePath) => {
|
|
27426
27141
|
try {
|
|
27427
|
-
return (await
|
|
27142
|
+
return (await fs5.stat(filePath)).size;
|
|
27428
27143
|
} catch (error2) {
|
|
27429
27144
|
if (error2.code === "ENOENT") return 0;
|
|
27430
27145
|
throw error2;
|
|
@@ -27553,7 +27268,7 @@ var VirtualSubagentSessions = class {
|
|
|
27553
27268
|
const sessionDir = getSubagentSessionDir(projectDir, parentSessionId);
|
|
27554
27269
|
let names;
|
|
27555
27270
|
try {
|
|
27556
|
-
names = await
|
|
27271
|
+
names = await fs5.readdir(sessionDir);
|
|
27557
27272
|
} catch (error2) {
|
|
27558
27273
|
if (error2.code === "ENOENT") return void 0;
|
|
27559
27274
|
throw error2;
|
|
@@ -27609,7 +27324,7 @@ var VirtualSubagentSessions = class {
|
|
|
27609
27324
|
const sessionDir = getSubagentSessionDir(projectDir, parentSessionId);
|
|
27610
27325
|
let names;
|
|
27611
27326
|
try {
|
|
27612
|
-
names = await
|
|
27327
|
+
names = await fs5.readdir(sessionDir);
|
|
27613
27328
|
} catch (error2) {
|
|
27614
27329
|
if (error2.code === "ENOENT") return void 0;
|
|
27615
27330
|
throw error2;
|
|
@@ -28134,34 +27849,6 @@ function registerSessionRoutes(app, deps) {
|
|
|
28134
27849
|
const LANGUAGE_CODES = deps.languageCodes;
|
|
28135
27850
|
const transcriptCursorMasterKey = crypto3.randomBytes(32);
|
|
28136
27851
|
const transcriptCursorCodecs = /* @__PURE__ */ new Map();
|
|
28137
|
-
const worktreeRestoreTails = /* @__PURE__ */ new WeakMap();
|
|
28138
|
-
const acquireWorktreeRestore = /* @__PURE__ */ __name(async (bridge, sessionId) => {
|
|
28139
|
-
let tails = worktreeRestoreTails.get(bridge);
|
|
28140
|
-
if (!tails) {
|
|
28141
|
-
tails = /* @__PURE__ */ new Map();
|
|
28142
|
-
worktreeRestoreTails.set(bridge, tails);
|
|
28143
|
-
}
|
|
28144
|
-
const key = normalizeSessionIdForLookup(sessionId);
|
|
28145
|
-
const previous = tails.get(key);
|
|
28146
|
-
let releaseGate;
|
|
28147
|
-
const gate = new Promise((resolve7) => {
|
|
28148
|
-
releaseGate = resolve7;
|
|
28149
|
-
});
|
|
28150
|
-
const tail = (previous ?? Promise.resolve()).then(() => gate);
|
|
28151
|
-
tails.set(key, tail);
|
|
28152
|
-
if (previous) {
|
|
28153
|
-
await previous;
|
|
28154
|
-
}
|
|
28155
|
-
let released = false;
|
|
28156
|
-
return () => {
|
|
28157
|
-
if (released) return;
|
|
28158
|
-
released = true;
|
|
28159
|
-
releaseGate();
|
|
28160
|
-
if (tails.get(key) === tail) {
|
|
28161
|
-
tails.delete(key);
|
|
28162
|
-
}
|
|
28163
|
-
};
|
|
28164
|
-
}, "acquireWorktreeRestore");
|
|
28165
27852
|
const activeBranchSessions = /* @__PURE__ */ new Map();
|
|
28166
27853
|
const inFlightBranchWorkspaces = /* @__PURE__ */ new Set();
|
|
28167
27854
|
const clearBranchSessionEntry = /* @__PURE__ */ __name((sessionId) => {
|
|
@@ -28270,28 +27957,28 @@ function registerSessionRoutes(app, deps) {
|
|
|
28270
27957
|
const cwd = parseOptionalWorkspaceCwd(body, boundWorkspace, res);
|
|
28271
27958
|
if (cwd === void 0) return void 0;
|
|
28272
27959
|
const isWithinConversationRoot = /* @__PURE__ */ __name((root, candidate) => {
|
|
28273
|
-
const relative5 =
|
|
28274
|
-
return relative5 === "" || relative5 !== ".." && !relative5.startsWith(`..${
|
|
27960
|
+
const relative5 = path11.relative(root, candidate);
|
|
27961
|
+
return relative5 === "" || relative5 !== ".." && !relative5.startsWith(`..${path11.sep}`) && !path11.isAbsolute(relative5);
|
|
28275
27962
|
}, "isWithinConversationRoot");
|
|
28276
27963
|
const canonicalizeIfPresent = /* @__PURE__ */ __name((candidate) => {
|
|
28277
|
-
const resolved =
|
|
27964
|
+
const resolved = path11.resolve(candidate);
|
|
28278
27965
|
try {
|
|
28279
|
-
return
|
|
27966
|
+
return fs6.realpathSync.native(resolved);
|
|
28280
27967
|
} catch {
|
|
28281
27968
|
return resolved;
|
|
28282
27969
|
}
|
|
28283
27970
|
}, "canonicalizeIfPresent");
|
|
28284
27971
|
const canonicalizeExistingAncestor = /* @__PURE__ */ __name((candidate) => {
|
|
28285
|
-
let ancestor =
|
|
27972
|
+
let ancestor = path11.resolve(candidate);
|
|
28286
27973
|
const missingTail = [];
|
|
28287
27974
|
while (true) {
|
|
28288
27975
|
try {
|
|
28289
|
-
return
|
|
27976
|
+
return path11.join(fs6.realpathSync.native(ancestor), ...missingTail);
|
|
28290
27977
|
} catch (error2) {
|
|
28291
27978
|
if (error2.code !== "ENOENT") throw error2;
|
|
28292
|
-
const parent =
|
|
27979
|
+
const parent = path11.dirname(ancestor);
|
|
28293
27980
|
if (parent === ancestor) throw error2;
|
|
28294
|
-
missingTail.unshift(
|
|
27981
|
+
missingTail.unshift(path11.basename(ancestor));
|
|
28295
27982
|
ancestor = parent;
|
|
28296
27983
|
}
|
|
28297
27984
|
}
|
|
@@ -28304,8 +27991,8 @@ function registerSessionRoutes(app, deps) {
|
|
|
28304
27991
|
return void 0;
|
|
28305
27992
|
}, "rejectReservedConversationRoot");
|
|
28306
27993
|
if ("cwd" in body && deps.liveConversationRootPath && isWithinConversationRoot(
|
|
28307
|
-
|
|
28308
|
-
|
|
27994
|
+
path11.resolve(deps.liveConversationRootPath),
|
|
27995
|
+
path11.resolve(cwd)
|
|
28309
27996
|
)) {
|
|
28310
27997
|
return rejectReservedConversationRoot();
|
|
28311
27998
|
}
|
|
@@ -28328,7 +28015,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
28328
28015
|
const liveRoots = [
|
|
28329
28016
|
...workspaceRegistry.listAllEntries().filter((entry2) => entry2.internal).map((entry2) => entry2.workspaceCwd),
|
|
28330
28017
|
...deps.liveConversationRootPath ? [
|
|
28331
|
-
|
|
28018
|
+
path11.resolve(deps.liveConversationRootPath),
|
|
28332
28019
|
canonicalizeIfPresent(deps.liveConversationRootPath)
|
|
28333
28020
|
] : []
|
|
28334
28021
|
];
|
|
@@ -28378,7 +28065,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
28378
28065
|
const workspaceParam = req.params[paramName] ?? "";
|
|
28379
28066
|
const byId = workspaceRegistry.getByWorkspaceId(workspaceParam);
|
|
28380
28067
|
if (byId) return byId;
|
|
28381
|
-
if (!
|
|
28068
|
+
if (!path11.isAbsolute(workspaceParam)) {
|
|
28382
28069
|
res.status(400).json({
|
|
28383
28070
|
error: `\`:${paramName}\` must decode to a workspace id or absolute path`
|
|
28384
28071
|
});
|
|
@@ -28431,11 +28118,11 @@ function registerSessionRoutes(app, deps) {
|
|
|
28431
28118
|
}
|
|
28432
28119
|
const selector = req.params[paramName] ?? "";
|
|
28433
28120
|
let entry = workspaceRegistry.getManagedEntryByWorkspaceId(selector);
|
|
28434
|
-
if (!entry &&
|
|
28121
|
+
if (!entry && path11.isAbsolute(selector)) {
|
|
28435
28122
|
entry = workspaceRegistry.getManagedEntryByWorkspaceCwd(selector);
|
|
28436
28123
|
}
|
|
28437
|
-
const configuredRoot = deps.liveConversationRootPath ?
|
|
28438
|
-
const matchesConfiguredRoot = configuredRoot !== void 0 && selector === configuredRoot &&
|
|
28124
|
+
const configuredRoot = deps.liveConversationRootPath ? path11.resolve(deps.liveConversationRootPath) : void 0;
|
|
28125
|
+
const matchesConfiguredRoot = configuredRoot !== void 0 && selector === configuredRoot && path11.resolve(selector) === selector;
|
|
28439
28126
|
if ((!entry || !entry.internal) && !matchesConfiguredRoot) {
|
|
28440
28127
|
return void 0;
|
|
28441
28128
|
}
|
|
@@ -28464,7 +28151,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
28464
28151
|
}, "resolveLiveCatalogRuntime");
|
|
28465
28152
|
const resolveQualifiedSessionTarget = /* @__PURE__ */ __name((req, res, options = {}) => {
|
|
28466
28153
|
const selector = req.params["workspace"] ?? "";
|
|
28467
|
-
const entry = workspaceRegistry.getManagedEntryByWorkspaceId(selector) ?? (
|
|
28154
|
+
const entry = workspaceRegistry.getManagedEntryByWorkspaceId(selector) ?? (path11.isAbsolute(selector) ? workspaceRegistry.getManagedEntryByWorkspaceCwd(selector) : void 0);
|
|
28468
28155
|
if (entry?.internal) return { kind: "internal", entry };
|
|
28469
28156
|
const runtime = resolveWorkspaceRuntimeFromParam(
|
|
28470
28157
|
workspaceRegistry,
|
|
@@ -28741,8 +28428,8 @@ function registerSessionRoutes(app, deps) {
|
|
|
28741
28428
|
const resolveRuntimeForSessionRestore = /* @__PURE__ */ __name(async (body, res, route, sessionId) => {
|
|
28742
28429
|
const cwd = parseOptionalWorkspaceCwd(body, boundWorkspace, res);
|
|
28743
28430
|
if (cwd === void 0) return void 0;
|
|
28744
|
-
const configuredRoot = deps.liveConversationRootPath ?
|
|
28745
|
-
const bootstrappedRuntime = "cwd" in body && configuredRoot !== void 0 &&
|
|
28431
|
+
const configuredRoot = deps.liveConversationRootPath ? path11.resolve(deps.liveConversationRootPath) : void 0;
|
|
28432
|
+
const bootstrappedRuntime = "cwd" in body && configuredRoot !== void 0 && path11.isAbsolute(cwd) && path11.resolve(cwd) === configuredRoot && deps.ensureConversationRuntime ? await deps.ensureConversationRuntime() : void 0;
|
|
28746
28433
|
let key;
|
|
28747
28434
|
try {
|
|
28748
28435
|
key = canonicalizeWorkspace(cwd);
|
|
@@ -29451,6 +29138,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
29451
29138
|
coordinator: archiveCoordinator,
|
|
29452
29139
|
coordinatorLockHeld,
|
|
29453
29140
|
assertCanMutate,
|
|
29141
|
+
runtimeWorkspaceCwd: runtime.workspaceCwd,
|
|
29454
29142
|
onError: /* @__PURE__ */ __name(({ phase, sessionId, error: error2 }) => {
|
|
29455
29143
|
writeStderrLine(
|
|
29456
29144
|
`qwen serve: ${phase}Session failed for ${safeLogValue(sessionId)}: ${safeLogValue(error2)}`
|
|
@@ -29901,7 +29589,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
29901
29589
|
} catch (error2) {
|
|
29902
29590
|
if (!session.attached) {
|
|
29903
29591
|
try {
|
|
29904
|
-
|
|
29592
|
+
await runWithWorkspaceRuntimeStorage(
|
|
29905
29593
|
runtime,
|
|
29906
29594
|
() => deleteDaemonSessionIfOrphan({
|
|
29907
29595
|
sessionId: session.sessionId,
|
|
@@ -29910,18 +29598,25 @@ function registerSessionRoutes(app, deps) {
|
|
|
29910
29598
|
coordinator: archiveCoordinator
|
|
29911
29599
|
})
|
|
29912
29600
|
);
|
|
29913
|
-
if (removed) {
|
|
29914
|
-
if (worktreeMeta) {
|
|
29915
|
-
await new GitWorktreeService(workspaceCwd).removeUserWorktree(worktreeMeta.slug, { deleteBranch: true }).catch(() => {
|
|
29916
|
-
});
|
|
29917
|
-
}
|
|
29918
|
-
}
|
|
29919
29601
|
} catch {
|
|
29920
29602
|
}
|
|
29921
29603
|
} else {
|
|
29922
29604
|
await runtime.bridge.detachClient(session.sessionId, session.clientId).catch(() => {
|
|
29923
29605
|
});
|
|
29924
29606
|
}
|
|
29607
|
+
if (worktreeMeta) {
|
|
29608
|
+
const rollbackSlug = worktreeMeta.slug;
|
|
29609
|
+
await new GitWorktreeService(workspaceCwd).removeUserWorktree(rollbackSlug, { deleteBranch: true }).catch((removalError) => {
|
|
29610
|
+
daemonLog?.warn(
|
|
29611
|
+
"worktree removal failed during generation-closed rollback",
|
|
29612
|
+
{
|
|
29613
|
+
sessionId: session.sessionId,
|
|
29614
|
+
slug: rollbackSlug,
|
|
29615
|
+
error: removalError instanceof Error ? removalError.message : String(removalError)
|
|
29616
|
+
}
|
|
29617
|
+
);
|
|
29618
|
+
});
|
|
29619
|
+
}
|
|
29925
29620
|
throw error2;
|
|
29926
29621
|
}
|
|
29927
29622
|
if (daemonLog) {
|
|
@@ -29986,7 +29681,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
29986
29681
|
if (worktreeMeta) {
|
|
29987
29682
|
try {
|
|
29988
29683
|
const createAllowedRoots = [
|
|
29989
|
-
|
|
29684
|
+
path11.join(workspaceCwd, ".qwen", "worktrees")
|
|
29990
29685
|
];
|
|
29991
29686
|
let createRepoTop = null;
|
|
29992
29687
|
try {
|
|
@@ -29997,10 +29692,10 @@ function registerSessionRoutes(app, deps) {
|
|
|
29997
29692
|
}
|
|
29998
29693
|
if (createRepoTop && createRepoTop !== workspaceCwd) {
|
|
29999
29694
|
createAllowedRoots.push(
|
|
30000
|
-
|
|
29695
|
+
path11.join(createRepoTop, ".qwen", "worktrees")
|
|
30001
29696
|
);
|
|
30002
29697
|
}
|
|
30003
|
-
const expectedWorktreePath =
|
|
29698
|
+
const expectedWorktreePath = fs6.realpathSync(worktreeMeta.path);
|
|
30004
29699
|
const changed = await runtime.bridge.changeSessionCwd(
|
|
30005
29700
|
session.sessionId,
|
|
30006
29701
|
{
|
|
@@ -30350,21 +30045,42 @@ function registerSessionRoutes(app, deps) {
|
|
|
30350
30045
|
};
|
|
30351
30046
|
const isChannelRestore = restoreRequestMetadata.sourceType === "channel";
|
|
30352
30047
|
let isPart4AWorktreeRestore = false;
|
|
30353
|
-
|
|
30048
|
+
let part4AWorktreeKey;
|
|
30049
|
+
if (runtime.provenance !== "live-conversation") {
|
|
30354
30050
|
const sidecarBeforeRestore = await readWorktreeSessionStrict(
|
|
30355
30051
|
sessionService.getWorktreeSessionPath(restoredStorageSessionId)
|
|
30356
30052
|
);
|
|
30053
|
+
if (isChannelRestore) {
|
|
30054
|
+
suppressWorktreeContextRestore = !(sidecarBeforeRestore.state === "valid" && sidecarBeforeRestore.session.workspaceCwd === void 0);
|
|
30055
|
+
}
|
|
30357
30056
|
isPart4AWorktreeRestore = sidecarBeforeRestore.state === "valid" && sidecarBeforeRestore.session.workspaceCwd !== void 0;
|
|
30358
|
-
|
|
30057
|
+
if (isPart4AWorktreeRestore && sidecarBeforeRestore.state === "valid") {
|
|
30058
|
+
const recordedPath = sidecarBeforeRestore.session.worktreePath;
|
|
30059
|
+
try {
|
|
30060
|
+
part4AWorktreeKey = fs6.realpathSync(recordedPath);
|
|
30061
|
+
} catch {
|
|
30062
|
+
part4AWorktreeKey = recordedPath;
|
|
30063
|
+
}
|
|
30064
|
+
}
|
|
30359
30065
|
} else {
|
|
30360
30066
|
suppressWorktreeContextRestore = isChannelRestore;
|
|
30361
30067
|
}
|
|
30362
30068
|
deferRestoreAskUserQuestionPrompt = suppressWorktreeContextRestore && runtime.bridge.fireDeferredRestoreAskUserQuestionPrompt !== void 0 && runtime.bridge.discardDeferredRestoreAskUserQuestionPrompt !== void 0;
|
|
30363
|
-
if (
|
|
30364
|
-
releaseWorktreeRestore = await
|
|
30365
|
-
|
|
30366
|
-
|
|
30367
|
-
|
|
30069
|
+
if (isPart4AWorktreeRestore && part4AWorktreeKey !== void 0) {
|
|
30070
|
+
releaseWorktreeRestore = await acquireWorktreeOwnershipOp(part4AWorktreeKey);
|
|
30071
|
+
if (isChannelRestore) {
|
|
30072
|
+
const sidecarUnderLock = await readWorktreeSessionStrict(
|
|
30073
|
+
sessionService.getWorktreeSessionPath(
|
|
30074
|
+
restoredStorageSessionId
|
|
30075
|
+
)
|
|
30076
|
+
);
|
|
30077
|
+
if (sidecarUnderLock.state === "valid" && sidecarUnderLock.session.supersededBy !== void 0) {
|
|
30078
|
+
throw new WorktreeSessionSupersededError(
|
|
30079
|
+
restoredStorageSessionId,
|
|
30080
|
+
sidecarUnderLock.session.supersededBy
|
|
30081
|
+
);
|
|
30082
|
+
}
|
|
30083
|
+
}
|
|
30368
30084
|
}
|
|
30369
30085
|
assertRuntimeGenerationOpen?.();
|
|
30370
30086
|
if (isInternalWorkspaceRuntime(runtime)) {
|
|
@@ -30511,7 +30227,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
30511
30227
|
let candidateRoots = [];
|
|
30512
30228
|
let validationError;
|
|
30513
30229
|
try {
|
|
30514
|
-
const workspaceRoots = [
|
|
30230
|
+
const workspaceRoots = [fs6.realpathSync(workspaceCwd)];
|
|
30515
30231
|
let repoTop = null;
|
|
30516
30232
|
try {
|
|
30517
30233
|
repoTop = await new GitWorktreeService(
|
|
@@ -30520,24 +30236,24 @@ function registerSessionRoutes(app, deps) {
|
|
|
30520
30236
|
} catch {
|
|
30521
30237
|
}
|
|
30522
30238
|
if (repoTop) {
|
|
30523
|
-
const realRepoTop =
|
|
30239
|
+
const realRepoTop = fs6.realpathSync(repoTop);
|
|
30524
30240
|
if (!workspaceRoots.includes(realRepoTop)) {
|
|
30525
30241
|
workspaceRoots.push(realRepoTop);
|
|
30526
30242
|
}
|
|
30527
30243
|
}
|
|
30528
|
-
const realOriginalCwd =
|
|
30244
|
+
const realOriginalCwd = fs6.realpathSync(sidecar.originalCwd);
|
|
30529
30245
|
if (!workspaceRoots.includes(realOriginalCwd)) {
|
|
30530
30246
|
throw new Error("legacy sidecar belongs to another workspace");
|
|
30531
30247
|
}
|
|
30532
30248
|
candidateRoots = workspaceRoots.map(
|
|
30533
|
-
(root) =>
|
|
30249
|
+
(root) => path11.join(root, ".qwen", "worktrees")
|
|
30534
30250
|
);
|
|
30535
|
-
realTarget =
|
|
30251
|
+
realTarget = fs6.realpathSync(sidecar.worktreePath);
|
|
30536
30252
|
const contained = candidateRoots.some((root) => {
|
|
30537
30253
|
try {
|
|
30538
|
-
const realRoot =
|
|
30539
|
-
const relative5 =
|
|
30540
|
-
return relative5.length > 0 && !relative5.startsWith("..") && !
|
|
30254
|
+
const realRoot = fs6.realpathSync(root);
|
|
30255
|
+
const relative5 = path11.relative(realRoot, realTarget);
|
|
30256
|
+
return relative5.length > 0 && !relative5.startsWith("..") && !path11.isAbsolute(relative5);
|
|
30541
30257
|
} catch {
|
|
30542
30258
|
return false;
|
|
30543
30259
|
}
|
|
@@ -30584,11 +30300,17 @@ function registerSessionRoutes(app, deps) {
|
|
|
30584
30300
|
throw new Error("Worktree sidecar is missing or invalid");
|
|
30585
30301
|
}
|
|
30586
30302
|
const sidecar = sidecarResult.session;
|
|
30587
|
-
|
|
30303
|
+
if (sidecar.supersededBy !== void 0) {
|
|
30304
|
+
throw new WorktreeSessionSupersededError(
|
|
30305
|
+
restoredStorageSessionId,
|
|
30306
|
+
sidecar.supersededBy
|
|
30307
|
+
);
|
|
30308
|
+
}
|
|
30309
|
+
const realWorkspace = fs6.realpathSync(workspaceCwd);
|
|
30588
30310
|
if (sidecar.workspaceCwd !== void 0) {
|
|
30589
30311
|
let realSidecarWorkspace;
|
|
30590
30312
|
try {
|
|
30591
|
-
realSidecarWorkspace =
|
|
30313
|
+
realSidecarWorkspace = fs6.realpathSync(sidecar.workspaceCwd);
|
|
30592
30314
|
} catch {
|
|
30593
30315
|
throw new Error(
|
|
30594
30316
|
"Worktree sidecar workspace is missing or inaccessible"
|
|
@@ -30609,11 +30331,11 @@ function registerSessionRoutes(app, deps) {
|
|
|
30609
30331
|
} catch {
|
|
30610
30332
|
}
|
|
30611
30333
|
if (repoTop && repoTop !== realWorkspace) {
|
|
30612
|
-
workspaceRoots.push(
|
|
30334
|
+
workspaceRoots.push(fs6.realpathSync(repoTop));
|
|
30613
30335
|
}
|
|
30614
30336
|
let realOriginalCwd;
|
|
30615
30337
|
try {
|
|
30616
|
-
realOriginalCwd =
|
|
30338
|
+
realOriginalCwd = fs6.realpathSync(sidecar.originalCwd);
|
|
30617
30339
|
} catch {
|
|
30618
30340
|
throw new Error(
|
|
30619
30341
|
"Worktree sidecar workspace is missing or inaccessible"
|
|
@@ -30625,19 +30347,19 @@ function registerSessionRoutes(app, deps) {
|
|
|
30625
30347
|
);
|
|
30626
30348
|
}
|
|
30627
30349
|
const candidateRoots = workspaceRoots.map(
|
|
30628
|
-
(root) =>
|
|
30350
|
+
(root) => path11.join(root, ".qwen", "worktrees")
|
|
30629
30351
|
);
|
|
30630
30352
|
let realTarget;
|
|
30631
30353
|
try {
|
|
30632
|
-
realTarget =
|
|
30354
|
+
realTarget = fs6.realpathSync(sidecar.worktreePath);
|
|
30633
30355
|
} catch {
|
|
30634
30356
|
throw new Error("Worktree checkout is missing or inaccessible");
|
|
30635
30357
|
}
|
|
30636
30358
|
const contained = candidateRoots.some((root) => {
|
|
30637
30359
|
try {
|
|
30638
|
-
const realRoot =
|
|
30639
|
-
const relative5 =
|
|
30640
|
-
return relative5.length > 0 && !relative5.startsWith("..") && !
|
|
30360
|
+
const realRoot = fs6.realpathSync(root);
|
|
30361
|
+
const relative5 = path11.relative(realRoot, realTarget);
|
|
30362
|
+
return relative5.length > 0 && !relative5.startsWith("..") && !path11.isAbsolute(relative5);
|
|
30641
30363
|
} catch {
|
|
30642
30364
|
return false;
|
|
30643
30365
|
}
|
|
@@ -30647,6 +30369,30 @@ function registerSessionRoutes(app, deps) {
|
|
|
30647
30369
|
}
|
|
30648
30370
|
const marker = await readWorktreeSessionMarkerStrict(realTarget);
|
|
30649
30371
|
if (marker.state !== "valid" || marker.sessionId !== restoredStorageSessionId) {
|
|
30372
|
+
if (sidecar.supersedes !== void 0 && (marker.state === "missing" || marker.state === "valid" && marker.sessionId === sidecar.supersedes)) {
|
|
30373
|
+
const oldSidecar = await readWorktreeSessionStrict(
|
|
30374
|
+
createWorkspaceRuntimeSessionService(
|
|
30375
|
+
runtime
|
|
30376
|
+
).getWorktreeSessionPath(sidecar.supersedes)
|
|
30377
|
+
);
|
|
30378
|
+
if (oldSidecar.state === "valid" && oldSidecar.session.supersededBy === restoredStorageSessionId) {
|
|
30379
|
+
daemonLog?.warn(
|
|
30380
|
+
"worktree restore found an interrupted reset",
|
|
30381
|
+
{
|
|
30382
|
+
sessionId: restoredStorageSessionId,
|
|
30383
|
+
supersedesSessionId: sidecar.supersedes
|
|
30384
|
+
}
|
|
30385
|
+
);
|
|
30386
|
+
throw new WorktreeResetInterruptedError(
|
|
30387
|
+
restoredStorageSessionId
|
|
30388
|
+
);
|
|
30389
|
+
}
|
|
30390
|
+
}
|
|
30391
|
+
if (marker.state === "missing") {
|
|
30392
|
+
throw new WorktreeMarkerMissingError(
|
|
30393
|
+
restoredStorageSessionId
|
|
30394
|
+
);
|
|
30395
|
+
}
|
|
30650
30396
|
throw new Error("Worktree marker ownership is invalid");
|
|
30651
30397
|
}
|
|
30652
30398
|
const worktree = {
|
|
@@ -30654,28 +30400,28 @@ function registerSessionRoutes(app, deps) {
|
|
|
30654
30400
|
path: realTarget,
|
|
30655
30401
|
branch: sidecar.worktreeBranch
|
|
30656
30402
|
};
|
|
30657
|
-
const hasUnlocatedRestoredPrompt = session.hasActivePrompt && !session.attached && session.currentCwd === void 0;
|
|
30403
|
+
const hasUnlocatedRestoredPrompt = session.hasActivePrompt && !session.attached && session.currentCwd === void 0 && !deferRestoreAskUserQuestionPrompt;
|
|
30658
30404
|
if (hasUnlocatedRestoredPrompt) {
|
|
30659
30405
|
runtime.bridge.setSessionWorktree(sessionId, worktree);
|
|
30660
30406
|
session.worktree = worktree;
|
|
30661
|
-
} else if (session.hasActivePrompt) {
|
|
30662
|
-
if (session.currentCwd !== realTarget) {
|
|
30663
|
-
throw new Error("Active session is outside its worktree");
|
|
30664
|
-
}
|
|
30665
30407
|
} else {
|
|
30666
|
-
|
|
30667
|
-
|
|
30668
|
-
|
|
30669
|
-
path: realTarget,
|
|
30670
|
-
allowedRoots: candidateRoots
|
|
30408
|
+
if (session.hasActivePrompt) {
|
|
30409
|
+
if (session.currentCwd !== realTarget) {
|
|
30410
|
+
throw new Error("Active session is outside its worktree");
|
|
30671
30411
|
}
|
|
30672
|
-
|
|
30673
|
-
|
|
30674
|
-
|
|
30412
|
+
} else {
|
|
30413
|
+
const changed = await runtime.bridge.changeSessionCwd(
|
|
30414
|
+
sessionId,
|
|
30415
|
+
{
|
|
30416
|
+
path: realTarget,
|
|
30417
|
+
allowedRoots: candidateRoots
|
|
30418
|
+
}
|
|
30419
|
+
);
|
|
30420
|
+
if (changed.newCwd !== realTarget) {
|
|
30421
|
+
throw new Error("Worktree relocation was rejected");
|
|
30422
|
+
}
|
|
30423
|
+
session.currentCwd = changed.newCwd;
|
|
30675
30424
|
}
|
|
30676
|
-
session.currentCwd = changed.newCwd;
|
|
30677
|
-
}
|
|
30678
|
-
if (!hasUnlocatedRestoredPrompt) {
|
|
30679
30425
|
runtime.bridge.setSessionWorktree(sessionId, worktree);
|
|
30680
30426
|
assertRuntimeGenerationOpen?.();
|
|
30681
30427
|
session.worktree = worktree;
|
|
@@ -30750,6 +30496,448 @@ function registerSessionRoutes(app, deps) {
|
|
|
30750
30496
|
}, "restoreSessionHandler");
|
|
30751
30497
|
app.post("/session/:id/load", mutate(), restoreSessionHandler("load"));
|
|
30752
30498
|
app.post("/session/:id/resume", mutate(), restoreSessionHandler("resume"));
|
|
30499
|
+
const resolveWorktreeOwnershipTarget = /* @__PURE__ */ __name(async (runtime, workspaceCwd, sidecar, sessionId) => {
|
|
30500
|
+
const invalidState = /* @__PURE__ */ __name((reason) => {
|
|
30501
|
+
daemonLog?.warn("worktree reset rejected sidecar state", {
|
|
30502
|
+
sessionId,
|
|
30503
|
+
reason
|
|
30504
|
+
});
|
|
30505
|
+
return new WorktreeResetInvalidStateError(sessionId);
|
|
30506
|
+
}, "invalidState");
|
|
30507
|
+
const realWorkspace = fs6.realpathSync(workspaceCwd);
|
|
30508
|
+
if (sidecar.workspaceCwd !== void 0) {
|
|
30509
|
+
let realSidecarWorkspace;
|
|
30510
|
+
try {
|
|
30511
|
+
realSidecarWorkspace = fs6.realpathSync(sidecar.workspaceCwd);
|
|
30512
|
+
} catch {
|
|
30513
|
+
throw invalidState("sidecar workspace is missing or inaccessible");
|
|
30514
|
+
}
|
|
30515
|
+
if (realSidecarWorkspace !== realWorkspace) {
|
|
30516
|
+
throw invalidState("sidecar belongs to another workspace");
|
|
30517
|
+
}
|
|
30518
|
+
}
|
|
30519
|
+
const workspaceRoots = [realWorkspace];
|
|
30520
|
+
let repoTop = null;
|
|
30521
|
+
try {
|
|
30522
|
+
repoTop = await new GitWorktreeService(realWorkspace).getRepoTopLevel();
|
|
30523
|
+
} catch {
|
|
30524
|
+
}
|
|
30525
|
+
if (repoTop && repoTop !== realWorkspace) {
|
|
30526
|
+
workspaceRoots.push(fs6.realpathSync(repoTop));
|
|
30527
|
+
}
|
|
30528
|
+
let realOriginalCwd;
|
|
30529
|
+
try {
|
|
30530
|
+
realOriginalCwd = fs6.realpathSync(sidecar.originalCwd);
|
|
30531
|
+
} catch {
|
|
30532
|
+
throw invalidState("sidecar original cwd is missing or inaccessible");
|
|
30533
|
+
}
|
|
30534
|
+
if (!workspaceRoots.includes(realOriginalCwd)) {
|
|
30535
|
+
throw invalidState("sidecar original cwd is outside the accepted roots");
|
|
30536
|
+
}
|
|
30537
|
+
const candidateRoots = workspaceRoots.map(
|
|
30538
|
+
(root) => path11.join(root, ".qwen", "worktrees")
|
|
30539
|
+
);
|
|
30540
|
+
let realTarget;
|
|
30541
|
+
try {
|
|
30542
|
+
realTarget = fs6.realpathSync(sidecar.worktreePath);
|
|
30543
|
+
} catch {
|
|
30544
|
+
throw invalidState("worktree checkout is missing or inaccessible");
|
|
30545
|
+
}
|
|
30546
|
+
const contained = candidateRoots.some((root) => {
|
|
30547
|
+
try {
|
|
30548
|
+
const realRoot = fs6.realpathSync(root);
|
|
30549
|
+
const relative5 = path11.relative(realRoot, realTarget);
|
|
30550
|
+
return relative5.length > 0 && !relative5.startsWith("..") && !path11.isAbsolute(relative5);
|
|
30551
|
+
} catch {
|
|
30552
|
+
return false;
|
|
30553
|
+
}
|
|
30554
|
+
});
|
|
30555
|
+
if (!contained) {
|
|
30556
|
+
throw invalidState("worktree path failed containment");
|
|
30557
|
+
}
|
|
30558
|
+
return { realTarget, candidateRoots };
|
|
30559
|
+
}, "resolveWorktreeOwnershipTarget");
|
|
30560
|
+
const worktreeResetHandler = /* @__PURE__ */ __name(async (req, res) => {
|
|
30561
|
+
const route = "POST /session/:id/worktree-reset";
|
|
30562
|
+
const sessionId = requireSessionId(req, res);
|
|
30563
|
+
if (!sessionId) return;
|
|
30564
|
+
if (parseVirtualSubagentSessionId(sessionId)) {
|
|
30565
|
+
res.status(400).json({
|
|
30566
|
+
error: "Virtual subagent sessions do not support worktree reset",
|
|
30567
|
+
code: "unsupported_action",
|
|
30568
|
+
sessionId
|
|
30569
|
+
});
|
|
30570
|
+
return;
|
|
30571
|
+
}
|
|
30572
|
+
const body = safeBody(req);
|
|
30573
|
+
let resolvedRuntime;
|
|
30574
|
+
try {
|
|
30575
|
+
resolvedRuntime = await resolveRuntimeForSessionRestore(
|
|
30576
|
+
body,
|
|
30577
|
+
res,
|
|
30578
|
+
route,
|
|
30579
|
+
sessionId
|
|
30580
|
+
);
|
|
30581
|
+
} catch (err) {
|
|
30582
|
+
if (sendConversationRuntimeError(res, err)) return;
|
|
30583
|
+
sendBridgeError2(res, err, { route, sessionId });
|
|
30584
|
+
return;
|
|
30585
|
+
}
|
|
30586
|
+
if (resolvedRuntime === void 0) return;
|
|
30587
|
+
const { runtime, workspaceCwd } = resolvedRuntime;
|
|
30588
|
+
const approvalMode = parseOptionalApprovalMode(body, res);
|
|
30589
|
+
if (approvalMode === null) return;
|
|
30590
|
+
const source = parseRequestedSessionSource(body, res);
|
|
30591
|
+
if (source === null) return;
|
|
30592
|
+
const modelServiceId = typeof body["modelServiceId"] === "string" ? body["modelServiceId"] : void 0;
|
|
30593
|
+
const assertRuntimeGenerationOpen = captureRuntimeGenerationAssertion(runtime);
|
|
30594
|
+
try {
|
|
30595
|
+
await runOwnerRuntimeActivity(
|
|
30596
|
+
runtime,
|
|
30597
|
+
() => archiveCoordinator.runSharedMany([sessionId], async () => {
|
|
30598
|
+
const sessionService = createWorkspaceRuntimeSessionService(runtime);
|
|
30599
|
+
const storageSessionId = await resolveSessionIdForRestore(
|
|
30600
|
+
sessionService,
|
|
30601
|
+
sessionId
|
|
30602
|
+
);
|
|
30603
|
+
if (storageSessionId === void 0) {
|
|
30604
|
+
throw new SessionNotFoundError(sessionId);
|
|
30605
|
+
}
|
|
30606
|
+
const oldSidecarPath = sessionService.getWorktreeSessionPath(storageSessionId);
|
|
30607
|
+
if (runtime.bridge.setSessionResetPending === void 0 || runtime.bridge.clearSessionResetPending === void 0 || runtime.bridge.clearSessionWorktree === void 0 || runtime.bridge.severSessionClients === void 0) {
|
|
30608
|
+
throw new Error("Bridge does not support worktree reset");
|
|
30609
|
+
}
|
|
30610
|
+
const preRead = await readWorktreeSessionStrict(oldSidecarPath);
|
|
30611
|
+
if (preRead.state === "missing" || preRead.state === "valid" && preRead.session.workspaceCwd === void 0) {
|
|
30612
|
+
throw new WorktreeResetUnsupportedError(sessionId);
|
|
30613
|
+
}
|
|
30614
|
+
if (preRead.state !== "valid") {
|
|
30615
|
+
daemonLog?.warn("worktree reset rejected invalid sidecar", {
|
|
30616
|
+
sessionId,
|
|
30617
|
+
reason: preRead.reason
|
|
30618
|
+
});
|
|
30619
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30620
|
+
}
|
|
30621
|
+
const preTarget = await resolveWorktreeOwnershipTarget(
|
|
30622
|
+
runtime,
|
|
30623
|
+
workspaceCwd,
|
|
30624
|
+
preRead.session,
|
|
30625
|
+
sessionId
|
|
30626
|
+
);
|
|
30627
|
+
const releaseOwnership = await acquireWorktreeOwnershipOp(
|
|
30628
|
+
preTarget.realTarget
|
|
30629
|
+
);
|
|
30630
|
+
try {
|
|
30631
|
+
const lockedRead = await readWorktreeSessionStrict(oldSidecarPath);
|
|
30632
|
+
if (lockedRead.state === "missing" || lockedRead.state === "valid" && lockedRead.session.workspaceCwd === void 0) {
|
|
30633
|
+
throw new WorktreeResetUnsupportedError(sessionId);
|
|
30634
|
+
}
|
|
30635
|
+
if (lockedRead.state !== "valid") {
|
|
30636
|
+
daemonLog?.warn("worktree reset rejected invalid sidecar", {
|
|
30637
|
+
sessionId,
|
|
30638
|
+
reason: lockedRead.reason
|
|
30639
|
+
});
|
|
30640
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30641
|
+
}
|
|
30642
|
+
const oldSidecar = lockedRead.session;
|
|
30643
|
+
const { realTarget, candidateRoots } = await resolveWorktreeOwnershipTarget(
|
|
30644
|
+
runtime,
|
|
30645
|
+
workspaceCwd,
|
|
30646
|
+
oldSidecar,
|
|
30647
|
+
sessionId
|
|
30648
|
+
);
|
|
30649
|
+
if (realTarget !== preTarget.realTarget) {
|
|
30650
|
+
daemonLog?.warn("worktree reset rejected: sidecar moved", {
|
|
30651
|
+
sessionId
|
|
30652
|
+
});
|
|
30653
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30654
|
+
}
|
|
30655
|
+
const readSummary = /* @__PURE__ */ __name((id) => {
|
|
30656
|
+
try {
|
|
30657
|
+
return runtime.bridge.getSessionSummary(id);
|
|
30658
|
+
} catch (error2) {
|
|
30659
|
+
if (error2 instanceof SessionNotFoundError) return void 0;
|
|
30660
|
+
throw error2;
|
|
30661
|
+
}
|
|
30662
|
+
}, "readSummary");
|
|
30663
|
+
runtime.bridge.setSessionResetPending(sessionId);
|
|
30664
|
+
let barrierArmed = true;
|
|
30665
|
+
try {
|
|
30666
|
+
let effectiveOldSidecar = oldSidecar;
|
|
30667
|
+
if (oldSidecar.supersededBy !== void 0) {
|
|
30668
|
+
const replacementId = oldSidecar.supersededBy;
|
|
30669
|
+
const newSidecarPath = sessionService.getWorktreeSessionPath(replacementId);
|
|
30670
|
+
const newRead = await readWorktreeSessionStrict(newSidecarPath);
|
|
30671
|
+
const linksAgree = newRead.state === "valid" && newRead.session.supersedes === storageSessionId;
|
|
30672
|
+
const marker = await readWorktreeSessionMarkerStrict(realTarget);
|
|
30673
|
+
if (marker.state === "invalid") {
|
|
30674
|
+
daemonLog?.warn("worktree reset resume rejected marker", {
|
|
30675
|
+
sessionId,
|
|
30676
|
+
reason: marker.reason
|
|
30677
|
+
});
|
|
30678
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30679
|
+
}
|
|
30680
|
+
if (marker.state === "missing" || marker.state === "valid" && marker.sessionId === storageSessionId) {
|
|
30681
|
+
if (!linksAgree) {
|
|
30682
|
+
daemonLog?.warn(
|
|
30683
|
+
"worktree reset resume found inconsistent links",
|
|
30684
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30685
|
+
);
|
|
30686
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30687
|
+
}
|
|
30688
|
+
if (marker.state === "missing" && readSummary(replacementId) !== void 0) {
|
|
30689
|
+
daemonLog?.warn(
|
|
30690
|
+
"worktree reset resume found a live replacement with no marker",
|
|
30691
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30692
|
+
);
|
|
30693
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30694
|
+
}
|
|
30695
|
+
const { supersededBy: _drop, ...restoredOld } = oldSidecar;
|
|
30696
|
+
const removed = await runWithWorkspaceRuntimeStorage(
|
|
30697
|
+
runtime,
|
|
30698
|
+
() => deleteDaemonSessionIfOrphan({
|
|
30699
|
+
sessionId: replacementId,
|
|
30700
|
+
service: sessionService,
|
|
30701
|
+
bridge: runtime.bridge,
|
|
30702
|
+
coordinator: archiveCoordinator
|
|
30703
|
+
})
|
|
30704
|
+
).catch(() => false);
|
|
30705
|
+
if (!removed) {
|
|
30706
|
+
daemonLog?.warn(
|
|
30707
|
+
"worktree reset could not remove the interrupted replacement",
|
|
30708
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30709
|
+
);
|
|
30710
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30711
|
+
}
|
|
30712
|
+
await clearWorktreeSession(newSidecarPath);
|
|
30713
|
+
await writeWorktreeSession(oldSidecarPath, restoredOld);
|
|
30714
|
+
daemonLog?.warn(
|
|
30715
|
+
"worktree reset rolled back an interrupted transfer",
|
|
30716
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30717
|
+
);
|
|
30718
|
+
effectiveOldSidecar = restoredOld;
|
|
30719
|
+
} else if (marker.state === "valid" && marker.sessionId === replacementId) {
|
|
30720
|
+
barrierArmed = false;
|
|
30721
|
+
if (!linksAgree) {
|
|
30722
|
+
daemonLog?.warn(
|
|
30723
|
+
"worktree reset resume found inconsistent links",
|
|
30724
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30725
|
+
);
|
|
30726
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30727
|
+
}
|
|
30728
|
+
const newSummary = readSummary(replacementId);
|
|
30729
|
+
if (newSummary && (newSummary.hasActivePrompt || (newSummary.pendingInteractionCount ?? 0) > 0)) {
|
|
30730
|
+
throw new WorktreeResetActiveError(replacementId);
|
|
30731
|
+
}
|
|
30732
|
+
runtime.bridge.clearSessionWorktree(sessionId);
|
|
30733
|
+
const severCompleted = await runtime.bridge.severSessionClients(sessionId);
|
|
30734
|
+
if (severCompleted) {
|
|
30735
|
+
runtime.bridge.clearSessionResetPending(sessionId);
|
|
30736
|
+
} else {
|
|
30737
|
+
daemonLog?.warn(
|
|
30738
|
+
"worktree reset left the superseded session live",
|
|
30739
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30740
|
+
);
|
|
30741
|
+
}
|
|
30742
|
+
assertRuntimeGenerationOpen?.();
|
|
30743
|
+
daemonLog?.info(
|
|
30744
|
+
"worktree session reset resumed after interruption",
|
|
30745
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30746
|
+
);
|
|
30747
|
+
res.status(200).json({
|
|
30748
|
+
sessionId: replacementId,
|
|
30749
|
+
workspaceCwd,
|
|
30750
|
+
currentCwd: realTarget,
|
|
30751
|
+
worktree: {
|
|
30752
|
+
slug: oldSidecar.slug,
|
|
30753
|
+
path: realTarget,
|
|
30754
|
+
branch: oldSidecar.worktreeBranch
|
|
30755
|
+
},
|
|
30756
|
+
worktreeState: "persisted-v1",
|
|
30757
|
+
attached: false,
|
|
30758
|
+
...severCompleted ? {} : { supersededSessionLive: true }
|
|
30759
|
+
});
|
|
30760
|
+
return;
|
|
30761
|
+
} else {
|
|
30762
|
+
daemonLog?.warn(
|
|
30763
|
+
"worktree reset resume found a marker naming another session",
|
|
30764
|
+
{ sessionId }
|
|
30765
|
+
);
|
|
30766
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30767
|
+
}
|
|
30768
|
+
}
|
|
30769
|
+
const oldSummary = readSummary(sessionId);
|
|
30770
|
+
if (oldSummary && (oldSummary.hasActivePrompt || (oldSummary.pendingInteractionCount ?? 0) > 0)) {
|
|
30771
|
+
throw new WorktreeResetActiveError(sessionId);
|
|
30772
|
+
}
|
|
30773
|
+
let spawnedNew;
|
|
30774
|
+
let newSidecarWritten = false;
|
|
30775
|
+
let oldSupersededWritten = false;
|
|
30776
|
+
let markerTransferred = false;
|
|
30777
|
+
try {
|
|
30778
|
+
assertRuntimeGenerationOpen?.();
|
|
30779
|
+
const spawned = await runtime.bridge.spawnOrAttach({
|
|
30780
|
+
workspaceCwd,
|
|
30781
|
+
modelServiceId,
|
|
30782
|
+
sessionScope: "thread",
|
|
30783
|
+
...approvalMode !== void 0 ? { approvalMode } : {},
|
|
30784
|
+
...source.sourceType !== void 0 ? { sourceType: source.sourceType } : {},
|
|
30785
|
+
...source.sourceId !== void 0 ? { sourceId: source.sourceId } : {}
|
|
30786
|
+
});
|
|
30787
|
+
spawnedNew = { sessionId: spawned.sessionId };
|
|
30788
|
+
const changed = await runtime.bridge.changeSessionCwd(
|
|
30789
|
+
spawned.sessionId,
|
|
30790
|
+
{ path: realTarget, allowedRoots: candidateRoots }
|
|
30791
|
+
);
|
|
30792
|
+
if (changed.newCwd !== realTarget) {
|
|
30793
|
+
throw new Error("Worktree relocation was rejected");
|
|
30794
|
+
}
|
|
30795
|
+
await writeWorktreeSession(oldSidecarPath, {
|
|
30796
|
+
...effectiveOldSidecar,
|
|
30797
|
+
supersededBy: spawned.sessionId
|
|
30798
|
+
});
|
|
30799
|
+
oldSupersededWritten = true;
|
|
30800
|
+
const newSidecarPath = sessionService.getWorktreeSessionPath(
|
|
30801
|
+
spawned.sessionId
|
|
30802
|
+
);
|
|
30803
|
+
const {
|
|
30804
|
+
supersededBy: _dropOld,
|
|
30805
|
+
supersedes: _dropOldLink,
|
|
30806
|
+
...oldSidecarCore
|
|
30807
|
+
} = effectiveOldSidecar;
|
|
30808
|
+
await writeWorktreeSession(newSidecarPath, {
|
|
30809
|
+
...oldSidecarCore,
|
|
30810
|
+
supersedes: storageSessionId
|
|
30811
|
+
});
|
|
30812
|
+
newSidecarWritten = true;
|
|
30813
|
+
if (res.destroyed || res.socket?.writable === false) {
|
|
30814
|
+
throw new Error(
|
|
30815
|
+
"Client disconnected before the worktree ownership flip"
|
|
30816
|
+
);
|
|
30817
|
+
}
|
|
30818
|
+
const windingDown = readSummary(sessionId);
|
|
30819
|
+
if (windingDown && (windingDown.hasActivePrompt || (windingDown.pendingInteractionCount ?? 0) > 0)) {
|
|
30820
|
+
throw new WorktreeResetActiveError(sessionId);
|
|
30821
|
+
}
|
|
30822
|
+
const markerBeforeFlip = await readWorktreeSessionMarkerStrict(realTarget);
|
|
30823
|
+
try {
|
|
30824
|
+
await transferWorktreeSessionMarkerOwner(
|
|
30825
|
+
realTarget,
|
|
30826
|
+
markerBeforeFlip.state === "missing" ? null : storageSessionId,
|
|
30827
|
+
spawned.sessionId
|
|
30828
|
+
);
|
|
30829
|
+
} catch (markerError) {
|
|
30830
|
+
daemonLog?.warn("worktree marker transfer failed", {
|
|
30831
|
+
sessionId,
|
|
30832
|
+
replacementSessionId: spawned.sessionId,
|
|
30833
|
+
error: markerError instanceof Error ? markerError.message : String(markerError)
|
|
30834
|
+
});
|
|
30835
|
+
if (markerError instanceof WorktreeMarkerCommittedError) {
|
|
30836
|
+
markerTransferred = true;
|
|
30837
|
+
barrierArmed = false;
|
|
30838
|
+
throw new Error(
|
|
30839
|
+
"Worktree ownership moved to the replacement, but the marker commit did not finish cleanly; retry the reset to complete the transfer"
|
|
30840
|
+
);
|
|
30841
|
+
}
|
|
30842
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30843
|
+
}
|
|
30844
|
+
markerTransferred = true;
|
|
30845
|
+
barrierArmed = false;
|
|
30846
|
+
const newWorktree = {
|
|
30847
|
+
slug: effectiveOldSidecar.slug,
|
|
30848
|
+
path: realTarget,
|
|
30849
|
+
branch: effectiveOldSidecar.worktreeBranch
|
|
30850
|
+
};
|
|
30851
|
+
runtime.bridge.setSessionWorktree(
|
|
30852
|
+
spawned.sessionId,
|
|
30853
|
+
newWorktree
|
|
30854
|
+
);
|
|
30855
|
+
assertRuntimeGenerationOpen?.();
|
|
30856
|
+
runtime.bridge.clearSessionWorktree(sessionId);
|
|
30857
|
+
const severCompleted = await runtime.bridge.severSessionClients(sessionId);
|
|
30858
|
+
if (severCompleted) {
|
|
30859
|
+
runtime.bridge.clearSessionResetPending(sessionId);
|
|
30860
|
+
} else {
|
|
30861
|
+
daemonLog?.warn(
|
|
30862
|
+
"worktree reset left the superseded session live",
|
|
30863
|
+
{
|
|
30864
|
+
sessionId,
|
|
30865
|
+
replacementSessionId: spawned.sessionId
|
|
30866
|
+
}
|
|
30867
|
+
);
|
|
30868
|
+
}
|
|
30869
|
+
daemonLog?.info("worktree session reset", {
|
|
30870
|
+
sessionId,
|
|
30871
|
+
replacementSessionId: spawned.sessionId
|
|
30872
|
+
});
|
|
30873
|
+
res.status(200).json({
|
|
30874
|
+
...spawned,
|
|
30875
|
+
currentCwd: realTarget,
|
|
30876
|
+
worktree: newWorktree,
|
|
30877
|
+
worktreeState: "persisted-v1",
|
|
30878
|
+
...severCompleted ? {} : { supersededSessionLive: true }
|
|
30879
|
+
});
|
|
30880
|
+
} catch (transferError) {
|
|
30881
|
+
if (markerTransferred) {
|
|
30882
|
+
daemonLog?.warn(
|
|
30883
|
+
"worktree reset failed after the ownership flip",
|
|
30884
|
+
{
|
|
30885
|
+
sessionId,
|
|
30886
|
+
replacementSessionId: spawnedNew?.sessionId,
|
|
30887
|
+
error: transferError instanceof Error ? transferError.message : String(transferError)
|
|
30888
|
+
}
|
|
30889
|
+
);
|
|
30890
|
+
throw transferError;
|
|
30891
|
+
}
|
|
30892
|
+
if (spawnedNew) {
|
|
30893
|
+
const orphanSessionId = spawnedNew.sessionId;
|
|
30894
|
+
const removed = await runWithWorkspaceRuntimeStorage(
|
|
30895
|
+
runtime,
|
|
30896
|
+
() => deleteDaemonSessionIfOrphan({
|
|
30897
|
+
sessionId: orphanSessionId,
|
|
30898
|
+
service: sessionService,
|
|
30899
|
+
bridge: runtime.bridge,
|
|
30900
|
+
coordinator: archiveCoordinator
|
|
30901
|
+
})
|
|
30902
|
+
).catch(() => false);
|
|
30903
|
+
if (!removed) {
|
|
30904
|
+
daemonLog?.warn(
|
|
30905
|
+
"worktree reset could not remove the spawned replacement",
|
|
30906
|
+
{ sessionId, replacementSessionId: orphanSessionId }
|
|
30907
|
+
);
|
|
30908
|
+
throw transferError;
|
|
30909
|
+
}
|
|
30910
|
+
}
|
|
30911
|
+
if (newSidecarWritten && spawnedNew) {
|
|
30912
|
+
await clearWorktreeSession(
|
|
30913
|
+
sessionService.getWorktreeSessionPath(spawnedNew.sessionId)
|
|
30914
|
+
);
|
|
30915
|
+
}
|
|
30916
|
+
if (oldSupersededWritten) {
|
|
30917
|
+
await writeWorktreeSession(
|
|
30918
|
+
oldSidecarPath,
|
|
30919
|
+
effectiveOldSidecar
|
|
30920
|
+
);
|
|
30921
|
+
}
|
|
30922
|
+
throw transferError;
|
|
30923
|
+
}
|
|
30924
|
+
} finally {
|
|
30925
|
+
if (barrierArmed) {
|
|
30926
|
+
runtime.bridge.clearSessionResetPending(sessionId);
|
|
30927
|
+
}
|
|
30928
|
+
}
|
|
30929
|
+
} finally {
|
|
30930
|
+
releaseOwnership();
|
|
30931
|
+
}
|
|
30932
|
+
})
|
|
30933
|
+
);
|
|
30934
|
+
} catch (err) {
|
|
30935
|
+
if (!res.headersSent) {
|
|
30936
|
+
sendBridgeError2(res, err, { route, sessionId });
|
|
30937
|
+
}
|
|
30938
|
+
}
|
|
30939
|
+
}, "worktreeResetHandler");
|
|
30940
|
+
app.post("/session/:id/worktree-reset", mutate(), worktreeResetHandler);
|
|
30753
30941
|
app.get("/session/:id/subagents/:subagentRef", async (req, res) => {
|
|
30754
30942
|
const route = "GET /session/:id/subagents/:subagentRef";
|
|
30755
30943
|
const sessionId = requireSessionId(req, res);
|
|
@@ -31018,7 +31206,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
31018
31206
|
async (req, res, sessionId, runtime) => {
|
|
31019
31207
|
const body = safeBody(req);
|
|
31020
31208
|
const targetPath = body["path"];
|
|
31021
|
-
if (typeof targetPath !== "string" || targetPath.length === 0 || !
|
|
31209
|
+
if (typeof targetPath !== "string" || targetPath.length === 0 || !path11.isAbsolute(targetPath)) {
|
|
31022
31210
|
res.status(400).json({
|
|
31023
31211
|
error: "`path` is required and must be an absolute path",
|
|
31024
31212
|
code: "invalid_path"
|
|
@@ -33486,6 +33674,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
33486
33674
|
sessionId: session.sessionId,
|
|
33487
33675
|
clientCount: session.clientCount,
|
|
33488
33676
|
hasActivePrompt: session.hasActivePrompt,
|
|
33677
|
+
...session.activeWorkState !== void 0 ? { activeWorkState: session.activeWorkState } : {},
|
|
33489
33678
|
isWaitingForPermission: session.isWaitingForPermission ?? false,
|
|
33490
33679
|
isWaitingForUserQuestion: session.isWaitingForUserQuestion ?? false,
|
|
33491
33680
|
// Bridge-local activity watermark, absent until a running prompt in
|
|
@@ -34083,8 +34272,8 @@ __name(registerSessionRoutes, "registerSessionRoutes");
|
|
|
34083
34272
|
// packages/cli/src/serve/routes/session-pr-backfill.ts
|
|
34084
34273
|
init_esbuild_shims();
|
|
34085
34274
|
import { existsSync } from "node:fs";
|
|
34086
|
-
import * as
|
|
34087
|
-
import * as
|
|
34275
|
+
import * as fs7 from "node:fs/promises";
|
|
34276
|
+
import * as path12 from "node:path";
|
|
34088
34277
|
var SLUG_PR_PATTERN = /^pr-([1-9]\d{0,8})$/;
|
|
34089
34278
|
var BRANCH_PR_PATTERN = /^worktree-pr-([1-9]\d{0,8})$/;
|
|
34090
34279
|
function parsePrNumberFromWorktree(slug, branch) {
|
|
@@ -34173,7 +34362,7 @@ async function backfillWorkspaceSessionPrs(runtime, fetchPullRequests = fetchGit
|
|
|
34173
34362
|
for (const sessionId of sessionIds) {
|
|
34174
34363
|
if (!isValidSessionId(sessionId)) continue;
|
|
34175
34364
|
result.scanned += 1;
|
|
34176
|
-
const dir =
|
|
34365
|
+
const dir = path12.dirname(
|
|
34177
34366
|
sessionService.getWorktreeSessionPathForArchiveState(
|
|
34178
34367
|
sessionId,
|
|
34179
34368
|
archiveState
|
|
@@ -34182,15 +34371,15 @@ async function backfillWorkspaceSessionPrs(runtime, fetchPullRequests = fetchGit
|
|
|
34182
34371
|
let worktree;
|
|
34183
34372
|
try {
|
|
34184
34373
|
worktree = await readWorktreeSession(
|
|
34185
|
-
|
|
34374
|
+
path12.join(dir, `${sessionId}.worktree.json`)
|
|
34186
34375
|
);
|
|
34187
34376
|
} catch {
|
|
34188
34377
|
worktree = null;
|
|
34189
34378
|
}
|
|
34190
34379
|
let transcriptRaw;
|
|
34191
34380
|
try {
|
|
34192
|
-
transcriptRaw = await
|
|
34193
|
-
|
|
34381
|
+
transcriptRaw = await fs7.readFile(
|
|
34382
|
+
path12.join(dir, `${sessionId}.jsonl`),
|
|
34194
34383
|
"utf8"
|
|
34195
34384
|
);
|
|
34196
34385
|
} catch {
|
|
@@ -34210,7 +34399,7 @@ async function backfillWorkspaceSessionPrs(runtime, fetchPullRequests = fetchGit
|
|
|
34210
34399
|
candidates.push({
|
|
34211
34400
|
sessionId,
|
|
34212
34401
|
archiveState,
|
|
34213
|
-
transcriptPath:
|
|
34402
|
+
transcriptPath: path12.join(dir, `${sessionId}.jsonl`),
|
|
34214
34403
|
conventionNumber,
|
|
34215
34404
|
mentions: reviewed.mentions,
|
|
34216
34405
|
reviewedUrlForms: reviewed.reviewedUrlForms
|
|
@@ -34342,8 +34531,8 @@ async function backfillWorkspaceSessionPrs(runtime, fetchPullRequests = fetchGit
|
|
|
34342
34531
|
candidate.sessionId,
|
|
34343
34532
|
archiveState
|
|
34344
34533
|
);
|
|
34345
|
-
const transcriptPath =
|
|
34346
|
-
|
|
34534
|
+
const transcriptPath = path12.join(
|
|
34535
|
+
path12.dirname(prPath),
|
|
34347
34536
|
`${candidate.sessionId}.jsonl`
|
|
34348
34537
|
);
|
|
34349
34538
|
const snapshotAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -34986,7 +35175,7 @@ __name(registerStandaloneSessionRoutes, "registerStandaloneSessionRoutes");
|
|
|
34986
35175
|
|
|
34987
35176
|
// packages/cli/src/serve/routes/channel-notify.ts
|
|
34988
35177
|
init_esbuild_shims();
|
|
34989
|
-
import { randomUUID as
|
|
35178
|
+
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
34990
35179
|
function sendDeliveryError(res, error2) {
|
|
34991
35180
|
if (!isChannelDeliveryError(error2)) {
|
|
34992
35181
|
res.status(502).json({
|
|
@@ -35007,7 +35196,7 @@ function parseNotifyBody(body) {
|
|
|
35007
35196
|
);
|
|
35008
35197
|
}
|
|
35009
35198
|
return normalizeChannelDelivery(
|
|
35010
|
-
|
|
35199
|
+
randomUUID9(),
|
|
35011
35200
|
parseChannelDelivery(body["delivery"]),
|
|
35012
35201
|
body["text"]
|
|
35013
35202
|
);
|
|
@@ -35210,7 +35399,7 @@ __name(registerUsageStatsRoutes, "registerUsageStatsRoutes");
|
|
|
35210
35399
|
// packages/cli/src/serve/scheduled-task-keepalive.ts
|
|
35211
35400
|
init_esbuild_shims();
|
|
35212
35401
|
import * as fsSync from "node:fs";
|
|
35213
|
-
import * as
|
|
35402
|
+
import * as path13 from "node:path";
|
|
35214
35403
|
var log = createDebugLogger("SCHED_KEEPALIVE");
|
|
35215
35404
|
function collectBoundSessionIds(tasks) {
|
|
35216
35405
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -35442,8 +35631,8 @@ function startScheduledTaskKeepalive(opts) {
|
|
|
35442
35631
|
opts.runtimeBaseDir,
|
|
35443
35632
|
() => getCronFilePath(boundWorkspace)
|
|
35444
35633
|
);
|
|
35445
|
-
const cronDir =
|
|
35446
|
-
const cronFileName =
|
|
35634
|
+
const cronDir = path13.dirname(cronFilePath);
|
|
35635
|
+
const cronFileName = path13.basename(cronFilePath);
|
|
35447
35636
|
let fileWatcher;
|
|
35448
35637
|
try {
|
|
35449
35638
|
fsSync.mkdirSync(cronDir, { recursive: true });
|
|
@@ -36166,6 +36355,10 @@ function workflowsEnabledForRuntime(runtime, daemonEnv) {
|
|
|
36166
36355
|
}
|
|
36167
36356
|
__name(workflowsEnabledForRuntime, "workflowsEnabledForRuntime");
|
|
36168
36357
|
function registerCapabilitiesRoutes(app, deps) {
|
|
36358
|
+
const configuredPollIntervalMs = Number(
|
|
36359
|
+
deps.daemonEnv["QWEN_SESSION_LIVE_STATE_POLL_INTERVAL_MS"]
|
|
36360
|
+
);
|
|
36361
|
+
const sessionLiveStatePollIntervalMs = Number.isSafeInteger(configuredPollIntervalMs) && configuredPollIntervalMs >= 1e3 && configuredPollIntervalMs <= 2147483647 ? configuredPollIntervalMs : 5e3;
|
|
36169
36362
|
app.get("/capabilities", (_req, res) => {
|
|
36170
36363
|
const entries = deps.workspaceRegistry.listAllEntries().filter(
|
|
36171
36364
|
(entry) => !entry.internal || entry.state === "active" && entry.current !== void 0
|
|
@@ -36182,6 +36375,7 @@ function registerCapabilitiesRoutes(app, deps) {
|
|
|
36182
36375
|
...deps.qwenCodeVersion ? { qwenCodeVersion: deps.qwenCodeVersion } : {},
|
|
36183
36376
|
mode: deps.mode,
|
|
36184
36377
|
features,
|
|
36378
|
+
sessionLiveStatePollIntervalMs,
|
|
36185
36379
|
modelServices: [],
|
|
36186
36380
|
// Surface the primary workspace so clients can omit `cwd` on
|
|
36187
36381
|
// `POST /session`; multi-workspace clients use `workspaces[]`.
|
|
@@ -37242,7 +37436,7 @@ __name(registerUserLanguageRoutes, "registerUserLanguageRoutes");
|
|
|
37242
37436
|
|
|
37243
37437
|
// packages/cli/src/serve/routes/sse-events.ts
|
|
37244
37438
|
init_esbuild_shims();
|
|
37245
|
-
import { randomUUID as
|
|
37439
|
+
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
37246
37440
|
import { performance as performance3 } from "node:perf_hooks";
|
|
37247
37441
|
|
|
37248
37442
|
// packages/cli/src/serve/server/error-response.ts
|
|
@@ -37623,6 +37817,63 @@ function sendBridgeError(res, err, ctx, daemonLog) {
|
|
|
37623
37817
|
});
|
|
37624
37818
|
return;
|
|
37625
37819
|
}
|
|
37820
|
+
if (err instanceof SessionResetPendingError) {
|
|
37821
|
+
res.status(409).json({
|
|
37822
|
+
error: err.message,
|
|
37823
|
+
code: "worktree_reset_active",
|
|
37824
|
+
sessionId: err.sessionId
|
|
37825
|
+
});
|
|
37826
|
+
return;
|
|
37827
|
+
}
|
|
37828
|
+
if (err instanceof WorktreeSessionSupersededError) {
|
|
37829
|
+
res.status(409).json({
|
|
37830
|
+
error: err.message,
|
|
37831
|
+
code: "worktree_session_superseded",
|
|
37832
|
+
sessionId: err.sessionId,
|
|
37833
|
+
replacementSessionId: err.replacementSessionId
|
|
37834
|
+
});
|
|
37835
|
+
return;
|
|
37836
|
+
}
|
|
37837
|
+
if (err instanceof WorktreeMarkerMissingError) {
|
|
37838
|
+
res.status(409).json({
|
|
37839
|
+
error: err.message,
|
|
37840
|
+
code: "worktree_marker_missing",
|
|
37841
|
+
sessionId: err.sessionId
|
|
37842
|
+
});
|
|
37843
|
+
return;
|
|
37844
|
+
}
|
|
37845
|
+
if (err instanceof WorktreeResetInterruptedError) {
|
|
37846
|
+
res.status(409).json({
|
|
37847
|
+
error: err.message,
|
|
37848
|
+
code: "worktree_reset_interrupted",
|
|
37849
|
+
sessionId: err.sessionId
|
|
37850
|
+
});
|
|
37851
|
+
return;
|
|
37852
|
+
}
|
|
37853
|
+
if (err instanceof WorktreeResetActiveError) {
|
|
37854
|
+
res.status(409).json({
|
|
37855
|
+
error: err.message,
|
|
37856
|
+
code: "worktree_reset_active",
|
|
37857
|
+
sessionId: err.sessionId
|
|
37858
|
+
});
|
|
37859
|
+
return;
|
|
37860
|
+
}
|
|
37861
|
+
if (err instanceof WorktreeResetUnsupportedError) {
|
|
37862
|
+
res.status(409).json({
|
|
37863
|
+
error: err.message,
|
|
37864
|
+
code: "worktree_reset_unsupported",
|
|
37865
|
+
sessionId: err.sessionId
|
|
37866
|
+
});
|
|
37867
|
+
return;
|
|
37868
|
+
}
|
|
37869
|
+
if (err instanceof WorktreeResetInvalidStateError) {
|
|
37870
|
+
res.status(409).json({
|
|
37871
|
+
error: err.message,
|
|
37872
|
+
code: "worktree_reset_invalid_state",
|
|
37873
|
+
sessionId: err.sessionId
|
|
37874
|
+
});
|
|
37875
|
+
return;
|
|
37876
|
+
}
|
|
37626
37877
|
if (err instanceof TrustGateError) {
|
|
37627
37878
|
res.status(403).json({
|
|
37628
37879
|
error: err.message,
|
|
@@ -38088,7 +38339,7 @@ function registerSseEventsRoutes(app, deps) {
|
|
|
38088
38339
|
app.get("/session/:id/events", async (req, res) => {
|
|
38089
38340
|
const sessionId = req.params["id"];
|
|
38090
38341
|
const diagnosticSessionId = boundedDiagnosticString(sessionId);
|
|
38091
|
-
const streamId =
|
|
38342
|
+
const streamId = randomUUID10();
|
|
38092
38343
|
const clientId = parseSseClientId(req.headers["x-qwen-client-id"]);
|
|
38093
38344
|
const connectReason = parseSseConnectReason(req.query["connectReason"]);
|
|
38094
38345
|
const previousStreamId = parsePreviousSseStreamId(
|
|
@@ -38980,7 +39231,7 @@ __name(registerWorkspaceModelsRoutes, "registerWorkspaceModelsRoutes");
|
|
|
38980
39231
|
// packages/cli/src/serve/routes/a2ui-action.ts
|
|
38981
39232
|
init_esbuild_shims();
|
|
38982
39233
|
import * as fsp4 from "node:fs/promises";
|
|
38983
|
-
import * as
|
|
39234
|
+
import * as path14 from "node:path";
|
|
38984
39235
|
var A2UI_MIME = "application/a2ui+json";
|
|
38985
39236
|
var ACTION_TOOL = "action";
|
|
38986
39237
|
var CALL_TIMEOUT_MS = 15e3;
|
|
@@ -39003,7 +39254,7 @@ __name(usableServerConfig, "usableServerConfig");
|
|
|
39003
39254
|
async function findFromSettingsFile(workspaceCwd) {
|
|
39004
39255
|
try {
|
|
39005
39256
|
const raw = await fsp4.readFile(
|
|
39006
|
-
|
|
39257
|
+
path14.join(workspaceCwd, ".qwen", "settings.json"),
|
|
39007
39258
|
"utf8"
|
|
39008
39259
|
);
|
|
39009
39260
|
const settings = JSON.parse(raw);
|
|
@@ -39164,7 +39415,7 @@ __name(registerA2uiActionRoutes, "registerA2uiActionRoutes");
|
|
|
39164
39415
|
|
|
39165
39416
|
// packages/cli/src/serve/server/fs-factory.ts
|
|
39166
39417
|
init_esbuild_shims();
|
|
39167
|
-
import * as
|
|
39418
|
+
import * as path15 from "node:path";
|
|
39168
39419
|
var IDE_WORKSPACE_PATH_ENV_VAR = "QWEN_CODE_IDE_WORKSPACE_PATH";
|
|
39169
39420
|
var NEW_FILE_MODE_ENV_VAR = "QWEN_SERVE_NEW_FILE_MODE";
|
|
39170
39421
|
function parseNewFileModePolicy(env = process.env) {
|
|
@@ -39253,14 +39504,14 @@ function parseIdeWorkspacePathEnv(value) {
|
|
|
39253
39504
|
const parsed = JSON.parse(value);
|
|
39254
39505
|
if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
|
|
39255
39506
|
return parsed.filter(
|
|
39256
|
-
(workspace) => workspace.length > 0 &&
|
|
39507
|
+
(workspace) => workspace.length > 0 && path15.isAbsolute(workspace)
|
|
39257
39508
|
);
|
|
39258
39509
|
}
|
|
39259
39510
|
throw new Error("IDE workspace path JSON must be a string array");
|
|
39260
39511
|
} catch {
|
|
39261
39512
|
}
|
|
39262
39513
|
}
|
|
39263
|
-
return value.split(
|
|
39514
|
+
return value.split(path15.delimiter).filter((workspace) => workspace.length > 0 && path15.isAbsolute(workspace));
|
|
39264
39515
|
}
|
|
39265
39516
|
__name(parseIdeWorkspacePathEnv, "parseIdeWorkspacePathEnv");
|
|
39266
39517
|
function dropNestedWorkspacesPreservingPrimary(workspaces) {
|
|
@@ -39749,7 +40000,7 @@ __name(registerWorkspaceQualifiedLifecycleRoutes, "registerWorkspaceQualifiedLif
|
|
|
39749
40000
|
init_esbuild_shims();
|
|
39750
40001
|
import { readdir as readdir3, stat as stat2 } from "node:fs/promises";
|
|
39751
40002
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
39752
|
-
import { basename as basename7, dirname as
|
|
40003
|
+
import { basename as basename7, dirname as dirname8, isAbsolute as isAbsolute9, join as join11, resolve as resolve5, sep as sep4 } from "node:path";
|
|
39753
40004
|
var MAX_PATH_SUGGESTIONS = 50;
|
|
39754
40005
|
function registerWorkspaceManagementRoutes(app, deps) {
|
|
39755
40006
|
const {
|
|
@@ -40138,7 +40389,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
|
|
|
40138
40389
|
});
|
|
40139
40390
|
return;
|
|
40140
40391
|
}
|
|
40141
|
-
if (!
|
|
40392
|
+
if (!isAbsolute9(prefix)) {
|
|
40142
40393
|
res.status(400).json({
|
|
40143
40394
|
error: "`prefix` must be an absolute path",
|
|
40144
40395
|
code: "invalid_prefix"
|
|
@@ -40146,7 +40397,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
|
|
|
40146
40397
|
return;
|
|
40147
40398
|
}
|
|
40148
40399
|
const endsWithSep = prefix.endsWith("/") || process.platform === "win32" && prefix.endsWith("\\");
|
|
40149
|
-
const dir = endsWithSep ?
|
|
40400
|
+
const dir = endsWithSep ? join11(prefix, ".") : dirname8(prefix);
|
|
40150
40401
|
const filter = endsWithSep ? "" : basename7(prefix);
|
|
40151
40402
|
const filterLower = filter.toLowerCase();
|
|
40152
40403
|
const suggestions = [];
|
|
@@ -40162,7 +40413,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
|
|
|
40162
40413
|
let isDir = entry.isDirectory();
|
|
40163
40414
|
if (!isDir && entry.isSymbolicLink()) {
|
|
40164
40415
|
try {
|
|
40165
|
-
isDir = (await stat2(
|
|
40416
|
+
isDir = (await stat2(join11(dir, entry.name))).isDirectory();
|
|
40166
40417
|
} catch {
|
|
40167
40418
|
continue;
|
|
40168
40419
|
}
|
|
@@ -40172,7 +40423,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
|
|
|
40172
40423
|
truncated = true;
|
|
40173
40424
|
break;
|
|
40174
40425
|
}
|
|
40175
|
-
suggestions.push({ name: entry.name, path:
|
|
40426
|
+
suggestions.push({ name: entry.name, path: join11(dir, entry.name) });
|
|
40176
40427
|
}
|
|
40177
40428
|
} catch {
|
|
40178
40429
|
}
|
|
@@ -45646,7 +45897,7 @@ init_esbuild_shims();
|
|
|
45646
45897
|
|
|
45647
45898
|
// packages/cli/src/serve/live/live-host-coordinator.ts
|
|
45648
45899
|
init_esbuild_shims();
|
|
45649
|
-
import { randomUUID as
|
|
45900
|
+
import { randomUUID as randomUUID11, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
45650
45901
|
var DEFAULT_HELLO_TIMEOUT_MS = 5e3;
|
|
45651
45902
|
var DEFAULT_HEARTBEAT_INTERVAL_MS = 5e3;
|
|
45652
45903
|
var DEFAULT_HEARTBEAT_TIMEOUT_MS = 15e3;
|
|
@@ -45829,7 +46080,7 @@ __name(projectStatusForHost, "projectStatusForHost");
|
|
|
45829
46080
|
var LiveHostCoordinator = class {
|
|
45830
46081
|
constructor(options) {
|
|
45831
46082
|
this.options = options;
|
|
45832
|
-
this.daemonInstanceNonce = options.daemonInstanceNonce ??
|
|
46083
|
+
this.daemonInstanceNonce = options.daemonInstanceNonce ?? randomUUID11();
|
|
45833
46084
|
this.handlers = options.handlers ?? {};
|
|
45834
46085
|
this.now = options.now ?? Date.now;
|
|
45835
46086
|
this.helloTimeoutMs = options.helloTimeoutMs ?? DEFAULT_HELLO_TIMEOUT_MS;
|
|
@@ -45860,6 +46111,7 @@ var LiveHostCoordinator = class {
|
|
|
45860
46111
|
};
|
|
45861
46112
|
call;
|
|
45862
46113
|
pendingStartMode;
|
|
46114
|
+
actionGeneration = 0;
|
|
45863
46115
|
nextEpoch = 0;
|
|
45864
46116
|
inputMuted = false;
|
|
45865
46117
|
outputMuted = false;
|
|
@@ -45880,6 +46132,7 @@ var LiveHostCoordinator = class {
|
|
|
45880
46132
|
return this.getStatus();
|
|
45881
46133
|
}
|
|
45882
46134
|
async deactivate() {
|
|
46135
|
+
++this.actionGeneration;
|
|
45883
46136
|
this.pendingStartMode = void 0;
|
|
45884
46137
|
if (this.call) {
|
|
45885
46138
|
const stopped = new Promise((resolve7) => {
|
|
@@ -45995,6 +46248,18 @@ var LiveHostCoordinator = class {
|
|
|
45995
46248
|
} : {}
|
|
45996
46249
|
};
|
|
45997
46250
|
}
|
|
46251
|
+
async requestStart(mode) {
|
|
46252
|
+
const generation = ++this.actionGeneration;
|
|
46253
|
+
this.pendingStartMode = void 0;
|
|
46254
|
+
try {
|
|
46255
|
+
await this.handlers.beforeStart?.();
|
|
46256
|
+
} catch (error2) {
|
|
46257
|
+
if (generation !== this.actionGeneration) return this.getStatus();
|
|
46258
|
+
throw error2;
|
|
46259
|
+
}
|
|
46260
|
+
if (generation !== this.actionGeneration) return this.getStatus();
|
|
46261
|
+
return this.start(mode).status;
|
|
46262
|
+
}
|
|
45998
46263
|
start(mode) {
|
|
45999
46264
|
const status = this.getStatus();
|
|
46000
46265
|
if (!status.available) throw new LiveUnavailableError(status);
|
|
@@ -46021,7 +46286,7 @@ var LiveHostCoordinator = class {
|
|
|
46021
46286
|
startCall(mode) {
|
|
46022
46287
|
const call = {
|
|
46023
46288
|
epoch: ++this.nextEpoch,
|
|
46024
|
-
callId:
|
|
46289
|
+
callId: randomUUID11(),
|
|
46025
46290
|
mode,
|
|
46026
46291
|
state: "starting",
|
|
46027
46292
|
pendingPermission: false,
|
|
@@ -46046,6 +46311,7 @@ var LiveHostCoordinator = class {
|
|
|
46046
46311
|
return { epoch: call.epoch, callId: call.callId, status: this.getStatus() };
|
|
46047
46312
|
}
|
|
46048
46313
|
stop() {
|
|
46314
|
+
++this.actionGeneration;
|
|
46049
46315
|
this.pendingStartMode = void 0;
|
|
46050
46316
|
if (this.call) this.beginCallStop(this.call);
|
|
46051
46317
|
return this.getStatus();
|
|
@@ -46080,7 +46346,7 @@ var LiveHostCoordinator = class {
|
|
|
46080
46346
|
new Error("Qwen Live Host must be connected to change the shortcut.")
|
|
46081
46347
|
);
|
|
46082
46348
|
}
|
|
46083
|
-
const requestId =
|
|
46349
|
+
const requestId = randomUUID11();
|
|
46084
46350
|
return new Promise((resolve7, reject) => {
|
|
46085
46351
|
const timer = setTimeout(() => {
|
|
46086
46352
|
this.rejectPendingShortcut(
|
|
@@ -46170,7 +46436,7 @@ var LiveHostCoordinator = class {
|
|
|
46170
46436
|
)
|
|
46171
46437
|
);
|
|
46172
46438
|
}
|
|
46173
|
-
const requestId =
|
|
46439
|
+
const requestId = randomUUID11();
|
|
46174
46440
|
return new Promise((resolve7, reject) => {
|
|
46175
46441
|
const timer = setTimeout(() => {
|
|
46176
46442
|
this.pendingAppshots.delete(requestId);
|
|
@@ -46235,6 +46501,7 @@ var LiveHostCoordinator = class {
|
|
|
46235
46501
|
this.sendHost({ type: "host.clear_output", epoch });
|
|
46236
46502
|
}
|
|
46237
46503
|
dispose() {
|
|
46504
|
+
++this.actionGeneration;
|
|
46238
46505
|
this.pendingStartMode = void 0;
|
|
46239
46506
|
if (this.call) this.finishCall(this.call);
|
|
46240
46507
|
if (this.host) {
|
|
@@ -46459,19 +46726,14 @@ var LiveHostCoordinator = class {
|
|
|
46459
46726
|
}
|
|
46460
46727
|
}
|
|
46461
46728
|
startFromHost(mode) {
|
|
46462
|
-
|
|
46463
|
-
this.start(mode);
|
|
46464
|
-
} catch (error2) {
|
|
46729
|
+
void this.requestStart(mode).catch((error2) => {
|
|
46465
46730
|
if (error2 instanceof LiveUnavailableError) {
|
|
46466
46731
|
this.sendState(error2.status);
|
|
46467
46732
|
return;
|
|
46468
46733
|
}
|
|
46469
|
-
this.
|
|
46470
|
-
|
|
46471
|
-
|
|
46472
|
-
message: "Live Voice failed to start."
|
|
46473
|
-
});
|
|
46474
|
-
}
|
|
46734
|
+
this.lastCallError = error2 instanceof ConversationRuntimeOwnershipError ? error2.message : "Live Voice failed to start.";
|
|
46735
|
+
this.sendState(this.buildStatus(false));
|
|
46736
|
+
});
|
|
46475
46737
|
}
|
|
46476
46738
|
handleAudioFrame(lease, data) {
|
|
46477
46739
|
if (!lease.hello) {
|
|
@@ -46513,7 +46775,7 @@ var LiveHostCoordinator = class {
|
|
|
46513
46775
|
this.disconnectHost(lease, 4008, "Live Host heartbeat timed out.");
|
|
46514
46776
|
return;
|
|
46515
46777
|
}
|
|
46516
|
-
const pingId =
|
|
46778
|
+
const pingId = randomUUID11();
|
|
46517
46779
|
lease.pingId = pingId;
|
|
46518
46780
|
this.sendHost({ type: "host.ping", pingId });
|
|
46519
46781
|
}
|
|
@@ -46598,9 +46860,10 @@ var LiveHostCoordinator = class {
|
|
|
46598
46860
|
this.broadcastState();
|
|
46599
46861
|
}
|
|
46600
46862
|
stopForReadinessLoss() {
|
|
46863
|
+
++this.actionGeneration;
|
|
46864
|
+
this.pendingStartMode = void 0;
|
|
46601
46865
|
const call = this.call;
|
|
46602
46866
|
if (!call) return;
|
|
46603
|
-
this.pendingStartMode = void 0;
|
|
46604
46867
|
this.beginCallStop(call);
|
|
46605
46868
|
}
|
|
46606
46869
|
disconnectHost(lease, code, reason) {
|
|
@@ -46694,8 +46957,7 @@ function registerLiveRoutes(app, deps) {
|
|
|
46694
46957
|
});
|
|
46695
46958
|
app.post("/live/start", deps.mutate(), async (_req, res) => {
|
|
46696
46959
|
try {
|
|
46697
|
-
await deps.
|
|
46698
|
-
res.status(200).json(deps.coordinator.start("resume").status);
|
|
46960
|
+
res.status(200).json(await deps.coordinator.requestStart("resume"));
|
|
46699
46961
|
} catch (error2) {
|
|
46700
46962
|
if (sendUnavailable(res, error2)) return;
|
|
46701
46963
|
throw error2;
|
|
@@ -46703,8 +46965,7 @@ function registerLiveRoutes(app, deps) {
|
|
|
46703
46965
|
});
|
|
46704
46966
|
app.post("/live/new", deps.mutate(), async (_req, res) => {
|
|
46705
46967
|
try {
|
|
46706
|
-
await deps.
|
|
46707
|
-
res.status(200).json(deps.coordinator.start("new").status);
|
|
46968
|
+
res.status(200).json(await deps.coordinator.requestStart("new"));
|
|
46708
46969
|
} catch (error2) {
|
|
46709
46970
|
if (sendUnavailable(res, error2)) return;
|
|
46710
46971
|
throw error2;
|
|
@@ -46781,7 +47042,7 @@ init_esbuild_shims();
|
|
|
46781
47042
|
|
|
46782
47043
|
// packages/cli/src/serve/live/live-setup-controller.ts
|
|
46783
47044
|
init_esbuild_shims();
|
|
46784
|
-
import { randomUUID as
|
|
47045
|
+
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
46785
47046
|
|
|
46786
47047
|
// packages/cli/src/serve/live/provider-credentials.ts
|
|
46787
47048
|
init_esbuild_shims();
|
|
@@ -46879,7 +47140,7 @@ __name(resolveLiveProviderCredential, "resolveLiveProviderCredential");
|
|
|
46879
47140
|
|
|
46880
47141
|
// packages/cli/src/serve/live/qwen-realtime-session.ts
|
|
46881
47142
|
init_esbuild_shims();
|
|
46882
|
-
import { randomUUID as
|
|
47143
|
+
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
46883
47144
|
var QWEN_REALTIME_LIMITS = {
|
|
46884
47145
|
maxInputAudioFrameBytes: 64 * 1024,
|
|
46885
47146
|
maxOutputAudioFrameBytes: 256 * 1024,
|
|
@@ -47294,7 +47555,7 @@ function openQwenRealtimeSession(config, callbacks = {}, deps = {}) {
|
|
|
47294
47555
|
const sendJson = /* @__PURE__ */ __name((body) => {
|
|
47295
47556
|
if (terminal || closedByClient || ws.readyState !== ws.OPEN) return false;
|
|
47296
47557
|
try {
|
|
47297
|
-
ws.send(JSON.stringify({ event_id:
|
|
47558
|
+
ws.send(JSON.stringify({ event_id: randomUUID12(), ...body }));
|
|
47298
47559
|
return true;
|
|
47299
47560
|
} catch (error2) {
|
|
47300
47561
|
fail(
|
|
@@ -48657,7 +48918,7 @@ async function validateCredential(credential) {
|
|
|
48657
48918
|
apiKey: credential.apiKey,
|
|
48658
48919
|
model: credential.realtimeModel,
|
|
48659
48920
|
voice: credential.voice,
|
|
48660
|
-
callEpoch: `setup-${
|
|
48921
|
+
callEpoch: `setup-${randomUUID13()}`
|
|
48661
48922
|
});
|
|
48662
48923
|
session.close({ discardPendingInput: true });
|
|
48663
48924
|
}
|
|
@@ -48964,11 +49225,11 @@ __name(registerLiveSetupRoutes, "registerLiveSetupRoutes");
|
|
|
48964
49225
|
// packages/cli/src/serve/live/live-host-installer.ts
|
|
48965
49226
|
init_esbuild_shims();
|
|
48966
49227
|
import { execFile as execFile2 } from "node:child_process";
|
|
48967
|
-
import { createHash as createHash4, randomUUID as
|
|
48968
|
-
import * as
|
|
49228
|
+
import { createHash as createHash4, randomUUID as randomUUID14 } from "node:crypto";
|
|
49229
|
+
import * as fs8 from "node:fs";
|
|
48969
49230
|
import * as fsp5 from "node:fs/promises";
|
|
48970
49231
|
import * as os2 from "node:os";
|
|
48971
|
-
import * as
|
|
49232
|
+
import * as path16 from "node:path";
|
|
48972
49233
|
import { Readable, Transform } from "node:stream";
|
|
48973
49234
|
import { pipeline } from "node:stream/promises";
|
|
48974
49235
|
import { promisify as promisify2 } from "node:util";
|
|
@@ -49048,7 +49309,7 @@ async function readBundleValue(appPath, key) {
|
|
|
49048
49309
|
"raw",
|
|
49049
49310
|
"-o",
|
|
49050
49311
|
"-",
|
|
49051
|
-
|
|
49312
|
+
path16.join(appPath, "Contents", "Info.plist")
|
|
49052
49313
|
]);
|
|
49053
49314
|
}
|
|
49054
49315
|
__name(readBundleValue, "readBundleValue");
|
|
@@ -49156,7 +49417,7 @@ async function downloadAsset(asset, url, destination, onProgress, fetchImpl) {
|
|
|
49156
49417
|
await pipeline(
|
|
49157
49418
|
Readable.fromWeb(response.body),
|
|
49158
49419
|
guard,
|
|
49159
|
-
|
|
49420
|
+
fs8.createWriteStream(destination, { flags: "wx", mode: 384 })
|
|
49160
49421
|
);
|
|
49161
49422
|
if (received !== asset.size || hash.digest("hex") !== asset.sha256) {
|
|
49162
49423
|
throw new Error("Live Host checksum verification failed.");
|
|
@@ -49190,13 +49451,13 @@ async function downloadLiveHostRelease(currentArchitecture, destination, onProgr
|
|
|
49190
49451
|
__name(downloadLiveHostRelease, "downloadLiveHostRelease");
|
|
49191
49452
|
async function installLatestHost(currentArchitecture, onStatus) {
|
|
49192
49453
|
const temporaryDirectory = await fsp5.mkdtemp(
|
|
49193
|
-
|
|
49454
|
+
path16.join(os2.tmpdir(), "qwen-live-host-")
|
|
49194
49455
|
);
|
|
49195
|
-
const archivePath =
|
|
49196
|
-
const extractedPath =
|
|
49197
|
-
const candidatePath =
|
|
49198
|
-
const stagingPath = `/Applications/.Qwen Live Host.install-${
|
|
49199
|
-
const backupPath = `/Applications/.Qwen Live Host.backup-${
|
|
49456
|
+
const archivePath = path16.join(temporaryDirectory, "Qwen-Live-Host.zip");
|
|
49457
|
+
const extractedPath = path16.join(temporaryDirectory, "extracted");
|
|
49458
|
+
const candidatePath = path16.join(extractedPath, LIVE_HOST_APP_NAME);
|
|
49459
|
+
const stagingPath = `/Applications/.Qwen Live Host.install-${randomUUID14()}.app`;
|
|
49460
|
+
const backupPath = `/Applications/.Qwen Live Host.backup-${randomUUID14()}.app`;
|
|
49200
49461
|
let movedExisting = false;
|
|
49201
49462
|
let installedCandidate = false;
|
|
49202
49463
|
try {
|
|
@@ -49347,15 +49608,15 @@ var LiveHostInstaller = class {
|
|
|
49347
49608
|
|
|
49348
49609
|
// packages/cli/src/serve/live/live-session-coordinator.ts
|
|
49349
49610
|
init_esbuild_shims();
|
|
49350
|
-
import { createHash as createHash5, randomUUID as
|
|
49611
|
+
import { createHash as createHash5, randomUUID as randomUUID15 } from "node:crypto";
|
|
49351
49612
|
import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync2 } from "node:fs";
|
|
49352
|
-
import { join as
|
|
49613
|
+
import { join as join14 } from "node:path";
|
|
49353
49614
|
|
|
49354
49615
|
// packages/cli/src/serve/live/realtime-startup-context.ts
|
|
49355
49616
|
init_esbuild_shims();
|
|
49356
49617
|
import { readdirSync } from "node:fs";
|
|
49357
49618
|
import { homedir } from "node:os";
|
|
49358
|
-
import { basename as basename8, join as
|
|
49619
|
+
import { basename as basename8, join as join13 } from "node:path";
|
|
49359
49620
|
var STARTUP_CONTEXT_HEADER = "Startup context from Qwen Code.\nThis is background context about recent work and machine/workspace layout. It may be incomplete or stale. Use it to inform responses, and do not repeat it back unless relevant.";
|
|
49360
49621
|
var CURRENT_THREAD_SECTION_TOKEN_BUDGET = 1200;
|
|
49361
49622
|
var RECENT_WORK_SECTION_TOKEN_BUDGET = 2200;
|
|
@@ -49597,7 +49858,7 @@ function collectTreeLines(directory, depth, lines) {
|
|
|
49597
49858
|
const indent = " ".repeat(depth);
|
|
49598
49859
|
lines.push(`${indent}- ${entry.name}${entry.isDirectory() ? "/" : ""}`);
|
|
49599
49860
|
if (entry.isDirectory()) {
|
|
49600
|
-
collectTreeLines(
|
|
49861
|
+
collectTreeLines(join13(directory, entry.name), depth + 1, lines);
|
|
49601
49862
|
}
|
|
49602
49863
|
}
|
|
49603
49864
|
if (entries.length > DIR_ENTRY_LIMIT) {
|
|
@@ -49716,7 +49977,7 @@ function openLiveAudioCapture(source, identifier) {
|
|
|
49716
49977
|
try {
|
|
49717
49978
|
mkdirSync2(directory, { recursive: true, mode: 448 });
|
|
49718
49979
|
const safeIdentifier = identifier.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
49719
|
-
const path19 =
|
|
49980
|
+
const path19 = join14(
|
|
49720
49981
|
directory,
|
|
49721
49982
|
`${source}-${Date.now()}-${safeIdentifier}.pcm`
|
|
49722
49983
|
);
|
|
@@ -50077,7 +50338,7 @@ var LiveSessionCoordinator = class {
|
|
|
50077
50338
|
context.speechInProgress = true;
|
|
50078
50339
|
context.inputCommitPending = true;
|
|
50079
50340
|
context.inputAwaitingResponse = false;
|
|
50080
|
-
const partialItemId = itemId ?? `partial:${
|
|
50341
|
+
const partialItemId = itemId ?? `partial:${randomUUID15()}`;
|
|
50081
50342
|
context.activePartialInputItemId = partialItemId;
|
|
50082
50343
|
if (!context.partialInputTranscripts.has(partialItemId)) {
|
|
50083
50344
|
context.partialInputTranscripts.set(partialItemId, "");
|
|
@@ -50107,7 +50368,7 @@ var LiveSessionCoordinator = class {
|
|
|
50107
50368
|
}, "onInputCommitted"),
|
|
50108
50369
|
onInputTranscriptDelta: /* @__PURE__ */ __name(({ itemId, text }) => {
|
|
50109
50370
|
if (this.isCurrentSocket(context, generation)) {
|
|
50110
|
-
const partialItemId = itemId ?? context.activePartialInputItemId ?? `partial:${
|
|
50371
|
+
const partialItemId = itemId ?? context.activePartialInputItemId ?? `partial:${randomUUID15()}`;
|
|
50111
50372
|
context.activePartialInputItemId = partialItemId;
|
|
50112
50373
|
context.partialInputTranscripts.set(partialItemId, text);
|
|
50113
50374
|
this.options.host.setTranscript?.(context.epoch, text);
|
|
@@ -50117,7 +50378,7 @@ var LiveSessionCoordinator = class {
|
|
|
50117
50378
|
if (this.isCurrentSocket(context, generation)) {
|
|
50118
50379
|
context.speechInProgress = false;
|
|
50119
50380
|
context.inputCommitPending = false;
|
|
50120
|
-
const completedItemId = itemId ?? context.activePartialInputItemId ?? `unattributed:${
|
|
50381
|
+
const completedItemId = itemId ?? context.activePartialInputItemId ?? `unattributed:${randomUUID15()}`;
|
|
50121
50382
|
context.partialInputTranscripts.delete(completedItemId);
|
|
50122
50383
|
if (context.activePartialInputItemId === completedItemId) {
|
|
50123
50384
|
context.activePartialInputItemId = void 0;
|
|
@@ -50849,7 +51110,7 @@ var LiveSessionCoordinator = class {
|
|
|
50849
51110
|
const runtime = context.runtime;
|
|
50850
51111
|
if (!runtime) throw new Error("Conversation workspace is unavailable.");
|
|
50851
51112
|
const bridge = runtime.bridge;
|
|
50852
|
-
const promptId =
|
|
51113
|
+
const promptId = randomUUID15();
|
|
50853
51114
|
const lastEventId = bridge.getSessionLastEventId(locator.sessionId);
|
|
50854
51115
|
const turnAbort = new AbortController();
|
|
50855
51116
|
this.inFlightTurnAborts.add(turnAbort);
|
|
@@ -51166,7 +51427,7 @@ var LiveSessionCoordinator = class {
|
|
|
51166
51427
|
|
|
51167
51428
|
// packages/cli/src/serve/live/live-task-service.ts
|
|
51168
51429
|
init_esbuild_shims();
|
|
51169
|
-
import { randomUUID as
|
|
51430
|
+
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
51170
51431
|
var DEFAULT_LIST_LIMIT = 20;
|
|
51171
51432
|
var DEFAULT_READ_TURN_LIMIT = 3;
|
|
51172
51433
|
var DEFAULT_WAIT_TIMEOUT_MS = 12e4;
|
|
@@ -51852,7 +52113,7 @@ var LiveTaskService = class {
|
|
|
51852
52113
|
const record = target;
|
|
51853
52114
|
if (record["type"] === "projectless") {
|
|
51854
52115
|
const created = await this.getStandaloneSessionService().createWithInitialPrompt(
|
|
51855
|
-
{ sessionId:
|
|
52116
|
+
{ sessionId: randomUUID16() },
|
|
51856
52117
|
prompt
|
|
51857
52118
|
);
|
|
51858
52119
|
return {
|
|
@@ -51904,7 +52165,7 @@ var LiveTaskService = class {
|
|
|
51904
52165
|
{ sessionId, prompt: [{ type: "text", text: prompt }] },
|
|
51905
52166
|
void 0,
|
|
51906
52167
|
{
|
|
51907
|
-
promptId:
|
|
52168
|
+
promptId: randomUUID16(),
|
|
51908
52169
|
onPromptAdmitted: /* @__PURE__ */ __name(() => {
|
|
51909
52170
|
admitted = true;
|
|
51910
52171
|
onAdmitted?.();
|
|
@@ -52177,7 +52438,7 @@ var ConversationRuntimeManager = class {
|
|
|
52177
52438
|
}
|
|
52178
52439
|
async ensureOnce() {
|
|
52179
52440
|
this.assertNotTerminal();
|
|
52180
|
-
await this.options.
|
|
52441
|
+
if (!this.runtime) await this.options.checkLegacyOwner();
|
|
52181
52442
|
this.assertNotTerminal();
|
|
52182
52443
|
const root = await this.revalidateRoot();
|
|
52183
52444
|
this.assertNotTerminal();
|
|
@@ -52268,6 +52529,226 @@ var ConversationRuntimeManager = class {
|
|
|
52268
52529
|
}
|
|
52269
52530
|
};
|
|
52270
52531
|
|
|
52532
|
+
// packages/cli/src/serve/conversations/conversation-runtime-ownership.ts
|
|
52533
|
+
init_esbuild_shims();
|
|
52534
|
+
import { constants as fsConstants3 } from "node:fs";
|
|
52535
|
+
import * as fs9 from "node:fs/promises";
|
|
52536
|
+
import * as path17 from "node:path";
|
|
52537
|
+
var OWNER_DIRECTORY = "conversations";
|
|
52538
|
+
var OWNER_FILE = "runtime-owner.json";
|
|
52539
|
+
var OWNER_LOCK = ".runtime-owner.lock";
|
|
52540
|
+
var MAX_OWNER_BYTES = 4 * 1024;
|
|
52541
|
+
var NONCE_PATTERN = /^[A-Za-z0-9_-]{16,256}$/;
|
|
52542
|
+
var DEFAULT_HANDOFF_GRACE_MS = 1e3;
|
|
52543
|
+
var UnsafeOwnershipStateError = class extends Error {
|
|
52544
|
+
static {
|
|
52545
|
+
__name(this, "UnsafeOwnershipStateError");
|
|
52546
|
+
}
|
|
52547
|
+
};
|
|
52548
|
+
function getConversationRuntimeOwnerPath(stableBaseDir) {
|
|
52549
|
+
return path17.join(stableBaseDir, OWNER_DIRECTORY, OWNER_FILE);
|
|
52550
|
+
}
|
|
52551
|
+
__name(getConversationRuntimeOwnerPath, "getConversationRuntimeOwnerPath");
|
|
52552
|
+
function processIsAlive(pid) {
|
|
52553
|
+
try {
|
|
52554
|
+
process.kill(pid, 0);
|
|
52555
|
+
return true;
|
|
52556
|
+
} catch (error2) {
|
|
52557
|
+
return error2.code !== "ESRCH";
|
|
52558
|
+
}
|
|
52559
|
+
}
|
|
52560
|
+
__name(processIsAlive, "processIsAlive");
|
|
52561
|
+
function delay2(milliseconds) {
|
|
52562
|
+
return new Promise((resolve7) => {
|
|
52563
|
+
setTimeout(resolve7, milliseconds);
|
|
52564
|
+
});
|
|
52565
|
+
}
|
|
52566
|
+
__name(delay2, "delay");
|
|
52567
|
+
function isMissing2(error2) {
|
|
52568
|
+
return error2.code === "ENOENT";
|
|
52569
|
+
}
|
|
52570
|
+
__name(isMissing2, "isMissing");
|
|
52571
|
+
function assertOwnerRecord(value) {
|
|
52572
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
52573
|
+
throw new UnsafeOwnershipStateError();
|
|
52574
|
+
}
|
|
52575
|
+
const keys = Object.keys(value).sort();
|
|
52576
|
+
if (keys.length !== 3 || keys[0] !== "instanceNonce" || keys[1] !== "pid" || keys[2] !== "version") {
|
|
52577
|
+
throw new UnsafeOwnershipStateError();
|
|
52578
|
+
}
|
|
52579
|
+
const record = value;
|
|
52580
|
+
if (record["version"] !== 1 || !Number.isSafeInteger(record["pid"]) || record["pid"] <= 0 || typeof record["instanceNonce"] !== "string" || !NONCE_PATTERN.test(record["instanceNonce"])) {
|
|
52581
|
+
throw new UnsafeOwnershipStateError();
|
|
52582
|
+
}
|
|
52583
|
+
return {
|
|
52584
|
+
version: 1,
|
|
52585
|
+
pid: record["pid"],
|
|
52586
|
+
instanceNonce: record["instanceNonce"]
|
|
52587
|
+
};
|
|
52588
|
+
}
|
|
52589
|
+
__name(assertOwnerRecord, "assertOwnerRecord");
|
|
52590
|
+
function sameRecord(left, right) {
|
|
52591
|
+
return left.version === right.version && left.pid === right.pid && left.instanceNonce === right.instanceNonce;
|
|
52592
|
+
}
|
|
52593
|
+
__name(sameRecord, "sameRecord");
|
|
52594
|
+
async function inspectDirectory(directory, requirePrivateMode) {
|
|
52595
|
+
const stat3 = await fs9.lstat(directory);
|
|
52596
|
+
if (!stat3.isDirectory() || stat3.isSymbolicLink()) {
|
|
52597
|
+
throw new UnsafeOwnershipStateError();
|
|
52598
|
+
}
|
|
52599
|
+
if (process.platform !== "win32" && (typeof process.getuid === "function" && stat3.uid !== process.getuid() || requirePrivateMode && (stat3.mode & 511) !== 448)) {
|
|
52600
|
+
throw new UnsafeOwnershipStateError();
|
|
52601
|
+
}
|
|
52602
|
+
return { dev: stat3.dev, ino: stat3.ino };
|
|
52603
|
+
}
|
|
52604
|
+
__name(inspectDirectory, "inspectDirectory");
|
|
52605
|
+
async function assertDirectoryIdentity(directory, expected, requirePrivateMode = true) {
|
|
52606
|
+
const current = await inspectDirectory(directory, requirePrivateMode);
|
|
52607
|
+
if (current.dev !== expected.dev || current.ino !== expected.ino) {
|
|
52608
|
+
throw new UnsafeOwnershipStateError();
|
|
52609
|
+
}
|
|
52610
|
+
}
|
|
52611
|
+
__name(assertDirectoryIdentity, "assertDirectoryIdentity");
|
|
52612
|
+
async function assertLockShapeIfPresent(lockPath) {
|
|
52613
|
+
let stat3;
|
|
52614
|
+
try {
|
|
52615
|
+
stat3 = await fs9.lstat(lockPath);
|
|
52616
|
+
} catch (error2) {
|
|
52617
|
+
if (isMissing2(error2)) return;
|
|
52618
|
+
throw error2;
|
|
52619
|
+
}
|
|
52620
|
+
if (!stat3.isDirectory() || stat3.isSymbolicLink() || process.platform !== "win32" && typeof process.getuid === "function" && stat3.uid !== process.getuid()) {
|
|
52621
|
+
throw new UnsafeOwnershipStateError();
|
|
52622
|
+
}
|
|
52623
|
+
}
|
|
52624
|
+
__name(assertLockShapeIfPresent, "assertLockShapeIfPresent");
|
|
52625
|
+
async function readOwnerRecord(ownerPath) {
|
|
52626
|
+
let pathStat;
|
|
52627
|
+
try {
|
|
52628
|
+
pathStat = await fs9.lstat(ownerPath);
|
|
52629
|
+
} catch (error2) {
|
|
52630
|
+
if (isMissing2(error2)) return void 0;
|
|
52631
|
+
throw error2;
|
|
52632
|
+
}
|
|
52633
|
+
if (!pathStat.isFile() || pathStat.isSymbolicLink() || pathStat.nlink !== 1 || pathStat.size <= 0 || pathStat.size > MAX_OWNER_BYTES || process.platform !== "win32" && ((pathStat.mode & 511) !== 384 || typeof process.getuid === "function" && pathStat.uid !== process.getuid())) {
|
|
52634
|
+
throw new UnsafeOwnershipStateError();
|
|
52635
|
+
}
|
|
52636
|
+
let handle;
|
|
52637
|
+
try {
|
|
52638
|
+
handle = await fs9.open(
|
|
52639
|
+
ownerPath,
|
|
52640
|
+
process.platform === "win32" ? fsConstants3.O_RDONLY : fsConstants3.O_RDONLY | fsConstants3.O_NOFOLLOW
|
|
52641
|
+
);
|
|
52642
|
+
} catch (error2) {
|
|
52643
|
+
if (error2.code === "ELOOP") {
|
|
52644
|
+
throw new UnsafeOwnershipStateError(void 0, { cause: error2 });
|
|
52645
|
+
}
|
|
52646
|
+
throw error2;
|
|
52647
|
+
}
|
|
52648
|
+
try {
|
|
52649
|
+
const handleStat = await handle.stat();
|
|
52650
|
+
if (!handleStat.isFile() || handleStat.nlink !== 1 || handleStat.dev !== pathStat.dev || handleStat.ino !== pathStat.ino || handleStat.size !== pathStat.size || process.platform !== "win32" && ((handleStat.mode & 511) !== 384 || typeof process.getuid === "function" && handleStat.uid !== process.getuid())) {
|
|
52651
|
+
throw new UnsafeOwnershipStateError();
|
|
52652
|
+
}
|
|
52653
|
+
const serialized = await handle.readFile("utf8");
|
|
52654
|
+
let parsed;
|
|
52655
|
+
try {
|
|
52656
|
+
parsed = JSON.parse(serialized);
|
|
52657
|
+
} catch (error2) {
|
|
52658
|
+
throw new UnsafeOwnershipStateError(void 0, { cause: error2 });
|
|
52659
|
+
}
|
|
52660
|
+
return assertOwnerRecord(parsed);
|
|
52661
|
+
} finally {
|
|
52662
|
+
await handle.close();
|
|
52663
|
+
}
|
|
52664
|
+
}
|
|
52665
|
+
__name(readOwnerRecord, "readOwnerRecord");
|
|
52666
|
+
async function syncDirectory(directory) {
|
|
52667
|
+
if (process.platform === "win32") return;
|
|
52668
|
+
const handle = await fs9.open(directory, fsConstants3.O_RDONLY);
|
|
52669
|
+
try {
|
|
52670
|
+
await handle.sync();
|
|
52671
|
+
} finally {
|
|
52672
|
+
await handle.close();
|
|
52673
|
+
}
|
|
52674
|
+
}
|
|
52675
|
+
__name(syncDirectory, "syncDirectory");
|
|
52676
|
+
async function checkLegacyConversationRuntimeOwner(options) {
|
|
52677
|
+
const ownerPath = getConversationRuntimeOwnerPath(options.stableBaseDir);
|
|
52678
|
+
const directory = path17.dirname(ownerPath);
|
|
52679
|
+
const lockPath = path17.join(directory, OWNER_LOCK);
|
|
52680
|
+
let reclaimed = false;
|
|
52681
|
+
try {
|
|
52682
|
+
let base;
|
|
52683
|
+
let identity;
|
|
52684
|
+
try {
|
|
52685
|
+
base = await inspectDirectory(options.stableBaseDir, false);
|
|
52686
|
+
identity = await inspectDirectory(directory, true);
|
|
52687
|
+
} catch (error2) {
|
|
52688
|
+
if (isMissing2(error2)) return;
|
|
52689
|
+
throw error2;
|
|
52690
|
+
}
|
|
52691
|
+
await assertLockShapeIfPresent(lockPath);
|
|
52692
|
+
const lockfile = (await import("./proper-lockfile-3LHWIM44.js")).default;
|
|
52693
|
+
let compromised = false;
|
|
52694
|
+
const release = await lockfile.lock(directory, {
|
|
52695
|
+
realpath: false,
|
|
52696
|
+
lockfilePath: lockPath,
|
|
52697
|
+
stale: 5e3,
|
|
52698
|
+
update: 1e3,
|
|
52699
|
+
retries: { retries: 40, minTimeout: 10, maxTimeout: 50 },
|
|
52700
|
+
...options.lockOptions,
|
|
52701
|
+
onCompromised: /* @__PURE__ */ __name(() => {
|
|
52702
|
+
compromised = true;
|
|
52703
|
+
}, "onCompromised")
|
|
52704
|
+
});
|
|
52705
|
+
let operationError;
|
|
52706
|
+
try {
|
|
52707
|
+
await assertLockShapeIfPresent(lockPath);
|
|
52708
|
+
await assertDirectoryIdentity(options.stableBaseDir, base, false);
|
|
52709
|
+
await assertDirectoryIdentity(directory, identity);
|
|
52710
|
+
const existing = await readOwnerRecord(ownerPath);
|
|
52711
|
+
if (compromised) throw new UnsafeOwnershipStateError();
|
|
52712
|
+
if (existing) {
|
|
52713
|
+
if ((options.isProcessAlive ?? processIsAlive)(existing.pid)) {
|
|
52714
|
+
throw conversationRuntimeInUseError();
|
|
52715
|
+
}
|
|
52716
|
+
const confirmed = await readOwnerRecord(ownerPath);
|
|
52717
|
+
if (!confirmed || !sameRecord(existing, confirmed)) {
|
|
52718
|
+
throw new UnsafeOwnershipStateError();
|
|
52719
|
+
}
|
|
52720
|
+
await assertDirectoryIdentity(options.stableBaseDir, base, false);
|
|
52721
|
+
await assertDirectoryIdentity(directory, identity);
|
|
52722
|
+
if (compromised) throw new UnsafeOwnershipStateError();
|
|
52723
|
+
await fs9.unlink(ownerPath);
|
|
52724
|
+
await syncDirectory(directory);
|
|
52725
|
+
reclaimed = true;
|
|
52726
|
+
}
|
|
52727
|
+
} catch (error2) {
|
|
52728
|
+
operationError = error2;
|
|
52729
|
+
}
|
|
52730
|
+
try {
|
|
52731
|
+
await release();
|
|
52732
|
+
} catch (error2) {
|
|
52733
|
+
throw new UnsafeOwnershipStateError(void 0, { cause: error2 });
|
|
52734
|
+
}
|
|
52735
|
+
if (compromised) throw new UnsafeOwnershipStateError();
|
|
52736
|
+
if (operationError) throw operationError;
|
|
52737
|
+
if (reclaimed) {
|
|
52738
|
+
await (options.wait ?? delay2)(
|
|
52739
|
+
options.handoffGraceMs ?? DEFAULT_HANDOFF_GRACE_MS
|
|
52740
|
+
);
|
|
52741
|
+
}
|
|
52742
|
+
} catch (error2) {
|
|
52743
|
+
if (error2 instanceof ConversationRuntimeOwnershipError) throw error2;
|
|
52744
|
+
if (error2 instanceof UnsafeOwnershipStateError || error2.code === "ECOMPROMISED") {
|
|
52745
|
+
throw conversationRuntimeOwnershipCompromisedError(error2);
|
|
52746
|
+
}
|
|
52747
|
+
throw conversationRuntimeUnavailableError(error2);
|
|
52748
|
+
}
|
|
52749
|
+
}
|
|
52750
|
+
__name(checkLegacyConversationRuntimeOwner, "checkLegacyConversationRuntimeOwner");
|
|
52751
|
+
|
|
52271
52752
|
// packages/cli/src/serve/server.ts
|
|
52272
52753
|
var warnedDefaultTrust = false;
|
|
52273
52754
|
function loadServeChannelWebhookConfigs(sources) {
|
|
@@ -52808,22 +53289,9 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
52808
53289
|
}
|
|
52809
53290
|
}, "getProviderReadiness")
|
|
52810
53291
|
});
|
|
52811
|
-
const
|
|
52812
|
-
|
|
52813
|
-
|
|
52814
|
-
path18.resolve(
|
|
52815
|
-
deps.liveDiscoveryStableBaseDir ?? getStableLiveDiscoveryBaseDir()
|
|
52816
|
-
)
|
|
52817
|
-
) ?? createConversationRuntimeOwnership({
|
|
52818
|
-
pid: process.pid,
|
|
52819
|
-
instanceNonce: liveCoordinator.daemonInstanceNonce,
|
|
52820
|
-
stableBaseDir: path18.resolve(
|
|
52821
|
-
deps.liveDiscoveryStableBaseDir ?? getStableLiveDiscoveryBaseDir()
|
|
52822
|
-
)
|
|
52823
|
-
}) : void 0;
|
|
52824
|
-
if (conversationRuntimeOwnership) {
|
|
52825
|
-
serveAppLifecycle.setOwnership(conversationRuntimeOwnership);
|
|
52826
|
-
}
|
|
53292
|
+
const stableLiveDiscoveryBaseDir = path18.resolve(
|
|
53293
|
+
deps.liveDiscoveryStableBaseDir ?? getStableLiveDiscoveryBaseDir()
|
|
53294
|
+
);
|
|
52827
53295
|
liveCoordinator.setAppshotReadiness(
|
|
52828
53296
|
liveVoiceEnabled && deps.liveConversationWorkspace ? {
|
|
52829
53297
|
state: "checking",
|
|
@@ -52835,7 +53303,9 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
52835
53303
|
);
|
|
52836
53304
|
let standaloneSessionService;
|
|
52837
53305
|
const conversationRuntimeManager = deps.liveConversationWorkspace ? new ConversationRuntimeManager({
|
|
52838
|
-
|
|
53306
|
+
checkLegacyOwner: deps.checkLegacyConversationOwner ?? (() => checkLegacyConversationRuntimeOwner({
|
|
53307
|
+
stableBaseDir: stableLiveDiscoveryBaseDir
|
|
53308
|
+
})),
|
|
52839
53309
|
workspace: deps.liveConversationWorkspace,
|
|
52840
53310
|
registry: workspaceRegistry,
|
|
52841
53311
|
publishRuntime: /* @__PURE__ */ __name(async (canonicalRoot, validate) => {
|
|
@@ -53119,6 +53589,14 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
53119
53589
|
interruptTaskWaits: /* @__PURE__ */ __name((callerSessionId) => liveTaskService.interruptWait(callerSessionId), "interruptTaskWaits")
|
|
53120
53590
|
});
|
|
53121
53591
|
liveCoordinator.setHandlers({
|
|
53592
|
+
beforeStart: /* @__PURE__ */ __name(async () => {
|
|
53593
|
+
await ensureConversationRuntimeWithLifecycle();
|
|
53594
|
+
await publishLiveVoiceEnabled(true);
|
|
53595
|
+
await assertLiveDiscoveryPublisher(stableLiveDiscoveryBaseDir, {
|
|
53596
|
+
pid: process.pid,
|
|
53597
|
+
instanceNonce: liveCoordinator.daemonInstanceNonce
|
|
53598
|
+
});
|
|
53599
|
+
}, "beforeStart"),
|
|
53122
53600
|
onHostReady: /* @__PURE__ */ __name(() => {
|
|
53123
53601
|
if (!liveVoiceEnabled) return;
|
|
53124
53602
|
void verifyLiveAppshotChannel();
|
|
@@ -53412,10 +53890,6 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
53412
53890
|
if (liveVoiceSurfaceAvailable) {
|
|
53413
53891
|
registerLiveRoutes(app, {
|
|
53414
53892
|
coordinator: liveCoordinator,
|
|
53415
|
-
ensureRuntimeReady: /* @__PURE__ */ __name(async () => {
|
|
53416
|
-
await ensureConversationRuntimeWithLifecycle();
|
|
53417
|
-
await publishLiveVoiceEnabled(true);
|
|
53418
|
-
}, "ensureRuntimeReady"),
|
|
53419
53893
|
mutate,
|
|
53420
53894
|
...deps.persistSetting ? {
|
|
53421
53895
|
persistShortcut: /* @__PURE__ */ __name(async (shortcut) => {
|