hermex 1.1.1 → 1.2.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/dist/cli.js CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
3
  import ora from 'ora';
4
- import chalk6 from 'chalk';
4
+ import chalk5 from 'chalk';
5
+ import { minimatch } from 'minimatch';
5
6
  import { parseSync } from '@swc/core';
6
7
  import fs3 from 'fs';
7
8
  import Table from 'cli-table3';
@@ -45,7 +46,6 @@ function createState() {
45
46
  // src/swc-parser/patterns/imports.ts
46
47
  function analyzeImportDeclaration(node, state) {
47
48
  const source = node.source.value;
48
- console.log(`\u{1F4E6} Found import: ${source}`);
49
49
  for (const spec of node.specifiers) {
50
50
  switch (spec.type) {
51
51
  case "ImportDefaultSpecifier":
@@ -297,7 +297,6 @@ function analyzeJSXOpeningElement(node, state, parent) {
297
297
  if (!state.usagePatterns.jsxUsage.has(elementName)) {
298
298
  state.usagePatterns.jsxUsage.set(elementName, usage);
299
299
  }
300
- console.log(`\u{1F3A8} JSX Usage: <${elementName}>`);
301
300
  }
302
301
 
303
302
  // src/swc-parser/utils/matchers.ts
@@ -319,7 +318,6 @@ function analyzeVariableDeclaration(node, state) {
319
318
  line: node.span?.start || 0
320
319
  });
321
320
  state.componentNames.add(varName);
322
- console.log(`\u{1F4DD} Variable assignment: ${varName} = ${assignment}`);
323
321
  }
324
322
  }
325
323
  }
@@ -340,7 +338,6 @@ function analyzeDestructuringPattern(pattern, init, state) {
340
338
  line: pattern.span?.start || 0
341
339
  });
342
340
  state.componentNames.add(propName);
343
- console.log(`\u{1F527} Destructuring: ${propName} from ${init.value}`);
344
341
  }
345
342
  }
346
343
  }
@@ -368,7 +365,6 @@ function analyzeConditionalExpression(node, state) {
368
365
  alternate: alternate || "",
369
366
  line: node.span?.start || 0
370
367
  });
371
- console.log("\u{1F500} Conditional component usage found");
372
368
  }
373
369
  }
374
370
 
@@ -385,7 +381,6 @@ function analyzeArrayExpression(node, state) {
385
381
  components: node.elements?.map((elem) => elem?.value).filter(Boolean),
386
382
  line: node.span?.start || 0
387
383
  });
388
- console.log("\u{1F4CB} Array with components found");
389
384
  }
390
385
  }
391
386
  function analyzeObjectExpression(node, state) {
@@ -403,7 +398,6 @@ function analyzeObjectExpression(node, state) {
403
398
  })),
404
399
  line: node.span?.start || 0
405
400
  });
406
- console.log("\u{1F5FA}\uFE0F Object mapping with components found");
407
401
  }
408
402
  }
409
403
 
@@ -419,7 +413,6 @@ function analyzeLazyImport(node, state) {
419
413
  source,
420
414
  line: node.span?.start || 0
421
415
  });
422
- console.log(`\u{1F504} Found lazy import: ${source}`);
423
416
  }
424
417
  }
425
418
  }
@@ -431,7 +424,6 @@ function analyzeDynamicImport(node, state) {
431
424
  source,
432
425
  line: node.span?.start || 0
433
426
  });
434
- console.log(`\u26A1 Found dynamic import: ${source}`);
435
427
  }
436
428
  }
437
429
 
@@ -442,7 +434,6 @@ function analyzeHOCUsage(node, state) {
442
434
  component: node.arguments?.[0]?.value || "[unknown]",
443
435
  line: node.span?.start || 0
444
436
  });
445
- console.log(`\u{1F381} HOC usage found`);
446
437
  }
447
438
  function analyzeMemoUsage(node, state) {
448
439
  const component = node.arguments?.[0];
@@ -451,28 +442,23 @@ function analyzeMemoUsage(node, state) {
451
442
  component: component.value,
452
443
  line: node.span?.start || 0
453
444
  });
454
- console.log(`\u{1F9E0} Memoized component: ${component.value}`);
455
445
  }
456
446
  }
457
447
  function analyzeForwardRefUsage(node, state) {
458
448
  state.usagePatterns.forwardedRefs.add({
459
449
  line: node.span?.start || 0
460
450
  });
461
- console.log("\u2197\uFE0F ForwardRef usage found");
462
451
  }
