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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/README.md +3 -2
  2. package/{_executeModel-KE6MBNUJ.js → _executeModel-4GGQQHOB.js} +111 -82
  3. package/{accountResolver-4LKIHEKL.js → accountResolver-EK2S4PWF.js} +6 -6
  4. package/{action-DF5UYSJF.js → action-CK64LS6S.js} +12 -11
  5. package/{addContentAction-N2YC5IL3.js → addContentAction-GDHDOF4U.js} +18 -17
  6. package/{addDialogAgentAction-3NKVQCEC.js → addDialogAgentAction-CAKRU3ZT.js} +21 -20
  7. package/{agentDeleteCommand-NWK7VU4N.js → agentDeleteCommand-BPV2XZL7.js} +128 -119
  8. package/{agentEmailCommands-UZ4DHEX2.js → agentEmailCommands-EJOS75YL.js} +132 -124
  9. package/{agentFavoriteCommands-EDK743YA.js → agentFavoriteCommands-2LKGKSUD.js} +7 -8
  10. package/{agentGrantCommands-RQWK2TEV.js → agentGrantCommands-QQV4N4JW.js} +5 -5
  11. package/{agentListCommands-HE7L2A6L.js → agentListCommands-HIZODBF3.js} +196 -124
  12. package/{agentMachineCommands-6TE4MBMP.js → agentMachineCommands-ZMQ2CY7Y.js} +62 -53
  13. package/{agentProviderCommands-Q5O33MED.js → agentProviderCommands-WKJOAWBP.js} +5 -5
  14. package/{agentPullCommand-6EM3URVK.js → agentPullCommand-XN6ZPBUW.js} +7 -7
  15. package/agentRecordCommands-OMXVDLDX.js +176 -0
  16. package/agentRunCommand-CB34YWMV.js +206 -0
  17. package/{agentRunControl-OI3LOENH.js → agentRunControl-JNONH3RP.js} +30 -15
  18. package/{agentRuntimeLocal-HL526DNQ.js → agentRuntimeLocal-QZPFWMLG.js} +52 -45
  19. package/{agentSlice-TMYP2UEA.js → agentSlice-RD2CDU7T.js} +20 -19
  20. package/{appDeleteCommands-ZERW4AXY.js → appDeleteCommands-QCCFDIEQ.js} +61 -52
  21. package/{appDeployCommands-DUWSMYHL.js → appDeployCommands-V2T7TNMQ.js} +61 -52
  22. package/{appDeployStatusCommands-N2KIE4BF.js → appDeployStatusCommands-6PGH7ZCG.js} +61 -52
  23. package/{appGetCommands-YVR4NPVY.js → appGetCommands-3L7WWJA6.js} +61 -52
  24. package/{appListCommands-JS6HOHZS.js → appListCommands-ENJCK4PO.js} +61 -52
  25. package/{authCommand-FE2C3ZUM.js → authCommand-6V47SYGK.js} +29 -28
  26. package/{authCommands-HV3EAU3V.js → authCommands-GAJ3NIXO.js} +14 -13
  27. package/{builtinSkillRegistry-3YOIGEF6.js → builtinSkillRegistry-2ECA42FC.js} +11 -13
  28. package/{chromeCommands-REEAH4SX.js → chromeCommands-G5UDKVSV.js} +3 -3
  29. package/{chromeOpsCommands-HEN5AX2J.js → chromeOpsCommands-YKX2QX3A.js} +20 -10
  30. package/{chunk-DM6UMOEL.js → chunk-27PCUMJI.js} +2 -2
  31. package/chunk-2CI3ZFWD.js +97 -0
  32. package/{chunk-HIRC32DV.js → chunk-2GJKRKI6.js} +543 -29
  33. package/{chunk-SM3NSZJV.js → chunk-2UCBGYO4.js} +20 -1
  34. package/{chunk-PYRUW7XN.js → chunk-2VUZSVAS.js} +136 -54
  35. package/chunk-2YGBI2XB.js +30 -0
  36. package/chunk-2ZKFCIJJ.js +13 -0
  37. package/{chunk-CJRONOYL.js → chunk-34J5K2YA.js} +19 -75
  38. package/{chunk-LOEO7LRC.js → chunk-3IK6ILVW.js} +4 -1
  39. package/{chunk-CTPXME7U.js → chunk-3LMUPOHG.js} +29 -6
  40. package/chunk-44X52WOJ.js +1621 -0
  41. package/{chunk-6VLJ6YA7.js → chunk-4DESLZTK.js} +9 -9
  42. package/{chunk-MYOH447Z.js → chunk-4JVNURX4.js} +1 -1
  43. package/chunk-5CHGAKRT.js +364 -0
  44. package/{chunk-YDH3FDFQ.js → chunk-5FUN7EG4.js} +1 -1
  45. package/{chunk-LKDF3ATR.js → chunk-5RKUPJYL.js} +1 -1
  46. package/{chunk-ZC3CMUKU.js → chunk-6OVNSQHN.js} +84 -2
  47. package/{chunk-IF45XG7K.js → chunk-6WU5572L.js} +40 -24
  48. package/{chunk-OHNELDTO.js → chunk-7EEZJ6BS.js} +11 -152
  49. package/{chunk-Y6ORVLSS.js → chunk-7ET2U67U.js} +1 -1
  50. package/{chunk-G7MLNNEX.js → chunk-7JLY4WYF.js} +5 -5
  51. package/{chunk-P5L7CXOC.js → chunk-7Z6EW7AH.js} +3 -2
  52. package/{chunk-IIQ6JGRI.js → chunk-AD5EWDFD.js} +2 -2
  53. package/{chunk-WXYLV624.js → chunk-AIHYNKGV.js} +4 -4
  54. package/{chunk-HPFCI4SK.js → chunk-AK5O76CC.js} +3 -3
  55. package/{chunk-Y63ZSOR6.js → chunk-AL3TYDIF.js} +1 -1
  56. package/{chunk-PJNFNEJE.js → chunk-AMEOV5VZ.js} +59 -13
  57. package/chunk-AN74ON4G.js +675 -0
  58. package/{chunk-HRMJUN5J.js → chunk-AQZ6BMRK.js} +1 -1
  59. package/{chunk-CQ46IRNN.js → chunk-B4GOW4MT.js} +445 -201
  60. package/{chunk-4KB6WQUL.js → chunk-BGP2EDFG.js} +1 -1
  61. package/{chunk-NBTY7YJF.js → chunk-BR3GT6MR.js} +1 -0
  62. package/{chunk-7RFNTILS.js → chunk-BUDVRYES.js} +2 -2
  63. package/{chunk-D2MDMY2M.js → chunk-BV3FLP2L.js} +47 -1
  64. package/{chunk-25JZEIXN.js → chunk-C4VAR65S.js} +92 -150
  65. package/{chunk-AVTVGMDY.js → chunk-C4WTX5TU.js} +2 -2
  66. package/{chunk-ZL5RAEEB.js → chunk-CIRB724Q.js} +1 -1
  67. package/{chunk-F6UUQOG6.js → chunk-CKT6QUE2.js} +4 -4
  68. package/{chunk-M6RL5JCD.js → chunk-CMZ3Z5PT.js} +14 -14
  69. package/{secretCommands-4QS3HCA2.js → chunk-D726I5AZ.js} +191 -16
  70. package/{chunk-INSBKSBB.js → chunk-DNKTQ3IN.js} +4 -4
  71. package/chunk-DVQH4BTR.js +1137 -0
  72. package/{chunk-SOHTHFV2.js → chunk-DWX2HEVC.js} +91 -132
  73. package/{chunk-NOMIGOST.js → chunk-EIAI3PPH.js} +116 -124
  74. package/chunk-EUCFKKDM.js +247 -0
  75. package/chunk-EWQ3HGNZ.js +90 -0
  76. package/{chunk-RPQXPZZF.js → chunk-F3GRJO4Z.js} +908 -13
  77. package/{chunk-GSQNH63I.js → chunk-FIYSMXHY.js} +3 -19
  78. package/{chunk-KSTEXKL6.js → chunk-FJ23FZXF.js} +76 -31
  79. package/{chunk-INN4LTAJ.js → chunk-FJK526XH.js} +2 -2
  80. package/chunk-FS2XP5D7.js +142 -0
  81. package/{chunk-QT6PKHYJ.js → chunk-FYF2TONJ.js} +5 -5
  82. package/{chunk-OXME3PEE.js → chunk-GBWGPTA7.js} +2 -1
  83. package/{chunk-RU4SD66C.js → chunk-GYVCJABP.js} +30 -254
  84. package/{chunk-YUXQAVRD.js → chunk-HOCHUZQ7.js} +257 -90
  85. package/{chunk-Y2WUYX4I.js → chunk-HXER7YJF.js} +4 -4
  86. package/chunk-HYIETXA6.js +99 -0
  87. package/{chunk-H2TJUNCH.js → chunk-I4EADJ4P.js} +6 -6
  88. package/{chunk-TCZHTTUU.js → chunk-I7WBYGBP.js} +8 -8
  89. package/{chunk-5RYBGBQH.js → chunk-IILMY4W4.js} +14 -9
  90. package/chunk-JA3ICVJY.js +271 -0
  91. package/{chunk-ZRSNONOB.js → chunk-JWXITTQB.js} +8 -3
  92. package/{chunk-JNKSDZFS.js → chunk-KEN3N2TN.js} +310 -66
  93. package/{chunk-LEC5ALIN.js → chunk-KEPOVMF4.js} +1 -1
  94. package/{chunk-UHJGXRJ4.js → chunk-KQSYAIZR.js} +3 -3
  95. package/{chunk-4VJAC32I.js → chunk-L5I543VB.js} +3 -2
  96. package/chunk-LKA64WH4.js +227 -0
  97. package/{chunk-6OQUPIQF.js → chunk-LVL6GFCM.js} +4 -4
  98. package/{chunk-UTV2AYEG.js → chunk-MAIITKBT.js} +2 -2
  99. package/chunk-MBG66ZBH.js +226 -0
  100. package/{chunk-YUA6OAH5.js → chunk-MDLS23JK.js} +2 -2
  101. package/{chunk-VL5KOY2C.js → chunk-MK2Q7ZJD.js} +67 -5
  102. package/{chunk-B7NJ3T4A.js → chunk-MS4NZNKI.js} +10 -10
  103. package/{chunk-3AKFVZ2I.js → chunk-MYHNBEXD.js} +3 -3
  104. package/{chunk-VZKUKCA6.js → chunk-MZLE5HQ3.js} +3673 -241
  105. package/{chunk-AZMYUSVF.js → chunk-N5Z2V73W.js} +1 -1
  106. package/chunk-NIZ2BXFD.js +526 -0
  107. package/{chunk-YPD3VJZW.js → chunk-NWP2OYOX.js} +20 -20
  108. package/{chunk-3FOQHGHN.js → chunk-O6J3OTOP.js} +4 -4
  109. package/{chunk-3RQVYR4B.js → chunk-OB6DVWPF.js} +197 -65
  110. package/{chunk-YWSEPJ7C.js → chunk-OBWT45ZU.js} +3 -3
  111. package/{chunk-5AQR3DGV.js → chunk-ODJ7BVSI.js} +80 -11
  112. package/{chunk-XJWWBO34.js → chunk-OJKUU3LP.js} +5 -7
  113. package/{chunk-GNDJKC4B.js → chunk-ON37YXGX.js} +29 -29
  114. package/{chunk-D5RCRX4A.js → chunk-P5ZJRTCH.js} +9415 -5169
  115. package/{chunk-6XIE5ZGI.js → chunk-PDCV7P5W.js} +1 -1
  116. package/{chunk-EZFQ6XRV.js → chunk-PJCIP64Z.js} +861 -59
  117. package/{chunk-GPO7FCEZ.js → chunk-PJVKMGPZ.js} +1222 -1719
  118. package/{chunk-CKAHAVMK.js → chunk-PPJYZRSQ.js} +40 -26
  119. package/chunk-QHEN7NZ7.js +46 -0
  120. package/{chunk-4KH4J3G5.js → chunk-QNWG52I4.js} +19 -7
  121. package/{chunk-YGILMZ7N.js → chunk-QVBXJNZ2.js} +1 -1
  122. package/chunk-RDH5CQ4T.js +1382 -0
  123. package/{chunk-C6KNNXWU.js → chunk-RGQ4UUWZ.js} +25 -2
  124. package/{chunk-OWYYDMGJ.js → chunk-S2NTVGA2.js} +4 -2
  125. package/{chunk-KC4XDTT3.js → chunk-SOF4OWDM.js} +6 -4
  126. package/{chunk-IAPCBNEE.js → chunk-SQYIK6HO.js} +1 -1
  127. package/{chunk-22CIEBYO.js → chunk-SVT62ULE.js} +50 -48
  128. package/{chunk-KIM6CLW5.js → chunk-SY3C4SQ7.js} +42 -15
  129. package/{chunk-JY5NGFFH.js → chunk-SYTHYBMI.js} +5 -5
  130. package/{chunk-6NSSLV67.js → chunk-T6DXNI6Z.js} +52 -50
  131. package/chunk-TLE77UJ5.js +230 -0
  132. package/{chunk-4VNS5WPM.js → chunk-U67V476Y.js} +1 -8
  133. package/{chunk-F7CI2ZC5.js → chunk-UAIHKQIA.js} +2 -1
  134. package/{chunk-MMNYUVLW.js → chunk-UB3D4TRQ.js} +11 -77
  135. package/{chunk-WPORQFYN.js → chunk-UVLYNWIE.js} +2 -2
  136. package/{chunk-YOIW77S2.js → chunk-UYOICCYG.js} +29 -19
  137. package/{chunk-4I7ERB7F.js → chunk-VREDDN25.js} +1 -1
  138. package/{chunk-JIT6FSXJ.js → chunk-WAE3GFCJ.js} +3 -3
  139. package/{chunk-IJXYFTV7.js → chunk-WI67URFP.js} +20 -20
  140. package/{chunk-7OCO4TDT.js → chunk-WJVYAO6P.js} +1 -1
  141. package/{chunk-T43B7LB2.js → chunk-WKGQSYTB.js} +1 -1
  142. package/{chunk-YJMRHHGY.js → chunk-WUUH4LWZ.js} +60 -30
  143. package/{chunk-PDGKOTO7.js → chunk-X7UF53VA.js} +33 -22
  144. package/{chunk-TY3TIUJK.js → chunk-XI2BWJM5.js} +65 -0
  145. package/{chunk-OOF4UPC5.js → chunk-XWVCYUUU.js} +16 -159
  146. package/{chunk-J5JTMQIA.js → chunk-YFLVRVYK.js} +1 -1
  147. package/{chunk-EYLGAEB4.js → chunk-YGMBIXCF.js} +132 -0
  148. package/chunk-YL3EFYL3.js +199 -0
  149. package/{chunk-MMA3LZ3W.js → chunk-YNIYE47Z.js} +1 -1
  150. package/{chunk-W4S457LU.js → chunk-YU4ZPWVF.js} +41 -5
  151. package/{chunk-NJR3WKVP.js → chunk-YWWDC3O7.js} +281 -159
  152. package/chunk-YZMNK53S.js +68 -0
  153. package/{chunk-FHU44LN3.js → chunk-Z2PITYZN.js} +2179 -552
  154. package/{chunk-FY7F4Q6X.js → chunk-Z4PCXPUE.js} +2 -2
  155. package/{cliAgentConfigHelpers-WJBZQTLW.js → cliAgentConfigHelpers-TKYL43MT.js} +15 -16
  156. package/{cliAuthorityBrokerClient-PM3U6Q6J.js → cliAuthorityBrokerClient-XHH7MH2P.js} +1 -1
  157. package/{cliAuthorityStoreDriver-TKLXNNTG.js → cliAuthorityStoreDriver-6FE3BJNB.js} +1 -1
  158. package/{cliEnvHelpers-BVYTMUPJ.js → cliEnvHelpers-VPSJ4XWC.js} +3 -3
  159. package/{cliExecutor-BWBF2MTI.js → cliExecutor-4MAX3PZL.js} +2 -2
  160. package/cliLocalAgentRecordReader-MHHD4T7R.js +90 -0
  161. package/{commandRegistry-VVMTPFAX.js → commandRegistry-5DA5UP7S.js} +106 -98
  162. package/{contentThunks-N52O67MI.js → contentThunks-5GUQ7FWJ.js} +47 -43
  163. package/{cooldownCommands-YXLWOXWR.js → cooldownCommands-X7P5M2V5.js} +5 -4
  164. package/{createAgentAutomationAction-ZC57YRSV.js → createAgentAutomationAction-UCLTHQRI.js} +51 -49
  165. package/{createDialogAction-VQW5WDYX.js → createDialogAction-UPN774AF.js} +46 -48
  166. package/{createPageAction-M5VDA7SC.js → createPageAction-JRQ2TA4O.js} +50 -48
  167. package/{cursorProvider-YGGNMVWX.js → cursorProvider-2RACMEMF.js} +1 -1
  168. package/{db-HUCI5R4G.js → db-CS4ZJQKV.js} +1 -1
  169. package/{dbSlice-HP7G4LX3.js → dbSlice-WNON7TOL.js} +17 -16
  170. package/{deleteFile-7VQGLK2V.js → deleteFile-Q3YDB4ML.js} +9 -9
  171. package/{desktopFolderProjects-SFY5EZS3.js → desktopFolderProjects-4POAMVJN.js} +2 -2
  172. package/{dialogCommands-JHMR2N2Y.js → dialogCommands-VRI7VCXH.js} +64 -57
  173. package/dialogNotifyCommand-6TMCX4D2.js +36 -0
  174. package/{dialogSlice-GRSVGDTF.js → dialogSlice-LFNVUSAN.js} +42 -40
  175. package/{dialogUsageCommand-7KCPYGHG.js → dialogUsageCommand-HTVPR2CX.js} +11 -10
  176. package/{docCreateCommands-F2K3UPSQ.js → docCreateCommands-AMPXMOX3.js} +61 -54
  177. package/{docDeleteCommands-XGXB5RFT.js → docDeleteCommands-I5WFAEHP.js} +63 -57
  178. package/{docReadCommands-7HWZZV6J.js → docReadCommands-X53ELNIE.js} +61 -54
  179. package/{docStore-KNZK6Y2G.js → docStore-2VAWVLWH.js} +21 -20
  180. package/{docUpdateCommands-OZZ7NQII.js → docUpdateCommands-6QPNDC7M.js} +64 -57
  181. package/{fetchMessages-M3QU7ZCQ.js → fetchMessages-TQEUZD7H.js} +8 -7
  182. package/{getPricing-2MNMXEVG.js → getPricing-MB2GBXOK.js} +6 -6
  183. package/{handleSendMessageAction-SHIH74GJ.js → handleSendMessageAction-AAJOHXOB.js} +193 -301
  184. package/{hostCredentialCreate-X64WK4JD.js → hostCredentialCreate-GLMJ22M6.js} +123 -114
  185. package/index.js +29 -29
  186. package/{keys-BEGDOTRL.js → keys-RWF7UCB4.js} +5 -4
  187. package/legacyMigration-TF4SYJCZ.js +19 -0
  188. package/{lib-5KKIBFIT.js → lib-OT5OTXRU.js} +7087 -6664
  189. package/{localDialogRead-XRLAH4CZ.js → localDialogRead-SVTPA5GY.js} +3 -3
  190. package/{localFirstLog-DHNOY2NA.js → localFirstLog-OIETGK66.js} +1 -1
  191. package/localRecall-2J6QPOK2.js +15 -0
  192. package/{localRuntimeAdapter-A7K3ABA6.js → localRuntimeAdapter-BMP57P42.js} +119 -110
  193. package/{localRuntimeAuthority-OYH4AE4G.js → localRuntimeAuthority-IBJAT62G.js} +1 -1
  194. package/{localRuntimeDb-VBIMCWUC.js → localRuntimeDb-N7KHDXS2.js} +2 -2
  195. package/{machineCommands-DE3MR7CJ.js → machineCommands-3MLIAK5Q.js} +128 -119
  196. package/{machineInfo-UKPTZO5Y.js → machineInfo-LWHTEBHJ.js} +1 -1
  197. package/machineWsRunDispatch-FKIGROQF.js +191 -0
  198. package/{memberThunks-7WJAY5V6.js → memberThunks-ZGLZ36PK.js} +29 -28
  199. package/{memoryCommands-ASCE5STX.js → memoryCommands-5WC3T66U.js} +4 -4
  200. package/models-ULVWLSQ6.js +9 -0
  201. package/{oauthTokenStore-OEERZFUC.js → oauthTokenStore-RUYNYALS.js} +1 -1
  202. package/{offlineMarxistsAgentCommand-2QTHJCHV.js → offlineMarxistsAgentCommand-4IC3Y4C6.js} +4 -4
  203. package/overlay-THLKYIWY.js +11 -0
  204. package/package.json +2 -2
  205. package/{pdf-U6KSUEZZ.js → pdf-KE3QI2V7.js} +1 -1
  206. package/{processSpawn-ZU5QFM43.js → processSpawn-6GEO77KV.js} +1 -1
  207. package/{profileConfig-KN3N2BLF.js → profileConfig-KOWK4HOG.js} +1 -1
  208. package/{projectArchive-GGL5HLMD.js → projectArchive-HK63GMF4.js} +52 -50
  209. package/{providerPresetApply-YXGV6NXB.js → providerPresetApply-OIFQ73LH.js} +19 -12
  210. package/{providerRegistry-S6UL6UNA.js → providerRegistry-KZ3SDZ3D.js} +10 -10
  211. package/{read-4VZQODSN.js → read-MRQHJMJ2.js} +10 -10
  212. package/{readDocTool-AVD32RUJ.js → readDocTool-4BGTXTXA.js} +2 -2
  213. package/{readlineWorkspace-XKYKNL2I.js → readlineWorkspace-AKAHSCNY.js} +6505 -4634
  214. package/{removeDialogAgentAction-FKL4BYMR.js → removeDialogAgentAction-B6H7DXFM.js} +23 -22
  215. package/{runAgentClientLoop-V7E2WBVM.js → runAgentClientLoop-UVAWGEON.js} +81 -79
  216. package/{runtimeDoctorCommands-QAI3MBKQ.js → runtimeDoctorCommands-FW6XKDUG.js} +12 -12
  217. package/{runtimeModeArgs-2Y7BALTO.js → runtimeModeArgs-X7DL7PUN.js} +1 -1
  218. package/secretCommands-LJXOOYA7.js +24 -0
  219. package/{setDialogExtraReferencesAction-TLIOLWWI.js → setDialogExtraReferencesAction-EVCY3TRW.js} +22 -21
  220. package/{setPrimaryDialogAgentAction-2OLWRFYR.js → setPrimaryDialogAgentAction-KPFVPHCJ.js} +23 -22
  221. package/{settingThunks-UGBPCNYF.js → settingThunks-ENOAK2WV.js} +97 -88
  222. package/{skillDiscovery-XKHROSH2.js → skillDiscovery-B5V23AXP.js} +4 -4
  223. package/{skillSummaryMarker-42HKSXYY.js → skillSummaryMarker-62UW7HI7.js} +1 -1
  224. package/{slateToRenderMarkdown-Y5IYN73U.js → slateToRenderMarkdown-R3X74MCX.js} +1 -1
  225. package/{slateUtils-NGV2NMKM.js → slateUtils-ESQAJ6RN.js} +1 -1
  226. package/{spaceCommands-4KSLKVNF.js → spaceCommands-DTTNAS2L.js} +61 -53
  227. package/store-JRVN62NM.js +46 -0
  228. package/{streamAgentChatTurn-7FR7X2NU.js → streamAgentChatTurn-R5UY25VB.js} +875 -618
  229. package/{switchDialogAgentAction-UZSAG2N5.js → switchDialogAgentAction-SZ44XDRY.js} +21 -20
  230. package/{tableCommands-MP6VFSVT.js → tableCommands-HITDSLHS.js} +10 -10
  231. package/tombstones-FQQMEDOW.js +32 -0
  232. package/{toolApiClient-HGNO53TC.js → toolApiClient-OGQEBQVX.js} +4 -4
  233. package/{tools-ZLKCC25W.js → tools-HWFG6GMJ.js} +75 -74
  234. package/tuiSummaryLlmCaller-HQQZAMYF.js +44 -0
  235. package/{updateCommands-4744PL3P.js → updateCommands-RJVCRSBP.js} +10 -8
  236. package/{updateDialogTitleAction-U53ZT7PJ.js → updateDialogTitleAction-KNPOAMVS.js} +48 -46
  237. package/{usageCommand-F4IPVMIZ.js → usageCommand-FWZCB7AM.js} +11 -10
  238. package/{usageRebuildCommand-HAW2AD5N.js → usageRebuildCommand-SP2BLNJU.js} +12 -11
  239. package/userDataMerge-HT2ZVHBJ.js +13 -0
  240. package/{windowsSelfUpdate-XSQVF2GK.js → windowsSelfUpdate-KERHIAB4.js} +3 -3
  241. package/{workloadLifecycle-4BEQHMSD.js → workloadLifecycle-DYNEYHV5.js} +7 -6
  242. package/agentRecordCommands-L3QQ7HZ4.js +0 -167
  243. package/agentRunCommand-2IFGQHCO.js +0 -196
  244. package/chunk-3CGG2PAL.js +0 -594
  245. package/chunk-5XBUWM6I.js +0 -89
  246. package/chunk-BFM34N54.js +0 -842
  247. package/chunk-CJEIOP3E.js +0 -0
  248. package/chunk-CZM5YTZ7.js +0 -977
  249. package/chunk-EYUBHHFB.js +0 -636
  250. package/chunk-JTDORD5P.js +0 -415
  251. package/chunk-NRFKLKRU.js +0 -339
  252. package/chunk-VPAZOH2D.js +0 -115
  253. package/chunk-WJZOQR2J.js +0 -151
  254. package/chunk-ZCWRMUWT.js +0 -89
  255. package/dist-M676ULYG.js +0 -7314
  256. package/machineWsRunDispatch-R26P5V36.js +0 -182
  257. package/models-PJBE6JDV.js +0 -9
  258. package/tuiSummaryLlmCaller-WC54MVGP.js +0 -160
  259. package/{chunk-WACI5I6V.js → chunk-2THCNKE4.js} +3 -3
  260. package/{chunk-2QHFH3DR.js → chunk-47ITIXO7.js} +6 -6
  261. package/{chunk-GOO6G4PY.js → chunk-CKG3PRZ7.js} +0 -0
  262. package/{chunk-OQHIVPG4.js → chunk-SNBZZPYH.js} +3 -3
  263. package/{chunk-AETZ7AD6.js → chunk-W6RFEDN4.js} +3 -3
