@google/gemini-cli 0.65.0-nightly.20261013.g51617c1bc → 0.65.0-preview.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/bundle/{chunk-BXWN65YH.js → chunk-2WVLIJA5.js} +1 -1
  2. package/bundle/{chunk-5322VSKQ.js → chunk-43EXRO7A.js} +1 -1
  3. package/bundle/{chunk-3EFBILEW.js → chunk-4DCA4L53.js} +2 -2
  4. package/bundle/{chunk-NAGGT65S.js → chunk-4JGVVJGK.js} +1 -1
  5. package/bundle/{chunk-VJXI22NX.js → chunk-BFIV7GTA.js} +2 -2
  6. package/bundle/{chunk-NJIZWOAO.js → chunk-F6AJM4WN.js} +3 -3
  7. package/bundle/{chunk-EPXYFN6C.js → chunk-GSQEBEGC.js} +3 -3
  8. package/bundle/{chunk-SSAL6PAH.js → chunk-H2CZXS7F.js} +1 -1
  9. package/bundle/{chunk-76GSGGHI.js → chunk-HLOOE7YN.js} +1 -1
  10. package/bundle/{chunk-ZZJRXUDM.js → chunk-K4G5D5ZZ.js} +1 -1
  11. package/bundle/{chunk-B22AOTUS.js → chunk-K7AA35SP.js} +26 -22
  12. package/bundle/{chunk-HVVLEMLR.js → chunk-K7NOVQ6G.js} +24 -20
  13. package/bundle/{chunk-C3XVWXTB.js → chunk-LLE5Z636.js} +7 -7
  14. package/bundle/{chunk-KR7RUPIE.js → chunk-NL7ZHGCH.js} +1 -1
  15. package/bundle/{chunk-6M4QEFFF.js → chunk-QJK54DSE.js} +8 -9
  16. package/bundle/{chunk-EA2F2LNY.js → chunk-RPHDSDL6.js} +1 -1
  17. package/bundle/{chunk-LBJNFX6K.js → chunk-S7BCRBI4.js} +1 -1
  18. package/bundle/{chunk-LB7T3Q3K.js → chunk-SN7QZKXC.js} +58 -71
  19. package/bundle/{chunk-GI5HEZHG.js → chunk-TP236FKO.js} +14976 -7914
  20. package/bundle/{chunk-LJV6OKHI.js → chunk-V2R74WAG.js} +5 -7
  21. package/bundle/{chunk-VLEIPZMF.js → chunk-V72FRESD.js} +2 -2
  22. package/bundle/{chunk-N2N4FSJX.js → chunk-VF5WQSOE.js} +1 -1
  23. package/bundle/{chunk-5OZJ7SSG.js → chunk-WGL5FJOS.js} +3 -3
  24. package/bundle/{chunk-JCR3XD5H.js → chunk-WTRK3NVX.js} +7 -7
  25. package/bundle/{cleanup-C3GRMYTQ.js → cleanup-HPADDONA.js} +2 -2
  26. package/bundle/{cleanup-HHEU7BTA.js → cleanup-JOMSXKMP.js} +2 -2
  27. package/bundle/{cleanup-VCQCBVRV.js → cleanup-LYRJHMMO.js} +2 -2
  28. package/bundle/{core-EX2SPRDZ.js → core-IVQAI4S6.js} +1 -1
  29. package/bundle/{dist-GG436DD3.js → core-NCJTYARO.js} +1 -1
  30. package/bundle/{devtoolsService-OI7AEJQC.js → devtoolsService-HIZA3JGR.js} +2 -2
  31. package/bundle/{devtoolsService-E3YLHACW.js → devtoolsService-JFJBTZ4B.js} +3 -4
  32. package/bundle/{devtoolsService-CSRUFNFL.js → devtoolsService-WP2OPVPB.js} +2 -2
  33. package/bundle/{dist-MRDCUCIF.js → dist-GQKLLBDW.js} +1 -1
  34. package/bundle/{gemini-TWP2M62H.js → gemini-546WMAHG.js} +198 -214
  35. package/bundle/{gemini-W7O4SF3Y.js → gemini-5TUKZVGS.js} +14 -14
  36. package/bundle/{gemini-GG2HNQFT.js → gemini-7CHJYSHM.js} +13 -13
  37. package/bundle/gemini.js +7 -7
  38. package/bundle/{interactiveCli-3Y2RHZKF.js → interactiveCli-5XIAIY74.js} +1069 -554
  39. package/bundle/{interactiveCli-GBXKC6IY.js → interactiveCli-E3PUPYMZ.js} +1069 -554
  40. package/bundle/{interactiveCli-E5RBGMKR.js → interactiveCli-L4PK7YY3.js} +1348 -852
  41. package/bundle/{liteRtServerManager-BV7LQRJK.js → liteRtServerManager-22ISMNN2.js} +4 -4
  42. package/bundle/{liteRtServerManager-EW5TUX2V.js → liteRtServerManager-JCTYJBV5.js} +4 -4
  43. package/bundle/{liteRtServerManager-G3ETQGQD.js → liteRtServerManager-JERG6KYC.js} +4 -4
  44. package/bundle/{oauth2-provider-NVW65VJA.js → oauth2-provider-477UJQX6.js} +1 -1
  45. package/bundle/{oauth2-provider-6Z2ZXOX6.js → oauth2-provider-MKWWBW4K.js} +79 -41
  46. package/bundle/{oauth2-provider-4CXU66CN.js → oauth2-provider-XRUER2XR.js} +1 -1
  47. package/bundle/{start-AZFYLAF2.js → start-AGMBPY3O.js} +6 -6
  48. package/bundle/{start-BHB4KDHO.js → start-MVIPJNQ5.js} +6 -6
  49. package/bundle/{start-CHWZQ4ZN.js → start-RZWSVT55.js} +6 -6
  50. package/package.json +1 -1
  51. package/bundle/chunk-5YND2HLC.js +0 -1571
  52. package/bundle/chunk-IJ7X4I2Z.js +0 -425
  53. package/bundle/chunk-K6N5Z54J.js +0 -154
  54. package/bundle/chunk-LZISQJNJ.js +0 -512
  55. package/bundle/chunk-OB6IRF7N.js +0 -118
  56. package/bundle/chunk-TLYQMFOC.js +0 -17535
  57. package/bundle/chunk-UVUPZGTC.js +0 -402042
  58. package/bundle/chunk-XHQIF7OW.js +0 -103253
  59. package/bundle/cleanup-XUHY5LXE.js +0 -32
  60. package/bundle/devtoolsService-NB2AMKES.js +0 -4359
  61. package/bundle/dist-O7VOOHX4.js +0 -2268
  62. package/bundle/gemini-UZP4MEXP.js +0 -17951
  63. package/bundle/interactiveCli-R3ZT6N5Z.js +0 -35014
  64. package/bundle/liteRtServerManager-YM2L7SJG.js +0 -65
  65. package/bundle/oauth2-provider-VEKJJAQ2.js +0 -273
  66. package/bundle/start-NJW6EU4P.js +0 -18
@@ -171,10 +171,10 @@ import {
171
171
  widestLineFromStyledChars,
172
172
  wordBreakStyledChars,
173
173
  wrapStyledChars
174
- } from "./chunk-LB7T3Q3K.js";
174
+ } from "./chunk-WTRK3NVX.js";
175
175
  import {
176
176
  require_source
177
- } from "./chunk-SSAL6PAH.js";
177
+ } from "./chunk-H2CZXS7F.js";
178
178
  import {
179
179
  appEvents
180
180
  } from "./chunk-5PS3AYFU.js";
@@ -227,24 +227,24 @@ import {
227
227
  stripAnsi,
228
228
  stripUnsafeCharacters,
229
229
  toCodePoints
230
- } from "./chunk-LJV6OKHI.js";
230
+ } from "./chunk-2WVLIJA5.js";
231
231
  import {
232
232
  handleAutoUpdate,
233
233
  isDevelopment,
234
234
  relaunchApp,
235
235
  setUpdateHandler
236
- } from "./chunk-VLEIPZMF.js";
236
+ } from "./chunk-4DCA4L53.js";
237
237
  import {
238
238
  isTodoList,
239
239
  mapCoreStatusToDisplayStatus,
240
240
  require_react
241
- } from "./chunk-LZISQJNJ.js";
241
+ } from "./chunk-NL7ZHGCH.js";
242
242
  import {
243
243
  registerCleanup,
244
244
  removeCleanup,
245
245
  runExitCleanup,
246
246
  setupTtyCheck
247
- } from "./chunk-LBJNFX6K.js";
247
+ } from "./chunk-RPHDSDL6.js";
248
248
  import {
249
249
  ACTIVATE_SKILL_TOOL_NAME,
250
250
  AGENT_TOOL_NAME,
@@ -450,7 +450,7 @@ import {
450
450
  validatePlanContent,
451
451
  validatePlanPath,
452
452
  writeToStdout
453
- } from "./chunk-B22AOTUS.js";
453
+ } from "./chunk-K7AA35SP.js";
454
454
  import "./chunk-664ZODQF.js";
455
455
  import "./chunk-IUUIT4SU.js";
456
456
  import "./chunk-L6PII3GR.js";
@@ -18733,6 +18733,9 @@ function useDebouncedValue(value, delay2 = 200) {
18733
18733
  }, [value, delay2]);
18734
18734
  return debounced;
18735
18735
  }
