wave-code 1.0.0 → 1.0.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/cli.js +20 -1
- package/dist/components/App.js +7 -0
- package/dist/components/BtwDisplay.js +13 -3
- package/dist/components/ChatInterface.js +25 -8
- package/dist/components/InputBox.d.ts +1 -3
- package/dist/components/InputBox.js +12 -9
- package/dist/components/LoadingIndicator.d.ts +1 -2
- package/dist/components/LoadingIndicator.js +2 -2
- package/dist/components/LoginCommand.js +4 -2
- package/dist/components/Markdown.js +13 -16
- package/dist/components/Notifications.d.ts +7 -0
- package/dist/components/Notifications.js +9 -0
- package/dist/components/StatusLine.d.ts +0 -4
- package/dist/components/StatusLine.js +6 -10
- package/dist/components/TaskList.js +2 -1
- package/dist/components/ToolDisplay.d.ts +1 -0
- package/dist/components/ToolDisplay.js +17 -9
- package/dist/constants/commands.js +0 -6
- package/dist/contexts/useChat.d.ts +4 -6
- package/dist/contexts/useChat.js +253 -110
- package/dist/daemon-cli.d.ts +10 -0
- package/dist/daemon-cli.js +15 -0
- package/dist/hooks/useInputManager.js +99 -22
- package/dist/index.js +10 -0
- package/dist/managers/inputHandlers.js +50 -22
- package/dist/managers/inputReducer.d.ts +12 -2
- package/dist/managers/inputReducer.js +57 -9
- package/dist/stdio/agentBridge.d.ts +23 -0
- package/dist/stdio/agentBridge.js +134 -16
- package/dist/stdio/daemonServer.d.ts +67 -0
- package/dist/stdio/daemonServer.js +191 -0
- package/dist/stdio/index.d.ts +2 -0
- package/dist/stdio/index.js +2 -0
- package/dist/stdio/jsonRpcConnection.d.ts +30 -0
- package/dist/stdio/jsonRpcConnection.js +127 -0
- package/dist/stdio/protocol.d.ts +2 -2
- package/dist/stdio/stdioServer.d.ts +2 -7
- package/dist/stdio/stdioServer.js +9 -100
- package/dist/utils/bracketedPaste.d.ts +39 -0
- package/dist/utils/bracketedPaste.js +122 -0
- package/dist/utils/markdownTable.d.ts +34 -0
- package/dist/utils/markdownTable.js +302 -0
- package/dist/utils/throttle.d.ts +3 -3
- package/package.json +4 -2
- package/src/cli.tsx +20 -1
- package/src/components/App.tsx +5 -0
- package/src/components/BtwDisplay.tsx +36 -12
- package/src/components/ChatInterface.tsx +30 -15
- package/src/components/InputBox.tsx +25 -24
- package/src/components/LoadingIndicator.tsx +1 -4
- package/src/components/LoginCommand.tsx +4 -2
- package/src/components/Markdown.tsx +15 -18
- package/src/components/Notifications.tsx +31 -0
- package/src/components/StatusLine.tsx +17 -44
- package/src/components/TaskList.tsx +2 -1
- package/src/components/ToolDisplay.tsx +17 -6
- package/src/constants/commands.ts +0 -6
- package/src/contexts/useChat.tsx +326 -140
- package/src/daemon-cli.ts +17 -0
- package/src/hooks/useInputManager.ts +108 -22
- package/src/index.ts +12 -0
- package/src/managers/inputHandlers.ts +49 -22
- package/src/managers/inputReducer.ts +66 -11
- package/src/stdio/agentBridge.ts +196 -17
- package/src/stdio/daemonServer.ts +212 -0
- package/src/stdio/index.ts +2 -0
- package/src/stdio/jsonRpcConnection.ts +160 -0
- package/src/stdio/protocol.ts +5 -2
- package/src/stdio/stdioServer.ts +14 -120
- package/src/utils/bracketedPaste.ts +170 -0
- package/src/utils/markdownTable.ts +359 -0
- package/src/utils/throttle.ts +8 -8
|
@@ -14,6 +14,7 @@ import { PluginManagerShell } from "./PluginManagerShell.js";
|
|
|
14
14
|
import { ModelSelector } from "./ModelSelector.js";
|
|
15
15
|
import { WorkflowManager } from "./WorkflowManager.js";
|
|
16
16
|
import { StatusLine } from "./StatusLine.js";
|
|
17
|
+
import { Notifications } from "./Notifications.js";
|
|
17
18
|
import { BtwDisplay } from "./BtwDisplay.js";
|
|
18
19
|
import { useInputManager } from "../hooks/useInputManager.js";
|
|
19
20
|
import { useChat } from "../contexts/useChat.js";
|
|
@@ -32,7 +33,6 @@ export interface InputBoxProps {
|
|
|
32
33
|
isLoading?: boolean;
|
|
33
34
|
isCommandRunning?: boolean;
|
|
34
35
|
isCompacting?: boolean;
|
|
35
|
-
isGoalEvaluating?: boolean;
|
|
36
36
|
workdir?: string;
|
|
37
37
|
sendMessage?: (
|
|
38
38
|
message: string,
|
|
@@ -50,16 +50,14 @@ export interface InputBoxProps {
|
|
|
50
50
|
// Token usage
|
|
51
51
|
latestTotalTokens?: number;
|
|
52
52
|
maxInputTokens?: number;
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
goalElapsed?: string;
|
|
53
|
+
// Login hint
|
|
54
|
+
showLoginHint?: boolean;
|
|
56
55
|
}
|
|
57
56
|
|
|
58
57
|
export const InputBox: React.FC<InputBoxProps> = ({
|
|
59
58
|
isLoading,
|
|
60
59
|
isCommandRunning,
|
|
61
60
|
isCompacting,
|
|
62
|
-
isGoalEvaluating,
|
|
63
61
|
sendMessage = () => {},
|
|
64
62
|
abortMessage = () => {},
|
|
65
63
|
mcpServers = [],
|
|
@@ -69,8 +67,7 @@ export const InputBox: React.FC<InputBoxProps> = ({
|
|
|
69
67
|
hasSlashCommand = () => false,
|
|
70
68
|
latestTotalTokens = 0,
|
|
71
69
|
maxInputTokens = 200000,
|
|
72
|
-
|
|
73
|
-
goalElapsed,
|
|
70
|
+
showLoginHint = false,
|
|
74
71
|
}) => {
|
|
75
72
|
const {
|
|
76
73
|
permissionMode: chatPermissionMode,
|
|
@@ -84,13 +81,13 @@ export const InputBox: React.FC<InputBoxProps> = ({
|
|
|
84
81
|
askBtw,
|
|
85
82
|
clearMessages,
|
|
86
83
|
compact,
|
|
87
|
-
goalCommand,
|
|
88
84
|
currentModel,
|
|
89
85
|
configuredModels,
|
|
90
86
|
setModel,
|
|
91
87
|
recreateAgent,
|
|
92
88
|
recallQueuedMessage,
|
|
93
89
|
queuedMessages,
|
|
90
|
+
setIsBtwActive,
|
|
94
91
|
} = useChat();
|
|
95
92
|
|
|
96
93
|
// Ref to hold setInputText so queue callbacks can access it before useInputManager returns
|
|
@@ -100,12 +97,7 @@ export const InputBox: React.FC<InputBoxProps> = ({
|
|
|
100
97
|
|
|
101
98
|
// Idle means no AI work in flight. Esc double-press clear only applies when
|
|
102
99
|
// idle; while busy, Esc keeps its abort semantics.
|
|
103
|
-
const isIdle = !(
|
|
104
|
-
isLoading ||
|
|
105
|
-
isCommandRunning ||
|
|
106
|
-
isCompacting ||
|
|
107
|
-
isGoalEvaluating
|
|
108
|
-
);
|
|
100
|
+
const isIdle = !(isLoading || isCommandRunning || isCompacting);
|
|
109
101
|
|
|
110
102
|
const onRecallQueuedMessage = useCallback(() => {
|
|
111
103
|
const msg = recallQueuedMessage();
|
|
@@ -174,7 +166,6 @@ export const InputBox: React.FC<InputBoxProps> = ({
|
|
|
174
166
|
onAskBtw: askBtw,
|
|
175
167
|
onClearMessages: clearMessages,
|
|
176
168
|
onCompact: compact,
|
|
177
|
-
onGoalCommand: goalCommand,
|
|
178
169
|
onHasSlashCommand: hasSlashCommand,
|
|
179
170
|
onAbortMessage: abortMessage,
|
|
180
171
|
onBackgroundCurrentTask: backgroundCurrentTask,
|
|
@@ -192,6 +183,13 @@ export const InputBox: React.FC<InputBoxProps> = ({
|
|
|
192
183
|
setInputTextRef.current = setInputText;
|
|
193
184
|
}, [setInputText]);
|
|
194
185
|
|
|
186
|
+
// Sync the btw overlay's visibility to ChatContext so siblings (TaskList)
|
|
187
|
+
// can hide while the side-question is on display (aligned with Claude Code,
|
|
188
|
+
// which suppresses the expanded task list while a local-jsx command shows).
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
setIsBtwActive(btwState.question !== "" || btwState.answer !== undefined);
|
|
191
|
+
}, [btwState.question, btwState.answer, setIsBtwActive]);
|
|
192
|
+
|
|
195
193
|
// Sync permission mode from useChat to InputManager
|
|
196
194
|
useEffect(() => {
|
|
197
195
|
setPermissionMode(chatPermissionMode);
|
|
@@ -349,7 +347,7 @@ export const InputBox: React.FC<InputBoxProps> = ({
|
|
|
349
347
|
<WorkflowManager onCancel={() => setShowWorkflowManager(false)} />
|
|
350
348
|
)}
|
|
351
349
|
|
|
352
|
-
{btwState.question
|
|
350
|
+
{btwState.question || btwState.answer
|
|
353
351
|
? null
|
|
354
352
|
: showBackgroundTaskManager ||
|
|
355
353
|
showMcpManager ||
|
|
@@ -381,14 +379,17 @@ export const InputBox: React.FC<InputBoxProps> = ({
|
|
|
381
379
|
)}
|
|
382
380
|
</Text>
|
|
383
381
|
</Box>
|
|
384
|
-
<
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
382
|
+
<Box justifyContent="space-between">
|
|
383
|
+
<StatusLine
|
|
384
|
+
permissionMode={permissionMode}
|
|
385
|
+
isShellCommand={isShellCommand}
|
|
386
|
+
/>
|
|
387
|
+
<Notifications
|
|
388
|
+
latestTotalTokens={latestTotalTokens}
|
|
389
|
+
maxInputTokens={maxInputTokens}
|
|
390
|
+
showLoginHint={showLoginHint}
|
|
391
|
+
/>
|
|
392
|
+
</Box>
|
|
392
393
|
</Box>
|
|
393
394
|
)}
|
|
394
395
|
</Box>
|
|
@@ -5,7 +5,6 @@ export interface LoadingIndicatorProps {
|
|
|
5
5
|
isLoading?: boolean;
|
|
6
6
|
isCommandRunning?: boolean;
|
|
7
7
|
isCompacting?: boolean;
|
|
8
|
-
isGoalEvaluating?: boolean;
|
|
9
8
|
latestTotalTokens?: number;
|
|
10
9
|
}
|
|
11
10
|
|
|
@@ -13,12 +12,11 @@ export const LoadingIndicator = ({
|
|
|
13
12
|
isLoading = false,
|
|
14
13
|
isCommandRunning = false,
|
|
15
14
|
isCompacting = false,
|
|
16
|
-
isGoalEvaluating = false,
|
|
17
15
|
latestTotalTokens = 0,
|
|
18
16
|
}: LoadingIndicatorProps) => {
|
|
19
17
|
return (
|
|
20
18
|
<Box flexDirection="column">
|
|
21
|
-
{isLoading && !isCompacting &&
|
|
19
|
+
{isLoading && !isCompacting && (
|
|
22
20
|
<Box>
|
|
23
21
|
<Text color="yellow">✻ AI is thinking... </Text>
|
|
24
22
|
{latestTotalTokens > 0 && (
|
|
@@ -51,7 +49,6 @@ export const LoadingIndicator = ({
|
|
|
51
49
|
{isCompacting && (
|
|
52
50
|
<Text color="magenta">✻ Compacting message history...</Text>
|
|
53
51
|
)}
|
|
54
|
-
{isGoalEvaluating && <Text color="cyan">✻ Evaluating goal...</Text>}
|
|
55
52
|
</Box>
|
|
56
53
|
);
|
|
57
54
|
};
|
|
@@ -80,7 +80,9 @@ export const LoginCommand: React.FC<LoginCommandProps> = ({ onCancel }) => {
|
|
|
80
80
|
const handleEnter = async () => {
|
|
81
81
|
if (isLoadingRef.current) return;
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
// A stale-but-present SSO token still counts as logged in; it refreshes
|
|
84
|
+
// lazily on the next API call. Enter toggles logout only when a token exists.
|
|
85
|
+
const isAuthenticated = Boolean(authService.getSSOToken());
|
|
84
86
|
if (isAuthenticated) {
|
|
85
87
|
await authService.clearAuth();
|
|
86
88
|
setMessage("Logged out successfully");
|
|
@@ -123,7 +125,7 @@ export const LoginCommand: React.FC<LoginCommandProps> = ({ onCancel }) => {
|
|
|
123
125
|
}
|
|
124
126
|
};
|
|
125
127
|
|
|
126
|
-
const isAuthenticated = authService.
|
|
128
|
+
const isAuthenticated = Boolean(authService.getSSOToken());
|
|
127
129
|
const token = authService.getSSOToken();
|
|
128
130
|
const serverUrl = authService.getServerUrl();
|
|
129
131
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React, { useMemo } from "react";
|
|
2
|
-
import { Box, Text } from "ink";
|
|
2
|
+
import { Box, Text, useStdout } from "ink";
|
|
3
3
|
import { Renderer, marked, type Tokens } from "marked";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import { highlightToAnsi } from "../utils/highlightUtils.js";
|
|
6
|
+
import { renderMarkdownTable } from "../utils/markdownTable.js";
|
|
6
7
|
|
|
7
8
|
export interface MarkdownProps {
|
|
8
9
|
children: string;
|
|
@@ -19,6 +20,10 @@ const unescapeHtml = (html: string) => {
|
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
class AnsiRenderer extends Renderer<string> {
|
|
23
|
+
constructor(private readonly columns: number) {
|
|
24
|
+
super();
|
|
25
|
+
}
|
|
26
|
+
|
|
22
27
|
override code({ text, lang }: Tokens.Code): string {
|
|
23
28
|
const prefix = lang ? `\`\`\`${lang}` : "```";
|
|
24
29
|
const suffix = "```";
|
|
@@ -82,20 +87,10 @@ class AnsiRenderer extends Renderer<string> {
|
|
|
82
87
|
}
|
|
83
88
|
|
|
84
89
|
override table(token: Tokens.Table): string {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return `\n${header}\n${body}\n`;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
override tablerow({ text }: Tokens.TableRow): string {
|
|
93
|
-
return text + "\n";
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
override tablecell(token: Tokens.TableCell): string {
|
|
97
|
-
const text = token.header ? chalk.bold(token.text) : token.text;
|
|
98
|
-
return text + " | ";
|
|
90
|
+
const table = renderMarkdownTable(token, this.columns, (tokens) =>
|
|
91
|
+
this.parser.parseInline(tokens),
|
|
92
|
+
);
|
|
93
|
+
return `\n${table}\n`;
|
|
99
94
|
}
|
|
100
95
|
|
|
101
96
|
override strong({ tokens }: Tokens.Strong): string {
|
|
@@ -140,17 +135,19 @@ class AnsiRenderer extends Renderer<string> {
|
|
|
140
135
|
}
|
|
141
136
|
}
|
|
142
137
|
|
|
143
|
-
const
|
|
138
|
+
const createRenderer = (columns: number) => new AnsiRenderer(columns);
|
|
144
139
|
|
|
145
140
|
// Markdown component using custom ANSI renderer
|
|
146
141
|
export const Markdown = React.memo(({ children }: MarkdownProps) => {
|
|
142
|
+
const { stdout } = useStdout();
|
|
143
|
+
const columns = stdout?.columns ?? 80;
|
|
147
144
|
const ansiContent = useMemo(() => {
|
|
148
145
|
return marked.parse(children, {
|
|
149
|
-
renderer,
|
|
146
|
+
renderer: createRenderer(columns),
|
|
150
147
|
gfm: true,
|
|
151
148
|
breaks: true,
|
|
152
149
|
}) as string;
|
|
153
|
-
}, [children]);
|
|
150
|
+
}, [children, columns]);
|
|
154
151
|
|
|
155
152
|
return (
|
|
156
153
|
<Box flexDirection="column">
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
|
|
4
|
+
export interface NotificationsProps {
|
|
5
|
+
latestTotalTokens?: number;
|
|
6
|
+
maxInputTokens?: number;
|
|
7
|
+
showLoginHint?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const Notifications: React.FC<NotificationsProps> = ({
|
|
11
|
+
latestTotalTokens = 0,
|
|
12
|
+
maxInputTokens = 200000,
|
|
13
|
+
showLoginHint = false,
|
|
14
|
+
}) => {
|
|
15
|
+
const percentage =
|
|
16
|
+
latestTotalTokens > 0
|
|
17
|
+
? Math.min(Math.round((latestTotalTokens / maxInputTokens) * 100), 100)
|
|
18
|
+
: 0;
|
|
19
|
+
|
|
20
|
+
const contextColor =
|
|
21
|
+
percentage > 95 ? "red" : percentage > 80 ? "yellow" : "gray";
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<Box gap={1}>
|
|
25
|
+
{showLoginHint && <Text color="gray">Type /login to authenticate</Text>}
|
|
26
|
+
{percentage > 0 && (
|
|
27
|
+
<Text color={contextColor}>{percentage}% context</Text>
|
|
28
|
+
)}
|
|
29
|
+
</Box>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
@@ -4,62 +4,35 @@ import { Box, Text } from "ink";
|
|
|
4
4
|
export interface StatusLineProps {
|
|
5
5
|
permissionMode: string;
|
|
6
6
|
isShellCommand: boolean;
|
|
7
|
-
isGoalActive?: boolean;
|
|
8
|
-
goalElapsed?: string;
|
|
9
|
-
latestTotalTokens?: number;
|
|
10
|
-
maxInputTokens?: number;
|
|
11
7
|
}
|
|
12
8
|
|
|
13
9
|
export const StatusLine: React.FC<StatusLineProps> = ({
|
|
14
10
|
permissionMode,
|
|
15
11
|
isShellCommand,
|
|
16
|
-
isGoalActive,
|
|
17
|
-
goalElapsed,
|
|
18
|
-
latestTotalTokens = 0,
|
|
19
|
-
maxInputTokens = 200000,
|
|
20
12
|
}) => {
|
|
21
|
-
const percentage =
|
|
22
|
-
latestTotalTokens > 0
|
|
23
|
-
? Math.min(Math.round((latestTotalTokens / maxInputTokens) * 100), 100)
|
|
24
|
-
: 0;
|
|
25
|
-
|
|
26
|
-
const contextColor =
|
|
27
|
-
percentage > 95 ? "red" : percentage > 80 ? "yellow" : "gray";
|
|
28
|
-
|
|
29
13
|
return (
|
|
30
|
-
<Box
|
|
14
|
+
<Box>
|
|
31
15
|
{isShellCommand ? (
|
|
32
16
|
<Text color="gray">
|
|
33
17
|
Shell: <Text color="yellow">Run shell command</Text>
|
|
34
18
|
</Text>
|
|
35
19
|
) : (
|
|
36
|
-
<
|
|
37
|
-
{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
bold={permissionMode === "bypassPermissions"}
|
|
54
|
-
>
|
|
55
|
-
{permissionMode}
|
|
56
|
-
</Text>{" "}
|
|
57
|
-
(Shift+Tab to cycle)
|
|
58
|
-
</Text>
|
|
59
|
-
</Box>
|
|
60
|
-
)}
|
|
61
|
-
{percentage > 0 && (
|
|
62
|
-
<Text color={contextColor}>{percentage}% context</Text>
|
|
20
|
+
<Text color="gray">
|
|
21
|
+
Mode:{" "}
|
|
22
|
+
<Text
|
|
23
|
+
color={
|
|
24
|
+
permissionMode === "plan"
|
|
25
|
+
? "yellow"
|
|
26
|
+
: permissionMode === "bypassPermissions"
|
|
27
|
+
? "red"
|
|
28
|
+
: "cyan"
|
|
29
|
+
}
|
|
30
|
+
bold={permissionMode === "bypassPermissions"}
|
|
31
|
+
>
|
|
32
|
+
{permissionMode}
|
|
33
|
+
</Text>{" "}
|
|
34
|
+
(Shift+Tab to cycle)
|
|
35
|
+
</Text>
|
|
63
36
|
)}
|
|
64
37
|
</Box>
|
|
65
38
|
);
|
|
@@ -91,7 +91,7 @@ function getDisplayLimit(rows: number | undefined): number {
|
|
|
91
91
|
|
|
92
92
|
export const TaskList: React.FC = () => {
|
|
93
93
|
const tasks = useTasks();
|
|
94
|
-
const { isTaskListVisible } = useChat();
|
|
94
|
+
const { isTaskListVisible, isBtwActive } = useChat();
|
|
95
95
|
const { stdout } = useStdout();
|
|
96
96
|
|
|
97
97
|
const completionTimestampsRef = React.useRef<Map<string, number>>(new Map());
|
|
@@ -188,6 +188,7 @@ export const TaskList: React.FC = () => {
|
|
|
188
188
|
if (
|
|
189
189
|
tasks.length === 0 ||
|
|
190
190
|
!isTaskListVisible ||
|
|
191
|
+
isBtwActive ||
|
|
191
192
|
autoHidden ||
|
|
192
193
|
(allCompleted && !hadIncompleteRef.current)
|
|
193
194
|
) {
|
|
@@ -9,6 +9,22 @@ interface ToolDisplayProps {
|
|
|
9
9
|
isExpanded?: boolean;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
// Status dot color for a tool block. In-flight stages (start/streaming/running)
|
|
13
|
+
// never show red — the outcome isn't known until the tool reaches "end".
|
|
14
|
+
// An explicit error overrides everything.
|
|
15
|
+
export const getToolStatusColor = (
|
|
16
|
+
stage: ToolBlock["stage"],
|
|
17
|
+
success?: boolean,
|
|
18
|
+
error?: string | Error,
|
|
19
|
+
): string => {
|
|
20
|
+
if (error) return "red";
|
|
21
|
+
if (stage === "start" || stage === "streaming") return "gray";
|
|
22
|
+
if (stage === "running") return "yellow";
|
|
23
|
+
if (success) return "green";
|
|
24
|
+
if (success === false) return "red";
|
|
25
|
+
return "gray"; // Unknown state or no state information
|
|
26
|
+
};
|
|
27
|
+
|
|
12
28
|
export const ToolDisplay: React.FC<ToolDisplayProps> = ({
|
|
13
29
|
block,
|
|
14
30
|
isExpanded = false,
|
|
@@ -19,12 +35,7 @@ export const ToolDisplay: React.FC<ToolDisplayProps> = ({
|
|
|
19
35
|
// Directly use compactParams
|
|
20
36
|
// (no change needed as we destructured it above)
|
|
21
37
|
|
|
22
|
-
const getStatusColor = () =>
|
|
23
|
-
if (stage === "running") return "yellow";
|
|
24
|
-
if (success) return "green";
|
|
25
|
-
if (error || success === false) return "red";
|
|
26
|
-
return "gray"; // Unknown state or no state information
|
|
27
|
-
};
|
|
38
|
+
const getStatusColor = () => getToolStatusColor(stage, success, error);
|
|
28
39
|
|
|
29
40
|
const hasImages = () => {
|
|
30
41
|
return block.images && block.images.length > 0;
|
|
@@ -80,10 +80,4 @@ export const AVAILABLE_COMMANDS: SlashCommand[] = [
|
|
|
80
80
|
description: "Compact conversation history to reduce context usage",
|
|
81
81
|
handler: () => {},
|
|
82
82
|
},
|
|
83
|
-
{
|
|
84
|
-
id: "goal",
|
|
85
|
-
name: "goal",
|
|
86
|
-
description: "Set, check, or clear an autonomous goal for the session",
|
|
87
|
-
handler: () => {},
|
|
88
|
-
},
|
|
89
83
|
];
|