@@ -1,21 +1,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-NRFKLKRU.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,59 +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";
36
- 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-D5RCRX4A.js";
84
+ rankMemoryCandidates,
85
+ recallMemoryVNextLocal
86
+ } from "./chunk-YL3EFYL3.js";
53
87
  import {
54
- clearCredentialAvailability,
55
- readEffectiveCredentialEntry,
56
- recordCredentialProbe
57
- } from "./chunk-GSQNH63I.js";
88
+ DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET,
89
+ EXPLICIT_REMEMBER_PREFIX_REGEX,
90
+ buildMemoryOverlay
91
+ } from "./chunk-EUCFKKDM.js";
58
92
  import {
59
- readDbRecord,
60
- resolveAgentRecordFromHybridStore
61
- } from "./chunk-IF45XG7K.js";
93
+ buildLegacyMemoryEvidence,
94
+ resolveLegacyMemoryPrincipal
95
+ } from "./chunk-QHEN7NZ7.js";
62
96
  import {
63
97
  isBuiltinNoloAgentRef,
64
98
  resolveLocalUserId
65
- } from "./chunk-G7MLNNEX.js";
66
- import {
67
- isLocalCliAgentKey
68
- } from "./chunk-NBTY7YJF.js";
99
+ } from "./chunk-7JLY4WYF.js";
69
100
  import {
70
101
  CliProviderQuotaError
71
- } 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";
72
109
  import {
73
110
  resolveCliLocalRuntimeKeyCapability
74
- } from "./chunk-CQ46IRNN.js";
111
+ } from "./chunk-B4GOW4MT.js";
75
112
  import {
76
113
  isTransientFetchError
77
114
  } from "./chunk-KFHREHUQ.js";
78
- import {
79
- extractGoogleValidationLink
80
- } from "./chunk-BMQ2MJUK.js";
81
115
  import {
82
116
  parseUiCard,
83
117
  uiCardFallback
84
- } from "./chunk-GNDJKC4B.js";
118
+ } from "./chunk-ON37YXGX.js";
85
119
  import {
86
120
  isGatewayHttpStatus
87
121
  } from "./chunk-NF64D32W.js";
@@ -90,15 +124,17 @@ import {
90
124
  chooseMemoryOwners,
91
125
  loadMemoryCandidatesFromDb,
92
126
  resolveAgentMemoryPolicy
93
- } from "./chunk-OOF4UPC5.js";
127
+ } from "./chunk-XWVCYUUU.js";
94
128
  import {
95
129
  API_REPORTED_COST_MULTIPLIER,
96
130
  estimateMessagesTokens,
131
+ isAgentRunStartFailureStatus,
132
+ isAgentRunStatusNormal,
97
133
  parseUiAskChoiceContent,
98
134
  resolveAgentContextWindow,
99
135
  resolveOccupancy,
100
136
  resolveOccupancyWindow
101
- } from "./chunk-VZKUKCA6.js";
137
+ } from "./chunk-MZLE5HQ3.js";
102
138
  import {
103
139
  isCliAuthorityBrokerProtocolError,
104
140
  isCliAuthorityBrokerTimeoutError,
@@ -106,48 +142,43 @@ import {
106
142
  } from "./chunk-5ZMIIR23.js";
107
143
  import {
108
144
  getDefaultCliLocalRuntimeDb
109
- } from "./chunk-AZMYUSVF.js";
145
+ } from "./chunk-N5Z2V73W.js";
110
146
  import {
111
- buildSkillDiscoveryContextLayer
112
- } from "./chunk-F6UUQOG6.js";
113
- import {
114
- parseExternalSkillMarkdown,
115
- parseSkillDocProtocol
116
- } from "./chunk-AETZ7AD6.js";
147
+ isLocalCliAgentKey
148
+ } from "./chunk-BR3GT6MR.js";
117
149
  import {
118
150
  LOCAL_AGENT_CONFIG_MISSING_CODE,
119
151
  LOCAL_TURN_ABORTED_CODE,
152
+ evaluateTaskExecutionContract,
153
+ markCliUserBatchPhase,
120
154
  readActionGate
121
- } from "./chunk-FHU44LN3.js";
155
+ } from "./chunk-Z2PITYZN.js";
122
156
  import {
123
157
  resolveAgentRuntimeConfigFromRecord
124
- } from "./chunk-W4S457LU.js";
158
+ } from "./chunk-YU4ZPWVF.js";
125
159
  import {
126
160
  createThinkParserState,
127
161
  flushThinkParser,
128
162
  processThinkChunk
129
163
  } from "./chunk-56GBUMO5.js";
130
164
  import {
131
- PROBE_INTERVAL_MS,
132
- QUOTA_ERROR_PATTERNS,
133
165
  classifyFailureSubclass,
134
166
  isCapacitySaturatedRateLimit,
135
- isQuotaExhaustedError,
136
167
  isQuotaExhaustedText,
137
- mergeAvailabilityDeadline,
138
- resolveCooldownGate,
168
+ resolveAvailabilityAction,
139
169
  resolveCredentialKeyWithFallback
140
- } from "./chunk-YUXQAVRD.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-JTDORD5P.js";
181
+ } from "./chunk-RDH5CQ4T.js";
151
182
  import {
152
183
  isOAuthApiKeyRef
153
184
  } from "./chunk-UKZX3NHN.js";
@@ -157,37 +188,65 @@ import {
157
188
  import {
158
189
  normalizeRuntimeToolPolicyOverride,
159
190
  resolveEffectiveRuntimeToolPolicy
160
- } from "./chunk-2QHFH3DR.js";
191
+ } from "./chunk-47ITIXO7.js";
161
192
  import {
162
193
  compactWhitespace
163
194
  } from "./chunk-DWLEOOGR.js";
164
195
  import {
165
- buildAgentsMdLayer,
166
- buildAgentsMdLayerHeader,
167
- buildMemoryOverlayLayer,
168
- buildMemoryUseGuidanceLayer,
169
- partitionScopedBlocks,
170
- renderTurnContextBlocksWithScope
171
- } from "./chunk-ZRSNONOB.js";
196
+ isAntigravityOAuthAgent
197
+ } from "./chunk-SY3C4SQ7.js";
198
+ import {
199
+ parseExternalSkillMarkdown,
200
+ parseSkillDocProtocol
201
+ } from "./chunk-W6RFEDN4.js";
172
202
  import {
173
203
  BUILTIN_NOLO_AGENT_KEY,
174
204
  BUILTIN_NOLO_AGENT_NAME,
175
205
  builtinAgentCatalogEntryById,
176
206
  parseBuiltinPlatformAgentId
177
- } from "./chunk-LOEO7LRC.js";
207
+ } from "./chunk-3IK6ILVW.js";
178
208
  import {
179
209
  parsePublicAgentId
180
210
  } from "./chunk-M2EJHDJP.js";
181
211
  import {
182
- isAntigravityOAuthAgent
183
- } from "./chunk-KIM6CLW5.js";
212
+ createMemoryKey
213
+ } from "./chunk-SYTHYBMI.js";
184
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";
233
+ import {
234
+ agentRunCardLabels,
235
+ getCliLocale,
236
+ t,
237
+ toolLabel,
238
+ toolLabelVariants
239
+ } from "./chunk-OB6DVWPF.js";
240
+ import {
241
+ awaitLocalWriterChild,
185
242
  createRunActivityTracker,
186
243
  createShellApprovalChild,
187
244
  getRunResultHeaderMeta,
245
+ isHistoryIntegrityFailure,
188
246
  popSingleQueueMessage,
189
247
  readRunRecord,
190
248
  recordRunResultHeaderMeta,
249
+ registerLocalForegroundWriter,
191
250
  reportRunProcessIdentity,
192
251
  resolveResultServerMeta,
193
252
  resolveRunQueuePath,
@@ -195,65 +254,52 @@ import {
195
254
  serverOriginForDialog,
196
255
  settleRunTerminalAuthoritatively,
197
256
  spawnLocalBackgroundRun
198
- } from "./chunk-HIRC32DV.js";
257
+ } from "./chunk-2GJKRKI6.js";
199
258
  import {
200
259
  formatAgentListCard,
201
260
  formatFinishedRunCard,
261
+ formatIdentityRow,
202
262
  formatListRunsCard,
203
263
  formatNotFoundRunCard,
204
- formatStartRunCard,
205
264
  formatStatusRunCard,
206
265
  formatStopRunCard,
266
+ getAgentRunStatusIcon,
207
267
  isAgentRunTerminalStatus
208
- } from "./chunk-PJNFNEJE.js";
268
+ } from "./chunk-AMEOV5VZ.js";
209
269
  import {
210
- resolveClientVersion
211
- } from "./chunk-TCZHTTUU.js";
270
+ QUOTA_ERROR_PATTERNS,
271
+ isQuotaExhaustedError
272
+ } from "./chunk-EWQ3HGNZ.js";
212
273
  import {
213
- findModelConfig
214
- } from "./chunk-SM3NSZJV.js";
274
+ resolveClientVersion
275
+ } from "./chunk-I7WBYGBP.js";
215
276
  import {
216
277
  toErrorMessage
217
278
  } from "./chunk-HNMXYYJR.js";
279
+ import {
280
+ asTrimmedString
281
+ } from "./chunk-3EUW3WEO.js";
282
+ import {
283
+ findModelConfig
284
+ } from "./chunk-2UCBGYO4.js";
218
285
  import {
219
286
  CLIENT_VERSION_TOO_OLD_CODE,
220
287
  NOLO_CLIENT_VERSION_HEADER,
221
288
  buildClientVersionUpgradeMessage
222
- } from "./chunk-GOO6G4PY.js";
289
+ } from "./chunk-CKG3PRZ7.js";
223
290
  import {
224
291
  asTrimmedLowercaseString
225
292
  } from "./chunk-QSJ3HFEF.js";
226
- import {
227
- getLogger,
228
- normalizeError
229
- } from "./chunk-EYLGAEB4.js";
230
293
  import {
231
294
  resolveAuthToken
232
- } from "./chunk-WACI5I6V.js";
233
- import {
234
- readPipeText,
235
- spawnProcess
236
- } from "./chunk-4O22PGNQ.js";
237
- import {
238
- agentRunCardLabels,
239
- getCliLocale,
240
- t,
241
- toolLabel,
242
- toolLabelVariants
243
- } from "./chunk-3RQVYR4B.js";
244
- import {
245
- createMemoryKey
246
- } from "./chunk-JY5NGFFH.js";
247
- import {
248
- ulid
249
- } from "./chunk-XJWWBO34.js";
250
- import {
251
- asTrimmedString
252
- } from "./chunk-3EUW3WEO.js";
295
+ } from "./chunk-2THCNKE4.js";
253
296
  import {
254
297
  asOptionalTrimmedString
255
298
  } from "./chunk-G3SUCT4W.js";
256
299
 
300
+ // packages/cli/agentRunCommand.ts
301
+ import { createHash } from "node:crypto";
302
+
257
303
  // packages/cli/client/instaboxRunConfigWrite.ts
258
304
  import { randomUUID } from "node:crypto";
