wave-code 0.0.4 → 0.0.6

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 (102) hide show
  1. package/README.md +2 -2
  2. package/dist/components/ChatInterface.d.ts.map +1 -1
  3. package/dist/components/ChatInterface.js +4 -24
  4. package/dist/components/CommandSelector.js +4 -4
  5. package/dist/components/DiffViewer.d.ts +1 -1
  6. package/dist/components/DiffViewer.d.ts.map +1 -1
  7. package/dist/components/DiffViewer.js +15 -15
  8. package/dist/components/FileSelector.js +2 -2
  9. package/dist/components/InputBox.d.ts.map +1 -1
  10. package/dist/components/InputBox.js +46 -101
  11. package/dist/components/Markdown.d.ts +6 -0
  12. package/dist/components/Markdown.d.ts.map +1 -0
  13. package/dist/components/Markdown.js +22 -0
  14. package/dist/components/MessageItem.d.ts +9 -0
  15. package/dist/components/MessageItem.d.ts.map +1 -0
  16. package/dist/components/MessageItem.js +15 -0
  17. package/dist/components/MessageList.d.ts +1 -1
  18. package/dist/components/MessageList.d.ts.map +1 -1
  19. package/dist/components/MessageList.js +33 -32
  20. package/dist/components/SubagentBlock.d.ts +1 -2
  21. package/dist/components/SubagentBlock.d.ts.map +1 -1
  22. package/dist/components/SubagentBlock.js +29 -20
  23. package/dist/components/ToolResultDisplay.js +5 -5
  24. package/dist/contexts/useChat.d.ts +1 -0
  25. package/dist/contexts/useChat.d.ts.map +1 -1
  26. package/dist/contexts/useChat.js +29 -2
  27. package/dist/hooks/useInputManager.d.ts +93 -0
  28. package/dist/hooks/useInputManager.d.ts.map +1 -0
  29. package/dist/hooks/useInputManager.js +332 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +17 -10
  32. package/dist/managers/InputManager.d.ts +171 -0
  33. package/dist/managers/InputManager.d.ts.map +1 -0
  34. package/dist/managers/InputManager.js +826 -0
  35. package/dist/print-cli.d.ts +8 -0
  36. package/dist/print-cli.d.ts.map +1 -0
  37. package/dist/print-cli.js +128 -0
  38. package/dist/utils/constants.d.ts +1 -1
  39. package/dist/utils/constants.js +1 -1
  40. package/dist/utils/fileSearch.d.ts +20 -0
  41. package/dist/utils/fileSearch.d.ts.map +1 -0
  42. package/dist/utils/fileSearch.js +102 -0
  43. package/dist/utils/logger.js +3 -3
  44. package/dist/utils/usageSummary.d.ts +33 -0
  45. package/dist/utils/usageSummary.d.ts.map +1 -0
  46. package/dist/utils/usageSummary.js +154 -0
  47. package/package.json +10 -6
  48. package/src/components/ChatInterface.tsx +13 -43
  49. package/src/components/CommandSelector.tsx +5 -5
  50. package/src/components/DiffViewer.tsx +18 -16
  51. package/src/components/FileSelector.tsx +2 -2
  52. package/src/components/InputBox.tsx +78 -169
  53. package/src/components/Markdown.tsx +29 -0
  54. package/src/components/MessageItem.tsx +104 -0
  55. package/src/components/MessageList.tsx +142 -198
  56. package/src/components/SubagentBlock.tsx +56 -73
  57. package/src/components/ToolResultDisplay.tsx +6 -6
  58. package/src/contexts/useChat.tsx +34 -2
  59. package/src/hooks/useInputManager.ts +461 -0
  60. package/src/index.ts +20 -10
  61. package/src/managers/InputManager.ts +1132 -0
  62. package/src/print-cli.ts +160 -0
  63. package/src/utils/constants.ts +1 -1
  64. package/src/utils/fileSearch.ts +133 -0
  65. package/src/utils/logger.ts +3 -3
  66. package/src/utils/usageSummary.ts +234 -0
  67. package/dist/hooks/useBashHistorySelector.d.ts +0 -15
  68. package/dist/hooks/useBashHistorySelector.d.ts.map +0 -1
  69. package/dist/hooks/useBashHistorySelector.js +0 -61
  70. package/dist/hooks/useCommandSelector.d.ts +0 -24
  71. package/dist/hooks/useCommandSelector.d.ts.map +0 -1
  72. package/dist/hooks/useCommandSelector.js +0 -98
  73. package/dist/hooks/useFileSelector.d.ts +0 -16
  74. package/dist/hooks/useFileSelector.d.ts.map +0 -1
  75. package/dist/hooks/useFileSelector.js +0 -174
  76. package/dist/hooks/useImageManager.d.ts +0 -13
  77. package/dist/hooks/useImageManager.d.ts.map +0 -1
  78. package/dist/hooks/useImageManager.js +0 -46
  79. package/dist/hooks/useInputHistory.d.ts +0 -11
  80. package/dist/hooks/useInputHistory.d.ts.map +0 -1
  81. package/dist/hooks/useInputHistory.js +0 -64
  82. package/dist/hooks/useInputKeyboardHandler.d.ts +0 -83
  83. package/dist/hooks/useInputKeyboardHandler.d.ts.map +0 -1
  84. package/dist/hooks/useInputKeyboardHandler.js +0 -507
  85. package/dist/hooks/useInputState.d.ts +0 -14
  86. package/dist/hooks/useInputState.d.ts.map +0 -1
  87. package/dist/hooks/useInputState.js +0 -57
  88. package/dist/hooks/useMemoryTypeSelector.d.ts +0 -9
  89. package/dist/hooks/useMemoryTypeSelector.d.ts.map +0 -1
  90. package/dist/hooks/useMemoryTypeSelector.js +0 -27
  91. package/dist/plain-cli.d.ts +0 -7
  92. package/dist/plain-cli.d.ts.map +0 -1
  93. package/dist/plain-cli.js +0 -44
  94. package/src/hooks/useBashHistorySelector.ts +0 -77
  95. package/src/hooks/useCommandSelector.ts +0 -131
  96. package/src/hooks/useFileSelector.ts +0 -227
  97. package/src/hooks/useImageManager.ts +0 -64
  98. package/src/hooks/useInputHistory.ts +0 -74
  99. package/src/hooks/useInputKeyboardHandler.ts +0 -778
  100. package/src/hooks/useInputState.ts +0 -66
  101. package/src/hooks/useMemoryTypeSelector.ts +0 -40
  102. package/src/plain-cli.ts +0 -60
