centaurus-cli 2.8.7 → 2.8.9

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 (92) hide show
  1. package/dist/cli-adapter.d.ts +61 -0
  2. package/dist/cli-adapter.d.ts.map +1 -1
  3. package/dist/cli-adapter.js +324 -29
  4. package/dist/cli-adapter.js.map +1 -1
  5. package/dist/config/ConfigManager.d.ts.map +1 -1
  6. package/dist/config/ConfigManager.js +6 -5
  7. package/dist/config/ConfigManager.js.map +1 -1
  8. package/dist/config/build-config.d.ts +42 -0
  9. package/dist/config/build-config.d.ts.map +1 -0
  10. package/dist/config/build-config.js +44 -0
  11. package/dist/config/build-config.js.map +1 -0
  12. package/dist/config/manager.d.ts +2 -2
  13. package/dist/config/manager.d.ts.map +1 -1
  14. package/dist/config/manager.js +9 -12
  15. package/dist/config/manager.js.map +1 -1
  16. package/dist/config/mcp-config-manager.d.ts +5 -0
  17. package/dist/config/mcp-config-manager.d.ts.map +1 -1
  18. package/dist/config/mcp-config-manager.js +17 -8
  19. package/dist/config/mcp-config-manager.js.map +1 -1
  20. package/dist/config/models.d.ts +40 -42
  21. package/dist/config/models.d.ts.map +1 -1
  22. package/dist/config/models.js +116 -130
  23. package/dist/config/models.js.map +1 -1
  24. package/dist/config/slash-commands.d.ts +1 -0
  25. package/dist/config/slash-commands.d.ts.map +1 -1
  26. package/dist/config/slash-commands.js +21 -0
  27. package/dist/config/slash-commands.js.map +1 -1
  28. package/dist/context/context-manager.d.ts.map +1 -1
  29. package/dist/context/context-manager.js +6 -6
  30. package/dist/context/context-manager.js.map +1 -1
  31. package/dist/index.d.ts +6 -0
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +64 -28
  34. package/dist/index.js.map +1 -1
  35. package/dist/mcp/mcp-command-handler.d.ts.map +1 -1
  36. package/dist/mcp/mcp-command-handler.js +5 -3
  37. package/dist/mcp/mcp-command-handler.js.map +1 -1
  38. package/dist/mcp/mcp-server-manager.d.ts.map +1 -1
  39. package/dist/mcp/mcp-server-manager.js +5 -3
  40. package/dist/mcp/mcp-server-manager.js.map +1 -1
  41. package/dist/services/ai-service-client.d.ts.map +1 -1
  42. package/dist/services/ai-service-client.js +8 -6
  43. package/dist/services/ai-service-client.js.map +1 -1
  44. package/dist/services/api-client.d.ts +26 -0
  45. package/dist/services/api-client.d.ts.map +1 -1
  46. package/dist/services/api-client.js +19 -7
  47. package/dist/services/api-client.js.map +1 -1
  48. package/dist/services/background-task-manager.d.ts +114 -0
  49. package/dist/services/background-task-manager.d.ts.map +1 -0
  50. package/dist/services/background-task-manager.js +301 -0
  51. package/dist/services/background-task-manager.js.map +1 -0
  52. package/dist/services/local-chat-storage.d.ts.map +1 -1
  53. package/dist/services/local-chat-storage.js +5 -4
  54. package/dist/services/local-chat-storage.js.map +1 -1
  55. package/dist/tools/web-search.d.ts.map +1 -1
  56. package/dist/tools/web-search.js +8 -6
  57. package/dist/tools/web-search.js.map +1 -1
  58. package/dist/ui/components/App.d.ts +31 -0
  59. package/dist/ui/components/App.d.ts.map +1 -1
  60. package/dist/ui/components/App.js +290 -50
  61. package/dist/ui/components/App.js.map +1 -1
  62. package/dist/ui/components/ErrorBoundary.d.ts.map +1 -1
  63. package/dist/ui/components/ErrorBoundary.js +2 -1
  64. package/dist/ui/components/ErrorBoundary.js.map +1 -1
  65. package/dist/ui/components/InputBox.d.ts +6 -0
  66. package/dist/ui/components/InputBox.d.ts.map +1 -1
  67. package/dist/ui/components/InputBox.js +121 -20
  68. package/dist/ui/components/InputBox.js.map +1 -1
  69. package/dist/ui/components/ToolExecutionMessage.js +2 -2
  70. package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
  71. package/dist/ui/components/VersionUpdatePrompt.d.ts +1 -2
  72. package/dist/ui/components/VersionUpdatePrompt.d.ts.map +1 -1
  73. package/dist/ui/components/VersionUpdatePrompt.js +108 -27
  74. package/dist/ui/components/VersionUpdatePrompt.js.map +1 -1
  75. package/dist/utils/command-history.d.ts.map +1 -1
  76. package/dist/utils/command-history.js +2 -1
  77. package/dist/utils/command-history.js.map +1 -1
  78. package/dist/utils/conversation-logger.d.ts +15 -0
  79. package/dist/utils/conversation-logger.d.ts.map +1 -1
  80. package/dist/utils/conversation-logger.js +56 -2
  81. package/dist/utils/conversation-logger.js.map +1 -1
  82. package/dist/utils/editor-utils.d.ts.map +1 -1
  83. package/dist/utils/editor-utils.js +3 -2
  84. package/dist/utils/editor-utils.js.map +1 -1
  85. package/dist/utils/input-classifier.d.ts.map +1 -1
  86. package/dist/utils/input-classifier.js +2 -1
  87. package/dist/utils/input-classifier.js.map +1 -1
  88. package/dist/utils/logger.d.ts.map +1 -1
  89. package/dist/utils/logger.js +31 -1
  90. package/dist/utils/logger.js.map +1 -1
  91. package/package.json +1 -2
  92. package/models-config.json +0 -126
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../src/ui/components/App.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../src/ui/components/App.tsx"],"names":[],"mappings":"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"}
@@ -2,8 +2,7 @@ import React, { useState, useCallback } from 'react';
2
2
  import { Box, Text, useApp, useInput, Static } from 'ink';
