wave-code 0.14.1 → 0.14.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.
Files changed (32) hide show
  1. package/dist/components/ChatInterface.js +2 -2
  2. package/dist/components/CompactDisplay.d.ts +9 -0
  3. package/dist/components/CompactDisplay.d.ts.map +1 -0
  4. package/dist/components/{CompressDisplay.js → CompactDisplay.js} +2 -2
  5. package/dist/components/InstalledView.d.ts.map +1 -1
  6. package/dist/components/InstalledView.js +5 -2
  7. package/dist/components/LoadingIndicator.d.ts +2 -2
  8. package/dist/components/LoadingIndicator.d.ts.map +1 -1
  9. package/dist/components/LoadingIndicator.js +2 -2
  10. package/dist/components/MessageBlockItem.js +2 -2
  11. package/dist/components/ModelSelector.d.ts.map +1 -1
  12. package/dist/components/ModelSelector.js +8 -1
  13. package/dist/components/PluginList.d.ts.map +1 -1
  14. package/dist/components/PluginList.js +5 -2
  15. package/dist/contexts/useChat.d.ts +1 -1
  16. package/dist/contexts/useChat.d.ts.map +1 -1
  17. package/dist/contexts/useChat.js +6 -6
  18. package/dist/utils/usageSummary.d.ts +1 -1
  19. package/dist/utils/usageSummary.d.ts.map +1 -1
  20. package/dist/utils/usageSummary.js +7 -7
  21. package/package.json +2 -2
  22. package/src/components/ChatInterface.tsx +3 -3
  23. package/src/components/{CompressDisplay.tsx → CompactDisplay.tsx} +5 -5
  24. package/src/components/InstalledView.tsx +15 -2
  25. package/src/components/LoadingIndicator.tsx +5 -5
  26. package/src/components/MessageBlockItem.tsx +3 -3
  27. package/src/components/ModelSelector.tsx +36 -16
  28. package/src/components/PluginList.tsx +16 -2
  29. package/src/contexts/useChat.tsx +7 -7
  30. package/src/utils/usageSummary.ts +8 -8
  31. package/dist/components/CompressDisplay.d.ts +0 -9
  32. package/dist/components/CompressDisplay.d.ts.map +0 -1
@@ -10,7 +10,7 @@ import { ConfirmationDetails } from "./ConfirmationDetails.js";
10
10
  import { ConfirmationSelector } from "./ConfirmationSelector.js";
11
11
  import { useChat } from "../contexts/useChat.js";
12
12
  export const ChatInterface = () => {
13
- const { messages, isLoading, isCommandRunning, isCompressing, sendMessage, abortMessage, mcpServers, connectMcpServer, disconnectMcpServer, isExpanded, sessionId, latestTotalTokens, slashCommands, hasSlashCommand, isConfirmationVisible, hasPendingConfirmations, confirmingTool, handleConfirmationDecision, handleConfirmationCancel, version, workdir, remountKey, requestRemount, } = useChat();
13
+ const { messages, isLoading, isCommandRunning, isCompacting, sendMessage, abortMessage, mcpServers, connectMcpServer, disconnectMcpServer, isExpanded, sessionId, latestTotalTokens, slashCommands, hasSlashCommand, isConfirmationVisible, hasPendingConfirmations, confirmingTool, handleConfirmationDecision, handleConfirmationCancel, version, workdir, remountKey, requestRemount, } = useChat();
14
14
  const displayMessages = messages;
15
15
  const [forceStatic, setForceStatic] = useState(false);
16
16
  const { stdout } = useStdout();
@@ -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 }, "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 })] }))] }));
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 || isCompacting) && (_jsx(LoadingIndicator, { isLoading: isLoading, isCommandRunning: isCommandRunning, isCompacting: isCompacting, 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 })] }))] }));
41
41
  };
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import type { CompactBlock } from "wave-agent-sdk";
3
+ interface CompactDisplayProps {
4
+ block: CompactBlock;
5
+ isExpanded?: boolean;
6
+ }
7
+ export declare const CompactDisplay: React.FC<CompactDisplayProps>;
8
+ export {};
9
+ //# sourceMappingURL=CompactDisplay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompactDisplay.d.ts","sourceRoot":"","sources":["../../src/components/CompactDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,UAAU,mBAAmB;IAC3B,KAAK,EAAE,YAAY,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA+BxD,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useMemo } from "react";
3
3
  import { Box, Text } from "ink";
