wave-code 0.4.0 → 0.6.1

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 (105) hide show
  1. package/dist/commands/plugin/uninstall.js +1 -1
  2. package/dist/components/App.d.ts.map +1 -1
  3. package/dist/components/App.js +38 -2
  4. package/dist/components/BackgroundTaskManager.d.ts +6 -0
  5. package/dist/components/BackgroundTaskManager.d.ts.map +1 -0
  6. package/dist/components/BackgroundTaskManager.js +114 -0
  7. package/dist/components/ChatInterface.d.ts.map +1 -1
  8. package/dist/components/ChatInterface.js +39 -5
  9. package/dist/components/CommandSelector.d.ts.map +1 -1
  10. package/dist/components/CommandSelector.js +13 -5
  11. package/dist/components/CompressDisplay.d.ts.map +1 -1
  12. package/dist/components/CompressDisplay.js +6 -10
  13. package/dist/components/ConfirmationDetails.d.ts +9 -0
  14. package/dist/components/ConfirmationDetails.d.ts.map +1 -0
  15. package/dist/components/ConfirmationDetails.js +53 -0
  16. package/dist/components/{Confirmation.d.ts → ConfirmationSelector.d.ts} +3 -3
  17. package/dist/components/ConfirmationSelector.d.ts.map +1 -0
  18. package/dist/components/{Confirmation.js → ConfirmationSelector.js} +92 -101
  19. package/dist/components/DiffDisplay.d.ts +0 -1
  20. package/dist/components/DiffDisplay.d.ts.map +1 -1
  21. package/dist/components/DiffDisplay.js +82 -60
  22. package/dist/components/FileSelector.d.ts.map +1 -1
  23. package/dist/components/FileSelector.js +2 -2
  24. package/dist/components/HistorySearch.d.ts.map +1 -1
  25. package/dist/components/HistorySearch.js +12 -4
  26. package/dist/components/InputBox.d.ts +1 -3
  27. package/dist/components/InputBox.d.ts.map +1 -1
  28. package/dist/components/InputBox.js +9 -18
  29. package/dist/components/LoadingIndicator.d.ts +11 -0
  30. package/dist/components/LoadingIndicator.d.ts.map +1 -0
  31. package/dist/components/LoadingIndicator.js +6 -0
  32. package/dist/components/Markdown.d.ts.map +1 -1
  33. package/dist/components/Markdown.js +114 -120
  34. package/dist/components/MessageItem.d.ts.map +1 -1
  35. package/dist/components/MessageItem.js +1 -2
  36. package/dist/components/MessageList.d.ts +2 -3
  37. package/dist/components/MessageList.d.ts.map +1 -1
  38. package/dist/components/MessageList.js +7 -7
  39. package/dist/components/PlanDisplay.d.ts.map +1 -1
  40. package/dist/components/PlanDisplay.js +4 -12
  41. package/dist/components/PluginDetail.js +1 -1
  42. package/dist/components/RewindCommand.d.ts +4 -0
  43. package/dist/components/RewindCommand.d.ts.map +1 -1
  44. package/dist/components/RewindCommand.js +19 -2
  45. package/dist/components/SubagentBlock.d.ts.map +1 -1
  46. package/dist/components/SubagentBlock.js +12 -5
  47. package/dist/components/TaskList.d.ts +3 -0
  48. package/dist/components/TaskList.d.ts.map +1 -0
  49. package/dist/components/TaskList.js +49 -0
  50. package/dist/components/ToolResultDisplay.d.ts.map +1 -1
  51. package/dist/components/ToolResultDisplay.js +2 -1
  52. package/dist/contexts/useChat.d.ts +15 -6
  53. package/dist/contexts/useChat.d.ts.map +1 -1
  54. package/dist/contexts/useChat.js +52 -43
  55. package/dist/hooks/useInputManager.d.ts +2 -13
  56. package/dist/hooks/useInputManager.d.ts.map +1 -1
  57. package/dist/hooks/useInputManager.js +8 -57
  58. package/dist/hooks/usePluginManager.d.ts.map +1 -1
  59. package/dist/hooks/usePluginManager.js +8 -4
  60. package/dist/hooks/useTasks.d.ts +2 -0
  61. package/dist/hooks/useTasks.d.ts.map +1 -0
  62. package/dist/hooks/useTasks.js +5 -0
  63. package/dist/managers/InputManager.d.ts +5 -28
  64. package/dist/managers/InputManager.d.ts.map +1 -1
  65. package/dist/managers/InputManager.js +26 -127
  66. package/package.json +9 -10
  67. package/src/commands/plugin/uninstall.ts +1 -1
  68. package/src/components/App.tsx +50 -3
  69. package/src/components/{BashShellManager.tsx → BackgroundTaskManager.tsx} +79 -73
  70. package/src/components/ChatInterface.tsx +79 -23
  71. package/src/components/CommandSelector.tsx +38 -20
  72. package/src/components/CompressDisplay.tsx +5 -22
  73. package/src/components/ConfirmationDetails.tsx +108 -0
  74. package/src/components/{Confirmation.tsx → ConfirmationSelector.tsx} +162 -187
  75. package/src/components/DiffDisplay.tsx +122 -107
  76. package/src/components/FileSelector.tsx +0 -2
  77. package/src/components/HistorySearch.tsx +45 -21
  78. package/src/components/InputBox.tsx +14 -34
  79. package/src/components/LoadingIndicator.tsx +56 -0
  80. package/src/components/Markdown.tsx +126 -318
  81. package/src/components/MessageItem.tsx +1 -3
  82. package/src/components/MessageList.tsx +10 -67
  83. package/src/components/PlanDisplay.tsx +5 -33
  84. package/src/components/PluginDetail.tsx +1 -1
  85. package/src/components/RewindCommand.tsx +38 -1
  86. package/src/components/SubagentBlock.tsx +28 -14
  87. package/src/components/TaskList.tsx +70 -0
  88. package/src/components/ToolResultDisplay.tsx +6 -2
  89. package/src/contexts/useChat.tsx +82 -60
  90. package/src/hooks/useInputManager.ts +9 -73
  91. package/src/hooks/usePluginManager.ts +10 -4
  92. package/src/hooks/useTasks.ts +6 -0
  93. package/src/managers/InputManager.ts +30 -157
  94. package/dist/components/BashShellManager.d.ts +0 -6
  95. package/dist/components/BashShellManager.d.ts.map +0 -1
  96. package/dist/components/BashShellManager.js +0 -116
  97. package/dist/components/Confirmation.d.ts.map +0 -1
  98. package/dist/components/MemoryDisplay.d.ts +0 -8
  99. package/dist/components/MemoryDisplay.d.ts.map +0 -1
  100. package/dist/components/MemoryDisplay.js +0 -25
  101. package/dist/components/MemoryTypeSelector.d.ts +0 -8
  102. package/dist/components/MemoryTypeSelector.d.ts.map +0 -1
  103. package/dist/components/MemoryTypeSelector.js +0 -38
  104. package/src/components/MemoryDisplay.tsx +0 -62
  105. package/src/components/MemoryTypeSelector.tsx +0 -98
