@testany/hephos 0.3.9 → 0.3.10
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/out/repl/ReplModeInk.d.ts.map +1 -1
- package/out/repl/ReplModeInk.js +198 -4
- package/out/repl/ReplModeInk.js.map +1 -1
- package/out/repl/components/HistoryOverlay.d.ts +20 -0
- package/out/repl/components/HistoryOverlay.d.ts.map +1 -0
- package/out/repl/components/HistoryOverlay.js +66 -0
- package/out/repl/components/HistoryOverlay.js.map +1 -0
- package/out/repl/hooks/useHistory.d.ts +56 -0
- package/out/repl/hooks/useHistory.d.ts.map +1 -0
- package/out/repl/hooks/useHistory.js +514 -0
- package/out/repl/hooks/useHistory.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReplModeInk.d.ts","sourceRoot":"","sources":["../../src/repl/ReplModeInk.tsx"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"ReplModeInk.d.ts","sourceRoot":"","sources":["../../src/repl/ReplModeInk.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAy1FH,MAAM,WAAW,gBAAgB;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,QAMjF"}
|
package/out/repl/ReplModeInk.js
CHANGED
|
@@ -25,6 +25,8 @@ import { SessionStorageService } from '@testany/agent-chatter-core';
|
|
|
25
25
|
import { RestorePrompt } from './components/RestorePrompt.js';
|
|
26
26
|
import { QueueDisplay } from './components/QueueDisplay.js';
|
|
27
27
|
import { TipsBar } from './components/TipsBar.js';
|
|
28
|
+
import { HistoryOverlay } from './components/HistoryOverlay.js';
|
|
29
|
+
import { useHistory } from './hooks/useHistory.js';
|
|
28
30
|
// Read version from package.json
|
|
29
31
|
const __filename = fileURLToPath(import.meta.url);
|
|
30
32
|
const __dirname = path.dirname(__filename);
|
|
@@ -230,6 +232,8 @@ function App({ registryPath, debug = false, proxyUrl }) {
|
|
|
230
232
|
const [isExiting, setIsExiting] = useState(false);
|
|
231
233
|
const [queueState, setQueueState] = useState(null);
|
|
232
234
|
const [showTips, setShowTips] = useState(true); // Tips bar visibility (default: on)
|
|
235
|
+
// Command history management
|
|
236
|
+
const history = useHistory();
|
|
233
237
|
// Track previous queue size to detect DROP-triggered clears
|
|
234
238
|
const prevQueueSizeRef = useRef(0);
|
|
235
239
|
// Streaming event handling
|
|
@@ -560,7 +564,30 @@ function App({ registryPath, debug = false, proxyUrl }) {
|
|
|
560
564
|
};
|
|
561
565
|
// Handle input submission (Enter key)
|
|
562
566
|
const handleInputSubmit = (value) => {
|
|
563
|
-
|
|
567
|
+
let submittedValue = value;
|
|
568
|
+
// Exit search mode if active (user submitted with Enter while in search mode)
|
|
569
|
+
// Use the selected history entry as the submitted value for consistency
|
|
570
|
+
if (history.searchMode) {
|
|
571
|
+
const selectedEntry = history.acceptSearch();
|
|
572
|
+
if (selectedEntry !== null) {
|
|
573
|
+
submittedValue = selectedEntry;
|
|
574
|
+
setInput(selectedEntry); // Sync input state
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
// Exit history mode if active (user submitted with Enter while browsing history)
|
|
578
|
+
// Use the selected history entry as the submitted value for consistency
|
|
579
|
+
else if (history.isActive) {
|
|
580
|
+
const selectedEntry = history.acceptHistory();
|
|
581
|
+
if (selectedEntry !== null) {
|
|
582
|
+
submittedValue = selectedEntry;
|
|
583
|
+
setInput(selectedEntry); // Sync input state
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
const trimmed = submittedValue.trim();
|
|
587
|
+
// Add to history (filtering handled by hook)
|
|
588
|
+
if (trimmed) {
|
|
589
|
+
history.addEntry(trimmed);
|
|
590
|
+
}
|
|
564
591
|
// Handle / commands
|
|
565
592
|
if (trimmed.startsWith('/')) {
|
|
566
593
|
const cmd = trimmed.split(' ')[0].toLowerCase();
|
|
@@ -645,8 +672,21 @@ function App({ registryPath, debug = false, proxyUrl }) {
|
|
|
645
672
|
}
|
|
646
673
|
return;
|
|
647
674
|
}
|
|
648
|
-
// ESC key -
|
|
675
|
+
// ESC key - Exit search/history mode or cancel agent execution
|
|
649
676
|
if (key.escape) {
|
|
677
|
+
// First, check if we're in search mode
|
|
678
|
+
if (history.searchMode) {
|
|
679
|
+
const savedInput = history.exitSearchMode();
|
|
680
|
+
setInput(savedInput);
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
// Then check if we're in history browsing mode
|
|
684
|
+
if (history.isActive) {
|
|
685
|
+
const savedInput = history.exitHistory();
|
|
686
|
+
setInput(savedInput);
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
// Cancel agent execution in conversation mode
|
|
650
690
|
if (mode === 'conversation' && activeCoordinator && executingAgent) {
|
|
651
691
|
// Check if ESC cancellation is allowed (LLD-05: use uiPrefs)
|
|
652
692
|
if (uiPrefs.allowEscCancel) {
|
|
@@ -660,8 +700,80 @@ function App({ registryPath, debug = false, proxyUrl }) {
|
|
|
660
700
|
}
|
|
661
701
|
}
|
|
662
702
|
}
|
|
703
|
+
// Ctrl+R - Enter search mode or search backward
|
|
704
|
+
if (key.ctrl && inputChar === 'r') {
|
|
705
|
+
if (mode === 'normal' || mode === 'conversation') {
|
|
706
|
+
if (history.searchMode) {
|
|
707
|
+
// Already in search mode - search backward
|
|
708
|
+
const result = history.searchBackward();
|
|
709
|
+
if (result !== null) {
|
|
710
|
+
setInput(result);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
else {
|
|
714
|
+
// Enter search mode
|
|
715
|
+
history.enterSearchMode(input);
|
|
716
|
+
}
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
// Ctrl+S - Search forward (only in search mode)
|
|
721
|
+
if (key.ctrl && inputChar === 's') {
|
|
722
|
+
if (history.searchMode) {
|
|
723
|
+
const result = history.searchForward();
|
|
724
|
+
if (result !== null) {
|
|
725
|
+
setInput(result);
|
|
726
|
+
}
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
// Ctrl+P - Navigate to previous (older) history entry (same as ↑)
|
|
731
|
+
if (key.ctrl && inputChar === 'p') {
|
|
732
|
+
if (mode === 'normal' || mode === 'conversation') {
|
|
733
|
+
// In search mode, navigate search results
|
|
734
|
+
if (history.searchMode) {
|
|
735
|
+
const result = history.searchBackward();
|
|
736
|
+
if (result !== null) {
|
|
737
|
+
setInput(result);
|
|
738
|
+
}
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
// Regular history navigation
|
|
742
|
+
const historyEntry = history.navigateUp(input);
|
|
743
|
+
if (historyEntry !== null) {
|
|
744
|
+
setInput(historyEntry);
|
|
745
|
+
}
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
// Ctrl+N - Navigate to next (newer) history entry (same as ↓)
|
|
750
|
+
if (key.ctrl && inputChar === 'n') {
|
|
751
|
+
if (mode === 'normal' || mode === 'conversation') {
|
|
752
|
+
// In search mode, navigate search results
|
|
753
|
+
if (history.searchMode) {
|
|
754
|
+
const result = history.searchForward();
|
|
755
|
+
if (result !== null) {
|
|
756
|
+
setInput(result);
|
|
757
|
+
}
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
// Regular history navigation
|
|
761
|
+
const historyEntry = history.navigateDown();
|
|
762
|
+
if (historyEntry !== null) {
|
|
763
|
+
setInput(historyEntry);
|
|
764
|
+
}
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
663
768
|
// Ctrl+C 退出或取消
|
|
664
769
|
if (key.ctrl && inputChar === 'c') {
|
|
770
|
+
// First, clean up any search/history state
|
|
771
|
+
if (history.searchMode) {
|
|
772
|
+
history.exitSearchMode();
|
|
773
|
+
}
|
|
774
|
+
else if (history.isActive) {
|
|
775
|
+
history.exitHistory();
|
|
776
|
+
}
|
|
665
777
|
if (mode === 'conversation' && activeCoordinator) {
|
|
666
778
|
// 退出对话模式
|
|
667
779
|
// stop() is async, fire-and-forget for UI responsiveness
|
|
@@ -741,14 +853,60 @@ function App({ registryPath, debug = false, proxyUrl }) {
|
|
|
741
853
|
// normal/conversation/wizard/form 由 TextInput 的 onSubmit 处理
|
|
742
854
|
return;
|
|
743
855
|
}
|
|
856
|
+
// Alt+↑ - Large jump backward (skip 5 entries)
|
|
857
|
+
// Cross-platform: key.meta captures Option key on macOS, Alt key on Windows/Linux
|
|
858
|
+
// in most modern terminal emulators (Windows Terminal, iTerm2, etc.)
|
|
859
|
+
if (key.meta && key.upArrow) {
|
|
860
|
+
if ((mode === 'normal' || mode === 'conversation') && !history.searchMode) {
|
|
861
|
+
const historyEntry = history.jumpUp(input);
|
|
862
|
+
if (historyEntry !== null) {
|
|
863
|
+
setInput(historyEntry);
|
|
864
|
+
}
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
// Alt+↓ - Large jump forward (skip 5 entries)
|
|
869
|
+
// Cross-platform: key.meta captures Option key on macOS, Alt key on Windows/Linux
|
|
870
|
+
if (key.meta && key.downArrow) {
|
|
871
|
+
if ((mode === 'normal' || mode === 'conversation') && !history.searchMode && history.isActive) {
|
|
872
|
+
const historyEntry = history.jumpDown();
|
|
873
|
+
if (historyEntry !== null) {
|
|
874
|
+
setInput(historyEntry);
|
|
875
|
+
}
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
744
879
|
// 处理不同模式下的上下键导航
|
|
745
880
|
if (key.upArrow) {
|
|
881
|
+
// Search mode takes priority - navigate search results
|
|
882
|
+
if (history.searchMode) {
|
|
883
|
+
const result = history.searchBackward();
|
|
884
|
+
if (result !== null) {
|
|
885
|
+
setInput(result);
|
|
886
|
+
}
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
746
889
|
if (mode === 'normal') {
|
|
747
890
|
const matches = getMatches();
|
|
748
891
|
if (matches.length > 0) {
|
|
892
|
+
// Command hint navigation has priority
|
|
749
893
|
setSelectedIndex(prev => (prev > 0 ? prev - 1 : matches.length - 1));
|
|
750
894
|
return;
|
|
751
895
|
}
|
|
896
|
+
// No command hints - use regular history navigation
|
|
897
|
+
const historyEntry = history.navigateUp(input);
|
|
898
|
+
if (historyEntry !== null) {
|
|
899
|
+
setInput(historyEntry);
|
|
900
|
+
}
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
else if (mode === 'conversation') {
|
|
904
|
+
// Regular history navigation in conversation mode
|
|
905
|
+
const historyEntry = history.navigateUp(input);
|
|
906
|
+
if (historyEntry !== null) {
|
|
907
|
+
setInput(historyEntry);
|
|
908
|
+
}
|
|
909
|
+
return;
|
|
752
910
|
}
|
|
753
911
|
else if (mode === 'menu' && menuItems.length > 0) {
|
|
754
912
|
setSelectedIndex(prev => (prev > 0 ? prev - 1 : menuItems.length - 1));
|
|
@@ -760,12 +918,35 @@ function App({ registryPath, debug = false, proxyUrl }) {
|
|
|
760
918
|
}
|
|
761
919
|
}
|
|
762
920
|
if (key.downArrow) {
|
|
921
|
+
// Search mode takes priority - navigate search results
|
|
922
|
+
if (history.searchMode) {
|
|
923
|
+
const result = history.searchForward();
|
|
924
|
+
if (result !== null) {
|
|
925
|
+
setInput(result);
|
|
926
|
+
}
|
|
927
|
+
return;
|
|
928
|
+
}
|
|
763
929
|
if (mode === 'normal') {
|
|
764
930
|
const matches = getMatches();
|
|
765
931
|
if (matches.length > 0) {
|
|
932
|
+
// Command hint navigation has priority
|
|
766
933
|
setSelectedIndex(prev => (prev < matches.length - 1 ? prev + 1 : 0));
|
|
767
934
|
return;
|
|
768
935
|
}
|
|
936
|
+
// No command hints - use regular history navigation
|
|
937
|
+
const historyEntry = history.navigateDown();
|
|
938
|
+
if (historyEntry !== null) {
|
|
939
|
+
setInput(historyEntry);
|
|
940
|
+
}
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
else if (mode === 'conversation') {
|
|
944
|
+
// Regular history navigation in conversation mode
|
|
945
|
+
const historyEntry = history.navigateDown();
|
|
946
|
+
if (historyEntry !== null) {
|
|
947
|
+
setInput(historyEntry);
|
|
948
|
+
}
|
|
949
|
+
return;
|
|
769
950
|
}
|
|
770
951
|
else if (mode === 'menu' && menuItems.length > 0) {
|
|
771
952
|
setSelectedIndex(prev => (prev < menuItems.length - 1 ? prev + 1 : 0));
|
|
@@ -1620,6 +1801,13 @@ function App({ registryPath, debug = false, proxyUrl }) {
|
|
|
1620
1801
|
}
|
|
1621
1802
|
}
|
|
1622
1803
|
}
|
|
1804
|
+
// Show search/history mode indicator in conversation mode
|
|
1805
|
+
if (history.searchMode) {
|
|
1806
|
+
return _jsxs(Text, { color: "yellow", children: ["[search:", teamName, "] ", history.searchQuery ? `"${history.searchQuery}"` : '', "> "] });
|
|
1807
|
+
}
|
|
1808
|
+
if (history.isActive) {
|
|
1809
|
+
return _jsxs(Text, { color: "green", bold: true, children: ["[history:", teamName, "] ", memberPrompt, "> "] });
|
|
1810
|
+
}
|
|
1623
1811
|
return _jsxs(Text, { color: "green", bold: true, children: ["[conversation:", teamName, "] ", memberPrompt, "> "] });
|
|
1624
1812
|
}
|
|
1625
1813
|
case 'wizard':
|
|
@@ -1627,10 +1815,16 @@ function App({ registryPath, debug = false, proxyUrl }) {
|
|
|
1627
1815
|
case 'form':
|
|
1628
1816
|
return _jsx(Text, { color: "cyan", bold: true, children: "[form] input> " });
|
|
1629
1817
|
default:
|
|
1630
|
-
// 'normal' mode
|
|
1818
|
+
// 'normal' mode - show search/history mode indicator
|
|
1819
|
+
if (history.searchMode) {
|
|
1820
|
+
return _jsxs(Text, { color: "yellow", children: ["[search] ", history.searchQuery ? `"${history.searchQuery}"` : '', "> "] });
|
|
1821
|
+
}
|
|
1822
|
+
if (history.isActive) {
|
|
1823
|
+
return _jsx(Text, { color: "cyan", children: "[history] hephos> " });
|
|
1824
|
+
}
|
|
1631
1825
|
return _jsx(Text, { color: "cyan", children: "[normal] hephos> " });
|
|
1632
1826
|
}
|
|
1633
|
-
})(), _jsx(TextInput, { value: input, onChange: setInput, onSubmit: handleInputSubmit, placeholder: " " })] }), _jsx(Text, { color: mode === 'conversation' ? 'green' : 'cyan', dimColor: true, children: '─'.repeat(terminalWidth - 4) })] })), !isExiting && mode === 'normal' && _jsx(CommandHints, { input: input, selectedIndex: selectedIndex }), !isExiting && mode === 'conversation' && (_jsx(TipsBar, { visible: showTips, terminalWidth: terminalWidth }))] }));
|
|
1827
|
+
})(), _jsx(TextInput, { value: input, onChange: setInput, onSubmit: handleInputSubmit, placeholder: " " })] }), _jsx(Text, { color: mode === 'conversation' ? 'green' : 'cyan', dimColor: true, children: '─'.repeat(terminalWidth - 4) })] })), !isExiting && (mode === 'normal' || mode === 'conversation') && (history.isActive || history.searchMode) && (_jsx(HistoryOverlay, { visible: true, entries: history.entries, currentIndex: history.currentIndex, searchMode: history.searchMode, searchQuery: history.searchQuery, terminalWidth: terminalWidth })), !isExiting && mode === 'normal' && !history.isActive && !history.searchMode && _jsx(CommandHints, { input: input, selectedIndex: selectedIndex }), !isExiting && mode === 'conversation' && !history.isActive && !history.searchMode && (_jsx(TipsBar, { visible: showTips, terminalWidth: terminalWidth }))] }));
|
|
1634
1828
|
}
|
|
1635
1829
|
export function startReplInk(registryPath, options = {}) {
|
|
1636
1830
|
render(_jsx(App, { registryPath: registryPath, debug: options.debug, proxyUrl: options.proxyUrl }), {
|