4
- export const CompressDisplay = ({ block }) => {
4
+ export const CompactDisplay = ({ block }) => {
5
5
  const { content } = block;
6
6
  const { displayContent } = useMemo(() => {
7
7
  if (!content) {
@@ -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: "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: "Compacted 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":"InstalledView.d.ts","sourceRoot":"","sources":["../../src/components/InstalledView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAwDjC,CAAC"}
1
+ {"version":3,"file":"InstalledView.d.ts","sourceRoot":"","sources":["../../src/components/InstalledView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAqEjC,CAAC"}
@@ -23,8 +23,11 @@ export const InstalledView = () => {
23
23
  if (installedPlugins.length === 0) {
24
24
  return (_jsx(Box, { padding: 1, children: _jsx(Text, { dimColor: true, children: "No plugins installed." }) }));
25
25
  }
26
- return (_jsx(Box, { flexDirection: "column", children: installedPlugins.map((plugin, index) => {
27
- const isSelected = index === selectedIndex;
26
+ const MAX_VISIBLE_ITEMS = 3;
27
+ const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2), Math.max(0, installedPlugins.length - MAX_VISIBLE_ITEMS)));
28
+ const visiblePlugins = installedPlugins.slice(startIndex, startIndex + MAX_VISIBLE_ITEMS);
29
+ return (_jsx(Box, { flexDirection: "column", children: visiblePlugins.map((plugin, index) => {
30
+ const isSelected = index + startIndex === selectedIndex;
28
31
  return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "cyan" : undefined, children: [isSelected ? "> " : " ", _jsx(Text, { bold: true, children: plugin.name }), _jsxs(Text, { dimColor: true, children: [" @", plugin.marketplace] }), plugin.scope && _jsxs(Text, { color: "gray", children: [" (", plugin.scope, ")"] })] }) }), isSelected && (_jsx(Box, { marginLeft: 4, children: _jsx(Text, { dimColor: true, children: "Press Enter for actions" }) }))] }, `${plugin.name}@${plugin.marketplace}`));
29
32
  }) }));
30
33
  };
@@ -1,11 +1,11 @@
1
1
  export interface LoadingIndicatorProps {
2
2
  isLoading?: boolean;
3
3
  isCommandRunning?: boolean;
4
- isCompressing?: boolean;
4
+ isCompacting?: boolean;
5
5
  latestTotalTokens?: number;
6
6
  }
7
7
  export declare const LoadingIndicator: {
8
- ({ isLoading, isCommandRunning, isCompressing, latestTotalTokens, }: LoadingIndicatorProps): import("react/jsx-runtime").JSX.Element;
8
+ ({ isLoading, isCommandRunning, isCompacting, latestTotalTokens, }: LoadingIndicatorProps): import("react/jsx-runtime").JSX.Element;
9
9
  displayName: string;
10
10
  };
11
11
  //# sourceMappingURL=LoadingIndicator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LoadingIndicator.d.ts","sourceRoot":"","sources":["../../src/components/LoadingIndicator.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,gBAAgB;yEAK1B,qBAAqB;;CAsCvB,CAAC"}
1
+ {"version":3,"file":"LoadingIndicator.d.ts","sourceRoot":"","sources":["../../src/components/LoadingIndicator.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,gBAAgB;wEAK1B,qBAAqB;;CAsCvB,CAAC"}
@@ -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
- export const LoadingIndicator = ({ isLoading = false, isCommandRunning = false, isCompressing = false, latestTotalTokens = 0, }) => {
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..." }))] }));
3
+ export const LoadingIndicator = ({ isLoading = false, isCommandRunning = false, isCompacting = false, latestTotalTokens = 0, }) => {
4
+ return (_jsxs(Box, { flexDirection: "column", children: [isLoading && !isCompacting && (_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..." }), isCompacting && (_jsx(Text, { color: "magenta", children: "\u273B Compacting message history..." }))] }));
5
5
  };
6
6
  LoadingIndicator.displayName = "LoadingIndicator";
@@ -3,7 +3,7 @@ import { Box, Text } from "ink";
3
3
  import { MessageSource } from "wave-agent-sdk";
4
4
  import { BangDisplay } from "./BangDisplay.js";
5
5
  import { ToolDisplay } from "./ToolDisplay.js";
6
- import { CompressDisplay } from "./CompressDisplay.js";
6
+ import { CompactDisplay } from "./CompactDisplay.js";
7
7
  import { ReasoningDisplay } from "./ReasoningDisplay.js";
8
8
  import { Markdown } from "./Markdown.js";
9
9
  import { TaskNotificationMessage } from "./TaskNotificationMessage.js";
@@ -11,5 +11,5 @@ export const MessageBlockItem = ({ block, message, isExpanded, paddingTop = 0, }
11
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
12
  const flat = block.content.replace(/\n/g, "\\n");
13
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 }))] }));
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 === "compact" && (_jsx(CompactDisplay, { block: block, isExpanded: isExpanded })), block.type === "reasoning" && (_jsx(ReasoningDisplay, { block: block, isExpanded: isExpanded })), block.type === "task_notification" && (_jsx(TaskNotificationMessage, { block: block }))] }));
15
15
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ModelSelector.d.ts","sourceRoot":"","sources":["../../src/components/ModelSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAkGtD,CAAC"}
1
+ {"version":3,"file":"ModelSelector.d.ts","sourceRoot":"","sources":["../../src/components/ModelSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAID,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAoHtD,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from "react";
3
3
  import { Box, Text, useInput } from "ink";
4
+ const MAX_VISIBLE_ITEMS = 5;
4
5
  export const ModelSelector = ({ onCancel, currentModel, configuredModels, onSelectModel, }) => {
5
6
  const [selectedIndex, setSelectedIndex] = useState(() => {
6
7
  const index = configuredModels.indexOf(currentModel);
@@ -27,8 +28,14 @@ export const ModelSelector = ({ onCancel, currentModel, configuredModels, onSele
27
28
  return;
28
29
  }
29
30
  });
31
+ // Calculate visible window
32
+ const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2), Math.max(0, configuredModels.length - MAX_VISIBLE_ITEMS)));
33
+ const visibleModels = configuredModels.slice(startIndex, startIndex + MAX_VISIBLE_ITEMS);
30
34
  if (configuredModels.length === 0) {
31
35
  return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "Select AI Model" }), _jsx(Text, { children: "No models configured" }), _jsx(Text, { dimColor: true, children: "Press Escape to close" })] }));