@@ -1,18 +1,16 @@
1
1
  import React from "react";
2
2
  import type { McpServerStatus, SlashCommand } from "wave-agent-sdk";
3
- export declare const INPUT_PLACEHOLDER_TEXT = "Type your message (use @ to reference files, / for commands, # to add memory, Ctrl+R to search history)...";
3
+ export declare const INPUT_PLACEHOLDER_TEXT = "Type your message (use @ to reference files, / for commands, Ctrl+R to search history, Ctrl+O to expand messages, Ctrl+T to toggle tasks)...";
4
4
  export declare const INPUT_PLACEHOLDER_TEXT_PREFIX: string;
5
5
  export interface InputBoxProps {
6
6
  isLoading?: boolean;
7
7
  isCommandRunning?: boolean;
8
8
  workdir?: string;
9
- userInputHistory?: string[];
10
9
  sendMessage?: (message: string, images?: Array<{
11
10
  path: string;
12
11
  mimeType: string;
13
12
  }>) => void;
14
13
  abortMessage?: () => void;
15
- saveMemory?: (message: string, type: "project" | "user") => Promise<void>;
16
14
  mcpServers?: McpServerStatus[];
17
15
  connectMcpServer?: (serverName: string) => Promise<boolean>;
18
16
  disconnectMcpServer?: (serverName: string) => Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAazC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,+GAC2E,CAAC;AAE/G,eAAO,MAAM,6BAA6B,QAGzC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,KAC/C,IAAI,CAAC;IACV,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1E,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/D,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAClD;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA+N5C,CAAC"}
1
+ {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAYzC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,iJAC6G,CAAC;AAEjJ,eAAO,MAAM,6BAA6B,QAGzC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,KAC/C,IAAI,CAAC;IACV,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAE1B,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/D,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAClD;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA8M5C,CAAC"}
@@ -5,16 +5,15 @@ import { useInput } from "ink";
5
5
  import { FileSelector } from "./FileSelector.js";
6
6
  import { CommandSelector } from "./CommandSelector.js";
7
7
  import { HistorySearch } from "./HistorySearch.js";
8
- import { MemoryTypeSelector } from "./MemoryTypeSelector.js";
9
- import { BashShellManager } from "./BashShellManager.js";
8
+ import { BackgroundTaskManager } from "./BackgroundTaskManager.js";
10
9
  import { McpManager } from "./McpManager.js";
11
10
  import { RewindCommand } from "./RewindCommand.js";
12
11
  import { useInputManager } from "../hooks/useInputManager.js";
13
12
  import { useChat } from "../contexts/useChat.js";
14
- export const INPUT_PLACEHOLDER_TEXT = "Type your message (use @ to reference files, / for commands, # to add memory, Ctrl+R to search history)...";
13
+ export const INPUT_PLACEHOLDER_TEXT = "Type your message (use @ to reference files, / for commands, Ctrl+R to search history, Ctrl+O to expand messages, Ctrl+T to toggle tasks)...";
15
14
  export const INPUT_PLACEHOLDER_TEXT_PREFIX = INPUT_PLACEHOLDER_TEXT.substring(0, 10);
16
- export const InputBox = ({ isLoading = false, isCommandRunning = false, userInputHistory = [], sendMessage = () => { }, abortMessage = () => { }, saveMemory = async () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, }) => {
17
- const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, messages, } = useChat();
15
+ export const InputBox = ({ isLoading = false, isCommandRunning = false, sendMessage = () => { }, abortMessage = () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, }) => {
16
+ const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, } = useChat();
18
17
  // Input manager with all input state and functionality (including images)
19
18
  const { inputText, cursorPosition,
20
19
  // Image management
@@ -23,34 +22,26 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, userInpu
23
22
  showFileSelector, filteredFiles, fileSearchQuery: searchQuery, handleFileSelect, handleCancelFileSelect,
24
23
  // Command selector
25
24
  showCommandSelector, commandSearchQuery, handleCommandSelect, handleCommandInsert, handleCancelCommandSelect, handleHistorySearchSelect, handleCancelHistorySearch,
26
- // Memory type selector
27
- showMemoryTypeSelector, memoryMessage, handleMemoryTypeSelect, handleCancelMemoryTypeSelect,
28
25
  // History search
29
26
  showHistorySearch, historySearchQuery,
30
- // Bash/MCP Manager
31
- showBashManager, showMcpManager, showRewindManager, setShowBashManager, setShowMcpManager, setShowRewindManager,
27
+ // Task/MCP Manager
28
+ showBackgroundTaskManager, showMcpManager, showRewindManager, setShowBackgroundTaskManager, setShowMcpManager, setShowRewindManager,
32
29
  // Permission mode
33
30
  permissionMode, setPermissionMode,
34
- // Input history
35
- setUserInputHistory,
36
31
  // Main handler
37
32
  handleInput,
38
33
  // Manager ready state
39
34
  isManagerReady, } = useInputManager({
40
35
  onSendMessage: sendMessage,
41
36
  onHasSlashCommand: hasSlashCommand,
42
- onSaveMemory: saveMemory,
43
37
  onAbortMessage: abortMessage,
38
+ onBackgroundCurrentTask: backgroundCurrentTask,
44
39
  onPermissionModeChange: setChatPermissionMode,
45
40
  });
46
41
  // Sync permission mode from useChat to InputManager
47
42
  useEffect(() => {
48
43
  setPermissionMode(chatPermissionMode);
49
44
  }, [chatPermissionMode, setPermissionMode]);
50
- // Set user input history when it changes
51
- useEffect(() => {
52
- setUserInputHistory(userInputHistory);
53
- }, [userInputHistory, setUserInputHistory]);
54
45
  // Use the InputManager's unified input handler
55
46
  useInput(async (input, key) => {
56
47
  await handleInput(input, key, attachedImages, isLoading, isCommandRunning, clearImages);
@@ -81,7 +72,7 @@ export const InputBox = ({ isLoading = false, isCommandRunning = false, userInpu
81
72
  await handleRewindSelect(index);
82
73
  };
83
74
  if (showRewindManager) {
84
- return (_jsx(RewindCommand, { messages: messages, onSelect: handleRewindSelectWithClose, onCancel: handleRewindCancel }));
75
+ return (_jsx(RewindCommand, { messages: messages, onSelect: handleRewindSelectWithClose, onCancel: handleRewindCancel, getFullMessageThread: getFullMessageThread }));
85
76
  }
86
- return (_jsxs(Box, { flexDirection: "column", children: [showFileSelector && (_jsx(FileSelector, { files: filteredFiles, searchQuery: searchQuery, onSelect: handleFileSelect, onCancel: handleCancelFileSelect })), showCommandSelector && (_jsx(CommandSelector, { searchQuery: commandSearchQuery, onSelect: handleCommandSelect, onInsert: handleCommandInsert, onCancel: handleCancelCommandSelect, commands: slashCommands })), showHistorySearch && (_jsx(HistorySearch, { searchQuery: historySearchQuery, onSelect: handleHistorySearchSelect, onCancel: handleCancelHistorySearch })), showMemoryTypeSelector && (_jsx(MemoryTypeSelector, { message: memoryMessage, onSelect: handleMemoryTypeSelect, onCancel: handleCancelMemoryTypeSelect })), showBashManager && (_jsx(BashShellManager, { onCancel: () => setShowBashManager(false) })), showMcpManager && (_jsx(McpManager, { onCancel: () => setShowMcpManager(false), servers: mcpServers, onConnectServer: connectMcpServer, onDisconnectServer: disconnectMcpServer })), showBashManager || showMcpManager || showRewindManager || (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { borderStyle: "single", borderColor: "gray", borderLeft: false, borderRight: false, children: _jsx(Text, { color: isPlaceholder ? "gray" : "white", children: shouldShowCursor ? (_jsxs(_Fragment, { children: [beforeCursor, _jsx(Text, { backgroundColor: "white", color: "black", children: atCursor }), afterCursor] })) : (displayText) }) }), _jsx(Box, { paddingRight: 1, children: _jsxs(Text, { color: "gray", children: ["Mode:", " ", _jsx(Text, { color: permissionMode === "plan" ? "yellow" : "cyan", children: permissionMode }), " ", "(Shift+Tab to cycle)"] }) })] }))] }));
77
+ return (_jsxs(Box, { flexDirection: "column", children: [showFileSelector && (_jsx(FileSelector, { files: filteredFiles, searchQuery: searchQuery, onSelect: handleFileSelect, onCancel: handleCancelFileSelect })), showCommandSelector && (_jsx(CommandSelector, { searchQuery: commandSearchQuery, onSelect: handleCommandSelect, onInsert: handleCommandInsert, onCancel: handleCancelCommandSelect, commands: slashCommands })), showHistorySearch && (_jsx(HistorySearch, { searchQuery: historySearchQuery, onSelect: handleHistorySearchSelect, onCancel: handleCancelHistorySearch })), showBackgroundTaskManager && (_jsx(BackgroundTaskManager, { onCancel: () => setShowBackgroundTaskManager(false) })), showMcpManager && (_jsx(McpManager, { onCancel: () => setShowMcpManager(false), servers: mcpServers, onConnectServer: connectMcpServer, onDisconnectServer: disconnectMcpServer })), showBackgroundTaskManager || showMcpManager || showRewindManager || (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { borderStyle: "single", borderColor: "gray", borderLeft: false, borderRight: false, children: _jsx(Text, { color: isPlaceholder ? "gray" : "white", children: shouldShowCursor ? (_jsxs(_Fragment, { children: [beforeCursor, _jsx(Text, { backgroundColor: "white", color: "black", children: atCursor }), afterCursor] })) : (displayText) }) }), _jsx(Box, { paddingRight: 1, justifyContent: "space-between", width: "100%", children: _jsxs(Text, { color: "gray", children: ["Mode:", " ", _jsx(Text, { color: permissionMode === "plan" ? "yellow" : "cyan", children: permissionMode }), " ", "(Shift+Tab to cycle)"] }) })] }))] }));
87
78
  };
