summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/components/ConsolePatcher.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/ui/components/ConsolePatcher.tsx')
-rw-r--r--packages/cli/src/ui/components/ConsolePatcher.tsx85
1 files changed, 85 insertions, 0 deletions
diff --git a/packages/cli/src/ui/components/ConsolePatcher.tsx b/packages/cli/src/ui/components/ConsolePatcher.tsx
new file mode 100644
index 00000000..7070fbe4
--- /dev/null
+++ b/packages/cli/src/ui/components/ConsolePatcher.tsx
@@ -0,0 +1,85 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState, useEffect, Key } from 'react';
+import { Box, Text } from 'ink';
+import util from 'util';
+
+interface ConsoleMessage {
+ id: Key;
+ type: 'log' | 'warn' | 'error';
+ content: string;
+}
+
+// Using a module-level counter for unique IDs.
+// This ensures IDs are unique across messages.
+let messageIdCounter = 0;
+
+export const ConsoleOutput: React.FC = () => {
+ const [messages, setMessages] = useState<ConsoleMessage[]>([]);
+
+ useEffect(() => {
+ const originalConsoleLog = console.log;
+ const originalConsoleWarn = console.warn;
+ const originalConsoleError = console.error;
+
+ const formatArgs = (args: unknown[]): string => util.format(...args);
+ const addMessage = (type: 'log' | 'warn' | 'error', args: unknown[]) => {
+ setMessages((prevMessages) => [
+ ...prevMessages,
+ {
+ id: `console-msg-${messageIdCounter++}`,
+ type,
+ content: formatArgs(args),
+ },
+ ]);
+ };
+
+ // It's patching time
+ console.log = (...args: unknown[]) => addMessage('log', args);
+ console.warn = (...args: unknown[]) => addMessage('warn', args);
+ console.error = (...args: unknown[]) => addMessage('error', args);
+
+ return () => {
+ console.log = originalConsoleLog;
+ console.warn = originalConsoleWarn;
+ console.error = originalConsoleError;
+ };
+ }, []);
+
+ return (
+ <Box flexDirection="column">
+ {messages.map((msg) => {
+ const textProps: { color?: string } = {};
+ let prefix = '';
+
+ switch (msg.type) {
+ case 'warn':
+ textProps.color = 'yellow';
+ prefix = 'WARN: ';
+ break;
+ case 'error':
+ textProps.color = 'red';
+ prefix = 'ERROR: ';
+ break;
+ case 'log':
+ default:
+ prefix = 'LOG: ';
+ break;
+ }
+
+ return (
+ <Box key={msg.id}>
+ <Text {...textProps}>
+ {prefix}
+ {msg.content}
+ </Text>
+ </Box>
+ );
+ })}
+ </Box>
+ );
+};