cognium-dev 3.106.2 → 3.107.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.
Files changed (2) hide show
  1. package/dist/cli.js +343 -23
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -5,7 +5,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
5
5
  // src/cli.ts
6
6
  import { readFileSync, existsSync } from "fs";
7
7
  import { stat as stat2, readdir as readdir2 } from "fs/promises";
8
- import { join as join2, dirname as dirname2, extname, resolve, relative as relative3 } from "path";
8
+ import { join as join2, dirname as dirname3, extname, resolve as resolve2, relative as relative4 } from "path";
9
9
  import { createRequire as createRequire2 } from "module";
10
10
 
11
11
  // ../../node_modules/web-tree-sitter/web-tree-sitter.js
@@ -23657,6 +23657,17 @@ var SQL_BUILDER_WRAPPER_CALL_RE = /\.(?:wrap|quote|escape|identifier)\s*\(/;
23657
23657
  var SQL_EXTRACTION_RETURN_RE = /^(?:String|CharSequence|Optional\s*<\s*String\s*>)$/;
23658
23658
  var SQL_EXTRACTION_NAME_RE = /^(?:get|extract|build).*(?:[Ss]ql|[Qq]uery)|^toSql|.*Statement.*ToString$|.*Query.*String$/;
23659
23659
  var SQL_EXTRACTION_PRIMITIVE_INPUT_RE = /^(?:String|CharSequence)$/;
23660
+ var SQL_EXEC_METHODS = new Set([
23661
+ "prepareStatement",
23662
+ "prepareCall",
23663
+ "execute",
23664
+ "executeQuery",
23665
+ "executeUpdate",
23666
+ "executeLargeUpdate",
23667
+ "addBatch"
23668
+ ]);
23669
+ var JAVA_SQL_ASSIGN_RE_TEMPLATE = "\\b(?:String|CharSequence|final\\s+String|var)\\s+SQLVAR\\b\\s*=\\s*(.+?);";
23670
+ var JAVA_INLINE_MATCHES_RE = /\.\s*matches\s*\(\s*"((?:[^"\\]|\\.)*)"\s*\)/g;
23660
23671
  function resolveJavaReceiverType(receiver, sinkLine, sourceLines) {
23661
23672
  if (!receiver || !/^[A-Za-z_]\w*$/.test(receiver))
23662
23673
  return null;
@@ -23715,6 +23726,116 @@ function findEnclosingMethodFromIr(types, sinkLine) {
23715
23726
  }
23716
23727
  return null;
23717
23728
  }
