cto-ai-cli 5.0.0 → 5.2.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.
@@ -848,6 +848,35 @@ declare function optimizeBudget(files: AnalyzedFile[], budget: number): Promise<
848
848
  declare function pruneFile(file: AnalyzedFile, level: PruneLevel): Promise<PrunedContent>;
849
849
  declare function pruneFiles(files: AnalyzedFile[], levelFn: (file: AnalyzedFile) => PruneLevel): Promise<PrunedContent[]>;
850
850
 
851
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
852
+ interface LogEntry {
853
+ level: LogLevel;
854
+ msg: string;
855
+ ts: string;
856
+ module?: string;
857
+ [key: string]: unknown;
858
+ }
859
+ declare function setLogLevel(level: LogLevel): void;
860
+ declare function setJsonLogging(enabled: boolean): void;
861
+ declare function createLogger(module: string): {
862
+ debug: (msg: string, data?: Record<string, unknown>) => void;
863
+ info: (msg: string, data?: Record<string, unknown>) => void;
864
+ warn: (msg: string, data?: Record<string, unknown>) => void;
865
+ error: (msg: string, data?: Record<string, unknown>) => void;
866
+ };
867
+ type Logger = ReturnType<typeof createLogger>;
868
+
869
+ type CtoErrorCode = 'ANALYSIS_FAILED' | 'FILE_READ_ERROR' | 'FILE_WRITE_ERROR' | 'GRAPH_BUILD_FAILED' | 'SELECTION_FAILED' | 'PRUNING_FAILED' | 'SCORING_FAILED' | 'AUDIT_FAILED' | 'GATEWAY_ERROR' | 'CONFIG_INVALID' | 'GIT_ERROR' | 'REVIEW_FAILED' | 'PREDICTION_FAILED' | 'MONOREPO_ERROR' | 'MCP_ERROR' | 'INVALID_INPUT';
870
+ declare class CtoError extends Error {
871
+ readonly code: CtoErrorCode;
872
+ readonly module: string;
873
+ readonly context?: Record<string, unknown>;
874
+ constructor(code: CtoErrorCode, message: string, module: string, context?: Record<string, unknown>);
875
+ toJSON(): Record<string, unknown>;
876
+ }
877
+ declare function isCtoError(err: unknown): err is CtoError;
878
+ declare function wrapError(err: unknown, code: CtoErrorCode, module: string, context?: Record<string, unknown>): CtoError;
879
+
851
880
  declare function countTokensTiktoken(text: string): number;
852
881
  declare function countTokensChars4(sizeInBytes: number): number;
853
882
  declare function estimateTokens(content: string, sizeInBytes: number, method?: 'chars4' | 'tiktoken'): number;
