nolo-cli 0.212.0-alpha.1 → 0.222.0-alpha.2

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.
Files changed (263) hide show
  1. package/README.md +3 -2
  2. package/{_executeModel-KE6MBNUJ.js → _executeModel-4GGQQHOB.js} +111 -82
  3. package/{accountResolver-4LKIHEKL.js → accountResolver-EK2S4PWF.js} +6 -6
  4. package/{action-DF5UYSJF.js → action-CK64LS6S.js} +12 -11
  5. package/{addContentAction-N2YC5IL3.js → addContentAction-GDHDOF4U.js} +18 -17
  6. package/{addDialogAgentAction-3NKVQCEC.js → addDialogAgentAction-CAKRU3ZT.js} +21 -20
  7. package/{agentDeleteCommand-NWK7VU4N.js → agentDeleteCommand-BPV2XZL7.js} +128 -119
  8. package/{agentEmailCommands-UZ4DHEX2.js → agentEmailCommands-EJOS75YL.js} +132 -124
  9. package/{agentFavoriteCommands-EDK743YA.js → agentFavoriteCommands-2LKGKSUD.js} +7 -8
  10. package/{agentGrantCommands-RQWK2TEV.js → agentGrantCommands-QQV4N4JW.js} +5 -5
  11. package/{agentListCommands-HE7L2A6L.js → agentListCommands-HIZODBF3.js} +196 -124
  12. package/{agentMachineCommands-6TE4MBMP.js → agentMachineCommands-ZMQ2CY7Y.js} +62 -53
  13. package/{agentProviderCommands-Q5O33MED.js → agentProviderCommands-WKJOAWBP.js} +5 -5
  14. package/{agentPullCommand-6EM3URVK.js → agentPullCommand-XN6ZPBUW.js} +7 -7
  15. package/agentRecordCommands-OMXVDLDX.js +176 -0
  16. package/agentRunCommand-CB34YWMV.js +206 -0
  17. package/{agentRunControl-OI3LOENH.js → agentRunControl-JNONH3RP.js} +30 -15
  18. package/{agentRuntimeLocal-HL526DNQ.js → agentRuntimeLocal-QZPFWMLG.js} +52 -45
  19. package/{agentSlice-TMYP2UEA.js → agentSlice-RD2CDU7T.js} +20 -19
  20. package/{appDeleteCommands-ZERW4AXY.js → appDeleteCommands-QCCFDIEQ.js} +61 -52
  21. package/{appDeployCommands-DUWSMYHL.js → appDeployCommands-V2T7TNMQ.js} +61 -52
  22. package/{appDeployStatusCommands-N2KIE4BF.js → appDeployStatusCommands-6PGH7ZCG.js} +61 -52
  23. package/{appGetCommands-YVR4NPVY.js → appGetCommands-3L7WWJA6.js} +61 -52
  24. package/{appListCommands-JS6HOHZS.js → appListCommands-ENJCK4PO.js} +61 -52
  25. package/{authCommand-FE2C3ZUM.js → authCommand-6V47SYGK.js} +29 -28
  26. package/{authCommands-HV3EAU3V.js → authCommands-GAJ3NIXO.js} +14 -13
  27. package/{builtinSkillRegistry-3YOIGEF6.js → builtinSkillRegistry-2ECA42FC.js} +11 -13
  28. package/{chromeCommands-REEAH4SX.js → chromeCommands-G5UDKVSV.js} +3 -3
  29. package/{chromeOpsCommands-HEN5AX2J.js → chromeOpsCommands-YKX2QX3A.js} +20 -10
  30. package/{chunk-DM6UMOEL.js → chunk-27PCUMJI.js} +2 -2
  31. package/chunk-2CI3ZFWD.js +97 -0
  32. package/{chunk-HIRC32DV.js → chunk-2GJKRKI6.js} +543 -29
  33. package/{chunk-SM3NSZJV.js → chunk-2UCBGYO4.js} +20 -1
  34. package/{chunk-PYRUW7XN.js → chunk-2VUZSVAS.js} +136 -54
  35. package/chunk-2YGBI2XB.js +30 -0
  36. package/chunk-2ZKFCIJJ.js +13 -0
  37. package/{chunk-CJRONOYL.js → chunk-34J5K2YA.js} +19 -75
  38. package/{chunk-LOEO7LRC.js → chunk-3IK6ILVW.js} +4 -1
  39. package/{chunk-CTPXME7U.js → chunk-3LMUPOHG.js} +29 -6
  40. package/chunk-44X52WOJ.js +1621 -0
  41. package/{chunk-6VLJ6YA7.js → chunk-4DESLZTK.js} +9 -9
  42. package/{chunk-MYOH447Z.js → chunk-4JVNURX4.js} +1 -1
  43. package/chunk-5CHGAKRT.js +364 -0
  44. package/{chunk-YDH3FDFQ.js → chunk-5FUN7EG4.js} +1 -1
  45. package/{chunk-LKDF3ATR.js → chunk-5RKUPJYL.js} +1 -1
  46. package/{chunk-ZC3CMUKU.js → chunk-6OVNSQHN.js} +84 -2
  47. package/{chunk-IF45XG7K.js → chunk-6WU5572L.js} +40 -24
  48. package/{chunk-OHNELDTO.js → chunk-7EEZJ6BS.js} +11 -152
  49. package/{chunk-Y6ORVLSS.js → chunk-7ET2U67U.js} +1 -1
  50. package/{chunk-G7MLNNEX.js → chunk-7JLY4WYF.js} +5 -5
  51. package/{chunk-P5L7CXOC.js → chunk-7Z6EW7AH.js} +3 -2
  52. package/{chunk-IIQ6JGRI.js → chunk-AD5EWDFD.js} +2 -2
  53. package/{chunk-WXYLV624.js → chunk-AIHYNKGV.js} +4 -4
  54. package/{chunk-HPFCI4SK.js → chunk-AK5O76CC.js} +3 -3
  55. package/{chunk-Y63ZSOR6.js → chunk-AL3TYDIF.js} +1 -1
  56. package/{chunk-PJNFNEJE.js → chunk-AMEOV5VZ.js} +59 -13
  57. package/chunk-AN74ON4G.js +675 -0
  58. package/{chunk-HRMJUN5J.js → chunk-AQZ6BMRK.js} +1 -1
  59. package/{chunk-CQ46IRNN.js → chunk-B4GOW4MT.js} +445 -201
  60. package/{chunk-4KB6WQUL.js → chunk-BGP2EDFG.js} +1 -1
  61. package/{chunk-NBTY7YJF.js → chunk-BR3GT6MR.js} +1 -0
  62. package/{chunk-7RFNTILS.js → chunk-BUDVRYES.js} +2 -2
  63. package/{chunk-D2MDMY2M.js → chunk-BV3FLP2L.js} +47 -1
  64. package/{chunk-25JZEIXN.js → chunk-C4VAR65S.js} +92 -150
  65. package/{chunk-AVTVGMDY.js → chunk-C4WTX5TU.js} +2 -2
  66. package/{chunk-ZL5RAEEB.js → chunk-CIRB724Q.js} +1 -1
  67. package/{chunk-F6UUQOG6.js → chunk-CKT6QUE2.js} +4 -4
  68. package/{chunk-M6RL5JCD.js → chunk-CMZ3Z5PT.js} +14 -14
  69. package/{secretCommands-4QS3HCA2.js → chunk-D726I5AZ.js} +191 -16
  70. package/{chunk-INSBKSBB.js → chunk-DNKTQ3IN.js} +4 -4
  71. package/chunk-DVQH4BTR.js +1137 -0
  72. package/{chunk-SOHTHFV2.js → chunk-DWX2HEVC.js} +91 -132
  73. package/{chunk-NOMIGOST.js → chunk-EIAI3PPH.js} +116 -124
  74. package/chunk-EUCFKKDM.js +247 -0
  75. package/chunk-EWQ3HGNZ.js +90 -0
  76. package/{chunk-RPQXPZZF.js → chunk-F3GRJO4Z.js} +908 -13
  77. package/{chunk-GSQNH63I.js → chunk-FIYSMXHY.js} +3 -19
  78. package/{chunk-KSTEXKL6.js → chunk-FJ23FZXF.js} +76 -31
  79. package/{chunk-INN4LTAJ.js → chunk-FJK526XH.js} +2 -2
  80. package/chunk-FS2XP5D7.js +142 -0
  81. package/{chunk-QT6PKHYJ.js → chunk-FYF2TONJ.js} +5 -5
  82. package/{chunk-OXME3PEE.js → chunk-GBWGPTA7.js} +2 -1
  83. package/{chunk-RU4SD66C.js → chunk-GYVCJABP.js} +30 -254
  84. package/{chunk-YUXQAVRD.js → chunk-HOCHUZQ7.js} +257 -90
  85. package/{chunk-Y2WUYX4I.js → chunk-HXER7YJF.js} +4 -4
  86. package/chunk-HYIETXA6.js +99 -0
  87. package/{chunk-H2TJUNCH.js → chunk-I4EADJ4P.js} +6 -6
  88. package/{chunk-TCZHTTUU.js → chunk-I7WBYGBP.js} +8 -8
  89. package/{chunk-5RYBGBQH.js → chunk-IILMY4W4.js} +14 -9
  90. package/chunk-JA3ICVJY.js +271 -0
  91. package/{chunk-ZRSNONOB.js → chunk-JWXITTQB.js} +8 -3
  92. package/{chunk-JNKSDZFS.js → chunk-KEN3N2TN.js} +310 -66
  93. package/{chunk-LEC5ALIN.js → chunk-KEPOVMF4.js} +1 -1
  94. package/{chunk-UHJGXRJ4.js → chunk-KQSYAIZR.js} +3 -3
  95. package/{chunk-4VJAC32I.js → chunk-L5I543VB.js} +3 -2
  96. package/chunk-LKA64WH4.js +227 -0
  97. package/{chunk-6OQUPIQF.js → chunk-LVL6GFCM.js} +4 -4
  98. package/{chunk-UTV2AYEG.js → chunk-MAIITKBT.js} +2 -2
  99. package/chunk-MBG66ZBH.js +226 -0
  100. package/{chunk-YUA6OAH5.js → chunk-MDLS23JK.js} +2 -2
  101. package/{chunk-VL5KOY2C.js → chunk-MK2Q7ZJD.js} +67 -5
  102. package/{chunk-B7NJ3T4A.js → chunk-MS4NZNKI.js} +10 -10
  103. package/{chunk-3AKFVZ2I.js → chunk-MYHNBEXD.js} +3 -3
  104. package/{chunk-VZKUKCA6.js → chunk-MZLE5HQ3.js} +3673 -241
  105. package/{chunk-AZMYUSVF.js → chunk-N5Z2V73W.js} +1 -1
  106. package/chunk-NIZ2BXFD.js +526 -0
  107. package/{chunk-YPD3VJZW.js → chunk-NWP2OYOX.js} +20 -20
  108. package/{chunk-3FOQHGHN.js → chunk-O6J3OTOP.js} +4 -4
  109. package/{chunk-3RQVYR4B.js → chunk-OB6DVWPF.js} +197 -65
  110. package/{chunk-YWSEPJ7C.js → chunk-OBWT45ZU.js} +3 -3
  111. package/{chunk-5AQR3DGV.js → chunk-ODJ7BVSI.js} +80 -11
  112. package/{chunk-XJWWBO34.js → chunk-OJKUU3LP.js} +5 -7
  113. package/{chunk-GNDJKC4B.js → chunk-ON37YXGX.js} +29 -29
  114. package/{chunk-D5RCRX4A.js → chunk-P5ZJRTCH.js} +9415 -5169
  115. package/{chunk-6XIE5ZGI.js → chunk-PDCV7P5W.js} +1 -1
  116. package/{chunk-EZFQ6XRV.js → chunk-PJCIP64Z.js} +861 -59
  117. package/{chunk-GPO7FCEZ.js → chunk-PJVKMGPZ.js} +1222 -1719
  118. package/{chunk-CKAHAVMK.js → chunk-PPJYZRSQ.js} +40 -26
  119. package/chunk-QHEN7NZ7.js +46 -0
  120. package/{chunk-4KH4J3G5.js → chunk-QNWG52I4.js} +19 -7
  121. package/{chunk-YGILMZ7N.js → chunk-QVBXJNZ2.js} +1 -1
  122. package/chunk-RDH5CQ4T.js +1382 -0
  123. package/{chunk-C6KNNXWU.js → chunk-RGQ4UUWZ.js} +25 -2
  124. package/{chunk-OWYYDMGJ.js → chunk-S2NTVGA2.js} +4 -2
  125. package/{chunk-KC4XDTT3.js → chunk-SOF4OWDM.js} +6 -4
  126. package/{chunk-IAPCBNEE.js → chunk-SQYIK6HO.js} +1 -1
  127. package/{chunk-22CIEBYO.js → chunk-SVT62ULE.js} +50 -48
  128. package/{chunk-KIM6CLW5.js → chunk-SY3C4SQ7.js} +42 -15
  129. package/{chunk-JY5NGFFH.js → chunk-SYTHYBMI.js} +5 -5
  130. package/{chunk-6NSSLV67.js → chunk-T6DXNI6Z.js} +52 -50
  131. package/chunk-TLE77UJ5.js +230 -0
  132. package/{chunk-4VNS5WPM.js → chunk-U67V476Y.js} +1 -8
  133. package/{chunk-F7CI2ZC5.js → chunk-UAIHKQIA.js} +2 -1
  134. package/{chunk-MMNYUVLW.js → chunk-UB3D4TRQ.js} +11 -77
  135. package/{chunk-WPORQFYN.js → chunk-UVLYNWIE.js} +2 -2
  136. package/{chunk-YOIW77S2.js → chunk-UYOICCYG.js} +29 -19
  137. package/{chunk-4I7ERB7F.js → chunk-VREDDN25.js} +1 -1
  138. package/{chunk-JIT6FSXJ.js → chunk-WAE3GFCJ.js} +3 -3
  139. package/{chunk-IJXYFTV7.js → chunk-WI67URFP.js} +20 -20
  140. package/{chunk-7OCO4TDT.js → chunk-WJVYAO6P.js} +1 -1
  141. package/{chunk-T43B7LB2.js → chunk-WKGQSYTB.js} +1 -1
  142. package/{chunk-YJMRHHGY.js → chunk-WUUH4LWZ.js} +60 -30
  143. package/{chunk-PDGKOTO7.js → chunk-X7UF53VA.js} +33 -22
  144. package/{chunk-TY3TIUJK.js → chunk-XI2BWJM5.js} +65 -0
  145. package/{chunk-OOF4UPC5.js → chunk-XWVCYUUU.js} +16 -159
  146. package/{chunk-J5JTMQIA.js → chunk-YFLVRVYK.js} +1 -1
  147. package/{chunk-EYLGAEB4.js → chunk-YGMBIXCF.js} +132 -0
  148. package/chunk-YL3EFYL3.js +199 -0
  149. package/{chunk-MMA3LZ3W.js → chunk-YNIYE47Z.js} +1 -1
  150. package/{chunk-W4S457LU.js → chunk-YU4ZPWVF.js} +41 -5
  151. package/{chunk-NJR3WKVP.js → chunk-YWWDC3O7.js} +281 -159
  152. package/chunk-YZMNK53S.js +68 -0
  153. package/{chunk-FHU44LN3.js → chunk-Z2PITYZN.js} +2179 -552
  154. package/{chunk-FY7F4Q6X.js → chunk-Z4PCXPUE.js} +2 -2
  155. package/{cliAgentConfigHelpers-WJBZQTLW.js → cliAgentConfigHelpers-TKYL43MT.js} +15 -16
  156. package/{cliAuthorityBrokerClient-PM3U6Q6J.js → cliAuthorityBrokerClient-XHH7MH2P.js} +1 -1
  157. package/{cliAuthorityStoreDriver-TKLXNNTG.js → cliAuthorityStoreDriver-6FE3BJNB.js} +1 -1
  158. package/{cliEnvHelpers-BVYTMUPJ.js → cliEnvHelpers-VPSJ4XWC.js} +3 -3
  159. package/{cliExecutor-BWBF2MTI.js → cliExecutor-4MAX3PZL.js} +2 -2
  160. package/cliLocalAgentRecordReader-MHHD4T7R.js +90 -0
  161. package/{commandRegistry-VVMTPFAX.js → commandRegistry-5DA5UP7S.js} +106 -98
  162. package/{contentThunks-N52O67MI.js → contentThunks-5GUQ7FWJ.js} +47 -43
  163. package/{cooldownCommands-YXLWOXWR.js → cooldownCommands-X7P5M2V5.js} +5 -4
  164. package/{createAgentAutomationAction-ZC57YRSV.js → createAgentAutomationAction-UCLTHQRI.js} +51 -49
  165. package/{createDialogAction-VQW5WDYX.js → createDialogAction-UPN774AF.js} +46 -48
  166. package/{createPageAction-M5VDA7SC.js → createPageAction-JRQ2TA4O.js} +50 -48
  167. package/{cursorProvider-YGGNMVWX.js → cursorProvider-2RACMEMF.js} +1 -1
  168. package/{db-HUCI5R4G.js → db-CS4ZJQKV.js} +1 -1
  169. package/{dbSlice-HP7G4LX3.js → dbSlice-WNON7TOL.js} +17 -16
  170. package/{deleteFile-7VQGLK2V.js → deleteFile-Q3YDB4ML.js} +9 -9
  171. package/{desktopFolderProjects-SFY5EZS3.js → desktopFolderProjects-4POAMVJN.js} +2 -2
  172. package/{dialogCommands-JHMR2N2Y.js → dialogCommands-VRI7VCXH.js} +64 -57
  173. package/dialogNotifyCommand-6TMCX4D2.js +36 -0
  174. package/{dialogSlice-GRSVGDTF.js → dialogSlice-LFNVUSAN.js} +42 -40
  175. package/{dialogUsageCommand-7KCPYGHG.js → dialogUsageCommand-HTVPR2CX.js} +11 -10
  176. package/{docCreateCommands-F2K3UPSQ.js → docCreateCommands-AMPXMOX3.js} +61 -54
  177. package/{docDeleteCommands-XGXB5RFT.js → docDeleteCommands-I5WFAEHP.js} +63 -57
  178. package/{docReadCommands-7HWZZV6J.js → docReadCommands-X53ELNIE.js} +61 -54
  179. package/{docStore-KNZK6Y2G.js → docStore-2VAWVLWH.js} +21 -20
  180. package/{docUpdateCommands-OZZ7NQII.js → docUpdateCommands-6QPNDC7M.js} +64 -57
  181. package/{fetchMessages-M3QU7ZCQ.js → fetchMessages-TQEUZD7H.js} +8 -7
  182. package/{getPricing-2MNMXEVG.js → getPricing-MB2GBXOK.js} +6 -6
  183. package/{handleSendMessageAction-SHIH74GJ.js → handleSendMessageAction-AAJOHXOB.js} +193 -301
  184. package/{hostCredentialCreate-X64WK4JD.js → hostCredentialCreate-GLMJ22M6.js} +123 -114
  185. package/index.js +29 -29
  186. package/{keys-BEGDOTRL.js → keys-RWF7UCB4.js} +5 -4
  187. package/legacyMigration-TF4SYJCZ.js +19 -0
  188. package/{lib-5KKIBFIT.js → lib-OT5OTXRU.js} +7087 -6664
  189. package/{localDialogRead-XRLAH4CZ.js → localDialogRead-SVTPA5GY.js} +3 -3
  190. package/{localFirstLog-DHNOY2NA.js → localFirstLog-OIETGK66.js} +1 -1
  191. package/localRecall-2J6QPOK2.js +15 -0
  192. package/{localRuntimeAdapter-A7K3ABA6.js → localRuntimeAdapter-BMP57P42.js} +119 -110
  193. package/{localRuntimeAuthority-OYH4AE4G.js → localRuntimeAuthority-IBJAT62G.js} +1 -1
  194. package/{localRuntimeDb-VBIMCWUC.js → localRuntimeDb-N7KHDXS2.js} +2 -2
  195. package/{machineCommands-DE3MR7CJ.js → machineCommands-3MLIAK5Q.js} +128 -119
  196. package/{machineInfo-UKPTZO5Y.js → machineInfo-LWHTEBHJ.js} +1 -1
  197. package/machineWsRunDispatch-FKIGROQF.js +191 -0
  198. package/{memberThunks-7WJAY5V6.js → memberThunks-ZGLZ36PK.js} +29 -28
  199. package/{memoryCommands-ASCE5STX.js → memoryCommands-5WC3T66U.js} +4 -4
  200. package/models-ULVWLSQ6.js +9 -0
  201. package/{oauthTokenStore-OEERZFUC.js → oauthTokenStore-RUYNYALS.js} +1 -1
  202. package/{offlineMarxistsAgentCommand-2QTHJCHV.js → offlineMarxistsAgentCommand-4IC3Y4C6.js} +4 -4
  203. package/overlay-THLKYIWY.js +11 -0
  204. package/package.json +2 -2
  205. package/{pdf-U6KSUEZZ.js → pdf-KE3QI2V7.js} +1 -1
  206. package/{processSpawn-ZU5QFM43.js → processSpawn-6GEO77KV.js} +1 -1
  207. package/{profileConfig-KN3N2BLF.js → profileConfig-KOWK4HOG.js} +1 -1
  208. package/{projectArchive-GGL5HLMD.js → projectArchive-HK63GMF4.js} +52 -50
  209. package/{providerPresetApply-YXGV6NXB.js → providerPresetApply-OIFQ73LH.js} +19 -12
  210. package/{providerRegistry-S6UL6UNA.js → providerRegistry-KZ3SDZ3D.js} +10 -10
  211. package/{read-4VZQODSN.js → read-MRQHJMJ2.js} +10 -10
  212. package/{readDocTool-AVD32RUJ.js → readDocTool-4BGTXTXA.js} +2 -2
  213. package/{readlineWorkspace-XKYKNL2I.js → readlineWorkspace-AKAHSCNY.js} +6505 -4634
  214. package/{removeDialogAgentAction-FKL4BYMR.js → removeDialogAgentAction-B6H7DXFM.js} +23 -22
  215. package/{runAgentClientLoop-V7E2WBVM.js → runAgentClientLoop-UVAWGEON.js} +81 -79
  216. package/{runtimeDoctorCommands-QAI3MBKQ.js → runtimeDoctorCommands-FW6XKDUG.js} +12 -12
  217. package/{runtimeModeArgs-2Y7BALTO.js → runtimeModeArgs-X7DL7PUN.js} +1 -1
  218. package/secretCommands-LJXOOYA7.js +24 -0
  219. package/{setDialogExtraReferencesAction-TLIOLWWI.js → setDialogExtraReferencesAction-EVCY3TRW.js} +22 -21
  220. package/{setPrimaryDialogAgentAction-2OLWRFYR.js → setPrimaryDialogAgentAction-KPFVPHCJ.js} +23 -22
  221. package/{settingThunks-UGBPCNYF.js → settingThunks-ENOAK2WV.js} +97 -88
  222. package/{skillDiscovery-XKHROSH2.js → skillDiscovery-B5V23AXP.js} +4 -4
  223. package/{skillSummaryMarker-42HKSXYY.js → skillSummaryMarker-62UW7HI7.js} +1 -1
  224. package/{slateToRenderMarkdown-Y5IYN73U.js → slateToRenderMarkdown-R3X74MCX.js} +1 -1
  225. package/{slateUtils-NGV2NMKM.js → slateUtils-ESQAJ6RN.js} +1 -1
  226. package/{spaceCommands-4KSLKVNF.js → spaceCommands-DTTNAS2L.js} +61 -53
  227. package/store-JRVN62NM.js +46 -0
  228. package/{streamAgentChatTurn-7FR7X2NU.js → streamAgentChatTurn-R5UY25VB.js} +875 -618
  229. package/{switchDialogAgentAction-UZSAG2N5.js → switchDialogAgentAction-SZ44XDRY.js} +21 -20
  230. package/{tableCommands-MP6VFSVT.js → tableCommands-HITDSLHS.js} +10 -10
  231. package/tombstones-FQQMEDOW.js +32 -0
  232. package/{toolApiClient-HGNO53TC.js → toolApiClient-OGQEBQVX.js} +4 -4
  233. package/{tools-ZLKCC25W.js → tools-HWFG6GMJ.js} +75 -74
  234. package/tuiSummaryLlmCaller-HQQZAMYF.js +44 -0
  235. package/{updateCommands-4744PL3P.js → updateCommands-RJVCRSBP.js} +10 -8
  236. package/{updateDialogTitleAction-U53ZT7PJ.js → updateDialogTitleAction-KNPOAMVS.js} +48 -46
  237. package/{usageCommand-F4IPVMIZ.js → usageCommand-FWZCB7AM.js} +11 -10
  238. package/{usageRebuildCommand-HAW2AD5N.js → usageRebuildCommand-SP2BLNJU.js} +12 -11
  239. package/userDataMerge-HT2ZVHBJ.js +13 -0
  240. package/{windowsSelfUpdate-XSQVF2GK.js → windowsSelfUpdate-KERHIAB4.js} +3 -3
  241. package/{workloadLifecycle-4BEQHMSD.js → workloadLifecycle-DYNEYHV5.js} +7 -6
  242. package/agentRecordCommands-L3QQ7HZ4.js +0 -167
  243. package/agentRunCommand-2IFGQHCO.js +0 -196
  244. package/chunk-3CGG2PAL.js +0 -594
  245. package/chunk-5XBUWM6I.js +0 -89
  246. package/chunk-BFM34N54.js +0 -842
  247. package/chunk-CJEIOP3E.js +0 -0
  248. package/chunk-CZM5YTZ7.js +0 -977
  249. package/chunk-EYUBHHFB.js +0 -636
  250. package/chunk-JTDORD5P.js +0 -415
  251. package/chunk-NRFKLKRU.js +0 -339
  252. package/chunk-VPAZOH2D.js +0 -115
  253. package/chunk-WJZOQR2J.js +0 -151
  254. package/chunk-ZCWRMUWT.js +0 -89
  255. package/dist-M676ULYG.js +0 -7314
  256. package/machineWsRunDispatch-R26P5V36.js +0 -182
  257. package/models-PJBE6JDV.js +0 -9
  258. package/tuiSummaryLlmCaller-WC54MVGP.js +0 -160
  259. package/{chunk-WACI5I6V.js → chunk-2THCNKE4.js} +3 -3
  260. package/{chunk-2QHFH3DR.js → chunk-47ITIXO7.js} +6 -6
  261. package/{chunk-GOO6G4PY.js → chunk-CKG3PRZ7.js} +0 -0
  262. package/{chunk-OQHIVPG4.js → chunk-SNBZZPYH.js} +3 -3
  263. package/{chunk-AETZ7AD6.js → chunk-W6RFEDN4.js} +3 -3
