@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 +70 -2
- package/dist/client.d.ts +70 -2
- package/dist/index.d.mts +260 -9
- package/dist/index.d.ts +260 -9
- package/dist/index.js +122 -3
- package/dist/index.mjs +120 -3
- package/package.json +1 -1
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
|
-
*
|
|
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
|
-
*
|
|
225
|
-
* -
|
|
226
|
-
* -
|
|
227
|
-
* -
|
|
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
|
-
*
|
|
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
|
-
*
|
|
225
|
-
* -
|
|
226
|
-
* -
|
|
227
|
-
* -
|
|
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
|
|
2314
|
-
|
|
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
|
|
1842
|
-
|
|
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,
|