centaurus-cli 3.1.3 → 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.
Files changed (138) hide show
  1. package/dist/cli-adapter.js +685 -153
  2. package/dist/cli-adapter.js.map +1 -1
  3. package/dist/config/defaultConfig.js +1 -4
  4. package/dist/config/defaultConfig.js.map +1 -1
  5. package/dist/config/models.js +4 -0
  6. package/dist/config/models.js.map +1 -1
  7. package/dist/config/slash-commands.js +66 -2
  8. package/dist/config/slash-commands.js.map +1 -1
  9. package/dist/config/types.js +4 -4
  10. package/dist/config/types.js.map +1 -1
  11. package/dist/index.js +36 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/services/ai-context-injector.js +109 -0
  14. package/dist/services/ai-context-injector.js.map +1 -1
  15. package/dist/services/api-client.js.map +1 -1
  16. package/dist/services/background-task-manager.js +59 -0
  17. package/dist/services/background-task-manager.js.map +1 -1
  18. package/dist/services/local-chat-storage.js +2 -0
  19. package/dist/services/local-chat-storage.js.map +1 -1
  20. package/dist/services/skill-storage.js +141 -0
  21. package/dist/services/skill-storage.js.map +1 -0
  22. package/dist/services/sub-agent-manager.js +49 -8
  23. package/dist/services/sub-agent-manager.js.map +1 -1
  24. package/dist/services/warpify-detector.js +17 -5
  25. package/dist/services/warpify-detector.js.map +1 -1
  26. package/dist/tools/background-command.js +5 -2
  27. package/dist/tools/background-command.js.map +1 -1
  28. package/dist/tools/command.js +367 -109
  29. package/dist/tools/command.js.map +1 -1
  30. package/dist/tools/file-ops.js +23 -6
  31. package/dist/tools/file-ops.js.map +1 -1
  32. package/dist/tools/plan-mode.js +184 -336
  33. package/dist/tools/plan-mode.js.map +1 -1
  34. package/dist/tools/sub-agent.js +24 -5
  35. package/dist/tools/sub-agent.js.map +1 -1
  36. package/dist/tools/todo-list.js +157 -0
  37. package/dist/tools/todo-list.js.map +1 -0
  38. package/dist/types/skill.js +30 -0
  39. package/dist/types/skill.js.map +1 -0
  40. package/dist/ui/components/App.js +956 -162
  41. package/dist/ui/components/App.js.map +1 -1
  42. package/dist/ui/components/AuthScreen.js +3 -1
  43. package/dist/ui/components/AuthScreen.js.map +1 -1
  44. package/dist/ui/components/AuthWelcomeScreen.js +3 -1
  45. package/dist/ui/components/AuthWelcomeScreen.js.map +1 -1
  46. package/dist/ui/components/CodeBlock.js +3 -1
  47. package/dist/ui/components/CodeBlock.js.map +1 -1
  48. package/dist/ui/components/CompactShellPreview.js +44 -0
  49. package/dist/ui/components/CompactShellPreview.js.map +1 -0
  50. package/dist/ui/components/ConfigViewer.js +3 -1
  51. package/dist/ui/components/ConfigViewer.js.map +1 -1
  52. package/dist/ui/components/ConfirmPrompt.js +3 -1
  53. package/dist/ui/components/ConfirmPrompt.js.map +1 -1
  54. package/dist/ui/components/ConnectionStatusMessage.js +3 -1
  55. package/dist/ui/components/ConnectionStatusMessage.js.map +1 -1
  56. package/dist/ui/components/DetailedPlanReviewScreen.js +84 -74
  57. package/dist/ui/components/DetailedPlanReviewScreen.js.map +1 -1
  58. package/dist/ui/components/DiffViewer.js +6 -3
  59. package/dist/ui/components/DiffViewer.js.map +1 -1
  60. package/dist/ui/components/FileCreationPreview.js.map +1 -1
  61. package/dist/ui/components/FileTagAutocomplete.js +4 -2
  62. package/dist/ui/components/FileTagAutocomplete.js.map +1 -1
  63. package/dist/ui/components/InputBox.js +243 -40
  64. package/dist/ui/components/InputBox.js.map +1 -1
  65. package/dist/ui/components/InteractiveShell.js +5 -3
  66. package/dist/ui/components/InteractiveShell.js.map +1 -1
  67. package/dist/ui/components/KeyboardHelp.js +4 -1
  68. package/dist/ui/components/KeyboardHelp.js.map +1 -1
  69. package/dist/ui/components/LoadingIndicator.js +3 -1
  70. package/dist/ui/components/LoadingIndicator.js.map +1 -1
  71. package/dist/ui/components/MCPAddScreen.js +63 -13
  72. package/dist/ui/components/MCPAddScreen.js.map +1 -1
  73. package/dist/ui/components/MarkdownRenderer.js +3 -1
  74. package/dist/ui/components/MarkdownRenderer.js.map +1 -1
  75. package/dist/ui/components/MessageDisplay.js +9 -7
  76. package/dist/ui/components/MessageDisplay.js.map +1 -1
  77. package/dist/ui/components/ModelPicker.js +170 -0
  78. package/dist/ui/components/ModelPicker.js.map +1 -0
  79. package/dist/ui/components/MonitorModeAIPanel.js +3 -1
  80. package/dist/ui/components/MonitorModeAIPanel.js.map +1 -1
  81. package/dist/ui/components/PlanAcceptedMessage.js +12 -6
  82. package/dist/ui/components/PlanAcceptedMessage.js.map +1 -1
  83. package/dist/ui/components/PlanQuestionMessage.js +37 -0
  84. package/dist/ui/components/PlanQuestionMessage.js.map +1 -0
  85. package/dist/ui/components/PlanQuestionScreen.js +138 -0
  86. package/dist/ui/components/PlanQuestionScreen.js.map +1 -0
  87. package/dist/ui/components/PlanReviewScreen.js +7 -9
  88. package/dist/ui/components/PlanReviewScreen.js.map +1 -1
  89. package/dist/ui/components/RulesEditorScreen.js +65 -28
  90. package/dist/ui/components/RulesEditorScreen.js.map +1 -1
  91. package/dist/ui/components/SelectPrompt.js +3 -1
  92. package/dist/ui/components/SelectPrompt.js.map +1 -1
  93. package/dist/ui/components/SkillCreatorScreen.js +217 -0
  94. package/dist/ui/components/SkillCreatorScreen.js.map +1 -0
  95. package/dist/ui/components/SlashCommandAutocomplete.js +4 -2
  96. package/dist/ui/components/SlashCommandAutocomplete.js.map +1 -1
  97. package/dist/ui/components/StatusBar.js +4 -2
  98. package/dist/ui/components/StatusBar.js.map +1 -1
  99. package/dist/ui/components/StreamingMessageDisplay.js +5 -3
  100. package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
  101. package/dist/ui/components/SubAgentListScreen.js +65 -0
  102. package/dist/ui/components/SubAgentListScreen.js.map +1 -0
  103. package/dist/ui/components/SubAgentViewScreen.js +123 -0
  104. package/dist/ui/components/SubAgentViewScreen.js.map +1 -0
  105. package/dist/ui/components/TaskCompletedMessage.js +40 -8
  106. package/dist/ui/components/TaskCompletedMessage.js.map +1 -1
  107. package/dist/ui/components/TaskProgressIndicator.js +6 -4
  108. package/dist/ui/components/TaskProgressIndicator.js.map +1 -1
  109. package/dist/ui/components/TextEditor.js +297 -0
  110. package/dist/ui/components/TextEditor.js.map +1 -0
  111. package/dist/ui/components/TodoListMessage.js +59 -0
  112. package/dist/ui/components/TodoListMessage.js.map +1 -0
  113. package/dist/ui/components/ToolExecutionMessage.js +134 -84
  114. package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
  115. package/dist/ui/components/ToolExecutionStatus.js +3 -1
  116. package/dist/ui/components/ToolExecutionStatus.js.map +1 -1
  117. package/dist/ui/components/WelcomeBanner.js +33 -33
  118. package/dist/ui/components/WelcomeBanner.js.map +1 -1
  119. package/dist/ui/components/WorkflowCreatorScreen.js +5 -3
  120. package/dist/ui/components/WorkflowCreatorScreen.js.map +1 -1
  121. package/dist/ui/theme.js +97 -0
  122. package/dist/ui/theme.js.map +1 -0
  123. package/dist/ui/utils/chat-history-limit.js +247 -0
  124. package/dist/ui/utils/chat-history-limit.js.map +1 -0
  125. package/dist/utils/chat-formatter.js +22 -9
  126. package/dist/utils/chat-formatter.js.map +1 -1
  127. package/dist/utils/input-classifier.js +11 -1
  128. package/dist/utils/input-classifier.js.map +1 -1
  129. package/dist/utils/output-truncation.js +175 -0
  130. package/dist/utils/output-truncation.js.map +1 -0
  131. package/dist/utils/rule-reference-resolver.js +3 -3
  132. package/dist/utils/rule-reference-resolver.js.map +1 -1
  133. package/dist/utils/tunnel-commands-manager.js +134 -0
  134. package/dist/utils/tunnel-commands-manager.js.map +1 -0
  135. package/package.json +91 -90
  136. package/postinstall.js +4 -11
  137. package/dist/ui/components/MultiLineInput.js +0 -255
  138. 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 (/[\s\n]/.test(char)) break;
