@aiready/core 0.7.7 → 0.7.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/index.d.mts +139 -1
- package/dist/index.d.ts +139 -1
- package/dist/index.js +165 -0
- package/dist/index.mjs +155 -0
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -34,9 +34,12 @@ interface AIReadyConfig {
|
|
|
34
34
|
scan?: {
|
|
35
35
|
include?: string[];
|
|
36
36
|
exclude?: string[];
|
|
37
|
+
tools?: string[];
|
|
37
38
|
};
|
|
38
39
|
tools?: {
|
|
39
40
|
'pattern-detect'?: {
|
|
41
|
+
enabled?: boolean;
|
|
42
|
+
scoreWeight?: number;
|
|
40
43
|
minSimilarity?: number;
|
|
41
44
|
minLines?: number;
|
|
42
45
|
batchSize?: number;
|
|
@@ -47,6 +50,8 @@ interface AIReadyConfig {
|
|
|
47
50
|
maxResults?: number;
|
|
48
51
|
};
|
|
49
52
|
'context-analyzer'?: {
|
|
53
|
+
enabled?: boolean;
|
|
54
|
+
scoreWeight?: number;
|
|
50
55
|
maxDepth?: number;
|
|
51
56
|
maxContextBudget?: number;
|
|
52
57
|
minCohesion?: number;
|
|
@@ -59,10 +64,23 @@ interface AIReadyConfig {
|
|
|
59
64
|
pathDomainMap?: Record<string, string>;
|
|
60
65
|
};
|
|
61
66
|
'consistency'?: {
|
|
67
|
+
enabled?: boolean;
|
|
68
|
+
scoreWeight?: number;
|
|
62
69
|
acceptedAbbreviations?: string[];
|
|
63
70
|
shortWords?: string[];
|
|
64
71
|
disableChecks?: ('single-letter' | 'abbreviation' | 'convention-mix' | 'unclear' | 'poor-naming')[];
|
|
65
72
|
};
|
|
73
|
+
[toolName: string]: {
|
|
74
|
+
enabled?: boolean;
|
|
75
|
+
scoreWeight?: number;
|
|
76
|
+
[key: string]: any;
|
|
77
|
+
} | undefined;
|
|
78
|
+
};
|
|
79
|
+
scoring?: {
|
|
80
|
+
threshold?: number;
|
|
81
|
+
showBreakdown?: boolean;
|
|
82
|
+
compareBaseline?: string;
|
|
83
|
+
saveTo?: string;
|
|
66
84
|
};
|
|
67
85
|
output?: {
|
|
68
86
|
format?: 'console' | 'json' | 'html';
|
|
@@ -85,6 +103,16 @@ interface Report {
|
|
|
85
103
|
}
|
|
86
104
|
|
|
87
105
|
declare const DEFAULT_EXCLUDE: string[];
|
|
106
|
+
/**
|
|
107
|
+
* Scan files in a directory using glob patterns
|
|
108
|
+
*
|
|
109
|
+
* Note: This scanner includes multiple language file types by default (.ts, .tsx, .js, .jsx, .py, .java)
|
|
110
|
+
* to support potential multi-language analysis in the future. Individual tools (like @aiready/consistency)
|
|
111
|
+
* should filter to their supported languages before processing.
|
|
112
|
+
*
|
|
113
|
+
* @param options - Scan configuration
|
|
114
|
+
* @returns Array of absolute file paths matching the patterns
|
|
115
|
+
*/
|
|
88
116
|
declare function scanFiles(options: ScanOptions): Promise<string[]>;
|
|
89
117
|
declare function readFileContent(filePath: string): Promise<string>;
|
|
90
118
|
declare function getFileExtension(filePath: string): string;
|
|
@@ -186,4 +214,114 @@ declare function handleCLIError(error: unknown, commandName: string): never;
|
|
|
186
214
|
*/
|
|
187
215
|
declare function getElapsedTime(startTime: number): string;
|
|
188
216
|
|
|
189
|
-
|
|
217
|
+
/**
|
|
218
|
+
* AI Readiness Scoring System
|
|
219
|
+
*
|
|
220
|
+
* Provides dynamic, composable scoring across multiple analysis tools.
|
|
221
|
+
* Each tool contributes a 0-100 score with configurable weights.
|
|
222
|
+
*/
|
|
223
|
+
interface ToolScoringOutput {
|
|
224
|
+
/** Unique tool identifier (e.g., "pattern-detect") */
|
|
225
|
+
toolName: string;
|
|
226
|
+
/** Normalized 0-100 score for this tool */
|
|
227
|
+
score: number;
|
|
228
|
+
/** Raw metrics used to calculate the score */
|
|
229
|
+
rawMetrics: Record<string, any>;
|
|
230
|
+
/** Factors that influenced the score */
|
|
231
|
+
factors: Array<{
|
|
232
|
+
name: string;
|
|
233
|
+
impact: number;
|
|
234
|
+
description: string;
|
|
235
|
+
}>;
|
|
236
|
+
/** Actionable recommendations with estimated impact */
|
|
237
|
+
recommendations: Array<{
|
|
238
|
+
action: string;
|
|
239
|
+
estimatedImpact: number;
|
|
240
|
+
priority: 'high' | 'medium' | 'low';
|
|
241
|
+
}>;
|
|
242
|
+
}
|
|
243
|
+
interface ScoringResult {
|
|
244
|
+
/** Overall AI Readiness Score (0-100) */
|
|
245
|
+
overall: number;
|
|
246
|
+
/** Rating category */
|
|
247
|
+
rating: 'Excellent' | 'Good' | 'Fair' | 'Needs Work' | 'Critical';
|
|
248
|
+
/** Timestamp of score calculation */
|
|
249
|
+
timestamp: string;
|
|
250
|
+
/** Tools that contributed to this score */
|
|
251
|
+
toolsUsed: string[];
|
|
252
|
+
/** Breakdown by tool */
|
|
253
|
+
breakdown: ToolScoringOutput[];
|
|
254
|
+
/** Calculation details */
|
|
255
|
+
calculation: {
|
|
256
|
+
formula: string;
|
|
257
|
+
weights: Record<string, number>;
|
|
258
|
+
normalized: string;
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
interface ScoringConfig {
|
|
262
|
+
/** Minimum passing score (exit code 1 if below) */
|
|
263
|
+
threshold?: number;
|
|
264
|
+
/** Show detailed breakdown in output */
|
|
265
|
+
showBreakdown?: boolean;
|
|
266
|
+
/** Path to baseline JSON for comparison */
|
|
267
|
+
compareBaseline?: string;
|
|
268
|
+
/** Auto-save score to this path */
|
|
269
|
+
saveTo?: string;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Default weights for known tools.
|
|
273
|
+
* New tools get weight of 10 if not specified.
|
|
274
|
+
*/
|
|
275
|
+
declare const DEFAULT_TOOL_WEIGHTS: Record<string, number>;
|
|
276
|
+
/**
|
|
277
|
+
* Tool name normalization map (shorthand -> full name)
|
|
278
|
+
*/
|
|
279
|
+
declare const TOOL_NAME_MAP: Record<string, string>;
|
|
280
|
+
/**
|
|
281
|
+
* Normalize tool name from shorthand to full name
|
|
282
|
+
*/
|
|
283
|
+
declare function normalizeToolName(shortName: string): string;
|
|
284
|
+
/**
|
|
285
|
+
* Get tool weight with fallback priority:
|
|
286
|
+
* 1. CLI override
|
|
287
|
+
* 2. Tool config scoreWeight
|
|
288
|
+
* 3. Default weight
|
|
289
|
+
* 4. 10 (for unknown tools)
|
|
290
|
+
*/
|
|
291
|
+
declare function getToolWeight(toolName: string, toolConfig?: {
|
|
292
|
+
scoreWeight?: number;
|
|
293
|
+
}, cliOverride?: number): number;
|
|
294
|
+
/**
|
|
295
|
+
* Parse weight string from CLI (e.g., "patterns:50,context:30")
|
|
296
|
+
*/
|
|
297
|
+
declare function parseWeightString(weightStr?: string): Map<string, number>;
|
|
298
|
+
/**
|
|
299
|
+
* Calculate overall AI Readiness Score from multiple tool scores.
|
|
300
|
+
*
|
|
301
|
+
* Formula: Σ(tool_score × tool_weight) / Σ(active_tool_weights)
|
|
302
|
+
*
|
|
303
|
+
* This allows dynamic composition - score adjusts automatically
|
|
304
|
+
* based on which tools actually ran.
|
|
305
|
+
*/
|
|
306
|
+
declare function calculateOverallScore(toolOutputs: Map<string, ToolScoringOutput>, config?: any, cliWeights?: Map<string, number>): ScoringResult;
|
|
307
|
+
/**
|
|
308
|
+
* Convert numeric score to rating category
|
|
309
|
+
*/
|
|
310
|
+
declare function getRating(score: number): ScoringResult['rating'];
|
|
311
|
+
/**
|
|
312
|
+
* Get rating emoji and color for display
|
|
313
|
+
*/
|
|
314
|
+
declare function getRatingDisplay(rating: ScoringResult['rating']): {
|
|
315
|
+
emoji: string;
|
|
316
|
+
color: string;
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* Format score for display with rating
|
|
320
|
+
*/
|
|
321
|
+
declare function formatScore(result: ScoringResult): string;
|
|
322
|
+
/**
|
|
323
|
+
* Format individual tool score for display
|
|
324
|
+
*/
|
|
325
|
+
declare function formatToolScore(output: ToolScoringOutput): string;
|
|
326
|
+
|
|
327
|
+
export { type AIReadyConfig, type ASTNode, type AnalysisResult, type CLIOptions, DEFAULT_EXCLUDE, DEFAULT_TOOL_WEIGHTS, type ExportWithImports, type FileImport, type Issue, type IssueType, type Location, type Metrics, type Report, type ScanOptions, type ScoringConfig, type ScoringResult, TOOL_NAME_MAP, type ToolScoringOutput, calculateImportSimilarity, calculateOverallScore, estimateTokens, extractFunctions, extractImports, formatScore, formatToolScore, getElapsedTime, getFileExtension, getRating, getRatingDisplay, getToolWeight, handleCLIError, handleJSONOutput, isSourceFile, loadConfig, loadMergedConfig, mergeConfigWithDefaults, normalizeToolName, parseCode, parseFileExports, parseWeightString, readFileContent, resolveOutputPath, scanFiles };
|
package/dist/index.d.ts
CHANGED
|
@@ -34,9 +34,12 @@ interface AIReadyConfig {
|
|
|
34
34
|
scan?: {
|
|
35
35
|
include?: string[];
|
|
36
36
|
exclude?: string[];
|
|
37
|
+
tools?: string[];
|
|
37
38
|
};
|
|
38
39
|
tools?: {
|
|
39
40
|
'pattern-detect'?: {
|
|
41
|
+
enabled?: boolean;
|
|
42
|
+
scoreWeight?: number;
|
|
40
43
|
minSimilarity?: number;
|
|
41
44
|
minLines?: number;
|
|
42
45
|
batchSize?: number;
|
|
@@ -47,6 +50,8 @@ interface AIReadyConfig {
|
|
|
47
50
|
maxResults?: number;
|
|
48
51
|
};
|
|
49
52
|
'context-analyzer'?: {
|
|
53
|
+
enabled?: boolean;
|
|
54
|
+
scoreWeight?: number;
|
|
50
55
|
maxDepth?: number;
|
|
51
56
|
maxContextBudget?: number;
|
|
52
57
|
minCohesion?: number;
|
|
@@ -59,10 +64,23 @@ interface AIReadyConfig {
|
|
|
59
64
|
pathDomainMap?: Record<string, string>;
|
|
60
65
|
};
|
|
61
66
|
'consistency'?: {
|
|
67
|
+
enabled?: boolean;
|
|
68
|
+
scoreWeight?: number;
|
|
62
69
|
acceptedAbbreviations?: string[];
|
|
63
70
|
shortWords?: string[];
|
|
64
71
|
disableChecks?: ('single-letter' | 'abbreviation' | 'convention-mix' | 'unclear' | 'poor-naming')[];
|
|
65
72
|
};
|
|
73
|
+
[toolName: string]: {
|
|
74
|
+
enabled?: boolean;
|
|
75
|
+
scoreWeight?: number;
|
|
76
|
+
[key: string]: any;
|
|
77
|
+
} | undefined;
|
|
78
|
+
};
|
|
79
|
+
scoring?: {
|
|
80
|
+
threshold?: number;
|
|
81
|
+
showBreakdown?: boolean;
|
|
82
|
+
compareBaseline?: string;
|
|
83
|
+
saveTo?: string;
|
|
66
84
|
};
|
|
67
85
|
output?: {
|
|
68
86
|
format?: 'console' | 'json' | 'html';
|
|
@@ -85,6 +103,16 @@ interface Report {
|
|
|
85
103
|
}
|
|
86
104
|
|
|
87
105
|
declare const DEFAULT_EXCLUDE: string[];
|
|
106
|
+
/**
|
|
107
|
+
* Scan files in a directory using glob patterns
|
|
108
|
+
*
|
|
109
|
+
* Note: This scanner includes multiple language file types by default (.ts, .tsx, .js, .jsx, .py, .java)
|
|
110
|
+
* to support potential multi-language analysis in the future. Individual tools (like @aiready/consistency)
|
|
111
|
+
* should filter to their supported languages before processing.
|
|
112
|
+
*
|
|
113
|
+
* @param options - Scan configuration
|
|
114
|
+
* @returns Array of absolute file paths matching the patterns
|
|
115
|
+
*/
|
|
88
116
|
declare function scanFiles(options: ScanOptions): Promise<string[]>;
|
|
89
117
|
declare function readFileContent(filePath: string): Promise<string>;
|
|
90
118
|
declare function getFileExtension(filePath: string): string;
|
|
@@ -186,4 +214,114 @@ declare function handleCLIError(error: unknown, commandName: string): never;
|
|
|
186
214
|
*/
|
|
187
215
|
declare function getElapsedTime(startTime: number): string;
|
|
188
216
|
|
|
189
|
-
|
|
217
|
+
/**
|
|
218
|
+
* AI Readiness Scoring System
|
|
219
|
+
*
|
|
220
|
+
* Provides dynamic, composable scoring across multiple analysis tools.
|
|
221
|
+
* Each tool contributes a 0-100 score with configurable weights.
|
|
222
|
+
*/
|
|
223
|
+
interface ToolScoringOutput {
|
|
224
|
+
/** Unique tool identifier (e.g., "pattern-detect") */
|
|
225
|
+
toolName: string;
|
|
226
|
+
/** Normalized 0-100 score for this tool */
|
|
227
|
+
score: number;
|
|
228
|
+
/** Raw metrics used to calculate the score */
|
|
229
|
+
rawMetrics: Record<string, any>;
|
|
230
|
+
/** Factors that influenced the score */
|
|
231
|
+
factors: Array<{
|
|
232
|
+
name: string;
|
|
233
|
+
impact: number;
|
|
234
|
+
description: string;
|
|
235
|
+
}>;
|
|
236
|
+
/** Actionable recommendations with estimated impact */
|
|
237
|
+
recommendations: Array<{
|
|
238
|
+
action: string;
|
|
239
|
+
estimatedImpact: number;
|
|
240
|
+
priority: 'high' | 'medium' | 'low';
|
|
241
|
+
}>;
|
|
242
|
+
}
|
|
243
|
+
interface ScoringResult {
|
|
244
|
+
/** Overall AI Readiness Score (0-100) */
|
|
245
|
+
overall: number;
|
|
246
|
+
/** Rating category */
|
|
247
|
+
rating: 'Excellent' | 'Good' | 'Fair' | 'Needs Work' | 'Critical';
|
|
248
|
+
/** Timestamp of score calculation */
|
|
249
|
+
timestamp: string;
|
|
250
|
+
/** Tools that contributed to this score */
|
|
251
|
+
toolsUsed: string[];
|
|
252
|
+
/** Breakdown by tool */
|
|
253
|
+
breakdown: ToolScoringOutput[];
|
|
254
|
+
/** Calculation details */
|
|
255
|
+
calculation: {
|
|
256
|
+
formula: string;
|
|
257
|
+
weights: Record<string, number>;
|
|
258
|
+
normalized: string;
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
interface ScoringConfig {
|
|
262
|
+
/** Minimum passing score (exit code 1 if below) */
|
|
263
|
+
threshold?: number;
|
|
264
|
+
/** Show detailed breakdown in output */
|
|
265
|
+
showBreakdown?: boolean;
|
|
266
|
+
/** Path to baseline JSON for comparison */
|
|
267
|
+
compareBaseline?: string;
|
|
268
|
+
/** Auto-save score to this path */
|
|
269
|
+
saveTo?: string;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Default weights for known tools.
|
|
273
|
+
* New tools get weight of 10 if not specified.
|
|
274
|
+
*/
|
|
275
|
+
declare const DEFAULT_TOOL_WEIGHTS: Record<string, number>;
|
|
276
|
+
/**
|
|
277
|
+
* Tool name normalization map (shorthand -> full name)
|
|
278
|
+
*/
|
|
279
|
+
declare const TOOL_NAME_MAP: Record<string, string>;
|
|
280
|
+
/**
|
|
281
|
+
* Normalize tool name from shorthand to full name
|
|
282
|
+
*/
|
|
283
|
+
declare function normalizeToolName(shortName: string): string;
|
|
284
|
+
/**
|
|
285
|
+
* Get tool weight with fallback priority:
|
|
286
|
+
* 1. CLI override
|
|
287
|
+
* 2. Tool config scoreWeight
|
|
288
|
+
* 3. Default weight
|
|
289
|
+
* 4. 10 (for unknown tools)
|
|
290
|
+
*/
|
|
291
|
+
declare function getToolWeight(toolName: string, toolConfig?: {
|
|
292
|
+
scoreWeight?: number;
|
|
293
|
+
}, cliOverride?: number): number;
|
|
294
|
+
/**
|
|
295
|
+
* Parse weight string from CLI (e.g., "patterns:50,context:30")
|
|
296
|
+
*/
|
|
297
|
+
declare function parseWeightString(weightStr?: string): Map<string, number>;
|
|
298
|
+
/**
|
|
299
|
+
* Calculate overall AI Readiness Score from multiple tool scores.
|
|
300
|
+
*
|
|
301
|
+
* Formula: Σ(tool_score × tool_weight) / Σ(active_tool_weights)
|
|
302
|
+
*
|
|
303
|
+
* This allows dynamic composition - score adjusts automatically
|
|
304
|
+
* based on which tools actually ran.
|
|
305
|
+
*/
|
|
306
|
+
declare function calculateOverallScore(toolOutputs: Map<string, ToolScoringOutput>, config?: any, cliWeights?: Map<string, number>): ScoringResult;
|
|
307
|
+
/**
|
|
308
|
+
* Convert numeric score to rating category
|
|
309
|
+
*/
|
|
310
|
+
declare function getRating(score: number): ScoringResult['rating'];
|
|
311
|
+
/**
|
|
312
|
+
* Get rating emoji and color for display
|
|
313
|
+
*/
|
|
314
|
+
declare function getRatingDisplay(rating: ScoringResult['rating']): {
|
|
315
|
+
emoji: string;
|
|
316
|
+
color: string;
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* Format score for display with rating
|
|
320
|
+
*/
|
|
321
|
+
declare function formatScore(result: ScoringResult): string;
|
|
322
|
+
/**
|
|
323
|
+
* Format individual tool score for display
|
|
324
|
+
*/
|
|
325
|
+
declare function formatToolScore(output: ToolScoringOutput): string;
|
|
326
|
+
|
|
327
|
+
export { type AIReadyConfig, type ASTNode, type AnalysisResult, type CLIOptions, DEFAULT_EXCLUDE, DEFAULT_TOOL_WEIGHTS, type ExportWithImports, type FileImport, type Issue, type IssueType, type Location, type Metrics, type Report, type ScanOptions, type ScoringConfig, type ScoringResult, TOOL_NAME_MAP, type ToolScoringOutput, calculateImportSimilarity, calculateOverallScore, estimateTokens, extractFunctions, extractImports, formatScore, formatToolScore, getElapsedTime, getFileExtension, getRating, getRatingDisplay, getToolWeight, handleCLIError, handleJSONOutput, isSourceFile, loadConfig, loadMergedConfig, mergeConfigWithDefaults, normalizeToolName, parseCode, parseFileExports, parseWeightString, readFileContent, resolveOutputPath, scanFiles };
|
package/dist/index.js
CHANGED
|
@@ -21,20 +21,30 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
DEFAULT_EXCLUDE: () => DEFAULT_EXCLUDE,
|
|
24
|
+
DEFAULT_TOOL_WEIGHTS: () => DEFAULT_TOOL_WEIGHTS,
|
|
25
|
+
TOOL_NAME_MAP: () => TOOL_NAME_MAP,
|
|
24
26
|
calculateImportSimilarity: () => calculateImportSimilarity,
|
|
27
|
+
calculateOverallScore: () => calculateOverallScore,
|
|
25
28
|
estimateTokens: () => estimateTokens,
|
|
26
29
|
extractFunctions: () => extractFunctions,
|
|
27
30
|
extractImports: () => extractImports,
|
|
31
|
+
formatScore: () => formatScore,
|
|
32
|
+
formatToolScore: () => formatToolScore,
|
|
28
33
|
getElapsedTime: () => getElapsedTime,
|
|
29
34
|
getFileExtension: () => getFileExtension,
|
|
35
|
+
getRating: () => getRating,
|
|
36
|
+
getRatingDisplay: () => getRatingDisplay,
|
|
37
|
+
getToolWeight: () => getToolWeight,
|
|
30
38
|
handleCLIError: () => handleCLIError,
|
|
31
39
|
handleJSONOutput: () => handleJSONOutput,
|
|
32
40
|
isSourceFile: () => isSourceFile,
|
|
33
41
|
loadConfig: () => loadConfig,
|
|
34
42
|
loadMergedConfig: () => loadMergedConfig,
|
|
35
43
|
mergeConfigWithDefaults: () => mergeConfigWithDefaults,
|
|
44
|
+
normalizeToolName: () => normalizeToolName,
|
|
36
45
|
parseCode: () => parseCode,
|
|
37
46
|
parseFileExports: () => parseFileExports,
|
|
47
|
+
parseWeightString: () => parseWeightString,
|
|
38
48
|
readFileContent: () => readFileContent,
|
|
39
49
|
resolveOutputPath: () => resolveOutputPath,
|
|
40
50
|
scanFiles: () => scanFiles
|
|
@@ -93,6 +103,7 @@ async function scanFiles(options) {
|
|
|
93
103
|
const {
|
|
94
104
|
rootDir,
|
|
95
105
|
include = ["**/*.{ts,tsx,js,jsx,py,java}"],
|
|
106
|
+
// Broad default - tools should filter further
|
|
96
107
|
exclude
|
|
97
108
|
} = options;
|
|
98
109
|
const finalExclude = exclude ? [.../* @__PURE__ */ new Set([...DEFAULT_EXCLUDE, ...exclude])] : DEFAULT_EXCLUDE;
|
|
@@ -408,23 +419,177 @@ function handleCLIError(error, commandName) {
|
|
|
408
419
|
function getElapsedTime(startTime) {
|
|
409
420
|
return ((Date.now() - startTime) / 1e3).toFixed(2);
|
|
410
421
|
}
|
|
422
|
+
|
|
423
|
+
// src/scoring.ts
|
|
424
|
+
var DEFAULT_TOOL_WEIGHTS = {
|
|
425
|
+
"pattern-detect": 40,
|
|
426
|
+
"context-analyzer": 35,
|
|
427
|
+
"consistency": 25,
|
|
428
|
+
"doc-drift": 20,
|
|
429
|
+
"deps": 15
|
|
430
|
+
};
|
|
431
|
+
var TOOL_NAME_MAP = {
|
|
432
|
+
"patterns": "pattern-detect",
|
|
433
|
+
"context": "context-analyzer",
|
|
434
|
+
"consistency": "consistency",
|
|
435
|
+
"doc-drift": "doc-drift",
|
|
436
|
+
"deps": "deps"
|
|
437
|
+
};
|
|
438
|
+
function normalizeToolName(shortName) {
|
|
439
|
+
return TOOL_NAME_MAP[shortName] || shortName;
|
|
440
|
+
}
|
|
441
|
+
function getToolWeight(toolName, toolConfig, cliOverride) {
|
|
442
|
+
if (cliOverride !== void 0) {
|
|
443
|
+
return cliOverride;
|
|
444
|
+
}
|
|
445
|
+
if (toolConfig?.scoreWeight !== void 0) {
|
|
446
|
+
return toolConfig.scoreWeight;
|
|
447
|
+
}
|
|
448
|
+
return DEFAULT_TOOL_WEIGHTS[toolName] || 10;
|
|
449
|
+
}
|
|
450
|
+
function parseWeightString(weightStr) {
|
|
451
|
+
const weights = /* @__PURE__ */ new Map();
|
|
452
|
+
if (!weightStr) {
|
|
453
|
+
return weights;
|
|
454
|
+
}
|
|
455
|
+
const pairs = weightStr.split(",");
|
|
456
|
+
for (const pair of pairs) {
|
|
457
|
+
const [toolShortName, weightStr2] = pair.split(":");
|
|
458
|
+
if (toolShortName && weightStr2) {
|
|
459
|
+
const toolName = normalizeToolName(toolShortName.trim());
|
|
460
|
+
const weight = parseInt(weightStr2.trim(), 10);
|
|
461
|
+
if (!isNaN(weight) && weight > 0) {
|
|
462
|
+
weights.set(toolName, weight);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
return weights;
|
|
467
|
+
}
|
|
468
|
+
function calculateOverallScore(toolOutputs, config, cliWeights) {
|
|
469
|
+
if (toolOutputs.size === 0) {
|
|
470
|
+
throw new Error("No tool outputs provided for scoring");
|
|
471
|
+
}
|
|
472
|
+
const weights = /* @__PURE__ */ new Map();
|
|
473
|
+
for (const [toolName] of toolOutputs.entries()) {
|
|
474
|
+
const cliWeight = cliWeights?.get(toolName);
|
|
475
|
+
const configWeight = config?.tools?.[toolName]?.scoreWeight;
|
|
476
|
+
const weight = cliWeight ?? configWeight ?? DEFAULT_TOOL_WEIGHTS[toolName] ?? 10;
|
|
477
|
+
weights.set(toolName, weight);
|
|
478
|
+
}
|
|
479
|
+
let weightedSum = 0;
|
|
480
|
+
let totalWeight = 0;
|
|
481
|
+
const breakdown = [];
|
|
482
|
+
const toolsUsed = [];
|
|
483
|
+
const calculationWeights = {};
|
|
484
|
+
for (const [toolName, output] of toolOutputs.entries()) {
|
|
485
|
+
const weight = weights.get(toolName) || 10;
|
|
486
|
+
const weightedScore = output.score * weight;
|
|
487
|
+
weightedSum += weightedScore;
|
|
488
|
+
totalWeight += weight;
|
|
489
|
+
toolsUsed.push(toolName);
|
|
490
|
+
calculationWeights[toolName] = weight;
|
|
491
|
+
breakdown.push(output);
|
|
492
|
+
}
|
|
493
|
+
const overall = Math.round(weightedSum / totalWeight);
|
|
494
|
+
const rating = getRating(overall);
|
|
495
|
+
const formulaParts = Array.from(toolOutputs.entries()).map(([name, output]) => {
|
|
496
|
+
const w = weights.get(name) || 10;
|
|
497
|
+
return `(${output.score} \xD7 ${w})`;
|
|
498
|
+
});
|
|
499
|
+
const formulaStr = `[${formulaParts.join(" + ")}] / ${totalWeight} = ${overall}`;
|
|
500
|
+
return {
|
|
501
|
+
overall,
|
|
502
|
+
rating,
|
|
503
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
504
|
+
toolsUsed,
|
|
505
|
+
breakdown,
|
|
506
|
+
calculation: {
|
|
507
|
+
formula: formulaStr,
|
|
508
|
+
weights: calculationWeights,
|
|
509
|
+
normalized: formulaStr
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
function getRating(score) {
|
|
514
|
+
if (score >= 90) return "Excellent";
|
|
515
|
+
if (score >= 75) return "Good";
|
|
516
|
+
if (score >= 60) return "Fair";
|
|
517
|
+
if (score >= 40) return "Needs Work";
|
|
518
|
+
return "Critical";
|
|
519
|
+
}
|
|
520
|
+
function getRatingDisplay(rating) {
|
|
521
|
+
switch (rating) {
|
|
522
|
+
case "Excellent":
|
|
523
|
+
return { emoji: "\u2705", color: "green" };
|
|
524
|
+
case "Good":
|
|
525
|
+
return { emoji: "\u{1F44D}", color: "blue" };
|
|
526
|
+
case "Fair":
|
|
527
|
+
return { emoji: "\u26A0\uFE0F", color: "yellow" };
|
|
528
|
+
case "Needs Work":
|
|
529
|
+
return { emoji: "\u{1F528}", color: "orange" };
|
|
530
|
+
case "Critical":
|
|
531
|
+
return { emoji: "\u274C", color: "red" };
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
function formatScore(result) {
|
|
535
|
+
const { emoji, color } = getRatingDisplay(result.rating);
|
|
536
|
+
return `${result.overall}/100 (${result.rating}) ${emoji}`;
|
|
537
|
+
}
|
|
538
|
+
function formatToolScore(output) {
|
|
539
|
+
let result = ` Score: ${output.score}/100
|
|
540
|
+
|
|
541
|
+
`;
|
|
542
|
+
if (output.factors && output.factors.length > 0) {
|
|
543
|
+
result += ` Factors:
|
|
544
|
+
`;
|
|
545
|
+
output.factors.forEach((factor) => {
|
|
546
|
+
const impactSign = factor.impact > 0 ? "+" : "";
|
|
547
|
+
result += ` \u2022 ${factor.name}: ${impactSign}${factor.impact} - ${factor.description}
|
|
548
|
+
`;
|
|
549
|
+
});
|
|
550
|
+
result += "\n";
|
|
551
|
+
}
|
|
552
|
+
if (output.recommendations && output.recommendations.length > 0) {
|
|
553
|
+
result += ` Recommendations:
|
|
554
|
+
`;
|
|
555
|
+
output.recommendations.forEach((rec, i) => {
|
|
556
|
+
const priorityIcon = rec.priority === "high" ? "\u{1F534}" : rec.priority === "medium" ? "\u{1F7E1}" : "\u{1F535}";
|
|
557
|
+
result += ` ${i + 1}. ${priorityIcon} ${rec.action}
|
|
558
|
+
`;
|
|
559
|
+
result += ` Impact: +${rec.estimatedImpact} points
|
|
560
|
+
|
|
561
|
+
`;
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
return result;
|
|
565
|
+
}
|
|
411
566
|
// Annotate the CommonJS export names for ESM import in node:
|
|
412
567
|
0 && (module.exports = {
|
|
413
568
|
DEFAULT_EXCLUDE,
|
|
569
|
+
DEFAULT_TOOL_WEIGHTS,
|
|
570
|
+
TOOL_NAME_MAP,
|
|
414
571
|
calculateImportSimilarity,
|
|
572
|
+
calculateOverallScore,
|
|
415
573
|
estimateTokens,
|
|
416
574
|
extractFunctions,
|
|
417
575
|
extractImports,
|
|
576
|
+
formatScore,
|
|
577
|
+
formatToolScore,
|
|
418
578
|
getElapsedTime,
|
|
419
579
|
getFileExtension,
|
|
580
|
+
getRating,
|
|
581
|
+
getRatingDisplay,
|
|
582
|
+
getToolWeight,
|
|
420
583
|
handleCLIError,
|
|
421
584
|
handleJSONOutput,
|
|
422
585
|
isSourceFile,
|
|
423
586
|
loadConfig,
|
|
424
587
|
loadMergedConfig,
|
|
425
588
|
mergeConfigWithDefaults,
|
|
589
|
+
normalizeToolName,
|
|
426
590
|
parseCode,
|
|
427
591
|
parseFileExports,
|
|
592
|
+
parseWeightString,
|
|
428
593
|
readFileContent,
|
|
429
594
|
resolveOutputPath,
|
|
430
595
|
scanFiles
|
package/dist/index.mjs
CHANGED
|
@@ -50,6 +50,7 @@ async function scanFiles(options) {
|
|
|
50
50
|
const {
|
|
51
51
|
rootDir,
|
|
52
52
|
include = ["**/*.{ts,tsx,js,jsx,py,java}"],
|
|
53
|
+
// Broad default - tools should filter further
|
|
53
54
|
exclude
|
|
54
55
|
} = options;
|
|
55
56
|
const finalExclude = exclude ? [.../* @__PURE__ */ new Set([...DEFAULT_EXCLUDE, ...exclude])] : DEFAULT_EXCLUDE;
|
|
@@ -365,22 +366,176 @@ function handleCLIError(error, commandName) {
|
|
|
365
366
|
function getElapsedTime(startTime) {
|
|
366
367
|
return ((Date.now() - startTime) / 1e3).toFixed(2);
|
|
367
368
|
}
|
|
369
|
+
|
|
370
|
+
// src/scoring.ts
|
|
371
|
+
var DEFAULT_TOOL_WEIGHTS = {
|
|
372
|
+
"pattern-detect": 40,
|
|
373
|
+
"context-analyzer": 35,
|
|
374
|
+
"consistency": 25,
|
|
375
|
+
"doc-drift": 20,
|
|
376
|
+
"deps": 15
|
|
377
|
+
};
|
|
378
|
+
var TOOL_NAME_MAP = {
|
|
379
|
+
"patterns": "pattern-detect",
|
|
380
|
+
"context": "context-analyzer",
|
|
381
|
+
"consistency": "consistency",
|
|
382
|
+
"doc-drift": "doc-drift",
|
|
383
|
+
"deps": "deps"
|
|
384
|
+
};
|
|
385
|
+
function normalizeToolName(shortName) {
|
|
386
|
+
return TOOL_NAME_MAP[shortName] || shortName;
|
|
387
|
+
}
|
|
388
|
+
function getToolWeight(toolName, toolConfig, cliOverride) {
|
|
389
|
+
if (cliOverride !== void 0) {
|
|
390
|
+
return cliOverride;
|
|
391
|
+
}
|
|
392
|
+
if (toolConfig?.scoreWeight !== void 0) {
|
|
393
|
+
return toolConfig.scoreWeight;
|
|
394
|
+
}
|
|
395
|
+
return DEFAULT_TOOL_WEIGHTS[toolName] || 10;
|
|
396
|
+
}
|
|
397
|
+
function parseWeightString(weightStr) {
|
|
398
|
+
const weights = /* @__PURE__ */ new Map();
|
|
399
|
+
if (!weightStr) {
|
|
400
|
+
return weights;
|
|
401
|
+
}
|
|
402
|
+
const pairs = weightStr.split(",");
|
|
403
|
+
for (const pair of pairs) {
|
|
404
|
+
const [toolShortName, weightStr2] = pair.split(":");
|
|
405
|
+
if (toolShortName && weightStr2) {
|
|
406
|
+
const toolName = normalizeToolName(toolShortName.trim());
|
|
407
|
+
const weight = parseInt(weightStr2.trim(), 10);
|
|
408
|
+
if (!isNaN(weight) && weight > 0) {
|
|
409
|
+
weights.set(toolName, weight);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return weights;
|
|
414
|
+
}
|
|
415
|
+
function calculateOverallScore(toolOutputs, config, cliWeights) {
|
|
416
|
+
if (toolOutputs.size === 0) {
|
|
417
|
+
throw new Error("No tool outputs provided for scoring");
|
|
418
|
+
}
|
|
419
|
+
const weights = /* @__PURE__ */ new Map();
|
|
420
|
+
for (const [toolName] of toolOutputs.entries()) {
|
|
421
|
+
const cliWeight = cliWeights?.get(toolName);
|
|
422
|
+
const configWeight = config?.tools?.[toolName]?.scoreWeight;
|
|
423
|
+
const weight = cliWeight ?? configWeight ?? DEFAULT_TOOL_WEIGHTS[toolName] ?? 10;
|
|
424
|
+
weights.set(toolName, weight);
|
|
425
|
+
}
|
|
426
|
+
let weightedSum = 0;
|
|
427
|
+
let totalWeight = 0;
|
|
428
|
+
const breakdown = [];
|
|
429
|
+
const toolsUsed = [];
|
|
430
|
+
const calculationWeights = {};
|
|
431
|
+
for (const [toolName, output] of toolOutputs.entries()) {
|
|
432
|
+
const weight = weights.get(toolName) || 10;
|
|
433
|
+
const weightedScore = output.score * weight;
|
|
434
|
+
weightedSum += weightedScore;
|
|
435
|
+
totalWeight += weight;
|
|
436
|
+
toolsUsed.push(toolName);
|
|
437
|
+
calculationWeights[toolName] = weight;
|
|
438
|
+
breakdown.push(output);
|
|
439
|
+
}
|
|
440
|
+
const overall = Math.round(weightedSum / totalWeight);
|
|
441
|
+
const rating = getRating(overall);
|
|
442
|
+
const formulaParts = Array.from(toolOutputs.entries()).map(([name, output]) => {
|
|
443
|
+
const w = weights.get(name) || 10;
|
|
444
|
+
return `(${output.score} \xD7 ${w})`;
|
|
445
|
+
});
|
|
446
|
+
const formulaStr = `[${formulaParts.join(" + ")}] / ${totalWeight} = ${overall}`;
|
|
447
|
+
return {
|
|
448
|
+
overall,
|
|
449
|
+
rating,
|
|
450
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
451
|
+
toolsUsed,
|
|
452
|
+
breakdown,
|
|
453
|
+
calculation: {
|
|
454
|
+
formula: formulaStr,
|
|
455
|
+
weights: calculationWeights,
|
|
456
|
+
normalized: formulaStr
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
function getRating(score) {
|
|
461
|
+
if (score >= 90) return "Excellent";
|
|
462
|
+
if (score >= 75) return "Good";
|
|
463
|
+
if (score >= 60) return "Fair";
|
|
464
|
+
if (score >= 40) return "Needs Work";
|
|
465
|
+
return "Critical";
|
|
466
|
+
}
|
|
467
|
+
function getRatingDisplay(rating) {
|
|
468
|
+
switch (rating) {
|
|
469
|
+
case "Excellent":
|
|
470
|
+
return { emoji: "\u2705", color: "green" };
|
|
471
|
+
case "Good":
|
|
472
|
+
return { emoji: "\u{1F44D}", color: "blue" };
|
|
473
|
+
case "Fair":
|
|
474
|
+
return { emoji: "\u26A0\uFE0F", color: "yellow" };
|
|
475
|
+
case "Needs Work":
|
|
476
|
+
return { emoji: "\u{1F528}", color: "orange" };
|
|
477
|
+
case "Critical":
|
|
478
|
+
return { emoji: "\u274C", color: "red" };
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
function formatScore(result) {
|
|
482
|
+
const { emoji, color } = getRatingDisplay(result.rating);
|
|
483
|
+
return `${result.overall}/100 (${result.rating}) ${emoji}`;
|
|
484
|
+
}
|
|
485
|
+
function formatToolScore(output) {
|
|
486
|
+
let result = ` Score: ${output.score}/100
|
|
487
|
+
|
|
488
|
+
`;
|
|
489
|
+
if (output.factors && output.factors.length > 0) {
|
|
490
|
+
result += ` Factors:
|
|
491
|
+
`;
|
|
492
|
+
output.factors.forEach((factor) => {
|
|
493
|
+
const impactSign = factor.impact > 0 ? "+" : "";
|
|
494
|
+
result += ` \u2022 ${factor.name}: ${impactSign}${factor.impact} - ${factor.description}
|
|
495
|
+
`;
|
|
496
|
+
});
|
|
497
|
+
result += "\n";
|
|
498
|
+
}
|
|
499
|
+
if (output.recommendations && output.recommendations.length > 0) {
|
|
500
|
+
result += ` Recommendations:
|
|
501
|
+
`;
|
|
502
|
+
output.recommendations.forEach((rec, i) => {
|
|
503
|
+
const priorityIcon = rec.priority === "high" ? "\u{1F534}" : rec.priority === "medium" ? "\u{1F7E1}" : "\u{1F535}";
|
|
504
|
+
result += ` ${i + 1}. ${priorityIcon} ${rec.action}
|
|
505
|
+
`;
|
|
506
|
+
result += ` Impact: +${rec.estimatedImpact} points
|
|
507
|
+
|
|
508
|
+
`;
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
return result;
|
|
512
|
+
}
|
|
368
513
|
export {
|
|
369
514
|
DEFAULT_EXCLUDE,
|
|
515
|
+
DEFAULT_TOOL_WEIGHTS,
|
|
516
|
+
TOOL_NAME_MAP,
|
|
370
517
|
calculateImportSimilarity,
|
|
518
|
+
calculateOverallScore,
|
|
371
519
|
estimateTokens,
|
|
372
520
|
extractFunctions,
|
|
373
521
|
extractImports,
|
|
522
|
+
formatScore,
|
|
523
|
+
formatToolScore,
|
|
374
524
|
getElapsedTime,
|
|
375
525
|
getFileExtension,
|
|
526
|
+
getRating,
|
|
527
|
+
getRatingDisplay,
|
|
528
|
+
getToolWeight,
|
|
376
529
|
handleCLIError,
|
|
377
530
|
handleJSONOutput,
|
|
378
531
|
isSourceFile,
|
|
379
532
|
loadConfig,
|
|
380
533
|
loadMergedConfig,
|
|
381
534
|
mergeConfigWithDefaults,
|
|
535
|
+
normalizeToolName,
|
|
382
536
|
parseCode,
|
|
383
537
|
parseFileExports,
|
|
538
|
+
parseWeightString,
|
|
384
539
|
readFileContent,
|
|
385
540
|
resolveOutputPath,
|
|
386
541
|
scanFiles
|