nolo-cli 0.213.0 → 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 (262) hide show
  1. package/README.md +3 -2
  2. package/{_executeModel-CUJLCFWR.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-WERAONNY.js → addContentAction-GDHDOF4U.js} +18 -17
  6. package/{addDialogAgentAction-7VI7YRML.js → addDialogAgentAction-CAKRU3ZT.js} +21 -20
  7. package/{agentDeleteCommand-XJORXPGU.js → agentDeleteCommand-BPV2XZL7.js} +128 -119
  8. package/{agentEmailCommands-XTYYFR6Z.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-OBLRBLHS.js → agentListCommands-HIZODBF3.js} +155 -92
  12. package/{agentMachineCommands-5FMT3OT5.js → agentMachineCommands-ZMQ2CY7Y.js} +62 -54
  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-TAMHJQSR.js → agentRunControl-JNONH3RP.js} +30 -15
  18. package/{agentRuntimeLocal-SOO2OPJG.js → agentRuntimeLocal-QZPFWMLG.js} +52 -45
  19. package/{agentSlice-CHR6KOZN.js → agentSlice-RD2CDU7T.js} +20 -19
  20. package/{appDeleteCommands-GUP6P5YE.js → appDeleteCommands-QCCFDIEQ.js} +61 -53
  21. package/{appDeployCommands-MH2FX4O5.js → appDeployCommands-V2T7TNMQ.js} +61 -53
  22. package/{appDeployStatusCommands-SUHN3HPJ.js → appDeployStatusCommands-6PGH7ZCG.js} +61 -53
  23. package/{appGetCommands-YWDEX6Z4.js → appGetCommands-3L7WWJA6.js} +61 -53
  24. package/{appListCommands-ZQVMLPAY.js → appListCommands-ENJCK4PO.js} +61 -53
  25. package/{authCommand-PWX2ZNUP.js → authCommand-6V47SYGK.js} +29 -28
  26. package/{authCommands-HV3EAU3V.js → authCommands-GAJ3NIXO.js} +14 -13
  27. package/{builtinSkillRegistry-2QETTQPM.js → builtinSkillRegistry-2ECA42FC.js} +11 -13
  28. package/{chromeCommands-REEAH4SX.js → chromeCommands-G5UDKVSV.js} +3 -3
  29. package/{chromeOpsCommands-DIVM2K3T.js → chromeOpsCommands-YKX2QX3A.js} +20 -10
  30. package/{chunk-CRHOO2ZR.js → chunk-27PCUMJI.js} +2 -2
  31. package/chunk-2CI3ZFWD.js +97 -0
  32. package/{chunk-NSAPDIN2.js → chunk-2GJKRKI6.js} +541 -31
  33. package/{chunk-SM3NSZJV.js → chunk-2UCBGYO4.js} +20 -1
  34. package/{chunk-PYRUW7XN.js → chunk-2VUZSVAS.js} +136 -54
  35. package/{chunk-YB3YZK56.js → chunk-2WZXXAQD.js} +1 -67
  36. package/chunk-2YGBI2XB.js +30 -0
  37. package/chunk-2ZKFCIJJ.js +13 -0
  38. package/{chunk-QG4AOSON.js → chunk-34J5K2YA.js} +13 -32
  39. package/{chunk-LOEO7LRC.js → chunk-3IK6ILVW.js} +4 -1
  40. package/{chunk-CTPXME7U.js → chunk-3LMUPOHG.js} +29 -6
  41. package/chunk-44X52WOJ.js +1621 -0
  42. package/{chunk-6VLJ6YA7.js → chunk-4DESLZTK.js} +9 -9
  43. package/{chunk-MYOH447Z.js → chunk-4JVNURX4.js} +1 -1
  44. package/chunk-5CHGAKRT.js +364 -0
  45. package/{chunk-YDH3FDFQ.js → chunk-5FUN7EG4.js} +1 -1
  46. package/{chunk-INUFILG6.js → chunk-5RKUPJYL.js} +1 -1
  47. package/{chunk-ZC3CMUKU.js → chunk-6OVNSQHN.js} +84 -2
  48. package/{chunk-MOIJOHA5.js → chunk-6WU5572L.js} +36 -25
  49. package/{chunk-IXNGOHV5.js → chunk-7EEZJ6BS.js} +11 -152
  50. package/{chunk-Y6ORVLSS.js → chunk-7ET2U67U.js} +1 -1
  51. package/{chunk-G7MLNNEX.js → chunk-7JLY4WYF.js} +5 -5
  52. package/{chunk-P5L7CXOC.js → chunk-7Z6EW7AH.js} +3 -2
  53. package/{chunk-NJLL224W.js → chunk-AD5EWDFD.js} +2 -2
  54. package/{chunk-J2NHJ7WX.js → chunk-AIHYNKGV.js} +4 -4
  55. package/{chunk-HPFCI4SK.js → chunk-AK5O76CC.js} +3 -3
  56. package/{chunk-Y63ZSOR6.js → chunk-AL3TYDIF.js} +1 -1
  57. package/{chunk-ALQ3657A.js → chunk-AMEOV5VZ.js} +32 -12
  58. package/chunk-AN74ON4G.js +675 -0
  59. package/{chunk-HRMJUN5J.js → chunk-AQZ6BMRK.js} +1 -1
  60. package/{chunk-XHQC4PXX.js → chunk-B4GOW4MT.js} +424 -194
  61. package/{chunk-4KB6WQUL.js → chunk-BGP2EDFG.js} +1 -1
  62. package/{chunk-NBTY7YJF.js → chunk-BR3GT6MR.js} +1 -0
  63. package/{chunk-7RFNTILS.js → chunk-BUDVRYES.js} +2 -2
  64. package/{chunk-SVYO6AO7.js → chunk-BV3FLP2L.js} +41 -1
  65. package/{chunk-RZOV7OMV.js → chunk-C4VAR65S.js} +83 -141
  66. package/{chunk-COFEN36Z.js → chunk-C4WTX5TU.js} +2 -2
  67. package/{chunk-ZL5RAEEB.js → chunk-CIRB724Q.js} +1 -1
  68. package/{chunk-F6UUQOG6.js → chunk-CKT6QUE2.js} +4 -4
  69. package/{chunk-X7SDOJUM.js → chunk-CMZ3Z5PT.js} +14 -14
  70. package/{secretCommands-LXDWOLZ6.js → chunk-D726I5AZ.js} +191 -16
  71. package/{chunk-TAKB25RM.js → chunk-DNKTQ3IN.js} +4 -4
  72. package/chunk-DVQH4BTR.js +1137 -0
  73. package/{chunk-WYDI6TGM.js → chunk-DWX2HEVC.js} +91 -132
  74. package/{chunk-5MQRBSMW.js → chunk-EIAI3PPH.js} +111 -113
  75. package/chunk-EUCFKKDM.js +247 -0
  76. package/chunk-EWQ3HGNZ.js +90 -0
  77. package/{chunk-RPQXPZZF.js → chunk-F3GRJO4Z.js} +908 -13
  78. package/{chunk-YTF4WH7J.js → chunk-FIYSMXHY.js} +1 -1
  79. package/{chunk-75XIDFBW.js → chunk-FJ23FZXF.js} +72 -28
  80. package/{chunk-INN4LTAJ.js → chunk-FJK526XH.js} +2 -2
  81. package/chunk-FS2XP5D7.js +142 -0
  82. package/{chunk-FUGMREBO.js → chunk-FYF2TONJ.js} +5 -5
  83. package/{chunk-PCLE46CE.js → chunk-GBWGPTA7.js} +2 -1
  84. package/{chunk-TX5EYMGT.js → chunk-GYVCJABP.js} +30 -254
  85. package/{chunk-3UKL3HPD.js → chunk-HOCHUZQ7.js} +8 -78
  86. package/{chunk-EHSZD5OI.js → chunk-HXER7YJF.js} +4 -4
  87. package/chunk-HYIETXA6.js +99 -0
  88. package/{chunk-H2TJUNCH.js → chunk-I4EADJ4P.js} +6 -6
  89. package/{chunk-TCZHTTUU.js → chunk-I7WBYGBP.js} +8 -8
  90. package/{chunk-6DWMYIUY.js → chunk-IILMY4W4.js} +14 -9
  91. package/chunk-JA3ICVJY.js +271 -0
  92. package/{chunk-ZRSNONOB.js → chunk-JWXITTQB.js} +8 -3
  93. package/{chunk-H4UOTUOX.js → chunk-KEN3N2TN.js} +148 -18
  94. package/{chunk-LEC5ALIN.js → chunk-KEPOVMF4.js} +1 -1
  95. package/{chunk-UHJGXRJ4.js → chunk-KQSYAIZR.js} +3 -3
  96. package/{chunk-4VJAC32I.js → chunk-L5I543VB.js} +3 -2
  97. package/chunk-LKA64WH4.js +227 -0
  98. package/{chunk-QHPRUL4O.js → chunk-LVL6GFCM.js} +4 -4
  99. package/{chunk-H5HF7TJA.js → chunk-MAIITKBT.js} +2 -2
  100. package/chunk-MBG66ZBH.js +226 -0
  101. package/{chunk-YUA6OAH5.js → chunk-MDLS23JK.js} +2 -2
  102. package/{chunk-VL5KOY2C.js → chunk-MK2Q7ZJD.js} +67 -5
  103. package/{chunk-MDB67IWP.js → chunk-MS4NZNKI.js} +10 -10
  104. package/{chunk-VO4WSAVP.js → chunk-MYHNBEXD.js} +3 -3
  105. package/{chunk-ZXOUUDCG.js → chunk-MZLE5HQ3.js} +3654 -231
  106. package/{chunk-AZMYUSVF.js → chunk-N5Z2V73W.js} +1 -1
  107. package/{chunk-V5Y3R6BT.js → chunk-NIZ2BXFD.js} +213 -210
  108. package/{chunk-KFLT5KAD.js → chunk-NWP2OYOX.js} +20 -20
  109. package/{chunk-G2BQWAVT.js → chunk-O6J3OTOP.js} +4 -4
  110. package/{chunk-VNYYOX3V.js → chunk-OB6DVWPF.js} +141 -48
  111. package/{chunk-YWSEPJ7C.js → chunk-OBWT45ZU.js} +3 -3
  112. package/{chunk-ZNWI6OVT.js → chunk-ODJ7BVSI.js} +80 -11
  113. package/{chunk-XJWWBO34.js → chunk-OJKUU3LP.js} +5 -7
  114. package/{chunk-HUBHAQK2.js → chunk-ON37YXGX.js} +29 -29
  115. package/{chunk-UYD5HQ6T.js → chunk-P5ZJRTCH.js} +5429 -1752
  116. package/{chunk-6XIE5ZGI.js → chunk-PDCV7P5W.js} +1 -1
  117. package/{chunk-WRYQ35LQ.js → chunk-PJCIP64Z.js} +859 -57
  118. package/{chunk-7QTZCMKL.js → chunk-PJVKMGPZ.js} +1089 -1639
  119. package/{chunk-A7TFUNZO.js → chunk-PPJYZRSQ.js} +6 -2
  120. package/chunk-QHEN7NZ7.js +46 -0
  121. package/{chunk-OQPKUBPB.js → chunk-QNWG52I4.js} +19 -7
  122. package/{chunk-YGILMZ7N.js → chunk-QVBXJNZ2.js} +1 -1
  123. package/{chunk-7BT37FK3.js → chunk-RDH5CQ4T.js} +648 -131
  124. package/{chunk-C6KNNXWU.js → chunk-RGQ4UUWZ.js} +25 -2
  125. package/{chunk-OWYYDMGJ.js → chunk-S2NTVGA2.js} +4 -2
  126. package/{chunk-KC4XDTT3.js → chunk-SOF4OWDM.js} +6 -4
  127. package/{chunk-RLBNLZVC.js → chunk-SQYIK6HO.js} +1 -1
  128. package/{chunk-YJAFKXMU.js → chunk-SVT62ULE.js} +50 -48
  129. package/{chunk-KIM6CLW5.js → chunk-SY3C4SQ7.js} +42 -15
  130. package/{chunk-JY5NGFFH.js → chunk-SYTHYBMI.js} +5 -5
  131. package/{chunk-WMTBPBMP.js → chunk-T6DXNI6Z.js} +52 -50
  132. package/chunk-TLE77UJ5.js +230 -0
  133. package/{chunk-4VNS5WPM.js → chunk-U67V476Y.js} +1 -8
  134. package/{chunk-F7CI2ZC5.js → chunk-UAIHKQIA.js} +2 -1
  135. package/{chunk-R5O4QAWG.js → chunk-UB3D4TRQ.js} +11 -77
  136. package/{chunk-WPORQFYN.js → chunk-UVLYNWIE.js} +2 -2
  137. package/{chunk-NOKUNJON.js → chunk-UYOICCYG.js} +29 -19
  138. package/{chunk-4I7ERB7F.js → chunk-VREDDN25.js} +1 -1
  139. package/{chunk-O2TZF4AI.js → chunk-WAE3GFCJ.js} +3 -3
  140. package/{chunk-H7PPIYWP.js → chunk-WI67URFP.js} +20 -20
  141. package/{chunk-7OCO4TDT.js → chunk-WJVYAO6P.js} +1 -1
  142. package/{chunk-T43B7LB2.js → chunk-WKGQSYTB.js} +1 -1
  143. package/{chunk-BBJ22CLB.js → chunk-WUUH4LWZ.js} +60 -30
  144. package/{chunk-4T2WNOY7.js → chunk-X7UF53VA.js} +33 -22
  145. package/{chunk-TY3TIUJK.js → chunk-XI2BWJM5.js} +65 -0
  146. package/{chunk-LLRPJECG.js → chunk-XWVCYUUU.js} +16 -159
  147. package/{chunk-J5JTMQIA.js → chunk-YFLVRVYK.js} +1 -1
  148. package/{chunk-EYLGAEB4.js → chunk-YGMBIXCF.js} +132 -0
  149. package/chunk-YL3EFYL3.js +199 -0
  150. package/{chunk-MMA3LZ3W.js → chunk-YNIYE47Z.js} +1 -1
  151. package/{chunk-W4S457LU.js → chunk-YU4ZPWVF.js} +41 -5
  152. package/{chunk-7Y4YTDQF.js → chunk-YWWDC3O7.js} +281 -159
  153. package/chunk-YZMNK53S.js +68 -0
  154. package/{chunk-RSHTSUEG.js → chunk-Z2PITYZN.js} +2060 -602
  155. package/{chunk-FY7F4Q6X.js → chunk-Z4PCXPUE.js} +2 -2
  156. package/{cliAgentConfigHelpers-WJBZQTLW.js → cliAgentConfigHelpers-TKYL43MT.js} +15 -16
  157. package/{cliAuthorityBrokerClient-PM3U6Q6J.js → cliAuthorityBrokerClient-XHH7MH2P.js} +1 -1
  158. package/{cliAuthorityStoreDriver-TKLXNNTG.js → cliAuthorityStoreDriver-6FE3BJNB.js} +1 -1
  159. package/{cliEnvHelpers-BVYTMUPJ.js → cliEnvHelpers-VPSJ4XWC.js} +3 -3
  160. package/{cliExecutor-BWBF2MTI.js → cliExecutor-4MAX3PZL.js} +2 -2
  161. package/cliLocalAgentRecordReader-MHHD4T7R.js +90 -0
  162. package/{commandRegistry-W63CYRZJ.js → commandRegistry-5DA5UP7S.js} +105 -97
  163. package/{contentThunks-U7PL5MQD.js → contentThunks-5GUQ7FWJ.js} +47 -43
  164. package/{cooldownCommands-TIGUHXTD.js → cooldownCommands-X7P5M2V5.js} +5 -4
  165. package/{createAgentAutomationAction-OLBQDD6R.js → createAgentAutomationAction-UCLTHQRI.js} +51 -49
  166. package/{createDialogAction-SVH6B3SB.js → createDialogAction-UPN774AF.js} +46 -48
  167. package/{createPageAction-F4DIWZ2Z.js → createPageAction-JRQ2TA4O.js} +50 -48
  168. package/{cursorProvider-YGGNMVWX.js → cursorProvider-2RACMEMF.js} +1 -1
  169. package/{db-HUCI5R4G.js → db-CS4ZJQKV.js} +1 -1
  170. package/{dbSlice-BVH2YZPQ.js → dbSlice-WNON7TOL.js} +17 -16
  171. package/{deleteFile-5YOEKV4U.js → deleteFile-Q3YDB4ML.js} +9 -9
  172. package/{desktopFolderProjects-SFY5EZS3.js → desktopFolderProjects-4POAMVJN.js} +2 -2
  173. package/{dialogCommands-KHIEPY3M.js → dialogCommands-VRI7VCXH.js} +64 -57
  174. package/dialogNotifyCommand-6TMCX4D2.js +36 -0
  175. package/{dialogSlice-ZCTDV2PZ.js → dialogSlice-LFNVUSAN.js} +42 -40
  176. package/{dialogUsageCommand-7KCPYGHG.js → dialogUsageCommand-HTVPR2CX.js} +11 -10
  177. package/{docCreateCommands-DPMZI7G5.js → docCreateCommands-AMPXMOX3.js} +61 -55
  178. package/{docDeleteCommands-IRQQLUBT.js → docDeleteCommands-I5WFAEHP.js} +63 -57
  179. package/{docReadCommands-LK37XH6L.js → docReadCommands-X53ELNIE.js} +61 -55
  180. package/{docStore-V2KECILA.js → docStore-2VAWVLWH.js} +21 -20
  181. package/{docUpdateCommands-O6T3HJHH.js → docUpdateCommands-6QPNDC7M.js} +64 -58
  182. package/{fetchMessages-NR4KNQLO.js → fetchMessages-TQEUZD7H.js} +8 -7
  183. package/{getPricing-2MNMXEVG.js → getPricing-MB2GBXOK.js} +6 -6
  184. package/{handleSendMessageAction-2PE25WM3.js → handleSendMessageAction-AAJOHXOB.js} +194 -302
  185. package/{hostCredentialCreate-S233UMAP.js → hostCredentialCreate-GLMJ22M6.js} +123 -114
  186. package/index.js +29 -29
  187. package/{keys-BEGDOTRL.js → keys-RWF7UCB4.js} +5 -4
  188. package/legacyMigration-TF4SYJCZ.js +19 -0
  189. package/{lib-5KKIBFIT.js → lib-OT5OTXRU.js} +7087 -6664
  190. package/{localDialogRead-7NNDVVF7.js → localDialogRead-SVTPA5GY.js} +3 -3
  191. package/{localFirstLog-DHNOY2NA.js → localFirstLog-OIETGK66.js} +1 -1
  192. package/localRecall-2J6QPOK2.js +15 -0
  193. package/{localRuntimeAdapter-KY6WXNBR.js → localRuntimeAdapter-BMP57P42.js} +119 -110
  194. package/{localRuntimeAuthority-OYH4AE4G.js → localRuntimeAuthority-IBJAT62G.js} +1 -1
  195. package/{localRuntimeDb-VBIMCWUC.js → localRuntimeDb-N7KHDXS2.js} +2 -2
  196. package/{machineCommands-Q6HA3IXF.js → machineCommands-3MLIAK5Q.js} +128 -119
  197. package/{machineInfo-UKPTZO5Y.js → machineInfo-LWHTEBHJ.js} +1 -1
  198. package/machineWsRunDispatch-FKIGROQF.js +191 -0
  199. package/{memberThunks-7EDJADWU.js → memberThunks-ZGLZ36PK.js} +29 -28
  200. package/{memoryCommands-ASCE5STX.js → memoryCommands-5WC3T66U.js} +4 -4
  201. package/models-ULVWLSQ6.js +9 -0
  202. package/{oauthTokenStore-OEERZFUC.js → oauthTokenStore-RUYNYALS.js} +1 -1
  203. package/{offlineMarxistsAgentCommand-2QTHJCHV.js → offlineMarxistsAgentCommand-4IC3Y4C6.js} +4 -4
  204. package/overlay-THLKYIWY.js +11 -0
  205. package/package.json +2 -2
  206. package/{pdf-U6KSUEZZ.js → pdf-KE3QI2V7.js} +1 -1
  207. package/{processSpawn-ZU5QFM43.js → processSpawn-6GEO77KV.js} +1 -1
  208. package/{profileConfig-KN3N2BLF.js → profileConfig-KOWK4HOG.js} +1 -1
  209. package/{projectArchive-DRTDIMEV.js → projectArchive-HK63GMF4.js} +52 -50
  210. package/{providerPresetApply-YXGV6NXB.js → providerPresetApply-OIFQ73LH.js} +19 -12
  211. package/{providerRegistry-S6UL6UNA.js → providerRegistry-KZ3SDZ3D.js} +10 -10
  212. package/{read-4V2RMG7N.js → read-MRQHJMJ2.js} +10 -10
  213. package/{readDocTool-BH6ATGQO.js → readDocTool-4BGTXTXA.js} +2 -2
  214. package/{readlineWorkspace-2W4WRCOU.js → readlineWorkspace-AKAHSCNY.js} +7982 -6274
  215. package/{removeDialogAgentAction-LYAZGNKW.js → removeDialogAgentAction-B6H7DXFM.js} +23 -22
  216. package/{runAgentClientLoop-J2VQBS2Z.js → runAgentClientLoop-UVAWGEON.js} +81 -79
  217. package/{runtimeDoctorCommands-QAI3MBKQ.js → runtimeDoctorCommands-FW6XKDUG.js} +12 -12
  218. package/{runtimeModeArgs-2Y7BALTO.js → runtimeModeArgs-X7DL7PUN.js} +1 -1
  219. package/secretCommands-LJXOOYA7.js +24 -0
  220. package/{setDialogExtraReferencesAction-OCRPGPYH.js → setDialogExtraReferencesAction-EVCY3TRW.js} +22 -21
  221. package/{setPrimaryDialogAgentAction-HFJDQIBU.js → setPrimaryDialogAgentAction-KPFVPHCJ.js} +23 -22
  222. package/{settingThunks-RAMHMTGM.js → settingThunks-ENOAK2WV.js} +97 -88
  223. package/{skillDiscovery-XKHROSH2.js → skillDiscovery-B5V23AXP.js} +4 -4
  224. package/{skillSummaryMarker-42HKSXYY.js → skillSummaryMarker-62UW7HI7.js} +1 -1
  225. package/{slateToRenderMarkdown-Y5IYN73U.js → slateToRenderMarkdown-R3X74MCX.js} +1 -1
  226. package/{slateUtils-NGV2NMKM.js → slateUtils-ESQAJ6RN.js} +1 -1
  227. package/{spaceCommands-KVJZVKVO.js → spaceCommands-DTTNAS2L.js} +61 -53
  228. package/store-JRVN62NM.js +46 -0
  229. package/{streamAgentChatTurn-GHBMJJ6S.js → streamAgentChatTurn-R5UY25VB.js} +875 -618
  230. package/{switchDialogAgentAction-EBRMW3RA.js → switchDialogAgentAction-SZ44XDRY.js} +21 -20
  231. package/{tableCommands-MP6VFSVT.js → tableCommands-HITDSLHS.js} +10 -10
  232. package/tombstones-FQQMEDOW.js +32 -0
  233. package/{toolApiClient-HGNO53TC.js → toolApiClient-OGQEBQVX.js} +4 -4
  234. package/{tools-EWKCPKMS.js → tools-HWFG6GMJ.js} +75 -74
  235. package/tuiSummaryLlmCaller-HQQZAMYF.js +44 -0
  236. package/{updateCommands-ZQYU6SCI.js → updateCommands-RJVCRSBP.js} +10 -8
  237. package/{updateDialogTitleAction-5GGMBTDF.js → updateDialogTitleAction-KNPOAMVS.js} +48 -46
  238. package/{usageCommand-F4IPVMIZ.js → usageCommand-FWZCB7AM.js} +11 -10
  239. package/{usageRebuildCommand-HAW2AD5N.js → usageRebuildCommand-SP2BLNJU.js} +12 -11
  240. package/userDataMerge-HT2ZVHBJ.js +13 -0
  241. package/{windowsSelfUpdate-257DV2T6.js → windowsSelfUpdate-KERHIAB4.js} +3 -3
  242. package/{workloadLifecycle-4C42SVBD.js → workloadLifecycle-DYNEYHV5.js} +6 -6
  243. package/agentRecordCommands-ZQ7SVYGG.js +0 -167
  244. package/agentRunCommand-WS7IGO2W.js +0 -196
  245. package/chunk-3CGG2PAL.js +0 -594
  246. package/chunk-5XBUWM6I.js +0 -89
  247. package/chunk-CJEIOP3E.js +0 -0
  248. package/chunk-EHGEOAHI.js +0 -636
  249. package/chunk-FW6YHHLI.js +0 -842
  250. package/chunk-GPVRUGGY.js +0 -115
  251. package/chunk-HSVBJRF4.js +0 -339
  252. package/chunk-WJZOQR2J.js +0 -151
  253. package/chunk-ZCWRMUWT.js +0 -89
  254. package/dist-M676ULYG.js +0 -7314
  255. package/machineWsRunDispatch-WWJQ6WR3.js +0 -182
  256. package/models-PJBE6JDV.js +0 -9
  257. package/tuiSummaryLlmCaller-ALQYUUWB.js +0 -189
  258. package/{chunk-WACI5I6V.js → chunk-2THCNKE4.js} +3 -3
  259. package/{chunk-2QHFH3DR.js → chunk-47ITIXO7.js} +6 -6
  260. package/{chunk-GOO6G4PY.js → chunk-CKG3PRZ7.js} +0 -0
  261. package/{chunk-OQHIVPG4.js → chunk-SNBZZPYH.js} +3 -3
  262. package/{chunk-AETZ7AD6.js → chunk-W6RFEDN4.js} +3 -3
@@ -1,21 +1,71 @@
1
- import {
2
- findPotentialSecrets
3
- } from "./chunk-6QDYSCPW.js";
4
1
  import {
5
2
  parsePositiveFiniteNumberOrFallback
6
3
  } from "./chunk-Y5GCAMGP.js";
7
4
  import {
5
+ getReadableCliDb
6
+ } from "./chunk-YFLVRVYK.js";
7
+ import {
8
+ INSTABOX_RUN_CONFIG_ENV,
9
+ attachLocalCommandObservations,
8
10
  buildLocalRunEnv,
11
+ captureLocalRunBase,
12
+ collectHostTaskPlannedWorkspace,
13
+ collectHostTaskWorkspace,
14
+ createCliLocalRuntimeAdapter,
15
+ createHostAuthorExecution,
16
+ detectCurrentMachineId,
17
+ formatLocalRunSummary,
18
+ getOrCreateSharedStore,
19
+ hashInstaboxDeliveryManifest,
20
+ hostTaskEventsRoot,
21
+ inspectLocalRunWorkspace,
22
+ isCliProviderAgentConfig,
23
+ isDockerRuntimeKey,
9
24
  isFullstackCodingAgentRef,
25
+ isInstaboxBillingPolicy,
26
+ isLiveAgentRunObservation,
27
+ isMachineBoundLocalhostCustomProvider,
28
+ isSubtaskRun,
29
+ matchesHostReviewDispatch,
30
+ observeLocalCommandResult,
10
31
  parseAgentRunArgs,
32
+ parseAgentRunEvent,
11
33
  readFlagValue,
34
+ readHostTask,
35
+ readHostTaskAcceptancePlan,
36
+ redactSecrets,
37
+ resolveAuthToken as resolveAuthToken2,
38
+ resolveBoundMachineId,
39
+ resolveFileWriteGateEnabled,
12
40
  resolveRawAgentInput,
13
41
  resolveServerUrl,
42
+ safeAskText,
43
+ settleHostReviewsForScope,
44
+ shouldPrintLocalRunSummary,
45
+ unknownLocalRunAcceptance,
46
+ unknownTaskCompletion,
47
+ validateInstaboxWorkspaceSelection,
48
+ withHostReviewDispatch,
49
+ withholdIfSecretLike,
50
+ wrapLocalCommandWorkspaceObservation,
14
51
  writeUsage
15
- } from "./chunk-HSVBJRF4.js";
52
+ } from "./chunk-P5ZJRTCH.js";
16
53
  import {
17
- getReadableCliDb
18
- } from "./chunk-J5JTMQIA.js";
54
+ clearCredentialAvailability,
55
+ readEffectiveCredentialEntry
56
+ } from "./chunk-FIYSMXHY.js";
57
+ import {
58
+ readDbRecord,
59
+ resolveAgentRecordFromHybridStore
60
+ } from "./chunk-6WU5572L.js";
61
+ import {
62
+ boxGlyphs,
63
+ displayWidth,
64
+ resolveBoxCharset,
65
+ stripAnsi,
66
+ tokenizeAnsiLine,
67
+ visibleWidth
68
+ } from "./chunk-F3GRJO4Z.js";
19
69
  import {
20
70
  _appendEntityBatch,
21
71
  _appendEvidenceBatch,
@@ -29,58 +79,43 @@ import {
29
79
  listMemoryStatesForEntityVNext,
30
80
  loadMemoryVNextCatalog,
31
81
  putMemoryEvidenceVNext
32
- } from "./chunk-TY3TIUJK.js";
82
+ } from "./chunk-XI2BWJM5.js";
33
83
  import {
34
- resolveMachineId
35
- } from "./chunk-S73EPYNC.js";
84
+ rankMemoryCandidates,
85
+ recallMemoryVNextLocal
86
+ } from "./chunk-YL3EFYL3.js";
36
87
  import {
37
- INSTABOX_RUN_CONFIG_ENV,
38
- createCliLocalRuntimeAdapter,
39
- detectCurrentMachineId,
40
- hashInstaboxDeliveryManifest,
41
- isCliProviderAgentConfig,
42
- isDockerRuntimeKey,
43
- isInstaboxBillingPolicy,
44
- isLiveAgentRunObservation,
45
- isMachineBoundLocalhostCustomProvider,
46
- isSubtaskRun,
47
- parseAgentRunEvent,
48
- resolveAuthToken as resolveAuthToken2,
49
- resolveBoundMachineId,
50
- resolveFileWriteGateEnabled,
51
- validateInstaboxWorkspaceSelection
52
- } from "./chunk-UYD5HQ6T.js";
88
+ DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET,
89
+ EXPLICIT_REMEMBER_PREFIX_REGEX,
90
+ buildMemoryOverlay
91
+ } from "./chunk-EUCFKKDM.js";
53
92
  import {
54
- clearCredentialAvailability,
55
- readEffectiveCredentialEntry
56
- } from "./chunk-YTF4WH7J.js";
57
- import {
58
- readDbRecord,
59
- resolveAgentRecordFromHybridStore
60
- } from "./chunk-MOIJOHA5.js";
93
+ buildLegacyMemoryEvidence,
94
+ resolveLegacyMemoryPrincipal
95
+ } from "./chunk-QHEN7NZ7.js";
61
96
  import {
62
97
  isBuiltinNoloAgentRef,
63
98
  resolveLocalUserId
64
- } from "./chunk-G7MLNNEX.js";
65
- import {
66
- isLocalCliAgentKey
67
- } from "./chunk-NBTY7YJF.js";
99
+ } from "./chunk-7JLY4WYF.js";
68
100
  import {
69
101
  CliProviderQuotaError
70
- } from "./chunk-VL5KOY2C.js";
102
+ } from "./chunk-MK2Q7ZJD.js";
103
+ import {
104
+ resolveMachineId
105
+ } from "./chunk-S73EPYNC.js";
106
+ import {
107
+ extractGoogleValidationLink
108
+ } from "./chunk-BMQ2MJUK.js";
71
109
  import {
72
110
  resolveCliLocalRuntimeKeyCapability
73
- } from "./chunk-XHQC4PXX.js";
111
+ } from "./chunk-B4GOW4MT.js";
74
112
  import {
75
113
  isTransientFetchError
76
114
  } from "./chunk-KFHREHUQ.js";