643
+ if (char === '"' && i > 0 && value[i - 1] === "@") {
644
+ atPosition = i - 1;
645
+ isQuoted = true;
646
+ break;
647
+ }
600
648
  if (char === "@") {
601
- atPosition = i;
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
- const query = value.slice(atPosition + 1, cursorOffset);
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 baseValue = beforeTag + "@" + selected.insertText;
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 + 1 + selected.insertText.length;
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 + 1 + selected.insertText.length;
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 + 1 + selected.insertText.length + trailingSuffix.length;
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 + 1 + selected.insertText.length,
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 isAltV = key.meta && input === "v" || input === "\u221A";
985
- if (isAltV && !commandMode) {
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(`Alt+V: Rejected file paste, limit exceeded (${currentCount} + ${newCount} > 5)`);
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(`Alt+V: Found ${files.length} file(s) in clipboard, adding to input`);
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("Alt+V: No file in clipboard");
1152
+ logDebug("Ctrl+V: No file in clipboard");
1006
1153
  }
1007
1154
  } catch (error) {
1008
- logDebug(`Alt+V: Failed to check clipboard: ${error instanceof Error ? error.message : "Unknown error"}`);
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
- const isAltX = key.meta && input === "x" || input === "\u2248";
1014
- if (isAltX && !commandMode) {
1015
- if (confirmedClipboardFiles.length > 0) {
1016
- logDebug(`Alt+X: Removing last attached file`);
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
- return;
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: "#00ccff", bold: true }, char);
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" : "#257aa5ff"
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: "#666666" }, "CWD: "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true, wrap: "truncate-start" }, currentDir), gitDiffStats && (gitDiffStats.additions > 0 || gitDiffStats.deletions > 0) && /* @__PURE__ */ React.createElement(
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: "#00ccff" }, 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: "#00ccff", bold: true }, "Auto ["), detectedIntent === "command" ? /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "Terminal") : /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, "Agent"), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", 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: "#00ccff" }, "Agent"))))),
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: "#00ccff", 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(
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,