@@ -0,0 +1,11 @@
1
+ export interface LoadingIndicatorProps {
2
+ isLoading?: boolean;
3
+ isCommandRunning?: boolean;
4
+ isCompressing?: boolean;
5
+ latestTotalTokens?: number;
6
+ }
7
+ export declare const LoadingIndicator: {
8
+ ({ isLoading, isCommandRunning, isCompressing, latestTotalTokens, }: LoadingIndicatorProps): import("react/jsx-runtime").JSX.Element;
9
+ displayName: string;
10
+ };
11
+ //# sourceMappingURL=LoadingIndicator.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
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 && (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "\uD83D\uDCAD 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: "\uD83D\uDE80 Command is running..." }), isCompressing && (_jsx(Text, { color: "magenta", children: "\uD83D\uDDDC\uFE0F Compressing message history..." }))] }));
5
+ };
6
+ LoadingIndicator.displayName = "LoadingIndicator";
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAKvC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB;AA8UD,eAAO,MAAM,QAAQ,2CAA6B,aAAa,6CAQ7D,CAAC"}
1
+ {"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAKvC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAwID,eAAO,MAAM,QAAQ,2CAA6B,aAAa,6CAc7D,CAAC"}
@@ -1,8 +1,8 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import React, { useMemo } from "react";
3
- import { Box, Text, useStdout } from "ink";
4
- import { marked } from "marked";
5
- import { highlight } from "cli-highlight";
3
+ import { Box, Text } from "ink";
4
+ import { Renderer, marked } from "marked";
5
+ import chalk from "chalk";
6
6
  const unescapeHtml = (html) => {
7
7
  return html
8
8
  .replace(/&amp;/g, "&")
@@ -12,123 +12,117 @@ const unescapeHtml = (html) => {
12
12
  .replace(/&#39;/g, "'")
13
13
  .replace(/&apos;/g, "'");
14
14
  };
15
- const InlineRenderer = ({ tokens }) => {
16
- return (_jsx(_Fragment, { children: tokens.map((token, index) => {
17
- switch (token.type) {
18
- case "text": {
19
- const t = token;
20
- if (t.tokens) {
21
- return _jsx(InlineRenderer, { tokens: t.tokens }, index);
22
- }
23
- return _jsx(Text, { children: unescapeHtml(t.text) }, index);
24
- }
25
- case "strong":
26
- return (_jsx(Text, { bold: true, children: token.tokens ? (_jsx(InlineRenderer, { tokens: token.tokens })) : (unescapeHtml(token.text)) }, index));
27
- case "em":
28
- return (_jsx(Text, { italic: true, children: token.tokens ? (_jsx(InlineRenderer, { tokens: token.tokens })) : (unescapeHtml(token.text)) }, index));
29
- case "codespan":
30
- return (_jsx(Text, { color: "yellow", children: unescapeHtml(token.text) }, index));
31
- case "link": {
32
- const t = token;
33
- return (_jsxs(Text, { children: [_jsx(Text, { color: "blue", underline: true, children: t.tokens ? (_jsx(InlineRenderer, { tokens: t.tokens })) : (unescapeHtml(t.text)) }), _jsxs(Text, { color: "gray", children: [" (", t.href, ")"] })] }, index));
34
- }
35
- case "br":
36
- return _jsx(Text, { children: "\n" }, index);
37
- case "del":
38
- return (_jsx(Text, { strikethrough: true, children: token.tokens ? (_jsx(InlineRenderer, { tokens: token.tokens })) : (unescapeHtml(token.text)) }, index));
39
- default:
40
- return _jsx(Text, { children: token.raw }, index);
41
- }
42
- }) }));
43
- };
44
- const TableRenderer = ({ token }) => {
45
- const { stdout } = useStdout();
46
- const terminalWidth = (stdout?.columns || 80) - 2;
47
- const columnWidths = useMemo(() => {
48
- const numCols = token.header.length;
49
- const minWidth = 5;
50
- const maxColWidth = 40;
51
- const widths = token.header.map((h) => Math.min(maxColWidth, Math.max(minWidth, h.text.length)));
52
- token.rows.forEach((row) => {
53
- row.forEach((cell, i) => {
54
- widths[i] = Math.min(maxColWidth, Math.max(widths[i] || minWidth, cell.text.length));
55
- });
56
- });
57
- const paddedWidths = widths.map((w) => w + 2);
58
- const totalWidth = paddedWidths.reduce((a, b) => a + b, 0) + numCols + 1;
59
- if (totalWidth <= terminalWidth) {
60
- return paddedWidths;
61
- }
62
- // If table is too wide, scale down columns proportionally
63
- const availableWidth = terminalWidth - numCols - 1;
64
- const scaleFactor = availableWidth / (totalWidth - numCols - 1);
65
- return paddedWidths.map((w) => Math.max(minWidth, Math.floor(w * scaleFactor)));
66
- }, [token, terminalWidth]);
67
- return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, borderStyle: "single", borderColor: "gray", width: columnWidths.reduce((a, b) => a + b, 0) + token.header.length + 1, children: [_jsx(Box, { flexDirection: "row", borderStyle: "single", borderBottom: true, borderTop: false, borderLeft: false, borderRight: false, borderColor: "gray", children: token.header.map((cell, i) => (_jsx(Box, { width: columnWidths[i], paddingX: 1, borderStyle: "single", borderLeft: i > 0, borderRight: false, borderTop: false, borderBottom: false, borderColor: "gray", children: _jsx(Text, { bold: true, wrap: "wrap", children: _jsx(InlineRenderer, { tokens: cell.tokens }) }) }, i))) }), token.rows.map((row, rowIndex) => (_jsx(Box, { flexDirection: "row", children: row.map((cell, i) => (_jsx(Box, { width: columnWidths[i], paddingX: 1, borderStyle: "single", borderLeft: i > 0, borderRight: false, borderTop: false, borderBottom: false, borderColor: "gray", children: _jsx(Text, { wrap: "wrap", children: _jsx(InlineRenderer, { tokens: cell.tokens }) }) }, i))) }, rowIndex)))] }));
68
- };
69
- const BlockRenderer = ({ tokens }) => {
70
- return (_jsx(_Fragment, { children: tokens.map((token, index) => {
71
- switch (token.type) {
72
- case "heading": {
73
- const t = token;
74
- return (_jsx(Box, { marginBottom: 1, flexDirection: "column", children: _jsxs(Text, { bold: true, color: "cyan", children: ["#".repeat(t.depth), " ", _jsx(InlineRenderer, { tokens: t.tokens })] }) }, index));
75
- }
76
- case "paragraph": {
77
- const t = token;
78
- return (_jsx(Box, { marginBottom: 1, flexDirection: "row", children: _jsx(Text, { children: _jsx(InlineRenderer, { tokens: t.tokens }) }) }, index));
79
- }
80
- case "code": {
81
- const t = token;
82
- if (t.lang !== undefined) {
83
- const raw = token.raw.endsWith("\n")
84
- ? token.raw.slice(0, -1)
85
- : token.raw;
86
- const lines = raw.split("\n");
87
- const opening = lines[0];
88
- const closing = lines[lines.length - 1];
89
- const content = lines.slice(1, -1).join("\n");
90
- const highlighted = content
91
- ? highlight(unescapeHtml(content), {
92
- language: t.lang,
93
- ignoreIllegals: true,
94
- })
95
- : "";
96
- return (_jsxs(Box, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [_jsx(Text, { color: "gray", children: opening }), highlighted && _jsx(Text, { children: highlighted }), _jsx(Text, { color: "gray", children: closing })] }, index));
97
- }
98
- return (_jsx(Box, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: _jsx(Text, { children: unescapeHtml(t.text) }) }, index));
99
- }
100
- case "list": {
101
- const t = token;
102
- return (_jsx(Box, { flexDirection: "column", marginBottom: 1, paddingLeft: 2, children: t.items.map((item, i) => {
103
- const start = t.start || 1;
104
- return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "gray", children: t.ordered ? `${start + i}. ` : "• " }), _jsx(Box, { flexDirection: "column", flexGrow: 1, children: item.tokens.map((itemToken, itemIndex) => {
105
- if (itemToken.type === "text") {
106
- const it = itemToken;
107
- return (_jsx(Box, { flexDirection: "row", children: _jsx(Text, { children: _jsx(InlineRenderer, { tokens: it.tokens || [itemToken] }) }) }, itemIndex));
108
- }
109
- return (_jsx(BlockRenderer, { tokens: [itemToken] }, itemIndex));
110
- }) })] }, i));
111
- }) }, index));
112
- }
113
- case "blockquote": {
114
- const t = token;
115
- return (_jsx(Box, { flexDirection: "column", paddingLeft: 2, borderStyle: "single", borderLeft: true, borderRight: false, borderTop: false, borderBottom: false, borderColor: "gray", marginBottom: 1, children: _jsx(BlockRenderer, { tokens: t.tokens }) }, index));
116
- }
117
- case "hr":
118
- return (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "gray", children: "─".repeat(20) }) }, index));
119
- case "table":
120
- return _jsx(TableRenderer, { token: token }, index);
121
- case "space":
122
- return null;
123
- default:
124
- return (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: token.raw }) }, index));
125
- }
126
- }) }));
127
- };
128
- // Markdown component using custom Ink-based renderer
15
+ class AnsiRenderer extends Renderer {
16
+ code({ text, lang }) {
17
+ const prefix = lang ? `\`\`\`${lang}` : "```";
18
+ const suffix = "```";
19
+ return `\n${chalk.gray(prefix)}\n${text}\n${chalk.gray(suffix)}\n`;
20
+ }
21
+ blockquote({ tokens }) {
22
+ const body = this.parser.parse(tokens);
23
+ return ("\n" +
24
+ body
25
+ .trim()
26
+ .split("\n")
27
+ .map((line) => chalk.gray("> ") + line)
28
+ .join("\n") +
29
+ "\n");
30
+ }
31
+ heading({ tokens, depth }) {
32
+ const text = this.parser.parseInline(tokens);
33
+ const hashes = "#".repeat(depth);
34
+ return `\n${chalk.cyan(`${hashes} ${text}`)}\n`;
35
+ }
36
+ hr() {
37
+ return `\n${chalk.gray("".repeat(20))}\n`;
38
+ }
39
+ list(token) {
40
+ const body = token.items
41
+ .map((item, i) => {
42
+ const text = this.listitem(item);
43
+ const prefix = token.ordered
44
+ ? chalk.gray(`${(token.start || 1) + i}. `)
45
+ : chalk.gray("• ");
46
+ const lines = text.split("\n");
47
+ const firstLine = prefix + lines[0];
48
+ const restLines = lines
49
+ .slice(1)
50
+ .filter((line) => line.length > 0)
51
+ .map((line) => " " + line);
52
+ return [firstLine, ...restLines].join("\n") + "\n";
53
+ })
54
+ .join("");
55
+ return `\n${body}`;
56
+ }
57
+ listitem(item) {
58
+ return `${this.parser.parse(item.tokens).trim()}\n`;
59
+ }
60
+ checkbox({ checked }) {
61
+ return checked ? chalk.green("[x] ") : chalk.gray("[ ] ");
62
+ }
63
+ paragraph({ tokens }) {
64
+ const text = this.parser.parseInline(tokens);
65
+ return `\n${text}\n`;
66
+ }
67
+ table(token) {
68
+ const header = token.header.map((cell) => this.tablecell(cell)).join("");
69
+ const body = token.rows
70
+ .map((row) => row.map((cell) => this.tablecell(cell)).join("") + "\n")
71
+ .join("");
72
+ return `\n${header}\n${body}\n`;
73
+ }
74
+ tablerow({ text }) {
75
+ return text + "\n";
76
+ }
77
+ tablecell(token) {
78
+ const text = token.header ? chalk.bold(token.text) : token.text;
79
+ return text + " | ";
80
+ }
81
+ strong({ tokens }) {
82
+ const text = this.parser.parseInline(tokens);
83
+ return chalk.bold(text);
84
+ }
85
+ em({ tokens }) {
86
+ const text = this.parser.parseInline(tokens);
87
+ return chalk.italic(text);
88
+ }
89
+ codespan({ text }) {
90
+ return chalk.yellow(text);
91
+ }
92
+ br() {
93
+ return "\n";
94
+ }
95
+ del({ tokens }) {
96
+ const text = this.parser.parseInline(tokens);
97
+ return chalk.strikethrough(text);
98
+ }
99
+ link({ href, tokens }) {
100
+ const text = this.parser.parseInline(tokens);
101
+ const linkText = chalk.blue.underline(text);
102
+ const hrefText = chalk.gray(`(${href})`);
103
+ return `${linkText} ${hrefText}`;
104
+ }
105
+ image({ href, tokens, text }) {
106
+ const alt = this.parser.parseInline(tokens) || text;
107
+ return chalk.gray(`![${alt}](${href})`);
108
+ }
109
+ text(token) {
110
+ return "tokens" in token && token.tokens
111
+ ? this.parser.parseInline(token.tokens)
112
+ : unescapeHtml(token.text);
113
+ }
114
+ }
115
+ const renderer = new AnsiRenderer();
116
+ // Markdown component using custom ANSI renderer
129
117
  export const Markdown = React.memo(({ children }) => {
130
- const tokens = useMemo(() => marked.lexer(children), [children]);
131
- return (_jsx(Box, { flexDirection: "column", children: _jsx(BlockRenderer, { tokens: tokens }) }));
118
+ const ansiContent = useMemo(() => {
119
+ return marked.parse(children, {
120
+ renderer,
121
+ gfm: true,
122
+ breaks: true,
123
+ });
124
+ }, [children]);
125
+ return (_jsx(Box, { flexDirection: "column", children: _jsx(Text, { children: ansiContent.trim() }) }));
132
126
  });