77
- import {
78
- extractGoogleValidationLink
79
- } from "./chunk-BMQ2MJUK.js";
80
115
  import {
81
116
  parseUiCard,
82
117
  uiCardFallback
83
- } from "./chunk-HUBHAQK2.js";
118
+ } from "./chunk-ON37YXGX.js";
84
119
  import {
85
120
  isGatewayHttpStatus
86
121
  } from "./chunk-NF64D32W.js";
@@ -89,15 +124,17 @@ import {
89
124
  chooseMemoryOwners,
90
125
  loadMemoryCandidatesFromDb,
91
126
  resolveAgentMemoryPolicy
92
- } from "./chunk-LLRPJECG.js";
127
+ } from "./chunk-XWVCYUUU.js";
93
128
  import {
94
129
  API_REPORTED_COST_MULTIPLIER,
95
130
  estimateMessagesTokens,
131
+ isAgentRunStartFailureStatus,
132
+ isAgentRunStatusNormal,
96
133
  parseUiAskChoiceContent,
97
134
  resolveAgentContextWindow,
98
135
  resolveOccupancy,
99
136
  resolveOccupancyWindow
100
- } from "./chunk-ZXOUUDCG.js";
137
+ } from "./chunk-MZLE5HQ3.js";
101
138
  import {
102
139
  isCliAuthorityBrokerProtocolError,
103
140
  isCliAuthorityBrokerTimeoutError,
@@ -105,52 +142,43 @@ import {
105
142
  } from "./chunk-5ZMIIR23.js";
106
143
  import {
107
144
  getDefaultCliLocalRuntimeDb
108
- } from "./chunk-AZMYUSVF.js";
109
- import {
110
- buildSkillDiscoveryContextLayer
111
- } from "./chunk-F6UUQOG6.js";
145
+ } from "./chunk-N5Z2V73W.js";
112
146
  import {
113
- parseExternalSkillMarkdown,
114
- parseSkillDocProtocol
115
- } from "./chunk-AETZ7AD6.js";
147
+ isLocalCliAgentKey
148
+ } from "./chunk-BR3GT6MR.js";
116
149
  import {
117
150
  LOCAL_AGENT_CONFIG_MISSING_CODE,
118
151
  LOCAL_TURN_ABORTED_CODE,
152
+ evaluateTaskExecutionContract,
153
+ markCliUserBatchPhase,
119
154
  readActionGate
120
- } from "./chunk-RSHTSUEG.js";
155
+ } from "./chunk-Z2PITYZN.js";
121
156
  import {
122
157
  resolveAgentRuntimeConfigFromRecord
123
- } from "./chunk-W4S457LU.js";
158
+ } from "./chunk-YU4ZPWVF.js";
124
159
  import {
125
160
  createThinkParserState,
126
161
  flushThinkParser,
127
162
  processThinkChunk
128
163
  } from "./chunk-56GBUMO5.js";
129
164
  import {
130
- resolveSubtaskBudgetLimits
131
- } from "./chunk-RZOV7OMV.js";
132
- import {
133
- QUOTA_ERROR_PATTERNS,
134
165
  classifyFailureSubclass,
135
166
  isCapacitySaturatedRateLimit,
136
- isQuotaExhaustedError,
137
167
  isQuotaExhaustedText,
138
168
  resolveAvailabilityAction,
139
169
  resolveCredentialKeyWithFallback
140
- } from "./chunk-3UKL3HPD.js";
170
+ } from "./chunk-HOCHUZQ7.js";
141
171
  import {
142
172
  ATTACHMENT_PART_TYPE,
143
173
  ATTACHMENT_PART_VERSION,
144
174
  describeAttachmentForModel,
145
175
  normalizeAttachmentPart
146
- } from "./chunk-WJZOQR2J.js";
176
+ } from "./chunk-NIZ2BXFD.js";
147
177
  import {
178
+ findCodexOAuthPinnedContextWindow,
148
179
  normalizeUsage,
149
180
  readCacheReadInputTokensOrNull
150
- } from "./chunk-V5Y3R6BT.js";
151
- import {
152
- findCodexOAuthPinnedContextWindow
153
- } from "./chunk-7BT37FK3.js";
181
+ } from "./chunk-RDH5CQ4T.js";
154
182
  import {
155
183
  isOAuthApiKeyRef
156
184
  } from "./chunk-UKZX3NHN.js";
@@ -160,37 +188,65 @@ import {
160
188
  import {
161
189
  normalizeRuntimeToolPolicyOverride,
162
190
  resolveEffectiveRuntimeToolPolicy
163
- } from "./chunk-2QHFH3DR.js";
191
+ } from "./chunk-47ITIXO7.js";
164
192
  import {
165
193
  compactWhitespace
166
194
  } from "./chunk-DWLEOOGR.js";
167
195
  import {
168
- buildAgentsMdLayer,
169
- buildAgentsMdLayerHeader,
170
- buildMemoryOverlayLayer,
171
- buildMemoryUseGuidanceLayer,
172
- partitionScopedBlocks,
173
- renderTurnContextBlocksWithScope
174
- } from "./chunk-ZRSNONOB.js";
196
+ isAntigravityOAuthAgent
197
+ } from "./chunk-SY3C4SQ7.js";
198
+ import {
199
+ parseExternalSkillMarkdown,
200
+ parseSkillDocProtocol
201
+ } from "./chunk-W6RFEDN4.js";
175
202
  import {
176
203
  BUILTIN_NOLO_AGENT_KEY,
177
204
  BUILTIN_NOLO_AGENT_NAME,
178
205
  builtinAgentCatalogEntryById,
179
206
  parseBuiltinPlatformAgentId
180
- } from "./chunk-LOEO7LRC.js";
207
+ } from "./chunk-3IK6ILVW.js";
181
208
  import {
182
209
  parsePublicAgentId
183
210
  } from "./chunk-M2EJHDJP.js";
184
211
  import {
185
- isAntigravityOAuthAgent
186
- } from "./chunk-KIM6CLW5.js";
212
+ createMemoryKey
213
+ } from "./chunk-SYTHYBMI.js";
214
+ import {
215
+ ulid
216
+ } from "./chunk-OJKUU3LP.js";
217
+ import {
218
+ buildSkillDiscoveryContextLayer
219
+ } from "./chunk-CKT6QUE2.js";
220
+ import {
221
+ buildAgentsMdLayer,
222
+ buildAgentsMdLayerHeader,
223
+ buildMemoryOverlayLayer,
224
+ buildMemoryUseGuidanceLayer,
225
+ partitionScopedBlocks,
226
+ renderTurnContextBlocksWithScope
227
+ } from "./chunk-JWXITTQB.js";
228
+ import {
229
+ exitCliFromWatchdog,
230
+ getLogger,
231
+ normalizeError
232
+ } from "./chunk-YGMBIXCF.js";
187
233
  import {
234
+ agentRunCardLabels,
235
+ getCliLocale,
236
+ t,
237
+ toolLabel,
238
+ toolLabelVariants
239
+ } from "./chunk-OB6DVWPF.js";
240
+ import {
241
+ awaitLocalWriterChild,
188
242
  createRunActivityTracker,
189
243
  createShellApprovalChild,
190
244
  getRunResultHeaderMeta,
245
+ isHistoryIntegrityFailure,
191
246
  popSingleQueueMessage,
192
247
  readRunRecord,
193
248
  recordRunResultHeaderMeta,
249
+ registerLocalForegroundWriter,
194
250
  reportRunProcessIdentity,
195
251
  resolveResultServerMeta,
196
252
  resolveRunQueuePath,
@@ -198,7 +254,7 @@ import {
198
254
  serverOriginForDialog,
199
255
  settleRunTerminalAuthoritatively,
200
256
  spawnLocalBackgroundRun
201
- } from "./chunk-NSAPDIN2.js";
257
+ } from "./chunk-2GJKRKI6.js";
202
258
  import {
203
259
  formatAgentListCard,
204
260
  formatFinishedRunCard,
@@ -209,55 +265,41 @@ import {
209
265
  formatStopRunCard,
210
266
  getAgentRunStatusIcon,
211
267
  isAgentRunTerminalStatus
212
- } from "./chunk-ALQ3657A.js";
268
+ } from "./chunk-AMEOV5VZ.js";
213
269
  import {
214
- resolveClientVersion
215
- } from "./chunk-TCZHTTUU.js";
270
+ QUOTA_ERROR_PATTERNS,
271
+ isQuotaExhaustedError
272
+ } from "./chunk-EWQ3HGNZ.js";
216
273
  import {
217
- findModelConfig
218
- } from "./chunk-SM3NSZJV.js";
274
+ resolveClientVersion
275
+ } from "./chunk-I7WBYGBP.js";
219
276
  import {
220
277
  toErrorMessage
221
278
  } from "./chunk-HNMXYYJR.js";
279
+ import {
280
+ asTrimmedString
281
+ } from "./chunk-3EUW3WEO.js";
282
+ import {
283
+ findModelConfig
284
+ } from "./chunk-2UCBGYO4.js";
222
285
  import {
223
286
  CLIENT_VERSION_TOO_OLD_CODE,
224
287
  NOLO_CLIENT_VERSION_HEADER,
225
288
  buildClientVersionUpgradeMessage
226
- } from "./chunk-GOO6G4PY.js";
289
+ } from "./chunk-CKG3PRZ7.js";
227
290
  import {
228
291
  asTrimmedLowercaseString
229
292
  } from "./chunk-QSJ3HFEF.js";
230
- import {
231
- getLogger,
232
- normalizeError
233
- } from "./chunk-EYLGAEB4.js";
234
293
  import {
235
294
  resolveAuthToken
236
- } from "./chunk-WACI5I6V.js";
237
- import {
238
- readPipeText,
239
- spawnProcess
240
- } from "./chunk-4O22PGNQ.js";
241
- import {
242
- agentRunCardLabels,
243
- getCliLocale,
244
- t,
245
- toolLabel,
246
- toolLabelVariants
247
- } from "./chunk-VNYYOX3V.js";
248
- import {
249
- createMemoryKey
250
- } from "./chunk-JY5NGFFH.js";
251
- import {
252
- ulid
253
- } from "./chunk-XJWWBO34.js";
254
- import {
255
- asTrimmedString
256
- } from "./chunk-3EUW3WEO.js";
295
+ } from "./chunk-2THCNKE4.js";
257
296
  import {
258
297
  asOptionalTrimmedString
259
298
  } from "./chunk-G3SUCT4W.js";
260
299
 
300
+ // packages/cli/agentRunCommand.ts
301
+ import { createHash } from "node:crypto";
302
+
261
303
  // packages/cli/client/instaboxRunConfigWrite.ts
262
304
  import { randomUUID } from "node:crypto";