23729
+ function splitJavaConcatTokens(rhs) {
23730
+ const tokens = [];
23731
+ let cur = "";
23732
+ let depth = 0;
23733
+ let inString = false;
23734
+ let i2 = 0;
23735
+ while (i2 < rhs.length) {
23736
+ const ch = rhs[i2] ?? "";
23737
+ if (inString) {
23738
+ cur += ch;
23739
+ if (ch === "\\" && i2 + 1 < rhs.length) {
23740
+ cur += rhs[i2 + 1] ?? "";
23741
+ i2 += 2;
23742
+ continue;
23743
+ }
23744
+ if (ch === '"')
23745
+ inString = false;
23746
+ i2++;
23747
+ continue;
23748
+ }
23749
+ if (ch === '"') {
23750
+ inString = true;
23751
+ cur += ch;
23752
+ i2++;
23753
+ continue;
23754
+ }
23755
+ if (ch === "(" || ch === "[" || ch === "{") {
23756
+ depth++;
23757
+ cur += ch;
23758
+ i2++;
23759
+ continue;
23760
+ }
23761
+ if (ch === ")" || ch === "]" || ch === "}") {
23762
+ depth--;
23763
+ cur += ch;
23764
+ i2++;
23765
+ continue;
23766
+ }
23767
+ if (ch === "+" && depth === 0) {
23768
+ tokens.push(cur.trim());
23769
+ cur = "";
23770
+ i2++;
23771
+ continue;
23772
+ }
23773
+ cur += ch;
23774
+ i2++;
23775
+ }
23776
+ if (cur.trim())
23777
+ tokens.push(cur.trim());
23778
+ return tokens;
23779
+ }
23780
+ function isImplicitlyAnchoredAllowlistRegex(re) {
23781
+ if (re === "")
23782
+ return false;
23783
+ const stripped = re.replace(/\[(?:[^\]\\]|\\.)*\]/g, "");
23784
+ const cleaned = stripped.replace(/\\./g, "");
23785
+ if (cleaned.includes("."))
23786
+ return false;
23787
+ if (cleaned.includes("|"))
23788
+ return false;
23789
+ return true;
23790
+ }
23791
+ function findJavaMethodBody(methodName, sourceLines) {
23792
+ if (!/^[A-Za-z_]\w*$/.test(methodName))
23793
+ return null;
23794
+ const sigRe = new RegExp(`\\b(?:public|private|protected|static|final|synchronized|\\s)+[\\w<>?,\\s\\[\\]]+?\\b${methodName}\\s*\\(`);
23795
+ for (let i2 = 0;i2 < sourceLines.length; i2++) {
23796
+ const ln = sourceLines[i2] ?? "";
23797
+ if (!sigRe.test(ln))
23798
+ continue;
23799
+ let braceLine = -1;
23800
+ for (let j = i2;j < Math.min(sourceLines.length, i2 + 4); j++) {
23801
+ if ((sourceLines[j] ?? "").includes("{")) {
23802
+ braceLine = j;
23803
+ break;
23804
+ }
23805
+ }
23806
+ if (braceLine < 0)
23807
+ continue;
23808
+ let depth = 0;
23809
+ const body2 = [];
23810
+ for (let j = braceLine;j < sourceLines.length; j++) {
23811
+ const ln2 = sourceLines[j] ?? "";
23812
+ body2.push(ln2);
23813
+ for (const ch of ln2) {
23814
+ if (ch === "{")
23815
+ depth++;
23816
+ else if (ch === "}")
23817
+ depth--;
23818
+ }
23819
+ if (depth <= 0 && j > braceLine)
23820
+ return body2;
23821
+ }
23822
+ return null;
23823
+ }
23824
+ return null;
23825
+ }
23826
+ function javaBodyHasInlineRegexAllowlistThrow(bodyLines) {
23827
+ const text = bodyLines.join(`
23828
+ `);
23829
+ if (!/\bthrow\s+/.test(text))
23830
+ return false;
23831
+ JAVA_INLINE_MATCHES_RE.lastIndex = 0;
23832
+ let m;
23833
+ while ((m = JAVA_INLINE_MATCHES_RE.exec(text)) !== null) {
23834
+ if (isImplicitlyAnchoredAllowlistRegex(m[1] ?? ""))
23835
+ return true;
23836
+ }
23837
+ return false;
23838
+ }
23718
23839
  function isJavaLiteralOrAnnotationAccessor(expr) {
23719
23840
  const e = expr.trim();
23720
23841
  if (e === "")
@@ -23950,6 +24071,24 @@ class SinkFilterPass {
23950
24071
  }
23951
24072
  if (language === "java") {
23952
24073
  const sourceLines = ctx.code.split(`
24074
+ `);
24075
+ filtered = filtered.filter((sink) => {
24076
+ if (sink.type !== "xxe")
24077
+ return true;
24078
+ const sinkLineText = sourceLines[sink.line - 1] ?? "";
24079
+ const receiverMatch = sinkLineText.match(/\b(\w+)\s*\.\s*(\w+)\s*\(/);
24080
+ const receiver = receiverMatch?.[1];
24081
+ const method = sink.method ?? receiverMatch?.[2];
24082
+ if (method === "parse" && receiver) {
24083
+ const recvType = resolveJavaReceiverType(receiver, sink.line, sourceLines);
24084
+ if (recvType && DATA_PARSER_TYPES.has(recvType))
24085
+ return false;
24086
+ }
24087
+ return true;
24088
+ });
24089
+ }
24090
+ if (language === "java") {
24091
+ const sourceLines = ctx.code.split(`
23953
24092
  `);
23954
24093
  filtered = filtered.filter((sink) => {
23955
24094
  if (sink.type !== "command_injection")
@@ -24158,6 +24297,65 @@ class SinkFilterPass {
24158
24297
  });
24159
24298
  }
24160
24299
  }
24300
+ if (language === "java") {
24301
+ const sourceLines = ctx.code.split(`
24302
+ `);
24303
+ filtered = filtered.filter((sink) => {
24304
+ if (sink.type !== "sql_injection")
24305
+ return true;
24306
+ const method = sink.method ?? "";
24307
+ if (!SQL_EXEC_METHODS.has(method))
24308
+ return true;
24309
+ const sinkLineText = sourceLines[sink.line - 1] ?? "";
24310
+ const callArgs = extractJavaCallArgs(method, sinkLineText);
24311
+ if (!callArgs || callArgs.length === 0)
24312
+ return true;
24313
+ const sqlVar = callArgs[0]?.trim() ?? "";
24314
+ if (!/^[A-Za-z_]\w*$/.test(sqlVar))
24315
+ return true;
24316
+ const lo = Math.max(0, sink.line - 31);
24317
+ const assignRe = new RegExp(JAVA_SQL_ASSIGN_RE_TEMPLATE.replace("SQLVAR", sqlVar));
24318
+ let rhs = null;
24319
+ for (let i2 = sink.line - 2;i2 >= lo; i2--) {
24320
+ const ln = sourceLines[i2] ?? "";
24321
+ const m = ln.match(assignRe);
24322
+ if (m) {
24323
+ rhs = m[1] ?? null;
24324
+ break;
24325
+ }
24326
+ }
24327
+ if (!rhs)
24328
+ return true;
24329
+ const tokens = splitJavaConcatTokens(rhs);
24330
+ if (tokens.length < 2)
24331
+ return true;
24332
+ let hasPlaceholder = false;
24333
+ const methodCallNames = [];
24334
+ for (const tk of tokens) {
24335
+ if (/^"(?:[^"\\]|\\.)*"$/.test(tk)) {
24336
+ if (tk.includes("?"))
24337
+ hasPlaceholder = true;
24338
+ continue;
24339
+ }
24340
+ const callMatch = tk.match(/^([A-Za-z_]\w*)\s*\(/);
24341
+ if (callMatch) {
24342
+ methodCallNames.push(callMatch[1] ?? "");
24343
+ continue;
24344
+ }
24345
+ return true;
24346
+ }
24347
+ if (!hasPlaceholder)
24348
+ return true;
24349
+ if (methodCallNames.length === 0)
24350
+ return true;
24351
+ for (const mname of methodCallNames) {
24352
+ const body2 = findJavaMethodBody(mname, sourceLines);
24353
+ if (body2 && javaBodyHasInlineRegexAllowlistThrow(body2))
24354
+ return false;
24355
+ }
24356
+ return true;
24357
+ });
24358
+ }
24161
24359
  return { sources, sinks: filtered, sanitizers };
24162
24360
  }
