@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.mjs CHANGED
@@ -38,12 +38,13 @@ import {
38
38
  getProjectSizeTier,
39
39
  getRating,
40
40
  getRatingDisplay,
41
+ getRatingSlug,
41
42
  getRatingWithContext,
42
43
  getRecommendedThreshold,
43
44
  getToolWeight,
44
45
  normalizeToolName,
45
46
  parseWeightString
46
- } from "./chunk-5HIXDC3X.mjs";
47
+ } from "./chunk-NGHT7JOG.mjs";
47
48
 
48
49
  // src/types/contract.ts
49
50
  function validateSpokeOutput(toolName, output) {
@@ -303,7 +304,7 @@ async function scanFiles(options) {
303
304
  try {
304
305
  const txt = await readFile(ignoreFilePath, "utf-8");
305
306
  ignoreFromFile = txt.split(/\r?\n/).map((s) => s.trim()).filter(Boolean).filter((l) => !l.startsWith("#")).filter((l) => !l.startsWith("!"));
306
- } catch (e) {
307
+ } catch {
307
308
  ignoreFromFile = [];
308
309
  }
309
310
  }
@@ -357,7 +358,7 @@ async function scanFiles(options) {
357
358
  return !ig.ignores(rel);
358
359
  });
359
360
  return filtered;
360
- } catch (e) {
361
+ } catch {
361
362
  return files;
362
363
  }
363
364
  }
@@ -365,14 +366,14 @@ async function scanFiles(options) {
365
366
  }
