centaurus-cli 3.1.3 → 3.1.4

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 (138) hide show
  1. package/dist/cli-adapter.js +685 -153
  2. package/dist/cli-adapter.js.map +1 -1
  3. package/dist/config/defaultConfig.js +1 -4
  4. package/dist/config/defaultConfig.js.map +1 -1
  5. package/dist/config/models.js +4 -0
  6. package/dist/config/models.js.map +1 -1
  7. package/dist/config/slash-commands.js +66 -2
  8. package/dist/config/slash-commands.js.map +1 -1
  9. package/dist/config/types.js +4 -4
  10. package/dist/config/types.js.map +1 -1
  11. package/dist/index.js +36 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/services/ai-context-injector.js +109 -0
  14. package/dist/services/ai-context-injector.js.map +1 -1
  15. package/dist/services/api-client.js.map +1 -1
  16. package/dist/services/background-task-manager.js +59 -0
  17. package/dist/services/background-task-manager.js.map +1 -1
  18. package/dist/services/local-chat-storage.js +2 -0
  19. package/dist/services/local-chat-storage.js.map +1 -1
  20. package/dist/services/skill-storage.js +141 -0
  21. package/dist/services/skill-storage.js.map +1 -0
  22. package/dist/services/sub-agent-manager.js +49 -8
  23. package/dist/services/sub-agent-manager.js.map +1 -1
  24. package/dist/services/warpify-detector.js +17 -5
  25. package/dist/services/warpify-detector.js.map +1 -1
  26. package/dist/tools/background-command.js +5 -2
  27. package/dist/tools/background-command.js.map +1 -1
  28. package/dist/tools/command.js +367 -109
  29. package/dist/tools/command.js.map +1 -1
  30. package/dist/tools/file-ops.js +23 -6
  31. package/dist/tools/file-ops.js.map +1 -1
  32. package/dist/tools/plan-mode.js +184 -336
  33. package/dist/tools/plan-mode.js.map +1 -1
  34. package/dist/tools/sub-agent.js +24 -5
  35. package/dist/tools/sub-agent.js.map +1 -1
  36. package/dist/tools/todo-list.js +157 -0
  37. package/dist/tools/todo-list.js.map +1 -0
  38. package/dist/types/skill.js +30 -0
  39. package/dist/types/skill.js.map +1 -0
  40. package/dist/ui/components/App.js +956 -162
  41. package/dist/ui/components/App.js.map +1 -1
  42. package/dist/ui/components/AuthScreen.js +3 -1
  43. package/dist/ui/components/AuthScreen.js.map +1 -1
  44. package/dist/ui/components/AuthWelcomeScreen.js +3 -1
  45. package/dist/ui/components/AuthWelcomeScreen.js.map +1 -1
  46. package/dist/ui/components/CodeBlock.js +3 -1
  47. package/dist/ui/components/CodeBlock.js.map +1 -1
  48. package/dist/ui/components/CompactShellPreview.js +44 -0
  49. package/dist/ui/components/CompactShellPreview.js.map +1 -0
  50. package/dist/ui/components/ConfigViewer.js +3 -1
  51. package/dist/ui/components/ConfigViewer.js.map +1 -1
  52. package/dist/ui/components/ConfirmPrompt.js +3 -1
  53. package/dist/ui/components/ConfirmPrompt.js.map +1 -1
  54. package/dist/ui/components/ConnectionStatusMessage.js +3 -1
  55. package/dist/ui/components/ConnectionStatusMessage.js.map +1 -1
  56. package/dist/ui/components/DetailedPlanReviewScreen.js +84 -74
  57. package/dist/ui/components/DetailedPlanReviewScreen.js.map +1 -1
  58. package/dist/ui/components/DiffViewer.js +6 -3
  59. package/dist/ui/components/DiffViewer.js.map +1 -1
  60. package/dist/ui/components/FileCreationPreview.js.map +1 -1
  61. package/dist/ui/components/FileTagAutocomplete.js +4 -2
  62. package/dist/ui/components/FileTagAutocomplete.js.map +1 -1
  63. package/dist/ui/components/InputBox.js +243 -40
  64. package/dist/ui/components/InputBox.js.map +1 -1
  65. package/dist/ui/components/InteractiveShell.js +5 -3
  66. package/dist/ui/components/InteractiveShell.js.map +1 -1
  67. package/dist/ui/components/KeyboardHelp.js +4 -1
  68. package/dist/ui/components/KeyboardHelp.js.map +1 -1
  69. package/dist/ui/components/LoadingIndicator.js +3 -1
  70. package/dist/ui/components/LoadingIndicator.js.map +1 -1
  71. package/dist/ui/components/MCPAddScreen.js +63 -13
  72. package/dist/ui/components/MCPAddScreen.js.map +1 -1
  73. package/dist/ui/components/MarkdownRenderer.js +3 -1
  74. package/dist/ui/components/MarkdownRenderer.js.map +1 -1
  75. package/dist/ui/components/MessageDisplay.js +9 -7
  76. package/dist/ui/components/MessageDisplay.js.map +1 -1
  77. package/dist/ui/components/ModelPicker.js +170 -0
  78. package/dist/ui/components/ModelPicker.js.map +1 -0
  79. package/dist/ui/components/MonitorModeAIPanel.js +3 -1
  80. package/dist/ui/components/MonitorModeAIPanel.js.map +1 -1
  81. package/dist/ui/components/PlanAcceptedMessage.js +12 -6
  82. package/dist/ui/components/PlanAcceptedMessage.js.map +1 -1
  83. package/dist/ui/components/PlanQuestionMessage.js +37 -0
  84. package/dist/ui/components/PlanQuestionMessage.js.map +1 -0
  85. package/dist/ui/components/PlanQuestionScreen.js +138 -0
  86. package/dist/ui/components/PlanQuestionScreen.js.map +1 -0
  87. package/dist/ui/components/PlanReviewScreen.js +7 -9
  88. package/dist/ui/components/PlanReviewScreen.js.map +1 -1
  89. package/dist/ui/components/RulesEditorScreen.js +65 -28
  90. package/dist/ui/components/RulesEditorScreen.js.map +1 -1
  91. package/dist/ui/components/SelectPrompt.js +3 -1
  92. package/dist/ui/components/SelectPrompt.js.map +1 -1
  93. package/dist/ui/components/SkillCreatorScreen.js +217 -0
  94. package/dist/ui/components/SkillCreatorScreen.js.map +1 -0
  95. package/dist/ui/components/SlashCommandAutocomplete.js +4 -2
  96. package/dist/ui/components/SlashCommandAutocomplete.js.map +1 -1
  97. package/dist/ui/components/StatusBar.js +4 -2
  98. package/dist/ui/components/StatusBar.js.map +1 -1
  99. package/dist/ui/components/StreamingMessageDisplay.js +5 -3
  100. package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
  101. package/dist/ui/components/SubAgentListScreen.js +65 -0
  102. package/dist/ui/components/SubAgentListScreen.js.map +1 -0
  103. package/dist/ui/components/SubAgentViewScreen.js +123 -0
  104. package/dist/ui/components/SubAgentViewScreen.js.map +1 -0
  105. package/dist/ui/components/TaskCompletedMessage.js +40 -8
  106. package/dist/ui/components/TaskCompletedMessage.js.map +1 -1
  107. package/dist/ui/components/TaskProgressIndicator.js +6 -4
  108. package/dist/ui/components/TaskProgressIndicator.js.map +1 -1
  109. package/dist/ui/components/TextEditor.js +297 -0
  110. package/dist/ui/components/TextEditor.js.map +1 -0
  111. package/dist/ui/components/TodoListMessage.js +59 -0
  112. package/dist/ui/components/TodoListMessage.js.map +1 -0
  113. package/dist/ui/components/ToolExecutionMessage.js +134 -84
  114. package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
  115. package/dist/ui/components/ToolExecutionStatus.js +3 -1
  116. package/dist/ui/components/ToolExecutionStatus.js.map +1 -1
  117. package/dist/ui/components/WelcomeBanner.js +33 -33
  118. package/dist/ui/components/WelcomeBanner.js.map +1 -1
  119. package/dist/ui/components/WorkflowCreatorScreen.js +5 -3
  120. package/dist/ui/components/WorkflowCreatorScreen.js.map +1 -1
  121. package/dist/ui/theme.js +97 -0
  122. package/dist/ui/theme.js.map +1 -0
  123. package/dist/ui/utils/chat-history-limit.js +247 -0
  124. package/dist/ui/utils/chat-history-limit.js.map +1 -0
  125. package/dist/utils/chat-formatter.js +22 -9
  126. package/dist/utils/chat-formatter.js.map +1 -1
  127. package/dist/utils/input-classifier.js +11 -1
  128. package/dist/utils/input-classifier.js.map +1 -1
  129. package/dist/utils/output-truncation.js +175 -0
  130. package/dist/utils/output-truncation.js.map +1 -0
  131. package/dist/utils/rule-reference-resolver.js +3 -3
  132. package/dist/utils/rule-reference-resolver.js.map +1 -1
  133. package/dist/utils/tunnel-commands-manager.js +134 -0
  134. package/dist/utils/tunnel-commands-manager.js.map +1 -0
  135. package/package.json +91 -90
  136. package/postinstall.js +4 -11
  137. package/dist/ui/components/MultiLineInput.js +0 -255
  138. package/dist/ui/components/MultiLineInput.js.map +0 -1
@@ -23,10 +23,7 @@ const defaultConfig = {
23
23
  debugMode: false,
24
24
  logLevel: "error",
25
25
  temperature: 0.7,
26
- maxTokens: 8192,
27
- // Agent Mode Settings
28
- autonomousMode: true
29
- // Enable autonomous mode by default (optimized for code generation)
26
+ maxTokens: 8192
30
27
  };
