wave-code 0.9.0 → 0.9.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.
- package/dist/components/FileSelector.d.ts +1 -0
- package/dist/components/FileSelector.d.ts.map +1 -1
- package/dist/components/FileSelector.js +3 -3
- package/dist/components/HistorySearch.d.ts +2 -1
- package/dist/components/HistorySearch.d.ts.map +1 -1
- package/dist/components/HistorySearch.js +1 -1
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +4 -3
- package/dist/hooks/useInputManager.d.ts +3 -2
- package/dist/hooks/useInputManager.d.ts.map +1 -1
- package/dist/hooks/useInputManager.js +8 -7
- package/dist/managers/inputHandlers.d.ts.map +1 -1
- package/dist/managers/inputHandlers.js +19 -4
- package/dist/managers/inputReducer.d.ts +18 -2
- package/dist/managers/inputReducer.d.ts.map +1 -1
- package/dist/managers/inputReducer.js +92 -3
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +13 -1
- package/package.json +2 -2
- package/src/components/FileSelector.tsx +13 -3
- package/src/components/HistorySearch.tsx +2 -2
- package/src/components/InputBox.tsx +4 -0
- package/src/hooks/useInputManager.ts +13 -10
- package/src/managers/inputHandlers.ts +26 -4
- package/src/managers/inputReducer.ts +104 -6
- package/src/utils/logger.ts +15 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileSelector.d.ts","sourceRoot":"","sources":["../../src/components/FileSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,
|
|
1
|
+
{"version":3,"file":"FileSelector.d.ts","sourceRoot":"","sources":["../../src/components/FileSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA8HpD,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { jsxs as _jsxs,
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { Box, Text, useInput } from "ink";
|
|
4
|
-
export const FileSelector = ({ files, searchQuery, onSelect, onCancel, }) => {
|
|
4
|
+
export const FileSelector = ({ files, searchQuery, isLoading = false, onSelect, onCancel, }) => {
|
|
5
5
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
6
6
|
useInput((input, key) => {
|
|
7
7
|
if (key.return || key.tab) {
|
|
@@ -24,7 +24,7 @@ export const FileSelector = ({ files, searchQuery, onSelect, onCancel, }) => {
|
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
26
|
if (files.length === 0) {
|
|
27
|
-
return (
|
|
27
|
+
return (_jsx(Box, { flexDirection: "column", borderStyle: "single", borderColor: isLoading ? "cyan" : "yellow", borderBottom: false, borderLeft: false, borderRight: false, children: isLoading ? (_jsx(Text, { color: "cyan", bold: true, children: "Select File/Directory..." })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { color: "yellow", children: ["No files found for \"", searchQuery, "\""] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] })) }));
|
|
28
28
|
}
|
|
29
29
|
const maxDisplay = 10;
|
|
30
30
|
// Calculate display window start and end positions
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { type PromptEntry } from "wave-agent-sdk";
|
|
2
3
|
export interface HistorySearchProps {
|
|
3
4
|
searchQuery: string;
|
|
4
|
-
onSelect: (
|
|
5
|
+
onSelect: (entry: PromptEntry) => void;
|
|
5
6
|
onCancel: () => void;
|
|
6
7
|
}
|
|
7
8
|
export declare const HistorySearch: React.FC<HistorySearchProps>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HistorySearch.d.ts","sourceRoot":"","sources":["../../src/components/HistorySearch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"HistorySearch.d.ts","sourceRoot":"","sources":["../../src/components/HistorySearch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAwB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAExE,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACvC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAkKtD,CAAC"}
|
|
@@ -27,7 +27,7 @@ export const HistorySearch = ({ searchQuery, onSelect, onCancel, }) => {
|
|
|
27
27
|
if (key.return) {
|
|
28
28
|
if (entriesRef.current.length > 0 &&
|
|
29
29
|
selectedIndexRef.current < entriesRef.current.length) {
|
|
30
|
-
onSelect(entriesRef.current[selectedIndexRef.current]
|
|
30
|
+
onSelect(entriesRef.current[selectedIndexRef.current]);
|
|
31
31
|
}
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAczC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,mDACe,CAAC;AAEnD,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,
|
|
1
|
+
{"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAczC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,mDACe,CAAC;AAEnD,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,CAsO5C,CAAC"}
|
|
@@ -15,13 +15,13 @@ import { useChat } from "../contexts/useChat.js";
|
|
|
15
15
|
export const INPUT_PLACEHOLDER_TEXT = "Type your message (use /help for more info)...";
|
|
16
16
|
export const INPUT_PLACEHOLDER_TEXT_PREFIX = INPUT_PLACEHOLDER_TEXT.substring(0, 10);
|
|
17
17
|
export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, }) => {
|
|
18
|
-
const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, clearMessages, } = useChat();
|
|
18
|
+
const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, clearMessages, sessionId, } = useChat();
|
|
19
19
|
// Input manager with all input state and functionality (including images)
|
|
20
20
|
const { inputText, cursorPosition,
|
|
21
21
|
// Image management
|
|
22
22
|
attachedImages, clearImages,
|
|
23
23
|
// File selector
|
|
24
|
-
showFileSelector, filteredFiles, fileSearchQuery: searchQuery, handleFileSelect, handleCancelFileSelect,
|
|
24
|
+
showFileSelector, filteredFiles, fileSearchQuery: searchQuery, isFileSearching, handleFileSelect, handleCancelFileSelect,
|
|
25
25
|
// Command selector
|
|
26
26
|
showCommandSelector, commandSearchQuery, handleCommandSelect, handleCommandInsert, handleCancelCommandSelect, handleHistorySearchSelect, handleCancelHistorySearch,
|
|
27
27
|
// History search
|
|
@@ -40,6 +40,7 @@ export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mc
|
|
|
40
40
|
onBackgroundCurrentTask: backgroundCurrentTask,
|
|
41
41
|
onPermissionModeChange: setChatPermissionMode,
|
|
42
42
|
onClearMessages: clearMessages,
|
|
43
|
+
sessionId,
|
|
43
44
|
});
|
|
44
45
|
// Sync permission mode from useChat to InputManager
|
|
45
46
|
useEffect(() => {
|
|
@@ -84,7 +85,7 @@ export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mc
|
|
|
84
85
|
if (showStatusCommand) {
|
|
85
86
|
return _jsx(StatusCommand, { onCancel: () => setShowStatusCommand(false) });
|
|
86
87
|
}
|
|
87
|
-
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 ||
|
|
88
|
+
return (_jsxs(Box, { flexDirection: "column", children: [showFileSelector && (_jsx(FileSelector, { files: filteredFiles, searchQuery: searchQuery, isLoading: isFileSearching, 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 ||
|
|
88
89
|
showMcpManager ||
|
|
89
90
|
showRewindManager ||
|
|
90
91
|
showHelp ||
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Key } from "ink";
|
|
2
2
|
import { InputManagerCallbacks } from "../managers/inputReducer.js";
|
|
3
|
-
import { PermissionMode } from "wave-agent-sdk";
|
|
3
|
+
import { PermissionMode, PromptEntry } from "wave-agent-sdk";
|
|
4
4
|
export declare const useInputManager: (callbacks?: Partial<InputManagerCallbacks>) => {
|
|
5
5
|
inputText: string;
|
|
6
6
|
cursorPosition: number;
|
|
7
7
|
showFileSelector: boolean;
|
|
8
8
|
filteredFiles: import("wave-agent-sdk").FileItem[];
|
|
9
9
|
fileSearchQuery: string;
|
|
10
|
+
isFileSearching: boolean;
|
|
10
11
|
atPosition: number;
|
|
11
12
|
showCommandSelector: boolean;
|
|
12
13
|
commandSearchQuery: string;
|
|
@@ -46,7 +47,7 @@ export declare const useInputManager: (callbacks?: Partial<InputManagerCallbacks
|
|
|
46
47
|
handleCancelCommandSelect: () => void;
|
|
47
48
|
updateCommandSearchQuery: (query: string) => void;
|
|
48
49
|
checkForSlashDeletion: (cursorPos: number) => boolean;
|
|
49
|
-
handleHistorySearchSelect: (
|
|
50
|
+
handleHistorySearchSelect: (entry: PromptEntry) => void;
|
|
50
51
|
handleCancelHistorySearch: () => void;
|
|
51
52
|
processSelectorInput: (char: string) => void;
|
|
52
53
|
setShowBackgroundTaskManager: (show: boolean) => void;
|
|
@@ -1 +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,EAGL,qBAAqB,EACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,
|
|
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,EAGL,qBAAqB,EACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,cAAc,EACd,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAGxB,eAAO,MAAM,eAAe,GAC1B,YAAW,OAAO,CAAC,qBAAqB,CAAM;;;;;;;;;;;;;;;;;;;;;+BAsIA,MAAM;;;;;qCAoBA,MAAM;iCAIV,MAAM;;;;;mCAaJ,MAAM;oCAIL,MAAM;wCAIF,MAAM;mCAIX,MAAM;;;;mCASN,MAAM;;;;;sCAkCH,MAAM;uCAIL,MAAM;uCAQN,WAAW;;iCAQjB,MAAM;yCAYE,OAAO;8BAIlB,OAAO;iCAIJ,OAAO;wBAIhB,OAAO;iCAIE,OAAO;8BAIV,cAAc;0BAKlB,MAAM,YAAY,MAAM;2BAIvB,MAAM;;;8BAYH,MAAM;mCAW/B,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;uCAYnB,MAAM;;yBAajD,MAAM,OACR,GAAG,kBACQ,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,gBACvD,MAAM,IAAI;yBAxFY,MAAM;kCAIG,MAAM;;CAoLxD,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect, useReducer, useCallback, useRef } from "react";
|
|
2
2
|
import { inputReducer, initialState, } from "../managers/inputReducer.js";
|
|
3
|
-
import { searchFiles as searchFilesUtil } from "wave-agent-sdk";
|
|
3
|
+
import { searchFiles as searchFilesUtil, } from "wave-agent-sdk";
|
|
4
4
|
import * as handlers from "../managers/inputHandlers.js";
|
|
5
5
|
export const useInputManager = (callbacks = {}) => {
|
|
6
6
|
const [state, dispatch] = useReducer(inputReducer, initialState);
|
|
@@ -25,7 +25,9 @@ export const useInputManager = (callbacks = {}) => {
|
|
|
25
25
|
// Handle debounced file search
|
|
26
26
|
useEffect(() => {
|
|
27
27
|
if (state.showFileSelector) {
|
|
28
|
-
const debounceDelay =
|
|
28
|
+
const debounceDelay = state.fileSearchQuery === ""
|
|
29
|
+
? 0
|
|
30
|
+
: parseInt(process.env.FILE_SELECTOR_DEBOUNCE_MS || "300", 10);
|
|
29
31
|
const timer = setTimeout(async () => {
|
|
30
32
|
try {
|
|
31
33
|
const fileItems = await searchFilesUtil(state.fileSearchQuery);
|
|
@@ -47,7 +49,7 @@ export const useInputManager = (callbacks = {}) => {
|
|
|
47
49
|
const processedInput = stateRef.current.pasteBuffer.replace(/\r/g, "\n");
|
|
48
50
|
dispatch({ type: "COMPRESS_AND_INSERT_TEXT", payload: processedInput });
|
|
49
51
|
dispatch({ type: "END_PASTE" });
|
|
50
|
-
|
|
52
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
51
53
|
}, pasteDebounceDelay);
|
|
52
54
|
return () => clearTimeout(timer);
|
|
53
55
|
}
|
|
@@ -161,10 +163,8 @@ export const useInputManager = (callbacks = {}) => {
|
|
|
161
163
|
const checkForSlashDeletion = useCallback((cursorPos) => {
|
|
162
164
|
return handlers.checkForSlashDeletion(stateRef.current, dispatch, cursorPos);
|
|
163
165
|
}, []);
|
|
164
|
-
const handleHistorySearchSelect = useCallback((
|
|
165
|
-
dispatch({ type: "
|
|
166
|
-
dispatch({ type: "SET_CURSOR_POSITION", payload: prompt.length });
|
|
167
|
-
dispatch({ type: "CANCEL_HISTORY_SEARCH" });
|
|
166
|
+
const handleHistorySearchSelect = useCallback((entry) => {
|
|
167
|
+
dispatch({ type: "SELECT_HISTORY_ENTRY", payload: entry });
|
|
168
168
|
}, []);
|
|
169
169
|
const handleCancelHistorySearch = useCallback(() => {
|
|
170
170
|
dispatch({ type: "CANCEL_HISTORY_SEARCH" });
|
|
@@ -231,6 +231,7 @@ export const useInputManager = (callbacks = {}) => {
|
|
|
231
231
|
showFileSelector: state.showFileSelector,
|
|
232
232
|
filteredFiles: state.filteredFiles,
|
|
233
233
|
fileSearchQuery: state.fileSearchQuery,
|
|
234
|
+
isFileSearching: state.isFileSearching,
|
|
234
235
|
atPosition: state.atPosition,
|
|
235
236
|
showCommandSelector: state.showCommandSelector,
|
|
236
237
|
commandSearchQuery: state.commandSearchQuery,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inputHandlers.d.ts","sourceRoot":"","sources":["../../src/managers/inputHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAwB,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EACL,UAAU,EACV,WAAW,EACX,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,eAAO,MAAM,0BAA0B,GACrC,MAAM,MAAM,EACZ,aAAa,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAClC,MAcF,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,yBAAyB,KAAK,CAAC;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,KACD,OAAO,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"inputHandlers.d.ts","sourceRoot":"","sources":["../../src/managers/inputHandlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,12 +27,12 @@ export const handleSubmit = async (state, dispatch, callbacks, attachedImagesOve
|
|
|
27
27
|
.map((img) => ({ path: img.path, mimeType: img.mimeType }));
|
|
28
28
|
let cleanContent = state.inputText.replace(imageRegex, "").trim();
|
|
29
29
|
cleanContent = expandLongTextPlaceholders(cleanContent, state.longTextMap);
|
|
30
|
-
PromptHistoryManager.addEntry(cleanContent).catch((err) => {
|
|
30
|
+
PromptHistoryManager.addEntry(cleanContent, callbacks.sessionId, state.longTextMap).catch((err) => {
|
|
31
31
|
callbacks.logger?.error("Failed to save prompt history", err);
|
|
32
32
|
});
|
|
33
33
|
callbacks.onSendMessage?.(cleanContent, referencedImages.length > 0 ? referencedImages : undefined);
|
|
34
34
|
dispatch({ type: "CLEAR_INPUT" });
|
|
35
|
-
|
|
35
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
36
36
|
dispatch({ type: "CLEAR_LONG_TEXT_MAP" });
|
|
37
37
|
}
|
|
38
38
|
};
|
|
@@ -190,7 +190,7 @@ export const handlePasteInput = (state, dispatch, callbacks, input) => {
|
|
|
190
190
|
if (char === "!" && state.cursorPosition === 0) {
|
|
191
191
|
char = "!";
|
|
192
192
|
}
|
|
193
|
-
|
|
193
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
194
194
|
dispatch({ type: "INSERT_TEXT", payload: char });
|
|
195
195
|
processSelectorInput(state, dispatch, char);
|
|
196
196
|
}
|
|
@@ -348,6 +348,21 @@ export const handleNormalInput = async (state, dispatch, callbacks, input, key,
|
|
|
348
348
|
else if (state.showCommandSelector) {
|
|
349
349
|
dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
|
|
350
350
|
}
|
|
351
|
+
else if (state.historyIndex !== -1) {
|
|
352
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
353
|
+
}
|
|
354
|
+
return true;
|
|
355
|
+
}
|
|
356
|
+
if (key.upArrow) {
|
|
357
|
+
if (state.history.length === 0) {
|
|
358
|
+
const history = await PromptHistoryManager.getHistory(callbacks.sessionId);
|
|
359
|
+
dispatch({ type: "SET_HISTORY_ENTRIES", payload: history });
|
|
360
|
+
}
|
|
361
|
+
dispatch({ type: "NAVIGATE_HISTORY", payload: "up" });
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
364
|
+
if (key.downArrow) {
|
|
365
|
+
dispatch({ type: "NAVIGATE_HISTORY", payload: "down" });
|
|
351
366
|
return true;
|
|
352
367
|
}
|
|
353
368
|
if (key.backspace || key.delete) {
|
|
@@ -357,7 +372,7 @@ export const handleNormalInput = async (state, dispatch, callbacks, input, key,
|
|
|
357
372
|
const afterCursor = state.inputText.substring(state.cursorPosition);
|
|
358
373
|
const newInputText = beforeCursor + afterCursor;
|
|
359
374
|
dispatch({ type: "DELETE_CHAR" });
|
|
360
|
-
|
|
375
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
361
376
|
checkForAtDeletion(state, dispatch, newCursorPosition);
|
|
362
377
|
checkForSlashDeletion(state, dispatch, newCursorPosition);
|
|
363
378
|
// Reactivate file selector if cursor is now within an @word
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FileItem, PermissionMode, Logger } from "wave-agent-sdk";
|
|
1
|
+
import { FileItem, PermissionMode, Logger, PromptEntry } from "wave-agent-sdk";
|
|
2
2
|
export interface AttachedImage {
|
|
3
3
|
id: number;
|
|
4
4
|
path: string;
|
|
@@ -24,8 +24,8 @@ export interface InputManagerCallbacks {
|
|
|
24
24
|
onAbortMessage?: () => void;
|
|
25
25
|
onClearMessages?: () => void;
|
|
26
26
|
onBackgroundCurrentTask?: () => void;
|
|
27
|
-
onResetHistoryNavigation?: () => void;
|
|
28
27
|
onPermissionModeChange?: (mode: PermissionMode) => void;
|
|
28
|
+
sessionId?: string;
|
|
29
29
|
logger?: Logger;
|
|
30
30
|
}
|
|
31
31
|
export interface InputState {
|
|
@@ -54,6 +54,11 @@ export interface InputState {
|
|
|
54
54
|
isPasting: boolean;
|
|
55
55
|
pasteBuffer: string;
|
|
56
56
|
initialPasteCursorPosition: number;
|
|
57
|
+
history: PromptEntry[];
|
|
58
|
+
historyIndex: number;
|
|
59
|
+
originalInputText: string;
|
|
60
|
+
originalLongTextMap: Record<string, string>;
|
|
61
|
+
isFileSearching: boolean;
|
|
57
62
|
}
|
|
58
63
|
export declare const initialState: InputState;
|
|
59
64
|
export type InputAction = {
|
|
@@ -152,6 +157,17 @@ export type InputAction = {
|
|
|
152
157
|
path: string;
|
|
153
158
|
mimeType: string;
|
|
154
159
|
};
|
|
160
|
+
} | {
|
|
161
|
+
type: "SET_HISTORY_ENTRIES";
|
|
162
|
+
payload: PromptEntry[];
|
|
163
|
+
} | {
|
|
164
|
+
type: "NAVIGATE_HISTORY";
|
|
165
|
+
payload: "up" | "down";
|
|
166
|
+
} | {
|
|
167
|
+
type: "RESET_HISTORY_NAVIGATION";
|
|
168
|
+
} | {
|
|
169
|
+
type: "SELECT_HISTORY_ENTRY";
|
|
170
|
+
payload: PromptEntry;
|
|
155
171
|
};
|
|
156
172
|
export declare function inputReducer(state: InputState, action: InputAction): InputState;
|
|
157
173
|
//# sourceMappingURL=inputReducer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inputReducer.d.ts","sourceRoot":"","sources":["../../src/managers/inputReducer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"inputReducer.d.ts","sourceRoot":"","sources":["../../src/managers/inputReducer.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,11 +24,20 @@ export const initialState = {
|
|
|
24
24
|
isPasting: false,
|
|
25
25
|
pasteBuffer: "",
|
|
26
26
|
initialPasteCursorPosition: 0,
|
|
27
|
+
history: [],
|
|
28
|
+
historyIndex: -1,
|
|
29
|
+
originalInputText: "",
|
|
30
|
+
originalLongTextMap: {},
|
|
31
|
+
isFileSearching: false,
|
|
27
32
|
};
|
|
28
33
|
export function inputReducer(state, action) {
|
|
29
34
|
switch (action.type) {
|
|
30
35
|
case "SET_INPUT_TEXT":
|
|
31
|
-
return {
|
|
36
|
+
return {
|
|
37
|
+
...state,
|
|
38
|
+
inputText: action.payload,
|
|
39
|
+
historyIndex: -1,
|
|
40
|
+
};
|
|
32
41
|
case "SET_CURSOR_POSITION":
|
|
33
42
|
return {
|
|
34
43
|
...state,
|
|
@@ -43,6 +52,7 @@ export function inputReducer(state, action) {
|
|
|
43
52
|
...state,
|
|
44
53
|
inputText: newText,
|
|
45
54
|
cursorPosition: newCursorPosition,
|
|
55
|
+
historyIndex: -1,
|
|
46
56
|
};
|
|
47
57
|
}
|
|
48
58
|
case "DELETE_CHAR": {
|
|
@@ -55,6 +65,7 @@ export function inputReducer(state, action) {
|
|
|
55
65
|
...state,
|
|
56
66
|
inputText: newText,
|
|
57
67
|
cursorPosition: newCursorPosition,
|
|
68
|
+
historyIndex: -1,
|
|
58
69
|
};
|
|
59
70
|
}
|
|
60
71
|
return state;
|
|
@@ -70,11 +81,20 @@ export function inputReducer(state, action) {
|
|
|
70
81
|
atPosition: action.payload,
|
|
71
82
|
fileSearchQuery: "",
|
|
72
83
|
filteredFiles: [],
|
|
84
|
+
isFileSearching: true,
|
|
73
85
|
};
|
|
74
86
|
case "SET_FILE_SEARCH_QUERY":
|
|
75
|
-
return {
|
|
87
|
+
return {
|
|
88
|
+
...state,
|
|
89
|
+
fileSearchQuery: action.payload,
|
|
90
|
+
isFileSearching: true,
|
|
91
|
+
};
|
|
76
92
|
case "SET_FILTERED_FILES":
|
|
77
|
-
return {
|
|
93
|
+
return {
|
|
94
|
+
...state,
|
|
95
|
+
filteredFiles: action.payload,
|
|
96
|
+
isFileSearching: false,
|
|
97
|
+
};
|
|
78
98
|
case "CANCEL_FILE_SELECTOR":
|
|
79
99
|
return {
|
|
80
100
|
...state,
|
|
@@ -83,6 +103,7 @@ export function inputReducer(state, action) {
|
|
|
83
103
|
fileSearchQuery: "",
|
|
84
104
|
filteredFiles: [],
|
|
85
105
|
selectorJustUsed: true,
|
|
106
|
+
isFileSearching: false,
|
|
86
107
|
};
|
|
87
108
|
case "ACTIVATE_COMMAND_SELECTOR":
|
|
88
109
|
return {
|
|
@@ -189,6 +210,7 @@ export function inputReducer(state, action) {
|
|
|
189
210
|
cursorPosition: newCursorPosition,
|
|
190
211
|
longTextCounter: newLongTextCounter,
|
|
191
212
|
longTextMap: newLongTextMap,
|
|
213
|
+
historyIndex: -1,
|
|
192
214
|
};
|
|
193
215
|
}
|
|
194
216
|
case "CLEAR_LONG_TEXT_MAP":
|
|
@@ -198,6 +220,7 @@ export function inputReducer(state, action) {
|
|
|
198
220
|
...state,
|
|
199
221
|
inputText: "",
|
|
200
222
|
cursorPosition: 0,
|
|
223
|
+
historyIndex: -1,
|
|
201
224
|
};
|
|
202
225
|
case "START_PASTE":
|
|
203
226
|
return {
|
|
@@ -234,8 +257,74 @@ export function inputReducer(state, action) {
|
|
|
234
257
|
imageIdCounter: state.imageIdCounter + 1,
|
|
235
258
|
inputText: newText,
|
|
236
259
|
cursorPosition: newCursorPosition,
|
|
260
|
+
historyIndex: -1,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
case "SET_HISTORY_ENTRIES":
|
|
264
|
+
return { ...state, history: action.payload };
|
|
265
|
+
case "NAVIGATE_HISTORY": {
|
|
266
|
+
const direction = action.payload;
|
|
267
|
+
let newIndex = state.historyIndex;
|
|
268
|
+
let newOriginalInputText = state.originalInputText;
|
|
269
|
+
let newOriginalLongTextMap = state.originalLongTextMap;
|
|
270
|
+
if (direction === "up") {
|
|
271
|
+
if (newIndex === -1) {
|
|
272
|
+
newOriginalInputText = state.inputText;
|
|
273
|
+
newOriginalLongTextMap = state.longTextMap;
|
|
274
|
+
}
|
|
275
|
+
newIndex = Math.min(state.history.length - 1, newIndex + 1);
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
newIndex = Math.max(-1, newIndex - 1);
|
|
279
|
+
}
|
|
280
|
+
if (newIndex === -1) {
|
|
281
|
+
return {
|
|
282
|
+
...state,
|
|
283
|
+
historyIndex: newIndex,
|
|
284
|
+
inputText: newOriginalInputText,
|
|
285
|
+
longTextMap: newOriginalLongTextMap,
|
|
286
|
+
cursorPosition: newOriginalInputText.length,
|
|
287
|
+
originalInputText: newOriginalInputText,
|
|
288
|
+
originalLongTextMap: newOriginalLongTextMap,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
const entry = state.history[newIndex];
|
|
293
|
+
return {
|
|
294
|
+
...state,
|
|
295
|
+
historyIndex: newIndex,
|
|
296
|
+
inputText: entry.prompt,
|
|
297
|
+
longTextMap: entry.longTextMap || {},
|
|
298
|
+
cursorPosition: entry.prompt.length,
|
|
299
|
+
originalInputText: newOriginalInputText,
|
|
300
|
+
originalLongTextMap: newOriginalLongTextMap,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
case "SELECT_HISTORY_ENTRY": {
|
|
305
|
+
const entry = action.payload;
|
|
306
|
+
return {
|
|
307
|
+
...state,
|
|
308
|
+
inputText: entry.prompt,
|
|
309
|
+
longTextMap: entry.longTextMap || {},
|
|
310
|
+
cursorPosition: entry.prompt.length,
|
|
311
|
+
historyIndex: -1,
|
|
312
|
+
history: [],
|
|
313
|
+
originalInputText: "",
|
|
314
|
+
originalLongTextMap: {},
|
|
315
|
+
showHistorySearch: false,
|
|
316
|
+
historySearchQuery: "",
|
|
317
|
+
selectorJustUsed: true,
|
|
237
318
|
};
|
|
238
319
|
}
|
|
320
|
+
case "RESET_HISTORY_NAVIGATION":
|
|
321
|
+
return {
|
|
322
|
+
...state,
|
|
323
|
+
historyIndex: -1,
|
|
324
|
+
history: [],
|
|
325
|
+
originalInputText: "",
|
|
326
|
+
originalLongTextMap: {},
|
|
327
|
+
};
|
|
239
328
|
default:
|
|
240
329
|
return state;
|
|
241
330
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH;;GAEG;AACH,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAsBD;;GAEG;AACH,UAAU,SAAS;IACjB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;CAC7B;AA+HD;;GAEG;AACH,eAAO,MAAM,MAAM;IACjB;;OAEG;qBACc,OAAO,EAAE,KAAG,IAAI;IAIjC;;OAEG;oBACa,OAAO,EAAE,KAAG,IAAI;IAIhC;;OAEG;oBACa,OAAO,EAAE,KAAG,IAAI;IAIhC;;OAEG;qBACc,OAAO,EAAE,KAAG,IAAI;CAGlC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,QAAO,SAE/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,QAAO,MAE7B,CAAC;AAEF;;GAEG;AACH,UAAU,gBAAgB;IACxB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;CACnB;AAqDD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GACtB,eAAe,OAAO,CAAC,gBAAgB,CAAC,KACvC,OAAO,CAAC,IAAI,CAiBd,CAAC"}
|
package/dist/utils/logger.js
CHANGED
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
* - This can significantly improve test execution performance by avoiding unnecessary disk writes
|
|
9
9
|
*/
|
|
10
10
|
import * as fs from "fs";
|
|
11
|
+
import { Chalk } from "chalk";
|
|
11
12
|
import { LOG_FILE, DATA_DIRECTORY } from "./constants.js";
|
|
13
|
+
const chalk = new Chalk({ level: 3 });
|
|
12
14
|
const logFile = process.env.LOG_FILE || LOG_FILE;
|
|
13
15
|
/**
|
|
14
16
|
* Log level enumeration
|
|
@@ -29,6 +31,15 @@ const LOG_LEVEL_NAMES = {
|
|
|
29
31
|
[LogLevel.WARN]: "WARN",
|
|
30
32
|
[LogLevel.ERROR]: "ERROR",
|
|
31
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* Log level color mapping
|
|
36
|
+
*/
|
|
37
|
+
const LEVEL_COLORS = {
|
|
38
|
+
[LogLevel.DEBUG]: chalk.gray,
|
|
39
|
+
[LogLevel.INFO]: chalk.blue,
|
|
40
|
+
[LogLevel.WARN]: chalk.yellow,
|
|
41
|
+
[LogLevel.ERROR]: chalk.red,
|
|
42
|
+
};
|
|
32
43
|
/**
|
|
33
44
|
* Parse log level from environment variable
|
|
34
45
|
*/
|
|
@@ -125,7 +136,8 @@ const logMessage = (level, ...args) => {
|
|
|
125
136
|
}
|
|
126
137
|
const levelName = LOG_LEVEL_NAMES[level];
|
|
127
138
|
const timestamp = new Date().toISOString();
|
|
128
|
-
const
|
|
139
|
+
const color = LEVEL_COLORS[level] || ((s) => s);
|
|
140
|
+
const formattedMessage = `[${chalk.gray(timestamp)}] [${color(levelName)}] ${messageText}\n`;
|
|
129
141
|
try {
|
|
130
142
|
// Ensure directory exists
|
|
131
143
|
if (!fs.existsSync(DATA_DIRECTORY)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wave-code",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "CLI-based code assistant powered by AI, built with React and Ink",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"react": "^19.2.4",
|
|
40
40
|
"react-dom": "19.2.4",
|
|
41
41
|
"yargs": "^17.7.2",
|
|
42
|
-
"wave-agent-sdk": "0.9.
|
|
42
|
+
"wave-agent-sdk": "0.9.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/react": "^19.1.8",
|
|
@@ -7,6 +7,7 @@ export { type FileItem } from "wave-agent-sdk";
|
|
|
7
7
|
export interface FileSelectorProps {
|
|
8
8
|
files: FileItem[];
|
|
9
9
|
searchQuery: string;
|
|
10
|
+
isLoading?: boolean;
|
|
10
11
|
onSelect: (filePath: string) => void;
|
|
11
12
|
onCancel: () => void;
|
|
12
13
|
}
|
|
@@ -14,6 +15,7 @@ export interface FileSelectorProps {
|
|
|
14
15
|
export const FileSelector: React.FC<FileSelectorProps> = ({
|
|
15
16
|
files,
|
|
16
17
|
searchQuery,
|
|
18
|
+
isLoading = false,
|
|
17
19
|
onSelect,
|
|
18
20
|
onCancel,
|
|
19
21
|
}) => {
|
|
@@ -48,13 +50,21 @@ export const FileSelector: React.FC<FileSelectorProps> = ({
|
|
|
48
50
|
<Box
|
|
49
51
|
flexDirection="column"
|
|
50
52
|
borderStyle="single"
|
|
51
|
-
borderColor="yellow"
|
|
53
|
+
borderColor={isLoading ? "cyan" : "yellow"}
|
|
52
54
|
borderBottom={false}
|
|
53
55
|
borderLeft={false}
|
|
54
56
|
borderRight={false}
|
|
55
57
|
>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
{isLoading ? (
|
|
59
|
+
<Text color="cyan" bold>
|
|
60
|
+
Select File/Directory...
|
|
61
|
+
</Text>
|
|
62
|
+
) : (
|
|
63
|
+
<>
|
|
64
|
+
<Text color="yellow">No files found for "{searchQuery}"</Text>
|
|
65
|
+
<Text dimColor>Press Escape to cancel</Text>
|
|
66
|
+
</>
|
|
67
|
+
)}
|
|
58
68
|
</Box>
|
|
59
69
|
);
|
|
60
70
|
}
|
|
@@ -4,7 +4,7 @@ import { PromptHistoryManager, type PromptEntry } from "wave-agent-sdk";
|
|
|
4
4
|
|
|
5
5
|
export interface HistorySearchProps {
|
|
6
6
|
searchQuery: string;
|
|
7
|
-
onSelect: (
|
|
7
|
+
onSelect: (entry: PromptEntry) => void;
|
|
8
8
|
onCancel: () => void;
|
|
9
9
|
}
|
|
10
10
|
|
|
@@ -44,7 +44,7 @@ export const HistorySearch: React.FC<HistorySearchProps> = ({
|
|
|
44
44
|
entriesRef.current.length > 0 &&
|
|
45
45
|
selectedIndexRef.current < entriesRef.current.length
|
|
46
46
|
) {
|
|
47
|
-
onSelect(entriesRef.current[selectedIndexRef.current]
|
|
47
|
+
onSelect(entriesRef.current[selectedIndexRef.current]);
|
|
48
48
|
}
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
@@ -57,6 +57,7 @@ export const InputBox: React.FC<InputBoxProps> = ({
|
|
|
57
57
|
messages,
|
|
58
58
|
getFullMessageThread,
|
|
59
59
|
clearMessages,
|
|
60
|
+
sessionId,
|
|
60
61
|
} = useChat();
|
|
61
62
|
|
|
62
63
|
// Input manager with all input state and functionality (including images)
|
|
@@ -70,6 +71,7 @@ export const InputBox: React.FC<InputBoxProps> = ({
|
|
|
70
71
|
showFileSelector,
|
|
71
72
|
filteredFiles,
|
|
72
73
|
fileSearchQuery: searchQuery,
|
|
74
|
+
isFileSearching,
|
|
73
75
|
handleFileSelect,
|
|
74
76
|
handleCancelFileSelect,
|
|
75
77
|
// Command selector
|
|
@@ -108,6 +110,7 @@ export const InputBox: React.FC<InputBoxProps> = ({
|
|
|
108
110
|
onBackgroundCurrentTask: backgroundCurrentTask,
|
|
109
111
|
onPermissionModeChange: setChatPermissionMode,
|
|
110
112
|
onClearMessages: clearMessages,
|
|
113
|
+
sessionId,
|
|
111
114
|
});
|
|
112
115
|
|
|
113
116
|
// Sync permission mode from useChat to InputManager
|
|
@@ -183,6 +186,7 @@ export const InputBox: React.FC<InputBoxProps> = ({
|
|
|
183
186
|
<FileSelector
|
|
184
187
|
files={filteredFiles}
|
|
185
188
|
searchQuery={searchQuery}
|
|
189
|
+
isLoading={isFileSearching}
|
|
186
190
|
onSelect={handleFileSelect}
|
|
187
191
|
onCancel={handleCancelFileSelect}
|
|
188
192
|
/>
|
|
@@ -5,7 +5,11 @@ import {
|
|
|
5
5
|
initialState,
|
|
6
6
|
InputManagerCallbacks,
|
|
7
7
|
} from "../managers/inputReducer.js";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
searchFiles as searchFilesUtil,
|
|
10
|
+
PermissionMode,
|
|
11
|
+
PromptEntry,
|
|
12
|
+
} from "wave-agent-sdk";
|
|
9
13
|
import * as handlers from "../managers/inputHandlers.js";
|
|
10
14
|
|
|
11
15
|
export const useInputManager = (
|
|
@@ -37,10 +41,10 @@ export const useInputManager = (
|
|
|
37
41
|
// Handle debounced file search
|
|
38
42
|
useEffect(() => {
|
|
39
43
|
if (state.showFileSelector) {
|
|
40
|
-
const debounceDelay =
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
const debounceDelay =
|
|
45
|
+
state.fileSearchQuery === ""
|
|
46
|
+
? 0
|
|
47
|
+
: parseInt(process.env.FILE_SELECTOR_DEBOUNCE_MS || "300", 10);
|
|
44
48
|
const timer = setTimeout(async () => {
|
|
45
49
|
try {
|
|
46
50
|
const fileItems = await searchFilesUtil(state.fileSearchQuery);
|
|
@@ -68,7 +72,7 @@ export const useInputManager = (
|
|
|
68
72
|
);
|
|
69
73
|
dispatch({ type: "COMPRESS_AND_INSERT_TEXT", payload: processedInput });
|
|
70
74
|
dispatch({ type: "END_PASTE" });
|
|
71
|
-
|
|
75
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
72
76
|
}, pasteDebounceDelay);
|
|
73
77
|
return () => clearTimeout(timer);
|
|
74
78
|
}
|
|
@@ -247,10 +251,8 @@ export const useInputManager = (
|
|
|
247
251
|
);
|
|
248
252
|
}, []);
|
|
249
253
|
|
|
250
|
-
const handleHistorySearchSelect = useCallback((
|
|
251
|
-
dispatch({ type: "
|
|
252
|
-
dispatch({ type: "SET_CURSOR_POSITION", payload: prompt.length });
|
|
253
|
-
dispatch({ type: "CANCEL_HISTORY_SEARCH" });
|
|
254
|
+
const handleHistorySearchSelect = useCallback((entry: PromptEntry) => {
|
|
255
|
+
dispatch({ type: "SELECT_HISTORY_ENTRY", payload: entry });
|
|
254
256
|
}, []);
|
|
255
257
|
|
|
256
258
|
const handleCancelHistorySearch = useCallback(() => {
|
|
@@ -370,6 +372,7 @@ export const useInputManager = (
|
|
|
370
372
|
showFileSelector: state.showFileSelector,
|
|
371
373
|
filteredFiles: state.filteredFiles,
|
|
372
374
|
fileSearchQuery: state.fileSearchQuery,
|
|
375
|
+
isFileSearching: state.isFileSearching,
|
|
373
376
|
atPosition: state.atPosition,
|
|
374
377
|
showCommandSelector: state.showCommandSelector,
|
|
375
378
|
commandSearchQuery: state.commandSearchQuery,
|
|
@@ -54,7 +54,11 @@ export const handleSubmit = async (
|
|
|
54
54
|
let cleanContent = state.inputText.replace(imageRegex, "").trim();
|
|
55
55
|
cleanContent = expandLongTextPlaceholders(cleanContent, state.longTextMap);
|
|
56
56
|
|
|
57
|
-
PromptHistoryManager.addEntry(
|
|
57
|
+
PromptHistoryManager.addEntry(
|
|
58
|
+
cleanContent,
|
|
59
|
+
callbacks.sessionId,
|
|
60
|
+
state.longTextMap,
|
|
61
|
+
).catch((err: unknown) => {
|
|
58
62
|
callbacks.logger?.error("Failed to save prompt history", err);
|
|
59
63
|
});
|
|
60
64
|
|
|
@@ -63,7 +67,7 @@ export const handleSubmit = async (
|
|
|
63
67
|
referencedImages.length > 0 ? referencedImages : undefined,
|
|
64
68
|
);
|
|
65
69
|
dispatch({ type: "CLEAR_INPUT" });
|
|
66
|
-
|
|
70
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
67
71
|
dispatch({ type: "CLEAR_LONG_TEXT_MAP" });
|
|
68
72
|
}
|
|
69
73
|
};
|
|
@@ -276,7 +280,7 @@ export const handlePasteInput = (
|
|
|
276
280
|
char = "!";
|
|
277
281
|
}
|
|
278
282
|
|
|
279
|
-
|
|
283
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
280
284
|
dispatch({ type: "INSERT_TEXT", payload: char });
|
|
281
285
|
|
|
282
286
|
processSelectorInput(state, dispatch, char);
|
|
@@ -494,10 +498,28 @@ export const handleNormalInput = async (
|
|
|
494
498
|
dispatch({ type: "CANCEL_FILE_SELECTOR" });
|
|
495
499
|
} else if (state.showCommandSelector) {
|
|
496
500
|
dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
|
|
501
|
+
} else if (state.historyIndex !== -1) {
|
|
502
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
497
503
|
}
|
|
498
504
|
return true;
|
|
499
505
|
}
|
|
500
506
|
|
|
507
|
+
if (key.upArrow) {
|
|
508
|
+
if (state.history.length === 0) {
|
|
509
|
+
const history = await PromptHistoryManager.getHistory(
|
|
510
|
+
callbacks.sessionId,
|
|
511
|
+
);
|
|
512
|
+
dispatch({ type: "SET_HISTORY_ENTRIES", payload: history });
|
|
513
|
+
}
|
|
514
|
+
dispatch({ type: "NAVIGATE_HISTORY", payload: "up" });
|
|
515
|
+
return true;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
if (key.downArrow) {
|
|
519
|
+
dispatch({ type: "NAVIGATE_HISTORY", payload: "down" });
|
|
520
|
+
return true;
|
|
521
|
+
}
|
|
522
|
+
|
|
501
523
|
if (key.backspace || key.delete) {
|
|
502
524
|
if (state.cursorPosition > 0) {
|
|
503
525
|
const newCursorPosition = state.cursorPosition - 1;
|
|
@@ -509,7 +531,7 @@ export const handleNormalInput = async (
|
|
|
509
531
|
const newInputText = beforeCursor + afterCursor;
|
|
510
532
|
|
|
511
533
|
dispatch({ type: "DELETE_CHAR" });
|
|
512
|
-
|
|
534
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
513
535
|
|
|
514
536
|
checkForAtDeletion(state, dispatch, newCursorPosition);
|
|
515
537
|
checkForSlashDeletion(state, dispatch, newCursorPosition);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FileItem, PermissionMode, Logger } from "wave-agent-sdk";
|
|
1
|
+
import { FileItem, PermissionMode, Logger, PromptEntry } from "wave-agent-sdk";
|
|
2
2
|
|
|
3
3
|
export interface AttachedImage {
|
|
4
4
|
id: number;
|
|
@@ -35,8 +35,8 @@ export interface InputManagerCallbacks {
|
|
|
35
35
|
onAbortMessage?: () => void;
|
|
36
36
|
onClearMessages?: () => void;
|
|
37
37
|
onBackgroundCurrentTask?: () => void;
|
|
38
|
-
onResetHistoryNavigation?: () => void;
|
|
39
38
|
onPermissionModeChange?: (mode: PermissionMode) => void;
|
|
39
|
+
sessionId?: string;
|
|
40
40
|
logger?: Logger;
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -66,6 +66,11 @@ export interface InputState {
|
|
|
66
66
|
isPasting: boolean;
|
|
67
67
|
pasteBuffer: string;
|
|
68
68
|
initialPasteCursorPosition: number;
|
|
69
|
+
history: PromptEntry[];
|
|
70
|
+
historyIndex: number;
|
|
71
|
+
originalInputText: string;
|
|
72
|
+
originalLongTextMap: Record<string, string>;
|
|
73
|
+
isFileSearching: boolean;
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
export const initialState: InputState = {
|
|
@@ -94,6 +99,11 @@ export const initialState: InputState = {
|
|
|
94
99
|
isPasting: false,
|
|
95
100
|
pasteBuffer: "",
|
|
96
101
|
initialPasteCursorPosition: 0,
|
|
102
|
+
history: [],
|
|
103
|
+
historyIndex: -1,
|
|
104
|
+
originalInputText: "",
|
|
105
|
+
originalLongTextMap: {},
|
|
106
|
+
isFileSearching: false,
|
|
97
107
|
};
|
|
98
108
|
|
|
99
109
|
export type InputAction =
|
|
@@ -131,7 +141,11 @@ export type InputAction =
|
|
|
131
141
|
| {
|
|
132
142
|
type: "ADD_IMAGE_AND_INSERT_PLACEHOLDER";
|
|
133
143
|
payload: { path: string; mimeType: string };
|
|
134
|
-
}
|
|
144
|
+
}
|
|
145
|
+
| { type: "SET_HISTORY_ENTRIES"; payload: PromptEntry[] }
|
|
146
|
+
| { type: "NAVIGATE_HISTORY"; payload: "up" | "down" }
|
|
147
|
+
| { type: "RESET_HISTORY_NAVIGATION" }
|
|
148
|
+
| { type: "SELECT_HISTORY_ENTRY"; payload: PromptEntry };
|
|
135
149
|
|
|
136
150
|
export function inputReducer(
|
|
137
151
|
state: InputState,
|
|
@@ -139,7 +153,11 @@ export function inputReducer(
|
|
|
139
153
|
): InputState {
|
|
140
154
|
switch (action.type) {
|
|
141
155
|
case "SET_INPUT_TEXT":
|
|
142
|
-
return {
|
|
156
|
+
return {
|
|
157
|
+
...state,
|
|
158
|
+
inputText: action.payload,
|
|
159
|
+
historyIndex: -1,
|
|
160
|
+
};
|
|
143
161
|
case "SET_CURSOR_POSITION":
|
|
144
162
|
return {
|
|
145
163
|
...state,
|
|
@@ -157,6 +175,7 @@ export function inputReducer(
|
|
|
157
175
|
...state,
|
|
158
176
|
inputText: newText,
|
|
159
177
|
cursorPosition: newCursorPosition,
|
|
178
|
+
historyIndex: -1,
|
|
160
179
|
};
|
|
161
180
|
}
|
|
162
181
|
case "DELETE_CHAR": {
|
|
@@ -172,6 +191,7 @@ export function inputReducer(
|
|
|
172
191
|
...state,
|
|
173
192
|
inputText: newText,
|
|
174
193
|
cursorPosition: newCursorPosition,
|
|
194
|
+
historyIndex: -1,
|
|
175
195
|
};
|
|
176
196
|
}
|
|
177
197
|
return state;
|
|
@@ -190,11 +210,20 @@ export function inputReducer(
|
|
|
190
210
|
atPosition: action.payload,
|
|
191
211
|
fileSearchQuery: "",
|
|
192
212
|
filteredFiles: [],
|
|
213
|
+
isFileSearching: true,
|
|
193
214
|
};
|
|
194
215
|
case "SET_FILE_SEARCH_QUERY":
|
|
195
|
-
return {
|
|
216
|
+
return {
|
|
217
|
+
...state,
|
|
218
|
+
fileSearchQuery: action.payload,
|
|
219
|
+
isFileSearching: true,
|
|
220
|
+
};
|
|
196
221
|
case "SET_FILTERED_FILES":
|
|
197
|
-
return {
|
|
222
|
+
return {
|
|
223
|
+
...state,
|
|
224
|
+
filteredFiles: action.payload,
|
|
225
|
+
isFileSearching: false,
|
|
226
|
+
};
|
|
198
227
|
case "CANCEL_FILE_SELECTOR":
|
|
199
228
|
return {
|
|
200
229
|
...state,
|
|
@@ -203,6 +232,7 @@ export function inputReducer(
|
|
|
203
232
|
fileSearchQuery: "",
|
|
204
233
|
filteredFiles: [],
|
|
205
234
|
selectorJustUsed: true,
|
|
235
|
+
isFileSearching: false,
|
|
206
236
|
};
|
|
207
237
|
case "ACTIVATE_COMMAND_SELECTOR":
|
|
208
238
|
return {
|
|
@@ -314,6 +344,7 @@ export function inputReducer(
|
|
|
314
344
|
cursorPosition: newCursorPosition,
|
|
315
345
|
longTextCounter: newLongTextCounter,
|
|
316
346
|
longTextMap: newLongTextMap,
|
|
347
|
+
historyIndex: -1,
|
|
317
348
|
};
|
|
318
349
|
}
|
|
319
350
|
case "CLEAR_LONG_TEXT_MAP":
|
|
@@ -323,6 +354,7 @@ export function inputReducer(
|
|
|
323
354
|
...state,
|
|
324
355
|
inputText: "",
|
|
325
356
|
cursorPosition: 0,
|
|
357
|
+
historyIndex: -1,
|
|
326
358
|
};
|
|
327
359
|
case "START_PASTE":
|
|
328
360
|
return {
|
|
@@ -359,8 +391,74 @@ export function inputReducer(
|
|
|
359
391
|
imageIdCounter: state.imageIdCounter + 1,
|
|
360
392
|
inputText: newText,
|
|
361
393
|
cursorPosition: newCursorPosition,
|
|
394
|
+
historyIndex: -1,
|
|
362
395
|
};
|
|
363
396
|
}
|
|
397
|
+
case "SET_HISTORY_ENTRIES":
|
|
398
|
+
return { ...state, history: action.payload };
|
|
399
|
+
case "NAVIGATE_HISTORY": {
|
|
400
|
+
const direction = action.payload;
|
|
401
|
+
let newIndex = state.historyIndex;
|
|
402
|
+
let newOriginalInputText = state.originalInputText;
|
|
403
|
+
let newOriginalLongTextMap = state.originalLongTextMap;
|
|
404
|
+
|
|
405
|
+
if (direction === "up") {
|
|
406
|
+
if (newIndex === -1) {
|
|
407
|
+
newOriginalInputText = state.inputText;
|
|
408
|
+
newOriginalLongTextMap = state.longTextMap;
|
|
409
|
+
}
|
|
410
|
+
newIndex = Math.min(state.history.length - 1, newIndex + 1);
|
|
411
|
+
} else {
|
|
412
|
+
newIndex = Math.max(-1, newIndex - 1);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (newIndex === -1) {
|
|
416
|
+
return {
|
|
417
|
+
...state,
|
|
418
|
+
historyIndex: newIndex,
|
|
419
|
+
inputText: newOriginalInputText,
|
|
420
|
+
longTextMap: newOriginalLongTextMap,
|
|
421
|
+
cursorPosition: newOriginalInputText.length,
|
|
422
|
+
originalInputText: newOriginalInputText,
|
|
423
|
+
originalLongTextMap: newOriginalLongTextMap,
|
|
424
|
+
};
|
|
425
|
+
} else {
|
|
426
|
+
const entry = state.history[newIndex];
|
|
427
|
+
return {
|
|
428
|
+
...state,
|
|
429
|
+
historyIndex: newIndex,
|
|
430
|
+
inputText: entry.prompt,
|
|
431
|
+
longTextMap: entry.longTextMap || {},
|
|
432
|
+
cursorPosition: entry.prompt.length,
|
|
433
|
+
originalInputText: newOriginalInputText,
|
|
434
|
+
originalLongTextMap: newOriginalLongTextMap,
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
case "SELECT_HISTORY_ENTRY": {
|
|
439
|
+
const entry = action.payload;
|
|
440
|
+
return {
|
|
441
|
+
...state,
|
|
442
|
+
inputText: entry.prompt,
|
|
443
|
+
longTextMap: entry.longTextMap || {},
|
|
444
|
+
cursorPosition: entry.prompt.length,
|
|
445
|
+
historyIndex: -1,
|
|
446
|
+
history: [],
|
|
447
|
+
originalInputText: "",
|
|
448
|
+
originalLongTextMap: {},
|
|
449
|
+
showHistorySearch: false,
|
|
450
|
+
historySearchQuery: "",
|
|
451
|
+
selectorJustUsed: true,
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
case "RESET_HISTORY_NAVIGATION":
|
|
455
|
+
return {
|
|
456
|
+
...state,
|
|
457
|
+
historyIndex: -1,
|
|
458
|
+
history: [],
|
|
459
|
+
originalInputText: "",
|
|
460
|
+
originalLongTextMap: {},
|
|
461
|
+
};
|
|
364
462
|
default:
|
|
365
463
|
return state;
|
|
366
464
|
}
|
package/src/utils/logger.ts
CHANGED
|
@@ -9,8 +9,11 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import * as fs from "fs";
|
|
12
|
+
import { Chalk } from "chalk";
|
|
12
13
|
import { LOG_FILE, DATA_DIRECTORY } from "./constants.js";
|
|
13
14
|
|
|
15
|
+
const chalk = new Chalk({ level: 3 });
|
|
16
|
+
|
|
14
17
|
const logFile = process.env.LOG_FILE || LOG_FILE;
|
|
15
18
|
|
|
16
19
|
/**
|
|
@@ -33,6 +36,16 @@ const LOG_LEVEL_NAMES = {
|
|
|
33
36
|
[LogLevel.ERROR]: "ERROR",
|
|
34
37
|
};
|
|
35
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Log level color mapping
|
|
41
|
+
*/
|
|
42
|
+
const LEVEL_COLORS = {
|
|
43
|
+
[LogLevel.DEBUG]: chalk.gray,
|
|
44
|
+
[LogLevel.INFO]: chalk.blue,
|
|
45
|
+
[LogLevel.WARN]: chalk.yellow,
|
|
46
|
+
[LogLevel.ERROR]: chalk.red,
|
|
47
|
+
};
|
|
48
|
+
|
|
36
49
|
/**
|
|
37
50
|
* Log configuration interface
|
|
38
51
|
*/
|
|
@@ -146,7 +159,8 @@ const logMessage = (level: LogLevel, ...args: unknown[]): void => {
|
|
|
146
159
|
|
|
147
160
|
const levelName = LOG_LEVEL_NAMES[level];
|
|
148
161
|
const timestamp = new Date().toISOString();
|
|
149
|
-
const
|
|
162
|
+
const color = LEVEL_COLORS[level] || ((s: string) => s);
|
|
163
|
+
const formattedMessage = `[${chalk.gray(timestamp)}] [${color(levelName)}] ${messageText}\n`;
|
|
150
164
|
|
|
151
165
|
try {
|
|
152
166
|
// Ensure directory exists
|