@@ -1017,4 +1046,4 @@ interface ReviewOptions {
1017
1046
  declare function analyzeForReview(analysis: ProjectAnalysis, options?: ReviewOptions): Promise<ReviewResult>;
1018
1047
  declare function renderReviewSummary(branch: string, baseBranch: string, changedFiles: ReviewFile[], breakingChanges: BreakingChange[], missingFiles: MissingFile[], impactRadius: ImpactRadius, reviewQuality: ReviewQuality): string;
1019
1048
 
1020
- export { type Baseline, type BenchmarkResult, type BreakingChange, type ChangeType, type ChangedFile, type CompilabilityMetrics, type CompilabilityResult, type CompileProofResult, type CompileProofStrategy, type ContextScore, type CrossPackageEdge, type CrossRepoModel, type CrossRepoPrediction, DEFAULT_GATE_CONFIG, type DiffHunk, type DimensionScore, type FeedbackEntry, type FeedbackInsight, type FeedbackModel, type FeedbackOutcome, type FileChangeEvent, type Grade, type ImpactRadius, MODEL_REGISTRY, type MissingFile, type ModelOptimization, type ModelProfile, type MonorepoAnalysis, type MonorepoTool, type MultiModelResult, type PRContextOptions, type PRContextResult, type PackageContextResult, type PackageInfo, type PredictionResult, type PredictorModel, type ProjectFingerprint, ProjectWatcher, type QualityBenchmarkResult, type QualityGateCheck, type QualityGateConfig, type QualityGateResult, type QualityMetrics, type ReviewFactor, type ReviewFile, type ReviewOptions, type ReviewQuality, type ReviewResult, type ScoreInsight, type SelectionInput, type SemanticAnalysis, type SemanticDomain, type SemanticFingerprint, type StrategyResult, type TeamFeedbackExport, type WatcherOptions, analyzeForReview, analyzeMonorepo, analyzeProject, analyzeSemantics, bfsBidirectional, buildAdjacencyList, buildProjectGraph, calculateCoverage, classifyFileKind, computeContextScore, computeFingerprint, configureCache, countTokensChars4, countTokensTiktoken, createProject, detectMonorepoTool, detectStack, estimateFileTokens, estimateTokens, exportFeedbackForTeam, freeEncoder, generatePRContext, getActiveWatchers, getCTODir, getCacheStats, getCachedAnalysis, getConfigPath, getCrossRepoStats, getFeedbackBoosts, getModelStats, getPolicyPath, getPredictorBoosts, getPruneLevelForRisk, importTeamFeedback, initProjectConfig, invalidateCache, loadBaseline, loadConfig, loadFeedbackModel, loadGlobalModel, loadModel, loadPolicyFromYAML, matchGlob, optimizeBudget, optimizeForModels, predictFromCrossRepo, predictRelevantFiles, pruneFile, pruneFiles, recordCrossRepoSelection, recordFeedback, recordSelection, renderBenchmark, renderCompilabilityBenchmark, renderCompileProof, renderContextScore, renderCrossRepoReport, renderFeedbackReport, renderMonorepoAnalysis, renderMultiModelResult, renderPackageContext, renderQualityBenchmark, renderReviewSummary, renderSemanticAnalysis, runBenchmark, runCompilabilityBenchmark, runCompileProof, runQualityBenchmark, runQualityGate, saveBaseline, saveConfig, scoreAllFiles, scoreFile, selectContext, selectPackageContext, semanticBoosts, unwatchAll, unwatchProject, walkProject, watchProject, wilsonLowerBound };
1049
+ export { type Baseline, type BenchmarkResult, type BreakingChange, type ChangeType, type ChangedFile, type CompilabilityMetrics, type CompilabilityResult, type CompileProofResult, type CompileProofStrategy, type ContextScore, type CrossPackageEdge, type CrossRepoModel, type CrossRepoPrediction, CtoError, type CtoErrorCode, DEFAULT_GATE_CONFIG, type DiffHunk, type DimensionScore, type FeedbackEntry, type FeedbackInsight, type FeedbackModel, type FeedbackOutcome, type FileChangeEvent, type Grade, type ImpactRadius, type LogEntry, type LogLevel, type Logger, MODEL_REGISTRY, type MissingFile, type ModelOptimization, type ModelProfile, type MonorepoAnalysis, type MonorepoTool, type MultiModelResult, type PRContextOptions, type PRContextResult, type PackageContextResult, type PackageInfo, type PredictionResult, type PredictorModel, type ProjectFingerprint, ProjectWatcher, type QualityBenchmarkResult, type QualityGateCheck, type QualityGateConfig, type QualityGateResult, type QualityMetrics, type ReviewFactor, type ReviewFile, type ReviewOptions, type ReviewQuality, type ReviewResult, type ScoreInsight, type SelectionInput, type SemanticAnalysis, type SemanticDomain, type SemanticFingerprint, type StrategyResult, type TeamFeedbackExport, type WatcherOptions, analyzeForReview, analyzeMonorepo, analyzeProject, analyzeSemantics, bfsBidirectional, buildAdjacencyList, buildProjectGraph, calculateCoverage, classifyFileKind, computeContextScore, computeFingerprint, configureCache, countTokensChars4, countTokensTiktoken, createLogger, createProject, detectMonorepoTool, detectStack, estimateFileTokens, estimateTokens, exportFeedbackForTeam, freeEncoder, generatePRContext, getActiveWatchers, getCTODir, getCacheStats, getCachedAnalysis, getConfigPath, getCrossRepoStats, getFeedbackBoosts, getModelStats, getPolicyPath, getPredictorBoosts, getPruneLevelForRisk, importTeamFeedback, initProjectConfig, invalidateCache, isCtoError, loadBaseline, loadConfig, loadFeedbackModel, loadGlobalModel, loadModel, loadPolicyFromYAML, matchGlob, optimizeBudget, optimizeForModels, predictFromCrossRepo, predictRelevantFiles, pruneFile, pruneFiles, recordCrossRepoSelection, recordFeedback, recordSelection, renderBenchmark, renderCompilabilityBenchmark, renderCompileProof, renderContextScore, renderCrossRepoReport, renderFeedbackReport, renderMonorepoAnalysis, renderMultiModelResult, renderPackageContext, renderQualityBenchmark, renderReviewSummary, renderSemanticAnalysis, runBenchmark, runCompilabilityBenchmark, runCompileProof, runQualityBenchmark, runQualityGate, saveBaseline, saveConfig, scoreAllFiles, scoreFile, selectContext, selectPackageContext, semanticBoosts, setJsonLogging, setLogLevel, unwatchAll, unwatchProject, walkProject, watchProject, wilsonLowerBound, wrapError };
@@ -610,8 +610,8 @@ async function analyzeProject(projectPath, config) {
610
610
  maxDepth: mergedConfig.analysis.maxDepth
611
611
  });