31
28
  const themes = {
32
29
  default: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/defaultConfig.ts"],"sourcesContent":["/**\r\n * Default Configuration\r\n * Defines default settings and configuration types\r\n */\r\n\r\nexport interface CentaurusConfig {\r\n // Model settings\r\n model: string;\r\n \r\n // Features\r\n autoAccept: boolean;\r\n streamResponses: boolean;\r\n saveSession: boolean;\r\n \r\n // UI Settings\r\n theme: string;\r\n showWelcomeBanner: boolean;\r\n showStatusBar: boolean;\r\n syntaxHighlighting: boolean;\r\n \r\n // Tool Settings\r\n requireApproval: boolean;\r\n toolTimeout: number;\r\n maxRetries: number;\r\n \r\n // Session Settings\r\n maxHistorySize: number;\r\n contextWindowSize: number;\r\n \r\n // Advanced Settings\r\n debugMode: boolean;\r\n logLevel: 'error' | 'warn' | 'info' | 'debug';\r\n temperature: number;\r\n maxTokens: number;\r\n \r\n // Agent Mode Settings\r\n autonomousMode?: boolean; // Enable autonomous mode (Silent Operator with task_complete)\r\n}\r\n\r\nexport const defaultConfig: CentaurusConfig = {\r\n // Model settings\r\n model: 'gemini-2.5-flash',\r\n \r\n // Features\r\n autoAccept: false,\r\n streamResponses: true,\r\n saveSession: true,\r\n \r\n // UI Settings\r\n theme: 'default',\r\n showWelcomeBanner: true,\r\n showStatusBar: true,\r\n syntaxHighlighting: true,\r\n \r\n // Tool Settings\r\n requireApproval: true,\r\n toolTimeout: 30000, // 30 seconds\r\n maxRetries: 3,\r\n \r\n // Session Settings\r\n maxHistorySize: 1000,\r\n contextWindowSize: 50, // Number of messages to keep in context\r\n \r\n // Advanced Settings\r\n debugMode: false,\r\n logLevel: 'error',\r\n temperature: 0.7,\r\n maxTokens: 8192,\r\n \r\n // Agent Mode Settings\r\n autonomousMode: true // Enable autonomous mode by default (optimized for code generation)\r\n};\r\n\r\nexport const themes = {\r\n default: {\r\n primary: '#00CED1', // Cyan\r\n secondary: '#1E90FF', // Dodger Blue\r\n success: '#00FF00', // Green\r\n error: '#FF0000', // Red\r\n warning: '#FFA500', // Orange\r\n info: '#87CEEB', // Sky Blue\r\n text: '#FFFFFF', // White\r\n dimText: '#808080' // Gray\r\n },\r\n dark: {\r\n primary: '#00CED1',\r\n secondary: '#4B0082',\r\n success: '#32CD32',\r\n error: '#DC143C',\r\n warning: '#FF8C00',\r\n info: '#4682B4',\r\n text: '#F0F0F0',\r\n dimText: '#696969'\r\n },\r\n light: {\r\n primary: '#008B8B',\r\n secondary: '#0000CD',\r\n success: '#228B22',\r\n error: '#B22222',\r\n warning: '#FF6347',\r\n info: '#1E90FF',\r\n text: '#000000',\r\n dimText: '#A9A9A9'\r\n },\r\n ocean: {\r\n primary: '#00CED1',\r\n secondary: '#20B2AA',\r\n success: '#3CB371',\r\n error: '#FF6B6B',\r\n warning: '#FFD700',\r\n info: '#48D1CC',\r\n text: '#E0FFFF',\r\n dimText: '#708090'\r\n },\r\n forest: {\r\n primary: '#228B22',\r\n secondary: '#008000',\r\n success: '#00FF00',\r\n error: '#8B0000',\r\n warning: '#FFD700',\r\n info: '#90EE90',\r\n text: '#F5FFFA',\r\n dimText: '#556B2F'\r\n }\r\n};\r\n\r\nexport default defaultConfig;"],"mappings":"AAuCO,MAAM,gBAAiC;AAAA;AAAA,EAE5C,OAAO;AAAA;AAAA,EAGP,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,aAAa;AAAA;AAAA,EAGb,OAAO;AAAA,EACP,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,oBAAoB;AAAA;AAAA,EAGpB,iBAAiB;AAAA,EACjB,aAAa;AAAA;AAAA,EACb,YAAY;AAAA;AAAA,EAGZ,gBAAgB;AAAA,EAChB,mBAAmB;AAAA;AAAA;AAAA,EAGnB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW;AAAA;AAAA,EAGX,gBAAgB;AAAA;AAClB;AAEO,MAAM,SAAS;AAAA,EACpB,SAAS;AAAA,IACP,SAAS;AAAA;AAAA,IACT,WAAW;AAAA;AAAA,IACX,SAAS;AAAA;AAAA,IACT,OAAO;AAAA;AAAA,IACP,SAAS;AAAA;AAAA,IACT,MAAM;AAAA;AAAA,IACN,MAAM;AAAA;AAAA,IACN,SAAS;AAAA;AAAA,EACX;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AACF;AAEA,IAAO,wBAAQ;","names":[]}
1
+ {"version":3,"sources":["../../src/config/defaultConfig.ts"],"sourcesContent":["/**\r\n * Default Configuration\r\n * Defines default settings and configuration types\r\n */\r\n\r\nexport interface CentaurusConfig {\r\n // Model settings\r\n model: string;\r\n \r\n // Features\r\n autoAccept: boolean;\r\n streamResponses: boolean;\r\n saveSession: boolean;\r\n \r\n // UI Settings\r\n theme: string;\r\n showWelcomeBanner: boolean;\r\n showStatusBar: boolean;\r\n syntaxHighlighting: boolean;\r\n \r\n // Tool Settings\r\n requireApproval: boolean;\r\n toolTimeout: number;\r\n maxRetries: number;\r\n \r\n // Session Settings\r\n maxHistorySize: number;\r\n contextWindowSize: number;\r\n \r\n // Advanced Settings\r\n debugMode: boolean;\r\n logLevel: 'error' | 'warn' | 'info' | 'debug';\r\n temperature: number;\r\n maxTokens: number;\r\n}\r\n\r\nexport const defaultConfig: CentaurusConfig = {\r\n // Model settings\r\n model: 'gemini-2.5-flash',\r\n \r\n // Features\r\n autoAccept: false,\r\n streamResponses: true,\r\n saveSession: true,\r\n \r\n // UI Settings\r\n theme: 'default',\r\n showWelcomeBanner: true,\r\n showStatusBar: true,\r\n syntaxHighlighting: true,\r\n \r\n // Tool Settings\r\n requireApproval: true,\r\n toolTimeout: 30000, // 30 seconds\r\n maxRetries: 3,\r\n \r\n // Session Settings\r\n maxHistorySize: 1000,\r\n contextWindowSize: 50, // Number of messages to keep in context\r\n \r\n // Advanced Settings\r\n debugMode: false,\r\n logLevel: 'error',\r\n temperature: 0.7,\r\n maxTokens: 8192,\r\n};\r\n\r\nexport const themes = {\r\n default: {\r\n primary: '#00CED1', // Cyan\r\n secondary: '#1E90FF', // Dodger Blue\r\n success: '#00FF00', // Green\r\n error: '#FF0000', // Red\r\n warning: '#FFA500', // Orange\r\n info: '#87CEEB', // Sky Blue\r\n text: '#FFFFFF', // White\r\n dimText: '#808080' // Gray\r\n },\r\n dark: {\r\n primary: '#00CED1',\r\n secondary: '#4B0082',\r\n success: '#32CD32',\r\n error: '#DC143C',\r\n warning: '#FF8C00',\r\n info: '#4682B4',\r\n text: '#F0F0F0',\r\n dimText: '#696969'\r\n },\r\n light: {\r\n primary: '#008B8B',\r\n secondary: '#0000CD',\r\n success: '#228B22',\r\n error: '#B22222',\r\n warning: '#FF6347',\r\n info: '#1E90FF',\r\n text: '#000000',\r\n dimText: '#A9A9A9'\r\n },\r\n ocean: {\r\n primary: '#00CED1',\r\n secondary: '#20B2AA',\r\n success: '#3CB371',\r\n error: '#FF6B6B',\r\n warning: '#FFD700',\r\n info: '#48D1CC',\r\n text: '#E0FFFF',\r\n dimText: '#708090'\r\n },\r\n forest: {\r\n primary: '#228B22',\r\n secondary: '#008000',\r\n success: '#00FF00',\r\n error: '#8B0000',\r\n warning: '#FFD700',\r\n info: '#90EE90',\r\n text: '#F5FFFA',\r\n dimText: '#556B2F'\r\n }\r\n};\r\n\r\nexport default defaultConfig;"],"mappings":"AAoCO,MAAM,gBAAiC;AAAA;AAAA,EAE5C,OAAO;AAAA;AAAA,EAGP,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,aAAa;AAAA;AAAA,EAGb,OAAO;AAAA,EACP,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,oBAAoB;AAAA;AAAA,EAGpB,iBAAiB;AAAA,EACjB,aAAa;AAAA;AAAA,EACb,YAAY;AAAA;AAAA,EAGZ,gBAAgB;AAAA,EAChB,mBAAmB;AAAA;AAAA;AAAA,EAGnB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW;AACb;AAEO,MAAM,SAAS;AAAA,EACpB,SAAS;AAAA,IACP,SAAS;AAAA;AAAA,IACT,WAAW;AAAA;AAAA,IACX,SAAS;AAAA;AAAA,IACT,OAAO;AAAA;AAAA,IACP,SAAS;AAAA;AAAA,IACT,MAAM;AAAA;AAAA,IACN,MAAM;AAAA;AAAA,IACN,SAAS;AAAA;AAAA,EACX;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AACF;AAEA,IAAO,wBAAQ;","names":[]}
@@ -69,6 +69,10 @@ function getModelContextWindowSync(modelNameOrId) {
69
69
  if (nameLower.includes("kimi")) return 128e3;
70
70
  if (nameLower.includes("glm")) return 128e3;
71
71
  if (nameLower.includes("minimax")) return 128e3;
72
+ if (nameLower.includes("qwen")) return 131072;
73
+ if (nameLower.includes("gpt-oss")) return 128e3;
74
+ if (nameLower.includes("nemotron")) return 131072;
75
+ if (nameLower.includes("deepseek")) return 131072;
72
76
  if (nameLower.includes("gemini")) return 1e6;
73
77
  return 1e6;
74
78
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/models.ts"],"sourcesContent":["/**\r\n * Supported AI models\r\n * Fetched from backend API with caching\r\n */\r\n\r\nimport { apiClient, ModelConfig, ModelsConfig } from '../services/api-client.js';\r\nimport { logWarning } from '../utils/logger.js';\r\nimport { quickLog } from '../utils/conversation-logger.js';\r\n\r\n// Re-export types\r\nexport type { ModelConfig, ModelsConfig };\r\n\r\n/**\r\n * Cached models configuration\r\n * Fetched once per session from backend\r\n */\r\nlet cachedConfig: ModelsConfig | null = null;\r\nlet fetchPromise: Promise<ModelsConfig> | null = null;\r\n\r\n/**\r\n * Default fallback configuration when backend is unavailable\r\n */\r\nconst FALLBACK_CONFIG: ModelsConfig = {\r\n models: [\r\n {\r\n uid: 'gemini-2-5-flash',\r\n id: 'gemini-2.5-flash',\r\n name: 'Gemini 2.5 Flash',\r\n description: 'Fast and efficient',\r\n provider: 'google',\r\n contextWindow: 1000000,\r\n region: 'us-central1',\r\n supportsThinking: true,\r\n thinkingConfig: { thinking_config: { include_thoughts: true } },\r\n generationConfig: {\r\n temperature: 0.1,\r\n topP: 0.95,\r\n maxOutputTokens: 16384\r\n }\r\n }\r\n ],\r\n defaultModel: 'gemini-2.5-flash'\r\n};\r\n\r\n/**\r\n * Fetch models configuration from backend (with caching)\r\n * This is the main entry point for getting model config\r\n */\r\nexport async function fetchModelsConfig(): Promise<ModelsConfig> {\r\n // Return cached config if available\r\n if (cachedConfig) {\r\n return cachedConfig;\r\n }\r\n\r\n // If a fetch is already in progress, wait for it\r\n if (fetchPromise) {\r\n return fetchPromise;\r\n }\r\n\r\n // Start fetching from backend\r\n fetchPromise = (async () => {\r\n try {\r\n const config = await apiClient.getModelsConfig();\r\n cachedConfig = config;\r\n return config;\r\n } catch (error) {\r\n // On error, use fallback config\r\n logWarning('Failed to fetch models config from backend, using fallback');\r\n cachedConfig = FALLBACK_CONFIG;\r\n return FALLBACK_CONFIG;\r\n } finally {\r\n fetchPromise = null;\r\n }\r\n })();\r\n\r\n return fetchPromise;\r\n}\r\n\r\n/**\r\n * Clear cached config (useful for refreshing)\r\n */\r\nexport function clearModelsCache(): void {\r\n cachedConfig = null;\r\n fetchPromise = null;\r\n}\r\n\r\n/**\r\n * Get context window size for a model SYNCHRONOUSLY from cache\r\n * This is useful for UI components that need immediate values\r\n * Returns fallback defaults if cache is not yet populated\r\n * @param modelNameOrId - Model name or ID (case-insensitive search)\r\n * @returns Context window size in tokens\r\n */\r\nexport function getModelContextWindowSync(modelNameOrId: string): number {\r\n // DEBUG: Log cache state to file\r\n quickLog(`[${new Date().toISOString()}] [getModelContextWindowSync] Looking up: \"${modelNameOrId}\", cache populated: ${!!cachedConfig}, models in cache: ${cachedConfig?.models?.length || 0}\\n`);\r\n\r\n // Try to find in cache first\r\n if (cachedConfig) {\r\n const model = cachedConfig.models.find(m =>\r\n m.name.toLowerCase() === modelNameOrId.toLowerCase() ||\r\n m.id.toLowerCase() === modelNameOrId.toLowerCase()\r\n );\r\n if (model) {\r\n quickLog(`[${new Date().toISOString()}] [getModelContextWindowSync] Found model \"${model.name}\" with contextWindow: ${model.contextWindow}\\n`);\r\n return model.contextWindow;\r\n }\r\n quickLog(`[${new Date().toISOString()}] [getModelContextWindowSync] Model NOT found in cache. Available: ${cachedConfig.models.map(m => m.name).join(', ')}\\n`);\r\n }\r\n\r\n // Fallback defaults based on known patterns\r\n const nameLower = modelNameOrId.toLowerCase();\r\n if (nameLower.includes('kimi')) return 128000;\r\n if (nameLower.includes('glm')) return 128000;\r\n if (nameLower.includes('minimax')) return 128000;\r\n if (nameLower.includes('gemini')) return 1000000;\r\n return 1000000; // Default 1M tokens\r\n}\r\n\r\n\r\n/**\r\n * Get all model configurations (async)\r\n * @returns Promise resolving to array of all model configurations\r\n */\r\nexport async function getAllModelConfigs(): Promise<ModelConfig[]> {\r\n const config = await fetchModelsConfig();\r\n return config.models;\r\n}\r\n\r\n/**\r\n * Get model configuration by ID (async)\r\n * @param modelId - Model ID\r\n * @returns Promise resolving to model configuration or undefined\r\n */\r\nexport async function getModelConfig(modelId: string): Promise<ModelConfig | undefined> {\r\n const config = await fetchModelsConfig();\r\n return config.models.find(m => m.id === modelId);\r\n}\r\n\r\n/**\r\n * Get model configuration by ID and name (for duplicate model IDs with different configs)\r\n * @param modelId - Model ID\r\n * @param modelName - Model display name\r\n * @returns Promise resolving to model configuration or undefined\r\n */\r\nexport async function getModelConfigByIdAndName(modelId: string, modelName: string): Promise<ModelConfig | undefined> {\r\n const config = await fetchModelsConfig();\r\n return config.models.find(m => m.id === modelId && m.name === modelName);\r\n}\r\n\r\n/**\r\n * Get default model ID (async)\r\n * @returns Promise resolving to default model ID\r\n */\r\nexport async function getDefaultModel(): Promise<string> {\r\n const config = await fetchModelsConfig();\r\n return config.defaultModel;\r\n}\r\n\r\n/**\r\n * Get list of supported model IDs (unique) (async)\r\n * Excludes internal models that are not meant to be user-selectable\r\n * @returns Promise resolving to array of unique model IDs\r\n */\r\nexport async function getSupportedModels(): Promise<string[]> {\r\n const config = await fetchModelsConfig();\r\n // Backend already filters allowFrontendDisplay: false, but we check here too for robustness\r\n const userFacingModels = config.models.filter(m => m.allowFrontendDisplay !== false);\r\n return Array.from(new Set(userFacingModels.map(m => m.id)));\r\n}\r\n\r\n/**\r\n * Validate if a model name is supported (async)\r\n * @param model - Model name to validate\r\n * @returns Promise resolving to true if model is supported\r\n */\r\nexport async function isValidModel(model: string): Promise<boolean> {\r\n const models = await getSupportedModels();\r\n return models.includes(model);\r\n}\r\n\r\n/**\r\n * Get a user-friendly error message for invalid models (async)\r\n * @param invalidModel - The invalid model name\r\n * @returns Promise resolving to error message with list of valid models\r\n */\r\nexport async function getInvalidModelError(invalidModel: string): Promise<string> {\r\n const config = await fetchModelsConfig();\r\n // Only show user-facing models\r\n const userFacingModels = config.models.filter(m => m.allowFrontendDisplay !== false);\r\n return `Invalid model: ${invalidModel}\\n\\n` +\r\n `Supported models:\\n` +\r\n userFacingModels.map(m => ` - ${m.id} (${m.name})`).join('\\n') +\r\n `\\n\\nUse /model to select from available models.`;\r\n}\r\n\r\n/**\r\n * Get model display name with description (async)\r\n * @param model - Model ID\r\n * @returns Promise resolving to display name with description\r\n */\r\nexport async function getModelDisplayName(model: string): Promise<string> {\r\n const config = await getModelConfig(model);\r\n if (config) {\r\n return `${config.name} - ${config.description}`;\r\n }\r\n return model;\r\n}\r\n\r\n/**\r\n * Get context window size for a model (async)\r\n * @param model - Model ID\r\n * @returns Promise resolving to context window size in tokens\r\n */\r\nexport async function getModelContextWindow(model: string): Promise<number> {\r\n const config = await getModelConfig(model);\r\n return config?.contextWindow || 2000000; // Default 2M tokens\r\n}\r\n\r\n/**\r\n * Check if model supports thinking (async)\r\n * @param model - Model ID\r\n * @returns Promise resolving to true if model supports thinking\r\n */\r\nexport async function modelSupportsThinking(model: string): Promise<boolean> {\r\n const config = await getModelConfig(model);\r\n return config?.supportsThinking || false;\r\n}\r\n\r\n\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/config/models.ts"],"sourcesContent":["/**\r\n * Supported AI models\r\n * Fetched from backend API with caching\r\n */\r\n\r\nimport { apiClient, ModelConfig, ModelsConfig } from '../services/api-client.js';\r\nimport { logWarning } from '../utils/logger.js';\r\nimport { quickLog } from '../utils/conversation-logger.js';\r\n\r\n// Re-export types\r\nexport type { ModelConfig, ModelsConfig };\r\n\r\n/**\r\n * Cached models configuration\r\n * Fetched once per session from backend\r\n */\r\nlet cachedConfig: ModelsConfig | null = null;\r\nlet fetchPromise: Promise<ModelsConfig> | null = null;\r\n\r\n/**\r\n * Default fallback configuration when backend is unavailable\r\n */\r\nconst FALLBACK_CONFIG: ModelsConfig = {\r\n models: [\r\n {\r\n uid: 'gemini-2-5-flash',\r\n id: 'gemini-2.5-flash',\r\n name: 'Gemini 2.5 Flash',\r\n description: 'Fast and efficient',\r\n provider: 'google',\r\n contextWindow: 1000000,\r\n region: 'us-central1',\r\n supportsThinking: true,\r\n thinkingConfig: { thinking_config: { include_thoughts: true } },\r\n generationConfig: {\r\n temperature: 0.1,\r\n topP: 0.95,\r\n maxOutputTokens: 16384\r\n }\r\n }\r\n ],\r\n defaultModel: 'gemini-2.5-flash'\r\n};\r\n\r\n/**\r\n * Fetch models configuration from backend (with caching)\r\n * This is the main entry point for getting model config\r\n */\r\nexport async function fetchModelsConfig(): Promise<ModelsConfig> {\r\n // Return cached config if available\r\n if (cachedConfig) {\r\n return cachedConfig;\r\n }\r\n\r\n // If a fetch is already in progress, wait for it\r\n if (fetchPromise) {\r\n return fetchPromise;\r\n }\r\n\r\n // Start fetching from backend\r\n fetchPromise = (async () => {\r\n try {\r\n const config = await apiClient.getModelsConfig();\r\n cachedConfig = config;\r\n return config;\r\n } catch (error) {\r\n // On error, use fallback config\r\n logWarning('Failed to fetch models config from backend, using fallback');\r\n cachedConfig = FALLBACK_CONFIG;\r\n return FALLBACK_CONFIG;\r\n } finally {\r\n fetchPromise = null;\r\n }\r\n })();\r\n\r\n return fetchPromise;\r\n}\r\n\r\n/**\r\n * Clear cached config (useful for refreshing)\r\n */\r\nexport function clearModelsCache(): void {\r\n cachedConfig = null;\r\n fetchPromise = null;\r\n}\r\n\r\n/**\r\n * Get context window size for a model SYNCHRONOUSLY from cache\r\n * This is useful for UI components that need immediate values\r\n * Returns fallback defaults if cache is not yet populated\r\n * @param modelNameOrId - Model name or ID (case-insensitive search)\r\n * @returns Context window size in tokens\r\n */\r\nexport function getModelContextWindowSync(modelNameOrId: string): number {\r\n // DEBUG: Log cache state to file\r\n quickLog(`[${new Date().toISOString()}] [getModelContextWindowSync] Looking up: \"${modelNameOrId}\", cache populated: ${!!cachedConfig}, models in cache: ${cachedConfig?.models?.length || 0}\\n`);\r\n\r\n // Try to find in cache first\r\n if (cachedConfig) {\r\n const model = cachedConfig.models.find(m =>\r\n m.name.toLowerCase() === modelNameOrId.toLowerCase() ||\r\n m.id.toLowerCase() === modelNameOrId.toLowerCase()\r\n );\r\n if (model) {\r\n quickLog(`[${new Date().toISOString()}] [getModelContextWindowSync] Found model \"${model.name}\" with contextWindow: ${model.contextWindow}\\n`);\r\n return model.contextWindow;\r\n }\r\n quickLog(`[${new Date().toISOString()}] [getModelContextWindowSync] Model NOT found in cache. Available: ${cachedConfig.models.map(m => m.name).join(', ')}\\n`);\r\n }\r\n\r\n // Fallback defaults based on known patterns\r\n const nameLower = modelNameOrId.toLowerCase();\r\n if (nameLower.includes('kimi')) return 128000;\r\n if (nameLower.includes('glm')) return 128000;\r\n if (nameLower.includes('minimax')) return 128000;\r\n if (nameLower.includes('qwen')) return 131072;\r\n if (nameLower.includes('gpt-oss')) return 128000;\r\n if (nameLower.includes('nemotron')) return 131072;\r\n if (nameLower.includes('deepseek')) return 131072;\r\n if (nameLower.includes('gemini')) return 1000000;\r\n return 1000000; // Default 1M tokens\r\n}\r\n\r\n\r\n/**\r\n * Get all model configurations (async)\r\n * @returns Promise resolving to array of all model configurations\r\n */\r\nexport async function getAllModelConfigs(): Promise<ModelConfig[]> {\r\n const config = await fetchModelsConfig();\r\n return config.models;\r\n}\r\n\r\n/**\r\n * Get model configuration by ID (async)\r\n * @param modelId - Model ID\r\n * @returns Promise resolving to model configuration or undefined\r\n */\r\nexport async function getModelConfig(modelId: string): Promise<ModelConfig | undefined> {\r\n const config = await fetchModelsConfig();\r\n return config.models.find(m => m.id === modelId);\r\n}\r\n\r\n/**\r\n * Get model configuration by ID and name (for duplicate model IDs with different configs)\r\n * @param modelId - Model ID\r\n * @param modelName - Model display name\r\n * @returns Promise resolving to model configuration or undefined\r\n */\r\nexport async function getModelConfigByIdAndName(modelId: string, modelName: string): Promise<ModelConfig | undefined> {\r\n const config = await fetchModelsConfig();\r\n return config.models.find(m => m.id === modelId && m.name === modelName);\r\n}\r\n\r\n/**\r\n * Get default model ID (async)\r\n * @returns Promise resolving to default model ID\r\n */\r\nexport async function getDefaultModel(): Promise<string> {\r\n const config = await fetchModelsConfig();\r\n return config.defaultModel;\r\n}\r\n\r\n/**\r\n * Get list of supported model IDs (unique) (async)\r\n * Excludes internal models that are not meant to be user-selectable\r\n * @returns Promise resolving to array of unique model IDs\r\n */\r\nexport async function getSupportedModels(): Promise<string[]> {\r\n const config = await fetchModelsConfig();\r\n // Backend already filters allowFrontendDisplay: false, but we check here too for robustness\r\n const userFacingModels = config.models.filter(m => m.allowFrontendDisplay !== false);\r\n return Array.from(new Set(userFacingModels.map(m => m.id)));\r\n}\r\n\r\n/**\r\n * Validate if a model name is supported (async)\r\n * @param model - Model name to validate\r\n * @returns Promise resolving to true if model is supported\r\n */\r\nexport async function isValidModel(model: string): Promise<boolean> {\r\n const models = await getSupportedModels();\r\n return models.includes(model);\r\n}\r\n\r\n/**\r\n * Get a user-friendly error message for invalid models (async)\r\n * @param invalidModel - The invalid model name\r\n * @returns Promise resolving to error message with list of valid models\r\n */\r\nexport async function getInvalidModelError(invalidModel: string): Promise<string> {\r\n const config = await fetchModelsConfig();\r\n // Only show user-facing models\r\n const userFacingModels = config.models.filter(m => m.allowFrontendDisplay !== false);\r\n return `Invalid model: ${invalidModel}\\n\\n` +\r\n `Supported models:\\n` +\r\n userFacingModels.map(m => ` - ${m.id} (${m.name})`).join('\\n') +\r\n `\\n\\nUse /model to select from available models.`;\r\n}\r\n\r\n/**\r\n * Get model display name with description (async)\r\n * @param model - Model ID\r\n * @returns Promise resolving to display name with description\r\n */\r\nexport async function getModelDisplayName(model: string): Promise<string> {\r\n const config = await getModelConfig(model);\r\n if (config) {\r\n return `${config.name} - ${config.description}`;\r\n }\r\n return model;\r\n}\r\n\r\n/**\r\n * Get context window size for a model (async)\r\n * @param model - Model ID\r\n * @returns Promise resolving to context window size in tokens\r\n */\r\nexport async function getModelContextWindow(model: string): Promise<number> {\r\n const config = await getModelConfig(model);\r\n return config?.contextWindow || 2000000; // Default 2M tokens\r\n}\r\n\r\n/**\r\n * Check if model supports thinking (async)\r\n * @param model - Model ID\r\n * @returns Promise resolving to true if model supports thinking\r\n */\r\nexport async function modelSupportsThinking(model: string): Promise<boolean> {\r\n const config = await getModelConfig(model);\r\n return config?.supportsThinking || false;\r\n}\r\n\r\n\r\n"],"mappings":"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","names":[]}
@@ -20,7 +20,10 @@ const SLASH_COMMANDS = [
20
20
  { name: "exit", description: "Exit the application" },
21
21
  { name: "workflow", description: "Create and manage replayable command workflows", aliases: ["wf"] },
22
22
  { name: "rules", description: "Create and manage reusable prompt rules" },
23
- { name: "revert", description: "Revert to a previous question (undoes file changes)" }
23
+ { name: "revert", description: "Revert to a previous question (undoes file changes)" },
24
+ { name: "sub-agent", description: "View and manage running sub-agents", aliases: ["subagent"] },
25
+ { name: "compact", description: "Compact conversation context (removes file reads & terminal output)" },
26
+ { name: "skill", description: "Create and manage reusable agent skills" }
24
27
  ];
25
28
  const MCP_SUBCOMMANDS = [
26
29
  { name: "list", description: "List configured MCP servers and tools" },
@@ -55,12 +58,41 @@ const MODELS_SUBCOMMANDS = [
55
58
  { name: "local", description: "Select from locally installed Ollama models" }
56
59
  ];
57
60
  const SETTINGS_SUBCOMMANDS = [
58
- { name: "auto-suggest", description: "AI-powered command suggestions (on/off)" }
61
+ { name: "auto-suggest", description: "AI-powered command suggestions (on/off)" },
62
+ { name: "limit-chat-history", description: "Limit rendered chat history in the UI (on/off)" },
63
+ { name: "theme", description: "Change the UI accent color theme" },
64
+ { name: "add-tunnel-command", description: "Register a command prefix for Alt+E custom tunneling" }
59
65
  ];
60
66
  const SETTINGS_AUTOSUGGEST_OPTIONS = [
61
67
  { name: "on", description: "Enable AI auto-suggestions after 5 seconds of inactivity" },
62
68
  { name: "off", description: "Disable AI auto-suggestions" }
63
69
  ];
70
+ const SETTINGS_LIMIT_CHAT_HISTORY_OPTIONS = [
71
+ { name: "on", description: "Show only recent chat history in the UI to reduce terminal buffer usage" },
72
+ { name: "off", description: "Show the full chat history in the UI" }
73
+ ];
74
+ const SETTINGS_THEME_OPTIONS = [
75
+ { name: "blue", description: "Ocean Blue (default)", swatchColor: "#00ccff" },
76
+ { name: "cyan", description: "Cyan Teal", swatchColor: "#00ddbb" },
77
+ { name: "green", description: "Emerald Green", swatchColor: "#00cc88" },
78
+ { name: "lime", description: "Lime", swatchColor: "#88cc00" },
79
+ { name: "yellow", description: "Golden Yellow", swatchColor: "#ffcc00" },
80
+ { name: "orange", description: "Sunset Orange", swatchColor: "#ff8844" },
81
+ { name: "red", description: "Ruby Red", swatchColor: "#ff4466" },
82
+ { name: "pink", description: "Pink", swatchColor: "#ff66aa" },
83
+ { name: "violet", description: "Violet Purple", swatchColor: "#aa66ff" },
84
+ { name: "sky", description: "Sky Blue", swatchColor: "#4499ff" }
85
+ ];
86
+ const SUB_AGENT_SUBCOMMANDS = [
87
+ { name: "list", description: "List sub-agents and view their activity" },
88
+ { name: "terminate", description: "Terminate a running sub-agent" }
89
+ ];
90
+ const SKILL_SUBCOMMANDS = [
91
+ { name: "new", description: "Create a new agent skill" },
92
+ { name: "list", description: "List saved skills" },
93
+ { name: "edit", description: "Edit a saved skill (usage: /skill edit <name>)" },
94
+ { name: "delete", description: "Delete a saved skill (usage: /skill delete <name>)" }
95
+ ];
64
96
  const WORKFLOW_SUBCOMMANDS = [
65
97
  { name: "new", description: "Create a new workflow" },
66
98
  { name: "list", description: "List saved workflows" },
@@ -134,12 +166,40 @@ function filterCommands(query) {
134
166
  (cmd) => cmd.name.toLowerCase().startsWith(subQuery) || cmd.description.toLowerCase().includes(subQuery)
135
167
  );
136
168
  }
169
+ if (normalized.startsWith("settings limit-chat-history ")) {
170
+ const subQuery = normalized.slice(28);
171
+ return SETTINGS_LIMIT_CHAT_HISTORY_OPTIONS.filter(
172
+ (cmd) => cmd.name.toLowerCase().startsWith(subQuery) || cmd.description.toLowerCase().includes(subQuery)
173
+ );
174
+ }
175
+ if (normalized.startsWith("settings theme ")) {
176
+ const subQuery = normalized.slice(15);
177
+ return SETTINGS_THEME_OPTIONS.filter(
178
+ (cmd) => cmd.name.toLowerCase().startsWith(subQuery) || cmd.description.toLowerCase().includes(subQuery)
179
+ );
180
+ }
137
181
  if (normalized.startsWith("settings ")) {
138
182
  const subQuery = normalized.slice(9);
139
183
  return SETTINGS_SUBCOMMANDS.filter(
140
184
  (cmd) => cmd.name.toLowerCase().startsWith(subQuery) || cmd.description.toLowerCase().includes(subQuery)
141
185
  );
142
186
  }
187
+ if (normalized.startsWith("sub-agent ") || normalized.startsWith("subagent ")) {
188
+ const prefixLen = normalized.startsWith("sub-agent ") ? 10 : 9;
189
+ const subQuery = normalized.slice(prefixLen);
190
+ return SUB_AGENT_SUBCOMMANDS.filter(
191
+ (cmd) => cmd.name.toLowerCase().startsWith(subQuery) || cmd.description.toLowerCase().includes(subQuery)
192
+ );
193
+ }
194
+ if (normalized.startsWith("skill ")) {
195
+ const subQuery = normalized.slice(6);
196
+ if (subQuery.startsWith("edit ") || subQuery.startsWith("delete ")) {
197
+ return [];
198
+ }
199
+ return SKILL_SUBCOMMANDS.filter(
200
+ (cmd) => cmd.name.toLowerCase().startsWith(subQuery) || cmd.description.toLowerCase().includes(subQuery)
201
+ );
202
+ }
143
203
  if (normalized.startsWith("workflow new ") || normalized.startsWith("wf new ")) {
144
204
  const prefixLen = normalized.startsWith("workflow new ") ? 13 : 7;
145
205
  const subQuery = normalized.slice(prefixLen);
@@ -192,8 +252,12 @@ export {
192
252
  MODELS_SUBCOMMANDS,
193
253
  RULES_SUBCOMMANDS,
194
254
  SETTINGS_AUTOSUGGEST_OPTIONS,
255
+ SETTINGS_LIMIT_CHAT_HISTORY_OPTIONS,
195
256
  SETTINGS_SUBCOMMANDS,
257
+ SETTINGS_THEME_OPTIONS,
258
+ SKILL_SUBCOMMANDS,
196
259
  SLASH_COMMANDS,
260
+ SUB_AGENT_SUBCOMMANDS,
197
261
  SYNC_SUBCOMMANDS,
198
262
  WORKFLOW_NEW_SUBCOMMANDS,
199
263
  WORKFLOW_SUBCOMMANDS,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/slash-commands.ts"],"sourcesContent":["export interface SlashCommand {\r\n name: string;\r\n description: string;\r\n aliases?: string[];\r\n}\r\n\r\nexport const SLASH_COMMANDS: SlashCommand[] = [\r\n { name: 'help', description: 'Show this help message' },\r\n { name: 'init', description: 'Analyze project and create/load centaurus.md context file' },\r\n { name: 'chat', description: 'Manage chat sessions (resume previous chats)' },\r\n { name: 'clear', description: 'Clear conversation and start a new chat' },\r\n { name: 'sync', description: 'Sync data to/from cloud (upload/restore subcommands)' },\r\n { name: 'clean-ui', description: 'Refresh UI display to fix visual glitches', aliases: ['refresh-ui', 'redraw'] },\r\n { name: 'config', description: 'View current configuration' },\r\n { name: 'models', description: 'Select AI models (local Ollama or cloud)', aliases: ['model'] },\r\n { name: 'plan', description: 'Toggle plan mode for complex implementations' },\r\n { name: 'mcp', description: 'Manage configured MCP servers and tools' },\r\n { name: 'add-command', description: 'Manage custom terminal commands for auto-detect', aliases: ['add-command-auto-detect'] },\r\n { name: 'docs', description: 'Open Centaurus documentation in browser' },\r\n { name: 'background-task', description: 'Manage background shell tasks', aliases: ['bkg', 'bg-task'] },\r\n { name: 'copy-chat-context', description: 'Copy chat history as readable text to clipboard' },\r\n { name: 'session-limits', description: 'View session quota usage and limits' },\r\n { name: 'settings', description: 'Configure CLI settings' },\r\n { name: 'sign-in', description: 'Sign in with Google (if not already signed in)' },\r\n { name: 'logout', description: 'Sign out, clear session, and exit CLI' },\r\n { name: 'exit', description: 'Exit the application' },\r\n { name: 'workflow', description: 'Create and manage replayable command workflows', aliases: ['wf'] },\r\n { name: 'rules', description: 'Create and manage reusable prompt rules' },\r\n { name: 'revert', description: 'Revert to a previous question (undoes file changes)' },\r\n];\r\n\r\n// MCP subcommands\r\nexport const MCP_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'list', description: 'List configured MCP servers and tools' },\r\n { name: 'refresh', description: 'Restart MCP servers' },\r\n { name: 'add', description: 'Add a new MCP server' },\r\n { name: 'remove', description: 'Remove an MCP server' },\r\n { name: 'enable', description: 'Enable a disabled server' },\r\n { name: 'disable', description: 'Disable an enabled server' },\r\n];\r\n\r\n// Chat subcommands\r\nexport const CHAT_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'resume', description: 'Resume a previous chat session' },\r\n { name: 'list', description: 'List all saved chats' },\r\n { name: 'delete', description: 'Delete a saved chat' },\r\n { name: 'new', description: 'Start a new chat session' },\r\n { name: 'rename', description: 'Rename a saved chat' },\r\n];\r\n\r\n// Add-command subcommands (for custom terminal command auto-detect)\r\nexport const ADD_COMMAND_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'add', description: 'Add a custom command word (e.g., /add-command add mycommand)' },\r\n { name: 'delete', description: 'Delete a custom command word (e.g., /add-command delete mycommand)' },\r\n { name: 'list', description: 'List all custom command words' },\r\n];\r\n\r\n// Background-task subcommands\r\nexport const BACKGROUND_TASK_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'list', description: 'List running background tasks and view their output' },\r\n { name: 'cancel', description: 'Cancel a running background task' },\r\n];\r\n\r\n// Sync subcommands\r\nexport const SYNC_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'upload', description: 'Upload local chat history and config to cloud (overwrites cloud data)' },\r\n { name: 'restore', description: 'Download cloud data and restore locally (overwrites local data)' },\r\n];\r\n\r\n// Models subcommands (local vs cloud)\r\nexport const MODELS_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'cloud', description: 'Select powerful models from leading providers' },\r\n { name: 'local', description: 'Select from locally installed Ollama models' },\r\n];\r\n\r\n// Settings subcommands\r\nexport const SETTINGS_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'auto-suggest', description: 'AI-powered command suggestions (on/off)' },\r\n];\r\n\r\n// Settings auto-suggest options\r\nexport const SETTINGS_AUTOSUGGEST_OPTIONS: SlashCommand[] = [\r\n { name: 'on', description: 'Enable AI auto-suggestions after 5 seconds of inactivity' },\r\n { name: 'off', description: 'Disable AI auto-suggestions' },\r\n];\r\n\r\n// Workflow subcommands\r\nexport const WORKFLOW_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'new', description: 'Create a new workflow' },\r\n { name: 'list', description: 'List saved workflows' },\r\n { name: 'run', description: 'Run a workflow (usage: /workflow run <name>)' },\r\n { name: 'view', description: 'View workflow steps (usage: /workflow view <name>)' },\r\n { name: 'delete', description: 'Delete a workflow (usage: /workflow delete <name>)' },\r\n];\r\n\r\n// Rules subcommands\r\nexport const RULES_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'list', description: 'List saved reusable rules' },\r\n { name: 'add', description: 'Create a new reusable rule' },\r\n { name: 'edit', description: 'Edit a saved rule (usage: /rules edit <name>)' },\r\n { name: 'delete', description: 'Delete a saved rule (usage: /rules delete <name>)' },\r\n];\r\n\r\n// Workflow new subcommands (methods of creating a workflow)\r\nexport const WORKFLOW_NEW_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'manual', description: 'Manually create a workflow by typing steps' },\r\n { name: 'learn-workflow', description: 'Learn a workflow by recording your commands and prompts' },\r\n];\r\n\r\n/**\r\n * Filter commands based on query string\r\n * @param query The search query (without the leading /)\r\n * @returns Filtered and sorted commands\r\n */\r\nexport function filterCommands(query: string): SlashCommand[] {\r\n if (!query) {\r\n // No query - return all commands\r\n return SLASH_COMMANDS;\r\n }\r\n\r\n const normalized = query.toLowerCase();\r\n\r\n // Check if this is an MCP subcommand query (e.g., \"mcp list\")\r\n if (normalized.startsWith('mcp ')) {\r\n const subQuery = normalized.slice(4); // Remove \"mcp \"\r\n return MCP_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a chat subcommand query (e.g., \"chat resume\")\r\n if (normalized.startsWith('chat ')) {\r\n const subQuery = normalized.slice(5); // Remove \"chat \"\r\n return CHAT_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is an add-command subcommand query (e.g., \"add-command add\")\r\n if (normalized.startsWith('add-command ') || normalized.startsWith('add-command-auto-detect ')) {\r\n const prefixLen = normalized.startsWith('add-command-auto-detect ') ? 24 : 12;\r\n const subQuery = normalized.slice(prefixLen);\r\n return ADD_COMMAND_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a background-task subcommand query (e.g., \"background-task list\")\r\n if (normalized.startsWith('background-task ') || normalized.startsWith('bkg ') || normalized.startsWith('bg-task ')) {\r\n let subQuery = '';\r\n if (normalized.startsWith('background-task ')) {\r\n subQuery = normalized.slice(16);\r\n } else if (normalized.startsWith('bkg ')) {\r\n subQuery = normalized.slice(4);\r\n } else if (normalized.startsWith('bg-task ')) {\r\n subQuery = normalized.slice(8);\r\n }\r\n return BACKGROUND_TASK_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a sync subcommand query (e.g., \"sync upload\")\r\n if (normalized.startsWith('sync ')) {\r\n const subQuery = normalized.slice(5); // Remove \"sync \"\r\n return SYNC_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a models subcommand query (e.g., \"models local\" or \"model local\")\r\n if (normalized.startsWith('models ') || normalized.startsWith('model ')) {\r\n const prefixLen = normalized.startsWith('models ') ? 7 : 6;\r\n const subQuery = normalized.slice(prefixLen);\r\n return MODELS_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a settings auto-suggest option query (e.g., \"settings auto-suggest on\")\r\n if (normalized.startsWith('settings auto-suggest ')) {\r\n const subQuery = normalized.slice(22); // Remove \"settings auto-suggest \"\r\n return SETTINGS_AUTOSUGGEST_OPTIONS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a settings subcommand query (e.g., \"settings auto-suggest\")\r\n if (normalized.startsWith('settings ')) {\r\n const subQuery = normalized.slice(9); // Remove \"settings \"\r\n return SETTINGS_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a workflow new subcommand query (e.g., \"workflow new manual\" or \"wf new learn-workflow\")\r\n if (normalized.startsWith('workflow new ') || normalized.startsWith('wf new ')) {\r\n const prefixLen = normalized.startsWith('workflow new ') ? 13 : 7;\r\n const subQuery = normalized.slice(prefixLen);\r\n return WORKFLOW_NEW_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a revert subcommand query (e.g., \"revert checkpoint-123\")\r\n // Revert checkpoints are dynamic and fetched from CheckpointManager\r\n // Return empty array here - InputBox.tsx will handle dynamic checkpoint list\r\n if (normalized.startsWith('revert ')) {\r\n return []; // Dynamic - handled by InputBox with getCheckpoints()\r\n }\r\n\r\n // Check if this is a rules name query (e.g., \"rules edit frontend-review\")\r\n // Rule names are dynamic and fetched from RulesStorageService\r\n if (normalized.startsWith('rules edit ') || normalized.startsWith('rules delete ')) {\r\n return []; // Dynamic - handled by InputBox\r\n }\r\n\r\n // Check if this is a rules subcommand query (e.g., \"rules add\")\r\n if (normalized.startsWith('rules ')) {\r\n const subQuery = normalized.slice(6);\r\n return RULES_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a workflow subcommand query (e.g., \"workflow new\" or \"wf new\")\r\n if (normalized.startsWith('workflow ') || normalized.startsWith('wf ')) {\r\n const prefixLen = normalized.startsWith('workflow ') ? 9 : 3;\r\n const subQuery = normalized.slice(prefixLen);\r\n return WORKFLOW_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Filter commands that match\r\n const matches = SLASH_COMMANDS.filter(cmd => {\r\n // Match if command name starts with query\r\n if (cmd.name.toLowerCase().startsWith(normalized)) {\r\n return true;\r\n }\r\n\r\n // Or if description contains query\r\n if (cmd.description.toLowerCase().includes(normalized)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n });\r\n\r\n // Sort by relevance: exact prefix matches first\r\n matches.sort((a, b) => {\r\n const aStarts = a.name.toLowerCase().startsWith(normalized);\r\n const bStarts = b.name.toLowerCase().startsWith(normalized);\r\n\r\n if (aStarts && !bStarts) return -1;\r\n if (!aStarts && bStarts) return 1;\r\n\r\n // Both start or both don't start - sort alphabetically\r\n return a.name.localeCompare(b.name);\r\n });\r\n\r\n // Limit to 10 results\r\n return matches.slice(0, 10);\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/config/slash-commands.ts"],"sourcesContent":["export interface SlashCommand {\r\n name: string;\r\n description: string;\r\n aliases?: string[];\r\n swatchColor?: string; // Optional hex color for display swatch (used by theme options)\r\n}\r\n\r\nexport const SLASH_COMMANDS: SlashCommand[] = [\r\n { name: 'help', description: 'Show this help message' },\r\n { name: 'init', description: 'Analyze project and create/load centaurus.md context file' },\r\n { name: 'chat', description: 'Manage chat sessions (resume previous chats)' },\r\n { name: 'clear', description: 'Clear conversation and start a new chat' },\r\n { name: 'sync', description: 'Sync data to/from cloud (upload/restore subcommands)' },\r\n { name: 'clean-ui', description: 'Refresh UI display to fix visual glitches', aliases: ['refresh-ui', 'redraw'] },\r\n { name: 'config', description: 'View current configuration' },\r\n { name: 'models', description: 'Select AI models (local Ollama or cloud)', aliases: ['model'] },\r\n { name: 'plan', description: 'Toggle plan mode for complex implementations' },\r\n { name: 'mcp', description: 'Manage configured MCP servers and tools' },\r\n { name: 'add-command', description: 'Manage custom terminal commands for auto-detect', aliases: ['add-command-auto-detect'] },\r\n { name: 'docs', description: 'Open Centaurus documentation in browser' },\r\n { name: 'background-task', description: 'Manage background shell tasks', aliases: ['bkg', 'bg-task'] },\r\n { name: 'copy-chat-context', description: 'Copy chat history as readable text to clipboard' },\r\n { name: 'session-limits', description: 'View session quota usage and limits' },\r\n { name: 'settings', description: 'Configure CLI settings' },\r\n { name: 'sign-in', description: 'Sign in with Google (if not already signed in)' },\r\n { name: 'logout', description: 'Sign out, clear session, and exit CLI' },\r\n { name: 'exit', description: 'Exit the application' },\r\n { name: 'workflow', description: 'Create and manage replayable command workflows', aliases: ['wf'] },\r\n { name: 'rules', description: 'Create and manage reusable prompt rules' },\r\n { name: 'revert', description: 'Revert to a previous question (undoes file changes)' },\r\n { name: 'sub-agent', description: 'View and manage running sub-agents', aliases: ['subagent'] },\r\n { name: 'compact', description: 'Compact conversation context (removes file reads & terminal output)' },\r\n { name: 'skill', description: 'Create and manage reusable agent skills' },\r\n];\r\n\r\n// MCP subcommands\r\nexport const MCP_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'list', description: 'List configured MCP servers and tools' },\r\n { name: 'refresh', description: 'Restart MCP servers' },\r\n { name: 'add', description: 'Add a new MCP server' },\r\n { name: 'remove', description: 'Remove an MCP server' },\r\n { name: 'enable', description: 'Enable a disabled server' },\r\n { name: 'disable', description: 'Disable an enabled server' },\r\n];\r\n\r\n// Chat subcommands\r\nexport const CHAT_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'resume', description: 'Resume a previous chat session' },\r\n { name: 'list', description: 'List all saved chats' },\r\n { name: 'delete', description: 'Delete a saved chat' },\r\n { name: 'new', description: 'Start a new chat session' },\r\n { name: 'rename', description: 'Rename a saved chat' },\r\n];\r\n\r\n// Add-command subcommands (for custom terminal command auto-detect)\r\nexport const ADD_COMMAND_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'add', description: 'Add a custom command word (e.g., /add-command add mycommand)' },\r\n { name: 'delete', description: 'Delete a custom command word (e.g., /add-command delete mycommand)' },\r\n { name: 'list', description: 'List all custom command words' },\r\n];\r\n\r\n// Background-task subcommands\r\nexport const BACKGROUND_TASK_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'list', description: 'List running background tasks and view their output' },\r\n { name: 'cancel', description: 'Cancel a running background task' },\r\n];\r\n\r\n// Sync subcommands\r\nexport const SYNC_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'upload', description: 'Upload local chat history and config to cloud (overwrites cloud data)' },\r\n { name: 'restore', description: 'Download cloud data and restore locally (overwrites local data)' },\r\n];\r\n\r\n// Models subcommands (local vs cloud)\r\nexport const MODELS_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'cloud', description: 'Select powerful models from leading providers' },\r\n { name: 'local', description: 'Select from locally installed Ollama models' },\r\n];\r\n\r\n// Settings subcommands\r\nexport const SETTINGS_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'auto-suggest', description: 'AI-powered command suggestions (on/off)' },\r\n { name: 'limit-chat-history', description: 'Limit rendered chat history in the UI (on/off)' },\r\n { name: 'theme', description: 'Change the UI accent color theme' },\r\n { name: 'add-tunnel-command', description: 'Register a command prefix for Alt+E custom tunneling' },\r\n];\r\n\r\n// Settings auto-suggest options\r\nexport const SETTINGS_AUTOSUGGEST_OPTIONS: SlashCommand[] = [\r\n { name: 'on', description: 'Enable AI auto-suggestions after 5 seconds of inactivity' },\r\n { name: 'off', description: 'Disable AI auto-suggestions' },\r\n];\r\n\r\nexport const SETTINGS_LIMIT_CHAT_HISTORY_OPTIONS: SlashCommand[] = [\r\n { name: 'on', description: 'Show only recent chat history in the UI to reduce terminal buffer usage' },\r\n { name: 'off', description: 'Show the full chat history in the UI' },\r\n];\r\n\r\n// Settings theme color options\r\nexport const SETTINGS_THEME_OPTIONS: SlashCommand[] = [\r\n { name: 'blue', description: 'Ocean Blue (default)', swatchColor: '#00ccff' },\r\n { name: 'cyan', description: 'Cyan Teal', swatchColor: '#00ddbb' },\r\n { name: 'green', description: 'Emerald Green', swatchColor: '#00cc88' },\r\n { name: 'lime', description: 'Lime', swatchColor: '#88cc00' },\r\n { name: 'yellow', description: 'Golden Yellow', swatchColor: '#ffcc00' },\r\n { name: 'orange', description: 'Sunset Orange', swatchColor: '#ff8844' },\r\n { name: 'red', description: 'Ruby Red', swatchColor: '#ff4466' },\r\n { name: 'pink', description: 'Pink', swatchColor: '#ff66aa' },\r\n { name: 'violet', description: 'Violet Purple', swatchColor: '#aa66ff' },\r\n { name: 'sky', description: 'Sky Blue', swatchColor: '#4499ff' },\r\n];\r\n\r\n// Sub-agent subcommands\r\nexport const SUB_AGENT_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'list', description: 'List sub-agents and view their activity' },\r\n { name: 'terminate', description: 'Terminate a running sub-agent' },\r\n];\r\n\r\n// Skill subcommands\r\nexport const SKILL_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'new', description: 'Create a new agent skill' },\r\n { name: 'list', description: 'List saved skills' },\r\n { name: 'edit', description: 'Edit a saved skill (usage: /skill edit <name>)' },\r\n { name: 'delete', description: 'Delete a saved skill (usage: /skill delete <name>)' },\r\n];\r\n\r\n// Workflow subcommands\r\nexport const WORKFLOW_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'new', description: 'Create a new workflow' },\r\n { name: 'list', description: 'List saved workflows' },\r\n { name: 'run', description: 'Run a workflow (usage: /workflow run <name>)' },\r\n { name: 'view', description: 'View workflow steps (usage: /workflow view <name>)' },\r\n { name: 'delete', description: 'Delete a workflow (usage: /workflow delete <name>)' },\r\n];\r\n\r\n// Rules subcommands\r\nexport const RULES_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'list', description: 'List saved reusable rules' },\r\n { name: 'add', description: 'Create a new reusable rule' },\r\n { name: 'edit', description: 'Edit a saved rule (usage: /rules edit <name>)' },\r\n { name: 'delete', description: 'Delete a saved rule (usage: /rules delete <name>)' },\r\n];\r\n\r\n// Workflow new subcommands (methods of creating a workflow)\r\nexport const WORKFLOW_NEW_SUBCOMMANDS: SlashCommand[] = [\r\n { name: 'manual', description: 'Manually create a workflow by typing steps' },\r\n { name: 'learn-workflow', description: 'Learn a workflow by recording your commands and prompts' },\r\n];\r\n\r\n/**\r\n * Filter commands based on query string\r\n * @param query The search query (without the leading /)\r\n * @returns Filtered and sorted commands\r\n */\r\nexport function filterCommands(query: string): SlashCommand[] {\r\n if (!query) {\r\n // No query - return all commands\r\n return SLASH_COMMANDS;\r\n }\r\n\r\n const normalized = query.toLowerCase();\r\n\r\n // Check if this is an MCP subcommand query (e.g., \"mcp list\")\r\n if (normalized.startsWith('mcp ')) {\r\n const subQuery = normalized.slice(4); // Remove \"mcp \"\r\n return MCP_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a chat subcommand query (e.g., \"chat resume\")\r\n if (normalized.startsWith('chat ')) {\r\n const subQuery = normalized.slice(5); // Remove \"chat \"\r\n return CHAT_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is an add-command subcommand query (e.g., \"add-command add\")\r\n if (normalized.startsWith('add-command ') || normalized.startsWith('add-command-auto-detect ')) {\r\n const prefixLen = normalized.startsWith('add-command-auto-detect ') ? 24 : 12;\r\n const subQuery = normalized.slice(prefixLen);\r\n return ADD_COMMAND_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a background-task subcommand query (e.g., \"background-task list\")\r\n if (normalized.startsWith('background-task ') || normalized.startsWith('bkg ') || normalized.startsWith('bg-task ')) {\r\n let subQuery = '';\r\n if (normalized.startsWith('background-task ')) {\r\n subQuery = normalized.slice(16);\r\n } else if (normalized.startsWith('bkg ')) {\r\n subQuery = normalized.slice(4);\r\n } else if (normalized.startsWith('bg-task ')) {\r\n subQuery = normalized.slice(8);\r\n }\r\n return BACKGROUND_TASK_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a sync subcommand query (e.g., \"sync upload\")\r\n if (normalized.startsWith('sync ')) {\r\n const subQuery = normalized.slice(5); // Remove \"sync \"\r\n return SYNC_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a models subcommand query (e.g., \"models local\" or \"model local\")\r\n if (normalized.startsWith('models ') || normalized.startsWith('model ')) {\r\n const prefixLen = normalized.startsWith('models ') ? 7 : 6;\r\n const subQuery = normalized.slice(prefixLen);\r\n return MODELS_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a settings auto-suggest option query (e.g., \"settings auto-suggest on\")\r\n if (normalized.startsWith('settings auto-suggest ')) {\r\n const subQuery = normalized.slice(22); // Remove \"settings auto-suggest \"\r\n return SETTINGS_AUTOSUGGEST_OPTIONS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a settings limit-chat-history option query (e.g., \"settings limit-chat-history on\")\r\n if (normalized.startsWith('settings limit-chat-history ')) {\r\n const subQuery = normalized.slice(28); // Remove \"settings limit-chat-history \"\r\n return SETTINGS_LIMIT_CHAT_HISTORY_OPTIONS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a settings theme option query (e.g., \"settings theme blue\")\r\n if (normalized.startsWith('settings theme ')) {\r\n const subQuery = normalized.slice(15); // Remove \"settings theme \"\r\n return SETTINGS_THEME_OPTIONS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a settings subcommand query (e.g., \"settings auto-suggest\")\r\n if (normalized.startsWith('settings ')) {\r\n const subQuery = normalized.slice(9); // Remove \"settings \"\r\n return SETTINGS_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a sub-agent subcommand query (e.g., \"sub-agent list\")\r\n if (normalized.startsWith('sub-agent ') || normalized.startsWith('subagent ')) {\r\n const prefixLen = normalized.startsWith('sub-agent ') ? 10 : 9;\r\n const subQuery = normalized.slice(prefixLen);\r\n return SUB_AGENT_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a skill subcommand query (e.g., \"skill new\")\r\n if (normalized.startsWith('skill ')) {\r\n const subQuery = normalized.slice(6);\r\n // For edit/delete, dynamic skill names are handled by InputBox\r\n if (subQuery.startsWith('edit ') || subQuery.startsWith('delete ')) {\r\n return []; // Dynamic — handled by InputBox\r\n }\r\n return SKILL_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a workflow new subcommand query (e.g., \"workflow new manual\" or \"wf new learn-workflow\")\r\n if (normalized.startsWith('workflow new ') || normalized.startsWith('wf new ')) {\r\n const prefixLen = normalized.startsWith('workflow new ') ? 13 : 7;\r\n const subQuery = normalized.slice(prefixLen);\r\n return WORKFLOW_NEW_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a revert subcommand query (e.g., \"revert checkpoint-123\")\r\n // Revert checkpoints are dynamic and fetched from CheckpointManager\r\n // Return empty array here - InputBox.tsx will handle dynamic checkpoint list\r\n if (normalized.startsWith('revert ')) {\r\n return []; // Dynamic - handled by InputBox with getCheckpoints()\r\n }\r\n\r\n // Check if this is a rules name query (e.g., \"rules edit frontend-review\")\r\n // Rule names are dynamic and fetched from RulesStorageService\r\n if (normalized.startsWith('rules edit ') || normalized.startsWith('rules delete ')) {\r\n return []; // Dynamic - handled by InputBox\r\n }\r\n\r\n // Check if this is a rules subcommand query (e.g., \"rules add\")\r\n if (normalized.startsWith('rules ')) {\r\n const subQuery = normalized.slice(6);\r\n return RULES_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Check if this is a workflow subcommand query (e.g., \"workflow new\" or \"wf new\")\r\n if (normalized.startsWith('workflow ') || normalized.startsWith('wf ')) {\r\n const prefixLen = normalized.startsWith('workflow ') ? 9 : 3;\r\n const subQuery = normalized.slice(prefixLen);\r\n return WORKFLOW_SUBCOMMANDS.filter(cmd =>\r\n cmd.name.toLowerCase().startsWith(subQuery) ||\r\n cmd.description.toLowerCase().includes(subQuery)\r\n );\r\n }\r\n\r\n // Filter commands that match\r\n const matches = SLASH_COMMANDS.filter(cmd => {\r\n // Match if command name starts with query\r\n if (cmd.name.toLowerCase().startsWith(normalized)) {\r\n return true;\r\n }\r\n\r\n // Or if description contains query\r\n if (cmd.description.toLowerCase().includes(normalized)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n });\r\n\r\n // Sort by relevance: exact prefix matches first\r\n matches.sort((a, b) => {\r\n const aStarts = a.name.toLowerCase().startsWith(normalized);\r\n const bStarts = b.name.toLowerCase().startsWith(normalized);\r\n\r\n if (aStarts && !bStarts) return -1;\r\n if (!aStarts && bStarts) return 1;\r\n\r\n // Both start or both don't start - sort alphabetically\r\n return a.name.localeCompare(b.name);\r\n });\r\n\r\n // Limit to 10 results\r\n return matches.slice(0, 10);\r\n}\r\n"],"mappings":"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","names":[]}
@@ -1,14 +1,14 @@
1
1
  const DEFAULT_CONFIG = {
2
2
  model: "gemini-2.5-flash",
3
3
  autoApprove: false,
4
- enhancedQuality: true,
5
- // Enable enhanced quality features by default
6
4
  externalThinking: false,
7
5
  // Disable external thinking by default (internal reasoning)
8
- autonomousMode: false,
9
- // Disable autonomous mode by default (for backward compatibility)
10
6
  aiAutoSuggest: false,
11
7
  // Disable AI auto-suggest by default
8
+ limitChatHistory: true,
9
+ // Limit rendered chat history by default to avoid terminal buffer overflows
10
+ themeColor: "#00ccff",
11
+ // Default blue theme
12
12
  subshell: {
13
13
  enabled: true,
14
14
  ssh: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/types.ts"],"sourcesContent":["export interface SubshellConfig {\r\n enabled?: boolean;\r\n ssh?: {\r\n enabled?: boolean;\r\n defaultAuthMethod?: 'password' | 'key';\r\n keyPath?: string;\r\n timeout?: number;\r\n };\r\n wsl?: {\r\n enabled?: boolean;\r\n defaultDistribution?: string;\r\n timeout?: number;\r\n };\r\n docker?: {\r\n enabled?: boolean;\r\n timeout?: number;\r\n };\r\n commandTimeout?: number;\r\n stateQueryTimeout?: number;\r\n reconnectAttempts?: number;\r\n reconnectBackoff?: number;\r\n}\r\n\r\nexport interface Config {\r\n model: string;\r\n modelUid?: string; // Unique uid for the selected model entry (e.g. \"claude-opus-4-6-thinking\")\r\n modelName?: string; // Display name of the selected model\r\n isLocalModel?: boolean; // True if using a local Ollama model, false for cloud models\r\n autoApprove?: boolean;\r\n subshell?: SubshellConfig;\r\n enhancedQuality?: boolean;\r\n externalThinking?: boolean; // Enable external thinking mode (show <thinking> tags)\r\n autonomousMode?: boolean; // Enable autonomous mode (Silent Operator with task_complete)\r\n aiAutoSuggest?: boolean; // Enable AI-powered command auto-suggestions\r\n}\r\n\r\nexport const DEFAULT_CONFIG: Partial<Config> = {\r\n model: 'gemini-2.5-flash',\r\n autoApprove: false,\r\n enhancedQuality: true, // Enable enhanced quality features by default\r\n externalThinking: false, // Disable external thinking by default (internal reasoning)\r\n autonomousMode: false, // Disable autonomous mode by default (for backward compatibility)\r\n aiAutoSuggest: false, // Disable AI auto-suggest by default\r\n subshell: {\r\n enabled: true,\r\n ssh: {\r\n enabled: true,\r\n defaultAuthMethod: 'key',\r\n timeout: 30000,\r\n },\r\n wsl: {\r\n enabled: true,\r\n timeout: 30000,\r\n },\r\n docker: {\r\n enabled: true,\r\n timeout: 30000,\r\n },\r\n commandTimeout: 30000,\r\n stateQueryTimeout: 10000,\r\n reconnectAttempts: 3,\r\n reconnectBackoff: 1000,\r\n },\r\n};\r\n"],"mappings":"AAoCO,MAAM,iBAAkC;AAAA,EAC7C,OAAO;AAAA,EACP,aAAa;AAAA,EACb,iBAAiB;AAAA;AAAA,EACjB,kBAAkB;AAAA;AAAA,EAClB,gBAAgB;AAAA;AAAA,EAChB,eAAe;AAAA;AAAA,EACf,UAAU;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,MACH,SAAS;AAAA,MACT,mBAAmB;AAAA,MACnB,SAAS;AAAA,IACX;AAAA,IACA,KAAK;AAAA,MACH,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,IACnB,kBAAkB;AAAA,EACpB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/config/types.ts"],"sourcesContent":["export interface SubshellConfig {\r\n enabled?: boolean;\r\n ssh?: {\r\n enabled?: boolean;\r\n defaultAuthMethod?: 'password' | 'key';\r\n keyPath?: string;\r\n timeout?: number;\r\n };\r\n wsl?: {\r\n enabled?: boolean;\r\n defaultDistribution?: string;\r\n timeout?: number;\r\n };\r\n docker?: {\r\n enabled?: boolean;\r\n timeout?: number;\r\n };\r\n commandTimeout?: number;\r\n stateQueryTimeout?: number;\r\n reconnectAttempts?: number;\r\n reconnectBackoff?: number;\r\n}\r\n\r\nexport interface Config {\r\n model: string;\r\n modelUid?: string; // Unique uid for the selected model entry (e.g. \"claude-opus-4-6-thinking\")\r\n modelName?: string; // Display name of the selected model\r\n isLocalModel?: boolean; // True if using a local Ollama model, false for cloud models\r\n autoApprove?: boolean;\r\n subshell?: SubshellConfig;\r\n externalThinking?: boolean; // Enable external thinking mode (show <thinking> tags)\r\n aiAutoSuggest?: boolean; // Enable AI-powered command auto-suggestions\r\n limitChatHistory?: boolean; // Limit rendered chat history to reduce terminal buffer pressure\r\n themeColor?: string; // Theme accent color hex (e.g. '#00ccff')\r\n}\r\n\r\nexport const DEFAULT_CONFIG: Partial<Config> = {\r\n model: 'gemini-2.5-flash',\r\n autoApprove: false,\r\n externalThinking: false, // Disable external thinking by default (internal reasoning)\r\n aiAutoSuggest: false, // Disable AI auto-suggest by default\r\n limitChatHistory: true, // Limit rendered chat history by default to avoid terminal buffer overflows\r\n themeColor: '#00ccff', // Default blue theme\r\n subshell: {\r\n enabled: true,\r\n ssh: {\r\n enabled: true,\r\n defaultAuthMethod: 'key',\r\n timeout: 30000,\r\n },\r\n wsl: {\r\n enabled: true,\r\n timeout: 30000,\r\n },\r\n docker: {\r\n enabled: true,\r\n timeout: 30000,\r\n },\r\n commandTimeout: 30000,\r\n stateQueryTimeout: 10000,\r\n reconnectAttempts: 3,\r\n reconnectBackoff: 1000,\r\n },\r\n};\r\n"],"mappings":"AAoCO,MAAM,iBAAkC;AAAA,EAC7C,OAAO;AAAA,EACP,aAAa;AAAA,EACb,kBAAkB;AAAA;AAAA,EAClB,eAAe;AAAA;AAAA,EACf,kBAAkB;AAAA;AAAA,EAClB,YAAY;AAAA;AAAA,EACZ,UAAU;AAAA,IACR,SAAS;AAAA,IACT,KAAK;AAAA,MACH,SAAS;AAAA,MACT,mBAAmB;AAAA,MACnB,SAAS;AAAA,IACX;AAAA,IACA,KAAK;AAAA,MACH,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,IACnB,kBAAkB;AAAA,EACpB;AACF;","names":[]}
package/dist/index.js CHANGED
@@ -178,9 +178,15 @@ async function main() {
178
178
  onPlanCreated: (callback) => {
179
179
  cli.setOnPlanCreated(callback);
180
180
  },
181
+ onPlanQuestionRequest: (callback) => {
182
+ cli.setOnPlanQuestionRequest(callback);
183
+ },
181
184
  onTaskCompleted: (callback) => {
182
185
  cli.setOnTaskCompleted(callback);
183
186
  },
187
+ onTodoListUpdate: (callback) => {
188
+ cli.setOnTodoListUpdate(callback);
189
+ },
184
190
  onFileChangeSummary: (callback) => {
185
191
  cli.setOnFileChangeSummaryCallback(callback);
186
192
  },
@@ -190,6 +196,9 @@ async function main() {
190
196
  onToggleCommandMode: () => {
191
197
  cli.toggleCommandMode();
192
198
  },
199
+ onTogglePlanMode: () => {
200
+ cli.togglePlanMode();
201
+ },
193
202
  onBackgroundModeChange: (callback) => {
194
203
  cli.setOnBackgroundModeChange(callback);
195
204
  },
@@ -323,9 +332,36 @@ async function main() {
323
332
  onWarpifySession: (command, type, connectionString) => {
324
333
  return cli.warpifySession(command, type, connectionString);
325
334
  },
335
+ onCustomTunnelStateChange: (command) => {
336
+ cli.setCustomTunnelCommand(command);
337
+ },
326
338
  onAiAutoSuggestChange: (callback) => {
327
339
  cli.setOnAiAutoSuggestChange(callback);
328
340
  },
341
+ onLimitChatHistoryChange: (callback) => {
342
+ cli.setOnLimitChatHistoryChange(callback);
343
+ },
344
+ onThemeColorChange: (callback) => {
345
+ cli.setOnThemeColorChange(callback);
346
+ },
347
+ onSubAgentListScreenSetup: (callback) => {
348
+ cli.setOnSubAgentListScreenSetup(callback);
349
+ },
350
+ onSubAgentViewScreenSetup: (callback) => {
351
+ cli.setOnSubAgentViewScreenSetup(callback);
352
+ },
353
+ onSubAgentTerminateScreenSetup: (callback) => {
354
+ cli.setOnSubAgentTerminateScreenSetup(callback);
355
+ },
356
+ onSkillEditorScreenSetup: (callback) => {
357
+ cli.setOnSkillEditorScreenSetup(callback);
358
+ },
359
+ onSkillSave: (skill, previousName) => {
360
+ return cli.saveSkill(skill, previousName);
361
+ },
362
+ onSkillExecute: (skillName, params) => {
363
+ return cli.executeSkill(skillName, params);
364
+ },
329
365
  // Workflow callbacks
330
366
  onWorkflowCreatorSetup: (callback) => {
331
367
  cli.setOnShowWorkflowCreator(callback);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\n/**\r\n * Centaurus CLI Entry Point\r\n * \r\n * NOTE: NO .env file loading! All configuration is baked in at build time.\r\n * See config/build-config.ts for the compile-time configuration.\r\n */\r\n\r\nimport { fileURLToPath } from 'url';\r\nimport { dirname } from 'path';\r\n\r\nconst __filename = fileURLToPath(import.meta.url);\r\nconst __dirname = dirname(__filename);\r\n\r\n// Import logger early for error handlers\r\nimport { logError, logWarning, logInfo } from './utils/logger.js';\r\nimport { quickLog } from './utils/conversation-logger.js';\r\n\r\n// Global handler for EPIPE errors from MCP servers during shutdown\r\n// This prevents crashes when MCP server processes try to write to closed pipes\r\nprocess.stdout.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EPIPE') {\r\n // Silently ignore EPIPE errors - these happen during graceful shutdown\r\n logWarning(`stdout EPIPE error (suppressed): ${err.message}`);\r\n return;\r\n }\r\n logError('stdout error', err as Error);\r\n});\r\n\r\nprocess.stderr.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EPIPE') {\r\n logWarning(`stderr EPIPE error (suppressed): ${err.message}`);\r\n return;\r\n }\r\n logError('stderr error', err as Error);\r\n});\r\n\r\nprocess.stdin.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EPIPE' || err.code === 'EOF') {\r\n logWarning(`stdin error (suppressed): ${err.code} - ${err.message}`);\r\n return;\r\n }\r\n logError('stdin error', err as Error);\r\n});\r\n\r\n// Handle uncaught errors from child processes (MCP servers)\r\nprocess.on('uncaughtException', (err: NodeJS.ErrnoException) => {\r\n // EPIPE, ECONNRESET, and similar errors from MCP/network operations - log and continue\r\n if (err.code === 'EPIPE' || err.code === 'ECONNRESET' || err.code === 'ENOTCONN') {\r\n logWarning(`Uncaught exception (suppressed): ${err.code} - ${err.message}`);\r\n return;\r\n }\r\n\r\n // Yoga WASM memory access errors - these occur during rapid layout recalculations\r\n // in agent control mode and are non-fatal (the app can continue)\r\n if (err.name === 'RuntimeError' && err.message?.includes('memory access out of bounds')) {\r\n // Log to file only, not terminal\r\n quickLog(`[${new Date().toISOString()}] [WASM] Yoga memory error suppressed: ${err.message}\\n`);\r\n return;\r\n }\r\n\r\n // For critical errors, log and exit\r\n logError('Uncaught exception (fatal)', err as Error);\r\n process.exit(1);\r\n});\r\n\r\n// Handle unhandled promise rejections\r\nprocess.on('unhandledRejection', (reason: any, promise: Promise<any>) => {\r\n const error = reason instanceof Error ? reason : new Error(String(reason));\r\n const errnoError = error as NodeJS.ErrnoException;\r\n\r\n // Suppress common non-fatal errors from MCP/network operations\r\n if (errnoError.code === 'EPIPE' || errnoError.code === 'ECONNRESET' ||\r\n errnoError.code === 'ENOTCONN' || errnoError.code === 'ERR_STREAM_DESTROYED') {\r\n logWarning(`Unhandled rejection (suppressed): ${errnoError.code} - ${error.message}`);\r\n return;\r\n }\r\n\r\n logError('Unhandled rejection', error);\r\n});\r\n\r\nimport React from 'react';\r\nimport { render } from 'ink';\r\nimport { App } from './ui/components/App.js';\r\nimport { ErrorBoundary } from './ui/components/ErrorBoundary.js';\r\nimport { AuthWelcomeScreen } from './ui/components/AuthWelcomeScreen.js';\r\nimport { WelcomeBanner } from './ui/components/WelcomeBanner.js';\r\nimport { CentaurusCLI } from './cli-adapter.js';\r\nimport { apiClient } from './services/api-client.js';\r\nimport { authenticateWithGoogle } from './services/auth-handler.js';\r\nimport { Text, Box } from 'ink';\r\nimport { Plan, PlanStep } from './tools/plan-mode.js';\r\n\r\nasync function handleAuthentication(): Promise<boolean> {\r\n // Check if already authenticated and verify session is valid\r\n if (apiClient.isAuthenticated()) {\r\n try {\r\n // Verify the session is actually valid by checking with backend\r\n await apiClient.getCurrentUser();\r\n return true; // Session is valid\r\n } catch (error) {\r\n // Session is invalid/expired, clear it and continue to auth flow\r\n logWarning('Session expired. User needs to sign in again.');\r\n }\r\n }\r\n\r\n // Check if backend is reachable\r\n let backendReachable = false;\r\n try {\r\n await apiClient.healthCheck();\r\n backendReachable = true;\r\n } catch (error) {\r\n // Backend is not reachable - we'll still show auth screen but inform user\r\n logWarning('Backend API is not reachable during authentication.');\r\n }\r\n\r\n // Show authentication welcome screen with picker\r\n // Pre-render the WelcomeBanner to stdout BEFORE starting the interactive\r\n // Ink instance. This way the banner is static terminal output that won't\r\n // be redrawn when the selector re-renders inside the Ink tree.\r\n const { renderToString } = await import('./utils/ink-static-render.js');\r\n const bannerOutput = renderToString(React.createElement(WelcomeBanner));\r\n process.stdout.write(bannerOutput + '\\n');\r\n\r\n return new Promise<boolean>((resolve) => {\r\n const { waitUntilExit, clear } = render(\r\n React.createElement(AuthWelcomeScreen, {\r\n onSignIn: async () => {\r\n clear();\r\n\r\n logInfo('Starting authentication process...');\r\n\r\n // Attempt authentication via web app\r\n // The auth handler will open the browser and wait for callback\r\n const result = await authenticateWithGoogle();\r\n\r\n if (result.success) {\r\n logInfo('Authentication successful!');\r\n resolve(true);\r\n } else {\r\n logWarning(`Authentication failed: ${result.error || 'Unknown error'}`);\r\n process.exit(1);\r\n }\r\n },\r\n onExit: () => {\r\n clear();\r\n logInfo('User exited authentication screen.');\r\n process.exit(0);\r\n },\r\n }),\r\n {\r\n patchConsole: false,\r\n exitOnCtrlC: true,\r\n }\r\n );\r\n });\r\n}\r\n\r\nasync function main() {\r\n // Handle authentication\r\n await handleAuthentication();\r\n\r\n const cli = new CentaurusCLI();\r\n\r\n // Initialize CLI (load config, register tools)\r\n await cli.initialize();\r\n\r\n // Check if configuration migration occurred and show message\r\n const migrationMessage = cli.getMigrationMessage();\r\n if (migrationMessage) {\r\n logInfo(`Configuration migration: ${migrationMessage}`);\r\n\r\n // Wait for user to press Enter, but only if interactive\r\n if (process.stdin.isTTY) {\r\n await new Promise<void>((resolve) => {\r\n const onData = () => {\r\n process.stdin.removeListener('end', onEnd);\r\n resolve();\r\n };\r\n const onEnd = () => {\r\n process.stdin.removeListener('data', onData);\r\n resolve();\r\n };\r\n process.stdin.once('data', onData);\r\n process.stdin.once('end', onEnd);\r\n });\r\n }\r\n }\r\n\r\n // Clear the terminal before starting the UI\r\n process.stdout.write('\\x1b[2J\\x1b[3J\\x1b[H');\r\n\r\n // Render Ink app with error boundary\r\n // patchConsole: false prevents console.log from interfering with Ink's rendering\r\n // This is CRITICAL for Static component to work properly\r\n // debug: false reduces flickering by disabling debug output\r\n const { waitUntilExit } = render(\r\n React.createElement(ErrorBoundary, null,\r\n React.createElement(App, {\r\n onMessage: (msg: string) => cli.handleMessage(msg),\r\n onCancelRequest: () => cli.cancelCurrentRequest(),\r\n initialModel: cli.getModel(),\r\n initialPlanMode: cli.getPlanMode(),\r\n onResponseReceived: (callback: (message: string) => void) => {\r\n cli.setOnResponseCallback(callback);\r\n },\r\n onDirectMessage: (callback: (message: string) => void) => {\r\n cli.setOnDirectMessageCallback(callback);\r\n },\r\n onResponseStream: (callback: (chunk: string) => void) => {\r\n cli.setOnResponseStreamCallback(callback);\r\n },\r\n onClearStreamedResponse: (callback: () => void) => {\r\n cli.setOnClearStreamedResponse(callback);\r\n },\r\n onThoughtStream: (callback: (thought: string) => void) => {\r\n cli.setOnThoughtStreamCallback(callback);\r\n },\r\n onThoughtComplete: (callback: (durationSeconds: number) => void) => {\r\n cli.setOnThoughtCompleteCallback(callback);\r\n },\r\n onPickerSetup: (callback: (options: { message: string; choices: Array<{ label: string; value: string }>; type: 'model' }) => void) => {\r\n cli.setOnShowPickerCallback(callback);\r\n },\r\n onPickerSelection: (selection: string, type: 'model') => {\r\n return cli.handlePickerSelection(selection, type);\r\n },\r\n onToolExecutionUpdate: (callback: (update: { toolName: string; status: 'pending' | 'executing' | 'completed' | 'error'; result?: string; error?: string; arguments?: Record<string, any> }) => void) => {\r\n cli.setOnToolExecutionUpdate(callback);\r\n },\r\n onToolApprovalRequest: (callback: (request: { message: string; risky: boolean; preview?: { type: 'code' | 'diff'; content: string; language?: string }; operationType?: 'write_file' | 'edit_file' | 'execute_command'; operationDetails?: Record<string, any> }) => Promise<boolean>) => {\r\n cli.setOnToolApprovalRequest(callback);\r\n },\r\n onToolStreamingOutput: (callback: (update: { toolName: string; chunk: string; type: 'stdout' | 'stderr' }) => void) => {\r\n cli.setOnToolStreamingOutput(callback);\r\n },\r\n onPlanModeChange: (callback: (planMode: boolean) => void) => {\r\n cli.setOnPlanModeChange(callback);\r\n },\r\n onPlanApprovalRequest: (callback: (plan: Plan) => Promise<boolean>) => {\r\n cli.setOnPlanApprovalRequest(callback);\r\n },\r\n onPlanCreated: (callback: (plan: Plan) => void) => {\r\n cli.setOnPlanCreated(callback);\r\n },\r\n onTaskCompleted: (callback: (task: PlanStep, taskNumber: number, totalTasks: number, completionNote?: string, taskDescription?: string) => void) => {\r\n cli.setOnTaskCompleted(callback);\r\n },\r\n onFileChangeSummary: (callback: (data: { filesChanged: number; insertions: number; deletions: number }) => void) => {\r\n cli.setOnFileChangeSummaryCallback(callback);\r\n },\r\n onCommandModeChange: (callback: (commandMode: boolean) => void) => {\r\n cli.setOnCommandModeChange(callback);\r\n },\r\n onToggleCommandMode: () => {\r\n cli.toggleCommandMode();\r\n },\r\n onBackgroundModeChange: (callback: (backgroundMode: boolean) => void) => {\r\n cli.setOnBackgroundModeChange(callback);\r\n },\r\n onToggleBackgroundMode: () => {\r\n cli.toggleBackgroundMode();\r\n },\r\n onBackgroundTaskCountChange: (callback: (count: number) => void) => {\r\n cli.setOnBackgroundTaskCountChange(callback);\r\n },\r\n onSubAgentCountChange: (callback: (count: number) => void) => {\r\n cli.setOnSubAgentCountChange(callback);\r\n },\r\n onSetAutoModeSetup: (callback: (enabled: boolean) => void) => {\r\n cli.setOnSetAutoMode(callback);\r\n },\r\n\r\n onCwdChange: (callback: (cwd: string) => void) => {\r\n cli.setOnCwdChange(callback);\r\n },\r\n onModelChange: (callback: (modelName: string, contextWindow: number) => void) => {\r\n cli.setOnModelChange(callback);\r\n },\r\n onSubshellContextChange: (callback: (context: any) => void) => {\r\n cli.setOnSubshellContextChange(callback);\r\n },\r\n onPasswordRequest: (callback: (message: string) => Promise<string>) => {\r\n cli.setOnPasswordRequest(callback);\r\n },\r\n onShellInput: (input: string) => {\r\n cli.writeToShellStdin(input);\r\n },\r\n onShellSignal: (signal: string) => {\r\n cli.sendSignalToShell(signal as NodeJS.Signals);\r\n },\r\n onKillProcess: () => {\r\n cli.killCurrentProcess();\r\n },\r\n onInteractiveEditorMode: (callback: (active: boolean, command?: string, cwd?: string, remoteContext?: any, parentContext?: any) => void) => {\r\n cli.setOnInteractiveEditorMode(callback);\r\n },\r\n onConnectionStatusUpdate: (callback: (status: { type: 'ssh' | 'wsl' | 'docker'; status: 'connecting' | 'connected' | 'error' | 'disconnected'; connectionString?: string; error?: string }) => void) => {\r\n cli.setOnConnectionStatusUpdate(callback);\r\n },\r\n onTokenCountUpdate: (callback: (tokens: number) => void) => {\r\n cli.setOnTokenCountUpdate(callback);\r\n },\r\n onContextLimitReached: (callback: (reached: boolean) => void) => {\r\n cli.setOnContextLimitReached(callback);\r\n },\r\n onChatPickerSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatPickerCallback(callback);\r\n },\r\n onChatPickerSelection: (chatId: string) => {\r\n return cli.handleChatPickerSelection(chatId);\r\n },\r\n onChatDeletePickerSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatDeletePickerCallback(callback);\r\n },\r\n onChatDeletePickerSelection: (chatId: string) => {\r\n return cli.handleChatDeleteSelection(chatId);\r\n },\r\n onChatListSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatListCallback(callback);\r\n },\r\n onChatRenamePickerSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatRenamePickerCallback(callback);\r\n },\r\n onChatRename: (chatId: string, newTitle: string) => {\r\n cli.handleChatRename(chatId, newTitle);\r\n },\r\n onRestoreMessagesSetup: (callback: (messages: any[]) => void) => {\r\n cli.setOnRestoreMessagesCallback(callback);\r\n },\r\n onUIMessageHistoryUpdate: (messages: any[]) => {\r\n cli.updateUIMessageHistory(messages);\r\n },\r\n onBackgroundTaskListSetup: (callback: (tasks: any[]) => void) => {\r\n cli.setOnShowBackgroundTaskPickerCallback(callback);\r\n },\r\n onBackgroundTaskSelection: (taskId: string) => {\r\n cli.handleBackgroundTaskSelection(taskId);\r\n },\r\n onBackgroundTaskCancelSetup: (callback: (tasks: any[]) => void) => {\r\n cli.setOnShowBackgroundTaskCancelPickerCallback(callback);\r\n },\r\n onBackgroundTaskCancel: (taskId: string) => {\r\n cli.handleBackgroundTaskCancel(taskId);\r\n },\r\n onBackgroundTaskViewSetup: (callback: (task: any) => void) => {\r\n cli.setOnBackgroundTaskViewCallback(callback);\r\n },\r\n onSessionQuotaUpdate: (callback: (remaining: number, canSend: boolean, timeRemaining: string) => void) => {\r\n cli.setOnSessionQuotaUpdate(callback);\r\n },\r\n // MCP management callbacks\r\n onMCPAddScreenSetup: (callback: () => void) => {\r\n cli.setOnMCPAddScreenSetup(callback);\r\n },\r\n onMCPRemoveScreenSetup: (callback: (servers: Array<{ name: string; command: string; args?: string[]; enabled?: boolean }>) => void) => {\r\n cli.setOnMCPRemoveScreenSetup(callback);\r\n },\r\n onMCPEnableScreenSetup: (callback: (servers: Array<{ name: string; command: string; args?: string[]; enabled?: boolean }>) => void) => {\r\n cli.setOnMCPEnableScreenSetup(callback);\r\n },\r\n onMCPDisableScreenSetup: (callback: (servers: Array<{ name: string; command: string; args?: string[]; enabled?: boolean }>) => void) => {\r\n cli.setOnMCPDisableScreenSetup(callback);\r\n },\r\n onMCPListScreenSetup: (callback: (servers: Array<{ name: string; enabled: boolean; status: 'connected' | 'disconnected' | 'error' | 'connecting'; tools: Array<{ name: string }> }>) => void) => {\r\n cli.setOnMCPListScreenSetup(callback);\r\n },\r\n onMCPAddServer: (config: any) => {\r\n return cli.mcpAddServer(config);\r\n },\r\n onMCPRemoveServer: (name: string) => {\r\n cli.mcpRemoveServer(name);\r\n },\r\n onMCPEnableServer: (name: string) => {\r\n cli.mcpEnableServer(name);\r\n },\r\n onMCPDisableServer: (name: string) => {\r\n cli.mcpDisableServer(name);\r\n },\r\n onMCPValidateConfig: (jsonString: string) => {\r\n return cli.mcpValidateConfig(jsonString);\r\n },\r\n onPromptAnswered: (callback: (shellId: string) => void) => {\r\n cli.setOnPromptAnswered(callback);\r\n },\r\n getMainConversation: () => {\r\n return cli.getConversationHistory();\r\n },\r\n onWarpifySession: (command: string, type: 'ssh' | 'wsl' | 'docker', connectionString?: string) => {\r\n return cli.warpifySession(command, type, connectionString);\r\n },\r\n onAiAutoSuggestChange: (callback: (enabled: boolean) => void) => {\r\n cli.setOnAiAutoSuggestChange(callback);\r\n },\r\n // Workflow callbacks\r\n\r\n onWorkflowCreatorSetup: (callback: (initialSteps?: Array<{ type: 'command' | 'instruction'; content: string }>) => void) => {\r\n cli.setOnShowWorkflowCreator(callback);\r\n },\r\n onWorkflowSave: (name: string, steps: Array<{ type: 'command' | 'instruction'; content: string }>, description?: string) => {\r\n cli.saveWorkflow(name, steps, description);\r\n },\r\n onRulesEditorSetup: (callback: (request: { mode: 'add' | 'edit'; initialName?: string; initialContent?: string }) => void) => {\r\n cli.setOnShowRulesEditor(callback);\r\n },\r\n onRuleSave: (name: string, content: string, previousName?: string) => {\r\n return cli.saveRule(name, content, previousName);\r\n },\r\n getCheckpoints: () => {\r\n return cli.getCheckpointsForAutocomplete();\r\n },\r\n onRevertToCheckpointSetup: (callback: (checkpointIndex: number, prompt: string) => void) => {\r\n cli.setOnRevertToCheckpoint(callback);\r\n },\r\n onSetInputSetup: (callback: (value: string) => void) => {\r\n cli.setOnSetInput(callback);\r\n },\r\n onInterruptQueueUpdate: (callback: (queue: string[]) => void) => {\r\n cli.setOnInterruptQueueUpdate(callback);\r\n },\r\n onQueuedMessageDispatched: (callback: (message: string) => void) => {\r\n cli.setOnQueuedMessageDispatched(callback);\r\n },\r\n onCommandQueueUpdate: (callback: (queue: string[]) => void) => {\r\n cli.setOnCommandQueueUpdate(callback);\r\n },\r\n onQueuedCommandDispatched: (callback: (command: string) => void) => {\r\n cli.setOnQueuedCommandDispatched(callback);\r\n }\r\n })\r\n ),\r\n {\r\n patchConsole: false,\r\n exitOnCtrlC: false,\r\n debug: false\r\n }\r\n );\r\n\r\n // Wait for user to exit, with a fallback mechanism\r\n // If the React component tree crashes silently or the Ink runtime enters an unexpected state,\r\n // waitUntilExit() may never resolve. This fallback ensures we can still exit via signals.\r\n const exitPromise = waitUntilExit();\r\n\r\n const fallbackPromise = new Promise<void>((resolve) => {\r\n const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM'];\r\n\r\n // We don't want to immediately exit on the first SIGINT if Ink is healthy \r\n // and processing it to gracefully unmount. We add a short timeout, \r\n // or just rely on the fact that if this resolves first, we exit.\r\n const signalHandler = (sig: string) => {\r\n logWarning(`Received ${sig} (Fallback handler triggered)`);\r\n // Give Ink a small window to gracefully exit first before we force it\r\n setTimeout(() => {\r\n resolve();\r\n }, 500).unref();\r\n\r\n signals.forEach(s => process.removeListener(s, signalHandler));\r\n };\r\n\r\n signals.forEach(sig => process.once(sig, signalHandler));\r\n });\r\n\r\n try {\r\n await Promise.race([exitPromise, fallbackPromise]);\r\n } catch (err) {\r\n logError('Ink render error', err as Error);\r\n } finally {\r\n // Ensure all background processes and timers are terminated\r\n process.exit(0);\r\n }\r\n}\r\n\r\nmain().catch((error) => {\r\n logError('Fatal error in main()', error);\r\n process.exit(1);\r\n});\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\n/**\r\n * Centaurus CLI Entry Point\r\n * \r\n * NOTE: NO .env file loading! All configuration is baked in at build time.\r\n * See config/build-config.ts for the compile-time configuration.\r\n */\r\n\r\nimport { fileURLToPath } from 'url';\r\nimport { dirname } from 'path';\r\n\r\nconst __filename = fileURLToPath(import.meta.url);\r\nconst __dirname = dirname(__filename);\r\n\r\n// Import logger early for error handlers\r\nimport { logError, logWarning, logInfo } from './utils/logger.js';\r\nimport { quickLog } from './utils/conversation-logger.js';\r\n\r\n// Global handler for EPIPE errors from MCP servers during shutdown\r\n// This prevents crashes when MCP server processes try to write to closed pipes\r\nprocess.stdout.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EPIPE') {\r\n // Silently ignore EPIPE errors - these happen during graceful shutdown\r\n logWarning(`stdout EPIPE error (suppressed): ${err.message}`);\r\n return;\r\n }\r\n logError('stdout error', err as Error);\r\n});\r\n\r\nprocess.stderr.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EPIPE') {\r\n logWarning(`stderr EPIPE error (suppressed): ${err.message}`);\r\n return;\r\n }\r\n logError('stderr error', err as Error);\r\n});\r\n\r\nprocess.stdin.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EPIPE' || err.code === 'EOF') {\r\n logWarning(`stdin error (suppressed): ${err.code} - ${err.message}`);\r\n return;\r\n }\r\n logError('stdin error', err as Error);\r\n});\r\n\r\n// Handle uncaught errors from child processes (MCP servers)\r\nprocess.on('uncaughtException', (err: NodeJS.ErrnoException) => {\r\n // EPIPE, ECONNRESET, and similar errors from MCP/network operations - log and continue\r\n if (err.code === 'EPIPE' || err.code === 'ECONNRESET' || err.code === 'ENOTCONN') {\r\n logWarning(`Uncaught exception (suppressed): ${err.code} - ${err.message}`);\r\n return;\r\n }\r\n\r\n // Yoga WASM memory access errors - these occur during rapid layout recalculations\r\n // in agent control mode and are non-fatal (the app can continue)\r\n if (err.name === 'RuntimeError' && err.message?.includes('memory access out of bounds')) {\r\n // Log to file only, not terminal\r\n quickLog(`[${new Date().toISOString()}] [WASM] Yoga memory error suppressed: ${err.message}\\n`);\r\n return;\r\n }\r\n\r\n // For critical errors, log and exit\r\n logError('Uncaught exception (fatal)', err as Error);\r\n process.exit(1);\r\n});\r\n\r\n// Handle unhandled promise rejections\r\nprocess.on('unhandledRejection', (reason: any, promise: Promise<any>) => {\r\n const error = reason instanceof Error ? reason : new Error(String(reason));\r\n const errnoError = error as NodeJS.ErrnoException;\r\n\r\n // Suppress common non-fatal errors from MCP/network operations\r\n if (errnoError.code === 'EPIPE' || errnoError.code === 'ECONNRESET' ||\r\n errnoError.code === 'ENOTCONN' || errnoError.code === 'ERR_STREAM_DESTROYED') {\r\n logWarning(`Unhandled rejection (suppressed): ${errnoError.code} - ${error.message}`);\r\n return;\r\n }\r\n\r\n logError('Unhandled rejection', error);\r\n});\r\n\r\nimport React from 'react';\r\nimport { render } from 'ink';\r\nimport { App } from './ui/components/App.js';\r\nimport { ErrorBoundary } from './ui/components/ErrorBoundary.js';\r\nimport { AuthWelcomeScreen } from './ui/components/AuthWelcomeScreen.js';\r\nimport { WelcomeBanner } from './ui/components/WelcomeBanner.js';\r\nimport { CentaurusCLI } from './cli-adapter.js';\r\nimport { apiClient } from './services/api-client.js';\r\nimport { authenticateWithGoogle } from './services/auth-handler.js';\r\nimport { Text, Box } from 'ink';\r\nimport { Plan } from './tools/plan-mode.js';\r\n\r\nasync function handleAuthentication(): Promise<boolean> {\r\n // Check if already authenticated and verify session is valid\r\n if (apiClient.isAuthenticated()) {\r\n try {\r\n // Verify the session is actually valid by checking with backend\r\n await apiClient.getCurrentUser();\r\n return true; // Session is valid\r\n } catch (error) {\r\n // Session is invalid/expired, clear it and continue to auth flow\r\n logWarning('Session expired. User needs to sign in again.');\r\n }\r\n }\r\n\r\n // Check if backend is reachable\r\n let backendReachable = false;\r\n try {\r\n await apiClient.healthCheck();\r\n backendReachable = true;\r\n } catch (error) {\r\n // Backend is not reachable - we'll still show auth screen but inform user\r\n logWarning('Backend API is not reachable during authentication.');\r\n }\r\n\r\n // Show authentication welcome screen with picker\r\n // Pre-render the WelcomeBanner to stdout BEFORE starting the interactive\r\n // Ink instance. This way the banner is static terminal output that won't\r\n // be redrawn when the selector re-renders inside the Ink tree.\r\n const { renderToString } = await import('./utils/ink-static-render.js');\r\n const bannerOutput = renderToString(React.createElement(WelcomeBanner));\r\n process.stdout.write(bannerOutput + '\\n');\r\n\r\n return new Promise<boolean>((resolve) => {\r\n const { waitUntilExit, clear } = render(\r\n React.createElement(AuthWelcomeScreen, {\r\n onSignIn: async () => {\r\n clear();\r\n\r\n logInfo('Starting authentication process...');\r\n\r\n // Attempt authentication via web app\r\n // The auth handler will open the browser and wait for callback\r\n const result = await authenticateWithGoogle();\r\n\r\n if (result.success) {\r\n logInfo('Authentication successful!');\r\n resolve(true);\r\n } else {\r\n logWarning(`Authentication failed: ${result.error || 'Unknown error'}`);\r\n process.exit(1);\r\n }\r\n },\r\n onExit: () => {\r\n clear();\r\n logInfo('User exited authentication screen.');\r\n process.exit(0);\r\n },\r\n }),\r\n {\r\n patchConsole: false,\r\n exitOnCtrlC: true,\r\n }\r\n );\r\n });\r\n}\r\n\r\nasync function main() {\r\n // Handle authentication\r\n await handleAuthentication();\r\n\r\n const cli = new CentaurusCLI();\r\n\r\n // Initialize CLI (load config, register tools)\r\n await cli.initialize();\r\n\r\n // Check if configuration migration occurred and show message\r\n const migrationMessage = cli.getMigrationMessage();\r\n if (migrationMessage) {\r\n logInfo(`Configuration migration: ${migrationMessage}`);\r\n\r\n // Wait for user to press Enter, but only if interactive\r\n if (process.stdin.isTTY) {\r\n await new Promise<void>((resolve) => {\r\n const onData = () => {\r\n process.stdin.removeListener('end', onEnd);\r\n resolve();\r\n };\r\n const onEnd = () => {\r\n process.stdin.removeListener('data', onData);\r\n resolve();\r\n };\r\n process.stdin.once('data', onData);\r\n process.stdin.once('end', onEnd);\r\n });\r\n }\r\n }\r\n\r\n // Clear the terminal before starting the UI\r\n process.stdout.write('\\x1b[2J\\x1b[3J\\x1b[H');\r\n\r\n // Render Ink app with error boundary\r\n // patchConsole: false prevents console.log from interfering with Ink's rendering\r\n // This is CRITICAL for Static component to work properly\r\n // debug: false reduces flickering by disabling debug output\r\n const { waitUntilExit } = render(\r\n React.createElement(ErrorBoundary, null,\r\n React.createElement(App, {\r\n onMessage: (msg: string) => cli.handleMessage(msg),\r\n onCancelRequest: () => cli.cancelCurrentRequest(),\r\n initialModel: cli.getModel(),\r\n initialPlanMode: cli.getPlanMode(),\r\n onResponseReceived: (callback: (message: string) => void) => {\r\n cli.setOnResponseCallback(callback);\r\n },\r\n onDirectMessage: (callback: (message: string) => void) => {\r\n cli.setOnDirectMessageCallback(callback);\r\n },\r\n onResponseStream: (callback: (chunk: string) => void) => {\r\n cli.setOnResponseStreamCallback(callback);\r\n },\r\n onClearStreamedResponse: (callback: () => void) => {\r\n cli.setOnClearStreamedResponse(callback);\r\n },\r\n onThoughtStream: (callback: (thought: string) => void) => {\r\n cli.setOnThoughtStreamCallback(callback);\r\n },\r\n onThoughtComplete: (callback: (durationSeconds: number) => void) => {\r\n cli.setOnThoughtCompleteCallback(callback);\r\n },\r\n onPickerSetup: (callback: (options: { message: string; choices: Array<{ label: string; value: string }>; type: 'model' | 'local-model'; modelConfigs?: any[]; currentModelName?: string }) => void) => {\r\n cli.setOnShowPickerCallback(callback);\r\n },\r\n onPickerSelection: (selection: string, type: 'model' | 'local-model') => {\r\n return cli.handlePickerSelection(selection, type);\r\n },\r\n onToolExecutionUpdate: (callback: (update: { toolName: string; status: 'pending' | 'executing' | 'completed' | 'error'; result?: string; error?: string; arguments?: Record<string, any> }) => void) => {\r\n cli.setOnToolExecutionUpdate(callback);\r\n },\r\n onToolApprovalRequest: (callback: (request: { message: string; risky: boolean; preview?: { type: 'code' | 'diff'; content: string; language?: string }; operationType?: 'write_file' | 'edit_file' | 'execute_command'; operationDetails?: Record<string, any> }) => Promise<boolean>) => {\r\n cli.setOnToolApprovalRequest(callback);\r\n },\r\n onToolStreamingOutput: (callback: (update: { toolName: string; chunk: string; type: 'stdout' | 'stderr' }) => void) => {\r\n cli.setOnToolStreamingOutput(callback);\r\n },\r\n onPlanModeChange: (callback: (planMode: boolean) => void) => {\r\n cli.setOnPlanModeChange(callback);\r\n },\r\n onPlanApprovalRequest: (callback: (plan: Plan) => Promise<boolean>) => {\r\n cli.setOnPlanApprovalRequest(callback);\r\n },\r\n onPlanCreated: (callback: (plan: Plan) => void) => {\r\n cli.setOnPlanCreated(callback);\r\n },\r\n onPlanQuestionRequest: (callback: (question: string, options: string[]) => Promise<string>) => {\r\n cli.setOnPlanQuestionRequest(callback);\r\n },\r\n onTaskCompleted: (callback: (stepNumber: number, stepDescription: string, completedCount: number, totalCount: number, completionNote?: string, allSteps?: Array<{ id: number; description: string; status: string }>) => void) => {\r\n cli.setOnTaskCompleted(callback);\r\n },\r\n onTodoListUpdate: (callback: (todos: Array<{ id: string; content: string; status: 'pending' | 'in_progress' | 'completed' }>, completedCount: number, totalCount: number) => void) => {\r\n cli.setOnTodoListUpdate(callback);\r\n },\r\n onFileChangeSummary: (callback: (data: { filesChanged: number; insertions: number; deletions: number }) => void) => {\r\n cli.setOnFileChangeSummaryCallback(callback);\r\n },\r\n onCommandModeChange: (callback: (commandMode: boolean) => void) => {\r\n cli.setOnCommandModeChange(callback);\r\n },\r\n onToggleCommandMode: () => {\r\n cli.toggleCommandMode();\r\n },\r\n onTogglePlanMode: () => {\r\n cli.togglePlanMode();\r\n },\r\n onBackgroundModeChange: (callback: (backgroundMode: boolean) => void) => {\r\n cli.setOnBackgroundModeChange(callback);\r\n },\r\n onToggleBackgroundMode: () => {\r\n cli.toggleBackgroundMode();\r\n },\r\n onBackgroundTaskCountChange: (callback: (count: number) => void) => {\r\n cli.setOnBackgroundTaskCountChange(callback);\r\n },\r\n onSubAgentCountChange: (callback: (count: number) => void) => {\r\n cli.setOnSubAgentCountChange(callback);\r\n },\r\n onSetAutoModeSetup: (callback: (enabled: boolean) => void) => {\r\n cli.setOnSetAutoMode(callback);\r\n },\r\n\r\n onCwdChange: (callback: (cwd: string) => void) => {\r\n cli.setOnCwdChange(callback);\r\n },\r\n onModelChange: (callback: (modelName: string, contextWindow: number) => void) => {\r\n cli.setOnModelChange(callback);\r\n },\r\n onSubshellContextChange: (callback: (context: any) => void) => {\r\n cli.setOnSubshellContextChange(callback);\r\n },\r\n onPasswordRequest: (callback: (message: string) => Promise<string>) => {\r\n cli.setOnPasswordRequest(callback);\r\n },\r\n onShellInput: (input: string) => {\r\n cli.writeToShellStdin(input);\r\n },\r\n onShellSignal: (signal: string) => {\r\n cli.sendSignalToShell(signal as NodeJS.Signals);\r\n },\r\n onKillProcess: () => {\r\n cli.killCurrentProcess();\r\n },\r\n onInteractiveEditorMode: (callback: (active: boolean, command?: string, cwd?: string, remoteContext?: any, parentContext?: any) => void) => {\r\n cli.setOnInteractiveEditorMode(callback);\r\n },\r\n onConnectionStatusUpdate: (callback: (status: { type: 'ssh' | 'wsl' | 'docker'; status: 'connecting' | 'connected' | 'error' | 'disconnected'; connectionString?: string; error?: string }) => void) => {\r\n cli.setOnConnectionStatusUpdate(callback);\r\n },\r\n onTokenCountUpdate: (callback: (tokens: number) => void) => {\r\n cli.setOnTokenCountUpdate(callback);\r\n },\r\n onContextLimitReached: (callback: (reached: boolean) => void) => {\r\n cli.setOnContextLimitReached(callback);\r\n },\r\n onChatPickerSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatPickerCallback(callback);\r\n },\r\n onChatPickerSelection: (chatId: string) => {\r\n return cli.handleChatPickerSelection(chatId);\r\n },\r\n onChatDeletePickerSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatDeletePickerCallback(callback);\r\n },\r\n onChatDeletePickerSelection: (chatId: string) => {\r\n return cli.handleChatDeleteSelection(chatId);\r\n },\r\n onChatListSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatListCallback(callback);\r\n },\r\n onChatRenamePickerSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatRenamePickerCallback(callback);\r\n },\r\n onChatRename: (chatId: string, newTitle: string) => {\r\n cli.handleChatRename(chatId, newTitle);\r\n },\r\n onRestoreMessagesSetup: (callback: (messages: any[]) => void) => {\r\n cli.setOnRestoreMessagesCallback(callback);\r\n },\r\n onUIMessageHistoryUpdate: (messages: any[]) => {\r\n cli.updateUIMessageHistory(messages);\r\n },\r\n onBackgroundTaskListSetup: (callback: (tasks: any[]) => void) => {\r\n cli.setOnShowBackgroundTaskPickerCallback(callback);\r\n },\r\n onBackgroundTaskSelection: (taskId: string) => {\r\n cli.handleBackgroundTaskSelection(taskId);\r\n },\r\n onBackgroundTaskCancelSetup: (callback: (tasks: any[]) => void) => {\r\n cli.setOnShowBackgroundTaskCancelPickerCallback(callback);\r\n },\r\n onBackgroundTaskCancel: (taskId: string) => {\r\n cli.handleBackgroundTaskCancel(taskId);\r\n },\r\n onBackgroundTaskViewSetup: (callback: (task: any) => void) => {\r\n cli.setOnBackgroundTaskViewCallback(callback);\r\n },\r\n onSessionQuotaUpdate: (callback: (remaining: number, canSend: boolean, timeRemaining: string) => void) => {\r\n cli.setOnSessionQuotaUpdate(callback);\r\n },\r\n // MCP management callbacks\r\n onMCPAddScreenSetup: (callback: () => void) => {\r\n cli.setOnMCPAddScreenSetup(callback);\r\n },\r\n onMCPRemoveScreenSetup: (callback: (servers: Array<{ name: string; command: string; args?: string[]; enabled?: boolean }>) => void) => {\r\n cli.setOnMCPRemoveScreenSetup(callback);\r\n },\r\n onMCPEnableScreenSetup: (callback: (servers: Array<{ name: string; command: string; args?: string[]; enabled?: boolean }>) => void) => {\r\n cli.setOnMCPEnableScreenSetup(callback);\r\n },\r\n onMCPDisableScreenSetup: (callback: (servers: Array<{ name: string; command: string; args?: string[]; enabled?: boolean }>) => void) => {\r\n cli.setOnMCPDisableScreenSetup(callback);\r\n },\r\n onMCPListScreenSetup: (callback: (servers: Array<{ name: string; enabled: boolean; status: 'connected' | 'disconnected' | 'error' | 'connecting'; tools: Array<{ name: string }> }>) => void) => {\r\n cli.setOnMCPListScreenSetup(callback);\r\n },\r\n onMCPAddServer: (config: any) => {\r\n return cli.mcpAddServer(config);\r\n },\r\n onMCPRemoveServer: (name: string) => {\r\n cli.mcpRemoveServer(name);\r\n },\r\n onMCPEnableServer: (name: string) => {\r\n cli.mcpEnableServer(name);\r\n },\r\n onMCPDisableServer: (name: string) => {\r\n cli.mcpDisableServer(name);\r\n },\r\n onMCPValidateConfig: (jsonString: string) => {\r\n return cli.mcpValidateConfig(jsonString);\r\n },\r\n onPromptAnswered: (callback: (shellId: string) => void) => {\r\n cli.setOnPromptAnswered(callback);\r\n },\r\n getMainConversation: () => {\r\n return cli.getConversationHistory();\r\n },\r\n onWarpifySession: (command: string, type: 'ssh' | 'wsl' | 'docker', connectionString?: string) => {\r\n return cli.warpifySession(command, type, connectionString);\r\n },\r\n onCustomTunnelStateChange: (command: string | null) => {\r\n cli.setCustomTunnelCommand(command);\r\n },\r\n onAiAutoSuggestChange: (callback: (enabled: boolean) => void) => {\r\n cli.setOnAiAutoSuggestChange(callback);\r\n },\r\n onLimitChatHistoryChange: (callback: (enabled: boolean) => void) => {\r\n cli.setOnLimitChatHistoryChange(callback);\r\n },\r\n onThemeColorChange: (callback: (color: string) => void) => {\r\n cli.setOnThemeColorChange(callback);\r\n },\r\n onSubAgentListScreenSetup: (callback: (agents: any[]) => void) => {\r\n cli.setOnSubAgentListScreenSetup(callback);\r\n },\r\n onSubAgentViewScreenSetup: (callback: (agentId: string) => void) => {\r\n cli.setOnSubAgentViewScreenSetup(callback);\r\n },\r\n onSubAgentTerminateScreenSetup: (callback: (agents: any[]) => void) => {\r\n cli.setOnSubAgentTerminateScreenSetup(callback);\r\n },\r\n onSkillEditorScreenSetup: (callback: (request: any) => void) => {\r\n cli.setOnSkillEditorScreenSetup(callback);\r\n },\r\n onSkillSave: (skill: any, previousName?: string) => {\r\n return cli.saveSkill(skill, previousName);\r\n },\r\n onSkillExecute: (skillName: string, params: string) => {\r\n return cli.executeSkill(skillName, params);\r\n },\r\n // Workflow callbacks\r\n\r\n onWorkflowCreatorSetup: (callback: (initialSteps?: Array<{ type: 'command' | 'instruction'; content: string }>) => void) => {\r\n cli.setOnShowWorkflowCreator(callback);\r\n },\r\n onWorkflowSave: (name: string, steps: Array<{ type: 'command' | 'instruction'; content: string }>, description?: string) => {\r\n cli.saveWorkflow(name, steps, description);\r\n },\r\n onRulesEditorSetup: (callback: (request: { mode: 'add' | 'edit'; initialName?: string; initialContent?: string }) => void) => {\r\n cli.setOnShowRulesEditor(callback);\r\n },\r\n onRuleSave: (name: string, content: string, previousName?: string) => {\r\n return cli.saveRule(name, content, previousName);\r\n },\r\n getCheckpoints: () => {\r\n return cli.getCheckpointsForAutocomplete();\r\n },\r\n onRevertToCheckpointSetup: (callback: (checkpointIndex: number, prompt: string) => void) => {\r\n cli.setOnRevertToCheckpoint(callback);\r\n },\r\n onSetInputSetup: (callback: (value: string) => void) => {\r\n cli.setOnSetInput(callback);\r\n },\r\n onInterruptQueueUpdate: (callback: (queue: string[]) => void) => {\r\n cli.setOnInterruptQueueUpdate(callback);\r\n },\r\n onQueuedMessageDispatched: (callback: (message: string) => void) => {\r\n cli.setOnQueuedMessageDispatched(callback);\r\n },\r\n onCommandQueueUpdate: (callback: (queue: string[]) => void) => {\r\n cli.setOnCommandQueueUpdate(callback);\r\n },\r\n onQueuedCommandDispatched: (callback: (command: string) => void) => {\r\n cli.setOnQueuedCommandDispatched(callback);\r\n }\r\n })\r\n ),\r\n {\r\n patchConsole: false,\r\n exitOnCtrlC: false,\r\n debug: false\r\n }\r\n );\r\n\r\n // Wait for user to exit, with a fallback mechanism\r\n // If the React component tree crashes silently or the Ink runtime enters an unexpected state,\r\n // waitUntilExit() may never resolve. This fallback ensures we can still exit via signals.\r\n const exitPromise = waitUntilExit();\r\n\r\n const fallbackPromise = new Promise<void>((resolve) => {\r\n const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM'];\r\n\r\n // We don't want to immediately exit on the first SIGINT if Ink is healthy \r\n // and processing it to gracefully unmount. We add a short timeout, \r\n // or just rely on the fact that if this resolves first, we exit.\r\n const signalHandler = (sig: string) => {\r\n logWarning(`Received ${sig} (Fallback handler triggered)`);\r\n // Give Ink a small window to gracefully exit first before we force it\r\n setTimeout(() => {\r\n resolve();\r\n }, 500).unref();\r\n\r\n signals.forEach(s => process.removeListener(s, signalHandler));\r\n };\r\n\r\n signals.forEach(sig => process.once(sig, signalHandler));\r\n });\r\n\r\n try {\r\n await Promise.race([exitPromise, fallbackPromise]);\r\n } catch (err) {\r\n logError('Ink render error', err as Error);\r\n } finally {\r\n // Ensure all background processes and timers are terminated\r\n process.exit(0);\r\n }\r\n}\r\n\r\nmain().catch((error) => {\r\n logError('Fatal error in main()', error);\r\n process.exit(1);\r\n});\r\n"],"mappings":"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","names":[]}