3
3
  import SelectInput from 'ink-select-input';
4
4
  import TextInput from 'ink-text-input';
5
- import { spawn } from 'child_process';
6
- import * as fs from 'fs';
5
+ import { quickLog } from '../../utils/conversation-logger.js';
7
6
  import { WelcomeBanner } from './WelcomeBanner.js';
8
7
  import { InputBox } from './InputBox.js';
9
8
  import { MessageDisplay, countImagesInMessage } from './MessageDisplay.js';
@@ -24,6 +23,7 @@ import { DetailedPlanReviewScreen } from './DetailedPlanReviewScreen.js';
24
23
  import { TaskCompletedMessage } from './TaskCompletedMessage.js';
25
24
  import { PlanAcceptedMessage } from './PlanAcceptedMessage.js';
26
25
  import { processTerminalOutput } from '../../utils/terminal-output.js';
26
+ import { BackgroundTaskManager } from '../../services/background-task-manager.js';
27
27
  import { apiClient } from '../../services/api-client.js';
28
28
  import { conversationManager } from '../../services/conversation-manager.js';
29
29
  import { logDebug, logError } from '../../utils/logger.js';
@@ -136,9 +136,10 @@ const RenameInputScreen = ({ currentTitle, onRename, onCancel }) => {
136
136
  React.createElement(Box, { marginTop: 1 },
137
137
  React.createElement(Text, { dimColor: true }, "Press Enter to save, ESC to cancel"))));
138
138
  };
