nolo-cli 0.95.0-alpha.6 → 0.95.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 (181) hide show
  1. package/README.md +1 -1
  2. package/{_executeModel-AUQRMRWL.js → _executeModel-2A5AFVBG.js} +67 -63
  3. package/{action-YVYQEAAV.js → action-GI44T4DR.js} +10 -10
  4. package/{addContentAction-O7R66HEX.js → addContentAction-B2DRF7P6.js} +9 -9
  5. package/{addDialogAgentAction-74OA7KYP.js → addDialogAgentAction-T3I7IXPK.js} +15 -17
  6. package/{agentDeleteCommand-4BAHJRU3.js → agentDeleteCommand-QYCCUQ35.js} +47 -43
  7. package/{agentEmailCommands-QISOY7Y6.js → agentEmailCommands-IX6COKHS.js} +89 -82
  8. package/{agentListCommands-U46ODMQU.js → agentListCommands-JDU7V3M5.js} +77 -82
  9. package/{agentMachineCommands-EHV2KM2C.js → agentMachineCommands-W36VFO5M.js} +42 -38
  10. package/{agentProviderCommands-GNPTL5XR.js → agentProviderCommands-YK2BIIXZ.js} +1 -1
  11. package/{agentPullCommand-O5MPVJ5E.js → agentPullCommand-HF4A42D4.js} +1 -1
  12. package/agentRecordCommands-JGOTOBTW.js +135 -0
  13. package/{agentRunCommand-K4CLMA6B.js → agentRunCommand-LJBG6YF2.js} +89 -80
  14. package/{agentRunControl-XLGD3UZ5.js → agentRunControl-5T64LM2M.js} +2 -2
  15. package/{agentRuntimeLocal-O4HPUJA4.js → agentRuntimeLocal-SYLNOKCT.js} +44 -36
  16. package/{agentSlice-ZYT2OUR3.js → agentSlice-FZ7GGQM2.js} +11 -11
  17. package/{appDeleteCommands-R5BBTKQK.js → appDeleteCommands-IP22BHZE.js} +42 -38
  18. package/{appDeployCommands-ZJIXOJWD.js → appDeployCommands-5ZTQL6UL.js} +42 -38
  19. package/{appDeployStatusCommands-B3R2ZTBF.js → appDeployStatusCommands-G6EMAT75.js} +42 -38
  20. package/{appGetCommands-2AQSOV2A.js → appGetCommands-UXBDAYEM.js} +42 -38
  21. package/{appListCommands-HCIJGZFY.js → appListCommands-J274GTVP.js} +42 -38
  22. package/{authCommand-F4EFRRX6.js → authCommand-2YPMMIJN.js} +117 -23
  23. package/{authCommands-RGOGCPP6.js → authCommands-FFDS4FVX.js} +7 -5
  24. package/{builtinSkillRegistry-FUAVTRVZ.js → builtinSkillRegistry-ZMF6YGNO.js} +6 -5
  25. package/{chatQueueReduxAdapter-Q5V4YJVI.js → chatQueueReduxAdapter-PRP4YQP7.js} +30 -29
  26. package/{chromeCommands-FZYAU75D.js → chromeCommands-K27J4OVZ.js} +124 -28
  27. package/{chromeOpsCommands-62P2Q2YB.js → chromeOpsCommands-IXRLN57H.js} +4 -3
  28. package/{chunk-6OZ36FXI.js → chunk-27ONFIEY.js} +22 -4
  29. package/chunk-2QZTQEW4.js +13349 -0
  30. package/{chunk-JEDZAO7L.js → chunk-2SYTUTLI.js} +257 -37
  31. package/{chunk-OIVSQH2O.js → chunk-3BXNTXYI.js} +299 -5
  32. package/{chunk-ZLR5JN3E.js → chunk-4B4DAAFV.js} +7 -7
  33. package/{chunk-EYAQT56M.js → chunk-4DPP773Q.js} +2 -2
  34. package/chunk-4LCOCOR5.js +50 -0
  35. package/{chunk-BZWBEHGD.js → chunk-4MPGAOXS.js} +66 -38
  36. package/{chunk-JOHSKZQX.js → chunk-4RTK7EHT.js} +865 -207
  37. package/{chunk-2GRGFCF6.js → chunk-4VJAC32I.js} +2 -1
  38. package/{chunk-MC4XLIJ7.js → chunk-523DITKR.js} +1 -1
  39. package/{chunk-IAO6JBYW.js → chunk-5B7XS6UO.js} +164 -14
  40. package/{chunk-E4MARS3Q.js → chunk-5GVBDNTO.js} +1 -1
  41. package/chunk-5J3PYNUP.js +255 -0
  42. package/chunk-5MMAK75Q.js +15 -0
  43. package/{chunk-JPGCXHNM.js → chunk-5OA5HMTL.js} +1 -1
  44. package/{chunk-42V6BK2E.js → chunk-62IL3KQV.js} +4 -34
  45. package/{chunk-YQTQQX2H.js → chunk-67HHBCFJ.js} +1 -1
  46. package/{chunk-SNPMM7H3.js → chunk-67T7O467.js} +13 -13
  47. package/{chunk-6YTOJY35.js → chunk-6D2JFXLY.js} +35 -0
  48. package/{chunk-4MY4GLIW.js → chunk-6IHBIRPK.js} +969 -1090
  49. package/{chunk-3BMYXEUW.js → chunk-6O4IK4V2.js} +1 -1
  50. package/{chunk-XOVEWFLK.js → chunk-6RDFAKG7.js} +100 -100
  51. package/{chunk-DHDMC6FO.js → chunk-6TPOEJMQ.js} +9 -4
  52. package/{chunk-WADCY6G6.js → chunk-6ZWMH6TJ.js} +111 -41
  53. package/{chunk-ABQYVJBJ.js → chunk-7CHC4W22.js} +1 -1
  54. package/{chunk-GQBOR3G6.js → chunk-7KVZ5LDQ.js} +2 -2
  55. package/{chunk-OA6Q2A4I.js → chunk-A7RSPKU6.js} +98 -22
  56. package/{chunk-KQ4ONNQD.js → chunk-ALFH24P3.js} +56 -7
  57. package/{chunk-Q554LLSI.js → chunk-AUDNYVRC.js} +1 -1
  58. package/{chunk-GPCZ7UXG.js → chunk-AZRHIN5B.js} +1 -1
  59. package/{chunk-JRQFUXY7.js → chunk-B2XUQXQX.js} +96 -19
  60. package/{chunk-EGSKXKR5.js → chunk-BJJL5DZF.js} +1 -1
  61. package/chunk-BMQ2MJUK.js +153 -0
  62. package/{chunk-XRWZB6CF.js → chunk-BVWTQJAA.js} +23 -76
  63. package/{chunk-3IIEFNGY.js → chunk-C53ZG23R.js} +2 -2
  64. package/chunk-CHOZJMJS.js +78 -0
  65. package/{chunk-HJUYAD4A.js → chunk-CPUFH46E.js} +8 -8
  66. package/{chunk-LS2ZANRJ.js → chunk-CTUQJVQM.js} +1 -1
  67. package/{chunk-BP4XNZRM.js → chunk-CU3QB4HW.js} +3 -3
  68. package/{chunk-ACTMNVHM.js → chunk-CYSYR67N.js} +1 -1
  69. package/{chunk-VLTIYV3X.js → chunk-DCLMZ5TX.js} +4 -4
  70. package/{chunk-UKZDAFYT.js → chunk-DSSTTEKI.js} +6 -10
  71. package/{chunk-HVURBGF3.js → chunk-ESRMFY7G.js} +2 -2
  72. package/{chunk-TRV2MIDW.js → chunk-EXAJ6DCR.js} +1 -0
  73. package/chunk-GMZLP5DV.js +82 -0
  74. package/{chunk-FDTR4QJ6.js → chunk-H6A6X4EK.js} +32 -1
  75. package/{chunk-DVINR3PL.js → chunk-HDLLCBRF.js} +1 -1
  76. package/{chunk-ONXOABJR.js → chunk-HNGRBWYF.js} +3 -0
  77. package/{chunk-H62HCIUP.js → chunk-HYZIYH2H.js} +11 -10
  78. package/{chunk-MMPXJXHT.js → chunk-HZH7RULB.js} +582 -478
  79. package/{chunk-NTW5GWDM.js → chunk-I3QNET24.js} +32 -17
  80. package/{chunk-WV42OMV7.js → chunk-IAESIMK7.js} +4 -4
  81. package/{chunk-QIAVMDHY.js → chunk-IUVCUGQR.js} +4 -4
  82. package/{chunk-AFDS2CVM.js → chunk-K5UOP7AI.js} +15 -20
  83. package/{chunk-IIVGDG4I.js → chunk-LNPYTNMG.js} +8 -4
  84. package/{chunk-BLJWCTRL.js → chunk-LVITW736.js} +1 -1
  85. package/chunk-LYS4T7MY.js +7600 -0
  86. package/{chunk-76WEAXJB.js → chunk-M3LRSBOX.js} +18 -15
  87. package/{chunk-7S4YWN7P.js → chunk-MX574M24.js} +1 -1
  88. package/{chunk-FZGV4FGK.js → chunk-NUHHBEJC.js} +378 -187
  89. package/{chunk-53HEEOTT.js → chunk-O26PCYLS.js} +80 -13
  90. package/{chunk-3DII57IT.js → chunk-O2OWEFII.js} +1 -1
  91. package/chunk-OCZKATRC.js +129 -0
  92. package/{chunk-6D6VBVEW.js → chunk-OTEMQQZI.js} +80 -14
  93. package/chunk-P6GMCCAT.js +870 -0
  94. package/{chunk-CPH3W5A7.js → chunk-Q4GP72HX.js} +94 -3
  95. package/{chunk-A6G32FNX.js → chunk-QYFBT4CV.js} +13 -13
  96. package/{chunk-Z77CRGTW.js → chunk-R4SQ3LGW.js} +1 -1
  97. package/{chunk-DEUUPHOO.js → chunk-RKGKDQGJ.js} +74 -17
  98. package/{chunk-ZXKVPF4K.js → chunk-RQNHAVSR.js} +236 -36
  99. package/{chunk-LLT642J4.js → chunk-RS4XOX6Y.js} +24 -5
  100. package/{chunk-V4MJDUSR.js → chunk-RSEEDUMS.js} +2 -2
  101. package/{chunk-UZGQNTVW.js → chunk-S5XGT6GB.js} +5 -3
  102. package/{chunk-AFUORTY4.js → chunk-SONWNI3L.js} +21 -21
  103. package/{chunk-BYMV6QZG.js → chunk-TNIX77YM.js} +4 -0
  104. package/{chunk-OF7AQZUG.js → chunk-TU5NE4U3.js} +9 -84
  105. package/chunk-TY3TIUJK.js +89 -0
  106. package/chunk-UNYJU5L6.js +780 -0
  107. package/{chunk-J4MOO56S.js → chunk-UQNS32WZ.js} +10 -2
  108. package/chunk-VIWDGTDA.js +8 -0
  109. package/chunk-VJVNU77E.js +83 -0
  110. package/{chunk-JAXOVNM4.js → chunk-WILHZY7K.js} +45 -45
  111. package/{chunk-BGSLKVCP.js → chunk-WIU4KIBL.js} +6 -7
  112. package/{chunk-UKWGR5SS.js → chunk-WIWM4FE3.js} +187 -398
  113. package/{chunk-O6OSWFZQ.js → chunk-XUWRURDF.js} +6 -0
  114. package/{chunk-Q67DOFOO.js → chunk-Y3PMXGLH.js} +2 -0
  115. package/{chunk-SH43IESU.js → chunk-YUNJN43V.js} +44 -9
  116. package/{chunk-TOP2VXOR.js → chunk-Z4CSIXYP.js} +2 -2
  117. package/{chunk-2F7RJC6L.js → chunk-ZOVKKMF6.js} +1 -1
  118. package/chunk-ZRAU6T47.js +56 -0
  119. package/commandRegistry-ESFYIRF4.js +833 -0
  120. package/{contentThunks-PT23JWJX.js → contentThunks-ECQ6KK3I.js} +32 -30
  121. package/{cooldownCommands-REAWYVTY.js → cooldownCommands-ZLEPIB4A.js} +2 -2
  122. package/{createAgentAutomationAction-N27SYTLU.js → createAgentAutomationAction-6EES5YQO.js} +32 -30
  123. package/{createDialogAction-XZPLHD5G.js → createDialogAction-JTKMM4VG.js} +36 -33
  124. package/{createPageAction-KHVJQ3CS.js → createPageAction-WQZTMGAG.js} +38 -36
  125. package/{chunk-3SJQXXGY.js → cursorProvider-YGGNMVWX.js} +2560 -9879
  126. package/{dbSlice-XVWBAGYN.js → dbSlice-DQ32LYTJ.js} +8 -8
  127. package/{deleteFile-YG6QMJLU.js → deleteFile-NX6QHCWZ.js} +3 -3
  128. package/{dialogCommands-ZUWW5UT6.js → dialogCommands-XXZH5K6U.js} +45 -41
  129. package/{dialogSlice-3YH242HS.js → dialogSlice-I6GN3I5B.js} +36 -29
  130. package/{dist-VODFSGNG.js → dist-NJC2W7I4.js} +61 -54
  131. package/{docCreateCommands-Q6FADDSJ.js → docCreateCommands-FLNUDWG6.js} +44 -40
  132. package/{docDeleteCommands-ZKIH54PZ.js → docDeleteCommands-74OURFAB.js} +44 -40
  133. package/{docReadCommands-7BZT2QTW.js → docReadCommands-QENWDQVH.js} +43 -39
  134. package/{docStore-YSZRNUUD.js → docStore-B2ZM4PCR.js} +11 -10
  135. package/{docUpdateCommands-WJXWTRL7.js → docUpdateCommands-J4HWJ5JO.js} +44 -40
  136. package/{fetchMessages-EIU7UFFK.js → fetchMessages-67MEFPZR.js} +2 -2
  137. package/{getPricing-LUSEABA6.js → getPricing-NMMFT3YI.js} +3 -3
  138. package/{handleSendMessageAction-KJO2QDBM.js → handleSendMessageAction-BAUWHASB.js} +91 -83
  139. package/index.js +87 -884
  140. package/{localDialogRead-BTFJ4V2I.js → localDialogRead-EBRS242U.js} +2 -2
  141. package/{localRuntimeAuthority-6IR6BBXE.js → localRuntimeAuthority-5W6IJRAD.js} +6 -6
  142. package/{localRuntimeDb-SYQGUF4U.js → localRuntimeDb-3LRMNLCM.js} +1 -1
  143. package/{machineCommands-QC4TD7GJ.js → machineCommands-SG3QGVOP.js} +84 -77
  144. package/{machineWsRunDispatch-XUOIAXO7.js → machineWsRunDispatch-RTFT3ZDL.js} +81 -74
  145. package/{memberThunks-QGFLFVCI.js → memberThunks-5ZXPR63F.js} +9 -9
  146. package/{models-T3SG6MJ5.js → models-ZPU5EDF4.js} +2 -2
  147. package/oauthTokenStore-ITEB663N.js +23 -0
  148. package/package.json +1 -1
  149. package/pdf-U6KSUEZZ.js +26435 -0
  150. package/processSpawn-SOAV3FEV.js +11 -0
  151. package/profileConfig-ZGOFORWV.js +43 -0
  152. package/{providerPresetApply-FG6NZ57W.js → providerPresetApply-DD6NGWW6.js} +7 -7
  153. package/{providerRegistry-757OWH3O.js → providerRegistry-XDRLMYGJ.js} +7 -7
  154. package/{read-COE3ZYR6.js → read-EPTJRAEF.js} +5 -5
  155. package/{readDocTool-5USN4A6V.js → readDocTool-W4NDXNEX.js} +5 -3
  156. package/{readlineWorkspace-74TXXSLO.js → readlineWorkspace-MCNBLA56.js} +2449 -2022
  157. package/{removeDialogAgentAction-IX3MN2ZO.js → removeDialogAgentAction-BVAWQKXE.js} +17 -19
  158. package/{runAgentClientLoop-37BXJD62.js → runAgentClientLoop-XDPBFXV2.js} +61 -58
  159. package/{runtimeDoctorCommands-X6WDBEQX.js → runtimeDoctorCommands-3USD722U.js} +3 -3
  160. package/runtimeModeArgs-2Y7BALTO.js +31 -0
  161. package/{setDialogExtraReferencesAction-X4HCPNZL.js → setDialogExtraReferencesAction-LYY45IAD.js} +12 -11
  162. package/{setPrimaryDialogAgentAction-4GMIQLOD.js → setPrimaryDialogAgentAction-73IL7DLU.js} +18 -20
  163. package/{settingSlice-ZQZVUPKK.js → settingSlice-Q6EKL7EQ.js} +9 -9
  164. package/{skillDiscovery-CYUCJMAG.js → skillDiscovery-ZBU76COE.js} +3 -3
  165. package/{spaceCommands-P3ONT6LL.js → spaceCommands-BYDGOMW7.js} +44 -40
  166. package/{streamAgentChatTurn-FGXQXALU.js → streamAgentChatTurn-BBH3QDEZ.js} +183 -91
  167. package/{switchDialogAgentAction-N52LRPA3.js → switchDialogAgentAction-UUXDSQ6X.js} +15 -17
  168. package/{tableCommands-O6NWHFKV.js → tableCommands-G7RV3RU3.js} +4 -4
  169. package/{toolApiClient-QVJ6HDNN.js → toolApiClient-INIQCPGY.js} +3 -3
  170. package/{tools-R5UF2KZO.js → tools-OQWSBQJA.js} +54 -51
  171. package/{tuiSummaryLlmCaller-T2SHYMDZ.js → tuiSummaryLlmCaller-74NRRLVW.js} +18 -16
  172. package/{updateCommands-2M74UL7P.js → updateCommands-4EHDLF5J.js} +3 -3
  173. package/{updateDialogTitleAction-RTADGV7A.js → updateDialogTitleAction-E25IG3J3.js} +81 -43
  174. package/agentRecordCommands-SIPURU2S.js +0 -128
  175. package/chunk-FOWEGIMF.js +0 -18881
  176. package/chunk-M76ECQRD.js +0 -13658
  177. package/chunk-Q5FJJ6XI.js +0 -103
  178. package/chunk-S7Z2HMCN.js +0 -25
  179. package/{chunk-VMFTFOWF.js → chunk-3AH7LNUB.js} +7 -7
  180. package/{chunk-X7HHHIOZ.js → chunk-Y6ROFCZO.js} +0 -0
  181. 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,
