@coana-tech/cli 15.0.12 → 15.1.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/cli.mjs CHANGED
@@ -16020,9 +16020,9 @@ var require_picomatch = __commonJS({
16020
16020
  var utils = require_utils();
16021
16021
  var constants4 = require_constants();
16022
16022
  var isObject2 = (val2) => val2 && typeof val2 === "object" && !Array.isArray(val2);
16023
- var picomatch13 = (glob2, options, returnState = false) => {
16023
+ var picomatch12 = (glob2, options, returnState = false) => {
16024
16024
  if (Array.isArray(glob2)) {
16025
- const fns = glob2.map((input) => picomatch13(input, options, returnState));
16025
+ const fns = glob2.map((input) => picomatch12(input, options, returnState));
16026
16026
  const arrayMatcher = (str) => {
16027
16027
  for (const isMatch4 of fns) {
16028
16028
  const state2 = isMatch4(str);
@@ -16038,16 +16038,16 @@ var require_picomatch = __commonJS({
16038
16038
  }
16039
16039
  const opts = options || {};
16040
16040
  const posix3 = opts.windows;
16041
- const regex = isState ? picomatch13.compileRe(glob2, options) : picomatch13.makeRe(glob2, options, false, true);
16041
+ const regex = isState ? picomatch12.compileRe(glob2, options) : picomatch12.makeRe(glob2, options, false, true);
16042
16042
  const state = regex.state;
16043
16043
  delete regex.state;
16044
16044
  let isIgnored = () => false;
16045
16045
  if (opts.ignore) {
16046
16046
  const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };
16047
- isIgnored = picomatch13(opts.ignore, ignoreOpts, returnState);
16047
+ isIgnored = picomatch12(opts.ignore, ignoreOpts, returnState);
16048
16048
  }
16049
16049
  const matcher = (input, returnObject = false) => {
16050
- const { isMatch: isMatch4, match: match2, output } = picomatch13.test(input, regex, options, { glob: glob2, posix: posix3 });
16050
+ const { isMatch: isMatch4, match: match2, output } = picomatch12.test(input, regex, options, { glob: glob2, posix: posix3 });
16051
16051
  const result = { glob: glob2, state, regex, posix: posix3, input, output, match: match2, isMatch: isMatch4 };
16052
16052
  if (typeof opts.onResult === "function") {
16053
16053
  opts.onResult(result);
@@ -16073,7 +16073,7 @@ var require_picomatch = __commonJS({
16073
16073
  }
16074
16074
  return matcher;
16075
16075
  };
16076
- picomatch13.test = (input, regex, options, { glob: glob2, posix: posix3 } = {}) => {
16076
+ picomatch12.test = (input, regex, options, { glob: glob2, posix: posix3 } = {}) => {
16077
16077
  if (typeof input !== "string") {
16078
16078
  throw new TypeError("Expected input to be a string");
16079
16079
  }
@@ -16090,24 +16090,24 @@ var require_picomatch = __commonJS({
16090
16090
  }
16091
16091
  if (match2 === false || opts.capture === true) {
16092
16092
  if (opts.matchBase === true || opts.basename === true) {
16093
- match2 = picomatch13.matchBase(input, regex, options, posix3);
16093
+ match2 = picomatch12.matchBase(input, regex, options, posix3);
16094
16094
  } else {
16095
16095
  match2 = regex.exec(output);
16096
16096
  }
16097
16097
  }
16098
16098
  return { isMatch: Boolean(match2), match: match2, output };
16099
16099
  };
16100
- picomatch13.matchBase = (input, glob2, options) => {
16101
- const regex = glob2 instanceof RegExp ? glob2 : picomatch13.makeRe(glob2, options);
16100
+ picomatch12.matchBase = (input, glob2, options) => {
16101
+ const regex = glob2 instanceof RegExp ? glob2 : picomatch12.makeRe(glob2, options);
16102
16102
  return regex.test(utils.basename(input));
16103
16103
  };
16104
- picomatch13.isMatch = (str, patterns, options) => picomatch13(patterns, options)(str);
16105
- picomatch13.parse = (pattern, options) => {
16106
- if (Array.isArray(pattern)) return pattern.map((p3) => picomatch13.parse(p3, options));
16104
+ picomatch12.isMatch = (str, patterns, options) => picomatch12(patterns, options)(str);
16105
+ picomatch12.parse = (pattern, options) => {
16106
+ if (Array.isArray(pattern)) return pattern.map((p3) => picomatch12.parse(p3, options));
16107
16107
  return parse16(pattern, { ...options, fastpaths: false });
16108
16108
  };
16109
- picomatch13.scan = (input, options) => scan(input, options);
16110
- picomatch13.compileRe = (state, options, returnOutput = false, returnState = false) => {
16109
+ picomatch12.scan = (input, options) => scan(input, options);
16110
+ picomatch12.compileRe = (state, options, returnOutput = false, returnState = false) => {
16111
16111
  if (returnOutput === true) {
16112
16112
  return state.output;
16113
16113
  }
@@ -16118,13 +16118,13 @@ var require_picomatch = __commonJS({
16118
16118
  if (state && state.negated === true) {
16119
16119
  source = `^(?!${source}).*$`;
16120
16120
  }
16121
- const regex = picomatch13.toRegex(source, options);
16121
+ const regex = picomatch12.toRegex(source, options);
16122
16122
  if (returnState === true) {
16123
16123
  regex.state = state;
16124
16124
  }
16125
16125
  return regex;
16126
16126
  };
16127
- picomatch13.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
16127
+ picomatch12.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
16128
16128
  if (!input || typeof input !== "string") {
16129
16129
  throw new TypeError("Expected a non-empty string");
16130
16130
  }
@@ -16135,9 +16135,9 @@ var require_picomatch = __commonJS({
16135
16135
  if (!parsed.output) {
16136
16136
  parsed = parse16(input, options);
16137
16137
  }
16138
- return picomatch13.compileRe(parsed, options, returnOutput, returnState);
16138
+ return picomatch12.compileRe(parsed, options, returnOutput, returnState);
16139
16139
  };
16140
- picomatch13.toRegex = (source, options) => {
16140
+ picomatch12.toRegex = (source, options) => {
16141
16141
  try {
16142
16142
  const opts = options || {};
16143
16143
  return new RegExp(source, opts.flags || (opts.nocase ? "i" : ""));
@@ -16146,8 +16146,8 @@ var require_picomatch = __commonJS({
16146
16146
  return /$^/;
16147
16147
  }
16148
16148
  };
16149
- picomatch13.constants = constants4;
16150
- module2.exports = picomatch13;
16149
+ picomatch12.constants = constants4;
16150
+ module2.exports = picomatch12;
16151
16151
  }
16152
16152
  });
16153
16153
 
@@ -16157,14 +16157,14 @@ var require_picomatch2 = __commonJS({
16157
16157
  "use strict";
16158
16158
  var pico = require_picomatch();
16159
16159
  var utils = require_utils();
16160
- function picomatch13(glob2, options, returnState = false) {
16160
+ function picomatch12(glob2, options, returnState = false) {
16161
16161
  if (options && (options.windows === null || options.windows === void 0)) {
16162
16162
  options = { ...options, windows: utils.isWindows() };
16163
16163
  }
16164
16164
  return pico(glob2, options, returnState);
16165
16165
  }
16166
- Object.assign(picomatch13, pico);
16167
- module2.exports = picomatch13;
16166
+ Object.assign(picomatch12, pico);
16167
+ module2.exports = picomatch12;
16168
16168
  }
16169
16169
  });
16170
16170
 
@@ -39550,9 +39550,9 @@ var require_picomatch3 = __commonJS({
39550
39550
  var utils = require_utils3();
39551
39551
  var constants4 = require_constants3();
39552
39552
  var isObject2 = (val2) => val2 && typeof val2 === "object" && !Array.isArray(val2);
39553
- var picomatch13 = (glob2, options, returnState = false) => {
39553
+ var picomatch12 = (glob2, options, returnState = false) => {
39554
39554
  if (Array.isArray(glob2)) {
39555
- const fns = glob2.map((input) => picomatch13(input, options, returnState));
39555
+ const fns = glob2.map((input) => picomatch12(input, options, returnState));
39556
39556
  const arrayMatcher = (str) => {
39557
39557
  for (const isMatch4 of fns) {
39558
39558
  const state2 = isMatch4(str);
@@ -39568,16 +39568,16 @@ var require_picomatch3 = __commonJS({
39568
39568
  }
39569
39569
  const opts = options || {};
39570
39570
  const posix3 = utils.isWindows(options);
39571
- const regex = isState ? picomatch13.compileRe(glob2, options) : picomatch13.makeRe(glob2, options, false, true);
39571
+ const regex = isState ? picomatch12.compileRe(glob2, options) : picomatch12.makeRe(glob2, options, false, true);
39572
39572
  const state = regex.state;
39573
39573
  delete regex.state;
39574
39574
  let isIgnored = () => false;
39575
39575
  if (opts.ignore) {
39576
39576
  const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };
39577
- isIgnored = picomatch13(opts.ignore, ignoreOpts, returnState);
39577
+ isIgnored = picomatch12(opts.ignore, ignoreOpts, returnState);
39578
39578
  }
39579
39579
  const matcher = (input, returnObject = false) => {
39580
- const { isMatch: isMatch4, match: match2, output } = picomatch13.test(input, regex, options, { glob: glob2, posix: posix3 });
39580
+ const { isMatch: isMatch4, match: match2, output } = picomatch12.test(input, regex, options, { glob: glob2, posix: posix3 });
39581
39581
  const result = { glob: glob2, state, regex, posix: posix3, input, output, match: match2, isMatch: isMatch4 };
39582
39582
  if (typeof opts.onResult === "function") {
39583
39583
  opts.onResult(result);
@@ -39603,7 +39603,7 @@ var require_picomatch3 = __commonJS({
39603
39603
  }
39604
39604
  return matcher;
39605
39605
  };
39606
- picomatch13.test = (input, regex, options, { glob: glob2, posix: posix3 } = {}) => {
39606
+ picomatch12.test = (input, regex, options, { glob: glob2, posix: posix3 } = {}) => {
39607
39607
  if (typeof input !== "string") {
39608
39608
  throw new TypeError("Expected input to be a string");
39609
39609
  }
@@ -39620,24 +39620,24 @@ var require_picomatch3 = __commonJS({
39620
39620
  }
39621
39621
  if (match2 === false || opts.capture === true) {
39622
39622
  if (opts.matchBase === true || opts.basename === true) {
39623
- match2 = picomatch13.matchBase(input, regex, options, posix3);
39623
+ match2 = picomatch12.matchBase(input, regex, options, posix3);
39624
39624
  } else {
39625
39625
  match2 = regex.exec(output);
39626
39626
  }
39627
39627
  }
39628
39628
  return { isMatch: Boolean(match2), match: match2, output };
39629
39629
  };
39630
- picomatch13.matchBase = (input, glob2, options, posix3 = utils.isWindows(options)) => {
39631
- const regex = glob2 instanceof RegExp ? glob2 : picomatch13.makeRe(glob2, options);
39630
+ picomatch12.matchBase = (input, glob2, options, posix3 = utils.isWindows(options)) => {
39631
+ const regex = glob2 instanceof RegExp ? glob2 : picomatch12.makeRe(glob2, options);
39632
39632
  return regex.test(path9.basename(input));
39633
39633
  };
39634
- picomatch13.isMatch = (str, patterns, options) => picomatch13(patterns, options)(str);
39635
- picomatch13.parse = (pattern, options) => {
39636
- if (Array.isArray(pattern)) return pattern.map((p3) => picomatch13.parse(p3, options));
39634
+ picomatch12.isMatch = (str, patterns, options) => picomatch12(patterns, options)(str);
39635
+ picomatch12.parse = (pattern, options) => {
39636
+ if (Array.isArray(pattern)) return pattern.map((p3) => picomatch12.parse(p3, options));
39637
39637
  return parse16(pattern, { ...options, fastpaths: false });
39638
39638
  };
39639
- picomatch13.scan = (input, options) => scan(input, options);
39640
- picomatch13.compileRe = (state, options, returnOutput = false, returnState = false) => {
39639
+ picomatch12.scan = (input, options) => scan(input, options);
39640
+ picomatch12.compileRe = (state, options, returnOutput = false, returnState = false) => {
39641
39641
  if (returnOutput === true) {
39642
39642
  return state.output;
39643
39643
  }
@@ -39648,13 +39648,13 @@ var require_picomatch3 = __commonJS({
39648
39648
  if (state && state.negated === true) {
39649
39649
  source = `^(?!${source}).*$`;
39650
39650
  }
39651
- const regex = picomatch13.toRegex(source, options);
39651
+ const regex = picomatch12.toRegex(source, options);
39652
39652
  if (returnState === true) {
39653
39653
  regex.state = state;
39654
39654
  }
39655
39655
  return regex;
39656
39656
  };
39657
- picomatch13.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
39657
+ picomatch12.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
39658
39658
  if (!input || typeof input !== "string") {
39659
39659
  throw new TypeError("Expected a non-empty string");
39660
39660
  }
@@ -39665,9 +39665,9 @@ var require_picomatch3 = __commonJS({
39665
39665
  if (!parsed.output) {
39666
39666
  parsed = parse16(input, options);
39667
39667
  }
39668
- return picomatch13.compileRe(parsed, options, returnOutput, returnState);
39668
+ return picomatch12.compileRe(parsed, options, returnOutput, returnState);
39669
39669
  };
39670
- picomatch13.toRegex = (source, options) => {
39670
+ picomatch12.toRegex = (source, options) => {
39671
39671
  try {
39672
39672
  const opts = options || {};
39673
39673
  return new RegExp(source, opts.flags || (opts.nocase ? "i" : ""));
@@ -39676,8 +39676,8 @@ var require_picomatch3 = __commonJS({
39676
39676
  return /$^/;
39677
39677
  }
39678
39678
  };
39679
- picomatch13.constants = constants4;
39680
- module2.exports = picomatch13;
39679
+ picomatch12.constants = constants4;
39680
+ module2.exports = picomatch12;
39681
39681
  }
39682
39682
  });
39683
39683
 
@@ -39695,7 +39695,7 @@ var require_micromatch = __commonJS({
39695
39695
  "use strict";
39696
39696
  var util5 = __require("util");
39697
39697
  var braces = require_braces();
39698
- var picomatch13 = require_picomatch4();
39698
+ var picomatch12 = require_picomatch4();
39699
39699
  var utils = require_utils3();
39700
39700
  var isEmptyString = (val2) => val2 === "" || val2 === "./";
39701
39701
  var micromatch4 = (list2, patterns, options) => {
@@ -39712,7 +39712,7 @@ var require_micromatch = __commonJS({
39712
39712
  }
39713
39713
  };
39714
39714
  for (let i7 = 0; i7 < patterns.length; i7++) {
39715
- let isMatch4 = picomatch13(String(patterns[i7]), { ...options, onResult }, true);
39715
+ let isMatch4 = picomatch12(String(patterns[i7]), { ...options, onResult }, true);
39716
39716
  let negated = isMatch4.state.negated || isMatch4.state.negatedExtglob;
39717
39717
  if (negated) negatives++;
39718
39718
  for (let item of list2) {
@@ -39740,8 +39740,8 @@ var require_micromatch = __commonJS({
39740
39740
  return matches;
39741
39741
  };
39742
39742
  micromatch4.match = micromatch4;
39743
- micromatch4.matcher = (pattern, options) => picomatch13(pattern, options);
39744
- micromatch4.isMatch = (str, patterns, options) => picomatch13(patterns, options)(str);
39743
+ micromatch4.matcher = (pattern, options) => picomatch12(pattern, options);
39744
+ micromatch4.isMatch = (str, patterns, options) => picomatch12(patterns, options)(str);
39745
39745
  micromatch4.any = micromatch4.isMatch;
39746
39746
  micromatch4.not = (list2, patterns, options = {}) => {
39747
39747
  patterns = [].concat(patterns).map(String);
@@ -39788,7 +39788,7 @@ var require_micromatch = __commonJS({
39788
39788
  micromatch4.some = (list2, patterns, options) => {
39789
39789
  let items = [].concat(list2);
39790
39790
  for (let pattern of [].concat(patterns)) {
39791
- let isMatch4 = picomatch13(String(pattern), options);
39791
+ let isMatch4 = picomatch12(String(pattern), options);
39792
39792
  if (items.some((item) => isMatch4(item))) {
39793
39793
  return true;
39794
39794
  }
@@ -39798,7 +39798,7 @@ var require_micromatch = __commonJS({
39798
39798
  micromatch4.every = (list2, patterns, options) => {
39799
39799
  let items = [].concat(list2);
39800
39800
  for (let pattern of [].concat(patterns)) {
39801
- let isMatch4 = picomatch13(String(pattern), options);
39801
+ let isMatch4 = picomatch12(String(pattern), options);
39802
39802
  if (!items.every((item) => isMatch4(item))) {
39803
39803
  return false;
39804
39804
  }
@@ -39809,23 +39809,23 @@ var require_micromatch = __commonJS({
39809
39809
  if (typeof str !== "string") {
39810
39810
  throw new TypeError(`Expected a string: "${util5.inspect(str)}"`);
39811
39811
  }
39812
- return [].concat(patterns).every((p3) => picomatch13(p3, options)(str));
39812
+ return [].concat(patterns).every((p3) => picomatch12(p3, options)(str));
39813
39813
  };
39814
39814
  micromatch4.capture = (glob2, input, options) => {
39815
39815
  let posix3 = utils.isWindows(options);
39816
- let regex = picomatch13.makeRe(String(glob2), { ...options, capture: true });
39816
+ let regex = picomatch12.makeRe(String(glob2), { ...options, capture: true });
39817
39817
  let match2 = regex.exec(posix3 ? utils.toPosixSlashes(input) : input);
39818
39818
  if (match2) {
39819
39819
  return match2.slice(1).map((v) => v === void 0 ? "" : v);
39820
39820
  }
39821
39821
  };
39822
- micromatch4.makeRe = (...args2) => picomatch13.makeRe(...args2);
39823
- micromatch4.scan = (...args2) => picomatch13.scan(...args2);
39822
+ micromatch4.makeRe = (...args2) => picomatch12.makeRe(...args2);
39823
+ micromatch4.scan = (...args2) => picomatch12.scan(...args2);
39824
39824
  micromatch4.parse = (patterns, options) => {
39825
39825
  let res = [];
39826
39826
  for (let pattern of [].concat(patterns || [])) {
39827
39827
  for (let str of braces(String(pattern), options)) {
39828
- res.push(picomatch13.parse(str, options));
39828
+ res.push(picomatch12.parse(str, options));
39829
39829
  }
39830
39830
  }
39831
39831
  return res;
@@ -147531,7 +147531,7 @@ var require_micromatch2 = __commonJS({
147531
147531
  "use strict";
147532
147532
  var util5 = __require("util");
147533
147533
  var braces = require_braces2();
147534
- var picomatch13 = require_picomatch4();
147534
+ var picomatch12 = require_picomatch4();
147535
147535
  var utils = require_utils3();
147536
147536
  var isEmptyString = (v) => v === "" || v === "./";
147537
147537
  var hasBraces = (v) => {
@@ -147552,7 +147552,7 @@ var require_micromatch2 = __commonJS({
147552
147552
  }
147553
147553
  };
147554
147554
  for (let i7 = 0; i7 < patterns.length; i7++) {
147555
- let isMatch4 = picomatch13(String(patterns[i7]), { ...options, onResult }, true);
147555
+ let isMatch4 = picomatch12(String(patterns[i7]), { ...options, onResult }, true);
147556
147556
  let negated = isMatch4.state.negated || isMatch4.state.negatedExtglob;
147557
147557
  if (negated) negatives++;
147558
147558
  for (let item of list2) {
@@ -147580,8 +147580,8 @@ var require_micromatch2 = __commonJS({
147580
147580
  return matches;
147581
147581
  };
147582
147582
  micromatch4.match = micromatch4;
147583
- micromatch4.matcher = (pattern, options) => picomatch13(pattern, options);
147584
- micromatch4.isMatch = (str, patterns, options) => picomatch13(patterns, options)(str);
147583
+ micromatch4.matcher = (pattern, options) => picomatch12(pattern, options);
147584
+ micromatch4.isMatch = (str, patterns, options) => picomatch12(patterns, options)(str);
147585
147585
  micromatch4.any = micromatch4.isMatch;
147586
147586
  micromatch4.not = (list2, patterns, options = {}) => {
147587
147587
  patterns = [].concat(patterns).map(String);
@@ -147628,7 +147628,7 @@ var require_micromatch2 = __commonJS({
147628
147628
  micromatch4.some = (list2, patterns, options) => {
147629
147629
  let items = [].concat(list2);
147630
147630
  for (let pattern of [].concat(patterns)) {
147631
- let isMatch4 = picomatch13(String(pattern), options);
147631
+ let isMatch4 = picomatch12(String(pattern), options);
147632
147632
  if (items.some((item) => isMatch4(item))) {
147633
147633
  return true;
147634
147634
  }
@@ -147638,7 +147638,7 @@ var require_micromatch2 = __commonJS({
147638
147638
  micromatch4.every = (list2, patterns, options) => {
147639
147639
  let items = [].concat(list2);
147640
147640
  for (let pattern of [].concat(patterns)) {
147641
- let isMatch4 = picomatch13(String(pattern), options);
147641
+ let isMatch4 = picomatch12(String(pattern), options);
147642
147642
  if (!items.every((item) => isMatch4(item))) {
147643
147643
  return false;
147644
147644
  }
@@ -147649,23 +147649,23 @@ var require_micromatch2 = __commonJS({
147649
147649
  if (typeof str !== "string") {
147650
147650
  throw new TypeError(`Expected a string: "${util5.inspect(str)}"`);
147651
147651
  }
147652
- return [].concat(patterns).every((p3) => picomatch13(p3, options)(str));
147652
+ return [].concat(patterns).every((p3) => picomatch12(p3, options)(str));
147653
147653
  };
147654
147654
  micromatch4.capture = (glob2, input, options) => {
147655
147655
  let posix3 = utils.isWindows(options);
147656
- let regex = picomatch13.makeRe(String(glob2), { ...options, capture: true });
147656
+ let regex = picomatch12.makeRe(String(glob2), { ...options, capture: true });
147657
147657
  let match2 = regex.exec(posix3 ? utils.toPosixSlashes(input) : input);
147658
147658
  if (match2) {
147659
147659
  return match2.slice(1).map((v) => v === void 0 ? "" : v);
147660
147660
  }
147661
147661
  };
147662
- micromatch4.makeRe = (...args2) => picomatch13.makeRe(...args2);
147663
- micromatch4.scan = (...args2) => picomatch13.scan(...args2);
147662
+ micromatch4.makeRe = (...args2) => picomatch12.makeRe(...args2);
147663
+ micromatch4.scan = (...args2) => picomatch12.scan(...args2);
147664
147664
  micromatch4.parse = (patterns, options) => {
147665
147665
  let res = [];
147666
147666
  for (let pattern of [].concat(patterns || [])) {
147667
147667
  for (let str of braces(String(pattern), options)) {
147668
- res.push(picomatch13.parse(str, options));
147668
+ res.push(picomatch12.parse(str, options));
147669
147669
  }
147670
147670
  }
147671
147671
  return res;
@@ -204498,7 +204498,11 @@ async function fetchArtifactsFromManifestsTarHash(manifestsTarHash, includePreco
204498
204498
  try {
204499
204499
  const params = new URLSearchParams({
204500
204500
  tarHash: manifestsTarHash,
204501
- includePrecomputedReachabilityResults: String(includePrecomputedReachabilityResults ?? false)
204501
+ includePrecomputedReachabilityResults: String(includePrecomputedReachabilityResults ?? false),
204502
+ // Opt in to depscan PR #19451: returns artifacts with `missingMetadata: true` for packages
204503
+ // whose precrawl metadata is unavailable (private registry, workspace, git deps). This CLI
204504
+ // version strips them after reachability analysis (see filterMissingMetadataArtifacts).
204505
+ includeMissingMetadata: "true"
204502
204506
  });
204503
204507
  const url2 = getSocketApiUrl(`orgs/${process.env.SOCKET_ORG_SLUG}/compute-artifacts?${params.toString()}`);
204504
204508
  responseData = (await axios2.post(url2, {}, { headers: getAuthHeaders() })).data;
@@ -234357,6 +234361,14 @@ function shouldIgnoreDueToExcludeDirsOrChangedFiles({ mainProjectDir, excludeDir
234357
234361
  const relativeToProjectDir = relative19(mainProjectDir, fullPath) || ".";
234358
234362
  return !!(isMatch3(relativeToProjectDir, excludeDirs) || changedFiles && !changedFiles.some((changedFile) => changedFile.startsWith(relativeToProjectDir)));
234359
234363
  }
234364
+ function shouldIncludeWorkspaceForAnalysis(config3, workspaceFullPath) {
234365
+ if (shouldIgnoreDueToExcludeDirsOrChangedFiles(config3, workspaceFullPath)) return false;
234366
+ if (config3.includeDirs.length > 0) {
234367
+ const relPath = relative19(config3.mainProjectDir, workspaceFullPath);
234368
+ if (!isMatch3(relPath, config3.includeDirs)) return false;
234369
+ }
234370
+ return true;
234371
+ }
234360
234372
 
234361
234373
  // ../project-management/src/project-management/project-manager.ts
234362
234374
  var ProjectManager = class _ProjectManager {
@@ -235062,7 +235074,6 @@ import { existsSync as existsSync30, writeFileSync as writeFileSync3 } from "fs"
235062
235074
  import { mkdir as mkdir6, rm as rm3, writeFile as writeFile15 } from "fs/promises";
235063
235075
  var import_lodash15 = __toESM(require_lodash(), 1);
235064
235076
  import os2 from "os";
235065
- var import_picomatch12 = __toESM(require_picomatch2(), 1);
235066
235077
  import { join as join34, relative as relative22, resolve as resolve42 } from "path";
235067
235078
 
235068
235079
  // ../utils/src/dashboard-api/shared-api.ts
@@ -235079,12 +235090,16 @@ var DashboardAPI = class {
235079
235090
  }
235080
235091
  async createReport(repoUrl, projectName, cliVersion2, commitSha, branchName, cliOptions, apiKey, cliRunEnv, systemInformation) {
235081
235092
  if (this.disableAnalyticsSharing) {
235082
- return;
235093
+ return { reportId: void 0, legacyMode: false };
235083
235094
  }
235084
235095
  if (this.socketMode) {
235085
- return (await this.socketAPI.createSocketTier1Scan(cliOptions, cliVersion2, systemInformation)).tier1_reachability_scan_id;
235096
+ const response = await this.socketAPI.createSocketTier1Scan(cliOptions, cliVersion2, systemInformation);
235097
+ return {
235098
+ reportId: response.tier1_reachability_scan_id,
235099
+ legacyMode: response.legacy_mode ?? false
235100
+ };
235086
235101
  } else {
235087
- return await this.coanaAPI.createCoanaReport(
235102
+ const reportId = await this.coanaAPI.createCoanaReport(
235088
235103
  repoUrl,
235089
235104
  projectName,
235090
235105
  cliVersion2,
@@ -235094,6 +235109,7 @@ var DashboardAPI = class {
235094
235109
  apiKey,
235095
235110
  cliRunEnv
235096
235111
  );
235112
+ return { reportId, legacyMode: false };
235097
235113
  }
235098
235114
  }
235099
235115
  async sendErrorReport(apiKey, stackTrace, shouldLogSharing, errorType, reportId, repoUrl, projectName, logContent) {
@@ -237051,6 +237067,60 @@ function displayWorkspaceDiagnosticsSummaryInternal(diagnosticsEntries, vulns) {
237051
237067
  }
237052
237068
 
237053
237069
  // dist/internal/socket-report-socket-dependency-tree.js
237070
+ function filterMissingMetadataArtifacts(artifacts) {
237071
+ const missingIds = new Set(artifacts.filter((a4) => a4.missingMetadata).map((a4) => a4.id));
237072
+ if (missingIds.size === 0)
237073
+ return artifacts;
237074
+ const byId = new Map(artifacts.map((a4) => [a4.id, a4]));
237075
+ const resolveCache = /* @__PURE__ */ new Map();
237076
+ function resolveDependencies(id, visiting) {
237077
+ const cached = resolveCache.get(id);
237078
+ if (cached)
237079
+ return cached;
237080
+ if (visiting.has(id))
237081
+ return [];
237082
+ visiting.add(id);
237083
+ const node = byId.get(id);
237084
+ const out = /* @__PURE__ */ new Set();
237085
+ if (node) {
237086
+ for (const ref of node.dependencies ?? []) {
237087
+ if (missingIds.has(ref)) {
237088
+ for (const r3 of resolveDependencies(ref, visiting))
237089
+ out.add(r3);
237090
+ } else if (byId.has(ref)) {
237091
+ out.add(ref);
237092
+ }
237093
+ }
237094
+ }
237095
+ visiting.delete(id);
237096
+ const res = [...out];
237097
+ resolveCache.set(id, res);
237098
+ return res;
237099
+ }
237100
+ logger.debug(`Filtered out ${missingIds.size} missing-metadata component(s) after reachability analysis`);
237101
+ return artifacts.filter((a4) => !missingIds.has(a4.id)).map((a4) => {
237102
+ let dependencies = a4.dependencies;
237103
+ if (dependencies?.some((r3) => missingIds.has(r3))) {
237104
+ const out = /* @__PURE__ */ new Set();
237105
+ for (const r3 of dependencies) {
237106
+ if (missingIds.has(r3)) {
237107
+ for (const sub of resolveDependencies(r3, /* @__PURE__ */ new Set())) {
237108
+ if (sub !== a4.id)
237109
+ out.add(sub);
237110
+ }
237111
+ } else {
237112
+ out.add(r3);
237113
+ }
237114
+ }
237115
+ dependencies = [...out];
237116
+ }
237117
+ let toplevelAncestors = a4.toplevelAncestors;
237118
+ if (toplevelAncestors?.some((r3) => missingIds.has(r3))) {
237119
+ toplevelAncestors = toplevelAncestors.filter((r3) => !missingIds.has(r3));
237120
+ }
237121
+ return { ...a4, dependencies, toplevelAncestors };
237122
+ });
237123
+ }
237054
237124
  function filterOrphanedArtifacts(artifacts) {
237055
237125
  const reachable = /* @__PURE__ */ new Set();
237056
237126
  const queue = [];
@@ -237116,6 +237186,7 @@ function toSocketFactsSocketDependencyTree(artifacts, vulnerabilities, tier1Reac
237116
237186
  });
237117
237187
  }
237118
237188
  }
237189
+ artifacts = filterMissingMetadataArtifacts(artifacts);
237119
237190
  const componentsWithoutPatterns = artifacts.map((artifact) => {
237120
237191
  if (!artifact.vulnerabilities) {
237121
237192
  return { ...artifact };
@@ -252023,7 +252094,7 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
252023
252094
  }
252024
252095
 
252025
252096
  // dist/version.js
252026
- var version3 = "15.0.12";
252097
+ var version3 = "15.1.0";
252027
252098
 
252028
252099
  // dist/cli-core.js
252029
252100
  var { mapValues, omit, partition, pickBy: pickBy2 } = import_lodash15.default;
@@ -252169,6 +252240,35 @@ var CliCore = class {
252169
252240
  const allowedEcosystems = new Set(this.options.purlTypes.map((pt) => getAdvisoryEcosystemFromPurlType(pt)).filter((e) => e !== void 0));
252170
252241
  return ecosystems.filter((e) => allowedEcosystems.has(e));
252171
252242
  }
252243
+ /**
252244
+ * Opt out of the v15 reachability halts by enabling every
252245
+ * `--reach-continue-on-*` flag that wasn't already set explicitly by the
252246
+ * user (via CLI flag or env override). Invoked when the depscan `PUT
252247
+ * /tier1-reachability-scan` response reports `legacy_mode: true` — i.e. the
252248
+ * org ran the pre-v15 CLI before the admin-configured cutoff and has not
252249
+ * been promoted out of legacy mode.
252250
+ */
252251
+ applyLegacyModeOptOut() {
252252
+ logger.warn([
252253
+ "",
252254
+ "\u26A0\uFE0F Legacy mode is enabled for this organization.",
252255
+ "",
252256
+ "Reachability analysis will continue through install failures, analysis errors,",
252257
+ "workspaces with no source files, and Gradle/SBT projects missing their lock files",
252258
+ "instead of halting. This preserves the pre-v15 behavior for organizations that",
252259
+ "were already running Coana before the v15 rollout.",
252260
+ "",
252261
+ "Legacy mode hides real problems: failed installs and analysis errors silently",
252262
+ "downgrade to precomputed (Tier 2) results, so reachability coverage may be lower",
252263
+ "than expected. To opt into the new, stricter behavior, reach out to the Socket",
252264
+ "team and ask to have your organization promoted out of legacy mode.",
252265
+ ""
252266
+ ].join("\n"));
252267
+ this.options.reachContinueOnInstallErrors ??= true;
252268
+ this.options.reachContinueOnAnalysisErrors ??= true;
252269
+ this.options.reachContinueOnNoSourceFiles ??= true;
252270
+ this.options.reachContinueOnMissingLockFiles ??= true;
252271
+ }
252172
252272
  async main() {
252173
252273
  const tmpDir = await createTmpDirectory("coana-cli-");
252174
252274
  this.coanaLogPath = join34(tmpDir, "coana-log.txt");
@@ -252191,7 +252291,11 @@ var CliCore = class {
252191
252291
  try {
252192
252292
  if (this.shareWithDashboard && this.apiKey.type === "present" || this.options.socketMode) {
252193
252293
  const gitData = await getGitDataToMetadataIfAvailable(this.rootWorkingDirectory);
252194
- this.reportId = await this.dashboardAPI.createReport(this.options.repoUrl, this.options.projectName, version3, gitData?.sha, gitData?.branchName, omit(this.options, "apiKey", "print-report", "repoUrl", "projectName", "writeReportToFile"), this.apiKey, this.options.runEnv, getSystemInformation());
252294
+ const createReportResult = await this.dashboardAPI.createReport(this.options.repoUrl, this.options.projectName, version3, gitData?.sha, gitData?.branchName, omit(this.options, "apiKey", "print-report", "repoUrl", "projectName", "writeReportToFile"), this.apiKey, this.options.runEnv, getSystemInformation());
252295
+ this.reportId = createReportResult.reportId;
252296
+ if (createReportResult.legacyMode) {
252297
+ this.applyLegacyModeOptOut();
252298
+ }
252195
252299
  if (this.options.socketMode && this.reportId) {
252196
252300
  const batchedLogStreamer = new BatchedHttpLogStreamer({
252197
252301
  reportId: this.reportId,
@@ -252306,23 +252410,17 @@ var CliCore = class {
252306
252410
  if (this.options.purlTypes && !this.options.purlTypes.some((purlType) => getAdvisoryEcosystemFromPurlType(purlType) === ecosystem)) {
252307
252411
  continue;
252308
252412
  }
252309
- const includeDirs = this.options.includeDirs ?? [];
252413
+ const filterConfig = {
252414
+ mainProjectDir: this.rootWorkingDirectory,
252415
+ excludeDirs: this.options.excludeDirs ?? [],
252416
+ changedFiles: this.options.changedFiles,
252417
+ includeDirs: this.options.includeDirs ?? []
252418
+ };
252310
252419
  const filteredWorkspaces = {};
252311
252420
  for (const [workspace, analysisData] of Object.entries(workspaceToAnalysisData)) {
252312
252421
  const resolvedWorkspace = resolve42(this.rootWorkingDirectory, workspace);
252313
- const shouldExclude = shouldIgnoreDueToExcludeDirsOrChangedFiles({
252314
- mainProjectDir: this.rootWorkingDirectory,
252315
- excludeDirs: this.options.excludeDirs ?? [],
252316
- changedFiles: this.options.changedFiles,
252317
- includeDirs
252318
- }, resolvedWorkspace);
252319
- if (shouldExclude)
252422
+ if (!shouldIncludeWorkspaceForAnalysis(filterConfig, resolvedWorkspace))
252320
252423
  continue;
252321
- if (includeDirs.length > 0) {
252322
- const relPath = relative22(this.rootWorkingDirectory, resolvedWorkspace);
252323
- if (!import_picomatch12.default.isMatch(relPath, includeDirs))
252324
- continue;
252325
- }
252326
252424
  filteredWorkspaces[workspace] = analysisData;
252327
252425
  }
252328
252426
  if (Object.keys(filteredWorkspaces).length > 0) {
@@ -253049,7 +253147,7 @@ Subproject: ${subproject}`);
253049
253147
  logger.error(displayLines.join("\n"));
253050
253148
  }
253051
253149
  shouldExcludeAnalyzingWorkspace(subprojectPath, workspacePath, workspacePrefix = "") {
253052
- const shouldExcludeWorkspaceForAnalysis = shouldIgnoreDueToExcludeDirsOrChangedFiles({
253150
+ const shouldExcludeWorkspaceForAnalysis = !shouldIncludeWorkspaceForAnalysis({
253053
253151
  mainProjectDir: this.rootWorkingDirectory,
253054
253152
  excludeDirs: this.options.excludeDirs ?? [],
253055
253153
  changedFiles: this.options.changedFiles,
@@ -253087,7 +253185,8 @@ Subproject: ${subproject}`);
253087
253185
  disableBucketing: !!this.options.disableAnalysisSplitting,
253088
253186
  lightweightReachability: this.options.lightweightReachability,
253089
253187
  skipCacheUsage: this.options.skipCacheUsage,
253090
- haltOnInstallErrors: !!this.options.socketMode && !this.options.reachContinueOnInstallErrors
253188
+ haltOnInstallErrors: !!this.options.socketMode && !this.options.reachContinueOnInstallErrors,
253189
+ jsAnalysisEngine: this.options.legacyJsAnalysisEngine ? "jelly" : "sparjs"
253091
253190
  }, rootWorkingDirOverride, displaySubprojectPath, preinstallDir);
253092
253191
  result.push(...analysisResult.vulnerabilities);
253093
253192
  this.sendProgress("REACHABILITY_ANALYSIS", false, subprojectPath, workspacePath);
@@ -253380,8 +253479,11 @@ async function writeAnalysisDebugInfo(outputFilePath, ecosystemToWorkspaceToVuln
253380
253479
  handleNexeBinaryMode();
253381
253480
  var program2 = new Command();
253382
253481
  var run2 = new Command();
253383
- run2.name("run").argument("<path>", "File system path to folder containing the project").option("-o, --output-dir <path>", "Write json report to <path>/coana-report.json").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("--silent-spinner", "Silence spinner", "CI" in process.env || !process.stdin.isTTY).option("-p, --print-report", "Print the report to the console", false).option("--offline-database <path>", "Path to a coana-offline-db.json file for running the CLI without internet connectivity", void 0).option("-t, --timeout <timeout>", "Set API <timeout> in milliseconds to Coana backend.", "300000").option("-a, --analysis-timeout <timeout>", "Set <timeout> in seconds for each reachability analysis run").option("--memory-limit <memoryInMB>", "Set memory limit for analysis to <memoryInMB> megabytes of memory.", "8192").option("-c, --concurrency <concurrency>", "Set the maximum number of concurrent reachability analysis runs. It's recommended to choose a concurrency level that ensures that each analysis run has at least the --memory-limit amount of memory available. NPM reachability analysis does not support concurrent execution, so the concurrency level is ignored for NPM.", "1").option("--api-key <key>", "Set the Coana dashboard API key. By setting you also enable the dashboard integration.").addOption(new Option("--write-report-to-file", "Write the report dashboard-compatible report to dashboard-report.json. This report may help the Coana team debug issues with the report insertion mechanism.").default(false).hideHelp()).option("--project-name <repoName>", "Set the name of the repository. Used for dashboard integration.").option("--repo-url <repoUrl>", "Set the URL of the repository. Used for dashboard integration.").option("--include-dirs <relativeDirs...>", "globs for directories to include from the detection of subprojects (space-separated)(use relative paths from the project root). Notice, projects that are not included may still be scanned if they are referenced from included projects.").option("--exclude-dirs <relativeDirs...>", "globs for directories to exclude from the detection of subprojects (space-separated)(use relative paths from the project root). Notice, excluded projects may still be scanned if they are referenced from non-excluded projects.").option("--disable-analysis-splitting", "Limits Coana to at most 1 reachability analysis run per workspace").option("--print-analysis-log-file", "Store log output from the JavaScript/TypeScript reachability analysis in the file js-analysis.log file in the root of each workspace", false).option("--entry-points <entryPoints...>", "List of files to analyze for root workspace. The reachability analysis automatically analyzes all files used by the entry points. If not provided, all JavaScript and TypeScript files are considered entry points. For non-root workspaces, all JavaScript and TypeScript files are analyzed as well.").option("--include-projects-with-no-reachability-support", "Also runs Coana on projects where we support traditional SCA, but does not yet support reachability analysis.", false).option("--ecosystems <ecosystems...>", "List of ecosystems to analyze (space-separated). Currently NPM, PIP, MAVEN, NUGET and GO are supported. Default is all supported ecosystems.").addOption(new Option("--purl-types <purlTypes...>", "List of PURL types to analyze (space-separated). Currently npm, pypi, maven, nuget, golang and cargo are supported. Default is all supported purl types.").hideHelp()).option("--changed-files <files...>", "List of files that have changed. If provided, Coana only analyzes workspaces and modules that contain changed files.").option("--disable-report-submission", "Disable the submission of the report to the Coana dashboard. Used by the pipeline blocking feature.", false).option("--disable-analytics-sharing", "Disable analytics sharing.", false).option("--provider-project <path>", "File system path to folder containing the provider project (Only supported for Maven, Gradle, and SBT)").option("--provider-workspaces <dirs...>", "List of workspaces that build the provided runtime environment (Only supported for Maven, Gradle, and SBT)", (paths) => paths.split(" ")).option("--lightweight-reachability", "Runs Coana in lightweight mode. This increases analysis speed but also raises the risk of Coana misclassifying the reachability of certain complex vulnerabilities. Recommended only for use with Coana Guardrail mode.", false).addOption(new Option("--run-without-docker", "Run package managers and reachability analyzers without using docker").default(process.env.RUN_WITHOUT_DOCKER === "true").hideHelp()).addOption(new Option("--run-env <env>", "Specifies the environment in which the CLI is run. So far only MANAGED_SCAN and UNKNOWN are supported.").default("UNKNOWN").choices(["UNKNOWN", "MANAGED_SCAN"]).hideHelp()).addOption(new Option("--guardrail-mode", "Run Coana in guardrail mode. This mode is used to prevent new reachable vulnerabilities from being introduced into the codebase. Usually run as a CI check when pushing new commits to a pull request.")).option("--ignore-failing-workspaces", "Continue processing when a workspace fails instead of exiting. Failed workspaces will be logged at termination.", false).option("--reach-continue-on-install-errors", "Continue analysis when package installation fails, falling back to precomputed (Tier 2) reachability results. By default, the CLI halts on installation errors in socket mode.", process.env.COANA_CONTINUE_ON_INSTALL_ERRORS === "true").option("--reach-continue-on-analysis-errors", "Continue analysis when errors occur (timeouts, OOM, parse errors, etc.), falling back to precomputed (Tier 2) reachability results. By default, the CLI halts on analysis errors in socket mode.", false).option("--reach-continue-on-no-source-files", "Continue analysis when a workspace contains no source files for its ecosystem. By default, the CLI halts in socket mode.", false).option("--reach-continue-on-missing-lock-files", "Continue analysis when a Gradle or SBT project is missing its lock file (or Gradle version catalog / pre-generated SBOM). By default, the CLI halts in socket mode.", process.env.COANA_REACH_CONTINUE_ON_MISSING_LOCK_FILES === "true").addOption(new Option("--socket-mode <output-file>", "Run Coana in socket mode and write report to <output-file>").hideHelp()).addOption(new Option("--manifests-tar-hash <hash>", "Hash of the tarball containing all manifest files already uploaded to Socket. If provided, Socket will be used for computing dependency trees.").hideHelp()).option("--skip-cache-usage", "Do not attempt to use cached analysis configuration from previous runs", false).addOption(new Option("--lazy-mode", "Enable lazy analysis mode for JavaScript/TypeScript. This can significantly speed up analysis by only analyzing code that is actually relevant for the vulnerabilities being analyzed.").default(false).hideHelp()).addOption(new Option("--min-severity <severity>", "Set the minimum severity of vulnerabilities to analyze. Supported severities are info, low, moderate, high and critical.").choices(["info", "INFO", "low", "LOW", "moderate", "MODERATE", "high", "HIGH", "critical", "CRITICAL"])).option("--use-unreachable-from-precomputation", "Skip the reachability analysis for vulnerabilities that are already known to be unreachable from the precomputed reachability analysis (Tier 2).", false).addOption(new Option("--use-only-pregenerated-sboms", "Only include artifacts that have CDX or SPDX files in their manifest files.").default(false).hideHelp()).option("--disable-external-tool-checks", "Disable validation of external tools (npm, python, go, etc.) before running analysis.", false).version(version3).configureHelp({ sortOptions: true }).action(async (path9, options) => {
253482
+ run2.name("run").argument("<path>", "File system path to folder containing the project").option("-o, --output-dir <path>", "Write json report to <path>/coana-report.json").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("--silent-spinner", "Silence spinner", "CI" in process.env || !process.stdin.isTTY).option("-p, --print-report", "Print the report to the console", false).option("--offline-database <path>", "Path to a coana-offline-db.json file for running the CLI without internet connectivity", void 0).option("-t, --timeout <timeout>", "Set API <timeout> in milliseconds to Coana backend.", "300000").option("-a, --analysis-timeout <timeout>", "Set <timeout> in seconds for each reachability analysis run").option("--memory-limit <memoryInMB>", "Set memory limit for analysis to <memoryInMB> megabytes of memory.", "8192").option("-c, --concurrency <concurrency>", "Set the maximum number of concurrent reachability analysis runs. It's recommended to choose a concurrency level that ensures that each analysis run has at least the --memory-limit amount of memory available. NPM reachability analysis does not support concurrent execution, so the concurrency level is ignored for NPM.", "1").option("--api-key <key>", "Set the Coana dashboard API key. By setting you also enable the dashboard integration.").addOption(new Option("--write-report-to-file", "Write the report dashboard-compatible report to dashboard-report.json. This report may help the Coana team debug issues with the report insertion mechanism.").default(false).hideHelp()).option("--project-name <repoName>", "Set the name of the repository. Used for dashboard integration.").option("--repo-url <repoUrl>", "Set the URL of the repository. Used for dashboard integration.").option("--include-dirs <relativeDirs...>", "globs for directories to include from the detection of subprojects (space-separated)(use relative paths from the project root). Notice, projects that are not included may still be scanned if they are referenced from included projects.").option("--exclude-dirs <relativeDirs...>", "globs for directories to exclude from the detection of subprojects (space-separated)(use relative paths from the project root). Notice, excluded projects may still be scanned if they are referenced from non-excluded projects.").option("--disable-analysis-splitting", "Limits Coana to at most 1 reachability analysis run per workspace").option("--print-analysis-log-file", "Store log output from the JavaScript/TypeScript reachability analysis in the file js-analysis.log file in the root of each workspace", false).option("--entry-points <entryPoints...>", "List of files to analyze for root workspace. The reachability analysis automatically analyzes all files used by the entry points. If not provided, all JavaScript and TypeScript files are considered entry points. For non-root workspaces, all JavaScript and TypeScript files are analyzed as well.").option("--include-projects-with-no-reachability-support", "Also runs Coana on projects where we support traditional SCA, but does not yet support reachability analysis.", false).option("--ecosystems <ecosystems...>", "List of ecosystems to analyze (space-separated). Currently NPM, PIP, MAVEN, NUGET and GO are supported. Default is all supported ecosystems.").addOption(new Option("--purl-types <purlTypes...>", "List of PURL types to analyze (space-separated). Currently npm, pypi, maven, nuget, golang and cargo are supported. Default is all supported purl types.").hideHelp()).option("--changed-files <files...>", "List of files that have changed. If provided, Coana only analyzes workspaces and modules that contain changed files.").option("--disable-report-submission", "Disable the submission of the report to the Coana dashboard. Used by the pipeline blocking feature.", false).option("--disable-analytics-sharing", "Disable analytics sharing.", false).option("--provider-project <path>", "File system path to folder containing the provider project (Only supported for Maven, Gradle, and SBT)").option("--provider-workspaces <dirs...>", "List of workspaces that build the provided runtime environment (Only supported for Maven, Gradle, and SBT)", (paths) => paths.split(" ")).option("--lightweight-reachability", "Runs Coana in lightweight mode. This increases analysis speed but also raises the risk of Coana misclassifying the reachability of certain complex vulnerabilities. Recommended only for use with Coana Guardrail mode.", false).addOption(new Option("--run-without-docker", "Run package managers and reachability analyzers without using docker").default(process.env.RUN_WITHOUT_DOCKER === "true").hideHelp()).addOption(new Option("--run-env <env>", "Specifies the environment in which the CLI is run. So far only MANAGED_SCAN and UNKNOWN are supported.").default("UNKNOWN").choices(["UNKNOWN", "MANAGED_SCAN"]).hideHelp()).addOption(new Option("--guardrail-mode", "Run Coana in guardrail mode. This mode is used to prevent new reachable vulnerabilities from being introduced into the codebase. Usually run as a CI check when pushing new commits to a pull request.")).option("--ignore-failing-workspaces", "Continue processing when a workspace fails instead of exiting. Failed workspaces will be logged at termination.", false).option("--reach-continue-on-install-errors", "Continue analysis when package installation fails, falling back to precomputed (Tier 2) reachability results. By default, the CLI halts on installation errors in socket mode.", process.env.COANA_REACH_CONTINUE_ON_INSTALL_ERRORS === "true" || process.env.COANA_CONTINUE_ON_INSTALL_ERRORS === "true" || void 0).option("--reach-continue-on-analysis-errors", "Continue analysis when errors occur (timeouts, OOM, parse errors, etc.), falling back to precomputed (Tier 2) reachability results. By default, the CLI halts on analysis errors in socket mode.", process.env.COANA_REACH_CONTINUE_ON_ANALYSIS_ERRORS === "true" || void 0).option("--reach-continue-on-no-source-files", "Continue analysis when a workspace contains no source files for its ecosystem. By default, the CLI halts in socket mode.", process.env.COANA_REACH_CONTINUE_ON_NO_SOURCE_FILES === "true" || void 0).option("--reach-continue-on-missing-lock-files", "Continue analysis when a Gradle or SBT project is missing its lock file (or Gradle version catalog / pre-generated SBOM). By default, the CLI halts in socket mode.", process.env.COANA_REACH_CONTINUE_ON_MISSING_LOCK_FILES === "true" || void 0).addOption(new Option("--socket-mode <output-file>", "Run Coana in socket mode and write report to <output-file>").hideHelp()).addOption(new Option("--manifests-tar-hash <hash>", "Hash of the tarball containing all manifest files already uploaded to Socket. If provided, Socket will be used for computing dependency trees.").hideHelp()).option("--skip-cache-usage", "Do not attempt to use cached analysis configuration from previous runs", false).addOption(new Option("--lazy-mode", "Enable lazy analysis mode for JavaScript/TypeScript. This can significantly speed up analysis by only analyzing code that is actually relevant for the vulnerabilities being analyzed.").default(false).implies({ legacyJsAnalysisEngine: true }).hideHelp()).addOption(new Option("--legacy-js-analysis-engine", "Use the legacy Jelly engine for JavaScript/TypeScript reachability analysis instead of SPAR-JS.").default(false).hideHelp()).addOption(new Option("--min-severity <severity>", "Set the minimum severity of vulnerabilities to analyze. Supported severities are info, low, moderate, high and critical.").choices(["info", "INFO", "low", "LOW", "moderate", "MODERATE", "high", "HIGH", "critical", "CRITICAL"])).option("--use-unreachable-from-precomputation", "Skip the reachability analysis for vulnerabilities that are already known to be unreachable from the precomputed reachability analysis (Tier 2).", false).addOption(new Option("--use-only-pregenerated-sboms", "Only include artifacts that have CDX or SPDX files in their manifest files.").default(false).hideHelp()).option("--disable-external-tool-checks", "Disable validation of external tools (npm, python, go, etc.) before running analysis.", false).version(version3).configureHelp({ sortOptions: true }).action(async (path9, options) => {
253384
253483
  process.env.DOCKER_IMAGE_TAG ??= version3;
253484
+ if (process.env.COANA_CONTINUE_ON_INSTALL_ERRORS === "true" && process.env.COANA_REACH_CONTINUE_ON_INSTALL_ERRORS !== "true") {
253485
+ logger.warn("COANA_CONTINUE_ON_INSTALL_ERRORS is deprecated; use COANA_REACH_CONTINUE_ON_INSTALL_ERRORS instead.");
253486
+ }
253385
253487
  options.ecosystems = options.ecosystems?.map((e) => e.toUpperCase());
253386
253488
  options.minSeverity = options.minSeverity?.toUpperCase();
253387
253489
  options.purlTypes = options.purlTypes?.map((e) => e.toLowerCase());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coana-tech/cli",
3
- "version": "15.0.12",
3
+ "version": "15.1.0",
4
4
  "description": "Coana CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -80581,12 +80581,16 @@ var DashboardAPI = class {
80581
80581
  }
80582
80582
  async createReport(repoUrl, projectName, cliVersion2, commitSha, branchName, cliOptions, apiKey3, cliRunEnv, systemInformation) {
80583
80583
  if (this.disableAnalyticsSharing) {
80584
- return;
80584
+ return { reportId: void 0, legacyMode: false };
80585
80585
  }
80586
80586
  if (this.socketMode) {
80587
- return (await this.socketAPI.createSocketTier1Scan(cliOptions, cliVersion2, systemInformation)).tier1_reachability_scan_id;
80587
+ const response = await this.socketAPI.createSocketTier1Scan(cliOptions, cliVersion2, systemInformation);
80588
+ return {
80589
+ reportId: response.tier1_reachability_scan_id,
80590
+ legacyMode: response.legacy_mode ?? false
80591
+ };
80588
80592
  } else {
80589
- return await this.coanaAPI.createCoanaReport(
80593
+ const reportId = await this.coanaAPI.createCoanaReport(
80590
80594
  repoUrl,
80591
80595
  projectName,
80592
80596
  cliVersion2,
@@ -80596,6 +80600,7 @@ var DashboardAPI = class {
80596
80600
  apiKey3,
80597
80601
  cliRunEnv
80598
80602
  );
80603
+ return { reportId, legacyMode: false };
80599
80604
  }
80600
80605
  }
80601
80606
  async sendErrorReport(apiKey3, stackTrace, shouldLogSharing, errorType, reportId, repoUrl, projectName, logContent) {
@@ -112082,10 +112087,10 @@ var JSCodeAwareVulnerabilityScanner = class _JSCodeAwareVulnerabilityScanner {
112082
112087
  this.options = options;
112083
112088
  this.engineOverride = engineOverride;
112084
112089
  }
112085
- resolveEngine(experiment) {
112086
- if (this.engineOverride === "sparjs" || !this.engineOverride && experiment === "SPARJS_EXPERIMENT")
112087
- return this.sparjsEngine;
112088
- return this.jellyEngine;
112090
+ resolveEngine() {
112091
+ if (this.engineOverride === "jelly")
112092
+ return this.jellyEngine;
112093
+ return this.sparjsEngine;
112089
112094
  }
112090
112095
  async cleanup() {
112091
112096
  await Promise.all([this.jellyEngine.cleanup(), this.sparjsEngine.cleanup()]);
@@ -112108,7 +112113,7 @@ var JSCodeAwareVulnerabilityScanner = class _JSCodeAwareVulnerabilityScanner {
112108
112113
  const analysisOptionsFromHeuristic = heuristic.getOptions(vulnerabilities);
112109
112114
  try {
112110
112115
  analysisOptionsFromHeuristic.approx = process.env.JELLY_APPROX === "true" || experiment === "JELLY_APPROX";
112111
- const analysisRes = await this.resolveEngine(experiment).runAnalysis(this.mainProjectDir, this.projectDir, analysisOptionsFromHeuristic, this.options, timeoutInSeconds, vulnerabilities, experiment, telemetryHandler, analyzerTelemetryHandler);
112116
+ const analysisRes = await this.resolveEngine().runAnalysis(this.mainProjectDir, this.projectDir, analysisOptionsFromHeuristic, this.options, timeoutInSeconds, vulnerabilities, experiment, telemetryHandler, analyzerTelemetryHandler);
112112
112117
  const { analysisDiagnostics: diagnostics, matches } = analysisRes;
112113
112118
  const terminatedEarly = diagnostics.rangeError ?? (diagnostics.aborted || diagnostics.timeout || diagnostics.lowmemory);
112114
112119
  return {
@@ -114341,11 +114346,27 @@ function transformVulnsToUrlToReachability(augmentedVulnerabilities) {
114341
114346
  }
114342
114347
 
114343
114348
  // dist/whole-program-code-aware-vulnerability-scanner/php/heuristics.js
114349
+ var INCLUDE_PACKAGE_COMPANIONS = {
114350
+ "guzzlehttp/guzzle": ["guzzlehttp/promises"]
114351
+ };
114352
+ function expandIncludePackageCompanions(packages) {
114353
+ const expanded = new Set(packages);
114354
+ const worklist = [...packages];
114355
+ for (const pkg of worklist) {
114356
+ for (const companion of INCLUDE_PACKAGE_COMPANIONS[pkg] ?? []) {
114357
+ if (!expanded.has(companion)) {
114358
+ expanded.add(companion);
114359
+ worklist.push(companion);
114360
+ }
114361
+ }
114362
+ }
114363
+ return [...expanded];
114364
+ }
114344
114365
  var PhpHeuristics = {
114345
114366
  ONLY_VULN_PATH_PACKAGES: {
114346
114367
  name: "ONLY_VULN_PATH_PACKAGES",
114347
114368
  splitAnalysisInBuckets: true,
114348
- getIncludePackages: (vulns) => computePackagesOnVulnPath(vulns, { includeLeafPackages: true })
114369
+ getIncludePackages: (vulns) => expandIncludePackageCompanions(computePackagesOnVulnPath(vulns, { includeLeafPackages: true }))
114349
114370
  }
114350
114371
  };
114351
114372
 
@@ -114930,7 +114951,7 @@ var NpmAnalyzer = class {
114930
114951
  constructor(state, projectDir) {
114931
114952
  this.state = state;
114932
114953
  this.projectDir = projectDir;
114933
- this.engine = this.state.otherAnalysisOptions.jsAnalysisEngine === "sparjs" ? new SparJSAnalysisEngine() : new JellyJSAnalysisEngine();
114954
+ this.engine = this.state.otherAnalysisOptions.jsAnalysisEngine === "jelly" ? new JellyJSAnalysisEngine() : new SparJSAnalysisEngine();
114934
114955
  }
114935
114956
  async installDependencies(preinstallDir) {
114936
114957
  if (existsSync20(resolve25(this.state.subprojectDir, "node_modules")))