@kage-core/kage-graph-mcp 2.2.5 → 2.2.6

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.
Files changed (2) hide show
  1. package/dist/kernel.js +20 -5
  2. package/package.json +1 -1
package/dist/kernel.js CHANGED
@@ -8533,6 +8533,12 @@ const TRUTH_COMMON_SYMBOL_NAMES = new Set([
8533
8533
  "build", "parse", "load", "save", "update", "delete", "remove", "test", "validate",
8534
8534
  "format", "process", "next", "send", "write", "read", "config", "helper", "util",
8535
8535
  ]);
8536
+ // Convention-named local closures that collide across unrelated code by idiom,
8537
+ // not duplication. Kept separate from common-names so the intent is clear.
8538
+ const TRUTH_DUPLICATE_NAME_DENYLIST = new Set([
8539
+ "decorator", "wrapper", "inner", "callback", "wrapped", "fn", "cb", "noop",
8540
+ "predicate", "comparator", "getter", "setter", "factory", "visit",
8541
+ ]);
8536
8542
  function truthExcludedPath(path) {
8537
8543
  return /(^|\/)(tests?|__tests__|specs?|examples?|fixtures?|benchmarks?|mocks?|__mocks__|vendor|node_modules|dist|build)\//i.test(path)
8538
8544
  || /\.(test|spec)\.[^.]+$/i.test(path)
@@ -8619,7 +8625,14 @@ function truthReport(projectDir) {
8619
8625
  // 1a. Duplicate implementations: same-name symbols spread across directories.
8620
8626
  const symbolsByName = new Map();
8621
8627
  for (const symbol of graph.symbols) {
8622
- if (!["function", "class", "method"].includes(symbol.kind))
8628
+ // Methods are excluded: same-named methods on different classes (__init__,
8629
+ // to_dict, validate, ...) are normal polymorphism, not duplication. Only
8630
+ // top-level functions and classes can be genuine parallel implementations.
8631
+ if (!["function", "class"].includes(symbol.kind))
8632
+ continue;
8633
+ // Dunders and convention-named local closures (decorator/wrapper/inner/...)
8634
+ // collide by language idiom across unrelated code; never real duplicates.
8635
+ if (/^__.*__$/.test(symbol.name) || TRUTH_DUPLICATE_NAME_DENYLIST.has(symbol.name.toLowerCase()))
8623
8636
  continue;
8624
8637
  if (symbol.name.length < 4 || TRUTH_COMMON_SYMBOL_NAMES.has(symbol.name.toLowerCase()))
8625
8638
  continue;
@@ -8641,14 +8654,16 @@ function truthReport(projectDir) {
8641
8654
  signatureCounts.set(normalized, (signatureCounts.get(normalized) ?? 0) + 1);
8642
8655
  }
8643
8656
  const signatureMatch = [...signatureCounts.values()].some((count) => count >= 2);
8657
+ // A same-name-only collision across dirs is weak signal and the source of
8658
+ // most false positives. Require a matching signature to report it at all.
8659
+ if (!signatureMatch)
8660
+ continue;
8644
8661
  const newestEpoch = Math.max(0, ...members.map((member) => fileNewestEpoch.get(member.path) ?? 0));
8645
8662
  const recent = hasGit && newestEpoch > aiEraCutoff;
8646
8663
  duplicateFindings.push({
8647
8664
  kind: "duplicate_cluster",
8648
- title: `${members[0].name} — ${paths.size} implementations across ${dirs.size} directories${recent ? " [recent, likely AI-era]" : ""}`,
8649
- detail: signatureMatch
8650
- ? "Same name AND near-identical signature: almost certainly parallel implementations of the same idea."
8651
- : "Same name in unrelated directories: agents and humans may be solving the same problem twice.",
8665
+ title: `${members[0].name} — ${paths.size} implementations across ${dirs.size} directories${recent ? " [recently changed]" : ""}`,
8666
+ detail: "Same name and near-identical signature in unrelated directories — likely parallel implementations of the same idea, worth a look.",
8652
8667
  evidence: members.slice(0, 5).map((member) => `${member.path}:${member.line} ${member.kind} ${member.signature.slice(0, 80)}`),
8653
8668
  surprise: Math.min(100, 45 + paths.size * 8 + (signatureMatch ? 15 : 0) + (recent ? 20 : 0)),
8654
8669
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kage-core/kage-graph-mcp",
3
- "version": "2.2.5",
3
+ "version": "2.2.6",
4
4
  "description": "Local-first repo memory, code graph, and recall MCP server for coding agents",
5
5
  "main": "dist/index.js",
6
6
  "files": [