centaurus-cli 2.5.2 → 2.6.0
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 +6 -0
- package/dist/cli-adapter.d.ts.map +1 -1
- package/dist/cli-adapter.js +215 -29
- package/dist/cli-adapter.js.map +1 -1
- package/dist/commands/CommandParser.js +2 -2
- package/dist/commands/CommandParser.js.map +1 -1
- package/dist/config/defaultConfig.js +1 -1
- package/dist/config/defaultConfig.js.map +1 -1
- package/dist/config/models.d.ts +50 -5
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +144 -20
- package/dist/config/models.js.map +1 -1
- package/dist/config/types.d.ts +3 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +3 -1
- package/dist/config/types.js.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/services/ai-service-client.d.ts +8 -2
- package/dist/services/ai-service-client.d.ts.map +1 -1
- package/dist/services/ai-service-client.js +2 -1
- package/dist/services/ai-service-client.js.map +1 -1
- package/dist/services/environment-context-injector.d.ts +69 -0
- package/dist/services/environment-context-injector.d.ts.map +1 -0
- package/dist/services/environment-context-injector.js +198 -0
- package/dist/services/environment-context-injector.js.map +1 -0
- package/dist/tools/ToolRegistry.d.ts.map +1 -1
- package/dist/tools/ToolRegistry.js +120 -26
- package/dist/tools/ToolRegistry.js.map +1 -1
- package/dist/tools/command.d.ts.map +1 -1
- package/dist/tools/command.js +30 -6
- package/dist/tools/command.js.map +1 -1
- package/dist/tools/file-ops.d.ts.map +1 -1
- package/dist/tools/file-ops.js +70 -23
- package/dist/tools/file-ops.js.map +1 -1
- package/dist/tools/find-files.d.ts +47 -0
- package/dist/tools/find-files.d.ts.map +1 -0
- package/dist/tools/find-files.js +190 -0
- package/dist/tools/find-files.js.map +1 -0
- package/dist/tools/get-diff.d.ts +45 -0
- package/dist/tools/get-diff.d.ts.map +1 -0
- package/dist/tools/get-diff.js +138 -0
- package/dist/tools/get-diff.js.map +1 -0
- package/dist/tools/grep-search.d.ts +85 -0
- package/dist/tools/grep-search.d.ts.map +1 -0
- package/dist/tools/grep-search.js +497 -0
- package/dist/tools/grep-search.js.map +1 -0
- package/dist/tools/inspect-symbol.d.ts +27 -0
- package/dist/tools/inspect-symbol.d.ts.map +1 -0
- package/dist/tools/inspect-symbol.js +259 -0
- package/dist/tools/inspect-symbol.js.map +1 -0
- package/dist/tools/validation.d.ts +49 -0
- package/dist/tools/validation.d.ts.map +1 -0
- package/dist/tools/validation.js +125 -0
- package/dist/tools/validation.js.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/ui/components/App.d.ts +3 -0
- package/dist/ui/components/App.d.ts.map +1 -1
- package/dist/ui/components/App.js +272 -72
- package/dist/ui/components/App.js.map +1 -1
- package/dist/ui/components/ContextWindowIndicator.d.ts +8 -0
- package/dist/ui/components/ContextWindowIndicator.d.ts.map +1 -0
- package/dist/ui/components/ContextWindowIndicator.js +34 -0
- package/dist/ui/components/ContextWindowIndicator.js.map +1 -0
- package/dist/ui/components/FontRecommendation.d.ts +1 -0
- package/dist/ui/components/FontRecommendation.d.ts.map +1 -0
- package/dist/ui/components/FontRecommendation.js +1 -0
- package/dist/ui/components/FontRecommendation.js.map +1 -0
- package/dist/ui/components/InputBox.d.ts +2 -0
- package/dist/ui/components/InputBox.d.ts.map +1 -1
- package/dist/ui/components/InputBox.js +9 -4
- package/dist/ui/components/InputBox.js.map +1 -1
- package/dist/ui/components/MarkdownRenderer.d.ts.map +1 -1
- package/dist/ui/components/MarkdownRenderer.js +34 -9
- package/dist/ui/components/MarkdownRenderer.js.map +1 -1
- package/dist/ui/components/MessageDisplay.d.ts.map +1 -1
- package/dist/ui/components/MessageDisplay.js +9 -2
- package/dist/ui/components/MessageDisplay.js.map +1 -1
- package/dist/ui/components/StreamingMessageDisplay.d.ts.map +1 -1
- package/dist/ui/components/StreamingMessageDisplay.js +11 -3
- package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
- package/dist/ui/components/ThinkingDisplay.d.ts +12 -0
- package/dist/ui/components/ThinkingDisplay.d.ts.map +1 -0
- package/dist/ui/components/ThinkingDisplay.js +41 -0
- package/dist/ui/components/ThinkingDisplay.js.map +1 -0
- package/dist/utils/markdown-parser.d.ts +4 -0
- package/dist/utils/markdown-parser.d.ts.map +1 -1
- package/dist/utils/markdown-parser.js +15 -1
- package/dist/utils/markdown-parser.js.map +1 -1
- package/dist/utils/version-checker.d.ts.map +1 -1
- package/dist/utils/version-checker.js +3 -31
- package/dist/utils/version-checker.js.map +1 -1
- package/package.json +6 -5
- package/README.md +0 -501
- package/dist/ai/provider-factory.d.ts +0 -6
- package/dist/ai/provider-factory.d.ts.map +0 -1
- package/dist/ai/provider-factory.js +0 -27
- package/dist/ai/provider-factory.js.map +0 -1
- package/dist/ai/providers/base.d.ts +0 -25
- package/dist/ai/providers/base.d.ts.map +0 -1
- package/dist/ai/providers/base.js +0 -9
- package/dist/ai/providers/base.js.map +0 -1
- package/dist/ai/providers/gemini.d.ts +0 -34
- package/dist/ai/providers/gemini.d.ts.map +0 -1
- package/dist/ai/providers/gemini.js +0 -146
- package/dist/ai/providers/gemini.js.map +0 -1
- package/dist/commands/view-duplication-logs.d.ts +0 -5
- package/dist/commands/view-duplication-logs.d.ts.map +0 -1
- package/dist/commands/view-duplication-logs.js +0 -14
- package/dist/commands/view-duplication-logs.js.map +0 -1
- package/dist/context/__tests__/command-detector.test.d.ts +0 -14
- package/dist/context/__tests__/command-detector.test.d.ts.map +0 -1
- package/dist/context/__tests__/command-detector.test.js +0 -318
- package/dist/context/__tests__/command-detector.test.js.map +0 -1
- package/dist/context/__tests__/context-manager.test.d.ts +0 -16
- package/dist/context/__tests__/context-manager.test.d.ts.map +0 -1
- package/dist/context/__tests__/context-manager.test.js +0 -375
- package/dist/context/__tests__/context-manager.test.js.map +0 -1
- package/dist/context/__tests__/error-handling.test.d.ts +0 -15
- package/dist/context/__tests__/error-handling.test.d.ts.map +0 -1
- package/dist/context/__tests__/error-handling.test.js +0 -447
- package/dist/context/__tests__/error-handling.test.js.map +0 -1
- package/dist/context/handlers/__tests__/docker-handler.test.d.ts +0 -13
- package/dist/context/handlers/__tests__/docker-handler.test.d.ts.map +0 -1
- package/dist/context/handlers/__tests__/docker-handler.test.js +0 -285
- package/dist/context/handlers/__tests__/docker-handler.test.js.map +0 -1
- package/dist/context/handlers/__tests__/ssh-handler.test.d.ts +0 -13
- package/dist/context/handlers/__tests__/ssh-handler.test.d.ts.map +0 -1
- package/dist/context/handlers/__tests__/ssh-handler.test.js +0 -251
- package/dist/context/handlers/__tests__/ssh-handler.test.js.map +0 -1
- package/dist/context/handlers/__tests__/wsl-handler.test.d.ts +0 -7
- package/dist/context/handlers/__tests__/wsl-handler.test.d.ts.map +0 -1
- package/dist/context/handlers/__tests__/wsl-handler.test.js +0 -331
- package/dist/context/handlers/__tests__/wsl-handler.test.js.map +0 -1
- package/dist/index-custom.d.ts +0 -3
- package/dist/index-custom.d.ts.map +0 -1
- package/dist/index-custom.js +0 -65
- package/dist/index-custom.js.map +0 -1
- package/dist/prompts/system-prompt.d.ts +0 -47
- package/dist/prompts/system-prompt.d.ts.map +0 -1
- package/dist/prompts/system-prompt.js +0 -377
- package/dist/prompts/system-prompt.js.map +0 -1
- package/dist/providers/GoogleProvider.d.ts +0 -26
- package/dist/providers/GoogleProvider.d.ts.map +0 -1
- package/dist/providers/GoogleProvider.js +0 -313
- package/dist/providers/GoogleProvider.js.map +0 -1
- package/dist/providers/Provider.d.ts +0 -114
- package/dist/providers/Provider.d.ts.map +0 -1
- package/dist/providers/Provider.js +0 -44
- package/dist/providers/Provider.js.map +0 -1
- package/dist/services/__tests__/ai-context-injector.test.d.ts +0 -15
- package/dist/services/__tests__/ai-context-injector.test.d.ts.map +0 -1
- package/dist/services/__tests__/ai-context-injector.test.js +0 -326
- package/dist/services/__tests__/ai-context-injector.test.js.map +0 -1
- package/dist/src/context/types.js +0 -27
- package/dist/src/services/ai-context-injector.js +0 -96
- package/dist/src/services/ai-service-client.js +0 -270
- package/dist/src/services/api-client.js +0 -349
- package/dist/src/tools/types.js +0 -1
- package/dist/src/types/index.js +0 -1
- package/dist/test/context/types.js +0 -27
- package/dist/test/services/__tests__/ai-context-injector.test.js +0 -325
- package/dist/test/services/ai-context-injector.js +0 -96
- package/dist/test/services/ai-service-client.js +0 -270
- package/dist/test/services/api-client.js +0 -349
- package/dist/test/tools/types.js +0 -1
- package/dist/test/types/index.js +0 -1
- package/dist/test-ai-context-injector.js +0 -97
- package/dist/tests/automated-verification.d.ts +0 -27
- package/dist/tests/automated-verification.d.ts.map +0 -1
- package/dist/tests/automated-verification.js +0 -359
- package/dist/tests/automated-verification.js.map +0 -1
- package/dist/tests/integration-tests.d.ts +0 -50
- package/dist/tests/integration-tests.d.ts.map +0 -1
- package/dist/tests/integration-tests.js +0 -648
- package/dist/tests/integration-tests.js.map +0 -1
- package/dist/tools/file-ops-test.d.ts +0 -6
- package/dist/tools/file-ops-test.d.ts.map +0 -1
- package/dist/tools/file-ops-test.js +0 -197
- package/dist/tools/file-ops-test.js.map +0 -1
- package/dist/ui/DisplayHistory.d.ts +0 -53
- package/dist/ui/DisplayHistory.d.ts.map +0 -1
- package/dist/ui/DisplayHistory.js +0 -82
- package/dist/ui/DisplayHistory.js.map +0 -1
- package/dist/ui/clack-ui.d.ts +0 -83
- package/dist/ui/clack-ui.d.ts.map +0 -1
- package/dist/ui/clack-ui.js +0 -304
- package/dist/ui/clack-ui.js.map +0 -1
- package/dist/ui/components/DisplayItemRenderer.d.ts +0 -18
- package/dist/ui/components/DisplayItemRenderer.d.ts.map +0 -1
- package/dist/ui/components/DisplayItemRenderer.js +0 -53
- package/dist/ui/components/DisplayItemRenderer.js.map +0 -1
- package/dist/ui/components/DynamicMessage.d.ts +0 -13
- package/dist/ui/components/DynamicMessage.d.ts.map +0 -1
- package/dist/ui/components/DynamicMessage.js +0 -27
- package/dist/ui/components/DynamicMessage.js.map +0 -1
- package/dist/ui/components/FileViewerScreen.d.ts +0 -14
- package/dist/ui/components/FileViewerScreen.d.ts.map +0 -1
- package/dist/ui/components/FileViewerScreen.js +0 -74
- package/dist/ui/components/FileViewerScreen.js.map +0 -1
- package/dist/ui/components/ScrollableContent.d.ts +0 -7
- package/dist/ui/components/ScrollableContent.d.ts.map +0 -1
- package/dist/ui/components/ScrollableContent.js +0 -6
- package/dist/ui/components/ScrollableContent.js.map +0 -1
- package/dist/ui/components/ScrollableMessageList.d.ts +0 -10
- package/dist/ui/components/ScrollableMessageList.d.ts.map +0 -1
- package/dist/ui/components/ScrollableMessageList.js +0 -133
- package/dist/ui/components/ScrollableMessageList.js.map +0 -1
- package/dist/ui/components/ScrollableScreen.d.ts +0 -9
- package/dist/ui/components/ScrollableScreen.d.ts.map +0 -1
- package/dist/ui/components/ScrollableScreen.js +0 -22
- package/dist/ui/components/ScrollableScreen.js.map +0 -1
- package/dist/ui/components/StaticMessageHistory.d.ts +0 -14
- package/dist/ui/components/StaticMessageHistory.d.ts.map +0 -1
- package/dist/ui/components/StaticMessageHistory.js +0 -19
- package/dist/ui/components/StaticMessageHistory.js.map +0 -1
- package/dist/ui/components/code-block.d.ts +0 -10
- package/dist/ui/components/code-block.d.ts.map +0 -1
- package/dist/ui/components/code-block.js +0 -74
- package/dist/ui/components/code-block.js.map +0 -1
- package/dist/ui/components/confirm-prompt.d.ts +0 -12
- package/dist/ui/components/confirm-prompt.d.ts.map +0 -1
- package/dist/ui/components/confirm-prompt.js +0 -104
- package/dist/ui/components/confirm-prompt.js.map +0 -1
- package/dist/ui/components/diff-viewer.d.ts +0 -9
- package/dist/ui/components/diff-viewer.d.ts.map +0 -1
- package/dist/ui/components/diff-viewer.js +0 -57
- package/dist/ui/components/diff-viewer.js.map +0 -1
- package/dist/ui/components/input-box.d.ts +0 -18
- package/dist/ui/components/input-box.d.ts.map +0 -1
- package/dist/ui/components/input-box.js +0 -157
- package/dist/ui/components/input-box.js.map +0 -1
- package/dist/ui/components/keyboard-help.d.ts +0 -7
- package/dist/ui/components/keyboard-help.d.ts.map +0 -1
- package/dist/ui/components/keyboard-help.js +0 -43
- package/dist/ui/components/keyboard-help.js.map +0 -1
- package/dist/ui/components/loading-indicator.d.ts +0 -3
- package/dist/ui/components/loading-indicator.d.ts.map +0 -1
- package/dist/ui/components/loading-indicator.js +0 -42
- package/dist/ui/components/loading-indicator.js.map +0 -1
- package/dist/ui/components/message-display.d.ts +0 -7
- package/dist/ui/components/message-display.d.ts.map +0 -1
- package/dist/ui/components/message-display.js +0 -104
- package/dist/ui/components/message-display.js.map +0 -1
- package/dist/ui/components/misc.d.ts +0 -28
- package/dist/ui/components/misc.d.ts.map +0 -1
- package/dist/ui/components/misc.js +0 -128
- package/dist/ui/components/misc.js.map +0 -1
- package/dist/ui/components/select-prompt.d.ts +0 -13
- package/dist/ui/components/select-prompt.d.ts.map +0 -1
- package/dist/ui/components/select-prompt.js +0 -42
- package/dist/ui/components/select-prompt.js.map +0 -1
- package/dist/ui/components/status-bar.d.ts +0 -11
- package/dist/ui/components/status-bar.d.ts.map +0 -1
- package/dist/ui/components/status-bar.js +0 -47
- package/dist/ui/components/status-bar.js.map +0 -1
- package/dist/ui/components/tool-execution.d.ts +0 -3
- package/dist/ui/components/tool-execution.d.ts.map +0 -1
- package/dist/ui/components/tool-execution.js +0 -374
- package/dist/ui/components/tool-execution.js.map +0 -1
- package/dist/ui/components/tool-result.d.ts +0 -11
- package/dist/ui/components/tool-result.d.ts.map +0 -1
- package/dist/ui/components/tool-result.js +0 -58
- package/dist/ui/components/tool-result.js.map +0 -1
- package/dist/ui/components/welcome-banner.d.ts +0 -3
- package/dist/ui/components/welcome-banner.d.ts.map +0 -1
- package/dist/ui/components/welcome-banner.js +0 -46
- package/dist/ui/components/welcome-banner.js.map +0 -1
- package/dist/ui/hooks/useDisplayHistory.d.ts +0 -13
- package/dist/ui/hooks/useDisplayHistory.d.ts.map +0 -1
- package/dist/ui/hooks/useDisplayHistory.js +0 -45
- package/dist/ui/hooks/useDisplayHistory.js.map +0 -1
- package/dist/ui/render-engine.d.ts +0 -69
- package/dist/ui/render-engine.d.ts.map +0 -1
- package/dist/ui/render-engine.js +0 -197
- package/dist/ui/render-engine.js.map +0 -1
- package/dist/ui/terminal/TerminalRenderer.d.ts +0 -84
- package/dist/ui/terminal/TerminalRenderer.d.ts.map +0 -1
- package/dist/ui/terminal/TerminalRenderer.js +0 -154
- package/dist/ui/terminal/TerminalRenderer.js.map +0 -1
- package/dist/ui/terminal/TerminalUI.d.ts +0 -139
- package/dist/ui/terminal/TerminalUI.d.ts.map +0 -1
- package/dist/ui/terminal/TerminalUI.js +0 -430
- package/dist/ui/terminal/TerminalUI.js.map +0 -1
- package/dist/ui/terminal/VirtualChatBuffer.d.ts +0 -32
- package/dist/ui/terminal/VirtualChatBuffer.d.ts.map +0 -1
- package/dist/ui/terminal/VirtualChatBuffer.js +0 -37
- package/dist/ui/terminal/VirtualChatBuffer.js.map +0 -1
- package/dist/ui/terminal-kit-base.d.ts +0 -117
- package/dist/ui/terminal-kit-base.d.ts.map +0 -1
- package/dist/ui/terminal-kit-base.js +0 -188
- package/dist/ui/terminal-kit-base.js.map +0 -1
- package/dist/ui/utils/duplication-detector.d.ts +0 -32
- package/dist/ui/utils/duplication-detector.d.ts.map +0 -1
- package/dist/ui/utils/duplication-detector.js +0 -227
- package/dist/ui/utils/duplication-detector.js.map +0 -1
- package/dist/ui/utils/duplication-logger.d.ts +0 -21
- package/dist/ui/utils/duplication-logger.d.ts.map +0 -1
- package/dist/ui/utils/duplication-logger.js +0 -85
- package/dist/ui/utils/duplication-logger.js.map +0 -1
- package/dist/ui/utils/terminal-scanner.d.ts +0 -19
- package/dist/ui/utils/terminal-scanner.d.ts.map +0 -1
- package/dist/ui/utils/terminal-scanner.js +0 -217
- package/dist/ui/utils/terminal-scanner.js.map +0 -1
- package/dist/version.d.ts +0 -2
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js +0 -3
- package/dist/version.js.map +0 -1
- package/scripts/generate-version.js +0 -25
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useState, useCallback } from 'react';
|
|
2
2
|
import { Box, Text, useApp, useInput, Static } from 'ink';
|
|
3
3
|
import { spawn } from 'child_process';
|
|
4
|
+
import * as fs from 'fs';
|
|
4
5
|
import { WelcomeBanner } from './WelcomeBanner.js';
|
|
5
6
|
import { InputBox } from './InputBox.js';
|
|
6
7
|
import { MessageDisplay } from './MessageDisplay.js';
|
|
@@ -49,13 +50,43 @@ const ApprovalSection = React.memo(({ approvalRequest, onApprove }) => {
|
|
|
49
50
|
// Only re-render if the approval request message changes
|
|
50
51
|
return prevProps.approvalRequest.message === nextProps.approvalRequest.message;
|
|
51
52
|
});
|
|
52
|
-
export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceived, onResponseStream, onPickerSetup, onPickerSelection, onToolExecutionUpdate, onToolApprovalRequest, onToolStreamingOutput, onPlanModeChange, onPlanApprovalRequest, onCommandModeChange, onToggleCommandMode, onCwdChange, onSubshellContextChange, onPasswordRequest }) => {
|
|
53
|
+
export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceived, onResponseStream, onThoughtStream, onThoughtComplete, onPickerSetup, onPickerSelection, onToolExecutionUpdate, onToolApprovalRequest, onToolStreamingOutput, onPlanModeChange, onPlanApprovalRequest, onCommandModeChange, onToggleCommandMode, onCwdChange, onModelChange, onSubshellContextChange, onPasswordRequest }) => {
|
|
53
54
|
const { exit } = useApp();
|
|
54
55
|
const autoAcceptRef = React.useRef(false);
|
|
55
56
|
// Helper to clear screen
|
|
56
57
|
const clearScreen = useCallback(() => {
|
|
57
58
|
process.stdout.write('\x1b[2J\x1b[3J\x1b[H');
|
|
58
59
|
}, []);
|
|
60
|
+
// Helper to get max tokens for a model
|
|
61
|
+
const getMaxTokensForModel = useCallback((model) => {
|
|
62
|
+
// Import dynamically to avoid circular dependencies
|
|
63
|
+
try {
|
|
64
|
+
const { getModelContextWindow } = require('../../config/models.js');
|
|
65
|
+
return getModelContextWindow(model);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
// Fallback to defaults if config loading fails
|
|
69
|
+
if (model.includes('gemini-3'))
|
|
70
|
+
return 2000000;
|
|
71
|
+
if (model.includes('gemini-2.5'))
|
|
72
|
+
return 2000000;
|
|
73
|
+
if (model.includes('kimi'))
|
|
74
|
+
return 128000;
|
|
75
|
+
return 2000000;
|
|
76
|
+
}
|
|
77
|
+
}, []);
|
|
78
|
+
// Helper to estimate tokens (rough approximation: 1 token ≈ 4 characters)
|
|
79
|
+
const estimateTokens = useCallback((text) => {
|
|
80
|
+
return Math.ceil(text.length / 4);
|
|
81
|
+
}, []);
|
|
82
|
+
// Helper to calculate total tokens from messages
|
|
83
|
+
const calculateTotalTokens = useCallback((messages) => {
|
|
84
|
+
let total = 0;
|
|
85
|
+
for (const msg of messages) {
|
|
86
|
+
total += estimateTokens(msg.content);
|
|
87
|
+
}
|
|
88
|
+
return total;
|
|
89
|
+
}, [estimateTokens]);
|
|
59
90
|
const [state, setState] = useState({
|
|
60
91
|
screen: 'chat',
|
|
61
92
|
messageHistory: [],
|
|
@@ -63,7 +94,7 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
63
94
|
autoAcceptMode: false,
|
|
64
95
|
isLoading: false,
|
|
65
96
|
loadingMessage: '',
|
|
66
|
-
currentModel: initialModel || 'gemini-2.
|
|
97
|
+
currentModel: initialModel || 'gemini-2.5-flash',
|
|
67
98
|
planMode: initialPlanMode || false,
|
|
68
99
|
commandMode: false,
|
|
69
100
|
currentWorkingDirectory: process.cwd(),
|
|
@@ -72,6 +103,9 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
72
103
|
subshellContext: undefined,
|
|
73
104
|
versionInfo: undefined,
|
|
74
105
|
checkingVersion: true,
|
|
106
|
+
isAiWorking: false,
|
|
107
|
+
currentTokens: 0,
|
|
108
|
+
maxTokens: getMaxTokensForModel(initialModel || 'gemini-2.5-flash'),
|
|
75
109
|
pickerOptions: undefined,
|
|
76
110
|
approvalRequest: undefined,
|
|
77
111
|
planApprovalRequest: undefined,
|
|
@@ -98,6 +132,20 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
98
132
|
React.useEffect(() => {
|
|
99
133
|
autoAcceptRef.current = state.autoAcceptMode;
|
|
100
134
|
}, [state.autoAcceptMode]);
|
|
135
|
+
// Update token count whenever messages change
|
|
136
|
+
React.useEffect(() => {
|
|
137
|
+
const allMessages = [...state.messageHistory];
|
|
138
|
+
if (state.currentMessage) {
|
|
139
|
+
allMessages.push(state.currentMessage);
|
|
140
|
+
}
|
|
141
|
+
const totalTokens = calculateTotalTokens(allMessages);
|
|
142
|
+
if (totalTokens !== state.currentTokens) {
|
|
143
|
+
setState(prev => ({
|
|
144
|
+
...prev,
|
|
145
|
+
currentTokens: totalTokens
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
}, [state.messageHistory, state.currentMessage, calculateTotalTokens]);
|
|
101
149
|
// Track if we're currently streaming
|
|
102
150
|
const isStreamingRef = React.useRef(false);
|
|
103
151
|
// Set up callback to receive streaming chunks - only once on mount
|
|
@@ -105,33 +153,131 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
105
153
|
onResponseStream((chunk) => {
|
|
106
154
|
isStreamingRef.current = true; // Mark that we're streaming
|
|
107
155
|
setState(prev => {
|
|
108
|
-
// If we
|
|
156
|
+
// If we have a current assistant message (possibly created by thoughts), append to it
|
|
157
|
+
if (prev.currentMessage && prev.currentMessage.role === 'assistant') {
|
|
158
|
+
return {
|
|
159
|
+
...prev,
|
|
160
|
+
currentMessage: {
|
|
161
|
+
...prev.currentMessage,
|
|
162
|
+
content: prev.currentMessage.content + chunk
|
|
163
|
+
},
|
|
164
|
+
isAiWorking: true // Keep AI working state active
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
// Otherwise create a new message
|
|
168
|
+
const now = new Date();
|
|
169
|
+
const newMessage = {
|
|
170
|
+
id: `assistant-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
|
|
171
|
+
role: 'assistant',
|
|
172
|
+
content: chunk,
|
|
173
|
+
timestamp: now,
|
|
174
|
+
shouldStream: true // AI responses should stream
|
|
175
|
+
};
|
|
176
|
+
return {
|
|
177
|
+
...prev,
|
|
178
|
+
currentMessage: newMessage,
|
|
179
|
+
isLoading: false,
|
|
180
|
+
isAiWorking: true // AI is actively working
|
|
181
|
+
};
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
}, [onResponseStream]);
|
|
185
|
+
// Set up callback to receive thought chunks
|
|
186
|
+
React.useEffect(() => {
|
|
187
|
+
onThoughtStream((thought) => {
|
|
188
|
+
// Debug logging to file
|
|
189
|
+
try {
|
|
190
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Received thought: ${thought.substring(0, 100)}\n`);
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
// Ignore logging errors
|
|
194
|
+
}
|
|
195
|
+
setState(prev => {
|
|
196
|
+
// If we don't have a current assistant message, create one for the thoughts
|
|
109
197
|
if (!prev.currentMessage || prev.currentMessage.role !== 'assistant') {
|
|
198
|
+
try {
|
|
199
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Creating new assistant message for thoughts\n`);
|
|
200
|
+
}
|
|
201
|
+
catch (e) {
|
|
202
|
+
// Ignore logging errors
|
|
203
|
+
}
|
|
110
204
|
const now = new Date();
|
|
205
|
+
const newLines = thought.split('\n').filter(line => line.trim());
|
|
206
|
+
const last3Lines = newLines.slice(-3);
|
|
111
207
|
const newMessage = {
|
|
112
208
|
id: `assistant-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
|
|
113
209
|
role: 'assistant',
|
|
114
|
-
content:
|
|
210
|
+
content: '', // Empty content initially, will be filled when text arrives
|
|
115
211
|
timestamp: now,
|
|
116
|
-
shouldStream: true
|
|
212
|
+
shouldStream: true,
|
|
213
|
+
thoughts: last3Lines
|
|
117
214
|
};
|
|
118
215
|
return {
|
|
119
216
|
...prev,
|
|
120
217
|
currentMessage: newMessage,
|
|
121
|
-
isLoading: false
|
|
218
|
+
isLoading: false,
|
|
219
|
+
isAiWorking: true
|
|
122
220
|
};
|
|
123
221
|
}
|
|
124
|
-
//
|
|
222
|
+
// Split thought into lines and keep only last 3
|
|
223
|
+
const newLines = thought.split('\n').filter(line => line.trim());
|
|
224
|
+
const existingThoughts = prev.currentMessage.thoughts || [];
|
|
225
|
+
const allLines = [...existingThoughts, ...newLines];
|
|
226
|
+
const last3Lines = allLines.slice(-3);
|
|
227
|
+
try {
|
|
228
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Updating thoughts: ${JSON.stringify(last3Lines)}\n`);
|
|
229
|
+
}
|
|
230
|
+
catch (e) {
|
|
231
|
+
// Ignore logging errors
|
|
232
|
+
}
|
|
125
233
|
return {
|
|
126
234
|
...prev,
|
|
127
235
|
currentMessage: {
|
|
128
236
|
...prev.currentMessage,
|
|
129
|
-
|
|
237
|
+
thoughts: last3Lines,
|
|
238
|
+
thinkingDuration: undefined // Clear duration while thinking
|
|
130
239
|
}
|
|
131
240
|
};
|
|
132
241
|
});
|
|
133
242
|
});
|
|
134
|
-
}, [
|
|
243
|
+
}, [onThoughtStream]);
|
|
244
|
+
// Set up callback for when thinking completes
|
|
245
|
+
React.useEffect(() => {
|
|
246
|
+
onThoughtComplete((durationSeconds) => {
|
|
247
|
+
try {
|
|
248
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] onThoughtComplete called with ${durationSeconds}s\n`);
|
|
249
|
+
}
|
|
250
|
+
catch (e) {
|
|
251
|
+
// Ignore
|
|
252
|
+
}
|
|
253
|
+
setState(prev => {
|
|
254
|
+
// Only update if we have a current assistant message
|
|
255
|
+
if (!prev.currentMessage || prev.currentMessage.role !== 'assistant') {
|
|
256
|
+
try {
|
|
257
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] No current assistant message for thought completion\n`);
|
|
258
|
+
}
|
|
259
|
+
catch (e) {
|
|
260
|
+
// Ignore
|
|
261
|
+
}
|
|
262
|
+
return prev;
|
|
263
|
+
}
|
|
264
|
+
try {
|
|
265
|
+
fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] Setting thinkingDuration to ${durationSeconds}s on message ${prev.currentMessage.id}\n`);
|
|
266
|
+
}
|
|
267
|
+
catch (e) {
|
|
268
|
+
// Ignore
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
...prev,
|
|
272
|
+
currentMessage: {
|
|
273
|
+
...prev.currentMessage,
|
|
274
|
+
thoughts: undefined, // Clear thoughts
|
|
275
|
+
thinkingDuration: durationSeconds // Set duration
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
}, [onThoughtComplete]);
|
|
135
281
|
// Set up callback to receive complete responses (for slash commands and non-streaming responses)
|
|
136
282
|
React.useEffect(() => {
|
|
137
283
|
onResponseReceived((message) => {
|
|
@@ -148,7 +294,8 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
148
294
|
return {
|
|
149
295
|
...prev,
|
|
150
296
|
currentMessage: null,
|
|
151
|
-
isLoading: false
|
|
297
|
+
isLoading: false,
|
|
298
|
+
isAiWorking: false // AI finished working
|
|
152
299
|
};
|
|
153
300
|
}
|
|
154
301
|
// Create complete message with full content
|
|
@@ -161,12 +308,14 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
161
308
|
...prev,
|
|
162
309
|
messageHistory: [...prev.messageHistory, completeMessage],
|
|
163
310
|
currentMessage: null,
|
|
164
|
-
isLoading: false
|
|
311
|
+
isLoading: false,
|
|
312
|
+
isAiWorking: false // AI finished working
|
|
165
313
|
};
|
|
166
314
|
}
|
|
167
315
|
return {
|
|
168
316
|
...prev,
|
|
169
|
-
isLoading: false
|
|
317
|
+
isLoading: false,
|
|
318
|
+
isAiWorking: false // AI finished working
|
|
170
319
|
};
|
|
171
320
|
});
|
|
172
321
|
return;
|
|
@@ -187,7 +336,8 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
187
336
|
...prev,
|
|
188
337
|
messageHistory: [...prev.messageHistory, outputMessage],
|
|
189
338
|
currentMessage: null,
|
|
190
|
-
isLoading: false
|
|
339
|
+
isLoading: false,
|
|
340
|
+
isAiWorking: false // AI finished working
|
|
191
341
|
};
|
|
192
342
|
}
|
|
193
343
|
// For non-streaming responses (like slash commands), display the complete message
|
|
@@ -205,14 +355,16 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
205
355
|
...prev,
|
|
206
356
|
messageHistory: [...prev.messageHistory, prev.currentMessage],
|
|
207
357
|
currentMessage: newMessage,
|
|
208
|
-
isLoading: false
|
|
358
|
+
isLoading: false,
|
|
359
|
+
isAiWorking: false // AI finished working
|
|
209
360
|
};
|
|
210
361
|
}
|
|
211
362
|
// Otherwise just set as current
|
|
212
363
|
return {
|
|
213
364
|
...prev,
|
|
214
365
|
currentMessage: newMessage,
|
|
215
|
-
isLoading: false
|
|
366
|
+
isLoading: false,
|
|
367
|
+
isAiWorking: false // AI finished working
|
|
216
368
|
};
|
|
217
369
|
});
|
|
218
370
|
});
|
|
@@ -244,36 +396,47 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
244
396
|
timestamp: new Date(),
|
|
245
397
|
toolExecution: { ...update }
|
|
246
398
|
};
|
|
247
|
-
// If current message is a tool with same name and executing, update it
|
|
399
|
+
// If current message is a tool with same name and executing, update it in place
|
|
248
400
|
if (prev.currentMessage?.role === 'tool' &&
|
|
249
401
|
prev.currentMessage.toolExecution?.toolName === update.toolName &&
|
|
250
402
|
prev.currentMessage.toolExecution?.status === 'executing' &&
|
|
251
403
|
update.status !== 'executing') {
|
|
252
|
-
//
|
|
404
|
+
// Tool completed - update in place and keep as current
|
|
253
405
|
return {
|
|
254
406
|
...prev,
|
|
255
|
-
|
|
256
|
-
|
|
407
|
+
currentMessage: { ...prev.currentMessage, toolExecution: { ...update } },
|
|
408
|
+
isAiWorking: true // Keep AI working state active (more tool calls or response may follow)
|
|
257
409
|
};
|
|
258
410
|
}
|
|
259
|
-
// If starting new tool execution
|
|
411
|
+
// If starting new tool execution
|
|
260
412
|
if (update.status === 'executing') {
|
|
261
|
-
//
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
413
|
+
// IMPORTANT: Always preserve current message by moving it to history first
|
|
414
|
+
let newHistory = prev.messageHistory;
|
|
415
|
+
if (prev.currentMessage) {
|
|
416
|
+
// Move ANY current message to history before showing tool
|
|
417
|
+
newHistory = [...prev.messageHistory, prev.currentMessage];
|
|
418
|
+
}
|
|
265
419
|
return {
|
|
266
420
|
...prev,
|
|
267
421
|
messageHistory: newHistory,
|
|
268
422
|
currentMessage: toolMessage,
|
|
269
|
-
isLoading: false
|
|
423
|
+
isLoading: false,
|
|
424
|
+
isAiWorking: true
|
|
270
425
|
};
|
|
271
426
|
}
|
|
272
|
-
// For completed tools without a current executing one
|
|
427
|
+
// For completed tools without a current executing one
|
|
428
|
+
// IMPORTANT: Preserve current message before adding tool to history
|
|
429
|
+
let newHistory = prev.messageHistory;
|
|
430
|
+
// If there's a current message, move it to history first
|
|
431
|
+
if (prev.currentMessage) {
|
|
432
|
+
newHistory = [...prev.messageHistory, prev.currentMessage];
|
|
433
|
+
}
|
|
434
|
+
// Add tool message to history
|
|
273
435
|
return {
|
|
274
436
|
...prev,
|
|
275
|
-
messageHistory: [...
|
|
276
|
-
currentMessage: null
|
|
437
|
+
messageHistory: [...newHistory, toolMessage],
|
|
438
|
+
currentMessage: null,
|
|
439
|
+
isAiWorking: true // Keep AI working state active
|
|
277
440
|
};
|
|
278
441
|
});
|
|
279
442
|
});
|
|
@@ -303,22 +466,27 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
303
466
|
resolve: (approved) => {
|
|
304
467
|
// Clear screen and return to chat
|
|
305
468
|
clearScreen();
|
|
306
|
-
// Add approval result to chat history
|
|
307
|
-
const resultMessage = {
|
|
308
|
-
id: `approval-result-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
|
|
309
|
-
role: 'system',
|
|
310
|
-
content: approved
|
|
311
|
-
? `✓ ${request.operationType === 'write_file' ? 'File write' : request.operationType === 'edit_file' ? 'File edit' : 'Command'} approved`
|
|
312
|
-
: `✗ ${request.operationType === 'write_file' ? 'File write' : request.operationType === 'edit_file' ? 'File edit' : 'Command'} declined`,
|
|
313
|
-
timestamp: new Date()
|
|
314
|
-
};
|
|
315
469
|
// Switch back to chat and clear approval request
|
|
316
|
-
setState(prev =>
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
470
|
+
setState(prev => {
|
|
471
|
+
const nextState = {
|
|
472
|
+
...prev,
|
|
473
|
+
screen: 'chat',
|
|
474
|
+
approvalRequest: undefined,
|
|
475
|
+
};
|
|
476
|
+
if (!approved) {
|
|
477
|
+
const resultMessage = {
|
|
478
|
+
id: `approval-result-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
|
|
479
|
+
role: 'system',
|
|
480
|
+
content: `✗ ${request.operationType === 'write_file' ? 'File write' : request.operationType === 'edit_file' ? 'File edit' : 'Command'} declined`,
|
|
481
|
+
timestamp: new Date()
|
|
482
|
+
};
|
|
483
|
+
return {
|
|
484
|
+
...nextState,
|
|
485
|
+
messageHistory: [...prev.messageHistory, resultMessage]
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
return nextState;
|
|
489
|
+
});
|
|
322
490
|
resolve(approved);
|
|
323
491
|
}
|
|
324
492
|
},
|
|
@@ -338,21 +506,26 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
338
506
|
operationType: request.operationType,
|
|
339
507
|
operationDetails: request.operationDetails,
|
|
340
508
|
resolve: (approved) => {
|
|
341
|
-
//
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
509
|
+
// Clear approval request
|
|
510
|
+
setState(prev => {
|
|
511
|
+
const nextState = {
|
|
512
|
+
...prev,
|
|
513
|
+
approvalRequest: undefined,
|
|
514
|
+
};
|
|
515
|
+
if (!approved) {
|
|
516
|
+
const resultMessage = {
|
|
517
|
+
id: `approval-result-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
|
|
518
|
+
role: 'system',
|
|
519
|
+
content: `✗ Command declined`,
|
|
520
|
+
timestamp: new Date()
|
|
521
|
+
};
|
|
522
|
+
return {
|
|
523
|
+
...nextState,
|
|
524
|
+
messageHistory: [...prev.messageHistory, resultMessage]
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
return nextState;
|
|
528
|
+
});
|
|
356
529
|
resolve(approved);
|
|
357
530
|
}
|
|
358
531
|
},
|
|
@@ -412,6 +585,15 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
412
585
|
}));
|
|
413
586
|
});
|
|
414
587
|
}, [onCwdChange]);
|
|
588
|
+
// Set up callback to receive model changes
|
|
589
|
+
React.useEffect(() => {
|
|
590
|
+
onModelChange((modelName) => {
|
|
591
|
+
setState(prev => ({
|
|
592
|
+
...prev,
|
|
593
|
+
currentModel: modelName
|
|
594
|
+
}));
|
|
595
|
+
});
|
|
596
|
+
}, [onModelChange]);
|
|
415
597
|
// Set up callback to receive subshell context changes
|
|
416
598
|
React.useEffect(() => {
|
|
417
599
|
onSubshellContextChange((context) => {
|
|
@@ -493,10 +675,11 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
493
675
|
// Ctrl+C handling - double press to exit
|
|
494
676
|
if (key.ctrl && input === 'c') {
|
|
495
677
|
// If AI is loading/executing, first Ctrl+C cancels the operation
|
|
496
|
-
if (state.isLoading) {
|
|
678
|
+
if (state.isLoading || state.isAiWorking) {
|
|
497
679
|
setState(prev => ({
|
|
498
680
|
...prev,
|
|
499
681
|
isLoading: false,
|
|
682
|
+
isAiWorking: false,
|
|
500
683
|
currentMessage: null,
|
|
501
684
|
showExitWarning: true
|
|
502
685
|
}));
|
|
@@ -567,7 +750,8 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
567
750
|
...prev,
|
|
568
751
|
messageHistory: [],
|
|
569
752
|
currentMessage: null,
|
|
570
|
-
isLoading: false
|
|
753
|
+
isLoading: false,
|
|
754
|
+
currentTokens: 0
|
|
571
755
|
}));
|
|
572
756
|
// Still call onMessage to clear backend history
|
|
573
757
|
try {
|
|
@@ -597,6 +781,7 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
597
781
|
messageHistory: [...newHistory, commandMessage],
|
|
598
782
|
currentMessage: null,
|
|
599
783
|
isLoading: false,
|
|
784
|
+
isAiWorking: false, // Command mode doesn't use AI
|
|
600
785
|
};
|
|
601
786
|
});
|
|
602
787
|
}
|
|
@@ -620,6 +805,7 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
620
805
|
currentMessage: null,
|
|
621
806
|
isLoading: true,
|
|
622
807
|
loadingMessage: 'Processing your request...',
|
|
808
|
+
isAiWorking: true // AI is starting to work
|
|
623
809
|
};
|
|
624
810
|
});
|
|
625
811
|
}
|
|
@@ -629,6 +815,7 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
629
815
|
...prev,
|
|
630
816
|
isLoading: true,
|
|
631
817
|
loadingMessage: 'Processing command...',
|
|
818
|
+
isAiWorking: true // AI is starting to work
|
|
632
819
|
}));
|
|
633
820
|
}
|
|
634
821
|
// Add to command history (avoid duplicates of the last command)
|
|
@@ -658,14 +845,16 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
658
845
|
...prev,
|
|
659
846
|
messageHistory: newHistory,
|
|
660
847
|
currentMessage: null,
|
|
661
|
-
isLoading: false
|
|
848
|
+
isLoading: false,
|
|
849
|
+
isAiWorking: false // AI finished working
|
|
662
850
|
};
|
|
663
851
|
});
|
|
664
852
|
}
|
|
665
853
|
finally {
|
|
666
854
|
setState(prev => ({
|
|
667
855
|
...prev,
|
|
668
|
-
isLoading: false
|
|
856
|
+
isLoading: false,
|
|
857
|
+
isAiWorking: false // AI finished working
|
|
669
858
|
}));
|
|
670
859
|
}
|
|
671
860
|
}, [onMessage]);
|
|
@@ -675,18 +864,16 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
675
864
|
autoAcceptMode: !prev.autoAcceptMode
|
|
676
865
|
}));
|
|
677
866
|
}, []);
|
|
678
|
-
// Check if there are any executing tools to avoid double spinners
|
|
679
|
-
const hasExecutingTools = React.useMemo(() => state.currentMessage?.role === 'tool' && state.currentMessage?.toolExecution?.status === 'executing', [state.currentMessage]);
|
|
680
867
|
return (React.createElement(Box, { flexDirection: "column" },
|
|
681
868
|
state.screen === 'chat' && (React.createElement(React.Fragment, null,
|
|
682
869
|
React.createElement(MessageList, { history: state.messageHistory, current: state.currentMessage, showBanner: true }),
|
|
683
|
-
state.
|
|
870
|
+
state.isAiWorking && React.createElement(LoadingIndicator, { key: "loading-indicator" }),
|
|
684
871
|
state.approvalRequest ? (React.createElement(ApprovalSection, { key: `approval-${state.approvalRequest.message}`, approvalRequest: state.approvalRequest, onApprove: (approved) => {
|
|
685
872
|
const resolve = state.approvalRequest?.resolve;
|
|
686
873
|
if (resolve) {
|
|
687
874
|
resolve(approved);
|
|
688
875
|
}
|
|
689
|
-
} })) : (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 })),
|
|
876
|
+
} })) : (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 })),
|
|
690
877
|
state.showExitWarning && (React.createElement(Box, { marginTop: 1 },
|
|
691
878
|
React.createElement(Text, { color: "#ffaa00", bold: true }, "\u26A0\uFE0F Press Ctrl+C again to exit"))))),
|
|
692
879
|
state.screen === 'approval' && state.approvalRequest && (React.createElement(ApprovalSection, { key: `approval-${state.approvalRequest.message}`, approvalRequest: state.approvalRequest, onApprove: (approved) => {
|
|
@@ -700,8 +887,13 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
700
887
|
setState(prev => ({ ...prev, screen: 'chat', isLoading: true }));
|
|
701
888
|
try {
|
|
702
889
|
await onPickerSelection(value, state.pickerOptions.type);
|
|
703
|
-
//
|
|
704
|
-
|
|
890
|
+
// Model name will be updated via onModelChange callback
|
|
891
|
+
// Just update loading state here
|
|
892
|
+
setState(prev => ({
|
|
893
|
+
...prev,
|
|
894
|
+
isLoading: false,
|
|
895
|
+
isAiWorking: false
|
|
896
|
+
}));
|
|
705
897
|
}
|
|
706
898
|
catch (error) {
|
|
707
899
|
setState(prev => {
|
|
@@ -715,7 +907,8 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
715
907
|
...prev,
|
|
716
908
|
messageHistory: [...prev.messageHistory, errorMessage],
|
|
717
909
|
currentMessage: null,
|
|
718
|
-
isLoading: false
|
|
910
|
+
isLoading: false,
|
|
911
|
+
isAiWorking: false
|
|
719
912
|
};
|
|
720
913
|
});
|
|
721
914
|
}
|
|
@@ -741,7 +934,8 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
741
934
|
...prev,
|
|
742
935
|
screen: 'chat',
|
|
743
936
|
planApprovalRequest: undefined,
|
|
744
|
-
isLoading: true
|
|
937
|
+
isLoading: true,
|
|
938
|
+
isAiWorking: true
|
|
745
939
|
}));
|
|
746
940
|
}, onNo: () => {
|
|
747
941
|
const resolve = state.planApprovalRequest?.resolve;
|
|
@@ -779,8 +973,14 @@ export const App = ({ onMessage, initialModel, initialPlanMode, onResponseReceiv
|
|
|
779
973
|
});
|
|
780
974
|
installProcess.on('close', (code) => {
|
|
781
975
|
if (code === 0) {
|
|
782
|
-
console.log('\n✅ Update complete
|
|
783
|
-
|
|
976
|
+
console.log('\n✅ Update complete! Restarting Centaurus CLI...\n');
|
|
977
|
+
// Restart the CLI
|
|
978
|
+
const restartProcess = spawn('centaurus', [], {
|
|
979
|
+
stdio: 'inherit',
|
|
980
|
+
shell: true,
|
|
981
|
+
detached: true
|
|
982
|
+
});
|
|
983
|
+
restartProcess.unref();
|
|
784
984
|
process.exit(0);
|
|
785
985
|
}
|
|
786
986
|
else {
|