139
- export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode, onResponseReceived, onDirectMessage, onResponseStream, onThoughtStream, onThoughtComplete, onPickerSetup, onPickerSelection, onToolExecutionUpdate, onToolApprovalRequest, onToolStreamingOutput, onPlanModeChange, onPlanApprovalRequest, onPlanCreated, onTaskCompleted, onCommandModeChange, onToggleCommandMode, onCwdChange, onModelChange, onSubshellContextChange, onPasswordRequest, onShellInput, onShellSignal, onKillProcess, onInteractiveEditorMode, onConnectionStatusUpdate, onChatPickerSetup, onChatPickerSelection, onChatDeletePickerSetup, onChatDeletePickerSelection, onChatListSetup, onChatRenamePickerSetup, onChatRename, onRestoreMessagesSetup, onUIMessageHistoryUpdate }) => {
139
+ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode, onResponseReceived, onDirectMessage, onResponseStream, onThoughtStream, onThoughtComplete, onPickerSetup, onPickerSelection, onToolExecutionUpdate, onToolApprovalRequest, onToolStreamingOutput, onPlanModeChange, onPlanApprovalRequest, onPlanCreated, onTaskCompleted, onCommandModeChange, onToggleCommandMode, onBackgroundModeChange, onToggleBackgroundMode, onBackgroundTaskCountChange, onSetAutoModeSetup, onCwdChange, onModelChange, onSubshellContextChange, onPasswordRequest, onShellInput, onShellSignal, onKillProcess, onInteractiveEditorMode, onConnectionStatusUpdate, onChatPickerSetup, onChatPickerSelection, onChatDeletePickerSetup, onChatDeletePickerSelection, onChatListSetup, onChatRenamePickerSetup, onChatRename, onRestoreMessagesSetup, onUIMessageHistoryUpdate, onBackgroundTaskListSetup, onBackgroundTaskSelection, onBackgroundTaskCancelSetup, onBackgroundTaskCancel, onBackgroundTaskViewSetup }) => {
140
140
  const { exit } = useApp();
141
141
  const autoAcceptRef = React.useRef(false);
142
+ const setAutoModeCallbackRef = React.useRef(null);
142
143
  // Helper to clear screen
143
144
  const clearScreen = useCallback(() => {
144
145
  process.stdout.write('\x1b[2J\x1b[3J\x1b[H');
@@ -183,6 +184,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
183
184
  currentModel: initialModel || 'gemini-2.5-flash',
184
185
  planMode: initialPlanMode || false,
185
186
  commandMode: false,
187
+ backgroundMode: false,
186
188
  currentWorkingDirectory: process.cwd(),
187
189
  showExitWarning: false,
188
190
  commandHistory: [],
@@ -199,6 +201,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
199
201
  planApprovalRequest: undefined,
200
202
  passwordRequest: undefined,
201
203
  connectionStatus: undefined,
204
+ backgroundTaskCount: 0,
202
205
  });
203
206
  // Track last terminal width to detect actual width changes
204
207
  const lastTerminalWidthRef = React.useRef(process.stdout.columns || 80);
@@ -209,6 +212,9 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
209
212
  const savedCurrentRef = React.useRef(null);
210
213
  // Debounce timer ref
211
214
  const resizeDebounceRef = React.useRef(null);
215
+ // Preserve input text across screen transitions (approval screens, etc.)
216
+ // Using ref to avoid re-renders when value changes
217
+ const preservedInputTextRef = React.useRef('');
212
218
  // Handle terminal resize events using the same logic as /clean-ui command
213
219
  // Uses debounce to wait until width is stable before triggering clean-ui
214
220
  React.useEffect(() => {
@@ -385,7 +391,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
385
391
  onThoughtStream((thought) => {
386
392
  // Debug logging to file
387
393
  try {
388
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Received thought chunk (${thought.length} chars): ${thought.substring(0, 100)}\n`);
394
+ quickLog(`[${new Date().toISOString()}] [App] Received thought chunk (${thought.length} chars): ${thought.substring(0, 100)}\n`);
389
395
  }
390
396
  catch (e) {
391
397
  // Ignore logging errors
@@ -404,7 +410,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
404
410
  (prev.currentMessage.thinkingDuration !== undefined && !isThoughtOnlyMessage);
405
411
  if (needsNewMessage) {
406
412
  try {
407
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Creating new assistant message for thoughts (reason: ${!prev.currentMessage ? 'no current' : prev.currentMessage.role !== 'assistant' ? 'not assistant' : 'has thinkingDuration'})\n`);
413
+ quickLog(`[${new Date().toISOString()}] [App] Creating new assistant message for thoughts (reason: ${!prev.currentMessage ? 'no current' : prev.currentMessage.role !== 'assistant' ? 'not assistant' : 'has thinkingDuration'})\n`);
408
414
  }
409
415
  catch (e) {
410
416
  // Ignore logging errors
@@ -443,7 +449,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
443
449
  // (don't accumulate - the tool will handle displaying)
444
450
  if (isThoughtOnlyMessage) {
445
451
  try {
446
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Skipping thought chunk - current is thought-only message waiting for tool\n`);
452
+ quickLog(`[${new Date().toISOString()}] [App] Skipping thought chunk - current is thought-only message waiting for tool\n`);
447
453
  }
448
454
  catch (e) { }
449
455
  return prev;
@@ -455,7 +461,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
455
461
  const allLines = thoughtAccumulatorRef.current.split('\n').filter(line => line.trim());
456
462
  const last3Lines = allLines.slice(-3);
457
463
  try {
458
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Accumulated ${allLines.length} total lines, showing last 3: ${JSON.stringify(last3Lines)}\n`);
464
+ quickLog(`[${new Date().toISOString()}] [App] Accumulated ${allLines.length} total lines, showing last 3: ${JSON.stringify(last3Lines)}\n`);
459
465
  }
460
466
  catch (e) {
461
467
  // Ignore logging errors
@@ -475,7 +481,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
475
481
  React.useEffect(() => {
476
482
  onThoughtComplete((durationSeconds) => {
477
483
  try {
478
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] onThoughtComplete called with ${durationSeconds}s\n`);
484
+ quickLog(`[${new Date().toISOString()}] [App] onThoughtComplete called with ${durationSeconds}s\n`);
479
485
  }
480
486
  catch (e) {
481
487
  // Ignore
@@ -486,7 +492,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
486
492
  // Only update if we have a current assistant message
487
493
  if (!prev.currentMessage || prev.currentMessage.role !== 'assistant') {
488
494
  try {
489
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] No current assistant message for thought completion\n`);
495
+ quickLog(`[${new Date().toISOString()}] [App] No current assistant message for thought completion\n`);
490
496
  }
491
497
  catch (e) {
492
498
  // Ignore
@@ -494,7 +500,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
494
500
  return prev;
495
501
  }
496
502
  try {
497
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Setting thinkingDuration to ${durationSeconds}s on message ${prev.currentMessage.id}\n`);
503
+ quickLog(`[${new Date().toISOString()}] [App] Setting thinkingDuration to ${durationSeconds}s on message ${prev.currentMessage.id}\n`);
498
504
  }
499
505
  catch (e) {
500
506
  // Ignore
@@ -591,7 +597,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
591
597
  // (meaning the message was moved to history mid-stream)
592
598
  if (lastAssistant.content.length < message.length) {
593
599
  try {
594
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] onResponseReceived: Updating history assistant message from ${lastAssistant.content.length} chars to ${message.length} chars\n`);
600
+ quickLog(`[${new Date().toISOString()}] [App] onResponseReceived: Updating history assistant message from ${lastAssistant.content.length} chars to ${message.length} chars\n`);
595
601
  }
596
602
  catch (e) { }
597
603
  const updatedHistory = [...prev.messageHistory];
@@ -733,6 +739,33 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
733
739
  }));
734
740
  });
735
741
  }, []); // Empty dependency array - only register once
