nolo-cli 0.91.0-alpha.1 → 0.91.1

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 (173) hide show
  1. package/README.md +1 -1
  2. package/{_executeModel-U5V7LOJX.js → _executeModel-H35GQ2XO.js} +61 -60
  3. package/{action-EXQVY3UO.js → action-3ZOODRBC.js} +11 -11
  4. package/{addContentAction-6IXQSRD2.js → addContentAction-IJHG2ZV7.js} +9 -9
  5. package/{addDialogAgentAction-FZOB4BYM.js → addDialogAgentAction-IGFS2UBX.js} +11 -11
  6. package/{agentDeleteCommand-4MIJFQQB.js → agentDeleteCommand-XOFMXMHW.js} +43 -42
  7. package/{agentEmailCommands-JUXT36BY.js → agentEmailCommands-H2SEP6ZQ.js} +82 -78
  8. package/{agentGrantCommands-YW6PQAQ2.js → agentGrantCommands-M3XFO6EN.js} +2 -2
  9. package/{agentListCommands-MUVKMMZ5.js → agentListCommands-RYGH6NUL.js} +72 -80
  10. package/{agentMachineCommands-56FTZLYV.js → agentMachineCommands-XELOBZIP.js} +37 -36
  11. package/{agentProviderCommands-TOMVKJOV.js → agentProviderCommands-JCRK6ST2.js} +1 -1
  12. package/{agentPullCommand-GLOOXJ2E.js → agentPullCommand-HF4A42D4.js} +3 -3
  13. package/agentRecordCommands-43HAXAZO.js +130 -0
  14. package/{agentRunCommand-UMUEVIY2.js → agentRunCommand-GIPN6DBO.js} +80 -75
  15. package/{agentRunControl-XLGD3UZ5.js → agentRunControl-AVJR4JW4.js} +2 -2
  16. package/{agentRuntimeLocal-NH6GSGAJ.js → agentRuntimeLocal-SDOSSCLU.js} +38 -33
  17. package/{agentSlice-YZK6KG73.js → agentSlice-B2DLZMAC.js} +11 -11
  18. package/{appDeleteCommands-U45KXYX7.js → appDeleteCommands-7OR5MAOR.js} +37 -36
  19. package/{appDeployCommands-LWQIQCFX.js → appDeployCommands-5GNI723H.js} +37 -36
  20. package/{appDeployStatusCommands-LZO33PGD.js → appDeployStatusCommands-WL2NG3SG.js} +37 -36
  21. package/{appGetCommands-OJSO6BCF.js → appGetCommands-7BVKQS44.js} +37 -36
  22. package/{appListCommands-NE56V7DI.js → appListCommands-5VXFJOBU.js} +37 -36
  23. package/{authCommand-U5LA6H4Y.js → authCommand-N4Q6463J.js} +115 -23
  24. package/{authCommands-RGOGCPP6.js → authCommands-GBIFZWD3.js} +5 -5
  25. package/{builtinSkillRegistry-4NB7PCOF.js → builtinSkillRegistry-JPY2DKRF.js} +7 -7
  26. package/{chatQueueReduxAdapter-FRMSYX7N.js → chatQueueReduxAdapter-3KDRKXTT.js} +29 -29
  27. package/{chromeCommands-VOIRNJBL.js → chromeCommands-NKU3OWKH.js} +36 -11
  28. package/{chromeOpsCommands-M7DPCX2T.js → chromeOpsCommands-OQDJGD4Y.js} +31 -1
  29. package/{chunk-R2YY6MWV.js → chunk-232453C2.js} +994 -1036
  30. package/{chunk-HWZAXNO7.js → chunk-25GAGMRK.js} +6 -83
  31. package/{chunk-DM4UNXPK.js → chunk-3IYMTWYZ.js} +22 -22
  32. package/{chunk-NTW5GWDM.js → chunk-3VNWWVKB.js} +2 -0
  33. package/{chunk-X2ZTVRXP.js → chunk-46CRK7XP.js} +7 -7
  34. package/{chunk-WKEUHK57.js → chunk-55VQ4OPL.js} +4 -4
  35. package/{chunk-JPGCXHNM.js → chunk-5OA5HMTL.js} +1 -1
  36. package/{chunk-DWUCB2A3.js → chunk-62IL3KQV.js} +4 -34
  37. package/{chunk-4JBZUECA.js → chunk-64TIEZHF.js} +1 -1
  38. package/{chunk-6YTOJY35.js → chunk-6D2JFXLY.js} +35 -0
  39. package/{chunk-3BMYXEUW.js → chunk-6O4IK4V2.js} +1 -1
  40. package/{chunk-UBNV6CS6.js → chunk-6PELJ3DS.js} +533 -236
  41. package/{chunk-7IBK6MYW.js → chunk-7EMJBGCA.js} +966 -218
  42. package/{chunk-YPYMGGPJ.js → chunk-7YMUSSHQ.js} +93 -93
  43. package/chunk-ACTMNVHM.js +93 -0
  44. package/{chunk-Q554LLSI.js → chunk-AUDNYVRC.js} +1 -1
  45. package/{chunk-UKWGR5SS.js → chunk-AUXHZ2M5.js} +186 -397
  46. package/{chunk-377KM42Z.js → chunk-B4PW6UAI.js} +61 -34
  47. package/{chunk-XLGHBHGP.js → chunk-B7ANJQWZ.js} +2 -2
  48. package/{chunk-COM7GG76.js → chunk-BAAKVSMZ.js} +4 -4
  49. package/{chunk-QMASIHYZ.js → chunk-BFCXG6AJ.js} +16 -16
  50. package/{chunk-KR3YI36B.js → chunk-BJUDYFV5.js} +10 -2
  51. package/chunk-BMQ2MJUK.js +153 -0
  52. package/{chunk-XGJAR4T5.js → chunk-BNGW5ASC.js} +65 -4
  53. package/{chunk-VOOTT7HA.js → chunk-BTSYHR7J.js} +4 -4
  54. package/{chunk-LS2ZANRJ.js → chunk-CTUQJVQM.js} +1 -1
  55. package/{chunk-JEDZAO7L.js → chunk-D2W6WRHT.js} +13 -8
  56. package/{chunk-U47DH2WO.js → chunk-D76D3RTR.js} +2 -2
  57. package/{chunk-HQCSU3DI.js → chunk-DCLMZ5TX.js} +4 -4
  58. package/{chunk-OOLWKQSM.js → chunk-EFZKILX6.js} +4 -4
  59. package/{chunk-WP6BC7OF.js → chunk-EHO5EGU4.js} +23 -76
  60. package/{chunk-HVURBGF3.js → chunk-ESRMFY7G.js} +2 -2
  61. package/{chunk-ABQYVJBJ.js → chunk-ETZWFV6M.js} +1 -1
  62. package/{chunk-TRV2MIDW.js → chunk-EXAJ6DCR.js} +1 -0
  63. package/{chunk-BF2K6MRF.js → chunk-F64B2W3R.js} +110 -34
  64. package/{chunk-S3UI4IUJ.js → chunk-G4EMOUX3.js} +886 -154
  65. package/{chunk-B4S7MR5S.js → chunk-GJUKGFHG.js} +74 -16
  66. package/{chunk-LSSBA2TN.js → chunk-GMVELWJG.js} +3 -3
  67. package/chunk-GMZLP5DV.js +82 -0
  68. package/{chunk-CJCJF5XB.js → chunk-H6A6X4EK.js} +36 -3
  69. package/{chunk-DSX6K7C2.js → chunk-HBTA2SGQ.js} +97 -21
  70. package/{chunk-ONXOABJR.js → chunk-HNGRBWYF.js} +3 -0
  71. package/{chunk-W2E6HIIK.js → chunk-HNRASX3X.js} +8 -8
  72. package/{chunk-CPH3W5A7.js → chunk-I3TQJXQ7.js} +94 -3
  73. package/{chunk-E3VQ6S3A.js → chunk-IS5VEM2G.js} +140 -15
  74. package/{chunk-NKIH4Q7W.js → chunk-ISHYYQJC.js} +5 -3
  75. package/{chunk-RLEWGSM5.js → chunk-K7M4I3PF.js} +30 -7
  76. package/{chunk-OH7H6LPC.js → chunk-KQOD3G2X.js} +165 -15
  77. package/{chunk-YOXYA2GU.js → chunk-LNPYTNMG.js} +10 -5
  78. package/{chunk-GRDSMV4V.js → chunk-LS2MI3B4.js} +45 -45
  79. package/{chunk-GII32WZW.js → chunk-M2EJHDJP.js} +3 -0
  80. package/{chunk-7S4YWN7P.js → chunk-MX574M24.js} +1 -1
  81. package/{chunk-RZYQMSQA.js → chunk-N3XA2O6O.js} +1 -1
  82. package/{chunk-SASGLNUD.js → chunk-NILSKYOE.js} +3 -3
  83. package/chunk-OCZKATRC.js +129 -0
  84. package/{chunk-MBEEYLGL.js → chunk-OOSVFT6S.js} +2 -2
  85. package/{chunk-QCZX4FTW.js → chunk-OY5IJI2N.js} +194 -21
  86. package/{chunk-SUERPXJZ.js → chunk-PAYUVQ6P.js} +7517 -1091
  87. package/{chunk-JTYPAMGP.js → chunk-Q67DOFOO.js} +59 -4
  88. package/{chunk-F3UTRUDO.js → chunk-QALRKMHF.js} +11 -10
  89. package/{chunk-546FPOW3.js → chunk-QDSINZM3.js} +1 -1
  90. package/{chunk-TMAZ3VHN.js → chunk-QJLEMM2V.js} +1 -1
  91. package/{chunk-IIKPWSPX.js → chunk-R4SQ3LGW.js} +1 -1
  92. package/{chunk-E2NP7ZQU.js → chunk-RZ6CQZB2.js} +34 -20
  93. package/{chunk-SAFZABH7.js → chunk-SV5IJK6K.js} +1 -1
  94. package/{chunk-AQDH76OK.js → chunk-T5V7HA3K.js} +1 -1
  95. package/{chunk-BYMV6QZG.js → chunk-TNIX77YM.js} +4 -0
  96. package/chunk-UNYJU5L6.js +780 -0
  97. package/{chunk-QFMFJZLO.js → chunk-V7E4PXQD.js} +1 -1
  98. package/{chunk-G5X57NDE.js → chunk-VBSVA6CB.js} +2 -2
  99. package/{chunk-3XMOAYRC.js → chunk-VETFWL5K.js} +1 -1
  100. package/chunk-VJVNU77E.js +83 -0
  101. package/{chunk-6D6VBVEW.js → chunk-VPFEPRME.js} +9 -9
  102. package/{chunk-HGRDL36J.js → chunk-W2P25VGS.js} +25 -6
  103. package/{chunk-XAQAF25W.js → chunk-WC6A2Q7S.js} +5 -3
  104. package/{chunk-WON762L4.js → chunk-WT2IAJAJ.js} +4 -4
  105. package/chunk-X6YIXGPT.js +870 -0
  106. package/{chunk-ZKMYGRO7.js → chunk-YMPTI7RZ.js} +9 -9
  107. package/{chunk-BKP7CFUD.js → chunk-YRIFJ6XQ.js} +13 -13
  108. package/{chunk-FZGV4FGK.js → chunk-YRRASA5Q.js} +268 -143
  109. package/{chunk-UDEFS2PV.js → chunk-Z5W7UMQV.js} +2 -2
  110. package/{chunk-ZHUTWJ3N.js → chunk-ZGJLSHER.js} +2 -2
  111. package/{chunk-4CAPEGHN.js → chunk-ZI2MEZMT.js} +304 -136
  112. package/{chunk-2F7RJC6L.js → chunk-ZOVKKMF6.js} +1 -1
  113. package/commandRegistry-BP5JLW24.js +822 -0
  114. package/{contentThunks-TC3AENBY.js → contentThunks-2HYFUXUM.js} +29 -29
  115. package/{cooldownCommands-BSCH2W7P.js → cooldownCommands-ZLEPIB4A.js} +2 -2
  116. package/{createAgentAutomationAction-67EOD3WK.js → createAgentAutomationAction-DCKUSJH7.js} +29 -29
  117. package/{createDialogAction-4OCQC5MW.js → createDialogAction-NRIAEH2A.js} +32 -32
  118. package/{createPageAction-JLGVP57B.js → createPageAction-AUJHHXGG.js} +35 -35
  119. package/{dbSlice-RDGCE5MU.js → dbSlice-HFPIJT5P.js} +8 -8
  120. package/{deleteFile-YG6QMJLU.js → deleteFile-UEAD5A5Z.js} +3 -3
  121. package/{dialogCommands-JHSDKCR5.js → dialogCommands-UJRGCRN6.js} +42 -39
  122. package/{dialogSlice-I2DK32ZT.js → dialogSlice-AHU4XXIW.js} +35 -29
  123. package/{dist-VODFSGNG.js → dist-NJC2W7I4.js} +61 -54
  124. package/{docCreateCommands-QUL6VWK2.js → docCreateCommands-ZOV3ZBLW.js} +39 -38
  125. package/{docDeleteCommands-DMQ2MU6I.js → docDeleteCommands-G4KAXJYQ.js} +39 -38
  126. package/{docReadCommands-FVHENBU6.js → docReadCommands-B2MM3JIT.js} +38 -37
  127. package/{docStore-OLC6MD7B.js → docStore-SITH63V3.js} +9 -9
  128. package/{docUpdateCommands-VA6V5C6L.js → docUpdateCommands-2QNF5CYN.js} +39 -38
  129. package/{fetchMessages-EIU7UFFK.js → fetchMessages-67MEFPZR.js} +2 -2
  130. package/{getPricing-YYXTEPBP.js → getPricing-OX7B4R6B.js} +3 -3
  131. package/{handleSendMessageAction-GRDIRXAK.js → handleSendMessageAction-7ZMJMWLC.js} +72 -80
  132. package/index.js +74 -877
  133. package/{localDialogRead-BTFJ4V2I.js → localDialogRead-EBRS242U.js} +2 -2
  134. package/{localRuntimeAuthority-6IR6BBXE.js → localRuntimeAuthority-5W6IJRAD.js} +6 -6
  135. package/{localRuntimeDb-SYQGUF4U.js → localRuntimeDb-3LRMNLCM.js} +1 -1
  136. package/{machineCommands-IJJ66MYU.js → machineCommands-YCTD5KOL.js} +75 -71
  137. package/{machineWsRunDispatch-PP2ZBS6D.js → machineWsRunDispatch-JFMD4ZAW.js} +73 -69
  138. package/{memberThunks-WQGQWYYT.js → memberThunks-SKFZ37VS.js} +9 -9
  139. package/{models-UN7YGMPM.js → models-T3SG6MJ5.js} +2 -2
  140. package/oauthTokenStore-ITEB663N.js +23 -0
  141. package/{offlineMarxistsAgentCommand-JEWCIAWM.js → offlineMarxistsAgentCommand-HGXZV4XJ.js} +1 -1
  142. package/package.json +1 -1
  143. package/pdf-U6KSUEZZ.js +26435 -0
  144. package/processSpawn-SOAV3FEV.js +11 -0
  145. package/profileConfig-ZGOFORWV.js +43 -0
  146. package/{providerPresetApply-NO73BG45.js → providerPresetApply-2QTBYN36.js} +7 -7
  147. package/{providerRegistry-OVY4VKNN.js → providerRegistry-SVXE4G4T.js} +7 -7
  148. package/{read-S4WC2OUK.js → read-IEJLLUXY.js} +5 -5
  149. package/{readDocTool-PQNM63KV.js → readDocTool-4SPYCP2Y.js} +5 -3
  150. package/{readlineWorkspace-ASJECDJD.js → readlineWorkspace-M3PLTBLD.js} +2396 -2018
  151. package/{removeDialogAgentAction-YJZ6XJV6.js → removeDialogAgentAction-LILXTOQY.js} +14 -14
  152. package/{runAgentClientLoop-KIOQSDRC.js → runAgentClientLoop-QMCXBOBH.js} +55 -55
  153. package/{runtimeDoctorCommands-X6WDBEQX.js → runtimeDoctorCommands-3USD722U.js} +3 -3
  154. package/runtimeModeArgs-2Y7BALTO.js +31 -0
  155. package/{setDialogExtraReferencesAction-E6A3WL4E.js → setDialogExtraReferencesAction-LVNHLNT5.js} +10 -10
  156. package/{setPrimaryDialogAgentAction-WBLIVICQ.js → setPrimaryDialogAgentAction-DCKO5NTW.js} +14 -14
  157. package/{settingSlice-JR6S7TRD.js → settingSlice-CNE75ISY.js} +10 -10
  158. package/{spaceCommands-WDUNCAK5.js → spaceCommands-3U6OHM6O.js} +39 -38
  159. package/{streamAgentChatTurn-EGQDPMAO.js → streamAgentChatTurn-JPMJQSEE.js} +144 -84
  160. package/{switchDialogAgentAction-DTR36ZY2.js → switchDialogAgentAction-JSYUQ5CG.js} +11 -11
  161. package/{tableCommands-O6NWHFKV.js → tableCommands-G7RV3RU3.js} +4 -4
  162. package/{toolApiClient-7PSIFQPJ.js → toolApiClient-INIQCPGY.js} +3 -3
  163. package/{tools-AOVE5LKM.js → tools-XQ5GIH6P.js} +49 -49
  164. package/{tuiSummaryLlmCaller-XRQCSNYQ.js → tuiSummaryLlmCaller-L63PDJUD.js} +16 -15
  165. package/{updateCommands-2M74UL7P.js → updateCommands-ECWKIWLQ.js} +3 -3
  166. package/{updateDialogTitleAction-T66TXHIR.js → updateDialogTitleAction-EGAZMLUB.js} +32 -32
  167. package/agentRecordCommands-FST3KAKG.js +0 -126
  168. package/chunk-4QKBQHPQ.js +0 -79
  169. package/chunk-Q5FJJ6XI.js +0 -103
  170. package/chunk-S7Z2HMCN.js +0 -25
  171. package/{chunk-VMFTFOWF.js → chunk-3AH7LNUB.js} +7 -7
  172. package/{chunk-X7HHHIOZ.js → chunk-Y6ROFCZO.js} +0 -0
  173. 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,