32
36
  }
33
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsx(Text, { color: "cyan", bold: true, children: "Select AI Model" }) }), _jsx(Text, { dimColor: true, children: "Select a model to use for the current session" }), configuredModels.map((model, index) => (_jsx(Box, { children: _jsxs(Text, { color: index === selectedIndex ? "black" : "white", backgroundColor: index === selectedIndex ? "cyan" : undefined, children: [index === selectedIndex ? "▶ " : " ", model, model === currentModel ? (_jsx(Text, { color: "green", children: " (current)" })) : ("")] }) }, model))), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191/\u2193 to select \u00B7 Enter to confirm \u00B7 Esc to cancel" }) })] }));
37
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsx(Text, { color: "cyan", bold: true, children: "Select AI Model" }) }), _jsx(Text, { dimColor: true, children: "Select a model to use for the current session" }), visibleModels.map((model, index) => {
38
+ const actualIndex = startIndex + index;
39
+ return (_jsx(Box, { children: _jsxs(Text, { color: actualIndex === selectedIndex ? "black" : "white", backgroundColor: actualIndex === selectedIndex ? "cyan" : undefined, children: [actualIndex === selectedIndex ? "▶ " : " ", model, model === currentModel ? (_jsx(Text, { color: "green", children: " (current)" })) : ("")] }) }, model));
40
+ }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191/\u2193 to select \u00B7 Enter to confirm \u00B7 Esc to cancel" }) })] }));
34
41
  };
@@ -1 +1 @@
1
- {"version":3,"file":"PluginList.d.ts","sourceRoot":"","sources":["../../src/components/PluginList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAExD,UAAU,eAAe;IACvB,OAAO,EAAE,CAAC,sBAAsB,GAAG;QACjC,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,EAAE,CAAC;IACL,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAoChD,CAAC"}
1
+ {"version":3,"file":"PluginList.d.ts","sourceRoot":"","sources":["../../src/components/PluginList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAExD,UAAU,eAAe;IACvB,OAAO,EAAE,CAAC,sBAAsB,GAAG;QACjC,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,EAAE,CAAC;IACL,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAID,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAgDhD,CAAC"}
@@ -1,11 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text } from "ink";
3
+ const MAX_VISIBLE_ITEMS = 3;
3
4
  export const PluginList = ({ plugins, selectedIndex, }) => {
4
5
  if (plugins.length === 0) {
5
6
  return (_jsx(Box, { padding: 1, children: _jsx(Text, { dimColor: true, children: "No plugins found." }) }));
6
7
  }
7
- return (_jsx(Box, { flexDirection: "column", children: plugins.map((plugin, index) => {
8
- const isSelected = index === selectedIndex;
8
+ const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2), Math.max(0, plugins.length - MAX_VISIBLE_ITEMS)));
9
+ const visiblePlugins = plugins.slice(startIndex, startIndex + MAX_VISIBLE_ITEMS);
10
+ return (_jsx(Box, { flexDirection: "column", children: visiblePlugins.map((plugin, index) => {
11
+ const isSelected = index + startIndex === selectedIndex;
9
12
  const pluginId = `${plugin.name}@${plugin.marketplace}`;
10
13
  return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "cyan" : undefined, children: [isSelected ? "> " : " ", _jsx(Text, { bold: true, children: plugin.name }), _jsxs(Text, { dimColor: true, children: [" @", plugin.marketplace] }), plugin.version && _jsxs(Text, { color: "blue", children: [" v", plugin.version] })] }) }), _jsx(Box, { marginLeft: 4, children: _jsx(Text, { dimColor: true, children: plugin.description }) })] }, pluginId));
11
14
  }) }));
