centaurus-cli 3.1.2 → 3.1.4
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/cli-adapter.js +689 -155
- package/dist/cli-adapter.js.map +1 -1
- package/dist/config/defaultConfig.js +1 -4
- package/dist/config/defaultConfig.js.map +1 -1
- package/dist/config/models.js +6 -0
- package/dist/config/models.js.map +1 -1
- package/dist/config/slash-commands.js +66 -2
- package/dist/config/slash-commands.js.map +1 -1
- package/dist/config/types.js +4 -4
- package/dist/config/types.js.map +1 -1
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -1
- package/dist/services/ai-context-injector.js +109 -0
- package/dist/services/ai-context-injector.js.map +1 -1
- package/dist/services/ai-service-client.js +3 -2
- package/dist/services/ai-service-client.js.map +1 -1
- package/dist/services/api-client.js.map +1 -1
- package/dist/services/background-task-manager.js +59 -0
- package/dist/services/background-task-manager.js.map +1 -1
- package/dist/services/local-chat-storage.js +2 -0
- package/dist/services/local-chat-storage.js.map +1 -1
- package/dist/services/skill-storage.js +141 -0
- package/dist/services/skill-storage.js.map +1 -0
- package/dist/services/sub-agent-manager.js +49 -8
- package/dist/services/sub-agent-manager.js.map +1 -1
- package/dist/services/warpify-detector.js +17 -5
- package/dist/services/warpify-detector.js.map +1 -1
- package/dist/tools/background-command.js +5 -2
- package/dist/tools/background-command.js.map +1 -1
- package/dist/tools/command.js +367 -109
- package/dist/tools/command.js.map +1 -1
- package/dist/tools/file-ops.js +23 -6
- package/dist/tools/file-ops.js.map +1 -1
- package/dist/tools/plan-mode.js +184 -336
- package/dist/tools/plan-mode.js.map +1 -1
- package/dist/tools/sub-agent.js +24 -5
- package/dist/tools/sub-agent.js.map +1 -1
- package/dist/tools/todo-list.js +157 -0
- package/dist/tools/todo-list.js.map +1 -0
- package/dist/types/skill.js +30 -0
- package/dist/types/skill.js.map +1 -0
- package/dist/ui/components/App.js +956 -162
- package/dist/ui/components/App.js.map +1 -1
- package/dist/ui/components/AuthScreen.js +3 -1
- package/dist/ui/components/AuthScreen.js.map +1 -1
- package/dist/ui/components/AuthWelcomeScreen.js +3 -1
- package/dist/ui/components/AuthWelcomeScreen.js.map +1 -1
- package/dist/ui/components/CodeBlock.js +3 -1
- package/dist/ui/components/CodeBlock.js.map +1 -1
- package/dist/ui/components/CompactShellPreview.js +44 -0
- package/dist/ui/components/CompactShellPreview.js.map +1 -0
- package/dist/ui/components/ConfigViewer.js +3 -1
- package/dist/ui/components/ConfigViewer.js.map +1 -1
- package/dist/ui/components/ConfirmPrompt.js +3 -1
- package/dist/ui/components/ConfirmPrompt.js.map +1 -1
- package/dist/ui/components/ConnectionStatusMessage.js +3 -1
- package/dist/ui/components/ConnectionStatusMessage.js.map +1 -1
- package/dist/ui/components/DetailedPlanReviewScreen.js +84 -74
- package/dist/ui/components/DetailedPlanReviewScreen.js.map +1 -1
- package/dist/ui/components/DiffViewer.js +6 -3
- package/dist/ui/components/DiffViewer.js.map +1 -1
- package/dist/ui/components/FileCreationPreview.js.map +1 -1
- package/dist/ui/components/FileTagAutocomplete.js +4 -2
- package/dist/ui/components/FileTagAutocomplete.js.map +1 -1
- package/dist/ui/components/InputBox.js +243 -40
- package/dist/ui/components/InputBox.js.map +1 -1
- package/dist/ui/components/InteractiveShell.js +5 -3
- package/dist/ui/components/InteractiveShell.js.map +1 -1
- package/dist/ui/components/KeyboardHelp.js +4 -1
- package/dist/ui/components/KeyboardHelp.js.map +1 -1
- package/dist/ui/components/LoadingIndicator.js +3 -1
- package/dist/ui/components/LoadingIndicator.js.map +1 -1
- package/dist/ui/components/MCPAddScreen.js +63 -13
- package/dist/ui/components/MCPAddScreen.js.map +1 -1
- package/dist/ui/components/MarkdownRenderer.js +3 -1
- package/dist/ui/components/MarkdownRenderer.js.map +1 -1
- package/dist/ui/components/MessageDisplay.js +9 -7
- package/dist/ui/components/MessageDisplay.js.map +1 -1
- package/dist/ui/components/ModelPicker.js +170 -0
- package/dist/ui/components/ModelPicker.js.map +1 -0
- package/dist/ui/components/MonitorModeAIPanel.js +3 -1
- package/dist/ui/components/MonitorModeAIPanel.js.map +1 -1
- package/dist/ui/components/PlanAcceptedMessage.js +12 -6
- package/dist/ui/components/PlanAcceptedMessage.js.map +1 -1
- package/dist/ui/components/PlanQuestionMessage.js +37 -0
- package/dist/ui/components/PlanQuestionMessage.js.map +1 -0
- package/dist/ui/components/PlanQuestionScreen.js +138 -0
- package/dist/ui/components/PlanQuestionScreen.js.map +1 -0
- package/dist/ui/components/PlanReviewScreen.js +7 -9
- package/dist/ui/components/PlanReviewScreen.js.map +1 -1
- package/dist/ui/components/RulesEditorScreen.js +65 -28
- package/dist/ui/components/RulesEditorScreen.js.map +1 -1
- package/dist/ui/components/SelectPrompt.js +3 -1
- package/dist/ui/components/SelectPrompt.js.map +1 -1
- package/dist/ui/components/SkillCreatorScreen.js +217 -0
- package/dist/ui/components/SkillCreatorScreen.js.map +1 -0
- package/dist/ui/components/SlashCommandAutocomplete.js +4 -2
- package/dist/ui/components/SlashCommandAutocomplete.js.map +1 -1
- package/dist/ui/components/StatusBar.js +4 -2
- package/dist/ui/components/StatusBar.js.map +1 -1
- package/dist/ui/components/StreamingMessageDisplay.js +5 -3
- package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
- package/dist/ui/components/SubAgentListScreen.js +65 -0
- package/dist/ui/components/SubAgentListScreen.js.map +1 -0
- package/dist/ui/components/SubAgentViewScreen.js +123 -0
- package/dist/ui/components/SubAgentViewScreen.js.map +1 -0
- package/dist/ui/components/TaskCompletedMessage.js +40 -8
- package/dist/ui/components/TaskCompletedMessage.js.map +1 -1
- package/dist/ui/components/TaskProgressIndicator.js +6 -4
- package/dist/ui/components/TaskProgressIndicator.js.map +1 -1
- package/dist/ui/components/TextEditor.js +297 -0
- package/dist/ui/components/TextEditor.js.map +1 -0
- package/dist/ui/components/TodoListMessage.js +59 -0
- package/dist/ui/components/TodoListMessage.js.map +1 -0
- package/dist/ui/components/ToolExecutionMessage.js +134 -84
- package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
- package/dist/ui/components/ToolExecutionStatus.js +3 -1
- package/dist/ui/components/ToolExecutionStatus.js.map +1 -1
- package/dist/ui/components/WelcomeBanner.js +33 -33
- package/dist/ui/components/WelcomeBanner.js.map +1 -1
- package/dist/ui/components/WorkflowCreatorScreen.js +5 -3
- package/dist/ui/components/WorkflowCreatorScreen.js.map +1 -1
- package/dist/ui/theme.js +97 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/ui/utils/chat-history-limit.js +247 -0
- package/dist/ui/utils/chat-history-limit.js.map +1 -0
- package/dist/utils/chat-formatter.js +22 -9
- package/dist/utils/chat-formatter.js.map +1 -1
- package/dist/utils/git-stats.js +7 -5
- package/dist/utils/git-stats.js.map +1 -1
- package/dist/utils/input-classifier.js +11 -1
- package/dist/utils/input-classifier.js.map +1 -1
- package/dist/utils/output-truncation.js +175 -0
- package/dist/utils/output-truncation.js.map +1 -0
- package/dist/utils/rule-reference-resolver.js +3 -3
- package/dist/utils/rule-reference-resolver.js.map +1 -1
- package/dist/utils/tunnel-commands-manager.js +134 -0
- package/dist/utils/tunnel-commands-manager.js.map +1 -0
- package/package.json +91 -90
- package/postinstall.js +4 -11
- package/dist/ui/components/MultiLineInput.js +0 -255
- package/dist/ui/components/MultiLineInput.js.map +0 -1
|
@@ -6,6 +6,8 @@ import { useConnectivity } from "../../hooks/useConnectivity.js";
|
|
|
6
6
|
import { Breadcrumbs } from "./Breadcrumbs.js";
|
|
7
7
|
import { GitDiffBreadcrumb } from "./GitDiffBreadcrumb.js";
|
|
8
8
|
import { ContextWindowIndicator } from "./ContextWindowIndicator.js";
|
|
9
|
+
import { LoadingIndicator } from "./LoadingIndicator.js";
|
|
10
|
+
import { AgentTimer } from "./AgentTimer.js";
|
|
9
11
|
import { logDebug } from "../../utils/logger.js";
|
|
10
12
|
import { detectIntent } from "../../utils/input-classifier.js";
|
|
11
13
|
import { CommandHistoryManager } from "../../utils/command-history.js";
|
|
@@ -17,6 +19,8 @@ import { useTerminalDimensions, TERMINAL_HEIGHT_CONSTANTS } from "../../hooks/us
|
|
|
17
19
|
import { AIAutocompleteAgent, AI_AUTOCOMPLETE_DEBOUNCE_MS } from "../../services/ai-autocomplete-agent.js";
|
|
18
20
|
import { workflowStorage } from "../../services/workflow-storage.js";
|
|
19
21
|
import { rulesStorage } from "../../services/rules-storage.js";
|
|
22
|
+
import { skillStorage } from "../../services/skill-storage.js";
|
|
23
|
+
import { useTheme } from "../theme.js";
|
|
20
24
|
const getVisualLines = (text, width) => {
|
|
21
25
|
const logicalLines = text.split("\n");
|
|
22
26
|
const visualLines = [];
|
|
@@ -65,6 +69,7 @@ const InputBox = React.memo(({
|
|
|
65
69
|
commandHistory = [],
|
|
66
70
|
onToggleAutoAccept,
|
|
67
71
|
onToggleCommandMode,
|
|
72
|
+
onTogglePlanMode,
|
|
68
73
|
onToggleBackgroundMode,
|
|
69
74
|
isActive = true,
|
|
70
75
|
subshellContext,
|
|
@@ -73,6 +78,8 @@ const InputBox = React.memo(({
|
|
|
73
78
|
maxTokens = 1e6,
|
|
74
79
|
contextLimitReached = false,
|
|
75
80
|
isShellRunning = false,
|
|
81
|
+
allowSubmitWhileShellRunning = false,
|
|
82
|
+
customTunnelCommand,
|
|
76
83
|
backgroundTaskCount = 0,
|
|
77
84
|
initialValue = "",
|
|
78
85
|
onValueChange,
|
|
@@ -84,8 +91,11 @@ const InputBox = React.memo(({
|
|
|
84
91
|
sessionCommands = [],
|
|
85
92
|
getCheckpoints,
|
|
86
93
|
onSetInputSetup,
|
|
87
|
-
gitDiffStats
|
|
94
|
+
gitDiffStats,
|
|
95
|
+
isAiWorking = false,
|
|
96
|
+
lastFileChangeSummary
|
|
88
97
|
}) => {
|
|
98
|
+
const theme = useTheme();
|
|
89
99
|
const [value, setValueInternal] = useState(initialValue);
|
|
90
100
|
const [cursorOffset, setCursorOffset] = useState(0);
|
|
91
101
|
const [completions, setCompletions] = useState([]);
|
|
@@ -115,6 +125,7 @@ const InputBox = React.memo(({
|
|
|
115
125
|
const isConnected = useConnectivity();
|
|
116
126
|
const dimensions = useTerminalDimensions();
|
|
117
127
|
const slashMaxVisibleItems = dimensions.rows < TERMINAL_HEIGHT_CONSTANTS.MIN_ROWS_FOR_STREAMING ? 0 : Math.min(5, Math.max(1, Math.floor((dimensions.rows - 20) / 3)));
|
|
128
|
+
const isCompactMode = !dimensions.shouldEnableStreaming;
|
|
118
129
|
const showBottomHints = dimensions.columns >= 90;
|
|
119
130
|
const showModeIndicator = dimensions.columns >= 70;
|
|
120
131
|
const [fileTagAutocompleteVisible, setFileTagAutocompleteVisible] = useState(false);
|
|
@@ -123,6 +134,7 @@ const InputBox = React.memo(({
|
|
|
123
134
|
const [activeFileTagStart, setActiveFileTagStart] = useState(null);
|
|
124
135
|
const [confirmedFileTags, setConfirmedFileTags] = useState([]);
|
|
125
136
|
const [confirmedClipboardFiles, setConfirmedClipboardFiles] = useState([]);
|
|
137
|
+
const [fileSelectionIndex, setFileSelectionIndex] = useState(-1);
|
|
126
138
|
const [visualLineCount, setVisualLineCount] = useState(1);
|
|
127
139
|
const MAX_VISIBLE_LINES = 9;
|
|
128
140
|
const setValue = React.useCallback((newValue) => {
|
|
@@ -386,6 +398,21 @@ const InputBox = React.memo(({
|
|
|
386
398
|
return matches;
|
|
387
399
|
}, []);
|
|
388
400
|
const updateSlashAutocomplete = React.useCallback((nextValue) => {
|
|
401
|
+
if (nextValue.startsWith("#")) {
|
|
402
|
+
const query = nextValue.slice(1).split(/\s+/)[0].toLowerCase();
|
|
403
|
+
if (!nextValue.includes(" ")) {
|
|
404
|
+
const skills = skillStorage.list();
|
|
405
|
+
const matches = skills.filter((s) => s.name.toLowerCase().startsWith(query) || s.name.toLowerCase().includes(query)).map((s) => ({ name: s.name, description: `${s.accessLevel} \u2014 ${s.promptPreview}` }));
|
|
406
|
+
if (matches.length > 0 || query.length === 0) {
|
|
407
|
+
showSlashAutocomplete(matches.length > 0 ? matches : [{ name: "(no skills)", description: "Use /skill new to create one" }]);
|
|
408
|
+
} else {
|
|
409
|
+
setSlashAutocompleteVisible(false);
|
|
410
|
+
}
|
|
411
|
+
} else {
|
|
412
|
+
setSlashAutocompleteVisible(false);
|
|
413
|
+
}
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
389
416
|
if (!nextValue.startsWith("/")) {
|
|
390
417
|
setSlashAutocompleteVisible(false);
|
|
391
418
|
return;
|
|
@@ -422,6 +449,10 @@ const InputBox = React.memo(({
|
|
|
422
449
|
showSlashAutocomplete(filterCommands(nextValue.slice(1)));
|
|
423
450
|
return;
|
|
424
451
|
}
|
|
452
|
+
if (nextValue.startsWith("/settings limit-chat-history ")) {
|
|
453
|
+
showSlashAutocomplete(filterCommands(nextValue.slice(1)));
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
425
456
|
if (nextValue.startsWith("/settings ")) {
|
|
426
457
|
showSlashAutocomplete(filterCommands(nextValue.slice(1)));
|
|
427
458
|
return;
|
|
@@ -449,6 +480,18 @@ const InputBox = React.memo(({
|
|
|
449
480
|
showSlashAutocomplete(getRuleNameAutocompleteEntries(partialName));
|
|
450
481
|
return;
|
|
451
482
|
}
|
|
483
|
+
if (nextValue.match(/^\/skill\s+(edit|delete|rm)\s+/)) {
|
|
484
|
+
const match = nextValue.match(/^\/skill\s+(?:edit|delete|rm)\s+(.*)$/);
|
|
485
|
+
const partialName = (match ? match[1] : "").toLowerCase();
|
|
486
|
+
const skills = skillStorage.list();
|
|
487
|
+
const matchingSkills = skills.filter((s) => s.name.toLowerCase().includes(partialName)).slice(0, 10).map((s) => ({ name: s.name, description: `${s.accessLevel} \u2014 ${s.promptPreview}` }));
|
|
488
|
+
showSlashAutocomplete(matchingSkills.length > 0 ? matchingSkills : [{ name: "(no skills)", description: "Use /skill new to create one" }]);
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
if (nextValue.startsWith("/skill ")) {
|
|
492
|
+
showSlashAutocomplete(filterCommands(nextValue.slice(1)));
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
452
495
|
if (nextValue.startsWith("/rules ")) {
|
|
453
496
|
showSlashAutocomplete(filterCommands(nextValue.slice(1)));
|
|
454
497
|
return;
|
|
@@ -594,20 +637,36 @@ const InputBox = React.memo(({
|
|
|
594
637
|
return;
|
|
595
638
|
}
|
|
596
639
|
let atPosition = -1;
|
|
640
|
+
let isQuoted = false;
|
|
597
641
|
for (let i = cursorOffset - 1; i >= 0; i--) {
|
|
598
642
|
const char = value[i];
|
|
599
|
-
if (
|
|
643
|
+
if (char === '"' && i > 0 && value[i - 1] === "@") {
|
|
644
|
+
atPosition = i - 1;
|
|
645
|
+
isQuoted = true;
|
|
646
|
+
break;
|
|
647
|
+
}
|
|
600
648
|
if (char === "@") {
|
|
601
|
-
|
|
649
|
+
if (i + 1 < value.length && value[i + 1] === '"') {
|
|
650
|
+
atPosition = i;
|
|
651
|
+
isQuoted = true;
|
|
652
|
+
} else {
|
|
653
|
+
atPosition = i;
|
|
654
|
+
}
|
|
602
655
|
break;
|
|
603
656
|
}
|
|
657
|
+
if (!isQuoted && /[\s\n]/.test(char)) break;
|
|
604
658
|
}
|
|
605
659
|
if (atPosition === -1 || atPosition > 0 && !/[\s\n]/.test(value[atPosition - 1])) {
|
|
606
660
|
setFileTagAutocompleteVisible(false);
|
|
607
661
|
setActiveFileTagStart(null);
|
|
608
662
|
return;
|
|
609
663
|
}
|
|
610
|
-
|
|
664
|
+
let query;
|
|
665
|
+
if (isQuoted) {
|
|
666
|
+
query = value.slice(atPosition + 2, cursorOffset).replace(/^"/, "");
|
|
667
|
+
} else {
|
|
668
|
+
query = value.slice(atPosition + 1, cursorOffset);
|
|
669
|
+
}
|
|
611
670
|
const matches = getMatchingMentionSuggestions(query);
|
|
612
671
|
if (matches.length > 0) {
|
|
613
672
|
setFileTagSuggestions(matches);
|
|
@@ -639,24 +698,27 @@ const InputBox = React.memo(({
|
|
|
639
698
|
pushToUndoStack();
|
|
640
699
|
const beforeTag = value.slice(0, activeFileTagStart);
|
|
641
700
|
const afterCursor = value.slice(cursorOffset);
|
|
642
|
-
const
|
|
701
|
+
const needsQuotes = /\s/.test(selected.insertText);
|
|
702
|
+
const insertStr = needsQuotes ? `"${selected.insertText}"` : selected.insertText;
|
|
703
|
+
const baseValue = beforeTag + "@" + insertStr;
|
|
704
|
+
const insertLen = 1 + insertStr.length;
|
|
643
705
|
if (selected.kind === "rule-namespace") {
|
|
644
706
|
const newValue2 = baseValue + afterCursor;
|
|
645
|
-
const newCursorPos2 = activeFileTagStart +
|
|
707
|
+
const newCursorPos2 = activeFileTagStart + insertLen;
|
|
646
708
|
setValue(newValue2);
|
|
647
709
|
setCursorOffset(newCursorPos2);
|
|
648
710
|
return;
|
|
649
711
|
}
|
|
650
712
|
if (viaTab && selected.kind === "directory") {
|
|
651
713
|
const newValue2 = baseValue + afterCursor;
|
|
652
|
-
const newCursorPos2 = activeFileTagStart +
|
|
714
|
+
const newCursorPos2 = activeFileTagStart + insertLen;
|
|
653
715
|
setValue(newValue2);
|
|
654
716
|
setCursorOffset(newCursorPos2);
|
|
655
717
|
return;
|
|
656
718
|
}
|
|
657
719
|
const trailingSuffix = viaTab ? "" : " ";
|
|
658
720
|
const newValue = baseValue + trailingSuffix + afterCursor;
|
|
659
|
-
const newCursorPos = activeFileTagStart +
|
|
721
|
+
const newCursorPos = activeFileTagStart + insertLen + trailingSuffix.length;
|
|
660
722
|
setValue(newValue);
|
|
661
723
|
setCursorOffset(newCursorPos);
|
|
662
724
|
setConfirmedFileTags((prev) => [
|
|
@@ -665,7 +727,7 @@ const InputBox = React.memo(({
|
|
|
665
727
|
),
|
|
666
728
|
{
|
|
667
729
|
start: activeFileTagStart,
|
|
668
|
-
end: activeFileTagStart +
|
|
730
|
+
end: activeFileTagStart + insertLen,
|
|
669
731
|
fileName: selected.name
|
|
670
732
|
}
|
|
671
733
|
]);
|
|
@@ -704,6 +766,13 @@ const InputBox = React.memo(({
|
|
|
704
766
|
setSlashAutocompleteVisible(false);
|
|
705
767
|
return;
|
|
706
768
|
}
|
|
769
|
+
if (value.startsWith("#")) {
|
|
770
|
+
const newValue = `#${selected.name} `;
|
|
771
|
+
setValue(newValue);
|
|
772
|
+
setCursorOffset(newValue.length);
|
|
773
|
+
setSlashAutocompleteVisible(false);
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
707
776
|
if (value.startsWith("/mcp ")) {
|
|
708
777
|
const newValue = `/mcp ${selected.name} `;
|
|
709
778
|
setValue(newValue);
|
|
@@ -812,11 +881,53 @@ const InputBox = React.memo(({
|
|
|
812
881
|
setSlashAutocompleteVisible(false);
|
|
813
882
|
}
|
|
814
883
|
}
|
|
884
|
+
} else if (value.startsWith("/sub-agent ") || value.startsWith("/subagent ")) {
|
|
885
|
+
const prefix = value.startsWith("/sub-agent ") ? "/sub-agent " : "/subagent ";
|
|
886
|
+
const newValue = `${prefix}${selected.name}`;
|
|
887
|
+
setValue(newValue);
|
|
888
|
+
setCursorOffset(newValue.length);
|
|
889
|
+
setSlashAutocompleteVisible(false);
|
|
890
|
+
} else if (value.startsWith("/skill edit ") || value.startsWith("/skill delete ") || value.startsWith("/skill rm ")) {
|
|
891
|
+
const prefix = value.match(/^\/skill\s+(?:edit|delete|rm)\s+/)?.[0] || "/skill edit ";
|
|
892
|
+
const newValue = `${prefix}${selected.name}`;
|
|
893
|
+
setValue(newValue);
|
|
894
|
+
setCursorOffset(newValue.length);
|
|
895
|
+
setSlashAutocompleteVisible(false);
|
|
896
|
+
} else if (value.startsWith("/skill ")) {
|
|
897
|
+
const newValue = `/skill ${selected.name} `;
|
|
898
|
+
setValue(newValue);
|
|
899
|
+
setCursorOffset(newValue.length);
|
|
900
|
+
if (selected.name === "edit" || selected.name === "delete") {
|
|
901
|
+
const skills = skillStorage.list();
|
|
902
|
+
const skillMatches = skills.map((s) => ({
|
|
903
|
+
name: s.name,
|
|
904
|
+
description: `${s.accessLevel} \u2014 ${s.promptPreview}`
|
|
905
|
+
}));
|
|
906
|
+
if (skillMatches.length > 0) {
|
|
907
|
+
setSlashAutocompleteCommands(skillMatches);
|
|
908
|
+
setSlashAutocompleteSelectedIndex(0);
|
|
909
|
+
setSlashAutocompleteScrollOffset(0);
|
|
910
|
+
} else {
|
|
911
|
+
setSlashAutocompleteVisible(false);
|
|
912
|
+
}
|
|
913
|
+
} else {
|
|
914
|
+
setSlashAutocompleteVisible(false);
|
|
915
|
+
}
|
|
916
|
+
} else if (value.startsWith("/settings theme ")) {
|
|
917
|
+
const newValue = `/settings theme ${selected.name}`;
|
|
918
|
+
setValue(newValue);
|
|
919
|
+
setCursorOffset(newValue.length);
|
|
920
|
+
setSlashAutocompleteVisible(false);
|
|
815
921
|
} else if (value.startsWith("/settings auto-suggest ")) {
|
|
816
922
|
const newValue = `/settings auto-suggest ${selected.name}`;
|
|
817
923
|
setValue(newValue);
|
|
818
924
|
setCursorOffset(newValue.length);
|
|
819
925
|
setSlashAutocompleteVisible(false);
|
|
926
|
+
} else if (value.startsWith("/settings limit-chat-history ")) {
|
|
927
|
+
const newValue = `/settings limit-chat-history ${selected.name}`;
|
|
928
|
+
setValue(newValue);
|
|
929
|
+
setCursorOffset(newValue.length);
|
|
930
|
+
setSlashAutocompleteVisible(false);
|
|
820
931
|
} else if (value.startsWith("/settings ")) {
|
|
821
932
|
const newValue = `/settings ${selected.name} `;
|
|
822
933
|
setValue(newValue);
|
|
@@ -830,6 +941,24 @@ const InputBox = React.memo(({
|
|
|
830
941
|
} else {
|
|
831
942
|
setSlashAutocompleteVisible(false);
|
|
832
943
|
}
|
|
944
|
+
} else if (selected.name === "limit-chat-history") {
|
|
945
|
+
const optionMatches = filterCommands("settings limit-chat-history ");
|
|
946
|
+
if (optionMatches.length > 0) {
|
|
947
|
+
setSlashAutocompleteCommands(optionMatches);
|
|
948
|
+
setSlashAutocompleteSelectedIndex(0);
|
|
949
|
+
setSlashAutocompleteScrollOffset(0);
|
|
950
|
+
} else {
|
|
951
|
+
setSlashAutocompleteVisible(false);
|
|
952
|
+
}
|
|
953
|
+
} else if (selected.name === "theme") {
|
|
954
|
+
const themeMatches = filterCommands("settings theme ");
|
|
955
|
+
if (themeMatches.length > 0) {
|
|
956
|
+
setSlashAutocompleteCommands(themeMatches);
|
|
957
|
+
setSlashAutocompleteSelectedIndex(0);
|
|
958
|
+
setSlashAutocompleteScrollOffset(0);
|
|
959
|
+
} else {
|
|
960
|
+
setSlashAutocompleteVisible(false);
|
|
961
|
+
}
|
|
833
962
|
} else {
|
|
834
963
|
setSlashAutocompleteVisible(false);
|
|
835
964
|
}
|
|
@@ -918,6 +1047,24 @@ const InputBox = React.memo(({
|
|
|
918
1047
|
} else {
|
|
919
1048
|
setSlashAutocompleteVisible(false);
|
|
920
1049
|
}
|
|
1050
|
+
} else if (selected.name === "sub-agent" || selected.name === "subagent") {
|
|
1051
|
+
const subcommandMatches = filterCommands("sub-agent ");
|
|
1052
|
+
if (subcommandMatches.length > 0) {
|
|
1053
|
+
setSlashAutocompleteCommands(subcommandMatches);
|
|
1054
|
+
setSlashAutocompleteSelectedIndex(0);
|
|
1055
|
+
setSlashAutocompleteScrollOffset(0);
|
|
1056
|
+
} else {
|
|
1057
|
+
setSlashAutocompleteVisible(false);
|
|
1058
|
+
}
|
|
1059
|
+
} else if (selected.name === "skill") {
|
|
1060
|
+
const subcommandMatches = filterCommands("skill ");
|
|
1061
|
+
if (subcommandMatches.length > 0) {
|
|
1062
|
+
setSlashAutocompleteCommands(subcommandMatches);
|
|
1063
|
+
setSlashAutocompleteSelectedIndex(0);
|
|
1064
|
+
setSlashAutocompleteScrollOffset(0);
|
|
1065
|
+
} else {
|
|
1066
|
+
setSlashAutocompleteVisible(false);
|
|
1067
|
+
}
|
|
921
1068
|
} else if (selected.name === "revert") {
|
|
922
1069
|
const checkpoints = getCheckpoints ? getCheckpoints() : [];
|
|
923
1070
|
if (checkpoints.length === 0) {
|
|
@@ -981,8 +1128,8 @@ const InputBox = React.memo(({
|
|
|
981
1128
|
return;
|
|
982
1129
|
}
|
|
983
1130
|
}
|
|
984
|
-
const
|
|
985
|
-
if (
|
|
1131
|
+
const isPasteFile = key.ctrl && input === "v" || input === "\u221A";
|
|
1132
|
+
if (isPasteFile && !commandMode) {
|
|
986
1133
|
(async () => {
|
|
987
1134
|
try {
|
|
988
1135
|
const files = await getClipboardFiles();
|
|
@@ -990,35 +1137,54 @@ const InputBox = React.memo(({
|
|
|
990
1137
|
const currentCount = confirmedClipboardFiles.length;
|
|
991
1138
|
const newCount = files.length;
|
|
992
1139
|
if (currentCount + newCount > 5) {
|
|
993
|
-
logDebug(`
|
|
1140
|
+
logDebug(`Ctrl+V: Rejected file paste, limit exceeded (${currentCount} + ${newCount} > 5)`);
|
|
994
1141
|
setRejectFlash(true);
|
|
995
1142
|
setTimeout(() => setRejectFlash(false), 1e3);
|
|
996
1143
|
return;
|
|
997
1144
|
}
|
|
998
|
-
logDebug(`
|
|
1145
|
+
logDebug(`Ctrl+V: Found ${files.length} file(s) in clipboard, adding to input`);
|
|
999
1146
|
const newFilesWithIds = files.map((file) => ({
|
|
1000
1147
|
...file,
|
|
1001
1148
|
id: `${file.id}_${Date.now()}_${Math.random().toString(36).substring(7)}`
|
|
1002
1149
|
}));
|
|
1003
1150
|
setConfirmedClipboardFiles((prev) => [...prev, ...newFilesWithIds]);
|
|
1004
1151
|
} else {
|
|
1005
|
-
logDebug("
|
|
1152
|
+
logDebug("Ctrl+V: No file in clipboard");
|
|
1006
1153
|
}
|
|
1007
1154
|
} catch (error) {
|
|
1008
|
-
logDebug(`
|
|
1155
|
+
logDebug(`Ctrl+V: Failed to check clipboard: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1009
1156
|
}
|
|
1010
1157
|
})();
|
|
1011
1158
|
return;
|
|
1012
1159
|
}
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
setConfirmedClipboardFiles((prev) => prev.slice(0, -1));
|
|
1018
|
-
} else {
|
|
1019
|
-
logDebug(`Alt+X: No files to remove`);
|
|
1160
|
+
if (fileSelectionIndex >= 0) {
|
|
1161
|
+
if (key.leftArrow) {
|
|
1162
|
+
setFileSelectionIndex((prev) => Math.max(prev - 1, 0));
|
|
1163
|
+
return;
|
|
1020
1164
|
}
|
|
1021
|
-
|
|
1165
|
+
if (key.rightArrow) {
|
|
1166
|
+
setFileSelectionIndex((prev) => Math.min(prev + 1, confirmedClipboardFiles.length - 1));
|
|
1167
|
+
return;
|
|
1168
|
+
}
|
|
1169
|
+
if (key.backspace || key.delete) {
|
|
1170
|
+
const idxToRemove = fileSelectionIndex;
|
|
1171
|
+
setConfirmedClipboardFiles((prev) => prev.filter((_, i) => i !== idxToRemove));
|
|
1172
|
+
const newLen = confirmedClipboardFiles.length - 1;
|
|
1173
|
+
if (newLen <= 0) {
|
|
1174
|
+
setFileSelectionIndex(-1);
|
|
1175
|
+
} else {
|
|
1176
|
+
setFileSelectionIndex(Math.min(idxToRemove, newLen - 1));
|
|
1177
|
+
}
|
|
1178
|
+
return;
|
|
1179
|
+
}
|
|
1180
|
+
if (key.downArrow || key.escape) {
|
|
1181
|
+
setFileSelectionIndex(-1);
|
|
1182
|
+
return;
|
|
1183
|
+
}
|
|
1184
|
+
if (key.upArrow) {
|
|
1185
|
+
return;
|
|
1186
|
+
}
|
|
1187
|
+
setFileSelectionIndex(-1);
|
|
1022
1188
|
}
|
|
1023
1189
|
if (isMacOptionWordBackwardSequence) {
|
|
1024
1190
|
if (cursorOffset > 0) {
|
|
@@ -1077,6 +1243,16 @@ const InputBox = React.memo(({
|
|
|
1077
1243
|
}, 100);
|
|
1078
1244
|
return;
|
|
1079
1245
|
}
|
|
1246
|
+
if (key.ctrl && input.toLowerCase() === "p") {
|
|
1247
|
+
if (onTogglePlanMode) {
|
|
1248
|
+
ignoreNextChangeRef.current = true;
|
|
1249
|
+
onTogglePlanMode();
|
|
1250
|
+
setTimeout(() => {
|
|
1251
|
+
ignoreNextChangeRef.current = false;
|
|
1252
|
+
}, 100);
|
|
1253
|
+
}
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1080
1256
|
if (key.ctrl && input.toLowerCase() === "d") {
|
|
1081
1257
|
if (onToggleCommandMode) {
|
|
1082
1258
|
ignoreNextChangeRef.current = true;
|
|
@@ -1224,6 +1400,13 @@ const InputBox = React.memo(({
|
|
|
1224
1400
|
currentVisualLineIndex = visualLines.length - 1;
|
|
1225
1401
|
}
|
|
1226
1402
|
if (currentVisualLineIndex <= 0) {
|
|
1403
|
+
if (confirmedClipboardFiles.length > 0 && (historyIndex <= 0 || commandHistory.length === 0)) {
|
|
1404
|
+
if (historyIndex === -1 && commandHistory.length > 0) {
|
|
1405
|
+
setTempValue(value);
|
|
1406
|
+
}
|
|
1407
|
+
setFileSelectionIndex(confirmedClipboardFiles.length - 1);
|
|
1408
|
+
return;
|
|
1409
|
+
}
|
|
1227
1410
|
if (commandHistory.length > 0) {
|
|
1228
1411
|
if (historyIndex === -1) {
|
|
1229
1412
|
setTempValue(value);
|
|
@@ -1475,7 +1658,7 @@ const InputBox = React.memo(({
|
|
|
1475
1658
|
};
|
|
1476
1659
|
const handleSubmit = () => {
|
|
1477
1660
|
if (!isActive) return;
|
|
1478
|
-
if (isShellRunning) {
|
|
1661
|
+
if (isShellRunning && !allowSubmitWhileShellRunning) {
|
|
1479
1662
|
setRejectFlash(true);
|
|
1480
1663
|
setTimeout(() => setRejectFlash(false), 1e3);
|
|
1481
1664
|
return;
|
|
@@ -1498,6 +1681,7 @@ const InputBox = React.memo(({
|
|
|
1498
1681
|
setAutocompleteSuggestion(null);
|
|
1499
1682
|
setConfirmedFileTags([]);
|
|
1500
1683
|
setConfirmedClipboardFiles([]);
|
|
1684
|
+
setFileSelectionIndex(-1);
|
|
1501
1685
|
}
|
|
1502
1686
|
};
|
|
1503
1687
|
const renderInput = () => {
|
|
@@ -1574,7 +1758,7 @@ const InputBox = React.memo(({
|
|
|
1574
1758
|
const isInActiveFileTag = activeFileTagStart !== null && absPos >= activeFileTagStart && absPos < activeFileTagEnd;
|
|
1575
1759
|
let isInConfirmedFileTag = false;
|
|
1576
1760
|
if (!commandMode) {
|
|
1577
|
-
const fileTagRegex = /(?:^|[\s\n])(@[^\s@]+)/g;
|
|
1761
|
+
const fileTagRegex = /(?:^|[\s\n])(@"[^"]*"|@[^\s@]+)/g;
|
|
1578
1762
|
let match;
|
|
1579
1763
|
while ((match = fileTagRegex.exec(value)) !== null) {
|
|
1580
1764
|
const fullMatch = match[0];
|
|
@@ -1598,7 +1782,7 @@ const InputBox = React.memo(({
|
|
|
1598
1782
|
return /* @__PURE__ */ React.createElement(Text, { key: charIdx, backgroundColor: "white", color: "black" }, char);
|
|
1599
1783
|
}
|
|
1600
1784
|
if (isInConfirmedFileTag || isInActiveFileTag) {
|
|
1601
|
-
return /* @__PURE__ */ React.createElement(Text, { key: charIdx, color:
|
|
1785
|
+
return /* @__PURE__ */ React.createElement(Text, { key: charIdx, color: theme.accent, bold: true }, char);
|
|
1602
1786
|
}
|
|
1603
1787
|
return /* @__PURE__ */ React.createElement(Text, { key: charIdx }, char);
|
|
1604
1788
|
});
|
|
@@ -1619,6 +1803,35 @@ const InputBox = React.memo(({
|
|
|
1619
1803
|
return /* @__PURE__ */ React.createElement(Text, { key: idx }, renderedChars);
|
|
1620
1804
|
}), endLine < totalVisualLines && /* @__PURE__ */ React.createElement(Text, { color: "gray" }, "\u2193 ..."));
|
|
1621
1805
|
};
|
|
1806
|
+
if (isCompactMode) {
|
|
1807
|
+
const compactBorderColor = rejectFlash ? "#ff3366" : sessionQuotaExhausted ? "#ff3366" : backgroundMode ? "#9966ff" : commandMode ? "#00cc66" : theme.border;
|
|
1808
|
+
const ruleWidth = Math.max(10, dimensions.columns - 4);
|
|
1809
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { justifyContent: "space-between", width: "100%", flexDirection: "row" }, isAiWorking ? /* @__PURE__ */ React.createElement(Box, { flexDirection: "row" }, /* @__PURE__ */ React.createElement(LoadingIndicator, null), /* @__PURE__ */ React.createElement(AgentTimer, null)) : /* @__PURE__ */ React.createElement(Box, { flexShrink: 1, minWidth: 0, flexDirection: "row" }, subshellContext && subshellContext.type !== "local" && /* @__PURE__ */ React.createElement(Breadcrumbs, { context: subshellContext, stack: subshellContextStack }), customTunnelCommand && /* @__PURE__ */ React.createElement(Box, { marginRight: 1 }, subshellContext && subshellContext.type !== "local" && /* @__PURE__ */ React.createElement(Text, { color: "gray" }, " \u203A "), /* @__PURE__ */ React.createElement(Text, { color: "#9945FF", bold: true }, "[tunnel: ", customTunnelCommand, "]")), /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, "CWD: "), /* @__PURE__ */ React.createElement(Text, { color: theme.accent, bold: true, wrap: "truncate-start" }, currentDir), gitDiffStats && (gitDiffStats.additions > 0 || gitDiffStats.deletions > 0) && /* @__PURE__ */ React.createElement(
|
|
1810
|
+
GitDiffBreadcrumb,
|
|
1811
|
+
{
|
|
1812
|
+
additions: gitDiffStats.additions,
|
|
1813
|
+
deletions: gitDiffStats.deletions
|
|
1814
|
+
}
|
|
1815
|
+
), confirmedClipboardFiles.length > 0 && confirmedClipboardFiles.map((_, i) => /* @__PURE__ */ React.createElement(Text, { key: i, color: fileSelectionIndex === i ? "#000000" : "#ff69b4", backgroundColor: fileSelectionIndex === i ? "#ff69b4" : void 0, bold: fileSelectionIndex === i }, " [file_", i + 1, "]"))), lastFileChangeSummary && lastFileChangeSummary.filesChanged > 0 && /* @__PURE__ */ React.createElement(Box, { paddingRight: 1, flexDirection: "row", flexShrink: 0 }, /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, lastFileChangeSummary.filesChanged, " file", lastFileChangeSummary.filesChanged !== 1 ? "s" : "", " changed "), lastFileChangeSummary.insertions > 0 && /* @__PURE__ */ React.createElement(Text, { color: "green" }, "+", lastFileChangeSummary.insertions), lastFileChangeSummary.insertions > 0 && lastFileChangeSummary.deletions > 0 && /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, " "), lastFileChangeSummary.deletions > 0 && /* @__PURE__ */ React.createElement(Text, { color: "red" }, "-", lastFileChangeSummary.deletions))), /* @__PURE__ */ React.createElement(Text, { color: compactBorderColor }, "\u2500".repeat(ruleWidth)), /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", width: "100%" }, /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, "> "), renderInput()), /* @__PURE__ */ React.createElement(Text, { color: compactBorderColor }, "\u2500".repeat(ruleWidth)), slashAutocompleteVisible && slashAutocompleteCommands.length > 0 ? /* @__PURE__ */ React.createElement(Box, { width: "100%" }, (() => {
|
|
1816
|
+
const selected = slashAutocompleteCommands[slashAutocompleteSelectedIndex];
|
|
1817
|
+
if (!selected) return null;
|
|
1818
|
+
return /* @__PURE__ */ React.createElement(Box, { gap: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.accent, bold: true, inverse: true }, " ", selected.name, " "), selected.swatchColor ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, { color: selected.swatchColor }, "\u2588\u2588\u2588\u2588"), /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, selected.description)) : /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, selected.description), slashAutocompleteCommands.length > 1 && /* @__PURE__ */ React.createElement(Text, { color: "#555555", dimColor: true }, " (", slashAutocompleteSelectedIndex + 1, "/", slashAutocompleteCommands.length, ") \u2191\u2193"));
|
|
1819
|
+
})()) : fileTagAutocompleteVisible && fileTagSuggestions.length > 0 ? /* @__PURE__ */ React.createElement(Box, { width: "100%" }, (() => {
|
|
1820
|
+
const selected = fileTagSuggestions[fileTagSelectedIndex];
|
|
1821
|
+
if (!selected) return null;
|
|
1822
|
+
const icon = selected.kind === "directory" ? "\u{1F4C1}" : selected.kind === "rule" ? "\u{1F4DC}" : "\u{1F4C4}";
|
|
1823
|
+
return /* @__PURE__ */ React.createElement(Box, { gap: 1 }, /* @__PURE__ */ React.createElement(Text, { color: theme.accent, bold: true, inverse: true }, " ", icon, " ", selected.name, " "), selected.description && /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, selected.description), fileTagSuggestions.length > 1 && /* @__PURE__ */ React.createElement(Text, { color: "#555555", dimColor: true }, " (", fileTagSelectedIndex + 1, "/", fileTagSuggestions.length, ") \u2191\u2193"));
|
|
1824
|
+
})()) : (
|
|
1825
|
+
/* ── Normal status line ── */
|
|
1826
|
+
/* @__PURE__ */ React.createElement(Box, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, "Mode: "), isAutoMode ? /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.accent, bold: true }, "Auto ["), detectedIntent === "command" ? /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "Terminal") : /* @__PURE__ */ React.createElement(Text, { color: theme.accent }, "Agent"), /* @__PURE__ */ React.createElement(Text, { color: theme.accent, bold: true }, "]")) : backgroundMode ? /* @__PURE__ */ React.createElement(Text, { color: "#9966ff", bold: true }, "Background") : commandMode ? /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "Terminal") : planMode ? /* @__PURE__ */ React.createElement(Text, { color: "#ffaa00", bold: true }, "Plan") : /* @__PURE__ */ React.createElement(Text, { color: theme.accent }, "Agent"), model && !commandMode && !backgroundMode && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, null, " "), /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, "Model: "), /* @__PURE__ */ React.createElement(Text, { color: theme.accent }, model))), /* @__PURE__ */ React.createElement(Box, { gap: 1 }, subAgentCount > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.accent, bold: true }, "[sub-agent: ", subAgentCount, "]"), backgroundTaskCount > 0 && /* @__PURE__ */ React.createElement(Text, { color: "#9966ff", bold: true }, "[bkg tasks: ", backgroundTaskCount, "]"), !commandMode && !backgroundMode && planMode && /* @__PURE__ */ React.createElement(Text, { color: "#ffaa00", bold: true }, "[PLANNING]"), !commandMode && !backgroundMode && autoAcceptMode && /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "[AUTO-ACCEPT: ON]"), !commandMode && !backgroundMode && currentTokens > 0 ? /* @__PURE__ */ React.createElement(
|
|
1827
|
+
ContextWindowIndicator,
|
|
1828
|
+
{
|
|
1829
|
+
currentTokens,
|
|
1830
|
+
maxTokens
|
|
1831
|
+
}
|
|
1832
|
+
) : /* @__PURE__ */ React.createElement(Text, { color: "#666666", dimColor: true }, isAutoMode ? showBottomHints ? autoAcceptMode ? "Ctrl+D to switch modes" : "Ctrl+D to switch modes \u2022 Ctrl+T to auto-approve" : "Ctrl+D to switch modes" : backgroundMode ? "Ctrl+D to switch modes \u2022 Commands run in background" : commandMode ? "Ctrl+D to switch modes \u2022 Tab for autocomplete" : showBottomHints ? autoAcceptMode ? "Ctrl+D to switch modes" : "Ctrl+D to switch modes \u2022 Ctrl+T to auto-approve" : "Ctrl+D to switch modes")))
|
|
1833
|
+
));
|
|
1834
|
+
}
|
|
1622
1835
|
return /* @__PURE__ */ React.createElement(
|
|
1623
1836
|
Box,
|
|
1624
1837
|
{
|
|
@@ -1626,32 +1839,22 @@ const InputBox = React.memo(({
|
|
|
1626
1839
|
borderStyle: "round",
|
|
1627
1840
|
borderColor: rejectFlash ? "#ff3366" : sessionQuotaExhausted ? "#ff3366" : (
|
|
1628
1841
|
// Red when quota exhausted
|
|
1629
|
-
backgroundMode ? "#9966ff" : commandMode ? "#00cc66" :
|
|
1842
|
+
backgroundMode ? "#9966ff" : commandMode ? "#00cc66" : theme.border
|
|
1630
1843
|
),
|
|
1631
1844
|
paddingX: 1,
|
|
1632
1845
|
paddingY: 0,
|
|
1633
1846
|
width: "100%"
|
|
1634
1847
|
},
|
|
1635
|
-
/* @__PURE__ */ React.createElement(Box, { marginY: 1, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexShrink: 1, minWidth: 0, flexDirection: "row" }, subshellContext && subshellContext.type !== "local" && /* @__PURE__ */ React.createElement(Breadcrumbs, { context: subshellContext, stack: subshellContextStack }), /* @__PURE__ */ React.createElement(Text, { color: "#
|
|
1848
|
+
/* @__PURE__ */ React.createElement(Box, { marginY: 1, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { flexShrink: 1, minWidth: 0, flexDirection: "row" }, subshellContext && subshellContext.type !== "local" && /* @__PURE__ */ React.createElement(Breadcrumbs, { context: subshellContext, stack: subshellContextStack }), customTunnelCommand && /* @__PURE__ */ React.createElement(Box, { marginRight: 1 }, subshellContext && subshellContext.type !== "local" && /* @__PURE__ */ React.createElement(Text, { color: "gray" }, " \u203A "), /* @__PURE__ */ React.createElement(Text, { color: "#9945FF", bold: true }, "[tunnel: ", customTunnelCommand, "]")), /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, "CWD: "), /* @__PURE__ */ React.createElement(Text, { color: theme.accent, bold: true, wrap: "truncate-start" }, currentDir), gitDiffStats && (gitDiffStats.additions > 0 || gitDiffStats.deletions > 0) && /* @__PURE__ */ React.createElement(
|
|
1636
1849
|
GitDiffBreadcrumb,
|
|
1637
1850
|
{
|
|
1638
1851
|
additions: gitDiffStats.additions,
|
|
1639
1852
|
deletions: gitDiffStats.deletions
|
|
1640
1853
|
}
|
|
1641
|
-
)), /* @__PURE__ */ React.createElement(Box, { flexShrink: 0 }, model && !commandMode && !backgroundMode && /* @__PURE__ */ React.createElement(Box, { marginRight: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, "Model: "), /* @__PURE__ */ React.createElement(Text, { color:
|
|
1642
|
-
confirmedClipboardFiles.length > 0 && /* @__PURE__ */ React.createElement(Box, { marginBottom: 1, flexDirection: "row", flexWrap: "wrap", gap: 1 }, confirmedClipboardFiles.map((file, index) => /* @__PURE__ */ React.createElement(
|
|
1643
|
-
Box,
|
|
1644
|
-
{
|
|
1645
|
-
key: file.id,
|
|
1646
|
-
borderStyle: "round",
|
|
1647
|
-
borderColor: "#ff69b4",
|
|
1648
|
-
paddingX: 1
|
|
1649
|
-
},
|
|
1650
|
-
/* @__PURE__ */ React.createElement(Text, { color: "#ff69b4", bold: true }, "file_", index + 1)
|
|
1651
|
-
))),
|
|
1854
|
+
), confirmedClipboardFiles.length > 0 && confirmedClipboardFiles.map((_, i) => /* @__PURE__ */ React.createElement(Text, { key: i, color: fileSelectionIndex === i ? "#000000" : "#ff69b4", backgroundColor: fileSelectionIndex === i ? "#ff69b4" : void 0, bold: fileSelectionIndex === i }, " [file_", i + 1, "]"))), /* @__PURE__ */ React.createElement(Box, { flexShrink: 0 }, model && !commandMode && !backgroundMode && /* @__PURE__ */ React.createElement(Box, { marginRight: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, "Model: "), /* @__PURE__ */ React.createElement(Text, { color: theme.accent }, model)), /* @__PURE__ */ React.createElement(Box, null, showModeIndicator && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, "Mode: "), isAutoMode ? /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: theme.accent, bold: true }, "Auto ["), detectedIntent === "command" ? /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "Terminal") : /* @__PURE__ */ React.createElement(Text, { color: theme.accent }, "Agent"), /* @__PURE__ */ React.createElement(Text, { color: theme.accent, bold: true }, "]")) : backgroundMode ? /* @__PURE__ */ React.createElement(Text, { color: "#9966ff", bold: true }, "Background") : commandMode ? /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "Terminal") : planMode ? /* @__PURE__ */ React.createElement(Text, { color: "#ffaa00", bold: true }, "Plan") : /* @__PURE__ */ React.createElement(Text, { color: theme.accent }, "Agent"))))),
|
|
1652
1855
|
showQuotaMessage && /* @__PURE__ */ React.createElement(Box, { justifyContent: "flex-end", marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "#ff3366", bold: true }, "Session quota reached. Try again in ", sessionQuotaTimeRemaining)),
|
|
1653
1856
|
/* @__PURE__ */ React.createElement(Box, { flexDirection: "row", width: "100%" }, /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, "> "), renderInput()),
|
|
1654
|
-
/* @__PURE__ */ React.createElement(Box, { marginY: 1, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React.createElement(Text, { color: "#666666", dimColor: true }, isAutoMode ? showBottomHints ? "Ctrl+D to switch modes \u2022 Ctrl+T to auto-approve" : "Ctrl+D to switch modes" : backgroundMode ? "Ctrl+D to switch modes \u2022 Commands run in background" : commandMode ? "Ctrl+D to switch modes \u2022 Tab for autocomplete" : showBottomHints ? "Ctrl+D to switch modes \u2022 Ctrl+T to auto-approve" : "Ctrl+D to switch modes"), /* @__PURE__ */ React.createElement(Box, { gap: 1 }, subAgentCount > 0 && /* @__PURE__ */ React.createElement(Text, { color:
|
|
1857
|
+
/* @__PURE__ */ React.createElement(Box, { marginY: 1, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React.createElement(Text, { color: "#666666", dimColor: true }, isAutoMode ? showBottomHints ? "Ctrl+D to switch modes \u2022 Ctrl+T to auto-approve" : "Ctrl+D to switch modes" : backgroundMode ? "Ctrl+D to switch modes \u2022 Commands run in background" : commandMode ? "Ctrl+D to switch modes \u2022 Tab for autocomplete" : showBottomHints ? "Ctrl+D to switch modes \u2022 Ctrl+T to auto-approve" : "Ctrl+D to switch modes"), /* @__PURE__ */ React.createElement(Box, { gap: 1 }, subAgentCount > 0 && /* @__PURE__ */ React.createElement(Text, { color: theme.accent, bold: true }, "[sub-agent: ", subAgentCount, "]"), backgroundTaskCount > 0 && /* @__PURE__ */ React.createElement(Text, { color: "#9966ff", bold: true }, "[bkg tasks: ", backgroundTaskCount, "]"), !commandMode && !backgroundMode && planMode && /* @__PURE__ */ React.createElement(Text, { color: "#ffaa00", bold: true }, "[PLANNING]"), !commandMode && !backgroundMode && autoAcceptMode ? /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "[AUTO-ACCEPT: ON]") : !commandMode && !backgroundMode ? /* @__PURE__ */ React.createElement(Text, { color: "#666666", dimColor: true }, "[AUTO-ACCEPT: OFF]") : null, !commandMode && !backgroundMode && /* @__PURE__ */ React.createElement(Box, { marginLeft: 1 }, /* @__PURE__ */ React.createElement(
|
|
1655
1858
|
ContextWindowIndicator,
|
|
1656
1859
|
{
|
|
1657
1860
|
currentTokens,
|