wave-code 0.0.2 → 0.0.3

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.
@@ -43,6 +43,6 @@ export const FileSelector = ({ files, searchQuery, onSelect, onCancel, }) => {
43
43
  const actualIndex = startIndex + displayIndex;
44
44
  const isSelected = actualIndex === selectedIndex;
45
45
  const icon = fileItem.type === "directory" ? "📁" : "📄";
46
- return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "cyan" : undefined, children: [isSelected ? "â–ļ " : " ", icon, " ", fileItem.path] }) }, fileItem.path));
46
+ return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "cyan" : undefined, children: [" ", icon, " ", fileItem.path] }) }, fileItem.path));
47
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 to select, Escape to cancel" }), _jsxs(Text, { dimColor: true, children: ["File ", selectedIndex + 1, " of ", files.length] })] })] }));
48
48
  };
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAkG9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAyGlD,CAAC"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAuG9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAyGlD,CAAC"}
@@ -6,11 +6,12 @@ import { CommandOutputDisplay } from "./CommandOutputDisplay.js";
6
6
  import { ToolResultDisplay } from "./ToolResultDisplay.js";
7
7
  import { MemoryDisplay } from "./MemoryDisplay.js";
8
8
  import { CompressDisplay } from "./CompressDisplay.js";
9
+ import { SubagentBlock } from "./SubagentBlock.js";
9
10
  import { usePagination } from "../hooks/usePagination.js";
10
11
  // Function to render a single message