@@ -26,51 +26,76 @@ import {
26
26
  resolveFileWriteGateEnabled,
27
27
  resolveLocalUserId,
28
28
  t,
29
- toolLabel
30
- } from "./chunk-3SJQXXGY.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-LYS4T7MY.js";
39
32
  import {
40
33
  clearCredentialAvailability,
41
34
  readCredentialEntry,
42
- recordCredentialProbe,
43
- resolveCredentialKeyWithFallback
44
- } from "./chunk-42V6BK2E.js";
35
+ recordCredentialProbe
36
+ } from "./chunk-62IL3KQV.js";
45
37
  import {
46
38
  getReadableCliDb
47
- } from "./chunk-LS2ZANRJ.js";
39
+ } from "./chunk-CTUQJVQM.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";
54
+ import {
55
+ resolveMachineId
56
+ } from "./chunk-ESHYE7WU.js";
48
57
  import {
49
58
  readDbRecord,
50
59
  resolveAgentRecordFromHybridStore
51
- } from "./chunk-76WEAXJB.js";
60
+ } from "./chunk-M3LRSBOX.js";
52
61
  import {
53
62
  isLocalCliAgentKey
54
63
  } from "./chunk-SV5IJK6K.js";
64
+ import {
65
+ extractGoogleValidationLink
66
+ } from "./chunk-BMQ2MJUK.js";
67
+ import {
68
+ createRunActivityTracker,
69
+ popSingleQueueMessage,
70
+ readRunRecord,
71
+ resolveRunQueuePath,
72
+ settleRunTerminalAuthoritatively,
73
+ spawnLocalBackgroundRun
74
+ } from "./chunk-Q4GP72HX.js";
75
+ import {
76
+ isCliAuthorityBrokerProtocolError,
77
+ isCliAuthorityBrokerTimeoutError,
78
+ isCliAuthorityBrokerUnavailableError
79
+ } from "./chunk-EXAJ6DCR.js";
80
+ import {
81
+ getDefaultCliLocalRuntimeDb
82
+ } from "./chunk-ZOVKKMF6.js";
55
83
  import {
56
84
  CliProviderQuotaError
57
85
  } from "./chunk-MP64VFGD.js";
58
- import {
59
- resolveMachineId
60
- } from "./chunk-ESHYE7WU.js";
61
86
  import {
62
87
  applyModelLayerOverride,
63
88
  buildModelLayerOverride
64
89
  } from "./chunk-LTRXGFMS.js";
65
90
  import {
66
91
  formatAgentListCard
67
- } from "./chunk-MMPXJXHT.js";
68
- import {
69
- isTransientFetchError
70
- } from "./chunk-5UTFL4QJ.js";
92
+ } from "./chunk-HZH7RULB.js";
71
93
  import {
72
94
  isGatewayHttpStatus
73
95
  } from "./chunk-NF64D32W.js";
96
+ import {
97
+ isTransientFetchError
98
+ } from "./chunk-5UTFL4QJ.js";
74
99
  import {
75
100
  formatFinishedRunCard,
76
101
  formatListRunsCard,
@@ -79,43 +104,35 @@ import {
79
104
  formatStatusRunCard,
80
105
  formatStopRunCard,
81
106
  isAgentRunTerminalStatus
82
- } from "./chunk-NTW5GWDM.js";
107
+ } from "./chunk-I3QNET24.js";
83
108
  import {
84
109
  buildMemorySubjectsForAgent,
85
110
  chooseMemoryOwners,
86
111
  loadMemoryCandidatesFromDb,
87
112
  resolveAgentMemoryPolicy
88
- } from "./chunk-AFDS2CVM.js";
113
+ } from "./chunk-K5UOP7AI.js";
89
114
  import {
90
115
  API_REPORTED_COST_MULTIPLIER,
91
116
  parseUiAskChoiceContent
92
- } from "./chunk-FOWEGIMF.js";
117
+ } from "./chunk-2QZTQEW4.js";
93
118
  import {
94
119
  isOAuthApiKeyRef
95
120
  } from "./chunk-YYLHWIW6.js";
96
- import {
97
- isCliAuthorityBrokerProtocolError,
98
- isCliAuthorityBrokerTimeoutError,
99
- isCliAuthorityBrokerUnavailableError
100
- } from "./chunk-TRV2MIDW.js";
101
- import {
102
- getDefaultCliLocalRuntimeDb
103
- } from "./chunk-2F7RJC6L.js";
104
121
  import {
105
122
  buildSkillDiscoveryContextLayer
106
- } from "./chunk-E4MARS3Q.js";
123
+ } from "./chunk-5GVBDNTO.js";
107
124
  import {
108
125
  parseExternalSkillMarkdown,
109
126
  parseSkillDocProtocol
110
- } from "./chunk-Q554LLSI.js";
127
+ } from "./chunk-AUDNYVRC.js";
111
128
  import {
112
129
  LOCAL_AGENT_CONFIG_MISSING_CODE,
113
130
  LOCAL_TURN_ABORTED_CODE,
114
131
  readActionGate
115
- } from "./chunk-4MY4GLIW.js";
132
+ } from "./chunk-6IHBIRPK.js";
116
133
  import {
117
134
  resolveAgentRuntimeConfigFromRecord
118
- } from "./chunk-3IIEFNGY.js";
135
+ } from "./chunk-C53ZG23R.js";
119
136
  import {
120
137
  createThinkParserState,
121
138
  flushThinkParser,
@@ -126,57 +143,62 @@ import {
126
143
  isQuotaExhaustedError,
127
144
  isQuotaLimited403Body,
128
145
  mergeAvailabilityDeadline,
129
- resolveCooldownGate
130
- } from "./chunk-FDTR4QJ6.js";
146
+ resolveCooldownGate,
147
+ resolveCredentialKeyWithFallback
148
+ } from "./chunk-H6A6X4EK.js";
131
149
  import {
132
150
  isAntigravityOAuthAgent
133
- } from "./chunk-UZGQNTVW.js";
151
+ } from "./chunk-S5XGT6GB.js";
134
152
  import {
135
153
  resolveClientVersion
136
- } from "./chunk-6OZ36FXI.js";
154
+ } from "./chunk-27ONFIEY.js";
137
155
  import {
138
156
  DEFAULT_CONTEXT_WINDOW,
139
157
  getModelContextWindow,
140
158
  normalizeUsage
141
- } from "./chunk-JAXOVNM4.js";
159
+ } from "./chunk-WILHZY7K.js";
142
160
  import {
143
161
  clipCompactText
144
- } from "./chunk-WADCY6G6.js";
145
- import {
146
- findModelConfig
147
- } from "./chunk-OIVSQH2O.js";
162
+ } from "./chunk-5MMAK75Q.js";
148
163
  import {
149
164
  compactWhitespace
150
165
  } from "./chunk-DWLEOOGR.js";
151
166
  import {
152
167
  toErrorMessage
153
168
  } from "./chunk-HNMXYYJR.js";
169
+ import {
170
+ findModelConfig
171
+ } from "./chunk-3BXNTXYI.js";
154
172
  import {
155
173
  buildAgentsMdLayer,
156
174
  buildMemoryOverlayLayer,
157
175
  buildMemoryUseGuidanceLayer,
158
176
  partitionScopedBlocks,
159
177
  renderTurnContextBlocksWithScope
160
- } from "./chunk-DVINR3PL.js";
178
+ } from "./chunk-HDLLCBRF.js";
161
179
  import {
162
- readPipeText,
163
- spawnProcess
164
- } from "./chunk-X7HHHIOZ.js";
180
+ getLogger,
181
+ normalizeError
182
+ } from "./chunk-UNYJU5L6.js";
165
183
  import {
166
184
  resolveAuthToken
167
185
  } from "./chunk-A7GB5UGH.js";
186
+ import {
187
+ readPipeText,
188
+ spawnProcess
189
+ } from "./chunk-Y6ROFCZO.js";
168
190
  import {
169
191
  CLIENT_VERSION_TOO_OLD_CODE,
170
192
  NOLO_CLIENT_VERSION_HEADER,
171
193
  buildClientVersionUpgradeMessage
172
- } from "./chunk-Q67DOFOO.js";
194
+ } from "./chunk-Y3PMXGLH.js";
173
195
  import {
174
196
  parsePositiveFiniteNumberOrFallback
175
197
  } from "./chunk-Y5GCAMGP.js";
176
198
  import {
177
199
  createMemoryKey,
178
200
  ulid
179
- } from "./chunk-VMFTFOWF.js";
201
+ } from "./chunk-3AH7LNUB.js";
180
202
  import {
181
203
  asTrimmedLowercaseString
182
204
  } from "./chunk-QSJ3HFEF.js";