133
127
  // Add display name for debugging
134
128
  Markdown.displayName = "Markdown";
@@ -1 +1 @@
1
- {"version":3,"file":"MessageItem.d.ts","sourceRoot":"","sources":["../../src/components/MessageItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAU9C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,WAAW,GAAI,4CAIzB,gBAAgB,mDAyElB,CAAC"}
1
+ {"version":3,"file":"MessageItem.d.ts","sourceRoot":"","sources":["../../src/components/MessageItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAS9C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,WAAW,GAAI,4CAIzB,gBAAgB,mDAwElB,CAAC"}
@@ -3,7 +3,6 @@ import { Box, Text } from "ink";
3
3
  import { MessageSource } from "wave-agent-sdk";
4
4
  import { CommandOutputDisplay } from "./CommandOutputDisplay.js";
5
5
  import { ToolResultDisplay } from "./ToolResultDisplay.js";
6
- import { MemoryDisplay } from "./MemoryDisplay.js";
7
6
  import { CompressDisplay } from "./CompressDisplay.js";
8
7
  import { SubagentBlock } from "./SubagentBlock.js";
9
8
  import { ReasoningDisplay } from "./ReasoningDisplay.js";
@@ -11,5 +10,5 @@ import { Markdown } from "./Markdown.js";
11
10
  export const MessageItem = ({ message, isExpanded, shouldShowHeader, }) => {
12
11
  if (message.blocks.length === 0)
13
12
  return null;
14
- return (_jsxs(Box, { flexDirection: "column", gap: 1, marginTop: 1, children: [shouldShowHeader && (_jsx(Box, { children: _jsx(Text, { color: message.role === "user" ? "cyan" : "green", bold: true, children: message.role === "user" ? "👤 You" : "🤖 Assistant" }) })), _jsx(Box, { flexDirection: "column", gap: 1, children: message.blocks.map((block, blockIndex) => (_jsxs(Box, { children: [block.type === "text" && block.content.trim() && (_jsxs(Box, { children: [block.customCommandContent && (_jsxs(Text, { color: "cyan", bold: true, children: ["\u26A1", " "] })), block.source === MessageSource.HOOK && (_jsxs(Text, { color: "magenta", bold: true, children: ["\uD83D\uDD17", " "] })), _jsx(Markdown, { children: block.content })] })), block.type === "error" && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["\u274C Error: ", block.content] }) })), 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 === "subagent" && _jsx(SubagentBlock, { block: block }), block.type === "reasoning" && _jsx(ReasoningDisplay, { block: block })] }, blockIndex))) })] }));
13
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, marginTop: 1, children: [shouldShowHeader && (_jsx(Box, { children: _jsx(Text, { color: message.role === "user" ? "cyan" : "green", bold: true, children: message.role === "user" ? "👤 You" : "🤖 Assistant" }) })), _jsx(Box, { flexDirection: "column", gap: 1, children: message.blocks.map((block, blockIndex) => (_jsxs(Box, { children: [block.type === "text" && block.content.trim() && (_jsxs(Box, { children: [block.customCommandContent && (_jsxs(Text, { color: "cyan", bold: true, children: ["\u26A1", " "] })), block.source === MessageSource.HOOK && (_jsxs(Text, { color: "magenta", bold: true, children: ["\uD83D\uDD17", " "] })), _jsx(Markdown, { children: block.content })] })), block.type === "error" && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["\u274C Error: ", block.content] }) })), 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 === "compress" && (_jsx(CompressDisplay, { block: block, isExpanded: isExpanded })), block.type === "subagent" && _jsx(SubagentBlock, { block: block }), block.type === "reasoning" && _jsx(ReasoningDisplay, { block: block })] }, blockIndex))) })] }));
15
14
  };
