nolo-cli 0.149.0-alpha.1 → 0.151.0-alpha.3
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/{_executeModel-OW3H7ICR.js → _executeModel-T7ANHTUW.js} +134 -91
- package/accountResolver-7RYB4D2P.js +300 -0
- package/action-SXJD5N5R.js +23 -0
- package/{addContentAction-B2DRF7P6.js → addContentAction-ZV774PHH.js} +20 -14
- package/{addDialogAgentAction-2P2FLTLD.js → addDialogAgentAction-A6SMKAGH.js} +26 -22
- package/{agentDeleteCommand-7IDWF6E3.js → agentDeleteCommand-4L5KCKFY.js} +181 -93
- package/{agentEmailCommands-A6XBQZBN.js → agentEmailCommands-2IMMIRO2.js} +132 -112
- package/{agentGrantCommands-M3XFO6EN.js → agentGrantCommands-HOJ3JBBQ.js} +3 -3
- package/agentListCommands-TWFLUYIZ.js +802 -0
- package/{agentMachineCommands-DQPUIMAC.js → agentMachineCommands-KIWXWT6L.js} +58 -62
- package/{agentProviderCommands-YK2BIIXZ.js → agentProviderCommands-HL6MBLCL.js} +149 -2
- package/{agentPullCommand-HF4A42D4.js → agentPullCommand-FA43RBRU.js} +7 -7
- package/agentRecordCommands-727NPCRW.js +154 -0
- package/agentRunCommand-JASIG3FZ.js +183 -0
- package/{agentRunControl-2SKCR4SB.js → agentRunControl-IFM7IGMG.js} +10 -2
- package/{agentRuntimeLocal-AK2QVJHY.js → agentRuntimeLocal-KKSQJMTE.js} +47 -50
- package/{agentSlice-O4RUQUMT.js → agentSlice-SLV57QGU.js} +23 -16
- package/{appDeleteCommands-N3XEVVYC.js → appDeleteCommands-4PL4KYRN.js} +58 -59
- package/{appDeployCommands-AWFIXYVW.js → appDeployCommands-EEEXCEB6.js} +67 -63
- package/{appDeployStatusCommands-CZRON2FO.js → appDeployStatusCommands-35ZX7T66.js} +56 -56
- package/{appGetCommands-XQIUY4TD.js → appGetCommands-WFCHXJWF.js} +56 -56
- package/{appListCommands-NNG4H36Y.js → appListCommands-XY2U6DPF.js} +57 -59
- package/{authCommand-UBJ4EWYZ.js → authCommand-QYN47CQD.js} +371 -68
- package/{authCommands-H6WKKCRW.js → authCommands-77CHYBGF.js} +12 -9
- package/{builtinSkillRegistry-ZMF6YGNO.js → builtinSkillRegistry-TDQ6JB2E.js} +13 -11
- package/{chromeCommands-2N6MEWRU.js → chromeCommands-OBBNJCLS.js} +314 -13
- package/chromeOpsCommands-3Z34RKSE.js +472 -0
- package/{chunk-ALXHV7NK.js → chunk-2GGXHQIW.js} +43 -4
- package/{localRuntimeAuthority-5W6IJRAD.js → chunk-2IXDJNZI.js} +154 -75
- package/{chunk-IVZJWTDI.js → chunk-36OMEXXR.js} +89 -21
- package/{chunk-H6A6X4EK.js → chunk-3MZAGMYY.js} +16 -0
- package/chunk-3PVYUPXK.js +40 -0
- package/chunk-3SZA4U64.js +1192 -0
- package/{chunk-ID7LNBWR.js → chunk-3T4ZG6AC.js} +1920 -644
- package/{chunk-GNMAFAIS.js → chunk-44WXLHFI.js} +1 -1
- package/{chunk-AGGIDPCZ.js → chunk-4JH2UMJR.js} +6 -0
- package/chunk-4LCOCOR5.js +50 -0
- package/chunk-4YRTZIVN.js +871 -0
- package/{chunk-N7J63Q6C.js → chunk-56GBUMO5.js} +10 -1
- package/{chunk-W7XHHYWM.js → chunk-5BHQICF2.js} +5 -1
- package/{chunk-XUWRURDF.js → chunk-5EBLANFT.js} +1 -1
- package/{chunk-3AH7LNUB.js → chunk-5EMSBTQ6.js} +33 -14
- package/{chunk-YRRASA5Q.js → chunk-5MM7NNO6.js} +113 -52
- package/chunk-5MMAK75Q.js +15 -0
- package/{chunk-TXH4IWJL.js → chunk-626KHJNX.js} +20 -11
- package/{chunk-M5PVFLD4.js → chunk-64K7WX26.js} +90 -21
- package/{chunk-AKG5W4LG.js → chunk-6CCFTVBP.js} +76 -221
- package/chunk-6MJNEXUU.js +614 -0
- package/{chunk-62IL3KQV.js → chunk-6MXDOUMH.js} +15 -3
- package/{chunk-QOKAKDPE.js → chunk-6Q7UTJKR.js} +6 -94
- package/chunk-6QDYSCPW.js +223 -0
- package/{chunk-HYZIYH2H.js → chunk-74RAWNQN.js} +56 -63
- package/chunk-7DPNBQSV.js +9 -0
- package/{chunk-IAESIMK7.js → chunk-A4MW3YZL.js} +10 -14
- package/{chunk-OMRJYNCI.js → chunk-AG7MCDLR.js} +26 -31
- package/chunk-AGIM7IMJ.js +147 -0
- package/{chunk-7CHC4W22.js → chunk-AIZE5TDM.js} +3 -3
- package/chunk-AJ3G7X2K.js +7012 -0
- package/{chunk-5GVBDNTO.js → chunk-AU7AXHUL.js} +1 -1
- package/{chunk-4H22P2JV.js → chunk-AUIJZACN.js} +2073 -1275
- package/{chunk-CIF4X6ZM.js → chunk-AWVFQMOV.js} +25 -3
- package/{chunk-YAQJJDC2.js → chunk-BJEZC5RA.js} +214 -51
- package/{chunk-RYZINGPM.js → chunk-BPMPOFWP.js} +347 -235
- package/{chunk-YUNJN43V.js → chunk-BU2YQBV4.js} +215 -28
- package/{chunk-XPRWFQQK.js → chunk-CBHGZRCE.js} +38 -12
- package/{chunk-Y3PMXGLH.js → chunk-CHCS6XPJ.js} +365 -144
- package/chunk-CHOZJMJS.js +78 -0
- package/chunk-CYJWI3NH.js +119 -0
- package/{chunk-GBRG75BQ.js → chunk-D2MDMY2M.js} +1 -0
- package/{chunk-3SV7RM24.js → chunk-D2QN6CTI.js} +117 -72
- package/{chunk-TZZ2WRBL.js → chunk-DFDXM2Y4.js} +20 -16
- package/{chunk-5TEEECZM.js → chunk-E2AKSW7L.js} +10 -7
- package/{chunk-RSEEDUMS.js → chunk-EDX5XSJM.js} +2 -2
- package/{chunk-QDSINZM3.js → chunk-EUGTFFO6.js} +2 -23
- package/{chunk-UNYJU5L6.js → chunk-EYLGAEB4.js} +5 -1
- package/{chunk-CU3QB4HW.js → chunk-EYWJT7A2.js} +12 -12
- package/{chunk-BNGW5ASC.js → chunk-EZVK3N5L.js} +66 -18
- package/{chunk-6FGTMQCL.js → chunk-F32Z66T4.js} +6 -10
- package/{chunk-ZOVKKMF6.js → chunk-FY4SDK2E.js} +1 -1
- package/chunk-G6OOUQWJ.js +417 -0
- package/{chunk-PQWU42UQ.js → chunk-GCKHQECX.js} +6 -6
- package/chunk-GKXCHNTE.js +15 -0
- package/{chunk-P6GMCCAT.js → chunk-GQV5KHJU.js} +78 -12
- package/{chunk-B2XUQXQX.js → chunk-HIQ4GF53.js} +191 -68
- package/{chunk-GMZLP5DV.js → chunk-HNUWUO75.js} +30 -19
- package/{chunk-UASIEDKM.js → chunk-I2XLRXVX.js} +36 -31
- package/{chunk-5UTFL4QJ.js → chunk-I2ZMGXXF.js} +10 -5
- package/chunk-I42VC5KR.js +15 -0
- package/{chunk-3BXNTXYI.js → chunk-I4SN4NUQ.js} +1199 -56
- package/chunk-IA7TRNNR.js +11 -0
- package/{chunk-WIWM4FE3.js → chunk-IJERIUXS.js} +55 -748
- package/{chunk-BIDGLJQ3.js → chunk-IK2TSJQA.js} +45 -8
- package/{chunk-CPUFH46E.js → chunk-ILU2NPWY.js} +10 -10
- package/{chunk-SLLGJZDT.js → chunk-ISQL4V7C.js} +4 -4
- package/chunk-IT3ZZRJE.js +12 -0
- package/{chunk-DY7ANLKG.js → chunk-JKMLSTZK.js} +43 -12
- package/{chunk-6TPOEJMQ.js → chunk-JZX2XLKC.js} +64 -23
- package/{chunk-27ONFIEY.js → chunk-K2AER7RX.js} +19 -12
- package/{chunk-O2OWEFII.js → chunk-KFHQQ3NO.js} +1 -1
- package/{chunk-QXGPFY6J.js → chunk-LGN377P3.js} +27 -17
- package/{chunk-L36OWPP3.js → chunk-LIQJTQRN.js} +118 -139
- package/{chunk-BFU6C242.js → chunk-NMFV26UG.js} +1 -1
- package/{chunk-5J3PYNUP.js → chunk-NYYFIKHI.js} +17 -3
- package/{chunk-6O4IK4V2.js → chunk-OFFL4DCR.js} +1 -1
- package/{chunk-B6SAMB33.js → chunk-OWYYDMGJ.js} +209 -9
- package/{chunk-KQHGZWSV.js → chunk-OXME3PEE.js} +1 -1
- package/{chunk-CTUQJVQM.js → chunk-P5QACQDK.js} +1 -1
- package/{chunk-TB3MIBRC.js → chunk-PIDUNDFS.js} +572 -430
- package/{chunk-4JMDLJAD.js → chunk-PJNFNEJE.js} +114 -37
- package/chunk-PKZKOVA5.js +11507 -0
- package/{chunk-Z4CSIXYP.js → chunk-PLSVXHSA.js} +3 -3
- package/chunk-PWTNI4N7.js +47 -0
- package/chunk-QFEW2ULV.js +42 -0
- package/{chunk-RGNEEJ3Y.js → chunk-QLQ573SU.js} +35 -9
- package/chunk-QQ56R7KS.js +88 -0
- package/chunk-QYPE3TS3.js +43 -0
- package/{chunk-HTVYCXBP.js → chunk-RN2GPWN6.js} +354 -120
- package/{chunk-ATLTFRYJ.js → chunk-ROCUB2H2.js} +280 -98
- package/{chunk-4DPP773Q.js → chunk-RSHPU4PD.js} +59 -11
- package/chunk-RVWMAFIT.js +134 -0
- package/{chunk-ESHYE7WU.js → chunk-S73EPYNC.js} +10 -7
- package/{chunk-UQNS32WZ.js → chunk-SCMHQUMK.js} +1 -1
- package/chunk-SW4S4XYB.js +1794 -0
- package/{chunk-ZUEK6A6C.js → chunk-TTH4HOJD.js} +1973 -754
- package/chunk-TY3TIUJK.js +89 -0
- package/{chunk-X2QRZXZH.js → chunk-TYJ5XFEA.js} +4 -4
- package/{chunk-ALFH24P3.js → chunk-TYYRSFBG.js} +197 -155
- package/{chunk-MST6R3E4.js → chunk-U5GPBQDG.js} +34 -22
- package/chunk-U5ICMAFV.js +14110 -0
- package/{chunk-7KVZ5LDQ.js → chunk-UBUH2TCC.js} +18 -4
- package/chunk-UEILX4EV.js +15 -0
- package/chunk-UHTDNB5Y.js +140 -0
- package/{chunk-YYLHWIW6.js → chunk-UKZX3NHN.js} +1 -1
- package/{chunk-OHOVNO7I.js → chunk-UOKFKFPO.js} +6 -3
- package/{chunk-XISEYOGH.js → chunk-USHQX6VT.js} +5 -5
- package/chunk-UUPR3TD7.js +53 -0
- package/{chunk-3DAVPNFT.js → chunk-V4EE3D54.js} +122 -107
- package/{chunk-HDLLCBRF.js → chunk-VEA7H5FG.js} +2 -2
- package/chunk-VHGD6FHV.js +116 -0
- package/chunk-VIWDGTDA.js +8 -0
- package/{chunk-GOH6RW6F.js → chunk-VJXHL6MH.js} +34 -11
- package/{chunk-4XEYAFLY.js → chunk-VL5KOY2C.js} +623 -94
- package/{chunk-EADNWBAZ.js → chunk-VP3BINY7.js} +13 -0
- package/{chunk-DXHL7G2L.js → chunk-VWW6O2TL.js} +274 -93
- package/{chunk-EOARMOVD.js → chunk-W4S6OTSC.js} +6 -3
- package/chunk-WD4XYDYC.js +567 -0
- package/chunk-WJZOQR2J.js +151 -0
- package/{chunk-AUDNYVRC.js → chunk-XETG4RIX.js} +5 -5
- package/{chunk-MX574M24.js → chunk-XI7DGLUK.js} +4 -4
- package/{chunk-3L2WKC3W.js → chunk-XPWGOTBQ.js} +8 -1
- package/chunk-XRUSXPCQ.js +514 -0
- package/{chunk-I4OPU5TK.js → chunk-XS47QOFV.js} +273 -11
- package/{chunk-S5XGT6GB.js → chunk-XZNCX52W.js} +30 -9
- package/{chunk-5OA5HMTL.js → chunk-YLMMECCH.js} +1 -1
- package/{chunk-CFT5HBGW.js → chunk-YVLQXTUB.js} +448 -12
- package/chunk-YVPQATSC.js +709 -0
- package/chunk-ZEZC7IIM.js +126 -0
- package/{chunk-ALGORS6Y.js → chunk-ZF6526IQ.js} +43 -8
- package/chunk-ZIWPQEFU.js +165 -0
- package/chunk-ZRAU6T47.js +56 -0
- package/{cliExecutor-AWYR3T33.js → cliExecutor-BWBF2MTI.js} +4 -3
- package/{clipboardy-BX4NMYHE.js → clipboardy-GCO3GT3I.js} +3 -8
- package/{commandRegistry-2KBOXZQC.js → commandRegistry-NBLZEMCW.js} +183 -107
- package/contentThunks-6AIWNSGO.js +84 -0
- package/{cooldownCommands-ZLEPIB4A.js → cooldownCommands-JFKTYS2D.js} +2 -2
- package/{createAgentAutomationAction-5UGTB26P.js → createAgentAutomationAction-4BUS65DZ.js} +53 -44
- package/createDialogAction-QAIKSCG4.js +76 -0
- package/{createPageAction-CDLDKPRM.js → createPageAction-DXCZ334C.js} +65 -54
- package/cursorProvider-YGGNMVWX.js +6123 -0
- package/{db-VQSAOWAO.js → db-2QOTXYGH.js} +11 -5
- package/{dbSlice-DQ32LYTJ.js → dbSlice-J37OGIXH.js} +19 -13
- package/{deleteFile-NX6QHCWZ.js → deleteFile-6JWDDRVP.js} +10 -6
- package/dialogCommands-YZLSJB6X.js +113 -0
- package/{dialogSlice-N3YB65G5.js → dialogSlice-PVUSMKFW.js} +53 -39
- package/{docCreateCommands-ZSLGVBZT.js → docCreateCommands-JB2RRMRJ.js} +54 -57
- package/{docDeleteCommands-5N4GVZBG.js → docDeleteCommands-AQENULNM.js} +56 -58
- package/{docReadCommands-YJSAA7AV.js → docReadCommands-DYD25YLQ.js} +53 -56
- package/{docStore-E3CEOV5Q.js → docStore-CSEBEMKP.js} +25 -16
- package/{docUpdateCommands-WEMLSW6W.js → docUpdateCommands-3GVS23QL.js} +54 -57
- package/{fetchMessages-67MEFPZR.js → fetchMessages-IIJWQ3HR.js} +5 -4
- package/{getPricing-NMMFT3YI.js → getPricing-FKK3F5EJ.js} +11 -9
- package/{handleSendMessageAction-DQAD5ERJ.js → handleSendMessageAction-G2TLYGC4.js} +422 -118
- package/index.js +11 -7
- package/{lib-FRRS27KN.js → lib-4YTWAGY7.js} +581 -248
- package/{localDialogRead-EBRS242U.js → localDialogRead-FSOMOPDZ.js} +2 -2
- package/localRuntimeAdapter-B4TAYYA7.js +244 -0
- package/localRuntimeAuthority-JDAD7CB6.js +16 -0
- package/{localRuntimeDb-3LRMNLCM.js → localRuntimeDb-CVC62PM5.js} +1 -1
- package/{machineCommands-HAP75VSG.js → machineCommands-6OBFD3XF.js} +503 -161
- package/{machineInfo-66ZFUMLE.js → machineInfo-UKPTZO5Y.js} +2 -2
- package/machineWsRunDispatch-OO7N3O3Y.js +169 -0
- package/{memberThunks-5ZXPR63F.js → memberThunks-66DH6ABQ.js} +25 -18
- package/{models-ZPU5EDF4.js → models-LAS4B2B5.js} +2 -2
- package/package.json +1 -1
- package/{providerPresetApply-DD6NGWW6.js → providerPresetApply-MY66I6NT.js} +10 -10
- package/{providerRegistry-XDRLMYGJ.js → providerRegistry-QOE2FT57.js} +13 -9
- package/{read-EPTJRAEF.js → read-DC4NUGN6.js} +12 -8
- package/{readDocTool-W4NDXNEX.js → readDocTool-NCJ5NT25.js} +1 -1
- package/{readlineWorkspace-7BC66QSX.js → readlineWorkspace-UIQN7JUR.js} +5017 -915
- package/{removeDialogAgentAction-OSYNZRX7.js → removeDialogAgentAction-E2H3OZU6.js} +29 -28
- package/{runAgentClientLoop-6E6UC3CE.js → runAgentClientLoop-GS3SGG37.js} +154 -97
- package/{runtimeDoctorCommands-ID23PNNZ.js → runtimeDoctorCommands-GIOGC5SC.js} +17 -17
- package/secretCommands-ZXZRLR3R.js +700 -0
- package/setDialogExtraReferencesAction-SITRPMYU.js +37 -0
- package/{setPrimaryDialogAgentAction-WZ7KI3YA.js → setPrimaryDialogAgentAction-U7N45TGC.js} +30 -29
- package/{chunk-SONWNI3L.js → settingThunks-Y7SVJOMZ.js} +223 -928
- package/{skillDiscovery-ZBU76COE.js → skillDiscovery-QC35EQY4.js} +2 -2
- package/{slateUtils-RIZES3PV.js → slateUtils-NGV2NMKM.js} +1 -1
- package/{spaceCommands-UJOVU4XI.js → spaceCommands-ZR5BR3GX.js} +59 -59
- package/{streamAgentChatTurn-3UXPYFNX.js → streamAgentChatTurn-4XYC33KE.js} +309 -165
- package/{switchDialogAgentAction-GMR7WN3P.js → switchDialogAgentAction-OMGBD3N2.js} +26 -22
- package/{tableCommands-G7RV3RU3.js → tableCommands-U3QDY4L6.js} +19 -17
- package/{toolApiClient-CVGWM4PN.js → toolApiClient-7WSJJJBV.js} +6 -5
- package/tools-P77EE7Q4.js +124 -0
- package/tuiSummaryLlmCaller-BM3VSTBU.js +130 -0
- package/{updateCommands-4EHDLF5J.js → updateCommands-NQXAGFM7.js} +3 -3
- package/{updateDialogTitleAction-UPFV7TDT.js → updateDialogTitleAction-CIANVPZC.js} +102 -57
- package/workloadLifecycle-36DXRZKU.js +320 -0
- package/action-GI44T4DR.js +0 -31
- package/agentListCommands-IW3GQVUP.js +0 -427
- package/agentRecordCommands-VCA76W6B.js +0 -134
- package/agentRunCommand-YNLDKVR7.js +0 -161
- package/browser-image-compression-MFDTD7K6.js +0 -1763
- package/chatQueueReduxAdapter-TJRMXMYA.js +0 -186
- package/chromeOpsCommands-IXRLN57H.js +0 -289
- package/chunk-36KZDDO5.js +0 -2415
- package/chunk-ACQD6YI2.js +0 -25363
- package/chunk-CQ3WA2NE.js +0 -299
- package/chunk-CYSYR67N.js +0 -93
- package/chunk-JBTJAPUF.js +0 -35
- package/chunk-K2CSUCHJ.js +0 -620
- package/chunk-LTRXGFMS.js +0 -83
- package/chunk-M76ECQRD.js +0 -13658
- package/chunk-MEYIRKDN.js +0 -8967
- package/chunk-OCZKATRC.js +0 -129
- package/chunk-OTGFTBLI.js +0 -13
- package/chunk-PUOC4YRO.js +0 -394
- package/chunk-PZZTFEKK.js +0 -34
- package/chunk-URMS4XY2.js +0 -10
- package/chunk-UV6VISQJ.js +0 -20
- package/chunk-VJVNU77E.js +0 -83
- package/chunk-XYJSY4KG.js +0 -13807
- package/chunk-Y5GCAMGP.js +0 -9
- package/chunk-YPREESF4.js +0 -225
- package/contentThunks-BDIQRZR6.js +0 -73
- package/createDialogAction-B7VGVEVU.js +0 -66
- package/dialogCommands-G7YBVAMC.js +0 -102
- package/levelLazyShim-GZBKODGI.js +0 -7
- package/machineWsRunDispatch-L32G7C4P.js +0 -149
- package/serverStoreFactory-YMXDF4NI.js +0 -20
- package/setDialogExtraReferencesAction-M32UYNCG.js +0 -30
- package/settingSlice-Q6EKL7EQ.js +0 -204
- package/syncMapping-N6RGXGBW.js +0 -437
- package/tools-MKYDMWA4.js +0 -111
- package/tuiSummaryLlmCaller-3YFNHCTW.js +0 -128
- package/{chunk-SV5IJK6K.js → chunk-NBTY7YJF.js} +3 -3
- package/{chunk-2SYTUTLI.js → chunk-YBNHPX4S.js} +3 -3
- package/{offlineMarxistsAgentCommand-HGXZV4XJ.js → offlineMarxistsAgentCommand-2QTHJCHV.js} +4 -4
|
@@ -1,18 +1,407 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isAgentRunTerminalStatus,
|
|
3
3
|
normalizeRunTitle
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PJNFNEJE.js";
|
|
5
|
+
import {
|
|
6
|
+
resolvePlatformAuthToken
|
|
7
|
+
} from "./chunk-K2AER7RX.js";
|
|
5
8
|
import {
|
|
6
9
|
isCompiledBinary,
|
|
7
10
|
resolveCliEntrypointPath
|
|
8
11
|
} from "./chunk-A7GB5UGH.js";
|
|
9
12
|
|
|
13
|
+
// packages/cli/client/originShellApprovalTransport.ts
|
|
14
|
+
import { realpathSync } from "node:fs";
|
|
15
|
+
import { randomUUID } from "node:crypto";
|
|
16
|
+
|
|
17
|
+
// packages/cli/client/originShellApprovalBridge.ts
|
|
18
|
+
import { isAbsolute } from "node:path";
|
|
19
|
+
var IDENTITY_KEYS = ["runId", "agentKey", "ownerUserId", "deviceId", "workspaceRoot"];
|
|
20
|
+
var CALL_KEYS = [...IDENTITY_KEYS, "toolName", "command", "executionPayload"];
|
|
21
|
+
var MAX_REQUESTS_PER_BRIDGE = 256;
|
|
22
|
+
function createOriginShellApprovalBridge(deps) {
|
|
23
|
+
const binding = { ...deps.binding };
|
|
24
|
+
const now = deps.now ?? Date.now;
|
|
25
|
+
const createRequestId = deps.createRequestId ?? (() => crypto.randomUUID());
|
|
26
|
+
const timeoutMs = deps.timeoutMs ?? 6e4;
|
|
27
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > 3e5) {
|
|
28
|
+
throw new Error("Shell approval timeout must be finite, > 0 and <= 300000ms");
|
|
29
|
+
}
|
|
30
|
+
const requests = /* @__PURE__ */ new Map();
|
|
31
|
+
const fail = (reason) => ({ ok: false, reason });
|
|
32
|
+
const snapshot = (request) => ({ ok: true, request: { ...request } });
|
|
33
|
+
const validIdentity = (call) => {
|
|
34
|
+
try {
|
|
35
|
+
return IDENTITY_KEYS.every((key) => typeof call[key] === "string" && call[key].trim().length > 0 && call[key] === binding[key]) && isAbsolute(call.workspaceRoot) && deps.resolveWorkspace(call.workspaceRoot) === binding.workspaceRoot;
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
if (!validIdentity(binding)) throw new Error("Shell approval requires a canonical host binding");
|
|
41
|
+
const timeout = () => {
|
|
42
|
+
const time = now();
|
|
43
|
+
let expired = 0;
|
|
44
|
+
for (const [id, request] of requests) {
|
|
45
|
+
if ((request.state === "pending" || request.state === "approved") && (!Number.isFinite(time) || time < request.createdAt || time >= request.expiresAt)) {
|
|
46
|
+
requests.set(id, { ...request, state: "expired" });
|
|
47
|
+
expired += 1;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return expired;
|
|
51
|
+
};
|
|
52
|
+
const lookup = (id, call) => {
|
|
53
|
+
timeout();
|
|
54
|
+
if (!validIdentity(call)) return fail("identity_mismatch");
|
|
55
|
+
const request = requests.get(id);
|
|
56
|
+
if (!request) return fail("unknown_request");
|
|
57
|
+
if (!CALL_KEYS.every((key) => request[key] === call[key])) return fail("call_mismatch");
|
|
58
|
+
return snapshot(request);
|
|
59
|
+
};
|
|
60
|
+
return {
|
|
61
|
+
request(call) {
|
|
62
|
+
timeout();
|
|
63
|
+
if (!validIdentity(call)) return fail("identity_mismatch");
|
|
64
|
+
if (typeof call.toolName !== "string" || !call.toolName.trim() || typeof call.command !== "string" || !call.command.trim()) return fail("invalid_request");
|
|
65
|
+
if (requests.size >= MAX_REQUESTS_PER_BRIDGE) return fail("capacity");
|
|
66
|
+
const createdAt = now();
|
|
67
|
+
if (!Number.isFinite(createdAt) || !Number.isFinite(createdAt + timeoutMs)) return fail("invalid_request");
|
|
68
|
+
let requestId;
|
|
69
|
+
try {
|
|
70
|
+
requestId = createRequestId();
|
|
71
|
+
} catch {
|
|
72
|
+
return fail("invalid_request");
|
|
73
|
+
}
|
|
74
|
+
if (typeof requestId !== "string" || !requestId.trim() || requests.has(requestId)) return fail("invalid_request");
|
|
75
|
+
const request = {
|
|
76
|
+
...binding,
|
|
77
|
+
toolName: call.toolName,
|
|
78
|
+
command: call.command,
|
|
79
|
+
...call.executionPayload !== void 0 ? { executionPayload: call.executionPayload } : {},
|
|
80
|
+
requestId,
|
|
81
|
+
createdAt,
|
|
82
|
+
expiresAt: createdAt + timeoutMs,
|
|
83
|
+
state: "pending"
|
|
84
|
+
};
|
|
85
|
+
requests.set(requestId, request);
|
|
86
|
+
return snapshot(request);
|
|
87
|
+
},
|
|
88
|
+
decide(id, call, decision) {
|
|
89
|
+
const result = lookup(id, call);
|
|
90
|
+
if (!result.ok) return result;
|
|
91
|
+
if (result.request.state !== "pending") {
|
|
92
|
+
return fail(result.request.state === "approved" ? "invalid_request" : result.request.state);
|
|
93
|
+
}
|
|
94
|
+
if (decision !== "approve" && decision !== "deny") return fail("invalid_request");
|
|
95
|
+
const request = {
|
|
96
|
+
...result.request,
|
|
97
|
+
state: decision === "approve" ? "approved" : "denied"
|
|
98
|
+
};
|
|
99
|
+
requests.set(id, request);
|
|
100
|
+
return snapshot(request);
|
|
101
|
+
},
|
|
102
|
+
revoke() {
|
|
103
|
+
for (const [id, request] of requests) {
|
|
104
|
+
if (request.state === "pending" || request.state === "approved") {
|
|
105
|
+
requests.set(id, { ...request, state: "revoked" });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
timeout,
|
|
110
|
+
consume(id, call) {
|
|
111
|
+
const result = lookup(id, call);
|
|
112
|
+
if (!result.ok) return result;
|
|
113
|
+
if (result.request.state !== "approved") return fail(result.request.state);
|
|
114
|
+
const request = { ...result.request, state: "consumed" };
|
|
115
|
+
requests.set(id, request);
|
|
116
|
+
return snapshot(request);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// packages/cli/client/originShellApprovalTransport.ts
|
|
122
|
+
var KIND = "nolo.shell-approval.v1";
|
|
123
|
+
var MAX = 256;
|
|
124
|
+
var TTL = 6e4;
|
|
125
|
+
var NOTICE = "Executes with this local user's reachable permissions; workspace is NOT a directory sandbox.";
|
|
126
|
+
function payloadCall(payload, binding) {
|
|
127
|
+
if (typeof payload !== "string" || payload.length > 262144) throw new Error("Invalid approval payload");
|
|
128
|
+
const execution = JSON.parse(JSON.parse(payload).binding);
|
|
129
|
+
if (execution.workspaceRoot !== binding.workspaceRoot || typeof execution.input?.command !== "string") {
|
|
130
|
+
throw new Error("Approval binding mismatch");
|
|
131
|
+
}
|
|
132
|
+
return { ...binding, toolName: "execShell", command: execution.input.command, executionPayload: payload };
|
|
133
|
+
}
|
|
134
|
+
function send(channel, message) {
|
|
135
|
+
if (channel.connected === false || !channel.send) throw new Error("Approval channel disconnected");
|
|
136
|
+
channel.send({ kind: KIND, ...message });
|
|
137
|
+
}
|
|
138
|
+
function attachShellApprovalHost(channel, host) {
|
|
139
|
+
const binding = Object.freeze({ ...host.binding });
|
|
140
|
+
const bridge = createOriginShellApprovalBridge({ binding, resolveWorkspace: realpathSync });
|
|
141
|
+
let closed = false;
|
|
142
|
+
let count = 0;
|
|
143
|
+
const active = /* @__PURE__ */ new Set();
|
|
144
|
+
const close = () => {
|
|
145
|
+
if (closed) return;
|
|
146
|
+
closed = true;
|
|
147
|
+
bridge.revoke();
|
|
148
|
+
for (const controller of active) controller.abort();
|
|
149
|
+
active.clear();
|
|
150
|
+
try {
|
|
151
|
+
send(channel, { type: "revoke" });
|
|
152
|
+
} catch {
|
|
153
|
+
}
|
|
154
|
+
channel.removeListener("message", receive);
|
|
155
|
+
channel.removeListener("disconnect", close);
|
|
156
|
+
channel.removeListener("exit", close);
|
|
157
|
+
channel.removeListener("error", close);
|
|
158
|
+
host.signal.removeEventListener("abort", close);
|
|
159
|
+
};
|
|
160
|
+
const receive = (message) => {
|
|
161
|
+
if (closed || message?.kind !== KIND) return;
|
|
162
|
+
if (message.type === "hello") {
|
|
163
|
+
try {
|
|
164
|
+
send(channel, { type: "binding", binding });
|
|
165
|
+
} catch {
|
|
166
|
+
close();
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (message.type !== "request") return;
|
|
171
|
+
if (++count > MAX || typeof message.id !== "string" || message.id.length > 100) {
|
|
172
|
+
close();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const id = message.id;
|
|
176
|
+
void (async () => {
|
|
177
|
+
let controller;
|
|
178
|
+
let timer;
|
|
179
|
+
try {
|
|
180
|
+
if (message.runId !== binding.runId) throw new Error("Wrong run");
|
|
181
|
+
const call = payloadCall(message.payload, binding);
|
|
182
|
+
const pending = bridge.request(call);
|
|
183
|
+
if (!pending.ok) throw new Error("Request refused");
|
|
184
|
+
controller = new AbortController();
|
|
185
|
+
active.add(controller);
|
|
186
|
+
const cancelled = new Promise((resolve2) => {
|
|
187
|
+
controller.signal.addEventListener("abort", () => resolve2(false), { once: true });
|
|
188
|
+
});
|
|
189
|
+
timer = setTimeout(() => controller.abort(), Math.max(0, pending.request.expiresAt - Date.now()));
|
|
190
|
+
const approved = await Promise.race([
|
|
191
|
+
host.confirm({
|
|
192
|
+
...binding,
|
|
193
|
+
toolName: "execShell",
|
|
194
|
+
command: call.command,
|
|
195
|
+
expiresAt: pending.request.expiresAt,
|
|
196
|
+
permissionNotice: NOTICE
|
|
197
|
+
}, controller.signal),
|
|
198
|
+
cancelled
|
|
199
|
+
]);
|
|
200
|
+
if (closed || controller.signal.aborted || approved !== true) throw new Error("Not approved");
|
|
201
|
+
const decided = bridge.decide(pending.request.requestId, call, "approve");
|
|
202
|
+
const consumed = decided.ok && bridge.consume(pending.request.requestId, call);
|
|
203
|
+
if (!consumed || !consumed.ok) throw new Error("Approval expired");
|
|
204
|
+
send(channel, {
|
|
205
|
+
type: "decision",
|
|
206
|
+
id,
|
|
207
|
+
runId: binding.runId,
|
|
208
|
+
approved: true,
|
|
209
|
+
ticket: pending.request.requestId,
|
|
210
|
+
expiresAt: pending.request.expiresAt
|
|
211
|
+
});
|
|
212
|
+
} catch {
|
|
213
|
+
try {
|
|
214
|
+
if (!closed) send(channel, { type: "decision", id, runId: binding.runId, approved: false });
|
|
215
|
+
} catch {
|
|
216
|
+
close();
|
|
217
|
+
}
|
|
218
|
+
} finally {
|
|
219
|
+
if (timer) clearTimeout(timer);
|
|
220
|
+
if (controller) {
|
|
221
|
+
controller.abort();
|
|
222
|
+
active.delete(controller);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
})();
|
|
226
|
+
};
|
|
227
|
+
channel.on("message", receive);
|
|
228
|
+
channel.on("disconnect", close);
|
|
229
|
+
channel.on("exit", close);
|
|
230
|
+
channel.on("error", close);
|
|
231
|
+
host.signal.addEventListener("abort", close, { once: true });
|
|
232
|
+
if (host.signal.aborted) close();
|
|
233
|
+
return close;
|
|
234
|
+
}
|
|
235
|
+
function createShellApprovalChild(channel, timeoutMs = TTL) {
|
|
236
|
+
let closed = false;
|
|
237
|
+
let binding;
|
|
238
|
+
let count = 0;
|
|
239
|
+
const pending = /* @__PURE__ */ new Map();
|
|
240
|
+
const tickets = /* @__PURE__ */ new Map();
|
|
241
|
+
const close = () => {
|
|
242
|
+
if (closed) return;
|
|
243
|
+
closed = true;
|
|
244
|
+
tickets.clear();
|
|
245
|
+
for (const entry of pending.values()) {
|
|
246
|
+
clearTimeout(entry.timer);
|
|
247
|
+
entry.reject(new Error("Shell approval revoked"));
|
|
248
|
+
}
|
|
249
|
+
pending.clear();
|
|
250
|
+
channel.removeListener("message", receive);
|
|
251
|
+
channel.removeListener("disconnect", close);
|
|
252
|
+
};
|
|
253
|
+
const receive = (message) => {
|
|
254
|
+
if (closed || message?.kind !== KIND) return;
|
|
255
|
+
if (message.type === "revoke") {
|
|
256
|
+
close();
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (message.type === "binding") {
|
|
260
|
+
if (binding) {
|
|
261
|
+
close();
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
binding = Object.freeze({ ...message.binding });
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (message.type !== "decision") return;
|
|
268
|
+
const entry = pending.get(message.id);
|
|
269
|
+
if (!entry) return;
|
|
270
|
+
pending.delete(message.id);
|
|
271
|
+
clearTimeout(entry.timer);
|
|
272
|
+
if (!binding || message.runId !== binding.runId || message.approved !== true || typeof message.ticket !== "string" || !Number.isFinite(message.expiresAt) || message.expiresAt <= Date.now() || message.expiresAt > Date.now() + TTL || tickets.has(message.ticket)) {
|
|
273
|
+
entry.reject(new Error("Shell approval denied"));
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
tickets.set(message.ticket, { payload: entry.payload, expiresAt: message.expiresAt });
|
|
277
|
+
entry.resolve(message.ticket);
|
|
278
|
+
};
|
|
279
|
+
channel.on("message", receive);
|
|
280
|
+
channel.on("disconnect", close);
|
|
281
|
+
try {
|
|
282
|
+
send(channel, { type: "hello" });
|
|
283
|
+
} catch {
|
|
284
|
+
close();
|
|
285
|
+
}
|
|
286
|
+
return {
|
|
287
|
+
close,
|
|
288
|
+
authority: {
|
|
289
|
+
async request(payload) {
|
|
290
|
+
if (++count > MAX) throw new Error("Shell approval capacity exceeded");
|
|
291
|
+
const deadline = Date.now() + Math.min(timeoutMs, TTL);
|
|
292
|
+
while (!binding && !closed && Date.now() < deadline) await new Promise((resolve2) => setTimeout(resolve2, 5));
|
|
293
|
+
if (closed || !binding) throw new Error("Shell approval unavailable");
|
|
294
|
+
payloadCall(payload, binding);
|
|
295
|
+
const id = randomUUID();
|
|
296
|
+
return new Promise((resolve2, reject) => {
|
|
297
|
+
const timer = setTimeout(() => {
|
|
298
|
+
pending.delete(id);
|
|
299
|
+
reject(new Error("Shell approval timeout"));
|
|
300
|
+
}, Math.min(timeoutMs, TTL));
|
|
301
|
+
pending.set(id, { payload, resolve: resolve2, reject, timer });
|
|
302
|
+
try {
|
|
303
|
+
send(channel, { type: "request", id, runId: binding.runId, payload });
|
|
304
|
+
} catch {
|
|
305
|
+
close();
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
},
|
|
309
|
+
consume(ticket, payload) {
|
|
310
|
+
const entry = tickets.get(ticket);
|
|
311
|
+
tickets.delete(ticket);
|
|
312
|
+
if (closed || channel.connected === false || !binding || !entry || entry.payload !== payload || entry.expiresAt <= Date.now()) {
|
|
313
|
+
throw new Error("Shell approval invalid or revoked");
|
|
314
|
+
}
|
|
315
|
+
payloadCall(payload, binding);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
10
321
|
// packages/cli/agentRunControl.ts
|
|
11
322
|
import { homedir as nodeHomedir } from "node:os";
|
|
12
|
-
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
323
|
+
import { dirname, isAbsolute as isAbsolute2, join, resolve } from "node:path";
|
|
13
324
|
import * as nodeFs from "node:fs";
|
|
14
325
|
import { execFileSync as nodeExecFileSync, spawn as nodeSpawn } from "node:child_process";
|
|
15
326
|
|
|
327
|
+
// packages/cli/client/localRuntimeHelpers.ts
|
|
328
|
+
var REMOTE_DIALOG_SYNC_TIMEOUT_MS = 1e4;
|
|
329
|
+
var remoteDialogSyncTimeoutMsForTest;
|
|
330
|
+
function setRemoteDialogSyncTimeoutForTest(ms) {
|
|
331
|
+
remoteDialogSyncTimeoutMsForTest = ms;
|
|
332
|
+
}
|
|
333
|
+
function remoteDialogSyncTimeout() {
|
|
334
|
+
return remoteDialogSyncTimeoutMsForTest ?? REMOTE_DIALOG_SYNC_TIMEOUT_MS;
|
|
335
|
+
}
|
|
336
|
+
function resolveRuntimeServerUrl(env) {
|
|
337
|
+
return (env?.NOLO_SERVER_URL || env?.NOLO_SERVER || env?.BASE_URL || "").replace(/\/+$/, "");
|
|
338
|
+
}
|
|
339
|
+
function resolveRuntimeAuthToken(env) {
|
|
340
|
+
return resolvePlatformAuthToken(env ?? {});
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// packages/cli/agentRunResultFile.ts
|
|
344
|
+
function resolveResultServerMeta(input) {
|
|
345
|
+
const serverUrl = resolveRuntimeServerUrl(input.env);
|
|
346
|
+
const authToken = resolveRuntimeAuthToken(input.env);
|
|
347
|
+
const syncEnabled = input.userId !== "local" && Boolean(serverUrl) && Boolean(authToken);
|
|
348
|
+
if (!syncEnabled) {
|
|
349
|
+
return { server: "local", serverSync: "none" };
|
|
350
|
+
}
|
|
351
|
+
return {
|
|
352
|
+
server: serverOriginForDialog(serverUrl),
|
|
353
|
+
serverSync: input.hasSubjectRefs === void 0 ? void 0 : input.hasSubjectRefs ? "awaited" : "best-effort"
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
var resultHeaderMeta = /* @__PURE__ */ new WeakMap();
|
|
357
|
+
function recordRunResultHeaderMeta(result, meta) {
|
|
358
|
+
const clean = {};
|
|
359
|
+
if (meta.model) clean.model = meta.model;
|
|
360
|
+
if (meta.dialogServer) clean.dialogServer = meta.dialogServer;
|
|
361
|
+
if (meta.serverSync) clean.serverSync = meta.serverSync;
|
|
362
|
+
if (Object.keys(clean).length > 0) resultHeaderMeta.set(result, clean);
|
|
363
|
+
}
|
|
364
|
+
function getRunResultHeaderMeta(result) {
|
|
365
|
+
return result && resultHeaderMeta.get(result) || {};
|
|
366
|
+
}
|
|
367
|
+
function serverOriginForDialog(serverUrl) {
|
|
368
|
+
const raw = serverUrl?.trim();
|
|
369
|
+
if (!raw) return "local";
|
|
370
|
+
try {
|
|
371
|
+
return new URL(raw).origin;
|
|
372
|
+
} catch {
|
|
373
|
+
return raw.replace(/\/+$/, "") || "local";
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
function yamlScalar(value) {
|
|
377
|
+
return typeof value === "number" ? String(value) : JSON.stringify(value);
|
|
378
|
+
}
|
|
379
|
+
function buildResultFrontMatter(input) {
|
|
380
|
+
const entries = [
|
|
381
|
+
["runId", input.runId],
|
|
382
|
+
["status", input.status],
|
|
383
|
+
["agentName", input.agentName],
|
|
384
|
+
["model", input.model],
|
|
385
|
+
["startedAt", input.startedAt],
|
|
386
|
+
["endedAt", input.endedAt],
|
|
387
|
+
["durationMs", input.durationMs],
|
|
388
|
+
["toolCallCount", input.toolCallCount],
|
|
389
|
+
["dialogId", input.dialogId],
|
|
390
|
+
["server", input.server],
|
|
391
|
+
["serverSync", input.serverSync],
|
|
392
|
+
["cwd", input.cwd],
|
|
393
|
+
["continuedFrom", input.continuedFrom]
|
|
394
|
+
];
|
|
395
|
+
const lines = entries.filter(([, v]) => v !== void 0 && v !== "").map(([k, v]) => `${k}: ${yamlScalar(v)}`);
|
|
396
|
+
return `---
|
|
397
|
+
${lines.join("\n")}
|
|
398
|
+
---
|
|
399
|
+
`;
|
|
400
|
+
}
|
|
401
|
+
function buildResultFileContent(input, body) {
|
|
402
|
+
return `${buildResultFrontMatter(input)}${body}`;
|
|
403
|
+
}
|
|
404
|
+
|
|
16
405
|
// packages/ai/tools/agent/runFailureClass.ts
|
|
17
406
|
var RATE_LIMIT_PATTERN = /429|rate.?limit|quota|insufficient.?balance|UPSTREAM_402|cooling|冷却/i;
|
|
18
407
|
var PROVIDER_ERROR_PATTERN = /provider|upstream|5\d\d|bad.?gateway|service.?unavailable|overloaded/i;
|
|
@@ -676,6 +1065,7 @@ async function gcRunRecords(deps = {}, options = {}) {
|
|
|
676
1065
|
const runsDirForLegacy = resolveRunsDir(deps.env, deps.homedir);
|
|
677
1066
|
tryUnlinkFile(fs, join(runsDirForLegacy, `${record.runId}.report.md`));
|
|
678
1067
|
tryUnlinkFile(fs, join(runsDirForLegacy, `${record.runId}.report.json`));
|
|
1068
|
+
tryUnlinkFile(fs, record.resultFile ?? join(runsDirForLegacy, `${record.runId}.result.md`));
|
|
679
1069
|
if (!logOk || !msgOk || !queueOk) {
|
|
680
1070
|
failedIds.push(record.runId);
|
|
681
1071
|
continue;
|
|
@@ -716,7 +1106,7 @@ function stripBackgroundFlag(args) {
|
|
|
716
1106
|
function absolutizeSkillArgs(args, baseCwd = process.cwd()) {
|
|
717
1107
|
const result = [];
|
|
718
1108
|
const resolveIfPath = (value) => {
|
|
719
|
-
if (
|
|
1109
|
+
if (isAbsolute2(value)) return value;
|
|
720
1110
|
const looksLikePath = value.includes("/") || value.endsWith(".md");
|
|
721
1111
|
return looksLikePath ? resolve(baseCwd, value) : value;
|
|
722
1112
|
};
|
|
@@ -855,7 +1245,8 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
|
|
|
855
1245
|
...typeof input.parentDialogId === "string" && input.parentDialogId.trim() ? { parentDialogId: input.parentDialogId.trim() } : {},
|
|
856
1246
|
...dodCommands && dodCommands.length > 0 ? { dodCommands } : {},
|
|
857
1247
|
...spawnHead ? { spawnHead } : {},
|
|
858
|
-
...input.ephemeral ? { ephemeral: true } : {}
|
|
1248
|
+
...input.ephemeral ? { ephemeral: true } : {},
|
|
1249
|
+
...typeof input.continuedFrom === "string" && input.continuedFrom.trim() ? { continuedFrom: input.continuedFrom.trim() } : {}
|
|
859
1250
|
};
|
|
860
1251
|
fs.writeFileSync(recordPath, JSON.stringify(record, null, 2));
|
|
861
1252
|
const rawArgsWithQueue = (input.rawArgs ?? []).some(
|
|
@@ -880,8 +1271,17 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
|
|
|
880
1271
|
cwd: input.cwd,
|
|
881
1272
|
env: childEnv,
|
|
882
1273
|
detached: true,
|
|
883
|
-
stdio: ["ignore", logFd, logFd]
|
|
1274
|
+
stdio: deps.shellApprovalHost ? ["ignore", logFd, logFd, "ipc"] : ["ignore", logFd, logFd]
|
|
884
1275
|
});
|
|
1276
|
+
if (deps.shellApprovalHost) {
|
|
1277
|
+
attachShellApprovalHost(proc, { ...deps.shellApprovalHost, binding: {
|
|
1278
|
+
...deps.shellApprovalHost.binding,
|
|
1279
|
+
runId,
|
|
1280
|
+
agentKey: input.agentKey,
|
|
1281
|
+
workspaceRoot: nodeFs.realpathSync(input.cwd ?? process.cwd())
|
|
1282
|
+
} });
|
|
1283
|
+
proc.channel?.unref?.();
|
|
1284
|
+
}
|
|
885
1285
|
proc.unref();
|
|
886
1286
|
if (typeof proc.pid === "number") {
|
|
887
1287
|
const processStartedAt = (deps.getProcessStartTime ?? defaultGetProcessStartTime)(proc.pid);
|
|
@@ -998,17 +1398,37 @@ function transitionRunToTerminal(runId, update, deps = {}, options = {}) {
|
|
|
998
1398
|
}
|
|
999
1399
|
if (typeof update.lastAssistantText === "string" && update.lastAssistantText) {
|
|
1000
1400
|
record2.lastAssistantText = update.lastAssistantText.slice(0, 2e3);
|
|
1001
|
-
}
|
|
1401
|
+
}
|
|
1402
|
+
record2.endedAt = now().toISOString();
|
|
1403
|
+
if (typeof update.lastAssistantText === "string" && update.lastAssistantText) {
|
|
1002
1404
|
try {
|
|
1003
1405
|
const fs = deps.fs ?? nodeFs;
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1406
|
+
const resultFile = join(resolveRunsDir(deps.env, deps.homedir), `${runId}.result.md`);
|
|
1407
|
+
const startedMs = Date.parse(record2.startedAt);
|
|
1408
|
+
const endedMs = Date.parse(record2.endedAt);
|
|
1409
|
+
const content = buildResultFileContent(
|
|
1410
|
+
{
|
|
1411
|
+
runId,
|
|
1412
|
+
status: record2.status,
|
|
1413
|
+
agentName: record2.agentName,
|
|
1414
|
+
model: update.model,
|
|
1415
|
+
startedAt: record2.startedAt,
|
|
1416
|
+
endedAt: record2.endedAt,
|
|
1417
|
+
...Number.isFinite(startedMs) && Number.isFinite(endedMs) ? { durationMs: Math.max(0, endedMs - startedMs) } : {},
|
|
1418
|
+
toolCallCount: record2.toolCallCount,
|
|
1419
|
+
dialogId: record2.dialogId,
|
|
1420
|
+
server: update.dialogServer ?? "local",
|
|
1421
|
+
serverSync: update.serverSync,
|
|
1422
|
+
cwd: record2.cwd,
|
|
1423
|
+
continuedFrom: record2.continuedFrom
|
|
1424
|
+
},
|
|
1425
|
+
update.lastAssistantText
|
|
1426
|
+
);
|
|
1427
|
+
fs.writeFileSync(resultFile, content, "utf8");
|
|
1428
|
+
record2.resultFile = resultFile;
|
|
1008
1429
|
} catch {
|
|
1009
1430
|
}
|
|
1010
1431
|
}
|
|
1011
|
-
record2.endedAt = now().toISOString();
|
|
1012
1432
|
if (typeof update.note === "string" && update.note.trim()) {
|
|
1013
1433
|
record2.note = update.note.trim();
|
|
1014
1434
|
}
|
|
@@ -1059,7 +1479,14 @@ function defaultGetProcessStartTime(pid) {
|
|
|
1059
1479
|
const output = nodeExecFileSync("ps", ["-o", "lstart=", "-p", String(pid)], {
|
|
1060
1480
|
encoding: "utf8",
|
|
1061
1481
|
stdio: ["ignore", "pipe", "ignore"],
|
|
1062
|
-
timeout: 1e3
|
|
1482
|
+
timeout: 1e3,
|
|
1483
|
+
// `ps -o lstart` 的日期串随系统 locale 变化:
|
|
1484
|
+
// LANG=en_US.UTF-8 → "Thu Oct 8 08:54:18 2026"(new Date 可解析)
|
|
1485
|
+
// LANG=zh_CN.UTF-8 → "四 10月 8 08:54:18 2026"(new Date → NaN → null)
|
|
1486
|
+
// 这会让 isPidReused 的结论依赖调用者环境:同一条 run 记录在英文
|
|
1487
|
+
// locale 下被判 pid reused → orphaned,中文 locale 下不判。强制 C
|
|
1488
|
+
// locale 让输出恒为可解析的英文格式,结果与 locale 无关。
|
|
1489
|
+
env: { ...process.env, LC_ALL: "C", LANG: "C" }
|
|
1063
1490
|
}).trim();
|
|
1064
1491
|
if (!output) return null;
|
|
1065
1492
|
const d = new Date(output);
|
|
@@ -1543,6 +1970,15 @@ async function runAgentKillCommand(args, deps) {
|
|
|
1543
1970
|
}
|
|
1544
1971
|
|
|
1545
1972
|
export {
|
|
1973
|
+
createShellApprovalChild,
|
|
1974
|
+
setRemoteDialogSyncTimeoutForTest,
|
|
1975
|
+
remoteDialogSyncTimeout,
|
|
1976
|
+
resolveRuntimeServerUrl,
|
|
1977
|
+
resolveRuntimeAuthToken,
|
|
1978
|
+
resolveResultServerMeta,
|
|
1979
|
+
recordRunResultHeaderMeta,
|
|
1980
|
+
getRunResultHeaderMeta,
|
|
1981
|
+
serverOriginForDialog,
|
|
1546
1982
|
RUN_TERMINAL_STATUSES,
|
|
1547
1983
|
isRunTerminalStatus,
|
|
1548
1984
|
resolveNoloHome,
|