ctxloom-pro 1.0.17 → 1.0.18
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.
|
@@ -455,6 +455,27 @@ var ASTParser = class {
|
|
|
455
455
|
kotlinLang = null;
|
|
456
456
|
swiftLang = null;
|
|
457
457
|
phpLang = null;
|
|
458
|
+
/**
|
|
459
|
+
* Per-language parser cache. Each TreeSitter.Parser is a
|
|
460
|
+
* WASM-allocated object; instantiating one per file (the previous
|
|
461
|
+
* behaviour) leaked memory faster than V8 could reclaim it — OOM
|
|
462
|
+
* at ~1100 files even with --max-old-space-size=8192. Reusing one
|
|
463
|
+
* parser per language for the lifetime of the ASTParser instance
|
|
464
|
+
* is exactly what the tree-sitter docs recommend.
|
|
465
|
+
*
|
|
466
|
+
* Map key is the resolved Language; the same Language object is
|
|
467
|
+
* cached per-language above (tsLang, pyLang, …) so the WeakMap is
|
|
468
|
+
* stable across calls.
|
|
469
|
+
*/
|
|
470
|
+
parserCache = /* @__PURE__ */ new WeakMap();
|
|
471
|
+
getParser(language) {
|
|
472
|
+
let parser = this.parserCache.get(language);
|
|
473
|
+
if (parser) return parser;
|
|
474
|
+
parser = new TreeSitter.Parser();
|
|
475
|
+
parser.setLanguage(language);
|
|
476
|
+
this.parserCache.set(language, parser);
|
|
477
|
+
return parser;
|
|
478
|
+
}
|
|
458
479
|
dartLang = null;
|
|
459
480
|
grammarLoader = new GrammarLoader();
|
|
460
481
|
async init() {
|
|
@@ -611,12 +632,15 @@ var ASTParser = class {
|
|
|
611
632
|
if (ext === ".php") return this.parsePhp(filePath);
|
|
612
633
|
if (ext === ".dart") return this.parseDart(filePath);
|
|
613
634
|
if (ext === ".vue") return this.parseVue(filePath);
|
|
614
|
-
const parser =
|
|
615
|
-
parser.setLanguage(this.tsLang);
|
|
635
|
+
const parser = this.getParser(this.tsLang);
|
|
616
636
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
617
637
|
const tree = parser.parse(source);
|
|
618
638
|
if (!tree) return [];
|
|
619
|
-
|
|
639
|
+
try {
|
|
640
|
+
return this.extractTSNodes(tree.rootNode, filePath, source.split("\n"));
|
|
641
|
+
} finally {
|
|
642
|
+
tree.delete();
|
|
643
|
+
}
|
|
620
644
|
}
|
|
621
645
|
extractTSNodes(rootNode, _filePath, lines) {
|
|
622
646
|
const nodes = [];
|
|
@@ -793,21 +817,27 @@ var ASTParser = class {
|
|
|
793
817
|
if (!match?.[1]?.trim()) return [];
|
|
794
818
|
const scriptContent = match[1];
|
|
795
819
|
if (!this.tsLang) return [];
|
|
796
|
-
const parser =
|
|
797
|
-
parser.setLanguage(this.tsLang);
|
|
820
|
+
const parser = this.getParser(this.tsLang);
|
|
798
821
|
const tree = parser.parse(scriptContent);
|
|
799
822
|
if (!tree) return [];
|
|
800
|
-
|
|
823
|
+
try {
|
|
824
|
+
return this.extractTSNodes(tree.rootNode, filePath, scriptContent.split("\n"));
|
|
825
|
+
} finally {
|
|
826
|
+
tree.delete();
|
|
827
|
+
}
|
|
801
828
|
}
|
|
802
829
|
async parsePython(filePath) {
|
|
803
830
|
if (!this.pyLang) await this.loadPython();
|
|
804
831
|
if (!this.pyLang) return [];
|
|
805
|
-
const parser =
|
|
806
|
-
parser.setLanguage(this.pyLang);
|
|
832
|
+
const parser = this.getParser(this.pyLang);
|
|
807
833
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
808
834
|
const tree = parser.parse(source);
|
|
809
835
|
if (!tree) return [];
|
|
810
|
-
|
|
836
|
+
try {
|
|
837
|
+
return this.extractPythonNodes(tree.rootNode, filePath, source);
|
|
838
|
+
} finally {
|
|
839
|
+
tree.delete();
|
|
840
|
+
}
|
|
811
841
|
}
|
|
812
842
|
async parseNotebook(filePath) {
|
|
813
843
|
if (!this.pyLang) await this.loadPython();
|
|
@@ -816,11 +846,14 @@ var ASTParser = class {
|
|
|
816
846
|
const raw = fs2.readFileSync(filePath, "utf-8");
|
|
817
847
|
const pythonSource = extractNotebookPythonSource(raw);
|
|
818
848
|
if (!pythonSource.trim()) return [];
|
|
819
|
-
const parser =
|
|
820
|
-
parser.setLanguage(this.pyLang);
|
|
849
|
+
const parser = this.getParser(this.pyLang);
|
|
821
850
|
const tree = parser.parse(pythonSource);
|
|
822
851
|
if (!tree) return [];
|
|
823
|
-
|
|
852
|
+
try {
|
|
853
|
+
return this.extractPythonNodes(tree.rootNode, filePath, pythonSource);
|
|
854
|
+
} finally {
|
|
855
|
+
tree.delete();
|
|
856
|
+
}
|
|
824
857
|
} catch {
|
|
825
858
|
return [];
|
|
826
859
|
}
|
|
@@ -903,8 +936,7 @@ var ASTParser = class {
|
|
|
903
936
|
async parseGo(filePath) {
|
|
904
937
|
if (!this.goLang) await this.loadGo();
|
|
905
938
|
if (!this.goLang) return [];
|
|
906
|
-
const parser =
|
|
907
|
-
parser.setLanguage(this.goLang);
|
|
939
|
+
const parser = this.getParser(this.goLang);
|
|
908
940
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
909
941
|
const tree = parser.parse(source);
|
|
910
942
|
if (!tree) return [];
|
|
@@ -984,14 +1016,17 @@ var ASTParser = class {
|
|
|
984
1016
|
if (child) walk(child);
|
|
985
1017
|
}
|
|
986
1018
|
};
|
|
987
|
-
|
|
988
|
-
|
|
1019
|
+
try {
|
|
1020
|
+
walk(tree.rootNode);
|
|
1021
|
+
return nodes;
|
|
1022
|
+
} finally {
|
|
1023
|
+
tree.delete();
|
|
1024
|
+
}
|
|
989
1025
|
}
|
|
990
1026
|
async parseRust(filePath) {
|
|
991
1027
|
if (!this.rustLang) await this.loadRust();
|
|
992
1028
|
if (!this.rustLang) return [];
|
|
993
|
-
const parser =
|
|
994
|
-
parser.setLanguage(this.rustLang);
|
|
1029
|
+
const parser = this.getParser(this.rustLang);
|
|
995
1030
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
996
1031
|
const tree = parser.parse(source);
|
|
997
1032
|
if (!tree) return [];
|
|
@@ -1093,14 +1128,17 @@ var ASTParser = class {
|
|
|
1093
1128
|
if (child) walk(child);
|
|
1094
1129
|
}
|
|
1095
1130
|
};
|
|
1096
|
-
|
|
1097
|
-
|
|
1131
|
+
try {
|
|
1132
|
+
walk(tree.rootNode);
|
|
1133
|
+
return nodes;
|
|
1134
|
+
} finally {
|
|
1135
|
+
tree.delete();
|
|
1136
|
+
}
|
|
1098
1137
|
}
|
|
1099
1138
|
async parseJava(filePath) {
|
|
1100
1139
|
if (!this.javaLang) await this.loadJava();
|
|
1101
1140
|
if (!this.javaLang) return [];
|
|
1102
|
-
const parser =
|
|
1103
|
-
parser.setLanguage(this.javaLang);
|
|
1141
|
+
const parser = this.getParser(this.javaLang);
|
|
1104
1142
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1105
1143
|
const tree = parser.parse(source);
|
|
1106
1144
|
if (!tree) return [];
|
|
@@ -1193,14 +1231,17 @@ var ASTParser = class {
|
|
|
1193
1231
|
if (child) walk(child);
|
|
1194
1232
|
}
|
|
1195
1233
|
};
|
|
1196
|
-
|
|
1197
|
-
|
|
1234
|
+
try {
|
|
1235
|
+
walk(tree.rootNode);
|
|
1236
|
+
return nodes;
|
|
1237
|
+
} finally {
|
|
1238
|
+
tree.delete();
|
|
1239
|
+
}
|
|
1198
1240
|
}
|
|
1199
1241
|
async parseCSharp(filePath) {
|
|
1200
1242
|
if (!this.csLang) await this.loadCSharp();
|
|
1201
1243
|
if (!this.csLang) return [];
|
|
1202
|
-
const parser =
|
|
1203
|
-
parser.setLanguage(this.csLang);
|
|
1244
|
+
const parser = this.getParser(this.csLang);
|
|
1204
1245
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1205
1246
|
const tree = parser.parse(source);
|
|
1206
1247
|
if (!tree) return [];
|
|
@@ -1271,14 +1312,17 @@ var ASTParser = class {
|
|
|
1271
1312
|
if (child) walk(child);
|
|
1272
1313
|
}
|
|
1273
1314
|
};
|
|
1274
|
-
|
|
1275
|
-
|
|
1315
|
+
try {
|
|
1316
|
+
walk(tree.rootNode);
|
|
1317
|
+
return nodes;
|
|
1318
|
+
} finally {
|
|
1319
|
+
tree.delete();
|
|
1320
|
+
}
|
|
1276
1321
|
}
|
|
1277
1322
|
async parseRuby(filePath) {
|
|
1278
1323
|
if (!this.rubyLang) await this.loadRuby();
|
|
1279
1324
|
if (!this.rubyLang) return [];
|
|
1280
|
-
const parser =
|
|
1281
|
-
parser.setLanguage(this.rubyLang);
|
|
1325
|
+
const parser = this.getParser(this.rubyLang);
|
|
1282
1326
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1283
1327
|
const tree = parser.parse(source);
|
|
1284
1328
|
if (!tree) return [];
|
|
@@ -1334,14 +1378,17 @@ var ASTParser = class {
|
|
|
1334
1378
|
if (child) walk(child);
|
|
1335
1379
|
}
|
|
1336
1380
|
};
|
|
1337
|
-
|
|
1338
|
-
|
|
1381
|
+
try {
|
|
1382
|
+
walk(tree.rootNode);
|
|
1383
|
+
return nodes;
|
|
1384
|
+
} finally {
|
|
1385
|
+
tree.delete();
|
|
1386
|
+
}
|
|
1339
1387
|
}
|
|
1340
1388
|
async parseKotlin(filePath) {
|
|
1341
1389
|
if (!this.kotlinLang) await this.loadKotlin();
|
|
1342
1390
|
if (!this.kotlinLang) return [];
|
|
1343
|
-
const parser =
|
|
1344
|
-
parser.setLanguage(this.kotlinLang);
|
|
1391
|
+
const parser = this.getParser(this.kotlinLang);
|
|
1345
1392
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1346
1393
|
const tree = parser.parse(source);
|
|
1347
1394
|
if (!tree) return [];
|
|
@@ -1394,14 +1441,17 @@ var ASTParser = class {
|
|
|
1394
1441
|
if (child) walk(child);
|
|
1395
1442
|
}
|
|
1396
1443
|
};
|
|
1397
|
-
|
|
1398
|
-
|
|
1444
|
+
try {
|
|
1445
|
+
walk(tree.rootNode);
|
|
1446
|
+
return nodes;
|
|
1447
|
+
} finally {
|
|
1448
|
+
tree.delete();
|
|
1449
|
+
}
|
|
1399
1450
|
}
|
|
1400
1451
|
async parseSwift(filePath) {
|
|
1401
1452
|
if (!this.swiftLang) await this.loadSwift();
|
|
1402
1453
|
if (!this.swiftLang) return [];
|
|
1403
|
-
const parser =
|
|
1404
|
-
parser.setLanguage(this.swiftLang);
|
|
1454
|
+
const parser = this.getParser(this.swiftLang);
|
|
1405
1455
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1406
1456
|
const tree = parser.parse(source);
|
|
1407
1457
|
if (!tree) return [];
|
|
@@ -1466,14 +1516,17 @@ var ASTParser = class {
|
|
|
1466
1516
|
if (child) walk(child);
|
|
1467
1517
|
}
|
|
1468
1518
|
};
|
|
1469
|
-
|
|
1470
|
-
|
|
1519
|
+
try {
|
|
1520
|
+
walk(tree.rootNode);
|
|
1521
|
+
return nodes;
|
|
1522
|
+
} finally {
|
|
1523
|
+
tree.delete();
|
|
1524
|
+
}
|
|
1471
1525
|
}
|
|
1472
1526
|
async parsePhp(filePath) {
|
|
1473
1527
|
if (!this.phpLang) await this.loadPhp();
|
|
1474
1528
|
if (!this.phpLang) return [];
|
|
1475
|
-
const parser =
|
|
1476
|
-
parser.setLanguage(this.phpLang);
|
|
1529
|
+
const parser = this.getParser(this.phpLang);
|
|
1477
1530
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1478
1531
|
const tree = parser.parse(source);
|
|
1479
1532
|
if (!tree) return [];
|
|
@@ -1545,14 +1598,17 @@ var ASTParser = class {
|
|
|
1545
1598
|
if (child) walk(child);
|
|
1546
1599
|
}
|
|
1547
1600
|
};
|
|
1548
|
-
|
|
1549
|
-
|
|
1601
|
+
try {
|
|
1602
|
+
walk(tree.rootNode);
|
|
1603
|
+
return nodes;
|
|
1604
|
+
} finally {
|
|
1605
|
+
tree.delete();
|
|
1606
|
+
}
|
|
1550
1607
|
}
|
|
1551
1608
|
async parseDart(filePath) {
|
|
1552
1609
|
if (!this.dartLang) await this.loadDart();
|
|
1553
1610
|
if (!this.dartLang) return [];
|
|
1554
|
-
const parser =
|
|
1555
|
-
parser.setLanguage(this.dartLang);
|
|
1611
|
+
const parser = this.getParser(this.dartLang);
|
|
1556
1612
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1557
1613
|
const tree = parser.parse(source);
|
|
1558
1614
|
if (!tree) return [];
|
|
@@ -1607,16 +1663,19 @@ var ASTParser = class {
|
|
|
1607
1663
|
if (child) walk(child);
|
|
1608
1664
|
}
|
|
1609
1665
|
};
|
|
1610
|
-
|
|
1611
|
-
|
|
1666
|
+
try {
|
|
1667
|
+
walk(tree.rootNode);
|
|
1668
|
+
return nodes;
|
|
1669
|
+
} finally {
|
|
1670
|
+
tree.delete();
|
|
1671
|
+
}
|
|
1612
1672
|
}
|
|
1613
1673
|
/**
|
|
1614
1674
|
* Find all call sites of a symbol in a file.
|
|
1615
1675
|
*/
|
|
1616
1676
|
async findCallSites(filePath, symbolName) {
|
|
1617
1677
|
if (!this.tsLang) throw new Error("ASTParser not initialized. Call init() first.");
|
|
1618
|
-
const parser =
|
|
1619
|
-
parser.setLanguage(this.tsLang);
|
|
1678
|
+
const parser = this.getParser(this.tsLang);
|
|
1620
1679
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1621
1680
|
const tree = parser.parse(source);
|
|
1622
1681
|
if (!tree) return [];
|
|
@@ -1641,8 +1700,12 @@ var ASTParser = class {
|
|
|
1641
1700
|
if (child) walk(child);
|
|
1642
1701
|
}
|
|
1643
1702
|
};
|
|
1644
|
-
|
|
1645
|
-
|
|
1703
|
+
try {
|
|
1704
|
+
walk(tree.rootNode);
|
|
1705
|
+
return results;
|
|
1706
|
+
} finally {
|
|
1707
|
+
tree.delete();
|
|
1708
|
+
}
|
|
1646
1709
|
}
|
|
1647
1710
|
/**
|
|
1648
1711
|
* Extract all call edges in a TypeScript/TSX file.
|
|
@@ -1651,8 +1714,7 @@ var ASTParser = class {
|
|
|
1651
1714
|
*/
|
|
1652
1715
|
async parseAllCallEdges(filePath) {
|
|
1653
1716
|
if (!this.tsLang) throw new Error("ASTParser not initialized. Call init() first.");
|
|
1654
|
-
const parser =
|
|
1655
|
-
parser.setLanguage(this.tsLang);
|
|
1717
|
+
const parser = this.getParser(this.tsLang);
|
|
1656
1718
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1657
1719
|
const tree = parser.parse(source);
|
|
1658
1720
|
if (!tree) return [];
|
|
@@ -1683,8 +1745,12 @@ var ASTParser = class {
|
|
|
1683
1745
|
if (child) walk(child, newStack);
|
|
1684
1746
|
}
|
|
1685
1747
|
};
|
|
1686
|
-
|
|
1687
|
-
|
|
1748
|
+
try {
|
|
1749
|
+
walk(tree.rootNode, []);
|
|
1750
|
+
return results;
|
|
1751
|
+
} finally {
|
|
1752
|
+
tree.delete();
|
|
1753
|
+
}
|
|
1688
1754
|
}
|
|
1689
1755
|
};
|
|
1690
1756
|
|
|
@@ -3771,27 +3837,68 @@ var Skeletonizer = class {
|
|
|
3771
3837
|
}
|
|
3772
3838
|
/**
|
|
3773
3839
|
* Produce a plain-text skeleton of the file.
|
|
3840
|
+
*
|
|
3841
|
+
* Three layers of pathological-input defense — without them, a single
|
|
3842
|
+
* minified bundled file (e.g. Next.js ships entire compiled vendor
|
|
3843
|
+
* packages as 466KB-on-16-lines `.cjs` files) explodes into hundreds
|
|
3844
|
+
* of MB of output. The `import` and `interface` cases call
|
|
3845
|
+
* `readLines(node.startLine, node.endLine)`; on minified one-line
|
|
3846
|
+
* source where every node spans the whole file, that returns the
|
|
3847
|
+
* entire file each time, and many such nodes repeat the duplication.
|
|
3848
|
+
* Observed: 466KB → 211MB (452× expansion) on @vercel/blob's compiled
|
|
3849
|
+
* bundle in next.js. Defenses, in order of cheapest:
|
|
3850
|
+
*
|
|
3851
|
+
* 1. `MAX_INPUT_BYTES` — skip files larger than 256KB. AI context
|
|
3852
|
+
* tools shouldn't be skeletonizing pre-built vendor bundles
|
|
3853
|
+
* anyway; they're not human-authored source.
|
|
3854
|
+
* 2. Average-line-length heuristic — if mean line >1KB, treat as
|
|
3855
|
+
* minified and skip. Catches the .cjs/.min.js pattern that
|
|
3856
|
+
* slips under the 256KB ceiling.
|
|
3857
|
+
* 3. `MAX_OUTPUT_BYTES` running cap — belt-and-suspenders against
|
|
3858
|
+
* anything the first two miss. Stop appending and return what
|
|
3859
|
+
* we have rather than OOM.
|
|
3860
|
+
*
|
|
3861
|
+
* Skipped files return a single comment so callers can distinguish
|
|
3862
|
+
* "deliberately skipped" from "skeletonized to empty".
|
|
3774
3863
|
*/
|
|
3775
3864
|
async skeletonize(filePath) {
|
|
3865
|
+
const fileSource = fs13.readFileSync(filePath, "utf-8");
|
|
3866
|
+
const fileLines = fileSource.split("\n");
|
|
3867
|
+
const MAX_INPUT_BYTES = 256 * 1024;
|
|
3868
|
+
if (fileSource.length > MAX_INPUT_BYTES) {
|
|
3869
|
+
return `// Source: ${filePath}
|
|
3870
|
+
// (skipped: ${fileSource.length} bytes exceeds ${MAX_INPUT_BYTES} byte limit; likely a bundled vendor file)`;
|
|
3871
|
+
}
|
|
3872
|
+
const meanLineBytes = fileSource.length / Math.max(fileLines.length, 1);
|
|
3873
|
+
if (meanLineBytes > 1024) {
|
|
3874
|
+
return `// Source: ${filePath}
|
|
3875
|
+
// (skipped: appears minified \u2014 ${fileLines.length} lines for ${fileSource.length} bytes)`;
|
|
3876
|
+
}
|
|
3776
3877
|
const nodes = await this.parser.parse(filePath);
|
|
3777
|
-
const fileLines = fs13.readFileSync(filePath, "utf-8").split("\n");
|
|
3778
3878
|
const lines = [`// Source: ${filePath}`];
|
|
3879
|
+
const MAX_OUTPUT_BYTES = 1024 * 1024;
|
|
3880
|
+
let outputBytes = lines[0].length;
|
|
3779
3881
|
for (const node of nodes) {
|
|
3882
|
+
if (outputBytes > MAX_OUTPUT_BYTES) {
|
|
3883
|
+
lines.push(`// (output truncated at ${MAX_OUTPUT_BYTES} bytes)`);
|
|
3884
|
+
break;
|
|
3885
|
+
}
|
|
3886
|
+
let chunk = "";
|
|
3780
3887
|
switch (node.type) {
|
|
3781
3888
|
case "import":
|
|
3782
|
-
|
|
3889
|
+
chunk = this.readLines(fileLines, node.startLine, node.endLine);
|
|
3783
3890
|
break;
|
|
3784
3891
|
case "interface":
|
|
3785
|
-
|
|
3892
|
+
chunk = this.readLines(fileLines, node.startLine, node.endLine);
|
|
3786
3893
|
break;
|
|
3787
3894
|
case "function":
|
|
3788
|
-
|
|
3895
|
+
chunk = `${node.signature};`;
|
|
3789
3896
|
break;
|
|
3790
3897
|
case "arrow_function":
|
|
3791
|
-
|
|
3898
|
+
chunk = `${node.signature};`;
|
|
3792
3899
|
break;
|
|
3793
3900
|
case "export_default":
|
|
3794
|
-
|
|
3901
|
+
chunk = `${node.signature};`;
|
|
3795
3902
|
break;
|
|
3796
3903
|
case "class": {
|
|
3797
3904
|
const methodLines = (node.methodRanges ?? []).map((mr) => {
|
|
@@ -3801,12 +3908,16 @@ var Skeletonizer = class {
|
|
|
3801
3908
|
if (methodLines.length === 0 && node.methods) {
|
|
3802
3909
|
node.methods.forEach((m) => methodLines.push(` ${m}(...): unknown;`));
|
|
3803
3910
|
}
|
|
3804
|
-
|
|
3911
|
+
chunk = `class ${node.name} {
|
|
3805
3912
|
${methodLines.join("\n")}
|
|
3806
|
-
}
|
|
3913
|
+
}`;
|
|
3807
3914
|
break;
|
|
3808
3915
|
}
|
|
3809
3916
|
}
|
|
3917
|
+
if (chunk) {
|
|
3918
|
+
lines.push(chunk);
|
|
3919
|
+
outputBytes += chunk.length + 1;
|
|
3920
|
+
}
|
|
3810
3921
|
}
|
|
3811
3922
|
return lines.join("\n");
|
|
3812
3923
|
}
|
|
@@ -303,6 +303,27 @@ var ASTParser = class {
|
|
|
303
303
|
kotlinLang = null;
|
|
304
304
|
swiftLang = null;
|
|
305
305
|
phpLang = null;
|
|
306
|
+
/**
|
|
307
|
+
* Per-language parser cache. Each TreeSitter.Parser is a
|
|
308
|
+
* WASM-allocated object; instantiating one per file (the previous
|
|
309
|
+
* behaviour) leaked memory faster than V8 could reclaim it — OOM
|
|
310
|
+
* at ~1100 files even with --max-old-space-size=8192. Reusing one
|
|
311
|
+
* parser per language for the lifetime of the ASTParser instance
|
|
312
|
+
* is exactly what the tree-sitter docs recommend.
|
|
313
|
+
*
|
|
314
|
+
* Map key is the resolved Language; the same Language object is
|
|
315
|
+
* cached per-language above (tsLang, pyLang, …) so the WeakMap is
|
|
316
|
+
* stable across calls.
|
|
317
|
+
*/
|
|
318
|
+
parserCache = /* @__PURE__ */ new WeakMap();
|
|
319
|
+
getParser(language) {
|
|
320
|
+
let parser = this.parserCache.get(language);
|
|
321
|
+
if (parser) return parser;
|
|
322
|
+
parser = new TreeSitter.Parser();
|
|
323
|
+
parser.setLanguage(language);
|
|
324
|
+
this.parserCache.set(language, parser);
|
|
325
|
+
return parser;
|
|
326
|
+
}
|
|
306
327
|
dartLang = null;
|
|
307
328
|
grammarLoader = new GrammarLoader();
|
|
308
329
|
async init() {
|
|
@@ -459,12 +480,15 @@ var ASTParser = class {
|
|
|
459
480
|
if (ext === ".php") return this.parsePhp(filePath);
|
|
460
481
|
if (ext === ".dart") return this.parseDart(filePath);
|
|
461
482
|
if (ext === ".vue") return this.parseVue(filePath);
|
|
462
|
-
const parser =
|
|
463
|
-
parser.setLanguage(this.tsLang);
|
|
483
|
+
const parser = this.getParser(this.tsLang);
|
|
464
484
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
465
485
|
const tree = parser.parse(source);
|
|
466
486
|
if (!tree) return [];
|
|
467
|
-
|
|
487
|
+
try {
|
|
488
|
+
return this.extractTSNodes(tree.rootNode, filePath, source.split("\n"));
|
|
489
|
+
} finally {
|
|
490
|
+
tree.delete();
|
|
491
|
+
}
|
|
468
492
|
}
|
|
469
493
|
extractTSNodes(rootNode, _filePath, lines) {
|
|
470
494
|
const nodes = [];
|
|
@@ -641,21 +665,27 @@ var ASTParser = class {
|
|
|
641
665
|
if (!match?.[1]?.trim()) return [];
|
|
642
666
|
const scriptContent = match[1];
|
|
643
667
|
if (!this.tsLang) return [];
|
|
644
|
-
const parser =
|
|
645
|
-
parser.setLanguage(this.tsLang);
|
|
668
|
+
const parser = this.getParser(this.tsLang);
|
|
646
669
|
const tree = parser.parse(scriptContent);
|
|
647
670
|
if (!tree) return [];
|
|
648
|
-
|
|
671
|
+
try {
|
|
672
|
+
return this.extractTSNodes(tree.rootNode, filePath, scriptContent.split("\n"));
|
|
673
|
+
} finally {
|
|
674
|
+
tree.delete();
|
|
675
|
+
}
|
|
649
676
|
}
|
|
650
677
|
async parsePython(filePath) {
|
|
651
678
|
if (!this.pyLang) await this.loadPython();
|
|
652
679
|
if (!this.pyLang) return [];
|
|
653
|
-
const parser =
|
|
654
|
-
parser.setLanguage(this.pyLang);
|
|
680
|
+
const parser = this.getParser(this.pyLang);
|
|
655
681
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
656
682
|
const tree = parser.parse(source);
|
|
657
683
|
if (!tree) return [];
|
|
658
|
-
|
|
684
|
+
try {
|
|
685
|
+
return this.extractPythonNodes(tree.rootNode, filePath, source);
|
|
686
|
+
} finally {
|
|
687
|
+
tree.delete();
|
|
688
|
+
}
|
|
659
689
|
}
|
|
660
690
|
async parseNotebook(filePath) {
|
|
661
691
|
if (!this.pyLang) await this.loadPython();
|
|
@@ -664,11 +694,14 @@ var ASTParser = class {
|
|
|
664
694
|
const raw = fs2.readFileSync(filePath, "utf-8");
|
|
665
695
|
const pythonSource = extractNotebookPythonSource(raw);
|
|
666
696
|
if (!pythonSource.trim()) return [];
|
|
667
|
-
const parser =
|
|
668
|
-
parser.setLanguage(this.pyLang);
|
|
697
|
+
const parser = this.getParser(this.pyLang);
|
|
669
698
|
const tree = parser.parse(pythonSource);
|
|
670
699
|
if (!tree) return [];
|
|
671
|
-
|
|
700
|
+
try {
|
|
701
|
+
return this.extractPythonNodes(tree.rootNode, filePath, pythonSource);
|
|
702
|
+
} finally {
|
|
703
|
+
tree.delete();
|
|
704
|
+
}
|
|
672
705
|
} catch {
|
|
673
706
|
return [];
|
|
674
707
|
}
|
|
@@ -751,8 +784,7 @@ var ASTParser = class {
|
|
|
751
784
|
async parseGo(filePath) {
|
|
752
785
|
if (!this.goLang) await this.loadGo();
|
|
753
786
|
if (!this.goLang) return [];
|
|
754
|
-
const parser =
|
|
755
|
-
parser.setLanguage(this.goLang);
|
|
787
|
+
const parser = this.getParser(this.goLang);
|
|
756
788
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
757
789
|
const tree = parser.parse(source);
|
|
758
790
|
if (!tree) return [];
|
|
@@ -832,14 +864,17 @@ var ASTParser = class {
|
|
|
832
864
|
if (child) walk(child);
|
|
833
865
|
}
|
|
834
866
|
};
|
|
835
|
-
|
|
836
|
-
|
|
867
|
+
try {
|
|
868
|
+
walk(tree.rootNode);
|
|
869
|
+
return nodes;
|
|
870
|
+
} finally {
|
|
871
|
+
tree.delete();
|
|
872
|
+
}
|
|
837
873
|
}
|
|
838
874
|
async parseRust(filePath) {
|
|
839
875
|
if (!this.rustLang) await this.loadRust();
|
|
840
876
|
if (!this.rustLang) return [];
|
|
841
|
-
const parser =
|
|
842
|
-
parser.setLanguage(this.rustLang);
|
|
877
|
+
const parser = this.getParser(this.rustLang);
|
|
843
878
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
844
879
|
const tree = parser.parse(source);
|
|
845
880
|
if (!tree) return [];
|
|
@@ -941,14 +976,17 @@ var ASTParser = class {
|
|
|
941
976
|
if (child) walk(child);
|
|
942
977
|
}
|
|
943
978
|
};
|
|
944
|
-
|
|
945
|
-
|
|
979
|
+
try {
|
|
980
|
+
walk(tree.rootNode);
|
|
981
|
+
return nodes;
|
|
982
|
+
} finally {
|
|
983
|
+
tree.delete();
|
|
984
|
+
}
|
|
946
985
|
}
|
|
947
986
|
async parseJava(filePath) {
|
|
948
987
|
if (!this.javaLang) await this.loadJava();
|
|
949
988
|
if (!this.javaLang) return [];
|
|
950
|
-
const parser =
|
|
951
|
-
parser.setLanguage(this.javaLang);
|
|
989
|
+
const parser = this.getParser(this.javaLang);
|
|
952
990
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
953
991
|
const tree = parser.parse(source);
|
|
954
992
|
if (!tree) return [];
|
|
@@ -1041,14 +1079,17 @@ var ASTParser = class {
|
|
|
1041
1079
|
if (child) walk(child);
|
|
1042
1080
|
}
|
|
1043
1081
|
};
|
|
1044
|
-
|
|
1045
|
-
|
|
1082
|
+
try {
|
|
1083
|
+
walk(tree.rootNode);
|
|
1084
|
+
return nodes;
|
|
1085
|
+
} finally {
|
|
1086
|
+
tree.delete();
|
|
1087
|
+
}
|
|
1046
1088
|
}
|
|
1047
1089
|
async parseCSharp(filePath) {
|
|
1048
1090
|
if (!this.csLang) await this.loadCSharp();
|
|
1049
1091
|
if (!this.csLang) return [];
|
|
1050
|
-
const parser =
|
|
1051
|
-
parser.setLanguage(this.csLang);
|
|
1092
|
+
const parser = this.getParser(this.csLang);
|
|
1052
1093
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1053
1094
|
const tree = parser.parse(source);
|
|
1054
1095
|
if (!tree) return [];
|
|
@@ -1119,14 +1160,17 @@ var ASTParser = class {
|
|
|
1119
1160
|
if (child) walk(child);
|
|
1120
1161
|
}
|
|
1121
1162
|
};
|
|
1122
|
-
|
|
1123
|
-
|
|
1163
|
+
try {
|
|
1164
|
+
walk(tree.rootNode);
|
|
1165
|
+
return nodes;
|
|
1166
|
+
} finally {
|
|
1167
|
+
tree.delete();
|
|
1168
|
+
}
|
|
1124
1169
|
}
|
|
1125
1170
|
async parseRuby(filePath) {
|
|
1126
1171
|
if (!this.rubyLang) await this.loadRuby();
|
|
1127
1172
|
if (!this.rubyLang) return [];
|
|
1128
|
-
const parser =
|
|
1129
|
-
parser.setLanguage(this.rubyLang);
|
|
1173
|
+
const parser = this.getParser(this.rubyLang);
|
|
1130
1174
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1131
1175
|
const tree = parser.parse(source);
|
|
1132
1176
|
if (!tree) return [];
|
|
@@ -1182,14 +1226,17 @@ var ASTParser = class {
|
|
|
1182
1226
|
if (child) walk(child);
|
|
1183
1227
|
}
|
|
1184
1228
|
};
|
|
1185
|
-
|
|
1186
|
-
|
|
1229
|
+
try {
|
|
1230
|
+
walk(tree.rootNode);
|
|
1231
|
+
return nodes;
|
|
1232
|
+
} finally {
|
|
1233
|
+
tree.delete();
|
|
1234
|
+
}
|
|
1187
1235
|
}
|
|
1188
1236
|
async parseKotlin(filePath) {
|
|
1189
1237
|
if (!this.kotlinLang) await this.loadKotlin();
|
|
1190
1238
|
if (!this.kotlinLang) return [];
|
|
1191
|
-
const parser =
|
|
1192
|
-
parser.setLanguage(this.kotlinLang);
|
|
1239
|
+
const parser = this.getParser(this.kotlinLang);
|
|
1193
1240
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1194
1241
|
const tree = parser.parse(source);
|
|
1195
1242
|
if (!tree) return [];
|
|
@@ -1242,14 +1289,17 @@ var ASTParser = class {
|
|
|
1242
1289
|
if (child) walk(child);
|
|
1243
1290
|
}
|
|
1244
1291
|
};
|
|
1245
|
-
|
|
1246
|
-
|
|
1292
|
+
try {
|
|
1293
|
+
walk(tree.rootNode);
|
|
1294
|
+
return nodes;
|
|
1295
|
+
} finally {
|
|
1296
|
+
tree.delete();
|
|
1297
|
+
}
|
|
1247
1298
|
}
|
|
1248
1299
|
async parseSwift(filePath) {
|
|
1249
1300
|
if (!this.swiftLang) await this.loadSwift();
|
|
1250
1301
|
if (!this.swiftLang) return [];
|
|
1251
|
-
const parser =
|
|
1252
|
-
parser.setLanguage(this.swiftLang);
|
|
1302
|
+
const parser = this.getParser(this.swiftLang);
|
|
1253
1303
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1254
1304
|
const tree = parser.parse(source);
|
|
1255
1305
|
if (!tree) return [];
|
|
@@ -1314,14 +1364,17 @@ var ASTParser = class {
|
|
|
1314
1364
|
if (child) walk(child);
|
|
1315
1365
|
}
|
|
1316
1366
|
};
|
|
1317
|
-
|
|
1318
|
-
|
|
1367
|
+
try {
|
|
1368
|
+
walk(tree.rootNode);
|
|
1369
|
+
return nodes;
|
|
1370
|
+
} finally {
|
|
1371
|
+
tree.delete();
|
|
1372
|
+
}
|
|
1319
1373
|
}
|
|
1320
1374
|
async parsePhp(filePath) {
|
|
1321
1375
|
if (!this.phpLang) await this.loadPhp();
|
|
1322
1376
|
if (!this.phpLang) return [];
|
|
1323
|
-
const parser =
|
|
1324
|
-
parser.setLanguage(this.phpLang);
|
|
1377
|
+
const parser = this.getParser(this.phpLang);
|
|
1325
1378
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1326
1379
|
const tree = parser.parse(source);
|
|
1327
1380
|
if (!tree) return [];
|
|
@@ -1393,14 +1446,17 @@ var ASTParser = class {
|
|
|
1393
1446
|
if (child) walk(child);
|
|
1394
1447
|
}
|
|
1395
1448
|
};
|
|
1396
|
-
|
|
1397
|
-
|
|
1449
|
+
try {
|
|
1450
|
+
walk(tree.rootNode);
|
|
1451
|
+
return nodes;
|
|
1452
|
+
} finally {
|
|
1453
|
+
tree.delete();
|
|
1454
|
+
}
|
|
1398
1455
|
}
|
|
1399
1456
|
async parseDart(filePath) {
|
|
1400
1457
|
if (!this.dartLang) await this.loadDart();
|
|
1401
1458
|
if (!this.dartLang) return [];
|
|
1402
|
-
const parser =
|
|
1403
|
-
parser.setLanguage(this.dartLang);
|
|
1459
|
+
const parser = this.getParser(this.dartLang);
|
|
1404
1460
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1405
1461
|
const tree = parser.parse(source);
|
|
1406
1462
|
if (!tree) return [];
|
|
@@ -1455,16 +1511,19 @@ var ASTParser = class {
|
|
|
1455
1511
|
if (child) walk(child);
|
|
1456
1512
|
}
|
|
1457
1513
|
};
|
|
1458
|
-
|
|
1459
|
-
|
|
1514
|
+
try {
|
|
1515
|
+
walk(tree.rootNode);
|
|
1516
|
+
return nodes;
|
|
1517
|
+
} finally {
|
|
1518
|
+
tree.delete();
|
|
1519
|
+
}
|
|
1460
1520
|
}
|
|
1461
1521
|
/**
|
|
1462
1522
|
* Find all call sites of a symbol in a file.
|
|
1463
1523
|
*/
|
|
1464
1524
|
async findCallSites(filePath, symbolName) {
|
|
1465
1525
|
if (!this.tsLang) throw new Error("ASTParser not initialized. Call init() first.");
|
|
1466
|
-
const parser =
|
|
1467
|
-
parser.setLanguage(this.tsLang);
|
|
1526
|
+
const parser = this.getParser(this.tsLang);
|
|
1468
1527
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1469
1528
|
const tree = parser.parse(source);
|
|
1470
1529
|
if (!tree) return [];
|
|
@@ -1489,8 +1548,12 @@ var ASTParser = class {
|
|
|
1489
1548
|
if (child) walk(child);
|
|
1490
1549
|
}
|
|
1491
1550
|
};
|
|
1492
|
-
|
|
1493
|
-
|
|
1551
|
+
try {
|
|
1552
|
+
walk(tree.rootNode);
|
|
1553
|
+
return results;
|
|
1554
|
+
} finally {
|
|
1555
|
+
tree.delete();
|
|
1556
|
+
}
|
|
1494
1557
|
}
|
|
1495
1558
|
/**
|
|
1496
1559
|
* Extract all call edges in a TypeScript/TSX file.
|
|
@@ -1499,8 +1562,7 @@ var ASTParser = class {
|
|
|
1499
1562
|
*/
|
|
1500
1563
|
async parseAllCallEdges(filePath) {
|
|
1501
1564
|
if (!this.tsLang) throw new Error("ASTParser not initialized. Call init() first.");
|
|
1502
|
-
const parser =
|
|
1503
|
-
parser.setLanguage(this.tsLang);
|
|
1565
|
+
const parser = this.getParser(this.tsLang);
|
|
1504
1566
|
const source = fs2.readFileSync(filePath, "utf-8");
|
|
1505
1567
|
const tree = parser.parse(source);
|
|
1506
1568
|
if (!tree) return [];
|
|
@@ -1531,8 +1593,12 @@ var ASTParser = class {
|
|
|
1531
1593
|
if (child) walk(child, newStack);
|
|
1532
1594
|
}
|
|
1533
1595
|
};
|
|
1534
|
-
|
|
1535
|
-
|
|
1596
|
+
try {
|
|
1597
|
+
walk(tree.rootNode, []);
|
|
1598
|
+
return results;
|
|
1599
|
+
} finally {
|
|
1600
|
+
tree.delete();
|
|
1601
|
+
}
|
|
1536
1602
|
}
|
|
1537
1603
|
};
|
|
1538
1604
|
|
|
@@ -4051,27 +4117,68 @@ var Skeletonizer = class {
|
|
|
4051
4117
|
}
|
|
4052
4118
|
/**
|
|
4053
4119
|
* Produce a plain-text skeleton of the file.
|
|
4120
|
+
*
|
|
4121
|
+
* Three layers of pathological-input defense — without them, a single
|
|
4122
|
+
* minified bundled file (e.g. Next.js ships entire compiled vendor
|
|
4123
|
+
* packages as 466KB-on-16-lines `.cjs` files) explodes into hundreds
|
|
4124
|
+
* of MB of output. The `import` and `interface` cases call
|
|
4125
|
+
* `readLines(node.startLine, node.endLine)`; on minified one-line
|
|
4126
|
+
* source where every node spans the whole file, that returns the
|
|
4127
|
+
* entire file each time, and many such nodes repeat the duplication.
|
|
4128
|
+
* Observed: 466KB → 211MB (452× expansion) on @vercel/blob's compiled
|
|
4129
|
+
* bundle in next.js. Defenses, in order of cheapest:
|
|
4130
|
+
*
|
|
4131
|
+
* 1. `MAX_INPUT_BYTES` — skip files larger than 256KB. AI context
|
|
4132
|
+
* tools shouldn't be skeletonizing pre-built vendor bundles
|
|
4133
|
+
* anyway; they're not human-authored source.
|
|
4134
|
+
* 2. Average-line-length heuristic — if mean line >1KB, treat as
|
|
4135
|
+
* minified and skip. Catches the .cjs/.min.js pattern that
|
|
4136
|
+
* slips under the 256KB ceiling.
|
|
4137
|
+
* 3. `MAX_OUTPUT_BYTES` running cap — belt-and-suspenders against
|
|
4138
|
+
* anything the first two miss. Stop appending and return what
|
|
4139
|
+
* we have rather than OOM.
|
|
4140
|
+
*
|
|
4141
|
+
* Skipped files return a single comment so callers can distinguish
|
|
4142
|
+
* "deliberately skipped" from "skeletonized to empty".
|
|
4054
4143
|
*/
|
|
4055
4144
|
async skeletonize(filePath) {
|
|
4145
|
+
const fileSource = fs12.readFileSync(filePath, "utf-8");
|
|
4146
|
+
const fileLines = fileSource.split("\n");
|
|
4147
|
+
const MAX_INPUT_BYTES = 256 * 1024;
|
|
4148
|
+
if (fileSource.length > MAX_INPUT_BYTES) {
|
|
4149
|
+
return `// Source: ${filePath}
|
|
4150
|
+
// (skipped: ${fileSource.length} bytes exceeds ${MAX_INPUT_BYTES} byte limit; likely a bundled vendor file)`;
|
|
4151
|
+
}
|
|
4152
|
+
const meanLineBytes = fileSource.length / Math.max(fileLines.length, 1);
|
|
4153
|
+
if (meanLineBytes > 1024) {
|
|
4154
|
+
return `// Source: ${filePath}
|
|
4155
|
+
// (skipped: appears minified \u2014 ${fileLines.length} lines for ${fileSource.length} bytes)`;
|
|
4156
|
+
}
|
|
4056
4157
|
const nodes = await this.parser.parse(filePath);
|
|
4057
|
-
const fileLines = fs12.readFileSync(filePath, "utf-8").split("\n");
|
|
4058
4158
|
const lines = [`// Source: ${filePath}`];
|
|
4159
|
+
const MAX_OUTPUT_BYTES = 1024 * 1024;
|
|
4160
|
+
let outputBytes = lines[0].length;
|
|
4059
4161
|
for (const node of nodes) {
|
|
4162
|
+
if (outputBytes > MAX_OUTPUT_BYTES) {
|
|
4163
|
+
lines.push(`// (output truncated at ${MAX_OUTPUT_BYTES} bytes)`);
|
|
4164
|
+
break;
|
|
4165
|
+
}
|
|
4166
|
+
let chunk = "";
|
|
4060
4167
|
switch (node.type) {
|
|
4061
4168
|
case "import":
|
|
4062
|
-
|
|
4169
|
+
chunk = this.readLines(fileLines, node.startLine, node.endLine);
|
|
4063
4170
|
break;
|
|
4064
4171
|
case "interface":
|
|
4065
|
-
|
|
4172
|
+
chunk = this.readLines(fileLines, node.startLine, node.endLine);
|
|
4066
4173
|
break;
|
|
4067
4174
|
case "function":
|
|
4068
|
-
|
|
4175
|
+
chunk = `${node.signature};`;
|
|
4069
4176
|
break;
|
|
4070
4177
|
case "arrow_function":
|
|
4071
|
-
|
|
4178
|
+
chunk = `${node.signature};`;
|
|
4072
4179
|
break;
|
|
4073
4180
|
case "export_default":
|
|
4074
|
-
|
|
4181
|
+
chunk = `${node.signature};`;
|
|
4075
4182
|
break;
|
|
4076
4183
|
case "class": {
|
|
4077
4184
|
const methodLines = (node.methodRanges ?? []).map((mr) => {
|
|
@@ -4081,12 +4188,16 @@ var Skeletonizer = class {
|
|
|
4081
4188
|
if (methodLines.length === 0 && node.methods) {
|
|
4082
4189
|
node.methods.forEach((m) => methodLines.push(` ${m}(...): unknown;`));
|
|
4083
4190
|
}
|
|
4084
|
-
|
|
4191
|
+
chunk = `class ${node.name} {
|
|
4085
4192
|
${methodLines.join("\n")}
|
|
4086
|
-
}
|
|
4193
|
+
}`;
|
|
4087
4194
|
break;
|
|
4088
4195
|
}
|
|
4089
4196
|
}
|
|
4197
|
+
if (chunk) {
|
|
4198
|
+
lines.push(chunk);
|
|
4199
|
+
outputBytes += chunk.length + 1;
|
|
4200
|
+
}
|
|
4090
4201
|
}
|
|
4091
4202
|
return lines.join("\n");
|
|
4092
4203
|
}
|
|
@@ -8420,4 +8531,4 @@ export {
|
|
|
8420
8531
|
track,
|
|
8421
8532
|
captureError
|
|
8422
8533
|
};
|
|
8423
|
-
//# sourceMappingURL=chunk-
|
|
8534
|
+
//# sourceMappingURL=chunk-EHFVPRTN.js.map
|
package/dist/index.js
CHANGED
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
startTrial,
|
|
35
35
|
track,
|
|
36
36
|
writeCODEOWNERS
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-EHFVPRTN.js";
|
|
38
38
|
import {
|
|
39
39
|
VectorStore
|
|
40
40
|
} from "./chunk-NEHYSE2Y.js";
|
|
@@ -512,7 +512,7 @@ try {
|
|
|
512
512
|
} catch {
|
|
513
513
|
}
|
|
514
514
|
var args = process.argv.slice(2);
|
|
515
|
-
var ctxloomVersion = "1.0.
|
|
515
|
+
var ctxloomVersion = "1.0.18".length > 0 ? "1.0.18" : "dev";
|
|
516
516
|
if (args.includes("--version") || args.includes("-v")) {
|
|
517
517
|
process.stdout.write(`ctxloom ${ctxloomVersion}
|
|
518
518
|
`);
|
|
@@ -585,7 +585,7 @@ async function checkLicense() {
|
|
|
585
585
|
if (command !== void 0 && LICENSE_GATE_BYPASS_COMMANDS.has(command)) return;
|
|
586
586
|
const ciKey = process.env["CTXLOOM_LICENSE_KEY"];
|
|
587
587
|
if (ciKey) {
|
|
588
|
-
const { ApiClient } = await import("./src-
|
|
588
|
+
const { ApiClient } = await import("./src-IHPQZOZE.js");
|
|
589
589
|
const client = new ApiClient(process.env["CTXLOOM_API_BASE"]);
|
|
590
590
|
try {
|
|
591
591
|
const result = await client.validate(ciKey, "ci-ephemeral");
|
|
@@ -1112,7 +1112,7 @@ Suggested reviewers for ${files.length} file(s):`);
|
|
|
1112
1112
|
process.stderr.write("[ctxloom] --limit must be a non-negative integer (0 for unlimited)\n");
|
|
1113
1113
|
process.exit(2);
|
|
1114
1114
|
}
|
|
1115
|
-
const { loadRulesConfig, RulesChecker, formatText, formatJson, RulesConfigError } = await import("./src-
|
|
1115
|
+
const { loadRulesConfig, RulesChecker, formatText, formatJson, RulesConfigError } = await import("./src-IHPQZOZE.js");
|
|
1116
1116
|
let config;
|
|
1117
1117
|
try {
|
|
1118
1118
|
config = await loadRulesConfig(root);
|
|
@@ -1136,7 +1136,7 @@ Suggested reviewers for ${files.length} file(s):`);
|
|
|
1136
1136
|
}
|
|
1137
1137
|
let graph;
|
|
1138
1138
|
if (useSnapshot) {
|
|
1139
|
-
const { DependencyGraph: DG } = await import("./src-
|
|
1139
|
+
const { DependencyGraph: DG } = await import("./src-IHPQZOZE.js");
|
|
1140
1140
|
graph = new DG();
|
|
1141
1141
|
const loaded = await graph.loadSnapshotOnly(root);
|
|
1142
1142
|
if (!loaded) {
|
|
@@ -1145,7 +1145,7 @@ Suggested reviewers for ${files.length} file(s):`);
|
|
|
1145
1145
|
}
|
|
1146
1146
|
} else {
|
|
1147
1147
|
process.stderr.write("[ctxloom] Building dependency graph...\n");
|
|
1148
|
-
const { ASTParser: ASTParser2, DependencyGraph: DependencyGraph2 } = await import("./src-
|
|
1148
|
+
const { ASTParser: ASTParser2, DependencyGraph: DependencyGraph2 } = await import("./src-IHPQZOZE.js");
|
|
1149
1149
|
let parser;
|
|
1150
1150
|
try {
|
|
1151
1151
|
parser = new ASTParser2();
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
startTrial,
|
|
70
70
|
track,
|
|
71
71
|
writeCODEOWNERS
|
|
72
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-EHFVPRTN.js";
|
|
73
73
|
import {
|
|
74
74
|
VectorStore
|
|
75
75
|
} from "./chunk-NEHYSE2Y.js";
|
|
@@ -160,4 +160,4 @@ export {
|
|
|
160
160
|
track,
|
|
161
161
|
writeCODEOWNERS
|
|
162
162
|
};
|
|
163
|
-
//# sourceMappingURL=src-
|
|
163
|
+
//# sourceMappingURL=src-IHPQZOZE.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ctxloom-pro",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.18",
|
|
4
4
|
"description": "ctxloom — The Universal Code Context Engine. A local-first MCP server providing intelligent code context via hybrid Vector + AST + Graph search with Skeletonization (92% token reduction).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|