nolo-cli 0.54.0-alpha.2 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/{_executeModel-ANY4SIAS.js → _executeModel-OPTKYHJA.js} +48 -42
  2. package/{action-Q4W5JPI5.js → action-ORXWW2ZG.js} +8 -8
  3. package/{addContentAction-O25HFR37.js → addContentAction-53BZ34AE.js} +8 -7
  4. package/{addDialogAgentAction-GH7AUPPB.js → addDialogAgentAction-JRYUS54Y.js} +10 -9
  5. package/{agentDeleteCommand-JWIKNWWI.js → agentDeleteCommand-FJIWU2BS.js} +30 -28
  6. package/{agentEmailCommands-PL22BEU5.js → agentEmailCommands-CE32L43B.js} +57 -52
  7. package/{agentListCommands-6NR7AQEK.js → agentListCommands-VJNKULIK.js} +42 -33
  8. package/{agentMachineCommands-TASPU6OA.js → agentMachineCommands-HCJ3WQXL.js} +30 -28
  9. package/{agentRecordCommands-Z64TA63M.js → agentRecordCommands-QFWERED4.js} +55 -50
  10. package/{agentRunCommand-4QJQLPRW.js → agentRunCommand-G3GQMUNN.js} +65 -53
  11. package/{agentRunControl-4GHHSXFZ.js → agentRunControl-INKFDXDA.js} +3 -1
  12. package/{agentRuntimeLocal-PCJJ56J2.js → agentRuntimeLocal-K327ELSL.js} +30 -26
  13. package/{agentSlice-KYLDUSNN.js → agentSlice-ODKF4J6M.js} +8 -8
  14. package/{agentSuperviseCommands-VB6BUS5H.js → agentSuperviseCommands-5AR3DKNN.js} +2 -2
  15. package/{appDeleteCommands-WLHMJAVT.js → appDeleteCommands-XUXMFDI4.js} +31 -29
  16. package/{appDeployCommands-CKON7N2E.js → appDeployCommands-37F4GPCU.js} +31 -29
  17. package/{appDeployStatusCommands-PXRLDASH.js → appDeployStatusCommands-WSPU7TUK.js} +31 -29
  18. package/{appGetCommands-RAB5RM4M.js → appGetCommands-YLOBA3EM.js} +31 -29
  19. package/{appListCommands-GU57FB62.js → appListCommands-UD62R5ME.js} +31 -29
  20. package/{authCommand-QOPOEYEK.js → authCommand-OK6HLHGS.js} +13 -13
  21. package/{authCommands-SBQVTD6V.js → authCommands-2DUIUEMT.js} +2 -2
  22. package/{chatQueueReduxAdapter-5O2WLITN.js → chatQueueReduxAdapter-TV2TUOQS.js} +26 -23
  23. package/{chunk-7CH6U3FL.js → chunk-2GRGFCF6.js} +2 -4
  24. package/{chunk-T27IEBNQ.js → chunk-2QDDKFG5.js} +74 -1
  25. package/{chunk-VULELK4T.js → chunk-2WBFJHQA.js} +4 -26
  26. package/{chunk-IKTHA3JH.js → chunk-3LKZRP7E.js} +2 -2
  27. package/{chunk-INXBNYCG.js → chunk-3Y2K5O2R.js} +64 -6
  28. package/{chunk-VRZIH5JO.js → chunk-3ZTR7ZO4.js} +1 -1
  29. package/{chunk-GV35EHNA.js → chunk-5FCIPEKT.js} +262 -96
  30. package/{chunk-RTLJUGQH.js → chunk-5UAYZEXO.js} +2 -2
  31. package/{chunk-TI5BCZCH.js → chunk-6COJEAYH.js} +32 -101
  32. package/{chunk-Y7LNKP32.js → chunk-6HDYSFLO.js} +4 -6
  33. package/chunk-6IGD47IC.js +19 -0
  34. package/chunk-6YTOJY35.js +352 -0
  35. package/{chunk-6FGXGFAH.js → chunk-75MSWWUE.js} +1 -1
  36. package/{chunk-3Z3DXZBD.js → chunk-7FAS3NEF.js} +16 -16
  37. package/{chunk-AV6KQCM5.js → chunk-7NYDJAQ7.js} +19 -14
  38. package/{chunk-CVT7L2WZ.js → chunk-A65UV3M5.js} +4 -4
  39. package/{chunk-7APQB6R6.js → chunk-AUVFJGPC.js} +3 -3
  40. package/{chunk-H4RYESI6.js → chunk-BBTN4NQD.js} +4 -4
  41. package/{chunk-757BGY6Y.js → chunk-BG7J6Y5X.js} +1 -1
  42. package/chunk-BY2FF2C4.js +526 -0
  43. package/{chunk-FA4SY4F5.js → chunk-BYEJ7K2Z.js} +1 -1
  44. package/chunk-BYXBJQAS.js +0 -0
  45. package/{chunk-3AOLVADY.js → chunk-DVINR3PL.js} +1 -1
  46. package/{chunk-UITMHBVK.js → chunk-EA5OYZVD.js} +1 -1
  47. package/{chunk-4NN3EK7H.js → chunk-EICIFHVS.js} +1 -1
  48. package/chunk-EJE33XNR.js +19059 -0
  49. package/{chunk-6SZ52ORL.js → chunk-FJHMLRDQ.js} +9 -9
  50. package/{chunk-RU5D3B22.js → chunk-GRFK2XP4.js} +2 -2
  51. package/{chunk-J3UALFHL.js → chunk-HJTAGT3W.js} +1 -1
  52. package/{chunk-WL3UOGYO.js → chunk-HPW5MNDQ.js} +38 -98
  53. package/{chunk-H2G6JXTR.js → chunk-HQUORJTM.js} +1 -1
  54. package/{chunk-OYNDYVSE.js → chunk-JON2PHYT.js} +1 -1
  55. package/{chunk-7K5VMB4Q.js → chunk-JXIP6ZWH.js} +7 -7
  56. package/{chunk-KUUTWU4I.js → chunk-K4NISKOR.js} +46 -8
  57. package/{chunk-SP3DPVBH.js → chunk-KLIBF3BY.js} +2 -2
  58. package/chunk-LRGKOI5Y.js +297 -0
  59. package/{chunk-LN3OQJGG.js → chunk-MLEZPE3U.js} +2 -2
  60. package/{chunk-FGEYVPPR.js → chunk-MYMBBB6Q.js} +5 -64
  61. package/{chunk-VRJUIUIY.js → chunk-N4JKMCY3.js} +2 -2
  62. package/{chunk-U5Z7LFZF.js → chunk-NFLA6GSU.js} +4 -4
  63. package/{chunk-SVEUG45B.js → chunk-NHRQCXIQ.js} +0 -24
  64. package/{chunk-56W233KG.js → chunk-NJUQBYFJ.js} +3 -1
  65. package/{chunk-Q24S4NDF.js → chunk-Q4XZVZPN.js} +1 -1
  66. package/{chunk-UW4INMD2.js → chunk-RHMDMTDK.js} +2 -2
  67. package/{chunk-MFI4FGHX.js → chunk-SAJSBPI2.js} +1 -1
  68. package/{chunk-WHVQA7PJ.js → chunk-SSXTSPSG.js} +27 -6
  69. package/{chunk-2BWU4ORW.js → chunk-SUEIAK5N.js} +1 -1
  70. package/{chunk-3QJTD6DO.js → chunk-SVC3GGUA.js} +5 -5
  71. package/{chunk-QDHZCAH3.js → chunk-SVDMVX4G.js} +118 -2
  72. package/{chunk-GBADO3SM.js → chunk-SWJGJMTW.js} +1 -1
  73. package/{chunk-DQLYEGP7.js → chunk-SYYUU7EV.js} +2 -2
  74. package/{chunk-U2A47SVI.js → chunk-TC6P4NDR.js} +7 -7
  75. package/{chunk-V4KZGLOI.js → chunk-TR4DXUYX.js} +1983 -447
  76. package/{chunk-BANYWEYY.js → chunk-TY3ADTX5.js} +1 -1
  77. package/chunk-UAD2WT54.js +64 -0
  78. package/{chunk-PAHILFNT.js → chunk-UGBHDMHI.js} +4 -4
  79. package/{chunk-6FQ2552G.js → chunk-UOWXD4VN.js} +799 -956
  80. package/{chunk-5WADL4O7.js → chunk-UR66XPVF.js} +3 -3
  81. package/{chunk-6BYAXNH5.js → chunk-VZMUOPYG.js} +12 -2
  82. package/{chunk-LA4IDAK7.js → chunk-WQHGJHAL.js} +440 -2981
  83. package/{chunk-GLGD2JGY.js → chunk-XIJZOCSP.js} +7 -7
  84. package/{chunk-BJLYCOZK.js → chunk-YBFJQC2M.js} +93 -776
  85. package/{chunk-MRWGHF56.js → chunk-YDH3FDFQ.js} +12 -356
  86. package/{chunk-32I5RVMY.js → chunk-YLCUU3WM.js} +3 -3
  87. package/{chunk-D3JQPONH.js → chunk-YQBXOHE6.js} +1 -1
  88. package/chunk-ZJ7UHBJS.js +89 -0
  89. package/{chunk-TNPCQNGQ.js → chunk-ZVOHVJI3.js} +4 -9
  90. package/contentThunks-KNI6VXLT.js +71 -0
  91. package/{createAgentAutomationAction-UJLNFFFC.js → createAgentAutomationAction-OK4L33KF.js} +27 -23
  92. package/{createDialogAction-TJCX6GUE.js → createDialogAction-JDSMY4AY.js} +28 -24
  93. package/{createPageAction-N3IYABHV.js → createPageAction-T7RA3HCG.js} +29 -24
  94. package/{dbSlice-D5CNGWPD.js → dbSlice-TVX6SN2T.js} +6 -6
  95. package/{deleteFile-44TUM34Y.js → deleteFile-JYKRT7C3.js} +3 -3
  96. package/{dialogCommands-35M6RBAC.js → dialogCommands-UQZYWOOV.js} +32 -30
  97. package/{dialogSlice-KO7ADD7H.js → dialogSlice-TYW2G7IL.js} +26 -23
  98. package/{docCreateCommands-VXHZWQ3P.js → docCreateCommands-OA6HZBWO.js} +34 -32
  99. package/{docDeleteCommands-4WFAJR6A.js → docDeleteCommands-KBB3YQI2.js} +31 -29
  100. package/{docReadCommands-OYREEFAR.js → docReadCommands-ZLMFVC67.js} +30 -28
  101. package/{docStore-5BU76DFK.js → docStore-2URPBVCS.js} +8 -33
  102. package/{docUpdateCommands-A7QERSME.js → docUpdateCommands-HMH5KUON.js} +34 -32
  103. package/{fetchMessages-KZQVBXKY.js → fetchMessages-DRABNDPZ.js} +3 -3
  104. package/{getPricing-HAU62AFM.js → getPricing-RFOPUWHY.js} +4 -4
  105. package/{handleSendMessageAction-OSGQJQ45.js → handleSendMessageAction-GO53TY7U.js} +28 -25
  106. package/index.js +56 -56
  107. package/{localDialogRead-NQ33HBSI.js → localDialogRead-PUQKFI73.js} +1 -1
  108. package/{machineCommands-J43U3TX5.js → machineCommands-RK6L7ZWL.js} +59 -54
  109. package/{machineWsRunDispatch-Z2Z6STXZ.js → machineWsRunDispatch-3X64DW2Z.js} +54 -49
  110. package/memberThunks-THZYZFSN.js +638 -0
  111. package/{models-4QF4BJVY.js → models-JVKUEER5.js} +2 -2
  112. package/package.json +1 -1
  113. package/{read-RGNPI5H2.js → read-K4JU4MQC.js} +3 -3
  114. package/{readDocTool-6ESWKTXD.js → readDocTool-LQGR6FUN.js} +1 -1
  115. package/{readlineWorkspace-YRPV6JPN.js → readlineWorkspace-XUFJV3RS.js} +604 -263
  116. package/{removeDialogAgentAction-JYT73FU2.js → removeDialogAgentAction-ECHCFB7N.js} +12 -11
  117. package/{runAgentClientLoop-5YM5WMAY.js → runAgentClientLoop-24GQ2AW6.js} +46 -40
  118. package/{setDialogExtraReferencesAction-D564LMYQ.js → setDialogExtraReferencesAction-KCVJNGMB.js} +9 -8
  119. package/{setPrimaryDialogAgentAction-ACY3BLYA.js → setPrimaryDialogAgentAction-VDOBOMKC.js} +12 -11
  120. package/{settingSlice-MKI3MNZJ.js → settingSlice-VR2IJSXC.js} +7 -7
  121. package/{skillDiscovery-GPUDHDTZ.js → skillDiscovery-2QTZINON.js} +3 -3
  122. package/{spaceCommands-MY26V52L.js → spaceCommands-S5YJJXL7.js} +30 -28
  123. package/{streamAgentChatTurn-XV5X5TNQ.js → streamAgentChatTurn-QHKP3ABO.js} +77 -64
  124. package/{switchDialogAgentAction-CJ5H6SAR.js → switchDialogAgentAction-5L4UP7VI.js} +10 -9
  125. package/{toolApiClient-B2MFXMEG.js → toolApiClient-53U4UDFF.js} +3 -2
  126. package/{tools-MIMELA2Y.js → tools-SSXSTC3O.js} +37 -32
  127. package/{tuiSummaryLlmCaller-XJ5BKNNS.js → tuiSummaryLlmCaller-URFJHFC5.js} +17 -15
  128. package/{updateDialogTitleAction-EIZUSWHR.js → updateDialogTitleAction-YFYAEW3T.js} +28 -24
  129. package/chunk-6BGAQ3KR.js +0 -7081
  130. package/chunk-YBV6QJKM.js +0 -441
  131. package/spaceSlice-JUIXC365.js +0 -127
  132. package/{chunk-NQ4N4IGO.js → chunk-CS6TCJ7E.js} +3 -3
  133. package/{chunk-PYKV6FSC.js → chunk-XOJRZUPF.js} +3 -3
