nolo-cli 0.107.0-alpha.3 → 0.107.0

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 (209) hide show
  1. package/README.md +1 -1
  2. package/{_executeModel-UDCSOTD2.js → _executeModel-C4EH5TZG.js} +77 -69
  3. package/action-GVA5ARSJ.js +20 -0
  4. package/{addContentAction-MB2HHMDZ.js → addContentAction-M2WOWZCL.js} +13 -12
  5. package/{addDialogAgentAction-MCEABSBA.js → addDialogAgentAction-QMAQ5Z6N.js} +19 -20
  6. package/{agentDeleteCommand-OWYHN6D6.js → agentDeleteCommand-D3RICSHX.js} +118 -43
  7. package/{agentEmailCommands-BQFXQIHF.js → agentEmailCommands-YC2A4USQ.js} +99 -89
  8. package/agentListCommands-UDJELMYP.js +741 -0
  9. package/{agentMachineCommands-6DTI7YSG.js → agentMachineCommands-XH4IBGTO.js} +48 -44
  10. package/{agentProviderCommands-GNPTL5XR.js → agentProviderCommands-CMVTBY5X.js} +97 -2
  11. package/{agentPullCommand-O5MPVJ5E.js → agentPullCommand-B4T2DJ5H.js} +1 -1
  12. package/agentRecordCommands-3EOC2QMN.js +138 -0
  13. package/agentRunCommand-BTHYOVVS.js +167 -0
  14. package/{agentRunControl-AVJR4JW4.js → agentRunControl-3HWA2LLQ.js} +2 -2
  15. package/{agentRuntimeLocal-KCMC2TBD.js → agentRuntimeLocal-N4YGKL7M.js} +44 -40
  16. package/{agentSlice-R7PR6KYM.js → agentSlice-NIN4T6CF.js} +15 -14
  17. package/{appDeleteCommands-JEPA3EWE.js → appDeleteCommands-7DAF33AM.js} +46 -42
  18. package/{appDeployCommands-UTB76XFM.js → appDeployCommands-ZPZSMFGZ.js} +46 -42
  19. package/{appDeployStatusCommands-LGHF2SBD.js → appDeployStatusCommands-FWBDSSS5.js} +46 -42
  20. package/{appGetCommands-PX2BFHOB.js → appGetCommands-SZZOHGEP.js} +46 -42
  21. package/{appListCommands-BSMPTWKC.js → appListCommands-FPMUBDPM.js} +46 -42
  22. package/{authCommand-YW42YZA4.js → authCommand-VL3G26NQ.js} +119 -25
  23. package/{authCommands-RGOGCPP6.js → authCommands-5RTUDYZW.js} +7 -5
  24. package/{builtinSkillRegistry-FUAVTRVZ.js → builtinSkillRegistry-ZK4K67Y5.js} +11 -9
  25. package/{chromeCommands-FZYAU75D.js → chromeCommands-AU5ZJXBG.js} +289 -37
  26. package/{chromeOpsCommands-62P2Q2YB.js → chromeOpsCommands-ZYTCMNHG.js} +156 -22
  27. package/{chunk-JDPFV2JV.js → chunk-2NNRWRM5.js} +20 -11
  28. package/{chunk-JEDZAO7L.js → chunk-2SYTUTLI.js} +257 -37
  29. package/{chunk-HVURBGF3.js → chunk-2U3NHADM.js} +6 -6
  30. package/{chunk-AVTT555J.js → chunk-2ZHBFX5R.js} +29 -9
  31. package/{chunk-QTGQ2LTL.js → chunk-3DQY5IFB.js} +6 -10
  32. package/chunk-4LCOCOR5.js +50 -0
  33. package/{chunk-JPGCXHNM.js → chunk-4LKMZ3RR.js} +1 -1
  34. package/{chunk-2GRGFCF6.js → chunk-4VJAC32I.js} +2 -1
  35. package/{chunk-6D6VBVEW.js → chunk-4W24JM32.js} +80 -14
  36. package/{chunk-MC4XLIJ7.js → chunk-523DITKR.js} +1 -1
  37. package/{chunk-E4MARS3Q.js → chunk-5GVBDNTO.js} +1 -1
  38. package/chunk-5MMAK75Q.js +15 -0
  39. package/{chunk-7S4YWN7P.js → chunk-5UUIGN6I.js} +4 -4
  40. package/{chunk-42V6BK2E.js → chunk-62IL3KQV.js} +4 -34
  41. package/{chunk-C63CN6KA.js → chunk-6IJDSYUA.js} +849 -279
  42. package/{chunk-4MK3I7Y4.js → chunk-6MAW4XOF.js} +5 -5
  43. package/chunk-76HO2DP6.js +15 -0
  44. package/chunk-7AY2H3GA.js +13692 -0
  45. package/{chunk-4CR5I7BD.js → chunk-7HYOPBUW.js} +47 -67
  46. package/{chunk-VLTIYV3X.js → chunk-7I25CBT5.js} +34 -8
  47. package/chunk-AGIM7IMJ.js +147 -0
  48. package/{chunk-5UTFL4QJ.js → chunk-AOTBKDRK.js} +7 -0
  49. package/{chunk-6OZ36FXI.js → chunk-BIPGGSJS.js} +22 -4
  50. package/{chunk-EYAQT56M.js → chunk-BNQMNUKZ.js} +9 -6
  51. package/{chunk-62CATUYY.js → chunk-CBUMFIFE.js} +834 -962
  52. package/{chunk-OIVSQH2O.js → chunk-CDEEFJXN.js} +308 -11
  53. package/chunk-CHOZJMJS.js +78 -0
  54. package/{chunk-ETI2NYVF.js → chunk-CIP3AAMT.js} +4 -4
  55. package/{chunk-GBRG75BQ.js → chunk-D2MDMY2M.js} +1 -0
  56. package/{chunk-IBOZNTG2.js → chunk-DGEUP3DK.js} +23 -28
  57. package/{chunk-Q554LLSI.js → chunk-DMXLXZKL.js} +1 -1
  58. package/{chunk-3VNWWVKB.js → chunk-E3YWHWCR.js} +50 -18
  59. package/{chunk-HKNXJGEC.js → chunk-ECFHBYUW.js} +85 -50
  60. package/{chunk-ACTMNVHM.js → chunk-EHSYSKXV.js} +1 -1
  61. package/{chunk-WV42OMV7.js → chunk-ELUDRSRD.js} +8 -8
  62. package/{chunk-ABQYVJBJ.js → chunk-EV235ILT.js} +5 -5
  63. package/{chunk-TRV2MIDW.js → chunk-EXAJ6DCR.js} +1 -0
  64. package/{chunk-BFDFRLLQ.js → chunk-EZ4VZHAG.js} +5 -5
  65. package/{chunk-GO3Z72MT.js → chunk-FHLMQIU7.js} +65 -95
  66. package/{chunk-2F7RJC6L.js → chunk-FOXQ7BAB.js} +1 -1
  67. package/{chunk-SH43IESU.js → chunk-GGC55Q32.js} +199 -29
  68. package/chunk-GMZLP5DV.js +82 -0
  69. package/{chunk-FDTR4QJ6.js → chunk-H6A6X4EK.js} +32 -1
  70. package/{chunk-DVINR3PL.js → chunk-HDLLCBRF.js} +1 -1
  71. package/{chunk-QOKAKDPE.js → chunk-HIM3FCLF.js} +0 -1
  72. package/{chunk-ONXOABJR.js → chunk-HNGRBWYF.js} +3 -0
  73. package/{chunk-BNGW5ASC.js → chunk-I2RGRVQ7.js} +22 -2
  74. package/{chunk-O6OSWFZQ.js → chunk-IHPDK6UD.js} +6 -0
  75. package/{chunk-QDSINZM3.js → chunk-IXH3HKY2.js} +1 -22
  76. package/{chunk-GQBOR3G6.js → chunk-JBKHQOYK.js} +8 -4
  77. package/{chunk-XD2MJFUG.js → chunk-JEFXP73H.js} +1 -1
  78. package/{chunk-PBA4UJBK.js → chunk-JIXGJTBU.js} +4 -4
  79. package/{chunk-AEOE4Z6Q.js → chunk-K6L5PNXK.js} +39 -15
  80. package/{chunk-Z77CRGTW.js → chunk-KA5O5KQL.js} +1 -1
  81. package/{chunk-GPCZ7UXG.js → chunk-KD6D6BLA.js} +1 -1
  82. package/{chunk-UZGQNTVW.js → chunk-KHKTDMYG.js} +8 -6
  83. package/{chunk-MRIHM22T.js → chunk-LBFL6RZG.js} +58 -9
  84. package/{chunk-C3M4465B.js → chunk-LKIVH2I2.js} +403 -658
  85. package/{chunk-LS2ZANRJ.js → chunk-LOCNXNOU.js} +1 -1
  86. package/{chunk-DHDMC6FO.js → chunk-LUBFABMJ.js} +15 -14
  87. package/{chunk-NA35QHCF.js → chunk-LVBFKW65.js} +1 -1
  88. package/chunk-LWLNLZC5.js +265 -0
  89. package/{chunk-EEGDMATE.js → chunk-M3NMHYRB.js} +86 -81
  90. package/chunk-N4NGJDT6.js +929 -0
  91. package/{chunk-GL3EHUR4.js → chunk-N7NLLRQQ.js} +68 -46
  92. package/{chunk-BFU6C242.js → chunk-NMFV26UG.js} +1 -1
  93. package/{chunk-FZGV4FGK.js → chunk-NUHHBEJC.js} +378 -187
  94. package/chunk-NWENLDMM.js +42 -0
  95. package/chunk-O7SVKKLY.js +875 -0
  96. package/chunk-OCZKATRC.js +129 -0
  97. package/{chunk-6Z7MY3V7.js → chunk-OEJLGVBL.js} +5 -5
  98. package/{chunk-VMFTFOWF.js → chunk-OKGVNZTL.js} +35 -8
  99. package/{chunk-GEPUP7OO.js → chunk-OR2UWD6X.js} +3 -3
  100. package/{chunk-KQHGZWSV.js → chunk-OXME3PEE.js} +1 -1
  101. package/{chunk-J4MOO56S.js → chunk-PNXHPLRU.js} +10 -2
  102. package/{chunk-3BMYXEUW.js → chunk-R5AJODNI.js} +1 -1
  103. package/{chunk-P5EVSOPA.js → chunk-R6EBQEQE.js} +22 -29
  104. package/{chunk-NOF3HDSN.js → chunk-RLSF5CSE.js} +11 -9
  105. package/chunk-RQ6CTX2E.js +164 -0
  106. package/{chunk-3UZPUAES.js → chunk-RSB4PWX4.js} +1 -1
  107. package/{chunk-KQ4ONNQD.js → chunk-RXA3HAVW.js} +190 -8
  108. package/{chunk-IIVGDG4I.js → chunk-SJKULPGX.js} +13 -7
  109. package/chunk-SQHMSDDU.js +8004 -0
  110. package/{chunk-Q67DOFOO.js → chunk-SZC4REES.js} +212 -105
  111. package/{chunk-JRQFUXY7.js → chunk-TBAXFWOS.js} +99 -22
  112. package/{chunk-PQFHGD77.js → chunk-TBM2RS3U.js} +161 -14
  113. package/{chunk-XT35TTFG.js → chunk-TCYU7L6V.js} +18 -20
  114. package/{chunk-BYMV6QZG.js → chunk-TNIX77YM.js} +4 -0
  115. package/chunk-TY3TIUJK.js +89 -0
  116. package/{chunk-I3TQJXQ7.js → chunk-U3C3IA32.js} +9 -2
  117. package/{chunk-YYLHWIW6.js → chunk-UKZX3NHN.js} +1 -1
  118. package/chunk-UM7TA3K4.js +1008 -0
  119. package/{chunk-6YTOJY35.js → chunk-VBG7GWWR.js} +253 -8
  120. package/chunk-VIWDGTDA.js +8 -0
  121. package/chunk-VJVNU77E.js +83 -0
  122. package/{chunk-W7HLWAQ7.js → chunk-VPLUU4IX.js} +118 -90
  123. package/{chunk-UKWGR5SS.js → chunk-VY6VFGKR.js} +194 -1144
  124. package/chunk-VZLO4XJD.js +17 -0
  125. package/{chunk-AHAHBQMU.js → chunk-WDLSZMTA.js} +2 -2
  126. package/{chunk-53HEEOTT.js → chunk-WF5X57VW.js} +83 -16
  127. package/{chunk-VRTTFDBM.js → chunk-WPHY3VPF.js} +35 -22
  128. package/{chunk-ASIFZ2WY.js → chunk-YKZLFY5J.js} +66 -54
  129. package/chunk-YV25TM3R.js +780 -0
  130. package/{chunk-B2C6QTY4.js → chunk-YXKNBVYW.js} +19 -17
  131. package/chunk-ZRAU6T47.js +56 -0
  132. package/commandRegistry-UU6IOTHI.js +833 -0
  133. package/{contentThunks-IV2T3EJC.js → contentThunks-ARD56LKI.js} +39 -36
  134. package/{cooldownCommands-REAWYVTY.js → cooldownCommands-ZLEPIB4A.js} +2 -2
  135. package/{createAgentAutomationAction-JCOIEYY4.js → createAgentAutomationAction-HWJLU6DD.js} +40 -37
  136. package/createDialogAction-CHYA6PZE.js +70 -0
  137. package/{createPageAction-D2VOOLP3.js → createPageAction-TSCYNFX7.js} +47 -43
  138. package/{chunk-VFEJQMH4.js → cursorProvider-YGGNMVWX.js} +2751 -10172
  139. package/{dbSlice-A6C6H32X.js → dbSlice-TG4MZ5EB.js} +12 -11
  140. package/{deleteFile-YG6QMJLU.js → deleteFile-KESP65GC.js} +7 -6
  141. package/{dialogCommands-H7FPUYUQ.js → dialogCommands-IJYQAQMB.js} +49 -46
  142. package/{dialogSlice-6JZOOTDS.js → dialogSlice-H476I77R.js} +57 -37
  143. package/{dist-VODFSGNG.js → dist-NJC2W7I4.js} +61 -54
  144. package/{docCreateCommands-WRG2JLGM.js → docCreateCommands-AZSK4NAG.js} +48 -44
  145. package/{docDeleteCommands-SHWJIBJS.js → docDeleteCommands-DDJMSMFZ.js} +49 -45
  146. package/{docReadCommands-WJN3WT6O.js → docReadCommands-5F5Q6EBZ.js} +47 -43
  147. package/{docStore-HUPQ2FSS.js → docStore-HW2RDZDM.js} +17 -13
  148. package/{docUpdateCommands-IE32IL6O.js → docUpdateCommands-XPNPVZOC.js} +48 -44
  149. package/{fetchMessages-EIU7UFFK.js → fetchMessages-3PXAHKCR.js} +5 -5
  150. package/{getPricing-LUSEABA6.js → getPricing-DOBBZLOK.js} +4 -4
  151. package/{handleSendMessageAction-DFPMQ7YM.js → handleSendMessageAction-IOXE7ILC.js} +109 -42
  152. package/index.js +87 -884
  153. package/{lib-FRRS27KN.js → lib-PU2G2MSO.js} +523 -191
  154. package/{localDialogRead-BTFJ4V2I.js → localDialogRead-UYCKO7YZ.js} +2 -2
  155. package/{localRuntimeAuthority-6IR6BBXE.js → localRuntimeAuthority-TU6OBC76.js} +9 -6
  156. package/{localRuntimeDb-SYQGUF4U.js → localRuntimeDb-VKWVOPPI.js} +1 -1
  157. package/{machineCommands-OL4NLMXG.js → machineCommands-Q7TDGM6P.js} +96 -86
  158. package/machineWsRunDispatch-T5VFOQ3R.js +154 -0
  159. package/{memberThunks-P2ECUJ56.js → memberThunks-5S5D3N4U.js} +20 -18
  160. package/{models-T3SG6MJ5.js → models-PQU25T6Q.js} +2 -2
  161. package/oauthTokenStore-ITEB663N.js +23 -0
  162. package/package.json +1 -1
  163. package/processSpawn-SOAV3FEV.js +11 -0
  164. package/profileConfig-ZGOFORWV.js +43 -0
  165. package/{providerPresetApply-FG6NZ57W.js → providerPresetApply-HAQWVAQX.js} +7 -7
  166. package/{providerRegistry-757OWH3O.js → providerRegistry-5FGWB3X5.js} +11 -7
  167. package/{read-COE3ZYR6.js → read-LSYFLSIM.js} +8 -7
  168. package/{readDocTool-5USN4A6V.js → readDocTool-XWRXV3DR.js} +5 -3
  169. package/{readlineWorkspace-BOENUIW2.js → readlineWorkspace-25U6P3DG.js} +2595 -2031
  170. package/{removeDialogAgentAction-J6X5QMTA.js → removeDialogAgentAction-4TEFC3VL.js} +22 -26
  171. package/{runAgentClientLoop-5ZA62FBA.js → runAgentClientLoop-CZOYWHDN.js} +78 -71
  172. package/{runtimeDoctorCommands-X6WDBEQX.js → runtimeDoctorCommands-PIVSBZRZ.js} +4 -4
  173. package/runtimeModeArgs-2Y7BALTO.js +31 -0
  174. package/{setDialogExtraReferencesAction-WX5VTY6O.js → setDialogExtraReferencesAction-LSEN44OY.js} +16 -14
  175. package/{setPrimaryDialogAgentAction-FN22THHT.js → setPrimaryDialogAgentAction-SR366X5A.js} +23 -27
  176. package/{chunk-GP5LKBUZ.js → settingThunks-CTVPPGIN.js} +226 -940
  177. package/{skillDiscovery-CYUCJMAG.js → skillDiscovery-ZBU76COE.js} +3 -3
  178. package/{slateUtils-RIZES3PV.js → slateUtils-NGV2NMKM.js} +1 -1
  179. package/{spaceCommands-5GLCWZPO.js → spaceCommands-3UK63WPE.js} +51 -47
  180. package/{streamAgentChatTurn-6UZJMYRB.js → streamAgentChatTurn-LV6ZWUD4.js} +214 -114
  181. package/{switchDialogAgentAction-LVTEV3FR.js → switchDialogAgentAction-M6NAFOOU.js} +19 -20
  182. package/{tableCommands-O6NWHFKV.js → tableCommands-6U4BMLRR.js} +10 -10
  183. package/{toolApiClient-QVJ6HDNN.js → toolApiClient-AD7CXTA4.js} +4 -3
  184. package/tools-UJOV6CQZ.js +117 -0
  185. package/{tuiSummaryLlmCaller-OHHFTHMG.js → tuiSummaryLlmCaller-DEH7ZEM6.js} +25 -23
  186. package/{updateCommands-2M74UL7P.js → updateCommands-4EHDLF5J.js} +3 -3
  187. package/{updateDialogTitleAction-QTKNIURB.js → updateDialogTitleAction-JYXKIBNJ.js} +84 -45
  188. package/action-P4TNFGAD.js +0 -31
  189. package/agentListCommands-B2V4YAC4.js +0 -410
  190. package/agentRecordCommands-UTHKMMJY.js +0 -128
  191. package/agentRunCommand-D4OBAOVW.js +0 -156
  192. package/browser-image-compression-MFDTD7K6.js +0 -1763
  193. package/chatQueueReduxAdapter-2P6NFX64.js +0 -186
  194. package/chunk-CQ3WA2NE.js +0 -299
  195. package/chunk-M76ECQRD.js +0 -13658
  196. package/chunk-MEYIRKDN.js +0 -8967
  197. package/chunk-PUOC4YRO.js +0 -394
  198. package/chunk-Q5FJJ6XI.js +0 -103
  199. package/chunk-S7Z2HMCN.js +0 -25
  200. package/chunk-T75QD6AB.js +0 -20923
  201. package/chunk-Y5GCAMGP.js +0 -9
  202. package/chunk-YPREESF4.js +0 -225
  203. package/createDialogAction-NGG7YVNU.js +0 -65
  204. package/machineWsRunDispatch-64SG2RUI.js +0 -144
  205. package/settingSlice-P4ZW7K5X.js +0 -204
  206. package/syncMapping-N6RGXGBW.js +0 -437
  207. package/tools-KMGFWO43.js +0 -110
  208. package/{chunk-X7HHHIOZ.js → chunk-Y6ROFCZO.js} +0 -0
  209. package/{db-WK5MDZVN.js → db-VQSAOWAO.js} +1 -1
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  findPotentialSecrets
3
- } from "./chunk-S7Z2HMCN.js";
3
+ } from "./chunk-VJVNU77E.js";
4
4
  import {
5
5
  buildLocalRunEnv,
6
6
  isFullstackCodingAgentRef,
@@ -10,9 +10,6 @@ import {
10
10
  resolveServerUrl,
11
11
  writeUsage
12
12
  } from "./chunk-V7E4PXQD.js";
13
- import {
14
- resolveMachineId
15
- } from "./chunk-ESHYE7WU.js";
16
13
  import {
17
14
  agentRunCardLabels,
18
15
  createCliLocalRuntimeAdapter,
@@ -29,57 +26,55 @@ import {
29
26
  resolveFileWriteGateEnabled,
30
27
  resolveLocalUserId,
31
28
  t,
32
- toolLabel
33
- } from "./chunk-VFEJQMH4.js";
34
- import {
35
- createRunActivityTracker,
36
- popSingleQueueMessage,
37
- readRunRecord,
38
- resolveRunQueuePath,
39
- settleRunTerminalAuthoritatively,
40
- spawnLocalBackgroundRun
41
- } from "./chunk-I3TQJXQ7.js";
29
+ toolLabel,
30
+ toolLabelVariants
31
+ } from "./chunk-SQHMSDDU.js";
42
32
  import {
43
33
  clearCredentialAvailability,
44
34
  readCredentialEntry,
45
- recordCredentialProbe,
46
- resolveCredentialKeyWithFallback
47
- } from "./chunk-42V6BK2E.js";
35
+ recordCredentialProbe
36
+ } from "./chunk-62IL3KQV.js";
48
37
  import {
49
38
  getReadableCliDb
50
- } from "./chunk-LS2ZANRJ.js";
39
+ } from "./chunk-LOCNXNOU.js";
40
+ import {
41
+ _appendEntityBatch,
42
+ _appendEvidenceBatch,
43
+ _appendRelationBatch,
44
+ _appendRetiredStateBatch,
45
+ _appendStateBatch,
46
+ getMemoryEntityVNext,
47
+ getMemoryEvidenceVNext,
48
+ getMemoryEvidenceVNextStrict,
49
+ getMemoryStateVNext,
50
+ listMemoryStatesForEntityVNext,
51
+ loadMemoryVNextCatalog,
52
+ putMemoryEvidenceVNext
53
+ } from "./chunk-TY3TIUJK.js";
51
54
  import {
52
55
  readDbRecord,
53
56
  resolveAgentRecordFromHybridStore
54
- } from "./chunk-AEOE4Z6Q.js";
57
+ } from "./chunk-K6L5PNXK.js";
55
58
  import {
56
59
  isLocalCliAgentKey
57
60
  } from "./chunk-SV5IJK6K.js";
