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
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { FileItem } from "../components/FileSelector.js";
|
|
2
2
|
import {
|
|
3
3
|
searchFiles as searchFilesUtil,
|
|
4
|
-
deleteBashCommandFromHistory,
|
|
5
4
|
PermissionMode,
|
|
6
5
|
Logger,
|
|
6
|
+
PromptHistoryManager,
|
|
7
7
|
} from "wave-agent-sdk";
|
|
8
8
|
import { readClipboardImage } from "../utils/clipboard.js";
|
|
9
9
|
import type { Key } from "ink";
|
|
@@ -28,16 +28,14 @@ export interface InputManagerCallbacks {
|
|
|
28
28
|
query: string,
|
|
29
29
|
position: number,
|
|
30
30
|
) => void;
|
|
31
|
-
|
|
32
|
-
show: boolean,
|
|
33
|
-
query: string,
|
|
34
|
-
position: number,
|
|
35
|
-
) => void;
|
|
31
|
+
onHistorySearchStateChange?: (show: boolean, query: string) => void;
|
|
36
32
|
onMemoryTypeSelectorStateChange?: (show: boolean, message: string) => void;
|
|
37
|
-
|
|
33
|
+
onShowTaskManager?: () => void;
|
|
34
|
+
onTaskManagerStateChange?: (show: boolean) => void;
|
|
38
35
|
onShowMcpManager?: () => void;
|
|
39
|
-
onBashManagerStateChange?: (show: boolean) => void;
|
|
40
36
|
onMcpManagerStateChange?: (show: boolean) => void;
|
|
37
|
+
onShowRewindManager?: () => void;
|
|
38
|
+
onRewindManagerStateChange?: (show: boolean) => void;
|
|
41
39
|
onImagesStateChange?: (images: AttachedImage[]) => void;
|
|
42
40
|
onSendMessage?: (
|
|
43
41
|
content: string,
|
|
@@ -46,6 +44,7 @@ export interface InputManagerCallbacks {
|
|
|
46
44
|
onHasSlashCommand?: (commandId: string) => boolean;
|
|
47
45
|
onSaveMemory?: (message: string, type: "project" | "user") => Promise<void>;
|
|
48
46
|
onAbortMessage?: () => void;
|
|
47
|
+
onBackgroundCurrentTask?: () => void;
|
|
49
48
|
onResetHistoryNavigation?: () => void;
|
|
50
49
|
onPermissionModeChange?: (mode: PermissionMode) => void;
|
|
51
50
|
logger?: Logger;
|
|
@@ -68,10 +67,9 @@ export class InputManager {
|
|
|
68
67
|
private slashPosition: number = -1;
|
|
69
68
|
private commandSearchQuery: string = "";
|
|
70
69
|
|
|
71
|
-
//
|
|
72
|
-
private
|
|
73
|
-
private
|
|
74
|
-
private bashHistorySearchQuery: string = "";
|
|
70
|
+
// History search state
|
|
71
|
+
private showHistorySearch: boolean = false;
|
|
72
|
+
private historySearchQuery: string = "";
|
|
75
73
|
|
|
76
74
|
// Memory type selector state
|
|
77
75
|
private showMemoryTypeSelector: boolean = false;
|
|
@@ -97,8 +95,9 @@ export class InputManager {
|
|
|
97
95
|
private imageIdCounter: number = 1;
|
|
98
96
|
|
|
99
97
|
// Additional UI state
|
|
100
|
-
private
|
|
98
|
+
private showTaskManager: boolean = false;
|
|
101
99
|
private showMcpManager: boolean = false;
|
|
100
|
+
private showRewindManager: boolean = false;
|
|
102
101
|
|
|
103
102
|
// Permission mode state
|
|
104
103
|
private permissionMode: PermissionMode = "default";
|
|
@@ -363,12 +362,18 @@ export class InputManager {
|
|
|
363
362
|
|
|
364
363
|
// If not an agent command or execution failed, check local commands
|
|
365
364
|
if (!commandExecuted) {
|
|
366
|
-
if (command === "
|
|
367
|
-
this.callbacks.
|
|
365
|
+
if (command === "tasks" && this.callbacks.onShowTaskManager) {
|
|
366
|
+
this.callbacks.onShowTaskManager();
|
|
368
367
|
commandExecuted = true;
|
|
369
368
|
} else if (command === "mcp" && this.callbacks.onShowMcpManager) {
|
|
370
369
|
this.callbacks.onShowMcpManager();
|
|
371
370
|
commandExecuted = true;
|
|
371
|
+
} else if (
|
|
372
|
+
command === "rewind" &&
|
|
373
|
+
this.callbacks.onShowRewindManager
|
|
374
|
+
) {
|
|
375
|
+
this.callbacks.onShowRewindManager();
|
|
376
|
+
commandExecuted = true;
|
|
372
377
|
}
|
|
373
378
|
}
|
|
374
379
|
})();
|
|
@@ -434,105 +439,6 @@ export class InputManager {
|
|
|
434
439
|
return false;
|
|
435
440
|
}
|
|
436
441
|
|
|
437
|
-
// Bash history selector methods
|
|
438
|
-
activateBashHistorySelector(position: number): void {
|
|
439
|
-
this.showBashHistorySelector = true;
|
|
440
|
-
this.exclamationPosition = position;
|
|
441
|
-
this.bashHistorySearchQuery = "";
|
|
442
|
-
|
|
443
|
-
this.callbacks.onBashHistorySelectorStateChange?.(true, "", position);
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
updateBashHistorySearchQuery(query: string): void {
|
|
447
|
-
this.bashHistorySearchQuery = query;
|
|
448
|
-
this.callbacks.onBashHistorySelectorStateChange?.(
|
|
449
|
-
this.showBashHistorySelector,
|
|
450
|
-
query,
|
|
451
|
-
this.exclamationPosition,
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
handleBashHistorySelect(command: string): {
|
|
456
|
-
newInput: string;
|
|
457
|
-
newCursorPosition: number;
|
|
458
|
-
} {
|
|
459
|
-
if (this.exclamationPosition >= 0) {
|
|
460
|
-
const beforeExclamation = this.inputText.substring(
|
|
461
|
-
0,
|
|
462
|
-
this.exclamationPosition,
|
|
463
|
-
);
|
|
464
|
-
const afterQuery = this.inputText.substring(this.cursorPosition);
|
|
465
|
-
const newInput = beforeExclamation + `!${command}` + afterQuery;
|
|
466
|
-
const newCursorPosition = beforeExclamation.length + command.length + 1;
|
|
467
|
-
|
|
468
|
-
this.inputText = newInput;
|
|
469
|
-
this.cursorPosition = newCursorPosition;
|
|
470
|
-
|
|
471
|
-
this.handleCancelBashHistorySelect();
|
|
472
|
-
|
|
473
|
-
// Set flag to prevent handleInput from processing the same Enter key
|
|
474
|
-
this.selectorJustUsed = true;
|
|
475
|
-
setTimeout(() => {
|
|
476
|
-
this.selectorJustUsed = false;
|
|
477
|
-
}, 0);
|
|
478
|
-
|
|
479
|
-
this.callbacks.onInputTextChange?.(newInput);
|
|
480
|
-
this.callbacks.onCursorPositionChange?.(newCursorPosition);
|
|
481
|
-
|
|
482
|
-
return { newInput, newCursorPosition };
|
|
483
|
-
}
|
|
484
|
-
return { newInput: this.inputText, newCursorPosition: this.cursorPosition };
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
handleCancelBashHistorySelect(): void {
|
|
488
|
-
this.showBashHistorySelector = false;
|
|
489
|
-
this.exclamationPosition = -1;
|
|
490
|
-
this.bashHistorySearchQuery = "";
|
|
491
|
-
|
|
492
|
-
this.callbacks.onBashHistorySelectorStateChange?.(false, "", -1);
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
handleBashHistoryExecute(command: string): string {
|
|
496
|
-
this.showBashHistorySelector = false;
|
|
497
|
-
this.exclamationPosition = -1;
|
|
498
|
-
this.bashHistorySearchQuery = "";
|
|
499
|
-
|
|
500
|
-
this.callbacks.onBashHistorySelectorStateChange?.(false, "", -1);
|
|
501
|
-
|
|
502
|
-
return command; // Return command to execute
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
handleBashHistoryExecuteAndSend(command: string): void {
|
|
506
|
-
const commandToExecute = this.handleBashHistoryExecute(command);
|
|
507
|
-
// Clear input box and execute command, ensure command starts with !
|
|
508
|
-
const bashCommand = commandToExecute.startsWith("!")
|
|
509
|
-
? commandToExecute
|
|
510
|
-
: `!${commandToExecute}`;
|
|
511
|
-
this.clearInput();
|
|
512
|
-
this.callbacks.onSendMessage?.(bashCommand);
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
handleBashHistoryDelete(command: string, workdir?: string): void {
|
|
516
|
-
deleteBashCommandFromHistory(command, workdir);
|
|
517
|
-
// Trigger a refresh of the selector state to force re-render of BashHistorySelector
|
|
518
|
-
this.callbacks.onBashHistorySelectorStateChange?.(
|
|
519
|
-
this.showBashHistorySelector,
|
|
520
|
-
this.bashHistorySearchQuery,
|
|
521
|
-
this.exclamationPosition,
|
|
522
|
-
);
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
checkForExclamationDeletion(cursorPosition: number): boolean {
|
|
526
|
-
if (
|
|
527
|
-
this.showBashHistorySelector &&
|
|
528
|
-
cursorPosition <= this.exclamationPosition
|
|
529
|
-
) {
|
|
530
|
-
this.handleCancelBashHistorySelect();
|
|
531
|
-
return true;
|
|
532
|
-
}
|
|
533
|
-
return false;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
442
|
// Memory type selector methods
|
|
537
443
|
activateMemoryTypeSelector(message: string): void {
|
|
538
444
|
this.showMemoryTypeSelector = true;
|
|
@@ -631,10 +537,6 @@ export class InputManager {
|
|
|
631
537
|
return this.showCommandSelector;
|
|
632
538
|
}
|
|
633
539
|
|
|
634
|
-
isBashHistorySelectorActive(): boolean {
|
|
635
|
-
return this.showBashHistorySelector;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
540
|
isMemoryTypeSelectorActive(): boolean {
|
|
639
541
|
return this.showMemoryTypeSelector;
|
|
640
542
|
}
|
|
@@ -656,14 +558,6 @@ export class InputManager {
|
|
|
656
558
|
};
|
|
657
559
|
}
|
|
658
560
|
|
|
659
|
-
getBashHistorySelectorState() {
|
|
660
|
-
return {
|
|
661
|
-
show: this.showBashHistorySelector,
|
|
662
|
-
query: this.bashHistorySearchQuery,
|
|
663
|
-
position: this.exclamationPosition,
|
|
664
|
-
};
|
|
665
|
-
}
|
|
666
|
-
|
|
667
561
|
getMemoryTypeSelectorState() {
|
|
668
562
|
return {
|
|
669
563
|
show: this.showMemoryTypeSelector,
|
|
@@ -686,11 +580,6 @@ export class InputManager {
|
|
|
686
580
|
const queryEnd = cursorPosition;
|
|
687
581
|
const newQuery = inputText.substring(queryStart, queryEnd);
|
|
688
582
|
this.updateCommandSearchQuery(newQuery);
|
|
689
|
-
} else if (this.showBashHistorySelector && this.exclamationPosition >= 0) {
|
|
690
|
-
const queryStart = this.exclamationPosition + 1;
|
|
691
|
-
const queryEnd = cursorPosition;
|
|
692
|
-
const newQuery = inputText.substring(queryStart, queryEnd);
|
|
693
|
-
this.updateBashHistorySearchQuery(newQuery);
|
|
694
583
|
}
|
|
695
584
|
}
|
|
696
585
|
|
|
@@ -698,11 +587,14 @@ export class InputManager {
|
|
|
698
587
|
handleSpecialCharInput(char: string): void {
|
|
699
588
|
if (char === "@") {
|
|
700
589
|
this.activateFileSelector(this.cursorPosition - 1);
|
|
701
|
-
} else if (
|
|
590
|
+
} else if (
|
|
591
|
+
char === "/" &&
|
|
592
|
+
!this.showFileSelector &&
|
|
593
|
+
this.cursorPosition === 1
|
|
594
|
+
) {
|
|
702
595
|
// Don't activate command selector when file selector is active
|
|
596
|
+
// Only activate command selector if '/' is at the start of input
|
|
703
597
|
this.activateCommandSelector(this.cursorPosition - 1);
|
|
704
|
-
} else if (char === "!" && this.cursorPosition === 1) {
|
|
705
|
-
this.activateBashHistorySelector(0);
|
|
706
598
|
} else if (char === "#" && this.cursorPosition === 1) {
|
|
707
599
|
// Memory message detection will be handled in submit
|
|
708
600
|
} else {
|
|
@@ -860,14 +752,14 @@ export class InputManager {
|
|
|
860
752
|
}
|
|
861
753
|
}
|
|
862
754
|
|
|
863
|
-
//
|
|
864
|
-
|
|
865
|
-
return this.
|
|
755
|
+
// Task manager state methods
|
|
756
|
+
getShowTaskManager(): boolean {
|
|
757
|
+
return this.showTaskManager;
|
|
866
758
|
}
|
|
867
759
|
|
|
868
|
-
|
|
869
|
-
this.
|
|
870
|
-
this.callbacks.
|
|
760
|
+
setShowTaskManager(show: boolean): void {
|
|
761
|
+
this.showTaskManager = show;
|
|
762
|
+
this.callbacks.onTaskManagerStateChange?.(show);
|
|
871
763
|
}
|
|
872
764
|
|
|
873
765
|
getShowMcpManager(): boolean {
|
|
@@ -879,6 +771,15 @@ export class InputManager {
|
|
|
879
771
|
this.callbacks.onMcpManagerStateChange?.(show);
|
|
880
772
|
}
|
|
881
773
|
|
|
774
|
+
getShowRewindManager(): boolean {
|
|
775
|
+
return this.showRewindManager;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
setShowRewindManager(show: boolean): void {
|
|
779
|
+
this.showRewindManager = show;
|
|
780
|
+
this.callbacks.onRewindManagerStateChange?.(show);
|
|
781
|
+
}
|
|
782
|
+
|
|
882
783
|
// Permission mode methods
|
|
883
784
|
getPermissionMode(): PermissionMode {
|
|
884
785
|
return this.permissionMode;
|
|
@@ -941,6 +842,11 @@ export class InputManager {
|
|
|
941
842
|
let cleanContent = this.inputText.replace(imageRegex, "").trim();
|
|
942
843
|
cleanContent = this.expandLongTextPlaceholders(cleanContent);
|
|
943
844
|
|
|
845
|
+
// Save to prompt history
|
|
846
|
+
PromptHistoryManager.addEntry(cleanContent).catch((err: unknown) => {
|
|
847
|
+
this.logger?.error("Failed to save prompt history", err);
|
|
848
|
+
});
|
|
849
|
+
|
|
944
850
|
this.callbacks.onSendMessage?.(
|
|
945
851
|
cleanContent,
|
|
946
852
|
referencedImages.length > 0 ? referencedImages : undefined,
|
|
@@ -961,7 +867,6 @@ export class InputManager {
|
|
|
961
867
|
// Check for special character deletion
|
|
962
868
|
this.checkForAtDeletion(newCursorPosition);
|
|
963
869
|
this.checkForSlashDeletion(newCursorPosition);
|
|
964
|
-
this.checkForExclamationDeletion(newCursorPosition);
|
|
965
870
|
|
|
966
871
|
// Update search queries using the same logic as character input
|
|
967
872
|
this.updateSearchQueriesForActiveSelectors(
|
|
@@ -1004,6 +909,32 @@ export class InputManager {
|
|
|
1004
909
|
return false;
|
|
1005
910
|
}
|
|
1006
911
|
|
|
912
|
+
// History search methods
|
|
913
|
+
activateHistorySearch(): void {
|
|
914
|
+
this.showHistorySearch = true;
|
|
915
|
+
this.historySearchQuery = "";
|
|
916
|
+
this.callbacks.onHistorySearchStateChange?.(true, "");
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
updateHistorySearchQuery(query: string): void {
|
|
920
|
+
this.historySearchQuery = query;
|
|
921
|
+
this.callbacks.onHistorySearchStateChange?.(true, query);
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
handleHistorySearchSelect(prompt: string): void {
|
|
925
|
+
this.inputText = prompt;
|
|
926
|
+
this.cursorPosition = prompt.length;
|
|
927
|
+
this.callbacks.onInputTextChange?.(prompt);
|
|
928
|
+
this.callbacks.onCursorPositionChange?.(prompt.length);
|
|
929
|
+
this.handleCancelHistorySearch();
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
handleCancelHistorySearch(): void {
|
|
933
|
+
this.showHistorySearch = false;
|
|
934
|
+
this.historySearchQuery = "";
|
|
935
|
+
this.callbacks.onHistorySearchStateChange?.(false, "");
|
|
936
|
+
}
|
|
937
|
+
|
|
1007
938
|
// Handle normal input (when no selector is active)
|
|
1008
939
|
async handleNormalInput(
|
|
1009
940
|
input: string,
|
|
@@ -1024,8 +955,6 @@ export class InputManager {
|
|
|
1024
955
|
this.handleCancelFileSelect();
|
|
1025
956
|
} else if (this.showCommandSelector) {
|
|
1026
957
|
this.handleCancelCommandSelect();
|
|
1027
|
-
} else if (this.showBashHistorySelector) {
|
|
1028
|
-
this.handleCancelBashHistorySelect();
|
|
1029
958
|
}
|
|
1030
959
|
return true;
|
|
1031
960
|
}
|
|
@@ -1039,7 +968,6 @@ export class InputManager {
|
|
|
1039
968
|
const newCursorPosition = this.cursorPosition - 1;
|
|
1040
969
|
this.checkForAtDeletion(newCursorPosition);
|
|
1041
970
|
this.checkForSlashDeletion(newCursorPosition);
|
|
1042
|
-
this.checkForExclamationDeletion(newCursorPosition);
|
|
1043
971
|
}
|
|
1044
972
|
return true;
|
|
1045
973
|
}
|
|
@@ -1072,23 +1000,25 @@ export class InputManager {
|
|
|
1072
1000
|
return true;
|
|
1073
1001
|
}
|
|
1074
1002
|
|
|
1003
|
+
// Handle Ctrl+R for history search
|
|
1004
|
+
if (key.ctrl && input === "r") {
|
|
1005
|
+
this.activateHistorySearch();
|
|
1006
|
+
return true;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
// Handle Ctrl+B for backgrounding current task
|
|
1010
|
+
if (key.ctrl && input === "b") {
|
|
1011
|
+
this.callbacks.onBackgroundCurrentTask?.();
|
|
1012
|
+
return true;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1075
1015
|
// Handle up/down keys for history navigation (only when no selector is active)
|
|
1076
|
-
if (
|
|
1077
|
-
key.upArrow &&
|
|
1078
|
-
!this.showFileSelector &&
|
|
1079
|
-
!this.showCommandSelector &&
|
|
1080
|
-
!this.showBashHistorySelector
|
|
1081
|
-
) {
|
|
1016
|
+
if (key.upArrow && !this.showFileSelector && !this.showCommandSelector) {
|
|
1082
1017
|
this.navigateHistory("up", this.inputText);
|
|
1083
1018
|
return true;
|
|
1084
1019
|
}
|
|
1085
1020
|
|
|
1086
|
-
if (
|
|
1087
|
-
key.downArrow &&
|
|
1088
|
-
!this.showFileSelector &&
|
|
1089
|
-
!this.showCommandSelector &&
|
|
1090
|
-
!this.showBashHistorySelector
|
|
1091
|
-
) {
|
|
1021
|
+
if (key.downArrow && !this.showFileSelector && !this.showCommandSelector) {
|
|
1092
1022
|
this.navigateHistory("down", this.inputText);
|
|
1093
1023
|
return true;
|
|
1094
1024
|
}
|
|
@@ -1147,19 +1077,40 @@ export class InputManager {
|
|
|
1147
1077
|
if (
|
|
1148
1078
|
this.showFileSelector ||
|
|
1149
1079
|
this.showCommandSelector ||
|
|
1150
|
-
this.
|
|
1080
|
+
this.showHistorySearch ||
|
|
1151
1081
|
this.showMemoryTypeSelector ||
|
|
1152
|
-
this.
|
|
1153
|
-
this.showMcpManager
|
|
1082
|
+
this.showTaskManager ||
|
|
1083
|
+
this.showMcpManager ||
|
|
1084
|
+
this.showRewindManager
|
|
1154
1085
|
) {
|
|
1155
1086
|
if (
|
|
1156
1087
|
this.showMemoryTypeSelector ||
|
|
1157
|
-
this.
|
|
1158
|
-
this.showMcpManager
|
|
1088
|
+
this.showTaskManager ||
|
|
1089
|
+
this.showMcpManager ||
|
|
1090
|
+
this.showRewindManager
|
|
1159
1091
|
) {
|
|
1160
|
-
// Memory type selector,
|
|
1092
|
+
// Memory type selector, task manager, MCP manager and Rewind don't need to handle input, handled by component itself
|
|
1161
1093
|
return false;
|
|
1162
1094
|
}
|
|
1095
|
+
|
|
1096
|
+
if (this.showHistorySearch) {
|
|
1097
|
+
if (key.escape) {
|
|
1098
|
+
this.handleCancelHistorySearch();
|
|
1099
|
+
return true;
|
|
1100
|
+
}
|
|
1101
|
+
if (key.backspace || key.delete) {
|
|
1102
|
+
if (this.historySearchQuery.length > 0) {
|
|
1103
|
+
this.updateHistorySearchQuery(this.historySearchQuery.slice(0, -1));
|
|
1104
|
+
}
|
|
1105
|
+
return true;
|
|
1106
|
+
}
|
|
1107
|
+
if (input && !key.ctrl && !key.meta && !key.return && !key.tab) {
|
|
1108
|
+
this.updateHistorySearchQuery(this.historySearchQuery + input);
|
|
1109
|
+
return true;
|
|
1110
|
+
}
|
|
1111
|
+
return true; // Let HistorySearch component handle arrows and Enter
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1163
1114
|
return this.handleSelectorInput(input, key);
|
|
1164
1115
|
} else {
|
|
1165
1116
|
return await this.handleNormalInput(
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "ink";
|
|
3
|
+
import { PluginManagerShell } from "./components/PluginManagerShell.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Entry point for the Plugin Manager CLI.
|
|
7
|
+
* Renders the Ink component and handles the lifecycle.
|
|
8
|
+
*/
|
|
9
|
+
export async function startPluginManagerCli(): Promise<boolean> {
|
|
10
|
+
const { waitUntilExit } = render(<PluginManagerShell />);
|
|
11
|
+
await waitUntilExit();
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, Box } from "ink";
|
|
3
|
+
import { listSessions, truncateContent } from "wave-agent-sdk";
|
|
4
|
+
import { SessionSelector } from "./components/SessionSelector.js";
|
|
5
|
+
|
|
6
|
+
export async function startSessionSelectorCli(): Promise<string | null> {
|
|
7
|
+
const currentWorkdir = process.cwd();
|
|
8
|
+
const sessions = await listSessions(currentWorkdir);
|
|
9
|
+
|
|
10
|
+
if (sessions.length === 0) {
|
|
11
|
+
console.log(`No sessions found for workdir: ${currentWorkdir}`);
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const sessionsWithContent = sessions.map((s) => ({
|
|
16
|
+
...s,
|
|
17
|
+
firstMessage: truncateContent(s.firstMessage || "No content", 80),
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
const { unmount } = render(
|
|
22
|
+
<Box padding={1}>
|
|
23
|
+
<SessionSelector
|
|
24
|
+
sessions={sessionsWithContent}
|
|
25
|
+
onSelect={(sessionId) => {
|
|
26
|
+
unmount();
|
|
27
|
+
resolve(sessionId);
|
|
28
|
+
}}
|
|
29
|
+
onCancel={() => {
|
|
30
|
+
unmount();
|
|
31
|
+
resolve(null);
|
|
32
|
+
}}
|
|
33
|
+
/>
|
|
34
|
+
</Box>,
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
export interface BashHistorySelectorProps {
|
|
3
|
-
searchQuery: string;
|
|
4
|
-
workdir: string;
|
|
5
|
-
onSelect: (command: string) => void;
|
|
6
|
-
onExecute: (command: string) => void;
|
|
7
|
-
onDelete: (command: string, workdir?: string) => void;
|
|
8
|
-
onCancel: () => void;
|
|
9
|
-
}
|
|
10
|
-
export declare const BashHistorySelector: React.FC<BashHistorySelectorProps>;
|
|
11
|
-
//# sourceMappingURL=BashHistorySelector.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BashHistorySelector.d.ts","sourceRoot":"","sources":["../../src/components/BashHistorySelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAKnD,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACtD,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAsKlE,CAAC"}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useEffect } from "react";
|
|
3
|
-
import { Box, Text, useInput } from "ink";
|
|
4
|
-
import { searchBashHistory } from "wave-agent-sdk";
|
|
5
|
-
import { logger } from "../utils/logger.js";
|
|
6
|
-
export const BashHistorySelector = ({ searchQuery, workdir, onSelect, onExecute, onDelete, onCancel, }) => {
|
|
7
|
-
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
8
|
-
const [commands, setCommands] = useState([]);
|
|
9
|
-
const [refreshCounter, setRefreshCounter] = useState(0);
|
|
10
|
-
// Search bash history
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
const results = searchBashHistory(searchQuery, 10);
|
|
13
|
-
setCommands(results);
|
|
14
|
-
setSelectedIndex(0);
|
|
15
|
-
logger.debug("Bash history search:", {
|
|
16
|
-
searchQuery,
|
|
17
|
-
workdir,
|
|
18
|
-
resultCount: results.length,
|
|
19
|
-
refreshCounter,
|
|
20
|
-
});
|
|
21
|
-
}, [searchQuery, workdir, refreshCounter]);
|
|
22
|
-
useInput((input, key) => {
|
|
23
|
-
logger.debug("BashHistorySelector useInput:", {
|
|
24
|
-
input,
|
|
25
|
-
key,
|
|
26
|
-
commandsLength: commands.length,
|
|
27
|
-
selectedIndex,
|
|
28
|
-
});
|
|
29
|
-
if (key.return) {
|
|
30
|
-
if (commands.length > 0 && selectedIndex < commands.length) {
|
|
31
|
-
const selectedCommand = commands[selectedIndex];
|
|
32
|
-
onExecute(selectedCommand.command);
|
|
33
|
-
}
|
|
34
|
-
else if (commands.length === 0 && searchQuery.trim()) {
|
|
35
|
-
// When no history records match, execute the search query as a new command
|
|
36
|
-
onExecute(searchQuery.trim());
|
|
37
|
-
}
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
if (key.tab) {
|
|
41
|
-
if (commands.length > 0 && selectedIndex < commands.length) {
|
|
42
|
-
const selectedCommand = commands[selectedIndex];
|
|
43
|
-
onSelect(selectedCommand.command);
|
|
44
|
-
}
|
|
45
|
-
else if (commands.length === 0 && searchQuery.trim()) {
|
|
46
|
-
// When no history records match, insert the search query
|
|
47
|
-
onSelect(searchQuery.trim());
|
|
48
|
-
}
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
if (key.escape) {
|
|
52
|
-
onCancel();
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
if (key.ctrl && input === "d") {
|
|
56
|
-
if (commands.length > 0 && selectedIndex < commands.length) {
|
|
57
|
-
const selectedCommand = commands[selectedIndex];
|
|
58
|
-
onDelete(selectedCommand.command, selectedCommand.workdir);
|
|
59
|
-
setRefreshCounter((prev) => prev + 1);
|
|
60
|
-
}
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
if (key.upArrow) {
|
|
64
|
-
setSelectedIndex(Math.max(0, selectedIndex - 1));
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
if (key.downArrow) {
|
|
68
|
-
setSelectedIndex(Math.min(commands.length - 1, selectedIndex + 1));
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
if (commands.length === 0) {
|
|
73
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, children: [_jsxs(Text, { color: "yellow", children: ["No bash history found ", searchQuery && `for "${searchQuery}"`] }), searchQuery.trim() && (_jsxs(Text, { color: "green", children: ["Press Enter to execute: ", searchQuery] })), searchQuery.trim() && (_jsxs(Text, { color: "blue", children: ["Press Tab to insert: ", searchQuery] })), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
|
|
74
|
-
}
|
|
75
|
-
const formatTimestamp = (timestamp) => {
|
|
76
|
-
const date = new Date(timestamp);
|
|
77
|
-
const now = new Date();
|
|
78
|
-
const diffMs = now.getTime() - date.getTime();
|
|
79
|
-
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
|
80
|
-
const diffDays = Math.floor(diffHours / 24);
|
|
81
|
-
if (diffDays > 0) {
|
|
82
|
-
return `${diffDays}d ago`;
|
|
83
|
-
}
|
|
84
|
-
else if (diffHours > 0) {
|
|
85
|
-
return `${diffHours}h ago`;
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
const diffMinutes = Math.floor(diffMs / (1000 * 60));
|
|
89
|
-
return diffMinutes > 0 ? `${diffMinutes}m ago` : "just now";
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "blue", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "blue", bold: true, children: ["Bash History ", searchQuery && `(filtering: "${searchQuery}")`] }) }), commands.map((cmd, index) => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: index === selectedIndex ? "black" : "white", backgroundColor: index === selectedIndex ? "blue" : undefined, children: cmd.command }), index === selectedIndex && (_jsx(Box, { marginLeft: 4, flexDirection: "column", children: _jsxs(Text, { color: "gray", dimColor: true, children: [formatTimestamp(cmd.timestamp), cmd.workdir !== workdir && ` • in ${cmd.workdir}`] }) }))] }, index))), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate, Enter to execute, Tab to insert, Ctrl+d to remove, Escape to cancel" }) })] }));
|
|
93
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BashShellManager.d.ts","sourceRoot":"","sources":["../../src/components/BashShellManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAanD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAwS5D,CAAC"}
|