centaurus-cli 2.8.8 → 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 (84) 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 +320 -26
  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 +8 -0
  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 +34 -23
  34. package/dist/index.js.map +1 -1
  35. package/dist/mcp/mcp-command-handler.js +2 -2
  36. package/dist/mcp/mcp-command-handler.js.map +1 -1
  37. package/dist/services/ai-service-client.d.ts.map +1 -1
  38. package/dist/services/ai-service-client.js +8 -6
  39. package/dist/services/ai-service-client.js.map +1 -1
  40. package/dist/services/api-client.d.ts +26 -0
  41. package/dist/services/api-client.d.ts.map +1 -1
  42. package/dist/services/api-client.js +19 -7
  43. package/dist/services/api-client.js.map +1 -1
  44. package/dist/services/background-task-manager.d.ts +114 -0
  45. package/dist/services/background-task-manager.d.ts.map +1 -0
  46. package/dist/services/background-task-manager.js +301 -0
  47. package/dist/services/background-task-manager.js.map +1 -0
  48. package/dist/services/local-chat-storage.d.ts.map +1 -1
  49. package/dist/services/local-chat-storage.js +5 -4
  50. package/dist/services/local-chat-storage.js.map +1 -1
  51. package/dist/tools/web-search.d.ts.map +1 -1
  52. package/dist/tools/web-search.js +8 -6
  53. package/dist/tools/web-search.js.map +1 -1
  54. package/dist/ui/components/App.d.ts +31 -0
  55. package/dist/ui/components/App.d.ts.map +1 -1
  56. package/dist/ui/components/App.js +277 -24
  57. package/dist/ui/components/App.js.map +1 -1
  58. package/dist/ui/components/ErrorBoundary.d.ts.map +1 -1
  59. package/dist/ui/components/ErrorBoundary.js +2 -1
  60. package/dist/ui/components/ErrorBoundary.js.map +1 -1
  61. package/dist/ui/components/InputBox.d.ts +4 -0
  62. package/dist/ui/components/InputBox.d.ts.map +1 -1
  63. package/dist/ui/components/InputBox.js +102 -19
  64. package/dist/ui/components/InputBox.js.map +1 -1
  65. package/dist/ui/components/ToolExecutionMessage.js +2 -2
  66. package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
  67. package/dist/utils/command-history.d.ts.map +1 -1
  68. package/dist/utils/command-history.js +2 -1
  69. package/dist/utils/command-history.js.map +1 -1
  70. package/dist/utils/conversation-logger.d.ts +15 -0
  71. package/dist/utils/conversation-logger.d.ts.map +1 -1
  72. package/dist/utils/conversation-logger.js +56 -2
  73. package/dist/utils/conversation-logger.js.map +1 -1
  74. package/dist/utils/editor-utils.d.ts.map +1 -1
  75. package/dist/utils/editor-utils.js +3 -2
  76. package/dist/utils/editor-utils.js.map +1 -1
  77. package/dist/utils/input-classifier.d.ts.map +1 -1
  78. package/dist/utils/input-classifier.js +2 -1
  79. package/dist/utils/input-classifier.js.map +1 -1
  80. package/dist/utils/logger.d.ts.map +1 -1
  81. package/dist/utils/logger.js +31 -1
  82. package/dist/utils/logger.js.map +1 -1
  83. package/package.json +1 -2
  84. package/models-config.json +0 -126
@@ -17,9 +17,10 @@ async function performBackendSearch(query, limit = 10, allowedDomains, blockedDo
17
17
  'Web search is a backend feature that requires authentication.');
18
18
  }