@@ -3,11 +3,12 @@ import {
3
3
  normalizeDialogRecord,
4
4
  readDialogSnapshot,
5
5
  sortDialogs
6
- } from "./chunk-GLGD2JGY.js";
6
+ } from "./chunk-XIJZOCSP.js";
7
7
  import {
8
8
  ANSI_ESCAPE_REGEX,
9
9
  COLLAPSED_PASTE_PLACEHOLDER_RE,
10
10
  THEME_PALETTES,
11
+ TUI_TREE_MARKER,
11
12
  allocateCollapsedPaste,
12
13
  applyDetectedBackground,
13
14
  applyTerminalOutputToText,
@@ -24,12 +25,15 @@ import {
24
25
  findCollapsedPasteSpanAt,
25
26
  fitAnsiLine,
26
27
  formatAssistantDisplay,
28
+ formatCreditsChip,
27
29
  formatTokenCount,
28
30
  getActiveThemeMode,
29
31
  getActiveThemeName,
30
32
  isBalanceExhaustedError,
31
- normalizeToolDisplayMode,
32
33
  padOrTruncateToWidth,
34
+ polishBreathInsertsBlankBetween,
35
+ readAgentsMdLayerFromDisk,
36
+ redactSecrets,
33
37
  releaseCollapsedPaste,
34
38
  releaseCollapsedPasteReferences,
35
39
  renderSurfaceLine,
@@ -62,30 +66,32 @@ import {
62
66
  wrapTextToLines,
63
67
  wrapTranscriptLine,
64
68
  wrapTranscriptLineWithLayout
65
- } from "./chunk-6FQ2552G.js";
69
+ } from "./chunk-UOWXD4VN.js";
70
+ import "./chunk-S7Z2HMCN.js";
71
+ import "./chunk-LYGNQHUW.js";
72
+ import "./chunk-ESHYE7WU.js";
66
73
  import {
67
74
  listFavoriteAgentIdsAcrossServers,
68
75
  listLocalCachedAgents,
69
76
  listRemoteAgents,
70
77
  listRemoteAgentsAcrossServers,
71
78
  normalizeListedAgent
72
- } from "./chunk-5WADL4O7.js";
79
+ } from "./chunk-UR66XPVF.js";
73
80
  import "./chunk-ID4G2MAR.js";
74
81
  import {
75
82
  listUserRecordsFromServers,
76
83
  readLiveDbRecordAfterTombstoneMerge
77
- } from "./chunk-Q24S4NDF.js";
78
- import "./chunk-J3UALFHL.js";
79
- import "./chunk-LYGNQHUW.js";
84
+ } from "./chunk-Q4XZVZPN.js";
80
85
  import {
86
+ RUN_WAKE_CHANNEL_ENV,
81
87
  createCliLocalRuntimeAdapter,
82
88
  initCliLocale,
83
89
  parseCliLocale,
84
90
  readTimestamp,
85
91
  setCliLocale,
86
92
  t
87
- } from "./chunk-GV35EHNA.js";
88
- import "./chunk-U5Z7LFZF.js";
93
+ } from "./chunk-5FCIPEKT.js";
94
+ import "./chunk-NFLA6GSU.js";
89
95
  import "./chunk-EADNWBAZ.js";
90
96
  import "./chunk-NI2BS6UD.js";
91
97
  import {
@@ -95,37 +101,46 @@ import {
95
101
  deleteDbRecord,
96
102
  queryUserRecords,
97
103
  readDbRecord
98
- } from "./chunk-DQLYEGP7.js";
99
- import "./chunk-OYNDYVSE.js";
104
+ } from "./chunk-SYYUU7EV.js";
105
+ import "./chunk-JON2PHYT.js";
100
106
  import {
101
107
  NOLO_DEFAULT_AGENT_KEY,
102
108
  resolveCliAgentKeyInput
103
109
  } from "./chunk-EKLRRZIN.js";
110
+ import "./chunk-HJTAGT3W.js";
111
+ import {
112
+ createChatQueueRuntime,
113
+ createTurnRequest,
114
+ normalizeRunCompletionShape
115
+ } from "./chunk-YPREESF4.js";
104
116
  import "./chunk-JDSUTNYY.js";
117
+ import "./chunk-JBTJAPUF.js";
105
118
  import {
119
+ backfillRunRecordParentDialog,
106
120
  checkStaleRun,
107
121
  isRunRecordClaimed,
108
122
  listRunRecords,
109
123
  readRunRecord
110
- } from "./chunk-WHVQA7PJ.js";
111
- import "./chunk-ESHYE7WU.js";
112
- import "./chunk-JBTJAPUF.js";
124
+ } from "./chunk-SSXTSPSG.js";
113
125
  import "./chunk-LTRXGFMS.js";
114
- import "./chunk-4NN3EK7H.js";
126
+ import "./chunk-EICIFHVS.js";
115
127
  import "./chunk-ATNTHIZI.js";
116
128
  import "./chunk-JEXVIMYZ.js";
117
129
  import {
118
130
  prepareTools
119
- } from "./chunk-UW4INMD2.js";
131
+ } from "./chunk-RHMDMTDK.js";
132
+ import {
133
+ buildResponseGuidelines
134
+ } from "./chunk-6IGD47IC.js";
120
135
  import "./chunk-HS7MLR74.js";
121
- import "./chunk-757BGY6Y.js";
122
- import "./chunk-V4KZGLOI.js";
136
+ import "./chunk-BG7J6Y5X.js";
137
+ import "./chunk-TR4DXUYX.js";
123
138
  import "./chunk-5XTOKQLW.js";
124
139
  import "./chunk-NF64D32W.js";
125
140
  import "./chunk-3L2WKC3W.js";
126
- import "./chunk-RU5D3B22.js";
141
+ import "./chunk-GRFK2XP4.js";
127
142
  import "./chunk-KQHGZWSV.js";
128
- import "./chunk-VRZIH5JO.js";
143
+ import "./chunk-3ZTR7ZO4.js";
129
144
  import {
130
145
  clipText,
131
146
  formatDuration,
@@ -137,39 +152,38 @@ import {
137
152
  runShowsLogTail,
138
153
  shortRunId
139
154
  } from "./chunk-KXKQO4Q6.js";
155
+ import "./chunk-LRGKOI5Y.js";
156
+ import "./chunk-TY3ADTX5.js";
157
+ import "./chunk-UGBHDMHI.js";
140
158
  import "./chunk-INZZJSQF.js";
141
- import "./chunk-Y7LNKP32.js";
142
- import "./chunk-BANYWEYY.js";
143
- import "./chunk-PAHILFNT.js";
144
159
  import "./chunk-MEYIRKDN.js";
145
160
  import "./chunk-63W5N6P3.js";
146
161
  import "./chunk-VF4K2QE6.js";
162
+ import "./chunk-6HDYSFLO.js";
163
+ import "./chunk-FJHMLRDQ.js";
164
+ import "./chunk-WQHGJHAL.js";
165
+ import "./chunk-ZJ7UHBJS.js";
147
166
  import {
148
- createChatQueueRuntime,
149
- createTurnRequest,
150
- normalizeRunCompletionShape
151
- } from "./chunk-YPREESF4.js";
152
- import "./chunk-6SZ52ORL.js";
153
- import "./chunk-LA4IDAK7.js";
154
- import {
155
- extractReferenceKeysFromMessage
156
- } from "./chunk-BJLYCOZK.js";
167
+ extractReferenceKeysFromMessage,
168
+ normalizeUsage
169
+ } from "./chunk-YBFJQC2M.js";
157
170
  import "./chunk-EVBFYPDC.js";
158
- import "./chunk-H2G6JXTR.js";
171
+ import "./chunk-HQUORJTM.js";
159
172
  import "./chunk-YYLHWIW6.js";
160
- import "./chunk-U2A47SVI.js";
161
173
  import "./chunk-AGGIDPCZ.js";
162
- import "./chunk-32I5RVMY.js";
174
+ import "./chunk-TC6P4NDR.js";
175
+ import "./chunk-YLCUU3WM.js";
163
176
  import "./chunk-5RGU3J7P.js";
177
+ import "./chunk-6YTOJY35.js";
164
178
  import "./chunk-M76ECQRD.js";
165
- import "./chunk-MRWGHF56.js";
179
+ import "./chunk-YDH3FDFQ.js";
166
180
  import "./chunk-URMS4XY2.js";
167
181
  import "./chunk-IA3A5373.js";
168
182
  import "./chunk-GLKOYSRU.js";
169
183
  import {
170
184
  buildSkillDiscoveryContextBlock,
171
185
  buildSkillDiscoveryContextLayer
172
- } from "./chunk-2BWU4ORW.js";
186
+ } from "./chunk-SUEIAK5N.js";
173
187
  import "./chunk-AA564GBL.js";
174
188
  import {
175
189
  expandEnabledPacks
@@ -180,23 +194,23 @@ import {
180
194
  buildLocalWorkspaceToolset,
181
195
  getProcessRegistry,
182
196
  readCommandActionGatePayload
183
- } from "./chunk-6BGAQ3KR.js";
184
- import "./chunk-INXBNYCG.js";
197
+ } from "./chunk-EJE33XNR.js";
185
198
  import "./chunk-ZNFJWEN4.js";
186
- import "./chunk-CVT7L2WZ.js";
187
- import "./chunk-T27IEBNQ.js";
199
+ import "./chunk-3Y2K5O2R.js";
200
+ import "./chunk-A65UV3M5.js";
201
+ import "./chunk-2QDDKFG5.js";
188
202
  import "./chunk-N7J63Q6C.js";
189
203
  import {
190
204
  buildCurrentTimeBlock,
191
205
  buildIdentityBlock,
192
206
  buildRuntimeGuidanceBlocks,
193
207
  resolveToolGuidedSections
194
- } from "./chunk-YBV6QJKM.js";
195
- import "./chunk-6BYAXNH5.js";
208
+ } from "./chunk-BY2FF2C4.js";
209
+ import "./chunk-VZMUOPYG.js";
196
210
  import {
197
211
  resolvePlatformAuthToken
198
- } from "./chunk-SP3DPVBH.js";
199
- import "./chunk-TNPCQNGQ.js";
212
+ } from "./chunk-KLIBF3BY.js";
213
+ import "./chunk-ZVOHVJI3.js";
200
214
  import {
201
215
  isQuotaExhaustedError
202
216
  } from "./chunk-IWUMSAQF.js";
