wave-code 0.9.0 → 0.9.2
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 +23 -6
- 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 +33 -6
- 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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"}
|
|
@@ -25,14 +25,16 @@ export const handleSubmit = async (state, dispatch, callbacks, attachedImagesOve
|
|
|
25
25
|
})
|
|
26
26
|
.filter((img) => img !== undefined)
|
|
27
27
|
.map((img) => ({ path: img.path, mimeType: img.mimeType }));
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
const contentWithPlaceholders = state.inputText
|
|
29
|
+
.replace(imageRegex, "")
|
|
30
|
+
.trim();
|
|
31
|
+
const cleanContent = expandLongTextPlaceholders(contentWithPlaceholders, state.longTextMap);
|
|
32
|
+
PromptHistoryManager.addEntry(contentWithPlaceholders, callbacks.sessionId, state.longTextMap).catch((err) => {
|
|
31
33
|
callbacks.logger?.error("Failed to save prompt history", err);
|
|
32
34
|
});
|
|
33
35
|
callbacks.onSendMessage?.(cleanContent, referencedImages.length > 0 ? referencedImages : undefined);
|
|
34
36
|
dispatch({ type: "CLEAR_INPUT" });
|
|
35
|
-
|
|
37
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
36
38
|
dispatch({ type: "CLEAR_LONG_TEXT_MAP" });
|
|
37
39
|
}
|
|
38
40
|
};
|
|
@@ -190,7 +192,7 @@ export const handlePasteInput = (state, dispatch, callbacks, input) => {
|
|
|
190
192
|
if (char === "!" && state.cursorPosition === 0) {
|
|
191
193
|
char = "!";
|
|
192
194
|
}
|
|
193
|
-
|
|
195
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
194
196
|
dispatch({ type: "INSERT_TEXT", payload: char });
|
|
195
197
|
processSelectorInput(state, dispatch, char);
|
|
196
198
|
}
|
|
@@ -348,6 +350,21 @@ export const handleNormalInput = async (state, dispatch, callbacks, input, key,
|
|
|
348
350
|
else if (state.showCommandSelector) {
|
|
349
351
|
dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
|
|
350
352
|
}
|
|
353
|
+
else if (state.historyIndex !== -1) {
|
|
354
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
355
|
+
}
|
|
356
|
+
return true;
|
|
357
|
+
}
|
|
358
|
+
if (key.upArrow) {
|
|
359
|
+
if (state.history.length === 0) {
|
|
360
|
+
const history = await PromptHistoryManager.getHistory(callbacks.sessionId);
|
|
361
|
+
dispatch({ type: "SET_HISTORY_ENTRIES", payload: history });
|
|
362
|
+
}
|
|
363
|
+
dispatch({ type: "NAVIGATE_HISTORY", payload: "up" });
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
if (key.downArrow) {
|
|
367
|
+
dispatch({ type: "NAVIGATE_HISTORY", payload: "down" });
|
|
351
368
|
return true;
|
|
352
369
|
}
|
|
353
370
|
if (key.backspace || key.delete) {
|
|
@@ -357,7 +374,7 @@ export const handleNormalInput = async (state, dispatch, callbacks, input, key,
|
|
|
357
374
|
const afterCursor = state.inputText.substring(state.cursorPosition);
|
|
358
375
|
const newInputText = beforeCursor + afterCursor;
|
|
359
376
|
dispatch({ type: "DELETE_CHAR" });
|
|
360
|
-
|
|
377
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
361
378
|
checkForAtDeletion(state, dispatch, newCursorPosition);
|
|
362
379
|
checkForSlashDeletion(state, dispatch, newCursorPosition);
|
|
363
380
|
// 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.2",
|
|
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.2"
|
|
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,
|
|
@@ -51,10 +51,19 @@ export const handleSubmit = async (
|
|
|
51
51
|
)
|
|
52
52
|
.map((img) => ({ path: img.path, mimeType: img.mimeType }));
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
const contentWithPlaceholders = state.inputText
|
|
55
|
+
.replace(imageRegex, "")
|
|
56
|
+
.trim();
|
|
57
|
+
const cleanContent = expandLongTextPlaceholders(
|
|
58
|
+
contentWithPlaceholders,
|
|
59
|
+
state.longTextMap,
|
|
60
|
+
);
|
|
56
61
|
|
|
57
|
-
PromptHistoryManager.addEntry(
|
|
62
|
+
PromptHistoryManager.addEntry(
|
|
63
|
+
contentWithPlaceholders,
|
|
64
|
+
callbacks.sessionId,
|
|
65
|
+
state.longTextMap,
|
|
66
|
+
).catch((err: unknown) => {
|
|
58
67
|
callbacks.logger?.error("Failed to save prompt history", err);
|
|
59
68
|
});
|
|
60
69
|
|
|
@@ -63,7 +72,7 @@ export const handleSubmit = async (
|
|
|
63
72
|
referencedImages.length > 0 ? referencedImages : undefined,
|
|
64
73
|
);
|
|
65
74
|
dispatch({ type: "CLEAR_INPUT" });
|
|
66
|
-
|
|
75
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
67
76
|
dispatch({ type: "CLEAR_LONG_TEXT_MAP" });
|
|
68
77
|
}
|
|
69
78
|
};
|
|
@@ -276,7 +285,7 @@ export const handlePasteInput = (
|
|
|
276
285
|
char = "!";
|
|
277
286
|
}
|
|
278
287
|
|
|
279
|
-
|
|
288
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
280
289
|
dispatch({ type: "INSERT_TEXT", payload: char });
|
|
281
290
|
|
|
282
291
|
processSelectorInput(state, dispatch, char);
|
|
@@ -494,10 +503,28 @@ export const handleNormalInput = async (
|
|
|
494
503
|
dispatch({ type: "CANCEL_FILE_SELECTOR" });
|
|
495
504
|
} else if (state.showCommandSelector) {
|
|
496
505
|
dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
|
|
506
|
+
} else if (state.historyIndex !== -1) {
|
|
507
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
497
508
|
}
|
|
498
509
|
return true;
|
|
499
510
|
}
|
|
500
511
|
|
|
512
|
+
if (key.upArrow) {
|
|
513
|
+
if (state.history.length === 0) {
|
|
514
|
+
const history = await PromptHistoryManager.getHistory(
|
|
515
|
+
callbacks.sessionId,
|
|
516
|
+
);
|
|
517
|
+
dispatch({ type: "SET_HISTORY_ENTRIES", payload: history });
|
|
518
|
+
}
|
|
519
|
+
dispatch({ type: "NAVIGATE_HISTORY", payload: "up" });
|
|
520
|
+
return true;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
if (key.downArrow) {
|
|
524
|
+
dispatch({ type: "NAVIGATE_HISTORY", payload: "down" });
|
|
525
|
+
return true;
|
|
526
|
+
}
|
|
527
|
+
|
|
501
528
|
if (key.backspace || key.delete) {
|
|
502
529
|
if (state.cursorPosition > 0) {
|
|
503
530
|
const newCursorPosition = state.cursorPosition - 1;
|
|
@@ -509,7 +536,7 @@ export const handleNormalInput = async (
|
|
|
509
536
|
const newInputText = beforeCursor + afterCursor;
|
|
510
537
|
|
|
511
538
|
dispatch({ type: "DELETE_CHAR" });
|
|
512
|
-
|
|
539
|
+
dispatch({ type: "RESET_HISTORY_NAVIGATION" });
|
|
513
540
|
|
|
514
541
|
checkForAtDeletion(state, dispatch, newCursorPosition);
|
|
515
542
|
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
|