@aiready/core 0.23.2 → 0.23.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/__tests__/parser-factory.test.d.ts +1 -1
  2. package/dist/__tests__/parser-factory.test.js +62 -50
  3. package/dist/__tests__/python-parser.test.d.ts +1 -1
  4. package/dist/__tests__/python-parser.test.js +111 -109
  5. package/dist/__tests__/scoring.test.d.ts +1 -1
  6. package/dist/__tests__/scoring.test.js +193 -176
  7. package/dist/chunk-3YI4IS3D.mjs +191 -173
  8. package/dist/chunk-5HIXDC3X.mjs +273 -251
  9. package/dist/chunk-5V3L53AE.mjs +805 -0
  10. package/dist/chunk-CKVKHN3G.mjs +228 -211
  11. package/dist/chunk-COHIBX3Q.mjs +213 -195
  12. package/dist/chunk-CWRCDSKZ.mjs +91 -82
  13. package/dist/chunk-D3D3NCRR.mjs +147 -129
  14. package/dist/chunk-HCFYP7UD.mjs +805 -0
  15. package/dist/chunk-HFLFBA6F.mjs +79 -72
  16. package/dist/chunk-HKSARRCD.mjs +66 -58
  17. package/dist/chunk-JJ5JL5FX.mjs +91 -82
  18. package/dist/chunk-KDSTXVLQ.mjs +724 -0
  19. package/dist/chunk-KI7XORTN.mjs +91 -82
  20. package/dist/chunk-LTMHFNFK.mjs +690 -0
  21. package/dist/chunk-LTNXTXRI.mjs +228 -211
  22. package/dist/chunk-M22BXHBR.mjs +805 -0
  23. package/dist/chunk-MH3A3LX6.mjs +200 -182
  24. package/dist/chunk-NGHT7JOG.mjs +697 -0
  25. package/dist/chunk-OQ6IGDXG.mjs +147 -129
  26. package/dist/chunk-QAFB3HXQ.mjs +181 -165
  27. package/dist/chunk-QQBKXHLU.mjs +678 -0
  28. package/dist/chunk-RDHYGES7.mjs +678 -0
  29. package/dist/chunk-SWTDBVYJ.mjs +228 -213
  30. package/dist/chunk-UIWL5JQB.mjs +79 -72
  31. package/dist/chunk-UQGI67WR.mjs +79 -72
  32. package/dist/chunk-UTZOO4XO.mjs +147 -131
  33. package/dist/chunk-X4F46I5L.mjs +213 -195
  34. package/dist/chunk-XKK7YHPX.mjs +204 -186
  35. package/dist/chunk-YCA4FTEK.mjs +190 -172
  36. package/dist/chunk-ZSZRRTJM.mjs +719 -0
  37. package/dist/client-BgmiMoil.d.mts +1344 -0
  38. package/dist/client-BgmiMoil.d.ts +1344 -0
  39. package/dist/client-BxGrPuuN.d.mts +1191 -0
  40. package/dist/client-BxGrPuuN.d.ts +1191 -0
  41. package/dist/client-D-cn9ydj.d.mts +1136 -0
  42. package/dist/client-D-cn9ydj.d.ts +1136 -0
  43. package/dist/client-D9seCH4K.d.mts +1334 -0
  44. package/dist/client-D9seCH4K.d.ts +1334 -0
  45. package/dist/client-DIXIh7rw.d.mts +1193 -0
  46. package/dist/client-DIXIh7rw.d.ts +1193 -0
  47. package/dist/client-DVHXWOHw.d.mts +1245 -0
  48. package/dist/client-DVHXWOHw.d.ts +1245 -0
  49. package/dist/client.d.mts +2 -1098
  50. package/dist/client.d.ts +2 -1098
  51. package/dist/client.js +23 -43
  52. package/dist/client.mjs +3 -25
  53. package/dist/index.d.mts +329 -107
  54. package/dist/index.d.ts +329 -107
  55. package/dist/index.js +329 -340
  56. package/dist/index.mjs +305 -322
  57. package/dist/parsers/parser-factory.d.ts +45 -45
  58. package/dist/parsers/parser-factory.js +86 -84
  59. package/dist/parsers/python-parser.d.ts +33 -28
  60. package/dist/parsers/python-parser.js +224 -222
  61. package/dist/parsers/typescript-parser.d.ts +15 -10
  62. package/dist/parsers/typescript-parser.js +223 -197
  63. package/dist/scoring.d.ts +59 -49
  64. package/dist/scoring.js +129 -127
  65. package/dist/types/language.d.ts +104 -93
  66. package/dist/types/language.js +23 -23
  67. package/dist/types.d.ts +105 -87
  68. package/dist/types.js +1 -1
  69. package/dist/utils/ast-parser.d.ts +42 -33
  70. package/dist/utils/ast-parser.js +159 -162
  71. package/dist/utils/cli-helpers.d.ts +27 -10
  72. package/dist/utils/cli-helpers.js +45 -43
  73. package/dist/utils/config.d.ts +8 -3
  74. package/dist/utils/config.js +67 -69
  75. package/dist/utils/file-scanner.d.ts +1 -1
  76. package/dist/utils/file-scanner.js +80 -76
  77. package/dist/utils/metrics.d.ts +1 -1
  78. package/dist/utils/metrics.js +2 -2
  79. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -127,12 +127,17 @@ __export(index_exports, {
127
127
  getProjectSizeTier: () => getProjectSizeTier,
128
128
  getRating: () => getRating,
129
129
  getRatingDisplay: () => getRatingDisplay,
130
+ getRatingSlug: () => getRatingSlug,
130
131
  getRatingWithContext: () => getRatingWithContext,
131
132
  getRecommendedThreshold: () => getRecommendedThreshold,
132
133
  getRepoMetadata: () => getRepoMetadata,
133
134
  getSafetyIcon: () => getSafetyIcon,
134
135
  getScoreBar: () => getScoreBar,
136
+ getSeverityBadge: () => getSeverityBadge,
135
137
  getSeverityColor: () => getSeverityColor,
138
+ getSeverityEnum: () => getSeverityEnum,
139
+ getSeverityLevel: () => getSeverityLevel,
140
+ getSeverityValue: () => getSeverityValue,
136
141
  getSupportedLanguages: () => getSupportedLanguages,
137
142
  getToolWeight: () => getToolWeight,
138
143
  getWasmPath: () => getWasmPath,
@@ -328,33 +333,28 @@ var UnifiedReportSchema = import_zod.z.object({
328
333
  // src/types.ts
329
334
  var GLOBAL_INFRA_OPTIONS = [
330
335
  "rootDir",
331
- // Essential for every tool
332
336
  "include",
333
337
  "exclude",
334
- "onProgress",
335
- "progressCallback",
336
- "includeTests",
337
- "useSmartDefaults",
338
- "streamResults",
339
- "batchSize",
340
- "costConfig",
341
338
  "tools",
342
- "toolConfigs"
339
+ "scoring"
340
+ ];
341
+ var GLOBAL_SCAN_OPTIONS = [
342
+ "rootDir",
343
+ "include",
344
+ "exclude",
345
+ "config",
346
+ "threshold",
347
+ "output",
348
+ "format",
349
+ "parallel",
350
+ "showBreakdown"
343
351
  ];
344
352
  var COMMON_FINE_TUNING_OPTIONS = [
345
353
  "maxDepth",
346
354
  "minSimilarity",
347
- "minLines",
348
- "minCohesion",
349
- // AI Signal Clarity options
350
- "checkMagicLiterals",
351
- "checkBooleanTraps",
352
- "checkAmbiguousNames",
353
- "checkUndocumentedExports",
354
- "checkImplicitSideEffects",
355
- "checkDeepCallbacks"
355
+ "threshold",
356
+ "showBreakdown"
356
357
  ];
357
- var GLOBAL_SCAN_OPTIONS = [...GLOBAL_INFRA_OPTIONS];
358
358
 
359
359
  // src/types/language.ts
360
360
  var Language = /* @__PURE__ */ ((Language3) => {
@@ -645,7 +645,7 @@ async function scanFiles(options) {
645
645
  try {
646
646
  const txt = await (0, import_promises.readFile)(ignoreFilePath, "utf-8");
647
647
  ignoreFromFile = txt.split(/\r?\n/).map((s) => s.trim()).filter(Boolean).filter((l) => !l.startsWith("#")).filter((l) => !l.startsWith("!"));
648
- } catch (e) {
648
+ } catch {
649
649
  ignoreFromFile = [];
650
650
  }
651
651
  }
@@ -699,7 +699,7 @@ async function scanFiles(options) {
699
699
  return !ig.ignores(rel);
700
700
  });
701
701
  return filtered;
702
- } catch (e) {
702
+ } catch {
703
703
  return files;
704
704
  }
705
705
  }
@@ -707,14 +707,14 @@ async function scanFiles(options) {
707
707
  }
708
708
  async function scanEntries(options) {
709
709
  const files = await scanFiles(options);
710
- const { rootDir, include = ["**/*"], exclude, includeTests } = options;
710
+ const { rootDir, exclude, includeTests } = options;
711
711
  const ignoreFilePath = (0, import_path.join)(rootDir || ".", ".aireadyignore");
712
712
  let ignoreFromFile = [];
713
713
  if ((0, import_fs.existsSync)(ignoreFilePath)) {
714
714
  try {
715
715
  const txt = await (0, import_promises.readFile)(ignoreFilePath, "utf-8");
716
716
  ignoreFromFile = txt.split(/\r?\n/).map((s) => s.trim()).filter(Boolean).filter((l) => !l.startsWith("#")).filter((l) => !l.startsWith("!"));
717
- } catch (e) {
717
+ } catch {
718
718
  ignoreFromFile = [];
719
719
  }
720
720
  }
@@ -783,6 +783,7 @@ function isSourceFile(filePath) {
783
783
  // src/utils/cli-helpers.ts
784
784
  var import_fs2 = require("fs");
785
785
  var import_path2 = require("path");
786
+ var import_chalk = __toESM(require("chalk"));
786
787
  function resolveOutputPath(userPath, defaultFilename, workingDir = process.cwd()) {
787
788
  let outputPath;
788
789
  if (userPath) {
@@ -850,22 +851,72 @@ function emitProgress(processed, total, toolId, message, onProgress, throttleCou
850
851
  onProgress(processed, total, `${message} (${processed}/${total})`);
851
852
  }
852
853
  }
853
- function getSeverityColor(severity, chalk) {
854
+ function getSeverityColor(severity, chalkInstance = import_chalk.default) {
854
855
  switch (severity.toLowerCase()) {
855
856
  case "critical":
856
857
  case "high-risk":
857
858
  case "blind-risk":
858
- return chalk.red;
859
+ return chalkInstance.red;
859
860
  case "major":
860
861
  case "moderate-risk":
861
- return chalk.yellow;
862
+ return chalkInstance.yellow;
862
863
  case "minor":
863
864
  case "safe":
864
- return chalk.green;
865
+ return chalkInstance.green;
866
+ case "info":
867
+ return chalkInstance.blue;
868
+ default:
869
+ return chalkInstance.white;
870
+ }
871
+ }
872
+ function getSeverityValue(s) {
873
+ if (!s) return 0;
874
+ switch (s.toLowerCase()) {
875
+ case "critical":
876
+ return 4;
877
+ case "major":
878
+ return 3;
879
+ case "minor":
880
+ return 2;
865
881
  case "info":
866
- return chalk.blue;
882
+ return 1;
867
883
  default:
868
- return chalk.white;
884
+ return 0;
885
+ }
886
+ }
887
+ function getSeverityLevel(s) {
888
+ return getSeverityValue(s);
889
+ }
890
+ function getSeverityBadge(severity, chalkInstance = import_chalk.default) {
891
+ const val = getSeverityValue(
892
+ typeof severity === "string" ? severity : severity
893
+ );
894
+ switch (val) {
895
+ case 4:
896
+ return chalkInstance.bgRed.white.bold(" CRITICAL ");
897
+ case 3:
898
+ return chalkInstance.bgYellow.black.bold(" MAJOR ");
899
+ case 2:
900
+ return chalkInstance.bgBlue.white.bold(" MINOR ");
901
+ case 1:
902
+ return chalkInstance.bgCyan.black(" INFO ");
903
+ default:
904
+ return chalkInstance.bgCyan.black(" INFO ");
905
+ }
906
+ }
907
+ function getSeverityEnum(s) {
908
+ const level = getSeverityLevel(s);
909
+ switch (level) {
910
+ case 4:
911
+ return "critical";
912
+ case 3:
913
+ return "major";
914
+ case 2:
915
+ return "minor";
916
+ case 1:
917
+ return "info";
918
+ default:
919
+ return "info";
869
920
  }
870
921
  }
871
922
  function findLatestReport(dirPath) {
@@ -1314,94 +1365,6 @@ var TypeScriptParser = class {
1314
1365
  }
1315
1366
  };
1316
1367
 
1317
- // src/parsers/tree-sitter-utils.ts
1318
- var Parser = __toESM(require("web-tree-sitter"));
1319
- var path = __toESM(require("path"));
1320
- var fs = __toESM(require("fs"));
1321
- var isTreeSitterInitialized = false;
1322
- async function initTreeSitter() {
1323
- if (isTreeSitterInitialized) return;
1324
- try {
1325
- const wasmPath = getWasmPath("web-tree-sitter");
1326
- await Parser.Parser.init({
1327
- locateFile() {
1328
- return wasmPath || "web-tree-sitter.wasm";
1329
- }
1330
- });
1331
- isTreeSitterInitialized = true;
1332
- } catch (error) {
1333
- console.error("Failed to initialize web-tree-sitter:", error);
1334
- isTreeSitterInitialized = true;
1335
- }
1336
- }
1337
- function findInPnpmStore(startDir, fileName, depth = 0) {
1338
- if (depth > 8) return null;
1339
- const pnpmDir = path.join(startDir, "node_modules", ".pnpm");
1340
- if (fs.existsSync(pnpmDir)) {
1341
- return findFileRecursively(pnpmDir, fileName, 0);
1342
- }
1343
- const parent = path.dirname(startDir);
1344
- if (parent === startDir) return null;
1345
- return findInPnpmStore(parent, fileName, depth + 1);
1346
- }
1347
- function findFileRecursively(dir, fileName, depth) {
1348
- if (depth > 6) return null;
1349
- try {
1350
- const entries = fs.readdirSync(dir, { withFileTypes: true });
1351
- for (const entry of entries) {
1352
- if (entry.isFile() && entry.name === fileName) {
1353
- return path.join(dir, entry.name);
1354
- }
1355
- }
1356
- for (const entry of entries) {
1357
- if (entry.isDirectory()) {
1358
- const found = findFileRecursively(
1359
- path.join(dir, entry.name),
1360
- fileName,
1361
- depth + 1
1362
- );
1363
- if (found) return found;
1364
- }
1365
- }
1366
- } catch (err) {
1367
- }
1368
- return null;
1369
- }
1370
- function getWasmPath(language) {
1371
- const wasmFileName = language === "web-tree-sitter" ? "web-tree-sitter.wasm" : `tree-sitter-${language}.wasm`;
1372
- const immediatePaths = [
1373
- path.join(process.cwd(), wasmFileName),
1374
- path.join(__dirname, wasmFileName),
1375
- path.join(__dirname, "assets", wasmFileName)
1376
- ];
1377
- for (const p of immediatePaths) {
1378
- if (fs.existsSync(p)) return p;
1379
- }
1380
- const pnpmPath = findInPnpmStore(__dirname, wasmFileName);
1381
- if (pnpmPath) return pnpmPath;
1382
- const pnpmPathCwd = findInPnpmStore(process.cwd(), wasmFileName);
1383
- if (pnpmPathCwd) return pnpmPathCwd;
1384
- console.warn(
1385
- `[Parser] WASM file for ${language} not found. CWD: ${process.cwd()}, DIR: ${__dirname}`
1386
- );
1387
- return null;
1388
- }
1389
- async function setupParser(language) {
1390
- await initTreeSitter();
1391
- const wasmPath = getWasmPath(language);
1392
- if (!wasmPath) {
1393
- return null;
1394
- }
1395
- try {
1396
- const parser = new Parser.Parser();
1397
- const Lang = await Parser.Language.load(wasmPath);
1398
- parser.setLanguage(Lang);
1399
- return parser;
1400
- } catch (error) {
1401
- return null;
1402
- }
1403
- }
1404
-
1405
1368
  // src/parsers/metadata-utils.ts
1406
1369
  function analyzeNodeMetadata(node, code, options) {
1407
1370
  const metadata = {
@@ -1497,11 +1460,97 @@ function analyzeNodeMetadata(node, code, options) {
1497
1460
  return metadata;
1498
1461
  }
1499
1462
 
1500
- // src/parsers/python-parser.ts
1501
- var PythonParser = class {
1463
+ // src/parsers/tree-sitter-utils.ts
1464
+ var Parser = __toESM(require("web-tree-sitter"));
1465
+ var path = __toESM(require("path"));
1466
+ var fs = __toESM(require("fs"));
1467
+ var isTreeSitterInitialized = false;
1468
+ async function initTreeSitter() {
1469
+ if (isTreeSitterInitialized) return;
1470
+ try {
1471
+ const wasmPath = getWasmPath("web-tree-sitter");
1472
+ await Parser.Parser.init({
1473
+ locateFile() {
1474
+ return wasmPath || "web-tree-sitter.wasm";
1475
+ }
1476
+ });
1477
+ isTreeSitterInitialized = true;
1478
+ } catch (error) {
1479
+ console.error("Failed to initialize web-tree-sitter:", error);
1480
+ isTreeSitterInitialized = true;
1481
+ }
1482
+ }
1483
+ function findInPnpmStore(startDir, fileName, depth = 0) {
1484
+ if (depth > 8) return null;
1485
+ const pnpmDir = path.join(startDir, "node_modules", ".pnpm");
1486
+ if (fs.existsSync(pnpmDir)) {
1487
+ return findFileRecursively(pnpmDir, fileName, 0);
1488
+ }
1489
+ const parent = path.dirname(startDir);
1490
+ if (parent === startDir) return null;
1491
+ return findInPnpmStore(parent, fileName, depth + 1);
1492
+ }
1493
+ function findFileRecursively(dir, fileName, depth) {
1494
+ if (depth > 6) return null;
1495
+ try {
1496
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
1497
+ for (const entry of entries) {
1498
+ if (entry.isFile() && entry.name === fileName) {
1499
+ return path.join(dir, entry.name);
1500
+ }
1501
+ }
1502
+ for (const entry of entries) {
1503
+ if (entry.isDirectory()) {
1504
+ const found = findFileRecursively(
1505
+ path.join(dir, entry.name),
1506
+ fileName,
1507
+ depth + 1
1508
+ );
1509
+ if (found) return found;
1510
+ }
1511
+ }
1512
+ } catch {
1513
+ }
1514
+ return null;
1515
+ }
1516
+ function getWasmPath(language) {
1517
+ const wasmFileName = language === "web-tree-sitter" ? "web-tree-sitter.wasm" : `tree-sitter-${language}.wasm`;
1518
+ const immediatePaths = [
1519
+ path.join(process.cwd(), wasmFileName),
1520
+ path.join(__dirname, wasmFileName),
1521
+ path.join(__dirname, "assets", wasmFileName)
1522
+ ];
1523
+ for (const p of immediatePaths) {
1524
+ if (fs.existsSync(p)) return p;
1525
+ }
1526
+ const pnpmPath = findInPnpmStore(__dirname, wasmFileName);
1527
+ if (pnpmPath) return pnpmPath;
1528
+ const pnpmPathCwd = findInPnpmStore(process.cwd(), wasmFileName);
1529
+ if (pnpmPathCwd) return pnpmPathCwd;
1530
+ console.warn(
1531
+ `[Parser] WASM file for ${language} not found. CWD: ${process.cwd()}, DIR: ${__dirname}`
1532
+ );
1533
+ return null;
1534
+ }
1535
+ async function setupParser(language) {
1536
+ await initTreeSitter();
1537
+ const wasmPath = getWasmPath(language);
1538
+ if (!wasmPath) {
1539
+ return null;
1540
+ }
1541
+ try {
1542
+ const parser = new Parser.Parser();
1543
+ const Lang = await Parser.Language.load(wasmPath);
1544
+ parser.setLanguage(Lang);
1545
+ return parser;
1546
+ } catch {
1547
+ return null;
1548
+ }
1549
+ }
1550
+
1551
+ // src/parsers/base-parser.ts
1552
+ var BaseLanguageParser = class {
1502
1553
  constructor() {
1503
- this.language = "python" /* Python */;
1504
- this.extensions = [".py"];
1505
1554
  this.parser = null;
1506
1555
  this.initialized = false;
1507
1556
  }
@@ -1510,19 +1559,19 @@ var PythonParser = class {
1510
1559
  */
1511
1560
  async initialize() {
1512
1561
  if (this.initialized) return;
1513
- this.parser = await setupParser("python");
1514
- this.initialized = true;
1562
+ try {
1563
+ this.parser = await setupParser(this.getParserName());
1564
+ this.initialized = true;
1565
+ } catch (error) {
1566
+ console.warn(`Failed to initialize ${this.language} parser:`, error);
1567
+ }
1515
1568
  }
1516
- async getAST(code, filePath) {
1569
+ async getAST(code, _filePath) {
1570
+ void _filePath;
1517
1571
  if (!this.initialized) await this.initialize();
1518
1572
  if (!this.parser) return null;
1519
1573
  return this.parser.parse(code);
1520
1574
  }
1521
- analyzeMetadata(node, code) {
1522
- return analyzeNodeMetadata(node, code, {
1523
- sideEffectSignatures: ["print(", "input(", "open("]
1524
- });
1525
- }
1526
1575
  parse(code, filePath) {
1527
1576
  if (!this.initialized || !this.parser) {
1528
1577
  return this.parseRegex(code, filePath);
@@ -1532,19 +1581,42 @@ var PythonParser = class {
1532
1581
  if (!tree || tree.rootNode.type === "ERROR" || tree.rootNode.hasError) {
1533
1582
  return this.parseRegex(code, filePath);
1534
1583
  }
1535
- const rootNode = tree.rootNode;
1536
- const imports = this.extractImportsAST(rootNode);
1537
- const exports2 = this.extractExportsAST(rootNode, code);
1584
+ const imports = this.extractImportsAST(tree.rootNode);
1585
+ const exports2 = this.extractExportsAST(tree.rootNode, code);
1538
1586
  return {
1539
1587
  exports: exports2,
1540
1588
  imports,
1541
- language: "python" /* Python */,
1589
+ language: this.language,
1542
1590
  warnings: []
1543
1591
  };
1544
1592
  } catch (error) {
1593
+ console.warn(
1594
+ `AST parsing failed for ${filePath}, falling back to regex: ${error.message}`
1595
+ );
1545
1596
  return this.parseRegex(code, filePath);
1546
1597
  }
1547
1598
  }
1599
+ canHandle(filePath) {
1600
+ const lowerPath = filePath.toLowerCase();
1601
+ return this.extensions.some((ext) => lowerPath.endsWith(ext));
1602
+ }
1603
+ };
1604
+
1605
+ // src/parsers/python-parser.ts
1606
+ var PythonParser = class extends BaseLanguageParser {
1607
+ constructor() {
1608
+ super(...arguments);
1609
+ this.language = "python" /* Python */;
1610
+ this.extensions = [".py"];
1611
+ }
1612
+ getParserName() {
1613
+ return "python";
1614
+ }
1615
+ analyzeMetadata(node, code) {
1616
+ return analyzeNodeMetadata(node, code, {
1617
+ sideEffectSignatures: ["print(", "input(", "open("]
1618
+ });
1619
+ }
1548
1620
  extractImportsAST(rootNode) {
1549
1621
  const imports = [];
1550
1622
  const processImportNode = (node) => {
@@ -1730,10 +1802,11 @@ var PythonParser = class {
1730
1802
  ]
1731
1803
  };
1732
1804
  } catch (error) {
1733
- throw new ParseError(
1734
- `Failed to parse Python file ${filePath}: ${error.message}`,
1735
- filePath
1805
+ const wrapper = new Error(
1806
+ `Failed to parse Python file ${filePath}: ${error.message}`
1736
1807
  );
1808
+ wrapper.cause = error;
1809
+ throw wrapper;
1737
1810
  }
1738
1811
  }
1739
1812
  getNamingConventions() {
@@ -1764,6 +1837,7 @@ var PythonParser = class {
1764
1837
  return filePath.toLowerCase().endsWith(".py");
1765
1838
  }
1766
1839
  extractImportsRegex(code, _filePath) {
1840
+ void _filePath;
1767
1841
  const imports = [];
1768
1842
  const lines = code.split("\n");
1769
1843
  const importRegex = /^\s*import\s+([a-zA-Z0-9_., ]+)/;
@@ -1814,6 +1888,7 @@ var PythonParser = class {
1814
1888
  return imports;
1815
1889
  }
1816
1890
  extractExportsRegex(code, _filePath) {
1891
+ void _filePath;
1817
1892
  const exports2 = [];
1818
1893
  const lines = code.split("\n");
1819
1894
  const funcRegex = /^def\s+([a-zA-Z0-9_]+)\s*\(/;
@@ -1978,25 +2053,14 @@ function extractParameterNames(node) {
1978
2053
  }
1979
2054
 
1980
2055
  // src/parsers/java-parser.ts
1981
- var JavaParser = class {
2056
+ var JavaParser = class extends BaseLanguageParser {
1982
2057
  constructor() {
2058
+ super(...arguments);
1983
2059
  this.language = "java" /* Java */;
1984
2060
  this.extensions = [".java"];
1985
- this.parser = null;
1986
- this.initialized = false;
1987
2061
  }
1988
- /**
1989
- * Initialize the tree-sitter parser
1990
- */
1991
- async initialize() {
1992
- if (this.initialized) return;
1993
- this.parser = await setupParser("java");
1994
- this.initialized = true;
1995
- }
1996
- async getAST(code, filePath) {
1997
- if (!this.initialized) await this.initialize();
1998
- if (!this.parser) return null;
1999
- return this.parser.parse(code);
2062
+ getParserName() {
2063
+ return "java";
2000
2064
  }
2001
2065
  analyzeMetadata(node, code) {
2002
2066
  return analyzeGeneralMetadata(node, code, {
@@ -2008,32 +2072,7 @@ var JavaParser = class {
2008
2072
  ]
2009
2073
  });
2010
2074
  }
2011
- parse(code, filePath) {
2012
- if (!this.initialized || !this.parser) {
2013
- return this.parseRegex(code, filePath);
2014
- }
2015
- try {
2016
- const tree = this.parser.parse(code);
2017
- if (!tree || tree.rootNode.type === "ERROR" || tree.rootNode.hasError) {
2018
- return this.parseRegex(code, filePath);
2019
- }
2020
- const rootNode = tree.rootNode;
2021
- const imports = this.extractImportsAST(rootNode);
2022
- const exports2 = this.extractExportsAST(rootNode, code);
2023
- return {
2024
- exports: exports2,
2025
- imports,
2026
- language: "java" /* Java */,
2027
- warnings: []
2028
- };
2029
- } catch (error) {
2030
- console.warn(
2031
- `AST parsing failed for ${filePath}, falling back to regex: ${error.message}`
2032
- );
2033
- return this.parseRegex(code, filePath);
2034
- }
2035
- }
2036
- parseRegex(code, filePath) {
2075
+ parseRegex(code) {
2037
2076
  const lines = code.split("\n");
2038
2077
  const exports2 = [];
2039
2078
  const imports = [];
@@ -2107,10 +2146,8 @@ var JavaParser = class {
2107
2146
  for (const node of rootNode.children) {
2108
2147
  if (node.type === "import_declaration") {
2109
2148
  const sourceArr = [];
2110
- let isStatic = false;
2111
2149
  let isWildcard = false;
2112
2150
  for (const child of node.children) {
2113
- if (child.type === "static") isStatic = true;
2114
2151
  if (child.type === "scoped_identifier" || child.type === "identifier") {
2115
2152
  sourceArr.push(child.text);
2116
2153
  }
@@ -2221,55 +2258,21 @@ var JavaParser = class {
2221
2258
  };
2222
2259
 
2223
2260
  // src/parsers/csharp-parser.ts
2224
- var CSharpParser = class {
2261
+ var CSharpParser = class extends BaseLanguageParser {
2225
2262
  constructor() {
2263
+ super(...arguments);
2226
2264
  this.language = "csharp" /* CSharp */;
2227
2265
  this.extensions = [".cs"];
2228
- this.parser = null;
2229
- this.initialized = false;
2230
2266
  }
2231
- /**
2232
- * Initialize the tree-sitter parser
2233
- */
2234
- async initialize() {
2235
- if (this.initialized) return;
2236
- this.parser = await setupParser("c_sharp");
2237
- this.initialized = true;
2238
- }
2239
- async getAST(code, filePath) {
2240
- if (!this.initialized) await this.initialize();
2241
- if (!this.parser) return null;
2242
- return this.parser.parse(code);
2267
+ getParserName() {
2268
+ return "c_sharp";
2243
2269
  }
2244
2270
  analyzeMetadata(node, code) {
2245
2271
  return analyzeGeneralMetadata(node, code, {
2246
2272
  sideEffectSignatures: ["Console.Write", "File.Write", "Logging."]
2247
2273
  });
2248
2274
  }
2249
- parse(code, filePath) {
2250
- if (!this.initialized || !this.parser) {
2251
- return this.parseRegex(code, filePath);
2252
- }
2253
- try {
2254
- const tree = this.parser.parse(code);
2255
- if (!tree) throw new Error("Parser.parse(code) returned null");
2256
- const rootNode = tree.rootNode;
2257
- const imports = this.extractImportsAST(rootNode);
2258
- const exports2 = this.extractExportsAST(rootNode, code);
2259
- return {
2260
- exports: exports2,
2261
- imports,
2262
- language: "csharp" /* CSharp */,
2263
- warnings: []
2264
- };
2265
- } catch (error) {
2266
- console.warn(
2267
- `AST parsing failed for ${filePath}, falling back to regex: ${error.message}`
2268
- );
2269
- return this.parseRegex(code, filePath);
2270
- }
2271
- }
2272
- parseRegex(code, filePath) {
2275
+ parseRegex(code) {
2273
2276
  const lines = code.split("\n");
2274
2277
  const exports2 = [];
2275
2278
  const imports = [];
@@ -2465,57 +2468,21 @@ var CSharpParser = class {
2465
2468
  };
2466
2469
 
2467
2470
  // src/parsers/go-parser.ts
2468
- var GoParser = class {
2471
+ var GoParser = class extends BaseLanguageParser {
2469
2472
  constructor() {
2473
+ super(...arguments);
2470
2474
  this.language = "go" /* Go */;
2471
2475
  this.extensions = [".go"];
2472
- this.parser = null;
2473
- this.initialized = false;
2474
- }
2475
- /**
2476
- * Initialize the tree-sitter parser
2477
- */
2478
- async initialize() {
2479
- if (this.initialized) return;
2480
- this.parser = await setupParser("go");
2481
- this.initialized = true;
2482
2476
  }
2483
- async getAST(code, filePath) {
2484
- if (!this.initialized) await this.initialize();
2485
- if (!this.parser) return null;
2486
- return this.parser.parse(code);
2477
+ getParserName() {
2478
+ return "go";
2487
2479
  }
2488
2480
  analyzeMetadata(node, code) {
2489
2481
  return analyzeGeneralMetadata(node, code, {
2490
2482
  sideEffectSignatures: ["<-", "fmt.Print", "fmt.Fprintf", "os.Exit"]
2491
2483
  });
2492
2484
  }
2493
- parse(code, filePath) {
2494
- if (!this.initialized || !this.parser) {
2495
- return this.parseRegex(code, filePath);
2496
- }
2497
- try {
2498
- const tree = this.parser.parse(code);
2499
- if (!tree || tree.rootNode.type === "ERROR" || tree.rootNode.hasError) {
2500
- return this.parseRegex(code, filePath);
2501
- }
2502
- const rootNode = tree.rootNode;
2503
- const imports = this.extractImportsAST(rootNode);
2504
- const exports2 = this.extractExportsAST(rootNode, code);
2505
- return {
2506
- exports: exports2,
2507
- imports,
2508
- language: "go" /* Go */,
2509
- warnings: []
2510
- };
2511
- } catch (error) {
2512
- console.warn(
2513
- `AST parsing failed for ${filePath}, falling back to regex: ${error.message}`
2514
- );
2515
- return this.parseRegex(code, filePath);
2516
- }
2517
- }
2518
- parseRegex(code, filePath) {
2485
+ parseRegex(code) {
2519
2486
  const lines = code.split("\n");
2520
2487
  const exports2 = [];
2521
2488
  const imports = [];
@@ -2841,48 +2808,7 @@ function getSupportedLanguages() {
2841
2808
  return ParserFactory.getInstance().getSupportedLanguages();
2842
2809
  }
2843
2810
 
2844
- // src/utils/ast-parser.ts
2845
- function parseFileExports(code, filePath) {
2846
- const parser = getParser(filePath);
2847
- if (parser && parser.language !== "typescript" /* TypeScript */ && parser.language !== "javascript" /* JavaScript */) {
2848
- try {
2849
- const result = parser.parse(code, filePath);
2850
- return {
2851
- exports: result.exports.map((e) => ({
2852
- name: e.name,
2853
- type: e.type,
2854
- imports: e.imports || [],
2855
- dependencies: e.dependencies || [],
2856
- typeReferences: e.typeReferences || [],
2857
- loc: e.loc ? {
2858
- start: { line: e.loc.start.line, column: e.loc.start.column },
2859
- end: { line: e.loc.end.line, column: e.loc.end.column }
2860
- } : void 0
2861
- })),
2862
- imports: result.imports.map((i) => ({
2863
- source: i.source,
2864
- specifiers: i.specifiers,
2865
- isTypeOnly: i.isTypeOnly || false
2866
- }))
2867
- };
2868
- } catch (e) {
2869
- return { exports: [], imports: [] };
2870
- }
2871
- }
2872
- try {
2873
- const ast = (0, import_typescript_estree2.parse)(code, {
2874
- loc: true,
2875
- range: true,
2876
- jsx: filePath.endsWith(".tsx") || filePath.endsWith(".jsx"),
2877
- filePath
2878
- });
2879
- const imports = extractFileImports(ast);
2880
- const exports2 = extractExportsWithDependencies(ast, imports);
2881
- return { exports: exports2, imports };
2882
- } catch (error) {
2883
- return { exports: [], imports: [] };
2884
- }
2885
- }
2811
+ // src/utils/ast-visitor.ts
2886
2812
  function extractFileImports(ast) {
2887
2813
  const imports = [];
2888
2814
  for (const node of ast.body) {
@@ -2940,22 +2866,23 @@ function extractExportsWithDependencies(ast, fileImports) {
2940
2866
  }
2941
2867
  return exports2;
2942
2868
  }
2943
- function extractFromDeclaration(declaration) {
2869
+ function extractFromDeclaration(node) {
2870
+ if (!node) return [];
2944
2871
  const results = [];
2945
- if (declaration.type === "FunctionDeclaration" && "id" in declaration && declaration.id) {
2946
- results.push({ name: declaration.id.name, type: "function" });
2947
- } else if (declaration.type === "ClassDeclaration" && "id" in declaration && declaration.id) {
2948
- results.push({ name: declaration.id.name, type: "class" });
2949
- } else if (declaration.type === "VariableDeclaration") {
2950
- for (const declarator of declaration.declarations) {
2951
- if (declarator.id.type === "Identifier") {
2952
- results.push({ name: declarator.id.name, type: "const" });
2872
+ if (node.type === "FunctionDeclaration" && node.id) {
2873
+ results.push({ name: node.id.name, type: "function" });
2874
+ } else if (node.type === "ClassDeclaration" && node.id) {
2875
+ results.push({ name: node.id.name, type: "class" });
2876
+ } else if (node.type === "VariableDeclaration") {
2877
+ for (const decl of node.declarations) {
2878
+ if (decl.id.type === "Identifier") {
2879
+ results.push({ name: decl.id.name, type: "const" });
2953
2880
  }
2954
2881
  }
2955
- } else if (declaration.type === "TSTypeAliasDeclaration") {
2956
- results.push({ name: declaration.id.name, type: "type" });
2957
- } else if (declaration.type === "TSInterfaceDeclaration") {
2958
- results.push({ name: declaration.id.name, type: "interface" });
2882
+ } else if (node.type === "TSInterfaceDeclaration" && node.id) {
2883
+ results.push({ name: node.id.name, type: "interface" });
2884
+ } else if (node.type === "TSTypeAliasDeclaration" && node.id) {
2885
+ results.push({ name: node.id.name, type: "type" });
2959
2886
  }
2960
2887
  return results;
2961
2888
  }
@@ -2983,16 +2910,6 @@ function findUsedImports(node, importedNames) {
2983
2910
  visit(node);
2984
2911
  return Array.from(usedImports);
2985
2912
  }
2986
- function calculateImportSimilarity(export1, export2) {
2987
- if (export1.imports.length === 0 && export2.imports.length === 0) {
2988
- return 1;
2989
- }
2990
- const set1 = new Set(export1.imports);
2991
- const set2 = new Set(export2.imports);
2992
- const intersection = new Set([...set1].filter((x) => set2.has(x)));
2993
- const union = /* @__PURE__ */ new Set([...set1, ...set2]);
2994
- return intersection.size / union.size;
2995
- }
2996
2913
  function extractTypeReferences(node) {
2997
2914
  const types = /* @__PURE__ */ new Set();
2998
2915
  function visit(n) {
@@ -3030,13 +2947,70 @@ function extractTypeReferences(node) {
3030
2947
  visit(node);
3031
2948
  return Array.from(types);
3032
2949
  }
3033
- function parseCode(code, language) {
2950
+
2951
+ // src/utils/ast-parser.ts
2952
+ function parseFileExports(code, filePath) {
2953
+ const parser = getParser(filePath);
2954
+ if (parser && parser.language !== "typescript" /* TypeScript */ && parser.language !== "javascript" /* JavaScript */) {
2955
+ try {
2956
+ const result = parser.parse(code, filePath);
2957
+ return {
2958
+ exports: result.exports.map((e) => ({
2959
+ name: e.name,
2960
+ type: e.type,
2961
+ imports: e.imports || [],
2962
+ dependencies: e.dependencies || [],
2963
+ typeReferences: e.typeReferences || [],
2964
+ loc: e.loc ? {
2965
+ start: { line: e.loc.start.line, column: e.loc.start.column },
2966
+ end: { line: e.loc.end.line, column: e.loc.end.column }
2967
+ } : void 0
2968
+ })),
2969
+ imports: result.imports.map((i) => ({
2970
+ source: i.source,
2971
+ specifiers: i.specifiers,
2972
+ isTypeOnly: i.isTypeOnly || false
2973
+ }))
2974
+ };
2975
+ } catch {
2976
+ return { exports: [], imports: [] };
2977
+ }
2978
+ }
2979
+ try {
2980
+ const ast = (0, import_typescript_estree2.parse)(code, {
2981
+ loc: true,
2982
+ range: true,
2983
+ jsx: filePath.endsWith(".tsx") || filePath.endsWith(".jsx"),
2984
+ filePath
2985
+ });
2986
+ const imports = extractFileImports(ast);
2987
+ const exports2 = extractExportsWithDependencies(ast, imports);
2988
+ return { exports: exports2, imports };
2989
+ } catch {
2990
+ return { exports: [], imports: [] };
2991
+ }
2992
+ }
2993
+ function calculateImportSimilarity(export1, export2) {
2994
+ if (export1.imports.length === 0 && export2.imports.length === 0) {
2995
+ return 1;
2996
+ }
2997
+ const set1 = new Set(export1.imports);
2998
+ const set2 = new Set(export2.imports);
2999
+ const intersection = new Set([...set1].filter((x) => set2.has(x)));
3000
+ const union = /* @__PURE__ */ new Set([...set1, ...set2]);
3001
+ return intersection.size / union.size;
3002
+ }
3003
+ function parseCode(_code, _language) {
3004
+ void _code;
3005
+ void _language;
3034
3006
  return null;
3035
3007
  }
3036
- function extractFunctions(ast) {
3008
+ function extractFunctions(_ast) {
3009
+ void _ast;
3037
3010
  return [];
3038
3011
  }
3039
- function extractImports(ast) {
3012
+ function extractImports(_ast) {
3013
+ void _ast;
3040
3014
  return [];
3041
3015
  }
3042
3016
 
@@ -3093,14 +3067,14 @@ async function loadConfig(rootDir) {
3093
3067
  return config;
3094
3068
  } catch (error) {
3095
3069
  const errorMessage = error instanceof Error ? error.message : String(error);
3096
- const e = new Error(
3070
+ const configError = new Error(
3097
3071
  `Failed to load config from ${configPath}: ${errorMessage}`
3098
3072
  );
3099
3073
  try {
3100
- e.cause = error instanceof Error ? error : void 0;
3074
+ configError.cause = error instanceof Error ? error : void 0;
3101
3075
  } catch {
3102
3076
  }
3103
- throw e;
3077
+ throw configError;
3104
3078
  }
3105
3079
  }
3106
3080
  const parent = (0, import_path3.dirname)(currentDir);
@@ -3113,28 +3087,28 @@ async function loadConfig(rootDir) {
3113
3087
  }
3114
3088
  function mergeConfigWithDefaults(userConfig, defaults) {
3115
3089
  if (!userConfig) return defaults;
3116
- const result = { ...defaults };
3090
+ const mergedConfig = { ...defaults };
3117
3091
  if (userConfig.scan) {
3118
- if (userConfig.scan.include) result.include = userConfig.scan.include;
3119
- if (userConfig.scan.exclude) result.exclude = userConfig.scan.exclude;
3092
+ if (userConfig.scan.include) mergedConfig.include = userConfig.scan.include;
3093
+ if (userConfig.scan.exclude) mergedConfig.exclude = userConfig.scan.exclude;
3120
3094
  }
3121
3095
  const toolOverrides = userConfig.tools && !Array.isArray(userConfig.tools) && typeof userConfig.tools === "object" ? userConfig.tools : userConfig.toolConfigs;
3122
3096
  if (toolOverrides) {
3123
- if (!result.toolConfigs) result.toolConfigs = {};
3097
+ if (!mergedConfig.toolConfigs) mergedConfig.toolConfigs = {};
3124
3098
  for (const [toolName, toolConfig] of Object.entries(toolOverrides)) {
3125
3099
  if (typeof toolConfig === "object" && toolConfig !== null) {
3126
- result[toolName] = { ...result[toolName], ...toolConfig };
3127
- result.toolConfigs[toolName] = {
3128
- ...result.toolConfigs[toolName],
3100
+ mergedConfig[toolName] = { ...mergedConfig[toolName], ...toolConfig };
3101
+ mergedConfig.toolConfigs[toolName] = {
3102
+ ...mergedConfig.toolConfigs[toolName],
3129
3103
  ...toolConfig
3130
3104
  };
3131
3105
  }
3132
3106
  }
3133
3107
  }
3134
3108
  if (userConfig.output) {
3135
- result.output = { ...result.output, ...userConfig.output };
3109
+ mergedConfig.output = { ...mergedConfig.output, ...userConfig.output };
3136
3110
  }
3137
- return result;
3111
+ return mergedConfig;
3138
3112
  }
3139
3113
 
3140
3114
  // src/utils/visualization.ts
@@ -3503,6 +3477,13 @@ function getRating(score) {
3503
3477
  if (score >= 40) return "Needs Work" /* NeedsWork */;
3504
3478
  return "Critical" /* Critical */;
3505
3479
  }
3480
+ function getRatingSlug(score) {
3481
+ if (score >= 90) return "excellent";
3482
+ if (score >= 75) return "good";
3483
+ if (score >= 60) return "fair";
3484
+ if (score >= 40) return "needs-work";
3485
+ return "critical";
3486
+ }
3506
3487
  function getRatingWithContext(score, fileCount, modelTier = "standard") {
3507
3488
  const threshold = getRecommendedThreshold(fileCount, modelTier);
3508
3489
  const normalized = score - threshold + 70;
@@ -3772,7 +3753,10 @@ function predictAcceptanceRate(toolOutputs) {
3772
3753
  impact: Math.round((50 - aiSignalClarity.score) * 2e-3 * 100)
3773
3754
  });
3774
3755
  }
3775
- const totalImpact = factors.reduce((sum, f) => sum + f.impact / 100, 0);
3756
+ const totalImpact = factors.reduce(
3757
+ (sum, f) => sum + f.impact / 100,
3758
+ 0
3759
+ );
3776
3760
  const rate = Math.max(0.05, Math.min(0.8, baseRate + totalImpact));
3777
3761
  let confidence = 0.35;
3778
3762
  if (toolOutputs.size >= 4) confidence = 0.75;
@@ -5112,12 +5096,17 @@ function emitIssuesAsAnnotations(issues) {
5112
5096
  getProjectSizeTier,
5113
5097
  getRating,
5114
5098
  getRatingDisplay,
5099
+ getRatingSlug,
5115
5100
  getRatingWithContext,
5116
5101
  getRecommendedThreshold,
5117
5102
  getRepoMetadata,
5118
5103
  getSafetyIcon,
5119
5104
  getScoreBar,
5105
+ getSeverityBadge,
5120
5106
  getSeverityColor,
5107
+ getSeverityEnum,
5108
+ getSeverityLevel,
5109
+ getSeverityValue,
5121
5110
  getSupportedLanguages,
5122
5111
  getToolWeight,
5123
5112
  getWasmPath,