reasonix 0.46.0 → 0.46.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 (147) hide show
  1. package/README.md +3 -0
  2. package/README.zh-CN.md +3 -0
  3. package/dashboard/dist/app.js +76 -6
  4. package/dashboard/dist/app.js.map +1 -1
  5. package/dist/cli/{acp-LGBLHBKY.js → acp-LKJU5DZX.js} +19 -19
  6. package/dist/cli/chat-W7LAWEN6.js +51 -0
  7. package/dist/cli/chunk-2425HK6U.js +0 -0
  8. package/dist/cli/chunk-25T6CVUP.js +0 -0
  9. package/dist/cli/{chunk-5I2C4JEO.js → chunk-2AASOSD5.js} +6 -6
  10. package/dist/cli/{chunk-5I2C4JEO.js.map → chunk-2AASOSD5.js.map} +1 -1
  11. package/dist/cli/chunk-2UQP6H6T.js +0 -0
  12. package/dist/cli/{chunk-HVUZWNSP.js → chunk-3AAG2CUT.js} +2 -2
  13. package/dist/cli/chunk-5QCB62C4.js +0 -0
  14. package/dist/cli/chunk-6OWJV3YW.js +0 -0
  15. package/dist/cli/{chunk-IJ7JA32V.js → chunk-6VANO7KB.js} +44 -8
  16. package/dist/cli/chunk-6VANO7KB.js.map +1 -0
  17. package/dist/cli/{chunk-LIR2HBQH.js → chunk-7LOJS3LV.js} +2 -2
  18. package/dist/cli/{chunk-I4L2GTSE.js → chunk-7SGGXNB2.js} +2 -2
  19. package/dist/cli/{chunk-CBIQWMS6.js → chunk-7YW6TPXK.js} +7 -7
  20. package/dist/cli/{chunk-A3TSSDS2.js → chunk-C72TNHDE.js} +2 -2
  21. package/dist/cli/chunk-CXVWUPA3.js +0 -0
  22. package/dist/cli/{chunk-AVFXO2EZ.js → chunk-DGA5QYFM.js} +107 -4
  23. package/dist/cli/chunk-DGA5QYFM.js.map +1 -0
  24. package/dist/cli/{chunk-JNAQYELD.js → chunk-DHRVZJ2D.js} +2 -2
  25. package/dist/cli/{chunk-5ACMUK4Q.js → chunk-E7TAHQ4A.js} +2 -1
  26. package/dist/cli/{chunk-C53JQES5.js → chunk-EAOL43HB.js} +3 -3
  27. package/dist/cli/chunk-FEZK652I.js +0 -0
  28. package/dist/cli/chunk-HNXDZGC6.js +0 -0
  29. package/dist/cli/{chunk-QJDDIK3Z.js → chunk-IYQ325V7.js} +2 -2
  30. package/dist/cli/chunk-J5XJHLWM.js +0 -0
  31. package/dist/cli/{chunk-4CTDEJUF.js → chunk-JLQDNLZF.js} +2 -2
  32. package/dist/cli/chunk-JMBMLOBP.js +0 -0
  33. package/dist/cli/{chunk-RDRC3XDT.js → chunk-JVFEJAJX.js} +2 -2
  34. package/dist/cli/{chunk-GTZTQNX5.js → chunk-JVQT5IYP.js} +7 -7
  35. package/dist/cli/{chunk-YY227BIQ.js → chunk-K3AIFMI6.js} +2 -2
  36. package/dist/cli/{chunk-ZZYBBX5N.js → chunk-M4E5JK6S.js} +23 -9
  37. package/dist/cli/chunk-M4E5JK6S.js.map +1 -0
  38. package/dist/cli/{chunk-V26WPN3J.js → chunk-MIIZJD5O.js} +28 -1
  39. package/dist/cli/chunk-MIIZJD5O.js.map +1 -0
  40. package/dist/cli/{chunk-4HCP2UQW.js → chunk-NCBP5D6E.js} +2 -2
  41. package/dist/cli/chunk-PLHAZOLZ.js +0 -0
  42. package/dist/cli/{chunk-HKWSPKMU.js → chunk-R2ASNSEO.js} +8 -8
  43. package/dist/cli/chunk-S4XVGLRW.js +0 -0
  44. package/dist/cli/{chunk-W7YGWUWU.js → chunk-SE7C5ZSI.js} +3 -3
  45. package/dist/cli/{chunk-KQU2TYIL.js → chunk-SPXN5JIT.js} +1128 -675
  46. package/dist/cli/chunk-SPXN5JIT.js.map +1 -0
  47. package/dist/cli/chunk-SZ5XES2N.js +0 -0
  48. package/dist/cli/{chunk-WK3UFQY3.js → chunk-TDSBASOF.js} +2 -2
  49. package/dist/cli/chunk-TEUDEGX2.js +0 -0
  50. package/dist/cli/chunk-TUK7OWJA.js +0 -0
  51. package/dist/cli/{chunk-XSU4QVFW.js → chunk-WQ6ZRDQM.js} +12 -3
  52. package/dist/cli/chunk-WQ6ZRDQM.js.map +1 -0
  53. package/dist/cli/{chunk-R3CTO2HM.js → chunk-WRONKNIH.js} +2 -2
  54. package/dist/cli/chunk-X53B3JIX.js +0 -0
  55. package/dist/cli/chunk-XJXDHAES.js +0 -0
  56. package/dist/cli/{chunk-MJ6W5UN3.js → chunk-XPAUNFOL.js} +2 -2
  57. package/dist/cli/chunk-XXC2BYTV.js +0 -0
  58. package/dist/cli/{chunk-NVURFF27.js → chunk-YRLC2EDF.js} +2 -2
  59. package/dist/cli/{chunk-WL6SNQ5T.js → chunk-ZOQHVQON.js} +9 -93
  60. package/dist/cli/chunk-ZOQHVQON.js.map +1 -0
  61. package/dist/cli/chunk-ZZM6QJ4W.js +0 -0
  62. package/dist/cli/{code-DFHSASJ4.js → code-2JIHL5M2.js} +29 -30
  63. package/dist/cli/code-2JIHL5M2.js.map +1 -0
  64. package/dist/cli/{commands-OCU42XG4.js → commands-OPT5AJNH.js} +4 -4
  65. package/dist/cli/{commit-XCQIQCYG.js → commit-KA37H6GM.js} +3 -3
  66. package/dist/cli/{desktop-ZCUG7LMF.js → desktop-5ONTRU3C.js} +20 -20
  67. package/dist/cli/devtools-HW3WDT3Q.js +0 -0
  68. package/dist/cli/{diff-66B2KWOJ.js → diff-SOIA7AKH.js} +8 -8
  69. package/dist/cli/{doctor-Y73CPPRZ.js → doctor-RCUP4XRV.js} +9 -9
  70. package/dist/cli/{events-NGZ2OJYH.js → events-6KHITNX4.js} +3 -3
  71. package/dist/cli/index.js +39 -88
  72. package/dist/cli/index.js.map +1 -1
  73. package/dist/cli/{mcp-MPVGBBJF.js → mcp-JP5OWD6R.js} +2 -2
  74. package/dist/cli/{mcp-browse-4XOTC3FJ.js → mcp-browse-ONCJJPJN.js} +2 -2
  75. package/dist/cli/{mcp-inspect-CEMGKKAH.js → mcp-inspect-TPLHW5JA.js} +4 -4
  76. package/dist/cli/{prompt-2D7ID24X.js → prompt-RJDNCQAP.js} +3 -3
  77. package/dist/cli/{prune-sessions-OJEYYLHY.js → prune-sessions-MKEATRVL.js} +2 -2
  78. package/dist/cli/{replay-AKYQNAQJ.js → replay-4NILJG4U.js} +8 -8
  79. package/dist/cli/{run-5DPQFSP6.js → run-WFGXB4SB.js} +17 -18
  80. package/dist/cli/run-WFGXB4SB.js.map +1 -0
  81. package/dist/cli/{server-TQ2IHYQJ.js → server-5VFQP3PV.js} +13 -13
  82. package/dist/cli/{sessions-KY54NG45.js → sessions-5XDJDALO.js} +28 -14
  83. package/dist/cli/sessions-5XDJDALO.js.map +1 -0
  84. package/dist/cli/{setup-XPIOZWS7.js → setup-F6XSWLRA.js} +7 -7
  85. package/dist/cli/setup-F6XSWLRA.js.map +1 -0
  86. package/dist/cli/{stats-X2VTWKNS.js → stats-ALHBZICE.js} +6 -6
  87. package/dist/cli/update-6ITLPRDV.js +0 -0
  88. package/dist/cli/{version-7O6A5T7Q.js → version-JVRAHBMM.js} +14 -14
  89. package/dist/index.d.ts +23 -13
  90. package/dist/index.js +1112 -1090
  91. package/dist/index.js.map +1 -1
  92. package/package.json +1 -1
  93. package/dist/cli/.-3G6VX5S7.js +0 -327
  94. package/dist/cli/.-6YRPB2C7.js +0 -329
  95. package/dist/cli/.-EYSVINK3.js +0 -317
  96. package/dist/cli/chat-ECK5ZGMV.js +0 -51
  97. package/dist/cli/chunk-AVFXO2EZ.js.map +0 -1
  98. package/dist/cli/chunk-IJ7JA32V.js.map +0 -1
  99. package/dist/cli/chunk-KQU2TYIL.js.map +0 -1
  100. package/dist/cli/chunk-V26WPN3J.js.map +0 -1
  101. package/dist/cli/chunk-WL6SNQ5T.js.map +0 -1
  102. package/dist/cli/chunk-XSU4QVFW.js.map +0 -1
  103. package/dist/cli/chunk-ZZYBBX5N.js.map +0 -1
  104. package/dist/cli/code-DFHSASJ4.js.map +0 -1
  105. package/dist/cli/doctor-Y73CPPRZ.js.map +0 -1
  106. package/dist/cli/prompt-2D7ID24X.js.map +0 -1
  107. package/dist/cli/run-5DPQFSP6.js.map +0 -1
  108. package/dist/cli/sessions-KY54NG45.js.map +0 -1
  109. package/dist/cli/setup-XPIOZWS7.js.map +0 -1
  110. package/dist/cli/stats-X2VTWKNS.js.map +0 -1
  111. /package/dist/cli/{acp-LGBLHBKY.js.map → acp-LKJU5DZX.js.map} +0 -0
  112. /package/dist/cli/{.-3G6VX5S7.js.map → chat-W7LAWEN6.js.map} +0 -0
  113. /package/dist/cli/{chunk-HVUZWNSP.js.map → chunk-3AAG2CUT.js.map} +0 -0
  114. /package/dist/cli/{chunk-LIR2HBQH.js.map → chunk-7LOJS3LV.js.map} +0 -0
  115. /package/dist/cli/{chunk-I4L2GTSE.js.map → chunk-7SGGXNB2.js.map} +0 -0
  116. /package/dist/cli/{chunk-CBIQWMS6.js.map → chunk-7YW6TPXK.js.map} +0 -0
  117. /package/dist/cli/{chunk-A3TSSDS2.js.map → chunk-C72TNHDE.js.map} +0 -0
  118. /package/dist/cli/{chunk-JNAQYELD.js.map → chunk-DHRVZJ2D.js.map} +0 -0
  119. /package/dist/cli/{chunk-5ACMUK4Q.js.map → chunk-E7TAHQ4A.js.map} +0 -0
  120. /package/dist/cli/{chunk-C53JQES5.js.map → chunk-EAOL43HB.js.map} +0 -0
  121. /package/dist/cli/{chunk-QJDDIK3Z.js.map → chunk-IYQ325V7.js.map} +0 -0
  122. /package/dist/cli/{chunk-4CTDEJUF.js.map → chunk-JLQDNLZF.js.map} +0 -0
  123. /package/dist/cli/{chunk-RDRC3XDT.js.map → chunk-JVFEJAJX.js.map} +0 -0
  124. /package/dist/cli/{chunk-GTZTQNX5.js.map → chunk-JVQT5IYP.js.map} +0 -0
  125. /package/dist/cli/{chunk-YY227BIQ.js.map → chunk-K3AIFMI6.js.map} +0 -0
  126. /package/dist/cli/{chunk-4HCP2UQW.js.map → chunk-NCBP5D6E.js.map} +0 -0
  127. /package/dist/cli/{chunk-HKWSPKMU.js.map → chunk-R2ASNSEO.js.map} +0 -0
  128. /package/dist/cli/{chunk-W7YGWUWU.js.map → chunk-SE7C5ZSI.js.map} +0 -0
  129. /package/dist/cli/{chunk-WK3UFQY3.js.map → chunk-TDSBASOF.js.map} +0 -0
  130. /package/dist/cli/{chunk-R3CTO2HM.js.map → chunk-WRONKNIH.js.map} +0 -0
  131. /package/dist/cli/{chunk-MJ6W5UN3.js.map → chunk-XPAUNFOL.js.map} +0 -0
  132. /package/dist/cli/{chunk-NVURFF27.js.map → chunk-YRLC2EDF.js.map} +0 -0
  133. /package/dist/cli/{commands-OCU42XG4.js.map → commands-OPT5AJNH.js.map} +0 -0
  134. /package/dist/cli/{commit-XCQIQCYG.js.map → commit-KA37H6GM.js.map} +0 -0
  135. /package/dist/cli/{desktop-ZCUG7LMF.js.map → desktop-5ONTRU3C.js.map} +0 -0
  136. /package/dist/cli/{diff-66B2KWOJ.js.map → diff-SOIA7AKH.js.map} +0 -0
  137. /package/dist/cli/{.-6YRPB2C7.js.map → doctor-RCUP4XRV.js.map} +0 -0
  138. /package/dist/cli/{events-NGZ2OJYH.js.map → events-6KHITNX4.js.map} +0 -0
  139. /package/dist/cli/{mcp-MPVGBBJF.js.map → mcp-JP5OWD6R.js.map} +0 -0
  140. /package/dist/cli/{mcp-browse-4XOTC3FJ.js.map → mcp-browse-ONCJJPJN.js.map} +0 -0
  141. /package/dist/cli/{mcp-inspect-CEMGKKAH.js.map → mcp-inspect-TPLHW5JA.js.map} +0 -0
  142. /package/dist/cli/{.-EYSVINK3.js.map → prompt-RJDNCQAP.js.map} +0 -0
  143. /package/dist/cli/{prune-sessions-OJEYYLHY.js.map → prune-sessions-MKEATRVL.js.map} +0 -0
  144. /package/dist/cli/{replay-AKYQNAQJ.js.map → replay-4NILJG4U.js.map} +0 -0
  145. /package/dist/cli/{server-TQ2IHYQJ.js.map → server-5VFQP3PV.js.map} +0 -0
  146. /package/dist/cli/{chat-ECK5ZGMV.js.map → stats-ALHBZICE.js.map} +0 -0
  147. /package/dist/cli/{version-7O6A5T7Q.js.map → version-JVRAHBMM.js.map} +0 -0
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-JMBMLOBP.js";
10
10
  import {
11
11
  createMcpRuntime
12
- } from "./chunk-GTZTQNX5.js";
12
+ } from "./chunk-JVQT5IYP.js";
13
13
  import {
14
14
  Eventizer,
15
15
  autoResolveVerdict,
@@ -19,10 +19,10 @@ import {
19
19
  import {
20
20
  formatMcpLifecycleEvent,
21
21
  formatMcpSlowToast
22
- } from "./chunk-4HCP2UQW.js";
22
+ } from "./chunk-NCBP5D6E.js";
23
23
  import {
24
24
  buildTransportFromSpec
25
- } from "./chunk-NVURFF27.js";
25
+ } from "./chunk-YRLC2EDF.js";
26
26
  import {
27
27
  dumpStartupProfile,
28
28
  markPhase,
@@ -53,19 +53,19 @@ import {
53
53
  toWholeFileEditBlock,
54
54
  walkFilesStream,
55
55
  webFetch
56
- } from "./chunk-WL6SNQ5T.js";
56
+ } from "./chunk-ZOQHVQON.js";
57
57
  import {
58
58
  openTranscriptFile,
59
59
  recordFromLoopEvent,
60
60
  writeRecord
61
- } from "./chunk-C53JQES5.js";
61
+ } from "./chunk-EAOL43HB.js";
62
62
  import {
63
63
  McpClient
64
- } from "./chunk-XSU4QVFW.js";
64
+ } from "./chunk-WQ6ZRDQM.js";
65
65
  import {
66
66
  MemoryStore,
67
67
  effectivePriority
68
- } from "./chunk-JNAQYELD.js";
68
+ } from "./chunk-DHRVZJ2D.js";
69
69
  import {
70
70
  wrapper_default
71
71
  } from "./chunk-FEZK652I.js";
@@ -73,7 +73,7 @@ import {
73
73
  KeystrokeProvider,
74
74
  SingleSelect,
75
75
  useKeystroke
76
- } from "./chunk-YY227BIQ.js";
76
+ } from "./chunk-K3AIFMI6.js";
77
77
  import {
78
78
  COLOR,
79
79
  GLYPH,
@@ -81,7 +81,7 @@ import {
81
81
  ThemeProvider,
82
82
  useColor,
83
83
  useThemeTokens
84
- } from "./chunk-I4L2GTSE.js";
84
+ } from "./chunk-7SGGXNB2.js";
85
85
  import {
86
86
  Box_default,
87
87
  Text,
@@ -101,20 +101,20 @@ import {
101
101
  } from "./chunk-2425HK6U.js";
102
102
  import {
103
103
  runDoctorChecks
104
- } from "./chunk-HKWSPKMU.js";
104
+ } from "./chunk-R2ASNSEO.js";
105
105
  import {
106
106
  countTokensBounded
107
107
  } from "./chunk-6OWJV3YW.js";
108
108
  import {
109
109
  DeepSeekClient,
110
110
  pickPrimaryBalance
111
- } from "./chunk-V26WPN3J.js";
111
+ } from "./chunk-MIIZJD5O.js";
112
112
  import {
113
113
  loadDotenv
114
114
  } from "./chunk-2UQP6H6T.js";
115
115
  import {
116
116
  renderDashboard
117
- } from "./chunk-W7YGWUWU.js";
117
+ } from "./chunk-SE7C5ZSI.js";
118
118
  import {
119
119
  MANUAL_UPDATE_COMMANDS,
120
120
  planUpdate
@@ -140,11 +140,11 @@ import {
140
140
  restoreCheckpoint,
141
141
  savePlanState,
142
142
  suggestSlashCommands
143
- } from "./chunk-5I2C4JEO.js";
143
+ } from "./chunk-2AASOSD5.js";
144
144
  import {
145
145
  eventLogPath,
146
146
  openEventSink
147
- } from "./chunk-QJDDIK3Z.js";
147
+ } from "./chunk-IYQ325V7.js";
148
148
  import {
149
149
  fetchSmitheryDetail,
150
150
  loadMorePages,
@@ -156,7 +156,7 @@ import {
156
156
  formatCommandResult,
157
157
  pauseGate,
158
158
  runCommand
159
- } from "./chunk-RDRC3XDT.js";
159
+ } from "./chunk-JVFEJAJX.js";
160
160
  import {
161
161
  PROJECT_MEMORY_FILE,
162
162
  SkillStore,
@@ -171,14 +171,16 @@ import {
171
171
  loadHooks,
172
172
  projectSettingsPath,
173
173
  runHooks
174
- } from "./chunk-A3TSSDS2.js";
174
+ } from "./chunk-C72TNHDE.js";
175
175
  import {
176
176
  deleteSession,
177
177
  detectGitBranch,
178
178
  freshSessionName,
179
+ listSessions,
179
180
  listSessionsForWorkspace,
180
181
  loadSessionMessages,
181
182
  loadSessionMeta,
183
+ normalizeWorkspace,
182
184
  patchSessionMeta,
183
185
  renameSession,
184
186
  resolveSession,
@@ -186,18 +188,18 @@ import {
186
188
  sessionPath,
187
189
  sessionsDir,
188
190
  timestampSuffix
189
- } from "./chunk-5ACMUK4Q.js";
191
+ } from "./chunk-E7TAHQ4A.js";
190
192
  import {
191
193
  aggregateUsage,
192
194
  appendUsage,
193
195
  defaultUsageLogPath,
194
196
  readUsageLog
195
- } from "./chunk-R3CTO2HM.js";
197
+ } from "./chunk-WRONKNIH.js";
196
198
  import {
197
199
  DEEPSEEK_CONTEXT_TOKENS,
198
- DEEPSEEK_PRICING,
199
- DEFAULT_CONTEXT_TOKENS
200
- } from "./chunk-ZZYBBX5N.js";
200
+ DEFAULT_CONTEXT_TOKENS,
201
+ pricingFor
202
+ } from "./chunk-M4E5JK6S.js";
201
203
  import {
202
204
  getLanguage,
203
205
  getSupportedLanguages,
@@ -206,7 +208,7 @@ import {
206
208
  setLanguage,
207
209
  t,
208
210
  tObj
209
- } from "./chunk-IJ7JA32V.js";
211
+ } from "./chunk-6VANO7KB.js";
210
212
  import {
211
213
  CARD,
212
214
  FG,
@@ -217,7 +219,9 @@ import {
217
219
  addSkillPath,
218
220
  balanceColor,
219
221
  clearProjectShellAllowed,
222
+ decideQQAccess,
220
223
  defaultConfigPath,
224
+ describeQQAccess,
221
225
  editModeHintShown,
222
226
  formatBalance,
223
227
  formatCost,
@@ -229,17 +233,22 @@ import {
229
233
  loadEditMode,
230
234
  loadProjectShellAllowed,
231
235
  loadQQConfig,
236
+ loadRateLimit,
232
237
  loadReasoningEffort,
238
+ loadRecentWorkspaces,
233
239
  loadResolvedSkillPaths,
234
240
  loadSkillPaths,
235
241
  loadTheme,
242
+ loadWorkspaceDir,
236
243
  markEditModeHintShown,
237
244
  markMouseClipboardHintShown,
238
245
  mouseClipboardHintShown,
239
246
  normalizeMcpConfig,
240
247
  parseMcpSpec,
248
+ pushRecentWorkspace,
241
249
  readConfig,
242
250
  redactKey,
251
+ redactQQOpenId,
243
252
  removeProjectShellAllowed,
244
253
  removeSkillPath,
245
254
  resolveThemePreference,
@@ -252,7 +261,7 @@ import {
252
261
  webSearchEndpoint,
253
262
  webSearchEngine,
254
263
  writeConfig
255
- } from "./chunk-AVFXO2EZ.js";
264
+ } from "./chunk-DGA5QYFM.js";
256
265
  import {
257
266
  VERSION,
258
267
  compareVersions,
@@ -44304,7 +44313,7 @@ var require_dist = __commonJS({
44304
44313
  });
44305
44314
 
44306
44315
  // src/cli/commands/chat.tsx
44307
- var import_react92 = __toESM(require_react(), 1);
44316
+ var import_react93 = __toESM(require_react(), 1);
44308
44317
 
44309
44318
  // src/qq/channel.ts
44310
44319
  import { mkdirSync, readFileSync, unlinkSync, writeFileSync } from "fs";
@@ -44511,13 +44520,14 @@ var QQBot = class extends EventEmitter {
44511
44520
  this.closed = true;
44512
44521
  this.cleanup();
44513
44522
  }
44514
- async sendPrivateMessage(openid, content, msgId) {
44523
+ async sendPrivateMessage(openid, content, msgId, msgSeq) {
44515
44524
  const token = await this.ensureToken();
44516
44525
  const body = {
44517
44526
  content,
44518
44527
  msg_type: 0
44519
44528
  };
44520
44529
  if (msgId) body.msg_id = msgId;
44530
+ if (typeof msgSeq === "number" && Number.isFinite(msgSeq)) body.msg_seq = Math.trunc(msgSeq);
44521
44531
  const res = await fetch(`${this.baseUrl}/v2/users/${encodeURIComponent(openid)}/messages`, {
44522
44532
  method: "POST",
44523
44533
  headers: {
@@ -44537,17 +44547,41 @@ var QQBot = class extends EventEmitter {
44537
44547
 
44538
44548
  // src/qq/channel.ts
44539
44549
  var QQ_LOCK_FILE = join(homedir(), ".reasonix", "qq-channel.pid");
44540
- function chunkMessage(text, maxLen = 1500) {
44550
+ var QQ_MAX_CHUNK_BYTES = 1500;
44551
+ var NATURAL_SPLIT_MIN_FRACTION = 0.6;
44552
+ function fitUtf8Slice(text, maxBytes) {
44553
+ let end = 0;
44554
+ let bytes = 0;
44555
+ for (const char of text) {
44556
+ const nextBytes = Buffer.byteLength(char, "utf8");
44557
+ if (bytes > 0 && bytes + nextBytes > maxBytes) break;
44558
+ end += char.length;
44559
+ bytes += nextBytes;
44560
+ }
44561
+ return end > 0 ? text.slice(0, end) : text.slice(0, 1);
44562
+ }
44563
+ function pickNaturalSplit(candidate) {
44564
+ const minSplit = Math.floor(candidate.length * NATURAL_SPLIT_MIN_FRACTION);
44565
+ const splitters = ["\n\n", "\n", " "];
44566
+ for (const splitter of splitters) {
44567
+ const at = candidate.lastIndexOf(splitter);
44568
+ if (at >= minSplit) return at + splitter.length;
44569
+ }
44570
+ return candidate.length;
44571
+ }
44572
+ function splitQQMessage(text, maxBytes = QQ_MAX_CHUNK_BYTES) {
44541
44573
  const chunks = [];
44542
44574
  let remaining = text;
44543
- while (remaining.length > maxLen) {
44544
- let splitAt = remaining.lastIndexOf("\n", maxLen);
44545
- if (splitAt < 0) splitAt = remaining.lastIndexOf(" ", maxLen);
44546
- if (splitAt < 0) splitAt = maxLen;
44547
- chunks.push(remaining.slice(0, splitAt));
44548
- remaining = remaining.slice(splitAt).trim();
44549
- }
44550
- if (remaining.length > 0) chunks.push(remaining);
44575
+ while (remaining.length > 0) {
44576
+ if (Buffer.byteLength(remaining, "utf8") <= maxBytes) {
44577
+ chunks.push(remaining);
44578
+ break;
44579
+ }
44580
+ const candidate = fitUtf8Slice(remaining, maxBytes);
44581
+ const splitAt = pickNaturalSplit(candidate);
44582
+ chunks.push(candidate.slice(0, splitAt));
44583
+ remaining = remaining.slice(splitAt).trimStart();
44584
+ }
44551
44585
  return chunks;
44552
44586
  }
44553
44587
  var QQChannel = class {
@@ -44558,9 +44592,13 @@ var QQChannel = class {
44558
44592
  bot = null;
44559
44593
  qqUserId = null;
44560
44594
  qqMessageId = null;
44595
+ ownerOpenId;
44596
+ allowlist;
44597
+ runtimeBoundOpenId = null;
44561
44598
  processedMsgIds = /* @__PURE__ */ new Set();
44562
44599
  processedMsgIdQueue = [];
44563
44600
  lockAcquired = false;
44601
+ nextOutboundMsgSeq = 1;
44564
44602
  rememberMessage(id) {
44565
44603
  if (this.processedMsgIds.has(id)) return false;
44566
44604
  this.processedMsgIds.add(id);
@@ -44602,6 +44640,52 @@ var QQChannel = class {
44602
44640
  }
44603
44641
  this.lockAcquired = false;
44604
44642
  }
44643
+ applyAccessConfig(config) {
44644
+ this.ownerOpenId = config.ownerOpenId;
44645
+ this.allowlist = config.allowlist;
44646
+ if (this.ownerOpenId || (this.allowlist?.length ?? 0) > 0) {
44647
+ this.runtimeBoundOpenId = null;
44648
+ }
44649
+ }
44650
+ handlePrivateMessage(msg) {
44651
+ const text = msg.content?.trim();
44652
+ if (!text) return;
44653
+ if (!this.rememberMessage(msg.id)) return;
44654
+ const openid = msg.author.user_openid;
44655
+ const verdict = decideQQAccess(
44656
+ {
44657
+ ownerOpenId: this.ownerOpenId,
44658
+ allowlist: this.allowlist,
44659
+ runtimeBoundOpenId: this.runtimeBoundOpenId
44660
+ },
44661
+ openid
44662
+ );
44663
+ if (!verdict.accept) {
44664
+ this.callbacks.onError?.(
44665
+ `QQ ignored message from unauthorized openid ${redactQQOpenId(openid)}. Current access: ${this.describeAccess()}.`
44666
+ );
44667
+ return;
44668
+ }
44669
+ if (verdict.bindRuntime) {
44670
+ this.runtimeBoundOpenId = openid;
44671
+ this.callbacks.onError?.(
44672
+ `QQ temporarily bound this run to first sender ${redactQQOpenId(openid)}. Set \`qq.ownerOpenId\` in config to persist access.`
44673
+ );
44674
+ }
44675
+ this.qqUserId = openid;
44676
+ this.qqMessageId = msg.id;
44677
+ this.callbacks.onSubmitMessage(`[QQ] ${text}`);
44678
+ }
44679
+ refreshAccessConfig() {
44680
+ this.applyAccessConfig(loadQQConfig());
44681
+ }
44682
+ describeAccess() {
44683
+ return describeQQAccess({
44684
+ ownerOpenId: this.ownerOpenId,
44685
+ allowlist: this.allowlist,
44686
+ runtimeBoundOpenId: this.runtimeBoundOpenId
44687
+ });
44688
+ }
44605
44689
  async start() {
44606
44690
  loadDotenv();
44607
44691
  this.acquireLock();
@@ -44614,6 +44698,7 @@ var QQChannel = class {
44614
44698
  this.releaseLock();
44615
44699
  throw new Error("QQ App Secret is required. Run `/qq connect` to configure.");
44616
44700
  }
44701
+ this.applyAccessConfig(config);
44617
44702
  const bot = new QQBot({
44618
44703
  appid: config.appId,
44619
44704
  secret: config.appSecret,
@@ -44626,20 +44711,15 @@ var QQChannel = class {
44626
44711
  this.callbacks.onError?.(msg);
44627
44712
  });
44628
44713
  bot.on("message.private", (msg) => {
44629
- const text = msg.content?.trim();
44630
- if (!text) return;
44631
- if (!this.rememberMessage(msg.id)) return;
44632
- this.qqUserId = msg.author.user_openid;
44633
- this.qqMessageId = msg.id;
44634
- this.callbacks.onSubmitMessage(`[QQ] ${text}`);
44714
+ this.handlePrivateMessage(msg);
44635
44715
  });
44636
44716
  this.bot = bot;
44637
44717
  try {
44638
44718
  await bot.start();
44639
44719
  const readyOrError = await Promise.race([
44640
- new Promise((resolve3) => bot.once("online", () => resolve3("ready"))),
44641
- new Promise((resolve3) => bot.once("bot_error", () => resolve3("error"))),
44642
- new Promise((resolve3) => setTimeout(() => resolve3("timeout"), 15e3))
44720
+ new Promise((resolve4) => bot.once("online", () => resolve4("ready"))),
44721
+ new Promise((resolve4) => bot.once("bot_error", () => resolve4("error"))),
44722
+ new Promise((resolve4) => setTimeout(() => resolve4("timeout"), 15e3))
44643
44723
  ]);
44644
44724
  if (readyOrError === "error") {
44645
44725
  throw new Error("QQ bot authentication failed - check your appId and appSecret");
@@ -44654,13 +44734,21 @@ var QQChannel = class {
44654
44734
  }
44655
44735
  async sendResponse(text) {
44656
44736
  if (!this.bot || !this.qqUserId) return;
44657
- const chunks = chunkMessage(text);
44658
- for (const chunk of chunks) {
44737
+ const chunks = splitQQMessage(text);
44738
+ for (let index = 0; index < chunks.length; index++) {
44739
+ const chunk = chunks[index];
44740
+ if (!chunk) continue;
44659
44741
  try {
44660
- await this.bot.sendPrivateMessage(this.qqUserId, chunk, this.qqMessageId ?? void 0);
44742
+ await this.bot.sendPrivateMessage(
44743
+ this.qqUserId,
44744
+ chunk,
44745
+ this.qqMessageId ?? void 0,
44746
+ this.nextOutboundMsgSeq++
44747
+ );
44661
44748
  } catch (err) {
44662
- const msg = `QQ sendResponse error: ${err.message}`;
44749
+ const msg = `QQ sendResponse chunk ${index + 1}/${chunks.length} failed: ${err.message}`;
44663
44750
  this.callbacks.onError?.(msg);
44751
+ break;
44664
44752
  }
44665
44753
  }
44666
44754
  }
@@ -44671,9 +44759,9 @@ var QQChannel = class {
44671
44759
  };
44672
44760
 
44673
44761
  // src/cli/ui/App.tsx
44674
- import { statSync } from "fs";
44675
- import { relative as relative2, resolve as resolve2 } from "path";
44676
- var import_react89 = __toESM(require_react(), 1);
44762
+ import { statSync as statSync2 } from "fs";
44763
+ import { relative as relative2, resolve as resolve3 } from "path";
44764
+ var import_react90 = __toESM(require_react(), 1);
44677
44765
 
44678
44766
  // src/code/pending-edits.ts
44679
44767
  import { existsSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "fs";
@@ -44808,8 +44896,8 @@ function useQQChannel({
44808
44896
  if (isRawModeSupported) setRawMode(false);
44809
44897
  const rl = createInterface({ input: process.stdin, output: process.stdout });
44810
44898
  try {
44811
- const answer = await new Promise((resolve3) => {
44812
- rl.question(prompt, resolve3);
44899
+ const answer = await new Promise((resolve4) => {
44900
+ rl.question(prompt, resolve4);
44813
44901
  });
44814
44902
  return answer.trim() || fallback || "";
44815
44903
  } finally {
@@ -44845,9 +44933,24 @@ function useQQChannel({
44845
44933
  if (!appId || !appSecret) {
44846
44934
  throw new Error("QQ App ID and App Secret are required.");
44847
44935
  }
44848
- saveQQConfig({ appId, appSecret, sandbox, enabled: false });
44936
+ saveQQConfig({
44937
+ appId,
44938
+ appSecret,
44939
+ sandbox,
44940
+ enabled: false,
44941
+ ownerOpenId: existing.ownerOpenId,
44942
+ allowlist: existing.allowlist
44943
+ });
44849
44944
  if (channelRef.current) {
44850
- saveQQConfig({ appId, appSecret, sandbox, enabled: true });
44945
+ saveQQConfig({
44946
+ appId,
44947
+ appSecret,
44948
+ sandbox,
44949
+ enabled: true,
44950
+ ownerOpenId: existing.ownerOpenId,
44951
+ allowlist: existing.allowlist
44952
+ });
44953
+ channelRef.current.refreshAccessConfig();
44851
44954
  return `QQ is already connected (${codeMode ? "code" : "chat"} mode). Auto-start is enabled.`;
44852
44955
  }
44853
44956
  const channel = new QQChannel({
@@ -44856,7 +44959,14 @@ function useQQChannel({
44856
44959
  });
44857
44960
  await channel.start();
44858
44961
  channelRef.current = channel;
44859
- saveQQConfig({ appId, appSecret, sandbox, enabled: true });
44962
+ saveQQConfig({
44963
+ appId,
44964
+ appSecret,
44965
+ sandbox,
44966
+ enabled: true,
44967
+ ownerOpenId: existing.ownerOpenId,
44968
+ allowlist: existing.allowlist
44969
+ });
44860
44970
  return `QQ connected in ${codeMode ? "code" : "chat"} mode. It will auto-start on future launches.`;
44861
44971
  },
44862
44972
  [codeMode, log, promptLine, setQueuedSubmit]
@@ -44876,7 +44986,11 @@ function useQQChannel({
44876
44986
  const enabled = config.enabled ? "enabled" : "disabled";
44877
44987
  const appId = config.appId ? `${config.appId.slice(0, 6)}...` : "none";
44878
44988
  const sandbox = config.sandbox ? "sandbox" : "production";
44879
- return `QQ: ${connected}, auto-start ${enabled}, credentials ${configured}, appId ${appId}, ${sandbox}, current mode ${codeMode ? "code" : "chat"}.`;
44989
+ const access = channelRef.current?.describeAccess() ?? describeQQAccess({
44990
+ ownerOpenId: config.ownerOpenId,
44991
+ allowlist: config.allowlist
44992
+ });
44993
+ return `QQ: ${connected}, auto-start ${enabled}, credentials ${configured}, appId ${appId}, ${sandbox}, access ${access}, current mode ${codeMode ? "code" : "chat"}.`;
44880
44994
  }, [codeMode]);
44881
44995
  const resetInteractions = (0, import_react.useCallback)(() => {
44882
44996
  interactionRef.current = { kind: null, payload: null };
@@ -45490,6 +45604,79 @@ function recordSlashUse(name) {
45490
45604
  return counts;
45491
45605
  }
45492
45606
 
45607
+ // src/workspaces.ts
45608
+ import { statSync } from "fs";
45609
+ import { resolve } from "path";
45610
+ function listKnownWorkspaces(currentRoot, configPath) {
45611
+ const { stats: stats2, pathByKey } = collectSessionWorkspaceStats();
45612
+ const out = [];
45613
+ const seen = /* @__PURE__ */ new Map();
45614
+ const add = (raw, current = false) => {
45615
+ if (typeof raw !== "string" || raw.trim().length === 0) return;
45616
+ const path = resolve(raw);
45617
+ if (!isDirectory(path)) return;
45618
+ const key = normalizeWorkspace(path);
45619
+ const found = seen.get(key);
45620
+ const s = stats2.get(key);
45621
+ if (found) {
45622
+ found.current ||= current;
45623
+ if (s) {
45624
+ found.sessions = s.sessions;
45625
+ found.lastActive = s.lastActive;
45626
+ }
45627
+ return;
45628
+ }
45629
+ const info = {
45630
+ path,
45631
+ current,
45632
+ sessions: s?.sessions ?? 0,
45633
+ lastActive: s?.lastActive
45634
+ };
45635
+ seen.set(key, info);
45636
+ out.push(info);
45637
+ };
45638
+ add(currentRoot, true);
45639
+ add(loadWorkspaceDir(configPath));
45640
+ for (const p of loadRecentWorkspaces(configPath)) add(p);
45641
+ for (const [key, s] of stats2) {
45642
+ const path = pathByKey.get(key);
45643
+ if (!path) continue;
45644
+ add(path);
45645
+ }
45646
+ return out;
45647
+ }
45648
+ function rememberWorkspace(path, configPath) {
45649
+ const resolved = resolve(path);
45650
+ pushRecentWorkspace(resolved, configPath);
45651
+ return resolved;
45652
+ }
45653
+ function collectSessionWorkspaceStats() {
45654
+ const stats2 = /* @__PURE__ */ new Map();
45655
+ const pathByKey = /* @__PURE__ */ new Map();
45656
+ for (const session of listSessions()) {
45657
+ const raw = session.meta.workspace;
45658
+ if (typeof raw !== "string" || raw.trim().length === 0) continue;
45659
+ const path = resolve(raw);
45660
+ if (!isDirectory(path)) continue;
45661
+ const key = normalizeWorkspace(path);
45662
+ pathByKey.set(key, path);
45663
+ const cur = stats2.get(key) ?? { sessions: 0 };
45664
+ cur.sessions += 1;
45665
+ if (!cur.lastActive || session.mtime.getTime() > cur.lastActive.getTime()) {
45666
+ cur.lastActive = session.mtime;
45667
+ }
45668
+ stats2.set(key, cur);
45669
+ }
45670
+ return { stats: stats2, pathByKey };
45671
+ }
45672
+ function isDirectory(path) {
45673
+ try {
45674
+ return statSync(path).isDirectory();
45675
+ } catch {
45676
+ return false;
45677
+ }
45678
+ }
45679
+
45493
45680
  // src/cli/edit/external-editor.ts
45494
45681
  import { spawn } from "child_process";
45495
45682
  import { mkdtempSync, readFileSync as readFileSync4, rmSync, writeFileSync as writeFileSync4 } from "fs";
@@ -45532,14 +45719,14 @@ async function openInExternalEditor(initial2) {
45532
45719
  }
45533
45720
  }
45534
45721
  function spawnEditor(editor, path) {
45535
- return new Promise((resolve3, reject) => {
45722
+ return new Promise((resolve4, reject) => {
45536
45723
  const child = spawn(`${editor} "${path}"`, {
45537
45724
  shell: true,
45538
45725
  stdio: "inherit"
45539
45726
  });
45540
45727
  child.on("error", reject);
45541
45728
  child.on("exit", (code) => {
45542
- if (code === 0 || code === null) resolve3();
45729
+ if (code === 0 || code === null) resolve4();
45543
45730
  else reject(new Error(String(code)));
45544
45731
  });
45545
45732
  });
@@ -46400,6 +46587,13 @@ function textToSegments(line, pastes) {
46400
46587
 
46401
46588
  // src/cli/ui/PromptInput.tsx
46402
46589
  var INLINE_PASTE_THRESHOLD = 200;
46590
+ var IME_GUARD_MS = 50;
46591
+ function hasNonAscii(s) {
46592
+ for (let i = 0; i < s.length; i++) {
46593
+ if (s.charCodeAt(i) > 127) return true;
46594
+ }
46595
+ return false;
46596
+ }
46403
46597
  function shouldInlinePaste(content) {
46404
46598
  return !content.includes("\n") && content.length <= INLINE_PASTE_THRESHOLD;
46405
46599
  }
@@ -46423,6 +46617,7 @@ function PromptInput({
46423
46617
  }, [cursor, onCursorChange]);
46424
46618
  const pastesRef = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
46425
46619
  const nextPasteIdRef = (0, import_react9.useRef)(0);
46620
+ const lastNonAsciiInputAtRef = (0, import_react9.useRef)(0);
46426
46621
  const lastLocalValueRef = (0, import_react9.useRef)(value);
46427
46622
  const cursorRef = (0, import_react9.useRef)(cursor);
46428
46623
  cursorRef.current = cursor;
@@ -46454,6 +46649,9 @@ function PromptInput({
46454
46649
  if (ev.input.length > 0) registerPaste(ev.input);
46455
46650
  return;
46456
46651
  }
46652
+ if (ev.input.length > 0 && hasNonAscii(ev.input)) {
46653
+ lastNonAsciiInputAtRef.current = Date.now();
46654
+ }
46457
46655
  const key = {
46458
46656
  input: ev.input,
46459
46657
  return: ev.return,
@@ -46487,6 +46685,10 @@ function PromptInput({
46487
46685
  setCursor(action.cursor);
46488
46686
  }
46489
46687
  if (action.submit) {
46688
+ if (Date.now() - lastNonAsciiInputAtRef.current < IME_GUARD_MS) {
46689
+ lastNonAsciiInputAtRef.current = 0;
46690
+ return;
46691
+ }
46490
46692
  const raw = action.submitValue ?? lastLocalValueRef.current;
46491
46693
  const expanded = expandPasteSentinels(raw, pastesRef.current);
46492
46694
  const reachable = new Set(listPasteIdsInBuffer(raw));
@@ -52633,6 +52835,23 @@ function SessionPicker({
52633
52835
  onFocusChange
52634
52836
  }) {
52635
52837
  const [focus, setFocus] = (0, import_react43.useState)(0);
52838
+ const [searching, setSearching] = (0, import_react43.useState)(false);
52839
+ const [query, setQuery] = (0, import_react43.useState)("");
52840
+ const hasSearch = searching || query.length > 0;
52841
+ const filteredSessions = (0, import_react43.useMemo)(() => {
52842
+ const needle = query.trim().toLowerCase();
52843
+ if (!needle) return sessions2;
52844
+ return sessions2.filter(
52845
+ (s) => [s.name, s.meta.summary, s.meta.branch, s.meta.workspace, s.meta.balanceCurrency].some(
52846
+ (value) => value?.toLowerCase().includes(needle)
52847
+ )
52848
+ );
52849
+ }, [sessions2, query]);
52850
+ const activeSessions = hasSearch ? filteredSessions : sessions2;
52851
+ const maxFocus = hasSearch ? Math.max(0, activeSessions.length - 1) : activeSessions.length;
52852
+ (0, import_react43.useEffect)(() => {
52853
+ setFocus((f) => Math.max(0, Math.min(f, maxFocus)));
52854
+ }, [maxFocus]);
52636
52855
  (0, import_react43.useEffect)(() => {
52637
52856
  onFocusChange?.(focus);
52638
52857
  }, [focus, onFocusChange]);
@@ -52687,6 +52906,7 @@ function SessionPicker({
52687
52906
  useKeystroke((ev) => {
52688
52907
  if (ev.paste) {
52689
52908
  if (renaming) setRenaming({ ...renaming, buf: renaming.buf + ev.input });
52909
+ else if (searching) setQuery((q) => `${q}${oneLine(ev.input)}`);
52690
52910
  return;
52691
52911
  }
52692
52912
  if (renaming) {
@@ -52710,15 +52930,48 @@ function SessionPicker({
52710
52930
  }
52711
52931
  return;
52712
52932
  }
52933
+ if (searching) {
52934
+ if (ev.escape) {
52935
+ setSearching(false);
52936
+ setQuery("");
52937
+ setFocus(0);
52938
+ return;
52939
+ }
52940
+ if (ev.upArrow) return setFocus((f) => Math.max(0, f - 1));
52941
+ if (ev.downArrow) return setFocus((f) => Math.min(maxFocus, f + 1));
52942
+ if (ev.return) {
52943
+ const target2 = activeSessions[focus];
52944
+ if (target2) return onChoose({ kind: "open", name: target2.name });
52945
+ return;
52946
+ }
52947
+ if (ev.backspace) {
52948
+ if (query.length === 0) {
52949
+ setSearching(false);
52950
+ return;
52951
+ }
52952
+ setQuery((q) => q.slice(0, -1));
52953
+ return;
52954
+ }
52955
+ if (ev.input && !ev.ctrl && !ev.meta && !ev.tab) {
52956
+ setQuery((q) => `${q}${ev.input}`);
52957
+ }
52958
+ return;
52959
+ }
52713
52960
  if (ev.escape) return onChoose({ kind: "quit" });
52714
52961
  if (ev.upArrow) return setFocus((f) => Math.max(0, f - 1));
52715
- if (ev.downArrow) return setFocus((f) => Math.min(sessions2.length, f + 1));
52962
+ if (ev.downArrow) return setFocus((f) => Math.min(maxFocus, f + 1));
52716
52963
  if (ev.return) {
52717
52964
  if (sessions2.length === 0 || focus === sessions2.length) return onChoose({ kind: "new" });
52718
52965
  const target2 = sessions2[focus];
52719
52966
  return onChoose({ kind: "open", name: target2.name });
52720
52967
  }
52721
52968
  if (!ev.input) return;
52969
+ if (ev.input === "/") {
52970
+ setSearching(true);
52971
+ setQuery("");
52972
+ setFocus(0);
52973
+ return;
52974
+ }
52722
52975
  if (ev.input === "n") return onChoose({ kind: "new" });
52723
52976
  if (ev.input === "q") return onChoose({ kind: "quit" });
52724
52977
  if (sessions2.length === 0) return;
@@ -52729,12 +52982,18 @@ function SessionPicker({
52729
52982
  });
52730
52983
  const start = Math.max(
52731
52984
  0,
52732
- Math.min(focus - Math.floor(visibleCount / 2), sessions2.length - visibleCount)
52985
+ Math.min(focus - Math.floor(visibleCount / 2), activeSessions.length - visibleCount)
52733
52986
  );
52734
- const end = Math.min(sessions2.length, start + visibleCount);
52735
- const shown = sessions2.slice(start, end);
52736
- const hiddenBelow = sessions2.length - end;
52737
- return /* @__PURE__ */ import_react43.default.createElement(Box_default, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ import_react43.default.createElement(Box_default, null, /* @__PURE__ */ import_react43.default.createElement(Text, { bold: true, color: TONE.brand }, t("sessionPicker.header")), /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.meta }, ` \xB7 ${workspace}`)), /* @__PURE__ */ import_react43.default.createElement(Box_default, { height: 1 }), sessions2.length === 0 ? /* @__PURE__ */ import_react43.default.createElement(Box_default, null, /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.faint }, t("sessionPicker.empty")), /* @__PURE__ */ import_react43.default.createElement(Text, { bold: true, color: TONE.brand }, "\u23CE"), /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.faint }, t("sessionPicker.emptyNew"))) : shown.map((s, i) => /* @__PURE__ */ import_react43.default.createElement(
52987
+ const end = Math.min(activeSessions.length, start + visibleCount);
52988
+ const shown = activeSessions.slice(start, end);
52989
+ const hiddenBelow = activeSessions.length - end;
52990
+ return /* @__PURE__ */ import_react43.default.createElement(Box_default, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ import_react43.default.createElement(Box_default, null, /* @__PURE__ */ import_react43.default.createElement(Text, { bold: true, color: TONE.brand }, t("sessionPicker.header")), /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.meta }, ` \xB7 ${workspace}`), hasSearch ? /* @__PURE__ */ import_react43.default.createElement(
52991
+ Text,
52992
+ {
52993
+ color: FG.meta
52994
+ },
52995
+ ` \xB7 /${query} (${activeSessions.length}/${sessions2.length})`
52996
+ ) : null), /* @__PURE__ */ import_react43.default.createElement(Box_default, { height: 1 }), sessions2.length === 0 ? /* @__PURE__ */ import_react43.default.createElement(Box_default, null, /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.faint }, t("sessionPicker.empty")), /* @__PURE__ */ import_react43.default.createElement(Text, { bold: true, color: TONE.brand }, "\u23CE"), /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.faint }, t("sessionPicker.emptyNew"))) : activeSessions.length === 0 ? /* @__PURE__ */ import_react43.default.createElement(Box_default, null, /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.faint }, t("sessionPicker.searchEmpty"))) : shown.map((s, i) => /* @__PURE__ */ import_react43.default.createElement(
52738
52997
  SessionRow,
52739
52998
  {
52740
52999
  key: s.name,
@@ -52742,7 +53001,7 @@ function SessionPicker({
52742
53001
  focused: start + i === focus,
52743
53002
  walletCurrency
52744
53003
  }
52745
- )), hiddenBelow > 0 ? /* @__PURE__ */ import_react43.default.createElement(Box_default, null, /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.faint }, t("cardLabels.more", { count: hiddenBelow }))) : null, renaming ? /* @__PURE__ */ import_react43.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.faint }, t("sessionPicker.renamePrompt", { from: renaming.from })), /* @__PURE__ */ import_react43.default.createElement(Text, { bold: true, color: TONE.brand }, renaming.buf), /* @__PURE__ */ import_react43.default.createElement(Text, { backgroundColor: TONE.brand, color: "black" }, " ")) : null, /* @__PURE__ */ import_react43.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.faint }, renaming ? t("sessionPicker.renameHint") : sessions2.length === 0 ? t("sessionPicker.emptyHint") : t("sessionPicker.pickerHint"))));
53004
+ )), hiddenBelow > 0 ? /* @__PURE__ */ import_react43.default.createElement(Box_default, null, /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.faint }, t("cardLabels.more", { count: hiddenBelow }))) : null, renaming ? /* @__PURE__ */ import_react43.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.faint }, t("sessionPicker.renamePrompt", { from: renaming.from })), /* @__PURE__ */ import_react43.default.createElement(Text, { bold: true, color: TONE.brand }, renaming.buf), /* @__PURE__ */ import_react43.default.createElement(Text, { backgroundColor: TONE.brand, color: "black" }, " ")) : null, searching ? /* @__PURE__ */ import_react43.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.faint }, t("sessionPicker.searchPrompt")), /* @__PURE__ */ import_react43.default.createElement(Text, { bold: true, color: TONE.brand }, query), /* @__PURE__ */ import_react43.default.createElement(Text, { backgroundColor: TONE.brand, color: "black" }, " ")) : null, /* @__PURE__ */ import_react43.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react43.default.createElement(Text, { color: FG.faint }, renaming ? t("sessionPicker.renameHint") : searching ? t("sessionPicker.searchHint") : sessions2.length === 0 ? t("sessionPicker.emptyHint") : t("sessionPicker.pickerHint"))));
52746
53005
  }
52747
53006
  function SessionRow({
52748
53007
  info,
@@ -52762,6 +53021,9 @@ function truncate2(s, max) {
52762
53021
  if (s.length <= max) return s;
52763
53022
  return `${s.slice(0, max - 1)}\u2026`;
52764
53023
  }
53024
+ function oneLine(s) {
53025
+ return s.replace(/\s+/g, " ").trim();
53026
+ }
52765
53027
  function relativeTime2(date) {
52766
53028
  const ms = Date.now() - date.getTime();
52767
53029
  const mins = Math.floor(ms / 6e4);
@@ -52980,6 +53242,110 @@ function WelcomeBanner({
52980
53242
  ), /* @__PURE__ */ import_react46.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react46.default.createElement(Text, { color: FG.sub }, startTextRaw)), /* @__PURE__ */ import_react46.default.createElement(Box_default, { marginTop: 1, flexDirection: "row", gap: 3 }, HINTS.map((cmd) => /* @__PURE__ */ import_react46.default.createElement(Text, { key: cmd, color: FG.meta }, cmd))), inCodeMode && workspaceRoot ? /* @__PURE__ */ import_react46.default.createElement(Box_default, { marginTop: 1, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react46.default.createElement(Text, { color: TONE.brand }, t("welcomeBanner.workspace")), /* @__PURE__ */ import_react46.default.createElement(Text, { color: FG.faint }, "\xB7"), /* @__PURE__ */ import_react46.default.createElement(Text, { color: FG.body }, workspaceRoot), /* @__PURE__ */ import_react46.default.createElement(Text, { color: FG.faint }, t("welcomeBanner.relaunchHint"))) : null, dashboardUrl ? /* @__PURE__ */ import_react46.default.createElement(Box_default, { marginTop: 1, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react46.default.createElement(Text, { color: TONE.brand, bold: true }, t("welcomeBanner.dashboard")), /* @__PURE__ */ import_react46.default.createElement(Text, { color: FG.faint }, "\xB7"), /* @__PURE__ */ import_react46.default.createElement(Text, { color: TONE.accent }, dashboardUrl)) : null);
52981
53243
  }
52982
53244
 
53245
+ // src/cli/ui/WorkspacePicker.tsx
53246
+ import { basename } from "path";
53247
+ var import_react47 = __toESM(require_react(), 1);
53248
+ var PAGE_MARGIN4 = 6;
53249
+ function WorkspacePicker({
53250
+ workspaces,
53251
+ currentWorkspace,
53252
+ onChoose
53253
+ }) {
53254
+ const [focus, setFocus] = (0, import_react47.useState)(0);
53255
+ const [searching, setSearching] = (0, import_react47.useState)(false);
53256
+ const [query, setQuery] = (0, import_react47.useState)("");
53257
+ const hasSearch = searching || query.length > 0;
53258
+ const activeWorkspaces = (0, import_react47.useMemo)(() => {
53259
+ const needle = query.trim().toLowerCase();
53260
+ if (!needle) return workspaces;
53261
+ return workspaces.filter((w) => w.path.toLowerCase().includes(needle));
53262
+ }, [workspaces, query]);
53263
+ const maxFocus = Math.max(0, activeWorkspaces.length - 1);
53264
+ (0, import_react47.useEffect)(() => {
53265
+ setFocus((f) => Math.max(0, Math.min(f, maxFocus)));
53266
+ }, [maxFocus]);
53267
+ const { stdout } = use_stdout_default();
53268
+ const rows = stdout?.rows ?? 40;
53269
+ const visibleCount = Math.max(3, rows - PAGE_MARGIN4);
53270
+ useKeystroke((ev) => {
53271
+ if (ev.paste) {
53272
+ if (searching) setQuery((q) => `${q}${oneLine2(ev.input)}`);
53273
+ return;
53274
+ }
53275
+ if (searching) {
53276
+ if (ev.escape) {
53277
+ setSearching(false);
53278
+ setQuery("");
53279
+ setFocus(0);
53280
+ return;
53281
+ }
53282
+ if (ev.upArrow) return setFocus((f) => Math.max(0, f - 1));
53283
+ if (ev.downArrow) return setFocus((f) => Math.min(maxFocus, f + 1));
53284
+ if (ev.return) {
53285
+ const target = activeWorkspaces[focus];
53286
+ if (target) onChoose({ kind: "open", path: target.path });
53287
+ return;
53288
+ }
53289
+ if (ev.backspace) {
53290
+ if (query.length === 0) {
53291
+ setSearching(false);
53292
+ return;
53293
+ }
53294
+ setQuery((q) => q.slice(0, -1));
53295
+ return;
53296
+ }
53297
+ if (ev.input && !ev.ctrl && !ev.meta && !ev.tab) setQuery((q) => `${q}${ev.input}`);
53298
+ return;
53299
+ }
53300
+ if (ev.escape) return onChoose({ kind: "quit" });
53301
+ if (ev.upArrow) return setFocus((f) => Math.max(0, f - 1));
53302
+ if (ev.downArrow) return setFocus((f) => Math.min(maxFocus, f + 1));
53303
+ if (ev.return) {
53304
+ const target = activeWorkspaces[focus];
53305
+ if (target) return onChoose({ kind: "open", path: target.path });
53306
+ return;
53307
+ }
53308
+ if (!ev.input) return;
53309
+ if (ev.input === "/") {
53310
+ setSearching(true);
53311
+ setQuery("");
53312
+ setFocus(0);
53313
+ return;
53314
+ }
53315
+ if (ev.input === "q") return onChoose({ kind: "quit" });
53316
+ });
53317
+ const start = Math.max(
53318
+ 0,
53319
+ Math.min(focus - Math.floor(visibleCount / 2), activeWorkspaces.length - visibleCount)
53320
+ );
53321
+ const end = Math.min(activeWorkspaces.length, start + visibleCount);
53322
+ const shown = activeWorkspaces.slice(start, end);
53323
+ const hiddenBelow = activeWorkspaces.length - end;
53324
+ return /* @__PURE__ */ import_react47.default.createElement(Box_default, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ import_react47.default.createElement(Box_default, null, /* @__PURE__ */ import_react47.default.createElement(Text, { bold: true, color: TONE.brand }, t("workspacePicker.header")), /* @__PURE__ */ import_react47.default.createElement(Text, { color: FG.meta }, ` \xB7 ${currentWorkspace}`), hasSearch ? /* @__PURE__ */ import_react47.default.createElement(
53325
+ Text,
53326
+ {
53327
+ color: FG.meta
53328
+ },
53329
+ ` \xB7 /${query} (${activeWorkspaces.length}/${workspaces.length})`
53330
+ ) : null), /* @__PURE__ */ import_react47.default.createElement(Box_default, { height: 1 }), workspaces.length === 0 ? /* @__PURE__ */ import_react47.default.createElement(Box_default, null, /* @__PURE__ */ import_react47.default.createElement(Text, { color: FG.faint }, t("workspacePicker.empty"))) : activeWorkspaces.length === 0 ? /* @__PURE__ */ import_react47.default.createElement(Box_default, null, /* @__PURE__ */ import_react47.default.createElement(Text, { color: FG.faint }, t("workspacePicker.searchEmpty"))) : shown.map((w, i) => /* @__PURE__ */ import_react47.default.createElement(WorkspaceRow, { key: w.path, info: w, focused: start + i === focus })), hiddenBelow > 0 ? /* @__PURE__ */ import_react47.default.createElement(Box_default, null, /* @__PURE__ */ import_react47.default.createElement(Text, { color: FG.faint }, t("cardLabels.more", { count: hiddenBelow }))) : null, searching ? /* @__PURE__ */ import_react47.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react47.default.createElement(Text, { color: FG.faint }, t("workspacePicker.searchPrompt")), /* @__PURE__ */ import_react47.default.createElement(Text, { bold: true, color: TONE.brand }, query), /* @__PURE__ */ import_react47.default.createElement(Text, { backgroundColor: TONE.brand, color: "black" }, " ")) : null, /* @__PURE__ */ import_react47.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react47.default.createElement(Text, { color: FG.faint }, searching ? t("workspacePicker.searchHint") : t("workspacePicker.pickerHint"))));
53331
+ }
53332
+ function WorkspaceRow({
53333
+ info,
53334
+ focused
53335
+ }) {
53336
+ const label = basename(info.path) || info.path;
53337
+ const meta = t(
53338
+ info.sessions === 1 ? "workspacePicker.sessions" : "workspacePicker.sessionsPlural",
53339
+ {
53340
+ count: info.sessions
53341
+ }
53342
+ );
53343
+ return /* @__PURE__ */ import_react47.default.createElement(Box_default, null, /* @__PURE__ */ import_react47.default.createElement(Text, { color: focused ? TONE.brand : FG.faint }, focused ? " \u25B8 " : " "), /* @__PURE__ */ import_react47.default.createElement(Text, { bold: focused, color: focused ? FG.strong : FG.sub }, label.padEnd(16)), /* @__PURE__ */ import_react47.default.createElement(Text, { color: FG.meta }, info.current ? ` \xB7 ${t("workspacePicker.current")} \xB7 ` : " \xB7 "), /* @__PURE__ */ import_react47.default.createElement(Text, { color: focused ? FG.body : FG.sub }, info.path), /* @__PURE__ */ import_react47.default.createElement(Box_default, { flexGrow: 1 }), /* @__PURE__ */ import_react47.default.createElement(Text, { color: FG.faint }, meta));
53344
+ }
53345
+ function oneLine2(s) {
53346
+ return s.replace(/\s+/g, " ").trim();
53347
+ }
53348
+
52983
53349
  // src/cli/ui/bang.ts
52984
53350
  function detectBangCommand(text) {
52985
53351
  if (!text.startsWith("!")) return null;
@@ -52993,7 +53359,7 @@ ${output}`;
52993
53359
  }
52994
53360
 
52995
53361
  // src/cli/ui/copy-mode/CopyMode.tsx
52996
- var import_react47 = __toESM(require_react(), 1);
53362
+ var import_react48 = __toESM(require_react(), 1);
52997
53363
 
52998
53364
  // src/frame/width.ts
52999
53365
  var segmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
@@ -53106,16 +53472,16 @@ function isYankable(line) {
53106
53472
  // src/cli/ui/copy-mode/CopyMode.tsx
53107
53473
  var CHROME_ROWS2 = 3;
53108
53474
  function CopyMode({ cards, onClose }) {
53109
- const snapshot = (0, import_react47.useMemo)(() => buildSnapshot(cards), [cards]);
53475
+ const snapshot = (0, import_react48.useMemo)(() => buildSnapshot(cards), [cards]);
53110
53476
  const { stdout } = use_stdout_default();
53111
53477
  const termRows = stdout?.rows ?? 30;
53112
53478
  const termCols = stdout?.columns ?? 80;
53113
53479
  const bodyRows = Math.max(4, termRows - CHROME_ROWS2);
53114
53480
  const lastYankableIdx = findLastYankable(snapshot);
53115
53481
  const initialCursor = findFirstYankable(snapshot);
53116
- const [cursor, setCursor] = (0, import_react47.useState)(initialCursor);
53117
- const [anchor, setAnchor] = (0, import_react47.useState)(null);
53118
- const [status2, setStatus] = (0, import_react47.useState)(null);
53482
+ const [cursor, setCursor] = (0, import_react48.useState)(initialCursor);
53483
+ const [anchor, setAnchor] = (0, import_react48.useState)(null);
53484
+ const [status2, setStatus] = (0, import_react48.useState)(null);
53119
53485
  const stepDown = (i) => stepBy(snapshot, i, 1);
53120
53486
  const stepUp = (i) => stepBy(snapshot, i, -1);
53121
53487
  useKeystroke((ev) => {
@@ -53147,9 +53513,9 @@ function CopyMode({ cards, onClose }) {
53147
53513
  const selRange = anchor === null ? null : [Math.min(anchor, cursor), Math.max(anchor, cursor)];
53148
53514
  const totalY = countYankable(snapshot);
53149
53515
  const cursorY = countYankableUntil(snapshot, cursor);
53150
- return /* @__PURE__ */ import_react47.default.createElement(Box_default, { flexDirection: "column" }, /* @__PURE__ */ import_react47.default.createElement(Box_default, null, /* @__PURE__ */ import_react47.default.createElement(Text, { color: TONE.brand, bold: true }, t("copyMode.title")), /* @__PURE__ */ import_react47.default.createElement(Text, { color: FG.faint }, ` ${t("copyMode.help")}`)), /* @__PURE__ */ import_react47.default.createElement(Box_default, { flexDirection: "column" }, snapshot.length === 0 ? /* @__PURE__ */ import_react47.default.createElement(Text, { color: FG.faint }, t("copyMode.empty")) : window2.lines.map((line, i) => {
53516
+ return /* @__PURE__ */ import_react48.default.createElement(Box_default, { flexDirection: "column" }, /* @__PURE__ */ import_react48.default.createElement(Box_default, null, /* @__PURE__ */ import_react48.default.createElement(Text, { color: TONE.brand, bold: true }, t("copyMode.title")), /* @__PURE__ */ import_react48.default.createElement(Text, { color: FG.faint }, ` ${t("copyMode.help")}`)), /* @__PURE__ */ import_react48.default.createElement(Box_default, { flexDirection: "column" }, snapshot.length === 0 ? /* @__PURE__ */ import_react48.default.createElement(Text, { color: FG.faint }, t("copyMode.empty")) : window2.lines.map((line, i) => {
53151
53517
  const idx = window2.start + i;
53152
- return /* @__PURE__ */ import_react47.default.createElement(
53518
+ return /* @__PURE__ */ import_react48.default.createElement(
53153
53519
  CopyLine,
53154
53520
  {
53155
53521
  key: `${line.cardId}-${idx}`,
@@ -53159,11 +53525,11 @@ function CopyMode({ cards, onClose }) {
53159
53525
  inSelection: selRange !== null && idx >= selRange[0] && idx <= selRange[1]
53160
53526
  }
53161
53527
  );
53162
- })), /* @__PURE__ */ import_react47.default.createElement(Box_default, null, /* @__PURE__ */ import_react47.default.createElement(Text, { color: FG.meta }, t("copyMode.statusBar", {
53528
+ })), /* @__PURE__ */ import_react48.default.createElement(Box_default, null, /* @__PURE__ */ import_react48.default.createElement(Text, { color: FG.meta }, t("copyMode.statusBar", {
53163
53529
  cur: cursorY > 0 ? cursorY : 1,
53164
53530
  total: Math.max(1, totalY),
53165
53531
  sel: anchor === null ? "\u2014" : String(rangeYankable(snapshot, anchor, cursor))
53166
- })), status2 ? /* @__PURE__ */ import_react47.default.createElement(Text, { color: TONE.ok }, ` ${status2}`) : null));
53532
+ })), status2 ? /* @__PURE__ */ import_react48.default.createElement(Text, { color: TONE.ok }, ` ${status2}`) : null));
53167
53533
  }
53168
53534
  function CopyLine({
53169
53535
  line,
@@ -53175,10 +53541,10 @@ function CopyLine({
53175
53541
  const room = Math.max(1, cols - 2);
53176
53542
  const display = line.kind === "blank" ? "" : clipToCells(line.text, room);
53177
53543
  if (line.kind === "header") {
53178
- return /* @__PURE__ */ import_react47.default.createElement(Box_default, null, /* @__PURE__ */ import_react47.default.createElement(Text, { color: isCursor ? TONE.brand : FG.faint }, marker), /* @__PURE__ */ import_react47.default.createElement(Text, { color: FG.meta }, display));
53544
+ return /* @__PURE__ */ import_react48.default.createElement(Box_default, null, /* @__PURE__ */ import_react48.default.createElement(Text, { color: isCursor ? TONE.brand : FG.faint }, marker), /* @__PURE__ */ import_react48.default.createElement(Text, { color: FG.meta }, display));
53179
53545
  }
53180
53546
  const color = isCursor ? TONE.brand : FG.body;
53181
- return /* @__PURE__ */ import_react47.default.createElement(Box_default, null, /* @__PURE__ */ import_react47.default.createElement(Text, { color: isCursor ? TONE.brand : FG.faint }, marker), /* @__PURE__ */ import_react47.default.createElement(Text, { color, inverse: inSelection }, display.length === 0 ? " " : display));
53547
+ return /* @__PURE__ */ import_react48.default.createElement(Box_default, null, /* @__PURE__ */ import_react48.default.createElement(Text, { color: isCursor ? TONE.brand : FG.faint }, marker), /* @__PURE__ */ import_react48.default.createElement(Text, { color, inverse: inSelection }, display.length === 0 ? " " : display));
53182
53548
  }
53183
53549
  function findFirstYankable(snapshot) {
53184
53550
  for (let i = 0; i < snapshot.length; i++) if (isYankable(snapshot[i])) return i;
@@ -53585,14 +53951,14 @@ function useActivityLabel() {
53585
53951
  }
53586
53952
 
53587
53953
  // src/cli/ui/hooks/useAgentSession.ts
53588
- var import_react48 = __toESM(require_react(), 1);
53954
+ var import_react49 = __toESM(require_react(), 1);
53589
53955
  function useAgentSession({
53590
53956
  sessionId,
53591
53957
  model: model2,
53592
53958
  workspace,
53593
53959
  branch
53594
53960
  }) {
53595
- return (0, import_react48.useMemo)(
53961
+ return (0, import_react49.useMemo)(
53596
53962
  () => ({
53597
53963
  id: sessionId ?? "default",
53598
53964
  branch: branch ?? "main",
@@ -53604,10 +53970,10 @@ function useAgentSession({
53604
53970
  }
53605
53971
 
53606
53972
  // src/cli/ui/hooks/useCodeMode.ts
53607
- var import_react49 = __toESM(require_react(), 1);
53973
+ var import_react50 = __toESM(require_react(), 1);
53608
53974
  function useCodeMode(opts) {
53609
53975
  const { codeMode, pendingEdits, currentRootDir, session, syncPendingCount, recordEdit } = opts;
53610
- const codeApply = (0, import_react49.useCallback)(
53976
+ const codeApply = (0, import_react50.useCallback)(
53611
53977
  (indices) => {
53612
53978
  if (!codeMode) return "not in code mode";
53613
53979
  const blocks = pendingEdits.current;
@@ -53633,7 +53999,7 @@ function useCodeMode(opts) {
53633
53999
  },
53634
54000
  [codeMode, currentRootDir, session, syncPendingCount, recordEdit, pendingEdits]
53635
54001
  );
53636
- const codeDiscard = (0, import_react49.useCallback)(
54002
+ const codeDiscard = (0, import_react50.useCallback)(
53637
54003
  (indices) => {
53638
54004
  const blocks = pendingEdits.current;
53639
54005
  if (blocks.length === 0) return "nothing pending to discard.";
@@ -53655,26 +54021,26 @@ function useCodeMode(opts) {
53655
54021
  }
53656
54022
 
53657
54023
  // src/cli/ui/hooks/useEditGate.ts
53658
- var import_react50 = __toESM(require_react(), 1);
54024
+ var import_react51 = __toESM(require_react(), 1);
53659
54025
  var FLASH_MS = 1200;
53660
54026
  function useEditGate(codeMode) {
53661
- const pendingEdits = (0, import_react50.useRef)([]);
53662
- const [pendingCount, setPendingCount] = (0, import_react50.useState)(0);
53663
- const [pendingTick, setPendingTick] = (0, import_react50.useState)(0);
53664
- const syncPendingCount = (0, import_react50.useCallback)(() => {
54027
+ const pendingEdits = (0, import_react51.useRef)([]);
54028
+ const [pendingCount, setPendingCount] = (0, import_react51.useState)(0);
54029
+ const [pendingTick, setPendingTick] = (0, import_react51.useState)(0);
54030
+ const syncPendingCount = (0, import_react51.useCallback)(() => {
53665
54031
  setPendingCount(pendingEdits.current.length);
53666
54032
  setPendingTick((t2) => t2 + 1);
53667
54033
  }, []);
53668
- const [editMode, setEditMode] = (0, import_react50.useState)(() => codeMode ? loadEditMode() : "review");
53669
- const editModeRef = (0, import_react50.useRef)(editMode);
53670
- (0, import_react50.useEffect)(() => {
54034
+ const [editMode, setEditMode] = (0, import_react51.useState)(() => codeMode ? loadEditMode() : "review");
54035
+ const editModeRef = (0, import_react51.useRef)(editMode);
54036
+ (0, import_react51.useEffect)(() => {
53671
54037
  editModeRef.current = editMode;
53672
54038
  if (codeMode) saveEditMode(editMode);
53673
54039
  }, [editMode, codeMode]);
53674
- const [modeFlash, setModeFlash] = (0, import_react50.useState)(false);
53675
- const flashTimerRef = (0, import_react50.useRef)(null);
53676
- const prevEditModeRef = (0, import_react50.useRef)(editMode);
53677
- (0, import_react50.useEffect)(() => {
54040
+ const [modeFlash, setModeFlash] = (0, import_react51.useState)(false);
54041
+ const flashTimerRef = (0, import_react51.useRef)(null);
54042
+ const prevEditModeRef = (0, import_react51.useRef)(editMode);
54043
+ (0, import_react51.useEffect)(() => {
53678
54044
  if (prevEditModeRef.current === editMode) return;
53679
54045
  prevEditModeRef.current = editMode;
53680
54046
  setModeFlash(true);
@@ -53697,12 +54063,12 @@ function useEditGate(codeMode) {
53697
54063
  }
53698
54064
 
53699
54065
  // src/cli/ui/hooks/useHookList.ts
53700
- var import_react51 = __toESM(require_react(), 1);
54066
+ var import_react52 = __toESM(require_react(), 1);
53701
54067
  function useHookList(initialProjectRoot) {
53702
- const [hookList, setHookList] = (0, import_react51.useState)(
54068
+ const [hookList, setHookList] = (0, import_react52.useState)(
53703
54069
  () => loadHooks({ projectRoot: initialProjectRoot })
53704
54070
  );
53705
- const reloadHooks = (0, import_react51.useCallback)((projectRoot) => {
54071
+ const reloadHooks = (0, import_react52.useCallback)((projectRoot) => {
53706
54072
  const fresh = loadHooks({ projectRoot });
53707
54073
  setHookList(fresh);
53708
54074
  return fresh.length;
@@ -53711,56 +54077,56 @@ function useHookList(initialProjectRoot) {
53711
54077
  }
53712
54078
 
53713
54079
  // src/cli/ui/hooks/useInputRecall.ts
53714
- var import_react52 = __toESM(require_react(), 1);
54080
+ var import_react53 = __toESM(require_react(), 1);
53715
54081
  var HISTORY_MAX = 100;
53716
54082
  function useInputRecall(setInput) {
53717
- const [history2, setHistory] = (0, import_react52.useState)([]);
53718
- const historyCursor = (0, import_react52.useRef)(-1);
53719
- const recallPrev = (0, import_react52.useCallback)(() => {
54083
+ const [history2, setHistory] = (0, import_react53.useState)([]);
54084
+ const historyCursor = (0, import_react53.useRef)(-1);
54085
+ const recallPrev = (0, import_react53.useCallback)(() => {
53720
54086
  if (history2.length === 0) return;
53721
54087
  const nextCursor = Math.min(historyCursor.current + 1, history2.length - 1);
53722
54088
  historyCursor.current = nextCursor;
53723
54089
  setInput(history2[history2.length - 1 - nextCursor] ?? "");
53724
54090
  }, [setInput, history2]);
53725
- const recallNext = (0, import_react52.useCallback)(() => {
54091
+ const recallNext = (0, import_react53.useCallback)(() => {
53726
54092
  if (historyCursor.current < 0) return;
53727
54093
  const nextCursor = historyCursor.current - 1;
53728
54094
  historyCursor.current = nextCursor;
53729
54095
  setInput(nextCursor < 0 ? "" : history2[history2.length - 1 - nextCursor] ?? "");
53730
54096
  }, [setInput, history2]);
53731
- const pushHistory = (0, import_react52.useCallback)((text) => {
54097
+ const pushHistory = (0, import_react53.useCallback)((text) => {
53732
54098
  if (!text) return;
53733
54099
  setHistory((prev) => {
53734
54100
  const next = prev.length >= HISTORY_MAX ? prev.slice(prev.length - HISTORY_MAX + 1) : prev;
53735
54101
  return [...next, text];
53736
54102
  });
53737
54103
  }, []);
53738
- const resetCursor = (0, import_react52.useCallback)(() => {
54104
+ const resetCursor = (0, import_react53.useCallback)(() => {
53739
54105
  historyCursor.current = -1;
53740
54106
  }, []);
53741
54107
  return { recallPrev, recallNext, pushHistory, resetCursor, history: history2 };
53742
54108
  }
53743
54109
 
53744
54110
  // src/cli/ui/hooks/useLanguageReload.ts
53745
- var import_react53 = __toESM(require_react(), 1);
54111
+ var import_react54 = __toESM(require_react(), 1);
53746
54112
  function useLanguageReload() {
53747
- const [version, setVersion] = (0, import_react53.useState)(0);
53748
- (0, import_react53.useEffect)(() => onLanguageChange(() => setVersion((v) => v + 1)), []);
54113
+ const [version, setVersion] = (0, import_react54.useState)(0);
54114
+ (0, import_react54.useEffect)(() => onLanguageChange(() => setVersion((v) => v + 1)), []);
53749
54115
  return version;
53750
54116
  }
53751
54117
 
53752
54118
  // src/cli/ui/hooks/useLoopMode.ts
53753
- var import_react54 = __toESM(require_react(), 1);
54119
+ var import_react55 = __toESM(require_react(), 1);
53754
54120
  function useLoopMode(opts) {
53755
54121
  const { log, busyRef, handleSubmitRef } = opts;
53756
- const [activeLoop, setActiveLoop] = (0, import_react54.useState)(null);
53757
- const activeLoopRef = (0, import_react54.useRef)(null);
53758
- const loopTimerRef = (0, import_react54.useRef)(null);
53759
- const loopFiringRef = (0, import_react54.useRef)(false);
53760
- (0, import_react54.useEffect)(() => {
54122
+ const [activeLoop, setActiveLoop] = (0, import_react55.useState)(null);
54123
+ const activeLoopRef = (0, import_react55.useRef)(null);
54124
+ const loopTimerRef = (0, import_react55.useRef)(null);
54125
+ const loopFiringRef = (0, import_react55.useRef)(false);
54126
+ (0, import_react55.useEffect)(() => {
53761
54127
  activeLoopRef.current = activeLoop;
53762
54128
  }, [activeLoop]);
53763
- const stopLoop = (0, import_react54.useCallback)(() => {
54129
+ const stopLoop = (0, import_react55.useCallback)(() => {
53764
54130
  if (loopTimerRef.current) {
53765
54131
  clearTimeout(loopTimerRef.current);
53766
54132
  loopTimerRef.current = null;
@@ -53770,7 +54136,7 @@ function useLoopMode(opts) {
53770
54136
  setActiveLoop(null);
53771
54137
  log.pushInfo(`\u25B8 loop stopped (after ${cur.iter} iter${cur.iter === 1 ? "" : "s"}).`);
53772
54138
  }, [log]);
53773
- const startLoop = (0, import_react54.useCallback)((intervalMs, prompt) => {
54139
+ const startLoop = (0, import_react55.useCallback)((intervalMs, prompt) => {
53774
54140
  if (loopTimerRef.current) {
53775
54141
  clearTimeout(loopTimerRef.current);
53776
54142
  loopTimerRef.current = null;
@@ -53782,7 +54148,7 @@ function useLoopMode(opts) {
53782
54148
  iter: 0
53783
54149
  });
53784
54150
  }, []);
53785
- const getLoopStatus = (0, import_react54.useCallback)(() => {
54151
+ const getLoopStatus = (0, import_react55.useCallback)(() => {
53786
54152
  const cur = activeLoopRef.current;
53787
54153
  if (!cur) return null;
53788
54154
  return {
@@ -53792,12 +54158,12 @@ function useLoopMode(opts) {
53792
54158
  nextFireMs: Math.max(0, cur.nextFireAt - Date.now())
53793
54159
  };
53794
54160
  }, []);
53795
- const isLoopActive = (0, import_react54.useCallback)(() => activeLoopRef.current !== null, []);
53796
- const isLoopFiring = (0, import_react54.useCallback)(() => loopFiringRef.current, []);
53797
- const clearFiringFlag = (0, import_react54.useCallback)(() => {
54161
+ const isLoopActive = (0, import_react55.useCallback)(() => activeLoopRef.current !== null, []);
54162
+ const isLoopFiring = (0, import_react55.useCallback)(() => loopFiringRef.current, []);
54163
+ const clearFiringFlag = (0, import_react55.useCallback)(() => {
53798
54164
  loopFiringRef.current = false;
53799
54165
  }, []);
53800
- (0, import_react54.useEffect)(() => {
54166
+ (0, import_react55.useEffect)(() => {
53801
54167
  if (!activeLoop) return;
53802
54168
  const delay = Math.max(0, activeLoop.nextFireAt - Date.now());
53803
54169
  const timer = setTimeout(async () => {
@@ -53837,27 +54203,27 @@ function useLoopMode(opts) {
53837
54203
  }
53838
54204
 
53839
54205
  // src/cli/ui/hooks/usePresetMode.ts
53840
- var import_react55 = __toESM(require_react(), 1);
54206
+ var import_react56 = __toESM(require_react(), 1);
53841
54207
  function usePresetMode(model2) {
53842
- const [preset2, setPreset] = (0, import_react55.useState)(
54208
+ const [preset2, setPreset] = (0, import_react56.useState)(
53843
54209
  () => model2 === "deepseek-v4-pro" ? "pro" : "auto"
53844
54210
  );
53845
- const [proArmed, setProArmed] = (0, import_react55.useState)(false);
53846
- const [turnOnPro, setTurnOnPro] = (0, import_react55.useState)(false);
54211
+ const [proArmed, setProArmed] = (0, import_react56.useState)(false);
54212
+ const [turnOnPro, setTurnOnPro] = (0, import_react56.useState)(false);
53847
54213
  return { preset: preset2, setPreset, proArmed, setProArmed, turnOnPro, setTurnOnPro };
53848
54214
  }
53849
54215
 
53850
54216
  // src/cli/ui/hooks/useQuit.ts
53851
- var import_react56 = __toESM(require_react(), 1);
54217
+ var import_react57 = __toESM(require_react(), 1);
53852
54218
  function useQuit(transcriptRef) {
53853
- const quitProcess = (0, import_react56.useCallback)(() => {
54219
+ const quitProcess = (0, import_react57.useCallback)(() => {
53854
54220
  transcriptRef.current?.end();
53855
54221
  void (async () => {
53856
54222
  await stopAndSaveCpuProfile();
53857
54223
  process.exit(0);
53858
54224
  })();
53859
54225
  }, [transcriptRef]);
53860
- (0, import_react56.useEffect)(() => {
54226
+ (0, import_react57.useEffect)(() => {
53861
54227
  process.on("SIGINT", quitProcess);
53862
54228
  return () => {
53863
54229
  process.off("SIGINT", quitProcess);
@@ -53867,7 +54233,7 @@ function useQuit(transcriptRef) {
53867
54233
  }
53868
54234
 
53869
54235
  // src/cli/ui/hooks/useScrollback.ts
53870
- var import_react57 = __toESM(require_react(), 1);
54236
+ var import_react58 = __toESM(require_react(), 1);
53871
54237
  var seq = 0;
53872
54238
  function nextId2(prefix) {
53873
54239
  seq += 1;
@@ -53880,7 +54246,7 @@ function formatTok(n) {
53880
54246
  }
53881
54247
  function useScrollback() {
53882
54248
  const dispatch = useDispatch();
53883
- return (0, import_react57.useMemo)(
54249
+ return (0, import_react58.useMemo)(
53884
54250
  () => ({
53885
54251
  pushUser(text) {
53886
54252
  const id = nextId2("u");
@@ -54094,12 +54460,12 @@ ${stack}` : message
54094
54460
  }
54095
54461
 
54096
54462
  // src/cli/ui/hooks/useToolProgressDisplay.ts
54097
- var import_react58 = __toESM(require_react(), 1);
54463
+ var import_react59 = __toESM(require_react(), 1);
54098
54464
  function useToolProgressDisplay(progressSink) {
54099
- const [ongoingTool, setOngoingTool] = (0, import_react58.useState)(null);
54100
- const [toolProgress, setToolProgress] = (0, import_react58.useState)(null);
54101
- const [statusLine, setStatusLine] = (0, import_react58.useState)(null);
54102
- (0, import_react58.useEffect)(() => {
54465
+ const [ongoingTool, setOngoingTool] = (0, import_react59.useState)(null);
54466
+ const [toolProgress, setToolProgress] = (0, import_react59.useState)(null);
54467
+ const [statusLine, setStatusLine] = (0, import_react59.useState)(null);
54468
+ (0, import_react59.useEffect)(() => {
54103
54469
  if (!progressSink) return;
54104
54470
  progressSink.current = (info) => {
54105
54471
  setToolProgress({
@@ -54112,7 +54478,7 @@ function useToolProgressDisplay(progressSink) {
54112
54478
  if (progressSink.current) progressSink.current = null;
54113
54479
  };
54114
54480
  }, [progressSink]);
54115
- const clear = (0, import_react58.useCallback)(() => {
54481
+ const clear = (0, import_react59.useCallback)(() => {
54116
54482
  setOngoingTool(null);
54117
54483
  setToolProgress(null);
54118
54484
  setStatusLine(null);
@@ -54129,9 +54495,9 @@ function useToolProgressDisplay(progressSink) {
54129
54495
  }
54130
54496
 
54131
54497
  // src/cli/ui/hooks/useTranscriptWriter.ts
54132
- var import_react59 = __toESM(require_react(), 1);
54498
+ var import_react60 = __toESM(require_react(), 1);
54133
54499
  function useTranscriptWriter(transcriptRef, model2, prefixHash) {
54134
- return (0, import_react59.useCallback)(
54500
+ return (0, import_react60.useCallback)(
54135
54501
  (ev) => {
54136
54502
  const stream = transcriptRef.current;
54137
54503
  if (!stream) return;
@@ -54142,34 +54508,34 @@ function useTranscriptWriter(transcriptRef, model2, prefixHash) {
54142
54508
  }
54143
54509
 
54144
54510
  // src/cli/ui/hooks/useWorkspaceRoot.ts
54145
- var import_react60 = __toESM(require_react(), 1);
54511
+ var import_react61 = __toESM(require_react(), 1);
54146
54512
  function useWorkspaceRoot(launchRoot) {
54147
- const [currentRootDir, setCurrentRootDir] = (0, import_react60.useState)(() => launchRoot ?? process.cwd());
54148
- const currentRootDirRef = (0, import_react60.useRef)(currentRootDir);
54149
- (0, import_react60.useEffect)(() => {
54513
+ const [currentRootDir, setCurrentRootDir] = (0, import_react61.useState)(() => launchRoot ?? process.cwd());
54514
+ const currentRootDirRef = (0, import_react61.useRef)(currentRootDir);
54515
+ (0, import_react61.useEffect)(() => {
54150
54516
  currentRootDirRef.current = currentRootDir;
54151
54517
  }, [currentRootDir]);
54152
54518
  return { currentRootDir, setCurrentRootDir, currentRootDirRef };
54153
54519
  }
54154
54520
 
54155
54521
  // src/cli/ui/layout/CardStream.tsx
54156
- var import_react83 = __toESM(require_react(), 1);
54522
+ var import_react84 = __toESM(require_react(), 1);
54157
54523
 
54158
54524
  // src/cli/ui/cards/CardRenderer.tsx
54159
- var import_react82 = __toESM(require_react(), 1);
54525
+ var import_react83 = __toESM(require_react(), 1);
54160
54526
 
54161
54527
  // src/cli/ui/cards/CtxCard.tsx
54162
- var import_react61 = __toESM(require_react(), 1);
54528
+ var import_react62 = __toESM(require_react(), 1);
54163
54529
  var BAR_CELLS = 32;
54164
54530
  function row(label, tokens, ratio, color) {
54165
54531
  const filled = Math.max(0, Math.min(BAR_CELLS, Math.round(ratio * BAR_CELLS)));
54166
- return /* @__PURE__ */ import_react61.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react61.default.createElement(Text, { color: FG.sub }, label.padEnd(7)), /* @__PURE__ */ import_react61.default.createElement(Text, { color }, "\u2588".repeat(filled)), /* @__PURE__ */ import_react61.default.createElement(Text, { color: FG.faint }, "\u2591".repeat(BAR_CELLS - filled)), /* @__PURE__ */ import_react61.default.createElement(Text, { bold: true, color: FG.body }, tokens.toLocaleString()), /* @__PURE__ */ import_react61.default.createElement(Text, { color: FG.faint }, `\xB7 ${(ratio * 100).toFixed(1)}%`));
54532
+ return /* @__PURE__ */ import_react62.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react62.default.createElement(Text, { color: FG.sub }, label.padEnd(7)), /* @__PURE__ */ import_react62.default.createElement(Text, { color }, "\u2588".repeat(filled)), /* @__PURE__ */ import_react62.default.createElement(Text, { color: FG.faint }, "\u2591".repeat(BAR_CELLS - filled)), /* @__PURE__ */ import_react62.default.createElement(Text, { bold: true, color: FG.body }, tokens.toLocaleString()), /* @__PURE__ */ import_react62.default.createElement(Text, { color: FG.faint }, `\xB7 ${(ratio * 100).toFixed(1)}%`));
54167
54533
  }
54168
54534
  function CtxCard({ card }) {
54169
54535
  const cap = Math.max(1, card.ctxMax);
54170
54536
  const used = card.systemTokens + card.toolsTokens + card.logTokens + card.inputTokens;
54171
54537
  const usedPct = used / cap * 100;
54172
- return /* @__PURE__ */ import_react61.default.createElement(Card, { tone: TONE.brand }, /* @__PURE__ */ import_react61.default.createElement(
54538
+ return /* @__PURE__ */ import_react62.default.createElement(Card, { tone: TONE.brand }, /* @__PURE__ */ import_react62.default.createElement(
54173
54539
  CardHeader,
54174
54540
  {
54175
54541
  glyph: "\u25CF",
@@ -54177,7 +54543,7 @@ function CtxCard({ card }) {
54177
54543
  title: t("cardTitles.context"),
54178
54544
  meta: [`${used.toLocaleString()} / ${cap.toLocaleString()} (${usedPct.toFixed(1)}%)`]
54179
54545
  }
54180
- ), row(t("cardLabels.system"), card.systemTokens, card.systemTokens / cap, TONE.brand), row(t("cardLabels.tools"), card.toolsTokens, card.toolsTokens / cap, TONE.warn), row(t("cardLabels.log"), card.logTokens, card.logTokens / cap, TONE.ok), row(t("cardLabels.input"), card.inputTokens, card.inputTokens / cap, TONE.accent), card.topTools.length > 0 ? /* @__PURE__ */ import_react61.default.createElement(import_react61.default.Fragment, null, /* @__PURE__ */ import_react61.default.createElement(Text, { color: FG.faint }, `${t("cardLabels.topTools")} \xB7 ${card.toolsCount} ${t("cardLabels.tools")} \xB7 ${card.logMessages} ${t("cardLabels.logMsgs")}`), card.topTools.slice(0, 5).map((tool) => /* @__PURE__ */ import_react61.default.createElement(Box_default, { key: `${tool.turn}-${tool.name}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react61.default.createElement(Text, { color: FG.sub }, tool.name), /* @__PURE__ */ import_react61.default.createElement(
54546
+ ), row(t("cardLabels.system"), card.systemTokens, card.systemTokens / cap, TONE.brand), row(t("cardLabels.tools"), card.toolsTokens, card.toolsTokens / cap, TONE.warn), row(t("cardLabels.log"), card.logTokens, card.logTokens / cap, TONE.ok), row(t("cardLabels.input"), card.inputTokens, card.inputTokens / cap, TONE.accent), card.topTools.length > 0 ? /* @__PURE__ */ import_react62.default.createElement(import_react62.default.Fragment, null, /* @__PURE__ */ import_react62.default.createElement(Text, { color: FG.faint }, `${t("cardLabels.topTools")} \xB7 ${card.toolsCount} ${t("cardLabels.tools")} \xB7 ${card.logMessages} ${t("cardLabels.logMsgs")}`), card.topTools.slice(0, 5).map((tool) => /* @__PURE__ */ import_react62.default.createElement(Box_default, { key: `${tool.turn}-${tool.name}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react62.default.createElement(Text, { color: FG.sub }, tool.name), /* @__PURE__ */ import_react62.default.createElement(
54181
54547
  Text,
54182
54548
  {
54183
54549
  color: FG.faint
@@ -54187,7 +54553,7 @@ function CtxCard({ card }) {
54187
54553
  }
54188
54554
 
54189
54555
  // src/cli/ui/cards/DiffCard.tsx
54190
- var import_react62 = __toESM(require_react(), 1);
54556
+ var import_react63 = __toESM(require_react(), 1);
54191
54557
  var LINE_COLOR = {
54192
54558
  ctx: FG.sub,
54193
54559
  add: TONE.ok,
@@ -54202,7 +54568,7 @@ var LINE_GLYPH = {
54202
54568
  };
54203
54569
  function DiffCard({ card }) {
54204
54570
  const showFooter = card.hunks.length > 0;
54205
- return /* @__PURE__ */ import_react62.default.createElement(Card, { tone: TONE.ok }, /* @__PURE__ */ import_react62.default.createElement(
54571
+ return /* @__PURE__ */ import_react63.default.createElement(Card, { tone: TONE.ok }, /* @__PURE__ */ import_react63.default.createElement(
54206
54572
  CardHeader,
54207
54573
  {
54208
54574
  glyph: "\xB1",
@@ -54213,11 +54579,11 @@ function DiffCard({ card }) {
54213
54579
  { text: `-${card.stats.del}`, color: TONE.err }
54214
54580
  ]
54215
54581
  }
54216
- ), card.hunks.map((hunk) => /* @__PURE__ */ import_react62.default.createElement(Box_default, { key: `${card.id}:${hunk.header}`, flexDirection: "column" }, /* @__PURE__ */ import_react62.default.createElement(Text, { italic: true, color: FG.faint }, hunk.header), hunk.lines.map((line, li) => /* @__PURE__ */ import_react62.default.createElement(Box_default, { key: `${card.id}:${hunk.header}:${li}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react62.default.createElement(Text, { color: LINE_COLOR[line.kind] }, LINE_GLYPH[line.kind]), /* @__PURE__ */ import_react62.default.createElement(Text, { color: LINE_COLOR[line.kind], dimColor: line.kind === "ctx" }, line.text))))), showFooter && /* @__PURE__ */ import_react62.default.createElement(Box_default, { flexDirection: "row", gap: 2 }, /* @__PURE__ */ import_react62.default.createElement(Text, { bold: true, color: TONE.ok }, t("cardLabels.applyAction")), /* @__PURE__ */ import_react62.default.createElement(Text, { color: FG.sub }, t("cardLabels.skipAction")), /* @__PURE__ */ import_react62.default.createElement(Text, { bold: true, color: TONE.err }, t("cardLabels.rejectAction"))));
54582
+ ), card.hunks.map((hunk) => /* @__PURE__ */ import_react63.default.createElement(Box_default, { key: `${card.id}:${hunk.header}`, flexDirection: "column" }, /* @__PURE__ */ import_react63.default.createElement(Text, { italic: true, color: FG.faint }, hunk.header), hunk.lines.map((line, li) => /* @__PURE__ */ import_react63.default.createElement(Box_default, { key: `${card.id}:${hunk.header}:${li}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react63.default.createElement(Text, { color: LINE_COLOR[line.kind] }, LINE_GLYPH[line.kind]), /* @__PURE__ */ import_react63.default.createElement(Text, { color: LINE_COLOR[line.kind], dimColor: line.kind === "ctx" }, line.text))))), showFooter && /* @__PURE__ */ import_react63.default.createElement(Box_default, { flexDirection: "row", gap: 2 }, /* @__PURE__ */ import_react63.default.createElement(Text, { bold: true, color: TONE.ok }, t("cardLabels.applyAction")), /* @__PURE__ */ import_react63.default.createElement(Text, { color: FG.sub }, t("cardLabels.skipAction")), /* @__PURE__ */ import_react63.default.createElement(Text, { bold: true, color: TONE.err }, t("cardLabels.rejectAction"))));
54217
54583
  }
54218
54584
 
54219
54585
  // src/cli/ui/cards/DoctorCard.tsx
54220
- var import_react63 = __toESM(require_react(), 1);
54586
+ var import_react64 = __toESM(require_react(), 1);
54221
54587
  var LEVEL_GLYPH = {
54222
54588
  ok: "\u2713",
54223
54589
  warn: "\u26A0",
@@ -54245,7 +54611,7 @@ function DoctorCard({ card }) {
54245
54611
  const fail = card.checks.filter((c) => c.level === "fail").length;
54246
54612
  const labelWidth = card.checks.reduce((m, c) => Math.max(m, c.label.length), 0);
54247
54613
  const summary = `${card.checks.length} ${t("cardLabels.checksLabel")} \xB7 ${ok} ${t("cardLabels.passed")}${warn > 0 ? ` \xB7 ${warn} ${t("cardLabels.warnTag")}` : ""}${fail > 0 ? ` \xB7 ${fail} ${t("cardLabels.failTag")}` : ""}`;
54248
- return /* @__PURE__ */ import_react63.default.createElement(Card, { tone: CARD.tool.color }, /* @__PURE__ */ import_react63.default.createElement(
54614
+ return /* @__PURE__ */ import_react64.default.createElement(Card, { tone: CARD.tool.color }, /* @__PURE__ */ import_react64.default.createElement(
54249
54615
  CardHeader,
54250
54616
  {
54251
54617
  glyph: "\u25CF",
@@ -54253,11 +54619,11 @@ function DoctorCard({ card }) {
54253
54619
  title: t("cardTitles.doctor"),
54254
54620
  meta: [summary]
54255
54621
  }
54256
- ), card.checks.map((c) => /* @__PURE__ */ import_react63.default.createElement(Box_default, { key: c.label, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react63.default.createElement(Text, { color: levelColor[c.level] }, LEVEL_GLYPH[c.level]), /* @__PURE__ */ import_react63.default.createElement(Text, { bold: true, color: fg.body }, c.label.padEnd(labelWidth + 1)), /* @__PURE__ */ import_react63.default.createElement(Text, { color: fg.sub }, c.detail), /* @__PURE__ */ import_react63.default.createElement(Text, { color: levelColor[c.level] }, levelTag(c.level)))));
54622
+ ), card.checks.map((c) => /* @__PURE__ */ import_react64.default.createElement(Box_default, { key: c.label, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react64.default.createElement(Text, { color: levelColor[c.level] }, LEVEL_GLYPH[c.level]), /* @__PURE__ */ import_react64.default.createElement(Text, { bold: true, color: fg.body }, c.label.padEnd(labelWidth + 1)), /* @__PURE__ */ import_react64.default.createElement(Text, { color: fg.sub }, c.detail), /* @__PURE__ */ import_react64.default.createElement(Text, { color: levelColor[c.level] }, levelTag(c.level)))));
54257
54623
  }
54258
54624
 
54259
54625
  // src/cli/ui/cards/ErrorCard.tsx
54260
- var import_react64 = __toESM(require_react(), 1);
54626
+ var import_react65 = __toESM(require_react(), 1);
54261
54627
  var STACK_TAIL = 5;
54262
54628
  function ErrorCard({ card }) {
54263
54629
  const retryNote = card.retries !== void 0 && card.retries > 0 ? `${card.retries} ${t("cardLabels.retries")}` : null;
@@ -54267,7 +54633,7 @@ function ErrorCard({ card }) {
54267
54633
  const stackHidden = stackTrunc ? stackLines.length - stackVisible.length : 0;
54268
54634
  const hasStack = stackVisible.length > 0;
54269
54635
  const messageLines = card.message.split("\n");
54270
- return /* @__PURE__ */ import_react64.default.createElement(Card, { tone: TONE.err }, /* @__PURE__ */ import_react64.default.createElement(
54636
+ return /* @__PURE__ */ import_react65.default.createElement(Card, { tone: TONE.err }, /* @__PURE__ */ import_react65.default.createElement(
54271
54637
  CardHeader,
54272
54638
  {
54273
54639
  glyph: "\u2717",
@@ -54275,14 +54641,14 @@ function ErrorCard({ card }) {
54275
54641
  title: card.title || t("cardTitles.error"),
54276
54642
  meta: retryNote ? [retryNote] : void 0
54277
54643
  }
54278
- ), messageLines.map((line, i) => /* @__PURE__ */ import_react64.default.createElement(Text, { key: `${card.id}:msg:${i}`, color: TONE.err }, line || " ")), hasStack ? /* @__PURE__ */ import_react64.default.createElement(Box_default, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ import_react64.default.createElement(Text, { color: FG.meta }, t("cardLabels.stackTrace")), stackHidden > 0 ? /* @__PURE__ */ import_react64.default.createElement(Text, { color: FG.faint }, t(
54644
+ ), messageLines.map((line, i) => /* @__PURE__ */ import_react65.default.createElement(Text, { key: `${card.id}:msg:${i}`, color: TONE.err }, line || " ")), hasStack ? /* @__PURE__ */ import_react65.default.createElement(Box_default, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ import_react65.default.createElement(Text, { color: FG.meta }, t("cardLabels.stackTrace")), stackHidden > 0 ? /* @__PURE__ */ import_react65.default.createElement(Text, { color: FG.faint }, t(
54279
54645
  stackHidden === 1 ? "cardLabels.earlierStackLine" : "cardLabels.earlierStackLines",
54280
54646
  { count: stackHidden }
54281
- )) : null, stackVisible.map((line, i) => /* @__PURE__ */ import_react64.default.createElement(Text, { key: `${card.id}:stk:${stackHidden + i}`, color: FG.meta }, line || " "))) : null);
54647
+ )) : null, stackVisible.map((line, i) => /* @__PURE__ */ import_react65.default.createElement(Text, { key: `${card.id}:stk:${stackHidden + i}`, color: FG.meta }, line || " "))) : null);
54282
54648
  }
54283
54649
 
54284
54650
  // src/cli/ui/cards/LiveCard.tsx
54285
- var import_react65 = __toESM(require_react(), 1);
54651
+ var import_react66 = __toESM(require_react(), 1);
54286
54652
  var TONE_TO_COLOR = {
54287
54653
  ok: TONE.ok,
54288
54654
  warn: TONE.warn,
@@ -54306,11 +54672,11 @@ var VARIANT_GLYPH = {
54306
54672
  function LiveCard({ card }) {
54307
54673
  const color = TONE_TO_COLOR[card.tone];
54308
54674
  const glyph = VARIANT_GLYPH[card.variant];
54309
- return /* @__PURE__ */ import_react65.default.createElement(Box_default, { paddingLeft: 2, flexDirection: "row", gap: 1 }, card.variant === "thinking" ? /* @__PURE__ */ import_react65.default.createElement(Spinner, { kind: "circle", color, bold: true }) : /* @__PURE__ */ import_react65.default.createElement(Text, { bold: true, color }, glyph), /* @__PURE__ */ import_react65.default.createElement(Text, { color: FG.body }, card.text), card.meta !== void 0 ? /* @__PURE__ */ import_react65.default.createElement(Text, { color: FG.faint }, `\xB7 ${card.meta}`) : null);
54675
+ return /* @__PURE__ */ import_react66.default.createElement(Box_default, { paddingLeft: 2, flexDirection: "row", gap: 1 }, card.variant === "thinking" ? /* @__PURE__ */ import_react66.default.createElement(Spinner, { kind: "circle", color, bold: true }) : /* @__PURE__ */ import_react66.default.createElement(Text, { bold: true, color }, glyph), /* @__PURE__ */ import_react66.default.createElement(Text, { color: FG.body }, card.text), card.meta !== void 0 ? /* @__PURE__ */ import_react66.default.createElement(Text, { color: FG.faint }, `\xB7 ${card.meta}`) : null);
54310
54676
  }
54311
54677
 
54312
54678
  // src/cli/ui/cards/MemoryCard.tsx
54313
- var import_react66 = __toESM(require_react(), 1);
54679
+ var import_react67 = __toESM(require_react(), 1);
54314
54680
  var CATEGORY_ORDER = [
54315
54681
  "user",
54316
54682
  "feedback",
@@ -54345,7 +54711,7 @@ function MemoryCard({ card }) {
54345
54711
  const counts = countByCategory(card.entries);
54346
54712
  const summary = CATEGORY_ORDER.filter((c) => counts[c] > 0).map((c) => `${counts[c]} ${categoryLabel(c)}`).join(" \xB7 ");
54347
54713
  const tokens = card.tokens > 1024 ? `~${(card.tokens / 1024).toFixed(1)}K ${t("cardLabels.tok")}` : `~${card.tokens} ${t("cardLabels.tok")}`;
54348
- return /* @__PURE__ */ import_react66.default.createElement(Card, { tone: FG.meta }, /* @__PURE__ */ import_react66.default.createElement(
54714
+ return /* @__PURE__ */ import_react67.default.createElement(Card, { tone: FG.meta }, /* @__PURE__ */ import_react67.default.createElement(
54349
54715
  CardHeader,
54350
54716
  {
54351
54717
  glyph: "\u25CF",
@@ -54357,7 +54723,7 @@ function MemoryCard({ card }) {
54357
54723
  const all = card.entries.filter((e) => e.category === category);
54358
54724
  const shown = all.slice(0, 5);
54359
54725
  const remaining = all.length - shown.length;
54360
- return /* @__PURE__ */ import_react66.default.createElement(Box_default, { key: category, flexDirection: "column" }, /* @__PURE__ */ import_react66.default.createElement(Text, { color: FG.faint }, `${categoryLabel(category)} (${counts[category]})`), shown.map((entry) => /* @__PURE__ */ import_react66.default.createElement(Box_default, { key: `${category}:${entry.summary}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react66.default.createElement(Text, { color: CATEGORY_GLYPH_COLOR[category] }, CATEGORY_GLYPH[category]), /* @__PURE__ */ import_react66.default.createElement(Text, { color: FG.sub }, entry.summary))), remaining > 0 ? /* @__PURE__ */ import_react66.default.createElement(Text, { color: FG.faint }, t("cardLabels.more", { count: remaining })) : null);
54726
+ return /* @__PURE__ */ import_react67.default.createElement(Box_default, { key: category, flexDirection: "column" }, /* @__PURE__ */ import_react67.default.createElement(Text, { color: FG.faint }, `${categoryLabel(category)} (${counts[category]})`), shown.map((entry) => /* @__PURE__ */ import_react67.default.createElement(Box_default, { key: `${category}:${entry.summary}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react67.default.createElement(Text, { color: CATEGORY_GLYPH_COLOR[category] }, CATEGORY_GLYPH[category]), /* @__PURE__ */ import_react67.default.createElement(Text, { color: FG.sub }, entry.summary))), remaining > 0 ? /* @__PURE__ */ import_react67.default.createElement(Text, { color: FG.faint }, t("cardLabels.more", { count: remaining })) : null);
54361
54727
  }));
54362
54728
  }
54363
54729
  function countByCategory(entries) {
@@ -54372,18 +54738,18 @@ function countByCategory(entries) {
54372
54738
  }
54373
54739
 
54374
54740
  // src/cli/ui/cards/ReasoningCard.tsx
54375
- var import_react69 = __toESM(require_react(), 1);
54741
+ var import_react70 = __toESM(require_react(), 1);
54376
54742
 
54377
54743
  // src/cli/ui/primitives/CursorBlock.tsx
54378
- var import_react67 = __toESM(require_react(), 1);
54744
+ var import_react68 = __toESM(require_react(), 1);
54379
54745
  function CursorBlock() {
54380
54746
  const tick = useTick();
54381
54747
  const on = Math.floor(tick / 4) % 2 === 0;
54382
- return /* @__PURE__ */ import_react67.default.createElement(Text, { inverse: on, color: CARD.streaming.color }, " ");
54748
+ return /* @__PURE__ */ import_react68.default.createElement(Text, { inverse: on, color: CARD.streaming.color }, " ");
54383
54749
  }
54384
54750
 
54385
54751
  // src/cli/ui/cards/useIncrementalWrap.ts
54386
- var import_react68 = __toESM(require_react(), 1);
54752
+ var import_react69 = __toESM(require_react(), 1);
54387
54753
  function wrapAll(text, lineCells) {
54388
54754
  if (text.length === 0) return [""];
54389
54755
  return text.split("\n").flatMap((l) => wrapToCells(l, lineCells));
@@ -54430,16 +54796,16 @@ function wrapIncremental(text, lineCells, prev) {
54430
54796
  }
54431
54797
  var LINE_CELLS_DEBOUNCE_MS = 120;
54432
54798
  function useIncrementalWrap(text, lineCells) {
54433
- const cacheRef = (0, import_react68.useRef)(null);
54434
- const [effectiveCells, setEffectiveCells] = (0, import_react68.useState)(lineCells);
54435
- const pendingCellsRef = (0, import_react68.useRef)(lineCells);
54436
- (0, import_react68.useEffect)(() => {
54799
+ const cacheRef = (0, import_react69.useRef)(null);
54800
+ const [effectiveCells, setEffectiveCells] = (0, import_react69.useState)(lineCells);
54801
+ const pendingCellsRef = (0, import_react69.useRef)(lineCells);
54802
+ (0, import_react69.useEffect)(() => {
54437
54803
  if (pendingCellsRef.current === lineCells) return;
54438
54804
  pendingCellsRef.current = lineCells;
54439
54805
  const id = setTimeout(() => setEffectiveCells(lineCells), LINE_CELLS_DEBOUNCE_MS);
54440
54806
  return () => clearTimeout(id);
54441
54807
  }, [lineCells]);
54442
- return (0, import_react68.useMemo)(() => {
54808
+ return (0, import_react69.useMemo)(() => {
54443
54809
  cacheRef.current = wrapIncremental(text, effectiveCells, cacheRef.current);
54444
54810
  return cacheRef.current.visualLines;
54445
54811
  }, [text, effectiveCells]);
@@ -54462,7 +54828,7 @@ function ReasoningCard({
54462
54828
  const isEmpty = !card.streaming && !card.aborted && card.text.length === 0;
54463
54829
  const showBody = expanded && (card.text.length > 0 || card.streaming || isEmpty);
54464
54830
  const tone = card.aborted ? TONE.err : card.streaming ? TONE_ACTIVE.accent : TONE.accent;
54465
- return /* @__PURE__ */ import_react69.default.createElement(Card, { tone }, /* @__PURE__ */ import_react69.default.createElement(ReasoningHeader, { card, isEmpty }), showBody && (isEmpty ? /* @__PURE__ */ import_react69.default.createElement(EmptyHint, null) : card.streaming ? /* @__PURE__ */ import_react69.default.createElement(StreamingPreview, { card, visualLines, lineCells }) : /* @__PURE__ */ import_react69.default.createElement(SettledPreview, { card, visualLines, lineCells })));
54831
+ return /* @__PURE__ */ import_react70.default.createElement(Card, { tone }, /* @__PURE__ */ import_react70.default.createElement(ReasoningHeader, { card, isEmpty }), showBody && (isEmpty ? /* @__PURE__ */ import_react70.default.createElement(EmptyHint, null) : card.streaming ? /* @__PURE__ */ import_react70.default.createElement(StreamingPreview, { card, visualLines, lineCells }) : /* @__PURE__ */ import_react70.default.createElement(SettledPreview, { card, visualLines, lineCells })));
54466
54832
  }
54467
54833
  function ReasoningHeader({
54468
54834
  card,
@@ -54479,14 +54845,14 @@ function ReasoningHeader({
54479
54845
  const duration = headerDuration(card);
54480
54846
  if (duration) meta.push(duration);
54481
54847
  const modelBadge = card.model ? modelBadgeFor(card.model) : null;
54482
- return /* @__PURE__ */ import_react69.default.createElement(
54848
+ return /* @__PURE__ */ import_react70.default.createElement(
54483
54849
  CardHeader,
54484
54850
  {
54485
54851
  glyph,
54486
54852
  tone: headColor,
54487
54853
  title: title2,
54488
54854
  meta: meta.length > 0 ? meta : void 0,
54489
- right: /* @__PURE__ */ import_react69.default.createElement(import_react69.default.Fragment, null, streamingActive ? /* @__PURE__ */ import_react69.default.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.accent }) : null, modelBadge ? /* @__PURE__ */ import_react69.default.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null)
54855
+ right: /* @__PURE__ */ import_react70.default.createElement(import_react70.default.Fragment, null, streamingActive ? /* @__PURE__ */ import_react70.default.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.accent }) : null, modelBadge ? /* @__PURE__ */ import_react70.default.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null)
54490
54856
  }
54491
54857
  );
54492
54858
  }
@@ -54507,7 +54873,7 @@ function headerDuration(card) {
54507
54873
  function StreamingPreview({ card, visualLines, lineCells }) {
54508
54874
  const visible = visualLines.slice(-STREAMING_PREVIEW_LINES);
54509
54875
  const hasOverflow = visualLines.length > visible.length;
54510
- return /* @__PURE__ */ import_react69.default.createElement(import_react69.default.Fragment, null, hasOverflow ? /* @__PURE__ */ import_react69.default.createElement(Text, { color: FG.faint }, "\u22EE") : null, /* @__PURE__ */ import_react69.default.createElement(
54876
+ return /* @__PURE__ */ import_react70.default.createElement(import_react70.default.Fragment, null, hasOverflow ? /* @__PURE__ */ import_react70.default.createElement(Text, { color: FG.faint }, "\u22EE") : null, /* @__PURE__ */ import_react70.default.createElement(
54511
54877
  BodyLines,
54512
54878
  {
54513
54879
  card,
@@ -54522,16 +54888,16 @@ function SettledPreview({ card, visualLines, lineCells }) {
54522
54888
  if (card.tokens >= XL_TOKEN_THRESHOLD) {
54523
54889
  const visible = visualLines.slice(-SETTLED_TAIL_LINES);
54524
54890
  const droppedLines = Math.max(0, visualLines.length - visible.length);
54525
- return /* @__PURE__ */ import_react69.default.createElement(import_react69.default.Fragment, null, droppedLines > 0 ? /* @__PURE__ */ import_react69.default.createElement(ScrollPastHint, { card }) : null, /* @__PURE__ */ import_react69.default.createElement(BodyLines, { card, lines: visible, lineCells, indexOffset: droppedLines }));
54891
+ return /* @__PURE__ */ import_react70.default.createElement(import_react70.default.Fragment, null, droppedLines > 0 ? /* @__PURE__ */ import_react70.default.createElement(ScrollPastHint, { card }) : null, /* @__PURE__ */ import_react70.default.createElement(BodyLines, { card, lines: visible, lineCells, indexOffset: droppedLines }));
54526
54892
  }
54527
54893
  const totalShown = SETTLED_HEAD_LINES + SETTLED_TAIL_LINES;
54528
54894
  if (visualLines.length <= totalShown) {
54529
- return /* @__PURE__ */ import_react69.default.createElement(BodyLines, { card, lines: visualLines, lineCells, anchor: true });
54895
+ return /* @__PURE__ */ import_react70.default.createElement(BodyLines, { card, lines: visualLines, lineCells, anchor: true });
54530
54896
  }
54531
54897
  const headLines = visualLines.slice(0, SETTLED_HEAD_LINES);
54532
54898
  const tailLines = visualLines.slice(-SETTLED_TAIL_LINES);
54533
54899
  const droppedMid = visualLines.length - headLines.length - tailLines.length;
54534
- return /* @__PURE__ */ import_react69.default.createElement(import_react69.default.Fragment, null, /* @__PURE__ */ import_react69.default.createElement(BodyLines, { card, lines: headLines, lineCells, anchor: true }), /* @__PURE__ */ import_react69.default.createElement(MidElisionHint, { droppedLines: droppedMid }), /* @__PURE__ */ import_react69.default.createElement(
54900
+ return /* @__PURE__ */ import_react70.default.createElement(import_react70.default.Fragment, null, /* @__PURE__ */ import_react70.default.createElement(BodyLines, { card, lines: headLines, lineCells, anchor: true }), /* @__PURE__ */ import_react70.default.createElement(MidElisionHint, { droppedLines: droppedMid }), /* @__PURE__ */ import_react70.default.createElement(
54535
54901
  BodyLines,
54536
54902
  {
54537
54903
  card,
@@ -54542,7 +54908,7 @@ function SettledPreview({ card, visualLines, lineCells }) {
54542
54908
  ));
54543
54909
  }
54544
54910
  function EmptyHint() {
54545
- return /* @__PURE__ */ import_react69.default.createElement(Text, { italic: true, color: FG.faint }, "no thinking \u2014 direct answer");
54911
+ return /* @__PURE__ */ import_react70.default.createElement(Text, { italic: true, color: FG.faint }, "no thinking \u2014 direct answer");
54546
54912
  }
54547
54913
  function BodyLines({
54548
54914
  card,
@@ -54554,24 +54920,24 @@ function BodyLines({
54554
54920
  }) {
54555
54921
  const tone = card.aborted ? TONE.err : card.streaming ? TONE_ACTIVE.accent : TONE.accent;
54556
54922
  const innerCells = lineCells - (anchor ? 2 : 0);
54557
- return /* @__PURE__ */ import_react69.default.createElement(import_react69.default.Fragment, null, lines.map((line, i) => {
54923
+ return /* @__PURE__ */ import_react70.default.createElement(import_react70.default.Fragment, null, lines.map((line, i) => {
54558
54924
  const isLast = i === lines.length - 1;
54559
54925
  const isFirst = i === 0;
54560
- return /* @__PURE__ */ import_react69.default.createElement(Box_default, { key: `${card.id}:b:${indexOffset + i}`, flexDirection: "row", gap: 1 }, anchor ? /* @__PURE__ */ import_react69.default.createElement(Text, { color: tone }, isFirst ? "\u21B3" : " ") : null, /* @__PURE__ */ import_react69.default.createElement(Text, { italic: true, color: FG.meta }, clipToCells(line, innerCells)), isLast && cursorOnLast && /* @__PURE__ */ import_react69.default.createElement(CursorBlock, null));
54926
+ return /* @__PURE__ */ import_react70.default.createElement(Box_default, { key: `${card.id}:b:${indexOffset + i}`, flexDirection: "row", gap: 1 }, anchor ? /* @__PURE__ */ import_react70.default.createElement(Text, { color: tone }, isFirst ? "\u21B3" : " ") : null, /* @__PURE__ */ import_react70.default.createElement(Text, { italic: true, color: FG.meta }, clipToCells(line, innerCells)), isLast && cursorOnLast && /* @__PURE__ */ import_react70.default.createElement(CursorBlock, null));
54561
54927
  }));
54562
54928
  }
54563
54929
  function MidElisionHint({ droppedLines }) {
54564
- return /* @__PURE__ */ import_react69.default.createElement(Text, { color: FG.faint }, `\u22EF ${droppedLines} line${droppedLines === 1 ? "" : "s"} elided`);
54930
+ return /* @__PURE__ */ import_react70.default.createElement(Text, { color: FG.faint }, `\u22EF ${droppedLines} line${droppedLines === 1 ? "" : "s"} elided`);
54565
54931
  }
54566
54932
  function ScrollPastHint({ card }) {
54567
54933
  const parts = [];
54568
54934
  if (card.paragraphs > 0) parts.push(`${card.paragraphs} \xB6`);
54569
54935
  if (card.tokens > 0) parts.push(`~${card.tokens.toLocaleString()} tok`);
54570
- return /* @__PURE__ */ import_react69.default.createElement(Text, { color: FG.faint }, `\u22EF ${parts.join(" + ")} scrolled past \xB7 /reasoning last`);
54936
+ return /* @__PURE__ */ import_react70.default.createElement(Text, { color: FG.faint }, `\u22EF ${parts.join(" + ")} scrolled past \xB7 /reasoning last`);
54571
54937
  }
54572
54938
 
54573
54939
  // src/cli/ui/cards/SearchCard.tsx
54574
- var import_react70 = __toESM(require_react(), 1);
54940
+ var import_react71 = __toESM(require_react(), 1);
54575
54941
  function SearchCard({ card }) {
54576
54942
  const fileCount = new Set(card.hits.map((h) => h.file)).size;
54577
54943
  const elapsed = `${(card.elapsedMs / 1e3).toFixed(2)}s`;
@@ -54580,7 +54946,7 @@ function SearchCard({ card }) {
54580
54946
  files: fileCount
54581
54947
  });
54582
54948
  const grouped = groupByFile(card.hits.slice(0, 10));
54583
- return /* @__PURE__ */ import_react70.default.createElement(Card, { tone: TONE.info }, /* @__PURE__ */ import_react70.default.createElement(
54949
+ return /* @__PURE__ */ import_react71.default.createElement(Card, { tone: TONE.info }, /* @__PURE__ */ import_react71.default.createElement(
54584
54950
  CardHeader,
54585
54951
  {
54586
54952
  glyph: "\u25CF",
@@ -54589,7 +54955,7 @@ function SearchCard({ card }) {
54589
54955
  subtitle: `"${card.query}"`,
54590
54956
  meta: [stats2, elapsed]
54591
54957
  }
54592
- ), grouped.map(([file, hits]) => /* @__PURE__ */ import_react70.default.createElement(Box_default, { key: file, flexDirection: "column" }, /* @__PURE__ */ import_react70.default.createElement(Text, { bold: true, color: FG.strong }, file), hits.map((h, i) => /* @__PURE__ */ import_react70.default.createElement(Box_default, { key: `${file}:${h.line}:${i}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react70.default.createElement(Text, { color: FG.faint }, `${h.line.toString().padStart(4)} \u2502`), /* @__PURE__ */ import_react70.default.createElement(HighlightedLine, { text: h.preview, start: h.matchStart, end: h.matchEnd }))))), card.hits.length > 10 ? /* @__PURE__ */ import_react70.default.createElement(Text, { color: FG.faint }, t(
54958
+ ), grouped.map(([file, hits]) => /* @__PURE__ */ import_react71.default.createElement(Box_default, { key: file, flexDirection: "column" }, /* @__PURE__ */ import_react71.default.createElement(Text, { bold: true, color: FG.strong }, file), hits.map((h, i) => /* @__PURE__ */ import_react71.default.createElement(Box_default, { key: `${file}:${h.line}:${i}`, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react71.default.createElement(Text, { color: FG.faint }, `${h.line.toString().padStart(4)} \u2502`), /* @__PURE__ */ import_react71.default.createElement(HighlightedLine, { text: h.preview, start: h.matchStart, end: h.matchEnd }))))), card.hits.length > 10 ? /* @__PURE__ */ import_react71.default.createElement(Text, { color: FG.faint }, t(
54593
54959
  card.hits.length - 10 === 1 ? "cardLabels.moreHitSingular" : "cardLabels.moreHitsPlural",
54594
54960
  { count: card.hits.length - 10 }
54595
54961
  )) : null);
@@ -54600,9 +54966,9 @@ function HighlightedLine({
54600
54966
  end
54601
54967
  }) {
54602
54968
  if (start < 0 || end <= start || end > text.length) {
54603
- return /* @__PURE__ */ import_react70.default.createElement(Text, { color: FG.sub }, text);
54969
+ return /* @__PURE__ */ import_react71.default.createElement(Text, { color: FG.sub }, text);
54604
54970
  }
54605
- return /* @__PURE__ */ import_react70.default.createElement(import_react70.default.Fragment, null, /* @__PURE__ */ import_react70.default.createElement(Text, { color: FG.sub }, text.slice(0, start)), /* @__PURE__ */ import_react70.default.createElement(Text, { bold: true, inverse: true }, text.slice(start, end)), /* @__PURE__ */ import_react70.default.createElement(Text, { color: FG.sub }, text.slice(end)));
54971
+ return /* @__PURE__ */ import_react71.default.createElement(import_react71.default.Fragment, null, /* @__PURE__ */ import_react71.default.createElement(Text, { color: FG.sub }, text.slice(0, start)), /* @__PURE__ */ import_react71.default.createElement(Text, { bold: true, inverse: true }, text.slice(start, end)), /* @__PURE__ */ import_react71.default.createElement(Text, { color: FG.sub }, text.slice(end)));
54606
54972
  }
54607
54973
  function groupByFile(hits) {
54608
54974
  const map = /* @__PURE__ */ new Map();
@@ -54615,60 +54981,60 @@ function groupByFile(hits) {
54615
54981
  }
54616
54982
 
54617
54983
  // src/cli/ui/cards/StreamingCard.tsx
54618
- var import_react73 = __toESM(require_react(), 1);
54984
+ var import_react74 = __toESM(require_react(), 1);
54619
54985
 
54620
54986
  // src/cli/ui/layout/LiveExpandContext.ts
54621
- var import_react71 = __toESM(require_react(), 1);
54622
- var LiveExpandContext = (0, import_react71.createContext)(false);
54987
+ var import_react72 = __toESM(require_react(), 1);
54988
+ var LiveExpandContext = (0, import_react72.createContext)(false);
54623
54989
 
54624
54990
  // src/cli/ui/markdown.tsx
54625
54991
  var import_cli_highlight = __toESM(require_dist(), 1);
54626
- var import_react72 = __toESM(require_react(), 1);
54992
+ var import_react73 = __toESM(require_react(), 1);
54627
54993
  var BODY_LEFT_CELLS = 7;
54628
- var MarkdownWidthCtx = import_react72.default.createContext(void 0);
54994
+ var MarkdownWidthCtx = import_react73.default.createContext(void 0);
54629
54995
  function useWidth() {
54630
- const ctx = import_react72.default.useContext(MarkdownWidthCtx);
54996
+ const ctx = import_react73.default.useContext(MarkdownWidthCtx);
54631
54997
  if (ctx !== void 0) return ctx;
54632
54998
  return (use_stdout_default()?.stdout?.columns ?? process.stdout.columns ?? 80) - BODY_LEFT_CELLS;
54633
54999
  }
54634
55000
  marked.setOptions({ gfm: true, breaks: false });
54635
55001
  function Markdown({ text, width }) {
54636
- const tokens = import_react72.default.useMemo(() => marked.lexer(text), [text]);
55002
+ const tokens = import_react73.default.useMemo(() => marked.lexer(text), [text]);
54637
55003
  const ctxWidth = width !== void 0 ? Math.max(1, width) : void 0;
54638
- return /* @__PURE__ */ import_react72.default.createElement(MarkdownWidthCtx.Provider, { value: ctxWidth }, /* @__PURE__ */ import_react72.default.createElement(Box_default, { flexDirection: "column", gap: 1 }, tokens.map((token, i) => /* @__PURE__ */ import_react72.default.createElement(BlockToken, { key: `${i}-${token.type}`, token }))));
55004
+ return /* @__PURE__ */ import_react73.default.createElement(MarkdownWidthCtx.Provider, { value: ctxWidth }, /* @__PURE__ */ import_react73.default.createElement(Box_default, { flexDirection: "column", gap: 1 }, tokens.map((token, i) => /* @__PURE__ */ import_react73.default.createElement(BlockToken, { key: `${i}-${token.type}`, token }))));
54639
55005
  }
54640
55006
  function BlockToken({ token }) {
54641
55007
  switch (token.type) {
54642
55008
  case "heading":
54643
- return /* @__PURE__ */ import_react72.default.createElement(Heading, { token });
55009
+ return /* @__PURE__ */ import_react73.default.createElement(Heading, { token });
54644
55010
  case "paragraph":
54645
- return /* @__PURE__ */ import_react72.default.createElement(Paragraph, { token });
55011
+ return /* @__PURE__ */ import_react73.default.createElement(Paragraph, { token });
54646
55012
  case "list":
54647
- return /* @__PURE__ */ import_react72.default.createElement(List, { token, depth: 0 });
55013
+ return /* @__PURE__ */ import_react73.default.createElement(List, { token, depth: 0 });
54648
55014
  case "code":
54649
- return /* @__PURE__ */ import_react72.default.createElement(CodeBlock2, { token });
55015
+ return /* @__PURE__ */ import_react73.default.createElement(CodeBlock2, { token });
54650
55016
  case "blockquote":
54651
- return /* @__PURE__ */ import_react72.default.createElement(Blockquote, { token });
55017
+ return /* @__PURE__ */ import_react73.default.createElement(Blockquote, { token });
54652
55018
  case "hr":
54653
- return /* @__PURE__ */ import_react72.default.createElement(HorizontalRule, null);
55019
+ return /* @__PURE__ */ import_react73.default.createElement(HorizontalRule, null);
54654
55020
  case "table":
54655
- return /* @__PURE__ */ import_react72.default.createElement(Table, { token });
55021
+ return /* @__PURE__ */ import_react73.default.createElement(Table, { token });
54656
55022
  case "html":
54657
- return /* @__PURE__ */ import_react72.default.createElement(Text, { color: FG.body }, token.text);
55023
+ return /* @__PURE__ */ import_react73.default.createElement(Text, { color: FG.body }, token.text);
54658
55024
  case "space":
54659
55025
  return null;
54660
55026
  default:
54661
- return /* @__PURE__ */ import_react72.default.createElement(Text, { color: FG.body }, token.raw ?? "");
55027
+ return /* @__PURE__ */ import_react73.default.createElement(Text, { color: FG.body }, token.raw ?? "");
54662
55028
  }
54663
55029
  }
54664
55030
  function Heading({ token }) {
54665
- return /* @__PURE__ */ import_react72.default.createElement(Box_default, null, /* @__PURE__ */ import_react72.default.createElement(Text, { bold: true, color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${plainText(token.tokens)} `));
55031
+ return /* @__PURE__ */ import_react73.default.createElement(Box_default, null, /* @__PURE__ */ import_react73.default.createElement(Text, { bold: true, color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${plainText(token.tokens)} `));
54666
55032
  }
54667
55033
  function Paragraph({ token }) {
54668
- return /* @__PURE__ */ import_react72.default.createElement(Text, { color: FG.body }, /* @__PURE__ */ import_react72.default.createElement(Inline, { tokens: token.tokens ?? [] }));
55034
+ return /* @__PURE__ */ import_react73.default.createElement(Text, { color: FG.body }, /* @__PURE__ */ import_react73.default.createElement(Inline, { tokens: token.tokens ?? [] }));
54669
55035
  }
54670
55036
  function List({ token, depth }) {
54671
- return /* @__PURE__ */ import_react72.default.createElement(Box_default, { flexDirection: "column" }, token.items.map((item, i) => /* @__PURE__ */ import_react72.default.createElement(
55037
+ return /* @__PURE__ */ import_react73.default.createElement(Box_default, { flexDirection: "column" }, token.items.map((item, i) => /* @__PURE__ */ import_react73.default.createElement(
54672
55038
  ListItem,
54673
55039
  {
54674
55040
  key: `${i}-${item.text.slice(0, 24)}`,
@@ -54689,27 +55055,27 @@ function ListItem({
54689
55055
  const markerColor = item.task ? item.checked ? TONE.ok : FG.faint : FG.meta;
54690
55056
  const dim = item.task && item.checked === true;
54691
55057
  const indent = " ".repeat(depth + 1);
54692
- return /* @__PURE__ */ import_react72.default.createElement(Box_default, null, /* @__PURE__ */ import_react72.default.createElement(Text, { color: markerColor }, `${indent}${marker} `), /* @__PURE__ */ import_react72.default.createElement(Box_default, { flexDirection: "column" }, item.tokens.map((tok, i) => {
55058
+ return /* @__PURE__ */ import_react73.default.createElement(Box_default, null, /* @__PURE__ */ import_react73.default.createElement(Text, { color: markerColor }, `${indent}${marker} `), /* @__PURE__ */ import_react73.default.createElement(Box_default, { flexDirection: "column" }, item.tokens.map((tok, i) => {
54693
55059
  if (tok.type === "text") {
54694
55060
  const inner = tok.tokens;
54695
55061
  return (
54696
55062
  // biome-ignore lint/suspicious/noArrayIndexKey: list-item children are positional and stable per render
54697
- /* @__PURE__ */ import_react72.default.createElement(Text, { key: `t-${i}`, color: dim ? FG.faint : FG.body, strikethrough: dim }, inner ? /* @__PURE__ */ import_react72.default.createElement(Inline, { tokens: inner }) : tok.text)
55063
+ /* @__PURE__ */ import_react73.default.createElement(Text, { key: `t-${i}`, color: dim ? FG.faint : FG.body, strikethrough: dim }, inner ? /* @__PURE__ */ import_react73.default.createElement(Inline, { tokens: inner }) : tok.text)
54698
55064
  );
54699
55065
  }
54700
55066
  if (tok.type === "list") {
54701
- return /* @__PURE__ */ import_react72.default.createElement(List, { key: `l-${i}`, token: tok, depth: depth + 1 });
55067
+ return /* @__PURE__ */ import_react73.default.createElement(List, { key: `l-${i}`, token: tok, depth: depth + 1 });
54702
55068
  }
54703
- return /* @__PURE__ */ import_react72.default.createElement(BlockToken, { key: `b-${i}-${tok.type}`, token: tok });
55069
+ return /* @__PURE__ */ import_react73.default.createElement(BlockToken, { key: `b-${i}-${tok.type}`, token: tok });
54704
55070
  })));
54705
55071
  }
54706
55072
  function CodeBlock2({ token }) {
54707
55073
  const lang = token.lang?.split(/\s+/)[0] ?? "";
54708
55074
  const colored = highlightCode(decodeHtmlEntities(token.text), lang);
54709
55075
  const lines = colored.split("\n");
54710
- return /* @__PURE__ */ import_react72.default.createElement(Box_default, { flexDirection: "column" }, lang ? /* @__PURE__ */ import_react72.default.createElement(Box_default, null, /* @__PURE__ */ import_react72.default.createElement(Text, { color: FG.meta }, ` ${lang}`)) : null, /* @__PURE__ */ import_react72.default.createElement(Box_default, { flexDirection: "column" }, lines.map((line, i) => (
55076
+ return /* @__PURE__ */ import_react73.default.createElement(Box_default, { flexDirection: "column" }, lang ? /* @__PURE__ */ import_react73.default.createElement(Box_default, null, /* @__PURE__ */ import_react73.default.createElement(Text, { color: FG.meta }, ` ${lang}`)) : null, /* @__PURE__ */ import_react73.default.createElement(Box_default, { flexDirection: "column" }, lines.map((line, i) => (
54711
55077
  // biome-ignore lint/suspicious/noArrayIndexKey: code lines are positional and stable per render
54712
- /* @__PURE__ */ import_react72.default.createElement(Text, { key: `code-${i}`, backgroundColor: SURFACE.bgElev }, ` ${line} `)
55078
+ /* @__PURE__ */ import_react73.default.createElement(Text, { key: `code-${i}`, backgroundColor: SURFACE.bgElev }, ` ${line} `)
54713
55079
  ))));
54714
55080
  }
54715
55081
  function highlightCode(source, lang) {
@@ -54722,7 +55088,7 @@ function highlightCode(source, lang) {
54722
55088
  }
54723
55089
  }
54724
55090
  function Blockquote({ token }) {
54725
- return /* @__PURE__ */ import_react72.default.createElement(Box_default, { flexDirection: "column" }, (token.tokens ?? []).map((child, i) => /* @__PURE__ */ import_react72.default.createElement(Box_default, { key: `${i}-${child.type}`, flexDirection: "row" }, /* @__PURE__ */ import_react72.default.createElement(Text, { color: TONE.brand }, " \u258E "), /* @__PURE__ */ import_react72.default.createElement(Box_default, { flexDirection: "column", flexGrow: 1 }, child.type === "paragraph" ? /* @__PURE__ */ import_react72.default.createElement(Text, { italic: true, color: FG.sub }, /* @__PURE__ */ import_react72.default.createElement(Inline, { tokens: child.tokens ?? [] })) : /* @__PURE__ */ import_react72.default.createElement(BlockToken, { token: child })))));
55091
+ return /* @__PURE__ */ import_react73.default.createElement(Box_default, { flexDirection: "column" }, (token.tokens ?? []).map((child, i) => /* @__PURE__ */ import_react73.default.createElement(Box_default, { key: `${i}-${child.type}`, flexDirection: "row" }, /* @__PURE__ */ import_react73.default.createElement(Text, { color: TONE.brand }, " \u258E "), /* @__PURE__ */ import_react73.default.createElement(Box_default, { flexDirection: "column", flexGrow: 1 }, child.type === "paragraph" ? /* @__PURE__ */ import_react73.default.createElement(Text, { italic: true, color: FG.sub }, /* @__PURE__ */ import_react73.default.createElement(Inline, { tokens: child.tokens ?? [] })) : /* @__PURE__ */ import_react73.default.createElement(BlockToken, { token: child })))));
54726
55092
  }
54727
55093
  function padToCells(text, cells) {
54728
55094
  const w = stringWidth(text);
@@ -54732,7 +55098,7 @@ function padToCells(text, cells) {
54732
55098
  function HorizontalRule() {
54733
55099
  const width = useWidth();
54734
55100
  const rule = "\u2500".repeat(Math.max(width, 1));
54735
- return /* @__PURE__ */ import_react72.default.createElement(Text, { color: FG.faint }, ` ${rule}`);
55101
+ return /* @__PURE__ */ import_react73.default.createElement(Text, { color: FG.faint }, ` ${rule}`);
54736
55102
  }
54737
55103
  function tableLayout(headerCells, bodyCells, availableWidth) {
54738
55104
  const colCount = headerCells.length;
@@ -54760,7 +55126,7 @@ function Table({ token }) {
54760
55126
  const bodyCells = token.rows.map((row2) => row2.map((c) => plainText(c.tokens)));
54761
55127
  const layout = tableLayout(headerCells, bodyCells, width);
54762
55128
  if (!layout.fallback)
54763
- return /* @__PURE__ */ import_react72.default.createElement(
55129
+ return /* @__PURE__ */ import_react73.default.createElement(
54764
55130
  ColumnarTable,
54765
55131
  {
54766
55132
  headerCells,
@@ -54770,7 +55136,7 @@ function Table({ token }) {
54770
55136
  gap: layout.gap
54771
55137
  }
54772
55138
  );
54773
- return /* @__PURE__ */ import_react72.default.createElement(
55139
+ return /* @__PURE__ */ import_react73.default.createElement(
54774
55140
  FallbackTable,
54775
55141
  {
54776
55142
  headerCells,
@@ -54788,14 +55154,14 @@ function ColumnarTable({
54788
55154
  gap
54789
55155
  }) {
54790
55156
  const ruleRow = widths.map((w) => "\u2500".repeat(w)).join(gap);
54791
- return /* @__PURE__ */ import_react72.default.createElement(Box_default, { flexDirection: "column" }, /* @__PURE__ */ import_react72.default.createElement(Box_default, null, /* @__PURE__ */ import_react72.default.createElement(Text, null, " "), headerCells.map((cell, i) => (
55157
+ return /* @__PURE__ */ import_react73.default.createElement(Box_default, { flexDirection: "column" }, /* @__PURE__ */ import_react73.default.createElement(Box_default, null, /* @__PURE__ */ import_react73.default.createElement(Text, null, " "), headerCells.map((cell, i) => (
54792
55158
  // biome-ignore lint/suspicious/noArrayIndexKey: header cells positional
54793
- /* @__PURE__ */ import_react72.default.createElement(import_react72.default.Fragment, { key: `h-${i}` }, /* @__PURE__ */ import_react72.default.createElement(Text, { bold: true, color: FG.sub }, padToCells(cell, widths[i])), i < colCount - 1 ? /* @__PURE__ */ import_react72.default.createElement(Text, null, gap) : null)
54794
- ))), /* @__PURE__ */ import_react72.default.createElement(Box_default, null, /* @__PURE__ */ import_react72.default.createElement(Text, null, " "), /* @__PURE__ */ import_react72.default.createElement(Text, { color: FG.faint }, ruleRow)), bodyCells.map((row2, ri) => (
55159
+ /* @__PURE__ */ import_react73.default.createElement(import_react73.default.Fragment, { key: `h-${i}` }, /* @__PURE__ */ import_react73.default.createElement(Text, { bold: true, color: FG.sub }, padToCells(cell, widths[i])), i < colCount - 1 ? /* @__PURE__ */ import_react73.default.createElement(Text, null, gap) : null)
55160
+ ))), /* @__PURE__ */ import_react73.default.createElement(Box_default, null, /* @__PURE__ */ import_react73.default.createElement(Text, null, " "), /* @__PURE__ */ import_react73.default.createElement(Text, { color: FG.faint }, ruleRow)), bodyCells.map((row2, ri) => (
54795
55161
  // biome-ignore lint/suspicious/noArrayIndexKey: body rows positional
54796
- /* @__PURE__ */ import_react72.default.createElement(Box_default, { key: `tr-${ri}` }, /* @__PURE__ */ import_react72.default.createElement(Text, null, " "), row2.map((cell, i) => (
55162
+ /* @__PURE__ */ import_react73.default.createElement(Box_default, { key: `tr-${ri}` }, /* @__PURE__ */ import_react73.default.createElement(Text, null, " "), row2.map((cell, i) => (
54797
55163
  // biome-ignore lint/suspicious/noArrayIndexKey: cells positional
54798
- /* @__PURE__ */ import_react72.default.createElement(import_react72.default.Fragment, { key: `c-${ri}-${i}` }, /* @__PURE__ */ import_react72.default.createElement(Text, { color: FG.body }, padToCells(cell ?? "", widths[i])), i < colCount - 1 ? /* @__PURE__ */ import_react72.default.createElement(Text, null, gap) : null)
55164
+ /* @__PURE__ */ import_react73.default.createElement(import_react73.default.Fragment, { key: `c-${ri}-${i}` }, /* @__PURE__ */ import_react73.default.createElement(Text, { color: FG.body }, padToCells(cell ?? "", widths[i])), i < colCount - 1 ? /* @__PURE__ */ import_react73.default.createElement(Text, null, gap) : null)
54799
55165
  )))
54800
55166
  )));
54801
55167
  }
@@ -54805,20 +55171,20 @@ function FallbackTable({
54805
55171
  labelPad,
54806
55172
  valueCells
54807
55173
  }) {
54808
- return /* @__PURE__ */ import_react72.default.createElement(Box_default, { flexDirection: "column" }, bodyCells.map((row2, ri) => (
55174
+ return /* @__PURE__ */ import_react73.default.createElement(Box_default, { flexDirection: "column" }, bodyCells.map((row2, ri) => (
54809
55175
  // biome-ignore lint/suspicious/noArrayIndexKey: body rows positional
54810
- /* @__PURE__ */ import_react72.default.createElement(Box_default, { key: `fr-${ri}`, flexDirection: "column" }, ri > 0 ? /* @__PURE__ */ import_react72.default.createElement(Text, null, " ") : null, headerCells.map((h, ci) => {
55176
+ /* @__PURE__ */ import_react73.default.createElement(Box_default, { key: `fr-${ri}`, flexDirection: "column" }, ri > 0 ? /* @__PURE__ */ import_react73.default.createElement(Text, null, " ") : null, headerCells.map((h, ci) => {
54811
55177
  const label = `${padToCells(h, labelPad - 2)}: `;
54812
55178
  const lines = wrapToCells(row2[ci] ?? "", valueCells);
54813
55179
  return lines.map((line, li) => (
54814
55180
  // biome-ignore lint/suspicious/noArrayIndexKey: fallback table lines are positional
54815
- /* @__PURE__ */ import_react72.default.createElement(Box_default, { key: `fc-${ri}-${ci}-${li}` }, li === 0 ? /* @__PURE__ */ import_react72.default.createElement(Text, { bold: true, color: FG.sub }, label) : /* @__PURE__ */ import_react72.default.createElement(Text, null, padToCells("", labelPad)), /* @__PURE__ */ import_react72.default.createElement(Text, { color: FG.body }, line))
55181
+ /* @__PURE__ */ import_react73.default.createElement(Box_default, { key: `fc-${ri}-${ci}-${li}` }, li === 0 ? /* @__PURE__ */ import_react73.default.createElement(Text, { bold: true, color: FG.sub }, label) : /* @__PURE__ */ import_react73.default.createElement(Text, null, padToCells("", labelPad)), /* @__PURE__ */ import_react73.default.createElement(Text, { color: FG.body }, line))
54816
55182
  ));
54817
55183
  }))
54818
55184
  )));
54819
55185
  }
54820
55186
  function Inline({ tokens }) {
54821
- return /* @__PURE__ */ import_react72.default.createElement(import_react72.default.Fragment, null, tokens.map((tok, i) => /* @__PURE__ */ import_react72.default.createElement(InlineToken, { key: `${i}-${tok.type}`, token: tok })));
55187
+ return /* @__PURE__ */ import_react73.default.createElement(import_react73.default.Fragment, null, tokens.map((tok, i) => /* @__PURE__ */ import_react73.default.createElement(InlineToken, { key: `${i}-${tok.type}`, token: tok })));
54822
55188
  }
54823
55189
  var FILE_REF_RE2 = /\b([A-Za-z0-9_./@\-]+\.[A-Za-z0-9]{1,6})(?::(\d+)(?:-(\d+))?)?\b/g;
54824
55190
  var MENTION_RE = /(?<![A-Za-z0-9_])@([A-Za-z0-9_./\-]+\.[A-Za-z0-9]{1,6})/g;
@@ -54829,10 +55195,10 @@ function looksLikeFileRef(path, hasLine) {
54829
55195
  return ext.length >= 2;
54830
55196
  }
54831
55197
  function osc8(children, target, color) {
54832
- return /* @__PURE__ */ import_react72.default.createElement(Transform, { transform: (text) => `\x1B]8;;${target}\x1B\\${text}\x1B]8;;\x1B\\` }, /* @__PURE__ */ import_react72.default.createElement(Text, { color, underline: true }, children));
55198
+ return /* @__PURE__ */ import_react73.default.createElement(Transform, { transform: (text) => `\x1B]8;;${target}\x1B\\${text}\x1B]8;;\x1B\\` }, /* @__PURE__ */ import_react73.default.createElement(Text, { color, underline: true }, children));
54833
55199
  }
54834
55200
  function renderInlineText(raw) {
54835
- if (!raw) return /* @__PURE__ */ import_react72.default.createElement(Text, null, raw);
55201
+ if (!raw) return /* @__PURE__ */ import_react73.default.createElement(Text, null, raw);
54836
55202
  const out = [];
54837
55203
  let cursor = 0;
54838
55204
  const hits = [];
@@ -54843,7 +55209,7 @@ function renderInlineText(raw) {
54843
55209
  hits.push({
54844
55210
  start,
54845
55211
  end,
54846
- node: /* @__PURE__ */ import_react72.default.createElement(Text, { color: TONE.warn, underline: true }, `@${path}`)
55212
+ node: /* @__PURE__ */ import_react73.default.createElement(Text, { color: TONE.warn, underline: true }, `@${path}`)
54847
55213
  });
54848
55214
  }
54849
55215
  for (const m of raw.matchAll(FILE_REF_RE2)) {
@@ -54860,44 +55226,44 @@ function renderInlineText(raw) {
54860
55226
  let key = 0;
54861
55227
  for (const h of hits) {
54862
55228
  if (h.start > cursor) {
54863
- out.push(/* @__PURE__ */ import_react72.default.createElement(Text, { key: `t-${key++}` }, raw.slice(cursor, h.start)));
55229
+ out.push(/* @__PURE__ */ import_react73.default.createElement(Text, { key: `t-${key++}` }, raw.slice(cursor, h.start)));
54864
55230
  }
54865
- out.push(/* @__PURE__ */ import_react72.default.createElement(import_react72.default.Fragment, { key: `r-${key++}` }, h.node));
55231
+ out.push(/* @__PURE__ */ import_react73.default.createElement(import_react73.default.Fragment, { key: `r-${key++}` }, h.node));
54866
55232
  cursor = h.end;
54867
55233
  }
54868
- if (cursor < raw.length) out.push(/* @__PURE__ */ import_react72.default.createElement(Text, { key: `t-${key++}` }, raw.slice(cursor)));
54869
- return /* @__PURE__ */ import_react72.default.createElement(import_react72.default.Fragment, null, out);
55234
+ if (cursor < raw.length) out.push(/* @__PURE__ */ import_react73.default.createElement(Text, { key: `t-${key++}` }, raw.slice(cursor)));
55235
+ return /* @__PURE__ */ import_react73.default.createElement(import_react73.default.Fragment, null, out);
54870
55236
  }
54871
55237
  function InlineToken({ token }) {
54872
55238
  switch (token.type) {
54873
55239
  case "text": {
54874
55240
  const t2 = token;
54875
- return t2.tokens ? /* @__PURE__ */ import_react72.default.createElement(Inline, { tokens: t2.tokens }) : renderInlineText(t2.text);
55241
+ return t2.tokens ? /* @__PURE__ */ import_react73.default.createElement(Inline, { tokens: t2.tokens }) : renderInlineText(t2.text);
54876
55242
  }
54877
55243
  case "strong":
54878
- return /* @__PURE__ */ import_react72.default.createElement(Text, { bold: true, color: FG.strong }, /* @__PURE__ */ import_react72.default.createElement(Inline, { tokens: token.tokens }));
55244
+ return /* @__PURE__ */ import_react73.default.createElement(Text, { bold: true, color: FG.strong }, /* @__PURE__ */ import_react73.default.createElement(Inline, { tokens: token.tokens }));
54879
55245
  case "em":
54880
- return /* @__PURE__ */ import_react72.default.createElement(Text, { italic: true }, /* @__PURE__ */ import_react72.default.createElement(Inline, { tokens: token.tokens }));
55246
+ return /* @__PURE__ */ import_react73.default.createElement(Text, { italic: true }, /* @__PURE__ */ import_react73.default.createElement(Inline, { tokens: token.tokens }));
54881
55247
  case "codespan":
54882
- return /* @__PURE__ */ import_react72.default.createElement(Text, { color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${decodeHtmlEntities(token.text)} `);
55248
+ return /* @__PURE__ */ import_react73.default.createElement(Text, { color: FG.strong, backgroundColor: SURFACE.bgElev }, ` ${decodeHtmlEntities(token.text)} `);
54883
55249
  case "del":
54884
- return /* @__PURE__ */ import_react72.default.createElement(Text, { color: TONE.err, strikethrough: true }, /* @__PURE__ */ import_react72.default.createElement(Inline, { tokens: token.tokens }));
55250
+ return /* @__PURE__ */ import_react73.default.createElement(Text, { color: TONE.err, strikethrough: true }, /* @__PURE__ */ import_react73.default.createElement(Inline, { tokens: token.tokens }));
54885
55251
  case "link": {
54886
55252
  const l = token;
54887
- return osc8(/* @__PURE__ */ import_react72.default.createElement(Inline, { tokens: l.tokens }), l.href, TONE.brand);
55253
+ return osc8(/* @__PURE__ */ import_react73.default.createElement(Inline, { tokens: l.tokens }), l.href, TONE.brand);
54888
55254
  }
54889
55255
  case "image": {
54890
55256
  const im = token;
54891
- return /* @__PURE__ */ import_react72.default.createElement(Text, { color: TONE.brand }, `[image: ${im.text || im.href}]`);
55257
+ return /* @__PURE__ */ import_react73.default.createElement(Text, { color: TONE.brand }, `[image: ${im.text || im.href}]`);
54892
55258
  }
54893
55259
  case "br":
54894
- return /* @__PURE__ */ import_react72.default.createElement(Text, null, "\n");
55260
+ return /* @__PURE__ */ import_react73.default.createElement(Text, null, "\n");
54895
55261
  case "escape":
54896
- return /* @__PURE__ */ import_react72.default.createElement(Text, null, token.text);
55262
+ return /* @__PURE__ */ import_react73.default.createElement(Text, null, token.text);
54897
55263
  case "html":
54898
- return /* @__PURE__ */ import_react72.default.createElement(Text, null, token.text);
55264
+ return /* @__PURE__ */ import_react73.default.createElement(Text, null, token.text);
54899
55265
  default:
54900
- return /* @__PURE__ */ import_react72.default.createElement(Text, null, token.raw ?? "");
55266
+ return /* @__PURE__ */ import_react73.default.createElement(Text, null, token.raw ?? "");
54901
55267
  }
54902
55268
  }
54903
55269
  function plainText(tokens) {
@@ -54970,7 +55336,7 @@ function estimateLiveTokenCount(text, cardId, calibration, countFn = countTokens
54970
55336
  };
54971
55337
  }
54972
55338
  function useLiveTokenRate(card, enabled) {
54973
- const calibrationRef = import_react73.default.useRef(null);
55339
+ const calibrationRef = import_react74.default.useRef(null);
54974
55340
  if (!enabled) return { tokens: 0, tps: null };
54975
55341
  const estimate = estimateLiveTokenCount(card.text, card.id, calibrationRef.current);
54976
55342
  calibrationRef.current = estimate.calibration;
@@ -54980,7 +55346,7 @@ var PILL_RATE = { bg: "#11141a", fg: "#8b949e" };
54980
55346
  function StreamingCard({ card }) {
54981
55347
  const { stdout } = use_stdout_default();
54982
55348
  const cols = stdout?.columns ?? 80;
54983
- const expanded = (0, import_react73.useContext)(LiveExpandContext);
55349
+ const expanded = (0, import_react74.useContext)(LiveExpandContext);
54984
55350
  const reserveCap = expanded ? EXPANDED_MAX_LINES + 2 : STREAMING_PREVIEW_LINES2 + 2;
54985
55351
  useReserveRows("stream", {
54986
55352
  min: STREAMING_PREVIEW_LINES2 + 1,
@@ -54991,19 +55357,19 @@ function StreamingCard({ card }) {
54991
55357
  const lineCells = Math.max(20, cols - 4);
54992
55358
  const visualLines = useIncrementalWrap(card.text, lineCells);
54993
55359
  const modelBadge = card.model ? modelBadgeFor(card.model) : null;
54994
- const modelPill = modelBadge ? /* @__PURE__ */ import_react73.default.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null;
55360
+ const modelPill = modelBadge ? /* @__PURE__ */ import_react74.default.createElement(Pill, { label: modelBadge.label, ...PILL_MODEL[modelBadge.kind], bold: false }) : null;
54995
55361
  if (card.done && !card.aborted) {
54996
55362
  const { tokens, tps } = tokenRate(card.text, card.ts, card.endedAt ?? Date.now());
54997
- const ratePill = tokens >= MIN_TOKENS_FOR_RATE && tps !== null ? /* @__PURE__ */ import_react73.default.createElement(Pill, { label: `${formatTokenCount(tokens)} tok \xB7 ${tps} t/s`, ...PILL_RATE, bold: false }) : null;
54998
- return /* @__PURE__ */ import_react73.default.createElement(Card, { tone: TONE.ok }, /* @__PURE__ */ import_react73.default.createElement(
55363
+ const ratePill = tokens >= MIN_TOKENS_FOR_RATE && tps !== null ? /* @__PURE__ */ import_react74.default.createElement(Pill, { label: `${formatTokenCount(tokens)} tok \xB7 ${tps} t/s`, ...PILL_RATE, bold: false }) : null;
55364
+ return /* @__PURE__ */ import_react74.default.createElement(Card, { tone: TONE.ok }, /* @__PURE__ */ import_react74.default.createElement(
54999
55365
  CardHeader,
55000
55366
  {
55001
55367
  glyph: "\u2039",
55002
55368
  tone: TONE.ok,
55003
55369
  title: t("cardTitles.reply"),
55004
- right: /* @__PURE__ */ import_react73.default.createElement(import_react73.default.Fragment, null, ratePill, modelPill)
55370
+ right: /* @__PURE__ */ import_react74.default.createElement(import_react74.default.Fragment, null, ratePill, modelPill)
55005
55371
  }
55006
- ), /* @__PURE__ */ import_react73.default.createElement(Markdown, { text: card.text }));
55372
+ ), /* @__PURE__ */ import_react74.default.createElement(Markdown, { text: card.text }));
55007
55373
  }
55008
55374
  const cap = expanded ? EXPANDED_MAX_LINES : STREAMING_PREVIEW_LINES2;
55009
55375
  const visible = visualLines.slice(-cap);
@@ -55012,23 +55378,23 @@ function StreamingCard({ card }) {
55012
55378
  const headColor = aborted ? TONE.err : TONE_ACTIVE.brand;
55013
55379
  const glyph = aborted ? "\u2298" : "\u25CF";
55014
55380
  const headLabel = aborted ? t("cardLabels.aborted") : t("cardLabels.writing");
55015
- const liveRatePill = !aborted && liveRate.tokens >= MIN_TOKENS_FOR_RATE && liveRate.tps !== null ? /* @__PURE__ */ import_react73.default.createElement(Pill, { label: `${liveRate.tps} t/s`, ...PILL_RATE, bold: false }) : null;
55016
- const expandPill = !aborted ? /* @__PURE__ */ import_react73.default.createElement(Pill, { label: expanded ? "expanded \u2303o" : "preview \u2303o", ...PILL_RATE, bold: false }) : null;
55017
- return /* @__PURE__ */ import_react73.default.createElement(Card, { tone: headColor }, /* @__PURE__ */ import_react73.default.createElement(
55381
+ const liveRatePill = !aborted && liveRate.tokens >= MIN_TOKENS_FOR_RATE && liveRate.tps !== null ? /* @__PURE__ */ import_react74.default.createElement(Pill, { label: `${liveRate.tps} t/s`, ...PILL_RATE, bold: false }) : null;
55382
+ const expandPill = !aborted ? /* @__PURE__ */ import_react74.default.createElement(Pill, { label: expanded ? "expanded \u2303o" : "preview \u2303o", ...PILL_RATE, bold: false }) : null;
55383
+ return /* @__PURE__ */ import_react74.default.createElement(Card, { tone: headColor }, /* @__PURE__ */ import_react74.default.createElement(
55018
55384
  CardHeader,
55019
55385
  {
55020
55386
  glyph,
55021
55387
  tone: headColor,
55022
55388
  title: headLabel,
55023
- right: /* @__PURE__ */ import_react73.default.createElement(import_react73.default.Fragment, null, liveRatePill, expandPill, aborted ? null : /* @__PURE__ */ import_react73.default.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.brand }), modelPill)
55389
+ right: /* @__PURE__ */ import_react74.default.createElement(import_react74.default.Fragment, null, liveRatePill, expandPill, aborted ? null : /* @__PURE__ */ import_react74.default.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.brand }), modelPill)
55024
55390
  }
55025
- ), expanded && droppedAbove > 0 ? /* @__PURE__ */ import_react73.default.createElement(Text, { color: FG.faint }, t(droppedAbove === 1 ? "cardLabels.earlierLine" : "cardLabels.earlierLines", {
55391
+ ), expanded && droppedAbove > 0 ? /* @__PURE__ */ import_react74.default.createElement(Text, { color: FG.faint }, t(droppedAbove === 1 ? "cardLabels.earlierLine" : "cardLabels.earlierLines", {
55026
55392
  count: droppedAbove
55027
- })) : null, visible.map((line, i) => /* @__PURE__ */ import_react73.default.createElement(Box_default, { key: `${card.id}:${visualLines.length - visible.length + i}`, flexDirection: "row" }, /* @__PURE__ */ import_react73.default.createElement(Text, { color: aborted ? FG.meta : FG.body }, clipToCells(line, lineCells)))), aborted ? /* @__PURE__ */ import_react73.default.createElement(Text, { color: FG.faint }, t("cardLabels.truncatedByEsc")) : null);
55393
+ })) : null, visible.map((line, i) => /* @__PURE__ */ import_react74.default.createElement(Box_default, { key: `${card.id}:${visualLines.length - visible.length + i}`, flexDirection: "row" }, /* @__PURE__ */ import_react74.default.createElement(Text, { color: aborted ? FG.meta : FG.body }, clipToCells(line, lineCells)))), aborted ? /* @__PURE__ */ import_react74.default.createElement(Text, { color: FG.faint }, t("cardLabels.truncatedByEsc")) : null);
55028
55394
  }
55029
55395
 
55030
55396
  // src/cli/ui/cards/SubAgentCard.tsx
55031
- var import_react74 = __toESM(require_react(), 1);
55397
+ var import_react75 = __toESM(require_react(), 1);
55032
55398
  function SubAgentCard({ card }) {
55033
55399
  const { fg, tone, toneActive } = useThemeTokens();
55034
55400
  const statusColor = {
@@ -55040,9 +55406,9 @@ function SubAgentCard({ card }) {
55040
55406
  const headGlyph = card.status === "failed" ? "\u2717" : "\u232C";
55041
55407
  const runningChildren = card.children.filter((c) => !isChildDone(c)).length;
55042
55408
  const isRunning = card.status === "running";
55043
- const inLive = (0, import_react74.useContext)(ActiveCardContext);
55409
+ const inLive = (0, import_react75.useContext)(ActiveCardContext);
55044
55410
  const headerMeta2 = isRunning ? runningChildren > 0 ? [`${runningChildren} ${t("cardLabels.runningLabel")}`] : [t("cardLabels.workingLabel")] : [{ text: card.status, color: headColor }];
55045
- return /* @__PURE__ */ import_react74.default.createElement(Card, { tone: headColor }, /* @__PURE__ */ import_react74.default.createElement(
55411
+ return /* @__PURE__ */ import_react75.default.createElement(Card, { tone: headColor }, /* @__PURE__ */ import_react75.default.createElement(
55046
55412
  CardHeader,
55047
55413
  {
55048
55414
  glyph: headGlyph,
@@ -55051,7 +55417,7 @@ function SubAgentCard({ card }) {
55051
55417
  subtitle: card.task,
55052
55418
  meta: headerMeta2
55053
55419
  }
55054
- ), card.name ? /* @__PURE__ */ import_react74.default.createElement(Text, { color: fg.faint }, `${t("cardLabels.agent")} \xB7 ${card.name}`) : null, card.tools && card.tools.length > 0 && /* @__PURE__ */ import_react74.default.createElement(Text, { color: fg.faint }, `${t("cardLabels.tools")} \xB7 ${card.tools.join(", ")}`), card.children.map((child) => /* @__PURE__ */ import_react74.default.createElement(Box_default, { key: child.id, flexDirection: "row", gap: 1 }, inLive ? null : /* @__PURE__ */ import_react74.default.createElement(Text, { color: tone.violet }, "\u23BF"), /* @__PURE__ */ import_react74.default.createElement(ChildRow, { card: child }))));
55420
+ ), card.name ? /* @__PURE__ */ import_react75.default.createElement(Text, { color: fg.faint }, `${t("cardLabels.agent")} \xB7 ${card.name}`) : null, card.tools && card.tools.length > 0 && /* @__PURE__ */ import_react75.default.createElement(Text, { color: fg.faint }, `${t("cardLabels.tools")} \xB7 ${card.tools.join(", ")}`), card.children.map((child) => /* @__PURE__ */ import_react75.default.createElement(Box_default, { key: child.id, flexDirection: "row", gap: 1 }, inLive ? null : /* @__PURE__ */ import_react75.default.createElement(Text, { color: tone.violet }, "\u23BF"), /* @__PURE__ */ import_react75.default.createElement(ChildRow, { card: child }))));
55055
55421
  }
55056
55422
  function isChildDone(card) {
55057
55423
  switch (card.kind) {
@@ -55068,16 +55434,16 @@ function ChildRow({ card }) {
55068
55434
  const { fg, tone } = useThemeTokens();
55069
55435
  const v = childVisual(card, tone.ok, tone.err, fg.faint);
55070
55436
  const isDone = isChildDone(card);
55071
- return /* @__PURE__ */ import_react74.default.createElement(import_react74.default.Fragment, null, v.statusGlyph, /* @__PURE__ */ import_react74.default.createElement(Text, { color: v.kindColor }, v.kindGlyph), /* @__PURE__ */ import_react74.default.createElement(Text, { dimColor: isDone, color: fg.body }, v.text));
55437
+ return /* @__PURE__ */ import_react75.default.createElement(import_react75.default.Fragment, null, v.statusGlyph, /* @__PURE__ */ import_react75.default.createElement(Text, { color: v.kindColor }, v.kindGlyph), /* @__PURE__ */ import_react75.default.createElement(Text, { dimColor: isDone, color: fg.body }, v.text));
55072
55438
  }
55073
55439
  function runningGlyph(color) {
55074
- return /* @__PURE__ */ import_react74.default.createElement(Spinner, { kind: "circle", color });
55440
+ return /* @__PURE__ */ import_react75.default.createElement(Spinner, { kind: "circle", color });
55075
55441
  }
55076
55442
  function doneGlyph(color) {
55077
- return /* @__PURE__ */ import_react74.default.createElement(Text, { color }, "\u2713");
55443
+ return /* @__PURE__ */ import_react75.default.createElement(Text, { color }, "\u2713");
55078
55444
  }
55079
55445
  function failedGlyph(color) {
55080
- return /* @__PURE__ */ import_react74.default.createElement(Text, { color }, "\u2717");
55446
+ return /* @__PURE__ */ import_react75.default.createElement(Text, { color }, "\u2717");
55081
55447
  }
55082
55448
  function childVisual(card, doneColor, failedColor, fallbackColor) {
55083
55449
  switch (card.kind) {
@@ -55122,7 +55488,7 @@ function childVisual(card, doneColor, failedColor, fallbackColor) {
55122
55488
  };
55123
55489
  default:
55124
55490
  return {
55125
- statusGlyph: /* @__PURE__ */ import_react74.default.createElement(Text, { color: fallbackColor }, "\xB7"),
55491
+ statusGlyph: /* @__PURE__ */ import_react75.default.createElement(Text, { color: fallbackColor }, "\xB7"),
55126
55492
  kindGlyph: "\xB7",
55127
55493
  kindColor: fallbackColor,
55128
55494
  text: card.kind
@@ -55131,7 +55497,7 @@ function childVisual(card, doneColor, failedColor, fallbackColor) {
55131
55497
  }
55132
55498
 
55133
55499
  // src/cli/ui/cards/TaskCard.tsx
55134
- var import_react75 = __toESM(require_react(), 1);
55500
+ var import_react76 = __toESM(require_react(), 1);
55135
55501
  var STEP_GLYPH = {
55136
55502
  queued: "\u25CB",
55137
55503
  running: "\u25CF",
@@ -55157,7 +55523,7 @@ function TaskCard({ card }) {
55157
55523
  failed: tone.err
55158
55524
  };
55159
55525
  const elapsed = `${(card.elapsedMs / 1e3).toFixed(1)}s`;
55160
- return /* @__PURE__ */ import_react75.default.createElement(Card, { tone: taskColor[card.status] }, /* @__PURE__ */ import_react75.default.createElement(
55526
+ return /* @__PURE__ */ import_react76.default.createElement(Card, { tone: taskColor[card.status] }, /* @__PURE__ */ import_react76.default.createElement(
55161
55527
  CardHeader,
55162
55528
  {
55163
55529
  glyph: TASK_GLYPH[card.status],
@@ -55166,18 +55532,18 @@ function TaskCard({ card }) {
55166
55532
  subtitle: `${card.index} / ${card.total} ${card.title}`,
55167
55533
  meta: [elapsed, card.status]
55168
55534
  }
55169
- ), card.steps.map((step) => /* @__PURE__ */ import_react75.default.createElement(Box_default, { key: step.id, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react75.default.createElement(Text, { color: stepColor[step.status] }, STEP_GLYPH[step.status]), /* @__PURE__ */ import_react75.default.createElement(Text, { bold: true, color: fg.body }, (step.toolName ?? t("cardLabels.stepLabel")).padEnd(7)), /* @__PURE__ */ import_react75.default.createElement(Pill, { label: step.title, ...PILL_PATH, bold: false }), step.detail ? /* @__PURE__ */ import_react75.default.createElement(Text, { color: fg.faint }, step.detail) : null, step.elapsedMs !== void 0 ? /* @__PURE__ */ import_react75.default.createElement(Text, { color: fg.faint }, `${(step.elapsedMs / 1e3).toFixed(2)}s`) : null)));
55535
+ ), card.steps.map((step) => /* @__PURE__ */ import_react76.default.createElement(Box_default, { key: step.id, flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react76.default.createElement(Text, { color: stepColor[step.status] }, STEP_GLYPH[step.status]), /* @__PURE__ */ import_react76.default.createElement(Text, { bold: true, color: fg.body }, (step.toolName ?? t("cardLabels.stepLabel")).padEnd(7)), /* @__PURE__ */ import_react76.default.createElement(Pill, { label: step.title, ...PILL_PATH, bold: false }), step.detail ? /* @__PURE__ */ import_react76.default.createElement(Text, { color: fg.faint }, step.detail) : null, step.elapsedMs !== void 0 ? /* @__PURE__ */ import_react76.default.createElement(Text, { color: fg.faint }, `${(step.elapsedMs / 1e3).toFixed(2)}s`) : null)));
55170
55536
  }
55171
55537
 
55172
55538
  // src/cli/ui/cards/TipCard.tsx
55173
- var import_react76 = __toESM(require_react(), 1);
55539
+ var import_react77 = __toESM(require_react(), 1);
55174
55540
  var KEY_GUTTER = 4;
55175
55541
  function TipCard({ card }) {
55176
55542
  const keyWidth = card.sections.reduce(
55177
55543
  (max, sec) => sec.rows.reduce((m, r) => Math.max(m, stringWidth(r.key)), max),
55178
55544
  0
55179
55545
  );
55180
- return /* @__PURE__ */ import_react76.default.createElement(Box_default, { flexDirection: "column", paddingLeft: 2, marginY: 1 }, /* @__PURE__ */ import_react76.default.createElement(Box_default, { flexDirection: "row", justifyContent: "space-between" }, /* @__PURE__ */ import_react76.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react76.default.createElement(Text, { color: TONE.accent, bold: true }, "\u24D8"), /* @__PURE__ */ import_react76.default.createElement(Text, { color: FG.body, bold: true }, card.topic)), card.oneTime ? /* @__PURE__ */ import_react76.default.createElement(Text, { color: FG.faint }, t("ui.tipShownOnce")) : null), card.sections.map((section, i) => /* @__PURE__ */ import_react76.default.createElement(Box_default, { key: section.title ?? `section-${i}`, flexDirection: "column", marginTop: 1 }, section.title ? /* @__PURE__ */ import_react76.default.createElement(Box_default, { marginBottom: 0 }, /* @__PURE__ */ import_react76.default.createElement(Text, { color: FG.sub }, section.title)) : null, section.rows.map((row2) => /* @__PURE__ */ import_react76.default.createElement(
55546
+ return /* @__PURE__ */ import_react77.default.createElement(Box_default, { flexDirection: "column", paddingLeft: 2, marginY: 1 }, /* @__PURE__ */ import_react77.default.createElement(Box_default, { flexDirection: "row", justifyContent: "space-between" }, /* @__PURE__ */ import_react77.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react77.default.createElement(Text, { color: TONE.accent, bold: true }, "\u24D8"), /* @__PURE__ */ import_react77.default.createElement(Text, { color: FG.body, bold: true }, card.topic)), card.oneTime ? /* @__PURE__ */ import_react77.default.createElement(Text, { color: FG.faint }, t("ui.tipShownOnce")) : null), card.sections.map((section, i) => /* @__PURE__ */ import_react77.default.createElement(Box_default, { key: section.title ?? `section-${i}`, flexDirection: "column", marginTop: 1 }, section.title ? /* @__PURE__ */ import_react77.default.createElement(Box_default, { marginBottom: 0 }, /* @__PURE__ */ import_react77.default.createElement(Text, { color: FG.sub }, section.title)) : null, section.rows.map((row2) => /* @__PURE__ */ import_react77.default.createElement(
55181
55547
  TipRowRender,
55182
55548
  {
55183
55549
  key: row2.key,
@@ -55185,7 +55551,7 @@ function TipCard({ card }) {
55185
55551
  keyWidth,
55186
55552
  indent: section.title ? 2 : 0
55187
55553
  }
55188
- )))), card.footer ? /* @__PURE__ */ import_react76.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react76.default.createElement(Text, { color: FG.faint }, card.footer)) : null);
55554
+ )))), card.footer ? /* @__PURE__ */ import_react77.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react77.default.createElement(Text, { color: FG.faint }, card.footer)) : null);
55189
55555
  }
55190
55556
  function TipRowRender({
55191
55557
  row: row2,
@@ -55194,24 +55560,24 @@ function TipRowRender({
55194
55560
  }) {
55195
55561
  const pad = " ".repeat(Math.max(0, keyWidth - stringWidth(row2.key) + KEY_GUTTER));
55196
55562
  const lead = indent > 0 ? " ".repeat(indent) : "";
55197
- return /* @__PURE__ */ import_react76.default.createElement(Box_default, { flexDirection: "row" }, lead ? /* @__PURE__ */ import_react76.default.createElement(Text, null, lead) : null, /* @__PURE__ */ import_react76.default.createElement(Text, { color: TONE.accent }, row2.key), /* @__PURE__ */ import_react76.default.createElement(Text, null, pad), /* @__PURE__ */ import_react76.default.createElement(Text, { color: FG.body }, row2.text));
55563
+ return /* @__PURE__ */ import_react77.default.createElement(Box_default, { flexDirection: "row" }, lead ? /* @__PURE__ */ import_react77.default.createElement(Text, null, lead) : null, /* @__PURE__ */ import_react77.default.createElement(Text, { color: TONE.accent }, row2.key), /* @__PURE__ */ import_react77.default.createElement(Text, null, pad), /* @__PURE__ */ import_react77.default.createElement(Text, { color: FG.body }, row2.text));
55198
55564
  }
55199
55565
 
55200
55566
  // src/cli/ui/cards/ToolCard.tsx
55201
- var import_react78 = __toESM(require_react(), 1);
55567
+ var import_react79 = __toESM(require_react(), 1);
55202
55568
 
55203
55569
  // src/cli/ui/state/inflight-context.tsx
55204
- var import_react77 = __toESM(require_react(), 1);
55205
- var Ctx2 = (0, import_react77.createContext)(null);
55570
+ var import_react78 = __toESM(require_react(), 1);
55571
+ var Ctx2 = (0, import_react78.createContext)(null);
55206
55572
  function InflightProvider({
55207
55573
  inflight,
55208
55574
  children
55209
55575
  }) {
55210
- return /* @__PURE__ */ import_react77.default.createElement(Ctx2.Provider, { value: inflight }, children);
55576
+ return /* @__PURE__ */ import_react78.default.createElement(Ctx2.Provider, { value: inflight }, children);
55211
55577
  }
55212
55578
  function useIsInflight(id) {
55213
- const inflight = (0, import_react77.useContext)(Ctx2);
55214
- return (0, import_react77.useSyncExternalStore)(
55579
+ const inflight = (0, import_react78.useContext)(Ctx2);
55580
+ return (0, import_react78.useSyncExternalStore)(
55215
55581
  (cb) => inflight ? inflight.subscribe(cb) : noop,
55216
55582
  () => inflight ? inflight.has(id) : false,
55217
55583
  () => false
@@ -55232,7 +55598,7 @@ function ToolCard({ card }) {
55232
55598
  const cols = stdout?.columns ?? 80;
55233
55599
  const lineCells = Math.max(20, cols - 4);
55234
55600
  const argsLabel = formatArgsSummary(card.args);
55235
- const subagentMarkdown = import_react78.default.useMemo(
55601
+ const subagentMarkdown = import_react79.default.useMemo(
55236
55602
  () => unwrapSubagentMarkdown(card.name, card.output),
55237
55603
  [card.name, card.output]
55238
55604
  );
@@ -55254,7 +55620,7 @@ function ToolCard({ card }) {
55254
55620
  meta.push({ text: t("cardLabels.rejected"), color: TONE.err });
55255
55621
  }
55256
55622
  for (const part of metaTrail(card)) meta.push(part);
55257
- return /* @__PURE__ */ import_react78.default.createElement(Card, { tone: headColor }, /* @__PURE__ */ import_react78.default.createElement(
55623
+ return /* @__PURE__ */ import_react79.default.createElement(Card, { tone: headColor }, /* @__PURE__ */ import_react79.default.createElement(
55258
55624
  CardHeader,
55259
55625
  {
55260
55626
  glyph: statusGlyph2(status2),
@@ -55262,11 +55628,11 @@ function ToolCard({ card }) {
55262
55628
  title: card.name,
55263
55629
  subtitle: argsLabel || void 0,
55264
55630
  meta: meta.length > 0 ? meta : void 0,
55265
- right: status2 === "running" ? /* @__PURE__ */ import_react78.default.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.brand, bold: true }) : void 0
55631
+ right: status2 === "running" ? /* @__PURE__ */ import_react79.default.createElement(Spinner, { kind: "braille", color: TONE_ACTIVE.brand, bold: true }) : void 0
55266
55632
  }
55267
- ), showBody && (subagentMarkdown !== null ? /* @__PURE__ */ import_react78.default.createElement(Markdown, { text: subagentMarkdown, width: lineCells }) : /* @__PURE__ */ import_react78.default.createElement(import_react78.default.Fragment, null, hidden > 0 ? /* @__PURE__ */ import_react78.default.createElement(Text, { color: FG.faint }, t(hidden === 1 ? "cardLabels.earlierLine" : "cardLabels.earlierLines", {
55633
+ ), showBody && (subagentMarkdown !== null ? /* @__PURE__ */ import_react79.default.createElement(Markdown, { text: subagentMarkdown, width: lineCells }) : /* @__PURE__ */ import_react79.default.createElement(import_react79.default.Fragment, null, hidden > 0 ? /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.faint }, t(hidden === 1 ? "cardLabels.earlierLine" : "cardLabels.earlierLines", {
55268
55634
  count: hidden
55269
- })) : null, visible.map((line, i) => /* @__PURE__ */ import_react78.default.createElement(
55635
+ })) : null, visible.map((line, i) => /* @__PURE__ */ import_react79.default.createElement(
55270
55636
  Text,
55271
55637
  {
55272
55638
  key: `${card.id}:${hidden + i}`,
@@ -55368,7 +55734,7 @@ function formatBytes(n) {
55368
55734
  }
55369
55735
 
55370
55736
  // src/cli/ui/cards/UsageCard.tsx
55371
- var import_react79 = __toESM(require_react(), 1);
55737
+ var import_react80 = __toESM(require_react(), 1);
55372
55738
  var BAR_CELLS2 = 30;
55373
55739
  function compactNum(n) {
55374
55740
  if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
@@ -55378,10 +55744,10 @@ function compactNum(n) {
55378
55744
  function bar(ratio, color) {
55379
55745
  const filled = Math.max(0, Math.min(BAR_CELLS2, Math.round(ratio * BAR_CELLS2)));
55380
55746
  const empty = BAR_CELLS2 - filled;
55381
- return /* @__PURE__ */ import_react79.default.createElement(import_react79.default.Fragment, null, /* @__PURE__ */ import_react79.default.createElement(Text, { color }, "\u2588".repeat(filled)), /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.faint }, "\u2591".repeat(empty)));
55747
+ return /* @__PURE__ */ import_react80.default.createElement(import_react80.default.Fragment, null, /* @__PURE__ */ import_react80.default.createElement(Text, { color }, "\u2588".repeat(filled)), /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.faint }, "\u2591".repeat(empty)));
55382
55748
  }
55383
55749
  function UsageCard({ card }) {
55384
- if (card.compact) return /* @__PURE__ */ import_react79.default.createElement(CompactUsageRow, { card });
55750
+ if (card.compact) return /* @__PURE__ */ import_react80.default.createElement(CompactUsageRow, { card });
55385
55751
  const cap = Math.max(1, card.tokens.promptCap);
55386
55752
  const promptRatio = card.tokens.prompt / cap;
55387
55753
  const reasonRatio = card.tokens.reason / cap;
@@ -55391,15 +55757,15 @@ function UsageCard({ card }) {
55391
55757
  formatCost(card.cost, card.balanceCurrency)
55392
55758
  ];
55393
55759
  if (card.elapsedMs !== void 0) headerMeta2.push(`${(card.elapsedMs / 1e3).toFixed(1)}s`);
55394
- return /* @__PURE__ */ import_react79.default.createElement(Card, { tone: FG.meta }, /* @__PURE__ */ import_react79.default.createElement(CardHeader, { glyph: "\u03A3", tone: FG.meta, title: t("cardTitles.usage"), meta: headerMeta2 }), /* @__PURE__ */ import_react79.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.sub }, t("cardLabels.prompt")), bar(promptRatio, TONE.brand), /* @__PURE__ */ import_react79.default.createElement(Text, { bold: true, color: FG.body }, card.tokens.prompt.toLocaleString()), /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.faint }, `/ 1M \xB7 ${(promptRatio * 100).toFixed(1)}%`)), /* @__PURE__ */ import_react79.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.sub }, t("cardLabels.reason")), bar(reasonRatio, TONE.accent), /* @__PURE__ */ import_react79.default.createElement(Text, { bold: true, color: FG.body }, card.tokens.reason.toLocaleString())), /* @__PURE__ */ import_react79.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.sub }, t("cardLabels.output")), bar(outputRatio, TONE.brand), /* @__PURE__ */ import_react79.default.createElement(Text, { bold: true, color: FG.body }, card.tokens.output.toLocaleString())), /* @__PURE__ */ import_react79.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.sub }, t("cardLabels.cache"), " "), bar(card.cacheHit, TONE.ok), /* @__PURE__ */ import_react79.default.createElement(Text, { bold: true, color: TONE.ok }, `${(card.cacheHit * 100).toFixed(1)}%`)), /* @__PURE__ */ import_react79.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.faint }, t("cardLabels.session")), /* @__PURE__ */ import_react79.default.createElement(Text, { bold: true, color: FG.body }, `\u25CF ${formatCost(card.sessionCost, card.balanceCurrency, 3)}`), card.balance !== void 0 ? /* @__PURE__ */ import_react79.default.createElement(import_react79.default.Fragment, null, /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.faint }, `\xB7 ${t("cardLabels.balance")}`), /* @__PURE__ */ import_react79.default.createElement(Text, { bold: true, color: TONE.brand }, formatBalance(card.balance, card.balanceCurrency))) : null));
55760
+ return /* @__PURE__ */ import_react80.default.createElement(Card, { tone: FG.meta }, /* @__PURE__ */ import_react80.default.createElement(CardHeader, { glyph: "\u03A3", tone: FG.meta, title: t("cardTitles.usage"), meta: headerMeta2 }), /* @__PURE__ */ import_react80.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.sub }, t("cardLabels.prompt")), bar(promptRatio, TONE.brand), /* @__PURE__ */ import_react80.default.createElement(Text, { bold: true, color: FG.body }, card.tokens.prompt.toLocaleString()), /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.faint }, `/ 1M \xB7 ${(promptRatio * 100).toFixed(1)}%`)), /* @__PURE__ */ import_react80.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.sub }, t("cardLabels.reason")), bar(reasonRatio, TONE.accent), /* @__PURE__ */ import_react80.default.createElement(Text, { bold: true, color: FG.body }, card.tokens.reason.toLocaleString())), /* @__PURE__ */ import_react80.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.sub }, t("cardLabels.output")), bar(outputRatio, TONE.brand), /* @__PURE__ */ import_react80.default.createElement(Text, { bold: true, color: FG.body }, card.tokens.output.toLocaleString())), /* @__PURE__ */ import_react80.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.sub }, t("cardLabels.cache"), " "), bar(card.cacheHit, TONE.ok), /* @__PURE__ */ import_react80.default.createElement(Text, { bold: true, color: TONE.ok }, `${(card.cacheHit * 100).toFixed(1)}%`)), /* @__PURE__ */ import_react80.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.faint }, t("cardLabels.session")), /* @__PURE__ */ import_react80.default.createElement(Text, { bold: true, color: FG.body }, `\u25CF ${formatCost(card.sessionCost, card.balanceCurrency, 3)}`), card.balance !== void 0 ? /* @__PURE__ */ import_react80.default.createElement(import_react80.default.Fragment, null, /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.faint }, `\xB7 ${t("cardLabels.balance")}`), /* @__PURE__ */ import_react80.default.createElement(Text, { bold: true, color: TONE.brand }, formatBalance(card.balance, card.balanceCurrency))) : null));
55395
55761
  }
55396
55762
  function CompactUsageRow({ card }) {
55397
55763
  const elapsed = card.elapsedMs !== void 0 ? ` \xB7 ${(card.elapsedMs / 1e3).toFixed(1)}s` : "";
55398
- return /* @__PURE__ */ import_react79.default.createElement(Box_default, { flexDirection: "row", gap: 1, marginTop: 1 }, /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.meta }, "\u03A3"), /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.faint }, `${t("cardLabels.turn")} ${card.turn}`), /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.meta }, `\xB7 ${compactNum(card.tokens.prompt)} ${t("cardLabels.prompt")} \xB7 ${compactNum(card.tokens.output)} ${t("cardLabels.output")}`), /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.faint }, `\xB7 ${t("cardLabels.cache")}`), /* @__PURE__ */ import_react79.default.createElement(Text, { color: TONE.ok }, `${(card.cacheHit * 100).toFixed(0)}%`), /* @__PURE__ */ import_react79.default.createElement(Text, { color: FG.faint }, `\xB7 ${formatCost(card.cost, card.balanceCurrency)}${elapsed}`), card.balance !== void 0 ? /* @__PURE__ */ import_react79.default.createElement(Text, { color: TONE.brand }, `\xB7 ${formatBalance(card.balance, card.balanceCurrency)}`) : null);
55764
+ return /* @__PURE__ */ import_react80.default.createElement(Box_default, { flexDirection: "row", gap: 1, marginTop: 1 }, /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.meta }, "\u03A3"), /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.faint }, `${t("cardLabels.turn")} ${card.turn}`), /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.meta }, `\xB7 ${compactNum(card.tokens.prompt)} ${t("cardLabels.prompt")} \xB7 ${compactNum(card.tokens.output)} ${t("cardLabels.output")}`), /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.faint }, `\xB7 ${t("cardLabels.cache")}`), /* @__PURE__ */ import_react80.default.createElement(Text, { color: TONE.ok }, `${(card.cacheHit * 100).toFixed(0)}%`), /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.faint }, `\xB7 ${formatCost(card.cost, card.balanceCurrency)}${elapsed}`), card.balance !== void 0 ? /* @__PURE__ */ import_react80.default.createElement(Text, { color: TONE.brand }, `\xB7 ${formatBalance(card.balance, card.balanceCurrency)}`) : null);
55399
55765
  }
55400
55766
 
55401
55767
  // src/cli/ui/cards/UserCard.tsx
55402
- var import_react80 = __toESM(require_react(), 1);
55768
+ var import_react81 = __toESM(require_react(), 1);
55403
55769
 
55404
55770
  // src/cli/ui/cards/time.ts
55405
55771
  function formatRelativeTime(ts, now = Date.now()) {
@@ -55416,7 +55782,7 @@ function formatRelativeTime(ts, now = Date.now()) {
55416
55782
 
55417
55783
  // src/cli/ui/cards/UserCard.tsx
55418
55784
  function UserCard({ card }) {
55419
- return /* @__PURE__ */ import_react80.default.createElement(Card, { tone: CARD.user.color }, /* @__PURE__ */ import_react80.default.createElement(
55785
+ return /* @__PURE__ */ import_react81.default.createElement(Card, { tone: CARD.user.color }, /* @__PURE__ */ import_react81.default.createElement(
55420
55786
  CardHeader,
55421
55787
  {
55422
55788
  glyph: CARD.user.glyph,
@@ -55424,14 +55790,14 @@ function UserCard({ card }) {
55424
55790
  title: t("cardTitles.you"),
55425
55791
  meta: [formatRelativeTime(card.ts)]
55426
55792
  }
55427
- ), /* @__PURE__ */ import_react80.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react80.default.createElement(Text, { color: FG.sub }, "\u21B3"), /* @__PURE__ */ import_react80.default.createElement(Text, null, card.text)));
55793
+ ), /* @__PURE__ */ import_react81.default.createElement(Box_default, { flexDirection: "row", gap: 1 }, /* @__PURE__ */ import_react81.default.createElement(Text, { color: FG.sub }, "\u21B3"), /* @__PURE__ */ import_react81.default.createElement(Text, null, card.text)));
55428
55794
  }
55429
55795
 
55430
55796
  // src/cli/ui/cards/WarnCard.tsx
55431
- var import_react81 = __toESM(require_react(), 1);
55797
+ var import_react82 = __toESM(require_react(), 1);
55432
55798
  function WarnCard({ card }) {
55433
55799
  const messageLines = card.message.length > 0 ? card.message.split("\n") : [];
55434
- return /* @__PURE__ */ import_react81.default.createElement(Card, { tone: TONE.warn }, /* @__PURE__ */ import_react81.default.createElement(
55800
+ return /* @__PURE__ */ import_react82.default.createElement(Card, { tone: TONE.warn }, /* @__PURE__ */ import_react82.default.createElement(
55435
55801
  CardHeader,
55436
55802
  {
55437
55803
  glyph: "\u26A0",
@@ -55439,57 +55805,57 @@ function WarnCard({ card }) {
55439
55805
  title: card.title,
55440
55806
  meta: card.detail ? [card.detail] : void 0
55441
55807
  }
55442
- ), messageLines.map((line, i) => /* @__PURE__ */ import_react81.default.createElement(Text, { key: `${card.id}:${i}`, color: FG.body }, line || " ")));
55808
+ ), messageLines.map((line, i) => /* @__PURE__ */ import_react82.default.createElement(Text, { key: `${card.id}:${i}`, color: FG.body }, line || " ")));
55443
55809
  }
55444
55810
 
55445
55811
  // src/cli/ui/cards/CardRenderer.tsx
55446
- var CardRenderer = import_react82.default.memo(function CardRenderer2({
55812
+ var CardRenderer = import_react83.default.memo(function CardRenderer2({
55447
55813
  card
55448
55814
  }) {
55449
- return /* @__PURE__ */ import_react82.default.createElement(Box_default, { flexDirection: "column" }, renderCard(card));
55815
+ return /* @__PURE__ */ import_react83.default.createElement(Box_default, { flexDirection: "column" }, renderCard(card));
55450
55816
  });
55451
55817
  function renderCard(card) {
55452
55818
  switch (card.kind) {
55453
55819
  case "user":
55454
- return /* @__PURE__ */ import_react82.default.createElement(UserCard, { card });
55820
+ return /* @__PURE__ */ import_react83.default.createElement(UserCard, { card });
55455
55821
  case "reasoning":
55456
- return /* @__PURE__ */ import_react82.default.createElement(ReasoningCard, { card, expanded: true });
55822
+ return /* @__PURE__ */ import_react83.default.createElement(ReasoningCard, { card, expanded: true });
55457
55823
  case "streaming":
55458
- return /* @__PURE__ */ import_react82.default.createElement(StreamingCard, { card });
55824
+ return /* @__PURE__ */ import_react83.default.createElement(StreamingCard, { card });
55459
55825
  case "tool":
55460
- return /* @__PURE__ */ import_react82.default.createElement(ToolCard, { card });
55826
+ return /* @__PURE__ */ import_react83.default.createElement(ToolCard, { card });
55461
55827
  case "task":
55462
- return /* @__PURE__ */ import_react82.default.createElement(TaskCard, { card });
55828
+ return /* @__PURE__ */ import_react83.default.createElement(TaskCard, { card });
55463
55829
  case "plan":
55464
- return /* @__PURE__ */ import_react82.default.createElement(PlanCard, { card });
55830
+ return /* @__PURE__ */ import_react83.default.createElement(PlanCard, { card });
55465
55831
  case "diff":
55466
- return /* @__PURE__ */ import_react82.default.createElement(DiffCard, { card });
55832
+ return /* @__PURE__ */ import_react83.default.createElement(DiffCard, { card });
55467
55833
  case "error":
55468
- return /* @__PURE__ */ import_react82.default.createElement(ErrorCard, { card });
55834
+ return /* @__PURE__ */ import_react83.default.createElement(ErrorCard, { card });
55469
55835
  case "warn":
55470
- return /* @__PURE__ */ import_react82.default.createElement(WarnCard, { card });
55836
+ return /* @__PURE__ */ import_react83.default.createElement(WarnCard, { card });
55471
55837
  case "usage":
55472
- return /* @__PURE__ */ import_react82.default.createElement(UsageCard, { card });
55838
+ return /* @__PURE__ */ import_react83.default.createElement(UsageCard, { card });
55473
55839
  case "memory":
55474
- return /* @__PURE__ */ import_react82.default.createElement(MemoryCard, { card });
55840
+ return /* @__PURE__ */ import_react83.default.createElement(MemoryCard, { card });
55475
55841
  case "subagent":
55476
- return /* @__PURE__ */ import_react82.default.createElement(SubAgentCard, { card });
55842
+ return /* @__PURE__ */ import_react83.default.createElement(SubAgentCard, { card });
55477
55843
  case "search":
55478
- return /* @__PURE__ */ import_react82.default.createElement(SearchCard, { card });
55844
+ return /* @__PURE__ */ import_react83.default.createElement(SearchCard, { card });
55479
55845
  case "live":
55480
- return /* @__PURE__ */ import_react82.default.createElement(LiveCard, { card });
55846
+ return /* @__PURE__ */ import_react83.default.createElement(LiveCard, { card });
55481
55847
  case "tip":
55482
- return /* @__PURE__ */ import_react82.default.createElement(TipCard, { card });
55848
+ return /* @__PURE__ */ import_react83.default.createElement(TipCard, { card });
55483
55849
  case "ctx":
55484
- return /* @__PURE__ */ import_react82.default.createElement(CtxCard, { card });
55850
+ return /* @__PURE__ */ import_react83.default.createElement(CtxCard, { card });
55485
55851
  case "doctor":
55486
- return /* @__PURE__ */ import_react82.default.createElement(DoctorCard, { card });
55852
+ return /* @__PURE__ */ import_react83.default.createElement(DoctorCard, { card });
55487
55853
  default:
55488
- return /* @__PURE__ */ import_react82.default.createElement(FallbackCard, { card });
55854
+ return /* @__PURE__ */ import_react83.default.createElement(FallbackCard, { card });
55489
55855
  }
55490
55856
  }
55491
55857
  function FallbackCard({ card }) {
55492
- return /* @__PURE__ */ import_react82.default.createElement(Box_default, { flexDirection: "row" }, /* @__PURE__ */ import_react82.default.createElement(Text, { color: FG.faint }, ` \xB7 ${card.kind} card \xB7 not yet migrated`));
55858
+ return /* @__PURE__ */ import_react83.default.createElement(Box_default, { flexDirection: "row" }, /* @__PURE__ */ import_react83.default.createElement(Text, { color: FG.faint }, ` \xB7 ${card.kind} card \xB7 not yet migrated`));
55493
55859
  }
55494
55860
 
55495
55861
  // src/cli/ui/layout/CardStream.tsx
@@ -55529,15 +55895,15 @@ function CardStream({
55529
55895
  const scrollRows = useChatScrollState((s) => s.scrollRows);
55530
55896
  const cardHeights = useChatScrollState((s) => s.cardHeights);
55531
55897
  const { setMaxScroll, setCardHeight, pruneCardHeights } = useChatScrollActions();
55532
- const outerRef = (0, import_react83.useRef)(null);
55533
- const innerRef = (0, import_react83.useRef)(null);
55898
+ const outerRef = (0, import_react84.useRef)(null);
55899
+ const innerRef = (0, import_react84.useRef)(null);
55534
55900
  const outer = use_box_metrics_default(outerRef);
55535
55901
  const inner = use_box_metrics_default(innerRef);
55536
55902
  const maxScroll = Math.max(0, inner.height - outer.height);
55537
- (0, import_react83.useEffect)(() => {
55903
+ (0, import_react84.useEffect)(() => {
55538
55904
  setMaxScroll(maxScroll);
55539
55905
  }, [maxScroll, setMaxScroll]);
55540
- (0, import_react83.useEffect)(() => {
55906
+ (0, import_react84.useEffect)(() => {
55541
55907
  const live = /* @__PURE__ */ new Set();
55542
55908
  for (const c of cards) live.add(c.id);
55543
55909
  pruneCardHeights(live);
@@ -55546,23 +55912,23 @@ function CardStream({
55546
55912
  if (suppressLive && cards.length > 0 && !isFullySettled(cards[cards.length - 1])) {
55547
55913
  visible = cards.slice(0, -1);
55548
55914
  }
55549
- const items = (0, import_react83.useMemo)(
55915
+ const items = (0, import_react84.useMemo)(
55550
55916
  () => computeCardStreamItems(visible, cardHeights, scrollRows, outer.height),
55551
55917
  [visible, cardHeights, scrollRows, outer.height]
55552
55918
  );
55553
- return /* @__PURE__ */ import_react83.default.createElement(import_react83.default.Fragment, null, /* @__PURE__ */ import_react83.default.createElement(Box_default, { height: 1, flexShrink: 0 }, scrollRows > 0 ? /* @__PURE__ */ import_react83.default.createElement(ScrollIndicator, { scrollRows, maxScroll }) : null), /* @__PURE__ */ import_react83.default.createElement(Box_default, { ref: outerRef, flexDirection: "column", flexGrow: 1, overflow: "hidden" }, /* @__PURE__ */ import_react83.default.createElement(Box_default, { ref: innerRef, flexDirection: "column", marginTop: -scrollRows, flexShrink: 0 }, items.map(
55554
- (item) => item.kind === "spacer" ? /* @__PURE__ */ import_react83.default.createElement(Box_default, { key: item.key, height: item.rows, flexShrink: 0 }) : /* @__PURE__ */ import_react83.default.createElement(MeasuredCard, { key: item.card.id, card: item.card, report: setCardHeight })
55919
+ return /* @__PURE__ */ import_react84.default.createElement(import_react84.default.Fragment, null, /* @__PURE__ */ import_react84.default.createElement(Box_default, { height: 1, flexShrink: 0 }, scrollRows > 0 ? /* @__PURE__ */ import_react84.default.createElement(ScrollIndicator, { scrollRows, maxScroll }) : null), /* @__PURE__ */ import_react84.default.createElement(Box_default, { ref: outerRef, flexDirection: "column", flexGrow: 1, overflow: "hidden" }, /* @__PURE__ */ import_react84.default.createElement(Box_default, { ref: innerRef, flexDirection: "column", marginTop: -scrollRows, flexShrink: 0 }, items.map(
55920
+ (item) => item.kind === "spacer" ? /* @__PURE__ */ import_react84.default.createElement(Box_default, { key: item.key, height: item.rows, flexShrink: 0 }) : /* @__PURE__ */ import_react84.default.createElement(MeasuredCard, { key: item.card.id, card: item.card, report: setCardHeight })
55555
55921
  ))));
55556
55922
  }
55557
55923
  function MeasuredCard({
55558
55924
  card,
55559
55925
  report
55560
55926
  }) {
55561
- const ref = (0, import_react83.useRef)(null);
55927
+ const ref = (0, import_react84.useRef)(null);
55562
55928
  const m = use_box_metrics_default(ref);
55563
- const lastReportedRef = (0, import_react83.useRef)(0);
55929
+ const lastReportedRef = (0, import_react84.useRef)(0);
55564
55930
  const settled = isCardSettled(card);
55565
- (0, import_react83.useEffect)(() => {
55931
+ (0, import_react84.useEffect)(() => {
55566
55932
  const h = m.height;
55567
55933
  if (h <= 0) return;
55568
55934
  if (h === lastReportedRef.current) return;
@@ -55570,15 +55936,15 @@ function MeasuredCard({
55570
55936
  lastReportedRef.current = h;
55571
55937
  report(card.id, h);
55572
55938
  }, [card.id, m.height, report, settled]);
55573
- return /* @__PURE__ */ import_react83.default.createElement(Box_default, { ref, flexDirection: "column", flexShrink: 0 }, /* @__PURE__ */ import_react83.default.createElement(CardRenderer, { card }));
55939
+ return /* @__PURE__ */ import_react84.default.createElement(Box_default, { ref, flexDirection: "column", flexShrink: 0 }, /* @__PURE__ */ import_react84.default.createElement(CardRenderer, { card }));
55574
55940
  }
55575
55941
  function ScrollIndicator({
55576
55942
  scrollRows,
55577
55943
  maxScroll
55578
55944
  }) {
55579
55945
  const version = useChatScrollState((s) => s.scrollVersion);
55580
- const [hot, setHot] = import_react83.default.useState(false);
55581
- import_react83.default.useEffect(() => {
55946
+ const [hot, setHot] = import_react84.default.useState(false);
55947
+ import_react84.default.useEffect(() => {
55582
55948
  if (version === 0) return;
55583
55949
  setHot(true);
55584
55950
  const id = setTimeout(() => setHot(false), 220);
@@ -55588,7 +55954,7 @@ function ScrollIndicator({
55588
55954
  const above = scrollRows === 1 ? t("cardStream.scrollAbove", { scroll: scrollRows, max: maxScroll }) : t("cardStream.scrollAbovePlural", { scroll: scrollRows, max: maxScroll });
55589
55955
  const more = remaining > 0 ? t("cardStream.scrollMore", { remaining }) : "";
55590
55956
  const text = `${above}${more}${t("cardStream.scrollPgUp")}`;
55591
- return /* @__PURE__ */ import_react83.default.createElement(Text, { color: hot ? TONE.accent : FG.faint }, text);
55957
+ return /* @__PURE__ */ import_react84.default.createElement(Text, { color: hot ? TONE.accent : FG.faint }, text);
55592
55958
  }
55593
55959
  function isFullySettled(card) {
55594
55960
  switch (card.kind) {
@@ -56460,9 +56826,7 @@ var cwd = (args, _loop, ctx) => {
56460
56826
  }
56461
56827
  const target = args.join(" ").trim();
56462
56828
  if (!target) {
56463
- return {
56464
- info: ctx.codeRoot != null ? t("handlers.edits.cwdUsage", { current: ctx.codeRoot }) : t("handlers.edits.cwdUsageNoCurrent")
56465
- };
56829
+ return { openWorkspacePicker: true };
56466
56830
  }
56467
56831
  const result = ctx.switchCwd(stripOuterQuotes(target));
56468
56832
  return result.clear ? { info: result.info, clear: true } : { info: result.info };
@@ -56806,7 +57170,7 @@ function triggerReconnect(rawName, servers, postInfo, loop2) {
56806
57170
  var handlers8 = { mcp };
56807
57171
 
56808
57172
  // src/cli/ui/slash/handlers/memory.ts
56809
- import { basename } from "path";
57173
+ import { basename as basename2 } from "path";
56810
57174
  function pickTypeFlag(args) {
56811
57175
  const rest = [];
56812
57176
  let type = null;
@@ -56927,7 +57291,7 @@ var memory = (args, _loop, ctx) => {
56927
57291
  const parts = [];
56928
57292
  const projMem = readProjectMemory(ctx.memoryRoot);
56929
57293
  if (projMem) {
56930
- const label = basename(projMem.path);
57294
+ const label = basename2(projMem.path);
56931
57295
  const hdr = projMem.truncated ? `\u25B8 ${label}: ${projMem.path} (${projMem.originalChars.toLocaleString()} chars, truncated)` : `\u25B8 ${label}: ${projMem.path} (${projMem.originalChars.toLocaleString()} chars)`;
56932
57296
  parts.push(hdr, "", projMem.content);
56933
57297
  }
@@ -57105,7 +57469,7 @@ var handlers10 = {
57105
57469
  import { release } from "os";
57106
57470
 
57107
57471
  // src/cli/ui/ctx-breakdown.tsx
57108
- var import_react84 = __toESM(require_react(), 1);
57472
+ var import_react85 = __toESM(require_react(), 1);
57109
57473
  function computeCtxBreakdown(loop2) {
57110
57474
  const systemTokens = countTokensBounded(loop2.prefix.system);
57111
57475
  const toolsTokens = countTokensBounded(JSON.stringify(loop2.prefix.toolSpecs));
@@ -57261,6 +57625,7 @@ var status = (_args, loop2, ctx) => {
57261
57625
  count: loop2.log.length,
57262
57626
  resumed: loop2.resumedMessageCount
57263
57627
  }) : t("handlers.observability.statusSessionEphemeral");
57628
+ const rpm = loadRateLimit()?.rpm;
57264
57629
  const mcpCount = ctx.mcpSpecs?.length ?? 0;
57265
57630
  const toolCount = loop2.prefix.toolSpecs.length;
57266
57631
  const mcpLine = t("handlers.observability.statusMcp", { servers: mcpCount, tools: toolCount });
@@ -57278,6 +57643,7 @@ var status = (_args, loop2, ctx) => {
57278
57643
  }),
57279
57644
  cacheLine,
57280
57645
  ctxLine,
57646
+ `rate limit: ${rpm ? `${rpm} rpm` : "off"}`,
57281
57647
  mcpLine,
57282
57648
  sessionLine
57283
57649
  ];
@@ -57339,7 +57705,7 @@ var cost = (args, loop2, ctx) => {
57339
57705
  return {};
57340
57706
  };
57341
57707
  function estimateCost(userText, loop2) {
57342
- const pricing = DEEPSEEK_PRICING[loop2.model];
57708
+ const pricing = pricingFor(loop2.model);
57343
57709
  if (!pricing) {
57344
57710
  return { info: t("handlers.observability.costNoPricing", { model: loop2.model }) };
57345
57711
  }
@@ -57545,7 +57911,7 @@ var handlers12 = {
57545
57911
  };
57546
57912
 
57547
57913
  // src/cli/ui/slash/handlers/plans.ts
57548
- import { basename as basename2 } from "path";
57914
+ import { basename as basename3 } from "path";
57549
57915
  var plans = (args, loop2, ctx) => {
57550
57916
  const sessionName = loop2.sessionName;
57551
57917
  if (!sessionName) {
@@ -57625,7 +57991,7 @@ var replay = (args, loop2) => {
57625
57991
  completedStepIds: a.completedStepIds,
57626
57992
  completedAt: a.completedAt,
57627
57993
  relativeTime: relativeTime(a.completedAt),
57628
- archiveBasename: basename2(a.path),
57994
+ archiveBasename: basename3(a.path),
57629
57995
  index,
57630
57996
  total: archives.length
57631
57997
  }
@@ -57671,13 +58037,12 @@ var handlers13 = {
57671
58037
  var handlers14 = {
57672
58038
  qq(args, _loop, ctx) {
57673
58039
  const subcommand = (args[0] ?? "status").toLowerCase();
57674
- const rest = args.slice(1);
57675
58040
  if (!ctx.qq) {
57676
58041
  return { info: "/qq is not available in this session." };
57677
58042
  }
57678
58043
  if (subcommand === "connect") {
57679
58044
  ctx.postInfo?.("QQ: connecting...");
57680
- void ctx.qq.connect(rest).then(
58045
+ void ctx.qq.connect(args.slice(1)).then(
57681
58046
  (message) => ctx.postInfo?.(message),
57682
58047
  (err) => ctx.postInfo?.(`QQ connect failed: ${err.message}`)
57683
58048
  );
@@ -57694,7 +58059,9 @@ var handlers14 = {
57694
58059
  if (subcommand === "status") {
57695
58060
  return { info: ctx.qq.status() };
57696
58061
  }
57697
- return { info: "Usage: /qq connect [appId appSecret [sandbox]] | /qq status | /qq disconnect" };
58062
+ return {
58063
+ info: "Usage: /qq connect [appId appSecret [sandbox]] | /qq status | /qq disconnect"
58064
+ };
57698
58065
  }
57699
58066
  };
57700
58067
 
@@ -58206,9 +58573,38 @@ function hydrateCardsFromMessages(messages) {
58206
58573
  return cards;
58207
58574
  }
58208
58575
 
58576
+ // src/cli/ui/turn-interrupt.ts
58577
+ function handleTurnInterrupt(key, {
58578
+ turnActiveRef,
58579
+ abortedThisTurn,
58580
+ resetPendingModals,
58581
+ isLoopActive,
58582
+ stopLoop,
58583
+ loop: loop2,
58584
+ quitProcess
58585
+ }) {
58586
+ if (turnActiveRef.current) {
58587
+ if (abortedThisTurn.current) return "already-aborted";
58588
+ abortedThisTurn.current = true;
58589
+ resetPendingModals();
58590
+ if (isLoopActive()) stopLoop();
58591
+ loop2.abort();
58592
+ return "aborted";
58593
+ }
58594
+ if (key === "escape" && isLoopActive()) {
58595
+ stopLoop();
58596
+ return "stopped-loop";
58597
+ }
58598
+ if (key === "ctrl-c") {
58599
+ quitProcess();
58600
+ return "quit";
58601
+ }
58602
+ return "idle";
58603
+ }
58604
+
58209
58605
  // src/cli/ui/useCompletionPickers.ts
58210
- var import_react85 = __toESM(require_react(), 1);
58211
- import { isAbsolute, parse, relative, resolve } from "path";
58606
+ var import_react86 = __toESM(require_react(), 1);
58607
+ import { isAbsolute, parse, relative, resolve as resolve2 } from "path";
58212
58608
  var SEARCH_DEBOUNCE_MS = 80;
58213
58609
  var SEARCH_FLUSH_MS = 50;
58214
58610
  var SEARCH_RESULT_CAP = 200;
@@ -58221,38 +58617,38 @@ function useCompletionPickers({
58221
58617
  mcpServers,
58222
58618
  slashUsage
58223
58619
  }) {
58224
- const [slashSelected, setSlashSelected] = (0, import_react85.useState)(0);
58225
- const slashMatches = (0, import_react85.useMemo)(() => {
58620
+ const [slashSelected, setSlashSelected] = (0, import_react86.useState)(0);
58621
+ const slashMatches = (0, import_react86.useMemo)(() => {
58226
58622
  if (!input.startsWith("/") || input.includes(" ")) return null;
58227
58623
  return suggestSlashCommands(input.slice(1), !!codeMode, slashUsage);
58228
58624
  }, [input, codeMode, slashUsage]);
58229
58625
  const slashGroupMode = input === "/";
58230
- const slashAdvancedHidden = (0, import_react85.useMemo)(
58626
+ const slashAdvancedHidden = (0, import_react86.useMemo)(
58231
58627
  () => slashGroupMode ? countAdvancedCommands(!!codeMode) : 0,
58232
58628
  [slashGroupMode, codeMode]
58233
58629
  );
58234
- (0, import_react85.useEffect)(() => {
58630
+ (0, import_react86.useEffect)(() => {
58235
58631
  setSlashSelected((prev) => {
58236
58632
  if (!slashMatches || slashMatches.length === 0) return 0;
58237
58633
  if (prev >= slashMatches.length) return slashMatches.length - 1;
58238
58634
  return prev;
58239
58635
  });
58240
58636
  }, [slashMatches]);
58241
- const [atSelected, setAtSelected] = (0, import_react85.useState)(0);
58242
- const recentFilesRef = (0, import_react85.useRef)([]);
58243
- const recordRecentFile = (0, import_react85.useCallback)((p) => {
58637
+ const [atSelected, setAtSelected] = (0, import_react86.useState)(0);
58638
+ const recentFilesRef = (0, import_react86.useRef)([]);
58639
+ const recordRecentFile = (0, import_react86.useCallback)((p) => {
58244
58640
  const list2 = recentFilesRef.current;
58245
58641
  const i = list2.indexOf(p);
58246
58642
  if (i >= 0) list2.splice(i, 1);
58247
58643
  list2.unshift(p);
58248
58644
  if (list2.length > 20) list2.length = 20;
58249
58645
  }, []);
58250
- const atPicker = (0, import_react85.useMemo)(() => {
58646
+ const atPicker = (0, import_react86.useMemo)(() => {
58251
58647
  if (!codeMode) return null;
58252
58648
  if (slashMatches !== null) return null;
58253
58649
  return detectAtPicker(input);
58254
58650
  }, [codeMode, input, slashMatches]);
58255
- const parsed = (0, import_react85.useMemo)(
58651
+ const parsed = (0, import_react86.useMemo)(
58256
58652
  () => atPicker ? parseAtQuery(atPicker.query) : null,
58257
58653
  [atPicker]
58258
58654
  );
@@ -58264,7 +58660,7 @@ function useCompletionPickers({
58264
58660
  atMode === "search" && parsed ? parsed.filter : null,
58265
58661
  recentFilesRef
58266
58662
  );
58267
- const atState = (0, import_react85.useMemo)(() => {
58663
+ const atState = (0, import_react86.useMemo)(() => {
58268
58664
  if (!parsed) return null;
58269
58665
  if (atMode === "browse") {
58270
58666
  const entries = browseDir ? [parentBrowseEntry(browseDir), ...browse.entries] : browse.entries;
@@ -58283,7 +58679,7 @@ function useCompletionPickers({
58283
58679
  searching: search.searching
58284
58680
  };
58285
58681
  }, [parsed, atMode, browseDir, browse, search]);
58286
- (0, import_react85.useEffect)(() => {
58682
+ (0, import_react86.useEffect)(() => {
58287
58683
  setAtSelected((prev) => {
58288
58684
  const len = atState?.entries.length ?? 0;
58289
58685
  if (len === 0) return 0;
@@ -58291,7 +58687,7 @@ function useCompletionPickers({
58291
58687
  return prev;
58292
58688
  });
58293
58689
  }, [atState]);
58294
- const pickAtMention = (0, import_react85.useCallback)(
58690
+ const pickAtMention = (0, import_react86.useCallback)(
58295
58691
  (entry, action) => {
58296
58692
  if (!atPicker) return;
58297
58693
  const before = input.slice(0, atPicker.atOffset);
@@ -58301,8 +58697,8 @@ function useCompletionPickers({
58301
58697
  },
58302
58698
  [atPicker, input, setInput]
58303
58699
  );
58304
- const [slashArgSelected, setSlashArgSelected] = (0, import_react85.useState)(0);
58305
- const slashArgContext = (0, import_react85.useMemo)(() => {
58700
+ const [slashArgSelected, setSlashArgSelected] = (0, import_react86.useState)(0);
58701
+ const slashArgContext = (0, import_react86.useMemo)(() => {
58306
58702
  if (!input.startsWith("/")) return null;
58307
58703
  if (slashMatches !== null) return null;
58308
58704
  return detectSlashArgContext(input, !!codeMode);
@@ -58312,7 +58708,7 @@ function useCompletionPickers({
58312
58708
  slashArgContext?.kind === "picker" && slashArgContext.spec.argCompleter === "path" ? slashArgContext.partial : null,
58313
58709
  slashArgContext?.kind === "picker" && slashArgContext.spec.argCompleter === "path"
58314
58710
  );
58315
- const slashArgMatches = (0, import_react85.useMemo)(() => {
58711
+ const slashArgMatches = (0, import_react86.useMemo)(() => {
58316
58712
  if (!slashArgContext || slashArgContext.kind !== "picker") return null;
58317
58713
  const completer = slashArgContext.spec.argCompleter;
58318
58714
  const partial = slashArgContext.partial;
@@ -58366,14 +58762,14 @@ function useCompletionPickers({
58366
58762
  }
58367
58763
  return null;
58368
58764
  }, [slashArgContext, models, mcpServers, codeMode, slashArgPathCandidates]);
58369
- (0, import_react85.useEffect)(() => {
58765
+ (0, import_react86.useEffect)(() => {
58370
58766
  setSlashArgSelected((prev) => {
58371
58767
  if (!slashArgMatches || slashArgMatches.length === 0) return 0;
58372
58768
  if (prev >= slashArgMatches.length) return slashArgMatches.length - 1;
58373
58769
  return prev;
58374
58770
  });
58375
58771
  }, [slashArgMatches]);
58376
- const pickSlashArg = (0, import_react85.useCallback)(
58772
+ const pickSlashArg = (0, import_react86.useCallback)(
58377
58773
  (chosen, isDir) => {
58378
58774
  if (!slashArgContext) return;
58379
58775
  const before = input.slice(0, slashArgContext.partialOffset);
@@ -58407,8 +58803,8 @@ function useCompletionPickers({
58407
58803
  };
58408
58804
  }
58409
58805
  function usePathCandidates(rootDir, partial, isActive) {
58410
- const [entries, setEntries] = (0, import_react85.useState)([]);
58411
- (0, import_react85.useEffect)(() => {
58806
+ const [entries, setEntries] = (0, import_react86.useState)([]);
58807
+ (0, import_react86.useEffect)(() => {
58412
58808
  if (!isActive) {
58413
58809
  setEntries([]);
58414
58810
  return;
@@ -58428,7 +58824,7 @@ function usePathCandidates(rootDir, partial, isActive) {
58428
58824
  relPartial = partial.slice(root.length).replace(/\\/g, "/");
58429
58825
  insertIsAbsolute = true;
58430
58826
  } else {
58431
- const resolved = resolve(rootDir, partial);
58827
+ const resolved = resolve2(rootDir, partial);
58432
58828
  const relToRoot = relative(rootDir, resolved);
58433
58829
  if (relToRoot.startsWith("..") || isAbsolute(relToRoot)) {
58434
58830
  const root = parse(resolved).root;
@@ -58476,9 +58872,9 @@ function usePathCandidates(rootDir, partial, isActive) {
58476
58872
  return entries;
58477
58873
  }
58478
58874
  function useBrowseListing(rootDir, dir) {
58479
- const [entries, setEntries] = (0, import_react85.useState)([]);
58480
- const [loading, setLoading] = (0, import_react85.useState)(false);
58481
- (0, import_react85.useEffect)(() => {
58875
+ const [entries, setEntries] = (0, import_react86.useState)([]);
58876
+ const [loading, setLoading] = (0, import_react86.useState)(false);
58877
+ (0, import_react86.useEffect)(() => {
58482
58878
  if (dir === null) {
58483
58879
  setEntries([]);
58484
58880
  setLoading(false);
@@ -58519,12 +58915,12 @@ function parentBrowseEntry(currentDir) {
58519
58915
  };
58520
58916
  }
58521
58917
  function useStreamingSearch(rootDir, filter, recentFilesRef) {
58522
- const [, bumpRender] = (0, import_react85.useReducer)((x) => x + 1, 0);
58523
- const hitsRef = (0, import_react85.useRef)([]);
58524
- const scannedRef = (0, import_react85.useRef)(0);
58525
- const searchingRef = (0, import_react85.useRef)(false);
58526
- const rankedRef = (0, import_react85.useRef)([]);
58527
- (0, import_react85.useEffect)(() => {
58918
+ const [, bumpRender] = (0, import_react86.useReducer)((x) => x + 1, 0);
58919
+ const hitsRef = (0, import_react86.useRef)([]);
58920
+ const scannedRef = (0, import_react86.useRef)(0);
58921
+ const searchingRef = (0, import_react86.useRef)(false);
58922
+ const rankedRef = (0, import_react86.useRef)([]);
58923
+ (0, import_react86.useEffect)(() => {
58528
58924
  if (filter === null) {
58529
58925
  hitsRef.current = [];
58530
58926
  scannedRef.current = 0;
@@ -58595,14 +58991,14 @@ function rankSearchHits(hits, filter, recent) {
58595
58991
  }
58596
58992
 
58597
58993
  // src/cli/ui/useEditHistory.ts
58598
- var import_react86 = __toESM(require_react(), 1);
58994
+ var import_react87 = __toESM(require_react(), 1);
58599
58995
  function useEditHistory(codeMode) {
58600
- const editHistory = (0, import_react86.useRef)([]);
58601
- const nextHistoryId = (0, import_react86.useRef)(1);
58602
- const currentTurnEntry = (0, import_react86.useRef)(null);
58603
- const [undoBanner, setUndoBanner] = (0, import_react86.useState)(null);
58604
- const undoTimeoutRef = (0, import_react86.useRef)(null);
58605
- const recordEdit = (0, import_react86.useCallback)(
58996
+ const editHistory = (0, import_react87.useRef)([]);
58997
+ const nextHistoryId = (0, import_react87.useRef)(1);
58998
+ const currentTurnEntry = (0, import_react87.useRef)(null);
58999
+ const [undoBanner, setUndoBanner] = (0, import_react87.useState)(null);
59000
+ const undoTimeoutRef = (0, import_react87.useRef)(null);
59001
+ const recordEdit = (0, import_react87.useCallback)(
58606
59002
  (source, blocks, results, snaps) => {
58607
59003
  if (snaps.length === 0) return;
58608
59004
  let entry = currentTurnEntry.current;
@@ -58628,7 +59024,7 @@ function useEditHistory(codeMode) {
58628
59024
  },
58629
59025
  []
58630
59026
  );
58631
- const armUndoBanner = (0, import_react86.useCallback)((results) => {
59027
+ const armUndoBanner = (0, import_react87.useCallback)((results) => {
58632
59028
  setUndoBanner({ results, expiresAt: Date.now() + 5e3, pausedRemainingMs: null });
58633
59029
  if (undoTimeoutRef.current) clearTimeout(undoTimeoutRef.current);
58634
59030
  undoTimeoutRef.current = setTimeout(() => {
@@ -58636,7 +59032,7 @@ function useEditHistory(codeMode) {
58636
59032
  undoTimeoutRef.current = null;
58637
59033
  }, 5e3);
58638
59034
  }, []);
58639
- const toggleUndoPause = (0, import_react86.useCallback)(() => {
59035
+ const toggleUndoPause = (0, import_react87.useCallback)(() => {
58640
59036
  setUndoBanner((prev) => {
58641
59037
  if (!prev) return prev;
58642
59038
  if (prev.pausedRemainingMs === null) {
@@ -58655,7 +59051,7 @@ function useEditHistory(codeMode) {
58655
59051
  return { ...prev, expiresAt: Date.now() + remaining, pausedRemainingMs: null };
58656
59052
  });
58657
59053
  }, []);
58658
- const codeUndo = (0, import_react86.useCallback)(
59054
+ const codeUndo = (0, import_react87.useCallback)(
58659
59055
  (args = []) => {
58660
59056
  if (!codeMode) return "not in code mode";
58661
59057
  const root = codeMode.rootDir;
@@ -58713,7 +59109,7 @@ function useEditHistory(codeMode) {
58713
59109
  },
58714
59110
  [codeMode]
58715
59111
  );
58716
- const codeHistory = (0, import_react86.useCallback)(() => {
59112
+ const codeHistory = (0, import_react87.useCallback)(() => {
58717
59113
  if (!codeMode) return "not in code mode";
58718
59114
  const entries = editHistory.current;
58719
59115
  if (entries.length === 0) return "no edits recorded this session yet";
@@ -58738,7 +59134,7 @@ function useEditHistory(codeMode) {
58738
59134
  );
58739
59135
  return lines.join("\n");
58740
59136
  }, [codeMode]);
58741
- const codeShowEdit = (0, import_react86.useCallback)(
59137
+ const codeShowEdit = (0, import_react87.useCallback)(
58742
59138
  (args = []) => {
58743
59139
  if (!codeMode) return "not in code mode";
58744
59140
  const entries = editHistory.current;
@@ -58796,14 +59192,14 @@ function useEditHistory(codeMode) {
58796
59192
  },
58797
59193
  [codeMode]
58798
59194
  );
58799
- const sealCurrentEntry = (0, import_react86.useCallback)(() => {
59195
+ const sealCurrentEntry = (0, import_react87.useCallback)(() => {
58800
59196
  currentTurnEntry.current = null;
58801
59197
  }, []);
58802
- const hasUndoable = (0, import_react86.useCallback)(
59198
+ const hasUndoable = (0, import_react87.useCallback)(
58803
59199
  () => editHistory.current.some((e) => !isEntryFullyUndone(e)),
58804
59200
  []
58805
59201
  );
58806
- const touchedPaths = (0, import_react86.useCallback)(() => {
59202
+ const touchedPaths = (0, import_react87.useCallback)(() => {
58807
59203
  const seen = /* @__PURE__ */ new Set();
58808
59204
  for (const entry of editHistory.current) {
58809
59205
  for (const b of entry.blocks) seen.add(b.path);
@@ -58825,12 +59221,12 @@ function useEditHistory(codeMode) {
58825
59221
  }
58826
59222
 
58827
59223
  // src/cli/ui/useSessionInfo.ts
58828
- var import_react87 = __toESM(require_react(), 1);
59224
+ var import_react88 = __toESM(require_react(), 1);
58829
59225
  function useSessionInfo(loop2) {
58830
- const [balance, setBalance] = (0, import_react87.useState)(null);
58831
- const [models, setModels] = (0, import_react87.useState)(null);
58832
- const [latestVersion, setLatestVersion] = (0, import_react87.useState)(null);
58833
- (0, import_react87.useEffect)(() => {
59226
+ const [balance, setBalance] = (0, import_react88.useState)(null);
59227
+ const [models, setModels] = (0, import_react88.useState)(null);
59228
+ const [latestVersion, setLatestVersion] = (0, import_react88.useState)(null);
59229
+ (0, import_react88.useEffect)(() => {
58834
59230
  let cancelled = false;
58835
59231
  void (async () => {
58836
59232
  const bal = await loop2.client.getBalance().catch(() => null);
@@ -58843,7 +59239,7 @@ function useSessionInfo(loop2) {
58843
59239
  cancelled = true;
58844
59240
  };
58845
59241
  }, [loop2]);
58846
- (0, import_react87.useEffect)(() => {
59242
+ (0, import_react88.useEffect)(() => {
58847
59243
  let cancelled = false;
58848
59244
  void (async () => {
58849
59245
  const list2 = await loop2.client.listModels().catch(() => null);
@@ -58854,7 +59250,7 @@ function useSessionInfo(loop2) {
58854
59250
  cancelled = true;
58855
59251
  };
58856
59252
  }, [loop2]);
58857
- (0, import_react87.useEffect)(() => {
59253
+ (0, import_react88.useEffect)(() => {
58858
59254
  let cancelled = false;
58859
59255
  void (async () => {
58860
59256
  const latest = await getLatestVersion();
@@ -58866,7 +59262,7 @@ function useSessionInfo(loop2) {
58866
59262
  };
58867
59263
  }, []);
58868
59264
  const updateAvailable = latestVersion && compareVersions(VERSION, latestVersion) < 0 ? latestVersion : null;
58869
- const refreshBalance = (0, import_react87.useCallback)(() => {
59265
+ const refreshBalance = (0, import_react88.useCallback)(() => {
58870
59266
  void (async () => {
58871
59267
  const bal = await loop2.client.getBalance().catch(() => null);
58872
59268
  const primary = bal ? pickPrimaryBalance(bal.balance_infos) : null;
@@ -58875,13 +59271,13 @@ function useSessionInfo(loop2) {
58875
59271
  }
58876
59272
  })();
58877
59273
  }, [loop2]);
58878
- const refreshModels = (0, import_react87.useCallback)(() => {
59274
+ const refreshModels = (0, import_react88.useCallback)(() => {
58879
59275
  void (async () => {
58880
59276
  const list2 = await loop2.client.listModels().catch(() => null);
58881
59277
  if (list2) setModels(list2.data.map((m) => m.id));
58882
59278
  })();
58883
59279
  }, [loop2]);
58884
- const refreshLatestVersion = (0, import_react87.useCallback)(() => {
59280
+ const refreshLatestVersion = (0, import_react88.useCallback)(() => {
58885
59281
  void (async () => {
58886
59282
  const fresh = await getLatestVersion({ force: true });
58887
59283
  if (fresh) setLatestVersion(fresh);
@@ -58899,7 +59295,7 @@ function useSessionInfo(loop2) {
58899
59295
  }
58900
59296
 
58901
59297
  // src/cli/ui/useSubagent.ts
58902
- var import_react88 = __toESM(require_react(), 1);
59298
+ var import_react89 = __toESM(require_react(), 1);
58903
59299
  function reduceSubagentInnerEvent(prev, ev) {
58904
59300
  if (ev.kind === "inner") {
58905
59301
  if (!ev.inner) return prev;
@@ -58974,13 +59370,13 @@ function useSubagent({
58974
59370
  log,
58975
59371
  getWalletCurrency
58976
59372
  }) {
58977
- const [activities, setActivities] = (0, import_react88.useState)([]);
58978
- const sinkRef = (0, import_react88.useRef)({ current: null });
58979
- const getWalletCurrencyRef = (0, import_react88.useRef)(getWalletCurrency);
58980
- (0, import_react88.useEffect)(() => {
59373
+ const [activities, setActivities] = (0, import_react89.useState)([]);
59374
+ const sinkRef = (0, import_react89.useRef)({ current: null });
59375
+ const getWalletCurrencyRef = (0, import_react89.useRef)(getWalletCurrency);
59376
+ (0, import_react89.useEffect)(() => {
58981
59377
  getWalletCurrencyRef.current = getWalletCurrency;
58982
59378
  }, [getWalletCurrency]);
58983
- (0, import_react88.useEffect)(() => {
59379
+ (0, import_react89.useEffect)(() => {
58984
59380
  sinkRef.current.current = (ev) => {
58985
59381
  if (ev.kind === "start") {
58986
59382
  setActivities((prev) => {
@@ -59078,14 +59474,14 @@ function App(props) {
59078
59474
  model: props.model,
59079
59475
  workspace: props.codeMode?.rootDir ?? process.cwd()
59080
59476
  });
59081
- const initialCards = import_react89.default.useMemo(
59477
+ const initialCards = import_react90.default.useMemo(
59082
59478
  () => props.session ? hydrateCardsFromMessages(loadSessionMessages(props.session)) : [],
59083
59479
  [props.session]
59084
59480
  );
59085
- const [themeName, setThemeName] = import_react89.default.useState(
59481
+ const [themeName, setThemeName] = import_react90.default.useState(
59086
59482
  () => resolveThemePreference(loadTheme(), process.env.REASONIX_THEME)
59087
59483
  );
59088
- const statusBar = import_react89.default.useMemo(() => {
59484
+ const statusBar = import_react90.default.useMemo(() => {
59089
59485
  const cfg = readConfig().statusBar ?? {};
59090
59486
  return {
59091
59487
  showBalance: cfg.showBalance !== false,
@@ -59097,7 +59493,7 @@ function App(props) {
59097
59493
  showFeedbackHint: cfg.showFeedbackHint !== false
59098
59494
  };
59099
59495
  }, []);
59100
- return /* @__PURE__ */ import_react89.default.createElement(ThemeProvider, { name: themeName }, /* @__PURE__ */ import_react89.default.createElement(AgentStoreProvider, { session, initialCards }, /* @__PURE__ */ import_react89.default.createElement(ChatScrollProvider, null, /* @__PURE__ */ import_react89.default.createElement(
59496
+ return /* @__PURE__ */ import_react90.default.createElement(ThemeProvider, { name: themeName }, /* @__PURE__ */ import_react90.default.createElement(AgentStoreProvider, { session, initialCards }, /* @__PURE__ */ import_react90.default.createElement(ChatScrollProvider, null, /* @__PURE__ */ import_react90.default.createElement(
59101
59497
  AppInner,
59102
59498
  {
59103
59499
  ...props,
@@ -59113,7 +59509,6 @@ function AppInner({
59113
59509
  rebuildSystem,
59114
59510
  transcript,
59115
59511
  budgetUsd,
59116
- failureThreshold,
59117
59512
  session,
59118
59513
  tools,
59119
59514
  mcpSpecs,
@@ -59160,33 +59555,33 @@ function AppInner({
59160
59555
  const lastTurnMs = useAgentState((s) => s.status.lastTurnMs);
59161
59556
  const activityLabel = useActivityLabel();
59162
59557
  const chatScroll = useChatScrollActions();
59163
- const [input, setInput] = (0, import_react89.useState)("");
59164
- const [composerCursor, setComposerCursor] = (0, import_react89.useState)(0);
59165
- const [busy, setBusy] = (0, import_react89.useState)(false);
59166
- const [slashUsage, setSlashUsage] = (0, import_react89.useState)(
59558
+ const [input, setInput] = (0, import_react90.useState)("");
59559
+ const [composerCursor, setComposerCursor] = (0, import_react90.useState)(0);
59560
+ const [busy, setBusy] = (0, import_react90.useState)(false);
59561
+ const [slashUsage, setSlashUsage] = (0, import_react90.useState)(
59167
59562
  () => loadSlashUsage()
59168
59563
  );
59169
- const [liveExpand, setLiveExpand] = (0, import_react89.useState)(false);
59170
- (0, import_react89.useEffect)(() => {
59564
+ const [liveExpand, setLiveExpand] = (0, import_react90.useState)(false);
59565
+ (0, import_react90.useEffect)(() => {
59171
59566
  if (!isStreaming && liveExpand) setLiveExpand(false);
59172
59567
  }, [isStreaming, liveExpand]);
59173
59568
  const languageVersion = useLanguageReload();
59174
- const showBanner = (0, import_react89.useMemo)(() => readConfig().banner !== false, []);
59175
- const [bootReady, setBootReady] = (0, import_react89.useState)(!showBanner);
59176
- (0, import_react89.useEffect)(() => {
59569
+ const showBanner = (0, import_react90.useMemo)(() => readConfig().banner !== false, []);
59570
+ const [bootReady, setBootReady] = (0, import_react90.useState)(!showBanner);
59571
+ (0, import_react90.useEffect)(() => {
59177
59572
  if (!showBanner) return;
59178
59573
  const t2 = setTimeout(() => setBootReady(true), 1400);
59179
59574
  return () => clearTimeout(t2);
59180
59575
  }, [showBanner]);
59181
- (0, import_react89.useEffect)(() => {
59576
+ (0, import_react90.useEffect)(() => {
59182
59577
  markPhase("first_paint");
59183
59578
  dumpStartupProfile();
59184
59579
  }, []);
59185
- const [liveMcpServers, setLiveMcpServers] = (0, import_react89.useState)(() => mcpServers ?? []);
59186
- const liveMcpServersRef = (0, import_react89.useRef)(liveMcpServers);
59580
+ const [liveMcpServers, setLiveMcpServers] = (0, import_react90.useState)(() => mcpServers ?? []);
59581
+ const liveMcpServersRef = (0, import_react90.useRef)(liveMcpServers);
59187
59582
  liveMcpServersRef.current = liveMcpServers;
59188
- const abortedThisTurn = (0, import_react89.useRef)(false);
59189
- (0, import_react89.useEffect)(() => {
59583
+ const abortedThisTurn = (0, import_react90.useRef)(false);
59584
+ (0, import_react90.useEffect)(() => {
59190
59585
  busyRef.current = busy;
59191
59586
  }, [busy]);
59192
59587
  const {
@@ -59199,7 +59594,7 @@ function AppInner({
59199
59594
  clear: clearToolProgressDisplay
59200
59595
  } = useToolProgressDisplay(progressSink);
59201
59596
  const { stdout } = use_stdout_default();
59202
- const walletCurrencyRef = (0, import_react89.useRef)(void 0);
59597
+ const walletCurrencyRef = (0, import_react90.useRef)(void 0);
59203
59598
  const { activities: subagentActivities, sinkRef: subagentSinkRef } = useSubagent({
59204
59599
  session,
59205
59600
  log,
@@ -59232,37 +59627,39 @@ function AppInner({
59232
59627
  modeFlash
59233
59628
  } = useEditGate(!!codeMode);
59234
59629
  const { preset: preset2, setPreset, proArmed, setProArmed, turnOnPro, setTurnOnPro } = usePresetMode(model2);
59235
- const planModeRef = (0, import_react89.useRef)(false);
59236
- const latestVersionRef = (0, import_react89.useRef)(null);
59237
- const [pendingEditReview, setPendingEditReview] = (0, import_react89.useState)(null);
59238
- const [walkthroughActive, setWalkthroughActive] = (0, import_react89.useState)(false);
59239
- const editReviewResolveRef = (0, import_react89.useRef)(null);
59240
- const turnEditPolicyRef = (0, import_react89.useRef)("ask");
59241
- const [pendingShell, setPendingShell] = (0, import_react89.useState)(null);
59242
- const [pendingPath, setPendingPath] = (0, import_react89.useState)(null);
59243
- const [pendingPlan, setPendingPlan] = (0, import_react89.useState)(null);
59244
- const [pendingReviseEditor, setPendingReviseEditor] = (0, import_react89.useState)(null);
59245
- const [pendingSessionsPicker, setPendingSessionsPicker] = (0, import_react89.useState)(false);
59246
- const [sessionsPickerList, setSessionsPickerList] = (0, import_react89.useState)(
59630
+ const planModeRef = (0, import_react90.useRef)(false);
59631
+ const latestVersionRef = (0, import_react90.useRef)(null);
59632
+ const [pendingEditReview, setPendingEditReview] = (0, import_react90.useState)(null);
59633
+ const [walkthroughActive, setWalkthroughActive] = (0, import_react90.useState)(false);
59634
+ const editReviewResolveRef = (0, import_react90.useRef)(null);
59635
+ const turnEditPolicyRef = (0, import_react90.useRef)("ask");
59636
+ const [pendingShell, setPendingShell] = (0, import_react90.useState)(null);
59637
+ const [pendingPath, setPendingPath] = (0, import_react90.useState)(null);
59638
+ const [pendingPlan, setPendingPlan] = (0, import_react90.useState)(null);
59639
+ const [pendingReviseEditor, setPendingReviseEditor] = (0, import_react90.useState)(null);
59640
+ const [pendingSessionsPicker, setPendingSessionsPicker] = (0, import_react90.useState)(false);
59641
+ const [sessionsPickerList, setSessionsPickerList] = (0, import_react90.useState)(
59247
59642
  () => listSessionsForWorkspace(currentRootDir)
59248
59643
  );
59249
- const [sessionsPickerFocus, setSessionsPickerFocus] = (0, import_react89.useState)(0);
59250
- const [pendingCheckpointPicker, setPendingCheckpointPicker] = (0, import_react89.useState)(false);
59251
- const [checkpointPickerList, setCheckpointPickerList] = (0, import_react89.useState)([]);
59252
- const [pendingMcpHub, setPendingMcpHub] = (0, import_react89.useState)(null);
59253
- const [pendingModelPicker, setPendingModelPicker] = (0, import_react89.useState)(false);
59254
- const [pendingThemePicker, setPendingThemePicker] = (0, import_react89.useState)(false);
59255
- const [pendingCopyMode, setPendingCopyMode] = (0, import_react89.useState)(false);
59256
- const [stagedInput, setStagedInput] = (0, import_react89.useState)(null);
59257
- const [pendingCheckpoint, setPendingCheckpoint] = (0, import_react89.useState)(null);
59258
- const [stagedCheckpointRevise, setStagedCheckpointRevise] = (0, import_react89.useState)(null);
59259
- const [pendingRevision, setPendingRevision] = (0, import_react89.useState)(null);
59260
- const [pendingChoice, setPendingChoice] = (0, import_react89.useState)(null);
59261
- const [stagedChoiceCustom, setStagedChoiceCustom] = (0, import_react89.useState)(null);
59262
- const modalOpen = !!pendingShell || !!pendingPlan || !!pendingReviseEditor || !!pendingSessionsPicker || !!pendingCheckpointPicker || !!pendingMcpHub || pendingModelPicker || pendingThemePicker || pendingCopyMode || !!stagedInput || !!pendingEditReview || walkthroughActive || !!pendingChoice || !!stagedChoiceCustom || !!pendingRevision || !!stagedCheckpointRevise || !!pendingCheckpoint;
59263
- const noTakeoverOverlay = !pendingShell && !pendingPath && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview;
59264
- const [planMode, setPlanMode] = (0, import_react89.useState)(false);
59265
- const [queuedSubmit, setQueuedSubmit] = (0, import_react89.useState)(null);
59644
+ const [sessionsPickerFocus, setSessionsPickerFocus] = (0, import_react90.useState)(0);
59645
+ const [pendingWorkspacePicker, setPendingWorkspacePicker] = (0, import_react90.useState)(false);
59646
+ const [workspacePickerList, setWorkspacePickerList] = (0, import_react90.useState)(() => listKnownWorkspaces(currentRootDir));
59647
+ const [pendingCheckpointPicker, setPendingCheckpointPicker] = (0, import_react90.useState)(false);
59648
+ const [checkpointPickerList, setCheckpointPickerList] = (0, import_react90.useState)([]);
59649
+ const [pendingMcpHub, setPendingMcpHub] = (0, import_react90.useState)(null);
59650
+ const [pendingModelPicker, setPendingModelPicker] = (0, import_react90.useState)(false);
59651
+ const [pendingThemePicker, setPendingThemePicker] = (0, import_react90.useState)(false);
59652
+ const [pendingCopyMode, setPendingCopyMode] = (0, import_react90.useState)(false);
59653
+ const [stagedInput, setStagedInput] = (0, import_react90.useState)(null);
59654
+ const [pendingCheckpoint, setPendingCheckpoint] = (0, import_react90.useState)(null);
59655
+ const [stagedCheckpointRevise, setStagedCheckpointRevise] = (0, import_react90.useState)(null);
59656
+ const [pendingRevision, setPendingRevision] = (0, import_react90.useState)(null);
59657
+ const [pendingChoice, setPendingChoice] = (0, import_react90.useState)(null);
59658
+ const [stagedChoiceCustom, setStagedChoiceCustom] = (0, import_react90.useState)(null);
59659
+ const modalOpen = !!pendingShell || !!pendingPlan || !!pendingReviseEditor || !!pendingSessionsPicker || !!pendingWorkspacePicker || !!pendingCheckpointPicker || !!pendingMcpHub || pendingModelPicker || pendingThemePicker || pendingCopyMode || !!stagedInput || !!pendingEditReview || walkthroughActive || !!pendingChoice || !!stagedChoiceCustom || !!pendingRevision || !!stagedCheckpointRevise || !!pendingCheckpoint;
59660
+ const noTakeoverOverlay = !pendingShell && !pendingPath && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingWorkspacePicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview;
59661
+ const [planMode, setPlanMode] = (0, import_react90.useState)(false);
59662
+ const [queuedSubmit, setQueuedSubmit] = (0, import_react90.useState)(null);
59266
59663
  const {
59267
59664
  recallPrev,
59268
59665
  recallNext,
@@ -59271,7 +59668,7 @@ function AppInner({
59271
59668
  history: promptHistory
59272
59669
  } = useInputRecall(setInput);
59273
59670
  const { setRawMode, isRawModeSupported } = use_stdin_default();
59274
- const handleOpenExternalEditor = (0, import_react89.useCallback)(async () => {
59671
+ const handleOpenExternalEditor = (0, import_react90.useCallback)(async () => {
59275
59672
  if (!isRawModeSupported) {
59276
59673
  log.pushWarning(t("composer.editorFailed"), t("composer.editorNoRawMode"));
59277
59674
  return;
@@ -59285,25 +59682,25 @@ function AppInner({
59285
59682
  setRawMode(true);
59286
59683
  }
59287
59684
  }, [input, isRawModeSupported, log, setRawMode]);
59288
- const assistantIterCounter = (0, import_react89.useRef)(0);
59289
- const atUrlCache = (0, import_react89.useRef)(/* @__PURE__ */ new Map());
59290
- const handleSubmitRef = (0, import_react89.useRef)(null);
59291
- const busyRef = (0, import_react89.useRef)(false);
59292
- const submittingRef = (0, import_react89.useRef)(false);
59293
- const dashboardRef = (0, import_react89.useRef)(null);
59294
- const dashboardStartingRef = (0, import_react89.useRef)(null);
59295
- const eventSubscribersRef = (0, import_react89.useRef)(/* @__PURE__ */ new Set());
59296
- const activePickerResolverRef = (0, import_react89.useRef)(null);
59297
- const activePickerSnapshotRef = (0, import_react89.useRef)(null);
59298
- const activeViewerResolverRef = (0, import_react89.useRef)(null);
59299
- const activeViewerSnapshotRef = (0, import_react89.useRef)(null);
59300
- const [pendingReplayViewer, setPendingReplayViewer] = (0, import_react89.useState)(null);
59301
- const planStepsRef = (0, import_react89.useRef)(null);
59302
- const completedStepIdsRef = (0, import_react89.useRef)(/* @__PURE__ */ new Set());
59303
- const planBodyRef = (0, import_react89.useRef)(null);
59304
- const planSummaryRef = (0, import_react89.useRef)(null);
59305
- const toolStartedAtRef = (0, import_react89.useRef)(null);
59306
- const persistPlanState = (0, import_react89.useCallback)(() => {
59685
+ const assistantIterCounter = (0, import_react90.useRef)(0);
59686
+ const atUrlCache = (0, import_react90.useRef)(/* @__PURE__ */ new Map());
59687
+ const handleSubmitRef = (0, import_react90.useRef)(null);
59688
+ const busyRef = (0, import_react90.useRef)(false);
59689
+ const submittingRef = (0, import_react90.useRef)(false);
59690
+ const dashboardRef = (0, import_react90.useRef)(null);
59691
+ const dashboardStartingRef = (0, import_react90.useRef)(null);
59692
+ const eventSubscribersRef = (0, import_react90.useRef)(/* @__PURE__ */ new Set());
59693
+ const activePickerResolverRef = (0, import_react90.useRef)(null);
59694
+ const activePickerSnapshotRef = (0, import_react90.useRef)(null);
59695
+ const activeViewerResolverRef = (0, import_react90.useRef)(null);
59696
+ const activeViewerSnapshotRef = (0, import_react90.useRef)(null);
59697
+ const [pendingReplayViewer, setPendingReplayViewer] = (0, import_react90.useState)(null);
59698
+ const planStepsRef = (0, import_react90.useRef)(null);
59699
+ const completedStepIdsRef = (0, import_react90.useRef)(/* @__PURE__ */ new Set());
59700
+ const planBodyRef = (0, import_react90.useRef)(null);
59701
+ const planSummaryRef = (0, import_react90.useRef)(null);
59702
+ const toolStartedAtRef = (0, import_react90.useRef)(null);
59703
+ const persistPlanState = (0, import_react90.useCallback)(() => {
59307
59704
  if (!session) return;
59308
59705
  const steps = planStepsRef.current;
59309
59706
  if (!steps || steps.length === 0) {
@@ -59315,7 +59712,7 @@ function AppInner({
59315
59712
  if (planSummaryRef.current) extras.summary = planSummaryRef.current;
59316
59713
  savePlanState(session, steps, completedStepIdsRef.current, extras);
59317
59714
  }, [session]);
59318
- const [summary, setSummary] = (0, import_react89.useState)({
59715
+ const [summary, setSummary] = (0, import_react90.useState)({
59319
59716
  turns: 0,
59320
59717
  totalCostUsd: 0,
59321
59718
  totalInputCostUsd: 0,
@@ -59326,7 +59723,7 @@ function AppInner({
59326
59723
  lastPromptTokens: 0,
59327
59724
  lastTurnCostUsd: 0
59328
59725
  });
59329
- const transcriptRef = (0, import_react89.useRef)(null);
59726
+ const transcriptRef = (0, import_react90.useRef)(null);
59330
59727
  if (transcript && !transcriptRef.current) {
59331
59728
  transcriptRef.current = openTranscriptFile(transcript, {
59332
59729
  version: 1,
@@ -59335,21 +59732,21 @@ function AppInner({
59335
59732
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
59336
59733
  });
59337
59734
  }
59338
- const eventSinkRef = (0, import_react89.useRef)(null);
59339
- const eventizerRef = (0, import_react89.useRef)(null);
59735
+ const eventSinkRef = (0, import_react90.useRef)(null);
59736
+ const eventizerRef = (0, import_react90.useRef)(null);
59340
59737
  if (session && !eventSinkRef.current) {
59341
59738
  eventSinkRef.current = openEventSink(eventLogPath(session));
59342
59739
  eventizerRef.current = new Eventizer();
59343
59740
  eventSinkRef.current.append(eventizerRef.current.emitSessionOpened(0, session, 0));
59344
59741
  }
59345
- (0, import_react89.useEffect)(() => {
59742
+ (0, import_react90.useEffect)(() => {
59346
59743
  return () => {
59347
59744
  transcriptRef.current?.end();
59348
59745
  void eventSinkRef.current?.close();
59349
59746
  };
59350
59747
  }, []);
59351
- const loopRef = (0, import_react89.useRef)(null);
59352
- const loop2 = (0, import_react89.useMemo)(() => {
59748
+ const loopRef = (0, import_react90.useRef)(null);
59749
+ const loop2 = (0, import_react90.useMemo)(() => {
59353
59750
  if (loopRef.current) return loopRef.current;
59354
59751
  const client = new DeepSeekClient({ baseUrl: loadBaseUrl() });
59355
59752
  if (tools && !tools.has("run_skill")) {
@@ -59387,20 +59784,22 @@ function AppInner({
59387
59784
  tools,
59388
59785
  model: model2,
59389
59786
  budgetUsd,
59390
- failureThreshold,
59391
59787
  session,
59392
59788
  hooks: hookList,
59393
59789
  hookCwd: currentRootDir,
59394
59790
  // Restore the user's last-chosen effort cap. Without this a
59395
- // `/effort high` silently reverted to `max` on relaunch 闂?the
59791
+ // `/effort high` silently reverted to `max` on relaunch the
59396
59792
  // loop's constructor default wins over persisted state.
59397
59793
  reasoningEffort: loadReasoningEffort(),
59398
59794
  rebuildSystem
59399
59795
  });
59400
59796
  loopRef.current = l;
59401
59797
  return l;
59402
- }, [model2, system, rebuildSystem, budgetUsd, failureThreshold, session, tools, codeMode]);
59403
- const generateCurrentSessionTitle = (0, import_react89.useCallback)(
59798
+ }, [model2, system, rebuildSystem, budgetUsd, session, tools, codeMode]);
59799
+ (0, import_react90.useEffect)(() => {
59800
+ setSummary(loop2.stats.summary());
59801
+ }, [loop2]);
59802
+ const generateCurrentSessionTitle = (0, import_react90.useCallback)(
59404
59803
  async (seed) => {
59405
59804
  if (!session || !onSwitchSession) return t("app.sessionTitleNoSession");
59406
59805
  const userText = seed?.userText ?? lastMessageContent(loop2.log.entries, "user");
@@ -59435,7 +59834,44 @@ function AppInner({
59435
59834
  },
59436
59835
  [currentRootDir, loop2.client, loop2.log.entries, loop2.model, model2, onSwitchSession, session]
59437
59836
  );
59438
- (0, import_react89.useEffect)(() => {
59837
+ const switchWorkspaceRoot = (0, import_react90.useCallback)(
59838
+ (newPath) => {
59839
+ if (!codeMode?.reregisterTools) return { ok: false, info: t("handlers.edits.cwdCodeOnly") };
59840
+ const resolved = resolve3(newPath);
59841
+ let stat;
59842
+ try {
59843
+ stat = statSync2(resolved);
59844
+ } catch (err) {
59845
+ return { ok: false, info: `/cwd: ${err.message}` };
59846
+ }
59847
+ if (!stat.isDirectory()) {
59848
+ return { ok: false, info: `/cwd: ${resolved} is not a directory` };
59849
+ }
59850
+ codeMode.reregisterTools(resolved);
59851
+ codeMode.onRootChange?.(resolved);
59852
+ rememberWorkspace(resolved);
59853
+ setCurrentRootDir(resolved);
59854
+ setSessionsPickerList(listSessionsForWorkspace(resolved));
59855
+ setWorkspacePickerList(listKnownWorkspaces(resolved));
59856
+ reloadHooks(resolved);
59857
+ const reBootstrap = codeMode.reBootstrapSemantic;
59858
+ if (reBootstrap) {
59859
+ void reBootstrap(resolved).then(
59860
+ (r) => {
59861
+ log.pushInfo(
59862
+ r.enabled ? t("app.semanticRepointed", { root: resolved }) : t("app.semanticDisabledForRoot", { root: resolved })
59863
+ );
59864
+ },
59865
+ (err) => {
59866
+ log.pushInfo(t("app.semanticRebootstrapFailed", { reason: err.message }));
59867
+ }
59868
+ );
59869
+ }
59870
+ return { ok: true, info: t("app.workspaceSwitched", { root: resolved }) };
59871
+ },
59872
+ [codeMode, log, reloadHooks, setCurrentRootDir]
59873
+ );
59874
+ (0, import_react90.useEffect)(() => {
59439
59875
  if (!session || !tools) return;
59440
59876
  tools.setAuditListener((event) => {
59441
59877
  const sink = eventSinkRef.current;
@@ -59478,15 +59914,15 @@ function AppInner({
59478
59914
  pauseGate.setAuditListener(null);
59479
59915
  };
59480
59916
  }, [loop2, session, tools]);
59481
- (0, import_react89.useEffect)(() => {
59917
+ (0, import_react90.useEffect)(() => {
59482
59918
  loop2.hooks = hookList;
59483
59919
  }, [loop2, hookList]);
59484
- (0, import_react89.useEffect)(() => {
59920
+ (0, import_react90.useEffect)(() => {
59485
59921
  const canonical = loop2.model === "deepseek-v4-pro" ? "pro" : loop2.model === "deepseek-v4-flash" ? loop2.autoEscalate ? "auto" : "flash" : null;
59486
59922
  agentStore.dispatch({ type: "session.preset.change", preset: canonical });
59487
59923
  }, []);
59488
- const mcpBridgeStartedRef = (0, import_react89.useRef)(false);
59489
- (0, import_react89.useEffect)(() => {
59924
+ const mcpBridgeStartedRef = (0, import_react90.useRef)(false);
59925
+ (0, import_react90.useEffect)(() => {
59490
59926
  if (mcpBridgeStartedRef.current) return;
59491
59927
  if (!mcpRuntime || !mcpSpecs || mcpSpecs.length === 0) return;
59492
59928
  mcpBridgeStartedRef.current = true;
@@ -59558,18 +59994,18 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59558
59994
  }
59559
59995
  }, [mcpRuntime, mcpSpecs, loop2, log, agentStore]);
59560
59996
  const { balance, models, latestVersion, refreshBalance, refreshModels, refreshLatestVersion } = useSessionInfo(loop2);
59561
- (0, import_react89.useEffect)(() => {
59997
+ (0, import_react90.useEffect)(() => {
59562
59998
  planModeRef.current = planMode;
59563
59999
  }, [planMode]);
59564
- (0, import_react89.useEffect)(() => {
60000
+ (0, import_react90.useEffect)(() => {
59565
60001
  latestVersionRef.current = latestVersion ?? null;
59566
60002
  }, [latestVersion]);
59567
- const balanceRef = (0, import_react89.useRef)(null);
59568
- const modelsRef = (0, import_react89.useRef)(null);
59569
- (0, import_react89.useEffect)(() => {
60003
+ const balanceRef = (0, import_react90.useRef)(null);
60004
+ const modelsRef = (0, import_react90.useRef)(null);
60005
+ (0, import_react90.useEffect)(() => {
59570
60006
  modelsRef.current = models;
59571
60007
  }, [models]);
59572
- (0, import_react89.useEffect)(() => {
60008
+ (0, import_react90.useEffect)(() => {
59573
60009
  balanceRef.current = balance;
59574
60010
  walletCurrencyRef.current = balance?.currency;
59575
60011
  if (balance) {
@@ -59579,7 +60015,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59579
60015
  });
59580
60016
  }
59581
60017
  }, [balance, agentStore]);
59582
- const broadcastDashboardEvent = (0, import_react89.useCallback)((ev) => {
60018
+ const broadcastDashboardEvent = (0, import_react90.useCallback)((ev) => {
59583
60019
  const subs = eventSubscribersRef.current;
59584
60020
  if (subs.size === 0) return;
59585
60021
  for (const h of subs) {
@@ -59589,7 +60025,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59589
60025
  }
59590
60026
  }
59591
60027
  }, []);
59592
- const pickerPorts = (0, import_react89.useMemo)(
60028
+ const pickerPorts = (0, import_react90.useMemo)(
59593
60029
  () => ({
59594
60030
  broadcast: broadcastDashboardEvent,
59595
60031
  resolverRef: activePickerResolverRef,
@@ -59597,7 +60033,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59597
60033
  }),
59598
60034
  [broadcastDashboardEvent]
59599
60035
  );
59600
- const viewerPorts = (0, import_react89.useMemo)(
60036
+ const viewerPorts = (0, import_react90.useMemo)(
59601
60037
  () => ({
59602
60038
  broadcast: broadcastDashboardEvent,
59603
60039
  resolverRef: activeViewerResolverRef,
@@ -59611,10 +60047,10 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59611
60047
  () => setPendingReplayViewer(null),
59612
60048
  viewerPorts
59613
60049
  );
59614
- (0, import_react89.useEffect)(() => {
60050
+ (0, import_react90.useEffect)(() => {
59615
60051
  broadcastDashboardEvent({ kind: "busy-change", busy });
59616
60052
  }, [busy, broadcastDashboardEvent]);
59617
- (0, import_react89.useEffect)(() => {
60053
+ (0, import_react90.useEffect)(() => {
59618
60054
  if (!pendingShell) return;
59619
60055
  const modal = {
59620
60056
  kind: "shell",
@@ -59627,7 +60063,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59627
60063
  broadcastDashboardEvent({ kind: "modal-down", modalKind: "shell" });
59628
60064
  };
59629
60065
  }, [pendingShell, broadcastDashboardEvent]);
59630
- (0, import_react89.useEffect)(() => {
60066
+ (0, import_react90.useEffect)(() => {
59631
60067
  if (!pendingChoice) return;
59632
60068
  const modal = {
59633
60069
  kind: "choice",
@@ -59640,7 +60076,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59640
60076
  broadcastDashboardEvent({ kind: "modal-down", modalKind: "choice" });
59641
60077
  };
59642
60078
  }, [pendingChoice, broadcastDashboardEvent]);
59643
- (0, import_react89.useEffect)(() => {
60079
+ (0, import_react90.useEffect)(() => {
59644
60080
  if (!pendingPlan) return;
59645
60081
  broadcastDashboardEvent({
59646
60082
  kind: "modal-up",
@@ -59650,7 +60086,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59650
60086
  broadcastDashboardEvent({ kind: "modal-down", modalKind: "plan" });
59651
60087
  };
59652
60088
  }, [pendingPlan, broadcastDashboardEvent]);
59653
- (0, import_react89.useEffect)(() => {
60089
+ (0, import_react90.useEffect)(() => {
59654
60090
  if (!pendingEditReview) return;
59655
60091
  const previewLines = (pendingEditReview.search || pendingEditReview.replace || "").split("\n").slice(0, 12);
59656
60092
  const preview = previewLines.join("\n");
@@ -59670,7 +60106,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59670
60106
  broadcastDashboardEvent({ kind: "modal-down", modalKind: "edit-review" });
59671
60107
  };
59672
60108
  }, [pendingEditReview, broadcastDashboardEvent, pendingEdits]);
59673
- (0, import_react89.useEffect)(() => {
60109
+ (0, import_react90.useEffect)(() => {
59674
60110
  if (!pendingRevision) return;
59675
60111
  broadcastDashboardEvent({
59676
60112
  kind: "modal-up",
@@ -59690,7 +60126,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59690
60126
  broadcastDashboardEvent({ kind: "modal-down", modalKind: "revision" });
59691
60127
  };
59692
60128
  }, [pendingRevision, broadcastDashboardEvent]);
59693
- (0, import_react89.useEffect)(() => {
60129
+ (0, import_react90.useEffect)(() => {
59694
60130
  if (!pendingCheckpoint) return;
59695
60131
  broadcastDashboardEvent({
59696
60132
  kind: "modal-up",
@@ -59731,11 +60167,12 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59731
60167
  mcpServers: liveMcpServers,
59732
60168
  slashUsage
59733
60169
  });
59734
- (0, import_react89.useEffect)(() => {
60170
+ (0, import_react90.useEffect)(() => {
59735
60171
  setSessionsPickerList(listSessionsForWorkspace(currentRootDir));
60172
+ setWorkspacePickerList(listKnownWorkspaces(currentRootDir));
59736
60173
  }, [currentRootDir]);
59737
- const [dashboardUrl, setDashboardUrlState] = (0, import_react89.useState)(null);
59738
- const handleHistoryPrev = (0, import_react89.useCallback)(() => {
60174
+ const [dashboardUrl, setDashboardUrlState] = (0, import_react90.useState)(null);
60175
+ const handleHistoryPrev = (0, import_react90.useCallback)(() => {
59739
60176
  if (atState && atState.entries.length > 0) {
59740
60177
  setAtSelected((i) => Math.max(0, i - 1));
59741
60178
  return;
@@ -59758,7 +60195,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59758
60195
  setSlashSelected,
59759
60196
  recallPrev
59760
60197
  ]);
59761
- const handleHistoryNext = (0, import_react89.useCallback)(() => {
60198
+ const handleHistoryNext = (0, import_react90.useCallback)(() => {
59762
60199
  if (atState && atState.entries.length > 0) {
59763
60200
  setAtSelected((i) => Math.min(atState.entries.length - 1, i + 1));
59764
60201
  return;
@@ -59781,8 +60218,8 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59781
60218
  setSlashSelected,
59782
60219
  recallNext
59783
60220
  ]);
59784
- const sessionBannerShown = (0, import_react89.useRef)(false);
59785
- (0, import_react89.useEffect)(() => {
60221
+ const sessionBannerShown = (0, import_react90.useRef)(false);
60222
+ (0, import_react90.useEffect)(() => {
59786
60223
  if (sessionBannerShown.current) return;
59787
60224
  sessionBannerShown.current = true;
59788
60225
  if (!session) {
@@ -59852,19 +60289,27 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59852
60289
  return;
59853
60290
  }
59854
60291
  if (key.ctrl && key.input === "c") {
59855
- quitProcess();
59856
- return;
59857
- }
59858
- if (key.escape && busy) {
59859
- if (abortedThisTurn.current) return;
59860
- abortedThisTurn.current = true;
59861
- resetPendingModals();
59862
- if (isLoopActive()) stopLoop();
59863
- loop2.abort();
60292
+ handleTurnInterrupt("ctrl-c", {
60293
+ turnActiveRef: submittingRef,
60294
+ abortedThisTurn,
60295
+ resetPendingModals,
60296
+ isLoopActive,
60297
+ stopLoop,
60298
+ loop: loop2,
60299
+ quitProcess
60300
+ });
59864
60301
  return;
59865
60302
  }
59866
- if (key.escape && !busy && isLoopActive()) {
59867
- stopLoop();
60303
+ if (key.escape && (submittingRef.current || isLoopActive())) {
60304
+ handleTurnInterrupt("escape", {
60305
+ turnActiveRef: submittingRef,
60306
+ abortedThisTurn,
60307
+ resetPendingModals,
60308
+ isLoopActive,
60309
+ stopLoop,
60310
+ loop: loop2,
60311
+ quitProcess
60312
+ });
59868
60313
  return;
59869
60314
  }
59870
60315
  if (key.escape && !busy && (slashMatches || atState || slashArgContext)) {
@@ -59888,7 +60333,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59888
60333
  return;
59889
60334
  }
59890
60335
  if (codeMode && input.length === 0 && (chKey === "u" || chKey === "U") && !pendingShell && !pendingPath && !pendingPlan && !pendingReviseEditor && !pendingSessionsPicker && !pendingCheckpointPicker && !pendingMcpHub && !stagedInput && !pendingEditReview && !walkthroughActive && !pendingChoice && !stagedChoiceCustom && !pendingRevision && // Fire when EITHER the banner is up OR there's any non-undone
59891
- // history entry 闂?the keybind is useful long after the 5-second
60336
+ // history entry the keybind is useful long after the 5-second
59892
60337
  // banner expires, which users rightly want.
59893
60338
  (undoBanner || hasUndoable())) {
59894
60339
  const out = codeUndo([]);
@@ -59952,17 +60397,17 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
59952
60397
  }
59953
60398
  }
59954
60399
  });
59955
- (0, import_react89.useEffect)(() => {
60400
+ (0, import_react90.useEffect)(() => {
59956
60401
  if (!tools || !codeMode) return;
59957
60402
  tools.setToolInterceptor(async (name, args) => {
59958
60403
  if (name !== "edit_file" && name !== "write_file") return null;
59959
60404
  const rawPath = typeof args.path === "string" ? args.path : "";
59960
60405
  if (!rawPath) return null;
59961
60406
  const rootForEdit = currentRootDirRef.current;
59962
- const absRoot = resolve2(rootForEdit);
60407
+ const absRoot = resolve3(rootForEdit);
59963
60408
  let relPath;
59964
60409
  if (looksLikeAbsoluteSystemPath(rawPath)) {
59965
- const abs = resolve2(rawPath);
60410
+ const abs = resolve3(rawPath);
59966
60411
  if (!pathIsUnder(abs, absRoot)) return null;
59967
60412
  const rel = relative2(absRoot, abs);
59968
60413
  if (!rel) return null;
@@ -60034,7 +60479,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
60034
60479
  });
60035
60480
  const prefixHash = loop2.prefix.fingerprint;
60036
60481
  const writeTranscript = useTranscriptWriter(transcriptRef, model2, prefixHash);
60037
- const togglePlanMode = (0, import_react89.useCallback)(
60482
+ const togglePlanMode = (0, import_react90.useCallback)(
60038
60483
  (on) => {
60039
60484
  setPlanMode(on);
60040
60485
  tools?.setPlanMode(on);
@@ -60050,7 +60495,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
60050
60495
  clearFiringFlag,
60051
60496
  activeLoop
60052
60497
  } = useLoopMode({ log, busyRef, handleSubmitRef });
60053
- const startWalkthrough = (0, import_react89.useCallback)(() => {
60498
+ const startWalkthrough = (0, import_react90.useCallback)(() => {
60054
60499
  if (!codeMode) {
60055
60500
  return "/walk is only available inside `reasonix code`.";
60056
60501
  }
@@ -60060,11 +60505,11 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
60060
60505
  setWalkthroughActive(true);
60061
60506
  return `walking ${pendingEdits.current.length} edit block(s) - y apply - n reject - a apply rest - A flip to AUTO - Esc cancels (keeps remaining queued).`;
60062
60507
  }, [codeMode, pendingEdits]);
60063
- const startDashboard = (0, import_react89.useCallback)(async () => {
60508
+ const startDashboard = (0, import_react90.useCallback)(async () => {
60064
60509
  if (dashboardRef.current) return dashboardRef.current.url;
60065
60510
  if (dashboardStartingRef.current) return dashboardStartingRef.current;
60066
60511
  const startup = (async () => {
60067
- const { startDashboardServer } = await import("./server-TQ2IHYQJ.js");
60512
+ const { startDashboardServer } = await import("./server-5VFQP3PV.js");
60068
60513
  const handle = await startDashboardServer(
60069
60514
  {
60070
60515
  mode: "attached",
@@ -60140,7 +60585,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
60140
60585
  return { accepted: true };
60141
60586
  },
60142
60587
  abortTurn: () => {
60143
- if (busyRef.current) loop2.abort();
60588
+ if (submittingRef.current) loop2.abort();
60144
60589
  },
60145
60590
  isBusy: () => busyRef.current,
60146
60591
  getStats: () => {
@@ -60251,11 +60696,11 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
60251
60696
  handleStagedInputSubmitRef.current(text ?? "", { plan: plan2, mode: choice }).catch(() => void 0);
60252
60697
  },
60253
60698
  resolveEditReview: (choice) => {
60254
- const resolve3 = editReviewResolveRef.current;
60255
- if (resolve3) {
60699
+ const resolve4 = editReviewResolveRef.current;
60700
+ if (resolve4) {
60256
60701
  editReviewResolveRef.current = null;
60257
60702
  setPendingEditReview(null);
60258
- resolve3({ choice, denyContext: void 0 });
60703
+ resolve4({ choice, denyContext: void 0 });
60259
60704
  }
60260
60705
  },
60261
60706
  resolveCheckpointConfirm: (choice, text) => {
@@ -60328,7 +60773,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
60328
60773
  dashboardHost,
60329
60774
  dashboardToken
60330
60775
  ]);
60331
- const stopDashboard = (0, import_react89.useCallback)(async () => {
60776
+ const stopDashboard = (0, import_react90.useCallback)(async () => {
60332
60777
  const h = dashboardRef.current;
60333
60778
  if (!h) return;
60334
60779
  dashboardRef.current = null;
@@ -60339,10 +60784,10 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
60339
60784
  }
60340
60785
  log.pushInfo(t("app.dashboardStopped"));
60341
60786
  }, [log]);
60342
- const getDashboardUrl = (0, import_react89.useCallback)(() => {
60787
+ const getDashboardUrl = (0, import_react90.useCallback)(() => {
60343
60788
  return dashboardRef.current?.url ?? null;
60344
60789
  }, []);
60345
- (0, import_react89.useEffect)(() => {
60790
+ (0, import_react90.useEffect)(() => {
60346
60791
  if (noDashboard) return;
60347
60792
  if (dashboardRef.current) return;
60348
60793
  startDashboard().then((url) => {
@@ -60354,7 +60799,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
60354
60799
  log.pushInfo(t("ui.dashboardAutoStartFailed", { reason }));
60355
60800
  });
60356
60801
  }, [noDashboard, openDashboard, startDashboard, log]);
60357
- (0, import_react89.useEffect)(() => {
60802
+ (0, import_react90.useEffect)(() => {
60358
60803
  return () => {
60359
60804
  const h = dashboardRef.current;
60360
60805
  if (h) {
@@ -60363,7 +60808,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
60363
60808
  }
60364
60809
  };
60365
60810
  }, []);
60366
- const handleWalkChoice = (0, import_react89.useCallback)(
60811
+ const handleWalkChoice = (0, import_react90.useCallback)(
60367
60812
  (choice) => {
60368
60813
  if (choice === "apply") {
60369
60814
  log.pushInfo(codeApply([1]));
@@ -60385,20 +60830,20 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
60385
60830
  },
60386
60831
  [codeApply, codeDiscard, log, pendingEdits, setEditMode]
60387
60832
  );
60388
- const pendingGateIdRef = (0, import_react89.useRef)(null);
60389
- const handleShellConfirmRef = (0, import_react89.useRef)(() => void 0);
60390
- const handlePathConfirmRef = (0, import_react89.useRef)(() => void 0);
60391
- const handlePlanCancelRef = (0, import_react89.useRef)(() => void 0);
60392
- const handlePlanFeedbackRef = (0, import_react89.useRef)(() => void 0);
60393
- const handleCheckpointConfirmRef = (0, import_react89.useRef)(
60833
+ const pendingGateIdRef = (0, import_react90.useRef)(null);
60834
+ const handleShellConfirmRef = (0, import_react90.useRef)(() => void 0);
60835
+ const handlePathConfirmRef = (0, import_react90.useRef)(() => void 0);
60836
+ const handlePlanCancelRef = (0, import_react90.useRef)(() => void 0);
60837
+ const handlePlanFeedbackRef = (0, import_react90.useRef)(() => void 0);
60838
+ const handleCheckpointConfirmRef = (0, import_react90.useRef)(
60394
60839
  () => void 0
60395
60840
  );
60396
- const handleCheckpointReviseSubmitRef = (0, import_react89.useRef)(() => void 0);
60397
- const handleReviseConfirmRef = (0, import_react89.useRef)(
60841
+ const handleCheckpointReviseSubmitRef = (0, import_react90.useRef)(() => void 0);
60842
+ const handleReviseConfirmRef = (0, import_react90.useRef)(
60398
60843
  () => void 0
60399
60844
  );
60400
- const handleChoiceResolveRef = (0, import_react89.useRef)(() => void 0);
60401
- const handleQQModelPick = (0, import_react89.useCallback)(
60845
+ const handleChoiceResolveRef = (0, import_react90.useRef)(() => void 0);
60846
+ const handleQQModelPick = (0, import_react90.useCallback)(
60402
60847
  (target) => {
60403
60848
  if (target === "auto" || target === "flash" || target === "pro") {
60404
60849
  const preset3 = PRESETS[target];
@@ -60431,7 +60876,7 @@ run \`reasonix setup\` to remove this entry, or fix the underlying issue (missin
60431
60876
  },
60432
60877
  [agentStore, loop2, setPreset]
60433
60878
  );
60434
- const handleQQThemePick = (0, import_react89.useCallback)(
60879
+ const handleQQThemePick = (0, import_react90.useCallback)(
60435
60880
  (target) => {
60436
60881
  saveTheme(target);
60437
60882
  const active = resolveThemePreference(target, process.env.REASONIX_THEME);
@@ -60468,7 +60913,7 @@ active now: ${active}`;
60468
60913
  onPlanRevisionRef: handleReviseConfirmRef,
60469
60914
  onChoiceResolveRef: handleChoiceResolveRef
60470
60915
  });
60471
- const handleSubmit = (0, import_react89.useCallback)(
60916
+ const handleSubmit = (0, import_react90.useCallback)(
60472
60917
  async (raw) => {
60473
60918
  const incoming = qq.parseSubmit(raw);
60474
60919
  if (!incoming) return;
@@ -60682,37 +61127,7 @@ ${answer}`, "brand");
60682
61127
  return added;
60683
61128
  },
60684
61129
  reloadHooks: () => reloadHooks(codeMode ? currentRootDir : void 0),
60685
- switchCwd: codeMode?.reregisterTools ? (newPath) => {
60686
- const resolved = resolve2(newPath);
60687
- let stat;
60688
- try {
60689
- stat = statSync(resolved);
60690
- } catch (err) {
60691
- return { ok: false, info: `/cwd: ${err.message}` };
60692
- }
60693
- if (!stat.isDirectory()) {
60694
- return { ok: false, info: `/cwd: ${resolved} is not a directory` };
60695
- }
60696
- codeMode.reregisterTools?.(resolved);
60697
- setCurrentRootDir(resolved);
60698
- reloadHooks(resolved);
60699
- const reBootstrap = codeMode.reBootstrapSemantic;
60700
- if (reBootstrap) {
60701
- void reBootstrap(resolved).then(
60702
- (r) => {
60703
- log.pushInfo(
60704
- r.enabled ? `semantic_search re-pointed at ${resolved}` : `semantic_search disabled (no compatible index in ${resolved})`
60705
- );
60706
- },
60707
- (err) => {
60708
- log.pushInfo(
60709
- `semantic_search re-bootstrap failed: ${err.message}`
60710
- );
60711
- }
60712
- );
60713
- }
60714
- return { ok: true, info: `workspace switched to ${resolved}` };
60715
- } : void 0,
61130
+ switchCwd: codeMode?.reregisterTools ? switchWorkspaceRoot : void 0,
60716
61131
  reloadMcp: mcpRuntime ? async () => {
60717
61132
  const r = await mcpRuntime.reloadFromConfig(loop2);
60718
61133
  setLiveMcpServers(r.summaries);
@@ -60742,6 +61157,12 @@ ${answer}`, "brand");
60742
61157
  pushHistory(text);
60743
61158
  return;
60744
61159
  }
61160
+ if (result.openWorkspacePicker) {
61161
+ setWorkspacePickerList(listKnownWorkspaces(currentRootDir));
61162
+ setPendingWorkspacePicker(true);
61163
+ pushHistory(text);
61164
+ return;
61165
+ }
60745
61166
  if (result.openCheckpointPicker) {
60746
61167
  if (!codeMode) {
60747
61168
  log.pushInfo(t("app.restoreCodeOnly"));
@@ -60849,6 +61270,7 @@ ${answer}`, "brand");
60849
61270
  current: null
60850
61271
  };
60851
61272
  submittingRef.current = true;
61273
+ busyRef.current = true;
60852
61274
  setBusy(true);
60853
61275
  qq.noteTurnFromQQ(fromQQ);
60854
61276
  abortedThisTurn.current = false;
@@ -61073,6 +61495,7 @@ ${answer}`, "brand");
61073
61495
  }
61074
61496
  clearToolProgressDisplay();
61075
61497
  setSummary(loop2.stats.summary());
61498
+ busyRef.current = false;
61076
61499
  setBusy(false);
61077
61500
  submittingRef.current = false;
61078
61501
  qq.clearTurnReply();
@@ -61117,7 +61540,6 @@ ${answer}`, "brand");
61117
61540
  setEditMode,
61118
61541
  pendingEdits,
61119
61542
  syncPendingCount,
61120
- setCurrentRootDir,
61121
61543
  reloadHooks,
61122
61544
  setOngoingTool,
61123
61545
  setToolProgress,
@@ -61152,13 +61574,14 @@ ${answer}`, "brand");
61152
61574
  pushHistory,
61153
61575
  resetCursor,
61154
61576
  liveMcpServers,
61155
- generateCurrentSessionTitle
61577
+ generateCurrentSessionTitle,
61578
+ switchWorkspaceRoot
61156
61579
  ]
61157
61580
  );
61158
- (0, import_react89.useEffect)(() => {
61581
+ (0, import_react90.useEffect)(() => {
61159
61582
  handleSubmitRef.current = handleSubmit;
61160
61583
  }, [handleSubmit]);
61161
- const handleShellConfirm = (0, import_react89.useCallback)(
61584
+ const handleShellConfirm = (0, import_react90.useCallback)(
61162
61585
  (choice, denyContext) => {
61163
61586
  const pending = pendingShell;
61164
61587
  if (!pending || !codeMode) return;
@@ -61181,7 +61604,7 @@ ${answer}`, "brand");
61181
61604
  },
61182
61605
  [pendingShell, codeMode, currentRootDir, log]
61183
61606
  );
61184
- const handlePathConfirm = (0, import_react89.useCallback)(
61607
+ const handlePathConfirm = (0, import_react90.useCallback)(
61185
61608
  (choice, denyContext) => {
61186
61609
  const pending = pendingPath;
61187
61610
  if (!pending) return;
@@ -61197,7 +61620,7 @@ ${answer}`, "brand");
61197
61620
  },
61198
61621
  [pendingPath]
61199
61622
  );
61200
- const resetPendingModals = (0, import_react89.useCallback)(() => {
61623
+ const resetPendingModals = (0, import_react90.useCallback)(() => {
61201
61624
  const editResolve = editReviewResolveRef.current;
61202
61625
  if (editResolve) {
61203
61626
  editReviewResolveRef.current = null;
@@ -61217,7 +61640,7 @@ ${answer}`, "brand");
61217
61640
  qq.resetInteractions();
61218
61641
  pauseGate.cancelAll();
61219
61642
  }, [qq]);
61220
- (0, import_react89.useEffect)(() => {
61643
+ (0, import_react90.useEffect)(() => {
61221
61644
  if (queuedSubmit === null) return;
61222
61645
  const canBypassBusy = qq.canBypassBusy(queuedSubmit);
61223
61646
  if (!busy && !submittingRef.current || canBypassBusy) {
@@ -61226,7 +61649,7 @@ ${answer}`, "brand");
61226
61649
  void handleSubmit(text);
61227
61650
  }
61228
61651
  }, [busy, queuedSubmit, handleSubmit, qq]);
61229
- const handlePlanConfirm = (0, import_react89.useCallback)(
61652
+ const handlePlanConfirm = (0, import_react90.useCallback)(
61230
61653
  async (choice) => {
61231
61654
  const hadPendingPlan = pendingPlan !== null;
61232
61655
  if (!hadPendingPlan && choice !== "approve") {
@@ -61257,18 +61680,18 @@ ${answer}`, "brand");
61257
61680
  },
61258
61681
  [pendingPlan]
61259
61682
  );
61260
- const handlePlanConfirmRef = (0, import_react89.useRef)(handlePlanConfirm);
61261
- (0, import_react89.useEffect)(() => {
61683
+ const handlePlanConfirmRef = (0, import_react90.useRef)(handlePlanConfirm);
61684
+ (0, import_react90.useEffect)(() => {
61262
61685
  handlePlanConfirmRef.current = handlePlanConfirm;
61263
61686
  }, [handlePlanConfirm]);
61264
- (0, import_react89.useEffect)(() => {
61687
+ (0, import_react90.useEffect)(() => {
61265
61688
  handlePlanCancelRef.current = () => handlePlanConfirmRef.current("cancel");
61266
61689
  }, []);
61267
- const stableHandlePlanConfirm = (0, import_react89.useCallback)(
61690
+ const stableHandlePlanConfirm = (0, import_react90.useCallback)(
61268
61691
  async (choice) => handlePlanConfirmRef.current(choice),
61269
61692
  []
61270
61693
  );
61271
- const handleStagedInputSubmit = (0, import_react89.useCallback)(
61694
+ const handleStagedInputSubmit = (0, import_react90.useCallback)(
61272
61695
  async (feedback2, override) => {
61273
61696
  const staged = override ?? stagedInput;
61274
61697
  if (override) {
@@ -61324,18 +61747,18 @@ ${answer}`, "brand");
61324
61747
  },
61325
61748
  [stagedInput, togglePlanMode, persistPlanState, agentStore, log]
61326
61749
  );
61327
- const handleStagedInputSubmitRef = (0, import_react89.useRef)(handleStagedInputSubmit);
61328
- (0, import_react89.useEffect)(() => {
61750
+ const handleStagedInputSubmitRef = (0, import_react90.useRef)(handleStagedInputSubmit);
61751
+ (0, import_react90.useEffect)(() => {
61329
61752
  handleStagedInputSubmitRef.current = handleStagedInputSubmit;
61330
61753
  }, [handleStagedInputSubmit]);
61331
- (0, import_react89.useEffect)(() => {
61754
+ (0, import_react90.useEffect)(() => {
61332
61755
  handlePlanFeedbackRef.current = (feedback2, override) => handleStagedInputSubmitRef.current(feedback2, override);
61333
61756
  }, []);
61334
- const handleStagedInputCancel = (0, import_react89.useCallback)(() => {
61757
+ const handleStagedInputCancel = (0, import_react90.useCallback)(() => {
61335
61758
  if (stagedInput?.plan) setPendingPlan(stagedInput.plan);
61336
61759
  setStagedInput(null);
61337
61760
  }, [stagedInput]);
61338
- const handleChoiceConfirm = (0, import_react89.useCallback)(
61761
+ const handleChoiceConfirm = (0, import_react90.useCallback)(
61339
61762
  async (choice) => {
61340
61763
  const snap = pendingChoice;
61341
61764
  if (!snap) return;
@@ -61356,13 +61779,13 @@ ${answer}`, "brand");
61356
61779
  },
61357
61780
  [pendingChoice]
61358
61781
  );
61359
- (0, import_react89.useEffect)(() => {
61782
+ (0, import_react90.useEffect)(() => {
61360
61783
  handleShellConfirmRef.current = handleShellConfirm;
61361
61784
  }, [handleShellConfirm]);
61362
- (0, import_react89.useEffect)(() => {
61785
+ (0, import_react90.useEffect)(() => {
61363
61786
  handlePathConfirmRef.current = handlePathConfirm;
61364
61787
  }, [handlePathConfirm]);
61365
- (0, import_react89.useEffect)(() => {
61788
+ (0, import_react90.useEffect)(() => {
61366
61789
  return pauseGate.on((request) => {
61367
61790
  const payload = request.payload;
61368
61791
  pendingGateIdRef.current = request.id;
@@ -61445,23 +61868,23 @@ ${answer}`, "brand");
61445
61868
  }
61446
61869
  });
61447
61870
  }, [log, qq]);
61448
- const pendingPlanRef = (0, import_react89.useRef)(null);
61449
- (0, import_react89.useEffect)(() => {
61871
+ const pendingPlanRef = (0, import_react90.useRef)(null);
61872
+ (0, import_react90.useEffect)(() => {
61450
61873
  pendingPlanRef.current = pendingPlan;
61451
61874
  }, [pendingPlan]);
61452
- const pendingCheckpointRef = (0, import_react89.useRef)(null);
61453
- (0, import_react89.useEffect)(() => {
61875
+ const pendingCheckpointRef = (0, import_react90.useRef)(null);
61876
+ (0, import_react90.useEffect)(() => {
61454
61877
  pendingCheckpointRef.current = pendingCheckpoint;
61455
61878
  }, [pendingCheckpoint]);
61456
- const handleChoiceConfirmRef = (0, import_react89.useRef)(handleChoiceConfirm);
61457
- (0, import_react89.useEffect)(() => {
61879
+ const handleChoiceConfirmRef = (0, import_react90.useRef)(handleChoiceConfirm);
61880
+ (0, import_react90.useEffect)(() => {
61458
61881
  handleChoiceConfirmRef.current = handleChoiceConfirm;
61459
61882
  }, [handleChoiceConfirm]);
61460
- const stableHandleChoiceConfirm = (0, import_react89.useCallback)(
61883
+ const stableHandleChoiceConfirm = (0, import_react90.useCallback)(
61461
61884
  async (choice) => handleChoiceConfirmRef.current(choice),
61462
61885
  []
61463
61886
  );
61464
- const handleCheckpointConfirm = (0, import_react89.useCallback)(
61887
+ const handleCheckpointConfirm = (0, import_react90.useCallback)(
61465
61888
  (choice) => {
61466
61889
  const snap = pendingCheckpoint;
61467
61890
  if (!snap) return;
@@ -61506,10 +61929,10 @@ ${answer}`, "brand");
61506
61929
  },
61507
61930
  [pendingCheckpoint, codeMode, touchedPaths, log]
61508
61931
  );
61509
- (0, import_react89.useEffect)(() => {
61932
+ (0, import_react90.useEffect)(() => {
61510
61933
  handleCheckpointConfirmRef.current = handleCheckpointConfirm;
61511
61934
  }, [handleCheckpointConfirm]);
61512
- const handleAutoCheckpointContinue = (0, import_react89.useCallback)(
61935
+ const handleAutoCheckpointContinue = (0, import_react90.useCallback)(
61513
61936
  (stepId, title2) => {
61514
61937
  if (codeMode) {
61515
61938
  const paths = touchedPaths();
@@ -61534,15 +61957,15 @@ ${answer}`, "brand");
61534
61957
  },
61535
61958
  [codeMode, touchedPaths, log]
61536
61959
  );
61537
- const handleAutoCheckpointContinueRef = (0, import_react89.useRef)(handleAutoCheckpointContinue);
61538
- (0, import_react89.useEffect)(() => {
61960
+ const handleAutoCheckpointContinueRef = (0, import_react90.useRef)(handleAutoCheckpointContinue);
61961
+ (0, import_react90.useEffect)(() => {
61539
61962
  handleAutoCheckpointContinueRef.current = handleAutoCheckpointContinue;
61540
61963
  }, [handleAutoCheckpointContinue]);
61541
- const stableHandleCheckpointConfirm = (0, import_react89.useCallback)(
61964
+ const stableHandleCheckpointConfirm = (0, import_react90.useCallback)(
61542
61965
  (choice) => handleCheckpointConfirmRef.current(choice),
61543
61966
  []
61544
61967
  );
61545
- const handleCheckpointReviseSubmit = (0, import_react89.useCallback)(
61968
+ const handleCheckpointReviseSubmit = (0, import_react90.useCallback)(
61546
61969
  (feedback2, snapOverride) => {
61547
61970
  const snap = snapOverride;
61548
61971
  setStagedCheckpointRevise(null);
@@ -61564,15 +61987,15 @@ ${answer}`, "brand");
61564
61987
  },
61565
61988
  [log]
61566
61989
  );
61567
- const handleCheckpointReviseCancel = (0, import_react89.useCallback)(() => {
61990
+ const handleCheckpointReviseCancel = (0, import_react90.useCallback)(() => {
61568
61991
  const snap = stagedCheckpointRevise;
61569
61992
  setStagedCheckpointRevise(null);
61570
61993
  if (snap) setPendingCheckpoint(snap);
61571
61994
  }, [stagedCheckpointRevise]);
61572
- (0, import_react89.useEffect)(() => {
61995
+ (0, import_react90.useEffect)(() => {
61573
61996
  handleCheckpointReviseSubmitRef.current = handleCheckpointReviseSubmit;
61574
61997
  }, [handleCheckpointReviseSubmit]);
61575
- const handleChoiceCustomSubmit = (0, import_react89.useCallback)((answer) => {
61998
+ const handleChoiceCustomSubmit = (0, import_react90.useCallback)((answer) => {
61576
61999
  setStagedChoiceCustom(null);
61577
62000
  const trimmed = answer.trim();
61578
62001
  const gateId = pendingGateIdRef.current;
@@ -61580,12 +62003,12 @@ ${answer}`, "brand");
61580
62003
  pauseGate.resolve(gateId, { type: "text", text: trimmed || "" });
61581
62004
  }
61582
62005
  }, []);
61583
- const handleChoiceCustomCancel = (0, import_react89.useCallback)(() => {
62006
+ const handleChoiceCustomCancel = (0, import_react90.useCallback)(() => {
61584
62007
  const snap = stagedChoiceCustom;
61585
62008
  setStagedChoiceCustom(null);
61586
62009
  if (snap) setPendingChoice(snap);
61587
62010
  }, [stagedChoiceCustom]);
61588
- (0, import_react89.useEffect)(() => {
62011
+ (0, import_react90.useEffect)(() => {
61589
62012
  handleChoiceResolveRef.current = (resolution) => {
61590
62013
  if (resolution.type === "pick") {
61591
62014
  void handleChoiceConfirmRef.current({ kind: "pick", optionId: resolution.optionId });
@@ -61599,7 +62022,7 @@ ${answer}`, "brand");
61599
62022
  void handleChoiceConfirmRef.current({ kind: "cancel" });
61600
62023
  };
61601
62024
  }, [handleChoiceCustomSubmit]);
61602
- const handleReviseConfirm = (0, import_react89.useCallback)(
62025
+ const handleReviseConfirm = (0, import_react90.useCallback)(
61603
62026
  (choice) => {
61604
62027
  const snap = pendingRevision;
61605
62028
  if (!snap) return;
@@ -61633,7 +62056,7 @@ ${answer}`, "brand");
61633
62056
  },
61634
62057
  [pendingRevision, persistPlanState, agentStore, log]
61635
62058
  );
61636
- (0, import_react89.useEffect)(() => {
62059
+ (0, import_react90.useEffect)(() => {
61637
62060
  handleReviseConfirmRef.current = (choice) => {
61638
62061
  if (choice === "cancel") {
61639
62062
  const gateId = pendingGateIdRef.current;
@@ -61644,13 +62067,13 @@ ${answer}`, "brand");
61644
62067
  return handleReviseConfirm(choice);
61645
62068
  };
61646
62069
  }, [handleReviseConfirm]);
61647
- const stableHandleReviseConfirm = (0, import_react89.useCallback)(
62070
+ const stableHandleReviseConfirm = (0, import_react90.useCallback)(
61648
62071
  async (choice) => handleReviseConfirmRef.current(choice),
61649
62072
  []
61650
62073
  );
61651
62074
  const tickerSuspended = modalOpen || !busy && !isStreaming;
61652
- if (!bootReady) return /* @__PURE__ */ import_react89.default.createElement(BootSplash, null);
61653
- return /* @__PURE__ */ import_react89.default.createElement(import_react89.default.Fragment, null, /* @__PURE__ */ import_react89.default.createElement(
62075
+ if (!bootReady) return /* @__PURE__ */ import_react90.default.createElement(BootSplash, null);
62076
+ return /* @__PURE__ */ import_react90.default.createElement(import_react90.default.Fragment, null, /* @__PURE__ */ import_react90.default.createElement(
61654
62077
  HistoryTypingCapture,
61655
62078
  {
61656
62079
  input,
@@ -61658,7 +62081,7 @@ ${answer}`, "brand");
61658
62081
  enabled: !modalOpen && !busy,
61659
62082
  onReturnToBottom: chatScroll.jumpToBottom
61660
62083
  }
61661
- ), /* @__PURE__ */ import_react89.default.createElement(TickerProvider, { disabled: tickerSuspended }, /* @__PURE__ */ import_react89.default.createElement(ViewportBudgetProvider, null, /* @__PURE__ */ import_react89.default.createElement(InflightProvider, { inflight: loop2.inflight }, /* @__PURE__ */ import_react89.default.createElement(Box_default, { flexDirection: "row", height: stdout?.rows ?? 24 }, /* @__PURE__ */ import_react89.default.createElement(Box_default, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ import_react89.default.createElement(Box_default, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ import_react89.default.createElement(LiveExpandContext.Provider, { value: liveExpand }, /* @__PURE__ */ import_react89.default.createElement(CardStream, { suppressLive: modalOpen })), !hasConversation && !busy && !isStreaming && slashMatches === null ? /* @__PURE__ */ import_react89.default.createElement(
62084
+ ), /* @__PURE__ */ import_react90.default.createElement(TickerProvider, { disabled: tickerSuspended }, /* @__PURE__ */ import_react90.default.createElement(ViewportBudgetProvider, null, /* @__PURE__ */ import_react90.default.createElement(InflightProvider, { inflight: loop2.inflight }, /* @__PURE__ */ import_react90.default.createElement(Box_default, { flexDirection: "row", height: stdout?.rows ?? 24 }, /* @__PURE__ */ import_react90.default.createElement(Box_default, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ import_react90.default.createElement(Box_default, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ import_react90.default.createElement(LiveExpandContext.Provider, { value: liveExpand }, /* @__PURE__ */ import_react90.default.createElement(CardStream, { suppressLive: modalOpen })), !hasConversation && !busy && !isStreaming && slashMatches === null ? /* @__PURE__ */ import_react90.default.createElement(
61662
62085
  WelcomeBanner,
61663
62086
  {
61664
62087
  inCodeMode: !!codeMode,
@@ -61666,7 +62089,7 @@ ${answer}`, "brand");
61666
62089
  dashboardUrl,
61667
62090
  languageVersion
61668
62091
  }
61669
- ) : null, /* @__PURE__ */ import_react89.default.createElement(
62092
+ ) : null, /* @__PURE__ */ import_react90.default.createElement(
61670
62093
  LiveActivityArea,
61671
62094
  {
61672
62095
  noTakeoverOverlay,
@@ -61680,7 +62103,7 @@ ${answer}`, "brand");
61680
62103
  undoBanner,
61681
62104
  hideUndo: !!(pendingShell || pendingPlan || pendingReviseEditor || pendingSessionsPicker || pendingCheckpointPicker || pendingMcpHub || stagedInput || pendingEditReview || pendingChoice || stagedChoiceCustom || pendingRevision || stagedCheckpointRevise || pendingCheckpoint)
61682
62105
  }
61683
- )), stagedInput ? /* @__PURE__ */ import_react89.default.createElement(
62106
+ )), stagedInput ? /* @__PURE__ */ import_react90.default.createElement(
61684
62107
  PlanRefineInput,
61685
62108
  {
61686
62109
  mode: stagedInput.mode,
@@ -61688,21 +62111,21 @@ ${answer}`, "brand");
61688
62111
  onSubmit: handleStagedInputSubmit,
61689
62112
  onCancel: handleStagedInputCancel
61690
62113
  }
61691
- ) : stagedChoiceCustom ? /* @__PURE__ */ import_react89.default.createElement(
62114
+ ) : stagedChoiceCustom ? /* @__PURE__ */ import_react90.default.createElement(
61692
62115
  PlanRefineInput,
61693
62116
  {
61694
62117
  mode: "choice-custom",
61695
62118
  onSubmit: handleChoiceCustomSubmit,
61696
62119
  onCancel: handleChoiceCustomCancel
61697
62120
  }
61698
- ) : stagedCheckpointRevise ? /* @__PURE__ */ import_react89.default.createElement(
62121
+ ) : stagedCheckpointRevise ? /* @__PURE__ */ import_react90.default.createElement(
61699
62122
  PlanRefineInput,
61700
62123
  {
61701
62124
  mode: "checkpoint-revise",
61702
62125
  onSubmit: (text) => handleCheckpointReviseSubmit(text, stagedCheckpointRevise),
61703
62126
  onCancel: handleCheckpointReviseCancel
61704
62127
  }
61705
- ) : pendingChoice ? /* @__PURE__ */ import_react89.default.createElement(
62128
+ ) : pendingChoice ? /* @__PURE__ */ import_react90.default.createElement(
61706
62129
  ChoiceConfirm,
61707
62130
  {
61708
62131
  question: pendingChoice.question,
@@ -61710,7 +62133,7 @@ ${answer}`, "brand");
61710
62133
  allowCustom: pendingChoice.allowCustom,
61711
62134
  onChoose: stableHandleChoiceConfirm
61712
62135
  }
61713
- ) : pendingRevision ? /* @__PURE__ */ import_react89.default.createElement(
62136
+ ) : pendingRevision ? /* @__PURE__ */ import_react90.default.createElement(
61714
62137
  PlanReviseConfirm,
61715
62138
  {
61716
62139
  reason: pendingRevision.reason,
@@ -61721,7 +62144,7 @@ ${answer}`, "brand");
61721
62144
  summary: pendingRevision.summary,
61722
62145
  onChoose: stableHandleReviseConfirm
61723
62146
  }
61724
- ) : pendingCheckpoint ? /* @__PURE__ */ import_react89.default.createElement(
62147
+ ) : pendingCheckpoint ? /* @__PURE__ */ import_react90.default.createElement(
61725
62148
  PlanCheckpointConfirm,
61726
62149
  {
61727
62150
  stepId: pendingCheckpoint.stepId,
@@ -61732,7 +62155,7 @@ ${answer}`, "brand");
61732
62155
  completedStepIds: completedStepIdsRef.current,
61733
62156
  onChoose: stableHandleCheckpointConfirm
61734
62157
  }
61735
- ) : pendingCheckpointPicker ? /* @__PURE__ */ import_react89.default.createElement(
62158
+ ) : pendingCheckpointPicker ? /* @__PURE__ */ import_react90.default.createElement(
61736
62159
  CheckpointPicker,
61737
62160
  {
61738
62161
  checkpoints: checkpointPickerList,
@@ -61777,7 +62200,22 @@ ${answer}`, "brand");
61777
62200
  }
61778
62201
  }
61779
62202
  }
61780
- ) : pendingSessionsPicker ? /* @__PURE__ */ import_react89.default.createElement(
62203
+ ) : pendingWorkspacePicker ? /* @__PURE__ */ import_react90.default.createElement(
62204
+ WorkspacePicker,
62205
+ {
62206
+ workspaces: workspacePickerList,
62207
+ currentWorkspace: currentRootDir,
62208
+ onChoose: (outcome) => {
62209
+ setPendingWorkspacePicker(false);
62210
+ if (outcome.kind === "quit") return;
62211
+ const result = switchWorkspaceRoot(outcome.path);
62212
+ log.pushInfo(result.info);
62213
+ if (!result.ok) return;
62214
+ setSessionsPickerList(listSessionsForWorkspace(outcome.path));
62215
+ setPendingSessionsPicker(true);
62216
+ }
62217
+ }
62218
+ ) : pendingSessionsPicker ? /* @__PURE__ */ import_react90.default.createElement(
61781
62219
  SessionPicker,
61782
62220
  {
61783
62221
  sessions: sessionsPickerList,
@@ -61823,7 +62261,7 @@ ${answer}`, "brand");
61823
62261
  }
61824
62262
  }
61825
62263
  }
61826
- ) : pendingThemePicker ? /* @__PURE__ */ import_react89.default.createElement(
62264
+ ) : pendingThemePicker ? /* @__PURE__ */ import_react90.default.createElement(
61827
62265
  ThemePicker,
61828
62266
  {
61829
62267
  currentPreference: loadTheme() ?? "auto",
@@ -61841,7 +62279,7 @@ ${answer}`, "brand");
61841
62279
  active now: ${active}`);
61842
62280
  }
61843
62281
  }
61844
- ) : pendingCopyMode ? /* @__PURE__ */ import_react89.default.createElement(
62282
+ ) : pendingCopyMode ? /* @__PURE__ */ import_react90.default.createElement(
61845
62283
  CopyMode,
61846
62284
  {
61847
62285
  cards: agentStore.getState().cards,
@@ -61857,7 +62295,7 @@ ${answer}`, "brand");
61857
62295
  }
61858
62296
  }
61859
62297
  }
61860
- ) : pendingModelPicker ? /* @__PURE__ */ import_react89.default.createElement(
62298
+ ) : pendingModelPicker ? /* @__PURE__ */ import_react90.default.createElement(
61861
62299
  ModelPicker,
61862
62300
  {
61863
62301
  models,
@@ -61906,7 +62344,7 @@ ${answer}`, "brand");
61906
62344
  }
61907
62345
  }
61908
62346
  }
61909
- ) : pendingMcpHub ? /* @__PURE__ */ import_react89.default.createElement(
62347
+ ) : pendingMcpHub ? /* @__PURE__ */ import_react90.default.createElement(
61910
62348
  McpHub,
61911
62349
  {
61912
62350
  initialTab: pendingMcpHub.tab,
@@ -61926,7 +62364,7 @@ ${answer}`, "brand");
61926
62364
  return r;
61927
62365
  } : void 0
61928
62366
  }
61929
- ) : pendingPlan ? /* @__PURE__ */ import_react89.default.createElement(
62367
+ ) : pendingPlan ? /* @__PURE__ */ import_react90.default.createElement(
61930
62368
  PlanConfirm,
61931
62369
  {
61932
62370
  plan: pendingPlan,
@@ -61935,7 +62373,7 @@ ${answer}`, "brand");
61935
62373
  onChoose: stableHandlePlanConfirm,
61936
62374
  projectRoot: currentRootDir
61937
62375
  }
61938
- ) : pendingReviseEditor ? /* @__PURE__ */ import_react89.default.createElement(
62376
+ ) : pendingReviseEditor ? /* @__PURE__ */ import_react90.default.createElement(
61939
62377
  PlanReviseEditor,
61940
62378
  {
61941
62379
  steps: planStepsRef.current ?? [],
@@ -61954,7 +62392,7 @@ ${answer}`, "brand");
61954
62392
  setPendingPlan(planText);
61955
62393
  }
61956
62394
  }
61957
- ) : pendingShell ? /* @__PURE__ */ import_react89.default.createElement(
62395
+ ) : pendingShell ? /* @__PURE__ */ import_react90.default.createElement(
61958
62396
  ShellConfirm,
61959
62397
  {
61960
62398
  command: pendingShell.command,
@@ -61965,7 +62403,7 @@ ${answer}`, "brand");
61965
62403
  waitSec: pendingShell.waitSec,
61966
62404
  onChoose: handleShellConfirm
61967
62405
  }
61968
- ) : pendingPath ? /* @__PURE__ */ import_react89.default.createElement(
62406
+ ) : pendingPath ? /* @__PURE__ */ import_react90.default.createElement(
61969
62407
  PathConfirm,
61970
62408
  {
61971
62409
  path: pendingPath.path,
@@ -61975,26 +62413,26 @@ ${answer}`, "brand");
61975
62413
  allowPrefix: pendingPath.allowPrefix,
61976
62414
  onChoose: handlePathConfirm
61977
62415
  }
61978
- ) : pendingEditReview ? /* @__PURE__ */ import_react89.default.createElement(
62416
+ ) : pendingEditReview ? /* @__PURE__ */ import_react90.default.createElement(
61979
62417
  EditConfirm,
61980
62418
  {
61981
62419
  block: pendingEditReview,
61982
62420
  onChoose: (choice, denyContext) => {
61983
- const resolve3 = editReviewResolveRef.current;
61984
- if (resolve3) {
62421
+ const resolve4 = editReviewResolveRef.current;
62422
+ if (resolve4) {
61985
62423
  editReviewResolveRef.current = null;
61986
- resolve3({ choice, denyContext });
62424
+ resolve4({ choice, denyContext });
61987
62425
  }
61988
62426
  }
61989
62427
  }
61990
- ) : walkthroughActive && pendingEdits.current.length > 0 ? /* @__PURE__ */ import_react89.default.createElement(
62428
+ ) : walkthroughActive && pendingEdits.current.length > 0 ? /* @__PURE__ */ import_react90.default.createElement(
61991
62429
  EditConfirm,
61992
62430
  {
61993
62431
  key: `walk-${pendingTick}`,
61994
62432
  block: pendingEdits.current[0],
61995
62433
  onChoose: handleWalkChoice
61996
62434
  }
61997
- ) : /* @__PURE__ */ import_react89.default.createElement(
62435
+ ) : /* @__PURE__ */ import_react90.default.createElement(
61998
62436
  ComposerArea,
61999
62437
  {
62000
62438
  editMode,
@@ -62027,10 +62465,10 @@ ${answer}`, "brand");
62027
62465
  }
62028
62466
 
62029
62467
  // src/cli/ui/Setup.tsx
62030
- var import_react91 = __toESM(require_react(), 1);
62468
+ var import_react92 = __toESM(require_react(), 1);
62031
62469
 
62032
62470
  // src/cli/ui/MaskedInput.tsx
62033
- var import_react90 = __toESM(require_react(), 1);
62471
+ var import_react91 = __toESM(require_react(), 1);
62034
62472
  function stripPasteMarkers(s) {
62035
62473
  return s.replace(/\u001b?\[20[01]~/g, "").replace(/\u001b/g, "");
62036
62474
  }
@@ -62041,7 +62479,7 @@ function MaskedInput({
62041
62479
  mask = "\u2022",
62042
62480
  placeholder = ""
62043
62481
  }) {
62044
- const valueRef = (0, import_react90.useRef)(value);
62482
+ const valueRef = (0, import_react91.useRef)(value);
62045
62483
  valueRef.current = value;
62046
62484
  useKeystroke((ev) => {
62047
62485
  if (ev.return) {
@@ -62065,17 +62503,17 @@ function MaskedInput({
62065
62503
  });
62066
62504
  if (value.length === 0) {
62067
62505
  if (placeholder.length === 0) {
62068
- return /* @__PURE__ */ import_react90.default.createElement(Text, { inverse: true }, " ");
62506
+ return /* @__PURE__ */ import_react91.default.createElement(Text, { inverse: true }, " ");
62069
62507
  }
62070
- return /* @__PURE__ */ import_react90.default.createElement(import_react90.default.Fragment, null, /* @__PURE__ */ import_react90.default.createElement(Text, { inverse: true }, placeholder[0]), /* @__PURE__ */ import_react90.default.createElement(Text, { color: FG.faint }, placeholder.slice(1)));
62508
+ return /* @__PURE__ */ import_react91.default.createElement(import_react91.default.Fragment, null, /* @__PURE__ */ import_react91.default.createElement(Text, { inverse: true }, placeholder[0]), /* @__PURE__ */ import_react91.default.createElement(Text, { color: FG.faint }, placeholder.slice(1)));
62071
62509
  }
62072
- return /* @__PURE__ */ import_react90.default.createElement(import_react90.default.Fragment, null, /* @__PURE__ */ import_react90.default.createElement(Text, null, mask.repeat(value.length)), /* @__PURE__ */ import_react90.default.createElement(Text, { inverse: true }, " "));
62510
+ return /* @__PURE__ */ import_react91.default.createElement(import_react91.default.Fragment, null, /* @__PURE__ */ import_react91.default.createElement(Text, null, mask.repeat(value.length)), /* @__PURE__ */ import_react91.default.createElement(Text, { inverse: true }, " "));
62073
62511
  }
62074
62512
 
62075
62513
  // src/cli/ui/Setup.tsx
62076
62514
  function Setup({ onReady }) {
62077
- const [value, setValue] = (0, import_react91.useState)("");
62078
- const [error, setError] = (0, import_react91.useState)(null);
62515
+ const [value, setValue] = (0, import_react92.useState)("");
62516
+ const [error, setError] = (0, import_react92.useState)(null);
62079
62517
  const { exit: exit2 } = use_app_default();
62080
62518
  const handleSubmit = (raw) => {
62081
62519
  const trimmed = raw.trim();
@@ -62096,7 +62534,7 @@ function Setup({ onReady }) {
62096
62534
  }
62097
62535
  onReady(trimmed);
62098
62536
  };
62099
- return /* @__PURE__ */ import_react91.default.createElement(Box_default, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ import_react91.default.createElement(Box_default, null, /* @__PURE__ */ import_react91.default.createElement(Text, { bold: true, color: GRADIENT[0] }, GLYPH.brand), /* @__PURE__ */ import_react91.default.createElement(Text, null, " "), /* @__PURE__ */ import_react91.default.createElement(Text, { bold: true }, t("wizard.welcomeTitle"))), /* @__PURE__ */ import_react91.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react91.default.createElement(Text, { color: COLOR.info }, t("wizard.apiKeyPrompt"))), /* @__PURE__ */ import_react91.default.createElement(Box_default, null, /* @__PURE__ */ import_react91.default.createElement(Text, { dimColor: true }, ` ${t("wizard.apiKeyGetOne")}`)), /* @__PURE__ */ import_react91.default.createElement(Box_default, null, /* @__PURE__ */ import_react91.default.createElement(Text, { dimColor: true }, t("wizard.apiKeySavedLocally", { path: defaultConfigPath() }))), /* @__PURE__ */ import_react91.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react91.default.createElement(Text, { bold: true, color: COLOR.brand }, GLYPH.bar), /* @__PURE__ */ import_react91.default.createElement(Text, { bold: true, color: COLOR.primary }, " \u203A "), /* @__PURE__ */ import_react91.default.createElement(
62537
+ return /* @__PURE__ */ import_react92.default.createElement(Box_default, { flexDirection: "column", paddingX: 1, marginY: 1 }, /* @__PURE__ */ import_react92.default.createElement(Box_default, null, /* @__PURE__ */ import_react92.default.createElement(Text, { bold: true, color: GRADIENT[0] }, GLYPH.brand), /* @__PURE__ */ import_react92.default.createElement(Text, null, " "), /* @__PURE__ */ import_react92.default.createElement(Text, { bold: true }, t("wizard.welcomeTitle"))), /* @__PURE__ */ import_react92.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react92.default.createElement(Text, { color: COLOR.info }, t("wizard.apiKeyPrompt"))), /* @__PURE__ */ import_react92.default.createElement(Box_default, null, /* @__PURE__ */ import_react92.default.createElement(Text, { dimColor: true }, ` ${t("wizard.apiKeyGetOne")}`)), /* @__PURE__ */ import_react92.default.createElement(Box_default, null, /* @__PURE__ */ import_react92.default.createElement(Text, { dimColor: true }, t("wizard.apiKeySavedLocally", { path: defaultConfigPath() }))), /* @__PURE__ */ import_react92.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react92.default.createElement(Text, { bold: true, color: COLOR.brand }, GLYPH.bar), /* @__PURE__ */ import_react92.default.createElement(Text, { bold: true, color: COLOR.primary }, " \u203A "), /* @__PURE__ */ import_react92.default.createElement(
62100
62538
  MaskedInput,
62101
62539
  {
62102
62540
  value,
@@ -62105,7 +62543,7 @@ function Setup({ onReady }) {
62105
62543
  mask: "\u2022",
62106
62544
  placeholder: t("wizard.apiKeyPlaceholder")
62107
62545
  }
62108
- )), error ? /* @__PURE__ */ import_react91.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react91.default.createElement(Text, { color: COLOR.err, bold: true }, GLYPH.err), /* @__PURE__ */ import_react91.default.createElement(Text, { color: COLOR.err }, ` ${error}`)) : value ? /* @__PURE__ */ import_react91.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react91.default.createElement(Text, { dimColor: true }, t("wizard.apiKeyPreview", { redacted: redactKey(value) }))) : null, /* @__PURE__ */ import_react91.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react91.default.createElement(Text, { dimColor: true }, t("wizard.exitHint"))));
62546
+ )), error ? /* @__PURE__ */ import_react92.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react92.default.createElement(Text, { color: COLOR.err, bold: true }, GLYPH.err), /* @__PURE__ */ import_react92.default.createElement(Text, { color: COLOR.err }, ` ${error}`)) : value ? /* @__PURE__ */ import_react92.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react92.default.createElement(Text, { dimColor: true }, t("wizard.apiKeyPreview", { redacted: redactKey(value) }))) : null, /* @__PURE__ */ import_react92.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react92.default.createElement(Text, { dimColor: true }, t("wizard.exitHint"))));
62109
62547
  }
62110
62548
 
62111
62549
  // src/cli/ui/drain-tty.ts
@@ -62123,7 +62561,7 @@ async function drainTtyResponses(timeoutMs = 50) {
62123
62561
  return;
62124
62562
  }
62125
62563
  stdin.resume();
62126
- await new Promise((resolve3) => {
62564
+ await new Promise((resolve4) => {
62127
62565
  const onData = (_chunk) => {
62128
62566
  };
62129
62567
  stdin.on("data", onData);
@@ -62136,7 +62574,7 @@ async function drainTtyResponses(timeoutMs = 50) {
62136
62574
  } catch {
62137
62575
  }
62138
62576
  }
62139
- resolve3();
62577
+ resolve4();
62140
62578
  }, timeoutMs);
62141
62579
  timer.unref();
62142
62580
  });
@@ -62154,13 +62592,28 @@ function Root({
62154
62592
  startupInfoHints,
62155
62593
  ...appProps
62156
62594
  }) {
62157
- const [key, setKey] = (0, import_react92.useState)(initialKey);
62158
- const [pickerOpen, setPickerOpen] = (0, import_react92.useState)(showPicker);
62159
- const [activeSession, setActiveSession] = (0, import_react92.useState)(appProps.session);
62160
- const workspaceRoot = appProps.codeMode?.rootDir ?? process.cwd();
62161
- const [sessions2, setSessions] = (0, import_react92.useState)(() => listSessionsForWorkspace(workspaceRoot));
62595
+ const [key, setKey] = (0, import_react93.useState)(initialKey);
62596
+ const [pickerOpen, setPickerOpen] = (0, import_react93.useState)(showPicker);
62597
+ const [activeSession, setActiveSession] = (0, import_react93.useState)(appProps.session);
62598
+ const [activeRoot, setActiveRoot] = (0, import_react93.useState)(
62599
+ () => appProps.codeMode?.rootDir ?? process.cwd()
62600
+ );
62601
+ const workspaceRoot = activeRoot;
62602
+ const [sessions2, setSessions] = (0, import_react93.useState)(() => listSessionsForWorkspace(workspaceRoot));
62603
+ const codeMode = (0, import_react93.useMemo)(() => {
62604
+ if (!appProps.codeMode) return void 0;
62605
+ return {
62606
+ ...appProps.codeMode,
62607
+ rootDir: activeRoot,
62608
+ onRootChange: (newRoot) => {
62609
+ appProps.codeMode?.onRootChange?.(newRoot);
62610
+ setActiveRoot(newRoot);
62611
+ setSessions(listSessionsForWorkspace(newRoot));
62612
+ }
62613
+ };
62614
+ }, [appProps.codeMode, activeRoot]);
62162
62615
  if (!key) {
62163
- return /* @__PURE__ */ import_react92.default.createElement(KeystrokeProvider, null, /* @__PURE__ */ import_react92.default.createElement(
62616
+ return /* @__PURE__ */ import_react93.default.createElement(KeystrokeProvider, null, /* @__PURE__ */ import_react93.default.createElement(
62164
62617
  Setup,
62165
62618
  {
62166
62619
  onReady: (k) => {
@@ -62172,7 +62625,7 @@ function Root({
62172
62625
  }
62173
62626
  process.env.DEEPSEEK_API_KEY = key;
62174
62627
  if (pickerOpen) {
62175
- return /* @__PURE__ */ import_react92.default.createElement(KeystrokeProvider, null, /* @__PURE__ */ import_react92.default.createElement(
62628
+ return /* @__PURE__ */ import_react93.default.createElement(KeystrokeProvider, null, /* @__PURE__ */ import_react93.default.createElement(
62176
62629
  SessionPicker,
62177
62630
  {
62178
62631
  sessions: sessions2,
@@ -62208,7 +62661,7 @@ function Root({
62208
62661
  }
62209
62662
  ));
62210
62663
  }
62211
- return /* @__PURE__ */ import_react92.default.createElement(KeystrokeProvider, null, /* @__PURE__ */ import_react92.default.createElement(
62664
+ return /* @__PURE__ */ import_react93.default.createElement(KeystrokeProvider, null, /* @__PURE__ */ import_react93.default.createElement(
62212
62665
  App,
62213
62666
  {
62214
62667
  key: activeSession ?? "__new__",
@@ -62217,7 +62670,6 @@ function Root({
62217
62670
  rebuildSystem: appProps.rebuildSystem,
62218
62671
  transcript: appProps.transcript,
62219
62672
  budgetUsd: appProps.budgetUsd,
62220
- failureThreshold: appProps.failureThreshold,
62221
62673
  session: activeSession,
62222
62674
  tools,
62223
62675
  mcpSpecs,
@@ -62225,7 +62677,7 @@ function Root({
62225
62677
  mcpRuntime,
62226
62678
  progressSink,
62227
62679
  startupInfoHints,
62228
- codeMode: appProps.codeMode,
62680
+ codeMode,
62229
62681
  noDashboard: appProps.noDashboard,
62230
62682
  openDashboard: appProps.openDashboard,
62231
62683
  dashboardPort: appProps.dashboardPort,
@@ -62302,8 +62754,9 @@ async function chatCommand(opts) {
62302
62754
  `);
62303
62755
  }
62304
62756
  }
62757
+ process.stdout.setMaxListeners(200);
62305
62758
  const { waitUntilExit } = render_default(
62306
- /* @__PURE__ */ import_react92.default.createElement(
62759
+ /* @__PURE__ */ import_react93.default.createElement(
62307
62760
  Root,
62308
62761
  {
62309
62762
  initialKey,
@@ -62335,4 +62788,4 @@ async function chatCommand(opts) {
62335
62788
  export {
62336
62789
  chatCommand
62337
62790
  };
62338
- //# sourceMappingURL=chunk-KQU2TYIL.js.map
62791
+ //# sourceMappingURL=chunk-SPXN5JIT.js.map