@aiready/cli 0.9.40 → 0.9.41

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.
@@ -4,11 +4,11 @@
4
4
 
5
5
  import chalk from 'chalk';
6
6
  import { resolve as resolvePath } from 'path';
7
- import {
8
- loadMergedConfig,
9
- handleJSONOutput,
10
- handleCLIError,
11
- getElapsedTime,
7
+ import {
8
+ loadMergedConfig,
9
+ handleJSONOutput,
10
+ handleCLIError,
11
+ getElapsedTime,
12
12
  resolveOutputPath,
13
13
  formatToolScore,
14
14
  } from '@aiready/core';
@@ -25,7 +25,10 @@ interface ContextOptions {
25
25
  score?: boolean;
26
26
  }
27
27
 
28
- export async function contextAction(directory: string, options: ContextOptions) {
28
+ export async function contextAction(
29
+ directory: string,
30
+ options: ContextOptions
31
+ ) {
29
32
  console.log(chalk.blue('🧠 Analyzing context costs...\n'));
30
33
 
31
34
  const startTime = Date.now();
@@ -45,9 +48,11 @@ export async function contextAction(directory: string, options: ContextOptions)
45
48
  };
46
49
 
47
50
  // Load and merge config with CLI options
48
- let baseOptions = await loadMergedConfig(resolvedDir, defaults, {
51
+ const baseOptions = await loadMergedConfig(resolvedDir, defaults, {
49
52
  maxDepth: options.maxDepth ? parseInt(options.maxDepth) : undefined,
50
- maxContextBudget: options.maxContext ? parseInt(options.maxContext) : undefined,
53
+ maxContextBudget: options.maxContext
54
+ ? parseInt(options.maxContext)
55
+ : undefined,
51
56
  include: options.include?.split(','),
52
57
  exclude: options.exclude?.split(','),
53
58
  });
@@ -55,32 +60,41 @@ export async function contextAction(directory: string, options: ContextOptions)
55
60
  // Apply smart defaults for context analysis (always for individual context command)
56
61
  let finalOptions: any = { ...baseOptions };
57
62
  const { getSmartDefaults } = await import('@aiready/context-analyzer');
58
- const contextSmartDefaults = await getSmartDefaults(resolvedDir, baseOptions);
63
+ const contextSmartDefaults = await getSmartDefaults(
64
+ resolvedDir,
65
+ baseOptions
66
+ );
59
67
  finalOptions = { ...contextSmartDefaults, ...finalOptions };
60
-
68
+
61
69
  // Display configuration
62
70
  console.log('šŸ“‹ Configuration:');
63
71
  console.log(` Max depth: ${finalOptions.maxDepth}`);
64
72
  console.log(` Max context budget: ${finalOptions.maxContextBudget}`);
65
- console.log(` Min cohesion: ${(finalOptions.minCohesion * 100).toFixed(1)}%`);
66
- console.log(` Max fragmentation: ${(finalOptions.maxFragmentation * 100).toFixed(1)}%`);
73
+ console.log(
74
+ ` Min cohesion: ${(finalOptions.minCohesion * 100).toFixed(1)}%`
75
+ );
76
+ console.log(
77
+ ` Max fragmentation: ${(finalOptions.maxFragmentation * 100).toFixed(1)}%`
78
+ );
67
79
  console.log(` Analysis focus: ${finalOptions.focus}`);
68
80
  console.log('');
69
81
 
70
- const { analyzeContext, generateSummary, calculateContextScore } = await import('@aiready/context-analyzer');
82
+ const { analyzeContext, generateSummary, calculateContextScore } =
83
+ await import('@aiready/context-analyzer');
71
84
 
72
85
  const results = await analyzeContext(finalOptions);
73
86
 
74
87
  const elapsedTime = getElapsedTime(startTime);
75
88
  const summary = generateSummary(results);
76
-
89
+
77
90
  // Calculate score if requested
78
91
  let contextScore: ToolScoringOutput | undefined;
79
92
  if (options.score) {
80
93
  contextScore = calculateContextScore(summary as any);
81
94
  }
82
95
 
83
- const outputFormat = options.output || finalOptions.output?.format || 'console';
96
+ const outputFormat =
97
+ options.output || finalOptions.output?.format || 'console';
84
98
  const userOutputFile = options.outputFile || finalOptions.output?.file;
85
99
 
86
100
  if (outputFormat === 'json') {
@@ -95,8 +109,12 @@ export async function contextAction(directory: string, options: ContextOptions)
95
109
  `aiready-report-${getReportTimestamp()}.json`,
96
110
  resolvedDir
97
111
  );
98
-
99
- handleJSONOutput(outputData, outputPath, `āœ… Results saved to ${outputPath}`);
112
+
113
+ handleJSONOutput(
114
+ outputData,
115
+ outputPath,
116
+ `āœ… Results saved to ${outputPath}`
117
+ );
100
118
  } else {
101
119
  // Console output - format the results nicely
102
120
  const terminalWidth = process.stdout.columns || 80;
@@ -107,25 +125,48 @@ export async function contextAction(directory: string, options: ContextOptions)
107
125
  console.log(chalk.bold.white(' CONTEXT ANALYSIS SUMMARY'));
108
126
  console.log(chalk.cyan(divider) + '\n');
109
127
 
110
- console.log(chalk.white(`šŸ“ Files analyzed: ${chalk.bold(summary.totalFiles)}`));
111
- console.log(chalk.white(`šŸ“Š Total tokens: ${chalk.bold(summary.totalTokens.toLocaleString())}`));
112
- console.log(chalk.yellow(`šŸ’° Avg context budget: ${chalk.bold(summary.avgContextBudget.toFixed(0))} tokens/file`));
113
- console.log(chalk.white(`ā± Analysis time: ${chalk.bold(elapsedTime + 's')}\n`));
128
+ console.log(
129
+ chalk.white(`šŸ“ Files analyzed: ${chalk.bold(summary.totalFiles)}`)
130
+ );
131
+ console.log(
132
+ chalk.white(
133
+ `šŸ“Š Total tokens: ${chalk.bold(summary.totalTokens.toLocaleString())}`
134
+ )
135
+ );
136
+ console.log(
137
+ chalk.yellow(
138
+ `šŸ’° Avg context budget: ${chalk.bold(summary.avgContextBudget.toFixed(0))} tokens/file`
139
+ )
140
+ );
141
+ console.log(
142
+ chalk.white(`ā± Analysis time: ${chalk.bold(elapsedTime + 's')}\n`)
143
+ );
114
144
 
115
145
  // Issues summary
116
- const totalIssues = summary.criticalIssues + summary.majorIssues + summary.minorIssues;
146
+ const totalIssues =
147
+ summary.criticalIssues + summary.majorIssues + summary.minorIssues;
117
148
  if (totalIssues > 0) {
118
149
  console.log(chalk.bold('āš ļø Issues Found:\n'));
119
150
  if (summary.criticalIssues > 0) {
120
- console.log(chalk.red(` šŸ”“ Critical: ${chalk.bold(summary.criticalIssues)}`));
151
+ console.log(
152
+ chalk.red(` šŸ”“ Critical: ${chalk.bold(summary.criticalIssues)}`)
153
+ );
121
154
  }
122
155
  if (summary.majorIssues > 0) {
123
- console.log(chalk.yellow(` 🟔 Major: ${chalk.bold(summary.majorIssues)}`));
156
+ console.log(
157
+ chalk.yellow(` 🟔 Major: ${chalk.bold(summary.majorIssues)}`)
158
+ );
124
159
  }
125
160
  if (summary.minorIssues > 0) {
126
- console.log(chalk.blue(` šŸ”µ Minor: ${chalk.bold(summary.minorIssues)}`));
161
+ console.log(
162
+ chalk.blue(` šŸ”µ Minor: ${chalk.bold(summary.minorIssues)}`)
163
+ );
127
164
  }
128
- console.log(chalk.green(`\n šŸ’” Potential savings: ${chalk.bold(summary.totalPotentialSavings.toLocaleString())} tokens\n`));
165
+ console.log(
166
+ chalk.green(
167
+ `\n šŸ’” Potential savings: ${chalk.bold(summary.totalPotentialSavings.toLocaleString())} tokens\n`
168
+ )
169
+ );
129
170
  } else {
130
171
  console.log(chalk.green('āœ… No significant issues found!\n'));
131
172
  }
@@ -133,11 +174,17 @@ export async function contextAction(directory: string, options: ContextOptions)
133
174
  // Deep import chains
134
175
  if (summary.deepFiles.length > 0) {
135
176
  console.log(chalk.bold('šŸ“ Deep Import Chains:\n'));
136
- console.log(chalk.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`));
137
- console.log(chalk.gray(` Maximum depth: ${summary.maxImportDepth}\n`));
177
+ console.log(
178
+ chalk.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`)
179
+ );
180
+ console.log(
181
+ chalk.gray(` Maximum depth: ${summary.maxImportDepth}\n`)
182
+ );
138
183
  summary.deepFiles.slice(0, 10).forEach((item) => {
139
184
  const fileName = item.file.split('/').slice(-2).join('/');
140
- console.log(` ${chalk.cyan('→')} ${chalk.white(fileName)} ${chalk.dim(`(depth: ${item.depth})`)}`);
185
+ console.log(
186
+ ` ${chalk.cyan('→')} ${chalk.white(fileName)} ${chalk.dim(`(depth: ${item.depth})`)}`
187
+ );
141
188
  });
142
189
  console.log();
143
190
  }
@@ -145,10 +192,20 @@ export async function contextAction(directory: string, options: ContextOptions)
145
192
  // Fragmented modules
146
193
  if (summary.fragmentedModules.length > 0) {
147
194
  console.log(chalk.bold('🧩 Fragmented Modules:\n'));
148
- console.log(chalk.gray(` Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(0)}%\n`));
195
+ console.log(
196
+ chalk.gray(
197
+ ` Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(0)}%\n`
198
+ )
199
+ );
149
200
  summary.fragmentedModules.slice(0, 10).forEach((module) => {
150
- console.log(` ${chalk.yellow('ā—')} ${chalk.white(module.domain)} - ${chalk.dim(`${module.files.length} files, ${(module.fragmentationScore * 100).toFixed(0)}% scattered`)}`);
151
- console.log(chalk.dim(` Token cost: ${module.totalTokens.toLocaleString()}, Cohesion: ${(module.avgCohesion * 100).toFixed(0)}%`));
201
+ console.log(
202
+ ` ${chalk.yellow('ā—')} ${chalk.white(module.domain)} - ${chalk.dim(`${module.files.length} files, ${(module.fragmentationScore * 100).toFixed(0)}% scattered`)}`
203
+ );
204
+ console.log(
205
+ chalk.dim(
206
+ ` Token cost: ${module.totalTokens.toLocaleString()}, Cohesion: ${(module.avgCohesion * 100).toFixed(0)}%`
207
+ )
208
+ );
152
209
  });
153
210
  console.log();
154
211
  }
@@ -156,12 +213,18 @@ export async function contextAction(directory: string, options: ContextOptions)
156
213
  // Low cohesion files
157
214
  if (summary.lowCohesionFiles.length > 0) {
158
215
  console.log(chalk.bold('šŸ”€ Low Cohesion Files:\n'));
159
- console.log(chalk.gray(` Average cohesion: ${(summary.avgCohesion * 100).toFixed(0)}%\n`));
216
+ console.log(
217
+ chalk.gray(
218
+ ` Average cohesion: ${(summary.avgCohesion * 100).toFixed(0)}%\n`
219
+ )
220
+ );
160
221
  summary.lowCohesionFiles.slice(0, 10).forEach((item) => {
161
222
  const fileName = item.file.split('/').slice(-2).join('/');
162
223
  const scorePercent = (item.score * 100).toFixed(0);
163
224
  const color = item.score < 0.4 ? chalk.red : chalk.yellow;
164
- console.log(` ${color('ā—‹')} ${chalk.white(fileName)} ${chalk.dim(`(${scorePercent}% cohesion)`)}`);
225
+ console.log(
226
+ ` ${color('ā—‹')} ${chalk.white(fileName)} ${chalk.dim(`(${scorePercent}% cohesion)`)}`
227
+ );
165
228
  });
166
229
  console.log();
167
230
  }
@@ -171,12 +234,19 @@ export async function contextAction(directory: string, options: ContextOptions)
171
234
  console.log(chalk.bold('šŸ’ø Most Expensive Files (Context Budget):\n'));
172
235
  summary.topExpensiveFiles.slice(0, 10).forEach((item) => {
173
236
  const fileName = item.file.split('/').slice(-2).join('/');
174
- const severityColor = item.severity === 'critical' ? chalk.red : item.severity === 'major' ? chalk.yellow : chalk.blue;
175
- console.log(` ${severityColor('ā—')} ${chalk.white(fileName)} ${chalk.dim(`(${item.contextBudget.toLocaleString()} tokens)`)}`);
237
+ const severityColor =
238
+ item.severity === 'critical'
239
+ ? chalk.red
240
+ : item.severity === 'major'
241
+ ? chalk.yellow
242
+ : chalk.blue;
243
+ console.log(
244
+ ` ${severityColor('ā—')} ${chalk.white(fileName)} ${chalk.dim(`(${item.contextBudget.toLocaleString()} tokens)`)}`
245
+ );
176
246
  });
177
247
  console.log();
178
248
  }
179
-
249
+
180
250
  // Display score if calculated
181
251
  if (contextScore) {
182
252
  console.log(chalk.cyan(divider));
@@ -189,4 +259,4 @@ export async function contextAction(directory: string, options: ContextOptions)
189
259
  } catch (error) {
190
260
  handleCLIError(error, 'Context analysis');
191
261
  }
192
- }
262
+ }
@@ -8,7 +8,7 @@ import type { ToolScoringOutput } from '@aiready/core';
8
8
 
