wave-code 0.2.1 → 0.5.0
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/commands/plugin/disable.d.ts +2 -1
- package/dist/commands/plugin/disable.d.ts.map +1 -1
- package/dist/commands/plugin/disable.js +3 -2
- package/dist/commands/plugin/enable.d.ts +2 -1
- package/dist/commands/plugin/enable.d.ts.map +1 -1
- package/dist/commands/plugin/enable.js +3 -2
- package/dist/commands/plugin/install.d.ts +2 -1
- package/dist/commands/plugin/install.d.ts.map +1 -1
- package/dist/commands/plugin/list.d.ts.map +1 -1
- package/dist/commands/plugin/list.js +15 -3
- package/dist/commands/plugin/marketplace.d.ts +3 -0
- package/dist/commands/plugin/marketplace.d.ts.map +1 -1
- package/dist/commands/plugin/marketplace.js +15 -1
- package/dist/commands/plugin/uninstall.d.ts +4 -0
- package/dist/commands/plugin/uninstall.d.ts.map +1 -0
- package/dist/commands/plugin/uninstall.js +29 -0
- package/dist/commands/plugin/update.d.ts +4 -0
- package/dist/commands/plugin/update.d.ts.map +1 -0
- package/dist/commands/plugin/update.js +15 -0
- package/dist/components/ChatInterface.d.ts.map +1 -1
- package/dist/components/ChatInterface.js +2 -2
- package/dist/components/CommandSelector.d.ts.map +1 -1
- package/dist/components/CommandSelector.js +9 -3
- package/dist/components/Confirmation.d.ts.map +1 -1
- package/dist/components/Confirmation.js +73 -20
- package/dist/components/DiffDisplay.d.ts +0 -1
- package/dist/components/DiffDisplay.d.ts.map +1 -1
- package/dist/components/DiffDisplay.js +38 -59
- package/dist/components/DiscoverView.d.ts +3 -0
- package/dist/components/DiscoverView.d.ts.map +1 -0
- package/dist/components/DiscoverView.js +25 -0
- package/dist/components/FileSelector.js +1 -1
- package/dist/components/HistorySearch.d.ts +8 -0
- package/dist/components/HistorySearch.d.ts.map +1 -0
- package/dist/components/HistorySearch.js +67 -0
- package/dist/components/InputBox.d.ts +1 -1
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +29 -19
- package/dist/components/InstalledView.d.ts +3 -0
- package/dist/components/InstalledView.d.ts.map +1 -0
- package/dist/components/InstalledView.js +30 -0
- package/dist/components/Markdown.d.ts.map +1 -1
- package/dist/components/Markdown.js +24 -10
- package/dist/components/MarketplaceAddForm.d.ts +3 -0
- package/dist/components/MarketplaceAddForm.d.ts.map +1 -0
- package/dist/components/MarketplaceAddForm.js +26 -0
- package/dist/components/MarketplaceDetail.d.ts +3 -0
- package/dist/components/MarketplaceDetail.d.ts.map +1 -0
- package/dist/components/MarketplaceDetail.js +38 -0
- package/dist/components/MarketplaceList.d.ts +9 -0
- package/dist/components/MarketplaceList.d.ts.map +1 -0
- package/dist/components/MarketplaceList.js +16 -0
- package/dist/components/MarketplaceView.d.ts +3 -0
- package/dist/components/MarketplaceView.d.ts.map +1 -0
- package/dist/components/MarketplaceView.js +28 -0
- package/dist/components/PlanDisplay.d.ts.map +1 -1
- package/dist/components/PlanDisplay.js +2 -2
- package/dist/components/PluginDetail.d.ts +3 -0
- package/dist/components/PluginDetail.d.ts.map +1 -0
- package/dist/components/PluginDetail.js +63 -0
- package/dist/components/PluginList.d.ts +14 -0
- package/dist/components/PluginList.d.ts.map +1 -0
- package/dist/components/PluginList.js +12 -0
- package/dist/components/PluginManagerShell.d.ts +5 -0
- package/dist/components/PluginManagerShell.d.ts.map +1 -0
- package/dist/components/PluginManagerShell.js +89 -0
- package/dist/components/PluginManagerTypes.d.ts +33 -0
- package/dist/components/PluginManagerTypes.d.ts.map +1 -0
- package/dist/components/PluginManagerTypes.js +1 -0
- package/dist/components/RewindCommand.d.ts +9 -0
- package/dist/components/RewindCommand.d.ts.map +1 -0
- package/dist/components/RewindCommand.js +42 -0
- package/dist/components/SessionSelector.d.ts +11 -0
- package/dist/components/SessionSelector.d.ts.map +1 -0
- package/dist/components/SessionSelector.js +38 -0
- package/dist/components/SubagentBlock.d.ts.map +1 -1
- package/dist/components/SubagentBlock.js +24 -1
- package/dist/components/TaskManager.d.ts +6 -0
- package/dist/components/TaskManager.d.ts.map +1 -0
- package/dist/components/TaskManager.js +114 -0
- package/dist/components/ToolResultDisplay.d.ts.map +1 -1
- package/dist/components/ToolResultDisplay.js +2 -1
- package/dist/contexts/PluginManagerContext.d.ts +4 -0
- package/dist/contexts/PluginManagerContext.d.ts.map +1 -0
- package/dist/contexts/PluginManagerContext.js +9 -0
- package/dist/contexts/useChat.d.ts +7 -4
- package/dist/contexts/useChat.d.ts.map +1 -1
- package/dist/contexts/useChat.js +37 -12
- package/dist/hooks/useInputManager.d.ts +8 -16
- package/dist/hooks/useInputManager.d.ts.map +1 -1
- package/dist/hooks/useInputManager.js +39 -55
- package/dist/hooks/usePluginManager.d.ts +3 -0
- package/dist/hooks/usePluginManager.d.ts.map +1 -0
- package/dist/hooks/usePluginManager.js +227 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +150 -177
- package/dist/managers/InputManager.d.ts +18 -26
- package/dist/managers/InputManager.d.ts.map +1 -1
- package/dist/managers/InputManager.js +93 -119
- package/dist/plugin-manager-cli.d.ts +6 -0
- package/dist/plugin-manager-cli.d.ts.map +1 -0
- package/dist/plugin-manager-cli.js +12 -0
- package/dist/session-selector-cli.d.ts +2 -0
- package/dist/session-selector-cli.d.ts.map +1 -0
- package/dist/session-selector-cli.js +25 -0
- package/package.json +9 -5
- package/src/commands/plugin/disable.ts +7 -3
- package/src/commands/plugin/enable.ts +7 -3
- package/src/commands/plugin/install.ts +2 -1
- package/src/commands/plugin/list.ts +21 -3
- package/src/commands/plugin/marketplace.ts +17 -1
- package/src/commands/plugin/uninstall.ts +39 -0
- package/src/commands/plugin/update.ts +19 -0
- package/src/components/ChatInterface.tsx +2 -1
- package/src/components/CommandSelector.tsx +10 -3
- package/src/components/Confirmation.tsx +115 -25
- package/src/components/DiffDisplay.tsx +60 -106
- package/src/components/DiscoverView.tsx +31 -0
- package/src/components/FileSelector.tsx +1 -1
- package/src/components/HistorySearch.tsx +148 -0
- package/src/components/InputBox.tsx +51 -34
- package/src/components/InstalledView.tsx +61 -0
- package/src/components/Markdown.tsx +44 -28
- package/src/components/MarketplaceAddForm.tsx +39 -0
- package/src/components/MarketplaceDetail.tsx +79 -0
- package/src/components/MarketplaceList.tsx +52 -0
- package/src/components/MarketplaceView.tsx +43 -0
- package/src/components/PlanDisplay.tsx +14 -19
- package/src/components/PluginDetail.tsx +147 -0
- package/src/components/PluginList.tsx +51 -0
- package/src/components/PluginManagerShell.tsx +189 -0
- package/src/components/PluginManagerTypes.ts +47 -0
- package/src/components/RewindCommand.tsx +114 -0
- package/src/components/SessionSelector.tsx +127 -0
- package/src/components/SubagentBlock.tsx +34 -1
- package/src/components/{BashShellManager.tsx → TaskManager.tsx} +79 -75
- package/src/components/ToolResultDisplay.tsx +6 -2
- package/src/contexts/PluginManagerContext.ts +15 -0
- package/src/contexts/useChat.tsx +51 -20
- package/src/hooks/useInputManager.ts +39 -71
- package/src/hooks/usePluginManager.ts +302 -0
- package/src/index.ts +241 -280
- package/src/managers/InputManager.ts +113 -162
- package/src/plugin-manager-cli.tsx +13 -0
- package/src/session-selector-cli.tsx +37 -0
- package/dist/components/BashHistorySelector.d.ts +0 -11
- package/dist/components/BashHistorySelector.d.ts.map +0 -1
- package/dist/components/BashHistorySelector.js +0 -93
- package/dist/components/BashShellManager.d.ts +0 -6
- package/dist/components/BashShellManager.d.ts.map +0 -1
- package/dist/components/BashShellManager.js +0 -116
- package/dist/hooks/usePagination.d.ts +0 -20
- package/dist/hooks/usePagination.d.ts.map +0 -1
- package/dist/hooks/usePagination.js +0 -168
- package/src/components/BashHistorySelector.tsx +0 -181
- package/src/hooks/usePagination.ts +0 -203
package/src/contexts/useChat.tsx
CHANGED
|
@@ -11,7 +11,7 @@ import { useAppConfig } from "./useAppConfig.js";
|
|
|
11
11
|
import type {
|
|
12
12
|
Message,
|
|
13
13
|
McpServerStatus,
|
|
14
|
-
|
|
14
|
+
BackgroundTask,
|
|
15
15
|
SlashCommand,
|
|
16
16
|
PermissionDecision,
|
|
17
17
|
PermissionMode,
|
|
@@ -47,12 +47,12 @@ export interface ChatContextType {
|
|
|
47
47
|
mcpServers: McpServerStatus[];
|
|
48
48
|
connectMcpServer: (serverName: string) => Promise<boolean>;
|
|
49
49
|
disconnectMcpServer: (serverName: string) => Promise<boolean>;
|
|
50
|
-
// Background
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
// Background tasks
|
|
51
|
+
backgroundTasks: BackgroundTask[];
|
|
52
|
+
getBackgroundTaskOutput: (
|
|
53
|
+
taskId: string,
|
|
54
54
|
) => { stdout: string; stderr: string; status: string } | null;
|
|
55
|
-
|
|
55
|
+
stopBackgroundTask: (taskId: string) => boolean;
|
|
56
56
|
// Slash Command functionality
|
|
57
57
|
slashCommands: SlashCommand[];
|
|
58
58
|
hasSlashCommand: (commandId: string) => boolean;
|
|
@@ -78,6 +78,11 @@ export interface ChatContextType {
|
|
|
78
78
|
hideConfirmation: () => void;
|
|
79
79
|
handleConfirmationDecision: (decision: PermissionDecision) => void;
|
|
80
80
|
handleConfirmationCancel: () => void;
|
|
81
|
+
// Background current task
|
|
82
|
+
backgroundCurrentTask: () => void;
|
|
83
|
+
// Rewind functionality
|
|
84
|
+
rewindId: number;
|
|
85
|
+
handleRewindSelect: (index: number) => Promise<void>;
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
const ChatContext = createContext<ChatContextType | null>(null);
|
|
@@ -118,10 +123,8 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
118
123
|
// MCP State
|
|
119
124
|
const [mcpServers, setMcpServers] = useState<McpServerStatus[]>([]);
|
|
120
125
|
|
|
121
|
-
// Background
|
|
122
|
-
const [
|
|
123
|
-
[],
|
|
124
|
-
);
|
|
126
|
+
// Background tasks state
|
|
127
|
+
const [backgroundTasks, setBackgroundTasks] = useState<BackgroundTask[]>([]);
|
|
125
128
|
|
|
126
129
|
// Command state
|
|
127
130
|
const [slashCommands, setSlashCommands] = useState<SlashCommand[]>([]);
|
|
@@ -165,6 +168,9 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
165
168
|
reject: () => void;
|
|
166
169
|
} | null>(null);
|
|
167
170
|
|
|
171
|
+
// Rewind state
|
|
172
|
+
const [rewindId, setRewindId] = useState(0);
|
|
173
|
+
|
|
168
174
|
const agentRef = useRef<Agent | null>(null);
|
|
169
175
|
|
|
170
176
|
// Permission confirmation methods with queue support
|
|
@@ -216,8 +222,8 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
216
222
|
onCompressionStateChange: (isCompressingState) => {
|
|
217
223
|
setIsCompressing(isCompressingState);
|
|
218
224
|
},
|
|
219
|
-
|
|
220
|
-
|
|
225
|
+
onTasksChange: (tasks) => {
|
|
226
|
+
setBackgroundTasks([...tasks]);
|
|
221
227
|
},
|
|
222
228
|
onSubagentMessagesChange: (subagentId, messages) => {
|
|
223
229
|
logger.debug("onSubagentMessagesChange", subagentId, messages.length);
|
|
@@ -229,6 +235,9 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
229
235
|
onPermissionModeChange: (mode) => {
|
|
230
236
|
setPermissionModeState(mode);
|
|
231
237
|
},
|
|
238
|
+
onSlashCommandsChange: (commands) => {
|
|
239
|
+
setSlashCommands([...commands]);
|
|
240
|
+
},
|
|
232
241
|
};
|
|
233
242
|
|
|
234
243
|
try {
|
|
@@ -413,15 +422,15 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
413
422
|
return (await agentRef.current?.disconnectMcpServer(serverName)) ?? false;
|
|
414
423
|
}, []);
|
|
415
424
|
|
|
416
|
-
// Background
|
|
417
|
-
const
|
|
425
|
+
// Background task management methods - delegate to Agent
|
|
426
|
+
const getBackgroundTaskOutput = useCallback((taskId: string) => {
|
|
418
427
|
if (!agentRef.current) return null;
|
|
419
|
-
return agentRef.current.
|
|
428
|
+
return agentRef.current.getBackgroundTaskOutput(taskId);
|
|
420
429
|
}, []);
|
|
421
430
|
|
|
422
|
-
const
|
|
431
|
+
const stopBackgroundTask = useCallback((taskId: string) => {
|
|
423
432
|
if (!agentRef.current) return false;
|
|
424
|
-
return agentRef.current.
|
|
433
|
+
return agentRef.current.stopBackgroundTask(taskId);
|
|
425
434
|
}, []);
|
|
426
435
|
|
|
427
436
|
const hasSlashCommand = useCallback((commandId: string) => {
|
|
@@ -473,6 +482,25 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
473
482
|
hideConfirmation();
|
|
474
483
|
}, [currentConfirmation, hideConfirmation]);
|
|
475
484
|
|
|
485
|
+
const backgroundCurrentTask = useCallback(() => {
|
|
486
|
+
agentRef.current?.backgroundCurrentTask();
|
|
487
|
+
}, []);
|
|
488
|
+
|
|
489
|
+
const handleRewindSelect = useCallback(async (index: number) => {
|
|
490
|
+
if (agentRef.current) {
|
|
491
|
+
try {
|
|
492
|
+
await agentRef.current.truncateHistory(index);
|
|
493
|
+
|
|
494
|
+
// Clear terminal screen after rewind
|
|
495
|
+
process.stdout.write("\x1Bc", () => {
|
|
496
|
+
setRewindId((prev) => prev + 1);
|
|
497
|
+
});
|
|
498
|
+
} catch (error) {
|
|
499
|
+
logger.error("Failed to rewind:", error);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}, []);
|
|
503
|
+
|
|
476
504
|
// Listen for Ctrl+O hotkey to toggle collapse/expand state and ESC to cancel confirmation
|
|
477
505
|
useInput((input, key) => {
|
|
478
506
|
if (key.ctrl && input === "o") {
|
|
@@ -506,9 +534,9 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
506
534
|
mcpServers,
|
|
507
535
|
connectMcpServer,
|
|
508
536
|
disconnectMcpServer,
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
537
|
+
backgroundTasks,
|
|
538
|
+
getBackgroundTaskOutput,
|
|
539
|
+
stopBackgroundTask,
|
|
512
540
|
slashCommands,
|
|
513
541
|
hasSlashCommand,
|
|
514
542
|
subagentMessages,
|
|
@@ -520,6 +548,9 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
520
548
|
hideConfirmation,
|
|
521
549
|
handleConfirmationDecision,
|
|
522
550
|
handleConfirmationCancel,
|
|
551
|
+
backgroundCurrentTask,
|
|
552
|
+
rewindId,
|
|
553
|
+
handleRewindSelect,
|
|
523
554
|
};
|
|
524
555
|
|
|
525
556
|
return (
|
|
@@ -29,17 +29,17 @@ export const useInputManager = (
|
|
|
29
29
|
query: "",
|
|
30
30
|
position: -1,
|
|
31
31
|
});
|
|
32
|
-
const [
|
|
32
|
+
const [historySearchState, setHistorySearchState] = useState({
|
|
33
33
|
show: false,
|
|
34
34
|
query: "",
|
|
35
|
-
position: -1,
|
|
36
35
|
});
|
|
37
36
|
const [memoryTypeSelectorState, setMemoryTypeSelectorState] = useState({
|
|
38
37
|
show: false,
|
|
39
38
|
message: "",
|
|
40
39
|
});
|
|
41
|
-
const [
|
|
40
|
+
const [showTaskManager, setShowTaskManager] = useState(false);
|
|
42
41
|
const [showMcpManager, setShowMcpManager] = useState(false);
|
|
42
|
+
const [showRewindManager, setShowRewindManager] = useState(false);
|
|
43
43
|
const [permissionMode, setPermissionModeState] =
|
|
44
44
|
useState<PermissionMode>("default");
|
|
45
45
|
const [attachedImages, setAttachedImages] = useState<AttachedImage[]>([]);
|
|
@@ -58,25 +58,29 @@ export const useInputManager = (
|
|
|
58
58
|
onCommandSelectorStateChange: (show, query, position) => {
|
|
59
59
|
setCommandSelectorState({ show, query, position });
|
|
60
60
|
},
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
onHistorySearchStateChange: (show, query) => {
|
|
62
|
+
setHistorySearchState({ show, query });
|
|
63
63
|
},
|
|
64
64
|
onMemoryTypeSelectorStateChange: (show, message) => {
|
|
65
65
|
setMemoryTypeSelectorState({ show, message });
|
|
66
66
|
},
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
onTaskManagerStateChange: (show) => {
|
|
68
|
+
setShowTaskManager(show);
|
|
69
69
|
},
|
|
70
70
|
onMcpManagerStateChange: (show) => {
|
|
71
71
|
setShowMcpManager(show);
|
|
72
72
|
},
|
|
73
|
+
onRewindManagerStateChange: (show) => {
|
|
74
|
+
setShowRewindManager(show);
|
|
75
|
+
},
|
|
73
76
|
onPermissionModeChange: (mode) => {
|
|
74
77
|
setPermissionModeState(mode);
|
|
75
78
|
callbacks.onPermissionModeChange?.(mode);
|
|
76
79
|
},
|
|
77
80
|
onImagesStateChange: setAttachedImages,
|
|
78
|
-
|
|
81
|
+
onShowTaskManager: () => setShowTaskManager(true),
|
|
79
82
|
onShowMcpManager: () => setShowMcpManager(true),
|
|
83
|
+
onShowRewindManager: () => setShowRewindManager(true),
|
|
80
84
|
...callbacks,
|
|
81
85
|
});
|
|
82
86
|
|
|
@@ -94,25 +98,29 @@ export const useInputManager = (
|
|
|
94
98
|
onCommandSelectorStateChange: (show, query, position) => {
|
|
95
99
|
setCommandSelectorState({ show, query, position });
|
|
96
100
|
},
|
|
97
|
-
|
|
98
|
-
|
|
101
|
+
onHistorySearchStateChange: (show, query) => {
|
|
102
|
+
setHistorySearchState({ show, query });
|
|
99
103
|
},
|
|
100
104
|
onMemoryTypeSelectorStateChange: (show, message) => {
|
|
101
105
|
setMemoryTypeSelectorState({ show, message });
|
|
102
106
|
},
|
|
103
|
-
|
|
104
|
-
|
|
107
|
+
onTaskManagerStateChange: (show) => {
|
|
108
|
+
setShowTaskManager(show);
|
|
105
109
|
},
|
|
106
110
|
onMcpManagerStateChange: (show) => {
|
|
107
111
|
setShowMcpManager(show);
|
|
108
112
|
},
|
|
113
|
+
onRewindManagerStateChange: (show) => {
|
|
114
|
+
setShowRewindManager(show);
|
|
115
|
+
},
|
|
109
116
|
onPermissionModeChange: (mode) => {
|
|
110
117
|
setPermissionModeState(mode);
|
|
111
118
|
callbacks.onPermissionModeChange?.(mode);
|
|
112
119
|
},
|
|
113
120
|
onImagesStateChange: setAttachedImages,
|
|
114
|
-
|
|
121
|
+
onShowTaskManager: () => setShowTaskManager(true),
|
|
115
122
|
onShowMcpManager: () => setShowMcpManager(true),
|
|
123
|
+
onShowRewindManager: () => setShowRewindManager(true),
|
|
116
124
|
...callbacks,
|
|
117
125
|
});
|
|
118
126
|
}
|
|
@@ -235,37 +243,13 @@ export const useInputManager = (
|
|
|
235
243
|
return managerRef.current?.checkForSlashDeletion(cursorPos) || false;
|
|
236
244
|
}, []);
|
|
237
245
|
|
|
238
|
-
//
|
|
239
|
-
const
|
|
240
|
-
managerRef.current?.
|
|
241
|
-
}, []);
|
|
242
|
-
|
|
243
|
-
const handleBashHistorySelect = useCallback(
|
|
244
|
-
(command: string) => {
|
|
245
|
-
return (
|
|
246
|
-
managerRef.current?.handleBashHistorySelect(command) || {
|
|
247
|
-
newInput: inputText,
|
|
248
|
-
newCursorPosition: cursorPosition,
|
|
249
|
-
}
|
|
250
|
-
);
|
|
251
|
-
},
|
|
252
|
-
[inputText, cursorPosition],
|
|
253
|
-
);
|
|
254
|
-
|
|
255
|
-
const handleCancelBashHistorySelect = useCallback(() => {
|
|
256
|
-
managerRef.current?.handleCancelBashHistorySelect();
|
|
257
|
-
}, []);
|
|
258
|
-
|
|
259
|
-
const updateBashHistorySearchQuery = useCallback((query: string) => {
|
|
260
|
-
managerRef.current?.updateBashHistorySearchQuery(query);
|
|
246
|
+
// History search methods
|
|
247
|
+
const handleHistorySearchSelect = useCallback((prompt: string) => {
|
|
248
|
+
managerRef.current?.handleHistorySearchSelect(prompt);
|
|
261
249
|
}, []);
|
|
262
250
|
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
}, []);
|
|
266
|
-
|
|
267
|
-
const checkForExclamationDeletion = useCallback((cursorPos: number) => {
|
|
268
|
-
return managerRef.current?.checkForExclamationDeletion(cursorPos) || false;
|
|
251
|
+
const handleCancelHistorySearch = useCallback(() => {
|
|
252
|
+
managerRef.current?.handleCancelHistorySearch();
|
|
269
253
|
}, []);
|
|
270
254
|
|
|
271
255
|
// Memory type selector methods
|
|
@@ -320,17 +304,6 @@ export const useInputManager = (
|
|
|
320
304
|
}, []);
|
|
321
305
|
|
|
322
306
|
// Complex handlers that combine multiple operations
|
|
323
|
-
const handleBashHistoryExecuteAndSend = useCallback((command: string) => {
|
|
324
|
-
managerRef.current?.handleBashHistoryExecuteAndSend(command);
|
|
325
|
-
}, []);
|
|
326
|
-
|
|
327
|
-
const handleBashHistoryDelete = useCallback(
|
|
328
|
-
(command: string, workdir?: string) => {
|
|
329
|
-
managerRef.current?.handleBashHistoryDelete(command, workdir);
|
|
330
|
-
},
|
|
331
|
-
[],
|
|
332
|
-
);
|
|
333
|
-
|
|
334
307
|
return {
|
|
335
308
|
// State
|
|
336
309
|
inputText,
|
|
@@ -342,13 +315,13 @@ export const useInputManager = (
|
|
|
342
315
|
showCommandSelector: commandSelectorState.show,
|
|
343
316
|
commandSearchQuery: commandSelectorState.query,
|
|
344
317
|
slashPosition: commandSelectorState.position,
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
exclamationPosition: bashHistorySelectorState.position,
|
|
318
|
+
showHistorySearch: historySearchState.show,
|
|
319
|
+
historySearchQuery: historySearchState.query,
|
|
348
320
|
showMemoryTypeSelector: memoryTypeSelectorState.show,
|
|
349
321
|
memoryMessage: memoryTypeSelectorState.message,
|
|
350
|
-
|
|
322
|
+
showTaskManager,
|
|
351
323
|
showMcpManager,
|
|
324
|
+
showRewindManager,
|
|
352
325
|
permissionMode,
|
|
353
326
|
attachedImages,
|
|
354
327
|
isManagerReady,
|
|
@@ -377,14 +350,9 @@ export const useInputManager = (
|
|
|
377
350
|
updateCommandSearchQuery,
|
|
378
351
|
checkForSlashDeletion,
|
|
379
352
|
|
|
380
|
-
//
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
handleCancelBashHistorySelect,
|
|
384
|
-
updateBashHistorySearchQuery,
|
|
385
|
-
|
|
386
|
-
handleBashHistoryExecute,
|
|
387
|
-
checkForExclamationDeletion,
|
|
353
|
+
// History search
|
|
354
|
+
handleHistorySearchSelect,
|
|
355
|
+
handleCancelHistorySearch,
|
|
388
356
|
|
|
389
357
|
// Memory type selector
|
|
390
358
|
activateMemoryTypeSelector,
|
|
@@ -400,12 +368,16 @@ export const useInputManager = (
|
|
|
400
368
|
handleSpecialCharInput,
|
|
401
369
|
|
|
402
370
|
// Bash/MCP Manager
|
|
403
|
-
|
|
404
|
-
managerRef.current?.
|
|
371
|
+
setShowTaskManager: useCallback((show: boolean) => {
|
|
372
|
+
managerRef.current?.setShowTaskManager(show);
|
|
405
373
|
}, []),
|
|
406
374
|
setShowMcpManager: useCallback((show: boolean) => {
|
|
407
375
|
managerRef.current?.setShowMcpManager(show);
|
|
408
376
|
}, []),
|
|
377
|
+
setShowRewindManager: useCallback((show: boolean) => {
|
|
378
|
+
managerRef.current?.setShowRewindManager(show);
|
|
379
|
+
setShowRewindManager(show);
|
|
380
|
+
}, []),
|
|
409
381
|
setPermissionMode: useCallback((mode: PermissionMode) => {
|
|
410
382
|
setPermissionModeState(mode);
|
|
411
383
|
managerRef.current?.setPermissionMode(mode);
|
|
@@ -450,10 +422,6 @@ export const useInputManager = (
|
|
|
450
422
|
managerRef.current?.clearLongTextMap();
|
|
451
423
|
}, []),
|
|
452
424
|
|
|
453
|
-
// Complex handlers combining multiple operations
|
|
454
|
-
handleBashHistoryExecuteAndSend,
|
|
455
|
-
handleBashHistoryDelete,
|
|
456
|
-
|
|
457
425
|
// Main input handler
|
|
458
426
|
handleInput: useCallback(
|
|
459
427
|
async (
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { useState, useCallback, useEffect, useMemo } from "react";
|
|
2
|
+
import {
|
|
3
|
+
MarketplaceService,
|
|
4
|
+
PluginScopeManager,
|
|
5
|
+
ConfigurationService,
|
|
6
|
+
PluginManager,
|
|
7
|
+
KnownMarketplace,
|
|
8
|
+
InstalledPlugin,
|
|
9
|
+
MarketplacePluginEntry,
|
|
10
|
+
} from "wave-agent-sdk";
|
|
11
|
+
import {
|
|
12
|
+
PluginManagerState,
|
|
13
|
+
ViewType,
|
|
14
|
+
PluginManagerContextType,
|
|
15
|
+
} from "../components/PluginManagerTypes.js";
|
|
16
|
+
|
|
17
|
+
export function usePluginManager(): PluginManagerContextType {
|
|
18
|
+
const [state, setState] = useState<PluginManagerState>({
|
|
19
|
+
currentView: "DISCOVER",
|
|
20
|
+
selectedId: null,
|
|
21
|
+
isLoading: true,
|
|
22
|
+
error: null,
|
|
23
|
+
searchQuery: "",
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const [marketplaces, setMarketplaces] = useState<KnownMarketplace[]>([]);
|
|
27
|
+
const [installedPlugins, setInstalledPlugins] = useState<
|
|
28
|
+
(InstalledPlugin & { enabled: boolean })[]
|
|
29
|
+
>([]);
|
|
30
|
+
const [discoverablePlugins, setDiscoverablePlugins] = useState<
|
|
31
|
+
(MarketplacePluginEntry & {
|
|
32
|
+
marketplace: string;
|
|
33
|
+
installed: boolean;
|
|
34
|
+
version?: string;
|
|
35
|
+
})[]
|
|
36
|
+
>([]);
|
|
37
|
+
|
|
38
|
+
const marketplaceService = useMemo(() => new MarketplaceService(), []);
|
|
39
|
+
const configurationService = useMemo(() => new ConfigurationService(), []);
|
|
40
|
+
const pluginManager = useMemo(
|
|
41
|
+
() =>
|
|
42
|
+
new PluginManager({
|
|
43
|
+
workdir: process.cwd(),
|
|
44
|
+
configurationService,
|
|
45
|
+
}),
|
|
46
|
+
[configurationService],
|
|
47
|
+
);
|
|
48
|
+
const pluginScopeManager = useMemo(
|
|
49
|
+
() =>
|
|
50
|
+
new PluginScopeManager({
|
|
51
|
+
workdir: process.cwd(),
|
|
52
|
+
configurationService,
|
|
53
|
+
pluginManager,
|
|
54
|
+
}),
|
|
55
|
+
[configurationService, pluginManager],
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const refresh = useCallback(async () => {
|
|
59
|
+
setState((prev: PluginManagerState) => ({
|
|
60
|
+
...prev,
|
|
61
|
+
isLoading: true,
|
|
62
|
+
error: null,
|
|
63
|
+
}));
|
|
64
|
+
try {
|
|
65
|
+
const [mks, installed, enabledMap] = await Promise.all([
|
|
66
|
+
marketplaceService.listMarketplaces(),
|
|
67
|
+
marketplaceService.getInstalledPlugins(),
|
|
68
|
+
Promise.resolve(pluginScopeManager.getMergedEnabledPlugins()),
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
setMarketplaces(mks);
|
|
72
|
+
const allInstalledWithEnabled = installed.plugins.map((p) => {
|
|
73
|
+
const pluginId = `${p.name}@${p.marketplace}`;
|
|
74
|
+
return {
|
|
75
|
+
...p,
|
|
76
|
+
enabled: !!enabledMap[pluginId],
|
|
77
|
+
scope: pluginScopeManager.findPluginScope(pluginId) || undefined,
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Only show enabled plugins in the "Installed" view
|
|
82
|
+
setInstalledPlugins(allInstalledWithEnabled.filter((p) => p.enabled));
|
|
83
|
+
|
|
84
|
+
const allDiscoverable: (MarketplacePluginEntry & {
|
|
85
|
+
marketplace: string;
|
|
86
|
+
installed: boolean;
|
|
87
|
+
version?: string;
|
|
88
|
+
})[] = [];
|
|
89
|
+
for (const mk of mks) {
|
|
90
|
+
try {
|
|
91
|
+
const manifest = await marketplaceService.loadMarketplaceManifest(
|
|
92
|
+
marketplaceService.getMarketplacePath(mk),
|
|
93
|
+
);
|
|
94
|
+
manifest.plugins.forEach((p) => {
|
|
95
|
+
const pluginId = `${p.name}@${mk.name}`;
|
|
96
|
+
const isInstalled = installed.plugins.find(
|
|
97
|
+
(ip) => ip.name === p.name && ip.marketplace === mk.name,
|
|
98
|
+
);
|
|
99
|
+
const isEnabled = !!enabledMap[pluginId];
|
|
100
|
+
|
|
101
|
+
// Show in Discover if not installed OR if installed but not enabled in current scope
|
|
102
|
+
if (!isInstalled || !isEnabled) {
|
|
103
|
+
allDiscoverable.push({
|
|
104
|
+
...p,
|
|
105
|
+
marketplace: mk.name,
|
|
106
|
+
installed: !!isInstalled,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
} catch {
|
|
111
|
+
// Skip marketplaces that fail to load
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
setDiscoverablePlugins(allDiscoverable);
|
|
115
|
+
setState((prev: PluginManagerState) => ({ ...prev, isLoading: false }));
|
|
116
|
+
} catch (error) {
|
|
117
|
+
setState((prev: PluginManagerState) => ({
|
|
118
|
+
...prev,
|
|
119
|
+
isLoading: false,
|
|
120
|
+
error: error instanceof Error ? error.message : String(error),
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
}, [marketplaceService, pluginScopeManager]);
|
|
124
|
+
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
refresh();
|
|
127
|
+
}, [refresh]);
|
|
128
|
+
|
|
129
|
+
const setView = useCallback((view: ViewType) => {
|
|
130
|
+
setState((prev: PluginManagerState) => ({ ...prev, currentView: view }));
|
|
131
|
+
}, []);
|
|
132
|
+
|
|
133
|
+
const setSelectedId = useCallback((id: string | null) => {
|
|
134
|
+
setState((prev: PluginManagerState) => ({ ...prev, selectedId: id }));
|
|
135
|
+
}, []);
|
|
136
|
+
|
|
137
|
+
const addMarketplace = useCallback(
|
|
138
|
+
async (source: string) => {
|
|
139
|
+
setState((prev: PluginManagerState) => ({
|
|
140
|
+
...prev,
|
|
141
|
+
isLoading: true,
|
|
142
|
+
error: null,
|
|
143
|
+
}));
|
|
144
|
+
try {
|
|
145
|
+
await marketplaceService.addMarketplace(source);
|
|
146
|
+
await refresh();
|
|
147
|
+
} catch (error) {
|
|
148
|
+
setState((prev: PluginManagerState) => ({
|
|
149
|
+
...prev,
|
|
150
|
+
isLoading: false,
|
|
151
|
+
error: error instanceof Error ? error.message : String(error),
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
[marketplaceService, refresh],
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
const removeMarketplace = useCallback(
|
|
159
|
+
async (name: string) => {
|
|
160
|
+
setState((prev: PluginManagerState) => ({
|
|
161
|
+
...prev,
|
|
162
|
+
isLoading: true,
|
|
163
|
+
error: null,
|
|
164
|
+
}));
|
|
165
|
+
try {
|
|
166
|
+
await marketplaceService.removeMarketplace(name);
|
|
167
|
+
await refresh();
|
|
168
|
+
} catch (error) {
|
|
169
|
+
setState((prev: PluginManagerState) => ({
|
|
170
|
+
...prev,
|
|
171
|
+
isLoading: false,
|
|
172
|
+
error: error instanceof Error ? error.message : String(error),
|
|
173
|
+
}));
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
[marketplaceService, refresh],
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
const updateMarketplace = useCallback(
|
|
180
|
+
async (name: string) => {
|
|
181
|
+
setState((prev: PluginManagerState) => ({
|
|
182
|
+
...prev,
|
|
183
|
+
isLoading: true,
|
|
184
|
+
error: null,
|
|
185
|
+
}));
|
|
186
|
+
try {
|
|
187
|
+
await marketplaceService.updateMarketplace(name);
|
|
188
|
+
await refresh();
|
|
189
|
+
} catch (error) {
|
|
190
|
+
setState((prev: PluginManagerState) => ({
|
|
191
|
+
...prev,
|
|
192
|
+
isLoading: false,
|
|
193
|
+
error: error instanceof Error ? error.message : String(error),
|
|
194
|
+
}));
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
[marketplaceService, refresh],
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
const installPlugin = useCallback(
|
|
201
|
+
async (
|
|
202
|
+
name: string,
|
|
203
|
+
marketplace: string,
|
|
204
|
+
scope: "user" | "project" | "local" = "project",
|
|
205
|
+
) => {
|
|
206
|
+
setState((prev: PluginManagerState) => ({
|
|
207
|
+
...prev,
|
|
208
|
+
isLoading: true,
|
|
209
|
+
error: null,
|
|
210
|
+
}));
|
|
211
|
+
try {
|
|
212
|
+
const pluginId = `${name}@${marketplace}`;
|
|
213
|
+
const workdir = process.cwd();
|
|
214
|
+
await marketplaceService.installPlugin(pluginId, workdir);
|
|
215
|
+
await pluginScopeManager.enablePlugin(scope, pluginId);
|
|
216
|
+
await refresh();
|
|
217
|
+
} catch (error) {
|
|
218
|
+
setState((prev: PluginManagerState) => ({
|
|
219
|
+
...prev,
|
|
220
|
+
isLoading: false,
|
|
221
|
+
error: error instanceof Error ? error.message : String(error),
|
|
222
|
+
}));
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
[marketplaceService, pluginScopeManager, refresh],
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
const uninstallPlugin = useCallback(
|
|
229
|
+
async (name: string, marketplace: string) => {
|
|
230
|
+
setState((prev: PluginManagerState) => ({
|
|
231
|
+
...prev,
|
|
232
|
+
isLoading: true,
|
|
233
|
+
error: null,
|
|
234
|
+
}));
|
|
235
|
+
try {
|
|
236
|
+
const pluginId = `${name}@${marketplace}`;
|
|
237
|
+
const workdir = process.cwd();
|
|
238
|
+
|
|
239
|
+
// 1. Remove from global registry and potentially clean up cache
|
|
240
|
+
await marketplaceService.uninstallPlugin(pluginId, workdir);
|
|
241
|
+
|
|
242
|
+
// 2. Find the scope where it's currently enabled and remove it from there
|
|
243
|
+
const scope = pluginScopeManager.findPluginScope(pluginId);
|
|
244
|
+
if (scope) {
|
|
245
|
+
await configurationService.removeEnabledPlugin(
|
|
246
|
+
workdir,
|
|
247
|
+
scope,
|
|
248
|
+
pluginId,
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
await refresh();
|
|
252
|
+
} catch (error) {
|
|
253
|
+
setState((prev: PluginManagerState) => ({
|
|
254
|
+
...prev,
|
|
255
|
+
isLoading: false,
|
|
256
|
+
error: error instanceof Error ? error.message : String(error),
|
|
257
|
+
}));
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
[configurationService, marketplaceService, pluginScopeManager, refresh],
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
const updatePlugin = useCallback(
|
|
264
|
+
async (name: string, marketplace: string) => {
|
|
265
|
+
setState((prev: PluginManagerState) => ({
|
|
266
|
+
...prev,
|
|
267
|
+
isLoading: true,
|
|
268
|
+
error: null,
|
|
269
|
+
}));
|
|
270
|
+
try {
|
|
271
|
+
const pluginId = `${name}@${marketplace}`;
|
|
272
|
+
await marketplaceService.updatePlugin(pluginId);
|
|
273
|
+
await refresh();
|
|
274
|
+
} catch (error) {
|
|
275
|
+
setState((prev: PluginManagerState) => ({
|
|
276
|
+
...prev,
|
|
277
|
+
isLoading: false,
|
|
278
|
+
error: error instanceof Error ? error.message : String(error),
|
|
279
|
+
}));
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
[marketplaceService, refresh],
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
return {
|
|
286
|
+
state,
|
|
287
|
+
marketplaces,
|
|
288
|
+
installedPlugins,
|
|
289
|
+
discoverablePlugins,
|
|
290
|
+
actions: {
|
|
291
|
+
setView,
|
|
292
|
+
setSelectedId,
|
|
293
|
+
addMarketplace,
|
|
294
|
+
removeMarketplace,
|
|
295
|
+
updateMarketplace,
|
|
296
|
+
installPlugin,
|
|
297
|
+
uninstallPlugin,
|
|
298
|
+
updatePlugin,
|
|
299
|
+
refresh,
|
|
300
|
+
},
|
|
301
|
+
};
|
|
302
|
+
}
|