@@ -204,7 +218,7 @@ import "./chunk-2MBTWINN.js";
204
218
  import {
205
219
  DEFAULT_CONTEXT_WINDOW,
206
220
  getModelContextWindow
207
- } from "./chunk-KUUTWU4I.js";
221
+ } from "./chunk-K4NISKOR.js";
208
222
  import {
209
223
  buildCompactionMetricsFromPlan,
210
224
  buildCompactionUserContent,
@@ -215,32 +229,32 @@ import {
215
229
  formatMessagesForSummaryWithTruncation,
216
230
  planCompression,
217
231
  serializeMessageContent
218
- } from "./chunk-H4RYESI6.js";
219
- import "./chunk-VRJUIUIY.js";
220
- import "./chunk-NQ4N4IGO.js";
221
- import "./chunk-FD36SCCD.js";
222
- import "./chunk-QDHZCAH3.js";
232
+ } from "./chunk-BBTN4NQD.js";
233
+ import "./chunk-N4JKMCY3.js";
234
+ import "./chunk-BYXBJQAS.js";
235
+ import "./chunk-SVDMVX4G.js";
223
236
  import {
224
237
  compactWhitespace
225
238
  } from "./chunk-DWLEOOGR.js";
239
+ import "./chunk-CS6TCJ7E.js";
240
+ import "./chunk-FD36SCCD.js";
226
241
  import "./chunk-ZHXJ6M7T.js";
227
242
  import {
228
243
  toErrorMessage
229
244
  } from "./chunk-HNMXYYJR.js";
230
245
  import {
231
- buildAgentsMdLayer,
232
246
  buildMemoryOverlayLayer,
233
247
  buildMemoryUseGuidanceLayer,
234
248
  partitionScopedBlocks,
235
249
  renderTurnContextBlocksWithScope
236
- } from "./chunk-3AOLVADY.js";
250
+ } from "./chunk-DVINR3PL.js";
237
251
  import {
238
252
  buildUserResponseLanguageContext
239
- } from "./chunk-7CH6U3FL.js";
253
+ } from "./chunk-2GRGFCF6.js";
240
254
  import {
241
255
  canonicalizeToolNames
242
256
  } from "./chunk-O6OSWFZQ.js";
