wave-code 0.5.0 → 0.6.2
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.
- package/dist/components/App.d.ts.map +1 -1
- package/dist/components/App.js +40 -2
- package/dist/components/BackgroundTaskManager.d.ts +6 -0
- package/dist/components/BackgroundTaskManager.d.ts.map +1 -0
- package/dist/components/{TaskManager.js → BackgroundTaskManager.js} +1 -1
- package/dist/components/ChatInterface.d.ts.map +1 -1
- package/dist/components/ChatInterface.js +40 -5
- package/dist/components/CommandOutputDisplay.d.ts.map +1 -1
- package/dist/components/CommandOutputDisplay.js +6 -17
- package/dist/components/CommandSelector.d.ts.map +1 -1
- package/dist/components/CommandSelector.js +16 -2
- package/dist/components/CompressDisplay.d.ts.map +1 -1
- package/dist/components/CompressDisplay.js +6 -10
- package/dist/components/ConfirmationDetails.d.ts +9 -0
- package/dist/components/ConfirmationDetails.d.ts.map +1 -0
- package/dist/components/ConfirmationDetails.js +53 -0
- package/dist/components/{Confirmation.d.ts → ConfirmationSelector.d.ts} +3 -3
- package/dist/components/ConfirmationSelector.d.ts.map +1 -0
- package/dist/components/{Confirmation.js → ConfirmationSelector.js} +34 -96
- package/dist/components/DiffDisplay.d.ts.map +1 -1
- package/dist/components/DiffDisplay.js +48 -1
- package/dist/components/FileSelector.d.ts.map +1 -1
- package/dist/components/FileSelector.js +2 -2
- package/dist/components/HelpView.d.ts +6 -0
- package/dist/components/HelpView.d.ts.map +1 -0
- package/dist/components/HelpView.js +24 -0
- package/dist/components/HistorySearch.d.ts.map +1 -1
- package/dist/components/HistorySearch.js +12 -4
- package/dist/components/InputBox.d.ts +1 -3
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +14 -17
- package/dist/components/LoadingIndicator.d.ts +11 -0
- package/dist/components/LoadingIndicator.d.ts.map +1 -0
- package/dist/components/LoadingIndicator.js +6 -0
- package/dist/components/Markdown.d.ts.map +1 -1
- package/dist/components/Markdown.js +114 -121
- package/dist/components/MessageItem.d.ts +1 -1
- package/dist/components/MessageItem.d.ts.map +1 -1
- package/dist/components/MessageItem.js +3 -5
- package/dist/components/MessageList.d.ts +2 -3
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +29 -12
- package/dist/components/PlanDisplay.d.ts.map +1 -1
- package/dist/components/PlanDisplay.js +4 -12
- package/dist/components/RewindCommand.d.ts +4 -0
- package/dist/components/RewindCommand.d.ts.map +1 -1
- package/dist/components/RewindCommand.js +20 -3
- package/dist/components/TaskList.d.ts +3 -0
- package/dist/components/TaskList.d.ts.map +1 -0
- package/dist/components/TaskList.js +40 -0
- package/dist/components/ToolDisplay.d.ts +9 -0
- package/dist/components/ToolDisplay.d.ts.map +1 -0
- package/dist/components/ToolDisplay.js +44 -0
- package/dist/contexts/useChat.d.ts +11 -3
- package/dist/contexts/useChat.d.ts.map +1 -1
- package/dist/contexts/useChat.js +51 -32
- package/dist/hooks/useInputManager.d.ts +4 -15
- package/dist/hooks/useInputManager.d.ts.map +1 -1
- package/dist/hooks/useInputManager.js +20 -65
- package/dist/hooks/useTasks.d.ts +2 -0
- package/dist/hooks/useTasks.d.ts.map +1 -0
- package/dist/hooks/useTasks.js +5 -0
- package/dist/managers/InputManager.d.ts +8 -30
- package/dist/managers/InputManager.d.ts.map +1 -1
- package/dist/managers/InputManager.js +38 -144
- package/dist/print-cli.d.ts.map +1 -1
- package/dist/print-cli.js +11 -30
- package/package.json +5 -6
- package/src/components/App.tsx +51 -3
- package/src/components/{TaskManager.tsx → BackgroundTaskManager.tsx} +4 -2
- package/src/components/ChatInterface.tsx +80 -23
- package/src/components/CommandOutputDisplay.tsx +16 -38
- package/src/components/CommandSelector.tsx +41 -17
- package/src/components/CompressDisplay.tsx +5 -22
- package/src/components/ConfirmationDetails.tsx +108 -0
- package/src/components/{Confirmation.tsx → ConfirmationSelector.tsx} +74 -193
- package/src/components/DiffDisplay.tsx +71 -1
- package/src/components/FileSelector.tsx +0 -2
- package/src/components/HelpView.tsx +59 -0
- package/src/components/HistorySearch.tsx +45 -21
- package/src/components/InputBox.tsx +51 -63
- package/src/components/LoadingIndicator.tsx +56 -0
- package/src/components/Markdown.tsx +126 -323
- package/src/components/MessageItem.tsx +13 -24
- package/src/components/MessageList.tsx +48 -82
- package/src/components/PlanDisplay.tsx +4 -27
- package/src/components/RewindCommand.tsx +39 -2
- package/src/components/TaskList.tsx +58 -0
- package/src/components/{ToolResultDisplay.tsx → ToolDisplay.tsx} +8 -18
- package/src/contexts/useChat.tsx +73 -41
- package/src/hooks/useInputManager.ts +21 -83
- package/src/hooks/useTasks.ts +6 -0
- package/src/managers/InputManager.ts +43 -179
- package/src/print-cli.ts +17 -35
- package/dist/components/Confirmation.d.ts.map +0 -1
- package/dist/components/MemoryDisplay.d.ts +0 -8
- package/dist/components/MemoryDisplay.d.ts.map +0 -1
- package/dist/components/MemoryDisplay.js +0 -25
- package/dist/components/MemoryTypeSelector.d.ts +0 -8
- package/dist/components/MemoryTypeSelector.d.ts.map +0 -1
- package/dist/components/MemoryTypeSelector.js +0 -38
- package/dist/components/SubagentBlock.d.ts +0 -8
- package/dist/components/SubagentBlock.d.ts.map +0 -1
- package/dist/components/SubagentBlock.js +0 -70
- package/dist/components/TaskManager.d.ts +0 -6
- package/dist/components/TaskManager.d.ts.map +0 -1
- package/dist/components/ToolResultDisplay.d.ts +0 -9
- package/dist/components/ToolResultDisplay.d.ts.map +0 -1
- package/dist/components/ToolResultDisplay.js +0 -54
- package/src/components/MemoryDisplay.tsx +0 -62
- package/src/components/MemoryTypeSelector.tsx +0 -98
- package/src/components/SubagentBlock.tsx +0 -143
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Box, Text, Static } from "ink";
|
|
3
3
|
import type { Message } from "wave-agent-sdk";
|
|
4
|
+
import {
|
|
5
|
+
TASK_CREATE_TOOL_NAME,
|
|
6
|
+
TASK_GET_TOOL_NAME,
|
|
7
|
+
TASK_UPDATE_TOOL_NAME,
|
|
8
|
+
TASK_LIST_TOOL_NAME,
|
|
9
|
+
} from "wave-agent-sdk";
|
|
4
10
|
import { MessageItem } from "./MessageItem.js";
|
|
5
11
|
|
|
6
12
|
export interface MessageListProps {
|
|
7
13
|
messages: Message[];
|
|
8
14
|
isLoading?: boolean;
|
|
9
15
|
isCommandRunning?: boolean;
|
|
10
|
-
isCompressing?: boolean;
|
|
11
|
-
latestTotalTokens?: number;
|
|
12
16
|
isExpanded?: boolean;
|
|
17
|
+
forceStaticLastMessage?: boolean;
|
|
13
18
|
}
|
|
14
19
|
|
|
15
20
|
export const MessageList = React.memo(
|
|
@@ -17,15 +22,16 @@ export const MessageList = React.memo(
|
|
|
17
22
|
messages,
|
|
18
23
|
isLoading = false,
|
|
19
24
|
isCommandRunning = false,
|
|
20
|
-
isCompressing = false,
|
|
21
|
-
latestTotalTokens = 0,
|
|
22
25
|
isExpanded = false,
|
|
26
|
+
forceStaticLastMessage = false,
|
|
23
27
|
}: MessageListProps) => {
|
|
24
28
|
// Empty message state
|
|
25
29
|
if (messages.length === 0) {
|
|
26
30
|
return (
|
|
27
|
-
<Box flexDirection="column"
|
|
28
|
-
<
|
|
31
|
+
<Box flexDirection="column" gap={1}>
|
|
32
|
+
<Box flexDirection="column" paddingY={1}>
|
|
33
|
+
<Text color="gray">Welcome to WAVE Code Assistant!</Text>
|
|
34
|
+
</Box>
|
|
29
35
|
</Box>
|
|
30
36
|
);
|
|
31
37
|
}
|
|
@@ -34,15 +40,43 @@ export const MessageList = React.memo(
|
|
|
34
40
|
const maxExpandedMessages = 20;
|
|
35
41
|
const shouldLimitMessages =
|
|
36
42
|
isExpanded && messages.length > maxExpandedMessages;
|
|
43
|
+
|
|
44
|
+
// Filter out task management tools and empty messages
|
|
45
|
+
const taskMgmtTools = [
|
|
46
|
+
TASK_CREATE_TOOL_NAME,
|
|
47
|
+
TASK_GET_TOOL_NAME,
|
|
48
|
+
TASK_UPDATE_TOOL_NAME,
|
|
49
|
+
TASK_LIST_TOOL_NAME,
|
|
50
|
+
];
|
|
51
|
+
const filteredMessages = messages
|
|
52
|
+
.map((message) => ({
|
|
53
|
+
...message,
|
|
54
|
+
blocks: message.blocks.filter(
|
|
55
|
+
(block) =>
|
|
56
|
+
!(
|
|
57
|
+
block.type === "tool" &&
|
|
58
|
+
typeof block.name === "string" &&
|
|
59
|
+
taskMgmtTools.includes(block.name)
|
|
60
|
+
),
|
|
61
|
+
),
|
|
62
|
+
}))
|
|
63
|
+
.filter((message) => message.blocks.length > 0);
|
|
64
|
+
|
|
37
65
|
const displayMessages = shouldLimitMessages
|
|
38
|
-
?
|
|
39
|
-
:
|
|
40
|
-
const omittedCount = shouldLimitMessages
|
|
41
|
-
? messages.length - maxExpandedMessages
|
|
42
|
-
: 0;
|
|
66
|
+
? filteredMessages.slice(-maxExpandedMessages)
|
|
67
|
+
: filteredMessages;
|
|
43
68
|
|
|
44
69
|
// Compute which messages to render statically vs dynamically
|
|
45
|
-
const
|
|
70
|
+
const lastMessage = displayMessages[displayMessages.length - 1];
|
|
71
|
+
const hasNonEndTool = lastMessage?.blocks.some(
|
|
72
|
+
(block) => block.type === "tool" && block.stage !== "end",
|
|
73
|
+
);
|
|
74
|
+
const hasRunningCommand = lastMessage?.blocks.some(
|
|
75
|
+
(block) => block.type === "command_output" && block.isRunning,
|
|
76
|
+
);
|
|
77
|
+
const shouldRenderLastDynamic =
|
|
78
|
+
!forceStaticLastMessage &&
|
|
79
|
+
(isLoading || isCommandRunning || hasNonEndTool || hasRunningCommand);
|
|
46
80
|
const staticMessages = shouldRenderLastDynamic
|
|
47
81
|
? displayMessages.slice(0, -1)
|
|
48
82
|
: displayMessages;
|
|
@@ -52,17 +86,7 @@ export const MessageList = React.memo(
|
|
|
52
86
|
: [];
|
|
53
87
|
|
|
54
88
|
return (
|
|
55
|
-
<Box flexDirection="column"
|
|
56
|
-
{/* Show omitted message count when limiting */}
|
|
57
|
-
{omittedCount > 0 && (
|
|
58
|
-
<Box>
|
|
59
|
-
<Text color="gray" dimColor>
|
|
60
|
-
... {omittedCount} earlier message{omittedCount !== 1 ? "s" : ""}{" "}
|
|
61
|
-
omitted (showing latest {maxExpandedMessages})
|
|
62
|
-
</Text>
|
|
63
|
-
</Box>
|
|
64
|
-
)}
|
|
65
|
-
|
|
89
|
+
<Box flexDirection="column" paddingBottom={1}>
|
|
66
90
|
{/* Static messages */}
|
|
67
91
|
<Static items={staticMessages}>
|
|
68
92
|
{(message, key) => {
|
|
@@ -86,7 +110,7 @@ export const MessageList = React.memo(
|
|
|
86
110
|
const previousMessage =
|
|
87
111
|
messageIndex > 0 ? displayMessages[messageIndex - 1] : undefined;
|
|
88
112
|
return (
|
|
89
|
-
<Box key={`dynamic-${index}`}
|
|
113
|
+
<Box key={`dynamic-${index}`}>
|
|
90
114
|
<MessageItem
|
|
91
115
|
message={message}
|
|
92
116
|
shouldShowHeader={previousMessage?.role !== message.role}
|
|
@@ -95,64 +119,6 @@ export const MessageList = React.memo(
|
|
|
95
119
|
</Box>
|
|
96
120
|
);
|
|
97
121
|
})}
|
|
98
|
-
|
|
99
|
-
{(isLoading || isCommandRunning || isCompressing) && (
|
|
100
|
-
<Box flexDirection="column" gap={1}>
|
|
101
|
-
{isLoading && (
|
|
102
|
-
<Box>
|
|
103
|
-
<Text color="yellow">💭 AI is thinking... </Text>
|
|
104
|
-
<Text color="gray" dimColor>
|
|
105
|
-
|{" "}
|
|
106
|
-
</Text>
|
|
107
|
-
<Text color="red" bold>
|
|
108
|
-
Esc
|
|
109
|
-
</Text>
|
|
110
|
-
<Text color="gray" dimColor>
|
|
111
|
-
{" "}
|
|
112
|
-
to abort
|
|
113
|
-
</Text>
|
|
114
|
-
</Box>
|
|
115
|
-
)}
|
|
116
|
-
{isCommandRunning && (
|
|
117
|
-
<Text color="blue">🚀 Command is running...</Text>
|
|
118
|
-
)}
|
|
119
|
-
{isCompressing && (
|
|
120
|
-
<Text color="magenta">🗜️ Compressing message history...</Text>
|
|
121
|
-
)}
|
|
122
|
-
</Box>
|
|
123
|
-
)}
|
|
124
|
-
|
|
125
|
-
{/* Bottom info and shortcut key hints */}
|
|
126
|
-
{messages.length > 0 && (
|
|
127
|
-
<Box>
|
|
128
|
-
<Box justifyContent="space-between" width="100%">
|
|
129
|
-
<Box>
|
|
130
|
-
<Text color="gray">
|
|
131
|
-
Messages {messages.length}
|
|
132
|
-
{latestTotalTokens > 0 && (
|
|
133
|
-
<>
|
|
134
|
-
<Text color="gray" dimColor>
|
|
135
|
-
{" "}
|
|
136
|
-
|{" "}
|
|
137
|
-
</Text>
|
|
138
|
-
<Text color="blue" bold>
|
|
139
|
-
{latestTotalTokens.toLocaleString()}
|
|
140
|
-
</Text>
|
|
141
|
-
<Text color="gray" dimColor>
|
|
142
|
-
{" "}
|
|
143
|
-
tokens
|
|
144
|
-
</Text>
|
|
145
|
-
</>
|
|
146
|
-
)}
|
|
147
|
-
</Text>
|
|
148
|
-
</Box>
|
|
149
|
-
<Text color="gray" dimColor>
|
|
150
|
-
<Text color="cyan">Ctrl+O</Text> Toggle{" "}
|
|
151
|
-
{isExpanded ? "Collapse" : "Expand"}
|
|
152
|
-
</Text>
|
|
153
|
-
</Box>
|
|
154
|
-
</Box>
|
|
155
|
-
)}
|
|
156
122
|
</Box>
|
|
157
123
|
);
|
|
158
124
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import { Box
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box } from "ink";
|
|
3
3
|
import { Markdown } from "./Markdown.js";
|
|
4
4
|
|
|
5
5
|
interface PlanDisplayProps {
|
|
@@ -7,35 +7,12 @@ interface PlanDisplayProps {
|
|
|
7
7
|
isExpanded?: boolean;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export const PlanDisplay: React.FC<PlanDisplayProps> = ({
|
|
11
|
-
plan,
|
|
12
|
-
isExpanded = false,
|
|
13
|
-
}) => {
|
|
14
|
-
const { stdout } = useStdout();
|
|
15
|
-
const maxHeight = useMemo(() => {
|
|
16
|
-
// Similar to DiffDisplay.tsx maxHeight calculation
|
|
17
|
-
return Math.max(5, (stdout?.rows || 24) - 25);
|
|
18
|
-
}, [stdout?.rows]);
|
|
19
|
-
|
|
20
|
-
const lines = useMemo(() => plan.split("\n"), [plan]);
|
|
21
|
-
const isOverflowing = !isExpanded && lines.length > maxHeight;
|
|
22
|
-
|
|
10
|
+
export const PlanDisplay: React.FC<PlanDisplayProps> = ({ plan }) => {
|
|
23
11
|
return (
|
|
24
12
|
<Box flexDirection="column" marginTop={1}>
|
|
25
|
-
<Box
|
|
26
|
-
flexDirection="column"
|
|
27
|
-
height={isOverflowing ? maxHeight : undefined}
|
|
28
|
-
overflow="hidden"
|
|
29
|
-
>
|
|
13
|
+
<Box flexDirection="column">
|
|
30
14
|
<Markdown>{plan}</Markdown>
|
|
31
15
|
</Box>
|
|
32
|
-
{isOverflowing && (
|
|
33
|
-
<Box marginTop={1}>
|
|
34
|
-
<Text color="yellow" dimColor>
|
|
35
|
-
... (plan truncated, {lines.length} lines total)
|
|
36
|
-
</Text>
|
|
37
|
-
</Box>
|
|
38
|
-
)}
|
|
39
16
|
</Box>
|
|
40
17
|
);
|
|
41
18
|
};
|
|
@@ -6,13 +6,30 @@ export interface RewindCommandProps {
|
|
|
6
6
|
messages: Message[];
|
|
7
7
|
onSelect: (index: number) => void;
|
|
8
8
|
onCancel: () => void;
|
|
9
|
+
getFullMessageThread?: () => Promise<{
|
|
10
|
+
messages: Message[];
|
|
11
|
+
sessionIds: string[];
|
|
12
|
+
}>;
|
|
9
13
|
}
|
|
10
14
|
|
|
11
15
|
export const RewindCommand: React.FC<RewindCommandProps> = ({
|
|
12
|
-
messages,
|
|
16
|
+
messages: initialMessages,
|
|
13
17
|
onSelect,
|
|
14
18
|
onCancel,
|
|
19
|
+
getFullMessageThread,
|
|
15
20
|
}) => {
|
|
21
|
+
const [messages, setMessages] = useState<Message[]>(initialMessages);
|
|
22
|
+
const [isLoading, setIsLoading] = useState(!!getFullMessageThread);
|
|
23
|
+
|
|
24
|
+
React.useEffect(() => {
|
|
25
|
+
if (getFullMessageThread) {
|
|
26
|
+
getFullMessageThread().then(({ messages: fullMessages }) => {
|
|
27
|
+
setMessages(fullMessages);
|
|
28
|
+
setIsLoading(false);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}, [getFullMessageThread]);
|
|
32
|
+
|
|
16
33
|
// Filter user messages as checkpoints
|
|
17
34
|
const checkpoints = messages
|
|
18
35
|
.map((msg, index) => ({ msg, index }))
|
|
@@ -20,6 +37,11 @@ export const RewindCommand: React.FC<RewindCommandProps> = ({
|
|
|
20
37
|
|
|
21
38
|
const [selectedIndex, setSelectedIndex] = useState(checkpoints.length - 1);
|
|
22
39
|
|
|
40
|
+
// Update selectedIndex when checkpoints change (after loading full thread)
|
|
41
|
+
React.useEffect(() => {
|
|
42
|
+
setSelectedIndex(checkpoints.length - 1);
|
|
43
|
+
}, [checkpoints.length]);
|
|
44
|
+
|
|
23
45
|
useInput((input, key) => {
|
|
24
46
|
if (key.return) {
|
|
25
47
|
if (checkpoints.length > 0 && selectedIndex >= 0) {
|
|
@@ -44,6 +66,21 @@ export const RewindCommand: React.FC<RewindCommandProps> = ({
|
|
|
44
66
|
}
|
|
45
67
|
});
|
|
46
68
|
|
|
69
|
+
if (isLoading) {
|
|
70
|
+
return (
|
|
71
|
+
<Box
|
|
72
|
+
flexDirection="column"
|
|
73
|
+
paddingX={1}
|
|
74
|
+
borderStyle="single"
|
|
75
|
+
borderColor="cyan"
|
|
76
|
+
borderLeft={false}
|
|
77
|
+
borderRight={false}
|
|
78
|
+
>
|
|
79
|
+
<Text color="cyan">Loading full message thread...</Text>
|
|
80
|
+
</Box>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
47
84
|
if (checkpoints.length === 0) {
|
|
48
85
|
return (
|
|
49
86
|
<Box
|
|
@@ -106,7 +143,7 @@ export const RewindCommand: React.FC<RewindCommandProps> = ({
|
|
|
106
143
|
<Box>
|
|
107
144
|
<Text color="red" dimColor>
|
|
108
145
|
⚠️ Warning: This will delete all subsequent messages and revert file
|
|
109
|
-
changes.
|
|
146
|
+
and task list changes.
|
|
110
147
|
</Text>
|
|
111
148
|
</Box>
|
|
112
149
|
</Box>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useChat } from "../contexts/useChat.js";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
import { useTasks } from "../hooks/useTasks.js";
|
|
5
|
+
|
|
6
|
+
export const TaskList: React.FC = () => {
|
|
7
|
+
const tasks = useTasks();
|
|
8
|
+
const { isTaskListVisible } = useChat();
|
|
9
|
+
|
|
10
|
+
if (tasks.length === 0 || !isTaskListVisible) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const getStatusIcon = (status: string, isBlocked: boolean) => {
|
|
15
|
+
if (isBlocked) {
|
|
16
|
+
return <Text color="red">🔒</Text>;
|
|
17
|
+
}
|
|
18
|
+
switch (status) {
|
|
19
|
+
case "pending":
|
|
20
|
+
return <Text color="gray">□</Text>;
|
|
21
|
+
case "in_progress":
|
|
22
|
+
return <Text color="yellow">■</Text>;
|
|
23
|
+
case "completed":
|
|
24
|
+
return <Text color="green">✓</Text>;
|
|
25
|
+
case "deleted":
|
|
26
|
+
return <Text color="red">✕</Text>;
|
|
27
|
+
default:
|
|
28
|
+
return <Text color="gray">?</Text>;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<Box flexDirection="column">
|
|
34
|
+
{tasks.map((task) => {
|
|
35
|
+
const isDimmed =
|
|
36
|
+
task.status === "completed" || task.status === "deleted";
|
|
37
|
+
const isBlocked = task.blockedBy && task.blockedBy.length > 0;
|
|
38
|
+
const blockingTaskIds = isBlocked
|
|
39
|
+
? task.blockedBy.map((id) => `#${id}`)
|
|
40
|
+
: [];
|
|
41
|
+
|
|
42
|
+
const blockedByText =
|
|
43
|
+
isBlocked && blockingTaskIds.length > 0
|
|
44
|
+
? ` (Blocked by: ${blockingTaskIds.join(", ")})`
|
|
45
|
+
: "";
|
|
46
|
+
|
|
47
|
+
const fullText = `${task.subject}${blockedByText}`;
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<Box key={task.id} gap={1}>
|
|
51
|
+
{getStatusIcon(task.status, isBlocked)}
|
|
52
|
+
<Text dimColor={isDimmed}>{fullText}</Text>
|
|
53
|
+
</Box>
|
|
54
|
+
);
|
|
55
|
+
})}
|
|
56
|
+
</Box>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
@@ -3,12 +3,12 @@ import { Box, Text } from "ink";
|
|
|
3
3
|
import type { ToolBlock } from "wave-agent-sdk";
|
|
4
4
|
import { DiffDisplay } from "./DiffDisplay.js";
|
|
5
5
|
|
|
6
|
-
interface
|
|
6
|
+
interface ToolDisplayProps {
|
|
7
7
|
block: ToolBlock;
|
|
8
8
|
isExpanded?: boolean;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export const
|
|
11
|
+
export const ToolDisplay: React.FC<ToolDisplayProps> = ({
|
|
12
12
|
block,
|
|
13
13
|
isExpanded = false,
|
|
14
14
|
}) => {
|
|
@@ -25,13 +25,6 @@ export const ToolResultDisplay: React.FC<ToolResultDisplayProps> = ({
|
|
|
25
25
|
return "gray"; // Unknown state or no state information
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
const getStatusText = () => {
|
|
29
|
-
if (stage === "running") return "🔄";
|
|
30
|
-
if (success) return "";
|
|
31
|
-
if (error || success === false) return "❌";
|
|
32
|
-
return ""; // Don't display text for unknown state
|
|
33
|
-
};
|
|
34
|
-
|
|
35
28
|
const hasImages = () => {
|
|
36
29
|
return block.images && block.images.length > 0;
|
|
37
30
|
};
|
|
@@ -44,9 +37,6 @@ export const ToolResultDisplay: React.FC<ToolResultDisplayProps> = ({
|
|
|
44
37
|
|
|
45
38
|
const toolName = name ? String(name) : "Tool";
|
|
46
39
|
|
|
47
|
-
const isBackgroundable =
|
|
48
|
-
stage === "running" && (toolName === "Bash" || toolName === "Task");
|
|
49
|
-
|
|
50
40
|
// Get shortResult, if not available show last 5 lines of result
|
|
51
41
|
const getShortResult = () => {
|
|
52
42
|
if (block.shortResult) {
|
|
@@ -68,18 +58,18 @@ export const ToolResultDisplay: React.FC<ToolResultDisplayProps> = ({
|
|
|
68
58
|
const shortResult = getShortResult();
|
|
69
59
|
|
|
70
60
|
return (
|
|
71
|
-
<Box flexDirection="column"
|
|
61
|
+
<Box flexDirection="column">
|
|
72
62
|
<Box>
|
|
73
|
-
<
|
|
74
|
-
|
|
63
|
+
<Box flexShrink={0}>
|
|
64
|
+
<Text color={getStatusColor()}>● </Text>
|
|
65
|
+
<Text color="white">{toolName}</Text>
|
|
66
|
+
</Box>
|
|
75
67
|
{/* Display compactParams in collapsed state */}
|
|
76
68
|
{!isExpanded && compactParams && (
|
|
77
69
|
<Text color="gray"> {compactParams}</Text>
|
|
78
70
|
)}
|
|
79
|
-
<Text color={getStatusColor()}> {getStatusText()}</Text>
|
|
80
71
|
{/* Display image indicator */}
|
|
81
72
|
{hasImages() && <Text color="blue"> {getImageIndicator()}</Text>}
|
|
82
|
-
{isBackgroundable && <Text color="gray"> [Ctrl-B] Background</Text>}
|
|
83
73
|
</Box>
|
|
84
74
|
|
|
85
75
|
{/* Display shortResult in collapsed state */}
|
|
@@ -91,7 +81,7 @@ export const ToolResultDisplay: React.FC<ToolResultDisplayProps> = ({
|
|
|
91
81
|
flexDirection="column"
|
|
92
82
|
>
|
|
93
83
|
{shortResult.split("\n").map((line, index) => (
|
|
94
|
-
<Text key={index} color="
|
|
84
|
+
<Text key={index} color="gray">
|
|
95
85
|
{line}
|
|
96
86
|
</Text>
|
|
97
87
|
))}
|