@vybestack/llxprt-code 0.1.12 → 0.1.13-hotfix1

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 (248) hide show
  1. package/dist/index.js +0 -0
  2. package/dist/package.json +5 -5
  3. package/dist/src/acp/acp.d.ts +208 -0
  4. package/dist/src/acp/acp.js +193 -0
  5. package/dist/src/acp/acp.js.map +1 -0
  6. package/dist/src/acp/acpPeer.d.ts +8 -0
  7. package/dist/src/acp/acpPeer.js +537 -0
  8. package/dist/src/acp/acpPeer.js.map +1 -0
  9. package/dist/src/config/config.d.ts +2 -0
  10. package/dist/src/config/config.js +73 -19
  11. package/dist/src/config/config.js.map +1 -1
  12. package/dist/src/config/extension.d.ts +2 -2
  13. package/dist/src/config/extension.js +21 -16
  14. package/dist/src/config/extension.js.map +1 -1
  15. package/dist/src/config/settings.d.ts +7 -0
  16. package/dist/src/config/settings.js +15 -0
  17. package/dist/src/config/settings.js.map +1 -1
  18. package/dist/src/gemini.js +33 -34
  19. package/dist/src/gemini.js.map +1 -1
  20. package/dist/src/generated/git-commit.d.ts +1 -1
  21. package/dist/src/generated/git-commit.js +1 -1
  22. package/dist/src/nonInteractiveCli.js +36 -3
  23. package/dist/src/nonInteractiveCli.js.map +1 -1
  24. package/dist/src/providers/index.d.ts +1 -7
  25. package/dist/src/providers/index.js +2 -10
  26. package/dist/src/providers/index.js.map +1 -1
  27. package/dist/src/providers/providerConfigUtils.d.ts +1 -2
  28. package/dist/src/providers/providerConfigUtils.js +1 -1
  29. package/dist/src/providers/providerConfigUtils.js.map +1 -1
  30. package/dist/src/providers/providerManagerInstance.d.ts +2 -2
  31. package/dist/src/providers/providerManagerInstance.js +21 -19
  32. package/dist/src/providers/providerManagerInstance.js.map +1 -1
  33. package/dist/src/providers/types.d.ts +1 -9
  34. package/dist/src/providers/types.js +2 -10
  35. package/dist/src/providers/types.js.map +1 -1
  36. package/dist/src/services/CommandService.d.ts +3 -1
  37. package/dist/src/services/CommandService.js +50 -11
  38. package/dist/src/services/CommandService.js.map +1 -1
  39. package/dist/src/ui/App.js +24 -25
  40. package/dist/src/ui/App.js.map +1 -1
  41. package/dist/src/ui/commands/aboutCommand.js +21 -0
  42. package/dist/src/ui/commands/aboutCommand.js.map +1 -1
  43. package/dist/src/ui/commands/baseurlCommand.d.ts +7 -0
  44. package/dist/src/ui/commands/baseurlCommand.js +22 -0
  45. package/dist/src/ui/commands/baseurlCommand.js.map +1 -0
  46. package/dist/src/ui/commands/bugCommand.d.ts +7 -0
  47. package/dist/src/ui/commands/bugCommand.js +61 -0
  48. package/dist/src/ui/commands/bugCommand.js.map +1 -0
  49. package/dist/src/ui/commands/chatCommand.d.ts +7 -0
  50. package/dist/src/ui/commands/chatCommand.js +170 -0
  51. package/dist/src/ui/commands/chatCommand.js.map +1 -0
  52. package/dist/src/ui/commands/clearCommand.js +12 -2
  53. package/dist/src/ui/commands/clearCommand.js.map +1 -1
  54. package/dist/src/ui/commands/compressCommand.d.ts +7 -0
  55. package/dist/src/ui/commands/compressCommand.js +62 -0
  56. package/dist/src/ui/commands/compressCommand.js.map +1 -0
  57. package/dist/src/ui/commands/docsCommand.d.ts +7 -0
  58. package/dist/src/ui/commands/docsCommand.js +29 -0
  59. package/dist/src/ui/commands/docsCommand.js.map +1 -0
  60. package/dist/src/ui/commands/editorCommand.d.ts +7 -0
  61. package/dist/src/ui/commands/editorCommand.js +14 -0
  62. package/dist/src/ui/commands/editorCommand.js.map +1 -0
  63. package/dist/src/ui/commands/extensionsCommand.d.ts +7 -0
  64. package/dist/src/ui/commands/extensionsCommand.js +29 -0
  65. package/dist/src/ui/commands/extensionsCommand.js.map +1 -0
  66. package/dist/src/ui/commands/ideCommand.d.ts +8 -0
  67. package/dist/src/ui/commands/ideCommand.js +123 -0
  68. package/dist/src/ui/commands/ideCommand.js.map +1 -0
  69. package/dist/src/{providers/ProviderAwareContentGenerator.d.ts → ui/commands/keyCommand.d.ts} +2 -1
  70. package/dist/src/ui/commands/keyCommand.js +29 -0
  71. package/dist/src/ui/commands/keyCommand.js.map +1 -0
  72. package/dist/src/ui/commands/keyfileCommand.d.ts +7 -0
  73. package/dist/src/ui/commands/keyfileCommand.js +104 -0
  74. package/dist/src/ui/commands/keyfileCommand.js.map +1 -0
  75. package/dist/src/ui/commands/mcpCommand.d.ts +7 -0
  76. package/dist/src/ui/commands/mcpCommand.js +204 -0
  77. package/dist/src/ui/commands/mcpCommand.js.map +1 -0
  78. package/dist/src/ui/commands/modelCommand.d.ts +7 -0
  79. package/dist/src/ui/commands/modelCommand.js +60 -0
  80. package/dist/src/ui/commands/modelCommand.js.map +1 -0
  81. package/dist/src/ui/commands/providerCommand.d.ts +7 -0
  82. package/dist/src/ui/commands/providerCommand.js +86 -0
  83. package/dist/src/ui/commands/providerCommand.js.map +1 -0
  84. package/dist/src/ui/commands/quitCommand.d.ts +7 -0
  85. package/dist/src/ui/commands/quitCommand.js +32 -0
  86. package/dist/src/ui/commands/quitCommand.js.map +1 -0
  87. package/dist/src/ui/commands/restoreCommand.d.ts +8 -0
  88. package/dist/src/ui/commands/restoreCommand.js +126 -0
  89. package/dist/src/ui/commands/restoreCommand.js.map +1 -0
  90. package/dist/src/ui/commands/statsCommand.d.ts +7 -0
  91. package/dist/src/ui/commands/statsCommand.js +50 -0
  92. package/dist/src/ui/commands/statsCommand.js.map +1 -0
  93. package/dist/src/ui/commands/toolsCommand.d.ts +7 -0
  94. package/dist/src/ui/commands/toolsCommand.js +54 -0
  95. package/dist/src/ui/commands/toolsCommand.js.map +1 -0
  96. package/dist/src/ui/commands/types.d.ts +34 -2
  97. package/dist/src/ui/components/ContextSummaryDisplay.d.ts +6 -1
  98. package/dist/src/ui/components/ContextSummaryDisplay.js +46 -19
  99. package/dist/src/ui/components/ContextSummaryDisplay.js.map +1 -1
  100. package/dist/src/ui/components/Footer.d.ts +0 -1
  101. package/dist/src/ui/components/Footer.js +3 -21
  102. package/dist/src/ui/components/Footer.js.map +1 -1
  103. package/dist/src/ui/components/InputPrompt.js +110 -61
  104. package/dist/src/ui/components/InputPrompt.js.map +1 -1
  105. package/dist/src/ui/components/ProviderModelDialog.d.ts +1 -1
  106. package/dist/src/ui/components/ThemeDialog.js +25 -24
  107. package/dist/src/ui/components/ThemeDialog.js.map +1 -1
  108. package/dist/src/ui/components/messages/ToolGroupMessage.js +3 -1
  109. package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
  110. package/dist/src/ui/components/shared/MaxSizedBox.js +69 -2
  111. package/dist/src/ui/components/shared/MaxSizedBox.js.map +1 -1
  112. package/dist/src/ui/components/shared/RadioButtonSelect.d.ts +3 -1
  113. package/dist/src/ui/components/shared/RadioButtonSelect.js +60 -10
  114. package/dist/src/ui/components/shared/RadioButtonSelect.js.map +1 -1
  115. package/dist/src/ui/components/shared/text-buffer.js +1 -1
  116. package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
  117. package/dist/src/ui/constants.d.ts +1 -0
  118. package/dist/src/ui/constants.js +1 -0
  119. package/dist/src/ui/constants.js.map +1 -1
  120. package/dist/src/ui/containers/SessionController.js +1 -1
  121. package/dist/src/ui/containers/SessionController.js.map +1 -1
  122. package/dist/src/ui/contexts/OpenAIProviderContext.d.ts +1 -2
  123. package/dist/src/ui/contexts/OpenAIProviderContext.js.map +1 -1
  124. package/dist/src/ui/hooks/shellCommandProcessor.d.ts +1 -1
  125. package/dist/src/ui/hooks/shellCommandProcessor.js +35 -11
  126. package/dist/src/ui/hooks/shellCommandProcessor.js.map +1 -1
  127. package/dist/src/ui/hooks/slashCommandProcessor.d.ts +2 -9
  128. package/dist/src/ui/hooks/slashCommandProcessor.js +83 -622
  129. package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
  130. package/dist/src/ui/hooks/useAuthCommand.js +16 -2
  131. package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
  132. package/dist/src/ui/hooks/useCompletion.d.ts +1 -0
  133. package/dist/src/ui/hooks/useCompletion.js +21 -2
  134. package/dist/src/ui/hooks/useCompletion.js.map +1 -1
  135. package/dist/src/ui/hooks/useFocus.d.ts +6 -0
  136. package/dist/src/ui/hooks/useFocus.js +41 -0
  137. package/dist/src/ui/hooks/useFocus.js.map +1 -0
  138. package/dist/src/ui/hooks/useGeminiStream.js +34 -2
  139. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  140. package/dist/src/ui/hooks/useOpenAIProviderInfo.d.ts +3 -2
  141. package/dist/src/ui/hooks/useOpenAIProviderInfo.js +5 -4
  142. package/dist/src/ui/hooks/useOpenAIProviderInfo.js.map +1 -1
  143. package/dist/src/ui/hooks/usePrivacySettings.js +5 -5
  144. package/dist/src/ui/hooks/usePrivacySettings.js.map +1 -1
  145. package/dist/src/ui/hooks/useProviderDialog.d.ts +5 -2
  146. package/dist/src/ui/hooks/useProviderDialog.js +55 -3
  147. package/dist/src/ui/hooks/useProviderDialog.js.map +1 -1
  148. package/dist/src/ui/hooks/useProviderModelDialog.d.ts +1 -1
  149. package/dist/src/ui/themes/ansi-light.js +1 -1
  150. package/dist/src/ui/themes/ansi-light.js.map +1 -1
  151. package/dist/src/ui/themes/googlecode.js +1 -1
  152. package/dist/src/ui/themes/googlecode.js.map +1 -1
  153. package/dist/src/ui/themes/xcode.js +1 -1
  154. package/dist/src/ui/themes/xcode.js.map +1 -1
  155. package/dist/src/ui/types.d.ts +10 -0
  156. package/dist/src/ui/types.js.map +1 -1
  157. package/dist/src/ui/utils/updateCheck.js +10 -6
  158. package/dist/src/ui/utils/updateCheck.js.map +1 -1
  159. package/dist/src/utils/userStartupWarnings.js +1 -16
  160. package/dist/src/utils/userStartupWarnings.js.map +1 -1
  161. package/dist/tsconfig.tsbuildinfo +1 -1
  162. package/package.json +5 -5
  163. package/LICENSE +0 -202
  164. package/README.md +0 -256
  165. package/dist/src/providers/IMessage.d.ts +0 -38
  166. package/dist/src/providers/IMessage.js +0 -17
  167. package/dist/src/providers/IMessage.js.map +0 -1
  168. package/dist/src/providers/IModel.d.ts +0 -23
  169. package/dist/src/providers/IModel.js +0 -17
  170. package/dist/src/providers/IModel.js.map +0 -1
  171. package/dist/src/providers/IProvider.d.ts +0 -32
  172. package/dist/src/providers/IProvider.js +0 -17
  173. package/dist/src/providers/IProvider.js.map +0 -1
  174. package/dist/src/providers/ITool.d.ts +0 -23
  175. package/dist/src/providers/ITool.js +0 -17
  176. package/dist/src/providers/ITool.js.map +0 -1
  177. package/dist/src/providers/ProviderAwareContentGenerator.js +0 -9
  178. package/dist/src/providers/ProviderAwareContentGenerator.js.map +0 -1
  179. package/dist/src/providers/ProviderManager.d.ts +0 -19
  180. package/dist/src/providers/ProviderManager.js +0 -63
  181. package/dist/src/providers/ProviderManager.js.map +0 -1
  182. package/dist/src/providers/ProviderManagerAdapter.d.ts +0 -17
  183. package/dist/src/providers/ProviderManagerAdapter.js +0 -113
  184. package/dist/src/providers/ProviderManagerAdapter.js.map +0 -1
  185. package/dist/src/providers/README-qwen3.md +0 -60
  186. package/dist/src/providers/adapters/IStreamAdapter.d.ts +0 -18
  187. package/dist/src/providers/adapters/IStreamAdapter.js +0 -7
  188. package/dist/src/providers/adapters/IStreamAdapter.js.map +0 -1
  189. package/dist/src/providers/anthropic/AnthropicProvider.d.ts +0 -46
  190. package/dist/src/providers/anthropic/AnthropicProvider.js +0 -478
  191. package/dist/src/providers/anthropic/AnthropicProvider.js.map +0 -1
  192. package/dist/src/providers/contentGeneratorProvider.d.ts +0 -13
  193. package/dist/src/providers/contentGeneratorProvider.js +0 -17
  194. package/dist/src/providers/contentGeneratorProvider.js.map +0 -1
  195. package/dist/src/providers/gemini/GeminiProvider.d.ts +0 -72
  196. package/dist/src/providers/gemini/GeminiProvider.js +0 -454
  197. package/dist/src/providers/gemini/GeminiProvider.js.map +0 -1
  198. package/dist/src/providers/integration/TEST_INSTRUCTIONS.md +0 -197
  199. package/dist/src/providers/openai/ConversationCache.d.ts +0 -20
  200. package/dist/src/providers/openai/ConversationCache.js +0 -109
  201. package/dist/src/providers/openai/ConversationCache.js.map +0 -1
  202. package/dist/src/providers/openai/IChatGenerateParams.d.ts +0 -11
  203. package/dist/src/providers/openai/IChatGenerateParams.js +0 -2
  204. package/dist/src/providers/openai/IChatGenerateParams.js.map +0 -1
  205. package/dist/src/providers/openai/OpenAIProvider.d.ts +0 -71
  206. package/dist/src/providers/openai/OpenAIProvider.js +0 -486
  207. package/dist/src/providers/openai/OpenAIProvider.js.map +0 -1
  208. package/dist/src/providers/openai/Qwen3FireworksProvider.d.ts +0 -39
  209. package/dist/src/providers/openai/Qwen3FireworksProvider.js +0 -209
  210. package/dist/src/providers/openai/Qwen3FireworksProvider.js.map +0 -1
  211. package/dist/src/providers/openai/RESPONSES_API_MODELS.d.ts +0 -2
  212. package/dist/src/providers/openai/RESPONSES_API_MODELS.js +0 -14
  213. package/dist/src/providers/openai/RESPONSES_API_MODELS.js.map +0 -1
  214. package/dist/src/providers/openai/buildResponsesRequest.d.ts +0 -67
  215. package/dist/src/providers/openai/buildResponsesRequest.js +0 -144
  216. package/dist/src/providers/openai/buildResponsesRequest.js.map +0 -1
  217. package/dist/src/providers/openai/docs/accessing-provider-info.md +0 -172
  218. package/dist/src/providers/openai/docs/params-mapping.md +0 -91
  219. package/dist/src/providers/openai/docs/qwen3-fireworks.md +0 -47
  220. package/dist/src/providers/openai/docs/responses-api-tool-calls.md +0 -96
  221. package/dist/src/providers/openai/estimateRemoteTokens.d.ts +0 -26
  222. package/dist/src/providers/openai/estimateRemoteTokens.js +0 -75
  223. package/dist/src/providers/openai/estimateRemoteTokens.js.map +0 -1
  224. package/dist/src/providers/openai/getOpenAIProviderInfo.d.ts +0 -46
  225. package/dist/src/providers/openai/getOpenAIProviderInfo.js +0 -74
  226. package/dist/src/providers/openai/getOpenAIProviderInfo.js.map +0 -1
  227. package/dist/src/providers/openai/parseResponsesStream.d.ts +0 -3
  228. package/dist/src/providers/openai/parseResponsesStream.js +0 -444
  229. package/dist/src/providers/openai/parseResponsesStream.js.map +0 -1
  230. package/dist/src/providers/parsers/TextToolCallParser.d.ts +0 -35
  231. package/dist/src/providers/parsers/TextToolCallParser.js +0 -248
  232. package/dist/src/providers/parsers/TextToolCallParser.js.map +0 -1
  233. package/dist/src/providers/tokenizers/AnthropicTokenizer.d.ts +0 -19
  234. package/dist/src/providers/tokenizers/AnthropicTokenizer.js +0 -37
  235. package/dist/src/providers/tokenizers/AnthropicTokenizer.js.map +0 -1
  236. package/dist/src/providers/tokenizers/ITokenizer.d.ts +0 -18
  237. package/dist/src/providers/tokenizers/ITokenizer.js +0 -17
  238. package/dist/src/providers/tokenizers/ITokenizer.js.map +0 -1
  239. package/dist/src/providers/tokenizers/OpenAITokenizer.d.ts +0 -24
  240. package/dist/src/providers/tokenizers/OpenAITokenizer.js +0 -56
  241. package/dist/src/providers/tokenizers/OpenAITokenizer.js.map +0 -1
  242. package/dist/src/tools/IToolFormatter.d.ts +0 -40
  243. package/dist/src/tools/IToolFormatter.js +0 -17
  244. package/dist/src/tools/IToolFormatter.js.map +0 -1
  245. package/dist/src/tools/ToolFormatter.d.ts +0 -45
  246. package/dist/src/tools/ToolFormatter.js +0 -216
  247. package/dist/src/tools/ToolFormatter.js.map +0 -1
  248. package/dist/vybestack-llxprt-code-0.1.12.tgz +0 -0
