@wonderwhy-er/desktop-commander 0.2.43 → 0.2.45
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/bootstrap.d.ts +1 -0
- package/dist/bootstrap.js +22 -0
- package/dist/config-manager.d.ts +30 -1
- package/dist/config-manager.js +55 -8
- package/dist/handlers/filesystem-handlers.js +86 -53
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -0
- package/dist/remote-device/desktop-commander-integration.js +8 -2
- package/dist/remote-device/remote-channel.d.ts +1 -0
- package/dist/remote-device/remote-channel.js +34 -4
- package/dist/server.js +63 -22
- package/dist/tools/edit.d.ts +1 -1
- package/dist/tools/edit.js +30 -23
- package/dist/tools/filesystem.d.ts +1 -0
- package/dist/tools/filesystem.js +23 -13
- package/dist/tools/schemas.d.ts +19 -7
- package/dist/tools/schemas.js +20 -5
- package/dist/ui/config-editor/config-editor-runtime.js +49 -49
- package/dist/ui/config-editor/src/app.js +2 -11
- package/dist/ui/file-preview/preview-runtime.js +147 -146
- package/dist/ui/file-preview/src/app.js +172 -53
- package/dist/ui/file-preview/src/directory-controller.js +1 -1
- package/dist/ui/file-preview/src/markdown/controller.js +1 -0
- package/dist/ui/file-preview/src/panel-actions.js +2 -2
- package/dist/ui/file-preview/src/payload-utils.js +23 -7
- package/dist/utils/capture.d.ts +2 -0
- package/dist/utils/capture.js +19 -0
- package/dist/utils/files/base.d.ts +2 -0
- package/dist/utils/files/image.js +1 -1
- package/dist/utils/files/text.js +24 -19
- package/dist/utils/open-browser.d.ts +1 -1
- package/dist/utils/open-browser.js +5 -2
- package/dist/utils/usageTracker.d.ts +5 -1
- package/dist/utils/usageTracker.js +14 -3
- package/dist/utils/welcome-onboarding.d.ts +1 -1
- package/dist/utils/welcome-onboarding.js +2 -2
- package/dist/utils/withTimeout.d.ts +17 -0
- package/dist/utils/withTimeout.js +33 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/tools/edit.js
CHANGED
|
@@ -82,7 +82,7 @@ function getCharacterCodeData(expected, actual) {
|
|
|
82
82
|
diffLength: fullDiff.length
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
export async function performSearchReplace(filePath, block, expectedReplacements = 1) {
|
|
85
|
+
export async function performSearchReplace(filePath, block, expectedReplacements = 1, origin) {
|
|
86
86
|
// Get file extension for telemetry using path module
|
|
87
87
|
const fileExtension = path.extname(filePath).toLowerCase();
|
|
88
88
|
// Capture file extension and string sizes in telemetry without capturing the file path
|
|
@@ -176,13 +176,18 @@ RECOMMENDATION: For large search/replace operations, consider breaking them into
|
|
|
176
176
|
type: "text",
|
|
177
177
|
text: `${statusLine}${previewContent}`
|
|
178
178
|
}],
|
|
179
|
-
structuredContent:
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
179
|
+
// structuredContent only travels on widget-initiated calls: it is the
|
|
180
|
+
// widget's save-success signal (assertSuccessfulEditBlockResult) and
|
|
181
|
+
// metadata source. LLM-facing responses don't need it — nothing there
|
|
182
|
+
// consumes it, and the widget re-reads by path instead.
|
|
183
|
+
...(origin === 'ui' ? {
|
|
184
|
+
structuredContent: {
|
|
185
|
+
fileName: path.basename(resolvedEditPath),
|
|
186
|
+
filePath: resolvedEditPath,
|
|
187
|
+
fileType: resolvePreviewFileType(resolvedEditPath),
|
|
188
|
+
...await getDefaultEditorMetadata(resolvedEditPath),
|
|
189
|
+
},
|
|
190
|
+
} : {}),
|
|
186
191
|
};
|
|
187
192
|
}
|
|
188
193
|
// If exact match found but count doesn't match expected, inform the user
|
|
@@ -367,13 +372,14 @@ export async function handleEditBlock(args) {
|
|
|
367
372
|
type: "text",
|
|
368
373
|
text: `Successfully updated range ${parsed.range} in ${parsed.file_path}`
|
|
369
374
|
}],
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
375
|
+
...(parsed.origin === 'ui' ? {
|
|
376
|
+
structuredContent: {
|
|
377
|
+
fileName: path.basename(resolvedRangePath),
|
|
378
|
+
filePath: resolvedRangePath,
|
|
379
|
+
fileType: resolvePreviewFileType(resolvedRangePath),
|
|
380
|
+
...await getDefaultEditorMetadata(resolvedRangePath),
|
|
381
|
+
},
|
|
382
|
+
} : {}),
|
|
377
383
|
};
|
|
378
384
|
}
|
|
379
385
|
catch (error) {
|
|
@@ -404,13 +410,14 @@ export async function handleEditBlock(args) {
|
|
|
404
410
|
type: "text",
|
|
405
411
|
text: `Successfully applied ${result.editsApplied} edit(s) to ${parsed.file_path}`
|
|
406
412
|
}],
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
413
|
+
...(parsed.origin === 'ui' ? {
|
|
414
|
+
structuredContent: {
|
|
415
|
+
fileName: path.basename(resolvedEditRangePath),
|
|
416
|
+
filePath: resolvedEditRangePath,
|
|
417
|
+
fileType: resolvePreviewFileType(resolvedEditRangePath),
|
|
418
|
+
...await getDefaultEditorMetadata(resolvedEditRangePath),
|
|
419
|
+
},
|
|
420
|
+
} : {}),
|
|
414
421
|
};
|
|
415
422
|
}
|
|
416
423
|
const errorMsg = result.errors?.map(e => e.error).join('; ') || 'Unknown error';
|
|
@@ -424,5 +431,5 @@ export async function handleEditBlock(args) {
|
|
|
424
431
|
return performSearchReplace(parsed.file_path, {
|
|
425
432
|
search: parsed.old_string,
|
|
426
433
|
replace: parsed.new_string
|
|
427
|
-
}, parsed.expected_replacements);
|
|
434
|
+
}, parsed.expected_replacements, parsed.origin);
|
|
428
435
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReadOptions, FileResult, PdfPageItem } from '../utils/files/base.js';
|
|
2
2
|
import { PdfOperations, PdfMetadata } from './pdf/index.js';
|
|
3
|
+
export declare const READ_OPERATION_TIMEOUT_MS: number;
|
|
3
4
|
/**
|
|
4
5
|
* Validates a path to ensure it can be accessed or created.
|
|
5
6
|
* For existing paths, returns the real path (resolving symlinks).
|
package/dist/tools/filesystem.js
CHANGED
|
@@ -5,7 +5,7 @@ import fetch from 'cross-fetch';
|
|
|
5
5
|
import { execFile } from 'child_process';
|
|
6
6
|
import { promisify } from 'util';
|
|
7
7
|
import { capture } from '../utils/capture.js';
|
|
8
|
-
import { withTimeout } from '../utils/withTimeout.js';
|
|
8
|
+
import { withTimeout, runWithAbortableTimeout } from '../utils/withTimeout.js';
|
|
9
9
|
import { configManager } from '../config-manager.js';
|
|
10
10
|
import { getFileHandler, TextFileHandler } from '../utils/files/index.js';
|
|
11
11
|
import { isPdfFile } from "./mime-types.js";
|
|
@@ -16,6 +16,13 @@ const FILE_OPERATION_TIMEOUTS = {
|
|
|
16
16
|
URL_FETCH: 30000, // 30 seconds
|
|
17
17
|
FILE_READ: 30000, // 30 seconds
|
|
18
18
|
};
|
|
19
|
+
// Cap file read operations at 3 minutes. The MCP client's hard per-call limit
|
|
20
|
+
// is ~4 minutes; timing out at 3m lets us abort the underlying fs op and return
|
|
21
|
+
// a useful error (e.g. the cloud-storage guidance in buildPermissionError)
|
|
22
|
+
// BEFORE the client gives up with an opaque "No result received after 4
|
|
23
|
+
// minutes". Paired with runWithAbortableTimeout so the read is actually
|
|
24
|
+
// cancelled (fd/thread released), not just abandoned.
|
|
25
|
+
export const READ_OPERATION_TIMEOUT_MS = 3 * 60 * 1000; // 3 minutes
|
|
19
26
|
const FILE_SIZE_LIMITS = {
|
|
20
27
|
LINE_COUNT_LIMIT: 10 * 1024 * 1024, // 10MB for line counting
|
|
21
28
|
};
|
|
@@ -426,8 +433,9 @@ export async function readFileFromDisk(filePath, options) {
|
|
|
426
433
|
capture('server_read_file_error', { error: errorMessage, fileExtension: fileExtension });
|
|
427
434
|
// If we can't stat the file, continue anyway and let the read operation handle errors
|
|
428
435
|
}
|
|
429
|
-
//
|
|
430
|
-
|
|
436
|
+
// Read under an abortable timeout so a hung/stalled read is cancelled
|
|
437
|
+
// (fd/thread freed) rather than leaked until the OS call returns.
|
|
438
|
+
const readOperation = async (signal) => {
|
|
431
439
|
// Get appropriate handler for this file type (async - includes binary detection)
|
|
432
440
|
const handler = await getFileHandler(validPath);
|
|
433
441
|
// Use handler to read the file
|
|
@@ -436,7 +444,8 @@ export async function readFileFromDisk(filePath, options) {
|
|
|
436
444
|
length,
|
|
437
445
|
sheet,
|
|
438
446
|
range,
|
|
439
|
-
includeStatusMessage: true
|
|
447
|
+
includeStatusMessage: true,
|
|
448
|
+
signal
|
|
440
449
|
});
|
|
441
450
|
// Return with content as string
|
|
442
451
|
// For images: content is already base64-encoded string from handler
|
|
@@ -458,18 +467,17 @@ export async function readFileFromDisk(filePath, options) {
|
|
|
458
467
|
metadata: result.metadata
|
|
459
468
|
};
|
|
460
469
|
};
|
|
461
|
-
// Execute with timeout
|
|
470
|
+
// Execute with a 3-minute, cancellable timeout
|
|
462
471
|
let result;
|
|
463
472
|
try {
|
|
464
|
-
result = await
|
|
473
|
+
result = await runWithAbortableTimeout((signal) => readOperation(signal), READ_OPERATION_TIMEOUT_MS, `Read file operation for ${filePath}`);
|
|
465
474
|
}
|
|
466
475
|
catch (error) {
|
|
467
476
|
const err = error;
|
|
468
|
-
//
|
|
469
|
-
//
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
throw buildPermissionError(filePath, isWithTimeoutString ? 'ETIMEDOUT' : err.code);
|
|
477
|
+
// runWithAbortableTimeout rejects with an Error whose .code is 'ETIMEDOUT'
|
|
478
|
+
// on timeout; fs rejects with EPERM/EACCES. Map all to the guidance error.
|
|
479
|
+
if (err.code === 'EPERM' || err.code === 'EACCES' || err.code === 'ETIMEDOUT') {
|
|
480
|
+
throw buildPermissionError(filePath, err.code);
|
|
473
481
|
}
|
|
474
482
|
throw error;
|
|
475
483
|
}
|
|
@@ -515,8 +523,10 @@ export async function readFileInternal(filePath, offset = 0, length) {
|
|
|
515
523
|
// IMPORTANT: For internal operations (especially edit operations), we must
|
|
516
524
|
// preserve exact file content including original line endings.
|
|
517
525
|
// We cannot use readline-based reading as it strips line endings.
|
|
518
|
-
// Read entire file content preserving line endings
|
|
519
|
-
|
|
526
|
+
// Read entire file content preserving line endings, under a 3-minute,
|
|
527
|
+
// cancellable timeout so an edit on a stalled/cloud path can't hang forever
|
|
528
|
+
// (previously this read had no timeout at all).
|
|
529
|
+
const content = await runWithAbortableTimeout((signal) => fs.readFile(validPath, { encoding: 'utf8', signal }), READ_OPERATION_TIMEOUT_MS, `Internal read for ${filePath}`);
|
|
520
530
|
// If we need to apply offset/length, do it while preserving line endings
|
|
521
531
|
if (offset === 0 && length >= Number.MAX_SAFE_INTEGER) {
|
|
522
532
|
// Most common case for edit operations: read entire file
|
package/dist/tools/schemas.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
export declare const GetConfigArgsSchema: z.ZodObject<{
|
|
2
|
+
export declare const GetConfigArgsSchema: z.ZodObject<{
|
|
3
|
+
origin: z.ZodOptional<z.ZodEnum<["ui", "llm"]>>;
|
|
4
|
+
}, "strip", z.ZodTypeAny, {
|
|
5
|
+
origin?: "ui" | "llm" | undefined;
|
|
6
|
+
}, {
|
|
7
|
+
origin?: "ui" | "llm" | undefined;
|
|
8
|
+
}>;
|
|
3
9
|
export declare const SetConfigValueArgsSchema: z.ZodObject<{
|
|
4
10
|
key: z.ZodString;
|
|
5
11
|
value: z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodArray<z.ZodString, "many">, z.ZodNull]>;
|
|
@@ -19,14 +25,17 @@ export declare const StartProcessArgsSchema: z.ZodObject<{
|
|
|
19
25
|
timeout_ms: z.ZodNumber;
|
|
20
26
|
shell: z.ZodOptional<z.ZodString>;
|
|
21
27
|
verbose_timing: z.ZodOptional<z.ZodBoolean>;
|
|
28
|
+
origin: z.ZodOptional<z.ZodEnum<["ui", "llm"]>>;
|
|
22
29
|
}, "strip", z.ZodTypeAny, {
|
|
23
30
|
command: string;
|
|
24
31
|
timeout_ms: number;
|
|
32
|
+
origin?: "ui" | "llm" | undefined;
|
|
25
33
|
shell?: string | undefined;
|
|
26
34
|
verbose_timing?: boolean | undefined;
|
|
27
35
|
}, {
|
|
28
36
|
command: string;
|
|
29
37
|
timeout_ms: number;
|
|
38
|
+
origin?: "ui" | "llm" | undefined;
|
|
30
39
|
shell?: string | undefined;
|
|
31
40
|
verbose_timing?: boolean | undefined;
|
|
32
41
|
}>;
|
|
@@ -78,15 +87,15 @@ export declare const ReadFileArgsSchema: z.ZodObject<{
|
|
|
78
87
|
path: string;
|
|
79
88
|
offset: number;
|
|
80
89
|
isUrl: boolean;
|
|
81
|
-
options?: Record<string, any> | undefined;
|
|
82
90
|
origin?: "ui" | "llm" | undefined;
|
|
91
|
+
options?: Record<string, any> | undefined;
|
|
83
92
|
sheet?: string | undefined;
|
|
84
93
|
range?: string | undefined;
|
|
85
94
|
}, {
|
|
86
95
|
path: string;
|
|
87
96
|
length?: number | undefined;
|
|
88
|
-
options?: Record<string, any> | undefined;
|
|
89
97
|
origin?: "ui" | "llm" | undefined;
|
|
98
|
+
options?: Record<string, any> | undefined;
|
|
90
99
|
offset?: number | undefined;
|
|
91
100
|
isUrl?: boolean | undefined;
|
|
92
101
|
sheet?: string | undefined;
|
|
@@ -282,16 +291,16 @@ export declare const EditBlockArgsSchema: z.ZodEffects<z.ZodObject<{
|
|
|
282
291
|
}, "strip", z.ZodTypeAny, {
|
|
283
292
|
file_path: string;
|
|
284
293
|
expected_replacements: number;
|
|
285
|
-
options?: Record<string, any> | undefined;
|
|
286
294
|
origin?: "ui" | "llm" | undefined;
|
|
295
|
+
options?: Record<string, any> | undefined;
|
|
287
296
|
range?: string | undefined;
|
|
288
297
|
content?: any;
|
|
289
298
|
old_string?: string | undefined;
|
|
290
299
|
new_string?: string | undefined;
|
|
291
300
|
}, {
|
|
292
301
|
file_path: string;
|
|
293
|
-
options?: Record<string, any> | undefined;
|
|
294
302
|
origin?: "ui" | "llm" | undefined;
|
|
303
|
+
options?: Record<string, any> | undefined;
|
|
295
304
|
range?: string | undefined;
|
|
296
305
|
content?: any;
|
|
297
306
|
old_string?: string | undefined;
|
|
@@ -300,16 +309,16 @@ export declare const EditBlockArgsSchema: z.ZodEffects<z.ZodObject<{
|
|
|
300
309
|
}>, {
|
|
301
310
|
file_path: string;
|
|
302
311
|
expected_replacements: number;
|
|
303
|
-
options?: Record<string, any> | undefined;
|
|
304
312
|
origin?: "ui" | "llm" | undefined;
|
|
313
|
+
options?: Record<string, any> | undefined;
|
|
305
314
|
range?: string | undefined;
|
|
306
315
|
content?: any;
|
|
307
316
|
old_string?: string | undefined;
|
|
308
317
|
new_string?: string | undefined;
|
|
309
318
|
}, {
|
|
310
319
|
file_path: string;
|
|
311
|
-
options?: Record<string, any> | undefined;
|
|
312
320
|
origin?: "ui" | "llm" | undefined;
|
|
321
|
+
options?: Record<string, any> | undefined;
|
|
313
322
|
range?: string | undefined;
|
|
314
323
|
content?: any;
|
|
315
324
|
old_string?: string | undefined;
|
|
@@ -349,6 +358,7 @@ export declare const StartSearchArgsSchema: z.ZodObject<{
|
|
|
349
358
|
timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
350
359
|
earlyTermination: z.ZodOptional<z.ZodBoolean>;
|
|
351
360
|
literalSearch: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
361
|
+
origin: z.ZodOptional<z.ZodEnum<["ui", "llm"]>>;
|
|
352
362
|
}, "strip", z.ZodTypeAny, {
|
|
353
363
|
path: string;
|
|
354
364
|
pattern: string;
|
|
@@ -357,6 +367,7 @@ export declare const StartSearchArgsSchema: z.ZodObject<{
|
|
|
357
367
|
includeHidden: boolean;
|
|
358
368
|
contextLines: number;
|
|
359
369
|
literalSearch: boolean;
|
|
370
|
+
origin?: "ui" | "llm" | undefined;
|
|
360
371
|
timeout_ms?: number | undefined;
|
|
361
372
|
filePattern?: string | undefined;
|
|
362
373
|
maxResults?: number | undefined;
|
|
@@ -364,6 +375,7 @@ export declare const StartSearchArgsSchema: z.ZodObject<{
|
|
|
364
375
|
}, {
|
|
365
376
|
path: string;
|
|
366
377
|
pattern: string;
|
|
378
|
+
origin?: "ui" | "llm" | undefined;
|
|
367
379
|
timeout_ms?: number | undefined;
|
|
368
380
|
searchType?: "content" | "files" | undefined;
|
|
369
381
|
filePattern?: string | undefined;
|
package/dist/tools/schemas.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
// Config tools schemas
|
|
3
|
-
export const GetConfigArgsSchema = z.object({
|
|
3
|
+
export const GetConfigArgsSchema = z.object({
|
|
4
|
+
// 'ui' marks calls the config-editor widget fires programmatically; they are
|
|
5
|
+
// excluded from tool-call telemetry (see isUiOriginCall in server.ts).
|
|
6
|
+
origin: z.enum(['ui', 'llm']).optional(),
|
|
7
|
+
});
|
|
4
8
|
export const SetConfigValueArgsSchema = z.object({
|
|
5
9
|
key: z.string(),
|
|
6
10
|
value: z.union([
|
|
@@ -10,6 +14,7 @@ export const SetConfigValueArgsSchema = z.object({
|
|
|
10
14
|
z.array(z.string()),
|
|
11
15
|
z.null(),
|
|
12
16
|
]),
|
|
17
|
+
// 'ui' marks widget-fired calls; excluded from tool-call telemetry.
|
|
13
18
|
origin: z.enum(['ui', 'llm']).optional(),
|
|
14
19
|
});
|
|
15
20
|
// Empty schemas
|
|
@@ -20,6 +25,9 @@ export const StartProcessArgsSchema = z.object({
|
|
|
20
25
|
timeout_ms: z.number(),
|
|
21
26
|
shell: z.string().optional(),
|
|
22
27
|
verbose_timing: z.boolean().optional(),
|
|
28
|
+
// 'ui' marks widget-fired calls (e.g. open-in-folder/editor buttons);
|
|
29
|
+
// excluded from tool-call telemetry (see isUiOriginCall in server.ts).
|
|
30
|
+
origin: z.enum(['ui', 'llm']).optional(),
|
|
23
31
|
});
|
|
24
32
|
export const ReadProcessOutputArgsSchema = z.object({
|
|
25
33
|
pid: z.number(),
|
|
@@ -45,7 +53,8 @@ export const ReadFileArgsSchema = z.object({
|
|
|
45
53
|
range: z.string().optional(),
|
|
46
54
|
options: z.record(z.any()).optional(),
|
|
47
55
|
// Whether the call came from the file-preview UI (refresh/navigation) or the
|
|
48
|
-
// LLM.
|
|
56
|
+
// LLM. 'ui' calls are excluded from tool-call telemetry; see isUiOriginCall
|
|
57
|
+
// in server.ts.
|
|
49
58
|
origin: z.enum(['ui', 'llm']).optional(),
|
|
50
59
|
});
|
|
51
60
|
export const ReadMultipleFilesArgsSchema = z.object({
|
|
@@ -55,7 +64,8 @@ export const WriteFileArgsSchema = z.object({
|
|
|
55
64
|
path: z.string(),
|
|
56
65
|
content: z.string(),
|
|
57
66
|
mode: z.enum(['rewrite', 'append']).default('rewrite'),
|
|
58
|
-
//
|
|
67
|
+
// 'ui' when fired by the file-preview UI, else 'llm'. 'ui' calls are
|
|
68
|
+
// excluded from tool-call telemetry; see isUiOriginCall in server.ts.
|
|
59
69
|
origin: z.enum(['ui', 'llm']).optional(),
|
|
60
70
|
});
|
|
61
71
|
// PDF modification schemas - exported for reuse
|
|
@@ -97,7 +107,8 @@ export const CreateDirectoryArgsSchema = z.object({
|
|
|
97
107
|
export const ListDirectoryArgsSchema = z.object({
|
|
98
108
|
path: z.string(),
|
|
99
109
|
depth: z.number().optional().default(2),
|
|
100
|
-
//
|
|
110
|
+
// 'ui' when fired by the file-preview UI, else 'llm'. 'ui' calls are
|
|
111
|
+
// excluded from tool-call telemetry; see isUiOriginCall in server.ts.
|
|
101
112
|
origin: z.enum(['ui', 'llm']).optional(),
|
|
102
113
|
});
|
|
103
114
|
export const MoveFileArgsSchema = z.object({
|
|
@@ -122,7 +133,8 @@ export const EditBlockArgsSchema = z.object({
|
|
|
122
133
|
range: z.string().optional(),
|
|
123
134
|
content: z.any().optional(),
|
|
124
135
|
options: z.record(z.any()).optional(),
|
|
125
|
-
//
|
|
136
|
+
// 'ui' when fired by the file-preview UI, else 'llm'. 'ui' calls are
|
|
137
|
+
// excluded from tool-call telemetry; see isUiOriginCall in server.ts.
|
|
126
138
|
origin: z.enum(['ui', 'llm']).optional(),
|
|
127
139
|
}).refine(data => {
|
|
128
140
|
// Helper to check if value is actually provided (not undefined, not empty string)
|
|
@@ -162,6 +174,9 @@ export const StartSearchArgsSchema = z.object({
|
|
|
162
174
|
timeout_ms: z.number().optional(), // Match process naming convention
|
|
163
175
|
earlyTermination: z.boolean().optional(), // Stop search early when exact filename match is found (default: true for files, false for content)
|
|
164
176
|
literalSearch: z.boolean().optional().default(false), // Force literal string matching (-F flag) instead of regex
|
|
177
|
+
// 'ui' marks widget-fired calls (e.g. markdown link-target search);
|
|
178
|
+
// excluded from tool-call telemetry (see isUiOriginCall in server.ts).
|
|
179
|
+
origin: z.enum(['ui', 'llm']).optional(),
|
|
165
180
|
});
|
|
166
181
|
export const GetMoreSearchResultsArgsSchema = z.object({
|
|
167
182
|
sessionId: z.string(),
|