58
61
  import {
59
62
  CliProviderQuotaError
60
63
  } from "./chunk-MP64VFGD.js";
64
+ import {
65
+ resolveMachineId
66
+ } from "./chunk-ESHYE7WU.js";
61
67
  import {
62
68
  applyModelLayerOverride,
63
69
  buildModelLayerOverride
64
70
  } from "./chunk-LTRXGFMS.js";
65
- import {
66
- formatAgentListCard
67
- } from "./chunk-C3M4465B.js";
68
- import {
69
- isTransientFetchError
70
- } from "./chunk-5UTFL4QJ.js";
71
71
  import {
72
72
  isGatewayHttpStatus
73
73
  } from "./chunk-NF64D32W.js";
74
74
  import {
75
- formatFinishedRunCard,
76
- formatListRunsCard,
77
- formatNotFoundRunCard,
78
- formatStartRunCard,
79
- formatStatusRunCard,
80
- formatStopRunCard,
81
- isAgentRunTerminalStatus
82
- } from "./chunk-3VNWWVKB.js";
75
+ isTransientFetchError,
76
+ parsePositiveFiniteNumberOrFallback
77
+ } from "./chunk-AOTBKDRK.js";
83
78
  import {
84
79
  extractGoogleValidationLink
85
80
  } from "./chunk-BMQ2MJUK.js";
@@ -88,37 +83,55 @@ import {
88
83
  chooseMemoryOwners,
89
84
  loadMemoryCandidatesFromDb,
90
85
  resolveAgentMemoryPolicy
91
- } from "./chunk-IBOZNTG2.js";
86
+ } from "./chunk-DGEUP3DK.js";
92
87
  import {
93
- API_REPORTED_COST_MULTIPLIER,
94
- parseUiAskChoiceContent
95
- } from "./chunk-T75QD6AB.js";
88
+ createRunActivityTracker,
89
+ popSingleQueueMessage,
90
+ readRunRecord,
91
+ resolveRunQueuePath,
92
+ settleRunTerminalAuthoritatively,
93
+ spawnLocalBackgroundRun
94
+ } from "./chunk-U3C3IA32.js";
96
95
  import {
97
- isOAuthApiKeyRef
98
- } from "./chunk-YYLHWIW6.js";
96
+ formatAgentListCard,
97
+ formatFinishedRunCard,
98
+ formatListRunsCard,
99
+ formatNotFoundRunCard,
100
+ formatStartRunCard,
101
+ formatStatusRunCard,
102
+ formatStopRunCard,
103
+ isAgentRunTerminalStatus
104
+ } from "./chunk-E3YWHWCR.js";
99
105
  import {
100
106
  isCliAuthorityBrokerProtocolError,
101
107
  isCliAuthorityBrokerTimeoutError,
102
108
  isCliAuthorityBrokerUnavailableError
103
- } from "./chunk-TRV2MIDW.js";
109
+ } from "./chunk-EXAJ6DCR.js";
104
110
  import {
105
111
  getDefaultCliLocalRuntimeDb
106
- } from "./chunk-2F7RJC6L.js";
112
+ } from "./chunk-FOXQ7BAB.js";
113
+ import {
114
+ API_REPORTED_COST_MULTIPLIER,
115
+ parseUiAskChoiceContent
116
+ } from "./chunk-7AY2H3GA.js";
117
+ import {
118
+ isOAuthApiKeyRef
119
+ } from "./chunk-UKZX3NHN.js";
107
120
  import {
108
121
  buildSkillDiscoveryContextLayer
109
- } from "./chunk-E4MARS3Q.js";
122
+ } from "./chunk-5GVBDNTO.js";
110
123
  import {
111
124
  parseExternalSkillMarkdown,
112
125
  parseSkillDocProtocol
113
- } from "./chunk-Q554LLSI.js";
126
+ } from "./chunk-DMXLXZKL.js";
114
127
  import {
115
128
  LOCAL_AGENT_CONFIG_MISSING_CODE,
116
129
  LOCAL_TURN_ABORTED_CODE,
117
130
  readActionGate
118
- } from "./chunk-62CATUYY.js";
131
+ } from "./chunk-CBUMFIFE.js";
119
132
  import {
120
133
  resolveAgentRuntimeConfigFromRecord
121
- } from "./chunk-4MK3I7Y4.js";
134
+ } from "./chunk-6MAW4XOF.js";
122
135
  import {
123
136
  createThinkParserState,
124
137
  flushThinkParser,
@@ -129,57 +142,55 @@ import {
129
142
  isQuotaExhaustedError,
130
143
  isQuotaLimited403Body,
131
144
  mergeAvailabilityDeadline,
132
- resolveCooldownGate
133
- } from "./chunk-FDTR4QJ6.js";
134
- import {
135
- isAntigravityOAuthAgent
136
- } from "./chunk-UZGQNTVW.js";
137
- import {
138
- resolveClientVersion
139
- } from "./chunk-6OZ36FXI.js";
145
+ resolveCooldownGate,
146
+ resolveCredentialKeyWithFallback
147
+ } from "./chunk-H6A6X4EK.js";
140
148
  import {
141
149
  DEFAULT_CONTEXT_WINDOW,
142
150
  getModelContextWindow,
143
151
  normalizeUsage
144
- } from "./chunk-HKNXJGEC.js";
152
+ } from "./chunk-ECFHBYUW.js";
145
153
  import {
146
154
  clipCompactText
147
- } from "./chunk-P5EVSOPA.js";
148
- import {
149
- findModelConfig
150
- } from "./chunk-OIVSQH2O.js";
155
+ } from "./chunk-5MMAK75Q.js";
151
156
  import {
152
157
  compactWhitespace
153
158
  } from "./chunk-DWLEOOGR.js";
