@socketsecurity/cli-with-sentry 1.0.103 → 1.0.105

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.
@@ -73366,6 +73366,7 @@ async function registerAnalysisMetadataSocket(subprojectPath, workspacePath, eco
73366
73366
  }
73367
73367
  async function getLatestBucketsSocket(subprojectPath, workspacePath) {
73368
73368
  try {
73369
+ if (!process.env.SOCKET_REPO_NAME || !process.env.SOCKET_BRANCH_NAME) return void 0;
73369
73370
  const url2 = getSocketApiUrl("tier1-reachability-scan/latest-buckets");
73370
73371
  const params = {
73371
73372
  workspacePath,
@@ -73399,12 +73400,14 @@ async function getLatestBucketsSocket(subprojectPath, workspacePath) {
73399
73400
  return void 0;
73400
73401
  }
73401
73402
  }
73402
- async function registerAutofixOrUpgradePurlRun(manifestsTarHash, repositoryName, options, cliCommand) {
73403
+ async function registerAutofixOrUpgradePurlRun(manifestsTarHash, options, cliCommand) {
73403
73404
  try {
73404
73405
  const url2 = getSocketApiUrl(`orgs/${process.env.SOCKET_ORG_SLUG}/fixes/register-autofix-or-upgrade-cli-run`);
73405
73406
  const data2 = {
73406
73407
  manifestsTarHash,
73407
- repositoryName,
73408
+ // disabling rule to also catch case where process.env.SOCKET_REPO_NAME is the empty string.
73409
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
73410
+ repositoryName: process.env.SOCKET_REPO_NAME || "unknown-repo",
73408
73411
  options,
73409
73412
  cliCommand
73410
73413
  };
@@ -73587,22 +73590,22 @@ import { join as join3 } from "path";
73587
73590
  // ../utils/src/command-utils.ts
73588
73591
  import assert from "assert";
73589
73592
  import { execFile } from "child_process";
73590
- async function execAndLogOnFailure(cmd, dir, options) {
73593
+ async function execAndLogOnFailure(cmd, dir, options, logLevel = "info") {
73591
73594
  const result = await execNeverFail(cmd, dir, options);
73592
- if (result.error) logCommandOutput(result, cmd, dir);
73595
+ if (result.error) logCommandOutput(result, cmd, dir, logLevel);
73593
73596
  return !result.error;
73594
73597
  }
73595
- function logCommandOutput(cmdResult, cmd, dir) {
73598
+ function logCommandOutput(cmdResult, cmd, dir, logLevel = "info") {
73596
73599
  const { error, stdout, stderr } = cmdResult;
73597
- logger.info(error ? `Error running command: ${cmd}` : `Result of running command: ${cmd}`);
73598
- logger.info(`Directory: ${dir}`);
73600
+ logger[logLevel](error ? `Error running command: ${cmd}` : `Result of running command: ${cmd}`);
73601
+ logger[logLevel](`Directory: ${dir}`);
73599
73602
  if (error) {
73600
73603
  const em = error.message;
73601
- logger.info(`Error: ${em?.endsWith?.(`
73604
+ logger[logLevel](`Error: ${em?.endsWith?.(`
73602
73605
  ${stderr}`) ? em.slice(0, -stderr.length - 1) : em}`);
73603
73606
  }
73604
- logger.info(`stdout: ${stdout}`);
73605
- logger.info(`stderr: ${stderr}`);
73607
+ logger[logLevel](`stdout: ${stdout}`);
73608
+ logger[logLevel](`stderr: ${stderr}`);
73606
73609
  }
73607
73610
  async function execNeverFail(cmd, dir, options) {
73608
73611
  return new Promise((resolve16) => {
@@ -73747,17 +73750,18 @@ function excludeFiles(excludedDirsRoot, filesRoot, files, excludeDirs) {
73747
73750
  )
73748
73751
  ).map((f2) => relative(filesRoot, f2));
73749
73752
  }
73750
- function findParent(dir, predicate, wholePath) {
73751
- let curr = dir;
73752
- let last2 = dir;
73753
+ function* parents(dir) {
73754
+ let [curr, last2] = [dir, dir];
73753
73755
  do {
73754
- const name2 = wholePath ? curr : basename(curr);
73755
- if (predicate(name2)) return curr;
73756
- last2 = curr;
73757
- curr = resolve(curr, "..");
73756
+ yield curr;
73757
+ [last2, curr] = [curr, resolve(curr, "..")];
73758
73758
  } while (curr !== last2);
73759
73759
  return void 0;
73760
73760
  }
73761
+ function findParent(dir, predicate, wholePath) {
73762
+ for (const parent2 of parents(dir))
73763
+ if (predicate(wholePath ? parent2 : basename(parent2))) return parent2;
73764
+ }
73761
73765
  async function getFiles(dir, excludeDirs) {
73762
73766
  async function helper(currDir, arrayOfFiles) {
73763
73767
  for (const item of await readdir(currDir, { withFileTypes: true })) {
@@ -74201,6 +74205,7 @@ import { join as join4, resolve as resolve2 } from "path";
74201
74205
  import util3 from "util";
74202
74206
  var { once } = import_lodash4.default;
74203
74207
  var systemPython = once(() => execFileSync("which", ["python"], { encoding: "utf8" }).trim());
74208
+ var hasPyenv = once(async () => !(await execNeverFail("which pyenv")).error);
74204
74209
  async function getPythonVersion(executable) {
74205
74210
  return runCommandResolveStdOut([executable, "-SIc", `import sys; print(*sys.version_info[:3], sep='.')`]);
74206
74211
  }
@@ -74231,11 +74236,9 @@ var PythonVersionsManager = class _PythonVersionsManager {
74231
74236
  // Extracts the python version specifier from the workspace and returns it as an array of semver parts.
74232
74237
  async getPythonSpecifier(workspacePath, checkPyProject = true) {
74233
74238
  const absPath = resolve2(this.projectDir, workspacePath);
74234
- const pyenvOrigin = await runCommandResolveStdOut("pyenv version-origin", absPath);
74235
- const pyenvRoot = process.env.PYENV_ROOT ?? await runCommandResolveStdOut("pyenv root");
74236
- if (pyenvOrigin !== join4(pyenvRoot, "version"))
74239
+ for (const parent2 of parents(absPath))
74237
74240
  try {
74238
- return [(await readFile3(pyenvOrigin, "utf-8")).split("\n")[0].trim()];
74241
+ return [(await readFile3(join4(parent2, ".python-version"), "utf-8")).split("\n")[0].trim()];
74239
74242
  } catch (e) {
74240
74243
  if (e.code !== "ENOENT") logger.warn("Failed to read python version file with error", e);
74241
74244
  }
@@ -74283,7 +74286,12 @@ var PythonVersionsManager = class _PythonVersionsManager {
74283
74286
  if (semVerSpec) {
74284
74287
  const systemVer = await getPythonVersion(systemPython());
74285
74288
  if (versionMatchesSemverParts(systemVer, semVerSpec)) return systemPython();
74286
- }
74289
+ if (!await hasPyenv())
74290
+ throw Error(
74291
+ `System Python (${systemVer}) does not satisfy the specifier '${semVerSpec.join(", ")}'. A matching interpreter can automatically be installed if 'pyenv' is available.`
74292
+ );
74293
+ } else if (!await hasPyenv() || _PythonVersionsManager.getGlobalPythonVersion() === "system")
74294
+ return systemPython();
74287
74295
  return resolve2(await _PythonVersionsManager.getPythonPrefixMatchingSpecifier(semVerSpec), "bin", "python");
74288
74296
  }
74289
74297
  // Throws an error if the python version is not installed.
@@ -77166,7 +77174,7 @@ __export(traversing_exports, {
77166
77174
  nextUntil: () => nextUntil,
77167
77175
  not: () => not,
77168
77176
  parent: () => parent,
77169
- parents: () => parents,
77177
+ parents: () => parents2,
77170
77178
  parentsUntil: () => parentsUntil,
77171
77179
  prev: () => prev,
77172
77180
  prevAll: () => prevAll,
@@ -78428,7 +78436,7 @@ function _removeDuplicates(elems) {
78428
78436
  return Array.from(new Set(elems));
78429
78437
  }
78430
78438
  var parent = _singleMatcher(({ parent: parent2 }) => parent2 && !isDocument(parent2) ? parent2 : null, _removeDuplicates);
78431
- var parents = _matcher((elem) => {
78439
+ var parents2 = _matcher((elem) => {
78432
78440
  const matched = [];
78433
78441
  while (elem.parent && !isDocument(elem.parent)) {
78434
78442
  matched.push(elem.parent);
@@ -96448,9 +96456,9 @@ var PythonCodeAwareVulnerabilityScanner = class {
96448
96456
  const packagesToExclude = heuristic.getPackagesToExcludeFromAnalysis?.(vulns);
96449
96457
  const packagesToInstall = uniqBy(preInstalledDepInfos.filter((n) => !packagesToExclude?.has(n.packageName)), "packageName");
96450
96458
  if (!await this.tryUsingPreinstalledVirtualEnv(packagesToInstall)) {
96451
- logger.info("Setting up virtual environment");
96459
+ logger.info(`Setting up virtual environment`);
96452
96460
  await this.prepareVirtualEnv(packagesToInstall);
96453
- logger.debug("Done setting up virtual environment");
96461
+ logger.info("Done setting up virtual environment");
96454
96462
  }
96455
96463
  }
96456
96464
  async runAnalysis(vulns, heuristic, analyzesAllVulns) {
@@ -96512,7 +96520,7 @@ runpy.run_module("mambalade", alter_sys=True)
96512
96520
  "--",
96513
96521
  ...filesToAnalyze
96514
96522
  ];
96515
- logger.info(`Running mambalade on ${filesToAnalyze.length} files for vulnerabilities:
96523
+ logger.debug(`Running mambalade on ${filesToAnalyze.length} files for vulnerabilities:
96516
96524
  ${vulnAccPaths.join("\n")}`);
96517
96525
  logger.debug(`Running python executable: ${pythonExecutable}`);
96518
96526
  logger.debug(`With args: ${mambaladeArgs.slice(1).join(" ")}`);
@@ -96521,7 +96529,7 @@ ${vulnAccPaths.join("\n")}`);
96521
96529
  logger.debug("Done running mambalade");
96522
96530
  const errors = stderr.split("\n").filter((line) => line.startsWith("ERROR:") && !/^ERROR: Excluded distribution/.test(line));
96523
96531
  if (errors.length > 0)
96524
- logger.info(`Error messages from mambalade:
96532
+ logger.debug(`Error messages from mambalade:
96525
96533
  ${errors.join("\n")}`);
96526
96534
  const result = JSON.parse(await readFile10(vulnsOutputFile, "utf-8"));
96527
96535
  logger.debug("Analysis result:", JSON.stringify(result, null, 2));
@@ -96546,8 +96554,8 @@ ${errors.join("\n")}`);
96546
96554
  packageInstallationStats: this.virtualEnvInfo.packageInstallationStats
96547
96555
  // Including stats in all analysis diagnostics since we might discard the first one that actually installs it due to analysis timeout.
96548
96556
  };
96549
- logger.info("Analysis diagnostics:");
96550
- logger.info(JSON.stringify(omit(diagnostics, this.numberAnalysesRun === 0 ? [] : ["packageInstallationStats"]), null, 2));
96557
+ logger.debug("Analysis diagnostics:");
96558
+ logger.debug(JSON.stringify(omit(diagnostics, this.numberAnalysesRun === 0 ? [] : ["packageInstallationStats"]), null, 2));
96551
96559
  return {
96552
96560
  type: "success",
96553
96561
  diagnostics,
@@ -96592,21 +96600,25 @@ ${msg}`;
96592
96600
  rootWorkingDir: projectTmpDir,
96593
96601
  reachabilityAnalysisOptions: options
96594
96602
  }, projectTmpDir);
96595
- await scanner.prepareVirtualEnv([]);
96596
- const sitePackagesDir = scanner.virtualEnvInfo.virtualEnvPathToSitePackages;
96597
- for (const dep of dependencies) {
96598
- const dependencyDir = join20(sitePackagesDir, basename9(dep));
96599
- logger.info(`Copying ${dep} to ${dependencyDir}`);
96600
- await cp5(dep, dependencyDir, { recursive: true });
96601
- fileMappings.set(dependencyDir, dep);
96602
- }
96603
- const result = await scanner.runAnalysis([vuln], MambaladeHeuristics.ALL_PACKAGES, false);
96604
- if (result.type === "error")
96605
- return { error: result.message, terminatedEarly: true };
96606
- return {
96607
- detectedOccurrences: transformSourceLocations2(app, fileMappings, result.computeDetectedOccurrences({ ...vuln, url: "" })),
96608
- terminatedEarly: result.terminatedEarly
96609
- };
96603
+ try {
96604
+ await scanner.prepareVirtualEnv([]);
96605
+ const sitePackagesDir = scanner.virtualEnvInfo.virtualEnvPathToSitePackages;
96606
+ for (const dep of dependencies) {
96607
+ const dependencyDir = join20(sitePackagesDir, basename9(dep));
96608
+ logger.info(`Copying ${dep} to ${dependencyDir}`);
96609
+ await cp5(dep, dependencyDir, { recursive: true });
96610
+ fileMappings.set(dependencyDir, dep);
96611
+ }
96612
+ const result = await scanner.runAnalysis([vuln], MambaladeHeuristics.ALL_PACKAGES, false);
96613
+ if (result.type === "error")
96614
+ return { error: result.message, terminatedEarly: true };
96615
+ return {
96616
+ detectedOccurrences: transformSourceLocations2(app, fileMappings, result.computeDetectedOccurrences({ ...vuln, url: "" })),
96617
+ terminatedEarly: result.terminatedEarly
96618
+ };
96619
+ } finally {
96620
+ await scanner.cleanup();
96621
+ }
96610
96622
  });
96611
96623
  }
96612
96624
  static async runOnDependencyChain(chain, vuln, options) {
@@ -96628,7 +96640,7 @@ ${msg}`;
96628
96640
  const candidate = findBestWheel(packageName, version3, meta);
96629
96641
  if (candidate) {
96630
96642
  const filename = candidate.url.split("/").at(-1);
96631
- if (await downloadFile(candidate.url, join20(tmpDir, filename)) && await execAndLogOnFailure(["unzip", filename], tmpDir))
96643
+ if (await downloadFile(candidate.url, join20(tmpDir, filename)) && await execAndLogOnFailure(["unzip", filename], tmpDir, void 0, "debug"))
96632
96644
  return;
96633
96645
  }
96634
96646
  await exec(cmdt`uv pip install --python-platform ${uvPythonPlatform} --target ${tmpDir} --no-deps ${packageName}==${version3}`);
@@ -96677,6 +96689,8 @@ ${msg}`;
96677
96689
  }
96678
96690
  // public for testing only
96679
96691
  async prepareVirtualEnv(packages) {
96692
+ if (!await hasUv())
96693
+ throw new Error("uv (https://docs.astral.sh/uv/) is missing, but is required for Python analysis");
96680
96694
  const tmpDir = await createTmpDirectory("coana-python-analysis-venv");
96681
96695
  const virtualEnvFolder = join20(tmpDir, ".venv");
96682
96696
  const pythonExecutable = await this.vm.getPythonExecutableForWorkspace(this.projectDir, false);
@@ -96709,12 +96723,12 @@ ${msg}`;
96709
96723
  return true;
96710
96724
  const filename = candidate.url.split("/").at(-1);
96711
96725
  if (await downloadFile(candidate.url, join20(tmpDir, filename)) && await execAndLogOnFailure(cmdt`${uvTool(pythonExecutable)} --from installer==0.7.0 python -m installer
96712
- --no-compile-bytecode --prefix .venv ${filename}`, tmpDir)) {
96726
+ --no-compile-bytecode --prefix .venv ${filename}`, tmpDir, void 0, "debug")) {
96713
96727
  installStats.installedUsingSpecializedInstallCommand.push(packageName);
96714
96728
  return false;
96715
96729
  }
96716
96730
  } catch (e) {
96717
- logger.info(`Failed to construct specialized install command for ${packageName}==${version3}`, e);
96731
+ logger.debug(`Failed to construct specialized install command for ${packageName}==${version3}`, e);
96718
96732
  }
96719
96733
  return true;
96720
96734
  }, 4);
@@ -96723,13 +96737,7 @@ ${msg}`;
96723
96737
  const installPipDeps = once3(async () => exec([...uvInstallBase, "pip", "wheel"]));
96724
96738
  for (const { packageName, version: version3, requirement } of failingPackages) {
96725
96739
  const requirementToInstall = requirement ?? `${packageName}==${version3}`;
96726
- let success = await execAndLogOnFailure([
96727
- ...uvInstallBase,
96728
- "--no-deps",
96729
- "--no-binary",
96730
- packageName,
96731
- requirementToInstall
96732
- ]);
96740
+ let success = await execAndLogOnFailure([...uvInstallBase, "--no-deps", "--no-binary", packageName, requirementToInstall], void 0, void 0, "debug");
96733
96741
  if (!success) {
96734
96742
  await installPipDeps();
96735
96743
  success = await execAndLogOnFailure(
@@ -96738,7 +96746,9 @@ ${msg}`;
96738
96746
  cmdt`.venv/bin/python -m pip
96739
96747
  --no-input --require-virtualenv --disable-pip-version-check --no-cache-dir --isolated install
96740
96748
  --no-deps --ignore-requires-python --no-compile --no-binary ${packageName} ${requirementToInstall}`,
96741
- tmpDir
96749
+ tmpDir,
96750
+ void 0,
96751
+ "debug"
96742
96752
  );
96743
96753
  }
96744
96754
  (success ? installStats.installedWithoutOnlyBinary : installStats.failedToInstall).push(packageName);
@@ -96829,7 +96839,7 @@ async function getPythonInterpreter() {
96829
96839
  }
96830
96840
  async function setupMambalade() {
96831
96841
  const venvDir = await createTmpDirectory("mambalade-venv");
96832
- logger.info("Creating Mambalade virtual environment");
96842
+ logger.debug("Creating Mambalade virtual environment");
96833
96843
  const pythonInterpreter = await getPythonInterpreter();
96834
96844
  await exec(cmdt`${pythonInterpreter} -SIm venv ${venvDir}`);
96835
96845
  const mambaladeWheelsPath = join20(COANA_REPOS_PATH(), "mambalade", "dist");
@@ -96837,11 +96847,12 @@ async function setupMambalade() {
96837
96847
  const mambaladeWheels = wheelFiles.filter((f2) => f2.endsWith(".whl")).map((f2) => join20(mambaladeWheelsPath, f2));
96838
96848
  if (!mambaladeWheels.length)
96839
96849
  throw new Error(`No mambalade wheel files found in ${mambaladeWheelsPath}`);
96840
- logger.info(`Installing mambalade wheels: ${mambaladeWheels.join(", ")}`);
96850
+ logger.debug(`Installing mambalade wheels: ${mambaladeWheels.join(", ")}`);
96841
96851
  await exec(cmdt`${venvDir}/bin/pip install --no-deps ${mambaladeWheels}`);
96842
- logger.info("Mambalade virtual environment setup complete");
96852
+ logger.debug("Mambalade virtual environment setup complete");
96843
96853
  return venvDir;
96844
96854
  }
96855
+ var hasUv = once3(async () => !(await execNeverFail("which uv")).error);
96845
96856
 
96846
96857
  // dist/whole-program-code-aware-vulnerability-scanner/python/phantom-deps.js
96847
96858
  var { uniq: uniq8 } = import_lodash15.default;
@@ -96937,8 +96948,7 @@ var PipAnalyzer = class {
96937
96948
  this.heuristic = MambaladeHeuristics.createOnlyVulnPathPackagesHeuristic(this.preInstalledDepInfos);
96938
96949
  }
96939
96950
  prepareScanner = once4(async () => {
96940
- const { vulnerabilities } = this.state;
96941
- await this.scanner.prepareDependencies(this.preInstalledDepInfos, vulnerabilities.filter((v) => Array.isArray(v.vulnerabilityAccessPaths)), this.heuristic);
96951
+ await this.scanner.prepareDependencies(this.preInstalledDepInfos, this.state.vulnerabilities.filter((v) => Array.isArray(v.vulnerabilityAccessPaths)), this.heuristic);
96942
96952
  return this.scanner;
96943
96953
  });
96944
96954
  async runPhantomDependencyAnalysis() {
@@ -96970,14 +96980,13 @@ function getPreInstalledDepInfos(workspaceData) {
96970
96980
  }));
96971
96981
  } else {
96972
96982
  workspaceData.type;
96973
- const artifactsWithVersion = workspaceData.data.artifacts.filter((a2) => {
96983
+ return workspaceData.data.artifacts.filter((a2) => {
96974
96984
  if (!a2.version) {
96975
96985
  logger.warn(`Artifact ${a2.name} has no version information`);
96976
96986
  return false;
96977
96987
  }
96978
96988
  return true;
96979
- });
96980
- return artifactsWithVersion.map((a2) => ({ packageName: a2.name, version: a2.version }));
96989
+ }).map(({ name: name2, version: version3 }) => ({ packageName: name2, version: version3 }));
96981
96990
  }
96982
96991
  }
96983
96992
 
@@ -96985,11 +96994,12 @@ function getPreInstalledDepInfos(workspaceData) {
96985
96994
  var { groupBy } = import_lodash17.default;
96986
96995
  var CLI_VERSION_TO_USE_CACHING_FROM = { PIP: "14.9.15" };
96987
96996
  var CLI_VERSION_TO_USE_CACHING_FROM_DEFAULT = "13.16.6";
96997
+ var SOCKET_MODE = process.env.SOCKET_MODE === "true";
96988
96998
  function assertVulnChainDetails(vs) {
96989
96999
  assert8(vs.every((v) => v.vulnChainDetails));
96990
97000
  }
96991
97001
  var apiKey = COANA_API_KEY ? { type: "present", value: COANA_API_KEY } : { type: "missing" };
96992
- var dashboardAPI = new DashboardAPI(process.env.SOCKET_MODE === "true", process.env.DISABLE_ANALYTICS_SHARING === "true");
97002
+ var dashboardAPI = new DashboardAPI(SOCKET_MODE, process.env.DISABLE_ANALYTICS_SHARING === "true");
96993
97003
  async function analyzeWithHeuristics(state, vulns, heuristicsInOrder, doNotRecomputeForTimeoutsAndAborts, codeAwareScanner, analysisMetadataCollector, statusUpdater) {
96994
97004
  logger.debug("Starting analyzeWithHeuristics");
96995
97005
  assertVulnChainDetails(vulns);
@@ -97077,7 +97087,7 @@ async function analyzeWithHeuristics(state, vulns, heuristicsInOrder, doNotRecom
97077
97087
  }
97078
97088
  }
97079
97089
  async function getBucketsBasedOnPreviousResults() {
97080
- if (process.env.SOCKET_MODE !== "true" && (!COANA_REPORT_ID || apiKey.type === "missing"))
97090
+ if (!SOCKET_MODE && (!COANA_REPORT_ID || apiKey.type === "missing"))
97081
97091
  return void 0;
97082
97092
  const bucketsFromLastAnalysisAndCliVersion = await dashboardAPI.getBucketsForLastReport(relative5(state.rootWorkingDir, state.subprojectDir) || ".", state.workspacePath, vulnerabilities[0].ecosystem ?? "NPM", COANA_REPORT_ID, apiKey);
97083
97093
  if (!bucketsFromLastAnalysisAndCliVersion)
@@ -97168,6 +97178,7 @@ async function analyzeWithHeuristics(state, vulns, heuristicsInOrder, doNotRecom
97168
97178
  const enqueueWithoutSplitting = !allowSplitInBuckets && initialBucketContainingAllVulns && !state.reachabilityAnalysisOptions.timeoutInSeconds;
97169
97179
  await sendErrorAnalysisMetadata(result.message, !allowSplitInBuckets && isLastHeuristic(bucket.heuristic.name) && !enqueueWithoutSplitting, !allowSplitInBuckets);
97170
97180
  if (enqueueWithoutSplitting) {
97181
+ logger.info("Analysis failed, retrying different configuration.");
97171
97182
  enqueueBucket(vulnDepIdentifiers);
97172
97183
  return;
97173
97184
  }
@@ -97177,6 +97188,7 @@ async function analyzeWithHeuristics(state, vulns, heuristicsInOrder, doNotRecom
97177
97188
  }
97178
97189
  }
97179
97190
  if (allowSplitInBuckets) {
97191
+ logger.info("Analysis failed, rerunning analysis multiple times with fewer vulnerabilities per run.");
97180
97192
  const middle = Math.floor(vulnDepIdentifiers.length / 2);
97181
97193
  enqueueBucket(vulnDepIdentifiers.slice(0, middle));
97182
97194
  enqueueBucket(vulnDepIdentifiers.slice(middle));
@@ -97279,9 +97291,6 @@ function getHeuristicFromName(state, heuristicName, ecosystem) {
97279
97291
  if (ecosystem === "NPM") {
97280
97292
  return heuristics[heuristicName];
97281
97293
  } else if (ecosystem === "PIP") {
97282
- if (state.workspaceData.type !== "coana") {
97283
- throw new Error("MambaladeHeuristics only supports Coana data for analysis");
97284
- }
97285
97294
  if (heuristicName in MambaladeHeuristics)
97286
97295
  return MambaladeHeuristics[heuristicName];
97287
97296
  else if (heuristicName === "ONLY_VULN_PATH_PACKAGES") {
@@ -97314,6 +97323,13 @@ function augmentVulnsWithDetectedOccurrences(vulns, codeAwareScanner, heuristic,
97314
97323
  for (const v of vulns) {
97315
97324
  const detectedOccurrences = result.computeDetectedOccurrences(v);
97316
97325
  if (Array.isArray(detectedOccurrences) ? detectedOccurrences.length === 0 : detectedOccurrences.stacks.length === 0) {
97326
+ if (SOCKET_MODE && result.terminatedEarly && !result.reachedDependencies && Object.keys(v.vulnChainDetails.transitiveDependencies).length > 1) {
97327
+ v.results = {
97328
+ type: "analysisError",
97329
+ message: "Analysis terminated early and did not reach any dependencies"
97330
+ };
97331
+ continue;
97332
+ }
97317
97333
  const packageOnPathFailedToInstall = Object.values(v.vulnChainDetails.transitiveDependencies).map((p) => p.packageName).find((p) => packagesFailedToInstall.includes(p));
97318
97334
  if (packageOnPathFailedToInstall) {
97319
97335
  v.results = {
@@ -97517,16 +97533,16 @@ function canDismissVulnerability(phantomDependencies, vulnChainDetails) {
97517
97533
  const recHelper = (nodeIdentifier, depth) => {
97518
97534
  if (depth === 0)
97519
97535
  return void 0;
97520
- const parents2 = parentsMap.get(nodeIdentifier).filter((parent2) => parent2 !== ROOT_NODE_STR);
97536
+ const parents3 = parentsMap.get(nodeIdentifier).filter((parent2) => parent2 !== ROOT_NODE_STR);
97521
97537
  const thisReachabilityPrecomp = nodeIdentifier === vulnNodeIdentifier ? "Reachable" : vulnChainDetails.transitiveDependencies[nodeIdentifier].reachabilityPrecomp;
97522
97538
  if (!thisReachabilityPrecomp)
97523
97539
  return void 0;
97524
97540
  const thisMayReachVulnerableNode = ["Reachable", "Unknown"].includes(thisReachabilityPrecomp);
97525
- if (parents2.length === 0 && thisMayReachVulnerableNode) {
97541
+ if (parents3.length === 0 && thisMayReachVulnerableNode) {
97526
97542
  canDismiss = false;
97527
97543
  }
97528
- if (parents2) {
97529
- const parentsReachabilityPrecomp = parents2.map((p) => recHelper(p, depth - 1));
97544
+ if (parents3) {
97545
+ const parentsReachabilityPrecomp = parents3.map((p) => recHelper(p, depth - 1));
97530
97546
  if (parentsReachabilityPrecomp.some((reachabilityPrecomp) => !reachabilityPrecomp) && thisMayReachVulnerableNode) {
97531
97547
  canDismiss = false;
97532
97548
  }
@@ -97555,6 +97571,7 @@ var dashboardAPI2 = new DashboardAPI(process.env.SOCKET_MODE === "true", process
97555
97571
  async function runReachabilityAnalysis(state) {
97556
97572
  const projectDir = resolve15(state.subprojectDir, state.workspacePath);
97557
97573
  const ecosystem = state.workspaceData.data.type;
97574
+ logger.info(`Preparing for running reachability analysis for project at "${relative6(state.rootWorkingDir, projectDir) || "."}" (${ecosystem})`);
97558
97575
  const constructor = ecosystemAnalyzer[ecosystem];
97559
97576
  if (!constructor)
97560
97577
  throw Error(`No analyzer associated with ecosystem ${ecosystem}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@socketsecurity/cli-with-sentry",
3
- "version": "1.0.103",
3
+ "version": "1.0.105",
4
4
  "description": "CLI for Socket.dev, includes Sentry error handling, otherwise identical to the regular `socket` package",
5
5
  "homepage": "https://github.com/SocketDev/socket-cli",
6
6
  "license": "MIT",
@@ -86,7 +86,7 @@
86
86
  "@babel/preset-typescript": "7.27.1",
87
87
  "@babel/runtime": "7.28.3",
88
88
  "@biomejs/biome": "2.2.2",
89
- "@coana-tech/cli": "14.12.3",
89
+ "@coana-tech/cli": "14.12.10",
90
90
  "@cyclonedx/cdxgen": "11.6.0",
91
91
  "@dotenvx/dotenvx": "1.49.0",
92
92
  "@eslint/compat": "1.3.2",
@@ -114,7 +114,7 @@
114
114
  "@socketregistry/packageurl-js": "1.0.9",
115
115
  "@socketsecurity/config": "3.0.1",
116
116
  "@socketsecurity/registry": "1.0.275",
117
- "@socketsecurity/sdk": "1.4.79",
117
+ "@socketsecurity/sdk": "1.4.80",
118
118
  "@types/blessed": "0.1.25",
119
119
  "@types/cmd-shim": "5.0.2",
120
120
  "@types/js-yaml": "4.0.9",