trace-mcp 1.5.4 → 1.6.1
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 +1 -1
- package/dist/cli.js +658 -327
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +272 -16
- package/dist/index.js.map +1 -1
- package/package.json +4 -17
package/dist/index.d.ts
CHANGED
|
@@ -1546,6 +1546,7 @@ declare const TraceMcpConfigSchema: z.ZodObject<{
|
|
|
1546
1546
|
enabled?: boolean | undefined;
|
|
1547
1547
|
debounceMs?: number | undefined;
|
|
1548
1548
|
}>>;
|
|
1549
|
+
children: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
1549
1550
|
}, "strip", z.ZodTypeAny, {
|
|
1550
1551
|
root: string;
|
|
1551
1552
|
db: {
|
|
@@ -1719,6 +1720,7 @@ declare const TraceMcpConfigSchema: z.ZodObject<{
|
|
|
1719
1720
|
exclude?: string[] | undefined;
|
|
1720
1721
|
descriptions?: Record<string, string | Record<string, string>> | undefined;
|
|
1721
1722
|
} | undefined;
|
|
1723
|
+
children?: string[] | undefined;
|
|
1722
1724
|
}, {
|
|
1723
1725
|
root?: string | undefined;
|
|
1724
1726
|
db?: {
|
|
@@ -1892,6 +1894,7 @@ declare const TraceMcpConfigSchema: z.ZodObject<{
|
|
|
1892
1894
|
enabled?: boolean | undefined;
|
|
1893
1895
|
debounceMs?: number | undefined;
|
|
1894
1896
|
} | undefined;
|
|
1897
|
+
children?: string[] | undefined;
|
|
1895
1898
|
}>;
|
|
1896
1899
|
type TraceMcpConfig = z.infer<typeof TraceMcpConfigSchema>;
|
|
1897
1900
|
/**
|
package/dist/index.js
CHANGED
|
@@ -2498,6 +2498,26 @@ function detectWorkspaces(rootPath) {
|
|
|
2498
2498
|
if (composerResult.length > 0) return composerResult;
|
|
2499
2499
|
return [];
|
|
2500
2500
|
}
|
|
2501
|
+
function buildMultiRootWorkspaces(parentDir, childRoots) {
|
|
2502
|
+
const workspaces = [];
|
|
2503
|
+
for (const childRoot of childRoots) {
|
|
2504
|
+
if (!fs2.existsSync(childRoot)) {
|
|
2505
|
+
logger.warn({ childRoot }, "Skipping missing multi-root child directory");
|
|
2506
|
+
continue;
|
|
2507
|
+
}
|
|
2508
|
+
const relPath = path2.relative(parentDir, childRoot).replace(/\\/g, "/");
|
|
2509
|
+
const childName = path2.basename(childRoot);
|
|
2510
|
+
workspaces.push({ name: childName, path: relPath });
|
|
2511
|
+
const subWorkspaces = detectWorkspaces(childRoot);
|
|
2512
|
+
for (const sub of subWorkspaces) {
|
|
2513
|
+
workspaces.push({
|
|
2514
|
+
name: `${childName}/${sub.name}`,
|
|
2515
|
+
path: `${relPath}/${sub.path}`
|
|
2516
|
+
});
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
return workspaces;
|
|
2520
|
+
}
|
|
2501
2521
|
function detectPnpmWorkspaces(rootPath) {
|
|
2502
2522
|
const yamlPath = path2.join(rootPath, "pnpm-workspace.yaml");
|
|
2503
2523
|
if (!fs2.existsSync(yamlPath)) return [];
|
|
@@ -4779,12 +4799,15 @@ var FilePersister = class {
|
|
|
4779
4799
|
}
|
|
4780
4800
|
if (ext.symbols.length > 0) {
|
|
4781
4801
|
const insertedIds = store.insertSymbols(fileId, ext.symbols);
|
|
4782
|
-
const
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4802
|
+
const trigramBySymbolId = /* @__PURE__ */ new Map();
|
|
4803
|
+
for (let i = 0; i < ext.symbols.length; i++) {
|
|
4804
|
+
trigramBySymbolId.set(ext.symbols[i].symbolId, {
|
|
4805
|
+
id: insertedIds[i],
|
|
4806
|
+
name: ext.symbols[i].name,
|
|
4807
|
+
fqn: ext.symbols[i].fqn ?? null
|
|
4808
|
+
});
|
|
4809
|
+
}
|
|
4810
|
+
indexTrigramsBatch(store.db, [...trigramBySymbolId.values()]);
|
|
4788
4811
|
}
|
|
4789
4812
|
if (ext.otherEdges.length > 0) this.storeRawEdges(ext.otherEdges);
|
|
4790
4813
|
if (ext.importEdges.length > 0) {
|
|
@@ -4800,11 +4823,15 @@ var FilePersister = class {
|
|
|
4800
4823
|
for (const fwResult of ext.frameworkExtracts) {
|
|
4801
4824
|
if (fwResult.symbols.length > 0) {
|
|
4802
4825
|
const fwIds = store.insertSymbols(fileId, fwResult.symbols);
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4826
|
+
const fwTrigramBySymbolId = /* @__PURE__ */ new Map();
|
|
4827
|
+
for (let i = 0; i < fwResult.symbols.length; i++) {
|
|
4828
|
+
fwTrigramBySymbolId.set(fwResult.symbols[i].symbolId, {
|
|
4829
|
+
id: fwIds[i],
|
|
4830
|
+
name: fwResult.symbols[i].name,
|
|
4831
|
+
fqn: fwResult.symbols[i].fqn ?? null
|
|
4832
|
+
});
|
|
4833
|
+
}
|
|
4834
|
+
indexTrigramsBatch(store.db, [...fwTrigramBySymbolId.values()]);
|
|
4808
4835
|
}
|
|
4809
4836
|
if (fwResult.edges?.length) {
|
|
4810
4837
|
this.storeRawEdges(fwResult.edges);
|
|
@@ -5902,9 +5929,14 @@ var IndexingPipeline = class _IndexingPipeline {
|
|
|
5902
5929
|
const result = this._lock.then(async () => {
|
|
5903
5930
|
this._isIncremental = false;
|
|
5904
5931
|
const start = Date.now();
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
logger.info({ workspaces: this.workspaces.map((w) => w.name) }, "
|
|
5932
|
+
if (this.config.children?.length) {
|
|
5933
|
+
this.workspaces = buildMultiRootWorkspaces(this.rootPath, this.config.children);
|
|
5934
|
+
logger.info({ workspaces: this.workspaces.map((w) => w.name) }, "Multi-root workspaces");
|
|
5935
|
+
} else {
|
|
5936
|
+
this.workspaces = detectWorkspaces(this.rootPath);
|
|
5937
|
+
if (this.workspaces.length > 0) {
|
|
5938
|
+
logger.info({ workspaces: this.workspaces.map((w) => w.name) }, "Detected workspaces");
|
|
5939
|
+
}
|
|
5908
5940
|
}
|
|
5909
5941
|
const filePaths = await this.collectFiles();
|
|
5910
5942
|
return this.runPipeline(filePaths, force ?? false, start);
|
|
@@ -8036,6 +8068,14 @@ function buildInstructions(detectedFrameworks, verbosity) {
|
|
|
8036
8068
|
"Before creating new functions/classes:",
|
|
8037
8069
|
'- `check_duplication` { name: "functionName", kind: "function" } \u2014 checks if similar symbols already exist. Use BEFORE writing new code to avoid reinventing existing logic.',
|
|
8038
8070
|
"",
|
|
8071
|
+
"Bulk mechanical changes (adding async/await, updating patterns, fixing imports across many files):",
|
|
8072
|
+
"- `apply_codemod` { pattern, replacement, file_pattern } \u2014 regex find-and-replace across files. Dry-run by default (shows preview). Two-step workflow:",
|
|
8073
|
+
" 1. Call with dry_run: true (default) \u2192 review preview with context lines",
|
|
8074
|
+
" 2. Call with dry_run: false \u2192 apply changes. Requires confirm_large: true if >20 files affected.",
|
|
8075
|
+
"- Use `filter_content` to narrow scope to files containing a specific substring.",
|
|
8076
|
+
"- Use `multiline: true` for patterns spanning multiple lines.",
|
|
8077
|
+
"- NEVER use dozens of Edit calls for the same regex replacement \u2014 use apply_codemod instead.",
|
|
8078
|
+
"",
|
|
8039
8079
|
"WHEN TO USE native tools (Read/Grep/Glob):",
|
|
8040
8080
|
"- Non-code files (.md, .json, .yaml, .toml, config) \u2192 Read/Grep",
|
|
8041
8081
|
"- Reading a file before editing (Edit needs full content) \u2192 Read",
|
|
@@ -16974,6 +17014,7 @@ import { z as z6 } from "zod";
|
|
|
16974
17014
|
// src/tools/refactoring/refactor.ts
|
|
16975
17015
|
import fs23 from "fs";
|
|
16976
17016
|
import path35 from "path";
|
|
17017
|
+
import fg4 from "fast-glob";
|
|
16977
17018
|
function readLines2(filePath) {
|
|
16978
17019
|
return fs23.readFileSync(filePath, "utf-8").split("\n");
|
|
16979
17020
|
}
|
|
@@ -17307,6 +17348,193 @@ ${functionDef}`
|
|
|
17307
17348
|
}
|
|
17308
17349
|
return result;
|
|
17309
17350
|
}
|
|
17351
|
+
var CODEMOD_MAX_PREVIEW = 20;
|
|
17352
|
+
var CODEMOD_LARGE_THRESHOLD = 20;
|
|
17353
|
+
var CODEMOD_CONTEXT_LINES = 2;
|
|
17354
|
+
var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
17355
|
+
".png",
|
|
17356
|
+
".jpg",
|
|
17357
|
+
".jpeg",
|
|
17358
|
+
".gif",
|
|
17359
|
+
".bmp",
|
|
17360
|
+
".ico",
|
|
17361
|
+
".svg",
|
|
17362
|
+
".webp",
|
|
17363
|
+
".woff",
|
|
17364
|
+
".woff2",
|
|
17365
|
+
".ttf",
|
|
17366
|
+
".eot",
|
|
17367
|
+
".otf",
|
|
17368
|
+
".zip",
|
|
17369
|
+
".tar",
|
|
17370
|
+
".gz",
|
|
17371
|
+
".bz2",
|
|
17372
|
+
".7z",
|
|
17373
|
+
".rar",
|
|
17374
|
+
".pdf",
|
|
17375
|
+
".doc",
|
|
17376
|
+
".docx",
|
|
17377
|
+
".xls",
|
|
17378
|
+
".xlsx",
|
|
17379
|
+
".mp3",
|
|
17380
|
+
".mp4",
|
|
17381
|
+
".avi",
|
|
17382
|
+
".mov",
|
|
17383
|
+
".wav",
|
|
17384
|
+
".exe",
|
|
17385
|
+
".dll",
|
|
17386
|
+
".so",
|
|
17387
|
+
".dylib",
|
|
17388
|
+
".o",
|
|
17389
|
+
".a",
|
|
17390
|
+
".wasm",
|
|
17391
|
+
".pyc",
|
|
17392
|
+
".class"
|
|
17393
|
+
]);
|
|
17394
|
+
var SKIP_DIRS = ["node_modules", ".git", "dist", "build", "vendor", "__pycache__", ".next", ".nuxt"];
|
|
17395
|
+
function applyCodemod(projectRoot, pattern, replacement, filePattern, options) {
|
|
17396
|
+
const result = {
|
|
17397
|
+
success: false,
|
|
17398
|
+
tool: "apply_codemod",
|
|
17399
|
+
dry_run: options.dryRun,
|
|
17400
|
+
matches: [],
|
|
17401
|
+
files_modified: [],
|
|
17402
|
+
total_replacements: 0,
|
|
17403
|
+
total_files: 0,
|
|
17404
|
+
warnings: []
|
|
17405
|
+
};
|
|
17406
|
+
let regex;
|
|
17407
|
+
try {
|
|
17408
|
+
const flags = options.multiline ? "gms" : "gm";
|
|
17409
|
+
regex = new RegExp(pattern, flags);
|
|
17410
|
+
} catch (e) {
|
|
17411
|
+
result.error = `Invalid regex pattern: ${e.message}`;
|
|
17412
|
+
return result;
|
|
17413
|
+
}
|
|
17414
|
+
let files;
|
|
17415
|
+
try {
|
|
17416
|
+
files = fg4.sync(filePattern, {
|
|
17417
|
+
cwd: projectRoot,
|
|
17418
|
+
ignore: SKIP_DIRS.map((d) => `**/${d}/**`),
|
|
17419
|
+
onlyFiles: true,
|
|
17420
|
+
absolute: false
|
|
17421
|
+
});
|
|
17422
|
+
} catch (e) {
|
|
17423
|
+
result.error = `Invalid file pattern: ${e.message}`;
|
|
17424
|
+
return result;
|
|
17425
|
+
}
|
|
17426
|
+
files = files.filter((f) => !BINARY_EXTENSIONS.has(path35.extname(f).toLowerCase()));
|
|
17427
|
+
if (files.length === 0) {
|
|
17428
|
+
result.error = `No files matched pattern: ${filePattern}`;
|
|
17429
|
+
return result;
|
|
17430
|
+
}
|
|
17431
|
+
const allMatches = [];
|
|
17432
|
+
const filesWithMatches = /* @__PURE__ */ new Set();
|
|
17433
|
+
for (const relPath of files) {
|
|
17434
|
+
const absPath = path35.resolve(projectRoot, relPath);
|
|
17435
|
+
if (!fs23.existsSync(absPath)) continue;
|
|
17436
|
+
let content;
|
|
17437
|
+
try {
|
|
17438
|
+
content = fs23.readFileSync(absPath, "utf-8");
|
|
17439
|
+
} catch {
|
|
17440
|
+
result.warnings.push(`Could not read: ${relPath}`);
|
|
17441
|
+
continue;
|
|
17442
|
+
}
|
|
17443
|
+
if (options.filterContent && !content.includes(options.filterContent)) {
|
|
17444
|
+
continue;
|
|
17445
|
+
}
|
|
17446
|
+
const lines = content.split("\n");
|
|
17447
|
+
if (options.multiline) {
|
|
17448
|
+
regex.lastIndex = 0;
|
|
17449
|
+
if (!regex.test(content)) continue;
|
|
17450
|
+
filesWithMatches.add(relPath);
|
|
17451
|
+
regex.lastIndex = 0;
|
|
17452
|
+
let matchCount = 0;
|
|
17453
|
+
const matchPositions = [];
|
|
17454
|
+
let m;
|
|
17455
|
+
while ((m = regex.exec(content)) !== null) {
|
|
17456
|
+
matchPositions.push({ index: m.index, match: m[0] });
|
|
17457
|
+
matchCount++;
|
|
17458
|
+
if (m[0].length === 0) {
|
|
17459
|
+
regex.lastIndex++;
|
|
17460
|
+
}
|
|
17461
|
+
}
|
|
17462
|
+
for (const pos of matchPositions.slice(0, CODEMOD_MAX_PREVIEW - allMatches.length)) {
|
|
17463
|
+
const lineNum = content.slice(0, pos.index).split("\n").length;
|
|
17464
|
+
const original = pos.match;
|
|
17465
|
+
regex.lastIndex = 0;
|
|
17466
|
+
const replaced = original.replace(regex, replacement);
|
|
17467
|
+
allMatches.push({
|
|
17468
|
+
file: relPath,
|
|
17469
|
+
line: lineNum,
|
|
17470
|
+
original: original.length > 200 ? original.slice(0, 200) + "\u2026" : original,
|
|
17471
|
+
replaced: replaced.length > 200 ? replaced.slice(0, 200) + "\u2026" : replaced,
|
|
17472
|
+
context_before: lines.slice(Math.max(0, lineNum - 1 - CODEMOD_CONTEXT_LINES), lineNum - 1),
|
|
17473
|
+
context_after: lines.slice(lineNum, lineNum + CODEMOD_CONTEXT_LINES)
|
|
17474
|
+
});
|
|
17475
|
+
}
|
|
17476
|
+
result.total_replacements += matchCount;
|
|
17477
|
+
} else {
|
|
17478
|
+
let fileMatchCount = 0;
|
|
17479
|
+
for (let i = 0; i < lines.length; i++) {
|
|
17480
|
+
regex.lastIndex = 0;
|
|
17481
|
+
if (!regex.test(lines[i])) continue;
|
|
17482
|
+
filesWithMatches.add(relPath);
|
|
17483
|
+
fileMatchCount++;
|
|
17484
|
+
regex.lastIndex = 0;
|
|
17485
|
+
const newLine = lines[i].replace(regex, replacement);
|
|
17486
|
+
if (allMatches.length < CODEMOD_MAX_PREVIEW) {
|
|
17487
|
+
allMatches.push({
|
|
17488
|
+
file: relPath,
|
|
17489
|
+
line: i + 1,
|
|
17490
|
+
original: lines[i],
|
|
17491
|
+
replaced: newLine,
|
|
17492
|
+
context_before: lines.slice(Math.max(0, i - CODEMOD_CONTEXT_LINES), i),
|
|
17493
|
+
context_after: lines.slice(i + 1, i + 1 + CODEMOD_CONTEXT_LINES)
|
|
17494
|
+
});
|
|
17495
|
+
}
|
|
17496
|
+
}
|
|
17497
|
+
result.total_replacements += fileMatchCount;
|
|
17498
|
+
}
|
|
17499
|
+
}
|
|
17500
|
+
result.total_files = filesWithMatches.size;
|
|
17501
|
+
if (allMatches.length === 0) {
|
|
17502
|
+
result.error = `No matches found for pattern in ${files.length} files`;
|
|
17503
|
+
return result;
|
|
17504
|
+
}
|
|
17505
|
+
if (filesWithMatches.size > CODEMOD_LARGE_THRESHOLD && !options.confirmLarge) {
|
|
17506
|
+
result.matches = allMatches;
|
|
17507
|
+
result.warnings.push(
|
|
17508
|
+
`Affects ${filesWithMatches.size} files (>${CODEMOD_LARGE_THRESHOLD}). Re-run with confirm_large: true to proceed, or narrow file_pattern.`
|
|
17509
|
+
);
|
|
17510
|
+
result.dry_run = true;
|
|
17511
|
+
result.success = true;
|
|
17512
|
+
return result;
|
|
17513
|
+
}
|
|
17514
|
+
if (options.dryRun) {
|
|
17515
|
+
result.matches = allMatches;
|
|
17516
|
+
result.success = true;
|
|
17517
|
+
return result;
|
|
17518
|
+
}
|
|
17519
|
+
for (const relPath of filesWithMatches) {
|
|
17520
|
+
const absPath = path35.resolve(projectRoot, relPath);
|
|
17521
|
+
try {
|
|
17522
|
+
const content = fs23.readFileSync(absPath, "utf-8");
|
|
17523
|
+
const flags = options.multiline ? "gms" : "gm";
|
|
17524
|
+
const freshRegex = new RegExp(pattern, flags);
|
|
17525
|
+
const newContent = content.replace(freshRegex, replacement);
|
|
17526
|
+
if (newContent !== content) {
|
|
17527
|
+
fs23.writeFileSync(absPath, newContent, "utf-8");
|
|
17528
|
+
result.files_modified.push(relPath);
|
|
17529
|
+
}
|
|
17530
|
+
} catch (e) {
|
|
17531
|
+
result.warnings.push(`Failed to write ${relPath}: ${e.message}`);
|
|
17532
|
+
}
|
|
17533
|
+
}
|
|
17534
|
+
result.matches = allMatches;
|
|
17535
|
+
result.success = true;
|
|
17536
|
+
return result;
|
|
17537
|
+
}
|
|
17310
17538
|
function detectLanguage2(ext) {
|
|
17311
17539
|
switch (ext) {
|
|
17312
17540
|
case ".ts":
|
|
@@ -17543,6 +17771,31 @@ function registerRefactoringTools(server, ctx) {
|
|
|
17543
17771
|
return { content: [{ type: "text", text: j3(result) }] };
|
|
17544
17772
|
}
|
|
17545
17773
|
);
|
|
17774
|
+
server.tool(
|
|
17775
|
+
"apply_codemod",
|
|
17776
|
+
"Bulk regex find-and-replace across files. Dry-run by default \u2014 first call shows preview, second call with dry_run=false applies. Use for mechanical changes like adding async/await, renaming patterns, updating imports across many files.",
|
|
17777
|
+
{
|
|
17778
|
+
pattern: z6.string().min(1).max(1e3).describe("Regex pattern to match (JavaScript regex syntax)"),
|
|
17779
|
+
replacement: z6.string().max(1e3).describe("Replacement string ($1, $2 for capture groups)"),
|
|
17780
|
+
file_pattern: z6.string().min(1).max(512).describe('Glob pattern for files to scan (e.g. "tests/**/*.test.ts", "src/**/*.py")'),
|
|
17781
|
+
dry_run: z6.boolean().default(true).describe("Preview changes without writing (default: true). Set to false to apply."),
|
|
17782
|
+
confirm_large: z6.boolean().optional().describe("Required when >20 files affected. Acknowledges large-scale change."),
|
|
17783
|
+
filter_content: z6.string().max(500).optional().describe("Only process files containing this substring (narrows scope)"),
|
|
17784
|
+
multiline: z6.boolean().optional().describe("Enable multiline mode (dot matches newlines, patterns span lines)")
|
|
17785
|
+
},
|
|
17786
|
+
async ({ pattern, replacement, file_pattern, dry_run, confirm_large, filter_content, multiline }) => {
|
|
17787
|
+
const result = applyCodemod(projectRoot, pattern, replacement, file_pattern, {
|
|
17788
|
+
dryRun: dry_run,
|
|
17789
|
+
confirmLarge: confirm_large,
|
|
17790
|
+
filterContent: filter_content,
|
|
17791
|
+
multiline
|
|
17792
|
+
});
|
|
17793
|
+
if (!result.success) {
|
|
17794
|
+
return { content: [{ type: "text", text: j3(result) }], isError: true };
|
|
17795
|
+
}
|
|
17796
|
+
return { content: [{ type: "text", text: j3(result) }] };
|
|
17797
|
+
}
|
|
17798
|
+
);
|
|
17546
17799
|
}
|
|
17547
17800
|
|
|
17548
17801
|
// src/tools/register/advanced.ts
|
|
@@ -26515,6 +26768,8 @@ var KNOWN_PACKAGES = {
|
|
|
26515
26768
|
"@clack/prompts": { category: "infra", priority: "medium", plugin: "clack" },
|
|
26516
26769
|
"@clack/core": { category: "infra", priority: "medium", plugin: "clack" },
|
|
26517
26770
|
"tree-sitter": { category: "infra", priority: "medium", plugin: "tree-sitter" },
|
|
26771
|
+
"web-tree-sitter": { category: "infra", priority: "medium", plugin: "tree-sitter" },
|
|
26772
|
+
"tree-sitter-wasms": { category: "infra", priority: "low", plugin: "tree-sitter" },
|
|
26518
26773
|
"n8n-workflow": { category: "infra", priority: "high", plugin: "n8n" },
|
|
26519
26774
|
// --- JavaScript / npm: Build tools (with plugin) ---
|
|
26520
26775
|
"tsup": { category: "infra", priority: "low", plugin: "build-tools" },
|
|
@@ -27484,7 +27739,7 @@ function registerSessionTools(server, ctx) {
|
|
|
27484
27739
|
}
|
|
27485
27740
|
|
|
27486
27741
|
// src/server/server.ts
|
|
27487
|
-
var PKG_VERSION = true ? "1.
|
|
27742
|
+
var PKG_VERSION = true ? "1.6.1" : "0.0.0-dev";
|
|
27488
27743
|
function j2(value) {
|
|
27489
27744
|
return JSON.stringify(value, (_key, val) => val === null || val === void 0 ? void 0 : val);
|
|
27490
27745
|
}
|
|
@@ -29149,7 +29404,8 @@ var TraceMcpConfigSchema = z13.object({
|
|
|
29149
29404
|
watch: z13.object({
|
|
29150
29405
|
enabled: z13.boolean().default(true),
|
|
29151
29406
|
debounceMs: z13.number().int().min(500).max(3e4).default(2e3)
|
|
29152
|
-
}).default({})
|
|
29407
|
+
}).default({}),
|
|
29408
|
+
children: z13.array(z13.string()).optional()
|
|
29153
29409
|
});
|
|
29154
29410
|
function loadGlobalConfigRaw() {
|
|
29155
29411
|
if (!fs37.existsSync(GLOBAL_CONFIG_PATH)) return {};
|