@@ -4,7 +4,6 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { useCallback, useMemo, useEffect, useState } from 'react';
7
- import open from 'open';
8
7
  import process from 'node:process';
9
8
  import { ansi } from '../colors.js';
10
9
  import { useStateAndRef } from './useStateAndRef.js';
@@ -13,20 +12,16 @@ import { useSessionStats } from '../contexts/SessionContext.js';
13
12
  import { MessageType, } from '../types.js';
14
13
  import { promises as fs } from 'fs';
15
14
  import path from 'path';
16
- import { homedir } from 'os';
17
- // import { createShowMemoryAction } from './useShowMemoryCommand.js';
18
15
  import { GIT_COMMIT_INFO } from '../../generated/git-commit.js';
19
16
  import { formatDuration, formatMemoryUsage } from '../utils/formatters.js';
20
17
  import { getCliVersion } from '../../utils/version.js';
21
- import { SettingScope } from '../../config/settings.js';
22
18
  import { CommandService } from '../../services/CommandService.js';
23
19
  import { getProviderManager } from '../../providers/providerManagerInstance.js';
24
- import { ConversationContext, } from '../../utils/ConversationContext.js';
25
- import { setProviderApiKey, setProviderApiKeyFromFile, setProviderBaseUrl, } from '../../providers/providerConfigUtils.js';
20
+ import open from 'open';
26
21
  /**
27
22
  * Hook to define and process slash commands (e.g., /help, /clear).
28
23
  */