9
9
  export async function depsHealthAction(
10
10
  directory: string,
11
- options: any,
11
+ options: any
12
12
  ): Promise<ToolScoringOutput | undefined> {
13
13
  const { analyzeDeps } = await import('@aiready/deps');
14
14
 
@@ -21,7 +21,8 @@ export async function depsHealthAction(
21
21
  rootDir: directory,
22
22
  include: options.include,
23
23
  exclude: options.exclude,
24
- trainingCutoffYear: options.trainingCutoffYear ?? merged.trainingCutoffYear ?? 2023,
24
+ trainingCutoffYear:
25
+ options.trainingCutoffYear ?? merged.trainingCutoffYear ?? 2023,
25
26
  });
26
27
 
27
28
  const scoring: ToolScoringOutput = {
@@ -29,7 +30,11 @@ export async function depsHealthAction(
29
30
  score: report.summary.score,
30
31
  rawMetrics: report.rawData,
31
32
  factors: [],
32
- recommendations: report.recommendations.map((action: string) => ({ action, estimatedImpact: 5, priority: 'medium' }))
33
+ recommendations: report.recommendations.map((action: string) => ({
34
+ action,
35
+ estimatedImpact: 5,
36
+ priority: 'medium',
37
+ })),
33
38
  };
34
39
 
35
40
  if (options.output === 'json') {
@@ -37,7 +42,7 @@ export async function depsHealthAction(
37
42
  }
38
43
 
39
44
  const { summary } = report;
40
- const ratingColors: Record<string, Function> = {
45
+ const ratingColors: Record<string, (s: string) => string> = {
41
46
  excellent: chalk.green,
42
47
  good: chalk.blueBright,
43
48
  moderate: chalk.yellow,
@@ -45,9 +50,13 @@ export async function depsHealthAction(
45
50
  hazardous: chalk.bgRed.white,
46
51
  };
47
52
  const color = ratingColors[summary.rating] ?? chalk.white;
48
- console.log(` šŸ“¦ Dependency Health: ${chalk.bold(scoring.score + '/100 health')} (${color(summary.rating)})`);
53
+ console.log(
54
+ ` šŸ“¦ Dependency Health: ${chalk.bold(scoring.score + '/100 health')} (${color(summary.rating)})`
55
+ );
49
56
  if (report.issues.length > 0) {
50
- console.log(chalk.dim(` Found ${report.issues.length} dependency issues.`));
57
+ console.log(
58
+ chalk.dim(` Found ${report.issues.length} dependency issues.`)
59
+ );
51
60
  } else {
52
61
  console.log(chalk.dim(` Dependencies look healthy for AI assistance.`));
53
62
  }
@@ -8,7 +8,7 @@ import type { ToolScoringOutput } from '@aiready/core';
8
8
 
9
9
  export async function docDriftAction(
10
10
  directory: string,
11
- options: any,
11
+ options: any
12
12
  ): Promise<ToolScoringOutput | undefined> {
13
13
  const { analyzeDocDrift } = await import('@aiready/doc-drift');
14
14
 
@@ -29,7 +29,11 @@ export async function docDriftAction(
29
29
  score: report.summary.score,
30
30
  rawMetrics: report.rawData,
31
31
  factors: [],
32
- recommendations: report.recommendations.map((action: string) => ({ action, estimatedImpact: 5, priority: 'medium' }))
32
+ recommendations: report.recommendations.map((action: string) => ({
33
+ action,
34
+ estimatedImpact: 5,
35
+ priority: 'medium',
36
+ })),
33
37
  };
34
38
 
35
39
  if (options.output === 'json') {
@@ -37,7 +41,7 @@ export async function docDriftAction(
37
41
  }
38
42
 
39
43
  const { summary } = report;
40
- const ratingColors: Record<string, Function> = {
44
+ const ratingColors: Record<string, (s: string) => string> = {
41
45
  minimal: chalk.green,
42
46
  low: chalk.cyan,
43
47
  moderate: chalk.yellow,
@@ -45,7 +49,9 @@ export async function docDriftAction(
45
49
  severe: chalk.bgRed.white,
46
50
  };
47
51
  const color = ratingColors[summary.rating] ?? chalk.white;
48
- console.log(` šŸ“ Documentation Drift: ${chalk.bold(100 - scoring.score + '/100 health')} (${color(summary.rating)} risk)`);
52
+ console.log(
53
+ ` šŸ“ Documentation Drift: ${chalk.bold(100 - scoring.score + '/100 health')} (${color(summary.rating)} risk)`
54
+ );
49
55
  if (report.issues.length > 0) {
50
56
  console.log(chalk.dim(` Found ${report.issues.length} drift issues.`));
51
57
  } else {
@@ -6,8 +6,12 @@ export { scanAction, scanHelpText } from './scan';
6
6
  export { patternsAction, patternsHelpText } from './patterns';
7
7
  export { contextAction } from './context';
8
8
  export { consistencyAction } from './consistency';
9
- export { visualizeAction, visualizeHelpText, visualiseHelpText } from './visualize';
9
+ export {
10
+ visualizeAction,
11
+ visualizeHelpText,
12
+ visualiseHelpText,
13
+ } from './visualize';
10
14
  export { aiSignalClarityAction } from './ai-signal-clarity';
11
15
  export { agentGroundingAction } from './agent-grounding';
12
16
  export { testabilityAction } from './testability';
13
- export { changeAmplificationAction } from './change-amplification';
17
+ export { changeAmplificationAction } from './change-amplification';
@@ -4,11 +4,11 @@
4
4
 
5
5
  import chalk from 'chalk';
6
6
  import { resolve as resolvePath } from 'path';
7
- import {
8
- loadMergedConfig,
9
- handleJSONOutput,
10
- handleCLIError,
11
- getElapsedTime,
7
+ import {
8
+ loadMergedConfig,
9
+ handleJSONOutput,
10
+ handleCLIError,
11
+ getElapsedTime,
12
12
  resolveOutputPath,
13
13
  formatToolScore,
14
14
  } from '@aiready/core';
@@ -28,7 +28,10 @@ interface PatternsOptions {
28
28
  score?: boolean;
29
29
  }
30
30
 
31
- export async function patternsAction(directory: string, options: PatternsOptions) {
31
+ export async function patternsAction(
32
+ directory: string,
33
+ options: PatternsOptions
34
+ ) {
32
35
  console.log(chalk.blue('šŸ” Analyzing patterns...\n'));
33
36
 
34
37
  const startTime = Date.now();
@@ -57,7 +60,9 @@ export async function patternsAction(directory: string, options: PatternsOptions
57
60
 
58
61
  // Load and merge config with CLI options
59
62
  const cliOptions: any = {
60
- minSimilarity: options.similarity ? parseFloat(options.similarity) : undefined,
63
+ minSimilarity: options.similarity
64
+ ? parseFloat(options.similarity)
65
+ : undefined,
61
66
  minLines: options.minLines ? parseInt(options.minLines) : undefined,
62
67
  useSmartDefaults,
63
68
  include: options.include?.split(','),
@@ -72,22 +77,28 @@ export async function patternsAction(directory: string, options: PatternsOptions
72
77
  cliOptions.minSharedTokens = parseInt(options.minSharedTokens);
73
78
  }
74
79
 
75
- const finalOptions = await loadMergedConfig(resolvedDir, defaults, cliOptions);
80
+ const finalOptions = await loadMergedConfig(
81
+ resolvedDir,
82
+ defaults,
83
+ cliOptions
84
+ );
76
85
 
77
- const { analyzePatterns, generateSummary, calculatePatternScore } = await import('@aiready/pattern-detect');
86
+ const { analyzePatterns, generateSummary, calculatePatternScore } =
87
+ await import('@aiready/pattern-detect');
78
88
 
79
89
  const { results, duplicates } = await analyzePatterns(finalOptions);
80
90
 
81
91
  const elapsedTime = getElapsedTime(startTime);
82
92
  const summary = generateSummary(results);
83
-
93
+
84
94
  // Calculate score if requested
85
95
  let patternScore: ToolScoringOutput | undefined;
86
96
  if (options.score) {
87
97
  patternScore = calculatePatternScore(duplicates, results.length);
88
98
  }
89
99
 
90
- const outputFormat = options.output || finalOptions.output?.format || 'console';
100
+ const outputFormat =
101
+ options.output || finalOptions.output?.format || 'console';
91
102
  const userOutputFile = options.outputFile || finalOptions.output?.file;
92
103
 
93
104
  if (outputFormat === 'json') {
@@ -102,22 +113,38 @@ export async function patternsAction(directory: string, options: PatternsOptions
102
113
  `aiready-report-${getReportTimestamp()}.json`,
103
114
  resolvedDir
104
115
  );
105
-
106
- handleJSONOutput(outputData, outputPath, `āœ… Results saved to ${outputPath}`);
116
+
117
+ handleJSONOutput(
118
+ outputData,
119
+ outputPath,
120
+ `āœ… Results saved to ${outputPath}`
121
+ );
107
122
  } else {
108
123
  // Console output - format to match standalone CLI
109
124
  const terminalWidth = process.stdout.columns || 80;
110
125
  const dividerWidth = Math.min(60, terminalWidth - 2);
111
126
  const divider = '━'.repeat(dividerWidth);
112
-
127
+
113
128
  console.log(chalk.cyan(divider));
114
129
  console.log(chalk.bold.white(' PATTERN ANALYSIS SUMMARY'));
115
130
  console.log(chalk.cyan(divider) + '\n');
116
131
 
117
- console.log(chalk.white(`šŸ“ Files analyzed: ${chalk.bold(results.length)}`));
118
- console.log(chalk.yellow(`⚠ Duplicate patterns found: ${chalk.bold(summary.totalPatterns)}`));
119
- console.log(chalk.red(`šŸ’° Token cost (wasted): ${chalk.bold(summary.totalTokenCost.toLocaleString())}`));
120
- console.log(chalk.gray(`ā± Analysis time: ${chalk.bold(elapsedTime + 's')}`));
132
+ console.log(
133
+ chalk.white(`šŸ“ Files analyzed: ${chalk.bold(results.length)}`)
134
+ );
135
+ console.log(
136
+ chalk.yellow(
137
+ `⚠ Duplicate patterns found: ${chalk.bold(summary.totalPatterns)}`
138
+ )
139
+ );
140
+ console.log(
141
+ chalk.red(
142
+ `šŸ’° Token cost (wasted): ${chalk.bold(summary.totalTokenCost.toLocaleString())}`
143
+ )
144
+ );
145
+ console.log(
146
+ chalk.gray(`ā± Analysis time: ${chalk.bold(elapsedTime + 's')}`)
147
+ );
121
148
 
122
149
  // Show breakdown by pattern type
123
150
  const sortedTypes = Object.entries(summary.patternsByType || {})
@@ -145,18 +172,32 @@ export async function patternsAction(directory: string, options: PatternsOptions
145
172
  .slice(0, 10);
146
173
 
147
174
  topDuplicates.forEach((dup) => {
148
- const severity = dup.similarity > 0.95 ? 'CRITICAL' : dup.similarity > 0.9 ? 'HIGH' : 'MEDIUM';
149
- const severityIcon = dup.similarity > 0.95 ? 'šŸ”“' : dup.similarity > 0.9 ? '🟔' : 'šŸ”µ';
175
+ const severity =
176
+ dup.similarity > 0.95
177
+ ? 'CRITICAL'
178
+ : dup.similarity > 0.9
179
+ ? 'HIGH'
180
+ : 'MEDIUM';
181
+ const severityIcon =
182
+ dup.similarity > 0.95 ? 'šŸ”“' : dup.similarity > 0.9 ? '🟔' : 'šŸ”µ';
150
183
  const file1Name = dup.file1.split('/').pop() || dup.file1;
151
184
  const file2Name = dup.file2.split('/').pop() || dup.file2;
152
- console.log(`${severityIcon} ${severity}: ${chalk.bold(file1Name)} ↔ ${chalk.bold(file2Name)}`);
153
- console.log(` Similarity: ${chalk.bold(Math.round(dup.similarity * 100) + '%')} | Wasted: ${chalk.bold(dup.tokenCost.toLocaleString())} tokens each`);
154
- console.log(` Lines: ${chalk.cyan(dup.line1 + '-' + dup.endLine1)} ↔ ${chalk.cyan(dup.line2 + '-' + dup.endLine2)}\n`);
185
+ console.log(
186
+ `${severityIcon} ${severity}: ${chalk.bold(file1Name)} ↔ ${chalk.bold(file2Name)}`
187
+ );
188
+ console.log(
189
+ ` Similarity: ${chalk.bold(Math.round(dup.similarity * 100) + '%')} | Wasted: ${chalk.bold(dup.tokenCost.toLocaleString())} tokens each`
190
+ );
191
+ console.log(
192
+ ` Lines: ${chalk.cyan(dup.line1 + '-' + dup.endLine1)} ↔ ${chalk.cyan(dup.line2 + '-' + dup.endLine2)}\n`
193
+ );
155
194
  });
156
195
  } else {
157
- console.log(chalk.green('\n✨ Great! No duplicate patterns detected.\n'));
196
+ console.log(
197
+ chalk.green('\n✨ Great! No duplicate patterns detected.\n')
198
+ );
158
199
  }
159
-
200
+
160
201
  // Display score if calculated
161
202
  if (patternScore) {
162
203
  console.log(chalk.cyan(divider));
@@ -176,4 +217,4 @@ EXAMPLES:
176
217
  $ aiready patterns # Default analysis
177
218
  $ aiready patterns --similarity 0.6 # Stricter matching
178
219
  $ aiready patterns --min-lines 10 # Larger patterns only
179
- `;
220
+ `;