trace-mcp 1.19.0 → 1.20.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/dist/cli.js +412 -36
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +310 -34
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1365,6 +1365,11 @@ var init_symbol_repository = __esm({
|
|
|
1365
1365
|
getSymbolById(id) {
|
|
1366
1366
|
return this._stmts.getSymbolById.get(id);
|
|
1367
1367
|
}
|
|
1368
|
+
getSymbolChildren(parentId) {
|
|
1369
|
+
return this.db.prepare(
|
|
1370
|
+
"SELECT * FROM symbols WHERE parent_id = ?"
|
|
1371
|
+
).all(parentId);
|
|
1372
|
+
}
|
|
1368
1373
|
getSymbolByName(name, kind) {
|
|
1369
1374
|
if (kind) {
|
|
1370
1375
|
return this.db.prepare(
|
|
@@ -2228,6 +2233,9 @@ var init_store = __esm({
|
|
|
2228
2233
|
getSymbolByName(name, kind) {
|
|
2229
2234
|
return this.symbols.getSymbolByName(name, kind);
|
|
2230
2235
|
}
|
|
2236
|
+
getSymbolChildren(parentId) {
|
|
2237
|
+
return this.symbols.getSymbolChildren(parentId);
|
|
2238
|
+
}
|
|
2231
2239
|
getExportedSymbols(filePattern) {
|
|
2232
2240
|
return this.symbols.getExportedSymbols(filePattern);
|
|
2233
2241
|
}
|
|
@@ -5428,6 +5436,44 @@ function extractInheritanceEdges(bases, classSymbolId) {
|
|
|
5428
5436
|
metadata: { base }
|
|
5429
5437
|
}));
|
|
5430
5438
|
}
|
|
5439
|
+
function extractNameMainCallees(root) {
|
|
5440
|
+
const callees = [];
|
|
5441
|
+
for (const node of root.namedChildren) {
|
|
5442
|
+
if (node.type !== "if_statement") continue;
|
|
5443
|
+
const condition = node.childForFieldName("condition");
|
|
5444
|
+
if (!condition) continue;
|
|
5445
|
+
if (!isNameMainCondition(condition)) continue;
|
|
5446
|
+
const body = node.childForFieldName("consequence");
|
|
5447
|
+
if (!body) continue;
|
|
5448
|
+
collectCalleeNames(body, callees);
|
|
5449
|
+
}
|
|
5450
|
+
return callees;
|
|
5451
|
+
}
|
|
5452
|
+
function isNameMainCondition(node) {
|
|
5453
|
+
if (node.type !== "comparison_operator") return false;
|
|
5454
|
+
const text = node.text;
|
|
5455
|
+
return text.includes("__name__") && (text.includes('"__main__"') || text.includes("'__main__'"));
|
|
5456
|
+
}
|
|
5457
|
+
function collectCalleeNames(node, out) {
|
|
5458
|
+
for (const child of node.namedChildren) {
|
|
5459
|
+
if (child.type === "expression_statement") {
|
|
5460
|
+
collectCalleeNames(child, out);
|
|
5461
|
+
} else if (child.type === "call") {
|
|
5462
|
+
const fn2 = child.childForFieldName("function");
|
|
5463
|
+
if (fn2) {
|
|
5464
|
+
if (fn2.type === "identifier") {
|
|
5465
|
+
out.push(fn2.text);
|
|
5466
|
+
}
|
|
5467
|
+
const args = child.childForFieldName("arguments");
|
|
5468
|
+
if (args) collectCalleeNames(args, out);
|
|
5469
|
+
}
|
|
5470
|
+
} else if (child.type === "function_definition" || child.type === "class_definition") {
|
|
5471
|
+
continue;
|
|
5472
|
+
} else {
|
|
5473
|
+
collectCalleeNames(child, out);
|
|
5474
|
+
}
|
|
5475
|
+
}
|
|
5476
|
+
}
|
|
5431
5477
|
function extractTypeCheckingImports(root) {
|
|
5432
5478
|
const edges = [];
|
|
5433
5479
|
for (const node of root.namedChildren) {
|
|
@@ -6132,6 +6178,29 @@ function extractIterableStrings(node) {
|
|
|
6132
6178
|
}
|
|
6133
6179
|
function inferLocalTypes(body) {
|
|
6134
6180
|
const types = /* @__PURE__ */ new Map();
|
|
6181
|
+
const funcDef = body.parent;
|
|
6182
|
+
if (funcDef && (funcDef.type === "function_definition" || funcDef.type === "decorated_definition")) {
|
|
6183
|
+
const defNode = funcDef.type === "decorated_definition" ? funcDef.namedChildren.find((c) => c.type === "function_definition") : funcDef;
|
|
6184
|
+
if (defNode) {
|
|
6185
|
+
const params = defNode.childForFieldName("parameters");
|
|
6186
|
+
if (params) {
|
|
6187
|
+
for (const param of params.namedChildren) {
|
|
6188
|
+
if (param.type === "typed_parameter" || param.type === "typed_default_parameter") {
|
|
6189
|
+
const nameNode = param.childForFieldName("name") ?? param.namedChildren.find((c) => c.type === "identifier");
|
|
6190
|
+
const typeNode = param.childForFieldName("type");
|
|
6191
|
+
if (nameNode && typeNode) {
|
|
6192
|
+
const paramName = nameNode.text;
|
|
6193
|
+
if (paramName === "self" || paramName === "cls") continue;
|
|
6194
|
+
const typeName = extractParamAnnotationType(typeNode);
|
|
6195
|
+
if (typeName) {
|
|
6196
|
+
types.set(paramName, { type: typeName });
|
|
6197
|
+
}
|
|
6198
|
+
}
|
|
6199
|
+
}
|
|
6200
|
+
}
|
|
6201
|
+
}
|
|
6202
|
+
}
|
|
6203
|
+
}
|
|
6135
6204
|
for (const child of body.namedChildren) {
|
|
6136
6205
|
if (child.type === "expression_statement") {
|
|
6137
6206
|
const expr = child.namedChildren[0];
|
|
@@ -6193,6 +6262,34 @@ function extractAnnotationType(typeNode) {
|
|
|
6193
6262
|
}
|
|
6194
6263
|
return null;
|
|
6195
6264
|
}
|
|
6265
|
+
function extractParamAnnotationType(typeNode) {
|
|
6266
|
+
if (typeNode.type === "type") {
|
|
6267
|
+
return extractAnnotationType(typeNode);
|
|
6268
|
+
}
|
|
6269
|
+
if (typeNode.type === "identifier") {
|
|
6270
|
+
const name = typeNode.text;
|
|
6271
|
+
if (name[0] >= "A" && name[0] <= "Z") return name;
|
|
6272
|
+
return null;
|
|
6273
|
+
}
|
|
6274
|
+
if (typeNode.type === "attribute") {
|
|
6275
|
+
const attr = typeNode.childForFieldName("attribute");
|
|
6276
|
+
if (attr && attr.text[0] >= "A" && attr.text[0] <= "Z") return attr.text;
|
|
6277
|
+
return null;
|
|
6278
|
+
}
|
|
6279
|
+
if (typeNode.type === "subscript" || typeNode.type === "generic_type") {
|
|
6280
|
+
for (const child of typeNode.namedChildren) {
|
|
6281
|
+
if (child.type === "identifier" && child.text[0] >= "A" && child.text[0] <= "Z") {
|
|
6282
|
+
const WRAPPER_TYPES = /* @__PURE__ */ new Set(["Optional", "List", "Set", "Dict", "Tuple", "Type", "Sequence", "Iterable"]);
|
|
6283
|
+
if (!WRAPPER_TYPES.has(child.text)) return child.text;
|
|
6284
|
+
}
|
|
6285
|
+
}
|
|
6286
|
+
for (const child of typeNode.namedChildren) {
|
|
6287
|
+
const inner = extractParamAnnotationType(child);
|
|
6288
|
+
if (inner) return inner;
|
|
6289
|
+
}
|
|
6290
|
+
}
|
|
6291
|
+
return extractAnnotationType(typeNode);
|
|
6292
|
+
}
|
|
6196
6293
|
function parseCallTarget(fn2, line, localTypes) {
|
|
6197
6294
|
if (fn2.type === "identifier") {
|
|
6198
6295
|
const name = fn2.text;
|
|
@@ -6447,6 +6544,17 @@ var init_python = __esm({
|
|
|
6447
6544
|
sym.metadata.exported = true;
|
|
6448
6545
|
}
|
|
6449
6546
|
}
|
|
6547
|
+
const nameMainCallees = extractNameMainCallees(root);
|
|
6548
|
+
if (nameMainCallees.length > 0) {
|
|
6549
|
+
const calleeSet = new Set(nameMainCallees);
|
|
6550
|
+
for (const sym of symbols) {
|
|
6551
|
+
if (sym.parentSymbolId) continue;
|
|
6552
|
+
if (calleeSet.has(sym.name)) {
|
|
6553
|
+
sym.metadata = sym.metadata ?? {};
|
|
6554
|
+
sym.metadata.is_entry_point = "name_main";
|
|
6555
|
+
}
|
|
6556
|
+
}
|
|
6557
|
+
}
|
|
6450
6558
|
const moduleLevelCalls = extractCallSites(root);
|
|
6451
6559
|
if (moduleLevelCalls.length > 0) {
|
|
6452
6560
|
const moduleSymbolId = makeSymbolId3(filePath, "<module>", "function");
|
|
@@ -42528,11 +42636,17 @@ function resolvePythonCallEdges(state) {
|
|
|
42528
42636
|
if (!targetSymbol) continue;
|
|
42529
42637
|
const targetNodeId = symbolNodeMap.get(targetSymbol.id);
|
|
42530
42638
|
if (targetNodeId == null || targetNodeId === sourceNodeId) continue;
|
|
42639
|
+
const edgeMeta = { callee: call.calleeName, line: call.line };
|
|
42640
|
+
if (call.receiverType) edgeMeta.receiver_type = call.receiverType;
|
|
42641
|
+
else if (call.receiverAssignedFrom) {
|
|
42642
|
+
const inferredType = returnTypeIndex.get(call.receiverAssignedFrom);
|
|
42643
|
+
if (inferredType) edgeMeta.receiver_type = inferredType;
|
|
42644
|
+
}
|
|
42531
42645
|
insertStmt.run(
|
|
42532
42646
|
sourceNodeId,
|
|
42533
42647
|
targetNodeId,
|
|
42534
42648
|
callsEdgeType.id,
|
|
42535
|
-
JSON.stringify(
|
|
42649
|
+
JSON.stringify(edgeMeta)
|
|
42536
42650
|
);
|
|
42537
42651
|
created++;
|
|
42538
42652
|
}
|
|
@@ -42737,6 +42851,13 @@ function resolveMethodOnClass(typeName, calleeName, fileSymbols, fileImports, na
|
|
|
42737
42851
|
}
|
|
42738
42852
|
}
|
|
42739
42853
|
}
|
|
42854
|
+
const methodCandidates = nameIndex.get(calleeName);
|
|
42855
|
+
if (methodCandidates) {
|
|
42856
|
+
const match = methodCandidates.find(
|
|
42857
|
+
(s) => (s.kind === "method" || s.kind === "function") && s.parent_symbol_id != null
|
|
42858
|
+
);
|
|
42859
|
+
if (match) return match;
|
|
42860
|
+
}
|
|
42740
42861
|
return null;
|
|
42741
42862
|
}
|
|
42742
42863
|
function buildFileImportMap(state) {
|
|
@@ -42876,6 +42997,10 @@ function resolveTestCoversEdges(state) {
|
|
|
42876
42997
|
const targetRefs = store.getNodeRefsBatch(targetNodeIds);
|
|
42877
42998
|
const targetFileRefIds = [...targetRefs.values()].filter((r) => r.nodeType === "file").map((r) => r.refId);
|
|
42878
42999
|
const targetFileMap = store.getFilesByIds(targetFileRefIds);
|
|
43000
|
+
const targetSymbolRefIds = [...targetRefs.values()].filter((r) => r.nodeType === "symbol").map((r) => r.refId);
|
|
43001
|
+
const targetSymbolMap = store.getSymbolsByIds(targetSymbolRefIds);
|
|
43002
|
+
const symbolFileIds = [...new Set([...targetSymbolMap.values()].map((s) => s.file_id))];
|
|
43003
|
+
const symbolFileMap = store.getFilesByIds(symbolFileIds);
|
|
42879
43004
|
const testCoversType = store.db.prepare("SELECT id FROM edge_types WHERE name = ?").get("test_covers");
|
|
42880
43005
|
if (!testCoversType) return;
|
|
42881
43006
|
let created = 0;
|
|
@@ -42890,18 +43015,32 @@ function resolveTestCoversEdges(state) {
|
|
|
42890
43015
|
if (edge.edge_type_name !== "imports") continue;
|
|
42891
43016
|
if (!testNodeToFile.has(edge.source_node_id)) continue;
|
|
42892
43017
|
const targetRef = targetRefs.get(edge.target_node_id);
|
|
42893
|
-
if (!targetRef
|
|
42894
|
-
const targetFile = targetFileMap.get(targetRef.refId);
|
|
42895
|
-
if (!targetFile) continue;
|
|
42896
|
-
if (TEST_PATH_RE.test(targetFile.path)) continue;
|
|
43018
|
+
if (!targetRef) continue;
|
|
42897
43019
|
const testFile = testNodeToFile.get(edge.source_node_id);
|
|
42898
|
-
|
|
42899
|
-
|
|
42900
|
-
|
|
42901
|
-
|
|
42902
|
-
|
|
42903
|
-
|
|
42904
|
-
|
|
43020
|
+
if (targetRef.nodeType === "file") {
|
|
43021
|
+
const targetFile = targetFileMap.get(targetRef.refId);
|
|
43022
|
+
if (!targetFile) continue;
|
|
43023
|
+
if (TEST_PATH_RE.test(targetFile.path)) continue;
|
|
43024
|
+
insertStmt.run(
|
|
43025
|
+
edge.source_node_id,
|
|
43026
|
+
edge.target_node_id,
|
|
43027
|
+
testCoversType.id,
|
|
43028
|
+
JSON.stringify({ test_file: testFile.path })
|
|
43029
|
+
);
|
|
43030
|
+
created++;
|
|
43031
|
+
} else if (targetRef.nodeType === "symbol") {
|
|
43032
|
+
const targetSymbol = targetSymbolMap.get(targetRef.refId);
|
|
43033
|
+
if (!targetSymbol) continue;
|
|
43034
|
+
const parentFile = symbolFileMap.get(targetSymbol.file_id);
|
|
43035
|
+
if (!parentFile || TEST_PATH_RE.test(parentFile.path)) continue;
|
|
43036
|
+
insertStmt.run(
|
|
43037
|
+
edge.source_node_id,
|
|
43038
|
+
edge.target_node_id,
|
|
43039
|
+
testCoversType.id,
|
|
43040
|
+
JSON.stringify({ test_file: testFile.path, target_symbol: targetSymbol.symbol_id })
|
|
43041
|
+
);
|
|
43042
|
+
created++;
|
|
43043
|
+
}
|
|
42905
43044
|
}
|
|
42906
43045
|
})();
|
|
42907
43046
|
if (created > 0) {
|
|
@@ -89601,7 +89740,7 @@ import https from "https";
|
|
|
89601
89740
|
import { spawnSync } from "child_process";
|
|
89602
89741
|
import path65 from "path";
|
|
89603
89742
|
import fs66 from "fs";
|
|
89604
|
-
var CURRENT_VERSION = true ? "1.
|
|
89743
|
+
var CURRENT_VERSION = true ? "1.20.0" : "0.0.0-dev";
|
|
89605
89744
|
var UPDATE_CACHE_PATH = path65.join(TRACE_MCP_HOME, "update-check.json");
|
|
89606
89745
|
function readCache() {
|
|
89607
89746
|
try {
|
|
@@ -93266,6 +93405,119 @@ function resolveSymbolInput(store, opts) {
|
|
|
93266
93405
|
return { symbol: sym, file, resolved_via: resolvedVia };
|
|
93267
93406
|
}
|
|
93268
93407
|
|
|
93408
|
+
// src/tools/shared/cha.ts
|
|
93409
|
+
var HERITAGE_EDGE_TYPES = [
|
|
93410
|
+
"ts_extends",
|
|
93411
|
+
"ts_implements",
|
|
93412
|
+
// TypeScript
|
|
93413
|
+
"extends",
|
|
93414
|
+
"implements",
|
|
93415
|
+
// PHP
|
|
93416
|
+
"py_inherits"
|
|
93417
|
+
// Python (fallback)
|
|
93418
|
+
];
|
|
93419
|
+
function expandMethodViaCha(store, symbol, maxDepth = 10) {
|
|
93420
|
+
if (symbol.kind !== "method") {
|
|
93421
|
+
const nodeId = store.getNodeId("symbol", symbol.id);
|
|
93422
|
+
if (nodeId == null) return [];
|
|
93423
|
+
return [{ symbol, nodeId, relation: "self" }];
|
|
93424
|
+
}
|
|
93425
|
+
const methodName = symbol.name;
|
|
93426
|
+
const parentClass = symbol.parent_id != null ? store.getSymbolById(symbol.parent_id) : null;
|
|
93427
|
+
if (!parentClass || parentClass.kind !== "class" && parentClass.kind !== "interface") {
|
|
93428
|
+
const nodeId = store.getNodeId("symbol", symbol.id);
|
|
93429
|
+
if (nodeId == null) return [];
|
|
93430
|
+
return [{ symbol, nodeId, relation: "self" }];
|
|
93431
|
+
}
|
|
93432
|
+
const results = [];
|
|
93433
|
+
const selfNodeId = store.getNodeId("symbol", symbol.id);
|
|
93434
|
+
if (selfNodeId != null) {
|
|
93435
|
+
results.push({ symbol, nodeId: selfNodeId, relation: "self" });
|
|
93436
|
+
}
|
|
93437
|
+
const ancestorClassIds = /* @__PURE__ */ new Set();
|
|
93438
|
+
const descendantClassIds = /* @__PURE__ */ new Set();
|
|
93439
|
+
collectAncestors(store, parentClass, ancestorClassIds, /* @__PURE__ */ new Set(), maxDepth);
|
|
93440
|
+
collectDescendants(store, parentClass.name, descendantClassIds, /* @__PURE__ */ new Set(), maxDepth);
|
|
93441
|
+
for (const classId of ancestorClassIds) {
|
|
93442
|
+
const method = findMethodOnClass(store, classId, methodName);
|
|
93443
|
+
if (method && method.id !== symbol.id) {
|
|
93444
|
+
const nodeId = store.getNodeId("symbol", method.id);
|
|
93445
|
+
if (nodeId != null) {
|
|
93446
|
+
results.push({ symbol: method, nodeId, relation: "ancestor_method" });
|
|
93447
|
+
}
|
|
93448
|
+
}
|
|
93449
|
+
}
|
|
93450
|
+
for (const classId of descendantClassIds) {
|
|
93451
|
+
const method = findMethodOnClass(store, classId, methodName);
|
|
93452
|
+
if (method && method.id !== symbol.id) {
|
|
93453
|
+
const nodeId = store.getNodeId("symbol", method.id);
|
|
93454
|
+
if (nodeId != null) {
|
|
93455
|
+
results.push({ symbol: method, nodeId, relation: "descendant_method" });
|
|
93456
|
+
}
|
|
93457
|
+
}
|
|
93458
|
+
}
|
|
93459
|
+
return results;
|
|
93460
|
+
}
|
|
93461
|
+
function getChaNodeIds(store, symbol) {
|
|
93462
|
+
return expandMethodViaCha(store, symbol).map((m) => m.nodeId);
|
|
93463
|
+
}
|
|
93464
|
+
function collectAncestors(store, classSymbol, result, visited, depth) {
|
|
93465
|
+
if (depth <= 0 || visited.has(classSymbol.id)) return;
|
|
93466
|
+
visited.add(classSymbol.id);
|
|
93467
|
+
const nodeId = store.getNodeId("symbol", classSymbol.id);
|
|
93468
|
+
if (nodeId != null) {
|
|
93469
|
+
const outgoing = store.getOutgoingEdges(nodeId);
|
|
93470
|
+
for (const edge of outgoing) {
|
|
93471
|
+
if (!HERITAGE_EDGE_TYPES.includes(edge.edge_type_name)) continue;
|
|
93472
|
+
const targetRef = store.getNodeRef(edge.target_node_id);
|
|
93473
|
+
if (!targetRef || targetRef.nodeType !== "symbol") continue;
|
|
93474
|
+
result.add(targetRef.refId);
|
|
93475
|
+
const parentSym = store.getSymbolById(targetRef.refId);
|
|
93476
|
+
if (parentSym) {
|
|
93477
|
+
collectAncestors(store, parentSym, result, visited, depth - 1);
|
|
93478
|
+
}
|
|
93479
|
+
}
|
|
93480
|
+
}
|
|
93481
|
+
if (classSymbol.metadata) {
|
|
93482
|
+
try {
|
|
93483
|
+
const meta = JSON.parse(classSymbol.metadata);
|
|
93484
|
+
const parentNames = [];
|
|
93485
|
+
const ext = meta["extends"];
|
|
93486
|
+
if (Array.isArray(ext)) parentNames.push(...ext.filter((n) => typeof n === "string"));
|
|
93487
|
+
else if (typeof ext === "string") parentNames.push(ext);
|
|
93488
|
+
const impl = meta["implements"];
|
|
93489
|
+
if (Array.isArray(impl)) parentNames.push(...impl.filter((n) => typeof n === "string"));
|
|
93490
|
+
const bases = meta["bases"];
|
|
93491
|
+
if (Array.isArray(bases)) parentNames.push(...bases.filter((n) => typeof n === "string"));
|
|
93492
|
+
for (const name of parentNames) {
|
|
93493
|
+
const shortName3 = name.includes(".") ? name.split(".").pop() : name;
|
|
93494
|
+
const parentSym = store.getSymbolByName(shortName3, "class") ?? store.getSymbolByName(shortName3, "interface");
|
|
93495
|
+
if (parentSym && !result.has(parentSym.id)) {
|
|
93496
|
+
result.add(parentSym.id);
|
|
93497
|
+
collectAncestors(store, parentSym, result, visited, depth - 1);
|
|
93498
|
+
}
|
|
93499
|
+
}
|
|
93500
|
+
} catch {
|
|
93501
|
+
}
|
|
93502
|
+
}
|
|
93503
|
+
}
|
|
93504
|
+
function collectDescendants(store, className, result, visited, depth) {
|
|
93505
|
+
if (depth <= 0 || visited.has(className)) return;
|
|
93506
|
+
visited.add(className);
|
|
93507
|
+
const implementors = store.findImplementors(className);
|
|
93508
|
+
for (const impl of implementors) {
|
|
93509
|
+
if (result.has(impl.id)) continue;
|
|
93510
|
+
result.add(impl.id);
|
|
93511
|
+
collectDescendants(store, impl.name, result, visited, depth - 1);
|
|
93512
|
+
}
|
|
93513
|
+
}
|
|
93514
|
+
function findMethodOnClass(store, classId, methodName) {
|
|
93515
|
+
const children = store.getSymbolChildren(classId);
|
|
93516
|
+
return children.find(
|
|
93517
|
+
(s) => s.name === methodName && (s.kind === "method" || s.kind === "function")
|
|
93518
|
+
) ?? null;
|
|
93519
|
+
}
|
|
93520
|
+
|
|
93269
93521
|
// src/tools/analysis/impact.ts
|
|
93270
93522
|
function getModule(filePath, depth = 2) {
|
|
93271
93523
|
const parts = filePath.split("/");
|
|
@@ -93422,8 +93674,13 @@ function getChangeImpact(store, opts, depth = 3, maxDependents = 200, cwd) {
|
|
|
93422
93674
|
const sym = store.getSymbolBySymbolId(sid);
|
|
93423
93675
|
if (!sym) continue;
|
|
93424
93676
|
if (!firstSym) firstSym = sym;
|
|
93425
|
-
const
|
|
93426
|
-
if (
|
|
93677
|
+
const chaNodeIds = getChaNodeIds(store, sym);
|
|
93678
|
+
if (chaNodeIds.length > 0) {
|
|
93679
|
+
startNodeIds.push(...chaNodeIds);
|
|
93680
|
+
} else {
|
|
93681
|
+
const nid = store.getNodeId("symbol", sym.id);
|
|
93682
|
+
if (nid != null) startNodeIds.push(nid);
|
|
93683
|
+
}
|
|
93427
93684
|
}
|
|
93428
93685
|
if (!firstSym) {
|
|
93429
93686
|
return err(notFound(opts.symbolIds[0]));
|
|
@@ -93440,8 +93697,14 @@ function getChangeImpact(store, opts, depth = 3, maxDependents = 200, cwd) {
|
|
|
93440
93697
|
return err(notFound(opts.symbolId ?? opts.fqn ?? "unknown"));
|
|
93441
93698
|
}
|
|
93442
93699
|
const sym = resolved.symbol;
|
|
93443
|
-
const
|
|
93444
|
-
if (
|
|
93700
|
+
const chaNodeIds = getChaNodeIds(store, sym);
|
|
93701
|
+
if (chaNodeIds.length > 0) {
|
|
93702
|
+
startNodeIds.push(...chaNodeIds);
|
|
93703
|
+
} else {
|
|
93704
|
+
const nodeId = store.getNodeId("symbol", sym.id);
|
|
93705
|
+
if (nodeId != null) startNodeIds.push(nodeId);
|
|
93706
|
+
}
|
|
93707
|
+
startNodeIds = [...new Set(startNodeIds)];
|
|
93445
93708
|
targetPath = resolved.file.path;
|
|
93446
93709
|
targetSymbolId = sym.symbol_id;
|
|
93447
93710
|
targetSymbolName = sym.name;
|
|
@@ -98470,8 +98733,41 @@ function findReferences(store, opts) {
|
|
|
98470
98733
|
if (nodeId === void 0) {
|
|
98471
98734
|
return ok65({ target: targetMeta, references: [], total: 0 });
|
|
98472
98735
|
}
|
|
98473
|
-
|
|
98474
|
-
|
|
98736
|
+
let chaExpansion;
|
|
98737
|
+
let allTargetNodeIds = [nodeId];
|
|
98738
|
+
if (opts.symbolId || opts.fqn) {
|
|
98739
|
+
const resolved = resolveSymbolInput(store, opts);
|
|
98740
|
+
if (resolved) {
|
|
98741
|
+
const chaMatches = expandMethodViaCha(store, resolved.symbol);
|
|
98742
|
+
if (chaMatches.length > 1) {
|
|
98743
|
+
allTargetNodeIds = chaMatches.map((m) => m.nodeId);
|
|
98744
|
+
chaExpansion = chaMatches.filter((m) => m.relation !== "self").map((m) => ({
|
|
98745
|
+
symbol_id: m.symbol.symbol_id,
|
|
98746
|
+
name: m.symbol.name,
|
|
98747
|
+
relation: m.relation
|
|
98748
|
+
}));
|
|
98749
|
+
}
|
|
98750
|
+
}
|
|
98751
|
+
}
|
|
98752
|
+
const allIncomingEdges = [];
|
|
98753
|
+
const seenEdgeKeys = /* @__PURE__ */ new Set();
|
|
98754
|
+
for (const targetNid of allTargetNodeIds) {
|
|
98755
|
+
const edges = store.getIncomingEdges(targetNid);
|
|
98756
|
+
const isChaTarget = targetNid !== nodeId;
|
|
98757
|
+
for (const edge of edges) {
|
|
98758
|
+
const key = `${edge.source_node_id}:${edge.target_node_id}:${edge.edge_type_id}`;
|
|
98759
|
+
if (seenEdgeKeys.has(key)) continue;
|
|
98760
|
+
seenEdgeKeys.add(key);
|
|
98761
|
+
allIncomingEdges.push({
|
|
98762
|
+
edge,
|
|
98763
|
+
via_cha: isChaTarget ? chaExpansion?.find((c) => {
|
|
98764
|
+
const ref = store.getNodeRef(targetNid);
|
|
98765
|
+
return ref && ref.nodeType === "symbol" ? store.getSymbolById(ref.refId)?.symbol_id === c.symbol_id : false;
|
|
98766
|
+
})?.name : void 0
|
|
98767
|
+
});
|
|
98768
|
+
}
|
|
98769
|
+
}
|
|
98770
|
+
const sourceNodeIds = allIncomingEdges.map((e) => e.edge.source_node_id);
|
|
98475
98771
|
const nodeRefs = store.getNodeRefsBatch(sourceNodeIds);
|
|
98476
98772
|
const symbolRefIds = [];
|
|
98477
98773
|
const fileRefIds = [];
|
|
@@ -98485,7 +98781,7 @@ function findReferences(store, opts) {
|
|
|
98485
98781
|
const allFileIds = [.../* @__PURE__ */ new Set([...fileRefIds, ...symFileIds])];
|
|
98486
98782
|
const fileMap = allFileIds.length > 0 ? store.getFilesByIds(allFileIds) : /* @__PURE__ */ new Map();
|
|
98487
98783
|
const references = [];
|
|
98488
|
-
for (const edge of
|
|
98784
|
+
for (const { edge, via_cha } of allIncomingEdges) {
|
|
98489
98785
|
const sourceRef = nodeRefs.get(edge.source_node_id);
|
|
98490
98786
|
if (!sourceRef) continue;
|
|
98491
98787
|
let symbol = null;
|
|
@@ -98507,13 +98803,17 @@ function findReferences(store, opts) {
|
|
|
98507
98803
|
} else {
|
|
98508
98804
|
filePath = `[${sourceRef.nodeType}:${sourceRef.refId}]`;
|
|
98509
98805
|
}
|
|
98510
|
-
|
|
98806
|
+
const ref = {
|
|
98511
98807
|
edge_type: edge.edge_type_name,
|
|
98512
98808
|
symbol,
|
|
98513
98809
|
file: filePath
|
|
98514
|
-
}
|
|
98810
|
+
};
|
|
98811
|
+
if (via_cha) ref.via_cha = via_cha;
|
|
98812
|
+
references.push(ref);
|
|
98515
98813
|
}
|
|
98516
|
-
|
|
98814
|
+
const result = { target: targetMeta, references, total: references.length };
|
|
98815
|
+
if (chaExpansion && chaExpansion.length > 0) result.cha_expansion = chaExpansion;
|
|
98816
|
+
return ok65(result);
|
|
98517
98817
|
}
|
|
98518
98818
|
|
|
98519
98819
|
// src/tools/framework/call-graph.ts
|
|
@@ -98559,9 +98859,19 @@ function getCallGraph(store, opts, depth = 2) {
|
|
|
98559
98859
|
resolution_tiers: { lsp_resolved: 0, ast_resolved: 0, ast_inferred: 0, text_matched: 0 }
|
|
98560
98860
|
});
|
|
98561
98861
|
}
|
|
98862
|
+
const chaMatches = expandMethodViaCha(store, symbol);
|
|
98863
|
+
const chaAliasNodeIds = chaMatches.filter((m) => m.relation !== "self").map((m) => m.nodeId);
|
|
98562
98864
|
const edgeTypesUsed = /* @__PURE__ */ new Set();
|
|
98563
98865
|
const visited = /* @__PURE__ */ new Set();
|
|
98564
|
-
const { node: rootNode, tiers } = buildCallNode(
|
|
98866
|
+
const { node: rootNode, tiers } = buildCallNode(
|
|
98867
|
+
store,
|
|
98868
|
+
symbol.id,
|
|
98869
|
+
nodeId,
|
|
98870
|
+
depth,
|
|
98871
|
+
visited,
|
|
98872
|
+
edgeTypesUsed,
|
|
98873
|
+
chaAliasNodeIds
|
|
98874
|
+
);
|
|
98565
98875
|
return ok66({
|
|
98566
98876
|
root: rootNode,
|
|
98567
98877
|
edge_types_used: [...edgeTypesUsed],
|
|
@@ -98569,12 +98879,14 @@ function getCallGraph(store, opts, depth = 2) {
|
|
|
98569
98879
|
resolution_tiers: tiers
|
|
98570
98880
|
});
|
|
98571
98881
|
}
|
|
98572
|
-
function buildCallNode(store, rootSymbolId, rootNodeId, maxDepth, _visited, edgeTypesUsed) {
|
|
98882
|
+
function buildCallNode(store, rootSymbolId, rootNodeId, maxDepth, _visited, edgeTypesUsed, chaAliasNodeIds = []) {
|
|
98573
98883
|
const tiers = { lsp_resolved: 0, ast_resolved: 0, ast_inferred: 0, text_matched: 0 };
|
|
98574
98884
|
const nodeInfoMap = /* @__PURE__ */ new Map();
|
|
98575
98885
|
const visited = /* @__PURE__ */ new Set();
|
|
98576
|
-
|
|
98886
|
+
const chaAliasSet = new Set(chaAliasNodeIds);
|
|
98887
|
+
let frontier = [rootNodeId, ...chaAliasNodeIds];
|
|
98577
98888
|
visited.add(rootNodeId);
|
|
98889
|
+
for (const alias of chaAliasNodeIds) visited.add(alias);
|
|
98578
98890
|
nodeInfoMap.set(rootNodeId, { nodeId: rootNodeId, symbolRefId: rootSymbolId, outgoing: [], incoming: [] });
|
|
98579
98891
|
for (let d = 0; d < maxDepth; d++) {
|
|
98580
98892
|
if (frontier.length === 0) break;
|
|
@@ -98583,15 +98895,16 @@ function buildCallNode(store, rootSymbolId, rootNodeId, maxDepth, _visited, edge
|
|
|
98583
98895
|
for (const edge of batchEdges) {
|
|
98584
98896
|
if (!CALL_EDGE_TYPES2.has(edge.edge_type_name)) continue;
|
|
98585
98897
|
edgeTypesUsed.add(edge.edge_type_name);
|
|
98586
|
-
const
|
|
98898
|
+
const effectivePivot = chaAliasSet.has(edge.pivot_node_id) ? rootNodeId : edge.pivot_node_id;
|
|
98899
|
+
const pivotInfo = nodeInfoMap.get(effectivePivot);
|
|
98587
98900
|
if (!pivotInfo) continue;
|
|
98588
98901
|
const resolution = inferResolution(edge);
|
|
98589
98902
|
tiers[resolution]++;
|
|
98590
|
-
if (edge.source_node_id === edge.pivot_node_id && !visited.has(edge.target_node_id)) {
|
|
98903
|
+
if (edge.source_node_id === edge.pivot_node_id && !visited.has(edge.target_node_id) && !chaAliasSet.has(edge.target_node_id)) {
|
|
98591
98904
|
pivotInfo.outgoing.push({ nodeId: edge.target_node_id, edgeType: edge.edge_type_name, resolution });
|
|
98592
98905
|
newNeighbors.add(edge.target_node_id);
|
|
98593
98906
|
}
|
|
98594
|
-
if (edge.target_node_id === edge.pivot_node_id && !visited.has(edge.source_node_id)) {
|
|
98907
|
+
if (edge.target_node_id === edge.pivot_node_id && !visited.has(edge.source_node_id) && !chaAliasSet.has(edge.source_node_id)) {
|
|
98595
98908
|
pivotInfo.incoming.push({ nodeId: edge.source_node_id, edgeType: edge.edge_type_name, resolution });
|
|
98596
98909
|
newNeighbors.add(edge.source_node_id);
|
|
98597
98910
|
}
|
|
@@ -98884,26 +99197,31 @@ import { ok as ok68, err as err43 } from "neverthrow";
|
|
|
98884
99197
|
function getTestsFor(store, opts) {
|
|
98885
99198
|
let targetFile;
|
|
98886
99199
|
let targetSymbolId;
|
|
98887
|
-
let
|
|
99200
|
+
let symbolNodeId;
|
|
99201
|
+
let fileNodeId;
|
|
98888
99202
|
if (opts.symbolId || opts.fqn) {
|
|
98889
99203
|
const resolved = resolveSymbolInput(store, opts);
|
|
98890
99204
|
if (!resolved) return err43(notFound(opts.symbolId ?? opts.fqn ?? "unknown"));
|
|
98891
99205
|
const symbol = resolved.symbol;
|
|
98892
99206
|
targetSymbolId = symbol.symbol_id;
|
|
98893
99207
|
targetFile = resolved.file.path;
|
|
98894
|
-
|
|
99208
|
+
symbolNodeId = store.getNodeId("symbol", symbol.id);
|
|
99209
|
+
fileNodeId = store.getNodeId("file", resolved.file.id);
|
|
98895
99210
|
} else if (opts.filePath) {
|
|
98896
99211
|
const f = store.getFile(opts.filePath);
|
|
98897
99212
|
if (!f) return err43(notFound(opts.filePath));
|
|
98898
99213
|
targetFile = f.path;
|
|
98899
|
-
|
|
99214
|
+
fileNodeId = store.getNodeId("file", f.id);
|
|
98900
99215
|
} else {
|
|
98901
99216
|
return err43(notFound("provide symbol_id, fqn, or file_path"));
|
|
98902
99217
|
}
|
|
98903
99218
|
const tests = [];
|
|
98904
99219
|
const seen = /* @__PURE__ */ new Set();
|
|
98905
|
-
|
|
98906
|
-
|
|
99220
|
+
const nodeIdsToCheck = /* @__PURE__ */ new Set();
|
|
99221
|
+
if (symbolNodeId !== void 0) nodeIdsToCheck.add(symbolNodeId);
|
|
99222
|
+
if (fileNodeId !== void 0) nodeIdsToCheck.add(fileNodeId);
|
|
99223
|
+
for (const nid of nodeIdsToCheck) {
|
|
99224
|
+
const incoming = store.getIncomingEdges(nid);
|
|
98907
99225
|
for (const edge of incoming) {
|
|
98908
99226
|
if (edge.edge_type_name !== "test_covers") continue;
|
|
98909
99227
|
const ref = store.getNodeRef(edge.source_node_id);
|
|
@@ -99459,6 +99777,55 @@ function walkDescendants(store, name, result, visited, depth) {
|
|
|
99459
99777
|
walkDescendants(store, row.name, node.children, visited, depth - 1);
|
|
99460
99778
|
}
|
|
99461
99779
|
}
|
|
99780
|
+
function collectPyprojectEntryPoints(store) {
|
|
99781
|
+
const names = /* @__PURE__ */ new Set();
|
|
99782
|
+
const allFiles = store.getAllFiles();
|
|
99783
|
+
const pyprojectFile = allFiles.find((f) => f.path.endsWith("pyproject.toml"));
|
|
99784
|
+
if (!pyprojectFile) return names;
|
|
99785
|
+
const symbols = store.getSymbolsByFile(pyprojectFile.id);
|
|
99786
|
+
for (const sym of symbols) {
|
|
99787
|
+
if (!sym.metadata) continue;
|
|
99788
|
+
try {
|
|
99789
|
+
const meta = typeof sym.metadata === "string" ? JSON.parse(sym.metadata) : sym.metadata;
|
|
99790
|
+
const section = typeof meta.section === "string" ? meta.section : "";
|
|
99791
|
+
const isScriptSection = /(?:project\.(?:scripts|gui-scripts)|console_scripts|gui_scripts)/.test(section);
|
|
99792
|
+
if (!isScriptSection) continue;
|
|
99793
|
+
const value = typeof meta.value === "string" ? meta.value : sym.signature ?? "";
|
|
99794
|
+
const colonIdx = value.indexOf(":");
|
|
99795
|
+
if (colonIdx >= 0) {
|
|
99796
|
+
const funcPart = value.slice(colonIdx + 1).trim();
|
|
99797
|
+
const dotIdx = funcPart.lastIndexOf(".");
|
|
99798
|
+
names.add(dotIdx >= 0 ? funcPart.slice(dotIdx + 1) : funcPart);
|
|
99799
|
+
}
|
|
99800
|
+
} catch {
|
|
99801
|
+
}
|
|
99802
|
+
}
|
|
99803
|
+
const setupFile = allFiles.find((f) => f.path.endsWith("setup.py") || f.path.endsWith("setup.cfg"));
|
|
99804
|
+
if (setupFile) {
|
|
99805
|
+
const setupSymbols = store.getSymbolsByFile(setupFile.id);
|
|
99806
|
+
for (const sym of setupSymbols) {
|
|
99807
|
+
if (!sym.metadata) continue;
|
|
99808
|
+
try {
|
|
99809
|
+
const meta = typeof sym.metadata === "string" ? JSON.parse(sym.metadata) : sym.metadata;
|
|
99810
|
+
if (meta.console_scripts || meta.gui_scripts) {
|
|
99811
|
+
const scripts = meta.console_scripts ?? meta.gui_scripts;
|
|
99812
|
+
if (Array.isArray(scripts)) {
|
|
99813
|
+
for (const entry of scripts) {
|
|
99814
|
+
const colonIdx = entry.indexOf(":");
|
|
99815
|
+
if (colonIdx >= 0) {
|
|
99816
|
+
const funcPart = entry.slice(colonIdx + 1).trim();
|
|
99817
|
+
const dotIdx = funcPart.lastIndexOf(".");
|
|
99818
|
+
names.add(dotIdx >= 0 ? funcPart.slice(dotIdx + 1) : funcPart);
|
|
99819
|
+
}
|
|
99820
|
+
}
|
|
99821
|
+
}
|
|
99822
|
+
}
|
|
99823
|
+
} catch {
|
|
99824
|
+
}
|
|
99825
|
+
}
|
|
99826
|
+
}
|
|
99827
|
+
return names;
|
|
99828
|
+
}
|
|
99462
99829
|
function getDeadExports(store, filePattern) {
|
|
99463
99830
|
const exported = store.getExportedSymbols(filePattern).filter((s) => !TEST_FIXTURE_RE.test(s.file_path)).filter((s) => !TEST_FILE_RE.test(s.file_path));
|
|
99464
99831
|
const importedNames = /* @__PURE__ */ new Set();
|
|
@@ -99478,9 +99845,18 @@ function getDeadExports(store, filePattern) {
|
|
|
99478
99845
|
}
|
|
99479
99846
|
}
|
|
99480
99847
|
}
|
|
99848
|
+
const pyprojectEntryNames = collectPyprojectEntryPoints(store);
|
|
99481
99849
|
const dead = [];
|
|
99482
99850
|
for (const sym of exported) {
|
|
99483
99851
|
if (sym.kind === "method") continue;
|
|
99852
|
+
if (sym.metadata) {
|
|
99853
|
+
try {
|
|
99854
|
+
const meta = typeof sym.metadata === "string" ? JSON.parse(sym.metadata) : sym.metadata;
|
|
99855
|
+
if (meta.is_entry_point) continue;
|
|
99856
|
+
} catch {
|
|
99857
|
+
}
|
|
99858
|
+
}
|
|
99859
|
+
if (pyprojectEntryNames.has(sym.name)) continue;
|
|
99484
99860
|
if (!importedNames.has(sym.name)) {
|
|
99485
99861
|
dead.push({
|
|
99486
99862
|
symbol_id: sym.symbol_id,
|
|
@@ -119137,7 +119513,7 @@ var DecisionStore = class {
|
|
|
119137
119513
|
};
|
|
119138
119514
|
|
|
119139
119515
|
// src/server/server.ts
|
|
119140
|
-
var PKG_VERSION = true ? "1.
|
|
119516
|
+
var PKG_VERSION = true ? "1.20.0" : "0.0.0-dev";
|
|
119141
119517
|
function j2(value) {
|
|
119142
119518
|
return JSON.stringify(value, (_key, val) => val === null || val === void 0 ? void 0 : val);
|
|
119143
119519
|
}
|
|
@@ -124980,7 +125356,7 @@ var ProjectManager = class {
|
|
|
124980
125356
|
|
|
124981
125357
|
// src/cli.ts
|
|
124982
125358
|
init_global();
|
|
124983
|
-
var PKG_VERSION2 = true ? "1.
|
|
125359
|
+
var PKG_VERSION2 = true ? "1.20.0" : "0.0.0-dev";
|
|
124984
125360
|
function registerDefaultPlugins2(registry) {
|
|
124985
125361
|
for (const p5 of createAllLanguagePlugins()) registry.registerLanguagePlugin(p5);
|
|
124986
125362
|
for (const p5 of createAllIntegrationPlugins()) registry.registerFrameworkPlugin(p5);
|