29
- export const useSlashCommandProcessor = (config, settings, history, addItem, clearItems, loadHistory, refreshStatic, setShowHelp, onDebugMessage, openThemeDialog, openAuthDialog, openEditorDialog, openProviderDialog, openProviderModelDialog, performMemoryRefresh, toggleCorgiMode, showToolDescriptions = false, setQuittingMessages, openPrivacyNotice, checkPaymentModeChange) => {
24
+ export const useSlashCommandProcessor = (config, settings, addItem, clearItems, loadHistory, refreshStatic, setShowHelp, onDebugMessage, openThemeDialog, openAuthDialog, openEditorDialog, openProviderDialog, openProviderModelDialog, performMemoryRefresh, setQuittingMessages, openPrivacyNotice, checkPaymentModeChange, showToolDescriptions) => {
30
25
  const session = useSessionStats();
31
26
  const [commands, setCommands] = useState([]);
32
27
  const gitService = useMemo(() => {
@@ -61,6 +56,8 @@ export const useSlashCommandProcessor = (config, settings, history, addItem, cle
61
56
  modelVersion: message.modelVersion,
62
57
  selectedAuthType: message.selectedAuthType,
63
58
  gcpProject: message.gcpProject,
59
+ keyfile: message.keyfile,
60
+ key: message.key,
64
61
  };
65
62
  }
66
63
  else if (message.type === MessageType.STATS) {
@@ -117,7 +114,10 @@ export const useSlashCommandProcessor = (config, settings, history, addItem, cle
117
114
  console.clear();
118
115
  refreshStatic();
119
116
  },
117
+ loadHistory,
120
118
  setDebugMessage: onDebugMessage,
119
+ pendingItem: pendingCompressionItemRef.current,
120
+ setPendingItem: setPendingCompressionItem,
121
121
  },
122
122
  session: {
123
123
  stats: session.stats,
@@ -127,13 +127,16 @@ export const useSlashCommandProcessor = (config, settings, history, addItem, cle
127
127
  settings,
128
128
  gitService,
129
129
  logger,
130
+ loadHistory,
130
131
  addItem,
131
132
  clearItems,
132
133
  refreshStatic,
133
134
  session.stats,
134
135
  onDebugMessage,
136
+ pendingCompressionItemRef,
137
+ setPendingCompressionItem,
135
138
  ]);
136
- const commandService = useMemo(() => new CommandService(), []);
139
+ const commandService = useMemo(() => new CommandService(config), [config]);
137
140
  useEffect(() => {
138
141
  const load = async () => {
139
142
  await commandService.loadCommands();
@@ -141,7 +144,7 @@ export const useSlashCommandProcessor = (config, settings, history, addItem, cle
141
144
  };
142
145
  load();
143
146
  }, [commandService]);
144
- const savedChatTags = useCallback(async () => {
147
+ const _savedChatTags = useCallback(async () => {
145
148
  const geminiDir = config?.getProjectTempDir();
146
149
  if (!geminiDir) {
147
150
  return [];
@@ -159,13 +162,13 @@ export const useSlashCommandProcessor = (config, settings, history, addItem, cle
159
162
  // Define legacy commands
160
163
  // This list contains all commands that have NOT YET been migrated to the
161
164
  // new system. As commands are migrated, they are removed from this list.
162
- const legacyCommands = useMemo(() => {
165
+ const _legacyCommands = useMemo(() => {
163
166
  const commands = [
164
167
  // `/help` and `/clear` have been migrated and REMOVED from this list.
165
168
  {
166
169
  name: 'docs',
167
170
  description: 'open full LLxprt Code documentation in your browser',
168
- action: async (_mainCommand, _subCommand, _args) => {
171
+ action: async (_context, _args) => {
169
172
  const docsUrl = 'https://goo.gle/gemini-cli-docs';
170
173
  if (process.env.SANDBOX && process.env.SANDBOX !== 'sandbox-exec') {
171
174
  addMessage({
@@ -187,7 +190,8 @@ export const useSlashCommandProcessor = (config, settings, history, addItem, cle
187
190
  {
188
191
  name: 'auth',
189
192
  description: 'change the auth method',
190
- action: async (_mainCommand, authMode, _args) => {
193
+ action: async (_context, args) => {
194
+ const authMode = args?.split(' ')[0];
191
195
  const providerManager = getProviderManager();
192
196
  // If no auth mode specified, open the dialog
193
197
  if (!authMode) {
@@ -251,13 +255,17 @@ export const useSlashCommandProcessor = (config, settings, history, addItem, cle
251
255
  {
252
256
  name: 'editor',
253
257
  description: 'set external editor preference',
254
- action: (_mainCommand, _subCommand, _args) => openEditorDialog(),
258
+ action: (_context, _args) => ({
259
+ type: 'dialog',
260
+ dialog: 'editor',
261
+ }),
255
262
  },
256
263
  {
257
264
  name: 'stats',
258
265
  altName: 'usage',
259
266
  description: 'check session stats. Usage: /stats [model|tools]',
260
- action: (_mainCommand, subCommand, _args) => {
267
+ action: (_context, args) => {
268
+ const subCommand = args?.split(' ')[0];
261
269
  if (subCommand === 'model') {
262
270
  addMessage({
263
271
  type: MessageType.MODEL_STATS,
@@ -285,25 +293,29 @@ export const useSlashCommandProcessor = (config, settings, history, addItem, cle
285
293
  {
286
294
  name: 'mcp',
287
295
  description: 'list configured MCP servers and tools',
288
- action: async (_mainCommand, _subCommand, _args) => {
289
- // Check if the _subCommand includes a specific flag to control description visibility
296
+ action: async (_context, args) => {
297
+ // Check if the args includes a specific flag to control description visibility
298
+ const [subCommand, ...rest] = args?.split(' ') || [];
299
+ const remainingArgs = rest.join(' ');
290
300
  let useShowDescriptions = showToolDescriptions;
291
- if (_subCommand === 'desc' || _subCommand === 'descriptions') {
301
+ if (subCommand === 'desc' || subCommand === 'descriptions') {
292
302
  useShowDescriptions = true;
293
303
  }
294
- else if (_subCommand === 'nodesc' ||
295
- _subCommand === 'nodescriptions') {
304
+ else if (subCommand === 'nodesc' ||
305
+ subCommand === 'nodescriptions') {
296
306
  useShowDescriptions = false;
297
307
  }
298
- else if (_args === 'desc' || _args === 'descriptions') {
308
+ else if (remainingArgs === 'desc' ||
309
+ remainingArgs === 'descriptions') {
299
310
  useShowDescriptions = true;
300
311
  }
301
- else if (_args === 'nodesc' || _args === 'nodescriptions') {
312
+ else if (remainingArgs === 'nodesc' ||
313
+ remainingArgs === 'nodescriptions') {
302
314
  useShowDescriptions = false;
303
315
  }
304
- // Check if the _subCommand includes a specific flag to show detailed tool schema
316
+ // Check if the args includes a specific flag to show detailed tool schema
305
317
  let useShowSchema = false;
306
- if (_subCommand === 'schema' || _args === 'schema') {
318
+ if (subCommand === 'schema' || remainingArgs === 'schema') {
307
319
  useShowSchema = true;
308
320
  }
309
321
  const toolRegistry = await config?.getToolRegistry();
@@ -477,20 +489,24 @@ export const useSlashCommandProcessor = (config, settings, history, addItem, cle
477
489
  {
478
490
  name: 'tools',
479
491
  description: 'list available LLxprt Code tools',
480
- action: async (_mainCommand, _subCommand, _args) => {
481
- // Check if the _subCommand includes a specific flag to control description visibility
492
+ action: async (_context, args) => {
493
+ // Check if the args includes a specific flag to control description visibility
494
+ const [subCommand, ...rest] = args?.split(' ') || [];
495
+ const remainingArgs = rest.join(' ');
482
496
  let useShowDescriptions = showToolDescriptions;
483
- if (_subCommand === 'desc' || _subCommand === 'descriptions') {
497
+ if (subCommand === 'desc' || subCommand === 'descriptions') {
484
498
  useShowDescriptions = true;
485
499
  }
486
- else if (_subCommand === 'nodesc' ||
487
- _subCommand === 'nodescriptions') {
500
+ else if (subCommand === 'nodesc' ||
501
+ subCommand === 'nodescriptions') {
488
502
  useShowDescriptions = false;
489
503
  }
490
- else if (_args === 'desc' || _args === 'descriptions') {
504
+ else if (remainingArgs === 'desc' ||
505
+ remainingArgs === 'descriptions') {
491
506
  useShowDescriptions = true;
492
507
  }
493
- else if (_args === 'nodesc' || _args === 'nodescriptions') {
508
+ else if (remainingArgs === 'nodesc' ||
509
+ remainingArgs === 'nodescriptions') {
494
510
  useShowDescriptions = false;
495
511
  }
496
512
  const toolRegistry = await config?.getToolRegistry();
@@ -537,124 +553,11 @@ export const useSlashCommandProcessor = (config, settings, history, addItem, cle
537
553
  });
538
554
  },
539
555
  },
540
- {
541
- name: 'model',
542
- description: 'select or switch model',
543
- action: async (_mainCommand, _subCommand, _args) => {
544
- const modelName = _subCommand || _args;
545
- const providerManager = getProviderManager();
546
- // Always use provider model dialog
547
- if (!modelName) {
548
- openProviderModelDialog();
549
- return;
550
- }
551
- // Switch model in provider
552
- try {
553
- const activeProvider = providerManager.getActiveProvider();
554
- const currentModel = activeProvider.getCurrentModel
555
- ? activeProvider.getCurrentModel()
556
- : 'unknown';
557
- if (activeProvider.setModel) {
558
- activeProvider.setModel(modelName);
559
- // Keep config model in sync so /about shows correct model
560
- if (config) {
561
- config.setModel(modelName);
562
- }
563
- addMessage({
564
- type: MessageType.INFO,
565
- content: `Switched from ${currentModel} to ${modelName} in provider '${activeProvider.name}'`,
566
- timestamp: new Date(),
567
- });
568
- }
569
- else {
570
- addMessage({
571
- type: MessageType.ERROR,
572
- content: `Provider '${activeProvider.name}' does not support model switching`,
573
- timestamp: new Date(),
574
- });
575
- }
576
- }
577
- catch (error) {
578
- addMessage({
579
- type: MessageType.ERROR,
580
- content: `Failed to switch model: ${error instanceof Error ? error.message : String(error)}`,
581
- timestamp: new Date(),
582
- });
583
- }
584
- },
585
- },
586
- {
587
- name: 'provider',
588
- description: 'switch between different AI providers (openai, anthropic, etc.)',
589
- action: async (_mainCommand, providerName, _args) => {
590
- const providerManager = getProviderManager();
591
- if (!providerName) {
592
- // Open interactive provider selection dialog
593
- openProviderDialog();
594
- return;
595
- }
596
- try {
597
- const currentProvider = providerManager.getActiveProviderName();
598
- // Handle switching to same provider
599
- if (providerName === currentProvider) {
600
- addMessage({
601
- type: MessageType.INFO,
602
- content: `Already using provider: ${currentProvider}`,
603
- timestamp: new Date(),
604
- });
605
- return;
606
- }
607
- const fromProvider = currentProvider || 'none';
608
- providerManager.setActiveProvider(providerName);
609
- // Update config model to provider default
610
- const newActiveProvider = providerManager.getActiveProvider();
611
- if (config && newActiveProvider.getCurrentModel) {
612
- config.setModel(newActiveProvider.getCurrentModel());
613
- }
614
- // Set the appropriate auth type based on provider
615
- if (providerName === 'gemini') {
616
- settings.setValue(SettingScope.User, 'selectedAuthType', AuthType.USE_GEMINI);
617
- await config?.refreshAuth(AuthType.USE_GEMINI);
618
- }
619
- else {
620
- settings.setValue(SettingScope.User, 'selectedAuthType', AuthType.USE_PROVIDER);
621
- await config?.refreshAuth(AuthType.USE_PROVIDER);
622
- }
623
- addMessage({
624
- type: MessageType.INFO,
625
- content: `Switched from ${fromProvider} to ${providerName}`,
626
- timestamp: new Date(),
627
- });
628
- // Trigger payment mode check to show banner when switching providers
629
- // Pass the previous provider to ensure proper detection
630
- if (checkPaymentModeChange) {
631
- setTimeout(() => checkPaymentModeChange(fromProvider), 100);
632
- }
633
- }
634
- catch (error) {
635
- addMessage({
636
- type: MessageType.ERROR,
637
- content: `Failed to switch provider: ${error instanceof Error ? error.message : String(error)}`,
638
- timestamp: new Date(),
639
- });
640
- }
641
- },
642
- },
643
- {
644
- name: 'corgi',
645
- action: (_mainCommand, _subCommand, _args) => {
646
- toggleCorgiMode();
647
- },
648
- },
649
556
  {
650
557
  name: 'bug',
651
558
  description: 'submit a bug report',
652
- action: async (_mainCommand, _subCommand, args) => {
653
- let bugDescription = _subCommand || '';
654
- if (args) {
655
- bugDescription += ` ${args}`;
656
- }
657
- bugDescription = bugDescription.trim();
559
+ action: async (_context, args) => {
560
+ const bugDescription = args?.trim() || '';
658
561
  const osVersion = `${process.platform} ${process.version}`;
659
562
  let sandboxEnv = 'no sandbox';
660
563
  if (process.env.SANDBOX && process.env.SANDBOX !== 'sandbox-exec') {
@@ -702,418 +605,6 @@ export const useSlashCommandProcessor = (config, settings, history, addItem, cle
702
605
  })();
703
606
  },
704
607
  },
705
- {
706
- name: 'chat',
707
- description: 'Manage conversation history. Usage: /chat <list|save|resume> <tag>',
708
- action: async (_mainCommand, subCommand, args) => {
709
- const tag = (args || '').trim();
710
- const logger = new Logger(config?.getSessionId() || '');
711
- await logger.initialize();
712
- const chat = await config?.getGeminiClient()?.getChat();
713
- if (!chat) {
714
- addMessage({
715
- type: MessageType.ERROR,
716
- content: 'No chat client available for conversation status.',
717
- timestamp: new Date(),
718
- });
719
- return;
720
- }
721
- if (!subCommand) {
722
- addMessage({
723
- type: MessageType.ERROR,
724
- content: 'Missing command\nUsage: /chat <list|save|resume> <tag>',
725
- timestamp: new Date(),
726
- });
727
- return;
728
- }
729
- switch (subCommand) {
730
- case 'save': {
731
- if (!tag) {
732
- addMessage({
733
- type: MessageType.ERROR,
734
- content: 'Missing tag. Usage: /chat save <tag>',
735
- timestamp: new Date(),
736
- });
737
- return;
738
- }
739
- const history = chat.getHistory();
740
- if (history.length > 0) {
741
- await logger.saveCheckpoint(chat?.getHistory() || [], tag, ConversationContext.getContext());
742
- addMessage({
743
- type: MessageType.INFO,
744
- content: `Conversation checkpoint saved with tag: ${tag}.`,
745
- timestamp: new Date(),
746
- });
747
- }
748
- else {
749
- addMessage({
750
- type: MessageType.INFO,
751
- content: 'No conversation found to save.',
752
- timestamp: new Date(),
753
- });
754
- }
755
- return;
756
- }
757
- case 'resume':
758
- case 'restore':
759
- case 'load': {
760
- if (!tag) {
761
- addMessage({
762
- type: MessageType.ERROR,
763
- content: 'Missing tag. Usage: /chat resume <tag>',
764
- timestamp: new Date(),
765
- });
766
- return;
767
- }
768
- const { history: conversation, context } = await logger.loadCheckpoint(tag);
769
- if (conversation.length === 0) {
770
- addMessage({
771
- type: MessageType.INFO,
772
- content: `No saved checkpoint found with tag: ${tag}.`,
773
- timestamp: new Date(),
774
- });
775
- return;
776
- }
777
- if (context) {
778
- ConversationContext.setContext(context);
779
- }
780
- else {
781
- // For old checkpoints, start a new context
782
- ConversationContext.startNewConversation();
783
- }
784
- clearItems();
785
- chat.clearHistory();
786
- const rolemap = {
787
- user: MessageType.USER,
788
- model: MessageType.GEMINI,
789
- };
790
- let hasSystemPrompt = false;
791
- let i = 0;
792
- for (const item of conversation) {
793
- i += 1;
794
- // Add each item to history regardless of whether we display
795
- // it.
796
- chat.addHistory(item);
797
- const text = item.parts
798
- ?.filter((m) => !!m.text)
799
- .map((m) => m.text)
800
- .join('') || '';
801
- if (!text) {
802
- // Parsing Part[] back to various non-text output not yet implemented.
803
- continue;
804
- }
805
- if (i === 1 && text.match(/context for our chat/)) {
806
- hasSystemPrompt = true;
807
- }
808
- if (i > 2 || !hasSystemPrompt) {
809
- addItem({
810
- type: (item.role && rolemap[item.role]) || MessageType.GEMINI,
811
- text,
812
- }, i);
813
- }
814
- }
815
- console.clear();
816
- refreshStatic();
817
- return;
818
- }
819
- case 'list':
820
- addMessage({
821
- type: MessageType.INFO,
822
- content: 'list of saved conversations: ' +
823
- (await savedChatTags()).join(', '),
824
- timestamp: new Date(),
825
- });
826
- return;
827
- default:
828
- addMessage({
829
- type: MessageType.ERROR,
830
- content: `Unknown /chat command: ${subCommand}. Available: list, save, resume`,
831
- timestamp: new Date(),
832
- });
833
- return;
834
- }
835
- },
836
- completion: async () => (await savedChatTags()).map((tag) => 'resume ' + tag),
837
- },
838
- {
839
- name: 'quit',
840
- altName: 'exit',
841
- description: 'exit the cli',
842
- action: async (mainCommand, _subCommand, _args) => {
843
- const now = new Date();
844
- const { sessionStartTime } = session.stats;
845
- const wallDuration = now.getTime() - sessionStartTime.getTime();
846
- setQuittingMessages([
847
- {
848
- type: 'user',
849
- text: `/${mainCommand}`,
850
- id: now.getTime() - 1,
851
- },
852
- {
853
- type: 'quit',
854
- duration: formatDuration(wallDuration),
855
- id: now.getTime(),
856
- },
857
- ]);
858
- setTimeout(() => {
859
- process.exit(0);
860
- }, 100);
861
- },
862
- },
863
- {
864
- name: 'compress',
865
- altName: 'summarize',
866
- description: 'Compresses the context by replacing it with a summary.',
867
- action: async (_mainCommand, _subCommand, _args) => {
868
- if (pendingCompressionItemRef.current !== null) {
869
- addMessage({
870
- type: MessageType.ERROR,
871
- content: 'Already compressing, wait for previous request to complete',
872
- timestamp: new Date(),
873
- });
874
- return;
875
- }
876
- setPendingCompressionItem({
877
- type: MessageType.COMPRESSION,
878
- compression: {
879
- isPending: true,
880
- originalTokenCount: null,
881
- newTokenCount: null,
882
- },
883
- });
884
- try {
885
- const compressed = await config
886
- .getGeminiClient()
887
- // TODO: Set Prompt id for CompressChat from SlashCommandProcessor.
888
- .tryCompressChat('Prompt Id not set', true);
889
- if (compressed) {
890
- addMessage({
891
- type: MessageType.COMPRESSION,
892
- compression: {
893
- isPending: false,
894
- originalTokenCount: compressed.originalTokenCount,
895
- newTokenCount: compressed.newTokenCount,
896
- },
897
- timestamp: new Date(),
898
- });
899
- }
900
- else {
901
- addMessage({
902
- type: MessageType.ERROR,
903
- content: 'Failed to compress chat history.',
904
- timestamp: new Date(),
905
- });
906
- }
907
- }
908
- catch (e) {
909
- addMessage({
910
- type: MessageType.ERROR,
911
- content: `Failed to compress chat history: ${e instanceof Error ? e.message : String(e)}`,
912
- timestamp: new Date(),
913
- });
914
- }
915
- setPendingCompressionItem(null);
916
- },
917
- },
918
- {
919
- name: 'key',
920
- description: 'set or remove API key for the current provider',
921
- action: async (_mainCommand, apiKey, _args) => {
922
- const providerManager = getProviderManager();
923
- const result = await setProviderApiKey(providerManager, settings, apiKey, config ?? undefined);
924
- addMessage({
925
- type: result.success ? MessageType.INFO : MessageType.ERROR,
926
- content: result.message,
927
- timestamp: new Date(),
928
- });
929
- // Trigger payment mode check to show banner if needed
930
- if (result.success && checkPaymentModeChange) {
931
- setTimeout(checkPaymentModeChange, 100);
932
- }
933
- },
934
- },
935
- {
936
- name: 'keyfile',
937
- description: 'manage API key file for the current provider',
938
- action: async (_mainCommand, filePath, _args) => {
939
- const providerManager = getProviderManager();
940
- try {
941
- const activeProvider = providerManager.getActiveProvider();
942
- const providerName = activeProvider.name;
943
- // If no path provided, check for existing keyfile
944
- if (!filePath || filePath.trim() === '') {
945
- // Check common keyfile locations
946
- const keyfilePaths = [
947
- path.join(homedir(), `.${providerName}_key`),
948
- path.join(homedir(), `.${providerName}-key`),
949
- path.join(homedir(), `.${providerName}_api_key`),
950
- ];
951
- // For specific providers, check their known keyfile locations
952
- if (providerName === 'openai') {
953
- keyfilePaths.unshift(path.join(homedir(), '.openai_key'));
954
- }
955
- else if (providerName === 'anthropic') {
956
- keyfilePaths.unshift(path.join(homedir(), '.anthropic_key'));
957
- }
958
- let foundKeyfile = null;
959
- for (const keyfilePath of keyfilePaths) {
960
- try {
961
- await fs.access(keyfilePath);
962
- foundKeyfile = keyfilePath;
963
- break;
964
- }
965
- catch {
966
- // File doesn't exist, continue checking
967
- }
968
- }
969
- if (foundKeyfile) {
970
- addMessage({
971
- type: MessageType.INFO,
972
- content: `Current keyfile for provider '${providerName}': ${foundKeyfile}\nTo remove: /keyfile none\nTo change: /keyfile <new_path>`,
973
- timestamp: new Date(),
974
- });
975
- }
976
- else {
977
- addMessage({
978
- type: MessageType.INFO,
979
- content: `No keyfile found for provider '${providerName}'\nTo set: /keyfile <path>`,
980
- timestamp: new Date(),
981
- });
982
- }
983
- return;
984
- }
985
- // If 'none' is specified, remove the keyfile setting
986
- if (filePath.trim().toLowerCase() === 'none') {
987
- const result = await setProviderApiKey(providerManager, settings, undefined, // Clear the API key
988
- config ?? undefined);
989
- addMessage({
990
- type: result.success ? MessageType.INFO : MessageType.ERROR,
991
- content: result.message.replace('API key removed', 'Keyfile removed'),
992
- timestamp: new Date(),
993
- });
994
- // Trigger payment mode check to show banner if needed
995
- if (result.success && checkPaymentModeChange) {
996
- setTimeout(checkPaymentModeChange, 100);
997
- }
998
- return;
999
- }
1000
- // Load API key from file
1001
- const result = await setProviderApiKeyFromFile(providerManager, settings, filePath, config ?? undefined);
1002
- addMessage({
1003
- type: result.success ? MessageType.INFO : MessageType.ERROR,
1004
- content: result.message,
1005
- timestamp: new Date(),
1006
- });
1007
- // Trigger payment mode check to show banner if needed
1008
- if (result.success && checkPaymentModeChange) {
1009
- setTimeout(checkPaymentModeChange, 100);
1010
- }
1011
- }
1012
- catch (error) {
1013
- addMessage({
1014
- type: MessageType.ERROR,
1015
- content: `Failed to process keyfile: ${error instanceof Error ? error.message : String(error)}`,
1016
- timestamp: new Date(),
1017
- });
1018
- }
1019
- },
1020
- },
1021
- {
1022
- name: 'baseurl',
1023
- description: 'set base URL for the current provider',
1024
- action: async (_mainCommand, baseUrl, _args) => {
1025
- const providerManager = getProviderManager();
1026
- const result = await setProviderBaseUrl(providerManager, settings, baseUrl);
1027
- addMessage({
1028
- type: result.success ? MessageType.INFO : MessageType.ERROR,
1029
- content: result.message,
1030
- timestamp: new Date(),
1031
- });
1032
- },
1033
- },
1034
- {
1035
- name: 'toolformat',
1036
- description: 'override the auto-detected tool calling format',
1037
- action: async (_mainCommand, formatName, _args) => {
1038
- const providerManager = getProviderManager();
1039
- const activeProvider = providerManager.getActiveProvider();
1040
- const providerName = activeProvider.name;
1041
- // Supported formats
1042
- const structuredFormats = ['openai', 'anthropic', 'deepseek', 'qwen'];
1043
- const textFormats = ['hermes', 'xml', 'llama', 'gemma'];
1044
- const allFormats = [...structuredFormats, ...textFormats];
1045
- // Show current format
1046
- if (!formatName) {
1047
- const currentFormat = activeProvider.getToolFormat
1048
- ? activeProvider.getToolFormat()
1049
- : 'unknown';
1050
- const isAutoDetected = !(settings.merged.providerToolFormatOverrides &&
1051
- settings.merged.providerToolFormatOverrides[providerName]);
1052
- addMessage({
1053
- type: MessageType.INFO,
1054
- content: `Current tool format: ${currentFormat} (${isAutoDetected ? 'auto-detected' : 'manual override'})
1055
- To override: /toolformat <format>
1056
- To return to auto: /toolformat auto
1057
- Supported formats:
1058
- Structured: ${structuredFormats.join(', ')}
1059
- Text-based: ${textFormats.join(', ')}`,
1060
- timestamp: new Date(),
1061
- });
1062
- return;
1063
- }
1064
- // Return to auto-detection
1065
- if (formatName === 'auto') {
1066
- // Clear override in provider
1067
- if (activeProvider.setToolFormatOverride) {
1068
- activeProvider.setToolFormatOverride(null);
1069
- }
1070
- // Also clear from settings
1071
- const currentOverrides = settings.merged.providerToolFormatOverrides || {};
1072
- delete currentOverrides[providerName];
1073
- settings.setValue(SettingScope.User, 'providerToolFormatOverrides', currentOverrides);
1074
- addMessage({
1075
- type: MessageType.INFO,
1076
- content: `Tool format override cleared for provider '${providerName}'. Using auto-detection.`,
1077
- timestamp: new Date(),
1078
- });
1079
- return;
1080
- }
1081
- // Validate format
1082
- if (!allFormats.includes(formatName)) {
1083
- addMessage({
1084
- type: MessageType.ERROR,
1085
- content: `Invalid format '${formatName}'. Supported formats:
1086
- Structured: ${structuredFormats.join(', ')}
1087
- Text-based: ${textFormats.join(', ')}`,
1088
- timestamp: new Date(),
1089
- });
1090
- return;
1091
- }
1092
- // Set override
1093
- try {
1094
- // Update provider directly
1095
- if (activeProvider.setToolFormatOverride) {
1096
- activeProvider.setToolFormatOverride(formatName);
1097
- }
1098
- // Also save to settings for persistence
1099
- const currentOverrides = settings.merged.providerToolFormatOverrides || {};
1100
- currentOverrides[providerName] = formatName;
1101
- settings.setValue(SettingScope.User, 'providerToolFormatOverrides', currentOverrides);
1102
- addMessage({
1103
- type: MessageType.INFO,
1104
- content: `Tool format override set to '${formatName}' for provider '${providerName}'`,
1105
- timestamp: new Date(),
1106
- });
1107
- }
1108
- catch (error) {
1109
- addMessage({
1110
- type: MessageType.ERROR,
1111
- content: `Failed to set tool format override: ${error instanceof Error ? error.message : String(error)}`,
1112
- timestamp: new Date(),
1113
- });
1114
- }
1115
- },
1116
- },
1117
608
  ];
1118
609
  if (config?.getCheckpointingEnabled()) {
1119
610
  commands.push({
@@ -1136,7 +627,8 @@ Supported formats:
1136
627
  return [];
1137
628
  }
1138
629
  },
1139
- action: async (_mainCommand, subCommand, _args) => {
630
+ action: async (_context, args) => {
631
+ const subCommand = args?.split(' ')[0];
1140
632
  const checkpointDir = config?.getProjectTempDir()
1141
633
  ? path.join(config.getProjectTempDir(), 'checkpoints')
1142
634
  : undefined;
@@ -1227,25 +719,12 @@ Supported formats:
1227
719
  return commands;
1228
720
  }, [
1229
721
  addMessage,
1230
- openEditorDialog,
1231
- openProviderModelDialog,
1232
- openProviderDialog,
1233
- clearItems,
1234
- refreshStatic,
1235
- toggleCorgiMode,
1236
- savedChatTags,
722
+ openAuthDialog,
1237
723
  config,
1238
- showToolDescriptions,
1239
724
  session,
1240
725
  gitService,
1241
726
  loadHistory,
1242
- addItem,
1243
- setQuittingMessages,
1244
- pendingCompressionItemRef,
1245
- setPendingCompressionItem,
1246
- checkPaymentModeChange,
1247
- openAuthDialog,
1248
- settings,
727
+ showToolDescriptions,
1249
728
  ]);
1250
729
  const handleSlashCommand = useCallback(async (rawQuery) => {
1251
730
  if (typeof rawQuery !== 'string') {
@@ -1261,7 +740,6 @@ Supported formats:
1261
740
  }
1262
741
  const parts = trimmed.substring(1).trim().split(/\s+/);
1263
742
  const commandPath = parts.filter((p) => p); // The parts of the command, e.g., ['memory', 'add']
1264
- // --- Start of New Tree Traversal Logic ---
1265
743
  let currentCommands = commands;
1266
744
  let commandToExecute;
1267
745
  let pathIndex = 0;
@@ -1312,14 +790,39 @@ Supported formats:
1312
790
  case 'theme':
1313
791
  openThemeDialog();
1314
792
  return { type: 'handled' };
793
+ case 'editor':
794
+ openEditorDialog();
795
+ return { type: 'handled' };
1315
796
  case 'privacy':
1316
797
  openPrivacyNotice();
1317
798
  return { type: 'handled' };
799
+ case 'provider':
800
+ openProviderDialog();
801
+ return { type: 'handled' };
802
+ case 'providerModel':
803
+ openProviderModelDialog();
804
+ return { type: 'handled' };
1318
805
  default: {
1319
806
  const unhandled = result.dialog;
1320
807
  throw new Error(`Unhandled slash command result: ${unhandled}`);
1321
808
  }
1322
809
  }
810
+ case 'load_history': {
811
+ await config
812
+ ?.getGeminiClient()
813
+ ?.setHistory(result.clientHistory);
814
+ commandContext.ui.clear();
815
+ result.history.forEach((item, index) => {
816
+ commandContext.ui.addItem(item, index);
817
+ });
818
+ return { type: 'handled' };
819
+ }
820
+ case 'quit':
821
+ setQuittingMessages(result.messages);
822
+ setTimeout(() => {
823
+ process.exit(0);
824
+ }, 100);
825
+ return { type: 'handled' };
1323
826
  default: {
1324
827
  const unhandled = result;
1325
828
  throw new Error(`Unhandled slash command result: ${unhandled}`);
@@ -1340,32 +843,6 @@ Supported formats:
1340
843
  return { type: 'handled' };
1341
844
  }
1342
845
  }
1343
- // --- End of New Tree Traversal Logic ---
1344
- // --- Legacy Fallback Logic (for commands not yet migrated) ---
1345
- const mainCommand = parts[0];
1346
- const subCommand = parts[1];
1347
- const legacyArgs = parts.slice(2).join(' ');
1348
- for (const cmd of legacyCommands) {
1349
- if (mainCommand === cmd.name || mainCommand === cmd.altName) {
1350
- const actionResult = await cmd.action(mainCommand, subCommand, legacyArgs);
1351
- if (actionResult?.type === 'tool') {
1352
- return {
1353
- type: 'schedule_tool',
1354
- toolName: actionResult.toolName,
1355
- toolArgs: actionResult.toolArgs,
1356
- };
1357
- }
1358
- if (actionResult?.type === 'message') {
1359
- addItem({
1360
- type: actionResult.messageType === 'error'
1361
- ? MessageType.ERROR
1362
- : MessageType.INFO,
1363
- text: actionResult.content,
1364
- }, Date.now());
1365
- }
1366
- return { type: 'handled' };
1367
- }
1368
- }
1369
846
  addMessage({
1370
847
  type: MessageType.ERROR,
1371
848
  content: `Unknown command: ${trimmed}`,
@@ -1373,39 +850,23 @@ Supported formats:
1373
850
  });
1374
851
  return { type: 'handled' };
1375
852
  }, [
853
+ config,
1376
854
  addItem,
1377
855
  setShowHelp,
1378
856
  openAuthDialog,
1379
857
  commands,
1380
- legacyCommands,
1381
858
  commandContext,
1382
859
  addMessage,
1383
860
  openThemeDialog,
1384
861
  openPrivacyNotice,
862
+ openEditorDialog,
863
+ setQuittingMessages,
864
+ openProviderDialog,
865
+ openProviderModelDialog,
1385
866
  ]);
1386
- const allCommands = useMemo(() => {
1387
- // Adapt legacy commands to the new SlashCommand interface
1388
- const adaptedLegacyCommands = legacyCommands.map((legacyCmd) => ({
1389
- name: legacyCmd.name,
1390
- altName: legacyCmd.altName,
1391
- description: legacyCmd.description,
1392
- action: async (_context, args) => {
1393
- const parts = args.split(/\s+/);
1394
- const subCommand = parts[0] || undefined;
1395
- const restOfArgs = parts.slice(1).join(' ') || undefined;
1396
- return legacyCmd.action(legacyCmd.name, subCommand, restOfArgs);
1397
- },
1398
- completion: legacyCmd.completion
1399
- ? async (_context, _partialArg) => legacyCmd.completion()
1400
- : undefined,
1401
- }));
1402
- const newCommandNames = new Set(commands.map((c) => c.name));
1403
- const filteredAdaptedLegacy = adaptedLegacyCommands.filter((c) => !newCommandNames.has(c.name));
1404
- return [...commands, ...filteredAdaptedLegacy];
1405
- }, [commands, legacyCommands]);
1406
867
  return {
1407
868
  handleSlashCommand,
1408
- slashCommands: allCommands,
869
+ slashCommands: commands,
1409
870
  pendingHistoryItems,
1410
871
  commandContext,
1411
872
  };