@qwen-code/qwen-code 0.23.1-preview.2 → 0.23.2-nightly.20260909.2e212144d3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -15
- 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/auth.md +1 -1
- package/bundled/qc-helper/docs/configuration/model-providers.md +66 -16
- 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/_meta.ts +1 -0
- package/bundled/qc-helper/docs/features/channels/dingtalk.md +1 -1
- package/bundled/qc-helper/docs/features/channels/github.md +1 -9
- package/bundled/qc-helper/docs/features/channels/overview.md +27 -52
- package/bundled/qc-helper/docs/features/channels/qqbot.md +1 -2
- package/bundled/qc-helper/docs/features/commands.md +79 -17
- package/bundled/qc-helper/docs/features/computer-use.md +9 -7
- package/bundled/qc-helper/docs/features/cross-session-protocol.md +291 -0
- package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
- package/bundled/qc-helper/docs/features/goals.md +17 -3
- package/bundled/qc-helper/docs/features/sub-agents.md +8 -0
- package/bundled/qc-helper/docs/qwen-serve.md +80 -48
- package/chunks/{MaxSizedBox-IYIQ43IZ.js → MaxSizedBox-ZBGWYJZW.js} +29 -28
- package/chunks/{StandaloneSessionPicker-AWB2OHX6.js → StandaloneSessionPicker-NR5ACIJZ.js} +48 -47
- package/chunks/{acp-startup-profiler-BAL4LJTN.js → acp-startup-profiler-KEU6VAYR.js} +2 -2
- package/chunks/{acpAgent-ZC57OLS4.js → acpAgent-DM6XRCDQ.js} +361 -210
- package/chunks/{agent-GEBPAEJS.js → agent-EF3IIYE3.js} +20 -20
- package/chunks/{agent-headless-63ZEYAJK.js → agent-headless-5J2KFYR4.js} +20 -20
- package/chunks/{anthropicContentGenerator-6XDHXIII.js → anthropicContentGenerator-VIW2FG7G.js} +32 -9
- package/chunks/{artifact-tool-P52OKKEF.js → artifact-tool-G5LHNECG.js} +1 -1
- package/chunks/{askUserQuestion-3KAYLLMM.js → askUserQuestion-R3TXY77M.js} +1 -1
- package/chunks/{bridge-MHWO5I5T.js → bridge-LEMQM6QE.js} +32 -31
- package/chunks/{channel-management-service-NFRZXQFO.js → channel-management-service-TGF6XFXT.js} +4 -4
- package/chunks/{channel-settings-store-T7PMIHKC.js → channel-settings-store-FV365JSF.js} +40 -39
- package/chunks/{channel-worker-group-O2BWK5F7.js → channel-worker-group-SQ5FRWOH.js} +7 -7
- package/chunks/{channel-worker-manager-4WP7VJOD.js → channel-worker-manager-TU4ZNWOE.js} +7 -7
- package/chunks/{channel-worker-supervisor-CCUXD6J5.js → channel-worker-supervisor-EMITFMCP.js} +4 -4
- package/chunks/{chunk-3SH53ANB.js → chunk-22GORRNY.js} +12 -0
- package/chunks/{chunk-OFB36ZBA.js → chunk-2HYOOFDS.js} +10 -7
- package/chunks/chunk-2Z3T52OC.js +82 -0
- package/chunks/{chunk-LYHYXJJ3.js → chunk-34VPADLG.js} +3 -3
- package/chunks/{chunk-C7M445SS.js → chunk-3A2IMUDH.js} +14 -2
- package/chunks/{chunk-P5Z7VD23.js → chunk-3O77M472.js} +294 -87
- package/chunks/{chunk-4OCYWXKF.js → chunk-43EUMPKQ.js} +3 -3
- package/chunks/{chunk-W4LL5RZO.js → chunk-4ALNJDHL.js} +52 -13
- package/chunks/{chunk-VMFPZXRT.js → chunk-4DIMJKWU.js} +64 -43
- package/chunks/{chunk-ZRVFHLLK.js → chunk-5DQ4YTIZ.js} +1 -1
- package/chunks/{chunk-VYCJITND.js → chunk-5HV2HPO7.js} +1 -1
- package/chunks/{chunk-22QOQKG4.js → chunk-5WBA3DEF.js} +1 -1
- package/chunks/{chunk-3K65MUKD.js → chunk-65I7S4Z3.js} +2 -1
- package/chunks/{chunk-I7UNCY24.js → chunk-6GAYNM3F.js} +3 -3
- package/chunks/{chunk-2C3XDBGL.js → chunk-6S7YYUUH.js} +4 -4
- package/chunks/{chunk-Y3C5COGI.js → chunk-6VIATHL7.js} +1 -1
- package/chunks/{chunk-XNC2TCUO.js → chunk-76I36BEM.js} +4 -4
- package/chunks/{chunk-B54PFQS5.js → chunk-7CLLH5TI.js} +1 -1
- package/chunks/{chunk-RGAQDQ3Z.js → chunk-7IDZFJAV.js} +18 -9
- package/chunks/{chunk-5Z4FCEPY.js → chunk-7K4GGN3D.js} +606 -109
- package/chunks/{chunk-WLZRMF3C.js → chunk-7KZVXJ4U.js} +353 -11
- package/chunks/{chunk-REDVV5NC.js → chunk-7WCJEY3A.js} +7 -7
- package/chunks/{chunk-I67KJGM6.js → chunk-A7QZIGRB.js} +3 -3
- package/chunks/{chunk-SHX2HIE7.js → chunk-ATBLEXXV.js} +7 -2
- package/chunks/{chunk-RH344FKI.js → chunk-AUTUFD5X.js} +1 -1
- package/chunks/chunk-AXMWHKXA.js +42 -0
- package/chunks/{chunk-WFXD5OZH.js → chunk-AXWTG6R7.js} +2 -5
- package/chunks/{chunk-TSLRORQR.js → chunk-BDAVT6K2.js} +1809 -1588
- package/chunks/{chunk-HWZOOSEB.js → chunk-BDP3NTWD.js} +3 -3
- package/chunks/{chunk-RD3VPM4E.js → chunk-BZUHZCUO.js} +2 -2
- package/chunks/{chunk-HPE4LEWX.js → chunk-C24ZDDNY.js} +1 -1
- package/chunks/{chunk-R7TKFIQO.js → chunk-CALNF3Z3.js} +1 -1
- package/chunks/{chunk-RPFJJ33Z.js → chunk-CALTQWTZ.js} +1 -1
- package/chunks/{chunk-BF3RUIVP.js → chunk-CH2YDT6X.js} +36 -38
- package/chunks/{chunk-LD53HMPV.js → chunk-CRZBDVP2.js} +1 -0
- package/chunks/{chunk-GEV66YGE.js → chunk-D6AGS266.js} +1 -1
- package/chunks/{chunk-EPZWBYQI.js → chunk-D7DFZAK2.js} +19 -11
- package/chunks/{chunk-5V4B3EWA.js → chunk-DARWOZY6.js} +1 -1
- package/chunks/{chunk-XX4MBBFW.js → chunk-DGNRLJ6S.js} +4 -4
- package/chunks/{chunk-UTVIIA7N.js → chunk-DVOCOIS5.js} +1 -1
- package/chunks/{chunk-RQNAO42A.js → chunk-E4LXNQAK.js} +1 -1
- package/chunks/{chunk-EGRFCIXD.js → chunk-EATP5QCN.js} +84 -25
- package/chunks/{chunk-3RMVM33U.js → chunk-EDSU3VUG.js} +12 -5
- package/chunks/{chunk-733KQL63.js → chunk-EE5ZD4XU.js} +3 -3
- package/chunks/{chunk-QQGAR64U.js → chunk-EN3Q2S3J.js} +4 -4
- package/chunks/{chunk-PLUAIHZO.js → chunk-EOLGAQ25.js} +17 -16
- package/chunks/{chunk-37SOBIA3.js → chunk-ERXNTINK.js} +1 -1
- package/chunks/{chunk-L36LLVA5.js → chunk-EYCW6UF2.js} +7 -7
- package/chunks/{chunk-ZELCTN6Y.js → chunk-F23YN37B.js} +10 -0
- package/chunks/{chunk-FPGTNKCP.js → chunk-F3M6P6IQ.js} +199 -1
- package/chunks/{chunk-B44JBZBB.js → chunk-F4SAL7WM.js} +91 -3
- package/chunks/{chunk-F47DITLZ.js → chunk-FAWTMDX7.js} +14 -0
- package/chunks/{chunk-SI6Q52UI.js → chunk-FEEVHJOR.js} +3 -3
- package/chunks/{chunk-75UQFGFE.js → chunk-FN4KHWCL.js} +1 -1
- package/chunks/{chunk-WQBR7LN5.js → chunk-FRS3P7MQ.js} +15 -2
- package/chunks/{chunk-5JLQWQK6.js → chunk-FV4DM2M4.js} +2 -2
- package/chunks/{chunk-Z6DDPSGJ.js → chunk-GNY7B3CA.js} +1 -1
- package/chunks/{chunk-FDOGGKAA.js → chunk-GSFV5RQW.js} +2 -0
- package/chunks/{chunk-XBVNNDPK.js → chunk-GSYD7MYP.js} +8 -3
- package/chunks/{chunk-ERMAXPXA.js → chunk-HIXUUCGY.js} +187 -12
- package/chunks/{chunk-EJNYBDYC.js → chunk-HNLMYDQE.js} +1 -1
- package/chunks/{chunk-3K456UJF.js → chunk-HSO6D4KX.js} +93 -28
- package/chunks/{chunk-ANVC5CSK.js → chunk-HUJJFSMO.js} +10 -10
- package/chunks/{chunk-C4NXRR7T.js → chunk-HW4MRP4V.js} +2 -2
- package/chunks/{chunk-PMGWY6ZP.js → chunk-HWLLUDIA.js} +113 -18
- package/chunks/{chunk-RCUWMVN3.js → chunk-HZ2HUXX7.js} +1 -1
- package/chunks/{chunk-7PMKXGRP.js → chunk-IKK6NNS6.js} +91 -31
- package/chunks/{chunk-IMWCUWQT.js → chunk-J3TJH52D.js} +1 -1
- package/chunks/{chunk-BNWIX6BM.js → chunk-JFAGT5YG.js} +3 -3
- package/chunks/{chunk-RSU3I6UL.js → chunk-JGTMTJSQ.js} +1 -1
- package/chunks/{chunk-LTCI6ZOJ.js → chunk-JYGIJA4W.js} +1 -1
- package/chunks/{chunk-537SQ2AI.js → chunk-KECCLCXM.js} +146 -24
- package/chunks/{chunk-KAZWXVI3.js → chunk-KEPC5BOL.js} +5 -5
- package/chunks/{chunk-HZS3JRQW.js → chunk-L5VHJYHH.js} +40 -2
- package/chunks/{chunk-KTLT7VCX.js → chunk-LKBOBUA2.js} +2 -2
- package/chunks/{chunk-TDHVOZ65.js → chunk-LOBKNYPR.js} +2 -2
- package/chunks/{chunk-QW7BUOSI.js → chunk-LOVGQ3HZ.js} +26 -9
- package/chunks/{chunk-5FYGZ7E3.js → chunk-MUF4UGPB.js} +2 -2
- package/chunks/chunk-N3Z6Q7KC.js +384 -0
- package/chunks/{chunk-JOV46WGX.js → chunk-NB3NDQQK.js} +1 -1
- package/chunks/chunk-NFXXBWSE.js +463 -0
- package/chunks/chunk-NOO4QFXM.js +171 -0
- package/chunks/{chunk-PQSCGZT2.js → chunk-NPKCVSXX.js} +26 -2
- package/chunks/{chunk-FXYNIZPW.js → chunk-NV4YYXFT.js} +51 -10
- package/chunks/{chunk-FWH4736Q.js → chunk-O6BFERWN.js} +3 -3
- package/chunks/{chunk-UKADFFL2.js → chunk-OFVAS4AR.js} +1 -1
- package/chunks/{chunk-C55CR5I4.js → chunk-OVTPETDL.js} +6 -6
- package/chunks/chunk-PLEBBGHL.js +1401 -0
- package/chunks/{chunk-Z6KFLEG7.js → chunk-PSPAM24S.js} +1 -0
- package/chunks/{chunk-RRCNEW2A.js → chunk-PWR6BQ3U.js} +58 -4
- package/chunks/{chunk-SHK2SIR5.js → chunk-QA2B26PL.js} +4 -4
- package/chunks/{chunk-NFIDVZND.js → chunk-QB3KS3N3.js} +2 -21
- package/chunks/{chunk-NUQFUXOG.js → chunk-QTNCGZHQ.js} +2 -0
- package/chunks/{chunk-QJVZLILI.js → chunk-R7OO56VZ.js} +1 -1
- package/chunks/{chunk-MFCWL4LI.js → chunk-SK6VACCM.js} +936 -481
- package/chunks/{chunk-SD7Y2PMC.js → chunk-SM66GFKJ.js} +2 -2
- package/chunks/{chunk-ADJD4LZF.js → chunk-SNMUO5Z7.js} +1 -1
- package/chunks/{chunk-NXWYCSPL.js → chunk-SOA4HKRJ.js} +1 -1
- package/chunks/{chunk-IRKQ4YYX.js → chunk-SVWWF5TZ.js} +29 -1
- package/chunks/{chunk-YLFICBYK.js → chunk-SYKPMH2X.js} +3 -3
- package/chunks/{chunk-5HBA2Z7V.js → chunk-TGNNLRC3.js} +2 -3
- package/chunks/{chunk-AX23QSX3.js → chunk-TRQNRP2H.js} +4 -4
- package/chunks/{chunk-AUJOWIT5.js → chunk-UQOP2APG.js} +4 -24
- package/chunks/{chunk-HY3DXYZK.js → chunk-UYDQYDW2.js} +1 -1
- package/chunks/{chunk-IGOIYZBG.js → chunk-VAWM3A5N.js} +2 -2
- package/chunks/{chunk-6KYWU726.js → chunk-VJJXG73H.js} +417 -292
- package/chunks/{chunk-ZNI3V2XA.js → chunk-VJWJOKOQ.js} +2 -2
- package/chunks/{chunk-AWDF462I.js → chunk-VR6Y23FW.js} +2 -2
- package/chunks/{chunk-T7TP5UQL.js → chunk-VX2NR3SD.js} +21 -6
- package/chunks/{chunk-65GHQ4FX.js → chunk-WDVV3LRM.js} +707 -216
- package/chunks/{chunk-KP5QK3FB.js → chunk-WEU6O6VN.js} +397 -54
- package/chunks/{chunk-OHOO527W.js → chunk-WG7BL3FY.js} +52 -2
- package/chunks/{chunk-VU7O7CGQ.js → chunk-XDNFODER.js} +1 -1
- package/chunks/{chunk-YHDGABDC.js → chunk-XKBFYTCD.js} +1 -1
- package/chunks/{chunk-RUMSY4ES.js → chunk-Y7YHAY32.js} +28 -10
- package/chunks/{chunk-7IKXTGZT.js → chunk-YI2YCNSP.js} +1 -1
- package/chunks/{chunk-B5FF3LRF.js → chunk-YIE6REQ5.js} +29 -17
- package/chunks/{chunk-E4VX6LXB.js → chunk-YZTGGCEE.js} +10 -2
- package/chunks/{chunk-TXAEXF2B.js → chunk-ZEFWBG2C.js} +737 -1136
- package/chunks/{chunk-AIMZIXZM.js → chunk-ZM2TCZZ7.js} +5 -7
- package/chunks/{chunk-ZT3XUGSU.js → chunk-ZZ7RVOTU.js} +135 -26
- package/chunks/{config-utils-F4CFJ4MW.js → config-utils-SXFK3G4X.js} +33 -32
- package/chunks/{contextCommand-OIIGGOMU.js → contextCommand-QFPD26QO.js} +31 -30
- package/chunks/{core-runtime-JEHLOGMB.js → core-runtime-VXKNBODM.js} +35 -33
- package/chunks/{create-sub-session-MVFBE5RA.js → create-sub-session-7WSQETFR.js} +30 -29
- package/chunks/{daemon-LCUELM6E.js → daemon-U2456K5H.js} +2 -2
- package/chunks/{daemon-git-worktree-guard-5FTKLJOU.js → daemon-git-worktree-guard-I4DCSDUS.js} +29 -28
- package/chunks/{daemon-status-provider-P6A5MPMW.js → daemon-status-provider-5UV56RI4.js} +36 -35
- package/chunks/{daemon-trust-policy-ZJ3NFYUO.js → daemon-trust-policy-DKIBWTKU.js} +36 -35
- package/chunks/{daemon-trust-policy-monitor-6SDLEW7S.js → daemon-trust-policy-monitor-CPSD7UKT.js} +36 -35
- package/chunks/{deferred-core-runtime-DWOXIU5S.js → deferred-core-runtime-D2RF35BL.js} +29 -28
- package/chunks/{discovery-TUM3ZQ6U.js → discovery-XP4RMDUM.js} +4 -2
- package/chunks/{dist-P6YWBITG.js → dist-6YDUH3BB.js} +817 -152
- package/chunks/{dist-T4PRA5EZ.js → dist-BNQVF565.js} +2 -8
- package/chunks/{dist-AI25RVRA.js → dist-F34J4FZX.js} +1 -1
- package/chunks/{dist-3H3WODVS.js → dist-F6JLAJLE.js} +1 -1
- package/chunks/{dist-NXW4DUUX.js → dist-K5GHMXIG.js} +2 -2
- package/chunks/{dist-YNQU4CKC.js → dist-NP7QKLVG.js} +2 -2
- package/chunks/{dist-VCAS67N5.js → dist-UFTFGI6I.js} +1 -1
- package/chunks/{dist-I74QLLQS.js → dist-XLV33CLY.js} +1 -2
- package/chunks/{dist-XINEKB5A.js → dist-ZDNJK74R.js} +3 -7
- package/chunks/{edit-WPVXLL3T.js → edit-4IBADZ3O.js} +20 -20
- package/chunks/{enter-worktree-5A6VW6BN.js → enter-worktree-YFTKHXHZ.js} +2 -2
- package/chunks/{enterPlanMode-JSODW7E2.js → enterPlanMode-YN3GPQU5.js} +20 -20
- package/chunks/{environment-5LLJ3I3W.js → environment-E272IJMF.js} +32 -31
- package/chunks/{errors-IQT3YZEP.js → errors-CVAH3RWQ.js} +31 -30
- package/chunks/{exit-worktree-QV7E7KP6.js → exit-worktree-NF2XEMES.js} +3 -3
- package/chunks/{exitPlanMode-DDVFYNW4.js → exitPlanMode-24J5IHGC.js} +20 -20
- package/chunks/{fast-path-PAUQQEVU.js → fast-path-M5IDBMXF.js} +4 -4
- package/chunks/{fast-path-settings-ISEJPRYE.js → fast-path-settings-SATXY3PD.js} +3 -3
- package/chunks/{glob-SQ7CTZ7F.js → glob-ERBD7JYP.js} +20 -20
- package/chunks/{goal-tools-UWZRCLQB.js → goal-tools-245ULLQT.js} +20 -20
- package/chunks/{handleAutoUpdate-RUPZZTSG.js → handleAutoUpdate-JDZHHZKK.js} +32 -31
- package/chunks/{i18n-SF5MPWEB.js → i18n-LA4D5IXM.js} +32 -29
- package/chunks/{image-gen-Q3RUTVKR.js → image-gen-XP4NNIYG.js} +4 -4
- package/chunks/{initializer-CK4WPYZG.js → initializer-SHPTSWUZ.js} +36 -35
- package/chunks/{installationInfo-IRPQEYRF.js → installationInfo-QEQEPB3G.js} +29 -28
- package/chunks/{list-E3PS3EBJ.js → list-IBHCQWTF.js} +39 -38
- package/chunks/{list-agents-I5TRH3J7.js → list-agents-EDPZCGKN.js} +5 -4
- package/chunks/{llm-JQKBOYAF.js → llm-JAWCQLA4.js} +81 -75
- package/chunks/{llm-content-generator-2QWGBW42.js → llm-content-generator-GOV3A23T.js} +23 -8
- package/chunks/{loadedSettingsAdapter-DGXGVYZS.js → loadedSettingsAdapter-RVE2GNVU.js} +36 -35
- package/chunks/{loggingContentGenerator-ZYURLJKK.js → loggingContentGenerator-SSHNN5YW.js} +22 -22
- package/chunks/{managed-npm-update-HTHR63EA.js → managed-npm-update-BHSTITQO.js} +29 -28
- package/chunks/{mcp-I7G2AEWS.js → mcp-6ZZ7P2HU.js} +36 -35
- package/chunks/{monitor-4R76BCRZ.js → monitor-RKK6GSHG.js} +20 -20
- package/chunks/{nonInteractiveCli-24OQ3VP2.js → nonInteractiveCli-UQHP3G6P.js} +76 -72
- package/chunks/{notebook-edit-PPSH7FEX.js → notebook-edit-YM47A7WO.js} +20 -20
- package/chunks/{open-with-auth-D6JD6LDS.js → open-with-auth-6MVIHMXB.js} +1 -1
- package/chunks/{openaiContentGenerator-K7V5EO7F.js → openaiContentGenerator-FHKDWNI2.js} +11 -11
- package/chunks/{pidfile-TGIUY2GG.js → pidfile-SIIEJEEH.js} +32 -29
- package/chunks/{processUtils-3USXUQWX.js → processUtils-JF7CWBJC.js} +2 -2
- package/chunks/{prompt-terminal-ledger-XHVZRXJI.js → prompt-terminal-ledger-FXXHAEQU.js} +30 -29
- package/chunks/{qwenContentGenerator-MPBOQB64.js → qwenContentGenerator-KFJ77JP6.js} +24 -24
- package/chunks/{qwenOAuth2-BS5D2LYV.js → qwenOAuth2-KX6LVYQ3.js} +4 -4
- package/chunks/{read-file-R256LDWQ.js → read-file-S2NOCBIL.js} +4 -4
- package/chunks/{resumeHistoryUtils-S43LTFHD.js → resumeHistoryUtils-QHHPSQWU.js} +33 -32
- package/chunks/{ripGrep-L7HPZ75Y.js → ripGrep-F6TNOJUO.js} +5 -5
- package/chunks/{run-qwen-serve-CTFL5R6U.js → run-qwen-serve-KYBDQRDD.js} +229 -79
- package/chunks/{runtime-FS5TL6P7.js → runtime-3WNOFLCR.js} +43 -40
- package/chunks/{scheduled-tasks-QXPV3Q35.js → scheduled-tasks-RNBH56DJ.js} +34 -33
- package/chunks/{scheduler-EXU5HMVK.js → scheduler-ERMW7Q7B.js} +31 -30
- package/chunks/{send-message-GQKXGMPI.js → send-message-V5T3NMFM.js} +4 -4
- package/chunks/{serve-ITJC7WNN.js → serve-7NV46RMP.js} +36 -35
- package/chunks/{server-6JQY3PTU.js → server-6RZJR5QF.js} +1358 -932
- package/chunks/{session-PJDEKXD4.js → session-Z4EV7NVV.js} +107 -78
- package/chunks/{session-attachments-root-L37ORSST.js → session-attachments-root-SG5FC52X.js} +29 -28
- package/chunks/{session-pr-refresh-WIFD52YL.js → session-pr-refresh-ILC4Z3ZM.js} +33 -32
- package/chunks/{settings-LO6J5SAZ.js → settings-Y47SPE3X.js} +35 -34
- package/chunks/{shell-ANAFVYGR.js → shell-YBVCOPVO.js} +20 -20
- package/chunks/{skill-SHJWKSPH.js → skill-AXC63EBA.js} +4 -4
- package/chunks/{skill-settings-GX3XHZ5Q.js → skill-settings-AFPAYGLO.js} +35 -34
- package/chunks/{spawnChannel-WE42VBKM.js → spawnChannel-ZFL4J2V3.js} +29 -28
- package/chunks/{standalone-update-CWDIKJRP.js → standalone-update-Y2OZPLNJ.js} +31 -30
- package/chunks/{start-opentui-ui-BBHGFOTF.js → start-opentui-ui-G6TKT4LI.js} +2270 -1026
- package/chunks/{startInteractiveUI-FQX7LUYP.js → startInteractiveUI-YTNDPW7J.js} +1789 -2211
- package/chunks/{task-create-PMAFST2T.js → task-create-MWXJFRRM.js} +3 -3
- package/chunks/{task-list-R2HSY2NC.js → task-list-EYO3FE57.js} +2 -2
- package/chunks/{task-update-JYC57USF.js → task-update-2JJJRHMT.js} +3 -3
- package/chunks/{team-create-WKTPCH6D.js → team-create-BUFLGGSH.js} +20 -20
- package/chunks/{team-delete-CBHVBTPB.js → team-delete-IQZ6XGFI.js} +2 -2
- package/chunks/{team-plan-approval-Y23DL7WR.js → team-plan-approval-OUWWM42U.js} +20 -20
- package/chunks/{terminal-image-renderer-B646HBDW.js → terminal-image-renderer-WH2WV5ES.js} +29 -28
- package/chunks/{theme-manager-BNWESY26.js → theme-manager-5UDRARM2.js} +29 -28
- package/chunks/{tool-search-PVQ5O5Y2.js → tool-search-MCDIRPHN.js} +4 -4
- package/chunks/{total-session-admission-P5Z43KNW.js → total-session-admission-VL27U74Z.js} +33 -32
- package/chunks/{trustedFolders-FH2LT2MZ.js → trustedFolders-MSXT4VDD.js} +30 -29
- package/chunks/{update-relaunch-WOWTKJSN.js → update-relaunch-JKLEWVCB.js} +5 -5
- package/chunks/{updateCheck-3MYFMM35.js → updateCheck-ARTHAJT2.js} +31 -30
- package/chunks/{useAutoAcceptIndicator-Q7ZRRRKO.js → useAutoAcceptIndicator-YEAAGYVU.js} +38 -37
- package/chunks/{validateNonInterActiveAuth-MYEWJX3G.js → validateNonInterActiveAuth-EMRQKH5S.js} +71 -69
- package/chunks/{version-RO2FPO76.js → version-HFQU35WD.js} +3 -1
- package/chunks/{web-fetch-QAKY2LUA.js → web-fetch-QBXAO6VF.js} +7 -7
- package/chunks/{web-search-XA5Z4ZCD.js → web-search-2URQXA3A.js} +201 -13
- package/chunks/{web-shell-static-POZHGGXE.js → web-shell-static-BFDESDD4.js} +5 -4
- package/chunks/{workflow-QFIOCMDM.js → workflow-JDD6WDAH.js} +211 -75
- package/chunks/{workspace-providers-status-B2UD7RAG.js → workspace-providers-status-B4IKR6YJ.js} +38 -37
- package/chunks/{workspace-registration-store-VZLRTI3Q.js → workspace-registration-store-PJ3YHR45.js} +1 -2
- package/chunks/{workspace-registry-GYOGG6TM.js → workspace-registry-WVYJ5UGB.js} +33 -32
- package/chunks/{workspace-runtime-coordinator-7KRXGQ4V.js → workspace-runtime-coordinator-DXL5YVAG.js} +33 -32
- package/chunks/{workspace-service-DJEYGJE4.js → workspace-service-QNGAMVH7.js} +40 -39
- package/chunks/{workspace-skills-status-MOKNESUC.js → workspace-skills-status-BEISJIII.js} +36 -35
- package/chunks/{workspace-trust-reconciler-AXOSUTQW.js → workspace-trust-reconciler-ORYJF5L4.js} +40 -39
- package/chunks/{write-file-QOYVHAKK.js → write-file-DWLKFBTJ.js} +21 -21
- package/chunks/{zoom-image-UCCLGFNC.js → zoom-image-BYVIXSNQ.js} +4 -4
- package/cli.js +13 -13
- package/export-transcript-document.js +123 -119
- package/package.json +4 -4
- package/web-shell/assets/{abnfDiagram-VCTEODGH-CTstZpXw.js → abnfDiagram-VCTEODGH-C_8kzsly.js} +1 -1
- package/web-shell/assets/{arc-DKW0mbPo.js → arc-CDg7Zfpm.js} +1 -1
- package/web-shell/assets/{architectureDiagram-5GKGNRK7-DkMpJ42t.js → architectureDiagram-5GKGNRK7-DZzdCWyF.js} +1 -1
- package/web-shell/assets/{blockDiagram-NRAW4CY4-7Cp1_4i3.js → blockDiagram-NRAW4CY4-DI3B4gyR.js} +1 -1
- package/web-shell/assets/{c4Diagram-UCG6FXSJ-BfaoSlBK.js → c4Diagram-UCG6FXSJ-CfOgwHZW.js} +1 -1
- package/web-shell/assets/channel-e4xwS72w.js +1 -0
- package/web-shell/assets/{chunk-2Q5K7J3B-_n1qzAio.js → chunk-2Q5K7J3B-B_PUth0g.js} +1 -1
- package/web-shell/assets/{chunk-5VM5RSS4-0cira5ZV.js → chunk-5VM5RSS4-CrKtvBIL.js} +1 -1
- package/web-shell/assets/{chunk-F27PBJKO-DseRXSHC.js → chunk-F27PBJKO-B4z2n8Py.js} +1 -1
- package/web-shell/assets/{chunk-G27WJ6UU-BehQWin0.js → chunk-G27WJ6UU-BUtrFEO8.js} +1 -1
- package/web-shell/assets/{chunk-JWPE2WC7-B5ftg1Bb.js → chunk-JWPE2WC7-Cqw3aXW0.js} +1 -1
- package/web-shell/assets/{chunk-LCL6LL3I-D7rnbVdk.js → chunk-LCL6LL3I-CZolnvls.js} +1 -1
- package/web-shell/assets/{chunk-POPQ4Y6H-2Bp-Orju.js → chunk-POPQ4Y6H-DivgasCa.js} +1 -1
- package/web-shell/assets/{chunk-SVP7TREG-CD2goGva.js → chunk-SVP7TREG--seyb1B6.js} +1 -1
- package/web-shell/assets/{chunk-XXDRQBXY-DzQt-Rji.js → chunk-XXDRQBXY-D7pHtuVM.js} +1 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-CzXfUUOt.js +1 -0
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-CzXfUUOt.js +1 -0
- package/web-shell/assets/{cose-bilkent-JH36ORCC-C-BZXSUn.js → cose-bilkent-JH36ORCC-4MWaRF_3.js} +1 -1
- package/web-shell/assets/csv-CX7rUNeC.svg +1 -0
- package/web-shell/assets/{cynefin-OW5HDTMX-BTcvowe1.js → cynefin-OW5HDTMX-nhJhAjgD.js} +1 -1
- package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-BoUE6K81.js → cynefinDiagram-5FMLGOSQ-NF-PwXlq.js} +1 -1
- package/web-shell/assets/{dagre-3AP2YEHR-BHxy9xeB.js → dagre-3AP2YEHR-Bu0ncdWP.js} +1 -1
- package/web-shell/assets/{diagram-S7CK7UJ4-DMiJIvDT.js → diagram-S7CK7UJ4-CsvhFHZC.js} +1 -1
- package/web-shell/assets/{diagram-UQ7AKVKN-DXV09Aes.js → diagram-UQ7AKVKN-Ck61sIB3.js} +1 -1
- package/web-shell/assets/{diagram-VSXAHHWV-CocpRomV.js → diagram-VSXAHHWV-D0171zrb.js} +1 -1
- package/web-shell/assets/{diagram-VX7I27RA-DL7nqtb4.js → diagram-VX7I27RA-DvdxY4UL.js} +1 -1
- package/web-shell/assets/{diagram-Z3DM3KII-CPZ2Jux_.js → diagram-Z3DM3KII-CGGpseiB.js} +1 -1
- package/web-shell/assets/{ebnfDiagram-PWID7BFC-BX-eVNsX.js → ebnfDiagram-PWID7BFC-K8-QMvY8.js} +1 -1
- package/web-shell/assets/{erDiagram-SSCWMZ5O-CPy_Ir6y.js → erDiagram-SSCWMZ5O-D316nAem.js} +1 -1
- package/web-shell/assets/{flowDiagram-A5DVABFB-eknAOte9.js → flowDiagram-A5DVABFB-B7siy_mn.js} +1 -1
- package/web-shell/assets/{ganttDiagram-EL5Y4UJY-crAxw_t7.js → ganttDiagram-EL5Y4UJY-BZQDxzTu.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-M29pa3Tc.js → gitGraphDiagram-WWUBYQGX-DZynLCSV.js} +1 -1
- package/web-shell/assets/{index-C9R-iojE.js → index-9ie6xLTM.js} +1 -1
- package/web-shell/assets/index-DirkXQEg.js +2164 -0
- package/web-shell/assets/index-DzdST_7L.css +36 -0
- package/web-shell/assets/{infoDiagram-RXCK75RN-XqspXdOU.js → infoDiagram-RXCK75RN-B0gr769A.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-5VMMS53U-C5KFS-7j.js → ishikawaDiagram-5VMMS53U-0pQFfjvX.js} +1 -1
- package/web-shell/assets/{journeyDiagram-EYS64GPL-Cc57LVRo.js → journeyDiagram-EYS64GPL-DEGtClWb.js} +1 -1
- package/web-shell/assets/{kanban-definition-3QL26DDD-C81OG-AI.js → kanban-definition-3QL26DDD-CnN8gPzw.js} +1 -1
- package/web-shell/assets/{layout-CFVu37BB.js → layout-C_70RhaT.js} +1 -1
- package/web-shell/assets/{linear-ChBxdtWf.js → linear-BJ2ZLmcq.js} +1 -1
- package/web-shell/assets/{mermaid.core-CMLfue0w.js → mermaid.core-RlY0zPNC.js} +6 -6
- package/web-shell/assets/{mindmap-definition-FBJOCRG2-DFsvJThp.js → mindmap-definition-FBJOCRG2-CpVAxTNl.js} +1 -1
- package/web-shell/assets/{pegDiagram-XKGWAZYB-BzpRzM4F.js → pegDiagram-XKGWAZYB-DmrSv3hD.js} +1 -1
- package/web-shell/assets/{pieDiagram-E7YTZNPT-Cv0Kankl.js → pieDiagram-E7YTZNPT-CJmgp8KJ.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-AXDQQJYC-Bh2BJ3Ay.js → quadrantDiagram-AXDQQJYC-UsgOyNco.js} +1 -1
- package/web-shell/assets/{railroadDiagram-O6MQD6OU-y8rNDdDS.js → railroadDiagram-O6MQD6OU-DQ6gMs_W.js} +1 -1
- package/web-shell/assets/{requirementDiagram-EFPCY7ZU-C0m2DKJ_.js → requirementDiagram-EFPCY7ZU-DhqadamF.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-P5KCCOFB-BzdGnSF4.js → sankeyDiagram-P5KCCOFB-R4WnURaE.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-DPzAVmzz.js → sequenceDiagram-WJ2MYXX4-D7BwMi_D.js} +1 -1
- package/web-shell/assets/{sizeCapture-X5ZJPWSS-LcHG28Zh.js → sizeCapture-X5ZJPWSS-Bqngz088.js} +1 -1
- package/web-shell/assets/{stateDiagram-HBIQ2CUA-C1Bzy3IT.js → stateDiagram-HBIQ2CUA-DwaXPGqn.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-8GCQZAvv.js +1 -0
- package/web-shell/assets/{swimlanes-XN3QIQJK-Bftk8V64.js → swimlanes-XN3QIQJK-BsaLeRDY.js} +1 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-BoRBF2Yw.js +8 -0
- package/web-shell/assets/{timeline-definition-24CTP7MA-BfXHcN1A.js → timeline-definition-24CTP7MA-NJ9G-NUU.js} +1 -1
- package/web-shell/assets/{vennDiagram-4TSXK5OY-DRSlI9-V.js → vennDiagram-4TSXK5OY-Ca3W4rSq.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-VM6X3IG4-CaLmqGau.js → wardleyDiagram-VM6X3IG4-OabvjC-6.js} +1 -1
- package/web-shell/assets/{xychartDiagram-S5SC5T6Z-8lgUT6e8.js → xychartDiagram-S5SC5T6Z-C7rbjvpc.js} +1 -1
- package/web-shell/index.html +2 -2
- package/chunks/chunk-2LD5U7Q3.js +0 -114
- package/chunks/chunk-3UMWOKJC.js +0 -78
- package/chunks/chunk-IQAFKVXS.js +0 -22
- package/chunks/chunk-X35VIWWJ.js +0 -276
- package/chunks/chunk-ZJ2LM2SI.js +0 -198
- 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-B4TLaxWs.js +0 -2142
- 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-FEEVHJOR.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-HWLLUDIA.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";
|
|
@@ -52,18 +52,20 @@ import {
|
|
|
52
52
|
ACP_PRE_ATTACH_MAX_PAYLOAD_BYTES_GLOBAL,
|
|
53
53
|
ACP_PRE_ATTACH_MAX_PAYLOAD_BYTES_PER_CONNECTION,
|
|
54
54
|
AcpPreAttachBudget,
|
|
55
|
+
AmbiguousLanInterfaceError,
|
|
55
56
|
CAPABILITIES_SCHEMA_VERSION,
|
|
56
57
|
ClientMcpSenderRegistry,
|
|
57
|
-
ConversationRuntimeOwnershipError,
|
|
58
58
|
CredentialStore,
|
|
59
59
|
DeviceFlowRegistry,
|
|
60
60
|
LocalPathOpenUnavailableError,
|
|
61
61
|
MAX_CONCURRENT_VOICE_SESSIONS,
|
|
62
62
|
MutableOriginAllowlist,
|
|
63
63
|
NativeDirectoryPickerUnavailableError,
|
|
64
|
+
NoLanInterfaceError,
|
|
64
65
|
PathMutexRegistry,
|
|
65
66
|
QWEN_CDP_MCP_COMMAND_ENV,
|
|
66
67
|
TooManyActiveDeviceFlowsError,
|
|
68
|
+
UnknownLanInterfaceError,
|
|
67
69
|
UnsupportedDeviceFlowProviderError,
|
|
68
70
|
UpstreamDeviceFlowError,
|
|
69
71
|
VoiceLeaseAbortError,
|
|
@@ -73,10 +75,6 @@ import {
|
|
|
73
75
|
bearerAuth,
|
|
74
76
|
brandSecret,
|
|
75
77
|
buildDaemonStatusResponse,
|
|
76
|
-
conversationRootCompromisedError,
|
|
77
|
-
conversationRuntimeInUseError,
|
|
78
|
-
conversationRuntimeOwnershipCompromisedError,
|
|
79
|
-
conversationRuntimeUnavailableError,
|
|
80
78
|
createBridgeFileSystemAdapter,
|
|
81
79
|
createClientMcpServerProvider,
|
|
82
80
|
createManagedScratchDirectory,
|
|
@@ -89,6 +87,7 @@ import {
|
|
|
89
87
|
getServeProtocolVersions,
|
|
90
88
|
hostAllowlist,
|
|
91
89
|
installAccessLogMiddleware,
|
|
90
|
+
installRemoteSelfOriginMiddleware,
|
|
92
91
|
installSelfOriginStripMiddleware,
|
|
93
92
|
installServeAppLifecycle,
|
|
94
93
|
isBrowserAutomationMcpAvailable,
|
|
@@ -98,6 +97,7 @@ import {
|
|
|
98
97
|
isNativeDirectoryPickerAvailable,
|
|
99
98
|
isScratchRootCompatible,
|
|
100
99
|
isTrustedLoopbackMode,
|
|
100
|
+
listLanCandidates,
|
|
101
101
|
listenerIdentityOf,
|
|
102
102
|
listenerIdentityOfSocket,
|
|
103
103
|
openPathLocally,
|
|
@@ -109,12 +109,13 @@ import {
|
|
|
109
109
|
resolveAcpHttpEnabled,
|
|
110
110
|
resolveCdpMcpCommand,
|
|
111
111
|
sanitizeForStderr,
|
|
112
|
+
selectLanAddress,
|
|
112
113
|
setDeviceFlowRegistry,
|
|
113
114
|
setRateLimiter,
|
|
114
115
|
singleTokenCredentials,
|
|
115
116
|
tagListener,
|
|
116
117
|
unsafeRevealSecret
|
|
117
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-VJJXG73H.js";
|
|
118
119
|
import {
|
|
119
120
|
ConversationDirectoryIdentityError,
|
|
120
121
|
getConversationDirectoryName,
|
|
@@ -125,15 +126,16 @@ import {
|
|
|
125
126
|
import "./chunk-UXEO7E3V.js";
|
|
126
127
|
import {
|
|
127
128
|
createTotalSessionAdmissionController
|
|
128
|
-
} from "./chunk-
|
|
129
|
+
} from "./chunk-YI2YCNSP.js";
|
|
129
130
|
import {
|
|
130
131
|
assertValidChannelSecretUpdates
|
|
131
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-UQOP2APG.js";
|
|
132
133
|
import {
|
|
133
134
|
AONE_MAX_MR_VIEW_CALLS_PER_RUN,
|
|
134
135
|
DaemonDrainingError,
|
|
135
136
|
InvalidCursorError,
|
|
136
137
|
SessionArchiveCoordinator,
|
|
138
|
+
acquireWorktreeOwnershipOp,
|
|
137
139
|
archiveDaemonSessions,
|
|
138
140
|
assertSessionArchived,
|
|
139
141
|
assertSessionLoadable,
|
|
@@ -156,7 +158,7 @@ import {
|
|
|
156
158
|
runWithWorkspaceRuntimeStorage,
|
|
157
159
|
searchWorkspaceSessionsForResponse,
|
|
158
160
|
unarchiveDaemonSessions
|
|
159
|
-
} from "./chunk-
|
|
161
|
+
} from "./chunk-7KZVXJ4U.js";
|
|
160
162
|
import {
|
|
161
163
|
LIVE_SESSION_SOURCE_PREFIX,
|
|
162
164
|
isCompatibleLiveSessionSource,
|
|
@@ -196,10 +198,10 @@ import {
|
|
|
196
198
|
isServeDebugMode,
|
|
197
199
|
mountWebShellAssets,
|
|
198
200
|
mountWebShellSpaFallback
|
|
199
|
-
} from "./chunk-
|
|
201
|
+
} from "./chunk-QB3KS3N3.js";
|
|
200
202
|
import {
|
|
201
203
|
require_express
|
|
202
|
-
} from "./chunk-
|
|
204
|
+
} from "./chunk-SVWWF5TZ.js";
|
|
203
205
|
import "./chunk-FBX2SDQ4.js";
|
|
204
206
|
import {
|
|
205
207
|
formatHostForAuthority,
|
|
@@ -208,17 +210,17 @@ import {
|
|
|
208
210
|
import {
|
|
209
211
|
evaluateDaemonWorkspaceTrust,
|
|
210
212
|
readDaemonTrustPolicySnapshot
|
|
211
|
-
} from "./chunk-
|
|
213
|
+
} from "./chunk-EE5ZD4XU.js";
|
|
212
214
|
import {
|
|
213
215
|
readRecentPromptTerminals,
|
|
214
216
|
reconcileDanglingPromptTerminals,
|
|
215
217
|
withPromptTerminals
|
|
216
|
-
} from "./chunk-
|
|
218
|
+
} from "./chunk-BZUHZCUO.js";
|
|
217
219
|
import {
|
|
218
220
|
WorkspaceGenerationClosedError,
|
|
219
221
|
createSingleWorkspaceRegistry,
|
|
220
222
|
createWorkspaceSessionOwnerIndex
|
|
221
|
-
} from "./chunk-
|
|
223
|
+
} from "./chunk-R7OO56VZ.js";
|
|
222
224
|
import {
|
|
223
225
|
sessionAttachmentsRoots
|
|
224
226
|
} from "./chunk-XWJFDJZK.js";
|
|
@@ -244,11 +246,11 @@ import {
|
|
|
244
246
|
sendUntrustedWorkspaceResponse,
|
|
245
247
|
sendWorkspaceRuntimeUnavailable,
|
|
246
248
|
setWorkspaceRouteContext
|
|
247
|
-
} from "./chunk-
|
|
249
|
+
} from "./chunk-EN3Q2S3J.js";
|
|
248
250
|
import {
|
|
249
251
|
normalizeChannelDelivery,
|
|
250
252
|
parseChannelDelivery
|
|
251
|
-
} from "./chunk-
|
|
253
|
+
} from "./chunk-VJWJOKOQ.js";
|
|
252
254
|
import {
|
|
253
255
|
isValidSessionId,
|
|
254
256
|
normalizeSessionIdForLookup,
|
|
@@ -263,7 +265,7 @@ import {
|
|
|
263
265
|
getWorkspaceRuntimeCoordinator,
|
|
264
266
|
getWorkspaceRuntimeCoordinatorIfSupported,
|
|
265
267
|
supportsWorkspaceRuntimeLifecycle
|
|
266
|
-
} from "./chunk-
|
|
268
|
+
} from "./chunk-HZ2HUXX7.js";
|
|
267
269
|
import "./chunk-OIBUG24X.js";
|
|
268
270
|
import {
|
|
269
271
|
MAX_SESSION_RESTORE_TIMEOUT_MS,
|
|
@@ -285,14 +287,14 @@ import {
|
|
|
285
287
|
validateWorkspaceSkillName,
|
|
286
288
|
validateWorkspaceVoiceState,
|
|
287
289
|
voiceSettingsScopeToWire
|
|
288
|
-
} from "./chunk-
|
|
290
|
+
} from "./chunk-7WCJEY3A.js";
|
|
289
291
|
import {
|
|
290
292
|
PermissionRulesValidationError,
|
|
291
293
|
buildPermissionSettings,
|
|
292
294
|
isPermissionRuleType,
|
|
293
295
|
normalizePermissionRules,
|
|
294
296
|
readPermissionRuleSet
|
|
295
|
-
} from "./chunk-
|
|
297
|
+
} from "./chunk-FN4KHWCL.js";
|
|
296
298
|
import {
|
|
297
299
|
assertVoiceBaseUrlNetworkAllowed,
|
|
298
300
|
isStreamingVoiceModel,
|
|
@@ -300,18 +302,18 @@ import {
|
|
|
300
302
|
resolveVoiceTranscriptionConfig,
|
|
301
303
|
sanitizeVoiceErrorMessage,
|
|
302
304
|
transcribeVoiceAudio
|
|
303
|
-
} from "./chunk-
|
|
305
|
+
} from "./chunk-GNY7B3CA.js";
|
|
304
306
|
import {
|
|
305
307
|
isVoiceEnabled,
|
|
306
308
|
isVoiceMode,
|
|
307
309
|
readVoiceModel
|
|
308
|
-
} from "./chunk-
|
|
310
|
+
} from "./chunk-NB3NDQQK.js";
|
|
309
311
|
import "./chunk-Y53DG2HA.js";
|
|
310
312
|
import {
|
|
311
313
|
createDaemonStatusProvider
|
|
312
|
-
} from "./chunk-
|
|
313
|
-
import "./chunk-
|
|
314
|
-
import "./chunk-
|
|
314
|
+
} from "./chunk-E4LXNQAK.js";
|
|
315
|
+
import "./chunk-O6BFERWN.js";
|
|
316
|
+
import "./chunk-LOBKNYPR.js";
|
|
315
317
|
import "./chunk-JS73NNWF.js";
|
|
316
318
|
import {
|
|
317
319
|
SessionArtifactAuthorizationError,
|
|
@@ -320,7 +322,7 @@ import {
|
|
|
320
322
|
extractErrorCode,
|
|
321
323
|
extractErrorMessage,
|
|
322
324
|
parseSessionSource
|
|
323
|
-
} from "./chunk-
|
|
325
|
+
} from "./chunk-ZZ7RVOTU.js";
|
|
324
326
|
import {
|
|
325
327
|
EVENT_SCHEMA_VERSION,
|
|
326
328
|
EventBus,
|
|
@@ -333,21 +335,21 @@ import {
|
|
|
333
335
|
} from "./chunk-KA5HR3G2.js";
|
|
334
336
|
import {
|
|
335
337
|
createWorkspaceProvidersStatusProvider
|
|
336
|
-
} from "./chunk-
|
|
338
|
+
} from "./chunk-D7DFZAK2.js";
|
|
337
339
|
import {
|
|
338
340
|
PERSIST_REASONING_SELECTION_META_KEY,
|
|
339
341
|
REASONING_SELECTION_PERSISTED_META_KEY
|
|
340
|
-
} from "./chunk-
|
|
342
|
+
} from "./chunk-N3Z6Q7KC.js";
|
|
341
343
|
import {
|
|
342
344
|
getAuthTypeFromEnv,
|
|
343
345
|
resolveCliGenerationConfig
|
|
344
|
-
} from "./chunk-
|
|
346
|
+
} from "./chunk-6GAYNM3F.js";
|
|
345
347
|
import {
|
|
346
348
|
snapshotProcessEnv
|
|
347
349
|
} from "./chunk-6RZX2HIH.js";
|
|
348
350
|
import {
|
|
349
351
|
createWorkspaceSkillsStatusProvider
|
|
350
|
-
} from "./chunk-
|
|
352
|
+
} from "./chunk-MUF4UGPB.js";
|
|
351
353
|
import "./chunk-BHTYRHJF.js";
|
|
352
354
|
import {
|
|
353
355
|
BridgeTimeoutError,
|
|
@@ -366,29 +368,35 @@ import {
|
|
|
366
368
|
WorkspaceSkillNotFoundError,
|
|
367
369
|
mapWorkspaceSkillToggleError
|
|
368
370
|
} from "./chunk-FTJMWDND.js";
|
|
369
|
-
import "./chunk-
|
|
371
|
+
import "./chunk-KECCLCXM.js";
|
|
370
372
|
import {
|
|
371
373
|
daemonObservedContactsPath,
|
|
372
374
|
loadChannelsConfig
|
|
373
|
-
} from "./chunk-
|
|
374
|
-
import "./chunk-
|
|
375
|
+
} from "./chunk-EDSU3VUG.js";
|
|
376
|
+
import "./chunk-6S7YYUUH.js";
|
|
375
377
|
import "./chunk-57OAHC2Y.js";
|
|
376
378
|
import {
|
|
377
379
|
parseChannelWebhookConfigLenient
|
|
378
|
-
} from "./chunk-
|
|
380
|
+
} from "./chunk-JFAGT5YG.js";
|
|
379
381
|
import {
|
|
380
382
|
supportedChannelCatalog
|
|
381
|
-
} from "./chunk-
|
|
382
|
-
import "./chunk-
|
|
383
|
+
} from "./chunk-7IDZFJAV.js";
|
|
384
|
+
import "./chunk-AUTUFD5X.js";
|
|
383
385
|
import "./chunk-V6WHFGST.js";
|
|
384
386
|
import {
|
|
387
|
+
assertLiveDiscoveryPublisher,
|
|
385
388
|
getStableLiveDiscoveryBaseDir
|
|
386
|
-
} from "./chunk-
|
|
389
|
+
} from "./chunk-WG7BL3FY.js";
|
|
387
390
|
import {
|
|
391
|
+
ConversationRuntimeOwnershipError,
|
|
388
392
|
LIVE_HOST_BUNDLE_ID,
|
|
389
393
|
LIVE_HOST_PROTOCOL_VERSION,
|
|
390
|
-
LIVE_INPUT_AUDIO_EPOCH_BYTES
|
|
391
|
-
|
|
394
|
+
LIVE_INPUT_AUDIO_EPOCH_BYTES,
|
|
395
|
+
conversationRootCompromisedError,
|
|
396
|
+
conversationRuntimeInUseError,
|
|
397
|
+
conversationRuntimeOwnershipCompromisedError,
|
|
398
|
+
conversationRuntimeUnavailableError
|
|
399
|
+
} from "./chunk-2Z3T52OC.js";
|
|
392
400
|
import "./chunk-ZL4HFSL6.js";
|
|
393
401
|
import "./chunk-K6KS3LTN.js";
|
|
394
402
|
import "./chunk-OSHQMOBS.js";
|
|
@@ -399,13 +407,13 @@ import {
|
|
|
399
407
|
WorkspaceRegistrationStoreLimitError,
|
|
400
408
|
normalizeWorkspaceDisplayName,
|
|
401
409
|
workspaceRegistrationId
|
|
402
|
-
} from "./chunk-
|
|
410
|
+
} from "./chunk-AXWTG6R7.js";
|
|
403
411
|
import {
|
|
404
412
|
CHANNEL_PROMPT_META_KEY,
|
|
405
413
|
DAEMON_PROMPT_DISPLAY_TEXT_META_KEY,
|
|
406
414
|
REQUESTED_SESSION_ID_META_KEY,
|
|
407
415
|
gradeActiveWorkCoverage
|
|
408
|
-
} from "./chunk-
|
|
416
|
+
} from "./chunk-PSPAM24S.js";
|
|
409
417
|
import {
|
|
410
418
|
BranchWhilePromptActiveError,
|
|
411
419
|
BridgeChannelQuarantinedError,
|
|
@@ -431,6 +439,7 @@ import {
|
|
|
431
439
|
SessionLimitExceededError,
|
|
432
440
|
SessionNotArchivedError,
|
|
433
441
|
SessionNotFoundError,
|
|
442
|
+
SessionResetPendingError,
|
|
434
443
|
SessionShellClientRequiredError,
|
|
435
444
|
SessionShellDisabledError,
|
|
436
445
|
StandaloneSessionSpawnError,
|
|
@@ -441,7 +450,7 @@ import {
|
|
|
441
450
|
WorkspaceInitRaceError,
|
|
442
451
|
WorkspaceInitSymlinkError,
|
|
443
452
|
WorkspaceMismatchError
|
|
444
|
-
} from "./chunk-
|
|
453
|
+
} from "./chunk-FAWTMDX7.js";
|
|
445
454
|
import {
|
|
446
455
|
MAX_WORKSPACE_PATH_LENGTH,
|
|
447
456
|
canonicalizeWorkspace,
|
|
@@ -461,7 +470,7 @@ import {
|
|
|
461
470
|
} from "./chunk-STUJ7IMZ.js";
|
|
462
471
|
import {
|
|
463
472
|
normalizeWorkerDiagnostic
|
|
464
|
-
} from "./chunk-
|
|
473
|
+
} from "./chunk-DARWOZY6.js";
|
|
465
474
|
import {
|
|
466
475
|
QWEN_SERVER_TOKEN_ENV
|
|
467
476
|
} from "./chunk-GYTKQYDB.js";
|
|
@@ -477,11 +486,11 @@ import {
|
|
|
477
486
|
redactLogCredentials
|
|
478
487
|
} from "./chunk-M5GB774H.js";
|
|
479
488
|
import "./chunk-3VUENPWF.js";
|
|
489
|
+
import "./chunk-TGNNLRC3.js";
|
|
480
490
|
import {
|
|
481
491
|
sanitizeLogText
|
|
482
|
-
} from "./chunk-
|
|
492
|
+
} from "./chunk-WDVV3LRM.js";
|
|
483
493
|
import "./chunk-IW6RQPQB.js";
|
|
484
|
-
import "./chunk-5HBA2Z7V.js";
|
|
485
494
|
import {
|
|
486
495
|
WORKSPACE_RESTRICTED_SETTING_KEYS,
|
|
487
496
|
getDialogSettingKeys,
|
|
@@ -494,8 +503,8 @@ import {
|
|
|
494
503
|
resolveOutputLanguageOrPreserveAuto,
|
|
495
504
|
updateOutputLanguageFile,
|
|
496
505
|
validateSettingValue
|
|
497
|
-
} from "./chunk-
|
|
498
|
-
import "./chunk-
|
|
506
|
+
} from "./chunk-Y7YHAY32.js";
|
|
507
|
+
import "./chunk-LOVGQ3HZ.js";
|
|
499
508
|
import "./chunk-RKUWKYED.js";
|
|
500
509
|
import "./chunk-BW4333PP.js";
|
|
501
510
|
import "./chunk-IDS7MSUP.js";
|
|
@@ -504,24 +513,23 @@ import {
|
|
|
504
513
|
getCurrentLanguage,
|
|
505
514
|
resolveLanguageSetting,
|
|
506
515
|
setLanguageAsync
|
|
507
|
-
} from "./chunk-
|
|
516
|
+
} from "./chunk-CRZBDVP2.js";
|
|
508
517
|
import {
|
|
509
518
|
SUPPORTED_LANGUAGES,
|
|
510
519
|
resolveSupportedLanguage
|
|
511
520
|
} from "./chunk-5EJZE3FP.js";
|
|
512
|
-
import "./chunk-
|
|
513
|
-
import "./chunk-
|
|
514
|
-
import "./chunk-
|
|
521
|
+
import "./chunk-43EUMPKQ.js";
|
|
522
|
+
import "./chunk-QTNCGZHQ.js";
|
|
523
|
+
import "./chunk-ATBLEXXV.js";
|
|
515
524
|
import "./chunk-W3N5XAZ6.js";
|
|
516
525
|
import {
|
|
517
526
|
getWorkspaceTrustStatus
|
|
518
|
-
} from "./chunk-
|
|
527
|
+
} from "./chunk-D6AGS266.js";
|
|
519
528
|
import "./chunk-NPQ5ZKRP.js";
|
|
520
529
|
import {
|
|
521
530
|
isWithinRoot as isWithinRoot2
|
|
522
531
|
} from "./chunk-MR3PXB6E.js";
|
|
523
532
|
import {
|
|
524
|
-
ALL_PROVIDERS,
|
|
525
533
|
BTW_MAX_INPUT_LENGTH,
|
|
526
534
|
ClientMcpRegistrar,
|
|
527
535
|
IMAGE_CAPABILITY,
|
|
@@ -530,26 +538,30 @@ import {
|
|
|
530
538
|
WorkspaceMemoryWriteTimeoutError,
|
|
531
539
|
buildUsageDashboard,
|
|
532
540
|
loadIgnoreRules,
|
|
533
|
-
shouldShowStep,
|
|
534
541
|
writeWorkspaceContextFile
|
|
535
|
-
} from "./chunk-
|
|
542
|
+
} from "./chunk-ZEFWBG2C.js";
|
|
536
543
|
import "./chunk-GELRJXE2.js";
|
|
537
544
|
import "./chunk-32CM56LO.js";
|
|
538
|
-
import "./chunk-
|
|
545
|
+
import "./chunk-3A2IMUDH.js";
|
|
539
546
|
import "./chunk-2EKVPSIJ.js";
|
|
540
547
|
import "./chunk-LJZSMWOH.js";
|
|
541
548
|
import {
|
|
549
|
+
clearWorktreeSession,
|
|
542
550
|
readWorktreeSession,
|
|
543
551
|
readWorktreeSessionStrict,
|
|
544
552
|
writeWorktreeSession
|
|
545
|
-
} from "./chunk-
|
|
546
|
-
import
|
|
553
|
+
} from "./chunk-YZTGGCEE.js";
|
|
554
|
+
import {
|
|
555
|
+
ALL_PROVIDERS,
|
|
556
|
+
shouldShowStep
|
|
557
|
+
} from "./chunk-PLEBBGHL.js";
|
|
558
|
+
import "./chunk-JGTMTJSQ.js";
|
|
547
559
|
import "./chunk-DJXSOEFB.js";
|
|
548
|
-
import "./chunk-
|
|
560
|
+
import "./chunk-LKBOBUA2.js";
|
|
549
561
|
import "./chunk-J3VZF2AL.js";
|
|
550
562
|
import "./chunk-OWCFKIFQ.js";
|
|
551
563
|
import "./chunk-ZPJWUGCS.js";
|
|
552
|
-
import "./chunk-
|
|
564
|
+
import "./chunk-7K4GGN3D.js";
|
|
553
565
|
import "./chunk-BUQN5LTI.js";
|
|
554
566
|
import {
|
|
555
567
|
QwenOAuth2Client,
|
|
@@ -559,8 +571,8 @@ import {
|
|
|
559
571
|
isDeviceAuthorizationSuccess,
|
|
560
572
|
isDeviceTokenPending,
|
|
561
573
|
isDeviceTokenSuccess
|
|
562
|
-
} from "./chunk-
|
|
563
|
-
import "./chunk-
|
|
574
|
+
} from "./chunk-XDNFODER.js";
|
|
575
|
+
import "./chunk-SM66GFKJ.js";
|
|
564
576
|
import "./chunk-VNOVK4I7.js";
|
|
565
577
|
import {
|
|
566
578
|
BuiltinAgentRegistry,
|
|
@@ -644,23 +656,25 @@ import {
|
|
|
644
656
|
toSessionPrInfo,
|
|
645
657
|
upsertSessionPr,
|
|
646
658
|
watchRepoBranch
|
|
647
|
-
} from "./chunk-
|
|
659
|
+
} from "./chunk-BDAVT6K2.js";
|
|
648
660
|
import "./chunk-GOFAQQZA.js";
|
|
649
|
-
import "./chunk-
|
|
661
|
+
import "./chunk-65I7S4Z3.js";
|
|
650
662
|
import "./chunk-6HUXPLB5.js";
|
|
651
663
|
import "./chunk-TWPJO254.js";
|
|
652
664
|
import "./chunk-CQ35AJ4Z.js";
|
|
653
|
-
import "./chunk-
|
|
665
|
+
import "./chunk-XKBFYTCD.js";
|
|
654
666
|
import "./chunk-LYT2OU7D.js";
|
|
655
|
-
import "./chunk-
|
|
667
|
+
import "./chunk-7CLLH5TI.js";
|
|
656
668
|
import {
|
|
657
669
|
GitWorktreeService,
|
|
670
|
+
WorktreeMarkerCommittedError,
|
|
658
671
|
createWorktreeSessionMarkerExclusive,
|
|
659
|
-
readWorktreeSessionMarkerStrict
|
|
660
|
-
|
|
672
|
+
readWorktreeSessionMarkerStrict,
|
|
673
|
+
transferWorktreeSessionMarkerOwner
|
|
674
|
+
} from "./chunk-HIXUUCGY.js";
|
|
661
675
|
import "./chunk-6PVPNMXU.js";
|
|
662
676
|
import "./chunk-565U2ANU.js";
|
|
663
|
-
import "./chunk-
|
|
677
|
+
import "./chunk-GSFV5RQW.js";
|
|
664
678
|
import "./chunk-IRH27ZC2.js";
|
|
665
679
|
import "./chunk-QHWCP53L.js";
|
|
666
680
|
import {
|
|
@@ -677,8 +691,8 @@ import "./chunk-N6S3NUYJ.js";
|
|
|
677
691
|
import "./chunk-O6GEWCJA.js";
|
|
678
692
|
import "./chunk-CHEIIBT3.js";
|
|
679
693
|
import "./chunk-QAZ2MGYT.js";
|
|
680
|
-
import "./chunk-
|
|
681
|
-
import "./chunk-
|
|
694
|
+
import "./chunk-F4SAL7WM.js";
|
|
695
|
+
import "./chunk-CH2YDT6X.js";
|
|
682
696
|
import {
|
|
683
697
|
APPROVAL_MODES
|
|
684
698
|
} from "./chunk-JX6XHPTX.js";
|
|
@@ -688,25 +702,25 @@ import {
|
|
|
688
702
|
validateSkillName
|
|
689
703
|
} from "./chunk-CLKE4IY3.js";
|
|
690
704
|
import "./chunk-ZSTCM3MX.js";
|
|
691
|
-
import "./chunk-
|
|
705
|
+
import "./chunk-SOA4HKRJ.js";
|
|
692
706
|
import "./chunk-MLXTMF7H.js";
|
|
693
|
-
import "./chunk-
|
|
707
|
+
import "./chunk-2HYOOFDS.js";
|
|
694
708
|
import {
|
|
695
709
|
findGitRoot
|
|
696
710
|
} from "./chunk-3CZ2BQV6.js";
|
|
697
711
|
import "./chunk-PQEISIKS.js";
|
|
698
|
-
import "./chunk-
|
|
712
|
+
import "./chunk-HSO6D4KX.js";
|
|
699
713
|
import "./chunk-H3Q3RSKZ.js";
|
|
700
714
|
import "./chunk-S6LOFUVP.js";
|
|
701
715
|
import "./chunk-NAVJD2PQ.js";
|
|
702
|
-
import "./chunk-
|
|
703
|
-
import "./chunk-
|
|
716
|
+
import "./chunk-OFVAS4AR.js";
|
|
717
|
+
import "./chunk-HNLMYDQE.js";
|
|
704
718
|
import "./chunk-QHMLYMMS.js";
|
|
705
719
|
import "./chunk-CFKIH3D3.js";
|
|
706
|
-
import "./chunk-
|
|
720
|
+
import "./chunk-AXMWHKXA.js";
|
|
707
721
|
import "./chunk-DJ2GSRLV.js";
|
|
708
|
-
import "./chunk-
|
|
709
|
-
import "./chunk-
|
|
722
|
+
import "./chunk-4ALNJDHL.js";
|
|
723
|
+
import "./chunk-NOO4QFXM.js";
|
|
710
724
|
import "./chunk-KFFCDLKV.js";
|
|
711
725
|
import {
|
|
712
726
|
addDaemonRequestAttribute,
|
|
@@ -724,9 +738,9 @@ import "./chunk-XWRJCPHC.js";
|
|
|
724
738
|
import {
|
|
725
739
|
parseLineTolerant,
|
|
726
740
|
read
|
|
727
|
-
} from "./chunk-
|
|
741
|
+
} from "./chunk-FRS3P7MQ.js";
|
|
728
742
|
import "./chunk-5ETULJLP.js";
|
|
729
|
-
import "./chunk-
|
|
743
|
+
import "./chunk-GSYD7MYP.js";
|
|
730
744
|
import "./chunk-VGC4I5JJ.js";
|
|
731
745
|
import {
|
|
732
746
|
CursorNotAtLineBoundaryError,
|
|
@@ -740,9 +754,9 @@ import {
|
|
|
740
754
|
import "./chunk-EDIDYZBT.js";
|
|
741
755
|
import "./chunk-HD7O6WLV.js";
|
|
742
756
|
import "./chunk-WZAD4ZNJ.js";
|
|
743
|
-
import "./chunk-
|
|
757
|
+
import "./chunk-F3M6P6IQ.js";
|
|
744
758
|
import "./chunk-TIGXX4PA.js";
|
|
745
|
-
import "./chunk-
|
|
759
|
+
import "./chunk-EOLGAQ25.js";
|
|
746
760
|
import "./chunk-XFFRI3WM.js";
|
|
747
761
|
import "./chunk-4HOEU2OR.js";
|
|
748
762
|
import "./chunk-HHJLM3WQ.js";
|
|
@@ -802,93 +816,6 @@ import * as path18 from "node:path";
|
|
|
802
816
|
// packages/cli/src/serve/local-control/index.ts
|
|
803
817
|
init_esbuild_shims();
|
|
804
818
|
|
|
805
|
-
// packages/cli/src/serve/local-control/lan-interfaces.ts
|
|
806
|
-
init_esbuild_shims();
|
|
807
|
-
import { networkInterfaces } from "node:os";
|
|
808
|
-
function isLanIpv4(address) {
|
|
809
|
-
const octets = address.split(".").map((part) => Number(part));
|
|
810
|
-
if (octets.length !== 4 || octets.some((o) => !Number.isInteger(o))) {
|
|
811
|
-
return false;
|
|
812
|
-
}
|
|
813
|
-
const [a, b] = octets;
|
|
814
|
-
if (a === 10) return true;
|
|
815
|
-
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
816
|
-
if (a === 192 && b === 168) return true;
|
|
817
|
-
if (a === 169 && b === 254) return true;
|
|
818
|
-
return false;
|
|
819
|
-
}
|
|
820
|
-
__name(isLanIpv4, "isLanIpv4");
|
|
821
|
-
function isSoftwareNetwork(interfaceName) {
|
|
822
|
-
if (/vpn/i.test(interfaceName)) return true;
|
|
823
|
-
return /(^|[\s_.-])(utun|tun|tap|ppp|ipsec|wg|wireguard|tailscale|zerotier|zt[a-z0-9]*|hamachi|nordlynx|proton|wintun|docker|veth[0-9a-f]+|vmnet|vboxnet|vethernet|virtualbox|host[- ]only|podman|cni|lxcbr|lxdbr|flannel|virbr|br-[0-9a-f]+|bridge\d|anyconnect|globalprotect|pulse[\s-]secure|forticlient|fortinet|ivanti|cisco[\s_-]secure|citrix|sonicwall|cloudflare)(\d|[\s_.-]|$)/i.test(
|
|
824
|
-
interfaceName
|
|
825
|
-
);
|
|
826
|
-
}
|
|
827
|
-
__name(isSoftwareNetwork, "isSoftwareNetwork");
|
|
828
|
-
function listLanCandidates(interfaces = networkInterfaces()) {
|
|
829
|
-
const candidates = [];
|
|
830
|
-
for (const [interfaceName, addresses] of Object.entries(interfaces).sort()) {
|
|
831
|
-
if (isSoftwareNetwork(interfaceName)) continue;
|
|
832
|
-
for (const address of addresses ?? []) {
|
|
833
|
-
if (address.family !== "IPv4" || address.internal) continue;
|
|
834
|
-
if (!isLanIpv4(address.address)) continue;
|
|
835
|
-
candidates.push({ interfaceName, address: address.address });
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
return candidates;
|
|
839
|
-
}
|
|
840
|
-
__name(listLanCandidates, "listLanCandidates");
|
|
841
|
-
var NoLanInterfaceError = class extends Error {
|
|
842
|
-
static {
|
|
843
|
-
__name(this, "NoLanInterfaceError");
|
|
844
|
-
}
|
|
845
|
-
code = "no_lan_interface";
|
|
846
|
-
constructor() {
|
|
847
|
-
super(
|
|
848
|
-
"No private IPv4 address is available. Local Control needs the host to be on a local network (Wi-Fi or Ethernet)."
|
|
849
|
-
);
|
|
850
|
-
this.name = "NoLanInterfaceError";
|
|
851
|
-
}
|
|
852
|
-
};
|
|
853
|
-
var AmbiguousLanInterfaceError = class extends Error {
|
|
854
|
-
static {
|
|
855
|
-
__name(this, "AmbiguousLanInterfaceError");
|
|
856
|
-
}
|
|
857
|
-
code = "ambiguous_lan_interface";
|
|
858
|
-
candidates;
|
|
859
|
-
constructor(candidates) {
|
|
860
|
-
super(
|
|
861
|
-
"Multiple local networks are available; choose which one to expose: " + candidates.map((c) => `${c.interfaceName} (${c.address})`).join(", ")
|
|
862
|
-
);
|
|
863
|
-
this.name = "AmbiguousLanInterfaceError";
|
|
864
|
-
this.candidates = candidates;
|
|
865
|
-
}
|
|
866
|
-
};
|
|
867
|
-
var UnknownLanInterfaceError = class extends Error {
|
|
868
|
-
static {
|
|
869
|
-
__name(this, "UnknownLanInterfaceError");
|
|
870
|
-
}
|
|
871
|
-
code = "unknown_lan_interface";
|
|
872
|
-
constructor(requested) {
|
|
873
|
-
super(
|
|
874
|
-
`${requested} is not a private IPv4 address on this host right now. The network may have changed since the list was fetched.`
|
|
875
|
-
);
|
|
876
|
-
this.name = "UnknownLanInterfaceError";
|
|
877
|
-
}
|
|
878
|
-
};
|
|
879
|
-
function selectLanAddress(preferredAddress, interfaces = networkInterfaces()) {
|
|
880
|
-
const candidates = listLanCandidates(interfaces);
|
|
881
|
-
if (candidates.length === 0) throw new NoLanInterfaceError();
|
|
882
|
-
if (preferredAddress !== void 0) {
|
|
883
|
-
const match = candidates.find((c) => c.address === preferredAddress);
|
|
884
|
-
if (!match) throw new UnknownLanInterfaceError(preferredAddress);
|
|
885
|
-
return match;
|
|
886
|
-
}
|
|
887
|
-
if (candidates.length > 1) throw new AmbiguousLanInterfaceError(candidates);
|
|
888
|
-
return candidates[0];
|
|
889
|
-
}
|
|
890
|
-
__name(selectLanAddress, "selectLanAddress");
|
|
891
|
-
|
|
892
819
|
// packages/cli/src/serve/local-control/service.ts
|
|
893
820
|
init_esbuild_shims();
|
|
894
821
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
@@ -6220,7 +6147,7 @@ __name(createRequestedSessionIdAdmission, "createRequestedSessionIdAdmission");
|
|
|
6220
6147
|
|
|
6221
6148
|
// packages/cli/src/serve/conversations/standalone-session-service.ts
|
|
6222
6149
|
init_esbuild_shims();
|
|
6223
|
-
import { randomUUID as
|
|
6150
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
6224
6151
|
|
|
6225
6152
|
// packages/cli/src/serve/server/session-export.ts
|
|
6226
6153
|
init_esbuild_shims();
|
|
@@ -6289,473 +6216,10 @@ __name(exportSessionTranscript, "exportSessionTranscript");
|
|
|
6289
6216
|
|
|
6290
6217
|
// packages/cli/src/serve/conversations/standalone-deletion-journal.ts
|
|
6291
6218
|
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
6219
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
6300
6220
|
import { constants as fsConstants2 } from "node:fs";
|
|
6301
6221
|
import * as fs from "node:fs/promises";
|
|
6302
6222
|
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
6223
|
var JOURNAL_DIRECTORY = "deletions";
|
|
6760
6224
|
var MAX_RECORD_BYTES = 8 * 1024;
|
|
6761
6225
|
var STORAGE_SESSION_ID_PATTERN = /^[0-9a-fA-F-]{32,36}$/;
|
|
@@ -6770,10 +6234,10 @@ var StandaloneDeletionJournalError = class extends Error {
|
|
|
6770
6234
|
}
|
|
6771
6235
|
name = "StandaloneDeletionJournalError";
|
|
6772
6236
|
};
|
|
6773
|
-
function
|
|
6237
|
+
function isMissing(error2) {
|
|
6774
6238
|
return error2.code === "ENOENT";
|
|
6775
6239
|
}
|
|
6776
|
-
__name(
|
|
6240
|
+
__name(isMissing, "isMissing");
|
|
6777
6241
|
function parseSessionId(value) {
|
|
6778
6242
|
const parsed = parseCallerSuppliedSessionId(value);
|
|
6779
6243
|
if (parsed.kind !== "valid") {
|
|
@@ -6804,7 +6268,7 @@ function parseIdentity(value, pathField) {
|
|
|
6804
6268
|
if (!isIdentityNumber(value["device"]) || !isIdentityNumber(value["inode"]) || typeof value["inodeVerifiable"] !== "boolean" || (value["inodeVerifiable"] ? value["inode"] === 0 : value["inode"] !== 0)) {
|
|
6805
6269
|
return void 0;
|
|
6806
6270
|
}
|
|
6807
|
-
if (pathField && (typeof value["canonicalPath"] !== "string" || value["canonicalPath"].length === 0 || value["canonicalPath"].length > 4096 || !
|
|
6271
|
+
if (pathField && (typeof value["canonicalPath"] !== "string" || value["canonicalPath"].length === 0 || value["canonicalPath"].length > 4096 || !path7.isAbsolute(value["canonicalPath"]))) {
|
|
6808
6272
|
return void 0;
|
|
6809
6273
|
}
|
|
6810
6274
|
return {
|
|
@@ -6899,25 +6363,26 @@ function sameImmutableRecord(prepared, staged) {
|
|
|
6899
6363
|
}
|
|
6900
6364
|
__name(sameImmutableRecord, "sameImmutableRecord");
|
|
6901
6365
|
var StandaloneDeletionJournal = class {
|
|
6366
|
+
constructor(stableBaseDir) {
|
|
6367
|
+
this.stableBaseDir = stableBaseDir;
|
|
6368
|
+
if (!path7.isAbsolute(stableBaseDir)) {
|
|
6369
|
+
throw new TypeError("Standalone deletion journal base must be absolute.");
|
|
6370
|
+
}
|
|
6371
|
+
this.stateDirectory = path7.join(stableBaseDir, "conversations");
|
|
6372
|
+
this.journalDirectory = path7.join(this.stateDirectory, JOURNAL_DIRECTORY);
|
|
6373
|
+
}
|
|
6902
6374
|
static {
|
|
6903
6375
|
__name(this, "StandaloneDeletionJournal");
|
|
6904
6376
|
}
|
|
6905
|
-
|
|
6377
|
+
stateDirectory;
|
|
6906
6378
|
journalDirectory;
|
|
6379
|
+
directoryIdentities = /* @__PURE__ */ new Map();
|
|
6380
|
+
canonicalBaseDir;
|
|
6907
6381
|
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
6382
|
async hasRecord(rawSessionId) {
|
|
6918
6383
|
const sessionId = parseSessionId(rawSessionId);
|
|
6919
|
-
if (this.pendingClears.has(sessionId)) return true;
|
|
6920
6384
|
const identity = await this.inspectJournalDirectory();
|
|
6385
|
+
if (this.pendingClears.has(sessionId)) return true;
|
|
6921
6386
|
if (!identity) return false;
|
|
6922
6387
|
const exists = await this.pathExists(this.recordPath(sessionId, "prepared")) || await this.pathExists(this.recordPath(sessionId, "staged"));
|
|
6923
6388
|
await this.assertDirectoryIdentity(this.journalDirectory, identity);
|
|
@@ -6931,9 +6396,9 @@ var StandaloneDeletionJournal = class {
|
|
|
6931
6396
|
}
|
|
6932
6397
|
let names;
|
|
6933
6398
|
try {
|
|
6934
|
-
names = await
|
|
6399
|
+
names = await fs.readdir(this.journalDirectory);
|
|
6935
6400
|
} catch (error2) {
|
|
6936
|
-
if (
|
|
6401
|
+
if (isMissing(error2)) {
|
|
6937
6402
|
return [...ids].sort().slice(0, Math.max(0, limit));
|
|
6938
6403
|
}
|
|
6939
6404
|
throw error2;
|
|
@@ -6947,11 +6412,11 @@ var StandaloneDeletionJournal = class {
|
|
|
6947
6412
|
}
|
|
6948
6413
|
async read(rawSessionId, currentRoot) {
|
|
6949
6414
|
const sessionId = parseSessionId(rawSessionId);
|
|
6415
|
+
const identity = await this.inspectJournalDirectory();
|
|
6950
6416
|
const pending = this.pendingClears.get(sessionId);
|
|
6951
6417
|
if (pending) {
|
|
6952
6418
|
return this.validatePendingEntry(pending.entry, currentRoot);
|
|
6953
6419
|
}
|
|
6954
|
-
const identity = await this.inspectJournalDirectory();
|
|
6955
6420
|
if (!identity) return void 0;
|
|
6956
6421
|
const prepared = await this.readPhase(sessionId, "prepared", currentRoot);
|
|
6957
6422
|
const staged = await this.readPhase(sessionId, "staged", currentRoot);
|
|
@@ -6994,6 +6459,7 @@ var StandaloneDeletionJournal = class {
|
|
|
6994
6459
|
}
|
|
6995
6460
|
async clear(rawSessionId, currentRoot) {
|
|
6996
6461
|
const sessionId = parseSessionId(rawSessionId);
|
|
6462
|
+
await this.inspectJournalDirectory();
|
|
6997
6463
|
const pending = this.pendingClears.get(sessionId);
|
|
6998
6464
|
if (pending) {
|
|
6999
6465
|
this.validatePendingEntry(pending.entry, currentRoot);
|
|
@@ -7045,7 +6511,7 @@ var StandaloneDeletionJournal = class {
|
|
|
7045
6511
|
return { prepared, ...staged ? { staged } : {} };
|
|
7046
6512
|
}
|
|
7047
6513
|
recordPath(sessionId, phase) {
|
|
7048
|
-
return
|
|
6514
|
+
return path7.join(
|
|
7049
6515
|
this.journalDirectory,
|
|
7050
6516
|
`delete-${sessionId}.${phase}.json`
|
|
7051
6517
|
);
|
|
@@ -7054,17 +6520,17 @@ var StandaloneDeletionJournal = class {
|
|
|
7054
6520
|
const filePath = this.recordPath(sessionId, phase);
|
|
7055
6521
|
let pathStat;
|
|
7056
6522
|
try {
|
|
7057
|
-
pathStat = await
|
|
6523
|
+
pathStat = await fs.lstat(filePath);
|
|
7058
6524
|
} catch (error2) {
|
|
7059
|
-
if (
|
|
6525
|
+
if (isMissing(error2)) return void 0;
|
|
7060
6526
|
throw error2;
|
|
7061
6527
|
}
|
|
7062
6528
|
this.assertRecordFile(pathStat);
|
|
7063
6529
|
let handle;
|
|
7064
6530
|
try {
|
|
7065
|
-
handle = await
|
|
6531
|
+
handle = await fs.open(
|
|
7066
6532
|
filePath,
|
|
7067
|
-
|
|
6533
|
+
fsConstants2.O_RDONLY | (process.platform === "win32" ? 0 : fsConstants2.O_NOFOLLOW ?? 0)
|
|
7068
6534
|
);
|
|
7069
6535
|
} catch (error2) {
|
|
7070
6536
|
if (error2.code === "ELOOP") {
|
|
@@ -7099,9 +6565,9 @@ var StandaloneDeletionJournal = class {
|
|
|
7099
6565
|
const identity = await this.ensureJournalDirectory();
|
|
7100
6566
|
const target = this.recordPath(record.sessionId, record.phase);
|
|
7101
6567
|
await this.assertPathAbsent(target);
|
|
7102
|
-
const temporary =
|
|
6568
|
+
const temporary = path7.join(
|
|
7103
6569
|
this.journalDirectory,
|
|
7104
|
-
`.${
|
|
6570
|
+
`.${path7.basename(target)}.${randomUUID3()}.tmp`
|
|
7105
6571
|
);
|
|
7106
6572
|
const directory = await this.openDurableDirectory(
|
|
7107
6573
|
this.journalDirectory,
|
|
@@ -7110,9 +6576,9 @@ var StandaloneDeletionJournal = class {
|
|
|
7110
6576
|
let handle;
|
|
7111
6577
|
try {
|
|
7112
6578
|
await this.assertDirectoryIdentity(this.journalDirectory, identity);
|
|
7113
|
-
handle = await
|
|
6579
|
+
handle = await fs.open(
|
|
7114
6580
|
temporary,
|
|
7115
|
-
|
|
6581
|
+
fsConstants2.O_CREAT | fsConstants2.O_EXCL | fsConstants2.O_WRONLY | (process.platform === "win32" ? 0 : fsConstants2.O_NOFOLLOW ?? 0),
|
|
7116
6582
|
384
|
|
7117
6583
|
);
|
|
7118
6584
|
await handle.writeFile(serialized, "utf8");
|
|
@@ -7121,12 +6587,12 @@ var StandaloneDeletionJournal = class {
|
|
|
7121
6587
|
handle = void 0;
|
|
7122
6588
|
await this.assertDirectoryIdentity(this.journalDirectory, identity);
|
|
7123
6589
|
await this.assertPathAbsent(target);
|
|
7124
|
-
await
|
|
7125
|
-
if (process.platform !== "win32") await
|
|
6590
|
+
await fs.rename(temporary, target);
|
|
6591
|
+
if (process.platform !== "win32") await fs.chmod(target, 384);
|
|
7126
6592
|
await this.syncDurableDirectory(directory);
|
|
7127
6593
|
} catch (error2) {
|
|
7128
6594
|
await handle?.close().catch(() => void 0);
|
|
7129
|
-
await
|
|
6595
|
+
await fs.unlink(temporary).catch(() => void 0);
|
|
7130
6596
|
if (error2.code === "EEXIST") {
|
|
7131
6597
|
throw new StandaloneDeletionJournalError("conflict");
|
|
7132
6598
|
}
|
|
@@ -7136,48 +6602,107 @@ var StandaloneDeletionJournal = class {
|
|
|
7136
6602
|
}
|
|
7137
6603
|
}
|
|
7138
6604
|
async ensureJournalDirectory() {
|
|
7139
|
-
|
|
6605
|
+
await this.ensureStateDirectory(this.stableBaseDir, false);
|
|
6606
|
+
const owner = await this.ensureStateDirectory(this.stateDirectory, true);
|
|
7140
6607
|
const ownerHandle = await this.openDurableDirectory(
|
|
7141
|
-
this.
|
|
6608
|
+
this.stateDirectory,
|
|
7142
6609
|
owner
|
|
7143
6610
|
);
|
|
7144
6611
|
try {
|
|
7145
6612
|
let created = false;
|
|
7146
6613
|
try {
|
|
7147
|
-
await
|
|
6614
|
+
await fs.mkdir(this.journalDirectory, { mode: 448 });
|
|
7148
6615
|
created = true;
|
|
7149
6616
|
} catch (error2) {
|
|
7150
6617
|
if (error2.code !== "EEXIST") throw error2;
|
|
7151
6618
|
}
|
|
7152
6619
|
if (created && process.platform !== "win32") {
|
|
7153
|
-
await
|
|
6620
|
+
await fs.chmod(this.journalDirectory, 448);
|
|
7154
6621
|
}
|
|
7155
6622
|
await this.syncDurableDirectory(ownerHandle);
|
|
7156
6623
|
} finally {
|
|
7157
6624
|
await ownerHandle.handle.close().catch(() => void 0);
|
|
7158
6625
|
}
|
|
7159
|
-
return this.
|
|
6626
|
+
return await this.inspectJournalDirectory();
|
|
6627
|
+
}
|
|
6628
|
+
async ensureStateDirectory(directory, requirePrivate) {
|
|
6629
|
+
try {
|
|
6630
|
+
return await this.inspectPrivateDirectory(directory, requirePrivate);
|
|
6631
|
+
} catch (error2) {
|
|
6632
|
+
if (!isMissing(error2)) throw error2;
|
|
6633
|
+
}
|
|
6634
|
+
const parent = path7.dirname(directory);
|
|
6635
|
+
if (parent === directory)
|
|
6636
|
+
throw new StandaloneDeletionJournalError("compromised");
|
|
6637
|
+
const before = await this.ensureStateDirectory(parent, false);
|
|
6638
|
+
let created = false;
|
|
6639
|
+
try {
|
|
6640
|
+
await fs.mkdir(directory, { mode: 448 });
|
|
6641
|
+
created = true;
|
|
6642
|
+
} catch (error2) {
|
|
6643
|
+
if (error2.code !== "EEXIST") throw error2;
|
|
6644
|
+
}
|
|
6645
|
+
if (created && process.platform !== "win32")
|
|
6646
|
+
await fs.chmod(directory, 448);
|
|
6647
|
+
const after = await this.inspectPrivateDirectory(parent, false);
|
|
6648
|
+
if (!sameDirectoryIdentity(before, after)) {
|
|
6649
|
+
throw new StandaloneDeletionJournalError("compromised");
|
|
6650
|
+
}
|
|
6651
|
+
const handle = await fs.open(parent, fsConstants2.O_RDONLY);
|
|
6652
|
+
try {
|
|
6653
|
+
if (process.platform !== "win32") await handle.sync();
|
|
6654
|
+
} finally {
|
|
6655
|
+
await handle.close();
|
|
6656
|
+
}
|
|
6657
|
+
return this.inspectPrivateDirectory(directory, requirePrivate);
|
|
6658
|
+
}
|
|
6659
|
+
async inspectStateParent() {
|
|
6660
|
+
await this.inspectPrivateDirectory(this.stableBaseDir, false);
|
|
6661
|
+
const canonical = await fs.realpath(this.stableBaseDir);
|
|
6662
|
+
if (this.canonicalBaseDir !== void 0 && this.canonicalBaseDir !== canonical) {
|
|
6663
|
+
throw new StandaloneDeletionJournalError("compromised");
|
|
6664
|
+
}
|
|
6665
|
+
this.canonicalBaseDir = canonical;
|
|
6666
|
+
await this.inspectPrivateDirectory(this.stateDirectory);
|
|
7160
6667
|
}
|
|
7161
6668
|
async inspectJournalDirectory() {
|
|
7162
6669
|
try {
|
|
6670
|
+
await this.inspectStateParent();
|
|
7163
6671
|
return await this.inspectPrivateDirectory(this.journalDirectory);
|
|
7164
6672
|
} catch (error2) {
|
|
7165
|
-
if (
|
|
6673
|
+
if (isMissing(error2)) return void 0;
|
|
7166
6674
|
throw error2;
|
|
7167
6675
|
}
|
|
7168
6676
|
}
|
|
7169
|
-
async inspectPrivateDirectory(directory) {
|
|
7170
|
-
|
|
7171
|
-
|
|
6677
|
+
async inspectPrivateDirectory(directory, requirePrivate = true) {
|
|
6678
|
+
let stat3;
|
|
6679
|
+
try {
|
|
6680
|
+
stat3 = await fs.lstat(directory);
|
|
6681
|
+
} catch (error2) {
|
|
6682
|
+
if (isMissing(error2) && this.directoryIdentities.has(directory)) {
|
|
6683
|
+
throw new StandaloneDeletionJournalError("compromised");
|
|
6684
|
+
}
|
|
6685
|
+
throw error2;
|
|
6686
|
+
}
|
|
6687
|
+
if (!stat3.isDirectory() || stat3.isSymbolicLink() || process.platform !== "win32" && (requirePrivate && (stat3.mode & 511) !== 448 || typeof process.getuid === "function" && stat3.uid !== process.getuid())) {
|
|
7172
6688
|
throw new StandaloneDeletionJournalError("compromised");
|
|
7173
6689
|
}
|
|
7174
|
-
|
|
6690
|
+
const identity = {
|
|
7175
6691
|
device: stat3.dev,
|
|
7176
6692
|
inode: normalizedInode(stat3.ino),
|
|
7177
6693
|
inodeVerifiable: hasVerifiableInode(stat3.ino)
|
|
7178
6694
|
};
|
|
6695
|
+
if (directory === this.stableBaseDir || directory === this.stateDirectory || directory === this.journalDirectory) {
|
|
6696
|
+
const expected = this.directoryIdentities.get(directory);
|
|
6697
|
+
if (expected && !sameDirectoryIdentity(identity, expected)) {
|
|
6698
|
+
throw new StandaloneDeletionJournalError("compromised");
|
|
6699
|
+
}
|
|
6700
|
+
this.directoryIdentities.set(directory, identity);
|
|
6701
|
+
}
|
|
6702
|
+
return identity;
|
|
7179
6703
|
}
|
|
7180
6704
|
async assertDirectoryIdentity(directory, expected) {
|
|
6705
|
+
await this.inspectStateParent();
|
|
7181
6706
|
const current = await this.inspectPrivateDirectory(directory);
|
|
7182
6707
|
if (!sameDirectoryIdentity(current, expected)) {
|
|
7183
6708
|
throw new StandaloneDeletionJournalError("compromised");
|
|
@@ -7190,35 +6715,35 @@ var StandaloneDeletionJournal = class {
|
|
|
7190
6715
|
}
|
|
7191
6716
|
async assertPathAbsent(filePath) {
|
|
7192
6717
|
try {
|
|
7193
|
-
await
|
|
6718
|
+
await fs.lstat(filePath);
|
|
7194
6719
|
} catch (error2) {
|
|
7195
|
-
if (
|
|
6720
|
+
if (isMissing(error2)) return;
|
|
7196
6721
|
throw error2;
|
|
7197
6722
|
}
|
|
7198
6723
|
throw new StandaloneDeletionJournalError("conflict");
|
|
7199
6724
|
}
|
|
7200
6725
|
async pathExists(filePath) {
|
|
7201
6726
|
try {
|
|
7202
|
-
await
|
|
6727
|
+
await fs.lstat(filePath);
|
|
7203
6728
|
return true;
|
|
7204
6729
|
} catch (error2) {
|
|
7205
|
-
if (
|
|
6730
|
+
if (isMissing(error2)) return false;
|
|
7206
6731
|
throw error2;
|
|
7207
6732
|
}
|
|
7208
6733
|
}
|
|
7209
6734
|
async unlinkIfExists(filePath) {
|
|
7210
6735
|
try {
|
|
7211
|
-
await
|
|
6736
|
+
await fs.unlink(filePath);
|
|
7212
6737
|
} catch (error2) {
|
|
7213
|
-
if (!
|
|
6738
|
+
if (!isMissing(error2)) throw error2;
|
|
7214
6739
|
}
|
|
7215
6740
|
}
|
|
7216
6741
|
async openDurableDirectory(directory, expected) {
|
|
7217
6742
|
let handle;
|
|
7218
6743
|
try {
|
|
7219
|
-
handle = await
|
|
6744
|
+
handle = await fs.open(
|
|
7220
6745
|
directory,
|
|
7221
|
-
|
|
6746
|
+
fsConstants2.O_RDONLY | (process.platform === "win32" ? 0 : fsConstants2.O_NOFOLLOW ?? 0)
|
|
7222
6747
|
);
|
|
7223
6748
|
const opened = await handle.stat();
|
|
7224
6749
|
const openedIdentity = {
|
|
@@ -7375,6 +6900,7 @@ function mergeLiveStandaloneSummary(persisted, live) {
|
|
|
7375
6900
|
updatedAt: laterTimestamp(live.updatedAt, persisted.updatedAt),
|
|
7376
6901
|
clientCount: live.clientCount,
|
|
7377
6902
|
hasActivePrompt: live.hasActivePrompt,
|
|
6903
|
+
...live.activeWorkState !== void 0 ? { activeWorkState: live.activeWorkState } : {},
|
|
7378
6904
|
...live.isWaitingForPermission !== void 0 ? { isWaitingForPermission: live.isWaitingForPermission } : {},
|
|
7379
6905
|
...live.isWaitingForUserQuestion !== void 0 ? { isWaitingForUserQuestion: live.isWaitingForUserQuestion } : {},
|
|
7380
6906
|
...live.pendingInteractionCount !== void 0 ? { pendingInteractionCount: live.pendingInteractionCount } : {},
|
|
@@ -7586,7 +7112,7 @@ var StandaloneSessionService = class {
|
|
|
7586
7112
|
});
|
|
7587
7113
|
}
|
|
7588
7114
|
async repairDirectory(rawSessionId) {
|
|
7589
|
-
const clientId =
|
|
7115
|
+
const clientId = randomUUID4();
|
|
7590
7116
|
const restored = await this.restore("resume", rawSessionId, { clientId });
|
|
7591
7117
|
try {
|
|
7592
7118
|
await this.cleanupDisconnectedRestore(restored);
|
|
@@ -9058,7 +8584,7 @@ var StandaloneSessionService = class {
|
|
|
9058
8584
|
}
|
|
9059
8585
|
return { ...created, initialPrompt: created.initialPrompt };
|
|
9060
8586
|
}
|
|
9061
|
-
async createInternal(request2, prompt, parentSessionId, promptId =
|
|
8587
|
+
async createInternal(request2, prompt, parentSessionId, promptId = randomUUID4()) {
|
|
9062
8588
|
const { sessionId } = parseRequiredSessionId(request2.sessionId);
|
|
9063
8589
|
let entry;
|
|
9064
8590
|
try {
|
|
@@ -9601,8 +9127,8 @@ var StandaloneSessionService = class {
|
|
|
9601
9127
|
|
|
9602
9128
|
// packages/cli/src/serve/workspace-memory.ts
|
|
9603
9129
|
init_esbuild_shims();
|
|
9604
|
-
import { promises as
|
|
9605
|
-
import * as
|
|
9130
|
+
import { promises as fs2 } from "node:fs";
|
|
9131
|
+
import * as path8 from "node:path";
|
|
9606
9132
|
function requireTrustedWorkspace2(deps, res) {
|
|
9607
9133
|
if (deps.isWorkspaceTrusted?.() !== false) return true;
|
|
9608
9134
|
res.status(403).json({
|
|
@@ -9925,9 +9451,9 @@ async function collectWorkspaceMemoryStatus(boundWorkspace) {
|
|
|
9925
9451
|
files.push(...workspaceFiles);
|
|
9926
9452
|
const globalDir = Storage.getGlobalQwenDir();
|
|
9927
9453
|
for (const filename of filenames) {
|
|
9928
|
-
const candidate =
|
|
9454
|
+
const candidate = path8.join(globalDir, filename);
|
|
9929
9455
|
try {
|
|
9930
|
-
const stat3 = await
|
|
9456
|
+
const stat3 = await fs2.stat(candidate);
|
|
9931
9457
|
if (stat3.isFile()) {
|
|
9932
9458
|
files.push({
|
|
9933
9459
|
absolutePath: candidate,
|
|
@@ -9974,9 +9500,9 @@ __name(collectWorkspaceMemoryStatus, "collectWorkspaceMemoryStatus");
|
|
|
9974
9500
|
async function walkWorkspaceForMemory(start, filenames, errors) {
|
|
9975
9501
|
const out = [];
|
|
9976
9502
|
for (const filename of filenames) {
|
|
9977
|
-
const candidate =
|
|
9503
|
+
const candidate = path8.join(start, filename);
|
|
9978
9504
|
try {
|
|
9979
|
-
const stat3 = await
|
|
9505
|
+
const stat3 = await fs2.stat(candidate);
|
|
9980
9506
|
if (stat3.isFile()) {
|
|
9981
9507
|
out.push({
|
|
9982
9508
|
absolutePath: candidate,
|
|
@@ -10006,7 +9532,7 @@ __name(isEnoent, "isEnoent");
|
|
|
10006
9532
|
|
|
10007
9533
|
// packages/cli/src/serve/workspace-agents.ts
|
|
10008
9534
|
init_esbuild_shims();
|
|
10009
|
-
import { promises as
|
|
9535
|
+
import { promises as fs3 } from "node:fs";
|
|
10010
9536
|
import { isDeepStrictEqual } from "node:util";
|
|
10011
9537
|
var AGENT_TYPE_PATTERN = /^[\p{L}\p{N}_-]+$/u;
|
|
10012
9538
|
var AGENT_TYPE_MAX_LENGTH = 64;
|
|
@@ -10459,7 +9985,7 @@ function mountWorkspaceAgentsRoutes(app, deps) {
|
|
|
10459
9985
|
continue;
|
|
10460
9986
|
}
|
|
10461
9987
|
try {
|
|
10462
|
-
await
|
|
9988
|
+
await fs3.access(found.filePath);
|
|
10463
9989
|
remaining.push(found);
|
|
10464
9990
|
} catch {
|
|
10465
9991
|
removed.push(found);
|
|
@@ -10808,7 +10334,7 @@ function mountWorkspaceQualifiedAgentsRoutes(app, deps) {
|
|
|
10808
10334
|
}
|
|
10809
10335
|
if (existing?.filePath) {
|
|
10810
10336
|
try {
|
|
10811
|
-
await
|
|
10337
|
+
await fs3.access(existing.filePath);
|
|
10812
10338
|
writeStderrLine(
|
|
10813
10339
|
`qwen serve: DELETE /workspaces/:workspace/agents/${safeLogValue(agentType)} partial \u2014 remaining=${existing.level}:${existing.filePath}`
|
|
10814
10340
|
);
|
|
@@ -13383,6 +12909,7 @@ var AcpDispatcher = class {
|
|
|
13383
12909
|
...s.sourceId !== void 0 ? { sourceId: s.sourceId } : {},
|
|
13384
12910
|
clientCount: s.clientCount,
|
|
13385
12911
|
hasActivePrompt: s.hasActivePrompt,
|
|
12912
|
+
...s.activeWorkState !== void 0 ? { activeWorkState: s.activeWorkState } : {},
|
|
13386
12913
|
isArchived: s.isArchived === true,
|
|
13387
12914
|
...s.isPinned !== void 0 ? { isPinned: s.isPinned } : {},
|
|
13388
12915
|
...s.pinnedAt !== void 0 ? { pinnedAt: s.pinnedAt } : {},
|
|
@@ -15704,6 +15231,7 @@ var AcpDispatcher = class {
|
|
|
15704
15231
|
bridge: this.bridge,
|
|
15705
15232
|
coordinator: this.archiveCoordinator,
|
|
15706
15233
|
assertCanMutate: assertGenerationOpen,
|
|
15234
|
+
runtimeWorkspaceCwd: this.boundWorkspace,
|
|
15707
15235
|
onError: /* @__PURE__ */ __name(({ phase, sessionId, error: error2 }) => {
|
|
15708
15236
|
const safeSessionId = logSafe(sessionId.slice(0, 8));
|
|
15709
15237
|
const safeMessage = logSafe(error2);
|
|
@@ -16382,7 +15910,7 @@ var AcpDispatcher = class {
|
|
|
16382
15910
|
|
|
16383
15911
|
// packages/cli/src/serve/acp-http/connection-registry.ts
|
|
16384
15912
|
init_esbuild_shims();
|
|
16385
|
-
import { randomUUID as
|
|
15913
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
16386
15914
|
var DEFAULT_MAX_CONNECTIONS = 64;
|
|
16387
15915
|
var AcpConnection = class {
|
|
16388
15916
|
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 +15921,8 @@ var AcpConnection = class {
|
|
|
16393
15921
|
this.maxFramesPerConnection = maxFramesPerConnection;
|
|
16394
15922
|
this.maxPayloadBytesPerConnection = maxPayloadBytesPerConnection;
|
|
16395
15923
|
this.onPreAttachGuardFailure = onPreAttachGuardFailure;
|
|
16396
|
-
this.connectionId = connectionId ??
|
|
16397
|
-
this.clientId =
|
|
15924
|
+
this.connectionId = connectionId ?? randomUUID5();
|
|
15925
|
+
this.clientId = randomUUID5();
|
|
16398
15926
|
this.fromLoopback = fromLoopback;
|
|
16399
15927
|
}
|
|
16400
15928
|
static {
|
|
@@ -18445,6 +17973,23 @@ var CdpBrowserEmulator = class {
|
|
|
18445
17973
|
});
|
|
18446
17974
|
case "Target.getDevToolsTarget":
|
|
18447
17975
|
return this.cb.reply({ id, result: {} });
|
|
17976
|
+
// Target mutations the tunnel cannot perform: behind it is ONE tab the
|
|
17977
|
+
// user already has open, so there is nothing to create, close, or
|
|
17978
|
+
// isolate. These must not fall through to the empty ack below — a CDP
|
|
17979
|
+
// client reads `targetId` out of the createTarget result and then waits
|
|
17980
|
+
// for a target that never appears, so a fake success turns "open a new
|
|
17981
|
+
// page" into a protocol timeout instead of an immediate refusal.
|
|
17982
|
+
case "Target.createTarget":
|
|
17983
|
+
case "Target.closeTarget":
|
|
17984
|
+
case "Target.createBrowserContext":
|
|
17985
|
+
case "Target.disposeBrowserContext":
|
|
17986
|
+
return this.cb.reply({
|
|
17987
|
+
id,
|
|
17988
|
+
error: {
|
|
17989
|
+
code: SERVER_ERROR,
|
|
17990
|
+
message: `${method} is not supported by the CDP tunnel: it drives a single existing tab`
|
|
17991
|
+
}
|
|
17992
|
+
});
|
|
18448
17993
|
case "Target.attachToTarget": {
|
|
18449
17994
|
const targetId = params?.["targetId"];
|
|
18450
17995
|
if (targetId !== PAGE_TARGET_ID) {
|
|
@@ -18804,10 +18349,10 @@ function isAcpChannelUnavailable(err) {
|
|
|
18804
18349
|
return err?.data?.errorKind === "acp_channel_unavailable";
|
|
18805
18350
|
}
|
|
18806
18351
|
__name(isAcpChannelUnavailable, "isAcpChannelUnavailable");
|
|
18807
|
-
function
|
|
18352
|
+
function delay(ms) {
|
|
18808
18353
|
return new Promise((resolve7) => setTimeout(resolve7, ms));
|
|
18809
18354
|
}
|
|
18810
|
-
__name(
|
|
18355
|
+
__name(delay, "delay");
|
|
18811
18356
|
function buildChromeDevToolsMcpRuntimeConfig(localPort, hostname, env) {
|
|
18812
18357
|
if (localPort === void 0 || !Number.isInteger(localPort) || localPort <= 0) {
|
|
18813
18358
|
return void 0;
|
|
@@ -19068,7 +18613,7 @@ function mountAcpHttp(app, bridge, opts) {
|
|
|
19068
18613
|
if (!isAcpChannelUnavailable(err) || attempt >= RUNTIME_MCP_RETRY_ATTEMPTS || !opts.cdpTunnelRegistry?.hasActive()) {
|
|
19069
18614
|
throw err;
|
|
19070
18615
|
}
|
|
19071
|
-
await
|
|
18616
|
+
await delay(RUNTIME_MCP_RETRY_DELAY_MS);
|
|
19072
18617
|
}
|
|
19073
18618
|
}
|
|
19074
18619
|
if (result.skipped) {
|
|
@@ -22061,9 +21606,9 @@ __name(registerWorkspaceAuthRoutes, "registerWorkspaceAuthRoutes");
|
|
|
22061
21606
|
// packages/cli/src/serve/routes/workspace-extensions.ts
|
|
22062
21607
|
init_esbuild_shims();
|
|
22063
21608
|
import * as crypto2 from "node:crypto";
|
|
22064
|
-
import * as
|
|
21609
|
+
import * as fs4 from "node:fs/promises";
|
|
22065
21610
|
import * as os from "node:os";
|
|
22066
|
-
import * as
|
|
21611
|
+
import * as path9 from "node:path";
|
|
22067
21612
|
var import_express2 = __toESM(require_express(), 1);
|
|
22068
21613
|
|
|
22069
21614
|
// packages/cli/src/serve/extension-operation-scheduler.ts
|
|
@@ -22431,14 +21976,18 @@ function createExtensionsController(deps) {
|
|
|
22431
21976
|
async (release) => {
|
|
22432
21977
|
assertGenerationOpen?.();
|
|
22433
21978
|
return await task((generation) => {
|
|
22434
|
-
|
|
21979
|
+
if (!options.skipRefresh) {
|
|
21980
|
+
reconciliationReservation ??= options.reserveRuntimeReconciliation?.();
|
|
21981
|
+
}
|
|
22435
21982
|
committedGeneration = generation;
|
|
22436
21983
|
release();
|
|
22437
21984
|
});
|
|
22438
21985
|
}
|
|
22439
21986
|
);
|
|
22440
21987
|
if (committedGeneration === void 0) {
|
|
22441
|
-
|
|
21988
|
+
if (!options.skipRefresh) {
|
|
21989
|
+
reconciliationReservation ??= options.reserveRuntimeReconciliation?.();
|
|
21990
|
+
}
|
|
22442
21991
|
committedGeneration = result.generation;
|
|
22443
21992
|
}
|
|
22444
21993
|
for (const warning of result.warnings ?? []) {
|
|
@@ -22846,7 +22395,7 @@ var extensionArchiveBodyParser = import_express2.default.raw({
|
|
|
22846
22395
|
});
|
|
22847
22396
|
var assertDaemonExtensionInstallSource = /* @__PURE__ */ __name((installMetadata, source, ref, autoUpdate) => {
|
|
22848
22397
|
if (installMetadata.type === "local") {
|
|
22849
|
-
if (!
|
|
22398
|
+
if (!path9.isAbsolute(source)) {
|
|
22850
22399
|
throw new Error(
|
|
22851
22400
|
"Local extension sources must be absolute daemon-host paths; relative paths are not supported over the daemon endpoint."
|
|
22852
22401
|
);
|
|
@@ -23302,11 +22851,6 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
23302
22851
|
reserveRuntimeReconciliation,
|
|
23303
22852
|
onRuntimeReconciled
|
|
23304
22853
|
} : {}, "globalReconciliationOptions");
|
|
23305
|
-
const workspaceReconciliationOptions = /* @__PURE__ */ __name(() => workspaceRegistry ? {
|
|
23306
|
-
refreshRuntimes: [workspaceRegistry.primary],
|
|
23307
|
-
reserveRuntimeReconciliation,
|
|
23308
|
-
onRuntimeReconciled
|
|
23309
|
-
} : {}, "workspaceReconciliationOptions");
|
|
23310
22854
|
const mutationClientBridges = /* @__PURE__ */ __name((runtimes) => (typeof runtimes === "function" ? runtimes() : runtimes ?? workspaceRegistry?.listAll())?.map((runtime) => runtime.bridge) ?? [bridge], "mutationClientBridges");
|
|
23311
22855
|
if (workspaceRegistry) {
|
|
23312
22856
|
let observedGeneration;
|
|
@@ -23558,14 +23102,14 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
23558
23102
|
let result;
|
|
23559
23103
|
let failure;
|
|
23560
23104
|
try {
|
|
23561
|
-
uploadDir = await
|
|
23562
|
-
|
|
23105
|
+
uploadDir = await fs4.mkdtemp(
|
|
23106
|
+
path9.join(os.tmpdir(), "qwen-extension-upload-")
|
|
23563
23107
|
);
|
|
23564
|
-
const archivePath =
|
|
23108
|
+
const archivePath = path9.join(
|
|
23565
23109
|
uploadDir,
|
|
23566
23110
|
`extension${archiveName.suffix}`
|
|
23567
23111
|
);
|
|
23568
|
-
await
|
|
23112
|
+
await fs4.writeFile(archivePath, archive);
|
|
23569
23113
|
archive = void 0;
|
|
23570
23114
|
const prepared = await context.prepare(async (signal) => {
|
|
23571
23115
|
supersedeActiveInstallOperations(ctrl, operationId);
|
|
@@ -23598,7 +23142,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
23598
23142
|
}
|
|
23599
23143
|
if (uploadDir) {
|
|
23600
23144
|
try {
|
|
23601
|
-
await
|
|
23145
|
+
await fs4.rm(uploadDir, { recursive: true, force: true });
|
|
23602
23146
|
} catch (error2) {
|
|
23603
23147
|
failure ??= sanitizeUploadError(error2);
|
|
23604
23148
|
}
|
|
@@ -23962,7 +23506,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
23962
23506
|
return { status: "enabled", name: extension.name };
|
|
23963
23507
|
},
|
|
23964
23508
|
{
|
|
23965
|
-
|
|
23509
|
+
skipRefresh: true
|
|
23966
23510
|
}
|
|
23967
23511
|
);
|
|
23968
23512
|
} catch (err) {
|
|
@@ -24009,7 +23553,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
24009
23553
|
return { status: "disabled", name: extension.name };
|
|
24010
23554
|
},
|
|
24011
23555
|
{
|
|
24012
|
-
|
|
23556
|
+
skipRefresh: true
|
|
24013
23557
|
}
|
|
24014
23558
|
);
|
|
24015
23559
|
} catch (err) {
|
|
@@ -24298,6 +23842,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
24298
23842
|
};
|
|
24299
23843
|
},
|
|
24300
23844
|
{
|
|
23845
|
+
skipRefresh: true,
|
|
24301
23846
|
...workspaceRegistry ? { refreshRuntimes: /* @__PURE__ */ __name(() => workspaceRegistry.listAll(), "refreshRuntimes") } : {}
|
|
24302
23847
|
}
|
|
24303
23848
|
);
|
|
@@ -24338,6 +23883,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
24338
23883
|
};
|
|
24339
23884
|
},
|
|
24340
23885
|
{
|
|
23886
|
+
skipRefresh: true,
|
|
24341
23887
|
...workspaceRegistry ? { refreshRuntimes: /* @__PURE__ */ __name(() => workspaceRegistry.listAll(), "refreshRuntimes") } : {}
|
|
24342
23888
|
}
|
|
24343
23889
|
);
|
|
@@ -24858,6 +24404,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
24858
24404
|
};
|
|
24859
24405
|
},
|
|
24860
24406
|
{
|
|
24407
|
+
skipRefresh: true,
|
|
24861
24408
|
refreshRuntimes: [runtime],
|
|
24862
24409
|
assertGenerationOpen: /* @__PURE__ */ __name(() => runtime.generationGuard?.assertOpen(), "assertGenerationOpen")
|
|
24863
24410
|
}
|
|
@@ -24904,6 +24451,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
24904
24451
|
};
|
|
24905
24452
|
},
|
|
24906
24453
|
{
|
|
24454
|
+
skipRefresh: true,
|
|
24907
24455
|
refreshRuntimes: [runtime],
|
|
24908
24456
|
assertGenerationOpen: /* @__PURE__ */ __name(() => runtime.generationGuard?.assertOpen(), "assertGenerationOpen")
|
|
24909
24457
|
}
|
|
@@ -24949,6 +24497,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
24949
24497
|
return { status: activation.effective, name: extension.name };
|
|
24950
24498
|
},
|
|
24951
24499
|
{
|
|
24500
|
+
skipRefresh: true,
|
|
24952
24501
|
refreshRuntimes: [runtime],
|
|
24953
24502
|
assertGenerationOpen: /* @__PURE__ */ __name(() => runtime.generationGuard?.assertOpen(), "assertGenerationOpen")
|
|
24954
24503
|
}
|
|
@@ -24987,7 +24536,7 @@ __name(registerWorkspaceExtensionRoutes, "registerWorkspaceExtensionRoutes");
|
|
|
24987
24536
|
// packages/cli/src/serve/routes/workspace-file-write.ts
|
|
24988
24537
|
init_esbuild_shims();
|
|
24989
24538
|
var import_express3 = __toESM(require_express(), 1);
|
|
24990
|
-
import * as
|
|
24539
|
+
import * as path10 from "node:path";
|
|
24991
24540
|
function getFsFactory3(req, res) {
|
|
24992
24541
|
const context = getWorkspaceRouteContext(req);
|
|
24993
24542
|
if (context) return context.runtime.routeFileSystemFactory;
|
|
@@ -25420,8 +24969,8 @@ function fileUploadAdmission(deps, opts) {
|
|
|
25420
24969
|
sendParseError(res, ROUTE2, "`path` query parameter is required");
|
|
25421
24970
|
return;
|
|
25422
24971
|
}
|
|
25423
|
-
const dir =
|
|
25424
|
-
const basename9 =
|
|
24972
|
+
const dir = path10.dirname(queryPath);
|
|
24973
|
+
const basename9 = path10.basename(queryPath);
|
|
25425
24974
|
if (queryPath.endsWith("/") || basename9.length === 0 || basename9 === "." || basename9 === "..") {
|
|
25426
24975
|
sendParseError(res, ROUTE2, "`path` must name a file");
|
|
25427
24976
|
return;
|
|
@@ -25542,11 +25091,11 @@ async function handlePostFileUpload(req, res) {
|
|
|
25542
25091
|
);
|
|
25543
25092
|
return;
|
|
25544
25093
|
}
|
|
25545
|
-
const candidateAbs =
|
|
25094
|
+
const candidateAbs = path10.join(resolvedDir, candidateBasename);
|
|
25546
25095
|
let resolved;
|
|
25547
25096
|
try {
|
|
25548
25097
|
resolved = await fs10.resolve(
|
|
25549
|
-
|
|
25098
|
+
path10.join(queryDir, candidateBasename),
|
|
25550
25099
|
"write"
|
|
25551
25100
|
);
|
|
25552
25101
|
} catch (err) {
|
|
@@ -25901,6 +25450,12 @@ var legacySessionTelemetryRoutes = [
|
|
|
25901
25450
|
attribution: "handler_resolved",
|
|
25902
25451
|
route: "POST /session/:id/resume"
|
|
25903
25452
|
},
|
|
25453
|
+
{
|
|
25454
|
+
method: "POST",
|
|
25455
|
+
path: "/session/:id/worktree-reset",
|
|
25456
|
+
attribution: "handler_resolved",
|
|
25457
|
+
route: "POST /session/:id/worktree-reset"
|
|
25458
|
+
},
|
|
25904
25459
|
{
|
|
25905
25460
|
method: "POST",
|
|
25906
25461
|
path: "/session/:id/branch",
|
|
@@ -26876,11 +26431,92 @@ __name(registerPermissionRoutes, "registerPermissionRoutes");
|
|
|
26876
26431
|
// packages/cli/src/serve/routes/session.ts
|
|
26877
26432
|
init_esbuild_shims();
|
|
26878
26433
|
import * as crypto3 from "node:crypto";
|
|
26879
|
-
import * as
|
|
26880
|
-
import * as
|
|
26434
|
+
import * as fs6 from "node:fs";
|
|
26435
|
+
import * as path11 from "node:path";
|
|
26881
26436
|
import { inspect } from "node:util";
|
|
26882
26437
|
var import_express4 = __toESM(require_express(), 1);
|
|
26883
26438
|
|
|
26439
|
+
// packages/cli/src/serve/server/worktree-reset-errors.ts
|
|
26440
|
+
init_esbuild_shims();
|
|
26441
|
+
var WorktreeSessionSupersededError = class extends Error {
|
|
26442
|
+
static {
|
|
26443
|
+
__name(this, "WorktreeSessionSupersededError");
|
|
26444
|
+
}
|
|
26445
|
+
sessionId;
|
|
26446
|
+
replacementSessionId;
|
|
26447
|
+
constructor(sessionId, replacementSessionId) {
|
|
26448
|
+
super(
|
|
26449
|
+
`Session ${sessionId} was superseded by a worktree reset; restore the replacement session instead`
|
|
26450
|
+
);
|
|
26451
|
+
this.name = "WorktreeSessionSupersededError";
|
|
26452
|
+
this.sessionId = sessionId;
|
|
26453
|
+
this.replacementSessionId = replacementSessionId;
|
|
26454
|
+
}
|
|
26455
|
+
};
|
|
26456
|
+
var WorktreeMarkerMissingError = class extends Error {
|
|
26457
|
+
static {
|
|
26458
|
+
__name(this, "WorktreeMarkerMissingError");
|
|
26459
|
+
}
|
|
26460
|
+
sessionId;
|
|
26461
|
+
constructor(sessionId) {
|
|
26462
|
+
super(
|
|
26463
|
+
`Worktree ownership marker for session ${sessionId} is missing; reset the task to recreate it`
|
|
26464
|
+
);
|
|
26465
|
+
this.name = "WorktreeMarkerMissingError";
|
|
26466
|
+
this.sessionId = sessionId;
|
|
26467
|
+
}
|
|
26468
|
+
};
|
|
26469
|
+
var WorktreeResetInterruptedError = class extends Error {
|
|
26470
|
+
static {
|
|
26471
|
+
__name(this, "WorktreeResetInterruptedError");
|
|
26472
|
+
}
|
|
26473
|
+
sessionId;
|
|
26474
|
+
constructor(sessionId) {
|
|
26475
|
+
super(
|
|
26476
|
+
"A previous worktree reset was interrupted; retry the reset against the superseded session to finish or roll it back"
|
|
26477
|
+
);
|
|
26478
|
+
this.name = "WorktreeResetInterruptedError";
|
|
26479
|
+
this.sessionId = sessionId;
|
|
26480
|
+
}
|
|
26481
|
+
};
|
|
26482
|
+
var WorktreeResetActiveError = class extends Error {
|
|
26483
|
+
static {
|
|
26484
|
+
__name(this, "WorktreeResetActiveError");
|
|
26485
|
+
}
|
|
26486
|
+
sessionId;
|
|
26487
|
+
constructor(sessionId) {
|
|
26488
|
+
super(
|
|
26489
|
+
`Session ${sessionId} has a prompt in progress; wait for it to finish before resetting`
|
|
26490
|
+
);
|
|
26491
|
+
this.name = "WorktreeResetActiveError";
|
|
26492
|
+
this.sessionId = sessionId;
|
|
26493
|
+
}
|
|
26494
|
+
};
|
|
26495
|
+
var WorktreeResetUnsupportedError = class extends Error {
|
|
26496
|
+
static {
|
|
26497
|
+
__name(this, "WorktreeResetUnsupportedError");
|
|
26498
|
+
}
|
|
26499
|
+
sessionId;
|
|
26500
|
+
constructor(sessionId) {
|
|
26501
|
+
super(`Session ${sessionId} is not a worktree session`);
|
|
26502
|
+
this.name = "WorktreeResetUnsupportedError";
|
|
26503
|
+
this.sessionId = sessionId;
|
|
26504
|
+
}
|
|
26505
|
+
};
|
|
26506
|
+
var WorktreeResetInvalidStateError = class extends Error {
|
|
26507
|
+
static {
|
|
26508
|
+
__name(this, "WorktreeResetInvalidStateError");
|
|
26509
|
+
}
|
|
26510
|
+
sessionId;
|
|
26511
|
+
constructor(sessionId) {
|
|
26512
|
+
super(
|
|
26513
|
+
`Session ${sessionId}'s worktree ownership state is invalid; the reset made no destructive change`
|
|
26514
|
+
);
|
|
26515
|
+
this.name = "WorktreeResetInvalidStateError";
|
|
26516
|
+
this.sessionId = sessionId;
|
|
26517
|
+
}
|
|
26518
|
+
};
|
|
26519
|
+
|
|
26884
26520
|
// packages/cli/src/serve/server/prompt-deadline.ts
|
|
26885
26521
|
init_esbuild_shims();
|
|
26886
26522
|
function resolvePromptDeadlineMs(serverMs, requestMs) {
|
|
@@ -27005,7 +26641,7 @@ __name(deleteBranch, "deleteBranch");
|
|
|
27005
26641
|
|
|
27006
26642
|
// packages/cli/src/serve/virtual-subagent-sessions.ts
|
|
27007
26643
|
init_esbuild_shims();
|
|
27008
|
-
import * as
|
|
26644
|
+
import * as fs5 from "node:fs/promises";
|
|
27009
26645
|
import { createReadStream } from "node:fs";
|
|
27010
26646
|
import readline from "node:readline";
|
|
27011
26647
|
var PREFIX = "subagent.";
|
|
@@ -27215,7 +26851,7 @@ var VirtualSubagentTarget = class _VirtualSubagentTarget {
|
|
|
27215
26851
|
async readNewRecords(endOffset) {
|
|
27216
26852
|
let handle;
|
|
27217
26853
|
try {
|
|
27218
|
-
handle = await
|
|
26854
|
+
handle = await fs5.open(this.task.outputFile, "r");
|
|
27219
26855
|
const stat3 = await handle.stat();
|
|
27220
26856
|
const identity = `${stat3.dev}:${stat3.ino}`;
|
|
27221
26857
|
if (this.transcriptIdentity !== void 0 && this.transcriptIdentity !== identity || stat3.size < this.offset) {
|
|
@@ -27259,7 +26895,7 @@ var VirtualSubagentTarget = class _VirtualSubagentTarget {
|
|
|
27259
26895
|
const filePath = `${this.task.outputFile}.stream`;
|
|
27260
26896
|
let handle;
|
|
27261
26897
|
try {
|
|
27262
|
-
handle = await
|
|
26898
|
+
handle = await fs5.open(filePath, "r");
|
|
27263
26899
|
const stat3 = await handle.stat();
|
|
27264
26900
|
const identity = `${stat3.dev}:${stat3.ino}`;
|
|
27265
26901
|
if (this.streamIdentity !== void 0 && this.streamIdentity !== identity) {
|
|
@@ -27424,7 +27060,7 @@ var VirtualSubagentTarget = class _VirtualSubagentTarget {
|
|
|
27424
27060
|
async captureReadBounds() {
|
|
27425
27061
|
const size = /* @__PURE__ */ __name(async (filePath) => {
|
|
27426
27062
|
try {
|
|
27427
|
-
return (await
|
|
27063
|
+
return (await fs5.stat(filePath)).size;
|
|
27428
27064
|
} catch (error2) {
|
|
27429
27065
|
if (error2.code === "ENOENT") return 0;
|
|
27430
27066
|
throw error2;
|
|
@@ -27553,7 +27189,7 @@ var VirtualSubagentSessions = class {
|
|
|
27553
27189
|
const sessionDir = getSubagentSessionDir(projectDir, parentSessionId);
|
|
27554
27190
|
let names;
|
|
27555
27191
|
try {
|
|
27556
|
-
names = await
|
|
27192
|
+
names = await fs5.readdir(sessionDir);
|
|
27557
27193
|
} catch (error2) {
|
|
27558
27194
|
if (error2.code === "ENOENT") return void 0;
|
|
27559
27195
|
throw error2;
|
|
@@ -27609,7 +27245,7 @@ var VirtualSubagentSessions = class {
|
|
|
27609
27245
|
const sessionDir = getSubagentSessionDir(projectDir, parentSessionId);
|
|
27610
27246
|
let names;
|
|
27611
27247
|
try {
|
|
27612
|
-
names = await
|
|
27248
|
+
names = await fs5.readdir(sessionDir);
|
|
27613
27249
|
} catch (error2) {
|
|
27614
27250
|
if (error2.code === "ENOENT") return void 0;
|
|
27615
27251
|
throw error2;
|
|
@@ -28134,34 +27770,6 @@ function registerSessionRoutes(app, deps) {
|
|
|
28134
27770
|
const LANGUAGE_CODES = deps.languageCodes;
|
|
28135
27771
|
const transcriptCursorMasterKey = crypto3.randomBytes(32);
|
|
28136
27772
|
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
27773
|
const activeBranchSessions = /* @__PURE__ */ new Map();
|
|
28166
27774
|
const inFlightBranchWorkspaces = /* @__PURE__ */ new Set();
|
|
28167
27775
|
const clearBranchSessionEntry = /* @__PURE__ */ __name((sessionId) => {
|
|
@@ -28270,28 +27878,28 @@ function registerSessionRoutes(app, deps) {
|
|
|
28270
27878
|
const cwd = parseOptionalWorkspaceCwd(body, boundWorkspace, res);
|
|
28271
27879
|
if (cwd === void 0) return void 0;
|
|
28272
27880
|
const isWithinConversationRoot = /* @__PURE__ */ __name((root, candidate) => {
|
|
28273
|
-
const relative5 =
|
|
28274
|
-
return relative5 === "" || relative5 !== ".." && !relative5.startsWith(`..${
|
|
27881
|
+
const relative5 = path11.relative(root, candidate);
|
|
27882
|
+
return relative5 === "" || relative5 !== ".." && !relative5.startsWith(`..${path11.sep}`) && !path11.isAbsolute(relative5);
|
|
28275
27883
|
}, "isWithinConversationRoot");
|
|
28276
27884
|
const canonicalizeIfPresent = /* @__PURE__ */ __name((candidate) => {
|
|
28277
|
-
const resolved =
|
|
27885
|
+
const resolved = path11.resolve(candidate);
|
|
28278
27886
|
try {
|
|
28279
|
-
return
|
|
27887
|
+
return fs6.realpathSync.native(resolved);
|
|
28280
27888
|
} catch {
|
|
28281
27889
|
return resolved;
|
|
28282
27890
|
}
|
|
28283
27891
|
}, "canonicalizeIfPresent");
|
|
28284
27892
|
const canonicalizeExistingAncestor = /* @__PURE__ */ __name((candidate) => {
|
|
28285
|
-
let ancestor =
|
|
27893
|
+
let ancestor = path11.resolve(candidate);
|
|
28286
27894
|
const missingTail = [];
|
|
28287
27895
|
while (true) {
|
|
28288
27896
|
try {
|
|
28289
|
-
return
|
|
27897
|
+
return path11.join(fs6.realpathSync.native(ancestor), ...missingTail);
|
|
28290
27898
|
} catch (error2) {
|
|
28291
27899
|
if (error2.code !== "ENOENT") throw error2;
|
|
28292
|
-
const parent =
|
|
27900
|
+
const parent = path11.dirname(ancestor);
|
|
28293
27901
|
if (parent === ancestor) throw error2;
|
|
28294
|
-
missingTail.unshift(
|
|
27902
|
+
missingTail.unshift(path11.basename(ancestor));
|
|
28295
27903
|
ancestor = parent;
|
|
28296
27904
|
}
|
|
28297
27905
|
}
|
|
@@ -28304,8 +27912,8 @@ function registerSessionRoutes(app, deps) {
|
|
|
28304
27912
|
return void 0;
|
|
28305
27913
|
}, "rejectReservedConversationRoot");
|
|
28306
27914
|
if ("cwd" in body && deps.liveConversationRootPath && isWithinConversationRoot(
|
|
28307
|
-
|
|
28308
|
-
|
|
27915
|
+
path11.resolve(deps.liveConversationRootPath),
|
|
27916
|
+
path11.resolve(cwd)
|
|
28309
27917
|
)) {
|
|
28310
27918
|
return rejectReservedConversationRoot();
|
|
28311
27919
|
}
|
|
@@ -28328,7 +27936,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
28328
27936
|
const liveRoots = [
|
|
28329
27937
|
...workspaceRegistry.listAllEntries().filter((entry2) => entry2.internal).map((entry2) => entry2.workspaceCwd),
|
|
28330
27938
|
...deps.liveConversationRootPath ? [
|
|
28331
|
-
|
|
27939
|
+
path11.resolve(deps.liveConversationRootPath),
|
|
28332
27940
|
canonicalizeIfPresent(deps.liveConversationRootPath)
|
|
28333
27941
|
] : []
|
|
28334
27942
|
];
|
|
@@ -28378,7 +27986,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
28378
27986
|
const workspaceParam = req.params[paramName] ?? "";
|
|
28379
27987
|
const byId = workspaceRegistry.getByWorkspaceId(workspaceParam);
|
|
28380
27988
|
if (byId) return byId;
|
|
28381
|
-
if (!
|
|
27989
|
+
if (!path11.isAbsolute(workspaceParam)) {
|
|
28382
27990
|
res.status(400).json({
|
|
28383
27991
|
error: `\`:${paramName}\` must decode to a workspace id or absolute path`
|
|
28384
27992
|
});
|
|
@@ -28431,11 +28039,11 @@ function registerSessionRoutes(app, deps) {
|
|
|
28431
28039
|
}
|
|
28432
28040
|
const selector = req.params[paramName] ?? "";
|
|
28433
28041
|
let entry = workspaceRegistry.getManagedEntryByWorkspaceId(selector);
|
|
28434
|
-
if (!entry &&
|
|
28042
|
+
if (!entry && path11.isAbsolute(selector)) {
|
|
28435
28043
|
entry = workspaceRegistry.getManagedEntryByWorkspaceCwd(selector);
|
|
28436
28044
|
}
|
|
28437
|
-
const configuredRoot = deps.liveConversationRootPath ?
|
|
28438
|
-
const matchesConfiguredRoot = configuredRoot !== void 0 && selector === configuredRoot &&
|
|
28045
|
+
const configuredRoot = deps.liveConversationRootPath ? path11.resolve(deps.liveConversationRootPath) : void 0;
|
|
28046
|
+
const matchesConfiguredRoot = configuredRoot !== void 0 && selector === configuredRoot && path11.resolve(selector) === selector;
|
|
28439
28047
|
if ((!entry || !entry.internal) && !matchesConfiguredRoot) {
|
|
28440
28048
|
return void 0;
|
|
28441
28049
|
}
|
|
@@ -28464,7 +28072,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
28464
28072
|
}, "resolveLiveCatalogRuntime");
|
|
28465
28073
|
const resolveQualifiedSessionTarget = /* @__PURE__ */ __name((req, res, options = {}) => {
|
|
28466
28074
|
const selector = req.params["workspace"] ?? "";
|
|
28467
|
-
const entry = workspaceRegistry.getManagedEntryByWorkspaceId(selector) ?? (
|
|
28075
|
+
const entry = workspaceRegistry.getManagedEntryByWorkspaceId(selector) ?? (path11.isAbsolute(selector) ? workspaceRegistry.getManagedEntryByWorkspaceCwd(selector) : void 0);
|
|
28468
28076
|
if (entry?.internal) return { kind: "internal", entry };
|
|
28469
28077
|
const runtime = resolveWorkspaceRuntimeFromParam(
|
|
28470
28078
|
workspaceRegistry,
|
|
@@ -28741,8 +28349,8 @@ function registerSessionRoutes(app, deps) {
|
|
|
28741
28349
|
const resolveRuntimeForSessionRestore = /* @__PURE__ */ __name(async (body, res, route, sessionId) => {
|
|
28742
28350
|
const cwd = parseOptionalWorkspaceCwd(body, boundWorkspace, res);
|
|
28743
28351
|
if (cwd === void 0) return void 0;
|
|
28744
|
-
const configuredRoot = deps.liveConversationRootPath ?
|
|
28745
|
-
const bootstrappedRuntime = "cwd" in body && configuredRoot !== void 0 &&
|
|
28352
|
+
const configuredRoot = deps.liveConversationRootPath ? path11.resolve(deps.liveConversationRootPath) : void 0;
|
|
28353
|
+
const bootstrappedRuntime = "cwd" in body && configuredRoot !== void 0 && path11.isAbsolute(cwd) && path11.resolve(cwd) === configuredRoot && deps.ensureConversationRuntime ? await deps.ensureConversationRuntime() : void 0;
|
|
28746
28354
|
let key;
|
|
28747
28355
|
try {
|
|
28748
28356
|
key = canonicalizeWorkspace(cwd);
|
|
@@ -29451,6 +29059,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
29451
29059
|
coordinator: archiveCoordinator,
|
|
29452
29060
|
coordinatorLockHeld,
|
|
29453
29061
|
assertCanMutate,
|
|
29062
|
+
runtimeWorkspaceCwd: runtime.workspaceCwd,
|
|
29454
29063
|
onError: /* @__PURE__ */ __name(({ phase, sessionId, error: error2 }) => {
|
|
29455
29064
|
writeStderrLine(
|
|
29456
29065
|
`qwen serve: ${phase}Session failed for ${safeLogValue(sessionId)}: ${safeLogValue(error2)}`
|
|
@@ -29901,7 +29510,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
29901
29510
|
} catch (error2) {
|
|
29902
29511
|
if (!session.attached) {
|
|
29903
29512
|
try {
|
|
29904
|
-
|
|
29513
|
+
await runWithWorkspaceRuntimeStorage(
|
|
29905
29514
|
runtime,
|
|
29906
29515
|
() => deleteDaemonSessionIfOrphan({
|
|
29907
29516
|
sessionId: session.sessionId,
|
|
@@ -29910,18 +29519,25 @@ function registerSessionRoutes(app, deps) {
|
|
|
29910
29519
|
coordinator: archiveCoordinator
|
|
29911
29520
|
})
|
|
29912
29521
|
);
|
|
29913
|
-
if (removed) {
|
|
29914
|
-
if (worktreeMeta) {
|
|
29915
|
-
await new GitWorktreeService(workspaceCwd).removeUserWorktree(worktreeMeta.slug, { deleteBranch: true }).catch(() => {
|
|
29916
|
-
});
|
|
29917
|
-
}
|
|
29918
|
-
}
|
|
29919
29522
|
} catch {
|
|
29920
29523
|
}
|
|
29921
29524
|
} else {
|
|
29922
29525
|
await runtime.bridge.detachClient(session.sessionId, session.clientId).catch(() => {
|
|
29923
29526
|
});
|
|
29924
29527
|
}
|
|
29528
|
+
if (worktreeMeta) {
|
|
29529
|
+
const rollbackSlug = worktreeMeta.slug;
|
|
29530
|
+
await new GitWorktreeService(workspaceCwd).removeUserWorktree(rollbackSlug, { deleteBranch: true }).catch((removalError) => {
|
|
29531
|
+
daemonLog?.warn(
|
|
29532
|
+
"worktree removal failed during generation-closed rollback",
|
|
29533
|
+
{
|
|
29534
|
+
sessionId: session.sessionId,
|
|
29535
|
+
slug: rollbackSlug,
|
|
29536
|
+
error: removalError instanceof Error ? removalError.message : String(removalError)
|
|
29537
|
+
}
|
|
29538
|
+
);
|
|
29539
|
+
});
|
|
29540
|
+
}
|
|
29925
29541
|
throw error2;
|
|
29926
29542
|
}
|
|
29927
29543
|
if (daemonLog) {
|
|
@@ -29986,7 +29602,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
29986
29602
|
if (worktreeMeta) {
|
|
29987
29603
|
try {
|
|
29988
29604
|
const createAllowedRoots = [
|
|
29989
|
-
|
|
29605
|
+
path11.join(workspaceCwd, ".qwen", "worktrees")
|
|
29990
29606
|
];
|
|
29991
29607
|
let createRepoTop = null;
|
|
29992
29608
|
try {
|
|
@@ -29997,10 +29613,10 @@ function registerSessionRoutes(app, deps) {
|
|
|
29997
29613
|
}
|
|
29998
29614
|
if (createRepoTop && createRepoTop !== workspaceCwd) {
|
|
29999
29615
|
createAllowedRoots.push(
|
|
30000
|
-
|
|
29616
|
+
path11.join(createRepoTop, ".qwen", "worktrees")
|
|
30001
29617
|
);
|
|
30002
29618
|
}
|
|
30003
|
-
const expectedWorktreePath =
|
|
29619
|
+
const expectedWorktreePath = fs6.realpathSync(worktreeMeta.path);
|
|
30004
29620
|
const changed = await runtime.bridge.changeSessionCwd(
|
|
30005
29621
|
session.sessionId,
|
|
30006
29622
|
{
|
|
@@ -30350,21 +29966,42 @@ function registerSessionRoutes(app, deps) {
|
|
|
30350
29966
|
};
|
|
30351
29967
|
const isChannelRestore = restoreRequestMetadata.sourceType === "channel";
|
|
30352
29968
|
let isPart4AWorktreeRestore = false;
|
|
30353
|
-
|
|
29969
|
+
let part4AWorktreeKey;
|
|
29970
|
+
if (runtime.provenance !== "live-conversation") {
|
|
30354
29971
|
const sidecarBeforeRestore = await readWorktreeSessionStrict(
|
|
30355
29972
|
sessionService.getWorktreeSessionPath(restoredStorageSessionId)
|
|
30356
29973
|
);
|
|
29974
|
+
if (isChannelRestore) {
|
|
29975
|
+
suppressWorktreeContextRestore = !(sidecarBeforeRestore.state === "valid" && sidecarBeforeRestore.session.workspaceCwd === void 0);
|
|
29976
|
+
}
|
|
30357
29977
|
isPart4AWorktreeRestore = sidecarBeforeRestore.state === "valid" && sidecarBeforeRestore.session.workspaceCwd !== void 0;
|
|
30358
|
-
|
|
29978
|
+
if (isPart4AWorktreeRestore && sidecarBeforeRestore.state === "valid") {
|
|
29979
|
+
const recordedPath = sidecarBeforeRestore.session.worktreePath;
|
|
29980
|
+
try {
|
|
29981
|
+
part4AWorktreeKey = fs6.realpathSync(recordedPath);
|
|
29982
|
+
} catch {
|
|
29983
|
+
part4AWorktreeKey = recordedPath;
|
|
29984
|
+
}
|
|
29985
|
+
}
|
|
30359
29986
|
} else {
|
|
30360
29987
|
suppressWorktreeContextRestore = isChannelRestore;
|
|
30361
29988
|
}
|
|
30362
29989
|
deferRestoreAskUserQuestionPrompt = suppressWorktreeContextRestore && runtime.bridge.fireDeferredRestoreAskUserQuestionPrompt !== void 0 && runtime.bridge.discardDeferredRestoreAskUserQuestionPrompt !== void 0;
|
|
30363
|
-
if (
|
|
30364
|
-
releaseWorktreeRestore = await
|
|
30365
|
-
|
|
30366
|
-
|
|
30367
|
-
|
|
29990
|
+
if (isPart4AWorktreeRestore && part4AWorktreeKey !== void 0) {
|
|
29991
|
+
releaseWorktreeRestore = await acquireWorktreeOwnershipOp(part4AWorktreeKey);
|
|
29992
|
+
if (isChannelRestore) {
|
|
29993
|
+
const sidecarUnderLock = await readWorktreeSessionStrict(
|
|
29994
|
+
sessionService.getWorktreeSessionPath(
|
|
29995
|
+
restoredStorageSessionId
|
|
29996
|
+
)
|
|
29997
|
+
);
|
|
29998
|
+
if (sidecarUnderLock.state === "valid" && sidecarUnderLock.session.supersededBy !== void 0) {
|
|
29999
|
+
throw new WorktreeSessionSupersededError(
|
|
30000
|
+
restoredStorageSessionId,
|
|
30001
|
+
sidecarUnderLock.session.supersededBy
|
|
30002
|
+
);
|
|
30003
|
+
}
|
|
30004
|
+
}
|
|
30368
30005
|
}
|
|
30369
30006
|
assertRuntimeGenerationOpen?.();
|
|
30370
30007
|
if (isInternalWorkspaceRuntime(runtime)) {
|
|
@@ -30511,7 +30148,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
30511
30148
|
let candidateRoots = [];
|
|
30512
30149
|
let validationError;
|
|
30513
30150
|
try {
|
|
30514
|
-
const workspaceRoots = [
|
|
30151
|
+
const workspaceRoots = [fs6.realpathSync(workspaceCwd)];
|
|
30515
30152
|
let repoTop = null;
|
|
30516
30153
|
try {
|
|
30517
30154
|
repoTop = await new GitWorktreeService(
|
|
@@ -30520,24 +30157,24 @@ function registerSessionRoutes(app, deps) {
|
|
|
30520
30157
|
} catch {
|
|
30521
30158
|
}
|
|
30522
30159
|
if (repoTop) {
|
|
30523
|
-
const realRepoTop =
|
|
30160
|
+
const realRepoTop = fs6.realpathSync(repoTop);
|
|
30524
30161
|
if (!workspaceRoots.includes(realRepoTop)) {
|
|
30525
30162
|
workspaceRoots.push(realRepoTop);
|
|
30526
30163
|
}
|
|
30527
30164
|
}
|
|
30528
|
-
const realOriginalCwd =
|
|
30165
|
+
const realOriginalCwd = fs6.realpathSync(sidecar.originalCwd);
|
|
30529
30166
|
if (!workspaceRoots.includes(realOriginalCwd)) {
|
|
30530
30167
|
throw new Error("legacy sidecar belongs to another workspace");
|
|
30531
30168
|
}
|
|
30532
30169
|
candidateRoots = workspaceRoots.map(
|
|
30533
|
-
(root) =>
|
|
30170
|
+
(root) => path11.join(root, ".qwen", "worktrees")
|
|
30534
30171
|
);
|
|
30535
|
-
realTarget =
|
|
30172
|
+
realTarget = fs6.realpathSync(sidecar.worktreePath);
|
|
30536
30173
|
const contained = candidateRoots.some((root) => {
|
|
30537
30174
|
try {
|
|
30538
|
-
const realRoot =
|
|
30539
|
-
const relative5 =
|
|
30540
|
-
return relative5.length > 0 && !relative5.startsWith("..") && !
|
|
30175
|
+
const realRoot = fs6.realpathSync(root);
|
|
30176
|
+
const relative5 = path11.relative(realRoot, realTarget);
|
|
30177
|
+
return relative5.length > 0 && !relative5.startsWith("..") && !path11.isAbsolute(relative5);
|
|
30541
30178
|
} catch {
|
|
30542
30179
|
return false;
|
|
30543
30180
|
}
|
|
@@ -30584,11 +30221,17 @@ function registerSessionRoutes(app, deps) {
|
|
|
30584
30221
|
throw new Error("Worktree sidecar is missing or invalid");
|
|
30585
30222
|
}
|
|
30586
30223
|
const sidecar = sidecarResult.session;
|
|
30587
|
-
|
|
30224
|
+
if (sidecar.supersededBy !== void 0) {
|
|
30225
|
+
throw new WorktreeSessionSupersededError(
|
|
30226
|
+
restoredStorageSessionId,
|
|
30227
|
+
sidecar.supersededBy
|
|
30228
|
+
);
|
|
30229
|
+
}
|
|
30230
|
+
const realWorkspace = fs6.realpathSync(workspaceCwd);
|
|
30588
30231
|
if (sidecar.workspaceCwd !== void 0) {
|
|
30589
30232
|
let realSidecarWorkspace;
|
|
30590
30233
|
try {
|
|
30591
|
-
realSidecarWorkspace =
|
|
30234
|
+
realSidecarWorkspace = fs6.realpathSync(sidecar.workspaceCwd);
|
|
30592
30235
|
} catch {
|
|
30593
30236
|
throw new Error(
|
|
30594
30237
|
"Worktree sidecar workspace is missing or inaccessible"
|
|
@@ -30609,11 +30252,11 @@ function registerSessionRoutes(app, deps) {
|
|
|
30609
30252
|
} catch {
|
|
30610
30253
|
}
|
|
30611
30254
|
if (repoTop && repoTop !== realWorkspace) {
|
|
30612
|
-
workspaceRoots.push(
|
|
30255
|
+
workspaceRoots.push(fs6.realpathSync(repoTop));
|
|
30613
30256
|
}
|
|
30614
30257
|
let realOriginalCwd;
|
|
30615
30258
|
try {
|
|
30616
|
-
realOriginalCwd =
|
|
30259
|
+
realOriginalCwd = fs6.realpathSync(sidecar.originalCwd);
|
|
30617
30260
|
} catch {
|
|
30618
30261
|
throw new Error(
|
|
30619
30262
|
"Worktree sidecar workspace is missing or inaccessible"
|
|
@@ -30625,19 +30268,19 @@ function registerSessionRoutes(app, deps) {
|
|
|
30625
30268
|
);
|
|
30626
30269
|
}
|
|
30627
30270
|
const candidateRoots = workspaceRoots.map(
|
|
30628
|
-
(root) =>
|
|
30271
|
+
(root) => path11.join(root, ".qwen", "worktrees")
|
|
30629
30272
|
);
|
|
30630
30273
|
let realTarget;
|
|
30631
30274
|
try {
|
|
30632
|
-
realTarget =
|
|
30275
|
+
realTarget = fs6.realpathSync(sidecar.worktreePath);
|
|
30633
30276
|
} catch {
|
|
30634
30277
|
throw new Error("Worktree checkout is missing or inaccessible");
|
|
30635
30278
|
}
|
|
30636
30279
|
const contained = candidateRoots.some((root) => {
|
|
30637
30280
|
try {
|
|
30638
|
-
const realRoot =
|
|
30639
|
-
const relative5 =
|
|
30640
|
-
return relative5.length > 0 && !relative5.startsWith("..") && !
|
|
30281
|
+
const realRoot = fs6.realpathSync(root);
|
|
30282
|
+
const relative5 = path11.relative(realRoot, realTarget);
|
|
30283
|
+
return relative5.length > 0 && !relative5.startsWith("..") && !path11.isAbsolute(relative5);
|
|
30641
30284
|
} catch {
|
|
30642
30285
|
return false;
|
|
30643
30286
|
}
|
|
@@ -30647,6 +30290,30 @@ function registerSessionRoutes(app, deps) {
|
|
|
30647
30290
|
}
|
|
30648
30291
|
const marker = await readWorktreeSessionMarkerStrict(realTarget);
|
|
30649
30292
|
if (marker.state !== "valid" || marker.sessionId !== restoredStorageSessionId) {
|
|
30293
|
+
if (sidecar.supersedes !== void 0 && (marker.state === "missing" || marker.state === "valid" && marker.sessionId === sidecar.supersedes)) {
|
|
30294
|
+
const oldSidecar = await readWorktreeSessionStrict(
|
|
30295
|
+
createWorkspaceRuntimeSessionService(
|
|
30296
|
+
runtime
|
|
30297
|
+
).getWorktreeSessionPath(sidecar.supersedes)
|
|
30298
|
+
);
|
|
30299
|
+
if (oldSidecar.state === "valid" && oldSidecar.session.supersededBy === restoredStorageSessionId) {
|
|
30300
|
+
daemonLog?.warn(
|
|
30301
|
+
"worktree restore found an interrupted reset",
|
|
30302
|
+
{
|
|
30303
|
+
sessionId: restoredStorageSessionId,
|
|
30304
|
+
supersedesSessionId: sidecar.supersedes
|
|
30305
|
+
}
|
|
30306
|
+
);
|
|
30307
|
+
throw new WorktreeResetInterruptedError(
|
|
30308
|
+
restoredStorageSessionId
|
|
30309
|
+
);
|
|
30310
|
+
}
|
|
30311
|
+
}
|
|
30312
|
+
if (marker.state === "missing") {
|
|
30313
|
+
throw new WorktreeMarkerMissingError(
|
|
30314
|
+
restoredStorageSessionId
|
|
30315
|
+
);
|
|
30316
|
+
}
|
|
30650
30317
|
throw new Error("Worktree marker ownership is invalid");
|
|
30651
30318
|
}
|
|
30652
30319
|
const worktree = {
|
|
@@ -30654,28 +30321,28 @@ function registerSessionRoutes(app, deps) {
|
|
|
30654
30321
|
path: realTarget,
|
|
30655
30322
|
branch: sidecar.worktreeBranch
|
|
30656
30323
|
};
|
|
30657
|
-
const hasUnlocatedRestoredPrompt = session.hasActivePrompt && !session.attached && session.currentCwd === void 0;
|
|
30324
|
+
const hasUnlocatedRestoredPrompt = session.hasActivePrompt && !session.attached && session.currentCwd === void 0 && !deferRestoreAskUserQuestionPrompt;
|
|
30658
30325
|
if (hasUnlocatedRestoredPrompt) {
|
|
30659
30326
|
runtime.bridge.setSessionWorktree(sessionId, worktree);
|
|
30660
30327
|
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
30328
|
} else {
|
|
30666
|
-
|
|
30667
|
-
|
|
30668
|
-
|
|
30669
|
-
path: realTarget,
|
|
30670
|
-
allowedRoots: candidateRoots
|
|
30329
|
+
if (session.hasActivePrompt) {
|
|
30330
|
+
if (session.currentCwd !== realTarget) {
|
|
30331
|
+
throw new Error("Active session is outside its worktree");
|
|
30671
30332
|
}
|
|
30672
|
-
|
|
30673
|
-
|
|
30674
|
-
|
|
30333
|
+
} else {
|
|
30334
|
+
const changed = await runtime.bridge.changeSessionCwd(
|
|
30335
|
+
sessionId,
|
|
30336
|
+
{
|
|
30337
|
+
path: realTarget,
|
|
30338
|
+
allowedRoots: candidateRoots
|
|
30339
|
+
}
|
|
30340
|
+
);
|
|
30341
|
+
if (changed.newCwd !== realTarget) {
|
|
30342
|
+
throw new Error("Worktree relocation was rejected");
|
|
30343
|
+
}
|
|
30344
|
+
session.currentCwd = changed.newCwd;
|
|
30675
30345
|
}
|
|
30676
|
-
session.currentCwd = changed.newCwd;
|
|
30677
|
-
}
|
|
30678
|
-
if (!hasUnlocatedRestoredPrompt) {
|
|
30679
30346
|
runtime.bridge.setSessionWorktree(sessionId, worktree);
|
|
30680
30347
|
assertRuntimeGenerationOpen?.();
|
|
30681
30348
|
session.worktree = worktree;
|
|
@@ -30750,6 +30417,448 @@ function registerSessionRoutes(app, deps) {
|
|
|
30750
30417
|
}, "restoreSessionHandler");
|
|
30751
30418
|
app.post("/session/:id/load", mutate(), restoreSessionHandler("load"));
|
|
30752
30419
|
app.post("/session/:id/resume", mutate(), restoreSessionHandler("resume"));
|
|
30420
|
+
const resolveWorktreeOwnershipTarget = /* @__PURE__ */ __name(async (runtime, workspaceCwd, sidecar, sessionId) => {
|
|
30421
|
+
const invalidState = /* @__PURE__ */ __name((reason) => {
|
|
30422
|
+
daemonLog?.warn("worktree reset rejected sidecar state", {
|
|
30423
|
+
sessionId,
|
|
30424
|
+
reason
|
|
30425
|
+
});
|
|
30426
|
+
return new WorktreeResetInvalidStateError(sessionId);
|
|
30427
|
+
}, "invalidState");
|
|
30428
|
+
const realWorkspace = fs6.realpathSync(workspaceCwd);
|
|
30429
|
+
if (sidecar.workspaceCwd !== void 0) {
|
|
30430
|
+
let realSidecarWorkspace;
|
|
30431
|
+
try {
|
|
30432
|
+
realSidecarWorkspace = fs6.realpathSync(sidecar.workspaceCwd);
|
|
30433
|
+
} catch {
|
|
30434
|
+
throw invalidState("sidecar workspace is missing or inaccessible");
|
|
30435
|
+
}
|
|
30436
|
+
if (realSidecarWorkspace !== realWorkspace) {
|
|
30437
|
+
throw invalidState("sidecar belongs to another workspace");
|
|
30438
|
+
}
|
|
30439
|
+
}
|
|
30440
|
+
const workspaceRoots = [realWorkspace];
|
|
30441
|
+
let repoTop = null;
|
|
30442
|
+
try {
|
|
30443
|
+
repoTop = await new GitWorktreeService(realWorkspace).getRepoTopLevel();
|
|
30444
|
+
} catch {
|
|
30445
|
+
}
|
|
30446
|
+
if (repoTop && repoTop !== realWorkspace) {
|
|
30447
|
+
workspaceRoots.push(fs6.realpathSync(repoTop));
|
|
30448
|
+
}
|
|
30449
|
+
let realOriginalCwd;
|
|
30450
|
+
try {
|
|
30451
|
+
realOriginalCwd = fs6.realpathSync(sidecar.originalCwd);
|
|
30452
|
+
} catch {
|
|
30453
|
+
throw invalidState("sidecar original cwd is missing or inaccessible");
|
|
30454
|
+
}
|
|
30455
|
+
if (!workspaceRoots.includes(realOriginalCwd)) {
|
|
30456
|
+
throw invalidState("sidecar original cwd is outside the accepted roots");
|
|
30457
|
+
}
|
|
30458
|
+
const candidateRoots = workspaceRoots.map(
|
|
30459
|
+
(root) => path11.join(root, ".qwen", "worktrees")
|
|
30460
|
+
);
|
|
30461
|
+
let realTarget;
|
|
30462
|
+
try {
|
|
30463
|
+
realTarget = fs6.realpathSync(sidecar.worktreePath);
|
|
30464
|
+
} catch {
|
|
30465
|
+
throw invalidState("worktree checkout is missing or inaccessible");
|
|
30466
|
+
}
|
|
30467
|
+
const contained = candidateRoots.some((root) => {
|
|
30468
|
+
try {
|
|
30469
|
+
const realRoot = fs6.realpathSync(root);
|
|
30470
|
+
const relative5 = path11.relative(realRoot, realTarget);
|
|
30471
|
+
return relative5.length > 0 && !relative5.startsWith("..") && !path11.isAbsolute(relative5);
|
|
30472
|
+
} catch {
|
|
30473
|
+
return false;
|
|
30474
|
+
}
|
|
30475
|
+
});
|
|
30476
|
+
if (!contained) {
|
|
30477
|
+
throw invalidState("worktree path failed containment");
|
|
30478
|
+
}
|
|
30479
|
+
return { realTarget, candidateRoots };
|
|
30480
|
+
}, "resolveWorktreeOwnershipTarget");
|
|
30481
|
+
const worktreeResetHandler = /* @__PURE__ */ __name(async (req, res) => {
|
|
30482
|
+
const route = "POST /session/:id/worktree-reset";
|
|
30483
|
+
const sessionId = requireSessionId(req, res);
|
|
30484
|
+
if (!sessionId) return;
|
|
30485
|
+
if (parseVirtualSubagentSessionId(sessionId)) {
|
|
30486
|
+
res.status(400).json({
|
|
30487
|
+
error: "Virtual subagent sessions do not support worktree reset",
|
|
30488
|
+
code: "unsupported_action",
|
|
30489
|
+
sessionId
|
|
30490
|
+
});
|
|
30491
|
+
return;
|
|
30492
|
+
}
|
|
30493
|
+
const body = safeBody(req);
|
|
30494
|
+
let resolvedRuntime;
|
|
30495
|
+
try {
|
|
30496
|
+
resolvedRuntime = await resolveRuntimeForSessionRestore(
|
|
30497
|
+
body,
|
|
30498
|
+
res,
|
|
30499
|
+
route,
|
|
30500
|
+
sessionId
|
|
30501
|
+
);
|
|
30502
|
+
} catch (err) {
|
|
30503
|
+
if (sendConversationRuntimeError(res, err)) return;
|
|
30504
|
+
sendBridgeError2(res, err, { route, sessionId });
|
|
30505
|
+
return;
|
|
30506
|
+
}
|
|
30507
|
+
if (resolvedRuntime === void 0) return;
|
|
30508
|
+
const { runtime, workspaceCwd } = resolvedRuntime;
|
|
30509
|
+
const approvalMode = parseOptionalApprovalMode(body, res);
|
|
30510
|
+
if (approvalMode === null) return;
|
|
30511
|
+
const source = parseRequestedSessionSource(body, res);
|
|
30512
|
+
if (source === null) return;
|
|
30513
|
+
const modelServiceId = typeof body["modelServiceId"] === "string" ? body["modelServiceId"] : void 0;
|
|
30514
|
+
const assertRuntimeGenerationOpen = captureRuntimeGenerationAssertion(runtime);
|
|
30515
|
+
try {
|
|
30516
|
+
await runOwnerRuntimeActivity(
|
|
30517
|
+
runtime,
|
|
30518
|
+
() => archiveCoordinator.runSharedMany([sessionId], async () => {
|
|
30519
|
+
const sessionService = createWorkspaceRuntimeSessionService(runtime);
|
|
30520
|
+
const storageSessionId = await resolveSessionIdForRestore(
|
|
30521
|
+
sessionService,
|
|
30522
|
+
sessionId
|
|
30523
|
+
);
|
|
30524
|
+
if (storageSessionId === void 0) {
|
|
30525
|
+
throw new SessionNotFoundError(sessionId);
|
|
30526
|
+
}
|
|
30527
|
+
const oldSidecarPath = sessionService.getWorktreeSessionPath(storageSessionId);
|
|
30528
|
+
if (runtime.bridge.setSessionResetPending === void 0 || runtime.bridge.clearSessionResetPending === void 0 || runtime.bridge.clearSessionWorktree === void 0 || runtime.bridge.severSessionClients === void 0) {
|
|
30529
|
+
throw new Error("Bridge does not support worktree reset");
|
|
30530
|
+
}
|
|
30531
|
+
const preRead = await readWorktreeSessionStrict(oldSidecarPath);
|
|
30532
|
+
if (preRead.state === "missing" || preRead.state === "valid" && preRead.session.workspaceCwd === void 0) {
|
|
30533
|
+
throw new WorktreeResetUnsupportedError(sessionId);
|
|
30534
|
+
}
|
|
30535
|
+
if (preRead.state !== "valid") {
|
|
30536
|
+
daemonLog?.warn("worktree reset rejected invalid sidecar", {
|
|
30537
|
+
sessionId,
|
|
30538
|
+
reason: preRead.reason
|
|
30539
|
+
});
|
|
30540
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30541
|
+
}
|
|
30542
|
+
const preTarget = await resolveWorktreeOwnershipTarget(
|
|
30543
|
+
runtime,
|
|
30544
|
+
workspaceCwd,
|
|
30545
|
+
preRead.session,
|
|
30546
|
+
sessionId
|
|
30547
|
+
);
|
|
30548
|
+
const releaseOwnership = await acquireWorktreeOwnershipOp(
|
|
30549
|
+
preTarget.realTarget
|
|
30550
|
+
);
|
|
30551
|
+
try {
|
|
30552
|
+
const lockedRead = await readWorktreeSessionStrict(oldSidecarPath);
|
|
30553
|
+
if (lockedRead.state === "missing" || lockedRead.state === "valid" && lockedRead.session.workspaceCwd === void 0) {
|
|
30554
|
+
throw new WorktreeResetUnsupportedError(sessionId);
|
|
30555
|
+
}
|
|
30556
|
+
if (lockedRead.state !== "valid") {
|
|
30557
|
+
daemonLog?.warn("worktree reset rejected invalid sidecar", {
|
|
30558
|
+
sessionId,
|
|
30559
|
+
reason: lockedRead.reason
|
|
30560
|
+
});
|
|
30561
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30562
|
+
}
|
|
30563
|
+
const oldSidecar = lockedRead.session;
|
|
30564
|
+
const { realTarget, candidateRoots } = await resolveWorktreeOwnershipTarget(
|
|
30565
|
+
runtime,
|
|
30566
|
+
workspaceCwd,
|
|
30567
|
+
oldSidecar,
|
|
30568
|
+
sessionId
|
|
30569
|
+
);
|
|
30570
|
+
if (realTarget !== preTarget.realTarget) {
|
|
30571
|
+
daemonLog?.warn("worktree reset rejected: sidecar moved", {
|
|
30572
|
+
sessionId
|
|
30573
|
+
});
|
|
30574
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30575
|
+
}
|
|
30576
|
+
const readSummary = /* @__PURE__ */ __name((id) => {
|
|
30577
|
+
try {
|
|
30578
|
+
return runtime.bridge.getSessionSummary(id);
|
|
30579
|
+
} catch (error2) {
|
|
30580
|
+
if (error2 instanceof SessionNotFoundError) return void 0;
|
|
30581
|
+
throw error2;
|
|
30582
|
+
}
|
|
30583
|
+
}, "readSummary");
|
|
30584
|
+
runtime.bridge.setSessionResetPending(sessionId);
|
|
30585
|
+
let barrierArmed = true;
|
|
30586
|
+
try {
|
|
30587
|
+
let effectiveOldSidecar = oldSidecar;
|
|
30588
|
+
if (oldSidecar.supersededBy !== void 0) {
|
|
30589
|
+
const replacementId = oldSidecar.supersededBy;
|
|
30590
|
+
const newSidecarPath = sessionService.getWorktreeSessionPath(replacementId);
|
|
30591
|
+
const newRead = await readWorktreeSessionStrict(newSidecarPath);
|
|
30592
|
+
const linksAgree = newRead.state === "valid" && newRead.session.supersedes === storageSessionId;
|
|
30593
|
+
const marker = await readWorktreeSessionMarkerStrict(realTarget);
|
|
30594
|
+
if (marker.state === "invalid") {
|
|
30595
|
+
daemonLog?.warn("worktree reset resume rejected marker", {
|
|
30596
|
+
sessionId,
|
|
30597
|
+
reason: marker.reason
|
|
30598
|
+
});
|
|
30599
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30600
|
+
}
|
|
30601
|
+
if (marker.state === "missing" || marker.state === "valid" && marker.sessionId === storageSessionId) {
|
|
30602
|
+
if (!linksAgree) {
|
|
30603
|
+
daemonLog?.warn(
|
|
30604
|
+
"worktree reset resume found inconsistent links",
|
|
30605
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30606
|
+
);
|
|
30607
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30608
|
+
}
|
|
30609
|
+
if (marker.state === "missing" && readSummary(replacementId) !== void 0) {
|
|
30610
|
+
daemonLog?.warn(
|
|
30611
|
+
"worktree reset resume found a live replacement with no marker",
|
|
30612
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30613
|
+
);
|
|
30614
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30615
|
+
}
|
|
30616
|
+
const { supersededBy: _drop, ...restoredOld } = oldSidecar;
|
|
30617
|
+
const removed = await runWithWorkspaceRuntimeStorage(
|
|
30618
|
+
runtime,
|
|
30619
|
+
() => deleteDaemonSessionIfOrphan({
|
|
30620
|
+
sessionId: replacementId,
|
|
30621
|
+
service: sessionService,
|
|
30622
|
+
bridge: runtime.bridge,
|
|
30623
|
+
coordinator: archiveCoordinator
|
|
30624
|
+
})
|
|
30625
|
+
).catch(() => false);
|
|
30626
|
+
if (!removed) {
|
|
30627
|
+
daemonLog?.warn(
|
|
30628
|
+
"worktree reset could not remove the interrupted replacement",
|
|
30629
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30630
|
+
);
|
|
30631
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30632
|
+
}
|
|
30633
|
+
await clearWorktreeSession(newSidecarPath);
|
|
30634
|
+
await writeWorktreeSession(oldSidecarPath, restoredOld);
|
|
30635
|
+
daemonLog?.warn(
|
|
30636
|
+
"worktree reset rolled back an interrupted transfer",
|
|
30637
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30638
|
+
);
|
|
30639
|
+
effectiveOldSidecar = restoredOld;
|
|
30640
|
+
} else if (marker.state === "valid" && marker.sessionId === replacementId) {
|
|
30641
|
+
barrierArmed = false;
|
|
30642
|
+
if (!linksAgree) {
|
|
30643
|
+
daemonLog?.warn(
|
|
30644
|
+
"worktree reset resume found inconsistent links",
|
|
30645
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30646
|
+
);
|
|
30647
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30648
|
+
}
|
|
30649
|
+
const newSummary = readSummary(replacementId);
|
|
30650
|
+
if (newSummary && (newSummary.hasActivePrompt || (newSummary.pendingInteractionCount ?? 0) > 0)) {
|
|
30651
|
+
throw new WorktreeResetActiveError(replacementId);
|
|
30652
|
+
}
|
|
30653
|
+
runtime.bridge.clearSessionWorktree(sessionId);
|
|
30654
|
+
const severCompleted = await runtime.bridge.severSessionClients(sessionId);
|
|
30655
|
+
if (severCompleted) {
|
|
30656
|
+
runtime.bridge.clearSessionResetPending(sessionId);
|
|
30657
|
+
} else {
|
|
30658
|
+
daemonLog?.warn(
|
|
30659
|
+
"worktree reset left the superseded session live",
|
|
30660
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30661
|
+
);
|
|
30662
|
+
}
|
|
30663
|
+
assertRuntimeGenerationOpen?.();
|
|
30664
|
+
daemonLog?.info(
|
|
30665
|
+
"worktree session reset resumed after interruption",
|
|
30666
|
+
{ sessionId, replacementSessionId: replacementId }
|
|
30667
|
+
);
|
|
30668
|
+
res.status(200).json({
|
|
30669
|
+
sessionId: replacementId,
|
|
30670
|
+
workspaceCwd,
|
|
30671
|
+
currentCwd: realTarget,
|
|
30672
|
+
worktree: {
|
|
30673
|
+
slug: oldSidecar.slug,
|
|
30674
|
+
path: realTarget,
|
|
30675
|
+
branch: oldSidecar.worktreeBranch
|
|
30676
|
+
},
|
|
30677
|
+
worktreeState: "persisted-v1",
|
|
30678
|
+
attached: false,
|
|
30679
|
+
...severCompleted ? {} : { supersededSessionLive: true }
|
|
30680
|
+
});
|
|
30681
|
+
return;
|
|
30682
|
+
} else {
|
|
30683
|
+
daemonLog?.warn(
|
|
30684
|
+
"worktree reset resume found a marker naming another session",
|
|
30685
|
+
{ sessionId }
|
|
30686
|
+
);
|
|
30687
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30688
|
+
}
|
|
30689
|
+
}
|
|
30690
|
+
const oldSummary = readSummary(sessionId);
|
|
30691
|
+
if (oldSummary && (oldSummary.hasActivePrompt || (oldSummary.pendingInteractionCount ?? 0) > 0)) {
|
|
30692
|
+
throw new WorktreeResetActiveError(sessionId);
|
|
30693
|
+
}
|
|
30694
|
+
let spawnedNew;
|
|
30695
|
+
let newSidecarWritten = false;
|
|
30696
|
+
let oldSupersededWritten = false;
|
|
30697
|
+
let markerTransferred = false;
|
|
30698
|
+
try {
|
|
30699
|
+
assertRuntimeGenerationOpen?.();
|
|
30700
|
+
const spawned = await runtime.bridge.spawnOrAttach({
|
|
30701
|
+
workspaceCwd,
|
|
30702
|
+
modelServiceId,
|
|
30703
|
+
sessionScope: "thread",
|
|
30704
|
+
...approvalMode !== void 0 ? { approvalMode } : {},
|
|
30705
|
+
...source.sourceType !== void 0 ? { sourceType: source.sourceType } : {},
|
|
30706
|
+
...source.sourceId !== void 0 ? { sourceId: source.sourceId } : {}
|
|
30707
|
+
});
|
|
30708
|
+
spawnedNew = { sessionId: spawned.sessionId };
|
|
30709
|
+
const changed = await runtime.bridge.changeSessionCwd(
|
|
30710
|
+
spawned.sessionId,
|
|
30711
|
+
{ path: realTarget, allowedRoots: candidateRoots }
|
|
30712
|
+
);
|
|
30713
|
+
if (changed.newCwd !== realTarget) {
|
|
30714
|
+
throw new Error("Worktree relocation was rejected");
|
|
30715
|
+
}
|
|
30716
|
+
await writeWorktreeSession(oldSidecarPath, {
|
|
30717
|
+
...effectiveOldSidecar,
|
|
30718
|
+
supersededBy: spawned.sessionId
|
|
30719
|
+
});
|
|
30720
|
+
oldSupersededWritten = true;
|
|
30721
|
+
const newSidecarPath = sessionService.getWorktreeSessionPath(
|
|
30722
|
+
spawned.sessionId
|
|
30723
|
+
);
|
|
30724
|
+
const {
|
|
30725
|
+
supersededBy: _dropOld,
|
|
30726
|
+
supersedes: _dropOldLink,
|
|
30727
|
+
...oldSidecarCore
|
|
30728
|
+
} = effectiveOldSidecar;
|
|
30729
|
+
await writeWorktreeSession(newSidecarPath, {
|
|
30730
|
+
...oldSidecarCore,
|
|
30731
|
+
supersedes: storageSessionId
|
|
30732
|
+
});
|
|
30733
|
+
newSidecarWritten = true;
|
|
30734
|
+
if (res.destroyed || res.socket?.writable === false) {
|
|
30735
|
+
throw new Error(
|
|
30736
|
+
"Client disconnected before the worktree ownership flip"
|
|
30737
|
+
);
|
|
30738
|
+
}
|
|
30739
|
+
const windingDown = readSummary(sessionId);
|
|
30740
|
+
if (windingDown && (windingDown.hasActivePrompt || (windingDown.pendingInteractionCount ?? 0) > 0)) {
|
|
30741
|
+
throw new WorktreeResetActiveError(sessionId);
|
|
30742
|
+
}
|
|
30743
|
+
const markerBeforeFlip = await readWorktreeSessionMarkerStrict(realTarget);
|
|
30744
|
+
try {
|
|
30745
|
+
await transferWorktreeSessionMarkerOwner(
|
|
30746
|
+
realTarget,
|
|
30747
|
+
markerBeforeFlip.state === "missing" ? null : storageSessionId,
|
|
30748
|
+
spawned.sessionId
|
|
30749
|
+
);
|
|
30750
|
+
} catch (markerError) {
|
|
30751
|
+
daemonLog?.warn("worktree marker transfer failed", {
|
|
30752
|
+
sessionId,
|
|
30753
|
+
replacementSessionId: spawned.sessionId,
|
|
30754
|
+
error: markerError instanceof Error ? markerError.message : String(markerError)
|
|
30755
|
+
});
|
|
30756
|
+
if (markerError instanceof WorktreeMarkerCommittedError) {
|
|
30757
|
+
markerTransferred = true;
|
|
30758
|
+
barrierArmed = false;
|
|
30759
|
+
throw new Error(
|
|
30760
|
+
"Worktree ownership moved to the replacement, but the marker commit did not finish cleanly; retry the reset to complete the transfer"
|
|
30761
|
+
);
|
|
30762
|
+
}
|
|
30763
|
+
throw new WorktreeResetInvalidStateError(sessionId);
|
|
30764
|
+
}
|
|
30765
|
+
markerTransferred = true;
|
|
30766
|
+
barrierArmed = false;
|
|
30767
|
+
const newWorktree = {
|
|
30768
|
+
slug: effectiveOldSidecar.slug,
|
|
30769
|
+
path: realTarget,
|
|
30770
|
+
branch: effectiveOldSidecar.worktreeBranch
|
|
30771
|
+
};
|
|
30772
|
+
runtime.bridge.setSessionWorktree(
|
|
30773
|
+
spawned.sessionId,
|
|
30774
|
+
newWorktree
|
|
30775
|
+
);
|
|
30776
|
+
assertRuntimeGenerationOpen?.();
|
|
30777
|
+
runtime.bridge.clearSessionWorktree(sessionId);
|
|
30778
|
+
const severCompleted = await runtime.bridge.severSessionClients(sessionId);
|
|
30779
|
+
if (severCompleted) {
|
|
30780
|
+
runtime.bridge.clearSessionResetPending(sessionId);
|
|
30781
|
+
} else {
|
|
30782
|
+
daemonLog?.warn(
|
|
30783
|
+
"worktree reset left the superseded session live",
|
|
30784
|
+
{
|
|
30785
|
+
sessionId,
|
|
30786
|
+
replacementSessionId: spawned.sessionId
|
|
30787
|
+
}
|
|
30788
|
+
);
|
|
30789
|
+
}
|
|
30790
|
+
daemonLog?.info("worktree session reset", {
|
|
30791
|
+
sessionId,
|
|
30792
|
+
replacementSessionId: spawned.sessionId
|
|
30793
|
+
});
|
|
30794
|
+
res.status(200).json({
|
|
30795
|
+
...spawned,
|
|
30796
|
+
currentCwd: realTarget,
|
|
30797
|
+
worktree: newWorktree,
|
|
30798
|
+
worktreeState: "persisted-v1",
|
|
30799
|
+
...severCompleted ? {} : { supersededSessionLive: true }
|
|
30800
|
+
});
|
|
30801
|
+
} catch (transferError) {
|
|
30802
|
+
if (markerTransferred) {
|
|
30803
|
+
daemonLog?.warn(
|
|
30804
|
+
"worktree reset failed after the ownership flip",
|
|
30805
|
+
{
|
|
30806
|
+
sessionId,
|
|
30807
|
+
replacementSessionId: spawnedNew?.sessionId,
|
|
30808
|
+
error: transferError instanceof Error ? transferError.message : String(transferError)
|
|
30809
|
+
}
|
|
30810
|
+
);
|
|
30811
|
+
throw transferError;
|
|
30812
|
+
}
|
|
30813
|
+
if (spawnedNew) {
|
|
30814
|
+
const orphanSessionId = spawnedNew.sessionId;
|
|
30815
|
+
const removed = await runWithWorkspaceRuntimeStorage(
|
|
30816
|
+
runtime,
|
|
30817
|
+
() => deleteDaemonSessionIfOrphan({
|
|
30818
|
+
sessionId: orphanSessionId,
|
|
30819
|
+
service: sessionService,
|
|
30820
|
+
bridge: runtime.bridge,
|
|
30821
|
+
coordinator: archiveCoordinator
|
|
30822
|
+
})
|
|
30823
|
+
).catch(() => false);
|
|
30824
|
+
if (!removed) {
|
|
30825
|
+
daemonLog?.warn(
|
|
30826
|
+
"worktree reset could not remove the spawned replacement",
|
|
30827
|
+
{ sessionId, replacementSessionId: orphanSessionId }
|
|
30828
|
+
);
|
|
30829
|
+
throw transferError;
|
|
30830
|
+
}
|
|
30831
|
+
}
|
|
30832
|
+
if (newSidecarWritten && spawnedNew) {
|
|
30833
|
+
await clearWorktreeSession(
|
|
30834
|
+
sessionService.getWorktreeSessionPath(spawnedNew.sessionId)
|
|
30835
|
+
);
|
|
30836
|
+
}
|
|
30837
|
+
if (oldSupersededWritten) {
|
|
30838
|
+
await writeWorktreeSession(
|
|
30839
|
+
oldSidecarPath,
|
|
30840
|
+
effectiveOldSidecar
|
|
30841
|
+
);
|
|
30842
|
+
}
|
|
30843
|
+
throw transferError;
|
|
30844
|
+
}
|
|
30845
|
+
} finally {
|
|
30846
|
+
if (barrierArmed) {
|
|
30847
|
+
runtime.bridge.clearSessionResetPending(sessionId);
|
|
30848
|
+
}
|
|
30849
|
+
}
|
|
30850
|
+
} finally {
|
|
30851
|
+
releaseOwnership();
|
|
30852
|
+
}
|
|
30853
|
+
})
|
|
30854
|
+
);
|
|
30855
|
+
} catch (err) {
|
|
30856
|
+
if (!res.headersSent) {
|
|
30857
|
+
sendBridgeError2(res, err, { route, sessionId });
|
|
30858
|
+
}
|
|
30859
|
+
}
|
|
30860
|
+
}, "worktreeResetHandler");
|
|
30861
|
+
app.post("/session/:id/worktree-reset", mutate(), worktreeResetHandler);
|
|
30753
30862
|
app.get("/session/:id/subagents/:subagentRef", async (req, res) => {
|
|
30754
30863
|
const route = "GET /session/:id/subagents/:subagentRef";
|
|
30755
30864
|
const sessionId = requireSessionId(req, res);
|
|
@@ -31018,7 +31127,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
31018
31127
|
async (req, res, sessionId, runtime) => {
|
|
31019
31128
|
const body = safeBody(req);
|
|
31020
31129
|
const targetPath = body["path"];
|
|
31021
|
-
if (typeof targetPath !== "string" || targetPath.length === 0 || !
|
|
31130
|
+
if (typeof targetPath !== "string" || targetPath.length === 0 || !path11.isAbsolute(targetPath)) {
|
|
31022
31131
|
res.status(400).json({
|
|
31023
31132
|
error: "`path` is required and must be an absolute path",
|
|
31024
31133
|
code: "invalid_path"
|
|
@@ -33486,6 +33595,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
33486
33595
|
sessionId: session.sessionId,
|
|
33487
33596
|
clientCount: session.clientCount,
|
|
33488
33597
|
hasActivePrompt: session.hasActivePrompt,
|
|
33598
|
+
...session.activeWorkState !== void 0 ? { activeWorkState: session.activeWorkState } : {},
|
|
33489
33599
|
isWaitingForPermission: session.isWaitingForPermission ?? false,
|
|
33490
33600
|
isWaitingForUserQuestion: session.isWaitingForUserQuestion ?? false,
|
|
33491
33601
|
// Bridge-local activity watermark, absent until a running prompt in
|
|
@@ -34011,6 +34121,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
34011
34121
|
const body = safeBody(req);
|
|
34012
34122
|
const mode = body["mode"];
|
|
34013
34123
|
const persist = body["persist"];
|
|
34124
|
+
const planMode = body["planMode"];
|
|
34014
34125
|
if (typeof mode !== "string" || !APPROVAL_MODES.includes(mode)) {
|
|
34015
34126
|
res.status(400).json({
|
|
34016
34127
|
error: "`mode` is required and must be one of the allowed values",
|
|
@@ -34026,12 +34137,22 @@ function registerSessionRoutes(app, deps) {
|
|
|
34026
34137
|
});
|
|
34027
34138
|
return;
|
|
34028
34139
|
}
|
|
34140
|
+
if (planMode !== void 0 && (typeof planMode !== "boolean" || mode === "plan")) {
|
|
34141
|
+
res.status(400).json({
|
|
34142
|
+
error: "`planMode` must be a boolean with a non-plan execution mode",
|
|
34143
|
+
code: "invalid_plan_mode"
|
|
34144
|
+
});
|
|
34145
|
+
return;
|
|
34146
|
+
}
|
|
34029
34147
|
const clientId = parseClientIdHeader(req, res);
|
|
34030
34148
|
if (clientId === null) return;
|
|
34031
34149
|
const response = await runtime.bridge.setSessionApprovalMode(
|
|
34032
34150
|
sessionId,
|
|
34033
34151
|
mode,
|
|
34034
|
-
{
|
|
34152
|
+
{
|
|
34153
|
+
persist: persist === true,
|
|
34154
|
+
...typeof planMode === "boolean" ? { planMode } : {}
|
|
34155
|
+
},
|
|
34035
34156
|
clientId !== void 0 ? { clientId } : void 0
|
|
34036
34157
|
);
|
|
34037
34158
|
res.status(200).json(response);
|
|
@@ -34083,8 +34204,8 @@ __name(registerSessionRoutes, "registerSessionRoutes");
|
|
|
34083
34204
|
// packages/cli/src/serve/routes/session-pr-backfill.ts
|
|
34084
34205
|
init_esbuild_shims();
|
|
34085
34206
|
import { existsSync } from "node:fs";
|
|
34086
|
-
import * as
|
|
34087
|
-
import * as
|
|
34207
|
+
import * as fs7 from "node:fs/promises";
|
|
34208
|
+
import * as path12 from "node:path";
|
|
34088
34209
|
var SLUG_PR_PATTERN = /^pr-([1-9]\d{0,8})$/;
|
|
34089
34210
|
var BRANCH_PR_PATTERN = /^worktree-pr-([1-9]\d{0,8})$/;
|
|
34090
34211
|
function parsePrNumberFromWorktree(slug, branch) {
|
|
@@ -34173,7 +34294,7 @@ async function backfillWorkspaceSessionPrs(runtime, fetchPullRequests = fetchGit
|
|
|
34173
34294
|
for (const sessionId of sessionIds) {
|
|
34174
34295
|
if (!isValidSessionId(sessionId)) continue;
|
|
34175
34296
|
result.scanned += 1;
|
|
34176
|
-
const dir =
|
|
34297
|
+
const dir = path12.dirname(
|
|
34177
34298
|
sessionService.getWorktreeSessionPathForArchiveState(
|
|
34178
34299
|
sessionId,
|
|
34179
34300
|
archiveState
|
|
@@ -34182,15 +34303,15 @@ async function backfillWorkspaceSessionPrs(runtime, fetchPullRequests = fetchGit
|
|
|
34182
34303
|
let worktree;
|
|
34183
34304
|
try {
|
|
34184
34305
|
worktree = await readWorktreeSession(
|
|
34185
|
-
|
|
34306
|
+
path12.join(dir, `${sessionId}.worktree.json`)
|
|
34186
34307
|
);
|
|
34187
34308
|
} catch {
|
|
34188
34309
|
worktree = null;
|
|
34189
34310
|
}
|
|
34190
34311
|
let transcriptRaw;
|
|
34191
34312
|
try {
|
|
34192
|
-
transcriptRaw = await
|
|
34193
|
-
|
|
34313
|
+
transcriptRaw = await fs7.readFile(
|
|
34314
|
+
path12.join(dir, `${sessionId}.jsonl`),
|
|
34194
34315
|
"utf8"
|
|
34195
34316
|
);
|
|
34196
34317
|
} catch {
|
|
@@ -34210,7 +34331,7 @@ async function backfillWorkspaceSessionPrs(runtime, fetchPullRequests = fetchGit
|
|
|
34210
34331
|
candidates.push({
|
|
34211
34332
|
sessionId,
|
|
34212
34333
|
archiveState,
|
|
34213
|
-
transcriptPath:
|
|
34334
|
+
transcriptPath: path12.join(dir, `${sessionId}.jsonl`),
|
|
34214
34335
|
conventionNumber,
|
|
34215
34336
|
mentions: reviewed.mentions,
|
|
34216
34337
|
reviewedUrlForms: reviewed.reviewedUrlForms
|
|
@@ -34342,8 +34463,8 @@ async function backfillWorkspaceSessionPrs(runtime, fetchPullRequests = fetchGit
|
|
|
34342
34463
|
candidate.sessionId,
|
|
34343
34464
|
archiveState
|
|
34344
34465
|
);
|
|
34345
|
-
const transcriptPath =
|
|
34346
|
-
|
|
34466
|
+
const transcriptPath = path12.join(
|
|
34467
|
+
path12.dirname(prPath),
|
|
34347
34468
|
`${candidate.sessionId}.jsonl`
|
|
34348
34469
|
);
|
|
34349
34470
|
const snapshotAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -34986,7 +35107,7 @@ __name(registerStandaloneSessionRoutes, "registerStandaloneSessionRoutes");
|
|
|
34986
35107
|
|
|
34987
35108
|
// packages/cli/src/serve/routes/channel-notify.ts
|
|
34988
35109
|
init_esbuild_shims();
|
|
34989
|
-
import { randomUUID as
|
|
35110
|
+
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
34990
35111
|
function sendDeliveryError(res, error2) {
|
|
34991
35112
|
if (!isChannelDeliveryError(error2)) {
|
|
34992
35113
|
res.status(502).json({
|
|
@@ -35007,7 +35128,7 @@ function parseNotifyBody(body) {
|
|
|
35007
35128
|
);
|
|
35008
35129
|
}
|
|
35009
35130
|
return normalizeChannelDelivery(
|
|
35010
|
-
|
|
35131
|
+
randomUUID9(),
|
|
35011
35132
|
parseChannelDelivery(body["delivery"]),
|
|
35012
35133
|
body["text"]
|
|
35013
35134
|
);
|
|
@@ -35210,7 +35331,7 @@ __name(registerUsageStatsRoutes, "registerUsageStatsRoutes");
|
|
|
35210
35331
|
// packages/cli/src/serve/scheduled-task-keepalive.ts
|
|
35211
35332
|
init_esbuild_shims();
|
|
35212
35333
|
import * as fsSync from "node:fs";
|
|
35213
|
-
import * as
|
|
35334
|
+
import * as path13 from "node:path";
|
|
35214
35335
|
var log = createDebugLogger("SCHED_KEEPALIVE");
|
|
35215
35336
|
function collectBoundSessionIds(tasks) {
|
|
35216
35337
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -35442,8 +35563,8 @@ function startScheduledTaskKeepalive(opts) {
|
|
|
35442
35563
|
opts.runtimeBaseDir,
|
|
35443
35564
|
() => getCronFilePath(boundWorkspace)
|
|
35444
35565
|
);
|
|
35445
|
-
const cronDir =
|
|
35446
|
-
const cronFileName =
|
|
35566
|
+
const cronDir = path13.dirname(cronFilePath);
|
|
35567
|
+
const cronFileName = path13.basename(cronFilePath);
|
|
35447
35568
|
let fileWatcher;
|
|
35448
35569
|
try {
|
|
35449
35570
|
fsSync.mkdirSync(cronDir, { recursive: true });
|
|
@@ -36166,6 +36287,10 @@ function workflowsEnabledForRuntime(runtime, daemonEnv) {
|
|
|
36166
36287
|
}
|
|
36167
36288
|
__name(workflowsEnabledForRuntime, "workflowsEnabledForRuntime");
|
|
36168
36289
|
function registerCapabilitiesRoutes(app, deps) {
|
|
36290
|
+
const configuredPollIntervalMs = Number(
|
|
36291
|
+
deps.daemonEnv["QWEN_SESSION_LIVE_STATE_POLL_INTERVAL_MS"]
|
|
36292
|
+
);
|
|
36293
|
+
const sessionLiveStatePollIntervalMs = Number.isSafeInteger(configuredPollIntervalMs) && configuredPollIntervalMs >= 1e3 && configuredPollIntervalMs <= 2147483647 ? configuredPollIntervalMs : 5e3;
|
|
36169
36294
|
app.get("/capabilities", (_req, res) => {
|
|
36170
36295
|
const entries = deps.workspaceRegistry.listAllEntries().filter(
|
|
36171
36296
|
(entry) => !entry.internal || entry.state === "active" && entry.current !== void 0
|
|
@@ -36182,6 +36307,7 @@ function registerCapabilitiesRoutes(app, deps) {
|
|
|
36182
36307
|
...deps.qwenCodeVersion ? { qwenCodeVersion: deps.qwenCodeVersion } : {},
|
|
36183
36308
|
mode: deps.mode,
|
|
36184
36309
|
features,
|
|
36310
|
+
sessionLiveStatePollIntervalMs,
|
|
36185
36311
|
modelServices: [],
|
|
36186
36312
|
// Surface the primary workspace so clients can omit `cwd` on
|
|
36187
36313
|
// `POST /session`; multi-workspace clients use `workspaces[]`.
|
|
@@ -37242,7 +37368,7 @@ __name(registerUserLanguageRoutes, "registerUserLanguageRoutes");
|
|
|
37242
37368
|
|
|
37243
37369
|
// packages/cli/src/serve/routes/sse-events.ts
|
|
37244
37370
|
init_esbuild_shims();
|
|
37245
|
-
import { randomUUID as
|
|
37371
|
+
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
37246
37372
|
import { performance as performance3 } from "node:perf_hooks";
|
|
37247
37373
|
|
|
37248
37374
|
// packages/cli/src/serve/server/error-response.ts
|
|
@@ -37623,6 +37749,63 @@ function sendBridgeError(res, err, ctx, daemonLog) {
|
|
|
37623
37749
|
});
|
|
37624
37750
|
return;
|
|
37625
37751
|
}
|
|
37752
|
+
if (err instanceof SessionResetPendingError) {
|
|
37753
|
+
res.status(409).json({
|
|
37754
|
+
error: err.message,
|
|
37755
|
+
code: "worktree_reset_active",
|
|
37756
|
+
sessionId: err.sessionId
|
|
37757
|
+
});
|
|
37758
|
+
return;
|
|
37759
|
+
}
|
|
37760
|
+
if (err instanceof WorktreeSessionSupersededError) {
|
|
37761
|
+
res.status(409).json({
|
|
37762
|
+
error: err.message,
|
|
37763
|
+
code: "worktree_session_superseded",
|
|
37764
|
+
sessionId: err.sessionId,
|
|
37765
|
+
replacementSessionId: err.replacementSessionId
|
|
37766
|
+
});
|
|
37767
|
+
return;
|
|
37768
|
+
}
|
|
37769
|
+
if (err instanceof WorktreeMarkerMissingError) {
|
|
37770
|
+
res.status(409).json({
|
|
37771
|
+
error: err.message,
|
|
37772
|
+
code: "worktree_marker_missing",
|
|
37773
|
+
sessionId: err.sessionId
|
|
37774
|
+
});
|
|
37775
|
+
return;
|
|
37776
|
+
}
|
|
37777
|
+
if (err instanceof WorktreeResetInterruptedError) {
|
|
37778
|
+
res.status(409).json({
|
|
37779
|
+
error: err.message,
|
|
37780
|
+
code: "worktree_reset_interrupted",
|
|
37781
|
+
sessionId: err.sessionId
|
|
37782
|
+
});
|
|
37783
|
+
return;
|
|
37784
|
+
}
|
|
37785
|
+
if (err instanceof WorktreeResetActiveError) {
|
|
37786
|
+
res.status(409).json({
|
|
37787
|
+
error: err.message,
|
|
37788
|
+
code: "worktree_reset_active",
|
|
37789
|
+
sessionId: err.sessionId
|
|
37790
|
+
});
|
|
37791
|
+
return;
|
|
37792
|
+
}
|
|
37793
|
+
if (err instanceof WorktreeResetUnsupportedError) {
|
|
37794
|
+
res.status(409).json({
|
|
37795
|
+
error: err.message,
|
|
37796
|
+
code: "worktree_reset_unsupported",
|
|
37797
|
+
sessionId: err.sessionId
|
|
37798
|
+
});
|
|
37799
|
+
return;
|
|
37800
|
+
}
|
|
37801
|
+
if (err instanceof WorktreeResetInvalidStateError) {
|
|
37802
|
+
res.status(409).json({
|
|
37803
|
+
error: err.message,
|
|
37804
|
+
code: "worktree_reset_invalid_state",
|
|
37805
|
+
sessionId: err.sessionId
|
|
37806
|
+
});
|
|
37807
|
+
return;
|
|
37808
|
+
}
|
|
37626
37809
|
if (err instanceof TrustGateError) {
|
|
37627
37810
|
res.status(403).json({
|
|
37628
37811
|
error: err.message,
|
|
@@ -38088,7 +38271,7 @@ function registerSseEventsRoutes(app, deps) {
|
|
|
38088
38271
|
app.get("/session/:id/events", async (req, res) => {
|
|
38089
38272
|
const sessionId = req.params["id"];
|
|
38090
38273
|
const diagnosticSessionId = boundedDiagnosticString(sessionId);
|
|
38091
|
-
const streamId =
|
|
38274
|
+
const streamId = randomUUID10();
|
|
38092
38275
|
const clientId = parseSseClientId(req.headers["x-qwen-client-id"]);
|
|
38093
38276
|
const connectReason = parseSseConnectReason(req.query["connectReason"]);
|
|
38094
38277
|
const previousStreamId = parsePreviousSseStreamId(
|
|
@@ -38116,6 +38299,8 @@ function registerSseEventsRoutes(app, deps) {
|
|
|
38116
38299
|
}, "emitLifecycleLog");
|
|
38117
38300
|
let slowWarningCount = 0;
|
|
38118
38301
|
let eventBusEvictionReason;
|
|
38302
|
+
let closeReason;
|
|
38303
|
+
let terminalEventType;
|
|
38119
38304
|
const onSubscriberDiagnostic = /* @__PURE__ */ __name((diagnostic) => {
|
|
38120
38305
|
const triggerEventType = boundedDiagnosticString(
|
|
38121
38306
|
diagnostic.data.triggerEventType
|
|
@@ -38212,6 +38397,22 @@ function registerSseEventsRoutes(app, deps) {
|
|
|
38212
38397
|
} : {}
|
|
38213
38398
|
}
|
|
38214
38399
|
);
|
|
38400
|
+
closeReason = "event_bus_evicted";
|
|
38401
|
+
terminalEventType = "client_evicted";
|
|
38402
|
+
const evictionData = { ...diagnostic.data };
|
|
38403
|
+
Reflect.deleteProperty(evictionData, "triggerEventType");
|
|
38404
|
+
Reflect.deleteProperty(evictionData, "triggerEventBytes");
|
|
38405
|
+
try {
|
|
38406
|
+
res.write(
|
|
38407
|
+
formatSseFrame({
|
|
38408
|
+
v: 1,
|
|
38409
|
+
type: "client_evicted",
|
|
38410
|
+
data: evictionData
|
|
38411
|
+
})
|
|
38412
|
+
);
|
|
38413
|
+
} catch {
|
|
38414
|
+
}
|
|
38415
|
+
res.destroy();
|
|
38215
38416
|
}
|
|
38216
38417
|
return handled;
|
|
38217
38418
|
}, "onSubscriberDiagnostic");
|
|
@@ -38297,9 +38498,7 @@ function registerSseEventsRoutes(app, deps) {
|
|
|
38297
38498
|
return;
|
|
38298
38499
|
}
|
|
38299
38500
|
const openedAt = performance3.now();
|
|
38300
|
-
let closeReason;
|
|
38301
38501
|
let terminalCandidate;
|
|
38302
|
-
let terminalEventType;
|
|
38303
38502
|
let eventFramesWriteSettled = 0;
|
|
38304
38503
|
let lastEventIdWritten;
|
|
38305
38504
|
let backpressureCount = 0;
|
|
@@ -38693,7 +38892,7 @@ function registerSseEventsRoutes(app, deps) {
|
|
|
38693
38892
|
}
|
|
38694
38893
|
} finally {
|
|
38695
38894
|
cleanup();
|
|
38696
|
-
if (!res.writableEnded) res.end();
|
|
38895
|
+
if (!res.destroyed && !res.writableEnded) res.end();
|
|
38697
38896
|
}
|
|
38698
38897
|
})();
|
|
38699
38898
|
});
|
|
@@ -38980,7 +39179,7 @@ __name(registerWorkspaceModelsRoutes, "registerWorkspaceModelsRoutes");
|
|
|
38980
39179
|
// packages/cli/src/serve/routes/a2ui-action.ts
|
|
38981
39180
|
init_esbuild_shims();
|
|
38982
39181
|
import * as fsp4 from "node:fs/promises";
|
|
38983
|
-
import * as
|
|
39182
|
+
import * as path14 from "node:path";
|
|
38984
39183
|
var A2UI_MIME = "application/a2ui+json";
|
|
38985
39184
|
var ACTION_TOOL = "action";
|
|
38986
39185
|
var CALL_TIMEOUT_MS = 15e3;
|
|
@@ -39003,7 +39202,7 @@ __name(usableServerConfig, "usableServerConfig");
|
|
|
39003
39202
|
async function findFromSettingsFile(workspaceCwd) {
|
|
39004
39203
|
try {
|
|
39005
39204
|
const raw = await fsp4.readFile(
|
|
39006
|
-
|
|
39205
|
+
path14.join(workspaceCwd, ".qwen", "settings.json"),
|
|
39007
39206
|
"utf8"
|
|
39008
39207
|
);
|
|
39009
39208
|
const settings = JSON.parse(raw);
|
|
@@ -39164,7 +39363,7 @@ __name(registerA2uiActionRoutes, "registerA2uiActionRoutes");
|
|
|
39164
39363
|
|
|
39165
39364
|
// packages/cli/src/serve/server/fs-factory.ts
|
|
39166
39365
|
init_esbuild_shims();
|
|
39167
|
-
import * as
|
|
39366
|
+
import * as path15 from "node:path";
|
|
39168
39367
|
var IDE_WORKSPACE_PATH_ENV_VAR = "QWEN_CODE_IDE_WORKSPACE_PATH";
|
|
39169
39368
|
var NEW_FILE_MODE_ENV_VAR = "QWEN_SERVE_NEW_FILE_MODE";
|
|
39170
39369
|
function parseNewFileModePolicy(env = process.env) {
|
|
@@ -39253,14 +39452,14 @@ function parseIdeWorkspacePathEnv(value) {
|
|
|
39253
39452
|
const parsed = JSON.parse(value);
|
|
39254
39453
|
if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
|
|
39255
39454
|
return parsed.filter(
|
|
39256
|
-
(workspace) => workspace.length > 0 &&
|
|
39455
|
+
(workspace) => workspace.length > 0 && path15.isAbsolute(workspace)
|
|
39257
39456
|
);
|
|
39258
39457
|
}
|
|
39259
39458
|
throw new Error("IDE workspace path JSON must be a string array");
|
|
39260
39459
|
} catch {
|
|
39261
39460
|
}
|
|
39262
39461
|
}
|
|
39263
|
-
return value.split(
|
|
39462
|
+
return value.split(path15.delimiter).filter((workspace) => workspace.length > 0 && path15.isAbsolute(workspace));
|
|
39264
39463
|
}
|
|
39265
39464
|
__name(parseIdeWorkspacePathEnv, "parseIdeWorkspacePathEnv");
|
|
39266
39465
|
function dropNestedWorkspacesPreservingPrimary(workspaces) {
|
|
@@ -39749,7 +39948,7 @@ __name(registerWorkspaceQualifiedLifecycleRoutes, "registerWorkspaceQualifiedLif
|
|
|
39749
39948
|
init_esbuild_shims();
|
|
39750
39949
|
import { readdir as readdir3, stat as stat2 } from "node:fs/promises";
|
|
39751
39950
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
39752
|
-
import { basename as basename7, dirname as
|
|
39951
|
+
import { basename as basename7, dirname as dirname8, isAbsolute as isAbsolute9, join as join11, resolve as resolve5, sep as sep4 } from "node:path";
|
|
39753
39952
|
var MAX_PATH_SUGGESTIONS = 50;
|
|
39754
39953
|
function registerWorkspaceManagementRoutes(app, deps) {
|
|
39755
39954
|
const {
|
|
@@ -40138,7 +40337,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
|
|
|
40138
40337
|
});
|
|
40139
40338
|
return;
|
|
40140
40339
|
}
|
|
40141
|
-
if (!
|
|
40340
|
+
if (!isAbsolute9(prefix)) {
|
|
40142
40341
|
res.status(400).json({
|
|
40143
40342
|
error: "`prefix` must be an absolute path",
|
|
40144
40343
|
code: "invalid_prefix"
|
|
@@ -40146,7 +40345,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
|
|
|
40146
40345
|
return;
|
|
40147
40346
|
}
|
|
40148
40347
|
const endsWithSep = prefix.endsWith("/") || process.platform === "win32" && prefix.endsWith("\\");
|
|
40149
|
-
const dir = endsWithSep ?
|
|
40348
|
+
const dir = endsWithSep ? join11(prefix, ".") : dirname8(prefix);
|
|
40150
40349
|
const filter = endsWithSep ? "" : basename7(prefix);
|
|
40151
40350
|
const filterLower = filter.toLowerCase();
|
|
40152
40351
|
const suggestions = [];
|
|
@@ -40162,7 +40361,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
|
|
|
40162
40361
|
let isDir = entry.isDirectory();
|
|
40163
40362
|
if (!isDir && entry.isSymbolicLink()) {
|
|
40164
40363
|
try {
|
|
40165
|
-
isDir = (await stat2(
|
|
40364
|
+
isDir = (await stat2(join11(dir, entry.name))).isDirectory();
|
|
40166
40365
|
} catch {
|
|
40167
40366
|
continue;
|
|
40168
40367
|
}
|
|
@@ -40172,7 +40371,7 @@ function registerWorkspaceManagementRoutes(app, deps) {
|
|
|
40172
40371
|
truncated = true;
|
|
40173
40372
|
break;
|
|
40174
40373
|
}
|
|
40175
|
-
suggestions.push({ name: entry.name, path:
|
|
40374
|
+
suggestions.push({ name: entry.name, path: join11(dir, entry.name) });
|
|
40176
40375
|
}
|
|
40177
40376
|
} catch {
|
|
40178
40377
|
}
|
|
@@ -45646,7 +45845,7 @@ init_esbuild_shims();
|
|
|
45646
45845
|
|
|
45647
45846
|
// packages/cli/src/serve/live/live-host-coordinator.ts
|
|
45648
45847
|
init_esbuild_shims();
|
|
45649
|
-
import { randomUUID as
|
|
45848
|
+
import { randomUUID as randomUUID11, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
45650
45849
|
var DEFAULT_HELLO_TIMEOUT_MS = 5e3;
|
|
45651
45850
|
var DEFAULT_HEARTBEAT_INTERVAL_MS = 5e3;
|
|
45652
45851
|
var DEFAULT_HEARTBEAT_TIMEOUT_MS = 15e3;
|
|
@@ -45829,7 +46028,7 @@ __name(projectStatusForHost, "projectStatusForHost");
|
|
|
45829
46028
|
var LiveHostCoordinator = class {
|
|
45830
46029
|
constructor(options) {
|
|
45831
46030
|
this.options = options;
|
|
45832
|
-
this.daemonInstanceNonce = options.daemonInstanceNonce ??
|
|
46031
|
+
this.daemonInstanceNonce = options.daemonInstanceNonce ?? randomUUID11();
|
|
45833
46032
|
this.handlers = options.handlers ?? {};
|
|
45834
46033
|
this.now = options.now ?? Date.now;
|
|
45835
46034
|
this.helloTimeoutMs = options.helloTimeoutMs ?? DEFAULT_HELLO_TIMEOUT_MS;
|
|
@@ -45860,6 +46059,7 @@ var LiveHostCoordinator = class {
|
|
|
45860
46059
|
};
|
|
45861
46060
|
call;
|
|
45862
46061
|
pendingStartMode;
|
|
46062
|
+
actionGeneration = 0;
|
|
45863
46063
|
nextEpoch = 0;
|
|
45864
46064
|
inputMuted = false;
|
|
45865
46065
|
outputMuted = false;
|
|
@@ -45880,6 +46080,7 @@ var LiveHostCoordinator = class {
|
|
|
45880
46080
|
return this.getStatus();
|
|
45881
46081
|
}
|
|
45882
46082
|
async deactivate() {
|
|
46083
|
+
++this.actionGeneration;
|
|
45883
46084
|
this.pendingStartMode = void 0;
|
|
45884
46085
|
if (this.call) {
|
|
45885
46086
|
const stopped = new Promise((resolve7) => {
|
|
@@ -45995,6 +46196,18 @@ var LiveHostCoordinator = class {
|
|
|
45995
46196
|
} : {}
|
|
45996
46197
|
};
|
|
45997
46198
|
}
|
|
46199
|
+
async requestStart(mode) {
|
|
46200
|
+
const generation = ++this.actionGeneration;
|
|
46201
|
+
this.pendingStartMode = void 0;
|
|
46202
|
+
try {
|
|
46203
|
+
await this.handlers.beforeStart?.();
|
|
46204
|
+
} catch (error2) {
|
|
46205
|
+
if (generation !== this.actionGeneration) return this.getStatus();
|
|
46206
|
+
throw error2;
|
|
46207
|
+
}
|
|
46208
|
+
if (generation !== this.actionGeneration) return this.getStatus();
|
|
46209
|
+
return this.start(mode).status;
|
|
46210
|
+
}
|
|
45998
46211
|
start(mode) {
|
|
45999
46212
|
const status = this.getStatus();
|
|
46000
46213
|
if (!status.available) throw new LiveUnavailableError(status);
|
|
@@ -46021,7 +46234,7 @@ var LiveHostCoordinator = class {
|
|
|
46021
46234
|
startCall(mode) {
|
|
46022
46235
|
const call = {
|
|
46023
46236
|
epoch: ++this.nextEpoch,
|
|
46024
|
-
callId:
|
|
46237
|
+
callId: randomUUID11(),
|
|
46025
46238
|
mode,
|
|
46026
46239
|
state: "starting",
|
|
46027
46240
|
pendingPermission: false,
|
|
@@ -46046,6 +46259,7 @@ var LiveHostCoordinator = class {
|
|
|
46046
46259
|
return { epoch: call.epoch, callId: call.callId, status: this.getStatus() };
|
|
46047
46260
|
}
|
|
46048
46261
|
stop() {
|
|
46262
|
+
++this.actionGeneration;
|
|
46049
46263
|
this.pendingStartMode = void 0;
|
|
46050
46264
|
if (this.call) this.beginCallStop(this.call);
|
|
46051
46265
|
return this.getStatus();
|
|
@@ -46080,7 +46294,7 @@ var LiveHostCoordinator = class {
|
|
|
46080
46294
|
new Error("Qwen Live Host must be connected to change the shortcut.")
|
|
46081
46295
|
);
|
|
46082
46296
|
}
|
|
46083
|
-
const requestId =
|
|
46297
|
+
const requestId = randomUUID11();
|
|
46084
46298
|
return new Promise((resolve7, reject) => {
|
|
46085
46299
|
const timer = setTimeout(() => {
|
|
46086
46300
|
this.rejectPendingShortcut(
|
|
@@ -46170,7 +46384,7 @@ var LiveHostCoordinator = class {
|
|
|
46170
46384
|
)
|
|
46171
46385
|
);
|
|
46172
46386
|
}
|
|
46173
|
-
const requestId =
|
|
46387
|
+
const requestId = randomUUID11();
|
|
46174
46388
|
return new Promise((resolve7, reject) => {
|
|
46175
46389
|
const timer = setTimeout(() => {
|
|
46176
46390
|
this.pendingAppshots.delete(requestId);
|
|
@@ -46235,6 +46449,7 @@ var LiveHostCoordinator = class {
|
|
|
46235
46449
|
this.sendHost({ type: "host.clear_output", epoch });
|
|
46236
46450
|
}
|
|
46237
46451
|
dispose() {
|
|
46452
|
+
++this.actionGeneration;
|
|
46238
46453
|
this.pendingStartMode = void 0;
|
|
46239
46454
|
if (this.call) this.finishCall(this.call);
|
|
46240
46455
|
if (this.host) {
|
|
@@ -46459,19 +46674,14 @@ var LiveHostCoordinator = class {
|
|
|
46459
46674
|
}
|
|
46460
46675
|
}
|
|
46461
46676
|
startFromHost(mode) {
|
|
46462
|
-
|
|
46463
|
-
this.start(mode);
|
|
46464
|
-
} catch (error2) {
|
|
46677
|
+
void this.requestStart(mode).catch((error2) => {
|
|
46465
46678
|
if (error2 instanceof LiveUnavailableError) {
|
|
46466
46679
|
this.sendState(error2.status);
|
|
46467
46680
|
return;
|
|
46468
46681
|
}
|
|
46469
|
-
this.
|
|
46470
|
-
|
|
46471
|
-
|
|
46472
|
-
message: "Live Voice failed to start."
|
|
46473
|
-
});
|
|
46474
|
-
}
|
|
46682
|
+
this.lastCallError = error2 instanceof ConversationRuntimeOwnershipError ? error2.message : "Live Voice failed to start.";
|
|
46683
|
+
this.sendState(this.buildStatus(false));
|
|
46684
|
+
});
|
|
46475
46685
|
}
|
|
46476
46686
|
handleAudioFrame(lease, data) {
|
|
46477
46687
|
if (!lease.hello) {
|
|
@@ -46513,7 +46723,7 @@ var LiveHostCoordinator = class {
|
|
|
46513
46723
|
this.disconnectHost(lease, 4008, "Live Host heartbeat timed out.");
|
|
46514
46724
|
return;
|
|
46515
46725
|
}
|
|
46516
|
-
const pingId =
|
|
46726
|
+
const pingId = randomUUID11();
|
|
46517
46727
|
lease.pingId = pingId;
|
|
46518
46728
|
this.sendHost({ type: "host.ping", pingId });
|
|
46519
46729
|
}
|
|
@@ -46598,9 +46808,10 @@ var LiveHostCoordinator = class {
|
|
|
46598
46808
|
this.broadcastState();
|
|
46599
46809
|
}
|
|
46600
46810
|
stopForReadinessLoss() {
|
|
46811
|
+
++this.actionGeneration;
|
|
46812
|
+
this.pendingStartMode = void 0;
|
|
46601
46813
|
const call = this.call;
|
|
46602
46814
|
if (!call) return;
|
|
46603
|
-
this.pendingStartMode = void 0;
|
|
46604
46815
|
this.beginCallStop(call);
|
|
46605
46816
|
}
|
|
46606
46817
|
disconnectHost(lease, code, reason) {
|
|
@@ -46694,8 +46905,7 @@ function registerLiveRoutes(app, deps) {
|
|
|
46694
46905
|
});
|
|
46695
46906
|
app.post("/live/start", deps.mutate(), async (_req, res) => {
|
|
46696
46907
|
try {
|
|
46697
|
-
await deps.
|
|
46698
|
-
res.status(200).json(deps.coordinator.start("resume").status);
|
|
46908
|
+
res.status(200).json(await deps.coordinator.requestStart("resume"));
|
|
46699
46909
|
} catch (error2) {
|
|
46700
46910
|
if (sendUnavailable(res, error2)) return;
|
|
46701
46911
|
throw error2;
|
|
@@ -46703,8 +46913,7 @@ function registerLiveRoutes(app, deps) {
|
|
|
46703
46913
|
});
|
|
46704
46914
|
app.post("/live/new", deps.mutate(), async (_req, res) => {
|
|
46705
46915
|
try {
|
|
46706
|
-
await deps.
|
|
46707
|
-
res.status(200).json(deps.coordinator.start("new").status);
|
|
46916
|
+
res.status(200).json(await deps.coordinator.requestStart("new"));
|
|
46708
46917
|
} catch (error2) {
|
|
46709
46918
|
if (sendUnavailable(res, error2)) return;
|
|
46710
46919
|
throw error2;
|
|
@@ -46781,7 +46990,7 @@ init_esbuild_shims();
|
|
|
46781
46990
|
|
|
46782
46991
|
// packages/cli/src/serve/live/live-setup-controller.ts
|
|
46783
46992
|
init_esbuild_shims();
|
|
46784
|
-
import { randomUUID as
|
|
46993
|
+
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
46785
46994
|
|
|
46786
46995
|
// packages/cli/src/serve/live/provider-credentials.ts
|
|
46787
46996
|
init_esbuild_shims();
|
|
@@ -46879,7 +47088,7 @@ __name(resolveLiveProviderCredential, "resolveLiveProviderCredential");
|
|
|
46879
47088
|
|
|
46880
47089
|
// packages/cli/src/serve/live/qwen-realtime-session.ts
|
|
46881
47090
|
init_esbuild_shims();
|
|
46882
|
-
import { randomUUID as
|
|
47091
|
+
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
46883
47092
|
var QWEN_REALTIME_LIMITS = {
|
|
46884
47093
|
maxInputAudioFrameBytes: 64 * 1024,
|
|
46885
47094
|
maxOutputAudioFrameBytes: 256 * 1024,
|
|
@@ -47294,7 +47503,7 @@ function openQwenRealtimeSession(config, callbacks = {}, deps = {}) {
|
|
|
47294
47503
|
const sendJson = /* @__PURE__ */ __name((body) => {
|
|
47295
47504
|
if (terminal || closedByClient || ws.readyState !== ws.OPEN) return false;
|
|
47296
47505
|
try {
|
|
47297
|
-
ws.send(JSON.stringify({ event_id:
|
|
47506
|
+
ws.send(JSON.stringify({ event_id: randomUUID12(), ...body }));
|
|
47298
47507
|
return true;
|
|
47299
47508
|
} catch (error2) {
|
|
47300
47509
|
fail(
|
|
@@ -48657,7 +48866,7 @@ async function validateCredential(credential) {
|
|
|
48657
48866
|
apiKey: credential.apiKey,
|
|
48658
48867
|
model: credential.realtimeModel,
|
|
48659
48868
|
voice: credential.voice,
|
|
48660
|
-
callEpoch: `setup-${
|
|
48869
|
+
callEpoch: `setup-${randomUUID13()}`
|
|
48661
48870
|
});
|
|
48662
48871
|
session.close({ discardPendingInput: true });
|
|
48663
48872
|
}
|
|
@@ -48964,11 +49173,11 @@ __name(registerLiveSetupRoutes, "registerLiveSetupRoutes");
|
|
|
48964
49173
|
// packages/cli/src/serve/live/live-host-installer.ts
|
|
48965
49174
|
init_esbuild_shims();
|
|
48966
49175
|
import { execFile as execFile2 } from "node:child_process";
|
|
48967
|
-
import { createHash as createHash4, randomUUID as
|
|
48968
|
-
import * as
|
|
49176
|
+
import { createHash as createHash4, randomUUID as randomUUID14 } from "node:crypto";
|
|
49177
|
+
import * as fs8 from "node:fs";
|
|
48969
49178
|
import * as fsp5 from "node:fs/promises";
|
|
48970
49179
|
import * as os2 from "node:os";
|
|
48971
|
-
import * as
|
|
49180
|
+
import * as path16 from "node:path";
|
|
48972
49181
|
import { Readable, Transform } from "node:stream";
|
|
48973
49182
|
import { pipeline } from "node:stream/promises";
|
|
48974
49183
|
import { promisify as promisify2 } from "node:util";
|
|
@@ -49048,7 +49257,7 @@ async function readBundleValue(appPath, key) {
|
|
|
49048
49257
|
"raw",
|
|
49049
49258
|
"-o",
|
|
49050
49259
|
"-",
|
|
49051
|
-
|
|
49260
|
+
path16.join(appPath, "Contents", "Info.plist")
|
|
49052
49261
|
]);
|
|
49053
49262
|
}
|
|
49054
49263
|
__name(readBundleValue, "readBundleValue");
|
|
@@ -49156,7 +49365,7 @@ async function downloadAsset(asset, url, destination, onProgress, fetchImpl) {
|
|
|
49156
49365
|
await pipeline(
|
|
49157
49366
|
Readable.fromWeb(response.body),
|
|
49158
49367
|
guard,
|
|
49159
|
-
|
|
49368
|
+
fs8.createWriteStream(destination, { flags: "wx", mode: 384 })
|
|
49160
49369
|
);
|
|
49161
49370
|
if (received !== asset.size || hash.digest("hex") !== asset.sha256) {
|
|
49162
49371
|
throw new Error("Live Host checksum verification failed.");
|
|
@@ -49190,13 +49399,13 @@ async function downloadLiveHostRelease(currentArchitecture, destination, onProgr
|
|
|
49190
49399
|
__name(downloadLiveHostRelease, "downloadLiveHostRelease");
|
|
49191
49400
|
async function installLatestHost(currentArchitecture, onStatus) {
|
|
49192
49401
|
const temporaryDirectory = await fsp5.mkdtemp(
|
|
49193
|
-
|
|
49402
|
+
path16.join(os2.tmpdir(), "qwen-live-host-")
|
|
49194
49403
|
);
|
|
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-${
|
|
49404
|
+
const archivePath = path16.join(temporaryDirectory, "Qwen-Live-Host.zip");
|
|
49405
|
+
const extractedPath = path16.join(temporaryDirectory, "extracted");
|
|
49406
|
+
const candidatePath = path16.join(extractedPath, LIVE_HOST_APP_NAME);
|
|
49407
|
+
const stagingPath = `/Applications/.Qwen Live Host.install-${randomUUID14()}.app`;
|
|
49408
|
+
const backupPath = `/Applications/.Qwen Live Host.backup-${randomUUID14()}.app`;
|
|
49200
49409
|
let movedExisting = false;
|
|
49201
49410
|
let installedCandidate = false;
|
|
49202
49411
|
try {
|
|
@@ -49347,15 +49556,15 @@ var LiveHostInstaller = class {
|
|
|
49347
49556
|
|
|
49348
49557
|
// packages/cli/src/serve/live/live-session-coordinator.ts
|
|
49349
49558
|
init_esbuild_shims();
|
|
49350
|
-
import { createHash as createHash5, randomUUID as
|
|
49559
|
+
import { createHash as createHash5, randomUUID as randomUUID15 } from "node:crypto";
|
|
49351
49560
|
import { createWriteStream as createWriteStream2, mkdirSync as mkdirSync2 } from "node:fs";
|
|
49352
|
-
import { join as
|
|
49561
|
+
import { join as join14 } from "node:path";
|
|
49353
49562
|
|
|
49354
49563
|
// packages/cli/src/serve/live/realtime-startup-context.ts
|
|
49355
49564
|
init_esbuild_shims();
|
|
49356
49565
|
import { readdirSync } from "node:fs";
|
|
49357
49566
|
import { homedir } from "node:os";
|
|
49358
|
-
import { basename as basename8, join as
|
|
49567
|
+
import { basename as basename8, join as join13 } from "node:path";
|
|
49359
49568
|
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
49569
|
var CURRENT_THREAD_SECTION_TOKEN_BUDGET = 1200;
|
|
49361
49570
|
var RECENT_WORK_SECTION_TOKEN_BUDGET = 2200;
|
|
@@ -49597,7 +49806,7 @@ function collectTreeLines(directory, depth, lines) {
|
|
|
49597
49806
|
const indent = " ".repeat(depth);
|
|
49598
49807
|
lines.push(`${indent}- ${entry.name}${entry.isDirectory() ? "/" : ""}`);
|
|
49599
49808
|
if (entry.isDirectory()) {
|
|
49600
|
-
collectTreeLines(
|
|
49809
|
+
collectTreeLines(join13(directory, entry.name), depth + 1, lines);
|
|
49601
49810
|
}
|
|
49602
49811
|
}
|
|
49603
49812
|
if (entries.length > DIR_ENTRY_LIMIT) {
|
|
@@ -49716,7 +49925,7 @@ function openLiveAudioCapture(source, identifier) {
|
|
|
49716
49925
|
try {
|
|
49717
49926
|
mkdirSync2(directory, { recursive: true, mode: 448 });
|
|
49718
49927
|
const safeIdentifier = identifier.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
49719
|
-
const path19 =
|
|
49928
|
+
const path19 = join14(
|
|
49720
49929
|
directory,
|
|
49721
49930
|
`${source}-${Date.now()}-${safeIdentifier}.pcm`
|
|
49722
49931
|
);
|
|
@@ -50077,7 +50286,7 @@ var LiveSessionCoordinator = class {
|
|
|
50077
50286
|
context.speechInProgress = true;
|
|
50078
50287
|
context.inputCommitPending = true;
|
|
50079
50288
|
context.inputAwaitingResponse = false;
|
|
50080
|
-
const partialItemId = itemId ?? `partial:${
|
|
50289
|
+
const partialItemId = itemId ?? `partial:${randomUUID15()}`;
|
|
50081
50290
|
context.activePartialInputItemId = partialItemId;
|
|
50082
50291
|
if (!context.partialInputTranscripts.has(partialItemId)) {
|
|
50083
50292
|
context.partialInputTranscripts.set(partialItemId, "");
|
|
@@ -50107,7 +50316,7 @@ var LiveSessionCoordinator = class {
|
|
|
50107
50316
|
}, "onInputCommitted"),
|
|
50108
50317
|
onInputTranscriptDelta: /* @__PURE__ */ __name(({ itemId, text }) => {
|
|
50109
50318
|
if (this.isCurrentSocket(context, generation)) {
|
|
50110
|
-
const partialItemId = itemId ?? context.activePartialInputItemId ?? `partial:${
|
|
50319
|
+
const partialItemId = itemId ?? context.activePartialInputItemId ?? `partial:${randomUUID15()}`;
|
|
50111
50320
|
context.activePartialInputItemId = partialItemId;
|
|
50112
50321
|
context.partialInputTranscripts.set(partialItemId, text);
|
|
50113
50322
|
this.options.host.setTranscript?.(context.epoch, text);
|
|
@@ -50117,7 +50326,7 @@ var LiveSessionCoordinator = class {
|
|
|
50117
50326
|
if (this.isCurrentSocket(context, generation)) {
|
|
50118
50327
|
context.speechInProgress = false;
|
|
50119
50328
|
context.inputCommitPending = false;
|
|
50120
|
-
const completedItemId = itemId ?? context.activePartialInputItemId ?? `unattributed:${
|
|
50329
|
+
const completedItemId = itemId ?? context.activePartialInputItemId ?? `unattributed:${randomUUID15()}`;
|
|
50121
50330
|
context.partialInputTranscripts.delete(completedItemId);
|
|
50122
50331
|
if (context.activePartialInputItemId === completedItemId) {
|
|
50123
50332
|
context.activePartialInputItemId = void 0;
|
|
@@ -50849,7 +51058,7 @@ var LiveSessionCoordinator = class {
|
|
|
50849
51058
|
const runtime = context.runtime;
|
|
50850
51059
|
if (!runtime) throw new Error("Conversation workspace is unavailable.");
|
|
50851
51060
|
const bridge = runtime.bridge;
|
|
50852
|
-
const promptId =
|
|
51061
|
+
const promptId = randomUUID15();
|
|
50853
51062
|
const lastEventId = bridge.getSessionLastEventId(locator.sessionId);
|
|
50854
51063
|
const turnAbort = new AbortController();
|
|
50855
51064
|
this.inFlightTurnAborts.add(turnAbort);
|
|
@@ -51012,9 +51221,12 @@ var LiveSessionCoordinator = class {
|
|
|
51012
51221
|
if (update?.["sessionUpdate"] === "agent_message_chunk") {
|
|
51013
51222
|
const source = updateSource(update);
|
|
51014
51223
|
if (source === "background_notification") {
|
|
51015
|
-
|
|
51224
|
+
const text = updateText(update);
|
|
51225
|
+
announcement = announcement ? appendBounded(announcement, `
|
|
51226
|
+
${text}`) : text;
|
|
51016
51227
|
response = "";
|
|
51017
|
-
|
|
51228
|
+
const taskId = updateBackgroundTaskId(update);
|
|
51229
|
+
if (taskId !== void 0) backgroundTaskId = taskId;
|
|
51018
51230
|
} else if (source === "background_notification_response") {
|
|
51019
51231
|
response = appendBounded(response, updateText(update));
|
|
51020
51232
|
}
|
|
@@ -51166,7 +51378,7 @@ var LiveSessionCoordinator = class {
|
|
|
51166
51378
|
|
|
51167
51379
|
// packages/cli/src/serve/live/live-task-service.ts
|
|
51168
51380
|
init_esbuild_shims();
|
|
51169
|
-
import { randomUUID as
|
|
51381
|
+
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
51170
51382
|
var DEFAULT_LIST_LIMIT = 20;
|
|
51171
51383
|
var DEFAULT_READ_TURN_LIMIT = 3;
|
|
51172
51384
|
var DEFAULT_WAIT_TIMEOUT_MS = 12e4;
|
|
@@ -51852,7 +52064,7 @@ var LiveTaskService = class {
|
|
|
51852
52064
|
const record = target;
|
|
51853
52065
|
if (record["type"] === "projectless") {
|
|
51854
52066
|
const created = await this.getStandaloneSessionService().createWithInitialPrompt(
|
|
51855
|
-
{ sessionId:
|
|
52067
|
+
{ sessionId: randomUUID16() },
|
|
51856
52068
|
prompt
|
|
51857
52069
|
);
|
|
51858
52070
|
return {
|
|
@@ -51904,7 +52116,7 @@ var LiveTaskService = class {
|
|
|
51904
52116
|
{ sessionId, prompt: [{ type: "text", text: prompt }] },
|
|
51905
52117
|
void 0,
|
|
51906
52118
|
{
|
|
51907
|
-
promptId:
|
|
52119
|
+
promptId: randomUUID16(),
|
|
51908
52120
|
onPromptAdmitted: /* @__PURE__ */ __name(() => {
|
|
51909
52121
|
admitted = true;
|
|
51910
52122
|
onAdmitted?.();
|
|
@@ -52177,7 +52389,7 @@ var ConversationRuntimeManager = class {
|
|
|
52177
52389
|
}
|
|
52178
52390
|
async ensureOnce() {
|
|
52179
52391
|
this.assertNotTerminal();
|
|
52180
|
-
await this.options.
|
|
52392
|
+
if (!this.runtime) await this.options.checkLegacyOwner();
|
|
52181
52393
|
this.assertNotTerminal();
|
|
52182
52394
|
const root = await this.revalidateRoot();
|
|
52183
52395
|
this.assertNotTerminal();
|
|
@@ -52268,6 +52480,226 @@ var ConversationRuntimeManager = class {
|
|
|
52268
52480
|
}
|
|
52269
52481
|
};
|
|
52270
52482
|
|
|
52483
|
+
// packages/cli/src/serve/conversations/conversation-runtime-ownership.ts
|
|
52484
|
+
init_esbuild_shims();
|
|
52485
|
+
import { constants as fsConstants3 } from "node:fs";
|
|
52486
|
+
import * as fs9 from "node:fs/promises";
|
|
52487
|
+
import * as path17 from "node:path";
|
|
52488
|
+
var OWNER_DIRECTORY = "conversations";
|
|
52489
|
+
var OWNER_FILE = "runtime-owner.json";
|
|
52490
|
+
var OWNER_LOCK = ".runtime-owner.lock";
|
|
52491
|
+
var MAX_OWNER_BYTES = 4 * 1024;
|
|
52492
|
+
var NONCE_PATTERN = /^[A-Za-z0-9_-]{16,256}$/;
|
|
52493
|
+
var DEFAULT_HANDOFF_GRACE_MS = 1e3;
|
|
52494
|
+
var UnsafeOwnershipStateError = class extends Error {
|
|
52495
|
+
static {
|
|
52496
|
+
__name(this, "UnsafeOwnershipStateError");
|
|
52497
|
+
}
|
|
52498
|
+
};
|
|
52499
|
+
function getConversationRuntimeOwnerPath(stableBaseDir) {
|
|
52500
|
+
return path17.join(stableBaseDir, OWNER_DIRECTORY, OWNER_FILE);
|
|
52501
|
+
}
|
|
52502
|
+
__name(getConversationRuntimeOwnerPath, "getConversationRuntimeOwnerPath");
|
|
52503
|
+
function processIsAlive(pid) {
|
|
52504
|
+
try {
|
|
52505
|
+
process.kill(pid, 0);
|
|
52506
|
+
return true;
|
|
52507
|
+
} catch (error2) {
|
|
52508
|
+
return error2.code !== "ESRCH";
|
|
52509
|
+
}
|
|
52510
|
+
}
|
|
52511
|
+
__name(processIsAlive, "processIsAlive");
|
|
52512
|
+
function delay2(milliseconds) {
|
|
52513
|
+
return new Promise((resolve7) => {
|
|
52514
|
+
setTimeout(resolve7, milliseconds);
|
|
52515
|
+
});
|
|
52516
|
+
}
|
|
52517
|
+
__name(delay2, "delay");
|
|
52518
|
+
function isMissing2(error2) {
|
|
52519
|
+
return error2.code === "ENOENT";
|
|
52520
|
+
}
|
|
52521
|
+
__name(isMissing2, "isMissing");
|
|
52522
|
+
function assertOwnerRecord(value) {
|
|
52523
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
52524
|
+
throw new UnsafeOwnershipStateError();
|
|
52525
|
+
}
|
|
52526
|
+
const keys = Object.keys(value).sort();
|
|
52527
|
+
if (keys.length !== 3 || keys[0] !== "instanceNonce" || keys[1] !== "pid" || keys[2] !== "version") {
|
|
52528
|
+
throw new UnsafeOwnershipStateError();
|
|
52529
|
+
}
|
|
52530
|
+
const record = value;
|
|
52531
|
+
if (record["version"] !== 1 || !Number.isSafeInteger(record["pid"]) || record["pid"] <= 0 || typeof record["instanceNonce"] !== "string" || !NONCE_PATTERN.test(record["instanceNonce"])) {
|
|
52532
|
+
throw new UnsafeOwnershipStateError();
|
|
52533
|
+
}
|
|
52534
|
+
return {
|
|
52535
|
+
version: 1,
|
|
52536
|
+
pid: record["pid"],
|
|
52537
|
+
instanceNonce: record["instanceNonce"]
|
|
52538
|
+
};
|
|
52539
|
+
}
|
|
52540
|
+
__name(assertOwnerRecord, "assertOwnerRecord");
|
|
52541
|
+
function sameRecord(left, right) {
|
|
52542
|
+
return left.version === right.version && left.pid === right.pid && left.instanceNonce === right.instanceNonce;
|
|
52543
|
+
}
|
|
52544
|
+
__name(sameRecord, "sameRecord");
|
|
52545
|
+
async function inspectDirectory(directory, requirePrivateMode) {
|
|
52546
|
+
const stat3 = await fs9.lstat(directory);
|
|
52547
|
+
if (!stat3.isDirectory() || stat3.isSymbolicLink()) {
|
|
52548
|
+
throw new UnsafeOwnershipStateError();
|
|
52549
|
+
}
|
|
52550
|
+
if (process.platform !== "win32" && (typeof process.getuid === "function" && stat3.uid !== process.getuid() || requirePrivateMode && (stat3.mode & 511) !== 448)) {
|
|
52551
|
+
throw new UnsafeOwnershipStateError();
|
|
52552
|
+
}
|
|
52553
|
+
return { dev: stat3.dev, ino: stat3.ino };
|
|
52554
|
+
}
|
|
52555
|
+
__name(inspectDirectory, "inspectDirectory");
|
|
52556
|
+
async function assertDirectoryIdentity(directory, expected, requirePrivateMode = true) {
|
|
52557
|
+
const current = await inspectDirectory(directory, requirePrivateMode);
|
|
52558
|
+
if (current.dev !== expected.dev || current.ino !== expected.ino) {
|
|
52559
|
+
throw new UnsafeOwnershipStateError();
|
|
52560
|
+
}
|
|
52561
|
+
}
|
|
52562
|
+
__name(assertDirectoryIdentity, "assertDirectoryIdentity");
|
|
52563
|
+
async function assertLockShapeIfPresent(lockPath) {
|
|
52564
|
+
let stat3;
|
|
52565
|
+
try {
|
|
52566
|
+
stat3 = await fs9.lstat(lockPath);
|
|
52567
|
+
} catch (error2) {
|
|
52568
|
+
if (isMissing2(error2)) return;
|
|
52569
|
+
throw error2;
|
|
52570
|
+
}
|
|
52571
|
+
if (!stat3.isDirectory() || stat3.isSymbolicLink() || process.platform !== "win32" && typeof process.getuid === "function" && stat3.uid !== process.getuid()) {
|
|
52572
|
+
throw new UnsafeOwnershipStateError();
|
|
52573
|
+
}
|
|
52574
|
+
}
|
|
52575
|
+
__name(assertLockShapeIfPresent, "assertLockShapeIfPresent");
|
|
52576
|
+
async function readOwnerRecord(ownerPath) {
|
|
52577
|
+
let pathStat;
|
|
52578
|
+
try {
|
|
52579
|
+
pathStat = await fs9.lstat(ownerPath);
|
|
52580
|
+
} catch (error2) {
|
|
52581
|
+
if (isMissing2(error2)) return void 0;
|
|
52582
|
+
throw error2;
|
|
52583
|
+
}
|
|
52584
|
+
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())) {
|
|
52585
|
+
throw new UnsafeOwnershipStateError();
|
|
52586
|
+
}
|
|
52587
|
+
let handle;
|
|
52588
|
+
try {
|
|
52589
|
+
handle = await fs9.open(
|
|
52590
|
+
ownerPath,
|
|
52591
|
+
process.platform === "win32" ? fsConstants3.O_RDONLY : fsConstants3.O_RDONLY | fsConstants3.O_NOFOLLOW
|
|
52592
|
+
);
|
|
52593
|
+
} catch (error2) {
|
|
52594
|
+
if (error2.code === "ELOOP") {
|
|
52595
|
+
throw new UnsafeOwnershipStateError(void 0, { cause: error2 });
|
|
52596
|
+
}
|
|
52597
|
+
throw error2;
|
|
52598
|
+
}
|
|
52599
|
+
try {
|
|
52600
|
+
const handleStat = await handle.stat();
|
|
52601
|
+
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())) {
|
|
52602
|
+
throw new UnsafeOwnershipStateError();
|
|
52603
|
+
}
|
|
52604
|
+
const serialized = await handle.readFile("utf8");
|
|
52605
|
+
let parsed;
|
|
52606
|
+
try {
|
|
52607
|
+
parsed = JSON.parse(serialized);
|
|
52608
|
+
} catch (error2) {
|
|
52609
|
+
throw new UnsafeOwnershipStateError(void 0, { cause: error2 });
|
|
52610
|
+
}
|
|
52611
|
+
return assertOwnerRecord(parsed);
|
|
52612
|
+
} finally {
|
|
52613
|
+
await handle.close();
|
|
52614
|
+
}
|
|
52615
|
+
}
|
|
52616
|
+
__name(readOwnerRecord, "readOwnerRecord");
|
|
52617
|
+
async function syncDirectory(directory) {
|
|
52618
|
+
if (process.platform === "win32") return;
|
|
52619
|
+
const handle = await fs9.open(directory, fsConstants3.O_RDONLY);
|
|
52620
|
+
try {
|
|
52621
|
+
await handle.sync();
|
|
52622
|
+
} finally {
|
|
52623
|
+
await handle.close();
|
|
52624
|
+
}
|
|
52625
|
+
}
|
|
52626
|
+
__name(syncDirectory, "syncDirectory");
|
|
52627
|
+
async function checkLegacyConversationRuntimeOwner(options) {
|
|
52628
|
+
const ownerPath = getConversationRuntimeOwnerPath(options.stableBaseDir);
|
|
52629
|
+
const directory = path17.dirname(ownerPath);
|
|
52630
|
+
const lockPath = path17.join(directory, OWNER_LOCK);
|
|
52631
|
+
let reclaimed = false;
|
|
52632
|
+
try {
|
|
52633
|
+
let base;
|
|
52634
|
+
let identity;
|
|
52635
|
+
try {
|
|
52636
|
+
base = await inspectDirectory(options.stableBaseDir, false);
|
|
52637
|
+
identity = await inspectDirectory(directory, true);
|
|
52638
|
+
} catch (error2) {
|
|
52639
|
+
if (isMissing2(error2)) return;
|
|
52640
|
+
throw error2;
|
|
52641
|
+
}
|
|
52642
|
+
await assertLockShapeIfPresent(lockPath);
|
|
52643
|
+
const lockfile = (await import("./proper-lockfile-3LHWIM44.js")).default;
|
|
52644
|
+
let compromised = false;
|
|
52645
|
+
const release = await lockfile.lock(directory, {
|
|
52646
|
+
realpath: false,
|
|
52647
|
+
lockfilePath: lockPath,
|
|
52648
|
+
stale: 5e3,
|
|
52649
|
+
update: 1e3,
|
|
52650
|
+
retries: { retries: 40, minTimeout: 10, maxTimeout: 50 },
|
|
52651
|
+
...options.lockOptions,
|
|
52652
|
+
onCompromised: /* @__PURE__ */ __name(() => {
|
|
52653
|
+
compromised = true;
|
|
52654
|
+
}, "onCompromised")
|
|
52655
|
+
});
|
|
52656
|
+
let operationError;
|
|
52657
|
+
try {
|
|
52658
|
+
await assertLockShapeIfPresent(lockPath);
|
|
52659
|
+
await assertDirectoryIdentity(options.stableBaseDir, base, false);
|
|
52660
|
+
await assertDirectoryIdentity(directory, identity);
|
|
52661
|
+
const existing = await readOwnerRecord(ownerPath);
|
|
52662
|
+
if (compromised) throw new UnsafeOwnershipStateError();
|
|
52663
|
+
if (existing) {
|
|
52664
|
+
if ((options.isProcessAlive ?? processIsAlive)(existing.pid)) {
|
|
52665
|
+
throw conversationRuntimeInUseError();
|
|
52666
|
+
}
|
|
52667
|
+
const confirmed = await readOwnerRecord(ownerPath);
|
|
52668
|
+
if (!confirmed || !sameRecord(existing, confirmed)) {
|
|
52669
|
+
throw new UnsafeOwnershipStateError();
|
|
52670
|
+
}
|
|
52671
|
+
await assertDirectoryIdentity(options.stableBaseDir, base, false);
|
|
52672
|
+
await assertDirectoryIdentity(directory, identity);
|
|
52673
|
+
if (compromised) throw new UnsafeOwnershipStateError();
|
|
52674
|
+
await fs9.unlink(ownerPath);
|
|
52675
|
+
await syncDirectory(directory);
|
|
52676
|
+
reclaimed = true;
|
|
52677
|
+
}
|
|
52678
|
+
} catch (error2) {
|
|
52679
|
+
operationError = error2;
|
|
52680
|
+
}
|
|
52681
|
+
try {
|
|
52682
|
+
await release();
|
|
52683
|
+
} catch (error2) {
|
|
52684
|
+
throw new UnsafeOwnershipStateError(void 0, { cause: error2 });
|
|
52685
|
+
}
|
|
52686
|
+
if (compromised) throw new UnsafeOwnershipStateError();
|
|
52687
|
+
if (operationError) throw operationError;
|
|
52688
|
+
if (reclaimed) {
|
|
52689
|
+
await (options.wait ?? delay2)(
|
|
52690
|
+
options.handoffGraceMs ?? DEFAULT_HANDOFF_GRACE_MS
|
|
52691
|
+
);
|
|
52692
|
+
}
|
|
52693
|
+
} catch (error2) {
|
|
52694
|
+
if (error2 instanceof ConversationRuntimeOwnershipError) throw error2;
|
|
52695
|
+
if (error2 instanceof UnsafeOwnershipStateError || error2.code === "ECOMPROMISED") {
|
|
52696
|
+
throw conversationRuntimeOwnershipCompromisedError(error2);
|
|
52697
|
+
}
|
|
52698
|
+
throw conversationRuntimeUnavailableError(error2);
|
|
52699
|
+
}
|
|
52700
|
+
}
|
|
52701
|
+
__name(checkLegacyConversationRuntimeOwner, "checkLegacyConversationRuntimeOwner");
|
|
52702
|
+
|
|
52271
52703
|
// packages/cli/src/serve/server.ts
|
|
52272
52704
|
var warnedDefaultTrust = false;
|
|
52273
52705
|
function loadServeChannelWebhookConfigs(sources) {
|
|
@@ -52808,22 +53240,9 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
52808
53240
|
}
|
|
52809
53241
|
}, "getProviderReadiness")
|
|
52810
53242
|
});
|
|
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
|
-
}
|
|
53243
|
+
const stableLiveDiscoveryBaseDir = path18.resolve(
|
|
53244
|
+
deps.liveDiscoveryStableBaseDir ?? getStableLiveDiscoveryBaseDir()
|
|
53245
|
+
);
|
|
52827
53246
|
liveCoordinator.setAppshotReadiness(
|
|
52828
53247
|
liveVoiceEnabled && deps.liveConversationWorkspace ? {
|
|
52829
53248
|
state: "checking",
|
|
@@ -52835,7 +53254,9 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
52835
53254
|
);
|
|
52836
53255
|
let standaloneSessionService;
|
|
52837
53256
|
const conversationRuntimeManager = deps.liveConversationWorkspace ? new ConversationRuntimeManager({
|
|
52838
|
-
|
|
53257
|
+
checkLegacyOwner: deps.checkLegacyConversationOwner ?? (() => checkLegacyConversationRuntimeOwner({
|
|
53258
|
+
stableBaseDir: stableLiveDiscoveryBaseDir
|
|
53259
|
+
})),
|
|
52839
53260
|
workspace: deps.liveConversationWorkspace,
|
|
52840
53261
|
registry: workspaceRegistry,
|
|
52841
53262
|
publishRuntime: /* @__PURE__ */ __name(async (canonicalRoot, validate) => {
|
|
@@ -53119,6 +53540,14 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
53119
53540
|
interruptTaskWaits: /* @__PURE__ */ __name((callerSessionId) => liveTaskService.interruptWait(callerSessionId), "interruptTaskWaits")
|
|
53120
53541
|
});
|
|
53121
53542
|
liveCoordinator.setHandlers({
|
|
53543
|
+
beforeStart: /* @__PURE__ */ __name(async () => {
|
|
53544
|
+
await ensureConversationRuntimeWithLifecycle();
|
|
53545
|
+
await publishLiveVoiceEnabled(true);
|
|
53546
|
+
await assertLiveDiscoveryPublisher(stableLiveDiscoveryBaseDir, {
|
|
53547
|
+
pid: process.pid,
|
|
53548
|
+
instanceNonce: liveCoordinator.daemonInstanceNonce
|
|
53549
|
+
});
|
|
53550
|
+
}, "beforeStart"),
|
|
53122
53551
|
onHostReady: /* @__PURE__ */ __name(() => {
|
|
53123
53552
|
if (!liveVoiceEnabled) return;
|
|
53124
53553
|
void verifyLiveAppshotChannel();
|
|
@@ -53213,14 +53642,17 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
53213
53642
|
);
|
|
53214
53643
|
}
|
|
53215
53644
|
const originAllowlist = new MutableOriginAllowlist(parsedAllowOrigins);
|
|
53216
|
-
app.use(allowOriginCors(originAllowlist));
|
|
53217
|
-
app.use(hostAllowlist(opts.hostname, getPort));
|
|
53218
53645
|
const credentials = new CredentialStore(opts.token);
|
|
53219
53646
|
const authenticate = bearerAuth(credentials);
|
|
53220
53647
|
const rateLimiter = installRateLimiter(app, opts, daemonLog, {
|
|
53221
53648
|
mount: false,
|
|
53222
53649
|
workspaceQualifiedAcpEnabled
|
|
53223
53650
|
});
|
|
53651
|
+
installAccessLogMiddleware(app, daemonLog);
|
|
53652
|
+
app.use(daemonInboundTraceIdCaptureMiddleware);
|
|
53653
|
+
app.use(hostAllowlist(opts.hostname, getPort));
|
|
53654
|
+
installRemoteSelfOriginMiddleware(app, opts.hostname, opts.token);
|
|
53655
|
+
app.use(allowOriginCors(originAllowlist));
|
|
53224
53656
|
const healthRoutes = createHealthRoutes({
|
|
53225
53657
|
opts,
|
|
53226
53658
|
workspaceRegistry,
|
|
@@ -53237,8 +53669,6 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
53237
53669
|
});
|
|
53238
53670
|
healthRoutes.register(app);
|
|
53239
53671
|
}
|
|
53240
|
-
installAccessLogMiddleware(app, daemonLog);
|
|
53241
|
-
app.use(daemonInboundTraceIdCaptureMiddleware);
|
|
53242
53672
|
const webShellDir = opts.serveWebShell !== false ? deps.webShellDir : void 0;
|
|
53243
53673
|
const webShellFrameAncestors = opts.allowOrigins && opts.allowOrigins.length > 0 ? [...parseAllowOriginPatterns(opts.allowOrigins).origins].filter(
|
|
53244
53674
|
(o) => o.startsWith("chrome-extension://") || o.startsWith("moz-extension://")
|
|
@@ -53412,10 +53842,6 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
53412
53842
|
if (liveVoiceSurfaceAvailable) {
|
|
53413
53843
|
registerLiveRoutes(app, {
|
|
53414
53844
|
coordinator: liveCoordinator,
|
|
53415
|
-
ensureRuntimeReady: /* @__PURE__ */ __name(async () => {
|
|
53416
|
-
await ensureConversationRuntimeWithLifecycle();
|
|
53417
|
-
await publishLiveVoiceEnabled(true);
|
|
53418
|
-
}, "ensureRuntimeReady"),
|
|
53419
53845
|
mutate,
|
|
53420
53846
|
...deps.persistSetting ? {
|
|
53421
53847
|
persistShortcut: /* @__PURE__ */ __name(async (shortcut) => {
|