24163
24361
  }
@@ -24580,6 +24778,23 @@ class TaintPropagationPass {
24580
24778
  });
24581
24779
  }
24582
24780
  }
24781
+ const setIntervalLines = new Set;
24782
+ for (const s of sinks) {
24783
+ if (s.type === "code_injection" && (s.method === "setInterval" || s.method === "setTimeout")) {
24784
+ setIntervalLines.add(s.line);
24785
+ }
24786
+ }
24787
+ if (setIntervalLines.size > 0) {
24788
+ finalFlows = finalFlows.filter((f) => {
24789
+ if (f.sink_type !== "code_injection")
24790
+ return true;
24791
+ if (f.source_type !== "interprocedural_param")
24792
+ return true;
24793
+ if (!setIntervalLines.has(f.sink_line))
24794
+ return true;
24795
+ return false;
24796
+ });
24797
+ }
24583
24798
  if (finalFlows.length > 1) {
24584
24799
  const bestByKey = new Map;
24585
24800
  for (const f of finalFlows) {
@@ -35373,11 +35588,11 @@ function deriveProjectRoot(paths) {
35373
35588
  return common.join("/") || "/";
35374
35589
  }
35375
35590
  // ../project-profile-detect/dist/index.js
35376
- import { relative as relative2 } from "path";
35591
+ import { relative as relative3 } from "path";
35377
35592
 
35378
35593
  // ../project-profile-detect/dist/walk.js
35379
35594
  import { readdir, readFile, stat } from "fs/promises";
35380
- import { join, relative } from "path";
35595
+ import { join, relative as relative2 } from "path";
35381
35596
 
35382
35597
  // ../project-profile-detect/dist/maven-parse.js
35383
35598
  var TAG = (name2) => new RegExp(`<${name2}\\b[^>]*>([\\s\\S]*?)<\\/${name2}>`, "i");
@@ -35403,7 +35618,12 @@ var MAVEN_PLUGIN_MAP = {
35403
35618
  "exec-maven-plugin": "application",
35404
35619
  "maven-assembly-plugin": "application"
35405
35620
  };
35621
+ var MAVEN_PUBLISH_PLUGIN_URLS = {
35622
+ "central-publishing-maven-plugin": "https://central.sonatype.com/",
35623
+ "nexus-staging-maven-plugin": "https://oss.sonatype.org/"
35624
+ };
35406
35625
  function parseMavenPom(xml, moduleRoot, buildFile, directorySignals) {
35626
+ const parentRef = extractParentRef(xml);
35407
35627
  const stripped = xml.replace(/<parent\b[\s\S]*?<\/parent>/i, "");
35408
35628
  const groupId = firstTag(stripped, "groupId");
35409
35629
  const artifactId = firstTag(stripped, "artifactId");
@@ -35412,10 +35632,15 @@ function parseMavenPom(xml, moduleRoot, buildFile, directorySignals) {
35412
35632
  const buildBlock = firstTag(xml, "build") ?? "";
35413
35633
  const pluginBlocks = allTags(buildBlock, "plugin");
35414
35634
  const plugins = new Set;
35635
+ const publishUrls = new Set;
35415
35636
  for (const p of pluginBlocks) {
35416
35637
  const aid = firstTag(p, "artifactId");
35417
- if (aid && MAVEN_PLUGIN_MAP[aid])
35638
+ if (!aid)
35639
+ continue;
35640
+ if (MAVEN_PLUGIN_MAP[aid])
35418
35641
  plugins.add(MAVEN_PLUGIN_MAP[aid]);
35642
+ if (MAVEN_PUBLISH_PLUGIN_URLS[aid])
35643
+ publishUrls.add(MAVEN_PUBLISH_PLUGIN_URLS[aid]);
35419
35644
  }
35420
35645
  if (/<parent\b[\s\S]*?<artifactId>\s*spring-boot-starter-parent\s*<\/artifactId>/i.test(xml)) {
35421
35646
  plugins.add("spring-boot");
@@ -35428,7 +35653,8 @@ function parseMavenPom(xml, moduleRoot, buildFile, directorySignals) {
35428
35653
  plugins.add("maven-plugin");
35429
35654
  const distBlock = firstTag(xml, "distributionManagement") ?? "";
35430
35655
  const urls = [
35431
- ...allTags(distBlock, "url")
35656
+ ...allTags(distBlock, "url"),
35657
+ ...publishUrls
35432
35658
  ].map((u) => u.trim()).filter(Boolean);
35433
35659
  const signals = {
35434
35660
  ...directorySignals,
@@ -35443,9 +35669,34 @@ function parseMavenPom(xml, moduleRoot, buildFile, directorySignals) {
35443
35669
  groupId,
35444
35670
  artifactId,
35445
35671
  version,
35446
- signals
35672
+ signals,
35673
+ parentRef
35447
35674
  };
35448
35675
  }
35676
+ function extractParentRef(xml) {
35677
+ const block = TAG("parent").exec(xml);
35678
+ if (!block)
35679
+ return;
35680
+ const inner = block[1];
35681
+ const groupId = firstTag(inner, "groupId");
35682
+ const artifactId = firstTag(inner, "artifactId");
35683
+ const version = firstTag(inner, "version");
35684
+ let relativePath;
35685
+ let emptyRelativePath = false;
35686
+ const selfClosing = /<relativePath\b[^>]*\/\s*>/i.test(inner);
35687
+ if (selfClosing) {
35688
+ emptyRelativePath = true;
35689
+ } else {
35690
+ const rp = firstTag(inner, "relativePath");
35691
+ if (rp !== undefined) {
35692
+ if (rp.length === 0)
35693
+ emptyRelativePath = true;
35694
+ else
35695
+ relativePath = rp;
35696
+ }
35697
+ }
35698
+ return { groupId, artifactId, version, relativePath, emptyRelativePath };
35699
+ }
35449
35700
 
35450
35701
  // ../project-profile-detect/dist/gradle-parse.js
35451
35702
  var GRADLE_PLUGIN_MAP = {
@@ -35512,6 +35763,70 @@ function parseGradleBuild(text, moduleRoot, buildFile, buildSystem, directorySig
35512
35763
  };
35513
35764
  }
35514
35765
 
35766
+ // ../project-profile-detect/dist/maven-inherit.js
35767
+ import { dirname as dirname2, isAbsolute, normalize, relative, resolve } from "path";
35768
+ var MAX_DEPTH = 6;
35769
+ var DEFAULT_RELATIVE_PATH = "../pom.xml";
35770
+ function mergeMavenInheritance(modules, scanRoot) {
35771
+ const normalizedScanRoot = normalize(scanRoot);
35772
+ const byBuildFile = new Map;
35773
+ for (const m of modules) {
35774
+ if (m.buildSystem === "maven") {
35775
+ byBuildFile.set(normalize(m.buildFile), m);
35776
+ }
35777
+ }
35778
+ for (const child of modules) {
35779
+ if (child.buildSystem !== "maven")
35780
+ continue;
35781
+ if (!child.parentRef)
35782
+ continue;
35783
+ const inheritedUrls = new Set;
35784
+ const inheritedPlugins = new Set;
35785
+ walkParents(child, byBuildFile, normalizedScanRoot, inheritedUrls, inheritedPlugins);
35786
+ if (inheritedUrls.size === 0 && inheritedPlugins.size === 0)
35787
+ continue;
35788
+ const existingUrls = new Set(child.signals.distributionUrls);
35789
+ for (const u of inheritedUrls) {
35790
+ if (!existingUrls.has(u))
35791
+ child.signals.distributionUrls.push(u);
35792
+ }
35793
+ const existingPlugins = new Set(child.signals.plugins);
35794
+ for (const p of inheritedPlugins) {
35795
+ if (!existingPlugins.has(p))
35796
+ child.signals.plugins.push(p);
35797
+ }
35798
+ }
35799
+ }
35800
+ function walkParents(start2, byBuildFile, scanRoot, outUrls, outPlugins) {
35801
+ const visited = new Set([normalize(start2.buildFile)]);
35802
+ let current = start2;
35803
+ for (let depth = 0;depth < MAX_DEPTH; depth++) {
35804
+ const ref = current.parentRef;
35805
+ if (!ref)
35806
+ return;
35807
+ if (ref.emptyRelativePath)
35808
+ return;
35809
+ const childDir = dirname2(current.buildFile);
35810
+ const rel = ref.relativePath ?? DEFAULT_RELATIVE_PATH;
35811
+ const candidateAbs = normalize(isAbsolute(rel) ? rel : resolve(childDir, rel));
35812
+ const parentBuildFile = candidateAbs.endsWith("pom.xml") ? candidateAbs : normalize(resolve(candidateAbs, "pom.xml"));
35813
+ const relToRoot = relative(scanRoot, parentBuildFile);
35814
+ if (relToRoot.startsWith("..") || isAbsolute(relToRoot))
35815
+ return;
35816
+ if (visited.has(parentBuildFile))
35817
+ return;
35818
+ visited.add(parentBuildFile);
35819
+ const parent = byBuildFile.get(parentBuildFile);
35820
+ if (!parent)
35821
+ return;
35822
+ for (const u of parent.signals.distributionUrls)
35823
+ outUrls.add(u);
35824
+ for (const p of parent.signals.plugins)
35825
+ outPlugins.add(p);
35826
+ current = parent;
35827
+ }
35828
+ }
35829
+
35515
35830
  // ../project-profile-detect/dist/walk.js
35516
35831
  var BUILD_FILES = ["pom.xml", "build.gradle", "build.gradle.kts"];
35517
35832
  var SKIP_DIRS = new Set([
@@ -35532,6 +35847,7 @@ var SKIP_DIRS = new Set([
35532
35847
  async function discoverBuildModules(scanRoot) {
35533
35848
  const modules = [];
35534
35849
  await walk(scanRoot, modules);
35850
+ mergeMavenInheritance(modules, scanRoot);
35535
35851
  return modules;
35536
35852
  }
35537
35853
  async function walk(dir, out2) {
@@ -35739,6 +36055,10 @@ function resolveShape(mod) {
35739
36055
  reasons.push(...libSignals, "no public-registry distribution (internal helper)");
35740
36056
  return { shape: "application", reasons };
35741
36057
  }
36058
+ if (isPubliclyPublished(sig.distributionUrls)) {
36059
+ reasons.push("public-registry distribution", "no application/server/plugin signals → implicit library");
36060
+ return { shape: "library", reasons };
36061
+ }
35742
36062
  reasons.push("no shape signals");
35743
36063
  return { shape: "unknown", reasons };
35744
36064
  }
@@ -35826,7 +36146,7 @@ async function detectProjectProfiles(scanRoot, options = {}) {
35826
36146
  const profileByFile = new Map;
35827
36147
  const unknownFiles = [];
35828
36148
  for (const file of files) {
35829
- const rel = relative2(scanRoot, file);
36149
+ const rel = relative3(scanRoot, file);
35830
36150
  const ov = applyOverrides(rel, compiledOverrides);
35831
36151
  if (ov) {
35832
36152
  profileByFile.set(file, ov.profile);
@@ -35878,7 +36198,7 @@ var colors = {
35878
36198
  };
35879
36199
 
35880
36200
  // src/version.ts
35881
- var version = "3.106.1";
36201
+ var version = "3.107.0";
35882
36202
 
35883
36203
  // src/formatters.ts
35884
36204
  var LIBRARY_API_SURFACE_TAG2 = "library-api-surface:caller-responsibility";
@@ -36679,7 +36999,7 @@ function applySuppressionsToResults(results, suppressions, basePath) {
36679
36999
  if (suppressions.length === 0)
36680
37000
  return results;
36681
37001
  return results.map((result) => {
36682
- const relativeFile = relative3(basePath, result.file) || result.file;
37002
+ const relativeFile = relative4(basePath, result.file) || result.file;
36683
37003
  const filteredVulns = result.vulnerabilities.filter((vuln) => {
36684
37004
  for (const supp of suppressions) {
36685
37005
  if (supp.pass !== vuln.type)
@@ -36768,7 +37088,7 @@ async function collectFiles(targetPath, options = {}) {
36768
37088
  return files;
36769
37089
  }
36770
37090
  if (fileMatchesLanguage(targetPath, language)) {
36771
- const relativePath = basePath ? relative3(basePath, targetPath) : targetPath;
37091
+ const relativePath = basePath ? relative4(basePath, targetPath) : targetPath;
36772
37092
  if (includePatterns && includePatterns.length > 0) {
36773
37093
  if (!matchesAnyPattern(relativePath, includePatterns)) {
36774
37094
  return files;
@@ -36787,7 +37107,7 @@ async function collectFiles(targetPath, options = {}) {
36787
37107
  if (excludeTests && /^(test|tests|__tests__|spec|__mocks__)$/i.test(entry.name))
36788
37108
  continue;
36789
37109
  const fullPath = join2(targetPath, entry.name);
36790
- const relativePath = basePath ? relative3(basePath, fullPath) : fullPath;
37110
+ const relativePath = basePath ? relative4(basePath, fullPath) : fullPath;
36791
37111
  if (excludePatterns && entry.isDirectory()) {
36792
37112
  const dirPattern = relativePath + "/";
36793
37113
  if (excludePatterns.some((p) => matchesGlob(dirPattern, p) || matchesGlob(relativePath, p))) {
@@ -36885,14 +37205,14 @@ async function scanProject(files, language, analyzeOpts, crossFileBudgetMs) {
36885
37205
  async function initWasm(spin) {
36886
37206
  const isStandalone = import.meta.url.includes("/$bunfs/");
36887
37207
  if (isStandalone) {
36888
- const { dirname: dirname3, join: join3 } = await import("path");
36889
- const binaryDir = dirname3(process.execPath);
37208
+ const { dirname: dirname4, join: join3 } = await import("path");
37209
+ const binaryDir = dirname4(process.execPath);
36890
37210
  const cwd = process.cwd();
36891
37211
  let scriptDir = null;
36892
37212
  if (!import.meta.url.includes("/$bunfs/")) {
36893
37213
  try {
36894
37214
  const { fileURLToPath } = await import("url");
36895
- scriptDir = dirname3(fileURLToPath(import.meta.url));
37215
+ scriptDir = dirname4(fileURLToPath(import.meta.url));
36896
37216
  } catch {}
36897
37217
  }
36898
37218
  const wasmLocations = [
@@ -36945,7 +37265,7 @@ Please ensure the wasm/ directory is located next to the binary or in your curre
36945
37265
  } else {
36946
37266
  const require2 = createRequire2(import.meta.url);
36947
37267
  const circleIrPkg = require2.resolve("circle-ir/package.json");
36948
- const wasmBasePath = join2(dirname2(circleIrPkg), "dist", "wasm") + "/";
37268
+ const wasmBasePath = join2(dirname3(circleIrPkg), "dist", "wasm") + "/";
36949
37269
  await initAnalyzer({
36950
37270
  wasmPath: wasmBasePath + "web-tree-sitter.wasm",
36951
37271
  languagePaths: {
@@ -36974,7 +37294,7 @@ function buildProfileSummary(scanRoot, modules, resolvedProfiles) {
36974
37294
  return {
36975
37295
  scanRoot,
36976
37296
  modules: modules.map((m) => ({
36977
- root: relative3(scanRoot, m.module.root) || ".",
37297
+ root: relative4(scanRoot, m.module.root) || ".",
36978
37298
  profile: m.profile,
36979
37299
  reasons: m.reasons,
36980
37300
  buildSystem: m.module.buildSystem
@@ -37003,9 +37323,9 @@ function printProfileExplain(scanRoot, detection) {
37003
37323
  out2.push(" (no pom.xml, build.gradle, or build.gradle.kts found)");
37004
37324
  } else {
37005
37325
  for (const r of detection.modules) {
37006
- const rel = relative3(scanRoot, r.module.root) || ".";
37326
+ const rel = relative4(scanRoot, r.module.root) || ".";
37007
37327
  out2.push(` ${colors.cyan(rel || ".")} → ${colors.bold(r.profile)}`);
37008
- out2.push(` build: ${r.module.buildSystem} (${relative3(scanRoot, r.module.buildFile)})`);
37328
+ out2.push(` build: ${r.module.buildSystem} (${relative4(scanRoot, r.module.buildFile)})`);
37009
37329
  if (r.module.artifactId) {
37010
37330
  out2.push(` coords: ${r.module.groupId ?? "?"}:${r.module.artifactId}:${r.module.version ?? "?"}`);
37011
37331
  }
@@ -37050,7 +37370,7 @@ async function runScan(targetPath, options) {
37050
37370
  await initWasm(spin);
37051
37371
  if (spin)
37052
37372
  spin.text = "Collecting files...";
37053
- const absPath = resolve(targetPath);
37373
+ const absPath = resolve2(targetPath);
37054
37374
  if (!existsSync(absPath)) {
37055
37375
  if (spin)
37056
37376
  spin.fail(`Path not found: ${absPath}`);
@@ -37114,7 +37434,7 @@ async function runScan(targetPath, options) {
37114
37434
  results = [];
37115
37435
  let processed = 0;
37116
37436
  const formatCurrentFile = (file) => {
37117
- const rel = relative3(absPath, file) || file;
37437
+ const rel = relative4(absPath, file) || file;
37118
37438
  return rel.length > 80 ? `...${rel.slice(-77)}` : rel;
37119
37439
  };
37120
37440
  const concurrency = options.threads;
@@ -37290,7 +37610,7 @@ async function runMetrics(targetPath, options) {
37290
37610
  await initWasm(spin);
37291
37611
  if (spin)
37292
37612
  spin.text = "Collecting files...";
37293
- const absPath = resolve(targetPath);
37613
+ const absPath = resolve2(targetPath);
37294
37614
  if (!existsSync(absPath)) {
37295
37615
  if (spin)
37296
37616
  spin.fail(`Path not found: ${absPath}`);
@@ -37318,7 +37638,7 @@ async function runMetrics(targetPath, options) {
37318
37638
  continue;
37319
37639
  }
37320
37640
  if (spin) {
37321
- const rel = relative3(absPath, file) || file;
37641
+ const rel = relative4(absPath, file) || file;
37322
37642
  const maxLen = 80;
37323
37643
  const label = rel.length > maxLen ? `...${rel.slice(-(maxLen - 3))}` : rel;
37324
37644
  spin.text = `Analyzing ${label}... (${processed}/${totalFiles})`;
@@ -37363,7 +37683,7 @@ async function runMetrics(targetPath, options) {
37363
37683
  } else {
37364
37684
  const lines = [];
37365
37685
  for (const fm of filtered) {
37366
- const rel = relative3(absPath, fm.file) || fm.file;
37686
+ const rel = relative4(absPath, fm.file) || fm.file;
37367
37687
  lines.push(rel);
37368
37688
  const byCategory = new Map;
37369
37689
  for (const m of fm.metrics) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cognium-dev",
3
- "version": "3.106.2",
3
+ "version": "3.107.0",
4
4
  "description": "Static Application Security Testing CLI for detecting security vulnerabilities via taint tracking",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -66,7 +66,7 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@cognium/project-profile-detect": "^1.1.0",
69
- "circle-ir": "^3.106.0"
69
+ "circle-ir": "^3.107.0"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/node": "^25.5.0",