wave-code 0.2.0 → 0.4.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.
Files changed (140) hide show
  1. package/dist/commands/plugin/disable.d.ts +2 -1
  2. package/dist/commands/plugin/disable.d.ts.map +1 -1
  3. package/dist/commands/plugin/disable.js +3 -2
  4. package/dist/commands/plugin/enable.d.ts +2 -1
  5. package/dist/commands/plugin/enable.d.ts.map +1 -1
  6. package/dist/commands/plugin/enable.js +3 -2
  7. package/dist/commands/plugin/install.d.ts +2 -1
  8. package/dist/commands/plugin/install.d.ts.map +1 -1
  9. package/dist/commands/plugin/list.d.ts.map +1 -1
  10. package/dist/commands/plugin/list.js +15 -3
  11. package/dist/commands/plugin/marketplace.d.ts +3 -0
  12. package/dist/commands/plugin/marketplace.d.ts.map +1 -1
  13. package/dist/commands/plugin/marketplace.js +15 -1
  14. package/dist/commands/plugin/uninstall.d.ts +4 -0
  15. package/dist/commands/plugin/uninstall.d.ts.map +1 -0
  16. package/dist/commands/plugin/uninstall.js +29 -0
  17. package/dist/commands/plugin/update.d.ts +4 -0
  18. package/dist/commands/plugin/update.d.ts.map +1 -0
  19. package/dist/commands/plugin/update.js +15 -0
  20. package/dist/components/ChatInterface.d.ts.map +1 -1
  21. package/dist/components/ChatInterface.js +2 -2
  22. package/dist/components/CommandSelector.d.ts.map +1 -1
  23. package/dist/components/CommandSelector.js +6 -0
  24. package/dist/components/Confirmation.js +1 -1
  25. package/dist/components/DiscoverView.d.ts +3 -0
  26. package/dist/components/DiscoverView.d.ts.map +1 -0
  27. package/dist/components/DiscoverView.js +25 -0
  28. package/dist/components/FileSelector.js +1 -1
  29. package/dist/components/HistorySearch.d.ts +8 -0
  30. package/dist/components/HistorySearch.d.ts.map +1 -0
  31. package/dist/components/HistorySearch.js +67 -0
  32. package/dist/components/InputBox.d.ts +1 -1
  33. package/dist/components/InputBox.d.ts.map +1 -1
  34. package/dist/components/InputBox.js +26 -17
  35. package/dist/components/InstalledView.d.ts +3 -0
  36. package/dist/components/InstalledView.d.ts.map +1 -0
  37. package/dist/components/InstalledView.js +30 -0
  38. package/dist/components/Markdown.d.ts.map +1 -1
  39. package/dist/components/Markdown.js +22 -9
  40. package/dist/components/MarketplaceAddForm.d.ts +3 -0
  41. package/dist/components/MarketplaceAddForm.d.ts.map +1 -0
  42. package/dist/components/MarketplaceAddForm.js +26 -0
  43. package/dist/components/MarketplaceDetail.d.ts +3 -0
  44. package/dist/components/MarketplaceDetail.d.ts.map +1 -0
  45. package/dist/components/MarketplaceDetail.js +38 -0
  46. package/dist/components/MarketplaceList.d.ts +9 -0
  47. package/dist/components/MarketplaceList.d.ts.map +1 -0
  48. package/dist/components/MarketplaceList.js +16 -0
  49. package/dist/components/MarketplaceView.d.ts +3 -0
  50. package/dist/components/MarketplaceView.d.ts.map +1 -0
  51. package/dist/components/MarketplaceView.js +28 -0
  52. package/dist/components/PluginDetail.d.ts +3 -0
  53. package/dist/components/PluginDetail.d.ts.map +1 -0
  54. package/dist/components/PluginDetail.js +63 -0
  55. package/dist/components/PluginList.d.ts +14 -0
  56. package/dist/components/PluginList.d.ts.map +1 -0
  57. package/dist/components/PluginList.js +12 -0
  58. package/dist/components/PluginManagerShell.d.ts +5 -0
  59. package/dist/components/PluginManagerShell.d.ts.map +1 -0
  60. package/dist/components/PluginManagerShell.js +89 -0
  61. package/dist/components/PluginManagerTypes.d.ts +33 -0
  62. package/dist/components/PluginManagerTypes.d.ts.map +1 -0
  63. package/dist/components/PluginManagerTypes.js +1 -0
  64. package/dist/components/RewindCommand.d.ts +9 -0
  65. package/dist/components/RewindCommand.d.ts.map +1 -0
  66. package/dist/components/RewindCommand.js +42 -0
  67. package/dist/components/SessionSelector.d.ts +11 -0
  68. package/dist/components/SessionSelector.d.ts.map +1 -0
  69. package/dist/components/SessionSelector.js +38 -0
  70. package/dist/components/SubagentBlock.d.ts.map +1 -1
  71. package/dist/components/SubagentBlock.js +20 -1
  72. package/dist/components/ToolResultDisplay.js +1 -1
  73. package/dist/contexts/PluginManagerContext.d.ts +4 -0
  74. package/dist/contexts/PluginManagerContext.d.ts.map +1 -0
  75. package/dist/contexts/PluginManagerContext.js +9 -0
  76. package/dist/contexts/useChat.d.ts +2 -0
  77. package/dist/contexts/useChat.d.ts.map +1 -1
  78. package/dist/contexts/useChat.js +21 -0
  79. package/dist/hooks/useInputManager.d.ts +6 -14
  80. package/dist/hooks/useInputManager.d.ts.map +1 -1
  81. package/dist/hooks/useInputManager.js +29 -45
  82. package/dist/hooks/usePluginManager.d.ts +3 -0
  83. package/dist/hooks/usePluginManager.d.ts.map +1 -0
  84. package/dist/hooks/usePluginManager.js +223 -0
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +150 -177
  87. package/dist/managers/InputManager.d.ts +12 -21
  88. package/dist/managers/InputManager.d.ts.map +1 -1
  89. package/dist/managers/InputManager.js +77 -108
  90. package/dist/plugin-manager-cli.d.ts +6 -0
  91. package/dist/plugin-manager-cli.d.ts.map +1 -0
  92. package/dist/plugin-manager-cli.js +12 -0
  93. package/dist/session-selector-cli.d.ts +2 -0
  94. package/dist/session-selector-cli.d.ts.map +1 -0
  95. package/dist/session-selector-cli.js +25 -0
  96. package/package.json +7 -3
  97. package/src/commands/plugin/disable.ts +7 -3
  98. package/src/commands/plugin/enable.ts +7 -3
  99. package/src/commands/plugin/install.ts +2 -1
  100. package/src/commands/plugin/list.ts +21 -3
  101. package/src/commands/plugin/marketplace.ts +17 -1
  102. package/src/commands/plugin/uninstall.ts +39 -0
  103. package/src/commands/plugin/update.ts +19 -0
  104. package/src/components/ChatInterface.tsx +2 -1
  105. package/src/components/CommandSelector.tsx +7 -0
  106. package/src/components/Confirmation.tsx +1 -1
  107. package/src/components/DiscoverView.tsx +31 -0
  108. package/src/components/FileSelector.tsx +1 -1
  109. package/src/components/HistorySearch.tsx +148 -0
  110. package/src/components/InputBox.tsx +43 -28
  111. package/src/components/InstalledView.tsx +61 -0
  112. package/src/components/Markdown.tsx +37 -26
  113. package/src/components/MarketplaceAddForm.tsx +39 -0
  114. package/src/components/MarketplaceDetail.tsx +79 -0
  115. package/src/components/MarketplaceList.tsx +52 -0
  116. package/src/components/MarketplaceView.tsx +43 -0
  117. package/src/components/PluginDetail.tsx +147 -0
  118. package/src/components/PluginList.tsx +51 -0
  119. package/src/components/PluginManagerShell.tsx +189 -0
  120. package/src/components/PluginManagerTypes.ts +47 -0
  121. package/src/components/RewindCommand.tsx +114 -0
  122. package/src/components/SessionSelector.tsx +127 -0
  123. package/src/components/SubagentBlock.tsx +29 -1
  124. package/src/components/ToolResultDisplay.tsx +2 -2
  125. package/src/contexts/PluginManagerContext.ts +15 -0
  126. package/src/contexts/useChat.tsx +26 -0
  127. package/src/hooks/useInputManager.ts +29 -61
  128. package/src/hooks/usePluginManager.ts +296 -0
  129. package/src/index.ts +241 -280
  130. package/src/managers/InputManager.ts +93 -149
  131. package/src/plugin-manager-cli.tsx +13 -0
  132. package/src/session-selector-cli.tsx +37 -0
  133. package/dist/components/BashHistorySelector.d.ts +0 -11
  134. package/dist/components/BashHistorySelector.d.ts.map +0 -1
  135. package/dist/components/BashHistorySelector.js +0 -93
  136. package/dist/hooks/usePagination.d.ts +0 -20
  137. package/dist/hooks/usePagination.d.ts.map +0 -1
  138. package/dist/hooks/usePagination.js +0 -168
  139. package/src/components/BashHistorySelector.tsx +0 -181
  140. 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