243
- import "./chunk-FA4SY4F5.js";
257
+ import "./chunk-BYEJ7K2Z.js";
244
258
  import {
245
259
  checkForCliUpdate,
246
260
  runSelfUpdateDetailed
@@ -265,19 +279,20 @@ import {
265
279
  import {
266
280
  DEFAULT_NOLO_SERVER_URL
267
281
  } from "./chunk-OLZBQWZU.js";
268
- import "./chunk-56W233KG.js";
269
- import "./chunk-WL3UOGYO.js";
270
- import "./chunk-7APQB6R6.js";
271
- import "./chunk-3QJTD6DO.js";
282
+ import "./chunk-NJUQBYFJ.js";
283
+ import "./chunk-HPW5MNDQ.js";
284
+ import "./chunk-AUVFJGPC.js";
285
+ import "./chunk-SVC3GGUA.js";
272
286
  import "./chunk-Y5GCAMGP.js";
273
287
  import "./chunk-UZ6XXCVR.js";
274
288
  import "./chunk-KX6YBIHG.js";
275
- import "./chunk-FGEYVPPR.js";
276
- import "./chunk-AV6KQCM5.js";
277
- import "./chunk-SVEUG45B.js";
289
+ import "./chunk-MYMBBB6Q.js";
290
+ import "./chunk-UAD2WT54.js";
291
+ import "./chunk-7NYDJAQ7.js";
292
+ import "./chunk-NHRQCXIQ.js";
278
293
  import "./chunk-WWC7I6TA.js";
279
294
  import "./chunk-I42VC5KR.js";
280
- import "./chunk-MFI4FGHX.js";
295
+ import "./chunk-SAJSBPI2.js";
281
296
  import {
282
297
  asTrimmedLowercaseString
283
298
  } from "./chunk-QSJ3HFEF.js";
@@ -286,18 +301,18 @@ import {
286
301
  BUILTIN_NOLO_AGENT_MODEL,
287
302
  BUILTIN_NOLO_AGENT_NAME,
288
303
  builtinAgentCatalogEntryById
289
- } from "./chunk-VULELK4T.js";
304
+ } from "./chunk-2WBFJHQA.js";
290
305
  import {
291
306
  extractCustomId,
292
307
  parsePublicAgentId
293
308
  } from "./chunk-BJIRLHJR.js";
294
- import "./chunk-PYKV6FSC.js";
309
+ import "./chunk-XOJRZUPF.js";
295
310
  import "./chunk-QOKAKDPE.js";
296
311
  import "./chunk-OW765XBU.js";
297
312
  import "./chunk-GBRG75BQ.js";
298
- import "./chunk-KUG52IAP.js";
299
313
  import "./chunk-3EUW3WEO.js";
300
314
  import "./chunk-U6VC4MU4.js";
315
+ import "./chunk-KUG52IAP.js";
301
316
  import "./chunk-LCBAMY2M.js";
302
317
  import "./chunk-4SN6J65J.js";
303
318
  import "./chunk-CF7PE763.js";
@@ -1222,7 +1237,81 @@ function appendLocalTurn(history, command, output) {
1222
1237
  trimHistoryToBudget(history);
1223
1238
  resetStreamingTurnCache();
1224
1239
  }
1240
+ var TOOL_SUCCESS_LINE_RE = /^(▸ .*?)(?: ×(\d+))?( ✓)$/;
1241
+ function applyTreeRewrite(text, chunk) {
1242
+ if (!chunk.startsWith(TUI_TREE_MARKER)) return null;
1243
+ const payload = chunk.slice(TUI_TREE_MARKER.length).replace(/\u0002\n?$/, "");
1244
+ const tree = `\u2022 ${payload}`;
1245
+ const hadTrailingNewline = text.endsWith("\n");
1246
+ const body = hadTrailingNewline ? text.slice(0, -1) : text;
1247
+ const bodyLines = body.split("\n");
1248
+ const plainLines = bodyLines.map((line) => stripAnsi(line));
1249
+ const tail = plainLines.at(-1) ?? "";
1250
+ let prefix;
1251
+ if (tail.trimStart().startsWith("\u25B8 ")) {
1252
+ prefix = bodyLines.length < 2 ? "" : `${bodyLines.slice(0, -1).join("\n")}
1253
+ `;
1254
+ } else if (tail.trimStart().startsWith("\u2514\u2500\u2500 ")) {
1255
+ const headerIndex = plainLines.findLastIndex((line) => line.trimStart().startsWith("\u2022 "));
1256
+ if (headerIndex < 0) return null;
1257
+ prefix = `${bodyLines.slice(0, headerIndex).join("\n")}${headerIndex > 0 ? "\n" : ""}`;
1258
+ } else return null;
1259
+ return `${prefix}${tree}
1260
+ `;
1261
+ }
1262
+ function foldToolSuccessLine(text, chunk) {
1263
+ const plain = stripAnsi(chunk).replace(/\n+$/, "");
1264
+ if (!plain || plain.includes("\n") || !TOOL_SUCCESS_LINE_RE.test(plain)) return null;
1265
+ const hadTrailingNewline = text.endsWith("\n");
1266
+ const body = hadTrailingNewline ? text.slice(0, -1) : text;
1267
+ const newlineAt = body.lastIndexOf("\n");
1268
+ const tail = newlineAt === -1 ? body : body.slice(newlineAt + 1);
1269
+ const match = TOOL_SUCCESS_LINE_RE.exec(stripAnsi(tail));
1270
+ if (!match || `${match[1]}${match[3]}` !== plain) return null;
1271
+ const count = (match[2] ? Number(match[2]) : 1) + 1;
1272
+ const anchor = tail.lastIndexOf(" ");
1273
+ if (anchor < 0) return null;
1274
+ const head = tail.slice(0, anchor).replace(/\s×\d+$/, "");
1275
+ const merged = `${head} \xD7${count}${tail.slice(anchor)}`;
1276
+ const prefix = newlineAt === -1 ? "" : body.slice(0, newlineAt + 1);
1277
+ return `${prefix}${merged}${hadTrailingNewline ? "\n" : ""}`;
1278
+ }
1225
1279
  function applyOutputChunkToCurrentTurn(history, chunk, kind = "assistant") {
1280
+ if (kind === "tool") {
1281
+ if (chunk.startsWith(TUI_TREE_MARKER)) {
1282
+ const rewrittenTree = applyTreeRewrite(history.currentContent, chunk);
1283
+ if (rewrittenTree === null) {
1284
+ const safe = chunk.slice(TUI_TREE_MARKER.length).replace(/\u0002/g, "");
1285
+ const leaves = safe.split("\n").filter((line) => /^(?:├── |└── )/.test(line));
1286
+ const newest = leaves.at(-1)?.replace(/^(?:├── |└── )/, "\u25B8 ") ?? "";
1287
+ if (!newest) return false;
1288
+ const flat = `${newest}
1289
+ `;
1290
+ history.currentContent = applyTerminalOutputToText(history.currentContent, flat);
1291
+ appendCurrentBlock(history, kind, flat);
1292
+ return false;
1293
+ }
1294
+ const treeContent = rewrittenTree;
1295
+ history.currentContent = treeContent;
1296
+ const lastBlock = history.currentBlocks.at(-1);
1297
+ const treeLines = treeContent.split("\n");
1298
+ const treeHeaderIndex = treeLines.findIndex((line) => line.trimStart().startsWith("\u2022 "));
1299
+ const treeBlock = treeHeaderIndex >= 0 ? treeLines.slice(treeHeaderIndex).join("\n") : treeContent;
1300
+ if (lastBlock?.kind === "tool") lastBlock.content = lastBlock.content.replace(/[^\n]*$/, "") + treeBlock;
1301
+ else history.currentBlocks.push({ kind: "tool", content: treeBlock });
1302
+ return true;
1303
+ }
1304
+ const foldedContent = foldToolSuccessLine(history.currentContent, chunk);
1305
+ if (foldedContent !== null) {
1306
+ history.currentContent = foldedContent;
1307
+ const lastBlock = history.currentBlocks.at(-1);
1308
+ if (lastBlock?.kind === "tool") {
1309
+ const foldedBlock = foldToolSuccessLine(lastBlock.content, chunk);
1310
+ if (foldedBlock !== null) lastBlock.content = foldedBlock;
1311
+ }
1312
+ return true;
1313
+ }
1314
+ }
1226
1315
  const next = applyTerminalOutputToText(history.currentContent, chunk);
1227
1316
  if (next === history.currentContent) return false;
1228
1317
  history.currentContent = next;
@@ -1405,6 +1494,40 @@ var streamingTurnCache = null;
1405
1494
  function resetStreamingTurnCache() {
1406
1495
  streamingTurnCache = null;
1407
1496
  }
1497
+ function countFenceFlips(text) {
1498
+ const matches = text.match(/^[ \t]*```/gm);
1499
+ return matches ? matches.length : 0;
1500
+ }
1501
+ var HEADING_LIKE_RE = /^#{1,3} /;
1502
+ function isPipeRowLike(line) {
1503
+ const trimmed = line.trim();
1504
+ return trimmed.length > 0 && trimmed.startsWith("|");
1505
+ }
1506
+ function isSuspiciousAppend(newTail, fenceParityEven) {
1507
+ if (!fenceParityEven) return true;
1508
+ if (newTail.includes("\r")) return true;
1509
+ if (newTail.includes("```")) return true;
1510
+ if (newTail.includes("$$") || newTail.includes("\\[") || newTail.includes("\\]")) {
1511
+ return true;
1512
+ }
1513
+ if (/\n{4,}/.test(newTail)) return true;
1514
+ if (newTail.includes("\0")) return true;
1515
+ return hasPipeRowLine(newTail);
1516
+ }
1517
+ function hasPipeRowLine(text) {
1518
+ const lines = text.split("\n");
1519
+ return lines.some((line) => isPipeRowLike(line));
1520
+ }
1521
+ function isSuspiciousBoundary(committedLastLine, newTail) {
1522
+ const newlineIdx = newTail.indexOf("\n");
1523
+ const firstLine = newlineIdx === -1 ? newTail : newTail.slice(0, newlineIdx);
1524
+ if (HEADING_LIKE_RE.test(firstLine) && committedLastLine !== "") return true;
1525
+ if (HEADING_LIKE_RE.test(committedLastLine) && firstLine !== "") return true;
1526
+ if (isPipeRowLike(firstLine) || isPipeRowLike(committedLastLine)) {
1527
+ return true;
1528
+ }
1529
+ return polishBreathInsertsBlankBetween(committedLastLine, firstLine);
1530
+ }
1408
1531
  function renderPrefixTurnBlock(role, content, contentWidth, colorEnabled) {
1409
1532
  content = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
1410
1533
  if (role === "user") {
@@ -1447,62 +1570,94 @@ function renderTailTurnBlock(role, content, contentWidth, colorEnabled) {
1447
1570
  }
1448
1571
  }
1449
1572
  function getStreamingTurnLines(role, content, contentWidth, colorEnabled, themeFingerprint) {
1450
- if (streamingTurnCache && (streamingTurnCache.role !== role || streamingTurnCache.contentWidth !== contentWidth || streamingTurnCache.colorEnabled !== colorEnabled || streamingTurnCache.themeFingerprint !== themeFingerprint || !content.startsWith(streamingTurnCache.fullContent.slice(0, streamingTurnCache.prefixLength)))) {
1451
- streamingTurnCache = null;
1452
- }
1453
- if (!streamingTurnCache) {
1454
- streamingTurnCache = {
1455
- role,
1456
- contentWidth,
1457
- colorEnabled,
1458
- themeFingerprint,
1459
- fullContent: content,
1460
- prefixLength: 0,
1461
- prefixLines: [],
1462
- lastValidatedCut: 0
1463
- };
1464
- }
1465
- if (content.length > streamingTurnCache.fullContent.length) {
1466
- let searchPos = streamingTurnCache.prefixLength;
1467
- let candidateCut = -1;
1468
- while (true) {
1469
- const idx = content.indexOf("\n\n", searchPos);
1470
- if (idx === -1) break;
1471
- const cut = idx + 1;
1472
- searchPos = idx + 2;
1473
- const prefixSub = content.slice(0, cut);
1474
- const fenceCount = (prefixSub.match(/^```/gm) || []).length;
1475
- if (fenceCount % 2 === 0) {
1476
- candidateCut = cut;
1477
- break;
1478
- }
1479
- }
1480
- if (candidateCut > streamingTurnCache.prefixLength) {
1481
- const candidatePrefix = content.slice(0, candidateCut);
1482
- const candidateTail = content.slice(candidateCut);
1483
- const candPrefixLines = renderPrefixTurnBlock(role, candidatePrefix, contentWidth, colorEnabled);
1484
- const candTailLines = renderTailTurnBlock(role, candidateTail, contentWidth, colorEnabled);
1485
- const candCombined = [...candPrefixLines, ...candTailLines];
1486
- if (candidateCut !== streamingTurnCache.lastValidatedCut) {
1487
- const fullCheckLines = renderTurnBlock(role, content, contentWidth, colorEnabled);
1488
- const sameLines = candCombined.length === fullCheckLines.length && candCombined.every((line, index) => line === fullCheckLines[index]);
1489
- streamingTurnCache.lastValidatedCut = candidateCut;
1490
- if (sameLines) {
1491
- streamingTurnCache.prefixLength = candidateCut;
1492
- streamingTurnCache.prefixLines = candPrefixLines;
1493
- }
1494
- }
1495
- streamingTurnCache.fullContent = content;
1496
- } else {
1497
- streamingTurnCache.fullContent = content;
1498
- }
1499
- }
1500
- if (streamingTurnCache.prefixLength === 0) {
1501
- return renderTurnBlock(role, content, contentWidth, colorEnabled);
1573
+ const forceValidate = process.env.NOLO_TUI_RENDER_VALIDATE === "1";
1574
+ let cache = streamingTurnCache;
1575
+ const geometryChanged = !cache || cache.role !== role || cache.contentWidth !== contentWidth || cache.colorEnabled !== colorEnabled || cache.themeFingerprint !== themeFingerprint;
1576
+ if (geometryChanged || !content.startsWith(cache.fullContent)) {
1577
+ return rebuildStreamingCache(content, role, contentWidth, colorEnabled, themeFingerprint);
1578
+ }
1579
+ if (content === cache.fullContent && cache.lastResult) {
1580
+ return cache.lastResult;
1581
+ }
1582
+ const suffix = content.slice(cache.fullContent.length);
1583
+ if (suffix === "") {
1584
+ return cache.lastResult ?? cache.committedLines;
1585
+ }
1586
+ const renderFull = () => {
1587
+ const lines = renderTurnBlock(role, content, contentWidth, colorEnabled);
1588
+ cache.fullContent = content;
1589
+ cache.fenceFlips = countFenceFlips(content);
1590
+ const lastNewline = content.lastIndexOf("\n");
1591
+ cache.completeContentLength = lastNewline + 1;
1592
+ cache.committedLines = lastNewline === -1 ? [] : renderTurnBlock(role, content.slice(0, lastNewline), contentWidth, colorEnabled);
1593
+ cache.pendingTail = content.slice(lastNewline + 1);
1594
+ cache.committedLastLine = lastNewline === -1 ? "" : lastLogicalLineOf(content.slice(0, lastNewline + 1));
1595
+ cache.lastResult = lines;
1596
+ return lines;
1597
+ };
1598
+ const newTail = cache.pendingTail + suffix;
1599
+ if (!cache.fastPathEnabled || isSuspiciousAppend(newTail, cache.fenceFlips % 2 === 0) || isSuspiciousBoundary(cache.committedLastLine, newTail)) {
1600
+ return renderFull();
1601
+ }
1602
+ const tailRenderer = cache.completeContentLength === 0 ? renderPrefixTurnBlock : renderTailTurnBlock;
1603
+ const tailLines = tailRenderer(role, newTail, contentWidth, colorEnabled);
1604
+ const composed = cache.completeContentLength === 0 ? tailLines : [...cache.committedLines, ...tailLines];
1605
+ if (!cache.spliceValidated || forceValidate) {
1606
+ const full = renderTurnBlock(role, content, contentWidth, colorEnabled);
1607
+ cache.spliceValidated = true;
1608
+ if (composed.length === full.length && composed.every((line, index) => line === full[index])) {
1609
+ commitCompletedTail(cache, content, newTail, role, contentWidth, colorEnabled);
1610
+ cache.lastResult = composed;
1611
+ return composed;
1612
+ }
1613
+ cache.fastPathEnabled = false;
1614
+ return renderFull();
1615
+ }
1616
+ commitCompletedTail(cache, content, newTail, role, contentWidth, colorEnabled);
1617
+ cache.lastResult = composed;
1618
+ return composed;
1619
+ }
1620
+ function lastLogicalLineOf(content) {
1621
+ const trimmed = content.replace(/\n$/, "");
1622
+ const idx = trimmed.lastIndexOf("\n");
1623
+ return idx === -1 ? trimmed : trimmed.slice(idx + 1);
1624
+ }
1625
+ function rebuildStreamingCache(content, role, contentWidth, colorEnabled, themeFingerprint) {
1626
+ const lines = renderTurnBlock(role, content, contentWidth, colorEnabled);
1627
+ const lastNewline = content.lastIndexOf("\n");
1628
+ streamingTurnCache = {
1629
+ role,
1630
+ contentWidth,
1631
+ colorEnabled,
1632
+ themeFingerprint,
1633
+ fullContent: content,
1634
+ // committed 渲染源剥掉段尾 \n(幽灵空行修正,见 renderFull 注释)。
1635
+ committedLines: lastNewline === -1 ? [] : renderTurnBlock(role, content.slice(0, lastNewline), contentWidth, colorEnabled),
1636
+ completeContentLength: lastNewline + 1,
1637
+ pendingTail: content.slice(lastNewline + 1),
1638
+ fenceFlips: countFenceFlips(content),
1639
+ committedLastLine: lastNewline === -1 ? "" : lastLogicalLineOf(content.slice(0, lastNewline + 1)),
1640
+ fastPathEnabled: true,
1641
+ spliceValidated: false,
1642
+ lastResult: lines
1643
+ };
1644
+ return lines;
1645
+ }
1646
+ function commitCompletedTail(cache, content, newTail, role, contentWidth, colorEnabled) {
1647
+ const lastNewline = newTail.lastIndexOf("\n");
1648
+ if (lastNewline !== -1) {
1649
+ const completePart = newTail.slice(0, lastNewline + 1);
1650
+ const renderSource = completePart.slice(0, -1);
1651
+ const renderer = cache.completeContentLength === 0 ? renderPrefixTurnBlock : renderTailTurnBlock;
1652
+ cache.committedLines.push(
1653
+ ...renderer(role, renderSource, contentWidth, colorEnabled)
1654
+ );
1655
+ cache.completeContentLength += completePart.length;
1656
+ cache.fenceFlips += countFenceFlips(completePart);
1657
+ cache.committedLastLine = lastLogicalLineOf(completePart);
1658
+ cache.pendingTail = newTail.slice(lastNewline + 1);
1502
1659
  }
1503
- const tailContent = content.slice(streamingTurnCache.prefixLength);
1504
- const tailLines = renderTailTurnBlock(role, tailContent, contentWidth, colorEnabled);
1505
- return [...streamingTurnCache.prefixLines, ...tailLines];
1660
+ cache.fullContent = content;
1506
1661
  }
1507
1662
  function countTurnLines(role, content, contentWidth, command) {
1508
1663
  return layoutTurnRows(role, content, contentWidth, false, command).length;
@@ -1737,6 +1892,7 @@ function createHistoryOutputStream(history, onUpdate) {
1737
1892
  const stream = {
1738
1893
  isTTY: true,
1739
1894
  assistantLabelManaged: true,
1895
+ tuiTrees: true,
1740
1896
  write(chunk) {
1741
1897
  const text = typeof chunk === "string" ? chunk : chunk.toString();
1742
1898
  if (applyOutputChunkToCurrentTurn(history, text)) {
@@ -1745,9 +1901,9 @@ function createHistoryOutputStream(history, onUpdate) {
1745
1901
  return true;
1746
1902
  },
1747
1903
  writeToolBlock(chunk) {
1748
- if (applyOutputChunkToCurrentTurn(history, chunk, "tool")) {
1749
- onUpdate();
1750
- }
1904
+ const applied = applyOutputChunkToCurrentTurn(history, chunk, "tool");
1905
+ if (applied) onUpdate();
1906
+ return applied;
1751
1907
  }
1752
1908
  };
1753
1909
  return stream;
@@ -1810,6 +1966,14 @@ function resolveDialogBottomRow(args) {
1810
1966
  return Math.max(1, resolveTtyRows(args.output) - args.inputLines);
1811
1967
  }
1812
1968
  function createDialogHost(args) {
1969
+ let keyboardClaimed = false;
1970
+ const claimKeyboard = () => {
1971
+ keyboardClaimed = true;
1972
+ };
1973
+ const releaseKeyboard = () => {
1974
+ args.drainDecoder?.();
1975
+ keyboardClaimed = false;
1976
+ };
1813
1977
  return {
1814
1978
  async run(body) {
1815
1979
  const anchor = {
@@ -1819,14 +1983,25 @@ function createDialogHost(args) {
1819
1983
  inputLines: args.composer.getInputLines()
1820
1984
  })
1821
1985
  };
1986
+ claimKeyboard();
1822
1987
  args.composer.pause();
1823
1988
  try {
1824
1989
  return await body(anchor);
1825
1990
  } finally {
1826
1991
  resetHistoryFrameDiffCache(args.output);
1827
1992
  args.composer.resumeFromDialog();
1993
+ releaseKeyboard();
1828
1994
  }
1829
- }
1995
+ },
1996
+ async withKeyboard(body) {
1997
+ claimKeyboard();
1998
+ try {
1999
+ return await body();
2000
+ } finally {
2001
+ releaseKeyboard();
2002
+ }
2003
+ },
2004
+ isKeyboardClaimed: () => keyboardClaimed
1830
2005
  };
1831
2006
  }
1832
2007
 
@@ -1852,13 +2027,14 @@ function formatUnassignedFact(snapshot) {
1852
2027
  }
1853
2028
  function sanitizeRunSnapshotForNormal(snapshot) {
1854
2029
  const clean = (value) => stripAnsi(value).replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
2030
+ const errorMessage = snapshot.errorMessage?.trim() ? redactSecrets(clean(snapshot.errorMessage)) : void 0;
1855
2031
  return {
1856
2032
  ...snapshot,
1857
2033
  agentName: snapshot.agentName ? clean(snapshot.agentName) : snapshot.agentName,
1858
2034
  taskPreview: snapshot.taskPreview ? clean(snapshot.taskPreview) : snapshot.taskPreview,
1859
2035
  lastAssistantText: snapshot.lastAssistantText ? clean(snapshot.lastAssistantText) : snapshot.lastAssistantText,
1860
2036
  lastToolNames: snapshot.lastToolNames?.map(clean).filter(Boolean),
1861
- errorMessage: void 0,
2037
+ errorMessage,
1862
2038
  logLines: void 0
1863
2039
  };
1864
2040
  }
@@ -1899,9 +2075,10 @@ function formatAgentRunPanelLines(snapshot, colorEnabled, now = Date.now()) {
1899
2075
  const progressPart = formatPanelProgress(snapshot, now);
1900
2076
  const age = formatTerminalRunAge(snapshot, now);
1901
2077
  const agePart = age ? ` \xB7 ${age}` : "";
2078
+ const creditsPart = typeof snapshot.credits === "number" && Number.isFinite(snapshot.credits) ? ` \xB7 ${formatCreditsChip(snapshot.credits)}` : "";
1902
2079
  if (!colorEnabled) {
1903
2080
  lines.push(
1904
- `\u{1F916} Sub-Agent: ${name}${runId} \xB7 ${statusSymbol} ${status}${unassignedPart}${agePart}${progressPart}${errPart}`
2081
+ `\u{1F916} Sub-Agent: ${name}${runId} \xB7 ${statusSymbol} ${status}${unassignedPart}${agePart}${progressPart}${creditsPart}${errPart}`
1905
2082
  );
1906
2083
  } else {
1907
2084
  const botIcon = themeText("\u{1F916}", "accent", true);
@@ -1911,8 +2088,9 @@ function formatAgentRunPanelLines(snapshot, colorEnabled, now = Date.now()) {
1911
2088
  const unassignedText = unassignedPart ? themeText(unassignedPart, "muted") : "";
1912
2089
  const ageText = agePart ? themeText(agePart, "chrome") : "";
1913
2090
  const progressText = progressPart ? themeText(progressPart, "chrome") : "";
2091
+ const creditsText = creditsPart ? themeText(creditsPart, "muted") : "";
1914
2092
  const errorText = errPart ? themeText(errPart, "danger") : "";
1915
- lines.push(`${botIcon}${labelText}${nameText}${statusText}${unassignedText}${ageText}${progressText}${errorText}`);
2093
+ lines.push(`${botIcon}${labelText}${nameText}${statusText}${unassignedText}${ageText}${progressText}${creditsText}${errorText}`);
1916
2094
  }
1917
2095
  const detail = formatPanelDetail(snapshot);
1918
2096
  if (detail) {
@@ -2036,8 +2214,7 @@ function createRunDock(deps) {
2036
2214
  const ordered = orderedEntries();
2037
2215
  if (ordered.length === 0) return [];
2038
2216
  const at = now();
2039
- const mode = typeof deps.displayMode === "function" ? deps.displayMode() : deps.displayMode;
2040
- const displaySnapshots = mode === "normal" || mode === "hide" ? ordered.map((entry) => sanitizeRunSnapshotForNormal(entry.snapshot)) : ordered.map((entry) => entry.snapshot);
2217
+ const displaySnapshots = ordered.map((entry) => sanitizeRunSnapshotForNormal(entry.snapshot));
2041
2218
  if (displaySnapshots.length === 1) {
2042
2219
  return formatAgentRunPanelLines(displaySnapshots[0], colorEnabled, at);
2043
2220
  }
@@ -2109,6 +2286,9 @@ function formatRunDockRow(snapshot, colorEnabled, now) {
2109
2286
  if (typeof snapshot.toolCallCount === "number" && Number.isFinite(snapshot.toolCallCount)) {
2110
2287
  facts.push(`${snapshot.toolCallCount} tools`);
2111
2288
  }
2289
+ if (typeof snapshot.credits === "number" && Number.isFinite(snapshot.credits)) {
2290
+ facts.push(formatCreditsChip(snapshot.credits, { compact: true }));
2291
+ }
2112
2292
  const inFlight = activeInFlight(snapshot);
2113
2293
  if (inFlight) {
2114
2294
  facts.push(formatInFlightFact(inFlight, now));
@@ -2211,8 +2391,7 @@ function createActivityIndicator(deps) {
2211
2391
  onRepaint: deps.onRepaint,
2212
2392
  now,
2213
2393
  setIntervalFn,
2214
- clearIntervalFn,
2215
- displayMode: deps.displayMode
2394
+ clearIntervalFn
2216
2395
  });
2217
2396
  const updateAgentRun = (snapshot) => {
2218
2397
  runDock.update(snapshot);
@@ -2296,6 +2475,8 @@ function snapshotFromRunRecord(record, now) {
2296
2475
  ...startedAt !== void 0 ? { startedAt } : {},
2297
2476
  ...endedAt !== void 0 ? { finishedAt: endedAt } : {},
2298
2477
  ...typeof counters?.toolCalls === "number" ? { toolCallCount: counters.toolCalls } : {},
2478
+ // 收尾自报的平台积分 → dock 行「⚡ x.xx 积分」。
2479
+ ...typeof record.credits === "number" && Number.isFinite(record.credits) ? { credits: record.credits } : {},
2299
2480
  // note 在终态时是死因("orphaned: process gone…"),非终态时只是备注。
2300
2481
  ...record.note && isAgentRunTerminalStatus(record.status) ? { errorMessage: record.note } : {},
2301
2482
  inFlight,
@@ -2310,6 +2491,7 @@ function fingerprint(snapshot) {
2310
2491
  snapshot.toolCallCount ?? -1,
2311
2492
  snapshot.errorMessage ?? "",
2312
2493
  snapshot.finishedAt ?? 0,
2494
+ snapshot.credits ?? -1,
2313
2495
  snapshot.inFlight ? [snapshot.inFlight.kind, snapshot.inFlight.name, snapshot.inFlight.startedAt] : null
2314
2496
  ]);
2315
2497
  }
@@ -3726,6 +3908,12 @@ function renderComposerTokenChip(tokens, fallbackContextWindow, estimatedContext
3726
3908
  const pctText = pct > 0 && pct < 10 ? pct.toFixed(1) : Math.round(pct).toString();
3727
3909
  return `context: ${pctText}% (${formatTokenCount(used)}/${formatTokenCount(cw)})`;
3728
3910
  }
3911
+ function resolveStatusLineCredits(state) {
3912
+ const base = state.dialogCreditsBase;
3913
+ const session = state.sessionCredits;
3914
+ if (base === void 0 && session === void 0) return void 0;
3915
+ return (base ?? 0) + (session ?? 0);
3916
+ }
3729
3917
  function renderStatusLine(state, maxWidth) {
3730
3918
  const colorEnabled = resolveCliColorEnabled();
3731
3919
  const sep = themeText(" \xB7 ", "chrome", colorEnabled);
@@ -3742,18 +3930,19 @@ function renderStatusLine(state, maxWidth) {
3742
3930
  const untrackedText = untracked > 0 ? ` ${themeText(`?${untracked}`, "muted", colorEnabled)}` : "";
3743
3931
  parts.push(`${branchText}${modifiedText}${untrackedText}`);
3744
3932
  }
3745
- const credits = state.apiSource === "platform" ? state.dialogTotalCredits ?? state.turnTokens?.credits : void 0;
3746
- const creditsSuffix = credits !== void 0 && credits > 0 ? ` \xB7 \u26A1 ${credits.toFixed(2)} \u79EF\u5206` : "";
3933
+ const credits = resolveStatusLineCredits(state);
3747
3934
  const tokenSegment = themeText(
3748
3935
  renderComposerTokenChip(
3749
3936
  state.turnTokens,
3750
3937
  state.contextWindow,
3751
3938
  state.estimatedContextTokens
3752
- ) + creditsSuffix,
3939
+ ),
3753
3940
  "muted",
3754
3941
  colorEnabled
3755
3942
  );
3943
+ const creditsSegment = credits !== void 0 && credits > 0 ? themeText(formatCreditsChip(credits), "muted", colorEnabled) : "";
3756
3944
  parts.push(tokenSegment);
3945
+ if (creditsSegment) parts.push(creditsSegment);
3757
3946
  const runningTaskCount = getProcessRegistry().listBackground().filter((p) => p.status === "running").length;
3758
3947
  if (runningTaskCount > 0) {
3759
3948
  parts.push(themeText(`\u2699 ${runningTaskCount} running`, "info", colorEnabled));
@@ -3764,7 +3953,8 @@ function renderStatusLine(state, maxWidth) {
3764
3953
  let visibleParts = parts;
3765
3954
  if (maxWidth && maxWidth > 0) {
3766
3955
  const widthOf = (segments) => displayWidth(stripAnsi(segments.join(" \xB7 "))) + 2;
3767
- for (const optional of [tokenSegment, cwdSegment, agentSegment]) {
3956
+ for (const optional of [cwdSegment, agentSegment, tokenSegment, creditsSegment]) {
3957
+ if (!optional) continue;
3768
3958
  if (widthOf(visibleParts) <= maxWidth) break;
3769
3959
  visibleParts = visibleParts.filter((part) => part !== optional);
3770
3960
  }
@@ -3797,6 +3987,9 @@ function renderStatusLine(state, maxWidth) {
3797
3987
  colorEnabled
3798
3988
  ));
3799
3989
  }
3990
+ if (creditsSegment) {
3991
+ emergency.push(themeText(formatCreditsChip(credits ?? 0, { compact: true }), "muted", colorEnabled));
3992
+ }
3800
3993
  visibleParts = [emergency.join(" ")];
3801
3994
  }
3802
3995
  }
@@ -3927,6 +4120,20 @@ function renderTuiHelp(colorEnabled = resolveCliColorEnabled()) {
3927
4120
  return themeText(line, "muted", colorEnabled);
3928
4121
  }).join("\n");
3929
4122
  }
4123
+ function renderCreditsDebug(state, colorEnabled = resolveCliColorEnabled()) {
4124
+ const credits = resolveStatusLineCredits(state);
4125
+ const lines = [
4126
+ "[credits debug] \u79EF\u5206\u94FE\u8DEF\u771F\u503C",
4127
+ `\u2022 dialogCreditsBase : ${state.dialogCreditsBase?.toFixed(4) ?? "undefined\uFF08\u670D\u52A1\u7AEF\u57FA\u6570\u672A seed\u2014\u2014/pick \u540E\u9996\u6B21\u8BFB\u53D6\u5931\u8D25\u6216\u670D\u52A1\u7AEF\u672A\u5199 totalCost\uFF09"}`,
4128
+ `\u2022 sessionCredits : ${state.sessionCredits?.toFixed(4) ?? "undefined\uFF08\u672C\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u5E73\u53F0\u8BA1\u8D39\u8F6E\uFF09"}`,
4129
+ `\u2022 \u72B6\u6001\u884C\u663E\u793A : ${credits !== void 0 && credits > 0 ? formatCreditsChip(credits) : "\uFF08\u65E0 \u26A1\u2014\u2014\u4E24\u6BB5\u5408\u8BA1\u4E3A 0/undefined\uFF09"}`,
4130
+ `\u2022 turnTokens.credits: ${state.turnTokens?.credits?.toFixed(4) ?? "undefined"}\uFF08\u672C\u8F6E\u6700\u540E\u4E00\u6B21\u8C03\u7528\u7684\u6298\u7B97\u503C\uFF0C\u4EC5\u4F9B\u53C2\u8003\uFF0C\u4E0D\u8FDB\u72B6\u6001\u884C\uFF09`,
4131
+ `\u2022 contextWindow : ${state.contextWindow ?? "unknown"}`,
4132
+ '\u2022 \u5224\u5B9A\u53E3\u5F84\uFF1A\u53EA\u6709 billing_unit === "credits" \u7684\u5E73\u53F0\u8BA1\u8D39\u5E27\u624D\u7D2F\u8BA1\uFF1B\u81EA\u6709 API / \u8BA2\u9605\u5236\u6052\u4E3A undefined\u3002',
4133
+ "\u2022 \u82E5\u521A\u8DD1\u5B8C\u5E73\u53F0\u8BA1\u8D39\u8F6E\u4ECD\u65E0 \u26A1\uFF1A\u68C0\u67E5 runAgentTurn \u8FD4\u56DE\u662F\u5426\u5E26 turnCredits\uFF08foldLocalResultForTui \u767D\u540D\u5355\uFF09\u3002"
4134
+ ];
4135
+ return lines.map((line) => colorEnabled ? themeText(line, "chrome") : line).join("\n");
4136
+ }
3930
4137
  function renderContextPanel(state, colorEnabled = resolveCliColorEnabled()) {
3931
4138
  const docs = state.attachedDocs.length ? state.attachedDocs.join(", ") : "none";
3932
4139
  const skills = state.attachedSkills.length ? state.attachedSkills.join(", ") : "none";
@@ -3938,7 +4145,6 @@ function renderContextPanel(state, colorEnabled = resolveCliColorEnabled()) {
3938
4145
  t("contextFieldSkills"),
3939
4146
  t("contextFieldProfile"),
3940
4147
  t("contextFieldRuntime"),
3941
- t("contextFieldTools"),
3942
4148
  t("contextFieldServer")
3943
4149
  ];
3944
4150
  let maxW = 0;
@@ -3968,8 +4174,7 @@ function renderContextPanel(state, colorEnabled = resolveCliColorEnabled()) {
3968
4174
  field(labels[4], skills),
3969
4175
  field(labels[5], state.profileName),
3970
4176
  field(labels[6], state.runtimeMode),
3971
- field(labels[7], state.toolDisplay),
3972
- field(labels[8], state.serverUrl),
4177
+ field(labels[7], state.serverUrl),
3973
4178
  "",
3974
4179
  themeText(t("contextNext"), "chrome", colorEnabled),
3975
4180
  next("/agents ", ` ${t("contextNextAgents")}`),
@@ -4226,6 +4431,7 @@ var SLASH_COMMANDS = [
4226
4431
  "/theme",
4227
4432
  "/context",
4228
4433
  "/ctx",
4434
+ "/credits",
4229
4435
  "/cd",
4230
4436
  "/runtime",
4231
4437
  "/auto",
@@ -4395,7 +4601,6 @@ async function runAgentPicker(args) {
4395
4601
  name: selected.name,
4396
4602
  key: selected.key,
4397
4603
  model: selected.model,
4398
- apiSource: selected.apiSource ?? (selected.kind === "platform" ? "platform" : void 0),
4399
4604
  entries
4400
4605
  };
4401
4606
  }
@@ -4407,10 +4612,7 @@ function resolveAgentSwitchTarget(rawTarget, catalogEntries = []) {
4407
4612
  return {
4408
4613
  name: aliasEntry?.name ?? asTrimmedLowercaseString(target),
4409
4614
  key: resolvedKey,
4410
- ...aliasEntry?.model ? { model: aliasEntry.model } : {},
4411
- ...aliasEntry ? {
4412
- ...aliasEntry.apiSource ? { apiSource: aliasEntry.apiSource } : aliasEntry.kind === "platform" ? { apiSource: "platform" } : {}
4413
- } : {}
4615
+ ...aliasEntry?.model ? { model: aliasEntry.model } : {}
4414
4616
  };
4415
4617
  }
4416
4618
  return findAgentCatalogEntry(catalogEntries, rawTarget);
@@ -4528,7 +4730,6 @@ function createInitialTuiState(env = process.env) {
4528
4730
  modeLabel: asOptionalTrimmedString(env.NOLO_CLI_STATUS_MODE) ?? runtimeMode,
4529
4731
  userLanguage: asOptionalTrimmedString(env.NOLO_LANG),
4530
4732
  gitStatus: void 0,
4531
- toolDisplay: normalizeToolDisplayMode(env.NOLO_CLI_TOOLS ?? env.NOLO_TOOLS, "normal"),
4532
4733
  thinkingDisplay: resolveThinkingDisplayMode(env),
4533
4734
  contextWindow: resolveAgentContextWindow({ agentKey, agentName }),
4534
4735
  estimatedContextTokens: estimateDefaultCliContextTokens({
@@ -4536,8 +4737,7 @@ function createInitialTuiState(env = process.env) {
4536
4737
  agentKey,
4537
4738
  userLanguage: asOptionalTrimmedString(env.NOLO_LANG),
4538
4739
  ...resolveAgentModelIdentity({ agentKey, agentName })
4539
- }),
4540
- apiSource: PLATFORM_AGENTS.some((entry) => entry.key === agentKey) ? "platform" : void 0
4740
+ })
4541
4741
  };
4542
4742
  }
4543
4743
  function applyAgentSwitch(state, target) {
@@ -4558,8 +4758,7 @@ function applyAgentSwitch(state, target) {
4558
4758
  agentName: target.name,
4559
4759
  model: target.model,
4560
4760
  userLanguage: state.userLanguage
4561
- }),
4562
- apiSource: target.apiSource
4761
+ })
4563
4762
  },
4564
4763
  output: `Switched to ${target.name}. ${state.dialogId ? `Dialog kept: ${state.dialogId}` : "Dialog kept: new"}`
4565
4764
  };
@@ -4703,6 +4902,8 @@ ${t("cdUsage")}`
4703
4902
  case "/context":
4704
4903
  case "/ctx":
4705
4904
  return { nextState: state, output: renderContextPanel(state) };
4905
+ case "/credits":
4906
+ return { nextState: state, output: renderCreditsDebug(state) };
4706
4907
  case "/runtime": {
4707
4908
  if (argText !== "auto" && argText !== "local" && argText !== "server") {
4708
4909
  return {
@@ -5199,9 +5400,106 @@ function detectSystemBrightness(env = process.env, options = {}) {
5199
5400
  return null;
5200
5401
  }
5201
5402
 
5202
- // packages/cli/tui/tuiTurnRunner.ts
5203
- import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
5403
+ // packages/cli/tui/turnInjectionInbox.ts
5404
+ function appendStreamSafeNotice(history, text, deps) {
5405
+ const wasStreamingAssistant = history.currentRole === "assistant";
5406
+ if (wasStreamingAssistant && !history.currentContent) {
5407
+ history.currentRole = null;
5408
+ history.currentBlocks = [];
5409
+ }
5410
+ deps.appendLocalTurn(history, "", text);
5411
+ if (wasStreamingAssistant) deps.startTurn(history, "assistant");
5412
+ }
5413
+ function createTurnInjectionInbox() {
5414
+ let pending = [];
5415
+ let closed = false;
5416
+ return {
5417
+ push(entry) {
5418
+ if (closed) return false;
5419
+ if (!entry || typeof entry.text !== "string" || !entry.text.trim()) return false;
5420
+ pending.push(entry);
5421
+ return true;
5422
+ },
5423
+ drain() {
5424
+ if (pending.length === 0) return [];
5425
+ const taken = pending;
5426
+ pending = [];
5427
+ return taken.map((entry) => entry.text);
5428
+ },
5429
+ close() {
5430
+ closed = true;
5431
+ const remaining = pending;
5432
+ pending = [];
5433
+ return remaining;
5434
+ },
5435
+ get size() {
5436
+ return pending.length;
5437
+ },
5438
+ get closed() {
5439
+ return closed;
5440
+ }
5441
+ };
5442
+ }
5443
+
5444
+ // packages/cli/client/turnBillingAudit.ts
5445
+ import { appendFileSync, mkdirSync as mkdirSync2 } from "node:fs";
5446
+ import { homedir as homedir4 } from "node:os";
5204
5447
  import { join as join3 } from "node:path";
5448
+ function projectUsageForAudit(usage) {
5449
+ if (!usage || typeof usage !== "object") return null;
5450
+ const normalized = normalizeUsage(usage);
5451
+ const projected = {
5452
+ input_tokens: normalized.input_tokens,
5453
+ output_tokens: normalized.output_tokens,
5454
+ cache_read_input_tokens: normalized.cache_read_input_tokens,
5455
+ cache_creation_input_tokens: normalized.cache_creation_input_tokens
5456
+ };
5457
+ if (typeof usage.cost === "number" && Number.isFinite(usage.cost)) {
5458
+ projected.cost = usage.cost;
5459
+ }
5460
+ if (typeof usage.billing_unit === "string" && usage.billing_unit.trim()) {
5461
+ projected.billing_unit = usage.billing_unit;
5462
+ }
5463
+ if (typeof usage.provider_call_id === "string" && usage.provider_call_id.trim()) {
5464
+ projected.provider_call_id = usage.provider_call_id.trim();
5465
+ }
5466
+ return projected;
5467
+ }
5468
+ function resolveTurnBillingAuditLogPath(env = process.env) {
5469
+ const noloHome = env.NOLO_HOME?.trim() || join3(homedir4(), ".nolo");
5470
+ return join3(noloHome, "logs", "turn-billing.jsonl");
5471
+ }
5472
+ function appendTurnBillingAudit(input) {
5473
+ try {
5474
+ if (process.env.NOLO_TURN_BILLING_AUDIT === "0") return;
5475
+ const calls = (input.usageRecords ?? []).map((record) => {
5476
+ const usage = projectUsageForAudit(record?.usage);
5477
+ if (!usage) return null;
5478
+ return {
5479
+ ...record?.callId ? { callId: record.callId } : {},
5480
+ ...record?.model ? { model: record.model } : {},
5481
+ ...record?.provider ? { provider: record.provider } : {},
5482
+ ...usage
5483
+ };
5484
+ }).filter((call) => call !== null);
5485
+ if (calls.length === 0 && (input.turnCredits === void 0 || input.turnCredits === null)) {
5486
+ return;
5487
+ }
5488
+ const row = {
5489
+ ts: Date.now(),
5490
+ ...input.dialogId ? { dialogId: input.dialogId } : {},
5491
+ ...input.agentKey ? { agentKey: input.agentKey } : {},
5492
+ ...input.turnCredits !== void 0 && input.turnCredits !== null ? { turnCredits: input.turnCredits } : {},
5493
+ ...input.aborted ? { aborted: true } : {},
5494
+ calls
5495
+ };
5496
+ const logPath = resolveTurnBillingAuditLogPath();
5497
+ mkdirSync2(join3(logPath, ".."), { recursive: true });
5498
+ appendFileSync(logPath, `${JSON.stringify(row)}
5499
+ `);
5500
+ } catch {
5501
+ }
5502
+ }
5205
5503
 
5206
5504
  // packages/ai/tools/askChoiceState.ts
5207
5505
  function normalizeAskChoiceArgs(args) {
@@ -5980,24 +6278,6 @@ function emitTerminalBell(output) {
5980
6278
  }
5981
6279
 
5982
6280
  // packages/cli/tui/tuiTurnRunner.ts
5983
- var AGENTS_MD_MAX_BYTES = 8192;
5984
- function readAgentsMdLayer(cwd) {
5985
- for (const name of ["AGENTS.md", "CLAUDE.md"]) {
5986
- const filePath = join3(cwd, name);
5987
- if (existsSync3(filePath)) {
5988
- try {
5989
- let content = readFileSync3(filePath, "utf8").trim();
5990
- if (!content) continue;
5991
- if (Buffer.byteLength(content, "utf8") > AGENTS_MD_MAX_BYTES) {
5992
- content = Buffer.from(content, "utf8").subarray(0, AGENTS_MD_MAX_BYTES).toString("utf8") + "\n\n<!-- AGENTS.md truncated -->";
5993
- }
5994
- return buildAgentsMdLayer(content, name);
5995
- } catch {
5996
- }
5997
- }
5998
- }
5999
- return null;
6000
- }
6001
6281
  async function runAgentChat(scriptDir, state, message, env, output, agentRunner = runAgentTurn, options = {}) {
6002
6282
  const effectiveAgentKey = state.agentKey;
6003
6283
  const effectiveAgentName = state.agentName;
@@ -6042,12 +6322,16 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
6042
6322
  }
6043
6323
  }
6044
6324
  const layers = [
6045
- readAgentsMdLayer(state.cwd),
6325
+ readAgentsMdLayerFromDisk(state.cwd),
6046
6326
  // Skill discovery: scan conventional skill dirs for SKILL.md and inject an
6047
6327
  // index layer so the model knows what skills exist and can readFile them
6048
6328
  // on-demand. Mirrors agentRunCommand.ts and desktopAgentRuntimeTurnService.
6049
6329
  buildSkillDiscoveryContextLayer(state.cwd)
6050
6330
  ];
6331
+ const responseGuidelinesBlock = {
6332
+ content: buildResponseGuidelines(true),
6333
+ cacheScope: "session"
6334
+ };
6051
6335
  let memoryPromptBlock = state.cachedMemoryOverlay;
6052
6336
  if (memoryPromptBlock === void 0) {
6053
6337
  memoryPromptBlock = await resolveCliMemory({
@@ -6063,6 +6347,7 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
6063
6347
  const cwdNoticeBlocks = state.pendingCwdNotice ? [{ content: state.pendingCwdNotice, cacheScope: "turn" }] : [];
6064
6348
  const contextBlockScopes = partitionScopedBlocks([
6065
6349
  ...renderTurnContextBlocksWithScope(layers),
6350
+ responseGuidelinesBlock,
6066
6351
  ...renderTurnContextBlocksWithScope([memoryUseGuidanceLayer]),
6067
6352
  // Attached skill bodies are already self-contained sections built by
6068
6353
  // buildSkillContextBlocks; they stay turn-scope because the user can
@@ -6071,6 +6356,7 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
6071
6356
  ...renderTurnContextBlocksWithScope([memoryOverlayLayer]),
6072
6357
  ...cwdNoticeBlocks
6073
6358
  ]);
6359
+ const spawnedRunsMissingParent = [];
6074
6360
  const result = await agentRunner({
6075
6361
  agentName: effectiveAgentName,
6076
6362
  agentKey: effectiveAgentKey,
@@ -6088,10 +6374,12 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
6088
6374
  scriptDir,
6089
6375
  env: {
6090
6376
  ...env,
6091
- NOLO_LANG: state.userLanguage,
6092
- NOLO_CLI_TOOLS: state.toolDisplay
6377
+ NOLO_LANG: state.userLanguage
6378
+ },
6379
+ output: {
6380
+ ...output,
6381
+ tuiTrees: output.tuiTrees === true && typeof output.writeToolBlock === "function"
6093
6382
  },
6094
- output,
6095
6383
  showThinking: state.thinkingDisplay === "show",
6096
6384
  ...options.imageUrls && options.imageUrls.length > 0 ? { imageUrls: options.imageUrls } : {},
6097
6385
  ...options.actionGateHandler ? { actionGateHandler: options.actionGateHandler } : {},
@@ -6115,15 +6403,28 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
6115
6403
  // run-completion watcher can attribute terminal-state wakes to this
6116
6404
  // conversation.
6117
6405
  ...state.dialogId ? { parentDialogId: state.dialogId } : {},
6406
+ // 首轮无 dialogId 时的兜底:收集失归属的 spawn,turn 结束回填。
6407
+ onBackgroundRunSpawned: (runId) => {
6408
+ spawnedRunsMissingParent.push(runId);
6409
+ },
6118
6410
  ...options.activityReporter ? { activityReporter: options.activityReporter } : {}
6119
6411
  }),
6120
6412
  ...options.activityReporter ? { activityReporter: options.activityReporter } : {},
6121
6413
  // 转发 dock 订阅:runAgentTurn 的输出层靠它判断「有面板」从而抑制
6122
6414
  // transcript 的进展卡片;dock 本身也靠它接收模型轮询带回来的快照。
6123
6415
  ...options.onAgentRunStatus ? { onAgentRunStatus: options.onAgentRunStatus } : {},
6416
+ ...options.drainInjections ? { drainInjections: options.drainInjections } : {},
6124
6417
  ...skillAllowedTools !== void 0 ? { allowedToolNames: skillAllowedTools } : {},
6125
6418
  ...contextBlockScopes.length > 0 ? { contextBlockScopes } : {}
6126
6419
  });
6420
+ if (result.dialogId && spawnedRunsMissingParent.length > 0) {
6421
+ for (const runId of spawnedRunsMissingParent) {
6422
+ try {
6423
+ backfillRunRecordParentDialog(runId, result.dialogId, { env });
6424
+ } catch {
6425
+ }
6426
+ }
6427
+ }
6127
6428
  return {
6128
6429
  ...result,
6129
6430
  contextWindow: resolveAgentContextWindow({
@@ -6366,19 +6667,21 @@ async function resolveActionGate(gate, deps) {
6366
6667
  );
6367
6668
  return approved ? buildGateConfirmedResult(gate) : buildGateCancelledResult(gate, "confirmation declined");
6368
6669
  }
6369
- let subprocessRan = false;
6370
- deps.pauseComposer();
6371
- try {
6372
- return await waitForRawActionGate(deps.input, deps.output, gate, deps.spawnRunner, {
6373
- beforeSubprocess: () => {
6374
- subprocessRan = true;
6375
- },
6376
- afterSubprocess: deps.resumeComposerFromSubprocess,
6377
- registerToken: deps.registerToken
6378
- });
6379
- } finally {
6380
- if (!subprocessRan) deps.resumeComposerFromDialog();
6381
- }
6670
+ return deps.dialogHost.withKeyboard(async () => {
6671
+ let subprocessRan = false;
6672
+ deps.pauseComposer();
6673
+ try {
6674
+ return await waitForRawActionGate(deps.input, deps.output, gate, deps.spawnRunner, {
6675
+ beforeSubprocess: () => {
6676
+ subprocessRan = true;
6677
+ },
6678
+ afterSubprocess: deps.resumeComposerFromSubprocess,
6679
+ registerToken: deps.registerToken
6680
+ });
6681
+ } finally {
6682
+ if (!subprocessRan) deps.resumeComposerFromDialog();
6683
+ }
6684
+ });
6382
6685
  }
6383
6686
  async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, confirmDestructiveAction) {
6384
6687
  const scheduleTitlePatchSync = (runResult) => {
@@ -6451,7 +6754,6 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
6451
6754
  ctx.scheduleRender();
6452
6755
  }) : ctx.output;
6453
6756
  const requestUserChoice = isInteractiveInput(ctx.input) && ctx.dialogHost ? async (choiceReq) => {
6454
- ctx.modalOwnsKeyboard = true;
6455
6757
  try {
6456
6758
  return await ctx.dialogHost.run(
6457
6759
  (anchor) => runAskChoiceDialog({
@@ -6463,12 +6765,11 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
6463
6765
  );
6464
6766
  } catch {
6465
6767
  return { kind: "cancelled" };
6466
- } finally {
6467
- ctx.composerDecoderDrain?.();
6468
- ctx.modalOwnsKeyboard = false;
6469
6768
  }
6470
6769
  } : void 0;
6471
6770
  ctx.runRegistryPoller.beginHold();
6771
+ const injectionInbox = createTurnInjectionInbox();
6772
+ ctx.turnInjectionInbox = injectionInbox;
6472
6773
  try {
6473
6774
  ctx.activeTurnAbort = new AbortController();
6474
6775
  ctx.activeTurnEpoch = myEpoch;
@@ -6485,6 +6786,7 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
6485
6786
  ...confirmDestructiveAction ? { confirmDestructiveAction } : {},
6486
6787
  ...requestUserChoice ? { requestUserChoice } : {},
6487
6788
  abortSignal: ctx.activeTurnAbort.signal,
6789
+ drainInjections: () => injectionInbox.drain(),
6488
6790
  pastedTextStore: ctx.pasteStore,
6489
6791
  activityReporter: ctx.activityReporter,
6490
6792
  onAgentRunStatus: (snapshot) => {
@@ -6514,10 +6816,14 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
6514
6816
  // 本轮已发起 agent 调用(消息已注入),消费切换通知。
6515
6817
  pendingCwdNotice: void 0
6516
6818
  };
6517
- if (runResult.dialogId && nextDialogKey) {
6518
- ctx.refreshDialogTotalCredits(runResult.dialogId, nextDialogKey);
6519
- }
6520
6819
  }
6820
+ ctx.accumulateSessionCredits(runResult.turnCredits);
6821
+ appendTurnBillingAudit({
6822
+ dialogId: runResult.dialogId ?? null,
6823
+ turnCredits: runResult.turnCredits ?? null,
6824
+ usageRecords: runResult.usageRecords,
6825
+ aborted: true
6826
+ });
6521
6827
  scheduleTitlePatchSync(runResult);
6522
6828
  return { ok: false, aborted: true };
6523
6829
  }
@@ -6566,10 +6872,16 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
6566
6872
  // 而非纯 child-run-completed 事件短路)时才清除。
6567
6873
  pendingCwdNotice: void 0
6568
6874
  };
6569
- if (runResult.dialogId && nextDialogKey) {
6570
- ctx.refreshDialogTotalCredits(runResult.dialogId, nextDialogKey);
6571
- }
6572
6875
  }
6876
+ ctx.accumulateSessionCredits(runResult.turnCredits);
6877
+ appendTurnBillingAudit({
6878
+ dialogId: runResult.dialogId ?? null,
6879
+ turnCredits: runResult.turnCredits ?? null,
6880
+ usageRecords: runResult.usageRecords,
6881
+ // 普通中断(Esc)同样属于「账照记、轮未正常收尾」,审计行标注出来,
6882
+ // 与 1028 行 forceStop 路径及正常完成轮区分开。
6883
+ ...wasAborted || runResult.streamInterrupted ? { aborted: true } : {}
6884
+ });
6573
6885
  scheduleTitlePatchSync(runResult);
6574
6886
  if (!wasAborted && runResult.exitCode !== 0) {
6575
6887
  if (isBalanceExhaustedError(runResult.localError) && runResult.dialogId) {
@@ -6587,6 +6899,21 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
6587
6899
  ctx.runRegistryPoller.endHold();
6588
6900
  ctx.activityIndicator.stop();
6589
6901
  ctx.activeTurnAbort = null;
6902
+ if (ctx.turnInjectionInbox === injectionInbox) ctx.turnInjectionInbox = null;
6903
+ const leftover = injectionInbox.close();
6904
+ if (leftover.length > 0) {
6905
+ const binding = ensureChatQueueBinding(
6906
+ ctx,
6907
+ actionGateHandler,
6908
+ confirmDestructiveAction
6909
+ );
6910
+ for (const entry of leftover) {
6911
+ try {
6912
+ binding.enqueue(entry.fallback);
6913
+ } catch {
6914
+ }
6915
+ }
6916
+ }
6590
6917
  }
6591
6918
  }
6592
6919
  function ensureChatQueueBinding(ctx, actionGateHandler, confirmDestructiveAction) {
@@ -7659,7 +7986,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
7659
7986
  emitCommandOutput,
7660
7987
  renderHistoryToOutput,
7661
7988
  scheduleRender,
7662
- refreshDialogTotalCredits,
7989
+ seedDialogCreditsBase,
7663
7990
  persistExplicitAgentSwitch,
7664
7991
  persistAgentSelection: persistAgentSelection2,
7665
7992
  writeClipboard: writeClipboard2,
@@ -7707,8 +8034,10 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
7707
8034
  host.state = {
7708
8035
  ...host.state,
7709
8036
  turnTokens: void 0,
7710
- // 新对话累计积分从 0 开始,清掉旧对话残留的累计值,等首轮读取后再回填。
7711
- dialogTotalCredits: void 0,
8037
+ // 新对话的积分累计从 0 重新开始:既清掉旧对话的本会话累加,也清掉旧对话
8038
+ // 的历史基数(新对话没有历史)。
8039
+ sessionCredits: void 0,
8040
+ dialogCreditsBase: void 0,
7712
8041
  cachedMemoryOverlay: void 0,
7713
8042
  // 新对话重新加载记忆
7714
8043
  estimatedContextTokens: estimateDefaultCliContextTokens({
@@ -7758,9 +8087,10 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
7758
8087
  // composer chip falls back to the default CLI surface estimate and
7759
8088
  // the context percentage visibly drops. Mirrors the /clear reset.
7760
8089
  turnTokens: void 0,
7761
- // compact fork 出新的官方 dialog,其全量计费投影从新记录累计。
7762
- // 清掉旧累计值,等首轮读取后再回填新 dialog 的 totalCost。
7763
- dialogTotalCredits: void 0,
8090
+ // compact fork 出新的官方 dialog,计费从新记录开始累计;新 dialog 没有
8091
+ // 历史基数,本会话累加也随之归零。
8092
+ sessionCredits: void 0,
8093
+ dialogCreditsBase: void 0,
7764
8094
  cachedMemoryOverlay: void 0,
7765
8095
  // compact 创建新 dialog,重新加载记忆
7766
8096
  estimatedContextTokens: estimateDefaultCliContextTokens({
@@ -7875,7 +8205,6 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
7875
8205
  model: pickResult.model,
7876
8206
  userLanguage: host.state.userLanguage
7877
8207
  }),
7878
- ...pickResult.apiSource ? { apiSource: pickResult.apiSource } : {},
7879
8208
  cachedMemoryOverlay: void 0
7880
8209
  // 切换 agent 后重新加载记忆
7881
8210
  };
@@ -7992,13 +8321,14 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
7992
8321
  dialogLabel: pickResult.dialog.title || pickResult.dialog.id,
7993
8322
  dialogTitle: pickResult.dialog.title,
7994
8323
  turnTokens: void 0,
7995
- // 切换对话先清空上一个对话的累计积分,等下面异步读取成功后回填;
8324
+ // 切换对话先清空上一个对话的积分,等下面异步 seed 成功后回填历史基数;
7996
8325
  // 若读取失败也不至于把旧对话的累计值残留显示在状态行。
7997
- dialogTotalCredits: void 0,
8326
+ sessionCredits: void 0,
8327
+ dialogCreditsBase: void 0,
7998
8328
  cachedMemoryOverlay: void 0
7999
8329
  // 切换对话后重新加载记忆
8000
8330
  };
8001
- refreshDialogTotalCredits(pickResult.dialog.id, pickResult.dialog.dbKey);
8331
+ seedDialogCreditsBase(pickResult.dialog.id, pickResult.dialog.dbKey);
8002
8332
  clearCollapsedPasteStore(pasteStore);
8003
8333
  emitCommandOutput(
8004
8334
  `${t("resumedDialogPrefix")}: ${pickResult.dialog.title} (${pickResult.dialog.id})`
@@ -8275,7 +8605,6 @@ async function runTuiWorkspace(options) {
8275
8605
  isTurnActive: () => activeTurnAbort !== null,
8276
8606
  fallbackLabel: () => `${state.agentName} -> working`,
8277
8607
  stoppingLabel: () => t("turnStopping"),
8278
- displayMode: () => state.toolDisplay,
8279
8608
  onRepaint: () => {
8280
8609
  if (fixedInput.active && !fixedInput.isPaused()) {
8281
8610
  output.write("\x1B[?2026h\x1B[?25l");
@@ -8319,7 +8648,14 @@ async function runTuiWorkspace(options) {
8319
8648
  getInputLines: () => fixedInput.getInputLines(),
8320
8649
  isPaused: () => fixedInput.isPaused()
8321
8650
  },
8322
- output
8651
+ output,
8652
+ // The decoder-drain hook is only bound once the interactive raw-mode
8653
+ // composer installs its decoder (inside the `isInteractiveInput` block
8654
+ // below); the non-raw readline path never binds it, so this stays a
8655
+ // no-op there — which is correct, that path has no raw decoder to drain.
8656
+ drainDecoder: () => {
8657
+ if (composerDecoderDrain) composerDecoderDrain();
8658
+ }
8323
8659
  });
8324
8660
  let sessionEnded = false;
8325
8661
  const selectionState = createSelectionState();
@@ -8348,7 +8684,7 @@ async function runTuiWorkspace(options) {
8348
8684
  const repaintBanner = () => {
8349
8685
  if (!output.isTTY) return;
8350
8686
  if (fixedInput.isPaused()) return;
8351
- if (modalOwnsKeyboard) return;
8687
+ if (dialogHost.isKeyboardClaimed()) return;
8352
8688
  const currentColumns = output.columns ?? 80;
8353
8689
  const welcome = renderWelcome(state, 0, 0, currentColumns);
8354
8690
  const lines = welcome.split("\n");
@@ -8397,9 +8733,8 @@ async function runTuiWorkspace(options) {
8397
8733
  selectionState.anchor = null;
8398
8734
  selectionState.head = null;
8399
8735
  };
8400
- let modalOwnsKeyboard = false;
8401
8736
  let rawActionGateTokenHandler = null;
8402
- const refreshDialogTotalCredits = (dialogId, dialogKey) => {
8737
+ const seedDialogCreditsBase = (dialogId, dialogKey) => {
8403
8738
  const env = options.env ?? process.env;
8404
8739
  const authToken = resolvePlatformAuthToken(env);
8405
8740
  if (!authToken) return;
@@ -8411,14 +8746,19 @@ async function runTuiWorkspace(options) {
8411
8746
  }).then((record) => {
8412
8747
  if (sessionEnded) return;
8413
8748
  if (state.dialogId !== dialogId) return;
8749
+ if (state.sessionCredits !== void 0) return;
8414
8750
  const recordObj = record && typeof record === "object" ? record : null;
8415
8751
  const totalCost = recordObj ? Number(recordObj?.totalCost) : NaN;
8416
8752
  if (Number.isFinite(totalCost) && totalCost >= 0) {
8417
- state = { ...state, dialogTotalCredits: totalCost };
8753
+ state = { ...state, dialogCreditsBase: totalCost };
8418
8754
  }
8419
8755
  }).catch(() => {
8420
8756
  });
8421
8757
  };
8758
+ const accumulateSessionCredits = (credits) => {
8759
+ if (credits === void 0 || !Number.isFinite(credits)) return;
8760
+ state = { ...state, sessionCredits: (state.sessionCredits ?? 0) + credits };
8761
+ };
8422
8762
  let composerDecoderDrain = null;
8423
8763
  const emitCommandOutput = (text, command = "") => {
8424
8764
  if (!text) return;
@@ -8433,6 +8773,7 @@ async function runTuiWorkspace(options) {
8433
8773
  if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
8434
8774
  };
8435
8775
  let chatQueueBinding = null;
8776
+ let turnInjectionInbox = null;
8436
8777
  const turnCtx = {
8437
8778
  get state() {
8438
8779
  return state;
@@ -8470,24 +8811,18 @@ async function runTuiWorkspace(options) {
8470
8811
  set activeTurnEpoch(v) {
8471
8812
  activeTurnEpoch = v;
8472
8813
  },
8473
- get modalOwnsKeyboard() {
8474
- return modalOwnsKeyboard;
8475
- },
8476
- set modalOwnsKeyboard(v) {
8477
- modalOwnsKeyboard = v;
8478
- },
8479
- get composerDecoderDrain() {
8480
- return composerDecoderDrain;
8481
- },
8482
- set composerDecoderDrain(v) {
8483
- composerDecoderDrain = v;
8484
- },
8485
8814
  get chatQueueBinding() {
8486
8815
  return chatQueueBinding;
8487
8816
  },
8488
8817
  set chatQueueBinding(v) {
8489
8818
  chatQueueBinding = v;
8490
8819
  },
8820
+ get turnInjectionInbox() {
8821
+ return turnInjectionInbox;
8822
+ },
8823
+ set turnInjectionInbox(v) {
8824
+ turnInjectionInbox = v;
8825
+ },
8491
8826
  get sessionEnded() {
8492
8827
  return sessionEnded;
8493
8828
  },
@@ -8515,7 +8850,8 @@ async function runTuiWorkspace(options) {
8515
8850
  renderHistoryToOutput,
8516
8851
  scheduleRender,
8517
8852
  flushPendingRender,
8518
- refreshDialogTotalCredits,
8853
+ seedDialogCreditsBase,
8854
+ accumulateSessionCredits,
8519
8855
  emitCommandOutput
8520
8856
  };
8521
8857
  const persistExplicitAgentSwitch = (previousAgentKey) => {
@@ -8554,7 +8890,7 @@ async function runTuiWorkspace(options) {
8554
8890
  emitCommandOutput,
8555
8891
  renderHistoryToOutput,
8556
8892
  scheduleRender,
8557
- refreshDialogTotalCredits,
8893
+ seedDialogCreditsBase,
8558
8894
  persistExplicitAgentSwitch,
8559
8895
  persistAgentSelection,
8560
8896
  writeClipboard: writeClipboard2,
@@ -8669,47 +9005,33 @@ async function runTuiWorkspace(options) {
8669
9005
  input.setRawMode?.(false);
8670
9006
  };
8671
9007
  const buildInteractiveTurnHandlers = () => {
8672
- const releaseKeyboardToComposer = () => {
8673
- onData.destroy();
8674
- modalOwnsKeyboard = false;
8675
- };
8676
9008
  const actionGateHandler = async (gate) => {
8677
9009
  if (state.autoConfirm && isAutoConfirmableFileWriteGate(gate)) {
8678
9010
  return buildGateConfirmedResult(gate);
8679
9011
  }
8680
- modalOwnsKeyboard = true;
8681
- try {
8682
- return await resolveActionGate(gate, {
8683
- dialogHost,
8684
- input,
8685
- output,
8686
- spawnRunner,
8687
- registerToken: (handler) => {
8688
- rawActionGateTokenHandler = handler;
8689
- },
8690
- pauseComposer: () => fixedInput.pause(),
8691
- resumeComposerFromSubprocess: () => fixedInput.resumeFromSubprocess(),
8692
- resumeComposerFromDialog: () => fixedInput.resumeFromDialog()
8693
- });
8694
- } finally {
8695
- releaseKeyboardToComposer();
8696
- }
9012
+ return await resolveActionGate(gate, {
9013
+ dialogHost,
9014
+ input,
9015
+ output,
9016
+ spawnRunner,
9017
+ registerToken: (handler) => {
9018
+ rawActionGateTokenHandler = handler;
9019
+ },
9020
+ pauseComposer: () => fixedInput.pause(),
9021
+ resumeComposerFromSubprocess: () => fixedInput.resumeFromSubprocess(),
9022
+ resumeComposerFromDialog: () => fixedInput.resumeFromDialog()
9023
+ });
8697
9024
  };
8698
9025
  const confirmDestructiveAction = async (request) => {
8699
9026
  if (state.autoConfirm) return true;
8700
- modalOwnsKeyboard = true;
8701
- try {
8702
- return await dialogHost.run(
8703
- (anchor) => runConfirmDialog({
8704
- request,
8705
- input,
8706
- output,
8707
- ...anchor
8708
- })
8709
- );
8710
- } finally {
8711
- releaseKeyboardToComposer();
8712
- }
9027
+ return await dialogHost.run(
9028
+ (anchor) => runConfirmDialog({
9029
+ request,
9030
+ input,
9031
+ output,
9032
+ ...anchor
9033
+ })
9034
+ );
8713
9035
  };
8714
9036
  return { actionGateHandler, confirmDestructiveAction };
8715
9037
  };
@@ -8742,11 +9064,30 @@ ${err.message}` : ""}`
8742
9064
  flushPendingRender();
8743
9065
  fixedInput.exitOutputMode(buffer, cursorPos);
8744
9066
  };
9067
+ (options.env ?? process.env)[RUN_WAKE_CHANNEL_ENV] = "1";
8745
9068
  runWakeHandler = (event) => {
8746
9069
  if (done) return;
8747
9070
  if (busy || fixedInput.isPaused()) {
8748
- const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
8749
- ensureChatQueueBinding(turnCtx, actionGateHandler, confirmDestructiveAction).enqueue(event);
9071
+ const text = typeof event === "string" ? event : event.text;
9072
+ const injected = !!turnInjectionInbox && turnInjectionInbox.push({ text, fallback: event });
9073
+ if (injected) {
9074
+ const displayText = typeof event !== "string" && event.kind === "child-run-completed" ? event.displayText ?? event.text : text;
9075
+ const noticeLine = dimCliText(displayText, resolveCliColorEnabled());
9076
+ if (!isInteractiveInput(input)) {
9077
+ output.write(`${noticeLine}
9078
+ `);
9079
+ } else {
9080
+ history.followBottom = true;
9081
+ appendStreamSafeNotice(history, noticeLine, {
9082
+ appendLocalTurn,
9083
+ startTurn
9084
+ });
9085
+ renderHistoryToOutput();
9086
+ }
9087
+ } else {
9088
+ const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
9089
+ ensureChatQueueBinding(turnCtx, actionGateHandler, confirmDestructiveAction).enqueue(event);
9090
+ }
8750
9091
  if (fixedInput.active && !fixedInput.isPaused()) {
8751
9092
  fixedInput.repaint(buffer, cursorPos);
8752
9093
  }
@@ -8924,7 +9265,7 @@ ${hint}` : hint;
8924
9265
  };
8925
9266
  const handleInputToken = async (sequence) => {
8926
9267
  if (done) return;
8927
- if (modalOwnsKeyboard) {
9268
+ if (dialogHost.isKeyboardClaimed()) {
8928
9269
  rawActionGateTokenHandler?.(sequence);
8929
9270
  return;
8930
9271
  }