742
+ // Set up callback for background mode change
743
+ React.useEffect(() => {
744
+ onBackgroundModeChange((backgroundMode) => {
745
+ setState(prev => ({
746
+ ...prev,
747
+ backgroundMode
748
+ }));
749
+ });
750
+ }, []); // Empty dependency array - only register once
751
+ // Set up callback for background task count change
752
+ React.useEffect(() => {
753
+ onBackgroundTaskCountChange((count) => {
754
+ setState(prev => ({
755
+ ...prev,
756
+ backgroundTaskCount: count
757
+ }));
758
+ });
759
+ }, []); // Empty dependency array - only register once
760
+ // Set up callback for setting Auto mode (used after background task starts)
761
+ React.useEffect(() => {
762
+ onSetAutoModeSetup((enabled) => {
763
+ // Call the InputBox's setAutoMode callback if registered
764
+ if (setAutoModeCallbackRef.current) {
765
+ setAutoModeCallbackRef.current(enabled);
766
+ }
767
+ });
768
+ }, []); // Empty dependency array - only register once
736
769
  // Set up callback for message restoration (when resuming a chat)
737
770
  React.useEffect(() => {
738
771
  onRestoreMessagesSetup((restoredMessages) => {
@@ -746,6 +779,121 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
746
779
  }));
747
780
  });
748
781
  }, []); // Empty dependency array - only register once
782
+ // Set up callback for background task list picker
783
+ React.useEffect(() => {
784
+ onBackgroundTaskListSetup((tasks) => {
785
+ clearScreen();
786
+ setState(prev => ({
787
+ ...prev,
788
+ screen: 'background-task-list',
789
+ backgroundTasks: tasks,
790
+ isLoading: false
791
+ }));
792
+ });
793
+ }, []); // Empty dependency array - only register once
794
+ // Set up callback for background task cancel picker
795
+ React.useEffect(() => {
796
+ onBackgroundTaskCancelSetup((tasks) => {
797
+ clearScreen();
798
+ setState(prev => ({
799
+ ...prev,
800
+ screen: 'background-task-cancel',
801
+ backgroundTasks: tasks,
802
+ isLoading: false
803
+ }));
804
+ });
805
+ }, []); // Empty dependency array - only register once
806
+ // Set up callback for viewing a background task in focus mode (live streaming shell)
807
+ React.useEffect(() => {
808
+ onBackgroundTaskViewSetup((task) => {
809
+ clearScreen();
810
+ // Set up shell state for the background task - this displays in InteractiveShell
811
+ // isFocused: true to start directly in focus mode
812
+ // isBackgroundTask: true to prevent adding to history on exit
813
+ setState(prev => ({
814
+ ...prev,
815
+ screen: 'chat',
816
+ shellState: {
817
+ command: `[Background Task] ${task.command}`,
818
+ cwd: task.cwd,
819
+ output: task.output,
820
+ isRunning: task.isRunning,
821
+ exitCode: undefined,
822
+ error: undefined,
823
+ isFocused: true, // Start directly in focus mode
824
+ remoteContext: undefined,
825
+ isBackgroundTask: true, // Flag to prevent history addition
826
+ backgroundTaskId: task.id // Store task ID for input routing
827
+ },
828
+ isLoading: false,
829
+ isAiWorking: false // Don't show AI working for background tasks
830
+ }));
831
+ // Subscribe to output updates - append to shell output
832
+ task.onOutput((chunk) => {
833
+ setState(prev => {
834
+ if (!prev.shellState || !prev.shellState.isBackgroundTask)
835
+ return prev;
836
+ return {
837
+ ...prev,
838
+ shellState: {
839
+ ...prev.shellState,
840
+ output: prev.shellState.output + chunk
841
+ }
842
+ };
843
+ });
844
+ });
845
+ // Subscribe to task completion
846
+ task.onComplete((exitCode) => {
847
+ // Debug logging
848
+ try {
849
+ quickLog(`[${new Date().toISOString()}] [App.tsx] task.onComplete called: exitCode=${exitCode}\n`);
850
+ }
851
+ catch (e) { }
852
+ setState(prev => {
853
+ // If user already exited focus mode, don't do anything
854
+ if (!prev.shellState || !prev.shellState.isBackgroundTask) {
855
+ try {
856
+ quickLog(`[${new Date().toISOString()}] [App.tsx] task.onComplete: shellState not active, ignoring\n`);
857
+ }
858
+ catch (e) { }
859
+ return prev;
860
+ }
861
+ // Task completed - mark as done and update display
862
+ try {
863
+ quickLog(`[${new Date().toISOString()}] [App.tsx] task.onComplete: marking task as complete\n`);
864
+ }
865
+ catch (e) { }
866
+ return {
867
+ ...prev,
868
+ shellState: {
869
+ ...prev.shellState,
870
+ isRunning: false,
871
+ exitCode
872
+ }
873
+ };
874
+ });
875
+ // After a brief delay, automatically return to chat
876
+ // This gives the user time to see the final output
877
+ setTimeout(() => {
878
+ try {
879
+ quickLog(`[${new Date().toISOString()}] [App.tsx] task.onComplete: clearing shellState to return to chat\n`);
880
+ }
881
+ catch (e) { }
882
+ clearScreen();
883
+ setState(prev => {
884
+ // Only clear if still showing this background task
885
+ if (prev.shellState?.isBackgroundTask) {
886
+ return {
887
+ ...prev,
888
+ shellState: undefined
889
+ };
890
+ }
891
+ return prev;
892
+ });
893
+ }, 500); // 500ms delay to see final output
894
+ });
895
+ });
896
+ }, []); // Empty dependency array - only register once
749
897
  // Sync UI message history to CLI adapter whenever it changes
