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.
- package/dist/cli-adapter.d.ts +61 -0
- package/dist/cli-adapter.d.ts.map +1 -1
- package/dist/cli-adapter.js +324 -29
- package/dist/cli-adapter.js.map +1 -1
- package/dist/config/ConfigManager.d.ts.map +1 -1
- package/dist/config/ConfigManager.js +6 -5
- package/dist/config/ConfigManager.js.map +1 -1
- package/dist/config/build-config.d.ts +42 -0
- package/dist/config/build-config.d.ts.map +1 -0
- package/dist/config/build-config.js +44 -0
- package/dist/config/build-config.js.map +1 -0
- package/dist/config/manager.d.ts +2 -2
- package/dist/config/manager.d.ts.map +1 -1
- package/dist/config/manager.js +9 -12
- package/dist/config/manager.js.map +1 -1
- package/dist/config/mcp-config-manager.d.ts +5 -0
- package/dist/config/mcp-config-manager.d.ts.map +1 -1
- package/dist/config/mcp-config-manager.js +17 -8
- package/dist/config/mcp-config-manager.js.map +1 -1
- package/dist/config/models.d.ts +40 -42
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +116 -130
- package/dist/config/models.js.map +1 -1
- package/dist/config/slash-commands.d.ts +1 -0
- package/dist/config/slash-commands.d.ts.map +1 -1
- package/dist/config/slash-commands.js +21 -0
- package/dist/config/slash-commands.js.map +1 -1
- package/dist/context/context-manager.d.ts.map +1 -1
- package/dist/context/context-manager.js +6 -6
- package/dist/context/context-manager.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +64 -28
- package/dist/index.js.map +1 -1
- package/dist/mcp/mcp-command-handler.d.ts.map +1 -1
- package/dist/mcp/mcp-command-handler.js +5 -3
- package/dist/mcp/mcp-command-handler.js.map +1 -1
- package/dist/mcp/mcp-server-manager.d.ts.map +1 -1
- package/dist/mcp/mcp-server-manager.js +5 -3
- package/dist/mcp/mcp-server-manager.js.map +1 -1
- package/dist/services/ai-service-client.d.ts.map +1 -1
- package/dist/services/ai-service-client.js +8 -6
- package/dist/services/ai-service-client.js.map +1 -1
- package/dist/services/api-client.d.ts +26 -0
- package/dist/services/api-client.d.ts.map +1 -1
- package/dist/services/api-client.js +19 -7
- package/dist/services/api-client.js.map +1 -1
- package/dist/services/background-task-manager.d.ts +114 -0
- package/dist/services/background-task-manager.d.ts.map +1 -0
- package/dist/services/background-task-manager.js +301 -0
- package/dist/services/background-task-manager.js.map +1 -0
- package/dist/services/local-chat-storage.d.ts.map +1 -1
- package/dist/services/local-chat-storage.js +5 -4
- package/dist/services/local-chat-storage.js.map +1 -1
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +8 -6
- package/dist/tools/web-search.js.map +1 -1
- package/dist/ui/components/App.d.ts +31 -0
- package/dist/ui/components/App.d.ts.map +1 -1
- package/dist/ui/components/App.js +290 -50
- package/dist/ui/components/App.js.map +1 -1
- package/dist/ui/components/ErrorBoundary.d.ts.map +1 -1
- package/dist/ui/components/ErrorBoundary.js +2 -1
- package/dist/ui/components/ErrorBoundary.js.map +1 -1
- package/dist/ui/components/InputBox.d.ts +6 -0
- package/dist/ui/components/InputBox.d.ts.map +1 -1
- package/dist/ui/components/InputBox.js +121 -20
- package/dist/ui/components/InputBox.js.map +1 -1
- package/dist/ui/components/ToolExecutionMessage.js +2 -2
- package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
- package/dist/ui/components/VersionUpdatePrompt.d.ts +1 -2
- package/dist/ui/components/VersionUpdatePrompt.d.ts.map +1 -1
- package/dist/ui/components/VersionUpdatePrompt.js +108 -27
- package/dist/ui/components/VersionUpdatePrompt.js.map +1 -1
- package/dist/utils/command-history.d.ts.map +1 -1
- package/dist/utils/command-history.js +2 -1
- package/dist/utils/command-history.js.map +1 -1
- package/dist/utils/conversation-logger.d.ts +15 -0
- package/dist/utils/conversation-logger.d.ts.map +1 -1
- package/dist/utils/conversation-logger.js +56 -2
- package/dist/utils/conversation-logger.js.map +1 -1
- package/dist/utils/editor-utils.d.ts.map +1 -1
- package/dist/utils/editor-utils.js +3 -2
- package/dist/utils/editor-utils.js.map +1 -1
- package/dist/utils/input-classifier.d.ts.map +1 -1
- package/dist/utils/input-classifier.js +2 -1
- package/dist/utils/input-classifier.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +31 -1
- package/dist/utils/logger.js.map +1 -1
- package/package.json +1 -2
- package/models-config.json +0 -126
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../src/ui/components/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAsBrD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
899
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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,
|
|
2084
|
-
//
|
|
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
|