@@ -1,11 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text } from "ink";
3
3
  export const ToolResultDisplay = ({ block, isExpanded = false, }) => {
4
- const { parameters, result, compactParams, isRunning, success, error, name } = block;
4
+ const { parameters, result, compactParams, stage, success, error, name } = block;
5
5
  // Directly use compactParams
6
6
  // (no change needed as we destructured it above)
7
7
  const getStatusColor = () => {
8
- if (isRunning)
8
+ if (stage === "running")
9
9
  return "yellow";
10
10
  if (success)
11
11
  return "green";
@@ -14,12 +14,12 @@ export const ToolResultDisplay = ({ block, isExpanded = false, }) => {
14
14
  return "gray"; // Unknown state or no state information
15
15
  };
16
16
  const getStatusText = () => {
17
- if (isRunning)
17
+ if (stage === "running")
18
18
  return "🔄";
19
19
  if (success)
20
20
  return "";
21
21
  if (error || success === false)
22
- return "❌ Failed";
22
+ return "❌";
23
23
  return ""; // Don't display text for unknown state
24
24
  };
25
25
  const hasImages = () => {
@@ -48,5 +48,5 @@ export const ToolResultDisplay = ({ block, isExpanded = false, }) => {
48
48
  return null;
49
49
  };
50
50
  const shortResult = getShortResult();
51
- return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: "magenta", children: "\uD83D\uDD27 " }), _jsx(Text, { color: "white", children: toolName }), !isExpanded && compactParams && (_jsxs(Text, { color: "gray", children: [" (", compactParams, ")"] })), _jsxs(Text, { color: getStatusColor(), children: [" ", getStatusText()] }), hasImages() && _jsxs(Text, { color: "blue", children: [" ", getImageIndicator()] })] }), !isExpanded && shortResult && (_jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: shortResult.split("\n").map((line, index) => (_jsx(Text, { color: "white", children: line }, index))) })), isExpanded && parameters && (_jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Parameters:" }), _jsx(Text, { color: "gray", children: parameters })] })), isExpanded && result && (_jsx(Box, { flexDirection: "column", children: _jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "green", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Result:" }), _jsx(Text, { color: "white", children: result })] }) })), error && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", typeof error === "string" ? error : String(error)] }) }))] }));
51
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: "magenta", children: "\uD83D\uDD27 " }), _jsx(Text, { color: "white", children: toolName }), !isExpanded && compactParams && (_jsxs(Text, { color: "gray", children: [" ", compactParams] })), _jsxs(Text, { color: getStatusColor(), children: [" ", getStatusText()] }), hasImages() && _jsxs(Text, { color: "blue", children: [" ", getImageIndicator()] })] }), !isExpanded && shortResult && !error && (_jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: shortResult.split("\n").map((line, index) => (_jsx(Text, { color: "white", children: line }, index))) })), isExpanded && parameters && (_jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Parameters:" }), _jsx(Text, { color: "gray", children: parameters })] })), isExpanded && result && (_jsx(Box, { flexDirection: "column", children: _jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "green", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Result:" }), _jsx(Text, { color: "white", children: result })] }) })), error && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", typeof error === "string" ? error : String(error)] }) }))] }));
52
52
  };