263
305
  import { lstatSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
@@ -400,6 +442,151 @@ function writeInstaboxRunConfig(options) {
400
442
  return { configPath: targetPath, config };
401
443
  }
402
444
 
445
+ // packages/cli/client/contextRefusal.ts
446
+ function contextRefusalDiagnostics(error) {
447
+ return error && typeof error === "object" ? error.diagnostics : void 0;
448
+ }
449
+ var tokens = (value) => value >= 1e3 ? `${Math.round(value / 100) / 10}k` : String(value);
450
+ function describeContextRefusal(refusal) {
451
+ const budgetDetail = refusal && Number.isFinite(refusal.historyTokens) && refusal.historyTokens >= 0 && Number.isFinite(refusal.budget) && refusal.budget > 0 ? t("contextRefusalBudgetDetail", tokens(refusal.historyTokens), tokens(refusal.budget)) : "";
452
+ switch (refusal?.reason) {
453
+ case "summary-provider-busy":
454
+ return t("contextRefusalSummaryBusy", budgetDetail);
455
+ case "summary-failed":
456
+ return t("contextRefusalSummaryFailed", budgetDetail);
457
+ case "no-compactable-content":
458
+ return t("contextRefusalNoCompactableContent");
459
+ case "single-message-too-large":
460
+ if (refusal.largestMessageTokens >= 0 && Number.isFinite(refusal.largestMessageTokens)) {
461
+ return t("contextRefusalSingleMessageTooLarge", tokens(refusal.largestMessageTokens), tokens(refusal.budget));
462
+ }
463
+ }
464
+ return t("contextPreflightBlockedHint");
465
+ }
466
+
467
+ // packages/cli/client/cliBatchIdentity.ts
468
+ function cliBatchPhaseFailure(args) {
469
+ const { phase, batchId, requestStarted, replyPersisted, cause } = args;
470
+ const message = cause instanceof Error ? cause.message : String(cause);
471
+ const error = new Error(
472
+ `cli batch phase ${phase} failed for ${batchId} (requestStarted=${requestStarted}, replyPersisted=${replyPersisted}): ${message}`
473
+ );
474
+ error.code = "cli_batch_phase_failed";
475
+ error.phase = phase;
476
+ error.batchId = batchId;
477
+ error.requestStarted = requestStarted;
478
+ error.replyPersisted = replyPersisted;
479
+ error.cause = cause;
480
+ return error;
481
+ }
482
+ function resolveCliBatchIdentity(options) {
483
+ const batchId = options.cliBatchId?.trim();
484
+ if (!batchId) return void 0;
485
+ const userMessages = options.userMessages;
486
+ if (!userMessages || userMessages.length === 0) {
487
+ throw cliBatchPhaseFailure({
488
+ phase: "requested",
489
+ batchId,
490
+ requestStarted: false,
491
+ replyPersisted: false,
492
+ cause: new Error("batch identity requires userMessages")
493
+ });
494
+ }
495
+ const tailId = userMessages[userMessages.length - 1]?.cliMessageId;
496
+ if (tailId !== batchId) {
497
+ throw cliBatchPhaseFailure({
498
+ phase: "requested",
499
+ batchId,
500
+ requestStarted: false,
501
+ replyPersisted: false,
502
+ cause: new Error(`batch identity mismatch: tail=${tailId ?? "none"}`)
503
+ });
504
+ }
505
+ const messageIds = userMessages.map((message) => message.cliMessageId);
506
+ if (messageIds.some((id) => !id)) {
507
+ throw cliBatchPhaseFailure({
508
+ phase: "requested",
509
+ batchId,
510
+ requestStarted: false,
511
+ replyPersisted: false,
512
+ cause: new Error("batch user message missing cliMessageId")
513
+ });
514
+ }
515
+ return { batchId, messageIds };
516
+ }
517
+
518
+ // packages/cli/client/agentRun.ts
519
+ import { resolve as resolveHostReviewPath } from "node:path";
520
+
521
+ // packages/cli/client/hostTaskBinding.ts
522
+ import { resolve as resolve2 } from "node:path";
523
+ function bindHostTask(args) {
524
+ let latest;
525
+ let completion;
526
+ function load() {
527
+ if (!args.reference) return void 0;
528
+ if (resolve2(args.reference.workspace) !== resolve2(args.workspace) || args.reference.dialogId !== args.dialogId) {
529
+ return { authorization: "unknown", reason: "scope_mismatch" };
530
+ }
531
+ return readHostTask(hostTaskEventsRoot(args.env), args.reference);
532
+ }
533
+ latest = load();
534
+ const contract = args.completionEvidenceProvider && latest && latest.authorization !== "unknown" ? latest.contract : void 0;
535
+ const adapter = !args.reference ? args.adapter : {
536
+ ...args.adapter,
537
+ // Re-read authority before each protected action. A review-only binding owns
538
+ // typed review tools, not ordinary chat tools or their existing permission gates.
539
+ // Explicit completion tasks retain their all-tool stop semantics; unknown scope
540
+ // fails closed. Already running tools are not cancelled by this entry guard.
541
+ executeTool: async (call, opts) => {
542
+ latest = load();
543
+ const authorization = latest?.authorization ?? "unknown";
544
+ const protectedTool = call.name === "requestTaskReview" || call.name === "recordTaskReviewDecision";
545
+ if (authorization !== "active" && (args.completionEvidenceProvider || protectedTool || authorization === "unknown")) {
546
+ const code = authorization === "paused" ? "authorization_paused" : authorization === "revoked" ? "authorization_revoked" : "authorization_unknown";
547
+ throw Object.assign(new Error(`host task authority ${authorization}: tool "${call.name}" was not executed`), { code });
548
+ }
549
+ return args.adapter.executeTool(call, opts);
550
+ },
551
+ saveTurn: async (input) => {
552
+ latest = load();
553
+ const stopped = args.signal?.aborted || input.result.businessCompletion?.reasons.includes("stopped");
554
+ if (args.completionEvidenceProvider) {
555
+ const snapshot = latest && latest.authorization !== "unknown" ? latest.contract : void 0;
556
+ let evidence;
557
+ try {
558
+ evidence = snapshot ? await args.completionEvidenceProvider(snapshot) : void 0;
559
+ } catch {
560
+ }
561
+ latest = load();
562
+ const current = latest && latest.authorization !== "unknown" ? latest.contract : void 0;
563
+ completion = !current || !evidence || evidence.taskId !== current.taskId ? stopped ? { taskId: args.reference.taskId, status: "blocked", reasons: ["stopped"] } : unknownTaskCompletion(args.reference.taskId) : evaluateTaskExecutionContract({ ...evidence, authorization: current.authorization }, {
564
+ stopped,
565
+ executionFailed: input.result.error === true || !!input.result.runtimeProviderFailure || !!input.result.emptyAssistantFallbackReason,
566
+ budgetExhausted: input.result.businessCompletion?.reasons.includes("budget_exhausted")
567
+ });
568
+ }
569
+ const result = { ...input.result };
570
+ delete result.businessCompletion;
571
+ if (completion) result.businessCompletion = completion;
572
+ try {
573
+ return await args.adapter.saveTurn({ ...input, result });
574
+ } catch (error) {
575
+ if (args.completionEvidenceProvider) completion = { taskId: args.reference.taskId, status: "blocked", reasons: ["execution_failed"] };
576
+ throw error;
577
+ }
578
+ }
579
+ };
580
+ return {
581
+ adapter,
582
+ contract,
583
+ result: () => args.reference ? {
584
+ taskAuthorization: latest?.authorization ?? "unknown",
585
+ ...args.completionEvidenceProvider ? { businessCompletion: completion ?? unknownTaskCompletion(args.reference.taskId) } : {}
586
+ } : {}
587
+ };
588
+ }
589
+
403
590
  // packages/agent-runtime/modelLayerOverride.ts
404
591
  var MODEL_LAYER_KEYS = [
405
592
  "provider",
@@ -688,10 +875,10 @@ function platformCreditsFromUsage(usage) {
688
875
  const cost = typeof usage.cost === "number" ? usage.cost : 0;
689
876
  return Number.isFinite(cost) && cost > 0 ? cost : 0;
690
877
  }
691
- function withTurnCredits(tokens, credits) {
692
- if (!tokens) return tokens;
693
- if (credits === void 0) return tokens;
694
- return { ...tokens, credits };
878
+ function withTurnCredits(tokens2, credits) {
879
+ if (!tokens2) return tokens2;
880
+ if (credits === void 0) return tokens2;
881
+ return { ...tokens2, credits };
695
882
  }
696
883
  function formatCreditsChip(credits, options) {
697
884
  return options?.compact ? `\u26A1${credits.toFixed(2)}` : `\u26A1 ${credits.toFixed(2)} \u79EF\u5206`;
@@ -724,10 +911,18 @@ function computeBaselineContextTokens(options) {
724
911
  }
725
912
  return typeof fallbackEstimate === "function" ? fallbackEstimate() : fallbackEstimate;
726
913
  }
914
+ function preserveContextUsageWithoutReceipt(previous, estimatedContextTokens) {
915
+ return {
916
+ turnTokens: previous.turnTokens,
917
+ lastAuthorityTurnCount: previous.lastAuthorityTurnCount,
918
+ estimatedContextTokens,
919
+ liveTurnEstimatedTokens: previous.turnTokens && previous.turnTokens.input > 0 ? Math.max(0, estimatedContextTokens - previous.turnTokens.input) || void 0 : void 0
920
+ };
921
+ }
727
922
  function resolveContextUsage(opts = {}) {
728
- const tokens = opts.tokens;
729
- const contextWindow = tokens?.contextWindow ?? opts.fallbackContextWindow;
730
- const authoritativeInput = tokens && tokens.input > 0 ? tokens.input : void 0;
923
+ const tokens2 = opts.tokens;
924
+ const contextWindow = tokens2?.contextWindow ?? opts.fallbackContextWindow;
925
+ const authoritativeInput = tokens2 && tokens2.input > 0 ? tokens2.input : void 0;
731
926
  const baselineEstimate = opts.estimatedContextTokens != null && opts.estimatedContextTokens > 0 ? opts.estimatedContextTokens : void 0;
732
927
  const generatedSinceAuthority = opts.turnEstimatedTokens != null && opts.turnEstimatedTokens > 0 ? opts.turnEstimatedTokens : void 0;
733
928
  const occupancy = resolveOccupancy({
@@ -746,27 +941,27 @@ function resolveContextUsage(opts = {}) {
746
941
  }
747
942
  return usage;
748
943
  }
749
- function renderTokenStatus(tokens, fallback) {
944
+ function renderTokenStatus(tokens2, fallback) {
750
945
  const usage = resolveContextUsage({
751
- tokens,
946
+ tokens: tokens2,
752
947
  fallbackContextWindow: fallback?.contextWindow,
753
948
  estimatedContextTokens: fallback?.estimatedContextTokens,
754
949
  turnEstimatedTokens: fallback?.turnEstimatedTokens
755
950
  });
756
- const cache = tokens?.cacheRead != null && tokens.cacheRead > 0 ? ` (cache ${formatTokenCount(tokens.cacheRead)})` : "";
951
+ const cache = tokens2?.cacheRead != null && tokens2.cacheRead > 0 ? ` (cache ${formatTokenCount(tokens2.cacheRead)})` : "";
757
952
  if (usage.contextWindow === void 0) {
758
953
  const inStr = usage.used !== void 0 ? `${usage.estimated ? "~" : ""}${formatTokenCount(usage.used)}` : "\u2014";
759
- const outStr = tokens ? formatTokenCount(tokens.output) : "\u2014";
954
+ const outStr = tokens2 ? formatTokenCount(tokens2.output) : "\u2014";
760
955
  return `in ${inStr}${cache} out ${outStr} left \u2014`;
761
956
  }
762
- if (!tokens) {
957
+ if (!tokens2) {
763
958
  if (usage.used === void 0) return "in \u2014 out \u2014 left \u2014";
764
959
  const left2 = usage.left !== void 0 ? `~${formatTokenCount(usage.left)}` : "\u2014";
765
960
  return `in ~${formatTokenCount(usage.used)} out \u2014 left ${left2}`;
766
961
  }
767
- const inputText = tokens.input > 0 || usage.used === void 0 ? formatTokenCount(tokens.input) : `~${formatTokenCount(usage.used)}`;
768
- const left = tokens.remaining != null ? formatTokenCount(tokens.remaining) : usage.left !== void 0 ? `${usage.estimated ? "~" : ""}${formatTokenCount(usage.left)}` : "\u2014";
769
- return `in ${inputText}${cache} out ${formatTokenCount(tokens.output)} left ${left}`;
962
+ const inputText = tokens2.input > 0 || usage.used === void 0 ? formatTokenCount(tokens2.input) : `~${formatTokenCount(usage.used)}`;
963
+ const left = tokens2.remaining != null ? formatTokenCount(tokens2.remaining) : usage.left !== void 0 ? `${usage.estimated ? "~" : ""}${formatTokenCount(usage.left)}` : "\u2014";
964
+ return `in ${inputText}${cache} out ${formatTokenCount(tokens2.output)} left ${left}`;
770
965
  }
771
966
  function shouldShowUsage(env) {
772
967
  return env.NOLO_DEBUG === "1" || env.NOLO_SHOW_USAGE === "1";
@@ -851,754 +1046,6 @@ function formatCliHyperlink(url, label, enabled = resolveCliHyperlinkEnabled())
851
1046
  return `${OSC8_OPEN}${url}${OSC8_CLOSE}${safeLabel}${OSC8_OPEN}${OSC8_CLOSE}`;
852
1047
  }
853
1048
 
854
- // node_modules/ansi-regex/index.js
855
- function ansiRegex({ onlyFirst = false } = {}) {
856
- const ST2 = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
857
- const osc = `(?:\\u001B\\][^\\u0007\\u001B\\u009C]*${ST2})`;
858
- const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
859
- const pattern = `${osc}|${csi}`;
860
- return new RegExp(pattern, onlyFirst ? void 0 : "g");
861
- }
862
-
863
- // node_modules/strip-ansi/index.js
864
- var regex = ansiRegex();
865
- function stripAnsi(string) {
866
- if (typeof string !== "string") {
867
- throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
868
- }
869
- if (!string.includes("\x1B") && !string.includes("\x9B")) {
870
- return string;
871
- }
872
- return string.replace(regex, "");
873
- }
874
-
875
- // node_modules/get-east-asian-width/lookup-data.js
876
- var ambiguousMinimalCodePoint = 161;
877
- var ambiguousMaximumCodePoint = 1114109;
878
- var ambiguousRanges = [161, 161, 164, 164, 167, 168, 170, 170, 173, 174, 176, 180, 182, 186, 188, 191, 198, 198, 208, 208, 215, 216, 222, 225, 230, 230, 232, 234, 236, 237, 240, 240, 242, 243, 247, 250, 252, 252, 254, 254, 257, 257, 273, 273, 275, 275, 283, 283, 294, 295, 299, 299, 305, 307, 312, 312, 319, 322, 324, 324, 328, 331, 333, 333, 338, 339, 358, 359, 363, 363, 462, 462, 464, 464, 466, 466, 468, 468, 470, 470, 472, 472, 474, 474, 476, 476, 593, 593, 609, 609, 708, 708, 711, 711, 713, 715, 717, 717, 720, 720, 728, 731, 733, 733, 735, 735, 768, 879, 913, 929, 931, 937, 945, 961, 963, 969, 1025, 1025, 1040, 1103, 1105, 1105, 8208, 8208, 8211, 8214, 8216, 8217, 8220, 8221, 8224, 8226, 8228, 8231, 8240, 8240, 8242, 8243, 8245, 8245, 8251, 8251, 8254, 8254, 8308, 8308, 8319, 8319, 8321, 8324, 8364, 8364, 8451, 8451, 8453, 8453, 8457, 8457, 8467, 8467, 8470, 8470, 8481, 8482, 8486, 8486, 8491, 8491, 8531, 8532, 8539, 8542, 8544, 8555, 8560, 8569, 8585, 8585, 8592, 8601, 8632, 8633, 8658, 8658, 8660, 8660, 8679, 8679, 8704, 8704, 8706, 8707, 8711, 8712, 8715, 8715, 8719, 8719, 8721, 8721, 8725, 8725, 8730, 8730, 8733, 8736, 8739, 8739, 8741, 8741, 8743, 8748, 8750, 8750, 8756, 8759, 8764, 8765, 8776, 8776, 8780, 8780, 8786, 8786, 8800, 8801, 8804, 8807, 8810, 8811, 8814, 8815, 8834, 8835, 8838, 8839, 8853, 8853, 8857, 8857, 8869, 8869, 8895, 8895, 8978, 8978, 9312, 9449, 9451, 9547, 9552, 9587, 9600, 9615, 9618, 9621, 9632, 9633, 9635, 9641, 9650, 9651, 9654, 9655, 9660, 9661, 9664, 9665, 9670, 9672, 9675, 9675, 9678, 9681, 9698, 9701, 9711, 9711, 9733, 9734, 9737, 9737, 9742, 9743, 9756, 9756, 9758, 9758, 9792, 9792, 9794, 9794, 9824, 9825, 9827, 9829, 9831, 9834, 9836, 9837, 9839, 9839, 9886, 9887, 9919, 9919, 9926, 9933, 9935, 9939, 9941, 9953, 9955, 9955, 9960, 9961, 9963, 9969, 9972, 9972, 9974, 9977, 9979, 9980, 9982, 9983, 10045, 10045, 10102, 10111, 11094, 11097, 12872, 12879, 57344, 63743, 65024, 65039, 65533, 65533, 127232, 127242, 127248, 127277, 127280, 127337, 127344, 127373, 127375, 127376, 127387, 127404, 917760, 917999, 983040, 1048573, 1048576, 1114109];
879
- var fullwidthMinimalCodePoint = 12288;
880
- var fullwidthMaximumCodePoint = 65510;
881
- var fullwidthRanges = [12288, 12288, 65281, 65376, 65504, 65510];
882
- var wideMinimalCodePoint = 4352;
883
- var wideMaximumCodePoint = 262141;
884
- var wideRanges = [4352, 4447, 8986, 8987, 9001, 9002, 9193, 9196, 9200, 9200, 9203, 9203, 9725, 9726, 9748, 9749, 9776, 9783, 9800, 9811, 9855, 9855, 9866, 9871, 9875, 9875, 9889, 9889, 9898, 9899, 9917, 9918, 9924, 9925, 9934, 9934, 9940, 9940, 9962, 9962, 9970, 9971, 9973, 9973, 9978, 9978, 9981, 9981, 9989, 9989, 9994, 9995, 10024, 10024, 10060, 10060, 10062, 10062, 10067, 10069, 10071, 10071, 10133, 10135, 10160, 10160, 10175, 10175, 11035, 11036, 11088, 11088, 11093, 11093, 11904, 11929, 11931, 12019, 12032, 12245, 12272, 12287, 12289, 12350, 12353, 12438, 12441, 12543, 12549, 12591, 12593, 12686, 12688, 12773, 12783, 12830, 12832, 12871, 12880, 42124, 42128, 42182, 43360, 43388, 44032, 55203, 63744, 64255, 65040, 65049, 65072, 65106, 65108, 65126, 65128, 65131, 94176, 94180, 94192, 94198, 94208, 101594, 101631, 101664, 101760, 101874, 101888, 102801, 102816, 102866, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110888, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110952, 110960, 111355, 119552, 119638, 119648, 119670, 126980, 126980, 127183, 127183, 127374, 127374, 127377, 127386, 127406, 127406, 127488, 127490, 127504, 127547, 127552, 127560, 127568, 127569, 127584, 127589, 127744, 127776, 127789, 127797, 127799, 127868, 127870, 127891, 127904, 127946, 127951, 127955, 127968, 127984, 127988, 127988, 127992, 128062, 128064, 128064, 128066, 128252, 128255, 128317, 128331, 128334, 128336, 128359, 128378, 128378, 128405, 128406, 128420, 128420, 128507, 128591, 128640, 128709, 128716, 128716, 128720, 128722, 128725, 128729, 128732, 128735, 128747, 128748, 128756, 128764, 128986, 128986, 128992, 129003, 129008, 129008, 129292, 129338, 129340, 129349, 129351, 129535, 129648, 129660, 129664, 129734, 129736, 129736, 129740, 129757, 129759, 129771, 129775, 129786, 131072, 196605, 196608, 262141];
885
-
886
- // node_modules/get-east-asian-width/utilities.js
887
- var isInRange = (ranges, codePoint) => {
888
- let low = 0;
889
- let high = Math.floor(ranges.length / 2) - 1;
890
- while (low <= high) {
891
- const mid = Math.floor((low + high) / 2);
892
- const i = mid * 2;
893
- if (codePoint < ranges[i]) {
894
- high = mid - 1;
895
- } else if (codePoint > ranges[i + 1]) {
896
- low = mid + 1;
897
- } else {
898
- return true;
899
- }
900
- }
901
- return false;
902
- };
903
-
904
- // node_modules/get-east-asian-width/lookup.js
905
- var commonCjkCodePoint = 19968;
906
- var [wideFastPathStart, wideFastPathEnd] = /* @__PURE__ */ findWideFastPathRange(wideRanges);
907
- function findWideFastPathRange(ranges) {
908
- let fastPathStart = ranges[0];
909
- let fastPathEnd = ranges[1];
910
- for (let index = 0; index < ranges.length; index += 2) {
911
- const start = ranges[index];
912
- const end = ranges[index + 1];
913
- if (commonCjkCodePoint >= start && commonCjkCodePoint <= end) {
914
- return [start, end];
915
- }
916
- if (end - start > fastPathEnd - fastPathStart) {
917
- fastPathStart = start;
918
- fastPathEnd = end;
919
- }
920
- }
921
- return [fastPathStart, fastPathEnd];
922
- }
923
- var isAmbiguous = (codePoint) => {
924
- if (codePoint < ambiguousMinimalCodePoint || codePoint > ambiguousMaximumCodePoint) {
925
- return false;
926
- }
927
- return isInRange(ambiguousRanges, codePoint);
928
- };
929
- var isFullwidth = (codePoint) => {
930
- if (codePoint < fullwidthMinimalCodePoint || codePoint > fullwidthMaximumCodePoint) {
931
- return false;
932
- }
933
- return isInRange(fullwidthRanges, codePoint);
934
- };
935
- var isWide = (codePoint) => {
936
- if (codePoint >= wideFastPathStart && codePoint <= wideFastPathEnd) {
937
- return true;
938
- }
939
- if (codePoint < wideMinimalCodePoint || codePoint > wideMaximumCodePoint) {
940
- return false;
941
- }
942
- return isInRange(wideRanges, codePoint);
943
- };
944
-
945
- // node_modules/get-east-asian-width/index.js
946
- function validate(codePoint) {
947
- if (!Number.isSafeInteger(codePoint)) {
948
- throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
949
- }
950
- }
951
- function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
952
- validate(codePoint);
953
- if (isFullwidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) {
954
- return 2;
955
- }
956
- return 1;
957
- }
958
-
959
- // node_modules/string-width/index.js
960
- var segmenter = new Intl.Segmenter();
961
- var zeroWidthClusterRegex = new RegExp("^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Format}|\\p{Nonspacing_Mark}|\\p{Enclosing_Mark}|\\p{Surrogate})+$", "v");
962
- var leadingNonPrintingRegex = new RegExp("^[\\p{Default_Ignorable_Code_Point}\\p{Control}\\p{Format}\\p{Nonspacing_Mark}\\p{Enclosing_Mark}\\p{Surrogate}]+", "v");
963
- var spacingMarkRegex = new RegExp("\\p{Spacing_Mark}", "v");
964
- var rgiEmojiRegex = new RegExp("^\\p{RGI_Emoji}$", "v");
965
- var unqualifiedKeycapRegex = /^[\d#*]\u20E3$/;
966
- var extendedPictographicRegex = new RegExp("\\p{Extended_Pictographic}", "gu");
967
- function isDoubleWidthNonRgiEmojiSequence(segment) {
968
- if (segment.length > 50) {
969
- return false;
970
- }
971
- if (unqualifiedKeycapRegex.test(segment)) {
972
- return true;
973
- }
974
- if (segment.includes("\u200D")) {
975
- const pictographics = segment.match(extendedPictographicRegex);
976
- return pictographics !== null && pictographics.length >= 2;
977
- }
978
- return false;
979
- }
980
- function baseVisible(segment) {
981
- return segment.replace(leadingNonPrintingRegex, "");
982
- }
983
- function isZeroWidthCluster(segment) {
984
- return zeroWidthClusterRegex.test(segment);
985
- }
986
- function isHangulLeadingJamo(codePoint) {
987
- return codePoint >= 4352 && codePoint <= 4447 || codePoint >= 43360 && codePoint <= 43388;
988
- }
989
- function isHangulVowelJamo(codePoint) {
990
- return codePoint >= 4448 && codePoint <= 4519 || codePoint >= 55216 && codePoint <= 55238;
991
- }
992
- function isHangulTrailingJamo(codePoint) {
993
- return codePoint >= 4520 && codePoint <= 4607 || codePoint >= 55243 && codePoint <= 55291;
994
- }
995
- function isHangulJamo(codePoint) {
996
- return isHangulLeadingJamo(codePoint) || isHangulVowelJamo(codePoint) || isHangulTrailingJamo(codePoint);
997
- }
998
- function hangulClusterWidth(visibleSegment, eastAsianWidthOptions) {
999
- const codePoints = [];
1000
- for (const character of visibleSegment) {
1001
- if (zeroWidthClusterRegex.test(character)) {
1002
- continue;
1003
- }
1004
- codePoints.push(character.codePointAt(0));
1005
- }
1006
- if (codePoints.length === 0) {
1007
- return void 0;
1008
- }
1009
- let width = 0;
1010
- for (let index = 0; index < codePoints.length; index++) {
1011
- const codePoint = codePoints[index];
1012
- if (!isHangulJamo(codePoint)) {
1013
- if (width === 0) {
1014
- return void 0;
1015
- }
1016
- for (let remaining = index; remaining < codePoints.length; remaining++) {
1017
- width += eastAsianWidth(codePoints[remaining], eastAsianWidthOptions);
1018
- }
1019
- return width;
1020
- }
1021
- if (isHangulLeadingJamo(codePoint) && isHangulVowelJamo(codePoints[index + 1])) {
1022
- width += 2;
1023
- index += isHangulTrailingJamo(codePoints[index + 2]) ? 2 : 1;
1024
- continue;
1025
- }
1026
- width += eastAsianWidth(codePoint, eastAsianWidthOptions);
1027
- }
1028
- return width;
1029
- }
1030
- function trailingWidth(visibleSegment, eastAsianWidthOptions) {
1031
- let extra = 0;
1032
- let first = true;
1033
- for (const character of visibleSegment) {
1034
- if (first) {
1035
- first = false;
1036
- continue;
1037
- }
1038
- if (spacingMarkRegex.test(character) || character >= "\uFF00" && character <= "\uFFEF") {
1039
- extra += eastAsianWidth(character.codePointAt(0), eastAsianWidthOptions);
1040
- }
1041
- }
1042
- return extra;
1043
- }
1044
- function stringWidth(input, options = {}) {
1045
- if (typeof input !== "string" || input.length === 0) {
1046
- return 0;
1047
- }
1048
- const {
1049
- ambiguousIsNarrow = true,
1050
- countAnsiEscapeCodes = false
1051
- } = options;
1052
- let string = input;
1053
- if (!countAnsiEscapeCodes && (string.includes("\x1B") || string.includes("\x9B"))) {
1054
- string = stripAnsi(string);
1055
- }
1056
- if (string.length === 0) {
1057
- return 0;
1058
- }
1059
- if (/^[\u0020-\u007E]*$/.test(string)) {
1060
- return string.length;
1061
- }
1062
- let width = 0;
1063
- const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
1064
- for (const { segment } of segmenter.segment(string)) {
1065
- if (isZeroWidthCluster(segment)) {
1066
- continue;
1067
- }
1068
- if (rgiEmojiRegex.test(segment) || isDoubleWidthNonRgiEmojiSequence(segment)) {
1069
- width += 2;
1070
- continue;
1071
- }
1072
- const visibleSegment = baseVisible(segment);
1073
- const hangulWidth = hangulClusterWidth(visibleSegment, eastAsianWidthOptions);
1074
- if (hangulWidth !== void 0) {
1075
- width += hangulWidth;
1076
- continue;
1077
- }
1078
- const codePoint = visibleSegment.codePointAt(0);
1079
- width += eastAsianWidth(codePoint, eastAsianWidthOptions);
1080
- width += trailingWidth(visibleSegment, eastAsianWidthOptions);
1081
- }
1082
- return width;
1083
- }
1084
-
1085
- // packages/cli/tui/tuiAnsi.ts
1086
- var ANSI_ESCAPE_REGEX = /\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]/g;
1087
- var OSC8_HYPERLINK_REGEX = /\x1b\]8;;[^\x1b]*\x1b\\/g;
1088
- var ALL_ANSI_ESCAPE_REGEX = ansiRegex();
1089
- var FIRST_ANSI_ESCAPE_REGEX = ansiRegex({ onlyFirst: true });
1090
- function stripOsc8Hyperlinks(text) {
1091
- return text.replace(OSC8_HYPERLINK_REGEX, "");
1092
- }
1093
- function stripAnsi2(text) {
1094
- return text.replace(ANSI_ESCAPE_REGEX, "").replace(ALL_ANSI_ESCAPE_REGEX, "");
1095
- }
1096
- var SGR_SEQUENCE_REGEX = /^\x1b\[[0-9;]*m/;
1097
- var TRAILING_SGR_REGEX = /(?:\x1b\[[0-9;]*m)+$/;
1098
- function applyTerminalOutputToText(existing, chunk) {
1099
- if (!chunk) return existing;
1100
- let text = existing;
1101
- let index = 0;
1102
- while (index < chunk.length) {
1103
- if (chunk[index] === "\x1B") {
1104
- const sgr = SGR_SEQUENCE_REGEX.exec(chunk.slice(index));
1105
- if (sgr) {
1106
- text += sgr[0];
1107
- index += sgr[0].length;
1108
- continue;
1109
- }
1110
- const osc = chunk.slice(index).match(/^\x1b\]8;;[^\x07\x1b]*(?:\x07|\x1b\\)/);
1111
- if (osc) {
1112
- index += osc[0].length;
1113
- continue;
1114
- }
1115
- const csi = chunk.slice(index).match(/^\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]/);
1116
- if (csi) {
1117
- index += csi[0].length;
1118
- continue;
1119
- }
1120
- index += 1;
1121
- continue;
1122
- }
1123
- const ch = chunk[index];
1124
- if (ch === "\r") {
1125
- const lastNl = text.lastIndexOf("\n");
1126
- text = lastNl === -1 ? "" : text.slice(0, lastNl + 1);
1127
- index += 1;
1128
- continue;
1129
- }
1130
- if (ch === "\n") {
1131
- text += "\n";
1132
- index += 1;
1133
- continue;
1134
- }
1135
- if (ch === "\b") {
1136
- const trailing = TRAILING_SGR_REGEX.exec(text);
1137
- const sgrTail = trailing ? trailing[0] : "";
1138
- const head = sgrTail ? text.slice(0, -sgrTail.length) : text;
1139
- if (head.length > 0 && head[head.length - 1] !== "\n") {
1140
- text = head.slice(0, -1) + sgrTail;
1141
- }
1142
- index += 1;
1143
- continue;
1144
- }
1145
- const code = ch.charCodeAt(0);
1146
- if (code < 32 && ch !== " " || code === 127) {
1147
- index += 1;
1148
- continue;
1149
- }
1150
- text += ch;
1151
- index += 1;
1152
- }
1153
- return text;
1154
- }
1155
- function resolveAmbiguousWidth(explicit, env = process.env) {
1156
- if (explicit === "wide" || explicit === "narrow") return explicit;
1157
- const raw = env.NOLO_TUI_AMBIGUOUS_WIDTH;
1158
- if (typeof raw === "string") {
1159
- const trimmed = raw.trim().toLowerCase();
1160
- if (trimmed === "wide") return "wide";
1161
- if (trimmed === "narrow") return "narrow";
1162
- }
1163
- return "narrow";
1164
- }
1165
- function isAmbiguousWideSymbolCode(code) {
1166
- return code >= 8592 && code <= 8597 || // ←↑→↓↔↕
1167
- code === 8656 || code === 8658 || code === 8660 || // ⇐⇒⇔
1168
- code === 215 || code === 247 || code === 177 || // ×÷±
1169
- code === 8226 || code === 183 || // • ·
1170
- code === 176 || code === 8451 || // ° ℃
1171
- code >= 8208 && code <= 8213 || // ‐‑‒–—―
1172
- code >= 9312 && code <= 9471 || // ①②④⑤ 圈数字/括号序号
1173
- code === 8986 || code === 8987 || // ⌚ ⌛
1174
- code >= 9193 && code <= 9210;
1175
- }
1176
- function isForceWideSymbolCode(code) {
1177
- return code >= 9728 && code <= 10175 && !(code >= 10088 && code <= 10101) || code >= 11008 && code <= 11263 || code >= 127744 && code <= 129791 || isAmbiguousWideSymbolCode(code);
1178
- }
1179
- function isCjkQuoteCode(code) {
1180
- return code === 8220 || code === 8221 || code === 8216 || code === 8217;
1181
- }
1182
- function scanWidthNeeds(plain, locale, ambiguousWidth) {
1183
- let hasNonAscii = false;
1184
- const isWideMode = ambiguousWidth === "wide";
1185
- for (let i = 0; i < plain.length; i++) {
1186
- const cc = plain.charCodeAt(i);
1187
- if (isWideMode && isAmbiguousWideSymbolCode(cc)) {
1188
- return { hasNonAscii: true, hasCandidate: true };
1189
- }
1190
- if (cc < 8192) {
1191
- if (cc >= 128) hasNonAscii = true;
1192
- continue;
1193
- }
1194
- hasNonAscii = true;
1195
- let code = cc;
1196
- if (cc >= 55296 && cc <= 56319 && i + 1 < plain.length) {
1197
- const lo = plain.charCodeAt(i + 1);
1198
- if (lo >= 56320 && lo <= 57343) {
1199
- code = (cc - 55296) * 1024 + (lo - 56320) + 65536;
1200
- i += 1;
1201
- }
1202
- }
1203
- const isSymbolCandidate = isWideMode && isForceWideSymbolCode(code);
1204
- const isQuoteCandidate = locale === "zh" && isCjkQuoteCode(code);
1205
- if (isSymbolCandidate || isQuoteCandidate) {
1206
- return { hasNonAscii: true, hasCandidate: true };
1207
- }
1208
- }
1209
- return { hasNonAscii, hasCandidate: false };
1210
- }
1211
- var displayWidthCache = /* @__PURE__ */ new Map();
1212
- var DISPLAY_WIDTH_CACHE_MAX = 4096;
1213
- function displayWidth(str, ambiguousWidth = resolveAmbiguousWidth()) {
1214
- const plain = stripAnsi2(str);
1215
- const locale = getCliLocale();
1216
- const needs = scanWidthNeeds(plain, locale, ambiguousWidth);
1217
- if (!needs.hasNonAscii) {
1218
- return stringWidth(plain);
1219
- }
1220
- const key = locale + "\0" + ambiguousWidth + "\0" + plain;
1221
- const cached = displayWidthCache.get(key);
1222
- if (cached !== void 0) return cached;
1223
- const base = stringWidth(plain);
1224
- if (!needs.hasCandidate) {
1225
- if (displayWidthCache.size >= DISPLAY_WIDTH_CACHE_MAX) {
1226
- const eldest = displayWidthCache.keys().next().value;
1227
- if (eldest !== void 0) displayWidthCache.delete(eldest);
1228
- }
1229
- displayWidthCache.set(key, base);
1230
- return base;
1231
- }
1232
- let width = base;
1233
- const isWideMode = ambiguousWidth === "wide";
1234
- for (const { segment } of graphemeSegmenter.segment(plain)) {
1235
- const code = segment.codePointAt(0) ?? 0;
1236
- const isSymbol = isWideMode && isForceWideSymbolCode(code);
1237
- const isQuote = locale === "zh" && isCjkQuoteCode(code);
1238
- if (isSymbol || isQuote) {
1239
- if (stringWidth(segment) === 1) width += 1;
1240
- }
1241
- }
1242
- if (displayWidthCache.size >= DISPLAY_WIDTH_CACHE_MAX) {
1243
- const eldest = displayWidthCache.keys().next().value;
1244
- if (eldest !== void 0) displayWidthCache.delete(eldest);
1245
- }
1246
- displayWidthCache.set(key, width);
1247
- return width;
1248
- }
1249
- function visibleWidth(str) {
1250
- return displayWidth(stripAnsi2(str));
1251
- }
1252
- function truncateAnsi(text, maxWidth) {
1253
- if (maxWidth <= 0) return "";
1254
- text = stripOsc8Hyperlinks(text);
1255
- if (visibleWidth(text) <= maxWidth) return text;
1256
- let width = 0;
1257
- let out = "";
1258
- let i = 0;
1259
- let sawAnsi = false;
1260
- while (i < text.length) {
1261
- if (text[i] === "\x1B" && text[i + 1] === "[") {
1262
- sawAnsi = true;
1263
- let j = i + 2;
1264
- while (j < text.length) {
1265
- const code = text.charCodeAt(j);
1266
- j += 1;
1267
- if (code >= 64 && code <= 126) break;
1268
- }
1269
- out += text.slice(i, j);
1270
- i = j;
1271
- continue;
1272
- }
1273
- const codePoint = text.codePointAt(i) ?? 0;
1274
- const char = String.fromCodePoint(codePoint);
1275
- const charWidth = displayWidth(char);
1276
- if (width + charWidth > maxWidth) break;
1277
- out += char;
1278
- width += charWidth;
1279
- i += char.length;
1280
- }
1281
- return sawAnsi ? `${out}\x1B[0m` : out;
1282
- }
1283
- function fitAnsiLine(text, width, ellipsis = "\u2026") {
1284
- if (width <= 0) return "";
1285
- if (visibleWidth(text) <= width) return text;
1286
- const ellipsisWidth = displayWidth(ellipsis);
1287
- if (width < ellipsisWidth) return truncateAnsi(text, width);
1288
- if (width === ellipsisWidth) return truncateAnsi(ellipsis, width) || truncateAnsi(text, width);
1289
- return `${truncateAnsi(text, width - ellipsisWidth)}${ellipsis}`;
1290
- }
1291
- function countPhysicalLines(text, columns) {
1292
- const lines = text.split("\n");
1293
- let total = 0;
1294
- for (const line of lines) {
1295
- const width = visibleWidth(stripOsc8Hyperlinks(line));
1296
- total += Math.max(1, Math.ceil(width / columns));
1297
- }
1298
- return Math.max(total, 1);
1299
- }
1300
- function takeDisplayWidth(text, width) {
1301
- let used = 0;
1302
- let index = 0;
1303
- for (const char of text) {
1304
- const charWidth = displayWidth(char);
1305
- if (used + charWidth > width && used > 0) break;
1306
- used += charWidth;
1307
- index += char.length;
1308
- }
1309
- return { prefix: text.slice(0, index), rest: text.slice(index) };
1310
- }
1311
- function padOrTruncateToWidth(text, width) {
1312
- const textWidth = visibleWidth(text);
1313
- if (textWidth > width) {
1314
- return truncateAnsi(text, width);
1315
- }
1316
- return `${text}${" ".repeat(width - textWidth)}`;
1317
- }
1318
- var SGR_RESET_REGEX = /^\x1b\[0?m$/;
1319
- var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
1320
- function tokenizeAnsiLine(line) {
1321
- const tokens = [];
1322
- let index = 0;
1323
- while (index < line.length) {
1324
- if (line[index] === "\x1B") {
1325
- const osc = line.slice(index).match(/^\x1b\]8;;[^\x07\x1b]*(?:\x07|\x1b\\)/);
1326
- if (osc) {
1327
- tokens.push({ kind: "sgr", value: osc[0], width: 0, charIndex: index });
1328
- index += osc[0].length;
1329
- continue;
1330
- }
1331
- const sgr = SGR_SEQUENCE_REGEX.exec(line.slice(index));
1332
- if (sgr) {
1333
- tokens.push({ kind: "sgr", value: sgr[0], width: 0, charIndex: index });
1334
- index += sgr[0].length;
1335
- continue;
1336
- }
1337
- const csi = line.slice(index).match(/^\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]/);
1338
- if (csi) {
1339
- index += csi[0].length;
1340
- continue;
1341
- }
1342
- const escape = FIRST_ANSI_ESCAPE_REGEX.exec(line.slice(index));
1343
- if (escape?.index === 0) {
1344
- index += escape[0].length;
1345
- continue;
1346
- }
1347
- index += 1;
1348
- continue;
1349
- }
1350
- let nextEsc = line.indexOf("\x1B", index);
1351
- if (nextEsc === -1) nextEsc = line.length;
1352
- const chunk = line.slice(index, nextEsc);
1353
- for (const item of graphemeSegmenter.segment(chunk)) {
1354
- tokens.push({
1355
- kind: "char",
1356
- value: item.segment,
1357
- width: displayWidth(item.segment),
1358
- charIndex: index + item.index
1359
- });
1360
- }
1361
- index = nextEsc;
1362
- }
1363
- return tokens;
1364
- }
1365
- function buildSourceMapping(rawLine, styledLine, prefixCharCount) {
1366
- let contentStart = 0;
1367
- const headingMatch = rawLine.match(/^(#{1,3})\s+(.+)$/);
1368
- let lineToParse = rawLine;
1369
- if (headingMatch) {
1370
- contentStart = headingMatch[1].length + 1;
1371
- while (contentStart < rawLine.length && rawLine[contentStart] === " ") contentStart++;
1372
- lineToParse = rawLine.slice(contentStart);
1373
- }
1374
- const INLINE_RE = /(\[([^\]]+)\]\(([^)\s]+)\)|`([^`]+)`|\*\*(.+?)\*\*|(?<!\*)\*([^*]+?)\*(?!\*)|~~([^~]+?)~~)/g;
1375
- const mapping = [];
1376
- let lastIdx = 0;
1377
- let match;
1378
- while ((match = INLINE_RE.exec(lineToParse)) !== null) {
1379
- const plainBefore = lineToParse.slice(lastIdx, match.index);
1380
- for (let c = 0; c < plainBefore.length; c++) {
1381
- mapping.push(contentStart + lastIdx + c);
1382
- }
1383
- const fullMatch = match[0];
1384
- if (match[2] !== void 0 && match[3] !== void 0) {
1385
- const linkText = match[2];
1386
- const linkUrl = match[3];
1387
- const textOffset = contentStart + match.index + 1;
1388
- for (let c = 0; c < linkText.length; c++) {
1389
- mapping.push(textOffset + c);
1390
- }
1391
- const parenOffset = textOffset + linkText.length;
1392
- mapping.push(parenOffset);
1393
- mapping.push(parenOffset + 1);
1394
- const urlOffset = parenOffset + 2;
1395
- for (let c = 0; c < linkUrl.length; c++) {
1396
- mapping.push(urlOffset + c);
1397
- }
1398
- mapping.push(urlOffset + linkUrl.length);
1399
- } else if (match[4] !== void 0) {
1400
- const codeText = match[4];
1401
- const codeOffset = contentStart + match.index + 1;
1402
- for (let c = 0; c < codeText.length; c++) {
1403
- mapping.push(codeOffset + c);
1404
- }
1405
- } else if (match[5] !== void 0) {
1406
- const boldText = match[5];
1407
- const boldOffset = contentStart + match.index + 2;
1408
- for (let c = 0; c < boldText.length; c++) {
1409
- mapping.push(boldOffset + c);
1410
- }
1411
- } else if (match[6] !== void 0) {
1412
- const italicText = match[6];
1413
- const italicOffset = contentStart + match.index + 1;
1414
- for (let c = 0; c < italicText.length; c++) {
1415
- mapping.push(italicOffset + c);
1416
- }
1417
- } else if (match[7] !== void 0) {
1418
- const strikeText = match[7];
1419
- const strikeOffset = contentStart + match.index + 2;
1420
- for (let c = 0; c < strikeText.length; c++) {
1421
- mapping.push(strikeOffset + c);
1422
- }
1423
- }
1424
- lastIdx = match.index + fullMatch.length;
1425
- }
1426
- const plainRest = lineToParse.slice(lastIdx);
1427
- for (let c = 0; c < plainRest.length; c++) {
1428
- mapping.push(contentStart + lastIdx + c);
1429
- }
1430
- return mapping;
1431
- }
1432
- function wrapTranscriptLineWithLayout(line, columns, hangingIndent = "", lineSourceStart = 0, prefixWidth = 0, prefixCharCount = 0, sourceMapping, rawLineLength) {
1433
- if (line === "") {
1434
- const rawLen = rawLineLength ?? 0;
1435
- return [
1436
- {
1437
- rendered: "",
1438
- sourceStart: lineSourceStart,
1439
- sourceEnd: lineSourceStart + rawLen,
1440
- prefixWidth
1441
- }
1442
- ];
1443
- }
1444
- const tokens = tokenizeAnsiLine(line);
1445
- const rows = [];
1446
- let activeStyles = [];
1447
- const applyStyleToken = (value) => {
1448
- if (SGR_RESET_REGEX.test(value)) {
1449
- activeStyles = [];
1450
- } else {
1451
- activeStyles.push(value);
1452
- }
1453
- };
1454
- let lastContentTokenIndex = -1;
1455
- for (let i = tokens.length - 1; i >= 0; i -= 1) {
1456
- if (tokens[i].kind !== "sgr") {
1457
- lastContentTokenIndex = i;
1458
- break;
1459
- }
1460
- }
1461
- let plainCharIndexAtStart = 0;
1462
- let start = 0;
1463
- while (start < tokens.length) {
1464
- if (start > lastContentTokenIndex && rows.length > 0) break;
1465
- const openingStyles = [...activeStyles];
1466
- const isContinuation = rows.length > 0;
1467
- const currentPrefixWidth = isContinuation ? visibleWidth(hangingIndent) : prefixWidth;
1468
- const indentWidth = isContinuation ? visibleWidth(hangingIndent) : 0;
1469
- const maxSegmentWidth = Math.max(1, columns - indentWidth);
1470
- let width = 0;
1471
- let end = start;
1472
- let lastBreak2 = -1;
1473
- while (end < tokens.length) {
1474
- const token = tokens[end];
1475
- if (token.kind === "sgr") {
1476
- end += 1;
1477
- continue;
1478
- }
1479
- if (width + token.width > maxSegmentWidth && width > 0) break;
1480
- width += token.width;
1481
- end += 1;
1482
- if ((token.value === " " || token.value === " ") && token.charIndex >= prefixCharCount) {
1483
- lastBreak2 = end;
1484
- }
1485
- }
1486
- let segmentEnd = end;
1487
- if (end < tokens.length && lastBreak2 > start) {
1488
- const overflowToken = tokens[end];
1489
- if (overflowToken.kind === "char" && overflowToken.value !== " " && overflowToken.width === 1) {
1490
- segmentEnd = lastBreak2;
1491
- }
1492
- }
1493
- if (segmentEnd === start) segmentEnd = start + 1;
1494
- let segment = "";
1495
- let sawStyle = openingStyles.length > 0;
1496
- for (let i = start; i < segmentEnd; i += 1) {
1497
- const token = tokens[i];
1498
- segment += token.value;
1499
- if (token.kind === "sgr") {
1500
- sawStyle = true;
1501
- applyStyleToken(token.value);
1502
- }
1503
- }
1504
- const prefix = openingStyles.join("");
1505
- const needsReset = (sawStyle || activeStyles.length > 0) && !segment.endsWith("\x1B[0m");
1506
- const lineContent = `${prefix}${segment}${needsReset ? "\x1B[0m" : ""}`;
1507
- const rowRendered = isContinuation && hangingIndent.length > 0 ? `${hangingIndent}${lineContent}` : lineContent;
1508
- let segSourceStart = lineSourceStart;
1509
- let segSourceEnd = lineSourceStart;
1510
- let foundFirst = false;
1511
- const rowMapping = [];
1512
- let plainCharIndex = plainCharIndexAtStart;
1513
- for (let i = start; i < segmentEnd; i++) {
1514
- const tok = tokens[i];
1515
- if (tok.kind === "char" && tok.charIndex >= prefixCharCount) {
1516
- const mappedOffset = sourceMapping && sourceMapping[plainCharIndex] !== void 0 ? sourceMapping[plainCharIndex] : plainCharIndex;
1517
- if (!foundFirst) {
1518
- segSourceStart = lineSourceStart + mappedOffset;
1519
- foundFirst = true;
1520
- }
1521
- for (let c = 0; c < tok.value.length; c++) {
1522
- const idx = plainCharIndex + c;
1523
- const mapped = sourceMapping && sourceMapping[idx] !== void 0 ? sourceMapping[idx] : idx;
1524
- rowMapping.push(lineSourceStart + mapped);
1525
- }
1526
- const lastCharIdx = plainCharIndex + tok.value.length - 1;
1527
- const mappedEndOffset = sourceMapping && sourceMapping[lastCharIdx] !== void 0 ? sourceMapping[lastCharIdx] + 1 : plainCharIndex + tok.value.length;
1528
- segSourceEnd = lineSourceStart + mappedEndOffset;
1529
- plainCharIndex += tok.value.length;
1530
- }
1531
- }
1532
- start = segmentEnd;
1533
- let softWrapJoiner = "";
1534
- while (start < tokens.length) {
1535
- const token = tokens[start];
1536
- if (token.kind === "char" && token.value === " " && token.charIndex >= prefixCharCount) {
1537
- softWrapJoiner += token.value;
1538
- const mappedOffset = sourceMapping && sourceMapping[plainCharIndex] !== void 0 ? sourceMapping[plainCharIndex] + 1 : plainCharIndex + 1;
1539
- segSourceEnd = lineSourceStart + mappedOffset;
1540
- plainCharIndex += token.value.length;
1541
- start += 1;
1542
- continue;
1543
- }
1544
- break;
1545
- }
1546
- if (start >= tokens.length && rawLineLength !== void 0) {
1547
- segSourceEnd = lineSourceStart + rawLineLength;
1548
- }
1549
- plainCharIndexAtStart = plainCharIndex;
1550
- rows.push({
1551
- rendered: rowRendered,
1552
- sourceStart: segSourceStart,
1553
- sourceEnd: segSourceEnd,
1554
- prefixWidth: currentPrefixWidth,
1555
- sourceMapping: rowMapping.length > 0 ? rowMapping : void 0,
1556
- softWrapped: start < tokens.length,
1557
- softWrapJoiner
1558
- });
1559
- }
1560
- return rows.length > 0 ? rows : [
1561
- {
1562
- rendered: "",
1563
- sourceStart: lineSourceStart,
1564
- sourceEnd: lineSourceStart + (rawLineLength ?? 0),
1565
- prefixWidth
1566
- }
1567
- ];
1568
- }
1569
- function wrapTranscriptLine(line, columns, hangingIndent = "") {
1570
- return wrapTranscriptLineWithLayout(line, columns, hangingIndent).map((r) => r.rendered);
1571
- }
1572
- function buildWindowTitle(title) {
1573
- const plain = stripAnsi2(title).replace(/[\x00-\x1f\x7f]+/g, " ");
1574
- let truncated = "";
1575
- let width = 0;
1576
- const maxCols = 80;
1577
- for (const char of plain) {
1578
- const charWidth = displayWidth(char);
1579
- if (width + charWidth > maxCols) break;
1580
- truncated += char;
1581
- width += charWidth;
1582
- }
1583
- return `\x1B]0;${truncated}\x07\x1B]2;${truncated}\x07`;
1584
- }
1585
- function wrapTextToLines(text, columns) {
1586
- const result = [];
1587
- for (const logicalLine of text.split("\n")) {
1588
- if (logicalLine === "") {
1589
- result.push("");
1590
- continue;
1591
- }
1592
- let remaining = logicalLine;
1593
- while (remaining.length > 0) {
1594
- const { prefix, rest } = takeDisplayWidth(remaining, columns);
1595
- result.push(prefix);
1596
- remaining = rest;
1597
- }
1598
- }
1599
- return result;
1600
- }
1601
-
1602
1049
  // packages/cli/tui/theme.ts
1603
1050
  var THEME_PALETTES = {
1604
1051
  trail: {
@@ -2997,7 +2444,7 @@ var WIDTHS = [
2997
2444
  ];
2998
2445
 
2999
2446
  // node_modules/lovely-mermaid/dist/width.js
3000
- var segmenter2 = new Intl.Segmenter("en", { granularity: "grapheme" });
2447
+ var segmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
3001
2448
  var VS16 = 65039;
3002
2449
  var isRegionalIndicator = (cp) => cp >= 127462 && cp <= 127487;
3003
2450
  function codePointWidth(cp) {
@@ -3032,12 +2479,12 @@ function clusterWidth(cluster) {
3032
2479
  return vs16 || regional >= 2 ? 2 : w;
3033
2480
  }
3034
2481
  function* measured(s) {
3035
- for (const { segment } of segmenter2.segment(s))
2482
+ for (const { segment } of segmenter.segment(s))
3036
2483
  yield [segment, clusterWidth(segment)];
3037
2484
  }
3038
- function stringWidth2(s) {
2485
+ function stringWidth(s) {
3039
2486
  let w = 0;
3040
- for (const { segment } of segmenter2.segment(s))
2487
+ for (const { segment } of segmenter.segment(s))
3041
2488
  w += clusterWidth(segment);
3042
2489
  return w;
3043
2490
  }
@@ -3234,7 +2681,7 @@ function wrapLabel(label, width, maxLines) {
3234
2681
  let cur = "";
3235
2682
  let curW = 0;
3236
2683
  for (const word of label.split(/\s+/).filter((w) => w !== "")) {
3237
- const ww = stringWidth2(word);
2684
+ const ww = stringWidth(word);
3238
2685
  if (ww > width) {
3239
2686
  if (cur !== "") {
3240
2687
  lines.push(cur);
@@ -3248,7 +2695,7 @@ function wrapLabel(label, width, maxLines) {
3248
2695
  const carry = p === -1 ? "" : chunk.slice(p + 1);
3249
2696
  lines.push(p === -1 ? chunk : chunk.slice(0, p + 1));
3250
2697
  chunk = carry;
3251
- chunkW = stringWidth2(carry);
2698
+ chunkW = stringWidth(carry);
3252
2699
  }
3253
2700
  chunk += ch;
3254
2701
  chunkW += cw;
@@ -3287,7 +2734,7 @@ function wrapLabel(label, width, maxLines) {
3287
2734
  return lines;
3288
2735
  }
3289
2736
  function fitLabel(label, inner) {
3290
- if (stringWidth2(label) <= inner)
2737
+ if (stringWidth(label) <= inner)
3291
2738
  return label;
3292
2739
  let out = "";
3293
2740
  let used = 0;
@@ -4079,7 +3526,7 @@ function placeTd(ranks, maxRank, byRank, sizes, graph, placed) {
4079
3526
  const edgeLabelLeft = new Array(graph.edges.length).fill(false);
4080
3527
  const labelW = (e) => {
4081
3528
  const parts = [e.label, e.cardTo].filter((p) => p != null);
4082
- return parts.length === 0 ? -1 : Math.max(...parts.map((p) => Math.min(stringWidth2(p), MAX_LABEL)));
3529
+ return parts.length === 0 ? -1 : Math.max(...parts.map((p) => Math.min(stringWidth(p), MAX_LABEL)));
4083
3530
  };
4084
3531
  const skipsInto = graph.nodes.map(() => []);
4085
3532
  const fwdsInto = graph.nodes.map(() => []);
@@ -4247,21 +3694,21 @@ function placeTd(ranks, maxRank, byRank, sizes, graph, placed) {
4247
3694
  if (ranks[e.to] === ranks[e.from] + 1) {
4248
3695
  const parts = [e.label, e.cardTo].filter((part) => part != null);
4249
3696
  for (const part of parts) {
4250
- const lw = Math.min(stringWidth2(part), MAX_LABEL);
3697
+ const lw = Math.min(stringWidth(part), MAX_LABEL);
4251
3698
  contentW = Math.max(contentW, placed[e.to].cx + 2 + lw);
4252
3699
  }
4253
3700
  if (e.cardFrom !== void 0) {
4254
- contentW = Math.max(contentW, placed[e.from].cx + 2 + stringWidth2(e.cardFrom));
3701
+ contentW = Math.max(contentW, placed[e.from].cx + 2 + stringWidth(e.cardFrom));
4255
3702
  }
4256
3703
  } else if (isAdjacentBack(ranks, e)) {
4257
3704
  const text = edgeText(e);
4258
3705
  if (text !== null) {
4259
- contentW = Math.max(contentW, placed[e.to].cx + 2 + Math.min(stringWidth2(text), MAX_LABEL));
3706
+ contentW = Math.max(contentW, placed[e.to].cx + 2 + Math.min(stringWidth(text), MAX_LABEL));
4260
3707
  }
4261
3708
  } else {
4262
3709
  const text = edgeText(e);
4263
3710
  if (text !== null) {
4264
- contentW = Math.max(contentW, diagramW + Math.min(stringWidth2(text), MAX_LABEL) + 1);
3711
+ contentW = Math.max(contentW, diagramW + Math.min(stringWidth(text), MAX_LABEL) + 1);
4265
3712
  }
4266
3713
  }
4267
3714
  }
@@ -4315,8 +3762,8 @@ function placeLr(ranks, maxRank, byRank, sizes, graph, placed) {
4315
3762
  return;
4316
3763
  if (ranks[e.to] !== ranks[e.from] + 1 && !edgeStraight[i])
4317
3764
  return;
4318
- const verb = e.label === null ? 0 : Math.min(stringWidth2(e.label), MAX_LABEL);
4319
- const cards = [e.cardFrom, e.cardTo].filter((c) => c !== void 0).reduce((w, c) => w + stringWidth2(c) + 1, 0);
3765
+ const verb = e.label === null ? 0 : Math.min(stringWidth(e.label), MAX_LABEL);
3766
+ const cards = [e.cardFrom, e.cardTo].filter((c) => c !== void 0).reduce((w, c) => w + stringWidth(c) + 1, 0);
4320
3767
  bandLabel[ranks[e.from]] = Math.max(bandLabel[ranks[e.from]], verb + cards);
4321
3768
  });
4322
3769
  const edgeBus = new Array(graph.edges.length).fill(0);
@@ -4427,10 +3874,10 @@ function layoutCanvas(graph, extras) {
4427
3874
  for (const row of byRank)
4428
3875
  row.sort((a, b) => Number(inLane[a]) - Number(inLane[b]));
4429
3876
  const wrapped = graph.nodes.map((node) => wrapLabel(node.label, WRAP_WIDTH, MAX_LINES));
4430
- const widest = (lines) => Math.max(1, lines.length === 0 ? 1 : Math.max(...lines.map(stringWidth2)));
3877
+ const widest = (lines) => Math.max(1, lines.length === 0 ? 1 : Math.max(...lines.map(stringWidth)));
4431
3878
  const boxW = extras.map((extra, i) => {
4432
3879
  if (extra.kind === "frame") {
4433
- return Math.max(extra.sub.w + 2, stringWidth2(fitLabel(graph.nodes[i].label, WRAP_WIDTH)) + 4);
3880
+ return Math.max(extra.sub.w + 2, stringWidth(fitLabel(graph.nodes[i].label, WRAP_WIDTH)) + 4);
4434
3881
  }
4435
3882
  if (extra.kind === "compartments")
4436
3883
  return widest(extra.sections.flat()) + 2 * PAD + 2;
@@ -4453,7 +3900,7 @@ function layoutCanvas(graph, extras) {
4453
3900
  extraH[e.from] = 2;
4454
3901
  const text = edgeText(e);
4455
3902
  if (text !== null) {
4456
- selfLabelW[e.from] = Math.max(selfLabelW[e.from], Math.min(stringWidth2(text), MAX_LABEL));
3903
+ selfLabelW[e.from] = Math.max(selfLabelW[e.from], Math.min(stringWidth(text), MAX_LABEL));
4457
3904
  }
4458
3905
  }
4459
3906
  for (let i = 0; i < n; i++)
@@ -4719,7 +4166,7 @@ function drawBox(canvas, p, lines, shape, mirrored = false) {
4719
4166
  const ordered = mirrored ? [...lines].reverse() : lines;
4720
4167
  ordered.forEach((line, li) => {
4721
4168
  const text = fitLabel(line, inner);
4722
- const textX = x + 1 + PAD + half(sat(inner, stringWidth2(text)));
4169
+ const textX = x + 1 + PAD + half(sat(inner, stringWidth(text)));
4723
4170
  drawText(canvas, text, textX, y + 1 + li, "text");
4724
4171
  });
4725
4172
  }
@@ -4745,7 +4192,7 @@ function drawClassBox(canvas, p, sections, mirrored = false) {
4745
4192
  canvas.set(x, row, "\u2500", "border");
4746
4193
  canvas.set(p.x + p.w - 1, row, "\u2524", "border");
4747
4194
  } else {
4748
- const tx = r.center ? p.x + 1 + PAD + half(sat(inner, stringWidth2(r.text))) : p.x + 1 + PAD;
4195
+ const tx = r.center ? p.x + 1 + PAD + half(sat(inner, stringWidth(r.text))) : p.x + 1 + PAD;
4749
4196
  drawTextOverEdges(canvas, r.text, tx, row, "text");
4750
4197
  }
4751
4198
  });
@@ -4795,7 +4242,7 @@ function routeForward(canvas, from, to, edge, bus, entryX = -1, labelLeft = fals
4795
4242
  canvas.set(bx, by, headGlyph(edge.headFrom, "\u25B2"), "edge");
4796
4243
  if (edge.cardFrom === void 0 && edge.cardTo === void 0) {
4797
4244
  if (edge.label !== null) {
4798
- const start = labelLeft ? sat(tx, Math.min(stringWidth2(edge.label), MAX_LABEL)) : tx + 1;
4245
+ const start = labelLeft ? sat(tx, Math.min(stringWidth(edge.label), MAX_LABEL)) : tx + 1;
4799
4246
  placeLabel(canvas, edge.label, headRow, start);
4800
4247
  }
4801
4248
  return;
@@ -4811,7 +4258,7 @@ function routeForward(canvas, from, to, edge, bus, entryX = -1, labelLeft = fals
4811
4258
  const lineX = midRow > bus ? tx : bx;
4812
4259
  placeLabel(canvas, edge.label, midRow, lineX + 1);
4813
4260
  } else {
4814
- placeLabel(canvas, edge.label, headRow, tx + 1 + (edge.cardTo === void 0 ? 0 : stringWidth2(edge.cardTo) + 1));
4261
+ placeLabel(canvas, edge.label, headRow, tx + 1 + (edge.cardTo === void 0 ? 0 : stringWidth(edge.cardTo) + 1));
4815
4262
  }
4816
4263
  }
4817
4264
  }
@@ -4880,7 +4327,7 @@ function routeSkip(canvas, from, to, edge, at) {
4880
4327
  canvas.set(bx, bottom, headGlyph(edge.headFrom, "\u25B2"), "edge");
4881
4328
  const text = edgeText(edge);
4882
4329
  if (text !== null) {
4883
- const start = labelLeft ? sat(entryX, Math.min(stringWidth2(text), MAX_LABEL)) : entryX + 1;
4330
+ const start = labelLeft ? sat(entryX, Math.min(stringWidth(text), MAX_LABEL)) : entryX + 1;
4884
4331
  placeLabel(canvas, text, to.y - 1, start);
4885
4332
  }
4886
4333
  }
@@ -4901,7 +4348,7 @@ function routeBack(canvas, from, to, edge, laneX) {
4901
4348
  else
4902
4349
  canvas.set(tx + 1, tyc, headGlyph(edge.headTo, "\u25C4"), "edge");
4903
4350
  if (backText !== null) {
4904
- placeLabel(canvas, backText, sat(tyc, 1), sat(laneX, stringWidth2(backText) + 1));
4351
+ placeLabel(canvas, backText, sat(tyc, 1), sat(laneX, stringWidth(backText) + 1));
4905
4352
  }
4906
4353
  }
4907
4354
  function routeForwardLr(canvas, from, to, edge, bus) {
@@ -4928,7 +4375,7 @@ function routeForwardLr(canvas, from, to, edge, bus) {
4928
4375
  if (edge.cardFrom !== void 0)
4929
4376
  placeLabel(canvas, edge.cardFrom, sat(ry, 1), rx + 1);
4930
4377
  if (edge.cardTo !== void 0) {
4931
- placeLabel(canvas, edge.cardTo, sat(ly, 1), sat(headCol, stringWidth2(edge.cardTo)));
4378
+ placeLabel(canvas, edge.cardTo, sat(ly, 1), sat(headCol, stringWidth(edge.cardTo)));
4932
4379
  }
4933
4380
  }
4934
4381
  function routeSkipLr(canvas, from, to, edge, bus) {
@@ -4978,7 +4425,7 @@ function routeBackLr(canvas, from, to, edge, laneY, laneLabels) {
4978
4425
  }
4979
4426
  function placeLaneLabels(canvas, labels) {
4980
4427
  for (const { text, y, lo, hi } of labels) {
4981
- const tw = stringWidth2(text);
4428
+ const tw = stringWidth(text);
4982
4429
  const lastStart = hi - 1 - tw;
4983
4430
  if (lastStart < lo + 1 || y >= canvas.h)
4984
4431
  continue;
@@ -5488,10 +4935,10 @@ function parseEr(src) {
5488
4935
  }
5489
4936
  const rel = splitErRelationship(st);
5490
4937
  if (rel) {
5491
- const tokens = erTokens(rel.rel);
5492
- const op = tokens.length === 3 ? parseErOp(tokens[1]) : null;
5493
- const f = op === null ? null : erEntity(graph, tokens[0]);
5494
- const t2 = f === null ? null : erEntity(graph, tokens[2]);
4938
+ const tokens2 = erTokens(rel.rel);
4939
+ const op = tokens2.length === 3 ? parseErOp(tokens2[1]) : null;
4940
+ const f = op === null ? null : erEntity(graph, tokens2[0]);
4941
+ const t2 = f === null ? null : erEntity(graph, tokens2[2]);
5495
4942
  if (op === null || f === null || t2 === null) {
5496
4943
  graph.drop(st);
5497
4944
  } else {
@@ -6076,7 +5523,7 @@ var gitgraph = {
6076
5523
  parts.push([`\u21D0 ${branches[c.mergeFrom]}`, "edgeLabel"]);
6077
5524
  return parts;
6078
5525
  });
6079
- const width = graphW + Math.max(1, ...labels.map((parts) => parts === null ? 0 : parts.reduce((w, [t2]) => w + stringWidth2(t2) + 1, 0) - 1));
5526
+ const width = graphW + Math.max(1, ...labels.map((parts) => parts === null ? 0 : parts.reduce((w, [t2]) => w + stringWidth(t2) + 1, 0) - 1));
6080
5527
  const canvas = new Canvas(width, rows.length);
6081
5528
  const live = /* @__PURE__ */ new Set();
6082
5529
  rows.forEach((row, y) => {
@@ -6091,7 +5538,7 @@ var gitgraph = {
6091
5538
  let x = graphW;
6092
5539
  for (const [text, role] of labels[y] ?? []) {
6093
5540
  drawText(canvas, text, x, y, role);
6094
- x += stringWidth2(text) + 1;
5541
+ x += stringWidth(text) + 1;
6095
5542
  }
6096
5543
  return;
6097
5544
  }
@@ -6222,11 +5669,11 @@ var mindmap = {
6222
5669
  };
6223
5670
  for (const root of roots)
6224
5671
  walk(root, "", "");
6225
- const width = Math.max(...rows.map(([p, t2]) => stringWidth2(p) + stringWidth2(t2)));
5672
+ const width = Math.max(...rows.map(([p, t2]) => stringWidth(p) + stringWidth(t2)));
6226
5673
  const canvas = new Canvas(width, rows.length);
6227
5674
  rows.forEach(([prefix, text], y) => {
6228
5675
  drawText(canvas, prefix, 0, y, "edge");
6229
- drawText(canvas, text, stringWidth2(prefix), y, "text");
5676
+ drawText(canvas, text, stringWidth(prefix), y, "text");
6230
5677
  });
6231
5678
  return { canvas, warnings, classDefs: {} };
6232
5679
  }
@@ -6301,7 +5748,7 @@ var pie = {
6301
5748
  if (parsed === null)
6302
5749
  return null;
6303
5750
  const { title, slices, showData, warnings } = parsed;
6304
- const labelW = Math.max(...slices.map((s) => stringWidth2(s.label)));
5751
+ const labelW = Math.max(...slices.map((s) => stringWidth(s.label)));
6305
5752
  const total = slices.reduce((sum, s) => sum + s.value, 0);
6306
5753
  const rows = slices.map((s) => {
6307
5754
  const share = total === 0 ? 0 : s.value / total;
@@ -6311,11 +5758,11 @@ var pie = {
6311
5758
  });
6312
5759
  const barX = labelW + 2;
6313
5760
  const suffixX = barX + BAR_W + 1;
6314
- const width = suffixX + Math.max(...rows.map((r) => stringWidth2(r.suffix)));
5761
+ const width = suffixX + Math.max(...rows.map((r) => stringWidth(r.suffix)));
6315
5762
  const top = title === null ? 0 : 1;
6316
5763
  const canvas = new Canvas(width, top + rows.length);
6317
5764
  if (title !== null) {
6318
- drawText(canvas, title, Math.max(0, Math.floor((width - stringWidth2(title)) / 2)), 0, "title");
5765
+ drawText(canvas, title, Math.max(0, Math.floor((width - stringWidth(title)) / 2)), 0, "title");
6319
5766
  }
6320
5767
  rows.forEach((r, i) => {
6321
5768
  const y = top + i;
@@ -6325,7 +5772,7 @@ var pie = {
6325
5772
  if (bar === "" && r.value > 0)
6326
5773
  bar = "\u258F";
6327
5774
  drawText(canvas, bar, barX, y, "edge");
6328
- drawText(canvas, "\u2591".repeat(BAR_W - stringWidth2(bar)), barX + stringWidth2(bar), y, "border");
5775
+ drawText(canvas, "\u2591".repeat(BAR_W - stringWidth(bar)), barX + stringWidth(bar), y, "border");
6329
5776
  drawText(canvas, r.suffix, suffixX, y, "edgeLabel");
6330
5777
  });
6331
5778
  return { canvas, warnings, classDefs: {} };
@@ -6389,11 +5836,11 @@ function noteGeometry(xs, anchor, textW) {
6389
5836
  return { x: sat(xs[anchor.at], 2 + w - 1), w };
6390
5837
  return { x: xs[anchor.at] + 2, w };
6391
5838
  }
6392
- var itemTextW = (text) => text === null ? 0 : stringWidth2(text);
5839
+ var itemTextW = (text) => text === null ? 0 : stringWidth(text);
6393
5840
  function layoutSequence(seq) {
6394
5841
  const n = seq.labels.length;
6395
5842
  const labels = seq.labels.map((l) => fitLabel(l, WRAP_WIDTH));
6396
- const boxW = labels.map((l) => Math.max(1, stringWidth2(l)) + 2 * PAD + 2);
5843
+ const boxW = labels.map((l) => Math.max(1, stringWidth(l)) + 2 * PAD + 2);
6397
5844
  const boxH = 3;
6398
5845
  const gaps = Array.from({ length: sat(n, 1) }, (_, i) => Math.max(SEQ_GAP, Math.ceil(boxW[i] / 2) + Math.ceil(boxW[i + 1] / 2) + 1));
6399
5846
  const reqs = [];
@@ -6406,7 +5853,7 @@ function layoutSequence(seq) {
6406
5853
  reqs.push([item.from, item.from + 1, 5 + tw + 2]);
6407
5854
  }
6408
5855
  } else if (item.kind === "note") {
6409
- const tw = stringWidth2(item.text);
5856
+ const tw = stringWidth(item.text);
6410
5857
  const a = item.anchor;
6411
5858
  if (a.kind === "over" && a.from < a.to) {
6412
5859
  reqs.push([a.from, a.to, sat(tw, 1)]);
@@ -6438,7 +5885,7 @@ function layoutSequence(seq) {
6438
5885
  let leftPad = 0;
6439
5886
  for (const item of seq.items) {
6440
5887
  if (item.kind === "note" && item.anchor.kind === "left" && item.anchor.at === 0) {
6441
- const w = stringWidth2(item.text) + 2 * PAD + 2;
5888
+ const w = stringWidth(item.text) + 2 * PAD + 2;
6442
5889
  leftPad = Math.max(leftPad, sat(w + 1, xs[0]));
6443
5890
  }
6444
5891
  }
@@ -6450,10 +5897,10 @@ function layoutSequence(seq) {
6450
5897
  if (item.kind === "message" && item.from === item.to) {
6451
5898
  canvasW = Math.max(canvasW, xs[item.from] + 5 + itemTextW(item.text) + 1);
6452
5899
  } else if (item.kind === "note") {
6453
- const g = noteGeometry(xs, item.anchor, stringWidth2(item.text));
5900
+ const g = noteGeometry(xs, item.anchor, stringWidth(item.text));
6454
5901
  canvasW = Math.max(canvasW, g.x + g.w + 1);
6455
5902
  } else if (item.kind === "divider") {
6456
- canvasW = Math.max(canvasW, stringWidth2(item.text) + 4);
5903
+ canvasW = Math.max(canvasW, stringWidth(item.text) + 4);
6457
5904
  }
6458
5905
  }
6459
5906
  const rows = [];
@@ -6475,7 +5922,7 @@ function layoutSequence(seq) {
6475
5922
  seq.items.forEach((item, k) => {
6476
5923
  if (item.kind !== "note")
6477
5924
  return;
6478
- const g = noteGeometry(xs, item.anchor, stringWidth2(item.text));
5925
+ const g = noteGeometry(xs, item.anchor, stringWidth(item.text));
6479
5926
  drawBox(canvas, box(g.x, rows[k], g.w, 3), [item.text], "rect");
6480
5927
  });
6481
5928
  for (const x of xs) {
@@ -6558,7 +6005,7 @@ function drawMessage(canvas, item, xs, r) {
6558
6005
  if (item.text !== null) {
6559
6006
  const span = hi - lo - 1;
6560
6007
  const t2 = fitLabel(item.text, Math.max(1, span));
6561
- drawTextOverEdges(canvas, t2, lo + 1 + half(sat(span, stringWidth2(t2))), r, "text");
6008
+ drawTextOverEdges(canvas, t2, lo + 1 + half(sat(span, stringWidth(t2))), r, "text");
6562
6009
  }
6563
6010
  }
6564
6011
  function drawDivider(canvas, text, r, canvasW) {
@@ -7058,16 +6505,16 @@ var timeline = {
7058
6505
  if (parsed === null)
7059
6506
  return null;
7060
6507
  const { title, rows, warnings } = parsed;
7061
- const periodW = Math.max(...rows.map((r) => r.section ? 0 : stringWidth2(r.period)));
6508
+ const periodW = Math.max(...rows.map((r) => r.section ? 0 : stringWidth(r.period)));
7062
6509
  const top = title === null ? 0 : 1;
7063
- const width = Math.max(title === null ? 0 : stringWidth2(title) + 6, ...rows.map((r) => r.section ? stringWidth2(r.event) : periodW + 3 + stringWidth2(r.event)));
6510
+ const width = Math.max(title === null ? 0 : stringWidth(title) + 6, ...rows.map((r) => r.section ? stringWidth(r.event) : periodW + 3 + stringWidth(r.event)));
7064
6511
  const canvas = new Canvas(width, top + rows.length);
7065
6512
  if (title !== null) {
7066
6513
  const t2 = ` ${title} `;
7067
- const x = Math.max(0, Math.floor((width - stringWidth2(t2) - 4) / 2));
6514
+ const x = Math.max(0, Math.floor((width - stringWidth(t2) - 4) / 2));
7068
6515
  drawText(canvas, "\u2500\u2500", x, 0, "edge");
7069
6516
  drawText(canvas, t2, x + 2, 0, "title");
7070
- drawText(canvas, "\u2500\u2500", x + 2 + stringWidth2(t2), 0, "edge");
6517
+ drawText(canvas, "\u2500\u2500", x + 2 + stringWidth(t2), 0, "edge");
7071
6518
  }
7072
6519
  rows.forEach((row, i) => {
7073
6520
  const y = top + i;
@@ -7394,11 +6841,11 @@ function sourceBox(src, maxWidth) {
7394
6841
  acc.lines.push(...chunkLine(l, limit));
7395
6842
  return acc;
7396
6843
  }, { started: false, lines: [] }).lines;
7397
- const contentW = body.reduce((w, l) => Math.max(w, stringWidth2(l)), stringWidth2(title));
6844
+ const contentW = body.reduce((w, l) => Math.max(w, stringWidth(l)), stringWidth(title));
7398
6845
  const inner = contentW + 2;
7399
6846
  const plain = [];
7400
6847
  const styled = [];
7401
- const rule = "\u2500".repeat(sat(inner, stringWidth2(title)));
6848
+ const rule = "\u2500".repeat(sat(inner, stringWidth(title)));
7402
6849
  plain.push(`\u256D${title}${rule}\u256E`);
7403
6850
  styled.push([
7404
6851
  { text: "\u256D", role: "border" },
@@ -7406,7 +6853,7 @@ function sourceBox(src, maxWidth) {
7406
6853
  { text: `${rule}\u256E`, role: "border" }
7407
6854
  ]);
7408
6855
  for (const line of body) {
7409
- const pad = " ".repeat(sat(contentW, stringWidth2(line)));
6856
+ const pad = " ".repeat(sat(contentW, stringWidth(line)));
7410
6857
  plain.push(`\u2502 ${line}${pad} \u2502`);
7411
6858
  styled.push([
7412
6859
  { text: "\u2502 ", role: "border" },
@@ -7437,7 +6884,7 @@ function expandTabs(line) {
7437
6884
  return out;
7438
6885
  }
7439
6886
  function chunkLine(line, limit) {
7440
- if (limit === void 0 || stringWidth2(line) <= limit)
6887
+ if (limit === void 0 || stringWidth(line) <= limit)
7441
6888
  return [line];
7442
6889
  const out = [];
7443
6890
  let cur = "";
@@ -7467,7 +6914,7 @@ function render(src) {
7467
6914
  const art = drawn.canvas.toLines();
7468
6915
  const title = frontmatterTitle(src);
7469
6916
  if (title !== null) {
7470
- const tw = stringWidth2(title);
6917
+ const tw = stringWidth(title);
7471
6918
  art.width = Math.max(art.width, tw);
7472
6919
  const pad = " ".repeat(Math.floor((art.width - tw) / 2));
7473
6920
  art.plain.unshift(pad + title, "");
@@ -7936,7 +7383,7 @@ function renderMathBlock(latex, options = {}) {
7936
7383
  const den = transpileLatexToUnicode(fracMatch[2] ?? "");
7937
7384
  if (num.length > 8 || den.length > 8 || num.includes("+") || den.includes("+") || num.includes("-") || den.includes("-")) {
7938
7385
  const width = Math.max(visibleWidth(num), visibleWidth(den)) + 2;
7939
- const bar = "\u2500".repeat(width);
7386
+ const bar = boxGlyphs(resolveBoxCharset()).h.repeat(width);
7940
7387
  const padNum = " ".repeat(Math.max(0, Math.floor((width - visibleWidth(num)) / 2)));
7941
7388
  const padDen = " ".repeat(Math.max(0, Math.floor((width - visibleWidth(den)) / 2)));
7942
7389
  const l1 = padNum + num;
@@ -8183,21 +7630,21 @@ function resolveTableWidth(explicit, env = process.env) {
8183
7630
  }
8184
7631
  function wrapCellToWidth(text, max) {
8185
7632
  if (max <= 0 || displayWidth(text) <= max) return [text];
8186
- const tokens = tokenizeAnsiLine(text);
7633
+ const tokens2 = tokenizeAnsiLine(text);
8187
7634
  const charTokenIdx = [];
8188
- tokens.forEach((t2, i) => {
7635
+ tokens2.forEach((t2, i) => {
8189
7636
  if (t2.kind === "char") charTokenIdx.push(i);
8190
7637
  });
8191
7638
  const n = charTokenIdx.length;
8192
7639
  if (n === 0) return [text];
8193
- const widths = charTokenIdx.map((i) => tokens[i].width);
7640
+ const widths = charTokenIdx.map((i) => tokens2[i].width);
8194
7641
  const prefix = [0];
8195
7642
  for (let i = 0; i < widths.length; i += 1) prefix.push(prefix[i] + widths[i]);
8196
7643
  const segWidth = (a, b) => prefix[b] - prefix[a];
8197
7644
  const sliceTokens = (a, b) => {
8198
7645
  const startTok = a === 0 ? 0 : charTokenIdx[a - 1] + 1;
8199
- const endTok = b < n ? charTokenIdx[b] - 1 : tokens.length - 1;
8200
- return tokens.slice(startTok, endTok + 1);
7646
+ const endTok = b < n ? charTokenIdx[b] - 1 : tokens2.length - 1;
7647
+ return tokens2.slice(startTok, endTok + 1);
8201
7648
  };
8202
7649
  const applyStyles = (slice, state2) => {
8203
7650
  const next = [...state2];
@@ -8212,7 +7659,7 @@ function wrapCellToWidth(text, max) {
8212
7659
  }
8213
7660
  } else if (OSC8_OPENER_REGEX.test(t2.value)) {
8214
7661
  next.push(t2.value);
8215
- } else if (SGR_RESET_REGEX2.test(t2.value)) {
7662
+ } else if (SGR_RESET_REGEX.test(t2.value)) {
8216
7663
  for (let i = next.length - 1; i >= 0; i -= 1) {
8217
7664
  if (!OSC8_OPENER_REGEX.test(next[i]) && !OSC8_CLOSER_REGEX.test(next[i])) {
8218
7665
  next.splice(i, 1);
@@ -8244,7 +7691,7 @@ function wrapCellToWidth(text, max) {
8244
7691
  if (segWidth(start, i + 1) <= max) continue;
8245
7692
  let cut = -1;
8246
7693
  for (let j = i - 1; j > start; j -= 1) {
8247
- if (tokens[charTokenIdx[j]].value !== " ") continue;
7694
+ if (tokens2[charTokenIdx[j]].value !== " ") continue;
8248
7695
  if (segWidth(start, j) <= max && segWidth(j + 1, i + 1) <= max) {
8249
7696
  cut = j;
8250
7697
  break;
@@ -8275,7 +7722,7 @@ function wrapCellToWidth(text, max) {
8275
7722
  }
8276
7723
  return segments.length > 0 ? segments : [text];
8277
7724
  }
8278
- var SGR_RESET_REGEX2 = /^\x1b\[0?m$/;
7725
+ var SGR_RESET_REGEX = /^\x1b\[0?m$/;
8279
7726
  var OSC8_OPENER_REGEX = /^\x1b\]8;;[^\x07\x1b]+(?:\x07|\x1b\\)$/;
8280
7727
  var OSC8_CLOSER_REGEX = /^\x1b\]8;;\x1b\\$/;
8281
7728
  function padCell(text, width, align) {
@@ -8330,21 +7777,22 @@ function makeStyle(brightness, headerToken) {
8330
7777
  const paint = (t2) => `${color}${boldOn}${t2}${reset}`;
8331
7778
  return { header: paint, label: paint };
8332
7779
  }
8333
- function boxLine(left, mid, right, widths) {
8334
- const seg = widths.map((w) => "\u2500".repeat(w + 2));
7780
+ function boxLine(glyphs, left, mid, right, widths) {
7781
+ const seg = widths.map((w) => glyphs.h.repeat(w + 2));
8335
7782
  return `${left}${seg.join(mid)}${right}`;
8336
7783
  }
8337
- function dataRow(cells, aligns, widths, style, header) {
7784
+ function dataRow(cells, aligns, widths, style, header, glyphs) {
8338
7785
  const parts = cells.map((cell, i) => {
8339
7786
  const width = widths[i] ?? 0;
8340
7787
  const align = aligns[i] ?? "left";
8341
7788
  const padded = padCell(cell, width, align);
8342
7789
  const styled = header ? style.header(padded) : padded;
8343
- return ` ${styled} \u2502`;
7790
+ return ` ${styled} ${glyphs.v}`;
8344
7791
  });
8345
- return `\u2502${parts.join("")}`;
7792
+ return `${glyphs.v}${parts.join("")}`;
8346
7793
  }
8347
- function renderBoxTable(table, width, style) {
7794
+ function renderBoxTable(table, width, style, charset = resolveBoxCharset()) {
7795
+ const glyphs = boxGlyphs(charset);
8348
7796
  const colCount = table.headers.length;
8349
7797
  const widths = computeColumnWidths(table.headers, table.rows, width);
8350
7798
  const headerGrid = table.headers.map(
@@ -8358,7 +7806,7 @@ function renderBoxTable(table, width, style) {
8358
7806
  (r) => Math.max(1, ...r.map((g) => g.length))
8359
7807
  );
8360
7808
  const lines = [];
8361
- lines.push(boxLine("\u250C", "\u252C", "\u2510", widths));
7809
+ lines.push(boxLine(glyphs, glyphs.tl, glyphs.tm, glyphs.tr, widths));
8362
7810
  for (let r = 0; r < headerDisplayRows; r += 1) {
8363
7811
  lines.push(
8364
7812
  dataRow(
@@ -8366,15 +7814,16 @@ function renderBoxTable(table, width, style) {
8366
7814
  table.aligns,
8367
7815
  widths,
8368
7816
  style,
8369
- true
7817
+ true,
7818
+ glyphs
8370
7819
  )
8371
7820
  );
8372
7821
  }
8373
- lines.push(boxLine("\u251C", "\u253C", "\u2524", widths));
7822
+ lines.push(boxLine(glyphs, glyphs.ml, glyphs.mm, glyphs.mr, widths));
8374
7823
  const hasMultiLineRecord = bodyDisplayRows.some((rows) => rows > 1);
8375
7824
  bodyGrids.forEach((_, rec) => {
8376
7825
  if (hasMultiLineRecord && rec > 0) {
8377
- lines.push(boxLine("\u251C", "\u253C", "\u2524", widths));
7826
+ lines.push(boxLine(glyphs, glyphs.ml, glyphs.mm, glyphs.mr, widths));
8378
7827
  }
8379
7828
  for (let r = 0; r < bodyDisplayRows[rec]; r += 1) {
8380
7829
  lines.push(
@@ -8386,12 +7835,13 @@ function renderBoxTable(table, width, style) {
8386
7835
  table.aligns,
8387
7836
  widths,
8388
7837
  style,
8389
- false
7838
+ false,
7839
+ glyphs
8390
7840
  )
8391
7841
  );
8392
7842
  }
8393
7843
  });
8394
- lines.push(boxLine("\u2514", "\u2534", "\u2518", widths));
7844
+ lines.push(boxLine(glyphs, glyphs.bl, glyphs.bm, glyphs.br, widths));
8395
7845
  return lines.join("\n");
8396
7846
  }
8397
7847
  function renderRecordCards(table, width, style) {
@@ -8435,7 +7885,12 @@ function renderMarkdownTable(table, options = {}) {
8435
7885
  if (width < 40 || table.headers.length > 6) {
8436
7886
  return renderRecordCards(styledTable, width, style);
8437
7887
  }
8438
- return renderBoxTable(styledTable, width, style);
7888
+ return renderBoxTable(
7889
+ styledTable,
7890
+ width,
7891
+ style,
7892
+ options.boxCharset ?? resolveBoxCharset()
7893
+ );
8439
7894
  }
8440
7895
 
8441
7896
  // packages/cli/client/assistantOutput.ts
@@ -8684,11 +8139,10 @@ function normalizeListLine(line) {
8684
8139
  }
8685
8140
  return line;
8686
8141
  }
8687
- var TOOL_TREE_HEADER_RE = /^•\s+(.+?)\s+\((\d+)\)$/;
8688
- var TOOL_TREE_LEAF_RE = /^([├└]──\s+)(.*?)\s{2}(✓|✗|!)(?:\s+(.*))?$/;
8142
+ var TOOL_TREE_HEADER_RE = /^•\s+(.+?)\s+\((\d+)\) · (.*?) ✓$/;
8689
8143
  var TOOL_SINGLE_RE = /^▸\s+(.+?)(?:\s+·\s+(.*?))?(?:\s{2}(✓|✗|!)(?:\s+(.*))?)$/;
8690
8144
  function plainToolLine(line) {
8691
- return stripAnsi2(line);
8145
+ return stripAnsi(line);
8692
8146
  }
8693
8147
  var TOOL_TREE_GROUP_LABELS = new Set(
8694
8148
  ["execShell", "readFile", "fetchWebpage", "exa_search"].flatMap(toolLabelVariants)
@@ -8703,9 +8157,6 @@ function toolTreeHeaderMatch(line) {
8703
8157
  function isToolTreeHeaderLine(line) {
8704
8158
  return toolTreeHeaderMatch(line) !== null;
8705
8159
  }
8706
- function isToolTreeLeafLine(line) {
8707
- return TOOL_TREE_LEAF_RE.test(plainToolLine(line));
8708
- }
8709
8160
  function isToolSingleLine(line) {
8710
8161
  return TOOL_SINGLE_RE.test(plainToolLine(line));
8711
8162
  }
@@ -8724,17 +8175,10 @@ function toolGroupKeyOf(line) {
8724
8175
  return null;
8725
8176
  }
8726
8177
  function toolRowBoundary(cur, next) {
8727
- const curLeaf = isToolTreeLeafLine(cur);
8728
- const curHeader = isToolTreeHeaderLine(cur);
8729
- const nextLeaf = isToolTreeLeafLine(next);
8730
8178
  const curKey = toolGroupKeyOf(cur);
8731
8179
  const nextKey = toolGroupKeyOf(next);
8732
- if (curKey === null && !curLeaf) return null;
8733
- if (nextKey === null && !nextLeaf) return null;
8734
- if (curLeaf) return !nextLeaf;
8735
- if (curHeader && nextLeaf) return false;
8736
- if (curKey !== null && nextKey !== null) return curKey !== nextKey;
8737
- return true;
8180
+ if (curKey === null || nextKey === null) return null;
8181
+ return isToolTreeHeaderLine(cur) || isToolTreeHeaderLine(next) || curKey !== nextKey;
8738
8182
  }
8739
8183
  function statusColorSeq(marker, brightness) {
8740
8184
  if (marker === "\u2713") return colorSeq("success", brightness);
@@ -8747,18 +8191,7 @@ function styleTuiToolLine(line, brightness) {
8747
8191
  const muted = colorSeq("muted", brightness);
8748
8192
  const header = toolTreeHeaderMatch(plain);
8749
8193
  if (header) {
8750
- return `${chrome}\u2022${STYLE.reset} ${STYLE.bold}${muted}${header[1]}${STYLE.reset} ${chrome}${STYLE.dim}(${header[2]})${STYLE.reset}`;
8751
- }
8752
- const leaf = plain.match(TOOL_TREE_LEAF_RE);
8753
- if (leaf) {
8754
- const [, connector, detail, marker, statusDetail] = leaf;
8755
- let rendered = `${chrome}${connector}${STYLE.reset}${chrome}${detail}${STYLE.reset}`;
8756
- rendered += ` ${statusColorSeq(marker, brightness)}${marker}${STYLE.reset}`;
8757
- if (statusDetail) {
8758
- const metaSeq = marker === "\u2713" ? chrome : statusColorSeq(marker, brightness);
8759
- rendered += ` ${metaSeq}${STYLE.dim}${statusDetail}${STYLE.reset}`;
8760
- }
8761
- return rendered;
8194
+ return `${chrome}\u2022${STYLE.reset} ${STYLE.bold}${muted}${header[1]}${STYLE.reset} ${chrome}${STYLE.dim}(${header[2]})${STYLE.reset} ${chrome}\xB7 ${header[3]}${STYLE.reset} ${statusColorSeq("\u2713", brightness)}\u2713${STYLE.reset}`;
8762
8195
  }
8763
8196
  const single = plain.match(TOOL_SINGLE_RE);
8764
8197
  if (single) {
@@ -8782,14 +8215,14 @@ function isPolishFenceInteriorLine(line) {
8782
8215
  return /^\x00F\d+\x00$/.test(line);
8783
8216
  }
8784
8217
  function polishHeadingLevel(line) {
8785
- const match = stripAnsi2(line).match(/^(#{1,6})\s/);
8218
+ const match = stripAnsi(line).match(/^(#{1,6})\s/);
8786
8219
  return match ? match[1].length : null;
8787
8220
  }
8788
8221
  function isPolishHeadingLine(line) {
8789
8222
  return polishHeadingLevel(line) !== null;
8790
8223
  }
8791
8224
  function isPolishIntroLine(line) {
8792
- const plain = stripAnsi2(line).trimEnd();
8225
+ const plain = stripAnsi(line).trimEnd();
8793
8226
  return plain.endsWith("\uFF1A") || plain.endsWith(":");
8794
8227
  }
8795
8228
  function polishBreathInsertsBlankBetween(cur, next) {
@@ -8917,7 +8350,7 @@ function styleRichMarkdownLine(line, brightness) {
8917
8350
  return `${border}\u2502${STYLE.reset} ${STYLE.dim}${styled}${STYLE.reset}`;
8918
8351
  }
8919
8352
  if (THEMATIC_BREAK_RE.test(line)) {
8920
- return `${colorSeq("chrome", brightness)}${STYLE.dim}${"\u2500".repeat(36)}${STYLE.reset}`;
8353
+ return `${colorSeq("chrome", brightness)}${STYLE.dim}${boxGlyphs(resolveBoxCharset()).h.repeat(36)}${STYLE.reset}`;
8921
8354
  }
8922
8355
  const bullet = line.match(/^(\s*)(•)\s(.+)$/);
8923
8356
  if (bullet) {
@@ -9091,7 +8524,6 @@ function classifyStreamLine(line) {
9091
8524
  if (line === "") return "blank";
9092
8525
  const plain = plainToolLine(line);
9093
8526
  if (isToolTreeHeaderLine(plain)) return "tool-header";
9094
- if (isToolTreeLeafLine(plain)) return "tool-leaf";
9095
8527
  if (isToolSingleLine(plain)) return "tool";
9096
8528
  if (TASK_LIST_RE.test(plain) || UNORDERED_LIST_RE.test(plain) || ORDERED_LIST_RE.test(plain) || /^\s*(?:•|◦|☐|☑)\s/.test(plain) || /^\s*[\u2460-\u2473]/.test(plain)) {
9097
8529
  return "list";
@@ -9101,10 +8533,10 @@ function classifyStreamLine(line) {
9101
8533
  return "prose";
9102
8534
  }
9103
8535
  function isStreamToolKind(kind) {
9104
- return kind === "tool-header" || kind === "tool-leaf" || kind === "tool";
8536
+ return kind === "tool-header" || kind === "tool";
9105
8537
  }
9106
8538
  function isStreamListLike(kind) {
9107
- return kind === "list" || kind === "tool-header" || kind === "tool-leaf" || kind === "tool";
8539
+ return kind === "list" || kind === "tool-header" || kind === "tool";
9108
8540
  }
9109
8541
  function needsListProseBreath(prev, next, prevLine = "", nextLine = "") {
9110
8542
  if (prev === null || prev === "blank" || next === "blank") return false;
@@ -9300,44 +8732,35 @@ function formatAssistantTextForCli(text) {
9300
8732
  return text.replace(/\u003cthink\u003e[\s\S]*?\u003c\/think\u003e\s*/gi, "").replace(/\n{3,}/g, "\n\n").trim();
9301
8733
  }
9302
8734
 
9303
- // packages/cli/tui/redactSecrets.ts
9304
- var REDACTED = "\u27E8redacted\u27E9";
9305
- function redactSecrets(text) {
9306
- return text.replace(/\b(?:sk|pk)-[A-Za-z0-9_-]{10,}/g, REDACTED).replace(/\b(Bearer\s+)[A-Za-z0-9._~+/=-]{12,}/gi, `$1${REDACTED}`).replace(
9307
- /\b((?:api[_-]?key|apikey|access[_-]?token|auth[_-]?token|token|secret|password|passwd|credential)s?\s*[=:]\s*["']?)[^\s"',;]{8,}/gi,
9308
- `$1${REDACTED}`
9309
- ).replace(
9310
- /\b((?:--[a-z-]*(?:token|key|secret|password|credential)[a-z-]*)\s+)[^\s"']{8,}/gi,
9311
- `$1${REDACTED}`
9312
- );
9313
- }
9314
-
9315
- // packages/cli/tui/askTextSanitize.ts
9316
- var ASK_SECRET_PLACEHOLDER = "\u27E8redacted\u27E9";
9317
- var C0_C1_CONTROL_REGEX = /[\x00-\x1f\x7f-\x9f]/g;
9318
- var NORMAL_GIST_SECRET_PATTERNS = [
9319
- /\bbearer\s+[A-Za-z0-9._~+/=-]{8,}/i,
9320
- /\bsk-(?:ant-)?(?:api)?[0-9a-zA-Z-]{10,}/,
9321
- /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{10,}/,
9322
- /\bxox[baprs]-[A-Za-z0-9-]{10,}/
9323
- ];
9324
- function withholdIfSecretLike(gist) {
9325
- if (!gist) return "";
9326
- if (findPotentialSecrets(gist).length > 0) return "";
9327
- if (NORMAL_GIST_SECRET_PATTERNS.some((pattern) => pattern.test(gist))) return "";
9328
- return gist;
9329
- }
9330
- function toText(value) {
9331
- return typeof value === "string" ? value : String(value ?? "");
9332
- }
9333
- function cleanAskText(value) {
9334
- return stripAnsi2(toText(value)).replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").replace(C0_C1_CONTROL_REGEX, "").replace(/\s+/g, " ").trim();
8735
+ // packages/cli/tui/tuiLayout.ts
8736
+ var DEFAULT_TERMINAL_ROWS = 24;
8737
+ var DEFAULT_TERMINAL_COLUMNS = 80;
8738
+ var TUI_MARGIN_LEFT = 1;
8739
+ var TUI_MARGIN_RIGHT = 1;
8740
+ var TUI_MARGIN_RESPONSIVE_MIN_COLUMNS = 40;
8741
+ function resolveHistoryLayoutGeometry(columns) {
8742
+ const cols = Math.max(1, (columns ?? 0) > 0 ? columns : DEFAULT_TERMINAL_COLUMNS);
8743
+ if (cols <= TUI_MARGIN_RESPONSIVE_MIN_COLUMNS) {
8744
+ return {
8745
+ contentWidth: Math.max(1, cols - 1),
8746
+ marginLeft: 0,
8747
+ marginRight: 0
8748
+ };
8749
+ }
8750
+ const marginLeft = TUI_MARGIN_LEFT;
8751
+ const marginRight = TUI_MARGIN_RIGHT;
8752
+ const contentWidth = Math.max(1, cols - 1 - marginLeft - marginRight);
8753
+ return {
8754
+ contentWidth,
8755
+ marginLeft,
8756
+ marginRight
8757
+ };
9335
8758
  }
9336
- function safeAskText(value, max) {
9337
- const cleaned = redactSecrets(cleanAskText(value));
9338
- if (!cleaned) return "";
9339
- const guarded = withholdIfSecretLike(cleaned) || ASK_SECRET_PLACEHOLDER;
9340
- return max === void 0 ? guarded : clipCompactText(guarded, max, "\u2026");
8759
+ function resolveHistoryViewportHeight(terminalRows, composerRows, foregroundReservedRows = 0) {
8760
+ const rows = Math.max(1, terminalRows > 0 ? terminalRows : DEFAULT_TERMINAL_ROWS);
8761
+ const composer = Math.max(0, composerRows);
8762
+ const reserved = Math.max(0, foregroundReservedRows);
8763
+ return Math.max(0, rows - composer - reserved);
9341
8764
  }
9342
8765
 
9343
8766
  // node_modules/diff/libesm/diff/base.js
@@ -9686,9 +9109,6 @@ function formatConservativeActiveToolLabel(event) {
9686
9109
  function isRunToolName(name) {
9687
9110
  return name === "execShell" || name === "runCommand" || name === "launchProcess";
9688
9111
  }
9689
- function isReadToolName(name) {
9690
- return name === "readFile";
9691
- }
9692
9112
  function isFailedToolResult(event) {
9693
9113
  const exitCode = event.metadata?.exitCode;
9694
9114
  if (event.metadata?.actionGate) return false;
@@ -9880,7 +9300,7 @@ function formatToolTraceLine(text, colorEnabled, accent = "none") {
9880
9300
  return `${dimCliText(text, true)}
9881
9301
  `;
9882
9302
  }
9883
- var cleanUserText = (value) => stripAnsi2(value).replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
9303
+ var cleanUserText = (value) => stripAnsi(value).replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
9884
9304
  function renderRunCard(snapshot, opts) {
9885
9305
  const labels = agentRunCardLabels();
9886
9306
  const timing = { startedAt: snapshot.startedAt, finishedAt: snapshot.finishedAt };
@@ -9995,7 +9415,7 @@ function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
9995
9415
  const failed = event.type === "tool-error" || isFailedToolResult(event) || Boolean(event.metadata?.failed) || listFailed || /^Error:/i.test(rawDataStr.trim());
9996
9416
  if (failed) {
9997
9417
  const failureSnapshot = toolName === "startAgentRun" ? parseAgentRunEvent(event)?.snapshot : void 0;
9998
- const firstLine = stripAnsi2(failureSnapshot?.errorMessage || rawDataStr.trim().split("\n")[0] || event.summary || event.message || t("toolFailed"));
9418
+ const firstLine = stripAnsi(failureSnapshot?.errorMessage || rawDataStr.trim().split("\n")[0] || event.summary || event.message || t("toolFailed"));
9999
9419
  const message = clip(redactSecrets(firstLine), 96);
10000
9420
  if (!colorEnabled) {
10001
9421
  return `\u2717 ${rawLabel} ${message}
@@ -10007,8 +9427,24 @@ function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
10007
9427
  return `${cross} ${labelPart2} ${msgPart}
10008
9428
  `;
10009
9429
  }
9430
+ if (opts?.visibleRunIds && toolName === "startAgentRun") {
9431
+ const started = parseAgentRunEvent(event);
9432
+ const runId = started?.snapshot.runId;
9433
+ const startedStatus = started?.snapshot.status;
9434
+ if (started?.kind === "start" && typeof runId === "string" && runId.length > 0 && !started.snapshot.errorMessage && // 只认 core 定义的已知正常态。unknown/cancelling/not_found/未来新增状态
9435
+ // 都不算正常 → 保留回执。
9436
+ isAgentRunStatusNormal(startedStatus)) {
9437
+ let visible;
9438
+ try {
9439
+ visible = opts.visibleRunIds();
9440
+ } catch {
9441
+ visible = void 0;
9442
+ }
9443
+ if (visible?.has(runId)) return "";
9444
+ }
9445
+ }
10010
9446
  const parsedStart = toolName === "startAgentRun" ? parseAgentRunEvent(event) : null;
10011
- const startFailed = parsedStart && ["failed", "timeout", "orphaned", "cancelled", "killed"].includes(parsedStart.snapshot.status);
9447
+ const startFailed = parsedStart && isAgentRunStartFailureStatus(parsedStart.snapshot.status);
10012
9448
  let heading = parsedStart ? t(startFailed ? "agentStartFailedLabel" : "agentStartedLabel") : rawLabel;
10013
9449
  const displayData = rawDataStr.trim();
10014
9450
  const lines = displayData ? displayData.split("\n") : [];
@@ -10021,7 +9457,13 @@ function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
10021
9457
  heading = t("agentsCompactCount", String(total));
10022
9458
  if (total !== count) heading += ` \xB7 ${t("agentsPageCount", String(count))}`;
10023
9459
  if (listPayload.truncated === true) heading += ` \xB7 ${t("agentsTruncated")}`;
10024
- if (/^(?:Agents|智能体)\s*\(\d+\)$/.test(projected[0]?.trim() ?? "")) {
9460
+ if (/^(?:Agents|智能体|🤖)\s*\(\d+\)$/.test(projected[0]?.trim() ?? "")) {
9461
+ projected = projected.slice(1);
9462
+ }
9463
+ } else {
9464
+ const bakedHeader = /^(?:Agents|智能体|🤖)\s*\((\d+)\)$/.exec(projected[0]?.trim() ?? "");
9465
+ if (bakedHeader) {
9466
+ heading = t("agentsCompactCount", bakedHeader[1]);
10025
9467
  projected = projected.slice(1);
10026
9468
  }
10027
9469
  }
@@ -10064,7 +9506,7 @@ function sanitizeRunCardForNormal(lines) {
10064
9506
  break;
10065
9507
  }
10066
9508
  if (/^\s*error\b/i.test(line)) {
10067
- out.push(clip(redactSecrets(stripAnsi2(line)), 160));
9509
+ out.push(clip(redactSecrets(stripAnsi(line)), 160));
10068
9510
  errorIndent = line.length - line.trimStart().length;
10069
9511
  continue;
10070
9512
  }
@@ -10297,7 +9739,7 @@ function formatNormalToolDuration(elapsedMs) {
10297
9739
  if (elapsedMs < 1e3) return `${Math.round(elapsedMs)}ms`;
10298
9740
  return `${(elapsedMs / 1e3).toFixed(1)}s`;
10299
9741
  }
10300
- function formatNormalToolLine(event, pending, colorEnabled) {
9742
+ function formatNormalToolLine(event, pending, colorEnabled, opts) {
10301
9743
  if (event.type === "tool-call") return "";
10302
9744
  const toolName = event.toolName || pending?.toolName || "tool";
10303
9745
  if (event.type === "tool-result" && (event.toolName === "ask_user" || event.metadata?.uiAskChoice)) {
@@ -10305,7 +9747,10 @@ function formatNormalToolLine(event, pending, colorEnabled) {
10305
9747
  if (block) return block;
10306
9748
  }
10307
9749
  if (event.type === "tool-result" && (toolName === "listAgents" || toolName === "startAgentRun" || toolName === "controlAgentRun")) {
10308
- return formatOrchestrationCardBlock(event, toolName, colorEnabled, { safe: true });
9750
+ return formatOrchestrationCardBlock(event, toolName, colorEnabled, {
9751
+ safe: true,
9752
+ visibleRunIds: opts?.visibleRunIds
9753
+ });
10309
9754
  }
10310
9755
  if (event.type === "tool-result" && toolName === "loadSkill") {
10311
9756
  return formatLoadSkillBlock({ ...event, argumentsPreview: event.argumentsPreview || pending?.argumentsPreview }, colorEnabled, { safe: true }) ?? "";
@@ -10353,7 +9798,7 @@ function toolFailureReason(event) {
10353
9798
  return lines.slice(start + 1, end < 0 ? lines.length : end);
10354
9799
  };
10355
9800
  const reasonLine = sectionLines("stderr")[0] ?? sectionLines("stdout")[0] ?? lines.find((line) => !/^(stdout|stderr|exitCode)\s*:/i.test(line)) ?? lines[0] ?? "";
10356
- return reasonLine ? clip(redactSecrets(stripAnsi2(reasonLine)), 96) : "";
9801
+ return reasonLine ? clip(redactSecrets(stripAnsi(reasonLine)), 96) : "";
10357
9802
  }
10358
9803
  function resolveLoadSkillName(event) {
10359
9804
  const content = typeof event.content === "string" ? event.content : "";
@@ -10419,14 +9864,34 @@ function formatLoadSkillBlock(event, colorEnabled, opts) {
10419
9864
  }
10420
9865
  var TUI_TREE_MARKER = "TUI_TREE\n";
10421
9866
  var TUI_TREE_END = "";
9867
+ var TUI_TREE_TOOLS = {
9868
+ Run: ["execShell", "runCommand", "launchProcess"],
9869
+ Read: ["readFile"],
9870
+ Search: ["exa_search"],
9871
+ Fetch: ["fetchWebpage"]
9872
+ };
10422
9873
  function createToolEventFormatter(colorEnabled = resolveCliColorEnabled(), opts = {}) {
10423
9874
  const pending = /* @__PURE__ */ new Map();
10424
9875
  let tree = null;
10425
- const treeKind = (name) => isRunToolName(name) ? "Run" : isReadToolName(name) ? "Read" : name === "exa_search" ? "Search" : name === "fetchWebpage" ? "Fetch" : null;
10426
- const treeLine = (kind, items) => {
9876
+ const treeKind = (name) => Object.keys(TUI_TREE_TOOLS).find((kind) => TUI_TREE_TOOLS[kind].includes(name)) ?? null;
9877
+ const treeLine = (kind, items, fallback) => {
10427
9878
  const label = kind === "Run" ? toolLabel("execShell") : kind === "Read" ? toolLabel("readFile") : kind === "Fetch" ? toolLabel("fetchWebpage") : toolLabel("exa_search");
10428
- return `${TUI_TREE_MARKER}${label} (${items.length})
10429
- ${items.map((item, i) => `${i === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 "}${item} \u2713`).join("\n")}${TUI_TREE_END}
9879
+ const header = `${label} (${items.length}) \xB7 `;
9880
+ const columns = resolveHistoryLayoutGeometry(process.stdout.columns).contentWidth - displayWidth("\u25C8 ");
9881
+ let shown = 1;
9882
+ for (let count = 2; count <= items.length; count++) {
9883
+ const omitted2 = items.length - count;
9884
+ const suffix = omitted2 ? `, \u2026 +${omitted2}` : "";
9885
+ if (displayWidth(`\u2022 ${header}${items.slice(0, count).join(", ")}${suffix} \u2713`) > columns) break;
9886
+ shown = count;
9887
+ }
9888
+ const omitted = items.length - shown;
9889
+ const payload = {
9890
+ kind,
9891
+ summary: `${header}${items.slice(0, shown).join(", ")}${omitted ? `, \u2026 +${omitted}` : ""} \u2713`,
9892
+ fallback
9893
+ };
9894
+ return `${TUI_TREE_MARKER}${JSON.stringify(payload)}${TUI_TREE_END}
10430
9895
  `;
10431
9896
  };
10432
9897
  const formatTreeEvent = (event, call) => {
@@ -10453,8 +9918,8 @@ ${items.map((item, i) => `${i === items.length - 1 ? "\u2514\u2500\u2500 " : "\u
10453
9918
  item = withholdIfSecretLike(item) || toolLabel(name);
10454
9919
  if (tree?.kind !== kind) tree = { kind, items: [] };
10455
9920
  tree.items.push(item);
10456
- if (tree.items.length < 2) return formatNormalToolLine(event, call, colorEnabled);
10457
- return treeLine(kind, tree.items);
9921
+ if (tree.items.length < 2) return formatNormalToolLine(event, call, colorEnabled, opts);
9922
+ return treeLine(kind, tree.items, formatNormalToolLine(event, call, colorEnabled, opts));
10458
9923
  };
10459
9924
  const format = (event) => {
10460
9925
  if (event.type === "tool-call") {
@@ -10468,7 +9933,7 @@ ${items.map((item, i) => `${i === items.length - 1 ? "\u2514\u2500\u2500 " : "\u
10468
9933
  pending.delete(event.toolCallId);
10469
9934
  const treeOutput = formatTreeEvent(event, call);
10470
9935
  if (treeOutput !== null) return treeOutput;
10471
- return formatNormalToolLine(event, call, colorEnabled);
9936
+ return formatNormalToolLine(event, call, colorEnabled, opts);
10472
9937
  };
10473
9938
  format.reset = () => {
10474
9939
  tree = null;
@@ -10664,7 +10129,7 @@ function formatCompactionSummaryLine(event) {
10664
10129
  if (!event) return "";
10665
10130
  if (event.failed) {
10666
10131
  const reason = event.detail ? `\uFF1A${event.detail}` : "";
10667
- return `${STYLE.dim}\u81EA\u52A8\u4E0A\u4E0B\u6587\u538B\u7F29\u5931\u8D25${reason}\uFF0C\u672C\u8F6E\u4EE5\u672A\u538B\u7F29\u4E0A\u4E0B\u6587\u7EE7\u7EED\u3002\u82E5\u53CD\u590D\u51FA\u73B0\u53EF\u624B\u52A8 /compact\u3002${STYLE.reset}
10132
+ return `${STYLE.dim}\u81EA\u52A8\u4E0A\u4E0B\u6587\u538B\u7F29\u5931\u8D25${reason}\uFF0C\u4FDD\u7559\u5DF2\u6709\u5386\u53F2\uFF1B\u8D85\u51FA\u8BF7\u6C42\u9884\u7B97\u65F6\u5C06\u505C\u6B62\u53D1\u9001\u3002\u53EF\u624B\u52A8 /compact \u91CD\u8BD5\u3002${STYLE.reset}
10668
10133
  `;
10669
10134
  }
10670
10135
  if (event.skipped) {
@@ -10720,7 +10185,7 @@ function shouldPromoteTuiNarration(text) {
10720
10185
  return /(^|\n)\s*(?:#{1,3}\s|```|[-*+]\s|\d+[.)]\s)/.test(text);
10721
10186
  }
10722
10187
  function narrationActivityLabel(text) {
10723
- const oneLine = stripAnsi2(text).replace(/[`*_#>]/g, "").replace(/\s+/g, " ").trim();
10188
+ const oneLine = stripAnsi(text).replace(/[`*_#>]/g, "").replace(/\s+/g, " ").trim();
10724
10189
  return truncateThinkingHint(oneLine, 60);
10725
10190
  }
10726
10191
  function createCliTurnOutput(params) {
@@ -10728,7 +10193,8 @@ function createCliTurnOutput(params) {
10728
10193
  const workingLabel = params.workingLabel ?? `${options.agentName} -> working`;
10729
10194
  const spinner = params.spinner ?? new Spinner(options.output, workingLabel, Boolean(options.activityReporter));
10730
10195
  const formatToolEvent = createToolEventFormatter(void 0, {
10731
- tuiTrees: options.output.tuiTrees === true
10196
+ tuiTrees: options.output.tuiTrees === true,
10197
+ visibleRunIds: options.output.visibleRunIds
10732
10198
  });
10733
10199
  const eventMode = resolveAgentEventMode(options);
10734
10200
  const assistantLabelManaged = options.output.assistantLabelManaged === true;
@@ -10957,8 +10423,17 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
10957
10423
  */
10958
10424
  showPhase(phase) {
10959
10425
  const label = phase === "validating-context" ? t("contextChecking") : phase === "compacting" ? t("contextCompacting") : t("waitingForModel");
10960
- spinner.show(label);
10961
- options.activityReporter?.(label);
10426
+ this.showWorking(label);
10427
+ },
10428
+ handleCompactionActivity(event) {
10429
+ if (event.kind === "compaction-retry") {
10430
+ this.showWorking(t("contextCompactingRetry", String(event.attempt), String(event.maxAttempts)));
10431
+ } else if (event.kind === "compaction-start") {
10432
+ this.showPhase("compacting");
10433
+ } else if (event.kind === "compaction-end" || // Failed compaction continues with trimmed history; abort owns its terminal cleanup.
10434
+ event.kind === "compaction-failed" && event.reason !== "aborted") {
10435
+ this.showPhase("waiting-provider");
10436
+ }
10962
10437
  },
10963
10438
  finish(fallbackContent) {
10964
10439
  const flushedThink = flushThinkParser(thinkState);
@@ -11493,9 +10968,57 @@ function isBalanceExhaustedError(error) {
11493
10968
  return matchesBalanceError(message);
11494
10969
  }
11495
10970
 
10971
+ // packages/cli/client/hostTaskWorkspaceAssessment.ts
10972
+ import { resolve as resolve3 } from "node:path";
10973
+ var object = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
10974
+ var present = (value) => typeof value === "string" && value.trim().length > 0;
10975
+ function resolveCurrentHostTaskReference(input) {
10976
+ const ref = input.reference;
10977
+ if (!ref || !present(ref.taskId) || !present(ref.workspace) || !present(ref.dialogId) || ref.dialogId !== input.dialogId || resolve3(ref.workspace) !== resolve3(input.workspace) || readHostTask(hostTaskEventsRoot(input.env), ref).authorization === "unknown") return void 0;
10978
+ return structuredClone(ref);
10979
+ }
10980
+ async function assessHostTaskWorkspace(input) {
10981
+ const ref = resolveCurrentHostTaskReference(input);
10982
+ if (!ref) return void 0;
10983
+ const root = hostTaskEventsRoot(input.env);
10984
+ const blocked = (reason, businessReason = "invalid_contract") => ({
10985
+ exitCode: 1,
10986
+ hostTaskWorkspaceBlocker: reason,
10987
+ businessCompletion: { taskId: ref.taskId, status: "blocked", reasons: [businessReason] }
10988
+ });
10989
+ const fresh = await collectHostTaskWorkspace(ref, input.env);
10990
+ const plan = readHostTaskAcceptancePlan(ref, input.env);
10991
+ let planned;
10992
+ if (plan) {
10993
+ try {
10994
+ planned = { status: "ready", context: await collectHostTaskPlannedWorkspace(ref, input.env) };
10995
+ } catch {
10996
+ planned = { status: "blocked", reason: "task_planned_workspace_unavailable" };
10997
+ }
10998
+ }
10999
+ const authority = readHostTask(root, ref).authorization;
11000
+ if (authority === "paused" || authority === "revoked") return blocked(`authorization_${authority}`, `authorization_${authority}`);
11001
+ if (authority !== "active") return blocked("task_authority_unavailable");
11002
+ const supplied = object(input.evidence);
11003
+ if (supplied?.status === "blocked") return blocked(present(supplied.reason) ? supplied.reason : "workspace_blocked");
11004
+ if (fresh.status === "blocked") return blocked(fresh.reason);
11005
+ if (planned?.status === "blocked") return blocked(planned.reason);
11006
+ if (planned?.status === "ready" && planned.context.baseline !== fresh.context.baseline) {
11007
+ return blocked("task_plan_baseline_mismatch");
11008
+ }
11009
+ const context = object(supplied?.context);
11010
+ const scope = object(context?.scope);
11011
+ if (supplied?.status !== "ready" || !context || !scope || scope.taskId !== ref.taskId || scope.dialogId !== ref.dialogId || scope.taskInstanceId !== ref.taskInstanceId || !present(scope.workspace) || resolve3(scope.workspace) !== resolve3(ref.workspace)) return blocked("workspace_evidence_mismatch");
11012
+ const matches = (canonical) => context.baseline === canonical.baseline && context.revision === canonical.revision && Array.isArray(context.taskPaths) && context.taskPaths.length === canonical.taskPaths.length && context.taskPaths.every((path2, index) => path2 === canonical.taskPaths[index]);
11013
+ if (!matches(fresh.context) && !(planned?.status === "ready" && matches(planned.context))) {
11014
+ return blocked("workspace_evidence_mismatch");
11015
+ }
11016
+ return void 0;
11017
+ }
11018
+
11496
11019
  // packages/cli/client/agentRun.ts
11497
11020
  async function loadRunLocalAgentTurn() {
11498
- const { runLocalAgentTurn } = await import("./agentRuntimeLocal-SOO2OPJG.js");
11021
+ const { runLocalAgentTurn } = await import("./agentRuntimeLocal-QZPFWMLG.js");
11499
11022
  return runLocalAgentTurn;
11500
11023
  }
11501
11024
  var stripDebugNoise = (s) => s.replace(/\s*raw="[\s\S]*"/g, "").replace(/\s*raw=\S+/g, "").replace(/\s*headers=\[[^\]]*\]/g, "").replace(/\s*headers=\S+/g, "").trim();
@@ -11771,6 +11294,7 @@ function looksLikeQuotaExhaustedText(message) {
11771
11294
  }
11772
11295
  var BARE_UPSTREAM_5XX_RE = /\bHTTP[:\s]+(5\d\d)\b|\bstatus[:\s=]+(5\d\d)\b|\breturned error\s+(5\d\d)\b/i;
11773
11296
  function classifyLocalRunError(message) {
11297
+ if (isHistoryIntegrityFailure(message)) return { kind: "history_integrity" };
11774
11298
  const m = message.match(PROVIDER_HTTP_FAILED_RE);
11775
11299
  if (m) {
11776
11300
  const status = Number(m[2]);
@@ -12146,8 +11670,52 @@ function buildUpstreamFailure(ctx) {
12146
11670
  return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}). Detail: ${ctx.message} ${NO_FALLBACK} ${fix}, ${SERVER_FALLBACK_HINT}
12147
11671
  `;
12148
11672
  }
11673
+ function describeHistoryIntegrityFailure(message) {
11674
+ const ids = [...new Set(message.match(/\bcall_[A-Za-z0-9_-]+\b/g) ?? [])];
11675
+ const pairing = ids.length ? ` Missing tool result pairing: ${ids.join(", ")}.` : "";
11676
+ return `[nolo] history_integrity: Strict continuation history could not be verified.${pairing} Restore verified complete history from the original host or finish verified history recovery before retrying. No history was discarded or fabricated; blind retry will not repair coverage.
11677
+ `;
11678
+ }
11679
+ var LOCAL_CONTEXT_COVERAGE_TEXT = "Context protection: history cannot fit without losing messages";
11680
+ function isLocalContextCoverageFailure(error) {
11681
+ return error?.code === "LOCAL_CONTEXT_COVERAGE_REQUIRED" || toErrorMessage(error).includes(LOCAL_CONTEXT_COVERAGE_TEXT);
11682
+ }
11683
+ var BATCH_RECEIPT_MISSING_TEXT = "Missing durable batch receipt";
11684
+ function isMissingBatchReceiptFailure(message) {
11685
+ return message.includes(BATCH_RECEIPT_MISSING_TEXT);
11686
+ }
11687
+ function describeMissingBatchReceipt() {
11688
+ return "this turn's queued message batch has no durable admission receipt in this dialog, so the send state cannot be verified from local records. Your messages are kept. Re-send only if the previous reply never arrived; if it repeats, restart the TUI to restore the queue. This is not a credential or config problem";
11689
+ }
11690
+ function describeCliBatchPhaseFailure(error) {
11691
+ const cause = error.cause instanceof Error ? error.cause.message : String(error.cause ?? "");
11692
+ if (!error.requestStarted) {
11693
+ if (/already requested/i.test(cause)) {
11694
+ return `[nolo] queued batch ${error.batchId} was already requested; this attempt was blocked and not re-sent. The earlier attempt may have been sent and billed \u2014 check the dialog history before resending.
11695
+ `;
11696
+ }
11697
+ return `[nolo] queued batch ${error.batchId} was blocked before the model was called; this attempt was not sent and was not re-sent. The prior send state is unknown. ${cause} Your messages are kept.
11698
+ `;
11699
+ }
11700
+ return `[nolo] queued batch ${error.batchId}: the model was called but the reply/completion evidence was not confirmed saved. It was not re-sent. Check the dialog history before resending. ${cause}
11701
+ `;
11702
+ }
11703
+ function isCliBatchPhaseFailure(error) {
11704
+ return error?.code === "cli_batch_phase_failed";
11705
+ }
12149
11706
  function formatLocalTurnFailureLine(error) {
12150
11707
  const message = toErrorMessage(error);
11708
+ if (isCliBatchPhaseFailure(error)) {
11709
+ return describeCliBatchPhaseFailure(error);
11710
+ }
11711
+ if (isLocalContextCoverageFailure(error)) {
11712
+ return `[nolo] ${describeContextRefusal(contextRefusalDiagnostics(error))}
11713
+ `;
11714
+ }
11715
+ if (isMissingBatchReceiptFailure(message)) {
11716
+ return `[nolo] ${describeMissingBatchReceipt()}.
11717
+ `;
11718
+ }
12151
11719
  if (error?.code === "LLM_REQUEST_TIMEOUT") {
12152
11720
  const msMatch = /after (\d+)ms/.exec(message);
12153
11721
  const deadline = msMatch && Number.isFinite(Number(msMatch[1])) ? formatElapsed(Math.round(Number(msMatch[1]) / 1e3)) : "the configured window";
@@ -12155,6 +11723,7 @@ function formatLocalTurnFailureLine(error) {
12155
11723
  `;
12156
11724
  }
12157
11725
  const cls = classifyLocalRunError(message);
11726
+ if (cls.kind === "history_integrity") return describeHistoryIntegrityFailure(message);
12158
11727
  if (cls.kind === "rate-limit") {
12159
11728
  const rawCooldownUntil = error && typeof error === "object" ? error.cooldownUntil : void 0;
12160
11729
  return buildRateLimitFailure({
@@ -12233,9 +11802,21 @@ function describeLocalRunFailure(message, rawError) {
12233
11802
  if (isCliAuthorityBrokerProtocolError(rawError) || /CLI authority broker protocol|CLI authority broker .* returned malformed response/i.test(message)) {
12234
11803
  const cleaned = stripDebugNoise(message);
12235
11804
  return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} The local authority broker returned a protocol or malformed response error. Check the running broker process and retry, ${SERVER_FALLBACK_HINT}
11805
+ `;
11806
+ }
11807
+ if (isCliBatchPhaseFailure(rawError)) {
11808
+ return describeCliBatchPhaseFailure(rawError);
11809
+ }
11810
+ if (isLocalContextCoverageFailure(rawError ?? message)) {
11811
+ return `[nolo] ${describeContextRefusal(contextRefusalDiagnostics(rawError))}
11812
+ `;
11813
+ }
11814
+ if (isMissingBatchReceiptFailure(message)) {
11815
+ return `[nolo] ${describeMissingBatchReceipt()}.
12236
11816
  `;
12237
11817
  }
12238
11818
  const cls = classifyLocalRunError(message);
11819
+ if (cls.kind === "history_integrity") return describeHistoryIntegrityFailure(message);
12239
11820
  if (cls.kind === "generic") {
12240
11821
  if (/owner-required route not acknowledged/i.test(message)) {
12241
11822
  return `${RUN_UNAVAILABLE_PREFIX} (${message}). ${NO_FALLBACK} The server returned a successful response but did not acknowledge the owner route. Check server version or proxy configuration, ${SERVER_FALLBACK_HINT}
@@ -12607,6 +12188,12 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12607
12188
  } : void 0;
12608
12189
  const currentDialogId = options.continueDialogId ?? ulid2();
12609
12190
  const freshDialog = options.freshDialog ?? !options.continueDialogId;
12191
+ options = { ...options, hostTaskRef: resolveCurrentHostTaskReference({
12192
+ reference: options.hostTaskRef,
12193
+ workspace: options.localRuntimeCwd ?? process.cwd(),
12194
+ dialogId: currentDialogId,
12195
+ env: options.env
12196
+ }) };
12610
12197
  const turnId = `turn-${ulid2()}`;
12611
12198
  const runtimeContextWithOwnership = {
12612
12199
  ...runtimeContext ?? {},
@@ -12614,8 +12201,176 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12614
12201
  turnId,
12615
12202
  getProcessCausalDepth: options.getProcessCausalDepth
12616
12203
  };
12617
- const adapter = baseAdapter;
12204
+ const installReviewHost = baseAdapter.installTaskReviewHost;
12205
+ if (options.hostTaskRef && installReviewHost) {
12206
+ const scope = structuredClone(options.hostTaskRef);
12207
+ const authorExecutionId = createHostAuthorExecution(options.env, scope, turnId);
12208
+ installReviewHost({ scope, authorExecutionId, authorize: async () => {
12209
+ if (!scope.taskId?.trim() || !scope.workspace?.trim() || !scope.dialogId?.trim() || scope.dialogId !== currentDialogId || resolveHostReviewPath(scope.workspace) !== resolveHostReviewPath(options.localRuntimeCwd ?? process.cwd())) throw new Error("task_review_host_scope_mismatch");
12210
+ } });
12211
+ }
12212
+ let reviewContext;
12213
+ const requestedReview = options.hostReviewDispatch;
12214
+ if (requestedReview && options.hostTaskRef && requestedReview.scope.taskId === options.hostTaskRef.taskId && requestedReview.scope.dialogId === currentDialogId && resolveHostReviewPath(requestedReview.scope.workspace) === resolveHostReviewPath(options.hostTaskRef.workspace)) {
12215
+ reviewContext = { ...requestedReview, authorExecutionId: createHostAuthorExecution(options.env, options.hostTaskRef, turnId) };
12216
+ }
12217
+ const commandVersionBindings = /* @__PURE__ */ new Map();
12218
+ const commandAdapter = !options.runtimeKey || options.runtimeKey === "local" ? wrapLocalCommandWorkspaceObservation(baseAdapter, options.localRuntimeCwd ?? process.cwd(), commandVersionBindings, void 0, options.abortSignal) : baseAdapter;
12219
+ const reviewAdapter = {
12220
+ ...commandAdapter,
12221
+ executeTool: async (call, opts) => {
12222
+ let args = {};
12223
+ try {
12224
+ args = typeof call.arguments === "string" ? JSON.parse(call.arguments) : call.arguments ?? {};
12225
+ } catch {
12226
+ }
12227
+ const matched = call.name === "startAgentRun" && matchesHostReviewDispatch(reviewContext, call, args);
12228
+ const result = await withHostReviewDispatch(matched ? reviewContext : void 0, () => commandAdapter.executeTool(call, opts));
12229
+ return result;
12230
+ }
12231
+ };
12232
+ const completionEvidenceProvider = options.hostTaskRef ? options.hostTaskCompletionEvidenceProvider : void 0;
12233
+ let hostTask = bindHostTask({
12234
+ adapter: reviewAdapter,
12235
+ reference: options.hostTaskRef,
12236
+ workspace: options.localRuntimeCwd ?? process.cwd(),
12237
+ dialogId: currentDialogId,
12238
+ env: options.env,
12239
+ signal: options.abortSignal,
12240
+ completionEvidenceProvider
12241
+ });
12242
+ if (options.hostTaskRef && options.hostTaskWorkspaceEvidence !== void 0 && readHostTask(hostTaskEventsRoot(options.env), options.hostTaskRef).authorization === "active") {
12243
+ const blocker = await assessHostTaskWorkspace({
12244
+ reference: options.hostTaskRef,
12245
+ workspace: options.localRuntimeCwd ?? process.cwd(),
12246
+ dialogId: currentDialogId,
12247
+ env: options.env,
12248
+ evidence: options.hostTaskWorkspaceEvidence
12249
+ });
12250
+ if (blocker) {
12251
+ options.output.write(`[auto-review] blocked: ${blocker.hostTaskWorkspaceBlocker}
12252
+ `);
12253
+ try {
12254
+ const saved = await reviewAdapter.saveTurn({
12255
+ agentKey: options.agentKey,
12256
+ messages: [{ role: "user", content: options.message }],
12257
+ continueDialogId: currentDialogId,
12258
+ runtimeContext: runtimeContextWithOwnership,
12259
+ result: {
12260
+ model: "host-workspace-assessment",
12261
+ content: "",
12262
+ error: true,
12263
+ businessCompletion: blocker.businessCompletion
12264
+ }
12265
+ });
12266
+ return {
12267
+ ...blocker,
12268
+ hostTaskRef: options.hostTaskRef,
12269
+ dialogId: saved.dialogId,
12270
+ taskAuthorization: readHostTask(hostTaskEventsRoot(options.env), options.hostTaskRef).authorization
12271
+ };
12272
+ } catch (localError) {
12273
+ return { ...blocker, hostTaskRef: options.hostTaskRef, localError };
12274
+ }
12275
+ }
12276
+ }
12277
+ let usedReviewTool = false;
12278
+ let batchProviderStarted = false;
12279
+ let mainProviderStarted = false;
12280
+ let refusalModel = "";
12281
+ let turnPersisted = false;
12282
+ let batchIdentity;
12283
+ try {
12284
+ batchIdentity = resolveCliBatchIdentity(options);
12285
+ } catch (error) {
12286
+ options.output.write(`[nolo] ${error instanceof Error ? error.message : String(error)}
12287
+ `);
12288
+ return { exitCode: 1, localError: error };
12289
+ }
12290
+ const markBatch = async (phase) => {
12291
+ if (!batchIdentity) return;
12292
+ const store = await getOrCreateSharedStore({ env: options.env, cwd: options.localRuntimeCwd, fetchImpl: options.fetchImpl });
12293
+ try {
12294
+ await markCliUserBatchPhase(store, currentDialogId, batchIdentity.batchId, phase, batchIdentity.messageIds, phase === "requested" ? options.userMessages : void 0);
12295
+ } catch (error) {
12296
+ throw cliBatchPhaseFailure({ phase, batchId: batchIdentity.batchId, requestStarted: false, replyPersisted: false, cause: error });
12297
+ }
12298
+ };
12299
+ const adapter = {
12300
+ ...hostTask.adapter,
12301
+ resolveProvider: async (...args) => {
12302
+ const provider = await hostTask.adapter.resolveProvider(...args);
12303
+ const isTextOnly = Boolean(args[1]?.textOnly);
12304
+ if (!isTextOnly) refusalModel = provider.model;
12305
+ return {
12306
+ ...provider,
12307
+ complete: async (...completeArgs) => {
12308
+ if (!isTextOnly) {
12309
+ mainProviderStarted = true;
12310
+ }
12311
+ if (batchIdentity && !isTextOnly && !batchProviderStarted) {
12312
+ await markBatch("requested");
12313
+ batchProviderStarted = true;
12314
+ }
12315
+ return provider.complete(...completeArgs);
12316
+ }
12317
+ };
12318
+ },
12319
+ executeTool: async (call, opts) => {
12320
+ const protectedReview = call.name === "requestTaskReview" || call.name === "recordTaskReviewDecision";
12321
+ if (!protectedReview) return reviewAdapter.executeTool(call, opts);
12322
+ usedReviewTool = true;
12323
+ if (options.hostTaskRef?.taskInstanceId) {
12324
+ const authorize = baseAdapter.authorizeAccountTask;
12325
+ if (!authorize) throw new Error("task_review_account_authorization_unavailable");
12326
+ await authorize(options.hostTaskRef);
12327
+ }
12328
+ if (!options.hostTaskRef && ["requestTaskReview", "recordTaskReviewDecision"].includes(call.name)) {
12329
+ const admit = baseAdapter.admitAccountReviewTurn;
12330
+ if (!admit) throw new Error("task_review_account_admission_unavailable");
12331
+ const reference = await admit(currentDialogId, turnId);
12332
+ options = { ...options, hostTaskRef: reference };
12333
+ hostTask = bindHostTask({ adapter: reviewAdapter, reference, workspace: options.localRuntimeCwd ?? process.cwd(), dialogId: currentDialogId, env: options.env, signal: options.abortSignal });
12334
+ }
12335
+ return hostTask.adapter.executeTool(call, opts);
12336
+ },
12337
+ saveTurn: async (input) => {
12338
+ if (usedReviewTool && options.hostTaskRef) await settleHostReviewsForScope(options.hostTaskRef, options.env, options.hostReviewContentAcceptance);
12339
+ const completeBatch = Boolean(batchIdentity && batchProviderStarted && !input.result.error);
12340
+ const injectedBatches = options.drainInjectedBatches ?? [];
12341
+ const injectedMessageIds = new Set(injectedBatches.flatMap((batch) => batch.messageIds));
12342
+ const completeBatchIds = [
12343
+ ...completeBatch ? [batchIdentity.batchId] : [],
12344
+ ...!input.result.error ? injectedBatches.map((batch) => batch.batchId) : []
12345
+ ];
12346
+ try {
12347
+ const saved = await hostTask.adapter.saveTurn({
12348
+ ...input,
12349
+ messages: input.messages.filter((message) => {
12350
+ const cliMessageId = message.cliMessageId;
12351
+ if (!cliMessageId) return true;
12352
+ if (options.userMessages?.some((user) => user.cliMessageId === cliMessageId)) return false;
12353
+ if (injectedMessageIds.has(cliMessageId)) return false;
12354
+ return true;
12355
+ }),
12356
+ ...completeBatchIds.length ? { cliBatchCompletion: { batchIds: completeBatchIds } } : {}
12357
+ });
12358
+ turnPersisted = true;
12359
+ return saved;
12360
+ } catch (error) {
12361
+ if (batchIdentity && batchProviderStarted) {
12362
+ throw cliBatchPhaseFailure({ phase: "completed", batchId: batchIdentity.batchId, requestStarted: true, replyPersisted: false, cause: error });
12363
+ }
12364
+ throw error;
12365
+ }
12366
+ }
12367
+ };
12618
12368
  const expandedMessage = options.pastedTextStore?.items.size ? expandCollapsedPastes(options.message, options.pastedTextStore) : options.message;
12369
+ const commandObservations = [];
12370
+ const retainCommandObservations = (result) => {
12371
+ recordRunResultHeaderMeta(result, { commandObservations });
12372
+ return result;
12373
+ };
12619
12374
  const workingLabel = `${options.agentName} -> working locally`;
12620
12375
  const turnOutput = createCliTurnOutput({
12621
12376
  options,
@@ -12637,9 +12392,11 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12637
12392
  const runLocalAgentTurn = await loadRunLocalAgentTurn();
12638
12393
  const result = await runLocalAgentTurn({
12639
12394
  adapter,
12395
+ ...hostTask.contract ? { taskExecutionContract: hostTask.contract } : {},
12640
12396
  agentRef: options.agentKey,
12641
12397
  userLanguage: options.userLanguage ?? options.env.NOLO_LANG ?? null,
12642
12398
  input: buildUserInputContent(messageForLocal, options.imageUrls),
12399
+ userMessages: options.userMessages,
12643
12400
  ...expandedMessage !== options.message || localAttachmentCard !== "" ? {
12644
12401
  persistedInput: hasDurableAttachments ? buildUserInputContent(
12645
12402
  expandedMessage,
@@ -12669,7 +12426,6 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12669
12426
  parentDialogId: options.parentDialogId,
12670
12427
  runtimeContext: runtimeContextWithOwnership,
12671
12428
  runKind: options.env.NOLO_AGENT_RUN_CHILD === "1" ? "subtask" : "interactive",
12672
- ...options.env.NOLO_AGENT_RUN_CHILD === "1" ? { subtaskBudgetLimits: resolveSubtaskBudgetLimits({ env: options.env }) } : {},
12673
12429
  // 展示能力由宿主声明(TUI=narrow),非交互 CLI/后台留空 → unknown;
12674
12430
  // 排版段只在能力已知时由 localLoop 注入,server 线不读该字段。
12675
12431
  ...options.responseViewport ? { responseViewport: options.responseViewport } : {},
@@ -12688,15 +12444,7 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12688
12444
  if (event.kind === "turn-phase") {
12689
12445
  turnOutput.showPhase(event.phase);
12690
12446
  }
12691
- if (event.kind === "compaction-start") {
12692
- turnOutput.showPhase("compacting");
12693
- }
12694
- if (event.kind === "compaction-end" || // 压缩失败(timeout/provider-error)时 localLoop 按失败原子性语义
12695
- // 带着裁剪后的历史继续本轮,切回等待模型文案;aborted 时 turn 随即
12696
- // 结束,不再切文案(终态由 abort 路径收尾)。
12697
- event.kind === "compaction-failed" && event.reason !== "aborted") {
12698
- turnOutput.showPhase("waiting-provider");
12699
- }
12447
+ turnOutput.handleCompactionActivity(event);
12700
12448
  if (event.kind === "image-downgraded") {
12701
12449
  options.output.write(
12702
12450
  "[nolo] \u5F53\u524D agent \u88AB\u914D\u7F6E\u4E3A\u4E0D\u652F\u6301\u56FE\u7247\u8F93\u5165\uFF0C\u56FE\u7247\u5DF2\u7528\u5360\u4F4D\u6587\u672C\u66FF\u4EE3\u3002\u8BF7\u68C0\u67E5\u6A21\u578B\u7684\u56FE\u7247\u80FD\u529B\u914D\u7F6E\uFF0C\u6216\u7528 /switch \u9009\u62E9\u652F\u6301\u56FE\u7247\u7684 agent \u540E\u91CD\u65B0\u53D1\u9001\u56FE\u7247\u3002\n"
@@ -12713,6 +12461,8 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12713
12461
  // tool-gist-fold 后 onToolEvent 无条件挂载(不再受 traceLocalTools 开关
12714
12462
  // 控制,显示模式合并为单一 gist/折叠通道)——保留 alpha 的新形态。
12715
12463
  onToolEvent: (event) => {
12464
+ const observation = observeLocalCommandResult(event, options.localRuntimeCwd ?? process.cwd());
12465
+ if (observation) commandObservations.push({ ...observation, ...commandVersionBindings.get(event.toolCallId) });
12716
12466
  turnOutput.handleToolEvent(event);
12717
12467
  },
12718
12468
  ...!options.noStream ? {
@@ -12725,21 +12475,30 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12725
12475
  } : {}
12726
12476
  });
12727
12477
  turnOutput.finish(result.content);
12478
+ const usageRecords = result.usageRecords?.filter(
12479
+ (record) => Object.keys(record.usage ?? {}).length > 0
12480
+ );
12728
12481
  const turnCredits = sumPlatformCredits(result.usageRecords);
12482
+ const turnTokens = withTurnCredits(buildTurnTokenUsage(result.usage, result.model), turnCredits);
12729
12483
  const turnResult = {
12484
+ savedTurnPersisted: turnPersisted,
12485
+ mainProviderAttempted: mainProviderStarted,
12730
12486
  exitCode: 0,
12487
+ stopReason: result.stopReason,
12488
+ ...hostTask.result(),
12489
+ ...options.hostTaskRef ? { hostTaskRef: options.hostTaskRef } : {},
12731
12490
  dialogId: result.dialogId,
12732
12491
  ...typeof result.content === "string" && result.content.trim() ? { finalText: result.content } : {},
12733
- title: result.title,
12492
+ ...result.title !== void 0 ? { title: result.title } : {},
12734
12493
  ...result.titlePatchPromise ? { titlePatchPromise: result.titlePatchPromise } : {},
12735
12494
  ...pickEmptyAssistantFlags(result),
12736
12495
  // 积分口径按「全轮」而非「最后一次调用」:result.usage 只是收尾那次
12737
12496
  // provider 调用的 usage,本轮前面 N-1 次工具循环调用(以及自动压缩摘要)
12738
12497
  // 的 cost 都只存在于 usageRecords 里。token 字段仍取 result.usage——
12739
12498
  // 上下文占用本来就该看最后一次调用的累计输入,不是各次相加。
12740
- turnTokens: withTurnCredits(buildTurnTokenUsage(result.usage, result.model), turnCredits),
12499
+ ...turnTokens !== void 0 ? { turnTokens } : {},
12741
12500
  ...turnCredits !== void 0 ? { turnCredits } : {},
12742
- ...result.usageRecords?.length ? { usageRecords: result.usageRecords } : {}
12501
+ ...usageRecords?.length ? { usageRecords } : {}
12743
12502
  };
12744
12503
  const serverMeta = resolveResultServerMeta({
12745
12504
  env: options.env ?? {},
@@ -12747,6 +12506,7 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12747
12506
  hasSubjectRefs: (buildSubjectRefs(options)?.length ?? 0) > 0
12748
12507
  });
12749
12508
  recordRunResultHeaderMeta(turnResult, {
12509
+ commandObservations,
12750
12510
  model: result.model,
12751
12511
  dialogServer: serverMeta.server,
12752
12512
  serverSync: serverMeta.serverSync
@@ -12762,14 +12522,18 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12762
12522
  const abortedTurnCredits = sumPlatformCredits(abortedUsageRecords);
12763
12523
  if (error?.code === LOCAL_TURN_ABORTED_CODE || options.abortSignal?.aborted) {
12764
12524
  const pendingToolName = error?.pendingToolName;
12765
- return {
12525
+ return retainCommandObservations({
12766
12526
  exitCode: 0,
12527
+ ...hostTask.result(),
12528
+ savedTurnPersisted: turnPersisted,
12529
+ mainProviderAttempted: mainProviderStarted,
12530
+ ...options.hostTaskRef ? { hostTaskRef: options.hostTaskRef } : {},
12767
12531
  streamInterrupted: true,
12768
12532
  ...savedDialogId ? { dialogId: savedDialogId } : {},
12769
12533
  ...pendingToolName ? { pendingToolName } : {},
12770
12534
  ...abortedTurnCredits !== void 0 ? { turnCredits: abortedTurnCredits } : {},
12771
12535
  ...abortedUsageRecords?.length ? { usageRecords: abortedUsageRecords } : {}
12772
- };
12536
+ });
12773
12537
  }
12774
12538
  const cooldownUntil = await markStartupRateLimitCooldown(
12775
12539
  options,
@@ -12780,24 +12544,56 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12780
12544
  error.cooldownUntil = cooldownUntil;
12781
12545
  }
12782
12546
  if (settings.reportFailure) {
12783
- const failureLine = formatLocalTurnFailureLine(error);
12784
- if (typeof options.output.writeErr === "function") {
12785
- options.output.writeErr(failureLine);
12786
- } else {
12787
- options.output.write(failureLine);
12547
+ const suppressOutput = options.interactiveHost && isLocalContextCoverageFailure(error);
12548
+ if (!suppressOutput) {
12549
+ const failureLine = formatLocalTurnFailureLine(error);
12550
+ if (typeof options.output.writeErr === "function") {
12551
+ options.output.writeErr(failureLine);
12552
+ } else {
12553
+ options.output.write(failureLine);
12554
+ }
12788
12555
  }
12789
12556
  }
12790
- return {
12557
+ const isCoverage = isLocalContextCoverageFailure(error);
12558
+ const persisted = turnPersisted;
12559
+ const isTruePreflight = isCoverage && !persisted && !mainProviderStarted;
12560
+ const refusal = isCoverage ? contextRefusalDiagnostics(error) : void 0;
12561
+ if (isCoverage) {
12562
+ console.warn(`[nolo] context-refusal ${JSON.stringify({
12563
+ dialogId: savedDialogId ?? currentDialogId,
12564
+ agentKey: options.agentKey,
12565
+ model: refusalModel,
12566
+ reason: refusal?.reason ?? "unknown",
12567
+ historyTokens: refusal?.historyTokens ?? -1,
12568
+ budget: refusal?.budget ?? -1,
12569
+ largestMessageTokens: refusal?.largestMessageTokens ?? -1,
12570
+ droppedCount: refusal?.droppedCount ?? 0,
12571
+ detail: refusal?.detail ?? "diagnostics-unavailable"
12572
+ })}`);
12573
+ }
12574
+ return retainCommandObservations({
12791
12575
  exitCode: 1,
12576
+ ...hostTask.result(),
12792
12577
  localError: error,
12578
+ savedTurnPersisted: persisted,
12579
+ mainProviderAttempted: mainProviderStarted,
12793
12580
  failureSubclass: classifyFailureSubclass({
12794
12581
  message: toErrorMessage(error),
12795
12582
  body: error
12796
12583
  }),
12797
- ...savedDialogId ? { dialogId: savedDialogId } : {},
12584
+ ...savedDialogId ? { dialogId: savedDialogId } : isCoverage ? { dialogId: currentDialogId } : {},
12585
+ ...isTruePreflight ? {
12586
+ preflightBlocked: {
12587
+ code: "LOCAL_CONTEXT_COVERAGE_REQUIRED",
12588
+ phase: "preflight",
12589
+ retryable: true,
12590
+ mainRequestSent: false,
12591
+ ...refusal ? { refusal } : {}
12592
+ }
12593
+ } : {},
12798
12594
  ...abortedTurnCredits !== void 0 ? { turnCredits: abortedTurnCredits } : {},
12799
12595
  ...abortedUsageRecords?.length ? { usageRecords: abortedUsageRecords } : {}
12800
- };
12596
+ });
12801
12597
  }
12802
12598
  }
12803
12599
  async function resolveLocalCredentialKeysForDispatch(options) {
@@ -12833,9 +12629,19 @@ async function resolveLocalCredentialKeysForDispatch(options) {
12833
12629
  recordSuccess: recorder.recordStartupAvailabilityForAgent ? (status, body) => recorder.recordStartupAvailabilityForAgent(options.agentKey, status, body) : void 0
12834
12630
  };
12835
12631
  }
12632
+ function projectLocalTurnFacts(result) {
12633
+ return {
12634
+ ...result.savedTurnPersisted !== void 0 ? { savedTurnPersisted: result.savedTurnPersisted } : {},
12635
+ ...result.mainProviderAttempted !== void 0 ? { mainProviderAttempted: result.mainProviderAttempted } : {},
12636
+ ...result.preflightBlocked !== void 0 ? { preflightBlocked: result.preflightBlocked } : {},
12637
+ ...result.localError !== void 0 ? { localError: result.localError } : {}
12638
+ };
12639
+ }
12836
12640
  function foldLocalResultForTui(localResult) {
12837
12641
  const folded = {
12838
12642
  exitCode: localResult.exitCode,
12643
+ ...projectLocalTurnFacts(localResult),
12644
+ ...localResult.hostTaskRef ? { hostTaskRef: localResult.hostTaskRef } : {},
12839
12645
  ...localResult.dialogId ? { dialogId: localResult.dialogId } : {},
12840
12646
  title: localResult.title,
12841
12647
  ...localResult.titlePatchPromise ? { titlePatchPromise: localResult.titlePatchPromise } : {},
@@ -12905,7 +12711,7 @@ async function runAgentTurn(options) {
12905
12711
  }
12906
12712
  const skipLocal = await shouldSkipAutoLocalForServerPlatformTools(options);
12907
12713
  if (!skipLocal) {
12908
- const localResult = await runLocalAgentTurnForCli(options, {
12714
+ let localResult = await runLocalAgentTurnForCli(options, {
12909
12715
  reportFailure: false
12910
12716
  });
12911
12717
  if (localResult.exitCode === 0) {
@@ -12923,6 +12729,7 @@ async function runAgentTurn(options) {
12923
12729
  const retriedLocalResult = await runLocalAgentTurnForCli(options, {
12924
12730
  reportFailure: false
12925
12731
  });
12732
+ localResult = retriedLocalResult;
12926
12733
  if (retriedLocalResult.exitCode === 0) {
12927
12734
  return foldLocalResultForTui(retriedLocalResult);
12928
12735
  }
@@ -12937,19 +12744,30 @@ async function runAgentTurn(options) {
12937
12744
  message: localErrorMessage,
12938
12745
  body: localResult.localError
12939
12746
  });
12940
- options.output.write(describeLocalRunFailure(localErrorMessage, localResult.localError));
12941
- return {
12747
+ const suppressAutoFailureOutput = options.interactiveHost && Boolean(localResult.preflightBlocked || isLocalContextCoverageFailure(localResult.localError));
12748
+ if (!suppressAutoFailureOutput) {
12749
+ options.output.write(describeLocalRunFailure(localErrorMessage, localResult.localError));
12750
+ }
12751
+ const failureCoverageUsage = localResult.localError?.compactionUsage;
12752
+ const failureUsageRecords = failureCoverageUsage ? [...localResult.usageRecords ?? [], {
12753
+ // 形状对齐逐帧明细:callId 必填且本轮只有这一条救援摘要,
12754
+ // model 用固定标签(摘要走平台托管或当前 provider,无法从错误取得)。
12755
+ callId: "compaction-rescue",
12756
+ usage: failureCoverageUsage,
12757
+ model: "context-compaction"
12758
+ }] : localResult.usageRecords;
12759
+ const failedResult = {
12942
12760
  exitCode: 1,
12761
+ ...projectLocalTurnFacts(localResult),
12943
12762
  failureSubclass,
12944
12763
  ...localResult.dialogId ? { dialogId: localResult.dialogId } : {},
12945
- // Keep localError so TUI can show balance/quota/dialog-preserved hints
12946
- // instead of only the raw auto-runtime line.
12947
- ...localResult.localError ? { localError: localResult.localError } : {},
12948
12764
  // 失败轮同样可能已发生平台计费(abort/失败照样扣费):turnCredits 与
12949
12765
  // 逐帧明细一起随行,否则审计日志在 auto 失败路径上缺账。
12950
12766
  ...localResult.turnCredits !== void 0 ? { turnCredits: localResult.turnCredits } : {},
12951
- ...localResult.usageRecords?.length ? { usageRecords: localResult.usageRecords } : {}
12767
+ ...failureUsageRecords?.length ? { usageRecords: failureUsageRecords } : {}
12952
12768
  };
12769
+ recordRunResultHeaderMeta(failedResult, getRunResultHeaderMeta(localResult));
12770
+ return failedResult;
12953
12771
  }
12954
12772
  }
12955
12773
  if (!authToken) {
@@ -13167,7 +12985,7 @@ function buildHostEnvironmentLayer(options) {
13167
12985
 
13168
12986
  // packages/agent-runtime/agentsMd.ts
13169
12987
  import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
13170
- import { resolve as resolve2 } from "node:path";
12988
+ import { resolve as resolve4 } from "node:path";
13171
12989
  var AGENTS_MD_MAX_BYTES = 8192;
13172
12990
  var AGENTS_MD_MARKER_RESERVE_BYTES = 512;
13173
12991
  var AGENTS_MD_CANDIDATES = ["AGENTS.md", "CLAUDE.md"];
@@ -13227,6 +13045,37 @@ var parseAgentsMdItem = (body) => {
13227
13045
  rest: body.slice(firstClause.length).replace(/^[::\s]+/, "")
13228
13046
  };
13229
13047
  };
13048
+ var AGENTS_MD_COMMAND_TOKEN_PREFIX = /^(bunx?|npx|node|npm|pnpm|yarn|git|gh|tsc|deno)\b\s/;
13049
+ var extractAgentsMdCommandTokens = (body) => {
13050
+ const tokens2 = [];
13051
+ const seen = /* @__PURE__ */ new Set();
13052
+ for (const match of body.matchAll(/`([^`\n]+)`/g)) {
13053
+ const raw = match[1];
13054
+ if (!AGENTS_MD_COMMAND_TOKEN_PREFIX.test(raw)) continue;
13055
+ if (seen.has(raw)) continue;
13056
+ seen.add(raw);
13057
+ tokens2.push(raw);
13058
+ }
13059
+ return tokens2;
13060
+ };
13061
+ var buildAgentsMdItemGist = (firstSentence, bulletBody) => {
13062
+ const max = AGENTS_MD_SUMMARY_ITEM_MAX_CHARS;
13063
+ const clipped = clipToChars(firstSentence, max);
13064
+ const missing = extractAgentsMdCommandTokens(bulletBody).filter(
13065
+ (token) => !clipped.includes(token)
13066
+ );
13067
+ if (missing.length === 0) return clipped;
13068
+ let tail = "";
13069
+ for (const token of missing) {
13070
+ const candidate = tail ? `${tail} \`${token}\`` : `\`${token}\``;
13071
+ if (candidate.length > max) continue;
13072
+ tail = candidate;
13073
+ }
13074
+ if (!tail) return clipped;
13075
+ const room = max - tail.length - 2;
13076
+ const head = room > 0 ? clipToChars(firstSentence, room) : "";
13077
+ return head ? `${head} ${tail}` : tail;
13078
+ };
13230
13079
  var priorityOf = (label) => {
13231
13080
  const lowered = label.toLowerCase();
13232
13081
  for (let i = 0; i < AGENTS_MD_SUMMARY_PRIORITY_KEYWORDS.length; i += 1) {
@@ -13260,7 +13109,7 @@ var collectAgentsMdSummaryItems = (content) => {
13260
13109
  items.push({
13261
13110
  section,
13262
13111
  label,
13263
- gist: clipToChars(firstSentence, AGENTS_MD_SUMMARY_ITEM_MAX_CHARS),
13112
+ gist: buildAgentsMdItemGist(firstSentence, bullet[1]),
13264
13113
  priority: priorityOf(label)
13265
13114
  });
13266
13115
  }
@@ -13283,8 +13132,9 @@ ${AGENTS_MD_SUMMARY_DELETE_REFERENCE}
13283
13132
  ...items.filter((item) => item.priority >= 0).sort((a, b) => a.priority - b.priority),
13284
13133
  ...items.filter((item) => item.priority < 0)
13285
13134
  ];
13286
- const note = "\u2026\uFF08\u7D22\u5F15\u5DF2\u622A\u65AD\uFF0C\u5176\u4F59\u951A\u70B9\u89C1\u5B8C\u6574\u6587\u4EF6\uFF09";
13287
- const noteBytes = Buffer.byteLength(note, "utf8");
13135
+ const noteBlock = `
13136
+ \u2026\uFF08\u7D22\u5F15\u5DF2\u622A\u65AD\uFF0C\u5176\u4F59\u951A\u70B9\u89C1\u5B8C\u6574\u6587\u4EF6\uFF09`;
13137
+ const noteBytes = Buffer.byteLength(noteBlock, "utf8");
13288
13138
  let used = Buffer.byteLength(head, "utf8");
13289
13139
  const admitted = [];
13290
13140
  const seenSections = /* @__PURE__ */ new Set();
@@ -13318,8 +13168,7 @@ ${line}`, "utf8");
13318
13168
  }
13319
13169
  }
13320
13170
  if (admitted.length === 0) return null;
13321
- return `${head}${renderSummarySections(frozen)}${truncated ? `
13322
- ${note}` : ""}`;
13171
+ return `${head}${renderSummarySections(frozen)}${truncated ? noteBlock : ""}`;
13323
13172
  }
13324
13173
  var renderSummarySections = (entries) => {
13325
13174
  let rendered = "";
@@ -13337,7 +13186,7 @@ ${entry.line}`;
13337
13186
  };
13338
13187
  function readAgentsMdLayerFromDisk(cwd) {
13339
13188
  for (const name of AGENTS_MD_CANDIDATES) {
13340
- const filePath = resolve2(cwd, name);
13189
+ const filePath = resolve4(cwd, name);
13341
13190
  if (!existsSync2(filePath)) continue;
13342
13191
  try {
13343
13192
  const raw = readFileSync3(filePath, "utf8");
@@ -13479,16 +13328,16 @@ function runDoDCommands(commands, cwd, deps = {}) {
13479
13328
 
13480
13329
  // packages/cli/agentRunPrompts.ts
13481
13330
  import { existsSync as existsSync3, readFileSync as readFileSync4, readdirSync, statSync as statSync2 } from "node:fs";
13482
- import { dirname, extname, isAbsolute as isAbsolute2, join as join2, relative as relativePath, resolve as resolve3, sep } from "node:path";
13331
+ import { dirname, extname, isAbsolute as isAbsolute2, join as join2, relative as relativePath, resolve as resolve5, sep } from "node:path";
13483
13332
  function workflowRefToCandidatePath(cwd, ref) {
13484
13333
  const normalized = ref.trim();
13485
13334
  if (!normalized) return "";
13486
13335
  if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
13487
- const directPath = resolve3(cwd, normalized);
13336
+ const directPath = resolve5(cwd, normalized);
13488
13337
  if (existsSync3(directPath)) return directPath;
13489
13338
  }
13490
13339
  const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
13491
- return resolve3(cwd, "docs", "workflows", `${fileName}.md`);
13340
+ return resolve5(cwd, "docs", "workflows", `${fileName}.md`);
13492
13341
  }
13493
13342
  var SKILL_SEARCH_DIRS = [
13494
13343
  ".agents/skills"
@@ -13497,15 +13346,15 @@ function skillRefToCandidatePath(cwd, ref) {
13497
13346
  const normalized = ref.trim();
13498
13347
  if (!normalized) return "";
13499
13348
  if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
13500
- const directPath = resolve3(cwd, normalized);
13349
+ const directPath = resolve5(cwd, normalized);
13501
13350
  if (existsSync3(directPath)) return directPath;
13502
13351
  }
13503
13352
  const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
13504
13353
  for (const dir of SKILL_SEARCH_DIRS) {
13505
- const skillMdPath = resolve3(cwd, dir, fileName, "SKILL.md");
13354
+ const skillMdPath = resolve5(cwd, dir, fileName, "SKILL.md");
13506
13355
  if (existsSync3(skillMdPath)) return skillMdPath;
13507
13356
  }
13508
- return resolve3(cwd, ".agents", "skills", fileName, "SKILL.md");
13357
+ return resolve5(cwd, ".agents", "skills", fileName, "SKILL.md");
13509
13358
  }
13510
13359
  async function resolveWorkflowReference(ref, cwd = process.cwd()) {
13511
13360
  const path2 = workflowRefToCandidatePath(cwd, ref);
@@ -13522,11 +13371,11 @@ async function resolveWorkflowReference(ref, cwd = process.cwd()) {
13522
13371
  }
13523
13372
  function inlineRelativeRefs(body, skillDir) {
13524
13373
  const refPattern = /\[([^\]]+)\]\((\.\/[^)]+|[^)]+\/[^)]+)\)/g;
13525
- const normalizedSkillDir = resolve3(skillDir) + sep;
13374
+ const normalizedSkillDir = resolve5(skillDir) + sep;
13526
13375
  return body.replace(refPattern, (match, label, relPath) => {
13527
13376
  const cleaned = relPath.trim();
13528
13377
  if (!cleaned.startsWith("./") && !cleaned.startsWith("../")) return match;
13529
- const absPath = resolve3(skillDir, cleaned);
13378
+ const absPath = resolve5(skillDir, cleaned);
13530
13379
  const relative = relativePath(normalizedSkillDir, absPath);
13531
13380
  if (relative.startsWith("..") || isAbsolute2(relative)) return match;
13532
13381
  if (!existsSync3(absPath) || !absPath.endsWith(".md")) return match;
@@ -13676,7 +13525,7 @@ function prependSubjectDialogMarker(message, subjectDialogKey) {
13676
13525
  }
13677
13526
  function normalizeCliImageInput(input) {
13678
13527
  if (/^(https?:|data:|file:)/i.test(input)) return input;
13679
- const absolutePath = resolve3(input);
13528
+ const absolutePath = resolve5(input);
13680
13529
  if (!existsSync3(absolutePath)) return input;
13681
13530
  const base64 = readFileSync4(absolutePath).toString("base64");
13682
13531
  return `data:${imageMimeTypeForPath(absolutePath)};base64,${base64}`;
@@ -13695,55 +13544,6 @@ function imageMimeTypeForPath(path2) {
13695
13544
  }
13696
13545
  }
13697
13546
 
13698
- // packages/cli/agentRunLocalWorkspace.ts
13699
- async function runGitForLocalSummary(args, deps = {}) {
13700
- const spawn = deps.spawnProcess ?? spawnProcess;
13701
- const read = deps.readPipeText ?? readPipeText;
13702
- const proc = spawn({
13703
- cmd: ["git", ...args.gitArgs],
13704
- cwd: args.cwd,
13705
- stdout: "pipe",
13706
- stderr: "pipe"
13707
- });
13708
- const [stdout, stderr, exitCode] = await Promise.all([
13709
- read(proc.stdout),
13710
- read(proc.stderr),
13711
- proc.exited
13712
- ]);
13713
- if (exitCode !== 0) {
13714
- throw new Error((stderr || stdout || `git ${args.gitArgs.join(" ")} failed`).trim());
13715
- }
13716
- return stdout.trim();
13717
- }
13718
- async function inspectLocalRunWorkspace(cwd, deps = {}) {
13719
- const run = (gitArgs) => runGitForLocalSummary({ cwd, gitArgs }, deps);
13720
- const status = await run(["status", "--short"]);
13721
- const rawCommit = await run(["log", "-1", "--format=%h%x00%s"]).catch(() => "");
13722
- const [hash, subject] = rawCommit.split("\0");
13723
- return {
13724
- cwd,
13725
- clean: status.trim() === "",
13726
- status,
13727
- ...hash ? { commit: { hash, subject: subject ?? "" } } : {}
13728
- };
13729
- }
13730
- function shouldPrintLocalRunSummary(args) {
13731
- return Boolean(args.localRuntimeCwd && args.parsed.runtimeMode === "local");
13732
- }
13733
- function formatLocalRunSummary(args) {
13734
- return [
13735
- "",
13736
- "[nolo] local run summary",
13737
- `workspace: ${args.inspection.cwd}`,
13738
- ...args.dialogId ? [`dialog: ${args.dialogId}`] : [],
13739
- ...args.inspection.commit ? [`commit: ${args.inspection.commit.hash} ${args.inspection.commit.subject}`] : [],
13740
- `dirty: ${args.inspection.clean ? "clean" : "dirty"}`,
13741
- ...!args.inspection.clean && args.inspection.status.trim() ? [`status:
13742
- ${args.inspection.status.trim()}`] : [],
13743
- ""
13744
- ].join("\n");
13745
- }
13746
-
13747
13547
  // packages/ai/memory/storeShared.ts
13748
13548
  var retrievalCountOf = (item) => item.activationCount ?? 0;
13749
13549
  var touchMemoryItemsInDb = async (db, items, now = (/* @__PURE__ */ new Date()).toISOString()) => {
@@ -13760,367 +13560,6 @@ var touchMemoryItemsInDb = async (db, items, now = (/* @__PURE__ */ new Date()).
13760
13560
  await batch.write();
13761
13561
  };
13762
13562
 
13763
- // packages/ai/memory/constants.ts
13764
- var EXPLICIT_REMEMBER_PREFIX_REGEX = /^(你要记住|请记住|以后记住|记住)[,,。.\s::]*/u;
13765
-
13766
- // packages/ai/memory/source.ts
13767
- var getMemorySourceKind = (item) => {
13768
- if (item.sourceKind) return item.sourceKind;
13769
- if (item.patternKey === "explicit-remember") return "explicit-user-directive";
13770
- if (item.patternKey === "agent-remember" || item.patternKey === "procedural-runbook")
13771
- return "agent-tool";
13772
- if (item.patternKey?.startsWith("dialog-learning:"))
13773
- return "dialog-learning";
13774
- if (item.tags?.includes("understanding-memory"))
13775
- return "inferred-understanding";
13776
- return "agent-tool";
13777
- };
13778
-
13779
- // packages/ai/memory/overlay.ts
13780
- var KIND_TITLES = {
13781
- episodic: "Episodic",
13782
- semantic: "Semantic",
13783
- procedural: "Procedural"
13784
- };
13785
- var estimateTokens = (text) => {
13786
- let cjk = 0;
13787
- let ascii = 0;
13788
- for (const ch of text) {
13789
- const code = ch.codePointAt(0) ?? 0;
13790
- if (code >= 13312 && code <= 40959) cjk += 1;
13791
- else ascii += 1;
13792
- }
13793
- return Math.ceil(cjk * 1.5 + ascii / 4);
13794
- };
13795
- var OVERLAY_HEADER_LINES = [
13796
- "--- Memory (\u76F8\u5173\u65F6\u53C2\u8003\uFF0C\u7528\u6237\u8F93\u5165\u4F18\u5148) ---",
13797
- ""
13798
- ];
13799
- var OVERLAY_HEADER_TOKENS = estimateTokens(OVERLAY_HEADER_LINES.join("\n"));
13800
- var KIND_PRIORITY = {
13801
- semantic: 0,
13802
- procedural: 1,
13803
- episodic: 2
13804
- };
13805
- var FACET_DISPLAY = {
13806
- unfinished: { label: "\u8FD8\u6CA1\u5B9A\u4E0B", strip: "\u8FD8\u6CA1\u51B3\u5B9A" },
13807
- tension: { label: "\u5728\u6743\u8861", strip: "\u5728\u6743\u8861" },
13808
- preference: { label: "\u66F4\u5728\u610F", strip: "\u66F4\u5728\u610F" },
13809
- style: { label: "\u66F4\u504F\u597D", strip: "\u66F4\u559C\u6B22" },
13810
- goal: { label: "\u60F3\u63A8\u8FDB", strip: "\u60F3\u63A8\u8FDB" }
13811
- };
13812
- var INFERRED_SOURCE_KINDS = /* @__PURE__ */ new Set(["inferred-understanding", "dialog-learning"]);
13813
- var isInferredMemory = (item) => INFERRED_SOURCE_KINDS.has(getMemorySourceKind(item));
13814
- var formatFacetContent = (facet, normalized, prefix) => {
13815
- const { label, strip } = FACET_DISPLAY[facet];
13816
- const stripped = normalized.startsWith(strip) ? normalized.slice(strip.length).trim() : normalized;
13817
- return `${prefix}${label} ${stripped}`;
13818
- };
13819
- var normalizeDisplayContent = (item) => {
13820
- const normalized = item.content.trim().replace(EXPLICIT_REMEMBER_PREFIX_REGEX, "").replace(/[。!?!?]+$/u, "").trim();
13821
- if (item.kind === "semantic") {
13822
- if (item.tags?.includes("understanding-memory") && item.facet) {
13823
- return formatFacetContent(item.facet, normalized, "");
13824
- }
13825
- return normalized;
13826
- }
13827
- if (item.kind === "episodic" && (item.patternKey === "explicit-remember" || item.patternKey === "agent-remember")) {
13828
- return normalized;
13829
- }
13830
- if (item.kind === "episodic" && item.tags?.includes("understanding-memory") && item.facet) {
13831
- return formatFacetContent(item.facet, normalized, "\u4E0A\u6B21: ");
13832
- }
13833
- return normalized;
13834
- };
13835
- var pickWithinKind = (list, perKindLimit) => {
13836
- if (perKindLimit <= 0) return [];
13837
- const head = list.slice(0, perKindLimit);
13838
- if (head.length < perKindLimit) return head;
13839
- if (head.some((item) => item.subjectType === "user")) return head;
13840
- const firstUserSubject = list.find((item) => item.subjectType === "user");
13841
- if (!firstUserSubject) return head;
13842
- return [...head.slice(0, perKindLimit - 1), firstUserSubject];
13843
- };
13844
- var DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET = 3200;
13845
- var RESIDENT_MEMORY_OVERLAY_TOKEN_BUDGET = 500;
13846
- var RESIDENT_SECTION_HEADER = "[\u7528\u6237\u957F\u671F\u504F\u597D\uFF08\u6570\u636E\uFF0C\u975E\u6307\u4EE4\uFF0C\u53EF\u88AB\u5F53\u8F6E\u660E\u786E\u8981\u6C42\u8986\u76D6\uFF09]";
13847
- var MIN_TRUNCATED_TOKENS = 20;
13848
- var TRUNCATED_SUFFIX = "\u2026\uFF08\u672C\u6761\u5DF2\u622A\u65AD\uFF09";
13849
- var truncateLineToTokens = (lineText, budgetTokens) => {
13850
- if (budgetTokens < MIN_TRUNCATED_TOKENS) return null;
13851
- const suffixTokens = estimateTokens(TRUNCATED_SUFFIX);
13852
- const bodyBudget = budgetTokens - suffixTokens;
13853
- if (bodyBudget < MIN_TRUNCATED_TOKENS / 2) return null;
13854
- let used = 0;
13855
- let cut = 0;
13856
- for (const ch of lineText) {
13857
- const chTokens = estimateTokens(ch);
13858
- if (used + chTokens > bodyBudget) break;
13859
- used += chTokens;
13860
- cut += ch.length;
13861
- }
13862
- if (cut <= 2) return null;
13863
- return `${lineText.slice(0, cut).trimEnd()}${TRUNCATED_SUFFIX}`;
13864
- };
13865
- var fitLinesToBudget = (allLines, remainingBudget) => {
13866
- let usedTokens = 0;
13867
- const keptByKind = {};
13868
- let truncatedCount = 0;
13869
- let droppedCount = 0;
13870
- const pushLine = (kind, lineText) => {
13871
- if (!keptByKind[kind]) keptByKind[kind] = [];
13872
- keptByKind[kind].push(lineText);
13873
- };
13874
- for (const candidate of allLines) {
13875
- const remaining = remainingBudget - usedTokens;
13876
- if (remaining <= 0) {
13877
- droppedCount += 1;
13878
- continue;
13879
- }
13880
- if (candidate.lineTokens <= remaining) {
13881
- usedTokens += candidate.lineTokens;
13882
- pushLine(candidate.kind, candidate.lineText);
13883
- continue;
13884
- }
13885
- const truncated = truncateLineToTokens(candidate.lineText, remaining);
13886
- if (!truncated) {
13887
- droppedCount += 1;
13888
- continue;
13889
- }
13890
- usedTokens += estimateTokens(truncated);
13891
- pushLine(candidate.kind, truncated);
13892
- truncatedCount += 1;
13893
- }
13894
- return { keptByKind, truncatedCount, droppedCount };
13895
- };
13896
- var EMPTY_RETRIEVAL_FIT = {
13897
- keptByKind: {},
13898
- truncatedCount: 0,
13899
- droppedCount: 0
13900
- };
13901
- var EMPTY_RESIDENT_FIT = {
13902
- keptLines: [],
13903
- truncatedCount: 0,
13904
- droppedCount: 0
13905
- };
13906
- var fitResidentLines = (lines, remainingBudget) => {
13907
- let usedTokens = 0;
13908
- const keptLines = [];
13909
- let truncatedCount = 0;
13910
- let droppedCount = 0;
13911
- for (const candidate of lines) {
13912
- const remaining = remainingBudget - usedTokens;
13913
- if (remaining <= 0) {
13914
- droppedCount += 1;
13915
- continue;
13916
- }
13917
- if (candidate.lineTokens <= remaining) {
13918
- usedTokens += candidate.lineTokens;
13919
- keptLines.push(candidate.lineText);
13920
- continue;
13921
- }
13922
- const truncated = truncateLineToTokens(candidate.lineText, remaining);
13923
- if (!truncated) {
13924
- droppedCount += 1;
13925
- continue;
13926
- }
13927
- usedTokens += estimateTokens(truncated);
13928
- keptLines.push(truncated);
13929
- truncatedCount += 1;
13930
- }
13931
- return { keptLines, truncatedCount, droppedCount };
13932
- };
13933
- var buildBudgetFooter = (fit, residentFit) => {
13934
- const notices = [];
13935
- if (residentFit.truncatedCount > 0) {
13936
- notices.push(`${residentFit.truncatedCount} \u6761\u957F\u671F\u504F\u597D\u56E0\u9884\u7B97\u88AB\u622A\u65AD`);
13937
- }
13938
- if (residentFit.droppedCount > 0) {
13939
- notices.push(`${residentFit.droppedCount} \u6761\u957F\u671F\u504F\u597D\u672A\u663E\u793A`);
13940
- }
13941
- if (fit.truncatedCount > 0) {
13942
- notices.push(`${fit.truncatedCount} \u6761\u56E0\u9884\u7B97\u88AB\u622A\u65AD`);
13943
- }
13944
- if (fit.droppedCount > 0) {
13945
- notices.push(`${fit.droppedCount} \u6761\u672A\u663E\u793A`);
13946
- }
13947
- if (notices.length === 0) return [];
13948
- return [`\uFF08${notices.join("\u3001")}\uFF1B\u9700\u8981\u5B8C\u6574\u5185\u5BB9\u6216\u66F4\u591A\u76F8\u5173\u8BB0\u5FC6\u65F6\u7528 queryMemory \u68C0\u7D22\uFF09`];
13949
- };
13950
- var buildMemoryOverlay = (items, options) => {
13951
- if (items.length === 0) return null;
13952
- const maxTokens = options?.maxTokens ?? DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET;
13953
- const perKindLimit = options?.perKindLimit ?? 3;
13954
- const residentMaxTokens = options?.residentMaxTokens ?? RESIDENT_MEMORY_OVERLAY_TOKEN_BUDGET;
13955
- const residentItems = items.filter((item) => item.resident === true).sort((a, b) => b.createdAt.localeCompare(a.createdAt));
13956
- const retrievalItems = items.filter((item) => item.resident !== true);
13957
- const residentFit = residentItems.length === 0 ? EMPTY_RESIDENT_FIT : fitResidentLines(
13958
- residentItems.map((item) => {
13959
- const lineText = `- ${isInferredMemory(item) ? "\uFF08\u63A8\u65AD\uFF09" : ""}${normalizeDisplayContent(item)}`;
13960
- return { kind: item.kind, lineText, lineTokens: estimateTokens(lineText) };
13961
- }),
13962
- residentMaxTokens - estimateTokens(RESIDENT_SECTION_HEADER)
13963
- );
13964
- const byKind = {
13965
- episodic: [],
13966
- semantic: [],
13967
- procedural: []
13968
- };
13969
- for (const item of retrievalItems) {
13970
- byKind[item.kind].push(item);
13971
- }
13972
- const remainingBudget = maxTokens - OVERLAY_HEADER_TOKENS;
13973
- let retrievalFit = EMPTY_RETRIEVAL_FIT;
13974
- let retrievalSections = [];
13975
- if (remainingBudget > 0 && retrievalItems.length > 0) {
13976
- const allLines = Object.entries(byKind).filter(([, list]) => list.length > 0).flatMap(
13977
- ([kind, list]) => pickWithinKind(list, perKindLimit).map((item) => {
13978
- const lineText = `- ${isInferredMemory(item) ? "\uFF08\u63A8\u65AD\uFF09" : ""}${normalizeDisplayContent(item)}`;
13979
- return { kind, lineText, lineTokens: estimateTokens(lineText) };
13980
- })
13981
- ).sort((a, b) => (KIND_PRIORITY[a.kind] ?? 99) - (KIND_PRIORITY[b.kind] ?? 99));
13982
- retrievalFit = fitLinesToBudget(allLines, remainingBudget);
13983
- const kindOrder = ["semantic", "procedural", "episodic"];
13984
- retrievalSections = kindOrder.filter(
13985
- (kind) => retrievalFit.keptByKind[kind] && retrievalFit.keptByKind[kind].length > 0
13986
- ).map((kind) => {
13987
- return [`[${KIND_TITLES[kind]}]`, ...retrievalFit.keptByKind[kind]].join("\n");
13988
- });
13989
- }
13990
- const sections = [
13991
- ...residentFit.keptLines.length > 0 ? [[RESIDENT_SECTION_HEADER, ...residentFit.keptLines].join("\n")] : [],
13992
- ...retrievalSections
13993
- ];
13994
- if (sections.length === 0) {
13995
- return OVERLAY_HEADER_LINES.join("\n");
13996
- }
13997
- return [
13998
- ...OVERLAY_HEADER_LINES,
13999
- ...sections,
14000
- ...buildBudgetFooter(retrievalFit, residentFit)
14001
- ].join("\n");
14002
- };
14003
-
14004
- // packages/ai/memory/rank.ts
14005
- var CJK_SEQUENCE_REGEX = /[\u3400-\u4dbf\u4e00-\u9fff]+/g;
14006
- var MEMORY_IDENTIFIER_REGEX = /\b(?:memory|noise)-[a-z0-9][a-z0-9-]*/gi;
14007
- var buildCjkTokens = (text) => {
14008
- const sequences = text.match(CJK_SEQUENCE_REGEX) ?? [];
14009
- const tokens = [];
14010
- for (const sequence2 of sequences) {
14011
- if (sequence2.length >= 2) {
14012
- tokens.push(sequence2);
14013
- }
14014
- for (let index = 0; index < sequence2.length - 1; index += 1) {
14015
- tokens.push(sequence2.slice(index, index + 2));
14016
- }
14017
- }
14018
- return tokens;
14019
- };
14020
- var tokenize2 = (text) => {
14021
- const normalized = text.toLowerCase();
14022
- const wordTokens = normalized.split(/[\s,.;:!?()[\]{}"'`,。!?:;、]+/).map((token) => token.trim()).filter((token) => token.length >= 2);
14023
- return [...wordTokens, ...buildCjkTokens(normalized)];
14024
- };
14025
- var keywordScore = (query, item) => {
14026
- const queryTokens = new Set(tokenize2(query));
14027
- if (queryTokens.size === 0) return 0;
14028
- const haystack = /* @__PURE__ */ new Set([
14029
- ...tokenize2(item.content),
14030
- ...(item.tags ?? []).map((tag) => tag.toLowerCase()),
14031
- item.patternKey?.toLowerCase() ?? ""
14032
- ]);
14033
- let matches = 0;
14034
- for (const token of queryTokens) {
14035
- if (haystack.has(token)) matches += 1;
14036
- }
14037
- return Math.min(1, matches / Math.max(2, queryTokens.size));
14038
- };
14039
- var identifierScore = (query, item) => {
14040
- const identifiers = query.match(MEMORY_IDENTIFIER_REGEX) ?? [];
14041
- if (identifiers.length === 0) return 0;
14042
- const content = item.content.toLowerCase();
14043
- const matches = identifiers.filter(
14044
- (identifier) => content.includes(identifier.toLowerCase())
14045
- ).length;
14046
- return matches / identifiers.length;
14047
- };
14048
- var DAY_MS = 864e5;
14049
- var UNRETRIEVED_MEMORY_GRACE_DAYS = 3;
14050
- var MIN_UNRETRIEVED_SCORE_FACTOR = 0.3;
14051
- var UNRETRIEVED_DECAY_HALF_LIFE_DAYS = 7;
14052
- var retrievalFrequencyScore = (item, nowMs) => {
14053
- const lastRetrievedMs = Date.parse(item.lastActivatedAt || item.createdAt);
14054
- const ageDays = Math.max(0, (nowMs - lastRetrievedMs) / DAY_MS);
14055
- const recency = 1 / (1 + ageDays / 7);
14056
- const frequency = Math.min(1, Math.log1p(item.activationCount ?? 0) / 3);
14057
- return 0.7 * recency + 0.3 * frequency;
14058
- };
14059
- var unretrievedDecayFactor = (item, nowMs) => {
14060
- if ((item.activationCount ?? 0) !== 0) return 1;
14061
- const createdAgeDays = Math.max(0, (nowMs - Date.parse(item.createdAt)) / DAY_MS);
14062
- if (createdAgeDays <= UNRETRIEVED_MEMORY_GRACE_DAYS) return 1;
14063
- const overdue = createdAgeDays - UNRETRIEVED_MEMORY_GRACE_DAYS;
14064
- return Math.max(
14065
- MIN_UNRETRIEVED_SCORE_FACTOR,
14066
- 1 / (1 + overdue / UNRETRIEVED_DECAY_HALF_LIFE_DAYS)
14067
- );
14068
- };
14069
- var retrievalScore = (item, nowMs) => retrievalFrequencyScore(item, nowMs) * unretrievedDecayFactor(item, nowMs);
14070
- var creationRecencyScore = (item, nowMs) => {
14071
- const createdMs = Date.parse(item.createdAt);
14072
- const ageDays = Math.max(0, (nowMs - createdMs) / 864e5);
14073
- return 1 / (1 + ageDays / 7);
14074
- };
14075
- var typeFitScore = (item) => {
14076
- if (item.kind === "episodic") return 0.75;
14077
- if (item.kind === "semantic") return 0.9;
14078
- return 0.85;
14079
- };
14080
- var understandingScore = (item) => {
14081
- if (!item.tags?.includes("understanding-memory")) return 0;
14082
- if (item.facet === "unfinished") return 1;
14083
- if (item.facet === "tension") return 0.95;
14084
- if (item.facet === "preference") return 0.85;
14085
- if (item.facet === "style") return 0.75;
14086
- return 0.8;
14087
- };
14088
- var pathScore = (item, context) => {
14089
- let score = 0;
14090
- if (context?.currentOwner && item.ownerType === context.currentOwner.ownerType && item.ownerId === context.currentOwner.ownerId) {
14091
- score += 0.65;
14092
- }
14093
- if (context?.currentSubject && item.subjectType === context.currentSubject.subjectType && item.subjectId === context.currentSubject.subjectId) {
14094
- score += 0.85;
14095
- }
14096
- return Math.min(1, score);
14097
- };
14098
- var scoreMemoryItem = (item, query, nowMs = Date.now(), context) => {
14099
- const queryMatch = keywordScore(query, item);
14100
- const identifierMatch = identifierScore(query, item);
14101
- const retrieval = retrievalScore(item, nowMs);
14102
- const createdRecency = creationRecencyScore(item, nowMs);
14103
- const importance = item.importance ?? 0;
14104
- const confidence = item.confidence ?? 0;
14105
- const typeFit = typeFitScore(item);
14106
- const understanding = understandingScore(item);
14107
- const path2 = pathScore(item, context);
14108
- return 0.25 * queryMatch + 0.2 * identifierMatch + 0.2 * path2 + 0.09 * retrieval + // weak retrieval signal, NOT successful-use reinforcement
14109
- 0.16 * createdRecency + 0.06 * importance + 0.03 * confidence + 0.02 * typeFit + 0.01 * understanding;
14110
- };
14111
- var rankMemoryCandidates = (items, query, context) => {
14112
- const nowMs = Date.now();
14113
- return [...items].sort((a, b) => {
14114
- const aExplicit = a.sourceKind === "explicit-user-directive";
14115
- const bExplicit = b.sourceKind === "explicit-user-directive";
14116
- if (aExplicit !== bExplicit) return bExplicit ? 1 : -1;
14117
- if (aExplicit) {
14118
- return Date.parse(b.createdAt) - Date.parse(a.createdAt);
14119
- }
14120
- return scoreMemoryItem(b, query, nowMs, context) - scoreMemoryItem(a, query, nowMs, context);
14121
- });
14122
- };
14123
-
14124
13563
  // packages/ai/memory/vnext/detachedThrottle.ts
14125
13564
  var DEFAULT_DETACHED_MEMORY_COOLDOWN_MS = 10 * 60 * 1e3;
14126
13565
  var MAX_COOLDOWN_KEYS = 512;
@@ -14289,43 +13728,6 @@ ${catalogText(entities, states)}`
14289
13728
  };
14290
13729
  };
14291
13730
 
14292
- // packages/ai/memory/vnext/legacyMigration.ts
14293
- import { createHash } from "crypto";
14294
- var LEGACY_MEMORY_SOURCE_REF_PREFIX = "legacy-memory";
14295
- var LEGACY_MEMORY_EVIDENCE_ID_PREFIX = "mem-legacy-";
14296
- var resolveLegacyMemoryPrincipal = (item) => ({
14297
- ownerType: item.ownerType,
14298
- ownerId: item.ownerId,
14299
- principalId: `${item.ownerType}:${encodeURIComponent(item.ownerId)}`
14300
- });
14301
- var buildLegacyMemorySourceRef = (item) => {
14302
- const { principalId } = resolveLegacyMemoryPrincipal(item);
14303
- return `${LEGACY_MEMORY_SOURCE_REF_PREFIX}:${principalId}:${encodeURIComponent(item.id)}`;
14304
- };
14305
- var legacyEvidenceSeed = (principalId, itemId) => JSON.stringify([principalId, itemId]);
14306
- var buildLegacyEvidenceId = (item) => {
14307
- const { principalId } = resolveLegacyMemoryPrincipal(item);
14308
- const digest = createHash("sha256").update(legacyEvidenceSeed(principalId, item.id)).digest("hex");
14309
- return `${LEGACY_MEMORY_EVIDENCE_ID_PREFIX}${digest.slice(0, 32)}`;
14310
- };
14311
- var clampLegacyConfidence = (value) => {
14312
- if (typeof value !== "number" || !Number.isFinite(value)) return 0;
14313
- if (value < 0) return 0;
14314
- if (value > 1) return 1;
14315
- return value;
14316
- };
14317
- var buildLegacyMemoryEvidence = (item) => {
14318
- const { principalId } = resolveLegacyMemoryPrincipal(item);
14319
- return {
14320
- id: buildLegacyEvidenceId(item),
14321
- ownerId: principalId,
14322
- text: item.content,
14323
- sourceRef: buildLegacyMemorySourceRef(item),
14324
- confidence: clampLegacyConfidence(item.confidence),
14325
- createdAt: item.createdAt
14326
- };
14327
- };
14328
-
14329
13731
  // packages/ai/memory/vnext/shadowRead.ts
14330
13732
  var SHADOW_TIMEOUT_MS = 2e4;
14331
13733
  var ERROR_MESSAGE_MAX = 120;
@@ -14739,7 +14141,7 @@ var MEMORY_RELATION_TYPES = [
14739
14141
  var isObject = (value) => !!value && typeof value === "object" && !Array.isArray(value);
14740
14142
  var isString = (value) => typeof value === "string" && value.trim().length > 0;
14741
14143
  var isStringArray = (value) => Array.isArray(value) && value.every(isString);
14742
- var optionalArray = (value, validate2) => value === void 0 || Array.isArray(value) && value.every(validate2);
14144
+ var optionalArray = (value, validate) => value === void 0 || Array.isArray(value) && value.every(validate);
14743
14145
  var ACTIONS = /* @__PURE__ */ new Set([
14744
14146
  "no_op",
14745
14147
  "create",
@@ -15322,45 +14724,6 @@ var isMemoryVNextLazyPromotionEnabled = (env = typeof process !== "undefined" ?
15322
14724
  // packages/ai/memory/vnext/pureReadGate.ts
15323
14725
  var isMemoryVNextPureReadEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_PURE_READ === "1" || env.NOLO_MEMORY_VNEXT_PURE_READ === "true";
15324
14726
 
15325
- // packages/ai/memory/vnext/localRecall.ts
15326
- var MIN_SHARED_TOKENS = 2;
15327
- var MAX_LOCAL_RECALL_STATES = 8;
15328
- var SAFE_TECHNICAL_SYNONYMS = {
15329
- pr: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5", "diff"],
15330
- diff: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5"],
15331
- review: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5"],
15332
- deploy: ["\u90E8\u7F72", "\u53D1\u7248"],
15333
- release: ["\u53D1\u7248", "\u53D1\u5E03"],
15334
- desktop: ["\u684C\u9762", "\u684C\u9762\u7AEF"]
15335
- };
15336
- var distinctTokens = (text) => new Set(tokenize2(text).filter((token) => token.length >= 2));
15337
- var recallMemoryVNextLocal = (input) => {
15338
- const rawTokens = distinctTokens(input.query);
15339
- if (rawTokens.size === 0) return [];
15340
- const queryTokens = new Set(rawTokens);
15341
- for (const token of rawTokens) {
15342
- const syns = SAFE_TECHNICAL_SYNONYMS[token.toLowerCase()];
15343
- if (syns) {
15344
- for (const syn of syns) {
15345
- for (const t2 of distinctTokens(syn)) queryTokens.add(t2);
15346
- }
15347
- }
15348
- }
15349
- const entityById = new Map(input.entities.map((entity) => [entity.id, entity]));
15350
- const hits = [];
15351
- for (const state2 of input.states) {
15352
- if (state2.retiredAt || !state2.text.trim()) continue;
15353
- const entity = entityById.get(state2.entityId);
15354
- const haystack = distinctTokens(
15355
- [state2.facet, state2.text, entity?.name ?? "", ...entity?.aliases ?? []].join(" ")
15356
- );
15357
- let sharedTokens = 0;
15358
- for (const token of queryTokens) if (haystack.has(token)) sharedTokens++;
15359
- if (sharedTokens >= MIN_SHARED_TOKENS) hits.push({ state: state2, sharedTokens });
15360
- }
15361
- return hits.sort((a, b) => b.sharedTokens - a.sharedTokens || a.state.id.localeCompare(b.state.id)).slice(0, input.limit ?? MAX_LOCAL_RECALL_STATES);
15362
- };
15363
-
15364
14727
  // packages/ai/memory/vnext/pureVNextRuntime.ts
15365
14728
  var buildSynthesizedStateItem = (state2, entity, ownerType, ownerId) => ({
15366
14729
  id: `vnext-state-${state2.id}`,
@@ -15961,11 +15324,49 @@ async function runAgentRunCommand(args, deps) {
15961
15324
  writeUsage(output, deps.commandPath);
15962
15325
  return 1;
15963
15326
  }
15964
- const runner = deps.runner ?? runAgentTurn;
15327
+ const rawRunner = deps.runner ?? runAgentTurn;
15328
+ const watchdogAbort = new AbortController();
15329
+ let activeRunner;
15330
+ const runner = (options) => {
15331
+ activeRunner = Promise.resolve().then(() => rawRunner({ ...options, abortSignal: watchdogAbort.signal })).then((result) => {
15332
+ watchdogAbort.signal.throwIfAborted();
15333
+ return result;
15334
+ });
15335
+ return activeRunner;
15336
+ };
15337
+ const stopWatchdogRunner = async () => {
15338
+ watchdogAbort.abort(new Error("watchdog_stop"));
15339
+ if (!activeRunner) return true;
15340
+ let timer;
15341
+ try {
15342
+ return await Promise.race([
15343
+ activeRunner.then(() => true, () => true),
15344
+ new Promise((resolve6) => {
15345
+ timer = setTimeout(() => resolve6(false), 100);
15346
+ })
15347
+ ]);
15348
+ } finally {
15349
+ if (timer) clearTimeout(timer);
15350
+ }
15351
+ };
15965
15352
  const nowMs = () => deps.now ? deps.now().getTime() : Date.now();
15966
- const childRunId = env.NOLO_AGENT_RUN_ID;
15967
- const hasRegistry = typeof childRunId === "string" && childRunId.length > 0;
15968
- if (hasRegistry) reportRunProcessIdentity(childRunId, { env, homedir: deps.homedir, fs: deps.fs, now: deps.now });
15353
+ let childRunId = env.NOLO_AGENT_RUN_ID;
15354
+ let hasRegistry = typeof childRunId === "string" && childRunId.length > 0;
15355
+ const hostPolicy = () => ({
15356
+ runtimeKey: "local",
15357
+ hostWritesAuthorized: args.includes("--allow-host-writes"),
15358
+ readOnly: args.includes("--read-only"),
15359
+ ...parsed.allowedToolNames ? { allowedToolNames: parsed.allowedToolNames } : {},
15360
+ ...parsed.blockedToolNames ? { blockedToolNames: parsed.blockedToolNames } : {},
15361
+ provenance: "cli-command-authorized"
15362
+ });
15363
+ const locatedExecution = hasRegistry ? readRunRecord(childRunId, { env, homedir: deps.homedir, fs: deps.fs })?.execution : void 0;
15364
+ if (hasRegistry && (parsed.runtimeKey?.trim() === "local" || locatedExecution?.state === "known")) {
15365
+ const implicitReadonlyHost = !parsed.runtimeKey && args.includes("--read-only") && locatedExecution?.state === "known" && locatedExecution.runtimeKey === "local" && locatedExecution.permissions.readOnly;
15366
+ if (parsed.runtimeKey?.trim() !== "local" && !implicitReadonlyHost) throw new Error("[local-writer-resource] child binding runtime mismatch");
15367
+ await awaitLocalWriterChild(childRunId, parsed.cwd ?? process.cwd(), hostPolicy(), { env, homedir: deps.homedir, fs: deps.fs });
15368
+ }
15369
+ if (hasRegistry && parsed.runtimeKey?.trim() !== "local" && locatedExecution?.state !== "known") reportRunProcessIdentity(childRunId, { env, homedir: deps.homedir, fs: deps.fs, now: deps.now });
15969
15370
  const processExit = deps.processExit ?? ((code) => process.exit(code));
15970
15371
  const stallTimeoutMs = resolvePositiveMs(
15971
15372
  deps.stallTimeoutMs ?? env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS,
@@ -16007,9 +15408,9 @@ async function runAgentRunCommand(args, deps) {
16007
15408
  throw error;
16008
15409
  });
16009
15410
  };
16010
- const exitFromWatchdog = (code) => {
15411
+ const exitFromWatchdog = async (code) => {
16011
15412
  try {
16012
- processExit(code);
15413
+ await exitCliFromWatchdog(code, processExit, stopWatchdogRunner);
16013
15414
  } catch {
16014
15415
  }
16015
15416
  };
@@ -16056,8 +15457,8 @@ async function runAgentRunCommand(args, deps) {
16056
15457
  failureReason: "stalled",
16057
15458
  toolCallCount: currentActivity?.counters?.toolCalls
16058
15459
  });
15460
+ await exitFromWatchdog(outcome.exitCode);
16059
15461
  rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
16060
- exitFromWatchdog(outcome.exitCode);
16061
15462
  }
16062
15463
  }, Math.min(stallTimeoutMs, 1e4));
16063
15464
  }
@@ -16071,8 +15472,8 @@ async function runAgentRunCommand(args, deps) {
16071
15472
  terminalStatus.fail();
16072
15473
  const outcome = resolveRunOutcome({ kind: "timeout" });
16073
15474
  await finalizeWatchdogOutcome(outcome, note);
15475
+ await exitFromWatchdog(outcome.exitCode);
16074
15476
  rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
16075
- exitFromWatchdog(outcome.exitCode);
16076
15477
  }, parsed.timeoutMs);
16077
15478
  }
16078
15479
  const wantsFallbackSuggestions = parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0;
@@ -16081,8 +15482,8 @@ async function runAgentRunCommand(args, deps) {
16081
15482
  const explicitLocalCli = isLocalCliAgentKey(parsed.agentKey);
16082
15483
  const dockerRuntimeLocal = typeof parsed.runtimeKey === "string" && /^docker(:.+)?$/.test(parsed.runtimeKey.trim());
16083
15484
  const instaboxRuntimeLocal = typeof parsed.runtimeKey === "string" && parsed.runtimeKey.trim() === "instabox";
16084
- const hostRuntimeLocal = typeof parsed.runtimeKey === "string" && parsed.runtimeKey.trim() === "local";
16085
- if (hostRuntimeLocal && !args.includes("--allow-host-writes")) {
15485
+ const hostRuntimeLocal = typeof parsed.runtimeKey === "string" && parsed.runtimeKey.trim() === "local" || !parsed.runtimeKey && args.includes("--read-only") && locatedExecution?.state === "known" && locatedExecution.runtimeKey === "local" && locatedExecution.permissions.readOnly;
15486
+ if (hostRuntimeLocal && !args.includes("--read-only") && !args.includes("--allow-host-writes")) {
16086
15487
  output.write(t("agentRun.hostWriteGuard"));
16087
15488
  return 1;
16088
15489
  }
@@ -16219,6 +15620,9 @@ async function runAgentRunCommand(args, deps) {
16219
15620
  if (!localRuntimeCwd && (parsed.runtimeMode === "local" || hostRuntimeLocal)) {
16220
15621
  localRuntimeCwd = process.cwd();
16221
15622
  }
15623
+ const acceptanceCwd = localRuntimeCwd && (parsed.runtimeMode === "local" || hostRuntimeLocal) ? localRuntimeCwd : void 0;
15624
+ const acceptanceBase = acceptanceCwd ? await (deps.captureLocalRunBase ?? captureLocalRunBase)(acceptanceCwd, deps.localRunBaseCaptureOptions) : null;
15625
+ let finalWorkspaceInspection;
16222
15626
  if (parsed.runtimeKey === "instabox") {
16223
15627
  try {
16224
15628
  writeInstaboxRunConfig({
@@ -16246,9 +15650,20 @@ async function runAgentRunCommand(args, deps) {
16246
15650
  cliEntrypointPath: deps.cliEntrypointPath,
16247
15651
  agentKey,
16248
15652
  cwd: localRuntimeCwd,
15653
+ ...hostRuntimeLocal ? { localExecution: {
15654
+ runtimeKey: "local",
15655
+ hostWritesAuthorized: args.includes("--allow-host-writes"),
15656
+ readOnly: args.includes("--read-only"),
15657
+ ...parsed.allowedToolNames ? { allowedToolNames: parsed.allowedToolNames } : {},
15658
+ ...parsed.blockedToolNames ? { blockedToolNames: parsed.blockedToolNames } : {},
15659
+ provenance: "cli-command-authorized"
15660
+ } } : {},
15661
+ // Explicit host target is authorized above; read-only retains its existing tool restrictions.
15662
+ ...hostRuntimeLocal && !args.includes("--read-only") ? { claimLocalWrites: true } : {},
16249
15663
  msgFile: readFlagValue(args, "--msg-file"),
16250
15664
  message: parsed.message,
16251
15665
  timeoutMs: parsed.timeoutMs,
15666
+ ...parsed.ephemeral ? { ephemeral: true } : {},
16252
15667
  ...parsed.dodCommands?.length ? { dodCommands: parsed.dodCommands } : {},
16253
15668
  output
16254
15669
  },
@@ -16278,6 +15693,15 @@ async function runAgentRunCommand(args, deps) {
16278
15693
  const isSubtask = isSubtaskRun(env);
16279
15694
  const scopedLayers = [];
16280
15695
  const skillContentBlocks = [];
15696
+ if (hostRuntimeLocal && !parsed.background) {
15697
+ const policy = { ...hostPolicy(), ...skillAllowedToolOverride !== void 0 ? { allowedToolNames: skillAllowedToolOverride } : {} };
15698
+ if (hasRegistry) {
15699
+ await awaitLocalWriterChild(childRunId, localRuntimeCwd, policy, { env, homedir: deps.homedir, fs: deps.fs });
15700
+ } else if (!policy.readOnly) {
15701
+ childRunId = registerLocalForegroundWriter(localRuntimeCwd, policy, agentKey, { env, homedir: deps.homedir, fs: deps.fs, now: deps.now });
15702
+ hasRegistry = true;
15703
+ }
15704
+ }
16281
15705
  const extraContextBlocks = [];
16282
15706
  const contextBlockScopes = [];
16283
15707
  let memoryPromptBlock = null;
@@ -16408,6 +15832,7 @@ async function runAgentRunCommand(args, deps) {
16408
15832
  })
16409
15833
  );
16410
15834
  clearWatchdogs();
15835
+ const runCommandObservations = [...getRunResultHeaderMeta(result).commandObservations ?? []];
16411
15836
  let runCreditsTotal = result.turnCredits;
16412
15837
  let runCacheUsage = summarizeCacheUsageRecords(result.usageRecords);
16413
15838
  if (result.exitCode !== 0 && isQuotaExhaustedError(result.localError) && isLocalRun && parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0) {
@@ -16423,6 +15848,7 @@ async function runAgentRunCommand(args, deps) {
16423
15848
  })
16424
15849
  );
16425
15850
  clearWatchdogs();
15851
+ runCommandObservations.push(...getRunResultHeaderMeta(fallbackResult).commandObservations ?? []);
16426
15852
  if (fallbackResult.exitCode === 0) {
16427
15853
  result = fallbackResult;
16428
15854
  }
@@ -16475,6 +15901,7 @@ async function runAgentRunCommand(args, deps) {
16475
15901
  })
16476
15902
  );
16477
15903
  clearWatchdogs();
15904
+ runCommandObservations.push(...getRunResultHeaderMeta(turnResult).commandObservations ?? []);
16478
15905
  result = turnResult;
16479
15906
  if (turnResult.turnCredits !== void 0) {
16480
15907
  runCreditsTotal = (runCreditsTotal ?? 0) + turnResult.turnCredits;
@@ -16503,11 +15930,6 @@ async function runAgentRunCommand(args, deps) {
16503
15930
  );
16504
15931
  }
16505
15932
  }
16506
- terminalStatus.settle({
16507
- exitCode: result.exitCode,
16508
- streamInterrupted: result.streamInterrupted,
16509
- stalledOrTruncated: isRunResultStalledOrTruncated(result)
16510
- });
16511
15933
  if (result.dialogId) {
16512
15934
  if (parsed.background) {
16513
15935
  output.write(`
@@ -16521,11 +15943,12 @@ async function runAgentRunCommand(args, deps) {
16521
15943
  `);
16522
15944
  }
16523
15945
  }
16524
- if (shouldPrintLocalRunSummary({ parsed, localRuntimeCwd })) {
15946
+ if (acceptanceCwd || shouldPrintLocalRunSummary({ parsed, localRuntimeCwd })) {
16525
15947
  try {
16526
15948
  const inspect = deps.inspectLocalRunWorkspace ?? inspectLocalRunWorkspace;
16527
- const inspection = await inspect(localRuntimeCwd);
16528
- output.write(formatLocalRunSummary({
15949
+ const inspection = await inspect(localRuntimeCwd, {}, acceptanceCwd ? acceptanceBase : void 0);
15950
+ finalWorkspaceInspection = inspection;
15951
+ if (shouldPrintLocalRunSummary({ parsed, localRuntimeCwd })) output.write(formatLocalRunSummary({
16529
15952
  dialogId: result.dialogId,
16530
15953
  inspection
16531
15954
  }));
@@ -16564,6 +15987,8 @@ async function runAgentRunCommand(args, deps) {
16564
15987
  if (outcome.status === "failed") {
16565
15988
  if (result.emptyAssistantFallbackReason === "repetition_loop" || result.emptyAssistantFallbackReason === "stagnant_tool_calls") {
16566
15989
  failureReason = "stalled";
15990
+ } else if (result.localError && isHistoryIntegrityFailure(toErrorMessage(result.localError))) {
15991
+ failureReason = "history_integrity";
16567
15992
  } else if (result.localError && isQuotaExhaustedError(result.localError)) {
16568
15993
  failureReason = "provider_rate_limited";
16569
15994
  } else if (result.localError) {
@@ -16580,37 +16005,74 @@ async function runAgentRunCommand(args, deps) {
16580
16005
  toolCallCount = rawToolCount;
16581
16006
  }
16582
16007
  }
16583
- await settleRunTerminalAuthoritatively(
16584
- childRunId,
16585
- {
16586
- status: outcome.status,
16587
- exitCode: outcome.exitCode,
16588
- dialogId: result.dialogId,
16589
- ...dodResults ? { dodResults } : {},
16590
- // run 级累计的平台积分(主轮 + fallback + drain 轮):dock 行据此显示
16591
- // 「⚡ x.xx」,让派发任务的消耗可见。undefined = 全程无平台计费。
16592
- ...runCreditsTotal !== void 0 ? { credits: runCreditsTotal } : {},
16593
- // run 级缓存命中汇总:只进 .result.md 的 front matter(cached_tokens
16594
- // 为 null 表示 provider 未报缓存指标,与「命中 0」严格区分)。
16595
- ...runCacheUsage ? { cacheUsage: runCacheUsage } : {},
16596
- ...failureReason ? { failureReason } : {},
16597
- ...toolCallCount !== void 0 ? { toolCallCount } : {},
16598
- ...result.finalText ? { lastAssistantText: result.finalText } : {},
16599
- // 仅用于 .result.md 头(front matter):旁路读取,不改 result 形状。
16600
- ...getRunResultHeaderMeta(result),
16601
- ...truncationNote
16602
- },
16603
- {
16604
- env,
16605
- homedir: deps.homedir,
16606
- fs: deps.fs,
16607
- now: deps.now,
16608
- sleep: deps.sleep
16609
- },
16610
- deps.transitionRunToTerminal
16008
+ const acceptance = acceptanceCwd ? finalWorkspaceInspection?.acceptance ?? unknownLocalRunAcceptance(acceptanceCwd, acceptanceBase) : void 0;
16009
+ if (acceptance && dodResults?.length) {
16010
+ acceptance.checks.observations = dodResults.map((check, index) => ({
16011
+ // Command lines/output can contain credentials. Persist only a digest
16012
+ // here; the pre-existing registry is the execution evidence reference.
16013
+ commandFingerprint: `sha256:${createHash("sha256").update(check.command).digest("hex")}`,
16014
+ cwd: childRecordForDoD?.cwd || process.cwd(),
16015
+ exitCode: check.exitCode,
16016
+ evidence: `${childRunId}.json#/dodResults/${index}`,
16017
+ versionBinding: "unknown"
16018
+ }));
16019
+ }
16020
+ if (acceptance) attachLocalCommandObservations(
16021
+ acceptance,
16022
+ runCommandObservations,
16023
+ `${childRunId}.result.md`
16611
16024
  );
16025
+ let settlement;
16026
+ try {
16027
+ settlement = await settleRunTerminalAuthoritatively(
16028
+ childRunId,
16029
+ {
16030
+ status: outcome.status,
16031
+ exitCode: outcome.exitCode,
16032
+ dialogId: result.dialogId,
16033
+ ...dodResults ? { dodResults } : {},
16034
+ // run 级累计的平台积分(主轮 + fallback + drain 轮):dock 行据此显示
16035
+ // 「⚡ x.xx」,让派发任务的消耗可见。undefined = 全程无平台计费。
16036
+ ...runCreditsTotal !== void 0 ? { credits: runCreditsTotal } : {},
16037
+ // run 级缓存命中汇总:只进 .result.md 的 front matter(cached_tokens
16038
+ // 为 null 表示 provider 未报缓存指标,与「命中 0」严格区分)。
16039
+ ...runCacheUsage ? { cacheUsage: runCacheUsage } : {},
16040
+ ...failureReason ? { failureReason } : {},
16041
+ ...toolCallCount !== void 0 ? { toolCallCount } : {},
16042
+ ...acceptance ? { acceptance } : {},
16043
+ ...result.finalText ? { lastAssistantText: result.finalText } : {},
16044
+ // 仅用于 .result.md 头(front matter):旁路读取,不改 result 形状。
16045
+ ...getRunResultHeaderMeta(result),
16046
+ ...truncationNote
16047
+ },
16048
+ {
16049
+ env,
16050
+ homedir: deps.homedir,
16051
+ fs: deps.fs,
16052
+ now: deps.now,
16053
+ sleep: deps.sleep
16054
+ },
16055
+ deps.transitionRunToTerminal
16056
+ );
16057
+ } catch (error) {
16058
+ terminalStatus.fail();
16059
+ output.write(`[nolo] terminal settlement failed: ${error instanceof Error ? error.message : String(error)}
16060
+ `);
16061
+ return 1;
16062
+ }
16063
+ if (settlement && (settlement.kind === "transitioned" || settlement.kind === "kept" || settlement.kind === "contended") && settlement.record.status !== "done" && result.exitCode === 0) {
16064
+ result = { ...result, exitCode: settlement.record.exitCode || 1 };
16065
+ }
16612
16066
  }
16067
+ terminalStatus.settle({
16068
+ exitCode: result.exitCode,
16069
+ streamInterrupted: result.streamInterrupted,
16070
+ stalledOrTruncated: isRunResultStalledOrTruncated(result)
16071
+ });
16613
16072
  return result.exitCode;
16073
+ } catch (error) {
16074
+ terminalStatus.fail();
16075
+ throw error;
16614
16076
  } finally {
16615
16077
  shellApprovalChild?.close();
16616
16078
  if (shellApprovalChild && process.connected) process.disconnect();
@@ -16620,22 +16082,6 @@ async function runAgentRunCommand(args, deps) {
16620
16082
  export {
16621
16083
  resolveCliColorEnabled,
16622
16084
  dimCliText,
16623
- ANSI_ESCAPE_REGEX,
16624
- stripAnsi2 as stripAnsi,
16625
- applyTerminalOutputToText,
16626
- displayWidth,
16627
- visibleWidth,
16628
- truncateAnsi,
16629
- fitAnsiLine,
16630
- countPhysicalLines,
16631
- takeDisplayWidth,
16632
- padOrTruncateToWidth,
16633
- tokenizeAnsiLine,
16634
- buildSourceMapping,
16635
- wrapTranscriptLineWithLayout,
16636
- wrapTranscriptLine,
16637
- buildWindowTitle,
16638
- wrapTextToLines,
16639
16085
  THEME_PALETTES,
16640
16086
  getActiveThemeName,
16641
16087
  setActiveThemeName,
@@ -16657,9 +16103,10 @@ export {
16657
16103
  setMathRenderingEnabled,
16658
16104
  polishBreathInsertsBlankBetween,
16659
16105
  formatAssistantDisplay,
16660
- redactSecrets,
16661
- safeAskText,
16106
+ resolveHistoryLayoutGeometry,
16107
+ resolveHistoryViewportHeight,
16662
16108
  TUI_TREE_MARKER,
16109
+ TUI_TREE_TOOLS,
16663
16110
  resolveAgentModelIdentity,
16664
16111
  resolveAgentContextWindow2 as resolveAgentContextWindow,
16665
16112
  platformCreditsFromUsage,
@@ -16667,6 +16114,7 @@ export {
16667
16114
  formatTokenCount,
16668
16115
  resolveAuthorityTurnCount,
16669
16116
  computeBaselineContextTokens,
16117
+ preserveContextUsageWithoutReceipt,
16670
16118
  resolveContextUsage,
16671
16119
  renderTokenStatus,
16672
16120
  createIdleHeapReleaser,
@@ -16682,10 +16130,13 @@ export {
16682
16130
  findCollapsedPasteSpanAt,
16683
16131
  readAgentsMdLayerFromDisk,
16684
16132
  emitTerminalProgramStatus,
16133
+ contextRefusalDiagnostics,
16134
+ describeContextRefusal,
16685
16135
  isBalanceExhaustedError,
16686
16136
  OWNER_OAUTH_UNAVAILABLE_HINT,
16687
16137
  isOwnerOAuthUnavailableError,
16688
16138
  isInvalidGrantError,
16139
+ isLocalContextCoverageFailure,
16689
16140
  runAgentTurn,
16690
16141
  resolveWorkflowReference,
16691
16142
  resolveSkillReference,
@@ -16697,7 +16148,6 @@ export {
16697
16148
  FAILED_EMPTY_ASSISTANT_REASONS,
16698
16149
  isRunResultStalledOrTruncated,
16699
16150
  resolveTerminalProgramStatusState,
16700
- inspectLocalRunWorkspace,
16701
16151
  resolveRunOutcome,
16702
16152
  resolveRunSettlementNote,
16703
16153
  runAgentRunCommand