wave-code 0.13.4 → 0.13.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ChatInterface.d.ts","sourceRoot":"","sources":["../../src/components/ChatInterface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAa3D,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EA+HjC,CAAC"}
1
+ {"version":3,"file":"ChatInterface.d.ts","sourceRoot":"","sources":["../../src/components/ChatInterface.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAa3D,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAgIjC,CAAC"}
@@ -37,5 +37,5 @@ export const ChatInterface = () => {
37
37
  ]);
38
38
  if (!sessionId)
39
39
  return null;
40
- return (_jsxs(Box, { ref: chatInterfaceRef, flexDirection: "column", children: [_jsx(MessageList, { messages: displayMessages, isExpanded: isExpanded, version: version, workdir: workdir, forceStatic: forceStatic }, remountKey), !isConfirmationVisible && !isExpanded && (_jsxs(_Fragment, { children: [(isLoading || isCommandRunning || isCompressing) && (_jsx(LoadingIndicator, { isLoading: isLoading, isCommandRunning: isCommandRunning, isCompressing: isCompressing, latestTotalTokens: latestTotalTokens })), _jsx(TaskList, {}), _jsx(QueuedMessageList, {}), _jsx(InputBox, { isLoading: isLoading, isCommandRunning: isCommandRunning, sendMessage: sendMessage, abortMessage: abortMessage, mcpServers: mcpServers, connectMcpServer: connectMcpServer, disconnectMcpServer: disconnectMcpServer, slashCommands: slashCommands, hasSlashCommand: hasSlashCommand })] })), isConfirmationVisible && (_jsxs(_Fragment, { children: [forceStatic ? (_jsx(Static, { items: [{ key: "confirmation-details" }], children: () => (_jsx(ConfirmationDetails, { toolName: confirmingTool.name, toolInput: confirmingTool.input, planContent: confirmingTool.planContent, isExpanded: isExpanded })) })) : (_jsx(ConfirmationDetails, { toolName: confirmingTool.name, toolInput: confirmingTool.input, planContent: confirmingTool.planContent, isExpanded: isExpanded })), _jsx(ConfirmationSelector, { toolName: confirmingTool.name, toolInput: confirmingTool.input, suggestedPrefix: confirmingTool.suggestedPrefix, hidePersistentOption: confirmingTool.hidePersistentOption, isExpanded: isExpanded, onDecision: handleConfirmationDecision, onCancel: handleConfirmationCancel, onAbort: abortMessage })] }))] }));
40
+ return (_jsxs(Box, { ref: chatInterfaceRef, flexDirection: "column", children: [_jsx(MessageList, { messages: displayMessages, isExpanded: isExpanded, version: version, workdir: workdir, forceStatic: forceStatic }, remountKey), !isConfirmationVisible && !isExpanded && (_jsxs(_Fragment, { children: [(isLoading || isCommandRunning || isCompressing) && (_jsx(LoadingIndicator, { isLoading: isLoading, isCommandRunning: isCommandRunning, isCompressing: isCompressing, latestTotalTokens: latestTotalTokens })), _jsx(TaskList, {}), _jsx(QueuedMessageList, {}), _jsx(InputBox, { isLoading: isLoading, isCommandRunning: isCommandRunning, sendMessage: sendMessage, abortMessage: abortMessage, mcpServers: mcpServers, connectMcpServer: connectMcpServer, disconnectMcpServer: disconnectMcpServer, slashCommands: slashCommands, hasSlashCommand: hasSlashCommand })] })), isConfirmationVisible && (_jsxs(_Fragment, { children: [forceStatic ? (_jsx(Static, { items: [{ key: "confirmation-details" }], children: () => (_jsx(ConfirmationDetails, { toolName: confirmingTool.name, toolInput: confirmingTool.input, planContent: confirmingTool.planContent, isExpanded: isExpanded }, "confirmation-details")) })) : (_jsx(ConfirmationDetails, { toolName: confirmingTool.name, toolInput: confirmingTool.input, planContent: confirmingTool.planContent, isExpanded: isExpanded })), _jsx(ConfirmationSelector, { toolName: confirmingTool.name, toolInput: confirmingTool.input, suggestedPrefix: confirmingTool.suggestedPrefix, hidePersistentOption: confirmingTool.hidePersistentOption, isExpanded: isExpanded, onDecision: handleConfirmationDecision, onCancel: handleConfirmationCancel, onAbort: abortMessage })] }))] }));
41
41
  };