154
- import {
155
- toErrorMessage
156
- } from "./chunk-HNMXYYJR.js";
157
159
  import {
158
160
  buildAgentsMdLayer,
159
161
  buildMemoryOverlayLayer,
160
162
  buildMemoryUseGuidanceLayer,
161
163
  partitionScopedBlocks,
162
164
  renderTurnContextBlocksWithScope
163
- } from "./chunk-DVINR3PL.js";
165
+ } from "./chunk-HDLLCBRF.js";
164
166
  import {
165
- readPipeText,
166
- spawnProcess
167
- } from "./chunk-X7HHHIOZ.js";
167
+ isAntigravityOAuthAgent
168
+ } from "./chunk-KHKTDMYG.js";
169
+ import {
170
+ resolveClientVersion
171
+ } from "./chunk-BIPGGSJS.js";
172
+ import {
173
+ findModelConfig
174
+ } from "./chunk-CDEEFJXN.js";
175
+ import {
176
+ toErrorMessage
177
+ } from "./chunk-HNMXYYJR.js";
178
+ import {
179
+ getLogger,
180
+ normalizeError
181
+ } from "./chunk-YV25TM3R.js";
168
182
  import {
169
183
  resolveAuthToken
170
184
  } from "./chunk-A7GB5UGH.js";
185
+ import {
186
+ readPipeText,
187
+ spawnProcess
188
+ } from "./chunk-Y6ROFCZO.js";
171
189
  import {
172
190
  CLIENT_VERSION_TOO_OLD_CODE,
173
191
  NOLO_CLIENT_VERSION_HEADER,
174
192
  buildClientVersionUpgradeMessage
175
- } from "./chunk-Q67DOFOO.js";
176
- import {
177
- parsePositiveFiniteNumberOrFallback
178
- } from "./chunk-Y5GCAMGP.js";
179
- import {
180
- createMemoryKey,
181
- ulid
182
- } from "./chunk-VMFTFOWF.js";
193
+ } from "./chunk-SZC4REES.js";
183
194
  import {
184
195
  asTrimmedLowercaseString
185
196
  } from "./chunk-QSJ3HFEF.js";
@@ -187,13 +198,14 @@ import {
187
198
  BUILTIN_NOLO_AGENT_KEY,
188
199
  BUILTIN_NOLO_AGENT_NAME,
189
200
  builtinAgentCatalogEntryById
190
- } from "./chunk-BNGW5ASC.js";
201
+ } from "./chunk-I2RGRVQ7.js";
191
202
  import {
192
203
  parsePublicAgentId
193
204
  } from "./chunk-M2EJHDJP.js";
194
205
  import {
195
- isLevelNotFoundError
196
- } from "./chunk-OW765XBU.js";
206
+ createMemoryKey,
207
+ ulid
208
+ } from "./chunk-OKGVNZTL.js";
197
209
  import {
198
210
  asTrimmedString
199
211
  } from "./chunk-3EUW3WEO.js";