750
898
  React.useEffect(() => {
751
899
  onUIMessageHistoryUpdate(state.messageHistory);
@@ -756,7 +904,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
756
904
  // Special handling for execute_command
757
905
  if (update.toolName === 'execute_command') {
758
906
  try {
759
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] execute_command update: ${JSON.stringify(update)}\n`);
907
+ quickLog(`[${new Date().toISOString()}] [App] execute_command update: ${JSON.stringify(update)}\n`);
760
908
  }
761
909
  catch (e) { }
762
910
  // STARTING EXECUTION
@@ -895,10 +1043,10 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
895
1043
  setState(prev => {
896
1044
  // Debug logging to trace tool display issues
897
1045
  try {
898
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] onToolExecutionUpdate setState - toolName: ${update.toolName}, status: ${update.status}\n`);
899
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Current state: screen=${prev.screen}, currentMessage.role=${prev.currentMessage?.role}, currentMessage.id=${prev.currentMessage?.id}, historyLen=${prev.messageHistory.length}\n`);
1046
+ quickLog(`[${new Date().toISOString()}] [App] onToolExecutionUpdate setState - toolName: ${update.toolName}, status: ${update.status}\n`);
1047
+ quickLog(`[${new Date().toISOString()}] [App] Current state: screen=${prev.screen}, currentMessage.role=${prev.currentMessage?.role}, currentMessage.id=${prev.currentMessage?.id}, historyLen=${prev.messageHistory.length}\n`);
900
1048
  if (prev.currentMessage?.thinkingDuration !== undefined) {
901
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Current message has thinkingDuration: ${prev.currentMessage.thinkingDuration}s\n`);
1049
+ quickLog(`[${new Date().toISOString()}] [App] Current message has thinkingDuration: ${prev.currentMessage.thinkingDuration}s\n`);
902
1050
  }
903
1051
  }
904
1052
  catch (e) { }
@@ -909,7 +1057,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
909
1057
  // Only track completed tools, skip executing tools (they need approval flow)
910
1058
  if (update.status === 'completed' || update.status === 'error') {
911
1059
  try {
912
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Tool ${update.toolName} completed while on ${prev.screen} screen, adding to history\n`);
1060
+ quickLog(`[${new Date().toISOString()}] [App] Tool ${update.toolName} completed while on ${prev.screen} screen, adding to history\n`);
913
1061
  }
914
1062
  catch (e) { }
915
1063
  // Add completed tool directly to history
@@ -943,7 +1091,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
943
1091
  // Tool completed - move to history with updated status
944
1092
  // Note: We now match ANY executing tool, not just same toolName (handles overlapping tools)
945
1093
  try {
946
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Tool ${update.toolName} completed, moving current tool to history\n`);
1094
+ quickLog(`[${new Date().toISOString()}] [App] Tool ${update.toolName} completed, moving current tool to history\n`);
947
1095
  }
948
1096
  catch (e) { }
949
1097
  const completedToolMessage = {
@@ -961,7 +1109,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
961
1109
  // This ensures thought-only messages stay as currentMessage until executing arrives
962
1110
  if (update.status === 'pending') {
963
1111
  try {
964
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Tool ${update.toolName} pending - skipping state modification, waiting for executing\n`);
1112
+ quickLog(`[${new Date().toISOString()}] [App] Tool ${update.toolName} pending - skipping state modification, waiting for executing\n`);
965
1113
  }
966
1114
  catch (e) { }
967
1115
  return prev; // Return unchanged state
@@ -980,13 +1128,13 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
980
1128
  // Carry the thinkingDuration to the tool message, don't add empty message to history
981
1129
  pendingThinkingDuration = prev.currentMessage.thinkingDuration;
982
1130
  try {
983
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Found thought-only message, saving thinkingDuration ${pendingThinkingDuration}s for tool ${update.toolName}\n`);
1131
+ quickLog(`[${new Date().toISOString()}] [App] Found thought-only message, saving thinkingDuration ${pendingThinkingDuration}s for tool ${update.toolName}\n`);
984
1132
  }
985
1133
  catch (e) { }
986
1134
  }
