@qwen-code/qwen-code 0.0.7-nightly.0 → 0.0.7
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/dist/package.json +4 -3
- package/dist/qwen-code-qwen-code-0.0.6.tgz +0 -0
- package/dist/src/config/config.d.ts +3 -1
- package/dist/src/config/config.js +27 -9
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/settings.d.ts +3 -0
- package/dist/src/config/settings.js +6 -2
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +1 -1
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/nonInteractiveCli.js +21 -12
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/ui/App.js +6 -4
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/commands/directoryCommand.js +21 -1
- package/dist/src/ui/commands/directoryCommand.js.map +1 -1
- package/dist/src/ui/commands/ideCommand.js +48 -31
- package/dist/src/ui/commands/ideCommand.js.map +1 -1
- package/dist/src/ui/commands/memoryCommand.js +3 -1
- package/dist/src/ui/commands/memoryCommand.js.map +1 -1
- package/dist/src/ui/commands/setupGithubCommand.js +1 -1
- package/dist/src/ui/commands/setupGithubCommand.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +1 -0
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/components/QwenOAuthProgress.js +49 -38
- package/dist/src/ui/components/QwenOAuthProgress.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js +3 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAtCompletion.d.ts +23 -0
- package/dist/src/ui/hooks/useAtCompletion.js +177 -0
- package/dist/src/ui/hooks/useAtCompletion.js.map +1 -0
- package/dist/src/ui/hooks/useCommandCompletion.d.ts +6 -1
- package/dist/src/ui/hooks/useCommandCompletion.js +95 -383
- package/dist/src/ui/hooks/useCommandCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.d.ts +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +12 -2
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/usePhraseCycler.js +0 -3
- package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.d.ts +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js +3 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
- package/dist/src/ui/hooks/useReverseSearchCompletion.js +4 -2
- package/dist/src/ui/hooks/useReverseSearchCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.d.ts +20 -0
- package/dist/src/ui/hooks/useSlashCompletion.js +135 -0
- package/dist/src/ui/hooks/useSlashCompletion.js.map +1 -0
- package/dist/src/ui/hooks/vim.js +13 -4
- package/dist/src/ui/hooks/vim.js.map +1 -1
- package/dist/src/ui/utils/ConsolePatcher.d.ts +2 -1
- package/dist/src/ui/utils/ConsolePatcher.js +15 -8
- package/dist/src/ui/utils/ConsolePatcher.js.map +1 -1
- package/dist/src/utils/resolvePath.d.ts +6 -0
- package/dist/src/utils/resolvePath.js +21 -0
- package/dist/src/utils/resolvePath.js.map +1 -0
- package/dist/src/utils/sandbox.js +4 -0
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -3
|
@@ -3,438 +3,150 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import * as fs from 'fs/promises';
|
|
8
|
-
import * as path from 'path';
|
|
9
|
-
import { glob } from 'glob';
|
|
10
|
-
import { isNodeError, escapePath, unescapePath, getErrorMessage, DEFAULT_FILE_FILTERING_OPTIONS, SHELL_SPECIAL_CHARS, } from '@qwen-code/qwen-code-core';
|
|
6
|
+
import { useCallback, useMemo, useEffect } from 'react';
|
|
11
7
|
import { logicalPosToOffset, } from '../components/shared/text-buffer.js';
|
|
12
8
|
import { isSlashCommand } from '../utils/commandUtils.js';
|
|
13
9
|
import { toCodePoints } from '../utils/textUtils.js';
|
|
10
|
+
import { useAtCompletion } from './useAtCompletion.js';
|
|
11
|
+
import { useSlashCompletion } from './useSlashCompletion.js';
|
|
14
12
|
import { useCompletion } from './useCompletion.js';
|
|
13
|
+
export var CompletionMode;
|
|
14
|
+
(function (CompletionMode) {
|
|
15
|
+
CompletionMode["IDLE"] = "IDLE";
|
|
16
|
+
CompletionMode["AT"] = "AT";
|
|
17
|
+
CompletionMode["SLASH"] = "SLASH";
|
|
18
|
+
})(CompletionMode || (CompletionMode = {}));
|
|
15
19
|
export function useCommandCompletion(buffer, dirs, cwd, slashCommands, commandContext, reverseSearchActive = false, config) {
|
|
16
20
|
const { suggestions, activeSuggestionIndex, visibleStartIndex, showSuggestions, isLoadingSuggestions, isPerfectMatch, setSuggestions, setShowSuggestions, setActiveSuggestionIndex, setIsLoadingSuggestions, setIsPerfectMatch, setVisibleStartIndex, resetCompletionState, navigateUp, navigateDown, } = useCompletion();
|
|
17
|
-
const completionStart = useRef(-1);
|
|
18
|
-
const completionEnd = useRef(-1);
|
|
19
21
|
const cursorRow = buffer.cursor[0];
|
|
20
22
|
const cursorCol = buffer.cursor[1];
|
|
21
|
-
|
|
22
|
-
const commandIndex = useMemo(() => {
|
|
23
|
+
const { completionMode, query, completionStart, completionEnd } = useMemo(() => {
|
|
23
24
|
const currentLine = buffer.lines[cursorRow] || '';
|
|
24
25
|
if (cursorRow === 0 && isSlashCommand(currentLine.trim())) {
|
|
25
|
-
return
|
|
26
|
+
return {
|
|
27
|
+
completionMode: CompletionMode.SLASH,
|
|
28
|
+
query: currentLine,
|
|
29
|
+
completionStart: 0,
|
|
30
|
+
completionEnd: currentLine.length,
|
|
31
|
+
};
|
|
26
32
|
}
|
|
27
|
-
// For other completions like '@', we search backwards from the cursor.
|
|
28
33
|
const codePoints = toCodePoints(currentLine);
|
|
29
34
|
for (let i = cursorCol - 1; i >= 0; i--) {
|
|
30
35
|
const char = codePoints[i];
|
|
31
36
|
if (char === ' ') {
|
|
32
|
-
// Check for unescaped spaces.
|
|
33
37
|
let backslashCount = 0;
|
|
34
38
|
for (let j = i - 1; j >= 0 && codePoints[j] === '\\'; j--) {
|
|
35
39
|
backslashCount++;
|
|
36
40
|
}
|
|
37
41
|
if (backslashCount % 2 === 0) {
|
|
38
|
-
return
|
|
42
|
+
return {
|
|
43
|
+
completionMode: CompletionMode.IDLE,
|
|
44
|
+
query: null,
|
|
45
|
+
completionStart: -1,
|
|
46
|
+
completionEnd: -1,
|
|
47
|
+
};
|
|
39
48
|
}
|
|
40
49
|
}
|
|
41
50
|
else if (char === '@') {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
const currentLine = buffer.lines[cursorRow] || '';
|
|
54
|
-
const codePoints = toCodePoints(currentLine);
|
|
55
|
-
if (codePoints[commandIndex] === '/') {
|
|
56
|
-
// Always reset perfect match at the beginning of processing.
|
|
57
|
-
setIsPerfectMatch(false);
|
|
58
|
-
const fullPath = currentLine.substring(commandIndex + 1);
|
|
59
|
-
const hasTrailingSpace = currentLine.endsWith(' ');
|
|
60
|
-
// Get all non-empty parts of the command.
|
|
61
|
-
const rawParts = fullPath.split(/\s+/).filter((p) => p);
|
|
62
|
-
let commandPathParts = rawParts;
|
|
63
|
-
let partial = '';
|
|
64
|
-
// If there's no trailing space, the last part is potentially a partial segment.
|
|
65
|
-
// We tentatively separate it.
|
|
66
|
-
if (!hasTrailingSpace && rawParts.length > 0) {
|
|
67
|
-
partial = rawParts[rawParts.length - 1];
|
|
68
|
-
commandPathParts = rawParts.slice(0, -1);
|
|
69
|
-
}
|
|
70
|
-
// Traverse the Command Tree using the tentative completed path
|
|
71
|
-
let currentLevel = slashCommands;
|
|
72
|
-
let leafCommand = null;
|
|
73
|
-
for (const part of commandPathParts) {
|
|
74
|
-
if (!currentLevel) {
|
|
75
|
-
leafCommand = null;
|
|
76
|
-
currentLevel = [];
|
|
77
|
-
break;
|
|
78
|
-
}
|
|
79
|
-
const found = currentLevel.find((cmd) => cmd.name === part || cmd.altNames?.includes(part));
|
|
80
|
-
if (found) {
|
|
81
|
-
leafCommand = found;
|
|
82
|
-
currentLevel = found.subCommands;
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
leafCommand = null;
|
|
86
|
-
currentLevel = [];
|
|
87
|
-
break;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
let exactMatchAsParent;
|
|
91
|
-
// Handle the Ambiguous Case
|
|
92
|
-
if (!hasTrailingSpace && currentLevel) {
|
|
93
|
-
exactMatchAsParent = currentLevel.find((cmd) => (cmd.name === partial || cmd.altNames?.includes(partial)) &&
|
|
94
|
-
cmd.subCommands);
|
|
95
|
-
if (exactMatchAsParent) {
|
|
96
|
-
// It's a perfect match for a parent command. Override our initial guess.
|
|
97
|
-
// Treat it as a completed command path.
|
|
98
|
-
leafCommand = exactMatchAsParent;
|
|
99
|
-
currentLevel = exactMatchAsParent.subCommands;
|
|
100
|
-
partial = ''; // We now want to suggest ALL of its sub-commands.
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
// Check for perfect, executable match
|
|
104
|
-
if (!hasTrailingSpace) {
|
|
105
|
-
if (leafCommand && partial === '' && leafCommand.action) {
|
|
106
|
-
// Case: /command<enter> - command has action, no sub-commands were suggested
|
|
107
|
-
setIsPerfectMatch(true);
|
|
108
|
-
}
|
|
109
|
-
else if (currentLevel) {
|
|
110
|
-
// Case: /command subcommand<enter>
|
|
111
|
-
const perfectMatch = currentLevel.find((cmd) => (cmd.name === partial || cmd.altNames?.includes(partial)) &&
|
|
112
|
-
cmd.action);
|
|
113
|
-
if (perfectMatch) {
|
|
114
|
-
setIsPerfectMatch(true);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
const depth = commandPathParts.length;
|
|
119
|
-
const isArgumentCompletion = leafCommand?.completion &&
|
|
120
|
-
(hasTrailingSpace ||
|
|
121
|
-
(rawParts.length > depth && depth > 0 && partial !== ''));
|
|
122
|
-
// Set completion range
|
|
123
|
-
if (hasTrailingSpace || exactMatchAsParent) {
|
|
124
|
-
completionStart.current = currentLine.length;
|
|
125
|
-
completionEnd.current = currentLine.length;
|
|
126
|
-
}
|
|
127
|
-
else if (partial) {
|
|
128
|
-
if (isArgumentCompletion) {
|
|
129
|
-
const commandSoFar = `/${commandPathParts.join(' ')}`;
|
|
130
|
-
const argStartIndex = commandSoFar.length + (commandPathParts.length > 0 ? 1 : 0);
|
|
131
|
-
completionStart.current = argStartIndex;
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
completionStart.current = currentLine.length - partial.length;
|
|
135
|
-
}
|
|
136
|
-
completionEnd.current = currentLine.length;
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
// e.g. /
|
|
140
|
-
completionStart.current = commandIndex + 1;
|
|
141
|
-
completionEnd.current = currentLine.length;
|
|
142
|
-
}
|
|
143
|
-
// Provide Suggestions based on the now-corrected context
|
|
144
|
-
if (isArgumentCompletion) {
|
|
145
|
-
const fetchAndSetSuggestions = async () => {
|
|
146
|
-
setIsLoadingSuggestions(true);
|
|
147
|
-
const argString = rawParts.slice(depth).join(' ');
|
|
148
|
-
const results = (await leafCommand.completion(commandContext, argString)) || [];
|
|
149
|
-
const finalSuggestions = results.map((s) => ({ label: s, value: s }));
|
|
150
|
-
setSuggestions(finalSuggestions);
|
|
151
|
-
setShowSuggestions(finalSuggestions.length > 0);
|
|
152
|
-
setActiveSuggestionIndex(finalSuggestions.length > 0 ? 0 : -1);
|
|
153
|
-
setIsLoadingSuggestions(false);
|
|
154
|
-
};
|
|
155
|
-
fetchAndSetSuggestions();
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
// Command/Sub-command Completion
|
|
159
|
-
const commandsToSearch = currentLevel || [];
|
|
160
|
-
if (commandsToSearch.length > 0) {
|
|
161
|
-
let potentialSuggestions = commandsToSearch.filter((cmd) => cmd.description &&
|
|
162
|
-
(cmd.name.startsWith(partial) ||
|
|
163
|
-
cmd.altNames?.some((alt) => alt.startsWith(partial))));
|
|
164
|
-
// If a user's input is an exact match and it is a leaf command,
|
|
165
|
-
// enter should submit immediately.
|
|
166
|
-
if (potentialSuggestions.length > 0 && !hasTrailingSpace) {
|
|
167
|
-
const perfectMatch = potentialSuggestions.find((s) => s.name === partial || s.altNames?.includes(partial));
|
|
168
|
-
if (perfectMatch && perfectMatch.action) {
|
|
169
|
-
potentialSuggestions = [];
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
const finalSuggestions = potentialSuggestions.map((cmd) => ({
|
|
173
|
-
label: cmd.name,
|
|
174
|
-
value: cmd.name,
|
|
175
|
-
description: cmd.description,
|
|
176
|
-
}));
|
|
177
|
-
setSuggestions(finalSuggestions);
|
|
178
|
-
setShowSuggestions(finalSuggestions.length > 0);
|
|
179
|
-
setActiveSuggestionIndex(finalSuggestions.length > 0 ? 0 : -1);
|
|
180
|
-
setIsLoadingSuggestions(false);
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
// If we fall through, no suggestions are available.
|
|
184
|
-
resetCompletionState();
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
// Handle At Command Completion
|
|
188
|
-
completionEnd.current = codePoints.length;
|
|
189
|
-
for (let i = cursorCol; i < codePoints.length; i++) {
|
|
190
|
-
if (codePoints[i] === ' ') {
|
|
191
|
-
let backslashCount = 0;
|
|
192
|
-
for (let j = i - 1; j >= 0 && codePoints[j] === '\\'; j--) {
|
|
193
|
-
backslashCount++;
|
|
194
|
-
}
|
|
195
|
-
if (backslashCount % 2 === 0) {
|
|
196
|
-
completionEnd.current = i;
|
|
197
|
-
break;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
const pathStart = commandIndex + 1;
|
|
202
|
-
const partialPath = currentLine.substring(pathStart, completionEnd.current);
|
|
203
|
-
const lastSlashIndex = partialPath.lastIndexOf('/');
|
|
204
|
-
completionStart.current =
|
|
205
|
-
lastSlashIndex === -1 ? pathStart : pathStart + lastSlashIndex + 1;
|
|
206
|
-
const baseDirRelative = lastSlashIndex === -1
|
|
207
|
-
? '.'
|
|
208
|
-
: partialPath.substring(0, lastSlashIndex + 1);
|
|
209
|
-
const prefix = unescapePath(lastSlashIndex === -1
|
|
210
|
-
? partialPath
|
|
211
|
-
: partialPath.substring(lastSlashIndex + 1));
|
|
212
|
-
let isMounted = true;
|
|
213
|
-
const findFilesRecursively = async (startDir, searchPrefix, fileDiscovery, filterOptions, currentRelativePath = '', depth = 0, maxDepth = 10, // Limit recursion depth
|
|
214
|
-
maxResults = 50) => {
|
|
215
|
-
if (depth > maxDepth) {
|
|
216
|
-
return [];
|
|
217
|
-
}
|
|
218
|
-
const lowerSearchPrefix = searchPrefix.toLowerCase();
|
|
219
|
-
let foundSuggestions = [];
|
|
220
|
-
try {
|
|
221
|
-
const entries = await fs.readdir(startDir, { withFileTypes: true });
|
|
222
|
-
for (const entry of entries) {
|
|
223
|
-
if (foundSuggestions.length >= maxResults)
|
|
224
|
-
break;
|
|
225
|
-
const entryPathRelative = path.join(currentRelativePath, entry.name);
|
|
226
|
-
const entryPathFromRoot = path.relative(startDir, path.join(startDir, entry.name));
|
|
227
|
-
// Conditionally ignore dotfiles
|
|
228
|
-
if (!searchPrefix.startsWith('.') && entry.name.startsWith('.')) {
|
|
229
|
-
continue;
|
|
230
|
-
}
|
|
231
|
-
// Check if this entry should be ignored by filtering options
|
|
232
|
-
if (fileDiscovery &&
|
|
233
|
-
fileDiscovery.shouldIgnoreFile(entryPathFromRoot, filterOptions)) {
|
|
234
|
-
continue;
|
|
235
|
-
}
|
|
236
|
-
if (entry.name.toLowerCase().startsWith(lowerSearchPrefix)) {
|
|
237
|
-
foundSuggestions.push({
|
|
238
|
-
label: entryPathRelative + (entry.isDirectory() ? '/' : ''),
|
|
239
|
-
value: escapePath(entryPathRelative + (entry.isDirectory() ? '/' : '')),
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
if (entry.isDirectory() &&
|
|
243
|
-
entry.name !== 'node_modules' &&
|
|
244
|
-
!entry.name.startsWith('.')) {
|
|
245
|
-
if (foundSuggestions.length < maxResults) {
|
|
246
|
-
foundSuggestions = foundSuggestions.concat(await findFilesRecursively(path.join(startDir, entry.name), searchPrefix, // Pass original searchPrefix for recursive calls
|
|
247
|
-
fileDiscovery, filterOptions, entryPathRelative, depth + 1, maxDepth, maxResults - foundSuggestions.length));
|
|
51
|
+
let end = codePoints.length;
|
|
52
|
+
for (let i = cursorCol; i < codePoints.length; i++) {
|
|
53
|
+
if (codePoints[i] === ' ') {
|
|
54
|
+
let backslashCount = 0;
|
|
55
|
+
for (let j = i - 1; j >= 0 && codePoints[j] === '\\'; j--) {
|
|
56
|
+
backslashCount++;
|
|
57
|
+
}
|
|
58
|
+
if (backslashCount % 2 === 0) {
|
|
59
|
+
end = i;
|
|
60
|
+
break;
|
|
248
61
|
}
|
|
249
62
|
}
|
|
250
63
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
// Ignore errors like permission denied or ENOENT during recursive search
|
|
254
|
-
}
|
|
255
|
-
return foundSuggestions.slice(0, maxResults);
|
|
256
|
-
};
|
|
257
|
-
const findFilesWithGlob = async (searchPrefix, fileDiscoveryService, filterOptions, searchDir, maxResults = 50) => {
|
|
258
|
-
const globPattern = `**/${searchPrefix}*`;
|
|
259
|
-
const files = await glob(globPattern, {
|
|
260
|
-
cwd: searchDir,
|
|
261
|
-
dot: searchPrefix.startsWith('.'),
|
|
262
|
-
nocase: true,
|
|
263
|
-
});
|
|
264
|
-
const suggestions = files
|
|
265
|
-
.filter((file) => {
|
|
266
|
-
if (fileDiscoveryService) {
|
|
267
|
-
return !fileDiscoveryService.shouldIgnoreFile(file, filterOptions);
|
|
268
|
-
}
|
|
269
|
-
return true;
|
|
270
|
-
})
|
|
271
|
-
.map((file) => {
|
|
272
|
-
const absolutePath = path.resolve(searchDir, file);
|
|
273
|
-
const label = path.relative(cwd, absolutePath);
|
|
64
|
+
const pathStart = i + 1;
|
|
65
|
+
const partialPath = currentLine.substring(pathStart, end);
|
|
274
66
|
return {
|
|
275
|
-
|
|
276
|
-
|
|
67
|
+
completionMode: CompletionMode.AT,
|
|
68
|
+
query: partialPath,
|
|
69
|
+
completionStart: pathStart,
|
|
70
|
+
completionEnd: end,
|
|
277
71
|
};
|
|
278
|
-
})
|
|
279
|
-
.slice(0, maxResults);
|
|
280
|
-
return suggestions;
|
|
281
|
-
};
|
|
282
|
-
const fetchSuggestions = async () => {
|
|
283
|
-
setIsLoadingSuggestions(true);
|
|
284
|
-
let fetchedSuggestions = [];
|
|
285
|
-
const fileDiscoveryService = config ? config.getFileService() : null;
|
|
286
|
-
const enableRecursiveSearch = config?.getEnableRecursiveFileSearch() ?? true;
|
|
287
|
-
const filterOptions = config?.getFileFilteringOptions() ?? DEFAULT_FILE_FILTERING_OPTIONS;
|
|
288
|
-
try {
|
|
289
|
-
// If there's no slash, or it's the root, do a recursive search from workspace directories
|
|
290
|
-
for (const dir of dirs) {
|
|
291
|
-
let fetchedSuggestionsPerDir = [];
|
|
292
|
-
if (partialPath.indexOf('/') === -1 &&
|
|
293
|
-
prefix &&
|
|
294
|
-
enableRecursiveSearch) {
|
|
295
|
-
if (fileDiscoveryService) {
|
|
296
|
-
fetchedSuggestionsPerDir = await findFilesWithGlob(prefix, fileDiscoveryService, filterOptions, dir);
|
|
297
|
-
}
|
|
298
|
-
else {
|
|
299
|
-
fetchedSuggestionsPerDir = await findFilesRecursively(dir, prefix, null, filterOptions);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
else {
|
|
303
|
-
// Original behavior: list files in the specific directory
|
|
304
|
-
const lowerPrefix = prefix.toLowerCase();
|
|
305
|
-
const baseDirAbsolute = path.resolve(dir, baseDirRelative);
|
|
306
|
-
const entries = await fs.readdir(baseDirAbsolute, {
|
|
307
|
-
withFileTypes: true,
|
|
308
|
-
});
|
|
309
|
-
// Filter entries using git-aware filtering
|
|
310
|
-
const filteredEntries = [];
|
|
311
|
-
for (const entry of entries) {
|
|
312
|
-
// Conditionally ignore dotfiles
|
|
313
|
-
if (!prefix.startsWith('.') && entry.name.startsWith('.')) {
|
|
314
|
-
continue;
|
|
315
|
-
}
|
|
316
|
-
if (!entry.name.toLowerCase().startsWith(lowerPrefix))
|
|
317
|
-
continue;
|
|
318
|
-
const relativePath = path.relative(dir, path.join(baseDirAbsolute, entry.name));
|
|
319
|
-
if (fileDiscoveryService &&
|
|
320
|
-
fileDiscoveryService.shouldIgnoreFile(relativePath, filterOptions)) {
|
|
321
|
-
continue;
|
|
322
|
-
}
|
|
323
|
-
filteredEntries.push(entry);
|
|
324
|
-
}
|
|
325
|
-
fetchedSuggestionsPerDir = filteredEntries.map((entry) => {
|
|
326
|
-
const absolutePath = path.resolve(baseDirAbsolute, entry.name);
|
|
327
|
-
const label = cwd === dir ? entry.name : path.relative(cwd, absolutePath);
|
|
328
|
-
const suggestionLabel = entry.isDirectory() ? label + '/' : label;
|
|
329
|
-
return {
|
|
330
|
-
label: suggestionLabel,
|
|
331
|
-
value: escapePath(suggestionLabel),
|
|
332
|
-
};
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
fetchedSuggestions = [
|
|
336
|
-
...fetchedSuggestions,
|
|
337
|
-
...fetchedSuggestionsPerDir,
|
|
338
|
-
];
|
|
339
|
-
}
|
|
340
|
-
// Like glob, we always return forward slashes for path separators, even on Windows.
|
|
341
|
-
// But preserve backslash escaping for special characters.
|
|
342
|
-
const specialCharsLookahead = `(?![${SHELL_SPECIAL_CHARS.source.slice(1, -1)}])`;
|
|
343
|
-
const pathSeparatorRegex = new RegExp(`\\\\${specialCharsLookahead}`, 'g');
|
|
344
|
-
fetchedSuggestions = fetchedSuggestions.map((suggestion) => ({
|
|
345
|
-
...suggestion,
|
|
346
|
-
label: suggestion.label.replace(pathSeparatorRegex, '/'),
|
|
347
|
-
value: suggestion.value.replace(pathSeparatorRegex, '/'),
|
|
348
|
-
}));
|
|
349
|
-
// Sort by depth, then directories first, then alphabetically
|
|
350
|
-
fetchedSuggestions.sort((a, b) => {
|
|
351
|
-
const depthA = (a.label.match(/\//g) || []).length;
|
|
352
|
-
const depthB = (b.label.match(/\//g) || []).length;
|
|
353
|
-
if (depthA !== depthB) {
|
|
354
|
-
return depthA - depthB;
|
|
355
|
-
}
|
|
356
|
-
const aIsDir = a.label.endsWith('/');
|
|
357
|
-
const bIsDir = b.label.endsWith('/');
|
|
358
|
-
if (aIsDir && !bIsDir)
|
|
359
|
-
return -1;
|
|
360
|
-
if (!aIsDir && bIsDir)
|
|
361
|
-
return 1;
|
|
362
|
-
// exclude extension when comparing
|
|
363
|
-
const filenameA = a.label.substring(0, a.label.length - path.extname(a.label).length);
|
|
364
|
-
const filenameB = b.label.substring(0, b.label.length - path.extname(b.label).length);
|
|
365
|
-
return (filenameA.localeCompare(filenameB) || a.label.localeCompare(b.label));
|
|
366
|
-
});
|
|
367
|
-
if (isMounted) {
|
|
368
|
-
setSuggestions(fetchedSuggestions);
|
|
369
|
-
setShowSuggestions(fetchedSuggestions.length > 0);
|
|
370
|
-
setActiveSuggestionIndex(fetchedSuggestions.length > 0 ? 0 : -1);
|
|
371
|
-
setVisibleStartIndex(0);
|
|
372
|
-
}
|
|
373
72
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
}
|
|
381
|
-
else {
|
|
382
|
-
console.error(`Error fetching completion suggestions for ${partialPath}: ${getErrorMessage(error)}`);
|
|
383
|
-
if (isMounted) {
|
|
384
|
-
resetCompletionState();
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
if (isMounted) {
|
|
389
|
-
setIsLoadingSuggestions(false);
|
|
390
|
-
}
|
|
391
|
-
};
|
|
392
|
-
const debounceTimeout = setTimeout(fetchSuggestions, 100);
|
|
393
|
-
return () => {
|
|
394
|
-
isMounted = false;
|
|
395
|
-
clearTimeout(debounceTimeout);
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
completionMode: CompletionMode.IDLE,
|
|
76
|
+
query: null,
|
|
77
|
+
completionStart: -1,
|
|
78
|
+
completionEnd: -1,
|
|
396
79
|
};
|
|
397
|
-
}, [
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
dirs,
|
|
80
|
+
}, [cursorRow, cursorCol, buffer.lines]);
|
|
81
|
+
useAtCompletion({
|
|
82
|
+
enabled: completionMode === CompletionMode.AT,
|
|
83
|
+
pattern: query || '',
|
|
84
|
+
config,
|
|
403
85
|
cwd,
|
|
404
|
-
|
|
405
|
-
|
|
86
|
+
setSuggestions,
|
|
87
|
+
setIsLoadingSuggestions,
|
|
88
|
+
});
|
|
89
|
+
const slashCompletionRange = useSlashCompletion({
|
|
90
|
+
enabled: completionMode === CompletionMode.SLASH,
|
|
91
|
+
query,
|
|
406
92
|
slashCommands,
|
|
407
93
|
commandContext,
|
|
408
|
-
config,
|
|
409
|
-
reverseSearchActive,
|
|
410
94
|
setSuggestions,
|
|
411
|
-
setShowSuggestions,
|
|
412
|
-
setActiveSuggestionIndex,
|
|
413
95
|
setIsLoadingSuggestions,
|
|
414
96
|
setIsPerfectMatch,
|
|
415
|
-
|
|
97
|
+
});
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
setActiveSuggestionIndex(suggestions.length > 0 ? 0 : -1);
|
|
100
|
+
setVisibleStartIndex(0);
|
|
101
|
+
}, [suggestions, setActiveSuggestionIndex, setVisibleStartIndex]);
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
if (completionMode === CompletionMode.IDLE || reverseSearchActive) {
|
|
104
|
+
resetCompletionState();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
// Show suggestions if we are loading OR if there are results to display.
|
|
108
|
+
setShowSuggestions(isLoadingSuggestions || suggestions.length > 0);
|
|
109
|
+
}, [
|
|
110
|
+
completionMode,
|
|
111
|
+
suggestions.length,
|
|
112
|
+
isLoadingSuggestions,
|
|
113
|
+
reverseSearchActive,
|
|
114
|
+
resetCompletionState,
|
|
115
|
+
setShowSuggestions,
|
|
416
116
|
]);
|
|
417
117
|
const handleAutocomplete = useCallback((indexToUse) => {
|
|
418
118
|
if (indexToUse < 0 || indexToUse >= suggestions.length) {
|
|
419
119
|
return;
|
|
420
120
|
}
|
|
421
121
|
const suggestion = suggestions[indexToUse].value;
|
|
422
|
-
|
|
122
|
+
let start = completionStart;
|
|
123
|
+
let end = completionEnd;
|
|
124
|
+
if (completionMode === CompletionMode.SLASH) {
|
|
125
|
+
start = slashCompletionRange.completionStart;
|
|
126
|
+
end = slashCompletionRange.completionEnd;
|
|
127
|
+
}
|
|
128
|
+
if (start === -1 || end === -1) {
|
|
423
129
|
return;
|
|
424
130
|
}
|
|
425
|
-
const isSlash = (buffer.lines[cursorRow] || '')[commandIndex] === '/';
|
|
426
131
|
let suggestionText = suggestion;
|
|
427
|
-
if (
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
(buffer.lines[cursorRow] || '')[completionStart.current - 1] !== ' ') {
|
|
132
|
+
if (completionMode === CompletionMode.SLASH) {
|
|
133
|
+
if (start === end &&
|
|
134
|
+
start > 1 &&
|
|
135
|
+
(buffer.lines[cursorRow] || '')[start - 1] !== ' ') {
|
|
432
136
|
suggestionText = ' ' + suggestionText;
|
|
433
137
|
}
|
|
434
138
|
}
|
|
435
139
|
suggestionText += ' ';
|
|
436
|
-
buffer.replaceRangeByOffset(logicalPosToOffset(buffer.lines, cursorRow,
|
|
437
|
-
}, [
|
|
140
|
+
buffer.replaceRangeByOffset(logicalPosToOffset(buffer.lines, cursorRow, start), logicalPosToOffset(buffer.lines, cursorRow, end), suggestionText);
|
|
141
|
+
}, [
|
|
142
|
+
cursorRow,
|
|
143
|
+
buffer,
|
|
144
|
+
suggestions,
|
|
145
|
+
completionMode,
|
|
146
|
+
completionStart,
|
|
147
|
+
completionEnd,
|
|
148
|
+
slashCompletionRange,
|
|
149
|
+
]);
|
|
438
150
|
return {
|
|
439
151
|
suggestions,
|
|
440
152
|
activeSuggestionIndex,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCommandCompletion.js","sourceRoot":"","sources":["../../../../src/ui/hooks/useCommandCompletion.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EACL,WAAW,EACX,UAAU,EACV,YAAY,EACZ,eAAe,EAGf,8BAA8B,EAC9B,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,kBAAkB,GAEnB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAiBnD,MAAM,UAAU,oBAAoB,CAClC,MAAkB,EAClB,IAAuB,EACvB,GAAW,EACX,aAAsC,EACtC,cAA8B,EAC9B,sBAA+B,KAAK,EACpC,MAAe;IAEf,MAAM,EACJ,WAAW,EACX,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,cAAc,EAEd,cAAc,EACd,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EAEpB,oBAAoB,EACpB,UAAU,EACV,YAAY,GACb,GAAG,aAAa,EAAE,CAAC;IAEpB,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAEnC,2DAA2D;IAC3D,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE;QAChC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAClD,IAAI,SAAS,KAAK,CAAC,IAAI,cAAc,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC1D,OAAO,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClC,CAAC;QAED,uEAAuE;QAEvE,MAAM,UAAU,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;QAC7C,KAAK,IAAI,CAAC,GAAG,SAAS,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAE3B,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACjB,8BAA8B;gBAC9B,IAAI,cAAc,GAAG,CAAC,CAAC;gBACvB,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC1D,cAAc,EAAE,CAAC;gBACnB,CAAC;gBACD,IAAI,cAAc,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC7B,OAAO,CAAC,CAAC,CAAC,CAAC,+BAA+B;gBAC5C,CAAC;YACH,CAAC;iBAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACxB,uDAAuD;gBACvD,OAAO,CAAC,CAAC;YACX,CAAC;QACH,CAAC;QAED,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAEzC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,YAAY,KAAK,CAAC,CAAC,IAAI,mBAAmB,EAAE,CAAC;YAC/C,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,UAAU,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;QAE7C,IAAI,UAAU,CAAC,YAAY,CAAC,KAAK,GAAG,EAAE,CAAC;YACrC,6DAA6D;YAC7D,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAEzB,MAAM,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;YACzD,MAAM,gBAAgB,GAAG,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAEnD,0CAA0C;YAC1C,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;YAExD,IAAI,gBAAgB,GAAG,QAAQ,CAAC;YAChC,IAAI,OAAO,GAAG,EAAE,CAAC;YAEjB,gFAAgF;YAChF,8BAA8B;YAC9B,IAAI,CAAC,gBAAgB,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7C,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACxC,gBAAgB,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3C,CAAC;YAED,+DAA+D;YAC/D,IAAI,YAAY,GAAwC,aAAa,CAAC;YACtE,IAAI,WAAW,GAAwB,IAAI,CAAC;YAE5C,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;gBACpC,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,WAAW,GAAG,IAAI,CAAC;oBACnB,YAAY,GAAG,EAAE,CAAC;oBAClB,MAAM;gBACR,CAAC;gBACD,MAAM,KAAK,GAA6B,YAAY,CAAC,IAAI,CACvD,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,CAC3D,CAAC;gBACF,IAAI,KAAK,EAAE,CAAC;oBACV,WAAW,GAAG,KAAK,CAAC;oBACpB,YAAY,GAAG,KAAK,CAAC,WAER,CAAC;gBAChB,CAAC;qBAAM,CAAC;oBACN,WAAW,GAAG,IAAI,CAAC;oBACnB,YAAY,GAAG,EAAE,CAAC;oBAClB,MAAM;gBACR,CAAC;YACH,CAAC;YAED,IAAI,kBAA4C,CAAC;YACjD,4BAA4B;YAC5B,IAAI,CAAC,gBAAgB,IAAI,YAAY,EAAE,CAAC;gBACtC,kBAAkB,GAAG,YAAY,CAAC,IAAI,CACpC,CAAC,GAAG,EAAE,EAAE,CACN,CAAC,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;oBACzD,GAAG,CAAC,WAAW,CAClB,CAAC;gBAEF,IAAI,kBAAkB,EAAE,CAAC;oBACvB,yEAAyE;oBACzE,wCAAwC;oBACxC,WAAW,GAAG,kBAAkB,CAAC;oBACjC,YAAY,GAAG,kBAAkB,CAAC,WAAW,CAAC;oBAC9C,OAAO,GAAG,EAAE,CAAC,CAAC,kDAAkD;gBAClE,CAAC;YACH,CAAC;YAED,sCAAsC;YACtC,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtB,IAAI,WAAW,IAAI,OAAO,KAAK,EAAE,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;oBACxD,6EAA6E;oBAC7E,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC;qBAAM,IAAI,YAAY,EAAE,CAAC;oBACxB,mCAAmC;oBACnC,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CACpC,CAAC,GAAG,EAAE,EAAE,CACN,CAAC,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;wBACzD,GAAG,CAAC,MAAM,CACb,CAAC;oBACF,IAAI,YAAY,EAAE,CAAC;wBACjB,iBAAiB,CAAC,IAAI,CAAC,CAAC;oBAC1B,CAAC;gBACH,CAAC;YACH,CAAC;YAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,CAAC;YACtC,MAAM,oBAAoB,GACxB,WAAW,EAAE,UAAU;gBACvB,CAAC,gBAAgB;oBACf,CAAC,QAAQ,CAAC,MAAM,GAAG,KAAK,IAAI,KAAK,GAAG,CAAC,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC;YAE9D,uBAAuB;YACvB,IAAI,gBAAgB,IAAI,kBAAkB,EAAE,CAAC;gBAC3C,eAAe,CAAC,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC;gBAC7C,aAAa,CAAC,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC;YAC7C,CAAC;iBAAM,IAAI,OAAO,EAAE,CAAC;gBACnB,IAAI,oBAAoB,EAAE,CAAC;oBACzB,MAAM,YAAY,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;oBACtD,MAAM,aAAa,GACjB,YAAY,CAAC,MAAM,GAAG,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC9D,eAAe,CAAC,OAAO,GAAG,aAAa,CAAC;gBAC1C,CAAC;qBAAM,CAAC;oBACN,eAAe,CAAC,OAAO,GAAG,WAAW,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;gBAChE,CAAC;gBACD,aAAa,CAAC,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACN,SAAS;gBACT,eAAe,CAAC,OAAO,GAAG,YAAY,GAAG,CAAC,CAAC;gBAC3C,aAAa,CAAC,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC;YAC7C,CAAC;YAED,yDAAyD;YACzD,IAAI,oBAAoB,EAAE,CAAC;gBACzB,MAAM,sBAAsB,GAAG,KAAK,IAAI,EAAE;oBACxC,uBAAuB,CAAC,IAAI,CAAC,CAAC;oBAC9B,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAClD,MAAM,OAAO,GACX,CAAC,MAAM,WAAY,CAAC,UAAW,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;oBACpE,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;oBACtE,cAAc,CAAC,gBAAgB,CAAC,CAAC;oBACjC,kBAAkB,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;oBAChD,wBAAwB,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC/D,uBAAuB,CAAC,KAAK,CAAC,CAAC;gBACjC,CAAC,CAAC;gBACF,sBAAsB,EAAE,CAAC;gBACzB,OAAO;YACT,CAAC;YAED,iCAAiC;YACjC,MAAM,gBAAgB,GAAG,YAAY,IAAI,EAAE,CAAC;YAC5C,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,IAAI,oBAAoB,GAAG,gBAAgB,CAAC,MAAM,CAChD,CAAC,GAAG,EAAE,EAAE,CACN,GAAG,CAAC,WAAW;oBACf,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;wBAC3B,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAC1D,CAAC;gBAEF,gEAAgE;gBAChE,mCAAmC;gBACnC,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACzD,MAAM,YAAY,GAAG,oBAAoB,CAAC,IAAI,CAC5C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAC3D,CAAC;oBACF,IAAI,YAAY,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;wBACxC,oBAAoB,GAAG,EAAE,CAAC;oBAC5B,CAAC;gBACH,CAAC;gBAED,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBAC1D,KAAK,EAAE,GAAG,CAAC,IAAI;oBACf,KAAK,EAAE,GAAG,CAAC,IAAI;oBACf,WAAW,EAAE,GAAG,CAAC,WAAW;iBAC7B,CAAC,CAAC,CAAC;gBAEJ,cAAc,CAAC,gBAAgB,CAAC,CAAC;gBACjC,kBAAkB,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAChD,wBAAwB,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/D,uBAAuB,CAAC,KAAK,CAAC,CAAC;gBAC/B,OAAO;YACT,CAAC;YAED,oDAAoD;YACpD,oBAAoB,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QAED,+BAA+B;QAC/B,aAAa,CAAC,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC;QAC1C,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACnD,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBAC1B,IAAI,cAAc,GAAG,CAAC,CAAC;gBACvB,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC1D,cAAc,EAAE,CAAC;gBACnB,CAAC;gBAED,IAAI,cAAc,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC7B,aAAa,CAAC,OAAO,GAAG,CAAC,CAAC;oBAC1B,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,YAAY,GAAG,CAAC,CAAC;QACnC,MAAM,WAAW,GAAG,WAAW,CAAC,SAAS,CAAC,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;QAC5E,MAAM,cAAc,GAAG,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACpD,eAAe,CAAC,OAAO;YACrB,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,GAAG,cAAc,GAAG,CAAC,CAAC;QACrE,MAAM,eAAe,GACnB,cAAc,KAAK,CAAC,CAAC;YACnB,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,cAAc,GAAG,CAAC,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,YAAY,CACzB,cAAc,KAAK,CAAC,CAAC;YACnB,CAAC,CAAC,WAAW;YACb,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC,CAC9C,CAAC;QAEF,IAAI,SAAS,GAAG,IAAI,CAAC;QAErB,MAAM,oBAAoB,GAAG,KAAK,EAChC,QAAgB,EAChB,YAAoB,EACpB,aAA0C,EAC1C,aAGC,EACD,mBAAmB,GAAG,EAAE,EACxB,KAAK,GAAG,CAAC,EACT,QAAQ,GAAG,EAAE,EAAE,wBAAwB;QACvC,UAAU,GAAG,EAAE,EACQ,EAAE;YACzB,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC;gBACrB,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,iBAAiB,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;YACrD,IAAI,gBAAgB,GAAiB,EAAE,CAAC;YACxC,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oBAC5B,IAAI,gBAAgB,CAAC,MAAM,IAAI,UAAU;wBAAE,MAAM;oBAEjD,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;oBACrE,MAAM,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CACrC,QAAQ,EACR,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAChC,CAAC;oBAEF,gCAAgC;oBAChC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBAChE,SAAS;oBACX,CAAC;oBAED,6DAA6D;oBAC7D,IACE,aAAa;wBACb,aAAa,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,aAAa,CAAC,EAChE,CAAC;wBACD,SAAS;oBACX,CAAC;oBAED,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;wBAC3D,gBAAgB,CAAC,IAAI,CAAC;4BACpB,KAAK,EAAE,iBAAiB,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;4BAC3D,KAAK,EAAE,UAAU,CACf,iBAAiB,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CACrD;yBACF,CAAC,CAAC;oBACL,CAAC;oBACD,IACE,KAAK,CAAC,WAAW,EAAE;wBACnB,KAAK,CAAC,IAAI,KAAK,cAAc;wBAC7B,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAC3B,CAAC;wBACD,IAAI,gBAAgB,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;4BACzC,gBAAgB,GAAG,gBAAgB,CAAC,MAAM,CACxC,MAAM,oBAAoB,CACxB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,EAC/B,YAAY,EAAE,iDAAiD;4BAC/D,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,KAAK,GAAG,CAAC,EACT,QAAQ,EACR,UAAU,GAAG,gBAAgB,CAAC,MAAM,CACrC,CACF,CAAC;wBACJ,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,IAAI,EAAE,CAAC;gBACd,yEAAyE;YAC3E,CAAC;YACD,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAC/C,CAAC,CAAC;QAEF,MAAM,iBAAiB,GAAG,KAAK,EAC7B,YAAoB,EACpB,oBAA0C,EAC1C,aAGC,EACD,SAAiB,EACjB,UAAU,GAAG,EAAE,EACQ,EAAE;YACzB,MAAM,WAAW,GAAG,MAAM,YAAY,GAAG,CAAC;YAC1C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE;gBACpC,GAAG,EAAE,SAAS;gBACd,GAAG,EAAE,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC;gBACjC,MAAM,EAAE,IAAI;aACb,CAAC,CAAC;YAEH,MAAM,WAAW,GAAiB,KAAK;iBACpC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;gBACf,IAAI,oBAAoB,EAAE,CAAC;oBACzB,OAAO,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;gBACrE,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC,CAAC;iBACD,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE;gBACpB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;gBACnD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;gBAC/C,OAAO;oBACL,KAAK;oBACL,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC;iBACzB,CAAC;YACJ,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;YAExB,OAAO,WAAW,CAAC;QACrB,CAAC,CAAC;QAEF,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;YAClC,uBAAuB,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,kBAAkB,GAAiB,EAAE,CAAC;YAE1C,MAAM,oBAAoB,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACrE,MAAM,qBAAqB,GACzB,MAAM,EAAE,4BAA4B,EAAE,IAAI,IAAI,CAAC;YACjD,MAAM,aAAa,GACjB,MAAM,EAAE,uBAAuB,EAAE,IAAI,8BAA8B,CAAC;YAEtE,IAAI,CAAC;gBACH,0FAA0F;gBAC1F,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,IAAI,wBAAwB,GAAiB,EAAE,CAAC;oBAChD,IACE,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;wBAC/B,MAAM;wBACN,qBAAqB,EACrB,CAAC;wBACD,IAAI,oBAAoB,EAAE,CAAC;4BACzB,wBAAwB,GAAG,MAAM,iBAAiB,CAChD,MAAM,EACN,oBAAoB,EACpB,aAAa,EACb,GAAG,CACJ,CAAC;wBACJ,CAAC;6BAAM,CAAC;4BACN,wBAAwB,GAAG,MAAM,oBAAoB,CACnD,GAAG,EACH,MAAM,EACN,IAAI,EACJ,aAAa,CACd,CAAC;wBACJ,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,0DAA0D;wBAC1D,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;wBACzC,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;wBAC3D,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,eAAe,EAAE;4BAChD,aAAa,EAAE,IAAI;yBACpB,CAAC,CAAC;wBAEH,2CAA2C;wBAC3C,MAAM,eAAe,GAAG,EAAE,CAAC;wBAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;4BAC5B,gCAAgC;4BAChC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gCAC1D,SAAS;4BACX,CAAC;4BACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;gCAAE,SAAS;4BAEhE,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAChC,GAAG,EACH,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,IAAI,CAAC,CACvC,CAAC;4BACF,IACE,oBAAoB;gCACpB,oBAAoB,CAAC,gBAAgB,CACnC,YAAY,EACZ,aAAa,CACd,EACD,CAAC;gCACD,SAAS;4BACX,CAAC;4BAED,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;wBAC9B,CAAC;wBAED,wBAAwB,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;4BACvD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;4BAC/D,MAAM,KAAK,GACT,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;4BAC9D,MAAM,eAAe,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;4BAClE,OAAO;gCACL,KAAK,EAAE,eAAe;gCACtB,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC;6BACnC,CAAC;wBACJ,CAAC,CAAC,CAAC;oBACL,CAAC;oBACD,kBAAkB,GAAG;wBACnB,GAAG,kBAAkB;wBACrB,GAAG,wBAAwB;qBAC5B,CAAC;gBACJ,CAAC;gBAED,oFAAoF;gBACpF,0DAA0D;gBAC1D,MAAM,qBAAqB,GAAG,OAAO,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;gBACjF,MAAM,kBAAkB,GAAG,IAAI,MAAM,CACnC,OAAO,qBAAqB,EAAE,EAC9B,GAAG,CACJ,CAAC;gBACF,kBAAkB,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;oBAC3D,GAAG,UAAU;oBACb,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;oBACxD,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;iBACzD,CAAC,CAAC,CAAC;gBAEJ,6DAA6D;gBAC7D,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;oBAC/B,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;oBACnD,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;oBAEnD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;wBACtB,OAAO,MAAM,GAAG,MAAM,CAAC;oBACzB,CAAC;oBAED,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBACrC,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBACrC,IAAI,MAAM,IAAI,CAAC,MAAM;wBAAE,OAAO,CAAC,CAAC,CAAC;oBACjC,IAAI,CAAC,MAAM,IAAI,MAAM;wBAAE,OAAO,CAAC,CAAC;oBAEhC,mCAAmC;oBACnC,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,CACjC,CAAC,EACD,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAC9C,CAAC;oBACF,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,CACjC,CAAC,EACD,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAC9C,CAAC;oBAEF,OAAO,CACL,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CACrE,CAAC;gBACJ,CAAC,CAAC,CAAC;gBAEH,IAAI,SAAS,EAAE,CAAC;oBACd,cAAc,CAAC,kBAAkB,CAAC,CAAC;oBACnC,kBAAkB,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;oBAClD,wBAAwB,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBACjE,oBAAoB,CAAC,CAAC,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;YAAC,OAAO,KAAc,EAAE,CAAC;gBACxB,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAClD,IAAI,SAAS,EAAE,CAAC;wBACd,cAAc,CAAC,EAAE,CAAC,CAAC;wBACnB,kBAAkB,CAAC,KAAK,CAAC,CAAC;oBAC5B,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,KAAK,CACX,6CAA6C,WAAW,KAAK,eAAe,CAAC,KAAK,CAAC,EAAE,CACtF,CAAC;oBACF,IAAI,SAAS,EAAE,CAAC;wBACd,oBAAoB,EAAE,CAAC;oBACzB,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,SAAS,EAAE,CAAC;gBACd,uBAAuB,CAAC,KAAK,CAAC,CAAC;YACjC,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,eAAe,GAAG,UAAU,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;QAE1D,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,KAAK,CAAC;YAClB,YAAY,CAAC,eAAe,CAAC,CAAC;QAChC,CAAC,CAAC;IACJ,CAAC,EAAE;QACD,MAAM,CAAC,IAAI;QACX,SAAS;QACT,SAAS;QACT,MAAM,CAAC,KAAK;QACZ,IAAI;QACJ,GAAG;QACH,YAAY;QACZ,oBAAoB;QACpB,aAAa;QACb,cAAc;QACd,MAAM;QACN,mBAAmB;QACnB,cAAc;QACd,kBAAkB;QAClB,wBAAwB;QACxB,uBAAuB;QACvB,iBAAiB;QACjB,oBAAoB;KACrB,CAAC,CAAC;IAEH,MAAM,kBAAkB,GAAG,WAAW,CACpC,CAAC,UAAkB,EAAE,EAAE;QACrB,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACvD,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC;QAEjD,IAAI,eAAe,CAAC,OAAO,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;YACnE,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,KAAK,GAAG,CAAC;QACtE,IAAI,cAAc,GAAG,UAAU,CAAC;QAChC,IAAI,OAAO,EAAE,CAAC;YACZ,4FAA4F;YAC5F,IACE,eAAe,CAAC,OAAO,KAAK,aAAa,CAAC,OAAO;gBACjD,eAAe,CAAC,OAAO,GAAG,YAAY,GAAG,CAAC;gBAC1C,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,eAAe,CAAC,OAAO,GAAG,CAAC,CAAC,KAAK,GAAG,EACpE,CAAC;gBACD,cAAc,GAAG,GAAG,GAAG,cAAc,CAAC;YACxC,CAAC;QACH,CAAC;QAED,cAAc,IAAI,GAAG,CAAC;QAEtB,MAAM,CAAC,oBAAoB,CACzB,kBAAkB,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,eAAe,CAAC,OAAO,CAAC,EACpE,kBAAkB,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC,EAClE,cAAc,CACf,CAAC;IACJ,CAAC,EACD,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,CAAC,CAC/C,CAAC;IAEF,OAAO;QACL,WAAW;QACX,qBAAqB;QACrB,iBAAiB;QACjB,eAAe;QACf,oBAAoB;QACpB,cAAc;QACd,wBAAwB;QACxB,kBAAkB;QAClB,oBAAoB;QACpB,UAAU;QACV,YAAY;QACZ,kBAAkB;KACnB,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"useCommandCompletion.js","sourceRoot":"","sources":["../../../../src/ui/hooks/useCommandCompletion.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGxD,OAAO,EACL,kBAAkB,GAEnB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,CAAN,IAAY,cAIX;AAJD,WAAY,cAAc;IACxB,+BAAa,CAAA;IACb,2BAAS,CAAA;IACT,iCAAe,CAAA;AACjB,CAAC,EAJW,cAAc,KAAd,cAAc,QAIzB;AAiBD,MAAM,UAAU,oBAAoB,CAClC,MAAkB,EAClB,IAAuB,EACvB,GAAW,EACX,aAAsC,EACtC,cAA8B,EAC9B,sBAA+B,KAAK,EACpC,MAAe;IAEf,MAAM,EACJ,WAAW,EACX,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,cAAc,EAEd,cAAc,EACd,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EAEpB,oBAAoB,EACpB,UAAU,EACV,YAAY,GACb,GAAG,aAAa,EAAE,CAAC;IAEpB,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAEnC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,GAC7D,OAAO,CAAC,GAAG,EAAE;QACX,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAClD,IAAI,SAAS,KAAK,CAAC,IAAI,cAAc,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC1D,OAAO;gBACL,cAAc,EAAE,cAAc,CAAC,KAAK;gBACpC,KAAK,EAAE,WAAW;gBAClB,eAAe,EAAE,CAAC;gBAClB,aAAa,EAAE,WAAW,CAAC,MAAM;aAClC,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;QAC7C,KAAK,IAAI,CAAC,GAAG,SAAS,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAE3B,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACjB,IAAI,cAAc,GAAG,CAAC,CAAC;gBACvB,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC1D,cAAc,EAAE,CAAC;gBACnB,CAAC;gBACD,IAAI,cAAc,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC7B,OAAO;wBACL,cAAc,EAAE,cAAc,CAAC,IAAI;wBACnC,KAAK,EAAE,IAAI;wBACX,eAAe,EAAE,CAAC,CAAC;wBACnB,aAAa,EAAE,CAAC,CAAC;qBAClB,CAAC;gBACJ,CAAC;YACH,CAAC;iBAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACxB,IAAI,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC;gBAC5B,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACnD,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;wBAC1B,IAAI,cAAc,GAAG,CAAC,CAAC;wBACvB,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;4BAC1D,cAAc,EAAE,CAAC;wBACnB,CAAC;wBAED,IAAI,cAAc,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;4BAC7B,GAAG,GAAG,CAAC,CAAC;4BACR,MAAM;wBACR,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC;gBACxB,MAAM,WAAW,GAAG,WAAW,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;gBAC1D,OAAO;oBACL,cAAc,EAAE,cAAc,CAAC,EAAE;oBACjC,KAAK,EAAE,WAAW;oBAClB,eAAe,EAAE,SAAS;oBAC1B,aAAa,EAAE,GAAG;iBACnB,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO;YACL,cAAc,EAAE,cAAc,CAAC,IAAI;YACnC,KAAK,EAAE,IAAI;YACX,eAAe,EAAE,CAAC,CAAC;YACnB,aAAa,EAAE,CAAC,CAAC;SAClB,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAE3C,eAAe,CAAC;QACd,OAAO,EAAE,cAAc,KAAK,cAAc,CAAC,EAAE;QAC7C,OAAO,EAAE,KAAK,IAAI,EAAE;QACpB,MAAM;QACN,GAAG;QACH,cAAc;QACd,uBAAuB;KACxB,CAAC,CAAC;IAEH,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;QAC9C,OAAO,EAAE,cAAc,KAAK,cAAc,CAAC,KAAK;QAChD,KAAK;QACL,aAAa;QACb,cAAc;QACd,cAAc;QACd,uBAAuB;QACvB,iBAAiB;KAClB,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,wBAAwB,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,oBAAoB,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC,EAAE,CAAC,WAAW,EAAE,wBAAwB,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAElE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,cAAc,KAAK,cAAc,CAAC,IAAI,IAAI,mBAAmB,EAAE,CAAC;YAClE,oBAAoB,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QACD,yEAAyE;QACzE,kBAAkB,CAAC,oBAAoB,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrE,CAAC,EAAE;QACD,cAAc;QACd,WAAW,CAAC,MAAM;QAClB,oBAAoB;QACpB,mBAAmB;QACnB,oBAAoB;QACpB,kBAAkB;KACnB,CAAC,CAAC;IAEH,MAAM,kBAAkB,GAAG,WAAW,CACpC,CAAC,UAAkB,EAAE,EAAE;QACrB,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACvD,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC;QAEjD,IAAI,KAAK,GAAG,eAAe,CAAC;QAC5B,IAAI,GAAG,GAAG,aAAa,CAAC;QACxB,IAAI,cAAc,KAAK,cAAc,CAAC,KAAK,EAAE,CAAC;YAC5C,KAAK,GAAG,oBAAoB,CAAC,eAAe,CAAC;YAC7C,GAAG,GAAG,oBAAoB,CAAC,aAAa,CAAC;QAC3C,CAAC;QAED,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,IAAI,cAAc,GAAG,UAAU,CAAC;QAChC,IAAI,cAAc,KAAK,cAAc,CAAC,KAAK,EAAE,CAAC;YAC5C,IACE,KAAK,KAAK,GAAG;gBACb,KAAK,GAAG,CAAC;gBACT,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,EAClD,CAAC;gBACD,cAAc,GAAG,GAAG,GAAG,cAAc,CAAC;YACxC,CAAC;QACH,CAAC;QAED,cAAc,IAAI,GAAG,CAAC;QAEtB,MAAM,CAAC,oBAAoB,CACzB,kBAAkB,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,EAClD,kBAAkB,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,EAChD,cAAc,CACf,CAAC;IACJ,CAAC,EACD;QACE,SAAS;QACT,MAAM;QACN,WAAW;QACX,cAAc;QACd,eAAe;QACf,aAAa;QACb,oBAAoB;KACrB,CACF,CAAC;IAEF,OAAO;QACL,WAAW;QACX,qBAAqB;QACrB,iBAAiB;QACjB,eAAe;QACf,oBAAoB;QACpB,cAAc;QACd,wBAAwB;QACxB,kBAAkB;QAClB,oBAAoB;QACpB,UAAU;QACV,YAAY;QACZ,kBAAkB;KACnB,CAAC;AACJ,CAAC"}
|
|
@@ -12,7 +12,7 @@ export declare function mergePartListUnions(list: PartListUnion[]): PartListUnio
|
|
|
12
12
|
* Manages the Gemini stream, including user input, command processing,
|
|
13
13
|
* API interaction, and tool call lifecycle.
|
|
14
14
|
*/
|
|
15
|
-
export declare const useGeminiStream: (geminiClient: GeminiClient, history: HistoryItem[], addItem: UseHistoryManagerReturn["addItem"], config: Config, onDebugMessage: (message: string) => void, handleSlashCommand: (cmd: PartListUnion) => Promise<SlashCommandProcessorResult | false>, shellModeActive: boolean, getPreferredEditor: () => EditorType | undefined, onAuthError: () => void, performMemoryRefresh: () => Promise<void>, modelSwitchedFromQuotaError: boolean, setModelSwitchedFromQuotaError: React.Dispatch<React.SetStateAction<boolean
|
|
15
|
+
export declare const useGeminiStream: (geminiClient: GeminiClient, history: HistoryItem[], addItem: UseHistoryManagerReturn["addItem"], config: Config, onDebugMessage: (message: string) => void, handleSlashCommand: (cmd: PartListUnion) => Promise<SlashCommandProcessorResult | false>, shellModeActive: boolean, getPreferredEditor: () => EditorType | undefined, onAuthError: () => void, performMemoryRefresh: () => Promise<void>, modelSwitchedFromQuotaError: boolean, setModelSwitchedFromQuotaError: React.Dispatch<React.SetStateAction<boolean>>, onEditorClose: () => void) => {
|
|
16
16
|
streamingState: StreamingState;
|
|
17
17
|
submitQuery: (query: PartListUnion, options?: {
|
|
18
18
|
isContinuation: boolean;
|
|
@@ -41,10 +41,11 @@ var StreamProcessingStatus;
|
|
|
41
41
|
* Manages the Gemini stream, including user input, command processing,
|
|
42
42
|
* API interaction, and tool call lifecycle.
|
|
43
43
|
*/
|
|
44
|
-
export const useGeminiStream = (geminiClient, history, addItem, config, onDebugMessage, handleSlashCommand, shellModeActive, getPreferredEditor, onAuthError, performMemoryRefresh, modelSwitchedFromQuotaError, setModelSwitchedFromQuotaError) => {
|
|
44
|
+
export const useGeminiStream = (geminiClient, history, addItem, config, onDebugMessage, handleSlashCommand, shellModeActive, getPreferredEditor, onAuthError, performMemoryRefresh, modelSwitchedFromQuotaError, setModelSwitchedFromQuotaError, onEditorClose) => {
|
|
45
45
|
const [initError, setInitError] = useState(null);
|
|
46
46
|
const abortControllerRef = useRef(null);
|
|
47
47
|
const turnCancelledRef = useRef(false);
|
|
48
|
+
const isSubmittingQueryRef = useRef(false);
|
|
48
49
|
const [isResponding, setIsResponding] = useState(false);
|
|
49
50
|
const [thought, setThought] = useState(null);
|
|
50
51
|
const [pendingHistoryItemRef, setPendingHistoryItem] = useStateAndRef(null);
|
|
@@ -65,7 +66,7 @@ export const useGeminiStream = (geminiClient, history, addItem, config, onDebugM
|
|
|
65
66
|
// Handle tool response submission immediately when tools complete
|
|
66
67
|
await handleCompletedTools(completedToolCallsFromScheduler);
|
|
67
68
|
}
|
|
68
|
-
}, config, setPendingHistoryItem, getPreferredEditor);
|
|
69
|
+
}, config, setPendingHistoryItem, getPreferredEditor, onEditorClose);
|
|
69
70
|
const pendingToolCallGroupDisplay = useMemo(() => toolCalls.length ? mapTrackedToolCallsToDisplay(toolCalls) : undefined, [toolCalls]);
|
|
70
71
|
const loopDetectedRef = useRef(false);
|
|
71
72
|
const onExec = useCallback(async (done) => {
|
|
@@ -393,10 +394,16 @@ export const useGeminiStream = (geminiClient, history, addItem, config, onDebugM
|
|
|
393
394
|
handleSessionTokenLimitExceededEvent,
|
|
394
395
|
]);
|
|
395
396
|
const submitQuery = useCallback(async (query, options, prompt_id) => {
|
|
397
|
+
// Prevent concurrent executions of submitQuery
|
|
398
|
+
if (isSubmittingQueryRef.current) {
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
396
401
|
if ((streamingState === StreamingState.Responding ||
|
|
397
402
|
streamingState === StreamingState.WaitingForConfirmation) &&
|
|
398
403
|
!options?.isContinuation)
|
|
399
404
|
return;
|
|
405
|
+
// Set the flag to indicate we're now executing
|
|
406
|
+
isSubmittingQueryRef.current = true;
|
|
400
407
|
const userMessageTimestamp = Date.now();
|
|
401
408
|
// Reset quota error flag when starting a new query (not a continuation)
|
|
402
409
|
if (!options?.isContinuation) {
|
|
@@ -411,6 +418,7 @@ export const useGeminiStream = (geminiClient, history, addItem, config, onDebugM
|
|
|
411
418
|
}
|
|
412
419
|
const { queryToSend, shouldProceed } = await prepareQueryForGemini(query, userMessageTimestamp, abortSignal, prompt_id);
|
|
413
420
|
if (!shouldProceed || queryToSend === null) {
|
|
421
|
+
isSubmittingQueryRef.current = false;
|
|
414
422
|
return;
|
|
415
423
|
}
|
|
416
424
|
if (!options?.isContinuation) {
|
|
@@ -423,6 +431,7 @@ export const useGeminiStream = (geminiClient, history, addItem, config, onDebugM
|
|
|
423
431
|
const stream = geminiClient.sendMessageStream(queryToSend, abortSignal, prompt_id);
|
|
424
432
|
const processingStatus = await processGeminiStreamEvents(stream, userMessageTimestamp, abortSignal);
|
|
425
433
|
if (processingStatus === StreamProcessingStatus.UserCancelled) {
|
|
434
|
+
isSubmittingQueryRef.current = false;
|
|
426
435
|
return;
|
|
427
436
|
}
|
|
428
437
|
if (pendingHistoryItemRef.current) {
|
|
@@ -447,6 +456,7 @@ export const useGeminiStream = (geminiClient, history, addItem, config, onDebugM
|
|
|
447
456
|
}
|
|
448
457
|
finally {
|
|
449
458
|
setIsResponding(false);
|
|
459
|
+
isSubmittingQueryRef.current = false;
|
|
450
460
|
}
|
|
451
461
|
}, [
|
|
452
462
|
streamingState,
|