openkrak-mcp 1.0.18 → 1.0.19

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/index.js +145 -26
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -242516,7 +242516,7 @@ function detectSecurityPatterns(filePath, content) {
242516
242516
  }
242517
242517
  async function classifyTopology(repoRoot, allFiles) {
242518
242518
  const type = await detectProjectType(repoRoot);
242519
- const framework = await detectFramework(repoRoot);
242519
+ const framework = await detectFramework(repoRoot, allFiles);
242520
242520
  const entryPoints = detectEntryPoints(allFiles);
242521
242521
  const layers = detectLayers(allFiles);
242522
242522
  const modules = detectModules(allFiles);
@@ -242539,9 +242539,8 @@ async function detectProjectType(repoRoot) {
242539
242539
  }
242540
242540
  return "monolith";
242541
242541
  }
242542
- async function detectFramework(repoRoot) {
242542
+ async function readFrameworkFromPkg(pkgPath) {
242543
242543
  try {
242544
- const pkgPath = import_path4.default.join(repoRoot, "package.json");
242545
242544
  const pkg = JSON.parse(await import_promises3.default.readFile(pkgPath, "utf-8"));
242546
242545
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
242547
242546
  if (deps["next"]) return `next@${deps["next"].replace(/[\^~]/g, "")}`;
@@ -242558,30 +242557,68 @@ async function detectFramework(repoRoot) {
242558
242557
  if (deps["@angular/core"]) return "angular";
242559
242558
  } catch {
242560
242559
  }
242561
- try {
242562
- await import_promises3.default.access(import_path4.default.join(repoRoot, "next.config.js"));
242563
- return "next";
242564
- } catch {
242565
- }
242566
- try {
242567
- await import_promises3.default.access(import_path4.default.join(repoRoot, "next.config.mjs"));
242568
- return "next";
242569
- } catch {
242560
+ return null;
242561
+ }
242562
+ async function findSubPackageRoots(repoRoot, allFiles) {
242563
+ const candidates = /* @__PURE__ */ new Set();
242564
+ for (const f of allFiles) {
242565
+ const parts = f.split("/");
242566
+ if (parts.length >= 1) candidates.add(parts[0]);
242567
+ if (parts.length >= 2) candidates.add(`${parts[0]}/${parts[1]}`);
242570
242568
  }
242571
- try {
242572
- await import_promises3.default.access(import_path4.default.join(repoRoot, "next.config.ts"));
242573
- return "next";
242574
- } catch {
242569
+ const roots = [];
242570
+ for (const candidate of candidates) {
242571
+ const pkgPath = import_path4.default.join(repoRoot, candidate, "package.json");
242572
+ try {
242573
+ await import_promises3.default.access(pkgPath);
242574
+ roots.push(candidate);
242575
+ } catch {
242576
+ }
242575
242577
  }
242576
- try {
242577
- await import_promises3.default.access(import_path4.default.join(repoRoot, "vite.config.ts"));
242578
- return "vite";
242579
- } catch {
242578
+ return roots;
242579
+ }
242580
+ async function detectFramework(repoRoot, allFiles) {
242581
+ const rootFramework = await readFrameworkFromPkg(import_path4.default.join(repoRoot, "package.json"));
242582
+ if (rootFramework) return rootFramework;
242583
+ const configChecks = [
242584
+ ["next.config.js", "next"],
242585
+ ["next.config.mjs", "next"],
242586
+ ["next.config.ts", "next"],
242587
+ ["vite.config.ts", "vite"],
242588
+ ["astro.config.mjs", "astro"]
242589
+ ];
242590
+ for (const [cfg, name] of configChecks) {
242591
+ try {
242592
+ await import_promises3.default.access(import_path4.default.join(repoRoot, cfg));
242593
+ return name;
242594
+ } catch {
242595
+ }
242580
242596
  }
242581
- try {
242582
- await import_promises3.default.access(import_path4.default.join(repoRoot, "astro.config.mjs"));
242583
- return "astro";
242584
- } catch {
242597
+ if (allFiles && allFiles.length > 0) {
242598
+ const subRoots = await findSubPackageRoots(repoRoot, allFiles);
242599
+ const detected = [];
242600
+ for (const subRoot of subRoots) {
242601
+ const fw = await readFrameworkFromPkg(import_path4.default.join(repoRoot, subRoot, "package.json"));
242602
+ if (fw && !detected.includes(fw)) detected.push(fw);
242603
+ }
242604
+ for (const subRoot of subRoots) {
242605
+ for (const [cfg, name] of configChecks) {
242606
+ try {
242607
+ await import_promises3.default.access(import_path4.default.join(repoRoot, subRoot, cfg));
242608
+ if (!detected.includes(name)) detected.push(name);
242609
+ } catch {
242610
+ }
242611
+ }
242612
+ }
242613
+ if (detected.length === 1) return detected[0];
242614
+ if (detected.length > 1) {
242615
+ const prefixCount = /* @__PURE__ */ new Map();
242616
+ for (const d of detected) {
242617
+ const prefix = d.split("@")[0];
242618
+ prefixCount.set(prefix, (prefixCount.get(prefix) ?? 0) + 1);
242619
+ }
242620
+ return [...prefixCount.entries()].map(([fw, count]) => count > 1 ? `${fw} (\xD7${count})` : fw).join(", ");
242621
+ }
242585
242622
  }
242586
242623
  return null;
242587
242624
  }
@@ -242593,11 +242630,15 @@ function detectEntryPoints(files) {
242593
242630
  entries.push({ path: f, type });
242594
242631
  continue;
242595
242632
  }
242596
- if (/^app\/.*page\.(ts|js)x?$/.test(f) || /^app\/layout\.(ts|js)x?$/.test(f)) {
242633
+ if (/(?:^|\/)app\/.*page\.(ts|js)x?$/.test(f) || /(?:^|\/)app\/layout\.(ts|js)x?$/.test(f)) {
242634
+ entries.push({ path: f, type: "api" });
242635
+ continue;
242636
+ }
242637
+ if (/(?:^|\/)app\/.*(?:loading|error|not-found)\.(ts|js)x?$/.test(f)) {
242597
242638
  entries.push({ path: f, type: "api" });
242598
242639
  continue;
242599
242640
  }
242600
- if (/^app\/.*route\.(ts|js)x?$/.test(f) || /^pages\/api\//.test(f)) {
242641
+ if (/(?:^|\/)app\/.*route\.(ts|js)x?$/.test(f) || /(?:^|\/)pages\/api\//.test(f)) {
242601
242642
  entries.push({ path: f, type: "api" });
242602
242643
  continue;
242603
242644
  }
@@ -243034,6 +243075,73 @@ function buildImpactChains(candidates) {
243034
243075
  function describeMechanism(root, related, depth) {
243035
243076
  return `${root.type} in ${root.file} propagates via ${depth} dependency hop(s) to ${related.type} in ${related.file}`;
243036
243077
  }
243078
+ var CROSS_BUNDLE_SAFE_EXPORTS = /* @__PURE__ */ new Set([
243079
+ // action_contracts
243080
+ "ActionType",
243081
+ "PlannedAction",
243082
+ "ShellCommandSpec",
243083
+ "TEST_COMMAND_WHITELIST",
243084
+ "SENSITIVE_KEY_RE",
243085
+ "DESTRUCTIVE_RE",
243086
+ // orchestrator / plan
243087
+ "OrchestratorPlan",
243088
+ "OrchestratorStep",
243089
+ // contracts / store
243090
+ "MahadataStore",
243091
+ "InMemoryMahadataStore",
243092
+ "Mahadata",
243093
+ "TokenCounter",
243094
+ "LLMClientConfig",
243095
+ // handlers exposed via MCP tool layer
243096
+ "handleAnalyzeRepo",
243097
+ "handleBlastRadius",
243098
+ "handleGetHotspots",
243099
+ "handleGetMahadata",
243100
+ // shared utilities
243101
+ "calculateRiskScore",
243102
+ "assembleGraph",
243103
+ "classifyTopology",
243104
+ "resolveTaskDependencies",
243105
+ // constants / prompts
243106
+ "SYSTEM_PROMPT",
243107
+ "JSON_TAG_RE",
243108
+ // Next.js / framework reserved exports — always safe
243109
+ "metadata",
243110
+ "nextConfig",
243111
+ "geistSans",
243112
+ "geistMono",
243113
+ "default"
243114
+ // default exports are always externally consumable
243115
+ ]);
243116
+ var SAFE_EXPORT_PREFIXES = [
243117
+ "handle",
243118
+ // MCP handlers
243119
+ "create",
243120
+ // factory functions
243121
+ "build",
243122
+ // builder functions
243123
+ "run"
243124
+ // runner functions exposed to orchestrator
243125
+ ];
243126
+ var CROSS_BUNDLE_BARREL_PATTERNS = [
243127
+ /\/contracts\/index\.ts$/,
243128
+ /\/action_contracts\/index\.ts$/,
243129
+ /\/action_layer\/index\.ts$/,
243130
+ /\/shared\/index\.ts$/,
243131
+ /\/shared\/logger\/index\.ts$/,
243132
+ /\/orchestrator\/index\.ts$/
243133
+ ];
243134
+ function isCrossBundleSafeSymbol(symbolName, filePath) {
243135
+ if (CROSS_BUNDLE_SAFE_EXPORTS.has(symbolName)) return true;
243136
+ for (const prefix of SAFE_EXPORT_PREFIXES) {
243137
+ if (symbolName.startsWith(prefix)) return true;
243138
+ }
243139
+ if (symbolName === "logger" || symbolName.startsWith("logger")) return true;
243140
+ for (const pattern of CROSS_BUNDLE_BARREL_PATTERNS) {
243141
+ if (pattern.test(filePath)) return true;
243142
+ }
243143
+ return false;
243144
+ }
243037
243145
  function tagNoise(findings, chains) {
243038
243146
  const suppressionReasons = /* @__PURE__ */ new Map();
243039
243147
  const severityOrder = {
@@ -243043,6 +243151,17 @@ function tagNoise(findings, chains) {
243043
243151
  low: 1,
243044
243152
  info: 0
243045
243153
  };
243154
+ for (const f of findings) {
243155
+ if (f.type !== "dead_code") continue;
243156
+ if (suppressionReasons.has(f.id)) continue;
243157
+ const symbolName = f.symbol ? f.symbol.split("::")[1] ?? f.symbol : "";
243158
+ if (isCrossBundleSafeSymbol(symbolName, f.file)) {
243159
+ suppressionReasons.set(
243160
+ f.id,
243161
+ `Cross-bundle false positive: '${symbolName}' is a known exported interface consumed outside this scan boundary.`
243162
+ );
243163
+ }
243164
+ }
243046
243165
  const groupedByFileType = /* @__PURE__ */ new Map();
243047
243166
  for (const f of findings) {
243048
243167
  const key = `${f.file}::${f.type}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openkrak-mcp",
3
- "version": "1.0.18",
3
+ "version": "1.0.19",
4
4
  "description": "OpenKrak MCP Server - AI coding intelligence via Dorchester engine",
5
5
  "mcpName": "io.github.FrnzJulianBergmann/openkrak",
6
6
  "type": "commonjs",