@vybestack/llxprt-code 0.1.13-nightly.250728.2261021c → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/dist/package.json +7 -5
- package/dist/src/acp/acpPeer.js +1 -0
- package/dist/src/acp/acpPeer.js.map +1 -1
- package/dist/src/config/config.d.ts +3 -2
- package/dist/src/config/config.js +19 -32
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/settings.d.ts +7 -2
- package/dist/src/config/settings.js +25 -10
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/gemini.js +7 -33
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +1 -1
- package/dist/src/generated/git-commit.js +1 -1
- package/dist/src/patches/is-in-ci.d.ts +7 -0
- package/dist/src/patches/is-in-ci.js +15 -0
- package/dist/src/patches/is-in-ci.js.map +1 -0
- package/dist/src/services/BuiltinCommandLoader.d.ts +24 -0
- package/dist/src/services/BuiltinCommandLoader.js +82 -0
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -0
- package/dist/src/services/CommandService.d.ts +43 -7
- package/dist/src/services/CommandService.js +61 -64
- package/dist/src/services/CommandService.js.map +1 -1
- package/dist/src/services/FileCommandLoader.d.ts +37 -0
- package/dist/src/services/FileCommandLoader.js +156 -0
- package/dist/src/services/FileCommandLoader.js.map +1 -0
- package/dist/src/services/prompt-processors/argumentProcessor.d.ts +21 -0
- package/dist/src/services/prompt-processors/argumentProcessor.js +28 -0
- package/dist/src/services/prompt-processors/argumentProcessor.js.map +1 -0
- package/dist/src/services/prompt-processors/types.d.ts +34 -0
- package/dist/src/services/prompt-processors/types.js +10 -0
- package/dist/src/services/prompt-processors/types.js.map +1 -0
- package/dist/src/services/types.d.ts +22 -0
- package/dist/src/services/types.js +7 -0
- package/dist/src/services/types.js.map +1 -0
- package/dist/src/ui/App.js +19 -10
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/colors.js +6 -0
- package/dist/src/ui/colors.js.map +1 -1
- package/dist/src/ui/commands/aboutCommand.js +2 -0
- package/dist/src/ui/commands/aboutCommand.js.map +1 -1
- package/dist/src/ui/commands/authCommand.js +66 -4
- package/dist/src/ui/commands/authCommand.js.map +1 -1
- package/dist/src/ui/commands/baseurlCommand.js +2 -0
- package/dist/src/ui/commands/baseurlCommand.js.map +1 -1
- package/dist/src/ui/commands/bugCommand.js +3 -1
- package/dist/src/ui/commands/bugCommand.js.map +1 -1
- package/dist/src/ui/commands/chatCommand.js +12 -2
- package/dist/src/ui/commands/chatCommand.js.map +1 -1
- package/dist/src/ui/commands/clearCommand.js +2 -0
- package/dist/src/ui/commands/clearCommand.js.map +1 -1
- package/dist/src/ui/commands/compressCommand.js +3 -1
- package/dist/src/ui/commands/compressCommand.js.map +1 -1
- package/dist/src/ui/commands/copyCommand.d.ts +7 -0
- package/dist/src/ui/commands/copyCommand.js +59 -0
- package/dist/src/ui/commands/copyCommand.js.map +1 -0
- package/dist/src/ui/commands/docsCommand.js +2 -0
- package/dist/src/ui/commands/docsCommand.js.map +1 -1
- package/dist/src/ui/commands/editorCommand.js +2 -0
- package/dist/src/ui/commands/editorCommand.js.map +1 -1
- package/dist/src/ui/commands/extensionsCommand.js +2 -0
- package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
- package/dist/src/ui/commands/helpCommand.js +3 -1
- package/dist/src/ui/commands/helpCommand.js.map +1 -1
- package/dist/src/ui/commands/ideCommand.js +21 -23
- package/dist/src/ui/commands/ideCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.js +2 -0
- package/dist/src/ui/commands/keyCommand.js.map +1 -1
- package/dist/src/ui/commands/keyfileCommand.js +2 -0
- package/dist/src/ui/commands/keyfileCommand.js.map +1 -1
- package/dist/src/ui/commands/mcpCommand.js +181 -5
- package/dist/src/ui/commands/mcpCommand.js.map +1 -1
- package/dist/src/ui/commands/memoryCommand.js +11 -4
- package/dist/src/ui/commands/memoryCommand.js.map +1 -1
- package/dist/src/ui/commands/modelCommand.js +2 -0
- package/dist/src/ui/commands/modelCommand.js.map +1 -1
- package/dist/src/ui/commands/privacyCommand.js +2 -0
- package/dist/src/ui/commands/privacyCommand.js.map +1 -1
- package/dist/src/ui/commands/providerCommand.js +2 -0
- package/dist/src/ui/commands/providerCommand.js.map +1 -1
- package/dist/src/ui/commands/quitCommand.js +3 -1
- package/dist/src/ui/commands/quitCommand.js.map +1 -1
- package/dist/src/ui/commands/restoreCommand.js +2 -0
- package/dist/src/ui/commands/restoreCommand.js.map +1 -1
- package/dist/src/ui/commands/statsCommand.js +5 -1
- package/dist/src/ui/commands/statsCommand.js.map +1 -1
- package/dist/src/ui/commands/themeCommand.js +2 -0
- package/dist/src/ui/commands/themeCommand.js.map +1 -1
- package/dist/src/ui/commands/toolformatCommand.d.ts +7 -0
- package/dist/src/ui/commands/toolformatCommand.js +89 -0
- package/dist/src/ui/commands/toolformatCommand.js.map +1 -0
- package/dist/src/ui/commands/toolsCommand.js +2 -0
- package/dist/src/ui/commands/toolsCommand.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +30 -3
- package/dist/src/ui/commands/types.js +5 -1
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/commands/vimCommand.d.ts +7 -0
- package/dist/src/ui/commands/vimCommand.js +30 -0
- package/dist/src/ui/commands/vimCommand.js.map +1 -0
- package/dist/src/ui/components/ContextSummaryDisplay.d.ts +3 -2
- package/dist/src/ui/components/ContextSummaryDisplay.js +10 -10
- package/dist/src/ui/components/ContextSummaryDisplay.js.map +1 -1
- package/dist/src/ui/components/Footer.js +12 -1
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/Help.d.ts +1 -1
- package/dist/src/ui/components/IDEContextDetailDisplay.d.ts +11 -0
- package/dist/src/ui/components/IDEContextDetailDisplay.js +19 -0
- package/dist/src/ui/components/IDEContextDetailDisplay.js.map +1 -0
- package/dist/src/ui/components/InputPrompt.d.ts +1 -1
- package/dist/src/ui/components/InputPrompt.js +9 -99
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/ModelStatsDisplay.js.map +1 -1
- package/dist/src/ui/components/ThemeDialog.js +49 -18
- package/dist/src/ui/components/ThemeDialog.js.map +1 -1
- package/dist/src/ui/components/ToolStatsDisplay.js.map +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.d.ts +1 -0
- package/dist/src/ui/components/messages/DiffRenderer.js +12 -11
- package/dist/src/ui/components/messages/DiffRenderer.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +5 -4
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.d.ts +3 -1
- package/dist/src/ui/components/shared/text-buffer.js +10 -9
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/containers/SessionController.js +42 -31
- package/dist/src/ui/containers/SessionController.js.map +1 -1
- package/dist/src/ui/contexts/VimModeContext.d.ts +19 -0
- package/dist/src/ui/contexts/VimModeContext.js +51 -0
- package/dist/src/ui/contexts/VimModeContext.js.map +1 -0
- package/dist/src/ui/hooks/atCommandProcessor.js +54 -15
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.js +22 -8
- package/dist/src/ui/hooks/shellCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +2 -2
- package/dist/src/ui/hooks/slashCommandProcessor.js +43 -605
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAuthCommand.js +2 -2
- package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
- package/dist/src/ui/hooks/useCompletion.d.ts +3 -1
- package/dist/src/ui/hooks/useCompletion.js +113 -24
- package/dist/src/ui/hooks/useCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +57 -11
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useInputHistory.d.ts +1 -1
- package/dist/src/ui/hooks/usePhraseCycler.js +27 -131
- package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
- package/dist/src/ui/hooks/useShellHistory.d.ts +3 -2
- package/dist/src/ui/hooks/useShellHistory.js.map +1 -1
- package/dist/src/ui/hooks/useThemeCommand.js +22 -2
- package/dist/src/ui/hooks/useThemeCommand.js.map +1 -1
- package/dist/src/ui/privacy/PrivacyNotice.js +16 -2
- package/dist/src/ui/privacy/PrivacyNotice.js.map +1 -1
- package/dist/src/ui/themes/ansi-light.js +2 -0
- package/dist/src/ui/themes/ansi-light.js.map +1 -1
- package/dist/src/ui/themes/ansi.js +2 -0
- package/dist/src/ui/themes/ansi.js.map +1 -1
- package/dist/src/ui/themes/atom-one-dark.js +2 -0
- package/dist/src/ui/themes/atom-one-dark.js.map +1 -1
- package/dist/src/ui/themes/ayu-light.js +3 -1
- package/dist/src/ui/themes/ayu-light.js.map +1 -1
- package/dist/src/ui/themes/ayu.js +3 -1
- package/dist/src/ui/themes/ayu.js.map +1 -1
- package/dist/src/ui/themes/color-utils.d.ts +21 -0
- package/dist/src/ui/themes/color-utils.js +221 -0
- package/dist/src/ui/themes/color-utils.js.map +1 -0
- package/dist/src/ui/themes/dracula.js +2 -0
- package/dist/src/ui/themes/dracula.js.map +1 -1
- package/dist/src/ui/themes/github-dark.js +2 -0
- package/dist/src/ui/themes/github-dark.js.map +1 -1
- package/dist/src/ui/themes/github-light.js +2 -0
- package/dist/src/ui/themes/github-light.js.map +1 -1
- package/dist/src/ui/themes/googlecode.js +2 -0
- package/dist/src/ui/themes/googlecode.js.map +1 -1
- package/dist/src/ui/themes/green-screen.js +2 -0
- package/dist/src/ui/themes/green-screen.js.map +1 -1
- package/dist/src/ui/themes/no-color.js +3 -1
- package/dist/src/ui/themes/no-color.js.map +1 -1
- package/dist/src/ui/themes/shades-of-purple.d.ts +1 -1
- package/dist/src/ui/themes/shades-of-purple.js +3 -1
- package/dist/src/ui/themes/shades-of-purple.js.map +1 -1
- package/dist/src/ui/themes/theme-manager.d.ts +31 -6
- package/dist/src/ui/themes/theme-manager.js +104 -34
- package/dist/src/ui/themes/theme-manager.js.map +1 -1
- package/dist/src/ui/themes/theme.d.ts +22 -3
- package/dist/src/ui/themes/theme.js +229 -182
- package/dist/src/ui/themes/theme.js.map +1 -1
- package/dist/src/ui/themes/xcode.js +2 -0
- package/dist/src/ui/themes/xcode.js.map +1 -1
- package/dist/src/ui/types.d.ts +9 -1
- package/dist/src/ui/utils/CodeColorizer.d.ts +3 -1
- package/dist/src/ui/utils/CodeColorizer.js +23 -11
- package/dist/src/ui/utils/CodeColorizer.js.map +1 -1
- package/dist/src/ui/utils/commandUtils.d.ts +1 -0
- package/dist/src/ui/utils/commandUtils.js +47 -0
- package/dist/src/ui/utils/commandUtils.js.map +1 -1
- package/dist/src/ui/utils/markdownUtilities.js +1 -1
- package/dist/src/utils/sandbox.js +19 -19
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/utils/userStartupWarnings.js +22 -1
- package/dist/src/utils/userStartupWarnings.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.d.ts +7 -0
- package/dist/src/validateNonInterActiveAuth.js +61 -0
- package/dist/src/validateNonInterActiveAuth.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -5
@@ -5,23 +5,17 @@
|
|
5
5
|
*/
|
6
6
|
import { useCallback, useMemo, useEffect, useState } from 'react';
|
7
7
|
import process from 'node:process';
|
8
|
-
import { ansi } from '../colors.js';
|
9
8
|
import { useStateAndRef } from './useStateAndRef.js';
|
10
|
-
import { GitService, Logger
|
9
|
+
import { GitService, Logger } from '@vybestack/llxprt-code-core';
|
11
10
|
import { useSessionStats } from '../contexts/SessionContext.js';
|
12
11
|
import { MessageType, } from '../types.js';
|
13
|
-
import { promises as fs } from 'fs';
|
14
|
-
import path from 'path';
|
15
|
-
import { GIT_COMMIT_INFO } from '../../generated/git-commit.js';
|
16
|
-
import { formatDuration, formatMemoryUsage } from '../utils/formatters.js';
|
17
|
-
import { getCliVersion } from '../../utils/version.js';
|
18
12
|
import { CommandService } from '../../services/CommandService.js';
|
19
|
-
import {
|
20
|
-
import
|
13
|
+
import { BuiltinCommandLoader } from '../../services/BuiltinCommandLoader.js';
|
14
|
+
import { FileCommandLoader } from '../../services/FileCommandLoader.js';
|
21
15
|
/**
|
22
16
|
* Hook to define and process slash commands (e.g., /help, /clear).
|
23
17
|
*/
|
24
|
-
export const useSlashCommandProcessor = (config, settings, addItem, clearItems, loadHistory, refreshStatic, setShowHelp, onDebugMessage, openThemeDialog, openAuthDialog, openEditorDialog, openProviderDialog, openProviderModelDialog, performMemoryRefresh, setQuittingMessages, openPrivacyNotice, checkPaymentModeChange, showToolDescriptions) => {
|
18
|
+
export const useSlashCommandProcessor = (config, settings, addItem, clearItems, loadHistory, refreshStatic, setShowHelp, onDebugMessage, openThemeDialog, openAuthDialog, openEditorDialog, openProviderDialog, openProviderModelDialog, performMemoryRefresh, setQuittingMessages, openPrivacyNotice, checkPaymentModeChange, showToolDescriptions, toggleVimEnabled) => {
|
25
19
|
const session = useSessionStats();
|
26
20
|
const [commands, setCommands] = useState([]);
|
27
21
|
const gitService = useMemo(() => {
|
@@ -96,10 +90,6 @@ export const useSlashCommandProcessor = (config, settings, addItem, clearItems,
|
|
96
90
|
}
|
97
91
|
addItem(historyItemContent, message.timestamp.getTime());
|
98
92
|
}, [addItem]);
|
99
|
-
// const showMemoryAction = useMemo(
|
100
|
-
// () => createShowMemoryAction(config, settings, addMessage),
|
101
|
-
// [config, settings, addMessage],
|
102
|
-
// );
|
103
93
|
const commandContext = useMemo(() => ({
|
104
94
|
services: {
|
105
95
|
config,
|
@@ -118,6 +108,7 @@ export const useSlashCommandProcessor = (config, settings, addItem, clearItems,
|
|
118
108
|
setDebugMessage: onDebugMessage,
|
119
109
|
pendingItem: pendingCompressionItemRef.current,
|
120
110
|
setPendingItem: setPendingCompressionItem,
|
111
|
+
toggleVimEnabled,
|
121
112
|
},
|
122
113
|
session: {
|
123
114
|
stats: session.stats,
|
@@ -135,597 +126,23 @@ export const useSlashCommandProcessor = (config, settings, addItem, clearItems,
|
|
135
126
|
onDebugMessage,
|
136
127
|
pendingCompressionItemRef,
|
137
128
|
setPendingCompressionItem,
|
129
|
+
toggleVimEnabled,
|
138
130
|
]);
|
139
|
-
const commandService = useMemo(() => new CommandService(config), [config]);
|
140
131
|
useEffect(() => {
|
132
|
+
const controller = new AbortController();
|
141
133
|
const load = async () => {
|
142
|
-
|
134
|
+
const loaders = [
|
135
|
+
new BuiltinCommandLoader(config),
|
136
|
+
new FileCommandLoader(config),
|
137
|
+
];
|
138
|
+
const commandService = await CommandService.create(loaders, controller.signal);
|
143
139
|
setCommands(commandService.getCommands());
|
144
140
|
};
|
145
141
|
load();
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
if (!geminiDir) {
|
150
|
-
return [];
|
151
|
-
}
|
152
|
-
try {
|
153
|
-
const files = await fs.readdir(geminiDir);
|
154
|
-
return files
|
155
|
-
.filter((file) => file.startsWith('checkpoint-') && file.endsWith('.json'))
|
156
|
-
.map((file) => file.replace('checkpoint-', '').replace('.json', ''));
|
157
|
-
}
|
158
|
-
catch (_err) {
|
159
|
-
return [];
|
160
|
-
}
|
142
|
+
return () => {
|
143
|
+
controller.abort();
|
144
|
+
};
|
161
145
|
}, [config]);
|
162
|
-
// Define legacy commands
|
163
|
-
// This list contains all commands that have NOT YET been migrated to the
|
164
|
-
// new system. As commands are migrated, they are removed from this list.
|
165
|
-
const _legacyCommands = useMemo(() => {
|
166
|
-
const commands = [
|
167
|
-
// `/help` and `/clear` have been migrated and REMOVED from this list.
|
168
|
-
{
|
169
|
-
name: 'docs',
|
170
|
-
description: 'open full LLxprt Code documentation in your browser',
|
171
|
-
action: async (_context, _args) => {
|
172
|
-
const docsUrl = 'https://goo.gle/gemini-cli-docs';
|
173
|
-
if (process.env.SANDBOX && process.env.SANDBOX !== 'sandbox-exec') {
|
174
|
-
addMessage({
|
175
|
-
type: MessageType.INFO,
|
176
|
-
content: `Please open the following URL in your browser to view the documentation:\n${docsUrl}`,
|
177
|
-
timestamp: new Date(),
|
178
|
-
});
|
179
|
-
}
|
180
|
-
else {
|
181
|
-
addMessage({
|
182
|
-
type: MessageType.INFO,
|
183
|
-
content: `Opening documentation in your browser: ${docsUrl}`,
|
184
|
-
timestamp: new Date(),
|
185
|
-
});
|
186
|
-
await open(docsUrl);
|
187
|
-
}
|
188
|
-
},
|
189
|
-
},
|
190
|
-
{
|
191
|
-
name: 'auth',
|
192
|
-
description: 'change the auth method',
|
193
|
-
action: async (_context, args) => {
|
194
|
-
const authMode = args?.split(' ')[0];
|
195
|
-
const providerManager = getProviderManager();
|
196
|
-
// If no auth mode specified, open the dialog
|
197
|
-
if (!authMode) {
|
198
|
-
openAuthDialog();
|
199
|
-
return;
|
200
|
-
}
|
201
|
-
// Handle specific auth mode changes for Gemini provider
|
202
|
-
try {
|
203
|
-
const activeProvider = providerManager.getActiveProvider();
|
204
|
-
// Check if this is the Gemini provider
|
205
|
-
if (activeProvider.name === 'gemini' && config) {
|
206
|
-
const validModes = ['oauth', 'api-key', 'vertex'];
|
207
|
-
if (!validModes.includes(authMode)) {
|
208
|
-
addMessage({
|
209
|
-
type: MessageType.ERROR,
|
210
|
-
content: `Invalid auth mode. Valid modes: ${validModes.join(', ')}`,
|
211
|
-
timestamp: new Date(),
|
212
|
-
});
|
213
|
-
return;
|
214
|
-
}
|
215
|
-
// Map the auth mode to the appropriate AuthType
|
216
|
-
let authType;
|
217
|
-
switch (authMode) {
|
218
|
-
case 'oauth':
|
219
|
-
authType = AuthType.LOGIN_WITH_GOOGLE;
|
220
|
-
break;
|
221
|
-
case 'api-key':
|
222
|
-
authType = AuthType.USE_GEMINI;
|
223
|
-
break;
|
224
|
-
case 'vertex':
|
225
|
-
authType = AuthType.USE_VERTEX_AI;
|
226
|
-
break;
|
227
|
-
default:
|
228
|
-
authType = AuthType.LOGIN_WITH_GOOGLE;
|
229
|
-
}
|
230
|
-
// Refresh auth with the new type
|
231
|
-
await config.refreshAuth(authType);
|
232
|
-
addMessage({
|
233
|
-
type: MessageType.INFO,
|
234
|
-
content: `Switched to ${authMode} authentication mode`,
|
235
|
-
timestamp: new Date(),
|
236
|
-
});
|
237
|
-
}
|
238
|
-
else {
|
239
|
-
addMessage({
|
240
|
-
type: MessageType.ERROR,
|
241
|
-
content: 'Auth mode switching is only supported for the Gemini provider',
|
242
|
-
timestamp: new Date(),
|
243
|
-
});
|
244
|
-
}
|
245
|
-
}
|
246
|
-
catch (error) {
|
247
|
-
addMessage({
|
248
|
-
type: MessageType.ERROR,
|
249
|
-
content: `Failed to switch auth mode: ${error instanceof Error ? error.message : String(error)}`,
|
250
|
-
timestamp: new Date(),
|
251
|
-
});
|
252
|
-
}
|
253
|
-
},
|
254
|
-
},
|
255
|
-
{
|
256
|
-
name: 'editor',
|
257
|
-
description: 'set external editor preference',
|
258
|
-
action: (_context, _args) => ({
|
259
|
-
type: 'dialog',
|
260
|
-
dialog: 'editor',
|
261
|
-
}),
|
262
|
-
},
|
263
|
-
{
|
264
|
-
name: 'stats',
|
265
|
-
altName: 'usage',
|
266
|
-
description: 'check session stats. Usage: /stats [model|tools]',
|
267
|
-
action: (_context, args) => {
|
268
|
-
const subCommand = args?.split(' ')[0];
|
269
|
-
if (subCommand === 'model') {
|
270
|
-
addMessage({
|
271
|
-
type: MessageType.MODEL_STATS,
|
272
|
-
timestamp: new Date(),
|
273
|
-
});
|
274
|
-
return;
|
275
|
-
}
|
276
|
-
else if (subCommand === 'tools') {
|
277
|
-
addMessage({
|
278
|
-
type: MessageType.TOOL_STATS,
|
279
|
-
timestamp: new Date(),
|
280
|
-
});
|
281
|
-
return;
|
282
|
-
}
|
283
|
-
const now = new Date();
|
284
|
-
const { sessionStartTime } = session.stats;
|
285
|
-
const wallDuration = now.getTime() - sessionStartTime.getTime();
|
286
|
-
addMessage({
|
287
|
-
type: MessageType.STATS,
|
288
|
-
duration: formatDuration(wallDuration),
|
289
|
-
timestamp: new Date(),
|
290
|
-
});
|
291
|
-
},
|
292
|
-
},
|
293
|
-
{
|
294
|
-
name: 'mcp',
|
295
|
-
description: 'list configured MCP servers and tools',
|
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(' ');
|
300
|
-
let useShowDescriptions = showToolDescriptions;
|
301
|
-
if (subCommand === 'desc' || subCommand === 'descriptions') {
|
302
|
-
useShowDescriptions = true;
|
303
|
-
}
|
304
|
-
else if (subCommand === 'nodesc' ||
|
305
|
-
subCommand === 'nodescriptions') {
|
306
|
-
useShowDescriptions = false;
|
307
|
-
}
|
308
|
-
else if (remainingArgs === 'desc' ||
|
309
|
-
remainingArgs === 'descriptions') {
|
310
|
-
useShowDescriptions = true;
|
311
|
-
}
|
312
|
-
else if (remainingArgs === 'nodesc' ||
|
313
|
-
remainingArgs === 'nodescriptions') {
|
314
|
-
useShowDescriptions = false;
|
315
|
-
}
|
316
|
-
// Check if the args includes a specific flag to show detailed tool schema
|
317
|
-
let useShowSchema = false;
|
318
|
-
if (subCommand === 'schema' || remainingArgs === 'schema') {
|
319
|
-
useShowSchema = true;
|
320
|
-
}
|
321
|
-
const toolRegistry = await config?.getToolRegistry();
|
322
|
-
if (!toolRegistry) {
|
323
|
-
addMessage({
|
324
|
-
type: MessageType.ERROR,
|
325
|
-
content: 'Could not retrieve tool registry.',
|
326
|
-
timestamp: new Date(),
|
327
|
-
});
|
328
|
-
return;
|
329
|
-
}
|
330
|
-
const mcpServers = config?.getMcpServers() || {};
|
331
|
-
const serverNames = Object.keys(mcpServers);
|
332
|
-
if (serverNames.length === 0) {
|
333
|
-
const docsUrl = 'https://goo.gle/gemini-cli-docs-mcp';
|
334
|
-
if (process.env.SANDBOX && process.env.SANDBOX !== 'sandbox-exec') {
|
335
|
-
addMessage({
|
336
|
-
type: MessageType.INFO,
|
337
|
-
content: `No MCP servers configured. Please open the following URL in your browser to view documentation:\n${docsUrl}`,
|
338
|
-
timestamp: new Date(),
|
339
|
-
});
|
340
|
-
}
|
341
|
-
else {
|
342
|
-
addMessage({
|
343
|
-
type: MessageType.INFO,
|
344
|
-
content: `No MCP servers configured. Opening documentation in your browser: ${docsUrl}`,
|
345
|
-
timestamp: new Date(),
|
346
|
-
});
|
347
|
-
await open(docsUrl);
|
348
|
-
}
|
349
|
-
return;
|
350
|
-
}
|
351
|
-
// Check if any servers are still connecting
|
352
|
-
const connectingServers = serverNames.filter((name) => getMCPServerStatus(name) === MCPServerStatus.CONNECTING);
|
353
|
-
const discoveryState = getMCPDiscoveryState();
|
354
|
-
let message = '';
|
355
|
-
// Add overall discovery status message if needed
|
356
|
-
if (discoveryState === MCPDiscoveryState.IN_PROGRESS ||
|
357
|
-
connectingServers.length > 0) {
|
358
|
-
message +=
|
359
|
-
ansi.accentYellow(`⏳ MCP servers are starting up (${connectingServers.length} initializing)...`) + '\n';
|
360
|
-
message +=
|
361
|
-
ansi.gray('Note: First startup may take longer. Tool availability will update automatically.') + '\n\n';
|
362
|
-
}
|
363
|
-
message += 'Configured MCP servers:\n\n';
|
364
|
-
for (const serverName of serverNames) {
|
365
|
-
const serverTools = toolRegistry.getToolsByServer(serverName);
|
366
|
-
const status = getMCPServerStatus(serverName);
|
367
|
-
// Add status indicator with descriptive text
|
368
|
-
let statusIndicator = '';
|
369
|
-
let statusText = '';
|
370
|
-
switch (status) {
|
371
|
-
case MCPServerStatus.CONNECTED:
|
372
|
-
statusIndicator = '🟢';
|
373
|
-
statusText = 'Ready';
|
374
|
-
break;
|
375
|
-
case MCPServerStatus.CONNECTING:
|
376
|
-
statusIndicator = '🔄';
|
377
|
-
statusText = 'Starting... (first startup may take longer)';
|
378
|
-
break;
|
379
|
-
case MCPServerStatus.DISCONNECTED:
|
380
|
-
default:
|
381
|
-
statusIndicator = '🔴';
|
382
|
-
statusText = 'Disconnected';
|
383
|
-
break;
|
384
|
-
}
|
385
|
-
// Get server description if available
|
386
|
-
const server = mcpServers[serverName];
|
387
|
-
// Format server header with bold formatting and status
|
388
|
-
message += `${statusIndicator} ${ansi.bold(serverName)} - ${statusText}`;
|
389
|
-
// Add tool count with conditional messaging
|
390
|
-
if (status === MCPServerStatus.CONNECTED) {
|
391
|
-
message += ` (${serverTools.length} tools)`;
|
392
|
-
}
|
393
|
-
else if (status === MCPServerStatus.CONNECTING) {
|
394
|
-
message += ` (tools will appear when ready)`;
|
395
|
-
}
|
396
|
-
else {
|
397
|
-
message += ` (${serverTools.length} tools cached)`;
|
398
|
-
}
|
399
|
-
// Add server description with proper handling of multi-line descriptions
|
400
|
-
if ((useShowDescriptions || useShowSchema) && server?.description) {
|
401
|
-
const descLines = server.description.trim().split('\n');
|
402
|
-
if (descLines) {
|
403
|
-
message += ':\n';
|
404
|
-
for (const descLine of descLines) {
|
405
|
-
message += ` ${ansi.accentGreen(descLine)}\n`;
|
406
|
-
}
|
407
|
-
}
|
408
|
-
else {
|
409
|
-
message += '\n';
|
410
|
-
}
|
411
|
-
}
|
412
|
-
else {
|
413
|
-
message += '\n';
|
414
|
-
}
|
415
|
-
if (serverTools.length > 0) {
|
416
|
-
serverTools.forEach((tool) => {
|
417
|
-
if ((useShowDescriptions || useShowSchema) &&
|
418
|
-
tool.description) {
|
419
|
-
// Format tool name in cyan using simple ANSI cyan color
|
420
|
-
message += ` - ${ansi.accentCyan(tool.name)}`;
|
421
|
-
// Handle multi-line descriptions by properly indenting and preserving formatting
|
422
|
-
const descLines = tool.description.trim().split('\n');
|
423
|
-
if (descLines) {
|
424
|
-
message += ':\n';
|
425
|
-
for (const descLine of descLines) {
|
426
|
-
message += ` ${ansi.accentGreen(descLine)}\n`;
|
427
|
-
}
|
428
|
-
}
|
429
|
-
else {
|
430
|
-
message += '\n';
|
431
|
-
}
|
432
|
-
}
|
433
|
-
else {
|
434
|
-
// Use cyan color for the tool name even when not showing descriptions
|
435
|
-
message += ` - ${ansi.accentCyan(tool.name)}\n`;
|
436
|
-
}
|
437
|
-
if (useShowSchema) {
|
438
|
-
// Prefix the parameters in cyan
|
439
|
-
message += ` ${ansi.accentCyan('Parameters')}:\n`;
|
440
|
-
const paramsLines = JSON.stringify(tool.schema.parameters, null, 2)
|
441
|
-
.trim()
|
442
|
-
.split('\n');
|
443
|
-
if (paramsLines) {
|
444
|
-
for (const paramsLine of paramsLines) {
|
445
|
-
message += ` ${ansi.accentGreen(paramsLine)}\n`;
|
446
|
-
}
|
447
|
-
}
|
448
|
-
}
|
449
|
-
});
|
450
|
-
}
|
451
|
-
else {
|
452
|
-
message += ' No tools available\n';
|
453
|
-
}
|
454
|
-
message += '\n';
|
455
|
-
}
|
456
|
-
addMessage({
|
457
|
-
type: MessageType.INFO,
|
458
|
-
content: message,
|
459
|
-
timestamp: new Date(),
|
460
|
-
});
|
461
|
-
},
|
462
|
-
},
|
463
|
-
{
|
464
|
-
name: 'extensions',
|
465
|
-
description: 'list active extensions',
|
466
|
-
action: async () => {
|
467
|
-
const activeExtensions = config?.getActiveExtensions();
|
468
|
-
if (!activeExtensions || activeExtensions.length === 0) {
|
469
|
-
addMessage({
|
470
|
-
type: MessageType.INFO,
|
471
|
-
content: 'No active extensions.',
|
472
|
-
timestamp: new Date(),
|
473
|
-
});
|
474
|
-
return;
|
475
|
-
}
|
476
|
-
let message = 'Active extensions:\n\n';
|
477
|
-
for (const ext of activeExtensions) {
|
478
|
-
message += ` - \u001b[36m${ext.name} (v${ext.version})\u001b[0m\n`;
|
479
|
-
}
|
480
|
-
// Make sure to reset any ANSI formatting at the end to prevent it from affecting the terminal
|
481
|
-
message += '\u001b[0m';
|
482
|
-
addMessage({
|
483
|
-
type: MessageType.INFO,
|
484
|
-
content: message,
|
485
|
-
timestamp: new Date(),
|
486
|
-
});
|
487
|
-
},
|
488
|
-
},
|
489
|
-
{
|
490
|
-
name: 'tools',
|
491
|
-
description: 'list available LLxprt Code tools',
|
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(' ');
|
496
|
-
let useShowDescriptions = showToolDescriptions;
|
497
|
-
if (subCommand === 'desc' || subCommand === 'descriptions') {
|
498
|
-
useShowDescriptions = true;
|
499
|
-
}
|
500
|
-
else if (subCommand === 'nodesc' ||
|
501
|
-
subCommand === 'nodescriptions') {
|
502
|
-
useShowDescriptions = false;
|
503
|
-
}
|
504
|
-
else if (remainingArgs === 'desc' ||
|
505
|
-
remainingArgs === 'descriptions') {
|
506
|
-
useShowDescriptions = true;
|
507
|
-
}
|
508
|
-
else if (remainingArgs === 'nodesc' ||
|
509
|
-
remainingArgs === 'nodescriptions') {
|
510
|
-
useShowDescriptions = false;
|
511
|
-
}
|
512
|
-
const toolRegistry = await config?.getToolRegistry();
|
513
|
-
const tools = toolRegistry?.getAllTools();
|
514
|
-
if (!tools) {
|
515
|
-
addMessage({
|
516
|
-
type: MessageType.ERROR,
|
517
|
-
content: 'Could not retrieve tools.',
|
518
|
-
timestamp: new Date(),
|
519
|
-
});
|
520
|
-
return;
|
521
|
-
}
|
522
|
-
// Filter out MCP tools by checking if they have a serverName property
|
523
|
-
const geminiTools = tools.filter((tool) => !('serverName' in tool));
|
524
|
-
let message = 'Available Gemini CLI tools:\n\n';
|
525
|
-
if (geminiTools.length > 0) {
|
526
|
-
geminiTools.forEach((tool) => {
|
527
|
-
if (useShowDescriptions && tool.description) {
|
528
|
-
// Format tool name in cyan using simple ANSI cyan color
|
529
|
-
message += ` - ${ansi.accentCyan(`${tool.displayName} (${tool.name})`)}:\n`;
|
530
|
-
// Handle multi-line descriptions by properly indenting and preserving formatting
|
531
|
-
const descLines = tool.description.trim().split('\n');
|
532
|
-
// If there are multiple lines, add proper indentation for each line
|
533
|
-
if (descLines) {
|
534
|
-
for (const descLine of descLines) {
|
535
|
-
message += ` ${ansi.accentGreen(descLine)}\n`;
|
536
|
-
}
|
537
|
-
}
|
538
|
-
}
|
539
|
-
else {
|
540
|
-
// Use cyan color for the tool name even when not showing descriptions
|
541
|
-
message += ` - ${ansi.accentCyan(tool.displayName)}\n`;
|
542
|
-
}
|
543
|
-
});
|
544
|
-
}
|
545
|
-
else {
|
546
|
-
message += ' No tools available\n';
|
547
|
-
}
|
548
|
-
message += '\n';
|
549
|
-
addMessage({
|
550
|
-
type: MessageType.INFO,
|
551
|
-
content: message,
|
552
|
-
timestamp: new Date(),
|
553
|
-
});
|
554
|
-
},
|
555
|
-
},
|
556
|
-
{
|
557
|
-
name: 'bug',
|
558
|
-
description: 'submit a bug report',
|
559
|
-
action: async (_context, args) => {
|
560
|
-
const bugDescription = args?.trim() || '';
|
561
|
-
const osVersion = `${process.platform} ${process.version}`;
|
562
|
-
let sandboxEnv = 'no sandbox';
|
563
|
-
if (process.env.SANDBOX && process.env.SANDBOX !== 'sandbox-exec') {
|
564
|
-
sandboxEnv = process.env.SANDBOX.replace(/^gemini-(?:code-)?/, '');
|
565
|
-
}
|
566
|
-
else if (process.env.SANDBOX === 'sandbox-exec') {
|
567
|
-
sandboxEnv = `sandbox-exec (${process.env.SEATBELT_PROFILE || 'unknown'})`;
|
568
|
-
}
|
569
|
-
const modelVersion = config?.getModel() || 'Unknown';
|
570
|
-
const cliVersion = await getCliVersion();
|
571
|
-
const memoryUsage = formatMemoryUsage(process.memoryUsage().rss);
|
572
|
-
const info = `
|
573
|
-
* **CLI Version:** ${cliVersion}
|
574
|
-
* **Git Commit:** ${GIT_COMMIT_INFO}
|
575
|
-
* **Operating System:** ${osVersion}
|
576
|
-
* **Sandbox Environment:** ${sandboxEnv}
|
577
|
-
* **Model Version:** ${modelVersion}
|
578
|
-
* **Memory Usage:** ${memoryUsage}
|
579
|
-
`;
|
580
|
-
let bugReportUrl = 'https://github.com/acoliver/llxprt-code/issues/new?template=bug_report.yml&title={title}&info={info}';
|
581
|
-
const bugCommand = config?.getBugCommand();
|
582
|
-
if (bugCommand?.urlTemplate) {
|
583
|
-
bugReportUrl = bugCommand.urlTemplate;
|
584
|
-
}
|
585
|
-
bugReportUrl = bugReportUrl
|
586
|
-
.replace('{title}', encodeURIComponent(bugDescription))
|
587
|
-
.replace('{info}', encodeURIComponent(info));
|
588
|
-
addMessage({
|
589
|
-
type: MessageType.INFO,
|
590
|
-
content: `To submit your bug report, please open the following URL in your browser:\n${bugReportUrl}`,
|
591
|
-
timestamp: new Date(),
|
592
|
-
});
|
593
|
-
(async () => {
|
594
|
-
try {
|
595
|
-
await open(bugReportUrl);
|
596
|
-
}
|
597
|
-
catch (error) {
|
598
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
599
|
-
addMessage({
|
600
|
-
type: MessageType.ERROR,
|
601
|
-
content: `Could not open URL in browser: ${errorMessage}`,
|
602
|
-
timestamp: new Date(),
|
603
|
-
});
|
604
|
-
}
|
605
|
-
})();
|
606
|
-
},
|
607
|
-
},
|
608
|
-
];
|
609
|
-
if (config?.getCheckpointingEnabled()) {
|
610
|
-
commands.push({
|
611
|
-
name: 'restore',
|
612
|
-
description: 'restore a tool call. This will reset the conversation and file history to the state it was in when the tool call was suggested',
|
613
|
-
completion: async () => {
|
614
|
-
const checkpointDir = config?.getProjectTempDir()
|
615
|
-
? path.join(config.getProjectTempDir(), 'checkpoints')
|
616
|
-
: undefined;
|
617
|
-
if (!checkpointDir) {
|
618
|
-
return [];
|
619
|
-
}
|
620
|
-
try {
|
621
|
-
const files = await fs.readdir(checkpointDir);
|
622
|
-
return files
|
623
|
-
.filter((file) => file.endsWith('.json'))
|
624
|
-
.map((file) => file.replace('.json', ''));
|
625
|
-
}
|
626
|
-
catch (_err) {
|
627
|
-
return [];
|
628
|
-
}
|
629
|
-
},
|
630
|
-
action: async (_context, args) => {
|
631
|
-
const subCommand = args?.split(' ')[0];
|
632
|
-
const checkpointDir = config?.getProjectTempDir()
|
633
|
-
? path.join(config.getProjectTempDir(), 'checkpoints')
|
634
|
-
: undefined;
|
635
|
-
if (!checkpointDir) {
|
636
|
-
addMessage({
|
637
|
-
type: MessageType.ERROR,
|
638
|
-
content: 'Could not determine the .llxprt directory path.',
|
639
|
-
timestamp: new Date(),
|
640
|
-
});
|
641
|
-
return;
|
642
|
-
}
|
643
|
-
try {
|
644
|
-
// Ensure the directory exists before trying to read it.
|
645
|
-
await fs.mkdir(checkpointDir, { recursive: true });
|
646
|
-
const files = await fs.readdir(checkpointDir);
|
647
|
-
const jsonFiles = files.filter((file) => file.endsWith('.json'));
|
648
|
-
if (!subCommand) {
|
649
|
-
if (jsonFiles.length === 0) {
|
650
|
-
addMessage({
|
651
|
-
type: MessageType.INFO,
|
652
|
-
content: 'No restorable tool calls found.',
|
653
|
-
timestamp: new Date(),
|
654
|
-
});
|
655
|
-
return;
|
656
|
-
}
|
657
|
-
const truncatedFiles = jsonFiles.map((file) => {
|
658
|
-
const components = file.split('.');
|
659
|
-
if (components.length <= 1) {
|
660
|
-
return file;
|
661
|
-
}
|
662
|
-
components.pop();
|
663
|
-
return components.join('.');
|
664
|
-
});
|
665
|
-
const fileList = truncatedFiles.join('\n');
|
666
|
-
addMessage({
|
667
|
-
type: MessageType.INFO,
|
668
|
-
content: `Available tool calls to restore:\n\n${fileList}`,
|
669
|
-
timestamp: new Date(),
|
670
|
-
});
|
671
|
-
return;
|
672
|
-
}
|
673
|
-
const selectedFile = subCommand.endsWith('.json')
|
674
|
-
? subCommand
|
675
|
-
: `${subCommand}.json`;
|
676
|
-
if (!jsonFiles.includes(selectedFile)) {
|
677
|
-
addMessage({
|
678
|
-
type: MessageType.ERROR,
|
679
|
-
content: `File not found: ${selectedFile}`,
|
680
|
-
timestamp: new Date(),
|
681
|
-
});
|
682
|
-
return;
|
683
|
-
}
|
684
|
-
const filePath = path.join(checkpointDir, selectedFile);
|
685
|
-
const data = await fs.readFile(filePath, 'utf-8');
|
686
|
-
const toolCallData = JSON.parse(data);
|
687
|
-
if (toolCallData.history) {
|
688
|
-
loadHistory(toolCallData.history);
|
689
|
-
}
|
690
|
-
if (toolCallData.clientHistory) {
|
691
|
-
await config
|
692
|
-
?.getGeminiClient()
|
693
|
-
?.setHistory(toolCallData.clientHistory);
|
694
|
-
}
|
695
|
-
if (toolCallData.commitHash) {
|
696
|
-
await gitService?.restoreProjectFromSnapshot(toolCallData.commitHash);
|
697
|
-
addMessage({
|
698
|
-
type: MessageType.INFO,
|
699
|
-
content: `Restored project to the state before the tool call.`,
|
700
|
-
timestamp: new Date(),
|
701
|
-
});
|
702
|
-
}
|
703
|
-
return {
|
704
|
-
type: 'tool',
|
705
|
-
toolName: toolCallData.toolCall.name,
|
706
|
-
toolArgs: toolCallData.toolCall.args,
|
707
|
-
};
|
708
|
-
}
|
709
|
-
catch (error) {
|
710
|
-
addMessage({
|
711
|
-
type: MessageType.ERROR,
|
712
|
-
content: `Could not read restorable tool calls. This is the error: ${error}`,
|
713
|
-
timestamp: new Date(),
|
714
|
-
});
|
715
|
-
}
|
716
|
-
},
|
717
|
-
});
|
718
|
-
}
|
719
|
-
return commands;
|
720
|
-
}, [
|
721
|
-
addMessage,
|
722
|
-
openAuthDialog,
|
723
|
-
config,
|
724
|
-
session,
|
725
|
-
gitService,
|
726
|
-
loadHistory,
|
727
|
-
showToolDescriptions,
|
728
|
-
]);
|
729
146
|
const handleSlashCommand = useCallback(async (rawQuery) => {
|
730
147
|
if (typeof rawQuery !== 'string') {
|
731
148
|
return false;
|
@@ -735,16 +152,24 @@ export const useSlashCommandProcessor = (config, settings, addItem, clearItems,
|
|
735
152
|
return false;
|
736
153
|
}
|
737
154
|
const userMessageTimestamp = Date.now();
|
738
|
-
|
739
|
-
addItem({ type: MessageType.USER, text: trimmed }, userMessageTimestamp);
|
740
|
-
}
|
155
|
+
addItem({ type: MessageType.USER, text: trimmed }, userMessageTimestamp);
|
741
156
|
const parts = trimmed.substring(1).trim().split(/\s+/);
|
742
157
|
const commandPath = parts.filter((p) => p); // The parts of the command, e.g., ['memory', 'add']
|
743
158
|
let currentCommands = commands;
|
744
159
|
let commandToExecute;
|
745
160
|
let pathIndex = 0;
|
746
161
|
for (const part of commandPath) {
|
747
|
-
|
162
|
+
// TODO: For better performance and architectural clarity, this two-pass
|
163
|
+
// search could be replaced. A more optimal approach would be to
|
164
|
+
// pre-compute a single lookup map in `CommandService.ts` that resolves
|
165
|
+
// all name and alias conflicts during the initial loading phase. The
|
166
|
+
// processor would then perform a single, fast lookup on that map.
|
167
|
+
// First pass: check for an exact match on the primary command name.
|
168
|
+
let foundCommand = currentCommands.find((cmd) => cmd.name === part);
|
169
|
+
// Second pass: if no primary name matches, check for an alias.
|
170
|
+
if (!foundCommand) {
|
171
|
+
foundCommand = currentCommands.find((cmd) => cmd.altNames?.includes(part));
|
172
|
+
}
|
748
173
|
if (foundCommand) {
|
749
174
|
commandToExecute = foundCommand;
|
750
175
|
pathIndex++;
|
@@ -762,7 +187,15 @@ export const useSlashCommandProcessor = (config, settings, addItem, clearItems,
|
|
762
187
|
if (commandToExecute) {
|
763
188
|
const args = parts.slice(pathIndex).join(' ');
|
764
189
|
if (commandToExecute.action) {
|
765
|
-
const
|
190
|
+
const fullCommandContext = {
|
191
|
+
...commandContext,
|
192
|
+
invocation: {
|
193
|
+
raw: trimmed,
|
194
|
+
name: commandToExecute.name,
|
195
|
+
args,
|
196
|
+
},
|
197
|
+
};
|
198
|
+
const result = await commandToExecute.action(fullCommandContext, args);
|
766
199
|
if (result) {
|
767
200
|
switch (result.type) {
|
768
201
|
case 'tool':
|
@@ -811,9 +244,9 @@ export const useSlashCommandProcessor = (config, settings, addItem, clearItems,
|
|
811
244
|
await config
|
812
245
|
?.getGeminiClient()
|
813
246
|
?.setHistory(result.clientHistory);
|
814
|
-
|
247
|
+
fullCommandContext.ui.clear();
|
815
248
|
result.history.forEach((item, index) => {
|
816
|
-
|
249
|
+
fullCommandContext.ui.addItem(item, index);
|
817
250
|
});
|
818
251
|
return { type: 'handled' };
|
819
252
|
}
|
@@ -823,6 +256,11 @@ export const useSlashCommandProcessor = (config, settings, addItem, clearItems,
|
|
823
256
|
process.exit(0);
|
824
257
|
}, 100);
|
825
258
|
return { type: 'handled' };
|
259
|
+
case 'submit_prompt':
|
260
|
+
return {
|
261
|
+
type: 'submit_prompt',
|
262
|
+
content: result.content,
|
263
|
+
};
|
826
264
|
default: {
|
827
265
|
const unhandled = result;
|
828
266
|
throw new Error(`Unhandled slash command result: ${unhandled}`);
|