@@ -27,6 +27,7 @@ export interface ChatContextType {
27
27
  killBackgroundShell: (shellId: string) => boolean;
28
28
  slashCommands: SlashCommand[];
29
29
  hasSlashCommand: (commandId: string) => boolean;
30
+ subagentMessages: Record<string, Message[]>;
30
31
  }
31
32
  export declare const useChat: () => ChatContextType;
32
33
  export interface ChatProviderProps {
@@ -1 +1 @@
1
- {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EACf,eAAe,EACf,YAAY,EACb,MAAM,gBAAgB,CAAC;AAKxB,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAE3B,UAAU,EAAE,OAAO,CAAC;IAEpB,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,KAC/C,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAE1B,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzE,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,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,wBAAwB,EAAE,CACxB,OAAO,EAAE,MAAM,KACZ;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/D,mBAAmB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAElD,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CACjD;AAID,eAAO,MAAM,OAAO,uBAMnB,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAwOpD,CAAC"}
1
+ {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EACf,eAAe,EACf,YAAY,EACb,MAAM,gBAAgB,CAAC;AAMxB,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAE3B,UAAU,EAAE,OAAO,CAAC;IAEpB,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,KAC/C,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAE1B,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzE,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,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,wBAAwB,EAAE,CACxB,OAAO,EAAE,MAAM,KACZ;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/D,mBAAmB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAElD,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAEhD,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;CAC7C;AAID,eAAO,MAAM,OAAO,uBAMnB,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqQpD,CAAC"}
@@ -4,6 +4,7 @@ import { useInput } from "ink";
4
4
  import { useAppConfig } from "./useAppConfig.js";
5
5
  import { Agent } from "wave-agent-sdk";
6
6
  import { logger } from "../utils/logger.js";
7
+ import { displayUsageSummary } from "../utils/usageSummary.js";
7
8
  const ChatContext = createContext(null);
8
9
  export const useChat = () => {
9
10
  const context = useContext(ChatContext);
@@ -30,11 +31,19 @@ export const ChatProvider = ({ children }) => {
30
31
  const [backgroundShells, setBackgroundShells] = useState([]);
31
32
  // Command state
32
33
  const [slashCommands, setSlashCommands] = useState([]);
34
+ // Subagent messages state
35
+ const [subagentMessages, setSubagentMessages] = useState({});
33
36
  const agentRef = useRef(null);
34
37
  // Listen for Ctrl+O hotkey to toggle collapse/expand state
35
38
  useInput((input, key) => {
36
39
  if (key.ctrl && input === "o") {
37
- setIsExpanded((prev) => !prev);
40
+ // Clear terminal screen when expanded state changes
41
+ process.stdout.write("\x1Bc", () => {
42
+ setIsExpanded((prev) => {
43
+ const newExpanded = !prev;
44
+ return newExpanded;
45
+ });
46
+ });
38
47
  }
39
48
  });
40
49
  // Initialize AI manager
@@ -48,7 +57,9 @@ export const ChatProvider = ({ children }) => {
48
57
  setMcpServers([...servers]);
49
58
  },
50
59
  onSessionIdChange: (sessionId) => {
51
- setSessionId(sessionId);
60
+ process.stdout.write("\x1Bc", () => {
61
+ setSessionId(sessionId);
62
+ });
52
63
  },
53
64
  onLatestTotalTokensChange: (tokens) => {
54
65
  setlatestTotalTokens(tokens);
@@ -62,6 +73,12 @@ export const ChatProvider = ({ children }) => {
62
73
  onShellsChange: (shells) => {
63
74
  setBackgroundShells([...shells]);
64
75
  },
76
+ onSubagentMessagesChange: (subagentId, messages) => {
77
+ setSubagentMessages((prev) => ({
78
+ ...prev,
79
+ [subagentId]: [...messages],
80
+ }));
81
+ },
65
82
  };
66
83
  try {
67
84
  const agent = await Agent.create({
@@ -96,6 +113,15 @@ export const ChatProvider = ({ children }) => {
96
113
  useEffect(() => {
97
114
  return () => {
98
115
  if (agentRef.current) {
116
+ try {
117
+ // Display usage summary before cleanup
118
+ const usages = agentRef.current.usages;
119
+ const sessionFilePath = agentRef.current.sessionFilePath;
120
+ displayUsageSummary(usages, sessionFilePath);
121
+ }
122
+ catch {
123
+ // Silently ignore usage summary errors during cleanup
124
+ }
99
125
  agentRef.current.destroy();
100
126
  }
101
127
  };
@@ -203,6 +229,7 @@ export const ChatProvider = ({ children }) => {
203
229
  killBackgroundShell,
204
230
  slashCommands,
205
231
  hasSlashCommand,
232
+ subagentMessages,
206
233
  };
207
234
  return (_jsx(ChatContext.Provider, { value: contextValue, children: children }));
208
235
  };
@@ -0,0 +1,93 @@
1
+ import { Key } from "ink";
2
+ import { InputManager, InputManagerCallbacks, AttachedImage } from "../managers/InputManager.js";
3
+ import { FileItem } from "../components/FileSelector.js";
4
+ export declare const useInputManager: (callbacks?: Partial<InputManagerCallbacks>) => {
5
+ inputText: string;
6
+ cursorPosition: number;
7
+ showFileSelector: boolean;
8
+ filteredFiles: FileItem[];
9
+ fileSearchQuery: string;
10
+ atPosition: number;
11
+ showCommandSelector: boolean;
12
+ commandSearchQuery: string;
13
+ slashPosition: number;
14
+ showBashHistorySelector: boolean;
15
+ bashHistorySearchQuery: string;
16
+ exclamationPosition: number;
17
+ showMemoryTypeSelector: boolean;
18
+ memoryMessage: string;
19
+ showBashManager: boolean;
20
+ showMcpManager: boolean;
21
+ attachedImages: AttachedImage[];
22
+ isManagerReady: boolean;
23
+ insertTextAtCursor: (text: string, callback?: (newText: string, newCursorPosition: number) => void) => void;
24
+ deleteCharAtCursor: (callback?: (newText: string, newCursorPosition: number) => void) => void;
25
+ clearInput: () => void;
26
+ moveCursorLeft: () => void;
27
+ moveCursorRight: () => void;
28
+ moveCursorToStart: () => void;
29
+ moveCursorToEnd: () => void;
30
+ activateFileSelector: (position: number) => void;
31
+ handleFileSelect: (filePath: string) => {
32
+ newInput: string;
33
+ newCursorPosition: number;
34
+ };
35
+ handleCancelFileSelect: () => void;
36
+ updateFileSearchQuery: (query: string) => void;
37
+ checkForAtDeletion: (cursorPos: number) => boolean;
38
+ activateCommandSelector: (position: number) => void;
39
+ handleCommandSelect: (command: string) => {
40
+ newInput: string;
41
+ newCursorPosition: number;
42
+ };
43
+ handleCommandInsert: (command: string) => {
44
+ newInput: string;
45
+ newCursorPosition: number;
46
+ };
47
+ handleCancelCommandSelect: () => void;
48
+ updateCommandSearchQuery: (query: string) => void;
49
+ checkForSlashDeletion: (cursorPos: number) => boolean;
50
+ activateBashHistorySelector: (position: number) => void;
51
+ handleBashHistorySelect: (command: string) => {
52
+ newInput: string;
53
+ newCursorPosition: number;
54
+ };
55
+ handleCancelBashHistorySelect: () => void;
56
+ updateBashHistorySearchQuery: (query: string) => void;
57
+ handleBashHistoryExecute: (command: string) => string;
58
+ checkForExclamationDeletion: (cursorPos: number) => boolean;
59
+ activateMemoryTypeSelector: (message: string) => void;
60
+ handleMemoryTypeSelect: (type: "project" | "user") => Promise<void>;
61
+ handleCancelMemoryTypeSelect: () => void;
62
+ setUserInputHistory: (history: string[]) => void;
63
+ navigateHistory: (direction: "up" | "down", currentInput: string) => {
64
+ newInput: string;
65
+ newCursorPosition: number;
66
+ };
67
+ resetHistoryNavigation: () => void;
68
+ handleSpecialCharInput: (char: string) => void;
69
+ setShowBashManager: (show: boolean) => void;
70
+ setShowMcpManager: (show: boolean) => void;
71
+ addImage: (imagePath: string, mimeType: string) => AttachedImage | undefined;
72
+ removeImage: (imageId: number) => void;
73
+ clearImages: () => void;
74
+ handlePasteImage: () => Promise<boolean>;
75
+ handlePasteInput: (input: string) => void;
76
+ handleSubmit: (attachedImages: Array<{
77
+ id: number;
78
+ path: string;
79
+ mimeType: string;
80
+ }>, isLoading?: boolean, isCommandRunning?: boolean) => Promise<void>;
81
+ expandLongTextPlaceholders: (text: string) => string;
82
+ clearLongTextMap: () => void;
83
+ handleBashHistoryExecuteAndSend: (command: string) => void;
84
+ handleInput: (input: string, key: Key, attachedImages: Array<{
85
+ id: number;
86
+ path: string;
87
+ mimeType: string;
88
+ }>, isLoading?: boolean, isCommandRunning?: boolean, clearImages?: () => void) => Promise<boolean>;
89
+ setInputText: (text: string) => void;
90
+ setCursorPosition: (position: number) => void;
91
+ manager: InputManager | null;
92
+ };
93
+ //# sourceMappingURL=useInputManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInputManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useInputManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACd,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAEzD,eAAO,MAAM,eAAe,GAC1B,YAAW,OAAO,CAAC,qBAAqB,CAAM;;;;;;;;;;;;;;;;;;;+BA4GpC,MAAM,aACD,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,KAAK,IAAI;oCAQrD,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,KAAK,IAAI;;;;;;qCA2Bd,MAAM;iCAK7C,MAAM;;;;;mCAe+B,MAAM;oCAIL,MAAM;wCAKF,MAAM;mCAKjD,MAAM;;;;mCAYN,MAAM;;;;;sCAemC,MAAM;uCAIL,MAAM;4CAKD,MAAM;uCAKrD,MAAM;;;;;0CAeuC,MAAM;wCAIR,MAAM;6CAID,MAAM;0CAKT,MAAM;mCAKhD,SAAS,GAAG,MAAM;;mCAWiB,MAAM,EAAE;iCAK5C,IAAI,GAAG,MAAM,gBAAgB,MAAM;;;;;mCAgBC,MAAM;+BAsFf,OAAO;8BAGR,OAAO;0BAKX,MAAM,YAAY,MAAM;2BAGvB,MAAM;;;8BAWH,MAAM;mCAKxB,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,cAC1D,OAAO,qBACA,OAAO;uCAUkB,MAAM;;+CA/GO,MAAM;yBA4HvD,MAAM,OACR,GAAG,kBACQ,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,cAC1D,OAAO,qBACA,OAAO,gBACX,MAAM,IAAI;yBA1IgB,MAAM;kCAIG,MAAM;;CA6J9D,CAAC"}
@@ -0,0 +1,332 @@
1
+ import { useEffect, useRef, useState, useCallback } from "react";
2
+ import { InputManager, } from "../managers/InputManager.js";
3
+ export const useInputManager = (callbacks = {}) => {
4
+ const managerRef = useRef(null);
5
+ const [isManagerReady, setIsManagerReady] = useState(false);
6
+ // React state that mirrors InputManager state
7
+ const [inputText, setInputText] = useState("");
8
+ const [cursorPosition, setCursorPosition] = useState(0);
9
+ const [fileSelectorState, setFileSelectorState] = useState({
10
+ show: false,
11
+ files: [],
12
+ query: "",
13
+ position: -1,
14
+ });
15
+ const [commandSelectorState, setCommandSelectorState] = useState({
16
+ show: false,
17
+ query: "",
18
+ position: -1,
19
+ });
20
+ const [bashHistorySelectorState, setBashHistorySelectorState] = useState({
21
+ show: false,
22
+ query: "",
23
+ position: -1,
24
+ });
25
+ const [memoryTypeSelectorState, setMemoryTypeSelectorState] = useState({
26
+ show: false,
27
+ message: "",
28
+ });
29
+ const [showBashManager, setShowBashManager] = useState(false);
30
+ const [showMcpManager, setShowMcpManager] = useState(false);
31
+ const [attachedImages, setAttachedImages] = useState([]);
32
+ // Create InputManager on mount and update callbacks when they change
33
+ useEffect(() => {
34
+ if (!managerRef.current) {
35
+ // Create InputManager on first mount
36
+ const manager = new InputManager({
37
+ onInputTextChange: setInputText,
38
+ onCursorPositionChange: setCursorPosition,
39
+ onFileSelectorStateChange: (show, files, query, position) => {
40
+ setFileSelectorState({ show, files, query, position });
41
+ },
42
+ onCommandSelectorStateChange: (show, query, position) => {
43
+ setCommandSelectorState({ show, query, position });
44
+ },
45
+ onBashHistorySelectorStateChange: (show, query, position) => {
46
+ setBashHistorySelectorState({ show, query, position });
47
+ },
48
+ onMemoryTypeSelectorStateChange: (show, message) => {
49
+ setMemoryTypeSelectorState({ show, message });
50
+ },
51
+ onBashManagerStateChange: (show) => {
52
+ setShowBashManager(show);
53
+ },
54
+ onMcpManagerStateChange: (show) => {
55
+ setShowMcpManager(show);
56
+ },
57
+ onImagesStateChange: setAttachedImages,
58
+ onShowBashManager: () => setShowBashManager(true),
59
+ onShowMcpManager: () => setShowMcpManager(true),
60
+ ...callbacks,
61
+ });
62
+ managerRef.current = manager;
63
+ setIsManagerReady(true);
64
+ }
65
+ else {
66
+ // Update callbacks on existing manager
67
+ managerRef.current.updateCallbacks({
68
+ onInputTextChange: setInputText,
69
+ onCursorPositionChange: setCursorPosition,
70
+ onFileSelectorStateChange: (show, files, query, position) => {
71
+ setFileSelectorState({ show, files, query, position });
72
+ },
73
+ onCommandSelectorStateChange: (show, query, position) => {
74
+ setCommandSelectorState({ show, query, position });
75
+ },
76
+ onBashHistorySelectorStateChange: (show, query, position) => {
77
+ setBashHistorySelectorState({ show, query, position });
78
+ },
79
+ onMemoryTypeSelectorStateChange: (show, message) => {
80
+ setMemoryTypeSelectorState({ show, message });
81
+ },
82
+ onBashManagerStateChange: (show) => {
83
+ setShowBashManager(show);
84
+ },
85
+ onMcpManagerStateChange: (show) => {
86
+ setShowMcpManager(show);
87
+ },
88
+ onImagesStateChange: setAttachedImages,
89
+ onShowBashManager: () => setShowBashManager(true),
90
+ onShowMcpManager: () => setShowMcpManager(true),
91
+ ...callbacks,
92
+ });
93
+ }
94
+ }, [callbacks]);
95
+ // Cleanup on unmount
96
+ useEffect(() => {
97
+ return () => {
98
+ if (managerRef.current) {
99
+ managerRef.current.destroy();
100
+ }
101
+ };
102
+ }, []);
103
+ // Expose manager methods
104
+ const insertTextAtCursor = useCallback((text, callback) => {
105
+ managerRef.current?.insertTextAtCursor(text, callback);
106
+ }, []);
107
+ const deleteCharAtCursor = useCallback((callback) => {
108
+ managerRef.current?.deleteCharAtCursor(callback);
109
+ }, []);
110
+ const clearInput = useCallback(() => {
111
+ managerRef.current?.clearInput();
112
+ }, []);
113
+ const moveCursorLeft = useCallback(() => {
114
+ managerRef.current?.moveCursorLeft();
115
+ }, []);
116
+ const moveCursorRight = useCallback(() => {
117
+ managerRef.current?.moveCursorRight();
118
+ }, []);
119
+ const moveCursorToStart = useCallback(() => {
120
+ managerRef.current?.moveCursorToStart();
121
+ }, []);
122
+ const moveCursorToEnd = useCallback(() => {
123
+ managerRef.current?.moveCursorToEnd();
124
+ }, []);
125
+ // File selector methods
126
+ const activateFileSelector = useCallback((position) => {
127
+ managerRef.current?.activateFileSelector(position);
128
+ }, []);
129
+ const handleFileSelect = useCallback((filePath) => {
130
+ return (managerRef.current?.handleFileSelect(filePath) || {
131
+ newInput: inputText,
132
+ newCursorPosition: cursorPosition,
133
+ });
134
+ }, [inputText, cursorPosition]);
135
+ const handleCancelFileSelect = useCallback(() => {
136
+ managerRef.current?.handleCancelFileSelect();
137
+ }, []);
138
+ const updateFileSearchQuery = useCallback((query) => {
139
+ managerRef.current?.updateFileSearchQuery(query);
140
+ }, []);
141
+ const checkForAtDeletion = useCallback((cursorPos) => {
142
+ return managerRef.current?.checkForAtDeletion(cursorPos) || false;
143
+ }, []);
144
+ // Command selector methods
145
+ const activateCommandSelector = useCallback((position) => {
146
+ managerRef.current?.activateCommandSelector(position);
147
+ }, []);
148
+ const handleCommandSelect = useCallback((command) => {
149
+ return (managerRef.current?.handleCommandSelect(command) || {
150
+ newInput: inputText,
151
+ newCursorPosition: cursorPosition,
152
+ });
153
+ }, [inputText, cursorPosition]);
154
+ const handleCommandInsert = useCallback((command) => {
155
+ return (managerRef.current?.handleCommandInsert(command) || {
156
+ newInput: inputText,
157
+ newCursorPosition: cursorPosition,
158
+ });
159
+ }, [inputText, cursorPosition]);
160
+ const handleCancelCommandSelect = useCallback(() => {
161
+ managerRef.current?.handleCancelCommandSelect();
162
+ }, []);
163
+ const updateCommandSearchQuery = useCallback((query) => {
164
+ managerRef.current?.updateCommandSearchQuery(query);
165
+ }, []);
166
+ const checkForSlashDeletion = useCallback((cursorPos) => {
167
+ return managerRef.current?.checkForSlashDeletion(cursorPos) || false;
168
+ }, []);
169
+ // Bash history selector methods
170
+ const activateBashHistorySelector = useCallback((position) => {
171
+ managerRef.current?.activateBashHistorySelector(position);
172
+ }, []);
173
+ const handleBashHistorySelect = useCallback((command) => {
174
+ return (managerRef.current?.handleBashHistorySelect(command) || {
175
+ newInput: inputText,
176
+ newCursorPosition: cursorPosition,
177
+ });
178
+ }, [inputText, cursorPosition]);
179
+ const handleCancelBashHistorySelect = useCallback(() => {
180
+ managerRef.current?.handleCancelBashHistorySelect();
181
+ }, []);
182
+ const updateBashHistorySearchQuery = useCallback((query) => {
183
+ managerRef.current?.updateBashHistorySearchQuery(query);
184
+ }, []);
185
+ const handleBashHistoryExecute = useCallback((command) => {
186
+ return managerRef.current?.handleBashHistoryExecute(command) || command;
187
+ }, []);
188
+ const checkForExclamationDeletion = useCallback((cursorPos) => {
189
+ return managerRef.current?.checkForExclamationDeletion(cursorPos) || false;
190
+ }, []);
191
+ // Memory type selector methods
192
+ const activateMemoryTypeSelector = useCallback((message) => {
193
+ managerRef.current?.activateMemoryTypeSelector(message);
194
+ }, []);
195
+ const handleMemoryTypeSelect = useCallback(async (type) => {
196
+ await managerRef.current?.handleMemoryTypeSelect(type);
197
+ }, []);
198
+ const handleCancelMemoryTypeSelect = useCallback(() => {
199
+ managerRef.current?.handleCancelMemoryTypeSelect();
200
+ }, []);
201
+ // Input history methods
202
+ const setUserInputHistory = useCallback((history) => {
203
+ managerRef.current?.setUserInputHistory(history);
204
+ }, []);
205
+ const navigateHistory = useCallback((direction, currentInput) => {
206
+ return (managerRef.current?.navigateHistory(direction, currentInput) || {
207
+ newInput: currentInput,
208
+ newCursorPosition: currentInput.length,
209
+ });
210
+ }, []);
211
+ const resetHistoryNavigation = useCallback(() => {
212
+ managerRef.current?.resetHistoryNavigation();
213
+ }, []);
214
+ // Special character handling
215
+ const handleSpecialCharInput = useCallback((char) => {
216
+ managerRef.current?.handleSpecialCharInput(char);
217
+ }, []);
218
+ // Direct state access methods (for compatibility with existing code)
219
+ const setInputTextDirect = useCallback((text) => {
220
+ managerRef.current?.setInputText(text);
221
+ }, []);
222
+ const setCursorPositionDirect = useCallback((position) => {
223
+ managerRef.current?.setCursorPosition(position);
224
+ }, []);
225
+ // Complex handlers that combine multiple operations
226
+ const handleBashHistoryExecuteAndSend = useCallback((command) => {
227
+ managerRef.current?.handleBashHistoryExecuteAndSend(command);
228
+ }, []);
229
+ return {
230
+ // State
231
+ inputText,
232
+ cursorPosition,
233
+ showFileSelector: fileSelectorState.show,
234
+ filteredFiles: fileSelectorState.files,
235
+ fileSearchQuery: fileSelectorState.query,
236
+ atPosition: fileSelectorState.position,
237
+ showCommandSelector: commandSelectorState.show,
238
+ commandSearchQuery: commandSelectorState.query,
239
+ slashPosition: commandSelectorState.position,
240
+ showBashHistorySelector: bashHistorySelectorState.show,
241
+ bashHistorySearchQuery: bashHistorySelectorState.query,
242
+ exclamationPosition: bashHistorySelectorState.position,
243
+ showMemoryTypeSelector: memoryTypeSelectorState.show,
244
+ memoryMessage: memoryTypeSelectorState.message,
245
+ showBashManager,
246
+ showMcpManager,
247
+ attachedImages,
248
+ isManagerReady,
249
+ // Methods
250
+ insertTextAtCursor,
251
+ deleteCharAtCursor,
252
+ clearInput,
253
+ moveCursorLeft,
254
+ moveCursorRight,
255
+ moveCursorToStart,
256
+ moveCursorToEnd,
257
+ // File selector
258
+ activateFileSelector,
259
+ handleFileSelect,
260
+ handleCancelFileSelect,
261
+ updateFileSearchQuery,
262
+ checkForAtDeletion,
263
+ // Command selector
264
+ activateCommandSelector,
265
+ handleCommandSelect,
266
+ handleCommandInsert,
267
+ handleCancelCommandSelect,
268
+ updateCommandSearchQuery,
269
+ checkForSlashDeletion,
270
+ // Bash history selector
271
+ activateBashHistorySelector,
272
+ handleBashHistorySelect,
273
+ handleCancelBashHistorySelect,
274
+ updateBashHistorySearchQuery,
275
+ handleBashHistoryExecute,
276
+ checkForExclamationDeletion,
277
+ // Memory type selector
278
+ activateMemoryTypeSelector,
279
+ handleMemoryTypeSelect,
280
+ handleCancelMemoryTypeSelect,
281
+ // Input history
282
+ setUserInputHistory,
283
+ navigateHistory,
284
+ resetHistoryNavigation,
285
+ // Special handling
286
+ handleSpecialCharInput,
287
+ // Bash/MCP Manager
288
+ setShowBashManager: useCallback((show) => {
289
+ managerRef.current?.setShowBashManager(show);
290
+ }, []),
291
+ setShowMcpManager: useCallback((show) => {
292
+ managerRef.current?.setShowMcpManager(show);
293
+ }, []),
294
+ // Image management
295
+ addImage: useCallback((imagePath, mimeType) => {
296
+ return managerRef.current?.addImage(imagePath, mimeType);
297
+ }, []),
298
+ removeImage: useCallback((imageId) => {
299
+ managerRef.current?.removeImage(imageId);
300
+ }, []),
301
+ clearImages: useCallback(() => {
302
+ managerRef.current?.clearImages();
303
+ }, []),
304
+ handlePasteImage: useCallback(async () => {
305
+ return (await managerRef.current?.handlePasteImage()) || false;
306
+ }, []),
307
+ // Paste and text handling
308
+ handlePasteInput: useCallback((input) => {
309
+ managerRef.current?.handlePasteInput(input);
310
+ }, []),
311
+ handleSubmit: useCallback(async (attachedImages, isLoading = false, isCommandRunning = false) => {
312
+ await managerRef.current?.handleSubmit(attachedImages, isLoading, isCommandRunning);
313
+ }, []),
314
+ expandLongTextPlaceholders: useCallback((text) => {
315
+ return managerRef.current?.expandLongTextPlaceholders(text) || text;
316
+ }, []),
317
+ clearLongTextMap: useCallback(() => {
318
+ managerRef.current?.clearLongTextMap();
319
+ }, []),
320
+ // Complex handlers combining multiple operations
321
+ handleBashHistoryExecuteAndSend,
322
+ // Main input handler
323
+ handleInput: useCallback(async (input, key, attachedImages, isLoading = false, isCommandRunning = false, clearImages) => {
324
+ return ((await managerRef.current?.handleInput(input, key, attachedImages, isLoading, isCommandRunning, clearImages)) || false);
325
+ }, []),
326
+ // Direct state setters (for React compatibility)
327
+ setInputText: setInputTextDirect,
328
+ setCursorPosition: setCursorPositionDirect,
329
+ // Manager reference for advanced usage
330
+ manager: managerRef.current,
331
+ };
332
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,wBAAsB,IAAI,kBA+EzB;AAGD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,wBAAsB,IAAI,kBAyFzB;AAGD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import yargs from "yargs";
2
2
  import { hideBin } from "yargs/helpers";
3
3
  import { startCli } from "./cli.js";
4
- import { listSessions } from "wave-agent-sdk";
4
+ import { listSessions, getSessionFilePath } from "wave-agent-sdk";
5
5
  // Export main function for external use
6
6
  export async function main() {
7
7
  const argv = await yargs(hideBin(process.argv))
@@ -15,10 +15,14 @@ export async function main() {
15
15
  description: "Continue from last session",
16
16
  type: "boolean",
17
17
  })
18
- .option("plain", {
18
+ .option("print", {
19
19
  alias: "p",
20
- description: "Plain mode with message to send",
20
+ description: "Print response without interactive mode",
21
21
  type: "string",
22
+ })
23
+ .option("show-stats", {
24
+ description: "Show timing and usage statistics in print mode",
25
+ type: "boolean",
22
26
  })
23
27
  .option("list-sessions", {
24
28
  description: "List all available sessions",
@@ -29,8 +33,8 @@ export async function main() {
29
33
  .example("$0", "Start CLI with default settings")
30
34
  .example("$0 --restore session_123", "Restore specific session")
31
35
  .example("$0 --continue", "Continue from last session")
32
- .example("$0 --plain 'Hello'", "Send message in plain mode")
33
- .example("$0 -p 'Hello'", "Send message in plain mode (short)")
36
+ .example("$0 --print 'Hello'", "Send message in print mode")
37
+ .example("$0 -p 'Hello' --show-stats", "Send message in print mode with statistics")
34
38
  .example("$0 --list-sessions", "List all available sessions")
35
39
  .help("h")
36
40
  .parseAsync();
@@ -48,8 +52,10 @@ export async function main() {
48
52
  for (const session of sessions) {
49
53
  const startedAt = new Date(session.startedAt).toLocaleString();
50
54
  const lastActiveAt = new Date(session.lastActiveAt).toLocaleString();
55
+ const filePath = await getSessionFilePath(session.id, session.workdir);
51
56
  console.log(`ID: ${session.id}`);
52
57
  console.log(` Workdir: ${session.workdir}`);
58
+ console.log(` File Path: ${filePath}`);
53
59
  console.log(` Started: ${startedAt}`);
54
60
  console.log(` Last Active: ${lastActiveAt}`);
55
61
  console.log(` Last Message Tokens: ${session.latestTotalTokens}`);
@@ -62,13 +68,14 @@ export async function main() {
62
68
  process.exit(1);
63
69
  }
64
70
  }
65
- // Handle plain mode directly
66
- if (argv.plain !== undefined) {
67
- const { startPlainCli } = await import("./plain-cli.js");
68
- return startPlainCli({
71
+ // Handle print mode directly
72
+ if (argv.print !== undefined) {
73
+ const { startPrintCli } = await import("./print-cli.js");
74
+ return startPrintCli({
69
75
  restoreSessionId: argv.restore,
70
76
  continueLastSession: argv.continue,
71
- message: argv.plain,
77
+ message: argv.print,
78
+ showStats: argv.showStats,
72
79
  });
73
80
  }
74
81
  await startCli({