366
367
  async function scanEntries(options) {
367
368
  const files = await scanFiles(options);
368
- const { rootDir, include = ["**/*"], exclude, includeTests } = options;
369
+ const { rootDir, exclude, includeTests } = options;
369
370
  const ignoreFilePath = join(rootDir || ".", ".aireadyignore");
370
371
  let ignoreFromFile = [];
371
372
  if (existsSync(ignoreFilePath)) {
372
373
  try {
373
374
  const txt = await readFile(ignoreFilePath, "utf-8");
374
375
  ignoreFromFile = txt.split(/\r?\n/).map((s) => s.trim()).filter(Boolean).filter((l) => !l.startsWith("#")).filter((l) => !l.startsWith("!"));
375
- } catch (e) {
376
+ } catch {
376
377
  ignoreFromFile = [];
377
378
  }
378
379
  }
@@ -447,6 +448,7 @@ import {
447
448
  statSync
448
449
  } from "fs";
449
450
  import { join as join2, dirname as dirname2, resolve as resolvePath } from "path";
451
+ import chalk from "chalk";
450
452
  function resolveOutputPath(userPath, defaultFilename, workingDir = process.cwd()) {
451
453
  let outputPath;
452
454
  if (userPath) {
@@ -514,22 +516,72 @@ function emitProgress(processed, total, toolId, message, onProgress, throttleCou
514
516
  onProgress(processed, total, `${message} (${processed}/${total})`);
515
517
  }
516
518
  }
517
- function getSeverityColor(severity, chalk) {
519
+ function getSeverityColor(severity, chalkInstance = chalk) {
518
520
  switch (severity.toLowerCase()) {
519
521
  case "critical":
520
522
  case "high-risk":
521
523
  case "blind-risk":
522
- return chalk.red;
524
+ return chalkInstance.red;
523
525
  case "major":
524
526
  case "moderate-risk":
525
- return chalk.yellow;
527
+ return chalkInstance.yellow;
526
528
  case "minor":
527
529
  case "safe":
528
- return chalk.green;
530
+ return chalkInstance.green;
531
+ case "info":
532
+ return chalkInstance.blue;
533
+ default:
534
+ return chalkInstance.white;
535
+ }
536
+ }
537
+ function getSeverityValue(s) {
538
+ if (!s) return 0;
539
+ switch (s.toLowerCase()) {
540
+ case "critical":
541
+ return 4;
542
+ case "major":
543
+ return 3;
544
+ case "minor":
545
+ return 2;
529
546
  case "info":
530
- return chalk.blue;
547
+ return 1;
531
548
  default:
532
- return chalk.white;
549
+ return 0;
550
+ }
551
+ }
552
+ function getSeverityLevel(s) {
553
+ return getSeverityValue(s);
554
+ }
555
+ function getSeverityBadge(severity, chalkInstance = chalk) {
556
+ const val = getSeverityValue(
557
+ typeof severity === "string" ? severity : severity
558
+ );
559
+ switch (val) {
560
+ case 4:
561
+ return chalkInstance.bgRed.white.bold(" CRITICAL ");
562
+ case 3:
563
+ return chalkInstance.bgYellow.black.bold(" MAJOR ");
564
+ case 2:
565
+ return chalkInstance.bgBlue.white.bold(" MINOR ");
566
+ case 1:
567
+ return chalkInstance.bgCyan.black(" INFO ");
568
+ default:
569
+ return chalkInstance.bgCyan.black(" INFO ");
570
+ }
571
+ }
572
+ function getSeverityEnum(s) {
573
+ const level = getSeverityLevel(s);
574
+ switch (level) {
575
+ case 4:
576
+ return "critical";
577
+ case 3:
578
+ return "major";
579
+ case 2:
580
+ return "minor";
581
+ case 1:
582
+ return "info";
583
+ default:
584
+ return "info";
533
585
  }
534
586
  }
535
587
  function findLatestReport(dirPath) {
@@ -978,94 +1030,6 @@ var TypeScriptParser = class {
978
1030
  }
979
1031
  };
980
1032
 
981
- // src/parsers/tree-sitter-utils.ts
982
- import * as Parser from "web-tree-sitter";
983
- import * as path from "path";
984
- import * as fs from "fs";
985
- var isTreeSitterInitialized = false;
986
- async function initTreeSitter() {
987
- if (isTreeSitterInitialized) return;
988
- try {
989
- const wasmPath = getWasmPath("web-tree-sitter");
990
- await Parser.Parser.init({
991
- locateFile() {
992
- return wasmPath || "web-tree-sitter.wasm";
993
- }
994
- });
995
- isTreeSitterInitialized = true;
996
- } catch (error) {
997
- console.error("Failed to initialize web-tree-sitter:", error);
998
- isTreeSitterInitialized = true;
999
- }
1000
- }
1001
- function findInPnpmStore(startDir, fileName, depth = 0) {
1002
- if (depth > 8) return null;
1003
- const pnpmDir = path.join(startDir, "node_modules", ".pnpm");
1004
- if (fs.existsSync(pnpmDir)) {
1005
- return findFileRecursively(pnpmDir, fileName, 0);
1006
- }
1007
- const parent = path.dirname(startDir);
1008
- if (parent === startDir) return null;
1009
- return findInPnpmStore(parent, fileName, depth + 1);
1010
- }
1011
- function findFileRecursively(dir, fileName, depth) {
1012
- if (depth > 6) return null;
1013
- try {
1014
- const entries = fs.readdirSync(dir, { withFileTypes: true });
1015
- for (const entry of entries) {
1016
- if (entry.isFile() && entry.name === fileName) {
1017
- return path.join(dir, entry.name);
1018
- }
1019
- }
1020
- for (const entry of entries) {
1021
- if (entry.isDirectory()) {
1022
- const found = findFileRecursively(
1023
- path.join(dir, entry.name),
1024
- fileName,
1025
- depth + 1
1026
- );
1027
- if (found) return found;
1028
- }
1029
- }
1030
- } catch (err) {
1031
- }
1032
- return null;
1033
- }
1034
- function getWasmPath(language) {
1035
- const wasmFileName = language === "web-tree-sitter" ? "web-tree-sitter.wasm" : `tree-sitter-${language}.wasm`;
1036
- const immediatePaths = [
1037
- path.join(process.cwd(), wasmFileName),
1038
- path.join(__dirname, wasmFileName),
1039
- path.join(__dirname, "assets", wasmFileName)
1040
- ];
1041
- for (const p of immediatePaths) {
1042
- if (fs.existsSync(p)) return p;
1043
- }
1044
- const pnpmPath = findInPnpmStore(__dirname, wasmFileName);
1045
- if (pnpmPath) return pnpmPath;
1046
- const pnpmPathCwd = findInPnpmStore(process.cwd(), wasmFileName);
1047
- if (pnpmPathCwd) return pnpmPathCwd;
1048
- console.warn(
1049
- `[Parser] WASM file for ${language} not found. CWD: ${process.cwd()}, DIR: ${__dirname}`
1050
- );
1051
- return null;
1052
- }
1053
- async function setupParser(language) {
1054
- await initTreeSitter();
1055
- const wasmPath = getWasmPath(language);
1056
- if (!wasmPath) {
1057
- return null;
1058
- }
1059
- try {
1060
- const parser = new Parser.Parser();
1061
- const Lang = await Parser.Language.load(wasmPath);
1062
- parser.setLanguage(Lang);
1063
- return parser;
1064
- } catch (error) {
1065
- return null;
1066
- }
1067
- }
1068
-
1069
1033
  // src/parsers/metadata-utils.ts
1070
1034
  function analyzeNodeMetadata(node, code, options) {
1071
1035
  const metadata = {
@@ -1161,11 +1125,97 @@ function analyzeNodeMetadata(node, code, options) {
1161
1125
  return metadata;
1162
1126
  }
1163
1127
 
1164
- // src/parsers/python-parser.ts
1165
- var PythonParser = class {
1128
+ // src/parsers/tree-sitter-utils.ts
1129
+ import * as Parser from "web-tree-sitter";
1130
+ import * as path from "path";
1131
+ import * as fs from "fs";
1132
+ var isTreeSitterInitialized = false;
1133
+ async function initTreeSitter() {
1134
+ if (isTreeSitterInitialized) return;
1135
+ try {
1136
+ const wasmPath = getWasmPath("web-tree-sitter");
1137
+ await Parser.Parser.init({
1138
+ locateFile() {
1139
+ return wasmPath || "web-tree-sitter.wasm";
1140
+ }
1141
+ });
1142
+ isTreeSitterInitialized = true;
1143
+ } catch (error) {
1144
+ console.error("Failed to initialize web-tree-sitter:", error);
1145
+ isTreeSitterInitialized = true;
1146
+ }
1147
+ }
1148
+ function findInPnpmStore(startDir, fileName, depth = 0) {
1149
+ if (depth > 8) return null;
1150
+ const pnpmDir = path.join(startDir, "node_modules", ".pnpm");
1151
+ if (fs.existsSync(pnpmDir)) {
1152
+ return findFileRecursively(pnpmDir, fileName, 0);
1153
+ }
1154
+ const parent = path.dirname(startDir);
1155
+ if (parent === startDir) return null;
1156
+ return findInPnpmStore(parent, fileName, depth + 1);
1157
+ }
1158
+ function findFileRecursively(dir, fileName, depth) {
1159
+ if (depth > 6) return null;
1160
+ try {
1161
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
1162
+ for (const entry of entries) {
1163
+ if (entry.isFile() && entry.name === fileName) {
1164
+ return path.join(dir, entry.name);
1165
+ }
1166
+ }
1167
+ for (const entry of entries) {
1168
+ if (entry.isDirectory()) {
1169
+ const found = findFileRecursively(
1170
+ path.join(dir, entry.name),
1171
+ fileName,
1172
+ depth + 1
1173
+ );
1174
+ if (found) return found;
1175
+ }
1176
+ }
1177
+ } catch {
1178
+ }
1179
+ return null;
1180
+ }
1181
+ function getWasmPath(language) {
1182
+ const wasmFileName = language === "web-tree-sitter" ? "web-tree-sitter.wasm" : `tree-sitter-${language}.wasm`;
1183
+ const immediatePaths = [
1184
+ path.join(process.cwd(), wasmFileName),
1185
+ path.join(__dirname, wasmFileName),
1186
+ path.join(__dirname, "assets", wasmFileName)
1187
+ ];
1188
+ for (const p of immediatePaths) {
1189
+ if (fs.existsSync(p)) return p;
1190
+ }
1191
+ const pnpmPath = findInPnpmStore(__dirname, wasmFileName);
1192
+ if (pnpmPath) return pnpmPath;
1193
+ const pnpmPathCwd = findInPnpmStore(process.cwd(), wasmFileName);
1194
+ if (pnpmPathCwd) return pnpmPathCwd;
1195
+ console.warn(
1196
+ `[Parser] WASM file for ${language} not found. CWD: ${process.cwd()}, DIR: ${__dirname}`
1197
+ );
1198
+ return null;
1199
+ }
1200
+ async function setupParser(language) {
1201
+ await initTreeSitter();
1202
+ const wasmPath = getWasmPath(language);
1203
+ if (!wasmPath) {
1204
+ return null;
1205
+ }
1206
+ try {
1207
+ const parser = new Parser.Parser();
1208
+ const Lang = await Parser.Language.load(wasmPath);
1209
+ parser.setLanguage(Lang);
1210
+ return parser;
1211
+ } catch {
1212
+ return null;
1213
+ }
1214
+ }
1215
+
1216
+ // src/parsers/base-parser.ts
1217
+ var BaseLanguageParser = class {
1166
1218
  constructor() {
1167
- this.language = "python" /* Python */;
1168
- this.extensions = [".py"];
1169
1219
  this.parser = null;
1170
1220
  this.initialized = false;
1171
1221
  }
@@ -1174,19 +1224,19 @@ var PythonParser = class {
1174
1224
  */
1175
1225
  async initialize() {
1176
1226
  if (this.initialized) return;
1177
- this.parser = await setupParser("python");
1178
- this.initialized = true;
1227
+ try {
1228
+ this.parser = await setupParser(this.getParserName());
1229
+ this.initialized = true;
1230
+ } catch (error) {
1231
+ console.warn(`Failed to initialize ${this.language} parser:`, error);
1232
+ }
1179
1233
  }
1180
- async getAST(code, filePath) {
1234
+ async getAST(code, _filePath) {
1235
+ void _filePath;
1181
1236
  if (!this.initialized) await this.initialize();
1182
1237
  if (!this.parser) return null;
1183
1238
  return this.parser.parse(code);
1184
1239
  }
1185
- analyzeMetadata(node, code) {
1186
- return analyzeNodeMetadata(node, code, {
1187
- sideEffectSignatures: ["print(", "input(", "open("]
1188
- });
1189
- }
1190
1240
  parse(code, filePath) {
1191
1241
  if (!this.initialized || !this.parser) {
1192
1242
  return this.parseRegex(code, filePath);
@@ -1196,19 +1246,42 @@ var PythonParser = class {
1196
1246
  if (!tree || tree.rootNode.type === "ERROR" || tree.rootNode.hasError) {
1197
1247
  return this.parseRegex(code, filePath);
1198
1248
  }
1199
- const rootNode = tree.rootNode;
1200
- const imports = this.extractImportsAST(rootNode);
1201
- const exports = this.extractExportsAST(rootNode, code);
1249
+ const imports = this.extractImportsAST(tree.rootNode);
1250
+ const exports = this.extractExportsAST(tree.rootNode, code);
1202
1251
  return {
1203
1252
  exports,
1204
1253
  imports,
1205
- language: "python" /* Python */,
1254
+ language: this.language,
1206
1255
  warnings: []
1207
1256
  };
1208
1257
  } catch (error) {
1258
+ console.warn(
1259
+ `AST parsing failed for ${filePath}, falling back to regex: ${error.message}`
1260
+ );
1209
1261
  return this.parseRegex(code, filePath);
1210
1262
  }
1211
1263
  }
1264
+ canHandle(filePath) {
1265
+ const lowerPath = filePath.toLowerCase();
1266
+ return this.extensions.some((ext) => lowerPath.endsWith(ext));
1267
+ }
1268
+ };
1269
+
1270
+ // src/parsers/python-parser.ts
1271
+ var PythonParser = class extends BaseLanguageParser {
1272
+ constructor() {
1273
+ super(...arguments);
1274
+ this.language = "python" /* Python */;
1275
+ this.extensions = [".py"];
1276
+ }
1277
+ getParserName() {
1278
+ return "python";
1279
+ }
1280
+ analyzeMetadata(node, code) {
1281
+ return analyzeNodeMetadata(node, code, {
1282
+ sideEffectSignatures: ["print(", "input(", "open("]
1283
+ });
1284
+ }
1212
1285
  extractImportsAST(rootNode) {
1213
1286
  const imports = [];
1214
1287
  const processImportNode = (node) => {
@@ -1394,10 +1467,11 @@ var PythonParser = class {
1394
1467
  ]
1395
1468
  };
1396
1469
  } catch (error) {
1397
- throw new ParseError(
1398
- `Failed to parse Python file ${filePath}: ${error.message}`,
1399
- filePath
1470
+ const wrapper = new Error(
1471
+ `Failed to parse Python file ${filePath}: ${error.message}`
1400
1472
  );
1473
+ wrapper.cause = error;
1474
+ throw wrapper;
1401
1475
  }
1402
1476
  }
1403
1477
  getNamingConventions() {
@@ -1428,6 +1502,7 @@ var PythonParser = class {
1428
1502
  return filePath.toLowerCase().endsWith(".py");
1429
1503
  }
1430
1504
  extractImportsRegex(code, _filePath) {
1505
+ void _filePath;
1431
1506
  const imports = [];
1432
1507
  const lines = code.split("\n");
1433
1508
  const importRegex = /^\s*import\s+([a-zA-Z0-9_., ]+)/;
@@ -1478,6 +1553,7 @@ var PythonParser = class {
1478
1553
  return imports;
1479
1554
  }
1480
1555
  extractExportsRegex(code, _filePath) {
1556
+ void _filePath;
1481
1557
  const exports = [];
1482
1558
  const lines = code.split("\n");
1483
1559
  const funcRegex = /^def\s+([a-zA-Z0-9_]+)\s*\(/;
@@ -1642,25 +1718,14 @@ function extractParameterNames(node) {
1642
1718
  }
1643
1719
 
1644
1720
  // src/parsers/java-parser.ts
1645
- var JavaParser = class {
1721
+ var JavaParser = class extends BaseLanguageParser {
1646
1722
  constructor() {
1723
+ super(...arguments);
1647
1724
  this.language = "java" /* Java */;
1648
1725
  this.extensions = [".java"];
1649
- this.parser = null;
1650
- this.initialized = false;
1651
1726
  }
1652
- /**
1653
- * Initialize the tree-sitter parser
1654
- */
1655
- async initialize() {
1656
- if (this.initialized) return;
1657
- this.parser = await setupParser("java");
1658
- this.initialized = true;
1659
- }
1660
- async getAST(code, filePath) {
1661
- if (!this.initialized) await this.initialize();
1662
- if (!this.parser) return null;
1663
- return this.parser.parse(code);
1727
+ getParserName() {
1728
+ return "java";
1664
1729
  }
1665
1730
  analyzeMetadata(node, code) {
1666
1731
  return analyzeGeneralMetadata(node, code, {
@@ -1672,32 +1737,7 @@ var JavaParser = class {
1672
1737
  ]
1673
1738
  });
1674
1739
  }
1675
- parse(code, filePath) {
1676
- if (!this.initialized || !this.parser) {
1677
- return this.parseRegex(code, filePath);
1678
- }
1679
- try {
1680
- const tree = this.parser.parse(code);
1681
- if (!tree || tree.rootNode.type === "ERROR" || tree.rootNode.hasError) {
1682
- return this.parseRegex(code, filePath);
1683
- }
1684
- const rootNode = tree.rootNode;
1685
- const imports = this.extractImportsAST(rootNode);
1686
- const exports = this.extractExportsAST(rootNode, code);
1687
- return {
1688
- exports,
1689
- imports,
1690
- language: "java" /* Java */,
1691
- warnings: []
1692
- };
1693
- } catch (error) {
1694
- console.warn(
1695
- `AST parsing failed for ${filePath}, falling back to regex: ${error.message}`
1696
- );
1697
- return this.parseRegex(code, filePath);
1698
- }
1699
- }
1700
- parseRegex(code, filePath) {
1740
+ parseRegex(code) {
1701
1741
  const lines = code.split("\n");
1702
1742
  const exports = [];
1703
1743
  const imports = [];
@@ -1771,10 +1811,8 @@ var JavaParser = class {
1771
1811
  for (const node of rootNode.children) {
1772
1812
  if (node.type === "import_declaration") {
1773
1813
  const sourceArr = [];
1774
- let isStatic = false;
1775
1814
  let isWildcard = false;
1776
1815
  for (const child of node.children) {
1777
- if (child.type === "static") isStatic = true;
1778
1816
  if (child.type === "scoped_identifier" || child.type === "identifier") {
1779
1817
  sourceArr.push(child.text);
1780
1818
  }
@@ -1885,55 +1923,21 @@ var JavaParser = class {
1885
1923
  };
1886
1924
 
1887
1925
  // src/parsers/csharp-parser.ts
1888
- var CSharpParser = class {
1926
+ var CSharpParser = class extends BaseLanguageParser {
1889
1927
  constructor() {
1928
+ super(...arguments);
1890
1929
  this.language = "csharp" /* CSharp */;
1891
1930
  this.extensions = [".cs"];
1892
- this.parser = null;
1893
- this.initialized = false;
1894
1931
  }
1895
- /**
1896
- * Initialize the tree-sitter parser
1897
- */
1898
- async initialize() {
1899
- if (this.initialized) return;
1900
- this.parser = await setupParser("c_sharp");
1901
- this.initialized = true;
1902
- }
1903
- async getAST(code, filePath) {
1904
- if (!this.initialized) await this.initialize();
1905
- if (!this.parser) return null;
1906
- return this.parser.parse(code);
1932
+ getParserName() {
1933
+ return "c_sharp";
1907
1934
  }
1908
1935
  analyzeMetadata(node, code) {
1909
1936
  return analyzeGeneralMetadata(node, code, {
1910
1937
  sideEffectSignatures: ["Console.Write", "File.Write", "Logging."]
1911
1938
  });
1912
1939
  }
1913
- parse(code, filePath) {
1914
- if (!this.initialized || !this.parser) {
1915
- return this.parseRegex(code, filePath);
1916
- }
1917
- try {
1918
- const tree = this.parser.parse(code);
1919
- if (!tree) throw new Error("Parser.parse(code) returned null");
1920
- const rootNode = tree.rootNode;
1921
- const imports = this.extractImportsAST(rootNode);
1922
- const exports = this.extractExportsAST(rootNode, code);
1923
- return {
1924
- exports,
1925
- imports,
1926
- language: "csharp" /* CSharp */,
1927
- warnings: []
1928
- };
1929
- } catch (error) {
1930
- console.warn(
1931
- `AST parsing failed for ${filePath}, falling back to regex: ${error.message}`
1932
- );
1933
- return this.parseRegex(code, filePath);
1934
- }
1935
- }
1936
- parseRegex(code, filePath) {
1940
+ parseRegex(code) {
1937
1941
  const lines = code.split("\n");
1938
1942
  const exports = [];
1939
1943
  const imports = [];
@@ -2129,57 +2133,21 @@ var CSharpParser = class {
2129
2133
  };
2130
2134
 
2131
2135
  // src/parsers/go-parser.ts
2132
- var GoParser = class {
2136
+ var GoParser = class extends BaseLanguageParser {
2133
2137
  constructor() {
2138
+ super(...arguments);
2134
2139
  this.language = "go" /* Go */;
2135
2140
  this.extensions = [".go"];
2136
- this.parser = null;
2137
- this.initialized = false;
2138
- }
2139
- /**
2140
- * Initialize the tree-sitter parser
2141
- */
2142
- async initialize() {
2143
- if (this.initialized) return;
2144
- this.parser = await setupParser("go");
2145
- this.initialized = true;
2146
2141
  }
2147
- async getAST(code, filePath) {
2148
- if (!this.initialized) await this.initialize();
2149
- if (!this.parser) return null;
2150
- return this.parser.parse(code);
2142
+ getParserName() {
2143
+ return "go";
2151
2144
  }
2152
2145
  analyzeMetadata(node, code) {
2153
2146
  return analyzeGeneralMetadata(node, code, {
2154
2147
  sideEffectSignatures: ["<-", "fmt.Print", "fmt.Fprintf", "os.Exit"]
2155
2148
  });
2156
2149
  }
2157
- parse(code, filePath) {
2158
- if (!this.initialized || !this.parser) {
2159
- return this.parseRegex(code, filePath);
2160
- }
2161
- try {
2162
- const tree = this.parser.parse(code);
2163
- if (!tree || tree.rootNode.type === "ERROR" || tree.rootNode.hasError) {
2164
- return this.parseRegex(code, filePath);
2165
- }
2166
- const rootNode = tree.rootNode;
2167
- const imports = this.extractImportsAST(rootNode);
2168
- const exports = this.extractExportsAST(rootNode, code);
2169
- return {
2170
- exports,
2171
- imports,
2172
- language: "go" /* Go */,
2173
- warnings: []
2174
- };
2175
- } catch (error) {
2176
- console.warn(
2177
- `AST parsing failed for ${filePath}, falling back to regex: ${error.message}`
2178
- );
2179
- return this.parseRegex(code, filePath);
2180
- }
2181
- }
2182
- parseRegex(code, filePath) {
2150
+ parseRegex(code) {
2183
2151
  const lines = code.split("\n");
2184
2152
  const exports = [];
2185
2153
  const imports = [];
@@ -2505,48 +2473,7 @@ function getSupportedLanguages() {
2505
2473
  return ParserFactory.getInstance().getSupportedLanguages();
2506
2474
  }
2507
2475
 
2508
- // src/utils/ast-parser.ts
2509
- function parseFileExports(code, filePath) {
2510
- const parser = getParser(filePath);
2511
- if (parser && parser.language !== "typescript" /* TypeScript */ && parser.language !== "javascript" /* JavaScript */) {
2512
- try {
2513
- const result = parser.parse(code, filePath);
2514
- return {
2515
- exports: result.exports.map((e) => ({
2516
- name: e.name,
2517
- type: e.type,
2518
- imports: e.imports || [],
2519
- dependencies: e.dependencies || [],
2520
- typeReferences: e.typeReferences || [],
2521
- loc: e.loc ? {
2522
- start: { line: e.loc.start.line, column: e.loc.start.column },
2523
- end: { line: e.loc.end.line, column: e.loc.end.column }
2524
- } : void 0
2525
- })),
2526
- imports: result.imports.map((i) => ({
2527
- source: i.source,
2528
- specifiers: i.specifiers,
2529
- isTypeOnly: i.isTypeOnly || false
2530
- }))
2531
- };
2532
- } catch (e) {
2533
- return { exports: [], imports: [] };
2534
- }
2535
- }
2536
- try {
2537
- const ast = parse2(code, {
2538
- loc: true,
2539
- range: true,
2540
- jsx: filePath.endsWith(".tsx") || filePath.endsWith(".jsx"),
2541
- filePath
2542
- });
2543
- const imports = extractFileImports(ast);
2544
- const exports = extractExportsWithDependencies(ast, imports);
2545
- return { exports, imports };
2546
- } catch (error) {
2547
- return { exports: [], imports: [] };
2548
- }
2549
- }
2476
+ // src/utils/ast-visitor.ts
2550
2477
  function extractFileImports(ast) {
2551
2478
  const imports = [];
2552
2479
  for (const node of ast.body) {
@@ -2604,22 +2531,23 @@ function extractExportsWithDependencies(ast, fileImports) {
2604
2531
  }
2605
2532
  return exports;
2606
2533
  }
2607
- function extractFromDeclaration(declaration) {
2534
+ function extractFromDeclaration(node) {
2535
+ if (!node) return [];
2608
2536
  const results = [];
2609
- if (declaration.type === "FunctionDeclaration" && "id" in declaration && declaration.id) {
2610
- results.push({ name: declaration.id.name, type: "function" });
2611
- } else if (declaration.type === "ClassDeclaration" && "id" in declaration && declaration.id) {
2612
- results.push({ name: declaration.id.name, type: "class" });
2613
- } else if (declaration.type === "VariableDeclaration") {
2614
- for (const declarator of declaration.declarations) {
2615
- if (declarator.id.type === "Identifier") {
2616
- results.push({ name: declarator.id.name, type: "const" });
2537
+ if (node.type === "FunctionDeclaration" && node.id) {
2538
+ results.push({ name: node.id.name, type: "function" });
2539
+ } else if (node.type === "ClassDeclaration" && node.id) {
2540
+ results.push({ name: node.id.name, type: "class" });
2541
+ } else if (node.type === "VariableDeclaration") {
2542
+ for (const decl of node.declarations) {
2543
+ if (decl.id.type === "Identifier") {
2544
+ results.push({ name: decl.id.name, type: "const" });
2617
2545
  }
2618
2546
  }
2619
- } else if (declaration.type === "TSTypeAliasDeclaration") {
2620
- results.push({ name: declaration.id.name, type: "type" });
2621
- } else if (declaration.type === "TSInterfaceDeclaration") {
2622
- results.push({ name: declaration.id.name, type: "interface" });
2547
+ } else if (node.type === "TSInterfaceDeclaration" && node.id) {
2548
+ results.push({ name: node.id.name, type: "interface" });
2549
+ } else if (node.type === "TSTypeAliasDeclaration" && node.id) {
2550
+ results.push({ name: node.id.name, type: "type" });
2623
2551
  }
2624
2552
  return results;
2625
2553
  }
@@ -2647,16 +2575,6 @@ function findUsedImports(node, importedNames) {
2647
2575
  visit(node);
2648
2576
  return Array.from(usedImports);
2649
2577
  }
2650
- function calculateImportSimilarity(export1, export2) {
2651
- if (export1.imports.length === 0 && export2.imports.length === 0) {
2652
- return 1;
2653
- }
2654
- const set1 = new Set(export1.imports);
2655
- const set2 = new Set(export2.imports);
2656
- const intersection = new Set([...set1].filter((x) => set2.has(x)));
2657
- const union = /* @__PURE__ */ new Set([...set1, ...set2]);
2658
- return intersection.size / union.size;
2659
- }
2660
2578
  function extractTypeReferences(node) {
2661
2579
  const types = /* @__PURE__ */ new Set();
2662
2580
  function visit(n) {
@@ -2694,13 +2612,70 @@ function extractTypeReferences(node) {
2694
2612
  visit(node);
2695
2613
  return Array.from(types);
2696
2614
  }
2697
- function parseCode(code, language) {
2615
+
2616
+ // src/utils/ast-parser.ts
2617
+ function parseFileExports(code, filePath) {
2618
+ const parser = getParser(filePath);
2619
+ if (parser && parser.language !== "typescript" /* TypeScript */ && parser.language !== "javascript" /* JavaScript */) {
2620
+ try {
2621
+ const result = parser.parse(code, filePath);
2622
+ return {
2623
+ exports: result.exports.map((e) => ({
2624
+ name: e.name,
2625
+ type: e.type,
2626
+ imports: e.imports || [],
2627
+ dependencies: e.dependencies || [],
2628
+ typeReferences: e.typeReferences || [],
2629
+ loc: e.loc ? {
2630
+ start: { line: e.loc.start.line, column: e.loc.start.column },
2631
+ end: { line: e.loc.end.line, column: e.loc.end.column }
2632
+ } : void 0
2633
+ })),
2634
+ imports: result.imports.map((i) => ({
2635
+ source: i.source,
2636
+ specifiers: i.specifiers,
2637
+ isTypeOnly: i.isTypeOnly || false
2638
+ }))
2639
+ };
2640
+ } catch {
2641
+ return { exports: [], imports: [] };
2642
+ }
2643
+ }
2644
+ try {
2645
+ const ast = parse2(code, {
2646
+ loc: true,
2647
+ range: true,
2648
+ jsx: filePath.endsWith(".tsx") || filePath.endsWith(".jsx"),
2649
+ filePath
2650
+ });
2651
+ const imports = extractFileImports(ast);
2652
+ const exports = extractExportsWithDependencies(ast, imports);
2653
+ return { exports, imports };
2654
+ } catch {
2655
+ return { exports: [], imports: [] };
2656
+ }
2657
+ }
2658
+ function calculateImportSimilarity(export1, export2) {
2659
+ if (export1.imports.length === 0 && export2.imports.length === 0) {
2660
+ return 1;
2661
+ }
2662
+ const set1 = new Set(export1.imports);
2663
+ const set2 = new Set(export2.imports);
2664
+ const intersection = new Set([...set1].filter((x) => set2.has(x)));
2665
+ const union = /* @__PURE__ */ new Set([...set1, ...set2]);
2666
+ return intersection.size / union.size;
2667
+ }
2668
+ function parseCode(_code, _language) {
2669
+ void _code;
2670
+ void _language;
2698
2671
  return null;
2699
2672
  }
2700
- function extractFunctions(ast) {
2673
+ function extractFunctions(_ast) {
2674
+ void _ast;
2701
2675
  return [];
2702
2676
  }
2703
- function extractImports(ast) {
2677
+ function extractImports(_ast) {
2678
+ void _ast;
2704
2679
  return [];
2705
2680
  }
2706
2681
 
@@ -2757,14 +2732,14 @@ async function loadConfig(rootDir) {
2757
2732
  return config;
2758
2733
  } catch (error) {
2759
2734
  const errorMessage = error instanceof Error ? error.message : String(error);
2760
- const e = new Error(
2735
+ const configError = new Error(
2761
2736
  `Failed to load config from ${configPath}: ${errorMessage}`
2762
2737
  );
2763
2738
  try {
2764
- e.cause = error instanceof Error ? error : void 0;
2739
+ configError.cause = error instanceof Error ? error : void 0;
2765
2740
  } catch {
2766
2741
  }
2767
- throw e;
2742
+ throw configError;
2768
2743
  }
2769
2744
  }
2770
2745
  const parent = dirname4(currentDir);
@@ -2777,28 +2752,28 @@ async function loadConfig(rootDir) {
2777
2752
  }
2778
2753
  function mergeConfigWithDefaults(userConfig, defaults) {
2779
2754
  if (!userConfig) return defaults;
2780
- const result = { ...defaults };
2755
+ const mergedConfig = { ...defaults };
2781
2756
  if (userConfig.scan) {
2782
- if (userConfig.scan.include) result.include = userConfig.scan.include;
2783
- if (userConfig.scan.exclude) result.exclude = userConfig.scan.exclude;
2757
+ if (userConfig.scan.include) mergedConfig.include = userConfig.scan.include;
2758
+ if (userConfig.scan.exclude) mergedConfig.exclude = userConfig.scan.exclude;
2784
2759
  }
2785
2760
  const toolOverrides = userConfig.tools && !Array.isArray(userConfig.tools) && typeof userConfig.tools === "object" ? userConfig.tools : userConfig.toolConfigs;
2786
2761
  if (toolOverrides) {
2787
- if (!result.toolConfigs) result.toolConfigs = {};
2762
+ if (!mergedConfig.toolConfigs) mergedConfig.toolConfigs = {};
2788
2763
  for (const [toolName, toolConfig] of Object.entries(toolOverrides)) {
2789
2764
  if (typeof toolConfig === "object" && toolConfig !== null) {
2790
- result[toolName] = { ...result[toolName], ...toolConfig };
2791
- result.toolConfigs[toolName] = {
2792
- ...result.toolConfigs[toolName],
2765
+ mergedConfig[toolName] = { ...mergedConfig[toolName], ...toolConfig };
2766
+ mergedConfig.toolConfigs[toolName] = {
2767
+ ...mergedConfig.toolConfigs[toolName],
2793
2768
  ...toolConfig
2794
2769
  };
2795
2770
  }
2796
2771
  }
2797
2772
  }
2798
2773
  if (userConfig.output) {
2799
- result.output = { ...result.output, ...userConfig.output };
2774
+ mergedConfig.output = { ...mergedConfig.output, ...userConfig.output };
2800
2775
  }
2801
- return result;
2776
+ return mergedConfig;
2802
2777
  }
2803
2778
 
2804
2779
  // src/business/pricing-models.ts
@@ -3011,7 +2986,10 @@ function predictAcceptanceRate(toolOutputs) {
3011
2986
  impact: Math.round((50 - aiSignalClarity.score) * 2e-3 * 100)
3012
2987
  });
3013
2988
  }
3014
- const totalImpact = factors.reduce((sum, f) => sum + f.impact / 100, 0);
2989
+ const totalImpact = factors.reduce(
2990
+ (sum, f) => sum + f.impact / 100,
2991
+ 0
2992
+ );
3015
2993
  const rate = Math.max(0.05, Math.min(0.8, baseRate + totalImpact));
3016
2994
  let confidence = 0.35;
3017
2995
  if (toolOutputs.size >= 4) confidence = 0.75;
@@ -4350,12 +4328,17 @@ export {
4350
4328
  getProjectSizeTier,
4351
4329
  getRating,
4352
4330
  getRatingDisplay,
4331
+ getRatingSlug,
4353
4332
  getRatingWithContext,
4354
4333
  getRecommendedThreshold,
4355
4334
  getRepoMetadata,
4356
4335
  getSafetyIcon,
4357
4336
  getScoreBar,
4337
+ getSeverityBadge,
4358
4338
  getSeverityColor,
4339
+ getSeverityEnum,
4340
+ getSeverityLevel,
4341
+ getSeverityValue,
4359
4342
  getSupportedLanguages,
4360
4343
  getToolWeight,
4361
4344
  getWasmPath,