@aiready/core 0.23.8 → 0.23.10
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/chunk-CGOS2J6T.mjs +807 -0
- package/dist/client-BEoUYNLp.d.mts +1191 -0
- package/dist/client-BEoUYNLp.d.ts +1191 -0
- package/dist/client.d.mts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +9 -1
- package/dist/client.mjs +1 -1
- package/dist/index.d.mts +20 -4
- package/dist/index.d.ts +20 -4
- package/dist/index.js +84 -7
- package/dist/index.mjs +76 -7
- package/package.json +1 -1
package/dist/client.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { e as AIReadyConfig, h as AcceptancePrediction, A as AnalysisResult, r as AnalysisStatus, B as BusinessMetrics, t as COMMON_FINE_TUNING_OPTIONS, u as CONTEXT_TIER_THRESHOLDS, v as CommonASTNode, i as ComprehensionDifficulty, w as Config, C as CostConfig, D as DEFAULT_TOOL_WEIGHTS, n as ExportInfo, x as FRIENDLY_TOOL_NAMES, y as FileContent, G as GLOBAL_INFRA_OPTIONS, z as GLOBAL_SCAN_OPTIONS, H as GraphData, J as GraphEdge, K as GraphIssueSeverity, O as GraphMetadata, Q as GraphNode, I as Issue, U as IssueType, W as LANGUAGE_EXTENSIONS, l as Language, X as LanguageConfig, L as LanguageParser, Y as Lead, Z as LeadSchema, _ as LeadSource, $ as LeadSourceSchema, a0 as LeadSubmission, a1 as LeadSubmissionSchema, a2 as Location, M as Metrics, f as ModelContextTier, N as NamingConvention, a9 as ParseError, m as ParseResult, aa as ParseStatistics, P as ProductivityImpact, ab as ReadinessRating, ac as RecommendationPriority, ad as SCORING_PROFILES, ae as SIZE_ADJUSTED_THRESHOLDS, S as ScanOptions, af as ScanResult, ag as ScoringConfig, ah as ScoringProfile, ai as ScoringResult, d as Severity, d as SeverityType, ak as SourceLocation, al as SourceRange, a as SpokeOutput, ap as TOOL_NAME_MAP, k as TechnicalValueChain, j as TechnicalValueChainSummary, g as TokenBudget, T as ToolName, c as ToolOptions, ar as ToolOutput, b as ToolScoringOutput, as as UnifiedReport, at as UnifiedReportSchema, au as calculateOverallScore, av as formatScore, aw as formatToolScore, ax as generateHTML, ay as getProjectSizeTier, az as getRating, aA as getRatingDisplay, aB as getRatingSlug, aC as getRatingWithContext, aD as getRecommendedThreshold, aE as getToolWeight, aF as normalizeToolName, aG as parseWeightString } from './client-
|
|
1
|
+
export { e as AIReadyConfig, h as AcceptancePrediction, A as AnalysisResult, r as AnalysisStatus, B as BusinessMetrics, t as COMMON_FINE_TUNING_OPTIONS, u as CONTEXT_TIER_THRESHOLDS, v as CommonASTNode, i as ComprehensionDifficulty, w as Config, C as CostConfig, D as DEFAULT_TOOL_WEIGHTS, n as ExportInfo, x as FRIENDLY_TOOL_NAMES, y as FileContent, G as GLOBAL_INFRA_OPTIONS, z as GLOBAL_SCAN_OPTIONS, H as GraphData, J as GraphEdge, K as GraphIssueSeverity, O as GraphMetadata, Q as GraphNode, I as Issue, U as IssueType, W as LANGUAGE_EXTENSIONS, l as Language, X as LanguageConfig, L as LanguageParser, Y as Lead, Z as LeadSchema, _ as LeadSource, $ as LeadSourceSchema, a0 as LeadSubmission, a1 as LeadSubmissionSchema, a2 as Location, M as Metrics, f as ModelContextTier, N as NamingConvention, a9 as ParseError, m as ParseResult, aa as ParseStatistics, P as ProductivityImpact, ab as ReadinessRating, ac as RecommendationPriority, ad as SCORING_PROFILES, ae as SIZE_ADJUSTED_THRESHOLDS, S as ScanOptions, af as ScanResult, ag as ScoringConfig, ah as ScoringProfile, ai as ScoringResult, d as Severity, d as SeverityType, ak as SourceLocation, al as SourceRange, a as SpokeOutput, ap as TOOL_NAME_MAP, k as TechnicalValueChain, j as TechnicalValueChainSummary, g as TokenBudget, T as ToolName, c as ToolOptions, ar as ToolOutput, b as ToolScoringOutput, as as UnifiedReport, at as UnifiedReportSchema, au as calculateOverallScore, av as formatScore, aw as formatToolScore, ax as generateHTML, ay as getProjectSizeTier, az as getRating, aA as getRatingDisplay, aB as getRatingSlug, aC as getRatingWithContext, aD as getRecommendedThreshold, aE as getToolWeight, aF as normalizeToolName, aG as parseWeightString } from './client-BEoUYNLp.mjs';
|
|
2
2
|
import 'zod';
|
package/dist/client.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { e as AIReadyConfig, h as AcceptancePrediction, A as AnalysisResult, r as AnalysisStatus, B as BusinessMetrics, t as COMMON_FINE_TUNING_OPTIONS, u as CONTEXT_TIER_THRESHOLDS, v as CommonASTNode, i as ComprehensionDifficulty, w as Config, C as CostConfig, D as DEFAULT_TOOL_WEIGHTS, n as ExportInfo, x as FRIENDLY_TOOL_NAMES, y as FileContent, G as GLOBAL_INFRA_OPTIONS, z as GLOBAL_SCAN_OPTIONS, H as GraphData, J as GraphEdge, K as GraphIssueSeverity, O as GraphMetadata, Q as GraphNode, I as Issue, U as IssueType, W as LANGUAGE_EXTENSIONS, l as Language, X as LanguageConfig, L as LanguageParser, Y as Lead, Z as LeadSchema, _ as LeadSource, $ as LeadSourceSchema, a0 as LeadSubmission, a1 as LeadSubmissionSchema, a2 as Location, M as Metrics, f as ModelContextTier, N as NamingConvention, a9 as ParseError, m as ParseResult, aa as ParseStatistics, P as ProductivityImpact, ab as ReadinessRating, ac as RecommendationPriority, ad as SCORING_PROFILES, ae as SIZE_ADJUSTED_THRESHOLDS, S as ScanOptions, af as ScanResult, ag as ScoringConfig, ah as ScoringProfile, ai as ScoringResult, d as Severity, d as SeverityType, ak as SourceLocation, al as SourceRange, a as SpokeOutput, ap as TOOL_NAME_MAP, k as TechnicalValueChain, j as TechnicalValueChainSummary, g as TokenBudget, T as ToolName, c as ToolOptions, ar as ToolOutput, b as ToolScoringOutput, as as UnifiedReport, at as UnifiedReportSchema, au as calculateOverallScore, av as formatScore, aw as formatToolScore, ax as generateHTML, ay as getProjectSizeTier, az as getRating, aA as getRatingDisplay, aB as getRatingSlug, aC as getRatingWithContext, aD as getRecommendedThreshold, aE as getToolWeight, aF as normalizeToolName, aG as parseWeightString } from './client-
|
|
1
|
+
export { e as AIReadyConfig, h as AcceptancePrediction, A as AnalysisResult, r as AnalysisStatus, B as BusinessMetrics, t as COMMON_FINE_TUNING_OPTIONS, u as CONTEXT_TIER_THRESHOLDS, v as CommonASTNode, i as ComprehensionDifficulty, w as Config, C as CostConfig, D as DEFAULT_TOOL_WEIGHTS, n as ExportInfo, x as FRIENDLY_TOOL_NAMES, y as FileContent, G as GLOBAL_INFRA_OPTIONS, z as GLOBAL_SCAN_OPTIONS, H as GraphData, J as GraphEdge, K as GraphIssueSeverity, O as GraphMetadata, Q as GraphNode, I as Issue, U as IssueType, W as LANGUAGE_EXTENSIONS, l as Language, X as LanguageConfig, L as LanguageParser, Y as Lead, Z as LeadSchema, _ as LeadSource, $ as LeadSourceSchema, a0 as LeadSubmission, a1 as LeadSubmissionSchema, a2 as Location, M as Metrics, f as ModelContextTier, N as NamingConvention, a9 as ParseError, m as ParseResult, aa as ParseStatistics, P as ProductivityImpact, ab as ReadinessRating, ac as RecommendationPriority, ad as SCORING_PROFILES, ae as SIZE_ADJUSTED_THRESHOLDS, S as ScanOptions, af as ScanResult, ag as ScoringConfig, ah as ScoringProfile, ai as ScoringResult, d as Severity, d as SeverityType, ak as SourceLocation, al as SourceRange, a as SpokeOutput, ap as TOOL_NAME_MAP, k as TechnicalValueChain, j as TechnicalValueChainSummary, g as TokenBudget, T as ToolName, c as ToolOptions, ar as ToolOutput, b as ToolScoringOutput, as as UnifiedReport, at as UnifiedReportSchema, au as calculateOverallScore, av as formatScore, aw as formatToolScore, ax as generateHTML, ay as getProjectSizeTier, az as getRating, aA as getRatingDisplay, aB as getRatingSlug, aC as getRatingWithContext, aD as getRecommendedThreshold, aE as getToolWeight, aF as normalizeToolName, aG as parseWeightString } from './client-BEoUYNLp.js';
|
|
2
2
|
import 'zod';
|
package/dist/client.js
CHANGED
|
@@ -256,8 +256,16 @@ var AIReadyConfigSchema = import_zod.z.object({
|
|
|
256
256
|
profile: import_zod.z.string().optional(),
|
|
257
257
|
/** Custom weights for tools and metrics */
|
|
258
258
|
weights: import_zod.z.record(import_zod.z.string(), import_zod.z.number()).optional()
|
|
259
|
+
}).optional(),
|
|
260
|
+
/** Visualizer settings (interactive graph) */
|
|
261
|
+
visualizer: import_zod.z.object({
|
|
262
|
+
groupingDirs: import_zod.z.array(import_zod.z.string()).optional(),
|
|
263
|
+
graph: import_zod.z.object({
|
|
264
|
+
maxNodes: import_zod.z.number().optional(),
|
|
265
|
+
maxEdges: import_zod.z.number().optional()
|
|
266
|
+
}).optional()
|
|
259
267
|
}).optional()
|
|
260
|
-
});
|
|
268
|
+
}).catchall(import_zod.z.any());
|
|
261
269
|
|
|
262
270
|
// src/types/business.ts
|
|
263
271
|
var import_zod2 = require("zod");
|
package/dist/client.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as ToolName, S as ScanOptions, a as SpokeOutput, b as ToolScoringOutput, c as ToolOptions, d as Severity, A as AnalysisResult, E as ExportWithImports, F as FileImport, e as AIReadyConfig, I as Issue, M as Metrics, f as ModelContextTier, C as CostConfig, g as TokenBudget, P as ProductivityImpact, h as AcceptancePrediction, i as ComprehensionDifficulty, j as TechnicalValueChainSummary, k as TechnicalValueChain, L as LanguageParser, l as Language, m as ParseResult, N as NamingConvention, n as ExportInfo } from './client-
|
|
2
|
-
export { o as AIReadyConfigSchema, p as ASTNode, q as AnalysisResultSchema, r as AnalysisStatus, s as AnalysisStatusSchema, B as BusinessMetrics, t as COMMON_FINE_TUNING_OPTIONS, u as CONTEXT_TIER_THRESHOLDS, v as CommonASTNode, w as Config, D as DEFAULT_TOOL_WEIGHTS, x as FRIENDLY_TOOL_NAMES, y as FileContent, G as GLOBAL_INFRA_OPTIONS, z as GLOBAL_SCAN_OPTIONS, H as GraphData, J as GraphEdge, K as GraphIssueSeverity, O as GraphMetadata, Q as GraphNode, R as IssueSchema, U as IssueType, V as IssueTypeSchema, W as LANGUAGE_EXTENSIONS, X as LanguageConfig, Y as Lead, Z as LeadSchema, _ as LeadSource, $ as LeadSourceSchema, a0 as LeadSubmission, a1 as LeadSubmissionSchema, a2 as Location, a3 as LocationSchema, a4 as ManagedAccount, a5 as ManagedAccountSchema, a6 as MetricsSchema, a7 as ModelTier, a8 as ModelTierSchema, a9 as ParseError, aa as ParseStatistics, ab as ReadinessRating, ac as RecommendationPriority, ad as SCORING_PROFILES, ae as SIZE_ADJUSTED_THRESHOLDS, af as ScanResult, ag as ScoringConfig, ah as ScoringProfile, ai as ScoringResult, aj as SeveritySchema, ak as SourceLocation, al as SourceRange, am as SpokeOutputSchema, an as SpokeSummary, ao as SpokeSummarySchema, ap as TOOL_NAME_MAP, aq as ToolNameSchema, ar as ToolOutput, as as UnifiedReport, at as UnifiedReportSchema, au as calculateOverallScore, av as formatScore, aw as formatToolScore, ax as generateHTML, ay as getProjectSizeTier, az as getRating, aA as getRatingDisplay, aB as getRatingSlug, aC as getRatingWithContext, aD as getRecommendedThreshold, aE as getToolWeight, aF as normalizeToolName, aG as parseWeightString } from './client-
|
|
1
|
+
import { T as ToolName, S as ScanOptions, a as SpokeOutput, b as ToolScoringOutput, c as ToolOptions, d as Severity, A as AnalysisResult, E as ExportWithImports, F as FileImport, e as AIReadyConfig, I as Issue, M as Metrics, f as ModelContextTier, C as CostConfig, g as TokenBudget, P as ProductivityImpact, h as AcceptancePrediction, i as ComprehensionDifficulty, j as TechnicalValueChainSummary, k as TechnicalValueChain, L as LanguageParser, l as Language, m as ParseResult, N as NamingConvention, n as ExportInfo } from './client-BEoUYNLp.mjs';
|
|
2
|
+
export { o as AIReadyConfigSchema, p as ASTNode, q as AnalysisResultSchema, r as AnalysisStatus, s as AnalysisStatusSchema, B as BusinessMetrics, t as COMMON_FINE_TUNING_OPTIONS, u as CONTEXT_TIER_THRESHOLDS, v as CommonASTNode, w as Config, D as DEFAULT_TOOL_WEIGHTS, x as FRIENDLY_TOOL_NAMES, y as FileContent, G as GLOBAL_INFRA_OPTIONS, z as GLOBAL_SCAN_OPTIONS, H as GraphData, J as GraphEdge, K as GraphIssueSeverity, O as GraphMetadata, Q as GraphNode, R as IssueSchema, U as IssueType, V as IssueTypeSchema, W as LANGUAGE_EXTENSIONS, X as LanguageConfig, Y as Lead, Z as LeadSchema, _ as LeadSource, $ as LeadSourceSchema, a0 as LeadSubmission, a1 as LeadSubmissionSchema, a2 as Location, a3 as LocationSchema, a4 as ManagedAccount, a5 as ManagedAccountSchema, a6 as MetricsSchema, a7 as ModelTier, a8 as ModelTierSchema, a9 as ParseError, aa as ParseStatistics, ab as ReadinessRating, ac as RecommendationPriority, ad as SCORING_PROFILES, ae as SIZE_ADJUSTED_THRESHOLDS, af as ScanResult, ag as ScoringConfig, ah as ScoringProfile, ai as ScoringResult, aj as SeveritySchema, ak as SourceLocation, al as SourceRange, am as SpokeOutputSchema, an as SpokeSummary, ao as SpokeSummarySchema, ap as TOOL_NAME_MAP, aq as ToolNameSchema, ar as ToolOutput, as as UnifiedReport, at as UnifiedReportSchema, au as calculateOverallScore, av as formatScore, aw as formatToolScore, ax as generateHTML, ay as getProjectSizeTier, az as getRating, aA as getRatingDisplay, aB as getRatingSlug, aC as getRatingWithContext, aD as getRecommendedThreshold, aE as getToolWeight, aF as normalizeToolName, aG as parseWeightString } from './client-BEoUYNLp.mjs';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import * as Parser from 'web-tree-sitter';
|
|
5
5
|
|
|
@@ -1316,8 +1316,14 @@ declare function calculateAgentGrounding(params: {
|
|
|
1316
1316
|
* Testability Index Metrics.
|
|
1317
1317
|
* Measures how verifiable AI-generated changes are based on local testing infrastructure.
|
|
1318
1318
|
*
|
|
1319
|
-
* @lastUpdated 2026-03-
|
|
1319
|
+
* @lastUpdated 2026-03-19
|
|
1320
1320
|
*/
|
|
1321
|
+
interface FileTestability {
|
|
1322
|
+
filePath: string;
|
|
1323
|
+
score: number;
|
|
1324
|
+
purityScore: number;
|
|
1325
|
+
isEntryPoint: boolean;
|
|
1326
|
+
}
|
|
1321
1327
|
interface TestabilityIndex {
|
|
1322
1328
|
score: number;
|
|
1323
1329
|
rating: 'excellent' | 'good' | 'moderate' | 'poor' | 'unverifiable';
|
|
@@ -1330,6 +1336,10 @@ interface TestabilityIndex {
|
|
|
1330
1336
|
};
|
|
1331
1337
|
aiChangeSafetyRating: 'safe' | 'moderate-risk' | 'high-risk' | 'blind-risk';
|
|
1332
1338
|
recommendations: string[];
|
|
1339
|
+
/** Per-file testability metrics */
|
|
1340
|
+
fileMetrics?: FileTestability[];
|
|
1341
|
+
/** Score based only on library code (excluding CLI entry points) */
|
|
1342
|
+
libraryScore?: number;
|
|
1333
1343
|
}
|
|
1334
1344
|
/**
|
|
1335
1345
|
* Calculate the Testability Index for a project.
|
|
@@ -1345,6 +1355,7 @@ interface TestabilityIndex {
|
|
|
1345
1355
|
* @param params.totalInterfaces - Total number of interfaces analyzed.
|
|
1346
1356
|
* @param params.externalStateMutations - Count of nodes that mutate external state.
|
|
1347
1357
|
* @param params.hasTestFramework - Whether a testing framework (e.g., Vitest) is detected.
|
|
1358
|
+
* @param params.fileDetails - Optional per-file data for detailed analysis.
|
|
1348
1359
|
* @returns Comprehensive TestabilityIndex analysis.
|
|
1349
1360
|
*/
|
|
1350
1361
|
declare function calculateTestabilityIndex(params: {
|
|
@@ -1358,6 +1369,11 @@ declare function calculateTestabilityIndex(params: {
|
|
|
1358
1369
|
totalInterfaces: number;
|
|
1359
1370
|
externalStateMutations: number;
|
|
1360
1371
|
hasTestFramework: boolean;
|
|
1372
|
+
fileDetails?: Array<{
|
|
1373
|
+
filePath: string;
|
|
1374
|
+
pureFunctions: number;
|
|
1375
|
+
totalFunctions: number;
|
|
1376
|
+
}>;
|
|
1361
1377
|
}): TestabilityIndex;
|
|
1362
1378
|
|
|
1363
1379
|
/**
|
|
@@ -1638,4 +1654,4 @@ declare function severityToAnnotationLevel(severity: string): 'error' | 'warning
|
|
|
1638
1654
|
*/
|
|
1639
1655
|
declare function emitIssuesAsAnnotations(issues: any[]): void;
|
|
1640
1656
|
|
|
1641
|
-
export { AIReadyConfig, AcceptancePrediction, type AgentGroundingScore, type AiSignalClarity, type AiSignalClaritySignal, AnalysisResult, type CLIOptions, CSharpParser, type ChangeAmplificationScore, type CognitiveLoad, ComprehensionDifficulty, type ConceptCohesion, CostConfig, DEFAULT_COST_CONFIG, DEFAULT_EXCLUDE, type DependencyHealthScore, type DocDriftRisk, ExportInfo, ExportWithImports, FileImport, type FileWithDomain, GoParser, Issue, JavaParser, type KnowledgeConcentrationRisk, Language, LanguageParser, type LoadFactor, MODEL_PRICING_PRESETS, Metrics, ModelContextTier, type ModelPricingPreset, NamingConvention, ParseResult, ParserFactory, type PatternEntropy, ProductivityImpact, type ProviderFactoryConfig, PythonParser, SEVERITY_TIME_ESTIMATES, ScanOptions, type ScoreHistoryEntry, type ScoreTrend, type SemanticDistance, Severity, Severity as SeverityType, SpokeOutput, type TechnicalDebtInterest, TechnicalValueChain, TechnicalValueChainSummary, type TestabilityIndex, TokenBudget, ToolName, ToolOptions, type ToolProvider, ToolRegistry, ToolScoringOutput, TypeScriptParser, VAGUE_FILE_NAMES, buildSimpleProviderScore, buildSpokeOutput, calculateAgentGrounding, calculateAiSignalClarity, calculateBusinessROI, calculateChangeAmplification, calculateCognitiveLoad, calculateComprehensionDifficulty, calculateConceptCohesion, calculateDebtInterest, calculateDependencyHealth, calculateDocDrift, calculateExtendedFutureProofScore, calculateFutureProofScore, calculateImportSimilarity, calculateKnowledgeConcentration, calculateMonthlyCost, calculatePatternEntropy, calculateProductivityImpact, calculateSemanticDistance, calculateTechnicalValueChain, calculateTestabilityIndex, calculateTokenBudget, clearHistory, createProvider, emitAnnotation, emitIssuesAsAnnotations, emitProgress, estimateCostFromBudget, estimateTokens, exportHistory, findLatestReport, findLatestScanReport, formatAcceptanceRate, formatCost, formatHours, generateValueChain, getElapsedTime, getFileCommitTimestamps, getFileExtension, getHistorySummary, getLineRangeLastModifiedCached, getModelPreset, getParser, getRepoMetadata, getSafetyIcon, getScoreBar, getSeverityBadge, getSeverityColor, getSeverityEnum, getSeverityLevel, getSeverityValue, getSupportedLanguages, getWasmPath, groupIssuesByFile, handleCLIError, handleJSONOutput, initTreeSitter, initializeParsers, isFileSupported, isSourceFile, loadConfig, loadMergedConfig, loadScoreHistory, mergeConfigWithDefaults, normalizeAnalysisResult, normalizeIssue, normalizeMetrics, normalizeSpokeOutput, parseFileExports, predictAcceptanceRate, readFileContent, resolveOutputPath, saveScoreEntry, scanEntries, scanFiles, setupParser, severityToAnnotationLevel, validateSpokeOutput, validateWithSchema };
|
|
1657
|
+
export { AIReadyConfig, AcceptancePrediction, type AgentGroundingScore, type AiSignalClarity, type AiSignalClaritySignal, AnalysisResult, type CLIOptions, CSharpParser, type ChangeAmplificationScore, type CognitiveLoad, ComprehensionDifficulty, type ConceptCohesion, CostConfig, DEFAULT_COST_CONFIG, DEFAULT_EXCLUDE, type DependencyHealthScore, type DocDriftRisk, ExportInfo, ExportWithImports, FileImport, type FileTestability, type FileWithDomain, GoParser, Issue, JavaParser, type KnowledgeConcentrationRisk, Language, LanguageParser, type LoadFactor, MODEL_PRICING_PRESETS, Metrics, ModelContextTier, type ModelPricingPreset, NamingConvention, ParseResult, ParserFactory, type PatternEntropy, ProductivityImpact, type ProviderFactoryConfig, PythonParser, SEVERITY_TIME_ESTIMATES, ScanOptions, type ScoreHistoryEntry, type ScoreTrend, type SemanticDistance, Severity, Severity as SeverityType, SpokeOutput, type TechnicalDebtInterest, TechnicalValueChain, TechnicalValueChainSummary, type TestabilityIndex, TokenBudget, ToolName, ToolOptions, type ToolProvider, ToolRegistry, ToolScoringOutput, TypeScriptParser, VAGUE_FILE_NAMES, buildSimpleProviderScore, buildSpokeOutput, calculateAgentGrounding, calculateAiSignalClarity, calculateBusinessROI, calculateChangeAmplification, calculateCognitiveLoad, calculateComprehensionDifficulty, calculateConceptCohesion, calculateDebtInterest, calculateDependencyHealth, calculateDocDrift, calculateExtendedFutureProofScore, calculateFutureProofScore, calculateImportSimilarity, calculateKnowledgeConcentration, calculateMonthlyCost, calculatePatternEntropy, calculateProductivityImpact, calculateSemanticDistance, calculateTechnicalValueChain, calculateTestabilityIndex, calculateTokenBudget, clearHistory, createProvider, emitAnnotation, emitIssuesAsAnnotations, emitProgress, estimateCostFromBudget, estimateTokens, exportHistory, findLatestReport, findLatestScanReport, formatAcceptanceRate, formatCost, formatHours, generateValueChain, getElapsedTime, getFileCommitTimestamps, getFileExtension, getHistorySummary, getLineRangeLastModifiedCached, getModelPreset, getParser, getRepoMetadata, getSafetyIcon, getScoreBar, getSeverityBadge, getSeverityColor, getSeverityEnum, getSeverityLevel, getSeverityValue, getSupportedLanguages, getWasmPath, groupIssuesByFile, handleCLIError, handleJSONOutput, initTreeSitter, initializeParsers, isFileSupported, isSourceFile, loadConfig, loadMergedConfig, loadScoreHistory, mergeConfigWithDefaults, normalizeAnalysisResult, normalizeIssue, normalizeMetrics, normalizeSpokeOutput, parseFileExports, predictAcceptanceRate, readFileContent, resolveOutputPath, saveScoreEntry, scanEntries, scanFiles, setupParser, severityToAnnotationLevel, validateSpokeOutput, validateWithSchema };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as ToolName, S as ScanOptions, a as SpokeOutput, b as ToolScoringOutput, c as ToolOptions, d as Severity, A as AnalysisResult, E as ExportWithImports, F as FileImport, e as AIReadyConfig, I as Issue, M as Metrics, f as ModelContextTier, C as CostConfig, g as TokenBudget, P as ProductivityImpact, h as AcceptancePrediction, i as ComprehensionDifficulty, j as TechnicalValueChainSummary, k as TechnicalValueChain, L as LanguageParser, l as Language, m as ParseResult, N as NamingConvention, n as ExportInfo } from './client-
|
|
2
|
-
export { o as AIReadyConfigSchema, p as ASTNode, q as AnalysisResultSchema, r as AnalysisStatus, s as AnalysisStatusSchema, B as BusinessMetrics, t as COMMON_FINE_TUNING_OPTIONS, u as CONTEXT_TIER_THRESHOLDS, v as CommonASTNode, w as Config, D as DEFAULT_TOOL_WEIGHTS, x as FRIENDLY_TOOL_NAMES, y as FileContent, G as GLOBAL_INFRA_OPTIONS, z as GLOBAL_SCAN_OPTIONS, H as GraphData, J as GraphEdge, K as GraphIssueSeverity, O as GraphMetadata, Q as GraphNode, R as IssueSchema, U as IssueType, V as IssueTypeSchema, W as LANGUAGE_EXTENSIONS, X as LanguageConfig, Y as Lead, Z as LeadSchema, _ as LeadSource, $ as LeadSourceSchema, a0 as LeadSubmission, a1 as LeadSubmissionSchema, a2 as Location, a3 as LocationSchema, a4 as ManagedAccount, a5 as ManagedAccountSchema, a6 as MetricsSchema, a7 as ModelTier, a8 as ModelTierSchema, a9 as ParseError, aa as ParseStatistics, ab as ReadinessRating, ac as RecommendationPriority, ad as SCORING_PROFILES, ae as SIZE_ADJUSTED_THRESHOLDS, af as ScanResult, ag as ScoringConfig, ah as ScoringProfile, ai as ScoringResult, aj as SeveritySchema, ak as SourceLocation, al as SourceRange, am as SpokeOutputSchema, an as SpokeSummary, ao as SpokeSummarySchema, ap as TOOL_NAME_MAP, aq as ToolNameSchema, ar as ToolOutput, as as UnifiedReport, at as UnifiedReportSchema, au as calculateOverallScore, av as formatScore, aw as formatToolScore, ax as generateHTML, ay as getProjectSizeTier, az as getRating, aA as getRatingDisplay, aB as getRatingSlug, aC as getRatingWithContext, aD as getRecommendedThreshold, aE as getToolWeight, aF as normalizeToolName, aG as parseWeightString } from './client-
|
|
1
|
+
import { T as ToolName, S as ScanOptions, a as SpokeOutput, b as ToolScoringOutput, c as ToolOptions, d as Severity, A as AnalysisResult, E as ExportWithImports, F as FileImport, e as AIReadyConfig, I as Issue, M as Metrics, f as ModelContextTier, C as CostConfig, g as TokenBudget, P as ProductivityImpact, h as AcceptancePrediction, i as ComprehensionDifficulty, j as TechnicalValueChainSummary, k as TechnicalValueChain, L as LanguageParser, l as Language, m as ParseResult, N as NamingConvention, n as ExportInfo } from './client-BEoUYNLp.js';
|
|
2
|
+
export { o as AIReadyConfigSchema, p as ASTNode, q as AnalysisResultSchema, r as AnalysisStatus, s as AnalysisStatusSchema, B as BusinessMetrics, t as COMMON_FINE_TUNING_OPTIONS, u as CONTEXT_TIER_THRESHOLDS, v as CommonASTNode, w as Config, D as DEFAULT_TOOL_WEIGHTS, x as FRIENDLY_TOOL_NAMES, y as FileContent, G as GLOBAL_INFRA_OPTIONS, z as GLOBAL_SCAN_OPTIONS, H as GraphData, J as GraphEdge, K as GraphIssueSeverity, O as GraphMetadata, Q as GraphNode, R as IssueSchema, U as IssueType, V as IssueTypeSchema, W as LANGUAGE_EXTENSIONS, X as LanguageConfig, Y as Lead, Z as LeadSchema, _ as LeadSource, $ as LeadSourceSchema, a0 as LeadSubmission, a1 as LeadSubmissionSchema, a2 as Location, a3 as LocationSchema, a4 as ManagedAccount, a5 as ManagedAccountSchema, a6 as MetricsSchema, a7 as ModelTier, a8 as ModelTierSchema, a9 as ParseError, aa as ParseStatistics, ab as ReadinessRating, ac as RecommendationPriority, ad as SCORING_PROFILES, ae as SIZE_ADJUSTED_THRESHOLDS, af as ScanResult, ag as ScoringConfig, ah as ScoringProfile, ai as ScoringResult, aj as SeveritySchema, ak as SourceLocation, al as SourceRange, am as SpokeOutputSchema, an as SpokeSummary, ao as SpokeSummarySchema, ap as TOOL_NAME_MAP, aq as ToolNameSchema, ar as ToolOutput, as as UnifiedReport, at as UnifiedReportSchema, au as calculateOverallScore, av as formatScore, aw as formatToolScore, ax as generateHTML, ay as getProjectSizeTier, az as getRating, aA as getRatingDisplay, aB as getRatingSlug, aC as getRatingWithContext, aD as getRecommendedThreshold, aE as getToolWeight, aF as normalizeToolName, aG as parseWeightString } from './client-BEoUYNLp.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import * as Parser from 'web-tree-sitter';
|
|
5
5
|
|
|
@@ -1316,8 +1316,14 @@ declare function calculateAgentGrounding(params: {
|
|
|
1316
1316
|
* Testability Index Metrics.
|
|
1317
1317
|
* Measures how verifiable AI-generated changes are based on local testing infrastructure.
|
|
1318
1318
|
*
|
|
1319
|
-
* @lastUpdated 2026-03-
|
|
1319
|
+
* @lastUpdated 2026-03-19
|
|
1320
1320
|
*/
|
|
1321
|
+
interface FileTestability {
|
|
1322
|
+
filePath: string;
|
|
1323
|
+
score: number;
|
|
1324
|
+
purityScore: number;
|
|
1325
|
+
isEntryPoint: boolean;
|
|
1326
|
+
}
|
|
1321
1327
|
interface TestabilityIndex {
|
|
1322
1328
|
score: number;
|
|
1323
1329
|
rating: 'excellent' | 'good' | 'moderate' | 'poor' | 'unverifiable';
|
|
@@ -1330,6 +1336,10 @@ interface TestabilityIndex {
|
|
|
1330
1336
|
};
|
|
1331
1337
|
aiChangeSafetyRating: 'safe' | 'moderate-risk' | 'high-risk' | 'blind-risk';
|
|
1332
1338
|
recommendations: string[];
|
|
1339
|
+
/** Per-file testability metrics */
|
|
1340
|
+
fileMetrics?: FileTestability[];
|
|
1341
|
+
/** Score based only on library code (excluding CLI entry points) */
|
|
1342
|
+
libraryScore?: number;
|
|
1333
1343
|
}
|
|
1334
1344
|
/**
|
|
1335
1345
|
* Calculate the Testability Index for a project.
|
|
@@ -1345,6 +1355,7 @@ interface TestabilityIndex {
|
|
|
1345
1355
|
* @param params.totalInterfaces - Total number of interfaces analyzed.
|
|
1346
1356
|
* @param params.externalStateMutations - Count of nodes that mutate external state.
|
|
1347
1357
|
* @param params.hasTestFramework - Whether a testing framework (e.g., Vitest) is detected.
|
|
1358
|
+
* @param params.fileDetails - Optional per-file data for detailed analysis.
|
|
1348
1359
|
* @returns Comprehensive TestabilityIndex analysis.
|
|
1349
1360
|
*/
|
|
1350
1361
|
declare function calculateTestabilityIndex(params: {
|
|
@@ -1358,6 +1369,11 @@ declare function calculateTestabilityIndex(params: {
|
|
|
1358
1369
|
totalInterfaces: number;
|
|
1359
1370
|
externalStateMutations: number;
|
|
1360
1371
|
hasTestFramework: boolean;
|
|
1372
|
+
fileDetails?: Array<{
|
|
1373
|
+
filePath: string;
|
|
1374
|
+
pureFunctions: number;
|
|
1375
|
+
totalFunctions: number;
|
|
1376
|
+
}>;
|
|
1361
1377
|
}): TestabilityIndex;
|
|
1362
1378
|
|
|
1363
1379
|
/**
|
|
@@ -1638,4 +1654,4 @@ declare function severityToAnnotationLevel(severity: string): 'error' | 'warning
|
|
|
1638
1654
|
*/
|
|
1639
1655
|
declare function emitIssuesAsAnnotations(issues: any[]): void;
|
|
1640
1656
|
|
|
1641
|
-
export { AIReadyConfig, AcceptancePrediction, type AgentGroundingScore, type AiSignalClarity, type AiSignalClaritySignal, AnalysisResult, type CLIOptions, CSharpParser, type ChangeAmplificationScore, type CognitiveLoad, ComprehensionDifficulty, type ConceptCohesion, CostConfig, DEFAULT_COST_CONFIG, DEFAULT_EXCLUDE, type DependencyHealthScore, type DocDriftRisk, ExportInfo, ExportWithImports, FileImport, type FileWithDomain, GoParser, Issue, JavaParser, type KnowledgeConcentrationRisk, Language, LanguageParser, type LoadFactor, MODEL_PRICING_PRESETS, Metrics, ModelContextTier, type ModelPricingPreset, NamingConvention, ParseResult, ParserFactory, type PatternEntropy, ProductivityImpact, type ProviderFactoryConfig, PythonParser, SEVERITY_TIME_ESTIMATES, ScanOptions, type ScoreHistoryEntry, type ScoreTrend, type SemanticDistance, Severity, Severity as SeverityType, SpokeOutput, type TechnicalDebtInterest, TechnicalValueChain, TechnicalValueChainSummary, type TestabilityIndex, TokenBudget, ToolName, ToolOptions, type ToolProvider, ToolRegistry, ToolScoringOutput, TypeScriptParser, VAGUE_FILE_NAMES, buildSimpleProviderScore, buildSpokeOutput, calculateAgentGrounding, calculateAiSignalClarity, calculateBusinessROI, calculateChangeAmplification, calculateCognitiveLoad, calculateComprehensionDifficulty, calculateConceptCohesion, calculateDebtInterest, calculateDependencyHealth, calculateDocDrift, calculateExtendedFutureProofScore, calculateFutureProofScore, calculateImportSimilarity, calculateKnowledgeConcentration, calculateMonthlyCost, calculatePatternEntropy, calculateProductivityImpact, calculateSemanticDistance, calculateTechnicalValueChain, calculateTestabilityIndex, calculateTokenBudget, clearHistory, createProvider, emitAnnotation, emitIssuesAsAnnotations, emitProgress, estimateCostFromBudget, estimateTokens, exportHistory, findLatestReport, findLatestScanReport, formatAcceptanceRate, formatCost, formatHours, generateValueChain, getElapsedTime, getFileCommitTimestamps, getFileExtension, getHistorySummary, getLineRangeLastModifiedCached, getModelPreset, getParser, getRepoMetadata, getSafetyIcon, getScoreBar, getSeverityBadge, getSeverityColor, getSeverityEnum, getSeverityLevel, getSeverityValue, getSupportedLanguages, getWasmPath, groupIssuesByFile, handleCLIError, handleJSONOutput, initTreeSitter, initializeParsers, isFileSupported, isSourceFile, loadConfig, loadMergedConfig, loadScoreHistory, mergeConfigWithDefaults, normalizeAnalysisResult, normalizeIssue, normalizeMetrics, normalizeSpokeOutput, parseFileExports, predictAcceptanceRate, readFileContent, resolveOutputPath, saveScoreEntry, scanEntries, scanFiles, setupParser, severityToAnnotationLevel, validateSpokeOutput, validateWithSchema };
|
|
1657
|
+
export { AIReadyConfig, AcceptancePrediction, type AgentGroundingScore, type AiSignalClarity, type AiSignalClaritySignal, AnalysisResult, type CLIOptions, CSharpParser, type ChangeAmplificationScore, type CognitiveLoad, ComprehensionDifficulty, type ConceptCohesion, CostConfig, DEFAULT_COST_CONFIG, DEFAULT_EXCLUDE, type DependencyHealthScore, type DocDriftRisk, ExportInfo, ExportWithImports, FileImport, type FileTestability, type FileWithDomain, GoParser, Issue, JavaParser, type KnowledgeConcentrationRisk, Language, LanguageParser, type LoadFactor, MODEL_PRICING_PRESETS, Metrics, ModelContextTier, type ModelPricingPreset, NamingConvention, ParseResult, ParserFactory, type PatternEntropy, ProductivityImpact, type ProviderFactoryConfig, PythonParser, SEVERITY_TIME_ESTIMATES, ScanOptions, type ScoreHistoryEntry, type ScoreTrend, type SemanticDistance, Severity, Severity as SeverityType, SpokeOutput, type TechnicalDebtInterest, TechnicalValueChain, TechnicalValueChainSummary, type TestabilityIndex, TokenBudget, ToolName, ToolOptions, type ToolProvider, ToolRegistry, ToolScoringOutput, TypeScriptParser, VAGUE_FILE_NAMES, buildSimpleProviderScore, buildSpokeOutput, calculateAgentGrounding, calculateAiSignalClarity, calculateBusinessROI, calculateChangeAmplification, calculateCognitiveLoad, calculateComprehensionDifficulty, calculateConceptCohesion, calculateDebtInterest, calculateDependencyHealth, calculateDocDrift, calculateExtendedFutureProofScore, calculateFutureProofScore, calculateImportSimilarity, calculateKnowledgeConcentration, calculateMonthlyCost, calculatePatternEntropy, calculateProductivityImpact, calculateSemanticDistance, calculateTechnicalValueChain, calculateTestabilityIndex, calculateTokenBudget, clearHistory, createProvider, emitAnnotation, emitIssuesAsAnnotations, emitProgress, estimateCostFromBudget, estimateTokens, exportHistory, findLatestReport, findLatestScanReport, formatAcceptanceRate, formatCost, formatHours, generateValueChain, getElapsedTime, getFileCommitTimestamps, getFileExtension, getHistorySummary, getLineRangeLastModifiedCached, getModelPreset, getParser, getRepoMetadata, getSafetyIcon, getScoreBar, getSeverityBadge, getSeverityColor, getSeverityEnum, getSeverityLevel, getSeverityValue, getSupportedLanguages, getWasmPath, groupIssuesByFile, handleCLIError, handleJSONOutput, initTreeSitter, initializeParsers, isFileSupported, isSourceFile, loadConfig, loadMergedConfig, loadScoreHistory, mergeConfigWithDefaults, normalizeAnalysisResult, normalizeIssue, normalizeMetrics, normalizeSpokeOutput, parseFileExports, predictAcceptanceRate, readFileContent, resolveOutputPath, saveScoreEntry, scanEntries, scanFiles, setupParser, severityToAnnotationLevel, validateSpokeOutput, validateWithSchema };
|
package/dist/index.js
CHANGED
|
@@ -372,8 +372,16 @@ var AIReadyConfigSchema = import_zod.z.object({
|
|
|
372
372
|
profile: import_zod.z.string().optional(),
|
|
373
373
|
/** Custom weights for tools and metrics */
|
|
374
374
|
weights: import_zod.z.record(import_zod.z.string(), import_zod.z.number()).optional()
|
|
375
|
+
}).optional(),
|
|
376
|
+
/** Visualizer settings (interactive graph) */
|
|
377
|
+
visualizer: import_zod.z.object({
|
|
378
|
+
groupingDirs: import_zod.z.array(import_zod.z.string()).optional(),
|
|
379
|
+
graph: import_zod.z.object({
|
|
380
|
+
maxNodes: import_zod.z.number().optional(),
|
|
381
|
+
maxEdges: import_zod.z.number().optional()
|
|
382
|
+
}).optional()
|
|
375
383
|
}).optional()
|
|
376
|
-
});
|
|
384
|
+
}).catchall(import_zod.z.any());
|
|
377
385
|
|
|
378
386
|
// src/types/business.ts
|
|
379
387
|
var import_zod2 = require("zod");
|
|
@@ -4682,6 +4690,40 @@ function calculateAgentGrounding(params) {
|
|
|
4682
4690
|
}
|
|
4683
4691
|
|
|
4684
4692
|
// src/metrics/testability-index.ts
|
|
4693
|
+
function isLikelyEntryPoint(filePath) {
|
|
4694
|
+
const basename = filePath.split("/").pop() || "";
|
|
4695
|
+
const lowerBasename = basename.toLowerCase();
|
|
4696
|
+
const entryPointPatterns = [
|
|
4697
|
+
"cli",
|
|
4698
|
+
"main",
|
|
4699
|
+
"bin",
|
|
4700
|
+
"index",
|
|
4701
|
+
// often used as entry point
|
|
4702
|
+
"run",
|
|
4703
|
+
"serve",
|
|
4704
|
+
"start",
|
|
4705
|
+
"boot",
|
|
4706
|
+
"init"
|
|
4707
|
+
];
|
|
4708
|
+
const nameWithoutExt = lowerBasename.replace(
|
|
4709
|
+
/\.(ts|js|tsx|jsx|mjs|cjs)$/,
|
|
4710
|
+
""
|
|
4711
|
+
);
|
|
4712
|
+
if (entryPointPatterns.some(
|
|
4713
|
+
(p) => nameWithoutExt === p || nameWithoutExt.endsWith(`-${p}`) || nameWithoutExt.startsWith(`${p}-`)
|
|
4714
|
+
)) {
|
|
4715
|
+
return true;
|
|
4716
|
+
}
|
|
4717
|
+
const cliDirPatterns = ["/bin/", "/cli/", "/cmd/", "/commands/"];
|
|
4718
|
+
if (cliDirPatterns.some((p) => filePath.includes(p))) {
|
|
4719
|
+
return true;
|
|
4720
|
+
}
|
|
4721
|
+
return false;
|
|
4722
|
+
}
|
|
4723
|
+
function calculateFilePurityScore(pureFunctions, totalFunctions) {
|
|
4724
|
+
if (totalFunctions === 0) return 100;
|
|
4725
|
+
return Math.round(pureFunctions / totalFunctions * 100);
|
|
4726
|
+
}
|
|
4685
4727
|
function calculateTestabilityIndex(params) {
|
|
4686
4728
|
const {
|
|
4687
4729
|
testFiles,
|
|
@@ -4693,7 +4735,8 @@ function calculateTestabilityIndex(params) {
|
|
|
4693
4735
|
bloatedInterfaces,
|
|
4694
4736
|
totalInterfaces,
|
|
4695
4737
|
externalStateMutations,
|
|
4696
|
-
hasTestFramework
|
|
4738
|
+
hasTestFramework,
|
|
4739
|
+
fileDetails
|
|
4697
4740
|
} = params;
|
|
4698
4741
|
const rawCoverageRatio = sourceFiles > 0 ? testFiles / sourceFiles : 0;
|
|
4699
4742
|
const testCoverageRatio = Math.min(100, Math.round(rawCoverageRatio * 100));
|
|
@@ -4719,7 +4762,39 @@ function calculateTestabilityIndex(params) {
|
|
|
4719
4762
|
)
|
|
4720
4763
|
);
|
|
4721
4764
|
const frameworkWeight = hasTestFramework ? 1 : 0.8;
|
|
4722
|
-
|
|
4765
|
+
let fileMetrics;
|
|
4766
|
+
let libraryPureFunctions = pureFunctions;
|
|
4767
|
+
let libraryTotalFunctions = totalFunctions;
|
|
4768
|
+
let entryPointCount = 0;
|
|
4769
|
+
if (fileDetails && fileDetails.length > 0) {
|
|
4770
|
+
fileMetrics = fileDetails.map((file) => {
|
|
4771
|
+
const isEntryPoint = isLikelyEntryPoint(file.filePath);
|
|
4772
|
+
const purityScore2 = calculateFilePurityScore(
|
|
4773
|
+
file.pureFunctions,
|
|
4774
|
+
file.totalFunctions
|
|
4775
|
+
);
|
|
4776
|
+
if (isEntryPoint) {
|
|
4777
|
+
entryPointCount++;
|
|
4778
|
+
libraryPureFunctions -= file.pureFunctions;
|
|
4779
|
+
libraryTotalFunctions -= file.totalFunctions;
|
|
4780
|
+
}
|
|
4781
|
+
return {
|
|
4782
|
+
filePath: file.filePath,
|
|
4783
|
+
score: purityScore2,
|
|
4784
|
+
// Simplified - just purity for file-level
|
|
4785
|
+
purityScore: purityScore2,
|
|
4786
|
+
isEntryPoint
|
|
4787
|
+
};
|
|
4788
|
+
});
|
|
4789
|
+
}
|
|
4790
|
+
const libraryPurityScore = Math.max(
|
|
4791
|
+
0,
|
|
4792
|
+
Math.round(
|
|
4793
|
+
(libraryTotalFunctions > 0 ? libraryPureFunctions / libraryTotalFunctions : 0.7) * 100
|
|
4794
|
+
)
|
|
4795
|
+
);
|
|
4796
|
+
const effectivePurityScore = fileDetails && fileDetails.length > 0 ? libraryPurityScore : purityScore;
|
|
4797
|
+
const rawScore = (testCoverageRatio * 0.3 + effectivePurityScore * 0.25 + dependencyInjectionScore * 0.2 + interfaceFocusScore * 0.1 + observabilityScore * 0.15) * frameworkWeight;
|
|
4723
4798
|
const score = Math.max(0, Math.min(100, Math.round(rawScore)));
|
|
4724
4799
|
let rating;
|
|
4725
4800
|
if (score >= 85) rating = "excellent";
|
|
@@ -4744,9 +4819,9 @@ function calculateTestabilityIndex(params) {
|
|
|
4744
4819
|
`Add ~${neededTests} test files to reach 30% coverage ratio \u2014 minimum for safe AI assistance`
|
|
4745
4820
|
);
|
|
4746
4821
|
}
|
|
4747
|
-
if (
|
|
4822
|
+
if (effectivePurityScore < 50)
|
|
4748
4823
|
recommendations.push(
|
|
4749
|
-
"Extract pure functions from side-effectful code \u2014 pure functions are trivially AI-testable"
|
|
4824
|
+
entryPointCount > 0 ? `Extract pure functions from library code (${entryPointCount} entry point files excluded) \u2014 pure functions are trivially AI-testable` : "Extract pure functions from side-effectful code \u2014 pure functions are trivially AI-testable"
|
|
4750
4825
|
);
|
|
4751
4826
|
if (dependencyInjectionScore < 50 && totalClasses > 0)
|
|
4752
4827
|
recommendations.push(
|
|
@@ -4761,13 +4836,15 @@ function calculateTestabilityIndex(params) {
|
|
|
4761
4836
|
rating,
|
|
4762
4837
|
dimensions: {
|
|
4763
4838
|
testCoverageRatio,
|
|
4764
|
-
purityScore,
|
|
4839
|
+
purityScore: effectivePurityScore,
|
|
4765
4840
|
dependencyInjectionScore,
|
|
4766
4841
|
interfaceFocusScore,
|
|
4767
4842
|
observabilityScore
|
|
4768
4843
|
},
|
|
4769
4844
|
aiChangeSafetyRating,
|
|
4770
|
-
recommendations
|
|
4845
|
+
recommendations,
|
|
4846
|
+
fileMetrics,
|
|
4847
|
+
libraryScore: Math.max(0, fileMetrics ? libraryPurityScore : purityScore)
|
|
4771
4848
|
};
|
|
4772
4849
|
}
|
|
4773
4850
|
|
package/dist/index.mjs
CHANGED
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
getToolWeight,
|
|
51
51
|
normalizeToolName,
|
|
52
52
|
parseWeightString
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-CGOS2J6T.mjs";
|
|
54
54
|
|
|
55
55
|
// src/utils/normalization.ts
|
|
56
56
|
function normalizeIssue(raw) {
|
|
@@ -3818,6 +3818,40 @@ function calculateAgentGrounding(params) {
|
|
|
3818
3818
|
}
|
|
3819
3819
|
|
|
3820
3820
|
// src/metrics/testability-index.ts
|
|
3821
|
+
function isLikelyEntryPoint(filePath) {
|
|
3822
|
+
const basename = filePath.split("/").pop() || "";
|
|
3823
|
+
const lowerBasename = basename.toLowerCase();
|
|
3824
|
+
const entryPointPatterns = [
|
|
3825
|
+
"cli",
|
|
3826
|
+
"main",
|
|
3827
|
+
"bin",
|
|
3828
|
+
"index",
|
|
3829
|
+
// often used as entry point
|
|
3830
|
+
"run",
|
|
3831
|
+
"serve",
|
|
3832
|
+
"start",
|
|
3833
|
+
"boot",
|
|
3834
|
+
"init"
|
|
3835
|
+
];
|
|
3836
|
+
const nameWithoutExt = lowerBasename.replace(
|
|
3837
|
+
/\.(ts|js|tsx|jsx|mjs|cjs)$/,
|
|
3838
|
+
""
|
|
3839
|
+
);
|
|
3840
|
+
if (entryPointPatterns.some(
|
|
3841
|
+
(p) => nameWithoutExt === p || nameWithoutExt.endsWith(`-${p}`) || nameWithoutExt.startsWith(`${p}-`)
|
|
3842
|
+
)) {
|
|
3843
|
+
return true;
|
|
3844
|
+
}
|
|
3845
|
+
const cliDirPatterns = ["/bin/", "/cli/", "/cmd/", "/commands/"];
|
|
3846
|
+
if (cliDirPatterns.some((p) => filePath.includes(p))) {
|
|
3847
|
+
return true;
|
|
3848
|
+
}
|
|
3849
|
+
return false;
|
|
3850
|
+
}
|
|
3851
|
+
function calculateFilePurityScore(pureFunctions, totalFunctions) {
|
|
3852
|
+
if (totalFunctions === 0) return 100;
|
|
3853
|
+
return Math.round(pureFunctions / totalFunctions * 100);
|
|
3854
|
+
}
|
|
3821
3855
|
function calculateTestabilityIndex(params) {
|
|
3822
3856
|
const {
|
|
3823
3857
|
testFiles,
|
|
@@ -3829,7 +3863,8 @@ function calculateTestabilityIndex(params) {
|
|
|
3829
3863
|
bloatedInterfaces,
|
|
3830
3864
|
totalInterfaces,
|
|
3831
3865
|
externalStateMutations,
|
|
3832
|
-
hasTestFramework
|
|
3866
|
+
hasTestFramework,
|
|
3867
|
+
fileDetails
|
|
3833
3868
|
} = params;
|
|
3834
3869
|
const rawCoverageRatio = sourceFiles > 0 ? testFiles / sourceFiles : 0;
|
|
3835
3870
|
const testCoverageRatio = Math.min(100, Math.round(rawCoverageRatio * 100));
|
|
@@ -3855,7 +3890,39 @@ function calculateTestabilityIndex(params) {
|
|
|
3855
3890
|
)
|
|
3856
3891
|
);
|
|
3857
3892
|
const frameworkWeight = hasTestFramework ? 1 : 0.8;
|
|
3858
|
-
|
|
3893
|
+
let fileMetrics;
|
|
3894
|
+
let libraryPureFunctions = pureFunctions;
|
|
3895
|
+
let libraryTotalFunctions = totalFunctions;
|
|
3896
|
+
let entryPointCount = 0;
|
|
3897
|
+
if (fileDetails && fileDetails.length > 0) {
|
|
3898
|
+
fileMetrics = fileDetails.map((file) => {
|
|
3899
|
+
const isEntryPoint = isLikelyEntryPoint(file.filePath);
|
|
3900
|
+
const purityScore2 = calculateFilePurityScore(
|
|
3901
|
+
file.pureFunctions,
|
|
3902
|
+
file.totalFunctions
|
|
3903
|
+
);
|
|
3904
|
+
if (isEntryPoint) {
|
|
3905
|
+
entryPointCount++;
|
|
3906
|
+
libraryPureFunctions -= file.pureFunctions;
|
|
3907
|
+
libraryTotalFunctions -= file.totalFunctions;
|
|
3908
|
+
}
|
|
3909
|
+
return {
|
|
3910
|
+
filePath: file.filePath,
|
|
3911
|
+
score: purityScore2,
|
|
3912
|
+
// Simplified - just purity for file-level
|
|
3913
|
+
purityScore: purityScore2,
|
|
3914
|
+
isEntryPoint
|
|
3915
|
+
};
|
|
3916
|
+
});
|
|
3917
|
+
}
|
|
3918
|
+
const libraryPurityScore = Math.max(
|
|
3919
|
+
0,
|
|
3920
|
+
Math.round(
|
|
3921
|
+
(libraryTotalFunctions > 0 ? libraryPureFunctions / libraryTotalFunctions : 0.7) * 100
|
|
3922
|
+
)
|
|
3923
|
+
);
|
|
3924
|
+
const effectivePurityScore = fileDetails && fileDetails.length > 0 ? libraryPurityScore : purityScore;
|
|
3925
|
+
const rawScore = (testCoverageRatio * 0.3 + effectivePurityScore * 0.25 + dependencyInjectionScore * 0.2 + interfaceFocusScore * 0.1 + observabilityScore * 0.15) * frameworkWeight;
|
|
3859
3926
|
const score = Math.max(0, Math.min(100, Math.round(rawScore)));
|
|
3860
3927
|
let rating;
|
|
3861
3928
|
if (score >= 85) rating = "excellent";
|
|
@@ -3880,9 +3947,9 @@ function calculateTestabilityIndex(params) {
|
|
|
3880
3947
|
`Add ~${neededTests} test files to reach 30% coverage ratio \u2014 minimum for safe AI assistance`
|
|
3881
3948
|
);
|
|
3882
3949
|
}
|
|
3883
|
-
if (
|
|
3950
|
+
if (effectivePurityScore < 50)
|
|
3884
3951
|
recommendations.push(
|
|
3885
|
-
"Extract pure functions from side-effectful code \u2014 pure functions are trivially AI-testable"
|
|
3952
|
+
entryPointCount > 0 ? `Extract pure functions from library code (${entryPointCount} entry point files excluded) \u2014 pure functions are trivially AI-testable` : "Extract pure functions from side-effectful code \u2014 pure functions are trivially AI-testable"
|
|
3886
3953
|
);
|
|
3887
3954
|
if (dependencyInjectionScore < 50 && totalClasses > 0)
|
|
3888
3955
|
recommendations.push(
|
|
@@ -3897,13 +3964,15 @@ function calculateTestabilityIndex(params) {
|
|
|
3897
3964
|
rating,
|
|
3898
3965
|
dimensions: {
|
|
3899
3966
|
testCoverageRatio,
|
|
3900
|
-
purityScore,
|
|
3967
|
+
purityScore: effectivePurityScore,
|
|
3901
3968
|
dependencyInjectionScore,
|
|
3902
3969
|
interfaceFocusScore,
|
|
3903
3970
|
observabilityScore
|
|
3904
3971
|
},
|
|
3905
3972
|
aiChangeSafetyRating,
|
|
3906
|
-
recommendations
|
|
3973
|
+
recommendations,
|
|
3974
|
+
fileMetrics,
|
|
3975
|
+
libraryScore: Math.max(0, fileMetrics ? libraryPurityScore : purityScore)
|
|
3907
3976
|
};
|
|
3908
3977
|
}
|
|
3909
3978
|
|