18736
+ function escapeRegExp(value) {
18737
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
18738
+ }
18736
18739
  function useReverseSearchCompletion(buffer, history, reverseSearchActive) {
18737
18740
  const {
18738
18741
  suggestions,
@@ -18762,11 +18765,12 @@ function useReverseSearchCompletion(buffer, history, reverseSearchActive) {
18762
18765
  const searchHistory = (0, import_react63.useCallback)(
18763
18766
  (query, items) => {
18764
18767
  const out = [];
18768
+ const regex = new RegExp(escapeRegExp(query), "iu");
18765
18769
  for (let i = 0; i < items.length; i++) {
18766
18770
  const cmd = items[i];
18767
- const idx = cmd.toLowerCase().indexOf(query);
18768
- if (idx !== -1) {
18769
- out.push({ label: cmd, value: cmd, matchedIndex: idx });
18771
+ const match = regex.exec(cmd);
18772
+ if (match) {
18773
+ out.push({ label: cmd, value: cmd, matchedIndex: match.index });
18770
18774
  }
18771
18775
  }
18772
18776
  return out;
@@ -18781,10 +18785,10 @@ function useReverseSearchCompletion(buffer, history, reverseSearchActive) {
18781
18785
  value: cmd,
18782
18786
  matchedIndex: -1
18783
18787
  }));
18784
- const query = debouncedQuery.toLowerCase();
18785
- const canUseCache = prevQueryRef.current && query.startsWith(prevQueryRef.current) && prevMatchesRef.current.length > 0;
18788
+ const lowerQuery = debouncedQuery.toLowerCase();
18789
+ const canUseCache = prevQueryRef.current && lowerQuery.startsWith(prevQueryRef.current) && prevMatchesRef.current.length > 0;
18786
18790
  const source = canUseCache ? prevMatchesRef.current.map((m) => m.value) : history;
18787
- return searchHistory(query, source);
18791
+ return searchHistory(debouncedQuery, source);
18788
18792
  }, [debouncedQuery, history, reverseSearchActive, searchHistory]);
18789
18793
  (0, import_react63.useEffect)(() => {
18790
18794
  if (!reverseSearchActive) {
@@ -26709,7 +26713,7 @@ var useLogger = (config) => {
26709
26713
  };
26710
26714
 
26711
26715
  // packages/cli/src/ui/hooks/useGeminiStream.ts
26712
- var import_react97 = __toESM(require_react(), 1);
26716
+ var import_react99 = __toESM(require_react(), 1);
26713
26717
 
26714
26718
  // packages/cli/src/ui/utils/markdownUtilities.ts
26715
26719
  var isIndexInsideCodeBlock = (content, indexToTest) => {
@@ -27075,6 +27079,638 @@ function adaptToolCalls(coreCalls, prevTracked) {
27075
27079
  // packages/cli/src/ui/hooks/useGeminiStream.ts
27076
27080
  import { promises as fs6 } from "node:fs";
27077
27081
  import path13 from "node:path";
27082
+
27083
+ // packages/cli/src/ui/hooks/useAgentStream.ts
27084
+ var import_react98 = __toESM(require_react(), 1);
27085
+
27086
+ // packages/cli/src/ui/hooks/useTurnActivityMonitor.ts
27087
+ var import_react97 = __toESM(require_react(), 1);
27088
+ var useTurnActivityMonitor = (streamingState, activePtyId, pendingToolCalls = []) => {
27089
+ const [operationStartTime, setOperationStartTime] = (0, import_react97.useState)(0);
27090
+ const prevPtyIdRef = (0, import_react97.useRef)(void 0);
27091
+ const prevStreamingStateRef = (0, import_react97.useRef)(void 0);
27092
+ (0, import_react97.useEffect)(() => {
27093
+ const isNowResponding = streamingState === "responding" /* Responding */;
27094
+ const wasResponding = prevStreamingStateRef.current === "responding" /* Responding */;
27095
+ const ptyChanged = activePtyId !== prevPtyIdRef.current;
27096
+ if (isNowResponding && (!wasResponding || ptyChanged)) {
27097
+ setOperationStartTime(Date.now());
27098
+ } else if (!isNowResponding && wasResponding) {
27099
+ setOperationStartTime(0);
27100
+ }
27101
+ prevPtyIdRef.current = activePtyId;
27102
+ prevStreamingStateRef.current = streamingState;
27103
+ }, [streamingState, activePtyId]);
27104
+ const isRedirectionActive = (0, import_react97.useMemo)(
27105
+ () => (
27106
+ // Check active tool calls for run_shell_command
27107
+ pendingToolCalls.some((tc) => {
27108
+ if (tc.request.name !== "run_shell_command") return false;
27109
+ const command = tc.request.args?.command || "";
27110
+ return hasRedirection(command);
27111
+ })
27112
+ ),
27113
+ [pendingToolCalls]
27114
+ );
27115
+ return {
27116
+ operationStartTime,
27117
+ isRedirectionActive
27118
+ };
27119
+ };
27120
+
27121
+ // packages/cli/src/ui/hooks/useAgentStream.ts
27122
+ var CANCELLED_TOOL_ERROR_MESSAGE = "[Operation Cancelled] Reason: User cancelled operation";
27123
+ function createCancelledToolCall(request, tool, invocation) {
27124
+ const fallbackToolName = request.name.trim() || "generic_tool";
27125
+ return {
27126
+ status: CoreToolCallStatus.Cancelled,
27127
+ request,
27128
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
27129
+ tool: tool ?? {
27130
+ name: fallbackToolName,
27131
+ displayName: fallbackToolName
27132
+ },
27133
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
27134
+ invocation: invocation ?? {
27135
+ getDescription: () => fallbackToolName
27136
+ },
27137
+ response: {
27138
+ callId: request.callId,
27139
+ responseParts: [
27140
+ {
27141
+ functionResponse: {
27142
+ id: request.callId,
27143
+ name: request.name,
27144
+ response: {
27145
+ error: CANCELLED_TOOL_ERROR_MESSAGE
27146
+ }
27147
+ }
27148
+ }
27149
+ ],
27150
+ resultDisplay: void 0,
27151
+ error: new Error(CANCELLED_TOOL_ERROR_MESSAGE),
27152
+ errorType: ToolErrorType.UNHANDLED_EXCEPTION
27153
+ }
27154
+ };
27155
+ }
27156
+ var useAgentStream = ({
27157
+ agent,
27158
+ config,
27159
+ addItem,
27160
+ onCancelSubmit,
27161
+ isShellFocused,
27162
+ logger
27163
+ }) => {
27164
+ const [initError] = (0, import_react98.useState)(null);
27165
+ const [retryStatus] = (0, import_react98.useState)(null);
27166
+ const [streamingState, setStreamingState] = (0, import_react98.useState)(
27167
+ "idle" /* Idle */
27168
+ );
27169
+ const [thought, setThought] = (0, import_react98.useState)(null);
27170
+ const [lastOutputTime, setLastOutputTime] = (0, import_react98.useState)(Date.now());
27171
+ const currentStreamIdRef = (0, import_react98.useRef)(null);
27172
+ const userMessageTimestampRef = (0, import_react98.useRef)(0);
27173
+ const geminiMessageBufferRef = (0, import_react98.useRef)("");
27174
+ const [pendingHistoryItem, pendingHistoryItemRef, setPendingHistoryItem] = useStateAndRef(null);
27175
+ const [trackedTools, trackedToolsRef, setTrackedTools] = useStateAndRef([]);
27176
+ const toolRequestArgsRef = (0, import_react98.useRef)(
27177
+ /* @__PURE__ */ new Map()
27178
+ );
27179
+ const cancellationStateRef = (0, import_react98.useRef)(
27180
+ "idle" /* Idle */
27181
+ );
27182
+ const cancelPromiseRef = (0, import_react98.useRef)(Promise.resolve());
27183
+ const [pushedToolCallIds, pushedToolCallIdsRef, setPushedToolCallIds] = useStateAndRef(/* @__PURE__ */ new Set());
27184
+ const [_isFirstToolInGroup, isFirstToolInGroupRef, setIsFirstToolInGroup] = useStateAndRef(true);
27185
+ const [_hasEmittedBoxInTurn, hasEmittedBoxInTurnRef, setHasEmittedBoxInTurn] = useStateAndRef(false);
27186
+ const { startNewPrompt } = useSessionStats();
27187
+ const activePtyId = void 0;
27188
+ const backgroundTaskCount = 0;
27189
+ const isBackgroundTaskVisible = false;
27190
+ const toggleBackgroundTasks = (0, import_react98.useCallback)(() => {
27191
+ }, []);
27192
+ const backgroundCurrentExecution = void 0;
27193
+ const backgroundTasks = (0, import_react98.useMemo)(() => /* @__PURE__ */ new Map(), []);
27194
+ const dismissBackgroundTask = (0, import_react98.useCallback)(async (_pid) => {
27195
+ }, []);
27196
+ const pendingToolCalls = (0, import_react98.useMemo)(
27197
+ () => trackedTools.map((t) => ({
27198
+ request: {
27199
+ name: t.originalRequestName || t.name,
27200
+ args: { command: t.description },
27201
+ callId: t.callId,
27202
+ isClientInitiated: t.isClientInitiated ?? false,
27203
+ prompt_id: ""
27204
+ },
27205
+ status: t.status
27206
+ })),
27207
+ [trackedTools]
27208
+ );
27209
+ const [loopDetectionConfirmationRequest] = (0, import_react98.useState)(null);
27210
+ const flushPendingText = (0, import_react98.useCallback)(() => {
27211
+ if (pendingHistoryItemRef.current) {
27212
+ addItem(pendingHistoryItemRef.current, userMessageTimestampRef.current);
27213
+ setPendingHistoryItem(null);
27214
+ geminiMessageBufferRef.current = "";
27215
+ }
27216
+ }, [addItem, pendingHistoryItemRef, setPendingHistoryItem]);
27217
+ const cancelOngoingRequest = (0, import_react98.useCallback)(
27218
+ async (clearBuffer = true) => {
27219
+ if (!agent) {
27220
+ return;
27221
+ }
27222
+ if (cancellationStateRef.current === "cancelling" /* Cancelling */) {
27223
+ if (clearBuffer) {
27224
+ onCancelSubmit(false, true);
27225
+ }
27226
+ try {
27227
+ await cancelPromiseRef.current;
27228
+ } catch (error) {
27229
+ debugLogger.warn(`Error awaiting cancelTask: ${error}`);
27230
+ }
27231
+ return;
27232
+ }
27233
+ cancellationStateRef.current = "cancelling" /* Cancelling */;
27234
+ const cancelTask = (async () => {
27235
+ try {
27236
+ let timeoutId2;
27237
+ try {
27238
+ await Promise.race([
27239
+ agent.abort(),
27240
+ new Promise((resolve3) => {
27241
+ timeoutId2 = setTimeout(resolve3, 1e3);
27242
+ })
27243
+ ]);
27244
+ } finally {
27245
+ if (timeoutId2 !== void 0) {
27246
+ clearTimeout(timeoutId2);
27247
+ }
27248
+ }
27249
+ const unpushedTools = trackedToolsRef.current.filter(
27250
+ (tc) => !pushedToolCallIdsRef.current.has(tc.callId)
27251
+ );
27252
+ if (unpushedTools.length > 0) {
27253
+ setTrackedTools(
27254
+ (prev) => prev.map((tc) => {
27255
+ if (!pushedToolCallIdsRef.current.has(tc.callId) && tc.status !== CoreToolCallStatus.Success && tc.status !== CoreToolCallStatus.Error && tc.status !== CoreToolCallStatus.Cancelled) {
27256
+ return {
27257
+ ...tc,
27258
+ status: CoreToolCallStatus.Cancelled
27259
+ };
27260
+ }
27261
+ return tc;
27262
+ })
27263
+ );
27264
+ }
27265
+ try {
27266
+ const client = config?.getGeminiClient?.();
27267
+ const chat = client?.getChat?.();
27268
+ if (chat) {
27269
+ const seenCallIds = /* @__PURE__ */ new Set();
27270
+ const synthesizedCalls = [];
27271
+ for (const tc of unpushedTools) {
27272
+ if (tc.isClientInitiated) {
27273
+ continue;
27274
+ }
27275
+ seenCallIds.add(tc.callId);
27276
+ const name = tc.originalRequestName || tc.name;
27277
+ const args = toolRequestArgsRef.current.get(tc.callId) ?? {};
27278
+ synthesizedCalls.push(
27279
+ createCancelledToolCall({
27280
+ callId: tc.callId,
27281
+ name,
27282
+ args,
27283
+ isClientInitiated: false,
27284
+ prompt_id: ""
27285
+ })
27286
+ );
27287
+ }
27288
+ const clientHistory = client?.getHistory?.() ?? [];
27289
+ const lastTurn = clientHistory.at(-1);
27290
+ if (lastTurn?.role === "model" && Array.isArray(lastTurn.parts)) {
27291
+ let index = 0;
27292
+ for (const part of lastTurn.parts) {
27293
+ const fc = part.functionCall;
27294
+ if (fc?.name) {
27295
+ const callId = fc.id ?? `${fc.name}-${Date.now()}-${index++}`;
27296
+ if (!seenCallIds.has(callId)) {
27297
+ seenCallIds.add(callId);
27298
+ synthesizedCalls.push(
27299
+ createCancelledToolCall({
27300
+ callId,
27301
+ name: fc.name,
27302
+ args: fc.args ?? {},
27303
+ isClientInitiated: false,
27304
+ prompt_id: ""
27305
+ })
27306
+ );
27307
+ }
27308
+ }
27309
+ }
27310
+ }
27311
+ if (synthesizedCalls.length > 0) {
27312
+ const currentModel = client?.getCurrentSequenceModel?.() ?? config?.getModel?.() ?? "";
27313
+ chat.recordCompletedToolCalls(currentModel, synthesizedCalls);
27314
+ }
27315
+ }
27316
+ } catch (error) {
27317
+ debugLogger.warn(
27318
+ `Error recording cancelled tool calls in agent stream: ${error}`
27319
+ );
27320
+ }
27321
+ setStreamingState("idle" /* Idle */);
27322
+ onCancelSubmit(false, clearBuffer);
27323
+ } finally {
27324
+ cancellationStateRef.current = "idle" /* Idle */;
27325
+ }
27326
+ })();
27327
+ cancelPromiseRef.current = cancelTask;
27328
+ try {
27329
+ await cancelTask;
27330
+ } catch (error) {
27331
+ debugLogger.warn(`Error awaiting cancelTask: ${error}`);
27332
+ }
27333
+ },
27334
+ [
27335
+ agent,
27336
+ config,
27337
+ onCancelSubmit,
27338
+ pushedToolCallIdsRef,
27339
+ setStreamingState,
27340
+ setTrackedTools,
27341
+ trackedToolsRef
27342
+ ]
27343
+ );
27344
+ const handleApprovalModeChange = (0, import_react98.useCallback)(
27345
+ async (newApprovalMode) => {
27346
+ debugLogger.debug(`Approval mode changed to ${newApprovalMode} (stub)`);
27347
+ },
27348
+ []
27349
+ );
27350
+ const handleEvent = (0, import_react98.useCallback)(
27351
+ (event) => {
27352
+ setLastOutputTime(Date.now());
27353
+ switch (event.type) {
27354
+ case "agent_start":
27355
+ setStreamingState("responding" /* Responding */);
27356
+ break;
27357
+ case "agent_end":
27358
+ setStreamingState("idle" /* Idle */);
27359
+ flushPendingText();
27360
+ break;
27361
+ case "message":
27362
+ if (event.role === "agent") {
27363
+ for (const part of event.content) {
27364
+ if (part.type === "text") {
27365
+ geminiMessageBufferRef.current += part.text;
27366
+ const splitPoint = findLastSafeSplitPoint(
27367
+ geminiMessageBufferRef.current
27368
+ );
27369
+ if (splitPoint === geminiMessageBufferRef.current.length) {
27370
+ setPendingHistoryItem({
27371
+ type: "gemini",
27372
+ text: geminiMessageBufferRef.current
27373
+ });
27374
+ } else {
27375
+ const before = geminiMessageBufferRef.current.substring(
27376
+ 0,
27377
+ splitPoint
27378
+ );
27379
+ const after = geminiMessageBufferRef.current.substring(splitPoint);
27380
+ addItem(
27381
+ { type: "gemini", text: before },
27382
+ userMessageTimestampRef.current
27383
+ );
27384
+ geminiMessageBufferRef.current = after;
27385
+ setPendingHistoryItem({
27386
+ type: "gemini_content",
27387
+ text: after
27388
+ });
27389
+ }
27390
+ } else if (part.type === "thought") {
27391
+ setThought(parseThought(part.thought));
27392
+ }
27393
+ }
27394
+ }
27395
+ break;
27396
+ case "tool_request": {
27397
+ flushPendingText();
27398
+ toolRequestArgsRef.current.set(event.requestId, event.args);
27399
+ const legacyState = event._meta?.legacyState;
27400
+ const displayName = legacyState?.displayName ?? event.name;
27401
+ const isOutputMarkdown = legacyState?.isOutputMarkdown ?? false;
27402
+ const desc = legacyState?.description ?? "";
27403
+ const fallbackKind = Kind.Other;
27404
+ const newCall = {
27405
+ callId: event.requestId,
27406
+ name: displayName,
27407
+ originalRequestName: event.name,
27408
+ description: desc,
27409
+ display: event.display,
27410
+ status: CoreToolCallStatus.Scheduled,
27411
+ isClientInitiated: false,
27412
+ renderOutputAsMarkdown: isOutputMarkdown,
27413
+ kind: legacyState?.kind ?? fallbackKind,
27414
+ confirmationDetails: void 0,
27415
+ resultDisplay: void 0
27416
+ };
27417
+ setTrackedTools((prev) => [...prev, newCall]);
27418
+ break;
27419
+ }
27420
+ case "tool_update": {
27421
+ setTrackedTools(
27422
+ (prev) => prev.map((tc) => {
27423
+ if (tc.callId !== event.requestId) return tc;
27424
+ const legacyState = event._meta?.legacyState;
27425
+ const evtStatus = legacyState?.status;
27426
+ let status = tc.status;
27427
+ if (evtStatus === "executing")
27428
+ status = CoreToolCallStatus.Executing;
27429
+ else if (evtStatus === "error") status = CoreToolCallStatus.Error;
27430
+ else if (evtStatus === "success")
27431
+ status = CoreToolCallStatus.Success;
27432
+ const display = event.display?.result;
27433
+ const liveOutput = displayContentToString(display) ?? tc.resultDisplay;
27434
+ const progressMessage = legacyState?.progressMessage ?? tc.progressMessage;
27435
+ const progress = legacyState?.progress ?? tc.progress;
27436
+ const progressTotal = legacyState?.progressTotal ?? tc.progressTotal;
27437
+ const ptyId = legacyState?.pid ?? tc.ptyId;
27438
+ const description = legacyState?.description ?? tc.description;
27439
+ return {
27440
+ ...tc,
27441
+ status,
27442
+ display: event.display ? { ...tc.display, ...event.display } : tc.display,
27443
+ resultDisplay: liveOutput,
27444
+ progressMessage,
27445
+ progress,
27446
+ progressTotal,
27447
+ ptyId,
27448
+ description
27449
+ };
27450
+ })
27451
+ );
27452
+ break;
27453
+ }
27454
+ case "tool_response": {
27455
+ setTrackedTools(
27456
+ (prev) => prev.map((tc) => {
27457
+ if (tc.callId !== event.requestId) return tc;
27458
+ const legacyState = event._meta?.legacyState;
27459
+ const outputFile = legacyState?.outputFile;
27460
+ const display = event.display?.result;
27461
+ const resultDisplay = displayContentToString(display) ?? tc.resultDisplay;
27462
+ return {
27463
+ ...tc,
27464
+ status: event.isError ? CoreToolCallStatus.Error : CoreToolCallStatus.Success,
27465
+ display: event.display ? { ...tc.display, ...event.display } : tc.display,
27466
+ resultDisplay,
27467
+ outputFile
27468
+ };
27469
+ })
27470
+ );
27471
+ break;
27472
+ }
27473
+ case "error": {
27474
+ const message = event._meta?.["code"] === "AGENT_EXECUTION_BLOCKED" ? `Agent execution blocked: ${event.message}` : event.message;
27475
+ addItem(
27476
+ { type: "error" /* ERROR */, text: message },
27477
+ userMessageTimestampRef.current
27478
+ );
27479
+ break;
27480
+ }
27481
+ case "initialize":
27482
+ case "session_update":
27483
+ case "elicitation_request":
27484
+ case "elicitation_response":
27485
+ case "usage":
27486
+ case "custom":
27487
+ break;
27488
+ default:
27489
+ debugLogger.error("Unknown agent event type:", event);
27490
+ event;
27491
+ break;
27492
+ }
27493
+ },
27494
+ [
27495
+ addItem,
27496
+ flushPendingText,
27497
+ setPendingHistoryItem,
27498
+ setTrackedTools,
27499
+ setStreamingState,
27500
+ setThought,
27501
+ setLastOutputTime
27502
+ ]
27503
+ );
27504
+ (0, import_react98.useEffect)(() => {
27505
+ const unsubscribe = agent?.subscribe(handleEvent);
27506
+ return () => unsubscribe?.();
27507
+ }, [agent, handleEvent]);
27508
+ useKeypress(
27509
+ (key) => {
27510
+ if (key.name === "escape" && !isShellFocused) {
27511
+ void cancelOngoingRequest(false);
27512
+ return true;
27513
+ }
27514
+ return false;
27515
+ },
27516
+ {
27517
+ isActive: streamingState === "responding" /* Responding */ || streamingState === "waiting_for_confirmation" /* WaitingForConfirmation */
27518
+ }
27519
+ );
27520
+ const submitQuery = (0, import_react98.useCallback)(
27521
+ async (query, options, _prompt_id) => {
27522
+ if (!agent) return;
27523
+ const timestamp = Date.now();
27524
+ setLastOutputTime(timestamp);
27525
+ userMessageTimestampRef.current = timestamp;
27526
+ geminiMessageBufferRef.current = "";
27527
+ if (!options?.isContinuation) {
27528
+ toolRequestArgsRef.current.clear();
27529
+ if (typeof query === "string") {
27530
+ addItem({ type: "user" /* USER */, text: query }, timestamp);
27531
+ void logger?.logMessage(MessageSenderType.USER, query);
27532
+ }
27533
+ startNewPrompt();
27534
+ }
27535
+ const parts = geminiPartsToContentParts(
27536
+ typeof query === "string" ? [{ text: query }] : query
27537
+ );
27538
+ try {
27539
+ const { streamId } = await agent.send({
27540
+ message: { content: parts }
27541
+ });
27542
+ currentStreamIdRef.current = streamId;
27543
+ } catch (err) {
27544
+ addItem(
27545
+ { type: "error" /* ERROR */, text: getErrorMessage(err) },
27546
+ timestamp
27547
+ );
27548
+ }
27549
+ },
27550
+ [agent, addItem, logger, startNewPrompt]
27551
+ );
27552
+ (0, import_react98.useEffect)(() => {
27553
+ if (trackedTools.length > 0) {
27554
+ const isNewBatch = !trackedTools.some(
27555
+ (tc) => pushedToolCallIdsRef.current.has(tc.callId)
27556
+ );
27557
+ if (isNewBatch) {
27558
+ setPushedToolCallIds(/* @__PURE__ */ new Set());
27559
+ setIsFirstToolInGroup(true);
27560
+ }
27561
+ } else if (streamingState === "idle" /* Idle */) {
27562
+ setPushedToolCallIds(/* @__PURE__ */ new Set());
27563
+ setIsFirstToolInGroup(true);
27564
+ }
27565
+ }, [
27566
+ trackedTools,
27567
+ pushedToolCallIdsRef,
27568
+ setPushedToolCallIds,
27569
+ setIsFirstToolInGroup,
27570
+ streamingState
27571
+ ]);
27572
+ (0, import_react98.useEffect)(() => {
27573
+ if (trackedTools.length === 0) return;
27574
+ const allTerminal = trackedTools.every(
27575
+ (tc) => tc.status === "success" || tc.status === "error" || tc.status === "cancelled"
27576
+ );
27577
+ const toolsToPush = trackedTools.filter(
27578
+ (tc) => !pushedToolCallIdsRef.current.has(tc.callId)
27579
+ );
27580
+ if (allTerminal && toolsToPush.length > 0) {
27581
+ const newPushed = new Set(pushedToolCallIdsRef.current);
27582
+ for (const tc of toolsToPush) {
27583
+ newPushed.add(tc.callId);
27584
+ }
27585
+ const appearance = getToolGroupBorderAppearance(
27586
+ { type: "tool_group", tools: trackedTools },
27587
+ activePtyId,
27588
+ !!isShellFocused,
27589
+ [],
27590
+ backgroundTasks
27591
+ );
27592
+ const hasBoxInBatch = toolsToPush.some(
27593
+ (tc) => tc.display?.format !== "notice"
27594
+ );
27595
+ const shouldStartNewBlock = isFirstToolInGroupRef.current || !hasEmittedBoxInTurnRef.current && hasBoxInBatch;
27596
+ const historyItem = {
27597
+ type: "tool_display_group",
27598
+ tools: toolsToPush.map((tc) => ({
27599
+ name: tc.name,
27600
+ description: tc.description,
27601
+ ...tc.display,
27602
+ status: tc.status,
27603
+ originalRequestName: tc.originalRequestName
27604
+ })),
27605
+ borderTop: shouldStartNewBlock,
27606
+ borderBottom: true,
27607
+ ...appearance
27608
+ };
27609
+ addItem(historyItem);
27610
+ setPushedToolCallIds(newPushed);
27611
+ if (hasBoxInBatch) {
27612
+ setHasEmittedBoxInTurn(true);
27613
+ }
27614
+ setIsFirstToolInGroup(false);
27615
+ }
27616
+ }, [
27617
+ trackedTools,
27618
+ pushedToolCallIdsRef,
27619
+ isFirstToolInGroupRef,
27620
+ hasEmittedBoxInTurnRef,
27621
+ setPushedToolCallIds,
27622
+ setIsFirstToolInGroup,
27623
+ setHasEmittedBoxInTurn,
27624
+ addItem,
27625
+ activePtyId,
27626
+ isShellFocused,
27627
+ backgroundTasks
27628
+ ]);
27629
+ const pendingToolGroupItems = (0, import_react98.useMemo)(() => {
27630
+ const remainingTools = trackedTools.filter(
27631
+ (tc) => !pushedToolCallIdsRef.current.has(tc.callId)
27632
+ );
27633
+ const items = [];
27634
+ const appearance = getToolGroupBorderAppearance(
27635
+ { type: "tool_group", tools: trackedTools },
27636
+ activePtyId,
27637
+ !!isShellFocused,
27638
+ [],
27639
+ backgroundTasks
27640
+ );
27641
+ if (remainingTools.length > 0) {
27642
+ const hasBoxInPending = remainingTools.some(
27643
+ (tc) => tc.display?.format !== "notice"
27644
+ );
27645
+ const shouldStartNewBlock = pushedToolCallIds.size === 0 || !hasEmittedBoxInTurnRef.current && hasBoxInPending;
27646
+ items.push({
27647
+ type: "tool_display_group",
27648
+ tools: remainingTools.map((tc) => ({
27649
+ name: tc.name,
27650
+ description: tc.description,
27651
+ ...tc.display,
27652
+ status: tc.status,
27653
+ originalRequestName: tc.originalRequestName
27654
+ })),
27655
+ borderTop: shouldStartNewBlock,
27656
+ borderBottom: false,
27657
+ ...appearance
27658
+ });
27659
+ }
27660
+ const allTerminal = trackedTools.length > 0 && trackedTools.every(
27661
+ (tc) => tc.status === "success" || tc.status === "error" || tc.status === "cancelled"
27662
+ );
27663
+ const allPushed = trackedTools.length > 0 && trackedTools.every((tc) => pushedToolCallIds.has(tc.callId));
27664
+ const anyVisibleInHistory = pushedToolCallIds.size > 0;
27665
+ const anyVisibleInPending = remainingTools.length > 0;
27666
+ if (trackedTools.length > 0 && !(allTerminal && allPushed) && (anyVisibleInHistory || anyVisibleInPending)) {
27667
+ items.push({
27668
+ type: "tool_display_group",
27669
+ tools: [],
27670
+ borderTop: false,
27671
+ borderBottom: true,
27672
+ ...appearance
27673
+ });
27674
+ }
27675
+ return items;
27676
+ }, [
27677
+ trackedTools,
27678
+ pushedToolCallIds,
27679
+ pushedToolCallIdsRef,
27680
+ hasEmittedBoxInTurnRef,
27681
+ activePtyId,
27682
+ isShellFocused,
27683
+ backgroundTasks
27684
+ ]);
27685
+ const pendingHistoryItems = (0, import_react98.useMemo)(
27686
+ () => [pendingHistoryItem, ...pendingToolGroupItems].filter(
27687
+ (i) => i !== void 0 && i !== null
27688
+ ),
27689
+ [pendingHistoryItem, pendingToolGroupItems]
27690
+ );
27691
+ return {
27692
+ streamingState,
27693
+ submitQuery,
27694
+ initError,
27695
+ pendingHistoryItems,
27696
+ thought,
27697
+ cancelOngoingRequest,
27698
+ pendingToolCalls,
27699
+ handleApprovalModeChange,
27700
+ activePtyId,
27701
+ loopDetectionConfirmationRequest,
27702
+ lastOutputTime,
27703
+ backgroundTaskCount,
27704
+ isBackgroundTaskVisible,
27705
+ toggleBackgroundTasks,
27706
+ backgroundCurrentExecution,
27707
+ backgroundTasks,
27708
+ retryStatus,
27709
+ dismissBackgroundTask
27710
+ };
27711
+ };
27712
+
27713
+ // packages/cli/src/ui/hooks/useGeminiStream.ts
27078
27714
  var isTopicTool2 = (name) => name === UPDATE_TOPIC_TOOL_NAME || name === UPDATE_TOPIC_DISPLAY_NAME;
27079
27715
  var SUPPRESSED_TOOL_ERRORS_NOTE = 'Some internal tool attempts failed before this final error. Press F12 for diagnostics, or run /settings and change "Error Verbosity" to full for details.';
27080
27716
  var LOW_VERBOSITY_FAILURE_NOTE = 'This request failed. Press F12 for diagnostics, or run /settings and change "Error Verbosity" to full for full details.';
@@ -27122,35 +27758,41 @@ function calculateStreamingState(isResponding, toolCalls) {
27122
27758
  return "idle" /* Idle */;
27123
27759
  }
27124
27760
  var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebugMessage, handleSlashCommand, shellModeActive, getPreferredEditor, onAuthError, _performMemoryRefresh, modelSwitchedFromQuotaError, setModelSwitchedFromQuotaError, onCancelSubmit, setShellInputFocused, terminalWidth, terminalHeight, isShellFocused, consumeUserHint) => {
27125
- const [initError, setInitError] = (0, import_react97.useState)(null);
27126
- const [retryStatus, setRetryStatus] = (0, import_react97.useState)(
27761
+ const [initError, setInitError] = (0, import_react99.useState)(null);
27762
+ const [retryStatus, setRetryStatus] = (0, import_react99.useState)(
27127
27763
  null
27128
27764
  );
27129
27765
  const isLowErrorVerbosity = settings.merged.ui?.errorVerbosity !== "full";
27130
- const suppressedToolErrorCountRef = (0, import_react97.useRef)(0);
27131
- const suppressedToolErrorNoteShownRef = (0, import_react97.useRef)(false);
27132
- const lowVerbosityFailureNoteShownRef = (0, import_react97.useRef)(false);
27133
- const abortControllerRef = (0, import_react97.useRef)(null);
27134
- const turnCancelledRef = (0, import_react97.useRef)(false);
27135
- const activeQueryIdRef = (0, import_react97.useRef)(null);
27136
- const previousApprovalModeRef = (0, import_react97.useRef)(
27766
+ const suppressedToolErrorCountRef = (0, import_react99.useRef)(0);
27767
+ const suppressedToolErrorNoteShownRef = (0, import_react99.useRef)(false);
27768
+ const lowVerbosityFailureNoteShownRef = (0, import_react99.useRef)(false);
27769
+ const abortControllerRef = (0, import_react99.useRef)(null);
27770
+ const turnCancelledRef = (0, import_react99.useRef)(false);
27771
+ const pendingToolCallRequestsRef = (0, import_react99.useRef)([]);
27772
+ const activeSchedulePromiseRef = (0, import_react99.useRef)(null);
27773
+ const cancellationStateRef = (0, import_react99.useRef)(
27774
+ "idle" /* Idle */
27775
+ );
27776
+ const cancelPromiseRef = (0, import_react99.useRef)(Promise.resolve());
27777
+ const activeQueryIdRef = (0, import_react99.useRef)(null);
27778
+ const previousApprovalModeRef = (0, import_react99.useRef)(
27137
27779
  config.getApprovalMode()
27138
27780
  );
27139
27781
  const [isResponding, isRespondingRef, setIsResponding] = useStateAndRef(false);
27140
27782
  const [thought, thoughtRef, setThought] = useStateAndRef(null);
27141
27783
  const [pendingHistoryItem, pendingHistoryItemRef, setPendingHistoryItem] = useStateAndRef(null);
27142
- const [lastGeminiActivityTime, setLastGeminiActivityTime] = (0, import_react97.useState)(0);
27784
+ const [lastGeminiActivityTime, setLastGeminiActivityTime] = (0, import_react99.useState)(0);
27143
27785
  const [pushedToolCallIds, pushedToolCallIdsRef, setPushedToolCallIds] = useStateAndRef(/* @__PURE__ */ new Set());
27144
27786
  const [_isFirstToolInGroup, isFirstToolInGroupRef, setIsFirstToolInGroup] = useStateAndRef(true);
27145
27787
  const { startNewPrompt, getPromptCount } = useSessionStats();
27146
27788
  const logger = useLogger(config);
27147
- const gitService = (0, import_react97.useMemo)(() => {
27789
+ const gitService = (0, import_react99.useMemo)(() => {
27148
27790
  if (!config.getProjectRoot()) {
27149
27791
  return;
27150
27792
  }
27151
27793
  return new GitService(config.getProjectRoot(), config.storage);
27152
27794
  }, [config]);
27153
- (0, import_react97.useEffect)(() => {
27795
+ (0, import_react99.useEffect)(() => {
27154
27796
  const handleRetryAttempt = (payload) => {
27155
27797
  if (turnCancelledRef.current || !isRespondingRef.current) {
27156
27798
  return;
@@ -27171,6 +27813,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27171
27813
  lastToolOutputTime
27172
27814
  ] = useToolScheduler(
27173
27815
  async (completedToolCallsFromScheduler) => {
27816
+ pendingToolCallRequestsRef.current = [];
27174
27817
  if (completedToolCallsFromScheduler.length > 0) {
27175
27818
  const toolsToPush = completedToolCallsFromScheduler.filter(
27176
27819
  (tc) => !pushedToolCallIdsRef.current.has(tc.request.callId)
@@ -27205,15 +27848,25 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27205
27848
  }
27206
27849
  setToolCallsForDisplay([]);
27207
27850
  try {
27208
- const currentModel = config.getGeminiClient().getCurrentSequenceModel() ?? config.getModel();
27209
- config.getGeminiClient().getChat().recordCompletedToolCalls(
27210
- currentModel,
27211
- completedToolCallsFromScheduler
27212
- );
27213
- await recordToolCallInteractions(
27214
- config,
27215
- completedToolCallsFromScheduler
27851
+ const client = geminiClient ?? config.getGeminiClient();
27852
+ const currentModel = client?.getCurrentSequenceModel?.() ?? config.getModel();
27853
+ const normalizedCompletedCalls = completedToolCallsFromScheduler.map(
27854
+ (tc) => {
27855
+ if (tc.status === CoreToolCallStatus.Cancelled && (!tc.response?.responseParts || tc.response.responseParts.length === 0)) {
27856
+ return {
27857
+ ...tc,
27858
+ response: createCancelledToolCall(
27859
+ tc.request,
27860
+ tc.tool,
27861
+ tc.invocation
27862
+ ).response
27863
+ };
27864
+ }
27865
+ return tc;
27866
+ }
27216
27867
  );
27868
+ client?.getChat?.()?.recordCompletedToolCalls(currentModel, normalizedCompletedCalls);
27869
+ await recordToolCallInteractions(config, normalizedCompletedCalls);
27217
27870
  } catch (error) {
27218
27871
  debugLogger.warn(
27219
27872
  `Error recording completed tool call information: ${error}`
@@ -27225,13 +27878,13 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27225
27878
  config,
27226
27879
  getPreferredEditor
27227
27880
  );
27228
- const activeBackgroundExecutionId = (0, import_react97.useMemo)(() => {
27881
+ const activeBackgroundExecutionId = (0, import_react99.useMemo)(() => {
27229
27882
  const executingBackgroundableTool = toolCalls.find(
27230
27883
  isBackgroundableExecutingToolCall
27231
27884
  );
27232
27885
  return executingBackgroundableTool?.pid;
27233
27886
  }, [toolCalls]);
27234
- const onExec = (0, import_react97.useCallback)(
27887
+ const onExec = (0, import_react99.useCallback)(
27235
27888
  async (done) => {
27236
27889
  setIsResponding(true);
27237
27890
  await done;
@@ -27262,11 +27915,11 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27262
27915
  terminalHeight,
27263
27916
  activeBackgroundExecutionId
27264
27917
  );
27265
- const streamingState = (0, import_react97.useMemo)(
27918
+ const streamingState = (0, import_react99.useMemo)(
27266
27919
  () => calculateStreamingState(isResponding, toolCalls),
27267
27920
  [isResponding, toolCalls]
27268
27921
  );
27269
- (0, import_react97.useEffect)(() => {
27922
+ (0, import_react99.useEffect)(() => {
27270
27923
  if (toolCalls.length > 0) {
27271
27924
  const isNewBatch = !toolCalls.some(
27272
27925
  (tc) => pushedToolCallIdsRef.current.has(tc.request.callId)
@@ -27286,7 +27939,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27286
27939
  setIsFirstToolInGroup,
27287
27940
  streamingState
27288
27941
  ]);
27289
- (0, import_react97.useEffect)(() => {
27942
+ (0, import_react99.useEffect)(() => {
27290
27943
  const toolsToPush = [];
27291
27944
  for (let i = 0; i < toolCalls.length; i++) {
27292
27945
  const tc = toolCalls[i];
@@ -27386,7 +28039,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27386
28039
  backgroundTasks,
27387
28040
  settings.merged.ui?.compactToolOutput
27388
28041
  ]);
27389
- const pendingToolGroupItems = (0, import_react97.useMemo)(() => {
28042
+ const pendingToolGroupItems = (0, import_react99.useMemo)(() => {
27390
28043
  const remainingTools = toolCalls.filter(
27391
28044
  (tc) => !pushedToolCallIds.has(tc.request.callId)
27392
28045
  );
@@ -27456,26 +28109,26 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27456
28109
  backgroundTasks,
27457
28110
  settings.merged.ui?.compactToolOutput
27458
28111
  ]);
27459
- const lastQueryRef = (0, import_react97.useRef)(null);
27460
- const lastPromptIdRef = (0, import_react97.useRef)(null);
27461
- const loopDetectedRef = (0, import_react97.useRef)(false);
27462
- const autoNudgeAttemptCountRef = (0, import_react97.useRef)(0);
28112
+ const lastQueryRef = (0, import_react99.useRef)(null);
28113
+ const lastPromptIdRef = (0, import_react99.useRef)(null);
28114
+ const loopDetectedRef = (0, import_react99.useRef)(false);
28115
+ const autoNudgeAttemptCountRef = (0, import_react99.useRef)(0);
27463
28116
  const MAX_AUTO_NUDGE_ATTEMPTS = 2;
27464
- const submitQueryRef = (0, import_react97.useRef)(null);
28117
+ const submitQueryRef = (0, import_react99.useRef)(null);
27465
28118
  const [
27466
28119
  loopDetectionConfirmationRequest,
27467
28120
  setLoopDetectionConfirmationRequest
27468
- ] = (0, import_react97.useState)(null);
28121
+ ] = (0, import_react99.useState)(null);
27469
28122
  const activePtyId = activeShellPtyId ?? activeBackgroundExecutionId ?? void 0;
27470
- const prevActiveShellPtyIdRef = (0, import_react97.useRef)(null);
27471
- (0, import_react97.useEffect)(() => {
28123
+ const prevActiveShellPtyIdRef = (0, import_react99.useRef)(null);
28124
+ (0, import_react99.useEffect)(() => {
27472
28125
  if (turnCancelledRef.current && prevActiveShellPtyIdRef.current !== null && activeShellPtyId === null) {
27473
28126
  addItem({ type: "info" /* INFO */, text: "Request cancelled." });
27474
28127
  setIsResponding(false);
27475
28128
  }
27476
28129
  prevActiveShellPtyIdRef.current = activeShellPtyId;
27477
28130
  }, [activeShellPtyId, addItem, setIsResponding]);
27478
- (0, import_react97.useEffect)(() => {
28131
+ (0, import_react99.useEffect)(() => {
27479
28132
  if (config.getApprovalMode() === ApprovalMode.YOLO && streamingState === "idle" /* Idle */) {
27480
28133
  const lastUserMessageIndex = history.findLastIndex(
27481
28134
  (item) => item.type === "user" /* USER */
@@ -27489,12 +28142,12 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27489
28142
  }
27490
28143
  }
27491
28144
  }, [streamingState, config, history]);
27492
- (0, import_react97.useEffect)(() => {
28145
+ (0, import_react99.useEffect)(() => {
27493
28146
  if (!isResponding) {
27494
28147
  setRetryStatus(null);
27495
28148
  }
27496
28149
  }, [isResponding]);
27497
- const maybeAddSuppressedToolErrorNote = (0, import_react97.useCallback)(
28150
+ const maybeAddSuppressedToolErrorNote = (0, import_react99.useCallback)(
27498
28151
  (userMessageTimestamp) => {
27499
28152
  if (!isLowErrorVerbosity) {
27500
28153
  return;
@@ -27516,7 +28169,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27516
28169
  },
27517
28170
  [addItem, isLowErrorVerbosity]
27518
28171
  );
27519
- const maybeAddLowVerbosityFailureNote = (0, import_react97.useCallback)(
28172
+ const maybeAddLowVerbosityFailureNote = (0, import_react99.useCallback)(
27520
28173
  (userMessageTimestamp) => {
27521
28174
  if (!isLowErrorVerbosity || config.getDebugMode()) {
27522
28175
  return;
@@ -27535,16 +28188,25 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27535
28188
  },
27536
28189
  [addItem, config, isLowErrorVerbosity]
27537
28190
  );
27538
- const cancelOngoingRequest = (0, import_react97.useCallback)(
27539
- (clearBuffer = true) => {
28191
+ const cancelOngoingRequest = (0, import_react99.useCallback)(
28192
+ async (clearBuffer = true) => {
27540
28193
  if (turnCancelledRef.current) {
27541
28194
  if (clearBuffer) {
27542
28195
  onCancelSubmit(false, true);
27543
28196
  }
28197
+ if (cancellationStateRef.current === "cancelling" /* Cancelling */) {
28198
+ try {
28199
+ await cancelPromiseRef.current;
28200
+ } catch (error) {
28201
+ debugLogger.warn(
28202
+ `Error awaiting schedulePromise on cancel: ${error}`
28203
+ );
28204
+ }
28205
+ }
27544
28206
  return;
27545
28207
  }
27546
- const hasActiveTools = toolCalls.some(
27547
- (tc) => tc.status === CoreToolCallStatus.Executing || tc.status === CoreToolCallStatus.Scheduled || tc.status === CoreToolCallStatus.Validating
28208
+ const hasActiveTools = pendingToolCallRequestsRef.current.length > 0 || toolCalls.some(
28209
+ (tc) => tc.status === CoreToolCallStatus.Executing || tc.status === CoreToolCallStatus.Scheduled || tc.status === CoreToolCallStatus.Validating || tc.status === CoreToolCallStatus.AwaitingApproval
27548
28210
  );
27549
28211
  if (streamingState === "idle" /* Idle */ && !isRespondingRef.current && !hasActiveTools) {
27550
28212
  if (clearBuffer) {
@@ -27562,6 +28224,74 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27562
28224
  }
27563
28225
  abortControllerRef.current.abort();
27564
28226
  cancelAllToolCalls(abortControllerRef.current.signal);
28227
+ try {
28228
+ const client = geminiClient ?? config.getGeminiClient?.();
28229
+ const chat = client?.getChat?.();
28230
+ if (chat) {
28231
+ const seenCallIds = /* @__PURE__ */ new Set();
28232
+ const synthesizedCalls = [];
28233
+ for (const tc of toolCalls) {
28234
+ if (tc.request.isClientInitiated) {
28235
+ continue;
28236
+ }
28237
+ const isAlreadySubmitted = (tc.status === CoreToolCallStatus.Success || tc.status === CoreToolCallStatus.Error || tc.status === CoreToolCallStatus.Cancelled) && tc.responseSubmittedToGemini;
28238
+ if (isAlreadySubmitted) {
28239
+ seenCallIds.add(tc.request.callId);
28240
+ continue;
28241
+ }
28242
+ seenCallIds.add(tc.request.callId);
28243
+ if ((tc.status === CoreToolCallStatus.Success || tc.status === CoreToolCallStatus.Error || tc.status === CoreToolCallStatus.Cancelled) && (tc.response?.responseParts?.length ?? 0) > 0) {
28244
+ synthesizedCalls.push(tc);
28245
+ } else {
28246
+ synthesizedCalls.push(
28247
+ createCancelledToolCall(
28248
+ tc.request,
28249
+ tc.tool,
28250
+ "invocation" in tc ? tc.invocation : void 0
28251
+ )
28252
+ );
28253
+ }
28254
+ }
28255
+ for (const req of pendingToolCallRequestsRef.current) {
28256
+ if (req.isClientInitiated || seenCallIds.has(req.callId)) {
28257
+ continue;
28258
+ }
28259
+ seenCallIds.add(req.callId);
28260
+ synthesizedCalls.push(createCancelledToolCall(req));
28261
+ }
28262
+ const clientHistory = client?.getHistory?.() ?? [];
28263
+ const lastTurn = clientHistory.at(-1);
28264
+ if (lastTurn?.role === "model" && Array.isArray(lastTurn.parts)) {
28265
+ let index = 0;
28266
+ for (const part of lastTurn.parts) {
28267
+ const fc = part.functionCall;
28268
+ if (fc?.name) {
28269
+ const callId = fc.id ?? `${fc.name}-${Date.now()}-${index++}`;
28270
+ if (!seenCallIds.has(callId)) {
28271
+ seenCallIds.add(callId);
28272
+ synthesizedCalls.push(
28273
+ createCancelledToolCall({
28274
+ callId,
28275
+ name: fc.name,
28276
+ args: fc.args ?? {},
28277
+ isClientInitiated: false,
28278
+ prompt_id: lastPromptIdRef.current ?? ""
28279
+ })
28280
+ );
28281
+ }
28282
+ }
28283
+ }
28284
+ }
28285
+ if (synthesizedCalls.length > 0) {
28286
+ const currentModel = client?.getCurrentSequenceModel?.() ?? config.getModel?.() ?? "";
28287
+ chat.recordCompletedToolCalls(currentModel, synthesizedCalls);
28288
+ }
28289
+ }
28290
+ } catch (error) {
28291
+ debugLogger.warn(
28292
+ `Error recording cancelled tool calls on abort: ${error}`
28293
+ );
28294
+ }
27565
28295
  if (pendingHistoryItemRef.current) {
27566
28296
  if (pendingHistoryItemRef.current.type === "tool_group" && pendingHistoryItemRef.current.tools.some(
27567
28297
  (t) => t.name === SHELL_COMMAND_NAME
@@ -27598,6 +28328,35 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27598
28328
  }
27599
28329
  onCancelSubmit(false, clearBuffer);
27600
28330
  setShellInputFocused(false);
28331
+ const schedulePromise = activeSchedulePromiseRef.current;
28332
+ if (schedulePromise) {
28333
+ cancellationStateRef.current = "cancelling" /* Cancelling */;
28334
+ const cancelTask = (async () => {
28335
+ let timeoutId2;
28336
+ try {
28337
+ await Promise.race([
28338
+ Promise.resolve(schedulePromise).catch(() => {
28339
+ }),
28340
+ new Promise((resolve3) => {
28341
+ timeoutId2 = setTimeout(resolve3, 1e3);
28342
+ })
28343
+ ]);
28344
+ } finally {
28345
+ if (timeoutId2 !== void 0) {
28346
+ clearTimeout(timeoutId2);
28347
+ }
28348
+ cancellationStateRef.current = "idle" /* Idle */;
28349
+ }
28350
+ })();
28351
+ cancelPromiseRef.current = cancelTask;
28352
+ try {
28353
+ await cancelTask;
28354
+ } catch (error) {
28355
+ debugLogger.warn(
28356
+ `Error awaiting schedulePromise on cancel: ${error}`
28357
+ );
28358
+ }
28359
+ }
27601
28360
  },
27602
28361
  [
27603
28362
  streamingState,
@@ -27610,13 +28369,15 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27610
28369
  cancelAllToolCalls,
27611
28370
  toolCalls,
27612
28371
  activeShellPtyId,
27613
- setIsResponding
28372
+ setIsResponding,
28373
+ geminiClient,
28374
+ config
27614
28375
  ]
27615
28376
  );
27616
28377
  useKeypress(
27617
28378
  (key) => {
27618
28379
  if (key.name === "escape" && !isShellFocused) {
27619
- cancelOngoingRequest(false);
28380
+ void cancelOngoingRequest(false);
27620
28381
  return true;
27621
28382
  }
27622
28383
  return false;
@@ -27625,7 +28386,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27625
28386
  isActive: streamingState === "responding" /* Responding */ || streamingState === "waiting_for_confirmation" /* WaitingForConfirmation */
27626
28387
  }
27627
28388
  );
27628
- const prepareQueryForGemini = (0, import_react97.useCallback)(
28389
+ const prepareQueryForGemini = (0, import_react99.useCallback)(
27629
28390
  async (query, userMessageTimestamp, abortSignal, prompt_id) => {
27630
28391
  if (turnCancelledRef.current) {
27631
28392
  return { queryToSend: null, shouldProceed: false };
@@ -27731,7 +28492,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27731
28492
  settings
27732
28493
  ]
27733
28494
  );
27734
- const handleContentEvent = (0, import_react97.useCallback)(
28495
+ const handleContentEvent = (0, import_react99.useCallback)(
27735
28496
  (eventValue, currentGeminiMessageBuffer, userMessageTimestamp) => {
27736
28497
  setRetryStatus(null);
27737
28498
  if (turnCancelledRef.current) {
@@ -27772,7 +28533,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27772
28533
  },
27773
28534
  [addItem, pendingHistoryItemRef, setPendingHistoryItem]
27774
28535
  );
27775
- const handleThoughtEvent = (0, import_react97.useCallback)(
28536
+ const handleThoughtEvent = (0, import_react99.useCallback)(
27776
28537
  (eventValue, _userMessageTimestamp) => {
27777
28538
  setThought(eventValue);
27778
28539
  if (getInlineThinkingMode(settings) === "full") {
@@ -27784,7 +28545,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27784
28545
  },
27785
28546
  [addItem, settings, setThought]
27786
28547
  );
27787
- const handleUserCancelledEvent = (0, import_react97.useCallback)(
28548
+ const handleUserCancelledEvent = (0, import_react99.useCallback)(
27788
28549
  (userMessageTimestamp) => {
27789
28550
  if (turnCancelledRef.current) {
27790
28551
  return;
@@ -27819,7 +28580,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27819
28580
  setIsResponding
27820
28581
  ]
27821
28582
  );
27822
- const handleErrorEvent = (0, import_react97.useCallback)(
28583
+ const handleErrorEvent = (0, import_react99.useCallback)(
27823
28584
  (eventValue, userMessageTimestamp) => {
27824
28585
  if (pendingHistoryItemRef.current) {
27825
28586
  addItem(pendingHistoryItemRef.current, userMessageTimestamp);
@@ -27852,7 +28613,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27852
28613
  maybeAddLowVerbosityFailureNote
27853
28614
  ]
27854
28615
  );
27855
- const handleInvalidStreamEvent = (0, import_react97.useCallback)(
28616
+ const handleInvalidStreamEvent = (0, import_react99.useCallback)(
27856
28617
  (eventValue, userMessageTimestamp) => {
27857
28618
  if (pendingHistoryItemRef.current) {
27858
28619
  addItem(pendingHistoryItemRef.current, userMessageTimestamp);
@@ -27898,7 +28659,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27898
28659
  geminiClient
27899
28660
  ]
27900
28661
  );
27901
- const handleCitationEvent = (0, import_react97.useCallback)(
28662
+ const handleCitationEvent = (0, import_react99.useCallback)(
27902
28663
  (text, userMessageTimestamp) => {
27903
28664
  if (!showCitations(settings)) {
27904
28665
  return;
@@ -27911,7 +28672,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27911
28672
  },
27912
28673
  [addItem, pendingHistoryItemRef, setPendingHistoryItem, settings]
27913
28674
  );
27914
- const handleFinishedEvent = (0, import_react97.useCallback)(
28675
+ const handleFinishedEvent = (0, import_react99.useCallback)(
27915
28676
  (event, userMessageTimestamp) => {
27916
28677
  const finishReason = event.value.reason;
27917
28678
  if (!finishReason) {
@@ -27947,7 +28708,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27947
28708
  },
27948
28709
  [addItem]
27949
28710
  );
27950
- const handleChatCompressionEvent = (0, import_react97.useCallback)(
28711
+ const handleChatCompressionEvent = (0, import_react99.useCallback)(
27951
28712
  (eventValue, userMessageTimestamp) => {
27952
28713
  if (pendingHistoryItemRef.current) {
27953
28714
  addItem(pendingHistoryItemRef.current, userMessageTimestamp);
@@ -27973,14 +28734,14 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27973
28734
  },
27974
28735
  [addItem, pendingHistoryItemRef, setPendingHistoryItem, config]
27975
28736
  );
27976
- const handleMaxSessionTurnsEvent = (0, import_react97.useCallback)(
28737
+ const handleMaxSessionTurnsEvent = (0, import_react99.useCallback)(
27977
28738
  () => addItem({
27978
28739
  type: "info",
27979
28740
  text: `The session has reached the maximum number of turns: ${config.getMaxSessionTurns()}. Please update this limit in your setting.json file.`
27980
28741
  }),
27981
28742
  [addItem, config]
27982
28743
  );
27983
- const handleContextWindowWillOverflowEvent = (0, import_react97.useCallback)(
28744
+ const handleContextWindowWillOverflowEvent = (0, import_react99.useCallback)(
27984
28745
  (estimatedRequestTokenCount, remainingTokenCount) => {
27985
28746
  onCancelSubmit(true);
27986
28747
  const limit = tokenLimit(config.getModel());
@@ -27996,7 +28757,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
27996
28757
  },
27997
28758
  [addItem, onCancelSubmit, config]
27998
28759
  );
27999
- const handleChatModelEvent = (0, import_react97.useCallback)(
28760
+ const handleChatModelEvent = (0, import_react99.useCallback)(
28000
28761
  (eventValue, userMessageTimestamp) => {
28001
28762
  if (!settings.merged.ui.showModelInfoInChat) {
28002
28763
  return;
@@ -28015,7 +28776,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
28015
28776
  },
28016
28777
  [addItem, pendingHistoryItemRef, setPendingHistoryItem, settings]
28017
28778
  );
28018
- const handleAgentExecutionStoppedEvent = (0, import_react97.useCallback)(
28779
+ const handleAgentExecutionStoppedEvent = (0, import_react99.useCallback)(
28019
28780
  (reason, userMessageTimestamp, systemMessage, contextCleared) => {
28020
28781
  if (pendingHistoryItemRef.current) {
28021
28782
  addItem(pendingHistoryItemRef.current, userMessageTimestamp);
@@ -28048,7 +28809,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
28048
28809
  maybeAddLowVerbosityFailureNote
28049
28810
  ]
28050
28811
  );
28051
- const handleAgentExecutionBlockedEvent = (0, import_react97.useCallback)(
28812
+ const handleAgentExecutionBlockedEvent = (0, import_react99.useCallback)(
28052
28813
  (reason, userMessageTimestamp, systemMessage, contextCleared) => {
28053
28814
  if (pendingHistoryItemRef.current) {
28054
28815
  addItem(pendingHistoryItemRef.current, userMessageTimestamp);
@@ -28079,7 +28840,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
28079
28840
  maybeAddLowVerbosityFailureNote
28080
28841
  ]
28081
28842
  );
28082
- const processGeminiStreamEvents = (0, import_react97.useCallback)(
28843
+ const processGeminiStreamEvents = (0, import_react99.useCallback)(
28083
28844
  async (stream, userMessageTimestamp, signal, isContinuation, prompt_id) => {
28084
28845
  let geminiMessageBuffer = "";
28085
28846
  const toolCallRequests = [];
@@ -28102,6 +28863,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
28102
28863
  break;
28103
28864
  case GeminiEventType.ToolCallRequest:
28104
28865
  toolCallRequests.push(event.value);
28866
+ pendingToolCallRequestsRef.current.push(event.value);
28105
28867
  break;
28106
28868
  case GeminiEventType.UserCancelled:
28107
28869
  handleUserCancelledEvent(userMessageTimestamp);
@@ -28168,7 +28930,18 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
28168
28930
  addItem(pendingHistoryItemRef.current, userMessageTimestamp);
28169
28931
  setPendingHistoryItem(null);
28170
28932
  }
28171
- await scheduleToolCalls(toolCallRequests, signal);
28933
+ const schedulePromise = Promise.resolve(
28934
+ scheduleToolCalls(toolCallRequests, signal)
28935
+ );
28936
+ activeSchedulePromiseRef.current = schedulePromise;
28937
+ try {
28938
+ await schedulePromise;
28939
+ } finally {
28940
+ if (activeSchedulePromiseRef.current === schedulePromise) {
28941
+ activeSchedulePromiseRef.current = null;
28942
+ }
28943
+ pendingToolCallRequestsRef.current = [];
28944
+ }
28172
28945
  } else {
28173
28946
  const hasVisibleText = geminiMessageBuffer.trim().length > 0;
28174
28947
  if (isContinuation && !hasVisibleText && autoNudgeAttemptCountRef.current < MAX_AUTO_NUDGE_ATTEMPTS) {
@@ -28205,7 +28978,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
28205
28978
  setThought
28206
28979
  ]
28207
28980
  );
28208
- const submitQuery = (0, import_react97.useCallback)(
28981
+ const submitQuery = (0, import_react99.useCallback)(
28209
28982
  async (query, options, prompt_id) => runInDevTraceSpan(
28210
28983
  {
28211
28984
  operation: options?.isContinuation ? GeminiCliOperation.SystemPrompt : GeminiCliOperation.UserPrompt,
@@ -28219,6 +28992,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
28219
28992
  activeQueryIdRef.current = queryId;
28220
28993
  const userMessageTimestamp = Date.now();
28221
28994
  if (!options?.isContinuation) {
28995
+ pendingToolCallRequestsRef.current = [];
28222
28996
  autoNudgeAttemptCountRef.current = 0;
28223
28997
  setModelSwitchedFromQuotaError(false);
28224
28998
  config.setQuotaErrorOccurred(false);
@@ -28370,7 +29144,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
28370
29144
  ]
28371
29145
  );
28372
29146
  submitQueryRef.current = submitQuery;
28373
- const handleApprovalModeChange = (0, import_react97.useCallback)(
29147
+ const handleApprovalModeChange = (0, import_react99.useCallback)(
28374
29148
  async (newApprovalMode) => {
28375
29149
  if (previousApprovalModeRef.current === ApprovalMode.PLAN && newApprovalMode !== ApprovalMode.PLAN && streamingState === "idle" /* Idle */) {
28376
29150
  if (geminiClient) {
@@ -28433,7 +29207,7 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
28433
29207
  },
28434
29208
  [config, toolCalls, geminiClient, streamingState, addItem, onDebugMessage]
28435
29209
  );
28436
- const handleCompletedTools = (0, import_react97.useCallback)(
29210
+ const handleCompletedTools = (0, import_react99.useCallback)(
28437
29211
  async (completedToolCallsFromScheduler) => {
28438
29212
  const completedAndReadyToSubmitTools = completedToolCallsFromScheduler.filter(
28439
29213
  (tc) => {
@@ -28606,13 +29380,13 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
28606
29380
  toolCalls
28607
29381
  ]
28608
29382
  );
28609
- const pendingHistoryItems = (0, import_react97.useMemo)(
29383
+ const pendingHistoryItems = (0, import_react99.useMemo)(
28610
29384
  () => [pendingHistoryItem, ...pendingToolGroupItems].filter(
28611
29385
  (i) => i !== void 0 && i !== null
28612
29386
  ),
28613
29387
  [pendingHistoryItem, pendingToolGroupItems]
28614
29388
  );
28615
- (0, import_react97.useEffect)(() => {
29389
+ (0, import_react99.useEffect)(() => {
28616
29390
  const saveRestorableToolCalls = async () => {
28617
29391
  if (!config.getCheckpointingEnabled()) {
28618
29392
  return;
@@ -28681,475 +29455,6 @@ var useGeminiStream = (geminiClient, history, addItem, config, settings, onDebug
28681
29455
  };
28682
29456
  };
28683
29457
 
28684
- // packages/cli/src/ui/hooks/useAgentStream.ts
28685
- var import_react99 = __toESM(require_react(), 1);
28686
-
28687
- // packages/cli/src/ui/hooks/useTurnActivityMonitor.ts
28688
- var import_react98 = __toESM(require_react(), 1);
28689
- var useTurnActivityMonitor = (streamingState, activePtyId, pendingToolCalls = []) => {
28690
- const [operationStartTime, setOperationStartTime] = (0, import_react98.useState)(0);
28691
- const prevPtyIdRef = (0, import_react98.useRef)(void 0);
28692
- const prevStreamingStateRef = (0, import_react98.useRef)(void 0);
28693
- (0, import_react98.useEffect)(() => {
28694
- const isNowResponding = streamingState === "responding" /* Responding */;
28695
- const wasResponding = prevStreamingStateRef.current === "responding" /* Responding */;
28696
- const ptyChanged = activePtyId !== prevPtyIdRef.current;
28697
- if (isNowResponding && (!wasResponding || ptyChanged)) {
28698
- setOperationStartTime(Date.now());
28699
- } else if (!isNowResponding && wasResponding) {
28700
- setOperationStartTime(0);
28701
- }
28702
- prevPtyIdRef.current = activePtyId;
28703
- prevStreamingStateRef.current = streamingState;
28704
- }, [streamingState, activePtyId]);
28705
- const isRedirectionActive = (0, import_react98.useMemo)(
28706
- () => (
28707
- // Check active tool calls for run_shell_command
28708
- pendingToolCalls.some((tc) => {
28709
- if (tc.request.name !== "run_shell_command") return false;
28710
- const command = tc.request.args?.command || "";
28711
- return hasRedirection(command);
28712
- })
28713
- ),
28714
- [pendingToolCalls]
28715
- );
28716
- return {
28717
- operationStartTime,
28718
- isRedirectionActive
28719
- };
28720
- };
28721
-
28722
- // packages/cli/src/ui/hooks/useAgentStream.ts
28723
- var useAgentStream = ({
28724
- agent,
28725
- addItem,
28726
- onCancelSubmit,
28727
- isShellFocused,
28728
- logger
28729
- }) => {
28730
- const [initError] = (0, import_react99.useState)(null);
28731
- const [retryStatus] = (0, import_react99.useState)(null);
28732
- const [streamingState, setStreamingState] = (0, import_react99.useState)(
28733
- "idle" /* Idle */
28734
- );
28735
- const [thought, setThought] = (0, import_react99.useState)(null);
28736
- const [lastOutputTime, setLastOutputTime] = (0, import_react99.useState)(Date.now());
28737
- const currentStreamIdRef = (0, import_react99.useRef)(null);
28738
- const userMessageTimestampRef = (0, import_react99.useRef)(0);
28739
- const geminiMessageBufferRef = (0, import_react99.useRef)("");
28740
- const [pendingHistoryItem, pendingHistoryItemRef, setPendingHistoryItem] = useStateAndRef(null);
28741
- const [trackedTools, , setTrackedTools] = useStateAndRef([]);
28742
- const [pushedToolCallIds, pushedToolCallIdsRef, setPushedToolCallIds] = useStateAndRef(/* @__PURE__ */ new Set());
28743
- const [_isFirstToolInGroup, isFirstToolInGroupRef, setIsFirstToolInGroup] = useStateAndRef(true);
28744
- const [_hasEmittedBoxInTurn, hasEmittedBoxInTurnRef, setHasEmittedBoxInTurn] = useStateAndRef(false);
28745
- const { startNewPrompt } = useSessionStats();
28746
- const activePtyId = void 0;
28747
- const backgroundTaskCount = 0;
28748
- const isBackgroundTaskVisible = false;
28749
- const toggleBackgroundTasks = (0, import_react99.useCallback)(() => {
28750
- }, []);
28751
- const backgroundCurrentExecution = void 0;
28752
- const backgroundTasks = (0, import_react99.useMemo)(() => /* @__PURE__ */ new Map(), []);
28753
- const dismissBackgroundTask = (0, import_react99.useCallback)(async (_pid) => {
28754
- }, []);
28755
- const pendingToolCalls = (0, import_react99.useMemo)(
28756
- () => trackedTools.map((t) => ({
28757
- request: {
28758
- name: t.originalRequestName || t.name,
28759
- args: { command: t.description },
28760
- callId: t.callId,
28761
- isClientInitiated: t.isClientInitiated ?? false,
28762
- prompt_id: ""
28763
- },
28764
- status: t.status
28765
- })),
28766
- [trackedTools]
28767
- );
28768
- const [loopDetectionConfirmationRequest] = (0, import_react99.useState)(null);
28769
- const flushPendingText = (0, import_react99.useCallback)(() => {
28770
- if (pendingHistoryItemRef.current) {
28771
- addItem(pendingHistoryItemRef.current, userMessageTimestampRef.current);
28772
- setPendingHistoryItem(null);
28773
- geminiMessageBufferRef.current = "";
28774
- }
28775
- }, [addItem, pendingHistoryItemRef, setPendingHistoryItem]);
28776
- const cancelOngoingRequest = (0, import_react99.useCallback)(
28777
- async (clearBuffer = true) => {
28778
- if (agent) {
28779
- await agent.abort();
28780
- setStreamingState("idle" /* Idle */);
28781
- onCancelSubmit(false, clearBuffer);
28782
- }
28783
- },
28784
- [agent, onCancelSubmit]
28785
- );
28786
- const handleApprovalModeChange = (0, import_react99.useCallback)(
28787
- async (newApprovalMode) => {
28788
- debugLogger.debug(`Approval mode changed to ${newApprovalMode} (stub)`);
28789
- },
28790
- []
28791
- );
28792
- const handleEvent = (0, import_react99.useCallback)(
28793
- (event) => {
28794
- setLastOutputTime(Date.now());
28795
- switch (event.type) {
28796
- case "agent_start":
28797
- setStreamingState("responding" /* Responding */);
28798
- break;
28799
- case "agent_end":
28800
- setStreamingState("idle" /* Idle */);
28801
- flushPendingText();
28802
- break;
28803
- case "message":
28804
- if (event.role === "agent") {
28805
- for (const part of event.content) {
28806
- if (part.type === "text") {
28807
- geminiMessageBufferRef.current += part.text;
28808
- const splitPoint = findLastSafeSplitPoint(
28809
- geminiMessageBufferRef.current
28810
- );
28811
- if (splitPoint === geminiMessageBufferRef.current.length) {
28812
- setPendingHistoryItem({
28813
- type: "gemini",
28814
- text: geminiMessageBufferRef.current
28815
- });
28816
- } else {
28817
- const before = geminiMessageBufferRef.current.substring(
28818
- 0,
28819
- splitPoint
28820
- );
28821
- const after = geminiMessageBufferRef.current.substring(splitPoint);
28822
- addItem(
28823
- { type: "gemini", text: before },
28824
- userMessageTimestampRef.current
28825
- );
28826
- geminiMessageBufferRef.current = after;
28827
- setPendingHistoryItem({
28828
- type: "gemini_content",
28829
- text: after
28830
- });
28831
- }
28832
- } else if (part.type === "thought") {
28833
- setThought(parseThought(part.thought));
28834
- }
28835
- }
28836
- }
28837
- break;
28838
- case "tool_request": {
28839
- flushPendingText();
28840
- const legacyState = event._meta?.legacyState;
28841
- const displayName = legacyState?.displayName ?? event.name;
28842
- const isOutputMarkdown = legacyState?.isOutputMarkdown ?? false;
28843
- const desc = legacyState?.description ?? "";
28844
- const fallbackKind = Kind.Other;
28845
- const newCall = {
28846
- callId: event.requestId,
28847
- name: displayName,
28848
- originalRequestName: event.name,
28849
- description: desc,
28850
- display: event.display,
28851
- status: CoreToolCallStatus.Scheduled,
28852
- isClientInitiated: false,
28853
- renderOutputAsMarkdown: isOutputMarkdown,
28854
- kind: legacyState?.kind ?? fallbackKind,
28855
- confirmationDetails: void 0,
28856
- resultDisplay: void 0
28857
- };
28858
- setTrackedTools((prev) => [...prev, newCall]);
28859
- break;
28860
- }
28861
- case "tool_update": {
28862
- setTrackedTools(
28863
- (prev) => prev.map((tc) => {
28864
- if (tc.callId !== event.requestId) return tc;
28865
- const legacyState = event._meta?.legacyState;
28866
- const evtStatus = legacyState?.status;
28867
- let status = tc.status;
28868
- if (evtStatus === "executing")
28869
- status = CoreToolCallStatus.Executing;
28870
- else if (evtStatus === "error") status = CoreToolCallStatus.Error;
28871
- else if (evtStatus === "success")
28872
- status = CoreToolCallStatus.Success;
28873
- const display = event.display?.result;
28874
- const liveOutput = displayContentToString(display) ?? tc.resultDisplay;
28875
- const progressMessage = legacyState?.progressMessage ?? tc.progressMessage;
28876
- const progress = legacyState?.progress ?? tc.progress;
28877
- const progressTotal = legacyState?.progressTotal ?? tc.progressTotal;
28878
- const ptyId = legacyState?.pid ?? tc.ptyId;
28879
- const description = legacyState?.description ?? tc.description;
28880
- return {
28881
- ...tc,
28882
- status,
28883
- display: event.display ? { ...tc.display, ...event.display } : tc.display,
28884
- resultDisplay: liveOutput,
28885
- progressMessage,
28886
- progress,
28887
- progressTotal,
28888
- ptyId,
28889
- description
28890
- };
28891
- })
28892
- );
28893
- break;
28894
- }
28895
- case "tool_response": {
28896
- setTrackedTools(
28897
- (prev) => prev.map((tc) => {
28898
- if (tc.callId !== event.requestId) return tc;
28899
- const legacyState = event._meta?.legacyState;
28900
- const outputFile = legacyState?.outputFile;
28901
- const display = event.display?.result;
28902
- const resultDisplay = displayContentToString(display) ?? tc.resultDisplay;
28903
- return {
28904
- ...tc,
28905
- status: event.isError ? CoreToolCallStatus.Error : CoreToolCallStatus.Success,
28906
- display: event.display ? { ...tc.display, ...event.display } : tc.display,
28907
- resultDisplay,
28908
- outputFile
28909
- };
28910
- })
28911
- );
28912
- break;
28913
- }
28914
- case "error": {
28915
- const message = event._meta?.["code"] === "AGENT_EXECUTION_BLOCKED" ? `Agent execution blocked: ${event.message}` : event.message;
28916
- addItem(
28917
- { type: "error" /* ERROR */, text: message },
28918
- userMessageTimestampRef.current
28919
- );
28920
- break;
28921
- }
28922
- case "initialize":
28923
- case "session_update":
28924
- case "elicitation_request":
28925
- case "elicitation_response":
28926
- case "usage":
28927
- case "custom":
28928
- break;
28929
- default:
28930
- debugLogger.error("Unknown agent event type:", event);
28931
- event;
28932
- break;
28933
- }
28934
- },
28935
- [
28936
- addItem,
28937
- flushPendingText,
28938
- setPendingHistoryItem,
28939
- setTrackedTools,
28940
- setStreamingState,
28941
- setThought,
28942
- setLastOutputTime
28943
- ]
28944
- );
28945
- (0, import_react99.useEffect)(() => {
28946
- const unsubscribe = agent?.subscribe(handleEvent);
28947
- return () => unsubscribe?.();
28948
- }, [agent, handleEvent]);
28949
- useKeypress(
28950
- (key) => {
28951
- if (key.name === "escape" && !isShellFocused) {
28952
- void cancelOngoingRequest(false);
28953
- return true;
28954
- }
28955
- return false;
28956
- },
28957
- {
28958
- isActive: streamingState === "responding" /* Responding */ || streamingState === "waiting_for_confirmation" /* WaitingForConfirmation */
28959
- }
28960
- );
28961
- const submitQuery = (0, import_react99.useCallback)(
28962
- async (query, options, _prompt_id) => {
28963
- if (!agent) return;
28964
- const timestamp = Date.now();
28965
- setLastOutputTime(timestamp);
28966
- userMessageTimestampRef.current = timestamp;
28967
- geminiMessageBufferRef.current = "";
28968
- if (!options?.isContinuation) {
28969
- if (typeof query === "string") {
28970
- addItem({ type: "user" /* USER */, text: query }, timestamp);
28971
- void logger?.logMessage(MessageSenderType.USER, query);
28972
- }
28973
- startNewPrompt();
28974
- }
28975
- const parts = geminiPartsToContentParts(
28976
- typeof query === "string" ? [{ text: query }] : query
28977
- );
28978
- try {
28979
- const { streamId } = await agent.send({
28980
- message: { content: parts }
28981
- });
28982
- currentStreamIdRef.current = streamId;
28983
- } catch (err) {
28984
- addItem(
28985
- { type: "error" /* ERROR */, text: getErrorMessage(err) },
28986
- timestamp
28987
- );
28988
- }
28989
- },
28990
- [agent, addItem, logger, startNewPrompt]
28991
- );
28992
- (0, import_react99.useEffect)(() => {
28993
- if (trackedTools.length > 0) {
28994
- const isNewBatch = !trackedTools.some(
28995
- (tc) => pushedToolCallIdsRef.current.has(tc.callId)
28996
- );
28997
- if (isNewBatch) {
28998
- setPushedToolCallIds(/* @__PURE__ */ new Set());
28999
- setIsFirstToolInGroup(true);
29000
- }
29001
- } else if (streamingState === "idle" /* Idle */) {
29002
- setPushedToolCallIds(/* @__PURE__ */ new Set());
29003
- setIsFirstToolInGroup(true);
29004
- }
29005
- }, [
29006
- trackedTools,
29007
- pushedToolCallIdsRef,
29008
- setPushedToolCallIds,
29009
- setIsFirstToolInGroup,
29010
- streamingState
29011
- ]);
29012
- (0, import_react99.useEffect)(() => {
29013
- if (trackedTools.length === 0) return;
29014
- const allTerminal = trackedTools.every(
29015
- (tc) => tc.status === "success" || tc.status === "error" || tc.status === "cancelled"
29016
- );
29017
- const toolsToPush = trackedTools.filter(
29018
- (tc) => !pushedToolCallIdsRef.current.has(tc.callId)
29019
- );
29020
- if (allTerminal && toolsToPush.length > 0) {
29021
- const newPushed = new Set(pushedToolCallIdsRef.current);
29022
- for (const tc of toolsToPush) {
29023
- newPushed.add(tc.callId);
29024
- }
29025
- const appearance = getToolGroupBorderAppearance(
29026
- { type: "tool_group", tools: trackedTools },
29027
- activePtyId,
29028
- !!isShellFocused,
29029
- [],
29030
- backgroundTasks
29031
- );
29032
- const hasBoxInBatch = toolsToPush.some(
29033
- (tc) => tc.display?.format !== "notice"
29034
- );
29035
- const shouldStartNewBlock = isFirstToolInGroupRef.current || !hasEmittedBoxInTurnRef.current && hasBoxInBatch;
29036
- const historyItem = {
29037
- type: "tool_display_group",
29038
- tools: toolsToPush.map((tc) => ({
29039
- name: tc.name,
29040
- description: tc.description,
29041
- ...tc.display,
29042
- status: tc.status,
29043
- originalRequestName: tc.originalRequestName
29044
- })),
29045
- borderTop: shouldStartNewBlock,
29046
- borderBottom: true,
29047
- ...appearance
29048
- };
29049
- addItem(historyItem);
29050
- setPushedToolCallIds(newPushed);
29051
- if (hasBoxInBatch) {
29052
- setHasEmittedBoxInTurn(true);
29053
- }
29054
- setIsFirstToolInGroup(false);
29055
- }
29056
- }, [
29057
- trackedTools,
29058
- pushedToolCallIdsRef,
29059
- isFirstToolInGroupRef,
29060
- hasEmittedBoxInTurnRef,
29061
- setPushedToolCallIds,
29062
- setIsFirstToolInGroup,
29063
- setHasEmittedBoxInTurn,
29064
- addItem,
29065
- activePtyId,
29066
- isShellFocused,
29067
- backgroundTasks
29068
- ]);
29069
- const pendingToolGroupItems = (0, import_react99.useMemo)(() => {
29070
- const remainingTools = trackedTools.filter(
29071
- (tc) => !pushedToolCallIdsRef.current.has(tc.callId)
29072
- );
29073
- const items = [];
29074
- const appearance = getToolGroupBorderAppearance(
29075
- { type: "tool_group", tools: trackedTools },
29076
- activePtyId,
29077
- !!isShellFocused,
29078
- [],
29079
- backgroundTasks
29080
- );
29081
- if (remainingTools.length > 0) {
29082
- const hasBoxInPending = remainingTools.some(
29083
- (tc) => tc.display?.format !== "notice"
29084
- );
29085
- const shouldStartNewBlock = pushedToolCallIds.size === 0 || !hasEmittedBoxInTurnRef.current && hasBoxInPending;
29086
- items.push({
29087
- type: "tool_display_group",
29088
- tools: remainingTools.map((tc) => ({
29089
- name: tc.name,
29090
- description: tc.description,
29091
- ...tc.display,
29092
- status: tc.status,
29093
- originalRequestName: tc.originalRequestName
29094
- })),
29095
- borderTop: shouldStartNewBlock,
29096
- borderBottom: false,
29097
- ...appearance
29098
- });
29099
- }
29100
- const allTerminal = trackedTools.length > 0 && trackedTools.every(
29101
- (tc) => tc.status === "success" || tc.status === "error" || tc.status === "cancelled"
29102
- );
29103
- const allPushed = trackedTools.length > 0 && trackedTools.every((tc) => pushedToolCallIds.has(tc.callId));
29104
- const anyVisibleInHistory = pushedToolCallIds.size > 0;
29105
- const anyVisibleInPending = remainingTools.length > 0;
29106
- if (trackedTools.length > 0 && !(allTerminal && allPushed) && (anyVisibleInHistory || anyVisibleInPending)) {
29107
- items.push({
29108
- type: "tool_display_group",
29109
- tools: [],
29110
- borderTop: false,
29111
- borderBottom: true,
29112
- ...appearance
29113
- });
29114
- }
29115
- return items;
29116
- }, [
29117
- trackedTools,
29118
- pushedToolCallIds,
29119
- pushedToolCallIdsRef,
29120
- hasEmittedBoxInTurnRef,
29121
- activePtyId,
29122
- isShellFocused,
29123
- backgroundTasks
29124
- ]);
29125
- const pendingHistoryItems = (0, import_react99.useMemo)(
29126
- () => [pendingHistoryItem, ...pendingToolGroupItems].filter(
29127
- (i) => i !== void 0 && i !== null
29128
- ),
29129
- [pendingHistoryItem, pendingToolGroupItems]
29130
- );
29131
- return {
29132
- streamingState,
29133
- submitQuery,
29134
- initError,
29135
- pendingHistoryItems,
29136
- thought,
29137
- cancelOngoingRequest,
29138
- pendingToolCalls,
29139
- handleApprovalModeChange,
29140
- activePtyId,
29141
- loopDetectionConfirmationRequest,
29142
- lastOutputTime,
29143
- backgroundTaskCount,
29144
- isBackgroundTaskVisible,
29145
- toggleBackgroundTasks,
29146
- backgroundCurrentExecution,
29147
- backgroundTasks,
29148
- retryStatus,
29149
- dismissBackgroundTask
29150
- };
29151
- };
29152
-
29153
29458
  // packages/cli/src/ui/hooks/vim.ts
29154
29459
  var import_react100 = __toESM(require_react(), 1);
29155
29460
  var DIGIT_MULTIPLIER = 10;
@@ -32663,6 +32968,49 @@ function useVisibilityToggle() {
32663
32968
  var import_jsx_runtime137 = __toESM(require_jsx_runtime(), 1);
32664
32969
  var SHELL_WIDTH_FRACTION = 0.89;
32665
32970
  var SHELL_HEIGHT_PADDING = 10;
32971
+ var ENTER_SYNCHRONIZED_OUTPUT = "\x1B[?2026h";
32972
+ var EXIT_SYNCHRONIZED_OUTPUT = "\x1B[?2026l";
32973
+ var RESIZE_DEBOUNCE_MS = 100;
32974
+ var RESIZE_CORK_SAFETY_TIMEOUT_MS = 1e3;
32975
+ function discardCorkedStdoutBuffer(stream) {
32976
+ try {
32977
+ const state = stream._writableState;
32978
+ if (state && (state.corked ?? 0) > 0 && Array.isArray(state.buffered)) {
32979
+ const startIndex = state.bufferedIndex ?? 0;
32980
+ const entries = state.buffered.slice(startIndex);
32981
+ let discardedLength = 0;
32982
+ for (const entry of entries) {
32983
+ if (entry?.chunk) {
32984
+ if (typeof entry.chunk === "string") {
32985
+ discardedLength += Buffer.byteLength(
32986
+ entry.chunk,
32987
+ entry.encoding ?? "utf8"
32988
+ );
32989
+ } else if ("length" in entry.chunk && typeof entry.chunk.length === "number") {
32990
+ discardedLength += entry.chunk.length;
32991
+ }
32992
+ }
32993
+ }
32994
+ state.buffered.length = startIndex;
32995
+ state.length = Math.max(0, (state.length ?? 0) - discardedLength);
32996
+ if ("allBuffers" in state) state.allBuffers = true;
32997
+ if ("allNoop" in state) state.allNoop = true;
32998
+ for (const entry of entries) {
32999
+ if (entry && typeof entry.callback === "function") {
33000
+ entry.callback(null);
33001
+ }
33002
+ }
33003
+ }
33004
+ } catch (error) {
33005
+ debugLogger.warn("Failed to discard corked stdout buffer safely:", error);
33006
+ }
33007
+ }
33008
+ function refreshStdoutSize(stream) {
33009
+ const resizableStream = stream;
33010
+ if (typeof resizableStream._refreshSize === "function") {
33011
+ resizableStream._refreshSize();
33012
+ }
33013
+ }
32666
33014
  var AppContainer = (props) => {
32667
33015
  const isHelpDismissKey = useIsHelpDismissKey();
32668
33016
  const keyMatchers = useKeyMatchers();
@@ -32976,12 +33324,89 @@ var AppContainer = (props) => {
32976
33324
  addConfirmUpdateExtensionRequest,
32977
33325
  addItem: historyManager.addItem
32978
33326
  });
33327
+ const isStdoutCorkedRef = (0, import_react119.useRef)(false);
33328
+ const isRefreshingStaticRef = (0, import_react119.useRef)(false);
33329
+ const resizeCorkSafetyTimerRef = (0, import_react119.useRef)(null);
33330
+ const resizeDebounceTimerRef = (0, import_react119.useRef)(null);
33331
+ const lastStdoutColumnsRef = (0, import_react119.useRef)(
33332
+ stdout.columns ?? process12.stdout.columns ?? terminalWidth
33333
+ );
33334
+ const lastRefreshedColumnsRef = (0, import_react119.useRef)(terminalWidth);
33335
+ const terminalWidthRef = (0, import_react119.useRef)(terminalWidth);
33336
+ terminalWidthRef.current = terminalWidth;
33337
+ const clearResizeCorkSafetyTimer = (0, import_react119.useCallback)(() => {
33338
+ if (resizeCorkSafetyTimerRef.current) {
33339
+ clearTimeout(resizeCorkSafetyTimerRef.current);
33340
+ resizeCorkSafetyTimerRef.current = null;
33341
+ }
33342
+ }, []);
33343
+ const clearResizeDebounceTimer = (0, import_react119.useCallback)(() => {
33344
+ if (resizeDebounceTimerRef.current) {
33345
+ clearTimeout(resizeDebounceTimerRef.current);
33346
+ resizeDebounceTimerRef.current = null;
33347
+ }
33348
+ }, []);
33349
+ const corkStdout = (0, import_react119.useCallback)(() => {
33350
+ if (!isStdoutCorkedRef.current && typeof stdout.cork === "function") {
33351
+ stdout.cork();
33352
+ isStdoutCorkedRef.current = true;
33353
+ }
33354
+ }, [stdout]);
33355
+ const uncorkStdout = (0, import_react119.useCallback)(() => {
33356
+ clearResizeCorkSafetyTimer();
33357
+ if (isStdoutCorkedRef.current && typeof stdout.uncork === "function") {
33358
+ isStdoutCorkedRef.current = false;
33359
+ stdout.uncork();
33360
+ }
33361
+ }, [stdout, clearResizeCorkSafetyTimer]);
32979
33362
  const refreshStatic = (0, import_react119.useCallback)(() => {
32980
33363
  if (!isAlternateBuffer && !config.getUseTerminalBuffer()) {
33364
+ clearResizeDebounceTimer();
33365
+ refreshStdoutSize(stdout);
33366
+ if (typeof stdout.prependListener === "function" && stdout.columns !== void 0 && stdout.columns !== terminalWidthRef.current) {
33367
+ corkStdout();
33368
+ clearResizeCorkSafetyTimer();
33369
+ resizeCorkSafetyTimerRef.current = setTimeout(() => {
33370
+ discardCorkedStdoutBuffer(stdout);
33371
+ uncorkStdout();
33372
+ }, RESIZE_CORK_SAFETY_TIMEOUT_MS);
33373
+ return;
33374
+ }
33375
+ clearResizeCorkSafetyTimer();
33376
+ lastRefreshedColumnsRef.current = terminalWidthRef.current;
33377
+ if (typeof stdout.cork === "function") {
33378
+ corkStdout();
33379
+ discardCorkedStdoutBuffer(stdout);
33380
+ isRefreshingStaticRef.current = true;
33381
+ stdout.write(ENTER_SYNCHRONIZED_OUTPUT);
33382
+ }
32981
33383
  stdout.write(base_exports.clearTerminal);
32982
33384
  setHistoryRemountKey((prev) => prev + 1);
32983
33385
  }
32984
- }, [setHistoryRemountKey, isAlternateBuffer, stdout, config]);
33386
+ }, [
33387
+ setHistoryRemountKey,
33388
+ isAlternateBuffer,
33389
+ stdout,
33390
+ config,
33391
+ clearResizeDebounceTimer,
33392
+ clearResizeCorkSafetyTimer,
33393
+ corkStdout,
33394
+ uncorkStdout
33395
+ ]);
33396
+ (0, import_react119.useLayoutEffect)(() => {
33397
+ if (isRefreshingStaticRef.current) {
33398
+ isRefreshingStaticRef.current = false;
33399
+ refreshStdoutSize(stdout);
33400
+ if (stdout.columns !== void 0 && stdout.columns !== lastRefreshedColumnsRef.current) {
33401
+ discardCorkedStdoutBuffer(stdout);
33402
+ stdout.write(EXIT_SYNCHRONIZED_OUTPUT);
33403
+ uncorkStdout();
33404
+ return;
33405
+ }
33406
+ stdout.write(EXIT_SYNCHRONIZED_OUTPUT);
33407
+ uncorkStdout();
33408
+ }
33409
+ }, [historyRemountKey, stdout, uncorkStdout]);
32985
33410
  const shouldUseAlternateScreen = shouldEnterAlternateScreen(
32986
33411
  isAlternateBuffer,
32987
33412
  config.getScreenReader()
@@ -33226,6 +33651,28 @@ Logging in with Google... Restarting Gemini CLI to continue.
33226
33651
  toggleCleanUiDetailsVisible,
33227
33652
  revealCleanUiDetailsTemporarily
33228
33653
  } = useVisibilityToggle();
33654
+ const cancelPromiseRef = (0, import_react119.useRef)(null);
33655
+ const awaitCancelPromise = (0, import_react119.useCallback)(async () => {
33656
+ if (!cancelPromiseRef.current) {
33657
+ return;
33658
+ }
33659
+ let timeoutId2;
33660
+ try {
33661
+ await Promise.race([
33662
+ cancelPromiseRef.current,
33663
+ new Promise((resolve3) => {
33664
+ timeoutId2 = setTimeout(resolve3, 1e3);
33665
+ })
33666
+ ]);
33667
+ } catch (error) {
33668
+ debugLogger.warn(`Error awaiting cancellation: ${error}`);
33669
+ } finally {
33670
+ if (timeoutId2 !== void 0) {
33671
+ clearTimeout(timeoutId2);
33672
+ }
33673
+ cancelPromiseRef.current = null;
33674
+ }
33675
+ }, []);
33229
33676
  const slashCommandActions = (0, import_react119.useMemo)(
33230
33677
  () => ({
33231
33678
  openAuthDialog: () => setAuthState("updating" /* Updating */),
@@ -33242,6 +33689,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
33242
33689
  closeThemeDialog();
33243
33690
  setQuittingMessages(messages);
33244
33691
  setTimeout(async () => {
33692
+ await awaitCancelPromise();
33245
33693
  await runExitCleanup();
33246
33694
  process12.exit(0);
33247
33695
  }, 100);
@@ -33277,6 +33725,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
33277
33725
  openVoiceModelDialog,
33278
33726
  openAgentConfigDialog,
33279
33727
  setQuittingMessages,
33728
+ awaitCancelPromise,
33280
33729
  setDebugMessage,
33281
33730
  setShowPrivacyNotice,
33282
33731
  setCorgiMode,
@@ -33423,6 +33872,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
33423
33872
  // eslint-disable-next-line react-hooks/rules-of-hooks
33424
33873
  useAgentStream({
33425
33874
  agent: streamAgent,
33875
+ config,
33426
33876
  addItem: historyManager.addItem,
33427
33877
  onCancelSubmit,
33428
33878
  isShellFocused: embeddedShellFocused,
@@ -33777,15 +34227,18 @@ ${queuedText}` : queuedText;
33777
34227
  const [showFullTodos, setShowFullTodos] = (0, import_react119.useState)(false);
33778
34228
  const [renderMarkdown, setRenderMarkdown] = (0, import_react119.useState)(true);
33779
34229
  const handleExitRepeat = (0, import_react119.useCallback)(
33780
- (count) => {
34230
+ async (count) => {
33781
34231
  if (count > 2) {
33782
34232
  recordExitFail(config);
33783
34233
  }
33784
34234
  if (count > 1) {
33785
- void handleSlashCommand("/quit", void 0, void 0, false);
34235
+ if (cancelPromiseRef.current) {
34236
+ await awaitCancelPromise();
34237
+ }
34238
+ await handleSlashCommand("/quit", void 0, void 0, false);
33786
34239
  }
33787
34240
  },
33788
- [config, handleSlashCommand]
34241
+ [config, handleSlashCommand, awaitCancelPromise]
33789
34242
  );
33790
34243
  const { pressCount: ctrlCPressCount, handlePress: handleCtrlCPress } = useRepeatedKeyPress({
33791
34244
  windowMs: WARNING_PROMPT_DURATION_MS,
@@ -33813,6 +34266,7 @@ ${queuedText}` : queuedText;
33813
34266
  needsRestart: ideNeedsRestart,
33814
34267
  restartReason: ideTrustRestartReason
33815
34268
  } = useIdeTrustListener();
34269
+ const prevWidthRef = (0, import_react119.useRef)(terminalWidth);
33816
34270
  useIncludeDirsTrust(config, isTrustedFolder, historyManager, setCustomDialog);
33817
34271
  const tabFocusTimeoutRef = (0, import_react119.useRef)(null);
33818
34272
  (0, import_react119.useEffect)(() => {
@@ -33862,6 +34316,64 @@ ${queuedText}` : queuedText;
33862
34316
  setShowIdeRestartPrompt(true);
33863
34317
  }
33864
34318
  }, [ideNeedsRestart]);
34319
+ (0, import_react119.useEffect)(() => {
34320
+ if (isAlternateBuffer || config.getUseTerminalBuffer() || typeof stdout.prependListener !== "function") {
34321
+ return;
34322
+ }
34323
+ const handleResizeStart = () => {
34324
+ const currentColumns = stdout.columns ?? process12.stdout.columns;
34325
+ if (currentColumns !== void 0 && currentColumns !== lastStdoutColumnsRef.current) {
34326
+ lastStdoutColumnsRef.current = currentColumns;
34327
+ corkStdout();
34328
+ clearResizeCorkSafetyTimer();
34329
+ resizeCorkSafetyTimerRef.current = setTimeout(() => {
34330
+ discardCorkedStdoutBuffer(stdout);
34331
+ uncorkStdout();
34332
+ }, RESIZE_CORK_SAFETY_TIMEOUT_MS);
34333
+ }
34334
+ };
34335
+ stdout.prependListener("resize", handleResizeStart);
34336
+ return () => {
34337
+ stdout.off("resize", handleResizeStart);
34338
+ clearResizeDebounceTimer();
34339
+ if (isRefreshingStaticRef.current) {
34340
+ isRefreshingStaticRef.current = false;
34341
+ stdout.write(EXIT_SYNCHRONIZED_OUTPUT);
34342
+ }
34343
+ uncorkStdout();
34344
+ };
34345
+ }, [
34346
+ stdout,
34347
+ isAlternateBuffer,
34348
+ config,
34349
+ corkStdout,
34350
+ uncorkStdout,
34351
+ clearResizeDebounceTimer,
34352
+ clearResizeCorkSafetyTimer
34353
+ ]);
34354
+ (0, import_react119.useEffect)(() => {
34355
+ if (prevWidthRef.current === terminalWidth) {
34356
+ return;
34357
+ }
34358
+ prevWidthRef.current = terminalWidth;
34359
+ if (isAlternateBuffer || config.getUseTerminalBuffer()) {
34360
+ clearResizeDebounceTimer();
34361
+ return;
34362
+ }
34363
+ clearResizeDebounceTimer();
34364
+ resizeDebounceTimerRef.current = setTimeout(() => {
34365
+ refreshStatic();
34366
+ }, RESIZE_DEBOUNCE_MS);
34367
+ return () => {
34368
+ clearResizeDebounceTimer();
34369
+ };
34370
+ }, [
34371
+ terminalWidth,
34372
+ refreshStatic,
34373
+ clearResizeDebounceTimer,
34374
+ isAlternateBuffer,
34375
+ config
34376
+ ]);
33865
34377
  (0, import_react119.useEffect)(() => {
33866
34378
  const unsubscribe = ideContextStore.subscribe(setIdeContextState);
33867
34379
  setIdeContextState(ideContextStore.get());
@@ -33916,7 +34428,10 @@ ${queuedText}` : queuedText;
33916
34428
  return true;
33917
34429
  }
33918
34430
  if (keyMatchers["basic.quit" /* QUIT */](key)) {
33919
- void cancelOngoingRequest?.();
34431
+ const cancelPromise = cancelOngoingRequest?.();
34432
+ if (cancelPromise) {
34433
+ cancelPromiseRef.current = cancelPromise;
34434
+ }
33920
34435
  handleCtrlCPress();
33921
34436
  return true;
33922
34437
  } else if (keyMatchers["basic.exit" /* EXIT */](key)) {
@@ -33983,7 +34498,7 @@ ${queuedText}` : queuedText;
33983
34498
  if (keyMatchers["app.showErrorDetails" /* SHOW_ERROR_DETAILS */](key)) {
33984
34499
  if (settings.merged.general.devtools) {
33985
34500
  void (async () => {
33986
- const { toggleDevToolsPanel } = await import("./devtoolsService-E3YLHACW.js");
34501
+ const { toggleDevToolsPanel } = await import("./devtoolsService-WP2OPVPB.js");
33987
34502
  await toggleDevToolsPanel(
33988
34503
  config,
33989
34504
  showErrorDetails,