wave-code 0.6.3 → 0.6.4

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.
@@ -21,7 +21,7 @@ export const CommandOutputDisplay = ({ block, isExpanded = false, }) => {
21
21
  return "red";
22
22
  return "gray"; // Unknown state
23
23
  };
24
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: getStatusColor(), children: "$ " }), _jsx(Text, { color: "white", children: command })] }), output && (_jsx(Box, { paddingLeft: 2, height: isExpanded
24
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: getStatusColor(), children: "! " }), _jsx(Text, { color: "white", children: command })] }), output && (_jsx(Box, { paddingLeft: 2, height: isExpanded
25
25
  ? undefined
26
26
  : Math.min(output.split("\n").length, MAX_LINES), overflow: "hidden", children: _jsx(Text, { color: "gray", children: isOverflowing
27
27
  ? output.split("\n").slice(-MAX_LINES).join("\n")
@@ -9,5 +9,5 @@ export const CompressDisplay = ({ block }) => {
9
9
  }
10
10
  return { displayContent: content };
11
11
  }, [content]);
12
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsx(Text, { children: "\uD83D\uDCE6 Compressed Messages" }) }), content && (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: _jsx(Text, { color: "white", children: displayContent }) }) }))] }));
12
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsx(Text, { children: "Compressed Messages" }) }), content && (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: _jsx(Text, { color: "white", children: displayContent }) }) }))] }));
13
13
  };
@@ -1 +1 @@
1
- {"version":3,"file":"FileSelector.d.ts","sourceRoot":"","sources":["../../src/components/FileSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA2HpD,CAAC"}
1
+ {"version":3,"file":"FileSelector.d.ts","sourceRoot":"","sources":["../../src/components/FileSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqHpD,CAAC"}
@@ -24,7 +24,7 @@ export const FileSelector = ({ files, searchQuery, onSelect, onCancel, }) => {
24
24
  }
25
25
  });
26
26
  if (files.length === 0) {
27
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "yellow", children: ["\uD83D\uDCC1 No files found for \"", searchQuery, "\""] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
27
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "yellow", children: ["No files found for \"", searchQuery, "\""] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
28
28
  }
29
29
  const maxDisplay = 10;
30
30
  // Calculate display window start and end positions
@@ -39,10 +39,9 @@ export const FileSelector = ({ files, searchQuery, onSelect, onCancel, }) => {
39
39
  };
40
40
  };
41
41
  const { startIndex, endIndex, displayFiles } = getDisplayWindow();
