cto-ai-cli 1.3.0 → 3.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.
@@ -0,0 +1,816 @@
1
+ import { Project } from 'ts-morph';
2
+ import { EventEmitter } from 'node:events';
3
+
4
+ interface AnalyzedFile {
5
+ path: string;
6
+ relativePath: string;
7
+ extension: string;
8
+ size: number;
9
+ tokens: number;
10
+ lines: number;
11
+ lastModified: Date;
12
+ kind: FileKind;
13
+ imports: string[];
14
+ importedBy: string[];
15
+ isHub: boolean;
16
+ complexity: number;
17
+ riskScore: number;
18
+ riskFactors: RiskFactor[];
19
+ exclusionImpact: ExclusionImpact;
20
+ }
21
+ type FileKind = 'source' | 'type' | 'test' | 'config' | 'entry' | 'asset';
22
+ type ExclusionImpact = 'critical' | 'high' | 'medium' | 'low' | 'none';
23
+ interface ProjectAnalysis {
24
+ projectPath: string;
25
+ projectName: string;
26
+ analyzedAt: Date;
27
+ hash: string;
28
+ files: AnalyzedFile[];
29
+ totalFiles: number;
30
+ totalTokens: number;
31
+ graph: ProjectGraph;
32
+ riskProfile: RiskProfile;
33
+ stack: string[];
34
+ tokenMethod: 'chars4' | 'tiktoken';
35
+ }
36
+ interface ProjectGraph {
37
+ nodes: string[];
38
+ edges: GraphEdge[];
39
+ hubs: HubNode[];
40
+ leaves: string[];
41
+ orphans: string[];
42
+ clusters: FileCluster[];
43
+ }
44
+ interface GraphEdge {
45
+ from: string;
46
+ to: string;
47
+ type: 'import' | 'export' | 're-export';
48
+ }
49
+ interface HubNode {
50
+ relativePath: string;
51
+ dependents: number;
52
+ dependencies: number;
53
+ score: number;
54
+ }
55
+ interface FileCluster {
56
+ id: string;
57
+ name: string;
58
+ files: string[];
59
+ totalTokens: number;
60
+ internalEdges: number;
61
+ externalEdges: number;
62
+ cohesion: number;
63
+ }
64
+ interface RiskProfile {
65
+ distribution: {
66
+ critical: number;
67
+ high: number;
68
+ medium: number;
69
+ low: number;
70
+ };
71
+ topRiskFiles: AnalyzedFile[];
72
+ overallComplexity: number;
73
+ }
74
+ interface RiskFactor {
75
+ type: RiskFactorType;
76
+ score: number;
77
+ weight: number;
78
+ detail: string;
79
+ }
80
+ type RiskFactorType = 'hub' | 'type-provider' | 'complexity' | 'recency' | 'config' | 'churn';
81
+ interface RiskWeights {
82
+ hub: number;
83
+ typeProvider: number;
84
+ complexity: number;
85
+ recency: number;
86
+ config: number;
87
+ churn: number;
88
+ }
89
+ interface CoverageResult {
90
+ score: number;
91
+ relevantFiles: string[];
92
+ includedRelevant: string[];
93
+ missingRelevant: string[];
94
+ missingCritical: string[];
95
+ explanation: string;
96
+ }
97
+ interface ContextSelection {
98
+ files: SelectedFile[];
99
+ totalTokens: number;
100
+ budget: number;
101
+ usedPercent: number;
102
+ coverage: CoverageResult;
103
+ riskScore: number;
104
+ deterministic: boolean;
105
+ hash: string;
106
+ decisions: SelectionDecision[];
107
+ }
108
+ interface SelectedFile {
109
+ relativePath: string;
110
+ tokens: number;
111
+ originalTokens: number;
112
+ pruneLevel: PruneLevel;
113
+ riskScore: number;
114
+ reason: string;
115
+ }
116
+ type PruneLevel = 'full' | 'signatures' | 'skeleton' | 'excluded';
117
+ interface SelectionDecision {
118
+ file: string;
119
+ action: 'include-full' | 'include-signatures' | 'include-skeleton' | 'exclude';
120
+ reason: string;
121
+ alternatives?: string;
122
+ }
123
+ interface BudgetPlan {
124
+ budget: number;
125
+ used: number;
126
+ remaining: number;
127
+ fillPercent: number;
128
+ files: BudgetEntry[];
129
+ }
130
+ interface BudgetEntry {
131
+ relativePath: string;
132
+ originalTokens: number;
133
+ allocatedTokens: number;
134
+ pruneLevel: PruneLevel;
135
+ included: boolean;
136
+ reason: string;
137
+ }
138
+ interface PrunedContent {
139
+ relativePath: string;
140
+ originalTokens: number;
141
+ prunedTokens: number;
142
+ pruneLevel: PruneLevel;
143
+ content: string;
144
+ savingsPercent: number;
145
+ }
146
+ interface WalkEntry {
147
+ path: string;
148
+ relativePath: string;
149
+ extension: string;
150
+ size: number;
151
+ lastModified: Date;
152
+ lines: number;
153
+ }
154
+ interface WalkOptions {
155
+ ignoreDirs: string[];
156
+ ignorePatterns: string[];
157
+ extensions: string[];
158
+ maxDepth?: number;
159
+ }
160
+
161
+ interface CTOConfig {
162
+ version: string;
163
+ analysis: {
164
+ extensions: {
165
+ code: string[];
166
+ config: string[];
167
+ docs: string[];
168
+ };
169
+ ignore: {
170
+ dirs: string[];
171
+ patterns: string[];
172
+ };
173
+ maxDepth: number;
174
+ };
175
+ risk: {
176
+ weights: RiskWeights;
177
+ };
178
+ interaction: {
179
+ defaultBudget: number;
180
+ defaultModel: string;
181
+ };
182
+ tokens: {
183
+ method: 'chars4' | 'tiktoken';
184
+ };
185
+ governance: {
186
+ auditEnabled: boolean;
187
+ secretDetection: boolean;
188
+ retentionDays: number;
189
+ };
190
+ }
191
+
192
+ declare function walkProject(rootPath: string, options: WalkOptions): Promise<WalkEntry[]>;
193
+ declare function classifyFileKind(relativePath: string): FileKind;
194
+ declare function detectStack(files: WalkEntry[]): string[];
195
+ declare function analyzeProject(projectPath: string, config?: Partial<CTOConfig>): Promise<ProjectAnalysis>;
196
+
197
+ declare function createProject(projectPath: string, filePaths: string[]): Project;
198
+ declare function buildProjectGraph(projectPath: string, files: AnalyzedFile[]): ProjectGraph;
199
+
200
+ interface AdjacencyList {
201
+ forward: Map<string, string[]>;
202
+ reverse: Map<string, string[]>;
203
+ }
204
+ declare function buildAdjacencyList(edges: GraphEdge[]): AdjacencyList;
205
+ declare function bfsBidirectional(seeds: string[], adj: AdjacencyList, depth: number): Set<string>;
206
+ declare function matchGlob(path: string, pattern: string): boolean;
207
+
208
+ interface PolicySet {
209
+ version: string;
210
+ name: string;
211
+ rules: PolicyRule[];
212
+ }
213
+ interface PolicyRule {
214
+ id: string;
215
+ type: PolicyRuleType;
216
+ pattern?: string;
217
+ threshold?: number;
218
+ category?: string;
219
+ reason: string;
220
+ enabled: boolean;
221
+ }
222
+ type PolicyRuleType = 'include-always' | 'exclude-always' | 'budget-limit' | 'coverage-minimum' | 'risk-maximum' | 'secret-block';
223
+
224
+ declare function getConfigPath(projectPath: string): string;
225
+ declare function getPolicyPath(projectPath: string): string;
226
+ declare function getCTODir(projectPath: string): string;
227
+ declare function loadConfig(projectPath: string): Promise<CTOConfig>;
228
+ declare function saveConfig(projectPath: string, config: CTOConfig): Promise<string>;
229
+ declare function initProjectConfig(projectPath: string): Promise<{
230
+ configPath: string;
231
+ policyPath: string;
232
+ created: string[];
233
+ }>;
234
+ declare function loadPolicyFromYAML(projectPath: string): Promise<PolicySet | null>;
235
+
236
+ interface CacheOptions {
237
+ maxAgeMs: number;
238
+ maxEntries: number;
239
+ enabled: boolean;
240
+ }
241
+ /**
242
+ * Get a project analysis, using cache when possible.
243
+ *
244
+ * Cache hit: ~1-5ms (fingerprint check only)
245
+ * Cache miss: full analyzeProject() + cache update
246
+ */
247
+ declare function getCachedAnalysis(projectPath: string, config?: Partial<CTOConfig>): Promise<ProjectAnalysis>;
248
+ /**
249
+ * Invalidate cache for a specific project (e.g., after a known file change).
250
+ */
251
+ declare function invalidateCache(projectPath?: string): void;
252
+ /**
253
+ * Get cache statistics for debugging/monitoring.
254
+ */
255
+ declare function getCacheStats(): {
256
+ entries: number;
257
+ totalHits: number;
258
+ projects: {
259
+ path: string;
260
+ hits: number;
261
+ ageMs: number;
262
+ }[];
263
+ };
264
+ /**
265
+ * Configure cache behavior.
266
+ */
267
+ declare function configureCache(options: Partial<CacheOptions>): void;
268
+
269
+ interface WatcherOptions {
270
+ debounceMs?: number;
271
+ config?: Partial<CTOConfig>;
272
+ }
273
+ interface FileChangeEvent {
274
+ type: 'add' | 'change' | 'unlink';
275
+ path: string;
276
+ timestamp: Date;
277
+ }
278
+ declare class ProjectWatcher extends EventEmitter {
279
+ private watcher;
280
+ private projectPath;
281
+ private debounceMs;
282
+ private config;
283
+ private debounceTimer;
284
+ private pendingChanges;
285
+ private running;
286
+ constructor(projectPath: string, options?: WatcherOptions);
287
+ start(): Promise<void>;
288
+ stop(): Promise<void>;
289
+ isRunning(): boolean;
290
+ getProjectPath(): string;
291
+ private handleEvent;
292
+ private flush;
293
+ }
294
+ /**
295
+ * Start watching a project. Returns the watcher instance.
296
+ * If already watching, returns the existing watcher.
297
+ */
298
+ declare function watchProject(projectPath: string, options?: WatcherOptions): Promise<ProjectWatcher>;
299
+ /**
300
+ * Stop watching a specific project.
301
+ */
302
+ declare function unwatchProject(projectPath: string): Promise<void>;
303
+ /**
304
+ * Stop all active watchers. Call on process shutdown.
305
+ */
306
+ declare function unwatchAll(): Promise<void>;
307
+ /**
308
+ * Get all actively watched projects.
309
+ */
310
+ declare function getActiveWatchers(): {
311
+ path: string;
312
+ running: boolean;
313
+ }[];
314
+
315
+ type ChangeType = 'added' | 'modified' | 'deleted' | 'renamed';
316
+ interface ChangedFile {
317
+ relativePath: string;
318
+ changeType: ChangeType;
319
+ linesAdded: number;
320
+ linesRemoved: number;
321
+ }
322
+ interface PRContextResult {
323
+ baseBranch: string;
324
+ currentBranch: string;
325
+ isGitRepo: boolean;
326
+ changedFiles: ChangedFile[];
327
+ dependencyFiles: string[];
328
+ allRelevantFiles: AnalyzedFile[];
329
+ totalChangedTokens: number;
330
+ totalContextTokens: number;
331
+ riskSummary: {
332
+ critical: number;
333
+ high: number;
334
+ medium: number;
335
+ low: number;
336
+ maxRiskFile: string;
337
+ maxRiskScore: number;
338
+ };
339
+ renderedSummary: string;
340
+ }
341
+ interface PRContextOptions {
342
+ baseBranch?: string;
343
+ depth?: number;
344
+ includeTests?: boolean;
345
+ }
346
+ /**
347
+ * Generate PR-focused context by analyzing git changes and expanding dependencies.
348
+ *
349
+ * @param analysis - Project analysis (from analyzeProject or getCachedAnalysis)
350
+ * @param options - PR context options (baseBranch, depth, includeTests)
351
+ * @returns Structured PR context with changed files, dependencies, risk summary
352
+ */
353
+ declare function generatePRContext(analysis: ProjectAnalysis, options?: PRContextOptions): Promise<PRContextResult>;
354
+
355
+ type Grade = 'A+' | 'A' | 'A-' | 'B+' | 'B' | 'B-' | 'C+' | 'C' | 'C-' | 'D' | 'F';
356
+ interface ContextScore {
357
+ overall: number;
358
+ grade: Grade;
359
+ dimensions: {
360
+ efficiency: DimensionScore;
361
+ coverage: DimensionScore;
362
+ riskControl: DimensionScore;
363
+ structure: DimensionScore;
364
+ governance: DimensionScore;
365
+ };
366
+ insights: ScoreInsight[];
367
+ comparison: {
368
+ naiveTokens: number;
369
+ optimizedTokens: number;
370
+ savedTokens: number;
371
+ savedPercent: number;
372
+ monthlySavingsUSD: number;
373
+ };
374
+ meta: {
375
+ projectName: string;
376
+ totalFiles: number;
377
+ totalTokens: number;
378
+ analyzedAt: Date;
379
+ };
380
+ }
381
+ interface DimensionScore {
382
+ score: number;
383
+ weight: number;
384
+ weighted: number;
385
+ detail: string;
386
+ }
387
+ interface ScoreInsight {
388
+ type: 'strength' | 'weakness' | 'opportunity';
389
+ title: string;
390
+ detail: string;
391
+ impact: 'high' | 'medium' | 'low';
392
+ }
393
+ /**
394
+ * Compute the Context Score™ for a project.
395
+ *
396
+ * @param analysis - Project analysis (from analyzeProject or getCachedAnalysis)
397
+ * @param task - Representative task (default: "general code review")
398
+ * @param budget - Token budget (default: 50000)
399
+ */
400
+ declare function computeContextScore(analysis: ProjectAnalysis, task?: string, budget?: number): Promise<ContextScore>;
401
+ /**
402
+ * Render the Context Score as a beautiful terminal-friendly string.
403
+ */
404
+ declare function renderContextScore(score: ContextScore): string;
405
+
406
+ interface BenchmarkResult {
407
+ project: string;
408
+ totalFiles: number;
409
+ totalTokens: number;
410
+ budget: number;
411
+ task: string;
412
+ strategies: {
413
+ cto: StrategyResult;
414
+ naive: StrategyResult;
415
+ random: StrategyResult;
416
+ };
417
+ winner: 'cto' | 'naive' | 'random';
418
+ ctoAdvantage: {
419
+ vsNaiveTokensSaved: number;
420
+ vsNaiveTokensSavedPercent: number;
421
+ vsRandomCoverageGain: number;
422
+ vsNaiveCostSavedMonthlyUSD: number;
423
+ };
424
+ }
425
+ interface StrategyResult {
426
+ filesSelected: number;
427
+ tokensUsed: number;
428
+ coverageScore: number;
429
+ criticalFilesCovered: number;
430
+ criticalFilesTotal: number;
431
+ highRiskCovered: number;
432
+ highRiskTotal: number;
433
+ costPerInteractionUSD: number;
434
+ timeMs: number;
435
+ }
436
+ /**
437
+ * Run a full benchmark comparing CTO vs naive vs random selection.
438
+ */
439
+ declare function runBenchmark(analysis: ProjectAnalysis, task?: string, budget?: number): Promise<BenchmarkResult>;
440
+ /**
441
+ * Render benchmark results as a formatted comparison table.
442
+ */
443
+ declare function renderBenchmark(result: BenchmarkResult): string;
444
+
445
+ type TaskType = 'debug' | 'review' | 'refactor' | 'test' | 'docs' | 'feature' | 'architecture' | 'simple-edit';
446
+
447
+ interface QualityBenchmarkResult {
448
+ project: string;
449
+ task: string;
450
+ taskType: TaskType;
451
+ budget: number;
452
+ strategies: {
453
+ cto: QualityMetrics;
454
+ naive: QualityMetrics;
455
+ random: QualityMetrics;
456
+ };
457
+ comparison: {
458
+ ctoVsNaiveRelevance: number;
459
+ ctoVsRandomRelevance: number;
460
+ ctoVsNaiveCompleteness: number;
461
+ ctoVsRandomCompleteness: number;
462
+ ctoNoiseReduction: number;
463
+ };
464
+ prompts: {
465
+ cto: {
466
+ rendered: string;
467
+ tokens: number;
468
+ };
469
+ naive: {
470
+ rendered: string;
471
+ tokens: number;
472
+ };
473
+ };
474
+ verdict: string;
475
+ }
476
+ interface QualityMetrics {
477
+ filesSelected: number;
478
+ tokensUsed: number;
479
+ relevanceScore: number;
480
+ completenessScore: number;
481
+ noiseRatio: number;
482
+ typeCoverage: number;
483
+ dependencyClosure: number;
484
+ relevantFilesIncluded: number;
485
+ relevantFilesTotal: number;
486
+ typeFilesIncluded: number;
487
+ typeFilesNeeded: number;
488
+ depsIncluded: number;
489
+ depsNeeded: number;
490
+ }
491
+ /**
492
+ * Run a quality benchmark comparing CTO vs naive vs random context selection.
493
+ * Measures relevance, completeness, noise, and dependency closure.
494
+ */
495
+ declare function runQualityBenchmark(analysis: ProjectAnalysis, task: string, budget?: number): Promise<QualityBenchmarkResult>;
496
+ declare function renderQualityBenchmark(result: QualityBenchmarkResult): string;
497
+
498
+ interface PredictorModel {
499
+ version: number;
500
+ trainedAt: string;
501
+ totalObservations: number;
502
+ taskTypeFrequency: Record<string, Record<string, number>>;
503
+ keywordFrequency: Record<string, Record<string, number>>;
504
+ fileStats: Record<string, {
505
+ totalSelections: number;
506
+ avgRiskScore: number;
507
+ avgTokens: number;
508
+ lastSelected: string;
509
+ }>;
510
+ coSelection: Record<string, Record<string, number>>;
511
+ }
512
+ interface PredictionResult {
513
+ filePath: string;
514
+ predictedScore: number;
515
+ reasons: string[];
516
+ }
517
+ interface PredictorConfig {
518
+ maxCoSelectionPairs: number;
519
+ decayFactor: number;
520
+ minObservations: number;
521
+ }
522
+ declare function loadModel(projectPath: string): Promise<PredictorModel>;
523
+ declare function recordSelection(projectPath: string, task: string, selectedFiles: {
524
+ relativePath: string;
525
+ riskScore: number;
526
+ tokens: number;
527
+ }[]): Promise<PredictorModel>;
528
+ declare function predictRelevantFiles(projectPath: string, task: string, analysis: ProjectAnalysis, config?: Partial<PredictorConfig>): Promise<PredictionResult[]>;
529
+ declare function getPredictorBoosts(projectPath: string, task: string, analysis: ProjectAnalysis): Promise<Map<string, number>>;
530
+ declare function getModelStats(model: PredictorModel): {
531
+ observations: number;
532
+ taskTypes: number;
533
+ keywords: number;
534
+ trackedFiles: number;
535
+ coSelectionPairs: number;
536
+ trainedAt: string;
537
+ };
538
+
539
+ interface ProjectFingerprint {
540
+ stack: string[];
541
+ sizeClass: 'tiny' | 'small' | 'medium' | 'large' | 'huge';
542
+ hasTypes: boolean;
543
+ hasTests: boolean;
544
+ isMonorepo: boolean;
545
+ entryPointPatterns: string[];
546
+ dominantLanguage: string;
547
+ }
548
+ interface CrossRepoModel {
549
+ version: number;
550
+ updatedAt: string;
551
+ totalProjects: number;
552
+ totalObservations: number;
553
+ archetypes: Record<string, ArchetypeProfile>;
554
+ universalPatterns: PatternStats[];
555
+ }
556
+ interface ArchetypeProfile {
557
+ name: string;
558
+ fingerprint: ProjectFingerprint;
559
+ projectCount: number;
560
+ observationCount: number;
561
+ taskPatterns: Record<string, Record<string, PatternStats>>;
562
+ criticalKinds: {
563
+ kind: string;
564
+ importance: number;
565
+ }[];
566
+ criticalDirs: {
567
+ pattern: string;
568
+ importance: number;
569
+ }[];
570
+ }
571
+ interface PatternStats {
572
+ pattern: string;
573
+ hitCount: number;
574
+ totalSelections: number;
575
+ hitRate: number;
576
+ avgRelevanceBoost: number;
577
+ }
578
+ interface CrossRepoPrediction {
579
+ filePath: string;
580
+ boost: number;
581
+ reason: string;
582
+ confidence: number;
583
+ }
584
+ declare function computeFingerprint(analysis: ProjectAnalysis): ProjectFingerprint;
585
+ declare function loadGlobalModel(): Promise<CrossRepoModel>;
586
+ declare function recordCrossRepoSelection(analysis: ProjectAnalysis, task: string, selectedFiles: {
587
+ relativePath: string;
588
+ riskScore: number;
589
+ tokens: number;
590
+ }[]): Promise<CrossRepoModel>;
591
+ declare function predictFromCrossRepo(analysis: ProjectAnalysis, task: string): Promise<CrossRepoPrediction[]>;
592
+ declare function getCrossRepoStats(model: CrossRepoModel): {
593
+ totalProjects: number;
594
+ totalObservations: number;
595
+ archetypes: {
596
+ name: string;
597
+ projects: number;
598
+ observations: number;
599
+ }[];
600
+ universalPatterns: number;
601
+ };
602
+
603
+ interface FeedbackEntry {
604
+ id: string;
605
+ timestamp: string;
606
+ task: string;
607
+ taskType: TaskType;
608
+ contextHash: string;
609
+ filesIncluded: string[];
610
+ tokensUsed: number;
611
+ budget: number;
612
+ outcome: FeedbackOutcome;
613
+ model?: string;
614
+ promptTokens?: number;
615
+ }
616
+ interface FeedbackOutcome {
617
+ accepted: boolean;
618
+ compilable?: boolean;
619
+ testsPassed?: number;
620
+ testsTotal?: number;
621
+ linesGenerated?: number;
622
+ linesAccepted?: number;
623
+ timeToAcceptMs?: number;
624
+ userRating?: 1 | 2 | 3 | 4 | 5;
625
+ notes?: string;
626
+ }
627
+ interface FeedbackModel {
628
+ version: number;
629
+ updatedAt: string;
630
+ totalFeedback: number;
631
+ acceptRate: number;
632
+ fileAcceptance: Record<string, {
633
+ includedCount: number;
634
+ acceptedCount: number;
635
+ acceptRate: number;
636
+ avgTimeToAccept: number;
637
+ }>;
638
+ taskTypeAcceptance: Record<string, {
639
+ totalCount: number;
640
+ acceptedCount: number;
641
+ acceptRate: number;
642
+ avgCompilable: number;
643
+ }>;
644
+ pairAcceptance: Record<string, {
645
+ count: number;
646
+ acceptedCount: number;
647
+ acceptRate: number;
648
+ }>;
649
+ insights: FeedbackInsight[];
650
+ }
651
+ interface FeedbackInsight {
652
+ type: 'positive' | 'negative' | 'opportunity';
653
+ title: string;
654
+ detail: string;
655
+ impact: number;
656
+ }
657
+ declare function loadFeedbackModel(projectPath: string): Promise<FeedbackModel>;
658
+ declare function recordFeedback(projectPath: string, entry: Omit<FeedbackEntry, 'id' | 'timestamp' | 'taskType'>): Promise<FeedbackModel>;
659
+ declare function getFeedbackBoosts(projectPath: string, task: string): Promise<Map<string, number>>;
660
+ declare function renderFeedbackReport(model: FeedbackModel): string;
661
+
662
+ interface SemanticFingerprint {
663
+ filePath: string;
664
+ domains: SemanticDomain[];
665
+ exports: string[];
666
+ concepts: string[];
667
+ patterns: CodePattern[];
668
+ intentScore: Map<string, number>;
669
+ }
670
+ interface SemanticDomain {
671
+ name: string;
672
+ confidence: number;
673
+ signals: string[];
674
+ }
675
+ interface CodePattern {
676
+ type: 'route' | 'model' | 'middleware' | 'config' | 'test' | 'type' | 'util' | 'entry' | 'event' | 'error';
677
+ evidence: string;
678
+ }
679
+ interface SemanticAnalysis {
680
+ files: SemanticFingerprint[];
681
+ domainGraph: {
682
+ from: string;
683
+ to: string;
684
+ strength: number;
685
+ }[];
686
+ domainClusters: {
687
+ domain: string;
688
+ files: string[];
689
+ tokenBudget: number;
690
+ }[];
691
+ }
692
+ declare function analyzeSemantics(analysis: ProjectAnalysis): SemanticAnalysis;
693
+ declare function semanticBoosts(semantics: SemanticAnalysis, task: string): Map<string, number>;
694
+ declare function renderSemanticAnalysis(semantics: SemanticAnalysis): string;
695
+
696
+ interface CompilabilityResult {
697
+ project: string;
698
+ task: string;
699
+ budget: number;
700
+ strategies: {
701
+ cto: CompilabilityMetrics;
702
+ naive: CompilabilityMetrics;
703
+ random: CompilabilityMetrics;
704
+ };
705
+ comparison: {
706
+ ctoVsNaiveTypeAvailability: number;
707
+ ctoVsRandomTypeAvailability: number;
708
+ ctoVsNaivePredictedErrors: number;
709
+ naiveMissingTypes: string[];
710
+ randomMissingTypes: string[];
711
+ };
712
+ verdict: string;
713
+ }
714
+ interface CompilabilityMetrics {
715
+ typeFilesAvailable: number;
716
+ typeFilesTotal: number;
717
+ typeAvailabilityPercent: number;
718
+ importChainsComplete: number;
719
+ importChainsTotal: number;
720
+ importCompletenessPercent: number;
721
+ missingTypeFiles: string[];
722
+ missingDependencies: string[];
723
+ predictedTypeErrors: number;
724
+ predictedImportErrors: number;
725
+ predictedTotalErrors: number;
726
+ compilabilityScore: number;
727
+ filesSelected: number;
728
+ tokensUsed: number;
729
+ }
730
+ declare function runCompilabilityBenchmark(analysis: ProjectAnalysis, task: string, budget?: number): Promise<CompilabilityResult>;
731
+ declare function renderCompilabilityBenchmark(result: CompilabilityResult): string;
732
+
733
+ interface CompileProofResult {
734
+ project: string;
735
+ task: string;
736
+ budget: number;
737
+ cto: CompileProofStrategy;
738
+ naive: CompileProofStrategy;
739
+ random: CompileProofStrategy;
740
+ headline: string;
741
+ details: string;
742
+ }
743
+ interface CompileProofStrategy {
744
+ name: string;
745
+ filesIncluded: number;
746
+ tokensUsed: number;
747
+ typeFilesIncluded: string[];
748
+ typeFilesMissing: string[];
749
+ compileErrors: number;
750
+ errorMessages: string[];
751
+ compiles: boolean;
752
+ }
753
+ declare function runCompileProof(analysis: ProjectAnalysis, task: string, budget?: number): Promise<CompileProofResult>;
754
+ declare function renderCompileProof(result: CompileProofResult): string;
755
+
756
+ interface ModelProfile {
757
+ id: string;
758
+ name: string;
759
+ provider: 'openai' | 'anthropic' | 'google' | 'mistral' | 'meta' | 'custom';
760
+ contextWindow: number;
761
+ maxOutput: number;
762
+ costPer1MInput: number;
763
+ costPer1MOutput: number;
764
+ strengths: ModelStrength[];
765
+ recommendedBudgetPercent: number;
766
+ }
767
+ type ModelStrength = 'code-generation' | 'analysis' | 'refactoring' | 'debugging' | 'documentation' | 'testing' | 'general';
768
+ interface MultiModelResult {
769
+ task: string;
770
+ models: ModelOptimization[];
771
+ recommendation: {
772
+ bestValue: string;
773
+ bestQuality: string;
774
+ bestSpeed: string;
775
+ reasoning: string;
776
+ };
777
+ }
778
+ interface ModelOptimization {
779
+ model: ModelProfile;
780
+ budget: number;
781
+ selection: ContextSelection;
782
+ estimatedCost: number;
783
+ qualityScore: number;
784
+ recommendation: string;
785
+ }
786
+ declare const MODEL_REGISTRY: ModelProfile[];
787
+ declare function optimizeForModels(analysis: ProjectAnalysis, task: string, models?: string[]): Promise<MultiModelResult>;
788
+ declare function renderMultiModelResult(result: MultiModelResult): string;
789
+
790
+ declare function scoreAllFiles(files: AnalyzedFile[], graph: ProjectGraph, weights?: RiskWeights): void;
791
+ declare function scoreFile(file: AnalyzedFile, graph: ProjectGraph, weights?: RiskWeights): number;
792
+
793
+ declare function calculateCoverage(targetPaths: string[], includedPaths: string[], allFiles: AnalyzedFile[], graph: ProjectGraph, depth?: number): CoverageResult;
794
+
795
+ interface SelectionInput {
796
+ task: string;
797
+ analysis: ProjectAnalysis;
798
+ budget: number;
799
+ policies?: PolicySet;
800
+ depth?: number;
801
+ }
802
+ declare function selectContext(input: SelectionInput): Promise<ContextSelection>;
803
+
804
+ declare function getPruneLevelForRisk(riskScore: number): PruneLevel;
805
+ declare function optimizeBudget(files: AnalyzedFile[], budget: number): Promise<BudgetPlan>;
806
+
807
+ declare function pruneFile(file: AnalyzedFile, level: PruneLevel): Promise<PrunedContent>;
808
+ declare function pruneFiles(files: AnalyzedFile[], levelFn: (file: AnalyzedFile) => PruneLevel): Promise<PrunedContent[]>;
809
+
810
+ declare function countTokensTiktoken(text: string): number;
811
+ declare function countTokensChars4(sizeInBytes: number): number;
812
+ declare function estimateTokens(content: string, sizeInBytes: number, method?: 'chars4' | 'tiktoken'): number;
813
+ declare function estimateFileTokens(filePath: string, method?: 'chars4' | 'tiktoken'): Promise<number>;
814
+ declare function freeEncoder(): void;
815
+
816
+ export { type BenchmarkResult, type ChangeType, type ChangedFile, type CompilabilityMetrics, type CompilabilityResult, type CompileProofResult, type CompileProofStrategy, type ContextScore, type CrossRepoModel, type CrossRepoPrediction, type DimensionScore, type FeedbackEntry, type FeedbackInsight, type FeedbackModel, type FeedbackOutcome, type FileChangeEvent, type Grade, MODEL_REGISTRY, type ModelOptimization, type ModelProfile, type MultiModelResult, type PRContextOptions, type PRContextResult, type PredictionResult, type PredictorModel, type ProjectFingerprint, ProjectWatcher, type QualityBenchmarkResult, type QualityMetrics, type ScoreInsight, type SelectionInput, type SemanticAnalysis, type SemanticDomain, type SemanticFingerprint, type StrategyResult, type WatcherOptions, analyzeProject, analyzeSemantics, bfsBidirectional, buildAdjacencyList, buildProjectGraph, calculateCoverage, classifyFileKind, computeContextScore, computeFingerprint, configureCache, countTokensChars4, countTokensTiktoken, createProject, detectStack, estimateFileTokens, estimateTokens, freeEncoder, generatePRContext, getActiveWatchers, getCTODir, getCacheStats, getCachedAnalysis, getConfigPath, getCrossRepoStats, getFeedbackBoosts, getModelStats, getPolicyPath, getPredictorBoosts, getPruneLevelForRisk, initProjectConfig, invalidateCache, loadConfig, loadFeedbackModel, loadGlobalModel, loadModel, loadPolicyFromYAML, matchGlob, optimizeBudget, optimizeForModels, predictFromCrossRepo, predictRelevantFiles, pruneFile, pruneFiles, recordCrossRepoSelection, recordFeedback, recordSelection, renderBenchmark, renderCompilabilityBenchmark, renderCompileProof, renderContextScore, renderFeedbackReport, renderMultiModelResult, renderQualityBenchmark, renderSemanticAnalysis, runBenchmark, runCompilabilityBenchmark, runCompileProof, runQualityBenchmark, saveConfig, scoreAllFiles, scoreFile, selectContext, semanticBoosts, unwatchAll, unwatchProject, walkProject, watchProject };