987
1135
  else {
988
1136
  try {
989
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Moving current message (${prev.currentMessage.role}) to history for new tool ${update.toolName}\n`);
1137
+ quickLog(`[${new Date().toISOString()}] [App] Moving current message (${prev.currentMessage.role}) to history for new tool ${update.toolName}\n`);
990
1138
  }
991
1139
  catch (e) { }
992
1140
  // Move ANY current message to history before showing tool
@@ -1008,7 +1156,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
1008
1156
  }
1009
1157
  // For completed tools without a current executing one (edge case)
1010
1158
  try {
1011
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Tool ${update.toolName} completed without current executing tool, adding to history\n`);
1159
+ quickLog(`[${new Date().toISOString()}] [App] Tool ${update.toolName} completed without current executing tool, adding to history\n`);
1012
1160
  }
1013
1161
  catch (e) { }
1014
1162
  let newHistory = prev.messageHistory;
@@ -1263,7 +1411,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
1263
1411
  // The plan will be displayed via the plan-approval screen
1264
1412
  // This callback can be used for additional notifications if needed
1265
1413
  try {
1266
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Plan created: ${plan.title} with ${plan.steps.length} tasks\n`);
1414
+ quickLog(`[${new Date().toISOString()}] [App] Plan created: ${plan.title} with ${plan.steps.length} tasks\n`);
1267
1415
  }
1268
1416
  catch (e) { }
1269
1417
  });
@@ -1372,7 +1520,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
1372
1520
  }
1373
1521
  else {
1374
1522
  // Fallback if no client available
1375
- console.error('SSH client not available for editor mode');
1523
+ logError('SSH client not available for editor mode', new Error('No SSH client'));
1376
1524
  setState(prev => ({ ...prev, isInteractiveEditorMode: false }));
1377
1525
  }
1378
1526
  }
@@ -1754,6 +1902,10 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
1754
1902
  autoAcceptMode: !prev.autoAcceptMode
1755
1903
  }));
1756
1904
  }, []);
1905
+ // Handler for preserving input text across screen transitions
1906
+ const handleInputValueChange = useCallback((value) => {
1907
+ preservedInputTextRef.current = value;
1908
+ }, []);
1757
1909
  // If in interactive editor mode, render minimal UI to keep Ink mounted
1758
1910
  // but don't render any visible content - the editor has the screen
1759
1911
  if (state.isInteractiveEditorMode) {
@@ -1763,11 +1915,34 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
1763
1915
  state.screen === 'chat' && (React.createElement(React.Fragment, null,
1764
1916
  !state.shellState?.isFocused && (React.createElement(MessageList, { history: state.messageHistory, current: state.currentMessage, showBanner: true })),
1765
1917
  state.shellState && (getTerminalDimensions().shouldEnableStreaming || !state.shellState.isRunning) && (React.createElement(InteractiveShell, { command: state.shellState.command, cwd: state.shellState.cwd, isRunning: state.shellState.isRunning, output: state.shellState.output, exitCode: state.shellState.exitCode, error: state.shellState.error, isFocused: state.shellState.isFocused, onResize: state.shellState.onResize, remoteContext: state.shellState.remoteContext, onInput: (input) => {
1918
+ // Debug logging
1919
+ try {
1920
+ quickLog(`[${new Date().toISOString()}] [App.tsx onInput] input: ${JSON.stringify(input)}, isBackgroundTask: ${state.shellState?.isBackgroundTask}, backgroundTaskId: ${state.shellState?.backgroundTaskId}\n`);
1921
+ }
1922
+ catch (e) { }
1923
+ // Check if this is a background task
1924
+ if (state.shellState?.isBackgroundTask && state.shellState?.backgroundTaskId) {
1925
+ // Route input to background task
1926
+ BackgroundTaskManager.sendInput(state.shellState.backgroundTaskId, input);
1927
+ return;
1928
+ }
1766
1929
  // PTY MODE: Send everything immediately
1767
1930
  onShellInput(input);
1768
1931
  }, onFocusChange: (focused) => {
1769
1932
  // Clear screen when entering/exiting focus mode
1770
1933
  clearScreen();
1934
+ // Special handling for background tasks
1935
+ if (!focused && state.shellState?.isBackgroundTask) {
1936
+ // Exiting focus mode for a background task:
1937
+ // Just clear shellState and return to chat, no history message
1938
+ // The task continues running in background
1939
+ setState(prev => ({
1940
+ ...prev,
1941
+ shellState: undefined // Clear completely, no preview
1942
+ }));
1943
+ return;
1944
+ }
1945
+ // Normal shell focus change
1771
1946
  setState(prev => ({
1772
1947
  ...prev,
1773
1948
  shellState: prev.shellState ? {
@@ -1776,6 +1951,15 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
1776
1951
  } : undefined
1777
1952
  }));
1778
1953
  }, onSignal: (signal) => {
1954
+ // Check if this is a background task
1955
+ if (state.shellState?.isBackgroundTask && state.shellState?.backgroundTaskId) {
1956
+ // Route signal to background task
1957
+ const nodeSignal = signal === 'SIGINT' ? 'SIGINT' :
1958
+ signal === 'SIGTERM' ? 'SIGTERM' :
1959
+ signal === 'SIGKILL' ? 'SIGKILL' : 'SIGINT';
1960
+ BackgroundTaskManager.sendSignal(state.shellState.backgroundTaskId, nodeSignal);
1961
+ return;
1962
+ }
1779
1963
  onShellSignal(signal);
1780
1964
  } })),
1781
1965
  state.isAiWorking && !state.shellState && !state.approvalRequest &&
@@ -1787,7 +1971,13 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
1787
1971
  if (resolve) {
1788
1972
  resolve(approved);
1789
1973
  }
1790
- } })) : (React.createElement(InputBox, { key: "input-box", onSubmit: handleSubmit, autoAcceptMode: state.autoAcceptMode, model: state.currentModel, planMode: state.planMode, commandMode: state.commandMode, currentWorkingDirectory: state.currentWorkingDirectory, commandHistory: state.commandHistory, onToggleAutoAccept: handleToggleAutoAccept, onToggleCommandMode: onToggleCommandMode, isActive: true, subshellContext: state.subshellContext, currentTokens: state.currentTokens, maxTokens: state.maxTokens, isShellRunning: state.shellState?.isRunning }))),
1974
+ } })) : (React.createElement(InputBox, { key: "input-box", onSubmit: (value, clipboardImages) => {
1975
+ // Clear preserved input on submit
1976
+ preservedInputTextRef.current = '';
1977
+ handleSubmit(value, clipboardImages);
1978
+ }, autoAcceptMode: state.autoAcceptMode, model: state.currentModel, planMode: state.planMode, commandMode: state.commandMode, backgroundMode: state.backgroundMode, currentWorkingDirectory: state.currentWorkingDirectory, commandHistory: state.commandHistory, onToggleAutoAccept: handleToggleAutoAccept, onToggleCommandMode: onToggleCommandMode, onToggleBackgroundMode: onToggleBackgroundMode, isActive: true, subshellContext: state.subshellContext, currentTokens: state.currentTokens, maxTokens: state.maxTokens, isShellRunning: state.shellState?.isRunning, backgroundTaskCount: state.backgroundTaskCount, initialValue: preservedInputTextRef.current, onValueChange: handleInputValueChange, onSetAutoModeSetup: (callback) => {
1979
+ setAutoModeCallbackRef.current = callback;
1980
+ } }))),
1791
1981
  state.showExitWarning && (React.createElement(Box, { marginTop: 1 },
1792
1982
  React.createElement(Text, { color: "#ffaa00", bold: true }, "\u26A0\uFE0F Press Ctrl+C again to exit"))))),
1793
1983
  state.screen === 'approval' && state.approvalRequest && (React.createElement(ApprovalSection, { key: `approval-${state.approvalRequest.message}`, approvalRequest: state.approvalRequest, onApprove: (approved) => {
@@ -2080,35 +2270,85 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
2080
2270
  } })),
2081
2271
  state.screen === 'version-update' && state.versionInfo && (React.createElement(Box, { flexDirection: "column" },
2082
2272
  React.createElement(WelcomeBanner, null),
2083
- React.createElement(VersionUpdatePrompt, { currentVersion: state.versionInfo.currentVersion, latestVersion: state.versionInfo.latestVersion, onInstall: () => {
2084
- // Exit the app and let the user know to run the install command
2085
- exit();
2086
- // Clear screen before showing install message
2087
- process.stdout.write('\x1b[2J\x1b[3J\x1b[H');
2088
- const installProcess = spawn('npm', ['install', '-g', 'centaurus-cli@latest'], {
2089
- stdio: 'inherit',
2090
- shell: true
2091
- });
2092
- installProcess.on('close', (code) => {
2093
- if (code === 0) {
2094
- // Restart the CLI
2095
- const restartProcess = spawn('centaurus', [], {
2096
- stdio: 'inherit',
2097
- shell: true,
2098
- detached: true
2099
- });
2100
- restartProcess.unref();
2101
- process.exit(0);
2102
- }
2103
- else {
2104
- process.exit(1);
2105
- }
2106
- });
2107
- }, onLater: () => {
2273
+ React.createElement(VersionUpdatePrompt, { currentVersion: state.versionInfo.currentVersion, latestVersion: state.versionInfo.latestVersion, onComplete: () => {
2274
+ // If update fails, continue to chat screen
2108
2275
  setState(prev => ({
2109
2276
  ...prev,
2110
2277
  screen: 'chat'
2111
2278
  }));
2112
- } })))));
2279
+ } }))),
2280
+ state.screen === 'background-task-list' && state.backgroundTasks && (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#9966ff", paddingX: 1 },
2281
+ React.createElement(Text, { color: "#9966ff", bold: true }, "\uD83D\uDD04 Running Background Tasks"),
2282
+ React.createElement(Text, { dimColor: true }, "Select a task to view its output in focus mode"),
2283
+ React.createElement(Box, { marginTop: 1 },
2284
+ React.createElement(SelectInput, { items: state.backgroundTasks.map((task) => {
2285
+ const durationSec = Math.round(task.durationMs / 1000);
2286
+ return {
2287
+ label: task.command.length > 50 ? task.command.slice(0, 47) + '...' : task.command,
2288
+ value: task.id,
2289
+ cwd: task.cwd,
2290
+ duration: `${durationSec}s`,
2291
+ isRunning: task.isRunning,
2292
+ outputPreview: task.outputPreview.length > 60 ? task.outputPreview.slice(0, 57) + '...' : task.outputPreview
2293
+ };
2294
+ }), itemComponent: ({ isSelected, label, cwd, duration, isRunning, outputPreview }) => (React.createElement(Box, { flexDirection: "column" },
2295
+ React.createElement(Box, null,
2296
+ React.createElement(Text, { color: isSelected ? '#9966ff' : 'white', bold: isSelected },
2297
+ isSelected ? '> ' : ' ',
2298
+ label),
2299
+ React.createElement(Text, { color: isRunning ? '#00cc66' : '#ffaa00' },
2300
+ " [",
2301
+ isRunning ? 'running' : 'done',
2302
+ "]"),
2303
+ React.createElement(Text, { color: "gray" },
2304
+ " \u23F1\uFE0F ",
2305
+ duration)),
2306
+ React.createElement(Box, { paddingLeft: 4 },
2307
+ React.createElement(Text, { color: "gray" },
2308
+ "\uD83D\uDCC1 ",
2309
+ cwd)),
2310
+ outputPreview && (React.createElement(Box, { paddingLeft: 4 },
2311
+ React.createElement(Text, { color: "gray", dimColor: true },
2312
+ "\u2514\u2500 ",
2313
+ outputPreview))))), onSelect: (item) => {
2314
+ setState(prev => ({ ...prev, screen: 'chat', isLoading: false }));
2315
+ onBackgroundTaskSelection(item.value);
2316
+ } })),
2317
+ React.createElement(Box, { marginTop: 1 },
2318
+ React.createElement(Text, { dimColor: true }, "Press ESC to return to chat")))),
2319
+ state.screen === 'background-task-cancel' && state.backgroundTasks && (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#ff6666", paddingX: 1 },
2320
+ React.createElement(Text, { color: "#ff6666", bold: true }, "\uD83D\uDED1 Cancel a Background Task"),
2321
+ React.createElement(Text, { dimColor: true }, "Select a task to terminate it"),
2322
+ React.createElement(Box, { marginTop: 1 },
2323
+ React.createElement(SelectInput, { items: state.backgroundTasks.map((task) => {
2324
+ const durationSec = Math.round(task.durationMs / 1000);
2325
+ return {
2326
+ label: task.command.length > 50 ? task.command.slice(0, 47) + '...' : task.command,
2327
+ value: task.id,
2328
+ cwd: task.cwd,
2329
+ duration: `${durationSec}s`,
2330
+ isRunning: task.isRunning
2331
+ };
2332
+ }), itemComponent: ({ isSelected, label, cwd, duration, isRunning }) => (React.createElement(Box, { flexDirection: "column" },
2333
+ React.createElement(Box, null,
2334
+ React.createElement(Text, { color: isSelected ? '#ff6666' : 'white', bold: isSelected },
2335
+ isSelected ? '> ' : ' ',
2336
+ label),
2337
+ React.createElement(Text, { color: isRunning ? '#00cc66' : '#ffaa00' },
2338
+ " [",
2339
+ isRunning ? 'running' : 'done',
2340
+ "]"),
2341
+ React.createElement(Text, { color: "gray" },
2342
+ " \u23F1\uFE0F ",
2343
+ duration)),
2344
+ React.createElement(Box, { paddingLeft: 4 },
2345
+ React.createElement(Text, { color: "gray" },
2346
+ "\uD83D\uDCC1 ",
2347
+ cwd)))), onSelect: (item) => {
2348
+ setState(prev => ({ ...prev, screen: 'chat', isLoading: false }));
2349
+ onBackgroundTaskCancel(item.value);
2350
+ } })),
2351
+ React.createElement(Box, { marginTop: 1 },
2352
+ React.createElement(Text, { dimColor: true }, "Press ESC to return to chat"))))));
2113
2353
  };
2114
2354
  //# sourceMappingURL=App.js.map