42
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "cyan", bold: true, children: ["\uD83D\uDCC1 Select File/Directory", " ", searchQuery && `(filtering: "${searchQuery}")`] }), startIndex > 0 && (_jsxs(Text, { dimColor: true, children: ["... ", startIndex, " more files above"] })), displayFiles.map((fileItem, displayIndex) => {
42
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "cyan", bold: true, children: ["Select File/Directory ", searchQuery && `(filtering: "${searchQuery}")`] }), startIndex > 0 && (_jsxs(Text, { dimColor: true, children: ["... ", startIndex, " more files above"] })), displayFiles.map((fileItem, displayIndex) => {
43
43
  const actualIndex = startIndex + displayIndex;
44
44
  const isSelected = actualIndex === selectedIndex;
45
- const icon = fileItem.type === "directory" ? "📁" : "📄";
46
- return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "cyan" : undefined, children: [" ", icon, " ", fileItem.path] }) }, fileItem.path));
47
- }), endIndex < files.length && (_jsxs(Text, { dimColor: true, children: ["... ", files.length - endIndex, " more files below"] })), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate, Enter/Tab to select, Escape to cancel" }), _jsxs(Text, { dimColor: true, children: [", File ", selectedIndex + 1, " of ", files.length] })] })] }));
45
+ return (_jsx(Box, { children: _jsx(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "cyan" : undefined, children: fileItem.path }) }, fileItem.path));
46
+ }), endIndex < files.length && (_jsxs(Text, { dimColor: true, children: ["... ", files.length - endIndex, " more files below"] })), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate, Enter/Tab to select, Escape to cancel" }) })] }));
48
47
  };
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Box, Text } from "ink";
3
3
  export const LoadingIndicator = ({ isLoading = false, isCommandRunning = false, isCompressing = false, latestTotalTokens = 0, }) => {
4
- return (_jsxs(Box, { flexDirection: "column", children: [isLoading && (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "\u273B AI is thinking... " }), latestTotalTokens > 0 && (_jsxs(_Fragment, { children: [_jsxs(Text, { color: "gray", dimColor: true, children: ["|", " "] }), _jsx(Text, { color: "blue", bold: true, children: latestTotalTokens.toLocaleString() }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "tokens", " "] })] })), _jsxs(Text, { color: "gray", dimColor: true, children: ["|", " "] }), _jsx(Text, { color: "red", bold: true, children: "Esc" }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "to abort"] })] })), isCommandRunning && _jsx(Text, { color: "blue", children: "\uD83D\uDE80 Command is running..." }), isCompressing && (_jsx(Text, { color: "magenta", children: "\uD83D\uDDDC\uFE0F Compressing message history..." }))] }));
4
+ return (_jsxs(Box, { flexDirection: "column", children: [isLoading && !isCompressing && (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "\u273B AI is thinking... " }), latestTotalTokens > 0 && (_jsxs(_Fragment, { children: [_jsxs(Text, { color: "gray", dimColor: true, children: ["|", " "] }), _jsx(Text, { color: "blue", bold: true, children: latestTotalTokens.toLocaleString() }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "tokens", " "] })] })), _jsxs(Text, { color: "gray", dimColor: true, children: ["|", " "] }), _jsx(Text, { color: "red", bold: true, children: "Esc" }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "to abort"] })] })), isCommandRunning && _jsx(Text, { color: "blue", children: "\u273B Command is running..." }), isCompressing && (_jsx(Text, { color: "magenta", children: "\u273B Compressing message history..." }))] }));
5
5
  };
6
6
  LoadingIndicator.displayName = "LoadingIndicator";