@@ -5,7 +5,7 @@ export interface ChatContextType {
5
5
  messages: Message[];
6
6
  isLoading: boolean;
7
7
  isCommandRunning: boolean;
8
- isCompressing: boolean;
8
+ isCompacting: boolean;
9
9
  isExpanded: boolean;
10
10
  isTaskListVisible: boolean;
11
11
  setIsTaskListVisible: (visible: boolean) => void;
@@ -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":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EACf,cAAc,EACd,IAAI,EACJ,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,aAAa,EACd,MAAM,gBAAgB,CAAC;AAYxB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;IAEtB,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,oBAAoB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,cAAc,EAAE,aAAa,EAAE,CAAC;IAEhC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,CACX,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,EAClD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACjC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAE1B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,mBAAmB,EAAE,MAAM,MAAM,EAAE,CAAC;IACpC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,mBAAmB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9D,eAAe,EAAE,cAAc,EAAE,CAAC;IAElC,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,uBAAuB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK;QAC3C,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,IAAI,CAAC;IACT,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAEhD,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAEhD,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,kBAAkB,EAAE,OAAO,CAAC;IAE5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,uBAAuB,EAAE,OAAO,CAAC;IACjC,cAAc,CAAC,EAAE;QACf,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;QAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,gBAAgB,EAAE,CAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,eAAe,CAAC,EAAE,MAAM,EACxB,oBAAoB,CAAC,EAAE,OAAO,EAC9B,WAAW,CAAC,EAAE,MAAM,KACjB,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,0BAA0B,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACnE,wBAAwB,EAAE,MAAM,IAAI,CAAC;IAErC,qBAAqB,EAAE,MAAM,IAAI,CAAC;IAElC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,IAAI,CAAC;IAE3B,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,oBAAoB,EAAE,MAAM,OAAO,CAAC;QAClC,QAAQ,EAAE,OAAO,EAAE,CAAC;QACpB,UAAU,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC,CAAC;IAEH,gBAAgB,EAAE,MAAM,OAAO,gBAAgB,EAAE,aAAa,CAAC;IAC/D,cAAc,EAAE,MAAM,OAAO,gBAAgB,EAAE,WAAW,CAAC;IAC3D,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B;AAID,eAAO,MAAM,OAAO,uBAMnB,CAAC;AAEF,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA+oBpD,CAAC"}
@@ -48,7 +48,7 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
48
48
  const [latestTotalTokens, setlatestTotalTokens] = useState(0);
49
49
  const [sessionId, setSessionId] = useState("");
50
50
  const [isCommandRunning, setIsCommandRunning] = useState(false);
51
- const [isCompressing, setIsCompressing] = useState(false);
51
+ const [isCompacting, setIsCompacting] = useState(false);
52
52
  const [currentModel, setCurrentModelState] = useState("");
53
53
  const [configuredModels, setConfiguredModels] = useState([]);
54
54
  const [queuedMessages, setQueuedMessages] = useState([]);
@@ -129,8 +129,8 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
129
129
  onLatestTotalTokensChange: (tokens) => {
130
130
  throttledSetTokens(tokens);
131
131
  },