259
305
  import { lstatSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
@@ -396,6 +442,151 @@ function writeInstaboxRunConfig(options) {
396
442
  return { configPath: targetPath, config };
397
443
  }
398
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
+
399
590
  // packages/agent-runtime/modelLayerOverride.ts
400
591
  var MODEL_LAYER_KEYS = [
401
592
  "provider",
@@ -644,6 +835,8 @@ function parseUsageRecord(usage) {
644
835
  function resolveContextWindow(model) {
645
836
  const raw = model?.trim();
646
837
  if (!raw) return void 0;
838
+ const oauthPinned = findCodexOAuthPinnedContextWindow(raw);
839
+ if (oauthPinned !== void 0) return oauthPinned;
647
840
  for (const provider of PROVIDER_LOOKUP_ORDER) {
648
841
  const config = findModelConfig(provider, raw);
649
842
  if (config?.contextWindow) return config.contextWindow;
@@ -682,10 +875,10 @@ function platformCreditsFromUsage(usage) {
682
875
  const cost = typeof usage.cost === "number" ? usage.cost : 0;
683
876
  return Number.isFinite(cost) && cost > 0 ? cost : 0;
684
877
  }
685
- function withTurnCredits(tokens, credits) {
686
- if (!tokens) return tokens;
687
- if (credits === void 0) return tokens;
688
- return { ...tokens, credits };
878
+ function withTurnCredits(tokens2, credits) {
879
+ if (!tokens2) return tokens2;
880
+ if (credits === void 0) return tokens2;
881
+ return { ...tokens2, credits };
689
882
  }
690
883
  function formatCreditsChip(credits, options) {
691
884
  return options?.compact ? `\u26A1${credits.toFixed(2)}` : `\u26A1 ${credits.toFixed(2)} \u79EF\u5206`;
@@ -718,10 +911,18 @@ function computeBaselineContextTokens(options) {
718
911
  }
719
912
  return typeof fallbackEstimate === "function" ? fallbackEstimate() : fallbackEstimate;
720
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
+ }
721
922
  function resolveContextUsage(opts = {}) {
722
- const tokens = opts.tokens;
723
- const contextWindow = tokens?.contextWindow ?? opts.fallbackContextWindow;
724
- 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;
725
926
  const baselineEstimate = opts.estimatedContextTokens != null && opts.estimatedContextTokens > 0 ? opts.estimatedContextTokens : void 0;
726
927
  const generatedSinceAuthority = opts.turnEstimatedTokens != null && opts.turnEstimatedTokens > 0 ? opts.turnEstimatedTokens : void 0;
727
928
  const occupancy = resolveOccupancy({
@@ -740,27 +941,27 @@ function resolveContextUsage(opts = {}) {
740
941
  }
741
942
  return usage;
742
943
  }
743
- function renderTokenStatus(tokens, fallback) {
944
+ function renderTokenStatus(tokens2, fallback) {
744
945
  const usage = resolveContextUsage({
745
- tokens,
946
+ tokens: tokens2,
746
947
  fallbackContextWindow: fallback?.contextWindow,
747
948
  estimatedContextTokens: fallback?.estimatedContextTokens,
748
949
  turnEstimatedTokens: fallback?.turnEstimatedTokens
749
950
  });
750
- 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)})` : "";
751
952
  if (usage.contextWindow === void 0) {
752
953
  const inStr = usage.used !== void 0 ? `${usage.estimated ? "~" : ""}${formatTokenCount(usage.used)}` : "\u2014";
753
- const outStr = tokens ? formatTokenCount(tokens.output) : "\u2014";
954
+ const outStr = tokens2 ? formatTokenCount(tokens2.output) : "\u2014";
754
955
  return `in ${inStr}${cache} out ${outStr} left \u2014`;
755
956
  }
756
- if (!tokens) {
957
+ if (!tokens2) {
757
958
  if (usage.used === void 0) return "in \u2014 out \u2014 left \u2014";
758
959
  const left2 = usage.left !== void 0 ? `~${formatTokenCount(usage.left)}` : "\u2014";
759
960
  return `in ~${formatTokenCount(usage.used)} out \u2014 left ${left2}`;
760
961
  }
761
- const inputText = tokens.input > 0 || usage.used === void 0 ? formatTokenCount(tokens.input) : `~${formatTokenCount(usage.used)}`;
762
- const left = tokens.remaining != null ? formatTokenCount(tokens.remaining) : usage.left !== void 0 ? `${usage.estimated ? "~" : ""}${formatTokenCount(usage.left)}` : "\u2014";
763
- 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}`;
764
965
  }
765
966
  function shouldShowUsage(env) {
766
967
  return env.NOLO_DEBUG === "1" || env.NOLO_SHOW_USAGE === "1";
@@ -845,754 +1046,6 @@ function formatCliHyperlink(url, label, enabled = resolveCliHyperlinkEnabled())
845
1046
  return `${OSC8_OPEN}${url}${OSC8_CLOSE}${safeLabel}${OSC8_OPEN}${OSC8_CLOSE}`;
846
1047
  }
847
1048
 
848
- // node_modules/ansi-regex/index.js
849
- function ansiRegex({ onlyFirst = false } = {}) {
850
- const ST2 = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
851
- const osc = `(?:\\u001B\\][^\\u0007\\u001B\\u009C]*${ST2})`;
852
- const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
853
- const pattern = `${osc}|${csi}`;
854
- return new RegExp(pattern, onlyFirst ? void 0 : "g");
855
- }
856
-
857
- // node_modules/strip-ansi/index.js
858
- var regex = ansiRegex();
859
- function stripAnsi(string) {
860
- if (typeof string !== "string") {
861
- throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
862
- }
863
- if (!string.includes("\x1B") && !string.includes("\x9B")) {
864
- return string;
865
- }
866
- return string.replace(regex, "");
867
- }
868
-
869
- // node_modules/get-east-asian-width/lookup-data.js
870
- var ambiguousMinimalCodePoint = 161;
871
- var ambiguousMaximumCodePoint = 1114109;
872
- 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];
873
- var fullwidthMinimalCodePoint = 12288;
874
- var fullwidthMaximumCodePoint = 65510;
875
- var fullwidthRanges = [12288, 12288, 65281, 65376, 65504, 65510];
876
- var wideMinimalCodePoint = 4352;
877
- var wideMaximumCodePoint = 262141;
878
- 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];
879
-
880
- // node_modules/get-east-asian-width/utilities.js
881
- var isInRange = (ranges, codePoint) => {
882
- let low = 0;
883
- let high = Math.floor(ranges.length / 2) - 1;
884
- while (low <= high) {
885
- const mid = Math.floor((low + high) / 2);
886
- const i = mid * 2;
887
- if (codePoint < ranges[i]) {
888
- high = mid - 1;
889
- } else if (codePoint > ranges[i + 1]) {
890
- low = mid + 1;
891
- } else {
892
- return true;
893
- }
894
- }
895
- return false;
896
- };
897
-
898
- // node_modules/get-east-asian-width/lookup.js
899
- var commonCjkCodePoint = 19968;
900
- var [wideFastPathStart, wideFastPathEnd] = /* @__PURE__ */ findWideFastPathRange(wideRanges);
901
- function findWideFastPathRange(ranges) {
902
- let fastPathStart = ranges[0];
903
- let fastPathEnd = ranges[1];
904
- for (let index = 0; index < ranges.length; index += 2) {
905
- const start = ranges[index];
906
- const end = ranges[index + 1];
907
- if (commonCjkCodePoint >= start && commonCjkCodePoint <= end) {
908
- return [start, end];
909
- }
910
- if (end - start > fastPathEnd - fastPathStart) {
911
- fastPathStart = start;
912
- fastPathEnd = end;
913
- }
914
- }
915
- return [fastPathStart, fastPathEnd];
916
- }
917
- var isAmbiguous = (codePoint) => {
918
- if (codePoint < ambiguousMinimalCodePoint || codePoint > ambiguousMaximumCodePoint) {
919
- return false;
920
- }
921
- return isInRange(ambiguousRanges, codePoint);
922
- };
923
- var isFullwidth = (codePoint) => {
924
- if (codePoint < fullwidthMinimalCodePoint || codePoint > fullwidthMaximumCodePoint) {
925
- return false;
926
- }
927
- return isInRange(fullwidthRanges, codePoint);
928
- };
929
- var isWide = (codePoint) => {
930
- if (codePoint >= wideFastPathStart && codePoint <= wideFastPathEnd) {
931
- return true;
932
- }
933
- if (codePoint < wideMinimalCodePoint || codePoint > wideMaximumCodePoint) {
934
- return false;
935
- }
936
- return isInRange(wideRanges, codePoint);
937
- };
938
-
939
- // node_modules/get-east-asian-width/index.js
940
- function validate(codePoint) {
941
- if (!Number.isSafeInteger(codePoint)) {
942
- throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
943
- }
944
- }
945
- function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
946
- validate(codePoint);
947
- if (isFullwidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) {
948
- return 2;
949
- }
950
- return 1;
951
- }
952
-
953
- // node_modules/string-width/index.js
954
- var segmenter = new Intl.Segmenter();
955
- var zeroWidthClusterRegex = new RegExp("^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Format}|\\p{Nonspacing_Mark}|\\p{Enclosing_Mark}|\\p{Surrogate})+$", "v");
956
- var leadingNonPrintingRegex = new RegExp("^[\\p{Default_Ignorable_Code_Point}\\p{Control}\\p{Format}\\p{Nonspacing_Mark}\\p{Enclosing_Mark}\\p{Surrogate}]+", "v");
957
- var spacingMarkRegex = new RegExp("\\p{Spacing_Mark}", "v");
958
- var rgiEmojiRegex = new RegExp("^\\p{RGI_Emoji}$", "v");
959
- var unqualifiedKeycapRegex = /^[\d#*]\u20E3$/;
960
- var extendedPictographicRegex = new RegExp("\\p{Extended_Pictographic}", "gu");
961
- function isDoubleWidthNonRgiEmojiSequence(segment) {
962
- if (segment.length > 50) {
963
- return false;
964
- }
965
- if (unqualifiedKeycapRegex.test(segment)) {
966
- return true;
967
- }
968
- if (segment.includes("\u200D")) {
969
- const pictographics = segment.match(extendedPictographicRegex);
970
- return pictographics !== null && pictographics.length >= 2;
971
- }
972
- return false;
973
- }
974
- function baseVisible(segment) {
975
- return segment.replace(leadingNonPrintingRegex, "");
976
- }
977
- function isZeroWidthCluster(segment) {
978
- return zeroWidthClusterRegex.test(segment);
979
- }
980
- function isHangulLeadingJamo(codePoint) {
981
- return codePoint >= 4352 && codePoint <= 4447 || codePoint >= 43360 && codePoint <= 43388;
982
- }
983
- function isHangulVowelJamo(codePoint) {
984
- return codePoint >= 4448 && codePoint <= 4519 || codePoint >= 55216 && codePoint <= 55238;
985
- }
986
- function isHangulTrailingJamo(codePoint) {
987
- return codePoint >= 4520 && codePoint <= 4607 || codePoint >= 55243 && codePoint <= 55291;
988
- }
989
- function isHangulJamo(codePoint) {
990
- return isHangulLeadingJamo(codePoint) || isHangulVowelJamo(codePoint) || isHangulTrailingJamo(codePoint);
991
- }
992
- function hangulClusterWidth(visibleSegment, eastAsianWidthOptions) {
993
- const codePoints = [];
994
- for (const character of visibleSegment) {
995
- if (zeroWidthClusterRegex.test(character)) {
996
- continue;
997
- }
998
- codePoints.push(character.codePointAt(0));
999
- }
1000
- if (codePoints.length === 0) {
1001
- return void 0;
1002
- }
1003
- let width = 0;
1004
- for (let index = 0; index < codePoints.length; index++) {
1005
- const codePoint = codePoints[index];
1006
- if (!isHangulJamo(codePoint)) {
1007
- if (width === 0) {
1008
- return void 0;
1009
- }
1010
- for (let remaining = index; remaining < codePoints.length; remaining++) {
1011
- width += eastAsianWidth(codePoints[remaining], eastAsianWidthOptions);
1012
- }
1013
- return width;
1014
- }
1015
- if (isHangulLeadingJamo(codePoint) && isHangulVowelJamo(codePoints[index + 1])) {
1016
- width += 2;
1017
- index += isHangulTrailingJamo(codePoints[index + 2]) ? 2 : 1;
1018
- continue;
1019
- }
1020
- width += eastAsianWidth(codePoint, eastAsianWidthOptions);
1021
- }
1022
- return width;
1023
- }
1024
- function trailingWidth(visibleSegment, eastAsianWidthOptions) {
1025
- let extra = 0;
1026
- let first = true;
1027
- for (const character of visibleSegment) {
1028
- if (first) {
1029
- first = false;
1030
- continue;
1031
- }
1032
- if (spacingMarkRegex.test(character) || character >= "\uFF00" && character <= "\uFFEF") {
1033
- extra += eastAsianWidth(character.codePointAt(0), eastAsianWidthOptions);
1034
- }
1035
- }
1036
- return extra;
1037
- }
1038
- function stringWidth(input, options = {}) {
1039
- if (typeof input !== "string" || input.length === 0) {
1040
- return 0;
1041
- }
1042
- const {
1043
- ambiguousIsNarrow = true,
1044
- countAnsiEscapeCodes = false
1045
- } = options;
1046
- let string = input;
1047
- if (!countAnsiEscapeCodes && (string.includes("\x1B") || string.includes("\x9B"))) {
1048
- string = stripAnsi(string);
1049
- }
1050
- if (string.length === 0) {
1051
- return 0;
1052
- }
1053
- if (/^[\u0020-\u007E]*$/.test(string)) {
1054
- return string.length;
1055
- }
1056
- let width = 0;
1057
- const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
1058
- for (const { segment } of segmenter.segment(string)) {
1059
- if (isZeroWidthCluster(segment)) {
1060
- continue;
1061
- }
1062
- if (rgiEmojiRegex.test(segment) || isDoubleWidthNonRgiEmojiSequence(segment)) {
1063
- width += 2;
1064
- continue;
1065
- }
1066
- const visibleSegment = baseVisible(segment);
1067
- const hangulWidth = hangulClusterWidth(visibleSegment, eastAsianWidthOptions);
1068
- if (hangulWidth !== void 0) {
1069
- width += hangulWidth;
1070
- continue;
1071
- }
1072
- const codePoint = visibleSegment.codePointAt(0);
1073
- width += eastAsianWidth(codePoint, eastAsianWidthOptions);
1074
- width += trailingWidth(visibleSegment, eastAsianWidthOptions);
1075
- }
1076
- return width;
1077
- }
1078
-
1079
- // packages/cli/tui/tuiAnsi.ts
1080
- var ANSI_ESCAPE_REGEX = /\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]/g;
1081
- var OSC8_HYPERLINK_REGEX = /\x1b\]8;;[^\x1b]*\x1b\\/g;
1082
- var ALL_ANSI_ESCAPE_REGEX = ansiRegex();
1083
- var FIRST_ANSI_ESCAPE_REGEX = ansiRegex({ onlyFirst: true });
1084
- function stripOsc8Hyperlinks(text) {
1085
- return text.replace(OSC8_HYPERLINK_REGEX, "");
1086
- }
1087
- function stripAnsi2(text) {
1088
- return text.replace(ANSI_ESCAPE_REGEX, "").replace(ALL_ANSI_ESCAPE_REGEX, "");
1089
- }
1090
- var SGR_SEQUENCE_REGEX = /^\x1b\[[0-9;]*m/;
1091
- var TRAILING_SGR_REGEX = /(?:\x1b\[[0-9;]*m)+$/;
1092
- function applyTerminalOutputToText(existing, chunk) {
1093
- if (!chunk) return existing;
1094
- let text = existing;
1095
- let index = 0;
1096
- while (index < chunk.length) {
1097
- if (chunk[index] === "\x1B") {
1098
- const sgr = SGR_SEQUENCE_REGEX.exec(chunk.slice(index));
1099
- if (sgr) {
1100
- text += sgr[0];
1101
- index += sgr[0].length;
1102
- continue;
1103
- }
1104
- const osc = chunk.slice(index).match(/^\x1b\]8;;[^\x07\x1b]*(?:\x07|\x1b\\)/);
1105
- if (osc) {
1106
- index += osc[0].length;
1107
- continue;
1108
- }
1109
- const csi = chunk.slice(index).match(/^\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]/);
1110
- if (csi) {
1111
- index += csi[0].length;
1112
- continue;
1113
- }
1114
- index += 1;
1115
- continue;
1116
- }
1117
- const ch = chunk[index];
1118
- if (ch === "\r") {
1119
- const lastNl = text.lastIndexOf("\n");
1120
- text = lastNl === -1 ? "" : text.slice(0, lastNl + 1);
1121
- index += 1;
1122
- continue;
1123
- }
1124
- if (ch === "\n") {
1125
- text += "\n";
1126
- index += 1;
1127
- continue;
1128
- }
1129
- if (ch === "\b") {
1130
- const trailing = TRAILING_SGR_REGEX.exec(text);
1131
- const sgrTail = trailing ? trailing[0] : "";
1132
- const head = sgrTail ? text.slice(0, -sgrTail.length) : text;
1133
- if (head.length > 0 && head[head.length - 1] !== "\n") {
1134
- text = head.slice(0, -1) + sgrTail;
1135
- }
1136
- index += 1;
1137
- continue;
1138
- }
1139
- const code = ch.charCodeAt(0);
1140
- if (code < 32 && ch !== " " || code === 127) {
1141
- index += 1;
1142
- continue;
1143
- }
1144
- text += ch;
1145
- index += 1;
1146
- }
1147
- return text;
1148
- }
1149
- function resolveAmbiguousWidth(explicit, env = process.env) {
1150
- if (explicit === "wide" || explicit === "narrow") return explicit;
1151
- const raw = env.NOLO_TUI_AMBIGUOUS_WIDTH;
1152
- if (typeof raw === "string") {
1153
- const trimmed = raw.trim().toLowerCase();
1154
- if (trimmed === "wide") return "wide";
1155
- if (trimmed === "narrow") return "narrow";
1156
- }
1157
- return "narrow";
1158
- }
1159
- function isAmbiguousWideSymbolCode(code) {
1160
- return code >= 8592 && code <= 8597 || // ←↑→↓↔↕
1161
- code === 8656 || code === 8658 || code === 8660 || // ⇐⇒⇔
1162
- code === 215 || code === 247 || code === 177 || // ×÷±
1163
- code === 8226 || code === 183 || // • ·
1164
- code === 176 || code === 8451 || // ° ℃
1165
- code >= 8208 && code <= 8213 || // ‐‑‒–—―
1166
- code >= 9312 && code <= 9471 || // ①②④⑤ 圈数字/括号序号
1167
- code === 8986 || code === 8987 || // ⌚ ⌛
1168
- code >= 9193 && code <= 9210;
1169
- }
1170
- function isForceWideSymbolCode(code) {
1171
- return code >= 9728 && code <= 10175 && !(code >= 10088 && code <= 10101) || code >= 11008 && code <= 11263 || code >= 127744 && code <= 129791 || isAmbiguousWideSymbolCode(code);
1172
- }
1173
- function isCjkQuoteCode(code) {
1174
- return code === 8220 || code === 8221 || code === 8216 || code === 8217;
1175
- }
1176
- function scanWidthNeeds(plain, locale, ambiguousWidth) {
1177
- let hasNonAscii = false;
1178
- const isWideMode = ambiguousWidth === "wide";
1179
- for (let i = 0; i < plain.length; i++) {
1180
- const cc = plain.charCodeAt(i);
1181
- if (isWideMode && isAmbiguousWideSymbolCode(cc)) {
1182
- return { hasNonAscii: true, hasCandidate: true };
1183
- }
1184
- if (cc < 8192) {
1185
- if (cc >= 128) hasNonAscii = true;
1186
- continue;
1187
- }
1188
- hasNonAscii = true;
1189
- let code = cc;
1190
- if (cc >= 55296 && cc <= 56319 && i + 1 < plain.length) {
1191
- const lo = plain.charCodeAt(i + 1);
1192
- if (lo >= 56320 && lo <= 57343) {
1193
- code = (cc - 55296) * 1024 + (lo - 56320) + 65536;
1194
- i += 1;
1195
- }
1196
- }
1197
- const isSymbolCandidate = isWideMode && isForceWideSymbolCode(code);
1198
- const isQuoteCandidate = locale === "zh" && isCjkQuoteCode(code);
1199
- if (isSymbolCandidate || isQuoteCandidate) {
1200
- return { hasNonAscii: true, hasCandidate: true };
1201
- }
1202
- }
1203
- return { hasNonAscii, hasCandidate: false };
1204
- }
1205
- var displayWidthCache = /* @__PURE__ */ new Map();
1206
- var DISPLAY_WIDTH_CACHE_MAX = 4096;
1207
- function displayWidth(str, ambiguousWidth = resolveAmbiguousWidth()) {
1208
- const plain = stripAnsi2(str);
1209
- const locale = getCliLocale();
1210
- const needs = scanWidthNeeds(plain, locale, ambiguousWidth);
1211
- if (!needs.hasNonAscii) {
1212
- return stringWidth(plain);
1213
- }
1214
- const key = locale + "\0" + ambiguousWidth + "\0" + plain;
1215
- const cached = displayWidthCache.get(key);
1216
- if (cached !== void 0) return cached;
1217
- const base = stringWidth(plain);
1218
- if (!needs.hasCandidate) {
1219
- if (displayWidthCache.size >= DISPLAY_WIDTH_CACHE_MAX) {
1220
- const eldest = displayWidthCache.keys().next().value;
1221
- if (eldest !== void 0) displayWidthCache.delete(eldest);
1222
- }
1223
- displayWidthCache.set(key, base);
1224
- return base;
1225
- }
1226
- let width = base;
1227
- const isWideMode = ambiguousWidth === "wide";
1228
- for (const { segment } of graphemeSegmenter.segment(plain)) {
1229
- const code = segment.codePointAt(0) ?? 0;
1230
- const isSymbol = isWideMode && isForceWideSymbolCode(code);
1231
- const isQuote = locale === "zh" && isCjkQuoteCode(code);
1232
- if (isSymbol || isQuote) {
1233
- if (stringWidth(segment) === 1) width += 1;
1234
- }
1235
- }
1236
- if (displayWidthCache.size >= DISPLAY_WIDTH_CACHE_MAX) {
1237
- const eldest = displayWidthCache.keys().next().value;
1238
- if (eldest !== void 0) displayWidthCache.delete(eldest);
1239
- }
1240
- displayWidthCache.set(key, width);
1241
- return width;
1242
- }
1243
- function visibleWidth(str) {
1244
- return displayWidth(stripAnsi2(str));
1245
- }
1246
- function truncateAnsi(text, maxWidth) {
1247
- if (maxWidth <= 0) return "";
1248
- text = stripOsc8Hyperlinks(text);
1249
- if (visibleWidth(text) <= maxWidth) return text;
1250
- let width = 0;
1251
- let out = "";
1252
- let i = 0;
1253
- let sawAnsi = false;
1254
- while (i < text.length) {
1255
- if (text[i] === "\x1B" && text[i + 1] === "[") {
1256
- sawAnsi = true;
1257
- let j = i + 2;
1258
- while (j < text.length) {
1259
- const code = text.charCodeAt(j);
1260
- j += 1;
1261
- if (code >= 64 && code <= 126) break;
1262
- }
1263
- out += text.slice(i, j);
1264
- i = j;
1265
- continue;
1266
- }
1267
- const codePoint = text.codePointAt(i) ?? 0;
1268
- const char = String.fromCodePoint(codePoint);
1269
- const charWidth = displayWidth(char);
1270
- if (width + charWidth > maxWidth) break;
1271
- out += char;
1272
- width += charWidth;
1273
- i += char.length;
1274
- }
1275
- return sawAnsi ? `${out}\x1B[0m` : out;
1276
- }
1277
- function fitAnsiLine(text, width, ellipsis = "\u2026") {
1278
- if (width <= 0) return "";
1279
- if (visibleWidth(text) <= width) return text;
1280
- const ellipsisWidth = displayWidth(ellipsis);
1281
- if (width < ellipsisWidth) return truncateAnsi(text, width);
1282
- if (width === ellipsisWidth) return truncateAnsi(ellipsis, width) || truncateAnsi(text, width);
1283
- return `${truncateAnsi(text, width - ellipsisWidth)}${ellipsis}`;
1284
- }
1285
- function countPhysicalLines(text, columns) {
1286
- const lines = text.split("\n");
1287
- let total = 0;
1288
- for (const line of lines) {
1289
- const width = visibleWidth(stripOsc8Hyperlinks(line));
1290
- total += Math.max(1, Math.ceil(width / columns));
1291
- }
1292
- return Math.max(total, 1);
1293
- }
1294
- function takeDisplayWidth(text, width) {
1295
- let used = 0;
1296
- let index = 0;
1297
- for (const char of text) {
1298
- const charWidth = displayWidth(char);
1299
- if (used + charWidth > width && used > 0) break;
1300
- used += charWidth;
1301
- index += char.length;
1302
- }
1303
- return { prefix: text.slice(0, index), rest: text.slice(index) };
1304
- }
1305
- function padOrTruncateToWidth(text, width) {
1306
- const textWidth = visibleWidth(text);
1307
- if (textWidth > width) {
1308
- return truncateAnsi(text, width);
1309
- }
1310
- return `${text}${" ".repeat(width - textWidth)}`;
1311
- }
1312
- var SGR_RESET_REGEX = /^\x1b\[0?m$/;
1313
- var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
1314
- function tokenizeAnsiLine(line) {
1315
- const tokens = [];
1316
- let index = 0;
1317
- while (index < line.length) {
1318
- if (line[index] === "\x1B") {
1319
- const osc = line.slice(index).match(/^\x1b\]8;;[^\x07\x1b]*(?:\x07|\x1b\\)/);
1320
- if (osc) {
1321
- tokens.push({ kind: "sgr", value: osc[0], width: 0, charIndex: index });
1322
- index += osc[0].length;
1323
- continue;
1324
- }
1325
- const sgr = SGR_SEQUENCE_REGEX.exec(line.slice(index));
1326
- if (sgr) {
1327
- tokens.push({ kind: "sgr", value: sgr[0], width: 0, charIndex: index });
1328
- index += sgr[0].length;
1329
- continue;
1330
- }
1331
- const csi = line.slice(index).match(/^\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]/);
1332
- if (csi) {
1333
- index += csi[0].length;
1334
- continue;
1335
- }
1336
- const escape = FIRST_ANSI_ESCAPE_REGEX.exec(line.slice(index));
1337
- if (escape?.index === 0) {
1338
- index += escape[0].length;
1339
- continue;
1340
- }
1341
- index += 1;
1342
- continue;
1343
- }
1344
- let nextEsc = line.indexOf("\x1B", index);
1345
- if (nextEsc === -1) nextEsc = line.length;
1346
- const chunk = line.slice(index, nextEsc);
1347
- for (const item of graphemeSegmenter.segment(chunk)) {
1348
- tokens.push({
1349
- kind: "char",
1350
- value: item.segment,
1351
- width: displayWidth(item.segment),
1352
- charIndex: index + item.index
1353
- });
1354
- }
1355
- index = nextEsc;
1356
- }
1357
- return tokens;
1358
- }
1359
- function buildSourceMapping(rawLine, styledLine, prefixCharCount) {
1360
- let contentStart = 0;
1361
- const headingMatch = rawLine.match(/^(#{1,3})\s+(.+)$/);
1362
- let lineToParse = rawLine;
1363
- if (headingMatch) {
1364
- contentStart = headingMatch[1].length + 1;
1365
- while (contentStart < rawLine.length && rawLine[contentStart] === " ") contentStart++;
1366
- lineToParse = rawLine.slice(contentStart);
1367
- }
1368
- const INLINE_RE = /(\[([^\]]+)\]\(([^)\s]+)\)|`([^`]+)`|\*\*(.+?)\*\*|(?<!\*)\*([^*]+?)\*(?!\*)|~~([^~]+?)~~)/g;
1369
- const mapping = [];
1370
- let lastIdx = 0;
1371
- let match;
1372
- while ((match = INLINE_RE.exec(lineToParse)) !== null) {
1373
- const plainBefore = lineToParse.slice(lastIdx, match.index);
1374
- for (let c = 0; c < plainBefore.length; c++) {
1375
- mapping.push(contentStart + lastIdx + c);
1376
- }
1377
- const fullMatch = match[0];
1378
- if (match[2] !== void 0 && match[3] !== void 0) {
1379
- const linkText = match[2];
1380
- const linkUrl = match[3];
1381
- const textOffset = contentStart + match.index + 1;
1382
- for (let c = 0; c < linkText.length; c++) {
1383
- mapping.push(textOffset + c);
1384
- }
1385
- const parenOffset = textOffset + linkText.length;
1386
- mapping.push(parenOffset);
1387
- mapping.push(parenOffset + 1);
1388
- const urlOffset = parenOffset + 2;
1389
- for (let c = 0; c < linkUrl.length; c++) {
1390
- mapping.push(urlOffset + c);
1391
- }
1392
- mapping.push(urlOffset + linkUrl.length);
1393
- } else if (match[4] !== void 0) {
1394
- const codeText = match[4];
1395
- const codeOffset = contentStart + match.index + 1;
1396
- for (let c = 0; c < codeText.length; c++) {
1397
- mapping.push(codeOffset + c);
1398
- }
1399
- } else if (match[5] !== void 0) {
1400
- const boldText = match[5];
1401
- const boldOffset = contentStart + match.index + 2;
1402
- for (let c = 0; c < boldText.length; c++) {
1403
- mapping.push(boldOffset + c);
1404
- }
1405
- } else if (match[6] !== void 0) {
1406
- const italicText = match[6];
1407
- const italicOffset = contentStart + match.index + 1;
1408
- for (let c = 0; c < italicText.length; c++) {
1409
- mapping.push(italicOffset + c);
1410
- }
1411
- } else if (match[7] !== void 0) {
1412
- const strikeText = match[7];
1413
- const strikeOffset = contentStart + match.index + 2;
1414
- for (let c = 0; c < strikeText.length; c++) {
1415
- mapping.push(strikeOffset + c);
1416
- }
1417
- }
1418
- lastIdx = match.index + fullMatch.length;
1419
- }
1420
- const plainRest = lineToParse.slice(lastIdx);
1421
- for (let c = 0; c < plainRest.length; c++) {
1422
- mapping.push(contentStart + lastIdx + c);
1423
- }
1424
- return mapping;
1425
- }
1426
- function wrapTranscriptLineWithLayout(line, columns, hangingIndent = "", lineSourceStart = 0, prefixWidth = 0, prefixCharCount = 0, sourceMapping, rawLineLength) {
1427
- if (line === "") {
1428
- const rawLen = rawLineLength ?? 0;
1429
- return [
1430
- {
1431
- rendered: "",
1432
- sourceStart: lineSourceStart,
1433
- sourceEnd: lineSourceStart + rawLen,
1434
- prefixWidth
1435
- }
1436
- ];
1437
- }
1438
- const tokens = tokenizeAnsiLine(line);
1439
- const rows = [];
1440
- let activeStyles = [];
1441
- const applyStyleToken = (value) => {
1442
- if (SGR_RESET_REGEX.test(value)) {
1443
- activeStyles = [];
1444
- } else {
1445
- activeStyles.push(value);
1446
- }
1447
- };
1448
- let lastContentTokenIndex = -1;
1449
- for (let i = tokens.length - 1; i >= 0; i -= 1) {
1450
- if (tokens[i].kind !== "sgr") {
1451
- lastContentTokenIndex = i;
1452
- break;
1453
- }
1454
- }
1455
- let plainCharIndexAtStart = 0;
1456
- let start = 0;
1457
- while (start < tokens.length) {
1458
- if (start > lastContentTokenIndex && rows.length > 0) break;
1459
- const openingStyles = [...activeStyles];
1460
- const isContinuation = rows.length > 0;
1461
- const currentPrefixWidth = isContinuation ? visibleWidth(hangingIndent) : prefixWidth;
1462
- const indentWidth = isContinuation ? visibleWidth(hangingIndent) : 0;
1463
- const maxSegmentWidth = Math.max(1, columns - indentWidth);
1464
- let width = 0;
1465
- let end = start;
1466
- let lastBreak2 = -1;
1467
- while (end < tokens.length) {
1468
- const token = tokens[end];
1469
- if (token.kind === "sgr") {
1470
- end += 1;
1471
- continue;
1472
- }
1473
- if (width + token.width > maxSegmentWidth && width > 0) break;
1474
- width += token.width;
1475
- end += 1;
1476
- if ((token.value === " " || token.value === " ") && token.charIndex >= prefixCharCount) {
1477
- lastBreak2 = end;
1478
- }
1479
- }
1480
- let segmentEnd = end;
1481
- if (end < tokens.length && lastBreak2 > start) {
1482
- const overflowToken = tokens[end];
1483
- if (overflowToken.kind === "char" && overflowToken.value !== " " && overflowToken.width === 1) {
1484
- segmentEnd = lastBreak2;
1485
- }
1486
- }
1487
- if (segmentEnd === start) segmentEnd = start + 1;
1488
- let segment = "";
1489
- let sawStyle = openingStyles.length > 0;
1490
- for (let i = start; i < segmentEnd; i += 1) {
1491
- const token = tokens[i];
1492
- segment += token.value;
1493
- if (token.kind === "sgr") {
1494
- sawStyle = true;
1495
- applyStyleToken(token.value);
1496
- }
1497
- }
1498
- const prefix = openingStyles.join("");
1499
- const needsReset = (sawStyle || activeStyles.length > 0) && !segment.endsWith("\x1B[0m");
1500
- const lineContent = `${prefix}${segment}${needsReset ? "\x1B[0m" : ""}`;
1501
- const rowRendered = isContinuation && hangingIndent.length > 0 ? `${hangingIndent}${lineContent}` : lineContent;
1502
- let segSourceStart = lineSourceStart;
1503
- let segSourceEnd = lineSourceStart;
1504
- let foundFirst = false;
1505
- const rowMapping = [];
1506
- let plainCharIndex = plainCharIndexAtStart;
1507
- for (let i = start; i < segmentEnd; i++) {
1508
- const tok = tokens[i];
1509
- if (tok.kind === "char" && tok.charIndex >= prefixCharCount) {
1510
- const mappedOffset = sourceMapping && sourceMapping[plainCharIndex] !== void 0 ? sourceMapping[plainCharIndex] : plainCharIndex;
1511
- if (!foundFirst) {
1512
- segSourceStart = lineSourceStart + mappedOffset;
1513
- foundFirst = true;
1514
- }
1515
- for (let c = 0; c < tok.value.length; c++) {
1516
- const idx = plainCharIndex + c;
1517
- const mapped = sourceMapping && sourceMapping[idx] !== void 0 ? sourceMapping[idx] : idx;
1518
- rowMapping.push(lineSourceStart + mapped);
1519
- }
1520
- const lastCharIdx = plainCharIndex + tok.value.length - 1;
1521
- const mappedEndOffset = sourceMapping && sourceMapping[lastCharIdx] !== void 0 ? sourceMapping[lastCharIdx] + 1 : plainCharIndex + tok.value.length;
1522
- segSourceEnd = lineSourceStart + mappedEndOffset;
1523
- plainCharIndex += tok.value.length;
1524
- }
1525
- }
1526
- start = segmentEnd;
1527
- let softWrapJoiner = "";
1528
- while (start < tokens.length) {
1529
- const token = tokens[start];
1530
- if (token.kind === "char" && token.value === " " && token.charIndex >= prefixCharCount) {
1531
- softWrapJoiner += token.value;
1532
- const mappedOffset = sourceMapping && sourceMapping[plainCharIndex] !== void 0 ? sourceMapping[plainCharIndex] + 1 : plainCharIndex + 1;
1533
- segSourceEnd = lineSourceStart + mappedOffset;
1534
- plainCharIndex += token.value.length;
1535
- start += 1;
1536
- continue;
1537
- }
1538
- break;
1539
- }
1540
- if (start >= tokens.length && rawLineLength !== void 0) {
1541
- segSourceEnd = lineSourceStart + rawLineLength;
1542
- }
1543
- plainCharIndexAtStart = plainCharIndex;
1544
- rows.push({
1545
- rendered: rowRendered,
1546
- sourceStart: segSourceStart,
1547
- sourceEnd: segSourceEnd,
1548
- prefixWidth: currentPrefixWidth,
1549
- sourceMapping: rowMapping.length > 0 ? rowMapping : void 0,
1550
- softWrapped: start < tokens.length,
1551
- softWrapJoiner
1552
- });
1553
- }
1554
- return rows.length > 0 ? rows : [
1555
- {
1556
- rendered: "",
1557
- sourceStart: lineSourceStart,
1558
- sourceEnd: lineSourceStart + (rawLineLength ?? 0),
1559
- prefixWidth
1560
- }
1561
- ];
1562
- }
1563
- function wrapTranscriptLine(line, columns, hangingIndent = "") {
1564
- return wrapTranscriptLineWithLayout(line, columns, hangingIndent).map((r) => r.rendered);
1565
- }
1566
- function buildWindowTitle(title) {
1567
- const plain = stripAnsi2(title).replace(/[\x00-\x1f\x7f]+/g, " ");
1568
- let truncated = "";
1569
- let width = 0;
1570
- const maxCols = 80;
1571
- for (const char of plain) {
1572
- const charWidth = displayWidth(char);
1573
- if (width + charWidth > maxCols) break;
1574
- truncated += char;
1575
- width += charWidth;
1576
- }
1577
- return `\x1B]0;${truncated}\x07\x1B]2;${truncated}\x07`;
1578
- }
1579
- function wrapTextToLines(text, columns) {
1580
- const result = [];
1581
- for (const logicalLine of text.split("\n")) {
1582
- if (logicalLine === "") {
1583
- result.push("");
1584
- continue;
1585
- }
1586
- let remaining = logicalLine;
1587
- while (remaining.length > 0) {
1588
- const { prefix, rest } = takeDisplayWidth(remaining, columns);
1589
- result.push(prefix);
1590
- remaining = rest;
1591
- }
1592
- }
1593
- return result;
1594
- }
1595
-
1596
1049
  // packages/cli/tui/theme.ts
1597
1050
  var THEME_PALETTES = {
1598
1051
  trail: {
@@ -2991,7 +2444,7 @@ var WIDTHS = [
2991
2444
  ];
2992
2445
 
2993
2446
  // node_modules/lovely-mermaid/dist/width.js
2994
- var segmenter2 = new Intl.Segmenter("en", { granularity: "grapheme" });
2447
+ var segmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
2995
2448
  var VS16 = 65039;
2996
2449
  var isRegionalIndicator = (cp) => cp >= 127462 && cp <= 127487;
2997
2450
  function codePointWidth(cp) {
@@ -3026,12 +2479,12 @@ function clusterWidth(cluster) {
3026
2479
  return vs16 || regional >= 2 ? 2 : w;
3027
2480
  }
3028
2481
  function* measured(s) {
3029
- for (const { segment } of segmenter2.segment(s))
2482
+ for (const { segment } of segmenter.segment(s))
3030
2483
  yield [segment, clusterWidth(segment)];
3031
2484
  }
3032
- function stringWidth2(s) {
2485
+ function stringWidth(s) {
3033
2486
  let w = 0;
3034
- for (const { segment } of segmenter2.segment(s))
2487
+ for (const { segment } of segmenter.segment(s))
3035
2488
  w += clusterWidth(segment);
3036
2489
  return w;
3037
2490
  }
@@ -3228,7 +2681,7 @@ function wrapLabel(label, width, maxLines) {
3228
2681
  let cur = "";
3229
2682
  let curW = 0;
3230
2683
  for (const word of label.split(/\s+/).filter((w) => w !== "")) {
3231
- const ww = stringWidth2(word);
2684
+ const ww = stringWidth(word);
3232
2685
  if (ww > width) {
3233
2686
  if (cur !== "") {
3234
2687
  lines.push(cur);
@@ -3242,7 +2695,7 @@ function wrapLabel(label, width, maxLines) {
3242
2695
  const carry = p === -1 ? "" : chunk.slice(p + 1);
3243
2696
  lines.push(p === -1 ? chunk : chunk.slice(0, p + 1));
3244
2697
  chunk = carry;
3245
- chunkW = stringWidth2(carry);
2698
+ chunkW = stringWidth(carry);
3246
2699
  }
3247
2700
  chunk += ch;
3248
2701
  chunkW += cw;
@@ -3281,7 +2734,7 @@ function wrapLabel(label, width, maxLines) {
3281
2734
  return lines;
3282
2735
  }
3283
2736
  function fitLabel(label, inner) {
3284
- if (stringWidth2(label) <= inner)
2737
+ if (stringWidth(label) <= inner)
3285
2738
  return label;
3286
2739
  let out = "";
3287
2740
  let used = 0;
@@ -4073,7 +3526,7 @@ function placeTd(ranks, maxRank, byRank, sizes, graph, placed) {
4073
3526
  const edgeLabelLeft = new Array(graph.edges.length).fill(false);
4074
3527
  const labelW = (e) => {
4075
3528
  const parts = [e.label, e.cardTo].filter((p) => p != null);
4076
- 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)));
4077
3530
  };
4078
3531
  const skipsInto = graph.nodes.map(() => []);
4079
3532
  const fwdsInto = graph.nodes.map(() => []);
@@ -4241,21 +3694,21 @@ function placeTd(ranks, maxRank, byRank, sizes, graph, placed) {
4241
3694
  if (ranks[e.to] === ranks[e.from] + 1) {
4242
3695
  const parts = [e.label, e.cardTo].filter((part) => part != null);
4243
3696
  for (const part of parts) {
4244
- const lw = Math.min(stringWidth2(part), MAX_LABEL);
3697
+ const lw = Math.min(stringWidth(part), MAX_LABEL);
4245
3698
  contentW = Math.max(contentW, placed[e.to].cx + 2 + lw);
4246
3699
  }
4247
3700
  if (e.cardFrom !== void 0) {
4248
- 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));
4249
3702
  }
4250
3703
  } else if (isAdjacentBack(ranks, e)) {
4251
3704
  const text = edgeText(e);
4252
3705
  if (text !== null) {
4253
- 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));
4254
3707
  }
4255
3708
  } else {
4256
3709
  const text = edgeText(e);
4257
3710
  if (text !== null) {
4258
- 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);
4259
3712
  }
4260
3713
  }
4261
3714
  }
@@ -4309,8 +3762,8 @@ function placeLr(ranks, maxRank, byRank, sizes, graph, placed) {
4309
3762
  return;
4310
3763
  if (ranks[e.to] !== ranks[e.from] + 1 && !edgeStraight[i])
4311
3764
  return;
4312
- const verb = e.label === null ? 0 : Math.min(stringWidth2(e.label), MAX_LABEL);
4313
- 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);
4314
3767
  bandLabel[ranks[e.from]] = Math.max(bandLabel[ranks[e.from]], verb + cards);
4315
3768
  });
4316
3769
  const edgeBus = new Array(graph.edges.length).fill(0);
@@ -4421,10 +3874,10 @@ function layoutCanvas(graph, extras) {
4421
3874
  for (const row of byRank)
4422
3875
  row.sort((a, b) => Number(inLane[a]) - Number(inLane[b]));
4423
3876
  const wrapped = graph.nodes.map((node) => wrapLabel(node.label, WRAP_WIDTH, MAX_LINES));
4424
- 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)));
4425
3878
  const boxW = extras.map((extra, i) => {
4426
3879
  if (extra.kind === "frame") {
4427
- 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);
4428
3881
  }
4429
3882
  if (extra.kind === "compartments")
4430
3883
  return widest(extra.sections.flat()) + 2 * PAD + 2;
@@ -4447,7 +3900,7 @@ function layoutCanvas(graph, extras) {
4447
3900
  extraH[e.from] = 2;
4448
3901
  const text = edgeText(e);
4449
3902
  if (text !== null) {
4450
- 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));
4451
3904
  }
4452
3905
  }
4453
3906
  for (let i = 0; i < n; i++)
@@ -4713,7 +4166,7 @@ function drawBox(canvas, p, lines, shape, mirrored = false) {
4713
4166
  const ordered = mirrored ? [...lines].reverse() : lines;
4714
4167
  ordered.forEach((line, li) => {
4715
4168
  const text = fitLabel(line, inner);
4716
- const textX = x + 1 + PAD + half(sat(inner, stringWidth2(text)));
4169
+ const textX = x + 1 + PAD + half(sat(inner, stringWidth(text)));
4717
4170
  drawText(canvas, text, textX, y + 1 + li, "text");
4718
4171
  });
4719
4172
  }
@@ -4739,7 +4192,7 @@ function drawClassBox(canvas, p, sections, mirrored = false) {
4739
4192
  canvas.set(x, row, "\u2500", "border");
4740
4193
  canvas.set(p.x + p.w - 1, row, "\u2524", "border");
4741
4194
  } else {
4742
- 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;
4743
4196
  drawTextOverEdges(canvas, r.text, tx, row, "text");
4744
4197
  }
4745
4198
  });
@@ -4789,7 +4242,7 @@ function routeForward(canvas, from, to, edge, bus, entryX = -1, labelLeft = fals
4789
4242
  canvas.set(bx, by, headGlyph(edge.headFrom, "\u25B2"), "edge");
4790
4243
  if (edge.cardFrom === void 0 && edge.cardTo === void 0) {
4791
4244
  if (edge.label !== null) {
4792
- 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;
4793
4246
  placeLabel(canvas, edge.label, headRow, start);
4794
4247
  }
4795
4248
  return;
@@ -4805,7 +4258,7 @@ function routeForward(canvas, from, to, edge, bus, entryX = -1, labelLeft = fals
4805
4258
  const lineX = midRow > bus ? tx : bx;
4806
4259
  placeLabel(canvas, edge.label, midRow, lineX + 1);
4807
4260
  } else {
4808
- 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));
4809
4262
  }
4810
4263
  }
4811
4264
  }
@@ -4874,7 +4327,7 @@ function routeSkip(canvas, from, to, edge, at) {
4874
4327
  canvas.set(bx, bottom, headGlyph(edge.headFrom, "\u25B2"), "edge");
4875
4328
  const text = edgeText(edge);
4876
4329
  if (text !== null) {
4877
- 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;
4878
4331
  placeLabel(canvas, text, to.y - 1, start);
4879
4332
  }
4880
4333
  }
@@ -4895,7 +4348,7 @@ function routeBack(canvas, from, to, edge, laneX) {
4895
4348
  else
4896
4349
  canvas.set(tx + 1, tyc, headGlyph(edge.headTo, "\u25C4"), "edge");
4897
4350
  if (backText !== null) {
4898
- placeLabel(canvas, backText, sat(tyc, 1), sat(laneX, stringWidth2(backText) + 1));
4351
+ placeLabel(canvas, backText, sat(tyc, 1), sat(laneX, stringWidth(backText) + 1));
4899
4352
  }
4900
4353
  }
4901
4354
  function routeForwardLr(canvas, from, to, edge, bus) {
@@ -4922,7 +4375,7 @@ function routeForwardLr(canvas, from, to, edge, bus) {
4922
4375
  if (edge.cardFrom !== void 0)
4923
4376
  placeLabel(canvas, edge.cardFrom, sat(ry, 1), rx + 1);
4924
4377
  if (edge.cardTo !== void 0) {
4925
- 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)));
4926
4379
  }
4927
4380
  }
4928
4381
  function routeSkipLr(canvas, from, to, edge, bus) {
@@ -4972,7 +4425,7 @@ function routeBackLr(canvas, from, to, edge, laneY, laneLabels) {
4972
4425
  }
4973
4426
  function placeLaneLabels(canvas, labels) {
4974
4427
  for (const { text, y, lo, hi } of labels) {
4975
- const tw = stringWidth2(text);
4428
+ const tw = stringWidth(text);
4976
4429
  const lastStart = hi - 1 - tw;
4977
4430
  if (lastStart < lo + 1 || y >= canvas.h)
4978
4431
  continue;
@@ -5482,10 +4935,10 @@ function parseEr(src) {
5482
4935
  }
5483
4936
  const rel = splitErRelationship(st);
5484
4937
  if (rel) {
5485
- const tokens = erTokens(rel.rel);
5486
- const op = tokens.length === 3 ? parseErOp(tokens[1]) : null;
5487
- const f = op === null ? null : erEntity(graph, tokens[0]);
5488
- 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]);
5489
4942
  if (op === null || f === null || t2 === null) {
5490
4943
  graph.drop(st);
5491
4944
  } else {
@@ -6070,7 +5523,7 @@ var gitgraph = {
6070
5523
  parts.push([`\u21D0 ${branches[c.mergeFrom]}`, "edgeLabel"]);
6071
5524
  return parts;
6072
5525
  });
6073
- 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));
6074
5527
  const canvas = new Canvas(width, rows.length);
6075
5528
  const live = /* @__PURE__ */ new Set();
6076
5529
  rows.forEach((row, y) => {
@@ -6085,7 +5538,7 @@ var gitgraph = {
6085
5538
  let x = graphW;
6086
5539
  for (const [text, role] of labels[y] ?? []) {
6087
5540
  drawText(canvas, text, x, y, role);
6088
- x += stringWidth2(text) + 1;
5541
+ x += stringWidth(text) + 1;
6089
5542
  }
6090
5543
  return;
6091
5544
  }
@@ -6216,11 +5669,11 @@ var mindmap = {
6216
5669
  };
6217
5670
  for (const root of roots)
6218
5671
  walk(root, "", "");
6219
- 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)));
6220
5673
  const canvas = new Canvas(width, rows.length);
6221
5674
  rows.forEach(([prefix, text], y) => {
6222
5675
  drawText(canvas, prefix, 0, y, "edge");
6223
- drawText(canvas, text, stringWidth2(prefix), y, "text");
5676
+ drawText(canvas, text, stringWidth(prefix), y, "text");
6224
5677
  });
6225
5678
  return { canvas, warnings, classDefs: {} };
6226
5679
  }
@@ -6295,7 +5748,7 @@ var pie = {
6295
5748
  if (parsed === null)
6296
5749
  return null;
6297
5750
  const { title, slices, showData, warnings } = parsed;
6298
- const labelW = Math.max(...slices.map((s) => stringWidth2(s.label)));
5751
+ const labelW = Math.max(...slices.map((s) => stringWidth(s.label)));
6299
5752
  const total = slices.reduce((sum, s) => sum + s.value, 0);
6300
5753
  const rows = slices.map((s) => {
6301
5754
  const share = total === 0 ? 0 : s.value / total;
@@ -6305,11 +5758,11 @@ var pie = {
6305
5758
  });
6306
5759
  const barX = labelW + 2;
6307
5760
  const suffixX = barX + BAR_W + 1;
6308
- const width = suffixX + Math.max(...rows.map((r) => stringWidth2(r.suffix)));
5761
+ const width = suffixX + Math.max(...rows.map((r) => stringWidth(r.suffix)));
6309
5762
  const top = title === null ? 0 : 1;
6310
5763
  const canvas = new Canvas(width, top + rows.length);
6311
5764
  if (title !== null) {
6312
- 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");
6313
5766
  }
6314
5767
  rows.forEach((r, i) => {
6315
5768
  const y = top + i;
@@ -6319,7 +5772,7 @@ var pie = {
6319
5772
  if (bar === "" && r.value > 0)
6320
5773
  bar = "\u258F";
6321
5774
  drawText(canvas, bar, barX, y, "edge");
6322
- 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");
6323
5776
  drawText(canvas, r.suffix, suffixX, y, "edgeLabel");
6324
5777
  });
6325
5778
  return { canvas, warnings, classDefs: {} };
@@ -6383,11 +5836,11 @@ function noteGeometry(xs, anchor, textW) {
6383
5836
  return { x: sat(xs[anchor.at], 2 + w - 1), w };
6384
5837
  return { x: xs[anchor.at] + 2, w };
6385
5838
  }
6386
- var itemTextW = (text) => text === null ? 0 : stringWidth2(text);
5839
+ var itemTextW = (text) => text === null ? 0 : stringWidth(text);
6387
5840
  function layoutSequence(seq) {
6388
5841
  const n = seq.labels.length;
6389
5842
  const labels = seq.labels.map((l) => fitLabel(l, WRAP_WIDTH));
6390
- 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);
6391
5844
  const boxH = 3;
6392
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));
6393
5846
  const reqs = [];
@@ -6400,7 +5853,7 @@ function layoutSequence(seq) {
6400
5853
  reqs.push([item.from, item.from + 1, 5 + tw + 2]);
6401
5854
  }
6402
5855
  } else if (item.kind === "note") {
6403
- const tw = stringWidth2(item.text);
5856
+ const tw = stringWidth(item.text);
6404
5857
  const a = item.anchor;
6405
5858
  if (a.kind === "over" && a.from < a.to) {
6406
5859
  reqs.push([a.from, a.to, sat(tw, 1)]);
@@ -6432,7 +5885,7 @@ function layoutSequence(seq) {
6432
5885
  let leftPad = 0;
6433
5886
  for (const item of seq.items) {
6434
5887
  if (item.kind === "note" && item.anchor.kind === "left" && item.anchor.at === 0) {
6435
- const w = stringWidth2(item.text) + 2 * PAD + 2;
5888
+ const w = stringWidth(item.text) + 2 * PAD + 2;
6436
5889
  leftPad = Math.max(leftPad, sat(w + 1, xs[0]));
6437
5890
  }
6438
5891
  }
@@ -6444,10 +5897,10 @@ function layoutSequence(seq) {
6444
5897
  if (item.kind === "message" && item.from === item.to) {
6445
5898
  canvasW = Math.max(canvasW, xs[item.from] + 5 + itemTextW(item.text) + 1);
6446
5899
  } else if (item.kind === "note") {
6447
- const g = noteGeometry(xs, item.anchor, stringWidth2(item.text));
5900
+ const g = noteGeometry(xs, item.anchor, stringWidth(item.text));
6448
5901
  canvasW = Math.max(canvasW, g.x + g.w + 1);
6449
5902
  } else if (item.kind === "divider") {
6450
- canvasW = Math.max(canvasW, stringWidth2(item.text) + 4);
5903
+ canvasW = Math.max(canvasW, stringWidth(item.text) + 4);
6451
5904
  }
6452
5905
  }
6453
5906
  const rows = [];
@@ -6469,7 +5922,7 @@ function layoutSequence(seq) {
6469
5922
  seq.items.forEach((item, k) => {
6470
5923
  if (item.kind !== "note")
6471
5924
  return;
6472
- const g = noteGeometry(xs, item.anchor, stringWidth2(item.text));
5925
+ const g = noteGeometry(xs, item.anchor, stringWidth(item.text));
6473
5926
  drawBox(canvas, box(g.x, rows[k], g.w, 3), [item.text], "rect");
6474
5927
  });
6475
5928
  for (const x of xs) {
@@ -6552,7 +6005,7 @@ function drawMessage(canvas, item, xs, r) {
6552
6005
  if (item.text !== null) {
6553
6006
  const span = hi - lo - 1;
6554
6007
  const t2 = fitLabel(item.text, Math.max(1, span));
6555
- 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");
6556
6009
  }
6557
6010
  }
6558
6011
  function drawDivider(canvas, text, r, canvasW) {
@@ -7052,16 +6505,16 @@ var timeline = {
7052
6505
  if (parsed === null)
7053
6506
  return null;
7054
6507
  const { title, rows, warnings } = parsed;
7055
- 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)));
7056
6509
  const top = title === null ? 0 : 1;
7057
- 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)));
7058
6511
  const canvas = new Canvas(width, top + rows.length);
7059
6512
  if (title !== null) {
7060
6513
  const t2 = ` ${title} `;
7061
- 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));
7062
6515
  drawText(canvas, "\u2500\u2500", x, 0, "edge");
7063
6516
  drawText(canvas, t2, x + 2, 0, "title");
7064
- drawText(canvas, "\u2500\u2500", x + 2 + stringWidth2(t2), 0, "edge");
6517
+ drawText(canvas, "\u2500\u2500", x + 2 + stringWidth(t2), 0, "edge");
7065
6518
  }
7066
6519
  rows.forEach((row, i) => {
7067
6520
  const y = top + i;
@@ -7388,11 +6841,11 @@ function sourceBox(src, maxWidth) {
7388
6841
  acc.lines.push(...chunkLine(l, limit));
7389
6842
  return acc;
7390
6843
  }, { started: false, lines: [] }).lines;
7391
- 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));
7392
6845
  const inner = contentW + 2;
7393
6846
  const plain = [];
7394
6847
  const styled = [];
7395
- const rule = "\u2500".repeat(sat(inner, stringWidth2(title)));
6848
+ const rule = "\u2500".repeat(sat(inner, stringWidth(title)));
7396
6849
  plain.push(`\u256D${title}${rule}\u256E`);
7397
6850
  styled.push([
7398
6851
  { text: "\u256D", role: "border" },
@@ -7400,7 +6853,7 @@ function sourceBox(src, maxWidth) {
7400
6853
  { text: `${rule}\u256E`, role: "border" }
7401
6854
  ]);
7402
6855
  for (const line of body) {
7403
- const pad = " ".repeat(sat(contentW, stringWidth2(line)));
6856
+ const pad = " ".repeat(sat(contentW, stringWidth(line)));
7404
6857
  plain.push(`\u2502 ${line}${pad} \u2502`);
7405
6858
  styled.push([
7406
6859
  { text: "\u2502 ", role: "border" },
@@ -7431,7 +6884,7 @@ function expandTabs(line) {
7431
6884
  return out;
7432
6885
  }
7433
6886
  function chunkLine(line, limit) {
7434
- if (limit === void 0 || stringWidth2(line) <= limit)
6887
+ if (limit === void 0 || stringWidth(line) <= limit)
7435
6888
  return [line];
7436
6889
  const out = [];
7437
6890
  let cur = "";
@@ -7461,7 +6914,7 @@ function render(src) {
7461
6914
  const art = drawn.canvas.toLines();
7462
6915
  const title = frontmatterTitle(src);
7463
6916
  if (title !== null) {
7464
- const tw = stringWidth2(title);
6917
+ const tw = stringWidth(title);
7465
6918
  art.width = Math.max(art.width, tw);
7466
6919
  const pad = " ".repeat(Math.floor((art.width - tw) / 2));
7467
6920
  art.plain.unshift(pad + title, "");
@@ -7930,7 +7383,7 @@ function renderMathBlock(latex, options = {}) {
7930
7383
  const den = transpileLatexToUnicode(fracMatch[2] ?? "");
7931
7384
  if (num.length > 8 || den.length > 8 || num.includes("+") || den.includes("+") || num.includes("-") || den.includes("-")) {
7932
7385
  const width = Math.max(visibleWidth(num), visibleWidth(den)) + 2;
7933
- const bar = "\u2500".repeat(width);
7386
+ const bar = boxGlyphs(resolveBoxCharset()).h.repeat(width);
7934
7387
  const padNum = " ".repeat(Math.max(0, Math.floor((width - visibleWidth(num)) / 2)));
7935
7388
  const padDen = " ".repeat(Math.max(0, Math.floor((width - visibleWidth(den)) / 2)));
7936
7389
  const l1 = padNum + num;
@@ -8177,21 +7630,21 @@ function resolveTableWidth(explicit, env = process.env) {
8177
7630
  }
8178
7631
  function wrapCellToWidth(text, max) {
8179
7632
  if (max <= 0 || displayWidth(text) <= max) return [text];
8180
- const tokens = tokenizeAnsiLine(text);
7633
+ const tokens2 = tokenizeAnsiLine(text);
8181
7634
  const charTokenIdx = [];
8182
- tokens.forEach((t2, i) => {
7635
+ tokens2.forEach((t2, i) => {
8183
7636
  if (t2.kind === "char") charTokenIdx.push(i);
8184
7637
  });
8185
7638
  const n = charTokenIdx.length;
8186
7639
  if (n === 0) return [text];
8187
- const widths = charTokenIdx.map((i) => tokens[i].width);
7640
+ const widths = charTokenIdx.map((i) => tokens2[i].width);
8188
7641
  const prefix = [0];
8189
7642
  for (let i = 0; i < widths.length; i += 1) prefix.push(prefix[i] + widths[i]);
8190
7643
  const segWidth = (a, b) => prefix[b] - prefix[a];
8191
7644
  const sliceTokens = (a, b) => {
8192
7645
  const startTok = a === 0 ? 0 : charTokenIdx[a - 1] + 1;
8193
- const endTok = b < n ? charTokenIdx[b] - 1 : tokens.length - 1;
8194
- return tokens.slice(startTok, endTok + 1);
7646
+ const endTok = b < n ? charTokenIdx[b] - 1 : tokens2.length - 1;
7647
+ return tokens2.slice(startTok, endTok + 1);
8195
7648
  };
8196
7649
  const applyStyles = (slice, state2) => {
8197
7650
  const next = [...state2];
@@ -8206,7 +7659,7 @@ function wrapCellToWidth(text, max) {
8206
7659
  }
8207
7660
  } else if (OSC8_OPENER_REGEX.test(t2.value)) {
8208
7661
  next.push(t2.value);
8209
- } else if (SGR_RESET_REGEX2.test(t2.value)) {
7662
+ } else if (SGR_RESET_REGEX.test(t2.value)) {
8210
7663
  for (let i = next.length - 1; i >= 0; i -= 1) {
8211
7664
  if (!OSC8_OPENER_REGEX.test(next[i]) && !OSC8_CLOSER_REGEX.test(next[i])) {
8212
7665
  next.splice(i, 1);
@@ -8238,7 +7691,7 @@ function wrapCellToWidth(text, max) {
8238
7691
  if (segWidth(start, i + 1) <= max) continue;
8239
7692
  let cut = -1;
8240
7693
  for (let j = i - 1; j > start; j -= 1) {
8241
- if (tokens[charTokenIdx[j]].value !== " ") continue;
7694
+ if (tokens2[charTokenIdx[j]].value !== " ") continue;
8242
7695
  if (segWidth(start, j) <= max && segWidth(j + 1, i + 1) <= max) {
8243
7696
  cut = j;
8244
7697
  break;
@@ -8269,7 +7722,7 @@ function wrapCellToWidth(text, max) {
8269
7722
  }
8270
7723
  return segments.length > 0 ? segments : [text];
8271
7724
  }
8272
- var SGR_RESET_REGEX2 = /^\x1b\[0?m$/;
7725
+ var SGR_RESET_REGEX = /^\x1b\[0?m$/;
8273
7726
  var OSC8_OPENER_REGEX = /^\x1b\]8;;[^\x07\x1b]+(?:\x07|\x1b\\)$/;
8274
7727
  var OSC8_CLOSER_REGEX = /^\x1b\]8;;\x1b\\$/;
8275
7728
  function padCell(text, width, align) {
@@ -8324,21 +7777,22 @@ function makeStyle(brightness, headerToken) {
8324
7777
  const paint = (t2) => `${color}${boldOn}${t2}${reset}`;
8325
7778
  return { header: paint, label: paint };
8326
7779
  }
8327
- function boxLine(left, mid, right, widths) {
8328
- 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));
8329
7782
  return `${left}${seg.join(mid)}${right}`;
8330
7783
  }
8331
- function dataRow(cells, aligns, widths, style, header) {
7784
+ function dataRow(cells, aligns, widths, style, header, glyphs) {
8332
7785
  const parts = cells.map((cell, i) => {
8333
7786
  const width = widths[i] ?? 0;
8334
7787
  const align = aligns[i] ?? "left";
8335
7788
  const padded = padCell(cell, width, align);
8336
7789
  const styled = header ? style.header(padded) : padded;
8337
- return ` ${styled} \u2502`;
7790
+ return ` ${styled} ${glyphs.v}`;
8338
7791
  });
8339
- return `\u2502${parts.join("")}`;
7792
+ return `${glyphs.v}${parts.join("")}`;
8340
7793
  }
8341
- function renderBoxTable(table, width, style) {
7794
+ function renderBoxTable(table, width, style, charset = resolveBoxCharset()) {
7795
+ const glyphs = boxGlyphs(charset);
8342
7796
  const colCount = table.headers.length;
8343
7797
  const widths = computeColumnWidths(table.headers, table.rows, width);
8344
7798
  const headerGrid = table.headers.map(
@@ -8352,7 +7806,7 @@ function renderBoxTable(table, width, style) {
8352
7806
  (r) => Math.max(1, ...r.map((g) => g.length))
8353
7807
  );
8354
7808
  const lines = [];
8355
- lines.push(boxLine("\u250C", "\u252C", "\u2510", widths));
7809
+ lines.push(boxLine(glyphs, glyphs.tl, glyphs.tm, glyphs.tr, widths));
8356
7810
  for (let r = 0; r < headerDisplayRows; r += 1) {
8357
7811
  lines.push(
8358
7812
  dataRow(
@@ -8360,15 +7814,16 @@ function renderBoxTable(table, width, style) {
8360
7814
  table.aligns,
8361
7815
  widths,
8362
7816
  style,
8363
- true
7817
+ true,
7818
+ glyphs
8364
7819
  )
8365
7820
  );
8366
7821
  }
8367
- lines.push(boxLine("\u251C", "\u253C", "\u2524", widths));
7822
+ lines.push(boxLine(glyphs, glyphs.ml, glyphs.mm, glyphs.mr, widths));
8368
7823
  const hasMultiLineRecord = bodyDisplayRows.some((rows) => rows > 1);
8369
7824
  bodyGrids.forEach((_, rec) => {
8370
7825
  if (hasMultiLineRecord && rec > 0) {
8371
- lines.push(boxLine("\u251C", "\u253C", "\u2524", widths));
7826
+ lines.push(boxLine(glyphs, glyphs.ml, glyphs.mm, glyphs.mr, widths));
8372
7827
  }
8373
7828
  for (let r = 0; r < bodyDisplayRows[rec]; r += 1) {
8374
7829
  lines.push(
@@ -8380,12 +7835,13 @@ function renderBoxTable(table, width, style) {
8380
7835
  table.aligns,
8381
7836
  widths,
8382
7837
  style,
8383
- false
7838
+ false,
7839
+ glyphs
8384
7840
  )
8385
7841
  );
8386
7842
  }
8387
7843
  });
8388
- lines.push(boxLine("\u2514", "\u2534", "\u2518", widths));
7844
+ lines.push(boxLine(glyphs, glyphs.bl, glyphs.bm, glyphs.br, widths));
8389
7845
  return lines.join("\n");
8390
7846
  }
8391
7847
  function renderRecordCards(table, width, style) {
@@ -8429,7 +7885,12 @@ function renderMarkdownTable(table, options = {}) {
8429
7885
  if (width < 40 || table.headers.length > 6) {
8430
7886
  return renderRecordCards(styledTable, width, style);
8431
7887
  }
8432
- return renderBoxTable(styledTable, width, style);
7888
+ return renderBoxTable(
7889
+ styledTable,
7890
+ width,
7891
+ style,
7892
+ options.boxCharset ?? resolveBoxCharset()
7893
+ );
8433
7894
  }
8434
7895
 
8435
7896
  // packages/cli/client/assistantOutput.ts
@@ -8678,11 +8139,10 @@ function normalizeListLine(line) {
8678
8139
  }
8679
8140
  return line;
8680
8141
  }
8681
- var TOOL_TREE_HEADER_RE = /^•\s+(.+?)\s+\((\d+)\)$/;
8682
- var TOOL_TREE_LEAF_RE = /^([├└]──\s+)(.*?)\s{2}(✓|✗|!)(?:\s+(.*))?$/;
8142
+ var TOOL_TREE_HEADER_RE = /^•\s+(.+?)\s+\((\d+)\) · (.*?) ✓$/;
8683
8143
  var TOOL_SINGLE_RE = /^▸\s+(.+?)(?:\s+·\s+(.*?))?(?:\s{2}(✓|✗|!)(?:\s+(.*))?)$/;
8684
8144
  function plainToolLine(line) {
8685
- return stripAnsi2(line);
8145
+ return stripAnsi(line);
8686
8146
  }
8687
8147
  var TOOL_TREE_GROUP_LABELS = new Set(
8688
8148
  ["execShell", "readFile", "fetchWebpage", "exa_search"].flatMap(toolLabelVariants)
@@ -8697,9 +8157,6 @@ function toolTreeHeaderMatch(line) {
8697
8157
  function isToolTreeHeaderLine(line) {
8698
8158
  return toolTreeHeaderMatch(line) !== null;
8699
8159
  }
8700
- function isToolTreeLeafLine(line) {
8701
- return TOOL_TREE_LEAF_RE.test(plainToolLine(line));
8702
- }
8703
8160
  function isToolSingleLine(line) {
8704
8161
  return TOOL_SINGLE_RE.test(plainToolLine(line));
8705
8162
  }
@@ -8718,17 +8175,10 @@ function toolGroupKeyOf(line) {
8718
8175
  return null;
8719
8176
  }
8720
8177
  function toolRowBoundary(cur, next) {
8721
- const curLeaf = isToolTreeLeafLine(cur);
8722
- const curHeader = isToolTreeHeaderLine(cur);
8723
- const nextLeaf = isToolTreeLeafLine(next);
8724
8178
  const curKey = toolGroupKeyOf(cur);
8725
8179
  const nextKey = toolGroupKeyOf(next);
8726
- if (curKey === null && !curLeaf) return null;
8727
- if (nextKey === null && !nextLeaf) return null;
8728
- if (curLeaf) return !nextLeaf;
8729
- if (curHeader && nextLeaf) return false;
8730
- if (curKey !== null && nextKey !== null) return curKey !== nextKey;
8731
- return true;
8180
+ if (curKey === null || nextKey === null) return null;
8181
+ return isToolTreeHeaderLine(cur) || isToolTreeHeaderLine(next) || curKey !== nextKey;
8732
8182
  }
8733
8183
  function statusColorSeq(marker, brightness) {
8734
8184
  if (marker === "\u2713") return colorSeq("success", brightness);
@@ -8741,18 +8191,7 @@ function styleTuiToolLine(line, brightness) {
8741
8191
  const muted = colorSeq("muted", brightness);
8742
8192
  const header = toolTreeHeaderMatch(plain);
8743
8193
  if (header) {
8744
- return `${chrome}\u2022${STYLE.reset} ${STYLE.bold}${muted}${header[1]}${STYLE.reset} ${chrome}${STYLE.dim}(${header[2]})${STYLE.reset}`;
8745
- }
8746
- const leaf = plain.match(TOOL_TREE_LEAF_RE);
8747
- if (leaf) {
8748
- const [, connector, detail, marker, statusDetail] = leaf;
8749
- let rendered = `${chrome}${connector}${STYLE.reset}${chrome}${detail}${STYLE.reset}`;
8750
- rendered += ` ${statusColorSeq(marker, brightness)}${marker}${STYLE.reset}`;
8751
- if (statusDetail) {
8752
- const metaSeq = marker === "\u2713" ? chrome : statusColorSeq(marker, brightness);
8753
- rendered += ` ${metaSeq}${STYLE.dim}${statusDetail}${STYLE.reset}`;
8754
- }
8755
- 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}`;
8756
8195
  }