- onBashHistorySelectorStateChange?: (
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
  onShowBashManager?: () => void;
38
34
  onShowMcpManager?: () => void;
35
+ onShowRewindManager?: () => void;
39
36
  onBashManagerStateChange?: (show: boolean) => void;
40
37
  onMcpManagerStateChange?: (show: boolean) => void;
38
+ onRewindManagerStateChange?: (show: boolean) => void;
41
39
  onImagesStateChange?: (images: AttachedImage[]) => void;
42
40
  onSendMessage?: (
43
41
  content: string,
@@ -68,10 +66,9 @@ export class InputManager {
68
66
  private slashPosition: number = -1;
69
67
  private commandSearchQuery: string = "";
70
68
 
71
- // Bash history selector state
72
- private showBashHistorySelector: boolean = false;
73
- private exclamationPosition: number = -1;
74
- private bashHistorySearchQuery: string = "";
69
+ // History search state
70
+ private showHistorySearch: boolean = false;
71
+ private historySearchQuery: string = "";
75
72
 
76
73
  // Memory type selector state
77
74
  private showMemoryTypeSelector: boolean = false;
@@ -99,6 +96,7 @@ export class InputManager {
99
96
  // Additional UI state
100
97
  private showBashManager: boolean = false;
101
98
  private showMcpManager: boolean = false;
99
+ private showRewindManager: boolean = false;
102
100
 
103
101
  // Permission mode state
104
102
  private permissionMode: PermissionMode = "default";
@@ -369,6 +367,12 @@ export class InputManager {
369
367
  } else if (command === "mcp" && this.callbacks.onShowMcpManager) {
370
368
  this.callbacks.onShowMcpManager();
371
369
  commandExecuted = true;
370
+ } else if (
371
+ command === "rewind" &&
372
+ this.callbacks.onShowRewindManager
373
+ ) {
374
+ this.callbacks.onShowRewindManager();
375
+ commandExecuted = true;
372
376
  }
373
377
  }
374
378
  })();
@@ -434,105 +438,6 @@ export class InputManager {
434
438
  return false;
435
439
  }
436
440
 
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
441
  // Memory type selector methods
537
442
  activateMemoryTypeSelector(message: string): void {
538
443
  this.showMemoryTypeSelector = true;
@@ -631,10 +536,6 @@ export class InputManager {
631
536
  return this.showCommandSelector;
632
537
  }
633
538
 
634
- isBashHistorySelectorActive(): boolean {
635
- return this.showBashHistorySelector;
636
- }
637
-
638
539
  isMemoryTypeSelectorActive(): boolean {
639
540
  return this.showMemoryTypeSelector;
640
541
  }
@@ -656,14 +557,6 @@ export class InputManager {
656
557
  };
657
558
  }
658
559
 
659
- getBashHistorySelectorState() {
660
- return {
661
- show: this.showBashHistorySelector,
662
- query: this.bashHistorySearchQuery,
663
- position: this.exclamationPosition,
664
- };
665
- }
666
-
667
560
  getMemoryTypeSelectorState() {
668
561
  return {
669
562
  show: this.showMemoryTypeSelector,
@@ -686,11 +579,6 @@ export class InputManager {
686
579
  const queryEnd = cursorPosition;
687
580
  const newQuery = inputText.substring(queryStart, queryEnd);
688
581
  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
582
  }
695
583
  }
696
584
 
@@ -698,11 +586,14 @@ export class InputManager {
698
586
  handleSpecialCharInput(char: string): void {
699
587
  if (char === "@") {
700
588
  this.activateFileSelector(this.cursorPosition - 1);
701
- } else if (char === "/" && !this.showFileSelector) {
589
+ } else if (
590
+ char === "/" &&
591
+ !this.showFileSelector &&
592
+ this.cursorPosition === 1
593
+ ) {
702
594
  // Don't activate command selector when file selector is active
595
+ // Only activate command selector if '/' is at the start of input
703
596
  this.activateCommandSelector(this.cursorPosition - 1);
704
- } else if (char === "!" && this.cursorPosition === 1) {
705
- this.activateBashHistorySelector(0);
706
597
  } else if (char === "#" && this.cursorPosition === 1) {
707
598
  // Memory message detection will be handled in submit
708
599
  } else {
@@ -879,6 +770,15 @@ export class InputManager {
879
770
  this.callbacks.onMcpManagerStateChange?.(show);
880
771
  }
881
772
 
773
+ getShowRewindManager(): boolean {
774
+ return this.showRewindManager;
775
+ }
776
+
777
+ setShowRewindManager(show: boolean): void {
778
+ this.showRewindManager = show;
779
+ this.callbacks.onRewindManagerStateChange?.(show);
780
+ }
781
+
882
782
  // Permission mode methods
883
783
  getPermissionMode(): PermissionMode {
884
784
  return this.permissionMode;
@@ -941,6 +841,11 @@ export class InputManager {
941
841
  let cleanContent = this.inputText.replace(imageRegex, "").trim();
942
842
  cleanContent = this.expandLongTextPlaceholders(cleanContent);
943
843
 
844
+ // Save to prompt history
845
+ PromptHistoryManager.addEntry(cleanContent).catch((err: unknown) => {
846
+ this.logger?.error("Failed to save prompt history", err);
847
+ });
848
+
944
849
  this.callbacks.onSendMessage?.(
945
850
  cleanContent,
946
851
  referencedImages.length > 0 ? referencedImages : undefined,
@@ -961,7 +866,6 @@ export class InputManager {
961
866
  // Check for special character deletion
962
867
  this.checkForAtDeletion(newCursorPosition);
963
868
  this.checkForSlashDeletion(newCursorPosition);
964
- this.checkForExclamationDeletion(newCursorPosition);
965
869
 
966
870
  // Update search queries using the same logic as character input
967
871
  this.updateSearchQueriesForActiveSelectors(
@@ -1004,6 +908,32 @@ export class InputManager {
1004
908
  return false;
1005
909
  }
1006
910
 
911
+ // History search methods
912
+ activateHistorySearch(): void {
913
+ this.showHistorySearch = true;
914
+ this.historySearchQuery = "";
915
+ this.callbacks.onHistorySearchStateChange?.(true, "");
916
+ }
917
+
918
+ updateHistorySearchQuery(query: string): void {
919
+ this.historySearchQuery = query;
920
+ this.callbacks.onHistorySearchStateChange?.(true, query);
921
+ }
922
+
923
+ handleHistorySearchSelect(prompt: string): void {
924
+ this.inputText = prompt;
925
+ this.cursorPosition = prompt.length;
926
+ this.callbacks.onInputTextChange?.(prompt);
927
+ this.callbacks.onCursorPositionChange?.(prompt.length);
928
+ this.handleCancelHistorySearch();
929
+ }
930
+
931
+ handleCancelHistorySearch(): void {
932
+ this.showHistorySearch = false;
933
+ this.historySearchQuery = "";
934
+ this.callbacks.onHistorySearchStateChange?.(false, "");
935
+ }
936
+
1007
937
  // Handle normal input (when no selector is active)
1008
938
  async handleNormalInput(
1009
939
  input: string,
@@ -1024,8 +954,6 @@ export class InputManager {
1024
954
  this.handleCancelFileSelect();
1025
955
  } else if (this.showCommandSelector) {
1026
956
  this.handleCancelCommandSelect();
1027
- } else if (this.showBashHistorySelector) {
1028
- this.handleCancelBashHistorySelect();
1029
957
  }
1030
958
  return true;
1031
959
  }
@@ -1039,7 +967,6 @@ export class InputManager {
1039
967
  const newCursorPosition = this.cursorPosition - 1;
1040
968
  this.checkForAtDeletion(newCursorPosition);
1041
969
  this.checkForSlashDeletion(newCursorPosition);
1042
- this.checkForExclamationDeletion(newCursorPosition);
1043
970
  }
1044
971
  return true;
1045
972
  }
@@ -1072,23 +999,19 @@ export class InputManager {
1072
999
  return true;
1073
1000
  }
1074
1001
 
1002
+ // Handle Ctrl+R for history search
1003
+ if (key.ctrl && input === "r") {
1004
+ this.activateHistorySearch();
1005
+ return true;
1006
+ }
1007
+
1075
1008
  // 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
- ) {
1009
+ if (key.upArrow && !this.showFileSelector && !this.showCommandSelector) {
1082
1010
  this.navigateHistory("up", this.inputText);
1083
1011
  return true;
1084
1012
  }
1085
1013
 
1086
- if (
1087
- key.downArrow &&
1088
- !this.showFileSelector &&
1089
- !this.showCommandSelector &&
1090
- !this.showBashHistorySelector
1091
- ) {
1014
+ if (key.downArrow && !this.showFileSelector && !this.showCommandSelector) {
1092
1015
  this.navigateHistory("down", this.inputText);
1093
1016
  return true;
1094
1017
  }
@@ -1147,19 +1070,40 @@ export class InputManager {
1147
1070
  if (
1148
1071
  this.showFileSelector ||
1149
1072
  this.showCommandSelector ||
1150
- this.showBashHistorySelector ||
1073
+ this.showHistorySearch ||
1151
1074
  this.showMemoryTypeSelector ||
1152
1075
  this.showBashManager ||
1153
- this.showMcpManager
1076
+ this.showMcpManager ||
1077
+ this.showRewindManager
1154
1078
  ) {
1155
1079
  if (
1156
1080
  this.showMemoryTypeSelector ||
1157
1081
  this.showBashManager ||
1158
- this.showMcpManager
1082
+ this.showMcpManager ||
1083
+ this.showRewindManager
1159
1084
  ) {
1160
- // Memory type selector, bash manager and MCP manager don't need to handle input, handled by component itself
1085
+ // Memory type selector, bash manager, MCP manager and Rewind don't need to handle input, handled by component itself
1161
1086
  return false;
1162
1087
  }
1088
+
1089
+ if (this.showHistorySearch) {
1090
+ if (key.escape) {
1091
+ this.handleCancelHistorySearch();
1092
+ return true;
1093
+ }
1094
+ if (key.backspace || key.delete) {
1095
+ if (this.historySearchQuery.length > 0) {
1096
+ this.updateHistorySearchQuery(this.historySearchQuery.slice(0, -1));
1097
+ }
1098
+ return true;
1099
+ }
1100
+ if (input && !key.ctrl && !key.meta && !key.return && !key.tab) {
1101
+ this.updateHistorySearchQuery(this.historySearchQuery + input);
1102
+ return true;
1103
+ }
1104
+ return true; // Let HistorySearch component handle arrows and Enter
1105
+ }
1106
+
1163
1107
  return this.handleSelectorInput(input, key);
1164
1108
  } else {
1165
1109
  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,20 +0,0 @@
1
- import type { Message } from "wave-agent-sdk";
2
- interface PaginationInfo {
3
- currentPage: number;
4
- totalPages: number;
5
- startIndex: number;
6
- endIndex: number;
7
- messagesPerPage: number;
8
- }
9
- export declare const usePagination: (messages: Message[]) => {
10
- displayInfo: PaginationInfo;
11
- manualPage: number | null;
12
- setManualPage: import("react").Dispatch<import("react").SetStateAction<number | null>>;
13
- goToPage: (page: number | null) => void;
14
- goToPrevPage: () => void;
15
- goToNextPage: () => void;
16
- goToFirstPage: () => void;
17
- goToLastPage: () => void;
18
- };
19
- export {};
20
- //# sourceMappingURL=usePagination.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"usePagination.d.ts","sourceRoot":"","sources":["../../src/hooks/usePagination.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG9C,UAAU,cAAc;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,aAAa,GAAI,UAAU,OAAO,EAAE;;;;qBAwIvB,MAAM,GAAG,IAAI;;;;;CAqDtC,CAAC"}