cto-ai-cli 4.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
@@ -478,10 +478,7 @@ function deduplicateFindings(findings) {
478
478
  import { createHash as createHash2 } from "crypto";
479
479
 
480
480
  // src/engine/pruner.ts
481
- import { Project, SyntaxKind } from "ts-morph";
482
481
  import { readFile as readFile3 } from "fs/promises";
483
- import { existsSync as existsSync2 } from "fs";
484
- import { join as join2 } from "path";
485
482
 
486
483
  // src/engine/tokenizer.ts
487
484
  import { encodingForModel } from "js-tiktoken";
@@ -536,23 +533,7 @@ async function pruneTypeScript(file, level) {
536
533
  } catch {
537
534
  return emptyResult(file, level);
538
535
  }
539
- let project;
540
- try {
541
- const tsConfigPath = findTsConfig(file.path);
542
- project = new Project({
543
- tsConfigFilePath: tsConfigPath,
544
- skipAddingFilesFromTsConfig: true,
545
- compilerOptions: tsConfigPath ? void 0 : { allowJs: true, esModuleInterop: true }
546
- });
547
- project.createSourceFile(file.path, content, { overwrite: true });
548
- } catch {
549
- return pruneGenericFromContent(file, content, level);
550
- }
551
- const sourceFile = project.getSourceFiles()[0];
552
- if (!sourceFile) {
553
- return pruneGenericFromContent(file, content, level);
554
- }
555
- const prunedContent = level === "signatures" ? extractSignaturesAST(sourceFile) : extractSkeletonAST(sourceFile);
536
+ const prunedContent = level === "signatures" ? extractSignaturesRegex(content) : extractSkeletonRegex(content);
556
537
  const prunedTokens = countTokensChars4(Buffer.byteLength(prunedContent, "utf-8"));
557
538
  const savingsPercent = file.tokens > 0 ? (file.tokens - prunedTokens) / file.tokens * 100 : 0;
558
539
  return {
@@ -564,131 +545,281 @@ async function pruneTypeScript(file, level) {
564
545
  savingsPercent: Math.max(0, savingsPercent)
565
546
  };
566
547
  }
567
- function extractSignaturesAST(sf) {
548
+ function extractSignaturesRegex(content) {
549
+ const lines = content.split("\n");
568
550
  const parts = [];
569
- for (const imp of sf.getImportDeclarations()) {
570
- parts.push(imp.getText());
571
- }
572
- if (parts.length > 0) parts.push("");
573
- for (const ta of sf.getTypeAliases()) {
574
- addJSDoc(ta, parts);
575
- parts.push(ta.getText());
576
- }
577
- for (const iface of sf.getInterfaces()) {
578
- addJSDoc(iface, parts);
579
- parts.push(iface.getText());
580
- }
581
- for (const en of sf.getEnums()) {
582
- addJSDoc(en, parts);
583
- parts.push(en.getText());
584
- }
585
- for (const fn of sf.getFunctions()) {
586
- addJSDoc(fn, parts);
587
- const isExported = fn.isExported();
588
- const isAsync = fn.isAsync();
589
- const name = fn.getName() ?? "<anonymous>";
590
- const params = fn.getParameters().map((p) => p.getText()).join(", ");
591
- const returnType = fn.getReturnTypeNode()?.getText();
592
- const returnStr = returnType ? `: ${returnType}` : "";
593
- const prefix = isExported ? "export " : "";
594
- const asyncStr = isAsync ? "async " : "";
595
- parts.push(`${prefix}${asyncStr}function ${name}(${params})${returnStr} { /* ... */ }`);
596
- }
597
- for (const stmt of sf.getVariableStatements()) {
598
- for (const decl of stmt.getDeclarations()) {
599
- const init = decl.getInitializer();
600
- if (init && (init.getKind() === SyntaxKind.ArrowFunction || init.getKind() === SyntaxKind.FunctionExpression)) {
601
- addJSDoc(stmt, parts);
602
- const isExported = stmt.isExported();
603
- const prefix = isExported ? "export " : "";
604
- const kind = stmt.getDeclarationKind();
605
- const name = decl.getName();
606
- const typeNode = decl.getTypeNode()?.getText();
607
- const typeStr = typeNode ? `: ${typeNode}` : "";
608
- parts.push(`${prefix}${kind} ${name}${typeStr} = /* ... */;`);
609
- } else {
610
- addJSDoc(stmt, parts);
611
- parts.push(stmt.getText());
551
+ let i = 0;
552
+ while (i < lines.length) {
553
+ const line = lines[i];
554
+ const trimmed = line.trim();
555
+ if (trimmed === "") {
556
+ i++;
557
+ continue;
558
+ }
559
+ if (trimmed.startsWith("/**")) {
560
+ const docLines = [];
561
+ while (i < lines.length) {
562
+ docLines.push(lines[i]);
563
+ if (lines[i].includes("*/")) {
564
+ i++;
565
+ break;
566
+ }
567
+ i++;
568
+ }
569
+ parts.push(docLines.join("\n"));
570
+ continue;
571
+ }
572
+ if (trimmed.startsWith("//")) {
573
+ parts.push(line);
574
+ i++;
575
+ continue;
576
+ }
577
+ if (/^\s*(import|export)\s/.test(line) && (trimmed.includes(" from ") || trimmed.startsWith("import "))) {
578
+ const block = collectBracedLine(lines, i);
579
+ parts.push(block.text);
580
+ i = block.nextIndex;
581
+ continue;
582
+ }
583
+ if (/^\s*export\s*(\{|\*)/.test(trimmed)) {
584
+ const block = collectBracedLine(lines, i);
585
+ parts.push(block.text);
586
+ i = block.nextIndex;
587
+ continue;
588
+ }
589
+ if (/^\s*(export\s+)?type\s+\w/.test(trimmed) && !trimmed.startsWith("typeof")) {
590
+ const block = collectBalanced(lines, i);
591
+ parts.push(block.text);
592
+ i = block.nextIndex;
593
+ continue;
594
+ }
595
+ if (/^\s*(export\s+)?interface\s+\w/.test(trimmed)) {
596
+ const block = collectBalanced(lines, i);
597
+ parts.push(block.text);
598
+ i = block.nextIndex;
599
+ continue;
600
+ }
601
+ if (/^\s*(export\s+)?(const\s+)?enum\s+\w/.test(trimmed)) {
602
+ const block = collectBalanced(lines, i);
603
+ parts.push(block.text);
604
+ i = block.nextIndex;
605
+ continue;
606
+ }
607
+ const fnMatch = trimmed.match(/^(export\s+)?(async\s+)?function\s+(\w+)/);
608
+ if (fnMatch) {
609
+ const sig = extractFnSignature(lines, i);
610
+ parts.push(`${sig} { /* ... */ }`);
611
+ i = skipBlock(lines, i);
612
+ continue;
613
+ }
614
+ const arrowMatch = trimmed.match(/^(export\s+)?(const|let|var)\s+(\w+)/);
615
+ if (arrowMatch && looksLikeFunctionDecl(lines, i)) {
616
+ const prefix = trimmed.match(/^((?:export\s+)?(?:const|let|var)\s+\w+[^=]*=)/)?.[1];
617
+ if (prefix) {
618
+ parts.push(`${prefix} /* ... */;`);
612
619
  }
620
+ i = skipBlock(lines, i);
621
+ continue;
613
622
  }
614
- }
615
- for (const cls of sf.getClasses()) {
616
- addJSDoc(cls, parts);
617
- const isExported = cls.isExported();
618
- const prefix = isExported ? "export " : "";
619
- const name = cls.getName() ?? "<anonymous>";
620
- const ext = cls.getExtends()?.getText();
621
- const impl = cls.getImplements().map((i) => i.getText()).join(", ");
622
- let header = `${prefix}class ${name}`;
623
- if (ext) header += ` extends ${ext}`;
624
- if (impl) header += ` implements ${impl}`;
625
- header += " {";
626
- parts.push(header);
627
- for (const prop of cls.getProperties()) {
628
- parts.push(` ${prop.getText()}`);
629
- }
630
- const ctor = cls.getConstructors()[0];
631
- if (ctor) {
632
- const ctorParams = ctor.getParameters().map((p) => p.getText()).join(", ");
633
- parts.push(` constructor(${ctorParams}) { /* ... */ }`);
634
- }
635
- for (const method of cls.getMethods()) {
636
- const isStatic = method.isStatic();
637
- const isAsync = method.isAsync();
638
- const methodName = method.getName();
639
- const methodParams = method.getParameters().map((p) => p.getText()).join(", ");
640
- const returnType = method.getReturnTypeNode()?.getText();
641
- const returnStr = returnType ? `: ${returnType}` : "";
642
- const staticStr = isStatic ? "static " : "";
643
- const asyncStr = isAsync ? "async " : "";
644
- parts.push(` ${staticStr}${asyncStr}${methodName}(${methodParams})${returnStr} { /* ... */ }`);
645
- }
646
- parts.push("}");
647
- }
648
- for (const exp of sf.getExportDeclarations()) {
649
- parts.push(exp.getText());
650
- }
651
- for (const exp of sf.getExportAssignments()) {
652
- parts.push(exp.getText());
623
+ if (arrowMatch) {
624
+ const block = collectStatement(lines, i);
625
+ parts.push(block.text);
626
+ i = block.nextIndex;
627
+ continue;
628
+ }
629
+ if (/^\s*(export\s+)?(abstract\s+)?class\s+\w/.test(trimmed)) {
630
+ const classOutline = extractClassOutline(lines, i);
631
+ parts.push(classOutline.text);
632
+ i = classOutline.nextIndex;
633
+ continue;
634
+ }
635
+ i++;
653
636
  }
654
637
  return parts.join("\n");
655
638
  }
656
- function extractSkeletonAST(sf) {
639
+ function extractSkeletonRegex(content) {
640
+ const lines = content.split("\n");
657
641
  const parts = [];
658
- for (const imp of sf.getImportDeclarations()) {
659
- parts.push(imp.getText());
660
- }
661
- if (parts.length > 0) parts.push("");
662
- for (const ta of sf.getTypeAliases()) {
663
- if (ta.isExported()) parts.push(ta.getText());
664
- }
665
- for (const iface of sf.getInterfaces()) {
666
- if (!iface.isExported()) continue;
667
- const ext = iface.getExtends().map((e) => e.getText());
668
- const extStr = ext.length > 0 ? ` extends ${ext.join(", ")}` : "";
669
- parts.push(`export interface ${iface.getName()}${extStr} { /* ${iface.getProperties().length} props */ }`);
670
- }
671
- for (const en of sf.getEnums()) {
672
- if (!en.isExported()) continue;
673
- const members = en.getMembers().map((m) => m.getName());
674
- parts.push(`export enum ${en.getName()} { ${members.join(", ")} }`);
675
- }
676
- for (const fn of sf.getFunctions()) {
677
- if (!fn.isExported()) continue;
678
- const name = fn.getName() ?? "<anonymous>";
679
- const params = fn.getParameters().map((p) => p.getText()).join(", ");
680
- parts.push(`export function ${name}(${params});`);
681
- }
682
- for (const cls of sf.getClasses()) {
683
- if (!cls.isExported()) continue;
684
- const methods = cls.getMethods().map((m) => m.getName());
685
- parts.push(`export class ${cls.getName()} { /* methods: ${methods.join(", ")} */ }`);
686
- }
687
- for (const exp of sf.getExportDeclarations()) {
688
- parts.push(exp.getText());
642
+ let i = 0;
643
+ while (i < lines.length) {
644
+ const trimmed = lines[i].trim();
645
+ if (/^import\s/.test(trimmed)) {
646
+ const block = collectBracedLine(lines, i);
647
+ parts.push(block.text);
648
+ i = block.nextIndex;
649
+ continue;
650
+ }
651
+ if (/^export\s+(type|interface)\s+\w/.test(trimmed)) {
652
+ const block = collectBalanced(lines, i);
653
+ parts.push(block.text);
654
+ i = block.nextIndex;
655
+ continue;
656
+ }
657
+ if (/^export\s+(const\s+)?enum\s+\w/.test(trimmed)) {
658
+ const block = collectBalanced(lines, i);
659
+ parts.push(block.text);
660
+ i = block.nextIndex;
661
+ continue;
662
+ }
663
+ if (/^export\s+(async\s+)?function\s+\w/.test(trimmed)) {
664
+ const sig = extractFnSignature(lines, i);
665
+ parts.push(`${sig};`);
666
+ i = skipBlock(lines, i);
667
+ continue;
668
+ }
669
+ if (/^export\s+(abstract\s+)?class\s+/.test(trimmed)) {
670
+ const nameMatch = trimmed.match(/class\s+(\w+)/);
671
+ const name = nameMatch?.[1] ?? "Unknown";
672
+ const end = skipBlock(lines, i);
673
+ const methods = [];
674
+ for (let j = i + 1; j < end; j++) {
675
+ const mt = lines[j].trim();
676
+ const mm = mt.match(/^(?:static\s+)?(?:async\s+)?(\w+)\s*\(/);
677
+ if (mm && mm[1] !== "constructor") methods.push(mm[1]);
678
+ }
679
+ parts.push(`export class ${name} { /* methods: ${methods.join(", ")} */ }`);
680
+ i = end;
681
+ continue;
682
+ }
683
+ if (/^export\s*(\{|\*)/.test(trimmed)) {
684
+ const block = collectBracedLine(lines, i);
685
+ parts.push(block.text);
686
+ i = block.nextIndex;
687
+ continue;
688
+ }
689
+ i++;
689
690
  }
690
691
  return parts.join("\n");
691
692
  }
693
+ function collectBracedLine(lines, start) {
694
+ let text = lines[start];
695
+ let i = start + 1;
696
+ while (i < lines.length && !text.includes(";") && !text.trimEnd().endsWith("'") && !text.trimEnd().endsWith('"')) {
697
+ text += "\n" + lines[i];
698
+ i++;
699
+ }
700
+ return { text, nextIndex: i };
701
+ }
702
+ function collectBalanced(lines, start) {
703
+ let depth = 0;
704
+ let text = "";
705
+ let i = start;
706
+ let started = false;
707
+ while (i < lines.length) {
708
+ const line = lines[i];
709
+ text += (text ? "\n" : "") + line;
710
+ for (const ch of line) {
711
+ if (ch === "{" || ch === "(") {
712
+ depth++;
713
+ started = true;
714
+ }
715
+ if (ch === "}" || ch === ")") depth--;
716
+ }
717
+ i++;
718
+ if (started && depth <= 0) break;
719
+ if (!started && line.includes(";")) break;
720
+ }
721
+ return { text, nextIndex: i };
722
+ }
723
+ function collectStatement(lines, start) {
724
+ let text = lines[start];
725
+ let i = start + 1;
726
+ if (text.includes(";")) return { text, nextIndex: i };
727
+ let depth = 0;
728
+ for (const ch of text) {
729
+ if (ch === "{" || ch === "(" || ch === "[") depth++;
730
+ if (ch === "}" || ch === ")" || ch === "]") depth--;
731
+ }
732
+ while (i < lines.length && depth > 0) {
733
+ text += "\n" + lines[i];
734
+ for (const ch of lines[i]) {
735
+ if (ch === "{" || ch === "(" || ch === "[") depth++;
736
+ if (ch === "}" || ch === ")" || ch === "]") depth--;
737
+ }
738
+ i++;
739
+ }
740
+ return { text, nextIndex: i };
741
+ }
742
+ function extractFnSignature(lines, start) {
743
+ let sig = "";
744
+ let i = start;
745
+ while (i < lines.length) {
746
+ const line = lines[i].trim();
747
+ sig += (sig ? " " : "") + line;
748
+ if (line.includes("{")) {
749
+ sig = sig.replace(/\s*\{[^]*$/, "").trim();
750
+ break;
751
+ }
752
+ i++;
753
+ }
754
+ return sig;
755
+ }
756
+ function skipBlock(lines, start) {
757
+ let depth = 0;
758
+ let i = start;
759
+ let foundBrace = false;
760
+ while (i < lines.length) {
761
+ for (const ch of lines[i]) {
762
+ if (ch === "{") {
763
+ depth++;
764
+ foundBrace = true;
765
+ }
766
+ if (ch === "}") depth--;
767
+ }
768
+ i++;
769
+ if (foundBrace && depth <= 0) break;
770
+ if (!foundBrace && lines[i - 1].includes(";")) break;
771
+ }
772
+ return i;
773
+ }
774
+ function looksLikeFunctionDecl(lines, start) {
775
+ const chunk = lines.slice(start, Math.min(start + 5, lines.length)).join(" ");
776
+ return /=>/.test(chunk) || /=\s*function/.test(chunk);
777
+ }
778
+ function extractClassOutline(lines, start) {
779
+ const header = lines[start].trim();
780
+ let headerText = header;
781
+ let i = start + 1;
782
+ if (!header.includes("{")) {
783
+ while (i < lines.length) {
784
+ headerText += " " + lines[i].trim();
785
+ if (lines[i].includes("{")) {
786
+ i++;
787
+ break;
788
+ }
789
+ i++;
790
+ }
791
+ } else {
792
+ i = start + 1;
793
+ }
794
+ const bodyParts = [headerText.replace(/\{[^]*$/, "{").trim()];
795
+ let depth = 1;
796
+ while (i < lines.length && depth > 0) {
797
+ const line = lines[i];
798
+ const trimmed = line.trim();
799
+ for (const ch of line) {
800
+ if (ch === "{") depth++;
801
+ if (ch === "}") depth--;
802
+ }
803
+ if (depth <= 0) {
804
+ i++;
805
+ break;
806
+ }
807
+ if (depth === 1) {
808
+ if (/^(private|protected|public|readonly|static|#)/.test(trimmed) && !trimmed.includes("(")) {
809
+ bodyParts.push(` ${trimmed}`);
810
+ } else if (/^constructor\s*\(/.test(trimmed)) {
811
+ const sig = extractFnSignature(lines, i);
812
+ bodyParts.push(` ${sig} { /* ... */ }`);
813
+ } else if (/^(?:static\s+)?(?:async\s+)?(?:get\s+|set\s+)?\w+\s*[(<]/.test(trimmed) && !trimmed.startsWith("//")) {
814
+ const sig = extractFnSignature(lines, i);
815
+ bodyParts.push(` ${sig} { /* ... */ }`);
816
+ }
817
+ }
818
+ i++;
819
+ }
820
+ bodyParts.push("}");
821
+ return { text: bodyParts.join("\n"), nextIndex: i };
822
+ }
692
823
  async function pruneGeneric(file, level) {
693
824
  let content;
694
825
  try {
@@ -749,22 +880,6 @@ function emptyResult(file, level) {
749
880
  savingsPercent: 100
750
881
  };
751
882
  }
752
- function addJSDoc(node, parts) {
753
- if (!node.getJsDocs) return;
754
- const docs = node.getJsDocs();
755
- if (docs.length > 0) {
756
- parts.push(docs[0].getText());
757
- }
758
- }
759
- function findTsConfig(filePath) {
760
- let dir = filePath;
761
- for (let i = 0; i < 10; i++) {
762
- dir = join2(dir, "..");
763
- const candidate = join2(dir, "tsconfig.json");
764
- if (existsSync2(candidate)) return candidate;
765
- }
766
- return void 0;
767
- }
768
883
 
769
884
  // src/engine/graph-utils.ts
770
885
  function buildAdjacencyList(edges) {
@@ -1287,8 +1402,8 @@ async function optimizeContext(messages, analysis, config) {
1287
1402
  }
1288
1403
 
1289
1404
  // src/gateway/tracker.ts
1290
- import { mkdirSync as mkdirSync2, appendFileSync, readFileSync as readFileSync3, readdirSync, existsSync as existsSync3 } from "fs";
1291
- import { join as join3 } from "path";
1405
+ import { mkdirSync as mkdirSync2, appendFileSync, readFileSync as readFileSync3, readdirSync, existsSync as existsSync2 } from "fs";
1406
+ import { join as join2 } from "path";
1292
1407
  import { randomUUID } from "crypto";
1293
1408
  var UsageTracker = class {
1294
1409
  logDir;
@@ -1300,7 +1415,7 @@ var UsageTracker = class {
1300
1415
  memRecords = [];
1301
1416
  constructor(config) {
1302
1417
  this.config = config;
1303
- this.logDir = join3(config.logDir, "usage");
1418
+ this.logDir = join2(config.logDir, "usage");
1304
1419
  mkdirSync2(this.logDir, { recursive: true });
1305
1420
  }
1306
1421
  // ===== EVENT SYSTEM =====
@@ -1323,7 +1438,7 @@ var UsageTracker = class {
1323
1438
  ...params
1324
1439
  };
1325
1440
  const monthKey = this.getMonthKey(record.timestamp);
1326
- const logFile = join3(this.logDir, `${monthKey}.jsonl`);
1441
+ const logFile = join2(this.logDir, `${monthKey}.jsonl`);
1327
1442
  const line = JSON.stringify({
1328
1443
  ...record,
1329
1444
  timestamp: record.timestamp.toISOString()
@@ -1457,8 +1572,8 @@ var UsageTracker = class {
1457
1572
  return date.toISOString().slice(0, 7);
1458
1573
  }
1459
1574
  getMonthRecordsByKey(monthKey) {
1460
- const filePath = join3(this.logDir, `${monthKey}.jsonl`);
1461
- if (!existsSync3(filePath)) return [];
1575
+ const filePath = join2(this.logDir, `${monthKey}.jsonl`);
1576
+ if (!existsSync2(filePath)) return [];
1462
1577
  return readFileSync3(filePath, "utf-8").split("\n").filter((line) => line.trim()).map((line) => {
1463
1578
  try {
1464
1579
  const parsed = JSON.parse(line);
@@ -1472,8 +1587,8 @@ var UsageTracker = class {
1472
1587
  getMonthRecords(date) {
1473
1588
  const monthKey = this.getMonthKey(date);
1474
1589
  if (this.cache && this.cacheMonth === monthKey) return this.cache;
1475
- const filePath = join3(this.logDir, `${monthKey}.jsonl`);
1476
- if (!existsSync3(filePath)) return [];
1590
+ const filePath = join2(this.logDir, `${monthKey}.jsonl`);
1591
+ if (!existsSync2(filePath)) return [];
1477
1592
  const records = readFileSync3(filePath, "utf-8").split("\n").filter((line) => line.trim()).map((line) => {
1478
1593
  try {
1479
1594
  const parsed = JSON.parse(line);
@@ -1488,11 +1603,11 @@ var UsageTracker = class {
1488
1603
  return records;
1489
1604
  }
1490
1605
  getAllRecords() {
1491
- if (!existsSync3(this.logDir)) return [];
1606
+ if (!existsSync2(this.logDir)) return [];
1492
1607
  const files = readdirSync(this.logDir).filter((f) => f.endsWith(".jsonl")).sort();
1493
1608
  const allRecords = [];
1494
1609
  for (const file of files) {
1495
- const content = readFileSync3(join3(this.logDir, file), "utf-8");
1610
+ const content = readFileSync3(join2(this.logDir, file), "utf-8");
1496
1611
  const records = content.split("\n").filter((line) => line.trim()).map((line) => {
1497
1612
  try {
1498
1613
  const parsed = JSON.parse(line);
@@ -1510,7 +1625,7 @@ var UsageTracker = class {
1510
1625
 
1511
1626
  // src/engine/analyzer.ts
1512
1627
  import { readFile as readFile4, readdir, stat as stat2 } from "fs/promises";
1513
- import { join as join5, extname, relative as relative3, resolve as resolve4, basename as basename2 } from "path";
1628
+ import { join as join4, extname, relative as relative3, resolve as resolve4, basename as basename2 } from "path";
1514
1629
  import { createHash as createHash3 } from "crypto";
1515
1630
 
1516
1631
  // src/types/engine.ts
@@ -1563,14 +1678,14 @@ var DEFAULT_CONFIG = {
1563
1678
  };
1564
1679
 
1565
1680
  // src/engine/graph.ts
1566
- import { Project as Project2, SyntaxKind as SyntaxKind2 } from "ts-morph";
1567
- import { resolve as resolve3, relative as relative2, dirname as dirname2, join as join4 } from "path";
1568
- import { existsSync as existsSync4 } from "fs";
1681
+ import { Project, SyntaxKind } from "ts-morph";
1682
+ import { resolve as resolve3, relative as relative2, dirname as dirname2, join as join3 } from "path";
1683
+ import { existsSync as existsSync3 } from "fs";
1569
1684
  var TS_EXTENSIONS2 = /* @__PURE__ */ new Set(["ts", "tsx", "js", "jsx", "mts", "mjs", "cts", "cjs"]);
1570
1685
  function createProject(projectPath, filePaths) {
1571
- const tsConfigPath = join4(projectPath, "tsconfig.json");
1572
- const hasTsConfig = existsSync4(tsConfigPath);
1573
- const project = new Project2({
1686
+ const tsConfigPath = join3(projectPath, "tsconfig.json");
1687
+ const hasTsConfig = existsSync3(tsConfigPath);
1688
+ const project = new Project({
1574
1689
  tsConfigFilePath: hasTsConfig ? tsConfigPath : void 0,
1575
1690
  skipAddingFilesFromTsConfig: true,
1576
1691
  compilerOptions: hasTsConfig ? void 0 : {
@@ -1770,7 +1885,7 @@ function enrichComplexity(project, absPath, files) {
1770
1885
  }
1771
1886
  for (const varDecl of sourceFile.getVariableDeclarations()) {
1772
1887
  const init = varDecl.getInitializer();
1773
- if (init && (init.getKind() === SyntaxKind2.ArrowFunction || init.getKind() === SyntaxKind2.FunctionExpression)) {
1888
+ if (init && (init.getKind() === SyntaxKind.ArrowFunction || init.getKind() === SyntaxKind.FunctionExpression)) {
1774
1889
  totalComplexity += calculateCyclomaticComplexity(init);
1775
1890
  }
1776
1891
  }
@@ -1781,22 +1896,22 @@ function calculateCyclomaticComplexity(node) {
1781
1896
  let complexity = 1;
1782
1897
  node.forEachDescendant((descendant) => {
1783
1898
  switch (descendant.getKind()) {
1784
- case SyntaxKind2.IfStatement:
1785
- case SyntaxKind2.ConditionalExpression:
1786
- case SyntaxKind2.ForStatement:
1787
- case SyntaxKind2.ForInStatement:
1788
- case SyntaxKind2.ForOfStatement:
1789
- case SyntaxKind2.WhileStatement:
1790
- case SyntaxKind2.DoStatement:
1791
- case SyntaxKind2.CaseClause:
1792
- case SyntaxKind2.CatchClause:
1899
+ case SyntaxKind.IfStatement:
1900
+ case SyntaxKind.ConditionalExpression:
1901
+ case SyntaxKind.ForStatement:
1902
+ case SyntaxKind.ForInStatement:
1903
+ case SyntaxKind.ForOfStatement:
1904
+ case SyntaxKind.WhileStatement:
1905
+ case SyntaxKind.DoStatement:
1906
+ case SyntaxKind.CaseClause:
1907
+ case SyntaxKind.CatchClause:
1793
1908
  complexity++;
1794
1909
  break;
1795
- case SyntaxKind2.BinaryExpression: {
1910
+ case SyntaxKind.BinaryExpression: {
1796
1911
  const opToken = descendant.getOperatorToken?.();
1797
1912
  if (opToken) {
1798
1913
  const kind = opToken.getKind();
1799
- if (kind === SyntaxKind2.AmpersandAmpersandToken || kind === SyntaxKind2.BarBarToken || kind === SyntaxKind2.QuestionQuestionToken) {
1914
+ if (kind === SyntaxKind.AmpersandAmpersandToken || kind === SyntaxKind.BarBarToken || kind === SyntaxKind.QuestionQuestionToken) {
1800
1915
  complexity++;
1801
1916
  }
1802
1917
  }
@@ -1813,14 +1928,14 @@ function resolveImport(sourceFile, moduleSpecifier, projectRoot) {
1813
1928
  const extensions = [".ts", ".tsx", ".js", ".jsx", "/index.ts", "/index.tsx", "/index.js", "/index.jsx"];
1814
1929
  for (const ext of extensions) {
1815
1930
  const candidate = basePath.endsWith(ext) ? basePath : basePath + ext;
1816
- if (existsSync4(candidate)) {
1931
+ if (existsSync3(candidate)) {
1817
1932
  const rel = relative2(projectRoot, candidate);
1818
1933
  if (!rel.startsWith("..")) return rel;
1819
1934
  }
1820
1935
  }
1821
1936
  if (moduleSpecifier.endsWith(".js")) {
1822
1937
  const tsPath = basePath.replace(/\.js$/, ".ts");
1823
- if (existsSync4(tsPath)) {
1938
+ if (existsSync3(tsPath)) {
1824
1939
  const rel = relative2(projectRoot, tsPath);
1825
1940
  if (!rel.startsWith("..")) return rel;
1826
1941
  }
@@ -1981,7 +2096,7 @@ async function walkProject(rootPath, options) {
1981
2096
  }
1982
2097
  const promises = [];
1983
2098
  for (const entry of entries) {
1984
- const fullPath = join5(dir, entry.name);
2099
+ const fullPath = join4(dir, entry.name);
1985
2100
  if (entry.isDirectory()) {
1986
2101
  if (!ignoreDirSet.has(entry.name) && !entry.name.startsWith(".")) {
1987
2102
  promises.push(walk(fullPath, depth + 1));