@@ -9,7 +9,7 @@ import {
9
9
  resolveRawAgentInput,
10
10
  resolveServerUrl,
11
11
  writeUsage
12
- } from "./chunk-QFMFJZLO.js";
12
+ } from "./chunk-V7E4PXQD.js";
13
13
  import {
14
14
  agentRunCardLabels,
15
15
  createCliLocalRuntimeAdapter,
@@ -26,50 +26,62 @@ import {
26
26
  resolveFileWriteGateEnabled,
27
27
  resolveLocalUserId,
28
28
  t,
29
- toolLabel
30
- } from "./chunk-7IBK6MYW.js";
31
- import {
32
- createRunActivityTracker,
33
- popSingleQueueMessage,
34
- readRunRecord,
35
- resolveRunQueuePath,
36
- settleRunTerminalAuthoritatively,
37
- spawnLocalBackgroundRun
38
- } from "./chunk-CPH3W5A7.js";
29
+ toolLabel,
30
+ toolLabelVariants
31
+ } from "./chunk-7EMJBGCA.js";
39
32
  import {
33
+ clearCredentialAvailability,
40
34
  readCredentialEntry,
41
- recordCredentialProbe,
42
- resolveCredentialKeyWithFallback
43
- } from "./chunk-DWUCB2A3.js";
35
+ recordCredentialProbe
36
+ } from "./chunk-62IL3KQV.js";
44
37
  import {
45
38
  getReadableCliDb
46
- } from "./chunk-LS2ZANRJ.js";
39
+ } from "./chunk-CTUQJVQM.js";
40
+ import {
41
+ resolveMachineId
42
+ } from "./chunk-ESHYE7WU.js";
47
43
  import {
48
44
  readDbRecord,
49
45
  resolveAgentRecordFromHybridStore
50
- } from "./chunk-E2NP7ZQU.js";
46
+ } from "./chunk-RZ6CQZB2.js";
51
47
  import {
52
48
  isLocalCliAgentKey
53
- } from "./chunk-SAFZABH7.js";
49
+ } from "./chunk-SV5IJK6K.js";
50
+ import {
51
+ extractGoogleValidationLink
52
+ } from "./chunk-BMQ2MJUK.js";
53
+ import {
54
+ createRunActivityTracker,
55
+ popSingleQueueMessage,
56
+ readRunRecord,
57
+ resolveRunQueuePath,
58
+ settleRunTerminalAuthoritatively,
59
+ spawnLocalBackgroundRun
60
+ } from "./chunk-I3TQJXQ7.js";
61
+ import {
62
+ isCliAuthorityBrokerProtocolError,
63
+ isCliAuthorityBrokerTimeoutError,
64
+ isCliAuthorityBrokerUnavailableError
65
+ } from "./chunk-EXAJ6DCR.js";
66
+ import {
67
+ getDefaultCliLocalRuntimeDb
68
+ } from "./chunk-ZOVKKMF6.js";
54
69
  import {
55
70
  CliProviderQuotaError
56
71
  } from "./chunk-MP64VFGD.js";
57
- import {
58
- resolveMachineId
59
- } from "./chunk-ESHYE7WU.js";
60
72
  import {
61
73
  applyModelLayerOverride,
62
74
  buildModelLayerOverride
63
75
  } from "./chunk-LTRXGFMS.js";
64
76
  import {
65
77
  formatAgentListCard
66
- } from "./chunk-UBNV6CS6.js";
67
- import {
68
- isTransientFetchError
69
- } from "./chunk-5UTFL4QJ.js";
78
+ } from "./chunk-6PELJ3DS.js";
70
79
  import {
71
80
  isGatewayHttpStatus
72
81
  } from "./chunk-NF64D32W.js";
82
+ import {
83
+ isTransientFetchError
84
+ } from "./chunk-5UTFL4QJ.js";
73
85
  import {
74
86
  formatFinishedRunCard,
75
87
  formatListRunsCard,
@@ -78,43 +90,35 @@ import {
78
90
  formatStatusRunCard,
79
91
  formatStopRunCard,
80
92
  isAgentRunTerminalStatus
81
- } from "./chunk-NTW5GWDM.js";
93
+ } from "./chunk-3VNWWVKB.js";
82
94
  import {
83
95
  buildMemorySubjectsForAgent,
84
96
  chooseMemoryOwners,
85
97
  loadMemoryCandidatesFromDb,
86
98
  resolveAgentMemoryPolicy
87
- } from "./chunk-ZKMYGRO7.js";
99
+ } from "./chunk-YMPTI7RZ.js";
88
100
  import {
89
101
  API_REPORTED_COST_MULTIPLIER,
90
102
  parseUiAskChoiceContent
91
- } from "./chunk-SUERPXJZ.js";
103
+ } from "./chunk-PAYUVQ6P.js";
92
104
  import {
93
105
  isOAuthApiKeyRef
94
106
  } from "./chunk-YYLHWIW6.js";
95
- import {
96
- isCliAuthorityBrokerProtocolError,
97
- isCliAuthorityBrokerTimeoutError,
98
- isCliAuthorityBrokerUnavailableError
99
- } from "./chunk-TRV2MIDW.js";
100
- import {
101
- getDefaultCliLocalRuntimeDb
102
- } from "./chunk-2F7RJC6L.js";
103
107
  import {
104
108
  buildSkillDiscoveryContextLayer
105
109
  } from "./chunk-E4MARS3Q.js";
106
110
  import {
107
111
  parseExternalSkillMarkdown,
108
112
  parseSkillDocProtocol
109
- } from "./chunk-Q554LLSI.js";
113
+ } from "./chunk-AUDNYVRC.js";
110
114
  import {
111
115
  LOCAL_AGENT_CONFIG_MISSING_CODE,
112
116
  LOCAL_TURN_ABORTED_CODE,
113
117
  readActionGate
114
- } from "./chunk-R2YY6MWV.js";
118
+ } from "./chunk-232453C2.js";
115
119
  import {
116
120
  resolveAgentRuntimeConfigFromRecord
117
- } from "./chunk-G5X57NDE.js";
121
+ } from "./chunk-VBSVA6CB.js";
118
122
  import {
119
123
  createThinkParserState,
120
124
  flushThinkParser,
@@ -125,31 +129,32 @@ import {
125
129
  isQuotaExhaustedError,
126
130
  isQuotaLimited403Body,
127
131
  mergeAvailabilityDeadline,
128
- resolveCooldownGate
129
- } from "./chunk-CJCJF5XB.js";
132
+ resolveCooldownGate,
133
+ resolveCredentialKeyWithFallback
134
+ } from "./chunk-H6A6X4EK.js";
130
135
  import {
131
136
  isAntigravityOAuthAgent
132
- } from "./chunk-NKIH4Q7W.js";
137
+ } from "./chunk-ISHYYQJC.js";
133
138
  import {
134
139
  resolveClientVersion
135
- } from "./chunk-MBEEYLGL.js";
140
+ } from "./chunk-OOSVFT6S.js";
136
141
  import {
137
142
  DEFAULT_CONTEXT_WINDOW,
138
143
  getModelContextWindow,
139
144
  normalizeUsage
140
- } from "./chunk-GRDSMV4V.js";
145
+ } from "./chunk-LS2MI3B4.js";
141
146
  import {
142
147
  clipCompactText
143
- } from "./chunk-BF2K6MRF.js";
144
- import {
145
- findModelConfig
146
- } from "./chunk-4CAPEGHN.js";
148
+ } from "./chunk-F64B2W3R.js";
147
149
  import {
148
150
  compactWhitespace
149
151
  } from "./chunk-DWLEOOGR.js";
150
152
  import {
151
153
  toErrorMessage
152
154
  } from "./chunk-HNMXYYJR.js";
155
+ import {
156
+ findModelConfig
157
+ } from "./chunk-ZI2MEZMT.js";
153
158
  import {
154
159
  buildAgentsMdLayer,
155
160
  buildMemoryOverlayLayer,
@@ -158,38 +163,42 @@ import {
158
163
  renderTurnContextBlocksWithScope
159
164
  } from "./chunk-DVINR3PL.js";
160
165
  import {
161
- readPipeText,
162
- spawnProcess
163
- } from "./chunk-X7HHHIOZ.js";
166
+ getLogger,
167
+ normalizeError
168
+ } from "./chunk-UNYJU5L6.js";
164
169
  import {
165
170
  resolveAuthToken
166
171
  } from "./chunk-A7GB5UGH.js";
172
+ import {
173
+ readPipeText,
174
+ spawnProcess
175
+ } from "./chunk-Y6ROFCZO.js";
167
176
  import {
168
177
  CLIENT_VERSION_TOO_OLD_CODE,
169
178
  NOLO_CLIENT_VERSION_HEADER,
170
179
  buildClientVersionUpgradeMessage
171
- } from "./chunk-JTYPAMGP.js";
180
+ } from "./chunk-Q67DOFOO.js";
172
181
  import {
173
182
  parsePositiveFiniteNumberOrFallback
174
183
  } from "./chunk-Y5GCAMGP.js";
175
184
  import {
176
185
  createMemoryKey,
177
186
  ulid
178
- } from "./chunk-VMFTFOWF.js";
187
+ } from "./chunk-3AH7LNUB.js";
179
188
  import {
180
189
  asTrimmedLowercaseString
181
190
  } from "./chunk-QSJ3HFEF.js";