@@ -1,21 +1,25 @@
1
1
  import {
2
2
  resolveRuntimeAuthToken,
3
3
  resolveRuntimeServerUrl
4
- } from "./chunk-HRMJUN5J.js";
4
+ } from "./chunk-AQZ6BMRK.js";
5
5
  import {
6
6
  isAgentRunTerminalStatus,
7
- normalizeRunTitle
8
- } from "./chunk-PJNFNEJE.js";
7
+ normalizeRunTitle,
8
+ shortAgentKey
9
+ } from "./chunk-AMEOV5VZ.js";
9
10
  import {
10
11
  findPowerShellExecutable
11
- } from "./chunk-JNKSDZFS.js";
12
+ } from "./chunk-KEN3N2TN.js";
13
+ import {
14
+ AUTH_ERROR_PATTERNS
15
+ } from "./chunk-EWQ3HGNZ.js";
12
16
  import {
13
17
  isRecord
14
18
  } from "./chunk-KUG52IAP.js";
15
19
  import {
16
20
  isCompiledBinary,
17
21
  resolveCliEntrypointPath
18
- } from "./chunk-WACI5I6V.js";
22
+ } from "./chunk-2THCNKE4.js";
19
23
 
20
24
  // packages/cli/client/originShellApprovalTransport.ts