@@ -8206,7 +8218,12 @@ function emitPlainGap(text, keywords, info, accent, warning, reset) {
8206
8218
  var UNORDERED_LIST_RE = /^(\s*)([-*+])\s+(.+)$/;
8207
8219
  var ORDERED_LIST_RE = /^(\s*)(\d+)\.\s+(.+)$/;
8208
8220
  var TASK_LIST_RE = /^(\s*)([-*+])\s+\[([ xX])\]\s+(.+)$/;
8221
+ var THEMATIC_BREAK_PATTERN = "(?:(-[ \\t]*){3,}|(\\*[ \\t]*){3,}|(_[ \\t]*){3,})";
8222
+ var THEMATIC_BREAK_RE = new RegExp(`^[ ]{0,3}${THEMATIC_BREAK_PATTERN}$`);
8209
8223
  function normalizeListLine(line) {
8224
+ if (THEMATIC_BREAK_RE.test(line)) {
8225
+ return line;
8226
+ }
8210
8227
  const task = line.match(TASK_LIST_RE);
8211
8228
  if (task) {
8212
8229
  const checked = task[3] === "x" || task[3] === "X";
@@ -8222,12 +8239,99 @@ function normalizeListLine(line) {
8222
8239
  }
8223
8240
  return line;
8224
8241
  }
8242
+ var TOOL_TREE_HEADER_RE = /^•\s+(.+?)\s+\((\d+)\)$/;
8243
+ var TOOL_TREE_LEAF_RE = /^([├└]──\s+)(.*?)\s{2}(✓|✗|!)(?:\s+(.*))?$/;
8244
+ var TOOL_SINGLE_RE = /^▸\s+(.+?)(?:\s+·\s+(.*?))?(?:\s{2}(✓|✗|!)(?:\s+(.*))?)$/;
8245
+ function plainToolLine(line) {
8246
+ return stripAnsi2(line);
8247
+ }
8248
+ var TOOL_TREE_GROUP_LABELS = new Set(
8249
+ ["execShell", "readFile", "fetchWebpage", "exa_search"].flatMap(toolLabelVariants)
8250
+ );
8251
+ function isKnownToolGroupLabel(label) {
8252
+ return TOOL_TREE_GROUP_LABELS.has(label);
8253
+ }
8254
+ function toolTreeHeaderMatch(line) {
8255
+ const match = plainToolLine(line).match(TOOL_TREE_HEADER_RE);
8256
+ return match && isKnownToolGroupLabel(match[1]) ? match : null;
8257
+ }
8258
+ function isToolTreeHeaderLine(line) {
8259
+ return toolTreeHeaderMatch(line) !== null;
8260
+ }
8261
+ function isToolTreeLeafLine(line) {
8262
+ return TOOL_TREE_LEAF_RE.test(plainToolLine(line));
8263
+ }
8264
+ function isToolSingleLine(line) {
8265
+ return TOOL_SINGLE_RE.test(plainToolLine(line));
8266
+ }
8267
+ function isToolGroupBoundary(cur, next) {
8268
+ return isToolTreeLeafLine(cur) && isToolTreeHeaderLine(next);
8269
+ }
8270
+ function statusColorSeq(marker, brightness) {
8271
+ if (marker === "\u2713") return colorSeq("success", brightness);
8272
+ if (marker === "\u2717") return colorSeq("danger", brightness);
8273
+ return colorSeq("warning", brightness);
8274
+ }
8275
+ function styleTuiToolLine(line, brightness) {
8276
+ const plain = plainToolLine(line);
8277
+ const chrome = colorSeq("chrome", brightness);
8278
+ const muted = colorSeq("muted", brightness);
8279
+ const header = toolTreeHeaderMatch(plain);
8280
+ if (header) {
8281
+ return `${chrome}\u2022${STYLE.reset} ${STYLE.bold}${muted}${header[1]}${STYLE.reset} ${chrome}${STYLE.dim}(${header[2]})${STYLE.reset}`;
8282
+ }
8283
+ const leaf = plain.match(TOOL_TREE_LEAF_RE);
8284
+ if (leaf) {
8285
+ const [, connector, detail, marker, statusDetail] = leaf;
8286
+ let rendered = `${chrome}${connector}${STYLE.reset}${chrome}${detail}${STYLE.reset}`;
8287
+ rendered += ` ${statusColorSeq(marker, brightness)}${marker}${STYLE.reset}`;
8288
+ if (statusDetail) {
8289
+ const metaSeq = marker === "\u2713" ? chrome : statusColorSeq(marker, brightness);
8290
+ rendered += ` ${metaSeq}${STYLE.dim}${statusDetail}${STYLE.reset}`;
8291
+ }
8292
+ return rendered;
8293
+ }
8294
+ const single = plain.match(TOOL_SINGLE_RE);
8295
+ if (single) {
8296
+ const [, label, detail, marker, statusDetail] = single;
8297
+ let rendered = `${chrome}\u25B8${STYLE.reset} ${STYLE.bold}${muted}${label}${STYLE.reset}`;
8298
+ if (detail) rendered += ` ${chrome}\xB7 ${detail}${STYLE.reset}`;
8299
+ rendered += ` ${statusColorSeq(marker, brightness)}${marker}${STYLE.reset}`;
8300
+ if (statusDetail) {
8301
+ const metaSeq = marker === "\u2713" ? chrome : statusColorSeq(marker, brightness);
8302
+ rendered += ` ${metaSeq}${STYLE.dim}${statusDetail}${STYLE.reset}`;
8303
+ }
8304
+ return rendered;
8305
+ }
8306
+ return null;
8307
+ }
8225
8308
  function isPolishListLikeLine(line) {
8226
- return LIST_LIKE_RE_FOR_GUARD.test(normalizeListLine(line));
8309
+ return LIST_LIKE_RE_FOR_GUARD.test(normalizeListLine(plainToolLine(line)));
8310
+ }
8311
+ var LIST_LIKE_RE_FOR_GUARD = /^\s*(?:•|◦|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s|^\s*▸\s/;
8312
+ function isPolishFenceInteriorLine(line) {
8313
+ return /^\x00F\d+\x00$/.test(line);
8314
+ }
8315
+ function polishHeadingLevel(line) {
8316
+ const match = stripAnsi2(line).match(/^(#{1,6})\s/);
8317
+ return match ? match[1].length : null;
8318
+ }
8319
+ function isPolishHeadingLine(line) {
8320
+ return polishHeadingLevel(line) !== null;
8321
+ }
8322
+ function isPolishIntroLine(line) {
8323
+ const plain = stripAnsi2(line).trimEnd();
8324
+ return plain.endsWith("\uFF1A") || plain.endsWith(":");
8227
8325
  }
8228
- var LIST_LIKE_RE_FOR_GUARD = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
8229
8326
  function polishBreathInsertsBlankBetween(cur, next) {
8230
8327
  if (cur === "" || next === "") return false;
8328
+ if (isPolishFenceInteriorLine(cur) || isPolishFenceInteriorLine(next)) {
8329
+ return false;
8330
+ }
8331
+ if (isPolishIntroLine(cur) && isPolishListLikeLine(next)) return false;
8332
+ if (isPolishHeadingLine(cur) || isPolishHeadingLine(next)) return false;
8333
+ if (isCodeFenceLine(cur) !== isCodeFenceLine(next)) return true;
8334
+ if (isToolGroupBoundary(cur, next)) return true;
8231
8335
  return isPolishListLikeLine(cur) !== isPolishListLikeLine(next);
8232
8336
  }
8233
8337
  function convertMarkdownTablesForTerminal(text) {
@@ -8296,17 +8400,15 @@ function polishAssistantStructure(text, options = {}) {
8296
8400
  }
8297
8401
  return line;
8298
8402
  });
8299
- const afterHeading = maskedLines.join("\n").replace(/([^\n])\n(#{1,3} )/g, "$1\n\n$2").replace(/^(#{1,3} .+)\n(?!\n)/gm, "$1\n\n").replace(/\n{4,}/g, "\n\n\n");
8300
- const LIST_LIKE = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
8403
+ const afterHeading = maskedLines.join("\n").replace(/([^\n])\n(#{1,6} )/g, "$1\n\n$2").replace(/^(#{1,2} .+)\n(?!\n)/gm, "$1\n\n").replace(new RegExp(`([^\\n])\\n([ ]{0,3}${THEMATIC_BREAK_PATTERN})$`, "gm"), "$1\n\n$2").replace(new RegExp(`^([ ]{0,3}${THEMATIC_BREAK_PATTERN})\\n(?!\\n)`, "gm"), "$1\n\n").replace(/\n{3,}/g, "\n\n");
8301
8404
  const headingLines = afterHeading.split("\n");
8302
8405
  const breathed = [];
8303
8406
  for (let i = 0; i < headingLines.length; i++) {
8304
8407
  breathed.push(headingLines[i]);
8305
8408
  const cur = headingLines[i];
8306
8409
  const next = headingLines[i + 1];
8307
- if (cur === "" || next === void 0 || next === "") continue;
8308
- if (LIST_LIKE.test(cur) === LIST_LIKE.test(next)) continue;
8309
- breathed.push("");
8410
+ if (next === void 0) continue;
8411
+ if (polishBreathInsertsBlankBetween(cur, next)) breathed.push("");
8310
8412
  }
8311
8413
  const polishedMasked = breathed.join("\n");
8312
8414
  const polished = polishedMasked.replace(
@@ -8316,17 +8418,23 @@ function polishAssistantStructure(text, options = {}) {
8316
8418
  return options.trimEdges === false ? polished : polished.trim();
8317
8419
  }
8318
8420
  function styleRichMarkdownLine(line, brightness) {
8319
- const heading = line.match(/^(#{1,3})\s+(.+)$/);
8421
+ const toolLine = styleTuiToolLine(line, brightness);
8422
+ if (toolLine !== null) return toolLine;
8423
+ const heading = line.match(/^(#{1,6})\s+(.+)$/);
8320
8424
  if (heading) {
8321
8425
  const level = heading[1].length;
8322
8426
  const title = heading[2];
8427
+ const styledTitle = styleInlineMarkdown(title, brightness);
8323
8428
  if (level === 1) {
8324
- return `${STYLE.bold}\x1B[4m${colorSeq("accent", brightness)}${title}${STYLE.reset}`;
8429
+ return `${STYLE.bold}${colorSeq("accent", brightness)}${styledTitle}${STYLE.reset}`;
8325
8430
  }
8326
8431
  if (level === 2) {
8327
- return `${STYLE.bold}${colorSeq("warning", brightness)}${title}${STYLE.reset}`;
8432
+ return `${STYLE.bold}${colorSeq("warning", brightness)}${styledTitle}${STYLE.reset}`;
8328
8433
  }
8329
- return `${STYLE.bold}${colorSeq("info", brightness)}${title}${STYLE.reset}`;
8434
+ if (level === 3) {
8435
+ return `${STYLE.bold}${colorSeq("info", brightness)}${styledTitle}${STYLE.reset}`;
8436
+ }
8437
+ return `${STYLE.bold}${colorSeq("muted", brightness)}${styledTitle}${STYLE.reset}`;
8330
8438
  }
8331
8439
  if (line.startsWith("\u8FDB\u5165 nolo-plan")) {
8332
8440
  return `${colorSeq("chrome", brightness)}${STYLE.dim}${line}${STYLE.reset}`;
@@ -8335,15 +8443,19 @@ function styleRichMarkdownLine(line, brightness) {
8335
8443
  if (blockquote) {
8336
8444
  const border = colorSeq("chrome", brightness);
8337
8445
  const content = blockquote[1];
8338
- return `${border}\u2502${STYLE.reset} ${STYLE.dim}${content}${STYLE.reset}`;
8446
+ const styled = styleInlineMarkdown(content, brightness);
8447
+ return `${border}\u2502${STYLE.reset} ${STYLE.dim}${styled}${STYLE.reset}`;
8339
8448
  }
8340
- if (/^---+$/.test(line.trim())) {
8341
- return `${colorSeq("chrome", brightness)}${"\u2500".repeat(Math.min(line.trim().length, 40))}${STYLE.reset}`;
8449
+ if (THEMATIC_BREAK_RE.test(line)) {
8450
+ return `${colorSeq("chrome", brightness)}${STYLE.dim}${"\u2500".repeat(36)}${STYLE.reset}`;
8342
8451
  }
8343
8452
  const bullet = line.match(/^(\s*)(•)\s(.+)$/);
8344
8453
  if (bullet) {
8454
+ const indent = bullet[1];
8345
8455
  const styled = styleInlineMarkdown(bullet[3], brightness);
8346
- return `${bullet[1]}${colorSeq("accent", brightness)}\u2022${STYLE.reset} ${styled}`;
8456
+ const marker = indent.length >= 2 ? "\u25E6" : "\u2022";
8457
+ const markerColor = indent.length >= 2 ? colorSeq("chrome", brightness) : colorSeq("accent", brightness);
8458
+ return `${indent}${markerColor}${marker}${STYLE.reset} ${styled}`;
8347
8459
  }
8348
8460
  const ordered = line.match(/^(\s*)(\d+\.)\s(.+)$/);
8349
8461
  if (ordered) {
@@ -8467,16 +8579,28 @@ function emitFormattedAssistantBlock(write, text, trailingNewline = false) {
8467
8579
  }
8468
8580
  function classifyStreamLine(line) {
8469
8581
  if (line === "") return "blank";
8470
- if (TASK_LIST_RE.test(line) || UNORDERED_LIST_RE.test(line) || ORDERED_LIST_RE.test(line) || /^\s*(?:•|☐|☑)\s/.test(line) || /^\s*[\u2460-\u2473]/.test(line)) {
8582
+ const plain = plainToolLine(line);
8583
+ if (isToolTreeHeaderLine(plain)) return "tool-header";
8584
+ if (isToolTreeLeafLine(plain)) return "tool-leaf";
8585
+ if (isToolSingleLine(plain)) return "tool";
8586
+ 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)) {
8471
8587
  return "list";
8472
8588
  }
8589
+ if (isPolishListLikeLine(plain)) return "list";
8590
+ if (polishHeadingLevel(plain) !== null) return "heading";
8473
8591
  return "prose";
8474
8592
  }
8475
- function needsListProseBreath(prev, next) {
8593
+ function isStreamListLike(kind) {
8594
+ return kind === "list" || kind === "tool-header" || kind === "tool-leaf" || kind === "tool";
8595
+ }
8596
+ function needsListProseBreath(prev, next, prevLine = "") {
8476
8597
  if (prev === null || prev === "blank" || next === "blank") return false;
8477
- const prevList = prev === "list";
8478
- const nextList = next === "list";
8479
- return prevList !== nextList;
8598
+ if (next === "heading") return true;
8599
+ if (prev === "heading") return (polishHeadingLevel(prevLine) ?? 7) <= 2;
8600
+ if (prev === "fence" !== (next === "fence")) return true;
8601
+ if (isStreamListLike(next) && isPolishIntroLine(prevLine)) return false;
8602
+ if (prev === "tool-leaf" && next === "tool-header") return true;
8603
+ return isStreamListLike(prev) !== isStreamListLike(next);
8480
8604
  }
8481
8605
  function createRenderAwareStreamWriter(args) {
8482
8606
  const brightness = resolveTuiBrightness();
@@ -8486,9 +8610,16 @@ function createRenderAwareStreamWriter(args) {
8486
8610
  let inMermaid = false;
8487
8611
  let mermaidBody = [];
8488
8612
  let lastKind = null;
8613
+ let lastLine = "";
8614
+ let pendingBlankRow = false;
8489
8615
  const PARTIAL_FLUSH_THRESHOLD = 48;
8490
8616
  const emitBreathIfNeeded = (nextKind) => {
8491
- if (needsListProseBreath(lastKind, nextKind)) args.write("\n");
8617
+ if (pendingBlankRow) {
8618
+ args.write("\n");
8619
+ pendingBlankRow = false;
8620
+ lastKind = "blank";
8621
+ }
8622
+ if (needsListProseBreath(lastKind, nextKind, lastLine)) args.write("\n");
8492
8623
  };
8493
8624
  const flushPartialProse = () => {
8494
8625
  if (inFence || buffer.length < PARTIAL_FLUSH_THRESHOLD) return;
@@ -8506,6 +8637,7 @@ function createRenderAwareStreamWriter(args) {
8506
8637
  emitBreathIfNeeded("prose");
8507
8638
  emitFormattedAssistantBlock(args.write, prefix, false);
8508
8639
  lastKind = "prose";
8640
+ lastLine = prefix;
8509
8641
  buffer = prefix.length === buffer.length ? "" : buffer.slice(prefix.length);
8510
8642
  };
8511
8643
  const flushCompleteBlocks = () => {
@@ -8521,10 +8653,11 @@ function createRenderAwareStreamWriter(args) {
8521
8653
  inMermaid = false;
8522
8654
  inFence = false;
8523
8655
  fenceLang = "unknown";
8524
- emitBreathIfNeeded("other");
8656
+ emitBreathIfNeeded("fence");
8525
8657
  args.write(`${STYLE.dim}${firstLine}${STYLE.reset}
8526
8658
  `);
8527
- lastKind = "other";
8659
+ lastKind = "fence";
8660
+ lastLine = firstLine;
8528
8661
  buffer = lines.slice(1).join("\n");
8529
8662
  continue;
8530
8663
  }
@@ -8540,10 +8673,11 @@ function createRenderAwareStreamWriter(args) {
8540
8673
  }
8541
8674
  inFence = true;
8542
8675
  }
8543
- emitBreathIfNeeded("other");
8676
+ emitBreathIfNeeded("fence");
8544
8677
  args.write(`${STYLE.dim}${firstLine}${STYLE.reset}
8545
8678
  `);
8546
- lastKind = "other";
8679
+ lastKind = "fence";
8680
+ lastLine = firstLine;
8547
8681
  buffer = lines.slice(1).join("\n");
8548
8682
  continue;
8549
8683
  }
@@ -8555,7 +8689,8 @@ function createRenderAwareStreamWriter(args) {
8555
8689
  if (inFence) {
8556
8690
  args.write(`${highlightCodeLine(firstLine, fenceLang, brightness)}
8557
8691
  `);
8558
- lastKind = "other";
8692
+ lastKind = "fence";
8693
+ lastLine = firstLine;
8559
8694
  buffer = lines.slice(1).join("\n");
8560
8695
  continue;
8561
8696
  }
@@ -8568,6 +8703,7 @@ function createRenderAwareStreamWriter(args) {
8568
8703
  const inner = trimmedFirst.slice(2, trimmedFirst.length - 2);
8569
8704
  args.write(renderMathBlock(inner) + "\n");
8570
8705
  lastKind = "other";
8706
+ lastLine = trimmedFirst;
8571
8707
  buffer = lines.slice(1).join("\n");
8572
8708
  continue;
8573
8709
  }
@@ -8594,6 +8730,7 @@ function createRenderAwareStreamWriter(args) {
8594
8730
  if (lastInner) innerParts.push(lastInner);
8595
8731
  args.write(renderMathBlock(innerParts.join("\n")) + "\n");
8596
8732
  lastKind = "other";
8733
+ lastLine = trimmedFirst;
8597
8734
  buffer = lines.slice(closeIndex + 1).join("\n");
8598
8735
  continue;
8599
8736
  }
@@ -8614,14 +8751,23 @@ function createRenderAwareStreamWriter(args) {
8614
8751
  true
8615
8752
  );
8616
8753
  lastKind = "list";
8754
+ lastLine = lines[end - 1] ?? firstLine;
8617
8755
  buffer = lines.slice(end).join("\n");
8618
8756
  continue;
8619
8757
  }
8620
8758
  }
8621
8759
  const kind = classifyStreamLine(firstLine);
8760
+ if (kind === "blank") {
8761
+ if (lastKind !== null && lastKind !== "blank") pendingBlankRow = true;
8762
+ lastKind = "blank";
8763
+ lastLine = "";
8764
+ buffer = lines.slice(1).join("\n");
8765
+ continue;
8766
+ }
8622
8767
  emitBreathIfNeeded(kind);
8623
8768
  emitFormattedAssistantBlock(args.write, firstLine, true);
8624
8769
  lastKind = kind;
8770
+ lastLine = firstLine;
8625
8771
  buffer = lines.slice(1).join("\n");
8626
8772
  }
8627
8773
  };
@@ -9481,8 +9627,6 @@ function formatNormalToolDuration(elapsedMs) {
9481
9627
  function formatNormalToolLine(event, pending, colorEnabled) {
9482
9628
  if (event.type === "tool-call") return "";
9483
9629
  const toolName = event.toolName || pending?.toolName || "tool";
9484
- const todoBlock = formatTodoListForCli(event, colorEnabled);
9485
- if (todoBlock) return todoBlock;
9486
9630
  if (event.type === "tool-result" && (event.toolName === "ask_user" || event.metadata?.uiAskChoice)) {
9487
9631
  const block = formatUiAskChoiceBlock(event, colorEnabled);
9488
9632
  if (block) return block;
@@ -9545,39 +9689,6 @@ function resolveLoadSkillName(event) {
9545
9689
  if (match?.[1]) return match[1];
9546
9690
  return argName || "skill";
9547
9691
  }
9548
- function formatTodoListForCli(event, colorEnabled) {
9549
- if (event.type !== "tool-result" || event.toolName !== "setTodoList") {
9550
- return void 0;
9551
- }
9552
- let raw = event.metadata?.displayData;
9553
- let parsed = typeof raw === "object" && raw !== null;
9554
- if (typeof raw === "string") {
9555
- try {
9556
- raw = JSON.parse(raw);
9557
- parsed = true;
9558
- } catch {
9559
- raw = void 0;
9560
- }
9561
- }
9562
- if (!parsed && typeof event.content === "string") {
9563
- try {
9564
- raw = JSON.parse(event.content);
9565
- parsed = true;
9566
- } catch {
9567
- raw = void 0;
9568
- }
9569
- }
9570
- const todos = Array.isArray(raw?.todos) ? raw.todos : void 0;
9571
- if (!todos) return void 0;
9572
- if (todos.length === 0) return "\u2611 Todo\n (empty)\n";
9573
- const lines = todos.map((todo) => {
9574
- const status = todo?.status === "done" ? "\u2713" : todo?.status === "in_progress" ? "\u25D0" : "\u25CB";
9575
- const title = typeof todo?.title === "string" ? todo.title : "Untitled task";
9576
- return ` ${status} ${title}`;
9577
- });
9578
- const text = [`\u2611 Todo (${todos.length})`, ...lines].join("\n") + "\n";
9579
- return colorEnabled ? themeText(text, "chrome") : text;
9580
- }
9581
9692
  function formatLoadSkillBlock(event, colorEnabled, opts) {
9582
9693
  if (event.type !== "tool-result" || event.toolName !== "loadSkill") return null;
9583
9694
  const skillName = resolveLoadSkillName(event);
@@ -9834,6 +9945,7 @@ ${this.text}
9834
9945
  // packages/cli/client/agentRunOutput.ts
9835
9946
  var IDENTITY_LABEL_SEPARATOR = " > ";
9836
9947
  var THINKING_PREVIEW_BUFFER_LIMIT = 512;
9948
+ var TUI_PROGRESS_BUFFER_LIMIT = 1200;
9837
9949
  function appendThinkingPreview(current, chunk, limit = THINKING_PREVIEW_BUFFER_LIMIT) {
9838
9950
  if (limit <= 0) return "";
9839
9951
  const combined = current + chunk;
@@ -9895,6 +10007,14 @@ function formatToolJsonEvent(event) {
9895
10007
  })}
9896
10008
  `;
9897
10009
  }
10010
+ function shouldPromoteTuiNarration(text) {
10011
+ if (text.length >= TUI_PROGRESS_BUFFER_LIMIT) return true;
10012
+ return /(^|\n)\s*(?:#{1,3}\s|```|[-*+]\s|\d+[.)]\s)/.test(text);
10013
+ }
10014
+ function narrationActivityLabel(text) {
10015
+ const oneLine = stripAnsi2(text).replace(/[`*_#>]/g, "").replace(/\s+/g, " ").trim();
10016
+ return truncateThinkingHint(oneLine, 60);
10017
+ }
9898
10018
  function createCliTurnOutput(params) {
9899
10019
  const { options } = params;
9900
10020
  const workingLabel = params.workingLabel ?? `${options.agentName} -> working`;
@@ -9903,14 +10023,36 @@ function createCliTurnOutput(params) {
9903
10023
  tuiTrees: options.output.tuiTrees === true
9904
10024
  });
9905
10025
  const eventMode = resolveAgentEventMode(options);
9906
- const showThinking = options.showThinking !== false;
10026
+ const assistantLabelManaged = options.output.assistantLabelManaged === true;
10027
+ const showThinking = !assistantLabelManaged && options.showThinking !== false;
10028
+ const hidesRoutineTuiToolDetail = (event) => {
10029
+ if (!assistantLabelManaged || event.toolName !== "editFile") return false;
10030
+ if (event.type === "tool-error") return false;
10031
+ if (readActionGate(event.metadata?.actionGate)) return false;
10032
+ if (event.metadata?.timedOut || event.metadata?.failed || event.metadata?.error) return false;
10033
+ if (typeof event.metadata?.exitCode === "number" && event.metadata.exitCode !== 0) return false;
10034
+ return true;
10035
+ };
9907
10036
  let streamedAssistantText = false;
9908
10037
  let everStreamedAnyText = false;
9909
10038
  let printedAssistantLabel = false;
9910
10039
  let thinkState = createThinkParserState();
9911
10040
  let thinkingFirstAt = null;
9912
10041
  let thinkingPreview = "";
10042
+ let tuiThinkingReported = false;
10043
+ const clearTuiThinkingLabel = () => {
10044
+ if (!tuiThinkingReported) return;
10045
+ tuiThinkingReported = false;
10046
+ options.activityReporter?.(null);
10047
+ };
9913
10048
  const markThinkingDelta = (chunk) => {
10049
+ if (assistantLabelManaged) {
10050
+ if (!tuiThinkingReported && !streamedAssistantText) {
10051
+ tuiThinkingReported = true;
10052
+ options.activityReporter?.(t("thinkingActive"));
10053
+ }
10054
+ return;
10055
+ }
9914
10056
  if (!showThinking) return;
9915
10057
  if (streamedAssistantText) return;
9916
10058
  if (thinkingFirstAt === null) {
@@ -9928,6 +10070,7 @@ function createCliTurnOutput(params) {
9928
10070
  options.activityReporter?.(label);
9929
10071
  };
9930
10072
  const endThinkingPhase = () => {
10073
+ clearTuiThinkingLabel();
9931
10074
  if (thinkingFirstAt === null) return;
9932
10075
  const seconds = Math.max(0, Math.round((Date.now() - thinkingFirstAt) / 1e3));
9933
10076
  thinkingFirstAt = null;
@@ -9940,7 +10083,6 @@ function createCliTurnOutput(params) {
9940
10083
  }
9941
10084
  };
9942
10085
  let compactionEvent = null;
9943
- const assistantLabelManaged = options.output.assistantLabelManaged === true;
9944
10086
  const writeToolOutput = (chunk) => {
9945
10087
  if (!chunk) return;
9946
10088
  if (typeof options.output.writeToolBlock === "function") {
@@ -9952,9 +10094,25 @@ function createCliTurnOutput(params) {
9952
10094
  const renderWriter = createRenderAwareStreamWriter({
9953
10095
  write: (chunk) => options.output.write(chunk)
9954
10096
  });
10097
+ let pendingTuiNarration = "";
10098
+ let tuiNarrationPromoted = false;
10099
+ const flushPendingTuiNarration = () => {
10100
+ if (!pendingTuiNarration) return;
10101
+ formatToolEvent.reset?.();
10102
+ renderWriter.push(pendingTuiNarration);
10103
+ pendingTuiNarration = "";
10104
+ tuiNarrationPromoted = true;
10105
+ streamedAssistantText = true;
10106
+ options.activityReporter?.(null);
10107
+ };
10108
+ const dropPendingTuiProgress = () => {
10109
+ pendingTuiNarration = "";
10110
+ tuiNarrationPromoted = false;
10111
+ options.activityReporter?.(null);
10112
+ };
9955
10113
  const writeVisibleAssistantChunk = (chunk) => {
9956
10114
  if (!chunk) return;
9957
- formatToolEvent.reset?.();
10115
+ if (!assistantLabelManaged) formatToolEvent.reset?.();
9958
10116
  const parsed = processThinkChunk(chunk, thinkState);
9959
10117
  thinkState = parsed.state;
9960
10118
  if (!parsed.content && !parsed.reasoning) return;
@@ -9970,8 +10128,23 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
9970
10128
  }
9971
10129
  printedAssistantLabel = true;
9972
10130
  }
9973
- streamedAssistantText = true;
9974
10131
  everStreamedAnyText = true;
10132
+ if (assistantLabelManaged) {
10133
+ if (tuiNarrationPromoted) {
10134
+ renderWriter.push(parsed.content);
10135
+ streamedAssistantText = true;
10136
+ return;
10137
+ }
10138
+ pendingTuiNarration += parsed.content;
10139
+ if (shouldPromoteTuiNarration(pendingTuiNarration)) {
10140
+ flushPendingTuiNarration();
10141
+ } else {
10142
+ const label = narrationActivityLabel(pendingTuiNarration);
10143
+ if (label) options.activityReporter?.(label);
10144
+ }
10145
+ return;
10146
+ }
10147
+ streamedAssistantText = true;
9975
10148
  renderWriter.push(parsed.content);
9976
10149
  };
9977
10150
  const handleToolEvent = (event) => {
@@ -9987,13 +10160,19 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
9987
10160
  return;
9988
10161
  }
9989
10162
  if (event.type === "tool-call") {
10163
+ if (assistantLabelManaged && pendingTuiNarration) {
10164
+ dropPendingTuiProgress();
10165
+ }
9990
10166
  renderWriter.flush();
9991
- formatToolEvent(event);
10167
+ if (!hidesRoutineTuiToolDetail(event)) {
10168
+ formatToolEvent(event);
10169
+ }
9992
10170
  endThinkingPhase();
9993
10171
  if (streamedAssistantText) {
9994
10172
  options.output.write("\n");
9995
10173
  streamedAssistantText = false;
9996
10174
  }
10175
+ if (assistantLabelManaged) tuiNarrationPromoted = false;
9997
10176
  const activeLabel = formatConservativeActiveToolLabel(event);
9998
10177
  spinner.show(activeLabel);
9999
10178
  options.activityReporter?.(activeLabel);
@@ -10005,6 +10184,9 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
10005
10184
  }
10006
10185
  spinner.stop();
10007
10186
  options.activityReporter?.(null);
10187
+ if (hidesRoutineTuiToolDetail(event)) {
10188
+ return;
10189
+ }
10008
10190
  if (isLiveAgentRunObservation(event, parsedRunEvent)) {
10009
10191
  formatToolEvent.consume?.(event);
10010
10192
  return;
@@ -10017,6 +10199,26 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
10017
10199
  return {
10018
10200
  spinner,
10019
10201
  eventMode,
10202
+ /**
10203
+ * Terminal cleanup for abort/error paths that never reach `finish()`.
10204
+ *
10205
+ * A user abort discards the transient TUI progress buffer: the user stopped
10206
+ * on purpose and the dock already showed that text as activity. A genuine
10207
+ * failure must not swallow prose that never got the chance to be *proven*
10208
+ * durable (only a following tool call proves "progress"), so it promotes the
10209
+ * pending buffer and flushes what was already promoted — otherwise a short
10210
+ * final answer followed by a transport error disappears from the transcript.
10211
+ */
10212
+ cancel(cleanup) {
10213
+ if (assistantLabelManaged && cleanup?.preservePendingNarration) {
10214
+ flushPendingTuiNarration();
10215
+ if (streamedAssistantText) {
10216
+ renderWriter.flush();
10217
+ options.output.write("\n");
10218
+ }
10219
+ }
10220
+ dropPendingTuiProgress();
10221
+ },
10020
10222
  pushText(chunk) {
10021
10223
  writeVisibleAssistantChunk(chunk);
10022
10224
  },
@@ -10024,10 +10226,6 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
10024
10226
  markThinkingDelta(chunk);
10025
10227
  },
10026
10228
  handleToolEvent,
10027
- /** 记录一条 compaction 观测事件(TUI 在 turn 结束时渲染一行 dim 摘要)。
10028
- * 一轮内可能来多条(轮开始 + 每个 round),按显著性保留最高者:
10029
- * 失败 > 新生成摘要 > 投影复用 > 跳过,避免末尾的例行跳过事件
10030
- * 覆盖掉中途真正发生的压缩。 */
10031
10229
  recordCompaction(event) {
10032
10230
  const significance = (e) => e.failed ? 4 : e.summaryGenerated ? 3 : e.compressed ? 2 : 1;
10033
10231
  if (!compactionEvent || significance(event) >= significance(compactionEvent)) {
@@ -10039,12 +10237,28 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
10039
10237
  spinner.show(activeLabel);
10040
10238
  options.activityReporter?.(activeLabel);
10041
10239
  },
10240
+ /**
10241
+ * Pre-delta turn phase label (ctx-overflow-feedback batch 3).
10242
+ *
10243
+ * localLoop 在首个 provider delta 之前依次发出 turn-phase 事件
10244
+ * (validating-context → compacting → waiting-provider);此前 CLI 只有
10245
+ * llm-start 才进入明确 working 状态,压缩期间 spinner 停在通用
10246
+ * working 文案上,用户无法区分「卡在检查上下文 / 压缩 / 等模型」。
10247
+ * 两个显示面(bare CLI 的 spinner 与 TUI 的 dock activityReporter)与
10248
+ * showWorking 走同一条投影,保证两端文案不漂移。
10249
+ */
10250
+ showPhase(phase) {
10251
+ const label = phase === "validating-context" ? t("contextChecking") : phase === "compacting" ? t("contextCompacting") : t("waitingForModel");
10252
+ spinner.show(label);
10253
+ options.activityReporter?.(label);
10254
+ },
10042
10255
  finish(fallbackContent) {
10043
10256
  const flushedThink = flushThinkParser(thinkState);
10044
10257
  thinkState = flushedThink.state;
10045
10258
  if (flushedThink.content) {
10046
10259
  writeVisibleAssistantChunk(flushedThink.content);
10047
10260
  }
10261
+ if (assistantLabelManaged) flushPendingTuiNarration();
10048
10262
  endThinkingPhase();
10049
10263
  spinner.stop();
10050
10264
  options.activityReporter?.(null);
@@ -10149,6 +10363,7 @@ async function readStreamingAgentRun(options, res, existingSpinner) {
10149
10363
  let content = "";
10150
10364
  let dialogId;
10151
10365
  let usage;
10366
+ let sawDone = false;
10152
10367
  const handlePayload = (payload) => {
10153
10368
  if (typeof payload?.dialogId === "string" && payload.dialogId.trim()) {
10154
10369
  dialogId = payload.dialogId;
@@ -10161,6 +10376,7 @@ async function readStreamingAgentRun(options, res, existingSpinner) {
10161
10376
  }
10162
10377
  if (payload?.type === "done") {
10163
10378
  usage = payload.usage;
10379
+ sawDone = true;
10164
10380
  return;
10165
10381
  }
10166
10382
  if (payload?.type === "dialog" || payload?.type === "status") {
@@ -10214,6 +10430,9 @@ async function readStreamingAgentRun(options, res, existingSpinner) {
10214
10430
  }
10215
10431
  } catch (error) {
10216
10432
  turnOutput.spinner.stop();
10433
+ turnOutput.cancel({
10434
+ preservePendingNarration: !options.abortSignal?.aborted
10435
+ });
10217
10436
  if (options.abortSignal?.aborted) {
10218
10437
  return {
10219
10438
  exitCode: 0,
@@ -10243,6 +10462,15 @@ ${describeClientVersionTooOldFailure(message, error)}`);
10243
10462
  `);
10244
10463
  return { exitCode: 1 };
10245
10464
  }
10465
+ if (options.abortSignal?.aborted && !sawDone) {
10466
+ turnOutput.spinner.stop();
10467
+ turnOutput.cancel();
10468
+ return {
10469
+ exitCode: 0,
10470
+ ...dialogId ? { dialogId } : {},
10471
+ streamInterrupted: true
10472
+ };
10473
+ }
10246
10474
  turnOutput.finish(content);
10247
10475
  const usageText = formatUsage(usage, dialogId);
10248
10476
  if (usageText && shouldShowUsage(options.env))
@@ -10459,7 +10687,7 @@ function findCollapsedPasteSpanAt(buffer, pos, opts = {}) {
10459
10687
  // packages/cli/client/agentRun.ts
10460
10688
  import { ulid as ulid2 } from "ulid";
10461
10689
  async function loadRunLocalAgentTurn() {
10462
- const { runLocalAgentTurn } = await import("./agentRuntimeLocal-KCMC2TBD.js");
10690
+ const { runLocalAgentTurn } = await import("./agentRuntimeLocal-N4YGKL7M.js");
10463
10691
  return runLocalAgentTurn;
10464
10692
  }
10465
10693
  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();
@@ -10779,7 +11007,8 @@ function classifyLocalRunError(message) {
10779
11007
  }
10780
11008
  return { kind: "generic" };
10781
11009
  }
10782
- var HISTORY_REPLAY_REJECTION_RE = /invalid_request_error|invalid\s+tool\s+call\s+arguments?/i;
11010
+ var HISTORY_REPLAY_REJECTION_RE = /invalid\s+tool\s+call\s+arguments?/i;
11011
+ var REASONING_REPLAY_CONTRACT_RE = /reasoning_content[^.]*must be passed back/i;
10783
11012
  var RUN_UNAVAILABLE_PREFIX = "[nolo] auto runtime: local run unavailable";
10784
11013
  var NO_FALLBACK = "Not falling back to server.";
10785
11014
  var SERVER_FALLBACK_HINT = "or use --server to run on the server explicitly.";
@@ -10788,27 +11017,30 @@ function buildAuthFailure(ctx) {
10788
11017
  const fix = platformNoToken ? `This install is not logged in \u2014 run \`nolo login\`, or set AUTH_TOKEN / NOLO_SERVER` : ctx.where === "server chat proxy" ? `Check the agent's provider/api-key settings on nolo.chat` : `Fix the local credential/config and retry`;
10789
11018
  const { url: validationUrl, text: validationText } = extractGoogleValidationLink(ctx.message);
10790
11019
  const validationLabel = validationText || "Verify your account";
10791
- const validationHint = validationUrl ? `
10792
- \u24D8 This provider requires a one-time account verification. Open this link in a browser signed into that account, then retry:
10793
- ${formatCliHyperlink(
10794
- validationUrl,
10795
- validationLabel
10796
- )}` + // A 200-char Google url wraps on a narrow terminal, and a wrapped link
10797
- // loses its hit area in several terminals — so even when the clickable
10798
- // form is available, the raw url still gets its own copyable line. (In
10799
- // the disabled path `label (url)` already carries it.)
10800
- (resolveCliHyperlinkEnabled() ? `
10801
- \u6216\u590D\u5236\u6B64\u94FE\u63A5: ${validationUrl}` : "") : "";
10802
- return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}, auth rejected).${validationHint ? `${validationHint}
10803
- ` : " "}Detail: ${ctx.message} ${NO_FALLBACK} ${fix}, ${SERVER_FALLBACK_HINT}.
11020
+ if (validationUrl) {
11021
+ const linkLine = `
11022
+ ${formatCliHyperlink(validationUrl, validationLabel)}`;
11023
+ const rawLine = resolveCliHyperlinkEnabled() ? `
11024
+ \u70B9\u4E0D\u4E86\u5C31\u590D\u5236\u8FD9\u884C: ${validationUrl}` : "";
11025
+ const verifyHint = `
11026
+ \u24D8 \u60F3\u4E00\u952E\u6253\u5F00\uFF1F\u8DD1 \`nolo auth antigravity --verify\` \u2014\u2014 \u5B83\u4F1A\u7528\u672C\u5730\u51ED\u8BC1\u62FF\u5230\u5F53\u524D\u9A8C\u8BC1\u94FE\u63A5\u5E76\u76F4\u63A5\u62C9\u8D77\u6D4F\u89C8\u5668\u3002`;
11027
+ const retryLine = `
11028
+ \u9A8C\u8BC1\u5B8C\u6210\u540E\u76F4\u63A5\u91CD\u8BD5\u521A\u624D\u7684\u547D\u4EE4\u5373\u53EF\uFF0Ctoken \u4E0D\u7528\u91CD\u65B0\u767B\u5F55\u3002`;
11029
+ return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}: Google requires a one-time account verification \u2014 your credential is fine).
11030
+ Open this link in a browser signed into ${ctx.credentialAccountId ? `\`${ctx.credentialAccountId}\`` : "the Google account behind this credential"}:${linkLine}${rawLine}${verifyHint}${retryLine}
11031
+ Detail: ${ctx.message} ${NO_FALLBACK} Use --server to run on the server explicitly.
11032
+ `;
11033
+ }
11034
+ return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}, auth rejected). Detail: ${ctx.message} ${NO_FALLBACK} ${fix}, ${SERVER_FALLBACK_HINT}.
10804
11035
  `;
10805
11036
  }
10806
11037
  function isAuthNoTokenBody(message) {
10807
11038
  return /"authCode"\s*:\s*"AUTH_NO_TOKEN"/i.test(message) || /no authentication token provided/i.test(message);
10808
11039
  }
10809
11040
  function buildRejectedPayloadFailure(ctx) {
10810
- const looksLikeHistoryReplay = HISTORY_REPLAY_REJECTION_RE.test(ctx.message);
10811
- const cause = looksLikeHistoryReplay ? ` This usually happens when the dialog history contains tool_calls or reasoning produced by a different model/provider (e.g. after /switch); the new provider rejects that history. Start a fresh dialog, or clean the offending history.` : "";
11041
+ const looksLikeReasoningReplay = REASONING_REPLAY_CONTRACT_RE.test(ctx.message);
11042
+ const looksLikeHistoryReplay = !looksLikeReasoningReplay && HISTORY_REPLAY_REJECTION_RE.test(ctx.message);
11043
+ const cause = looksLikeReasoningReplay ? ` This is a thinking-mode replay contract violation: the history contains an assistant tool-call turn without reasoning_content, but this model requires every such turn to pass reasoning back to the API. The upstream may not have returned reasoning for that turn, or the history came from a different model.` : looksLikeHistoryReplay ? ` This usually happens when the dialog history contains tool_calls or reasoning produced by a different model/provider (e.g. after /switch); the new provider rejects that history. Start a fresh dialog, or clean the offending history.` : "";
10812
11044
  return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}, the provider rejected the request body \u2014 this is NOT a local credential/config issue). Detail: ${ctx.message}${cause} ${NO_FALLBACK} Use --server to run on the server explicitly, or start a fresh dialog.
10813
11045
  `;
10814
11046
  }
@@ -10835,6 +11067,17 @@ function buildUpstreamFailure(ctx) {
10835
11067
  return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}). Detail: ${ctx.message} ${NO_FALLBACK} ${fix}, ${SERVER_FALLBACK_HINT}.
10836
11068
  `;
10837
11069
  }
11070
+ function formatLocalTurnFailureLine(error) {
11071
+ const message = toErrorMessage(error);
11072
+ if (error?.code === "LLM_REQUEST_TIMEOUT") {
11073
+ const msMatch = /after (\d+)ms/.exec(message);
11074
+ const deadline = msMatch && Number.isFinite(Number(msMatch[1])) ? formatElapsed(Math.round(Number(msMatch[1]) / 1e3)) : "the configured window";
11075
+ return `[nolo] ${t("llmRequestTimedOut", deadline)}
11076
+ `;
11077
+ }
11078
+ return `[nolo] Local agent run failed: ${message}
11079
+ `;
11080
+ }
10838
11081
  var FAILURE_BUILDERS = {
10839
11082
  auth: buildAuthFailure,
10840
11083
  "rejected-payload": buildRejectedPayloadFailure,
@@ -10843,6 +11086,7 @@ var FAILURE_BUILDERS = {
10843
11086
  upstream: buildUpstreamFailure
10844
11087
  };
10845
11088
  function describeLocalRunFailure(message, rawError) {
11089
+ const credentialAccountId = rawError && typeof rawError === "object" && typeof rawError.credentialAccountId === "string" ? rawError.credentialAccountId.trim() || void 0 : void 0;
10846
11090
  if (rawError && typeof rawError === "object" && "code" in rawError && rawError.code === "PLATFORM_STREAM_INTERRUPTED") {
10847
11091
  return "[nolo] The platform LLM stream was interrupted before the turn completed. Your conversation was preserved. Send another message to continue.\n";
10848
11092
  }
@@ -10891,6 +11135,10 @@ function describeLocalRunFailure(message, rawError) {
10891
11135
  }
10892
11136
  if (/CLI authority broker could not attach or take ownership/i.test(message)) {
10893
11137
  const cleaned = stripDebugNoise(message);
11138
+ if (/EADDRINUSE/i.test(message)) {
11139
+ return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} Use --server to run on the server explicitly.
11140
+ `;
11141
+ }
10894
11142
  return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} The local runtime could not attach to an existing broker or take database ownership. Check running broker processes holding the local authority store or retry, ${SERVER_FALLBACK_HINT}.
10895
11143
  `;
10896
11144
  }
@@ -10920,7 +11168,8 @@ function describeLocalRunFailure(message, rawError) {
10920
11168
  status: cls.status,
10921
11169
  ...cls.statusInferred ? { statusInferred: true } : {},
10922
11170
  ...cls.quotaExhausted ? { quotaExhausted: true } : {},
10923
- ...cooldownUntil ? { cooldownUntil } : {}
11171
+ ...cooldownUntil ? { cooldownUntil } : {},
11172
+ ...credentialAccountId ? { credentialAccountId } : {}
10924
11173
  };
10925
11174
  return FAILURE_BUILDERS[cls.kind](ctx);
10926
11175
  }
@@ -11237,6 +11486,18 @@ async function runLocalAgentTurnForCli(options, settings) {
11237
11486
  if (event.kind === "llm-start") {
11238
11487
  turnOutput.showWorking();
11239
11488
  }
11489
+ if (event.kind === "turn-phase") {
11490
+ turnOutput.showPhase(event.phase);
11491
+ }
11492
+ if (event.kind === "compaction-start") {
11493
+ turnOutput.showPhase("compacting");
11494
+ }
11495
+ if (event.kind === "compaction-end" || // 压缩失败(timeout/provider-error)时 localLoop 按失败原子性语义
11496
+ // 带着裁剪后的历史继续本轮,切回等待模型文案;aborted 时 turn 随即
11497
+ // 结束,不再切文案(终态由 abort 路径收尾)。
11498
+ event.kind === "compaction-failed" && event.reason !== "aborted") {
11499
+ turnOutput.showPhase("waiting-provider");
11500
+ }
11240
11501
  if (event.kind === "image-downgraded") {
11241
11502
  options.output.write(
11242
11503
  "[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"
@@ -11282,6 +11543,9 @@ async function runLocalAgentTurnForCli(options, settings) {
11282
11543
  };
11283
11544
  } catch (error) {
11284
11545
  turnOutput.spinner.stop();
11546
+ turnOutput.cancel({
11547
+ preservePendingNarration: error?.code !== LOCAL_TURN_ABORTED_CODE && !options.abortSignal?.aborted
11548
+ });
11285
11549
  const savedDialogId = error?.dialogId;
11286
11550
  const abortedUsageRecords = error?.usageRecords;
11287
11551
  const abortedTurnCredits = sumPlatformCredits(abortedUsageRecords);
@@ -11305,10 +11569,12 @@ async function runLocalAgentTurnForCli(options, settings) {
11305
11569
  error.cooldownUntil = cooldownUntil;
11306
11570
  }
11307
11571
  if (settings.reportFailure) {
11308
- options.output.write(
11309
- `[nolo] Local agent run failed: ${toErrorMessage(error)}
11310
- `
11311
- );
11572
+ const failureLine = formatLocalTurnFailureLine(error);
11573
+ if (typeof options.output.writeErr === "function") {
11574
+ options.output.writeErr(failureLine);
11575
+ } else {
11576
+ options.output.write(failureLine);
11577
+ }
11312
11578
  if (cooldownUntil) {
11313
11579
  options.output.write(
11314
11580
  `[nolo] \u5DF2\u6807\u8BB0\u51B7\u5374\u81F3 ${cooldownUntil}\uFF0C\u5230\u671F\u524D\u6D3E\u53D1\u8BE5 agent \u4F1A\u88AB\u51B7\u5374\u95E8\u63A7\u62E6\u622A\u3002
@@ -11446,7 +11712,7 @@ async function runAgentTurn(options) {
11446
11712
  return { exitCode: 1 };
11447
11713
  }
11448
11714
  const localAvailability = await checkLocalAvailabilityBeforeHttpDispatch(options);
11449
- if (localAvailability?.exitCode) {
11715
+ if (localAvailability && "exitCode" in localAvailability) {
11450
11716
  return { exitCode: localAvailability.exitCode };
11451
11717
  }
11452
11718
  const httpResult = await runHttpAgentTurn(options, authToken);
@@ -12188,72 +12454,6 @@ var rankMemoryCandidates = (items, query, context) => {
12188
12454
  });
12189
12455
  };
12190
12456
 
12191
- // packages/ai/memory/vnext/store.ts
12192
- var enc = (value) => encodeURIComponent(value).replace(/-/g, "%2D");
12193
- var rangeOf = (prefix) => ({ gte: prefix, lte: `${prefix}\uFFFF` });
12194
- var entityKey = (ownerId, id) => `mem2-e-${enc(ownerId)}-${enc(id)}`;
12195
- var entityOwnerPrefix = (ownerId) => `mem2-e-${enc(ownerId)}-`;
12196
- var stateKey = (ownerId, id) => `mem2-s-${enc(ownerId)}-${enc(id)}`;
12197
- var stateEntityIndexKey = (ownerId, entityId, stateId) => `mem2-si-${enc(ownerId)}-${enc(entityId)}-${enc(stateId)}`;
12198
- var stateEntityIndexPrefix = (ownerId, entityId) => `mem2-si-${enc(ownerId)}-${enc(entityId)}-`;
12199
- var evidenceKey = (ownerId, id) => `mem2-v-${enc(ownerId)}-${enc(id)}`;
12200
- var relationKey = (ownerId, id) => `mem2-r-${enc(ownerId)}-${enc(id)}`;
12201
- var relationFromIndexKey = (ownerId, from, relationId) => `mem2-rf-${enc(ownerId)}-${enc(from)}-${enc(relationId)}`;
12202
- var relationToIndexKey = (ownerId, to, relationId) => `mem2-rt-${enc(ownerId)}-${enc(to)}-${enc(relationId)}`;
12203
- var readIndexed = async (db, prefix) => {
12204
- const refs = [];
12205
- for await (const [, value] of db.iterator({ ...rangeOf(prefix), reverse: false })) {
12206
- if (typeof value?.key === "string") refs.push(value.key);
12207
- }
12208
- const rows = await Promise.all(refs.map((key) => db.get(key).catch(() => null)));
12209
- return rows.filter((row) => !!row);
12210
- };
12211
- var getMemoryEntityVNext = async (db, ownerId, entityId) => db.get(entityKey(ownerId, entityId)).catch(() => null);
12212
- var listMemoryEntitiesVNext = async (db, ownerId) => {
12213
- const rows = [];
12214
- for await (const [, value] of db.iterator({
12215
- ...rangeOf(entityOwnerPrefix(ownerId)),
12216
- reverse: false
12217
- })) {
12218
- if (value) rows.push(value);
12219
- }
12220
- return rows;
12221
- };
12222
- var getMemoryStateVNext = async (db, ownerId, stateId) => db.get(stateKey(ownerId, stateId)).catch(() => null);
12223
- var listMemoryStatesForEntityVNext = (db, ownerId, entityId) => readIndexed(db, stateEntityIndexPrefix(ownerId, entityId));
12224
- var putMemoryEvidenceVNext = async (db, evidence) => {
12225
- await db.put(evidenceKey(evidence.ownerId, evidence.id), evidence);
12226
- };
12227
- var getMemoryEvidenceVNext = async (db, ownerId, evidenceId) => db.get(evidenceKey(ownerId, evidenceId)).catch(() => null);
12228
- var getMemoryEvidenceVNextStrict = async (db, ownerId, evidenceId) => {
12229
- try {
12230
- return await db.get(evidenceKey(ownerId, evidenceId));
12231
- } catch (error) {
12232
- if (isLevelNotFoundError(error)) return null;
12233
- throw error;
12234
- }
12235
- };
12236
- var _appendEntityBatch = (batch, entity) => {
12237
- batch.put(entityKey(entity.ownerId, entity.id), entity);
12238
- };
12239
- var _appendEvidenceBatch = (batch, evidence) => {
12240
- batch.put(evidenceKey(evidence.ownerId, evidence.id), evidence);
12241
- };
12242
- var _appendStateBatch = (batch, state2) => {
12243
- const key = stateKey(state2.ownerId, state2.id);
12244
- batch.put(key, state2);
12245
- batch.put(stateEntityIndexKey(state2.ownerId, state2.entityId, state2.id), { key });
12246
- };
12247
- var _appendRetiredStateBatch = (batch, state2) => {
12248
- batch.put(stateKey(state2.ownerId, state2.id), state2);
12249
- };
12250
- var _appendRelationBatch = (batch, relation) => {
12251
- const key = relationKey(relation.ownerId, relation.id);
12252
- batch.put(key, relation);
12253
- batch.put(relationFromIndexKey(relation.ownerId, relation.from, relation.id), { key });
12254
- batch.put(relationToIndexKey(relation.ownerId, relation.to, relation.id), { key });
12255
- };
12256
-
12257
12457
  // packages/ai/memory/vnext/recall.ts
12258
12458
  var MAX_RECALL_REFS = 6;
12259
12459
  var stripFence = (raw) => {
@@ -12283,14 +12483,6 @@ var parseSelection = (raw) => {
12283
12483
  reason: obj.reason
12284
12484
  };
12285
12485
  };
12286
- var buildCatalog = async (db, ownerId) => {
12287
- const entities = await listMemoryEntitiesVNext(db, ownerId);
12288
- const states = [];
12289
- for (const entity of entities) {
12290
- states.push(...await listMemoryStatesForEntityVNext(db, ownerId, entity.id));
12291
- }
12292
- return { entities, states };
12293
- };
12294
12486
  var catalogText = (entities, states) => JSON.stringify(
12295
12487
  {
12296
12488
  entities: entities.map((entity) => ({
@@ -12316,7 +12508,7 @@ var catalogText = (entities, states) => JSON.stringify(
12316
12508
  );
12317
12509
  var createMemoryVNextRecall = (input) => async (query) => {
12318
12510
  const startedAt = performance.now();
12319
- const { entities, states } = await buildCatalog(input.db, input.ownerId);
12511
+ const { entities, states } = await loadMemoryVNextCatalog(input.db, input.ownerId);
12320
12512
  if (entities.length === 0 && states.length === 0) {
12321
12513
  return {
12322
12514
  query,
@@ -13187,14 +13379,74 @@ var shortError2 = (error) => {
13187
13379
  return message.length > ERROR_MESSAGE_MAX2 ? `${message.slice(0, ERROR_MESSAGE_MAX2)}\u2026` : message;
13188
13380
  };
13189
13381
  var loadExistingContext = async (db, ownerId) => {
13190
- const entities = await listMemoryEntitiesVNext(db, ownerId);
13191
- const states = (await Promise.all(
13192
- entities.map((entity) => listMemoryStatesForEntityVNext(db, ownerId, entity.id))
13193
- )).flat();
13194
- return {
13195
- entityIds: entities.map((entity) => entity.id),
13196
- states
13382
+ const { entities, states } = await loadMemoryVNextCatalog(db, ownerId);
13383
+ return { entityIds: entities.map((entity) => entity.id), states };
13384
+ };
13385
+ var currentStatesCitingEvidence = (states, evidenceId) => states.filter((state2) => !state2.retiredAt && (state2.evidenceIds ?? []).includes(evidenceId));
13386
+ var isEvidenceCoveredByCurrentStates = (states, evidenceId) => currentStatesCitingEvidence(states, evidenceId).length > 0;
13387
+ var memoryVNextContextFingerprint = (existing) => {
13388
+ const states = existing.states ?? [];
13389
+ const entityIds = existing.entityIds ?? [];
13390
+ const canonical = [
13391
+ ...entityIds.map((id) => `e\0${id}`),
13392
+ ...states.map((state2) => `s\0${state2.id}\0${state2.updatedAt}\0${state2.retiredAt ?? ""}`)
13393
+ ].sort().join("");
13394
+ let hash = 2166136261;
13395
+ for (let i = 0; i < canonical.length; i++) {
13396
+ hash ^= canonical.charCodeAt(i);
13397
+ hash = Math.imul(hash, 16777619);
13398
+ }
13399
+ return `${entityIds.length}.${states.length}:${(hash >>> 0).toString(16)}`;
13400
+ };
13401
+ var MAX_NOOP_SUPPRESSIONS = 512;
13402
+ var noOpSuppressions = /* @__PURE__ */ new Map();
13403
+ var suppressionKey = (ownerId, evidenceId) => `${ownerId}\0${evidenceId}`;
13404
+ var recordNoOpSuppression = (ownerId, evidenceId, fingerprint) => {
13405
+ const key = suppressionKey(ownerId, evidenceId);
13406
+ noOpSuppressions.delete(key);
13407
+ noOpSuppressions.set(key, fingerprint);
13408
+ while (noOpSuppressions.size > MAX_NOOP_SUPPRESSIONS) {
13409
+ noOpSuppressions.delete(noOpSuppressions.keys().next().value);
13410
+ }
13411
+ };
13412
+ var noOpHistory = (ownerId, evidenceId, fingerprint) => {
13413
+ const recorded = noOpSuppressions.get(suppressionKey(ownerId, evidenceId));
13414
+ if (recorded === void 0) return "fresh";
13415
+ return recorded === fingerprint ? "suppressed" : "stale";
13416
+ };
13417
+ var pickFirstUncoveredLazyPromotionItem = async (db, selected) => {
13418
+ const contextByOwner = /* @__PURE__ */ new Map();
13419
+ const contextFor = (ownerId) => {
13420
+ let pending = contextByOwner.get(ownerId);
13421
+ if (!pending) {
13422
+ pending = loadExistingContext(db, ownerId).then((existing) => ({
13423
+ states: existing.states ?? [],
13424
+ fingerprint: memoryVNextContextFingerprint(existing)
13425
+ }));
13426
+ contextByOwner.set(ownerId, pending);
13427
+ }
13428
+ return pending;
13197
13429
  };
13430
+ let skippedCoveredCount = 0;
13431
+ let skippedNoOpCount = 0;
13432
+ let firstStale = null;
13433
+ for (const [selectedIndex, item] of selected.entries()) {
13434
+ const evidence = buildLegacyMemoryEvidence(item);
13435
+ const context = await contextFor(evidence.ownerId);
13436
+ if (isEvidenceCoveredByCurrentStates(context.states, evidence.id)) {
13437
+ skippedCoveredCount++;
13438
+ continue;
13439
+ }
13440
+ const history = noOpHistory(evidence.ownerId, evidence.id, context.fingerprint);
13441
+ if (history === "fresh") {
13442
+ return { item, selectedIndex, skippedCoveredCount, skippedNoOpCount };
13443
+ }
13444
+ if (history === "stale" && !firstStale) {
13445
+ firstStale = { item, selectedIndex, skippedCoveredCount, skippedNoOpCount };
13446
+ }
13447
+ skippedNoOpCount++;
13448
+ }
13449
+ return firstStale;
13198
13450
  };
13199
13451
  var withoutImportedEvidence = (mutation, importedEvidenceId) => ({
13200
13452
  ...mutation,
@@ -13210,6 +13462,11 @@ var runMemoryVNextLazyPromotion = async (input) => {
13210
13462
  }));
13211
13463
  const finish = (partial) => {
13212
13464
  const observation = {
13465
+ legacyItemId: input.item.id,
13466
+ evidenceId: deterministicEvidence.id,
13467
+ ...input.selectedIndex === void 0 ? {} : { selectedIndex: input.selectedIndex },
13468
+ ...input.skippedCoveredCount === void 0 ? {} : { skippedCoveredCount: input.skippedCoveredCount },
13469
+ ...input.skippedNoOpCount === void 0 ? {} : { skippedNoOpCount: input.skippedNoOpCount },
13213
13470
  ...partial,
13214
13471
  latencyMs: Math.round((clock() - startedAt) * 10) / 10
13215
13472
  };
@@ -13232,8 +13489,9 @@ var runMemoryVNextLazyPromotion = async (input) => {
13232
13489
  }
13233
13490
  const evidence = evidenceResult.evidence;
13234
13491
  const existing = await loadExistingContext(input.db, evidence.ownerId);
13235
- const alreadyCovered = (existing.states ?? []).some(
13236
- (state2) => !state2.retiredAt && state2.evidenceIds.includes(evidence.id)
13492
+ const alreadyCovered = isEvidenceCoveredByCurrentStates(
13493
+ existing.states ?? [],
13494
+ evidence.id
13237
13495
  );
13238
13496
  if (alreadyCovered) {
13239
13497
  return finish({ status: "already_covered" });
@@ -13248,6 +13506,11 @@ var runMemoryVNextLazyPromotion = async (input) => {
13248
13506
  });
13249
13507
  const semanticMutation = withoutImportedEvidence(interpreted.mutation, evidence.id);
13250
13508
  if (!hasWrites(semanticMutation)) {
13509
+ recordNoOpSuppression(
13510
+ evidence.ownerId,
13511
+ evidence.id,
13512
+ memoryVNextContextFingerprint(existing)
13513
+ );
13251
13514
  return finish({ status: "no_op", action: semanticMutation.action });
13252
13515
  }
13253
13516
  await applyMemoryInterpreterMutation(input.db, evidence.ownerId, semanticMutation);
@@ -13260,6 +13523,179 @@ var runMemoryVNextLazyPromotion = async (input) => {
13260
13523
  };
13261
13524
  var isMemoryVNextLazyPromotionEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_LAZY_PROMOTION === "1" || env.NOLO_MEMORY_VNEXT_LAZY_PROMOTION === "true";
13262
13525
 
13526
+ // packages/ai/memory/vnext/pureReadGate.ts
13527
+ var isMemoryVNextPureReadEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_PURE_READ === "1" || env.NOLO_MEMORY_VNEXT_PURE_READ === "true";
13528
+
13529
+ // packages/ai/memory/vnext/localRecall.ts
13530
+ var MIN_SHARED_TOKENS = 2;
13531
+ var MAX_LOCAL_RECALL_STATES = 8;
13532
+ var SAFE_TECHNICAL_SYNONYMS = {
13533
+ pr: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5", "diff"],
13534
+ diff: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5"],
13535
+ review: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5"],
13536
+ deploy: ["\u90E8\u7F72", "\u53D1\u7248"],
13537
+ release: ["\u53D1\u7248", "\u53D1\u5E03"],
13538
+ desktop: ["\u684C\u9762", "\u684C\u9762\u7AEF"]
13539
+ };
13540
+ var distinctTokens = (text) => new Set(tokenize2(text).filter((token) => token.length >= 2));
13541
+ var recallMemoryVNextLocal = (input) => {
13542
+ const rawTokens = distinctTokens(input.query);
13543
+ if (rawTokens.size === 0) return [];
13544
+ const queryTokens = new Set(rawTokens);
13545
+ for (const token of rawTokens) {
13546
+ const syns = SAFE_TECHNICAL_SYNONYMS[token.toLowerCase()];
13547
+ if (syns) {
13548
+ for (const syn of syns) {
13549
+ for (const t2 of distinctTokens(syn)) queryTokens.add(t2);
13550
+ }
13551
+ }
13552
+ }
13553
+ const entityById = new Map(input.entities.map((entity) => [entity.id, entity]));
13554
+ const hits = [];
13555
+ for (const state2 of input.states) {
13556
+ if (state2.retiredAt || !state2.text.trim()) continue;
13557
+ const entity = entityById.get(state2.entityId);
13558
+ const haystack = distinctTokens(
13559
+ [state2.facet, state2.text, entity?.name ?? "", ...entity?.aliases ?? []].join(" ")
13560
+ );
13561
+ let sharedTokens = 0;
13562
+ for (const token of queryTokens) if (haystack.has(token)) sharedTokens++;
13563
+ if (sharedTokens >= MIN_SHARED_TOKENS) hits.push({ state: state2, sharedTokens });
13564
+ }
13565
+ return hits.sort((a, b) => b.sharedTokens - a.sharedTokens || a.state.id.localeCompare(b.state.id)).slice(0, input.limit ?? MAX_LOCAL_RECALL_STATES);
13566
+ };
13567
+
13568
+ // packages/ai/memory/vnext/pureVNextRuntime.ts
13569
+ var buildSynthesizedStateItem = (state2, entity, ownerType, ownerId) => ({
13570
+ id: `vnext-state-${state2.id}`,
13571
+ ownerType,
13572
+ ownerId,
13573
+ visibility: "private",
13574
+ subjectType: "user",
13575
+ subjectId: ownerId,
13576
+ kind: "semantic",
13577
+ content: state2.text.trim(),
13578
+ createdAt: state2.createdAt,
13579
+ lastActivatedAt: state2.createdAt,
13580
+ activationCount: 1,
13581
+ importance: 0.9,
13582
+ confidence: 0.9,
13583
+ resident: state2.facet === "preference" || state2.facet === "style"
13584
+ });
13585
+ async function resolvePureVNextRuntime(input) {
13586
+ const { db, owners, userInput } = input;
13587
+ if (owners.length === 0 || !userInput.trim()) {
13588
+ return { selectedItems: [], promptBlock: null, recalledStateCount: 0 };
13589
+ }
13590
+ const ownerIds = owners.map((o) => `${o.ownerType}:${encodeURIComponent(o.ownerId)}`);
13591
+ const catalogs = await Promise.all(
13592
+ ownerIds.map((ownerId) => loadMemoryVNextCatalog(db, ownerId))
13593
+ );
13594
+ const selectedItems = [];
13595
+ const seenStateKeys = /* @__PURE__ */ new Set();
13596
+ for (let i = 0; i < owners.length; i++) {
13597
+ const owner = owners[i];
13598
+ const catalog = catalogs[i];
13599
+ const currentStates = catalog.states.filter((s) => !s.retiredAt && s.text.trim());
13600
+ const hits = recallMemoryVNextLocal({
13601
+ query: userInput,
13602
+ entities: catalog.entities,
13603
+ states: currentStates
13604
+ });
13605
+ const entityById = new Map(catalog.entities.map((e) => [e.id, e]));
13606
+ for (const hit of hits) {
13607
+ const stateKey = `${hit.state.ownerId}\0${hit.state.id}`;
13608
+ if (seenStateKeys.has(stateKey)) continue;
13609
+ seenStateKeys.add(stateKey);
13610
+ selectedItems.push(
13611
+ buildSynthesizedStateItem(hit.state, entityById.get(hit.state.entityId), owner.ownerType, owner.ownerId)
13612
+ );
13613
+ }
13614
+ }
13615
+ const promptBlock = selectedItems.length === 0 ? null : buildMemoryOverlay(selectedItems, {
13616
+ maxTokens: input.maxTokens ?? DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET
13617
+ });
13618
+ return {
13619
+ selectedItems,
13620
+ promptBlock,
13621
+ recalledStateCount: selectedItems.length
13622
+ };
13623
+ }
13624
+
13625
+ // packages/ai/memory/vnext/primaryRead.ts
13626
+ var MEMORY_VNEXT_PRIMARY_READ_TIMEOUT_MS = 300;
13627
+ var isMemoryVNextPrimaryReadEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_PRIMARY_READ === "1" || env.NOLO_MEMORY_VNEXT_PRIMARY_READ === "true";
13628
+ var buildSynthesizedStateItem2 = (state2, entity, ownerType, ownerId) => ({
13629
+ id: `vnext-state-${state2.id}`,
13630
+ ownerType,
13631
+ ownerId,
13632
+ visibility: "private",
13633
+ subjectType: "user",
13634
+ subjectId: ownerId,
13635
+ kind: "semantic",
13636
+ content: state2.text.trim(),
13637
+ createdAt: state2.createdAt,
13638
+ importance: 0.9,
13639
+ confidence: 0.9,
13640
+ // Flag resident preferences so they flow into overlay's resident section.
13641
+ resident: state2.facet === "preference" || state2.facet === "style",
13642
+ lastActivatedAt: state2.createdAt,
13643
+ activationCount: 1
13644
+ });
13645
+ var resolveMemoryVNextM4Selection = async (input) => {
13646
+ const { db, owners, query, selected } = input;
13647
+ const ownerIds = owners.map((o) => `${o.ownerType}:${encodeURIComponent(o.ownerId)}`);
13648
+ const catalogs = new Map(
13649
+ await Promise.all(
13650
+ ownerIds.map(async (ownerId) => [
13651
+ ownerId,
13652
+ await loadMemoryVNextCatalog(db, ownerId)
13653
+ ])
13654
+ )
13655
+ );
13656
+ const recalledStates = [];
13657
+ const recalledStateIds = /* @__PURE__ */ new Set();
13658
+ for (const owner of owners) {
13659
+ const principalId = `${owner.ownerType}:${encodeURIComponent(owner.ownerId)}`;
13660
+ const catalog = catalogs.get(principalId);
13661
+ if (!catalog) continue;
13662
+ const currentStates = catalog.states.filter((s) => !s.retiredAt && s.text.trim());
13663
+ const hits = recallMemoryVNextLocal({
13664
+ query,
13665
+ entities: catalog.entities,
13666
+ states: currentStates
13667
+ });
13668
+ const entityById = new Map(catalog.entities.map((e) => [e.id, e]));
13669
+ for (const hit of hits) {
13670
+ if (recalledStateIds.has(hit.state.id)) continue;
13671
+ recalledStateIds.add(hit.state.id);
13672
+ recalledStates.push(
13673
+ buildSynthesizedStateItem2(hit.state, entityById.get(hit.state.entityId), owner.ownerType, owner.ownerId)
13674
+ );
13675
+ }
13676
+ }
13677
+ const uncoveredLegacy = [];
13678
+ let coveredSuppressedCount = 0;
13679
+ for (const item of selected) {
13680
+ const evidence = buildLegacyMemoryEvidence(item);
13681
+ const catalog = catalogs.get(evidence.ownerId);
13682
+ const states = catalog?.states ?? [];
13683
+ const covering = currentStatesCitingEvidence(states, evidence.id);
13684
+ if (covering.length > 0) {
13685
+ coveredSuppressedCount++;
13686
+ } else {
13687
+ uncoveredLegacy.push(item);
13688
+ }
13689
+ }
13690
+ const renderItems = [...recalledStates, ...uncoveredLegacy];
13691
+ return {
13692
+ renderItems,
13693
+ recalledStateCount: recalledStates.length,
13694
+ uncoveredLegacyCount: uncoveredLegacy.length,
13695
+ coveredSuppressedCount
13696
+ };
13697
+ };
13698
+
13263
13699
  // packages/ai/memory/runtime.ts
13264
13700
  var COLD_STORAGE_CONFIDENCE = 0.3;
13265
13701
  var MEMORY_OVERLAY_TOKEN_BUDGET = DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET;
@@ -13382,6 +13818,18 @@ var resolveMemoryRuntime = async (input) => {
13382
13818
  if (owners.length === 0) {
13383
13819
  return { selectedItems: [], promptBlock: null };
13384
13820
  }
13821
+ if (isMemoryVNextPureReadEnabled()) {
13822
+ const pure = await resolvePureVNextRuntime({
13823
+ db: input.db,
13824
+ owners,
13825
+ userInput: input.userInput,
13826
+ maxTokens: MEMORY_OVERLAY_TOKEN_BUDGET
13827
+ });
13828
+ return {
13829
+ selectedItems: pure.selectedItems,
13830
+ promptBlock: pure.promptBlock
13831
+ };
13832
+ }
13385
13833
  const policy = resolveAgentMemoryPolicy({ agentKey: input.agentKey });
13386
13834
  const legacyStartedAt = performance.now();
13387
13835
  const candidates = await loadMemoryCandidatesFromDb(input.db, {
@@ -13411,10 +13859,62 @@ var resolveMemoryRuntime = async (input) => {
13411
13859
  );
13412
13860
  const selected = [...residentItems, ...ranked];
13413
13861
  const legacyLatencyMs = Math.round((performance.now() - legacyStartedAt) * 10) / 10;
13414
- const promptBlock = selected.length === 0 ? null : buildMemoryOverlay(selected, { maxTokens: MEMORY_OVERLAY_TOKEN_BUDGET });
13415
- const shadowEnabled = input.vNextShadowProvider != null && isMemoryVNextShadowReadEnabled();
13862
+ const renderOverlay = (items) => items.length === 0 ? null : buildMemoryOverlay(items, { maxTokens: MEMORY_OVERLAY_TOKEN_BUDGET });
13863
+ let promptBlock = renderOverlay(selected);
13864
+ const primaryRead = isMemoryVNextPrimaryReadEnabled();
13865
+ let allCoveredByVNext = false;
13866
+ if (primaryRead) {
13867
+ const emitPrimary = (observation) => {
13868
+ try {
13869
+ (input.primaryReadEmit ?? ((o) => console.info("[memory] vnext primary read", { event: "memory_vnext_primary_read", ...o })))(observation);
13870
+ } catch {
13871
+ }
13872
+ };
13873
+ const base = { legacyHitCount: selected.length, legacyLatencyMs };
13874
+ const vnextStartedAt = performance.now();
13875
+ const vnextLatency = () => Math.round((performance.now() - vnextStartedAt) * 10) / 10;
13876
+ if (selected.length === 0) {
13877
+ emitPrimary({ ...base, source: "none" });
13878
+ } else {
13879
+ try {
13880
+ let timer;
13881
+ const m4 = await Promise.race([
13882
+ resolveMemoryVNextM4Selection({ db: input.db, owners, query: input.userInput, selected }),
13883
+ new Promise((_, reject) => {
13884
+ timer = setTimeout(
13885
+ () => reject(Object.assign(new Error("timeout"), { name: "TimeoutError" })),
13886
+ MEMORY_VNEXT_PRIMARY_READ_TIMEOUT_MS
13887
+ );
13888
+ })
13889
+ ]).finally(() => clearTimeout(timer));
13890
+ promptBlock = renderOverlay(m4.renderItems);
13891
+ allCoveredByVNext = m4.uncoveredLegacyCount === 0 && m4.recalledStateCount > 0;
13892
+ const source = m4.recalledStateCount > 0 ? m4.uncoveredLegacyCount === 0 ? "vnext" : "hybrid" : m4.uncoveredLegacyCount > 0 ? "legacy_fallback" : "none";
13893
+ emitPrimary({
13894
+ ...base,
13895
+ source,
13896
+ uncoveredLegacyCount: m4.uncoveredLegacyCount,
13897
+ coveredSuppressedCount: m4.coveredSuppressedCount,
13898
+ recalledStateCount: m4.recalledStateCount,
13899
+ vnextLatencyMs: vnextLatency(),
13900
+ contextChars: promptBlock?.length ?? 0,
13901
+ ...source === "legacy_fallback" ? { fallbackReason: "no_vnext_context" } : {}
13902
+ });
13903
+ } catch (error) {
13904
+ emitPrimary({
13905
+ ...base,
13906
+ source: "legacy_fallback",
13907
+ vnextLatencyMs: vnextLatency(),
13908
+ contextChars: promptBlock?.length ?? 0,
13909
+ fallbackReason: "vnext_error",
13910
+ error: error instanceof Error ? error.name : "UnknownError"
13911
+ });
13912
+ }
13913
+ }
13914
+ }
13915
+ const shadowEnabled = !primaryRead && input.vNextShadowProvider != null && isMemoryVNextShadowReadEnabled();
13416
13916
  if (shadowEnabled) {
13417
- await runMemoryVNextShadowRead({
13917
+ void runMemoryVNextShadowRead({
13418
13918
  ctx: {
13419
13919
  db: input.db,
13420
13920
  owners,
@@ -13424,17 +13924,28 @@ var resolveMemoryRuntime = async (input) => {
13424
13924
  legacyItems: selected,
13425
13925
  legacyLatencyMs,
13426
13926
  legacyContextChars: promptBlock?.length ?? 0
13927
+ }).catch(() => {
13427
13928
  });
13428
13929
  }
13429
- const promotionCandidate = selected[0];
13430
13930
  const lazyPromotionEnabled = input.vNextShadowProvider != null && isMemoryVNextLazyPromotionEnabled();
13431
- if (lazyPromotionEnabled && promotionCandidate) {
13432
- void runMemoryVNextLazyPromotion({
13433
- db: input.db,
13434
- item: promotionCandidate,
13435
- provider: input.vNextShadowProvider,
13436
- ...input.lazyPromotionEmit ? { emit: input.lazyPromotionEmit } : {}
13437
- }).catch(() => {
13931
+ if (lazyPromotionEnabled && selected.length > 0 && !allCoveredByVNext) {
13932
+ void (async () => {
13933
+ const promotionPick = await pickFirstUncoveredLazyPromotionItem(
13934
+ input.db,
13935
+ selected
13936
+ );
13937
+ if (promotionPick) {
13938
+ await runMemoryVNextLazyPromotion({
13939
+ db: input.db,
13940
+ item: promotionPick.item,
13941
+ selectedIndex: promotionPick.selectedIndex,
13942
+ skippedCoveredCount: promotionPick.skippedCoveredCount,
13943
+ skippedNoOpCount: promotionPick.skippedNoOpCount,
13944
+ provider: input.vNextShadowProvider,
13945
+ ...input.lazyPromotionEmit ? { emit: input.lazyPromotionEmit } : {}
13946
+ });
13947
+ }
13948
+ })().catch(() => {
13438
13949
  });
13439
13950
  }
13440
13951
  if (selected.length === 0) {
@@ -13448,6 +13959,52 @@ var resolveMemoryRuntime = async (input) => {
13448
13959
  };
13449
13960
 
13450
13961
  // packages/cli/memoryRecall.ts
13962
+ var logger = getLogger("cli.memoryRecall");
13963
+ var DEDUP_WINDOW_MS = 5 * 60 * 1e3;
13964
+ var DEDUP_MAX_KEYS = 100;
13965
+ var dedupMap = /* @__PURE__ */ new Map();
13966
+ function evictDedupIfNeeded() {
13967
+ if (dedupMap.size < DEDUP_MAX_KEYS) return;
13968
+ let oldestKey = null;
13969
+ let oldestTs = Infinity;
13970
+ for (const [k, v] of dedupMap) {
13971
+ if (v.lastLog < oldestTs) {
13972
+ oldestTs = v.lastLog;
13973
+ oldestKey = k;
13974
+ }
13975
+ }
13976
+ if (oldestKey !== null) dedupMap.delete(oldestKey);
13977
+ }
13978
+ function logDeduped(level, fingerprint, message, error) {
13979
+ const now = Date.now();
13980
+ const entry = dedupMap.get(fingerprint);
13981
+ if (!entry) {
13982
+ evictDedupIfNeeded();
13983
+ dedupMap.set(fingerprint, { count: 1, suppressed: 0, lastLog: now });
13984
+ if (error !== void 0) logger[level](message, error);
13985
+ else logger[level](message);
13986
+ return;
13987
+ }
13988
+ entry.count += 1;
13989
+ if (now - entry.lastLog >= DEDUP_WINDOW_MS) {
13990
+ const suppressed = entry.suppressed;
13991
+ const summary = `${message} (deduplicated: ${entry.count} occurrences, ${suppressed} suppressed over ${Math.round((now - entry.lastLog) / 1e3)}s)`;
13992
+ if (error !== void 0) logger[level](summary, error);
13993
+ else logger[level](summary);
13994
+ entry.count = 1;
13995
+ entry.suppressed = 0;
13996
+ entry.lastLog = now;
13997
+ } else {
13998
+ entry.suppressed += 1;
13999
+ }
14000
+ }
14001
+ function fingerprintFor(kind, detail) {
14002
+ const d = detail === void 0 ? "" : sanitizeFp(String(detail));
14003
+ return `mem-${kind}:${d}`;
14004
+ }
14005
+ function sanitizeFp(s) {
14006
+ return s.replace(/\s+/g, " ").slice(0, 80);
14007
+ }
13451
14008
  var queryRemoteMemory = async (serverUrl, authToken, agentKey, userInput, spaceId) => {
13452
14009
  try {
13453
14010
  const response = await fetch(`${serverUrl}/api/memory/query`, {
@@ -13464,10 +14021,10 @@ var queryRemoteMemory = async (serverUrl, authToken, agentKey, userInput, spaceI
13464
14021
  signal: AbortSignal.timeout(5e3)
13465
14022
  });
13466
14023
  if (!response.ok) {
13467
- console.warn(
13468
- "[cli-memory] remote query returned non-ok status:",
13469
- response.status,
13470
- "\u2014 falling back to local"
14024
+ logDeduped(
14025
+ "warn",
14026
+ fingerprintFor("remote-nonok", response.status),
14027
+ `remote query returned non-ok status ${response.status} \u2014 falling back to local`
13471
14028
  );
13472
14029
  return null;
13473
14030
  }
@@ -13475,7 +14032,12 @@ var queryRemoteMemory = async (serverUrl, authToken, agentKey, userInput, spaceI
13475
14032
  const block = typeof payload?.promptBlock === "string" ? payload.promptBlock.trim() : "";
13476
14033
  return block || null;
13477
14034
  } catch (error) {
13478
- console.warn("[cli-memory] remote query failed, falling back to local:", error);
14035
+ logDeduped(
14036
+ "info",
14037
+ fingerprintFor("remote-failed", error instanceof Error ? error.name : void 0),
14038
+ "remote query failed, falling back to local",
14039
+ normalizeError(error)
14040
+ );
13479
14041
  return null;
13480
14042
  }
13481
14043
  };
@@ -13511,7 +14073,12 @@ var resolveCliMemory = async (input) => {
13511
14073
  input.spaceId
13512
14074
  );
13513
14075
  } catch (error) {
13514
- console.warn("[cli-memory] local recall failed, omitting memory layer:", error);
14076
+ logDeduped(
14077
+ "warn",
14078
+ fingerprintFor("local-failed", error instanceof Error ? error.name : void 0),
14079
+ "local recall failed, omitting memory layer",
14080
+ normalizeError(error)
14081
+ );
13515
14082
  return null;
13516
14083
  }
13517
14084
  };
@@ -13566,7 +14133,10 @@ async function resolveAgentRunAgentKey(args) {
13566
14133
  }
13567
14134
  async function runAgentRunCommand(args, deps) {
13568
14135
  const env = deps.env ?? process.env;
13569
- const output = deps.output ?? process.stdout;
14136
+ const output = deps.output ?? {
14137
+ write: (chunk) => process.stdout.write(chunk),
14138
+ writeErr: (chunk) => process.stderr.write(chunk)
14139
+ };
13570
14140
  if (args.includes("--help") || args.includes("-h")) {
13571
14141
  writeUsage(output, deps.commandPath);
13572
14142
  return 0;
@@ -14108,12 +14678,6 @@ function isBalanceExhaustedError(error) {
14108
14678
  }
14109
14679
 
14110
14680
  export {
14111
- resolveAgentModelIdentity,
14112
- resolveAgentContextWindow,
14113
- platformCreditsFromUsage,
14114
- formatCreditsChip,
14115
- formatTokenCount,
14116
- renderTokenStatus,
14117
14681
  resolveCliColorEnabled,
14118
14682
  dimCliText,
14119
14683
  ANSI_ESCAPE_REGEX,
@@ -14154,6 +14718,12 @@ export {
14154
14718
  formatAssistantDisplay,
14155
14719
  redactSecrets,
14156
14720
  TUI_TREE_MARKER,
14721
+ resolveAgentModelIdentity,
14722
+ resolveAgentContextWindow,
14723
+ platformCreditsFromUsage,
14724
+ formatCreditsChip,
14725
+ formatTokenCount,
14726
+ renderTokenStatus,
14157
14727
  COLLAPSED_PASTE_PLACEHOLDER_RE,
14158
14728
  shouldCollapsePaste,
14159
14729
  createCollapsedPasteStore,
@@ -14165,14 +14735,14 @@ export {
14165
14735
  expandRangeToCollapsedPasteChips,
14166
14736
  findCollapsedPasteSpanAt,
14167
14737
  runAgentTurn,
14168
- readAgentsMdLayerFromDisk,
14169
14738
  resolveWorkflowReference,
14170
14739
  resolveSkillReference,
14171
14740
  buildSkillContextBlocks,
14172
14741
  prependSubjectDialogMarker,
14173
14742
  normalizeCliImageInput,
14174
- inspectLocalRunWorkspace,
14743
+ readAgentsMdLayerFromDisk,
14175
14744
  resolveCliMemory,
14745
+ inspectLocalRunWorkspace,
14176
14746
  resolveRunOutcome,
14177
14747
  isRunResultStalledOrTruncated,
14178
14748
  resolveRunSettlementNote,