612
612
  const tokenMethod = mergedConfig.tokens.method;
613
- const files = [];
614
- for (const entry of walkEntries) {
613
+ const BATCH_SIZE = 50;
614
+ async function estimateFileTokens2(entry) {
615
615
  let tokens;
616
616
  if (tokenMethod === "tiktoken") {
617
617
  try {
@@ -623,7 +623,7 @@ async function analyzeProject(projectPath, config) {
623
623
  } else {
624
624
  tokens = countTokensChars4(entry.size);
625
625
  }
626
- files.push({
626
+ return {
627
627
  path: entry.path,
628
628
  relativePath: entry.relativePath,
629
629
  extension: entry.extension,
@@ -632,16 +632,20 @@ async function analyzeProject(projectPath, config) {
632
632
  lines: entry.lines,
633
633
  lastModified: entry.lastModified,
634
634
  kind: classifyFileKind(entry.relativePath),
635
- // Graph data — populated by graph analysis
636
635
  imports: [],
637
636
  importedBy: [],
638
637
  isHub: false,
639
638
  complexity: 0,
640
- // Risk data — populated by risk analysis
641
639
  riskScore: 0,
642
640
  riskFactors: [],
643
641
  exclusionImpact: "none"
644
- });
642
+ };
643
+ }
644
+ const files = [];
645
+ for (let i = 0; i < walkEntries.length; i += BATCH_SIZE) {
646
+ const batch = walkEntries.slice(i, i + BATCH_SIZE);
647
+ const results = await Promise.all(batch.map(estimateFileTokens2));
648
+ files.push(...results);
645
649
  }
646
650
  const graph = buildProjectGraph(absPath, files);
647
651
  for (const file of files) {
@@ -4983,7 +4987,8 @@ async function runTscWithContext(name, projectPath, selectedPaths, tokensUsed, t
4983
4987
  env: { ...process.env, NODE_ENV: "production" }
4984
4988
  });
4985
4989
  } catch (err) {
4986
- tscOutput = err.stdout ?? err.message ?? "";
4990
+ const e = err;
4991
+ tscOutput = e.stdout ?? (err instanceof Error ? err.message : "") ?? "";
4987
4992
  }
4988
4993
  const errorLines = tscOutput.split("\n").filter((l) => l.includes("error TS")).map((l) => l.trim());
4989
4994
  compileErrors = errorLines.length;
@@ -5267,6 +5272,83 @@ function fmt5(n) {
5267
5272
  return n.toString();
5268
5273
  }
5269
5274
 
5275
+ // src/engine/logger.ts
5276
+ var LEVEL_ORDER = { debug: 0, info: 1, warn: 2, error: 3 };
5277
+ var currentLevel = process.env.CTO_LOG_LEVEL ?? "warn";
5278
+ var jsonOutput = process.env.CTO_LOG_JSON === "1";
5279
+ function setLogLevel(level) {
5280
+ currentLevel = level;
5281
+ }
5282
+ function setJsonLogging(enabled) {
5283
+ jsonOutput = enabled;
5284
+ }
5285
+ function shouldLog(level) {
5286
+ return LEVEL_ORDER[level] >= LEVEL_ORDER[currentLevel];
5287
+ }
5288
+ function emit(entry) {
5289
+ if (!shouldLog(entry.level)) return;
5290
+ if (jsonOutput) {
5291
+ const stream = entry.level === "error" ? process.stderr : process.stdout;
5292
+ stream.write(JSON.stringify(entry) + "\n");
5293
+ return;
5294
+ }
5295
+ const prefix = entry.module ? `[${entry.module}]` : "";
5296
+ const extra = Object.entries(entry).filter(([k]) => !["level", "msg", "ts", "module"].includes(k)).map(([k, v]) => `${k}=${typeof v === "object" ? JSON.stringify(v) : v}`).join(" ");
5297
+ const line = `${prefix} ${entry.msg}${extra ? " " + extra : ""}`.trim();
5298
+ if (entry.level === "error") {
5299
+ process.stderr.write(` \u274C ${line}
5300
+ `);
5301
+ } else if (entry.level === "warn") {
5302
+ process.stderr.write(` \u26A0\uFE0F ${line}
5303
+ `);
5304
+ } else {
5305
+ process.stdout.write(` ${line}
5306
+ `);
5307
+ }
5308
+ }
5309
+ function createLogger(module) {
5310
+ const log = (level, msg, data) => {
5311
+ emit({ level, msg, ts: (/* @__PURE__ */ new Date()).toISOString(), module, ...data });
5312
+ };
5313
+ return {
5314
+ debug: (msg, data) => log("debug", msg, data),
5315
+ info: (msg, data) => log("info", msg, data),
5316
+ warn: (msg, data) => log("warn", msg, data),
5317
+ error: (msg, data) => log("error", msg, data)
5318
+ };
5319
+ }
5320
+
5321
+ // src/engine/errors.ts
5322
+ var CtoError = class extends Error {
5323
+ code;
5324
+ module;
5325
+ context;
5326
+ constructor(code, message, module, context) {
5327
+ super(message);
5328
+ this.name = "CtoError";
5329
+ this.code = code;
5330
+ this.module = module;
5331
+ this.context = context;
5332
+ }
5333
+ toJSON() {
5334
+ return {
5335
+ name: this.name,
5336
+ code: this.code,
5337
+ message: this.message,
5338
+ module: this.module,
5339
+ context: this.context
5340
+ };
5341
+ }
5342
+ };
5343
+ function isCtoError(err) {
5344
+ return err instanceof CtoError;
5345
+ }
5346
+ function wrapError(err, code, module, context) {
5347
+ if (isCtoError(err)) return err;
5348
+ const message = err instanceof Error ? err.message : String(err);
5349
+ return new CtoError(code, message, module, context);
5350
+ }
5351
+
5270
5352
  // src/engine/monorepo.ts
5271
5353
  import { readFile as readFile11, readdir as readdir4 } from "fs/promises";
5272
5354
  import { join as join10, relative as relative6, basename as basename5 } from "path";
@@ -6355,6 +6437,7 @@ function emptyResult3(baseBranch) {
6355
6437
  };
6356
6438
  }
6357
6439
  export {
6440
+ CtoError,
6358
6441
  DEFAULT_GATE_CONFIG,
6359
6442
  MODEL_REGISTRY2 as MODEL_REGISTRY,
6360
6443
  ProjectWatcher,
@@ -6372,6 +6455,7 @@ export {
6372
6455
  configureCache,
6373
6456
  countTokensChars4,
6374
6457
  countTokensTiktoken,
6458
+ createLogger,
6375
6459
  createProject,
6376
6460
  detectMonorepoTool,
6377
6461
  detectStack,
@@ -6394,6 +6478,7 @@ export {
6394
6478
  importTeamFeedback,
6395
6479
  initProjectConfig,
6396
6480
  invalidateCache,
6481
+ isCtoError,
6397
6482
  loadBaseline,
6398
6483
  loadConfig,
6399
6484
  loadFeedbackModel,
@@ -6434,10 +6519,13 @@ export {
6434
6519
  selectContext,
6435
6520
  selectPackageContext,
6436
6521
  semanticBoosts,
6522
+ setJsonLogging,
6523
+ setLogLevel,
6437
6524
  unwatchAll,
6438
6525
  unwatchProject,
6439
6526
  walkProject,
6440
6527
  watchProject,
6441
- wilsonLowerBound
6528
+ wilsonLowerBound,
6529
+ wrapError
6442
6530
  };
6443
6531
  //# sourceMappingURL=index.js.map