From c202cf314592222c548ddf18b489417d8fd434fa Mon Sep 17 00:00:00 2001 From: matt korwel Date: Wed, 11 Feb 2026 09:17:01 -0600 Subject: [PATCH] perf(cli): truncate large debug logs and limit message history (#18663) --- .../cli/src/ui/hooks/useConsoleMessages.ts | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/ui/hooks/useConsoleMessages.ts b/packages/cli/src/ui/hooks/useConsoleMessages.ts index 44cb0a5656..69fa7fe6e4 100644 --- a/packages/cli/src/ui/hooks/useConsoleMessages.ts +++ b/packages/cli/src/ui/hooks/useConsoleMessages.ts @@ -31,6 +31,7 @@ function consoleMessagesReducer( state: ConsoleMessageItem[], action: Action, ): ConsoleMessageItem[] { + const MAX_CONSOLE_MESSAGES = 1000; switch (action.type) { case 'ADD_MESSAGES': { const newMessages = [...state]; @@ -51,6 +52,12 @@ function consoleMessagesReducer( newMessages.push({ ...queuedMessage, count: 1 }); } } + + // Limit the number of messages to prevent memory issues + if (newMessages.length > MAX_CONSOLE_MESSAGES) { + return newMessages.slice(newMessages.length - MAX_CONSOLE_MESSAGES); + } + return newMessages; } case 'CLEAR': @@ -91,9 +98,17 @@ export function useConsoleMessages(): UseConsoleMessagesReturn { useEffect(() => { const handleConsoleLog = (payload: ConsoleLogPayload) => { + let content = payload.content; + const MAX_CONSOLE_MSG_LENGTH = 10000; + if (content.length > MAX_CONSOLE_MSG_LENGTH) { + content = + content.slice(0, MAX_CONSOLE_MSG_LENGTH) + + `... [Truncated ${content.length - MAX_CONSOLE_MSG_LENGTH} characters]`; + } + handleNewMessage({ type: payload.type, - content: payload.content, + content, count: 1, }); }; @@ -102,10 +117,18 @@ export function useConsoleMessages(): UseConsoleMessagesReturn { isStderr: boolean; chunk: Uint8Array | string; }) => { - const content = + let content = typeof payload.chunk === 'string' ? payload.chunk : new TextDecoder().decode(payload.chunk); + + const MAX_OUTPUT_CHUNK_LENGTH = 10000; + if (content.length > MAX_OUTPUT_CHUNK_LENGTH) { + content = + content.slice(0, MAX_OUTPUT_CHUNK_LENGTH) + + `... [Truncated ${content.length - MAX_OUTPUT_CHUNK_LENGTH} characters]`; + } + // It would be nice if we could show stderr as 'warn' but unfortunately // we log non warning info to stderr before the app starts so that would // be misleading.