@@ -4,9 +4,8 @@ export interface MessageListProps {
4
4
  messages: Message[];
5
5
  isLoading?: boolean;
6
6
  isCommandRunning?: boolean;
7
- isCompressing?: boolean;
8
- latestTotalTokens?: number;
9
7
  isExpanded?: boolean;
8
+ forceStaticLastMessage?: boolean;
10
9
  }
11
- export declare const MessageList: React.MemoExoticComponent<({ messages, isLoading, isCommandRunning, isCompressing, latestTotalTokens, isExpanded, }: MessageListProps) => import("react/jsx-runtime").JSX.Element>;
10
+ export declare const MessageList: React.MemoExoticComponent<({ messages, isLoading, isCommandRunning, isExpanded, forceStaticLastMessage, }: MessageListProps) => import("react/jsx-runtime").JSX.Element>;
12
11
  //# sourceMappingURL=MessageList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG9C,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,uHAQnB,gBAAgB,6CAwIpB,CAAC"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG9C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,eAAO,MAAM,WAAW,6GAOnB,gBAAgB,6CAiFpB,CAAC"}
@@ -1,11 +1,11 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from "react";
3
3
  import { Box, Text, Static } from "ink";
4
4
  import { MessageItem } from "./MessageItem.js";
5
- export const MessageList = React.memo(({ messages, isLoading = false, isCommandRunning = false, isCompressing = false, latestTotalTokens = 0, isExpanded = false, }) => {
5
+ export const MessageList = React.memo(({ messages, isLoading = false, isCommandRunning = false, isExpanded = false, forceStaticLastMessage = false, }) => {
6
6
  // Empty message state
7
7
  if (messages.length === 0) {
8
- return (_jsx(Box, { flexDirection: "column", paddingY: 1, children: _jsx(Text, { color: "gray", children: "Welcome to WAVE Code Assistant!" }) }));
8
+ return (_jsx(Box, { flexDirection: "column", gap: 1, children: _jsx(Box, { flexDirection: "column", paddingY: 1, children: _jsx(Text, { color: "gray", children: "Welcome to WAVE Code Assistant!" }) }) }));
9
9
  }
10
10
  // Limit messages when expanded to prevent long rendering times
11
11
  const maxExpandedMessages = 20;
@@ -17,22 +17,22 @@ export const MessageList = React.memo(({ messages, isLoading = false, isCommandR
17
17
  ? messages.length - maxExpandedMessages
18
18
  : 0;
19
19
  // Compute which messages to render statically vs dynamically
20
- const shouldRenderLastDynamic = isLoading || isCommandRunning;
20
+ const shouldRenderLastDynamic = !forceStaticLastMessage && (isLoading || isCommandRunning);
21
21
  const staticMessages = shouldRenderLastDynamic
22
22
  ? displayMessages.slice(0, -1)
23
23
  : displayMessages;
24
24
  const dynamicMessages = shouldRenderLastDynamic && displayMessages.length > 0
25
25
  ? [displayMessages[displayMessages.length - 1]]
26
26
  : [];
27
- return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [omittedCount > 0 && (_jsx(Box, { children: _jsxs(Text, { color: "gray", dimColor: true, children: ["... ", omittedCount, " earlier message", omittedCount !== 1 ? "s" : "", " ", "omitted (showing latest ", maxExpandedMessages, ")"] }) })), _jsx(Static, { items: staticMessages, children: (message, key) => {
27
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, paddingBottom: 1, children: [omittedCount > 0 && (_jsx(Box, { children: _jsxs(Text, { color: "gray", dimColor: true, children: ["... ", omittedCount, " earlier message", omittedCount !== 1 ? "s" : "", " ", "omitted (showing latest ", maxExpandedMessages, ")"] }) })), _jsx(Static, { items: staticMessages, children: (message, key) => {
28
28
  // Get previous message
29
29
  const previousMessage = key > 0 ? staticMessages[key - 1] : undefined;
30
30
  return (_jsx(MessageItem, { message: message, shouldShowHeader: previousMessage?.role !== message.role, isExpanded: isExpanded }, key));
31
31
  } }), dynamicMessages.map((message, index) => {
32
32
  const messageIndex = staticMessages.length + index;
33
33
  const previousMessage = messageIndex > 0 ? displayMessages[messageIndex - 1] : undefined;
34
- return (_jsx(Box, { marginTop: -1, children: _jsx(MessageItem, { message: message, shouldShowHeader: previousMessage?.role !== message.role, isExpanded: isExpanded }) }, `dynamic-${index}`));
35
- }), (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: "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: [_jsx(Box, { children: _jsxs(Text, { color: "gray", children: ["Messages ", messages.length, 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: "cyan", children: "Ctrl+O" }), " Toggle", " ", isExpanded ? "Collapse" : "Expand"] })] }) }))] }));
34
+ return (_jsx(Box, { children: _jsx(MessageItem, { message: message, shouldShowHeader: previousMessage?.role !== message.role, isExpanded: isExpanded }) }, `dynamic-${index}`));
35
+ })] }));
36
36
  });
37
37
  // Add display name for debugging
38
38
  MessageList.displayName = "MessageList";
@@ -1 +1 @@
1
- {"version":3,"file":"PlanDisplay.d.ts","sourceRoot":"","sources":["../../src/components/PlanDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAIvC,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAoClD,CAAC"}
1
+ {"version":3,"file":"PlanDisplay.d.ts","sourceRoot":"","sources":["../../src/components/PlanDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAQlD,CAAC"}
@@ -1,14 +1,6 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useMemo } from "react";
3
- import { Box, Text, useStdout } from "ink";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box } from "ink";
4
3
  import { Markdown } from "./Markdown.js";
5
- export const PlanDisplay = ({ plan, isExpanded = false, }) => {
6
- const { stdout } = useStdout();
7
- const maxHeight = useMemo(() => {
8
- // Similar to DiffDisplay.tsx maxHeight calculation
9
- return Math.max(5, (stdout?.rows || 24) - 20);
10
- }, [stdout?.rows]);
11
- const lines = useMemo(() => plan.split("\n"), [plan]);
12
- const isOverflowing = !isExpanded && lines.length > maxHeight;
13
- return (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "cyan", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Plan Content:" }), _jsx(Box, { flexDirection: "column", height: isOverflowing ? maxHeight : undefined, overflow: "hidden", children: _jsx(Markdown, { children: plan }) }), isOverflowing && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "yellow", dimColor: true, children: ["... (plan truncated, ", lines.length, " lines total)"] }) }))] }) }));
4
+ export const PlanDisplay = ({ plan }) => {
5
+ return (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(Box, { flexDirection: "column", children: _jsx(Markdown, { children: plan }) }) }));
14
6
  };
@@ -14,8 +14,8 @@ export const PluginDetail = () => {
14
14
  const plugin = discoverablePlugins.find((p) => `${p.name}@${p.marketplace}` === state.selectedId) ||
15
15
  installedPlugins.find((p) => `${p.name}@${p.marketplace}` === state.selectedId);
16
16
  const INSTALLED_ACTIONS = [
17
- { id: "uninstall", label: "Uninstall plugin" },
18
17
  { id: "update", label: "Update plugin (reinstall)" },
18
+ { id: "uninstall", label: "Uninstall plugin" },
19
19
  ];
20
20
  const isInstalledAndEnabled = plugin && "enabled" in plugin && plugin.enabled;
21
21
  useInput((input, key) => {
@@ -4,6 +4,10 @@ export interface RewindCommandProps {
4
4
  messages: Message[];
5
5
  onSelect: (index: number) => void;
6
6
  onCancel: () => void;
7
+ getFullMessageThread?: () => Promise<{
8
+ messages: Message[];
9
+ sessionIds: string[];
10
+ }>;
7
11
  }
8
12
  export declare const RewindCommand: React.FC<RewindCommandProps>;
9
13
  //# sourceMappingURL=RewindCommand.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RewindCommand.d.ts","sourceRoot":"","sources":["../../src/components/RewindCommand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,gBAAgB,CAAC;AAEzD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAuGtD,CAAC"}
1
+ {"version":3,"file":"RewindCommand.d.ts","sourceRoot":"","sources":["../../src/components/RewindCommand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,OAAO,EAAa,MAAM,gBAAgB,CAAC;AAEzD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,OAAO,CAAC;QACnC,QAAQ,EAAE,OAAO,EAAE,CAAC;QACpB,UAAU,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC,CAAC;CACJ;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAwItD,CAAC"}
@@ -1,12 +1,26 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from "react";
2
+ import React, { useState } from "react";
3
3
  import { Box, Text, useInput } from "ink";
4
- export const RewindCommand = ({ messages, onSelect, onCancel, }) => {
4
+ export const RewindCommand = ({ messages: initialMessages, onSelect, onCancel, getFullMessageThread, }) => {
5
+ const [messages, setMessages] = useState(initialMessages);
6
+ const [isLoading, setIsLoading] = useState(!!getFullMessageThread);
7
+ React.useEffect(() => {
8
+ if (getFullMessageThread) {
9
+ getFullMessageThread().then(({ messages: fullMessages }) => {
10
+ setMessages(fullMessages);
11
+ setIsLoading(false);
12
+ });
13
+ }
14
+ }, [getFullMessageThread]);
5
15
  // Filter user messages as checkpoints
6
16
  const checkpoints = messages
7
17
  .map((msg, index) => ({ msg, index }))
8
18
  .filter(({ msg }) => msg.role === "user");
9
19
  const [selectedIndex, setSelectedIndex] = useState(checkpoints.length - 1);
20
+ // Update selectedIndex when checkpoints change (after loading full thread)
21
+ React.useEffect(() => {
22
+ setSelectedIndex(checkpoints.length - 1);
23
+ }, [checkpoints.length]);
10
24
  useInput((input, key) => {
11
25
  if (key.return) {
12
26
  if (checkpoints.length > 0 && selectedIndex >= 0) {
@@ -27,6 +41,9 @@ export const RewindCommand = ({ messages, onSelect, onCancel, }) => {
27
41
  return;
28
42
  }
29
43
  });
44
+ if (isLoading) {
45
+ return (_jsx(Box, { flexDirection: "column", paddingX: 1, borderStyle: "single", borderColor: "cyan", borderLeft: false, borderRight: false, children: _jsx(Text, { color: "cyan", children: "Loading full message thread..." }) }));
46
+ }
30
47
  if (checkpoints.length === 0) {
31
48
  return (_jsxs(Box, { flexDirection: "column", paddingX: 1, borderStyle: "single", borderColor: "yellow", borderLeft: false, borderRight: false, children: [_jsx(Text, { color: "yellow", children: "No user messages found to rewind to." }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
32
49
  }
@@ -1 +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,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAIzE,UAAU,kBAAkB;IAC1B,KAAK,EAAE,iBAAiB,CAAC;CAC1B;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA+HtD,CAAC"}
1
+ {"version":3,"file":"SubagentBlock.d.ts","sourceRoot":"","sources":["../../src/components/SubagentBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAIzE,UAAU,kBAAkB;IAC1B,KAAK,EAAE,iBAAiB,CAAC;CAC1B;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA6ItD,CAAC"}