463
452
  function analyzePortalUsage(node, state) {
464
453
  state.usagePatterns.portalUsage.add({
465
454
  line: node.span?.start || 0
466
455
  });
467
- console.log("\u{1F300} Portal usage found");
468
456
  }
469
457
  function analyzeMemberExpression(node, state) {
470
458
  if (node.object?.type === "Identifier" && state.allIdentifiers.has(node.object.value)) {
471
- const namespaceName = node.object.value;
472
459
  const propertyName = node.property?.value;
473
460
  if (propertyName) {
474
461
  state.componentNames.add(propertyName);
475
- console.log(`\u{1F517} Namespace access: ${namespaceName}.${propertyName}`);
476
462
  }
477
463
  }
478
464
  }
@@ -664,14 +650,14 @@ function parseCode(code, options = {}) {
664
650
  return report;
665
651
  }
666
652
  function parseFile(filePath, options = {}) {
667
- console.log(`
668
- \u{1F4C1} Analyzing: ${filePath}`);
669
653
  try {
670
654
  const code = fs3.readFileSync(filePath, "utf8");
671
655
  return parseCode(code, options);
672
656
  } catch (error) {
673
- console.error(`\u274C Error parsing ${filePath}:`, error.message);
674
- return null;
657
+ if (options.ignoreErrors) {
658
+ return null;
659
+ }
660
+ throw error;
675
661
  }
676
662
  }