8757
8196
  const single = plain.match(TOOL_SINGLE_RE);
8758
8197
  if (single) {
@@ -8776,14 +8215,14 @@ function isPolishFenceInteriorLine(line) {
8776
8215
  return /^\x00F\d+\x00$/.test(line);
8777
8216
  }
8778
8217
  function polishHeadingLevel(line) {
8779
- const match = stripAnsi2(line).match(/^(#{1,6})\s/);
8218
+ const match = stripAnsi(line).match(/^(#{1,6})\s/);
8780
8219
  return match ? match[1].length : null;
8781
8220
  }
8782
8221
  function isPolishHeadingLine(line) {
8783
8222
  return polishHeadingLevel(line) !== null;
8784
8223
  }
8785
8224
  function isPolishIntroLine(line) {
8786
- const plain = stripAnsi2(line).trimEnd();
8225
+ const plain = stripAnsi(line).trimEnd();
8787
8226
  return plain.endsWith("\uFF1A") || plain.endsWith(":");
8788
8227
  }
8789
8228
  function polishBreathInsertsBlankBetween(cur, next) {
@@ -8911,7 +8350,7 @@ function styleRichMarkdownLine(line, brightness) {
8911
8350
  return `${border}\u2502${STYLE.reset} ${STYLE.dim}${styled}${STYLE.reset}`;
8912
8351
  }
8913
8352
  if (THEMATIC_BREAK_RE.test(line)) {
8914
- 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}`;
8915
8354
  }
8916
8355
  const bullet = line.match(/^(\s*)(•)\s(.+)$/);
8917
8356
  if (bullet) {
@@ -9085,7 +8524,6 @@ function classifyStreamLine(line) {
9085
8524
  if (line === "") return "blank";
9086
8525
  const plain = plainToolLine(line);
9087
8526
  if (isToolTreeHeaderLine(plain)) return "tool-header";
9088
- if (isToolTreeLeafLine(plain)) return "tool-leaf";
9089
8527
  if (isToolSingleLine(plain)) return "tool";
9090
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)) {
9091
8529
  return "list";
@@ -9095,10 +8533,10 @@ function classifyStreamLine(line) {
9095
8533
  return "prose";
9096
8534
  }
9097
8535
  function isStreamToolKind(kind) {
9098
- return kind === "tool-header" || kind === "tool-leaf" || kind === "tool";
8536
+ return kind === "tool-header" || kind === "tool";
9099
8537
  }
9100
8538
  function isStreamListLike(kind) {
9101
- return kind === "list" || kind === "tool-header" || kind === "tool-leaf" || kind === "tool";
8539
+ return kind === "list" || kind === "tool-header" || kind === "tool";
9102
8540
  }
9103
8541
  function needsListProseBreath(prev, next, prevLine = "", nextLine = "") {
9104
8542
  if (prev === null || prev === "blank" || next === "blank") return false;
@@ -9294,44 +8732,35 @@ function formatAssistantTextForCli(text) {
9294
8732
  return text.replace(/\u003cthink\u003e[\s\S]*?\u003c\/think\u003e\s*/gi, "").replace(/\n{3,}/g, "\n\n").trim();
9295
8733
  }
9296
8734
 
9297
- // packages/cli/tui/redactSecrets.ts
9298
- var REDACTED = "\u27E8redacted\u27E9";
9299
- function redactSecrets(text) {
9300
- 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(
9301
- /\b((?:api[_-]?key|apikey|access[_-]?token|auth[_-]?token|token|secret|password|passwd|credential)s?\s*[=:]\s*["']?)[^\s"',;]{8,}/gi,
9302
- `$1${REDACTED}`
9303
- ).replace(
9304
- /\b((?:--[a-z-]*(?:token|key|secret|password|credential)[a-z-]*)\s+)[^\s"']{8,}/gi,
9305
- `$1${REDACTED}`
9306
- );
9307
- }
9308
-
9309
- // packages/cli/tui/askTextSanitize.ts
9310
- var ASK_SECRET_PLACEHOLDER = "\u27E8redacted\u27E9";
9311
- var C0_C1_CONTROL_REGEX = /[\x00-\x1f\x7f-\x9f]/g;
9312
- var NORMAL_GIST_SECRET_PATTERNS = [
9313
- /\bbearer\s+[A-Za-z0-9._~+/=-]{8,}/i,
9314
- /\bsk-(?:ant-)?(?:api)?[0-9a-zA-Z-]{10,}/,
9315
- /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{10,}/,
9316
- /\bxox[baprs]-[A-Za-z0-9-]{10,}/
9317
- ];
9318
- function withholdIfSecretLike(gist) {
9319
- if (!gist) return "";
9320
- if (findPotentialSecrets(gist).length > 0) return "";
9321
- if (NORMAL_GIST_SECRET_PATTERNS.some((pattern) => pattern.test(gist))) return "";
9322
- return gist;
9323
- }
9324
- function toText(value) {
9325
- return typeof value === "string" ? value : String(value ?? "");
9326
- }
9327
- function cleanAskText(value) {
9328
- 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
+ };
9329
8758
  }
9330
- function safeAskText(value, max) {
9331
- const cleaned = redactSecrets(cleanAskText(value));
9332
- if (!cleaned) return "";
9333
- const guarded = withholdIfSecretLike(cleaned) || ASK_SECRET_PLACEHOLDER;
9334
- 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);
9335
8764
  }
9336
8765
 
9337
8766
  // node_modules/diff/libesm/diff/base.js
@@ -9675,14 +9104,11 @@ function clip(value, max = 72) {
9675
9104
  return clipCompactText(value, max, "\u2026");
9676
9105
  }
9677
9106
  function formatConservativeActiveToolLabel(event) {
9678
- return toolLabel(event.toolName || "tool");
9107
+ return event.toolName === "startAgentRun" ? t("agentStartingLabel") : toolLabel(event.toolName || "tool");
9679
9108
  }
9680
9109
  function isRunToolName(name) {
9681
9110
  return name === "execShell" || name === "runCommand" || name === "launchProcess";
9682
9111
  }
9683
- function isReadToolName(name) {
9684
- return name === "readFile";
9685
- }
9686
9112
  function isFailedToolResult(event) {
9687
9113
  const exitCode = event.metadata?.exitCode;
9688
9114
  if (event.metadata?.actionGate) return false;
@@ -9874,7 +9300,7 @@ function formatToolTraceLine(text, colorEnabled, accent = "none") {
9874
9300
  return `${dimCliText(text, true)}
9875
9301
  `;
9876
9302
  }
9877
- 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();
9878
9304
  function renderRunCard(snapshot, opts) {
9879
9305
  const labels = agentRunCardLabels();
9880
9306
  const timing = { startedAt: snapshot.startedAt, finishedAt: snapshot.finishedAt };
@@ -9925,8 +9351,9 @@ function recoverOrchestrationCard(event, toolName, opts) {
9925
9351
  if (toolName === "listAgents") {
9926
9352
  try {
9927
9353
  const parsed = JSON.parse(trimmed);
9928
- const agents = Array.isArray(parsed.agents) ? parsed.agents : [];
9929
- const card = formatAgentListCard(agents);
9354
+ if (parsed.success === false || !Array.isArray(parsed.agents)) return null;
9355
+ const agents = parsed.agents;
9356
+ const card = formatAgentListCard(agents, 8, /* @__PURE__ */ new Date(), !safe);
9930
9357
  const lines = card.split("\n");
9931
9358
  lines[0] = t("agentsListLabel", String(agents.length));
9932
9359
  return lines.join("\n");
@@ -9954,12 +9381,18 @@ function recoverOrchestrationCard(event, toolName, opts) {
9954
9381
  const name = safe ? cleanUserText(snapshot.agentName ?? "agent") : snapshot.agentName ?? "agent";
9955
9382
  const task = snapshot.taskPreview ? safe ? cleanUserText(snapshot.taskPreview) : snapshot.taskPreview : snapshot.taskPreview;
9956
9383
  const title = snapshot.title ? safe ? cleanUserText(snapshot.title) : snapshot.title : snapshot.title;
9957
- return formatStartRunCard(name, snapshot.status, {
9958
- task,
9959
- runId: snapshot.runId,
9960
- ...title ? { title } : {},
9961
- labels
9384
+ const identity = formatIdentityRow(name, snapshot.runId, {
9385
+ title,
9386
+ unnamedAgent: labels.unnamedAgent
9962
9387
  });
9388
+ const status = `${getAgentRunStatusIcon(snapshot.status)} ${labels.statusWord(snapshot.status)}`;
9389
+ const oneLine = identity ? `${identity} \xB7 ${status}` : status;
9390
+ const columns = process.stdout.columns || 80;
9391
+ const secondary = formatIdentityRow(name, snapshot.runId, { title, titleOnOwnLine: true, unnamedAgent: labels.unnamedAgent });
9392
+ const rows = identity && title && displayWidth(` ${oneLine}`) > columns ? [title, ` ${secondary ? `${secondary} \xB7 ` : ""}${status}`] : [oneLine];
9393
+ if (task && !title) rows.push(` ${labels.rows.task}${task}`);
9394
+ if (snapshot.errorMessage) rows.push(` ${labels.rows.error}${redactSecrets(cleanUserText(snapshot.errorMessage.split("\n")[0]))}`);
9395
+ return rows.join("\n");
9963
9396
  }
9964
9397
  if (kind === "gone") return formatNotFoundRunCard(labels);
9965
9398
  if (kind === "stop") return formatStopRunCard(snapshot.status, labels);
@@ -9969,10 +9402,20 @@ function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
9969
9402
  const safe = opts?.safe === true;
9970
9403
  const rawLabel = toolLabel(toolName);
9971
9404
  const bakedCard = typeof event.metadata?.displayData === "string" && event.metadata.displayData.trim() ? event.metadata.displayData : "";
9972
- const rawDataStr = recoverOrchestrationCard(event, toolName, { safe }) || bakedCard || (typeof event.content === "string" ? event.content : "");
9973
- const failed = event.type === "tool-error" || isFailedToolResult(event) || Boolean(event.metadata?.failed) || /^Error:/i.test(rawDataStr.trim());
9405
+ let listPayload;
9406
+ if (toolName === "listAgents" && typeof event.content === "string") {
9407
+ try {
9408
+ const value = JSON.parse(event.content);
9409
+ if (value && typeof value === "object" && !Array.isArray(value)) listPayload = value;
9410
+ } catch {
9411
+ }
9412
+ }
9413
+ const listFailed = listPayload?.success === false;
9414
+ const rawDataStr = listFailed ? typeof listPayload?.error === "string" ? listPayload.error : event.content || bakedCard : recoverOrchestrationCard(event, toolName, { safe }) || bakedCard || (typeof event.content === "string" ? event.content : "");
9415
+ const failed = event.type === "tool-error" || isFailedToolResult(event) || Boolean(event.metadata?.failed) || listFailed || /^Error:/i.test(rawDataStr.trim());
9974
9416
  if (failed) {
9975
- const firstLine = stripAnsi2(rawDataStr.trim().split("\n")[0] || event.summary || event.message || t("toolFailed"));
9417
+ const failureSnapshot = toolName === "startAgentRun" ? parseAgentRunEvent(event)?.snapshot : void 0;
9418
+ const firstLine = stripAnsi(failureSnapshot?.errorMessage || rawDataStr.trim().split("\n")[0] || event.summary || event.message || t("toolFailed"));
9976
9419
  const message = clip(redactSecrets(firstLine), 96);
9977
9420
  if (!colorEnabled) {
9978
9421
  return `\u2717 ${rawLabel} ${message}
@@ -9984,11 +9427,59 @@ function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
9984
9427
  return `${cross} ${labelPart2} ${msgPart}
9985
9428
  `;
9986
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
+ }
9446
+ const parsedStart = toolName === "startAgentRun" ? parseAgentRunEvent(event) : null;
9447
+ const startFailed = parsedStart && isAgentRunStartFailureStatus(parsedStart.snapshot.status);
9448
+ let heading = parsedStart ? t(startFailed ? "agentStartFailedLabel" : "agentStartedLabel") : rawLabel;
9987
9449
  const displayData = rawDataStr.trim();
9988
9450
  const lines = displayData ? displayData.split("\n") : [];
9989
- const projected = safe ? sanitizeRunCardForNormal(lines) : lines;
9451
+ if (toolName === "startAgentRun" && ["Run started", "\u8FD0\u884C\u5DF2\u542F\u52A8"].includes(lines[0]?.trim())) lines.shift();
9452
+ let projected = safe ? sanitizeRunCardForNormal(lines) : lines;
9453
+ if (safe && toolName === "listAgents") {
9454
+ if (Array.isArray(listPayload?.agents)) {
9455
+ const count = listPayload.agents.length;
9456
+ const total = typeof listPayload.total === "number" && Number.isSafeInteger(listPayload.total) && listPayload.total >= count ? listPayload.total : count;
9457
+ heading = t("agentsCompactCount", String(total));
9458
+ if (total !== count) heading += ` \xB7 ${t("agentsPageCount", String(count))}`;
9459
+ if (listPayload.truncated === true) heading += ` \xB7 ${t("agentsTruncated")}`;
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]);
9467
+ projected = projected.slice(1);
9468
+ }
9469
+ }
9470
+ projected = projected.map((line) => line.replace(/\s{2,}(?:agent-pub-[a-z0-9]+|agent-system-[a-z0-9]+|agent-[0-9a-f]{6,}-[a-z0-9-]+|\(agentKey unavailable\))\s*$/i, ""));
9471
+ }
9472
+ if (safe && toolName === "controlAgentRun" && projected.length > 0) {
9473
+ const first = projected[0].trim();
9474
+ const recognized = ["Run status", "\u8FD0\u884C\u72B6\u6001", "Run finished", "\u8FD0\u884C\u5DF2\u7ED3\u675F", "Run stopped", "\u8FD0\u884C\u5DF2\u505C\u6B62"];
9475
+ const merged = `${heading} \xB7 ${first}`;
9476
+ if (recognized.includes(first) && displayWidth(`\u25CF ${merged}`) <= (process.stdout.columns || 80)) {
9477
+ heading = merged;
9478
+ projected = projected.slice(1);
9479
+ }
9480
+ }
9990
9481
  if (!colorEnabled) {
9991
- let out2 = `\u25CF ${rawLabel}
9482
+ let out2 = `\u25CF ${heading}
9992
9483
  `;
9993
9484
  for (const line of projected) {
9994
9485
  out2 += ` ${line}
@@ -9997,7 +9488,7 @@ function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
9997
9488
  return out2;
9998
9489
  }
9999
9490
  const bullet = themeText("\u25CF", "success", true);
10000
- const labelPart = themeText(rawLabel, "muted", true);
9491
+ const labelPart = themeText(heading, "muted", true);
10001
9492
  let out = `${bullet} ${labelPart}
10002
9493
  `;
10003
9494
  for (const line of projected) {
@@ -10015,7 +9506,7 @@ function sanitizeRunCardForNormal(lines) {
10015
9506
  break;
10016
9507
  }
10017
9508
  if (/^\s*error\b/i.test(line)) {
10018
- out.push(clip(redactSecrets(stripAnsi2(line)), 160));
9509
+ out.push(clip(redactSecrets(stripAnsi(line)), 160));
10019
9510
  errorIndent = line.length - line.trimStart().length;
10020
9511
  continue;
10021
9512
  }
@@ -10248,7 +9739,7 @@ function formatNormalToolDuration(elapsedMs) {
10248
9739
  if (elapsedMs < 1e3) return `${Math.round(elapsedMs)}ms`;
10249
9740
  return `${(elapsedMs / 1e3).toFixed(1)}s`;
10250
9741
  }
10251
- function formatNormalToolLine(event, pending, colorEnabled) {
9742
+ function formatNormalToolLine(event, pending, colorEnabled, opts) {
10252
9743
  if (event.type === "tool-call") return "";
10253
9744
  const toolName = event.toolName || pending?.toolName || "tool";
10254
9745
  if (event.type === "tool-result" && (event.toolName === "ask_user" || event.metadata?.uiAskChoice)) {
@@ -10256,10 +9747,13 @@ function formatNormalToolLine(event, pending, colorEnabled) {
10256
9747
  if (block) return block;
10257
9748
  }
10258
9749
  if (event.type === "tool-result" && (toolName === "listAgents" || toolName === "startAgentRun" || toolName === "controlAgentRun")) {
10259
- return formatOrchestrationCardBlock(event, toolName, colorEnabled, { safe: true });
9750
+ return formatOrchestrationCardBlock(event, toolName, colorEnabled, {
9751
+ safe: true,
9752
+ visibleRunIds: opts?.visibleRunIds
9753
+ });
10260
9754
  }
10261
9755
  if (event.type === "tool-result" && toolName === "loadSkill") {
10262
- return formatLoadSkillBlock(event, colorEnabled, { safe: true }) ?? "";
9756
+ return formatLoadSkillBlock({ ...event, argumentsPreview: event.argumentsPreview || pending?.argumentsPreview }, colorEnabled, { safe: true }) ?? "";
10263
9757
  }
10264
9758
  if (event.type === "tool-result" && toolName === "show_interaction") {
10265
9759
  return formatShowInteractionBlock(event, colorEnabled);
@@ -10304,24 +9798,56 @@ function toolFailureReason(event) {
10304
9798
  return lines.slice(start + 1, end < 0 ? lines.length : end);
10305
9799
  };
10306
9800
  const reasonLine = sectionLines("stderr")[0] ?? sectionLines("stdout")[0] ?? lines.find((line) => !/^(stdout|stderr|exitCode)\s*:/i.test(line)) ?? lines[0] ?? "";
10307
- return reasonLine ? clip(redactSecrets(stripAnsi2(reasonLine)), 96) : "";
9801
+ return reasonLine ? clip(redactSecrets(stripAnsi(reasonLine)), 96) : "";
10308
9802
  }
10309
9803
  function resolveLoadSkillName(event) {
10310
- const metaName = typeof event.metadata?.name === "string" ? event.metadata.name : void 0;
10311
- if (metaName) return metaName;
10312
- const argName = event.argumentsPreview?.trim();
10313
- if (argName && !argName.startsWith("{")) return argName;
10314
9804
  const content = typeof event.content === "string" ? event.content : "";
10315
- const match = content.match(/Skill "([^"]+)" loaded inline/);
10316
- if (match?.[1]) return match[1];
10317
- return argName || "skill";
9805
+ let result;
9806
+ try {
9807
+ const value = JSON.parse(content);
9808
+ if (value && typeof value === "object" && !Array.isArray(value)) result = value;
9809
+ } catch {
9810
+ }
9811
+ const preview = event.argumentsPreview?.trim() ?? "";
9812
+ let args = {};
9813
+ if (preview.startsWith("{")) {
9814
+ try {
9815
+ const value = JSON.parse(preview);
9816
+ if (value && typeof value === "object" && !Array.isArray(value)) args = value;
9817
+ } catch {
9818
+ }
9819
+ } else if (/^(?:name|source|slug|dbKey|projectBinding|relativePath)=/.test(preview)) {
9820
+ for (const match of preview.matchAll(/(?:^|\s)(name|source|slug|dbKey|projectBinding|relativePath)=([^\s]+)/g)) args[match[1]] = match[2];
9821
+ } else if (preview) {
9822
+ args.name = preview;
9823
+ }
9824
+ const textName = content.match(/^Skill "([^"\n]+)" loaded inline\./)?.[1];
9825
+ const name = result?.name ?? textName ?? event.metadata?.name ?? args.name;
9826
+ const source = result?.source ?? event.metadata?.source ?? args.source;
9827
+ const slug = result?.slug ?? event.metadata?.slug ?? args.slug;
9828
+ const dbKey = result?.dbKey ?? event.metadata?.dbKey ?? args.dbKey;
9829
+ const relativePath2 = result?.relativePath ?? event.metadata?.relativePath ?? args.relativePath;
9830
+ const shortReference = (value) => {
9831
+ if (typeof value !== "string" || !value.trim()) return void 0;
9832
+ const normalized = value.trim().replace(/\\/g, "/");
9833
+ const parts = normalized.split("/").filter(Boolean);
9834
+ return parts.at(-1) === "SKILL.md" && parts.length > 1 ? parts.at(-2) : parts.at(-1);
9835
+ };
9836
+ const candidate = shortReference(name) ?? shortReference(slug) ?? shortReference(dbKey) ?? shortReference(relativePath2) ?? shortReference(source) ?? t("unnamedSkillReference");
9837
+ return clip(redactSecrets(cleanUserText(candidate)), 80);
10318
9838
  }
10319
9839
  function formatLoadSkillBlock(event, colorEnabled, opts) {
10320
9840
  if (event.type !== "tool-result" || event.toolName !== "loadSkill") return null;
10321
9841
  const skillName = resolveLoadSkillName(event);
10322
9842
  const content = typeof event.content === "string" ? event.content : "";
10323
- const failed = /^Skill\s+"[^"]*"\s+not found/.test(content) || isFailedToolResult(event);
10324
- const labelText = t("usedSkillLabel");
9843
+ let result;
9844
+ try {
9845
+ const value = JSON.parse(content);
9846
+ if (value && typeof value === "object" && !Array.isArray(value)) result = value;
9847
+ } catch {
9848
+ }
9849
+ const failed = /^Skill\s+"[^"]*"\s+not found/i.test(content) || /^Skill reference rejected:/i.test(content) || event.metadata?.resolved === false || Boolean(event.metadata?.failed) || result?.success === false || isFailedToolResult(event);
9850
+ const labelText = t(failed ? "loadSkillLabel" : "usedSkillLabel");
10325
9851
  if (failed) {
10326
9852
  const message = opts?.safe === true ? t("toolFailed") : clip(content.split("\n")[0] || t("toolFailed"), 96);
10327
9853
  return formatToolTraceLine(`\u25B8 ${labelText} (${skillName}) \u2717 ${message}`, colorEnabled, "error");
@@ -10338,14 +9864,34 @@ function formatLoadSkillBlock(event, colorEnabled, opts) {
10338
9864
  }
10339
9865
  var TUI_TREE_MARKER = "TUI_TREE\n";
10340
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
+ };
10341
9873
  function createToolEventFormatter(colorEnabled = resolveCliColorEnabled(), opts = {}) {
10342
9874
  const pending = /* @__PURE__ */ new Map();
10343
9875
  let tree = null;
10344
- const treeKind = (name) => isRunToolName(name) ? "Run" : isReadToolName(name) ? "Read" : name === "exa_search" ? "Search" : name === "fetchWebpage" ? "Fetch" : null;
10345
- 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) => {
10346
9878
  const label = kind === "Run" ? toolLabel("execShell") : kind === "Read" ? toolLabel("readFile") : kind === "Fetch" ? toolLabel("fetchWebpage") : toolLabel("exa_search");
10347
- return `${TUI_TREE_MARKER}${label} (${items.length})
10348
- ${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}
10349
9895
  `;
10350
9896
  };
10351
9897
  const formatTreeEvent = (event, call) => {
@@ -10372,8 +9918,8 @@ ${items.map((item, i) => `${i === items.length - 1 ? "\u2514\u2500\u2500 " : "\u
10372
9918
  item = withholdIfSecretLike(item) || toolLabel(name);
10373
9919
  if (tree?.kind !== kind) tree = { kind, items: [] };
10374
9920
  tree.items.push(item);
10375
- if (tree.items.length < 2) return formatNormalToolLine(event, call, colorEnabled);
10376
- 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));
10377
9923
  };
10378
9924
  const format = (event) => {
10379
9925
  if (event.type === "tool-call") {
@@ -10387,7 +9933,7 @@ ${items.map((item, i) => `${i === items.length - 1 ? "\u2514\u2500\u2500 " : "\u
10387
9933
  pending.delete(event.toolCallId);
10388
9934
  const treeOutput = formatTreeEvent(event, call);
10389
9935
  if (treeOutput !== null) return treeOutput;
10390
- return formatNormalToolLine(event, call, colorEnabled);
9936
+ return formatNormalToolLine(event, call, colorEnabled, opts);
10391
9937
  };
10392
9938
  format.reset = () => {
10393
9939
  tree = null;
@@ -10583,7 +10129,7 @@ function formatCompactionSummaryLine(event) {
10583
10129
  if (!event) return "";
10584
10130
  if (event.failed) {
10585
10131
  const reason = event.detail ? `\uFF1A${event.detail}` : "";
10586
- 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}
10587
10133
  `;
10588
10134
  }
10589
10135
  if (event.skipped) {
@@ -10639,7 +10185,7 @@ function shouldPromoteTuiNarration(text) {
10639
10185
  return /(^|\n)\s*(?:#{1,3}\s|```|[-*+]\s|\d+[.)]\s)/.test(text);
10640
10186
  }
10641
10187
  function narrationActivityLabel(text) {
10642
- const oneLine = stripAnsi2(text).replace(/[`*_#>]/g, "").replace(/\s+/g, " ").trim();
10188
+ const oneLine = stripAnsi(text).replace(/[`*_#>]/g, "").replace(/\s+/g, " ").trim();
10643
10189
  return truncateThinkingHint(oneLine, 60);
10644
10190
  }
10645
10191
  function createCliTurnOutput(params) {
@@ -10647,7 +10193,8 @@ function createCliTurnOutput(params) {
10647
10193
  const workingLabel = params.workingLabel ?? `${options.agentName} -> working`;
10648
10194
  const spinner = params.spinner ?? new Spinner(options.output, workingLabel, Boolean(options.activityReporter));
10649
10195
  const formatToolEvent = createToolEventFormatter(void 0, {
10650
- tuiTrees: options.output.tuiTrees === true
10196
+ tuiTrees: options.output.tuiTrees === true,
10197
+ visibleRunIds: options.output.visibleRunIds
10651
10198
  });
10652
10199
  const eventMode = resolveAgentEventMode(options);
10653
10200
  const assistantLabelManaged = options.output.assistantLabelManaged === true;
@@ -10876,8 +10423,17 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
10876
10423
  */
10877
10424
  showPhase(phase) {
10878
10425
  const label = phase === "validating-context" ? t("contextChecking") : phase === "compacting" ? t("contextCompacting") : t("waitingForModel");
10879
- spinner.show(label);
10880
- 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
+ }
10881
10437
  },
10882
10438
  finish(fallbackContent) {
10883
10439
  const flushedThink = flushThinkParser(thinkState);
@@ -11412,9 +10968,57 @@ function isBalanceExhaustedError(error) {
11412
10968
  return matchesBalanceError(message);
11413
10969
  }
11414
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
+
11415
11019
  // packages/cli/client/agentRun.ts
11416
11020
  async function loadRunLocalAgentTurn() {
11417
- const { runLocalAgentTurn } = await import("./agentRuntimeLocal-HL526DNQ.js");
11021
+ const { runLocalAgentTurn } = await import("./agentRuntimeLocal-QZPFWMLG.js");
11418
11022
  return runLocalAgentTurn;
11419
11023
  }
11420
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();
@@ -11690,6 +11294,7 @@ function looksLikeQuotaExhaustedText(message) {
11690
11294
  }
11691
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;
11692
11296
  function classifyLocalRunError(message) {
11297
+ if (isHistoryIntegrityFailure(message)) return { kind: "history_integrity" };
11693
11298
  const m = message.match(PROVIDER_HTTP_FAILED_RE);
11694
11299
  if (m) {
11695
11300
  const status = Number(m[2]);
@@ -11982,8 +11587,7 @@ function buildRateLimitFailure(ctx) {
11982
11587
  t(
11983
11588
  "localRunRateLimitCooldown",
11984
11589
  formatCooldownUntilLocal(cooldownUntil),
11985
- resetValue ? t("localRunRateLimitResetNote", resetValue) : "",
11986
- String(Math.round(PROBE_INTERVAL_MS / 6e4))
11590
+ resetValue ? t("localRunRateLimitResetNote", resetValue) : ""
11987
11591
  )
11988
11592
  );
11989
11593
  }
@@ -12066,8 +11670,52 @@ function buildUpstreamFailure(ctx) {
12066
11670
  return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}). Detail: ${ctx.message} ${NO_FALLBACK} ${fix}, ${SERVER_FALLBACK_HINT}
12067
11671
  `;
12068
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
+ }
12069
11706
  function formatLocalTurnFailureLine(error) {
12070
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
+ }
12071
11719
  if (error?.code === "LLM_REQUEST_TIMEOUT") {
12072
11720
  const msMatch = /after (\d+)ms/.exec(message);
12073
11721
  const deadline = msMatch && Number.isFinite(Number(msMatch[1])) ? formatElapsed(Math.round(Number(msMatch[1]) / 1e3)) : "the configured window";
@@ -12075,6 +11723,7 @@ function formatLocalTurnFailureLine(error) {
12075
11723
  `;
12076
11724
  }
12077
11725
  const cls = classifyLocalRunError(message);
11726
+ if (cls.kind === "history_integrity") return describeHistoryIntegrityFailure(message);
12078
11727
  if (cls.kind === "rate-limit") {
12079
11728
  const rawCooldownUntil = error && typeof error === "object" ? error.cooldownUntil : void 0;
12080
11729
  return buildRateLimitFailure({
@@ -12153,9 +11802,21 @@ function describeLocalRunFailure(message, rawError) {
12153
11802
  if (isCliAuthorityBrokerProtocolError(rawError) || /CLI authority broker protocol|CLI authority broker .* returned malformed response/i.test(message)) {
12154
11803
  const cleaned = stripDebugNoise(message);
12155
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()}.
12156
11816
  `;
12157
11817
  }
12158
11818
  const cls = classifyLocalRunError(message);
11819
+ if (cls.kind === "history_integrity") return describeHistoryIntegrityFailure(message);
12159
11820
  if (cls.kind === "generic") {
12160
11821
  if (/owner-required route not acknowledged/i.test(message)) {
12161
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}
@@ -12344,7 +12005,7 @@ async function runHttpAgentTurn(options, authToken) {
12344
12005
  const contentType = res.headers.get("content-type") || "";
12345
12006
  if (contentType.includes("text/event-stream") && res.body) {
12346
12007
  const result = await readStreamingAgentRun(options, res, spinner);
12347
- return result;
12008
+ return { ...result, httpOutcome: { status: res.status } };
12348
12009
  }
12349
12010
  spinner.stop();
12350
12011
  let data = {};
@@ -12431,7 +12092,7 @@ ${options.agentName} > (no text response)
12431
12092
  model: typeof data?.model === "string" ? data.model : void 0,
12432
12093
  dialogServer: serverOriginForDialog(options.serverUrl)
12433
12094
  });
12434
- return serverResult;
12095
+ return { ...serverResult, httpOutcome: { status: res.status, body: data } };
12435
12096
  }
12436
12097
  async function runInjectedLocalAgentTurn(options) {
12437
12098
  return runLocalAgentTurnForCli(options, { reportFailure: true });
@@ -12527,14 +12188,189 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12527
12188
  } : void 0;
12528
12189
  const currentDialogId = options.continueDialogId ?? ulid2();
12529
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
+ }) };
12530
12197
  const turnId = `turn-${ulid2()}`;
12531
12198
  const runtimeContextWithOwnership = {
12532
12199
  ...runtimeContext ?? {},
12533
12200
  dialogId: currentDialogId,
12534
- turnId
12201
+ turnId,
12202
+ getProcessCausalDepth: options.getProcessCausalDepth
12203
+ };
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
+ }
12535
12367
  };
12536
- const adapter = baseAdapter;
12537
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
+ };
12538
12374
  const workingLabel = `${options.agentName} -> working locally`;
12539
12375
  const turnOutput = createCliTurnOutput({
12540
12376
  options,
@@ -12556,9 +12392,11 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12556
12392
  const runLocalAgentTurn = await loadRunLocalAgentTurn();
12557
12393
  const result = await runLocalAgentTurn({
12558
12394
  adapter,
12395
+ ...hostTask.contract ? { taskExecutionContract: hostTask.contract } : {},
12559
12396
  agentRef: options.agentKey,
12560
12397
  userLanguage: options.userLanguage ?? options.env.NOLO_LANG ?? null,
12561
12398
  input: buildUserInputContent(messageForLocal, options.imageUrls),
12399
+ userMessages: options.userMessages,
12562
12400
  ...expandedMessage !== options.message || localAttachmentCard !== "" ? {
12563
12401
  persistedInput: hasDurableAttachments ? buildUserInputContent(
12564
12402
  expandedMessage,
@@ -12606,15 +12444,7 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12606
12444
  if (event.kind === "turn-phase") {
12607
12445
  turnOutput.showPhase(event.phase);
12608
12446
  }
12609
- if (event.kind === "compaction-start") {
12610
- turnOutput.showPhase("compacting");
12611
- }
12612
- if (event.kind === "compaction-end" || // 压缩失败(timeout/provider-error)时 localLoop 按失败原子性语义
12613
- // 带着裁剪后的历史继续本轮,切回等待模型文案;aborted 时 turn 随即
12614
- // 结束,不再切文案(终态由 abort 路径收尾)。
12615
- event.kind === "compaction-failed" && event.reason !== "aborted") {
12616
- turnOutput.showPhase("waiting-provider");
12617
- }
12447
+ turnOutput.handleCompactionActivity(event);
12618
12448
  if (event.kind === "image-downgraded") {
12619
12449
  options.output.write(
12620
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"
@@ -12631,6 +12461,8 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12631
12461
  // tool-gist-fold 后 onToolEvent 无条件挂载(不再受 traceLocalTools 开关
12632
12462
  // 控制,显示模式合并为单一 gist/折叠通道)——保留 alpha 的新形态。
12633
12463
  onToolEvent: (event) => {
12464
+ const observation = observeLocalCommandResult(event, options.localRuntimeCwd ?? process.cwd());
12465
+ if (observation) commandObservations.push({ ...observation, ...commandVersionBindings.get(event.toolCallId) });
12634
12466
  turnOutput.handleToolEvent(event);
12635
12467
  },
12636
12468
  ...!options.noStream ? {
@@ -12643,21 +12475,30 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12643
12475
  } : {}
12644
12476
  });
12645
12477
  turnOutput.finish(result.content);
12478
+ const usageRecords = result.usageRecords?.filter(
12479
+ (record) => Object.keys(record.usage ?? {}).length > 0
12480
+ );
12646
12481
  const turnCredits = sumPlatformCredits(result.usageRecords);
12482
+ const turnTokens = withTurnCredits(buildTurnTokenUsage(result.usage, result.model), turnCredits);
12647
12483
  const turnResult = {
12484
+ savedTurnPersisted: turnPersisted,
12485
+ mainProviderAttempted: mainProviderStarted,
12648
12486
  exitCode: 0,
12487
+ stopReason: result.stopReason,
12488
+ ...hostTask.result(),
12489
+ ...options.hostTaskRef ? { hostTaskRef: options.hostTaskRef } : {},
12649
12490
  dialogId: result.dialogId,
12650
12491
  ...typeof result.content === "string" && result.content.trim() ? { finalText: result.content } : {},
12651
- title: result.title,
12492
+ ...result.title !== void 0 ? { title: result.title } : {},
12652
12493
  ...result.titlePatchPromise ? { titlePatchPromise: result.titlePatchPromise } : {},
12653
12494
  ...pickEmptyAssistantFlags(result),
12654
12495
  // 积分口径按「全轮」而非「最后一次调用」:result.usage 只是收尾那次
12655
12496
  // provider 调用的 usage,本轮前面 N-1 次工具循环调用(以及自动压缩摘要)
12656
12497
  // 的 cost 都只存在于 usageRecords 里。token 字段仍取 result.usage——
12657
12498
  // 上下文占用本来就该看最后一次调用的累计输入,不是各次相加。
12658
- turnTokens: withTurnCredits(buildTurnTokenUsage(result.usage, result.model), turnCredits),
12499
+ ...turnTokens !== void 0 ? { turnTokens } : {},
12659
12500
  ...turnCredits !== void 0 ? { turnCredits } : {},
12660
- ...result.usageRecords?.length ? { usageRecords: result.usageRecords } : {}
12501
+ ...usageRecords?.length ? { usageRecords } : {}
12661
12502
  };
12662
12503
  const serverMeta = resolveResultServerMeta({
12663
12504
  env: options.env ?? {},
@@ -12665,6 +12506,7 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12665
12506
  hasSubjectRefs: (buildSubjectRefs(options)?.length ?? 0) > 0
12666
12507
  });
12667
12508
  recordRunResultHeaderMeta(turnResult, {
12509
+ commandObservations,
12668
12510
  model: result.model,
12669
12511
  dialogServer: serverMeta.server,
12670
12512
  serverSync: serverMeta.serverSync
@@ -12680,14 +12522,18 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12680
12522
  const abortedTurnCredits = sumPlatformCredits(abortedUsageRecords);
12681
12523
  if (error?.code === LOCAL_TURN_ABORTED_CODE || options.abortSignal?.aborted) {
12682
12524
  const pendingToolName = error?.pendingToolName;
12683
- return {
12525
+ return retainCommandObservations({
12684
12526
  exitCode: 0,
12527
+ ...hostTask.result(),
12528
+ savedTurnPersisted: turnPersisted,
12529
+ mainProviderAttempted: mainProviderStarted,
12530
+ ...options.hostTaskRef ? { hostTaskRef: options.hostTaskRef } : {},
12685
12531
  streamInterrupted: true,
12686
12532
  ...savedDialogId ? { dialogId: savedDialogId } : {},
12687
12533
  ...pendingToolName ? { pendingToolName } : {},
12688
12534
  ...abortedTurnCredits !== void 0 ? { turnCredits: abortedTurnCredits } : {},
12689
12535
  ...abortedUsageRecords?.length ? { usageRecords: abortedUsageRecords } : {}
12690
- };
12536
+ });
12691
12537
  }
12692
12538
  const cooldownUntil = await markStartupRateLimitCooldown(
12693
12539
  options,
@@ -12698,27 +12544,59 @@ async function executeLocalAgentTurnForCliWithAdapter(options, settings, resolve
12698
12544
  error.cooldownUntil = cooldownUntil;
12699
12545
  }
12700
12546
  if (settings.reportFailure) {
12701
- const failureLine = formatLocalTurnFailureLine(error);
12702
- if (typeof options.output.writeErr === "function") {
12703
- options.output.writeErr(failureLine);
12704
- } else {
12705
- 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
+ }
12706
12555
  }
12707
12556
  }
12708
- 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({
12709
12575
  exitCode: 1,
12576
+ ...hostTask.result(),
12710
12577
  localError: error,
12578
+ savedTurnPersisted: persisted,
12579
+ mainProviderAttempted: mainProviderStarted,
12711
12580
  failureSubclass: classifyFailureSubclass({
12712
12581
  message: toErrorMessage(error),
12713
12582
  body: error
12714
12583
  }),
12715
- ...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
+ } : {},
12716
12594
  ...abortedTurnCredits !== void 0 ? { turnCredits: abortedTurnCredits } : {},
12717
12595
  ...abortedUsageRecords?.length ? { usageRecords: abortedUsageRecords } : {}
12718
- };
12596
+ });
12719
12597
  }
12720
12598
  }
12721
- async function checkLocalAvailabilityBeforeHttpDispatch(options) {
12599
+ async function resolveLocalCredentialKeysForDispatch(options) {
12722
12600
  if (options.runtimeKey && !isDockerRuntimeKey(options.runtimeKey)) return null;
12723
12601
  const adapter = resolveLocalRuntimeAdapter(options);
12724
12602
  if (!adapter || typeof adapter.loadAgentConfig !== "function") return null;
@@ -12737,54 +12615,33 @@ async function checkLocalAvailabilityBeforeHttpDispatch(options) {
12737
12615
  config,
12738
12616
  options
12739
12617
  )) {
12740
- credentialKey = void 0;
12741
- }
12742
- const agentLevelAt = baseRecord.nextAvailableAt;
12743
- const agentLevelNextAvailableAt = typeof agentLevelAt === "number" && Number.isFinite(agentLevelAt) ? agentLevelAt : void 0;
12744
- if (!credentialKey && agentLevelNextAvailableAt === void 0) {
12745
- return { credentialKey };
12618
+ return null;
12746
12619
  }
12747
12620
  const env = options.env;
12748
12621
  const now = Date.now();
12749
- let entry;
12750
- let matchedKey;
12751
- if (credentialKey) {
12752
- const effective = await readEffectiveCredentialEntry(credentialKey, env, now).catch(() => void 0);
12753
- if (effective) {
12754
- entry = effective;
12755
- matchedKey = effective.matchedKey;
12756
- }
12757
- }
12758
- const entryAt = entry?.nextAvailableAt;
12759
- const effectiveNextAvailableAt = typeof entryAt === "number" ? mergeAvailabilityDeadline(agentLevelNextAvailableAt, entryAt) : agentLevelNextAvailableAt;
12760
- const activeKey = matchedKey || credentialKey;
12761
- if (typeof effectiveNextAvailableAt !== "number") {
12762
- return { credentialKey: credentialKey || activeKey, matchedKey };
12763
- }
12764
- const gateDecision = resolveCooldownGate(
12765
- { nextAvailableAt: effectiveNextAvailableAt, lastProbeAt: entry?.lastProbeAt },
12766
- now
12767
- );
12768
- if (gateDecision === "probe" && activeKey) {
12769
- await recordCredentialProbe(activeKey, env, now).catch(() => void 0);
12770
- return { credentialKey: credentialKey || activeKey, matchedKey };
12771
- }
12772
- if (gateDecision !== "blocked") return { credentialKey: credentialKey || activeKey, matchedKey };
12773
- options.output.write(
12774
- `${t(
12775
- "agentCooldownBlocked",
12776
- options.agentName || options.agentKey,
12777
- formatCooldownUntilLocal(
12778
- new Date(Number(effectiveNextAvailableAt)).toISOString()
12779
- )
12780
- )}
12781
- `
12782
- );
12783
- return { exitCode: 1, failureSubclass: "rate_limit" };
12622
+ const entry = credentialKey ? await readEffectiveCredentialEntry(credentialKey, env, now).catch(() => void 0) : void 0;
12623
+ const recorder = adapter;
12624
+ return {
12625
+ credentialKey,
12626
+ matchedKey: entry?.matchedKey,
12627
+ // 真实 status/body 由调用方透传(不再固定 200 无 body):HTTP 2xx 的 body 里
12628
+ // 也可能带配额错误码,固定成功的判定会把这类响应当成恢复而清掉冷却。
12629
+ recordSuccess: recorder.recordStartupAvailabilityForAgent ? (status, body) => recorder.recordStartupAvailabilityForAgent(options.agentKey, status, body) : void 0
12630
+ };
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
+ };
12784
12639
  }
12785
12640
  function foldLocalResultForTui(localResult) {
12786
12641
  const folded = {
12787
12642
  exitCode: localResult.exitCode,
12643
+ ...projectLocalTurnFacts(localResult),
12644
+ ...localResult.hostTaskRef ? { hostTaskRef: localResult.hostTaskRef } : {},
12788
12645
  ...localResult.dialogId ? { dialogId: localResult.dialogId } : {},
12789
12646
  title: localResult.title,
12790
12647
  ...localResult.titlePatchPromise ? { titlePatchPromise: localResult.titlePatchPromise } : {},
@@ -12854,7 +12711,7 @@ async function runAgentTurn(options) {
12854
12711
  }
12855
12712
  const skipLocal = await shouldSkipAutoLocalForServerPlatformTools(options);
12856
12713
  if (!skipLocal) {
12857
- const localResult = await runLocalAgentTurnForCli(options, {
12714
+ let localResult = await runLocalAgentTurnForCli(options, {
12858
12715
  reportFailure: false
12859
12716
  });
12860
12717
  if (localResult.exitCode === 0) {
@@ -12872,6 +12729,7 @@ async function runAgentTurn(options) {
12872
12729
  const retriedLocalResult = await runLocalAgentTurnForCli(options, {
12873
12730
  reportFailure: false
12874
12731
  });
12732
+ localResult = retriedLocalResult;
12875
12733
  if (retriedLocalResult.exitCode === 0) {
12876
12734
  return foldLocalResultForTui(retriedLocalResult);
12877
12735
  }
@@ -12886,19 +12744,30 @@ async function runAgentTurn(options) {
12886
12744
  message: localErrorMessage,
12887
12745
  body: localResult.localError
12888
12746
  });
12889
- options.output.write(describeLocalRunFailure(localErrorMessage, localResult.localError));
12890
- 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 = {
12891
12760
  exitCode: 1,
12761
+ ...projectLocalTurnFacts(localResult),
12892
12762
  failureSubclass,
12893
12763
  ...localResult.dialogId ? { dialogId: localResult.dialogId } : {},
12894
- // Keep localError so TUI can show balance/quota/dialog-preserved hints
12895
- // instead of only the raw auto-runtime line.
12896
- ...localResult.localError ? { localError: localResult.localError } : {},
12897
12764
  // 失败轮同样可能已发生平台计费(abort/失败照样扣费):turnCredits 与
12898
12765
  // 逐帧明细一起随行,否则审计日志在 auto 失败路径上缺账。
12899
12766
  ...localResult.turnCredits !== void 0 ? { turnCredits: localResult.turnCredits } : {},
12900
- ...localResult.usageRecords?.length ? { usageRecords: localResult.usageRecords } : {}
12767
+ ...failureUsageRecords?.length ? { usageRecords: failureUsageRecords } : {}
12901
12768
  };
12769
+ recordRunResultHeaderMeta(failedResult, getRunResultHeaderMeta(localResult));
12770
+ return failedResult;
12902
12771
  }
12903
12772
  }
12904
12773
  if (!authToken) {
@@ -12907,20 +12776,22 @@ async function runAgentTurn(options) {
12907
12776
  );
12908
12777
  return { exitCode: 1 };
12909
12778
  }
12910
- const localAvailability = await checkLocalAvailabilityBeforeHttpDispatch(options);
12911
- if (localAvailability?.exitCode) {
12912
- return {
12913
- exitCode: localAvailability.exitCode,
12914
- failureSubclass: localAvailability.failureSubclass ?? "rate_limit"
12915
- };
12916
- }
12917
- const httpResult = await runHttpAgentTurn(options, authToken);
12918
- if (httpResult.exitCode === 0 && !httpResult.streamInterrupted && (localAvailability?.credentialKey || localAvailability?.matchedKey)) {
12919
- const keyToClear = localAvailability.credentialKey || localAvailability.matchedKey;
12920
- await clearCredentialAvailability(
12921
- keyToClear,
12922
- options.env
12923
- ).catch(() => void 0);
12779
+ const localAvailability = await resolveLocalCredentialKeysForDispatch(options);
12780
+ const { httpOutcome, ...httpResult } = await runHttpAgentTurn(options, authToken);
12781
+ if (httpResult.exitCode === 0 && !httpResult.streamInterrupted && localAvailability) {
12782
+ const action = httpOutcome ? resolveAvailabilityAction(httpOutcome.status, httpOutcome.body, Date.now()) : void 0;
12783
+ if (action?.kind === "clear") {
12784
+ const keyToClear = localAvailability.credentialKey || localAvailability.matchedKey;
12785
+ if (keyToClear) {
12786
+ await clearCredentialAvailability(
12787
+ keyToClear,
12788
+ options.env
12789
+ ).catch(() => void 0);
12790
+ }
12791
+ }
12792
+ if (httpOutcome) {
12793
+ await localAvailability.recordSuccess?.(httpOutcome.status, httpOutcome.body).catch(() => void 0);
12794
+ }
12924
12795
  }
12925
12796
  return httpResult;
12926
12797
  }
@@ -13114,7 +12985,7 @@ function buildHostEnvironmentLayer(options) {
13114
12985
 
13115
12986
  // packages/agent-runtime/agentsMd.ts
13116
12987
  import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
13117
- import { resolve as resolve2 } from "node:path";
12988
+ import { resolve as resolve4 } from "node:path";
13118
12989
  var AGENTS_MD_MAX_BYTES = 8192;
13119
12990
  var AGENTS_MD_MARKER_RESERVE_BYTES = 512;
13120
12991
  var AGENTS_MD_CANDIDATES = ["AGENTS.md", "CLAUDE.md"];
@@ -13174,6 +13045,37 @@ var parseAgentsMdItem = (body) => {
13174
13045
  rest: body.slice(firstClause.length).replace(/^[::\s]+/, "")
13175
13046
  };
13176
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
+ };
13177
13079
  var priorityOf = (label) => {
13178
13080
  const lowered = label.toLowerCase();
13179
13081
  for (let i = 0; i < AGENTS_MD_SUMMARY_PRIORITY_KEYWORDS.length; i += 1) {
@@ -13207,7 +13109,7 @@ var collectAgentsMdSummaryItems = (content) => {
13207
13109
  items.push({
13208
13110
  section,
13209
13111
  label,
13210
- gist: clipToChars(firstSentence, AGENTS_MD_SUMMARY_ITEM_MAX_CHARS),
13112
+ gist: buildAgentsMdItemGist(firstSentence, bullet[1]),
13211
13113
  priority: priorityOf(label)
13212
13114
  });
13213
13115
  }
@@ -13230,8 +13132,9 @@ ${AGENTS_MD_SUMMARY_DELETE_REFERENCE}
13230
13132
  ...items.filter((item) => item.priority >= 0).sort((a, b) => a.priority - b.priority),
13231
13133
  ...items.filter((item) => item.priority < 0)
13232
13134
  ];
13233
- const note = "\u2026\uFF08\u7D22\u5F15\u5DF2\u622A\u65AD\uFF0C\u5176\u4F59\u951A\u70B9\u89C1\u5B8C\u6574\u6587\u4EF6\uFF09";
13234
- 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");
13235
13138
  let used = Buffer.byteLength(head, "utf8");
13236
13139
  const admitted = [];
13237
13140
  const seenSections = /* @__PURE__ */ new Set();
@@ -13265,8 +13168,7 @@ ${line}`, "utf8");
13265
13168
  }
13266
13169
  }
13267
13170
  if (admitted.length === 0) return null;
13268
- return `${head}${renderSummarySections(frozen)}${truncated ? `
13269
- ${note}` : ""}`;
13171
+ return `${head}${renderSummarySections(frozen)}${truncated ? noteBlock : ""}`;
13270
13172
  }
13271
13173
  var renderSummarySections = (entries) => {
13272
13174
  let rendered = "";
@@ -13284,7 +13186,7 @@ ${entry.line}`;
13284
13186
  };
13285
13187
  function readAgentsMdLayerFromDisk(cwd) {
13286
13188
  for (const name of AGENTS_MD_CANDIDATES) {
13287
- const filePath = resolve2(cwd, name);
13189
+ const filePath = resolve4(cwd, name);
13288
13190
  if (!existsSync2(filePath)) continue;
13289
13191
  try {
13290
13192
  const raw = readFileSync3(filePath, "utf8");
@@ -13426,16 +13328,16 @@ function runDoDCommands(commands, cwd, deps = {}) {
13426
13328
 
13427
13329
  // packages/cli/agentRunPrompts.ts
13428
13330
  import { existsSync as existsSync3, readFileSync as readFileSync4, readdirSync, statSync as statSync2 } from "node:fs";
13429
- 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";
13430
13332
  function workflowRefToCandidatePath(cwd, ref) {
13431
13333
  const normalized = ref.trim();
13432
13334
  if (!normalized) return "";
13433
13335
  if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
13434
- const directPath = resolve3(cwd, normalized);
13336
+ const directPath = resolve5(cwd, normalized);
13435
13337
  if (existsSync3(directPath)) return directPath;
13436
13338
  }
13437
13339
  const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
13438
- return resolve3(cwd, "docs", "workflows", `${fileName}.md`);
13340
+ return resolve5(cwd, "docs", "workflows", `${fileName}.md`);
13439
13341
  }
13440
13342
  var SKILL_SEARCH_DIRS = [
13441
13343
  ".agents/skills"
@@ -13444,15 +13346,15 @@ function skillRefToCandidatePath(cwd, ref) {
13444
13346
  const normalized = ref.trim();
13445
13347
  if (!normalized) return "";
13446
13348
  if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
13447
- const directPath = resolve3(cwd, normalized);
13349
+ const directPath = resolve5(cwd, normalized);
13448
13350
  if (existsSync3(directPath)) return directPath;
13449
13351
  }
13450
13352
  const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
13451
13353
  for (const dir of SKILL_SEARCH_DIRS) {
13452
- const skillMdPath = resolve3(cwd, dir, fileName, "SKILL.md");
13354
+ const skillMdPath = resolve5(cwd, dir, fileName, "SKILL.md");
13453
13355
  if (existsSync3(skillMdPath)) return skillMdPath;
13454
13356
  }
13455
- return resolve3(cwd, ".agents", "skills", fileName, "SKILL.md");
13357
+ return resolve5(cwd, ".agents", "skills", fileName, "SKILL.md");
13456
13358
  }
13457
13359
  async function resolveWorkflowReference(ref, cwd = process.cwd()) {
13458
13360
  const path2 = workflowRefToCandidatePath(cwd, ref);
@@ -13469,11 +13371,11 @@ async function resolveWorkflowReference(ref, cwd = process.cwd()) {
13469
13371
  }
13470
13372
  function inlineRelativeRefs(body, skillDir) {
13471
13373
  const refPattern = /\[([^\]]+)\]\((\.\/[^)]+|[^)]+\/[^)]+)\)/g;
13472
- const normalizedSkillDir = resolve3(skillDir) + sep;
13374
+ const normalizedSkillDir = resolve5(skillDir) + sep;
13473
13375
  return body.replace(refPattern, (match, label, relPath) => {
13474
13376
  const cleaned = relPath.trim();
13475
13377
  if (!cleaned.startsWith("./") && !cleaned.startsWith("../")) return match;
13476
- const absPath = resolve3(skillDir, cleaned);
13378
+ const absPath = resolve5(skillDir, cleaned);
13477
13379
  const relative = relativePath(normalizedSkillDir, absPath);
13478
13380
  if (relative.startsWith("..") || isAbsolute2(relative)) return match;
13479
13381
  if (!existsSync3(absPath) || !absPath.endsWith(".md")) return match;
@@ -13623,7 +13525,7 @@ function prependSubjectDialogMarker(message, subjectDialogKey) {
13623
13525
  }
13624
13526
  function normalizeCliImageInput(input) {
13625
13527
  if (/^(https?:|data:|file:)/i.test(input)) return input;
13626
- const absolutePath = resolve3(input);
13528
+ const absolutePath = resolve5(input);
13627
13529
  if (!existsSync3(absolutePath)) return input;
13628
13530
  const base64 = readFileSync4(absolutePath).toString("base64");
13629
13531
  return `data:${imageMimeTypeForPath(absolutePath)};base64,${base64}`;
@@ -13642,55 +13544,6 @@ function imageMimeTypeForPath(path2) {
13642
13544
  }
13643
13545
  }
13644
13546
 
13645
- // packages/cli/agentRunLocalWorkspace.ts
13646
- async function runGitForLocalSummary(args, deps = {}) {
13647
- const spawn = deps.spawnProcess ?? spawnProcess;
13648
- const read = deps.readPipeText ?? readPipeText;
13649
- const proc = spawn({
13650
- cmd: ["git", ...args.gitArgs],
13651
- cwd: args.cwd,
13652
- stdout: "pipe",
13653
- stderr: "pipe"
13654
- });
13655
- const [stdout, stderr, exitCode] = await Promise.all([
13656
- read(proc.stdout),
13657
- read(proc.stderr),
13658
- proc.exited
13659
- ]);
13660
- if (exitCode !== 0) {
13661
- throw new Error((stderr || stdout || `git ${args.gitArgs.join(" ")} failed`).trim());
13662
- }
13663
- return stdout.trim();
13664
- }
13665
- async function inspectLocalRunWorkspace(cwd, deps = {}) {
13666
- const run = (gitArgs) => runGitForLocalSummary({ cwd, gitArgs }, deps);
13667
- const status = await run(["status", "--short"]);
13668
- const rawCommit = await run(["log", "-1", "--format=%h%x00%s"]).catch(() => "");
13669
- const [hash, subject] = rawCommit.split("\0");
13670
- return {
13671
- cwd,
13672
- clean: status.trim() === "",
13673
- status,
13674
- ...hash ? { commit: { hash, subject: subject ?? "" } } : {}
13675
- };
13676
- }
13677
- function shouldPrintLocalRunSummary(args) {
13678
- return Boolean(args.localRuntimeCwd && args.parsed.runtimeMode === "local");
13679
- }
13680
- function formatLocalRunSummary(args) {
13681
- return [
13682
- "",
13683
- "[nolo] local run summary",
13684
- `workspace: ${args.inspection.cwd}`,
13685
- ...args.dialogId ? [`dialog: ${args.dialogId}`] : [],
13686
- ...args.inspection.commit ? [`commit: ${args.inspection.commit.hash} ${args.inspection.commit.subject}`] : [],
13687
- `dirty: ${args.inspection.clean ? "clean" : "dirty"}`,
13688
- ...!args.inspection.clean && args.inspection.status.trim() ? [`status:
13689
- ${args.inspection.status.trim()}`] : [],
13690
- ""
13691
- ].join("\n");
13692
- }
13693
-
13694
13547
  // packages/ai/memory/storeShared.ts
13695
13548
  var retrievalCountOf = (item) => item.activationCount ?? 0;
13696
13549
  var touchMemoryItemsInDb = async (db, items, now = (/* @__PURE__ */ new Date()).toISOString()) => {
@@ -13707,367 +13560,6 @@ var touchMemoryItemsInDb = async (db, items, now = (/* @__PURE__ */ new Date()).
13707
13560
  await batch.write();
13708
13561
  };
13709
13562
 
13710
- // packages/ai/memory/constants.ts
13711
- var EXPLICIT_REMEMBER_PREFIX_REGEX = /^(你要记住|请记住|以后记住|记住)[,,。.\s::]*/u;
13712
-
13713
- // packages/ai/memory/source.ts
13714
- var getMemorySourceKind = (item) => {
13715
- if (item.sourceKind) return item.sourceKind;
13716
- if (item.patternKey === "explicit-remember") return "explicit-user-directive";
13717
- if (item.patternKey === "agent-remember" || item.patternKey === "procedural-runbook")
13718
- return "agent-tool";
13719
- if (item.patternKey?.startsWith("dialog-learning:"))
13720
- return "dialog-learning";
13721
- if (item.tags?.includes("understanding-memory"))
13722
- return "inferred-understanding";
13723
- return "agent-tool";
13724
- };
13725
-
13726
- // packages/ai/memory/overlay.ts
13727
- var KIND_TITLES = {
13728
- episodic: "Episodic",
13729
- semantic: "Semantic",
13730
- procedural: "Procedural"
13731
- };
13732
- var estimateTokens = (text) => {
13733
- let cjk = 0;
13734
- let ascii = 0;
13735
- for (const ch of text) {
13736
- const code = ch.codePointAt(0) ?? 0;
13737
- if (code >= 13312 && code <= 40959) cjk += 1;
13738
- else ascii += 1;
13739
- }
13740
- return Math.ceil(cjk * 1.5 + ascii / 4);
13741
- };
13742
- var OVERLAY_HEADER_LINES = [
13743
- "--- Memory (\u76F8\u5173\u65F6\u53C2\u8003\uFF0C\u7528\u6237\u8F93\u5165\u4F18\u5148) ---",
13744
- ""
13745
- ];
13746
- var OVERLAY_HEADER_TOKENS = estimateTokens(OVERLAY_HEADER_LINES.join("\n"));
13747
- var KIND_PRIORITY = {
13748
- semantic: 0,
13749
- procedural: 1,
13750
- episodic: 2
13751
- };
13752
- var FACET_DISPLAY = {
13753
- unfinished: { label: "\u8FD8\u6CA1\u5B9A\u4E0B", strip: "\u8FD8\u6CA1\u51B3\u5B9A" },
13754
- tension: { label: "\u5728\u6743\u8861", strip: "\u5728\u6743\u8861" },
13755
- preference: { label: "\u66F4\u5728\u610F", strip: "\u66F4\u5728\u610F" },
13756
- style: { label: "\u66F4\u504F\u597D", strip: "\u66F4\u559C\u6B22" },
13757
- goal: { label: "\u60F3\u63A8\u8FDB", strip: "\u60F3\u63A8\u8FDB" }
13758
- };
13759
- var INFERRED_SOURCE_KINDS = /* @__PURE__ */ new Set(["inferred-understanding", "dialog-learning"]);
13760
- var isInferredMemory = (item) => INFERRED_SOURCE_KINDS.has(getMemorySourceKind(item));
13761
- var formatFacetContent = (facet, normalized, prefix) => {
13762
- const { label, strip } = FACET_DISPLAY[facet];
13763
- const stripped = normalized.startsWith(strip) ? normalized.slice(strip.length).trim() : normalized;
13764
- return `${prefix}${label} ${stripped}`;
13765
- };
13766
- var normalizeDisplayContent = (item) => {
13767
- const normalized = item.content.trim().replace(EXPLICIT_REMEMBER_PREFIX_REGEX, "").replace(/[。!?!?]+$/u, "").trim();
13768
- if (item.kind === "semantic") {
13769
- if (item.tags?.includes("understanding-memory") && item.facet) {
13770
- return formatFacetContent(item.facet, normalized, "");
13771
- }
13772
- return normalized;
13773
- }
13774
- if (item.kind === "episodic" && (item.patternKey === "explicit-remember" || item.patternKey === "agent-remember")) {
13775
- return normalized;
13776
- }
13777
- if (item.kind === "episodic" && item.tags?.includes("understanding-memory") && item.facet) {
13778
- return formatFacetContent(item.facet, normalized, "\u4E0A\u6B21: ");
13779
- }
13780
- return normalized;
13781
- };
13782
- var pickWithinKind = (list, perKindLimit) => {
13783
- if (perKindLimit <= 0) return [];
13784
- const head = list.slice(0, perKindLimit);
13785
- if (head.length < perKindLimit) return head;
13786
- if (head.some((item) => item.subjectType === "user")) return head;
13787
- const firstUserSubject = list.find((item) => item.subjectType === "user");
13788
- if (!firstUserSubject) return head;
13789
- return [...head.slice(0, perKindLimit - 1), firstUserSubject];
13790
- };
13791
- var DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET = 3200;
13792
- var RESIDENT_MEMORY_OVERLAY_TOKEN_BUDGET = 500;
13793
- 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]";
13794
- var MIN_TRUNCATED_TOKENS = 20;
13795
- var TRUNCATED_SUFFIX = "\u2026\uFF08\u672C\u6761\u5DF2\u622A\u65AD\uFF09";
13796
- var truncateLineToTokens = (lineText, budgetTokens) => {
13797
- if (budgetTokens < MIN_TRUNCATED_TOKENS) return null;
13798
- const suffixTokens = estimateTokens(TRUNCATED_SUFFIX);
13799
- const bodyBudget = budgetTokens - suffixTokens;
13800
- if (bodyBudget < MIN_TRUNCATED_TOKENS / 2) return null;
13801
- let used = 0;
13802
- let cut = 0;
13803
- for (const ch of lineText) {
13804
- const chTokens = estimateTokens(ch);
13805
- if (used + chTokens > bodyBudget) break;
13806
- used += chTokens;
13807
- cut += ch.length;
13808
- }
13809
- if (cut <= 2) return null;
13810
- return `${lineText.slice(0, cut).trimEnd()}${TRUNCATED_SUFFIX}`;
13811
- };
13812
- var fitLinesToBudget = (allLines, remainingBudget) => {
13813
- let usedTokens = 0;
13814
- const keptByKind = {};
13815
- let truncatedCount = 0;
13816
- let droppedCount = 0;
13817
- const pushLine = (kind, lineText) => {
13818
- if (!keptByKind[kind]) keptByKind[kind] = [];
13819
- keptByKind[kind].push(lineText);
13820
- };
13821
- for (const candidate of allLines) {
13822
- const remaining = remainingBudget - usedTokens;
13823
- if (remaining <= 0) {
13824
- droppedCount += 1;
13825
- continue;
13826
- }
13827
- if (candidate.lineTokens <= remaining) {
13828
- usedTokens += candidate.lineTokens;
13829
- pushLine(candidate.kind, candidate.lineText);
13830
- continue;
13831
- }
13832
- const truncated = truncateLineToTokens(candidate.lineText, remaining);
13833
- if (!truncated) {
13834
- droppedCount += 1;
13835
- continue;
13836
- }
13837
- usedTokens += estimateTokens(truncated);
13838
- pushLine(candidate.kind, truncated);
13839
- truncatedCount += 1;
13840
- }
13841
- return { keptByKind, truncatedCount, droppedCount };
13842
- };
13843
- var EMPTY_RETRIEVAL_FIT = {
13844
- keptByKind: {},
13845
- truncatedCount: 0,
13846
- droppedCount: 0
13847
- };
13848
- var EMPTY_RESIDENT_FIT = {
13849
- keptLines: [],
13850
- truncatedCount: 0,
13851
- droppedCount: 0
13852
- };
13853
- var fitResidentLines = (lines, remainingBudget) => {
13854
- let usedTokens = 0;
13855
- const keptLines = [];
13856
- let truncatedCount = 0;
13857
- let droppedCount = 0;
13858
- for (const candidate of lines) {
13859
- const remaining = remainingBudget - usedTokens;
13860
- if (remaining <= 0) {
13861
- droppedCount += 1;
13862
- continue;
13863
- }
13864
- if (candidate.lineTokens <= remaining) {
13865
- usedTokens += candidate.lineTokens;
13866
- keptLines.push(candidate.lineText);
13867
- continue;
13868
- }
13869
- const truncated = truncateLineToTokens(candidate.lineText, remaining);
13870
- if (!truncated) {
13871
- droppedCount += 1;
13872
- continue;
13873
- }
13874
- usedTokens += estimateTokens(truncated);
13875
- keptLines.push(truncated);
13876
- truncatedCount += 1;
13877
- }
13878
- return { keptLines, truncatedCount, droppedCount };
13879
- };
13880
- var buildBudgetFooter = (fit, residentFit) => {
13881
- const notices = [];
13882
- if (residentFit.truncatedCount > 0) {
13883
- notices.push(`${residentFit.truncatedCount} \u6761\u957F\u671F\u504F\u597D\u56E0\u9884\u7B97\u88AB\u622A\u65AD`);
13884
- }
13885
- if (residentFit.droppedCount > 0) {
13886
- notices.push(`${residentFit.droppedCount} \u6761\u957F\u671F\u504F\u597D\u672A\u663E\u793A`);
13887
- }
13888
- if (fit.truncatedCount > 0) {
13889
- notices.push(`${fit.truncatedCount} \u6761\u56E0\u9884\u7B97\u88AB\u622A\u65AD`);
13890
- }
13891
- if (fit.droppedCount > 0) {
13892
- notices.push(`${fit.droppedCount} \u6761\u672A\u663E\u793A`);
13893
- }
13894
- if (notices.length === 0) return [];
13895
- 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`];
13896
- };
13897
- var buildMemoryOverlay = (items, options) => {
13898
- if (items.length === 0) return null;
13899
- const maxTokens = options?.maxTokens ?? DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET;
13900
- const perKindLimit = options?.perKindLimit ?? 3;
13901
- const residentMaxTokens = options?.residentMaxTokens ?? RESIDENT_MEMORY_OVERLAY_TOKEN_BUDGET;
13902
- const residentItems = items.filter((item) => item.resident === true).sort((a, b) => b.createdAt.localeCompare(a.createdAt));
13903
- const retrievalItems = items.filter((item) => item.resident !== true);
13904
- const residentFit = residentItems.length === 0 ? EMPTY_RESIDENT_FIT : fitResidentLines(
13905
- residentItems.map((item) => {
13906
- const lineText = `- ${isInferredMemory(item) ? "\uFF08\u63A8\u65AD\uFF09" : ""}${normalizeDisplayContent(item)}`;
13907
- return { kind: item.kind, lineText, lineTokens: estimateTokens(lineText) };
13908
- }),
13909
- residentMaxTokens - estimateTokens(RESIDENT_SECTION_HEADER)
13910
- );
13911
- const byKind = {
13912
- episodic: [],
13913
- semantic: [],
13914
- procedural: []
13915
- };
13916
- for (const item of retrievalItems) {
13917
- byKind[item.kind].push(item);
13918
- }
13919
- const remainingBudget = maxTokens - OVERLAY_HEADER_TOKENS;
13920
- let retrievalFit = EMPTY_RETRIEVAL_FIT;
13921
- let retrievalSections = [];
13922
- if (remainingBudget > 0 && retrievalItems.length > 0) {
13923
- const allLines = Object.entries(byKind).filter(([, list]) => list.length > 0).flatMap(
13924
- ([kind, list]) => pickWithinKind(list, perKindLimit).map((item) => {
13925
- const lineText = `- ${isInferredMemory(item) ? "\uFF08\u63A8\u65AD\uFF09" : ""}${normalizeDisplayContent(item)}`;
13926
- return { kind, lineText, lineTokens: estimateTokens(lineText) };
13927
- })
13928
- ).sort((a, b) => (KIND_PRIORITY[a.kind] ?? 99) - (KIND_PRIORITY[b.kind] ?? 99));
13929
- retrievalFit = fitLinesToBudget(allLines, remainingBudget);
13930
- const kindOrder = ["semantic", "procedural", "episodic"];
13931
- retrievalSections = kindOrder.filter(
13932
- (kind) => retrievalFit.keptByKind[kind] && retrievalFit.keptByKind[kind].length > 0
13933
- ).map((kind) => {
13934
- return [`[${KIND_TITLES[kind]}]`, ...retrievalFit.keptByKind[kind]].join("\n");
13935
- });
13936
- }
13937
- const sections = [
13938
- ...residentFit.keptLines.length > 0 ? [[RESIDENT_SECTION_HEADER, ...residentFit.keptLines].join("\n")] : [],
13939
- ...retrievalSections
13940
- ];
13941
- if (sections.length === 0) {
13942
- return OVERLAY_HEADER_LINES.join("\n");
13943
- }
13944
- return [
13945
- ...OVERLAY_HEADER_LINES,
13946
- ...sections,
13947
- ...buildBudgetFooter(retrievalFit, residentFit)
13948
- ].join("\n");
13949
- };
13950
-
13951
- // packages/ai/memory/rank.ts
13952
- var CJK_SEQUENCE_REGEX = /[\u3400-\u4dbf\u4e00-\u9fff]+/g;
13953
- var MEMORY_IDENTIFIER_REGEX = /\b(?:memory|noise)-[a-z0-9][a-z0-9-]*/gi;
13954
- var buildCjkTokens = (text) => {
13955
- const sequences = text.match(CJK_SEQUENCE_REGEX) ?? [];
13956
- const tokens = [];
13957
- for (const sequence2 of sequences) {
13958
- if (sequence2.length >= 2) {
13959
- tokens.push(sequence2);
13960
- }
13961
- for (let index = 0; index < sequence2.length - 1; index += 1) {
13962
- tokens.push(sequence2.slice(index, index + 2));
13963
- }
13964
- }
13965
- return tokens;
13966
- };
13967
- var tokenize2 = (text) => {
13968
- const normalized = text.toLowerCase();
13969
- const wordTokens = normalized.split(/[\s,.;:!?()[\]{}"'`,。!?:;、]+/).map((token) => token.trim()).filter((token) => token.length >= 2);
13970
- return [...wordTokens, ...buildCjkTokens(normalized)];
13971
- };
13972
- var keywordScore = (query, item) => {
13973
- const queryTokens = new Set(tokenize2(query));
13974
- if (queryTokens.size === 0) return 0;
13975
- const haystack = /* @__PURE__ */ new Set([
13976
- ...tokenize2(item.content),
13977
- ...(item.tags ?? []).map((tag) => tag.toLowerCase()),
13978
- item.patternKey?.toLowerCase() ?? ""
13979
- ]);
13980
- let matches = 0;
13981
- for (const token of queryTokens) {
13982
- if (haystack.has(token)) matches += 1;
13983
- }
13984
- return Math.min(1, matches / Math.max(2, queryTokens.size));
13985
- };
13986
- var identifierScore = (query, item) => {
13987
- const identifiers = query.match(MEMORY_IDENTIFIER_REGEX) ?? [];
13988
- if (identifiers.length === 0) return 0;
13989
- const content = item.content.toLowerCase();
13990
- const matches = identifiers.filter(
13991
- (identifier) => content.includes(identifier.toLowerCase())
13992
- ).length;
13993
- return matches / identifiers.length;
13994
- };
13995
- var DAY_MS = 864e5;
13996
- var UNRETRIEVED_MEMORY_GRACE_DAYS = 3;
13997
- var MIN_UNRETRIEVED_SCORE_FACTOR = 0.3;
13998
- var UNRETRIEVED_DECAY_HALF_LIFE_DAYS = 7;
13999
- var retrievalFrequencyScore = (item, nowMs) => {
14000
- const lastRetrievedMs = Date.parse(item.lastActivatedAt || item.createdAt);
14001
- const ageDays = Math.max(0, (nowMs - lastRetrievedMs) / DAY_MS);
14002
- const recency = 1 / (1 + ageDays / 7);
14003
- const frequency = Math.min(1, Math.log1p(item.activationCount ?? 0) / 3);
14004
- return 0.7 * recency + 0.3 * frequency;
14005
- };
14006
- var unretrievedDecayFactor = (item, nowMs) => {
14007
- if ((item.activationCount ?? 0) !== 0) return 1;
14008
- const createdAgeDays = Math.max(0, (nowMs - Date.parse(item.createdAt)) / DAY_MS);
14009
- if (createdAgeDays <= UNRETRIEVED_MEMORY_GRACE_DAYS) return 1;
14010
- const overdue = createdAgeDays - UNRETRIEVED_MEMORY_GRACE_DAYS;
14011
- return Math.max(
14012
- MIN_UNRETRIEVED_SCORE_FACTOR,
14013
- 1 / (1 + overdue / UNRETRIEVED_DECAY_HALF_LIFE_DAYS)
14014
- );
14015
- };
14016
- var retrievalScore = (item, nowMs) => retrievalFrequencyScore(item, nowMs) * unretrievedDecayFactor(item, nowMs);
14017
- var creationRecencyScore = (item, nowMs) => {
14018
- const createdMs = Date.parse(item.createdAt);
14019
- const ageDays = Math.max(0, (nowMs - createdMs) / 864e5);
14020
- return 1 / (1 + ageDays / 7);
14021
- };
14022
- var typeFitScore = (item) => {
14023
- if (item.kind === "episodic") return 0.75;
14024
- if (item.kind === "semantic") return 0.9;
14025
- return 0.85;
14026
- };
14027
- var understandingScore = (item) => {
14028
- if (!item.tags?.includes("understanding-memory")) return 0;
14029
- if (item.facet === "unfinished") return 1;
14030
- if (item.facet === "tension") return 0.95;
14031
- if (item.facet === "preference") return 0.85;
14032
- if (item.facet === "style") return 0.75;
14033
- return 0.8;
14034
- };
14035
- var pathScore = (item, context) => {
14036
- let score = 0;
14037
- if (context?.currentOwner && item.ownerType === context.currentOwner.ownerType && item.ownerId === context.currentOwner.ownerId) {
14038
- score += 0.65;
14039
- }
14040
- if (context?.currentSubject && item.subjectType === context.currentSubject.subjectType && item.subjectId === context.currentSubject.subjectId) {
14041
- score += 0.85;
14042
- }
14043
- return Math.min(1, score);
14044
- };
14045
- var scoreMemoryItem = (item, query, nowMs = Date.now(), context) => {
14046
- const queryMatch = keywordScore(query, item);
14047
- const identifierMatch = identifierScore(query, item);
14048
- const retrieval = retrievalScore(item, nowMs);
14049
- const createdRecency = creationRecencyScore(item, nowMs);
14050
- const importance = item.importance ?? 0;
14051
- const confidence = item.confidence ?? 0;
14052
- const typeFit = typeFitScore(item);
14053
- const understanding = understandingScore(item);
14054
- const path2 = pathScore(item, context);
14055
- return 0.25 * queryMatch + 0.2 * identifierMatch + 0.2 * path2 + 0.09 * retrieval + // weak retrieval signal, NOT successful-use reinforcement
14056
- 0.16 * createdRecency + 0.06 * importance + 0.03 * confidence + 0.02 * typeFit + 0.01 * understanding;
14057
- };
14058
- var rankMemoryCandidates = (items, query, context) => {
14059
- const nowMs = Date.now();
14060
- return [...items].sort((a, b) => {
14061
- const aExplicit = a.sourceKind === "explicit-user-directive";
14062
- const bExplicit = b.sourceKind === "explicit-user-directive";
14063
- if (aExplicit !== bExplicit) return bExplicit ? 1 : -1;
14064
- if (aExplicit) {
14065
- return Date.parse(b.createdAt) - Date.parse(a.createdAt);
14066
- }
14067
- return scoreMemoryItem(b, query, nowMs, context) - scoreMemoryItem(a, query, nowMs, context);
14068
- });
14069
- };
14070
-
14071
13563
  // packages/ai/memory/vnext/detachedThrottle.ts
14072
13564
  var DEFAULT_DETACHED_MEMORY_COOLDOWN_MS = 10 * 60 * 1e3;
14073
13565
  var MAX_COOLDOWN_KEYS = 512;
@@ -14236,43 +13728,6 @@ ${catalogText(entities, states)}`
14236
13728
  };
14237
13729
  };
14238
13730
 
14239
- // packages/ai/memory/vnext/legacyMigration.ts
14240
- import { createHash } from "crypto";
14241
- var LEGACY_MEMORY_SOURCE_REF_PREFIX = "legacy-memory";
14242
- var LEGACY_MEMORY_EVIDENCE_ID_PREFIX = "mem-legacy-";
14243
- var resolveLegacyMemoryPrincipal = (item) => ({
14244
- ownerType: item.ownerType,
14245
- ownerId: item.ownerId,
14246
- principalId: `${item.ownerType}:${encodeURIComponent(item.ownerId)}`
14247
- });
14248
- var buildLegacyMemorySourceRef = (item) => {
14249
- const { principalId } = resolveLegacyMemoryPrincipal(item);
14250
- return `${LEGACY_MEMORY_SOURCE_REF_PREFIX}:${principalId}:${encodeURIComponent(item.id)}`;
14251
- };
14252
- var legacyEvidenceSeed = (principalId, itemId) => JSON.stringify([principalId, itemId]);
14253
- var buildLegacyEvidenceId = (item) => {
14254
- const { principalId } = resolveLegacyMemoryPrincipal(item);
14255
- const digest = createHash("sha256").update(legacyEvidenceSeed(principalId, item.id)).digest("hex");
14256
- return `${LEGACY_MEMORY_EVIDENCE_ID_PREFIX}${digest.slice(0, 32)}`;
14257
- };
14258
- var clampLegacyConfidence = (value) => {
14259
- if (typeof value !== "number" || !Number.isFinite(value)) return 0;
14260
- if (value < 0) return 0;
14261
- if (value > 1) return 1;
14262
- return value;
14263
- };
14264
- var buildLegacyMemoryEvidence = (item) => {
14265
- const { principalId } = resolveLegacyMemoryPrincipal(item);
14266
- return {
14267
- id: buildLegacyEvidenceId(item),
14268
- ownerId: principalId,
14269
- text: item.content,
14270
- sourceRef: buildLegacyMemorySourceRef(item),
14271
- confidence: clampLegacyConfidence(item.confidence),
14272
- createdAt: item.createdAt
14273
- };
14274
- };
14275
-
14276
13731
  // packages/ai/memory/vnext/shadowRead.ts
14277
13732
  var SHADOW_TIMEOUT_MS = 2e4;
14278
13733
  var ERROR_MESSAGE_MAX = 120;
@@ -14686,7 +14141,7 @@ var MEMORY_RELATION_TYPES = [
14686
14141
  var isObject = (value) => !!value && typeof value === "object" && !Array.isArray(value);
14687
14142
  var isString = (value) => typeof value === "string" && value.trim().length > 0;
14688
14143
  var isStringArray = (value) => Array.isArray(value) && value.every(isString);
14689
- 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);
14690
14145
  var ACTIONS = /* @__PURE__ */ new Set([
14691
14146
  "no_op",
14692
14147
  "create",
@@ -15269,45 +14724,6 @@ var isMemoryVNextLazyPromotionEnabled = (env = typeof process !== "undefined" ?
15269
14724
  // packages/ai/memory/vnext/pureReadGate.ts
15270
14725
  var isMemoryVNextPureReadEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_PURE_READ === "1" || env.NOLO_MEMORY_VNEXT_PURE_READ === "true";
15271
14726
 
15272
- // packages/ai/memory/vnext/localRecall.ts
15273
- var MIN_SHARED_TOKENS = 2;
15274
- var MAX_LOCAL_RECALL_STATES = 8;
15275
- var SAFE_TECHNICAL_SYNONYMS = {
15276
- pr: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5", "diff"],
15277
- diff: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5"],
15278
- review: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5"],
15279
- deploy: ["\u90E8\u7F72", "\u53D1\u7248"],
15280
- release: ["\u53D1\u7248", "\u53D1\u5E03"],
15281
- desktop: ["\u684C\u9762", "\u684C\u9762\u7AEF"]
15282
- };
15283
- var distinctTokens = (text) => new Set(tokenize2(text).filter((token) => token.length >= 2));
15284
- var recallMemoryVNextLocal = (input) => {
15285
- const rawTokens = distinctTokens(input.query);
15286
- if (rawTokens.size === 0) return [];
15287
- const queryTokens = new Set(rawTokens);
15288
- for (const token of rawTokens) {
15289
- const syns = SAFE_TECHNICAL_SYNONYMS[token.toLowerCase()];
15290
- if (syns) {
15291
- for (const syn of syns) {
15292
- for (const t2 of distinctTokens(syn)) queryTokens.add(t2);
15293
- }
15294
- }
15295
- }
15296
- const entityById = new Map(input.entities.map((entity) => [entity.id, entity]));
15297
- const hits = [];
15298
- for (const state2 of input.states) {
15299
- if (state2.retiredAt || !state2.text.trim()) continue;
15300
- const entity = entityById.get(state2.entityId);
15301
- const haystack = distinctTokens(
15302
- [state2.facet, state2.text, entity?.name ?? "", ...entity?.aliases ?? []].join(" ")
15303
- );
15304
- let sharedTokens = 0;
15305
- for (const token of queryTokens) if (haystack.has(token)) sharedTokens++;
15306
- if (sharedTokens >= MIN_SHARED_TOKENS) hits.push({ state: state2, sharedTokens });
15307
- }
15308
- return hits.sort((a, b) => b.sharedTokens - a.sharedTokens || a.state.id.localeCompare(b.state.id)).slice(0, input.limit ?? MAX_LOCAL_RECALL_STATES);
15309
- };
15310
-
15311
14727
  // packages/ai/memory/vnext/pureVNextRuntime.ts
15312
14728
  var buildSynthesizedStateItem = (state2, entity, ownerType, ownerId) => ({
15313
14729
  id: `vnext-state-${state2.id}`,
@@ -15908,11 +15324,49 @@ async function runAgentRunCommand(args, deps) {
15908
15324
  writeUsage(output, deps.commandPath);
15909
15325
  return 1;
15910
15326
  }
15911
- 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
+ };
15912
15352
  const nowMs = () => deps.now ? deps.now().getTime() : Date.now();
15913
- const childRunId = env.NOLO_AGENT_RUN_ID;
15914
- const hasRegistry = typeof childRunId === "string" && childRunId.length > 0;
15915
- 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 });
15916
15370
  const processExit = deps.processExit ?? ((code) => process.exit(code));
15917
15371
  const stallTimeoutMs = resolvePositiveMs(
15918
15372
  deps.stallTimeoutMs ?? env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS,
@@ -15954,9 +15408,9 @@ async function runAgentRunCommand(args, deps) {
15954
15408
  throw error;
15955
15409
  });
15956
15410
  };
15957
- const exitFromWatchdog = (code) => {
15411
+ const exitFromWatchdog = async (code) => {
15958
15412
  try {
15959
- processExit(code);
15413
+ await exitCliFromWatchdog(code, processExit, stopWatchdogRunner);
15960
15414
  } catch {
15961
15415
  }
15962
15416
  };
@@ -16003,8 +15457,8 @@ async function runAgentRunCommand(args, deps) {
16003
15457
  failureReason: "stalled",
16004
15458
  toolCallCount: currentActivity?.counters?.toolCalls
16005
15459
  });
15460
+ await exitFromWatchdog(outcome.exitCode);
16006
15461
  rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
16007
- exitFromWatchdog(outcome.exitCode);
16008
15462
  }
16009
15463
  }, Math.min(stallTimeoutMs, 1e4));
16010
15464
  }
@@ -16018,8 +15472,8 @@ async function runAgentRunCommand(args, deps) {
16018
15472
  terminalStatus.fail();
16019
15473
  const outcome = resolveRunOutcome({ kind: "timeout" });
16020
15474
  await finalizeWatchdogOutcome(outcome, note);
15475
+ await exitFromWatchdog(outcome.exitCode);
16021
15476
  rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
16022
- exitFromWatchdog(outcome.exitCode);
16023
15477
  }, parsed.timeoutMs);
16024
15478
  }
16025
15479
  const wantsFallbackSuggestions = parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0;
@@ -16028,8 +15482,8 @@ async function runAgentRunCommand(args, deps) {
16028
15482
  const explicitLocalCli = isLocalCliAgentKey(parsed.agentKey);
16029
15483
  const dockerRuntimeLocal = typeof parsed.runtimeKey === "string" && /^docker(:.+)?$/.test(parsed.runtimeKey.trim());
16030
15484
  const instaboxRuntimeLocal = typeof parsed.runtimeKey === "string" && parsed.runtimeKey.trim() === "instabox";
16031
- const hostRuntimeLocal = typeof parsed.runtimeKey === "string" && parsed.runtimeKey.trim() === "local";
16032
- 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")) {
16033
15487
  output.write(t("agentRun.hostWriteGuard"));
16034
15488
  return 1;
16035
15489
  }
@@ -16166,6 +15620,9 @@ async function runAgentRunCommand(args, deps) {
16166
15620
  if (!localRuntimeCwd && (parsed.runtimeMode === "local" || hostRuntimeLocal)) {
16167
15621
  localRuntimeCwd = process.cwd();
16168
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;
16169
15626
  if (parsed.runtimeKey === "instabox") {
16170
15627
  try {
16171
15628
  writeInstaboxRunConfig({
@@ -16193,9 +15650,20 @@ async function runAgentRunCommand(args, deps) {
16193
15650
  cliEntrypointPath: deps.cliEntrypointPath,
16194
15651
  agentKey,
16195
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 } : {},
16196
15663
  msgFile: readFlagValue(args, "--msg-file"),
16197
15664
  message: parsed.message,
16198
15665
  timeoutMs: parsed.timeoutMs,
15666
+ ...parsed.ephemeral ? { ephemeral: true } : {},
16199
15667
  ...parsed.dodCommands?.length ? { dodCommands: parsed.dodCommands } : {},
16200
15668
  output
16201
15669
  },
@@ -16225,6 +15693,15 @@ async function runAgentRunCommand(args, deps) {
16225
15693
  const isSubtask = isSubtaskRun(env);
16226
15694
  const scopedLayers = [];
16227
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
+ }
16228
15705
  const extraContextBlocks = [];
16229
15706
  const contextBlockScopes = [];
16230
15707
  let memoryPromptBlock = null;
@@ -16355,6 +15832,7 @@ async function runAgentRunCommand(args, deps) {
16355
15832
  })
16356
15833
  );
16357
15834
  clearWatchdogs();
15835
+ const runCommandObservations = [...getRunResultHeaderMeta(result).commandObservations ?? []];
16358
15836
  let runCreditsTotal = result.turnCredits;
16359
15837
  let runCacheUsage = summarizeCacheUsageRecords(result.usageRecords);
16360
15838
  if (result.exitCode !== 0 && isQuotaExhaustedError(result.localError) && isLocalRun && parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0) {
@@ -16370,6 +15848,7 @@ async function runAgentRunCommand(args, deps) {
16370
15848
  })
16371
15849
  );
16372
15850
  clearWatchdogs();
15851
+ runCommandObservations.push(...getRunResultHeaderMeta(fallbackResult).commandObservations ?? []);
16373
15852
  if (fallbackResult.exitCode === 0) {
16374
15853
  result = fallbackResult;
16375
15854
  }
@@ -16422,6 +15901,7 @@ async function runAgentRunCommand(args, deps) {
16422
15901
  })
16423
15902
  );
16424
15903
  clearWatchdogs();
15904
+ runCommandObservations.push(...getRunResultHeaderMeta(turnResult).commandObservations ?? []);
16425
15905
  result = turnResult;
16426
15906
  if (turnResult.turnCredits !== void 0) {
16427
15907
  runCreditsTotal = (runCreditsTotal ?? 0) + turnResult.turnCredits;
@@ -16450,11 +15930,6 @@ async function runAgentRunCommand(args, deps) {
16450
15930
  );
16451
15931
  }
16452
15932
  }
16453
- terminalStatus.settle({
16454
- exitCode: result.exitCode,
16455
- streamInterrupted: result.streamInterrupted,
16456
- stalledOrTruncated: isRunResultStalledOrTruncated(result)
16457
- });
16458
15933
  if (result.dialogId) {
16459
15934
  if (parsed.background) {
16460
15935
  output.write(`
@@ -16468,11 +15943,12 @@ async function runAgentRunCommand(args, deps) {
16468
15943
  `);
16469
15944
  }
16470
15945
  }
16471
- if (shouldPrintLocalRunSummary({ parsed, localRuntimeCwd })) {
15946
+ if (acceptanceCwd || shouldPrintLocalRunSummary({ parsed, localRuntimeCwd })) {
16472
15947
  try {
16473
15948
  const inspect = deps.inspectLocalRunWorkspace ?? inspectLocalRunWorkspace;
16474
- const inspection = await inspect(localRuntimeCwd);
16475
- output.write(formatLocalRunSummary({
15949
+ const inspection = await inspect(localRuntimeCwd, {}, acceptanceCwd ? acceptanceBase : void 0);
15950
+ finalWorkspaceInspection = inspection;
15951
+ if (shouldPrintLocalRunSummary({ parsed, localRuntimeCwd })) output.write(formatLocalRunSummary({
16476
15952
  dialogId: result.dialogId,
16477
15953
  inspection
16478
15954
  }));
@@ -16511,6 +15987,8 @@ async function runAgentRunCommand(args, deps) {
16511
15987
  if (outcome.status === "failed") {
16512
15988
  if (result.emptyAssistantFallbackReason === "repetition_loop" || result.emptyAssistantFallbackReason === "stagnant_tool_calls") {
16513
15989
  failureReason = "stalled";
15990
+ } else if (result.localError && isHistoryIntegrityFailure(toErrorMessage(result.localError))) {
15991
+ failureReason = "history_integrity";
16514
15992
  } else if (result.localError && isQuotaExhaustedError(result.localError)) {
16515
15993
  failureReason = "provider_rate_limited";
16516
15994
  } else if (result.localError) {
@@ -16527,37 +16005,74 @@ async function runAgentRunCommand(args, deps) {
16527
16005
  toolCallCount = rawToolCount;
16528
16006
  }
16529
16007
  }
16530
- await settleRunTerminalAuthoritatively(
16531
- childRunId,
16532
- {
16533
- status: outcome.status,
16534
- exitCode: outcome.exitCode,
16535
- dialogId: result.dialogId,
16536
- ...dodResults ? { dodResults } : {},
16537
- // run 级累计的平台积分(主轮 + fallback + drain 轮):dock 行据此显示
16538
- // 「⚡ x.xx」,让派发任务的消耗可见。undefined = 全程无平台计费。
16539
- ...runCreditsTotal !== void 0 ? { credits: runCreditsTotal } : {},
16540
- // run 级缓存命中汇总:只进 .result.md 的 front matter(cached_tokens
16541
- // 为 null 表示 provider 未报缓存指标,与「命中 0」严格区分)。
16542
- ...runCacheUsage ? { cacheUsage: runCacheUsage } : {},
16543
- ...failureReason ? { failureReason } : {},
16544
- ...toolCallCount !== void 0 ? { toolCallCount } : {},
16545
- ...result.finalText ? { lastAssistantText: result.finalText } : {},
16546
- // 仅用于 .result.md 头(front matter):旁路读取,不改 result 形状。
16547
- ...getRunResultHeaderMeta(result),
16548
- ...truncationNote
16549
- },
16550
- {
16551
- env,
16552
- homedir: deps.homedir,
16553
- fs: deps.fs,
16554
- now: deps.now,
16555
- sleep: deps.sleep
16556
- },
16557
- 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`
16558
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
+ }
16559
16066
  }
16067
+ terminalStatus.settle({
16068
+ exitCode: result.exitCode,
16069
+ streamInterrupted: result.streamInterrupted,
16070
+ stalledOrTruncated: isRunResultStalledOrTruncated(result)
16071
+ });
16560
16072
  return result.exitCode;
16073
+ } catch (error) {
16074
+ terminalStatus.fail();
16075
+ throw error;
16561
16076
  } finally {
16562
16077
  shellApprovalChild?.close();
16563
16078
  if (shellApprovalChild && process.connected) process.disconnect();
@@ -16567,22 +16082,6 @@ async function runAgentRunCommand(args, deps) {
16567
16082
  export {
16568
16083
  resolveCliColorEnabled,
16569
16084
  dimCliText,
16570
- ANSI_ESCAPE_REGEX,
16571
- stripAnsi2 as stripAnsi,
16572
- applyTerminalOutputToText,
16573
- displayWidth,
16574
- visibleWidth,
16575
- truncateAnsi,
16576
- fitAnsiLine,
16577
- countPhysicalLines,
16578
- takeDisplayWidth,
16579
- padOrTruncateToWidth,
16580
- tokenizeAnsiLine,
16581
- buildSourceMapping,
16582
- wrapTranscriptLineWithLayout,
16583
- wrapTranscriptLine,
16584
- buildWindowTitle,
16585
- wrapTextToLines,
16586
16085
  THEME_PALETTES,
16587
16086
  getActiveThemeName,
16588
16087
  setActiveThemeName,
@@ -16604,9 +16103,10 @@ export {
16604
16103
  setMathRenderingEnabled,
16605
16104
  polishBreathInsertsBlankBetween,
16606
16105
  formatAssistantDisplay,
16607
- redactSecrets,
16608
- safeAskText,
16106
+ resolveHistoryLayoutGeometry,
16107
+ resolveHistoryViewportHeight,
16609
16108
  TUI_TREE_MARKER,
16109
+ TUI_TREE_TOOLS,
16610
16110
  resolveAgentModelIdentity,
16611
16111
  resolveAgentContextWindow2 as resolveAgentContextWindow,
16612
16112
  platformCreditsFromUsage,
@@ -16614,6 +16114,7 @@ export {
16614
16114
  formatTokenCount,
16615
16115
  resolveAuthorityTurnCount,
16616
16116
  computeBaselineContextTokens,
16117
+ preserveContextUsageWithoutReceipt,
16617
16118
  resolveContextUsage,
16618
16119
  renderTokenStatus,
16619
16120
  createIdleHeapReleaser,
@@ -16629,10 +16130,13 @@ export {
16629
16130
  findCollapsedPasteSpanAt,
16630
16131
  readAgentsMdLayerFromDisk,
16631
16132
  emitTerminalProgramStatus,
16133
+ contextRefusalDiagnostics,
16134
+ describeContextRefusal,
16632
16135
  isBalanceExhaustedError,
16633
16136
  OWNER_OAUTH_UNAVAILABLE_HINT,
16634
16137
  isOwnerOAuthUnavailableError,
16635
16138
  isInvalidGrantError,
16139
+ isLocalContextCoverageFailure,
16636
16140
  runAgentTurn,
16637
16141
  resolveWorkflowReference,
16638
16142
  resolveSkillReference,
@@ -16644,7 +16148,6 @@ export {
16644
16148
  FAILED_EMPTY_ASSISTANT_REASONS,
16645
16149
  isRunResultStalledOrTruncated,
16646
16150
  resolveTerminalProgramStatusState,
16647
- inspectLocalRunWorkspace,
16648
16151
  resolveRunOutcome,
16649
16152
  resolveRunSettlementNote,
16650
16153
  runAgentRunCommand