21
25
  import { realpathSync } from "node:fs";
@@ -444,9 +448,10 @@ function redactLogLines(lines, options = {}) {
444
448
  }
445
449
 
446
450
  // packages/cli/agentRunControl.ts
447
- import { homedir as nodeHomedir } from "node:os";
451
+ import { hostname as nodeHostname, homedir as nodeHomedir } from "node:os";
448
452
  import { dirname, isAbsolute as isAbsolute2, join as join2, resolve } from "node:path";
449
453
  import * as nodeFs2 from "node:fs";
454
+ import { randomUUID as randomUUID2, createHash } from "node:crypto";
450
455
  import { execFileSync as nodeExecFileSync, spawn as nodeSpawn } from "node:child_process";
451
456
 
452
457
  // packages/cli/client/hostMemory.ts
@@ -1090,6 +1095,7 @@ function resolveResultServerMeta(input) {
1090
1095
  var resultHeaderMeta = /* @__PURE__ */ new WeakMap();
1091
1096
  function recordRunResultHeaderMeta(result, meta) {
1092
1097
  const clean = {};
1098
+ if (meta.commandObservations?.length) clean.commandObservations = meta.commandObservations;
1093
1099
  if (meta.model) clean.model = meta.model;
1094
1100
  if (meta.dialogServer) clean.dialogServer = meta.dialogServer;
1095
1101
  if (meta.serverSync) clean.serverSync = meta.serverSync;
@@ -1134,7 +1140,8 @@ function buildResultFrontMatter(input) {
1134
1140
  ["server", input.server],
1135
1141
  ["serverSync", input.serverSync],
1136
1142
  ["cwd", input.cwd],
1137
- ["continuedFrom", input.continuedFrom]
1143
+ ["continuedFrom", input.continuedFrom],
1144
+ ["acceptance", input.acceptance ? JSON.stringify(input.acceptance) : void 0]
1138
1145
  ];
1139
1146
  const lines = entries.filter(([, v]) => v !== void 0 && v !== "").map(([k, v]) => `${k}: ${yamlScalar(v)}`);
1140
1147
  return `---
@@ -1145,9 +1152,18 @@ ${lines.join("\n")}
1145
1152
  function buildResultFileContent(input, body) {
1146
1153
  return `${buildResultFrontMatter(input)}${body}`;
1147
1154
  }
1155
+ var RESULT_FRONT_MATTER_RE = /^---\nrunId: [^\n]*\n(?:[^\n]*\n)*?---\n/;
1156
+ function stripResultFrontMatter(text) {
1157
+ const match = RESULT_FRONT_MATTER_RE.exec(text);
1158
+ return match ? text.slice(match[0].length) : text;
1159
+ }
1148
1160
 
1149
1161
  // packages/ai/tools/agent/runFailureClass.ts
1150
- var RATE_LIMIT_PATTERN = /429|rate.?limit|quota|insufficient.?balance|UPSTREAM_402|cooling|冷却/i;
1162
+ function isHistoryIntegrityFailure(message) {
1163
+ return /^Strict continuation history load failed for [^\r\n]+:/i.test(message.trim());
1164
+ }
1165
+ var BALANCE_PATTERN = /\bUPSTREAM_402\b|\b402\b|insufficient[_\s-]+balance|余额不足|wallet\s+balance\s+is\s+insufficient|top\s+up\s+your\s+wallet|payment[_ ]required/i;
1166
+ var RATE_LIMIT_PATTERN = /429|rate.?limit|quota|cooling|冷却/i;
1151
1167
  var PROVIDER_ERROR_PATTERN = /provider|upstream|5\d\d|bad.?gateway|service.?unavailable|overloaded/i;
1152
1168
  var MALFORMED_PATTERN = /MALFORMED_FUNCTION_CALL|malformed|invalid.?function.?call|invalid.?tool.?call/i;
1153
1169
  var STALLED_PATTERN = /stall|no.?progress|repetition|stagnant|无进展|卡死/i;
@@ -1159,6 +1175,20 @@ function classifyRunFailure(input) {
1159
1175
  }
1160
1176
  const reason = typeof input.failureReason === "string" ? input.failureReason : "";
1161
1177
  const message = typeof input.errorMessage === "string" ? input.errorMessage : "";
1178
+ if (reason === "history_integrity" || isHistoryIntegrityFailure(message)) {
1179
+ return { failureClass: "history_integrity", retryable: false };
1180
+ }
1181
+ if (!reason || reason === "provider_rate_limited" || reason === "provider_error") {
1182
+ if (BALANCE_PATTERN.test(message)) {
1183
+ return { failureClass: "balance_exhausted", retryable: false };
1184
+ }
1185
+ if (AUTH_ERROR_PATTERNS.some((pattern) => pattern.test(message))) {
1186
+ return { failureClass: "auth", retryable: false };
1187
+ }
1188
+ if (reason === "provider_error" && RATE_LIMIT_PATTERN.test(message)) {
1189
+ return { failureClass: "rate_limited", retryable: true };
1190
+ }
1191
+ }
1162
1192
  switch (reason) {
1163
1193
  case "provider_rate_limited":
1164
1194
  return { failureClass: "rate_limited", retryable: true };
@@ -1552,7 +1582,9 @@ function withRunRecordLock(runId, deps, fn, opts = {}) {
1552
1582
  try {
1553
1583
  const stat = fs.statSync?.(lockPath);
1554
1584
  const ageMs = stat ? now().getTime() - stat.mtimeMs : Number.POSITIVE_INFINITY;
1555
- if (ageMs > LOCK_STALE_MS) {
1585
+ const ownerPid = opts.requireDeadOwner ? Number(String(fs.readFileSync(lockPath, "utf8"))) : void 0;
1586
+ const ownerGone = !opts.requireDeadOwner || Number.isSafeInteger(ownerPid) && ownerPid > 0 && isPidGone(ownerPid, deps);
1587
+ if (ageMs > LOCK_STALE_MS && ownerGone) {
1556
1588
  fs.unlinkSync(lockPath);
1557
1589
  fs.writeFileSync(lockPath, String(process.pid), { flag: "wx" });
1558
1590
  held = true;
@@ -1582,13 +1614,15 @@ function writeRunRecord(record, deps = {}) {
1582
1614
  fs.writeFileSync(tmp, payload);
1583
1615
  fs.renameSync(tmp, path);
1584
1616
  return;
1585
- } catch {
1617
+ } catch (error) {
1586
1618
  try {
1587
1619
  fs.unlinkSync(tmp);
1588
1620
  } catch {
1589
1621
  }
1622
+ if (record.writerLaunch) throw error;
1590
1623
  }
1591
1624
  }
1625
+ if (record.writerLaunch) throw new Error("[local-writer-resource] fenced launch requires atomic rename");
1592
1626
  fs.writeFileSync(path, payload);
1593
1627
  }
1594
1628
  function reportRunProcessIdentity(runId, deps = {}) {
@@ -2054,9 +2088,18 @@ async function gcRunRecords(deps = {}, options = {}) {
2054
2088
  const failedIds = [];
2055
2089
  for (const record of records) {
2056
2090
  if (!isRunTerminalStatus(record.status)) continue;
2091
+ if (localWriterStillOwns(record, deps)) continue;
2092
+ if (!/^[A-Za-z0-9._-]{1,128}$/.test(record.runId) || record.runId === "." || record.runId === "..") {
2093
+ failedIds.push(record.runId);
2094
+ continue;
2095
+ }
2057
2096
  const ts = record.reconciledAt ?? record.endedAt ?? record.startedAt;
2058
2097
  const ageMs = nowMs - new Date(ts).getTime();
2059
2098
  if (!Number.isFinite(ageMs) || ageMs < retentionMs) continue;
2099
+ if (fs.existsSync(`${resolveRunRecordPath(record.runId, deps.env, deps.homedir)}.lock`)) {
2100
+ failedIds.push(record.runId);
2101
+ continue;
2102
+ }
2060
2103
  const jsonPath = resolveRunRecordPath(record.runId, deps.env, deps.homedir);
2061
2104
  const logPath = resolveRunLogPath(record.runId, deps.env, deps.homedir);
2062
2105
  const queuePath = record.queuePath ?? resolveRunQueuePath(record.runId, deps.env, deps.homedir);
@@ -2076,8 +2119,30 @@ async function gcRunRecords(deps = {}, options = {}) {
2076
2119
  const runsDirForLegacy = resolveRunsDir(deps.env, deps.homedir);
2077
2120
  tryUnlinkFile(fs, join2(runsDirForLegacy, `${record.runId}.report.md`));
2078
2121
  tryUnlinkFile(fs, join2(runsDirForLegacy, `${record.runId}.report.json`));
2079
- tryUnlinkFile(fs, record.resultFile ?? join2(runsDirForLegacy, `${record.runId}.result.md`));
2080
- if (!logOk || !msgOk || !queueOk) {
2122
+ let resultOk = false;
2123
+ let artifactsOk = true;
2124
+ const artifactSweep = withRunRecordLock(record.runId, deps, () => {
2125
+ resultOk = tryUnlinkFile(fs, join2(runsDirForLegacy, `${record.runId}.result.md`));
2126
+ for (const artifact of record.resultArtifacts ?? []) {
2127
+ try {
2128
+ const prefix = `${record.runId}.result.md.`;
2129
+ const name = artifact.path.slice(join2(runsDirForLegacy, prefix).length);
2130
+ const uuid = "[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}";
2131
+ if (artifact.publisher !== "run-result-v1" || !/^[A-Za-z0-9._-]+$/.test(record.runId) || !["pending", "bak"].includes(artifact.kind) || !new RegExp(`^${uuid}\\.${artifact.kind}$`).test(name) || artifact.path !== join2(runsDirForLegacy, prefix + name)) throw new Error("unsafe artifact ownership");
2132
+ if (!fs.existsSync(artifact.path)) continue;
2133
+ const stat = fs.lstatSync?.(artifact.path);
2134
+ if (!stat || !stat.isFile() || stat.isSymbolicLink() || fs.realpathSync?.(artifact.path) !== resolve(artifact.path) || String(stat.dev) !== artifact.dev || String(stat.ino) !== artifact.ino || createHash("sha256").update(fs.readFileSync(artifact.path)).digest("hex") !== artifact.sha256) {
2135
+ throw new Error("artifact identity changed");
2136
+ }
2137
+ if (!tryUnlinkFile(fs, artifact.path)) artifactsOk = false;
2138
+ } catch {
2139
+ artifactsOk = false;
2140
+ }
2141
+ }
2142
+ return true;
2143
+ }, { strict: true });
2144
+ if (!artifactSweep) artifactsOk = false;
2145
+ if (!logOk || !msgOk || !queueOk || !resultOk || !artifactsOk) {
2081
2146
  failedIds.push(record.runId);
2082
2147
  continue;
2083
2148
  }
@@ -2090,12 +2155,12 @@ async function gcRunRecords(deps = {}, options = {}) {
2090
2155
  }
2091
2156
  try {
2092
2157
  const dir = resolveRunsDir(deps.env, deps.homedir);
2093
- const statSync = fs.statSync;
2158
+ const statSync2 = fs.statSync;
2094
2159
  for (const entry of fs.readdirSync(dir)) {
2095
2160
  if (typeof entry !== "string" || !entry.endsWith(".tmp")) continue;
2096
2161
  const tmpPath = join2(dir, entry);
2097
2162
  try {
2098
- const stat = statSync?.(tmpPath);
2163
+ const stat = statSync2?.(tmpPath);
2099
2164
  if (stat && nowMs - stat.mtimeMs <= TMP_STALE_MS) continue;
2100
2165
  } catch {
2101
2166
  continue;
@@ -2210,6 +2275,270 @@ function emitHostMemoryNotice(mem, output) {
2210
2275
  }
2211
2276
  return notice;
2212
2277
  }
2278
+ function trustedLocalWorktree(cwd, deps) {
2279
+ const fs = deps.fs ?? nodeFs2;
2280
+ try {
2281
+ const env = { ...process.env, ...deps.env };
2282
+ for (const key of Object.keys(env)) if (key.startsWith("GIT_")) delete env[key];
2283
+ const exec = deps.execFileSync ?? nodeExecFileSync;
2284
+ const git = (args) => exec("git", args, {
2285
+ cwd,
2286
+ env,
2287
+ encoding: "utf8",
2288
+ stdio: ["ignore", "pipe", "ignore"],
2289
+ timeout: 3e3
2290
+ }).trim();
2291
+ const real = (path) => String((fs.realpathSync ?? nodeFs2.realpathSync)(path));
2292
+ const [dir, top, common] = git(["rev-parse", "--path-format=absolute", "--git-dir", "--show-toplevel", "--git-common-dir"]).split("\n");
2293
+ if (!dir || !top || !common || ![dir, top, common].every(isAbsolute2)) return;
2294
+ const root = real(top), gitDir = real(dir), commonDir = real(common);
2295
+ const marker = join2(root, ".git");
2296
+ const stat = (path) => (fs.lstatSync ?? nodeFs2.lstatSync)(path);
2297
+ if (stat(marker).isSymbolicLink() || stat(commonDir).isSymbolicLink()) return;
2298
+ if (gitDir === commonDir) {
2299
+ if (!stat(marker).isDirectory() || real(marker) !== commonDir) return;
2300
+ } else {
2301
+ const registry = join2(commonDir, "worktrees");
2302
+ if (stat(registry).isSymbolicLink() || dirname(gitDir) !== real(registry) || !stat(gitDir).isDirectory() || stat(gitDir).isSymbolicLink() || !stat(marker).isFile()) return;
2303
+ const text = String(fs.readFileSync(marker, "utf8")).trim();
2304
+ if (!text.startsWith("gitdir: ") || real(resolve(root, text.slice(8))) !== gitDir) return;
2305
+ const back = String(fs.readFileSync(join2(gitDir, "gitdir"), "utf8")).trim();
2306
+ const commonBack = String(fs.readFileSync(join2(gitDir, "commondir"), "utf8")).trim();
2307
+ if (real(resolve(gitDir, back)) !== real(marker) || real(resolve(gitDir, commonBack)) !== commonDir) return;
2308
+ }
2309
+ const registered = git(["worktree", "list", "--porcelain"]).split("\n").filter((line) => line.startsWith("worktree ")).map((line) => line.slice(9));
2310
+ if (!registered.some((path) => real(path) === root)) return;
2311
+ const mainMarker = registered[0] && join2(registered[0], ".git");
2312
+ if (!mainMarker || stat(mainMarker).isSymbolicLink() || !stat(mainMarker).isDirectory() || real(mainMarker) !== commonDir) return;
2313
+ return { root, gitDir, commonDir };
2314
+ } catch {
2315
+ return;
2316
+ }
2317
+ }
2318
+ function localWriterRecovery(record) {
2319
+ if (record.localWriterClaim?.state !== "held" || typeof record.pid === "number" && record.pid > 0) return;
2320
+ return {
2321
+ state: "required",
2322
+ reason: "owner-unpublished",
2323
+ automaticReleaseAllowed: false,
2324
+ runId: record.runId,
2325
+ canonicalCwd: record.localWriterClaim.cwd,
2326
+ requiredEvidence: "native launch receipt proving no live child; parent death/timeouts/process-name search are insufficient"
2327
+ };
2328
+ }
2329
+ function revokePreparedWriterLaunch(runId, attemptId, deps = {}) {
2330
+ if (!/^[A-Za-z0-9_-]+$/.test(runId) || !attemptId) return "blocked";
2331
+ return withRunRecordLock("local-writer-admission", deps, () => {
2332
+ const snapshot = readRunRecord(runId, deps);
2333
+ if (!snapshot) return "blocked";
2334
+ return withRunRecordLock(runId, deps, () => {
2335
+ const latest = readRunRecord(runId, deps);
2336
+ if (!latest || JSON.stringify(latest) !== JSON.stringify(snapshot)) return "blocked";
2337
+ const launch = latest.writerLaunch;
2338
+ if (launch?.protocol !== "fenced-launch-v1" || launch.attemptId !== attemptId) return "blocked";
2339
+ if (launch.phase === "revoked") return latest.localWriterClaim?.state === "released" ? "already-revoked" : "blocked";
2340
+ if (launch.phase !== "prepared" || latest.localWriterClaim?.state !== "held" || latest.execution?.state !== "known" || latest.execution.owner.state !== "unknown" || latest.execution.canonicalCwd !== latest.localWriterClaim.cwd || latest.pid !== void 0 || latest.cwd !== latest.localWriterClaim.cwd || latest.execution.kind !== "host-local" || latest.execution.permissions.readOnly || !latest.execution.permissions.hostWritesAuthorized) return "blocked";
2341
+ launch.phase = "revoked";
2342
+ latest.localWriterClaim.state = "released";
2343
+ writeRunRecord(latest, deps);
2344
+ return "revoked";
2345
+ }, { strict: true, requireDeadOwner: true }) ?? "blocked";
2346
+ }, { strict: true, requireDeadOwner: true }) ?? "blocked";
2347
+ }
2348
+ function localWriterStillOwns(record, deps) {
2349
+ if (record.localWriterClaim?.state !== "held") return false;
2350
+ if (typeof record.pid !== "number" || record.pid <= 0) return true;
2351
+ const e = record.execution;
2352
+ const observed = e?.state === "known" && e.owner.state === "verified" ? nativeOwner(record.pid, deps) : void 0;
2353
+ const reused = observed?.state === "verified" && e?.state === "known" && e.owner.state === "verified" && (observed.startedAt !== e.owner.startedAt || (observed.linux?.bootId !== e.owner.linux?.bootId || observed.linux?.startTicks !== e.owner.linux?.startTicks));
2354
+ if (!isPidGone(record.pid, deps) && !reused) return true;
2355
+ const snapshot = JSON.stringify(record);
2356
+ const released = withRunRecordLock(record.runId, deps, () => {
2357
+ const latest = readRunRecord(record.runId, deps);
2358
+ if (!latest || JSON.stringify(latest) !== snapshot) return false;
2359
+ latest.localWriterClaim.state = "released";
2360
+ writeRunRecord(latest, deps);
2361
+ return true;
2362
+ }, { strict: true });
2363
+ return released !== true;
2364
+ }
2365
+ function acquireLocalWriterClaim(runId, cwd, deps) {
2366
+ const fs = deps.fs ?? nodeFs2;
2367
+ const canonical = String((fs.realpathSync ?? nodeFs2.realpathSync)(cwd));
2368
+ const worktree = trustedLocalWorktree(canonical, deps);
2369
+ const acquired = withRunRecordLock("local-writer-admission", deps, () => {
2370
+ const updated = withRunRecordLock(runId, deps, () => {
2371
+ const record = readRunRecord(runId, deps);
2372
+ if (!record) throw new Error(`[local-writer-resource] missing run ${runId}`);
2373
+ if (record.writerLaunch?.phase === "revoked") throw new Error("[local-writer-resource] claim attempt revoked");
2374
+ record.localWriterClaim = { cwd: canonical, ...worktree ? { worktree } : {}, state: "held" };
2375
+ if (record.writerLaunch && record.execution?.state === "known" && record.execution.owner.state === "verified" && record.pid === process.pid) {
2376
+ record.writerLaunch.phase = "granted";
2377
+ }
2378
+ writeRunRecord(record, deps);
2379
+ return true;
2380
+ }, { strict: true });
2381
+ if (!updated) throw new Error(`[local-writer-resource] run lock busy: ${runId}`);
2382
+ return true;
2383
+ }, { strict: true, requireDeadOwner: true });
2384
+ if (!acquired) throw new Error("[local-writer-resource] admission lock busy; no child spawned");
2385
+ return canonical;
2386
+ }
2387
+ function nativeOwner(pid, deps) {
2388
+ const first = probeProcessStartTime(pid, deps);
2389
+ let linux;
2390
+ if ((deps.platform ?? process.platform) === "linux") {
2391
+ try {
2392
+ const stat = nodeFs2.readFileSync(`/proc/${pid}/stat`, "utf8");
2393
+ const startTicks = stat.slice(stat.lastIndexOf(")") + 2).split(/\s+/)[19];
2394
+ const bootId = nodeFs2.readFileSync("/proc/sys/kernel/random/boot_id", "utf8").trim();
2395
+ if (/^\d+$/.test(startTicks) && bootId) linux = { startTicks, bootId };
2396
+ } catch {
2397
+ return { state: "unknown" };
2398
+ }
2399
+ }
2400
+ const second = probeProcessStartTime(pid, deps);
2401
+ if (!first || !second || first.getTime() !== second.getTime() || isPidGone(pid, deps) || (deps.platform ?? process.platform) === "linux" && !linux) return { state: "unknown" };
2402
+ return { state: "verified", pid, startedAt: first.toISOString(), source: "parent-native", ...linux ? { linux } : {} };
2403
+ }
2404
+ function validateLocalWriterChild(runId, cwd, policy, deps = {}) {
2405
+ const fail = (reason = "facts") => {
2406
+ throw new Error(`[local-writer-resource] child binding unknown or mismatched: ${reason}`);
2407
+ };
2408
+ if (!/^[A-Za-z0-9_-]+$/.test(runId)) fail();
2409
+ const validated = withRunRecordLock(runId, deps, () => {
2410
+ const r = readRunRecord(runId, deps), e = r?.execution;
2411
+ const launch = r?.writerLaunch;
2412
+ if (launch && (launch.protocol !== "fenced-launch-v1" || launch.phase !== "granted" || launch.attemptId !== deps.env?.NOLO_WRITER_LAUNCH_ATTEMPT)) fail("launch grant missing/revoked");
2413
+ const native = nativeOwner(process.pid, deps);
2414
+ const real = String((deps.fs?.realpathSync ?? nodeFs2.realpathSync)(cwd));
2415
+ if (!r || r.runId !== runId || r.pid !== process.pid || r.status !== "running" || e?.state !== "known" || e.kind !== "host-local" || e.runtimeKey !== "local" || e.device.kind !== "localhost" || e.device.hostname !== nodeHostname() || e.device.platform !== process.platform || !["cli-command-authorized", "cli-tool-dispatch-authorized"].includes(e.provenance) || e.owner.state !== "verified" || native.state !== "verified" || e.owner.pid !== process.pid || e.owner.startedAt !== native.startedAt || (e.owner.linux?.bootId !== native.linux?.bootId || e.owner.linux?.startTicks !== native.linux?.startTicks) || r.processIdentity !== "verified" || r.processStartedAt !== e.owner.startedAt || e.canonicalCwd !== real || r.cwd !== real || e.permissions.hostWritesAuthorized !== policy.hostWritesAuthorized || e.permissions.readOnly !== policy.readOnly) fail("native identity/authorization");
2416
+ if (e?.state !== "known") return fail();
2417
+ const set = (v) => JSON.stringify(v === void 0 ? null : [...new Set(v)].sort());
2418
+ if (set(e.permissions.allowedToolNames) !== set(policy.allowedToolNames) || set(e.permissions.blockedToolNames) !== set(policy.blockedToolNames) || JSON.stringify(e.worktree) !== JSON.stringify(trustedLocalWorktree(real, deps))) fail("scope/worktree");
2419
+ if (!policy.readOnly && (!policy.hostWritesAuthorized || r?.localWriterClaim?.state !== "held" || r.localWriterClaim.cwd !== real || e.worktree && (r.localWriterClaim.worktree?.root !== e.worktree.root || r.localWriterClaim.worktree.gitDir !== e.worktree.gitDir))) fail();
2420
+ return true;
2421
+ }, { strict: true, requireDeadOwner: true });
2422
+ if (!validated) fail("registry lock busy");
2423
+ }
2424
+ async function awaitLocalWriterChild(runId, cwd, policy, deps = {}) {
2425
+ if (!/^[A-Za-z0-9_-]+$/.test(runId)) throw new Error("[local-writer-resource] child binding invalid id");
2426
+ const deadline = Date.now() + 2e3;
2427
+ for (; ; ) {
2428
+ const r = readRunRecord(runId, deps);
2429
+ const publication = r?.ownerPublication;
2430
+ if (r?.writerLaunch && (r.writerLaunch.phase === "revoked" || r.writerLaunch.attemptId !== deps.env?.NOLO_WRITER_LAUNCH_ATTEMPT)) {
2431
+ throw new Error("[local-writer-resource] child binding launch revoked/mismatched");
2432
+ }
2433
+ const native = publication ? nativeOwner(publication.parent.pid, deps) : { state: "unknown" };
2434
+ const parentLive = publication && native.state === "verified" && publication.parent.startedAt === native.startedAt && publication.parent.linux?.bootId === native.linux?.bootId && publication.parent.linux?.startTicks === native.linux?.startTicks;
2435
+ try {
2436
+ validateLocalWriterChild(runId, cwd, policy, deps);
2437
+ return;
2438
+ } catch (error) {
2439
+ const lockBusy = String(error).includes("registry lock busy");
2440
+ const pending = publication?.state === "pending" && r?.execution?.state === "known" && r.execution.owner.state === "unknown";
2441
+ if (!parentLive || !pending && !lockBusy || Date.now() >= deadline) throw error;
2442
+ await new Promise((resolve2) => setTimeout(resolve2, 20));
2443
+ }
2444
+ }
2445
+ }
2446
+ function resolveLocalContinuation(record, deps = {}) {
2447
+ const fail = (why) => {
2448
+ throw new Error(`[local-continuation] ${why}; dispatch a fresh explicitly authorized run`);
2449
+ };
2450
+ const e = record.execution;
2451
+ if (e?.state !== "known" || e.kind !== "host-local" || e.runtimeKey !== "local" || e.device?.kind !== "localhost" || e.device.hostname !== nodeHostname() || e.device.platform !== process.platform || !["cli-command-authorized", "cli-tool-dispatch-authorized"].includes(e.provenance) || typeof e.permissions?.readOnly !== "boolean" || typeof e.permissions.hostWritesAuthorized !== "boolean" || !e.permissions.readOnly && !e.permissions.hostWritesAuthorized) return fail("execution unknown or unsupported");
2452
+ const lists = [e.permissions.allowedToolNames, e.permissions.blockedToolNames];
2453
+ if (lists.some((v) => v !== void 0 && (!Array.isArray(v) || v.some((t) => typeof t !== "string" || !t || t.startsWith("--"))))) return fail("tool scope invalid");
2454
+ let cwd;
2455
+ try {
2456
+ if (!e.canonicalCwd || !isAbsolute2(e.canonicalCwd) || record.cwd !== e.canonicalCwd) return fail("cwd identity missing");
2457
+ const fs = deps.fs ?? nodeFs2;
2458
+ cwd = String((fs.realpathSync ?? nodeFs2.realpathSync)(e.canonicalCwd));
2459
+ if (cwd !== e.canonicalCwd || !(fs.statSync ?? nodeFs2.statSync)(cwd).isDirectory()) return fail("cwd drift");
2460
+ if (JSON.stringify(e.worktree) !== JSON.stringify(trustedLocalWorktree(cwd, deps))) return fail("cwd worktree changed");
2461
+ } catch {
2462
+ return fail("cwd missing or moved");
2463
+ }
2464
+ const death = record.ownerDeath;
2465
+ const hasDeath = !record.pid && death && death.pid > 0 && JSON.stringify(death.executionOwner) === JSON.stringify(e.owner) && (!record.localWriterClaim || record.localWriterClaim.state === "released");
2466
+ if (!hasDeath && (typeof record.pid !== "number" || record.pid <= 0)) return fail("old owner unknown");
2467
+ const current = hasDeath ? { state: "unknown" } : nativeOwner(record.pid, deps);
2468
+ const old = e.owner;
2469
+ const reused = old?.state === "verified" && current.state === "verified" && (old.pid !== current.pid || old.startedAt !== current.startedAt || old.linux?.bootId !== current.linux?.bootId || old.linux?.startTicks !== current.linux?.startTicks);
2470
+ if (!hasDeath && !isPidGone(record.pid, deps) && !reused) return fail("old owner live or unknown");
2471
+ if (!e.permissions.readOnly && (record.localWriterClaim?.cwd !== cwd || !["held", "released"].includes(record.localWriterClaim.state))) return fail("writer claim unknown");
2472
+ const policy = { runtimeKey: "local", ...e.permissions, provenance: "cli-tool-dispatch-authorized" };
2473
+ const rawArgs = [
2474
+ "--runtime-key",
2475
+ "local",
2476
+ ...policy.hostWritesAuthorized ? ["--allow-host-writes"] : [],
2477
+ ...policy.readOnly ? ["--read-only"] : [],
2478
+ ...(policy.allowedToolNames ?? []).flatMap((t) => ["--allowed-tool", t]),
2479
+ ...(policy.blockedToolNames ?? []).flatMap((t) => ["--blocked-tool", t])
2480
+ ];
2481
+ return { cwd, policy, rawArgs };
2482
+ }
2483
+ function registerLocalForegroundWriter(cwd, policy, agentKey, deps = {}) {
2484
+ const fs = deps.fs ?? nodeFs2;
2485
+ const canonical = String((fs.realpathSync ?? nodeFs2.realpathSync)(cwd));
2486
+ const owner = nativeOwner(process.pid, deps);
2487
+ if (owner.state !== "verified" || policy.readOnly || !policy.hostWritesAuthorized) {
2488
+ throw new Error("[local-writer-resource] foreground native identity/authorization unknown");
2489
+ }
2490
+ const runId = defaultGenerateRunId();
2491
+ fs.mkdirSync(resolveRunsDir(deps.env, deps.homedir), { recursive: true });
2492
+ const worktree = trustedLocalWorktree(canonical, deps);
2493
+ const record = {
2494
+ runId,
2495
+ agentKey,
2496
+ writerLaunch: { protocol: "fenced-launch-v1", attemptId: randomUUID2(), phase: "prepared" },
2497
+ cwd: canonical,
2498
+ startedAt: (deps.now?.() ?? /* @__PURE__ */ new Date()).toISOString(),
2499
+ status: "running",
2500
+ logPath: resolveRunLogPath(runId, deps.env, deps.homedir),
2501
+ pid: process.pid,
2502
+ processStartedAt: owner.startedAt,
2503
+ processIdentity: "verified",
2504
+ execution: {
2505
+ state: "known",
2506
+ kind: "host-local",
2507
+ runtimeKey: "local",
2508
+ canonicalCwd: canonical,
2509
+ device: { kind: "localhost", hostname: nodeHostname(), platform: process.platform },
2510
+ ...worktree ? { worktree } : {},
2511
+ permissions: {
2512
+ hostWritesAuthorized: policy.hostWritesAuthorized,
2513
+ readOnly: policy.readOnly,
2514
+ ...policy.allowedToolNames ? { allowedToolNames: [...policy.allowedToolNames] } : {},
2515
+ ...policy.blockedToolNames ? { blockedToolNames: [...policy.blockedToolNames] } : {}
2516
+ },
2517
+ provenance: policy.provenance,
2518
+ owner
2519
+ }
2520
+ };
2521
+ writeRunRecord(record, deps);
2522
+ try {
2523
+ acquireLocalWriterClaim(runId, canonical, deps);
2524
+ } catch (error) {
2525
+ finalizeRunRecord(runId, { status: "failed", exitCode: 1, note: String(error) }, deps);
2526
+ throw error;
2527
+ }
2528
+ return runId;
2529
+ }
2530
+ function releaseUnspawnedLocalWriterClaim(runId, deps) {
2531
+ const released = withRunRecordLock(runId, deps, () => {
2532
+ const record = readRunRecord(runId, deps);
2533
+ if (record?.localWriterClaim) {
2534
+ if (record.writerLaunch?.phase === "prepared") record.writerLaunch.phase = "revoked";
2535
+ record.localWriterClaim.state = "released";
2536
+ writeRunRecord(record, deps);
2537
+ }
2538
+ return true;
2539
+ }, { strict: true });
2540
+ if (!released) throw new Error(`[local-writer-resource] release lock busy: ${runId}`);
2541
+ }
2213
2542
  async function spawnLocalBackgroundRun(input, deps = {}) {
2214
2543
  const homedir = deps.homedir ?? nodeHomedir;
2215
2544
  const env = deps.env ?? (deps.homedir ? { ...process.env, NOLO_HOME: join2(homedir(), ".nolo") } : process.env);
@@ -2255,13 +2584,43 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
2255
2584
  }
2256
2585
  } catch {
2257
2586
  }
2587
+ const executionRequest = input.localExecution;
2588
+ if (executionRequest && (executionRequest.runtimeKey !== "local" || typeof executionRequest.readOnly !== "boolean" || typeof executionRequest.hostWritesAuthorized !== "boolean" || !executionRequest.readOnly && !executionRequest.hostWritesAuthorized)) {
2589
+ throw new Error("Invalid authorized local execution facts");
2590
+ }
2591
+ const canonicalCwd = executionRequest ? String((fs.realpathSync ?? nodeFs2.realpathSync)(targetCwd)) : void 0;
2592
+ const executionWorktree = canonicalCwd ? trustedLocalWorktree(canonicalCwd, resolvedDeps) : void 0;
2593
+ const execution = executionRequest ? {
2594
+ state: "known",
2595
+ kind: "host-local",
2596
+ runtimeKey: "local",
2597
+ device: { kind: "localhost", hostname: nodeHostname(), platform: deps.platform ?? process.platform },
2598
+ canonicalCwd,
2599
+ ...executionWorktree ? { worktree: executionWorktree } : {},
2600
+ permissions: {
2601
+ hostWritesAuthorized: executionRequest.hostWritesAuthorized,
2602
+ readOnly: executionRequest.readOnly,
2603
+ ...executionRequest.allowedToolNames ? { allowedToolNames: [...executionRequest.allowedToolNames] } : {},
2604
+ ...executionRequest.blockedToolNames ? { blockedToolNames: [...executionRequest.blockedToolNames] } : {}
2605
+ },
2606
+ provenance: executionRequest.provenance,
2607
+ owner: { state: "unknown" }
2608
+ } : { state: "unknown", reason: "missing-host-facts" };
2258
2609
  const title = normalizeRunTitle(input.title);
2259
2610
  const record = {
2611
+ ...input.evidenceScope ? { evidenceScope: input.evidenceScope } : {},
2612
+ ...input.dispatchSpeedProvenance ? { dispatchSpeedProvenance: input.dispatchSpeedProvenance } : {},
2260
2613
  runId,
2261
2614
  agentKey: input.agentKey,
2262
- ...typeof input.agentName === "string" && input.agentName.trim() ? { agentName: input.agentName.trim() } : {},
2615
+ agentName: input.agentName?.trim() || shortAgentKey(input.agentKey),
2263
2616
  ...title ? { title } : {},
2264
- cwd: input.cwd,
2617
+ cwd: canonicalCwd ?? input.cwd,
2618
+ execution,
2619
+ ...executionRequest ? { writerLaunch: { protocol: "fenced-launch-v1", attemptId: randomUUID2(), phase: "prepared" } } : {},
2620
+ ...executionRequest ? (() => {
2621
+ const parent = nativeOwner(process.pid, resolvedDeps);
2622
+ return parent.state === "verified" ? { ownerPublication: { state: "pending", parent } } : {};
2623
+ })() : {},
2265
2624
  ...messagePath ? { msgFile: messagePath } : input.msgFile ? { msgFile: input.msgFile } : {},
2266
2625
  startedAt: now().toISOString(),
2267
2626
  ...typeof input.timeoutMs === "number" ? { timeoutMs: input.timeoutMs } : {},
@@ -2269,6 +2628,7 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
2269
2628
  logPath,
2270
2629
  queuePath,
2271
2630
  batchId,
2631
+ ...input.selectionCheck ? { selectionCheck: input.selectionCheck } : {},
2272
2632
  ...typeof input.credentialGroup === "string" && input.credentialGroup.trim() ? { credentialGroup: input.credentialGroup.trim() } : {},
2273
2633
  ...typeof input.parentDialogId === "string" && input.parentDialogId.trim() ? { parentDialogId: input.parentDialogId.trim() } : {},
2274
2634
  ...typeof input.dialogId === "string" && input.dialogId.trim() ? { dialogId: input.dialogId.trim() } : {},
@@ -2293,8 +2653,12 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
2293
2653
  const childEnv = {
2294
2654
  ...env,
2295
2655
  NOLO_AGENT_RUN_CHILD: "1",
2296
- NOLO_AGENT_RUN_ID: runId
2656
+ NOLO_AGENT_RUN_ID: runId,
2657
+ ...record.writerLaunch ? { NOLO_WRITER_LAUNCH_ATTEMPT: record.writerLaunch.attemptId } : {}
2297
2658
  };
2659
+ if (!record.writerLaunch) delete childEnv.NOLO_WRITER_LAUNCH_ATTEMPT;
2660
+ delete childEnv.NOLO_SUBTASK_MAX_TOOL_CALLS;
2661
+ delete childEnv.NOLO_SUBTASK_MAX_WALL_CLOCK_MS;
2298
2662
  let hostMemory = null;
2299
2663
  let reservation;
2300
2664
  const logFd = fs.openSync(logPath, "a");
@@ -2308,6 +2672,8 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
2308
2672
  ...fs.statSync ? { statSync: (path) => ({ mtimeMs: fs.statSync(path).mtimeMs }) } : {}
2309
2673
  };
2310
2674
  let proc;
2675
+ let preparedScope;
2676
+ const launchScope = (r) => JSON.stringify({ cwd: r.cwd, execution: r.execution, claim: r.localWriterClaim, publication: r.ownerPublication });
2311
2677
  try {
2312
2678
  reservation = reserveHostMemory({
2313
2679
  runsDir,
@@ -2319,8 +2685,14 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
2319
2685
  getProcessStartTime: () => null,
2320
2686
  withLock: (id, fn, opts) => withRunRecordLock(id, resolvedDeps, fn, opts)
2321
2687
  });
2688
+ const spawnCwd = input.claimLocalWrites ? acquireLocalWriterClaim(runId, input.cwd ?? process.cwd(), resolvedDeps) : canonicalCwd ?? input.cwd;
2689
+ if (record.writerLaunch) {
2690
+ const prepared = readRunRecord(runId, resolvedDeps);
2691
+ if (!prepared || prepared.writerLaunch?.phase !== "prepared" || prepared.writerLaunch.attemptId !== record.writerLaunch.attemptId) throw new Error("[local-writer-resource] launch attempt revoked before spawn");
2692
+ preparedScope = launchScope(prepared);
2693
+ }
2322
2694
  proc = spawn(execPath, childArgs, {
2323
- cwd: input.cwd,
2695
+ cwd: spawnCwd,
2324
2696
  env: childEnv,
2325
2697
  detached: true,
2326
2698
  // Detached on Windows means no console; hide the one its children would create.
@@ -2330,6 +2702,7 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
2330
2702
  } catch (error) {
2331
2703
  try {
2332
2704
  reservation?.release("spawn_sync_failed");
2705
+ if (input.claimLocalWrites) releaseUnspawnedLocalWriterClaim(runId, resolvedDeps);
2333
2706
  } finally {
2334
2707
  finalizeRunRecord(runId, { status: "failed", exitCode: 1, note: String(error) }, resolvedDeps);
2335
2708
  }
@@ -2352,13 +2725,56 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
2352
2725
  });
2353
2726
  const hostMemoryNotice = emitHostMemoryNotice(hostMemory, input.output);
2354
2727
  if (typeof proc.pid === "number") {
2355
- withRunRecordLock(runId, resolvedDeps, () => {
2356
- const latest = readRunRecord(runId, resolvedDeps) ?? record;
2728
+ const nativeStartedAt = executionRequest ? probeProcessStartTime(proc.pid, resolvedDeps) : null;
2729
+ let linuxIdentity;
2730
+ if (executionRequest && (deps.platform ?? process.platform) === "linux") {
2731
+ try {
2732
+ const stat = String(nodeFs2.readFileSync(`/proc/${proc.pid}/stat`, "utf8"));
2733
+ const startTicks = stat.slice(stat.lastIndexOf(")") + 2).split(/\s+/)[19];
2734
+ const bootId = nodeFs2.readFileSync("/proc/sys/kernel/random/boot_id", "utf8").trim();
2735
+ if (/^\d+$/.test(startTicks) && bootId) linuxIdentity = { bootId, startTicks };
2736
+ } catch {
2737
+ }
2738
+ }
2739
+ const confirmedStart = executionRequest ? probeProcessStartTime(proc.pid, resolvedDeps) : null;
2740
+ const stableNativeIdentity = nativeStartedAt && confirmedStart && nativeStartedAt.getTime() === confirmedStart.getTime() && !isPidGone(proc.pid, resolvedDeps);
2741
+ const publishOwner = () => withRunRecordLock(runId, resolvedDeps, () => {
2742
+ const latest = readRunRecord(runId, resolvedDeps);
2743
+ if (!latest) throw new Error("[local-writer-resource] publication record missing");
2744
+ if (record.writerLaunch) {
2745
+ const launch = latest.writerLaunch;
2746
+ if (launch?.protocol !== "fenced-launch-v1" || launch.attemptId !== record.writerLaunch.attemptId || launch.phase !== "prepared") {
2747
+ throw new Error("[local-writer-resource] publication attempt revoked/mismatched");
2748
+ }
2749
+ if (launchScope(latest) !== preparedScope) throw new Error("[local-writer-resource] publication scope changed");
2750
+ }
2357
2751
  latest.pid = proc.pid;
2358
- latest.processIdentity ??= "unverified";
2752
+ if (latest.execution?.state === "known") {
2753
+ const verified = stableNativeIdentity && ((deps.platform ?? process.platform) !== "linux" || linuxIdentity);
2754
+ latest.execution.owner = verified ? {
2755
+ state: "verified",
2756
+ pid: proc.pid,
2757
+ startedAt: nativeStartedAt.toISOString(),
2758
+ source: "parent-native",
2759
+ ...linuxIdentity ? { linux: linuxIdentity } : {}
2760
+ } : { state: "unknown" };
2761
+ latest.processIdentity = verified ? "verified" : "unverified";
2762
+ latest.processStartedAt = verified ? nativeStartedAt.toISOString() : void 0;
2763
+ } else {
2764
+ latest.processIdentity ??= "unverified";
2765
+ }
2766
+ if (latest.writerLaunch && latest.execution?.state === "known" && latest.execution.owner.state === "verified") {
2767
+ latest.writerLaunch.phase = "granted";
2768
+ }
2769
+ if (latest.ownerPublication) latest.ownerPublication.state = "complete";
2359
2770
  writeRunRecord(latest, resolvedDeps);
2360
2771
  return true;
2361
- }, { strict: true });
2772
+ }, { strict: true, requireDeadOwner: true });
2773
+ const publicationDeadline = Date.now() + 2e3;
2774
+ while (!publishOwner()) {
2775
+ if (Date.now() >= publicationDeadline) throw new Error("[local-writer-resource] parent owner publication lock busy");
2776
+ await new Promise((resolve2) => setTimeout(resolve2, 20));
2777
+ }
2362
2778
  try {
2363
2779
  const persisted = readRunRecord(runId, resolvedDeps);
2364
2780
  reservation.associate({ runId, pid: proc.pid, processStartedAt: persisted?.processStartedAt });
@@ -2383,6 +2799,8 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
2383
2799
  logPath,
2384
2800
  queuePath,
2385
2801
  batchId,
2802
+ agentName: record.agentName ?? shortAgentKey(input.agentKey),
2803
+ ...input.selectionCheck ? { selectionCheck: input.selectionCheck } : {},
2386
2804
  ...hostMemoryNotice ? { hostMemoryNotice } : {}
2387
2805
  };
2388
2806
  }
@@ -2491,8 +2909,31 @@ function transitionRunToTerminal(runId, update, deps = {}, options = {}) {
2491
2909
  if (typeof update.lastAssistantText === "string" && update.lastAssistantText) {
2492
2910
  record2.lastAssistantText = update.lastAssistantText.slice(0, 2e3);
2493
2911
  }
2912
+ if (update.cacheUsage) {
2913
+ record2.cacheHitRatio = update.cacheUsage.cache_hit_ratio;
2914
+ record2.cacheCachedTokens = update.cacheUsage.cached_tokens;
2915
+ }
2494
2916
  record2.endedAt = now().toISOString();
2495
- if (typeof update.lastAssistantText === "string" && update.lastAssistantText) {
2917
+ let resultWriteFailed = false;
2918
+ let pendingResultFile;
2919
+ let stagingComplete = false;
2920
+ let backupFile;
2921
+ let backupVerified = false;
2922
+ const registerArtifact = (path, kind) => {
2923
+ const fs = deps.fs ?? nodeFs2;
2924
+ const stat = fs.lstatSync?.(path);
2925
+ if (!stat || !stat.isFile() || stat.isSymbolicLink()) return;
2926
+ const artifact = {
2927
+ publisher: "run-result-v1",
2928
+ path,
2929
+ kind,
2930
+ dev: String(stat.dev),
2931
+ ino: String(stat.ino),
2932
+ sha256: createHash("sha256").update(fs.readFileSync(path)).digest("hex")
2933
+ };
2934
+ record2.resultArtifacts = [...(record2.resultArtifacts ?? []).filter((a) => a.path !== path), artifact];
2935
+ };
2936
+ if (typeof update.lastAssistantText === "string" && update.lastAssistantText || update.acceptance?.checks.observations?.length) {
2496
2937
  try {
2497
2938
  const fs = deps.fs ?? nodeFs2;
2498
2939
  const resultFile = join2(resolveRunsDir(deps.env, deps.homedir), `${runId}.result.md`);
@@ -2501,6 +2942,7 @@ function transitionRunToTerminal(runId, update, deps = {}, options = {}) {
2501
2942
  const content = buildResultFileContent(
2502
2943
  {
2503
2944
  runId,
2945
+ acceptance: update.acceptance,
2504
2946
  status: record2.status,
2505
2947
  agentName: record2.agentName,
2506
2948
  model: update.model,
@@ -2515,16 +2957,54 @@ function transitionRunToTerminal(runId, update, deps = {}, options = {}) {
2515
2957
  continuedFrom: record2.continuedFrom,
2516
2958
  ...update.cacheUsage ? { cacheUsage: update.cacheUsage } : {}
2517
2959
  },
2518
- update.lastAssistantText
2960
+ update.lastAssistantText ?? ""
2519
2961
  );
2520
- fs.writeFileSync(resultFile, content, "utf8");
2962
+ if (typeof fs.renameSync !== "function") throw new Error("atomic result publication requires renameSync");
2963
+ pendingResultFile = `${resultFile}.${randomUUID2()}.pending`;
2964
+ try {
2965
+ fs.writeFileSync(pendingResultFile, content, { encoding: "utf8", flag: "wx" });
2966
+ stagingComplete = true;
2967
+ } finally {
2968
+ if (fs.existsSync(pendingResultFile)) registerArtifact(pendingResultFile, "pending");
2969
+ }
2970
+ if (fs.existsSync(resultFile)) {
2971
+ const previous = fs.readFileSync(resultFile);
2972
+ const backup = `${resultFile}.${randomUUID2()}.bak`;
2973
+ backupFile = backup;
2974
+ try {
2975
+ fs.writeFileSync(backup, previous, { flag: "wx" });
2976
+ } finally {
2977
+ if (fs.existsSync(backup)) registerArtifact(backup, "bak");
2978
+ }
2979
+ const sameBytes = (a, b) => Buffer.from(a).equals(Buffer.from(b));
2980
+ if (!sameBytes(previous, fs.readFileSync(backup)) || !sameBytes(previous, fs.readFileSync(resultFile))) {
2981
+ throw new Error("previous result backup verification failed");
2982
+ }
2983
+ backupVerified = true;
2984
+ }
2985
+ fs.renameSync(pendingResultFile, resultFile);
2986
+ record2.resultArtifacts = record2.resultArtifacts?.filter((a) => a.path !== pendingResultFile);
2987
+ pendingResultFile = void 0;
2521
2988
  record2.resultFile = resultFile;
2522
2989
  } catch {
2990
+ resultWriteFailed = true;
2991
+ delete record2.resultFile;
2992
+ if (record2.status === "done") {
2993
+ record2.status = "failed";
2994
+ record2.exitCode = 1;
2995
+ }
2523
2996
  }
2524
2997
  }
2525
2998
  if (typeof update.note === "string" && update.note.trim()) {
2526
2999
  record2.note = update.note.trim();
2527
3000
  }
3001
+ if (resultWriteFailed) {
3002
+ if (record2.note?.startsWith("orphaned:")) record2.note = void 0;
3003
+ const fs = deps.fs ?? nodeFs2;
3004
+ const stagingNote = pendingResultFile ? fs.existsSync(pendingResultFile) ? `${stagingComplete ? "complete staging copy" : "incomplete staging fragment"}: ${pendingResultFile}` : `staging not created: ${pendingResultFile}` : "staging not created";
3005
+ const backupNote = backupFile ? `${fs.existsSync(backupFile) ? backupVerified ? "full verified backup" : "partial backup" : "backup not created"}: ${backupFile}` : "backup not created";
3006
+ record2.note = [record2.note, `result file write failed; complete final report was not saved; ${stagingNote}; ${backupNote}`].filter(Boolean).join("; ");
3007
+ }
2528
3008
  if (record2.note?.startsWith("orphaned:")) record2.note = void 0;
2529
3009
  writeRunRecord(record2, deps);
2530
3010
  return { kind: "transitioned", record: record2 };
@@ -2600,10 +3080,10 @@ function defaultGetProcessStartTime(pid, deps = {}) {
2600
3080
  // 这会让 isPidReused 的结论依赖调用者环境:同一条 run 记录在英文
2601
3081
  // locale 下被判 pid reused → orphaned,中文 locale 下不判。强制 C
2602
3082
  // locale 让输出恒为可解析的英文格式,结果与 locale 无关。
2603
- env: { ...process.env, LC_ALL: "C", LANG: "C" }
3083
+ env: { ...process.env, LC_ALL: "C", LANG: "C", TZ: "UTC" }
2604
3084
  }).trim();
2605
3085
  if (!output) return null;
2606
- const d = new Date(output);
3086
+ const d = new Date(output.endsWith("Z") || /[+-]\d\d:\d\d$/.test(output) ? output : `${output} UTC`);
2607
3087
  return isNaN(d.getTime()) ? null : d;
2608
3088
  } catch {
2609
3089
  return null;
@@ -2655,6 +3135,7 @@ function checkStaleRun(runId, deps = {}) {
2655
3135
  const latest = readRunRecord(runId, deps);
2656
3136
  if (!latest) return record;
2657
3137
  if (latest.status !== "running") return latest;
3138
+ if (latest.pid !== record.pid || latest.processStartedAt !== record.processStartedAt || latest.processIdentity !== record.processIdentity) return latest;
2658
3139
  if (latest.activity?.updatedAt !== record.activity?.updatedAt) return latest;
2659
3140
  const at = now().toISOString();
2660
3141
  latest.status = "orphaned";
@@ -2670,6 +3151,16 @@ function checkStaleRun(runId, deps = {}) {
2670
3151
  }
2671
3152
  latest.endedAt = at;
2672
3153
  latest.reconciledAt = at;
3154
+ if ((pidGone || pidReused) && latest.localWriterClaim?.state === "held") {
3155
+ latest.localWriterClaim.state = "released";
3156
+ }
3157
+ latest.ownerDeath = {
3158
+ pid: latest.pid,
3159
+ processStartedAt: latest.processStartedAt,
3160
+ processIdentity: latest.processIdentity,
3161
+ ...latest.execution?.state === "known" ? { executionOwner: latest.execution.owner } : {},
3162
+ confirmedAt: at
3163
+ };
2673
3164
  latest.pid = void 0;
2674
3165
  writeRunRecord(latest, deps);
2675
3166
  return latest;
@@ -2840,6 +3331,7 @@ async function runAgentStatusCommand(args, deps) {
2840
3331
  const { partialCheckpoint, ...summary } = record;
2841
3332
  deps.output.write(JSON.stringify({
2842
3333
  ...summary,
3334
+ ...localWriterRecovery(record) ? { writerRecovery: localWriterRecovery(record) } : {},
2843
3335
  ...includeCheckpoint ? { checkpoint: partialCheckpoint ? { ...partialCheckpoint, available: true } : { available: false, final: false, reason: "checkpoint_missing" } } : {}
2844
3336
  }) + "\n");
2845
3337
  return 0;
@@ -2874,6 +3366,9 @@ function printStatusOnce(record, deps) {
2874
3366
  deps.output.write(`status: ${record.status}
2875
3367
  `);
2876
3368
  deps.output.write(`pid: ${record.pid ?? "-"}
3369
+ `);
3370
+ const recovery = localWriterRecovery(record);
3371
+ if (recovery) deps.output.write(`writerRecovery: required (${recovery.reason}); automatic release forbidden; native launch evidence required
2877
3372
  `);
2878
3373
  deps.output.write(`agent: ${record.agentKey}
2879
3374
  `);
@@ -3131,16 +3626,28 @@ async function runAgentStopCommand(args, deps) {
3131
3626
  async function runAgentKillCommand(args, deps) {
3132
3627
  return runSignalCommand(args, "SIGKILL", "kill", deps);
3133
3628
  }
3629
+ async function runAgentRecoverPreparedWriterCommand(args, deps) {
3630
+ if (args.length !== 3 || args[1] !== "--attempt-id" || !/^[A-Za-z0-9_-]+$/.test(args[0] ?? "") || !args[2] || args[2].startsWith("-")) {
3631
+ deps.output.write("Usage: nolo agent recover-prepared-writer <runId> --attempt-id <attemptId>\n");
3632
+ return 1;
3633
+ }
3634
+ const [runId, , attemptId] = args;
3635
+ const outcome = revokePreparedWriterLaunch(runId, attemptId, deps);
3636
+ deps.output.write(JSON.stringify({ action: "recoverPreparedWriter", runId, attemptId, outcome }) + "\n");
3637
+ return outcome === "blocked" ? 1 : 0;
3638
+ }
3134
3639
 
3135
3640
  export {
3136
- TAIL_LINES_MAX,
3137
3641
  createShellApprovalChild,
3642
+ TAIL_LINES_MAX,
3138
3643
  readHostMemory,
3139
3644
  assertHostMemoryAdmission,
3140
3645
  resolveResultServerMeta,
3141
3646
  recordRunResultHeaderMeta,
3142
3647
  getRunResultHeaderMeta,
3143
3648
  serverOriginForDialog,
3649
+ stripResultFrontMatter,
3650
+ isHistoryIntegrityFailure,
3144
3651
  RUN_TERMINAL_STATUSES,
3145
3652
  isRunTerminalStatus,
3146
3653
  resolveNoloHome,
@@ -3188,6 +3695,12 @@ export {
3188
3695
  absolutizeSkillArgs,
3189
3696
  rewriteMsgFileArg,
3190
3697
  buildAgentRunChildCommand,
3698
+ localWriterRecovery,
3699
+ revokePreparedWriterLaunch,
3700
+ validateLocalWriterChild,
3701
+ awaitLocalWriterChild,
3702
+ resolveLocalContinuation,
3703
+ registerLocalForegroundWriter,
3191
3704
  spawnLocalBackgroundRun,
3192
3705
  ackRunRecord,
3193
3706
  DEFAULT_ACK_LEASE_TTL_MS,
@@ -3215,5 +3728,6 @@ export {
3215
3728
  TERMINATE_KILL_GRACE_MS,
3216
3729
  terminateRunProcess,
3217
3730
  runAgentStopCommand,
3218
- runAgentKillCommand
3731
+ runAgentKillCommand,
3732
+ runAgentRecoverPreparedWriterCommand
3219
3733
  };