191
+ import {
192
+ isLevelNotFoundError
193
+ } from "./chunk-OW765XBU.js";
182
194
  import {
183
195
  BUILTIN_NOLO_AGENT_KEY,
184
196
  BUILTIN_NOLO_AGENT_NAME,
185
197
  builtinAgentCatalogEntryById
186
- } from "./chunk-XGJAR4T5.js";
198
+ } from "./chunk-BNGW5ASC.js";
187
199
  import {
188
200
  parsePublicAgentId
189
- } from "./chunk-GII32WZW.js";
190
- import {
191
- isLevelNotFoundError
192
- } from "./chunk-OW765XBU.js";
201
+ } from "./chunk-M2EJHDJP.js";
193
202
  import {
194
203
  asTrimmedString
195
204
  } from "./chunk-3EUW3WEO.js";
@@ -385,6 +394,24 @@ function styleCliText(text, style, enabled = resolveCliColorEnabled()) {
385
394
  function dimCliText(text, enabled = resolveCliColorEnabled()) {
386
395
  return styleCliText(text, "dim", enabled);
387
396
  }
397
+ var OSC8_OPEN = "\x1B]8;;";
398
+ var OSC8_CLOSE = "\x1B\\";
399
+ function sanitizeHyperlinkLabel(label) {
400
+ return label.replace(/[\u0000-\u001f\u007f]/g, "");
401
+ }
402
+ function resolveCliHyperlinkEnabled(env = process.env, isTTY = Boolean(process.stdout.isTTY)) {
403
+ const setting = asTrimmedLowercaseString(env.NOLO_CLI_HYPERLINKS);
404
+ if (setting === "0" || setting === "false" || setting === "off") return false;
405
+ if (setting === "1" || setting === "true" || setting === "on") return true;
406
+ return isTTY;
407
+ }
408
+ function formatCliHyperlink(url, label, enabled = resolveCliHyperlinkEnabled()) {
409
+ if (!url) return label;
410
+ const safeLabel = sanitizeHyperlinkLabel(label);
411
+ if (!enabled) return `${safeLabel} (${url})`;
412
+ if (!safeLabel) return url;
413
+ return `${OSC8_OPEN}${url}${OSC8_CLOSE}${safeLabel}${OSC8_OPEN}${OSC8_CLOSE}`;
414
+ }
388
415
 
389
416
  // node_modules/ansi-regex/index.js
390
417
  function ansiRegex({ onlyFirst = false } = {}) {
@@ -619,8 +646,12 @@ function stringWidth(input, options = {}) {
619
646
 
620
647
  // packages/cli/tui/tuiAnsi.ts
621
648
  var ANSI_ESCAPE_REGEX = /\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]/g;
649
+ var OSC8_HYPERLINK_REGEX = /\x1b\]8;;[^\x1b]*\x1b\\/g;
622
650
  var ALL_ANSI_ESCAPE_REGEX = ansiRegex();
623
651
  var FIRST_ANSI_ESCAPE_REGEX = ansiRegex({ onlyFirst: true });
652
+ function stripOsc8Hyperlinks(text) {
653
+ return text.replace(OSC8_HYPERLINK_REGEX, "");
654
+ }
624
655
  function stripAnsi2(text) {
625
656
  return text.replace(ANSI_ESCAPE_REGEX, "").replace(ALL_ANSI_ESCAPE_REGEX, "");
626
657
  }
@@ -782,6 +813,7 @@ function visibleWidth(str) {
782
813
  }
783
814
  function truncateAnsi(text, maxWidth) {
784
815
  if (maxWidth <= 0) return "";
816
+ text = stripOsc8Hyperlinks(text);
785
817
  if (visibleWidth(text) <= maxWidth) return text;
786
818
  let width = 0;
787
819
  let out = "";
@@ -822,7 +854,7 @@ function countPhysicalLines(text, columns) {
822
854
  const lines = text.split("\n");
823
855
  let total = 0;
824
856
  for (const line of lines) {
825
- const width = displayWidth(line);
857
+ const width = visibleWidth(stripOsc8Hyperlinks(line));
826
858
  total += Math.max(1, Math.ceil(width / columns));
827
859
  }
828
860
  return Math.max(total, 1);
@@ -8179,7 +8211,12 @@ function emitPlainGap(text, keywords, info, accent, warning, reset) {
8179
8211
  var UNORDERED_LIST_RE = /^(\s*)([-*+])\s+(.+)$/;
8180
8212
  var ORDERED_LIST_RE = /^(\s*)(\d+)\.\s+(.+)$/;
8181
8213
  var TASK_LIST_RE = /^(\s*)([-*+])\s+\[([ xX])\]\s+(.+)$/;
8214
+ var THEMATIC_BREAK_PATTERN = "(?:(-[ \\t]*){3,}|(\\*[ \\t]*){3,}|(_[ \\t]*){3,})";
8215
+ var THEMATIC_BREAK_RE = new RegExp(`^[ ]{0,3}${THEMATIC_BREAK_PATTERN}$`);
8182
8216
  function normalizeListLine(line) {
8217
+ if (THEMATIC_BREAK_RE.test(line)) {
8218
+ return line;
8219
+ }
8183
8220
  const task = line.match(TASK_LIST_RE);
8184
8221
  if (task) {
8185
8222
  const checked = task[3] === "x" || task[3] === "X";
@@ -8195,12 +8232,99 @@ function normalizeListLine(line) {
8195
8232
  }
8196
8233
  return line;
8197
8234
  }
8235
+ var TOOL_TREE_HEADER_RE = /^•\s+(.+?)\s+\((\d+)\)$/;
8236
+ var TOOL_TREE_LEAF_RE = /^([├└]──\s+)(.*?)\s{2}(✓|✗|!)(?:\s+(.*))?$/;
8237
+ var TOOL_SINGLE_RE = /^▸\s+(.+?)(?:\s+·\s+(.*?))?(?:\s{2}(✓|✗|!)(?:\s+(.*))?)$/;
8238
+ function plainToolLine(line) {
8239
+ return stripAnsi2(line);
8240
+ }
8241
+ var TOOL_TREE_GROUP_LABELS = new Set(
8242
+ ["execShell", "readFile", "fetchWebpage", "exa_search"].flatMap(toolLabelVariants)
8243
+ );
8244
+ function isKnownToolGroupLabel(label) {
8245
+ return TOOL_TREE_GROUP_LABELS.has(label);
8246
+ }
8247
+ function toolTreeHeaderMatch(line) {
8248
+ const match = plainToolLine(line).match(TOOL_TREE_HEADER_RE);
8249
+ return match && isKnownToolGroupLabel(match[1]) ? match : null;
8250
+ }
8251
+ function isToolTreeHeaderLine(line) {
8252
+ return toolTreeHeaderMatch(line) !== null;
8253
+ }
8254
+ function isToolTreeLeafLine(line) {
8255
+ return TOOL_TREE_LEAF_RE.test(plainToolLine(line));
8256
+ }
8257
+ function isToolSingleLine(line) {
8258
+ return TOOL_SINGLE_RE.test(plainToolLine(line));
8259
+ }
8260
+ function isToolGroupBoundary(cur, next) {
8261
+ return isToolTreeLeafLine(cur) && isToolTreeHeaderLine(next);
8262
+ }
8263
+ function statusColorSeq(marker, brightness) {
8264
+ if (marker === "\u2713") return colorSeq("success", brightness);
8265
+ if (marker === "\u2717") return colorSeq("danger", brightness);
8266
+ return colorSeq("warning", brightness);
8267
+ }
8268
+ function styleTuiToolLine(line, brightness) {
8269
+ const plain = plainToolLine(line);
8270
+ const chrome = colorSeq("chrome", brightness);
8271
+ const muted = colorSeq("muted", brightness);
8272
+ const header = toolTreeHeaderMatch(plain);
8273
+ if (header) {
8274
+ return `${chrome}\u2022${STYLE.reset} ${STYLE.bold}${muted}${header[1]}${STYLE.reset} ${chrome}${STYLE.dim}(${header[2]})${STYLE.reset}`;
8275
+ }
8276
+ const leaf = plain.match(TOOL_TREE_LEAF_RE);
8277
+ if (leaf) {
8278
+ const [, connector, detail, marker, statusDetail] = leaf;
8279
+ let rendered = `${chrome}${connector}${STYLE.reset}${chrome}${detail}${STYLE.reset}`;
8280
+ rendered += ` ${statusColorSeq(marker, brightness)}${marker}${STYLE.reset}`;
8281
+ if (statusDetail) {
8282
+ const metaSeq = marker === "\u2713" ? chrome : statusColorSeq(marker, brightness);
8283
+ rendered += ` ${metaSeq}${STYLE.dim}${statusDetail}${STYLE.reset}`;
8284
+ }
8285
+ return rendered;
8286
+ }
8287
+ const single = plain.match(TOOL_SINGLE_RE);
8288
+ if (single) {
8289
+ const [, label, detail, marker, statusDetail] = single;
8290
+ let rendered = `${chrome}\u25B8${STYLE.reset} ${STYLE.bold}${muted}${label}${STYLE.reset}`;
8291
+ if (detail) rendered += ` ${chrome}\xB7 ${detail}${STYLE.reset}`;
8292
+ rendered += ` ${statusColorSeq(marker, brightness)}${marker}${STYLE.reset}`;
8293
+ if (statusDetail) {
8294
+ const metaSeq = marker === "\u2713" ? chrome : statusColorSeq(marker, brightness);
8295
+ rendered += ` ${metaSeq}${STYLE.dim}${statusDetail}${STYLE.reset}`;
8296
+ }
8297
+ return rendered;
8298
+ }
8299
+ return null;
8300
+ }
8198
8301
  function isPolishListLikeLine(line) {
8199
- return LIST_LIKE_RE_FOR_GUARD.test(normalizeListLine(line));
8302
+ return LIST_LIKE_RE_FOR_GUARD.test(normalizeListLine(plainToolLine(line)));
8303
+ }
8304
+ var LIST_LIKE_RE_FOR_GUARD = /^\s*(?:•|◦|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s|^\s*▸\s/;
8305
+ function isPolishFenceInteriorLine(line) {
8306
+ return /^\x00F\d+\x00$/.test(line);
8307
+ }
8308
+ function polishHeadingLevel(line) {
8309
+ const match = stripAnsi2(line).match(/^(#{1,6})\s/);
8310
+ return match ? match[1].length : null;
8311
+ }
8312
+ function isPolishHeadingLine(line) {
8313
+ return polishHeadingLevel(line) !== null;
8314
+ }
8315
+ function isPolishIntroLine(line) {
8316
+ const plain = stripAnsi2(line).trimEnd();
8317
+ return plain.endsWith("\uFF1A") || plain.endsWith(":");
8200
8318
  }
8201
- var LIST_LIKE_RE_FOR_GUARD = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
8202
8319
  function polishBreathInsertsBlankBetween(cur, next) {
8203
8320
  if (cur === "" || next === "") return false;
8321
+ if (isPolishFenceInteriorLine(cur) || isPolishFenceInteriorLine(next)) {
8322
+ return false;
8323
+ }
8324
+ if (isPolishIntroLine(cur) && isPolishListLikeLine(next)) return false;
8325
+ if (isPolishHeadingLine(cur) || isPolishHeadingLine(next)) return false;
8326
+ if (isCodeFenceLine(cur) !== isCodeFenceLine(next)) return true;
8327
+ if (isToolGroupBoundary(cur, next)) return true;
8204
8328
  return isPolishListLikeLine(cur) !== isPolishListLikeLine(next);
8205
8329
  }
8206
8330
  function convertMarkdownTablesForTerminal(text) {
@@ -8269,17 +8393,15 @@ function polishAssistantStructure(text, options = {}) {
8269
8393
  }
8270
8394
  return line;
8271
8395
  });
8272
- 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");
8273
- const LIST_LIKE = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
8396
+ 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");
8274
8397
  const headingLines = afterHeading.split("\n");
8275
8398
  const breathed = [];
8276
8399
  for (let i = 0; i < headingLines.length; i++) {
8277
8400
  breathed.push(headingLines[i]);
8278
8401
  const cur = headingLines[i];
8279
8402
  const next = headingLines[i + 1];
8280
- if (cur === "" || next === void 0 || next === "") continue;
8281
- if (LIST_LIKE.test(cur) === LIST_LIKE.test(next)) continue;
8282
- breathed.push("");
8403
+ if (next === void 0) continue;
8404
+ if (polishBreathInsertsBlankBetween(cur, next)) breathed.push("");
8283
8405
  }
8284
8406
  const polishedMasked = breathed.join("\n");
8285
8407
  const polished = polishedMasked.replace(
@@ -8289,17 +8411,23 @@ function polishAssistantStructure(text, options = {}) {
8289
8411
  return options.trimEdges === false ? polished : polished.trim();
8290
8412
  }
8291
8413
  function styleRichMarkdownLine(line, brightness) {
8292
- const heading = line.match(/^(#{1,3})\s+(.+)$/);
8414
+ const toolLine = styleTuiToolLine(line, brightness);
8415
+ if (toolLine !== null) return toolLine;
8416
+ const heading = line.match(/^(#{1,6})\s+(.+)$/);
8293
8417
  if (heading) {
8294
8418
  const level = heading[1].length;
8295
8419
  const title = heading[2];
8420
+ const styledTitle = styleInlineMarkdown(title, brightness);
8296
8421
  if (level === 1) {
8297
- return `${STYLE.bold}\x1B[4m${colorSeq("accent", brightness)}${title}${STYLE.reset}`;
8422
+ return `${STYLE.bold}${colorSeq("accent", brightness)}${styledTitle}${STYLE.reset}`;
8298
8423
  }
8299
8424
  if (level === 2) {
8300
- return `${STYLE.bold}${colorSeq("warning", brightness)}${title}${STYLE.reset}`;
8425
+ return `${STYLE.bold}${colorSeq("warning", brightness)}${styledTitle}${STYLE.reset}`;
8301
8426
  }
8302
- return `${STYLE.bold}${colorSeq("info", brightness)}${title}${STYLE.reset}`;
8427
+ if (level === 3) {
8428
+ return `${STYLE.bold}${colorSeq("info", brightness)}${styledTitle}${STYLE.reset}`;
8429
+ }
8430
+ return `${STYLE.bold}${colorSeq("muted", brightness)}${styledTitle}${STYLE.reset}`;
8303
8431
  }
8304
8432
  if (line.startsWith("\u8FDB\u5165 nolo-plan")) {
8305
8433
  return `${colorSeq("chrome", brightness)}${STYLE.dim}${line}${STYLE.reset}`;
@@ -8308,15 +8436,19 @@ function styleRichMarkdownLine(line, brightness) {
8308
8436
  if (blockquote) {
8309
8437
  const border = colorSeq("chrome", brightness);
8310
8438
  const content = blockquote[1];
8311
- return `${border}\u2502${STYLE.reset} ${STYLE.dim}${content}${STYLE.reset}`;
8439
+ const styled = styleInlineMarkdown(content, brightness);
8440
+ return `${border}\u2502${STYLE.reset} ${STYLE.dim}${styled}${STYLE.reset}`;
8312
8441
  }
8313
- if (/^---+$/.test(line.trim())) {
8314
- return `${colorSeq("chrome", brightness)}${"\u2500".repeat(Math.min(line.trim().length, 40))}${STYLE.reset}`;
8442
+ if (THEMATIC_BREAK_RE.test(line)) {
8443
+ return `${colorSeq("chrome", brightness)}${STYLE.dim}${"\u2500".repeat(36)}${STYLE.reset}`;
8315
8444
  }
8316
8445
  const bullet = line.match(/^(\s*)(•)\s(.+)$/);
8317
8446
  if (bullet) {
8447
+ const indent = bullet[1];
8318
8448
  const styled = styleInlineMarkdown(bullet[3], brightness);
8319
- return `${bullet[1]}${colorSeq("accent", brightness)}\u2022${STYLE.reset} ${styled}`;
8449
+ const marker = indent.length >= 2 ? "\u25E6" : "\u2022";
8450
+ const markerColor = indent.length >= 2 ? colorSeq("chrome", brightness) : colorSeq("accent", brightness);
8451
+ return `${indent}${markerColor}${marker}${STYLE.reset} ${styled}`;
8320
8452
  }
8321
8453
  const ordered = line.match(/^(\s*)(\d+\.)\s(.+)$/);
8322
8454
  if (ordered) {
@@ -8440,16 +8572,28 @@ function emitFormattedAssistantBlock(write, text, trailingNewline = false) {
8440
8572
  }
8441
8573
  function classifyStreamLine(line) {
8442
8574
  if (line === "") return "blank";
8443
- 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)) {
8575
+ const plain = plainToolLine(line);
8576
+ if (isToolTreeHeaderLine(plain)) return "tool-header";
8577
+ if (isToolTreeLeafLine(plain)) return "tool-leaf";
8578
+ if (isToolSingleLine(plain)) return "tool";
8579
+ 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)) {
8444
8580
  return "list";
8445
8581
  }
8582
+ if (isPolishListLikeLine(plain)) return "list";
8583
+ if (polishHeadingLevel(plain) !== null) return "heading";
8446
8584
  return "prose";
8447
8585
  }
8448
- function needsListProseBreath(prev, next) {
8586
+ function isStreamListLike(kind) {
8587
+ return kind === "list" || kind === "tool-header" || kind === "tool-leaf" || kind === "tool";
8588
+ }
8589
+ function needsListProseBreath(prev, next, prevLine = "") {
8449
8590
  if (prev === null || prev === "blank" || next === "blank") return false;
8450
- const prevList = prev === "list";
8451
- const nextList = next === "list";
8452
- return prevList !== nextList;
8591
+ if (next === "heading") return true;
8592
+ if (prev === "heading") return (polishHeadingLevel(prevLine) ?? 7) <= 2;
8593
+ if (prev === "fence" !== (next === "fence")) return true;
8594
+ if (isStreamListLike(next) && isPolishIntroLine(prevLine)) return false;
8595
+ if (prev === "tool-leaf" && next === "tool-header") return true;
8596
+ return isStreamListLike(prev) !== isStreamListLike(next);
8453
8597
  }
8454
8598
  function createRenderAwareStreamWriter(args) {
8455
8599
  const brightness = resolveTuiBrightness();
@@ -8459,9 +8603,16 @@ function createRenderAwareStreamWriter(args) {
8459
8603
  let inMermaid = false;
8460
8604
  let mermaidBody = [];
8461
8605
  let lastKind = null;
8606
+ let lastLine = "";
8607
+ let pendingBlankRow = false;
8462
8608
  const PARTIAL_FLUSH_THRESHOLD = 48;
8463
8609
  const emitBreathIfNeeded = (nextKind) => {
8464
- if (needsListProseBreath(lastKind, nextKind)) args.write("\n");
8610
+ if (pendingBlankRow) {
8611
+ args.write("\n");
8612
+ pendingBlankRow = false;
8613
+ lastKind = "blank";
8614
+ }
8615
+ if (needsListProseBreath(lastKind, nextKind, lastLine)) args.write("\n");
8465
8616
  };
8466
8617
  const flushPartialProse = () => {
8467
8618
  if (inFence || buffer.length < PARTIAL_FLUSH_THRESHOLD) return;
@@ -8479,6 +8630,7 @@ function createRenderAwareStreamWriter(args) {
8479
8630
  emitBreathIfNeeded("prose");
8480
8631
  emitFormattedAssistantBlock(args.write, prefix, false);
8481
8632
  lastKind = "prose";
8633
+ lastLine = prefix;
8482
8634
  buffer = prefix.length === buffer.length ? "" : buffer.slice(prefix.length);
8483
8635
  };
8484
8636
  const flushCompleteBlocks = () => {
@@ -8494,10 +8646,11 @@ function createRenderAwareStreamWriter(args) {
8494
8646
  inMermaid = false;
8495
8647
  inFence = false;
8496
8648
  fenceLang = "unknown";
8497
- emitBreathIfNeeded("other");
8649
+ emitBreathIfNeeded("fence");
8498
8650
  args.write(`${STYLE.dim}${firstLine}${STYLE.reset}
8499
8651
  `);
8500
- lastKind = "other";
8652
+ lastKind = "fence";
8653
+ lastLine = firstLine;
8501
8654
  buffer = lines.slice(1).join("\n");
8502
8655
  continue;
8503
8656
  }
@@ -8513,10 +8666,11 @@ function createRenderAwareStreamWriter(args) {
8513
8666
  }
8514
8667
  inFence = true;
8515
8668
  }
8516
- emitBreathIfNeeded("other");
8669
+ emitBreathIfNeeded("fence");
8517
8670
  args.write(`${STYLE.dim}${firstLine}${STYLE.reset}
8518
8671
  `);
8519
- lastKind = "other";
8672
+ lastKind = "fence";
8673
+ lastLine = firstLine;
8520
8674
  buffer = lines.slice(1).join("\n");
8521
8675
  continue;
8522
8676
  }
@@ -8528,7 +8682,8 @@ function createRenderAwareStreamWriter(args) {
8528
8682
  if (inFence) {
8529
8683
  args.write(`${highlightCodeLine(firstLine, fenceLang, brightness)}
8530
8684
  `);
8531
- lastKind = "other";
8685
+ lastKind = "fence";
8686
+ lastLine = firstLine;
8532
8687
  buffer = lines.slice(1).join("\n");
8533
8688
  continue;
8534
8689
  }
@@ -8541,6 +8696,7 @@ function createRenderAwareStreamWriter(args) {
8541
8696
  const inner = trimmedFirst.slice(2, trimmedFirst.length - 2);
8542
8697
  args.write(renderMathBlock(inner) + "\n");
8543
8698
  lastKind = "other";
8699
+ lastLine = trimmedFirst;
8544
8700
  buffer = lines.slice(1).join("\n");
8545
8701
  continue;
8546
8702
  }
@@ -8567,6 +8723,7 @@ function createRenderAwareStreamWriter(args) {
8567
8723
  if (lastInner) innerParts.push(lastInner);
8568
8724
  args.write(renderMathBlock(innerParts.join("\n")) + "\n");
8569
8725
  lastKind = "other";
8726
+ lastLine = trimmedFirst;
8570
8727
  buffer = lines.slice(closeIndex + 1).join("\n");
8571
8728
  continue;
8572
8729
  }
@@ -8587,14 +8744,23 @@ function createRenderAwareStreamWriter(args) {
8587
8744
  true
8588
8745
  );
8589
8746
  lastKind = "list";
8747
+ lastLine = lines[end - 1] ?? firstLine;
8590
8748
  buffer = lines.slice(end).join("\n");
8591
8749
  continue;
8592
8750
  }
8593
8751
  }
8594
8752
  const kind = classifyStreamLine(firstLine);
8753
+ if (kind === "blank") {
8754
+ if (lastKind !== null && lastKind !== "blank") pendingBlankRow = true;
8755
+ lastKind = "blank";
8756
+ lastLine = "";
8757
+ buffer = lines.slice(1).join("\n");
8758
+ continue;
8759
+ }
8595
8760
  emitBreathIfNeeded(kind);
8596
8761
  emitFormattedAssistantBlock(args.write, firstLine, true);
8597
8762
  lastKind = kind;
8763
+ lastLine = firstLine;
8598
8764
  buffer = lines.slice(1).join("\n");
8599
8765
  }
8600
8766
  };
@@ -9807,6 +9973,7 @@ ${this.text}
9807
9973
  // packages/cli/client/agentRunOutput.ts
9808
9974
  var IDENTITY_LABEL_SEPARATOR = " > ";
9809
9975
  var THINKING_PREVIEW_BUFFER_LIMIT = 512;
9976
+ var TUI_PROGRESS_BUFFER_LIMIT = 1200;
9810
9977
  function appendThinkingPreview(current, chunk, limit = THINKING_PREVIEW_BUFFER_LIMIT) {
9811
9978
  if (limit <= 0) return "";
9812
9979
  const combined = current + chunk;
@@ -9820,6 +9987,14 @@ function formatCompactionSummaryLine(event) {
9820
9987
  return `${STYLE.dim}\u81EA\u52A8\u4E0A\u4E0B\u6587\u538B\u7F29\u5931\u8D25${reason}\uFF0C\u672C\u8F6E\u4EE5\u672A\u538B\u7F29\u4E0A\u4E0B\u6587\u7EE7\u7EED\u3002\u82E5\u53CD\u590D\u51FA\u73B0\u53EF\u624B\u52A8 /compact\u3002${STYLE.reset}
9821
9988
  `;
9822
9989
  }
9990
+ if (event.skipped) {
9991
+ if (event.skipReason === "adapter-missing-summary-methods" || event.skipReason === "load-summary-failed") {
9992
+ return `${STYLE.dim}\u81EA\u52A8\u4E0A\u4E0B\u6587\u538B\u7F29\u4E0D\u53EF\u7528\uFF08${event.skipReason}\uFF09\uFF0C\u672C\u8F6E\u4E0D\u538B\u7F29\u3002${STYLE.reset}
9993
+ `;
9994
+ }
9995
+ return "";
9996
+ }
9997
+ if (!event.summaryGenerated) return "";
9823
9998
  let detail = "\u751F\u6210\u5386\u53F2\u6458\u8981";
9824
9999
  const saved = typeof event.savedTokens === "number" ? event.savedTokens : void 0;
9825
10000
  let line = `\u5DF2\u538B\u7F29\u4E0A\u4E0B\u6587\uFF1A${detail}`;
@@ -9860,6 +10035,14 @@ function formatToolJsonEvent(event) {
9860
10035
  })}
9861
10036
  `;
9862
10037
  }
10038
+ function shouldPromoteTuiNarration(text) {
10039
+ if (text.length >= TUI_PROGRESS_BUFFER_LIMIT) return true;
10040
+ return /(^|\n)\s*(?:#{1,3}\s|```|[-*+]\s|\d+[.)]\s)/.test(text);
10041
+ }
10042
+ function narrationActivityLabel(text) {
10043
+ const oneLine = stripAnsi2(text).replace(/[`*_#>]/g, "").replace(/\s+/g, " ").trim();
10044
+ return truncateThinkingHint(oneLine, 60);
10045
+ }
9863
10046
  function createCliTurnOutput(params) {
9864
10047
  const { options } = params;
9865
10048
  const workingLabel = params.workingLabel ?? `${options.agentName} -> working`;
@@ -9868,14 +10051,36 @@ function createCliTurnOutput(params) {
9868
10051
  tuiTrees: options.output.tuiTrees === true
9869
10052
  });
9870
10053
  const eventMode = resolveAgentEventMode(options);
9871
- const showThinking = options.showThinking !== false;
10054
+ const assistantLabelManaged = options.output.assistantLabelManaged === true;
10055
+ const showThinking = !assistantLabelManaged && options.showThinking !== false;
10056
+ const hidesRoutineTuiToolDetail = (event) => {
10057
+ if (!assistantLabelManaged || event.toolName !== "editFile") return false;
10058
+ if (event.type === "tool-error") return false;
10059
+ if (readActionGate(event.metadata?.actionGate)) return false;
10060
+ if (event.metadata?.timedOut || event.metadata?.failed || event.metadata?.error) return false;
10061
+ if (typeof event.metadata?.exitCode === "number" && event.metadata.exitCode !== 0) return false;
10062
+ return true;
10063
+ };
9872
10064
  let streamedAssistantText = false;
9873
10065
  let everStreamedAnyText = false;
9874
10066
  let printedAssistantLabel = false;
9875
10067
  let thinkState = createThinkParserState();
9876
10068
  let thinkingFirstAt = null;
9877
10069
  let thinkingPreview = "";
10070
+ let tuiThinkingReported = false;
10071
+ const clearTuiThinkingLabel = () => {
10072
+ if (!tuiThinkingReported) return;
10073
+ tuiThinkingReported = false;
10074
+ options.activityReporter?.(null);
10075
+ };
9878
10076
  const markThinkingDelta = (chunk) => {
10077
+ if (assistantLabelManaged) {
10078
+ if (!tuiThinkingReported && !streamedAssistantText) {
10079
+ tuiThinkingReported = true;
10080
+ options.activityReporter?.(t("thinkingActive"));
10081
+ }
10082
+ return;
10083
+ }
9879
10084
  if (!showThinking) return;
9880
10085
  if (streamedAssistantText) return;
9881
10086
  if (thinkingFirstAt === null) {
@@ -9893,6 +10098,7 @@ function createCliTurnOutput(params) {
9893
10098
  options.activityReporter?.(label);
9894
10099
  };
9895
10100
  const endThinkingPhase = () => {
10101
+ clearTuiThinkingLabel();
9896
10102
  if (thinkingFirstAt === null) return;
9897
10103
  const seconds = Math.max(0, Math.round((Date.now() - thinkingFirstAt) / 1e3));
9898
10104
  thinkingFirstAt = null;
@@ -9905,7 +10111,6 @@ function createCliTurnOutput(params) {
9905
10111
  }
9906
10112
  };
9907
10113
  let compactionEvent = null;
9908
- const assistantLabelManaged = options.output.assistantLabelManaged === true;
9909
10114
  const writeToolOutput = (chunk) => {
9910
10115
  if (!chunk) return;
9911
10116
  if (typeof options.output.writeToolBlock === "function") {
@@ -9917,9 +10122,25 @@ function createCliTurnOutput(params) {
9917
10122
  const renderWriter = createRenderAwareStreamWriter({
9918
10123
  write: (chunk) => options.output.write(chunk)
9919
10124
  });
10125
+ let pendingTuiNarration = "";
10126
+ let tuiNarrationPromoted = false;
10127
+ const flushPendingTuiNarration = () => {
10128
+ if (!pendingTuiNarration) return;
10129
+ formatToolEvent.reset?.();
10130
+ renderWriter.push(pendingTuiNarration);
10131
+ pendingTuiNarration = "";
10132
+ tuiNarrationPromoted = true;
10133
+ streamedAssistantText = true;
10134
+ options.activityReporter?.(null);
10135
+ };
10136
+ const dropPendingTuiProgress = () => {
10137
+ pendingTuiNarration = "";
10138
+ tuiNarrationPromoted = false;
10139
+ options.activityReporter?.(null);
10140
+ };
9920
10141
  const writeVisibleAssistantChunk = (chunk) => {
9921
10142
  if (!chunk) return;
9922
- formatToolEvent.reset?.();
10143
+ if (!assistantLabelManaged) formatToolEvent.reset?.();
9923
10144
  const parsed = processThinkChunk(chunk, thinkState);
9924
10145
  thinkState = parsed.state;
9925
10146
  if (!parsed.content && !parsed.reasoning) return;
@@ -9935,8 +10156,23 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
9935
10156
  }
9936
10157
  printedAssistantLabel = true;
9937
10158
  }
9938
- streamedAssistantText = true;
9939
10159
  everStreamedAnyText = true;
10160
+ if (assistantLabelManaged) {
10161
+ if (tuiNarrationPromoted) {
10162
+ renderWriter.push(parsed.content);
10163
+ streamedAssistantText = true;
10164
+ return;
10165
+ }
10166
+ pendingTuiNarration += parsed.content;
10167
+ if (shouldPromoteTuiNarration(pendingTuiNarration)) {
10168
+ flushPendingTuiNarration();
10169
+ } else {
10170
+ const label = narrationActivityLabel(pendingTuiNarration);
10171
+ if (label) options.activityReporter?.(label);
10172
+ }
10173
+ return;
10174
+ }
10175
+ streamedAssistantText = true;
9940
10176
  renderWriter.push(parsed.content);
9941
10177
  };
9942
10178
  const handleToolEvent = (event) => {
@@ -9952,13 +10188,19 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
9952
10188
  return;
9953
10189
  }
9954
10190
  if (event.type === "tool-call") {
10191
+ if (assistantLabelManaged && pendingTuiNarration) {
10192
+ dropPendingTuiProgress();
10193
+ }
9955
10194
  renderWriter.flush();
9956
- formatToolEvent(event);
10195
+ if (!hidesRoutineTuiToolDetail(event)) {
10196
+ formatToolEvent(event);
10197
+ }
9957
10198
  endThinkingPhase();
9958
10199
  if (streamedAssistantText) {
9959
10200
  options.output.write("\n");
9960
10201
  streamedAssistantText = false;
9961
10202
  }
10203
+ if (assistantLabelManaged) tuiNarrationPromoted = false;
9962
10204
  const activeLabel = formatConservativeActiveToolLabel(event);
9963
10205
  spinner.show(activeLabel);
9964
10206
  options.activityReporter?.(activeLabel);
@@ -9970,6 +10212,9 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
9970
10212
  }
9971
10213
  spinner.stop();
9972
10214
  options.activityReporter?.(null);
10215
+ if (hidesRoutineTuiToolDetail(event)) {
10216
+ return;
10217
+ }
9973
10218
  if (isLiveAgentRunObservation(event, parsedRunEvent)) {
9974
10219
  formatToolEvent.consume?.(event);
9975
10220
  return;
@@ -9982,6 +10227,26 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
9982
10227
  return {
9983
10228
  spinner,
9984
10229
  eventMode,
10230
+ /**
10231
+ * Terminal cleanup for abort/error paths that never reach `finish()`.
10232
+ *
10233
+ * A user abort discards the transient TUI progress buffer: the user stopped
10234
+ * on purpose and the dock already showed that text as activity. A genuine
10235
+ * failure must not swallow prose that never got the chance to be *proven*
10236
+ * durable (only a following tool call proves "progress"), so it promotes the
10237
+ * pending buffer and flushes what was already promoted — otherwise a short
10238
+ * final answer followed by a transport error disappears from the transcript.
10239
+ */
10240
+ cancel(cleanup) {
10241
+ if (assistantLabelManaged && cleanup?.preservePendingNarration) {
10242
+ flushPendingTuiNarration();
10243
+ if (streamedAssistantText) {
10244
+ renderWriter.flush();
10245
+ options.output.write("\n");
10246
+ }
10247
+ }
10248
+ dropPendingTuiProgress();
10249
+ },
9985
10250
  pushText(chunk) {
9986
10251
  writeVisibleAssistantChunk(chunk);
9987
10252
  },
@@ -9989,21 +10254,39 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
9989
10254
  markThinkingDelta(chunk);
9990
10255
  },
9991
10256
  handleToolEvent,
9992
- /** 记录一条 compaction 观测事件(TUI 在 turn 结束时渲染一行 dim 摘要)。 */
9993
10257
  recordCompaction(event) {
9994
- compactionEvent = event;
10258
+ const significance = (e) => e.failed ? 4 : e.summaryGenerated ? 3 : e.compressed ? 2 : 1;
10259
+ if (!compactionEvent || significance(event) >= significance(compactionEvent)) {
10260
+ compactionEvent = event;
10261
+ }
9995
10262
  },
9996
10263
  showWorking(label) {
9997
10264
  const activeLabel = label ?? workingLabel;
9998
10265
  spinner.show(activeLabel);
9999
10266
  options.activityReporter?.(activeLabel);
10000
10267
  },
10268
+ /**
10269
+ * Pre-delta turn phase label (ctx-overflow-feedback batch 3).
10270
+ *
10271
+ * localLoop 在首个 provider delta 之前依次发出 turn-phase 事件
10272
+ * (validating-context → compacting → waiting-provider);此前 CLI 只有
10273
+ * llm-start 才进入明确 working 状态,压缩期间 spinner 停在通用
10274
+ * working 文案上,用户无法区分「卡在检查上下文 / 压缩 / 等模型」。
10275
+ * 两个显示面(bare CLI 的 spinner 与 TUI 的 dock activityReporter)与
10276
+ * showWorking 走同一条投影,保证两端文案不漂移。
10277
+ */
10278
+ showPhase(phase) {
10279
+ const label = phase === "validating-context" ? t("contextChecking") : phase === "compacting" ? t("contextCompacting") : t("waitingForModel");
10280
+ spinner.show(label);
10281
+ options.activityReporter?.(label);
10282
+ },
10001
10283
  finish(fallbackContent) {
10002
10284
  const flushedThink = flushThinkParser(thinkState);
10003
10285
  thinkState = flushedThink.state;
10004
10286
  if (flushedThink.content) {
10005
10287
  writeVisibleAssistantChunk(flushedThink.content);
10006
10288
  }
10289
+ if (assistantLabelManaged) flushPendingTuiNarration();
10007
10290
  endThinkingPhase();
10008
10291
  spinner.stop();
10009
10292
  options.activityReporter?.(null);
@@ -10108,6 +10391,7 @@ async function readStreamingAgentRun(options, res, existingSpinner) {
10108
10391
  let content = "";
10109
10392
  let dialogId;
10110
10393
  let usage;
10394
+ let sawDone = false;
10111
10395
  const handlePayload = (payload) => {
10112
10396
  if (typeof payload?.dialogId === "string" && payload.dialogId.trim()) {
10113
10397
  dialogId = payload.dialogId;
@@ -10120,6 +10404,7 @@ async function readStreamingAgentRun(options, res, existingSpinner) {
10120
10404
  }
10121
10405
  if (payload?.type === "done") {
10122
10406
  usage = payload.usage;
10407
+ sawDone = true;
10123
10408
  return;
10124
10409
  }
10125
10410
  if (payload?.type === "dialog" || payload?.type === "status") {
@@ -10173,6 +10458,9 @@ async function readStreamingAgentRun(options, res, existingSpinner) {
10173
10458
  }
10174
10459
  } catch (error) {
10175
10460
  turnOutput.spinner.stop();
10461
+ turnOutput.cancel({
10462
+ preservePendingNarration: !options.abortSignal?.aborted
10463
+ });
10176
10464
  if (options.abortSignal?.aborted) {
10177
10465
  return {
10178
10466
  exitCode: 0,
@@ -10202,6 +10490,15 @@ ${describeClientVersionTooOldFailure(message, error)}`);
10202
10490
  `);
10203
10491
  return { exitCode: 1 };
10204
10492
  }
10493
+ if (options.abortSignal?.aborted && !sawDone) {
10494
+ turnOutput.spinner.stop();
10495
+ turnOutput.cancel();
10496
+ return {
10497
+ exitCode: 0,
10498
+ ...dialogId ? { dialogId } : {},
10499
+ streamInterrupted: true
10500
+ };
10501
+ }
10205
10502
  turnOutput.finish(content);
10206
10503
  const usageText = formatUsage(usage, dialogId);
10207
10504
  if (usageText && shouldShowUsage(options.env))
@@ -10418,7 +10715,7 @@ function findCollapsedPasteSpanAt(buffer, pos, opts = {}) {
10418
10715
  // packages/cli/client/agentRun.ts
10419
10716
  import { ulid as ulid2 } from "ulid";
10420
10717
  async function loadRunLocalAgentTurn() {
10421
- const { runLocalAgentTurn } = await import("./agentRuntimeLocal-NH6GSGAJ.js");
10718
+ const { runLocalAgentTurn } = await import("./agentRuntimeLocal-SDOSSCLU.js");
10422
10719
  return runLocalAgentTurn;
10423
10720
  }
10424
10721
  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();
@@ -10745,6 +11042,22 @@ var SERVER_FALLBACK_HINT = "or use --server to run on the server explicitly.";
10745
11042
  function buildAuthFailure(ctx) {
10746
11043
  const platformNoToken = ctx.where === "server chat proxy" && isAuthNoTokenBody(ctx.message);
10747
11044
  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`;
11045
+ const { url: validationUrl, text: validationText } = extractGoogleValidationLink(ctx.message);
11046
+ const validationLabel = validationText || "Verify your account";
11047
+ if (validationUrl) {
11048
+ const linkLine = `
11049
+ ${formatCliHyperlink(validationUrl, validationLabel)}`;
11050
+ const rawLine = resolveCliHyperlinkEnabled() ? `
11051
+ \u70B9\u4E0D\u4E86\u5C31\u590D\u5236\u8FD9\u884C: ${validationUrl}` : "";
11052
+ const verifyHint = `
11053
+ \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`;
11054
+ const retryLine = `
11055
+ \u9A8C\u8BC1\u5B8C\u6210\u540E\u76F4\u63A5\u91CD\u8BD5\u521A\u624D\u7684\u547D\u4EE4\u5373\u53EF\uFF0Ctoken \u4E0D\u7528\u91CD\u65B0\u767B\u5F55\u3002`;
11056
+ return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}: Google requires a one-time account verification \u2014 your credential is fine).
11057
+ Open this link in a browser signed into ${ctx.credentialAccountId ? `\`${ctx.credentialAccountId}\`` : "the Google account behind this credential"}:${linkLine}${rawLine}${verifyHint}${retryLine}
11058
+ Detail: ${ctx.message} ${NO_FALLBACK} Use --server to run on the server explicitly.
11059
+ `;
11060
+ }
10748
11061
  return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}, auth rejected). Detail: ${ctx.message} ${NO_FALLBACK} ${fix}, ${SERVER_FALLBACK_HINT}.
10749
11062
  `;
10750
11063
  }
@@ -10780,6 +11093,17 @@ function buildUpstreamFailure(ctx) {
10780
11093
  return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}). Detail: ${ctx.message} ${NO_FALLBACK} ${fix}, ${SERVER_FALLBACK_HINT}.
10781
11094
  `;
10782
11095
  }
11096
+ function formatLocalTurnFailureLine(error) {
11097
+ const message = toErrorMessage(error);
11098
+ if (error?.code === "LLM_REQUEST_TIMEOUT") {
11099
+ const msMatch = /after (\d+)ms/.exec(message);
11100
+ const deadline = msMatch && Number.isFinite(Number(msMatch[1])) ? formatElapsed(Math.round(Number(msMatch[1]) / 1e3)) : "the configured window";
11101
+ return `[nolo] ${t("llmRequestTimedOut", deadline)}
11102
+ `;
11103
+ }
11104
+ return `[nolo] Local agent run failed: ${message}
11105
+ `;
11106
+ }
10783
11107
  var FAILURE_BUILDERS = {
10784
11108
  auth: buildAuthFailure,
10785
11109
  "rejected-payload": buildRejectedPayloadFailure,
@@ -10788,6 +11112,7 @@ var FAILURE_BUILDERS = {
10788
11112
  upstream: buildUpstreamFailure
10789
11113
  };
10790
11114
  function describeLocalRunFailure(message, rawError) {
11115
+ const credentialAccountId = rawError && typeof rawError === "object" && typeof rawError.credentialAccountId === "string" ? rawError.credentialAccountId.trim() || void 0 : void 0;
10791
11116
  if (rawError && typeof rawError === "object" && "code" in rawError && rawError.code === "PLATFORM_STREAM_INTERRUPTED") {
10792
11117
  return "[nolo] The platform LLM stream was interrupted before the turn completed. Your conversation was preserved. Send another message to continue.\n";
10793
11118
  }
@@ -10865,7 +11190,8 @@ function describeLocalRunFailure(message, rawError) {
10865
11190
  status: cls.status,
10866
11191
  ...cls.statusInferred ? { statusInferred: true } : {},
10867
11192
  ...cls.quotaExhausted ? { quotaExhausted: true } : {},
10868
- ...cooldownUntil ? { cooldownUntil } : {}
11193
+ ...cooldownUntil ? { cooldownUntil } : {},
11194
+ ...credentialAccountId ? { credentialAccountId } : {}
10869
11195
  };
10870
11196
  return FAILURE_BUILDERS[cls.kind](ctx);
10871
11197
  }
@@ -11182,6 +11508,18 @@ async function runLocalAgentTurnForCli(options, settings) {
11182
11508
  if (event.kind === "llm-start") {
11183
11509
  turnOutput.showWorking();
11184
11510
  }
11511
+ if (event.kind === "turn-phase") {
11512
+ turnOutput.showPhase(event.phase);
11513
+ }
11514
+ if (event.kind === "compaction-start") {
11515
+ turnOutput.showPhase("compacting");
11516
+ }
11517
+ if (event.kind === "compaction-end" || // 压缩失败(timeout/provider-error)时 localLoop 按失败原子性语义
11518
+ // 带着裁剪后的历史继续本轮,切回等待模型文案;aborted 时 turn 随即
11519
+ // 结束,不再切文案(终态由 abort 路径收尾)。
11520
+ event.kind === "compaction-failed" && event.reason !== "aborted") {
11521
+ turnOutput.showPhase("waiting-provider");
11522
+ }
11185
11523
  if (event.kind === "image-downgraded") {
11186
11524
  options.output.write(
11187
11525
  "[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"
@@ -11227,6 +11565,9 @@ async function runLocalAgentTurnForCli(options, settings) {
11227
11565
  };
11228
11566
  } catch (error) {
11229
11567
  turnOutput.spinner.stop();
11568
+ turnOutput.cancel({
11569
+ preservePendingNarration: error?.code !== LOCAL_TURN_ABORTED_CODE && !options.abortSignal?.aborted
11570
+ });
11230
11571
  const savedDialogId = error?.dialogId;
11231
11572
  const abortedUsageRecords = error?.usageRecords;
11232
11573
  const abortedTurnCredits = sumPlatformCredits(abortedUsageRecords);
@@ -11250,10 +11591,12 @@ async function runLocalAgentTurnForCli(options, settings) {
11250
11591
  error.cooldownUntil = cooldownUntil;
11251
11592
  }
11252
11593
  if (settings.reportFailure) {
11253
- options.output.write(
11254
- `[nolo] Local agent run failed: ${toErrorMessage(error)}
11255
- `
11256
- );
11594
+ const failureLine = formatLocalTurnFailureLine(error);
11595
+ if (typeof options.output.writeErr === "function") {
11596
+ options.output.writeErr(failureLine);
11597
+ } else {
11598
+ options.output.write(failureLine);
11599
+ }
11257
11600
  if (cooldownUntil) {
11258
11601
  options.output.write(
11259
11602
  `[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
@@ -11290,22 +11633,24 @@ async function checkLocalAvailabilityBeforeHttpDispatch(options) {
11290
11633
  }
11291
11634
  const agentLevelAt = baseRecord.nextAvailableAt;
11292
11635
  const agentLevelNextAvailableAt = typeof agentLevelAt === "number" && Number.isFinite(agentLevelAt) ? agentLevelAt : void 0;
11293
- if (!credentialKey && agentLevelNextAvailableAt === void 0) return null;
11636
+ if (!credentialKey && agentLevelNextAvailableAt === void 0) {
11637
+ return { credentialKey };
11638
+ }
11294
11639
  const env = options.env;
11295
11640
  const now = Date.now();
11296
11641
  const entry = credentialKey ? await readCredentialEntry(credentialKey, env, now).catch(() => void 0) : void 0;
11297
11642
  const entryAt = entry?.nextAvailableAt;
11298
11643
  const effectiveNextAvailableAt = typeof entryAt === "number" ? mergeAvailabilityDeadline(agentLevelNextAvailableAt, entryAt) : agentLevelNextAvailableAt;
11299
- if (typeof effectiveNextAvailableAt !== "number") return null;
11644
+ if (typeof effectiveNextAvailableAt !== "number") return { credentialKey };
11300
11645
  const gateDecision = resolveCooldownGate(
11301
11646
  { nextAvailableAt: effectiveNextAvailableAt, lastProbeAt: entry?.lastProbeAt },
11302
11647
  now
11303
11648
  );
11304
11649
  if (gateDecision === "probe" && credentialKey) {
11305
11650
  await recordCredentialProbe(credentialKey, env, now).catch(() => void 0);
11306
- return null;
11651
+ return { credentialKey };
11307
11652
  }
11308
- if (gateDecision !== "blocked") return null;
11653
+ if (gateDecision !== "blocked") return { credentialKey };
11309
11654
  options.output.write(
11310
11655
  `[nolo] Agent ${options.agentName || options.agentKey} is temporarily unavailable (429 cooldown) until ${new Date(Number(effectiveNextAvailableAt)).toISOString()}.
11311
11656
  Dispatch aborted before reaching the server. Pick another agent via listAgents, or retry after the cooldown.
@@ -11388,11 +11733,18 @@ async function runAgentTurn(options) {
11388
11733
  );
11389
11734
  return { exitCode: 1 };
11390
11735
  }
11391
- const localBlock = await checkLocalAvailabilityBeforeHttpDispatch(options);
11392
- if (localBlock) {
11393
- return { exitCode: localBlock.exitCode };
11736
+ const localAvailability = await checkLocalAvailabilityBeforeHttpDispatch(options);
11737
+ if (localAvailability?.exitCode) {
11738
+ return { exitCode: localAvailability.exitCode };
11739
+ }
11740
+ const httpResult = await runHttpAgentTurn(options, authToken);
11741
+ if (httpResult.exitCode === 0 && !httpResult.streamInterrupted && localAvailability?.credentialKey) {
11742
+ await clearCredentialAvailability(
11743
+ localAvailability.credentialKey,
11744
+ options.env
11745
+ ).catch(() => void 0);
11394
11746
  }
11395
- return runHttpAgentTurn(options, authToken);
11747
+ return httpResult;
11396
11748
  }
11397
11749
 
11398
11750
  // packages/cli/agentRunCommand.ts
@@ -12155,6 +12507,11 @@ var listMemoryEntitiesVNext = async (db, ownerId) => {
12155
12507
  }
12156
12508
  return rows;
12157
12509
  };
12510
+ var loadMemoryVNextCatalog = async (db, ownerId) => {
12511
+ const entities = await listMemoryEntitiesVNext(db, ownerId);
12512
+ const states = (await Promise.all(entities.map((entity) => listMemoryStatesForEntityVNext(db, ownerId, entity.id)))).flat();
12513
+ return { entities, states };
12514
+ };
12158
12515
  var getMemoryStateVNext = async (db, ownerId, stateId) => db.get(stateKey(ownerId, stateId)).catch(() => null);
12159
12516
  var listMemoryStatesForEntityVNext = (db, ownerId, entityId) => readIndexed(db, stateEntityIndexPrefix(ownerId, entityId));
12160
12517
  var putMemoryEvidenceVNext = async (db, evidence) => {
@@ -12219,14 +12576,6 @@ var parseSelection = (raw) => {
12219
12576
  reason: obj.reason
12220
12577
  };
12221
12578
  };
12222
- var buildCatalog = async (db, ownerId) => {
12223
- const entities = await listMemoryEntitiesVNext(db, ownerId);
12224
- const states = [];
12225
- for (const entity of entities) {
12226
- states.push(...await listMemoryStatesForEntityVNext(db, ownerId, entity.id));
12227
- }
12228
- return { entities, states };
12229
- };
12230
12579
  var catalogText = (entities, states) => JSON.stringify(
12231
12580
  {
12232
12581
  entities: entities.map((entity) => ({
@@ -12252,7 +12601,7 @@ var catalogText = (entities, states) => JSON.stringify(
12252
12601
  );
12253
12602
  var createMemoryVNextRecall = (input) => async (query) => {
12254
12603
  const startedAt = performance.now();
12255
- const { entities, states } = await buildCatalog(input.db, input.ownerId);
12604
+ const { entities, states } = await loadMemoryVNextCatalog(input.db, input.ownerId);
12256
12605
  if (entities.length === 0 && states.length === 0) {
12257
12606
  return {
12258
12607
  query,
@@ -12394,10 +12743,14 @@ var withTimeout = async (promise, timeoutMs, label) => {
12394
12743
  };
12395
12744
  var runMemoryVNextShadowRead = async (input) => {
12396
12745
  const now = input.ctx.now ?? (() => performance.now());
12397
- const emit = input.emit ?? ((observation2) => console.info("[memory] vnext shadow read", {
12398
- event: "memory_vnext_shadow_read",
12399
- ...observation2
12400
- }));
12746
+ const defaultEmit = (observation2) => {
12747
+ const payload = {
12748
+ event: "memory_vnext_shadow_read",
12749
+ ...observation2
12750
+ };
12751
+ console.info("[memory] vnext shadow read", payload);
12752
+ };
12753
+ const emit = input.emit ?? defaultEmit;
12401
12754
  const legacyKeys = new Set(
12402
12755
  input.legacyItems.flatMap((item) => legacyItemKeys(item))
12403
12756
  );
@@ -13119,14 +13472,74 @@ var shortError2 = (error) => {
13119
13472
  return message.length > ERROR_MESSAGE_MAX2 ? `${message.slice(0, ERROR_MESSAGE_MAX2)}\u2026` : message;
13120
13473
  };
13121
13474
  var loadExistingContext = async (db, ownerId) => {
13122
- const entities = await listMemoryEntitiesVNext(db, ownerId);
13123
- const states = (await Promise.all(
13124
- entities.map((entity) => listMemoryStatesForEntityVNext(db, ownerId, entity.id))
13125
- )).flat();
13126
- return {
13127
- entityIds: entities.map((entity) => entity.id),
13128
- states
13475
+ const { entities, states } = await loadMemoryVNextCatalog(db, ownerId);
13476
+ return { entityIds: entities.map((entity) => entity.id), states };
13477
+ };
13478
+ var currentStatesCitingEvidence = (states, evidenceId) => states.filter((state2) => !state2.retiredAt && (state2.evidenceIds ?? []).includes(evidenceId));
13479
+ var isEvidenceCoveredByCurrentStates = (states, evidenceId) => currentStatesCitingEvidence(states, evidenceId).length > 0;
13480
+ var memoryVNextContextFingerprint = (existing) => {
13481
+ const states = existing.states ?? [];
13482
+ const entityIds = existing.entityIds ?? [];
13483
+ const canonical = [
13484
+ ...entityIds.map((id) => `e\0${id}`),
13485
+ ...states.map((state2) => `s\0${state2.id}\0${state2.updatedAt}\0${state2.retiredAt ?? ""}`)
13486
+ ].sort().join("");
13487
+ let hash = 2166136261;
13488
+ for (let i = 0; i < canonical.length; i++) {
13489
+ hash ^= canonical.charCodeAt(i);
13490
+ hash = Math.imul(hash, 16777619);
13491
+ }
13492
+ return `${entityIds.length}.${states.length}:${(hash >>> 0).toString(16)}`;
13493
+ };
13494
+ var MAX_NOOP_SUPPRESSIONS = 512;
13495
+ var noOpSuppressions = /* @__PURE__ */ new Map();
13496
+ var suppressionKey = (ownerId, evidenceId) => `${ownerId}\0${evidenceId}`;
13497
+ var recordNoOpSuppression = (ownerId, evidenceId, fingerprint) => {
13498
+ const key = suppressionKey(ownerId, evidenceId);
13499
+ noOpSuppressions.delete(key);
13500
+ noOpSuppressions.set(key, fingerprint);
13501
+ while (noOpSuppressions.size > MAX_NOOP_SUPPRESSIONS) {
13502
+ noOpSuppressions.delete(noOpSuppressions.keys().next().value);
13503
+ }
13504
+ };
13505
+ var noOpHistory = (ownerId, evidenceId, fingerprint) => {
13506
+ const recorded = noOpSuppressions.get(suppressionKey(ownerId, evidenceId));
13507
+ if (recorded === void 0) return "fresh";
13508
+ return recorded === fingerprint ? "suppressed" : "stale";
13509
+ };
13510
+ var pickFirstUncoveredLazyPromotionItem = async (db, selected) => {
13511
+ const contextByOwner = /* @__PURE__ */ new Map();
13512
+ const contextFor = (ownerId) => {
13513
+ let pending = contextByOwner.get(ownerId);
13514
+ if (!pending) {
13515
+ pending = loadExistingContext(db, ownerId).then((existing) => ({
13516
+ states: existing.states ?? [],
13517
+ fingerprint: memoryVNextContextFingerprint(existing)
13518
+ }));
13519
+ contextByOwner.set(ownerId, pending);
13520
+ }
13521
+ return pending;
13129
13522
  };
13523
+ let skippedCoveredCount = 0;
13524
+ let skippedNoOpCount = 0;
13525
+ let firstStale = null;
13526
+ for (const [selectedIndex, item] of selected.entries()) {
13527
+ const evidence = buildLegacyMemoryEvidence(item);
13528
+ const context = await contextFor(evidence.ownerId);
13529
+ if (isEvidenceCoveredByCurrentStates(context.states, evidence.id)) {
13530
+ skippedCoveredCount++;
13531
+ continue;
13532
+ }
13533
+ const history = noOpHistory(evidence.ownerId, evidence.id, context.fingerprint);
13534
+ if (history === "fresh") {
13535
+ return { item, selectedIndex, skippedCoveredCount, skippedNoOpCount };
13536
+ }
13537
+ if (history === "stale" && !firstStale) {
13538
+ firstStale = { item, selectedIndex, skippedCoveredCount, skippedNoOpCount };
13539
+ }
13540
+ skippedNoOpCount++;
13541
+ }
13542
+ return firstStale;
13130
13543
  };
13131
13544
  var withoutImportedEvidence = (mutation, importedEvidenceId) => ({
13132
13545
  ...mutation,
@@ -13142,6 +13555,11 @@ var runMemoryVNextLazyPromotion = async (input) => {
13142
13555
  }));
13143
13556
  const finish = (partial) => {
13144
13557
  const observation = {
13558
+ legacyItemId: input.item.id,
13559
+ evidenceId: deterministicEvidence.id,
13560
+ ...input.selectedIndex === void 0 ? {} : { selectedIndex: input.selectedIndex },
13561
+ ...input.skippedCoveredCount === void 0 ? {} : { skippedCoveredCount: input.skippedCoveredCount },
13562
+ ...input.skippedNoOpCount === void 0 ? {} : { skippedNoOpCount: input.skippedNoOpCount },
13145
13563
  ...partial,
13146
13564
  latencyMs: Math.round((clock() - startedAt) * 10) / 10
13147
13565
  };
@@ -13164,8 +13582,9 @@ var runMemoryVNextLazyPromotion = async (input) => {
13164
13582
  }
13165
13583
  const evidence = evidenceResult.evidence;
13166
13584
  const existing = await loadExistingContext(input.db, evidence.ownerId);
13167
- const alreadyCovered = (existing.states ?? []).some(
13168
- (state2) => !state2.retiredAt && state2.evidenceIds.includes(evidence.id)
13585
+ const alreadyCovered = isEvidenceCoveredByCurrentStates(
13586
+ existing.states ?? [],
13587
+ evidence.id
13169
13588
  );
13170
13589
  if (alreadyCovered) {
13171
13590
  return finish({ status: "already_covered" });
@@ -13180,6 +13599,11 @@ var runMemoryVNextLazyPromotion = async (input) => {
13180
13599
  });
13181
13600
  const semanticMutation = withoutImportedEvidence(interpreted.mutation, evidence.id);
13182
13601
  if (!hasWrites(semanticMutation)) {
13602
+ recordNoOpSuppression(
13603
+ evidence.ownerId,
13604
+ evidence.id,
13605
+ memoryVNextContextFingerprint(existing)
13606
+ );
13183
13607
  return finish({ status: "no_op", action: semanticMutation.action });
13184
13608
  }
13185
13609
  await applyMemoryInterpreterMutation(input.db, evidence.ownerId, semanticMutation);
@@ -13192,6 +13616,179 @@ var runMemoryVNextLazyPromotion = async (input) => {
13192
13616
  };
13193
13617
  var isMemoryVNextLazyPromotionEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_LAZY_PROMOTION === "1" || env.NOLO_MEMORY_VNEXT_LAZY_PROMOTION === "true";
13194
13618
 
13619
+ // packages/ai/memory/vnext/pureReadGate.ts
13620
+ var isMemoryVNextPureReadEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_PURE_READ === "1" || env.NOLO_MEMORY_VNEXT_PURE_READ === "true";
13621
+
13622
+ // packages/ai/memory/vnext/localRecall.ts
13623
+ var MIN_SHARED_TOKENS = 2;
13624
+ var MAX_LOCAL_RECALL_STATES = 8;
13625
+ var SAFE_TECHNICAL_SYNONYMS = {
13626
+ pr: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5", "diff"],
13627
+ diff: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5"],
13628
+ review: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5"],
13629
+ deploy: ["\u90E8\u7F72", "\u53D1\u7248"],
13630
+ release: ["\u53D1\u7248", "\u53D1\u5E03"],
13631
+ desktop: ["\u684C\u9762", "\u684C\u9762\u7AEF"]
13632
+ };
13633
+ var distinctTokens = (text) => new Set(tokenize2(text).filter((token) => token.length >= 2));
13634
+ var recallMemoryVNextLocal = (input) => {
13635
+ const rawTokens = distinctTokens(input.query);
13636
+ if (rawTokens.size === 0) return [];
13637
+ const queryTokens = new Set(rawTokens);
13638
+ for (const token of rawTokens) {
13639
+ const syns = SAFE_TECHNICAL_SYNONYMS[token.toLowerCase()];
13640
+ if (syns) {
13641
+ for (const syn of syns) {
13642
+ for (const t2 of distinctTokens(syn)) queryTokens.add(t2);
13643
+ }
13644
+ }
13645
+ }
13646
+ const entityById = new Map(input.entities.map((entity) => [entity.id, entity]));
13647
+ const hits = [];
13648
+ for (const state2 of input.states) {
13649
+ if (state2.retiredAt || !state2.text.trim()) continue;
13650
+ const entity = entityById.get(state2.entityId);
13651
+ const haystack = distinctTokens(
13652
+ [state2.facet, state2.text, entity?.name ?? "", ...entity?.aliases ?? []].join(" ")
13653
+ );
13654
+ let sharedTokens = 0;
13655
+ for (const token of queryTokens) if (haystack.has(token)) sharedTokens++;
13656
+ if (sharedTokens >= MIN_SHARED_TOKENS) hits.push({ state: state2, sharedTokens });
13657
+ }
13658
+ return hits.sort((a, b) => b.sharedTokens - a.sharedTokens || a.state.id.localeCompare(b.state.id)).slice(0, input.limit ?? MAX_LOCAL_RECALL_STATES);
13659
+ };
13660
+
13661
+ // packages/ai/memory/vnext/pureVNextRuntime.ts
13662
+ var buildSynthesizedStateItem = (state2, entity, ownerType, ownerId) => ({
13663
+ id: `vnext-state-${state2.id}`,
13664
+ ownerType,
13665
+ ownerId,
13666
+ visibility: "private",
13667
+ subjectType: "user",
13668
+ subjectId: ownerId,
13669
+ kind: "semantic",
13670
+ content: state2.text.trim(),
13671
+ createdAt: state2.createdAt,
13672
+ lastActivatedAt: state2.createdAt,
13673
+ activationCount: 1,
13674
+ importance: 0.9,
13675
+ confidence: 0.9,
13676
+ resident: state2.facet === "preference" || state2.facet === "style"
13677
+ });
13678
+ async function resolvePureVNextRuntime(input) {
13679
+ const { db, owners, userInput } = input;
13680
+ if (owners.length === 0 || !userInput.trim()) {
13681
+ return { selectedItems: [], promptBlock: null, recalledStateCount: 0 };
13682
+ }
13683
+ const ownerIds = owners.map((o) => `${o.ownerType}:${encodeURIComponent(o.ownerId)}`);
13684
+ const catalogs = await Promise.all(
13685
+ ownerIds.map((ownerId) => loadMemoryVNextCatalog(db, ownerId))
13686
+ );
13687
+ const selectedItems = [];
13688
+ const seenStateKeys = /* @__PURE__ */ new Set();
13689
+ for (let i = 0; i < owners.length; i++) {
13690
+ const owner = owners[i];
13691
+ const catalog = catalogs[i];
13692
+ const currentStates = catalog.states.filter((s) => !s.retiredAt && s.text.trim());
13693
+ const hits = recallMemoryVNextLocal({
13694
+ query: userInput,
13695
+ entities: catalog.entities,
13696
+ states: currentStates
13697
+ });
13698
+ const entityById = new Map(catalog.entities.map((e) => [e.id, e]));
13699
+ for (const hit of hits) {
13700
+ const stateKey2 = `${hit.state.ownerId}\0${hit.state.id}`;
13701
+ if (seenStateKeys.has(stateKey2)) continue;
13702
+ seenStateKeys.add(stateKey2);
13703
+ selectedItems.push(
13704
+ buildSynthesizedStateItem(hit.state, entityById.get(hit.state.entityId), owner.ownerType, owner.ownerId)
13705
+ );
13706
+ }
13707
+ }
13708
+ const promptBlock = selectedItems.length === 0 ? null : buildMemoryOverlay(selectedItems, {
13709
+ maxTokens: input.maxTokens ?? DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET
13710
+ });
13711
+ return {
13712
+ selectedItems,
13713
+ promptBlock,
13714
+ recalledStateCount: selectedItems.length
13715
+ };
13716
+ }
13717
+
13718
+ // packages/ai/memory/vnext/primaryRead.ts
13719
+ var MEMORY_VNEXT_PRIMARY_READ_TIMEOUT_MS = 300;
13720
+ var isMemoryVNextPrimaryReadEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_PRIMARY_READ === "1" || env.NOLO_MEMORY_VNEXT_PRIMARY_READ === "true";
13721
+ var buildSynthesizedStateItem2 = (state2, entity, ownerType, ownerId) => ({
13722
+ id: `vnext-state-${state2.id}`,
13723
+ ownerType,
13724
+ ownerId,
13725
+ visibility: "private",
13726
+ subjectType: "user",
13727
+ subjectId: ownerId,
13728
+ kind: "semantic",
13729
+ content: state2.text.trim(),
13730
+ createdAt: state2.createdAt,
13731
+ importance: 0.9,
13732
+ confidence: 0.9,
13733
+ // Flag resident preferences so they flow into overlay's resident section.
13734
+ resident: state2.facet === "preference" || state2.facet === "style",
13735
+ lastActivatedAt: state2.createdAt,
13736
+ activationCount: 1
13737
+ });
13738
+ var resolveMemoryVNextM4Selection = async (input) => {
13739
+ const { db, owners, query, selected } = input;
13740
+ const ownerIds = owners.map((o) => `${o.ownerType}:${encodeURIComponent(o.ownerId)}`);
13741
+ const catalogs = new Map(
13742
+ await Promise.all(
13743
+ ownerIds.map(async (ownerId) => [
13744
+ ownerId,
13745
+ await loadMemoryVNextCatalog(db, ownerId)
13746
+ ])
13747
+ )
13748
+ );
13749
+ const recalledStates = [];
13750
+ const recalledStateIds = /* @__PURE__ */ new Set();
13751
+ for (const owner of owners) {
13752
+ const principalId = `${owner.ownerType}:${encodeURIComponent(owner.ownerId)}`;
13753
+ const catalog = catalogs.get(principalId);
13754
+ if (!catalog) continue;
13755
+ const currentStates = catalog.states.filter((s) => !s.retiredAt && s.text.trim());
13756
+ const hits = recallMemoryVNextLocal({
13757
+ query,
13758
+ entities: catalog.entities,
13759
+ states: currentStates
13760
+ });
13761
+ const entityById = new Map(catalog.entities.map((e) => [e.id, e]));
13762
+ for (const hit of hits) {
13763
+ if (recalledStateIds.has(hit.state.id)) continue;
13764
+ recalledStateIds.add(hit.state.id);
13765
+ recalledStates.push(
13766
+ buildSynthesizedStateItem2(hit.state, entityById.get(hit.state.entityId), owner.ownerType, owner.ownerId)
13767
+ );
13768
+ }
13769
+ }
13770
+ const uncoveredLegacy = [];
13771
+ let coveredSuppressedCount = 0;
13772
+ for (const item of selected) {
13773
+ const evidence = buildLegacyMemoryEvidence(item);
13774
+ const catalog = catalogs.get(evidence.ownerId);
13775
+ const states = catalog?.states ?? [];
13776
+ const covering = currentStatesCitingEvidence(states, evidence.id);
13777
+ if (covering.length > 0) {
13778
+ coveredSuppressedCount++;
13779
+ } else {
13780
+ uncoveredLegacy.push(item);
13781
+ }
13782
+ }
13783
+ const renderItems = [...recalledStates, ...uncoveredLegacy];
13784
+ return {
13785
+ renderItems,
13786
+ recalledStateCount: recalledStates.length,
13787
+ uncoveredLegacyCount: uncoveredLegacy.length,
13788
+ coveredSuppressedCount
13789
+ };
13790
+ };
13791
+
13195
13792
  // packages/ai/memory/runtime.ts
13196
13793
  var COLD_STORAGE_CONFIDENCE = 0.3;
13197
13794
  var MEMORY_OVERLAY_TOKEN_BUDGET = DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET;
@@ -13314,6 +13911,18 @@ var resolveMemoryRuntime = async (input) => {
13314
13911
  if (owners.length === 0) {
13315
13912
  return { selectedItems: [], promptBlock: null };
13316
13913
  }
13914
+ if (isMemoryVNextPureReadEnabled()) {
13915
+ const pure = await resolvePureVNextRuntime({
13916
+ db: input.db,
13917
+ owners,
13918
+ userInput: input.userInput,
13919
+ maxTokens: MEMORY_OVERLAY_TOKEN_BUDGET
13920
+ });
13921
+ return {
13922
+ selectedItems: pure.selectedItems,
13923
+ promptBlock: pure.promptBlock
13924
+ };
13925
+ }
13317
13926
  const policy = resolveAgentMemoryPolicy({ agentKey: input.agentKey });
13318
13927
  const legacyStartedAt = performance.now();
13319
13928
  const candidates = await loadMemoryCandidatesFromDb(input.db, {
@@ -13343,10 +13952,62 @@ var resolveMemoryRuntime = async (input) => {
13343
13952
  );
13344
13953
  const selected = [...residentItems, ...ranked];
13345
13954
  const legacyLatencyMs = Math.round((performance.now() - legacyStartedAt) * 10) / 10;
13346
- const promptBlock = selected.length === 0 ? null : buildMemoryOverlay(selected, { maxTokens: MEMORY_OVERLAY_TOKEN_BUDGET });
13347
- const shadowEnabled = input.vNextShadowProvider != null && isMemoryVNextShadowReadEnabled();
13955
+ const renderOverlay = (items) => items.length === 0 ? null : buildMemoryOverlay(items, { maxTokens: MEMORY_OVERLAY_TOKEN_BUDGET });
13956
+ let promptBlock = renderOverlay(selected);
13957
+ const primaryRead = isMemoryVNextPrimaryReadEnabled();
13958
+ let allCoveredByVNext = false;
13959
+ if (primaryRead) {
13960
+ const emitPrimary = (observation) => {
13961
+ try {
13962
+ (input.primaryReadEmit ?? ((o) => console.info("[memory] vnext primary read", { event: "memory_vnext_primary_read", ...o })))(observation);
13963
+ } catch {
13964
+ }
13965
+ };
13966
+ const base = { legacyHitCount: selected.length, legacyLatencyMs };
13967
+ const vnextStartedAt = performance.now();
13968
+ const vnextLatency = () => Math.round((performance.now() - vnextStartedAt) * 10) / 10;
13969
+ if (selected.length === 0) {
13970
+ emitPrimary({ ...base, source: "none" });
13971
+ } else {
13972
+ try {
13973
+ let timer;
13974
+ const m4 = await Promise.race([
13975
+ resolveMemoryVNextM4Selection({ db: input.db, owners, query: input.userInput, selected }),
13976
+ new Promise((_, reject) => {
13977
+ timer = setTimeout(
13978
+ () => reject(Object.assign(new Error("timeout"), { name: "TimeoutError" })),
13979
+ MEMORY_VNEXT_PRIMARY_READ_TIMEOUT_MS
13980
+ );
13981
+ })
13982
+ ]).finally(() => clearTimeout(timer));
13983
+ promptBlock = renderOverlay(m4.renderItems);
13984
+ allCoveredByVNext = m4.uncoveredLegacyCount === 0 && m4.recalledStateCount > 0;
13985
+ const source = m4.recalledStateCount > 0 ? m4.uncoveredLegacyCount === 0 ? "vnext" : "hybrid" : m4.uncoveredLegacyCount > 0 ? "legacy_fallback" : "none";
13986
+ emitPrimary({
13987
+ ...base,
13988
+ source,
13989
+ uncoveredLegacyCount: m4.uncoveredLegacyCount,
13990
+ coveredSuppressedCount: m4.coveredSuppressedCount,
13991
+ recalledStateCount: m4.recalledStateCount,
13992
+ vnextLatencyMs: vnextLatency(),
13993
+ contextChars: promptBlock?.length ?? 0,
13994
+ ...source === "legacy_fallback" ? { fallbackReason: "no_vnext_context" } : {}
13995
+ });
13996
+ } catch (error) {
13997
+ emitPrimary({
13998
+ ...base,
13999
+ source: "legacy_fallback",
14000
+ vnextLatencyMs: vnextLatency(),
14001
+ contextChars: promptBlock?.length ?? 0,
14002
+ fallbackReason: "vnext_error",
14003
+ error: error instanceof Error ? error.name : "UnknownError"
14004
+ });
14005
+ }
14006
+ }
14007
+ }
14008
+ const shadowEnabled = !primaryRead && input.vNextShadowProvider != null && isMemoryVNextShadowReadEnabled();
13348
14009
  if (shadowEnabled) {
13349
- await runMemoryVNextShadowRead({
14010
+ void runMemoryVNextShadowRead({
13350
14011
  ctx: {
13351
14012
  db: input.db,
13352
14013
  owners,
@@ -13356,17 +14017,28 @@ var resolveMemoryRuntime = async (input) => {
13356
14017
  legacyItems: selected,
13357
14018
  legacyLatencyMs,
13358
14019
  legacyContextChars: promptBlock?.length ?? 0
14020
+ }).catch(() => {
13359
14021
  });
13360
14022
  }
13361
- const promotionCandidate = selected[0];
13362
14023
  const lazyPromotionEnabled = input.vNextShadowProvider != null && isMemoryVNextLazyPromotionEnabled();
13363
- if (lazyPromotionEnabled && promotionCandidate) {
13364
- void runMemoryVNextLazyPromotion({
13365
- db: input.db,
13366
- item: promotionCandidate,
13367
- provider: input.vNextShadowProvider,
13368
- ...input.lazyPromotionEmit ? { emit: input.lazyPromotionEmit } : {}
13369
- }).catch(() => {
14024
+ if (lazyPromotionEnabled && selected.length > 0 && !allCoveredByVNext) {
14025
+ void (async () => {
14026
+ const promotionPick = await pickFirstUncoveredLazyPromotionItem(
14027
+ input.db,
14028
+ selected
14029
+ );
14030
+ if (promotionPick) {
14031
+ await runMemoryVNextLazyPromotion({
14032
+ db: input.db,
14033
+ item: promotionPick.item,
14034
+ selectedIndex: promotionPick.selectedIndex,
14035
+ skippedCoveredCount: promotionPick.skippedCoveredCount,
14036
+ skippedNoOpCount: promotionPick.skippedNoOpCount,
14037
+ provider: input.vNextShadowProvider,
14038
+ ...input.lazyPromotionEmit ? { emit: input.lazyPromotionEmit } : {}
14039
+ });
14040
+ }
14041
+ })().catch(() => {
13370
14042
  });
13371
14043
  }
13372
14044
  if (selected.length === 0) {
@@ -13380,6 +14052,52 @@ var resolveMemoryRuntime = async (input) => {
13380
14052
  };
13381
14053
 
13382
14054
  // packages/cli/memoryRecall.ts
14055
+ var logger = getLogger("cli.memoryRecall");
14056
+ var DEDUP_WINDOW_MS = 5 * 60 * 1e3;
14057
+ var DEDUP_MAX_KEYS = 100;
14058
+ var dedupMap = /* @__PURE__ */ new Map();
14059
+ function evictDedupIfNeeded() {
14060
+ if (dedupMap.size < DEDUP_MAX_KEYS) return;
14061
+ let oldestKey = null;
14062
+ let oldestTs = Infinity;
14063
+ for (const [k, v] of dedupMap) {
14064
+ if (v.lastLog < oldestTs) {
14065
+ oldestTs = v.lastLog;
14066
+ oldestKey = k;
14067
+ }
14068
+ }
14069
+ if (oldestKey !== null) dedupMap.delete(oldestKey);
14070
+ }
14071
+ function logDeduped(level, fingerprint, message, error) {
14072
+ const now = Date.now();
14073
+ const entry = dedupMap.get(fingerprint);
14074
+ if (!entry) {
14075
+ evictDedupIfNeeded();
14076
+ dedupMap.set(fingerprint, { count: 1, suppressed: 0, lastLog: now });
14077
+ if (error !== void 0) logger[level](message, error);
14078
+ else logger[level](message);
14079
+ return;
14080
+ }
14081
+ entry.count += 1;
14082
+ if (now - entry.lastLog >= DEDUP_WINDOW_MS) {
14083
+ const suppressed = entry.suppressed;
14084
+ const summary = `${message} (deduplicated: ${entry.count} occurrences, ${suppressed} suppressed over ${Math.round((now - entry.lastLog) / 1e3)}s)`;
14085
+ if (error !== void 0) logger[level](summary, error);
14086
+ else logger[level](summary);
14087
+ entry.count = 1;
14088
+ entry.suppressed = 0;
14089
+ entry.lastLog = now;
14090
+ } else {
14091
+ entry.suppressed += 1;
14092
+ }
14093
+ }
14094
+ function fingerprintFor(kind, detail) {
14095
+ const d = detail === void 0 ? "" : sanitizeFp(String(detail));
14096
+ return `mem-${kind}:${d}`;
14097
+ }
14098
+ function sanitizeFp(s) {
14099
+ return s.replace(/\s+/g, " ").slice(0, 80);
14100
+ }
13383
14101
  var queryRemoteMemory = async (serverUrl, authToken, agentKey, userInput, spaceId) => {
13384
14102
  try {
13385
14103
  const response = await fetch(`${serverUrl}/api/memory/query`, {
@@ -13396,10 +14114,10 @@ var queryRemoteMemory = async (serverUrl, authToken, agentKey, userInput, spaceI
13396
14114
  signal: AbortSignal.timeout(5e3)
13397
14115
  });
13398
14116
  if (!response.ok) {
13399
- console.warn(
13400
- "[cli-memory] remote query returned non-ok status:",
13401
- response.status,
13402
- "\u2014 falling back to local"
14117
+ logDeduped(
14118
+ "warn",
14119
+ fingerprintFor("remote-nonok", response.status),
14120
+ `remote query returned non-ok status ${response.status} \u2014 falling back to local`
13403
14121
  );
13404
14122
  return null;
13405
14123
  }
@@ -13407,7 +14125,12 @@ var queryRemoteMemory = async (serverUrl, authToken, agentKey, userInput, spaceI
13407
14125
  const block = typeof payload?.promptBlock === "string" ? payload.promptBlock.trim() : "";
13408
14126
  return block || null;
13409
14127
  } catch (error) {
13410
- console.warn("[cli-memory] remote query failed, falling back to local:", error);
14128
+ logDeduped(
14129
+ "info",
14130
+ fingerprintFor("remote-failed", error instanceof Error ? error.name : void 0),
14131
+ "remote query failed, falling back to local",
14132
+ normalizeError(error)
14133
+ );
13411
14134
  return null;
13412
14135
  }
13413
14136
  };
@@ -13443,7 +14166,12 @@ var resolveCliMemory = async (input) => {
13443
14166
  input.spaceId
13444
14167
  );
13445
14168
  } catch (error) {
13446
- console.warn("[cli-memory] local recall failed, omitting memory layer:", error);
14169
+ logDeduped(
14170
+ "warn",
14171
+ fingerprintFor("local-failed", error instanceof Error ? error.name : void 0),
14172
+ "local recall failed, omitting memory layer",
14173
+ normalizeError(error)
14174
+ );
13447
14175
  return null;
13448
14176
  }
13449
14177
  };
@@ -13498,7 +14226,10 @@ async function resolveAgentRunAgentKey(args) {
13498
14226
  }
13499
14227
  async function runAgentRunCommand(args, deps) {
13500
14228
  const env = deps.env ?? process.env;
13501
- const output = deps.output ?? process.stdout;
14229
+ const output = deps.output ?? {
14230
+ write: (chunk) => process.stdout.write(chunk),
14231
+ writeErr: (chunk) => process.stderr.write(chunk)
14232
+ };
13502
14233
  if (args.includes("--help") || args.includes("-h")) {
13503
14234
  writeUsage(output, deps.commandPath);
13504
14235
  return 0;
@@ -14040,12 +14771,6 @@ function isBalanceExhaustedError(error) {
14040
14771
  }
14041
14772
 
14042
14773
  export {
14043
- resolveAgentModelIdentity,
14044
- resolveAgentContextWindow,
14045
- platformCreditsFromUsage,
14046
- formatCreditsChip,
14047
- formatTokenCount,
14048
- renderTokenStatus,
14049
14774
  resolveCliColorEnabled,
14050
14775
  dimCliText,
14051
14776
  ANSI_ESCAPE_REGEX,
@@ -14086,6 +14811,12 @@ export {
14086
14811
  formatAssistantDisplay,
14087
14812
  redactSecrets,
14088
14813
  TUI_TREE_MARKER,
14814
+ resolveAgentModelIdentity,
14815
+ resolveAgentContextWindow,
14816
+ platformCreditsFromUsage,
14817
+ formatCreditsChip,
14818
+ formatTokenCount,
14819
+ renderTokenStatus,
14089
14820
  COLLAPSED_PASTE_PLACEHOLDER_RE,
14090
14821
  shouldCollapsePaste,
14091
14822
  createCollapsedPasteStore,
@@ -14096,15 +14827,16 @@ export {
14096
14827
  releaseCollapsedPasteReferences,
14097
14828
  expandRangeToCollapsedPasteChips,
14098
14829
  findCollapsedPasteSpanAt,
14830
+ formatElapsed,
14099
14831
  runAgentTurn,
14100
- readAgentsMdLayerFromDisk,
14101
14832
  resolveWorkflowReference,
14102
14833
  resolveSkillReference,
14103
14834
  buildSkillContextBlocks,
14104
14835
  prependSubjectDialogMarker,
14105
14836
  normalizeCliImageInput,
14106
- inspectLocalRunWorkspace,
14837
+ readAgentsMdLayerFromDisk,
14107
14838
  resolveCliMemory,
14839
+ inspectLocalRunWorkspace,
14108
14840
  resolveRunOutcome,
14109
14841
  isRunResultStalledOrTruncated,
14110
14842
  resolveRunSettlementNote,