trace-mcp 1.7.0 → 1.8.0
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 +2 -2
- package/dist/cli.js +619 -499
- package/dist/cli.js.map +1 -1
- package/dist/index.js +107 -43
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -5,10 +5,16 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
9
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
10
|
+
}) : x)(function(x) {
|
|
11
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
12
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
13
|
+
});
|
|
8
14
|
var __esm = (fn, res) => function __init() {
|
|
9
15
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
16
|
};
|
|
11
|
-
var __commonJS = (cb, mod) => function
|
|
17
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
12
18
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
13
19
|
};
|
|
14
20
|
var __export = (target, all) => {
|
|
@@ -1107,7 +1113,7 @@ var require_parse = __commonJS({
|
|
|
1107
1113
|
}
|
|
1108
1114
|
return { risky: false };
|
|
1109
1115
|
};
|
|
1110
|
-
var
|
|
1116
|
+
var parse2 = (input, options) => {
|
|
1111
1117
|
if (typeof input !== "string") {
|
|
1112
1118
|
throw new TypeError("Expected a string");
|
|
1113
1119
|
}
|
|
@@ -1277,7 +1283,7 @@ var require_parse = __commonJS({
|
|
|
1277
1283
|
output = token.close = `)$))${extglobStar}`;
|
|
1278
1284
|
}
|
|
1279
1285
|
if (token.inner.includes("*") && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) {
|
|
1280
|
-
const expression =
|
|
1286
|
+
const expression = parse2(rest, { ...options, fastpaths: false }).output;
|
|
1281
1287
|
output = token.close = `)${expression})${extglobStar})`;
|
|
1282
1288
|
}
|
|
1283
1289
|
if (token.prev.type === "bos") {
|
|
@@ -1799,7 +1805,7 @@ var require_parse = __commonJS({
|
|
|
1799
1805
|
}
|
|
1800
1806
|
return state;
|
|
1801
1807
|
};
|
|
1802
|
-
|
|
1808
|
+
parse2.fastpaths = (input, options) => {
|
|
1803
1809
|
const opts = { ...options };
|
|
1804
1810
|
const max = typeof opts.maxLength === "number" ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
|
|
1805
1811
|
const len = input.length;
|
|
@@ -1864,7 +1870,7 @@ var require_parse = __commonJS({
|
|
|
1864
1870
|
}
|
|
1865
1871
|
return source;
|
|
1866
1872
|
};
|
|
1867
|
-
module.exports =
|
|
1873
|
+
module.exports = parse2;
|
|
1868
1874
|
}
|
|
1869
1875
|
});
|
|
1870
1876
|
|
|
@@ -1873,7 +1879,7 @@ var require_picomatch = __commonJS({
|
|
|
1873
1879
|
"node_modules/picomatch/lib/picomatch.js"(exports, module) {
|
|
1874
1880
|
"use strict";
|
|
1875
1881
|
var scan = require_scan();
|
|
1876
|
-
var
|
|
1882
|
+
var parse2 = require_parse();
|
|
1877
1883
|
var utils = require_utils();
|
|
1878
1884
|
var constants = require_constants();
|
|
1879
1885
|
var isObject = (val) => val && typeof val === "object" && !Array.isArray(val);
|
|
@@ -1961,7 +1967,7 @@ var require_picomatch = __commonJS({
|
|
|
1961
1967
|
picomatch3.isMatch = (str2, patterns, options) => picomatch3(patterns, options)(str2);
|
|
1962
1968
|
picomatch3.parse = (pattern, options) => {
|
|
1963
1969
|
if (Array.isArray(pattern)) return pattern.map((p5) => picomatch3.parse(p5, options));
|
|
1964
|
-
return
|
|
1970
|
+
return parse2(pattern, { ...options, fastpaths: false });
|
|
1965
1971
|
};
|
|
1966
1972
|
picomatch3.scan = (input, options) => scan(input, options);
|
|
1967
1973
|
picomatch3.compileRe = (state, options, returnOutput = false, returnState = false) => {
|
|
@@ -1987,10 +1993,10 @@ var require_picomatch = __commonJS({
|
|
|
1987
1993
|
}
|
|
1988
1994
|
let parsed = { negated: false, fastpaths: true };
|
|
1989
1995
|
if (options.fastpaths !== false && (input[0] === "." || input[0] === "*")) {
|
|
1990
|
-
parsed.output =
|
|
1996
|
+
parsed.output = parse2.fastpaths(input, options);
|
|
1991
1997
|
}
|
|
1992
1998
|
if (!parsed.output) {
|
|
1993
|
-
parsed =
|
|
1999
|
+
parsed = parse2(input, options);
|
|
1994
2000
|
}
|
|
1995
2001
|
return picomatch3.compileRe(parsed, options, returnOutput, returnState);
|
|
1996
2002
|
};
|
|
@@ -2117,7 +2123,7 @@ var init_layer_violations = __esm({
|
|
|
2117
2123
|
// src/cli.ts
|
|
2118
2124
|
import { Command as Command12 } from "commander";
|
|
2119
2125
|
import path107 from "path";
|
|
2120
|
-
import
|
|
2126
|
+
import fs97 from "fs";
|
|
2121
2127
|
import { randomUUID } from "crypto";
|
|
2122
2128
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
2123
2129
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
@@ -4377,7 +4383,7 @@ var PluginRegistry = class {
|
|
|
4377
4383
|
// src/config.ts
|
|
4378
4384
|
import { cosmiconfig } from "cosmiconfig";
|
|
4379
4385
|
import { z } from "zod";
|
|
4380
|
-
import
|
|
4386
|
+
import fs3 from "fs";
|
|
4381
4387
|
|
|
4382
4388
|
// src/global.ts
|
|
4383
4389
|
import path from "path";
|
|
@@ -4420,9 +4426,9 @@ var DEFAULT_CONFIG_JSONC = `{
|
|
|
4420
4426
|
"provider": "ollama", // "ollama" | "openai"
|
|
4421
4427
|
// "base_url": "http://localhost:11434", // custom endpoint
|
|
4422
4428
|
// "api_key": "", // required for openai; or set OPENAI_API_KEY env
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4429
|
+
"inference_model": "gemma4-e4b", // ollama: "gemma4-e4b", openai: "gpt-4o-mini"
|
|
4430
|
+
"fast_model": "gemma4-e4b", // ollama: "gemma4-e4b", openai: "gpt-4o-mini"
|
|
4431
|
+
"embedding_model": "qwen3-embedding:0.6b", // ollama: "qwen3-embedding:0.6b", openai: "text-embedding-3-small"
|
|
4426
4432
|
// "embedding_dimensions": 1536, // provider-specific
|
|
4427
4433
|
"summarize_on_index": true,
|
|
4428
4434
|
"summarize_batch_size": 20,
|
|
@@ -4569,6 +4575,73 @@ function getDbPath(projectRoot) {
|
|
|
4569
4575
|
return path.join(INDEX_DIR, `${projectName(absRoot)}-${projectHash(absRoot)}.db`);
|
|
4570
4576
|
}
|
|
4571
4577
|
|
|
4578
|
+
// src/config-jsonc.ts
|
|
4579
|
+
import fs2 from "fs";
|
|
4580
|
+
import { modify, applyEdits, parse } from "jsonc-parser";
|
|
4581
|
+
var FORMAT_OPTS = {
|
|
4582
|
+
formattingOptions: {
|
|
4583
|
+
tabSize: 2,
|
|
4584
|
+
insertSpaces: true,
|
|
4585
|
+
eol: "\n"
|
|
4586
|
+
}
|
|
4587
|
+
};
|
|
4588
|
+
function readGlobalConfigText() {
|
|
4589
|
+
ensureGlobalDirs();
|
|
4590
|
+
if (!fs2.existsSync(GLOBAL_CONFIG_PATH)) return DEFAULT_CONFIG_JSONC;
|
|
4591
|
+
return fs2.readFileSync(GLOBAL_CONFIG_PATH, "utf-8");
|
|
4592
|
+
}
|
|
4593
|
+
function modifyGlobalConfigJsonc(jsonPath, value) {
|
|
4594
|
+
const text = readGlobalConfigText();
|
|
4595
|
+
const edits = modify(text, jsonPath, value, FORMAT_OPTS);
|
|
4596
|
+
const updated = applyEdits(text, edits);
|
|
4597
|
+
fs2.writeFileSync(GLOBAL_CONFIG_PATH, updated);
|
|
4598
|
+
}
|
|
4599
|
+
function saveProjectConfigJsonc(projectRoot, config) {
|
|
4600
|
+
ensureGlobalDirs();
|
|
4601
|
+
modifyGlobalConfigJsonc(["projects", projectRoot], config);
|
|
4602
|
+
}
|
|
4603
|
+
function removeProjectConfigJsonc(projectRoot) {
|
|
4604
|
+
modifyGlobalConfigJsonc(["projects", projectRoot], void 0);
|
|
4605
|
+
}
|
|
4606
|
+
function migrateGlobalConfig() {
|
|
4607
|
+
ensureGlobalDirs();
|
|
4608
|
+
const result = { added: [], changed: false };
|
|
4609
|
+
const existingText = readGlobalConfigText();
|
|
4610
|
+
const existing = parse(existingText);
|
|
4611
|
+
const defaults = parse(DEFAULT_CONFIG_JSONC);
|
|
4612
|
+
if (!existing || !defaults) return result;
|
|
4613
|
+
let text = existingText;
|
|
4614
|
+
for (const key of Object.keys(defaults)) {
|
|
4615
|
+
if (key in existing) {
|
|
4616
|
+
if (typeof defaults[key] === "object" && defaults[key] !== null && !Array.isArray(defaults[key]) && typeof existing[key] === "object" && existing[key] !== null && !Array.isArray(existing[key])) {
|
|
4617
|
+
const defaultSub = defaults[key];
|
|
4618
|
+
const existingSub = existing[key];
|
|
4619
|
+
for (const subKey of Object.keys(defaultSub)) {
|
|
4620
|
+
if (!(subKey in existingSub)) {
|
|
4621
|
+
const edits2 = modify(text, [key, subKey], defaultSub[subKey], FORMAT_OPTS);
|
|
4622
|
+
if (edits2.length > 0) {
|
|
4623
|
+
text = applyEdits(text, edits2);
|
|
4624
|
+
result.added.push(`${key}.${subKey}`);
|
|
4625
|
+
}
|
|
4626
|
+
}
|
|
4627
|
+
}
|
|
4628
|
+
}
|
|
4629
|
+
continue;
|
|
4630
|
+
}
|
|
4631
|
+
const edits = modify(text, [key], defaults[key], FORMAT_OPTS);
|
|
4632
|
+
if (edits.length > 0) {
|
|
4633
|
+
text = applyEdits(text, edits);
|
|
4634
|
+
result.added.push(key);
|
|
4635
|
+
}
|
|
4636
|
+
}
|
|
4637
|
+
if (text !== existingText) {
|
|
4638
|
+
fs2.writeFileSync(GLOBAL_CONFIG_PATH, text);
|
|
4639
|
+
result.changed = true;
|
|
4640
|
+
logger.info({ added: result.added }, "Migrated global config \u2014 added new keys");
|
|
4641
|
+
}
|
|
4642
|
+
return result;
|
|
4643
|
+
}
|
|
4644
|
+
|
|
4572
4645
|
// src/config.ts
|
|
4573
4646
|
var SecurityConfigSchema = z.object({
|
|
4574
4647
|
secret_patterns: z.array(z.string()).optional(),
|
|
@@ -4772,9 +4845,9 @@ var TraceMcpConfigSchema = z.object({
|
|
|
4772
4845
|
children: z.array(z.string()).optional()
|
|
4773
4846
|
});
|
|
4774
4847
|
function loadGlobalConfigRaw() {
|
|
4775
|
-
if (!
|
|
4848
|
+
if (!fs3.existsSync(GLOBAL_CONFIG_PATH)) return {};
|
|
4776
4849
|
try {
|
|
4777
|
-
return JSON.parse(stripJsonComments(
|
|
4850
|
+
return JSON.parse(stripJsonComments(fs3.readFileSync(GLOBAL_CONFIG_PATH, "utf-8")));
|
|
4778
4851
|
} catch {
|
|
4779
4852
|
return {};
|
|
4780
4853
|
}
|
|
@@ -4834,40 +4907,25 @@ async function loadConfig(searchFrom) {
|
|
|
4834
4907
|
return err(configError(e instanceof Error ? e.message : String(e)));
|
|
4835
4908
|
}
|
|
4836
4909
|
}
|
|
4837
|
-
function saveProjectConfig(projectRoot, config) {
|
|
4838
|
-
ensureGlobalDirs();
|
|
4839
|
-
const existing = loadGlobalConfigRaw();
|
|
4840
|
-
const projects = existing.projects ?? {};
|
|
4841
|
-
projects[projectRoot] = config;
|
|
4842
|
-
existing.projects = projects;
|
|
4843
|
-
fs2.writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(existing, null, 2) + "\n");
|
|
4844
|
-
}
|
|
4845
|
-
function removeProjectConfig(projectRoot) {
|
|
4846
|
-
const existing = loadGlobalConfigRaw();
|
|
4847
|
-
const projects = existing.projects ?? {};
|
|
4848
|
-
delete projects[projectRoot];
|
|
4849
|
-
existing.projects = projects;
|
|
4850
|
-
fs2.writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(existing, null, 2) + "\n");
|
|
4851
|
-
}
|
|
4852
4910
|
|
|
4853
4911
|
// src/server/server.ts
|
|
4854
4912
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4855
4913
|
|
|
4856
4914
|
// src/indexer/pipeline.ts
|
|
4857
|
-
import
|
|
4915
|
+
import fs12 from "fs";
|
|
4858
4916
|
import path11 from "path";
|
|
4859
4917
|
import { cpus } from "os";
|
|
4860
4918
|
import fg3 from "fast-glob";
|
|
4861
4919
|
|
|
4862
4920
|
// src/indexer/project-context.ts
|
|
4863
|
-
import
|
|
4921
|
+
import fs4 from "fs";
|
|
4864
4922
|
import path2 from "path";
|
|
4865
4923
|
function buildProjectContext(rootPath) {
|
|
4866
4924
|
const detectedVersions = [];
|
|
4867
4925
|
const allDependencies = [];
|
|
4868
4926
|
const readFile = (rel) => {
|
|
4869
4927
|
try {
|
|
4870
|
-
return
|
|
4928
|
+
return fs4.readFileSync(path2.resolve(rootPath, rel), "utf-8");
|
|
4871
4929
|
} catch {
|
|
4872
4930
|
return void 0;
|
|
4873
4931
|
}
|
|
@@ -5181,14 +5239,14 @@ function buildProjectContext(rootPath) {
|
|
|
5181
5239
|
];
|
|
5182
5240
|
for (const name of CONFIG_FILE_NAMES) {
|
|
5183
5241
|
try {
|
|
5184
|
-
|
|
5242
|
+
fs4.accessSync(path2.resolve(rootPath, name));
|
|
5185
5243
|
configFiles.push(name);
|
|
5186
5244
|
} catch {
|
|
5187
5245
|
}
|
|
5188
5246
|
}
|
|
5189
5247
|
try {
|
|
5190
5248
|
const ghWorkflowDir = path2.resolve(rootPath, ".github/workflows");
|
|
5191
|
-
const entries =
|
|
5249
|
+
const entries = fs4.readdirSync(ghWorkflowDir);
|
|
5192
5250
|
for (const entry of entries) {
|
|
5193
5251
|
if (entry.endsWith(".yml") || entry.endsWith(".yaml")) {
|
|
5194
5252
|
configFiles.push(`.github/workflows/${entry}`);
|
|
@@ -5214,7 +5272,7 @@ function buildProjectContext(rootPath) {
|
|
|
5214
5272
|
}
|
|
5215
5273
|
|
|
5216
5274
|
// src/indexer/monorepo.ts
|
|
5217
|
-
import
|
|
5275
|
+
import fs5 from "fs";
|
|
5218
5276
|
import path3 from "path";
|
|
5219
5277
|
import { parse as parseYaml } from "yaml";
|
|
5220
5278
|
import fg from "fast-glob";
|
|
@@ -5230,7 +5288,7 @@ function detectWorkspaces(rootPath) {
|
|
|
5230
5288
|
function buildMultiRootWorkspaces(parentDir, childRoots) {
|
|
5231
5289
|
const workspaces = [];
|
|
5232
5290
|
for (const childRoot of childRoots) {
|
|
5233
|
-
if (!
|
|
5291
|
+
if (!fs5.existsSync(childRoot)) {
|
|
5234
5292
|
logger.warn({ childRoot }, "Skipping missing multi-root child directory");
|
|
5235
5293
|
continue;
|
|
5236
5294
|
}
|
|
@@ -5249,9 +5307,9 @@ function buildMultiRootWorkspaces(parentDir, childRoots) {
|
|
|
5249
5307
|
}
|
|
5250
5308
|
function detectPnpmWorkspaces(rootPath) {
|
|
5251
5309
|
const yamlPath = path3.join(rootPath, "pnpm-workspace.yaml");
|
|
5252
|
-
if (!
|
|
5310
|
+
if (!fs5.existsSync(yamlPath)) return [];
|
|
5253
5311
|
try {
|
|
5254
|
-
const content =
|
|
5312
|
+
const content = fs5.readFileSync(yamlPath, "utf-8");
|
|
5255
5313
|
const parsed = parseYaml(content);
|
|
5256
5314
|
if (!parsed?.packages?.length) return [];
|
|
5257
5315
|
return expandGlobPatterns(rootPath, parsed.packages);
|
|
@@ -5262,9 +5320,9 @@ function detectPnpmWorkspaces(rootPath) {
|
|
|
5262
5320
|
}
|
|
5263
5321
|
function detectNpmWorkspaces(rootPath) {
|
|
5264
5322
|
const pkgPath = path3.join(rootPath, "package.json");
|
|
5265
|
-
if (!
|
|
5323
|
+
if (!fs5.existsSync(pkgPath)) return [];
|
|
5266
5324
|
try {
|
|
5267
|
-
const content =
|
|
5325
|
+
const content = fs5.readFileSync(pkgPath, "utf-8");
|
|
5268
5326
|
const pkg = JSON.parse(content);
|
|
5269
5327
|
let patterns;
|
|
5270
5328
|
if (Array.isArray(pkg.workspaces)) {
|
|
@@ -5281,9 +5339,9 @@ function detectNpmWorkspaces(rootPath) {
|
|
|
5281
5339
|
}
|
|
5282
5340
|
function detectComposerWorkspaces(rootPath) {
|
|
5283
5341
|
const composerPath = path3.join(rootPath, "composer.json");
|
|
5284
|
-
if (!
|
|
5342
|
+
if (!fs5.existsSync(composerPath)) return [];
|
|
5285
5343
|
try {
|
|
5286
|
-
const content =
|
|
5344
|
+
const content = fs5.readFileSync(composerPath, "utf-8");
|
|
5287
5345
|
const composer = JSON.parse(content);
|
|
5288
5346
|
if (!composer.repositories?.length) return [];
|
|
5289
5347
|
const pathRepos = composer.repositories.filter((r) => r.type === "path" && r.url);
|
|
@@ -5308,8 +5366,8 @@ function expandGlobPatterns(rootPath, patterns) {
|
|
|
5308
5366
|
for (const match of matches) {
|
|
5309
5367
|
const relPath = match.replace(/\\/g, "/");
|
|
5310
5368
|
if (seen.has(relPath)) continue;
|
|
5311
|
-
const hasPackageJson =
|
|
5312
|
-
const hasComposerJson =
|
|
5369
|
+
const hasPackageJson = fs5.existsSync(path3.join(rootPath, relPath, "package.json"));
|
|
5370
|
+
const hasComposerJson = fs5.existsSync(path3.join(rootPath, relPath, "composer.json"));
|
|
5313
5371
|
if (!hasPackageJson && !hasComposerJson) continue;
|
|
5314
5372
|
const name = resolveWorkspaceName(rootPath, relPath);
|
|
5315
5373
|
seen.add(relPath);
|
|
@@ -5321,16 +5379,16 @@ function expandGlobPatterns(rootPath, patterns) {
|
|
|
5321
5379
|
function resolveWorkspaceName(rootPath, relPath) {
|
|
5322
5380
|
try {
|
|
5323
5381
|
const pkgPath = path3.join(rootPath, relPath, "package.json");
|
|
5324
|
-
if (
|
|
5325
|
-
const pkg = JSON.parse(
|
|
5382
|
+
if (fs5.existsSync(pkgPath)) {
|
|
5383
|
+
const pkg = JSON.parse(fs5.readFileSync(pkgPath, "utf-8"));
|
|
5326
5384
|
if (pkg.name) return pkg.name;
|
|
5327
5385
|
}
|
|
5328
5386
|
} catch {
|
|
5329
5387
|
}
|
|
5330
5388
|
try {
|
|
5331
5389
|
const composerPath = path3.join(rootPath, relPath, "composer.json");
|
|
5332
|
-
if (
|
|
5333
|
-
const composer = JSON.parse(
|
|
5390
|
+
if (fs5.existsSync(composerPath)) {
|
|
5391
|
+
const composer = JSON.parse(fs5.readFileSync(composerPath, "utf-8"));
|
|
5334
5392
|
if (composer.name) return composer.name;
|
|
5335
5393
|
}
|
|
5336
5394
|
} catch {
|
|
@@ -5456,7 +5514,7 @@ function isBinaryBuffer(buf) {
|
|
|
5456
5514
|
}
|
|
5457
5515
|
|
|
5458
5516
|
// src/utils/gitignore.ts
|
|
5459
|
-
import
|
|
5517
|
+
import fs6 from "fs";
|
|
5460
5518
|
import path5 from "path";
|
|
5461
5519
|
|
|
5462
5520
|
// src/utils/ignore-patterns.ts
|
|
@@ -5520,9 +5578,9 @@ var GitignoreMatcher = class {
|
|
|
5520
5578
|
}
|
|
5521
5579
|
loadGitignore(rootPath) {
|
|
5522
5580
|
const gitignorePath = path5.join(rootPath, ".gitignore");
|
|
5523
|
-
if (!
|
|
5581
|
+
if (!fs6.existsSync(gitignorePath)) return;
|
|
5524
5582
|
try {
|
|
5525
|
-
const content =
|
|
5583
|
+
const content = fs6.readFileSync(gitignorePath, "utf-8");
|
|
5526
5584
|
const lines = content.split("\n");
|
|
5527
5585
|
for (const line of lines) {
|
|
5528
5586
|
const rule = parseIgnorePattern(line);
|
|
@@ -5548,7 +5606,7 @@ var GitignoreMatcher = class {
|
|
|
5548
5606
|
};
|
|
5549
5607
|
|
|
5550
5608
|
// src/utils/traceignore.ts
|
|
5551
|
-
import
|
|
5609
|
+
import fs7 from "fs";
|
|
5552
5610
|
import path6 from "path";
|
|
5553
5611
|
var TraceignoreMatcher = class _TraceignoreMatcher {
|
|
5554
5612
|
rules = [];
|
|
@@ -5584,9 +5642,9 @@ var TraceignoreMatcher = class _TraceignoreMatcher {
|
|
|
5584
5642
|
}
|
|
5585
5643
|
loadTraceignore(rootPath) {
|
|
5586
5644
|
const traceignorePath = path6.join(rootPath, ".traceignore");
|
|
5587
|
-
if (!
|
|
5645
|
+
if (!fs7.existsSync(traceignorePath)) return;
|
|
5588
5646
|
try {
|
|
5589
|
-
const content =
|
|
5647
|
+
const content = fs7.readFileSync(traceignorePath, "utf-8");
|
|
5590
5648
|
const lines = content.split("\n");
|
|
5591
5649
|
for (const line of lines) {
|
|
5592
5650
|
const rule = parseIgnorePattern(line);
|
|
@@ -6905,7 +6963,7 @@ function resolveTypeScriptHeritageEdges(state) {
|
|
|
6905
6963
|
}
|
|
6906
6964
|
|
|
6907
6965
|
// src/indexer/edge-resolvers/imports.ts
|
|
6908
|
-
import
|
|
6966
|
+
import fs8 from "fs";
|
|
6909
6967
|
import path8 from "path";
|
|
6910
6968
|
|
|
6911
6969
|
// src/indexer/resolvers/es-modules.ts
|
|
@@ -6945,7 +7003,7 @@ function resolveEsmImportEdges(state) {
|
|
|
6945
7003
|
if (state.pendingImports.size === 0) return;
|
|
6946
7004
|
let resolver;
|
|
6947
7005
|
try {
|
|
6948
|
-
const tsconfigPath =
|
|
7006
|
+
const tsconfigPath = fs8.existsSync(path8.join(state.rootPath, "tsconfig.json")) ? path8.join(state.rootPath, "tsconfig.json") : void 0;
|
|
6949
7007
|
resolver = new EsModuleResolver(state.rootPath, tsconfigPath);
|
|
6950
7008
|
} catch {
|
|
6951
7009
|
logger.warn("EsModuleResolver init failed \u2014 skipping import edge resolution");
|
|
@@ -7271,12 +7329,12 @@ var EdgeResolver = class {
|
|
|
7271
7329
|
};
|
|
7272
7330
|
|
|
7273
7331
|
// src/indexer/file-extractor.ts
|
|
7274
|
-
import
|
|
7332
|
+
import fs10 from "fs";
|
|
7275
7333
|
import path9 from "path";
|
|
7276
7334
|
|
|
7277
7335
|
// src/utils/hasher.ts
|
|
7278
7336
|
import crypto2 from "crypto";
|
|
7279
|
-
import
|
|
7337
|
+
import fs9 from "fs";
|
|
7280
7338
|
function hashContent(content) {
|
|
7281
7339
|
return crypto2.createHash("md5").update(content).digest("hex");
|
|
7282
7340
|
}
|
|
@@ -7297,7 +7355,7 @@ var FileExtractor = class {
|
|
|
7297
7355
|
}
|
|
7298
7356
|
let fileMtimeMs = null;
|
|
7299
7357
|
try {
|
|
7300
|
-
const stat =
|
|
7358
|
+
const stat = fs10.lstatSync(absPath);
|
|
7301
7359
|
if (stat.isSymbolicLink()) {
|
|
7302
7360
|
logger.warn({ file: relPath }, "Symlink skipped");
|
|
7303
7361
|
return "error";
|
|
@@ -7315,7 +7373,7 @@ var FileExtractor = class {
|
|
|
7315
7373
|
}
|
|
7316
7374
|
let content;
|
|
7317
7375
|
try {
|
|
7318
|
-
content =
|
|
7376
|
+
content = fs10.readFileSync(absPath);
|
|
7319
7377
|
} catch {
|
|
7320
7378
|
logger.warn({ file: relPath }, "Cannot read file");
|
|
7321
7379
|
return "error";
|
|
@@ -7449,7 +7507,7 @@ var FileExtractor = class {
|
|
|
7449
7507
|
};
|
|
7450
7508
|
|
|
7451
7509
|
// src/indexer/env-indexer.ts
|
|
7452
|
-
import
|
|
7510
|
+
import fs11 from "fs";
|
|
7453
7511
|
import path10 from "path";
|
|
7454
7512
|
import fg2 from "fast-glob";
|
|
7455
7513
|
|
|
@@ -7579,7 +7637,7 @@ var EnvIndexer = class {
|
|
|
7579
7637
|
if (pathCheck.isErr()) continue;
|
|
7580
7638
|
let content;
|
|
7581
7639
|
try {
|
|
7582
|
-
content =
|
|
7640
|
+
content = fs11.readFileSync(absPath, "utf-8");
|
|
7583
7641
|
} catch {
|
|
7584
7642
|
logger.warn({ file: relPath }, "Cannot read .env file");
|
|
7585
7643
|
continue;
|
|
@@ -7846,7 +7904,7 @@ var IndexingPipeline = class _IndexingPipeline {
|
|
|
7846
7904
|
const cached = this._fileContentCache.get(relPath);
|
|
7847
7905
|
if (cached !== void 0) return cached;
|
|
7848
7906
|
try {
|
|
7849
|
-
return
|
|
7907
|
+
return fs12.readFileSync(path11.resolve(this.rootPath, relPath), "utf-8");
|
|
7850
7908
|
} catch {
|
|
7851
7909
|
return void 0;
|
|
7852
7910
|
}
|
|
@@ -8657,7 +8715,7 @@ Respond with one score per line, in order: just the number, nothing else.`;
|
|
|
8657
8715
|
};
|
|
8658
8716
|
|
|
8659
8717
|
// src/ai/summarization-pipeline.ts
|
|
8660
|
-
import
|
|
8718
|
+
import fs13 from "fs";
|
|
8661
8719
|
import path12 from "path";
|
|
8662
8720
|
var MAX_SOURCE_LINES = 80;
|
|
8663
8721
|
var SummarizationPipeline = class {
|
|
@@ -8752,7 +8810,7 @@ var SummarizationPipeline = class {
|
|
|
8752
8810
|
readSource(filePath, byteStart, byteEnd) {
|
|
8753
8811
|
try {
|
|
8754
8812
|
const absPath = path12.resolve(this.rootPath, filePath);
|
|
8755
|
-
const content =
|
|
8813
|
+
const content = fs13.readFileSync(absPath, "utf-8");
|
|
8756
8814
|
const slice = content.slice(byteStart, byteEnd);
|
|
8757
8815
|
const lines = slice.split("\n");
|
|
8758
8816
|
if (lines.length > MAX_SOURCE_LINES) {
|
|
@@ -9290,7 +9348,7 @@ function withHints(toolName, result) {
|
|
|
9290
9348
|
}
|
|
9291
9349
|
|
|
9292
9350
|
// src/savings.ts
|
|
9293
|
-
import
|
|
9351
|
+
import fs14 from "fs";
|
|
9294
9352
|
import path13 from "path";
|
|
9295
9353
|
var SAVINGS_PATH = path13.join(TRACE_MCP_HOME, "savings.json");
|
|
9296
9354
|
var RAW_COST_ESTIMATES = {
|
|
@@ -9409,8 +9467,8 @@ var SavingsTracker = class {
|
|
|
9409
9467
|
};
|
|
9410
9468
|
function loadPersistentSavings() {
|
|
9411
9469
|
try {
|
|
9412
|
-
if (!
|
|
9413
|
-
const raw = JSON.parse(
|
|
9470
|
+
if (!fs14.existsSync(SAVINGS_PATH)) return null;
|
|
9471
|
+
const raw = JSON.parse(fs14.readFileSync(SAVINGS_PATH, "utf-8"));
|
|
9414
9472
|
if (raw.version !== 1) return null;
|
|
9415
9473
|
return raw;
|
|
9416
9474
|
} catch {
|
|
@@ -9419,13 +9477,13 @@ function loadPersistentSavings() {
|
|
|
9419
9477
|
}
|
|
9420
9478
|
function savePersistentSavings(data) {
|
|
9421
9479
|
const tmpPath = SAVINGS_PATH + ".tmp";
|
|
9422
|
-
|
|
9423
|
-
|
|
9480
|
+
fs14.writeFileSync(tmpPath, JSON.stringify(data, null, 2) + "\n");
|
|
9481
|
+
fs14.renameSync(tmpPath, SAVINGS_PATH);
|
|
9424
9482
|
}
|
|
9425
9483
|
|
|
9426
9484
|
// src/session/journal.ts
|
|
9427
9485
|
import { createHash as createHash2 } from "crypto";
|
|
9428
|
-
import
|
|
9486
|
+
import fs15 from "fs";
|
|
9429
9487
|
import path14 from "path";
|
|
9430
9488
|
var SessionJournal = class _SessionJournal {
|
|
9431
9489
|
entries = [];
|
|
@@ -9749,8 +9807,8 @@ var SessionJournal = class _SessionJournal {
|
|
|
9749
9807
|
if (this.entries.length === 0) return;
|
|
9750
9808
|
const snapshot = this.getSnapshot();
|
|
9751
9809
|
const dir = path14.dirname(snapshotPath);
|
|
9752
|
-
if (!
|
|
9753
|
-
|
|
9810
|
+
if (!fs15.existsSync(dir)) fs15.mkdirSync(dir, { recursive: true });
|
|
9811
|
+
fs15.writeFileSync(snapshotPath, JSON.stringify({
|
|
9754
9812
|
timestamp: Date.now(),
|
|
9755
9813
|
markdown: snapshot.snapshot,
|
|
9756
9814
|
structured: snapshot.structured,
|
|
@@ -9781,7 +9839,7 @@ var SessionJournal = class _SessionJournal {
|
|
|
9781
9839
|
};
|
|
9782
9840
|
|
|
9783
9841
|
// src/session/resume.ts
|
|
9784
|
-
import
|
|
9842
|
+
import fs16 from "fs";
|
|
9785
9843
|
import path15 from "path";
|
|
9786
9844
|
var SESSIONS_DIR = path15.join(TRACE_MCP_HOME, "sessions");
|
|
9787
9845
|
var MAX_SESSIONS = 20;
|
|
@@ -9791,8 +9849,8 @@ function getSessionsPath(projectRoot) {
|
|
|
9791
9849
|
function loadSessions(projectRoot) {
|
|
9792
9850
|
try {
|
|
9793
9851
|
const filePath = getSessionsPath(projectRoot);
|
|
9794
|
-
if (!
|
|
9795
|
-
const data = JSON.parse(
|
|
9852
|
+
if (!fs16.existsSync(filePath)) return [];
|
|
9853
|
+
const data = JSON.parse(fs16.readFileSync(filePath, "utf-8"));
|
|
9796
9854
|
return Array.isArray(data) ? data : [];
|
|
9797
9855
|
} catch {
|
|
9798
9856
|
return [];
|
|
@@ -9801,10 +9859,10 @@ function loadSessions(projectRoot) {
|
|
|
9801
9859
|
function saveSessions(projectRoot, sessions) {
|
|
9802
9860
|
try {
|
|
9803
9861
|
ensureGlobalDirs();
|
|
9804
|
-
|
|
9862
|
+
fs16.mkdirSync(SESSIONS_DIR, { recursive: true });
|
|
9805
9863
|
const filePath = getSessionsPath(projectRoot);
|
|
9806
9864
|
const trimmed = sessions.slice(-MAX_SESSIONS);
|
|
9807
|
-
|
|
9865
|
+
fs16.writeFileSync(filePath, JSON.stringify(trimmed, null, 2));
|
|
9808
9866
|
} catch (e) {
|
|
9809
9867
|
logger.warn({ error: e }, "Failed to save session summary");
|
|
9810
9868
|
}
|
|
@@ -9886,7 +9944,7 @@ function getSessionResume(projectRoot, maxSessions = 5) {
|
|
|
9886
9944
|
}
|
|
9887
9945
|
|
|
9888
9946
|
// src/server/file-watcher.ts
|
|
9889
|
-
import
|
|
9947
|
+
import fs17 from "fs";
|
|
9890
9948
|
import path16 from "path";
|
|
9891
9949
|
var FileWatcher = class {
|
|
9892
9950
|
watcher = null;
|
|
@@ -9906,7 +9964,7 @@ var FileWatcher = class {
|
|
|
9906
9964
|
}
|
|
9907
9965
|
start() {
|
|
9908
9966
|
try {
|
|
9909
|
-
this.watcher =
|
|
9967
|
+
this.watcher = fs17.watch(this.projectRoot, { recursive: true }, (_event, filename) => {
|
|
9910
9968
|
if (!filename) return;
|
|
9911
9969
|
if (this.shouldIgnore(filename)) return;
|
|
9912
9970
|
if (this.extensions.size > 0) {
|
|
@@ -9956,7 +10014,7 @@ var FileWatcher = class {
|
|
|
9956
10014
|
};
|
|
9957
10015
|
|
|
9958
10016
|
// src/server/explored-tracker.ts
|
|
9959
|
-
import
|
|
10017
|
+
import fs18 from "fs";
|
|
9960
10018
|
import path17 from "path";
|
|
9961
10019
|
import os2 from "os";
|
|
9962
10020
|
import crypto3 from "crypto";
|
|
@@ -9964,7 +10022,7 @@ function createExploredTracker(projectRoot) {
|
|
|
9964
10022
|
const hash = crypto3.createHash("sha256").update(projectRoot).digest("hex").slice(0, 12);
|
|
9965
10023
|
const markerDir2 = path17.join(os2.tmpdir(), `trace-mcp-explored-${hash}`);
|
|
9966
10024
|
try {
|
|
9967
|
-
|
|
10025
|
+
fs18.mkdirSync(markerDir2, { recursive: true });
|
|
9968
10026
|
} catch {
|
|
9969
10027
|
}
|
|
9970
10028
|
return {
|
|
@@ -9972,7 +10030,7 @@ function createExploredTracker(projectRoot) {
|
|
|
9972
10030
|
const absPath = path17.isAbsolute(filePath) ? filePath : path17.resolve(projectRoot, filePath);
|
|
9973
10031
|
const fileHash2 = crypto3.createHash("sha256").update(absPath).digest("hex");
|
|
9974
10032
|
try {
|
|
9975
|
-
|
|
10033
|
+
fs18.writeFileSync(path17.join(markerDir2, fileHash2), absPath);
|
|
9976
10034
|
} catch {
|
|
9977
10035
|
}
|
|
9978
10036
|
}
|
|
@@ -10062,7 +10120,7 @@ function buildInstructions(detectedFrameworks, verbosity) {
|
|
|
10062
10120
|
}
|
|
10063
10121
|
|
|
10064
10122
|
// src/server/consultation-markers.ts
|
|
10065
|
-
import
|
|
10123
|
+
import fs19 from "fs";
|
|
10066
10124
|
import path18 from "path";
|
|
10067
10125
|
import os3 from "os";
|
|
10068
10126
|
import crypto4 from "crypto";
|
|
@@ -10075,8 +10133,8 @@ function markerDir(projectRoot) {
|
|
|
10075
10133
|
function markConsulted(projectRoot, relPath) {
|
|
10076
10134
|
try {
|
|
10077
10135
|
const dir = markerDir(projectRoot);
|
|
10078
|
-
|
|
10079
|
-
|
|
10136
|
+
fs19.mkdirSync(dir, { recursive: true });
|
|
10137
|
+
fs19.writeFileSync(path18.join(dir, fileHash(relPath)), "", { flag: "w" });
|
|
10080
10138
|
} catch {
|
|
10081
10139
|
}
|
|
10082
10140
|
}
|
|
@@ -10694,20 +10752,20 @@ import { z as z3 } from "zod";
|
|
|
10694
10752
|
import path20 from "path";
|
|
10695
10753
|
|
|
10696
10754
|
// src/utils/source-reader.ts
|
|
10697
|
-
import
|
|
10755
|
+
import fs20 from "fs";
|
|
10698
10756
|
import path19 from "path";
|
|
10699
10757
|
var GITIGNORED_NOTICE = "[content hidden \u2014 file is gitignored]";
|
|
10700
10758
|
function readByteRange(filePath, byteStart, byteEnd, gitignored) {
|
|
10701
10759
|
if (gitignored && !isEnvFile(filePath)) return GITIGNORED_NOTICE;
|
|
10702
10760
|
if (byteEnd <= byteStart || byteStart < 0) return "";
|
|
10703
|
-
const fd =
|
|
10761
|
+
const fd = fs20.openSync(filePath, "r");
|
|
10704
10762
|
try {
|
|
10705
10763
|
const length = byteEnd - byteStart;
|
|
10706
10764
|
const buffer = Buffer.alloc(length);
|
|
10707
|
-
const bytesRead =
|
|
10765
|
+
const bytesRead = fs20.readSync(fd, buffer, 0, length, byteStart);
|
|
10708
10766
|
return buffer.subarray(0, bytesRead).toString("utf8");
|
|
10709
10767
|
} finally {
|
|
10710
|
-
|
|
10768
|
+
fs20.closeSync(fd);
|
|
10711
10769
|
}
|
|
10712
10770
|
}
|
|
10713
10771
|
var ENV_BASENAME_RE = /^\.env(\..+)?$/;
|
|
@@ -11767,10 +11825,34 @@ var DEFAULT_WEIGHTS = { primary: 0.4, dependencies: 0.3, callers: 0.2, typeConte
|
|
|
11767
11825
|
function assembleStructuredContext(request) {
|
|
11768
11826
|
const weights = request.budgetWeights ?? DEFAULT_WEIGHTS;
|
|
11769
11827
|
const budget = request.totalBudget;
|
|
11770
|
-
const
|
|
11771
|
-
const
|
|
11772
|
-
|
|
11773
|
-
|
|
11828
|
+
const categories = ["primary", "dependencies", "callers", "typeContext"];
|
|
11829
|
+
const itemCounts = {
|
|
11830
|
+
primary: request.primary.length,
|
|
11831
|
+
dependencies: request.dependencies.length,
|
|
11832
|
+
callers: request.callers.length,
|
|
11833
|
+
typeContext: request.typeContext.length
|
|
11834
|
+
};
|
|
11835
|
+
let surplusWeight = 0;
|
|
11836
|
+
let activeWeight = 0;
|
|
11837
|
+
for (const cat of categories) {
|
|
11838
|
+
if (itemCounts[cat] === 0) {
|
|
11839
|
+
surplusWeight += weights[cat];
|
|
11840
|
+
} else {
|
|
11841
|
+
activeWeight += weights[cat];
|
|
11842
|
+
}
|
|
11843
|
+
}
|
|
11844
|
+
const effectiveWeights = { primary: 0, dependencies: 0, callers: 0, typeContext: 0 };
|
|
11845
|
+
for (const cat of categories) {
|
|
11846
|
+
if (itemCounts[cat] === 0) {
|
|
11847
|
+
effectiveWeights[cat] = 0;
|
|
11848
|
+
} else if (activeWeight > 0) {
|
|
11849
|
+
effectiveWeights[cat] = weights[cat] + surplusWeight * (weights[cat] / activeWeight);
|
|
11850
|
+
}
|
|
11851
|
+
}
|
|
11852
|
+
const primaryResult = assembleContext(request.primary, Math.floor(budget * effectiveWeights.primary));
|
|
11853
|
+
const depsResult = assembleContext(request.dependencies, Math.floor(budget * effectiveWeights.dependencies));
|
|
11854
|
+
const callersResult = assembleContext(request.callers, Math.floor(budget * effectiveWeights.callers));
|
|
11855
|
+
const typeResult = assembleContext(request.typeContext, Math.floor(budget * effectiveWeights.typeContext));
|
|
11774
11856
|
return {
|
|
11775
11857
|
primary: primaryResult.items,
|
|
11776
11858
|
dependencies: depsResult.items,
|
|
@@ -11813,19 +11895,34 @@ var CALL_EDGES = /* @__PURE__ */ new Set([
|
|
|
11813
11895
|
"nest_injects",
|
|
11814
11896
|
"graphql_resolves"
|
|
11815
11897
|
]);
|
|
11816
|
-
|
|
11817
|
-
|
|
11818
|
-
|
|
11819
|
-
return readByteRange(absPath, sym.byte_start, sym.byte_end, !!file.gitignored) ?? void 0;
|
|
11820
|
-
} catch {
|
|
11821
|
-
return void 0;
|
|
11898
|
+
var FileReadCache = class {
|
|
11899
|
+
constructor(rootPath) {
|
|
11900
|
+
this.rootPath = rootPath;
|
|
11822
11901
|
}
|
|
11823
|
-
|
|
11824
|
-
|
|
11902
|
+
rootPath;
|
|
11903
|
+
cache = /* @__PURE__ */ new Map();
|
|
11904
|
+
readSymbolSource(sym, file) {
|
|
11905
|
+
let buf = this.cache.get(file.id);
|
|
11906
|
+
if (buf === void 0) {
|
|
11907
|
+
try {
|
|
11908
|
+
const absPath = path22.resolve(this.rootPath, file.path);
|
|
11909
|
+
const fs98 = __require("fs");
|
|
11910
|
+
buf = fs98.readFileSync(absPath);
|
|
11911
|
+
} catch {
|
|
11912
|
+
buf = null;
|
|
11913
|
+
}
|
|
11914
|
+
this.cache.set(file.id, buf);
|
|
11915
|
+
}
|
|
11916
|
+
if (!buf || sym.byte_start == null || sym.byte_end == null) return void 0;
|
|
11917
|
+
if (file.gitignored) return "[gitignored]";
|
|
11918
|
+
return buf.subarray(sym.byte_start, sym.byte_end).toString("utf-8");
|
|
11919
|
+
}
|
|
11920
|
+
};
|
|
11921
|
+
function toContextItemCached(sym, file, cache, score, signatureOnly) {
|
|
11825
11922
|
return {
|
|
11826
11923
|
id: sym.symbol_id,
|
|
11827
11924
|
score,
|
|
11828
|
-
source:
|
|
11925
|
+
source: signatureOnly ? void 0 : cache.readSymbolSource(sym, file),
|
|
11829
11926
|
signature: sym.signature ?? void 0,
|
|
11830
11927
|
metadata: `[${sym.kind}] ${sym.fqn ?? sym.name} \u2014 ${file.path}`
|
|
11831
11928
|
};
|
|
@@ -11936,14 +12033,16 @@ function getContextBundle(store, rootPath, opts) {
|
|
|
11936
12033
|
}
|
|
11937
12034
|
}
|
|
11938
12035
|
}
|
|
12036
|
+
const fileCache = new FileReadCache(rootPath);
|
|
11939
12037
|
const primaryItems = primarySymbols.map(
|
|
11940
|
-
(p5, i) =>
|
|
12038
|
+
(p5, i) => toContextItemCached(p5.sym, p5.file, fileCache, 1 - i * 0.01, false)
|
|
11941
12039
|
);
|
|
12040
|
+
const MAX_FULL_SOURCE_DEPS = 10;
|
|
11942
12041
|
const depItems = depSymbols.map(
|
|
11943
|
-
(d, i) =>
|
|
12042
|
+
(d, i) => toContextItemCached(d.sym, d.file, fileCache, 0.8 - i * 5e-3, i >= MAX_FULL_SOURCE_DEPS)
|
|
11944
12043
|
);
|
|
11945
12044
|
const callerItems = callerSymbols.map(
|
|
11946
|
-
(c, i) =>
|
|
12045
|
+
(c, i) => toContextItemCached(c.sym, c.file, fileCache, 0.6 - i * 5e-3, i >= MAX_FULL_SOURCE_DEPS)
|
|
11947
12046
|
);
|
|
11948
12047
|
const assembled = assembleStructuredContext({
|
|
11949
12048
|
primary: primaryItems,
|
|
@@ -12530,7 +12629,7 @@ function buildNegativeEvidence(indexedFiles, indexedSymbols, queryExpanded, tool
|
|
|
12530
12629
|
}
|
|
12531
12630
|
|
|
12532
12631
|
// src/tools/navigation/search-text.ts
|
|
12533
|
-
import
|
|
12632
|
+
import fs21 from "fs";
|
|
12534
12633
|
import path24 from "path";
|
|
12535
12634
|
var import_picomatch = __toESM(require_picomatch2(), 1);
|
|
12536
12635
|
function searchText(store, projectRoot, opts) {
|
|
@@ -12580,9 +12679,9 @@ function searchText(store, projectRoot, opts) {
|
|
|
12580
12679
|
if (pathCheck.isErr()) continue;
|
|
12581
12680
|
let content;
|
|
12582
12681
|
try {
|
|
12583
|
-
const stat =
|
|
12682
|
+
const stat = fs21.statSync(absPath);
|
|
12584
12683
|
if (stat.size > 1048576) continue;
|
|
12585
|
-
content =
|
|
12684
|
+
content = fs21.readFileSync(absPath, "utf-8");
|
|
12586
12685
|
} catch {
|
|
12587
12686
|
continue;
|
|
12588
12687
|
}
|
|
@@ -13359,7 +13458,7 @@ function splitControllerRef(ref) {
|
|
|
13359
13458
|
}
|
|
13360
13459
|
|
|
13361
13460
|
// src/tools/framework/middleware-chain.ts
|
|
13362
|
-
import
|
|
13461
|
+
import fs22 from "fs";
|
|
13363
13462
|
import path26 from "path";
|
|
13364
13463
|
function getMiddlewareChain(store, rootPath, url) {
|
|
13365
13464
|
const allRoutes = store.getAllRoutes();
|
|
@@ -13407,9 +13506,9 @@ function detectFramework(allFiles) {
|
|
|
13407
13506
|
}
|
|
13408
13507
|
return "unknown";
|
|
13409
13508
|
}
|
|
13410
|
-
function
|
|
13509
|
+
function readSource(rootPath, filePath) {
|
|
13411
13510
|
try {
|
|
13412
|
-
return
|
|
13511
|
+
return fs22.readFileSync(path26.resolve(rootPath, filePath), "utf-8");
|
|
13413
13512
|
} catch {
|
|
13414
13513
|
return void 0;
|
|
13415
13514
|
}
|
|
@@ -13419,7 +13518,7 @@ function buildExpressChain(store, rootPath, url, allFiles, chain) {
|
|
|
13419
13518
|
const PATH_MW_RE = /(?:app|router)\s*\.\s*use\s*\(\s*['"`]([^'"`]+)['"`]\s*,\s*([A-Za-z][\w.]*)/g;
|
|
13420
13519
|
for (const file of allFiles) {
|
|
13421
13520
|
if (file.framework_role !== "express_router" && file.framework_role !== "express_middleware") continue;
|
|
13422
|
-
const source =
|
|
13521
|
+
const source = readSource(rootPath, file.path);
|
|
13423
13522
|
if (!source) continue;
|
|
13424
13523
|
let match;
|
|
13425
13524
|
const globalRe2 = new RegExp(GLOBAL_MW_RE.source, "g");
|
|
@@ -13444,7 +13543,7 @@ function buildNestChain(store, rootPath, route, allFiles, chain) {
|
|
|
13444
13543
|
const FILTERS_RE = /@UseFilters\(\s*([^)]+)\s*\)/g;
|
|
13445
13544
|
const controllerFiles = allFiles.filter((f) => f.framework_role === "nest_controller");
|
|
13446
13545
|
for (const file of controllerFiles) {
|
|
13447
|
-
const source =
|
|
13546
|
+
const source = readSource(rootPath, file.path);
|
|
13448
13547
|
if (!source) continue;
|
|
13449
13548
|
const extractDecorators2 = (regex, scope) => {
|
|
13450
13549
|
const re = new RegExp(regex.source, "g");
|
|
@@ -13497,7 +13596,7 @@ function buildFlaskChain(store, rootPath, url, allFiles, chain) {
|
|
|
13497
13596
|
}
|
|
13498
13597
|
for (const file of allFiles) {
|
|
13499
13598
|
if (file.framework_role !== "flask_routes") continue;
|
|
13500
|
-
const source =
|
|
13599
|
+
const source = readSource(rootPath, file.path);
|
|
13501
13600
|
if (!source) continue;
|
|
13502
13601
|
const decoratorRe = /@([\w.]+)\s*(?:\([^)]*\))?\s*\n\s*(?:@\w[\w.]*\s*(?:\([^)]*\))?\s*\n\s*)*def\s+\w+/g;
|
|
13503
13602
|
let m;
|
|
@@ -13512,7 +13611,7 @@ function buildFlaskChain(store, rootPath, url, allFiles, chain) {
|
|
|
13512
13611
|
function buildFastAPIChain(store, rootPath, url, allFiles, chain) {
|
|
13513
13612
|
for (const file of allFiles) {
|
|
13514
13613
|
if (file.framework_role !== "fastapi_routes" && file.framework_role !== "fastapi_app") continue;
|
|
13515
|
-
const source =
|
|
13614
|
+
const source = readSource(rootPath, file.path);
|
|
13516
13615
|
if (!source) continue;
|
|
13517
13616
|
const addMwRe = /(?:app|router)\s*\.\s*add_middleware\s*\(\s*([\w.]+)/g;
|
|
13518
13617
|
let m;
|
|
@@ -13540,7 +13639,7 @@ function buildFastAPIChain(store, rootPath, url, allFiles, chain) {
|
|
|
13540
13639
|
function buildDjangoChain(store, rootPath, allFiles, chain) {
|
|
13541
13640
|
for (const file of allFiles) {
|
|
13542
13641
|
if (!file.path.endsWith("settings.py") && !file.path.includes("settings/")) continue;
|
|
13543
|
-
const source =
|
|
13642
|
+
const source = readSource(rootPath, file.path);
|
|
13544
13643
|
if (!source) continue;
|
|
13545
13644
|
const mwMatch = source.match(/MIDDLEWARE\s*=\s*\[([\s\S]*?)\]/);
|
|
13546
13645
|
if (!mwMatch) continue;
|
|
@@ -13554,7 +13653,7 @@ function buildDjangoChain(store, rootPath, allFiles, chain) {
|
|
|
13554
13653
|
}
|
|
13555
13654
|
for (const file of allFiles) {
|
|
13556
13655
|
if (file.framework_role !== "view") continue;
|
|
13557
|
-
const source =
|
|
13656
|
+
const source = readSource(rootPath, file.path);
|
|
13558
13657
|
if (!source) continue;
|
|
13559
13658
|
const decoratorRe = /@([\w.]+)\s*(?:\([^)]*\))?\s*\n\s*(?:@\w[\w.]*\s*(?:\([^)]*\))?\s*\n\s*)*(?:def|class)\s+\w+/g;
|
|
13560
13659
|
let m;
|
|
@@ -13567,11 +13666,11 @@ function buildDjangoChain(store, rootPath, allFiles, chain) {
|
|
|
13567
13666
|
}
|
|
13568
13667
|
|
|
13569
13668
|
// src/tools/analysis/module-graph.ts
|
|
13570
|
-
import
|
|
13669
|
+
import fs24 from "fs";
|
|
13571
13670
|
import path28 from "path";
|
|
13572
13671
|
|
|
13573
13672
|
// src/indexer/plugins/integration/framework/nestjs/index.ts
|
|
13574
|
-
import
|
|
13673
|
+
import fs23 from "fs";
|
|
13575
13674
|
import path27 from "path";
|
|
13576
13675
|
var HTTP_METHODS = ["Get", "Post", "Put", "Delete", "Patch", "Head", "Options"];
|
|
13577
13676
|
var CONTROLLER_RE = /@Controller\(\s*['"`]([^'"`]*)['"`]\s*\)/;
|
|
@@ -13688,7 +13787,7 @@ var NestJSPlugin = class {
|
|
|
13688
13787
|
}
|
|
13689
13788
|
try {
|
|
13690
13789
|
const pkgPath = path27.join(ctx.rootPath, "package.json");
|
|
13691
|
-
const content =
|
|
13790
|
+
const content = fs23.readFileSync(pkgPath, "utf-8");
|
|
13692
13791
|
const pkg = JSON.parse(content);
|
|
13693
13792
|
const deps = {
|
|
13694
13793
|
...pkg.dependencies,
|
|
@@ -13841,7 +13940,7 @@ function getModuleGraph(store, rootPath, moduleName) {
|
|
|
13841
13940
|
for (const file of moduleFiles) {
|
|
13842
13941
|
let source;
|
|
13843
13942
|
try {
|
|
13844
|
-
source =
|
|
13943
|
+
source = fs24.readFileSync(path28.resolve(rootPath, file.path), "utf-8");
|
|
13845
13944
|
} catch {
|
|
13846
13945
|
continue;
|
|
13847
13946
|
}
|
|
@@ -19229,14 +19328,14 @@ function registerGitTools(server, ctx) {
|
|
|
19229
19328
|
import { z as z7 } from "zod";
|
|
19230
19329
|
|
|
19231
19330
|
// src/tools/refactoring/refactor.ts
|
|
19232
|
-
import
|
|
19331
|
+
import fs25 from "fs";
|
|
19233
19332
|
import path35 from "path";
|
|
19234
19333
|
import fg4 from "fast-glob";
|
|
19235
19334
|
function readLines2(filePath) {
|
|
19236
|
-
return
|
|
19335
|
+
return fs25.readFileSync(filePath, "utf-8").split("\n");
|
|
19237
19336
|
}
|
|
19238
19337
|
function writeLines(filePath, lines) {
|
|
19239
|
-
|
|
19338
|
+
fs25.writeFileSync(filePath, lines.join("\n"), "utf-8");
|
|
19240
19339
|
}
|
|
19241
19340
|
function getImportingFiles(store, fileId, projectRoot) {
|
|
19242
19341
|
const fileNodeId = store.getNodeId("file", fileId);
|
|
@@ -19306,7 +19405,7 @@ function applyRename(store, projectRoot, symbolId, newName) {
|
|
|
19306
19405
|
const regex = buildRenameRegex(oldName);
|
|
19307
19406
|
const modifiedFiles = /* @__PURE__ */ new Set();
|
|
19308
19407
|
for (const { filePath } of allFiles) {
|
|
19309
|
-
if (!
|
|
19408
|
+
if (!fs25.existsSync(filePath)) {
|
|
19310
19409
|
result.warnings.push(`File not found on disk: ${filePath}`);
|
|
19311
19410
|
continue;
|
|
19312
19411
|
}
|
|
@@ -19387,7 +19486,7 @@ function removeDeadCode(store, projectRoot, symbolId) {
|
|
|
19387
19486
|
return result;
|
|
19388
19487
|
}
|
|
19389
19488
|
const filePath = path35.resolve(projectRoot, symbolFile.path);
|
|
19390
|
-
if (!
|
|
19489
|
+
if (!fs25.existsSync(filePath)) {
|
|
19391
19490
|
result.error = `File not found on disk: ${filePath}`;
|
|
19392
19491
|
return result;
|
|
19393
19492
|
}
|
|
@@ -19454,7 +19553,7 @@ function extractFunction(store, projectRoot, filePath, startLine, endLine, funct
|
|
|
19454
19553
|
warnings: []
|
|
19455
19554
|
};
|
|
19456
19555
|
const absPath = path35.resolve(projectRoot, filePath);
|
|
19457
|
-
if (!
|
|
19556
|
+
if (!fs25.existsSync(absPath)) {
|
|
19458
19557
|
result.error = `File not found: ${filePath}`;
|
|
19459
19558
|
return result;
|
|
19460
19559
|
}
|
|
@@ -19649,10 +19748,10 @@ function applyCodemod(projectRoot, pattern, replacement, filePattern, options) {
|
|
|
19649
19748
|
const filesWithMatches = /* @__PURE__ */ new Set();
|
|
19650
19749
|
for (const relPath of files) {
|
|
19651
19750
|
const absPath = path35.resolve(projectRoot, relPath);
|
|
19652
|
-
if (!
|
|
19751
|
+
if (!fs25.existsSync(absPath)) continue;
|
|
19653
19752
|
let content;
|
|
19654
19753
|
try {
|
|
19655
|
-
content =
|
|
19754
|
+
content = fs25.readFileSync(absPath, "utf-8");
|
|
19656
19755
|
} catch {
|
|
19657
19756
|
result.warnings.push(`Could not read: ${relPath}`);
|
|
19658
19757
|
continue;
|
|
@@ -19736,12 +19835,12 @@ function applyCodemod(projectRoot, pattern, replacement, filePattern, options) {
|
|
|
19736
19835
|
for (const relPath of filesWithMatches) {
|
|
19737
19836
|
const absPath = path35.resolve(projectRoot, relPath);
|
|
19738
19837
|
try {
|
|
19739
|
-
const content =
|
|
19838
|
+
const content = fs25.readFileSync(absPath, "utf-8");
|
|
19740
19839
|
const flags = options.multiline ? "gms" : "gm";
|
|
19741
19840
|
const freshRegex = new RegExp(pattern, flags);
|
|
19742
19841
|
const newContent = content.replace(freshRegex, replacement);
|
|
19743
19842
|
if (newContent !== content) {
|
|
19744
|
-
|
|
19843
|
+
fs25.writeFileSync(absPath, newContent, "utf-8");
|
|
19745
19844
|
result.files_modified.push(relPath);
|
|
19746
19845
|
}
|
|
19747
19846
|
} catch (e) {
|
|
@@ -20472,7 +20571,7 @@ var TopologyStore = class {
|
|
|
20472
20571
|
};
|
|
20473
20572
|
|
|
20474
20573
|
// src/topology/service-detector.ts
|
|
20475
|
-
import
|
|
20574
|
+
import fs26 from "fs";
|
|
20476
20575
|
import path36 from "path";
|
|
20477
20576
|
function detectServices(repoRoots) {
|
|
20478
20577
|
const services = [];
|
|
@@ -20497,14 +20596,14 @@ function detectFromDockerCompose(root) {
|
|
|
20497
20596
|
let composePath;
|
|
20498
20597
|
for (const f of composeFiles) {
|
|
20499
20598
|
const p5 = path36.join(root, f);
|
|
20500
|
-
if (
|
|
20599
|
+
if (fs26.existsSync(p5)) {
|
|
20501
20600
|
composePath = p5;
|
|
20502
20601
|
break;
|
|
20503
20602
|
}
|
|
20504
20603
|
}
|
|
20505
20604
|
if (!composePath) return [];
|
|
20506
20605
|
try {
|
|
20507
|
-
const content =
|
|
20606
|
+
const content = fs26.readFileSync(composePath, "utf-8");
|
|
20508
20607
|
const services = [];
|
|
20509
20608
|
const lines = content.split("\n");
|
|
20510
20609
|
let inServices = false;
|
|
@@ -20550,7 +20649,7 @@ function detectFromDockerCompose(root) {
|
|
|
20550
20649
|
}
|
|
20551
20650
|
|
|
20552
20651
|
// src/topology/contract-parser.ts
|
|
20553
|
-
import
|
|
20652
|
+
import fs27 from "fs";
|
|
20554
20653
|
import path37 from "path";
|
|
20555
20654
|
var EXCLUDE_DIRS = ["node_modules", "vendor", ".git", "dist", "build", "__pycache__"];
|
|
20556
20655
|
function parseContracts(repoRoot) {
|
|
@@ -20558,7 +20657,7 @@ function parseContracts(repoRoot) {
|
|
|
20558
20657
|
const specFiles = findSpecFiles(repoRoot);
|
|
20559
20658
|
for (const { filePath, type } of specFiles) {
|
|
20560
20659
|
try {
|
|
20561
|
-
const content =
|
|
20660
|
+
const content = fs27.readFileSync(filePath, "utf-8");
|
|
20562
20661
|
const relPath = path37.relative(repoRoot, filePath);
|
|
20563
20662
|
let contract = null;
|
|
20564
20663
|
switch (type) {
|
|
@@ -20678,7 +20777,7 @@ function findSpecFiles(root) {
|
|
|
20678
20777
|
if (depth > 5) return;
|
|
20679
20778
|
let entries;
|
|
20680
20779
|
try {
|
|
20681
|
-
entries =
|
|
20780
|
+
entries = fs27.readdirSync(dir, { withFileTypes: true });
|
|
20682
20781
|
} catch {
|
|
20683
20782
|
return;
|
|
20684
20783
|
}
|
|
@@ -20929,11 +21028,11 @@ function getContractDrift(topoStore, store, projectRoot, additionalRepos, opts)
|
|
|
20929
21028
|
|
|
20930
21029
|
// src/federation/manager.ts
|
|
20931
21030
|
import path39 from "path";
|
|
20932
|
-
import
|
|
21031
|
+
import fs29 from "fs";
|
|
20933
21032
|
import Database3 from "better-sqlite3";
|
|
20934
21033
|
|
|
20935
21034
|
// src/federation/scanner.ts
|
|
20936
|
-
import
|
|
21035
|
+
import fs28 from "fs";
|
|
20937
21036
|
import path38 from "path";
|
|
20938
21037
|
var CALL_PATTERNS2 = [
|
|
20939
21038
|
// fetch('url') / fetch(`url`)
|
|
@@ -21061,7 +21160,7 @@ function walkAndScan(dir, repoRoot, results, depth) {
|
|
|
21061
21160
|
if (depth > 10) return;
|
|
21062
21161
|
let entries;
|
|
21063
21162
|
try {
|
|
21064
|
-
entries =
|
|
21163
|
+
entries = fs28.readdirSync(dir, { withFileTypes: true });
|
|
21065
21164
|
} catch {
|
|
21066
21165
|
return;
|
|
21067
21166
|
}
|
|
@@ -21072,7 +21171,7 @@ function walkAndScan(dir, repoRoot, results, depth) {
|
|
|
21072
21171
|
walkAndScan(fullPath, repoRoot, results, depth + 1);
|
|
21073
21172
|
} else if (entry.isFile() && CODE_EXTENSIONS.has(path38.extname(entry.name).toLowerCase())) {
|
|
21074
21173
|
try {
|
|
21075
|
-
const content =
|
|
21174
|
+
const content = fs28.readFileSync(fullPath, "utf-8");
|
|
21076
21175
|
const relPath = path38.relative(repoRoot, fullPath);
|
|
21077
21176
|
scanFileContent(relPath, content, results);
|
|
21078
21177
|
} catch {
|
|
@@ -21121,7 +21220,7 @@ var FederationManager = class {
|
|
|
21121
21220
|
*/
|
|
21122
21221
|
add(repoRoot, opts) {
|
|
21123
21222
|
const absRoot = path39.resolve(repoRoot);
|
|
21124
|
-
if (!
|
|
21223
|
+
if (!fs29.existsSync(absRoot)) {
|
|
21125
21224
|
throw new Error(`Repository path does not exist: ${absRoot}`);
|
|
21126
21225
|
}
|
|
21127
21226
|
const repoName = opts?.name ?? path39.basename(absRoot);
|
|
@@ -21129,7 +21228,7 @@ var FederationManager = class {
|
|
|
21129
21228
|
const repoId = this.topoStore.upsertFederatedRepo({
|
|
21130
21229
|
name: repoName,
|
|
21131
21230
|
repoRoot: absRoot,
|
|
21132
|
-
dbPath:
|
|
21231
|
+
dbPath: fs29.existsSync(dbPath) ? dbPath : void 0,
|
|
21133
21232
|
contractPaths: opts?.contractPaths
|
|
21134
21233
|
});
|
|
21135
21234
|
const detected = detectServices([absRoot]);
|
|
@@ -21146,7 +21245,7 @@ var FederationManager = class {
|
|
|
21146
21245
|
if (opts?.contractPaths) {
|
|
21147
21246
|
for (const cp of opts.contractPaths) {
|
|
21148
21247
|
const absContract = path39.resolve(absRoot, cp);
|
|
21149
|
-
if (
|
|
21248
|
+
if (fs29.existsSync(absContract)) {
|
|
21150
21249
|
const additionalContracts = parseContracts(path39.dirname(absContract));
|
|
21151
21250
|
contracts.push(...additionalContracts.filter(
|
|
21152
21251
|
(c) => path39.resolve(absRoot, c.specPath) === absContract
|
|
@@ -21295,7 +21394,7 @@ var FederationManager = class {
|
|
|
21295
21394
|
let endpointsUpdated = 0;
|
|
21296
21395
|
let clientCallsScanned = 0;
|
|
21297
21396
|
for (const repo of repos) {
|
|
21298
|
-
if (!
|
|
21397
|
+
if (!fs29.existsSync(repo.repo_root)) {
|
|
21299
21398
|
logger.warn({ repo: repo.name, root: repo.repo_root }, "Federated repo no longer exists, skipping");
|
|
21300
21399
|
continue;
|
|
21301
21400
|
}
|
|
@@ -21408,7 +21507,7 @@ var FederationManager = class {
|
|
|
21408
21507
|
for (const [repoName, calls] of byRepo) {
|
|
21409
21508
|
const repo2 = this.topoStore.getFederatedRepo(repoName);
|
|
21410
21509
|
for (const call of calls) {
|
|
21411
|
-
const symbols = repo2?.db_path &&
|
|
21510
|
+
const symbols = repo2?.db_path && fs29.existsSync(repo2.db_path) ? resolveSymbolsAtLocation(repo2.db_path, call.file_path, call.line) : [];
|
|
21412
21511
|
clients.push({
|
|
21413
21512
|
repo: repoName,
|
|
21414
21513
|
filePath: call.file_path,
|
|
@@ -23372,7 +23471,7 @@ function graphQuery(store, query, options = {}) {
|
|
|
23372
23471
|
}
|
|
23373
23472
|
|
|
23374
23473
|
// src/tools/analysis/dataflow.ts
|
|
23375
|
-
import
|
|
23474
|
+
import fs30 from "fs";
|
|
23376
23475
|
import path40 from "path";
|
|
23377
23476
|
function getDataflow(store, projectRoot, opts) {
|
|
23378
23477
|
const symbol = opts.symbolId ? store.getSymbolBySymbolId(opts.symbolId) : opts.fqn ? store.getSymbolByFqn(opts.fqn) : void 0;
|
|
@@ -23387,7 +23486,7 @@ function getDataflow(store, projectRoot, opts) {
|
|
|
23387
23486
|
const absPath = path40.resolve(projectRoot, file.path);
|
|
23388
23487
|
let content;
|
|
23389
23488
|
try {
|
|
23390
|
-
content =
|
|
23489
|
+
content = fs30.readFileSync(absPath, "utf-8");
|
|
23391
23490
|
} catch {
|
|
23392
23491
|
return err(validationError(`Cannot read file: ${file.path}`));
|
|
23393
23492
|
}
|
|
@@ -23540,7 +23639,7 @@ function escapeRegex3(str2) {
|
|
|
23540
23639
|
}
|
|
23541
23640
|
|
|
23542
23641
|
// src/tools/analysis/visualize.ts
|
|
23543
|
-
import
|
|
23642
|
+
import fs31 from "fs";
|
|
23544
23643
|
import path41 from "path";
|
|
23545
23644
|
var import_picomatch2 = __toESM(require_picomatch2(), 1);
|
|
23546
23645
|
function detectCommunities(nodeIds, edges) {
|
|
@@ -23914,7 +24013,7 @@ function visualizeGraph(store, opts) {
|
|
|
23914
24013
|
const layout = opts.layout ?? "force";
|
|
23915
24014
|
const html = generateHtml(nodes, edges, communities, layout);
|
|
23916
24015
|
const outputPath = opts.output ?? path41.join(process.env.TMPDIR ?? "/tmp", "trace-mcp-graph.html");
|
|
23917
|
-
|
|
24016
|
+
fs31.writeFileSync(outputPath, html, "utf-8");
|
|
23918
24017
|
return ok({
|
|
23919
24018
|
outputPath,
|
|
23920
24019
|
nodes: nodes.length,
|
|
@@ -25819,7 +25918,7 @@ function getCommunityDetail(store, communityId) {
|
|
|
25819
25918
|
}
|
|
25820
25919
|
|
|
25821
25920
|
// src/tools/quality/audit-config.ts
|
|
25822
|
-
import
|
|
25921
|
+
import fs32 from "fs";
|
|
25823
25922
|
import path42 from "path";
|
|
25824
25923
|
var CONFIG_PATTERNS = [
|
|
25825
25924
|
"CLAUDE.md",
|
|
@@ -25848,9 +25947,9 @@ function auditConfig(store, projectRoot, options = {}) {
|
|
|
25848
25947
|
const fileContents = /* @__PURE__ */ new Map();
|
|
25849
25948
|
for (const file of configFiles) {
|
|
25850
25949
|
const absPath = resolveConfigPath(file, projectRoot);
|
|
25851
|
-
if (!
|
|
25950
|
+
if (!fs32.existsSync(absPath)) continue;
|
|
25852
25951
|
try {
|
|
25853
|
-
const content =
|
|
25952
|
+
const content = fs32.readFileSync(absPath, "utf-8");
|
|
25854
25953
|
fileContents.set(file, { content, lines: content.split("\n") });
|
|
25855
25954
|
totalTokens += Math.ceil(content.length / 4);
|
|
25856
25955
|
} catch {
|
|
@@ -25863,7 +25962,7 @@ function auditConfig(store, projectRoot, options = {}) {
|
|
|
25863
25962
|
if (pathMatches) {
|
|
25864
25963
|
for (const ref of pathMatches) {
|
|
25865
25964
|
const refPath = path42.join(projectRoot, ref);
|
|
25866
|
-
if (!
|
|
25965
|
+
if (!fs32.existsSync(refPath) && !store.getFile(ref)) {
|
|
25867
25966
|
issues.push({
|
|
25868
25967
|
file,
|
|
25869
25968
|
line: i + 1,
|
|
@@ -25976,11 +26075,11 @@ function findConfigFiles(projectRoot) {
|
|
|
25976
26075
|
const found = [];
|
|
25977
26076
|
for (const pattern of CONFIG_PATTERNS) {
|
|
25978
26077
|
const absPath = path42.join(projectRoot, pattern);
|
|
25979
|
-
if (
|
|
26078
|
+
if (fs32.existsSync(absPath)) found.push(pattern);
|
|
25980
26079
|
}
|
|
25981
26080
|
for (const pattern of GLOBAL_CONFIG_PATTERNS) {
|
|
25982
26081
|
const absPath = pattern.replace("~", process.env.HOME ?? "");
|
|
25983
|
-
if (
|
|
26082
|
+
if (fs32.existsSync(absPath)) found.push(pattern);
|
|
25984
26083
|
}
|
|
25985
26084
|
return found;
|
|
25986
26085
|
}
|
|
@@ -26212,7 +26311,7 @@ function cfgToAscii(cfg) {
|
|
|
26212
26311
|
}
|
|
26213
26312
|
|
|
26214
26313
|
// src/tools/analysis/control-flow.ts
|
|
26215
|
-
import
|
|
26314
|
+
import fs33 from "fs";
|
|
26216
26315
|
import path43 from "path";
|
|
26217
26316
|
function getControlFlow(store, projectRoot, options) {
|
|
26218
26317
|
const { symbolId, fqn, format, simplify } = options;
|
|
@@ -26237,10 +26336,10 @@ function getControlFlow(store, projectRoot, options) {
|
|
|
26237
26336
|
return err(notFound(`file for symbol`));
|
|
26238
26337
|
}
|
|
26239
26338
|
const absPath = path43.isAbsolute(file.path) ? file.path : path43.join(projectRoot, file.path);
|
|
26240
|
-
if (!
|
|
26339
|
+
if (!fs33.existsSync(absPath)) {
|
|
26241
26340
|
return err(validationError(`File not on disk: ${file.path}`));
|
|
26242
26341
|
}
|
|
26243
|
-
const content =
|
|
26342
|
+
const content = fs33.readFileSync(absPath, "utf-8");
|
|
26244
26343
|
const lines = content.split("\n");
|
|
26245
26344
|
const startLine = symbol.line_start ?? 1;
|
|
26246
26345
|
const endLine = symbol.line_end ?? lines.length;
|
|
@@ -26301,12 +26400,12 @@ function simplifyCFG(cfg) {
|
|
|
26301
26400
|
}
|
|
26302
26401
|
|
|
26303
26402
|
// src/tools/project/package-deps.ts
|
|
26304
|
-
import
|
|
26403
|
+
import fs34 from "fs";
|
|
26305
26404
|
import path44 from "path";
|
|
26306
26405
|
function loadRegistry() {
|
|
26307
|
-
if (!
|
|
26406
|
+
if (!fs34.existsSync(REGISTRY_PATH)) return {};
|
|
26308
26407
|
try {
|
|
26309
|
-
const raw = JSON.parse(
|
|
26408
|
+
const raw = JSON.parse(fs34.readFileSync(REGISTRY_PATH, "utf-8"));
|
|
26310
26409
|
return raw.projects ?? raw ?? {};
|
|
26311
26410
|
} catch {
|
|
26312
26411
|
return {};
|
|
@@ -26315,9 +26414,9 @@ function loadRegistry() {
|
|
|
26315
26414
|
function readManifest(repoPath) {
|
|
26316
26415
|
const result = { name: void 0, deps: /* @__PURE__ */ new Map(), publishes: [] };
|
|
26317
26416
|
const pkgJsonPath = path44.join(repoPath, "package.json");
|
|
26318
|
-
if (
|
|
26417
|
+
if (fs34.existsSync(pkgJsonPath)) {
|
|
26319
26418
|
try {
|
|
26320
|
-
const pkg = JSON.parse(
|
|
26419
|
+
const pkg = JSON.parse(fs34.readFileSync(pkgJsonPath, "utf-8"));
|
|
26321
26420
|
result.name = pkg.name;
|
|
26322
26421
|
if (pkg.name) result.publishes.push(pkg.name);
|
|
26323
26422
|
for (const [dep, ver] of Object.entries(pkg.dependencies ?? {})) {
|
|
@@ -26330,9 +26429,9 @@ function readManifest(repoPath) {
|
|
|
26330
26429
|
}
|
|
26331
26430
|
}
|
|
26332
26431
|
const composerPath = path44.join(repoPath, "composer.json");
|
|
26333
|
-
if (
|
|
26432
|
+
if (fs34.existsSync(composerPath)) {
|
|
26334
26433
|
try {
|
|
26335
|
-
const composer = JSON.parse(
|
|
26434
|
+
const composer = JSON.parse(fs34.readFileSync(composerPath, "utf-8"));
|
|
26336
26435
|
if (composer.name) {
|
|
26337
26436
|
result.name ??= composer.name;
|
|
26338
26437
|
result.publishes.push(composer.name);
|
|
@@ -26348,9 +26447,9 @@ function readManifest(repoPath) {
|
|
|
26348
26447
|
}
|
|
26349
26448
|
}
|
|
26350
26449
|
const pyprojectPath = path44.join(repoPath, "pyproject.toml");
|
|
26351
|
-
if (
|
|
26450
|
+
if (fs34.existsSync(pyprojectPath)) {
|
|
26352
26451
|
try {
|
|
26353
|
-
const content =
|
|
26452
|
+
const content = fs34.readFileSync(pyprojectPath, "utf-8");
|
|
26354
26453
|
const nameMatch = content.match(/^name\s*=\s*"([^"]+)"/m);
|
|
26355
26454
|
if (nameMatch) {
|
|
26356
26455
|
result.name ??= nameMatch[1];
|
|
@@ -26375,7 +26474,7 @@ function getPackageDeps(options) {
|
|
|
26375
26474
|
const publishMap = /* @__PURE__ */ new Map();
|
|
26376
26475
|
for (const [repoPath, entry] of Object.entries(registry)) {
|
|
26377
26476
|
const absPath = repoPath;
|
|
26378
|
-
if (!
|
|
26477
|
+
if (!fs34.existsSync(absPath)) continue;
|
|
26379
26478
|
const manifest = readManifest(absPath);
|
|
26380
26479
|
repoManifests.set(repoPath, manifest);
|
|
26381
26480
|
const allPublishes = [...entry.publishes ?? [], ...manifest.publishes];
|
|
@@ -26729,7 +26828,7 @@ function escapeHtml(s) {
|
|
|
26729
26828
|
|
|
26730
26829
|
// src/tools/refactoring/pack-context.ts
|
|
26731
26830
|
init_graph_analysis();
|
|
26732
|
-
import
|
|
26831
|
+
import fs35 from "fs";
|
|
26733
26832
|
import path45 from "path";
|
|
26734
26833
|
function estimateTokens2(text) {
|
|
26735
26834
|
return Math.ceil(text.length / 4);
|
|
@@ -26808,10 +26907,10 @@ ${outlineLines.join("\n")}
|
|
|
26808
26907
|
let sourceTokens = 0;
|
|
26809
26908
|
for (const f of files) {
|
|
26810
26909
|
const absPath = path45.join(projectRoot, f.path);
|
|
26811
|
-
if (!
|
|
26910
|
+
if (!fs35.existsSync(absPath)) continue;
|
|
26812
26911
|
let content;
|
|
26813
26912
|
try {
|
|
26814
|
-
content =
|
|
26913
|
+
content = fs35.readFileSync(absPath, "utf-8");
|
|
26815
26914
|
} catch {
|
|
26816
26915
|
continue;
|
|
26817
26916
|
}
|
|
@@ -27728,11 +27827,11 @@ function registerAITools(server, ctx) {
|
|
|
27728
27827
|
// src/bundles.ts
|
|
27729
27828
|
import Database4 from "better-sqlite3";
|
|
27730
27829
|
import path47 from "path";
|
|
27731
|
-
import
|
|
27830
|
+
import fs36 from "fs";
|
|
27732
27831
|
import crypto5 from "crypto";
|
|
27733
27832
|
var BUNDLES_DIR = path47.join(TRACE_MCP_HOME, "bundles");
|
|
27734
27833
|
function ensureBundlesDir() {
|
|
27735
|
-
|
|
27834
|
+
fs36.mkdirSync(BUNDLES_DIR, { recursive: true });
|
|
27736
27835
|
}
|
|
27737
27836
|
function getBundlePath(packageName, version) {
|
|
27738
27837
|
const safeName = packageName.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
@@ -27743,22 +27842,22 @@ function getManifestPath() {
|
|
|
27743
27842
|
}
|
|
27744
27843
|
function loadManifest() {
|
|
27745
27844
|
const p5 = getManifestPath();
|
|
27746
|
-
if (!
|
|
27845
|
+
if (!fs36.existsSync(p5)) return { bundles: [] };
|
|
27747
27846
|
try {
|
|
27748
|
-
return JSON.parse(
|
|
27847
|
+
return JSON.parse(fs36.readFileSync(p5, "utf-8"));
|
|
27749
27848
|
} catch {
|
|
27750
27849
|
return { bundles: [] };
|
|
27751
27850
|
}
|
|
27752
27851
|
}
|
|
27753
27852
|
function saveManifest(manifest) {
|
|
27754
27853
|
ensureBundlesDir();
|
|
27755
|
-
|
|
27854
|
+
fs36.writeFileSync(getManifestPath(), JSON.stringify(manifest, null, 2) + "\n");
|
|
27756
27855
|
}
|
|
27757
27856
|
function exportBundle(sourceDbPath, packageName, version) {
|
|
27758
27857
|
ensureBundlesDir();
|
|
27759
27858
|
const bundlePath = getBundlePath(packageName, version);
|
|
27760
27859
|
const src = new Database4(sourceDbPath, { readonly: true });
|
|
27761
|
-
if (
|
|
27860
|
+
if (fs36.existsSync(bundlePath)) fs36.unlinkSync(bundlePath);
|
|
27762
27861
|
const dst = new Database4(bundlePath);
|
|
27763
27862
|
dst.pragma("journal_mode = WAL");
|
|
27764
27863
|
dst.pragma("synchronous = OFF");
|
|
@@ -27897,7 +27996,7 @@ function exportBundle(sourceDbPath, packageName, version) {
|
|
|
27897
27996
|
dst.exec("VACUUM");
|
|
27898
27997
|
dst.close();
|
|
27899
27998
|
src.close();
|
|
27900
|
-
const bundleContent =
|
|
27999
|
+
const bundleContent = fs36.readFileSync(bundlePath);
|
|
27901
28000
|
const sha256 = crypto5.createHash("sha256").update(bundleContent).digest("hex");
|
|
27902
28001
|
const sizeBytes = bundleContent.length;
|
|
27903
28002
|
const entry = {
|
|
@@ -27929,7 +28028,7 @@ function removeBundle(packageName, version) {
|
|
|
27929
28028
|
);
|
|
27930
28029
|
for (const entry of toRemove) {
|
|
27931
28030
|
const fp = path47.join(BUNDLES_DIR, entry.file);
|
|
27932
|
-
if (
|
|
28031
|
+
if (fs36.existsSync(fp)) fs36.unlinkSync(fp);
|
|
27933
28032
|
}
|
|
27934
28033
|
manifest.bundles = manifest.bundles.filter(
|
|
27935
28034
|
(b) => !(b.package === packageName && (!version || b.version === version))
|
|
@@ -27939,7 +28038,7 @@ function removeBundle(packageName, version) {
|
|
|
27939
28038
|
}
|
|
27940
28039
|
function loadBundle(packageName, version) {
|
|
27941
28040
|
const bundlePath = getBundlePath(packageName, version);
|
|
27942
|
-
if (!
|
|
28041
|
+
if (!fs36.existsSync(bundlePath)) return null;
|
|
27943
28042
|
try {
|
|
27944
28043
|
const db = new Database4(bundlePath, { readonly: true });
|
|
27945
28044
|
return { package: packageName, version, db };
|
|
@@ -28225,7 +28324,7 @@ var AnalyticsStore = class {
|
|
|
28225
28324
|
};
|
|
28226
28325
|
|
|
28227
28326
|
// src/analytics/log-parser.ts
|
|
28228
|
-
import
|
|
28327
|
+
import fs37 from "fs";
|
|
28229
28328
|
import path49 from "path";
|
|
28230
28329
|
import os4 from "os";
|
|
28231
28330
|
var CLAUDE_PROJECTS_DIR = path49.join(os4.homedir(), ".claude", "projects");
|
|
@@ -28303,7 +28402,7 @@ function processToolResult(item, toolResults) {
|
|
|
28303
28402
|
}
|
|
28304
28403
|
function parseSessionFile(filePath, projectPath) {
|
|
28305
28404
|
try {
|
|
28306
|
-
const content =
|
|
28405
|
+
const content = fs37.readFileSync(filePath, "utf-8");
|
|
28307
28406
|
const lines = content.split("\n").filter((l) => l.trim());
|
|
28308
28407
|
const sessionId = path49.basename(filePath, ".jsonl");
|
|
28309
28408
|
const toolCalls = [];
|
|
@@ -28395,7 +28494,7 @@ function decodeDirName(dirName) {
|
|
|
28395
28494
|
const seg = parts[i];
|
|
28396
28495
|
const candidate = base + "/" + (tail ? tail + "-" + seg : seg);
|
|
28397
28496
|
try {
|
|
28398
|
-
if (
|
|
28497
|
+
if (fs37.statSync(candidate).isDirectory()) {
|
|
28399
28498
|
base = candidate;
|
|
28400
28499
|
tail = "";
|
|
28401
28500
|
continue;
|
|
@@ -28405,7 +28504,7 @@ function decodeDirName(dirName) {
|
|
|
28405
28504
|
if (tail) {
|
|
28406
28505
|
const slashCandidate = base + "/" + tail;
|
|
28407
28506
|
try {
|
|
28408
|
-
if (
|
|
28507
|
+
if (fs37.statSync(slashCandidate).isDirectory()) {
|
|
28409
28508
|
base = slashCandidate;
|
|
28410
28509
|
tail = seg;
|
|
28411
28510
|
continue;
|
|
@@ -28418,8 +28517,8 @@ function decodeDirName(dirName) {
|
|
|
28418
28517
|
return tail ? base + "/" + tail : base;
|
|
28419
28518
|
}
|
|
28420
28519
|
function listProjectDirs() {
|
|
28421
|
-
if (!
|
|
28422
|
-
const entries =
|
|
28520
|
+
if (!fs37.existsSync(CLAUDE_PROJECTS_DIR)) return [];
|
|
28521
|
+
const entries = fs37.readdirSync(CLAUDE_PROJECTS_DIR, { withFileTypes: true });
|
|
28423
28522
|
return entries.filter((e) => e.isDirectory()).map((e) => ({
|
|
28424
28523
|
dirName: e.name,
|
|
28425
28524
|
projectPath: decodeDirName(e.name)
|
|
@@ -28427,11 +28526,11 @@ function listProjectDirs() {
|
|
|
28427
28526
|
}
|
|
28428
28527
|
function listSessionFiles(projectDirName) {
|
|
28429
28528
|
const dir = path49.join(CLAUDE_PROJECTS_DIR, projectDirName);
|
|
28430
|
-
if (!
|
|
28431
|
-
const entries =
|
|
28529
|
+
if (!fs37.existsSync(dir)) return [];
|
|
28530
|
+
const entries = fs37.readdirSync(dir, { withFileTypes: true });
|
|
28432
28531
|
return entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => {
|
|
28433
28532
|
const filePath = path49.join(dir, e.name);
|
|
28434
|
-
const stat =
|
|
28533
|
+
const stat = fs37.statSync(filePath);
|
|
28435
28534
|
return { filePath, mtime: stat.mtimeMs };
|
|
28436
28535
|
});
|
|
28437
28536
|
}
|
|
@@ -28445,14 +28544,14 @@ function listAllSessions() {
|
|
|
28445
28544
|
const clawProjectPaths = discoverClawProjects();
|
|
28446
28545
|
for (const projectPath of clawProjectPaths) {
|
|
28447
28546
|
const sessionsDir = path49.join(projectPath, CLAW_SESSIONS_DIR_NAME);
|
|
28448
|
-
if (!
|
|
28547
|
+
if (!fs37.existsSync(sessionsDir)) continue;
|
|
28449
28548
|
try {
|
|
28450
|
-
const entries =
|
|
28549
|
+
const entries = fs37.readdirSync(sessionsDir, { withFileTypes: true });
|
|
28451
28550
|
for (const e of entries) {
|
|
28452
28551
|
if (!e.isFile() || !e.name.endsWith(".jsonl")) continue;
|
|
28453
28552
|
const filePath = path49.join(sessionsDir, e.name);
|
|
28454
28553
|
try {
|
|
28455
|
-
const stat =
|
|
28554
|
+
const stat = fs37.statSync(filePath);
|
|
28456
28555
|
results.push({ filePath, projectPath, client: "claw-code", mtime: stat.mtimeMs });
|
|
28457
28556
|
} catch {
|
|
28458
28557
|
}
|
|
@@ -28465,25 +28564,25 @@ function listAllSessions() {
|
|
|
28465
28564
|
function discoverClawProjects() {
|
|
28466
28565
|
const paths = /* @__PURE__ */ new Set();
|
|
28467
28566
|
for (const { projectPath } of listProjectDirs()) {
|
|
28468
|
-
if (
|
|
28567
|
+
if (fs37.existsSync(path49.join(projectPath, CLAW_SESSIONS_DIR_NAME))) {
|
|
28469
28568
|
paths.add(projectPath);
|
|
28470
28569
|
}
|
|
28471
28570
|
}
|
|
28472
28571
|
const cwd = process.cwd();
|
|
28473
|
-
if (
|
|
28572
|
+
if (fs37.existsSync(path49.join(cwd, CLAW_SESSIONS_DIR_NAME))) {
|
|
28474
28573
|
paths.add(cwd);
|
|
28475
28574
|
}
|
|
28476
28575
|
const home = os4.homedir();
|
|
28477
28576
|
const commonRoots = ["Projects", "projects", "dev", "workspace", "code", "PhpstormProjects", "WebstormProjects", "src"];
|
|
28478
28577
|
for (const root of commonRoots) {
|
|
28479
28578
|
const rootDir = path49.join(home, root);
|
|
28480
|
-
if (!
|
|
28579
|
+
if (!fs37.existsSync(rootDir)) continue;
|
|
28481
28580
|
try {
|
|
28482
|
-
const entries =
|
|
28581
|
+
const entries = fs37.readdirSync(rootDir, { withFileTypes: true });
|
|
28483
28582
|
for (const e of entries) {
|
|
28484
28583
|
if (!e.isDirectory()) continue;
|
|
28485
28584
|
const projectDir = path49.join(rootDir, e.name);
|
|
28486
|
-
if (
|
|
28585
|
+
if (fs37.existsSync(path49.join(projectDir, CLAW_SESSIONS_DIR_NAME))) {
|
|
28487
28586
|
paths.add(projectDir);
|
|
28488
28587
|
}
|
|
28489
28588
|
}
|
|
@@ -29053,8 +29152,9 @@ function benchmarkContextBundle(store, symbols, count, rand) {
|
|
|
29053
29152
|
const group = sampled.slice(i * batchSize, (i + 1) * batchSize);
|
|
29054
29153
|
const totalSourceBytes = group.reduce((s, sym) => s + (sym.source_bytes || Math.round(sym.file_byte_length * 0.08)), 0);
|
|
29055
29154
|
const importOverhead = group.length * 200;
|
|
29056
|
-
const
|
|
29057
|
-
const
|
|
29155
|
+
const perCallHintsOverhead = group.length * 120;
|
|
29156
|
+
const bl = estimateTokens3(totalSourceBytes + importOverhead) + perCallHintsOverhead;
|
|
29157
|
+
const tm = estimateTokens3(Math.round((totalSourceBytes + importOverhead) * 0.45));
|
|
29058
29158
|
const names = group.map((g) => g.name).join(", ");
|
|
29059
29159
|
details.push({ query: names, file: group[0].file_path, baseline_tokens: bl, trace_mcp_tokens: tm, reduction_pct: reductionPct(bl, tm) });
|
|
29060
29160
|
}
|
|
@@ -29067,10 +29167,13 @@ function benchmarkBatchOverhead(symbols, files, count, rand) {
|
|
|
29067
29167
|
const details = [];
|
|
29068
29168
|
for (let i = 0; i < batches; i++) {
|
|
29069
29169
|
const group = sampledSymbols.slice(i * batchSize, (i + 1) * batchSize);
|
|
29070
|
-
const
|
|
29170
|
+
const perCallFramingOverhead = 150;
|
|
29171
|
+
const perCallHintsOverhead = 120;
|
|
29172
|
+
const perCallMetadataOverhead = 40;
|
|
29173
|
+
const perCallOverhead = perCallFramingOverhead + perCallHintsOverhead + perCallMetadataOverhead;
|
|
29071
29174
|
const contentTokens = group.reduce((s, sym) => s + estimateTokens3(sym.source_bytes || 200), 0);
|
|
29072
29175
|
const bl = contentTokens + batchSize * perCallOverhead;
|
|
29073
|
-
const tm = contentTokens +
|
|
29176
|
+
const tm = contentTokens + perCallFramingOverhead;
|
|
29074
29177
|
const names = group.map((g) => g.name).join(", ");
|
|
29075
29178
|
details.push({ query: names, file: group[0].file_path, baseline_tokens: bl, trace_mcp_tokens: tm, reduction_pct: reductionPct(bl, tm) });
|
|
29076
29179
|
}
|
|
@@ -29183,7 +29286,7 @@ function formatBenchmarkMarkdown(result) {
|
|
|
29183
29286
|
}
|
|
29184
29287
|
|
|
29185
29288
|
// src/analytics/tech-detector.ts
|
|
29186
|
-
import
|
|
29289
|
+
import fs38 from "fs";
|
|
29187
29290
|
import path50 from "path";
|
|
29188
29291
|
|
|
29189
29292
|
// src/analytics/known-packages.ts
|
|
@@ -29355,7 +29458,7 @@ var KNOWN_PACKAGES = {
|
|
|
29355
29458
|
// src/analytics/tech-detector.ts
|
|
29356
29459
|
function parsePackageJson(filePath) {
|
|
29357
29460
|
try {
|
|
29358
|
-
const pkg = JSON.parse(
|
|
29461
|
+
const pkg = JSON.parse(fs38.readFileSync(filePath, "utf-8"));
|
|
29359
29462
|
const deps = [];
|
|
29360
29463
|
for (const [name, version] of Object.entries(pkg.dependencies ?? {})) {
|
|
29361
29464
|
deps.push({ name, version: String(version), isDev: false });
|
|
@@ -29370,7 +29473,7 @@ function parsePackageJson(filePath) {
|
|
|
29370
29473
|
}
|
|
29371
29474
|
function parseComposerJson(filePath) {
|
|
29372
29475
|
try {
|
|
29373
|
-
const pkg = JSON.parse(
|
|
29476
|
+
const pkg = JSON.parse(fs38.readFileSync(filePath, "utf-8"));
|
|
29374
29477
|
const deps = [];
|
|
29375
29478
|
for (const [name, version] of Object.entries(pkg.require ?? {})) {
|
|
29376
29479
|
if (name === "php" || name.startsWith("ext-")) continue;
|
|
@@ -29386,7 +29489,7 @@ function parseComposerJson(filePath) {
|
|
|
29386
29489
|
}
|
|
29387
29490
|
function parseRequirementsTxt(filePath) {
|
|
29388
29491
|
try {
|
|
29389
|
-
const content =
|
|
29492
|
+
const content = fs38.readFileSync(filePath, "utf-8");
|
|
29390
29493
|
const deps = [];
|
|
29391
29494
|
for (const line of content.split("\n")) {
|
|
29392
29495
|
const trimmed = line.trim();
|
|
@@ -29403,7 +29506,7 @@ function parseRequirementsTxt(filePath) {
|
|
|
29403
29506
|
}
|
|
29404
29507
|
function parsePyprojectToml(filePath) {
|
|
29405
29508
|
try {
|
|
29406
|
-
const content =
|
|
29509
|
+
const content = fs38.readFileSync(filePath, "utf-8");
|
|
29407
29510
|
const deps = [];
|
|
29408
29511
|
const depSection = content.match(/\[project\][\s\S]*?dependencies\s*=\s*\[([\s\S]*?)\]/);
|
|
29409
29512
|
if (depSection) {
|
|
@@ -29419,7 +29522,7 @@ function parsePyprojectToml(filePath) {
|
|
|
29419
29522
|
}
|
|
29420
29523
|
function parseGoMod(filePath) {
|
|
29421
29524
|
try {
|
|
29422
|
-
const content =
|
|
29525
|
+
const content = fs38.readFileSync(filePath, "utf-8");
|
|
29423
29526
|
const deps = [];
|
|
29424
29527
|
const requireBlock = content.match(/require\s*\(([\s\S]*?)\)/);
|
|
29425
29528
|
if (requireBlock) {
|
|
@@ -29439,7 +29542,7 @@ function parseGoMod(filePath) {
|
|
|
29439
29542
|
}
|
|
29440
29543
|
function parseGemfile(filePath) {
|
|
29441
29544
|
try {
|
|
29442
|
-
const content =
|
|
29545
|
+
const content = fs38.readFileSync(filePath, "utf-8");
|
|
29443
29546
|
const deps = [];
|
|
29444
29547
|
for (const line of content.split("\n")) {
|
|
29445
29548
|
const m = line.match(/gem\s+['"]([^'"]+)['"]\s*(?:,\s*['"]([^'"]*)['""])?/);
|
|
@@ -29467,7 +29570,7 @@ function detectCoverage(projectRoot, opts = {}) {
|
|
|
29467
29570
|
const allDeps = [];
|
|
29468
29571
|
for (const { file, parser } of MANIFEST_PARSERS) {
|
|
29469
29572
|
const filePath = path50.join(projectRoot, file);
|
|
29470
|
-
if (!
|
|
29573
|
+
if (!fs38.existsSync(filePath)) continue;
|
|
29471
29574
|
manifestsFound.push(file);
|
|
29472
29575
|
const rawDeps = parser(filePath);
|
|
29473
29576
|
for (const raw of rawDeps) {
|
|
@@ -30239,7 +30342,14 @@ function registerSessionTools(server, ctx) {
|
|
|
30239
30342
|
const text = response.content?.[0]?.text;
|
|
30240
30343
|
if (text) {
|
|
30241
30344
|
try {
|
|
30242
|
-
|
|
30345
|
+
const parsed = JSON.parse(text);
|
|
30346
|
+
if (parsed && typeof parsed === "object") {
|
|
30347
|
+
delete parsed._hints;
|
|
30348
|
+
delete parsed._optimization_hint;
|
|
30349
|
+
delete parsed._budget_warning;
|
|
30350
|
+
delete parsed._budget_level;
|
|
30351
|
+
}
|
|
30352
|
+
results.push({ tool: call.tool, result: parsed });
|
|
30243
30353
|
} catch {
|
|
30244
30354
|
results.push({ tool: call.tool, result: text });
|
|
30245
30355
|
}
|
|
@@ -30257,7 +30367,7 @@ function registerSessionTools(server, ctx) {
|
|
|
30257
30367
|
}
|
|
30258
30368
|
|
|
30259
30369
|
// src/server/server.ts
|
|
30260
|
-
var PKG_VERSION = true ? "1.
|
|
30370
|
+
var PKG_VERSION = true ? "1.8.0" : "0.0.0-dev";
|
|
30261
30371
|
function j2(value) {
|
|
30262
30372
|
return JSON.stringify(value, (_key, val) => val === null || val === void 0 ? void 0 : val);
|
|
30263
30373
|
}
|
|
@@ -39077,7 +39187,7 @@ var XmlLanguagePlugin = class {
|
|
|
39077
39187
|
};
|
|
39078
39188
|
|
|
39079
39189
|
// src/indexer/plugins/integration/orm/prisma/index.ts
|
|
39080
|
-
import
|
|
39190
|
+
import fs39 from "fs";
|
|
39081
39191
|
import path51 from "path";
|
|
39082
39192
|
import { ok as ok28 } from "neverthrow";
|
|
39083
39193
|
var PrismaLanguagePlugin = class {
|
|
@@ -39115,7 +39225,7 @@ var PrismaPlugin = class {
|
|
|
39115
39225
|
path51.join(ctx.rootPath, "prisma", "schema.prisma"),
|
|
39116
39226
|
path51.join(ctx.rootPath, "schema.prisma")
|
|
39117
39227
|
];
|
|
39118
|
-
return candidates.some((p5) =>
|
|
39228
|
+
return candidates.some((p5) => fs39.existsSync(p5));
|
|
39119
39229
|
} catch {
|
|
39120
39230
|
return false;
|
|
39121
39231
|
}
|
|
@@ -39240,7 +39350,7 @@ function parsePrismaSchema(source) {
|
|
|
39240
39350
|
}
|
|
39241
39351
|
|
|
39242
39352
|
// src/indexer/plugins/integration/api/graphql/index.ts
|
|
39243
|
-
import
|
|
39353
|
+
import fs40 from "fs";
|
|
39244
39354
|
import { ok as ok29 } from "neverthrow";
|
|
39245
39355
|
var GraphQLLanguagePlugin = class {
|
|
39246
39356
|
manifest = {
|
|
@@ -39282,7 +39392,7 @@ var GraphQLPlugin = class {
|
|
|
39282
39392
|
];
|
|
39283
39393
|
if (gqlDeps.some((d) => d in deps)) return true;
|
|
39284
39394
|
try {
|
|
39285
|
-
return
|
|
39395
|
+
return fs40.readdirSync(ctx.rootPath).some((f) => f.endsWith(".graphql") || f.endsWith(".gql"));
|
|
39286
39396
|
} catch {
|
|
39287
39397
|
return false;
|
|
39288
39398
|
}
|
|
@@ -42044,7 +42154,7 @@ function createAllLanguagePlugins() {
|
|
|
42044
42154
|
}
|
|
42045
42155
|
|
|
42046
42156
|
// src/indexer/plugins/integration/framework/laravel/index.ts
|
|
42047
|
-
import
|
|
42157
|
+
import fs41 from "fs";
|
|
42048
42158
|
import path52 from "path";
|
|
42049
42159
|
import { ok as ok34 } from "neverthrow";
|
|
42050
42160
|
|
|
@@ -43848,7 +43958,7 @@ var LaravelPlugin = class {
|
|
|
43848
43958
|
} else {
|
|
43849
43959
|
try {
|
|
43850
43960
|
const composerPath = path52.join(ctx.rootPath, "composer.json");
|
|
43851
|
-
const content =
|
|
43961
|
+
const content = fs41.readFileSync(composerPath, "utf-8");
|
|
43852
43962
|
const json = JSON.parse(content);
|
|
43853
43963
|
deps = json.require;
|
|
43854
43964
|
} catch {
|
|
@@ -44520,7 +44630,7 @@ var LaravelPlugin = class {
|
|
|
44520
44630
|
};
|
|
44521
44631
|
|
|
44522
44632
|
// src/indexer/plugins/integration/framework/django/index.ts
|
|
44523
|
-
import
|
|
44633
|
+
import fs42 from "fs";
|
|
44524
44634
|
import path53 from "path";
|
|
44525
44635
|
import { ok as ok35 } from "neverthrow";
|
|
44526
44636
|
|
|
@@ -45028,13 +45138,13 @@ var DjangoPlugin = class {
|
|
|
45028
45138
|
return true;
|
|
45029
45139
|
}
|
|
45030
45140
|
try {
|
|
45031
|
-
|
|
45141
|
+
fs42.accessSync(path53.join(ctx.rootPath, "manage.py"), fs42.constants.F_OK);
|
|
45032
45142
|
return true;
|
|
45033
45143
|
} catch {
|
|
45034
45144
|
}
|
|
45035
45145
|
try {
|
|
45036
45146
|
const pyprojectPath = path53.join(ctx.rootPath, "pyproject.toml");
|
|
45037
|
-
const content =
|
|
45147
|
+
const content = fs42.readFileSync(pyprojectPath, "utf-8");
|
|
45038
45148
|
if (/django/i.test(content) && /dependencies|requires/i.test(content)) {
|
|
45039
45149
|
return true;
|
|
45040
45150
|
}
|
|
@@ -45042,7 +45152,7 @@ var DjangoPlugin = class {
|
|
|
45042
45152
|
}
|
|
45043
45153
|
try {
|
|
45044
45154
|
const reqPath = path53.join(ctx.rootPath, "requirements.txt");
|
|
45045
|
-
const content =
|
|
45155
|
+
const content = fs42.readFileSync(reqPath, "utf-8");
|
|
45046
45156
|
if (/^django(?:==|>=|<=|~=|!=|\[|\s|$)/im.test(content)) {
|
|
45047
45157
|
return true;
|
|
45048
45158
|
}
|
|
@@ -45050,7 +45160,7 @@ var DjangoPlugin = class {
|
|
|
45050
45160
|
}
|
|
45051
45161
|
try {
|
|
45052
45162
|
const setupPath = path53.join(ctx.rootPath, "setup.py");
|
|
45053
|
-
const content =
|
|
45163
|
+
const content = fs42.readFileSync(setupPath, "utf-8");
|
|
45054
45164
|
if (/['"]django['"]/i.test(content)) {
|
|
45055
45165
|
return true;
|
|
45056
45166
|
}
|
|
@@ -45124,7 +45234,7 @@ var DjangoPlugin = class {
|
|
|
45124
45234
|
if (file.language !== "python") continue;
|
|
45125
45235
|
let source;
|
|
45126
45236
|
try {
|
|
45127
|
-
source =
|
|
45237
|
+
source = fs42.readFileSync(
|
|
45128
45238
|
path53.resolve(ctx.rootPath, file.path),
|
|
45129
45239
|
"utf-8"
|
|
45130
45240
|
);
|
|
@@ -45785,7 +45895,7 @@ function normalizePath(path108) {
|
|
|
45785
45895
|
}
|
|
45786
45896
|
|
|
45787
45897
|
// src/indexer/plugins/integration/framework/express/index.ts
|
|
45788
|
-
import
|
|
45898
|
+
import fs43 from "fs";
|
|
45789
45899
|
import path54 from "path";
|
|
45790
45900
|
var ROUTE_RE = /(?:app|router)\s*\.\s*(get|post|put|delete|patch|head|options)\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
45791
45901
|
var MIDDLEWARE_RE = /(?:app|router)\s*\.\s*use\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
@@ -45857,7 +45967,7 @@ var ExpressPlugin = class {
|
|
|
45857
45967
|
}
|
|
45858
45968
|
try {
|
|
45859
45969
|
const pkgPath = path54.join(ctx.rootPath, "package.json");
|
|
45860
|
-
const content =
|
|
45970
|
+
const content = fs43.readFileSync(pkgPath, "utf-8");
|
|
45861
45971
|
const pkg = JSON.parse(content);
|
|
45862
45972
|
const deps = {
|
|
45863
45973
|
...pkg.dependencies,
|
|
@@ -45916,7 +46026,7 @@ var ExpressPlugin = class {
|
|
|
45916
46026
|
};
|
|
45917
46027
|
|
|
45918
46028
|
// src/indexer/plugins/integration/framework/fastapi/index.ts
|
|
45919
|
-
import
|
|
46029
|
+
import fs44 from "fs";
|
|
45920
46030
|
import path55 from "path";
|
|
45921
46031
|
import { ok as ok38, err as err25 } from "neverthrow";
|
|
45922
46032
|
var HTTP_METHODS3 = /* @__PURE__ */ new Set(["get", "post", "put", "delete", "patch", "options", "head"]);
|
|
@@ -45929,14 +46039,14 @@ function hasPythonDep(ctx, pkg) {
|
|
|
45929
46039
|
if (ctx.requirementsTxt?.includes(lowerPkg)) return true;
|
|
45930
46040
|
try {
|
|
45931
46041
|
const pyprojectPath = path55.join(ctx.rootPath, "pyproject.toml");
|
|
45932
|
-
const content =
|
|
46042
|
+
const content = fs44.readFileSync(pyprojectPath, "utf-8");
|
|
45933
46043
|
const re = new RegExp(`["']${escapeRegExp(pkg)}[>=<\\[!~\\s"']`, "i");
|
|
45934
46044
|
if (re.test(content)) return true;
|
|
45935
46045
|
} catch {
|
|
45936
46046
|
}
|
|
45937
46047
|
try {
|
|
45938
46048
|
const reqPath = path55.join(ctx.rootPath, "requirements.txt");
|
|
45939
|
-
const content =
|
|
46049
|
+
const content = fs44.readFileSync(reqPath, "utf-8");
|
|
45940
46050
|
const re = new RegExp(`^${escapeRegExp(pkg)}\\b`, "im");
|
|
45941
46051
|
if (re.test(content)) return true;
|
|
45942
46052
|
} catch {
|
|
@@ -46228,7 +46338,7 @@ var FastAPIPlugin = class {
|
|
|
46228
46338
|
};
|
|
46229
46339
|
|
|
46230
46340
|
// src/indexer/plugins/integration/framework/flask/index.ts
|
|
46231
|
-
import
|
|
46341
|
+
import fs45 from "fs";
|
|
46232
46342
|
import path56 from "path";
|
|
46233
46343
|
import { ok as ok39, err as err26 } from "neverthrow";
|
|
46234
46344
|
var DEFAULT_METHODS = ["GET"];
|
|
@@ -46241,14 +46351,14 @@ function hasPythonDep2(ctx, pkg) {
|
|
|
46241
46351
|
if (ctx.requirementsTxt?.includes(lowerPkg)) return true;
|
|
46242
46352
|
try {
|
|
46243
46353
|
const pyprojectPath = path56.join(ctx.rootPath, "pyproject.toml");
|
|
46244
|
-
const content =
|
|
46354
|
+
const content = fs45.readFileSync(pyprojectPath, "utf-8");
|
|
46245
46355
|
const re = new RegExp(`["']${escapeRegExp(pkg)}[>=<\\[!~\\s"']`, "i");
|
|
46246
46356
|
if (re.test(content)) return true;
|
|
46247
46357
|
} catch {
|
|
46248
46358
|
}
|
|
46249
46359
|
try {
|
|
46250
46360
|
const reqPath = path56.join(ctx.rootPath, "requirements.txt");
|
|
46251
|
-
const content =
|
|
46361
|
+
const content = fs45.readFileSync(reqPath, "utf-8");
|
|
46252
46362
|
const re = new RegExp(`^${escapeRegExp(pkg)}\\b`, "im");
|
|
46253
46363
|
if (re.test(content)) return true;
|
|
46254
46364
|
} catch {
|
|
@@ -46523,7 +46633,7 @@ var FlaskPlugin = class {
|
|
|
46523
46633
|
};
|
|
46524
46634
|
|
|
46525
46635
|
// src/indexer/plugins/integration/framework/hono/index.ts
|
|
46526
|
-
import
|
|
46636
|
+
import fs46 from "fs";
|
|
46527
46637
|
import path57 from "path";
|
|
46528
46638
|
var ROUTE_RE2 = /(?:app|router|hono)\s*\.\s*(get|post|put|delete|patch|head|options|all)\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
46529
46639
|
var ON_RE = /(?:app|router|hono)\s*\.\s*on\s*\(\s*['"`]([^'"`]+)['"`]\s*,\s*['"`]([^'"`]+)['"`]/g;
|
|
@@ -46595,7 +46705,7 @@ var HonoPlugin = class {
|
|
|
46595
46705
|
}
|
|
46596
46706
|
try {
|
|
46597
46707
|
const pkgPath = path57.join(ctx.rootPath, "package.json");
|
|
46598
|
-
const content =
|
|
46708
|
+
const content = fs46.readFileSync(pkgPath, "utf-8");
|
|
46599
46709
|
const pkg = JSON.parse(content);
|
|
46600
46710
|
const deps = {
|
|
46601
46711
|
...pkg.dependencies,
|
|
@@ -46649,7 +46759,7 @@ var HonoPlugin = class {
|
|
|
46649
46759
|
};
|
|
46650
46760
|
|
|
46651
46761
|
// src/indexer/plugins/integration/framework/fastify/index.ts
|
|
46652
|
-
import
|
|
46762
|
+
import fs47 from "fs";
|
|
46653
46763
|
import path58 from "path";
|
|
46654
46764
|
var SHORTHAND_ROUTE_RE = /(?:fastify|app|server|instance)\s*\.\s*(get|post|put|delete|patch|head|options)\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
46655
46765
|
var ROUTE_OBJECT_RE = /\.route\s*\(\s*\{[^}]*?method\s*:\s*['"`]([^'"`]+)['"`][^}]*?url\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
@@ -46710,7 +46820,7 @@ var FastifyPlugin = class {
|
|
|
46710
46820
|
}
|
|
46711
46821
|
try {
|
|
46712
46822
|
const pkgPath = path58.join(ctx.rootPath, "package.json");
|
|
46713
|
-
const content =
|
|
46823
|
+
const content = fs47.readFileSync(pkgPath, "utf-8");
|
|
46714
46824
|
const pkg = JSON.parse(content);
|
|
46715
46825
|
const deps = {
|
|
46716
46826
|
...pkg.dependencies,
|
|
@@ -46763,7 +46873,7 @@ var FastifyPlugin = class {
|
|
|
46763
46873
|
};
|
|
46764
46874
|
|
|
46765
46875
|
// src/indexer/plugins/integration/framework/nuxt/index.ts
|
|
46766
|
-
import
|
|
46876
|
+
import fs48 from "fs";
|
|
46767
46877
|
import path59 from "path";
|
|
46768
46878
|
function filePathToRoute(filePath, srcDir = ".") {
|
|
46769
46879
|
const pagesPrefix = srcDir === "." ? "pages/" : `${srcDir}/pages/`;
|
|
@@ -46832,7 +46942,7 @@ var NuxtPlugin = class {
|
|
|
46832
46942
|
}
|
|
46833
46943
|
try {
|
|
46834
46944
|
const configPath = path59.join(ctx.rootPath, "nuxt.config.ts");
|
|
46835
|
-
const configContent =
|
|
46945
|
+
const configContent = fs48.readFileSync(configPath, "utf-8");
|
|
46836
46946
|
if (/compatibilityVersion\s*:\s*4/.test(configContent)) {
|
|
46837
46947
|
return true;
|
|
46838
46948
|
}
|
|
@@ -46840,7 +46950,7 @@ var NuxtPlugin = class {
|
|
|
46840
46950
|
}
|
|
46841
46951
|
try {
|
|
46842
46952
|
const appPagesDir = path59.join(ctx.rootPath, "app", "pages");
|
|
46843
|
-
|
|
46953
|
+
fs48.accessSync(appPagesDir);
|
|
46844
46954
|
return true;
|
|
46845
46955
|
} catch {
|
|
46846
46956
|
}
|
|
@@ -46864,7 +46974,7 @@ var NuxtPlugin = class {
|
|
|
46864
46974
|
}
|
|
46865
46975
|
try {
|
|
46866
46976
|
const configPath = path59.join(ctx.rootPath, "nuxt.config.ts");
|
|
46867
|
-
|
|
46977
|
+
fs48.accessSync(configPath);
|
|
46868
46978
|
this.nuxt4 = this.isNuxt4(ctx);
|
|
46869
46979
|
this.srcDir = this.nuxt4 ? "app" : ".";
|
|
46870
46980
|
return true;
|
|
@@ -46872,7 +46982,7 @@ var NuxtPlugin = class {
|
|
|
46872
46982
|
}
|
|
46873
46983
|
try {
|
|
46874
46984
|
const pkgPath = path59.join(ctx.rootPath, "package.json");
|
|
46875
|
-
const content =
|
|
46985
|
+
const content = fs48.readFileSync(pkgPath, "utf-8");
|
|
46876
46986
|
const pkg = JSON.parse(content);
|
|
46877
46987
|
const deps = {
|
|
46878
46988
|
...pkg.dependencies,
|
|
@@ -46973,7 +47083,7 @@ var NuxtPlugin = class {
|
|
|
46973
47083
|
for (const file of vueFiles) {
|
|
46974
47084
|
let source;
|
|
46975
47085
|
try {
|
|
46976
|
-
source =
|
|
47086
|
+
source = fs48.readFileSync(path59.resolve(ctx.rootPath, file.path), "utf-8");
|
|
46977
47087
|
} catch {
|
|
46978
47088
|
continue;
|
|
46979
47089
|
}
|
|
@@ -47010,7 +47120,7 @@ var NuxtPlugin = class {
|
|
|
47010
47120
|
};
|
|
47011
47121
|
|
|
47012
47122
|
// src/indexer/plugins/integration/framework/nextjs/index.ts
|
|
47013
|
-
import
|
|
47123
|
+
import fs49 from "fs";
|
|
47014
47124
|
import path60 from "path";
|
|
47015
47125
|
var PAGE_EXTENSIONS = /\.(tsx|ts|jsx|js)$/;
|
|
47016
47126
|
var APP_ROUTER_FILES = ["page", "layout", "loading", "error", "not-found", "route", "template", "default"];
|
|
@@ -47116,7 +47226,7 @@ var NextJSPlugin = class {
|
|
|
47116
47226
|
}
|
|
47117
47227
|
try {
|
|
47118
47228
|
const pkgPath = path60.join(ctx.rootPath, "package.json");
|
|
47119
|
-
const content =
|
|
47229
|
+
const content = fs49.readFileSync(pkgPath, "utf-8");
|
|
47120
47230
|
const pkg = JSON.parse(content);
|
|
47121
47231
|
const deps = {
|
|
47122
47232
|
...pkg.dependencies,
|
|
@@ -47341,7 +47451,7 @@ var NextJSPlugin = class {
|
|
|
47341
47451
|
for (const file of pagesRouterFiles) {
|
|
47342
47452
|
let source;
|
|
47343
47453
|
try {
|
|
47344
|
-
source =
|
|
47454
|
+
source = fs49.readFileSync(path60.resolve(ctx.rootPath, file.path), "utf-8");
|
|
47345
47455
|
} catch {
|
|
47346
47456
|
continue;
|
|
47347
47457
|
}
|
|
@@ -47378,7 +47488,7 @@ var NextJSPlugin = class {
|
|
|
47378
47488
|
};
|
|
47379
47489
|
|
|
47380
47490
|
// src/indexer/plugins/integration/framework/gin/index.ts
|
|
47381
|
-
import
|
|
47491
|
+
import fs50 from "fs";
|
|
47382
47492
|
import path61 from "path";
|
|
47383
47493
|
var ROUTE_RE3 = /\b(\w+)\s*\.\s*(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS|Any)\s*\(\s*"([^"]+)"/g;
|
|
47384
47494
|
var GROUP_RE = /\b(\w+)\s*\.\s*Group\s*\(\s*"([^"]+)"/g;
|
|
@@ -47436,13 +47546,13 @@ var GinPlugin = class {
|
|
|
47436
47546
|
detect(ctx) {
|
|
47437
47547
|
try {
|
|
47438
47548
|
const goModPath = path61.join(ctx.rootPath, "go.mod");
|
|
47439
|
-
const content =
|
|
47549
|
+
const content = fs50.readFileSync(goModPath, "utf-8");
|
|
47440
47550
|
if (content.includes("github.com/gin-gonic/gin")) return true;
|
|
47441
47551
|
} catch {
|
|
47442
47552
|
}
|
|
47443
47553
|
try {
|
|
47444
47554
|
const goSumPath = path61.join(ctx.rootPath, "go.sum");
|
|
47445
|
-
const content =
|
|
47555
|
+
const content = fs50.readFileSync(goSumPath, "utf-8");
|
|
47446
47556
|
return content.includes("github.com/gin-gonic/gin");
|
|
47447
47557
|
} catch {
|
|
47448
47558
|
return false;
|
|
@@ -47503,7 +47613,7 @@ var GinPlugin = class {
|
|
|
47503
47613
|
};
|
|
47504
47614
|
|
|
47505
47615
|
// src/indexer/plugins/integration/framework/echo/index.ts
|
|
47506
|
-
import
|
|
47616
|
+
import fs51 from "fs";
|
|
47507
47617
|
import path62 from "path";
|
|
47508
47618
|
var ROUTE_RE4 = /\b(\w+)\s*\.\s*(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS|CONNECT|TRACE)\s*\(\s*"([^"]+)"/g;
|
|
47509
47619
|
var GROUP_RE2 = /\b(\w+)\s*\.\s*Group\s*\(\s*"([^"]+)"/g;
|
|
@@ -47561,13 +47671,13 @@ var EchoPlugin = class {
|
|
|
47561
47671
|
detect(ctx) {
|
|
47562
47672
|
try {
|
|
47563
47673
|
const goModPath = path62.join(ctx.rootPath, "go.mod");
|
|
47564
|
-
const content =
|
|
47674
|
+
const content = fs51.readFileSync(goModPath, "utf-8");
|
|
47565
47675
|
if (content.includes("github.com/labstack/echo")) return true;
|
|
47566
47676
|
} catch {
|
|
47567
47677
|
}
|
|
47568
47678
|
try {
|
|
47569
47679
|
const goSumPath = path62.join(ctx.rootPath, "go.sum");
|
|
47570
|
-
const content =
|
|
47680
|
+
const content = fs51.readFileSync(goSumPath, "utf-8");
|
|
47571
47681
|
return content.includes("github.com/labstack/echo");
|
|
47572
47682
|
} catch {
|
|
47573
47683
|
return false;
|
|
@@ -47734,7 +47844,7 @@ function extractTypeORMEntity(source, filePath) {
|
|
|
47734
47844
|
}
|
|
47735
47845
|
|
|
47736
47846
|
// src/indexer/plugins/integration/orm/sequelize/index.ts
|
|
47737
|
-
import
|
|
47847
|
+
import fs52 from "fs";
|
|
47738
47848
|
import path63 from "path";
|
|
47739
47849
|
import { ok as ok41 } from "neverthrow";
|
|
47740
47850
|
var SequelizePlugin = class {
|
|
@@ -47753,7 +47863,7 @@ var SequelizePlugin = class {
|
|
|
47753
47863
|
if ("sequelize" in deps || "sequelize-typescript" in deps) return true;
|
|
47754
47864
|
try {
|
|
47755
47865
|
const pkgPath = path63.join(ctx.rootPath, "package.json");
|
|
47756
|
-
const content =
|
|
47866
|
+
const content = fs52.readFileSync(pkgPath, "utf-8");
|
|
47757
47867
|
const json = JSON.parse(content);
|
|
47758
47868
|
const allDeps = { ...json.dependencies, ...json.devDependencies };
|
|
47759
47869
|
return "sequelize" in allDeps || "sequelize-typescript" in allDeps;
|
|
@@ -48073,7 +48183,7 @@ function extractScopes2(source, className) {
|
|
|
48073
48183
|
}
|
|
48074
48184
|
|
|
48075
48185
|
// src/indexer/plugins/integration/orm/mongoose/index.ts
|
|
48076
|
-
import
|
|
48186
|
+
import fs53 from "fs";
|
|
48077
48187
|
import path64 from "path";
|
|
48078
48188
|
import { ok as ok42 } from "neverthrow";
|
|
48079
48189
|
var MongoosePlugin = class {
|
|
@@ -48092,7 +48202,7 @@ var MongoosePlugin = class {
|
|
|
48092
48202
|
if ("mongoose" in deps) return true;
|
|
48093
48203
|
try {
|
|
48094
48204
|
const pkgPath = path64.join(ctx.rootPath, "package.json");
|
|
48095
|
-
const content =
|
|
48205
|
+
const content = fs53.readFileSync(pkgPath, "utf-8");
|
|
48096
48206
|
const json = JSON.parse(content);
|
|
48097
48207
|
const allDeps = { ...json.dependencies, ...json.devDependencies };
|
|
48098
48208
|
return "mongoose" in allDeps;
|
|
@@ -48381,7 +48491,7 @@ function extractRefs(fields, sourceModelName) {
|
|
|
48381
48491
|
}
|
|
48382
48492
|
|
|
48383
48493
|
// src/indexer/plugins/integration/orm/sqlalchemy/index.ts
|
|
48384
|
-
import
|
|
48494
|
+
import fs54 from "fs";
|
|
48385
48495
|
import path65 from "path";
|
|
48386
48496
|
import { ok as ok43, err as err27 } from "neverthrow";
|
|
48387
48497
|
var MODEL_BASES = /* @__PURE__ */ new Set([
|
|
@@ -48400,14 +48510,14 @@ function hasPythonDep3(ctx, pkg) {
|
|
|
48400
48510
|
if (ctx.requirementsTxt?.includes(lowerPkg)) return true;
|
|
48401
48511
|
try {
|
|
48402
48512
|
const pyprojectPath = path65.join(ctx.rootPath, "pyproject.toml");
|
|
48403
|
-
const content =
|
|
48513
|
+
const content = fs54.readFileSync(pyprojectPath, "utf-8");
|
|
48404
48514
|
const re = new RegExp(`["']${escapeRegExp(pkg)}[>=<\\[!~\\s"']`, "i");
|
|
48405
48515
|
if (re.test(content)) return true;
|
|
48406
48516
|
} catch {
|
|
48407
48517
|
}
|
|
48408
48518
|
try {
|
|
48409
48519
|
const reqPath = path65.join(ctx.rootPath, "requirements.txt");
|
|
48410
|
-
const content =
|
|
48520
|
+
const content = fs54.readFileSync(reqPath, "utf-8");
|
|
48411
48521
|
const re = new RegExp(`^${escapeRegExp(pkg)}\\b`, "im");
|
|
48412
48522
|
if (re.test(content)) return true;
|
|
48413
48523
|
} catch {
|
|
@@ -48962,7 +49072,7 @@ function toModelName(varName) {
|
|
|
48962
49072
|
}
|
|
48963
49073
|
|
|
48964
49074
|
// src/indexer/plugins/integration/orm/raw-sql/index.ts
|
|
48965
|
-
import
|
|
49075
|
+
import fs55 from "fs";
|
|
48966
49076
|
import path66 from "path";
|
|
48967
49077
|
var RAW_SQL_PACKAGES = [
|
|
48968
49078
|
"better-sqlite3",
|
|
@@ -49043,7 +49153,7 @@ var RawSqlPlugin = class {
|
|
|
49043
49153
|
}
|
|
49044
49154
|
try {
|
|
49045
49155
|
const pkgPath = path66.join(ctx.rootPath, "package.json");
|
|
49046
|
-
const content =
|
|
49156
|
+
const content = fs55.readFileSync(pkgPath, "utf-8");
|
|
49047
49157
|
const pkg = JSON.parse(content);
|
|
49048
49158
|
const deps = {
|
|
49049
49159
|
...pkg.dependencies,
|
|
@@ -49319,7 +49429,7 @@ var ReactPlugin = class {
|
|
|
49319
49429
|
};
|
|
49320
49430
|
|
|
49321
49431
|
// src/indexer/plugins/integration/view/vue/index.ts
|
|
49322
|
-
import
|
|
49432
|
+
import fs56 from "fs";
|
|
49323
49433
|
import path67 from "path";
|
|
49324
49434
|
|
|
49325
49435
|
// src/indexer/plugins/integration/view/vue/resolver.ts
|
|
@@ -49360,7 +49470,7 @@ var VueFrameworkPlugin = class {
|
|
|
49360
49470
|
}
|
|
49361
49471
|
try {
|
|
49362
49472
|
const pkgPath = path67.join(ctx.rootPath, "package.json");
|
|
49363
|
-
const content =
|
|
49473
|
+
const content = fs56.readFileSync(pkgPath, "utf-8");
|
|
49364
49474
|
const pkg = JSON.parse(content);
|
|
49365
49475
|
const deps = {
|
|
49366
49476
|
...pkg.dependencies,
|
|
@@ -49464,7 +49574,7 @@ var VueFrameworkPlugin = class {
|
|
|
49464
49574
|
};
|
|
49465
49575
|
|
|
49466
49576
|
// src/indexer/plugins/integration/view/react-native/index.ts
|
|
49467
|
-
import
|
|
49577
|
+
import fs57 from "fs";
|
|
49468
49578
|
import path68 from "path";
|
|
49469
49579
|
import { ok as ok46 } from "neverthrow";
|
|
49470
49580
|
function expoFileToRoute(filePath) {
|
|
@@ -49504,7 +49614,7 @@ var ReactNativePlugin = class {
|
|
|
49504
49614
|
}
|
|
49505
49615
|
try {
|
|
49506
49616
|
const pkgPath = path68.join(ctx.rootPath, "package.json");
|
|
49507
|
-
const content =
|
|
49617
|
+
const content = fs57.readFileSync(pkgPath, "utf-8");
|
|
49508
49618
|
const json = JSON.parse(content);
|
|
49509
49619
|
const allDeps = { ...json.dependencies, ...json.devDependencies };
|
|
49510
49620
|
if ("expo-router" in allDeps) this.hasExpoRouter = true;
|
|
@@ -49810,7 +49920,7 @@ function extractNativeModuleNames(source) {
|
|
|
49810
49920
|
}
|
|
49811
49921
|
|
|
49812
49922
|
// src/indexer/plugins/integration/view/blade/index.ts
|
|
49813
|
-
import
|
|
49923
|
+
import fs58 from "fs";
|
|
49814
49924
|
import path69 from "path";
|
|
49815
49925
|
var EXTENDS_RE = /@extends\(\s*['"]([\w.-]+)['"]\s*\)/g;
|
|
49816
49926
|
var INCLUDE_RE = /@include(?:If|When|Unless|First)?\(\s*['"]([\w.-]+)['"]/g;
|
|
@@ -49870,7 +49980,7 @@ var BladePlugin = class {
|
|
|
49870
49980
|
detect(ctx) {
|
|
49871
49981
|
try {
|
|
49872
49982
|
const viewsDir = path69.join(ctx.rootPath, "resources", "views");
|
|
49873
|
-
const stat =
|
|
49983
|
+
const stat = fs58.statSync(viewsDir);
|
|
49874
49984
|
if (!stat.isDirectory()) return false;
|
|
49875
49985
|
return this.hasBlade(viewsDir);
|
|
49876
49986
|
} catch {
|
|
@@ -49952,7 +50062,7 @@ var BladePlugin = class {
|
|
|
49952
50062
|
}
|
|
49953
50063
|
hasBlade(dir) {
|
|
49954
50064
|
try {
|
|
49955
|
-
const entries =
|
|
50065
|
+
const entries = fs58.readdirSync(dir, { withFileTypes: true });
|
|
49956
50066
|
for (const entry of entries) {
|
|
49957
50067
|
if (entry.isFile() && entry.name.endsWith(".blade.php")) return true;
|
|
49958
50068
|
if (entry.isDirectory()) {
|
|
@@ -49966,7 +50076,7 @@ var BladePlugin = class {
|
|
|
49966
50076
|
};
|
|
49967
50077
|
|
|
49968
50078
|
// src/indexer/plugins/integration/view/inertia/index.ts
|
|
49969
|
-
import
|
|
50079
|
+
import fs59 from "fs";
|
|
49970
50080
|
import path70 from "path";
|
|
49971
50081
|
var INERTIA_RENDER_RE = /(?:Inertia::render|inertia)\(\s*['"]([\w/.-]+)['"]\s*(?:,\s*\[([^\]]*)\])?\s*\)/g;
|
|
49972
50082
|
var ARRAY_KEY_RE = /['"](\w+)['"]\s*=>/g;
|
|
@@ -50014,7 +50124,7 @@ var InertiaPlugin = class {
|
|
|
50014
50124
|
}
|
|
50015
50125
|
try {
|
|
50016
50126
|
const composerPath = path70.join(ctx.rootPath, "composer.json");
|
|
50017
|
-
const content =
|
|
50127
|
+
const content = fs59.readFileSync(composerPath, "utf-8");
|
|
50018
50128
|
const json = JSON.parse(content);
|
|
50019
50129
|
const req = json.require;
|
|
50020
50130
|
if (req?.["inertiajs/inertia-laravel"]) return true;
|
|
@@ -50022,7 +50132,7 @@ var InertiaPlugin = class {
|
|
|
50022
50132
|
}
|
|
50023
50133
|
try {
|
|
50024
50134
|
const pkgPath = path70.join(ctx.rootPath, "package.json");
|
|
50025
|
-
const content =
|
|
50135
|
+
const content = fs59.readFileSync(pkgPath, "utf-8");
|
|
50026
50136
|
const pkg = JSON.parse(content);
|
|
50027
50137
|
const deps = {
|
|
50028
50138
|
...pkg.dependencies,
|
|
@@ -50063,7 +50173,7 @@ var InertiaPlugin = class {
|
|
|
50063
50173
|
if (file.language !== "php") continue;
|
|
50064
50174
|
let source;
|
|
50065
50175
|
try {
|
|
50066
|
-
source =
|
|
50176
|
+
source = fs59.readFileSync(path70.resolve(ctx.rootPath, file.path), "utf-8");
|
|
50067
50177
|
} catch {
|
|
50068
50178
|
continue;
|
|
50069
50179
|
}
|
|
@@ -50114,7 +50224,7 @@ var InertiaPlugin = class {
|
|
|
50114
50224
|
};
|
|
50115
50225
|
|
|
50116
50226
|
// src/indexer/plugins/integration/view/shadcn/index.ts
|
|
50117
|
-
import
|
|
50227
|
+
import fs60 from "fs";
|
|
50118
50228
|
import path71 from "path";
|
|
50119
50229
|
import { ok as ok47 } from "neverthrow";
|
|
50120
50230
|
var CVA_RE = /(?:export\s+(?:default\s+)?)?(?:const|let)\s+(\w+)\s*=\s*cva\s*\(/g;
|
|
@@ -50441,7 +50551,7 @@ function scanInstalledComponents(rootPath, config) {
|
|
|
50441
50551
|
for (const relDir of possibleDirs) {
|
|
50442
50552
|
const absDir = path71.resolve(rootPath, relDir);
|
|
50443
50553
|
try {
|
|
50444
|
-
const entries =
|
|
50554
|
+
const entries = fs60.readdirSync(absDir, { withFileTypes: true });
|
|
50445
50555
|
for (const entry of entries) {
|
|
50446
50556
|
if (entry.isFile() && /\.(tsx|vue|ts|jsx)$/.test(entry.name)) {
|
|
50447
50557
|
const baseName = entry.name.replace(/\.(tsx|vue|ts|jsx)$/, "");
|
|
@@ -50452,7 +50562,7 @@ function scanInstalledComponents(rootPath, config) {
|
|
|
50452
50562
|
});
|
|
50453
50563
|
} else if (entry.isDirectory()) {
|
|
50454
50564
|
try {
|
|
50455
|
-
const subEntries =
|
|
50565
|
+
const subEntries = fs60.readdirSync(path71.join(absDir, entry.name));
|
|
50456
50566
|
const indexFile = subEntries.find((f) => /^index\.(tsx|vue|ts|jsx)$/.test(f));
|
|
50457
50567
|
if (indexFile) {
|
|
50458
50568
|
components.push({
|
|
@@ -50501,7 +50611,7 @@ var ShadcnPlugin = class {
|
|
|
50501
50611
|
this.rootPath = ctx.rootPath;
|
|
50502
50612
|
try {
|
|
50503
50613
|
const configPath = path71.join(ctx.rootPath, "components.json");
|
|
50504
|
-
const raw =
|
|
50614
|
+
const raw = fs60.readFileSync(configPath, "utf-8");
|
|
50505
50615
|
this.config = JSON.parse(raw);
|
|
50506
50616
|
this.scanComponents(ctx);
|
|
50507
50617
|
return true;
|
|
@@ -51377,7 +51487,7 @@ var HeadlessUiPlugin = class {
|
|
|
51377
51487
|
};
|
|
51378
51488
|
|
|
51379
51489
|
// src/indexer/plugins/integration/view/nuxt-ui/index.ts
|
|
51380
|
-
import
|
|
51490
|
+
import fs61 from "fs";
|
|
51381
51491
|
import path72 from "path";
|
|
51382
51492
|
import { ok as ok51 } from "neverthrow";
|
|
51383
51493
|
var NUXT_UI_V3_COMPONENTS = /* @__PURE__ */ new Set([
|
|
@@ -51635,7 +51745,7 @@ var NuxtUiPlugin = class {
|
|
|
51635
51745
|
if (!hasNuxtUi) {
|
|
51636
51746
|
try {
|
|
51637
51747
|
const configPath = path72.join(ctx.rootPath, "nuxt.config.ts");
|
|
51638
|
-
const configContent =
|
|
51748
|
+
const configContent = fs61.readFileSync(configPath, "utf-8");
|
|
51639
51749
|
if (/@nuxt\/ui/.test(configContent)) return true;
|
|
51640
51750
|
} catch {
|
|
51641
51751
|
}
|
|
@@ -51834,7 +51944,7 @@ function extractBraceBody4(source, pos) {
|
|
|
51834
51944
|
}
|
|
51835
51945
|
|
|
51836
51946
|
// src/indexer/plugins/integration/view/angular/index.ts
|
|
51837
|
-
import
|
|
51947
|
+
import fs62 from "fs";
|
|
51838
51948
|
import path73 from "path";
|
|
51839
51949
|
var COMPONENT_RE2 = /@Component\s*\(\s*\{[^}]*selector\s*:\s*['"]([^'"]+)['"]/gs;
|
|
51840
51950
|
var INJECTABLE_RE2 = /@Injectable\s*\(/g;
|
|
@@ -51884,7 +51994,7 @@ var AngularPlugin = class {
|
|
|
51884
51994
|
}
|
|
51885
51995
|
try {
|
|
51886
51996
|
const pkgPath = path73.join(ctx.rootPath, "package.json");
|
|
51887
|
-
const content =
|
|
51997
|
+
const content = fs62.readFileSync(pkgPath, "utf-8");
|
|
51888
51998
|
const pkg = JSON.parse(content);
|
|
51889
51999
|
const deps = {
|
|
51890
52000
|
...pkg.dependencies,
|
|
@@ -52203,7 +52313,7 @@ function isHtmlTag(tag) {
|
|
|
52203
52313
|
}
|
|
52204
52314
|
|
|
52205
52315
|
// src/indexer/plugins/integration/view/svelte/index.ts
|
|
52206
|
-
import
|
|
52316
|
+
import fs63 from "fs";
|
|
52207
52317
|
import path74 from "path";
|
|
52208
52318
|
var EXPORT_LET_RE = /export\s+let\s+(\w+)/g;
|
|
52209
52319
|
var SLOT_RE = /<slot(?:\s+name\s*=\s*['"]([^'"]+)['"])?\s*\/?>/g;
|
|
@@ -52266,7 +52376,7 @@ var SveltePlugin = class {
|
|
|
52266
52376
|
}
|
|
52267
52377
|
try {
|
|
52268
52378
|
const pkgPath = path74.join(ctx.rootPath, "package.json");
|
|
52269
|
-
const content =
|
|
52379
|
+
const content = fs63.readFileSync(pkgPath, "utf-8");
|
|
52270
52380
|
const pkg = JSON.parse(content);
|
|
52271
52381
|
const deps = {
|
|
52272
52382
|
...pkg.dependencies,
|
|
@@ -52513,7 +52623,7 @@ var SveltePlugin = class {
|
|
|
52513
52623
|
};
|
|
52514
52624
|
|
|
52515
52625
|
// src/indexer/plugins/integration/api/trpc/index.ts
|
|
52516
|
-
import
|
|
52626
|
+
import fs64 from "fs";
|
|
52517
52627
|
import path75 from "path";
|
|
52518
52628
|
var PROCEDURE_RE = /(\w+)\s*:\s*\w*[Pp]rocedure[\s\S]{0,500}?\.(query|mutation|subscription)\s*\(/g;
|
|
52519
52629
|
var ROUTER_RE = /(?:t\.router|router)\s*\(\s*\{/g;
|
|
@@ -52547,7 +52657,7 @@ var TrpcPlugin = class {
|
|
|
52547
52657
|
}
|
|
52548
52658
|
try {
|
|
52549
52659
|
const pkgPath = path75.join(ctx.rootPath, "package.json");
|
|
52550
|
-
const content =
|
|
52660
|
+
const content = fs64.readFileSync(pkgPath, "utf-8");
|
|
52551
52661
|
const pkg = JSON.parse(content);
|
|
52552
52662
|
const deps = {
|
|
52553
52663
|
...pkg.dependencies,
|
|
@@ -52593,31 +52703,31 @@ var TrpcPlugin = class {
|
|
|
52593
52703
|
};
|
|
52594
52704
|
|
|
52595
52705
|
// src/indexer/plugins/integration/api/drf/index.ts
|
|
52596
|
-
import
|
|
52706
|
+
import fs65 from "fs";
|
|
52597
52707
|
import path76 from "path";
|
|
52598
52708
|
import { ok as ok52, err as err29 } from "neverthrow";
|
|
52599
52709
|
function hasPythonDep4(rootPath, depName) {
|
|
52600
52710
|
for (const reqFile of ["requirements.txt", "requirements/base.txt", "requirements/prod.txt"]) {
|
|
52601
52711
|
try {
|
|
52602
|
-
const content =
|
|
52712
|
+
const content = fs65.readFileSync(path76.join(rootPath, reqFile), "utf-8");
|
|
52603
52713
|
if (new RegExp(`^${escapeRegExp(depName)}\\b`, "m").test(content)) return true;
|
|
52604
52714
|
} catch {
|
|
52605
52715
|
}
|
|
52606
52716
|
}
|
|
52607
52717
|
try {
|
|
52608
|
-
const content =
|
|
52718
|
+
const content = fs65.readFileSync(path76.join(rootPath, "pyproject.toml"), "utf-8");
|
|
52609
52719
|
if (content.includes(depName)) return true;
|
|
52610
52720
|
} catch {
|
|
52611
52721
|
}
|
|
52612
52722
|
for (const f of ["setup.py", "setup.cfg"]) {
|
|
52613
52723
|
try {
|
|
52614
|
-
const content =
|
|
52724
|
+
const content = fs65.readFileSync(path76.join(rootPath, f), "utf-8");
|
|
52615
52725
|
if (content.includes(depName)) return true;
|
|
52616
52726
|
} catch {
|
|
52617
52727
|
}
|
|
52618
52728
|
}
|
|
52619
52729
|
try {
|
|
52620
|
-
const content =
|
|
52730
|
+
const content = fs65.readFileSync(path76.join(rootPath, "Pipfile"), "utf-8");
|
|
52621
52731
|
if (content.includes(depName)) return true;
|
|
52622
52732
|
} catch {
|
|
52623
52733
|
}
|
|
@@ -52931,7 +53041,7 @@ var DRFPlugin = class {
|
|
|
52931
53041
|
};
|
|
52932
53042
|
|
|
52933
53043
|
// src/indexer/plugins/integration/api/mcp-sdk/index.ts
|
|
52934
|
-
import
|
|
53044
|
+
import fs66 from "fs";
|
|
52935
53045
|
import path77 from "path";
|
|
52936
53046
|
var MCP_SDK_PKG = "@modelcontextprotocol/sdk";
|
|
52937
53047
|
var TOOL_RE = /\.tool\(\s*['"]([^'"]+)['"]\s*(?:,\s*['"]([^'"]*)['"]\s*)?/g;
|
|
@@ -52974,7 +53084,7 @@ var McpSdkPlugin = class {
|
|
|
52974
53084
|
}
|
|
52975
53085
|
try {
|
|
52976
53086
|
const pkgPath = path77.join(ctx.rootPath, "package.json");
|
|
52977
|
-
const content =
|
|
53087
|
+
const content = fs66.readFileSync(pkgPath, "utf-8");
|
|
52978
53088
|
const pkg = JSON.parse(content);
|
|
52979
53089
|
const deps = {
|
|
52980
53090
|
...pkg.dependencies,
|
|
@@ -53025,7 +53135,7 @@ var McpSdkPlugin = class {
|
|
|
53025
53135
|
};
|
|
53026
53136
|
|
|
53027
53137
|
// src/indexer/plugins/integration/validation/zod/index.ts
|
|
53028
|
-
import
|
|
53138
|
+
import fs67 from "fs";
|
|
53029
53139
|
import path78 from "path";
|
|
53030
53140
|
var ZOD_OBJECT_RE = /(?:export\s+(?:default\s+)?)?(?:const|let|var)\s+(\w+)\s*=\s*z\.object\s*\(\s*\{([^]*?)\}\s*\)/g;
|
|
53031
53141
|
var ZOD_FIELD_RE = /(\w+)\s*:\s*z\.(\w+)\s*\(([^)]*)\)([.\w()]*)/g;
|
|
@@ -53082,7 +53192,7 @@ var ZodPlugin = class {
|
|
|
53082
53192
|
}
|
|
53083
53193
|
try {
|
|
53084
53194
|
const pkgPath = path78.join(ctx.rootPath, "package.json");
|
|
53085
|
-
const content =
|
|
53195
|
+
const content = fs67.readFileSync(pkgPath, "utf-8");
|
|
53086
53196
|
const pkg = JSON.parse(content);
|
|
53087
53197
|
const deps = {
|
|
53088
53198
|
...pkg.dependencies,
|
|
@@ -53125,31 +53235,31 @@ var ZodPlugin = class {
|
|
|
53125
53235
|
};
|
|
53126
53236
|
|
|
53127
53237
|
// src/indexer/plugins/integration/validation/pydantic/index.ts
|
|
53128
|
-
import
|
|
53238
|
+
import fs68 from "fs";
|
|
53129
53239
|
import path79 from "path";
|
|
53130
53240
|
import { ok as ok53, err as err30 } from "neverthrow";
|
|
53131
53241
|
function hasPythonDep5(rootPath, depName) {
|
|
53132
53242
|
for (const reqFile of ["requirements.txt", "requirements/base.txt", "requirements/prod.txt"]) {
|
|
53133
53243
|
try {
|
|
53134
|
-
const content =
|
|
53244
|
+
const content = fs68.readFileSync(path79.join(rootPath, reqFile), "utf-8");
|
|
53135
53245
|
if (new RegExp(`^${escapeRegExp(depName)}\\b`, "m").test(content)) return true;
|
|
53136
53246
|
} catch {
|
|
53137
53247
|
}
|
|
53138
53248
|
}
|
|
53139
53249
|
try {
|
|
53140
|
-
const content =
|
|
53250
|
+
const content = fs68.readFileSync(path79.join(rootPath, "pyproject.toml"), "utf-8");
|
|
53141
53251
|
if (content.includes(depName)) return true;
|
|
53142
53252
|
} catch {
|
|
53143
53253
|
}
|
|
53144
53254
|
for (const f of ["setup.py", "setup.cfg"]) {
|
|
53145
53255
|
try {
|
|
53146
|
-
const content =
|
|
53256
|
+
const content = fs68.readFileSync(path79.join(rootPath, f), "utf-8");
|
|
53147
53257
|
if (content.includes(depName)) return true;
|
|
53148
53258
|
} catch {
|
|
53149
53259
|
}
|
|
53150
53260
|
}
|
|
53151
53261
|
try {
|
|
53152
|
-
const content =
|
|
53262
|
+
const content = fs68.readFileSync(path79.join(rootPath, "Pipfile"), "utf-8");
|
|
53153
53263
|
if (content.includes(depName)) return true;
|
|
53154
53264
|
} catch {
|
|
53155
53265
|
}
|
|
@@ -53692,7 +53802,7 @@ function extractBraceBody5(source, pos) {
|
|
|
53692
53802
|
}
|
|
53693
53803
|
|
|
53694
53804
|
// src/indexer/plugins/integration/realtime/socketio/index.ts
|
|
53695
|
-
import
|
|
53805
|
+
import fs69 from "fs";
|
|
53696
53806
|
import path80 from "path";
|
|
53697
53807
|
var LISTENER_RE = /(?:socket|io|server|namespace)\s*\.\s*on\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
53698
53808
|
var EMITTER_RE = /(?:socket|io|server|namespace)(?:\.broadcast)?\s*\.\s*emit\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
@@ -53737,7 +53847,7 @@ var SocketIoPlugin = class {
|
|
|
53737
53847
|
}
|
|
53738
53848
|
try {
|
|
53739
53849
|
const pkgPath = path80.join(ctx.rootPath, "package.json");
|
|
53740
|
-
const content =
|
|
53850
|
+
const content = fs69.readFileSync(pkgPath, "utf-8");
|
|
53741
53851
|
const pkg = JSON.parse(content);
|
|
53742
53852
|
const deps = {
|
|
53743
53853
|
...pkg.dependencies,
|
|
@@ -53791,7 +53901,7 @@ var SocketIoPlugin = class {
|
|
|
53791
53901
|
};
|
|
53792
53902
|
|
|
53793
53903
|
// src/indexer/plugins/integration/testing/index.ts
|
|
53794
|
-
import
|
|
53904
|
+
import fs70 from "fs";
|
|
53795
53905
|
|
|
53796
53906
|
// src/utils/regex.ts
|
|
53797
53907
|
var globalReCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -53914,7 +54024,7 @@ var TestingPlugin = class {
|
|
|
53914
54024
|
}
|
|
53915
54025
|
try {
|
|
53916
54026
|
const pkgPath = path81.join(ctx.rootPath, "package.json");
|
|
53917
|
-
const content =
|
|
54027
|
+
const content = fs70.readFileSync(pkgPath, "utf-8");
|
|
53918
54028
|
const pkg = JSON.parse(content);
|
|
53919
54029
|
const deps = {
|
|
53920
54030
|
...pkg.dependencies,
|
|
@@ -53985,31 +54095,31 @@ var TestingPlugin = class {
|
|
|
53985
54095
|
};
|
|
53986
54096
|
|
|
53987
54097
|
// src/indexer/plugins/integration/tooling/celery/index.ts
|
|
53988
|
-
import
|
|
54098
|
+
import fs71 from "fs";
|
|
53989
54099
|
import path82 from "path";
|
|
53990
54100
|
import { ok as ok55, err as err31 } from "neverthrow";
|
|
53991
54101
|
function hasPythonDep6(rootPath, depName) {
|
|
53992
54102
|
for (const reqFile of ["requirements.txt", "requirements/base.txt", "requirements/prod.txt"]) {
|
|
53993
54103
|
try {
|
|
53994
|
-
const content =
|
|
54104
|
+
const content = fs71.readFileSync(path82.join(rootPath, reqFile), "utf-8");
|
|
53995
54105
|
if (new RegExp(`^${escapeRegExp(depName)}\\b`, "m").test(content)) return true;
|
|
53996
54106
|
} catch {
|
|
53997
54107
|
}
|
|
53998
54108
|
}
|
|
53999
54109
|
try {
|
|
54000
|
-
const content =
|
|
54110
|
+
const content = fs71.readFileSync(path82.join(rootPath, "pyproject.toml"), "utf-8");
|
|
54001
54111
|
if (content.includes(depName)) return true;
|
|
54002
54112
|
} catch {
|
|
54003
54113
|
}
|
|
54004
54114
|
for (const f of ["setup.py", "setup.cfg"]) {
|
|
54005
54115
|
try {
|
|
54006
|
-
const content =
|
|
54116
|
+
const content = fs71.readFileSync(path82.join(rootPath, f), "utf-8");
|
|
54007
54117
|
if (content.includes(depName)) return true;
|
|
54008
54118
|
} catch {
|
|
54009
54119
|
}
|
|
54010
54120
|
}
|
|
54011
54121
|
try {
|
|
54012
|
-
const content =
|
|
54122
|
+
const content = fs71.readFileSync(path82.join(rootPath, "Pipfile"), "utf-8");
|
|
54013
54123
|
if (content.includes(depName)) return true;
|
|
54014
54124
|
} catch {
|
|
54015
54125
|
}
|
|
@@ -54257,7 +54367,7 @@ var CeleryPlugin = class {
|
|
|
54257
54367
|
};
|
|
54258
54368
|
|
|
54259
54369
|
// src/indexer/plugins/integration/tooling/n8n/index.ts
|
|
54260
|
-
import
|
|
54370
|
+
import fs72 from "fs";
|
|
54261
54371
|
import path83 from "path";
|
|
54262
54372
|
var CODE_TYPES = /* @__PURE__ */ new Set([
|
|
54263
54373
|
"n8n-nodes-base.code",
|
|
@@ -54886,7 +54996,7 @@ function findDisconnectedNodes(workflow, connections) {
|
|
|
54886
54996
|
function collectNodeFiles(dir) {
|
|
54887
54997
|
const results = [];
|
|
54888
54998
|
try {
|
|
54889
|
-
const entries =
|
|
54999
|
+
const entries = fs72.readdirSync(dir, { withFileTypes: true });
|
|
54890
55000
|
for (const entry of entries) {
|
|
54891
55001
|
const fullPath = path83.join(dir, entry.name);
|
|
54892
55002
|
if (entry.isDirectory()) {
|
|
@@ -55148,14 +55258,14 @@ var N8nPlugin = class {
|
|
|
55148
55258
|
}
|
|
55149
55259
|
}
|
|
55150
55260
|
try {
|
|
55151
|
-
if (
|
|
55261
|
+
if (fs72.existsSync(path83.join(ctx.rootPath, ".n8n"))) return true;
|
|
55152
55262
|
} catch {
|
|
55153
55263
|
}
|
|
55154
55264
|
const nodeDirs = ["nodes", "src/nodes"];
|
|
55155
55265
|
for (const dir of nodeDirs) {
|
|
55156
55266
|
try {
|
|
55157
55267
|
const fullDir = path83.join(ctx.rootPath, dir);
|
|
55158
|
-
if (
|
|
55268
|
+
if (fs72.existsSync(fullDir) && fs72.statSync(fullDir).isDirectory()) {
|
|
55159
55269
|
const files = collectNodeFiles(fullDir);
|
|
55160
55270
|
if (files.length > 0) return true;
|
|
55161
55271
|
}
|
|
@@ -55166,11 +55276,11 @@ var N8nPlugin = class {
|
|
|
55166
55276
|
for (const dir of searchDirs) {
|
|
55167
55277
|
try {
|
|
55168
55278
|
const fullDir = path83.join(ctx.rootPath, dir);
|
|
55169
|
-
if (!
|
|
55170
|
-
const files =
|
|
55279
|
+
if (!fs72.existsSync(fullDir) || !fs72.statSync(fullDir).isDirectory()) continue;
|
|
55280
|
+
const files = fs72.readdirSync(fullDir).filter((f) => f.endsWith(".json"));
|
|
55171
55281
|
for (const file of files.slice(0, 5)) {
|
|
55172
55282
|
try {
|
|
55173
|
-
const content =
|
|
55283
|
+
const content = fs72.readFileSync(path83.join(fullDir, file));
|
|
55174
55284
|
if (parseN8nWorkflow(content)) return true;
|
|
55175
55285
|
} catch {
|
|
55176
55286
|
}
|
|
@@ -55566,7 +55676,7 @@ function findNodeByteOffset(source, nodeName) {
|
|
|
55566
55676
|
}
|
|
55567
55677
|
|
|
55568
55678
|
// src/indexer/plugins/integration/tooling/data-fetching/index.ts
|
|
55569
|
-
import
|
|
55679
|
+
import fs73 from "fs";
|
|
55570
55680
|
import path84 from "path";
|
|
55571
55681
|
var USE_QUERY_OBJECT_RE = /\b(useQuery|useInfiniteQuery)\s*\(\s*\{[^}]*?queryFn\s*:\s*[^}]*?fetch\s*\(\s*[`'"](\/[^'"`$]*?)['"`]/g;
|
|
55572
55682
|
var USE_QUERY_ARRAY_RE = /\b(useQuery|useInfiniteQuery)\s*\(\s*\[[^\]]*\]\s*,\s*(?:\([^)]*\)\s*=>|function\s*\([^)]*\)\s*\{)[^)]*?fetch\s*\(\s*[`'"](\/[^'"`$]*?)['"`]/g;
|
|
@@ -55640,7 +55750,7 @@ var DataFetchingPlugin = class {
|
|
|
55640
55750
|
}
|
|
55641
55751
|
try {
|
|
55642
55752
|
const pkgPath = path84.join(ctx.rootPath, "package.json");
|
|
55643
|
-
const content =
|
|
55753
|
+
const content = fs73.readFileSync(pkgPath, "utf-8");
|
|
55644
55754
|
const pkg = JSON.parse(content);
|
|
55645
55755
|
const deps = {
|
|
55646
55756
|
...pkg.dependencies,
|
|
@@ -55684,7 +55794,7 @@ var DataFetchingPlugin = class {
|
|
|
55684
55794
|
};
|
|
55685
55795
|
|
|
55686
55796
|
// src/indexer/plugins/integration/tooling/commander/index.ts
|
|
55687
|
-
import
|
|
55797
|
+
import fs74 from "fs";
|
|
55688
55798
|
import path85 from "path";
|
|
55689
55799
|
var CLI_PACKAGES = ["commander", "yargs", "@oclif/core", "clipanion", "cac", "citty"];
|
|
55690
55800
|
var COMMAND_RE = /\.command\(\s*['"]([^'"]+)['"]\s*(?:,\s*['"]([^'"]*)['"]\s*)?/g;
|
|
@@ -55742,7 +55852,7 @@ var CommanderPlugin = class {
|
|
|
55742
55852
|
}
|
|
55743
55853
|
try {
|
|
55744
55854
|
const pkgPath = path85.join(ctx.rootPath, "package.json");
|
|
55745
|
-
const content =
|
|
55855
|
+
const content = fs74.readFileSync(pkgPath, "utf-8");
|
|
55746
55856
|
const pkg = JSON.parse(content);
|
|
55747
55857
|
const deps = {
|
|
55748
55858
|
...pkg.dependencies,
|
|
@@ -55795,7 +55905,7 @@ var CommanderPlugin = class {
|
|
|
55795
55905
|
};
|
|
55796
55906
|
|
|
55797
55907
|
// src/indexer/plugins/integration/tooling/tree-sitter/index.ts
|
|
55798
|
-
import
|
|
55908
|
+
import fs75 from "fs";
|
|
55799
55909
|
import path86 from "path";
|
|
55800
55910
|
var TREE_SITTER_PACKAGES = [
|
|
55801
55911
|
"tree-sitter",
|
|
@@ -55840,7 +55950,7 @@ var TreeSitterPlugin = class {
|
|
|
55840
55950
|
}
|
|
55841
55951
|
try {
|
|
55842
55952
|
const pkgPath = path86.join(ctx.rootPath, "package.json");
|
|
55843
|
-
const content =
|
|
55953
|
+
const content = fs75.readFileSync(pkgPath, "utf-8");
|
|
55844
55954
|
const pkg = JSON.parse(content);
|
|
55845
55955
|
const deps = {
|
|
55846
55956
|
...pkg.dependencies,
|
|
@@ -55886,7 +55996,7 @@ var TreeSitterPlugin = class {
|
|
|
55886
55996
|
};
|
|
55887
55997
|
|
|
55888
55998
|
// src/indexer/plugins/integration/tooling/build-tools/index.ts
|
|
55889
|
-
import
|
|
55999
|
+
import fs76 from "fs";
|
|
55890
56000
|
import path87 from "path";
|
|
55891
56001
|
var BUILD_PACKAGES = [
|
|
55892
56002
|
"tsup",
|
|
@@ -55971,7 +56081,7 @@ var BuildToolsPlugin = class {
|
|
|
55971
56081
|
}
|
|
55972
56082
|
try {
|
|
55973
56083
|
const pkgPath = path87.join(ctx.rootPath, "package.json");
|
|
55974
|
-
const content =
|
|
56084
|
+
const content = fs76.readFileSync(pkgPath, "utf-8");
|
|
55975
56085
|
const pkg = JSON.parse(content);
|
|
55976
56086
|
const deps = {
|
|
55977
56087
|
...pkg.dependencies,
|
|
@@ -56091,7 +56201,7 @@ var GithubActionsPlugin = class {
|
|
|
56091
56201
|
};
|
|
56092
56202
|
|
|
56093
56203
|
// src/indexer/plugins/integration/tooling/pino/index.ts
|
|
56094
|
-
import
|
|
56204
|
+
import fs77 from "fs";
|
|
56095
56205
|
import path88 from "path";
|
|
56096
56206
|
var LOGGING_PACKAGES = ["pino", "winston", "bunyan", "log4js", "pino-pretty", "pino-http"];
|
|
56097
56207
|
var LOGGER_CREATE_RE = /(?:pino|createLogger|getLogger|winston\.createLogger|bunyan\.createLogger)\s*\(/g;
|
|
@@ -56118,7 +56228,7 @@ var PinoPlugin = class {
|
|
|
56118
56228
|
}
|
|
56119
56229
|
try {
|
|
56120
56230
|
const pkgPath = path88.join(ctx.rootPath, "package.json");
|
|
56121
|
-
const content =
|
|
56231
|
+
const content = fs77.readFileSync(pkgPath, "utf-8");
|
|
56122
56232
|
const pkg = JSON.parse(content);
|
|
56123
56233
|
const deps = {
|
|
56124
56234
|
...pkg.dependencies,
|
|
@@ -56167,7 +56277,7 @@ var PinoPlugin = class {
|
|
|
56167
56277
|
};
|
|
56168
56278
|
|
|
56169
56279
|
// src/indexer/plugins/integration/tooling/cosmiconfig/index.ts
|
|
56170
|
-
import
|
|
56280
|
+
import fs78 from "fs";
|
|
56171
56281
|
import path89 from "path";
|
|
56172
56282
|
var CONFIG_PACKAGES = ["cosmiconfig", "lilconfig", "rc", "dotenv", "envalid", "env-var"];
|
|
56173
56283
|
var EXPLORER_RE = /(?:cosmiconfig|lilconfig|cosmiconfigSync|lilconfigSync)\(\s*['"]([^'"]+)['"]/g;
|
|
@@ -56193,7 +56303,7 @@ var CosmiconfigPlugin = class {
|
|
|
56193
56303
|
}
|
|
56194
56304
|
try {
|
|
56195
56305
|
const pkgPath = path89.join(ctx.rootPath, "package.json");
|
|
56196
|
-
const content =
|
|
56306
|
+
const content = fs78.readFileSync(pkgPath, "utf-8");
|
|
56197
56307
|
const pkg = JSON.parse(content);
|
|
56198
56308
|
const deps = {
|
|
56199
56309
|
...pkg.dependencies,
|
|
@@ -56238,7 +56348,7 @@ var CosmiconfigPlugin = class {
|
|
|
56238
56348
|
};
|
|
56239
56349
|
|
|
56240
56350
|
// src/indexer/plugins/integration/tooling/neverthrow/index.ts
|
|
56241
|
-
import
|
|
56351
|
+
import fs79 from "fs";
|
|
56242
56352
|
import path90 from "path";
|
|
56243
56353
|
var RESULT_PACKAGES = ["neverthrow", "ts-results", "oxide.ts", "true-myth", "@badrap/result"];
|
|
56244
56354
|
var RESULT_TYPE_RE = /(?:Result|ResultAsync|Ok|Err)\s*<[^>]+>/g;
|
|
@@ -56265,7 +56375,7 @@ var NeverthrowPlugin = class {
|
|
|
56265
56375
|
}
|
|
56266
56376
|
try {
|
|
56267
56377
|
const pkgPath = path90.join(ctx.rootPath, "package.json");
|
|
56268
|
-
const content =
|
|
56378
|
+
const content = fs79.readFileSync(pkgPath, "utf-8");
|
|
56269
56379
|
const pkg = JSON.parse(content);
|
|
56270
56380
|
const deps = {
|
|
56271
56381
|
...pkg.dependencies,
|
|
@@ -56312,7 +56422,7 @@ var NeverthrowPlugin = class {
|
|
|
56312
56422
|
};
|
|
56313
56423
|
|
|
56314
56424
|
// src/indexer/plugins/integration/tooling/clack/index.ts
|
|
56315
|
-
import
|
|
56425
|
+
import fs80 from "fs";
|
|
56316
56426
|
import path91 from "path";
|
|
56317
56427
|
var PROMPT_PACKAGES = [
|
|
56318
56428
|
"@clack/prompts",
|
|
@@ -56346,7 +56456,7 @@ var ClackPlugin = class {
|
|
|
56346
56456
|
}
|
|
56347
56457
|
try {
|
|
56348
56458
|
const pkgPath = path91.join(ctx.rootPath, "package.json");
|
|
56349
|
-
const content =
|
|
56459
|
+
const content = fs80.readFileSync(pkgPath, "utf-8");
|
|
56350
56460
|
const pkg = JSON.parse(content);
|
|
56351
56461
|
const deps = {
|
|
56352
56462
|
...pkg.dependencies,
|
|
@@ -56650,12 +56760,12 @@ import http from "http";
|
|
|
56650
56760
|
|
|
56651
56761
|
// src/cli/init.ts
|
|
56652
56762
|
import { Command } from "commander";
|
|
56653
|
-
import
|
|
56763
|
+
import fs90 from "fs";
|
|
56654
56764
|
import path102 from "path";
|
|
56655
56765
|
import * as p from "@clack/prompts";
|
|
56656
56766
|
|
|
56657
56767
|
// src/init/mcp-client.ts
|
|
56658
|
-
import
|
|
56768
|
+
import fs81 from "fs";
|
|
56659
56769
|
import path93 from "path";
|
|
56660
56770
|
import os5 from "os";
|
|
56661
56771
|
var HOME = os5.homedir();
|
|
@@ -56667,9 +56777,9 @@ function configureMcpClients(clientNames, projectRoot, opts) {
|
|
|
56667
56777
|
results.push({ target: name, action: "skipped", detail: "Unknown client" });
|
|
56668
56778
|
continue;
|
|
56669
56779
|
}
|
|
56670
|
-
if (
|
|
56780
|
+
if (fs81.existsSync(configPath)) {
|
|
56671
56781
|
try {
|
|
56672
|
-
const content = JSON.parse(
|
|
56782
|
+
const content = JSON.parse(fs81.readFileSync(configPath, "utf-8"));
|
|
56673
56783
|
if (content?.mcpServers?.["trace-mcp"]) {
|
|
56674
56784
|
results.push({ target: configPath, action: "already_configured", detail: name });
|
|
56675
56785
|
continue;
|
|
@@ -56696,12 +56806,12 @@ function configureMcpClients(clientNames, projectRoot, opts) {
|
|
|
56696
56806
|
}
|
|
56697
56807
|
function writeTraceMcpEntry(configPath, entry) {
|
|
56698
56808
|
const dir = path93.dirname(configPath);
|
|
56699
|
-
if (!
|
|
56809
|
+
if (!fs81.existsSync(dir)) fs81.mkdirSync(dir, { recursive: true });
|
|
56700
56810
|
let config = {};
|
|
56701
56811
|
let isNew = true;
|
|
56702
|
-
if (
|
|
56812
|
+
if (fs81.existsSync(configPath)) {
|
|
56703
56813
|
try {
|
|
56704
|
-
config = JSON.parse(
|
|
56814
|
+
config = JSON.parse(fs81.readFileSync(configPath, "utf-8"));
|
|
56705
56815
|
isNew = false;
|
|
56706
56816
|
} catch {
|
|
56707
56817
|
}
|
|
@@ -56710,7 +56820,7 @@ function writeTraceMcpEntry(configPath, entry) {
|
|
|
56710
56820
|
config.mcpServers = {};
|
|
56711
56821
|
}
|
|
56712
56822
|
config.mcpServers["trace-mcp"] = entry;
|
|
56713
|
-
|
|
56823
|
+
fs81.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
56714
56824
|
return isNew ? "created" : "updated";
|
|
56715
56825
|
}
|
|
56716
56826
|
function getConfigPath(name, projectRoot, scope) {
|
|
@@ -56733,7 +56843,7 @@ function getConfigPath(name, projectRoot, scope) {
|
|
|
56733
56843
|
}
|
|
56734
56844
|
|
|
56735
56845
|
// src/init/claude-md.ts
|
|
56736
|
-
import
|
|
56846
|
+
import fs82 from "fs";
|
|
56737
56847
|
import path94 from "path";
|
|
56738
56848
|
var START_MARKER = "<!-- trace-mcp:start -->";
|
|
56739
56849
|
var END_MARKER = "<!-- trace-mcp:end -->";
|
|
@@ -56767,20 +56877,20 @@ ${END_MARKER}`;
|
|
|
56767
56877
|
function updateClaudeMd(projectRoot, opts) {
|
|
56768
56878
|
const filePath = opts.scope === "global" ? path94.join(process.env.HOME ?? process.env.USERPROFILE ?? "", ".claude", "CLAUDE.md") : path94.join(projectRoot, "CLAUDE.md");
|
|
56769
56879
|
if (opts.dryRun) {
|
|
56770
|
-
if (!
|
|
56880
|
+
if (!fs82.existsSync(filePath)) {
|
|
56771
56881
|
return { target: filePath, action: "skipped", detail: "Would create CLAUDE.md" };
|
|
56772
56882
|
}
|
|
56773
|
-
const content2 =
|
|
56883
|
+
const content2 = fs82.readFileSync(filePath, "utf-8");
|
|
56774
56884
|
if (content2.includes(START_MARKER)) {
|
|
56775
56885
|
return { target: filePath, action: "skipped", detail: "Would update trace-mcp block" };
|
|
56776
56886
|
}
|
|
56777
56887
|
return { target: filePath, action: "skipped", detail: "Would append trace-mcp block" };
|
|
56778
56888
|
}
|
|
56779
|
-
if (!
|
|
56780
|
-
|
|
56889
|
+
if (!fs82.existsSync(filePath)) {
|
|
56890
|
+
fs82.writeFileSync(filePath, BLOCK + "\n");
|
|
56781
56891
|
return { target: filePath, action: "created" };
|
|
56782
56892
|
}
|
|
56783
|
-
let content =
|
|
56893
|
+
let content = fs82.readFileSync(filePath, "utf-8");
|
|
56784
56894
|
const originalContent = content;
|
|
56785
56895
|
content = removeCompetingBlocks(content);
|
|
56786
56896
|
if (content.includes(START_MARKER)) {
|
|
@@ -56790,13 +56900,13 @@ function updateClaudeMd(projectRoot, opts) {
|
|
|
56790
56900
|
if (content === originalContent) {
|
|
56791
56901
|
return { target: filePath, action: "already_configured" };
|
|
56792
56902
|
}
|
|
56793
|
-
|
|
56903
|
+
fs82.writeFileSync(filePath, content);
|
|
56794
56904
|
const cleaned2 = content !== removeCompetingBlocks(originalContent);
|
|
56795
56905
|
return { target: filePath, action: "updated", detail: cleaned2 ? "Updated trace-mcp block and removed competing sections" : void 0 };
|
|
56796
56906
|
}
|
|
56797
56907
|
content = cleanupWhitespace(content);
|
|
56798
56908
|
const separator = content.endsWith("\n") ? "\n" : "\n\n";
|
|
56799
|
-
|
|
56909
|
+
fs82.writeFileSync(filePath, content + separator + BLOCK + "\n");
|
|
56800
56910
|
const cleaned = originalContent !== content;
|
|
56801
56911
|
return { target: filePath, action: "updated", detail: cleaned ? "Appended trace-mcp block and removed competing sections" : "Appended trace-mcp block" };
|
|
56802
56912
|
}
|
|
@@ -56915,7 +57025,7 @@ function escapeRegex4(s) {
|
|
|
56915
57025
|
}
|
|
56916
57026
|
|
|
56917
57027
|
// src/init/hooks.ts
|
|
56918
|
-
import
|
|
57028
|
+
import fs83 from "fs";
|
|
56919
57029
|
import path95 from "path";
|
|
56920
57030
|
import os6 from "os";
|
|
56921
57031
|
|
|
@@ -56981,7 +57091,7 @@ function settingsPath(client, global) {
|
|
|
56981
57091
|
return global ? path95.join(HOME2, client.configDir, "settings.json") : path95.resolve(process.cwd(), client.configDir, "settings.local.json");
|
|
56982
57092
|
}
|
|
56983
57093
|
function clientExists(client) {
|
|
56984
|
-
return
|
|
57094
|
+
return fs83.existsSync(path95.join(HOME2, client.configDir));
|
|
56985
57095
|
}
|
|
56986
57096
|
function findHookSource(scriptName) {
|
|
56987
57097
|
const filename = `${scriptName}${HOOK_EXT}`;
|
|
@@ -56994,20 +57104,20 @@ function findHookSource(scriptName) {
|
|
|
56994
57104
|
path95.resolve(process.cwd(), "hooks", filename)
|
|
56995
57105
|
];
|
|
56996
57106
|
for (const c of candidates) {
|
|
56997
|
-
if (
|
|
57107
|
+
if (fs83.existsSync(c)) return c;
|
|
56998
57108
|
}
|
|
56999
57109
|
throw new Error(`Could not find hooks/${filename} \u2014 trace-mcp installation may be corrupted.`);
|
|
57000
57110
|
}
|
|
57001
57111
|
function ensureDir(dir) {
|
|
57002
|
-
if (!
|
|
57112
|
+
if (!fs83.existsSync(dir)) fs83.mkdirSync(dir, { recursive: true });
|
|
57003
57113
|
}
|
|
57004
57114
|
function readSettings(filePath) {
|
|
57005
|
-
if (!
|
|
57006
|
-
return JSON.parse(
|
|
57115
|
+
if (!fs83.existsSync(filePath)) return {};
|
|
57116
|
+
return JSON.parse(fs83.readFileSync(filePath, "utf-8"));
|
|
57007
57117
|
}
|
|
57008
57118
|
function writeSettings(filePath, settings) {
|
|
57009
57119
|
ensureDir(path95.dirname(filePath));
|
|
57010
|
-
|
|
57120
|
+
fs83.writeFileSync(filePath, JSON.stringify(settings, null, 2) + "\n");
|
|
57011
57121
|
}
|
|
57012
57122
|
function addHookEntry(settings, desc, dest) {
|
|
57013
57123
|
const hooks = settings.hooks ?? {};
|
|
@@ -57046,13 +57156,13 @@ function installHook(desc, opts) {
|
|
|
57046
57156
|
return { target: primaryDest, action: "skipped", detail: desc.dryRunLabel };
|
|
57047
57157
|
}
|
|
57048
57158
|
const hookSrc = findHookSource(desc.scriptName);
|
|
57049
|
-
const isUpdate =
|
|
57159
|
+
const isUpdate = fs83.existsSync(primaryDest);
|
|
57050
57160
|
for (const client of CLIENTS) {
|
|
57051
57161
|
if (client !== CLIENTS[0] && !clientExists(client)) continue;
|
|
57052
57162
|
const dest = hookDest(client, desc);
|
|
57053
57163
|
ensureDir(path95.dirname(dest));
|
|
57054
|
-
|
|
57055
|
-
if (!IS_WINDOWS)
|
|
57164
|
+
fs83.copyFileSync(hookSrc, dest);
|
|
57165
|
+
if (!IS_WINDOWS) fs83.chmodSync(dest, 493);
|
|
57056
57166
|
const sPath = settingsPath(client, !!opts.global);
|
|
57057
57167
|
const settings = readSettings(sPath);
|
|
57058
57168
|
addHookEntry(settings, desc, dest);
|
|
@@ -57067,13 +57177,13 @@ function installHook(desc, opts) {
|
|
|
57067
57177
|
function uninstallHook(desc, opts) {
|
|
57068
57178
|
for (const client of CLIENTS) {
|
|
57069
57179
|
const sPath = settingsPath(client, !!opts.global);
|
|
57070
|
-
if (
|
|
57180
|
+
if (fs83.existsSync(sPath)) {
|
|
57071
57181
|
const settings = readSettings(sPath);
|
|
57072
57182
|
removeHookEntry(settings, desc);
|
|
57073
57183
|
writeSettings(sPath, settings);
|
|
57074
57184
|
}
|
|
57075
57185
|
const dest = hookDest(client, desc);
|
|
57076
|
-
if (
|
|
57186
|
+
if (fs83.existsSync(dest)) fs83.unlinkSync(dest);
|
|
57077
57187
|
}
|
|
57078
57188
|
return { target: hookDest(CLIENTS[0], desc), action: "updated", detail: "Removed" };
|
|
57079
57189
|
}
|
|
@@ -57101,7 +57211,7 @@ function installWorktreeHook(opts) {
|
|
|
57101
57211
|
}
|
|
57102
57212
|
|
|
57103
57213
|
// src/init/ide-rules.ts
|
|
57104
|
-
import
|
|
57214
|
+
import fs84 from "fs";
|
|
57105
57215
|
import path96 from "path";
|
|
57106
57216
|
var START_MARKER2 = "<!-- trace-mcp:start -->";
|
|
57107
57217
|
var END_MARKER2 = "<!-- trace-mcp:end -->";
|
|
@@ -57142,8 +57252,8 @@ function installCursorRules(projectRoot, opts) {
|
|
|
57142
57252
|
const rulesDir = path96.join(base, "rules");
|
|
57143
57253
|
const filePath = path96.join(rulesDir, "trace-mcp.mdc");
|
|
57144
57254
|
if (opts.dryRun) {
|
|
57145
|
-
if (
|
|
57146
|
-
const content =
|
|
57255
|
+
if (fs84.existsSync(filePath)) {
|
|
57256
|
+
const content = fs84.readFileSync(filePath, "utf-8");
|
|
57147
57257
|
if (content === CURSOR_RULE) {
|
|
57148
57258
|
return { target: filePath, action: "skipped", detail: "Already up to date" };
|
|
57149
57259
|
}
|
|
@@ -57151,16 +57261,16 @@ function installCursorRules(projectRoot, opts) {
|
|
|
57151
57261
|
}
|
|
57152
57262
|
return { target: filePath, action: "skipped", detail: "Would create trace-mcp.mdc" };
|
|
57153
57263
|
}
|
|
57154
|
-
if (
|
|
57155
|
-
const content =
|
|
57264
|
+
if (fs84.existsSync(filePath)) {
|
|
57265
|
+
const content = fs84.readFileSync(filePath, "utf-8");
|
|
57156
57266
|
if (content === CURSOR_RULE) {
|
|
57157
57267
|
return { target: filePath, action: "already_configured" };
|
|
57158
57268
|
}
|
|
57159
|
-
|
|
57269
|
+
fs84.writeFileSync(filePath, CURSOR_RULE);
|
|
57160
57270
|
return { target: filePath, action: "updated" };
|
|
57161
57271
|
}
|
|
57162
|
-
|
|
57163
|
-
|
|
57272
|
+
fs84.mkdirSync(rulesDir, { recursive: true });
|
|
57273
|
+
fs84.writeFileSync(filePath, CURSOR_RULE);
|
|
57164
57274
|
return { target: filePath, action: "created" };
|
|
57165
57275
|
}
|
|
57166
57276
|
var WINDSURF_BLOCK = `${START_MARKER2}
|
|
@@ -57171,31 +57281,31 @@ ${END_MARKER2}`;
|
|
|
57171
57281
|
function installWindsurfRules(projectRoot, opts) {
|
|
57172
57282
|
const filePath = opts.global ? path96.join(process.env.HOME ?? process.env.USERPROFILE ?? "", ".windsurfrules") : path96.join(projectRoot, ".windsurfrules");
|
|
57173
57283
|
if (opts.dryRun) {
|
|
57174
|
-
if (!
|
|
57284
|
+
if (!fs84.existsSync(filePath)) {
|
|
57175
57285
|
return { target: filePath, action: "skipped", detail: "Would create .windsurfrules" };
|
|
57176
57286
|
}
|
|
57177
|
-
const content2 =
|
|
57287
|
+
const content2 = fs84.readFileSync(filePath, "utf-8");
|
|
57178
57288
|
if (content2.includes(START_MARKER2)) {
|
|
57179
57289
|
return { target: filePath, action: "skipped", detail: "Would update trace-mcp block" };
|
|
57180
57290
|
}
|
|
57181
57291
|
return { target: filePath, action: "skipped", detail: "Would append trace-mcp block" };
|
|
57182
57292
|
}
|
|
57183
|
-
if (!
|
|
57184
|
-
|
|
57293
|
+
if (!fs84.existsSync(filePath)) {
|
|
57294
|
+
fs84.writeFileSync(filePath, WINDSURF_BLOCK + "\n");
|
|
57185
57295
|
return { target: filePath, action: "created" };
|
|
57186
57296
|
}
|
|
57187
|
-
const content =
|
|
57297
|
+
const content = fs84.readFileSync(filePath, "utf-8");
|
|
57188
57298
|
if (content.includes(START_MARKER2)) {
|
|
57189
57299
|
const re = new RegExp(`${escapeRegex5(START_MARKER2)}[\\s\\S]*?${escapeRegex5(END_MARKER2)}`, "m");
|
|
57190
57300
|
const updated = content.replace(re, WINDSURF_BLOCK);
|
|
57191
57301
|
if (updated === content) {
|
|
57192
57302
|
return { target: filePath, action: "already_configured" };
|
|
57193
57303
|
}
|
|
57194
|
-
|
|
57304
|
+
fs84.writeFileSync(filePath, updated);
|
|
57195
57305
|
return { target: filePath, action: "updated" };
|
|
57196
57306
|
}
|
|
57197
57307
|
const separator = content.endsWith("\n") ? "\n" : "\n\n";
|
|
57198
|
-
|
|
57308
|
+
fs84.writeFileSync(filePath, content + separator + WINDSURF_BLOCK + "\n");
|
|
57199
57309
|
return { target: filePath, action: "updated", detail: "Appended trace-mcp block" };
|
|
57200
57310
|
}
|
|
57201
57311
|
function escapeRegex5(s) {
|
|
@@ -57203,7 +57313,7 @@ function escapeRegex5(s) {
|
|
|
57203
57313
|
}
|
|
57204
57314
|
|
|
57205
57315
|
// src/init/detector.ts
|
|
57206
|
-
import
|
|
57316
|
+
import fs85 from "fs";
|
|
57207
57317
|
import path97 from "path";
|
|
57208
57318
|
import os7 from "os";
|
|
57209
57319
|
import Database6 from "better-sqlite3";
|
|
@@ -57239,8 +57349,8 @@ function detectProject(dir) {
|
|
|
57239
57349
|
const existingConfig = detectExistingConfig(projectRoot);
|
|
57240
57350
|
const existingDb = detectExistingDb(projectRoot);
|
|
57241
57351
|
const claudeMdPath = path97.join(projectRoot, "CLAUDE.md");
|
|
57242
|
-
const hasClaudeMd =
|
|
57243
|
-
const claudeMdHasTraceMcpBlock = hasClaudeMd &&
|
|
57352
|
+
const hasClaudeMd = fs85.existsSync(claudeMdPath);
|
|
57353
|
+
const claudeMdHasTraceMcpBlock = hasClaudeMd && fs85.readFileSync(claudeMdPath, "utf-8").includes("<!-- trace-mcp:start -->");
|
|
57244
57354
|
const { hasGuardHook, guardHookVersion } = detectGuardHook();
|
|
57245
57355
|
return {
|
|
57246
57356
|
projectRoot,
|
|
@@ -57259,8 +57369,8 @@ function detectProject(dir) {
|
|
|
57259
57369
|
function detectPackageManagers(root) {
|
|
57260
57370
|
const managers = [];
|
|
57261
57371
|
const check = (file, type, lockfiles) => {
|
|
57262
|
-
if (
|
|
57263
|
-
const lockfile = lockfiles.find((l) =>
|
|
57372
|
+
if (fs85.existsSync(path97.join(root, file))) {
|
|
57373
|
+
const lockfile = lockfiles.find((l) => fs85.existsSync(path97.join(root, l)));
|
|
57264
57374
|
managers.push({ type, lockfile });
|
|
57265
57375
|
}
|
|
57266
57376
|
};
|
|
@@ -57274,7 +57384,7 @@ function detectPackageManagers(root) {
|
|
|
57274
57384
|
check("pyproject.toml", "poetry", ["poetry.lock", "uv.lock"]);
|
|
57275
57385
|
if (managers.length > 0 && managers[managers.length - 1].type === "poetry") {
|
|
57276
57386
|
if (managers[managers.length - 1].lockfile === "uv.lock") managers[managers.length - 1].type = "uv";
|
|
57277
|
-
else if (!managers[managers.length - 1].lockfile &&
|
|
57387
|
+
else if (!managers[managers.length - 1].lockfile && fs85.existsSync(path97.join(root, "requirements.txt"))) {
|
|
57278
57388
|
managers[managers.length - 1].type = "pip";
|
|
57279
57389
|
}
|
|
57280
57390
|
}
|
|
@@ -57283,7 +57393,7 @@ function detectPackageManagers(root) {
|
|
|
57283
57393
|
check("Gemfile", "bundler", ["Gemfile.lock"]);
|
|
57284
57394
|
check("pom.xml", "maven", []);
|
|
57285
57395
|
if (!managers.some((m) => m.type === "maven")) {
|
|
57286
|
-
if (
|
|
57396
|
+
if (fs85.existsSync(path97.join(root, "build.gradle")) || fs85.existsSync(path97.join(root, "build.gradle.kts"))) {
|
|
57287
57397
|
managers.push({ type: "gradle", lockfile: void 0 });
|
|
57288
57398
|
}
|
|
57289
57399
|
}
|
|
@@ -57292,9 +57402,9 @@ function detectPackageManagers(root) {
|
|
|
57292
57402
|
function detectMcpClients(projectRoot) {
|
|
57293
57403
|
const clients = [];
|
|
57294
57404
|
const checkConfig = (name, configPath) => {
|
|
57295
|
-
if (!
|
|
57405
|
+
if (!fs85.existsSync(configPath)) return;
|
|
57296
57406
|
try {
|
|
57297
|
-
const content = JSON.parse(
|
|
57407
|
+
const content = JSON.parse(fs85.readFileSync(configPath, "utf-8"));
|
|
57298
57408
|
const hasTraceMcp = !!content?.mcpServers?.["trace-mcp"];
|
|
57299
57409
|
clients.push({ name, configPath, hasTraceMcp });
|
|
57300
57410
|
} catch {
|
|
@@ -57337,12 +57447,12 @@ function detectExistingConfig(root) {
|
|
|
57337
57447
|
path97.join(root, ".config", "trace-mcp.json")
|
|
57338
57448
|
];
|
|
57339
57449
|
for (const p5 of candidates) {
|
|
57340
|
-
if (
|
|
57450
|
+
if (fs85.existsSync(p5)) return { path: p5 };
|
|
57341
57451
|
}
|
|
57342
57452
|
const pkgPath = path97.join(root, "package.json");
|
|
57343
|
-
if (
|
|
57453
|
+
if (fs85.existsSync(pkgPath)) {
|
|
57344
57454
|
try {
|
|
57345
|
-
const pkg = JSON.parse(
|
|
57455
|
+
const pkg = JSON.parse(fs85.readFileSync(pkgPath, "utf-8"));
|
|
57346
57456
|
if (pkg["trace-mcp"]) return { path: pkgPath };
|
|
57347
57457
|
} catch {
|
|
57348
57458
|
}
|
|
@@ -57351,7 +57461,7 @@ function detectExistingConfig(root) {
|
|
|
57351
57461
|
}
|
|
57352
57462
|
function detectExistingDb(root, globalDbPath) {
|
|
57353
57463
|
const candidates = globalDbPath ? [globalDbPath, path97.join(root, ".trace-mcp", "index.db")] : [path97.join(root, ".trace-mcp", "index.db")];
|
|
57354
|
-
const dbPath = candidates.find((p5) =>
|
|
57464
|
+
const dbPath = candidates.find((p5) => fs85.existsSync(p5));
|
|
57355
57465
|
if (!dbPath) return null;
|
|
57356
57466
|
try {
|
|
57357
57467
|
const db = new Database6(dbPath, { readonly: true });
|
|
@@ -57369,9 +57479,9 @@ function detectGuardHook() {
|
|
|
57369
57479
|
const ext = process.platform === "win32" ? ".cmd" : ".sh";
|
|
57370
57480
|
const hookPath = path97.join(HOME3, ".claude", "hooks", `trace-mcp-guard${ext}`);
|
|
57371
57481
|
const clawHookPath = path97.join(HOME3, ".claw", "hooks", `trace-mcp-guard${ext}`);
|
|
57372
|
-
const existingPath =
|
|
57482
|
+
const existingPath = fs85.existsSync(hookPath) ? hookPath : fs85.existsSync(clawHookPath) ? clawHookPath : null;
|
|
57373
57483
|
if (!existingPath) return { hasGuardHook: false, guardHookVersion: null };
|
|
57374
|
-
const content =
|
|
57484
|
+
const content = fs85.readFileSync(existingPath, "utf-8");
|
|
57375
57485
|
const match = content.match(/^(?:#|REM) trace-mcp-guard v(.+)$/m);
|
|
57376
57486
|
return {
|
|
57377
57487
|
hasGuardHook: true,
|
|
@@ -57380,7 +57490,7 @@ function detectGuardHook() {
|
|
|
57380
57490
|
}
|
|
57381
57491
|
|
|
57382
57492
|
// src/init/conflict-detector.ts
|
|
57383
|
-
import
|
|
57493
|
+
import fs86 from "fs";
|
|
57384
57494
|
import path98 from "path";
|
|
57385
57495
|
import os8 from "os";
|
|
57386
57496
|
var HOME4 = os8.homedir();
|
|
@@ -57507,10 +57617,10 @@ function scanMcpServerConfigs(projectRoot) {
|
|
|
57507
57617
|
const conflicts = [];
|
|
57508
57618
|
const configs = getMcpConfigPaths(projectRoot);
|
|
57509
57619
|
for (const { clientName, configPath } of configs) {
|
|
57510
|
-
if (!
|
|
57620
|
+
if (!fs86.existsSync(configPath)) continue;
|
|
57511
57621
|
let parsed;
|
|
57512
57622
|
try {
|
|
57513
|
-
parsed = JSON.parse(
|
|
57623
|
+
parsed = JSON.parse(fs86.readFileSync(configPath, "utf-8"));
|
|
57514
57624
|
} catch {
|
|
57515
57625
|
continue;
|
|
57516
57626
|
}
|
|
@@ -57570,12 +57680,12 @@ function scanHooksInSettings() {
|
|
|
57570
57680
|
path98.join(HOME4, ".claw", "settings.local.json")
|
|
57571
57681
|
];
|
|
57572
57682
|
const projectsDir = path98.join(HOME4, ".claude", "projects");
|
|
57573
|
-
if (
|
|
57683
|
+
if (fs86.existsSync(projectsDir)) {
|
|
57574
57684
|
try {
|
|
57575
|
-
for (const entry of
|
|
57685
|
+
for (const entry of fs86.readdirSync(projectsDir)) {
|
|
57576
57686
|
const projDir = path98.join(projectsDir, entry);
|
|
57577
57687
|
try {
|
|
57578
|
-
if (!
|
|
57688
|
+
if (!fs86.statSync(projDir).isDirectory()) continue;
|
|
57579
57689
|
} catch {
|
|
57580
57690
|
continue;
|
|
57581
57691
|
}
|
|
@@ -57586,10 +57696,10 @@ function scanHooksInSettings() {
|
|
|
57586
57696
|
}
|
|
57587
57697
|
}
|
|
57588
57698
|
for (const settingsPath2 of settingsFiles) {
|
|
57589
|
-
if (!
|
|
57699
|
+
if (!fs86.existsSync(settingsPath2)) continue;
|
|
57590
57700
|
let settings;
|
|
57591
57701
|
try {
|
|
57592
|
-
settings = JSON.parse(
|
|
57702
|
+
settings = JSON.parse(fs86.readFileSync(settingsPath2, "utf-8"));
|
|
57593
57703
|
} catch {
|
|
57594
57704
|
continue;
|
|
57595
57705
|
}
|
|
@@ -57631,10 +57741,10 @@ function scanHookScriptFiles() {
|
|
|
57631
57741
|
path98.join(HOME4, ".claw", "hooks")
|
|
57632
57742
|
];
|
|
57633
57743
|
for (const hooksDir of hooksDirs) {
|
|
57634
|
-
if (!
|
|
57744
|
+
if (!fs86.existsSync(hooksDir)) continue;
|
|
57635
57745
|
let files;
|
|
57636
57746
|
try {
|
|
57637
|
-
files =
|
|
57747
|
+
files = fs86.readdirSync(hooksDir);
|
|
57638
57748
|
} catch {
|
|
57639
57749
|
continue;
|
|
57640
57750
|
}
|
|
@@ -57667,17 +57777,17 @@ function scanClaudeMdFiles(projectRoot) {
|
|
|
57667
57777
|
path98.join(HOME4, ".claude", "AGENTS.md")
|
|
57668
57778
|
];
|
|
57669
57779
|
const projectsDir = path98.join(HOME4, ".claude", "projects");
|
|
57670
|
-
if (
|
|
57780
|
+
if (fs86.existsSync(projectsDir)) {
|
|
57671
57781
|
try {
|
|
57672
|
-
for (const entry of
|
|
57782
|
+
for (const entry of fs86.readdirSync(projectsDir)) {
|
|
57673
57783
|
const projDir = path98.join(projectsDir, entry);
|
|
57674
|
-
if (!
|
|
57784
|
+
if (!fs86.statSync(projDir).isDirectory()) continue;
|
|
57675
57785
|
files.push(path98.join(projDir, "CLAUDE.md"));
|
|
57676
57786
|
files.push(path98.join(projDir, "AGENTS.md"));
|
|
57677
57787
|
const memDir = path98.join(projDir, "memory");
|
|
57678
|
-
if (
|
|
57788
|
+
if (fs86.existsSync(memDir)) {
|
|
57679
57789
|
try {
|
|
57680
|
-
for (const memFile of
|
|
57790
|
+
for (const memFile of fs86.readdirSync(memDir)) {
|
|
57681
57791
|
if (memFile.endsWith(".md") && memFile !== "MEMORY.md") {
|
|
57682
57792
|
files.push(path98.join(memDir, memFile));
|
|
57683
57793
|
}
|
|
@@ -57696,10 +57806,10 @@ function scanClaudeMdFiles(projectRoot) {
|
|
|
57696
57806
|
);
|
|
57697
57807
|
}
|
|
57698
57808
|
for (const filePath of files) {
|
|
57699
|
-
if (!
|
|
57809
|
+
if (!fs86.existsSync(filePath)) continue;
|
|
57700
57810
|
let content;
|
|
57701
57811
|
try {
|
|
57702
|
-
content =
|
|
57812
|
+
content = fs86.readFileSync(filePath, "utf-8");
|
|
57703
57813
|
} catch {
|
|
57704
57814
|
continue;
|
|
57705
57815
|
}
|
|
@@ -57756,11 +57866,11 @@ function scanIdeRuleFiles(projectRoot) {
|
|
|
57756
57866
|
ruleFiles.push({ path: path98.join(projectRoot, ".continuerules"), type: ".continuerules" });
|
|
57757
57867
|
ruleFiles.push({ path: path98.join(projectRoot, ".github", "copilot-instructions.md"), type: "copilot-instructions.md" });
|
|
57758
57868
|
const clineRulesDir = path98.join(projectRoot, ".clinerules");
|
|
57759
|
-
if (
|
|
57869
|
+
if (fs86.existsSync(clineRulesDir)) {
|
|
57760
57870
|
try {
|
|
57761
|
-
const stat =
|
|
57871
|
+
const stat = fs86.statSync(clineRulesDir);
|
|
57762
57872
|
if (stat.isDirectory()) {
|
|
57763
|
-
for (const file of
|
|
57873
|
+
for (const file of fs86.readdirSync(clineRulesDir)) {
|
|
57764
57874
|
ruleFiles.push({ path: path98.join(clineRulesDir, file), type: `.clinerules/${file}` });
|
|
57765
57875
|
}
|
|
57766
57876
|
}
|
|
@@ -57771,9 +57881,9 @@ function scanIdeRuleFiles(projectRoot) {
|
|
|
57771
57881
|
const cursorRulesDirs = [path98.join(HOME4, ".cursor", "rules")];
|
|
57772
57882
|
if (projectRoot) cursorRulesDirs.push(path98.join(projectRoot, ".cursor", "rules"));
|
|
57773
57883
|
for (const rulesDir of cursorRulesDirs) {
|
|
57774
|
-
if (!
|
|
57884
|
+
if (!fs86.existsSync(rulesDir)) continue;
|
|
57775
57885
|
try {
|
|
57776
|
-
for (const file of
|
|
57886
|
+
for (const file of fs86.readdirSync(rulesDir)) {
|
|
57777
57887
|
if (!file.endsWith(".mdc") || file === "trace-mcp.mdc") continue;
|
|
57778
57888
|
ruleFiles.push({ path: path98.join(rulesDir, file), type: `.cursor/rules/${file}` });
|
|
57779
57889
|
}
|
|
@@ -57781,10 +57891,10 @@ function scanIdeRuleFiles(projectRoot) {
|
|
|
57781
57891
|
}
|
|
57782
57892
|
}
|
|
57783
57893
|
for (const { path: filePath, type } of ruleFiles) {
|
|
57784
|
-
if (!
|
|
57894
|
+
if (!fs86.existsSync(filePath)) continue;
|
|
57785
57895
|
let content;
|
|
57786
57896
|
try {
|
|
57787
|
-
content =
|
|
57897
|
+
content = fs86.readFileSync(filePath, "utf-8");
|
|
57788
57898
|
} catch {
|
|
57789
57899
|
continue;
|
|
57790
57900
|
}
|
|
@@ -57810,7 +57920,7 @@ function scanProjectConfigFiles(projectRoot) {
|
|
|
57810
57920
|
const conflicts = [];
|
|
57811
57921
|
for (const { file, competitor } of COMPETING_PROJECT_FILES) {
|
|
57812
57922
|
const filePath = path98.join(projectRoot, file);
|
|
57813
|
-
if (!
|
|
57923
|
+
if (!fs86.existsSync(filePath)) continue;
|
|
57814
57924
|
conflicts.push({
|
|
57815
57925
|
id: `config:${competitor}:${file}`,
|
|
57816
57926
|
category: "config_file",
|
|
@@ -57834,10 +57944,10 @@ function scanProjectConfigDirs(projectRoot) {
|
|
|
57834
57944
|
];
|
|
57835
57945
|
for (const { dir, competitor } of dirs) {
|
|
57836
57946
|
const fullPath = path98.join(projectRoot, dir);
|
|
57837
|
-
if (!
|
|
57947
|
+
if (!fs86.existsSync(fullPath)) continue;
|
|
57838
57948
|
let stat;
|
|
57839
57949
|
try {
|
|
57840
|
-
stat =
|
|
57950
|
+
stat = fs86.statSync(fullPath);
|
|
57841
57951
|
} catch {
|
|
57842
57952
|
continue;
|
|
57843
57953
|
}
|
|
@@ -57873,10 +57983,10 @@ function scanContinueConfigs(projectRoot) {
|
|
|
57873
57983
|
mcpServersDirs.push(path98.join(projectRoot, ".continue", "mcpServers"));
|
|
57874
57984
|
}
|
|
57875
57985
|
for (const mcpDir of mcpServersDirs) {
|
|
57876
|
-
if (!
|
|
57986
|
+
if (!fs86.existsSync(mcpDir)) continue;
|
|
57877
57987
|
let files;
|
|
57878
57988
|
try {
|
|
57879
|
-
files =
|
|
57989
|
+
files = fs86.readdirSync(mcpDir);
|
|
57880
57990
|
} catch {
|
|
57881
57991
|
continue;
|
|
57882
57992
|
}
|
|
@@ -57885,7 +57995,7 @@ function scanContinueConfigs(projectRoot) {
|
|
|
57885
57995
|
const filePath = path98.join(mcpDir, file);
|
|
57886
57996
|
let content;
|
|
57887
57997
|
try {
|
|
57888
|
-
content =
|
|
57998
|
+
content = fs86.readFileSync(filePath, "utf-8");
|
|
57889
57999
|
} catch {
|
|
57890
58000
|
continue;
|
|
57891
58001
|
}
|
|
@@ -57912,14 +58022,14 @@ function scanContinueConfigs(projectRoot) {
|
|
|
57912
58022
|
function scanGitHooks(projectRoot) {
|
|
57913
58023
|
const conflicts = [];
|
|
57914
58024
|
const hooksDir = path98.join(projectRoot, ".git", "hooks");
|
|
57915
|
-
if (!
|
|
58025
|
+
if (!fs86.existsSync(hooksDir)) return conflicts;
|
|
57916
58026
|
const hookFiles = ["pre-commit", "post-commit", "prepare-commit-msg"];
|
|
57917
58027
|
for (const hookFile of hookFiles) {
|
|
57918
58028
|
const hookPath = path98.join(hooksDir, hookFile);
|
|
57919
|
-
if (!
|
|
58029
|
+
if (!fs86.existsSync(hookPath)) continue;
|
|
57920
58030
|
let content;
|
|
57921
58031
|
try {
|
|
57922
|
-
content =
|
|
58032
|
+
content = fs86.readFileSync(hookPath, "utf-8");
|
|
57923
58033
|
} catch {
|
|
57924
58034
|
continue;
|
|
57925
58035
|
}
|
|
@@ -57942,10 +58052,10 @@ function scanGitHooks(projectRoot) {
|
|
|
57942
58052
|
function scanGlobalArtifacts() {
|
|
57943
58053
|
const conflicts = [];
|
|
57944
58054
|
for (const { dir, competitor } of COMPETING_GLOBAL_DIRS) {
|
|
57945
|
-
if (!
|
|
58055
|
+
if (!fs86.existsSync(dir)) continue;
|
|
57946
58056
|
let size = 0;
|
|
57947
58057
|
try {
|
|
57948
|
-
const files =
|
|
58058
|
+
const files = fs86.readdirSync(dir);
|
|
57949
58059
|
size = files.length;
|
|
57950
58060
|
} catch {
|
|
57951
58061
|
}
|
|
@@ -57971,7 +58081,7 @@ function truncate(s, maxLen) {
|
|
|
57971
58081
|
}
|
|
57972
58082
|
|
|
57973
58083
|
// src/init/conflict-resolver.ts
|
|
57974
|
-
import
|
|
58084
|
+
import fs87 from "fs";
|
|
57975
58085
|
import path99 from "path";
|
|
57976
58086
|
function fixConflict(conflict, opts = {}) {
|
|
57977
58087
|
if (!conflict.fixable) {
|
|
@@ -58008,16 +58118,16 @@ function fixMcpServer(conflict, opts) {
|
|
|
58008
58118
|
if (opts.dryRun) {
|
|
58009
58119
|
return { conflictId: conflict.id, action: "disabled", detail: `Would comment out "${serverName}" in ${shortPath2(configPath)}`, target: configPath };
|
|
58010
58120
|
}
|
|
58011
|
-
if (!
|
|
58121
|
+
if (!fs87.existsSync(configPath)) {
|
|
58012
58122
|
return { conflictId: conflict.id, action: "skipped", detail: "Config file no longer exists", target: configPath };
|
|
58013
58123
|
}
|
|
58014
58124
|
try {
|
|
58015
|
-
const raw =
|
|
58125
|
+
const raw = fs87.readFileSync(configPath, "utf-8");
|
|
58016
58126
|
const result = commentOutJsonKey(raw, serverName);
|
|
58017
58127
|
if (!result) {
|
|
58018
58128
|
return { conflictId: conflict.id, action: "skipped", detail: `Server "${serverName}" not found (already disabled?)`, target: configPath };
|
|
58019
58129
|
}
|
|
58020
|
-
|
|
58130
|
+
fs87.writeFileSync(configPath, result);
|
|
58021
58131
|
return { conflictId: conflict.id, action: "disabled", detail: `Commented out "${serverName}" in ${shortPath2(configPath)}`, target: configPath };
|
|
58022
58132
|
} catch (err32) {
|
|
58023
58133
|
return { conflictId: conflict.id, action: "skipped", detail: `Failed to update config: ${err32.message}`, target: configPath };
|
|
@@ -58069,11 +58179,11 @@ function fixHookInSettings(conflict, opts) {
|
|
|
58069
58179
|
if (opts.dryRun) {
|
|
58070
58180
|
return { conflictId: conflict.id, action: "removed", detail: `Would remove ${competitor} hooks from ${shortPath2(settingsPath2)}`, target: settingsPath2 };
|
|
58071
58181
|
}
|
|
58072
|
-
if (!
|
|
58182
|
+
if (!fs87.existsSync(settingsPath2)) {
|
|
58073
58183
|
return { conflictId: conflict.id, action: "skipped", detail: "Settings file no longer exists", target: settingsPath2 };
|
|
58074
58184
|
}
|
|
58075
58185
|
try {
|
|
58076
|
-
const settings = JSON.parse(
|
|
58186
|
+
const settings = JSON.parse(fs87.readFileSync(settingsPath2, "utf-8"));
|
|
58077
58187
|
const hooks = settings.hooks;
|
|
58078
58188
|
if (!hooks) {
|
|
58079
58189
|
return { conflictId: conflict.id, action: "skipped", detail: "No hooks section found", target: settingsPath2 };
|
|
@@ -58101,7 +58211,7 @@ function fixHookInSettings(conflict, opts) {
|
|
|
58101
58211
|
if (!modified) {
|
|
58102
58212
|
return { conflictId: conflict.id, action: "skipped", detail: "Hook entries already removed", target: settingsPath2 };
|
|
58103
58213
|
}
|
|
58104
|
-
|
|
58214
|
+
fs87.writeFileSync(settingsPath2, JSON.stringify(settings, null, 2) + "\n");
|
|
58105
58215
|
return { conflictId: conflict.id, action: "removed", detail: `Removed ${competitor} hooks from ${shortPath2(settingsPath2)}`, target: settingsPath2 };
|
|
58106
58216
|
} catch (err32) {
|
|
58107
58217
|
return { conflictId: conflict.id, action: "skipped", detail: `Failed to update settings: ${err32.message}`, target: settingsPath2 };
|
|
@@ -58112,11 +58222,11 @@ function fixHookScript(conflict, opts) {
|
|
|
58112
58222
|
if (opts.dryRun) {
|
|
58113
58223
|
return { conflictId: conflict.id, action: "removed", detail: `Would delete ${shortPath2(scriptPath)}`, target: scriptPath };
|
|
58114
58224
|
}
|
|
58115
|
-
if (!
|
|
58225
|
+
if (!fs87.existsSync(scriptPath)) {
|
|
58116
58226
|
return { conflictId: conflict.id, action: "skipped", detail: "Script already removed", target: scriptPath };
|
|
58117
58227
|
}
|
|
58118
58228
|
try {
|
|
58119
|
-
|
|
58229
|
+
fs87.unlinkSync(scriptPath);
|
|
58120
58230
|
return { conflictId: conflict.id, action: "removed", detail: `Deleted ${shortPath2(scriptPath)}`, target: scriptPath };
|
|
58121
58231
|
} catch (err32) {
|
|
58122
58232
|
return { conflictId: conflict.id, action: "skipped", detail: `Failed to delete: ${err32.message}`, target: scriptPath };
|
|
@@ -58127,11 +58237,11 @@ function fixClaudeMdBlock(conflict, opts) {
|
|
|
58127
58237
|
if (opts.dryRun) {
|
|
58128
58238
|
return { conflictId: conflict.id, action: "cleaned", detail: `Would remove ${conflict.competitor} content from ${shortPath2(filePath)}`, target: filePath };
|
|
58129
58239
|
}
|
|
58130
|
-
if (!
|
|
58240
|
+
if (!fs87.existsSync(filePath)) {
|
|
58131
58241
|
return { conflictId: conflict.id, action: "skipped", detail: "File no longer exists", target: filePath };
|
|
58132
58242
|
}
|
|
58133
58243
|
try {
|
|
58134
|
-
const content =
|
|
58244
|
+
const content = fs87.readFileSync(filePath, "utf-8");
|
|
58135
58245
|
const tools = ["jcodemunch", "code-index", "repomix", "aider", "cline", "cody", "greptile", "sourcegraph", "code-compass", "repo-map"];
|
|
58136
58246
|
const markerPattern = new RegExp(
|
|
58137
58247
|
`<!-- ?(${tools.join("|")}):start ?-->[\\s\\S]*?<!-- ?\\1:end ?-->\\n?`,
|
|
@@ -58140,7 +58250,7 @@ function fixClaudeMdBlock(conflict, opts) {
|
|
|
58140
58250
|
let updated = content.replace(markerPattern, "");
|
|
58141
58251
|
updated = removeCompetitorSections(updated, conflict.competitor);
|
|
58142
58252
|
if (filePath.includes("/memory/") && isEntirelyAboutCompetitor(updated, conflict.competitor)) {
|
|
58143
|
-
|
|
58253
|
+
fs87.unlinkSync(filePath);
|
|
58144
58254
|
removeFromMemoryIndex(filePath);
|
|
58145
58255
|
return { conflictId: conflict.id, action: "removed", detail: `Deleted memory file ${shortPath2(filePath)}`, target: filePath };
|
|
58146
58256
|
}
|
|
@@ -58148,7 +58258,7 @@ function fixClaudeMdBlock(conflict, opts) {
|
|
|
58148
58258
|
if (updated === content) {
|
|
58149
58259
|
return { conflictId: conflict.id, action: "skipped", detail: "No competing content found to remove", target: filePath };
|
|
58150
58260
|
}
|
|
58151
|
-
|
|
58261
|
+
fs87.writeFileSync(filePath, updated);
|
|
58152
58262
|
return { conflictId: conflict.id, action: "cleaned", detail: `Removed ${conflict.competitor} content from ${shortPath2(filePath)}`, target: filePath };
|
|
58153
58263
|
} catch (err32) {
|
|
58154
58264
|
return { conflictId: conflict.id, action: "skipped", detail: `Failed to update: ${err32.message}`, target: filePath };
|
|
@@ -58200,14 +58310,14 @@ function isEntirelyAboutCompetitor(content, competitor) {
|
|
|
58200
58310
|
function removeFromMemoryIndex(deletedFilePath) {
|
|
58201
58311
|
const memoryDir = path99.dirname(deletedFilePath);
|
|
58202
58312
|
const indexPath = path99.join(memoryDir, "MEMORY.md");
|
|
58203
|
-
if (!
|
|
58313
|
+
if (!fs87.existsSync(indexPath)) return;
|
|
58204
58314
|
try {
|
|
58205
|
-
const content =
|
|
58315
|
+
const content = fs87.readFileSync(indexPath, "utf-8");
|
|
58206
58316
|
const fileName = path99.basename(deletedFilePath);
|
|
58207
58317
|
const escaped = fileName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
58208
58318
|
const updated = content.split("\n").filter((line) => !new RegExp(`\\(${escaped}\\)`).test(line)).join("\n");
|
|
58209
58319
|
if (updated !== content) {
|
|
58210
|
-
|
|
58320
|
+
fs87.writeFileSync(indexPath, updated);
|
|
58211
58321
|
}
|
|
58212
58322
|
} catch {
|
|
58213
58323
|
}
|
|
@@ -58217,15 +58327,15 @@ function fixConfigFile(conflict, opts) {
|
|
|
58217
58327
|
if (opts.dryRun) {
|
|
58218
58328
|
return { conflictId: conflict.id, action: "removed", detail: `Would delete ${shortPath2(filePath)}`, target: filePath };
|
|
58219
58329
|
}
|
|
58220
|
-
if (!
|
|
58330
|
+
if (!fs87.existsSync(filePath)) {
|
|
58221
58331
|
return { conflictId: conflict.id, action: "skipped", detail: "Already removed", target: filePath };
|
|
58222
58332
|
}
|
|
58223
58333
|
try {
|
|
58224
|
-
const stat =
|
|
58334
|
+
const stat = fs87.statSync(filePath);
|
|
58225
58335
|
if (stat.isDirectory()) {
|
|
58226
|
-
|
|
58336
|
+
fs87.rmSync(filePath, { recursive: true, force: true });
|
|
58227
58337
|
} else {
|
|
58228
|
-
|
|
58338
|
+
fs87.unlinkSync(filePath);
|
|
58229
58339
|
}
|
|
58230
58340
|
return { conflictId: conflict.id, action: "removed", detail: `Deleted ${shortPath2(filePath)}`, target: filePath };
|
|
58231
58341
|
} catch (err32) {
|
|
@@ -58237,11 +58347,11 @@ function fixGlobalArtifact(conflict, opts) {
|
|
|
58237
58347
|
if (opts.dryRun) {
|
|
58238
58348
|
return { conflictId: conflict.id, action: "removed", detail: `Would remove ${shortPath2(dirPath)}`, target: dirPath };
|
|
58239
58349
|
}
|
|
58240
|
-
if (!
|
|
58350
|
+
if (!fs87.existsSync(dirPath)) {
|
|
58241
58351
|
return { conflictId: conflict.id, action: "skipped", detail: "Directory already removed", target: dirPath };
|
|
58242
58352
|
}
|
|
58243
58353
|
try {
|
|
58244
|
-
|
|
58354
|
+
fs87.rmSync(dirPath, { recursive: true, force: true });
|
|
58245
58355
|
return { conflictId: conflict.id, action: "removed", detail: `Removed ${shortPath2(dirPath)}`, target: dirPath };
|
|
58246
58356
|
} catch (err32) {
|
|
58247
58357
|
return { conflictId: conflict.id, action: "skipped", detail: `Failed to remove: ${err32.message}`, target: dirPath };
|
|
@@ -58254,7 +58364,7 @@ function shortPath2(p5) {
|
|
|
58254
58364
|
}
|
|
58255
58365
|
|
|
58256
58366
|
// src/project-root.ts
|
|
58257
|
-
import
|
|
58367
|
+
import fs88 from "fs";
|
|
58258
58368
|
import path100 from "path";
|
|
58259
58369
|
var ROOT_MARKERS = [
|
|
58260
58370
|
".git",
|
|
@@ -58271,10 +58381,10 @@ var ROOT_MARKERS = [
|
|
|
58271
58381
|
var SKIP_DIRS2 = /* @__PURE__ */ new Set([".git", "node_modules", "vendor", ".svn", "__pycache__", ".tox"]);
|
|
58272
58382
|
function discoverChildProjects(parentDir) {
|
|
58273
58383
|
const absParent = path100.resolve(parentDir);
|
|
58274
|
-
if (!
|
|
58384
|
+
if (!fs88.existsSync(absParent)) return [];
|
|
58275
58385
|
let entries;
|
|
58276
58386
|
try {
|
|
58277
|
-
entries =
|
|
58387
|
+
entries = fs88.readdirSync(absParent, { withFileTypes: true });
|
|
58278
58388
|
} catch {
|
|
58279
58389
|
return [];
|
|
58280
58390
|
}
|
|
@@ -58285,7 +58395,7 @@ function discoverChildProjects(parentDir) {
|
|
|
58285
58395
|
if (SKIP_DIRS2.has(entry.name)) continue;
|
|
58286
58396
|
const childDir = path100.join(absParent, entry.name);
|
|
58287
58397
|
for (const marker of ROOT_MARKERS) {
|
|
58288
|
-
if (
|
|
58398
|
+
if (fs88.existsSync(path100.join(childDir, marker))) {
|
|
58289
58399
|
children.push(childDir);
|
|
58290
58400
|
break;
|
|
58291
58401
|
}
|
|
@@ -58297,7 +58407,7 @@ function findProjectRoot(from) {
|
|
|
58297
58407
|
let dir = path100.resolve(from ?? process.cwd());
|
|
58298
58408
|
while (true) {
|
|
58299
58409
|
for (const marker of ROOT_MARKERS) {
|
|
58300
|
-
if (
|
|
58410
|
+
if (fs88.existsSync(path100.join(dir, marker))) {
|
|
58301
58411
|
return dir;
|
|
58302
58412
|
}
|
|
58303
58413
|
}
|
|
@@ -58544,15 +58654,15 @@ function generateConfig(detection) {
|
|
|
58544
58654
|
}
|
|
58545
58655
|
|
|
58546
58656
|
// src/registry.ts
|
|
58547
|
-
import
|
|
58657
|
+
import fs89 from "fs";
|
|
58548
58658
|
import path101 from "path";
|
|
58549
58659
|
function emptyRegistry() {
|
|
58550
58660
|
return { version: 1, projects: {} };
|
|
58551
58661
|
}
|
|
58552
58662
|
function loadRegistry2() {
|
|
58553
|
-
if (!
|
|
58663
|
+
if (!fs89.existsSync(REGISTRY_PATH)) return emptyRegistry();
|
|
58554
58664
|
try {
|
|
58555
|
-
const raw = JSON.parse(
|
|
58665
|
+
const raw = JSON.parse(fs89.readFileSync(REGISTRY_PATH, "utf-8"));
|
|
58556
58666
|
if (raw.version === 1 && raw.projects) return raw;
|
|
58557
58667
|
return emptyRegistry();
|
|
58558
58668
|
} catch {
|
|
@@ -58562,8 +58672,8 @@ function loadRegistry2() {
|
|
|
58562
58672
|
function saveRegistry(reg) {
|
|
58563
58673
|
ensureGlobalDirs();
|
|
58564
58674
|
const tmp = REGISTRY_PATH + ".tmp." + process.pid;
|
|
58565
|
-
|
|
58566
|
-
|
|
58675
|
+
fs89.writeFileSync(tmp, JSON.stringify(reg, null, 2) + "\n");
|
|
58676
|
+
fs89.renameSync(tmp, REGISTRY_PATH);
|
|
58567
58677
|
}
|
|
58568
58678
|
function registerProject(root, opts) {
|
|
58569
58679
|
const absRoot = path101.resolve(root);
|
|
@@ -58621,8 +58731,17 @@ function updateLastIndexed(root) {
|
|
|
58621
58731
|
// src/cli/init.ts
|
|
58622
58732
|
var initCommand = new Command("init").description("One-time global setup: configure MCP clients, install hooks, set up CLAUDE.md").option("--yes", "Skip prompts, use recommended defaults").option("--skip-hooks", "Do not install guard hooks").option("--skip-mcp-client", "Do not configure MCP client").option("--skip-claude-md", "Do not add CLAUDE.md block").option("--mcp-client <name>", "Force MCP client: claude-code | claude-desktop | cursor | windsurf | continue").option("--force", "Overwrite existing configuration").option("--dry-run", "Show what would be done without writing files").option("--json", "Output results as JSON (implies --yes)").option("--index", "Also register and index the current project").action(async (opts) => {
|
|
58623
58733
|
const nonInteractive = opts.yes || opts.json || opts.dryRun;
|
|
58734
|
+
let migrationStep;
|
|
58624
58735
|
if (!opts.dryRun) {
|
|
58625
58736
|
ensureGlobalDirs();
|
|
58737
|
+
const migration = migrateGlobalConfig();
|
|
58738
|
+
if (migration.changed) {
|
|
58739
|
+
migrationStep = {
|
|
58740
|
+
target: "~/.trace-mcp/.config.json",
|
|
58741
|
+
action: "updated",
|
|
58742
|
+
detail: `Config migrated \u2014 added: ${migration.added.join(", ")}`
|
|
58743
|
+
};
|
|
58744
|
+
}
|
|
58626
58745
|
}
|
|
58627
58746
|
const mcpClients = detectMcpClients();
|
|
58628
58747
|
const { hasGuardHook, guardHookVersion } = detectGuardHook();
|
|
@@ -58728,6 +58847,7 @@ var initCommand = new Command("init").description("One-time global setup: config
|
|
|
58728
58847
|
fixConflicts = true;
|
|
58729
58848
|
}
|
|
58730
58849
|
const steps = [];
|
|
58850
|
+
if (migrationStep) steps.push(migrationStep);
|
|
58731
58851
|
if (!nonInteractive) {
|
|
58732
58852
|
const spin = p.spinner();
|
|
58733
58853
|
spin.start("Setting up trace-mcp");
|
|
@@ -58808,7 +58928,7 @@ var initCommand = new Command("init").description("One-time global setup: config
|
|
|
58808
58928
|
const spin = !nonInteractive ? p.spinner() : null;
|
|
58809
58929
|
spin?.start("Upgrading registered projects");
|
|
58810
58930
|
for (const proj of existingProjects) {
|
|
58811
|
-
if (!
|
|
58931
|
+
if (!fs90.existsSync(proj.root)) {
|
|
58812
58932
|
steps.push({ target: proj.root, action: "skipped", detail: "Directory not found (stale)" });
|
|
58813
58933
|
continue;
|
|
58814
58934
|
}
|
|
@@ -58945,11 +59065,11 @@ async function registerAndIndexProject(dir, opts) {
|
|
|
58945
59065
|
}
|
|
58946
59066
|
const detection = detectProject(projectRoot);
|
|
58947
59067
|
const config = generateConfig(detection);
|
|
58948
|
-
|
|
59068
|
+
saveProjectConfigJsonc(projectRoot, { root: config.root, include: config.include, exclude: config.exclude });
|
|
58949
59069
|
const dbPath = getDbPath(projectRoot);
|
|
58950
59070
|
const oldDbPath = path102.join(projectRoot, ".trace-mcp", "index.db");
|
|
58951
|
-
if (
|
|
58952
|
-
|
|
59071
|
+
if (fs90.existsSync(oldDbPath) && !fs90.existsSync(dbPath)) {
|
|
59072
|
+
fs90.copyFileSync(oldDbPath, dbPath);
|
|
58953
59073
|
}
|
|
58954
59074
|
const db = initializeDatabase(dbPath);
|
|
58955
59075
|
db.close();
|
|
@@ -58987,12 +59107,12 @@ async function registerMultiRootProject(parentDir, childRoots, opts) {
|
|
|
58987
59107
|
const parentPrefix = parentDir + path102.sep;
|
|
58988
59108
|
for (const proj of allProjects) {
|
|
58989
59109
|
if (proj.root !== parentDir && proj.root.startsWith(parentPrefix)) {
|
|
58990
|
-
if (
|
|
59110
|
+
if (fs90.existsSync(proj.dbPath)) fs90.unlinkSync(proj.dbPath);
|
|
58991
59111
|
unregisterProject(proj.root);
|
|
58992
|
-
|
|
59112
|
+
removeProjectConfigJsonc(proj.root);
|
|
58993
59113
|
}
|
|
58994
59114
|
}
|
|
58995
|
-
|
|
59115
|
+
saveProjectConfigJsonc(parentDir, {
|
|
58996
59116
|
root: ".",
|
|
58997
59117
|
include: allInclude,
|
|
58998
59118
|
exclude: allExclude,
|
|
@@ -59031,7 +59151,7 @@ function shortPath3(p5) {
|
|
|
59031
59151
|
|
|
59032
59152
|
// src/cli/upgrade.ts
|
|
59033
59153
|
import { Command as Command2 } from "commander";
|
|
59034
|
-
import
|
|
59154
|
+
import fs91 from "fs";
|
|
59035
59155
|
import path103 from "path";
|
|
59036
59156
|
var upgradeCommand = new Command2("upgrade").description("Upgrade trace-mcp: run DB migrations, reindex with latest plugins, update hooks and CLAUDE.md").argument("[dir]", "Project directory (omit to upgrade all registered projects)").option("--skip-hooks", "Do not update guard hooks").option("--skip-reindex", "Do not trigger reindex").option("--skip-claude-md", "Do not update CLAUDE.md block").option("--dry-run", "Show what would be done without writing files").option("--json", "Output results as JSON").action(async (dir, opts) => {
|
|
59037
59157
|
const projectRoots = [];
|
|
@@ -59044,7 +59164,7 @@ var upgradeCommand = new Command2("upgrade").description("Upgrade trace-mcp: run
|
|
|
59044
59164
|
process.exit(1);
|
|
59045
59165
|
}
|
|
59046
59166
|
for (const p5 of projects) {
|
|
59047
|
-
if (
|
|
59167
|
+
if (fs91.existsSync(p5.root)) {
|
|
59048
59168
|
projectRoots.push(p5.root);
|
|
59049
59169
|
} else {
|
|
59050
59170
|
logger.warn({ root: p5.root }, "Skipping stale project (directory not found)");
|
|
@@ -59138,7 +59258,7 @@ var upgradeCommand = new Command2("upgrade").description("Upgrade trace-mcp: run
|
|
|
59138
59258
|
|
|
59139
59259
|
// src/cli/add.ts
|
|
59140
59260
|
import { Command as Command3 } from "commander";
|
|
59141
|
-
import
|
|
59261
|
+
import fs92 from "fs";
|
|
59142
59262
|
import path104 from "path";
|
|
59143
59263
|
import * as p2 from "@clack/prompts";
|
|
59144
59264
|
async function runIndexing(projectRoot, opts) {
|
|
@@ -59175,7 +59295,7 @@ function formatDuration2(ms) {
|
|
|
59175
59295
|
}
|
|
59176
59296
|
var addCommand = new Command3("add").description("Register a project for indexing: detect root, create DB, add to registry").argument("[dir]", "Project directory (default: current directory)", ".").option("--force", "Re-register even if already registered").option("--no-index", "Skip indexing after registration").option("--json", "Output results as JSON").action(async (dir, opts) => {
|
|
59177
59297
|
const resolvedDir = path104.resolve(dir);
|
|
59178
|
-
if (!
|
|
59298
|
+
if (!fs92.existsSync(resolvedDir)) {
|
|
59179
59299
|
console.error(`Directory does not exist: ${resolvedDir}`);
|
|
59180
59300
|
process.exit(1);
|
|
59181
59301
|
}
|
|
@@ -59248,12 +59368,12 @@ DB: ${shortPath4(existing.dbPath)}`, "Existing");
|
|
|
59248
59368
|
exclude: config.exclude
|
|
59249
59369
|
};
|
|
59250
59370
|
ensureGlobalDirs();
|
|
59251
|
-
|
|
59371
|
+
saveProjectConfigJsonc(projectRoot, configForSave);
|
|
59252
59372
|
const dbPath = getDbPath(projectRoot);
|
|
59253
59373
|
const oldDbPath = path104.join(projectRoot, ".trace-mcp", "index.db");
|
|
59254
59374
|
let migrated = false;
|
|
59255
|
-
if (
|
|
59256
|
-
|
|
59375
|
+
if (fs92.existsSync(oldDbPath) && !fs92.existsSync(dbPath)) {
|
|
59376
|
+
fs92.copyFileSync(oldDbPath, dbPath);
|
|
59257
59377
|
migrated = true;
|
|
59258
59378
|
}
|
|
59259
59379
|
const db = initializeDatabase(dbPath);
|
|
@@ -59359,11 +59479,11 @@ Discovered ${childRoots.length} child project(s):
|
|
|
59359
59479
|
const cleaned = [];
|
|
59360
59480
|
for (const proj of allProjects) {
|
|
59361
59481
|
if (proj.root.startsWith(parentDir + path104.sep) || proj.root.startsWith(parentDir + "/")) {
|
|
59362
|
-
if (
|
|
59363
|
-
|
|
59482
|
+
if (fs92.existsSync(proj.dbPath)) {
|
|
59483
|
+
fs92.unlinkSync(proj.dbPath);
|
|
59364
59484
|
}
|
|
59365
59485
|
unregisterProject(proj.root);
|
|
59366
|
-
|
|
59486
|
+
removeProjectConfigJsonc(proj.root);
|
|
59367
59487
|
cleaned.push(path104.basename(proj.root));
|
|
59368
59488
|
}
|
|
59369
59489
|
}
|
|
@@ -59377,7 +59497,7 @@ Discovered ${childRoots.length} child project(s):
|
|
|
59377
59497
|
exclude: mergedExclude,
|
|
59378
59498
|
children: childRoots
|
|
59379
59499
|
};
|
|
59380
|
-
|
|
59500
|
+
saveProjectConfigJsonc(parentDir, configForSave);
|
|
59381
59501
|
const dbPath = getDbPath(parentDir);
|
|
59382
59502
|
const db = initializeDatabase(dbPath);
|
|
59383
59503
|
db.close();
|
|
@@ -59574,7 +59694,7 @@ function shortPath5(p5) {
|
|
|
59574
59694
|
import { Command as Command5 } from "commander";
|
|
59575
59695
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
59576
59696
|
import path105 from "path";
|
|
59577
|
-
import
|
|
59697
|
+
import fs93 from "fs";
|
|
59578
59698
|
|
|
59579
59699
|
// src/ci/report-generator.ts
|
|
59580
59700
|
init_graph_analysis();
|
|
@@ -59985,15 +60105,15 @@ function writeOutput(outputPath, content) {
|
|
|
59985
60105
|
process.stdout.write(content + "\n");
|
|
59986
60106
|
} else {
|
|
59987
60107
|
const resolved = path105.resolve(outputPath);
|
|
59988
|
-
|
|
59989
|
-
|
|
60108
|
+
fs93.mkdirSync(path105.dirname(resolved), { recursive: true });
|
|
60109
|
+
fs93.writeFileSync(resolved, content, "utf-8");
|
|
59990
60110
|
logger.info({ path: resolved }, "CI report written");
|
|
59991
60111
|
}
|
|
59992
60112
|
}
|
|
59993
60113
|
|
|
59994
60114
|
// src/cli/check.ts
|
|
59995
60115
|
import { Command as Command6 } from "commander";
|
|
59996
|
-
import
|
|
60116
|
+
import fs94 from "fs";
|
|
59997
60117
|
function resolveDbPath2(projectRoot) {
|
|
59998
60118
|
const entry = getProject(projectRoot);
|
|
59999
60119
|
if (entry) return entry.dbPath;
|
|
@@ -60017,7 +60137,7 @@ var checkCommand = new Command6("check").description("Run quality gate checks ag
|
|
|
60017
60137
|
let gatesConfig;
|
|
60018
60138
|
if (opts.config) {
|
|
60019
60139
|
try {
|
|
60020
|
-
const raw = JSON.parse(
|
|
60140
|
+
const raw = JSON.parse(fs94.readFileSync(opts.config, "utf-8"));
|
|
60021
60141
|
const parsed = QualityGatesConfigSchema2.safeParse(raw.quality_gates ?? raw);
|
|
60022
60142
|
if (!parsed.success) {
|
|
60023
60143
|
console.error(`Invalid quality gates config: ${parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ")}`);
|
|
@@ -60540,7 +60660,7 @@ analyticsCommand.command("trends").description("Show daily usage trends: tokens,
|
|
|
60540
60660
|
|
|
60541
60661
|
// src/cli/remove.ts
|
|
60542
60662
|
import { Command as Command10 } from "commander";
|
|
60543
|
-
import
|
|
60663
|
+
import fs95 from "fs";
|
|
60544
60664
|
import path106 from "path";
|
|
60545
60665
|
import * as p4 from "@clack/prompts";
|
|
60546
60666
|
var removeCommand = new Command10("remove").description("Unregister a project and delete its index").argument("[dir]", "Project directory (default: current directory)", ".").option("--force", "Remove without confirmation").option("--keep-db", "Keep the database file (only unregister)").option("--json", "Output results as JSON").action(async (dir, opts) => {
|
|
@@ -60590,11 +60710,11 @@ var removeCommand = new Command10("remove").description("Unregister a project an
|
|
|
60590
60710
|
}
|
|
60591
60711
|
}
|
|
60592
60712
|
let dbDeleted = false;
|
|
60593
|
-
if (!opts.keepDb &&
|
|
60594
|
-
|
|
60713
|
+
if (!opts.keepDb && fs95.existsSync(entry.dbPath)) {
|
|
60714
|
+
fs95.unlinkSync(entry.dbPath);
|
|
60595
60715
|
dbDeleted = true;
|
|
60596
60716
|
}
|
|
60597
|
-
|
|
60717
|
+
removeProjectConfigJsonc(entry.root);
|
|
60598
60718
|
unregisterProject(entry.root);
|
|
60599
60719
|
if (opts.json) {
|
|
60600
60720
|
console.log(JSON.stringify({
|
|
@@ -60640,10 +60760,10 @@ Child to exclude: ${path106.basename(childRoot)}`,
|
|
|
60640
60760
|
const currentChildren = parent.children ?? [];
|
|
60641
60761
|
const newChildren = currentChildren.filter((c) => path106.resolve(c) !== path106.resolve(childRoot));
|
|
60642
60762
|
if (newChildren.length === 0) {
|
|
60643
|
-
if (!opts.keepDb &&
|
|
60644
|
-
|
|
60763
|
+
if (!opts.keepDb && fs95.existsSync(parent.dbPath)) {
|
|
60764
|
+
fs95.unlinkSync(parent.dbPath);
|
|
60645
60765
|
}
|
|
60646
|
-
|
|
60766
|
+
removeProjectConfigJsonc(parent.root);
|
|
60647
60767
|
unregisterProject(parent.root);
|
|
60648
60768
|
if (opts.json) {
|
|
60649
60769
|
console.log(JSON.stringify({
|
|
@@ -60659,10 +60779,10 @@ Child to exclude: ${path106.basename(childRoot)}`,
|
|
|
60659
60779
|
}
|
|
60660
60780
|
if (newChildren.length === 1) {
|
|
60661
60781
|
const remainingChild = newChildren[0];
|
|
60662
|
-
if (!opts.keepDb &&
|
|
60663
|
-
|
|
60782
|
+
if (!opts.keepDb && fs95.existsSync(parent.dbPath)) {
|
|
60783
|
+
fs95.unlinkSync(parent.dbPath);
|
|
60664
60784
|
}
|
|
60665
|
-
|
|
60785
|
+
removeProjectConfigJsonc(parent.root);
|
|
60666
60786
|
unregisterProject(parent.root);
|
|
60667
60787
|
if (opts.json) {
|
|
60668
60788
|
console.log(JSON.stringify({
|
|
@@ -60682,10 +60802,10 @@ Multi-root removed. Run \`trace-mcp add ${remainingChild}\` to re-register indiv
|
|
|
60682
60802
|
}
|
|
60683
60803
|
return;
|
|
60684
60804
|
}
|
|
60685
|
-
if (!opts.keepDb &&
|
|
60686
|
-
|
|
60805
|
+
if (!opts.keepDb && fs95.existsSync(parent.dbPath)) {
|
|
60806
|
+
fs95.unlinkSync(parent.dbPath);
|
|
60687
60807
|
}
|
|
60688
|
-
|
|
60808
|
+
removeProjectConfigJsonc(parent.root);
|
|
60689
60809
|
unregisterProject(parent.root);
|
|
60690
60810
|
if (opts.json) {
|
|
60691
60811
|
console.log(JSON.stringify({
|
|
@@ -60712,7 +60832,7 @@ function shortPath6(p5) {
|
|
|
60712
60832
|
|
|
60713
60833
|
// src/cli/status.ts
|
|
60714
60834
|
import { Command as Command11 } from "commander";
|
|
60715
|
-
import
|
|
60835
|
+
import fs96 from "fs";
|
|
60716
60836
|
import Database7 from "better-sqlite3";
|
|
60717
60837
|
function resolveDbPath5(projectRoot) {
|
|
60718
60838
|
const entry = getProject(projectRoot);
|
|
@@ -60757,7 +60877,7 @@ var statusCommand = new Command11("status").description("Show indexing progress
|
|
|
60757
60877
|
projectRoot = process.cwd();
|
|
60758
60878
|
}
|
|
60759
60879
|
const dbPath = resolveDbPath5(projectRoot);
|
|
60760
|
-
if (!
|
|
60880
|
+
if (!fs96.existsSync(dbPath)) {
|
|
60761
60881
|
console.log(`No index found for ${projectRoot}`);
|
|
60762
60882
|
console.log("Run `trace-mcp serve` or `trace-mcp index` first.");
|
|
60763
60883
|
process.exit(1);
|
|
@@ -60795,7 +60915,7 @@ trace-mcp status \u2014 ${projectRoot}
|
|
|
60795
60915
|
});
|
|
60796
60916
|
|
|
60797
60917
|
// src/cli.ts
|
|
60798
|
-
var PKG_VERSION2 = true ? "1.
|
|
60918
|
+
var PKG_VERSION2 = true ? "1.8.0" : "0.0.0-dev";
|
|
60799
60919
|
function registerDefaultPlugins(registry) {
|
|
60800
60920
|
for (const p5 of createAllLanguagePlugins()) registry.registerLanguagePlugin(p5);
|
|
60801
60921
|
for (const p5 of createAllIntegrationPlugins()) registry.registerFrameworkPlugin(p5);
|
|
@@ -61082,7 +61202,7 @@ program.command("serve-http").description("Start MCP server (HTTP/SSE transport)
|
|
|
61082
61202
|
});
|
|
61083
61203
|
program.command("index").description("Index a project directory").argument("<dir>", "Directory to index").option("-f, --force", "Force reindex all files").action(async (dir, opts) => {
|
|
61084
61204
|
const resolvedDir = path107.resolve(dir);
|
|
61085
|
-
if (!
|
|
61205
|
+
if (!fs97.existsSync(resolvedDir)) {
|
|
61086
61206
|
logger.error({ dir: resolvedDir }, "Directory does not exist");
|
|
61087
61207
|
process.exit(1);
|
|
61088
61208
|
}
|
|
@@ -61107,7 +61227,7 @@ program.command("index").description("Index a project directory").argument("<dir
|
|
|
61107
61227
|
});
|
|
61108
61228
|
program.command("index-file").description("Incrementally reindex a single file (called by the PostToolUse auto-reindex hook)").argument("<file>", "Absolute or relative path to the file to reindex").action(async (file) => {
|
|
61109
61229
|
const resolvedFile = path107.resolve(file);
|
|
61110
|
-
if (!
|
|
61230
|
+
if (!fs97.existsSync(resolvedFile)) {
|
|
61111
61231
|
process.exit(0);
|
|
61112
61232
|
}
|
|
61113
61233
|
let projectRoot;
|
|
@@ -61149,7 +61269,7 @@ program.command("list").description("List all registered projects").option("--js
|
|
|
61149
61269
|
console.log("Registered projects:\n");
|
|
61150
61270
|
for (const p5 of projects) {
|
|
61151
61271
|
const lastIdx = p5.lastIndexed ? new Date(p5.lastIndexed).toLocaleString() : "never";
|
|
61152
|
-
const dbExists =
|
|
61272
|
+
const dbExists = fs97.existsSync(p5.dbPath) ? "ok" : "missing";
|
|
61153
61273
|
console.log(` ${p5.name}`);
|
|
61154
61274
|
console.log(` Root: ${p5.root}`);
|
|
61155
61275
|
console.log(` DB: ${dbExists}`);
|