@aiready/core 0.9.27 → 0.9.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.mts CHANGED
@@ -10,7 +10,7 @@ interface Issue {
10
10
  location: Location;
11
11
  suggestion?: string;
12
12
  }
13
- type IssueType = 'duplicate-pattern' | 'context-fragmentation' | 'doc-drift' | 'naming-inconsistency' | 'naming-quality' | 'pattern-inconsistency' | 'architecture-inconsistency' | 'dead-code' | 'circular-dependency' | 'missing-types';
13
+ type IssueType = 'duplicate-pattern' | 'context-fragmentation' | 'doc-drift' | 'dependency-health' | 'naming-inconsistency' | 'naming-quality' | 'pattern-inconsistency' | 'architecture-inconsistency' | 'dead-code' | 'circular-dependency' | 'missing-types' | 'hallucination-risk' | 'low-testability' | 'agent-navigation-failure' | 'ambiguous-api' | 'magic-literal' | 'boolean-trap';
14
14
  interface Location {
15
15
  file: string;
16
16
  line: number;
@@ -26,6 +26,18 @@ interface Metrics {
26
26
  estimatedMonthlyCost?: number;
27
27
  estimatedDeveloperHours?: number;
28
28
  comprehensionDifficultyIndex?: number;
29
+ /** Probability (0-100) that AI will hallucinate in this file/module */
30
+ hallucinationRiskScore?: number;
31
+ /** How well an agent can navigate to/from this file unaided (0-100) */
32
+ agentGroundingScore?: number;
33
+ /** Whether AI-generated changes to this file can be safely verified (0-100) */
34
+ testabilityScore?: number;
35
+ /** Level of documentation drift vs code reality (0-100, higher = more drift) */
36
+ docDriftScore?: number;
37
+ /** Health of dependencies in relation to AI training knowledge (0-100) */
38
+ dependencyHealthScore?: number;
39
+ /** Model context tier this analysis was calibrated for */
40
+ modelContextTier?: 'compact' | 'standard' | 'extended' | 'frontier';
29
41
  }
30
42
  /**
31
43
  * Cost estimation configuration
@@ -478,12 +490,63 @@ interface ScoringConfig {
478
490
  /**
479
491
  * Default weights for known tools.
480
492
  * New tools get weight of 10 if not specified.
493
+ *
494
+ * Weight philosophy:
495
+ * - pattern-detect (40): Semantic duplication directly wastes token budget and
496
+ * confuses AI with contradictory in-context examples.
497
+ * - context-analyzer (35): Context limits are the primary hard constraint on
498
+ * AI effectiveness regardless of model size.
499
+ * - consistency (25): Naming/pattern inconsistency degrades AI intent understanding
500
+ * proportionally to codebase size.
501
+ * - hallucination-risk (20): Code patterns empirically causing AI to generate
502
+ * confidently wrong outputs — critical for agentic use cases.
503
+ * - agent-grounding (18): How well an autonomous agent can navigate unaided —
504
+ * increasingly important as agentic workflows grow.
505
+ * - testability (18): AI changes without verifiability create hidden risk.
506
+ * - doc-drift (15): Stale docs actively mislead AI; planned spoke.
507
+ * - deps (12): Dependency health affects AI suggestion accuracy; planned spoke.
481
508
  */
482
509
  declare const DEFAULT_TOOL_WEIGHTS: Record<string, number>;
483
510
  /**
484
511
  * Tool name normalization map (shorthand -> full name)
485
512
  */
486
513
  declare const TOOL_NAME_MAP: Record<string, string>;
514
+ /**
515
+ * Model context tiers for context-aware threshold calibration.
516
+ *
517
+ * As AI models evolve from 32k → 128k → 1M+ context windows, absolute token
518
+ * thresholds become meaningless. Use these tiers to adjust context-analyzer
519
+ * thresholds relative to the model your team uses.
520
+ */
521
+ type ModelContextTier = 'compact' | 'standard' | 'extended' | 'frontier';
522
+ /**
523
+ * Context budget thresholds per tier.
524
+ * Scores are interpolated between these boundaries.
525
+ */
526
+ declare const CONTEXT_TIER_THRESHOLDS: Record<ModelContextTier, {
527
+ /** Below this → full score for context budget */
528
+ idealTokens: number;
529
+ /** Above this → critical penalty for context budget */
530
+ criticalTokens: number;
531
+ /** Suggested max import depth before penalty */
532
+ idealDepth: number;
533
+ }>;
534
+ /**
535
+ * Project-size-adjusted minimum thresholds.
536
+ *
537
+ * Large codebases structurally accrue more issues. A score of 65 in an
538
+ * enterprise codebase is roughly equivalent to 75 in a small project.
539
+ * These are recommended minimum passing thresholds by project size.
540
+ */
541
+ declare const SIZE_ADJUSTED_THRESHOLDS: Record<string, number>;
542
+ /**
543
+ * Determine project size tier from file count
544
+ */
545
+ declare function getProjectSizeTier(fileCount: number): keyof typeof SIZE_ADJUSTED_THRESHOLDS;
546
+ /**
547
+ * Get the recommended minimum threshold for a project
548
+ */
549
+ declare function getRecommendedThreshold(fileCount: number, modelTier?: ModelContextTier): number;
487
550
  /**
488
551
  * Normalize tool name from shorthand to full name
489
552
  */
@@ -515,6 +578,11 @@ declare function calculateOverallScore(toolOutputs: Map<string, ToolScoringOutpu
515
578
  * Convert numeric score to rating category
516
579
  */
517
580
  declare function getRating(score: number): ScoringResult['rating'];
581
+ /**
582
+ * Convert score to rating with project-size awareness.
583
+ * Use this for display to give fairer assessment to large codebases.
584
+ */
585
+ declare function getRatingWithContext(score: number, fileCount: number, modelTier?: ModelContextTier): ScoringResult['rating'];
518
586
  /**
519
587
  * Get rating emoji and color for display
520
588
  */
@@ -544,4 +612,4 @@ declare function formatToolScore(output: ToolScoringOutput): string;
544
612
  */
545
613
  declare function generateHTML(graph: GraphData): string;
546
614
 
547
- export { type AIReadyConfig, type AcceptancePrediction, type AnalysisResult, type BusinessReport, type CommonASTNode, type ComprehensionDifficulty, type CostConfig, DEFAULT_TOOL_WEIGHTS, type ExportInfo, type GraphData, type GraphEdge, type GraphIssueSeverity, type GraphMetadata, type GraphNode, type ImportInfo, type Issue, type IssueType, LANGUAGE_EXTENSIONS, Language, type LanguageConfig, type LanguageParser, type Location, type Metrics, type NamingConvention, ParseError, type ParseResult, type ParseStatistics, type ProductivityImpact, type Report, type ScanOptions, type ScoringConfig, type ScoringResult, type SourceLocation, type SourceRange, TOOL_NAME_MAP, type ToolScoringOutput, calculateOverallScore, formatScore, formatToolScore, generateHTML, getRating, getRatingDisplay, getToolWeight, normalizeToolName, parseWeightString };
615
+ export { type AIReadyConfig, type AcceptancePrediction, type AnalysisResult, type BusinessReport, CONTEXT_TIER_THRESHOLDS, type CommonASTNode, type ComprehensionDifficulty, type CostConfig, DEFAULT_TOOL_WEIGHTS, type ExportInfo, type GraphData, type GraphEdge, type GraphIssueSeverity, type GraphMetadata, type GraphNode, type ImportInfo, type Issue, type IssueType, LANGUAGE_EXTENSIONS, Language, type LanguageConfig, type LanguageParser, type Location, type Metrics, type ModelContextTier, type NamingConvention, ParseError, type ParseResult, type ParseStatistics, type ProductivityImpact, type Report, SIZE_ADJUSTED_THRESHOLDS, type ScanOptions, type ScoringConfig, type ScoringResult, type SourceLocation, type SourceRange, TOOL_NAME_MAP, type ToolScoringOutput, calculateOverallScore, formatScore, formatToolScore, generateHTML, getProjectSizeTier, getRating, getRatingDisplay, getRatingWithContext, getRecommendedThreshold, getToolWeight, normalizeToolName, parseWeightString };
package/dist/client.d.ts CHANGED
@@ -10,7 +10,7 @@ interface Issue {
10
10
  location: Location;
11
11
  suggestion?: string;
12
12
  }
13
- type IssueType = 'duplicate-pattern' | 'context-fragmentation' | 'doc-drift' | 'naming-inconsistency' | 'naming-quality' | 'pattern-inconsistency' | 'architecture-inconsistency' | 'dead-code' | 'circular-dependency' | 'missing-types';
13
+ type IssueType = 'duplicate-pattern' | 'context-fragmentation' | 'doc-drift' | 'dependency-health' | 'naming-inconsistency' | 'naming-quality' | 'pattern-inconsistency' | 'architecture-inconsistency' | 'dead-code' | 'circular-dependency' | 'missing-types' | 'hallucination-risk' | 'low-testability' | 'agent-navigation-failure' | 'ambiguous-api' | 'magic-literal' | 'boolean-trap';
14
14
  interface Location {
15
15
  file: string;
16
16
  line: number;
@@ -26,6 +26,18 @@ interface Metrics {
26
26
  estimatedMonthlyCost?: number;
27
27
  estimatedDeveloperHours?: number;
28
28
  comprehensionDifficultyIndex?: number;
29
+ /** Probability (0-100) that AI will hallucinate in this file/module */
30
+ hallucinationRiskScore?: number;
31
+ /** How well an agent can navigate to/from this file unaided (0-100) */
32
+ agentGroundingScore?: number;
33
+ /** Whether AI-generated changes to this file can be safely verified (0-100) */
34
+ testabilityScore?: number;
35
+ /** Level of documentation drift vs code reality (0-100, higher = more drift) */
36
+ docDriftScore?: number;
37
+ /** Health of dependencies in relation to AI training knowledge (0-100) */
38
+ dependencyHealthScore?: number;
39
+ /** Model context tier this analysis was calibrated for */
40
+ modelContextTier?: 'compact' | 'standard' | 'extended' | 'frontier';
29
41
  }
30
42
  /**
31
43
  * Cost estimation configuration
@@ -478,12 +490,63 @@ interface ScoringConfig {
478
490
  /**
479
491
  * Default weights for known tools.
480
492
  * New tools get weight of 10 if not specified.
493
+ *
494
+ * Weight philosophy:
495
+ * - pattern-detect (40): Semantic duplication directly wastes token budget and
496
+ * confuses AI with contradictory in-context examples.
497
+ * - context-analyzer (35): Context limits are the primary hard constraint on
498
+ * AI effectiveness regardless of model size.
499
+ * - consistency (25): Naming/pattern inconsistency degrades AI intent understanding
500
+ * proportionally to codebase size.
501
+ * - hallucination-risk (20): Code patterns empirically causing AI to generate
502
+ * confidently wrong outputs — critical for agentic use cases.
503
+ * - agent-grounding (18): How well an autonomous agent can navigate unaided —
504
+ * increasingly important as agentic workflows grow.
505
+ * - testability (18): AI changes without verifiability create hidden risk.
506
+ * - doc-drift (15): Stale docs actively mislead AI; planned spoke.
507
+ * - deps (12): Dependency health affects AI suggestion accuracy; planned spoke.
481
508
  */
482
509
  declare const DEFAULT_TOOL_WEIGHTS: Record<string, number>;
483
510
  /**
484
511
  * Tool name normalization map (shorthand -> full name)
485
512
  */
486
513
  declare const TOOL_NAME_MAP: Record<string, string>;
514
+ /**
515
+ * Model context tiers for context-aware threshold calibration.
516
+ *
517
+ * As AI models evolve from 32k → 128k → 1M+ context windows, absolute token
518
+ * thresholds become meaningless. Use these tiers to adjust context-analyzer
519
+ * thresholds relative to the model your team uses.
520
+ */
521
+ type ModelContextTier = 'compact' | 'standard' | 'extended' | 'frontier';
522
+ /**
523
+ * Context budget thresholds per tier.
524
+ * Scores are interpolated between these boundaries.
525
+ */
526
+ declare const CONTEXT_TIER_THRESHOLDS: Record<ModelContextTier, {
527
+ /** Below this → full score for context budget */
528
+ idealTokens: number;
529
+ /** Above this → critical penalty for context budget */
530
+ criticalTokens: number;
531
+ /** Suggested max import depth before penalty */
532
+ idealDepth: number;
533
+ }>;
534
+ /**
535
+ * Project-size-adjusted minimum thresholds.
536
+ *
537
+ * Large codebases structurally accrue more issues. A score of 65 in an
538
+ * enterprise codebase is roughly equivalent to 75 in a small project.
539
+ * These are recommended minimum passing thresholds by project size.
540
+ */
541
+ declare const SIZE_ADJUSTED_THRESHOLDS: Record<string, number>;
542
+ /**
543
+ * Determine project size tier from file count
544
+ */
545
+ declare function getProjectSizeTier(fileCount: number): keyof typeof SIZE_ADJUSTED_THRESHOLDS;
546
+ /**
547
+ * Get the recommended minimum threshold for a project
548
+ */
549
+ declare function getRecommendedThreshold(fileCount: number, modelTier?: ModelContextTier): number;
487
550
  /**
488
551
  * Normalize tool name from shorthand to full name
489
552
  */
@@ -515,6 +578,11 @@ declare function calculateOverallScore(toolOutputs: Map<string, ToolScoringOutpu
515
578
  * Convert numeric score to rating category
516
579
  */
517
580
  declare function getRating(score: number): ScoringResult['rating'];
581
+ /**
582
+ * Convert score to rating with project-size awareness.
583
+ * Use this for display to give fairer assessment to large codebases.
584
+ */
585
+ declare function getRatingWithContext(score: number, fileCount: number, modelTier?: ModelContextTier): ScoringResult['rating'];
518
586
  /**
519
587
  * Get rating emoji and color for display
520
588
  */
@@ -544,4 +612,4 @@ declare function formatToolScore(output: ToolScoringOutput): string;
544
612
  */
545
613
  declare function generateHTML(graph: GraphData): string;
546
614
 
547
- export { type AIReadyConfig, type AcceptancePrediction, type AnalysisResult, type BusinessReport, type CommonASTNode, type ComprehensionDifficulty, type CostConfig, DEFAULT_TOOL_WEIGHTS, type ExportInfo, type GraphData, type GraphEdge, type GraphIssueSeverity, type GraphMetadata, type GraphNode, type ImportInfo, type Issue, type IssueType, LANGUAGE_EXTENSIONS, Language, type LanguageConfig, type LanguageParser, type Location, type Metrics, type NamingConvention, ParseError, type ParseResult, type ParseStatistics, type ProductivityImpact, type Report, type ScanOptions, type ScoringConfig, type ScoringResult, type SourceLocation, type SourceRange, TOOL_NAME_MAP, type ToolScoringOutput, calculateOverallScore, formatScore, formatToolScore, generateHTML, getRating, getRatingDisplay, getToolWeight, normalizeToolName, parseWeightString };
615
+ export { type AIReadyConfig, type AcceptancePrediction, type AnalysisResult, type BusinessReport, CONTEXT_TIER_THRESHOLDS, type CommonASTNode, type ComprehensionDifficulty, type CostConfig, DEFAULT_TOOL_WEIGHTS, type ExportInfo, type GraphData, type GraphEdge, type GraphIssueSeverity, type GraphMetadata, type GraphNode, type ImportInfo, type Issue, type IssueType, LANGUAGE_EXTENSIONS, Language, type LanguageConfig, type LanguageParser, type Location, type Metrics, type ModelContextTier, type NamingConvention, ParseError, type ParseResult, type ParseStatistics, type ProductivityImpact, type Report, SIZE_ADJUSTED_THRESHOLDS, type ScanOptions, type ScoringConfig, type ScoringResult, type SourceLocation, type SourceRange, TOOL_NAME_MAP, type ToolScoringOutput, calculateOverallScore, formatScore, formatToolScore, generateHTML, getProjectSizeTier, getRating, getRatingDisplay, getRatingWithContext, getRecommendedThreshold, getToolWeight, normalizeToolName, parseWeightString };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { ScanOptions, AIReadyConfig, CostConfig, ComprehensionDifficulty, ProductivityImpact, ToolScoringOutput, AcceptancePrediction, LanguageParser, Language, ParseResult, NamingConvention } from './client.mjs';
2
- export { AnalysisResult, BusinessReport, CommonASTNode, DEFAULT_TOOL_WEIGHTS, ExportInfo, GraphData, GraphEdge, GraphIssueSeverity, GraphMetadata, GraphNode, ImportInfo, Issue, IssueType, LANGUAGE_EXTENSIONS, LanguageConfig, Location, Metrics, ParseError, ParseStatistics, Report, ScoringConfig, ScoringResult, SourceLocation, SourceRange, TOOL_NAME_MAP, calculateOverallScore, formatScore, formatToolScore, generateHTML, getRating, getRatingDisplay, getToolWeight, normalizeToolName, parseWeightString } from './client.mjs';
1
+ import { ScanOptions, AIReadyConfig, CostConfig, ModelContextTier, ComprehensionDifficulty, ProductivityImpact, ToolScoringOutput, AcceptancePrediction, LanguageParser, Language, ParseResult, NamingConvention } from './client.mjs';
2
+ export { AnalysisResult, BusinessReport, CONTEXT_TIER_THRESHOLDS, CommonASTNode, DEFAULT_TOOL_WEIGHTS, ExportInfo, GraphData, GraphEdge, GraphIssueSeverity, GraphMetadata, GraphNode, ImportInfo, Issue, IssueType, LANGUAGE_EXTENSIONS, LanguageConfig, Location, Metrics, ParseError, ParseStatistics, Report, SIZE_ADJUSTED_THRESHOLDS, ScoringConfig, ScoringResult, SourceLocation, SourceRange, TOOL_NAME_MAP, calculateOverallScore, formatScore, formatToolScore, generateHTML, getProjectSizeTier, getRating, getRatingDisplay, getRatingWithContext, getRecommendedThreshold, getToolWeight, normalizeToolName, parseWeightString } from './client.mjs';
3
3
 
4
4
  declare const DEFAULT_EXCLUDE: string[];
5
5
  /**
@@ -120,8 +120,28 @@ declare function getElapsedTime(startTime: number): string;
120
120
  *
121
121
  * NEW in v0.11: Extended with temporal tracking, knowledge concentration, and
122
122
  * technical debt interest calculations.
123
+ * NEW in v0.12: Multi-model pricing presets, model-aware CDI calibration,
124
+ * and improved acceptance rate prediction with data-grounded baselines.
123
125
  */
124
126
 
127
+ /**
128
+ * AI model pricing presets for cost estimation.
129
+ * Prices are input token costs per 1K tokens (USD), as of Q1 2026.
130
+ * Update these as model pricing evolves — the calculation logic is unchanged.
131
+ */
132
+ interface ModelPricingPreset {
133
+ name: string;
134
+ pricePer1KInputTokens: number;
135
+ pricePer1KOutputTokens: number;
136
+ contextTier: ModelContextTier;
137
+ /** Approximate daily queries per active dev for this model class */
138
+ typicalQueriesPerDevPerDay: number;
139
+ }
140
+ declare const MODEL_PRICING_PRESETS: Record<string, ModelPricingPreset>;
141
+ /**
142
+ * Get a model pricing preset by ID, with fallback to gpt-4o
143
+ */
144
+ declare function getModelPreset(modelId: string): ModelPricingPreset;
125
145
  /**
126
146
  * Historical score entry for trend tracking
127
147
  */
@@ -203,7 +223,8 @@ interface DebtBreakdown {
203
223
  }
204
224
  /**
205
225
  * Default cost configuration
206
- * Based on GPT-4 pricing and typical team usage
226
+ * Points to GPT-4o as the default model (most common in 2026).
227
+ * Use MODEL_PRICING_PRESETS for model-specific accuracy.
207
228
  */
208
229
  declare const DEFAULT_COST_CONFIG: CostConfig;
209
230
  /**
@@ -221,10 +242,16 @@ declare function calculateProductivityImpact(issues: {
221
242
  /**
222
243
  * Predict AI suggestion acceptance rate based on code quality
223
244
  *
224
- * Research shows:
225
- * - High consistency correlates with 30%+ higher acceptance
226
- * - Low context budget improves understanding by ~40%
227
- * - Good naming patterns reduce clarification needs by 50%
245
+ * Calibration notes (v0.12):
246
+ * - GitHub Copilot reports ~30% industry average acceptance rate (2023 blog)
247
+ * - Internal teams with high-consistency codebases report 40-55%
248
+ * - Teams with semantic duplication report 20-25% (AI suggests wrong variant)
249
+ * - Context efficiency is the strongest single predictor
250
+ *
251
+ * Confidence levels:
252
+ * - 3 tools: 0.75 (triangulated estimate)
253
+ * - 2 tools: 0.55 (partial estimate)
254
+ * - 1 tool: 0.35 (weak estimate — don't over-rely)
228
255
  */
229
256
  declare function predictAcceptanceRate(toolOutputs: Map<string, ToolScoringOutput>): AcceptancePrediction;
230
257
  /**
@@ -232,8 +259,12 @@ declare function predictAcceptanceRate(toolOutputs: Map<string, ToolScoringOutpu
232
259
  *
233
260
  * A future-proof abstraction that normalizes multiple factors
234
261
  * into a single difficulty score. Lower = easier for AI.
262
+ *
263
+ * v0.12+: Now model-aware. Pass the `modelTier` of your AI toolchain
264
+ * to recalibrate token budget thresholds correctly. With frontier models
265
+ * (200k+ context), a 20k-token file is no longer "critical".
235
266
  */
236
- declare function calculateComprehensionDifficulty(contextBudget: number, importDepth: number, fragmentation: number, consistencyScore: number, totalFiles: number): ComprehensionDifficulty;
267
+ declare function calculateComprehensionDifficulty(contextBudget: number, importDepth: number, fragmentation: number, consistencyScore: number, totalFiles: number, modelTier?: ModelContextTier): ComprehensionDifficulty;
237
268
  /**
238
269
  * Format cost for display
239
270
  */
@@ -426,6 +457,11 @@ declare class PythonParser implements LanguageParser {
426
457
  * - Semantic Distance: How far apart related concepts are
427
458
  * - Concept Cohesion: How well grouped related ideas are
428
459
  * - Pattern Entropy: How ordered vs chaotic the structure is
460
+ * - Hallucination Risk: How likely AI is to generate incorrect code
461
+ * - Agent Grounding Score: How well an agent can navigate unaided
462
+ * - Testability Index: How verifiable AI-generated changes are
463
+ *
464
+ * v0.12+: Added hallucination risk, agent grounding, and testability dimensions.
429
465
  */
430
466
 
431
467
  /**
@@ -517,6 +553,221 @@ declare function calculateFutureProofScore(params: {
517
553
  conceptCohesion: ConceptCohesion;
518
554
  semanticDistances?: SemanticDistance[];
519
555
  }): ToolScoringOutput;
556
+ /**
557
+ * Signals that increase the likelihood of AI generating incorrect code.
558
+ * Technology-agnostic: these patterns confuse both current and future AI.
559
+ */
560
+ interface HallucinationRiskSignal {
561
+ name: string;
562
+ count: number;
563
+ riskContribution: number;
564
+ description: string;
565
+ examples?: string[];
566
+ }
567
+ /**
568
+ * Hallucination Risk Score (0-100, higher = more risk)
569
+ *
570
+ * Measures code patterns that empirically cause AI models to:
571
+ * - Confidently generate incorrect function signatures
572
+ * - Create plausible-but-wrong implementations
573
+ * - Miss implicit contracts / side effects
574
+ * - Misunderstand overloaded symbols
575
+ */
576
+ interface HallucinationRisk {
577
+ /** Overall risk score (0-100). Higher = more likely AI will hallucinate. */
578
+ score: number;
579
+ rating: 'minimal' | 'low' | 'moderate' | 'high' | 'severe';
580
+ signals: HallucinationRiskSignal[];
581
+ /** Most impactful signal to fix first */
582
+ topRisk: string;
583
+ recommendations: string[];
584
+ }
585
+ /**
586
+ * Calculate hallucination risk from code analysis results
587
+ *
588
+ * Input data can come from any parser; all inputs are normalized 0-N counts.
589
+ */
590
+ declare function calculateHallucinationRisk(params: {
591
+ /** Overloaded function names (same name, different signatures) */
592
+ overloadedSymbols: number;
593
+ /** Magic numbers and string literals without named constants */
594
+ magicLiterals: number;
595
+ /** Boolean trap parameters (function(true, false, null)) */
596
+ booleanTraps: number;
597
+ /** Implicit returns / void-implicit side effect functions */
598
+ implicitSideEffects: number;
599
+ /** Callback nesting depth > 3 (callback hell indicator) */
600
+ deepCallbacks: number;
601
+ /** Non-descriptive names: single letters, x1/x2 patterns, tmp/data/obj */
602
+ ambiguousNames: number;
603
+ /** Exported symbols with no JSDoc/docstring */
604
+ undocumentedExports: number;
605
+ /** Total symbols analyzed (for normalization) */
606
+ totalSymbols: number;
607
+ /** Total exports in codebase */
608
+ totalExports: number;
609
+ }): HallucinationRisk;
610
+ /**
611
+ * Agent Grounding Score
612
+ *
613
+ * Measures how well an AI agent can navigate a codebase *independently*,
614
+ * without human assistance or extensive prompting.
615
+ *
616
+ * High grounding = agent can find files, understand project structure,
617
+ * locate relevant code, and correctly infer ownership without being told.
618
+ *
619
+ * This is technology-agnostic: any agentic system (current or future)
620
+ * needs these structural guarantees to work effectively.
621
+ */
622
+ interface AgentGroundingScore {
623
+ /** 0-100 score; higher = better self-navigation */
624
+ score: number;
625
+ rating: 'excellent' | 'good' | 'moderate' | 'poor' | 'disorienting';
626
+ dimensions: {
627
+ /** Can agent find where to put new code? (directory structure clarity) */
628
+ structureClarityScore: number;
629
+ /** Can agent understand what a file does from its name alone? */
630
+ selfDocumentationScore: number;
631
+ /** Are entry points (index, main, README) present and accurate? */
632
+ entryPointScore: number;
633
+ /** Does the public API surface reflect the project's mental model? */
634
+ apiClarityScore: number;
635
+ /** Is the domain language consistent? (Same concept = same word everywhere) */
636
+ domainConsistencyScore: number;
637
+ };
638
+ recommendations: string[];
639
+ }
640
+ /**
641
+ * Calculate how well an AI agent can ground itself in the codebase
642
+ */
643
+ declare function calculateAgentGrounding(params: {
644
+ /** Number of directories exceeding recommended depth (> 4 levels) */
645
+ deepDirectories: number;
646
+ /** Total directories */
647
+ totalDirectories: number;
648
+ /** Files whose name alone doesn't reveal purpose (e.g., utils.ts, helpers.ts, misc.ts) */
649
+ vagueFileNames: number;
650
+ /** Total files */
651
+ totalFiles: number;
652
+ /** Whether a root README exists */
653
+ hasRootReadme: boolean;
654
+ /** Whether README has been updated in last 90 days (or unknown) */
655
+ readmeIsFresh: boolean;
656
+ /** Number of barrel exports (index.ts/index.js files that re-export) */
657
+ barrelExports: number;
658
+ /** Number of exported functions/classes/types with no type annotations */
659
+ untypedExports: number;
660
+ /** Total exports */
661
+ totalExports: number;
662
+ /** Number of domain terms used inconsistently (same concept, different names) */
663
+ inconsistentDomainTerms: number;
664
+ /** Distinct domain vocabulary size (unique business terms detected) */
665
+ domainVocabularySize: number;
666
+ }): AgentGroundingScore;
667
+ /**
668
+ * Testability Index
669
+ *
670
+ * Measures how verifiable AI-generated changes are.
671
+ * AI assistants are only as useful as your ability to validate their output.
672
+ *
673
+ * Core insight: A codebase where generated code CAN'T be verified
674
+ * is one where AI assistance actively introduces hidden risk.
675
+ *
676
+ * Technology-agnostic: test frameworks change; testability principles don't.
677
+ */
678
+ interface TestabilityIndex {
679
+ /** 0-100 score; higher = AI changes are more verifiable */
680
+ score: number;
681
+ rating: 'excellent' | 'good' | 'moderate' | 'poor' | 'unverifiable';
682
+ dimensions: {
683
+ /** Ratio of test files to source files */
684
+ testCoverageRatio: number;
685
+ /** Pure function prevalence (no side effects = easy to test) */
686
+ purityScore: number;
687
+ /** Dependency injection / inversion of control score */
688
+ dependencyInjectionScore: number;
689
+ /** Interface segregation (small, focused interfaces) */
690
+ interfaceFocusScore: number;
691
+ /** Observable outputs (functions return values vs mutate state) */
692
+ observabilityScore: number;
693
+ };
694
+ /** Estimated AI suggestion safety — without tests, AI changes are high-risk */
695
+ aiChangeSafetyRating: 'safe' | 'moderate-risk' | 'high-risk' | 'blind-risk';
696
+ recommendations: string[];
697
+ }
698
+ /**
699
+ * Calculate testability index from code structure analysis
700
+ */
701
+ declare function calculateTestabilityIndex(params: {
702
+ /** Number of test files (*.test.*, *.spec.*, __tests__/**) */
703
+ testFiles: number;
704
+ /** Number of source files (excluding tests, configs) */
705
+ sourceFiles: number;
706
+ /** Functions that take only data and return data (no I/O, no mutations) */
707
+ pureFunctions: number;
708
+ /** Total functions analyzed */
709
+ totalFunctions: number;
710
+ /** Classes/functions using constructor injection or factory patterns */
711
+ injectionPatterns: number;
712
+ /** Total classes/services */
713
+ totalClasses: number;
714
+ /** Interfaces/types with > 10 methods (low segregation) */
715
+ bloatedInterfaces: number;
716
+ /** Total interfaces/types */
717
+ totalInterfaces: number;
718
+ /** Functions that directly mutate external state (globals, DOM, DB without abstraction) */
719
+ externalStateMutations: number;
720
+ /** Has a defined testing framework (package.json test script exists) */
721
+ hasTestFramework: boolean;
722
+ }): TestabilityIndex;
723
+ interface DocDriftRisk {
724
+ score: number;
725
+ rating: 'minimal' | 'low' | 'moderate' | 'high' | 'severe';
726
+ dimensions: {
727
+ uncommentedExports: number;
728
+ outdatedComments: number;
729
+ undocumentedComplexity: number;
730
+ };
731
+ recommendations: string[];
732
+ }
733
+ declare function calculateDocDrift(params: {
734
+ uncommentedExports: number;
735
+ totalExports: number;
736
+ outdatedComments: number;
737
+ undocumentedComplexity: number;
738
+ }): DocDriftRisk;
739
+ interface DependencyHealthScore {
740
+ score: number;
741
+ rating: 'excellent' | 'good' | 'moderate' | 'poor' | 'hazardous';
742
+ dimensions: {
743
+ outdatedPackages: number;
744
+ deprecatedPackages: number;
745
+ trainingCutoffSkew: number;
746
+ };
747
+ aiKnowledgeConfidence: 'high' | 'moderate' | 'low' | 'blind';
748
+ recommendations: string[];
749
+ }
750
+ declare function calculateDependencyHealth(params: {
751
+ totalPackages: number;
752
+ outdatedPackages: number;
753
+ deprecatedPackages: number;
754
+ trainingCutoffSkew: number;
755
+ }): DependencyHealthScore;
756
+ /**
757
+ * Calculate the complete extended future-proof score including all dimensions.
758
+ * Replaces calculateFutureProofScore when all dimensions are available.
759
+ */
760
+ declare function calculateExtendedFutureProofScore(params: {
761
+ cognitiveLoad: CognitiveLoad;
762
+ patternEntropy: PatternEntropy;
763
+ conceptCohesion: ConceptCohesion;
764
+ hallucinationRisk: HallucinationRisk;
765
+ agentGrounding: AgentGroundingScore;
766
+ testability: TestabilityIndex;
767
+ docDrift?: DocDriftRisk;
768
+ dependencyHealth?: DependencyHealthScore;
769
+ semanticDistances?: SemanticDistance[];
770
+ }): ToolScoringOutput;
520
771
 
521
772
  /**
522
773
  * Temporal Tracking Utilities
@@ -555,4 +806,4 @@ declare function exportHistory(rootDir: string, format?: 'json' | 'csv'): string
555
806
  */
556
807
  declare function clearHistory(rootDir: string): void;
557
808
 
558
- export { AIReadyConfig, type ASTNode, AcceptancePrediction, type CLIOptions, type CognitiveLoad, ComprehensionDifficulty, type ConceptCohesion, CostConfig, DEFAULT_COST_CONFIG, DEFAULT_EXCLUDE, type DebtBreakdown, type ExportWithImports, type FileImport, type FileWithDomain, type KnowledgeConcentrationRisk, Language, LanguageParser, type LoadFactor, NamingConvention, ParseResult, ParserFactory, type PatternEntropy, ProductivityImpact, PythonParser, type RemediationVelocity, ScanOptions, type ScoreHistoryEntry, type ScoreTrend, type SemanticDistance, type TechnicalDebtInterest, ToolScoringOutput, TypeScriptParser, calculateCognitiveLoad, calculateComprehensionDifficulty, calculateConceptCohesion, calculateFutureProofScore, calculateImportSimilarity, calculateKnowledgeConcentration, calculateMonthlyCost, calculatePatternEntropy, calculateProductivityImpact, calculateRemediationVelocity, calculateScoreTrend, calculateSemanticDistance, calculateTechnicalDebtInterest, clearHistory, estimateTokens, exportHistory, extractFunctions, extractImports, formatAcceptanceRate, formatCost, formatHours, getDebtBreakdown, getElapsedTime, getFileExtension, getHistorySummary, getParser, getSupportedLanguages, handleCLIError, handleJSONOutput, isFileSupported, isSourceFile, loadConfig, loadMergedConfig, loadScoreHistory, mergeConfigWithDefaults, parseCode, parseFileExports, predictAcceptanceRate, readFileContent, resolveOutputPath, saveScoreEntry, scanFiles };
809
+ export { AIReadyConfig, type ASTNode, AcceptancePrediction, type AgentGroundingScore, type CLIOptions, type CognitiveLoad, ComprehensionDifficulty, type ConceptCohesion, CostConfig, DEFAULT_COST_CONFIG, DEFAULT_EXCLUDE, type DebtBreakdown, type DependencyHealthScore, type DocDriftRisk, type ExportWithImports, type FileImport, type FileWithDomain, type HallucinationRisk, type HallucinationRiskSignal, type KnowledgeConcentrationRisk, Language, LanguageParser, type LoadFactor, MODEL_PRICING_PRESETS, ModelContextTier, type ModelPricingPreset, NamingConvention, ParseResult, ParserFactory, type PatternEntropy, ProductivityImpact, PythonParser, type RemediationVelocity, ScanOptions, type ScoreHistoryEntry, type ScoreTrend, type SemanticDistance, type TechnicalDebtInterest, type TestabilityIndex, ToolScoringOutput, TypeScriptParser, calculateAgentGrounding, calculateCognitiveLoad, calculateComprehensionDifficulty, calculateConceptCohesion, calculateDependencyHealth, calculateDocDrift, calculateExtendedFutureProofScore, calculateFutureProofScore, calculateHallucinationRisk, calculateImportSimilarity, calculateKnowledgeConcentration, calculateMonthlyCost, calculatePatternEntropy, calculateProductivityImpact, calculateRemediationVelocity, calculateScoreTrend, calculateSemanticDistance, calculateTechnicalDebtInterest, calculateTestabilityIndex, clearHistory, estimateTokens, exportHistory, extractFunctions, extractImports, formatAcceptanceRate, formatCost, formatHours, getDebtBreakdown, getElapsedTime, getFileExtension, getHistorySummary, getModelPreset, getParser, getSupportedLanguages, handleCLIError, handleJSONOutput, isFileSupported, isSourceFile, loadConfig, loadMergedConfig, loadScoreHistory, mergeConfigWithDefaults, parseCode, parseFileExports, predictAcceptanceRate, readFileContent, resolveOutputPath, saveScoreEntry, scanFiles };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { ScanOptions, AIReadyConfig, CostConfig, ComprehensionDifficulty, ProductivityImpact, ToolScoringOutput, AcceptancePrediction, LanguageParser, Language, ParseResult, NamingConvention } from './client.js';
2
- export { AnalysisResult, BusinessReport, CommonASTNode, DEFAULT_TOOL_WEIGHTS, ExportInfo, GraphData, GraphEdge, GraphIssueSeverity, GraphMetadata, GraphNode, ImportInfo, Issue, IssueType, LANGUAGE_EXTENSIONS, LanguageConfig, Location, Metrics, ParseError, ParseStatistics, Report, ScoringConfig, ScoringResult, SourceLocation, SourceRange, TOOL_NAME_MAP, calculateOverallScore, formatScore, formatToolScore, generateHTML, getRating, getRatingDisplay, getToolWeight, normalizeToolName, parseWeightString } from './client.js';
1
+ import { ScanOptions, AIReadyConfig, CostConfig, ModelContextTier, ComprehensionDifficulty, ProductivityImpact, ToolScoringOutput, AcceptancePrediction, LanguageParser, Language, ParseResult, NamingConvention } from './client.js';
2
+ export { AnalysisResult, BusinessReport, CONTEXT_TIER_THRESHOLDS, CommonASTNode, DEFAULT_TOOL_WEIGHTS, ExportInfo, GraphData, GraphEdge, GraphIssueSeverity, GraphMetadata, GraphNode, ImportInfo, Issue, IssueType, LANGUAGE_EXTENSIONS, LanguageConfig, Location, Metrics, ParseError, ParseStatistics, Report, SIZE_ADJUSTED_THRESHOLDS, ScoringConfig, ScoringResult, SourceLocation, SourceRange, TOOL_NAME_MAP, calculateOverallScore, formatScore, formatToolScore, generateHTML, getProjectSizeTier, getRating, getRatingDisplay, getRatingWithContext, getRecommendedThreshold, getToolWeight, normalizeToolName, parseWeightString } from './client.js';
3
3
 
4
4
  declare const DEFAULT_EXCLUDE: string[];
5
5
  /**
@@ -120,8 +120,28 @@ declare function getElapsedTime(startTime: number): string;
120
120
  *
121
121
  * NEW in v0.11: Extended with temporal tracking, knowledge concentration, and
122
122
  * technical debt interest calculations.
123
+ * NEW in v0.12: Multi-model pricing presets, model-aware CDI calibration,
124
+ * and improved acceptance rate prediction with data-grounded baselines.
123
125
  */
124
126
 
127
+ /**
128
+ * AI model pricing presets for cost estimation.
129
+ * Prices are input token costs per 1K tokens (USD), as of Q1 2026.
130
+ * Update these as model pricing evolves — the calculation logic is unchanged.
131
+ */
132
+ interface ModelPricingPreset {
133
+ name: string;
134
+ pricePer1KInputTokens: number;
135
+ pricePer1KOutputTokens: number;
136
+ contextTier: ModelContextTier;
137
+ /** Approximate daily queries per active dev for this model class */
138
+ typicalQueriesPerDevPerDay: number;
139
+ }
140
+ declare const MODEL_PRICING_PRESETS: Record<string, ModelPricingPreset>;
141
+ /**
142
+ * Get a model pricing preset by ID, with fallback to gpt-4o
143
+ */
144
+ declare function getModelPreset(modelId: string): ModelPricingPreset;
125
145
  /**
126
146
  * Historical score entry for trend tracking
127
147
  */
@@ -203,7 +223,8 @@ interface DebtBreakdown {
203
223
  }
204
224
  /**
205
225
  * Default cost configuration
206
- * Based on GPT-4 pricing and typical team usage
226
+ * Points to GPT-4o as the default model (most common in 2026).
227
+ * Use MODEL_PRICING_PRESETS for model-specific accuracy.
207
228
  */
208
229
  declare const DEFAULT_COST_CONFIG: CostConfig;
209
230
  /**
@@ -221,10 +242,16 @@ declare function calculateProductivityImpact(issues: {
221
242
  /**
222
243
  * Predict AI suggestion acceptance rate based on code quality
223
244
  *
224
- * Research shows:
225
- * - High consistency correlates with 30%+ higher acceptance
226
- * - Low context budget improves understanding by ~40%
227
- * - Good naming patterns reduce clarification needs by 50%
245
+ * Calibration notes (v0.12):
246
+ * - GitHub Copilot reports ~30% industry average acceptance rate (2023 blog)
247
+ * - Internal teams with high-consistency codebases report 40-55%
248
+ * - Teams with semantic duplication report 20-25% (AI suggests wrong variant)
249
+ * - Context efficiency is the strongest single predictor
250
+ *
251
+ * Confidence levels:
252
+ * - 3 tools: 0.75 (triangulated estimate)
253
+ * - 2 tools: 0.55 (partial estimate)
254
+ * - 1 tool: 0.35 (weak estimate — don't over-rely)
228
255
  */
229
256
  declare function predictAcceptanceRate(toolOutputs: Map<string, ToolScoringOutput>): AcceptancePrediction;
230
257
  /**
@@ -232,8 +259,12 @@ declare function predictAcceptanceRate(toolOutputs: Map<string, ToolScoringOutpu
232
259
  *
233
260
  * A future-proof abstraction that normalizes multiple factors
234
261
  * into a single difficulty score. Lower = easier for AI.
262
+ *
263
+ * v0.12+: Now model-aware. Pass the `modelTier` of your AI toolchain
264
+ * to recalibrate token budget thresholds correctly. With frontier models
265
+ * (200k+ context), a 20k-token file is no longer "critical".
235
266
  */
236
- declare function calculateComprehensionDifficulty(contextBudget: number, importDepth: number, fragmentation: number, consistencyScore: number, totalFiles: number): ComprehensionDifficulty;
267
+ declare function calculateComprehensionDifficulty(contextBudget: number, importDepth: number, fragmentation: number, consistencyScore: number, totalFiles: number, modelTier?: ModelContextTier): ComprehensionDifficulty;
237
268
  /**
238
269
  * Format cost for display
239
270
  */
@@ -426,6 +457,11 @@ declare class PythonParser implements LanguageParser {
426
457
  * - Semantic Distance: How far apart related concepts are
427
458
  * - Concept Cohesion: How well grouped related ideas are
428
459
  * - Pattern Entropy: How ordered vs chaotic the structure is
460
+ * - Hallucination Risk: How likely AI is to generate incorrect code
461
+ * - Agent Grounding Score: How well an agent can navigate unaided
462
+ * - Testability Index: How verifiable AI-generated changes are
463
+ *
464
+ * v0.12+: Added hallucination risk, agent grounding, and testability dimensions.
429
465
  */
430
466
 
431
467
  /**
@@ -517,6 +553,221 @@ declare function calculateFutureProofScore(params: {
517
553
  conceptCohesion: ConceptCohesion;
518
554
  semanticDistances?: SemanticDistance[];
519
555
  }): ToolScoringOutput;
556
+ /**
557
+ * Signals that increase the likelihood of AI generating incorrect code.
558
+ * Technology-agnostic: these patterns confuse both current and future AI.
559
+ */
560
+ interface HallucinationRiskSignal {
561
+ name: string;
562
+ count: number;
563
+ riskContribution: number;
564
+ description: string;
565
+ examples?: string[];
566
+ }
567
+ /**
568
+ * Hallucination Risk Score (0-100, higher = more risk)
569
+ *
570
+ * Measures code patterns that empirically cause AI models to:
571
+ * - Confidently generate incorrect function signatures
572
+ * - Create plausible-but-wrong implementations
573
+ * - Miss implicit contracts / side effects
574
+ * - Misunderstand overloaded symbols
575
+ */
576
+ interface HallucinationRisk {
577
+ /** Overall risk score (0-100). Higher = more likely AI will hallucinate. */
578
+ score: number;
579
+ rating: 'minimal' | 'low' | 'moderate' | 'high' | 'severe';
580
+ signals: HallucinationRiskSignal[];
581
+ /** Most impactful signal to fix first */
582
+ topRisk: string;
583
+ recommendations: string[];
584
+ }
585
+ /**
586
+ * Calculate hallucination risk from code analysis results
587
+ *
588
+ * Input data can come from any parser; all inputs are normalized 0-N counts.
589
+ */
590
+ declare function calculateHallucinationRisk(params: {
591
+ /** Overloaded function names (same name, different signatures) */
592
+ overloadedSymbols: number;
593
+ /** Magic numbers and string literals without named constants */
594
+ magicLiterals: number;
595
+ /** Boolean trap parameters (function(true, false, null)) */
596
+ booleanTraps: number;
597
+ /** Implicit returns / void-implicit side effect functions */
598
+ implicitSideEffects: number;
599
+ /** Callback nesting depth > 3 (callback hell indicator) */
600
+ deepCallbacks: number;
601
+ /** Non-descriptive names: single letters, x1/x2 patterns, tmp/data/obj */
602
+ ambiguousNames: number;
603
+ /** Exported symbols with no JSDoc/docstring */
604
+ undocumentedExports: number;
605
+ /** Total symbols analyzed (for normalization) */
606
+ totalSymbols: number;
607
+ /** Total exports in codebase */
608
+ totalExports: number;
609
+ }): HallucinationRisk;
610
+ /**
611
+ * Agent Grounding Score
612
+ *
613
+ * Measures how well an AI agent can navigate a codebase *independently*,
614
+ * without human assistance or extensive prompting.
615
+ *
616
+ * High grounding = agent can find files, understand project structure,
617
+ * locate relevant code, and correctly infer ownership without being told.
618
+ *
619
+ * This is technology-agnostic: any agentic system (current or future)
620
+ * needs these structural guarantees to work effectively.
621
+ */
622
+ interface AgentGroundingScore {
623
+ /** 0-100 score; higher = better self-navigation */
624
+ score: number;
625
+ rating: 'excellent' | 'good' | 'moderate' | 'poor' | 'disorienting';
626
+ dimensions: {
627
+ /** Can agent find where to put new code? (directory structure clarity) */
628
+ structureClarityScore: number;
629
+ /** Can agent understand what a file does from its name alone? */
630
+ selfDocumentationScore: number;
631
+ /** Are entry points (index, main, README) present and accurate? */
632
+ entryPointScore: number;
633
+ /** Does the public API surface reflect the project's mental model? */
634
+ apiClarityScore: number;
635
+ /** Is the domain language consistent? (Same concept = same word everywhere) */
636
+ domainConsistencyScore: number;
637
+ };
638
+ recommendations: string[];
639
+ }
640
+ /**
641
+ * Calculate how well an AI agent can ground itself in the codebase
642
+ */
643
+ declare function calculateAgentGrounding(params: {
644
+ /** Number of directories exceeding recommended depth (> 4 levels) */
645
+ deepDirectories: number;
646
+ /** Total directories */
647
+ totalDirectories: number;
648
+ /** Files whose name alone doesn't reveal purpose (e.g., utils.ts, helpers.ts, misc.ts) */
649
+ vagueFileNames: number;
650
+ /** Total files */
651
+ totalFiles: number;
652
+ /** Whether a root README exists */
653
+ hasRootReadme: boolean;
654
+ /** Whether README has been updated in last 90 days (or unknown) */
655
+ readmeIsFresh: boolean;
656
+ /** Number of barrel exports (index.ts/index.js files that re-export) */
657
+ barrelExports: number;
658
+ /** Number of exported functions/classes/types with no type annotations */
659
+ untypedExports: number;
660
+ /** Total exports */
661
+ totalExports: number;
662
+ /** Number of domain terms used inconsistently (same concept, different names) */
663
+ inconsistentDomainTerms: number;
664
+ /** Distinct domain vocabulary size (unique business terms detected) */
665
+ domainVocabularySize: number;
666
+ }): AgentGroundingScore;
667
+ /**
668
+ * Testability Index
669
+ *
670
+ * Measures how verifiable AI-generated changes are.
671
+ * AI assistants are only as useful as your ability to validate their output.
672
+ *
673
+ * Core insight: A codebase where generated code CAN'T be verified
674
+ * is one where AI assistance actively introduces hidden risk.
675
+ *
676
+ * Technology-agnostic: test frameworks change; testability principles don't.
677
+ */
678
+ interface TestabilityIndex {
679
+ /** 0-100 score; higher = AI changes are more verifiable */
680
+ score: number;
681
+ rating: 'excellent' | 'good' | 'moderate' | 'poor' | 'unverifiable';
682
+ dimensions: {
683
+ /** Ratio of test files to source files */
684
+ testCoverageRatio: number;
685
+ /** Pure function prevalence (no side effects = easy to test) */
686
+ purityScore: number;
687
+ /** Dependency injection / inversion of control score */
688
+ dependencyInjectionScore: number;
689
+ /** Interface segregation (small, focused interfaces) */
690
+ interfaceFocusScore: number;
691
+ /** Observable outputs (functions return values vs mutate state) */
692
+ observabilityScore: number;
693
+ };
694
+ /** Estimated AI suggestion safety — without tests, AI changes are high-risk */
695
+ aiChangeSafetyRating: 'safe' | 'moderate-risk' | 'high-risk' | 'blind-risk';
696
+ recommendations: string[];
697
+ }
698
+ /**
699
+ * Calculate testability index from code structure analysis
700
+ */
701
+ declare function calculateTestabilityIndex(params: {
702
+ /** Number of test files (*.test.*, *.spec.*, __tests__/**) */
703
+ testFiles: number;
704
+ /** Number of source files (excluding tests, configs) */
705
+ sourceFiles: number;
706
+ /** Functions that take only data and return data (no I/O, no mutations) */
707
+ pureFunctions: number;
708
+ /** Total functions analyzed */
709
+ totalFunctions: number;
710
+ /** Classes/functions using constructor injection or factory patterns */
711
+ injectionPatterns: number;
712
+ /** Total classes/services */
713
+ totalClasses: number;
714
+ /** Interfaces/types with > 10 methods (low segregation) */
715
+ bloatedInterfaces: number;
716
+ /** Total interfaces/types */
717
+ totalInterfaces: number;
718
+ /** Functions that directly mutate external state (globals, DOM, DB without abstraction) */
719
+ externalStateMutations: number;
720
+ /** Has a defined testing framework (package.json test script exists) */
721
+ hasTestFramework: boolean;
722
+ }): TestabilityIndex;
723
+ interface DocDriftRisk {
724
+ score: number;
725
+ rating: 'minimal' | 'low' | 'moderate' | 'high' | 'severe';
726
+ dimensions: {
727
+ uncommentedExports: number;
728
+ outdatedComments: number;
729
+ undocumentedComplexity: number;
730
+ };
731
+ recommendations: string[];
732
+ }
733
+ declare function calculateDocDrift(params: {
734
+ uncommentedExports: number;
735
+ totalExports: number;
736
+ outdatedComments: number;
737
+ undocumentedComplexity: number;
738
+ }): DocDriftRisk;
739
+ interface DependencyHealthScore {
740
+ score: number;
741
+ rating: 'excellent' | 'good' | 'moderate' | 'poor' | 'hazardous';
742
+ dimensions: {
743
+ outdatedPackages: number;
744
+ deprecatedPackages: number;
745
+ trainingCutoffSkew: number;
746
+ };
747
+ aiKnowledgeConfidence: 'high' | 'moderate' | 'low' | 'blind';
748
+ recommendations: string[];
749
+ }
750
+ declare function calculateDependencyHealth(params: {
751
+ totalPackages: number;
752
+ outdatedPackages: number;
753
+ deprecatedPackages: number;
754
+ trainingCutoffSkew: number;
755
+ }): DependencyHealthScore;
756
+ /**
757
+ * Calculate the complete extended future-proof score including all dimensions.
758
+ * Replaces calculateFutureProofScore when all dimensions are available.
759
+ */
760
+ declare function calculateExtendedFutureProofScore(params: {
761
+ cognitiveLoad: CognitiveLoad;
762
+ patternEntropy: PatternEntropy;
763
+ conceptCohesion: ConceptCohesion;
764
+ hallucinationRisk: HallucinationRisk;
765
+ agentGrounding: AgentGroundingScore;
766
+ testability: TestabilityIndex;
767
+ docDrift?: DocDriftRisk;
768
+ dependencyHealth?: DependencyHealthScore;
769
+ semanticDistances?: SemanticDistance[];
770
+ }): ToolScoringOutput;
520
771
 
521
772
  /**
522
773
  * Temporal Tracking Utilities
@@ -555,4 +806,4 @@ declare function exportHistory(rootDir: string, format?: 'json' | 'csv'): string
555
806
  */
556
807
  declare function clearHistory(rootDir: string): void;
557
808
 
558
- export { AIReadyConfig, type ASTNode, AcceptancePrediction, type CLIOptions, type CognitiveLoad, ComprehensionDifficulty, type ConceptCohesion, CostConfig, DEFAULT_COST_CONFIG, DEFAULT_EXCLUDE, type DebtBreakdown, type ExportWithImports, type FileImport, type FileWithDomain, type KnowledgeConcentrationRisk, Language, LanguageParser, type LoadFactor, NamingConvention, ParseResult, ParserFactory, type PatternEntropy, ProductivityImpact, PythonParser, type RemediationVelocity, ScanOptions, type ScoreHistoryEntry, type ScoreTrend, type SemanticDistance, type TechnicalDebtInterest, ToolScoringOutput, TypeScriptParser, calculateCognitiveLoad, calculateComprehensionDifficulty, calculateConceptCohesion, calculateFutureProofScore, calculateImportSimilarity, calculateKnowledgeConcentration, calculateMonthlyCost, calculatePatternEntropy, calculateProductivityImpact, calculateRemediationVelocity, calculateScoreTrend, calculateSemanticDistance, calculateTechnicalDebtInterest, clearHistory, estimateTokens, exportHistory, extractFunctions, extractImports, formatAcceptanceRate, formatCost, formatHours, getDebtBreakdown, getElapsedTime, getFileExtension, getHistorySummary, getParser, getSupportedLanguages, handleCLIError, handleJSONOutput, isFileSupported, isSourceFile, loadConfig, loadMergedConfig, loadScoreHistory, mergeConfigWithDefaults, parseCode, parseFileExports, predictAcceptanceRate, readFileContent, resolveOutputPath, saveScoreEntry, scanFiles };
809
+ export { AIReadyConfig, type ASTNode, AcceptancePrediction, type AgentGroundingScore, type CLIOptions, type CognitiveLoad, ComprehensionDifficulty, type ConceptCohesion, CostConfig, DEFAULT_COST_CONFIG, DEFAULT_EXCLUDE, type DebtBreakdown, type DependencyHealthScore, type DocDriftRisk, type ExportWithImports, type FileImport, type FileWithDomain, type HallucinationRisk, type HallucinationRiskSignal, type KnowledgeConcentrationRisk, Language, LanguageParser, type LoadFactor, MODEL_PRICING_PRESETS, ModelContextTier, type ModelPricingPreset, NamingConvention, ParseResult, ParserFactory, type PatternEntropy, ProductivityImpact, PythonParser, type RemediationVelocity, ScanOptions, type ScoreHistoryEntry, type ScoreTrend, type SemanticDistance, type TechnicalDebtInterest, type TestabilityIndex, ToolScoringOutput, TypeScriptParser, calculateAgentGrounding, calculateCognitiveLoad, calculateComprehensionDifficulty, calculateConceptCohesion, calculateDependencyHealth, calculateDocDrift, calculateExtendedFutureProofScore, calculateFutureProofScore, calculateHallucinationRisk, calculateImportSimilarity, calculateKnowledgeConcentration, calculateMonthlyCost, calculatePatternEntropy, calculateProductivityImpact, calculateRemediationVelocity, calculateScoreTrend, calculateSemanticDistance, calculateTechnicalDebtInterest, calculateTestabilityIndex, clearHistory, estimateTokens, exportHistory, extractFunctions, extractImports, formatAcceptanceRate, formatCost, formatHours, getDebtBreakdown, getElapsedTime, getFileExtension, getHistorySummary, getModelPreset, getParser, getSupportedLanguages, handleCLIError, handleJSONOutput, isFileSupported, isSourceFile, loadConfig, loadMergedConfig, loadScoreHistory, mergeConfigWithDefaults, parseCode, parseFileExports, predictAcceptanceRate, readFileContent, resolveOutputPath, saveScoreEntry, scanFiles };
package/dist/index.js CHANGED
@@ -47,6 +47,8 @@ __export(index_exports, {
47
47
  calculateCognitiveLoad: () => calculateCognitiveLoad,
48
48
  calculateComprehensionDifficulty: () => calculateComprehensionDifficulty,
49
49
  calculateConceptCohesion: () => calculateConceptCohesion,
50
+ calculateDependencyHealth: () => calculateDependencyHealth,
51
+ calculateDocDrift: () => calculateDocDrift,
50
52
  calculateExtendedFutureProofScore: () => calculateExtendedFutureProofScore,
51
53
  calculateFutureProofScore: () => calculateFutureProofScore,
52
54
  calculateHallucinationRisk: () => calculateHallucinationRisk,
@@ -2303,6 +2305,85 @@ function calculateTestabilityIndex(params) {
2303
2305
  recommendations
2304
2306
  };
2305
2307
  }
2308
+ function calculateDocDrift(params) {
2309
+ const { uncommentedExports, totalExports, outdatedComments, undocumentedComplexity } = params;
2310
+ const uncommentedRatio = totalExports > 0 ? uncommentedExports / totalExports : 0;
2311
+ const outdatedScore = Math.min(100, outdatedComments * 15);
2312
+ const uncommentedScore = Math.min(100, uncommentedRatio * 100);
2313
+ const complexityScore = Math.min(100, undocumentedComplexity * 10);
2314
+ const score = Math.round(
2315
+ outdatedScore * 0.6 + uncommentedScore * 0.2 + complexityScore * 0.2
2316
+ );
2317
+ const finalScore = Math.min(100, Math.max(0, score));
2318
+ let rating;
2319
+ if (finalScore < 10) rating = "minimal";
2320
+ else if (finalScore < 30) rating = "low";
2321
+ else if (finalScore < 60) rating = "moderate";
2322
+ else if (finalScore < 85) rating = "high";
2323
+ else rating = "severe";
2324
+ const recommendations = [];
2325
+ if (outdatedComments > 0) {
2326
+ recommendations.push(`Update or remove ${outdatedComments} outdated comments that contradict the code.`);
2327
+ }
2328
+ if (uncommentedRatio > 0.3) {
2329
+ recommendations.push(`Add JSDoc to ${uncommentedExports} uncommented exports.`);
2330
+ }
2331
+ if (undocumentedComplexity > 0) {
2332
+ recommendations.push(`Explain the business logic for ${undocumentedComplexity} highly complex functions.`);
2333
+ }
2334
+ return {
2335
+ score: finalScore,
2336
+ rating,
2337
+ dimensions: {
2338
+ uncommentedExports,
2339
+ outdatedComments,
2340
+ undocumentedComplexity
2341
+ },
2342
+ recommendations
2343
+ };
2344
+ }
2345
+ function calculateDependencyHealth(params) {
2346
+ const { totalPackages, outdatedPackages, deprecatedPackages, trainingCutoffSkew } = params;
2347
+ const outdatedRatio = totalPackages > 0 ? outdatedPackages / totalPackages : 0;
2348
+ const deprecatedRatio = totalPackages > 0 ? deprecatedPackages / totalPackages : 0;
2349
+ const outdatedScore = Math.max(0, 100 - outdatedRatio * 200);
2350
+ const deprecatedScore = Math.max(0, 100 - deprecatedRatio * 500);
2351
+ const skewScore = Math.max(0, 100 - trainingCutoffSkew * 100);
2352
+ const rawScore = outdatedScore * 0.3 + deprecatedScore * 0.4 + skewScore * 0.3;
2353
+ const score = Math.round(Math.min(100, Math.max(0, rawScore)));
2354
+ let rating;
2355
+ if (score >= 85) rating = "excellent";
2356
+ else if (score >= 70) rating = "good";
2357
+ else if (score >= 50) rating = "moderate";
2358
+ else if (score >= 30) rating = "poor";
2359
+ else rating = "hazardous";
2360
+ let aiKnowledgeConfidence;
2361
+ if (trainingCutoffSkew < 0.2 && deprecatedPackages === 0) aiKnowledgeConfidence = "high";
2362
+ else if (trainingCutoffSkew < 0.5 && deprecatedPackages <= 2) aiKnowledgeConfidence = "moderate";
2363
+ else if (trainingCutoffSkew < 0.8) aiKnowledgeConfidence = "low";
2364
+ else aiKnowledgeConfidence = "blind";
2365
+ const recommendations = [];
2366
+ if (deprecatedPackages > 0) {
2367
+ recommendations.push(`Replace ${deprecatedPackages} deprecated packages, as AI will struggle to find modern solutions.`);
2368
+ }
2369
+ if (outdatedRatio > 0.2) {
2370
+ recommendations.push(`Update ${outdatedPackages} outdated packages to keep APIs aligned with AI training data.`);
2371
+ }
2372
+ if (trainingCutoffSkew > 0.5) {
2373
+ recommendations.push("High training cutoff skew detected. AI may hallucinate APIs that were introduced recently.");
2374
+ }
2375
+ return {
2376
+ score,
2377
+ rating,
2378
+ dimensions: {
2379
+ outdatedPackages,
2380
+ deprecatedPackages,
2381
+ trainingCutoffSkew
2382
+ },
2383
+ aiKnowledgeConfidence,
2384
+ recommendations
2385
+ };
2386
+ }
2306
2387
  function calculateExtendedFutureProofScore(params) {
2307
2388
  const loadScore = 100 - params.cognitiveLoad.score;
2308
2389
  const entropyScore = 100 - params.patternEntropy.entropy * 100;
@@ -2310,9 +2391,19 @@ function calculateExtendedFutureProofScore(params) {
2310
2391
  const hallucinationScore = 100 - params.hallucinationRisk.score;
2311
2392
  const groundingScore = params.agentGrounding.score;
2312
2393
  const testabilityScore = params.testability.score;
2313
- const overall = Math.round(
2314
- loadScore * 0.2 + entropyScore * 0.15 + cohesionScore * 0.15 + hallucinationScore * 0.2 + groundingScore * 0.15 + testabilityScore * 0.15
2315
- );
2394
+ const docDriftScore = params.docDrift ? 100 - params.docDrift.score : 100;
2395
+ const depsHealthScore = params.dependencyHealth ? params.dependencyHealth.score : 100;
2396
+ let totalWeight = 0.8;
2397
+ let overall = loadScore * 0.15 + entropyScore * 0.1 + cohesionScore * 0.1 + hallucinationScore * 0.15 + groundingScore * 0.15 + testabilityScore * 0.15;
2398
+ if (params.docDrift) {
2399
+ overall += docDriftScore * 0.1;
2400
+ totalWeight += 0.1;
2401
+ }
2402
+ if (params.dependencyHealth) {
2403
+ overall += depsHealthScore * 0.1;
2404
+ totalWeight += 0.1;
2405
+ }
2406
+ overall = Math.round(overall / totalWeight);
2316
2407
  const factors = [
2317
2408
  {
2318
2409
  name: "Cognitive Load",
@@ -2345,6 +2436,20 @@ function calculateExtendedFutureProofScore(params) {
2345
2436
  description: `${params.testability.rating} \u2014 AI changes are ${params.testability.aiChangeSafetyRating}`
2346
2437
  }
2347
2438
  ];
2439
+ if (params.docDrift) {
2440
+ factors.push({
2441
+ name: "Documentation Drift",
2442
+ impact: Math.round(docDriftScore - 50),
2443
+ description: `${params.docDrift.rating} risk of hallucination from drift`
2444
+ });
2445
+ }
2446
+ if (params.dependencyHealth) {
2447
+ factors.push({
2448
+ name: "Dependency Health",
2449
+ impact: Math.round(depsHealthScore - 50),
2450
+ description: `${params.dependencyHealth.rating} health \u2014 AI knowledge is ${params.dependencyHealth.aiKnowledgeConfidence}`
2451
+ });
2452
+ }
2348
2453
  const recommendations = [];
2349
2454
  for (const rec of params.hallucinationRisk.recommendations) {
2350
2455
  recommendations.push({ action: rec, estimatedImpact: 8, priority: "high" });
@@ -2359,6 +2464,16 @@ function calculateExtendedFutureProofScore(params) {
2359
2464
  for (const rec of params.patternEntropy.recommendations) {
2360
2465
  recommendations.push({ action: rec, estimatedImpact: 5, priority: "low" });
2361
2466
  }
2467
+ if (params.docDrift) {
2468
+ for (const rec of params.docDrift.recommendations) {
2469
+ recommendations.push({ action: rec, estimatedImpact: 8, priority: "high" });
2470
+ }
2471
+ }
2472
+ if (params.dependencyHealth) {
2473
+ for (const rec of params.dependencyHealth.recommendations) {
2474
+ recommendations.push({ action: rec, estimatedImpact: 7, priority: "medium" });
2475
+ }
2476
+ }
2362
2477
  const semanticDistanceAvg = params.semanticDistances && params.semanticDistances.length > 0 ? params.semanticDistances.reduce((s, d) => s + d.distance, 0) / params.semanticDistances.length : 0;
2363
2478
  return {
2364
2479
  toolName: "future-proof",
@@ -2370,6 +2485,8 @@ function calculateExtendedFutureProofScore(params) {
2370
2485
  hallucinationRiskScore: params.hallucinationRisk.score,
2371
2486
  agentGroundingScore: params.agentGrounding.score,
2372
2487
  testabilityScore: params.testability.score,
2488
+ docDriftScore: params.docDrift?.score,
2489
+ dependencyHealthScore: params.dependencyHealth?.score,
2373
2490
  semanticDistanceAvg
2374
2491
  },
2375
2492
  factors,
@@ -2469,6 +2586,8 @@ function clearHistory(rootDir) {
2469
2586
  calculateCognitiveLoad,
2470
2587
  calculateComprehensionDifficulty,
2471
2588
  calculateConceptCohesion,
2589
+ calculateDependencyHealth,
2590
+ calculateDocDrift,
2472
2591
  calculateExtendedFutureProofScore,
2473
2592
  calculateFutureProofScore,
2474
2593
  calculateHallucinationRisk,
package/dist/index.mjs CHANGED
@@ -1831,6 +1831,85 @@ function calculateTestabilityIndex(params) {
1831
1831
  recommendations
1832
1832
  };
1833
1833
  }
1834
+ function calculateDocDrift(params) {
1835
+ const { uncommentedExports, totalExports, outdatedComments, undocumentedComplexity } = params;
1836
+ const uncommentedRatio = totalExports > 0 ? uncommentedExports / totalExports : 0;
1837
+ const outdatedScore = Math.min(100, outdatedComments * 15);
1838
+ const uncommentedScore = Math.min(100, uncommentedRatio * 100);
1839
+ const complexityScore = Math.min(100, undocumentedComplexity * 10);
1840
+ const score = Math.round(
1841
+ outdatedScore * 0.6 + uncommentedScore * 0.2 + complexityScore * 0.2
1842
+ );
1843
+ const finalScore = Math.min(100, Math.max(0, score));
1844
+ let rating;
1845
+ if (finalScore < 10) rating = "minimal";
1846
+ else if (finalScore < 30) rating = "low";
1847
+ else if (finalScore < 60) rating = "moderate";
1848
+ else if (finalScore < 85) rating = "high";
1849
+ else rating = "severe";
1850
+ const recommendations = [];
1851
+ if (outdatedComments > 0) {
1852
+ recommendations.push(`Update or remove ${outdatedComments} outdated comments that contradict the code.`);
1853
+ }
1854
+ if (uncommentedRatio > 0.3) {
1855
+ recommendations.push(`Add JSDoc to ${uncommentedExports} uncommented exports.`);
1856
+ }
1857
+ if (undocumentedComplexity > 0) {
1858
+ recommendations.push(`Explain the business logic for ${undocumentedComplexity} highly complex functions.`);
1859
+ }
1860
+ return {
1861
+ score: finalScore,
1862
+ rating,
1863
+ dimensions: {
1864
+ uncommentedExports,
1865
+ outdatedComments,
1866
+ undocumentedComplexity
1867
+ },
1868
+ recommendations
1869
+ };
1870
+ }
1871
+ function calculateDependencyHealth(params) {
1872
+ const { totalPackages, outdatedPackages, deprecatedPackages, trainingCutoffSkew } = params;
1873
+ const outdatedRatio = totalPackages > 0 ? outdatedPackages / totalPackages : 0;
1874
+ const deprecatedRatio = totalPackages > 0 ? deprecatedPackages / totalPackages : 0;
1875
+ const outdatedScore = Math.max(0, 100 - outdatedRatio * 200);
1876
+ const deprecatedScore = Math.max(0, 100 - deprecatedRatio * 500);
1877
+ const skewScore = Math.max(0, 100 - trainingCutoffSkew * 100);
1878
+ const rawScore = outdatedScore * 0.3 + deprecatedScore * 0.4 + skewScore * 0.3;
1879
+ const score = Math.round(Math.min(100, Math.max(0, rawScore)));
1880
+ let rating;
1881
+ if (score >= 85) rating = "excellent";
1882
+ else if (score >= 70) rating = "good";
1883
+ else if (score >= 50) rating = "moderate";
1884
+ else if (score >= 30) rating = "poor";
1885
+ else rating = "hazardous";
1886
+ let aiKnowledgeConfidence;
1887
+ if (trainingCutoffSkew < 0.2 && deprecatedPackages === 0) aiKnowledgeConfidence = "high";
1888
+ else if (trainingCutoffSkew < 0.5 && deprecatedPackages <= 2) aiKnowledgeConfidence = "moderate";
1889
+ else if (trainingCutoffSkew < 0.8) aiKnowledgeConfidence = "low";
1890
+ else aiKnowledgeConfidence = "blind";
1891
+ const recommendations = [];
1892
+ if (deprecatedPackages > 0) {
1893
+ recommendations.push(`Replace ${deprecatedPackages} deprecated packages, as AI will struggle to find modern solutions.`);
1894
+ }
1895
+ if (outdatedRatio > 0.2) {
1896
+ recommendations.push(`Update ${outdatedPackages} outdated packages to keep APIs aligned with AI training data.`);
1897
+ }
1898
+ if (trainingCutoffSkew > 0.5) {
1899
+ recommendations.push("High training cutoff skew detected. AI may hallucinate APIs that were introduced recently.");
1900
+ }
1901
+ return {
1902
+ score,
1903
+ rating,
1904
+ dimensions: {
1905
+ outdatedPackages,
1906
+ deprecatedPackages,
1907
+ trainingCutoffSkew
1908
+ },
1909
+ aiKnowledgeConfidence,
1910
+ recommendations
1911
+ };
1912
+ }
1834
1913
  function calculateExtendedFutureProofScore(params) {
1835
1914
  const loadScore = 100 - params.cognitiveLoad.score;
1836
1915
  const entropyScore = 100 - params.patternEntropy.entropy * 100;
@@ -1838,9 +1917,19 @@ function calculateExtendedFutureProofScore(params) {
1838
1917
  const hallucinationScore = 100 - params.hallucinationRisk.score;
1839
1918
  const groundingScore = params.agentGrounding.score;
1840
1919
  const testabilityScore = params.testability.score;
1841
- const overall = Math.round(
1842
- loadScore * 0.2 + entropyScore * 0.15 + cohesionScore * 0.15 + hallucinationScore * 0.2 + groundingScore * 0.15 + testabilityScore * 0.15
1843
- );
1920
+ const docDriftScore = params.docDrift ? 100 - params.docDrift.score : 100;
1921
+ const depsHealthScore = params.dependencyHealth ? params.dependencyHealth.score : 100;
1922
+ let totalWeight = 0.8;
1923
+ let overall = loadScore * 0.15 + entropyScore * 0.1 + cohesionScore * 0.1 + hallucinationScore * 0.15 + groundingScore * 0.15 + testabilityScore * 0.15;
1924
+ if (params.docDrift) {
1925
+ overall += docDriftScore * 0.1;
1926
+ totalWeight += 0.1;
1927
+ }
1928
+ if (params.dependencyHealth) {
1929
+ overall += depsHealthScore * 0.1;
1930
+ totalWeight += 0.1;
1931
+ }
1932
+ overall = Math.round(overall / totalWeight);
1844
1933
  const factors = [
1845
1934
  {
1846
1935
  name: "Cognitive Load",
@@ -1873,6 +1962,20 @@ function calculateExtendedFutureProofScore(params) {
1873
1962
  description: `${params.testability.rating} \u2014 AI changes are ${params.testability.aiChangeSafetyRating}`
1874
1963
  }
1875
1964
  ];
1965
+ if (params.docDrift) {
1966
+ factors.push({
1967
+ name: "Documentation Drift",
1968
+ impact: Math.round(docDriftScore - 50),
1969
+ description: `${params.docDrift.rating} risk of hallucination from drift`
1970
+ });
1971
+ }
1972
+ if (params.dependencyHealth) {
1973
+ factors.push({
1974
+ name: "Dependency Health",
1975
+ impact: Math.round(depsHealthScore - 50),
1976
+ description: `${params.dependencyHealth.rating} health \u2014 AI knowledge is ${params.dependencyHealth.aiKnowledgeConfidence}`
1977
+ });
1978
+ }
1876
1979
  const recommendations = [];
1877
1980
  for (const rec of params.hallucinationRisk.recommendations) {
1878
1981
  recommendations.push({ action: rec, estimatedImpact: 8, priority: "high" });
@@ -1887,6 +1990,16 @@ function calculateExtendedFutureProofScore(params) {
1887
1990
  for (const rec of params.patternEntropy.recommendations) {
1888
1991
  recommendations.push({ action: rec, estimatedImpact: 5, priority: "low" });
1889
1992
  }
1993
+ if (params.docDrift) {
1994
+ for (const rec of params.docDrift.recommendations) {
1995
+ recommendations.push({ action: rec, estimatedImpact: 8, priority: "high" });
1996
+ }
1997
+ }
1998
+ if (params.dependencyHealth) {
1999
+ for (const rec of params.dependencyHealth.recommendations) {
2000
+ recommendations.push({ action: rec, estimatedImpact: 7, priority: "medium" });
2001
+ }
2002
+ }
1890
2003
  const semanticDistanceAvg = params.semanticDistances && params.semanticDistances.length > 0 ? params.semanticDistances.reduce((s, d) => s + d.distance, 0) / params.semanticDistances.length : 0;
1891
2004
  return {
1892
2005
  toolName: "future-proof",
@@ -1898,6 +2011,8 @@ function calculateExtendedFutureProofScore(params) {
1898
2011
  hallucinationRiskScore: params.hallucinationRisk.score,
1899
2012
  agentGroundingScore: params.agentGrounding.score,
1900
2013
  testabilityScore: params.testability.score,
2014
+ docDriftScore: params.docDrift?.score,
2015
+ dependencyHealthScore: params.dependencyHealth?.score,
1901
2016
  semanticDistanceAvg
1902
2017
  },
1903
2018
  factors,
@@ -1996,6 +2111,8 @@ export {
1996
2111
  calculateCognitiveLoad,
1997
2112
  calculateComprehensionDifficulty,
1998
2113
  calculateConceptCohesion,
2114
+ calculateDependencyHealth,
2115
+ calculateDocDrift,
1999
2116
  calculateExtendedFutureProofScore,
2000
2117
  calculateFutureProofScore,
2001
2118
  calculateHallucinationRisk,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/core",
3
- "version": "0.9.27",
3
+ "version": "0.9.30",
4
4
  "description": "Shared utilities for AIReady analysis tools",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",