@@ -188,9 +210,6 @@ import {
188
210
  import {
189
211
  parsePublicAgentId
190
212
  } from "./chunk-M2EJHDJP.js";
191
- import {
192
- isLevelNotFoundError
193
- } from "./chunk-OW765XBU.js";
194
213
  import {
195
214
  asTrimmedString
196
215
  } from "./chunk-3EUW3WEO.js";
@@ -386,6 +405,24 @@ function styleCliText(text, style, enabled = resolveCliColorEnabled()) {
386
405
  function dimCliText(text, enabled = resolveCliColorEnabled()) {
387
406
  return styleCliText(text, "dim", enabled);
388
407
  }
408
+ var OSC8_OPEN = "\x1B]8;;";
409
+ var OSC8_CLOSE = "\x1B\\";
410
+ function sanitizeHyperlinkLabel(label) {
411
+ return label.replace(/[\u0000-\u001f\u007f]/g, "");
412
+ }
413
+ function resolveCliHyperlinkEnabled(env = process.env, isTTY = Boolean(process.stdout.isTTY)) {
414
+ const setting = asTrimmedLowercaseString(env.NOLO_CLI_HYPERLINKS);
415
+ if (setting === "0" || setting === "false" || setting === "off") return false;
416
+ if (setting === "1" || setting === "true" || setting === "on") return true;
417
+ return isTTY;
418
+ }
419
+ function formatCliHyperlink(url, label, enabled = resolveCliHyperlinkEnabled()) {
420
+ if (!url) return label;
421
+ const safeLabel = sanitizeHyperlinkLabel(label);
422
+ if (!enabled) return `${safeLabel} (${url})`;
423
+ if (!safeLabel) return url;
424
+ return `${OSC8_OPEN}${url}${OSC8_CLOSE}${safeLabel}${OSC8_OPEN}${OSC8_CLOSE}`;
425
+ }
389
426
 
390
427
  // node_modules/ansi-regex/index.js
391
428
  function ansiRegex({ onlyFirst = false } = {}) {
@@ -620,8 +657,12 @@ function stringWidth(input, options = {}) {
620
657
 
621
658
  // packages/cli/tui/tuiAnsi.ts
622
659
  var ANSI_ESCAPE_REGEX = /\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]/g;
660
+ var OSC8_HYPERLINK_REGEX = /\x1b\]8;;[^\x1b]*\x1b\\/g;
623
661
  var ALL_ANSI_ESCAPE_REGEX = ansiRegex();
624
662
  var FIRST_ANSI_ESCAPE_REGEX = ansiRegex({ onlyFirst: true });
663
+ function stripOsc8Hyperlinks(text) {
664
+ return text.replace(OSC8_HYPERLINK_REGEX, "");
665
+ }
625
666
  function stripAnsi2(text) {
626
667
  return text.replace(ANSI_ESCAPE_REGEX, "").replace(ALL_ANSI_ESCAPE_REGEX, "");
627
668
  }
@@ -783,6 +824,7 @@ function visibleWidth(str) {
783
824
  }
784
825
  function truncateAnsi(text, maxWidth) {
785
826
  if (maxWidth <= 0) return "";
827
+ text = stripOsc8Hyperlinks(text);
786
828
  if (visibleWidth(text) <= maxWidth) return text;
787
829
  let width = 0;
788
830
  let out = "";
@@ -823,7 +865,7 @@ function countPhysicalLines(text, columns) {
823
865
  const lines = text.split("\n");
824
866
  let total = 0;
825
867
  for (const line of lines) {
826
- const width = displayWidth(line);
868
+ const width = visibleWidth(stripOsc8Hyperlinks(line));
827
869
  total += Math.max(1, Math.ceil(width / columns));
828
870
  }
829
871
  return Math.max(total, 1);
@@ -8180,7 +8222,12 @@ function emitPlainGap(text, keywords, info, accent, warning, reset) {
8180
8222
  var UNORDERED_LIST_RE = /^(\s*)([-*+])\s+(.+)$/;
8181
8223
  var ORDERED_LIST_RE = /^(\s*)(\d+)\.\s+(.+)$/;
8182
8224
  var TASK_LIST_RE = /^(\s*)([-*+])\s+\[([ xX])\]\s+(.+)$/;
8225
+ var THEMATIC_BREAK_PATTERN = "(?:(-[ \\t]*){3,}|(\\*[ \\t]*){3,}|(_[ \\t]*){3,})";
8226
+ var THEMATIC_BREAK_RE = new RegExp(`^[ ]{0,3}${THEMATIC_BREAK_PATTERN}$`);
8183
8227
  function normalizeListLine(line) {
8228
+ if (THEMATIC_BREAK_RE.test(line)) {
8229
+ return line;
8230
+ }
8184
8231
  const task = line.match(TASK_LIST_RE);
8185
8232
  if (task) {
8186
8233
  const checked = task[3] === "x" || task[3] === "X";
@@ -8196,12 +8243,99 @@ function normalizeListLine(line) {
8196
8243
  }
8197
8244
  return line;
8198
8245
  }
8246
+ var TOOL_TREE_HEADER_RE = /^•\s+(.+?)\s+\((\d+)\)$/;
8247
+ var TOOL_TREE_LEAF_RE = /^([├└]──\s+)(.*?)\s{2}(✓|✗|!)(?:\s+(.*))?$/;
8248
+ var TOOL_SINGLE_RE = /^▸\s+(.+?)(?:\s+·\s+(.*?))?(?:\s{2}(✓|✗|!)(?:\s+(.*))?)$/;
8249
+ function plainToolLine(line) {
8250
+ return stripAnsi2(line);
8251
+ }
8252
+ var TOOL_TREE_GROUP_LABELS = new Set(
8253
+ ["execShell", "readFile", "fetchWebpage", "exa_search"].flatMap(toolLabelVariants)
8254
+ );
8255
+ function isKnownToolGroupLabel(label) {
8256
+ return TOOL_TREE_GROUP_LABELS.has(label);
8257
+ }
8258
+ function toolTreeHeaderMatch(line) {
8259
+ const match = plainToolLine(line).match(TOOL_TREE_HEADER_RE);
8260
+ return match && isKnownToolGroupLabel(match[1]) ? match : null;
8261
+ }
8262
+ function isToolTreeHeaderLine(line) {
8263
+ return toolTreeHeaderMatch(line) !== null;
8264
+ }
8265
+ function isToolTreeLeafLine(line) {
8266
+ return TOOL_TREE_LEAF_RE.test(plainToolLine(line));
8267
+ }
8268
+ function isToolSingleLine(line) {
8269
+ return TOOL_SINGLE_RE.test(plainToolLine(line));
8270
+ }
8271
+ function isToolGroupBoundary(cur, next) {
8272
+ return isToolTreeLeafLine(cur) && isToolTreeHeaderLine(next);
8273
+ }
8274
+ function statusColorSeq(marker, brightness) {
8275
+ if (marker === "\u2713") return colorSeq("success", brightness);
8276
+ if (marker === "\u2717") return colorSeq("danger", brightness);
8277
+ return colorSeq("warning", brightness);
8278
+ }
8279
+ function styleTuiToolLine(line, brightness) {
8280
+ const plain = plainToolLine(line);
8281
+ const chrome = colorSeq("chrome", brightness);
8282
+ const muted = colorSeq("muted", brightness);
8283
+ const header = toolTreeHeaderMatch(plain);
8284
+ if (header) {
8285
+ return `${chrome}\u2022${STYLE.reset} ${STYLE.bold}${muted}${header[1]}${STYLE.reset} ${chrome}${STYLE.dim}(${header[2]})${STYLE.reset}`;
8286
+ }
8287
+ const leaf = plain.match(TOOL_TREE_LEAF_RE);
8288
+ if (leaf) {
8289
+ const [, connector, detail, marker, statusDetail] = leaf;
8290
+ let rendered = `${chrome}${connector}${STYLE.reset}${chrome}${detail}${STYLE.reset}`;
8291
+ rendered += ` ${statusColorSeq(marker, brightness)}${marker}${STYLE.reset}`;
8292
+ if (statusDetail) {
8293
+ const metaSeq = marker === "\u2713" ? chrome : statusColorSeq(marker, brightness);
8294
+ rendered += ` ${metaSeq}${STYLE.dim}${statusDetail}${STYLE.reset}`;
8295
+ }
8296
+ return rendered;
8297
+ }
8298
+ const single = plain.match(TOOL_SINGLE_RE);
8299
+ if (single) {
8300
+ const [, label, detail, marker, statusDetail] = single;
8301
+ let rendered = `${chrome}\u25B8${STYLE.reset} ${STYLE.bold}${muted}${label}${STYLE.reset}`;
8302
+ if (detail) rendered += ` ${chrome}\xB7 ${detail}${STYLE.reset}`;
8303
+ rendered += ` ${statusColorSeq(marker, brightness)}${marker}${STYLE.reset}`;
8304
+ if (statusDetail) {
8305
+ const metaSeq = marker === "\u2713" ? chrome : statusColorSeq(marker, brightness);
8306
+ rendered += ` ${metaSeq}${STYLE.dim}${statusDetail}${STYLE.reset}`;
8307
+ }
8308
+ return rendered;
8309
+ }
8310
+ return null;
8311
+ }
8199
8312
  function isPolishListLikeLine(line) {
8200
- return LIST_LIKE_RE_FOR_GUARD.test(normalizeListLine(line));
8313
+ return LIST_LIKE_RE_FOR_GUARD.test(normalizeListLine(plainToolLine(line)));
8314
+ }
8315
+ var LIST_LIKE_RE_FOR_GUARD = /^\s*(?:•|◦|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s|^\s*▸\s/;
8316
+ function isPolishFenceInteriorLine(line) {
8317
+ return /^\x00F\d+\x00$/.test(line);
8318
+ }
8319
+ function polishHeadingLevel(line) {
8320
+ const match = stripAnsi2(line).match(/^(#{1,6})\s/);
8321
+ return match ? match[1].length : null;
8322
+ }
8323
+ function isPolishHeadingLine(line) {
8324
+ return polishHeadingLevel(line) !== null;
8325
+ }
8326
+ function isPolishIntroLine(line) {
8327
+ const plain = stripAnsi2(line).trimEnd();
8328
+ return plain.endsWith("\uFF1A") || plain.endsWith(":");
8201
8329
  }
8202
- var LIST_LIKE_RE_FOR_GUARD = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
8203
8330
  function polishBreathInsertsBlankBetween(cur, next) {
8204
8331
  if (cur === "" || next === "") return false;
8332
+ if (isPolishFenceInteriorLine(cur) || isPolishFenceInteriorLine(next)) {
8333
+ return false;
8334
+ }
8335
+ if (isPolishIntroLine(cur) && isPolishListLikeLine(next)) return false;
8336
+ if (isPolishHeadingLine(cur) || isPolishHeadingLine(next)) return false;
8337
+ if (isCodeFenceLine(cur) !== isCodeFenceLine(next)) return true;
8338
+ if (isToolGroupBoundary(cur, next)) return true;
8205
8339
  return isPolishListLikeLine(cur) !== isPolishListLikeLine(next);
8206
8340
  }
8207
8341
  function convertMarkdownTablesForTerminal(text) {
@@ -8270,17 +8404,15 @@ function polishAssistantStructure(text, options = {}) {
8270
8404
  }
8271
8405
  return line;
8272
8406
  });
8273
- 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");
8274
- const LIST_LIKE = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
8407
+ 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");
8275
8408
  const headingLines = afterHeading.split("\n");
8276
8409
  const breathed = [];
8277
8410
  for (let i = 0; i < headingLines.length; i++) {
8278
8411
  breathed.push(headingLines[i]);
8279
8412
  const cur = headingLines[i];
8280
8413
  const next = headingLines[i + 1];
8281
- if (cur === "" || next === void 0 || next === "") continue;
8282
- if (LIST_LIKE.test(cur) === LIST_LIKE.test(next)) continue;
8283
- breathed.push("");
8414
+ if (next === void 0) continue;
8415
+ if (polishBreathInsertsBlankBetween(cur, next)) breathed.push("");
8284
8416
  }
8285
8417
  const polishedMasked = breathed.join("\n");
8286
8418
  const polished = polishedMasked.replace(
@@ -8290,17 +8422,23 @@ function polishAssistantStructure(text, options = {}) {
8290
8422
  return options.trimEdges === false ? polished : polished.trim();
8291
8423
  }
8292
8424
  function styleRichMarkdownLine(line, brightness) {
8293
- const heading = line.match(/^(#{1,3})\s+(.+)$/);
8425
+ const toolLine = styleTuiToolLine(line, brightness);
8426
+ if (toolLine !== null) return toolLine;
8427
+ const heading = line.match(/^(#{1,6})\s+(.+)$/);
8294
8428
  if (heading) {
8295
8429
  const level = heading[1].length;
8296
8430
  const title = heading[2];
8431
+ const styledTitle = styleInlineMarkdown(title, brightness);
8297
8432
  if (level === 1) {
8298
- return `${STYLE.bold}\x1B[4m${colorSeq("accent", brightness)}${title}${STYLE.reset}`;
8433
+ return `${STYLE.bold}${colorSeq("accent", brightness)}${styledTitle}${STYLE.reset}`;
8299
8434
  }
8300
8435
  if (level === 2) {
8301
- return `${STYLE.bold}${colorSeq("warning", brightness)}${title}${STYLE.reset}`;
8436
+ return `${STYLE.bold}${colorSeq("warning", brightness)}${styledTitle}${STYLE.reset}`;
8302
8437
  }
8303
- return `${STYLE.bold}${colorSeq("info", brightness)}${title}${STYLE.reset}`;
8438
+ if (level === 3) {
8439
+ return `${STYLE.bold}${colorSeq("info", brightness)}${styledTitle}${STYLE.reset}`;
8440
+ }
8441
+ return `${STYLE.bold}${colorSeq("muted", brightness)}${styledTitle}${STYLE.reset}`;
8304
8442
  }
8305
8443
  if (line.startsWith("\u8FDB\u5165 nolo-plan")) {
8306
8444
  return `${colorSeq("chrome", brightness)}${STYLE.dim}${line}${STYLE.reset}`;
@@ -8309,15 +8447,19 @@ function styleRichMarkdownLine(line, brightness) {
8309
8447
  if (blockquote) {
8310
8448
  const border = colorSeq("chrome", brightness);
8311
8449
  const content = blockquote[1];
8312
- return `${border}\u2502${STYLE.reset} ${STYLE.dim}${content}${STYLE.reset}`;
8450
+ const styled = styleInlineMarkdown(content, brightness);
8451
+ return `${border}\u2502${STYLE.reset} ${STYLE.dim}${styled}${STYLE.reset}`;
8313
8452
  }
8314
- if (/^---+$/.test(line.trim())) {
8315
- return `${colorSeq("chrome", brightness)}${"\u2500".repeat(Math.min(line.trim().length, 40))}${STYLE.reset}`;
8453
+ if (THEMATIC_BREAK_RE.test(line)) {
8454
+ return `${colorSeq("chrome", brightness)}${STYLE.dim}${"\u2500".repeat(36)}${STYLE.reset}`;
8316
8455
  }
8317
8456
  const bullet = line.match(/^(\s*)(•)\s(.+)$/);
8318
8457
  if (bullet) {
8458
+ const indent = bullet[1];
8319
8459
  const styled = styleInlineMarkdown(bullet[3], brightness);
8320
- return `${bullet[1]}${colorSeq("accent", brightness)}\u2022${STYLE.reset} ${styled}`;
8460
+ const marker = indent.length >= 2 ? "\u25E6" : "\u2022";
8461
+ const markerColor = indent.length >= 2 ? colorSeq("chrome", brightness) : colorSeq("accent", brightness);
8462
+ return `${indent}${markerColor}${marker}${STYLE.reset} ${styled}`;
8321
8463
  }
8322
8464
  const ordered = line.match(/^(\s*)(\d+\.)\s(.+)$/);
8323
8465
  if (ordered) {
@@ -8441,16 +8583,28 @@ function emitFormattedAssistantBlock(write, text, trailingNewline = false) {
8441
8583
  }
8442
8584
  function classifyStreamLine(line) {
8443
8585
  if (line === "") return "blank";
8444
- 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)) {
8586
+ const plain = plainToolLine(line);
8587
+ if (isToolTreeHeaderLine(plain)) return "tool-header";
8588
+ if (isToolTreeLeafLine(plain)) return "tool-leaf";
8589
+ if (isToolSingleLine(plain)) return "tool";
8590
+ 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)) {
8445
8591
  return "list";
8446
8592
  }
8593
+ if (isPolishListLikeLine(plain)) return "list";
8594
+ if (polishHeadingLevel(plain) !== null) return "heading";
8447
8595
  return "prose";
8448
8596
  }
8449
- function needsListProseBreath(prev, next) {
8597
+ function isStreamListLike(kind) {
8598
+ return kind === "list" || kind === "tool-header" || kind === "tool-leaf" || kind === "tool";
8599
+ }
8600
+ function needsListProseBreath(prev, next, prevLine = "") {
8450
8601
  if (prev === null || prev === "blank" || next === "blank") return false;
8451
- const prevList = prev === "list";
8452
- const nextList = next === "list";
8453
- return prevList !== nextList;
8602
+ if (next === "heading") return true;
8603
+ if (prev === "heading") return (polishHeadingLevel(prevLine) ?? 7) <= 2;
8604
+ if (prev === "fence" !== (next === "fence")) return true;
8605
+ if (isStreamListLike(next) && isPolishIntroLine(prevLine)) return false;
8606
+ if (prev === "tool-leaf" && next === "tool-header") return true;
8607
+ return isStreamListLike(prev) !== isStreamListLike(next);
8454
8608
  }
8455
8609
  function createRenderAwareStreamWriter(args) {
8456
8610
  const brightness = resolveTuiBrightness();
@@ -8460,9 +8614,16 @@ function createRenderAwareStreamWriter(args) {
8460
8614
  let inMermaid = false;
8461
8615
  let mermaidBody = [];
8462
8616
  let lastKind = null;
8617
+ let lastLine = "";
8618
+ let pendingBlankRow = false;
8463
8619
  const PARTIAL_FLUSH_THRESHOLD = 48;
8464
8620
  const emitBreathIfNeeded = (nextKind) => {
8465
- if (needsListProseBreath(lastKind, nextKind)) args.write("\n");
8621
+ if (pendingBlankRow) {
8622
+ args.write("\n");
8623
+ pendingBlankRow = false;
8624
+ lastKind = "blank";
8625
+ }
8626
+ if (needsListProseBreath(lastKind, nextKind, lastLine)) args.write("\n");
8466
8627
  };
8467
8628
  const flushPartialProse = () => {
8468
8629
  if (inFence || buffer.length < PARTIAL_FLUSH_THRESHOLD) return;
@@ -8480,6 +8641,7 @@ function createRenderAwareStreamWriter(args) {
8480
8641
  emitBreathIfNeeded("prose");
8481
8642
  emitFormattedAssistantBlock(args.write, prefix, false);
8482
8643
  lastKind = "prose";
8644
+ lastLine = prefix;
8483
8645
  buffer = prefix.length === buffer.length ? "" : buffer.slice(prefix.length);
8484
8646
  };
8485
8647
  const flushCompleteBlocks = () => {
@@ -8495,10 +8657,11 @@ function createRenderAwareStreamWriter(args) {
8495
8657
  inMermaid = false;
8496
8658
  inFence = false;
8497
8659
  fenceLang = "unknown";
8498
- emitBreathIfNeeded("other");
8660
+ emitBreathIfNeeded("fence");
8499
8661
  args.write(`${STYLE.dim}${firstLine}${STYLE.reset}
8500
8662
  `);
8501
- lastKind = "other";
8663
+ lastKind = "fence";
8664
+ lastLine = firstLine;
8502
8665
  buffer = lines.slice(1).join("\n");
8503
8666
  continue;
8504
8667
  }
@@ -8514,10 +8677,11 @@ function createRenderAwareStreamWriter(args) {
8514
8677
  }
8515
8678
  inFence = true;
8516
8679
  }
8517
- emitBreathIfNeeded("other");
8680
+ emitBreathIfNeeded("fence");
8518
8681
  args.write(`${STYLE.dim}${firstLine}${STYLE.reset}
8519
8682
  `);
8520
- lastKind = "other";
8683
+ lastKind = "fence";
8684
+ lastLine = firstLine;
8521
8685
  buffer = lines.slice(1).join("\n");
8522
8686
  continue;
8523
8687
  }
@@ -8529,7 +8693,8 @@ function createRenderAwareStreamWriter(args) {
8529
8693
  if (inFence) {
8530
8694
  args.write(`${highlightCodeLine(firstLine, fenceLang, brightness)}
8531
8695
  `);
8532
- lastKind = "other";
8696
+ lastKind = "fence";
8697
+ lastLine = firstLine;
8533
8698
  buffer = lines.slice(1).join("\n");
8534
8699
  continue;
8535
8700
  }
@@ -8542,6 +8707,7 @@ function createRenderAwareStreamWriter(args) {
8542
8707
  const inner = trimmedFirst.slice(2, trimmedFirst.length - 2);
8543
8708
  args.write(renderMathBlock(inner) + "\n");
8544
8709
  lastKind = "other";
8710
+ lastLine = trimmedFirst;
8545
8711
  buffer = lines.slice(1).join("\n");
8546
8712
  continue;
8547
8713
  }
@@ -8568,6 +8734,7 @@ function createRenderAwareStreamWriter(args) {
8568
8734
  if (lastInner) innerParts.push(lastInner);
8569
8735
  args.write(renderMathBlock(innerParts.join("\n")) + "\n");
8570
8736
  lastKind = "other";
8737
+ lastLine = trimmedFirst;
8571
8738
  buffer = lines.slice(closeIndex + 1).join("\n");
8572
8739
  continue;
8573
8740
  }
@@ -8588,14 +8755,23 @@ function createRenderAwareStreamWriter(args) {
8588
8755
  true
8589
8756
  );
8590
8757
  lastKind = "list";
8758
+ lastLine = lines[end - 1] ?? firstLine;
8591
8759
  buffer = lines.slice(end).join("\n");
8592
8760
  continue;
8593
8761
  }
8594
8762
  }
8595
8763
  const kind = classifyStreamLine(firstLine);
8764
+ if (kind === "blank") {
8765
+ if (lastKind !== null && lastKind !== "blank") pendingBlankRow = true;
8766
+ lastKind = "blank";
8767
+ lastLine = "";
8768
+ buffer = lines.slice(1).join("\n");
8769
+ continue;
8770
+ }
8596
8771
  emitBreathIfNeeded(kind);
8597
8772
  emitFormattedAssistantBlock(args.write, firstLine, true);
8598
8773
  lastKind = kind;
8774
+ lastLine = firstLine;
8599
8775
  buffer = lines.slice(1).join("\n");
8600
8776
  }
8601
8777
  };
@@ -9808,6 +9984,7 @@ ${this.text}
9808
9984
  // packages/cli/client/agentRunOutput.ts
9809
9985
  var IDENTITY_LABEL_SEPARATOR = " > ";
9810
9986
  var THINKING_PREVIEW_BUFFER_LIMIT = 512;
9987
+ var TUI_PROGRESS_BUFFER_LIMIT = 1200;
9811
9988
  function appendThinkingPreview(current, chunk, limit = THINKING_PREVIEW_BUFFER_LIMIT) {
9812
9989
  if (limit <= 0) return "";
9813
9990
  const combined = current + chunk;
@@ -9821,6 +9998,14 @@ function formatCompactionSummaryLine(event) {
9821
9998
  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}
9822
9999
  `;
9823
10000
  }
10001
+ if (event.skipped) {
10002
+ if (event.skipReason === "adapter-missing-summary-methods" || event.skipReason === "load-summary-failed") {
10003
+ 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}
10004
+ `;
10005
+ }
10006
+ return "";
10007
+ }
10008
+ if (!event.summaryGenerated) return "";
9824
10009
  let detail = "\u751F\u6210\u5386\u53F2\u6458\u8981";
9825
10010
  const saved = typeof event.savedTokens === "number" ? event.savedTokens : void 0;
9826
10011
  let line = `\u5DF2\u538B\u7F29\u4E0A\u4E0B\u6587\uFF1A${detail}`;
@@ -9861,6 +10046,14 @@ function formatToolJsonEvent(event) {
9861
10046
  })}
9862
10047
  `;
9863
10048
  }
10049
+ function shouldPromoteTuiNarration(text) {
10050
+ if (text.length >= TUI_PROGRESS_BUFFER_LIMIT) return true;
10051
+ return /(^|\n)\s*(?:#{1,3}\s|```|[-*+]\s|\d+[.)]\s)/.test(text);
10052
+ }
10053
+ function narrationActivityLabel(text) {
10054
+ const oneLine = stripAnsi2(text).replace(/[`*_#>]/g, "").replace(/\s+/g, " ").trim();
10055
+ return truncateThinkingHint(oneLine, 60);
10056
+ }
9864
10057
  function createCliTurnOutput(params) {
9865
10058
  const { options } = params;
9866
10059
  const workingLabel = params.workingLabel ?? `${options.agentName} -> working`;
@@ -9869,14 +10062,36 @@ function createCliTurnOutput(params) {
9869
10062
  tuiTrees: options.output.tuiTrees === true
9870
10063
  });
9871
10064
  const eventMode = resolveAgentEventMode(options);
9872
- const showThinking = options.showThinking !== false;
10065
+ const assistantLabelManaged = options.output.assistantLabelManaged === true;
10066
+ const showThinking = !assistantLabelManaged && options.showThinking !== false;
10067
+ const hidesRoutineTuiToolDetail = (event) => {
10068
+ if (!assistantLabelManaged || event.toolName !== "editFile") return false;
10069
+ if (event.type === "tool-error") return false;
10070
+ if (readActionGate(event.metadata?.actionGate)) return false;
10071
+ if (event.metadata?.timedOut || event.metadata?.failed || event.metadata?.error) return false;
10072
+ if (typeof event.metadata?.exitCode === "number" && event.metadata.exitCode !== 0) return false;
10073
+ return true;
10074
+ };
9873
10075
  let streamedAssistantText = false;
9874
10076
  let everStreamedAnyText = false;
9875
10077
  let printedAssistantLabel = false;
9876
10078
  let thinkState = createThinkParserState();
9877
10079
  let thinkingFirstAt = null;
9878
10080
  let thinkingPreview = "";
10081
+ let tuiThinkingReported = false;
10082
+ const clearTuiThinkingLabel = () => {
10083
+ if (!tuiThinkingReported) return;
10084
+ tuiThinkingReported = false;
10085
+ options.activityReporter?.(null);
10086
+ };
9879
10087
  const markThinkingDelta = (chunk) => {
10088
+ if (assistantLabelManaged) {
10089
+ if (!tuiThinkingReported && !streamedAssistantText) {
10090
+ tuiThinkingReported = true;
10091
+ options.activityReporter?.(t("thinkingActive"));
10092
+ }
10093
+ return;
10094
+ }
9880
10095
  if (!showThinking) return;
9881
10096
  if (streamedAssistantText) return;
9882
10097
  if (thinkingFirstAt === null) {
@@ -9894,6 +10109,7 @@ function createCliTurnOutput(params) {
9894
10109
  options.activityReporter?.(label);
9895
10110
  };
9896
10111
  const endThinkingPhase = () => {
10112
+ clearTuiThinkingLabel();
9897
10113
  if (thinkingFirstAt === null) return;
9898
10114
  const seconds = Math.max(0, Math.round((Date.now() - thinkingFirstAt) / 1e3));
9899
10115
  thinkingFirstAt = null;
@@ -9906,7 +10122,6 @@ function createCliTurnOutput(params) {
9906
10122
  }
9907
10123
  };
9908
10124
  let compactionEvent = null;
9909
- const assistantLabelManaged = options.output.assistantLabelManaged === true;
9910
10125
  const writeToolOutput = (chunk) => {
9911
10126
  if (!chunk) return;
9912
10127
  if (typeof options.output.writeToolBlock === "function") {
@@ -9918,9 +10133,25 @@ function createCliTurnOutput(params) {
9918
10133
  const renderWriter = createRenderAwareStreamWriter({
9919
10134
  write: (chunk) => options.output.write(chunk)
9920
10135
  });
10136
+ let pendingTuiNarration = "";
10137
+ let tuiNarrationPromoted = false;
10138
+ const flushPendingTuiNarration = () => {
10139
+ if (!pendingTuiNarration) return;
10140
+ formatToolEvent.reset?.();
10141
+ renderWriter.push(pendingTuiNarration);
10142
+ pendingTuiNarration = "";
10143
+ tuiNarrationPromoted = true;
10144
+ streamedAssistantText = true;
10145
+ options.activityReporter?.(null);
10146
+ };
10147
+ const dropPendingTuiProgress = () => {
10148
+ pendingTuiNarration = "";
10149
+ tuiNarrationPromoted = false;
10150
+ options.activityReporter?.(null);
10151
+ };
9921
10152
  const writeVisibleAssistantChunk = (chunk) => {
9922
10153
  if (!chunk) return;
9923
- formatToolEvent.reset?.();
10154
+ if (!assistantLabelManaged) formatToolEvent.reset?.();
9924
10155
  const parsed = processThinkChunk(chunk, thinkState);
9925
10156
  thinkState = parsed.state;
9926
10157
  if (!parsed.content && !parsed.reasoning) return;
@@ -9936,8 +10167,23 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
9936
10167
  }
9937
10168
  printedAssistantLabel = true;
9938
10169
  }
9939
- streamedAssistantText = true;
9940
10170
  everStreamedAnyText = true;
10171
+ if (assistantLabelManaged) {
10172
+ if (tuiNarrationPromoted) {
10173
+ renderWriter.push(parsed.content);
10174
+ streamedAssistantText = true;
10175
+ return;
10176
+ }
10177
+ pendingTuiNarration += parsed.content;
10178
+ if (shouldPromoteTuiNarration(pendingTuiNarration)) {
10179
+ flushPendingTuiNarration();
10180
+ } else {
10181
+ const label = narrationActivityLabel(pendingTuiNarration);
10182
+ if (label) options.activityReporter?.(label);
10183
+ }
10184
+ return;
10185
+ }
10186
+ streamedAssistantText = true;
9941
10187
  renderWriter.push(parsed.content);
9942
10188
  };
9943
10189
  const handleToolEvent = (event) => {
@@ -9953,13 +10199,19 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
9953
10199
  return;
9954
10200
  }
9955
10201
  if (event.type === "tool-call") {
10202
+ if (assistantLabelManaged && pendingTuiNarration) {
10203
+ dropPendingTuiProgress();
10204
+ }
9956
10205
  renderWriter.flush();
9957
- formatToolEvent(event);
10206
+ if (!hidesRoutineTuiToolDetail(event)) {
10207
+ formatToolEvent(event);
10208
+ }
9958
10209
  endThinkingPhase();
9959
10210
  if (streamedAssistantText) {
9960
10211
  options.output.write("\n");
9961
10212
  streamedAssistantText = false;
9962
10213
  }
10214
+ if (assistantLabelManaged) tuiNarrationPromoted = false;
9963
10215
  const activeLabel = formatConservativeActiveToolLabel(event);
9964
10216
  spinner.show(activeLabel);
9965
10217
  options.activityReporter?.(activeLabel);
@@ -9971,6 +10223,9 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
9971
10223
  }
9972
10224
  spinner.stop();
9973
10225
  options.activityReporter?.(null);
10226
+ if (hidesRoutineTuiToolDetail(event)) {
10227
+ return;
10228
+ }
9974
10229
  if (isLiveAgentRunObservation(event, parsedRunEvent)) {
9975
10230
  formatToolEvent.consume?.(event);
9976
10231
  return;
@@ -9983,6 +10238,26 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
9983
10238
  return {
9984
10239
  spinner,
9985
10240
  eventMode,
10241
+ /**
10242
+ * Terminal cleanup for abort/error paths that never reach `finish()`.
10243
+ *
10244
+ * A user abort discards the transient TUI progress buffer: the user stopped
10245
+ * on purpose and the dock already showed that text as activity. A genuine
10246
+ * failure must not swallow prose that never got the chance to be *proven*
10247
+ * durable (only a following tool call proves "progress"), so it promotes the
10248
+ * pending buffer and flushes what was already promoted — otherwise a short
10249
+ * final answer followed by a transport error disappears from the transcript.
10250
+ */
10251
+ cancel(cleanup) {
10252
+ if (assistantLabelManaged && cleanup?.preservePendingNarration) {
10253
+ flushPendingTuiNarration();
10254
+ if (streamedAssistantText) {
10255
+ renderWriter.flush();
10256
+ options.output.write("\n");
10257
+ }
10258
+ }
10259
+ dropPendingTuiProgress();
10260
+ },
9986
10261
  pushText(chunk) {
9987
10262
  writeVisibleAssistantChunk(chunk);
9988
10263
  },
@@ -9990,21 +10265,39 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
9990
10265
  markThinkingDelta(chunk);
9991
10266
  },
9992
10267
  handleToolEvent,
9993
- /** 记录一条 compaction 观测事件(TUI 在 turn 结束时渲染一行 dim 摘要)。 */
9994
10268
  recordCompaction(event) {
9995
- compactionEvent = event;
10269
+ const significance = (e) => e.failed ? 4 : e.summaryGenerated ? 3 : e.compressed ? 2 : 1;
10270
+ if (!compactionEvent || significance(event) >= significance(compactionEvent)) {
10271
+ compactionEvent = event;
10272
+ }
9996
10273
  },
9997
10274
  showWorking(label) {
9998
10275
  const activeLabel = label ?? workingLabel;
9999
10276
  spinner.show(activeLabel);
10000
10277
  options.activityReporter?.(activeLabel);
10001
10278
  },
10279
+ /**
10280
+ * Pre-delta turn phase label (ctx-overflow-feedback batch 3).
10281
+ *
10282
+ * localLoop 在首个 provider delta 之前依次发出 turn-phase 事件
10283
+ * (validating-context → compacting → waiting-provider);此前 CLI 只有
10284
+ * llm-start 才进入明确 working 状态,压缩期间 spinner 停在通用
10285
+ * working 文案上,用户无法区分「卡在检查上下文 / 压缩 / 等模型」。
10286
+ * 两个显示面(bare CLI 的 spinner 与 TUI 的 dock activityReporter)与
10287
+ * showWorking 走同一条投影,保证两端文案不漂移。
10288
+ */
10289
+ showPhase(phase) {
10290
+ const label = phase === "validating-context" ? t("contextChecking") : phase === "compacting" ? t("contextCompacting") : t("waitingForModel");
10291
+ spinner.show(label);
10292
+ options.activityReporter?.(label);
10293
+ },
10002
10294
  finish(fallbackContent) {
10003
10295
  const flushedThink = flushThinkParser(thinkState);
10004
10296
  thinkState = flushedThink.state;
10005
10297
  if (flushedThink.content) {
10006
10298
  writeVisibleAssistantChunk(flushedThink.content);
10007
10299
  }
10300
+ if (assistantLabelManaged) flushPendingTuiNarration();
10008
10301
  endThinkingPhase();
10009
10302
  spinner.stop();
10010
10303
  options.activityReporter?.(null);
@@ -10109,6 +10402,7 @@ async function readStreamingAgentRun(options, res, existingSpinner) {
10109
10402
  let content = "";
10110
10403
  let dialogId;
10111
10404
  let usage;
10405
+ let sawDone = false;
10112
10406
  const handlePayload = (payload) => {
10113
10407
  if (typeof payload?.dialogId === "string" && payload.dialogId.trim()) {
10114
10408
  dialogId = payload.dialogId;
@@ -10121,6 +10415,7 @@ async function readStreamingAgentRun(options, res, existingSpinner) {
10121
10415
  }
10122
10416
  if (payload?.type === "done") {
10123
10417
  usage = payload.usage;
10418
+ sawDone = true;
10124
10419
  return;
10125
10420
  }
10126
10421
  if (payload?.type === "dialog" || payload?.type === "status") {
@@ -10174,6 +10469,9 @@ async function readStreamingAgentRun(options, res, existingSpinner) {
10174
10469
  }
10175
10470
  } catch (error) {
10176
10471
  turnOutput.spinner.stop();
10472
+ turnOutput.cancel({
10473
+ preservePendingNarration: !options.abortSignal?.aborted
10474
+ });
10177
10475
  if (options.abortSignal?.aborted) {
10178
10476
  return {
10179
10477
  exitCode: 0,
@@ -10203,6 +10501,15 @@ ${describeClientVersionTooOldFailure(message, error)}`);
10203
10501
  `);
10204
10502
  return { exitCode: 1 };
10205
10503
  }
10504
+ if (options.abortSignal?.aborted && !sawDone) {
10505
+ turnOutput.spinner.stop();
10506
+ turnOutput.cancel();
10507
+ return {
10508
+ exitCode: 0,
10509
+ ...dialogId ? { dialogId } : {},
10510
+ streamInterrupted: true
10511
+ };
10512
+ }
10206
10513
  turnOutput.finish(content);
10207
10514
  const usageText = formatUsage(usage, dialogId);
10208
10515
  if (usageText && shouldShowUsage(options.env))
@@ -10419,7 +10726,7 @@ function findCollapsedPasteSpanAt(buffer, pos, opts = {}) {
10419
10726
  // packages/cli/client/agentRun.ts
10420
10727
  import { ulid as ulid2 } from "ulid";
10421
10728
  async function loadRunLocalAgentTurn() {
10422
- const { runLocalAgentTurn } = await import("./agentRuntimeLocal-O4HPUJA4.js");
10729
+ const { runLocalAgentTurn } = await import("./agentRuntimeLocal-SYLNOKCT.js");
10423
10730
  return runLocalAgentTurn;
10424
10731
  }
10425
10732
  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();
@@ -10746,6 +11053,22 @@ var SERVER_FALLBACK_HINT = "or use --server to run on the server explicitly.";
10746
11053
  function buildAuthFailure(ctx) {
10747
11054
  const platformNoToken = ctx.where === "server chat proxy" && isAuthNoTokenBody(ctx.message);
10748
11055
  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`;
11056
+ const { url: validationUrl, text: validationText } = extractGoogleValidationLink(ctx.message);
11057
+ const validationLabel = validationText || "Verify your account";
11058
+ if (validationUrl) {
11059
+ const linkLine = `
11060
+ ${formatCliHyperlink(validationUrl, validationLabel)}`;
11061
+ const rawLine = resolveCliHyperlinkEnabled() ? `
11062
+ \u70B9\u4E0D\u4E86\u5C31\u590D\u5236\u8FD9\u884C: ${validationUrl}` : "";
11063
+ const verifyHint = `
11064
+ \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`;
11065
+ const retryLine = `
11066
+ \u9A8C\u8BC1\u5B8C\u6210\u540E\u76F4\u63A5\u91CD\u8BD5\u521A\u624D\u7684\u547D\u4EE4\u5373\u53EF\uFF0Ctoken \u4E0D\u7528\u91CD\u65B0\u767B\u5F55\u3002`;
11067
+ return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}: Google requires a one-time account verification \u2014 your credential is fine).
11068
+ Open this link in a browser signed into ${ctx.credentialAccountId ? `\`${ctx.credentialAccountId}\`` : "the Google account behind this credential"}:${linkLine}${rawLine}${verifyHint}${retryLine}
11069
+ Detail: ${ctx.message} ${NO_FALLBACK} Use --server to run on the server explicitly.
11070
+ `;
11071
+ }
10749
11072
  return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}, auth rejected). Detail: ${ctx.message} ${NO_FALLBACK} ${fix}, ${SERVER_FALLBACK_HINT}.
10750
11073
  `;
10751
11074
  }
@@ -10781,6 +11104,17 @@ function buildUpstreamFailure(ctx) {
10781
11104
  return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}). Detail: ${ctx.message} ${NO_FALLBACK} ${fix}, ${SERVER_FALLBACK_HINT}.
10782
11105
  `;
10783
11106
  }
11107
+ function formatLocalTurnFailureLine(error) {
11108
+ const message = toErrorMessage(error);
11109
+ if (error?.code === "LLM_REQUEST_TIMEOUT") {
11110
+ const msMatch = /after (\d+)ms/.exec(message);
11111
+ const deadline = msMatch && Number.isFinite(Number(msMatch[1])) ? formatElapsed(Math.round(Number(msMatch[1]) / 1e3)) : "the configured window";
11112
+ return `[nolo] ${t("llmRequestTimedOut", deadline)}
11113
+ `;
11114
+ }
11115
+ return `[nolo] Local agent run failed: ${message}
11116
+ `;
11117
+ }
10784
11118
  var FAILURE_BUILDERS = {
10785
11119
  auth: buildAuthFailure,
10786
11120
  "rejected-payload": buildRejectedPayloadFailure,
@@ -10789,6 +11123,7 @@ var FAILURE_BUILDERS = {
10789
11123
  upstream: buildUpstreamFailure
10790
11124
  };
10791
11125
  function describeLocalRunFailure(message, rawError) {
11126
+ const credentialAccountId = rawError && typeof rawError === "object" && typeof rawError.credentialAccountId === "string" ? rawError.credentialAccountId.trim() || void 0 : void 0;
10792
11127
  if (rawError && typeof rawError === "object" && "code" in rawError && rawError.code === "PLATFORM_STREAM_INTERRUPTED") {
10793
11128
  return "[nolo] The platform LLM stream was interrupted before the turn completed. Your conversation was preserved. Send another message to continue.\n";
10794
11129
  }
@@ -10866,7 +11201,8 @@ function describeLocalRunFailure(message, rawError) {
10866
11201
  status: cls.status,
10867
11202
  ...cls.statusInferred ? { statusInferred: true } : {},
10868
11203
  ...cls.quotaExhausted ? { quotaExhausted: true } : {},
10869
- ...cooldownUntil ? { cooldownUntil } : {}
11204
+ ...cooldownUntil ? { cooldownUntil } : {},
11205
+ ...credentialAccountId ? { credentialAccountId } : {}
10870
11206
  };
10871
11207
  return FAILURE_BUILDERS[cls.kind](ctx);
10872
11208
  }
@@ -11183,6 +11519,18 @@ async function runLocalAgentTurnForCli(options, settings) {
11183
11519
  if (event.kind === "llm-start") {
11184
11520
  turnOutput.showWorking();
11185
11521
  }
11522
+ if (event.kind === "turn-phase") {
11523
+ turnOutput.showPhase(event.phase);
11524
+ }
11525
+ if (event.kind === "compaction-start") {
11526
+ turnOutput.showPhase("compacting");
11527
+ }
11528
+ if (event.kind === "compaction-end" || // 压缩失败(timeout/provider-error)时 localLoop 按失败原子性语义
11529
+ // 带着裁剪后的历史继续本轮,切回等待模型文案;aborted 时 turn 随即
11530
+ // 结束,不再切文案(终态由 abort 路径收尾)。
11531
+ event.kind === "compaction-failed" && event.reason !== "aborted") {
11532
+ turnOutput.showPhase("waiting-provider");
11533
+ }
11186
11534
  if (event.kind === "image-downgraded") {
11187
11535
  options.output.write(
11188
11536
  "[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"
@@ -11228,6 +11576,9 @@ async function runLocalAgentTurnForCli(options, settings) {
11228
11576
  };
11229
11577
  } catch (error) {
11230
11578
  turnOutput.spinner.stop();
11579
+ turnOutput.cancel({
11580
+ preservePendingNarration: error?.code !== LOCAL_TURN_ABORTED_CODE && !options.abortSignal?.aborted
11581
+ });
11231
11582
  const savedDialogId = error?.dialogId;
11232
11583
  const abortedUsageRecords = error?.usageRecords;
11233
11584
  const abortedTurnCredits = sumPlatformCredits(abortedUsageRecords);
@@ -11251,10 +11602,12 @@ async function runLocalAgentTurnForCli(options, settings) {
11251
11602
  error.cooldownUntil = cooldownUntil;
11252
11603
  }
11253
11604
  if (settings.reportFailure) {
11254
- options.output.write(
11255
- `[nolo] Local agent run failed: ${toErrorMessage(error)}
11256
- `
11257
- );
11605
+ const failureLine = formatLocalTurnFailureLine(error);
11606
+ if (typeof options.output.writeErr === "function") {
11607
+ options.output.writeErr(failureLine);
11608
+ } else {
11609
+ options.output.write(failureLine);
11610
+ }
11258
11611
  if (cooldownUntil) {
11259
11612
  options.output.write(
11260
11613
  `[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
@@ -11392,7 +11745,7 @@ async function runAgentTurn(options) {
11392
11745
  return { exitCode: 1 };
11393
11746
  }
11394
11747
  const localAvailability = await checkLocalAvailabilityBeforeHttpDispatch(options);
11395
- if (localAvailability?.exitCode) {
11748
+ if (localAvailability && "exitCode" in localAvailability) {
11396
11749
  return { exitCode: localAvailability.exitCode };
11397
11750
  }
11398
11751
  const httpResult = await runHttpAgentTurn(options, authToken);
@@ -12134,72 +12487,6 @@ var rankMemoryCandidates = (items, query, context) => {
12134
12487
  });
12135
12488
  };
12136
12489
 
12137
- // packages/ai/memory/vnext/store.ts
12138
- var enc = (value) => encodeURIComponent(value).replace(/-/g, "%2D");
12139
- var rangeOf = (prefix) => ({ gte: prefix, lte: `${prefix}\uFFFF` });
12140
- var entityKey = (ownerId, id) => `mem2-e-${enc(ownerId)}-${enc(id)}`;
12141
- var entityOwnerPrefix = (ownerId) => `mem2-e-${enc(ownerId)}-`;
12142
- var stateKey = (ownerId, id) => `mem2-s-${enc(ownerId)}-${enc(id)}`;
12143
- var stateEntityIndexKey = (ownerId, entityId, stateId) => `mem2-si-${enc(ownerId)}-${enc(entityId)}-${enc(stateId)}`;
12144
- var stateEntityIndexPrefix = (ownerId, entityId) => `mem2-si-${enc(ownerId)}-${enc(entityId)}-`;
12145
- var evidenceKey = (ownerId, id) => `mem2-v-${enc(ownerId)}-${enc(id)}`;
12146
- var relationKey = (ownerId, id) => `mem2-r-${enc(ownerId)}-${enc(id)}`;
12147
- var relationFromIndexKey = (ownerId, from, relationId) => `mem2-rf-${enc(ownerId)}-${enc(from)}-${enc(relationId)}`;
12148
- var relationToIndexKey = (ownerId, to, relationId) => `mem2-rt-${enc(ownerId)}-${enc(to)}-${enc(relationId)}`;
12149
- var readIndexed = async (db, prefix) => {
12150
- const refs = [];
12151
- for await (const [, value] of db.iterator({ ...rangeOf(prefix), reverse: false })) {
12152
- if (typeof value?.key === "string") refs.push(value.key);
12153
- }
12154
- const rows = await Promise.all(refs.map((key) => db.get(key).catch(() => null)));
12155
- return rows.filter((row) => !!row);
12156
- };
12157
- var getMemoryEntityVNext = async (db, ownerId, entityId) => db.get(entityKey(ownerId, entityId)).catch(() => null);
12158
- var listMemoryEntitiesVNext = async (db, ownerId) => {
12159
- const rows = [];
12160
- for await (const [, value] of db.iterator({
12161
- ...rangeOf(entityOwnerPrefix(ownerId)),
12162
- reverse: false
12163
- })) {
12164
- if (value) rows.push(value);
12165
- }
12166
- return rows;
12167
- };
12168
- var getMemoryStateVNext = async (db, ownerId, stateId) => db.get(stateKey(ownerId, stateId)).catch(() => null);
12169
- var listMemoryStatesForEntityVNext = (db, ownerId, entityId) => readIndexed(db, stateEntityIndexPrefix(ownerId, entityId));
12170
- var putMemoryEvidenceVNext = async (db, evidence) => {
12171
- await db.put(evidenceKey(evidence.ownerId, evidence.id), evidence);
12172
- };
12173
- var getMemoryEvidenceVNext = async (db, ownerId, evidenceId) => db.get(evidenceKey(ownerId, evidenceId)).catch(() => null);
12174
- var getMemoryEvidenceVNextStrict = async (db, ownerId, evidenceId) => {
12175
- try {
12176
- return await db.get(evidenceKey(ownerId, evidenceId));
12177
- } catch (error) {
12178
- if (isLevelNotFoundError(error)) return null;
12179
- throw error;
12180
- }
12181
- };
12182
- var _appendEntityBatch = (batch, entity) => {
12183
- batch.put(entityKey(entity.ownerId, entity.id), entity);
12184
- };
12185
- var _appendEvidenceBatch = (batch, evidence) => {
12186
- batch.put(evidenceKey(evidence.ownerId, evidence.id), evidence);
12187
- };
12188
- var _appendStateBatch = (batch, state2) => {
12189
- const key = stateKey(state2.ownerId, state2.id);
12190
- batch.put(key, state2);
12191
- batch.put(stateEntityIndexKey(state2.ownerId, state2.entityId, state2.id), { key });
12192
- };
12193
- var _appendRetiredStateBatch = (batch, state2) => {
12194
- batch.put(stateKey(state2.ownerId, state2.id), state2);
12195
- };
12196
- var _appendRelationBatch = (batch, relation) => {
12197
- const key = relationKey(relation.ownerId, relation.id);
12198
- batch.put(key, relation);
12199
- batch.put(relationFromIndexKey(relation.ownerId, relation.from, relation.id), { key });
12200
- batch.put(relationToIndexKey(relation.ownerId, relation.to, relation.id), { key });
12201
- };
12202
-
12203
12490
  // packages/ai/memory/vnext/recall.ts
12204
12491
  var MAX_RECALL_REFS = 6;
12205
12492
  var stripFence = (raw) => {
@@ -12229,14 +12516,6 @@ var parseSelection = (raw) => {
12229
12516
  reason: obj.reason
12230
12517
  };
12231
12518
  };
12232
- var buildCatalog = async (db, ownerId) => {
12233
- const entities = await listMemoryEntitiesVNext(db, ownerId);
12234
- const states = [];
12235
- for (const entity of entities) {
12236
- states.push(...await listMemoryStatesForEntityVNext(db, ownerId, entity.id));
12237
- }
12238
- return { entities, states };
12239
- };
12240
12519
  var catalogText = (entities, states) => JSON.stringify(
12241
12520
  {
12242
12521
  entities: entities.map((entity) => ({
@@ -12262,7 +12541,7 @@ var catalogText = (entities, states) => JSON.stringify(
12262
12541
  );
12263
12542
  var createMemoryVNextRecall = (input) => async (query) => {
12264
12543
  const startedAt = performance.now();
12265
- const { entities, states } = await buildCatalog(input.db, input.ownerId);
12544
+ const { entities, states } = await loadMemoryVNextCatalog(input.db, input.ownerId);
12266
12545
  if (entities.length === 0 && states.length === 0) {
12267
12546
  return {
12268
12547
  query,
@@ -13133,14 +13412,74 @@ var shortError2 = (error) => {
13133
13412
  return message.length > ERROR_MESSAGE_MAX2 ? `${message.slice(0, ERROR_MESSAGE_MAX2)}\u2026` : message;
13134
13413
  };
13135
13414
  var loadExistingContext = async (db, ownerId) => {
13136
- const entities = await listMemoryEntitiesVNext(db, ownerId);
13137
- const states = (await Promise.all(
13138
- entities.map((entity) => listMemoryStatesForEntityVNext(db, ownerId, entity.id))
13139
- )).flat();
13140
- return {
13141
- entityIds: entities.map((entity) => entity.id),
13142
- states
13415
+ const { entities, states } = await loadMemoryVNextCatalog(db, ownerId);
13416
+ return { entityIds: entities.map((entity) => entity.id), states };
13417
+ };
13418
+ var currentStatesCitingEvidence = (states, evidenceId) => states.filter((state2) => !state2.retiredAt && (state2.evidenceIds ?? []).includes(evidenceId));
13419
+ var isEvidenceCoveredByCurrentStates = (states, evidenceId) => currentStatesCitingEvidence(states, evidenceId).length > 0;
13420
+ var memoryVNextContextFingerprint = (existing) => {
13421
+ const states = existing.states ?? [];
13422
+ const entityIds = existing.entityIds ?? [];
13423
+ const canonical = [
13424
+ ...entityIds.map((id) => `e\0${id}`),
13425
+ ...states.map((state2) => `s\0${state2.id}\0${state2.updatedAt}\0${state2.retiredAt ?? ""}`)
13426
+ ].sort().join("");
13427
+ let hash = 2166136261;
13428
+ for (let i = 0; i < canonical.length; i++) {
13429
+ hash ^= canonical.charCodeAt(i);
13430
+ hash = Math.imul(hash, 16777619);
13431
+ }
13432
+ return `${entityIds.length}.${states.length}:${(hash >>> 0).toString(16)}`;
13433
+ };
13434
+ var MAX_NOOP_SUPPRESSIONS = 512;
13435
+ var noOpSuppressions = /* @__PURE__ */ new Map();
13436
+ var suppressionKey = (ownerId, evidenceId) => `${ownerId}\0${evidenceId}`;
13437
+ var recordNoOpSuppression = (ownerId, evidenceId, fingerprint) => {
13438
+ const key = suppressionKey(ownerId, evidenceId);
13439
+ noOpSuppressions.delete(key);
13440
+ noOpSuppressions.set(key, fingerprint);
13441
+ while (noOpSuppressions.size > MAX_NOOP_SUPPRESSIONS) {
13442
+ noOpSuppressions.delete(noOpSuppressions.keys().next().value);
13443
+ }
13444
+ };
13445
+ var noOpHistory = (ownerId, evidenceId, fingerprint) => {
13446
+ const recorded = noOpSuppressions.get(suppressionKey(ownerId, evidenceId));
13447
+ if (recorded === void 0) return "fresh";
13448
+ return recorded === fingerprint ? "suppressed" : "stale";
13449
+ };
13450
+ var pickFirstUncoveredLazyPromotionItem = async (db, selected) => {
13451
+ const contextByOwner = /* @__PURE__ */ new Map();
13452
+ const contextFor = (ownerId) => {
13453
+ let pending = contextByOwner.get(ownerId);
13454
+ if (!pending) {
13455
+ pending = loadExistingContext(db, ownerId).then((existing) => ({
13456
+ states: existing.states ?? [],
13457
+ fingerprint: memoryVNextContextFingerprint(existing)
13458
+ }));
13459
+ contextByOwner.set(ownerId, pending);
13460
+ }
13461
+ return pending;
13143
13462
  };
13463
+ let skippedCoveredCount = 0;
13464
+ let skippedNoOpCount = 0;
13465
+ let firstStale = null;
13466
+ for (const [selectedIndex, item] of selected.entries()) {
13467
+ const evidence = buildLegacyMemoryEvidence(item);
13468
+ const context = await contextFor(evidence.ownerId);
13469
+ if (isEvidenceCoveredByCurrentStates(context.states, evidence.id)) {
13470
+ skippedCoveredCount++;
13471
+ continue;
13472
+ }
13473
+ const history = noOpHistory(evidence.ownerId, evidence.id, context.fingerprint);
13474
+ if (history === "fresh") {
13475
+ return { item, selectedIndex, skippedCoveredCount, skippedNoOpCount };
13476
+ }
13477
+ if (history === "stale" && !firstStale) {
13478
+ firstStale = { item, selectedIndex, skippedCoveredCount, skippedNoOpCount };
13479
+ }
13480
+ skippedNoOpCount++;
13481
+ }
13482
+ return firstStale;
13144
13483
  };
13145
13484
  var withoutImportedEvidence = (mutation, importedEvidenceId) => ({
13146
13485
  ...mutation,
@@ -13156,6 +13495,11 @@ var runMemoryVNextLazyPromotion = async (input) => {
13156
13495
  }));
13157
13496
  const finish = (partial) => {
13158
13497
  const observation = {
13498
+ legacyItemId: input.item.id,
13499
+ evidenceId: deterministicEvidence.id,
13500
+ ...input.selectedIndex === void 0 ? {} : { selectedIndex: input.selectedIndex },
13501
+ ...input.skippedCoveredCount === void 0 ? {} : { skippedCoveredCount: input.skippedCoveredCount },
13502
+ ...input.skippedNoOpCount === void 0 ? {} : { skippedNoOpCount: input.skippedNoOpCount },
13159
13503
  ...partial,
13160
13504
  latencyMs: Math.round((clock() - startedAt) * 10) / 10
13161
13505
  };
@@ -13178,8 +13522,9 @@ var runMemoryVNextLazyPromotion = async (input) => {
13178
13522
  }
13179
13523
  const evidence = evidenceResult.evidence;
13180
13524
  const existing = await loadExistingContext(input.db, evidence.ownerId);
13181
- const alreadyCovered = (existing.states ?? []).some(
13182
- (state2) => !state2.retiredAt && state2.evidenceIds.includes(evidence.id)
13525
+ const alreadyCovered = isEvidenceCoveredByCurrentStates(
13526
+ existing.states ?? [],
13527
+ evidence.id
13183
13528
  );
13184
13529
  if (alreadyCovered) {
13185
13530
  return finish({ status: "already_covered" });
@@ -13194,6 +13539,11 @@ var runMemoryVNextLazyPromotion = async (input) => {
13194
13539
  });
13195
13540
  const semanticMutation = withoutImportedEvidence(interpreted.mutation, evidence.id);
13196
13541
  if (!hasWrites(semanticMutation)) {
13542
+ recordNoOpSuppression(
13543
+ evidence.ownerId,
13544
+ evidence.id,
13545
+ memoryVNextContextFingerprint(existing)
13546
+ );
13197
13547
  return finish({ status: "no_op", action: semanticMutation.action });
13198
13548
  }
13199
13549
  await applyMemoryInterpreterMutation(input.db, evidence.ownerId, semanticMutation);
@@ -13206,6 +13556,179 @@ var runMemoryVNextLazyPromotion = async (input) => {
13206
13556
  };
13207
13557
  var isMemoryVNextLazyPromotionEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_LAZY_PROMOTION === "1" || env.NOLO_MEMORY_VNEXT_LAZY_PROMOTION === "true";
13208
13558
 
13559
+ // packages/ai/memory/vnext/pureReadGate.ts
13560
+ var isMemoryVNextPureReadEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_PURE_READ === "1" || env.NOLO_MEMORY_VNEXT_PURE_READ === "true";
13561
+
13562
+ // packages/ai/memory/vnext/localRecall.ts
13563
+ var MIN_SHARED_TOKENS = 2;
13564
+ var MAX_LOCAL_RECALL_STATES = 8;
13565
+ var SAFE_TECHNICAL_SYNONYMS = {
13566
+ pr: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5", "diff"],
13567
+ diff: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5"],
13568
+ review: ["\u5BA1\u67E5", "\u4EE3\u7801\u5BA1\u67E5"],
13569
+ deploy: ["\u90E8\u7F72", "\u53D1\u7248"],
13570
+ release: ["\u53D1\u7248", "\u53D1\u5E03"],
13571
+ desktop: ["\u684C\u9762", "\u684C\u9762\u7AEF"]
13572
+ };
13573
+ var distinctTokens = (text) => new Set(tokenize2(text).filter((token) => token.length >= 2));
13574
+ var recallMemoryVNextLocal = (input) => {
13575
+ const rawTokens = distinctTokens(input.query);
13576
+ if (rawTokens.size === 0) return [];
13577
+ const queryTokens = new Set(rawTokens);
13578
+ for (const token of rawTokens) {
13579
+ const syns = SAFE_TECHNICAL_SYNONYMS[token.toLowerCase()];
13580
+ if (syns) {
13581
+ for (const syn of syns) {
13582
+ for (const t2 of distinctTokens(syn)) queryTokens.add(t2);
13583
+ }
13584
+ }
13585
+ }
13586
+ const entityById = new Map(input.entities.map((entity) => [entity.id, entity]));
13587
+ const hits = [];
13588
+ for (const state2 of input.states) {
13589
+ if (state2.retiredAt || !state2.text.trim()) continue;
13590
+ const entity = entityById.get(state2.entityId);
13591
+ const haystack = distinctTokens(
13592
+ [state2.facet, state2.text, entity?.name ?? "", ...entity?.aliases ?? []].join(" ")
13593
+ );
13594
+ let sharedTokens = 0;
13595
+ for (const token of queryTokens) if (haystack.has(token)) sharedTokens++;
13596
+ if (sharedTokens >= MIN_SHARED_TOKENS) hits.push({ state: state2, sharedTokens });
13597
+ }
13598
+ return hits.sort((a, b) => b.sharedTokens - a.sharedTokens || a.state.id.localeCompare(b.state.id)).slice(0, input.limit ?? MAX_LOCAL_RECALL_STATES);
13599
+ };
13600
+
13601
+ // packages/ai/memory/vnext/pureVNextRuntime.ts
13602
+ var buildSynthesizedStateItem = (state2, entity, ownerType, ownerId) => ({
13603
+ id: `vnext-state-${state2.id}`,
13604
+ ownerType,
13605
+ ownerId,
13606
+ visibility: "private",
13607
+ subjectType: "user",
13608
+ subjectId: ownerId,
13609
+ kind: "semantic",
13610
+ content: state2.text.trim(),
13611
+ createdAt: state2.createdAt,
13612
+ lastActivatedAt: state2.createdAt,
13613
+ activationCount: 1,
13614
+ importance: 0.9,
13615
+ confidence: 0.9,
13616
+ resident: state2.facet === "preference" || state2.facet === "style"
13617
+ });
13618
+ async function resolvePureVNextRuntime(input) {
13619
+ const { db, owners, userInput } = input;
13620
+ if (owners.length === 0 || !userInput.trim()) {
13621
+ return { selectedItems: [], promptBlock: null, recalledStateCount: 0 };
13622
+ }
13623
+ const ownerIds = owners.map((o) => `${o.ownerType}:${encodeURIComponent(o.ownerId)}`);
13624
+ const catalogs = await Promise.all(
13625
+ ownerIds.map((ownerId) => loadMemoryVNextCatalog(db, ownerId))
13626
+ );
13627
+ const selectedItems = [];
13628
+ const seenStateKeys = /* @__PURE__ */ new Set();
13629
+ for (let i = 0; i < owners.length; i++) {
13630
+ const owner = owners[i];
13631
+ const catalog = catalogs[i];
13632
+ const currentStates = catalog.states.filter((s) => !s.retiredAt && s.text.trim());
13633
+ const hits = recallMemoryVNextLocal({
13634
+ query: userInput,
13635
+ entities: catalog.entities,
13636
+ states: currentStates
13637
+ });
13638
+ const entityById = new Map(catalog.entities.map((e) => [e.id, e]));
13639
+ for (const hit of hits) {
13640
+ const stateKey = `${hit.state.ownerId}\0${hit.state.id}`;
13641
+ if (seenStateKeys.has(stateKey)) continue;
13642
+ seenStateKeys.add(stateKey);
13643
+ selectedItems.push(
13644
+ buildSynthesizedStateItem(hit.state, entityById.get(hit.state.entityId), owner.ownerType, owner.ownerId)
13645
+ );
13646
+ }
13647
+ }
13648
+ const promptBlock = selectedItems.length === 0 ? null : buildMemoryOverlay(selectedItems, {
13649
+ maxTokens: input.maxTokens ?? DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET
13650
+ });
13651
+ return {
13652
+ selectedItems,
13653
+ promptBlock,
13654
+ recalledStateCount: selectedItems.length
13655
+ };
13656
+ }
13657
+
13658
+ // packages/ai/memory/vnext/primaryRead.ts
13659
+ var MEMORY_VNEXT_PRIMARY_READ_TIMEOUT_MS = 300;
13660
+ var isMemoryVNextPrimaryReadEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_PRIMARY_READ === "1" || env.NOLO_MEMORY_VNEXT_PRIMARY_READ === "true";
13661
+ var buildSynthesizedStateItem2 = (state2, entity, ownerType, ownerId) => ({
13662
+ id: `vnext-state-${state2.id}`,
13663
+ ownerType,
13664
+ ownerId,
13665
+ visibility: "private",
13666
+ subjectType: "user",
13667
+ subjectId: ownerId,
13668
+ kind: "semantic",
13669
+ content: state2.text.trim(),
13670
+ createdAt: state2.createdAt,
13671
+ importance: 0.9,
13672
+ confidence: 0.9,
13673
+ // Flag resident preferences so they flow into overlay's resident section.
13674
+ resident: state2.facet === "preference" || state2.facet === "style",
13675
+ lastActivatedAt: state2.createdAt,
13676
+ activationCount: 1
13677
+ });
13678
+ var resolveMemoryVNextM4Selection = async (input) => {
13679
+ const { db, owners, query, selected } = input;
13680
+ const ownerIds = owners.map((o) => `${o.ownerType}:${encodeURIComponent(o.ownerId)}`);
13681
+ const catalogs = new Map(
13682
+ await Promise.all(
13683
+ ownerIds.map(async (ownerId) => [
13684
+ ownerId,
13685
+ await loadMemoryVNextCatalog(db, ownerId)
13686
+ ])
13687
+ )
13688
+ );
13689
+ const recalledStates = [];
13690
+ const recalledStateIds = /* @__PURE__ */ new Set();
13691
+ for (const owner of owners) {
13692
+ const principalId = `${owner.ownerType}:${encodeURIComponent(owner.ownerId)}`;
13693
+ const catalog = catalogs.get(principalId);
13694
+ if (!catalog) continue;
13695
+ const currentStates = catalog.states.filter((s) => !s.retiredAt && s.text.trim());
13696
+ const hits = recallMemoryVNextLocal({
13697
+ query,
13698
+ entities: catalog.entities,
13699
+ states: currentStates
13700
+ });
13701
+ const entityById = new Map(catalog.entities.map((e) => [e.id, e]));
13702
+ for (const hit of hits) {
13703
+ if (recalledStateIds.has(hit.state.id)) continue;
13704
+ recalledStateIds.add(hit.state.id);
13705
+ recalledStates.push(
13706
+ buildSynthesizedStateItem2(hit.state, entityById.get(hit.state.entityId), owner.ownerType, owner.ownerId)
13707
+ );
13708
+ }
13709
+ }
13710
+ const uncoveredLegacy = [];
13711
+ let coveredSuppressedCount = 0;
13712
+ for (const item of selected) {
13713
+ const evidence = buildLegacyMemoryEvidence(item);
13714
+ const catalog = catalogs.get(evidence.ownerId);
13715
+ const states = catalog?.states ?? [];
13716
+ const covering = currentStatesCitingEvidence(states, evidence.id);
13717
+ if (covering.length > 0) {
13718
+ coveredSuppressedCount++;
13719
+ } else {
13720
+ uncoveredLegacy.push(item);
13721
+ }
13722
+ }
13723
+ const renderItems = [...recalledStates, ...uncoveredLegacy];
13724
+ return {
13725
+ renderItems,
13726
+ recalledStateCount: recalledStates.length,
13727
+ uncoveredLegacyCount: uncoveredLegacy.length,
13728
+ coveredSuppressedCount
13729
+ };
13730
+ };
13731
+
13209
13732
  // packages/ai/memory/runtime.ts
13210
13733
  var COLD_STORAGE_CONFIDENCE = 0.3;
13211
13734
  var MEMORY_OVERLAY_TOKEN_BUDGET = DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET;
@@ -13328,6 +13851,18 @@ var resolveMemoryRuntime = async (input) => {
13328
13851
  if (owners.length === 0) {
13329
13852
  return { selectedItems: [], promptBlock: null };
13330
13853
  }
13854
+ if (isMemoryVNextPureReadEnabled()) {
13855
+ const pure = await resolvePureVNextRuntime({
13856
+ db: input.db,
13857
+ owners,
13858
+ userInput: input.userInput,
13859
+ maxTokens: MEMORY_OVERLAY_TOKEN_BUDGET
13860
+ });
13861
+ return {
13862
+ selectedItems: pure.selectedItems,
13863
+ promptBlock: pure.promptBlock
13864
+ };
13865
+ }
13331
13866
  const policy = resolveAgentMemoryPolicy({ agentKey: input.agentKey });
13332
13867
  const legacyStartedAt = performance.now();
13333
13868
  const candidates = await loadMemoryCandidatesFromDb(input.db, {
@@ -13357,10 +13892,62 @@ var resolveMemoryRuntime = async (input) => {
13357
13892
  );
13358
13893
  const selected = [...residentItems, ...ranked];
13359
13894
  const legacyLatencyMs = Math.round((performance.now() - legacyStartedAt) * 10) / 10;
13360
- const promptBlock = selected.length === 0 ? null : buildMemoryOverlay(selected, { maxTokens: MEMORY_OVERLAY_TOKEN_BUDGET });
13361
- const shadowEnabled = input.vNextShadowProvider != null && isMemoryVNextShadowReadEnabled();
13895
+ const renderOverlay = (items) => items.length === 0 ? null : buildMemoryOverlay(items, { maxTokens: MEMORY_OVERLAY_TOKEN_BUDGET });
13896
+ let promptBlock = renderOverlay(selected);
13897
+ const primaryRead = isMemoryVNextPrimaryReadEnabled();
13898
+ let allCoveredByVNext = false;
13899
+ if (primaryRead) {
13900
+ const emitPrimary = (observation) => {
13901
+ try {
13902
+ (input.primaryReadEmit ?? ((o) => console.info("[memory] vnext primary read", { event: "memory_vnext_primary_read", ...o })))(observation);
13903
+ } catch {
13904
+ }
13905
+ };
13906
+ const base = { legacyHitCount: selected.length, legacyLatencyMs };
13907
+ const vnextStartedAt = performance.now();
13908
+ const vnextLatency = () => Math.round((performance.now() - vnextStartedAt) * 10) / 10;
13909
+ if (selected.length === 0) {
13910
+ emitPrimary({ ...base, source: "none" });
13911
+ } else {
13912
+ try {
13913
+ let timer;
13914
+ const m4 = await Promise.race([
13915
+ resolveMemoryVNextM4Selection({ db: input.db, owners, query: input.userInput, selected }),
13916
+ new Promise((_, reject) => {
13917
+ timer = setTimeout(
13918
+ () => reject(Object.assign(new Error("timeout"), { name: "TimeoutError" })),
13919
+ MEMORY_VNEXT_PRIMARY_READ_TIMEOUT_MS
13920
+ );
13921
+ })
13922
+ ]).finally(() => clearTimeout(timer));
13923
+ promptBlock = renderOverlay(m4.renderItems);
13924
+ allCoveredByVNext = m4.uncoveredLegacyCount === 0 && m4.recalledStateCount > 0;
13925
+ const source = m4.recalledStateCount > 0 ? m4.uncoveredLegacyCount === 0 ? "vnext" : "hybrid" : m4.uncoveredLegacyCount > 0 ? "legacy_fallback" : "none";
13926
+ emitPrimary({
13927
+ ...base,
13928
+ source,
13929
+ uncoveredLegacyCount: m4.uncoveredLegacyCount,
13930
+ coveredSuppressedCount: m4.coveredSuppressedCount,
13931
+ recalledStateCount: m4.recalledStateCount,
13932
+ vnextLatencyMs: vnextLatency(),
13933
+ contextChars: promptBlock?.length ?? 0,
13934
+ ...source === "legacy_fallback" ? { fallbackReason: "no_vnext_context" } : {}
13935
+ });
13936
+ } catch (error) {
13937
+ emitPrimary({
13938
+ ...base,
13939
+ source: "legacy_fallback",
13940
+ vnextLatencyMs: vnextLatency(),
13941
+ contextChars: promptBlock?.length ?? 0,
13942
+ fallbackReason: "vnext_error",
13943
+ error: error instanceof Error ? error.name : "UnknownError"
13944
+ });
13945
+ }
13946
+ }
13947
+ }
13948
+ const shadowEnabled = !primaryRead && input.vNextShadowProvider != null && isMemoryVNextShadowReadEnabled();
13362
13949
  if (shadowEnabled) {
13363
- await runMemoryVNextShadowRead({
13950
+ void runMemoryVNextShadowRead({
13364
13951
  ctx: {
13365
13952
  db: input.db,
13366
13953
  owners,
@@ -13370,17 +13957,28 @@ var resolveMemoryRuntime = async (input) => {
13370
13957
  legacyItems: selected,
13371
13958
  legacyLatencyMs,
13372
13959
  legacyContextChars: promptBlock?.length ?? 0
13960
+ }).catch(() => {
13373
13961
  });
13374
13962
  }
13375
- const promotionCandidate = selected[0];
13376
13963
  const lazyPromotionEnabled = input.vNextShadowProvider != null && isMemoryVNextLazyPromotionEnabled();
13377
- if (lazyPromotionEnabled && promotionCandidate) {
13378
- void runMemoryVNextLazyPromotion({
13379
- db: input.db,
13380
- item: promotionCandidate,
13381
- provider: input.vNextShadowProvider,
13382
- ...input.lazyPromotionEmit ? { emit: input.lazyPromotionEmit } : {}
13383
- }).catch(() => {
13964
+ if (lazyPromotionEnabled && selected.length > 0 && !allCoveredByVNext) {
13965
+ void (async () => {
13966
+ const promotionPick = await pickFirstUncoveredLazyPromotionItem(
13967
+ input.db,
13968
+ selected
13969
+ );
13970
+ if (promotionPick) {
13971
+ await runMemoryVNextLazyPromotion({
13972
+ db: input.db,
13973
+ item: promotionPick.item,
13974
+ selectedIndex: promotionPick.selectedIndex,
13975
+ skippedCoveredCount: promotionPick.skippedCoveredCount,
13976
+ skippedNoOpCount: promotionPick.skippedNoOpCount,
13977
+ provider: input.vNextShadowProvider,
13978
+ ...input.lazyPromotionEmit ? { emit: input.lazyPromotionEmit } : {}
13979
+ });
13980
+ }
13981
+ })().catch(() => {
13384
13982
  });
13385
13983
  }
13386
13984
  if (selected.length === 0) {
@@ -13394,6 +13992,52 @@ var resolveMemoryRuntime = async (input) => {
13394
13992
  };
13395
13993
 
13396
13994
  // packages/cli/memoryRecall.ts
13995
+ var logger = getLogger("cli.memoryRecall");
13996
+ var DEDUP_WINDOW_MS = 5 * 60 * 1e3;
13997
+ var DEDUP_MAX_KEYS = 100;
13998
+ var dedupMap = /* @__PURE__ */ new Map();
13999
+ function evictDedupIfNeeded() {
14000
+ if (dedupMap.size < DEDUP_MAX_KEYS) return;
14001
+ let oldestKey = null;
14002
+ let oldestTs = Infinity;
14003
+ for (const [k, v] of dedupMap) {
14004
+ if (v.lastLog < oldestTs) {
14005
+ oldestTs = v.lastLog;
14006
+ oldestKey = k;
14007
+ }
14008
+ }
14009
+ if (oldestKey !== null) dedupMap.delete(oldestKey);
14010
+ }
14011
+ function logDeduped(level, fingerprint, message, error) {
14012
+ const now = Date.now();
14013
+ const entry = dedupMap.get(fingerprint);
14014
+ if (!entry) {
14015
+ evictDedupIfNeeded();
14016
+ dedupMap.set(fingerprint, { count: 1, suppressed: 0, lastLog: now });
14017
+ if (error !== void 0) logger[level](message, error);
14018
+ else logger[level](message);
14019
+ return;
14020
+ }
14021
+ entry.count += 1;
14022
+ if (now - entry.lastLog >= DEDUP_WINDOW_MS) {
14023
+ const suppressed = entry.suppressed;
14024
+ const summary = `${message} (deduplicated: ${entry.count} occurrences, ${suppressed} suppressed over ${Math.round((now - entry.lastLog) / 1e3)}s)`;
14025
+ if (error !== void 0) logger[level](summary, error);
14026
+ else logger[level](summary);
14027
+ entry.count = 1;
14028
+ entry.suppressed = 0;
14029
+ entry.lastLog = now;
14030
+ } else {
14031
+ entry.suppressed += 1;
14032
+ }
14033
+ }
14034
+ function fingerprintFor(kind, detail) {
14035
+ const d = detail === void 0 ? "" : sanitizeFp(String(detail));
14036
+ return `mem-${kind}:${d}`;
14037
+ }
14038
+ function sanitizeFp(s) {
14039
+ return s.replace(/\s+/g, " ").slice(0, 80);
14040
+ }
13397
14041
  var queryRemoteMemory = async (serverUrl, authToken, agentKey, userInput, spaceId) => {
13398
14042
  try {
13399
14043
  const response = await fetch(`${serverUrl}/api/memory/query`, {
@@ -13410,10 +14054,10 @@ var queryRemoteMemory = async (serverUrl, authToken, agentKey, userInput, spaceI
13410
14054
  signal: AbortSignal.timeout(5e3)
13411
14055
  });
13412
14056
  if (!response.ok) {
13413
- console.warn(
13414
- "[cli-memory] remote query returned non-ok status:",
13415
- response.status,
13416
- "\u2014 falling back to local"
14057
+ logDeduped(
14058
+ "warn",
14059
+ fingerprintFor("remote-nonok", response.status),
14060
+ `remote query returned non-ok status ${response.status} \u2014 falling back to local`
13417
14061
  );
13418
14062
  return null;
13419
14063
  }
@@ -13421,7 +14065,12 @@ var queryRemoteMemory = async (serverUrl, authToken, agentKey, userInput, spaceI
13421
14065
  const block = typeof payload?.promptBlock === "string" ? payload.promptBlock.trim() : "";
13422
14066
  return block || null;
13423
14067
  } catch (error) {
13424
- console.warn("[cli-memory] remote query failed, falling back to local:", error);
14068
+ logDeduped(
14069
+ "info",
14070
+ fingerprintFor("remote-failed", error instanceof Error ? error.name : void 0),
14071
+ "remote query failed, falling back to local",
14072
+ normalizeError(error)
14073
+ );
13425
14074
  return null;
13426
14075
  }
13427
14076
  };
@@ -13457,7 +14106,12 @@ var resolveCliMemory = async (input) => {
13457
14106
  input.spaceId
13458
14107
  );
13459
14108
  } catch (error) {
13460
- console.warn("[cli-memory] local recall failed, omitting memory layer:", error);
14109
+ logDeduped(
14110
+ "warn",
14111
+ fingerprintFor("local-failed", error instanceof Error ? error.name : void 0),
14112
+ "local recall failed, omitting memory layer",
14113
+ normalizeError(error)
14114
+ );
13461
14115
  return null;
13462
14116
  }
13463
14117
  };
@@ -13512,7 +14166,10 @@ async function resolveAgentRunAgentKey(args) {
13512
14166
  }
13513
14167
  async function runAgentRunCommand(args, deps) {
13514
14168
  const env = deps.env ?? process.env;
13515
- const output = deps.output ?? process.stdout;
14169
+ const output = deps.output ?? {
14170
+ write: (chunk) => process.stdout.write(chunk),
14171
+ writeErr: (chunk) => process.stderr.write(chunk)
14172
+ };
13516
14173
  if (args.includes("--help") || args.includes("-h")) {
13517
14174
  writeUsage(output, deps.commandPath);
13518
14175
  return 0;
@@ -14054,12 +14711,6 @@ function isBalanceExhaustedError(error) {
14054
14711
  }
14055
14712
 
14056
14713
  export {
14057
- resolveAgentModelIdentity,
14058
- resolveAgentContextWindow,
14059
- platformCreditsFromUsage,
14060
- formatCreditsChip,
14061
- formatTokenCount,
14062
- renderTokenStatus,
14063
14714
  resolveCliColorEnabled,
14064
14715
  dimCliText,
14065
14716
  ANSI_ESCAPE_REGEX,
@@ -14100,6 +14751,12 @@ export {
14100
14751
  formatAssistantDisplay,
14101
14752
  redactSecrets,
14102
14753
  TUI_TREE_MARKER,
14754
+ resolveAgentModelIdentity,
14755
+ resolveAgentContextWindow,
14756
+ platformCreditsFromUsage,
14757
+ formatCreditsChip,
14758
+ formatTokenCount,
14759
+ renderTokenStatus,
14103
14760
  COLLAPSED_PASTE_PLACEHOLDER_RE,
14104
14761
  shouldCollapsePaste,
14105
14762
  createCollapsedPasteStore,
@@ -14110,15 +14767,16 @@ export {
14110
14767
  releaseCollapsedPasteReferences,
14111
14768
  expandRangeToCollapsedPasteChips,
14112
14769
  findCollapsedPasteSpanAt,
14770
+ formatElapsed,
14113
14771
  runAgentTurn,
14114
- readAgentsMdLayerFromDisk,
14115
14772
  resolveWorkflowReference,
14116
14773
  resolveSkillReference,
14117
14774
  buildSkillContextBlocks,
14118
14775
  prependSubjectDialogMarker,
14119
14776
  normalizeCliImageInput,
14120
- inspectLocalRunWorkspace,
14777
+ readAgentsMdLayerFromDisk,
14121
14778
  resolveCliMemory,
14779
+ inspectLocalRunWorkspace,
14122
14780
  resolveRunOutcome,
14123
14781
  isRunResultStalledOrTruncated,
14124
14782
  resolveRunSettlementNote,