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
@@ -3,6 +3,7 @@ import { Plan, PlanStep } from './tools/plan-mode.js';
3
3
  import { SubshellContext } from './context/types.js';
4
4
  import { LocalChatMeta } from './services/local-chat-storage.js';
5
5
  import { Message } from './types/index.js';
6
+ import { BackgroundTaskInfo } from './services/background-task-manager.js';
6
7
  export declare class CentaurusCLI {
7
8
  private configManager;
8
9
  private toolRegistry;
@@ -11,6 +12,7 @@ export declare class CentaurusCLI {
11
12
  private planMode;
12
13
  private pendingPlanRequest;
13
14
  private commandMode;
15
+ private backgroundMode;
14
16
  private previousMode;
15
17
  private onResponseCallback?;
16
18
  private onDirectMessageCallback?;
@@ -49,6 +51,12 @@ export declare class CentaurusCLI {
49
51
  private uiMessageHistory;
50
52
  private localCwdBeforeRemote;
51
53
  private lastConnectionCommand;
54
+ private onBackgroundModeChange?;
55
+ private onBackgroundTaskCountChange?;
56
+ private onSetAutoMode?;
57
+ private onShowBackgroundTaskPickerCallback?;
58
+ private onShowBackgroundTaskCancelPickerCallback?;
59
+ private onBackgroundTaskViewCallback?;
52
60
  constructor();
53
61
  setOnResponseCallback(callback: (message: string) => void): void;
54
62
  setOnDirectMessageCallback(callback: (message: string) => void): void;
@@ -172,6 +180,54 @@ export declare class CentaurusCLI {
172
180
  * Set callback for showing chat rename picker
173
181
  */
174
182
  setOnShowChatRenamePickerCallback(callback: (chats: LocalChatMeta[], currentChatId: string | null) => void): void;
183
+ /**
184
+ * Set callback for background mode change
185
+ */
186
+ setOnBackgroundModeChange(callback: (backgroundMode: boolean) => void): void;
187
+ /**
188
+ * Set callback for background task count change
189
+ */
190
+ setOnBackgroundTaskCountChange(callback: (count: number) => void): void;
191
+ /**
192
+ * Set callback for setting Auto mode (used after background task starts)
193
+ */
194
+ setOnSetAutoMode(callback: (enabled: boolean) => void): void;
195
+ /**
196
+ * Set callback for showing background task picker
197
+ */
198
+ setOnShowBackgroundTaskPickerCallback(callback: (tasks: BackgroundTaskInfo[]) => void): void;
199
+ /**
200
+ * Set callback for showing background task cancel picker
201
+ */
202
+ setOnShowBackgroundTaskCancelPickerCallback(callback: (tasks: BackgroundTaskInfo[]) => void): void;
203
+ /**
204
+ * Toggle background mode
205
+ */
206
+ toggleBackgroundMode(): void;
207
+ /**
208
+ * Get current background mode state
209
+ */
210
+ getBackgroundMode(): boolean;
211
+ /**
212
+ * Handle background task cancellation
213
+ */
214
+ handleBackgroundTaskCancel(taskId: string): void;
215
+ /**
216
+ * Handle background task selection - show task output in focus mode
217
+ */
218
+ handleBackgroundTaskSelection(taskId: string): void;
219
+ /**
220
+ * Set callback for showing a background task in focus mode
221
+ */
222
+ setOnBackgroundTaskViewCallback(callback: (task: {
223
+ id: string;
224
+ command: string;
225
+ cwd: string;
226
+ output: string;
227
+ isRunning: boolean;
228
+ onOutput: (handler: (chunk: string) => void) => void;
229
+ onComplete: (handler: (exitCode: number) => void) => void;
230
+ }) => void): void;
175
231
  /**
176
232
  * Handle chat rename operation
177
233
  */
@@ -180,6 +236,11 @@ export declare class CentaurusCLI {
180
236
  * Handle chat delete picker selection
181
237
  */
182
238
  handleChatDeleteSelection(chatId: string): Promise<void>;
239
+ /**
240
+ * Handle background mode execution - runs command in background and returns immediately
241
+ * Supports both local and remote shells (SSH, WSL, Docker)
242
+ */
243
+ private handleBackgroundModeExecution;
183
244
  /**
184
245
  * Record a user shell command and its output to conversation history
185
246
  * This allows the AI to see what commands the user ran in command mode
@@ -1 +1 @@
1
- {"version":3,"file":"cli-adapter.d.ts","sourceRoot":"","sources":["../src/cli-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-adapter.d.ts","sourceRoot":"","sources":["../src/cli-adapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAY/C,OAAO,EAA6L,IAAI,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAcjP,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAQrD,OAAO,EAAmC,aAAa,EAAwC,MAAM,kCAAkC,CAAC;AACxI,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EAAyB,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAElG,qBAAa,YAAY;IACvB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,mBAAmB,CAAmB;IAC9C,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,YAAY,CAAyC;IAC7D,OAAO,CAAC,kBAAkB,CAAC,CAA4B;IACvD,OAAO,CAAC,uBAAuB,CAAC,CAA4B;IAC5D,OAAO,CAAC,wBAAwB,CAAC,CAA0B;IAC3D,OAAO,CAAC,uBAAuB,CAAC,CAA4B;IAC5D,OAAO,CAAC,yBAAyB,CAAC,CAAoC;IACtE,OAAO,CAAC,mBAAmB,CAAC,CAAiC;IAC7D,OAAO,CAAC,WAAW,CAAC,CAAwB;IAC5C,OAAO,CAAC,aAAa,CAAC,CAA8B;IACpD,OAAO,CAAC,oBAAoB,CAAC,CAA0G;IACvI,OAAO,CAAC,qBAAqB,CAAC,CAAoK;IAClM,OAAO,CAAC,qBAAqB,CAAC,CAAsP;IACpR,OAAO,CAAC,qBAAqB,CAAC,CAAmF;IACjH,OAAO,CAAC,gBAAgB,CAAC,CAA8B;IACvD,OAAO,CAAC,qBAAqB,CAAC,CAAmC;IACjE,OAAO,CAAC,aAAa,CAAC,CAAuB;IAC7C,OAAO,CAAC,eAAe,CAAC,CAA4F;IACpH,OAAO,CAAC,iBAAiB,CAAC,CAAuC;IACjE,OAAO,CAAC,yBAAyB,CAAC,CAAgC;IAClE,OAAO,CAAC,mBAAmB,CAAkB;IAC7C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,uBAAuB,CAAC,CAAqC;IACrE,OAAO,CAAC,sBAAsB,CAAC,CAAkB;IACjD,OAAO,CAAC,2BAA2B,CAAkB;IACrD,OAAO,CAAC,iBAAiB,CAAC,CAAoB;IAC9C,OAAO,CAAC,uBAAuB,CAAC,CAA6F;IAC7H,OAAO,CAAC,wBAAwB,CAAC,CAAiK;IAClM,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,wBAAwB,CAAC,CAAiE;IAClG,OAAO,CAAC,8BAA8B,CAAC,CAAiE;IACxG,OAAO,CAAC,sBAAsB,CAAC,CAAiE;IAChG,OAAO,CAAC,8BAA8B,CAAC,CAAiE;IACxG,OAAO,CAAC,yBAAyB,CAAC,CAAgC;IAClE,OAAO,CAAC,gBAAgB,CAAiB;IACzC,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,sBAAsB,CAAC,CAAoC;IACnE,OAAO,CAAC,2BAA2B,CAAC,CAA0B;IAC9D,OAAO,CAAC,aAAa,CAAC,CAA6B;IACnD,OAAO,CAAC,kCAAkC,CAAC,CAAiI;IAC5K,OAAO,CAAC,wCAAwC,CAAC,CAAiI;IAClL,OAAO,CAAC,4BAA4B,CAAC,CAAoN;;IA6BzP,qBAAqB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIhE,0BAA0B,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIrE,2BAA2B,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIpE,0BAA0B,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIrE,4BAA4B,CAAC,QAAQ,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAI/E,uBAAuB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI;IAIhJ,wBAAwB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI;IAI3M,wBAAwB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,aAAa,CAAC,EAAE,YAAY,GAAG,WAAW,GAAG,iBAAiB,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAIhT,wBAAwB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI;IAI1H,mBAAmB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAIhE,wBAAwB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAI1E,gBAAgB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI;IAItD,kBAAkB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAI7H,sBAAsB,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAItE,cAAc,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIrD,gBAAgB,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAI7D,0BAA0B,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI;IAI9E,oBAAoB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IAQ1E,0BAA0B,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI;IAItI,2BAA2B,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC;QAAC,MAAM,EAAE,YAAY,GAAG,WAAW,GAAG,OAAO,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI;YAI5K,aAAa;IAkB3B,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAUtC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI;IAU/C,kBAAkB,IAAI,IAAI;IAW1B,WAAW,IAAI,OAAO;IAItB,cAAc,IAAI,OAAO;IAIzB,0BAA0B,IAAI,MAAM;IAIpC,yBAAyB,IAAI,eAAe;IAI5C;;OAEG;IACH,wBAAwB,IAAI,MAAM,GAAG,IAAI;IAInC,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAoClF,OAAO,CAAC,UAAU,CAAC,CAAa;IAEhC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAkDxB;;OAEG;IACH,OAAO,CAAC,cAAc;IAUhB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA2CjC;;;OAGG;IACH,mBAAmB,IAAI,MAAM,GAAG,IAAI;IAkCpC;;OAEG;IACH,eAAe,IAAI,OAAO;IAI1B;;OAEG;YACW,yBAAyB;IA6BvC;;OAEG;YACW,oBAAoB;IAmBlC,QAAQ,IAAI,MAAM;IAMlB;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAQ5B;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAuC1B,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YA2nCrC,kBAAkB;IAiqBhC;;OAEG;IACH,2BAA2B,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI;IAI3G;;OAEG;IACH,iCAAiC,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI;IAIjH;;OAEG;IACH,yBAAyB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI;IAIzG;;OAEG;IACH,iCAAiC,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI;IAIjH;;OAEG;IACH,yBAAyB,CAAC,QAAQ,EAAE,CAAC,cAAc,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAI5E;;OAEG;IACH,8BAA8B,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAQvE;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAI5D;;OAEG;IACH,qCAAqC,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,IAAI,GAAG,IAAI;IAI5F;;OAEG;IACH,2CAA2C,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,IAAI,GAAG,IAAI;IAIlG;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAO5B;;OAEG;IACH,iBAAiB,IAAI,OAAO;IAI5B;;OAEG;IACH,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAehD;;OAEG;IACH,6BAA6B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAiEnD;;OAEG;IACH,+BAA+B,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;QAAC,UAAU,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI;IAIlQ;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAiBxD;;OAEG;IACG,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2C9D;;;OAGG;IACH,OAAO,CAAC,6BAA6B;IAyIrC;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAYnC;;OAEG;IACH,OAAO,CAAC,eAAe;IAiFvB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAkCjC;;OAEG;IACG,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkJ9D;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAa7B;;OAEG;IACH,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC;;OAEG;IACH,YAAY,IAAI,IAAI;IASpB;;;;;;OAMG;IACH,sBAAsB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI;IAmBjD;;OAEG;IACH,4BAA4B,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI;IAM3E;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAe7B;;;OAGG;IACH,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,uBAAuB;IAsC/B;;OAEG;IACH,iBAAiB,IAAI,IAAI;IA6BzB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAyC9B;;;OAGG;IACH,4BAA4B,CAAC,OAAO,EAAE,UAAU,CAAC,kBAAkB,GAAG,SAAS,GAAG,IAAI;IAItF;;OAEG;YACW,0BAA0B;CA6czC"}
@@ -20,7 +20,7 @@ import { readBinaryFileTool } from './tools/read-binary-file.js';
20
20
  import { apiClient } from './services/api-client.js';
21
21
  import { conversationManager } from './services/conversation-manager.js';
22
22
  import { aiServiceClient } from './services/ai-service-client.js';
23
- import { isValidModel, getInvalidModelError } from './config/models.js';
23
+ import { isValidModel, getInvalidModelError, fetchModelsConfig, getModelConfigByIdAndName } from './config/models.js';
24
24
  import { authenticateWithGoogle } from './services/auth-handler.js';
25
25
  import { ContextManager } from './context/context-manager.js';
26
26
  import { CommandDetector } from './context/command-detector.js';
@@ -32,9 +32,10 @@ import { MCPConfigManager } from './config/mcp-config-manager.js';
32
32
  import { MCPServerManager } from './mcp/mcp-server-manager.js';
33
33
  import { MCPCommandHandler } from './mcp/mcp-command-handler.js';
34
34
  import { isInteractiveEditorCommand, runWSLCommand, runDockerCommand, runSSHCommand } from './utils/editor-utils.js';
35
- import { conversationLogger } from './utils/conversation-logger.js';
35
+ import { conversationLogger, quickLog } from './utils/conversation-logger.js';
36
36
  import { localChatStorage } from './services/local-chat-storage.js';
37
37
  import { logWarning } from './utils/logger.js';
38
+ import { BackgroundTaskManager } from './services/background-task-manager.js';
38
39
  export class CentaurusCLI {
39
40
  configManager;
40
41
  toolRegistry;
@@ -43,6 +44,7 @@ export class CentaurusCLI {
43
44
  planMode = false;
44
45
  pendingPlanRequest = null; // Stores original user request during planning phase
45
46
  commandMode = false;
47
+ backgroundMode = false; // Background shell mode for running commands in background
46
48
  previousMode = 'execution';
47
49
  onResponseCallback;
48
50
  onDirectMessageCallback; // For slash commands - adds directly to history
@@ -81,6 +83,12 @@ export class CentaurusCLI {
81
83
  uiMessageHistory = []; // Mirror of App.tsx's messageHistory for saving
82
84
  localCwdBeforeRemote = null; // Track local CWD before entering remote session
83
85
  lastConnectionCommand = null; // Track the command used to connect to remote
86
+ onBackgroundModeChange;
87
+ onBackgroundTaskCountChange;
88
+ onSetAutoMode;
89
+ onShowBackgroundTaskPickerCallback;
90
+ onShowBackgroundTaskCancelPickerCallback;
91
+ onBackgroundTaskViewCallback;
84
92
  constructor() {
85
93
  this.configManager = new ConfigManager();
86
94
  this.toolRegistry = new ToolRegistry();
@@ -229,13 +237,13 @@ export class CentaurusCLI {
229
237
  }
230
238
  async handlePickerSelection(selection, pickerType) {
231
239
  try {
232
- // Selection is the index of the model in ALL_MODELS array
233
- const { ALL_MODELS } = await import('./config/models.js');
240
+ // Selection is the index of the model in models array from backend
241
+ const modelsConfig = await fetchModelsConfig();
234
242
  const modelIndex = parseInt(selection, 10);
235
- if (isNaN(modelIndex) || modelIndex < 0 || modelIndex >= ALL_MODELS.length) {
243
+ if (isNaN(modelIndex) || modelIndex < 0 || modelIndex >= modelsConfig.models.length) {
236
244
  throw new Error('Invalid model selection');
237
245
  }
238
- const selectedModel = ALL_MODELS[modelIndex];
246
+ const selectedModel = modelsConfig.models[modelIndex];
239
247
  // Store only the model ID and name (not the full config with thinkingConfig)
240
248
  // This prevents caching issues when we update model configs
241
249
  this.configManager.set('model', selectedModel.id);
@@ -485,7 +493,7 @@ Press Enter to continue...
485
493
  if (toolCallIds.size > 0) {
486
494
  // Log the cleanup for debugging
487
495
  try {
488
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [CLI] Cleaning up orphaned tool_calls: ${Array.from(toolCallIds).join(', ')}\n`);
496
+ quickLog(`[${new Date().toISOString()}] [CLI] Cleaning up orphaned tool_calls: ${Array.from(toolCallIds).join(', ')}\n`);
489
497
  }
490
498
  catch (e) { }
491
499
  // Remove the orphaned assistant message and any partial tool results after it
@@ -498,6 +506,11 @@ Press Enter to continue...
498
506
  await this.handleCommandModeExecution(message);
499
507
  return;
500
508
  }
509
+ // Handle background mode - execute commands in background
510
+ if (this.backgroundMode) {
511
+ this.handleBackgroundModeExecution(message);
512
+ return;
513
+ }
501
514
  // Handle slash commands
502
515
  if (message.startsWith('/')) {
503
516
  await this.handleSlashCommand(message);
@@ -569,10 +582,9 @@ DO NOT use write_to_file, edit_file, or execute_command until the plan is approv
569
582
  // Get selected model ID from config, then look up full config from models-config.json
570
583
  const config = this.configManager.load();
571
584
  const selectedModelId = config.model || 'gemini-2.5-flash';
572
- // Look up the full model config (including thinkingConfig) from models-config.json
573
- // This ensures we always use the latest config, not a cached version
574
- const { ALL_MODELS } = await import('./config/models.js');
575
- const selectedModelConfig = ALL_MODELS.find(m => m.id === selectedModelId && m.name === config.modelName);
585
+ // Look up the full model config (including thinkingConfig) from backend
586
+ // This ensures we always use the latest config
587
+ const selectedModelConfig = await getModelConfigByIdAndName(selectedModelId, config.modelName || '');
576
588
  const selectedModel = selectedModelId;
577
589
  const selectedModelThinkingConfig = selectedModelConfig?.thinkingConfig;
578
590
  // Build messages array WITHOUT system prompt - backend will inject it
@@ -629,10 +641,10 @@ DO NOT use write_to_file, edit_file, or execute_command until the plan is approv
629
641
  assistantWithToolCalls: messages.filter(m => m.role === 'assistant' && m.tool_calls && m.tool_calls.length > 0).length
630
642
  };
631
643
  try {
632
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [CLI] === TURN ${turnCount} AI CALL ===\n`);
633
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [CLI] Message history: ${messageStats.totalMessages} messages, ${messageStats.totalCharacters} chars\n`);
634
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [CLI] By role: system=${messageStats.byRole.system}, user=${messageStats.byRole.user}, assistant=${messageStats.byRole.assistant}, tool=${messageStats.byRole.tool}\n`);
635
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [CLI] Assistant messages with tool_calls: ${messageStats.assistantWithToolCalls}\n`);
644
+ quickLog(`[${new Date().toISOString()}] [CLI] === TURN ${turnCount} AI CALL ===\n`);
645
+ quickLog(`[${new Date().toISOString()}] [CLI] Message history: ${messageStats.totalMessages} messages, ${messageStats.totalCharacters} chars\n`);
646
+ quickLog(`[${new Date().toISOString()}] [CLI] By role: system=${messageStats.byRole.system}, user=${messageStats.byRole.user}, assistant=${messageStats.byRole.assistant}, tool=${messageStats.byRole.tool}\n`);
647
+ quickLog(`[${new Date().toISOString()}] [CLI] Assistant messages with tool_calls: ${messageStats.assistantWithToolCalls}\n`);
636
648
  }
637
649
  catch (e) { }
638
650
  // Stream AI response from backend
@@ -696,7 +708,7 @@ DO NOT use write_to_file, edit_file, or execute_command until the plan is approv
696
708
  const toolCall = chunk.toolCall;
697
709
  // Debug: Log every tool_call chunk received
698
710
  try {
699
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [CLI] *** TOOL_CALL CHUNK RECEIVED: ${toolCall?.name || 'unknown'}, toolCalls.length before push: ${toolCalls.length}\n`);
711
+ quickLog(`[${new Date().toISOString()}] [CLI] *** TOOL_CALL CHUNK RECEIVED: ${toolCall?.name || 'unknown'}, toolCalls.length before push: ${toolCalls.length}\n`);
700
712
  }
701
713
  catch (e) { }
702
714
  conversationLogger.logToolCall(toolCall?.name || 'unknown', toolCall?.id || 'unknown', toolCall?.arguments || {});
@@ -722,7 +734,7 @@ DO NOT use write_to_file, edit_file, or execute_command until the plan is approv
722
734
  }
723
735
  // Debug: Log after push
724
736
  try {
725
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [CLI] *** TOOL_CALL PUSHED: ${toolCall?.name || 'unknown'}, toolCalls.length after push: ${toolCalls.length}\n`);
737
+ quickLog(`[${new Date().toISOString()}] [CLI] *** TOOL_CALL PUSHED: ${toolCall?.name || 'unknown'}, toolCalls.length after push: ${toolCalls.length}\n`);
726
738
  }
727
739
  catch (e) { }
728
740
  }
@@ -777,7 +789,7 @@ DO NOT use write_to_file, edit_file, or execute_command until the plan is approv
777
789
  for (let i = 0; i < toolCalls.length; i++) {
778
790
  // Debug: Log which tool we're about to execute
779
791
  try {
780
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [CLI] *** ABOUT TO EXECUTE TOOL [${i + 1}/${toolCalls.length}]: ${toolCalls[i].name}\n`);
792
+ quickLog(`[${new Date().toISOString()}] [CLI] *** ABOUT TO EXECUTE TOOL [${i + 1}/${toolCalls.length}]: ${toolCalls[i].name}\n`);
781
793
  }
782
794
  catch (e) { }
783
795
  const toolCall = toolCalls[i];
@@ -1230,13 +1242,13 @@ DO NOT use write_to_file, edit_file, or execute_command until the plan is approv
1230
1242
  // Add assistant message with tool calls to conversation history
1231
1243
  if (toolCalls && toolCalls.length > 0) {
1232
1244
  try {
1233
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [CLI] Adapting assistant message: has toolCalls=${toolCalls.length}, first=${JSON.stringify(toolCalls[0])}\n`);
1245
+ quickLog(`[${new Date().toISOString()}] [CLI] Adapting assistant message: has toolCalls=${toolCalls.length}, first=${JSON.stringify(toolCalls[0])}\n`);
1234
1246
  }
1235
1247
  catch (e) { }
1236
1248
  }
1237
1249
  else {
1238
1250
  try {
1239
- fs.appendFileSync('cli_frontend_logs.txt', `[${new Date().toISOString()}] [CLI] Adapting assistant message: NO toolCalls\n`);
1251
+ quickLog(`[${new Date().toISOString()}] [CLI] Adapting assistant message: NO toolCalls\n`);
1240
1252
  }
1241
1253
  catch (e) { }
1242
1254
  }
@@ -1865,12 +1877,12 @@ Start by listing the directory structure to understand what you're working with.
1865
1877
  if (this.onShowPickerCallback) {
1866
1878
  const config = this.configManager.load();
1867
1879
  const currentModelName = config.modelName || '';
1868
- // Import ALL_MODELS to show all variants including duplicates
1869
- const { ALL_MODELS } = await import('./config/models.js');
1880
+ // Fetch models from backend
1881
+ const modelsConfig = await fetchModelsConfig();
1870
1882
  this.onShowPickerCallback({
1871
1883
  message: 'Select Model',
1872
1884
  type: 'model',
1873
- choices: ALL_MODELS.map((modelConfig, index) => ({
1885
+ choices: modelsConfig.models.map((modelConfig, index) => ({
1874
1886
  label: `${modelConfig.name} - ${modelConfig.description}${currentModelName === modelConfig.name ? ' [CURRENT]' : ''}`,
1875
1887
  value: `${index}` // Use index as unique identifier
1876
1888
  }))
@@ -1881,9 +1893,9 @@ Start by listing the directory structure to understand what you're working with.
1881
1893
  else {
1882
1894
  // Direct set via command argument
1883
1895
  const newModel = args.join(' ');
1884
- // Validate model
1885
- if (!isValidModel(newModel)) {
1886
- responseMessage = `āŒ ${getInvalidModelError(newModel)}`;
1896
+ // Validate model (async)
1897
+ if (!(await isValidModel(newModel))) {
1898
+ responseMessage = `āŒ ${await getInvalidModelError(newModel)}`;
1887
1899
  break;
1888
1900
  }
1889
1901
  try {
@@ -2084,6 +2096,57 @@ Start by listing the directory structure to understand what you're working with.
2084
2096
  ' /add-command delete <command> - Delete a custom command';
2085
2097
  }
2086
2098
  break;
2099
+ case 'background-task':
2100
+ case 'bkg':
2101
+ case 'bg-task':
2102
+ // Background task management commands
2103
+ const bkgSubCommand = args[0]?.toLowerCase();
2104
+ if (bkgSubCommand === 'list' || !bkgSubCommand) {
2105
+ // Show list of running background tasks
2106
+ const runningTasks = BackgroundTaskManager.getRunningTasks();
2107
+ if (runningTasks.length === 0) {
2108
+ responseMessage = 'šŸ“­ No background tasks running.\n\nSwitch to Background mode (Ctrl+D) to run commands in the background.';
2109
+ }
2110
+ else {
2111
+ // Show picker for task selection
2112
+ if (this.onShowBackgroundTaskPickerCallback) {
2113
+ this.onShowBackgroundTaskPickerCallback(runningTasks);
2114
+ return; // Don't send text response, picker will handle it
2115
+ }
2116
+ else {
2117
+ // Fallback: show as text
2118
+ responseMessage = 'šŸ”„ Running Background Tasks:\n\n' +
2119
+ runningTasks.map((task, i) => {
2120
+ const durationSec = Math.round(task.durationMs / 1000);
2121
+ return `${i + 1}. ${task.command}\n šŸ“ ${task.cwd} | ā±ļø ${durationSec}s running`;
2122
+ }).join('\n\n');
2123
+ }
2124
+ }
2125
+ }
2126
+ else if (bkgSubCommand === 'cancel') {
2127
+ // Show list of running tasks for cancellation
2128
+ const runningTasks = BackgroundTaskManager.getRunningTasks();
2129
+ if (runningTasks.length === 0) {
2130
+ responseMessage = 'šŸ“­ No background tasks to cancel.';
2131
+ }
2132
+ else {
2133
+ // Show picker for task cancellation
2134
+ if (this.onShowBackgroundTaskCancelPickerCallback) {
2135
+ this.onShowBackgroundTaskCancelPickerCallback(runningTasks);
2136
+ return; // Don't send text response, picker will handle it
2137
+ }
2138
+ else {
2139
+ responseMessage = 'āŒ Cancel picker not available. Use /background-task list to see tasks.';
2140
+ }
2141
+ }
2142
+ }
2143
+ else {
2144
+ responseMessage = `Unknown /background-task subcommand: ${bkgSubCommand}\n\n` +
2145
+ 'Usage:\n' +
2146
+ ' /background-task list - List running background tasks\n' +
2147
+ ' /background-task cancel - Cancel a running background task';
2148
+ }
2149
+ break;
2087
2150
  default:
2088
2151
  responseMessage = `Unknown command: /${cmd}\nType /help for available commands.`;
2089
2152
  }
@@ -2116,6 +2179,139 @@ Start by listing the directory structure to understand what you're working with.
2116
2179
  setOnShowChatRenamePickerCallback(callback) {
2117
2180
  this.onShowChatRenamePickerCallback = callback;
2118
2181
  }
2182
+ /**
2183
+ * Set callback for background mode change
2184
+ */
2185
+ setOnBackgroundModeChange(callback) {
2186
+ this.onBackgroundModeChange = callback;
2187
+ }
2188
+ /**
2189
+ * Set callback for background task count change
2190
+ */
2191
+ setOnBackgroundTaskCountChange(callback) {
2192
+ this.onBackgroundTaskCountChange = callback;
2193
+ // Subscribe to BackgroundTaskManager count changes
2194
+ BackgroundTaskManager.on('countChanged', (count) => {
2195
+ this.onBackgroundTaskCountChange?.(count);
2196
+ });
2197
+ }
2198
+ /**
2199
+ * Set callback for setting Auto mode (used after background task starts)
2200
+ */
2201
+ setOnSetAutoMode(callback) {
2202
+ this.onSetAutoMode = callback;
2203
+ }
2204
+ /**
2205
+ * Set callback for showing background task picker
2206
+ */
2207
+ setOnShowBackgroundTaskPickerCallback(callback) {
2208
+ this.onShowBackgroundTaskPickerCallback = callback;
2209
+ }
2210
+ /**
2211
+ * Set callback for showing background task cancel picker
2212
+ */
2213
+ setOnShowBackgroundTaskCancelPickerCallback(callback) {
2214
+ this.onShowBackgroundTaskCancelPickerCallback = callback;
2215
+ }
2216
+ /**
2217
+ * Toggle background mode
2218
+ */
2219
+ toggleBackgroundMode() {
2220
+ this.backgroundMode = !this.backgroundMode;
2221
+ if (this.onBackgroundModeChange) {
2222
+ this.onBackgroundModeChange(this.backgroundMode);
2223
+ }
2224
+ }
2225
+ /**
2226
+ * Get current background mode state
2227
+ */
2228
+ getBackgroundMode() {
2229
+ return this.backgroundMode;
2230
+ }
2231
+ /**
2232
+ * Handle background task cancellation
2233
+ */
2234
+ handleBackgroundTaskCancel(taskId) {
2235
+ const task = BackgroundTaskManager.getTask(taskId);
2236
+ const success = BackgroundTaskManager.cancelTask(taskId);
2237
+ if (success) {
2238
+ if (this.onDirectMessageCallback) {
2239
+ this.onDirectMessageCallback(`šŸ›‘ Cancelled background task: ${task?.command || taskId}`);
2240
+ }
2241
+ }
2242
+ else {
2243
+ if (this.onDirectMessageCallback) {
2244
+ this.onDirectMessageCallback(`āŒ Failed to cancel task. It may have already completed.`);
2245
+ }
2246
+ }
2247
+ }
2248
+ /**
2249
+ * Handle background task selection - show task output in focus mode
2250
+ */
2251
+ handleBackgroundTaskSelection(taskId) {
2252
+ const task = BackgroundTaskManager.getTask(taskId);
2253
+ if (!task) {
2254
+ if (this.onDirectMessageCallback) {
2255
+ this.onDirectMessageCallback(`āŒ Task not found: ${taskId}`);
2256
+ }
2257
+ return;
2258
+ }
2259
+ // Get the full output from the task
2260
+ const output = BackgroundTaskManager.getTaskOutput(taskId);
2261
+ // If we have the view callback, use it to show in focus mode (InteractiveShell)
2262
+ if (this.onBackgroundTaskViewCallback) {
2263
+ // Create event handlers for the App.tsx useEffect to subscribe to
2264
+ let onOutputHandler;
2265
+ let onCompleteHandler;
2266
+ // Subscribe to future output updates for this task
2267
+ const outputListener = (taskIdEvent, chunk) => {
2268
+ if (taskIdEvent === taskId && onOutputHandler) {
2269
+ onOutputHandler(chunk);
2270
+ }
2271
+ };
2272
+ // Subscribe to task completion
2273
+ const completeListener = (taskIdEvent, exitCode) => {
2274
+ if (taskIdEvent === taskId && onCompleteHandler) {
2275
+ onCompleteHandler(exitCode);
2276
+ // Cleanup listeners
2277
+ BackgroundTaskManager.off('taskOutput', outputListener);
2278
+ BackgroundTaskManager.off('taskCompleted', completeListener);
2279
+ }
2280
+ };
2281
+ BackgroundTaskManager.on('taskOutput', outputListener);
2282
+ BackgroundTaskManager.on('taskCompleted', completeListener);
2283
+ // Invoke the callback to set up shellState in App.tsx
2284
+ this.onBackgroundTaskViewCallback({
2285
+ id: taskId,
2286
+ command: task.command,
2287
+ cwd: task.cwd,
2288
+ output,
2289
+ isRunning: task.isRunning,
2290
+ onOutput: (handler) => { onOutputHandler = handler; },
2291
+ onComplete: (handler) => { onCompleteHandler = handler; }
2292
+ });
2293
+ // If task is already complete, immediately trigger completion
2294
+ if (!task.isRunning && task.exitCode !== undefined) {
2295
+ setTimeout(() => {
2296
+ if (onCompleteHandler) {
2297
+ onCompleteHandler(task.exitCode);
2298
+ }
2299
+ }, 100);
2300
+ }
2301
+ }
2302
+ else {
2303
+ // Fallback: show as static message
2304
+ if (this.onDirectMessageCallback) {
2305
+ this.onDirectMessageCallback(`šŸ“ŗ Viewing output for: ${task.command}\n\n${output || '(no output yet)'}`);
2306
+ }
2307
+ }
2308
+ }
2309
+ /**
2310
+ * Set callback for showing a background task in focus mode
2311
+ */
2312
+ setOnBackgroundTaskViewCallback(callback) {
2313
+ this.onBackgroundTaskViewCallback = callback;
2314
+ }
2119
2315
  /**
2120
2316
  * Handle chat rename operation
2121
2317
  */
@@ -2177,6 +2373,104 @@ Start by listing the directory structure to understand what you're working with.
2177
2373
  }
2178
2374
  }
2179
2375
  }
2376
+ /**
2377
+ * Handle background mode execution - runs command in background and returns immediately
2378
+ * Supports both local and remote shells (SSH, WSL, Docker)
2379
+ */
2380
+ handleBackgroundModeExecution(command) {
2381
+ if (!command.trim()) {
2382
+ return;
2383
+ }
2384
+ // Get current context to determine if we're in a remote shell
2385
+ const currentContext = this.contextManager.getCurrentContext();
2386
+ let taskId;
2387
+ let effectiveCwd;
2388
+ let remoteContextDisplay;
2389
+ if (currentContext.type === 'local') {
2390
+ // Local execution - use PTY
2391
+ effectiveCwd = this.cwd;
2392
+ taskId = BackgroundTaskManager.startTask(command, effectiveCwd);
2393
+ }
2394
+ else {
2395
+ // Remote execution - use appropriate remote PTY
2396
+ const metadata = currentContext.metadata;
2397
+ effectiveCwd = metadata?.workingDirectory || '~';
2398
+ // Build remote context display string
2399
+ if (currentContext.type === 'ssh' && metadata) {
2400
+ remoteContextDisplay = `${metadata.username || 'user'}@${metadata.hostname || 'remote'}`;
2401
+ }
2402
+ else if (currentContext.type === 'wsl' && metadata) {
2403
+ remoteContextDisplay = `wsl:${metadata.distroName || 'wsl'}`;
2404
+ }
2405
+ else if (currentContext.type === 'docker' && metadata) {
2406
+ remoteContextDisplay = `docker:${metadata.containerId?.substring(0, 12) || 'container'}`;
2407
+ }
2408
+ // Create the remote PTY process and register with BackgroundTaskManager
2409
+ if (currentContext.type === 'ssh') {
2410
+ const sshClient = currentContext.handler?.client;
2411
+ if (!sshClient) {
2412
+ if (this.onResponseCallback) {
2413
+ this.onResponseCallback('āŒ SSH client not available for background task');
2414
+ }
2415
+ return;
2416
+ }
2417
+ // Start remote task first to get callbacks
2418
+ const remoteTask = BackgroundTaskManager.startRemoteTask(command, effectiveCwd, remoteContextDisplay || 'ssh');
2419
+ taskId = remoteTask.id;
2420
+ // Create SSH PTY with the callbacks from BackgroundTaskManager
2421
+ const sshPty = runSSHCommand(sshClient, command, effectiveCwd, remoteTask.onData, remoteTask.onExit);
2422
+ remoteTask.setRemotePty(sshPty);
2423
+ }
2424
+ else if (currentContext.type === 'wsl') {
2425
+ const distribution = metadata?.distroName || 'Ubuntu';
2426
+ // Start remote task first to get callbacks
2427
+ const remoteTask = BackgroundTaskManager.startRemoteTask(command, effectiveCwd, remoteContextDisplay || 'wsl');
2428
+ taskId = remoteTask.id;
2429
+ // Create WSL PTY with the callbacks from BackgroundTaskManager
2430
+ const wslPty = runWSLCommand(distribution, command, effectiveCwd, remoteTask.onData, remoteTask.onExit);
2431
+ remoteTask.setRemotePty(wslPty);
2432
+ }
2433
+ else if (currentContext.type === 'docker') {
2434
+ const containerId = metadata?.containerId;
2435
+ if (!containerId) {
2436
+ if (this.onResponseCallback) {
2437
+ this.onResponseCallback('āŒ Docker container ID not available for background task');
2438
+ }
2439
+ return;
2440
+ }
2441
+ // Start remote task first to get callbacks
2442
+ const remoteTask = BackgroundTaskManager.startRemoteTask(command, effectiveCwd, remoteContextDisplay || 'docker');
2443
+ taskId = remoteTask.id;
2444
+ // Create Docker PTY with the callbacks from BackgroundTaskManager
2445
+ const dockerPty = runDockerCommand(containerId, command, effectiveCwd, remoteTask.onData, remoteTask.onExit);
2446
+ remoteTask.setRemotePty(dockerPty);
2447
+ }
2448
+ else {
2449
+ // Unknown remote type - fall back to local
2450
+ effectiveCwd = this.cwd;
2451
+ taskId = BackgroundTaskManager.startTask(command, effectiveCwd);
2452
+ }
2453
+ }
2454
+ // Notify user that task started
2455
+ const count = BackgroundTaskManager.getRunningCount();
2456
+ const locationInfo = remoteContextDisplay
2457
+ ? `\nšŸ“ Running on: ${remoteContextDisplay}`
2458
+ : '';
2459
+ if (this.onDirectMessageCallback) {
2460
+ this.onDirectMessageCallback(`šŸš€ Background task started: ${command}${locationInfo}\n\nTask ID: ${taskId}\nUse /background-task list to see running tasks.`);
2461
+ }
2462
+ // Optionally record to history for AI context
2463
+ this.recordShellCommandToHistory(command, '[Running in background]', effectiveCwd);
2464
+ // Reset to Auto mode after starting task
2465
+ this.backgroundMode = false;
2466
+ if (this.onBackgroundModeChange) {
2467
+ this.onBackgroundModeChange(false);
2468
+ }
2469
+ // Enable Auto mode in InputBox
2470
+ if (this.onSetAutoMode) {
2471
+ this.onSetAutoMode(true);
2472
+ }
2473
+ }
2180
2474
  /**
2181
2475
  * Record a user shell command and its output to conversation history
2182
2476
  * This allows the AI to see what commands the user ran in command mode