11
12
  const renderMessageItem = (message, originalIndex, isExpanded, previousMessage) => {
12
13
  const shouldShowHeader = previousMessage?.role !== message.role;
13
- return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [shouldShowHeader && (_jsx(Box, { children: _jsxs(Text, { color: message.role === "user" ? "cyan" : "green", bold: true, children: [message.role === "user" ? "👤 You" : "🤖 Assistant", _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "#", originalIndex + 1] })] }) })), _jsx(Box, { marginLeft: 2, flexDirection: "column", gap: 1, marginTop: shouldShowHeader ? 1 : 0, children: message.blocks.map((block, blockIndex) => (_jsxs(Box, { children: [block.type === "text" && block.content.trim() && (_jsx(Box, { children: _jsx(Text, { children: block.content }) })), block.type === "error" && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["\u274C Error: ", block.content] }) })), block.type === "diff" && (_jsx(DiffViewer, { block: block, isExpanded: isExpanded })), block.type === "command_output" && (_jsx(CommandOutputDisplay, { block: block, isExpanded: isExpanded })), block.type === "tool" && (_jsx(ToolResultDisplay, { 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 === "memory" && _jsx(MemoryDisplay, { block: block }), block.type === "compress" && (_jsx(CompressDisplay, { block: block, isExpanded: isExpanded })), block.type === "custom_command" && (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", bold: true, children: "\u26A1" }), _jsx(Text, { children: block.originalInput || `/${block.commandName}` })] }))] }, blockIndex))) })] }, `message-${originalIndex}`));
14
+ return (_jsxs(Box, { flexDirection: "column", children: [shouldShowHeader && (_jsx(Box, { children: _jsxs(Text, { color: message.role === "user" ? "cyan" : "green", bold: true, children: [message.role === "user" ? "👤 You" : "🤖 Assistant", _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "#", originalIndex + 1] })] }) })), _jsx(Box, { marginLeft: 2, flexDirection: "column", gap: 1, marginTop: shouldShowHeader ? 1 : 0, children: message.blocks.map((block, blockIndex) => (_jsxs(Box, { children: [block.type === "text" && block.content.trim() && (_jsx(Box, { children: _jsx(Text, { children: block.content }) })), block.type === "error" && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["\u274C Error: ", block.content] }) })), block.type === "diff" && (_jsx(DiffViewer, { block: block, isExpanded: isExpanded })), block.type === "command_output" && (_jsx(CommandOutputDisplay, { block: block, isExpanded: isExpanded })), block.type === "tool" && (_jsx(ToolResultDisplay, { 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 === "memory" && _jsx(MemoryDisplay, { block: block }), block.type === "compress" && (_jsx(CompressDisplay, { block: block, isExpanded: isExpanded })), block.type === "custom_command" && (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", bold: true, children: "\u26A1" }), _jsx(Text, { children: block.originalInput || `/${block.commandName}` })] })), block.type === "subagent" && (_jsx(SubagentBlock, { block: block, isExpanded: isExpanded }))] }, blockIndex))) })] }, `message-${originalIndex}`));
14
15
  };
15
16
  export const MessageList = ({ messages, isLoading = false, isCommandRunning = false, isCompressing = false, latestTotalTokens = 0, isExpanded = false, }) => {
16
17
  // Use original messages for pagination calculation
@@ -28,9 +29,9 @@ export const MessageList = ({ messages, isLoading = false, isCommandRunning = fa
28
29
  if (messages.length === 0) {
29
30
  return (_jsx(Box, { flexDirection: "column", paddingY: 1, children: _jsx(Text, { color: "gray", children: "Welcome to WAVE Code Assistant!" }) }));
30
31
  }
31
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { flexDirection: "column", children: currentMessagesWithIndex.map(({ message, originalIndex }) => {
32
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, marginTop: 1, children: [_jsx(Box, { flexDirection: "column", gap: 1, children: currentMessagesWithIndex.map(({ message, originalIndex }) => {
32
33
  // Get previous message
33
34
  const previousMessage = originalIndex > 0 ? messages[originalIndex - 1] : undefined;
34
35
  return renderMessageItem(message, originalIndex, isExpanded, previousMessage);
35
- }) }), !isExpanded && (isLoading || isCommandRunning || isCompressing) && (_jsxs(Box, { marginTop: 1, flexDirection: "column", gap: 1, children: [isLoading && (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "\uD83D\uDCAD AI is thinking... " }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "|", " "] }), _jsx(Text, { color: "blue", bold: true, children: latestTotalTokens.toLocaleString() }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "tokens |", " "] }), _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..." }))] })), messages.length > 0 && (_jsx(Box, { marginTop: 1, children: _jsxs(Box, { justifyContent: "space-between", width: "100%", children: [_jsxs(Box, { children: [_jsxs(Text, { color: "gray", children: ["Messages ", messages.length, " Page ", displayInfo.currentPage, "/", displayInfo.totalPages] }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "\u2190 ", _jsx(Text, { color: "cyan", children: "Ctrl+U/D" }), " Navigate"] })] }), _jsxs(Text, { color: "gray", dimColor: true, children: [_jsx(Text, { color: "cyan", children: "Ctrl+O" }), " Toggle", " ", isExpanded ? "Collapse" : "Expand"] })] }) }))] }));
36
+ }) }), !isExpanded && (isLoading || isCommandRunning || isCompressing) && (_jsxs(Box, { flexDirection: "column", gap: 1, children: [isLoading && (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "\uD83D\uDCAD AI is thinking... " }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "|", " "] }), _jsx(Text, { color: "blue", bold: true, children: latestTotalTokens.toLocaleString() }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "tokens |", " "] }), _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..." }))] })), messages.length > 0 && (_jsx(Box, { children: _jsxs(Box, { justifyContent: "space-between", width: "100%", children: [_jsxs(Box, { children: [_jsxs(Text, { color: "gray", children: ["Messages ", messages.length, " Page ", displayInfo.currentPage, "/", displayInfo.totalPages] }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "\u2190 ", _jsx(Text, { color: "cyan", children: "Ctrl+U/D" }), " Navigate"] })] }), _jsxs(Text, { color: "gray", dimColor: true, children: [_jsx(Text, { color: "cyan", children: "Ctrl+O" }), " Toggle", " ", isExpanded ? "Collapse" : "Expand"] })] }) }))] }));
36
37
  };
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import type { SubagentBlock as SubagentBlockType } from "wave-agent-sdk/src/types.js";
3
+ interface SubagentBlockProps {
4
+ block: SubagentBlockType;
5
+ isExpanded?: boolean;
6
+ }
7
+ export declare const SubagentBlock: React.FC<SubagentBlockProps>;
8
+ export {};
9
+ //# sourceMappingURL=SubagentBlock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubagentBlock.d.ts","sourceRoot":"","sources":["../../src/components/SubagentBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EACV,aAAa,IAAI,iBAAiB,EAGnC,MAAM,6BAA6B,CAAC;AA4BrC,UAAU,kBAAkB;IAC1B,KAAK,EAAE,iBAAiB,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAuFtD,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { ToolResultDisplay } from "./ToolResultDisplay.js";
4
+ const MessageBlockRenderer = ({ block, isExpanded, }) => {
5
+ switch (block.type) {
6
+ case "text":
7
+ return _jsx(Text, { children: block.content });
8
+ case "error":
9
+ return _jsxs(Text, { color: "red", children: ["\u274C Error: ", block.content] });
10
+ case "tool":
11
+ return _jsx(ToolResultDisplay, { block: block, isExpanded: isExpanded });
12
+ default:
13
+ return null;
14
+ }
15
+ };
16
+ export const SubagentBlock = ({ block, isExpanded = false, }) => {
17
+ // Status indicator mapping
18
+ const getStatusIndicator = (status) => {
19
+ switch (status) {
20
+ case "active":
21
+ return { icon: "🔄", color: "yellow" };
22
+ case "completed":
23
+ return { icon: "✅", color: "green" };
24
+ case "error":
25
+ return { icon: "❌", color: "red" };
26
+ case "aborted":
27
+ return { icon: "âšī¸", color: "gray" };
28
+ default:
29
+ return { icon: "âŗ", color: "gray" };
30
+ }
31
+ };
32
+ const statusInfo = getStatusIndicator(block.status);
33
+ // Determine how many messages to show
34
+ const messagesToShow = isExpanded
35
+ ? block.messages.slice(-10) // Up to 10 most recent when expanded
36
+ : block.messages.slice(-2); // Up to 2 most recent when collapsed
37
+ return (_jsxs(Box, { borderStyle: "round", borderColor: "magenta", paddingX: 1, paddingY: 0, flexDirection: "column", marginBottom: 1, children: [_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", alignItems: "center", children: [_jsxs(Box, { flexDirection: "row", alignItems: "center", children: [_jsxs(Text, { color: "cyan", children: ["\uD83E\uDD16 ", block.subagentName] }), _jsxs(Text, { color: statusInfo.color, dimColor: false, children: [" ", statusInfo.icon] })] }), !isExpanded && (_jsxs(Text, { color: "gray", dimColor: true, children: [block.messages.length, " messages"] }))] }), messagesToShow.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: 1, gap: 1, children: messagesToShow.map((message, index) => (_jsx(Box, { flexDirection: "column", marginBottom: 0, gap: 1, children: message.blocks.map((messageBlock, blockIndex) => (_jsx(Box, { flexDirection: "column", children: _jsx(MessageBlockRenderer, { block: messageBlock, isExpanded: isExpanded }) }, blockIndex))) }, index))) })), !isExpanded && block.messages.length > 2 && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "gray", dimColor: true, children: ["... and ", block.messages.length - 2, " more messages (Ctrl+O to expand)"] }) }))] }));
38
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"plain-cli.d.ts","sourceRoot":"","sources":["../src/plain-cli.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAwD3E"}
1
+ {"version":3,"file":"plain-cli.d.ts","sourceRoot":"","sources":["../src/plain-cli.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAkD3E"}
package/dist/plain-cli.js CHANGED
@@ -9,13 +9,12 @@ export async function startPlainCli(options) {
9
9
  process.exit(1);
10
10
  }
11
11
  let agent;
12
- let lastAssistantMessage;
13
12
  // Setup callbacks for agent
14
13
  const callbacks = {
15
14
  onAssistantMessageAdded: (content) => {
16
- // Store the content instead of immediately printing it
15
+ // Only output the content field, not tool calls
17
16
  if (content) {
18
- lastAssistantMessage = content;
17
+ console.log(content);
19
18
  }
20
19
  },
21
20
  };
@@ -31,10 +30,6 @@ export async function startPlainCli(options) {
31
30
  if (message && message.trim() !== "") {
32
31
  await agent.sendMessage(message);
33
32
  }
34
- // Output only the last assistant message
35
- if (lastAssistantMessage) {
36
- console.log(lastAssistantMessage);
37
- }
38
33
  // Destroy agent and exit after sendMessage completes
39
34
  agent.destroy();
40
35
  process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-code",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "CLI-based code assistant powered by AI, built with React and Ink",
5
5
  "keywords": [
6
6
  "ai",
@@ -29,7 +29,7 @@
29
29
  "yargs": "^17.7.2",
30
30
  "diff": "^8.0.2",
31
31
  "glob": "^11.0.3",
32
- "wave-agent-sdk": "0.0.2"
32
+ "wave-agent-sdk": "0.0.3"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/react": "^19.1.8",
@@ -112,7 +112,7 @@ export const FileSelector: React.FC<FileSelectorProps> = ({
112
112
  color={isSelected ? "black" : "white"}
113
113
  backgroundColor={isSelected ? "cyan" : undefined}
114
114
  >
115
- {isSelected ? "â–ļ " : " "}
115
+ {" "}
116
116
  {icon} {fileItem.path}
117
117
  </Text>
118
118
  </Box>
@@ -6,6 +6,7 @@ import { CommandOutputDisplay } from "./CommandOutputDisplay.js";
6
6
  import { ToolResultDisplay } from "./ToolResultDisplay.js";
7
7
  import { MemoryDisplay } from "./MemoryDisplay.js";
8
8
  import { CompressDisplay } from "./CompressDisplay.js";
9
+ import { SubagentBlock } from "./SubagentBlock.js";
9
10
  import { usePagination } from "../hooks/usePagination.js";
10
11
 
11
12
  // Function to render a single message
@@ -18,7 +19,7 @@ const renderMessageItem = (
18
19
  const shouldShowHeader = previousMessage?.role !== message.role;
19
20
 
20
21
  return (
21
- <Box key={`message-${originalIndex}`} flexDirection="column" marginTop={1}>
22
+ <Box key={`message-${originalIndex}`} flexDirection="column">
22
23
  {shouldShowHeader && (
23
24
  <Box>
24
25
  <Text color={message.role === "user" ? "cyan" : "green"} bold>
@@ -91,6 +92,10 @@ const renderMessageItem = (
91
92
  <Text>{block.originalInput || `/${block.commandName}`}</Text>
92
93
  </Box>
93
94
  )}
95
+
96
+ {block.type === "subagent" && (
97
+ <SubagentBlock block={block} isExpanded={isExpanded} />
98
+ )}
94
99
  </Box>
95
100
  ))}
96
101
  </Box>
@@ -138,9 +143,9 @@ export const MessageList: React.FC<MessageListProps> = ({
138
143
  }
139
144
 
140
145
  return (
141
- <Box flexDirection="column">
146
+ <Box flexDirection="column" gap={1} marginTop={1}>
142
147
  {/* Message list */}
143
- <Box flexDirection="column">
148
+ <Box flexDirection="column" gap={1}>
144
149
  {currentMessagesWithIndex.map(({ message, originalIndex }) => {
145
150
  // Get previous message
146
151
  const previousMessage =
@@ -156,7 +161,7 @@ export const MessageList: React.FC<MessageListProps> = ({
156
161
 
157
162
  {/* Loading state display - only show in non-expanded state */}
158
163
  {!isExpanded && (isLoading || isCommandRunning || isCompressing) && (
159
- <Box marginTop={1} flexDirection="column" gap={1}>
164
+ <Box flexDirection="column" gap={1}>
160
165
  {isLoading && (
161
166
  <Box>
162
167
  <Text color="yellow">💭 AI is thinking... </Text>
@@ -191,7 +196,7 @@ export const MessageList: React.FC<MessageListProps> = ({
191
196
 
192
197
  {/* Bottom info and shortcut key hints */}
193
198
  {messages.length > 0 && (
194
- <Box marginTop={1}>
199
+ <Box>
195
200
  <Box justifyContent="space-between" width="100%">
196
201
  <Box>
197
202
  <Text color="gray">
@@ -0,0 +1,127 @@
1
+ import React from "react";
2
+ import { Box, Text } from "ink";
3
+ import type {
4
+ SubagentBlock as SubagentBlockType,
5
+ Message,
6
+ MessageBlock,
7
+ } from "wave-agent-sdk/src/types.js";
8
+ import { ToolResultDisplay } from "./ToolResultDisplay.js";
9
+
10
+ // Component to render individual message blocks
11
+ interface MessageBlockRendererProps {
12
+ block: MessageBlock;
13
+ isExpanded: boolean;
14
+ }
15
+
16
+ const MessageBlockRenderer: React.FC<MessageBlockRendererProps> = ({
17
+ block,
18
+ isExpanded,
19
+ }) => {
20
+ switch (block.type) {
21
+ case "text":
22
+ return <Text>{block.content}</Text>;
23
+
24
+ case "error":
25
+ return <Text color="red">❌ Error: {block.content}</Text>;
26
+
27
+ case "tool":
28
+ return <ToolResultDisplay block={block} isExpanded={isExpanded} />;
29
+
30
+ default:
31
+ return null;
32
+ }
33
+ };
34
+
35
+ interface SubagentBlockProps {
36
+ block: SubagentBlockType;
37
+ isExpanded?: boolean;
38
+ }
39
+
40
+ export const SubagentBlock: React.FC<SubagentBlockProps> = ({
41
+ block,
42
+ isExpanded = false,
43
+ }) => {
44
+ // Status indicator mapping
45
+ const getStatusIndicator = (status: SubagentBlockType["status"]) => {
46
+ switch (status) {
47
+ case "active":
48
+ return { icon: "🔄", color: "yellow" as const };
49
+ case "completed":
50
+ return { icon: "✅", color: "green" as const };
51
+ case "error":
52
+ return { icon: "❌", color: "red" as const };
53
+ case "aborted":
54
+ return { icon: "âšī¸", color: "gray" as const };
55
+ default:
56
+ return { icon: "âŗ", color: "gray" as const };
57
+ }
58
+ };
59
+
60
+ const statusInfo = getStatusIndicator(block.status);
61
+
62
+ // Determine how many messages to show
63
+ const messagesToShow = isExpanded
64
+ ? block.messages.slice(-10) // Up to 10 most recent when expanded
65
+ : block.messages.slice(-2); // Up to 2 most recent when collapsed
66
+
67
+ return (
68
+ <Box
69
+ borderStyle="round"
70
+ borderColor="magenta"
71
+ paddingX={1}
72
+ paddingY={0}
73
+ flexDirection="column"
74
+ marginBottom={1}
75
+ >
76
+ {/* Header Section */}
77
+ <Box
78
+ flexDirection="row"
79
+ justifyContent="space-between"
80
+ alignItems="center"
81
+ >
82
+ <Box flexDirection="row" alignItems="center">
83
+ <Text color="cyan">🤖 {block.subagentName}</Text>
84
+ <Text color={statusInfo.color} dimColor={false}>
85
+ {" "}
86
+ {statusInfo.icon}
87
+ </Text>
88
+ </Box>
89
+
90
+ {!isExpanded && (
91
+ <Text color="gray" dimColor>
92
+ {block.messages.length} messages
93
+ </Text>
94
+ )}
95
+ </Box>
96
+
97
+ {/* Messages Section */}
98
+ {messagesToShow.length > 0 && (
99
+ <Box flexDirection="column" marginTop={1} gap={1}>
100
+ {messagesToShow.map((message: Message, index: number) => (
101
+ <Box key={index} flexDirection="column" marginBottom={0} gap={1}>
102
+ {message.blocks.map(
103
+ (messageBlock: MessageBlock, blockIndex: number) => (
104
+ <Box key={blockIndex} flexDirection="column">
105
+ <MessageBlockRenderer
106
+ block={messageBlock}
107
+ isExpanded={isExpanded}
108
+ />
109
+ </Box>
110
+ ),
111
+ )}
112
+ </Box>
113
+ ))}
114
+ </Box>
115
+ )}
116
+
117
+ {/* Show truncation indicator if there are more messages */}
118
+ {!isExpanded && block.messages.length > 2 && (
119
+ <Box marginTop={1}>
120
+ <Text color="gray" dimColor>
121
+ ... and {block.messages.length - 2} more messages (Ctrl+O to expand)
122
+ </Text>
123
+ </Box>
124
+ )}
125
+ </Box>
126
+ );
127
+ };
package/src/plain-cli.ts CHANGED
@@ -22,14 +22,13 @@ export async function startPlainCli(options: PlainCliOptions): Promise<void> {
22
22
  }
23
23
 
24
24
  let agent: Agent;
25
- let lastAssistantMessage: string | undefined;
26
25
 
27
26
  // Setup callbacks for agent
28
27
  const callbacks: AgentCallbacks = {
29
28
  onAssistantMessageAdded: (content?: string) => {
30
- // Store the content instead of immediately printing it
29
+ // Only output the content field, not tool calls
31
30
  if (content) {
32
- lastAssistantMessage = content;
31
+ console.log(content);
33
32
  }
34
33
  },
35
34
  };
@@ -48,11 +47,6 @@ export async function startPlainCli(options: PlainCliOptions): Promise<void> {
48
47
  await agent.sendMessage(message);
49
48
  }
50
49
 
51
- // Output only the last assistant message
52
- if (lastAssistantMessage) {
53
- console.log(lastAssistantMessage);
54
- }
55
-
56
50
  // Destroy agent and exit after sendMessage completes
57
51
  agent.destroy();
58
52
  process.exit(0);