@@ -1 +1 @@
1
- {"version":3,"file":"MessageBlockItem.d.ts","sourceRoot":"","sources":["../../src/components/MessageBlockItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAS5D,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,GAAI,6CAK9B,qBAAqB,4CAgEvB,CAAC"}
1
+ {"version":3,"file":"MessageBlockItem.d.ts","sourceRoot":"","sources":["../../src/components/MessageBlockItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAS5D,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,GAAI,6CAK9B,qBAAqB,4CAuEvB,CAAC"}
@@ -8,5 +8,8 @@ import { ReasoningDisplay } from "./ReasoningDisplay.js";
8
8
  import { Markdown } from "./Markdown.js";
9
9
  import { TaskNotificationMessage } from "./TaskNotificationMessage.js";
10
10
  export const MessageBlockItem = ({ block, message, isExpanded, paddingTop = 0, }) => {
11
- return (_jsxs(Box, { flexDirection: "column", paddingTop: paddingTop, children: [block.type === "text" && block.content.trim() && (_jsxs(Box, { children: [block.source === MessageSource.HOOK && (_jsxs(Text, { color: "magenta", bold: true, children: ["~", " "] })), message.role === "user" || isExpanded ? (_jsx(Text, { backgroundColor: message.role === "user" ? "gray" : undefined, 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 === "bang" && (_jsx(BangDisplay, { 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, isExpanded: isExpanded })), block.type === "task_notification" && (_jsx(TaskNotificationMessage, { block: block }))] }));
11
+ return (_jsxs(Box, { flexDirection: "column", paddingTop: paddingTop, children: [block.type === "text" && block.content.trim() && (_jsxs(Box, { children: [block.source === MessageSource.HOOK && (_jsxs(Text, { color: "magenta", bold: true, children: ["~", " "] })), message.role === "user" || isExpanded ? (_jsx(Text, { backgroundColor: message.role === "user" ? "gray" : undefined, color: "white", children: block.content })) : block.stage === "streaming" ? (_jsx(Text, { color: "gray", wrap: "truncate-end", children: (() => {
12
+ const flat = block.content.replace(/\n/g, "\\n");
13
+ return flat.length > 30 ? `…${flat.slice(-30)}` : flat;
14
+ })() })) : (_jsx(Markdown, { children: block.content }))] })), block.type === "error" && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", block.content] }) })), block.type === "bang" && (_jsx(BangDisplay, { 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, isExpanded: isExpanded })), block.type === "task_notification" && (_jsx(TaskNotificationMessage, { block: block }))] }));
12
15
  };
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,gBAAgB,CAAC;AAG5D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,WAAW,uFAOnB,gBAAgB,6CAuIpB,CAAC"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,gBAAgB,CAAC;AAG5D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,WAAW,uFAOnB,gBAAgB,6CAqIpB,CAAC"}
@@ -13,13 +13,14 @@ export const MessageList = React.memo(({ messages, isExpanded = false, forceStat
13
13
  (b.stage === "running" ||
14
14
  b.stage === "streaming" ||
15
15
  b.stage === "start")) ||
16
- (b.type === "bang" && b.stage === "running");
16
+ (b.type === "bang" && b.stage === "running") ||
17
+ (b.type === "reasoning" && b.stage === "streaming");
17
18
  // Flatten messages into blocks with metadata
18
- // Filter out streaming text/reasoning blocks to avoid frequent height changes
19
+ // Filter out streaming text blocks to avoid frequent height changes,
20
+ // but allow streaming reasoning blocks (rendered as truncated gray text)
19
21
  const allBlocks = visibleMessages.flatMap((message, messageIndex) => {
20
22
  return message.blocks
21
- .filter((block) => !((block.type === "text" || block.type === "reasoning") &&
22
- block.stage === "streaming"))
23
+ .filter((block) => !(block.type === "text" && block.stage === "streaming"))
23
24
  .map((block, blockIndex) => ({
24
25
  block,
25
26
  message,
@@ -1 +1 @@
1
- {"version":3,"file":"ReasoningDisplay.d.ts","sourceRoot":"","sources":["../../src/components/ReasoningDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,UAAU,qBAAqB;IAC7B,KAAK,EAAE,cAAc,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA4B5D,CAAC"}
1
+ {"version":3,"file":"ReasoningDisplay.d.ts","sourceRoot":"","sources":["../../src/components/ReasoningDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,UAAU,qBAAqB;IAC7B,KAAK,EAAE,cAAc,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAmC5D,CAAC"}
@@ -2,9 +2,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Box, Text } from "ink";
3
3
  import { Markdown } from "./Markdown.js";
4
4
  export const ReasoningDisplay = ({ block, isExpanded = false, }) => {
5
- const { content } = block;
5
+ const { content, stage } = block;
6
6
  if (!content || !content.trim()) {
7
7
  return null;
8
8
  }
9
- return (_jsx(Box, { borderRight: false, borderTop: false, borderBottom: false, borderStyle: "classic", borderColor: "blue", paddingLeft: 1, children: _jsx(Box, { flexDirection: "column", children: isExpanded ? (_jsx(Text, { color: "white", children: content })) : (_jsx(Markdown, { children: content })) }) }));
9
+ return (_jsx(Box, { borderRight: false, borderTop: false, borderBottom: false, borderStyle: "classic", borderColor: "blue", paddingLeft: 1, children: _jsx(Box, { flexDirection: "column", children: isExpanded ? (_jsx(Text, { color: "white", children: content })) : stage === "streaming" ? (_jsx(Text, { color: "gray", wrap: "truncate-end", children: ` ${(() => {
10
+ const flat = content.replace(/\n/g, "\\n");
11
+ return flat.length > 30 ? `…${flat.slice(-30)}` : flat;
12
+ })()}` })) : (_jsx(Markdown, { children: content })) }) }));
10
13
  };
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import type { Message, McpServerStatus, BackgroundTask, Task, SlashCommand, PermissionDecision, PermissionMode } from "wave-agent-sdk";
2
+ import type { Message, McpServerStatus, BackgroundTask, Task, SlashCommand, PermissionDecision, PermissionMode, QueuedMessage } from "wave-agent-sdk";
3
3
  import { BaseAppProps } from "../types.js";
4
4
  export interface ChatContextType {
5
5
  messages: Message[];
@@ -9,14 +9,7 @@ export interface ChatContextType {
9
9
  isExpanded: boolean;
10
10
  isTaskListVisible: boolean;
11
11
  setIsTaskListVisible: (visible: boolean) => void;
12
- queuedMessages: Array<{
13
- content: string;
14
- images?: Array<{
15
- path: string;
16
- mimeType: string;
17
- }>;
18
- longTextMap?: Record<string, string>;
19
- }>;
12
+ queuedMessages: QueuedMessage[];
20
13
  sessionId: string;
21
14
  sendMessage: (content: string, images?: Array<{
22
15
  path: string;
@@ -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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"}
@@ -22,7 +22,6 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
22
22
  const [isExpanded, setIsExpanded] = useState(false);
23
23
  const isExpandedRef = useRef(isExpanded);
24
24
  const [isTaskListVisible, setIsTaskListVisible] = useState(true);
25
- const [queuedMessages, setQueuedMessages] = useState([]);
26
25
  const [messages, setMessages] = useState([]);
27
26
  const throttledSetMessages = useMemo(() => throttle(() => {
28
27
  if (!isExpandedRef.current && agentRef.current) {
@@ -52,6 +51,7 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
52
51
  const [isCompressing, setIsCompressing] = useState(false);
53
52
  const [currentModel, setCurrentModelState] = useState("");
54
53
  const [configuredModels, setConfiguredModels] = useState([]);
54
+ const [queuedMessages, setQueuedMessages] = useState([]);
55
55
  // MCP State
56
56
  const [mcpServers, setMcpServers] = useState([]);
57
57
  // Background tasks state
@@ -150,23 +150,27 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
150
150
  onLoadingChange: (loading) => {
151
151
  setIsLoading(loading);
152
152
  },
153
+ onCommandRunningChange: (running) => {
154
+ setIsCommandRunning(running);
155
+ },
156
+ onQueuedMessagesChange: (messages) => {
157
+ setQueuedMessages([...messages]);
158
+ },
153
159
  };
154
160
  try {
155
161
  // Create the permission callback inside the try block to access showConfirmation
156
- const permissionCallback = bypassPermissions
157
- ? undefined
158
- : async (context) => {
159
- try {
160
- return await showConfirmation(context.toolName, context.toolInput, context.suggestedPrefix, context.hidePersistentOption, context.planContent);
161
- }
162
- catch {
163
- // If confirmation was cancelled or failed, deny the operation
164
- return {
165
- behavior: "deny",
166
- message: OPERATION_CANCELLED_BY_USER,
167
- };
168
- }
169
- };
162
+ const permissionCallback = async (context) => {
163
+ try {
164
+ return await showConfirmation(context.toolName, context.toolInput, context.suggestedPrefix, context.hidePersistentOption, context.planContent);
165
+ }
166
+ catch {
167
+ // If confirmation was cancelled or failed, deny the operation
168
+ return {
169
+ behavior: "deny",
170
+ message: OPERATION_CANCELLED_BY_USER,
171
+ };
172
+ }
173
+ };
170
174
  const agent = await Agent.create({
171
175
  callbacks,
172
176
  restoreSessionId,
@@ -249,13 +253,6 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
249
253
  const hasImageAttachments = images && images.length > 0;
250
254
  if (!hasTextContent && !hasImageAttachments)
251
255
  return;
252
- if (isLoading || isCommandRunning) {
253
- setQueuedMessages((prev) => [
254
- ...prev,
255
- { content, images, longTextMap },
256
- ]);
257
- return;
258
- }
259
256
  try {
260
257
  const expandedContent = longTextMap
261
258
  ? expandLongTextPlaceholders(content, longTextMap)
@@ -266,13 +263,7 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
266
263
  !hasImageAttachments) {
267
264
  const command = expandedContent.substring(1).trim();
268
265
  if (command) {
269
- setIsCommandRunning(true);
270
- try {
271
- await agentRef.current?.bang(command);
272
- }
273
- finally {
274
- setIsCommandRunning(false);
275
- }
266
+ await agentRef.current?.bang(command);
276
267
  return;
277
268
  }
278
269
  }
@@ -286,24 +277,15 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
286
277
  catch (error) {
287
278
  console.error("Failed to send message:", error);
288
279
  }
289
- }, [isLoading, isCommandRunning]);
280
+ }, []);
290
281
  const askBtw = useCallback(async (question) => {
291
282
  if (!agentRef.current) {
292
283
  throw new Error("Agent not initialized");
293
284
  }
294
285
  return await agentRef.current.askBtw(question);
295
286
  }, []);
296
- // Process queued messages when idle
297
- useEffect(() => {
298
- if (!isLoading && !isCommandRunning && queuedMessages.length > 0) {
299
- const nextMessage = queuedMessages[0];
300
- setQueuedMessages((prev) => prev.slice(1));
301
- sendMessage(nextMessage.content, nextMessage.images, nextMessage.longTextMap);
302
- }
303
- }, [isLoading, isCommandRunning, queuedMessages, sendMessage]);
304
287
  // Unified interrupt method, interrupt both AI messages and command execution
305
288
  const abortMessage = useCallback(() => {
306
- setQueuedMessages([]);
307
289
  agentRef.current?.abortMessage();
308
290
  }, []);
309
291
  // Permission management methods
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-code",
3
- "version": "0.13.4",
3
+ "version": "0.13.5",
4
4
  "description": "CLI-based code assistant powered by AI, built with React and Ink",
5
5
  "repository": {
6
6
  "type": "git",
@@ -42,7 +42,7 @@
42
42
  "semver": "^7.7.4",
43
43
  "yargs": "^17.7.2",
44
44
  "zod": "^3.23.8",
45
- "wave-agent-sdk": "0.13.4"
45
+ "wave-agent-sdk": "0.13.5"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/react": "^19.1.8",
@@ -109,6 +109,7 @@ export const ChatInterface: React.FC = () => {
109
109
  <Static items={[{ key: "confirmation-details" }]}>
110
110
  {() => (
111
111
  <ConfirmationDetails
112
+ key="confirmation-details"
112
113
  toolName={confirmingTool!.name}
113
114
  toolInput={confirmingTool!.input}
114
115
  planContent={confirmingTool!.planContent}
@@ -38,6 +38,13 @@ export const MessageBlockItem = ({
38
38
  >
39
39
  {block.content}
40
40
  </Text>
41
+ ) : block.stage === "streaming" ? (
42
+ <Text color="gray" wrap="truncate-end">
43
+ {(() => {
44
+ const flat = block.content.replace(/\n/g, "\\n");
45
+ return flat.length > 30 ? `…${flat.slice(-30)}` : flat;
46
+ })()}
47
+ </Text>
41
48
  ) : (
42
49
  <Markdown>{block.content}</Markdown>
43
50
  )}
@@ -42,18 +42,16 @@ export const MessageList = React.memo(
42
42
  (b.stage === "running" ||
43
43
  b.stage === "streaming" ||
44
44
  b.stage === "start")) ||
45
- (b.type === "bang" && b.stage === "running");
45
+ (b.type === "bang" && b.stage === "running") ||
46
+ (b.type === "reasoning" && b.stage === "streaming");
46
47
 
47
48
  // Flatten messages into blocks with metadata
48
- // Filter out streaming text/reasoning blocks to avoid frequent height changes
49
+ // Filter out streaming text blocks to avoid frequent height changes,
50
+ // but allow streaming reasoning blocks (rendered as truncated gray text)
49
51
  const allBlocks = visibleMessages.flatMap((message, messageIndex) => {
50
52
  return message.blocks
51
53
  .filter(
52
- (block) =>
53
- !(
54
- (block.type === "text" || block.type === "reasoning") &&
55
- block.stage === "streaming"
56
- ),
54
+ (block) => !(block.type === "text" && block.stage === "streaming"),
57
55
  )
58
56
  .map((block, blockIndex) => ({
59
57
  block,
@@ -12,7 +12,7 @@ export const ReasoningDisplay: React.FC<ReasoningDisplayProps> = ({
12
12
  block,
13
13
  isExpanded = false,
14
14
  }) => {
15
- const { content } = block;
15
+ const { content, stage } = block;
16
16
 
17
17
  if (!content || !content.trim()) {
18
18
  return null;
@@ -30,6 +30,13 @@ export const ReasoningDisplay: React.FC<ReasoningDisplayProps> = ({
30
30
  <Box flexDirection="column">
31
31
  {isExpanded ? (
32
32
  <Text color="white">{content}</Text>
33
+ ) : stage === "streaming" ? (
34
+ <Text color="gray" wrap="truncate-end">
35
+ {` ${(() => {
36
+ const flat = content.replace(/\n/g, "\\n");
37
+ return flat.length > 30 ? `…${flat.slice(-30)}` : flat;
38
+ })()}`}
39
+ </Text>
33
40
  ) : (
34
41
  <Markdown>{content}</Markdown>
35
42
  )}
@@ -17,6 +17,7 @@ import type {
17
17
  SlashCommand,
18
18
  PermissionDecision,
19
19
  PermissionMode,
20
+ QueuedMessage,
20
21
  } from "wave-agent-sdk";
21
22
  import {
22
23
  Agent,
@@ -41,11 +42,7 @@ export interface ChatContextType {
41
42
  isExpanded: boolean;
42
43
  isTaskListVisible: boolean;
43
44
  setIsTaskListVisible: (visible: boolean) => void;
44
- queuedMessages: Array<{
45
- content: string;
46
- images?: Array<{ path: string; mimeType: string }>;
47
- longTextMap?: Record<string, string>;
48
- }>;
45
+ queuedMessages: QueuedMessage[];
49
46
  // AI functionality
50
47
  sessionId: string;
51
48
  sendMessage: (
@@ -158,14 +155,6 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
158
155
 
159
156
  const [isTaskListVisible, setIsTaskListVisible] = useState(true);
160
157
 
161
- const [queuedMessages, setQueuedMessages] = useState<
162
- Array<{
163
- content: string;
164
- images?: Array<{ path: string; mimeType: string }>;
165
- longTextMap?: Record<string, string>;
166
- }>
167
- >([]);
168
-
169
158
  const [messages, setMessages] = useState<Message[]>([]);
170
159
 
171
160
  const throttledSetMessages = useMemo(
@@ -216,6 +205,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
216
205
  const [isCompressing, setIsCompressing] = useState(false);
217
206
  const [currentModel, setCurrentModelState] = useState("");
218
207
  const [configuredModels, setConfiguredModels] = useState<string[]>([]);
208
+ const [queuedMessages, setQueuedMessages] = useState<QueuedMessage[]>([]);
219
209
 
220
210
  // MCP State
221
211
  const [mcpServers, setMcpServers] = useState<McpServerStatus[]>([]);
@@ -378,31 +368,35 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
378
368
  onLoadingChange: (loading) => {
379
369
  setIsLoading(loading);
380
370
  },
371
+ onCommandRunningChange: (running) => {
372
+ setIsCommandRunning(running);
373
+ },
374
+ onQueuedMessagesChange: (messages) => {
375
+ setQueuedMessages([...messages]);
376
+ },
381
377
  };
382
378
 
383
379
  try {
384
380
  // Create the permission callback inside the try block to access showConfirmation
385
- const permissionCallback = bypassPermissions
386
- ? undefined
387
- : async (
388
- context: ToolPermissionContext,
389
- ): Promise<PermissionDecision> => {
390
- try {
391
- return await showConfirmation(
392
- context.toolName,
393
- context.toolInput,
394
- context.suggestedPrefix,
395
- context.hidePersistentOption,
396
- context.planContent,
397
- );
398
- } catch {
399
- // If confirmation was cancelled or failed, deny the operation
400
- return {
401
- behavior: "deny",
402
- message: OPERATION_CANCELLED_BY_USER,
403
- };
404
- }
381
+ const permissionCallback = async (
382
+ context: ToolPermissionContext,
383
+ ): Promise<PermissionDecision> => {
384
+ try {
385
+ return await showConfirmation(
386
+ context.toolName,
387
+ context.toolInput,
388
+ context.suggestedPrefix,
389
+ context.hidePersistentOption,
390
+ context.planContent,
391
+ );
392
+ } catch {
393
+ // If confirmation was cancelled or failed, deny the operation
394
+ return {
395
+ behavior: "deny",
396
+ message: OPERATION_CANCELLED_BY_USER,
405
397
  };
398
+ }
399
+ };
406
400
 
407
401
  const agent = await Agent.create({
408
402
  callbacks,
@@ -499,14 +493,6 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
499
493
 
500
494
  if (!hasTextContent && !hasImageAttachments) return;
501
495
 
502
- if (isLoading || isCommandRunning) {
503
- setQueuedMessages((prev) => [
504
- ...prev,
505
- { content, images, longTextMap },
506
- ]);
507
- return;
508
- }
509
-
510
496
  try {
511
497
  const expandedContent = longTextMap
512
498
  ? expandLongTextPlaceholders(content, longTextMap)
@@ -520,12 +506,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
520
506
  ) {
521
507
  const command = expandedContent.substring(1).trim();
522
508
  if (command) {
523
- setIsCommandRunning(true);
524
- try {
525
- await agentRef.current?.bang(command);
526
- } finally {
527
- setIsCommandRunning(false);
528
- }
509
+ await agentRef.current?.bang(command);
529
510
  return;
530
511
  }
531
512
  }
@@ -539,7 +520,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
539
520
  console.error("Failed to send message:", error);
540
521
  }
541
522
  },
542
- [isLoading, isCommandRunning],
523
+ [],
543
524
  );
544
525
 
545
526
  const askBtw = useCallback(async (question: string) => {
@@ -549,22 +530,8 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
549
530
  return await agentRef.current.askBtw(question);
550
531
  }, []);
551
532
 
552
- // Process queued messages when idle
553
- useEffect(() => {
554
- if (!isLoading && !isCommandRunning && queuedMessages.length > 0) {
555
- const nextMessage = queuedMessages[0];
556
- setQueuedMessages((prev) => prev.slice(1));
557
- sendMessage(
558
- nextMessage.content,
559
- nextMessage.images,
560
- nextMessage.longTextMap,
561
- );
562
- }
563
- }, [isLoading, isCommandRunning, queuedMessages, sendMessage]);
564
-
565
533
  // Unified interrupt method, interrupt both AI messages and command execution
566
534
  const abortMessage = useCallback(() => {
567
- setQueuedMessages([]);
568
535
  agentRef.current?.abortMessage();
569
536
  }, []);
570
537