132
- onCompressionStateChange: (isCompressingState) => {
133
- setIsCompressing(isCompressingState);
132
+ onCompactionStateChange: (isCompactingState) => {
133
+ setIsCompacting(isCompactingState);
134
134
  },
135
135
  onBackgroundTasksChange: (tasks) => {
136
136
  setBackgroundTasks([...tasks]);
@@ -196,7 +196,7 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
196
196
  setIsLoading(agent.isLoading);
197
197
  setlatestTotalTokens(agent.latestTotalTokens);
198
198
  setIsCommandRunning(agent.isCommandRunning);
199
- setIsCompressing(agent.isCompressing);
199
+ setIsCompacting(agent.isCompacting);
200
200
  setPermissionModeState(agent.getPermissionMode());
201
201
  setWorkingDirectory(agent.workingDirectory);
202
202
  setCurrentModelState(agent.getModelConfig().model);
@@ -246,7 +246,7 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
246
246
  setIsLoading(false);
247
247
  setlatestTotalTokens(0);
248
248
  setIsCommandRunning(false);
249
- setIsCompressing(false);
249
+ setIsCompacting(false);
250
250
  if (currentSessionId) {
251
251
  initializeAgent(currentSessionId);
252
252
  }
@@ -477,7 +477,7 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
477
477
  configuredModels,
478
478
  getConfiguredModels,
479
479
  setModel,
480
- isCompressing,
480
+ isCompacting,
481
481
  mcpServers,
482
482
  connectMcpServer,
483
483
  disconnectMcpServer,
@@ -9,7 +9,7 @@ export interface TokenSummary {
9
9
  total_tokens: number;
10
10
  operations: {
11
11
  agent_calls: number;
12
- compressions: number;
12
+ compactions: number;
13
13
  };
14
14
  cache_read_input_tokens?: number;
15
15
  cache_creation_input_tokens?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"usageSummary.d.ts","sourceRoot":"","sources":["../../src/utils/usageSummary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE;QACV,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IAEF,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,cAAc,CAAC,EAAE;QACf,yBAAyB,EAAE,MAAM,CAAC;QAClC,yBAAyB,EAAE,MAAM,CAAC;KACnC,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,KAAK,EAAE,GACd,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAyE9B;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,KAAK,EAAE,EACf,eAAe,CAAC,EAAE,MAAM,GACvB,IAAI,CAwHN"}
1
+ {"version":3,"file":"usageSummary.d.ts","sourceRoot":"","sources":["../../src/utils/usageSummary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE;QACV,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IAEF,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,cAAc,CAAC,EAAE;QACf,yBAAyB,EAAE,MAAM,CAAC;QAClC,yBAAyB,EAAE,MAAM,CAAC;KACnC,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,KAAK,EAAE,GACd,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAyE9B;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,KAAK,EAAE,EACf,eAAe,CAAC,EAAE,MAAM,GACvB,IAAI,CAwHN"}
@@ -15,7 +15,7 @@ export function calculateTokenSummary(usages) {
15
15
  total_tokens: 0,
16
16
  operations: {
17
17
  agent_calls: 0,
18
- compressions: 0,
18
+ compactions: 0,
19
19
  },
20
20
  });
21
21
  }
@@ -52,8 +52,8 @@ export function calculateTokenSummary(usages) {
52
52
  if (usage.operation_type === "agent") {
53
53
  summary.operations.agent_calls += 1;
54
54
  }
55
- else if (usage.operation_type === "compress") {
56
- summary.operations.compressions += 1;
55
+ else if (usage.operation_type === "compact") {
56
+ summary.operations.compactions += 1;
57
57
  }
58
58
  }
59
59
  // Convert Map to Record and sort by total tokens
@@ -83,7 +83,7 @@ export function displayUsageSummary(usages, sessionFilePath) {
83
83
  let totalCompletion = 0;
84
84
  let totalTokens = 0;
85
85
  let totalAgentCalls = 0;
86
- let totalCompressions = 0;
86
+ let totalCompactions = 0;
87
87
  let totalCacheRead = 0;
88
88
  let totalCacheCreation = 0;
89
89
  let totalCache5m = 0;
@@ -121,13 +121,13 @@ export function displayUsageSummary(usages, sessionFilePath) {
121
121
  }
122
122
  }
123
123
  }
124
- console.log(` Operations: ${summary.operations.agent_calls} agent calls, ${summary.operations.compressions} compressions`);
124
+ console.log(` Operations: ${summary.operations.agent_calls} agent calls, ${summary.operations.compactions} compactions`);
125
125
  console.log();
126
126
  totalPrompt += summary.prompt_tokens;
127
127
  totalCompletion += summary.completion_tokens;
128
128
  totalTokens += summary.total_tokens;
129
129
  totalAgentCalls += summary.operations.agent_calls;
130
- totalCompressions += summary.operations.compressions;
130
+ totalCompactions += summary.operations.compactions;
131
131
  }
132
132
  if (Object.keys(summaries).length > 1) {
133
133
  console.log("Overall Total:");
@@ -149,6 +149,6 @@ export function displayUsageSummary(usages, sessionFilePath) {
149
149
  console.log(` 1h cache: ${totalCache1h.toLocaleString()} tokens`);
150
150
  }
151
151
  }
152
- console.log(` Operations: ${totalAgentCalls} agent calls, ${totalCompressions} compressions`);
152
+ console.log(` Operations: ${totalAgentCalls} agent calls, ${totalCompactions} compactions`);
153
153
  }