@@ -9,5 +9,5 @@ import { Markdown } from "./Markdown.js";
9
9
  export const MessageItem = ({ message, isExpanded }) => {
10
10
  if (message.blocks.length === 0)
11
11
  return null;
12
- return (_jsx(Box, { flexDirection: "column", gap: 1, marginTop: 1, children: _jsx(Box, { flexDirection: "column", gap: 1, children: message.blocks.map((block, blockIndex) => (_jsxs(Box, { children: [block.type === "text" && block.content.trim() && (_jsxs(Box, { children: [block.customCommandContent && (_jsx(Text, { color: "cyan", bold: true, children: "\u26A1" })), block.source === MessageSource.HOOK && (_jsx(Text, { color: "magenta", bold: true, children: "\uD83D\uDD17" })), message.role === "user" ? (_jsx(Text, { backgroundColor: "gray", color: "white", children: block.content })) : (_jsx(Markdown, { children: block.content }))] })), block.type === "error" && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["\u274C Error: ", block.content] }) })), block.type === "command_output" && (_jsx(CommandOutputDisplay, { block: block, isExpanded: isExpanded })), block.type === "tool" && (_jsx(ToolDisplay, { block: block, isExpanded: isExpanded })), block.type === "image" && (_jsxs(Box, { children: [_jsx(Text, { color: "magenta", bold: true, children: "\uD83D\uDCF7 Image" }), block.imageUrls && block.imageUrls.length > 0 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" ", "(", block.imageUrls.length, ")"] }))] })), block.type === "compress" && (_jsx(CompressDisplay, { block: block, isExpanded: isExpanded })), block.type === "reasoning" && _jsx(ReasoningDisplay, { block: block })] }, blockIndex))) }) }));
12
+ return (_jsx(Box, { flexDirection: "column", gap: 1, marginTop: 1, children: _jsx(Box, { flexDirection: "column", gap: 1, children: message.blocks.map((block, blockIndex) => (_jsxs(Box, { children: [block.type === "text" && block.content.trim() && (_jsxs(Box, { children: [block.customCommandContent && (_jsx(Text, { color: "cyan", bold: true, children: "$" })), block.source === MessageSource.HOOK && (_jsx(Text, { color: "magenta", bold: true, children: "~" })), message.role === "user" ? (_jsx(Text, { backgroundColor: "gray", color: "white", children: block.content })) : (_jsx(Markdown, { children: block.content }))] })), block.type === "error" && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", block.content] }) })), block.type === "command_output" && (_jsx(CommandOutputDisplay, { block: block, isExpanded: isExpanded })), block.type === "tool" && (_jsx(ToolDisplay, { block: block, isExpanded: isExpanded })), block.type === "image" && (_jsxs(Box, { children: [_jsx(Text, { color: "magenta", bold: true, children: "# Image" }), block.imageUrls && block.imageUrls.length > 0 && (_jsxs(Text, { color: "gray", dimColor: true, children: [" ", "(", block.imageUrls.length, ")"] }))] })), block.type === "compress" && (_jsx(CompressDisplay, { block: block, isExpanded: isExpanded })), block.type === "reasoning" && _jsx(ReasoningDisplay, { block: block })] }, blockIndex))) }) }));
13
13
  };
@@ -21,7 +21,7 @@ export const ToolDisplay = ({ block, isExpanded = false, }) => {
21
21
  if (!hasImages())
22
22
  return "";
23
23
  const imageCount = block.images.length;
24
- return imageCount === 1 ? "🖼️" : `🖼️×${imageCount}`;
24
+ return imageCount === 1 ? "#" : `#×${imageCount}`;
25
25
  };
26
26
  const toolName = name ? String(name) : "Tool";
27
27
  // Get shortResult, if not available show last 5 lines of result
@@ -1 +1 @@
1
- {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"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"}
@@ -18,7 +18,6 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
18
18
  // Message Display State
19
19
  const [isExpanded, setIsExpanded] = useState(false);
20
20
  const isExpandedRef = useRef(isExpanded);
21
- const frozenMessagesRef = useRef(null);
22
21
  useEffect(() => {
23
22
  isExpandedRef.current = isExpanded;
24
23
  }, [isExpanded]);
@@ -73,10 +72,7 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
73
72
  const initializeAgent = async () => {
74
73
  const callbacks = {
75
74
  onMessagesChange: (newMessages) => {
76
- if (isExpandedRef.current) {
77
- frozenMessagesRef.current = [...newMessages];
78
- }
79
- else {
75
+ if (!isExpandedRef.current) {
80
76
  setMessages([...newMessages]);
81
77
  }
82
78
  },
@@ -333,9 +329,22 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, }) => {
333
329
  // Clear terminal screen when expanded state changes
334
330
  setIsExpanded((prev) => {
335
331
  const newExpanded = !prev;
336
- if (!newExpanded && frozenMessagesRef.current) {
337
- setMessages(frozenMessagesRef.current);
338
- frozenMessagesRef.current = null;
332
+ if (newExpanded) {
333
+ // Transitioning to EXPANDED: Freeze the current view
334
+ // Deep copy the last message to ensure it doesn't update if the agent is still writing to it
335
+ setMessages((currentMessages) => {
336
+ if (currentMessages.length === 0)
337
+ return currentMessages;
338
+ const lastMessage = currentMessages[currentMessages.length - 1];
339
+ const frozenLastMessage = JSON.parse(JSON.stringify(lastMessage));
340
+ return [...currentMessages.slice(0, -1), frozenLastMessage];
341
+ });
342
+ }
343
+ else {
344
+ // Transitioning to COLLAPSED: Restore from agent's actual state
345
+ if (agentRef.current) {
346
+ setMessages([...agentRef.current.messages]);
347
+ }
339
348
  }
340
349
  return newExpanded;
341
350
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-code",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "description": "CLI-based code assistant powered by AI, built with React and Ink",
5
5
  "repository": {
6
6
  "type": "git",
@@ -37,7 +37,7 @@
37
37
  "react": "^19.2.4",
38
38
  "react-dom": "19.2.4",
39
39
  "yargs": "^17.7.2",
40
- "wave-agent-sdk": "0.6.3"
40
+ "wave-agent-sdk": "0.6.4"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/react": "^19.1.8",
@@ -33,7 +33,7 @@ export const CommandOutputDisplay: React.FC<CommandOutputDisplayProps> = ({
33
33
  return (
34
34
  <Box flexDirection="column">
35
35
  <Box>
36
- <Text color={getStatusColor()}>$ </Text>
36
+ <Text color={getStatusColor()}>! </Text>
37
37
  <Text color="white">{command}</Text>
38
38
  </Box>
39
39
 
@@ -21,7 +21,7 @@ export const CompressDisplay: React.FC<CompressDisplayProps> = ({ block }) => {
21
21
  return (
22
22
  <Box flexDirection="column">
23
23
  <Box>
24
- <Text>📦 Compressed Messages</Text>
24
+ <Text>Compressed Messages</Text>
25
25
  </Box>
26
26
 
27
27
  {content && (
@@ -53,7 +53,7 @@ export const FileSelector: React.FC<FileSelectorProps> = ({
53
53
  borderLeft={false}
54
54
  borderRight={false}
55
55
  >
56
- <Text color="yellow">📁 No files found for "{searchQuery}"</Text>
56
+ <Text color="yellow">No files found for "{searchQuery}"</Text>
57
57
  <Text dimColor>Press Escape to cancel</Text>
58
58
  </Box>
59
59
  );
@@ -92,8 +92,7 @@ export const FileSelector: React.FC<FileSelectorProps> = ({
92
92
  borderRight={false}
93
93
  >
94
94
  <Text color="cyan" bold>
95
- 📁 Select File/Directory{" "}
96
- {searchQuery && `(filtering: "${searchQuery}")`}
95
+ Select File/Directory {searchQuery && `(filtering: "${searchQuery}")`}
97
96
  </Text>
98
97
 
99
98
  {/* Show hint for more files above */}
@@ -104,7 +103,6 @@ export const FileSelector: React.FC<FileSelectorProps> = ({
104
103
  {displayFiles.map((fileItem, displayIndex) => {
105
104
  const actualIndex = startIndex + displayIndex;
106
105
  const isSelected = actualIndex === selectedIndex;
107
- const icon = fileItem.type === "directory" ? "📁" : "📄";
108
106
 
109
107
  return (
110
108
  <Box key={fileItem.path}>
@@ -112,8 +110,7 @@ export const FileSelector: React.FC<FileSelectorProps> = ({
112
110
  color={isSelected ? "black" : "white"}
113
111
  backgroundColor={isSelected ? "cyan" : undefined}
114
112
  >
115
- {" "}
116
- {icon} {fileItem.path}
113
+ {fileItem.path}
117
114
  </Text>
118
115
  </Box>
119
116
  );
@@ -124,13 +121,10 @@ export const FileSelector: React.FC<FileSelectorProps> = ({
124
121
  <Text dimColor>... {files.length - endIndex} more files below</Text>
125
122
  )}
126
123
 
127
- <Box marginTop={1}>
124
+ <Box>
128
125
  <Text dimColor>
129
126
  Use ↑↓ to navigate, Enter/Tab to select, Escape to cancel
130
127
  </Text>
131
- <Text dimColor>
132
- , File {selectedIndex + 1} of {files.length}
133
- </Text>
134
128
  </Box>
135
129
  </Box>
136
130
  );
@@ -16,7 +16,7 @@ export const LoadingIndicator = ({
16
16
  }: LoadingIndicatorProps) => {
17
17
  return (
18
18
  <Box flexDirection="column">
19
- {isLoading && (
19
+ {isLoading && !isCompressing && (
20
20
  <Box>
21
21
  <Text color="yellow">✻ AI is thinking... </Text>
22
22
  {latestTotalTokens > 0 && (
@@ -45,9 +45,9 @@ export const LoadingIndicator = ({
45
45
  </Text>
46
46
  </Box>
47
47
  )}
48
- {isCommandRunning && <Text color="blue">🚀 Command is running...</Text>}
48
+ {isCommandRunning && <Text color="blue">✻ Command is running...</Text>}
49
49
  {isCompressing && (
50
- <Text color="magenta">🗜️ Compressing message history...</Text>
50
+ <Text color="magenta">✻ Compressing message history...</Text>
51
51
  )}
52
52
  </Box>
53
53
  );
@@ -26,12 +26,12 @@ export const MessageItem = ({ message, isExpanded }: MessageItemProps) => {
26
26
  <Box>
27
27
  {block.customCommandContent && (
28
28
  <Text color="cyan" bold>
29
-
29
+ $
30
30
  </Text>
31
31
  )}
32
32
  {block.source === MessageSource.HOOK && (
33
33
  <Text color="magenta" bold>
34
- 🔗
34
+ ~
35
35
  </Text>
36
36
  )}
37
37
  {message.role === "user" ? (
@@ -46,7 +46,7 @@ export const MessageItem = ({ message, isExpanded }: MessageItemProps) => {
46
46
 
47
47
  {block.type === "error" && (
48
48
  <Box>
49
- <Text color="red">❌ Error: {block.content}</Text>
49
+ <Text color="red">Error: {block.content}</Text>
50
50
  </Box>
51
51
  )}
52
52
 
@@ -61,7 +61,7 @@ export const MessageItem = ({ message, isExpanded }: MessageItemProps) => {
61
61
  {block.type === "image" && (
62
62
  <Box>
63
63
  <Text color="magenta" bold>
64
- 📷 Image
64
+ # Image
65
65
  </Text>
66
66
  {block.imageUrls && block.imageUrls.length > 0 && (
67
67
  <Text color="gray" dimColor>
@@ -32,7 +32,7 @@ export const ToolDisplay: React.FC<ToolDisplayProps> = ({
32
32
  const getImageIndicator = () => {
33
33
  if (!hasImages()) return "";
34
34
  const imageCount = block.images!.length;
35
- return imageCount === 1 ? "🖼️" : `🖼️×${imageCount}`;
35
+ return imageCount === 1 ? "#" : `#×${imageCount}`;
36
36
  };
37
37
 
38
38
  const toolName = name ? String(name) : "Tool";
@@ -120,7 +120,6 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
120
120
  // Message Display State
121
121
  const [isExpanded, setIsExpanded] = useState(false);
122
122
  const isExpandedRef = useRef(isExpanded);
123
- const frozenMessagesRef = useRef<Message[] | null>(null);
124
123
 
125
124
  useEffect(() => {
126
125
  isExpandedRef.current = isExpanded;
@@ -227,9 +226,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
227
226
  const initializeAgent = async () => {
228
227
  const callbacks: AgentCallbacks = {
229
228
  onMessagesChange: (newMessages) => {
230
- if (isExpandedRef.current) {
231
- frozenMessagesRef.current = [...newMessages];
232
- } else {
229
+ if (!isExpandedRef.current) {
233
230
  setMessages([...newMessages]);
234
231
  }
235
232
  },
@@ -528,9 +525,20 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
528
525
  // Clear terminal screen when expanded state changes
529
526
  setIsExpanded((prev) => {
530
527
  const newExpanded = !prev;
531
- if (!newExpanded && frozenMessagesRef.current) {
532
- setMessages(frozenMessagesRef.current);
533
- frozenMessagesRef.current = null;
528
+ if (newExpanded) {
529
+ // Transitioning to EXPANDED: Freeze the current view
530
+ // Deep copy the last message to ensure it doesn't update if the agent is still writing to it
531
+ setMessages((currentMessages) => {
532
+ if (currentMessages.length === 0) return currentMessages;
533
+ const lastMessage = currentMessages[currentMessages.length - 1];
534
+ const frozenLastMessage = JSON.parse(JSON.stringify(lastMessage));
535
+ return [...currentMessages.slice(0, -1), frozenLastMessage];
536
+ });
537
+ } else {
538
+ // Transitioning to COLLAPSED: Restore from agent's actual state
539
+ if (agentRef.current) {
540
+ setMessages([...agentRef.current.messages]);
541
+ }
534
542
  }
535
543
  return newExpanded;
536
544
  });