@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.
- package/dist/__tests__/parser-factory.test.d.ts +1 -1
- package/dist/__tests__/parser-factory.test.js +62 -50
- package/dist/__tests__/python-parser.test.d.ts +1 -1
- package/dist/__tests__/python-parser.test.js +111 -109
- package/dist/__tests__/scoring.test.d.ts +1 -1
- package/dist/__tests__/scoring.test.js +193 -176
- package/dist/chunk-3YI4IS3D.mjs +191 -173
- package/dist/chunk-5HIXDC3X.mjs +273 -251
- package/dist/chunk-5V3L53AE.mjs +805 -0
- package/dist/chunk-CKVKHN3G.mjs +228 -211
- package/dist/chunk-COHIBX3Q.mjs +213 -195
- package/dist/chunk-CWRCDSKZ.mjs +91 -82
- package/dist/chunk-D3D3NCRR.mjs +147 -129
- package/dist/chunk-HCFYP7UD.mjs +805 -0
- package/dist/chunk-HFLFBA6F.mjs +79 -72
- package/dist/chunk-HKSARRCD.mjs +66 -58
- package/dist/chunk-JJ5JL5FX.mjs +91 -82
- package/dist/chunk-KDSTXVLQ.mjs +724 -0
- package/dist/chunk-KI7XORTN.mjs +91 -82
- package/dist/chunk-LTMHFNFK.mjs +690 -0
- package/dist/chunk-LTNXTXRI.mjs +228 -211
- package/dist/chunk-M22BXHBR.mjs +805 -0
- package/dist/chunk-MH3A3LX6.mjs +200 -182
- package/dist/chunk-NGHT7JOG.mjs +697 -0
- package/dist/chunk-OQ6IGDXG.mjs +147 -129
- package/dist/chunk-QAFB3HXQ.mjs +181 -165
- package/dist/chunk-QQBKXHLU.mjs +678 -0
- package/dist/chunk-RDHYGES7.mjs +678 -0
- package/dist/chunk-SWTDBVYJ.mjs +228 -213
- package/dist/chunk-UIWL5JQB.mjs +79 -72
- package/dist/chunk-UQGI67WR.mjs +79 -72
- package/dist/chunk-UTZOO4XO.mjs +147 -131
- package/dist/chunk-X4F46I5L.mjs +213 -195
- package/dist/chunk-XKK7YHPX.mjs +204 -186
- package/dist/chunk-YCA4FTEK.mjs +190 -172
- package/dist/chunk-ZSZRRTJM.mjs +719 -0
- package/dist/client-BgmiMoil.d.mts +1344 -0
- package/dist/client-BgmiMoil.d.ts +1344 -0
- package/dist/client-BxGrPuuN.d.mts +1191 -0
- package/dist/client-BxGrPuuN.d.ts +1191 -0
- package/dist/client-D-cn9ydj.d.mts +1136 -0
- package/dist/client-D-cn9ydj.d.ts +1136 -0
- package/dist/client-D9seCH4K.d.mts +1334 -0
- package/dist/client-D9seCH4K.d.ts +1334 -0
- package/dist/client-DIXIh7rw.d.mts +1193 -0
- package/dist/client-DIXIh7rw.d.ts +1193 -0
- package/dist/client-DVHXWOHw.d.mts +1245 -0
- package/dist/client-DVHXWOHw.d.ts +1245 -0
- package/dist/client.d.mts +2 -1098
- package/dist/client.d.ts +2 -1098
- package/dist/client.js +23 -43
- package/dist/client.mjs +3 -25
- package/dist/index.d.mts +329 -107
- package/dist/index.d.ts +329 -107
- package/dist/index.js +329 -340
- package/dist/index.mjs +305 -322
- package/dist/parsers/parser-factory.d.ts +45 -45
- package/dist/parsers/parser-factory.js +86 -84
- package/dist/parsers/python-parser.d.ts +33 -28
- package/dist/parsers/python-parser.js +224 -222
- package/dist/parsers/typescript-parser.d.ts +15 -10
- package/dist/parsers/typescript-parser.js +223 -197
- package/dist/scoring.d.ts +59 -49
- package/dist/scoring.js +129 -127
- package/dist/types/language.d.ts +104 -93
- package/dist/types/language.js +23 -23
- package/dist/types.d.ts +105 -87
- package/dist/types.js +1 -1
- package/dist/utils/ast-parser.d.ts +42 -33
- package/dist/utils/ast-parser.js +159 -162
- package/dist/utils/cli-helpers.d.ts +27 -10
- package/dist/utils/cli-helpers.js +45 -43
- package/dist/utils/config.d.ts +8 -3
- package/dist/utils/config.js +67 -69
- package/dist/utils/file-scanner.d.ts +1 -1
- package/dist/utils/file-scanner.js +80 -76
- package/dist/utils/metrics.d.ts +1 -1
- package/dist/utils/metrics.js +2 -2
- 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
|
-
"
|
|
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
|
-
"
|
|
348
|
-
"
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
859
|
+
return chalkInstance.red;
|
|
859
860
|
case "major":
|
|
860
861
|
case "moderate-risk":
|
|
861
|
-
return
|
|
862
|
+
return chalkInstance.yellow;
|
|
862
863
|
case "minor":
|
|
863
864
|
case "safe":
|
|
864
|
-
return
|
|
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
|
|
882
|
+
return 1;
|
|
867
883
|
default:
|
|
868
|
-
return
|
|
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/
|
|
1501
|
-
var
|
|
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
|
-
|
|
1514
|
-
|
|
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,
|
|
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
|
|
1536
|
-
const
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2484
|
-
|
|
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
|
-
|
|
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-
|
|
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(
|
|
2869
|
+
function extractFromDeclaration(node) {
|
|
2870
|
+
if (!node) return [];
|
|
2944
2871
|
const results = [];
|
|
2945
|
-
if (
|
|
2946
|
-
results.push({ name:
|
|
2947
|
-
} else if (
|
|
2948
|
-
results.push({ name:
|
|
2949
|
-
} else if (
|
|
2950
|
-
for (const
|
|
2951
|
-
if (
|
|
2952
|
-
results.push({ name:
|
|
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 (
|
|
2956
|
-
results.push({ name:
|
|
2957
|
-
} else if (
|
|
2958
|
-
results.push({ name:
|
|
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
|
-
|
|
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(
|
|
3008
|
+
function extractFunctions(_ast) {
|
|
3009
|
+
void _ast;
|
|
3037
3010
|
return [];
|
|
3038
3011
|
}
|
|
3039
|
-
function extractImports(
|
|
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
|
|
3070
|
+
const configError = new Error(
|
|
3097
3071
|
`Failed to load config from ${configPath}: ${errorMessage}`
|
|
3098
3072
|
);
|
|
3099
3073
|
try {
|
|
3100
|
-
|
|
3074
|
+
configError.cause = error instanceof Error ? error : void 0;
|
|
3101
3075
|
} catch {
|
|
3102
3076
|
}
|
|
3103
|
-
throw
|
|
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
|
|
3090
|
+
const mergedConfig = { ...defaults };
|
|
3117
3091
|
if (userConfig.scan) {
|
|
3118
|
-
if (userConfig.scan.include)
|
|
3119
|
-
if (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 (!
|
|
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
|
-
|
|
3127
|
-
|
|
3128
|
-
...
|
|
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
|
-
|
|
3109
|
+
mergedConfig.output = { ...mergedConfig.output, ...userConfig.output };
|
|
3136
3110
|
}
|
|
3137
|
-
return
|
|
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(
|
|
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,
|