154
154
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-code",
3
- "version": "0.14.1",
3
+ "version": "0.14.3",
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.14.1"
45
+ "wave-agent-sdk": "0.14.3"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/react": "^19.1.8",
@@ -16,7 +16,7 @@ export const ChatInterface: React.FC = () => {
16
16
  messages,
17
17
  isLoading,
18
18
  isCommandRunning,
19
- isCompressing,
19
+ isCompacting,
20
20
  sendMessage,
21
21
  abortMessage,
22
22
  mcpServers,
@@ -79,11 +79,11 @@ export const ChatInterface: React.FC = () => {
79
79
 
80
80
  {!isConfirmationVisible && !isExpanded && (
81
81
  <>
82
- {(isLoading || isCommandRunning || isCompressing) && (
82
+ {(isLoading || isCommandRunning || isCompacting) && (
83
83
  <LoadingIndicator
84
84
  isLoading={isLoading}
85
85
  isCommandRunning={isCommandRunning}
86
- isCompressing={isCompressing}
86
+ isCompacting={isCompacting}
87
87
  latestTotalTokens={latestTotalTokens}
88
88
  />
89
89
  )}
@@ -1,13 +1,13 @@
1
1
  import React, { useMemo } from "react";
2
2
  import { Box, Text } from "ink";
3
- import type { CompressBlock } from "wave-agent-sdk";
3
+ import type { CompactBlock } from "wave-agent-sdk";
4
4
 
5
- interface CompressDisplayProps {
6
- block: CompressBlock;
5
+ interface CompactDisplayProps {
6
+ block: CompactBlock;
7
7
  isExpanded?: boolean;
8
8
  }
9
9
 
10
- export const CompressDisplay: React.FC<CompressDisplayProps> = ({ block }) => {
10
+ export const CompactDisplay: React.FC<CompactDisplayProps> = ({ block }) => {
11
11
  const { content } = block;
12
12
 
13
13
  const { displayContent } = useMemo(() => {
@@ -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>Compacted Messages</Text>
25
25
  </Box>
26
26
 
27
27
  {content && (
@@ -30,10 +30,23 @@ export const InstalledView: React.FC = () => {
30
30
  );
31
31
  }
32
32
 
33
+ const MAX_VISIBLE_ITEMS = 3;
34
+ const startIndex = Math.max(
35
+ 0,
36
+ Math.min(
37
+ selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2),
38
+ Math.max(0, installedPlugins.length - MAX_VISIBLE_ITEMS),
39
+ ),
40
+ );
41
+ const visiblePlugins = installedPlugins.slice(
42
+ startIndex,
43
+ startIndex + MAX_VISIBLE_ITEMS,
44
+ );
45
+
33
46
  return (
34
47
  <Box flexDirection="column">
35
- {installedPlugins.map((plugin, index) => {
36
- const isSelected = index === selectedIndex;
48
+ {visiblePlugins.map((plugin, index) => {
49
+ const isSelected = index + startIndex === selectedIndex;
37
50
  return (
38
51
  <Box
39
52
  key={`${plugin.name}@${plugin.marketplace}`}
@@ -4,19 +4,19 @@ import { Box, Text } from "ink";
4
4
  export interface LoadingIndicatorProps {
5
5
  isLoading?: boolean;
6
6
  isCommandRunning?: boolean;
7
- isCompressing?: boolean;
7
+ isCompacting?: boolean;
8
8
  latestTotalTokens?: number;
9
9
  }
10
10
 
11
11
  export const LoadingIndicator = ({
12
12
  isLoading = false,
13
13
  isCommandRunning = false,
14
- isCompressing = false,
14
+ isCompacting = false,
15
15
  latestTotalTokens = 0,
16
16
  }: LoadingIndicatorProps) => {
17
17
  return (
18
18
  <Box flexDirection="column">
19
- {isLoading && !isCompressing && (
19
+ {isLoading && !isCompacting && (
20
20
  <Box>
21
21
  <Text color="yellow">✻ AI is thinking... </Text>
22
22
  {latestTotalTokens > 0 && (
@@ -46,8 +46,8 @@ export const LoadingIndicator = ({
46
46
  </Box>
47
47
  )}
48
48
  {isCommandRunning && <Text color="blue">✻ Command is running...</Text>}
49
- {isCompressing && (
50
- <Text color="magenta">✻ Compressing message history...</Text>
49
+ {isCompacting && (
50
+ <Text color="magenta">✻ Compacting message history...</Text>
51
51
  )}
52
52
  </Box>
53
53
  );
@@ -4,7 +4,7 @@ import type { Message, MessageBlock } from "wave-agent-sdk";
4
4
  import { MessageSource } from "wave-agent-sdk";
5
5
  import { BangDisplay } from "./BangDisplay.js";
6
6
  import { ToolDisplay } from "./ToolDisplay.js";
7
- import { CompressDisplay } from "./CompressDisplay.js";
7
+ import { CompactDisplay } from "./CompactDisplay.js";
8
8
  import { ReasoningDisplay } from "./ReasoningDisplay.js";
9
9
  import { Markdown } from "./Markdown.js";
10
10
  import { TaskNotificationMessage } from "./TaskNotificationMessage.js";
@@ -79,8 +79,8 @@ export const MessageBlockItem = ({
79
79
  </Box>
80
80
  )}
81
81
 
82
- {block.type === "compress" && (
83
- <CompressDisplay block={block} isExpanded={isExpanded} />
82
+ {block.type === "compact" && (
83
+ <CompactDisplay block={block} isExpanded={isExpanded} />
84
84
  )}
85
85
 
86
86
  {block.type === "reasoning" && (
@@ -8,6 +8,8 @@ export interface ModelSelectorProps {
8
8
  onSelectModel: (model: string) => void;
9
9
  }
10
10
 
11
+ const MAX_VISIBLE_ITEMS = 5;
12
+
11
13
  export const ModelSelector: React.FC<ModelSelectorProps> = ({
12
14
  onCancel,
13
15
  currentModel,
@@ -46,6 +48,19 @@ export const ModelSelector: React.FC<ModelSelectorProps> = ({
46
48
  }
47
49
  });
48
50
 
51
+ // Calculate visible window
52
+ const startIndex = Math.max(
53
+ 0,
54
+ Math.min(
55
+ selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2),
56
+ Math.max(0, configuredModels.length - MAX_VISIBLE_ITEMS),
57
+ ),
58
+ );
59
+ const visibleModels = configuredModels.slice(
60
+ startIndex,
61
+ startIndex + MAX_VISIBLE_ITEMS,
62
+ );
63
+
49
64
  if (configuredModels.length === 0) {
50
65
  return (
51
66
  <Box
@@ -84,22 +99,27 @@ export const ModelSelector: React.FC<ModelSelectorProps> = ({
84
99
  </Box>
85
100
  <Text dimColor>Select a model to use for the current session</Text>
86
101
 
87
- {configuredModels.map((model, index) => (
88
- <Box key={model}>
89
- <Text
90
- color={index === selectedIndex ? "black" : "white"}
91
- backgroundColor={index === selectedIndex ? "cyan" : undefined}
92
- >
93
- {index === selectedIndex ? "▶ " : " "}
94
- {model}
95
- {model === currentModel ? (
96
- <Text color="green"> (current)</Text>
97
- ) : (
98
- ""
99
- )}
100
- </Text>
101
- </Box>
102
- ))}
102
+ {visibleModels.map((model, index) => {
103
+ const actualIndex = startIndex + index;
104
+ return (
105
+ <Box key={model}>
106
+ <Text
107
+ color={actualIndex === selectedIndex ? "black" : "white"}
108
+ backgroundColor={
109
+ actualIndex === selectedIndex ? "cyan" : undefined
110
+ }
111
+ >
112
+ {actualIndex === selectedIndex ? "▶ " : " "}
113
+ {model}
114
+ {model === currentModel ? (
115
+ <Text color="green"> (current)</Text>
116
+ ) : (
117
+ ""
118
+ )}
119
+ </Text>
120
+ </Box>
121
+ );
122
+ })}
103
123
 
104
124
  <Box marginTop={1}>
105
125
  <Text dimColor>↑/↓ to select · Enter to confirm · Esc to cancel</Text>
@@ -12,6 +12,8 @@ interface PluginListProps {
12
12
  onSelect?: (index: number) => void;
13
13
  }
14
14
 
15
+ const MAX_VISIBLE_ITEMS = 3;
16
+
15
17
  export const PluginList: React.FC<PluginListProps> = ({
16
18
  plugins,
17
19
  selectedIndex,
@@ -24,10 +26,22 @@ export const PluginList: React.FC<PluginListProps> = ({
24
26
  );
25
27
  }
26
28
 
29
+ const startIndex = Math.max(
30
+ 0,
31
+ Math.min(
32
+ selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2),
33
+ Math.max(0, plugins.length - MAX_VISIBLE_ITEMS),
34
+ ),
35
+ );
36
+ const visiblePlugins = plugins.slice(
37
+ startIndex,
38
+ startIndex + MAX_VISIBLE_ITEMS,
39
+ );
40
+
27
41
  return (
28
42
  <Box flexDirection="column">
29
- {plugins.map((plugin, index) => {
30
- const isSelected = index === selectedIndex;
43
+ {visiblePlugins.map((plugin, index) => {
44
+ const isSelected = index + startIndex === selectedIndex;
31
45
  const pluginId = `${plugin.name}@${plugin.marketplace}`;
32
46
 
33
47
  return (
@@ -37,7 +37,7 @@ export interface ChatContextType {
37
37
  messages: Message[];
38
38
  isLoading: boolean;
39
39
  isCommandRunning: boolean;
40
- isCompressing: boolean;
40
+ isCompacting: boolean;
41
41
  // Message display state
42
42
  isExpanded: boolean;
43
43
  isTaskListVisible: boolean;
@@ -204,7 +204,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
204
204
  const [latestTotalTokens, setlatestTotalTokens] = useState(0);
205
205
  const [sessionId, setSessionId] = useState("");
206
206
  const [isCommandRunning, setIsCommandRunning] = useState(false);
207
- const [isCompressing, setIsCompressing] = useState(false);
207
+ const [isCompacting, setIsCompacting] = useState(false);
208
208
  const [currentModel, setCurrentModelState] = useState("");
209
209
  const [configuredModels, setConfiguredModels] = useState<string[]>([]);
210
210
  const [queuedMessages, setQueuedMessages] = useState<QueuedMessage[]>([]);
@@ -352,8 +352,8 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
352
352
  onLatestTotalTokensChange: (tokens) => {
353
353
  throttledSetTokens(tokens);
354
354
  },
355
- onCompressionStateChange: (isCompressingState) => {
356
- setIsCompressing(isCompressingState);
355
+ onCompactionStateChange: (isCompactingState) => {
356
+ setIsCompacting(isCompactingState);
357
357
  },
358
358
  onBackgroundTasksChange: (tasks) => {
359
359
  setBackgroundTasks([...tasks]);
@@ -431,7 +431,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
431
431
  setIsLoading(agent.isLoading);
432
432
  setlatestTotalTokens(agent.latestTotalTokens);
433
433
  setIsCommandRunning(agent.isCommandRunning);
434
- setIsCompressing(agent.isCompressing);
434
+ setIsCompacting(agent.isCompacting);
435
435
  setPermissionModeState(agent.getPermissionMode());
436
436
  setWorkingDirectory(agent.workingDirectory);
437
437
  setCurrentModelState(agent.getModelConfig().model);
@@ -484,7 +484,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
484
484
  setIsLoading(false);
485
485
  setlatestTotalTokens(0);
486
486
  setIsCommandRunning(false);
487
- setIsCompressing(false);
487
+ setIsCompacting(false);
488
488
  if (currentSessionId) {
489
489
  initializeAgent(currentSessionId);
490
490
  }
@@ -753,7 +753,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
753
753
  configuredModels,
754
754
  getConfiguredModels,
755
755
  setModel,
756
- isCompressing,
756
+ isCompacting,
757
757
  mcpServers,
758
758
  connectMcpServer,
759
759
  disconnectMcpServer,
@@ -10,7 +10,7 @@ export interface TokenSummary {
10
10
  total_tokens: number;
11
11
  operations: {
12
12
  agent_calls: number;
13
- compressions: number;
13
+ compactions: number;
14
14
  };
15
15
  // Cache-related tokens (for Claude models)
16
16
  cache_read_input_tokens?: number;
@@ -42,7 +42,7 @@ export function calculateTokenSummary(
42
42
  total_tokens: 0,
43
43
  operations: {
44
44
  agent_calls: 0,
45
- compressions: 0,
45
+ compactions: 0,
46
46
  },
47
47
  });
48
48
  }
@@ -85,8 +85,8 @@ export function calculateTokenSummary(
85
85
  // Track operation types
86
86
  if (usage.operation_type === "agent") {
87
87
  summary.operations.agent_calls += 1;
88
- } else if (usage.operation_type === "compress") {
89
- summary.operations.compressions += 1;
88
+ } else if (usage.operation_type === "compact") {
89
+ summary.operations.compactions += 1;
90
90
  }
91
91
  }
92
92
 
@@ -129,7 +129,7 @@ export function displayUsageSummary(
129
129
  let totalCompletion = 0;
130
130
  let totalTokens = 0;
131
131
  let totalAgentCalls = 0;
132
- let totalCompressions = 0;
132
+ let totalCompactions = 0;
133
133
  let totalCacheRead = 0;
134
134
  let totalCacheCreation = 0;
135
135
  let totalCache5m = 0;
@@ -190,7 +190,7 @@ export function displayUsageSummary(
190
190
  }
191
191
 
192
192
  console.log(
193
- ` Operations: ${summary.operations.agent_calls} agent calls, ${summary.operations.compressions} compressions`,
193
+ ` Operations: ${summary.operations.agent_calls} agent calls, ${summary.operations.compactions} compactions`,
194
194
  );
195
195
  console.log();
196
196
 
@@ -198,7 +198,7 @@ export function displayUsageSummary(
198
198
  totalCompletion += summary.completion_tokens;
199
199
  totalTokens += summary.total_tokens;
200
200
  totalAgentCalls += summary.operations.agent_calls;
201
- totalCompressions += summary.operations.compressions;
201
+ totalCompactions += summary.operations.compactions;
202
202
  }
203
203
 
204
204
  if (Object.keys(summaries).length > 1) {
@@ -228,7 +228,7 @@ export function displayUsageSummary(
228
228
  }
229
229
 
230
230
  console.log(
231
- ` Operations: ${totalAgentCalls} agent calls, ${totalCompressions} compressions`,
231
+ ` Operations: ${totalAgentCalls} agent calls, ${totalCompactions} compactions`,
232
232
  );
233
233
  }
234
234
  }
@@ -1,9 +0,0 @@
1
- import React from "react";
2
- import type { CompressBlock } from "wave-agent-sdk";
3
- interface CompressDisplayProps {
4
- block: CompressBlock;
5
- isExpanded?: boolean;
6
- }
7
- export declare const CompressDisplay: React.FC<CompressDisplayProps>;
8
- export {};
9
- //# sourceMappingURL=CompressDisplay.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CompressDisplay.d.ts","sourceRoot":"","sources":["../../src/components/CompressDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,UAAU,oBAAoB;IAC5B,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA+B1D,CAAC"}