677
663
  function filterReportByLibrary(report, libraryName) {
@@ -712,7 +698,7 @@ function filterReportByLibrary(report, libraryName) {
712
698
  }
713
699
 
714
700
  // src/utils/aggregator.ts
715
- function aggregateReports(reports, versions = {}) {
701
+ function aggregateReports(reports, versions = {}, errors = []) {
716
702
  const componentUsageMap = /* @__PURE__ */ new Map();
717
703
  let totalImports = 0;
718
704
  let totalUsagePatterns = 0;
@@ -765,7 +751,8 @@ function aggregateReports(reports, versions = {}) {
765
751
  topComponents,
766
752
  allComponents,
767
753
  packageDistribution,
768
- reports
754
+ reports,
755
+ errors
769
756
  };
770
757
  }
771
758
  function resolvePackageFromImportPath(importPath, availablePackages) {
@@ -945,14 +932,14 @@ function formatCount(num) {
945
932
  return num.toLocaleString();
946
933
  }
947
934
  function formatDuration(seconds) {
948
- return `${seconds.toFixed(1)}s`;
935
+ return `${seconds.toFixed(2)}s`;
949
936
  }
950
937
 
951
938
  // src/utils/print-summary.ts
952
939
  function printHeader() {
953
- console.log(chalk6.green.bold("\n\u{1F4CA} Summary\n"));
940
+ console.log(chalk5.green.bold("\n\u{1F4CA} Summary\n"));
954
941
  }
955
- function printSummary(aggregated, elapsedTimeSeconds) {
942
+ function printSummary(aggregated) {
956
943
  printHeader();
957
944
  const table = new Table({
958
945
  head: ["Metric", "Count"],
@@ -975,30 +962,6 @@ function printSummary(aggregated, elapsedTimeSeconds) {
975
962
  ["Total Usages", formatCount(totalExternalUsage)]
976
963
  );
977
964
  console.log(table.toString());
978
- console.log(
979
- chalk6.green(
980
- `Analysis completed successfully in ${formatDuration(elapsedTimeSeconds)}
981
- `
982
- )
983
- );
984
- }
985
- function printHeader2() {
986
- console.log(chalk6.cyan.bold("\n\u{1F4CB} Details\n"));
987
- }
988
- function printDetails(aggregated) {
989
- printHeader2();
990
- console.log(
991
- chalk6.cyan(
992
- ` Total usage patterns: ${formatCount(aggregated.totalUsagePatterns)}`
993
- )
994
- );
995
- for (const pattern of aggregated.patternCounts) {
996
- if (pattern.count > 0) {
997
- console.log(
998
- chalk6.cyan(` ${pattern.displayName}: ${formatCount(pattern.count)}`)
999
- );
1000
- }
1001
- }
1002
965
  }
1003
966
  function renderBarChart(data, options = {}) {
1004
967
  const {
@@ -1008,12 +971,12 @@ function renderBarChart(data, options = {}) {
1008
971
  emptyChar = "\u2591"
1009
972
  } = options;
1010
973
  if (data.length === 0) {
1011
- console.log(chalk6.gray(" No data to display"));
974
+ console.log(chalk5.gray(" No data to display"));
1012
975
  return;
1013
976
  }
1014
977
  const maxValue = Math.max(...data.map((d) => d.value));
1015
978
  if (maxValue === 0) {
1016
- console.log(chalk6.gray(" All values are zero"));
979
+ console.log(chalk5.gray(" All values are zero"));
1017
980
  return;
1018
981
  }
1019
982
  const maxLabelLength = Math.max(...data.map((d) => d.label.length));
@@ -1022,7 +985,7 @@ function renderBarChart(data, options = {}) {
1022
985
  const barLength = Math.round(percentage * maxWidth);
1023
986
  const emptyLength = maxWidth - barLength;
1024
987
  const paddedLabel = item.label.padEnd(maxLabelLength, " ");
1025
- const bar = chalk6.green(barChar.repeat(barLength)) + chalk6.gray(emptyChar.repeat(emptyLength));
988
+ const bar = chalk5.green(barChar.repeat(barLength)) + chalk5.gray(emptyChar.repeat(emptyLength));
1026
989
  const valueStr = showValues ? ` ${formatCount(item.value)}` : "";
1027
990
  console.log(`${paddedLabel} ${bar}${valueStr}
1028
991
  `);
@@ -1030,8 +993,8 @@ function renderBarChart(data, options = {}) {
1030
993
  }
1031
994
 
1032
995
  // src/utils/print-components.ts
1033
- function printHeader3() {
1034
- console.log(chalk6.magenta.bold("\n\u269B\uFE0F Components\n"));
996
+ function printHeader2() {
997
+ console.log(chalk5.magenta.bold("\n\u269B\uFE0F Components\n"));
1035
998
  }
1036
999
  function printComponents(aggregated, mode) {
1037
1000
  const components = aggregated.topComponents;
@@ -1042,12 +1005,12 @@ function printComponents(aggregated, mode) {
1042
1005
  }
1043
1006
  }
1044
1007
  function printComponentsTable(components) {
1045
- printHeader3();
1008
+ printHeader2();
1046
1009
  const externalComponents = components.filter(
1047
1010
  (comp) => comp.source !== "unknown" && comp.source !== "local"
1048
1011
  );
1049
1012
  if (externalComponents.length === 0) {
1050
- console.log(chalk6.gray(" No external components found"));
1013
+ console.log(chalk5.gray(" No external components found"));
1051
1014
  return;
1052
1015
  }
1053
1016
  const table = new Table({
@@ -1063,12 +1026,12 @@ function printComponentsTable(components) {
1063
1026
  console.log(table.toString());
1064
1027
  }
1065
1028
  function printComponentsChart(components) {
1066
- printHeader3();
1029
+ printHeader2();
1067
1030
  const externalComponents = components.filter(
1068
1031
  (comp) => comp.source !== "unknown" && comp.source !== "local"
1069
1032
  );
1070
1033
  if (externalComponents.length === 0) {
1071
- console.log(chalk6.gray(" No external components found"));
1034
+ console.log(chalk5.gray(" No external components found"));
1072
1035
  return;
1073
1036
  }
1074
1037
  const data = externalComponents.map((comp) => ({
@@ -1077,8 +1040,8 @@ function printComponentsChart(components) {
1077
1040
  }));
1078
1041
  renderBarChart(data, { maxWidth: 50 });
1079
1042
  }
1080
- function printHeader4() {
1081
- console.log(chalk6.blue.bold("\n\u{1F50D} Code Patterns\n"));
1043
+ function printHeader3() {
1044
+ console.log(chalk5.blue.bold("\n\u{1F50D} Code Patterns\n"));
1082
1045
  }
1083
1046
  function printPatterns(aggregated, mode) {
1084
1047
  const patterns = aggregated.patternCounts.filter((p) => p.count > 0);
@@ -1089,9 +1052,9 @@ function printPatterns(aggregated, mode) {
1089
1052
  }
1090
1053
  }
1091
1054
  function printPatternsTable(patterns) {
1092
- printHeader4();
1055
+ printHeader3();
1093
1056
  if (patterns.length === 0) {
1094
- console.log(chalk6.gray(" No patterns found"));
1057
+ console.log(chalk5.gray(" No patterns found"));
1095
1058
  return;
1096
1059
  }
1097
1060
  const table = new Table({
@@ -1106,13 +1069,13 @@ function printPatternsTable(patterns) {
1106
1069
  });
1107
1070
  console.log(table.toString());
1108
1071
  const totalPatterns = patterns.reduce((sum, p) => sum + p.count, 0);
1109
- console.log(chalk6.gray(`
1072
+ console.log(chalk5.gray(`
1110
1073
  Total: ${totalPatterns} patterns detected`));
1111
1074
  }
1112
1075
  function printPatternsChart(patterns) {
1113
- printHeader4();
1076
+ printHeader3();
1114
1077
  if (patterns.length === 0) {
1115
- console.log(chalk6.gray(" No patterns found"));
1078
+ console.log(chalk5.gray(" No patterns found"));
1116
1079
  return;
1117
1080
  }
1118
1081
  const data = patterns.map((pattern) => ({
@@ -1121,8 +1084,8 @@ function printPatternsChart(patterns) {
1121
1084
  }));
1122
1085
  renderBarChart(data, { maxWidth: 50 });
1123
1086
  }
1124
- function printHeader5() {
1125
- console.log(chalk6.blueBright.bold("\n\u{1F4E6} Packages\n"));
1087
+ function printHeader4() {
1088
+ console.log(chalk5.blueBright.bold("\n\u{1F4E6} Packages\n"));
1126
1089
  }
1127
1090
  function printPackages(aggregated, mode) {
1128
1091
  const packages = aggregated.packageDistribution;
@@ -1133,9 +1096,9 @@ function printPackages(aggregated, mode) {
1133
1096
  }
1134
1097
  }
1135
1098
  function printPackagesTable(packages) {
1136
- printHeader5();
1099
+ printHeader4();
1137
1100
  if (packages.length === 0) {
1138
- console.log(chalk6.gray(" No packages found"));
1101
+ console.log(chalk5.gray(" No packages found"));
1139
1102
  return;
1140
1103
  }
1141
1104
  const table = new Table({
@@ -1161,16 +1124,16 @@ function printPackagesTable(packages) {
1161
1124
  );
1162
1125
  const totalExternalUsage = packages.reduce((sum, p) => sum + p.usageCount, 0);
1163
1126
  console.log(
1164
- chalk6.gray(
1127
+ chalk5.gray(
1165
1128
  `
1166
1129
  Total: ${formatCount(packages.length)} packages | ${formatCount(totalComponents)} unique components | ${formatCount(totalExternalUsage)} total usages`
1167
1130
  )
1168
1131
  );
1169
1132
  }
1170
1133
  function printPackagesChart(packages) {
1171
- printHeader5();
1134
+ printHeader4();
1172
1135
  if (packages.length === 0) {
1173
- console.log(chalk6.gray(" No packages found"));
1136
+ console.log(chalk5.gray(" No packages found"));
1174
1137
  return;
1175
1138
  }
1176
1139
  const maxBarWidth = 40;
@@ -1182,12 +1145,37 @@ function printPackagesChart(packages) {
1182
1145
  );
1183
1146
  const emptyLength = maxBarWidth - barLength;
1184
1147
  const paddedLabel = pkg.packageName.padEnd(maxLabelLength, " ");
1185
- const bar = chalk6.green("\u2588".repeat(barLength)) + chalk6.gray("\u2591".repeat(emptyLength));
1148
+ const bar = chalk5.green("\u2588".repeat(barLength)) + chalk5.gray("\u2591".repeat(emptyLength));
1186
1149
  console.log(
1187
- `${paddedLabel} ${bar} ${chalk6.bold(pkg.percentage.toFixed(1) + "%")} (${pkg.usageCount})`
1150
+ `${paddedLabel} ${bar} ${chalk5.bold(pkg.percentage.toFixed(1) + "%")} (${pkg.usageCount})`
1188
1151
  );
1189
1152
  });
1190
1153
  }
1154
+ function printHeader5(errorCount) {
1155
+ console.log(chalk5.red.bold(`
1156
+ \u274C Parse Errors (${errorCount})
1157
+ `));
1158
+ }
1159
+ function printErrors(aggregated) {
1160
+ const errors = aggregated.errors;
1161
+ if (errors.length === 0) {
1162
+ return;
1163
+ }
1164
+ printHeader5(errors.length);
1165
+ const table = new Table({
1166
+ head: ["File", "Error"],
1167
+ style: {
1168
+ head: ["cyan"],
1169
+ border: ["gray"]
1170
+ },
1171
+ colWidths: [50, 80],
1172
+ wordWrap: true
1173
+ });
1174
+ errors.forEach((error) => {
1175
+ table.push([chalk5.yellow(error.file), chalk5.red(error.message)]);
1176
+ });
1177
+ console.log(table.toString());
1178
+ }
1191
1179
  async function findFiles(pattern, ignorePatterns) {
1192
1180
  const files = await glob(pattern, {
1193
1181
  ignore: ignorePatterns,
@@ -1385,16 +1373,13 @@ function registerScanCommand(program2) {
1385
1373
  "**/node_modules/**",
1386
1374
  "**/dist/**",
1387
1375
  "**/build/**"
1376
+ ]).option("--allow-packages <pattern>", "Pattern for what packages to scan", [
1377
+ "**"
1388
1378
  ]).option(
1389
- "--allow-packages <pattern>",
1390
- "Glob pattern for what packages to scan",
1391
- "ALL"
1392
- // TO FIX
1393
- ).option(
1394
1379
  "--ignore-packages <pattern>",
1395
- "Glob pattern for what packages to ignore",
1380
+ "Pattern for what packages to ignore",
1396
1381
  []
1397
- ).option("--summary [mode]", "Show summary stats (log, false)", "log").option("--no-summary", "Do not show summary stats").option("--details", "Show detailed pattern counts").option(
1382
+ ).option("--no-summary", "Hide summary", "table").option(
1398
1383
  "--components [mode]",
1399
1384
  "Show components table/chart (table, chart)",
1400
1385
  "table"
@@ -1406,26 +1391,32 @@ function registerScanCommand(program2) {
1406
1391
  "--patterns [mode]",
1407
1392
  "Show patterns table/chart (table, chart)",
1408
1393
  "table"
1409
- ).option("--no-patterns", "Do not show patterns").action(async (pattern, options) => {
1394
+ ).option("--no-patterns", "Do not show patterns").option(
1395
+ "--ignore-errors",
1396
+ "Continue scanning even if some files fail to parse"
1397
+ ).action(async (pattern, options) => {
1410
1398
  const normalizedOptions = normalizeOptions(options);
1411
1399
  await executeScan(pattern, normalizedOptions);
1412
1400
  });
1413
1401
  }
1414
- function normalizeIgnorePatterns(ignore) {
1415
- if (!ignore) {
1402
+ function normalizeArray(value) {
1403
+ if (!value) {
1416
1404
  return [];
1417
1405
  }
1418
- return Array.isArray(ignore) ? ignore : [ignore];
1406
+ return Array.isArray(value) ? value : [value];
1419
1407
  }
1420
1408
  function normalizeOptions(options) {
1421
1409
  return {
1422
1410
  verbose: options.verbose || false,
1423
1411
  summary: options.summary === false || options.summary === "false" ? false : "log",
1424
- details: options.details || false,
1412
+ noSummary: options.noSummary || false,
1425
1413
  components: options.components || "table",
1426
1414
  packages: options.packages || "table",
1427
1415
  patterns: options.patterns || "table",
1428
- ignore: normalizeIgnorePatterns(options.ignore)
1416
+ ignore: normalizeArray(options.ignore),
1417
+ allowPackages: normalizeArray(options.allowPackages),
1418
+ ignorePackages: normalizeArray(options.ignorePackages),
1419
+ ignoreErrors: options.ignoreErrors || false
1429
1420
  };
1430
1421
  }
1431
1422
  async function executeScan(pattern, options) {
@@ -1433,59 +1424,82 @@ async function executeScan(pattern, options) {
1433
1424
  const spinner = ora("Parsing lockfile...").start();
1434
1425
  try {
1435
1426
  const lockfileResult = findAndParseLockfile(process.cwd());
1427
+ const allPackages = Object.keys(lockfileResult.versions);
1428
+ const filteredPackages = allPackages.filter((pkg) => {
1429
+ const allowed = options.allowPackages.some((p) => minimatch(pkg, p));
1430
+ const ignored = options.ignorePackages.some((p) => minimatch(pkg, p));
1431
+ return allowed && !ignored;
1432
+ });
1433
+ const filteredVersions = {};
1434
+ for (const pkg of filteredPackages) {
1435
+ filteredVersions[pkg] = lockfileResult.versions[pkg];
1436
+ }
1436
1437
  spinner.succeed(
1437
- chalk6.blue(
1438
- `\u{1F4E6} Found ${lockfileResult.lockfileType} lockfile (supports: ${lockfileResult.supportedVersions.join(", ")}) - ${Object.keys(lockfileResult.versions).length} packages`
1439
- )
1438
+ `Found ${lockfileResult.lockfileType} lockfile (supports: ${lockfileResult.supportedVersions.join(", ")}) - ${filteredPackages.length}/${allPackages.length} packages`
1440
1439
  );
1441
- console.log("availablePackages", lockfileResult);
1442
1440
  spinner.start("Finding files...");
1443
1441
  const files = await findFiles(pattern, options.ignore);
1444
1442
  if (files.length === 0) {
1445
- spinner.fail("TEST");
1443
+ spinner.fail(`No files found matching pattern: ${pattern}`);
1446
1444
  return;
1447
1445
  }
1448
- spinner.succeed(chalk6.green(` Found ${files.length} files`));
1446
+ spinner.succeed(chalk5.green(` Found ${files.length} files`));
1449
1447
  spinner.start("Analyzing files...");
1450
1448
  const reports = [];
1449
+ const errors = [];
1451
1450
  for (let i = 0; i < files.length; i++) {
1452
1451
  const file = files[i];
1453
1452
  if (!options.verbose) {
1454
1453
  spinner.text = `Analyzing files... (${i + 1}/${files.length})`;
1455
1454
  }
1456
1455
  try {
1457
- const report = parseFile(file);
1456
+ const report = parseFile(file, { ignoreErrors: options.ignoreErrors });
1458
1457
  if (report) {
1459
1458
  reports.push(report);
1459
+ } else if (options.ignoreErrors) {
1460
+ errors.push({
1461
+ file,
1462
+ message: "Failed to parse file"
1463
+ });
1460
1464
  }
1461
1465
  } catch (error) {
1462
- spinner.stop();
1463
- console.error(chalk6.red(`Error analyzing ${file}: ${error.message}`));
1464
- spinner.start();
1466
+ if (options.ignoreErrors) {
1467
+ errors.push({
1468
+ file,
1469
+ message: error.message || "Unknown error"
1470
+ });
1471
+ } else {
1472
+ throw error;
1473
+ }
1465
1474
  }
1466
1475
  }
1467
- spinner.succeed(
1468
- chalk6.green(`Analysis complete! Analyzed ${reports.length} files`)
1469
- );
1470
1476
  const elapsedTime = (Date.now() - startTime) / 1e3;
1471
- const aggregated = aggregateReports(reports, lockfileResult.versions);
1472
- if (options.packages) {
1477
+ const aggregated = aggregateReports(reports, filteredVersions, errors);
1478
+ printErrors(aggregated);
1479
+ if (options.packages && !options.noPackages) {
1473
1480
  printPackages(aggregated, options.packages);
1474
1481
  }
1475
- if (options.details) {
1476
- printDetails(aggregated);
1477
- }
1478
- if (options.components) {
1482
+ if (options.components && !options.noComponents) {
1479
1483
  printComponents(aggregated, options.components);
1480
1484
  }
1481
- if (options.patterns) {
1485
+ if (options.patterns && !options.noPatterns) {
1482
1486
  printPatterns(aggregated, options.patterns);
1483
1487
  }
1484
- if (options.summary) {
1485
- printSummary(aggregated, elapsedTime);
1488
+ if (options.summary && !options.noSummary) {
1489
+ printSummary(aggregated);
1490
+ }
1491
+ console.log("");
1492
+ const successMessage = aggregated.errors.length > 0 ? ` Analysis complete with ${aggregated.errors.length} error(s)! Analyzed ${reports.length}/${files.length} files in ${formatDuration(elapsedTime)}
1493
+ ` : ` Analysis complete! Analyzed ${reports.length} files in ${formatDuration(elapsedTime)}
1494
+ `;
1495
+ if (aggregated.errors.length > 0) {
1496
+ spinner.warn(chalk5.yellow.bold(successMessage));
1497
+ process.exit(1);
1498
+ } else {
1499
+ spinner.succeed(chalk5.green.bold(successMessage));
1486
1500
  }
1487
1501
  } catch (error) {
1488
- spinner.fail(chalk6.red("Analysis failed: " + error.message));
1502
+ spinner.fail(chalk5.red("Analysis failed: " + error.message));
1489
1503
  console.error(error);
1490
1504
  process.exit(1);
1491
1505
  }
@@ -1493,7 +1507,7 @@ async function executeScan(pattern, options) {
1493
1507
 
1494
1508
  // package.json
1495
1509
  var package_default = {
1496
- version: "1.1.1-beta.1"};
1510
+ version: "1.1.2"};
1497
1511
 
1498
1512
  // src/cli.ts
1499
1513
  var program = new Command();