19
19
  try {
20
- const baseURL = process.env.DEV_MODE === 'true'
21
- ? 'http://localhost:3002/api'
22
- : (process.env.BACKEND_URL || 'https://centaurus-backend-354715948975.asia-south1.run.app/api');
20
+ // Import build config - values frozen at compile time for security
21
+ // SECURITY: This prevents malicious .env files from overriding production URLs
22
+ const { IS_DEV_BUILD, DEV_BACKEND_URL, PRODUCTION_BACKEND_URL } = await import('../config/build-config.js');
23
+ const baseURL = IS_DEV_BUILD ? DEV_BACKEND_URL : PRODUCTION_BACKEND_URL;
23
24
  const response = await axios.post(`${baseURL}/web-search/search`, {
24
25
  query,
25
26
  limit,
@@ -60,9 +61,10 @@ async function fetchUrlViaBackend(url) {
60
61
  'URL fetching is a backend feature that requires authentication.');
61
62
  }
62
63
  try {
63
- const baseURL = process.env.DEV_MODE === 'true'
64
- ? 'http://localhost:3002/api'
65
- : (process.env.BACKEND_URL || 'https://centaurus-backend-354715948975.asia-south1.run.app/api');
64
+ // Import build config - values frozen at compile time for security
65
+ // SECURITY: This prevents malicious .env files from overriding production URLs
66
+ const { IS_DEV_BUILD, DEV_BACKEND_URL, PRODUCTION_BACKEND_URL } = await import('../config/build-config.js');
67
+ const baseURL = IS_DEV_BUILD ? DEV_BACKEND_URL : PRODUCTION_BACKEND_URL;
66
68
  const response = await axios.post(`${baseURL}/web-search/fetch-url`, { url }, {
67
69
  headers: {
68
70
  'Content-Type': 'application/json',
@@ -1 +1 @@
1
- {"version":3,"file":"web-search.js","sourceRoot":"","sources":["../../src/tools/web-search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"web-search.js","sourceRoot":"","sources":["../../src/tools/web-search.ts"],"names":[],"mappings":"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"}
@@ -52,6 +52,10 @@ interface AppProps {
52
52
  onTaskCompleted: (callback: (task: PlanStep, taskNumber: number, totalTasks: number, completionNote?: string) => void) => void;
53
53
  onCommandModeChange: (callback: (commandMode: boolean) => void) => void;
54
54
  onToggleCommandMode: () => void;
55
+ onBackgroundModeChange: (callback: (backgroundMode: boolean) => void) => void;
56
+ onToggleBackgroundMode: () => void;
57
+ onBackgroundTaskCountChange: (callback: (count: number) => void) => void;
58
+ onSetAutoModeSetup: (callback: (enabled: boolean) => void) => void;
55
59
  onCwdChange: (callback: (cwd: string) => void) => void;
56
60
  onModelChange: (callback: (modelName: string) => void) => void;
57
61
  onSubshellContextChange: (callback: (context: SubshellContext) => void) => void;
@@ -95,6 +99,33 @@ interface AppProps {
95
99
  onChatRename: (chatId: string, newTitle: string) => void;
96
100
  onRestoreMessagesSetup: (callback: (messages: Message[]) => void) => void;
97
101
  onUIMessageHistoryUpdate: (messages: Message[]) => void;
102
+ onBackgroundTaskListSetup: (callback: (tasks: Array<{
103
+ id: string;
104
+ command: string;
105
+ cwd: string;
106
+ durationMs: number;
107
+ isRunning: boolean;
108
+ outputPreview: string;
109
+ }>) => void) => void;
110
+ onBackgroundTaskSelection: (taskId: string) => void;
111
+ onBackgroundTaskCancelSetup: (callback: (tasks: Array<{
112
+ id: string;
113
+ command: string;
114
+ cwd: string;
115
+ durationMs: number;
116
+ isRunning: boolean;
117
+ outputPreview: string;
118
+ }>) => void) => void;
119
+ onBackgroundTaskCancel: (taskId: string) => void;
120
+ onBackgroundTaskViewSetup: (callback: (task: {
121
+ id: string;
122
+ command: string;
123
+ cwd: string;
124
+ output: string;
125
+ isRunning: boolean;
126
+ onOutput: (handler: (chunk: string) => void) => void;
127
+ onComplete: (handler: (exitCode: number) => void) => void;
128
+ }) => void) => void;
98
129
  }
99
130
  export declare const App: React.FC<AppProps>;
100
131
  export {};
@@ -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,7 +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 * as fs from 'fs';
5
+ import { quickLog } from '../../utils/conversation-logger.js';
6
6
  import { WelcomeBanner } from './WelcomeBanner.js';
7
7
  import { InputBox } from './InputBox.js';
8
8
  import { MessageDisplay, countImagesInMessage } from './MessageDisplay.js';
@@ -23,6 +23,7 @@ import { DetailedPlanReviewScreen } from './DetailedPlanReviewScreen.js';
23
23
  import { TaskCompletedMessage } from './TaskCompletedMessage.js';
24
24
  import { PlanAcceptedMessage } from './PlanAcceptedMessage.js';
25
25
  import { processTerminalOutput } from '../../utils/terminal-output.js';
26
+ import { BackgroundTaskManager } from '../../services/background-task-manager.js';
26
27
  import { apiClient } from '../../services/api-client.js';
27
28
  import { conversationManager } from '../../services/conversation-manager.js';
28
29
  import { logDebug, logError } from '../../utils/logger.js';
@@ -135,9 +136,10 @@ const RenameInputScreen = ({ currentTitle, onRename, onCancel }) => {
135
136
  React.createElement(Box, { marginTop: 1 },
136
137
  React.createElement(Text, { dimColor: true }, "Press Enter to save, ESC to cancel"))));
137
138
  };
138
- 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 }) => {
139
140
  const { exit } = useApp();
140
141
  const autoAcceptRef = React.useRef(false);
142
+ const setAutoModeCallbackRef = React.useRef(null);
141
143
  // Helper to clear screen
142
144
  const clearScreen = useCallback(() => {
143
145
  process.stdout.write('\x1b[2J\x1b[3J\x1b[H');
@@ -182,6 +184,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
182
184
  currentModel: initialModel || 'gemini-2.5-flash',
183
185
  planMode: initialPlanMode || false,
184
186
  commandMode: false,
187
+ backgroundMode: false,
185
188
  currentWorkingDirectory: process.cwd(),
186
189
  showExitWarning: false,
187
190
  commandHistory: [],
@@ -198,6 +201,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
198
201
  planApprovalRequest: undefined,
199
202
  passwordRequest: undefined,
200
203
  connectionStatus: undefined,
204
+ backgroundTaskCount: 0,
201
205
  });
202
206
  // Track last terminal width to detect actual width changes
203
207
  const lastTerminalWidthRef = React.useRef(process.stdout.columns || 80);
@@ -387,7 +391,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
387
391
  onThoughtStream((thought) => {
388
392
  // Debug logging to file
389
393
  try {
390
- 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`);
391
395
  }
392
396
  catch (e) {
393
397
  // Ignore logging errors
@@ -406,7 +410,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
406
410
  (prev.currentMessage.thinkingDuration !== undefined && !isThoughtOnlyMessage);
407
411
  if (needsNewMessage) {
408
412
  try {
409
- 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`);
410
414
  }
411
415
  catch (e) {
412
416
  // Ignore logging errors
@@ -445,7 +449,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
445
449
  // (don't accumulate - the tool will handle displaying)
446
450
  if (isThoughtOnlyMessage) {
447
451
  try {
448
- 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`);
449
453
  }
450
454
  catch (e) { }
451
455
  return prev;
@@ -457,7 +461,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
457
461
  const allLines = thoughtAccumulatorRef.current.split('\n').filter(line => line.trim());
458
462
  const last3Lines = allLines.slice(-3);
459
463
  try {
460
- 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`);
461
465
  }
462
466
  catch (e) {
463
467
  // Ignore logging errors
@@ -477,7 +481,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
477
481
  React.useEffect(() => {
478
482
  onThoughtComplete((durationSeconds) => {
479
483
  try {
480
- 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`);
481
485
  }
482
486
  catch (e) {
483
487
  // Ignore
@@ -488,7 +492,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
488
492
  // Only update if we have a current assistant message
489
493
  if (!prev.currentMessage || prev.currentMessage.role !== 'assistant') {
490
494
  try {
491
- 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`);
492
496
  }
493
497
  catch (e) {
494
498
  // Ignore
@@ -496,7 +500,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
496
500
  return prev;
497
501
  }
498
502
  try {
499
- 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`);
500
504
  }
501
505
  catch (e) {
502
506
  // Ignore
@@ -593,7 +597,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
593
597
  // (meaning the message was moved to history mid-stream)
594
598
  if (lastAssistant.content.length < message.length) {
595
599
  try {
596
- 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`);
597
601
  }
598
602
  catch (e) { }
599
603
  const updatedHistory = [...prev.messageHistory];
@@ -735,6 +739,33 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
735
739
  }));
736
740
  });
737
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
738
769
  // Set up callback for message restoration (when resuming a chat)
739
770
  React.useEffect(() => {
740
771
  onRestoreMessagesSetup((restoredMessages) => {
@@ -748,6 +779,121 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
748
779
  }));
749
780
  });
750
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
751
897
  // Sync UI message history to CLI adapter whenever it changes
752
898
  React.useEffect(() => {
753
899
  onUIMessageHistoryUpdate(state.messageHistory);
@@ -758,7 +904,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
758
904
  // Special handling for execute_command
759
905
  if (update.toolName === 'execute_command') {
760
906
  try {
761
- 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`);
762
908
  }
763
909
  catch (e) { }
764
910
  // STARTING EXECUTION
@@ -897,10 +1043,10 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
897
1043
  setState(prev => {
898
1044
  // Debug logging to trace tool display issues
899
1045
  try {
900
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [App] onToolExecutionUpdate setState - toolName: ${update.toolName}, status: ${update.status}\n`);
901
- 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`);
902
1048
  if (prev.currentMessage?.thinkingDuration !== undefined) {
903
- 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`);
904
1050
  }
905
1051
  }
906
1052
  catch (e) { }
@@ -911,7 +1057,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
911
1057
  // Only track completed tools, skip executing tools (they need approval flow)
912
1058
  if (update.status === 'completed' || update.status === 'error') {
913
1059
  try {
914
- 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`);
915
1061
  }
916
1062
  catch (e) { }
917
1063
  // Add completed tool directly to history
@@ -945,7 +1091,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
945
1091
  // Tool completed - move to history with updated status
946
1092
  // Note: We now match ANY executing tool, not just same toolName (handles overlapping tools)
947
1093
  try {
948
- 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`);
949
1095
  }
950
1096
  catch (e) { }
951
1097
  const completedToolMessage = {
@@ -963,7 +1109,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
963
1109
  // This ensures thought-only messages stay as currentMessage until executing arrives
964
1110
  if (update.status === 'pending') {
965
1111
  try {
966
- 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`);
967
1113
  }
968
1114
  catch (e) { }
969
1115
  return prev; // Return unchanged state
@@ -982,13 +1128,13 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
982
1128
  // Carry the thinkingDuration to the tool message, don't add empty message to history
983
1129
  pendingThinkingDuration = prev.currentMessage.thinkingDuration;
984
1130
  try {
985
- 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`);
986
1132
  }
987
1133
  catch (e) { }
988
1134
  }
989
1135
  else {
990
1136
  try {
991
- 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`);
992
1138
  }
993
1139
  catch (e) { }
994
1140
  // Move ANY current message to history before showing tool
@@ -1010,7 +1156,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
1010
1156
  }
1011
1157
  // For completed tools without a current executing one (edge case)
1012
1158
  try {
1013
- 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`);
1014
1160
  }
1015
1161
  catch (e) { }
1016
1162
  let newHistory = prev.messageHistory;
@@ -1265,7 +1411,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
1265
1411
  // The plan will be displayed via the plan-approval screen
1266
1412
  // This callback can be used for additional notifications if needed
1267
1413
  try {
1268
- 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`);
1269
1415
  }
1270
1416
  catch (e) { }
1271
1417
  });
@@ -1374,7 +1520,7 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
1374
1520
  }
1375
1521
  else {
1376
1522
  // Fallback if no client available
1377
- console.error('SSH client not available for editor mode');
1523
+ logError('SSH client not available for editor mode', new Error('No SSH client'));
1378
1524
  setState(prev => ({ ...prev, isInteractiveEditorMode: false }));
1379
1525
  }
1380
1526
  }
@@ -1769,11 +1915,34 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
1769
1915
  state.screen === 'chat' && (React.createElement(React.Fragment, null,
1770
1916
  !state.shellState?.isFocused && (React.createElement(MessageList, { history: state.messageHistory, current: state.currentMessage, showBanner: true })),
1771
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
+ }
1772
1929
  // PTY MODE: Send everything immediately
1773
1930
  onShellInput(input);
1774
1931
  }, onFocusChange: (focused) => {
1775
1932
  // Clear screen when entering/exiting focus mode
1776
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
1777
1946
  setState(prev => ({
1778
1947
  ...prev,
1779
1948
  shellState: prev.shellState ? {
@@ -1782,6 +1951,15 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
1782
1951
  } : undefined
1783
1952
  }));
1784
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
+ }
1785
1963
  onShellSignal(signal);
1786
1964
  } })),
1787
1965
  state.isAiWorking && !state.shellState && !state.approvalRequest &&
@@ -1797,7 +1975,9 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
1797
1975
  // Clear preserved input on submit
1798
1976
  preservedInputTextRef.current = '';
1799
1977
  handleSubmit(value, clipboardImages);
1800
- }, 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, initialValue: preservedInputTextRef.current, onValueChange: handleInputValueChange }))),
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
+ } }))),
1801
1981
  state.showExitWarning && (React.createElement(Box, { marginTop: 1 },
1802
1982
  React.createElement(Text, { color: "#ffaa00", bold: true }, "\u26A0\uFE0F Press Ctrl+C again to exit"))))),
1803
1983
  state.screen === 'approval' && state.approvalRequest && (React.createElement(ApprovalSection, { key: `approval-${state.approvalRequest.message}`, approvalRequest: state.approvalRequest, onApprove: (approved) => {
@@ -2096,6 +2276,79 @@ export const App = ({ onMessage, onCancelRequest, initialModel, initialPlanMode,
2096
2276
  ...prev,
2097
2277
  screen: 'chat'
2098
2278
  }));
2099
- } })))));
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"))))));
2100
2353
  };
2101
2354
  //# sourceMappingURL=App.js.map